ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

gpolicy.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.