如何在Windows服務程式中讀寫HKEY_CURRENT_USER註冊表

來源:互聯網
上載者:User

標籤:style   blog   http   color   io   os   使用   ar   for   

在服務程式中想要對註冊表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服務程式中讀寫HKEY_CURRENT_USER註冊表

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.