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 */