如何在Windows服务程序中读写HKEY_CURRENT_USER注册表

在服务程序中想要对注册表HKEY_CURRENT_USER下的内容进行读写,不会返回失败,但是始终无效。原因是:

1.服务运行在系统权限之下,而不是任何一个用户

2.HKEY_CURRENT_USER存储的是当前用户的信息================>导致在服务中读取HKEY_CURRENT_USER实际操作的不是当前登录的用户的数据。

所以如果我要操作HKEY_CURRENT_USER之内的键值,就必须模拟当前用户去读取。

有几种思路可以做到:

1.创建一个用户进程去操作注册表,使用CreateProcessAsUser函数可以做到

2.让当前线程模拟当前登录用户的安全上下文(lets the calling thread impersonate the security context of a logged-on user)。使用ImpersonateLoggedOnUser 函数可以做到。

第一个方法需要用到另外一个程序,感觉比较麻烦。

以下演示第二种方法:

BOOL GetTokenByName(HANDLE &hToken,LPTSTR lpName)

{

    if (!lpName)

        return FALSE;



    HANDLE         hProcessSnap = NULL; 

    BOOL           bRet      = FALSE; 

    PROCESSENTRY32 pe32      = {0}; 



    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 

    if (hProcessSnap == INVALID_HANDLE_VALUE) 

        return (FALSE); 



    pe32.dwSize = sizeof(PROCESSENTRY32); 



    if (Process32First(hProcessSnap, &pe32)) 

    {  

        do

        {

            if(!_tcscmp(_tcsupr(pe32.szExeFile),_tcsupr(lpName)))

            {

                HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pe32.th32ProcessID);

                bRet = OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken);

                CloseHandle (hProcess); 

                CloseHandle (hProcessSnap); 

                return (bRet);

            }

        }

        while (Process32Next(hProcessSnap, &pe32)); 

        bRet = FALSE; 

    } 

    else 

    {

        bRet = FALSE;

    }



    CloseHandle (hProcessSnap); 

    return (bRet);

}

//

//获取用户sid

//

bool GetAccountSid(LPTSTR AccountName, PSID *Sid)

{

    PSID pSID = NULL;

    DWORD cbSid = 0;

    LPTSTR DomainName = NULL;

    DWORD cbDomainName = 0;

    SID_NAME_USE SIDNameUse;

    BOOL  bDone = FALSE;

    try

    {

        if(!LookupAccountName(NULL,

            AccountName,

            pSID,

            &cbSid,

            DomainName,

            &cbDomainName,

            &SIDNameUse))

        {

            pSID = (PSID)malloc(cbSid);

            DomainName = (LPTSTR)malloc(cbDomainName * sizeof(TCHAR));

            if(!pSID || !DomainName)

            {

                throw;

            }

            if(!LookupAccountName(NULL,

                AccountName,

                pSID,

                &cbSid,

                DomainName,

                &cbDomainName,

                &SIDNameUse))

            {

                throw;

            }

            bDone = TRUE;

        }

    }

    catch(...)

    {

        //nothing

    }

    if(DomainName)

    {

        free(DomainName);

    }



    if(!bDone && pSID)

    {

        free(pSID);

    }

    if(bDone)

    {

        *Sid = pSID;

    }

    return bDone;

}



// 模拟当前用户环境设置默认打印机

void SimulateCurrentUserSetDefaultPrinter()

{

    HANDLE hToken = NULL;

    do 

    {

        if (!GetTokenByName(hToken,_T("EXPLORER.EXE")))

        {

            break;

        }



        // 模拟登录用户的安全上下文

        if(FALSE == ImpersonateLoggedOnUser(hToken))

        {

            break;

        }



        // 获取用户名

        TCHAR szUsername[MAX_PATH];

        DWORD dwUsernameLen = MAX_PATH;

        if(FALSE == GetUserName(szUsername, &dwUsernameLen))

            break;



        // 到这里已经模拟完了,别忘记返回原来的安全上下文

        if(FALSE == RevertToSelf())

            break;



        // 获取sid

        PSID pSid = NULL;

        LPWSTR sid;

        GetAccountSid(szUsername, &pSid); //获取得到的是一个结构体

        ConvertSidToStringSid(pSid, &sid); //从结构体中得到sid串



        // 设置默认打印机信息

        //SetDefaultPrinter(PSSD_PRINTER_NAME);

        HKEY hKey;

        int i=0;    //操作结果:0==succeed

        wchar_t lswRegValue[MAX_PATH];

        StringCchPrintf(lswRegValue, MAX_PATH, L"%s,winspool,%s", PSSD_PRINTER_NAME, PSSD_PRINTER_PORT_NAME);

        wchar_t lswKeyPath[MAX_PATH] = {0};

        StringCchPrintf(lswKeyPath, MAX_PATH, L"%s\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows", sid);

        if(RegOpenKeyEx(HKEY_USERS, lswKeyPath,    0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)

        {

            if(RegSetValueEx(hKey,L"Device",NULL,REG_SZ, (const LPBYTE)lswRegValue, (wcslen(lswRegValue) + 1) * sizeof(wchar_t))!=ERROR_SUCCESS)

            {

                i=1;

            }

            RegCloseKey(hKey);

        }

        else

        {

            i=1;

        }

        if(1 == i)

        {

            OutputDebugStringW(L"STST:   设置默认打印机失败");

        }

        else

        {

            SendNotifyMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0);

        }



    } while (false);

    if(NULL != hToken)

        CloseHandle(hToken);

}

你可能感兴趣的:(windows)