ReactOS  0.4.13-dev-257-gfabbd7c
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 
32 typedef struct _GP_NOTIFY
33 {
34  struct _GP_NOTIFY *Next;
38 
39 typedef enum
40 {
41  gpaUpdate = 0,
43 } GP_ACTION;
44 
45 static const WCHAR szLocalGPApplied[] = L"userenv: User Group Policy has been applied";
46 static const WCHAR szLocalGPMutex[] = L"userenv: user policy mutex";
47 static const WCHAR szLocalGPRefreshEvent[] = L"userenv: user policy refresh event";
48 static const WCHAR szLocalGPForceRefreshEvent[] = L"userenv: user policy force refresh event";
49 static const WCHAR szLocalGPDoneEvent[] = L"userenv: User Policy Foreground Done Event";
50 static const WCHAR szMachineGPApplied[] = L"Global\\userenv: Machine Group Policy has been applied";
51 static const WCHAR szMachineGPMutex[] = L"Global\\userenv: machine policy mutex";
52 static const WCHAR szMachineGPRefreshEvent[] = L"Global\\userenv: machine policy refresh event";
53 static const WCHAR szMachineGPForceRefreshEvent[] = L"Global\\userenv: machine policy force refresh event";
54 static const WCHAR szMachineGPDoneEvent[] = L"Global\\userenv: Machine Policy Foreground Done Event";
55 
63 
64 VOID
66 {
68 }
69 
70 VOID
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 
112 static
113 VOID
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 
129 static
130 DWORD
131 WINAPI
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 
160  if (hLocalGPAppliedEvent != NULL)
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. */
199  if (hLocalGPAppliedEvent != NULL)
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 
235  if (hLocalGPAppliedEvent != NULL)
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 
260 static
261 HANDLE
263  IN PSECURITY_DESCRIPTOR lpSecurityDescriptor)
264 {
265  HANDLE hEvent;
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 
280 BOOL
281 WINAPI
283  IN BOOL bMachine)
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);
335  if (hLocalGPAppliedEvent == NULL)
336  {
337  goto Cleanup;
338  }
339  }
340 
341  if (hNotificationThread == NULL)
342  {
344  0,
346  NULL,
347  0,
348  NULL);
349  }
350 
351  if (hNotificationThread != NULL)
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 
372 Cleanup:
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 
385 BOOL
386 WINAPI
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 
426 BOOL
427 WINAPI
429 {
430  HANDLE hEvent;
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 
446 BOOL
447 WINAPI
450 {
451  if (dwOptions & ~RP_FORCE)
452  {
454  return FALSE;
455  }
456 
457  if (dwOptions & RP_FORCE)
458  {
459  HANDLE hEvent;
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 
480 HANDLE
481 WINAPI
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 
518 BOOL
519 WINAPI
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 
536 BOOL
537 WINAPI
539 {
540  HANDLE hEvent;
541  BOOL Ret = FALSE;
542 
544  FALSE,
546  if (hEvent != NULL)
547  {
549  INFINITE) != WAIT_FAILED;
551  }
552 
553  return Ret;
554 }
555 
556 BOOL
557 WINAPI
559 {
560  HANDLE hEvent;
561  BOOL Ret = FALSE;
562 
564  FALSE,
566  if (hEvent != NULL)
567  {
569  INFINITE) != WAIT_FAILED;
571  }
572 
573  return Ret;
574 }
575 
576 DWORD
577 WINAPI
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 
590 DWORD
591 WINAPI
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 CreateEvent
Definition: winbase.h:3562
static const WCHAR szMachineGPApplied[]
Definition: gpolicy.c:50
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
BOOL WINAPI SHIM_OBJ_NAME() Notify(DWORD fdwReason, PVOID ptr)
DWORD dwOptions
Definition: solitaire.cpp:23
static const WCHAR szMachineGPDoneEvent[]
Definition: gpolicy.c:54
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
BOOL WINAPI RegisterGPNotification(IN HANDLE hEvent, IN BOOL bMachine)
Definition: gpolicy.c:282
struct _GP_NOTIFY * PGP_NOTIFY
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static const WCHAR szMachineGPRefreshEvent[]
Definition: gpolicy.c:52
static const WCHAR szLocalGPRefreshEvent[]
Definition: gpolicy.c:47
DWORD WINAPI GetAppliedGPOListA(_In_ DWORD dwFlags, _In_ LPCSTR pMachineName, _In_ PSID pSidUser, _In_ GUID *pGuidExtension, _Out_ PGROUP_POLICY_OBJECTA *ppGPOList)
Definition: gpolicy.c:578
VOID InitializeGPNotifications(VOID)
Definition: gpolicy.c:65
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
BOOL WINAPI WaitForMachinePolicyForegroundProcessing(VOID)
Definition: gpolicy.c:558
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static const WCHAR szLocalGPMutex[]
Definition: gpolicy.c:46
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
static CRITICAL_SECTION GPNotifyLock
Definition: gpolicy.c:56
BOOL bMachine
Definition: gpolicy.c:36
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:597
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventW(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
Definition: synch.c:628
static HANDLE hEvent
Definition: comm.c:54
VOID WINAPI FreeLibraryAndExitThread(HMODULE hLibModule, DWORD dwExitCode)
Definition: loader.c:514
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
static HANDLE hLocalGPAppliedEvent
Definition: gpolicy.c:61
HINSTANCE hInstance
Definition: charmap.c:20
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI RefreshPolicy(IN BOOL bMachine)
Definition: gpolicy.c:428
static PGP_NOTIFY NotificationList
Definition: gpolicy.c:57
BOOL WINAPI UnregisterGPNotification(IN HANDLE hEvent)
Definition: gpolicy.c:387
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:111
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:697
smooth NULL
Definition: ftsmooth.c:416
#define _Out_
Definition: no_sal2.h:323
void DPRINT(...)
Definition: polytest.cpp:61
const char * LPCSTR
Definition: xmlstorage.h:183
static HANDLE hMachineGPAppliedEvent
Definition: gpolicy.c:62
#define LMEM_FIXED
Definition: winbase.h:349
static const WCHAR szLocalGPDoneEvent[]
Definition: gpolicy.c:49
#define WAIT_OBJECT_0
Definition: winbase.h:387
__wchar_t WCHAR
Definition: xmlstorage.h:180
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
static const WCHAR szMachineGPMutex[]
Definition: gpolicy.c:51
#define WAIT_ABANDONED_0
Definition: winbase.h:388
#define WINAPI
Definition: msvc.h:8
static DWORD WINAPI GPNotificationThreadProc(IN LPVOID lpParameter)
Definition: gpolicy.c:132
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WAIT_FAILED
Definition: winbase.h:394
#define SetLastError(x)
Definition: compat.h:409
GP_ACTION
Definition: gpolicy.c:39
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:564
struct _GP_NOTIFY GP_NOTIFY
static const WCHAR L[]
Definition: oid.c:1250
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
LPVOID lpParameter
Definition: kernel32.h:234
static HANDLE hNotificationThreadEvent
Definition: gpolicy.c:60
static const WCHAR Cleanup[]
Definition: register.c:80
#define SYNCHRONIZE
Definition: nt_native.h:61
HANDLE WINAPI EnterCriticalPolicySection(IN BOOL bMachine)
Definition: gpolicy.c:482
static const WCHAR szMachineGPForceRefreshEvent[]
Definition: gpolicy.c:53
static const WCHAR szLocalGPForceRefreshEvent[]
Definition: gpolicy.c:48
#define _In_
Definition: no_sal2.h:204
PSECURITY_DESCRIPTOR CreateDefaultSecurityDescriptor(VOID)
Definition: misc.c:57
BOOL WINAPI GetModuleHandleExW(IN DWORD dwFlags, IN LPCWSTR lpwModuleName OPTIONAL, OUT HMODULE *phModule)
Definition: loader.c:873
LPVOID lpSecurityDescriptor
Definition: compat.h:181
static HANDLE CreateGPEvent(IN BOOL bMachine, IN PSECURITY_DESCRIPTOR lpSecurityDescriptor)
Definition: gpolicy.c:262
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
BOOL WINAPI WaitForUserPolicyForegroundProcessing(VOID)
Definition: gpolicy.c:538
BOOL WINAPI LeaveCriticalPolicySection(IN HANDLE hSection)
Definition: gpolicy.c:520
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:522
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:660
static HANDLE hNotificationThread
Definition: gpolicy.c:59
DWORD WINAPI GetAppliedGPOListW(_In_ DWORD dwFlags, _In_ LPCWSTR pMachineName, _In_ PSID pSidUser, _In_ GUID *pGuidExtension, _Out_ PGROUP_POLICY_OBJECTW *ppGPOList)
Definition: gpolicy.c:592
#define DPRINT1
Definition: precomp.h:8
HANDLE hEvent
Definition: gpolicy.c:35
#define EVENT_MODIFY_STATE
Definition: winbase.h:163
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1373
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
static GP_ACTION GPNotificationAction
Definition: gpolicy.c:58
#define INFINITE
Definition: serial.h:102
static VOID NotifyGPEvents(IN BOOL bMachine)
Definition: gpolicy.c:114
_In_ const BITMAPINFO _In_ UINT _In_opt_ HANDLE hSection
Definition: wingdi.h:3217
VOID UninitializeGPNotifications(VOID)
Definition: gpolicy.c:71
BOOL WINAPI RefreshPolicyEx(IN BOOL bMachine, IN DWORD dwOptions)
Definition: gpolicy.c:448
static PCWSTR BOOL bMachine
Definition: layerapi.c:33
static const WCHAR szLocalGPApplied[]
Definition: gpolicy.c:45
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
HMODULE hModule
Definition: animate.c:44
struct _GP_NOTIFY * Next
Definition: gpolicy.c:34