ReactOS 0.4.15-dev-7968-g24a56f8
gpolicy.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2006 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19/*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS system libraries
22 * FILE: dll/win32/userenv/gpolicy.c
23 * PURPOSE: Group policy functions
24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
25 */
26
27#include "precomp.h"
28
29#define NDEBUG
30#include <debug.h>
31
32typedef struct _GP_NOTIFY
33{
38
39typedef enum
40{
44
45static const WCHAR szLocalGPApplied[] = L"userenv: User Group Policy has been applied";
46static const WCHAR szLocalGPMutex[] = L"userenv: user policy mutex";
47static const WCHAR szLocalGPRefreshEvent[] = L"userenv: user policy refresh event";
48static const WCHAR szLocalGPForceRefreshEvent[] = L"userenv: user policy force refresh event";
49static const WCHAR szLocalGPDoneEvent[] = L"userenv: User Policy Foreground Done Event";
50static const WCHAR szMachineGPApplied[] = L"Global\\userenv: Machine Group Policy has been applied";
51static const WCHAR szMachineGPMutex[] = L"Global\\userenv: machine policy mutex";
52static const WCHAR szMachineGPRefreshEvent[] = L"Global\\userenv: machine policy refresh event";
53static const WCHAR szMachineGPForceRefreshEvent[] = L"Global\\userenv: machine policy force refresh event";
54static const WCHAR szMachineGPDoneEvent[] = L"Global\\userenv: Machine Policy Foreground Done Event";
55
63
64VOID
66{
68}
69
70VOID
72{
74
75 /* rundown the notification thread */
77 {
79
80 /* notify the thread */
83
85
86 /* wait for the thread to terminate itself */
88 INFINITE);
89
91
93 {
94 /* the handle should be closed by the thread,
95 just in case that didn't happen for an unknown reason */
98 }
99 }
100
102 {
105 }
106
108
110}
111
112static
113VOID
115{
117
118 while (Notify != NULL)
119 {
120 if (Notify->bMachine == bMachine)
121 {
122 SetEvent(Notify->hEvent);
123 }
124
125 Notify = Notify->Next;
126 }
127}
128
129static
130DWORD
131WINAPI
133{
135 DWORD WaitResult, WaitCount;
136 HANDLE WaitHandles[3];
137
138 /* reference the library so we don't screw up if the application
139 causes the DLL to unload while this thread is still running */
140 if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
142 &hModule))
143 {
145
147
149 WaitHandles[0] = hNotificationThreadEvent;
150 for (;;)
151 {
153
154 if (NotificationList == NULL)
155 break;
156
157 WaitCount = 2;
158 WaitHandles[1] = hMachineGPAppliedEvent;
159
161 {
162 WaitHandles[2] = hLocalGPAppliedEvent;
163 WaitCount++;
164 }
165
167
168 WaitResult = WaitForMultipleObjects(WaitCount,
169 WaitHandles,
170 FALSE,
171 INFINITE);
172
174
175 if (WaitResult != WAIT_FAILED)
176 {
177 if (WaitResult == WAIT_OBJECT_0)
178 {
180
182 {
183 /* terminate the thread */
184 break;
185 }
186 }
187 else if (WaitResult == WAIT_OBJECT_0 + 1 || WaitResult == WAIT_OBJECT_0 + 2)
188 {
189 /* group policies have been applied */
190 if (NotificationList != NULL)
191 {
192 NotifyGPEvents((WaitResult == WAIT_OBJECT_0 + 1));
193 }
194 }
195 else if (WaitResult == WAIT_ABANDONED_0 + 2)
196 {
197 /* In case the local group policies event was abandoned, keep watching!
198 But close the handle as it's no longer of any use. */
200 {
203 }
204 }
205 else if (WaitResult == WAIT_ABANDONED_0 || WaitResult == WAIT_ABANDONED_0 + 1)
206 {
207 /* terminate the thread if the machine group policies event was abandoned
208 or for some reason the rundown event got abandoned. */
209 break;
210 }
211 else
212 {
213 DPRINT("Unexpected wait result watching the group policy events: 0x%x\n", WaitResult);
214 ASSERT(FALSE);
215 break;
216 }
217
218 if (NotificationList == NULL)
219 break;
220 }
221 else
222 break;
223
224 }
225
226 /* cleanup handles no longer used */
229
234
236 {
239 }
241 {
244 }
245
247
248 /* dereference the library and exit */
250 0);
251 }
252 else
253 {
254 DPRINT1("Referencing the library failed!\n");
255 }
256
257 return 1;
258}
259
260static
261HANDLE
263 IN PSECURITY_DESCRIPTOR lpSecurityDescriptor)
264{
266 SECURITY_ATTRIBUTES SecurityAttributes;
267
268 SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
269 SecurityAttributes.lpSecurityDescriptor = lpSecurityDescriptor;
270 SecurityAttributes.bInheritHandle = FALSE;
271
272 hEvent = CreateEventW(&SecurityAttributes,
273 TRUE,
274 FALSE,
276
277 return hEvent;
278}
279
280BOOL
281WINAPI
284{
286 PSECURITY_DESCRIPTOR lpSecurityDescriptor = NULL;
287 BOOL Ret = FALSE;
288
290
291 /* create the thread notification event */
293 {
295 TRUE,
296 FALSE,
297 NULL);
299 {
300 goto Cleanup;
301 }
302 }
303
304 /* create or open the machine group policy event */
306 {
307 lpSecurityDescriptor = CreateDefaultSecurityDescriptor();
308 if (lpSecurityDescriptor == NULL)
309 {
310 goto Cleanup;
311 }
312
314 lpSecurityDescriptor);
316 {
317 goto Cleanup;
318 }
319 }
320
321 /* create or open the local group policy event only if necessary */
323 {
324 if (lpSecurityDescriptor == NULL)
325 {
326 lpSecurityDescriptor = CreateDefaultSecurityDescriptor();
327 if (lpSecurityDescriptor == NULL)
328 {
329 goto Cleanup;
330 }
331 }
332
334 lpSecurityDescriptor);
336 {
337 goto Cleanup;
338 }
339 }
340
342 {
344 0,
346 NULL,
347 0,
348 NULL);
349 }
350
352 {
354 sizeof(GP_NOTIFY));
355 if (Notify != NULL)
356 {
357 /* add the item to the beginning of the list */
358 Notify->Next = NotificationList;
359 Notify->hEvent = hEvent;
360 Notify->bMachine = bMachine;
361
363
364 /* notify the thread */
367
368 Ret = TRUE;
369 }
370 }
371
372Cleanup:
374
375 if (lpSecurityDescriptor != NULL)
376 {
377 LocalFree((HLOCAL)lpSecurityDescriptor);
378 }
379
380 /* NOTE: don't delete the events or close the handles created */
381
382 return Ret;
383}
384
385BOOL
386WINAPI
388{
389 PGP_NOTIFY Notify = NULL, *NotifyLink;
390 BOOL Ret = FALSE;
391
393
395 NotifyLink = &NotificationList;
396
397 while (Notify != NULL)
398 {
399 if (Notify->hEvent == hEvent)
400 {
401 /* remove and free the item */
402 *NotifyLink = Notify->Next;
404
405 /* notify the thread */
406 if (hNotificationThread != NULL &&
408 {
411 }
412
413 Ret = TRUE;
414 break;
415 }
416
417 NotifyLink = &Notify->Next;
418 Notify = Notify->Next;
419 }
420
422
423 return Ret;
424}
425
426BOOL
427WINAPI
429{
431 BOOL Ret = TRUE;
432
434 FALSE,
436 if (hEvent != NULL)
437 {
438 Ret = SetEvent(hEvent);
440 }
441
442 /* return TRUE even if the mutex doesn't exist! */
443 return Ret;
444}
445
446BOOL
447WINAPI
450{
451 if (dwOptions & ~RP_FORCE)
452 {
454 return FALSE;
455 }
456
457 if (dwOptions & RP_FORCE)
458 {
460 BOOL Ret = TRUE;
461
463 FALSE,
465 if (hEvent != NULL)
466 {
467 Ret = SetEvent(hEvent);
469 }
470
471 /* return TRUE even if the mutex doesn't exist! */
472 return Ret;
473 }
474 else
475 {
476 return RefreshPolicy(bMachine);
477 }
478}
479
480HANDLE
481WINAPI
483{
484 SECURITY_ATTRIBUTES SecurityAttributes;
485 PSECURITY_DESCRIPTOR lpSecurityDescriptor;
487
488 /* create or open the mutex */
489 lpSecurityDescriptor = CreateDefaultSecurityDescriptor();
490 if (lpSecurityDescriptor != NULL)
491 {
492 SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
493 SecurityAttributes.lpSecurityDescriptor = lpSecurityDescriptor;
494 SecurityAttributes.bInheritHandle = FALSE;
495
496 hSection = CreateMutexW(&SecurityAttributes,
497 FALSE,
499
500 LocalFree((HLOCAL)lpSecurityDescriptor);
501
502 if (hSection != NULL)
503 {
504 /* wait up to 10 minutes */
506 600000) != WAIT_FAILED)
507 {
508 return hSection;
509 }
510
512 }
513 }
514
515 return NULL;
516}
517
518BOOL
519WINAPI
521{
522 BOOL Ret;
523
524 if (hSection == NULL)
525 {
527 return FALSE;
528 }
529
530 Ret = ReleaseMutex(hSection);
532
533 return Ret;
534}
535
536BOOL
537WINAPI
539{
541 BOOL Ret = FALSE;
542
544 FALSE,
546 if (hEvent != NULL)
547 {
551 }
552
553 return Ret;
554}
555
556BOOL
557WINAPI
559{
561 BOOL Ret = FALSE;
562
564 FALSE,
566 if (hEvent != NULL)
567 {
571 }
572
573 return Ret;
574}
575
576DWORD
577WINAPI
580 _In_ LPCSTR pMachineName,
581 _In_ PSID pSidUser,
582 _In_ GUID *pGuidExtension,
583 _Out_ PGROUP_POLICY_OBJECTA *ppGPOList
584)
585{
586 DPRINT1("GetAppliedGPOListA is UNIMPLEMENTED!\n");
588}
589
590DWORD
591WINAPI
594 _In_ LPCWSTR pMachineName,
595 _In_ PSID pSidUser,
596 _In_ GUID *pGuidExtension,
597 _Out_ PGROUP_POLICY_OBJECTW *ppGPOList
598)
599{
600 DPRINT1("GetAppliedGPOListW is UNIMPLEMENTED!\n");
602}
#define DPRINT1
Definition: precomp.h:8
HINSTANCE hInstance
Definition: charmap.c:19
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI SHIM_OBJ_NAME() Notify(DWORD fdwReason, PVOID ptr)
HMODULE hModule
Definition: animate.c:44
#define CloseHandle
Definition: compat.h:739
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
#define SetLastError(x)
Definition: compat.h:752
BOOL WINAPI GetModuleHandleExW(IN DWORD dwFlags, IN LPCWSTR lpwModuleName OPTIONAL, OUT HMODULE *phModule)
Definition: loader.c:866
VOID WINAPI FreeLibraryAndExitThread(HMODULE hLibModule, DWORD dwExitCode)
Definition: loader.c:507
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
PSECURITY_DESCRIPTOR CreateDefaultSecurityDescriptor(VOID)
Definition: misc.c:57
static const WCHAR Cleanup[]
Definition: register.c:80
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
static HANDLE hMachineGPAppliedEvent
Definition: gpolicy.c:62
static HANDLE hNotificationThread
Definition: gpolicy.c:59
static PGP_NOTIFY NotificationList
Definition: gpolicy.c:57
HANDLE WINAPI EnterCriticalPolicySection(IN BOOL bMachine)
Definition: gpolicy.c:482
static const WCHAR szMachineGPForceRefreshEvent[]
Definition: gpolicy.c:53
static HANDLE CreateGPEvent(IN BOOL bMachine, IN PSECURITY_DESCRIPTOR lpSecurityDescriptor)
Definition: gpolicy.c:262
static const WCHAR szMachineGPRefreshEvent[]
Definition: gpolicy.c:52
DWORD WINAPI GetAppliedGPOListW(_In_ DWORD dwFlags, _In_ LPCWSTR pMachineName, _In_ PSID pSidUser, _In_ GUID *pGuidExtension, _Out_ PGROUP_POLICY_OBJECTW *ppGPOList)
Definition: gpolicy.c:592
struct _GP_NOTIFY GP_NOTIFY
GP_ACTION
Definition: gpolicy.c:40
@ gpaTerminate
Definition: gpolicy.c:42
@ gpaUpdate
Definition: gpolicy.c:41
BOOL WINAPI RefreshPolicyEx(IN BOOL bMachine, IN DWORD dwOptions)
Definition: gpolicy.c:448
BOOL WINAPI WaitForMachinePolicyForegroundProcessing(VOID)
Definition: gpolicy.c:558
static VOID NotifyGPEvents(IN BOOL bMachine)
Definition: gpolicy.c:114
static const WCHAR szLocalGPApplied[]
Definition: gpolicy.c:45
BOOL WINAPI RefreshPolicy(IN BOOL bMachine)
Definition: gpolicy.c:428
VOID InitializeGPNotifications(VOID)
Definition: gpolicy.c:65
static HANDLE hLocalGPAppliedEvent
Definition: gpolicy.c:61
static const WCHAR szLocalGPForceRefreshEvent[]
Definition: gpolicy.c:48
struct _GP_NOTIFY * PGP_NOTIFY
DWORD WINAPI GetAppliedGPOListA(_In_ DWORD dwFlags, _In_ LPCSTR pMachineName, _In_ PSID pSidUser, _In_ GUID *pGuidExtension, _Out_ PGROUP_POLICY_OBJECTA *ppGPOList)
Definition: gpolicy.c:578
static const WCHAR szMachineGPDoneEvent[]
Definition: gpolicy.c:54
static DWORD WINAPI GPNotificationThreadProc(IN LPVOID lpParameter)
Definition: gpolicy.c:132
static CRITICAL_SECTION GPNotifyLock
Definition: gpolicy.c:56
static const WCHAR szMachineGPMutex[]
Definition: gpolicy.c:51
VOID UninitializeGPNotifications(VOID)
Definition: gpolicy.c:71
BOOL WINAPI UnregisterGPNotification(IN HANDLE hEvent)
Definition: gpolicy.c:387
static GP_ACTION GPNotificationAction
Definition: gpolicy.c:58
static const WCHAR szLocalGPDoneEvent[]
Definition: gpolicy.c:49
BOOL WINAPI WaitForUserPolicyForegroundProcessing(VOID)
Definition: gpolicy.c:538
BOOL WINAPI RegisterGPNotification(IN HANDLE hEvent, IN BOOL bMachine)
Definition: gpolicy.c:282
static const WCHAR szMachineGPApplied[]
Definition: gpolicy.c:50
static const WCHAR szLocalGPMutex[]
Definition: gpolicy.c:46
BOOL WINAPI LeaveCriticalPolicySection(IN HANDLE hSection)
Definition: gpolicy.c:520
static HANDLE hNotificationThreadEvent
Definition: gpolicy.c:60
static const WCHAR szLocalGPRefreshEvent[]
Definition: gpolicy.c:47
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
static PCWSTR BOOL bMachine
Definition: layerapi.c:34
#define ASSERT(a)
Definition: mode.c:44
static HANDLE hEvent
Definition: comm.c:54
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define SYNCHRONIZE
Definition: nt_native.h:61
#define L(x)
Definition: ntvdm.h:50
#define DPRINT
Definition: sndvol32.h:71
DWORD dwOptions
Definition: solitaire.cpp:25
HANDLE hEvent
Definition: gpolicy.c:35
struct _GP_NOTIFY * Next
Definition: gpolicy.c:34
BOOL bMachine
Definition: gpolicy.c:36
LPVOID lpSecurityDescriptor
Definition: compat.h:193
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:682
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:576
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:618
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
#define IN
Definition: typedefs.h:39
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define EVENT_MODIFY_STATE
Definition: winbase.h:163
#define CreateEvent
Definition: winbase.h:3748
#define WAIT_ABANDONED_0
Definition: winbase.h:407
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define WAIT_OBJECT_0
Definition: winbase.h:406
#define WAIT_FAILED
Definition: winbase.h:413
#define LMEM_FIXED
Definition: winbase.h:368
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define WINAPI
Definition: msvc.h:6
_In_ const BITMAPINFO _In_ UINT _In_opt_ HANDLE hSection
Definition: wingdi.h:3239
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185