mirror of
				https://github.com/pbatard/rufus.git
				synced 2024-08-14 23:57:05 +00:00 
			
		
		
		
	[core] Set local group policies using a thread with timeout
* Closes #392
This commit is contained in:
		
							parent
							
								
									02697a025a
								
							
						
					
					
						commit
						3056703097
					
				
					 2 changed files with 57 additions and 23 deletions
				
			
		
							
								
								
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								src/rufus.rc
									
										
									
									
									
								
							|  | @ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL | ||||||
| 
 | 
 | ||||||
| IDD_DIALOG DIALOGEX 12, 12, 206, 329 | IDD_DIALOG DIALOGEX 12, 12, 206, 329 | ||||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||||
| CAPTION "Rufus 1.4.11.527" | CAPTION "Rufus 1.4.11.528" | ||||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||||
| BEGIN | BEGIN | ||||||
|     DEFPUSHBUTTON   "Start",IDC_START,94,291,50,14 |     DEFPUSHBUTTON   "Start",IDC_START,94,291,50,14 | ||||||
|  | @ -165,7 +165,7 @@ END | ||||||
| RTL_IDD_DIALOG DIALOGEX 12, 12, 206, 329 | RTL_IDD_DIALOG DIALOGEX 12, 12, 206, 329 | ||||||
| STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | ||||||
| EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL | EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL | ||||||
| CAPTION "Rufus 1.4.11.527" | CAPTION "Rufus 1.4.11.528" | ||||||
| FONT 8, "MS Shell Dlg", 400, 0, 0x1 | FONT 8, "MS Shell Dlg", 400, 0, 0x1 | ||||||
| BEGIN | BEGIN | ||||||
|     DEFPUSHBUTTON   "Start",IDC_START,94,291,50,14 |     DEFPUSHBUTTON   "Start",IDC_START,94,291,50,14 | ||||||
|  | @ -428,8 +428,8 @@ END | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION 1,4,11,527 |  FILEVERSION 1,4,11,528 | ||||||
|  PRODUCTVERSION 1,4,11,527 |  PRODUCTVERSION 1,4,11,528 | ||||||
|  FILEFLAGSMASK 0x3fL |  FILEFLAGSMASK 0x3fL | ||||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||||
|  FILEFLAGS 0x1L |  FILEFLAGS 0x1L | ||||||
|  | @ -446,13 +446,13 @@ BEGIN | ||||||
|         BEGIN |         BEGIN | ||||||
|             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" |             VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" | ||||||
|             VALUE "FileDescription", "Rufus" |             VALUE "FileDescription", "Rufus" | ||||||
|             VALUE "FileVersion", "1.4.11.527" |             VALUE "FileVersion", "1.4.11.528" | ||||||
|             VALUE "InternalName", "Rufus" |             VALUE "InternalName", "Rufus" | ||||||
|             VALUE "LegalCopyright", "© 2011-2014 Pete Batard (GPL v3)" |             VALUE "LegalCopyright", "© 2011-2014 Pete Batard (GPL v3)" | ||||||
|             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" |             VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" | ||||||
|             VALUE "OriginalFilename", "rufus.exe" |             VALUE "OriginalFilename", "rufus.exe" | ||||||
|             VALUE "ProductName", "Rufus" |             VALUE "ProductName", "Rufus" | ||||||
|             VALUE "ProductVersion", "1.4.11.527" |             VALUE "ProductVersion", "1.4.11.528" | ||||||
|         END |         END | ||||||
|     END |     END | ||||||
|     BLOCK "VarFileInfo" |     BLOCK "VarFileInfo" | ||||||
|  |  | ||||||
							
								
								
									
										68
									
								
								src/stdfn.c
									
										
									
									
									
								
							
							
						
						
									
										68
									
								
								src/stdfn.c
									
										
									
									
									
								
							|  | @ -560,8 +560,20 @@ DECLARE_INTERFACE_(IGroupPolicyObject, IUnknown) { | ||||||
| }; | }; | ||||||
| typedef IGroupPolicyObject *LPGROUPPOLICYOBJECT; | typedef IGroupPolicyObject *LPGROUPPOLICYOBJECT; | ||||||
| 
 | 
 | ||||||
| BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue) | // I've seen rare cases where pLGPO->lpVtbl->Save(...) gets stuck, which prevents the
 | ||||||
|  | // application from launching altogether. To alleviate this, use a thread that we can
 | ||||||
|  | // terminate if needed...
 | ||||||
|  | typedef struct { | ||||||
|  | 	BOOL bRestore; | ||||||
|  | 	BOOL* bExistingKey; | ||||||
|  | 	const char* szPath; | ||||||
|  | 	const char* szPolicy; | ||||||
|  | 	DWORD dwValue; | ||||||
|  | } SetLGP_Params; | ||||||
|  | 
 | ||||||
|  | DWORD WINAPI SetLGPThread(LPVOID param) | ||||||
| { | { | ||||||
|  | 	SetLGP_Params* p = (SetLGP_Params*)param; | ||||||
| 	LONG r; | 	LONG r; | ||||||
| 	DWORD disp, regtype, val=0, val_size=sizeof(DWORD); | 	DWORD disp, regtype, val=0, val_size=sizeof(DWORD); | ||||||
| 	HRESULT hr; | 	HRESULT hr; | ||||||
|  | @ -578,6 +590,9 @@ BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* s | ||||||
| 	// Can be anything really
 | 	// Can be anything really
 | ||||||
| 	GUID snap_guid = { 0x3D271CFC, 0x2BC6, 0x4AC2, {0xB6, 0x33, 0x3B, 0xDF, 0xF5, 0xBD, 0xAB, 0x2A} }; | 	GUID snap_guid = { 0x3D271CFC, 0x2BC6, 0x4AC2, {0xB6, 0x33, 0x3B, 0xDF, 0xF5, 0xBD, 0xAB, 0x2A} }; | ||||||
| 
 | 
 | ||||||
|  | 	// Reinitialize COM since it's not shared between threads
 | ||||||
|  | 	IGNORE_RETVAL(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)); | ||||||
|  | 
 | ||||||
| 	// We need an IGroupPolicyObject instance to set a Local Group Policy
 | 	// We need an IGroupPolicyObject instance to set a Local Group Policy
 | ||||||
| 	hr = CoCreateInstance(&my_CLSID_GroupPolicyObject, NULL, CLSCTX_INPROC_SERVER, &my_IID_IGroupPolicyObject, (LPVOID*)&pLGPO); | 	hr = CoCreateInstance(&my_CLSID_GroupPolicyObject, NULL, CLSCTX_INPROC_SERVER, &my_IID_IGroupPolicyObject, (LPVOID*)&pLGPO); | ||||||
| 	if (FAILED(hr)) { | 	if (FAILED(hr)) { | ||||||
|  | @ -598,31 +613,31 @@ BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* s | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// The DisableSystemRestore is set in Software\Policies\Microsoft\Windows\DeviceInstall\Settings
 | 	// The DisableSystemRestore is set in Software\Policies\Microsoft\Windows\DeviceInstall\Settings
 | ||||||
| 	r = RegCreateKeyExA(path_key, szPath, 0, NULL, 0, KEY_SET_VALUE | KEY_QUERY_VALUE, | 	r = RegCreateKeyExA(path_key, p->szPath, 0, NULL, 0, KEY_SET_VALUE | KEY_QUERY_VALUE, | ||||||
| 		NULL, &policy_key, &disp); | 		NULL, &policy_key, &disp); | ||||||
| 	if (r != ERROR_SUCCESS) { | 	if (r != ERROR_SUCCESS) { | ||||||
| 		uprintf("SetLGP: Failed to open LGPO path %s - error %x\n", szPath, hr); | 		uprintf("SetLGP: Failed to open LGPO path %s - error %x\n", p->szPath, hr); | ||||||
| 		goto error; | 		goto error; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if ((disp == REG_OPENED_EXISTING_KEY) && (!bRestore) && (!(*bExistingKey))) { | 	if ((disp == REG_OPENED_EXISTING_KEY) && (!p->bRestore) && (!(*(p->bExistingKey)))) { | ||||||
| 		// backup existing value for restore
 | 		// backup existing value for restore
 | ||||||
| 		*bExistingKey = TRUE; | 		*(p->bExistingKey) = TRUE; | ||||||
| 		regtype = REG_DWORD; | 		regtype = REG_DWORD; | ||||||
| 		r = RegQueryValueExA(policy_key, szPolicy, NULL, ®type, (LPBYTE)&original_val, &val_size); | 		r = RegQueryValueExA(policy_key, p->szPolicy, NULL, ®type, (LPBYTE)&original_val, &val_size); | ||||||
| 		if (r == ERROR_FILE_NOT_FOUND) { | 		if (r == ERROR_FILE_NOT_FOUND) { | ||||||
| 			// The Key exists but not its value, which is OK
 | 			// The Key exists but not its value, which is OK
 | ||||||
| 			*bExistingKey = FALSE; | 			*(p->bExistingKey) = FALSE; | ||||||
| 		} else if (r != ERROR_SUCCESS) { | 		} else if (r != ERROR_SUCCESS) { | ||||||
| 			uprintf("SetLGP: Failed to read original %s policy value - error %x\n", szPolicy, r); | 			uprintf("SetLGP: Failed to read original %s policy value - error %x\n", p->szPolicy, r); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if ((!bRestore) || (*bExistingKey)) { | 	if ((!p->bRestore) || (*(p->bExistingKey))) { | ||||||
| 		val = (bRestore)?original_val:dwValue; | 		val = (p->bRestore)?original_val:p->dwValue; | ||||||
| 		r = RegSetValueExA(policy_key, szPolicy, 0, REG_DWORD, (BYTE*)&val, sizeof(val)); | 		r = RegSetValueExA(policy_key, p->szPolicy, 0, REG_DWORD, (BYTE*)&val, sizeof(val)); | ||||||
| 	} else { | 	} else { | ||||||
| 		r = RegDeleteValueA(policy_key, szPolicy); | 		r = RegDeleteValueA(policy_key, p->szPolicy); | ||||||
| 	} | 	} | ||||||
| 	if (r != ERROR_SUCCESS) { | 	if (r != ERROR_SUCCESS) { | ||||||
| 		uprintf("SetLGP: RegSetValueEx / RegDeleteValue failed - error %x\n", r); | 		uprintf("SetLGP: RegSetValueEx / RegDeleteValue failed - error %x\n", r); | ||||||
|  | @ -631,15 +646,15 @@ BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* s | ||||||
| 	policy_key = NULL; | 	policy_key = NULL; | ||||||
| 
 | 
 | ||||||
| 	// Apply policy
 | 	// Apply policy
 | ||||||
| 	hr = pLGPO->lpVtbl->Save(pLGPO, TRUE, (bRestore)?FALSE:TRUE, &ext_guid, &snap_guid); | 	hr = pLGPO->lpVtbl->Save(pLGPO, TRUE, (p->bRestore)?FALSE:TRUE, &ext_guid, &snap_guid); | ||||||
| 	if (hr != S_OK) { | 	if (hr != S_OK) { | ||||||
| 		uprintf("SetLGP: Unable to apply %s policy - error %x\n", szPolicy, hr); | 		uprintf("SetLGP: Unable to apply %s policy - error %x\n", p->szPolicy, hr); | ||||||
| 		goto error; | 		goto error; | ||||||
| 	} else { | 	} else { | ||||||
| 		if ((!bRestore) || (*bExistingKey)) { | 		if ((!p->bRestore) || (*(p->bExistingKey))) { | ||||||
| 			uprintf("SetLGP: Successfully %s %s policy to 0x%08X\n", (bRestore)?"restored":"set", szPolicy, val); | 			uprintf("SetLGP: Successfully %s %s policy to 0x%08X\n", (p->bRestore)?"restored":"set", p->szPolicy, val); | ||||||
| 		} else { | 		} else { | ||||||
| 			uprintf("SetLGP: Successfully removed %s policy key\n", szPolicy); | 			uprintf("SetLGP: Successfully removed %s policy key\n", p->szPolicy); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -654,3 +669,22 @@ error: | ||||||
| 	return FALSE; | 	return FALSE; | ||||||
| } | } | ||||||
| #pragma pop_macro("INTERFACE") | #pragma pop_macro("INTERFACE") | ||||||
|  | 
 | ||||||
|  | BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue) | ||||||
|  | { | ||||||
|  | 	SetLGP_Params params = {bRestore, bExistingKey, szPath, szPolicy, dwValue}; | ||||||
|  | 	HANDLE thread_id = CreateThread(NULL, 0, SetLGPThread, (LPVOID)¶ms, 0, NULL); | ||||||
|  | 	DWORD r = FALSE; | ||||||
|  | 	if (thread_id == NULL) { | ||||||
|  | 		uprintf("SetLGP: Unable to start thread"); | ||||||
|  | 		return FALSE; | ||||||
|  | 	} | ||||||
|  | 	if (WaitForSingleObject(thread_id, 2500) != WAIT_OBJECT_0) { | ||||||
|  | 		uprintf("SetLGP: Killing stuck thread!"); | ||||||
|  | 		TerminateThread(thread_id, 0); | ||||||
|  | 		CloseHandle(thread_id); | ||||||
|  | 		return FALSE; | ||||||
|  | 	} | ||||||
|  | 	GetExitCodeThread(thread_id, &r); | ||||||
|  | 	return (BOOL) r; | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue