First hack at KMDLLs
authorRex Jolliff <rex@lvcablemodem.com>
Fri, 28 May 1999 18:24:27 +0000 (18:24 +0000)
committerRex Jolliff <rex@lvcablemodem.com>
Fri, 28 May 1999 18:24:27 +0000 (18:24 +0000)
svn path=/trunk/; revision=523

15 files changed:
reactos/bootflop.bat
reactos/include/ddk/miniport.h [new file with mode: 0644]
reactos/include/internal/module.h
reactos/include/pe.h
reactos/lib/crtdll/.cvsignore [new file with mode: 0644]
reactos/lib/fmifs/.cvsignore [new file with mode: 0644]
reactos/lib/ntdll/.cvsignore
reactos/lib/user32/.cvsignore [new file with mode: 0644]
reactos/makedisk.bat
reactos/makefile.dos
reactos/makefile_rex
reactos/ntoskrnl/ldr/loader.c
reactos/ntoskrnl/makefile_rex
reactos/ntoskrnl/rtl/wstring.c
reactos/subsys/win32k/.cvsignore [new file with mode: 0644]

index 962ba9f..6765477 100644 (file)
@@ -3,12 +3,12 @@
 :
 : copy files to HD...
 :
-COPY /Y BLUE.SYS C:\reactos\system\drivers\blue.SYS
-COPY /Y KEYBOARD.SYS C:\reactos\system\drivers\KEYBOARD.SYS
-COPY /Y NTDLL.DLL C:\reactos\system\NTDLL.DLL
-COPY /Y KERNEL32.DLL C:\reactos\system\KERNEL32.DLL
-: COPY /Y CRTDLL.DLL C:\reactos\system\CRTDLL.DLL
-COPY /Y SHELL.EXE C:\reactos\system\SHELL.EXE
+COPY /Y BLUE.SYS C:\reactos\system\drivers\blue.SYS > NUL:
+COPY /Y KEYBOARD.SYS C:\reactos\system\drivers\KEYBOARD.SYS > NUL:
+COPY /Y NTDLL.DLL C:\reactos\system\NTDLL.DLL > NUL:
+COPY /Y KERNEL32.DLL C:\reactos\system\KERNEL32.DLL > NUL:
+: COPY /Y CRTDLL.DLL C:\reactos\system\CRTDLL.DLL > NUL:
+COPY /Y SHELL.EXE C:\reactos\system\SHELL.EXE > NUL:
 
 :
 : present a menu to the booter...
diff --git a/reactos/include/ddk/miniport.h b/reactos/include/ddk/miniport.h
new file mode 100644 (file)
index 0000000..d1ee3ab
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * MINIPORT.H - miniport driver interface header
+ */
+
+#define  EMULATOR_READ_ACCESS   0x00000001
+#define  EMULATOR_WRITE_ACCESS  0x00000002
+
+typedef enum _EMULATOR_PORT_ACCESS_TYPE 
+{
+  Uchar,
+  Ushort,
+  Ulong
+} EMULATOR_PORT_ACCESS_TYPE, *PEMULATOR_PORT_ACCESS_TYPE;
+
+typedef struct _EMULATOR_ACCESS_ENTRY 
+{
+  ULONG  BasePort;
+  ULONG  NumConsecutivePorts;
+  EMULATOR_PORT_ACCESS_TYPE  AccessType;
+  UCHAR  AccessMode;
+  UCHAR  StringSupport;
+  PVOID  Routine;
+} EMULATOR_ACCESS_ENTRY, *PEMULATOR_ACCESS_ENTRY;
+
+
index 3f4a004..7a58e02 100644 (file)
@@ -2,6 +2,7 @@
 #ifndef __MODULE_H
 #define __MODULE_H
 
+#include <ddk/ntddk.h>
 #include <coff.h>
 #include <pe.h>
 
@@ -30,11 +31,13 @@ typedef struct _module
 
 typedef SCNHDR COFF_SECTION_HEADER, *PCOFF_SECTION_HEADER;
 
-typedef struct _MODULE
+typedef struct _MODULE_OBJECT
 {
-  PVOID Base;
-  unsigned int Size;
-  unsigned int Flags;
+  CSHORT  ObjectType;
+  CSHORT  ObjectSize;
+  PVOID  Base;
+  unsigned int  Flags;
+  PVOID  EntryPoint;
   union
     { 
       struct
@@ -51,10 +54,12 @@ typedef struct _MODULE
         {
           PIMAGE_FILE_HEADER FileHeader;
           PIMAGE_OPTIONAL_HEADER OptionalHeader;
-          PCOFF_SECTION_HEADER SectionList;
+          PIMAGE_SECTION_HEADER SectionList;
         } PE;
     } Image;
-} MODULE, *PMODULE;
+} MODULE_OBJECT, *PMODULE_OBJECT;
+
+typedef MODULE_OBJECT MODULE, *PMODULE;
 
 #define MODULE_FLAG_BIN  0x0001
 #define MODULE_FLAG_MZ   0x0002
@@ -64,7 +69,7 @@ typedef struct _MODULE
 
 typedef struct _INSTANCE
 {
- HANDLE ModuleHandle;
 HANDLE ModuleHandle;
 } INSTANCE, *PINSTANCE;
 
 BOOLEAN process_boot_module(unsigned int start);
index e5a3e91..811f99e 100644 (file)
@@ -554,6 +554,8 @@ typedef struct _IMAGE_SEPARATE_DEBUG_HEADER {
                         sizeof (IMAGE_FILE_HEADER)          +  \
                         sizeof (IMAGE_OPTIONAL_HEADER)))
 
+#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr) + (DWORD)(addValue))
+
 typedef struct _IMAGE_IMPORT_MODULE_DIRECTORY
 {
   DWORD    dwRVAFunctionNameList;
diff --git a/reactos/lib/crtdll/.cvsignore b/reactos/lib/crtdll/.cvsignore
new file mode 100644 (file)
index 0000000..38f835b
--- /dev/null
@@ -0,0 +1,2 @@
+crtdll.coff
+crtdll.dll
diff --git a/reactos/lib/fmifs/.cvsignore b/reactos/lib/fmifs/.cvsignore
new file mode 100644 (file)
index 0000000..8a9b128
--- /dev/null
@@ -0,0 +1,2 @@
+fmifs.coff
+fmifs.dll
index 8183b20..56fe6eb 100644 (file)
@@ -1,7 +1,8 @@
+base.tmp
+junk.tmp
 napi.asm
 napi.c
 ntdll.lib
-base.tmp
-junk.tmp
+ntdll.coff
 ntdll.dll
 temp.exp
diff --git a/reactos/lib/user32/.cvsignore b/reactos/lib/user32/.cvsignore
new file mode 100644 (file)
index 0000000..7bf9e03
--- /dev/null
@@ -0,0 +1,2 @@
+user32.coff
+user32.dll
index 7c5e20f..44c01f6 100644 (file)
@@ -1,13 +1,27 @@
 @echo off
 echo copying latest files to a:...
-copy /Y bootflop.bat a:\autoexec.bat
-copy /Y loaders\dos\loadros.com a:
-copy /Y apps\shell\shell.exe a:
-copy /Y ntoskrnl\ntoskrnl.exe a:
-copy /Y services\dd\blue\blue.sys a:
-copy /Y services\dd\keyboard\keyboard.sys a:
-copy /Y services\dd\ide\ide.sys a:
-copy /Y services\fs\vfat\vfatfsd.sys a:
-copy /Y lib\ntdll\ntdll.dll a:
-copy /Y lib\kernel32\kernel32.dll a:
-: copy /Y lib\crtdll\crtdll.dll a:
+copy /Y bootflop.bat a:\autoexec.bat > NUL:
+echo bootflop.bat to a:\autoexec.bat
+copy /Y loaders\dos\loadros.com a: > NUL:
+echo loadros.com
+copy /Y ntoskrnl\ntoskrnl.exe a: > NUL:
+echo ntoskrnl.exe
+copy /Y services\dd\ide\ide.sys a: > NUL:
+echo ide.sys
+copy /Y services\fs\vfat\vfatfsd.sys a: > NUL:
+echo vfatfsd.sys
+copy /Y services\dd\blue\blue.sys a: > NUL:
+echo blue.sys
+copy /Y services\dd\keyboard\keyboard.sys a: > NUL:
+echo keyboard.sys
+copy /Y lib\ntdll\ntdll.dll a: > NUL:
+echo ntdll.dll
+copy /Y lib\kernel32\kernel32.dll a: > NUL:
+echo kernel32.dll
+copy /Y apps\shell\shell.exe a: > NUL:
+echo shell.exe
+: copy /Y lib\crtdll\crtdll.dll a: > NUL:
+: echo lib\crtdll\crtdll.dll a:
+
+
+
index dbc9af8..69987ec 100644 (file)
@@ -17,6 +17,7 @@ include rules.mak
 COMPONENTS = iface_native ntoskrnl
 DLLS = ntdll kernel32 crtdll user32 fmifs gdi32
 #DLLS = crtdll mingw32
+SUBSYS = win32k
 
 #
 # Select the server(s) you want to build
@@ -41,7 +42,7 @@ KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS)
 APPS = args hello shell test cat bench
 # APPS = cmd
 
-all: $(COMPONENTS) $(DLLS) $(LOADERS) $(KERNEL_SERVICES) $(APPS)
+all: $(COMPONENTS) $(DLLS) $(SUBSYS) $(LOADERS) $(KERNEL_SERVICES) $(APPS)
 .PHONY: all
 
 clean: $(COMPONENTS:%=%_clean) $(DLLS:%=%_clean) $(LOADERS:%=%_clean) \
@@ -125,4 +126,15 @@ $(DLLS:%=%_clean): %_clean:
 
 .PHONY: $(DLLS) $(DLLS:%=%_clean)
 
+#
+# Kernel Subsystems
+#
+$(SUBSYS): %:
+       make -C subsys/$*
+
+$(SUBSYS:%=%_clean): %_clean:
+       make -C lib/$* clean
+
+.PHONY: $(SUBSYS) $(SUBSYS:%=%_clean)
+
 
index a329e4c..70ac1cd 100644 (file)
@@ -17,6 +17,7 @@ include rules.mak
 COMPONENTS = iface_native ntoskrnl
 DLLS = ntdll kernel32 crtdll user32 fmifs
 #DLLS = crtdll mingw32
+SUBSYS = win32k
 
 #
 # Select the server(s) you want to build
@@ -41,7 +42,7 @@ KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS)
 APPS = args hello shell test cat bench
 # APPS = cmd
 
-all: $(COMPONENTS) $(DLLS) $(LOADERS) $(KERNEL_SERVICES) $(APPS)
+all: $(COMPONENTS) $(DLLS) $(SUBSYS) $(LOADERS) $(KERNEL_SERVICES) $(APPS)
 .PHONY: all
 
 clean: $(COMPONENTS:%=%_clean) $(DLLS:%=%_clean) $(LOADERS:%=%_clean) \
@@ -125,4 +126,15 @@ $(DLLS:%=%_clean): %_clean:
 
 .PHONY: $(DLLS) $(DLLS:%=%_clean)
 
+#
+# Kernel Subsystems
+#
+$(SUBSYS): %:
+       make -C subsys/$*
+
+$(SUBSYS:%=%_clean): %_clean:
+       make -C lib/$* clean
+
+.PHONY: $(SUBSYS) $(SUBSYS:%=%_clean)
+
 
index 16a2c6b..fb9eb34 100644 (file)
@@ -22,6 +22,7 @@
 #include <internal/linkage.h>
 #include <internal/module.h>
 #include <internal/ntoskrnl.h>
+#include <internal/mmhal.h>
 #include <internal/ob.h>
 #include <internal/ps.h>
 #include <string.h>
@@ -38,6 +39,8 @@ NTSTATUS IoInitializeDriver(PDRIVER_INITIALIZE DriverEntry);
 
 /* MACROS ********************************************************************/
 
+#define  MODULE_ROOT_NAME  L"\\Modules\\"
+
 /* GLOBALS *******************************************************************/
 
 POBJECT_TYPE ObModuleType = NULL;
@@ -47,12 +50,25 @@ POBJECT_TYPE ObModuleType = NULL;
 NTSTATUS LdrLoadDriver(PUNICODE_STRING Filename);
 NTSTATUS LdrProcessDriver(PVOID ModuleLoadBase);
 
+PMODULE_OBJECT  LdrLoadModule(PUNICODE_STRING Filename);
+PMODULE_OBJECT  LdrProcessModule(PVOID ModuleLoadBase);
+PVOID  LdrGetExportAddress(PMODULE_OBJECT ModuleObject, char *Name, unsigned short Hint);
+static PIMAGE_SECTION_HEADER LdrPEGetEnclosingSectionHeader(DWORD  RVA,
+                                                            PMODULE_OBJECT  ModuleObject);
+static NTSTATUS LdrCreateModule(PVOID ObjectBody,
+                                PVOID Parent,
+                                PWSTR RemainingPath,
+                                POBJECT_ATTRIBUTES ObjectAttributes);
+
 /*  PE Driver load support  */
-static NTSTATUS LdrPEProcessDriver(PVOID ModuleLoadBase);
+static PMODULE_OBJECT  LdrPEProcessModule(PVOID ModuleLoadBase);
+static PVOID  LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject, 
+                                    char *Name, 
+                                    unsigned short Hint);
 static unsigned int LdrGetKernelSymbolAddr(char *Name);
 
 /*  COFF Driver load support  */
-static NTSTATUS LdrCOFFProcessDriver(PVOID ModuleLoadBase);
+static PMODULE_OBJECT  LdrCOFFProcessModule(PVOID ModuleLoadBase);
 static BOOLEAN LdrCOFFDoRelocations(module *Module, unsigned int SectionIndex);
 static BOOLEAN LdrCOFFDoAddr32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation);
 static BOOLEAN LdrCOFFDoReloc32Reloc(module *Module, SCNHDR *Section, RELOC *Relocation);
@@ -64,7 +80,14 @@ static unsigned int LdrCOFFGetSymbolValueByName(module *Module, char *SymbolName
 
 VOID LdrInitModuleManagement(VOID)
 {
+  HANDLE DirHandle, ModuleHandle;
+  NTSTATUS Status;
+  WCHAR NameBuffer[60];
   ANSI_STRING AnsiString;
+  UNICODE_STRING ModuleName;
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  PIMAGE_DOS_HEADER DosHeader;
+  PMODULE_OBJECT ModuleObject;
 
   /*  Register the process object type  */   
   ObModuleType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
@@ -82,8 +105,85 @@ VOID LdrInitModuleManagement(VOID)
   ObModuleType->Security = NULL;
   ObModuleType->QueryName = NULL;
   ObModuleType->OkayToClose = NULL;
+  ObModuleType->Create = LdrCreateModule;
   RtlInitAnsiString(&AnsiString, "Module");
   RtlAnsiStringToUnicodeString(&ObModuleType->TypeName, &AnsiString, TRUE);
+
+  /*  Create Modules object directory  */
+  wcscpy(NameBuffer, MODULE_ROOT_NAME);
+  *(wcsrchr(NameBuffer, L'\\')) = 0;
+  ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer);
+  ModuleName.Buffer = NameBuffer;
+  InitializeObjectAttributes(&ObjectAttributes, 
+                             &ModuleName, 
+                             0, 
+                             NULL, 
+                             NULL);
+  DPRINT("Create dir: %W\n", &ModuleName);
+  Status = ZwCreateDirectoryObject(&DirHandle, 0, &ObjectAttributes);
+  assert(NT_SUCCESS(Status));
+
+  /*  Add module entry for NTOSKRNL  */
+  wcscpy(NameBuffer, MODULE_ROOT_NAME);
+  wcscat(NameBuffer, L"ntoskrnl.exe");
+  ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer);
+  ModuleName.Buffer = NameBuffer;
+  DPRINT("Kernel's Module name is: %W\n", &ModuleName);
+  
+  /*  Initialize ObjectAttributes for ModuleObject  */
+  InitializeObjectAttributes(&ObjectAttributes, 
+                             &ModuleName, 
+                             0, 
+                             NULL, 
+                             NULL);
+
+  /*  Create module object  */
+  ModuleHandle = 0;
+  ModuleObject = ObCreateObject(&ModuleHandle,
+                                STANDARD_RIGHTS_REQUIRED,
+                                &ObjectAttributes,
+                                ObModuleType);
+  assert(ModuleObject != NULL);
+
+  /*  Initialize ModuleObject data  */
+  ModuleObject->Base = (PVOID) KERNEL_BASE;
+  ModuleObject->Flags = MODULE_FLAG_PE;
+  DosHeader = (PIMAGE_DOS_HEADER) KERNEL_BASE;
+  ModuleObject->Image.PE.FileHeader = 
+    (PIMAGE_FILE_HEADER) ((DWORD) ModuleObject->Base + 
+    DosHeader->e_lfanew + sizeof(ULONG));
+  ModuleObject->Image.PE.OptionalHeader = (PIMAGE_OPTIONAL_HEADER) 
+    ((DWORD)ModuleObject->Image.PE.FileHeader + sizeof(IMAGE_FILE_HEADER));
+  ModuleObject->Image.PE.SectionList = (PIMAGE_SECTION_HEADER) 
+    ((DWORD)ModuleObject->Image.PE.OptionalHeader + sizeof(IMAGE_OPTIONAL_HEADER));
+  ModuleObject->EntryPoint = (PVOID) ((DWORD) ModuleObject->Base + 
+    ModuleObject->Image.PE.OptionalHeader->AddressOfEntryPoint);
+  DPRINT("ModuleObject:%08x  entrypoint at %x\n", ModuleObject, ModuleObject->EntryPoint);
+
+  /* FIXME: Add fake module entry for HAL */
+
+}
+
+static NTSTATUS 
+LdrCreateModule(PVOID ObjectBody,
+                PVOID Parent,
+                PWSTR RemainingPath,
+                POBJECT_ATTRIBUTES ObjectAttributes)
+{
+  DPRINT("LdrCreateModule(ObjectBody %x, Parent %x, RemainingPath %w)\n",
+         ObjectBody, 
+         Parent, 
+         RemainingPath);
+  if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL)
+    {
+      return  STATUS_UNSUCCESSFUL;
+    }
+  if (Parent != NULL && RemainingPath != NULL)
+    {
+      ObAddEntryDirectory(Parent, ObjectBody, RemainingPath + 1);
+    }
+
+  return  STATUS_SUCCESS;
 }
 
 /*
@@ -125,17 +225,68 @@ VOID LdrLoadAutoConfigDrivers(VOID)
 
 NTSTATUS 
 LdrLoadDriver(PUNICODE_STRING Filename)
+{
+  PMODULE_OBJECT  ModuleObject;
+
+  ModuleObject = LdrLoadModule(Filename);
+  if (ModuleObject == 0)
+    {
+      return  STATUS_UNSUCCESSFUL;
+    }
+
+  /* FIXME: should we dereference the ModuleObject here?  */
+
+  return IoInitializeDriver(ModuleObject->EntryPoint); 
+}
+  
+PMODULE_OBJECT 
+LdrLoadModule(PUNICODE_STRING Filename)
 {
   PVOID ModuleLoadBase;
   NTSTATUS Status;
   HANDLE FileHandle;
-  OBJECT_ATTRIBUTES FileObjectAttributes;
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  PMODULE_OBJECT  ModuleObject;
   FILE_STANDARD_INFORMATION FileStdInfo;
+  WCHAR  NameBuffer[60];
+  PWSTR  RemainingPath;
+  UNICODE_STRING  ModuleName;
+
+  DPRINT("Loading Module %W...\n", Filename);
 
-  DbgPrint("Loading Driver %W...\n", Filename);
+  /*  Check for module already loaded  */
+  wcscpy(NameBuffer, MODULE_ROOT_NAME);
+  if (wcsrchr(Filename->Buffer, '\\') != 0)
+    {
+      wcscat(NameBuffer, wcsrchr(Filename->Buffer, '\\') + 1);
+    }
+  else
+    {
+      wcscat(NameBuffer, Filename->Buffer);
+    }  
+  ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer);
+  ModuleName.Buffer = NameBuffer;
+  InitializeObjectAttributes(&ObjectAttributes,
+                             &ModuleName, 
+                             0,
+                             NULL,
+                             NULL);
+  Status = ObFindObject(&ObjectAttributes,
+                        (PVOID *) &ModuleObject,
+                        &RemainingPath);
+  CHECKPOINT;
+  if (NT_SUCCESS(Status) && *RemainingPath == 0)
+    {
+      return ModuleObject;
+    }
+  CHECKPOINT;
+  if (!wcsncmp(Filename->Buffer, MODULE_ROOT_NAME, wcslen(MODULE_ROOT_NAME)))
+    {
+      return  0;
+    }
 
-  /*  Open the Driver  */
-  InitializeObjectAttributes(&FileObjectAttributes,
+  /*  Open the Module  */
+  InitializeObjectAttributes(&ObjectAttributes,
                              Filename, 
                              0,
                              NULL,
@@ -143,12 +294,13 @@ LdrLoadDriver(PUNICODE_STRING Filename)
   CHECKPOINT;
   Status = ZwOpenFile(&FileHandle, 
                       FILE_ALL_ACCESS, 
-                      &FileObjectAttributes, 
+                      &ObjectAttributes, 
                       NULL, 0, 0);
   CHECKPOINT;
   if (!NT_SUCCESS(Status))
     {
-      return Status;
+      DbgPrint("Could not open module file: %W\n", Filename);
+      return  0;
     }
   CHECKPOINT;
 
@@ -160,7 +312,8 @@ LdrLoadDriver(PUNICODE_STRING Filename)
                                   FileStandardInformation);
   if (!NT_SUCCESS(Status))
     {
-      return Status;
+      DbgPrint("Could not get file size\n");
+      return  0;
     }
   CHECKPOINT;
 
@@ -169,7 +322,8 @@ LdrLoadDriver(PUNICODE_STRING Filename)
                                   FileStdInfo.EndOfFile.u.LowPart);
   if (ModuleLoadBase == NULL)
     {
-      return STATUS_INSUFFICIENT_RESOURCES;
+      DbgPrint("could not allocate memory for module");
+      return  0;
     }
   CHECKPOINT;
 
@@ -181,23 +335,41 @@ LdrLoadDriver(PUNICODE_STRING Filename)
                       0, 0);
   if (!NT_SUCCESS(Status))
     {
+      DbgPrint("could not read module file into memory");
       ExFreePool(ModuleLoadBase);
-      return Status;
+
+      return  0;
     }
   CHECKPOINT;
 
   ZwClose(FileHandle);
 
-  Status = LdrProcessDriver(ModuleLoadBase);
+  ModuleObject = LdrProcessModule(ModuleLoadBase);
 
   /*  Cleanup  */
   ExFreePool(ModuleLoadBase);
 
-  return STATUS_SUCCESS;
+  return  ModuleObject;
 }
 
 NTSTATUS
 LdrProcessDriver(PVOID ModuleLoadBase)
+{
+  PMODULE_OBJECT ModuleObject;
+
+  ModuleObject = LdrProcessModule(ModuleLoadBase);
+  if (ModuleObject == 0)
+    {
+      return STATUS_UNSUCCESSFUL;
+    }
+
+  /* FIXME: should we dereference the ModuleObject here?  */
+
+  return IoInitializeDriver(ModuleObject->EntryPoint); 
+}
+
+PMODULE_OBJECT
+LdrProcessModule(PVOID ModuleLoadBase)
 {
   PIMAGE_DOS_HEADER PEDosHeader;
 
@@ -205,42 +377,66 @@ LdrProcessDriver(PVOID ModuleLoadBase)
   PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
   if (PEDosHeader->e_magic == IMAGE_DOS_MAGIC && PEDosHeader->e_lfanew != 0L)
     {
-      return LdrPEProcessDriver(ModuleLoadBase);
+      return LdrPEProcessModule(ModuleLoadBase);
     }
+#if 0
   if (PEDosHeader->e_magic == IMAGE_DOS_MAGIC)
     {
-      return STATUS_NOT_IMPLEMENTED;
+      return 0;
     }
   else  /*  Assume COFF format and load  */
     {
-      return LdrCOFFProcessDriver(ModuleLoadBase);
+      return LdrCOFFProcessModule(ModuleLoadBase);
     }
+#endif
+
+  return 0;
 }
 
-NTSTATUS 
-LdrPEProcessDriver(PVOID ModuleLoadBase)
+PVOID  
+LdrGetExportAddress(PMODULE_OBJECT ModuleObject, 
+                    char *Name, 
+                    unsigned short Hint)
 {
-  unsigned int DriverSize, Idx;
+  if (ModuleObject->Flags & MODULE_FLAG_PE)
+    {
+      return LdrPEGetExportAddress(ModuleObject, Name, Hint);
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+/*  ----------------------------------------------  PE Module support */
+
+PMODULE_OBJECT
+LdrPEProcessModule(PVOID ModuleLoadBase)
+{
+  unsigned int DriverSize, Idx, Idx2;
   ULONG RelocDelta, NumRelocs;
   DWORD CurrentSize, TotalRelocs;
-  PVOID DriverBase, CurrentBase, EntryPoint;
+  PVOID DriverBase, CurrentBase;
   PULONG PEMagic;
   PIMAGE_DOS_HEADER PEDosHeader;
   PIMAGE_FILE_HEADER PEFileHeader;
   PIMAGE_OPTIONAL_HEADER PEOptionalHeader;
   PIMAGE_SECTION_HEADER PESectionHeaders;
+  PIMAGE_EXPORT_DIRECTORY  ExportDirectory;
   PRELOCATION_DIRECTORY RelocDir;
   PRELOCATION_ENTRY RelocEntry;
-  PMODULE Library;
+  PMODULE_OBJECT  LibraryModuleObject;
+  HANDLE  ModuleHandle;
+  PMODULE_OBJECT  ModuleObject;
   PVOID *ImportAddressList;
   PULONG FunctionNameList;
   PCHAR pName, SymbolNameBuf;
-  PWORD pHint;
+  WORD Hint;
+  OBJECT_ATTRIBUTES  ObjectAttributes;
+  UNICODE_STRING  ModuleName;
+  WCHAR  NameBuffer[60];
   
-  /* FIXME: this could be used to load kernel DLLs also, however */
-  /*        the image headers should be preserved in such a case */
-
-  DPRINT("Processing PE Driver at module base:%08lx\n", ModuleLoadBase);
+  DPRINT("Processing PE Module at module base:%08lx\n", ModuleLoadBase);
 
   /*  Get header pointers  */
   PEDosHeader = (PIMAGE_DOS_HEADER) ModuleLoadBase;
@@ -258,23 +454,23 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
   /*  Check file magic numbers  */
   if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC)
     {
-      DPRINT("Incorrect MZ magic: %04x\n", PEDosHeader->e_magic);
-      return STATUS_UNSUCCESSFUL;
+      DbgPrint("Incorrect MZ magic: %04x\n", PEDosHeader->e_magic);
+      return 0;
     }
   if (PEDosHeader->e_lfanew == 0)
     {
-      DPRINT("Invalid lfanew offset: %08x\n", PEDosHeader->e_lfanew);
-      return STATUS_UNSUCCESSFUL;
+      DbgPrint("Invalid lfanew offset: %08x\n", PEDosHeader->e_lfanew);
+      return 0;
     }
   if (*PEMagic != IMAGE_PE_MAGIC)
     {
-      DPRINT("Incorrect PE magic: %08x\n", *PEMagic);
-      return STATUS_UNSUCCESSFUL;
+      DbgPrint("Incorrect PE magic: %08x\n", *PEMagic);
+      return 0;
     }
   if (PEFileHeader->Machine != IMAGE_FILE_MACHINE_I386)
     {
-      DPRINT("Incorrect Architechture: %04x\n", PEFileHeader->Machine);
-      return STATUS_UNSUCCESSFUL;
+      DbgPrint("Incorrect Architechture: %04x\n", PEFileHeader->Machine);
+      return 0;
     }
   CHECKPOINT;
 
@@ -299,10 +495,10 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
   if (DriverBase == 0)
     {
       DbgPrint("Failed to allocate a virtual section for driver\n");
-      return STATUS_INSUFFICIENT_RESOURCES;
+      return 0;
     }
   CHECKPOINT;
-   DbgPrint("Module is at base %x\n",DriverBase);
+   DPRINT("Module is at base %x\n",DriverBase);
    
   /*  Copy image sections into virtual section  */
   memcpy(DriverBase, ModuleLoadBase, PESectionHeaders[0].PointerToRawData);
@@ -390,8 +586,8 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
             }
           else if (Type != 0)
             {
-              DPRINT("Unknown relocation type %x\n",Type);
-              return STATUS_UNSUCCESSFUL;
+              DbgPrint("Unknown relocation type %x\n",Type);
+              return 0;
             }
         }
       TotalRelocs += RelocDir->SizeOfBlock;
@@ -415,21 +611,36 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
       ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)
         ((DWORD)DriverBase + PEOptionalHeader->
           DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
+      DPRINT("Processeing import directory at %p\n", ImportModuleDirectory);
       while (ImportModuleDirectory->dwRVAModuleName)
         {
-          /* FIXME: handle kernel mode DLLs  */
-
           /*  Check to make sure that import lib is kernel  */
-          Library = NULL;
           pName = (PCHAR) DriverBase + 
             ImportModuleDirectory->dwRVAModuleName;
-//          DPRINT("Import module: %s\n", pName);
-          if (strcmp(pName, "ntoskrnl.exe")!=0 && 
-              strcmp(pName, "HAL.dll")!=0)
+          if (!strcmp(pName, "ntoskrnl.exe") || !strcmp(pName, "HAL.dll"))
             {
-              DPRINT("Kernel mode DLLs are currently unsupported\n");
+              LibraryModuleObject = NULL;
+              DPRINT("Kernel imports\n");
+            }
+          else
+            {
+              wcscpy(NameBuffer, MODULE_ROOT_NAME);
+              for (Idx = 0; NameBuffer[Idx] != 0; Idx++)
+                ;
+              for (Idx2 = 0; pName[Idx2] != '\0'; Idx2++)
+                {
+                  NameBuffer[Idx + Idx2] = (WCHAR) pName[Idx2];
+                }
+              NameBuffer[Idx + Idx2] = 0;
+              ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer);
+              ModuleName.Buffer = NameBuffer;
+              DPRINT("Import module: %W\n", &ModuleName);
+              LibraryModuleObject = LdrLoadModule(&ModuleName);
+              if (LibraryModuleObject == 0)
+                {
+                  DbgPrint("Unknown import module: %W\n", &ModuleName);
+                }
             }
-
           /*  Get the import address list  */
           ImportAddressList = (PVOID *) ((DWORD)DriverBase + 
             ImportModuleDirectory->dwRVAFunctionAddressList);
@@ -445,35 +656,38 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
               FunctionNameList = (PULONG) ((DWORD)DriverBase + 
                 ImportModuleDirectory->dwRVAFunctionAddressList);
             }
-
           /*  Walk through function list and fixup addresses  */
-          while(*FunctionNameList != 0L)
+          while (*FunctionNameList != 0L)
             {
               if ((*FunctionNameList) & 0x80000000) // hint
                 {
-//                  DPRINT("  Hint: %08lx\n", *FunctionNameList);
-                  if (Library == NULL)
-                    {
-                      DPRINT("Hints for kernel symbols are not handled.\n");
-                      *ImportAddressList = 0;
-                    }
+                  pName = NULL;
+                  Hint = (*FunctionNameList) & 0xffff;
                 }
               else // hint-name
                 {
-                  pName = (PCHAR)((DWORD)DriverBase+ 
+                  pName = (PCHAR)((DWORD)DriverBase 
                                   *FunctionNameList + 2);
-                  pHint = (PWORD)((DWORD)DriverBase + *FunctionNameList);
- //                 DPRINT("  Hint:%04x  Name:%s\n", pHint, pName);
-                  
+                  Hint = *(PWORD)((DWORD)DriverBase + *FunctionNameList);
+                }
+              DPRINT("  Hint:%04x  Name:%s\n", Hint, pName);
+
+              /*  Fixup the current import symbol  */
+              if (LibraryModuleObject != NULL)
+                {
+                  *ImportAddressList = LdrGetExportAddress(LibraryModuleObject, 
+                                                           pName, 
+                                                           Hint);
+                }
+              else
+                {
                   /*  Get address for symbol  */
-                  if (Library == NULL)
+                  *SymbolNameBuf = '_';
+                  strcpy(SymbolNameBuf + 1, pName);
+                  *ImportAddressList = (PVOID) LdrGetKernelSymbolAddr(SymbolNameBuf);
+                  if (*ImportAddressList == 0L)
                     {
-                      *SymbolNameBuf = '_';
-                      strcpy(SymbolNameBuf + 1, pName);
-                      *ImportAddressList = (PVOID) LdrGetKernelSymbolAddr(SymbolNameBuf);                      if (*ImportAddressList == 0L)
-                        {
-                          DPRINT("Unresolved kernel symbol: %s\n", pName);
-                        }
+                      DbgPrint("Unresolved kernel symbol: %s\n", pName);
                     }
                 }
               ImportAddressList++;
@@ -485,15 +699,165 @@ LdrPEProcessDriver(PVOID ModuleLoadBase)
       ExFreePool(SymbolNameBuf);
     }
 
-  /*  Compute address of entry point  */
-  EntryPoint = (PVOID) ((DWORD)DriverBase + PEOptionalHeader->AddressOfEntryPoint);
-   DbgPrint("Calling entrypoint at %x\n",EntryPoint);
+  /*  Create ModuleName string  */
+  wcscpy(NameBuffer, MODULE_ROOT_NAME);
+  if (PEOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
+        .VirtualAddress != 0)
+    {
+      ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) (DriverBase +
+        PEOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
+          .VirtualAddress);
+      wcscat(NameBuffer, DriverBase + ExportDirectory->Name);
+    }
+  else
+    {
+      char buf[12];
+
+      sprintf(buf, "%08X", (DWORD) DriverBase);
+      for (Idx = 0; NameBuffer[Idx] != 0; Idx++)
+        ;
+      Idx2 = 0;
+      while ((NameBuffer[Idx + Idx2] = (WCHAR) buf[Idx2]) != 0)
+        Idx2++;
+    }
+  ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer);
+  ModuleName.Buffer = NameBuffer;
+  DPRINT("Module name is: %W\n", &ModuleName);
+  
+  /*  Initialize ObjectAttributes for ModuleObject  */
+  InitializeObjectAttributes(&ObjectAttributes, 
+                             &ModuleName, 
+                             0, 
+                             NULL, 
+                             NULL);
+
+  /*  Create module object  */
+  ModuleHandle = 0;
+  ModuleObject = ObCreateObject(&ModuleHandle,
+                                STANDARD_RIGHTS_REQUIRED,
+                                &ObjectAttributes,
+                                ObModuleType);
+
+  /*  Initialize ModuleObject data  */
+  ModuleObject->Base = DriverBase;
+  ModuleObject->Flags = MODULE_FLAG_PE;
+  ModuleObject->EntryPoint = (PVOID) ((DWORD)DriverBase + 
+    PEOptionalHeader->AddressOfEntryPoint);
+  DPRINT("entrypoint at %x\n", ModuleObject->EntryPoint);
+  ModuleObject->Image.PE.FileHeader = 
+    (PIMAGE_FILE_HEADER) ((unsigned int) DriverBase + 
+    PEDosHeader->e_lfanew + sizeof(ULONG));
+  DPRINT("FileHeader at %x\n", ModuleObject->Image.PE.FileHeader);
+  ModuleObject->Image.PE.OptionalHeader = 
+    (PIMAGE_OPTIONAL_HEADER) ((unsigned int) DriverBase + 
+    PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER));
+  DPRINT("OptionalHeader at %x\n", ModuleObject->Image.PE.OptionalHeader);
+  ModuleObject->Image.PE.SectionList = 
+    (PIMAGE_SECTION_HEADER) ((unsigned int) DriverBase + 
+    PEDosHeader->e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) +
+    sizeof(IMAGE_OPTIONAL_HEADER));
+  DPRINT("SectionList at %x\n", ModuleObject->Image.PE.SectionList);
+
+  return  ModuleObject;
+}
+
+static PVOID  
+LdrPEGetExportAddress(PMODULE_OBJECT ModuleObject, 
+                      char *Name, 
+                      unsigned short Hint)
+{
+  WORD  Idx;
+  DWORD  ExportsStartRVA, ExportsEndRVA, Delta;
+  PVOID  ExportAddress;
+  PWORD  OrdinalList;
+  PDWORD  FunctionList, NameList;
+  PIMAGE_SECTION_HEADER  SectionHeader;
+  PIMAGE_EXPORT_DIRECTORY  ExportDirectory;
+
+  ExportsStartRVA = ModuleObject->Image.PE.OptionalHeader->DataDirectory
+    [IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+  ExportsEndRVA = ExportsStartRVA + 
+    ModuleObject->Image.PE.OptionalHeader->DataDirectory
+      [IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
+  /*  Get the IMAGE_SECTION_HEADER that contains the exports.  This is
+      usually the .edata section, but doesn't have to be.  */
+  SectionHeader = LdrPEGetEnclosingSectionHeader(ExportsStartRVA, ModuleObject);
+  if (!SectionHeader)
+    {
+      return 0;
+    }
+  Delta = (DWORD)(SectionHeader->VirtualAddress - 
+    SectionHeader->PointerToRawData);
+  ExportDirectory = MakePtr(PIMAGE_EXPORT_DIRECTORY, 
+                            ModuleObject->Base,
+                            ExportsStartRVA - Delta);
+
+  FunctionList = (PDWORD)((DWORD)ExportDirectory->AddressOfFunctions - 
+    Delta + ModuleObject->Base);
+  NameList = (PDWORD)((DWORD)ExportDirectory->AddressOfNames - 
+    Delta + ModuleObject->Base);
+  OrdinalList = (PWORD)((DWORD)ExportDirectory->AddressOfNameOrdinals - 
+    Delta + ModuleObject->Base);
+  DPRINT("Delta:%08x\n", Delta);
+  DPRINT("Func:%08x  RVA:%08x  Name:%08x  RVA:%08x  Ord:%08x  RVA:%08x\n", FunctionList,
+         ExportDirectory->AddressOfFunctions, NameList,
+         ExportDirectory->AddressOfNames, OrdinalList,
+         ExportDirectory->AddressOfNameOrdinals);
+  DPRINT("NumNames:%d NumFuncs:%d\n", ExportDirectory->NumberOfNames, 
+         ExportDirectory->NumberOfFunctions);
+for(;;);
+  ExportAddress = 0;
+  if (Name != NULL)
+    {
+      for (Idx = 0; Idx < ExportDirectory->NumberOfNames; Idx++)
+        {
+          DPRINT("  Name:%s  NameList[%d]:%s\n", Name, Idx, NameList[Idx]);
+          if (!strcmp(Name, (PCHAR) ((DWORD)ModuleObject->Base + NameList[Idx])))
+            {
+              ExportAddress = (PVOID) ((DWORD)ModuleObject->Base +
+                FunctionList[OrdinalList[Idx]]);
+              break;
+            }
+        }
+    }
+  else  /*  use hint  */
+    {
+      ExportAddress = (PVOID) ((DWORD)ModuleObject->Base +
+        FunctionList[Hint - ExportDirectory->Base]);
+    }
+  if (ExportAddress == 0)
+    {
+      DbgPrint("Export not found for %d:%s\n", Hint, Name != NULL ? Name : "(Ordinal)");
+    }
+
+  return  ExportAddress;
+}
 
-  return IoInitializeDriver(EntryPoint); 
+static PIMAGE_SECTION_HEADER 
+LdrPEGetEnclosingSectionHeader(DWORD  RVA,
+                               PMODULE_OBJECT  ModuleObject)
+{
+  PIMAGE_SECTION_HEADER  SectionHeader = SECHDROFFSET(ModuleObject->Base);
+  unsigned  i;
+    
+  for (i = 0; i < ModuleObject->Image.PE.FileHeader->NumberOfSections; 
+       i++, SectionHeader++)
+    {
+      /*  Is the RVA within this section?  */
+      if ((RVA >= SectionHeader->VirtualAddress) && 
+          (RVA < (SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize)))
+        {
+          return SectionHeader;
+        }
+    }
+    
+  return 0;
 }
 
-NTSTATUS 
-LdrCOFFProcessDriver(PVOID ModuleLoadBase)
+/*  -------------------------------------------  COFF Module support */
+
+PMODULE_OBJECT 
+LdrCOFFProcessModule(PVOID ModuleLoadBase)
 {
   BOOLEAN FoundEntry;
   char SymbolName[255];
@@ -502,7 +866,12 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
   FILHDR *FileHeader;
   AOUTHDR *AOUTHeader;
   module *Module;
-  PDRIVER_INITIALIZE EntryRoutine;
+  PVOID  EntryRoutine;
+  HANDLE  ModuleHandle;
+  PMODULE_OBJECT  ModuleObject;
+  OBJECT_ATTRIBUTES  ObjectAttributes;
+  UNICODE_STRING  ModuleName;
+  WCHAR  NameBuffer[60];
 
   /*  Get header pointers  */
   FileHeader = ModuleLoadBase;
@@ -514,7 +883,7 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
     {
       DbgPrint("Module has bad magic value (%x)\n", 
                FileHeader->f_magic);
-      return STATUS_UNSUCCESSFUL;
+      return 0;
     }
   CHECKPOINT;
    
@@ -522,7 +891,7 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
   Module = (module *) ExAllocatePool(NonPagedPool, sizeof(module));
   if (Module == NULL)
     {
-      return STATUS_INSUFFICIENT_RESOURCES;
+      return 0;
     }
   Module->sym_list = (SYMENT *)(ModuleLoadBase + FileHeader->f_symptr);
   Module->str_tab = (char *)(ModuleLoadBase + FileHeader->f_symptr +
@@ -569,7 +938,7 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
     {
       DbgPrint("Failed to alloc section for module\n");
       ExFreePool(Module);
-      return STATUS_INSUFFICIENT_RESOURCES;
+      return 0;
     }
   CHECKPOINT;
 
@@ -589,14 +958,14 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
                  Module->scn_list[i].s_size);
           if (!LdrCOFFDoRelocations(Module, i))
             {
-              DPRINT("Relocation failed for section %s\n",
+              DbgPrint("Relocation failed for section %s\n",
                      Module->scn_list[i].s_name);
 
               /* FIXME: unallocate all sections here  */
 
               ExFreePool(Module);
 
-              return STATUS_UNSUCCESSFUL;
+              return 0;
             }
         }
       if (Module->scn_list[i].s_flags & STYP_BSS)
@@ -607,7 +976,7 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
         }
     }
    
-  DbgPrint("Module base: %x\n", Module->base);
+  DPRINT("Module base: %x\n", Module->base);
    
   /*  Find the entry point  */
   EntryOffset = 0L;
@@ -629,16 +998,46 @@ LdrCOFFProcessDriver(PVOID ModuleLoadBase)
 
       /* FIXME: unallocate all sections here  */
 
-      return STATUS_UNSUCCESSFUL;
+      return 0;
     }
    
   /*  Get the address of the module initalization routine  */
-  EntryRoutine = (PDRIVER_INITIALIZE)(Module->base + EntryOffset);
+  EntryRoutine = (PVOID)(Module->base + EntryOffset);
+
+  /*  Create ModuleName string  */
+  wcscpy(NameBuffer, MODULE_ROOT_NAME);
+  /* FIXME: someone who is interested needs to fix this.  */
+  wcscat(NameBuffer, L"BOGUS.o");
+  ModuleName.Length = ModuleName.MaximumLength = wcslen(NameBuffer);
+  ModuleName.Buffer = NameBuffer;
+  DPRINT("Module name is: %w", NameBuffer);
+  
+  /*  Initialize ObjectAttributes for ModuleObject  */
+  InitializeObjectAttributes(&ObjectAttributes, 
+                             &ModuleName, 
+                             0, 
+                             NULL, 
+                             NULL);
+
+  /*  Create module object  */
+  ModuleHandle = 0;
+  ModuleObject = ObCreateObject(&ModuleHandle,
+                                OBJECT_TYPE_ALL_ACCESS,
+                                &ObjectAttributes,
+                                ObModuleType);
+
+  /*  Initialize ModuleObject data  */
+  ModuleObject->Base = (PVOID) Module->base;
+  ModuleObject->Flags = MODULE_FLAG_COFF;
+  ModuleObject->EntryPoint = (PVOID) (Module->base + EntryOffset);
+  DPRINT("entrypoint at %x\n", ModuleObject->EntryPoint);
+  /* FIXME: the COFF headers need to be copied into the module 
+     space, and the ModuleObject needs to be set to point to them  */
 
   /*  Cleanup  */
   ExFreePool(Module);
 
-  return IoInitializeDriver(EntryRoutine);
+  return  ModuleObject;
 }
 
 /*   LdrCOFFDoRelocations
@@ -684,7 +1083,7 @@ LdrCOFFDoRelocations(module *Module, unsigned int SectionIndex)
             break;
 
           default:
-            DPRINT("%.8s: Unknown relocation type %x at %d in module\n",
+            DbgPrint("%.8s: Unknown relocation type %x at %d in module\n",
                    Module->scn_list[SectionIndex].s_name,
                    Relocation->r_type,
                    j);
@@ -846,7 +1245,7 @@ LdrGetKernelSymbolAddr(char *Name)
    if ((s=strchr(Name,'@'))!=NULL)
      {
        *s=0;
-       DbgPrint("Name %s ",Name);
+       DPRINT("Name %s ",Name);
      }
   while (symbol_table[i].name != NULL)
     {
@@ -855,7 +1254,7 @@ LdrGetKernelSymbolAddr(char *Name)
           if (s!=NULL)
             {
                *s=0;
-               DbgPrint("Matched with %s\n",symbol_table[i].name);
+               DPRINT("Matched with %s\n",symbol_table[i].name);
             }
           return symbol_table[i].value;
         }
index 20344e0..1b1d51d 100644 (file)
@@ -133,17 +133,19 @@ else
 endif
        $(CC) $(CFLAGS) -c ke/exports.c -o ke/exports.o
 
-ntoskrnl.exe: $(OBJECTS) ntoskrnl.def
-       $(LD) -r $(OBJECTS) -o ntoskrnl.o
-       $(DLLTOOL) --dllname ntoskrnl.exe --def ntoskrnl.def \
-                  --output-lib ntoskrnl.a
+all: ntoskrnl.a ntoskrnl.exe ntoskrnl.sym
+
+.PHONY: all
+
+ntoskrnl.exe: ntoskrnl.o ntoskrnl.def
        $(CC) -specs=../specs -mdll -o junk.tmp \
              -Wl,--image-base,0xc0000000 \
              -Wl,--file-alignment,0x1000 \
              -Wl,--section-alignment,0x1000 \
              -Wl,--defsym,_end=end \
              -Wl,--defsym,_edata=__data_end__ \
-             -Wl,--defsym,_etext=etext -Wl,--base-file,base.tmp ntoskrnl.o
+             -Wl,--defsym,_etext=etext -Wl,--base-file,base.tmp \
+              ntoskrnl.o
        - $(RM) junk.tmp
        $(DLLTOOL) --dllname ntoskrnl.exe --base-file base.tmp \
                   --output-exp temp.exp --def ntoskrnl.def
@@ -158,6 +160,13 @@ ntoskrnl.exe: $(OBJECTS) ntoskrnl.def
        - $(RM) temp.exp
        $(NM) --numeric-sort ntoskrnl.exe > ntoskrnl.sym
 
+ntoskrnl.o: $(OBJECTS)
+       $(LD) -r $(OBJECTS) -o ntoskrnl.o
+
+ntoskrnl.a: ntoskrnl.def
+       $(DLLTOOL) --dllname ntoskrnl.exe --def ntoskrnl.def \
+                  --output-lib ntoskrnl.a
+
 clean: $(CLEAN_FILES:%=%_clean)
 
 $(CLEAN_FILES:%=%_clean): %_clean:
index cb734a5..7b3fab4 100644 (file)
@@ -137,7 +137,12 @@ wcsncat(wchar_t *dest, const wchar_t *src, size_t count)
 int 
 wcsncmp(const wchar_t *cs, const wchar_t *ct, size_t count)
 {
-UNIMPLEMENTED;
+  while (*cs != '\0' && *ct != '\0' && *cs == *ct && --count)
+    {
+      cs++;
+      ct++;
+    }
+  return *cs - *ct;
 }
 
 
diff --git a/reactos/subsys/win32k/.cvsignore b/reactos/subsys/win32k/.cvsignore
new file mode 100644 (file)
index 0000000..ed76926
--- /dev/null
@@ -0,0 +1,2 @@
+win32k.coff
+win32k.sys