어떻게 읽기 및 쓰기 HKEY_CURRENT_USER 레지스트리 Windows 서비스 프로그램합니다

읽기 및 쓰기 위해 HKEY_CURRENT_USER 레지스트리에서 콘텐츠를 원하는, 그것은 서비스 프로그램에서 오류를 반환하지, 항상은 아니지만 작동합니다. 그 이유는 :

1.이 서비스는 오히려 어느 한 사용자보다 시스템 권한으로 실행

2.HKEY_CURRENT_USER 스토리지는 현재 사용자의 정보 ================> 사용자는 현재 서비스 데이터의 실제 작동 원인 HKEY_CURRENT_USER를 읽는에 기록되지 않습니다.

내가 HKEY_CURRENT_USER의 키를 조작하려는 경우 그래서, 읽을 현재 사용자를 시뮬레이션하는 것이 필요하다.

 

다음과 같이 인터넷은, 기록, 생각을 달성 할 수있는 방법을 찾기 위해 오랜 시간에 대한 정보를 찾을 수 있습니다

아이디어 : 현재의 thread가 로그온 한 사용자의 현재 보안 컨텍스트 시뮬레이션 할 수 있습니다. (부름에 스레드 가장 할을 할 수 있습니다 앳 보안 컨텍스트  사용자 (A)의 기록-ON). 사용 ImpersonateLoggedOnUser 기능을 수행 할 수 있습니다. 

코드 :

보이드 윈도우 서비스 ()
{
	// 사용자 이름
	TCHAR szUsername [MAX_PATH];
	플래그 BOOL = FALSE;
	HANDLE g_hToken = NULL;
	하다 
	{

		로거 ::의 getInstance은 () -> 정보 (__ FILE__, __LINE__는 "토큰을 얻기 위해 시작했다");
		플래그 INTER_GetExplorerToken을 (를 g_hToken) =;			
		경우 (플래그)
		{
			로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE__, "실패 토큰을 얻을");
			단절;
		}
		그밖에
		{
			로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE__, "토큰 성공을 얻을");
		}
		//는 로그온 한 사용자의 보안 컨텍스트를 시뮬레이션
		경우 (FALSE == ImpersonateLoggedOnUser (g_hToken))
		{
			단절;
		}
		DWORD dwUsernameLen = MAX_PATH;
		경우 (FALSE == 때 getUserName (szUsername, dwUsernameLen))
			단절;

		//// 시뮬레이션은 원래의 보안 컨텍스트로 복귀하는 것을 잊지 마세요, 여기에 완료되었습니다
		경우 (FALSE은 RevertToSelf == ())
			단절;
	} 동안 (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 ( "경로");
	숯 strValue의 [256] = {0};
	INT 길이 = 256;
	// 레지스트리를 읽고
	부울 상태 QueryRegKey (strSubKey, strValueName strValue의, 길이) =;
	sprintf_s (BUF '경로 % = S, = LEN % D, 상태 = % d 개, SID = % LS "strValue의 길이, 상태 SID);
	로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE __, 버피);
}

  

DWORD INTER_GetExplorerToken (pHandle에 phExplorerToken)
{
	DWORD dwStatus = ERROR_FILE_NOT_FOUND;
	BOOL 브레 = FALSE;
	HANDLE hProcess = NULL;
	HANDLE hProcessSnap = NULL;
	숯 szExplorerPath [MAX_PATH] = {0};
	숯 파일 이름 [MAX_PATH] = {0};
	PROCESSENTRY32 PE32 = {0};

	시험
	{
		hProcessSnap :: = 위해 CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
		경우 (hProcessSnap == INVALID_HANDLE_VALUE)
		{
			이 dwStatus을 GetLastError () =;
		}
		그밖에
		{
			pe32.dwSize =를 sizeof (PROCESSENTRY32);
			INT bMore :: = Process32First (hProcessSnap, PE32);
			반면 (bMore)
			{
				(0 :: wcscmp (pe32.szExeFile, _T ( "explorer.exe를")) == 있으면)
				{
					hProcess :: = OpenProcess에 (PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
					경우 (OpenProcessToken (hProcess, TOKEN_ALL_ACCESS, phExplorerToken))
					{
						dwStatus = 0;
					}
					그밖에
					{
						이 dwStatus을 GetLastError () =;
					}
					단절;
				}
				bMore :: = Process32Next (hProcessSnap, PE32);
			}
		}
	}
	캐치 (...)
	{
	}

	경우 (hProcess)
	{
		하여 CloseHandle (hProcess);
	}
	경우 (hProcessSnap)
	{
		하여 CloseHandle (hProcessSnap);
	}

	dwStatus를 반환;
}

  

불리언 GetAccountSid (LPTSTR 계정 이름, PSID * SID)
{
	PSID PSID = NULL;
	DWORD cbSid는 = 0;
	LPTSTR 도메인 이름 = NULL;
	DWORD cbDomainName는 = 0;
	SID_NAME_USE SIDNameUse;
	BOOL bDone = FALSE;
	시험
	{
		만약 (! 중 LookupAccountName (NULL,
			계정 이름,
			PSID,
			& cbSid,
			도메인 이름,
			& cbDomainName,
			및 SIDNameUse))
		{
			PSID = (PSID)의 malloc (cbSid);
			도메인 이름 = (LPTSTR)의 malloc (cbDomainName *를 sizeof (TCHAR));
			만약 (! PSID ||! 도메인 이름)
			{
				던지다;
			}
			만약 (! 중 LookupAccountName (NULL,
				계정 이름,
				PSID,
				& cbSid,
				도메인 이름,
				& cbDomainName,
				및 SIDNameUse))
			{
				던지다;
			}
			bDone이 = TRUE;
		}
	}
	캐치 (...)
	{
		//아무것도
	}
	경우 (도메인 이름)
	{
		무료 (도메인 이름);
	}

	만약 (! bDone && PSID)
	{
		무료 (PSID);
	}
	경우 (bDone)
	{
		* = PSID 시드;
	}
	bDone를 반환;
}

  

불리언 QueryRegKey (LPCWSTR strSubKey, LPCWSTR strValueName, * CHAR strValue의, INT 길이) //이 세 매개 변수 전달
{
	DWORD dwType = REG_SZ // 정의 데이터 형식
	DWORD dwLen = MAX_PATH;

	데이터의 wchar_t [MAX_PATH] = {0};
	HKEY HKEY;
	긴 ERR = ERROR_SUCCESS;
	// HKEY_CURRENT_USER KEY_READ
	ERR == RegOpenKeyEx (HKEY_USERS, strSubKey, 0, KEY_READ, HKEY);
	경우 (ERR == ERROR_SUCCESS)
	{
		숯 bufLog [128] = {0};
		로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE__, "RegOpenKeyEx 성공");

		긴 errRet = RegQueryValueEx (HKEY, _T ( "경로"), NULL, dwType (LPBYTE) 데이터, dwLen);
		
		경우 (ERROR_SUCCESS == errRet)
		{
			wcharTochar (데이터 strValue의 길이);
			// wprintf (L "데이터 = %의 LS 렌 % D = \ n", 데이터 나 strlen ((CONST * CHAR) 데이터));
			
			sprintf_s (bufLog "RegQueryValueEx : 데이터 = %의 LS, 렌 = % d의"데이터 나 strlen ((CONST * CHAR) 데이터));
			로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE__, bufLog);
			sprintf_s (bufLog "RegQueryValueEx : % S = strValue의 길이 = % D"strValue의 길이);
			로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE__, bufLog);
			을 RegCloseKey (HKEY); // 닫기 레지스트리
			true를 반환;
		}
		그밖에
		{
			숯 bufLog [128] = {0};
			
			sprintf_s (bufLog "RegQueryValueEx 실패 : RET = % D"errRet);
			로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE__, bufLog);
		}
		을 RegCloseKey (HKEY); // 닫기 레지스트리
	}
	그밖에
	{
		숯 bufLog [128] = {0};
		sprintf_s (bufLog "RegOpenKeyEx : strSubKey = % LS 렌 = % LD"strSubKey, ERR);
		로거 ::의 getInstance은 () -> 정보는 (__ FILE__는, __LINE__, "RegOpenKeyEx successOpenRegKey 반환은 false입니다!");
	}

	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>

 

추천

출처www.cnblogs.com/alinh/p/12410436.html