zoukankan      html  css  js  c++  java
  • 如何在Windows服务程序中读写HKEY_CURRENT_USER注册表

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

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

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

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

    网上找了很久的资料,找到了一种实现方式,记录下,思路,代码如下

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

    代码:

    void windowsService()
    {
    	//用户名
    	TCHAR szUsername[MAX_PATH];
    	BOOL flag = FALSE;
    	HANDLE g_hToken = NULL;
    	do 
    	{
    
    		Logger::getInstance()->info(__FILE__, __LINE__, "开始获取token");
    		flag = INTER_GetExplorerToken(&g_hToken);			
    		if (flag)
    		{
    			Logger::getInstance()->info(__FILE__, __LINE__, "获取token失败");
    			break;
    		}
    		else
    		{
    			Logger::getInstance()->info(__FILE__, __LINE__, "获取token成功");
    		}
    		// 模拟登录用户的安全上下文
    		if (FALSE == ImpersonateLoggedOnUser(g_hToken))
    		{
    			break;
    		}
    		DWORD dwUsernameLen = MAX_PATH;
    		if (FALSE == GetUserName(szUsername, &dwUsernameLen))
    			break;
    
    		//// 到这里已经模拟完了,别忘记返回原来的安全上下文
    		if (FALSE == RevertToSelf())
    			break;
    	} while (false);
    	// 获取sid
    	PSID pSid = NULL;
    	LPWSTR sid;
    	GetAccountSid(szUsername, &pSid); //获取得到的是一个结构体
    	ConvertSidToStringSid(pSid, &sid); //从结构体中得到sid串
    	wchar_t lswKeyPath[MAX_PATH] = { 0 };
    	StringCchPrintf(lswKeyPath, MAX_PATH, L"%ls\SOFTWARE\FatsClient", sid);
    	LPCWSTR strSubKey = lswKeyPath;//_T("SOFTWARE\FatsClient");
    	LPCWSTR strValueName = _T("path");
    	char strValue[256] = {0};
    	int length = 256;
    	//读注册表
    	bool status = QueryRegKey(strSubKey, strValueName, strValue, length);
    	sprintf_s(buf, "path=%s ,len=%d,status=%d,sid=%ls", strValue,length,status, sid);
    	Logger::getInstance()->info(__FILE__, __LINE__,buf);
    }
    

      

    DWORD INTER_GetExplorerToken(PHANDLE phExplorerToken)
    {
    	DWORD       dwStatus = ERROR_FILE_NOT_FOUND;
    	BOOL        bRet = FALSE;
    	HANDLE      hProcess = NULL;
    	HANDLE      hProcessSnap = NULL;
    	char        szExplorerPath[MAX_PATH] = { 0 };
    	char        FileName[MAX_PATH] = { 0 };
    	PROCESSENTRY32 pe32 = { 0 };
    
    	try
    	{
    		hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    		if (hProcessSnap == INVALID_HANDLE_VALUE)
    		{
    			dwStatus = GetLastError();
    		}
    		else
    		{
    			pe32.dwSize = sizeof(PROCESSENTRY32);
    			int bMore = ::Process32First(hProcessSnap, &pe32);
    			while (bMore)
    			{
    				if (::wcscmp(pe32.szExeFile, _T("explorer.exe")) == 0)
    				{
    					hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
    					if (OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, phExplorerToken))
    					{
    						dwStatus = 0;
    					}
    					else
    					{
    						dwStatus = GetLastError();
    					}
    					break;
    				}
    				bMore = ::Process32Next(hProcessSnap, &pe32);
    			}
    		}
    	}
    	catch (...)
    	{
    	}
    
    	if (hProcess)
    	{
    		CloseHandle(hProcess);
    	}
    	if (hProcessSnap)
    	{
    		CloseHandle(hProcessSnap);
    	}
    
    	return dwStatus;
    }
    

      

    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;
    }
    

      

    bool QueryRegKey(LPCWSTR strSubKey, LPCWSTR strValueName, char *strValue, int length)//这里是传3个参数
    {
    	DWORD dwType = REG_SZ;//定义数据类型
    	DWORD dwLen = MAX_PATH;
    
    	wchar_t data[MAX_PATH] = {0};
    	HKEY hKey;
    	long err = ERROR_SUCCESS;
    	//HKEY_CURRENT_USER KEY_READ
    	err == RegOpenKeyEx(HKEY_USERS, strSubKey, 0, KEY_READ, &hKey);
    	if (err == ERROR_SUCCESS)
    	{
    		char bufLog[128] = { 0 };
    		Logger::getInstance()->info(__FILE__, __LINE__, "RegOpenKeyEx success");
    
    		long errRet = RegQueryValueEx(hKey, _T("path"), NULL, &dwType, (LPBYTE)&data, &dwLen);
    		
    		if (ERROR_SUCCESS == errRet)
    		{
    			wcharTochar(data, strValue, length);
    			//wprintf(L"data = %ls,len= %d
    ", data, strlen((const char *)data));
    			
    			sprintf_s(bufLog, "RegQueryValueEx:data=%ls ,len=%d", data, strlen((const char *)data));
    			Logger::getInstance()->info(__FILE__, __LINE__, bufLog);
    			sprintf_s(bufLog, "RegQueryValueEx:strValue=%s ,length=%d", strValue, length);
    			Logger::getInstance()->info(__FILE__, __LINE__, bufLog);
    			RegCloseKey(hKey); //关闭注册表
    			return true;
    		}
    		else
    		{
    			char bufLog[128] = { 0 };
    			
    			sprintf_s(bufLog, "RegQueryValueEx fail:ret=%d", errRet);
    			Logger::getInstance()->info(__FILE__, __LINE__, bufLog);
    		}
    		RegCloseKey(hKey); //关闭注册表
    	}
    	else
    	{
    		char bufLog[128] = { 0 };
    		sprintf_s(bufLog, "RegOpenKeyEx:strSubKey=%ls ,len=%ld", strSubKey, err);
    		Logger::getInstance()->info(__FILE__, __LINE__, "RegOpenKeyEx successOpenRegKey return is false!");
    	}
    
    	return false;
    }
    

      所需要的头文件:#include <iostream> #include <assert.h> #include "windows.h" #include "tchar.h" #include "conio.h" #include "stdio.h" #include <strsafe.h> #include <sddl.h> #include "tlhelp32.h" #include <atlstr.h>

  • 相关阅读:
    HiveQL:数据定义
    linux学习整理
    Hive中问题解决整理
    Hive 数据类型和文件格式
    neo4j 简要安装步骤
    Leetcode 刷题笔记二 两数相加(使用链表) -- scala版本
    leetcode 刷题笔记一 两数之和 scala版本
    windows 安装 tensorflow
    elemnetui 下载,及引用
    cenos7 安装mysql
  • 原文地址:https://www.cnblogs.com/alinh/p/12410436.html
Copyright © 2011-2022 走看看