- partially implemented RegisterGPNotification() and UnregisterGPNotification() (depends on GetModuleHandleEx which is not yet implemented)

- use debug.h

svn path=/trunk/; revision=20792
This commit is contained in:
Thomas Bluemel
2006-01-11 22:40:31 +00:00
parent bd56021a5c
commit bfce7c398c
12 changed files with 451 additions and 14 deletions
+3
View File
@@ -27,6 +27,9 @@
#include <precomp.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ***************************************************************/
+3
View File
@@ -27,6 +27,9 @@
#include <precomp.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ***************************************************************/
+3
View File
@@ -27,6 +27,9 @@
#include <precomp.h>
#define NDEBUG
#include <debug.h>
static BOOL
SetUserEnvironmentVariable (LPVOID *Environment,
+403
View File
@@ -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;
}
+11 -14
View File
@@ -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 @@ BOOL
GetUserSidFromToken (HANDLE hToken,
PUNICODE_STRING SidString);
PVOID
CreateDefaultSD(VOID);
/* profile.c */
BOOL
AppendSystemPostfix (LPWSTR lpName,
@@ -109,6 +98,14 @@ UpdateUsersShellFolderSettings(LPCWSTR lpUserProfilePath,
/* userenv.c */
extern HINSTANCE hInstance;
/* gpolicy.c */
VOID
InitializeGPNotifications(VOID);
VOID
UninitializeGPNotifications(VOID);
#endif /* _INTERNAL_H */
/* EOF */
+10
View File
@@ -27,6 +27,9 @@
#include <precomp.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ***************************************************************/
@@ -109,6 +112,13 @@ GetUserSidFromToken (HANDLE hToken,
return TRUE;
}
PVOID
CreateDefaultSD(VOID)
{
/* FIXME - create a default security descriptor */
return NULL;
}
/* Dynamic DLL loading interface **********************************************/
/* OLE32.DLL import table */
+3
View File
@@ -27,6 +27,9 @@
#include <precomp.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ***************************************************************/
+3
View File
@@ -27,6 +27,9 @@
#include <precomp.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ***************************************************************/
+4
View File
@@ -27,6 +27,10 @@
#include <precomp.h>
#define NDEBUG
#include <debug.h>
typedef struct _FOLDERDATA
{
LPWSTR lpValueName;
+5
View File
@@ -27,6 +27,9 @@
#include <precomp.h>
#define NDEBUG
#include <debug.h>
HINSTANCE hInstance = NULL;
BOOL WINAPI
@@ -37,9 +40,11 @@ DllMain (HINSTANCE hinstDLL,
if (fdwReason == DLL_PROCESS_ATTACH)
{
hInstance = hinstDLL;
InitializeGPNotifications();
}
else if (fdwReason == DLL_PROCESS_DETACH)
{
UninitializeGPNotifications();
}
return TRUE;
+2
View File
@@ -31,5 +31,7 @@ GetUserProfileDirectoryA@12
GetUserProfileDirectoryW@12
LoadUserProfileA@8
LoadUserProfileW@8
RegisterGPNotification@8
UnloadUserProfile@8
UnregisterGPNotification@4
;EOF
+1
View File
@@ -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>