Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygengpolicy.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2006 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* 00020 * COPYRIGHT: See COPYING in the top level directory 00021 * PROJECT: ReactOS system libraries 00022 * FILE: lib/userenv/gpolicy.c 00023 * PURPOSE: Group policy functions 00024 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com> 00025 */ 00026 00027 #include <precomp.h> 00028 00029 #define NDEBUG 00030 #include <debug.h> 00031 00032 00033 typedef struct _GP_NOTIFY 00034 { 00035 struct _GP_NOTIFY *Next; 00036 HANDLE hEvent; 00037 BOOL bMachine; 00038 } GP_NOTIFY, *PGP_NOTIFY; 00039 00040 typedef enum 00041 { 00042 gpaUpdate = 0, 00043 gpaTerminate 00044 } GP_ACTION; 00045 00046 static const WCHAR szLocalGPApplied[] = L"userenv: User Group Policy has been applied"; 00047 static const WCHAR szLocalGPMutex[] = L"userenv: user policy mutex"; 00048 static const WCHAR szLocalGPRefreshEvent[] = L"userenv: user policy refresh event"; 00049 static const WCHAR szLocalGPForceRefreshEvent[] = L"userenv: user policy force refresh event"; 00050 static const WCHAR szLocalGPDoneEvent[] = L"userenv: User Policy Foreground Done Event"; 00051 static const WCHAR szMachineGPApplied[] = L"Global\\userenv: Machine Group Policy has been applied"; 00052 static const WCHAR szMachineGPMutex[] = L"Global\\userenv: machine policy mutex"; 00053 static const WCHAR szMachineGPRefreshEvent[] = L"Global\\userenv: machine policy refresh event"; 00054 static const WCHAR szMachineGPForceRefreshEvent[] = L"Global\\userenv: machine policy force refresh event"; 00055 static const WCHAR szMachineGPDoneEvent[] = L"Global\\userenv: Machine Policy Foreground Done Event"; 00056 00057 static CRITICAL_SECTION GPNotifyLock; 00058 static PGP_NOTIFY NotificationList = NULL; 00059 static GP_ACTION GPNotificationAction = gpaUpdate; 00060 static HANDLE hNotificationThread = NULL; 00061 static HANDLE hNotificationThreadEvent = NULL; 00062 static HANDLE hLocalGPAppliedEvent = NULL; 00063 static HANDLE hMachineGPAppliedEvent = NULL; 00064 00065 VOID 00066 InitializeGPNotifications(VOID) 00067 { 00068 InitializeCriticalSection(&GPNotifyLock); 00069 } 00070 00071 VOID 00072 UninitializeGPNotifications(VOID) 00073 { 00074 EnterCriticalSection(&GPNotifyLock); 00075 00076 /* rundown the notification thread */ 00077 if (hNotificationThread != NULL) 00078 { 00079 ASSERT(hNotificationThreadEvent != NULL); 00080 00081 /* notify the thread */ 00082 GPNotificationAction = gpaTerminate; 00083 SetEvent(hNotificationThreadEvent); 00084 00085 LeaveCriticalSection(&GPNotifyLock); 00086 00087 /* wait for the thread to terminate itself */ 00088 WaitForSingleObject(hNotificationThread, 00089 INFINITE); 00090 00091 EnterCriticalSection(&GPNotifyLock); 00092 00093 if (hNotificationThread != NULL) 00094 { 00095 /* the handle should be closed by the thread, 00096 just in case that didn't happen for an unknown reason */ 00097 CloseHandle(hNotificationThread); 00098 hNotificationThread = NULL; 00099 } 00100 } 00101 00102 if (hNotificationThreadEvent != NULL) 00103 { 00104 CloseHandle(hNotificationThreadEvent); 00105 hNotificationThreadEvent = NULL; 00106 } 00107 00108 LeaveCriticalSection(&GPNotifyLock); 00109 00110 DeleteCriticalSection(&GPNotifyLock); 00111 } 00112 00113 static VOID 00114 NotifyGPEvents(IN BOOL bMachine) 00115 { 00116 PGP_NOTIFY Notify = NotificationList; 00117 00118 while (Notify != NULL) 00119 { 00120 if (Notify->bMachine == bMachine) 00121 { 00122 SetEvent(Notify->hEvent); 00123 } 00124 00125 Notify = Notify->Next; 00126 } 00127 } 00128 00129 static DWORD WINAPI 00130 GPNotificationThreadProc(IN LPVOID lpParameter) 00131 { 00132 HMODULE hModule; 00133 DWORD WaitResult, WaitCount; 00134 HANDLE WaitHandles[3]; 00135 00136 /* reference the library so we don't screw up if the application 00137 causes the DLL to unload while this thread is still running */ 00138 if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, 00139 (LPCWSTR)hInstance, 00140 &hModule)) 00141 { 00142 ASSERT(hModule == hInstance); 00143 00144 EnterCriticalSection(&GPNotifyLock); 00145 00146 ASSERT(hNotificationThreadEvent != NULL); 00147 WaitHandles[0] = hNotificationThreadEvent; 00148 for (;;) 00149 { 00150 ASSERT(hMachineGPAppliedEvent != NULL); 00151 00152 if (NotificationList == NULL) 00153 break; 00154 00155 WaitCount = 2; 00156 WaitHandles[1] = hMachineGPAppliedEvent; 00157 00158 if (hLocalGPAppliedEvent != NULL) 00159 { 00160 WaitHandles[2] = hLocalGPAppliedEvent; 00161 WaitCount++; 00162 } 00163 00164 LeaveCriticalSection(&GPNotifyLock); 00165 00166 WaitResult = WaitForMultipleObjects(WaitCount, 00167 WaitHandles, 00168 FALSE, 00169 INFINITE); 00170 00171 EnterCriticalSection(&GPNotifyLock); 00172 00173 if (WaitResult != WAIT_FAILED) 00174 { 00175 if (WaitResult == WAIT_OBJECT_0) 00176 { 00177 ResetEvent(hNotificationThreadEvent); 00178 00179 if (GPNotificationAction == gpaTerminate) 00180 { 00181 /* terminate the thread */ 00182 break; 00183 } 00184 } 00185 else if (WaitResult == WAIT_OBJECT_0 + 1 || WaitResult == WAIT_OBJECT_0 + 2) 00186 { 00187 /* group policies have been applied */ 00188 if (NotificationList != NULL) 00189 { 00190 NotifyGPEvents((WaitResult == WAIT_OBJECT_0 + 1)); 00191 } 00192 } 00193 else if (WaitResult == WAIT_ABANDONED_0 + 2) 00194 { 00195 /* In case the local group policies event was abandoned, keep watching! 00196 But close the handle as it's no longer of any use. */ 00197 if (hLocalGPAppliedEvent != NULL) 00198 { 00199 CloseHandle(hLocalGPAppliedEvent); 00200 hLocalGPAppliedEvent = NULL; 00201 } 00202 } 00203 else if (WaitResult == WAIT_ABANDONED_0 || WaitResult == WAIT_ABANDONED_0 + 1) 00204 { 00205 /* terminate the thread if the machine group policies event was abandoned 00206 or for some reason the rundown event got abandoned. */ 00207 break; 00208 } 00209 else 00210 { 00211 DPRINT("Unexpected wait result watching the group policy events: 0x%x\n", WaitResult); 00212 ASSERT(FALSE); 00213 break; 00214 } 00215 00216 if (NotificationList == NULL) 00217 break; 00218 } 00219 else 00220 break; 00221 00222 } 00223 00224 /* cleanup handles no longer used */ 00225 ASSERT(hNotificationThread != NULL); 00226 ASSERT(hNotificationThreadEvent != NULL); 00227 00228 CloseHandle(hNotificationThread); 00229 CloseHandle(hNotificationThreadEvent); 00230 hNotificationThread = NULL; 00231 hNotificationThreadEvent = NULL; 00232 00233 if (hLocalGPAppliedEvent != NULL) 00234 { 00235 CloseHandle(hLocalGPAppliedEvent); 00236 hLocalGPAppliedEvent = NULL; 00237 } 00238 if (hMachineGPAppliedEvent != NULL) 00239 { 00240 CloseHandle(hMachineGPAppliedEvent); 00241 hMachineGPAppliedEvent = NULL; 00242 } 00243 00244 LeaveCriticalSection(&GPNotifyLock); 00245 00246 /* dereference the library and exit */ 00247 FreeLibraryAndExitThread(hModule, 00248 0); 00249 } 00250 else 00251 { 00252 DPRINT1("Referencing the library failed!\n"); 00253 } 00254 00255 return 1; 00256 } 00257 00258 static HANDLE 00259 CreateGPEvent(IN BOOL bMachine, 00260 IN PSECURITY_DESCRIPTOR lpSecurityDescriptor) 00261 { 00262 HANDLE hEvent; 00263 SECURITY_ATTRIBUTES SecurityAttributes; 00264 00265 SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); 00266 SecurityAttributes.lpSecurityDescriptor = lpSecurityDescriptor; 00267 SecurityAttributes.bInheritHandle = FALSE; 00268 00269 hEvent = CreateEventW(&SecurityAttributes, 00270 TRUE, 00271 FALSE, 00272 (bMachine ? szMachineGPApplied : szLocalGPApplied)); 00273 00274 return hEvent; 00275 } 00276 00277 BOOL WINAPI 00278 RegisterGPNotification(IN HANDLE hEvent, 00279 IN BOOL bMachine) 00280 { 00281 PGP_NOTIFY Notify; 00282 PSECURITY_DESCRIPTOR lpSecurityDescriptor = NULL; 00283 BOOL Ret = FALSE; 00284 00285 EnterCriticalSection(&GPNotifyLock); 00286 00287 /* create the thread notification event */ 00288 if (hNotificationThreadEvent == NULL) 00289 { 00290 hNotificationThreadEvent = CreateEvent(NULL, 00291 TRUE, 00292 FALSE, 00293 NULL); 00294 if (hNotificationThreadEvent == NULL) 00295 { 00296 goto Cleanup; 00297 } 00298 } 00299 00300 /* create or open the machine group policy event */ 00301 if (hMachineGPAppliedEvent == NULL) 00302 { 00303 lpSecurityDescriptor = CreateDefaultSecurityDescriptor(); 00304 if (lpSecurityDescriptor == NULL) 00305 { 00306 goto Cleanup; 00307 } 00308 00309 hMachineGPAppliedEvent = CreateGPEvent(TRUE, 00310 lpSecurityDescriptor); 00311 if (hMachineGPAppliedEvent == NULL) 00312 { 00313 goto Cleanup; 00314 } 00315 } 00316 00317 /* create or open the local group policy event only if necessary */ 00318 if (!bMachine && hLocalGPAppliedEvent == NULL) 00319 { 00320 if (lpSecurityDescriptor == NULL) 00321 { 00322 lpSecurityDescriptor = CreateDefaultSecurityDescriptor(); 00323 if (lpSecurityDescriptor == NULL) 00324 { 00325 goto Cleanup; 00326 } 00327 } 00328 00329 hLocalGPAppliedEvent = CreateGPEvent(FALSE, 00330 lpSecurityDescriptor); 00331 if (hLocalGPAppliedEvent == NULL) 00332 { 00333 goto Cleanup; 00334 } 00335 } 00336 00337 if (hNotificationThread == NULL) 00338 { 00339 hNotificationThread = CreateThread(NULL, 00340 0, 00341 GPNotificationThreadProc, 00342 NULL, 00343 0, 00344 NULL); 00345 } 00346 00347 if (hNotificationThread != NULL) 00348 { 00349 Notify = (PGP_NOTIFY)LocalAlloc(LMEM_FIXED, 00350 sizeof(GP_NOTIFY)); 00351 if (Notify != NULL) 00352 { 00353 /* add the item to the beginning of the list */ 00354 Notify->Next = NotificationList; 00355 Notify->hEvent = hEvent; 00356 Notify->bMachine = bMachine; 00357 00358 NotificationList = Notify; 00359 00360 /* notify the thread */ 00361 GPNotificationAction = gpaUpdate; 00362 SetEvent(hNotificationThreadEvent); 00363 00364 Ret = TRUE; 00365 } 00366 } 00367 00368 Cleanup: 00369 LeaveCriticalSection(&GPNotifyLock); 00370 00371 if (lpSecurityDescriptor != NULL) 00372 { 00373 LocalFree((HLOCAL)lpSecurityDescriptor); 00374 } 00375 00376 /* NOTE: don't delete the events or close the handles created */ 00377 00378 return Ret; 00379 } 00380 00381 BOOL WINAPI 00382 UnregisterGPNotification(IN HANDLE hEvent) 00383 { 00384 PGP_NOTIFY Notify = NULL, *NotifyLink; 00385 BOOL Ret = FALSE; 00386 00387 EnterCriticalSection(&GPNotifyLock); 00388 00389 Notify = NotificationList; 00390 NotifyLink = &NotificationList; 00391 00392 while (Notify != NULL) 00393 { 00394 if (Notify->hEvent == hEvent) 00395 { 00396 /* remove and free the item */ 00397 *NotifyLink = Notify->Next; 00398 LocalFree((HLOCAL)Notify); 00399 00400 /* notify the thread */ 00401 if (hNotificationThread != NULL && 00402 hNotificationThreadEvent != NULL) 00403 { 00404 GPNotificationAction = gpaUpdate; 00405 SetEvent(hNotificationThreadEvent); 00406 } 00407 00408 Ret = TRUE; 00409 break; 00410 } 00411 00412 NotifyLink = &Notify->Next; 00413 Notify = Notify->Next; 00414 } 00415 00416 LeaveCriticalSection(&GPNotifyLock); 00417 00418 return Ret; 00419 } 00420 00421 BOOL WINAPI 00422 RefreshPolicy(IN BOOL bMachine) 00423 { 00424 HANDLE hEvent; 00425 BOOL Ret = TRUE; 00426 00427 hEvent = OpenEventW(EVENT_MODIFY_STATE, 00428 FALSE, 00429 (bMachine ? szMachineGPRefreshEvent : szLocalGPRefreshEvent)); 00430 if (hEvent != NULL) 00431 { 00432 Ret = SetEvent(hEvent); 00433 CloseHandle(hEvent); 00434 } 00435 00436 /* return TRUE even if the mutex doesn't exist! */ 00437 return Ret; 00438 } 00439 00440 BOOL WINAPI 00441 RefreshPolicyEx(IN BOOL bMachine, 00442 IN DWORD dwOptions) 00443 { 00444 if (dwOptions & ~RP_FORCE) 00445 { 00446 SetLastError(ERROR_INVALID_PARAMETER); 00447 return FALSE; 00448 } 00449 00450 if (dwOptions & RP_FORCE) 00451 { 00452 HANDLE hEvent; 00453 BOOL Ret = TRUE; 00454 00455 hEvent = OpenEventW(EVENT_MODIFY_STATE, 00456 FALSE, 00457 (bMachine ? szMachineGPForceRefreshEvent : szLocalGPForceRefreshEvent)); 00458 if (hEvent != NULL) 00459 { 00460 Ret = SetEvent(hEvent); 00461 CloseHandle(hEvent); 00462 } 00463 00464 /* return TRUE even if the mutex doesn't exist! */ 00465 return Ret; 00466 } 00467 else 00468 { 00469 return RefreshPolicy(bMachine); 00470 } 00471 } 00472 00473 HANDLE WINAPI 00474 EnterCriticalPolicySection(IN BOOL bMachine) 00475 { 00476 SECURITY_ATTRIBUTES SecurityAttributes; 00477 PSECURITY_DESCRIPTOR lpSecurityDescriptor; 00478 HANDLE hSection; 00479 00480 /* create or open the mutex */ 00481 lpSecurityDescriptor = CreateDefaultSecurityDescriptor(); 00482 if (lpSecurityDescriptor != NULL) 00483 { 00484 SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); 00485 SecurityAttributes.lpSecurityDescriptor = lpSecurityDescriptor; 00486 SecurityAttributes.bInheritHandle = FALSE; 00487 00488 hSection = CreateMutexW(&SecurityAttributes, 00489 FALSE, 00490 (bMachine ? szMachineGPMutex : szLocalGPMutex)); 00491 00492 LocalFree((HLOCAL)lpSecurityDescriptor); 00493 00494 if (hSection != NULL) 00495 { 00496 /* wait up to 10 minutes */ 00497 if (WaitForSingleObject(hSection, 00498 600000) != WAIT_FAILED) 00499 { 00500 return hSection; 00501 } 00502 00503 CloseHandle(hSection); 00504 } 00505 } 00506 00507 return NULL; 00508 } 00509 00510 BOOL WINAPI 00511 LeaveCriticalPolicySection(IN HANDLE hSection) 00512 { 00513 BOOL Ret; 00514 00515 if (hSection == NULL) 00516 { 00517 SetLastError(ERROR_INVALID_PARAMETER); 00518 return FALSE; 00519 } 00520 00521 Ret = ReleaseMutex(hSection); 00522 CloseHandle(hSection); 00523 00524 return Ret; 00525 } 00526 00527 BOOL WINAPI 00528 WaitForUserPolicyForegroundProcessing(VOID) 00529 { 00530 HANDLE hEvent; 00531 BOOL Ret = FALSE; 00532 00533 hEvent = OpenEventW(SYNCHRONIZE, 00534 FALSE, 00535 szLocalGPDoneEvent); 00536 if (hEvent != NULL) 00537 { 00538 Ret = WaitForSingleObject(hEvent, 00539 INFINITE) != WAIT_FAILED; 00540 CloseHandle(hEvent); 00541 } 00542 00543 return Ret; 00544 } 00545 00546 BOOL WINAPI 00547 WaitForMachinePolicyForegroundProcessing(VOID) 00548 { 00549 HANDLE hEvent; 00550 BOOL Ret = FALSE; 00551 00552 hEvent = OpenEventW(SYNCHRONIZE, 00553 FALSE, 00554 szMachineGPDoneEvent); 00555 if (hEvent != NULL) 00556 { 00557 Ret = WaitForSingleObject(hEvent, 00558 INFINITE) != WAIT_FAILED; 00559 CloseHandle(hEvent); 00560 } 00561 00562 return Ret; 00563 } Generated on Sat May 26 2012 04:25:17 for ReactOS by
1.7.6.1
|