Updated CREDITS
authorDavid Welch <welch@cwcom.net>
Sat, 12 Aug 2000 19:33:23 +0000 (19:33 +0000)
committerDavid Welch <welch@cwcom.net>
Sat, 12 Aug 2000 19:33:23 +0000 (19:33 +0000)
Work on security
Updated heap code from wine implementation
Implemented kernel/user shared data page

svn path=/trunk/; revision=1297

29 files changed:
reactos/CREDITS
reactos/Makefile
reactos/include/lsass/lsass.h [new file with mode: 0644]
reactos/include/lsass/ntsecapi.h [new file with mode: 0644]
reactos/include/napi/shared_data.h [new file with mode: 0644]
reactos/install-system.sh
reactos/install.sh
reactos/lib/kernel32/makefile
reactos/lib/ntdll/ldr/startup.c
reactos/lib/ntdll/rtl/heap.c
reactos/lib/secur32/Makefile [new file with mode: 0644]
reactos/lib/secur32/dllmain.c [new file with mode: 0644]
reactos/lib/secur32/lsa.c [new file with mode: 0644]
reactos/lib/secur32/secur32.def [new file with mode: 0644]
reactos/lib/secur32/secur32.edf [new file with mode: 0644]
reactos/lib/secur32/secur32.rc [new file with mode: 0644]
reactos/loaders/dos/loadros.asm
reactos/ntoskrnl/hal/x86/misc.c
reactos/ntoskrnl/hal/x86/reboot.c
reactos/ntoskrnl/include/internal/mm.h
reactos/ntoskrnl/kd/kdebug.c
reactos/ntoskrnl/ke/bug.c
reactos/ntoskrnl/ldr/loader.c
reactos/ntoskrnl/mm/mm.c
reactos/ntoskrnl/mm/mminit.c
reactos/ntoskrnl/ps/kill.c
reactos/ntoskrnl/ps/process.c
reactos/services/winlogon/makefile
reactos/services/winlogon/winlogon.c

index 7facc2c..f5c43fe 100644 (file)
@@ -12,3 +12,10 @@ Jason Filby (jasonfilby@yahoo.com)
 Brian Palmer (brianp@sginet.com)
 Phillip Susi (phreak@iag.net)
 Paolo Pantaleo (paolopan@freemail.it)
+Casper S. Hornstrup (chorns@users.sourceforge.net)
+
+Source and inspiration from
+
+WINE (http://www.winehq.com)
+WinFree (http://www.stack.nl/~onno/win32/)
+Linux (http://www.kernel.org)
index 1158380..2565699 100644 (file)
@@ -6,7 +6,7 @@
 # Select your host
 #
 #HOST = mingw32-linux
-#HOST = mingw32-windows
+HOST = mingw32-windows
 
 include rules.mak
 
@@ -14,7 +14,7 @@ include rules.mak
 # Required to run the system
 #
 COMPONENTS = iface_native iface_additional ntoskrnl
-DLLS = ntdll kernel32 crtdll advapi32 fmifs gdi32
+DLLS = ntdll kernel32 crtdll advapi32 fmifs gdi32 secur32
 SUBSYS = smss win32k csrss
 
 #
@@ -44,7 +44,7 @@ NET_DRIVERS = ndis tcpip tditest
 KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS) $(NET_DRIVERS)
 
 APPS = args hello shell test cat bench apc shm lpc thread event file gditest \
-       pteb consume
+       pteb consume dump_shared_data
 
 #       objdir
 
diff --git a/reactos/include/lsass/lsass.h b/reactos/include/lsass/lsass.h
new file mode 100644 (file)
index 0000000..bca135e
--- /dev/null
@@ -0,0 +1,130 @@
+/* $Id: lsass.h,v 1.1 2000/08/12 19:33:18 dwelch Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS system libraries
+ * FILE:            include/lsass/lsass.h
+ * PURPOSE:         LSASS API declarations
+ * UPDATE HISTORY:
+ *                  Created 05/08/00
+ */
+
+#ifndef __INCLUDE_LSASS_LSASS_H
+#define __INCLUDE_LSASS_LSASS_H
+
+#include <ntos.h>
+#include <lsass/ntsecapi.h>
+#include <napi/lpc.h>
+
+#define LSASS_REQUEST_REGISTER_LOGON_PROCESS               (1)
+#define LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE          (2)
+#define LSASS_REQUEST_DEREGISTER_LOGON_PROCESS             (3)
+#define LSASS_REQUEST_LOGON_USER                           (4)
+#define LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE        (5)
+#define LSASS_REQUEST_MAXIMUM                              (6)
+
+typedef struct _LSASS_LOOKUP_AUTHENTICATION_PACKAGE_REQUEST
+{
+   ULONG PackageNameLength;
+   WCHAR PackageName[0];
+} LSASS_LOOKUP_AUTHENTICATION_PACKAGE_REQUEST,
+ *PLSASS_LOOKUP_AUTHENTICATION_PACKAGE_REQUEST;
+
+typedef struct _LSASS_LOOKUP_AUTHENTICATION_PACKAGE_REPLY
+{
+   ULONG Package;
+} LSASS_LOOKUP_AUTHENTICATION_PACKAGE_REPLY,
+ *PLSASS_LOOKUP_AUTHENTICATION_PACKAGE_REPLY;
+
+typedef struct _LSASS_DEREGISTER_LOGON_PROCESS_REQUEST
+{
+} LSASS_DEREGISTER_LOGON_PROCESS_REQUEST,
+ *PLSASS_DEREGISTER_LOGON_PROCES_REQUEST;
+
+typedef struct _LSASS_DEREGISTER_LOGON_PROCESS_REPLY
+{   
+} LSASS_DEREGISTER_LOGON_PROCESS_REPLY,
+ *PLSASS_DEREGISTER_LOGON_PROCESS_REPLY;
+
+typedef struct _LSASS_CALL_AUTHENTICATION_PACKAGE_REQUEST
+{
+   ULONG AuthenticationPackage;
+   ULONG InBufferLength;
+   UCHAR InBuffer[0];
+} LSASS_CALL_AUTHENTICATION_PACKAGE_REQUEST,
+*PLSASS_CALL_AUTHENTICATION_PACKAGE_REQUEST;
+
+typedef struct _LSASS_CALL_AUTHENTICATION_PACKAGE_REPLY
+{
+   ULONG OutBufferLength;
+   UCHAR OutBuffer[0];
+} LSASS_CALL_AUTHENTICATION_PACKAGE_REPLY,
+*PLSASS_CALL_AUTHENTICATION_PACKAGE_REPLY;
+
+typedef struct _LSASS_LOGON_USER_REQUEST
+{
+   ULONG OriginNameLength;
+   PWSTR OriginName;
+   SECURITY_LOGON_TYPE LogonType;
+   ULONG AuthenticationPackage;
+   PVOID AuthenticationInformation;
+   ULONG AuthenticationInformationLength;
+   ULONG LocalGroupsCount;
+   PSID_AND_ATTRIBUTES LocalGroups;
+   TOKEN_SOURCE SourceContext;
+   UCHAR Data[1];
+} LSASS_LOGON_USER_REQUEST, *PLSASS_LOGON_USER_REQUEST;
+
+typedef struct _LSASS_LOGON_USER_REPLY
+{
+   PVOID ProfileBuffer;
+   ULONG ProfileBufferLength;
+   LUID LogonId;
+   HANDLE Token;
+   QUOTA_LIMITS Quotas;
+   NTSTATUS SubStatus;
+   UCHAR Data[1];
+} LSASS_LOGON_USER_REPLY, *PLSASS_LOGON_USER_REPLY;
+
+typedef struct _LSASS_REGISTER_LOGON_PROCESS_REQUEST
+{
+   ULONG Length;
+   WCHAR LogonProcessNameBuffer[127];
+} LSASS_REGISTER_LOGON_PROCESS_REQUEST, *PLSASS_REGISTER_LOGON_PROCESS_REQUEST;
+
+typedef struct _LSASS_REGISTER_LOGON_PROCESS_REPLY
+{
+   LSA_OPERATIONAL_MODE OperationalMode;
+} LSASS_REGISTER_LOGON_PROCESS_REPLY, *PLSASS_REGISTER_LOGON_PROCESS_REPLY;
+
+typedef struct _LSASS_REQUEST
+{
+   LPC_MESSAGE_HEADER Header;
+   ULONG Type;
+   union
+     {
+       LSASS_REGISTER_LOGON_PROCESS_REQUEST RegisterLogonProcessRequest;
+       LSASS_LOGON_USER_REQUEST LogonUserRequest;
+       LSASS_CALL_AUTHENTICATION_PACKAGE_REQUEST 
+         CallAuthenticationPackageRequest;
+       LSASS_DEREGISTER_LOGON_PROCESS_REPLY DeregisterLogonProcessRequest;
+       LSASS_LOOKUP_AUTHENTICATION_PACKAGE_REQUEST
+         LookupAuthenticationPackageRequest;
+     } d;
+} LSASS_REQUEST, *PLSASS_REQUEST;
+
+typedef struct _LSASS_REPLY
+{
+   LPC_MESSAGE_HEADER Header;
+   NTSTATUS Status;
+   union
+     {
+       LSASS_REGISTER_LOGON_PROCESS_REPLY RegisterLogonProcessReply;
+       LSASS_LOGON_USER_REPLY LogonUserReply;
+       LSASS_CALL_AUTHENTICATION_PACKAGE_REPLY CallAuthenticationPackageReply;
+       LSASS_DEREGISTER_LOGON_PROCESS_REPLY DeregisterLogonProcessReply;
+       LSASS_LOOKUP_AUTHENTICATION_PACKAGE_REPLY 
+         LookupAuthenticationPackageReply;
+     } d;
+} LSASS_REPLY, *PLSASS_REPLY;
+
+#endif /* __INCLUDE_LSASS_LSASS_H */
diff --git a/reactos/include/lsass/ntsecapi.h b/reactos/include/lsass/ntsecapi.h
new file mode 100644 (file)
index 0000000..99f2864
--- /dev/null
@@ -0,0 +1,32 @@
+/* $Id: ntsecapi.h,v 1.1 2000/08/12 19:33:18 dwelch Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS system libraries
+ * FILE:            include/lsass/ntsecpai.h
+ * PURPOSE:         LSASS API declarations
+ * UPDATE HISTORY:
+ *                  Created 05/08/00
+ */
+
+#ifndef __INCLUDE_LSASS_NTSECAPI_H
+#define __INCLUDE_LSASS_NTSECAPI_H
+
+#define SECURITY_LOGON_INTERACTIVE        (2)
+#define SECURITY_LOGON_NETWORK            (3)
+#define SECURITY_LOGON_BATCH              (4)
+#define SECURITY_LOGON_SERVICE            (5)
+#define SECURITY_LOGON_PROXY              (6)
+#define SECURITY_LOGON_UNLOCK             (7)
+
+typedef ULONG SECURITY_LOGON_TYPE;
+
+typedef struct _LSA_STRING
+{
+   USHORT Length;
+   USHORT MaximumLength;
+   PWSTR Buffer;
+} LSA_STRING, *PLSA_STRING;
+
+typedef ULONG LSA_OPERATIONAL_MODE, *PLSA_OPERATIONAL_MODE;
+
+#endif /* __INCLUDE_LSASS_NTSECAPI_H */
diff --git a/reactos/include/napi/shared_data.h b/reactos/include/napi/shared_data.h
new file mode 100644 (file)
index 0000000..5bdace3
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __INCLUDE_NAPI_SHARED_DATA_H
+#define __INCLUDE_NAPI_SHARED_DATA_H
+
+typedef struct _KUSER_SHARED_DATA
+{
+   ULONG TickCountLow;
+   ULONG TickCountMultiplier;
+} KUSER_SHARED_DATA, *PKUSER_SHARED_DATA;
+
+#define KERNEL_SHARED_DATA_BASE    (0xFFDF0000)
+#define USER_SHARED_DATA_BASE      (0x7FFE0000)
+
+#endif /* __INCLUDE_NAPI_SHARED_DATA_H */
index 126fd7b..369dc34 100644 (file)
@@ -12,10 +12,3 @@ cp services/dd/ide/ide.sys $1
 cp ntoskrnl/ntoskrnl.exe $1/reactos/system32/
 cp services/fs/vfat/vfatfs.sys $1/reactos/system32/drivers/
 cp services/dd/ide/ide.sys $1/reactos/system32/drivers/
-#cp services/dd/floppy/floppy.sys $1/reactos/system32/drivers/
-cp services/dd/keyboard/keyboard.sys $1/reactos/system32/drivers
-cp services/dd/blue/blue.sys $1/reactos/system32/drivers
-#cp services/dd/vga/miniport/vgamp.sys $1/reactos/system32/drivers
-#cp services/dd/vga/display/vgaddi.dll $1/reactos/system32/drivers
-#cp services/dd/vidport/vidport.sys $1/reactos/system32/drivers
-cp services/fs/minix/minixfs.sys $1/reactos/system32/drivers
index 651a241..7f02d6a 100644 (file)
@@ -3,6 +3,13 @@ mkdir -p $1/reactos/system32
 mkdir -p $1/reactos/system32/drivers
 mkdir -p $1/reactos/bin
 ./install-system.sh $1
+cp services/dd/floppy/floppy.sys $1/reactos/system32/drivers/
+cp services/dd/keyboard/keyboard.sys $1/reactos/system32/drivers
+cp services/dd/blue/blue.sys $1/reactos/system32/drivers
+cp services/dd/vga/miniport/vgamp.sys $1/reactos/system32/drivers
+cp services/dd/vga/display/vgaddi.dll $1/reactos/system32/drivers
+cp services/dd/vidport/vidport.sys $1/reactos/system32/drivers
+cp services/fs/minix/minixfs.sys $1/reactos/system32/drivers
 cp apps/shell/shell.exe $1/reactos/system32
 cp lib/ntdll/ntdll.dll $1/reactos/system32
 cp lib/kernel32/kernel32.dll $1/reactos/system32
@@ -28,3 +35,4 @@ cp apps/file/file.exe $1/reactos/bin
 cp apps/pteb/pteb.exe $1/reactos/bin
 cp apps/consume/consume.exe $1/reactos/bin
 cp apps/float/float.exe $1/reactos/bin
+cp apps/dump_shared_data/dump_shared_data.exe $1/reactos/bin
index bfcb320..1883d16 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.36 2000/08/11 12:32:04 ekohl Exp $
+# $Id: makefile,v 1.37 2000/08/12 19:33:18 dwelch Exp $
 #
 # ReactOS Operating System
 #
@@ -157,5 +157,6 @@ else
        $(CP) $(TARGET).dll ../../$(DIST_DIR)/dlls/$(TARGET).dll
 endif
 
+WITH_DEBUGGING=yes
 WARNINGS_ARE_ERRORS = yes
 
index eb590f7..863f1ce 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: startup.c,v 1.28 2000/08/11 12:34:58 ekohl Exp $
+/* $Id: startup.c,v 1.29 2000/08/12 19:33:18 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
 #include <ntdll/ntdll.h>
 
 
-VOID RtlpInitProcessHeaps (PPEB Peb);
+VOID RtlInitializeHeapManager (VOID);
 
 /* GLOBALS *******************************************************************/
 
 DLL LdrDllListHead;
 extern unsigned int _image_base__;
 
-CRITICAL_SECTION PebLock;
+static CRITICAL_SECTION PebLock;
 
 ULONG NtGlobalFlag = 0;
 
@@ -97,6 +97,7 @@ LdrInitializeThunk (ULONG Unknown1,
    NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + PEDosHeader->e_lfanew);
 
    /* create process heap */
+   RtlInitializeHeapManager();
    Peb->ProcessHeap = RtlCreateHeap(0,
                                    (PVOID)HEAP_BASE,
                                    NTHeaders->OptionalHeader.SizeOfHeapCommit,
@@ -109,9 +110,6 @@ LdrInitializeThunk (ULONG Unknown1,
        ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
      }
 
-   /* initialize process heaps support */
-   RtlpInitProcessHeaps (Peb);
-
    /* initalize peb lock support */
    RtlInitializeCriticalSection (&PebLock);
    Peb->FastPebLock = &PebLock;
index 25763ad..cae6e8c 100644 (file)
@@ -5,6 +5,13 @@
  * Copyright 1998 Ulrich Weigand
  */
 
+
+/* Note: the heap data structures are based on what Pietrek describes in his
+ * book 'Windows 95 System Programming Secrets'. The layout is not exactly
+ * the same, but could be easily adapted if it turns out some programs
+ * require it.
+ */
+
 #include <string.h>
 #include <ddk/ntddk.h>
 #include <ntdll/rtl.h>
 #define NDEBUG
 #include <ntdll/ntdll.h>
 
-CRITICAL_SECTION ProcessHeapsLock;
+#define DPRINTF DPRINT
+#define ERR DPRINT
+#define SetLastError(x)
+#define WARN DPRINT
+#define TRACE DPRINT
+#define WARN_ON(x) (1)
+
+#ifdef NDEBUG
+#define TRACE_ON(x) (0)
+#define assert(x)
+#else
+#define TRACE_ON(x) (1)
+#define assert(x)
+#endif
+
+
+static CRITICAL_SECTION RtlpProcessHeapsListLock;
 
-/* Note: the heap data structures are based on what Pietrek describes in his
- * book 'Windows 95 System Programming Secrets'. The layout is not exactly
- * the same, but could be easily adapted if it turns out some programs
- * require it.
- */
 
 typedef struct tagARENA_INUSE
 {
     DWORD  size;                    /* Block size; must be the first field */
     WORD   threadId;                /* Allocating thread id */
     WORD   magic;                   /* Magic number */
-    DWORD  callerEIP;               /* EIP of caller upon allocation */
+    void  *callerEIP;               /* EIP of caller upon allocation */
 } ARENA_INUSE;
 
 typedef struct tagARENA_FREE
@@ -48,6 +66,9 @@ typedef struct tagARENA_FREE
 #define ARENA_INUSE_FILLER     0x55
 #define ARENA_FREE_FILLER      0xaa
 
+#define QUIET                  1           /* Suppress messages  */
+#define NOISY                  0           /* Report all errors  */
+
 #define HEAP_NB_FREE_LISTS   4   /* Number of free lists */
 
 /* Max size of the blocks on the free lists */
@@ -85,13 +106,43 @@ typedef struct tagHEAP
     CRITICAL_SECTION critSection;   /* Critical section for serialization */
     DWORD            flags;         /* Heap flags */
     DWORD            magic;         /* Magic number */
+    void            *private;       /* Private pointer for the user of the heap */
 } HEAP;
 
 #define HEAP_MAGIC       ((DWORD)('H' | ('E'<<8) | ('A'<<16) | ('P'<<24)))
 
 #define HEAP_DEF_SIZE        0x110000   /* Default heap size = 1Mb + 64Kb */
 #define HEAP_MIN_BLOCK_SIZE  (8+sizeof(ARENA_FREE))  /* Min. heap block size */
+#define COMMIT_MASK          0xffff  /* bitmask for commit/decommit granularity */
 
+#if 0
+HANDLE SystemHeap = 0;
+HANDLE SegptrHeap = 0;
+#endif
+
+#ifdef __WINE__
+SYSTEM_HEAP_DESCR *SystemHeapDescr = 0;
+#endif
+
+#if 0
+static HEAP *processHeap;  /* main process heap */
+static HEAP *firstHeap;    /* head of secondary heaps list */
+#endif
+
+#if 0
+/* address where we try to map the system heap */
+#define SYSTEM_HEAP_BASE  ((void*)0x65430000)
+#endif
+
+static BOOL HEAP_IsRealArena( HANDLE heap, DWORD flags, LPCVOID block, BOOL quiet );
+
+#ifdef __GNUC__
+#define GET_EIP()    (__builtin_return_address(0))
+#define SET_EIP(ptr) ((ARENA_INUSE*)(ptr) - 1)->callerEIP = GET_EIP()
+#else
+#define GET_EIP()    0
+#define SET_EIP(ptr) /* nothing */
+#endif  /* __GNUC__ */
 
 /***********************************************************************
  *           HEAP_Dump
@@ -102,19 +153,19 @@ void HEAP_Dump( HEAP *heap )
     SUBHEAP *subheap;
     char *ptr;
 
-    DPRINT( "Heap: %08lx\n", (DWORD)heap );
-    DPRINT( "Next: %08lx  Sub-heaps: %08lx",
+    DPRINTF( "Heap: %08lx\n", (DWORD)heap );
+    DPRINTF( "Next: %08lx  Sub-heaps: %08lx",
          (DWORD)heap->next, (DWORD)&heap->subheap );
     subheap = &heap->subheap;
     while (subheap->next)
     {
-        DPRINT( " -> %08lx", (DWORD)subheap->next );
+        DPRINTF( " -> %08lx", (DWORD)subheap->next );
         subheap = subheap->next;
     }
 
-    DPRINT( "\nFree lists:\n Block   Stat   Size    Id\n" );
+    DPRINTF( "\nFree lists:\n Block   Stat   Size    Id\n" );
     for (i = 0; i < HEAP_NB_FREE_LISTS; i++)
-        DPRINT( "%08lx free %08lx %04x prev=%08lx next=%08lx\n",
+        DPRINTF( "%08lx free %08lx %04x prev=%08lx next=%08lx\n",
              (DWORD)&heap->freeList[i].arena, heap->freeList[i].arena.size,
              heap->freeList[i].arena.threadId,
              (DWORD)heap->freeList[i].arena.prev,
@@ -124,17 +175,17 @@ void HEAP_Dump( HEAP *heap )
     while (subheap)
     {
         DWORD freeSize = 0, usedSize = 0, arenaSize = subheap->headerSize;
-        DPRINT( "\n\nSub-heap %08lx: size=%08lx committed=%08lx\n",
+        DPRINTF( "\n\nSub-heap %08lx: size=%08lx committed=%08lx\n",
              (DWORD)subheap, subheap->size, subheap->commitSize );
        
-        DPRINT( "\n Block   Stat   Size    Id\n" );
+        DPRINTF( "\n Block   Stat   Size    Id\n" );
         ptr = (char*)subheap + subheap->headerSize;
         while (ptr < (char *)subheap + subheap->size)
         {
             if (*(DWORD *)ptr & ARENA_FLAG_FREE)
             {
                 ARENA_FREE *pArena = (ARENA_FREE *)ptr;
-                DPRINT( "%08lx free %08lx %04x prev=%08lx next=%08lx\n",
+                DPRINTF( "%08lx free %08lx %04x prev=%08lx next=%08lx\n",
                      (DWORD)pArena, pArena->size & ARENA_SIZE_MASK,
                      pArena->threadId, (DWORD)pArena->prev,
                      (DWORD)pArena->next);
@@ -145,7 +196,7 @@ void HEAP_Dump( HEAP *heap )
             else if (*(DWORD *)ptr & ARENA_FLAG_PREV_FREE)
             {
                 ARENA_INUSE *pArena = (ARENA_INUSE *)ptr;
-                DPRINT( "%08lx Used %08lx %04x back=%08lx EIP=%08lx\n",
+                DPRINTF( "%08lx Used %08lx %04x back=%08lx EIP=%p\n",
                      (DWORD)pArena, pArena->size & ARENA_SIZE_MASK,
                      pArena->threadId, *((DWORD *)pArena - 1),
                      pArena->callerEIP );
@@ -156,7 +207,7 @@ void HEAP_Dump( HEAP *heap )
             else
             {
                 ARENA_INUSE *pArena = (ARENA_INUSE *)ptr;
-                DPRINT( "%08lx used %08lx %04x EIP=%08lx\n",
+                DPRINTF( "%08lx used %08lx %04x EIP=%p\n",
                      (DWORD)pArena, pArena->size & ARENA_SIZE_MASK,
                      pArena->threadId, pArena->callerEIP );
                 ptr += sizeof(*pArena) + (pArena->size & ARENA_SIZE_MASK);
@@ -164,7 +215,7 @@ void HEAP_Dump( HEAP *heap )
                 usedSize += pArena->size & ARENA_SIZE_MASK;
             }
         }
-        DPRINT( "\nTotal: Size=%08lx Committed=%08lx Free=%08lx Used=%08lx Arenas=%08lx (%ld%%)\n\n",
+        DPRINTF( "\nTotal: Size=%08lx Committed=%08lx Free=%08lx Used=%08lx Arenas=%08lx (%ld%%)\n\n",
              subheap->size, subheap->commitSize, freeSize, usedSize,
              arenaSize, (arenaSize * 100) / subheap->size );
         subheap = subheap->next;
@@ -184,17 +235,15 @@ static HEAP *HEAP_GetPtr(
     HEAP *heapPtr = (HEAP *)heap;
     if (!heapPtr || (heapPtr->magic != HEAP_MAGIC))
     {
-        DbgPrint(heap, "Invalid heap %08x!\n", heap );
-       for(;;);
-//        SetLastError( ERROR_INVALID_HANDLE );
+        ERR("Invalid heap %08x!\n", heap );
+        SetLastError( ERROR_INVALID_HANDLE );
         return NULL;
     }
-    if (!RtlValidateHeap( heap, 0, NULL ))
+    if (TRACE_ON(heap) && !HEAP_IsRealArena( heap, 0, NULL, NOISY ))
     {
         HEAP_Dump( heapPtr );
-        DbgPrint("NTDLL:%s:%d: assertion failed\n",__FILE__,__LINE__);
-       for(;;);
-//        SetLastError( ERROR_INVALID_HANDLE );
+        assert( FALSE );
+        SetLastError( ERROR_INVALID_HANDLE );
         return NULL;
     }
     return heapPtr;
@@ -246,32 +295,41 @@ static SUBHEAP *HEAP_FindSubHeap(
  *
  * Make sure the heap storage is committed up to (not including) ptr.
  */
-static BOOL HEAP_Commit( SUBHEAP *subheap, void *ptr )
+static inline BOOL HEAP_Commit( SUBHEAP *subheap, void *ptr )
 {
-   DWORD size = (DWORD)((char *)ptr - (char *)subheap);
-   ULONG commitsize;
-   PVOID address;
-   NTSTATUS Status;
+    DWORD size = (DWORD)((char *)ptr - (char *)subheap);
+    NTSTATUS Status;
+    PVOID address;
+    ULONG commitsize;
    
-   size = (size + 0xfff) & 0xfffff000;  /* Align size on a page boundary */
-   if (size > subheap->size) size = subheap->size;
-   if (size <= subheap->commitSize) return TRUE;
-   commitsize = size - subheap->commitSize;
-   address = (PVOID)((char *)subheap + subheap->commitSize);
-   Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
-                                   &address,
-                                   0,
-                                   &commitsize,
-                                   MEM_COMMIT,
-                                   PAGE_EXECUTE_READWRITE);
-   if (!NT_SUCCESS(Status))
-     {
-       DbgPrint("ZwAllocateVirtualMemory failed\n");
-       for(;;);
-       return(FALSE);
-     }
-   subheap->commitSize = size;
-   return TRUE;
+    size = (size + COMMIT_MASK) & ~COMMIT_MASK;
+    if (size > subheap->size) size = subheap->size;
+    if (size <= subheap->commitSize) return TRUE;
+   
+    address = (PVOID)((char *)subheap + subheap->commitSize);
+    commitsize = size - subheap->commitSize;
+#if 1   
+    Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+                                    &address,
+                                    0,
+                                    &commitsize,
+                                    MEM_COMMIT,
+                                    PAGE_EXECUTE_READWRITE);
+    if (!NT_SUCCESS(Status))
+#else   
+    if (!VirtualAlloc( (char *)subheap + subheap->commitSize,
+                       size - subheap->commitSize, MEM_COMMIT,
+                       PAGE_EXECUTE_READWRITE))
+#endif     
+    {
+        WARN("Could not commit %08lx bytes at %08lx for heap %08lx\n",
+                 size - subheap->commitSize,
+                 (DWORD)((char *)subheap + subheap->commitSize),
+                 (DWORD)subheap->heap );
+        return FALSE;
+    }
+    subheap->commitSize = size;
+    return TRUE;
 }
 
 
@@ -280,28 +338,33 @@ static BOOL HEAP_Commit( SUBHEAP *subheap, void *ptr )
  *
  * If possible, decommit the heap storage from (including) 'ptr'.
  */
-static BOOL HEAP_Decommit( SUBHEAP *subheap, void *ptr )
+static inline BOOL HEAP_Decommit( SUBHEAP *subheap, void *ptr )
 {
     DWORD size = (DWORD)((char *)ptr - (char *)subheap);
-   PVOID freebase;
-   ULONG freesize;
-   NTSTATUS Status;
-   
-    size = (size + 0xfff) & 0xfffff000;  /* Align size on a page boundary */
+    PVOID address;
+    ULONG decommitsize;
+    NTSTATUS Status;
+    /* round to next block and add one full block */
+    size = ((size + COMMIT_MASK) & ~COMMIT_MASK) + COMMIT_MASK + 1;
     if (size >= subheap->commitSize) return TRUE;
-   freebase = (PVOID)((char *)subheap + size);
-   freesize = subheap->commitSize - size;
-   Status = ZwFreeVirtualMemory(NtCurrentProcess(), 
-                               &freebase,
-                               &freesize,
-                               MEM_DECOMMIT);
-     if (!NT_SUCCESS(Status))
-     {
-        DbgPrint("Could not decommit %08lx bytes at %08lx for heap %08lx\n",
+   
+#if 1  
+    address = (PVOID)((char *)subheap + size);
+    decommitsize = subheap->commitSize - size;
+    Status = ZwFreeVirtualMemory(NtCurrentProcess(),
+                                &address,
+                                &decommitsize,
+                                MEM_DECOMMIT);
+    if (!NT_SUCCESS(Status));
+#else   
+    if (!VirtualFree( (char *)subheap + size,
+                      subheap->commitSize - size, MEM_DECOMMIT ))
+#endif     
+    {
+        WARN("Could not decommit %08lx bytes at %08lx for heap %08lx\n",
                  subheap->commitSize - size,
                  (DWORD)((char *)subheap + size),
                  (DWORD)subheap->heap );
-       for(;;);
         return FALSE;
     }
     subheap->commitSize = size;
@@ -322,11 +385,16 @@ static void HEAP_CreateFreeBlock( SUBHEAP *subheap, void *ptr, DWORD size )
     /* Create a free arena */
 
     pFree = (ARENA_FREE *)ptr;
+#if 0   
+    pFree->threadId = GetCurrentTask();
+#else   
+    pFree->threadId = (DWORD)NtCurrentTeb()->Cid.UniqueThread;
+#endif   
     pFree->magic = ARENA_FREE_MAGIC;
 
     /* If debugging, erase the freed block content */
 
-    if (1) // DEBUGGING
+    if (TRACE_ON(heap))
     {
         char *pEnd = (char *)ptr + size;
         if (pEnd > (char *)subheap + subheap->commitSize)
@@ -345,7 +413,7 @@ static void HEAP_CreateFreeBlock( SUBHEAP *subheap, void *ptr, DWORD size )
         pNext->next->prev = pNext->prev;
         pNext->prev->next = pNext->next;
         size += (pNext->size & ARENA_SIZE_MASK) + sizeof(*pNext);
-        if (1) // DEBUGGING
+        if (TRACE_ON(heap))
             memset( pNext, ARENA_FREE_FILLER, sizeof(ARENA_FREE) );
     }
 
@@ -409,13 +477,25 @@ static void HEAP_MakeInUseBlockFree( SUBHEAP *subheap, ARENA_INUSE *pArena )
         if (pPrev) pPrev->next = subheap->next;
         /* Free the memory */
         subheap->magic = 0;
-        ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID*)&subheap, 0, MEM_RELEASE );
+#if 0       
+        if (subheap->selector) FreeSelector16( subheap->selector );
+#endif
+#if 0       
+        VirtualFree( subheap, 0, MEM_RELEASE );
+#else
+        ZwFreeVirtualMemory(NtCurrentProcess(),
+                           (PVOID*)&subheap,
+                           0,
+                           MEM_RELEASE);
+#endif       
         return;
     }
     
     /* Decommit the end of the heap */
 
-    HEAP_Decommit( subheap, pFree + 1 );
+#if 0   
+    if (!(subheap->heap->flags & HEAP_WINE_SHARED)) HEAP_Decommit( subheap, pFree + 1 );
+#endif   
 }
 
 
@@ -447,31 +527,56 @@ static void HEAP_ShrinkBlock(SUBHEAP *subheap, ARENA_INUSE *pArena, DWORD size)
 static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags,
                                 DWORD commitSize, DWORD totalSize )
 {
-   SUBHEAP *subheap = (SUBHEAP *)address;
-   FREE_LIST_ENTRY *pEntry;
-   int i;
-   NTSTATUS Status;
+    SUBHEAP *subheap = (SUBHEAP *)address;
+    WORD selector = 0;
+    FREE_LIST_ENTRY *pEntry;
+    int i;
+    NTSTATUS Status;
    
     /* Commit memory */
 
-   Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
-                                   &address, 
-                                   0,
-                                   (PULONG)&commitSize, 
-                                   MEM_COMMIT, 
-                                   PAGE_EXECUTE_READWRITE);
+#if 0   
+    if (flags & HEAP_WINE_SHARED)
+        commitSize = totalSize;  /* always commit everything in a shared heap */
+#endif
+#if 0   
+    if (!VirtualAlloc(address, commitSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
+#else
+    Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+                                    &address,
+                                    0,
+                                    (PULONG)&commitSize,
+                                    MEM_COMMIT,
+                                    PAGE_EXECUTE_READWRITE);
    if (!NT_SUCCESS(Status))
+#endif     
     {
-        DbgPrint("Could not commit %08lx bytes for sub-heap %08lx\n",
+        WARN("Could not commit %08lx bytes for sub-heap %08lx\n",
                    commitSize, (DWORD)address );
-       for(;;);
         return FALSE;
     }
 
+    /* Allocate a selector if needed */
 
+#if 0   
+    if (flags & HEAP_WINE_SEGPTR)
+    {
+        selector = SELECTOR_AllocBlock( address, totalSize,
+                           (flags & (HEAP_WINE_CODESEG|HEAP_WINE_CODE16SEG))
+                            ? SEGMENT_CODE : SEGMENT_DATA,
+                           (flags & HEAP_WINE_CODESEG) != 0, FALSE );
+        if (!selector)
+        {
+            ERR("Could not allocate selector\n" );
+            return FALSE;
+        }
+    }
+#endif
+   
     /* Fill the sub-heap structure */
 
     subheap->heap       = heap;
+    subheap->selector   = selector;
     subheap->size       = totalSize;
     subheap->commitSize = commitSize;
     subheap->magic      = SUBHEAP_MAGIC;
@@ -511,6 +616,9 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags,
         /* Initialize critical section */
 
         RtlInitializeCriticalSection( &heap->critSection );
+#if 0       
+       if (!SystemHeap) MakeCriticalSectionGlobal( &heap->critSection );
+#endif       
     }
  
     /* Create the first free block */
@@ -527,37 +635,65 @@ static BOOL HEAP_InitSubHeap( HEAP *heap, LPVOID address, DWORD flags,
  * Create a sub-heap of the given size.
  * If heap == NULL, creates a main heap.
  */
-static SUBHEAP *HEAP_CreateSubHeap(PVOID BaseAddress,
-                                  HEAP *heap, 
-                                  DWORD flags,
-                                  DWORD commitSize, 
-                                  DWORD totalSize )
+static SUBHEAP *HEAP_CreateSubHeap(PVOID BaseAddress,  
+                                  HEAP *heap, DWORD flags, 
+                                   DWORD commitSize, DWORD totalSize )
 {
     LPVOID address;
+    NTSTATUS Status;
    
     /* Round-up sizes on a 64K boundary */
 
-   totalSize  = (totalSize + 0xffff) & 0xffff0000;
-   commitSize = (commitSize + 0xffff) & 0xffff0000;
-   if (!commitSize) commitSize = 0x10000;
-   if (totalSize < commitSize) totalSize = commitSize;
+#if 0   
+    if (flags & HEAP_WINE_SEGPTR)
+    {
+        totalSize = commitSize = 0x10000;  /* Only 64K at a time for SEGPTRs */
+    }
+    else
+#else
+    if (1)
+#endif       
+    {
+        totalSize  = (totalSize + 0xffff) & 0xffff0000;
+        commitSize = (commitSize + 0xffff) & 0xffff0000;
+        if (!commitSize) commitSize = 0x10000;
+        if (totalSize < commitSize) totalSize = commitSize;
+    }
 
     /* Allocate the memory block */
-   
-   address = BaseAddress;
-   ZwAllocateVirtualMemory(NtCurrentProcess(),
-                          &address,
-                          0,
-                          (PULONG)&totalSize,
-                          MEM_RESERVE, 
-                          PAGE_EXECUTE_READWRITE);
+
+#if 0   
+    if (!(address = VirtualAlloc( NULL, totalSize,
+                                  MEM_RESERVE, PAGE_EXECUTE_READWRITE )))
+#else
+    address = BaseAddress;
+    Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+                                    &address,
+                                    0,
+                                    (PULONG)&totalSize,
+                                    MEM_RESERVE,
+                                    PAGE_EXECUTE_READWRITE);
+    if (!NT_SUCCESS(Status))
+#endif     
+    {
+        WARN("Could not VirtualAlloc %08lx bytes\n",
+                 totalSize );
+        return NULL;
+    }
 
     /* Initialize subheap */
 
     if (!HEAP_InitSubHeap( heap? heap : (HEAP *)address, 
                            address, flags, commitSize, totalSize ))
     {
-        ZwFreeVirtualMemory(NtCurrentProcess(), address, 0, MEM_RELEASE );
+#if 0       
+        VirtualFree( address, 0, MEM_RELEASE );
+#else
+        ZwFreeVirtualMemory(NtCurrentProcess(),
+                           address,
+                           0,
+                           MEM_RELEASE);
+#endif       
         return NULL;
     }
 
@@ -601,7 +737,7 @@ static ARENA_FREE *HEAP_FindFreeBlock( HEAP *heap, DWORD size,
 
     if (!(heap->flags & HEAP_GROWABLE))
     {
-        DbgPrint("Not enough space in heap %08lx for %08lx bytes\n",
+        WARN("Not enough space in heap %08lx for %08lx bytes\n",
                  (DWORD)heap, size );
         return NULL;
     }
@@ -610,7 +746,7 @@ static ARENA_FREE *HEAP_FindFreeBlock( HEAP *heap, DWORD size,
                                         max( HEAP_DEF_SIZE, size ) )))
         return NULL;
 
-    DPRINT("created new sub-heap %08lx of %08lx bytes for heap %08lx\n",
+    TRACE("created new sub-heap %08lx of %08lx bytes for heap %08lx\n",
                 (DWORD)subheap, size, (DWORD)heap );
 
     *ppSubHeap = subheap;
@@ -646,58 +782,52 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
     /* Check magic number */
     if (pArena->magic != ARENA_FREE_MAGIC)
     {
-        DbgPrint("Heap %08lx: invalid free arena magic for %08lx (%x)\n",
-                 (DWORD)subheap->heap, (DWORD)pArena, &pArena->magic );
-       for(;;);
+        ERR("Heap %08lx: invalid free arena magic for %08lx\n",
+                 (DWORD)subheap->heap, (DWORD)pArena );
         return FALSE;
     }
     /* Check size flags */
     if (!(pArena->size & ARENA_FLAG_FREE) ||
         (pArena->size & ARENA_FLAG_PREV_FREE))
     {
-        DbgPrint("Heap %08lx: bad flags %lx for free arena %08lx\n",
+        ERR("Heap %08lx: bad flags %lx for free arena %08lx\n",
                  (DWORD)subheap->heap, pArena->size & ~ARENA_SIZE_MASK, (DWORD)pArena );
-       for(;;);
     }
     /* Check arena size */
     if ((char *)(pArena + 1) + (pArena->size & ARENA_SIZE_MASK) > heapEnd)
     {
-        DbgPrint("Heap %08lx: bad size %08lx for free arena %08lx\n",
+        ERR("Heap %08lx: bad size %08lx for free arena %08lx\n",
                  (DWORD)subheap->heap, (DWORD)pArena->size & ARENA_SIZE_MASK, (DWORD)pArena );
-       for(;;);
         return FALSE;
     }
     /* Check that next pointer is valid */
     if (!HEAP_IsValidArenaPtr( subheap->heap, pArena->next ))
     {
-        DbgPrint("Heap %08lx: bad next ptr %08lx for arena %08lx\n",
+        ERR("Heap %08lx: bad next ptr %08lx for arena %08lx\n",
                  (DWORD)subheap->heap, (DWORD)pArena->next, (DWORD)pArena );
-       for(;;);
         return FALSE;
     }
     /* Check that next arena is free */
     if (!(pArena->next->size & ARENA_FLAG_FREE) ||
         (pArena->next->magic != ARENA_FREE_MAGIC))
     { 
-        DPRINT("Heap %08lx: next arena %08lx invalid for %08lx\n", 
+        ERR("Heap %08lx: next arena %08lx invalid for %08lx\n", 
                  (DWORD)subheap->heap, (DWORD)pArena->next, (DWORD)pArena );
         return FALSE;
     }
     /* Check that prev pointer is valid */
     if (!HEAP_IsValidArenaPtr( subheap->heap, pArena->prev ))
     {
-        DbgPrint("Heap %08lx: bad prev ptr %08lx for arena %08lx\n",
+        ERR("Heap %08lx: bad prev ptr %08lx for arena %08lx\n",
                  (DWORD)subheap->heap, (DWORD)pArena->prev, (DWORD)pArena );
-       for(;;);
         return FALSE;
     }
     /* Check that prev arena is free */
     if (!(pArena->prev->size & ARENA_FLAG_FREE) ||
         (pArena->prev->magic != ARENA_FREE_MAGIC))
     { 
-        DbgPrint("Heap %08lx: prev arena %08lx invalid for %08lx\n", 
+        ERR("Heap %08lx: prev arena %08lx invalid for %08lx\n", 
                  (DWORD)subheap->heap, (DWORD)pArena->prev, (DWORD)pArena );
-       for(;;);
         return FALSE;
     }
     /* Check that next block has PREV_FREE flag */
@@ -706,19 +836,17 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
         if (!(*(DWORD *)((char *)(pArena + 1) +
             (pArena->size & ARENA_SIZE_MASK)) & ARENA_FLAG_PREV_FREE))
         {
-            DbgPrint("Heap %08lx: free arena %08lx next block has no PREV_FREE flag\n",
+            ERR("Heap %08lx: free arena %08lx next block has no PREV_FREE flag\n",
                      (DWORD)subheap->heap, (DWORD)pArena );
-          for(;;);
             return FALSE;
         }
         /* Check next block back pointer */
         if (*((ARENA_FREE **)((char *)(pArena + 1) +
             (pArena->size & ARENA_SIZE_MASK)) - 1) != pArena)
         {
-            DbgPrint("Heap %08lx: arena %08lx has wrong back ptr %08lx\n",
+            ERR("Heap %08lx: arena %08lx has wrong back ptr %08lx\n",
                      (DWORD)subheap->heap, (DWORD)pArena,
                      *((DWORD *)((char *)(pArena+1)+ (pArena->size & ARENA_SIZE_MASK)) - 1));
-          for(;;);
             return FALSE;
         }
     }
@@ -729,40 +857,45 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
 /***********************************************************************
  *           HEAP_ValidateInUseArena
  */
-static BOOL HEAP_ValidateInUseArena( SUBHEAP *subheap, ARENA_INUSE *pArena )
+static BOOL HEAP_ValidateInUseArena( SUBHEAP *subheap, ARENA_INUSE *pArena, BOOL quiet )
 {
     char *heapEnd = (char *)subheap + subheap->size;
 
     /* Check magic number */
     if (pArena->magic != ARENA_INUSE_MAGIC)
     {
-        DbgPrint("Heap %08lx: invalid in-use arena magic for %08lx (%x)\n",
-                 (DWORD)subheap->heap, (DWORD)pArena, &pArena->magic );
-       for(;;);
+        if (quiet == NOISY) {
+        ERR("Heap %08lx: invalid in-use arena magic for %08lx\n",
+                 (DWORD)subheap->heap, (DWORD)pArena );
+            if (TRACE_ON(heap))
+               HEAP_Dump( subheap->heap );
+        }  else if (WARN_ON(heap)) {
+            WARN("Heap %08lx: invalid in-use arena magic for %08lx\n",
+                 (DWORD)subheap->heap, (DWORD)pArena );
+            if (TRACE_ON(heap))
+               HEAP_Dump( subheap->heap );
+        }
         return FALSE;
     }
     /* Check size flags */
     if (pArena->size & ARENA_FLAG_FREE) 
     {
-        DbgPrint("Heap %08lx: bad flags %lx for in-use arena %08lx\n",
+        ERR("Heap %08lx: bad flags %lx for in-use arena %08lx\n",
                  (DWORD)subheap->heap, pArena->size & ~ARENA_SIZE_MASK, (DWORD)pArena );
-       for(;;);
     }
     /* Check arena size */
     if ((char *)(pArena + 1) + (pArena->size & ARENA_SIZE_MASK) > heapEnd)
     {
-        DbgPrint("Heap %08lx: bad size %08lx for in-use arena %08lx\n",
+        ERR("Heap %08lx: bad size %08lx for in-use arena %08lx\n",
                  (DWORD)subheap->heap, (DWORD)pArena->size & ARENA_SIZE_MASK, (DWORD)pArena );
-       for(;;);
         return FALSE;
     }
     /* Check next arena PREV_FREE flag */
     if (((char *)(pArena + 1) + (pArena->size & ARENA_SIZE_MASK) < heapEnd) &&
         (*(DWORD *)((char *)(pArena + 1) + (pArena->size & ARENA_SIZE_MASK)) & ARENA_FLAG_PREV_FREE))
     {
-        DbgPrint("Heap %08lx: in-use arena %08lx next block has PREV_FREE flag\n",
+        ERR("Heap %08lx: in-use arena %08lx next block has PREV_FREE flag\n",
                  (DWORD)subheap->heap, (DWORD)pArena );
-       for(;;);
         return FALSE;
     }
     /* Check prev free arena */
@@ -772,26 +905,23 @@ static BOOL HEAP_ValidateInUseArena( SUBHEAP *subheap, ARENA_INUSE *pArena )
         /* Check prev pointer */
         if (!HEAP_IsValidArenaPtr( subheap->heap, pPrev ))
         {
-            DbgPrint("Heap %08lx: bad back ptr %08lx for arena %08lx\n",
+            ERR("Heap %08lx: bad back ptr %08lx for arena %08lx\n",
                     (DWORD)subheap->heap, (DWORD)pPrev, (DWORD)pArena );
-          for(;;);
             return FALSE;
         }
         /* Check that prev arena is free */
         if (!(pPrev->size & ARENA_FLAG_FREE) ||
             (pPrev->magic != ARENA_FREE_MAGIC))
         { 
-            DbgPrint("Heap %08lx: prev arena %08lx invalid for in-use %08lx\n", 
+            ERR("Heap %08lx: prev arena %08lx invalid for in-use %08lx\n", 
                      (DWORD)subheap->heap, (DWORD)pPrev, (DWORD)pArena );
-          for(;;);
             return FALSE;
         }
         /* Check that prev arena is really the previous block */
         if ((char *)(pPrev + 1) + (pPrev->size & ARENA_SIZE_MASK) != (char *)pArena)
         {
-            DbgPrint("Heap %08lx: prev arena %08lx is not prev for in-use %08lx\n",
+            ERR("Heap %08lx: prev arena %08lx is not prev for in-use %08lx\n",
                      (DWORD)subheap->heap, (DWORD)pPrev, (DWORD)pArena );
-          for(;;);
             return FALSE;
         }
     }
@@ -823,11 +953,101 @@ int HEAP_IsInsideHeap(
 
     if (!heapPtr) return 0;
     flags |= heapPtr->flags;
-    if (!(flags & HEAP_NO_SERIALIZE)) RtlLockHeap( heap );
+    if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
     ret = (((subheap = HEAP_FindSubHeap( heapPtr, ptr )) != NULL) &&
            (((char *)ptr >= (char *)subheap + subheap->headerSize
                               + sizeof(ARENA_INUSE))));
-    if (!(flags & HEAP_NO_SERIALIZE)) RtlUnlockHeap( heap );
+    if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+    return ret;
+}
+
+
+
+
+/***********************************************************************
+ *           HEAP_IsRealArena  [Internal]
+ * Validates a block is a valid arena.
+ *
+ * RETURNS
+ *     TRUE: Success
+ *     FALSE: Failure
+ */
+static BOOL HEAP_IsRealArena(
+              HANDLE heap,   /* [in] Handle to the heap */
+              DWORD flags,   /* [in] Bit flags that control access during operation */
+              LPCVOID block, /* [in] Optional pointer to memory block to validate */
+              BOOL quiet     /* [in] Flag - if true, HEAP_ValidateInUseArena
+                              *             does not complain    */
+) {
+    SUBHEAP *subheap;
+    HEAP *heapPtr = (HEAP *)(heap);
+    BOOL ret = TRUE;
+
+    if (!heapPtr || (heapPtr->magic != HEAP_MAGIC))
+    {
+        ERR("Invalid heap %08x!\n", heap );
+        return FALSE;
+    }
+
+    flags &= HEAP_NO_SERIALIZE;
+    flags |= heapPtr->flags;
+    /* calling HeapLock may result in infinite recursion, so do the critsect directly */
+    if (!(flags & HEAP_NO_SERIALIZE))
+        RtlEnterCriticalSection( &heapPtr->critSection );
+
+    if (block)
+    {
+        /* Only check this single memory block */
+
+        /* The following code is really HEAP_IsInsideHeap   *
+         * with serialization already done.                 */
+        if (!(subheap = HEAP_FindSubHeap( heapPtr, block )) ||
+            ((char *)block < (char *)subheap + subheap->headerSize
+                              + sizeof(ARENA_INUSE)))
+        {
+            if (quiet == NOISY) 
+                ERR("Heap %08lx: block %08lx is not inside heap\n",
+                     (DWORD)heap, (DWORD)block );
+            else if (WARN_ON(heap)) 
+                WARN("Heap %08lx: block %08lx is not inside heap\n",
+                     (DWORD)heap, (DWORD)block );
+            ret = FALSE;
+        } else
+            ret = HEAP_ValidateInUseArena( subheap, (ARENA_INUSE *)block - 1, quiet );
+
+        if (!(flags & HEAP_NO_SERIALIZE))
+            RtlLeaveCriticalSection( &heapPtr->critSection );
+        return ret;
+    }
+
+    subheap = &heapPtr->subheap;
+    while (subheap && ret)
+    {
+        char *ptr = (char *)subheap + subheap->headerSize;
+        while (ptr < (char *)subheap + subheap->size)
+        {
+            if (*(DWORD *)ptr & ARENA_FLAG_FREE)
+            {
+                if (!HEAP_ValidateFreeArena( subheap, (ARENA_FREE *)ptr )) {
+                    ret = FALSE;
+                    break;
+                }
+                ptr += sizeof(ARENA_FREE) + (*(DWORD *)ptr & ARENA_SIZE_MASK);
+            }
+            else
+            {
+                if (!HEAP_ValidateInUseArena( subheap, (ARENA_INUSE *)ptr, NOISY )) {
+                    ret = FALSE;
+                    break;
+                }
+                ptr += sizeof(ARENA_INUSE) + (*(DWORD *)ptr & ARENA_SIZE_MASK);
+            }
+        }
+        subheap = subheap->next;
+    }
+
+    if (!(flags & HEAP_NO_SERIALIZE))
+       RtlLeaveCriticalSection( &heapPtr->critSection );
     return ret;
 }
 
@@ -845,31 +1065,49 @@ HANDLE STDCALL RtlCreateHeap(ULONG flags,
                             PVOID Unknown,
                             PRTL_HEAP_DEFINITION Definition) 
 {
-   SUBHEAP *subheap;
-   
-   /* Allocate the heap block */
-   
-   DPRINT("RtlCreateHeap(flags %x, BaseAddress %x, initialSize %x, "
-         "maxSize %x\n)",flags,BaseAddress,initialSize, maxSize);
+    SUBHEAP *subheap;
+    ULONG i;
    
+    /* Allocate the heap block */
+
     if (!maxSize)
     {
         maxSize = HEAP_DEF_SIZE;
         flags |= HEAP_GROWABLE;
     }
-    if (!(subheap = HEAP_CreateSubHeap(BaseAddress,
-                                      NULL, 
-                                      flags, 
-                                      initialSize, 
-                                      maxSize)))
+    if (!(subheap = HEAP_CreateSubHeap( BaseAddress, NULL, flags, initialSize, maxSize )))
     {
-//        SetLastError( ERROR_OUTOFMEMORY );
-       DbgPrint("RtlCreateHeap() = %x\n",0);
+        SetLastError( ERROR_OUTOFMEMORY );
         return 0;
     }
 
-   DPRINT("RtlCreateHeap() = %x\n",subheap);
-   
+#if 0   
+    /* link it into the per-process heap list */
+    if (processHeap)
+    {
+        HEAP *heapPtr = subheap->heap;
+        RtlEnterCriticalSection( &processHeap->critSection );
+        heapPtr->next = firstHeap;
+        firstHeap = heapPtr;
+        RtlLeaveCriticalSection( &processHeap->critSection );
+    }
+    else  /* assume the first heap we create is the process main heap */
+    {
+        processHeap = subheap->heap;
+    }
+#else
+   RtlEnterCriticalSection (&RtlpProcessHeapsListLock);
+   for (i = 0; i < NtCurrentPeb ()->NumberOfHeaps; i++)
+     {
+       if (NtCurrentPeb ()->ProcessHeaps[i] == NULL)
+         {
+            NtCurrentPeb()->ProcessHeaps[i] = (PVOID)subheap;
+            break;
+         }
+     }
+   RtlLeaveCriticalSection (&RtlpProcessHeapsListLock);   
+#endif   
+
     return (HANDLE)subheap;
 }
 
@@ -879,21 +1117,57 @@ HANDLE STDCALL RtlCreateHeap(ULONG flags,
  *     TRUE: Success
  *     FALSE: Failure
  */
-BOOL STDCALL RtlDestroyHeap(
-              HANDLE heap /* [in] Handle of heap */
-) {
+BOOL STDCALL RtlDestroyHeap( HANDLE heap /* [in] Handle of heap */ )
+{
     HEAP *heapPtr = HEAP_GetPtr( heap );
     SUBHEAP *subheap;
-
-    DPRINT("%08x\n", heap );
+    ULONG i;
+   
+    TRACE("%08x\n", heap );
     if (!heapPtr) return FALSE;
 
+#if 0   
+    if (heapPtr == processHeap)  /* cannot delete the main process heap */
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
+    else /* remove it from the per-process list */
+    {
+        HEAP **pptr;
+        RtlEnterCriticalSection( &processHeap->critSection );
+        pptr = &firstHeap;
+        while (*pptr && *pptr != heapPtr) pptr = &(*pptr)->next;
+        if (*pptr) *pptr = (*pptr)->next;
+        RtlLeaveCriticalSection( &processHeap->critSection );
+    }
+#else
+   RtlEnterCriticalSection (&RtlpProcessHeapsListLock);
+   for (i = 0; i < NtCurrentPeb ()->NumberOfHeaps; i++)
+     {
+       if (NtCurrentPeb ()->ProcessHeaps[i] == heap)
+         {
+            NtCurrentPeb()->ProcessHeaps[i] = NULL;
+            break;
+         }
+     }
+   RtlLeaveCriticalSection (&RtlpProcessHeapsListLock);
+#endif   
+   
     RtlDeleteCriticalSection( &heapPtr->critSection );
     subheap = &heapPtr->subheap;
     while (subheap)
     {
         SUBHEAP *next = subheap->next;
-        ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID*)&subheap, 0, MEM_RELEASE );
+#if 0       
+        if (subheap->selector) FreeSelector16( subheap->selector );
+        VirtualFree( subheap, 0, MEM_RELEASE );
+#else
+        ZwFreeVirtualMemory(NtCurrentProcess(),
+                           (PVOID*)&subheap,
+                           0,
+                           MEM_RELEASE);
+#endif       
         subheap = next;
     }
     return TRUE;
@@ -908,30 +1182,20 @@ BOOL STDCALL RtlDestroyHeap(
  */
 PVOID STDCALL RtlAllocateHeap(
               HANDLE heap, /* [in] Handle of private heap block */
-                            ULONG flags,   /* [in] Heap allocation control flags */
+              ULONG flags,   /* [in] Heap allocation control flags */
               ULONG size     /* [in] Number of bytes to allocate */
 ) {
     ARENA_FREE *pArena;
     ARENA_INUSE *pInUse;
     SUBHEAP *subheap;
-    HEAP *heapPtr = NULL;
+    HEAP *heapPtr = HEAP_GetPtr( heap );
 
     /* Validate the parameters */
 
+    if (!heapPtr) return NULL;
     flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY;
-    flags |= ((HEAP*)heap)->flags;
-    if (!(flags & HEAP_NO_SERIALIZE))
-     {
-       RtlLockHeap(heap);
-     }
-    heapPtr = HEAP_GetPtr(heap);
-    if (heapPtr == NULL)
-     {
-       if (!(flags & HEAP_NO_SERIALIZE))
-         {
-            RtlUnlockHeap(heap);
-         }
-     }
+    flags |= heapPtr->flags;
+    if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
     size = (size + 3) & ~3;
     if (size < HEAP_MIN_BLOCK_SIZE) size = HEAP_MIN_BLOCK_SIZE;
 
@@ -939,10 +1203,10 @@ PVOID STDCALL RtlAllocateHeap(
 
     if (!(pArena = HEAP_FindFreeBlock( heapPtr, size, &subheap )))
     {
-        DPRINT("(%08x,%08lx,%08lx): returning NULL\n",
+        TRACE("(%08x,%08lx,%08lx): returning NULL\n",
                   heap, flags, size  );
-        if (!(flags & HEAP_NO_SERIALIZE)) RtlUnlockHeap( heap );
-//        SetLastError( ERROR_COMMITMENT_LIMIT );
+        if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+        SetLastError( ERROR_COMMITMENT_LIMIT );
         return NULL;
     }
 
@@ -956,20 +1220,26 @@ PVOID STDCALL RtlAllocateHeap(
     pInUse = (ARENA_INUSE *)pArena;
     pInUse->size      = (pInUse->size & ~ARENA_FLAG_FREE)
                         + sizeof(ARENA_FREE) - sizeof(ARENA_INUSE);
-    pInUse->callerEIP = *((DWORD *)&heap - 1);  /* hack hack */
-//    pInUse->threadId  = GetCurrentTask();
+    pInUse->callerEIP = GET_EIP();
+#if 0   
+    pInUse->threadId  = GetCurrentTask();
+#else
+    pInUse->threadId  = (DWORD)NtCurrentTeb()->Cid.UniqueThread;
+#endif   
     pInUse->magic     = ARENA_INUSE_MAGIC;
 
     /* Shrink the block */
 
     HEAP_ShrinkBlock( subheap, pInUse, size );
 
-    if (flags & HEAP_ZERO_MEMORY) memset( pInUse + 1, 0, size );
-    else if (1) memset( pInUse + 1, ARENA_INUSE_FILLER, size ); //DEBUGGING
-    if (!(flags & HEAP_NO_SERIALIZE)) RtlUnlockHeap( heap );
+    if (flags & HEAP_ZERO_MEMORY)
+        memset( pInUse + 1, 0, pInUse->size & ARENA_SIZE_MASK );
+    else if (TRACE_ON(heap))
+        memset( pInUse + 1, ARENA_INUSE_FILLER, pInUse->size & ARENA_SIZE_MASK );
+
+    if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
 
-    DPRINT("(%08x,%08lx,%08lx): returning %08lx\n",
+    TRACE("(%08x,%08lx,%08lx): returning %08lx\n",
                   heap, flags, size, (DWORD)(pInUse + 1) );
     return (LPVOID)(pInUse + 1);
 }
@@ -988,35 +1258,26 @@ BOOLEAN STDCALL RtlFreeHeap(
 ) {
     ARENA_INUSE *pInUse;
     SUBHEAP *subheap;
-    HEAP *heapPtr = NULL;
+    HEAP *heapPtr = HEAP_GetPtr( heap );
 
     /* Validate the parameters */
 
-    flags &= HEAP_NO_SERIALIZE;
-    flags |= ((HEAP*)heap)->flags;
-    if (!(flags & HEAP_NO_SERIALIZE)) 
-     {
-       RtlLockHeap( heap );
-     }
-    heapPtr = HEAP_GetPtr(heap);
-    if (heapPtr == NULL)
-     {
-       if (!(flags & HEAP_NO_SERIALIZE))
-         {
-            RtlUnlockHeap(heap);
-         }
-       return(FALSE);
-     }
-    if (!ptr)
+    if (!heapPtr) return FALSE;
+    if (!ptr)  /* Freeing a NULL ptr is doesn't indicate an error in Win2k */
     {
-       DPRINT("(%08x,%08lx,%08lx): asked to free NULL\n",
+       WARN("(%08x,%08lx,%08lx): asked to free NULL\n",
                    heap, flags, (DWORD)ptr );
+       return TRUE;
     }
-    if (!ptr || !RtlValidateHeap( heap, HEAP_NO_SERIALIZE, ptr ))
+
+    flags &= HEAP_NO_SERIALIZE;
+    flags |= heapPtr->flags;
+    if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
+    if (!HEAP_IsRealArena( heap, HEAP_NO_SERIALIZE, ptr, QUIET ))
     {
-        if (!(flags & HEAP_NO_SERIALIZE)) RtlUnlockHeap( heap );
-//        SetLastError( ERROR_INVALID_PARAMETER );
-        DPRINT("(%08x,%08lx,%08lx): returning FALSE\n",
+        if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+        SetLastError( ERROR_INVALID_PARAMETER );
+        TRACE("(%08x,%08lx,%08lx): returning FALSE\n",
                       heap, flags, (DWORD)ptr );
         return FALSE;
     }
@@ -1027,10 +1288,9 @@ BOOLEAN STDCALL RtlFreeHeap(
     subheap = HEAP_FindSubHeap( heapPtr, pInUse );
     HEAP_MakeInUseBlockFree( subheap, pInUse );
 
-    if (!(flags & HEAP_NO_SERIALIZE)) RtlUnlockHeap( heap );
-/*    SetLastError( 0 ); */
+    if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
 
-    DPRINT("(%08x,%08lx,%08lx): returning TRUE\n",
+    TRACE("(%08x,%08lx,%08lx): returning TRUE\n",
                   heap, flags, (DWORD)ptr );
     return TRUE;
 }
@@ -1041,19 +1301,13 @@ BOOLEAN STDCALL RtlFreeHeap(
  * RETURNS
  *     Pointer to reallocated memory block
  *     NULL: Failure
- *
- * REVISIONS
- *     Renamed RtlReAllocateHeap as in NT
  */
-LPVOID
-STDCALL
-RtlReAllocateHeap (
-       HANDLE  heap,   /* [in] Handle of heap block */
-       DWORD   flags,  /* [in] Heap reallocation flags */
-       LPVOID  ptr,    /* [in] Address of memory to reallocate */
-       DWORD   size    /* [in] Number of bytes to reallocate */
-       )
-{
+LPVOID STDCALL RtlReAllocateHeap(
+              HANDLE heap, /* [in] Handle of heap block */
+              DWORD flags,   /* [in] Heap reallocation flags */
+              LPVOID ptr,    /* [in] Address of memory to reallocate */
+              DWORD size     /* [in] Number of bytes to reallocate */
+) {
     ARENA_INUSE *pArena;
     DWORD oldSize;
     HEAP *heapPtr;
@@ -1070,12 +1324,12 @@ RtlReAllocateHeap (
     size = (size + 3) & ~3;
     if (size < HEAP_MIN_BLOCK_SIZE) size = HEAP_MIN_BLOCK_SIZE;
 
-    if (!(flags & HEAP_NO_SERIALIZE)) RtlLockHeap( heap );
-    if (!RtlValidateHeap( heap, HEAP_NO_SERIALIZE, ptr ))
+    if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
+    if (!HEAP_IsRealArena( heap, HEAP_NO_SERIALIZE, ptr, QUIET ))
     {
-        if (!(flags & HEAP_NO_SERIALIZE)) RtlUnlockHeap( heap );
-//        SetLastError( ERROR_INVALID_PARAMETER );
-        DPRINT("(%08x,%08lx,%08lx,%08lx): returning NULL\n",
+        if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+        SetLastError( ERROR_INVALID_PARAMETER );
+        TRACE("(%08x,%08lx,%08lx,%08lx): returning NULL\n",
                       heap, flags, (DWORD)ptr, size );
         return NULL;
     }
@@ -1083,7 +1337,11 @@ RtlReAllocateHeap (
     /* Check if we need to grow the block */
 
     pArena = (ARENA_INUSE *)ptr - 1;
-//    pArena->threadId = GetCurrentTask();
+#if 0   
+    pArena->threadId = GetCurrentTask();
+#else
+    pArena->threadId = (DWORD)NtCurrentTeb()->Cid.UniqueThread;
+#endif   
     subheap = HEAP_FindSubHeap( heapPtr, pArena );
     oldSize = (pArena->size & ARENA_SIZE_MASK);
     if (size > oldSize)
@@ -1101,8 +1359,8 @@ RtlReAllocateHeap (
             if (!HEAP_Commit( subheap, (char *)pArena + sizeof(ARENA_INUSE)
                                                + size + HEAP_MIN_BLOCK_SIZE))
             {
-                if (!(flags & HEAP_NO_SERIALIZE)) RtlUnlockHeap( heap );
-//                SetLastError( ERROR_OUTOFMEMORY );
+                if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+                SetLastError( ERROR_OUTOFMEMORY );
                 return NULL;
             }
             HEAP_ShrinkBlock( subheap, pArena, size );
@@ -1116,8 +1374,8 @@ RtlReAllocateHeap (
             if ((flags & HEAP_REALLOC_IN_PLACE_ONLY) ||
                 !(pNew = HEAP_FindFreeBlock( heapPtr, size, &newsubheap )))
             {
-                if (!(flags & HEAP_NO_SERIALIZE)) RtlUnlockHeap( heap );
//               SetLastError( ERROR_OUTOFMEMORY );
+                if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+                SetLastError( ERROR_OUTOFMEMORY );
                 return NULL;
             }
 
@@ -1128,7 +1386,11 @@ RtlReAllocateHeap (
             pInUse = (ARENA_INUSE *)pNew;
             pInUse->size     = (pInUse->size & ~ARENA_FLAG_FREE)
                                + sizeof(ARENA_FREE) - sizeof(ARENA_INUSE);
-//            pInUse->threadId = GetCurrentTask();
+#if 0     
+            pInUse->threadId = GetCurrentTask();
+#else
+           pInUse->threadId = (DWORD)NtCurrentTeb()->Cid.UniqueThread;
+#endif    
             pInUse->magic    = ARENA_INUSE_MAGIC;
             HEAP_ShrinkBlock( newsubheap, pInUse, size );
             memcpy( pInUse + 1, pArena + 1, oldSize );
@@ -1149,17 +1411,17 @@ RtlReAllocateHeap (
         if (flags & HEAP_ZERO_MEMORY)
             memset( (char *)(pArena + 1) + oldSize, 0,
                     (pArena->size & ARENA_SIZE_MASK) - oldSize );
-        else if (1) // DEBUGGING
+        else if (TRACE_ON(heap))
             memset( (char *)(pArena + 1) + oldSize, ARENA_INUSE_FILLER,
                     (pArena->size & ARENA_SIZE_MASK) - oldSize );
     }
 
     /* Return the new arena */
 
-    pArena->callerEIP = *((DWORD *)&heap - 1);  /* hack hack */
-    if (!(flags & HEAP_NO_SERIALIZE)) RtlUnlockHeap( heap );
+    pArena->callerEIP = GET_EIP();
+    if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
 
-    DPRINT("(%08x,%08lx,%08lx,%08lx): returning %08lx\n",
+    TRACE("(%08x,%08lx,%08lx,%08lx): returning %08lx\n",
                   heap, flags, (DWORD)ptr, size, (DWORD)(pArena + 1) );
     return (LPVOID)(pArena + 1);
 }
@@ -1170,6 +1432,7 @@ RtlReAllocateHeap (
  */
 DWORD STDCALL RtlCompactHeap( HANDLE heap, DWORD flags )
 {
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
     return 0;
 }
 
@@ -1214,7 +1477,7 @@ BOOL STDCALL RtlUnlockHeap(
  *           HeapSize   (KERNEL32.341)
  * RETURNS
  *     Size in bytes of allocated memory
- *     0: Failure
+ *     0xffffffff: Failure
  */
 DWORD STDCALL RtlSizeHeap(
              HANDLE heap, /* [in] Handle of heap */
@@ -1227,10 +1490,10 @@ DWORD STDCALL RtlSizeHeap(
     if (!heapPtr) return FALSE;
     flags &= HEAP_NO_SERIALIZE;
     flags |= heapPtr->flags;
-    if (!(flags & HEAP_NO_SERIALIZE)) RtlLockHeap( heap );
-    if (!RtlValidateHeap( heap, HEAP_NO_SERIALIZE, ptr ))
+    if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
+    if (!HEAP_IsRealArena( heap, HEAP_NO_SERIALIZE, ptr, QUIET ))
     {
-//        SetLastError( ERROR_INVALID_PARAMETER );
+        SetLastError( ERROR_INVALID_PARAMETER );
         ret = 0xffffffff;
     }
     else
@@ -1238,9 +1501,9 @@ DWORD STDCALL RtlSizeHeap(
         ARENA_INUSE *pArena = (ARENA_INUSE *)ptr - 1;
         ret = pArena->size & ARENA_SIZE_MASK;
     }
-    if (!(flags & HEAP_NO_SERIALIZE)) RtlUnlockHeap( heap );
+    if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
 
-    DPRINT("(%08x,%08lx,%08lx): returning %08lx\n",
+    TRACE("(%08x,%08lx,%08lx): returning %08lx\n",
                   heap, flags, (DWORD)ptr, ret );
     return ret;
 }
@@ -1262,52 +1525,203 @@ BOOL STDCALL RtlValidateHeap(
               DWORD flags,   /* [in] Bit flags that control access during operation */
               PVOID block  /* [in] Optional pointer to memory block to validate */
 ) {
-    SUBHEAP *subheap;
-    HEAP *heapPtr = (HEAP *)(heap);
 
-    if (!heapPtr || (heapPtr->magic != HEAP_MAGIC))
+    return HEAP_IsRealArena( heap, flags, block, QUIET );
+}
+
+
+/***********************************************************************
+ *           HeapWalk   (KERNEL32.344)
+ * Enumerates the memory blocks in a specified heap.
+ * See HEAP_Dump() for info on heap structure.
+ *
+ * TODO
+ *   - handling of PROCESS_HEAP_ENTRY_MOVEABLE and
+ *     PROCESS_HEAP_ENTRY_DDESHARE (needs heap.c support)
+ *
+ * RETURNS
+ *     TRUE: Success
+ *     FALSE: Failure
+ */
+#if 0
+BOOL STDCALL HeapWalk(
+              HANDLE heap,               /* [in]  Handle to heap to enumerate */
+              LPPROCESS_HEAP_ENTRY entry /* [out] Pointer to structure of enumeration info */
+) {
+    HEAP *heapPtr = HEAP_GetPtr(heap);
+    SUBHEAP *sub, *currentheap = NULL;
+    BOOL ret = FALSE;
+    char *ptr;
+    int region_index = 0;
+
+    if (!heapPtr || !entry)
     {
-        DPRINT("Invalid heap %08x!\n", heap );
-        return FALSE;
+       SetLastError(ERROR_INVALID_PARAMETER);
+       return FALSE;
     }
 
-    if (block)
+    if (!(heapPtr->flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
+
+    /* set ptr to the next arena to be examined */
+
+    if (!entry->lpData) /* first call (init) ? */
     {
-        /* Only check this single memory block */
-        if (!(subheap = HEAP_FindSubHeap( heapPtr, block )) ||
-            ((char *)block < (char *)subheap + subheap->headerSize
-                              + sizeof(ARENA_INUSE)))
+       TRACE("begin walking of heap 0x%08x.\n", heap);
+       /*HEAP_Dump(heapPtr);*/
+       currentheap = &heapPtr->subheap;
+       ptr = (char*)currentheap + currentheap->headerSize;
+    }
+    else
+    {
+       ptr = entry->lpData;
+       sub = &heapPtr->subheap;
+       while (sub)
+       {
+           if (((char *)ptr >= (char *)sub) &&
+               ((char *)ptr < (char *)sub + sub->size))
+           {
+               currentheap = sub;
+               break;
+           }
+           sub = sub->next;
+           region_index++;
+       }
+       if (currentheap == NULL)
+       {
+           ERR("no matching subheap found, shouldn't happen !\n");
+           SetLastError(ERROR_NO_MORE_ITEMS);
+           goto HW_end;
+       }
+
+       ptr += entry->cbData; /* point to next arena */
+       if (ptr > (char *)currentheap + currentheap->size - 1)
+       {   /* proceed with next subheap */
+           if (!(currentheap = currentheap->next))
+           {  /* successfully finished */
+               TRACE("end reached.\n");
+               SetLastError(ERROR_NO_MORE_ITEMS);
+               goto HW_end;
+           }
+           ptr = (char*)currentheap + currentheap->headerSize;
+       }
+    }
+
+    entry->wFlags = 0;
+    if (*(DWORD *)ptr & ARENA_FLAG_FREE)
+    {
+       ARENA_FREE *pArena = (ARENA_FREE *)ptr;
+
+       /*TRACE("free, magic: %04x\n", pArena->magic);*/
+
+       entry->lpData = pArena + 1;
+       entry->cbData = pArena->size & ARENA_SIZE_MASK;
+       entry->cbOverhead = sizeof(ARENA_FREE);
+       entry->wFlags = PROCESS_HEAP_UNCOMMITTED_RANGE;
+    }
+    else
+    {
+       ARENA_INUSE *pArena = (ARENA_INUSE *)ptr;
+
+       /*TRACE("busy, magic: %04x\n", pArena->magic);*/
+       
+       entry->lpData = pArena + 1;
+       entry->cbData = pArena->size & ARENA_SIZE_MASK;
+       entry->cbOverhead = sizeof(ARENA_INUSE);
+       entry->wFlags = PROCESS_HEAP_ENTRY_BUSY;
+       /* FIXME: can't handle PROCESS_HEAP_ENTRY_MOVEABLE
+       and PROCESS_HEAP_ENTRY_DDESHARE yet */
+    }
+
+    entry->iRegionIndex = region_index;
+
+    /* first element of heap ? */
+    if (ptr == (char *)(currentheap + currentheap->headerSize))
+    {
+       entry->wFlags |= PROCESS_HEAP_REGION;
+       entry->Foo.Region.dwCommittedSize = currentheap->commitSize;
+       entry->Foo.Region.dwUnCommittedSize =
+               currentheap->size - currentheap->commitSize;
+       entry->Foo.Region.lpFirstBlock = /* first valid block */
+               currentheap + currentheap->headerSize;
+       entry->Foo.Region.lpLastBlock  = /* first invalid block */
+               currentheap + currentheap->size;
+    }
+    ret = TRUE;
+
+HW_end:
+    if (!(heapPtr->flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+
+    return ret;
+}
+
+
+/***********************************************************************
+ *           HEAP_CreateSystemHeap
+ *
+ * Create the system heap.
+ */
+BOOL HEAP_CreateSystemHeap(void)
+{
+    SYSTEM_HEAP_DESCR *descr;
+    HANDLE heap;
+    HEAP *heapPtr;
+    int created;
+
+    HANDLE map = CreateFileMappingA( INVALID_HANDLE_VALUE, NULL, SEC_COMMIT | PAGE_READWRITE,
+                                     0, HEAP_DEF_SIZE, "__SystemHeap" );
+    if (!map) return FALSE;
+    created = (GetLastError() != ERROR_ALREADY_EXISTS);
+
+    if (!(heapPtr = MapViewOfFileEx( map, FILE_MAP_ALL_ACCESS, 0, 0, 0, SYSTEM_HEAP_BASE )))
+    {
+        /* pre-defined address not available, use any one */
+        fprintf( stderr, "Warning: system heap base address %p not available\n",
+                 SYSTEM_HEAP_BASE );
+        if (!(heapPtr = MapViewOfFile( map, FILE_MAP_ALL_ACCESS, 0, 0, 0 )))
         {
-            DPRINT("Heap %08lx: block %08lx is not inside heap\n",
-                     (DWORD)heap, (DWORD)block );
+            CloseHandle( map );
             return FALSE;
         }
-        return HEAP_ValidateInUseArena( subheap, (ARENA_INUSE *)block - 1 );
     }
+    heap = (HANDLE)heapPtr;
 
-    subheap = &heapPtr->subheap;
-    while (subheap)
+    if (created)  /* newly created heap */
     {
-        char *ptr = (char *)subheap + subheap->headerSize;
-        while (ptr < (char *)subheap + subheap->size)
+        HEAP_InitSubHeap( heapPtr, heapPtr, HEAP_WINE_SHARED, 0, HEAP_DEF_SIZE );
+        HeapLock( heap );
+        descr = heapPtr->private = HeapAlloc( heap, HEAP_ZERO_MEMORY, sizeof(*descr) );
+        assert( descr );
+    }
+    else
+    {
+        /* wait for the heap to be initialized */
+        while (!heapPtr->private) Sleep(1);
+        HeapLock( heap );
+        /* remap it to the right address if necessary */
+        if (heapPtr->subheap.heap != heapPtr)
         {
-            if (*(DWORD *)ptr & ARENA_FLAG_FREE)
-            {
-                if (!HEAP_ValidateFreeArena( subheap, (ARENA_FREE *)ptr ))
-                    return FALSE;
-                ptr += sizeof(ARENA_FREE) + (*(DWORD *)ptr & ARENA_SIZE_MASK);
-            }
-            else
+            void *base = heapPtr->subheap.heap;
+            HeapUnlock( heap );
+            UnmapViewOfFile( heapPtr );
+            if (!(heapPtr = MapViewOfFileEx( map, FILE_MAP_ALL_ACCESS, 0, 0, 0, base )))
             {
-                if (!HEAP_ValidateInUseArena( subheap, (ARENA_INUSE *)ptr ))
-                    return FALSE;
-                ptr += sizeof(ARENA_INUSE) + (*(DWORD *)ptr & ARENA_SIZE_MASK);
+                fprintf( stderr, "Couldn't map system heap at the correct address (%p)\n", base );
+                CloseHandle( map );
+                return FALSE;
             }
+            heap = (HANDLE)heapPtr;
+            HeapLock( heap );
         }
-        subheap = subheap->next;
+        descr = heapPtr->private;
+        assert( descr );
     }
+    SystemHeap = heap;
+    SystemHeapDescr = descr;
+    HeapUnlock( heap );
+    CloseHandle( map );
     return TRUE;
 }
+#endif
 
 HANDLE STDCALL RtlGetProcessHeap(VOID)
 {
@@ -1316,13 +1730,17 @@ HANDLE STDCALL RtlGetProcessHeap(VOID)
 }
 
 VOID
-RtlpInitProcessHeaps (PPEB Peb)
+RtlInitializeHeapManager (VOID)
 {
-       Peb->NumberOfHeaps = 0;
-       Peb->MaximumNumberOfHeaps = (PAGESIZE - sizeof(PPEB)) / sizeof(HANDLE);
-       Peb->ProcessHeaps = (PVOID)Peb + sizeof(PEB);
-
-       RtlInitializeCriticalSection (&ProcessHeapsLock);
+   PPEB Peb;
+   
+   Peb = NtCurrentPeb();
+   
+   Peb->NumberOfHeaps = 0;
+   Peb->MaximumNumberOfHeaps = (PAGESIZE - sizeof(PPEB)) / sizeof(HANDLE);
+   Peb->ProcessHeaps = (PVOID)Peb + sizeof(PEB);
+   
+   RtlInitializeCriticalSection (&RtlpProcessHeapsListLock);
 }
 
 
@@ -1336,7 +1754,7 @@ RtlEnumProcessHeaps (
        NTSTATUS Status = STATUS_SUCCESS;
        ULONG i;
 
-       RtlEnterCriticalSection (&ProcessHeapsLock);
+       RtlEnterCriticalSection (&RtlpProcessHeapsListLock);
 
        for (i = 0; i < NtCurrentPeb ()->NumberOfHeaps; i++)
        {
@@ -1345,12 +1763,11 @@ RtlEnumProcessHeaps (
                        break;
        }
 
-       RtlLeaveCriticalSection (&ProcessHeapsLock);
+       RtlLeaveCriticalSection (&RtlpProcessHeapsListLock);
 
        return Status;
 }
 
-
 ULONG
 STDCALL
 RtlGetProcessHeaps (
@@ -1360,7 +1777,7 @@ RtlGetProcessHeaps (
 {
        ULONG Result = 0;
 
-       RtlEnterCriticalSection (&ProcessHeapsLock);
+       RtlEnterCriticalSection (&RtlpProcessHeapsListLock);
 
        if (NtCurrentPeb ()->NumberOfHeaps <= HeapCount)
        {
@@ -1370,7 +1787,7 @@ RtlGetProcessHeaps (
                         Result * sizeof(HANDLE));
        }
 
-       RtlLeaveCriticalSection (&ProcessHeapsLock);
+       RtlLeaveCriticalSection (&RtlpProcessHeapsListLock);
 
        return Result;
 }
@@ -1396,5 +1813,3 @@ RtlValidateProcessHeaps (
 
        return Result;
 }
-
-/* EOF */
diff --git a/reactos/lib/secur32/Makefile b/reactos/lib/secur32/Makefile
new file mode 100644 (file)
index 0000000..47d0cc3
--- /dev/null
@@ -0,0 +1,85 @@
+# $Id: Makefile,v 1.1 2000/08/12 19:33:19 dwelch Exp $
+#
+# ReactOS Operating System
+#
+TARGET = secur32
+
+SECUR32_BASE = 0x10000000
+
+BASE_CFLAGS = -I../../include
+
+CFLAGS = $(CFLAGS)
+
+include ../../rules.mak
+ifneq ($(HOST),mingw32-windows)
+  ifneq ($(HOST),mingw32-linux)
+    DLLTARGET=$(TARGET).a
+  else
+    DLLTARGET=$(TARGET).dll
+  endif
+else
+  DLLTARGET=$(TARGET).dll
+endif
+
+all: $(DLLTARGET)
+
+OBJECTS = lsa.o dllmain.o
+
+ifeq ($(DOSCLI),yes)
+CLEAN_FILES = $(OBJECTS) \
+              $(TARGET).o $(TARGET).a junk.tmp base.tmp temp.exp \
+             $(TARGET).dll $(TARGET).sym $(TARGET).coff
+else
+CLEAN_FILES = $(OBJECTS) \
+             $(TARGET).o $(TARGET).a junk.tmp base.tmp temp.exp \
+             $(TARGET).dll $(TARGET).sym $(TARGET).coff
+endif
+
+$(TARGET).coff: $(TARGET).rc ../../include/reactos/resource.h
+
+$(TARGET).a: $(OBJECTS)
+       $(AR) csr $(TARGET).a $(OBJECTS)
+
+$(TARGET).dll: $(DLLMAIN) $(OBJECTS) $(TARGET).def
+       $(LD) \
+               -r $(OBJECTS) \
+               -o $(TARGET).o
+       $(DLLTOOL) \
+               --dllname $(TARGET).dll \
+               --def $(TARGET).def \
+               --kill-at \
+               --output-lib $(TARGET).a
+       $(CC) \
+               -mdll \
+               -o junk.tmp \
+               -Wl,--base-file,base.tmp \
+               $(TARGET).o \
+               ../ntdll/ntdll.a
+       - $(RM) junk.tmp
+       $(DLLTOOL) \
+               --dllname $(TARGET).dll \
+               --base-file base.tmp \
+               --output-exp temp.exp \
+               --def $(TARGET).edf
+       - $(RM) base.tmp
+       $(CC) \
+               -mdll \
+               -o $(TARGET).dll \
+               $(TARGET).o \
+               ../ntdll/ntdll.a \
+               -Wl,--image-base,$(SECUR32_BASE) \
+               -Wl,--file-alignment,0x1000 \
+               -Wl,--section-alignment,0x1000 \
+               -Wl,temp.exp
+       - $(RM) temp.exp
+       $(NM) --numeric-sort $(TARGET).dll > $(TARGET).sym
+
+clean: $(CLEAN_FILES:%=%_clean)
+
+$(CLEAN_FILES:%=%_clean): %_clean:
+       - $(RM) $*
+
+.PHONY: clean $(CLEAN_FILES:%=%_clean)
+
+WARNINGS_ARE_ERRORS = yes
+
diff --git a/reactos/lib/secur32/dllmain.c b/reactos/lib/secur32/dllmain.c
new file mode 100644 (file)
index 0000000..30c21e5
--- /dev/null
@@ -0,0 +1,42 @@
+/* $Id: dllmain.c,v 1.1 2000/08/12 19:33:19 dwelch Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS system libraries
+ * FILE:            lib/secur32/lsa.c
+ * PURPOSE:         Client-side LSA functions
+ * UPDATE HISTORY:
+ *                  Created 05/08/00
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <windows.h>
+#include <ntos.h>
+
+/* GLOBALS *******************************************************************/
+
+HANDLE Secur32Heap;
+
+/* FUNCTIONS *****************************************************************/
+
+WINBOOL STDCALL DllMain(HINSTANCE hInstance, ULONG Reason, PVOID Reserved)
+{
+   switch (Reason)
+     {
+      case DLL_PROCESS_ATTACH:
+       Secur32Heap = RtlCreateHeap(0, NULL, 4096, 0, NULL, NULL);
+       if (Secur32Heap == 0)
+         {
+            return(FALSE);
+         }
+       break;
+       
+      case DLL_PROCESS_DETACH:
+       if (!RtlDestroyHeap(Secur32Heap))
+         {
+            return(FALSE);
+         }
+       break;
+     }
+   return(TRUE);
+}
diff --git a/reactos/lib/secur32/lsa.c b/reactos/lib/secur32/lsa.c
new file mode 100644 (file)
index 0000000..2a3cd5f
--- /dev/null
@@ -0,0 +1,309 @@
+/* $Id: lsa.c,v 1.1 2000/08/12 19:33:19 dwelch Exp $
+ *
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS system libraries
+ * FILE:            lib/secur32/lsa.c
+ * PURPOSE:         Client-side LSA functions
+ * UPDATE HISTORY:
+ *                  Created 05/08/00
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <windows.h>
+#include <ddk/ntddk.h>
+#include <napi/lpc.h>
+#include <lsass/lsass.h>
+
+/* GLOBALS *******************************************************************/
+
+extern HANDLE Secur32Heap;
+
+/* FUNCTIONS *****************************************************************/
+
+NTSTATUS STDCALL
+LsaDeregisterLogonProcess(HANDLE LsaHandle)
+{
+   LSASS_REQUEST Request;
+   LSASS_REPLY Reply;
+   NTSTATUS Status;
+      
+   Request.Header.DataSize = 0;
+   Request.Header.MessageSize = sizeof(LSASS_REQUEST);
+   Request.Type = LSASS_REQUEST_DEREGISTER_LOGON_PROCESS;
+   Status = NtRequestWaitReplyPort(LsaHandle,
+                                  &Request.Header,
+                                  &Reply.Header);
+   if (!NT_SUCCESS(Status))
+     {
+       return(Status);
+     }
+   
+   if (!NT_SUCCESS(Reply.Status))
+     {
+       return(Reply.Status);
+     }
+   
+   return(Status);
+}
+
+NTSTATUS STDCALL
+LsaConnectUntrusted(PHANDLE LsaHandle)
+{
+  return(STATUS_UNSUCCESSFUL);
+}
+
+NTSTATUS STDCALL
+LsaCallAuthenticationPackage(HANDLE LsaHandle,
+                            ULONG AuthenticationPackage,
+                            PVOID ProtocolSubmitBuffer,
+                            ULONG SubmitBufferLength,
+                            PVOID* ProtocolReturnBuffer,
+                            PULONG ReturnBufferLength,
+                            PNTSTATUS ProtocolStatus)
+{
+   PLSASS_REQUEST Request;
+   PLSASS_REPLY Reply;
+   UCHAR RawRequest[MAX_MESSAGE_DATA];
+   UCHAR RawReply[MAX_MESSAGE_DATA];
+   NTSTATUS Status;
+   ULONG OutBufferSize;
+
+   Request = (PLSASS_REQUEST)RawRequest;
+   Reply = (PLSASS_REPLY)RawReply;
+   
+   Request->Header.DataSize = sizeof(LSASS_REQUEST) + SubmitBufferLength -
+     sizeof(LPC_MESSAGE_HEADER);
+   Request->Header.MessageSize = 
+     Request->Header.DataSize + sizeof(LPC_MESSAGE_HEADER);
+   Request->Type = LSASS_REQUEST_CALL_AUTHENTICATION_PACKAGE;
+   Request->d.CallAuthenticationPackageRequest.AuthenticationPackage =
+     AuthenticationPackage;
+   Request->d.CallAuthenticationPackageRequest.InBufferLength =
+     SubmitBufferLength;
+   memcpy(Request->d.CallAuthenticationPackageRequest.InBuffer,
+         ProtocolSubmitBuffer,
+         SubmitBufferLength);
+   
+   Status = NtRequestWaitReplyPort(LsaHandle,
+                                  &Request->Header,
+                                  &Reply->Header);
+   if (!NT_SUCCESS(Status))
+     {
+       return(Status);
+     }
+   
+   if (!NT_SUCCESS(Reply->Status))
+     {
+       return(Reply->Status);
+     }
+   
+   OutBufferSize = Reply->d.CallAuthenticationPackageReply.OutBufferLength;
+   *ProtocolReturnBuffer = RtlAllocateHeap(Secur32Heap,
+                                          0,
+                                          OutBufferSize);
+   *ReturnBufferLength = OutBufferSize;
+   memcpy(*ProtocolReturnBuffer,
+         Reply->d.CallAuthenticationPackageReply.OutBuffer,
+         *ReturnBufferLength);
+   
+   return(Status);
+}
+
+NTSTATUS STDCALL
+LsaFreeReturnBuffer(PVOID Buffer)
+{
+   return(RtlFreeHeap(Secur32Heap, 0, Buffer));
+}
+
+NTSTATUS STDCALL
+LsaLookupAuthenticationPackage(HANDLE LsaHandle,
+                              PLSA_STRING PackageName,
+                              PULONG AuthenticationPackage)
+{
+   NTSTATUS Status;
+   PLSASS_REQUEST Request;
+   UCHAR RawRequest[MAX_MESSAGE_DATA];
+   LSASS_REPLY Reply;
+   
+   Request = (PLSASS_REQUEST)RawRequest;
+   Request->Header.DataSize = sizeof(LSASS_REQUEST) + PackageName->Length -
+     sizeof(LPC_MESSAGE_HEADER);
+   Request->Header.MessageSize = Request->Header.DataSize +
+     sizeof(LPC_MESSAGE_HEADER);
+   Request->Type = LSASS_REQUEST_LOOKUP_AUTHENTICATION_PACKAGE;
+   
+   Status = NtRequestWaitReplyPort(LsaHandle,
+                         &Request->Header,
+                         &Reply.Header);
+   if (!NT_SUCCESS(Status))
+     {
+       return(Status);
+     }
+   if (!NT_SUCCESS(Reply.Status))
+     {
+       return(Reply.Status);
+     }
+   
+   *AuthenticationPackage = Reply.d.LookupAuthenticationPackageReply.Package;
+   
+   return(Reply.Status);
+}
+
+NTSTATUS STDCALL
+LsaLogonUser(HANDLE LsaHandle,
+            PLSA_STRING OriginName,
+            SECURITY_LOGON_TYPE LogonType,
+            ULONG AuthenticationPackage,
+            PVOID AuthenticationInformation,
+            ULONG AuthenticationInformationLength,
+            PTOKEN_GROUPS LocalGroups,
+            PTOKEN_SOURCE SourceContext,
+            PVOID* ProfileBuffer,
+            PULONG ProfileBufferLength,
+            PLUID LogonId,
+            PHANDLE Token,
+            PQUOTA_LIMITS Quotas,
+            PNTSTATUS SubStatus)
+{
+   ULONG RequestLength;
+   ULONG CurrentLength;
+   PLSASS_REQUEST Request;
+   UCHAR RawMessage[MAX_MESSAGE_DATA];
+   PLSASS_REPLY Reply;
+   UCHAR RawReply[MAX_MESSAGE_DATA];
+   NTSTATUS Status;
+   
+   RequestLength = sizeof(LSASS_REQUEST) - sizeof(LPC_MESSAGE_HEADER);
+   RequestLength = RequestLength + (OriginName->Length * sizeof(WCHAR));
+   RequestLength = RequestLength + AuthenticationInformationLength;
+   RequestLength = RequestLength + 
+     (LocalGroups->GroupCount * sizeof(SID_AND_ATTRIBUTES));
+   
+   CurrentLength = 0;
+   Request = (PLSASS_REQUEST)RawMessage;
+   
+   Request->d.LogonUserRequest.OriginNameLength = OriginName->Length;
+   Request->d.LogonUserRequest.OriginName = (PWSTR)&RawMessage[CurrentLength];
+   memcpy((PWSTR)&RawMessage[CurrentLength],
+         OriginName->Buffer,
+         OriginName->Length * sizeof(WCHAR));
+   CurrentLength = CurrentLength + (OriginName->Length * sizeof(WCHAR));
+   
+   Request->d.LogonUserRequest.LogonType = LogonType;
+   
+   Request->d.LogonUserRequest.AuthenticationPackage =
+     AuthenticationPackage;
+   
+   Request->d.LogonUserRequest.AuthenticationInformation = 
+     (PVOID)&RawMessage[CurrentLength];
+   Request->d.LogonUserRequest.AuthenticationInformationLength =
+     AuthenticationInformationLength;
+   memcpy((PVOID)&RawMessage[CurrentLength],
+         AuthenticationInformation,
+         AuthenticationInformationLength);
+   CurrentLength = CurrentLength + AuthenticationInformationLength;
+   
+   Request->d.LogonUserRequest.LocalGroupsCount = LocalGroups->GroupCount;
+   Request->d.LogonUserRequest.LocalGroups = 
+     (PSID_AND_ATTRIBUTES)&RawMessage[CurrentLength];
+   memcpy((PSID_AND_ATTRIBUTES)&RawMessage[CurrentLength],
+         LocalGroups->Groups,
+         LocalGroups->GroupCount * sizeof(SID_AND_ATTRIBUTES));
+   
+   Request->d.LogonUserRequest.SourceContext = *SourceContext;
+   
+   Request->Type = LSASS_REQUEST_LOGON_USER;
+   Request->Header.DataSize = RequestLength - sizeof(LPC_MESSAGE_HEADER);
+   Request->Header.MessageSize = RequestLength + sizeof(LPC_MESSAGE_HEADER);
+   
+   Reply = (PLSASS_REPLY)RawReply;
+   
+   Status = NtRequestWaitReplyPort(LsaHandle,
+                                  &Request->Header,
+                                  &Reply->Header);
+   if (!NT_SUCCESS(Status))
+     {
+       return(Status);
+     }
+
+   *SubStatus = Reply->d.LogonUserReply.SubStatus;
+   
+   if (!NT_SUCCESS(Reply->Status))
+     {
+       return(Status);
+     }
+   
+   *ProfileBuffer = RtlAllocateHeap(Secur32Heap,
+                                   0,
+                                 Reply->d.LogonUserReply.ProfileBufferLength);
+   memcpy(*ProfileBuffer,
+         (PVOID)((ULONG)Reply->d.LogonUserReply.Data +
+                 (ULONG)Reply->d.LogonUserReply.ProfileBuffer),
+         Reply->d.LogonUserReply.ProfileBufferLength);
+   *LogonId = Reply->d.LogonUserReply.LogonId;
+   *Token = Reply->d.LogonUserReply.Token;
+   memcpy(Quotas, 
+         &Reply->d.LogonUserReply.Quotas,
+         sizeof(Reply->d.LogonUserReply.Quotas));
+   
+   return(Status);
+}
+
+NTSTATUS STDCALL
+LsaRegisterLogonProcess(PLSA_STRING LsaLogonProcessName,
+                       PHANDLE Handle,
+                       PLSA_OPERATIONAL_MODE OperationalMode)
+{
+   UNICODE_STRING Portname;
+   ULONG ConnectInfoLength;
+   NTSTATUS Status;
+   LSASS_REQUEST Request;
+   LSASS_REPLY Reply;
+   
+   RtlInitUnicodeString(&Portname, L"\\SeLsaCommandPort");
+   ConnectInfoLength = 0;
+   Status = NtConnectPort(Handle,
+                         &Portname,
+                         NULL,
+                         NULL,
+                         NULL,
+                         NULL,
+                         NULL,
+                         &ConnectInfoLength);
+   if (!NT_SUCCESS(Status))
+     {
+       return(Status);
+     }
+   
+   Request.Type = LSASS_REQUEST_REGISTER_LOGON_PROCESS;
+   Request.Header.DataSize = sizeof(LSASS_REQUEST) - 
+     sizeof(LPC_MESSAGE_HEADER);
+   Request.Header.MessageSize = sizeof(LSASS_REQUEST);
+   
+   Request.d.RegisterLogonProcessRequest.Length = LsaLogonProcessName->Length;
+   wcscpy(Request.d.RegisterLogonProcessRequest.LogonProcessNameBuffer,
+         LsaLogonProcessName->Buffer);
+   
+   Status = NtRequestWaitReplyPort(*Handle,
+                                  &Request.Header,
+                                  &Reply.Header);
+   if (!NT_SUCCESS(Status))
+     {
+       NtClose(*Handle);
+       *Handle = INVALID_HANDLE_VALUE;
+       return(Status);
+     }
+   
+   if (!NT_SUCCESS(Reply.Status))
+     {
+       NtClose(*Handle);
+       *Handle = INVALID_HANDLE_VALUE;
+       return(Status);
+     }
+   
+   *OperationalMode = Reply.d.RegisterLogonProcessReply.OperationalMode;
+   
+   return(Reply.Status);
+}
+
diff --git a/reactos/lib/secur32/secur32.def b/reactos/lib/secur32/secur32.def
new file mode 100644 (file)
index 0000000..f0d8ac0
--- /dev/null
@@ -0,0 +1,9 @@
+LIBRARY SECUR32.DLL
+EXPORTS
+LsaRegisterLogonProcess@12
+LsaLogonUser@56
+LsaDeregisterLogonProcess@4
+LsaConnectUntrusted@4
+LsaLookupAuthenticationPackage@12
+LsaFreeReturnBuffer@4
+LsaCallAuthenticationPackage@28
diff --git a/reactos/lib/secur32/secur32.edf b/reactos/lib/secur32/secur32.edf
new file mode 100644 (file)
index 0000000..4595f48
--- /dev/null
@@ -0,0 +1,9 @@
+LIBRARY KERNEL32.DLL
+EXPORTS
+LsaRegisterLogonProcess=LsaRegisterLogonProcess@12
+LsaLogonUser=LsaLogonUser@56
+LsaDeregisterLogonProcess=LsaDeregisterLogonProcess@4
+LsaConnectUntrusted=LsaConnectUntrusted@4
+LsaLookupAuthenticationPackage=LsaLookupAuthenticationPackage@12
+LsaFreeReturnBuffer=LsaFreeReturnBuffer@4
+LsaCallAuthenticationPackage=LsaCallAuthenticationPackage@28
diff --git a/reactos/lib/secur32/secur32.rc b/reactos/lib/secur32/secur32.rc
new file mode 100644 (file)
index 0000000..78588bb
--- /dev/null
@@ -0,0 +1,38 @@
+#include <defines.h>
+#include <reactos/resource.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+       FILEVERSION     RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
+       PRODUCTVERSION  RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD      
+       FILEFLAGSMASK   0x3fL
+#ifdef _DEBUG
+       FILEFLAGS       0x1L
+#else
+       FILEFLAGS       0x0L
+#endif
+       FILEOS          0x40004L
+       FILETYPE        0x2L
+       FILESUBTYPE     0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName",       RES_STR_COMPANY_NAME
+            VALUE "FileDescription",   "W32 subsystem kernel\0"
+            VALUE "FileVersion",       RES_STR_FILE_VERSION
+            VALUE "InternalName",      "kernel32\0"
+            VALUE "LegalCopyright",    RES_STR_LEGAL_COPYRIGHT
+            VALUE "OriginalFilename",  "kernel32.dll\0"
+            VALUE "ProductName",       RES_STR_PRODUCT_NAME
+            VALUE "ProductVersion",    RES_STR_PRODUCT_VERSION
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
index 6771b99..f8130d0 100644 (file)
@@ -34,7 +34,7 @@ org 100h
 ;
 BITS 16
 
-%define NDEBUG 1
+;%define NDEBUG 1
 
 %macro DPRINT  1+
 %ifndef        NDEBUG
index c8c6679..50fb2f2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.4 2000/04/09 15:58:13 ekohl Exp $
+/* $Id: misc.c,v 1.5 2000/08/12 19:33:20 dwelch Exp $
  *
  * COPYRIGHT:             See COPYING in the top level directory
  * PROJECT:               ReactOS kernel
@@ -14,8 +14,7 @@
 
 /* FUNCTIONS ****************************************************************/
 
-VOID
-STDCALL
+VOID STDCALL
 HalHandleNMI (ULONG Unused)
 {
        UCHAR ucStatus;
@@ -35,16 +34,18 @@ HalHandleNMI (ULONG Unused)
        KeEnterKernelDebugger ();
 }
 
-VOID
-STDCALL
+VOID STDCALL
 HalProcessorIdle (VOID)
 {
+#if 1
        __asm__("sti\n\t" \
                "hlt\n\t");
+#else
+   
+#endif
 }
 
-ULONG
-FASTCALL
+ULONG FASTCALL
 HalSystemVectorDispatchEntry (
        ULONG   Unknown1,
        ULONG   Unknown2,
@@ -54,8 +55,7 @@ HalSystemVectorDispatchEntry (
        return 0;
 }
 
-VOID
-STDCALL
+VOID STDCALL
 KeFlushWriteBuffer (
        VOID
        )
@@ -63,8 +63,7 @@ KeFlushWriteBuffer (
        return;
 }
 
-VOID
-STDCALL
+VOID STDCALL
 HalReportResourceUsage (
        VOID
        )
@@ -94,4 +93,4 @@ HalReportResourceUsage (
        return;
 }
 
-/* EOF */
\ No newline at end of file
+/* EOF */
index 6833b89..77fda6d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: reboot.c,v 1.4 2000/03/19 13:34:47 ekohl Exp $
+/* $Id: reboot.c,v 1.5 2000/08/12 19:33:20 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -47,12 +47,15 @@ HalReboot (VOID)
     outb_p (0x64, 0xfe);
 
     /* stop the processor */
+#if 1
     __asm__("hlt\n");
+#else
+   for(;;);
+#endif   
 }
 
 
-VOID
-STDCALL
+VOID STDCALL
 HalReturnToFirmware (
        ULONG   Action
        )
index 89af092..eca5db2 100644 (file)
@@ -26,6 +26,7 @@ enum
    MEMORY_AREA_RESERVE,
    MEMORY_AREA_SECTION_VIEW_RESERVE,
    MEMORY_AREA_CACHE_SEGMENT,
+   MEMORY_AREA_SHARED_DATA,
 };
 
 #define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
index baf9145..48fcaf6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: kdebug.c,v 1.12 2000/07/01 18:25:00 ekohl Exp $
+/* $Id: kdebug.c,v 1.13 2000/08/12 19:33:21 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -311,16 +311,17 @@ KdPollBreakIn (
        return Result;
 }
 
-VOID
-STDCALL
-KeEnterKernelDebugger (
-       VOID
-       )
+VOID STDCALL
+KeEnterKernelDebugger (VOID)
 {
        HalDisplayString ("\n\n *** Entered kernel debugger ***\n");
 
+#if 1
        for (;;)
                __asm__("hlt\n\t");
+#else
+   for(;;);
+#endif
 }
 
 /* EOF */
index 963af14..12c793d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: bug.c,v 1.13 2000/07/02 10:49:30 ekohl Exp $
+/* $Id: bug.c,v 1.14 2000/08/12 19:33:21 dwelch Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -32,8 +32,7 @@ VOID KeInitializeBugCheck(VOID)
    InBugCheck = 0;
 }
 
-BOOLEAN
-STDCALL
+BOOLEAN STDCALL
 KeDeregisterBugCheckCallback (
        PKBUGCHECK_CALLBACK_RECORD      CallbackRecord
        )
@@ -41,8 +40,7 @@ KeDeregisterBugCheckCallback (
    UNIMPLEMENTED;
 }
 
-BOOLEAN
-STDCALL
+BOOLEAN STDCALL
 KeRegisterBugCheckCallback (
        PKBUGCHECK_CALLBACK_RECORD      CallbackRecord,
        PKBUGCHECK_CALLBACK_ROUTINE     CallbackRoutine,
@@ -59,8 +57,7 @@ KeRegisterBugCheckCallback (
    return(TRUE);
 }
 
-VOID
-STDCALL
+VOID STDCALL
 KeBugCheckEx (
        ULONG   BugCheckCode,
        ULONG   BugCheckParameter1,
@@ -81,18 +78,19 @@ KeBugCheckEx (
    DbgPrint("Bug detected (code %x param %x %x %x %x)\n",BugCheckCode,
          BugCheckParameter1,BugCheckParameter2,BugCheckParameter3,
          BugCheckParameter4);
-   PsDumpThreads();
+//   PsDumpThreads();
    KeDumpStackFrames(&((&BugCheckCode)[-1]),64);
    
+#if 1
    for(;;)
           __asm__("hlt\n\t");  //PJS: use HLT instruction, rather than busy wait
+#else
+   for(;;);
+#endif   
 }
 
-VOID
-STDCALL
-KeBugCheck (
-       ULONG   BugCheckCode
-       )
+VOID STDCALL
+KeBugCheck (ULONG      BugCheckCode)
 /*
  * FUNCTION: Brings the system down in a controlled manner when an 
  * inconsistency that might otherwise cause corruption has been detected
@@ -109,12 +107,16 @@ KeBugCheck (
        for(;;);
      }
    InBugCheck = 1;
-   PsDumpThreads();
+//   PsDumpThreads();
    KeDumpStackFrames(&((&BugCheckCode)[-1]), 80);
+#if 1
    for(;;)
      {
        __asm__("hlt\n\t");
      }
+#else
+   for(;;);
+#endif
 }
 
 /* EOF */
index b124b91..719edf0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: loader.c,v 1.59 2000/07/19 14:18:18 dwelch Exp $
+/* $Id: loader.c,v 1.60 2000/08/12 19:33:21 dwelch Exp $
  * 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -182,7 +182,7 @@ static VOID LdrLoadAutoConfigDriver (LPWSTR RelativeDriverName)
    if (!NT_SUCCESS(Status))
      {
        DbgPrint("driver load failed, status (%x)\n", Status);
-       KeBugCheck(0);
+//     KeBugCheck(0);
      }
 }
 
@@ -200,9 +200,14 @@ VOID LdrLoadAutoConfigDrivers (VOID)
    LdrLoadAutoConfigDriver( L"blue.sys" );
    
    /*
-    * Floppy disk driver
+    * 
     */
-//   LdrLoadAutoConfigDriver(L"floppy.sys");
+   LdrLoadAutoConfigDriver(L"vidport.sys");
+   
+   /*
+    * 
+    */
+   LdrLoadAutoConfigDriver(L"vgamp.sys");
    
    /*
     * Minix filesystem driver
@@ -714,6 +719,7 @@ LdrPEProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING pModuleName)
               else
                 {
                    DbgPrint("Unresolved kernel symbol: %s\n", pName);
+                  return(NULL);
                 }
               ImportAddressList++;
               FunctionNameList++;
index 3ccaf9f..2a1a9ca 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mm.c,v 1.34 2000/07/07 10:30:56 dwelch Exp $
+/* $Id: mm.c,v 1.35 2000/08/12 19:33:22 dwelch Exp $
  *
  * COPYRIGHT:   See COPYING in the top directory
  * PROJECT:     ReactOS kernel 
@@ -33,6 +33,7 @@
 PVOID EXPORTED MmUserProbeAddress = NULL; 
 PVOID EXPORTED MmHighestUserAddress = NULL;
 MM_STATS MmStats; 
+extern PVOID MmSharedDataPagePhysicalAddress;
 
 /* FUNCTIONS ****************************************************************/
 
@@ -196,6 +197,14 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode,
                                                (PVOID)Address);
        break;
        
+      case MEMORY_AREA_SHARED_DATA:
+       MmSetPage(PsGetCurrentProcess(),
+                 (PVOID)PAGE_ROUND_DOWN(Address),
+                 PAGE_READONLY,
+                 (ULONG)MmSharedDataPagePhysicalAddress);
+       Status = STATUS_SUCCESS;
+       break;
+       
       default:
        Status = STATUS_UNSUCCESSFUL;
        break;
index a636544..872d74a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mminit.c,v 1.4 2000/07/19 14:18:19 dwelch Exp $
+/* $Id: mminit.c,v 1.5 2000/08/12 19:33:22 dwelch Exp $
  *
  * COPYRIGHT:   See COPYING in the top directory
  * PROJECT:     ReactOS kernel 
@@ -24,6 +24,7 @@
 #include <internal/io.h>
 #include <internal/ps.h>
 #include <internal/mmhal.h>
+#include <napi/shared_data.h>
 
 #define NDEBUG
 #include <internal/debug.h>
@@ -52,6 +53,9 @@ static MEMORY_AREA* kernel_text_desc = NULL;
 static MEMORY_AREA* kernel_data_desc = NULL;
 static MEMORY_AREA* kernel_param_desc = NULL;
 static MEMORY_AREA* kernel_pool_desc = NULL;
+static MEMORY_AREA* kernel_shared_data_desc = NULL;
+
+PVOID MmSharedDataPagePhysicalAddress = NULL;
 
 /* FUNCTIONS ****************************************************************/
 
@@ -139,7 +143,25 @@ VOID MmInitVirtualMemory(PLOADER_PARAMETER_BLOCK bp, ULONG LastKernelAddress)
                      Length,
                      0,
                      &kernel_pool_desc);
-
+   
+   DPRINT1("Creating shared data page\n");
+   BaseAddress = (PVOID)KERNEL_SHARED_DATA_BASE;
+   Length = PAGESIZE;
+   MmCreateMemoryArea(NULL,
+                     MmGetKernelAddressSpace(),
+                     MEMORY_AREA_SYSTEM,
+                     &BaseAddress,
+                     Length,
+                     0,
+                     &kernel_shared_data_desc);
+   MmSharedDataPagePhysicalAddress = MmAllocPage(0);
+   MmSetPage(NULL,
+            (PVOID)KERNEL_SHARED_DATA_BASE,
+            PAGE_READWRITE,
+            (ULONG)MmSharedDataPagePhysicalAddress);
+   ((PKUSER_SHARED_DATA)KERNEL_SHARED_DATA_BASE)->TickCountLow = 0xdeadbeef;
+   DPRINT1("Finished creating shared data page\n");
+   
 //   MmDumpMemoryAreas();
    DPRINT("MmInitVirtualMemory() done\n");
 }
index 7eaa935..2b00b9b 100644 (file)
@@ -188,10 +188,10 @@ NTSTATUS STDCALL NtTerminateProcess(IN    HANDLE          ProcessHandle,
    }
    
    PiTerminateProcessThreads(Process, ExitStatus);
-   if( PsGetCurrentThread()->ThreadsProcess == Process )
+   if (PsGetCurrentThread()->ThreadsProcess == Process)
      {
-       ObDereferenceObject( Process );
-       PsTerminateCurrentThread( ExitStatus );
+       ObDereferenceObject(Process);
+       PsTerminateCurrentThread(ExitStatus);
      }
    ObDereferenceObject(Process);
    return(STATUS_SUCCESS);
index 0f98864..9d07216 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.51 2000/07/07 00:49:02 phreak Exp $
+/* $Id: process.c,v 1.52 2000/08/12 19:33:22 dwelch Exp $
  *
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel
@@ -25,6 +25,7 @@
 #include <internal/port.h>
 #include <napi/dbg.h>
 #include <internal/dbg.h>
+#include <napi/shared_data.h>
 
 #define NDEBUG
 #include <internal/debug.h>
@@ -356,6 +357,8 @@ NTSTATUS STDCALL NtCreateProcess (OUT PHANDLE ProcessHandle,
    PVOID Peb;
    PEPORT DebugPort;
    PEPORT ExceptionPort;
+   PVOID BaseAddress;
+   PMEMORY_AREA MemoryArea;
    
    DPRINT("NtCreateProcess(ObjectAttributes %x)\n",ObjectAttributes);
 
@@ -446,7 +449,26 @@ NTSTATUS STDCALL NtCreateProcess (OUT PHANDLE ProcessHandle,
    /*
     * Now we have created the process proper
     */
-      
+   
+   /*
+    * Create the shared data page
+    */
+   MmLockAddressSpace(&Process->AddressSpace);
+   BaseAddress = (PVOID)USER_SHARED_DATA_BASE;
+   Status = MmCreateMemoryArea(Process,
+                              &Process->AddressSpace,
+                              MEMORY_AREA_SHARED_DATA,
+                              &BaseAddress,
+                              PAGESIZE,
+                              PAGE_READONLY,
+                              &MemoryArea);
+   MmUnlockAddressSpace(&Process->AddressSpace);
+   if (!NT_SUCCESS(Status))
+     {
+       DPRINT1("Failed to create shared data page\n");
+       KeBugCheck(0);
+     }
+   
    /*
     * Map ntdll
     */
index 5591f03..4b0fefd 100644 (file)
@@ -1,16 +1,16 @@
-# $Id: makefile,v 1.2 1999/08/29 13:45:06 dwelch Exp $
+# $Id: makefile,v 1.3 2000/08/12 19:33:23 dwelch Exp $
 #
 # Logon/login Application
 #
 # ReactOS Operating System
 #
-TARGET=winlogon
+TARGET = winlogon
 
 BASE_CFLAGS = -I../../include
 
-OBJECTS = $(TARGET).o init.o $(TARGET).coff
+OBJECTS = winlogon.o $(TARGET).coff
 
-LIBS = ../../lib/ntdll/ntdll.a
+LIBS = -lkernel32 ../../lib/ntdll/ntdll.a
 
 all: $(TARGET).exe
 
@@ -27,12 +27,11 @@ clean:
 $(TARGET).coff: $(TARGET).rc
        $(RC) $(TARGET).rc $(TARGET).coff
 
-$(TARGET).exe: $(OBJECTS) $(LIBS)
-       $(LD) \
+$(TARGET).exe: $(OBJECTS)
+       $(CC) \
                $(OBJECTS) \
                $(LIBS) \
-               -o $(TARGET).exe \
-               --subsystem native
+               -o $(TARGET).exe 
        $(NM) --numeric-sort $(TARGET).exe > $(TARGET).sym
 
 include ../../rules.mak
index dc61757..c69d41a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: winlogon.c,v 1.5 1999/11/20 21:53:53 ekohl Exp $
+/* $Id: winlogon.c,v 1.6 2000/08/12 19:33:23 dwelch Exp $
  * 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
 
 /* INCLUDES *****************************************************************/
 
-#include <ddk/ntddk.h>
-//#include <stdio.h>
+#include <ntos.h>
+#include <windows.h>
+#include <stdio.h>
+#include <lsass/ntsecapi.h>
 
 #include <wchar.h>
 
 
 /* GLOBALS ******************************************************************/
 
-HANDLE SM              = INVALID_HANDLE_VALUE; /* SM API LPC port */
-HANDLE SasEvent        = INVALID_HANDLE_VALUE; /* int 0x19 */
-
-
 /* FUNCTIONS *****************************************************************/
 
-
-/***********************************************************************
- *     SmTerminationRequestHandler
- */
-VOID
-STDCALL
-SmTerminationRequestHandler (VOID)
+BOOLEAN StartServices(VOID)
 {
-       /* Should winlogon perform any action
-        * before committing suicide?
-        */
-       NtTerminateProcess(
-               NtCurrentProcess(),
-               0
-               );
+   HANDLE ServicesInitEvent;
+   BOOLEAN Result;
+   STARTUPINFO StartupInfo;
+   PROCESS_INFORMATION ProcessInformation;
+   
+   ServicesInitEvent = CreateEvent(NULL,
+                               TRUE,
+                               FALSE,
+                               "\\ServicesInitDone");                          
+   
+   if (ServicesInitEvent == NULL)
+     {
+       DbgPrint("Failed to create services notification event\n");
+       return(FALSE);
+     }
+   
+   /* Start the Win32 subsystem (csrss.exe) */
+   DbgPrint("WL: Executing services.exe\n");
+   
+   StartupInfo.cb = sizeof(StartupInfo);
+   StartupInfo.lpReserved = NULL;
+   StartupInfo.lpDesktop = NULL;
+   StartupInfo.lpTitle = NULL;
+   StartupInfo.dwFlags = 0;
+   StartupInfo.cbReserved2 = 0;
+   StartupInfo.lpReserved2 = 0;
+   
+   Result = CreateProcess("C:\\reactos\\system32\\services.exe",
+                         NULL,
+                         NULL,
+                         NULL,
+                         FALSE,
+                         DETACHED_PROCESS,
+                         NULL,
+                         NULL,
+                         &StartupInfo,
+                         &ProcessInformation);
+   if (!Result)
+     {
+       DbgPrint("WL: Failed to execute services\n");
+       return(FALSE);
+     }
+   
+   DbgPrint("WL: Waiting for services\n");
+   WaitForSingleObject(ServicesInitEvent, INFINITE);
+   
+   DbgPrint("WL: Finished waiting for services\n");
+   return(TRUE);
 }
 
-
-/***********************************************************************
- *     HasSystemGui
- *     
- * DESCRIPTION
- *     Call the Session Manager to know if user I/O is via a GUI or
- *     via a CUI.
- *
- * RETURN VALUE
- *     TRUE    GUI active
- *     FALSE   CUI only
- */
-BOOL
-HasSystemGui (VOID)
+BOOLEAN StartLsass(VOID)
 {
-       /* FIXME: call smss.exe to know, since it
-        * controls environment subsystem servers
-        * waking up. ReactOS has only text mode
-        * now, therefore we can answer (EA.19990608).
-        */
-       return FALSE; /* NO GUI */
+   HANDLE LsassInitEvent;
+   BOOLEAN Result;
+   STARTUPINFO StartupInfo;
+   PROCESS_INFORMATION ProcessInformation;
+   
+   LsassInitEvent = CreateEvent(NULL,
+                               TRUE,
+                               FALSE,
+                               "\\LsassInitDone");                             
+   
+   if (LsassInitEvent == NULL)
+     {
+       DbgPrint("Failed to create lsass notification event\n");
+       return(FALSE);
+     }
+   
+   /* Start the Win32 subsystem (csrss.exe) */
+   DbgPrint("WL: Executing lsass.exe\n");
+   
+   StartupInfo.cb = sizeof(StartupInfo);
+   StartupInfo.lpReserved = NULL;
+   StartupInfo.lpDesktop = NULL;
+   StartupInfo.lpTitle = NULL;
+   StartupInfo.dwFlags = 0;
+   StartupInfo.cbReserved2 = 0;
+   StartupInfo.lpReserved2 = 0;
+   
+   Result = CreateProcess("C:\\reactos\\system32\\lsass.exe",
+                         NULL,
+                         NULL,
+                         NULL,
+                         FALSE,
+                         DETACHED_PROCESS,
+                         NULL,
+                         NULL,
+                         &StartupInfo,
+                         &ProcessInformation);
+   if (!Result)
+     {
+       DbgPrint("WL: Failed to execute lsass\n");
+       return(FALSE);
+     }
+   
+   DbgPrint("WL: Waiting for lsass\n");
+   WaitForSingleObject(LsassInitEvent, INFINITE);
+   
+   DbgPrint("WL: Finished waiting for lsass\n");
+   return(TRUE);
 }
 
-
-/***********************************************************************
- *     HasSystemActiveSession
- *     
- * DESCRIPTION
- *     Call the Session Manager to know if there is already an active
- *     session.
- *
- * RETURN VALUE
- *     TRUE    a session is active
- *     FALSE   no sessions
- */
-BOOL
-HasSystemActiveSession (VOID)
+VOID DoLoginUser(PCHAR Name, PCHAR Password)
 {
-       /* FIXME: call smss.exe to know */
-       return FALSE; /* NO SESSIONS */
+   PROCESS_INFORMATION ProcessInformation;
+   STARTUPINFO StartupInfo;
+   BOOLEAN Result;
+   
+   StartupInfo.cb = sizeof(StartupInfo);
+   StartupInfo.lpReserved = NULL;
+   StartupInfo.lpDesktop = NULL;
+   StartupInfo.lpTitle = NULL;
+   StartupInfo.dwFlags = 0;
+   StartupInfo.cbReserved2 = 0;
+   StartupInfo.lpReserved2 = 0;
+   
+   Result = CreateProcess("C:\\reactos\\system32\\shell.exe",
+                         NULL,
+                         NULL,
+                         NULL,
+                         FALSE,
+                         DETACHED_PROCESS,
+                         NULL,
+                         NULL,
+                         &StartupInfo,
+                         &ProcessInformation);
+   if (!Result)
+     {
+       DbgPrint("WL: Failed to execute user shell\n");
+       return;
+     }
+   WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
 }
 
-
-/***********************************************************************
- *     GuiLogin
- *     
- * DESCRIPTION
- *     Graphical login procedure
- *
- * NOTE
- *     Read values from
- *     
- *     HKEY_LOCAL-MACHINE
- *             SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon
- *
- */
-VOID
-GuiLogin (VOID)
+int STDCALL
+WinMain(HINSTANCE hInstance, 
+       HINSTANCE hPrevInstance,
+       LPSTR lpCmdLine, 
+       int nShowCmd)
 {
-       /* FIXME: Open logon dialog */
-}
-
-
-/***********************************************************************
- *     GuiMonitor
- *     
- * DESCRIPTION
- *     Graphical monitor procedure
- */
-VOID
-GuiMonitor (VOID)
-{
-       /* FIXME: Open Monitor dialog */
-}
-
-
-/***********************************************************************
- *     CuiLogin
- *     
- * DESCRIPTION
- *     Text mode (console) login procedure
- *
- * NOTE
- *     Read values from
- *     
- *     HKEY_LOCAL-MACHINE
- *             SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon
- *
- */
-VOID
-CuiLogin (VOID)
-{
-       char username[255];
-       char password[255];
-
-       /* FIXME: to be used ntdll.dll only? */
-       printf("Winlogon\n");
-       printf("login: ");
-       fgets(username, 255, stdin);
-       printf("Password: ");
-       fgets(password, 255, stdin);
-       /*
-        * 
-        */
-       NtCreateProcess(
-               L"\\\\??\\C:\\reactos\\system\\userinit.exe",
-               );
-       /*
-        *      Security issue: buffers are cleared.
-        */
-       NtZeroMemory(username, sizeof username);
-       NtZeroMemory(password, sizeof password);
+#if 0
+   LSA_STRING ProcessName;
+   NTSTATUS Status;
+   HANDLE LsaHandle;
+   LSA_OPERATIONAL_MODE Mode;
+#endif
+   CHAR LoginPrompt[] = "login:";
+   CHAR PasswordPrompt[] = "password:";
+   ULONG Result;
+   CHAR LoginName[255];
+   CHAR Password[255];
+   ULONG i;
+   
+   /* 
+    * FIXME: Create WindowStations here. At the moment lsass and services
+    * share ours
+    */
+   
+   StartLsass();
+   StartServices();
+   
+   /* FIXME: What name does the real WinLogon use? */
+#if 0
+   RtlInitUnicodeString((PUNICODE_STRING)&ProcessName, L"WinLogon");
+   Status = LsaRegisterLogonProcess(&ProcessName, &LsaHandle, &Mode);
+   if (!NT_SUCCESS(Status))
+     {
+       DbgPrint("WL: Failed to connect to lsass\n");
+       return(1);
+     }
+#endif
+   
+   /* smss wouldn't have created a console for us */
+   AllocConsole();
+   
+   /* Main loop */
+   for (;;)
+     {
+       /* Display login prompt */
+       WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
+                    LoginPrompt,
+                    wcslen(LoginPrompt),
+                    &Result,
+                    NULL);
+       i = 0;
+       do
+         {
+            ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
+                        &LoginName[i],
+                        1,
+                        &Result,
+                        NULL);
+            i++;
+         } while (LoginName[i - 1] != '\n');
+       LoginName[i - 1] = 0;
+       
+       /* Display password prompt */
+       WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
+                    PasswordPrompt,
+                    wcslen(PasswordPrompt),
+                    &Result,
+                    NULL);
+       i = 0;
+       do
+         {
+            ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
+                        &Password[i],
+                        1,
+                        &Result,
+                        NULL);
+            i++;
+         } while (Password[i - 1] != '\n');
+       Password[i - 1] =0;
+       
+       DoLoginUser(LoginName, Password);
+     }
 }
-
-
-/***********************************************************************
- *     CuiMonitor
- *     
- * DESCRIPTION
- *     Text mode (console) Monitor procedure
- */
-VOID
-CuiMonitor (VOID)
-{
-       WCHAR   HostName [64];
-       WCHAR   UserName [64];
-       WCHAR   FormattedDate [64];
-       WCHAR   InputKey = L'\0';
-
-       /* FIXME: query the system to get these info */
-       wcscpy( HostName, L"BACH" );
-       wcscpy( UserName, L"Administrator" );
-
-       /* FIXME: use locale info to format */
-        NtGetSystemTime(
-               );
-
-       /* Print info and Monitor menu */
-       NtDisplayString(L"\
-ReactOS Security:\n\
-\tYou are logged on as %s/%s\n\
-\yLogon date: %s\n\n\
-Use the Task Manager to close an application that is not responding.\n\n\
-1) Lock Workstation\n\
-2) Change Password\n\
-3) Logoff...\n\
-4) Task Manager...\n\
-5) Shut Down...\n\
-6) Cancel\n\n? ",
-               HostName,
-               UserName,
-               FormattedDate
-               );
-       while (TRUE)
-       {
-               /* FIXME: get a char and perform the requested action */
-               switch (InputKey)
-               {
-               case L'1':
-                       DisplayString(L"Workstation locked...\n");
-                       return;
-               case L'2':
-                       DisplayString(L"Changing Password:\n");
-                       return;
-               case L'3':
-                       DisplayString(L"Logging off...\n");
-                       return;
-               case L'4':
-                       DisplayString(L"Task Manager:\n");
-                       return;
-               case L'5':
-                       DisplayString(L"Shutting Down:\n");
-                       DisplayString(L"1) Shutdown\n");
-                       DisplayString(L"2) Restart\n");
-                       DisplayString(L"3) Logoff\n");
-                       DisplayString(L"4) Cancel\n");
-                       return;
-               case 27L: /* ESC */
-               case L'6':
-                       return;
-               default:
-                       DisplayString(L"Invalid key (1-6).\n");
-               }
-       }
-}
-
-
-HANDLE
-ConnectToSmApiPort(VOID)
-{
-       HANDLE                  PortHandle;
-       NTSTATUS                Status = STATUS_SUCCESS;
-       UNICODE_STRING          SmApiPort;
-       LPWSTR                  PortName = L"\\SmApiPort";
-       OBJECT_ATTRIBUTES       PortAttributes = {0};
-
-       SmApiPort.Length    = wcslen(PortName) * sizeof (WCHAR);
-       SmApiPort.MaxLength = SmApiPort.Length + sizeof (WCHAR);
-       SmApiPort.Buffer    = PortName;
-       Status = NtConnectPort(
-                       & PortHandle,
-                       & SmApiPort,
-                       & PortAttributes, /* FIXME: ? */
-                       0, /* FIXME: ? */
-                       0, /* FIXME: ? */
-                       0, /* FIXME: ? */
-                       0, /* FIXME: ? */
-                       0x00010000 /* FIXME: ? */
-                       );
-       return (NT_SUCCESS(Status))
-               ? PortHandle
-               : INVALID_HANDLE_VALUE;
-}
-
-
-/* Native process entry point */
-void
-NtProcessStartup( PSTARTUP_ARGUMENT StartupArgument )
-{
-       NTSTATUS                Status = STATUS_SUCCESS;
-
-       /* FIXME: connnect to the Session Manager
-        * for LPC calls
-        */
-       SM = ConnectToSmApiPort();
-       if (INVALID_HANDLE_VALUE == SM)
-       {
-               NtTerminateProcess(
-                       NtCurrentProcess(),
-                       0 /* FIXME: return a proper value to SM */
-                       );
-       }
-       /* FIXME: register a termination callback
-        * for smss.exe
-        */
-       /* ??? register SmTerminationRequestHandler */
-       /* FIXME: hook Ctrl+Alt+Del (int 0x19)
-        * (SAS = Secure Attention Sequence)
-        */
-       /* ??? SasEvent = ? */
-       while (TRUE)
-       {
-               /*
-                * Make the main thread wait
-                * for SAS indefinitely.
-                */
-               NtWaitForSingleObject(
-                       SasEvent
-                       /* ... */
-                       );
-               /*
-                * If there is no local session, begin
-                * the logon procedure; otherwise open
-                * the monitor dialog.
-                */
-               if (TRUE == HasSystemActiveSession())
-               {
-                       /* MONITOR */
-                       if (TRUE == HasSystemGui())
-                       {
-                               /* GUI active: monitor in graphical mode */
-                               GuiMonitor();
-                               continue;
-                       }
-                       /* No GUI: monitor in text mode */
-                       CuiMonitor();
-                       continue;
-               }
-               /* LOGON */
-               if (TRUE == HasSystemGui())
-               {
-                       /* GUI active, login in graphical mode */
-                       GuiLogin();
-                       continue;
-               }
-               /* No GUI, login in console mode */
-               CuiLogin();
-       }
-}
-
-
-/* EOF */