- partially implemented RegisterGPNotification() and UnregisterGPNotification() (depends on GetModuleHandleEx which is not yet implemented) - use debug.h Modified: trunk/reactos/lib/userenv/desktop.c Modified: trunk/reactos/lib/userenv/directory.c Modified: trunk/reactos/lib/userenv/environment.c Added: trunk/reactos/lib/userenv/gpolicy.c Modified: trunk/reactos/lib/userenv/internal.h Modified: trunk/reactos/lib/userenv/misc.c Modified: trunk/reactos/lib/userenv/profile.c Modified: trunk/reactos/lib/userenv/registry.c Modified: trunk/reactos/lib/userenv/setup.c Modified: trunk/reactos/lib/userenv/userenv.c Modified: trunk/reactos/lib/userenv/userenv.def Modified: trunk/reactos/lib/userenv/userenv.xml _____
Modified: trunk/reactos/lib/userenv/desktop.c --- trunk/reactos/lib/userenv/desktop.c 2006-01-11 22:13:02 UTC (rev 20791) +++ trunk/reactos/lib/userenv/desktop.c 2006-01-11 22:40:31 UTC (rev 20792) @@ -27,7 +27,10 @@
#include <precomp.h>
+#define NDEBUG +#include <debug.h>
+ /* FUNCTIONS ***************************************************************/
static BOOL _____
Modified: trunk/reactos/lib/userenv/directory.c --- trunk/reactos/lib/userenv/directory.c 2006-01-11 22:13:02 UTC (rev 20791) +++ trunk/reactos/lib/userenv/directory.c 2006-01-11 22:40:31 UTC (rev 20792) @@ -27,7 +27,10 @@
#include <precomp.h>
+#define NDEBUG +#include <debug.h>
+ /* FUNCTIONS ***************************************************************/
BOOL STDCALL _____
Modified: trunk/reactos/lib/userenv/environment.c --- trunk/reactos/lib/userenv/environment.c 2006-01-11 22:13:02 UTC (rev 20791) +++ trunk/reactos/lib/userenv/environment.c 2006-01-11 22:40:31 UTC (rev 20792) @@ -27,7 +27,10 @@
#include <precomp.h>
+#define NDEBUG +#include <debug.h>
+ static BOOL SetUserEnvironmentVariable (LPVOID *Environment, LPWSTR lpName, _____
Added: trunk/reactos/lib/userenv/gpolicy.c --- trunk/reactos/lib/userenv/gpolicy.c 2006-01-11 22:13:02 UTC (rev 20791) +++ trunk/reactos/lib/userenv/gpolicy.c 2006-01-11 22:40:31 UTC (rev 20792) @@ -0,0 +1,403 @@
+/* + * ReactOS kernel + * Copyright (C) 2006 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/userenv/gpolicy.c + * PURPOSE: Group policy functions + * PROGRAMMER: Thomas Weidenmueller w3seek@reactos.com + */ + +#include <precomp.h> + +#define NDEBUG +#include <debug.h> + + +typedef struct _GP_NOTIFY +{ + struct _GP_NOTIFY *Next; + HANDLE hEvent; + BOOL bMachine; +} GP_NOTIFY, *PGP_NOTIFY; + +typedef enum +{ + gpaUpdate = 0, + gpaTerminate +} GP_ACTION; + +static const WCHAR szLocalGPApplied[] = L"userenv: User Group Policy has been applied"; +static const WCHAR szMachineGPApplied[] = L"Global\userenv: Machine Group Policy has been applied"; + +static CRITICAL_SECTION GPNotifyLock; +static PGP_NOTIFY NotificationList = NULL; +static GP_ACTION GPNotificationAction = gpaUpdate; +static HANDLE hNotificationThread = NULL; +static HANDLE hNotificationThreadEvent = NULL; +static HANDLE hLocalGPAppliedEvent = NULL; +static HANDLE hMachineGPAppliedEvent = NULL; + +VOID +InitializeGPNotifications(VOID) +{ + InitializeCriticalSection(&GPNotifyLock); +} + +VOID +UninitializeGPNotifications(VOID) +{ + EnterCriticalSection(&GPNotifyLock); + + /* rundown the notification thread */ + if (hNotificationThread != NULL) + { + ASSERT(hNotificationThreadEvent != NULL); + + /* notify the thread */ + GPNotificationAction = gpaTerminate; + SetEvent(hNotificationThreadEvent); + + LeaveCriticalSection(&GPNotifyLock); + + /* wait for the thread to terminate itself */ + WaitForSingleObject(hNotificationThread, + INFINITE); + + EnterCriticalSection(&GPNotifyLock); + + if (hNotificationThread != NULL) + { + /* the handle should be closed by the thread, + just in case that didn't happen for an unknown reason */ + CloseHandle(hNotificationThread); + hNotificationThread = NULL; + } + } + + if (hNotificationThreadEvent != NULL) + { + CloseHandle(hNotificationThreadEvent); + hNotificationThreadEvent = NULL; + } + + LeaveCriticalSection(&GPNotifyLock); + + DeleteCriticalSection(&GPNotifyLock); +} + +static VOID +NotifyGPEvents(IN BOOL bMachine) +{ + PGP_NOTIFY Notify = NotificationList; + + while (Notify != NULL) + { + if (Notify->bMachine == bMachine) + { + SetEvent(Notify->hEvent); + } + + Notify = Notify->Next; + } +} + +static DWORD WINAPI +GPNotificationThreadProc(IN LPVOID lpParameter) +{ + HMODULE hModule; + DWORD WaitResult, WaitCount; + HANDLE WaitHandles[3]; + + /* reference the library so we don't screw up if the application + causes the DLL to unload while this thread is still running */ + if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + (LPCWSTR)hInstance, + &hModule)) + { + ASSERT(hModule == hInstance); + + EnterCriticalSection(&GPNotifyLock); + + ASSERT(hNotificationThreadEvent != NULL); + WaitHandles[0] = hNotificationThreadEvent; + for (;;) + { + ASSERT(hMachineGPAppliedEvent != NULL); + + if (NotificationList == NULL) + break; + + WaitCount = 2; + WaitHandles[1] = hMachineGPAppliedEvent; + + if (hLocalGPAppliedEvent != NULL) + { + WaitHandles[2] = hLocalGPAppliedEvent; + WaitCount++; + } + + LeaveCriticalSection(&GPNotifyLock); + + WaitResult = WaitForMultipleObjects(WaitCount, + WaitHandles, + FALSE, + INFINITE); + + EnterCriticalSection(&GPNotifyLock); + + if (WaitResult != WAIT_FAILED) + { + if (WaitResult == WAIT_OBJECT_0) + { + ResetEvent(hNotificationThreadEvent); + + if (GPNotificationAction == gpaTerminate) + { + /* terminate the thread */ + break; + } + } + else if (WaitResult == WAIT_OBJECT_0 + 1 || WaitResult == WAIT_OBJECT_0 + 2) + { + /* group policies have been applied */ + if (NotificationList != NULL) + { + NotifyGPEvents((WaitResult == WAIT_OBJECT_0 + 1)); + } + } + else if (WaitResult == WAIT_ABANDONED_0 + 2) + { + /* In case the local group policies event was abandoned, keep watching! + But close the handle as it's no longer of any use. */ + if (hLocalGPAppliedEvent != NULL) + { + CloseHandle(hLocalGPAppliedEvent); + hLocalGPAppliedEvent = NULL; + } + } + else if (WaitResult == WAIT_ABANDONED_0 || WaitResult == WAIT_ABANDONED_0 + 1) + { + /* terminate the thread if the machine group policies event was abandoned + or for some reason the rundown event got abandoned. */ + break; + } + else + { + DPRINT("Unexpected wait result watching the group policy events: 0x%x\n", WaitResult); + ASSERT(FALSE); + break; + } + + if (NotificationList == NULL) + break; + } + else + break; + + } + + /* cleanup handles no longer used */ + ASSERT(hNotificationThread != NULL); + ASSERT(hNotificationThreadEvent != NULL); + + CloseHandle(hNotificationThread); + CloseHandle(hNotificationThreadEvent); + hNotificationThread = NULL; + hNotificationThreadEvent = NULL; + + if (hLocalGPAppliedEvent != NULL) + { + CloseHandle(hLocalGPAppliedEvent); + hLocalGPAppliedEvent = NULL; + } + if (hMachineGPAppliedEvent != NULL) + { + CloseHandle(hMachineGPAppliedEvent); + hMachineGPAppliedEvent = NULL; + } + + LeaveCriticalSection(&GPNotifyLock); + + /* dereference the library and exit */ + FreeLibraryAndExitThread(hModule, + 0); + } + else + { + DPRINT1("Referencing the library failed!\n"); + } + + return 1; +} + +static HANDLE +CreateGPEvent(IN BOOL bMachine, + IN PVOID lpSecurityDescriptor) +{ + HANDLE hEvent; + SECURITY_ATTRIBUTES SecurityAttributes; + + SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + SecurityAttributes.lpSecurityDescriptor = lpSecurityDescriptor; + SecurityAttributes.bInheritHandle = FALSE; + + hEvent = CreateEventW((lpSecurityDescriptor != NULL ? &SecurityAttributes : NULL), + TRUE, + FALSE, + (bMachine ? szMachineGPApplied : szLocalGPApplied)); + + return hEvent; +} + +BOOL WINAPI +RegisterGPNotification(IN HANDLE hEvent, + IN BOOL bMachine) +{ + PGP_NOTIFY Notify; + PVOID lpSecurityDescriptor = NULL; + BOOL Ret = FALSE; + + EnterCriticalSection(&GPNotifyLock); + + /* create the thread notification event */ + if (hNotificationThreadEvent == NULL) + { + hNotificationThreadEvent = CreateEvent(NULL, + TRUE, + FALSE, + NULL); + if (hNotificationThreadEvent == NULL) + { + goto Cleanup; + } + } + + /* create or open the machine group policy event */ + if (hMachineGPAppliedEvent == NULL) + { + lpSecurityDescriptor = CreateDefaultSD(); + + hMachineGPAppliedEvent = CreateGPEvent(TRUE, + lpSecurityDescriptor); + if (hMachineGPAppliedEvent == NULL) + { + goto Cleanup; + } + } + + /* create or open the local group policy event only if necessary */ + if (!bMachine && hLocalGPAppliedEvent == NULL) + { + if (lpSecurityDescriptor == NULL) + { + lpSecurityDescriptor = CreateDefaultSD(); + } + + hLocalGPAppliedEvent = CreateGPEvent(FALSE, + lpSecurityDescriptor); + if (hLocalGPAppliedEvent == NULL) + { + goto Cleanup; + } + } + + if (hNotificationThread == NULL) + { + hNotificationThread = CreateThread(NULL, + 0, + GPNotificationThreadProc, + NULL, + 0, + NULL); + } + + if (hNotificationThread != NULL) + { + Notify = (PGP_NOTIFY)LocalAlloc(LMEM_FIXED, + sizeof(GP_NOTIFY)); + if (Notify != NULL) + { + /* add the item to the beginning of the list */ + Notify->Next = NotificationList; + Notify->hEvent = hEvent; + Notify->bMachine = bMachine; + + NotificationList = Notify; + + /* notify the thread */ + GPNotificationAction = gpaUpdate; + SetEvent(hNotificationThreadEvent); + + Ret = TRUE; + } + } + +Cleanup: + LeaveCriticalSection(&GPNotifyLock); + + if (lpSecurityDescriptor != NULL) + { + LocalFree((HLOCAL)lpSecurityDescriptor); + } + + /* NOTE: don't delete the events or close the handles created */ + + return Ret; +} + +BOOL WINAPI +UnregisterGPNotification(IN HANDLE hEvent) +{ + PGP_NOTIFY Notify = NULL, *NotifyLink; + BOOL Ret = FALSE; + + EnterCriticalSection(&GPNotifyLock); + + Notify = NotificationList; + NotifyLink = &NotificationList; + + while (Notify != NULL) + { + if (Notify->hEvent == hEvent) + { + /* remove and free the item */ + *NotifyLink = Notify->Next; + LocalFree((HLOCAL)Notify); + + /* notify the thread */ + if (hNotificationThread != NULL && + hNotificationThreadEvent != NULL) + { + GPNotificationAction = gpaUpdate; + SetEvent(hNotificationThreadEvent); + } + + Ret = TRUE; + break; + } + + NotifyLink = &Notify->Next; + Notify = Notify->Next; + } + + LeaveCriticalSection(&GPNotifyLock); + + return Ret; +} Property changes on: trunk/reactos/lib/userenv/gpolicy.c ___________________________________________________________________ Name: svn:keywords + author date revision Name: svn:eol-style + native _____
Modified: trunk/reactos/lib/userenv/internal.h --- trunk/reactos/lib/userenv/internal.h 2006-01-11 22:13:02 UTC (rev 20791) +++ trunk/reactos/lib/userenv/internal.h 2006-01-11 22:40:31 UTC (rev 20792) @@ -28,20 +28,6 @@
#ifndef _INTERNAL_H #define _INTERNAL_H
-/* debug.h */ -void -DebugPrint (char* fmt,...); - -#define DPRINT1 DebugPrint("(%s:%d) ",__FILE__,__LINE__), DebugPrint -#define CHECKPOINT1 do { DebugPrint("%s:%d\n",__FILE__,__LINE__); } while(0); - -#ifdef __GNUC__ -#define DPRINT(args...) -#else -#define DPRINT -#endif /* __GNUC__ */ -#define CHECKPOINT - /* directory.c */ BOOL CopyDirectory (LPCWSTR lpDestinationPath, @@ -91,6 +77,9 @@ GetUserSidFromToken (HANDLE hToken, PUNICODE_STRING SidString);
+PVOID +CreateDefaultSD(VOID); + /* profile.c */ BOOL AppendSystemPostfix (LPWSTR lpName, @@ -109,6 +98,14 @@ /* userenv.c */ extern HINSTANCE hInstance;
+/* gpolicy.c */ + +VOID +InitializeGPNotifications(VOID); + +VOID +UninitializeGPNotifications(VOID); + #endif /* _INTERNAL_H */
/* EOF */ _____
Modified: trunk/reactos/lib/userenv/misc.c --- trunk/reactos/lib/userenv/misc.c 2006-01-11 22:13:02 UTC (rev 20791) +++ trunk/reactos/lib/userenv/misc.c 2006-01-11 22:40:31 UTC (rev 20792) @@ -27,7 +27,10 @@
#include <precomp.h>
+#define NDEBUG +#include <debug.h>
+ /* FUNCTIONS ***************************************************************/
LPWSTR @@ -109,6 +112,13 @@ return TRUE; }
+PVOID +CreateDefaultSD(VOID) +{ + /* FIXME - create a default security descriptor */ + return NULL; +} + /* Dynamic DLL loading interface **********************************************/
/* OLE32.DLL import table */ _____
Modified: trunk/reactos/lib/userenv/profile.c --- trunk/reactos/lib/userenv/profile.c 2006-01-11 22:13:02 UTC (rev 20791) +++ trunk/reactos/lib/userenv/profile.c 2006-01-11 22:40:31 UTC (rev 20792) @@ -27,7 +27,10 @@
#include <precomp.h>
+#define NDEBUG +#include <debug.h>
+ /* FUNCTIONS ***************************************************************/
BOOL _____
Modified: trunk/reactos/lib/userenv/registry.c --- trunk/reactos/lib/userenv/registry.c 2006-01-11 22:13:02 UTC (rev 20791) +++ trunk/reactos/lib/userenv/registry.c 2006-01-11 22:40:31 UTC (rev 20792) @@ -27,7 +27,10 @@
#include <precomp.h>
+#define NDEBUG +#include <debug.h>
+ /* FUNCTIONS ***************************************************************/
static BOOL _____
Modified: trunk/reactos/lib/userenv/setup.c --- trunk/reactos/lib/userenv/setup.c 2006-01-11 22:13:02 UTC (rev 20791) +++ trunk/reactos/lib/userenv/setup.c 2006-01-11 22:40:31 UTC (rev 20792) @@ -27,6 +27,10 @@
#include <precomp.h>
+#define NDEBUG +#include <debug.h> + + typedef struct _FOLDERDATA { LPWSTR lpValueName; _____
Modified: trunk/reactos/lib/userenv/userenv.c --- trunk/reactos/lib/userenv/userenv.c 2006-01-11 22:13:02 UTC (rev 20791) +++ trunk/reactos/lib/userenv/userenv.c 2006-01-11 22:40:31 UTC (rev 20792) @@ -27,6 +27,9 @@
#include <precomp.h>
+#define NDEBUG +#include <debug.h> + HINSTANCE hInstance = NULL;
BOOL WINAPI @@ -37,9 +40,11 @@ if (fdwReason == DLL_PROCESS_ATTACH) { hInstance = hinstDLL; + InitializeGPNotifications(); } else if (fdwReason == DLL_PROCESS_DETACH) { + UninitializeGPNotifications(); }
return TRUE; _____
Modified: trunk/reactos/lib/userenv/userenv.def --- trunk/reactos/lib/userenv/userenv.def 2006-01-11 22:13:02 UTC (rev 20791) +++ trunk/reactos/lib/userenv/userenv.def 2006-01-11 22:40:31 UTC (rev 20792) @@ -31,5 +31,7 @@
GetUserProfileDirectoryW@12 LoadUserProfileA@8 LoadUserProfileW@8 +RegisterGPNotification@8 UnloadUserProfile@8 +UnregisterGPNotification@4 ;EOF _____
Modified: trunk/reactos/lib/userenv/userenv.xml --- trunk/reactos/lib/userenv/userenv.xml 2006-01-11 22:13:02 UTC (rev 20791) +++ trunk/reactos/lib/userenv/userenv.xml 2006-01-11 22:40:31 UTC (rev 20792) @@ -13,6 +13,7 @@
<file>desktop.c</file> <file>directory.c</file> <file>environment.c</file> + <file>gpolicy.c</file> <file>misc.c</file> <file>profile.c</file> <file>registry.c</file>