Open BNO directory with correct privileges, open CSR connection with
correct path. Add InWindows boolean to use the right CSR ServerID in
windows and add a hack to get kernel32 to be loadable if used with
.local to force an application to use our kernel and not the system one.
The result of this is that our kernel32 can now load in Windows XP (not
2000).
Modified: trunk/reactos/include/ndk/obtypes.h
Modified: trunk/reactos/lib/kernel32/kernel32.def
Modified: trunk/reactos/lib/kernel32/misc/dllmain.c
_____
Modified: trunk/reactos/include/ndk/obtypes.h
--- trunk/reactos/include/ndk/obtypes.h 2005-09-26 16:13:50 UTC (rev
18096)
+++ trunk/reactos/include/ndk/obtypes.h 2005-09-26 18:03:17 UTC (rev
18097)
@@ -36,7 +36,7 @@
#define DIRECTORY_TRAVERSE 0x0002
#define DIRECTORY_CREATE_OBJECT 0x0004
#define DIRECTORY_CREATE_SUBDIRECTORY 0x0008
-#define DIRECTORY_ALL_ACCESS STANDARD_RIGHTS_REQUIRED | 0xF
+#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED |
0xF)
#endif
/* Duplication Flags */
_____
Modified: trunk/reactos/lib/kernel32/kernel32.def
--- trunk/reactos/lib/kernel32/kernel32.def 2005-09-26 16:13:50 UTC
(rev 18096)
+++ trunk/reactos/lib/kernel32/kernel32.def 2005-09-26 18:03:17 UTC
(rev 18097)
@@ -55,7 +55,8 @@
BaseFlushAppcompatCache@0
;BaseInitAppcompatCache
;BaseInitAppcompatCacheSupport
-;BaseProcessInitPostImport
+BaseProcessInitPostImport@0
+BaseQueryModuleData@20
BaseUpdateAppcompatCache@12
Beep@8
BeginUpdateResourceA@8
_____
Modified: trunk/reactos/lib/kernel32/misc/dllmain.c
--- trunk/reactos/lib/kernel32/misc/dllmain.c 2005-09-26 16:13:50 UTC
(rev 18096)
+++ trunk/reactos/lib/kernel32/misc/dllmain.c 2005-09-26 18:03:17 UTC
(rev 18097)
@@ -13,11 +13,9 @@
#include <k32.h>
-#define NDEBUG
+//#define NDEBUG
#include "../include/debug.h"
-#define CSR_BASE_DLL 0 // <- This should be 1 when CSR gets committed
-
/* GLOBALS
*******************************************************************/
extern UNICODE_STRING SystemDirectory;
@@ -26,6 +24,8 @@
HANDLE hProcessHeap = NULL;
HMODULE hCurrentModule = NULL;
HANDLE hBaseDir = NULL;
+PPEB Peb;
+ULONG SessionId;
static BOOL DllInitialized = FALSE;
static BOOL ConsoleInitialized = FALSE;
@@ -44,6 +44,7 @@
extern BOOL FASTCALL NlsInit();
extern VOID FASTCALL NlsUninit();
+BOOLEAN InWindows = FALSE;
HANDLE
STDCALL
@@ -52,41 +53,77 @@
BOOL bInheritHandle,
DWORD dwOptions);
+#define WIN_OBJ_DIR L"\\Windows"
+#define SESSION_DIR L"\\Sessions"
+
/* FUNCTIONS
*****************************************************************/
-static NTSTATUS
+NTSTATUS
+WINAPI
OpenBaseDirectory(PHANDLE DirHandle)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\BaseNamedObjects");
- NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\BaseNamedObjects");
+ NTSTATUS Status;
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_CASE_INSENSITIVE|OBJ_PERMANENT,
- NULL,
- NULL);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
- Status = NtOpenDirectoryObject(DirHandle,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
+ Status = NtOpenDirectoryObject(DirHandle,
+ DIRECTORY_ALL_ACCESS &
+ ~(DELETE | WRITE_DAC | WRITE_OWNER),
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
{
- Status = NtCreateDirectoryObject(DirHandle,
- DIRECTORY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("NtCreateDirectoryObject() failed\n");
- }
-
- return Status;
+ /* FIXME: It's not our job to create the BNO directory, csr
does it */
+ Status = NtCreateDirectoryObject(DirHandle,
+ DIRECTORY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtCreateDirectoryObject() failed\n");
+ }
}
- return STATUS_SUCCESS;
+ DPRINT("Opened BNO: %lx\n", *DirHandle);
+ return Status;
}
+/*
+ * @unimplemented
+ */
BOOL
+WINAPI
+BaseQueryModuleData(IN LPSTR ModuleName,
+ IN LPSTR Unknown,
+ IN PVOID Unknown2,
+ IN PVOID Unknown3,
+ IN PVOID Unknown4)
+{
+ DPRINT1("BaseQueryModuleData called: %s %s %x %x %x\n",
+ ModuleName,
+ Unknown,
+ Unknown2,
+ Unknown3,
+ Unknown4);
+ return FALSE;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+WINAPI
+BaseProcessInitPostImport(VOID)
+{
+ /* FIXME: Initialize TS pointers */
+ return STATUS_SUCCESS;
+}
+
+BOOL
STDCALL
BasepInitConsole(VOID)
{
@@ -210,20 +247,75 @@
BOOLEAN IsServer;
ULONG Dummy;
ULONG DummySize = sizeof(Dummy);
+ WCHAR SessionDir[256];
DPRINT("DllMain(hInst %lx, dwReason %lu)\n",
hDll, dwReason);
+ /* Cache the PEB and Session ID */
+ Peb = NtCurrentPeb();
+ SessionId = Peb->SessionId;
+
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
+ /* OK, yes, this is really retarded but it works for now */
+ InWindows = NtCurrentPeb()->BeingDebugged;
+
+ /*
+ * CreateProcess will run in the real kernel32 and it will
write
+ * its own BaseProcessStartThunk EIP in the CONTEXT that
ZwContinue
+ * will get. We'll be first called by Ldr while initializing,
and we'll
+ * be wrapped in 3 layers of SEH, followed by two frames,
finally
+ * followed by our CONTEXT on the stack. We'll modify the EIP
in it
+ * to match the correct one (our own) and then everything
works.
+ * Tested on XP and 2K3, probably doesn't work in 2K.
+ */
+ if (InWindows)
+ {
+ /*
+ * Due to yet another bug in how Windows handles .local,
LDR will
+ * actually end up loading us twice. The second time will
be the
+ * "official" load, at a totally different address. It will
be,
+ * it will be at -that- address that all the APIs will be
called.
+ * However, that address is dynamic while this one will be
static,
+ * so we'll do initilization with this one. Plus, at this
one,
+ * we know exactly that we're within 3 SEH layers.
+ */
+ if (hDll == (HANDLE)0x7c800000)
+ {
+ PULONG Eip;
+ Eip =
(PULONG)*(PULONG)*(PULONG)NtCurrentTeb()->Tib.ExceptionList +
+ 0x9 +
+ FIELD_OFFSET(CONTEXT, Eip) / sizeof(ULONG);
+ *Eip = (ULONG)BaseProcessStartThunk;
+ }
+ }
+
/* Don't bother us for each thread */
LdrDisableThreadCalloutsForDll((PVOID)hDll);
+ /* Setup the right Object Directory path */
+ if (!SessionId)
+ {
+ /* Use the raw path */
+ wcscpy(SessionDir, WIN_OBJ_DIR);
+ }
+ else
+ {
+ /* Use the session path */
+ swprintf(SessionDir,
+ L"%ws\\%ld%ws",
+ SESSION_DIR,
+ SessionId,
+ WIN_OBJ_DIR);
+ }
+
/* Connect to the base server */
- Status = CsrClientConnectToServer(L"\\Windows", // <- FIXME:
SessionDir
- CSR_BASE_DLL,
+ DPRINT("Connecting to CSR...\n");
+ Status = CsrClientConnectToServer(SessionDir,
+ InWindows ? 1 : 0,
&Dummy,
&DummySize,
&IsServer);
@@ -238,85 +330,85 @@
if (!IsServer)
{
/* Set the termination port for the thread */
+ DPRINT("Creating new thread for CSR\n");
CsrNewThread();
}
- hProcessHeap = RtlGetProcessHeap();
- hCurrentModule = hDll;
+ hProcessHeap = RtlGetProcessHeap();
+ hCurrentModule = hDll;
+ DPRINT("Heap: %p\n", hProcessHeap);
- /*
- * Initialize WindowsDirectory and SystemDirectory
- */
- DPRINT("NtSystemRoot: %S\n",
- SharedUserData->NtSystemRoot);
- RtlCreateUnicodeString (&WindowsDirectory,
- SharedUserData->NtSystemRoot);
- SystemDirectory.MaximumLength = WindowsDirectory.MaximumLength +
18;
- SystemDirectory.Length = WindowsDirectory.Length + 18;
- SystemDirectory.Buffer = RtlAllocateHeap (hProcessHeap,
- 0,
-
SystemDirectory.MaximumLength);
- wcscpy (SystemDirectory.Buffer, WindowsDirectory.Buffer);
- wcscat (SystemDirectory.Buffer, L"\\System32");
+ /*
+ * Initialize WindowsDirectory and SystemDirectory
+ */
+ DPRINT("NtSystemRoot: %S\n", SharedUserData->NtSystemRoot);
+ RtlCreateUnicodeString (&WindowsDirectory,
SharedUserData->NtSystemRoot);
+ SystemDirectory.MaximumLength = WindowsDirectory.MaximumLength
+ 18;
+ SystemDirectory.Length = WindowsDirectory.Length + 18;
+ SystemDirectory.Buffer = RtlAllocateHeap(hProcessHeap,
+ 0,
+
SystemDirectory.MaximumLength);
+ wcscpy(SystemDirectory.Buffer, WindowsDirectory.Buffer);
+ wcscat(SystemDirectory.Buffer, L"\\System32");
- /* Open object base directory */
- Status = OpenBaseDirectory(&hBaseDir);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("Failed to open object base directory (Status
%lx)\n",
- Status);
- return FALSE;
- }
+ /* Open object base directory */
+ Status = OpenBaseDirectory(&hBaseDir);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to open object base directory (Status
%lx)\n", Status);
+ return FALSE;
+ }
- /* Initialize the DLL critical section */
- RtlInitializeCriticalSection(&DllLock);
+ /* Initialize the DLL critical section */
+ RtlInitializeCriticalSection(&DllLock);
- /* Initialize the National Language Support routines */
- if (! NlsInit())
- {
+ /* Initialize the National Language Support routines */
+ if (!NlsInit())
+ {
+ DPRINT1("NLS Init failed\n");
return FALSE;
- }
+ }
- /* Initialize Console Support */
- if (!BasepInitConsole())
- {
- DPRINT1("Failure to set up console\n");
- return FALSE;
- }
+ /* Initialize Console Support */
+ if (!BasepInitConsole())
+ {
+ DPRINT1("Failure to set up console\n");
+ return FALSE;
+ }
- /* Insert more dll attach stuff here! */
+ /* Insert more dll attach stuff here! */
+ DllInitialized = TRUE;
+ DPRINT1("Initialization complete\n");
+ break;
- DllInitialized = TRUE;
- break;
+ case DLL_PROCESS_DETACH:
- case DLL_PROCESS_DETACH:
- DPRINT("DLL_PROCESS_DETACH\n");
- if (DllInitialized == TRUE)
- {
- /* Insert more dll detach stuff here! */
+ DPRINT("DLL_PROCESS_DETACH\n");
+ if (DllInitialized == TRUE)
+ {
+ /* Insert more dll detach stuff here! */
+ NlsUninit();
- NlsUninit();
+ /* Delete DLL critical section */
+ if (ConsoleInitialized == TRUE)
+ {
+ RtlDeleteCriticalSection (&ConsoleLock);
+ }
+ RtlDeleteCriticalSection (&DllLock);
- /* Delete DLL critical section */
- if (ConsoleInitialized == TRUE)
- {
- RtlDeleteCriticalSection (&ConsoleLock);
- }
- RtlDeleteCriticalSection (&DllLock);
+ /* Close object base directory */
+ NtClose(hBaseDir);
- /* Close object base directory */
- NtClose(hBaseDir);
+ RtlFreeUnicodeString (&SystemDirectory);
+ RtlFreeUnicodeString (&WindowsDirectory);
+ }
+ break;
- RtlFreeUnicodeString (&SystemDirectory);
- RtlFreeUnicodeString (&WindowsDirectory);
- }
- break;
-
- default:
- break;
+ default:
+ break;
}
- return TRUE;
+ return TRUE;
}
/* EOF */