ntdll/kernel32: #13

Eric Pouech pouech-eric at wanadoo.fr
Sun Mar 23 12:32:50 CST 2003


- no longer using kernel32's APIs but ntdll's
- BUILTIN32_dlopen and BUILTIN32_dlclose now properly return NTDLL style 
status codes

A+
-- 
Eric Pouech
-------------- next part --------------
diff -u -x '*~' -x '.#*' if163212/builtin.c if1632/builtin.c
--- if163212/builtin.c	2003-03-21 21:59:24.000000000 +0100
+++ if1632/builtin.c	2003-03-21 21:56:04.000000000 +0100
@@ -202,7 +202,7 @@
     if ((descr = find_dll_descr( dllname )))
         return BUILTIN_DoLoadModule16( descr );
 
-    if ((handle = BUILTIN32_dlopen( dllname )))
+    if (BUILTIN32_dlopen( dllname, &handle ) == STATUS_SUCCESS)
     {
         if ((descr = find_dll_descr( dllname )))
             return BUILTIN_DoLoadModule16( descr );
diff -u -x '*~' -x '.#*' include12/module.h include/module.h
--- include12/module.h	2003-03-21 22:35:29.000000000 +0100
+++ include/module.h	2003-03-23 09:09:39.000000000 +0100
@@ -248,8 +248,8 @@
 /* relay32/builtin.c */
 extern NTSTATUS BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags, WINE_MODREF**);
 extern HMODULE BUILTIN32_LoadExeModule( HMODULE main );
-extern void *BUILTIN32_dlopen( const char *name );
-extern int BUILTIN32_dlclose( void *handle );
+extern NTSTATUS BUILTIN32_dlopen( const char *name, void** handle );
+extern NTSTATUS BUILTIN32_dlclose( void *handle );
 
 /* if1632/builtin.c */
 extern HMODULE16 BUILTIN_LoadModule( LPCSTR name );
diff -u -x '*~' -x '.#*' relay3212/builtin32.c relay32/builtin32.c
--- relay3212/builtin32.c	2003-03-21 19:20:44.000000000 +0100
+++ relay32/builtin32.c	2003-03-23 19:26:24.000000000 +0100
@@ -35,7 +35,7 @@
 #include "wine/library.h"
 #include "module.h"
 #include "file.h"
-#include "winerror.h"
+#include "ntdll_misc.h"
 #include "wine/server.h"
 #include "wine/debug.h"
 
@@ -45,37 +45,47 @@
 extern void RELAY_SetupDLL( const char *module );
 
 static HMODULE main_module;
+static NTSTATUS last_status; /* use to gather all errors in callback */
 
 /***********************************************************************
  *           BUILTIN32_dlopen
+ *
+ * The loader critical section must be locked while calling this function
  */
-void *BUILTIN32_dlopen( const char *name )
+NTSTATUS BUILTIN32_dlopen( const char *name, void** handle)
 {
-    void *handle;
     char error[256];
 
-    if (!(handle = wine_dll_load( name, error, sizeof(error) )))
+    last_status = STATUS_SUCCESS;
+    /* load_library will modify last_status. Note also that load_library can be
+     * called several times, if the .so file we're loading has dependencies.
+     * last_status will gather all the errors we may get while loading all these
+     * libraries
+     */
+    if (!(*handle = wine_dll_load( name, error, sizeof(error) )))
     {
         if (strstr(error, "cannot open") || strstr(error, "open failed") ||
             (strstr(error, "Shared object") && strstr(error, "not found"))) {
 	    /* The file does not exist -> WARN() */
             WARN("cannot open .so lib for builtin %s: %s\n", name, error);
+            last_status = STATUS_NO_SUCH_FILE;
         } else {
 	    /* ERR() for all other errors (missing functions, ...) */
             ERR("failed to load .so lib for builtin %s: %s\n", name, error );
+            last_status = STATUS_PROCEDURE_NOT_FOUND;
 	}
     }
-    return handle;
+    return last_status;
 }
 
 /***********************************************************************
  *           BUILTIN32_dlclose
  */
-int BUILTIN32_dlclose( void *handle )
+NTSTATUS BUILTIN32_dlclose( void *handle )
 {
     /* FIXME: should unregister descriptors first */
     /* wine_dll_unload( handle ); */
-    return 0;
+    return STATUS_SUCCESS;
 }
 
 
@@ -86,7 +96,8 @@
  */
 static void load_library( void *base, const char *filename )
 {
-    HMODULE module = (HMODULE)base;
+    UNICODE_STRING      wstr;
+    HMODULE module = (HMODULE)base, ret;
     IMAGE_NT_HEADERS *nt;
     WINE_MODREF *wm;
     char *fullname;
@@ -100,6 +111,7 @@
     if (!(nt = RtlImageNtHeader( module )))
     {
         ERR( "bad module for %s\n", filename ? filename : "main exe" );
+        last_status = STATUS_INVALID_IMAGE_FORMAT;
         return;
     }
 
@@ -110,14 +122,17 @@
         return; /* don't create the modref here, will be done later on */
     }
 
-    if (GetModuleHandleA( filename ))
-        MESSAGE( "Warning: loading builtin %s, but native version already present. Expect trouble.\n", filename );
+    RtlCreateUnicodeStringFromAsciiz(&wstr, filename);
+    if (LdrGetDllHandle(0, 0, &wstr, &ret) == STATUS_SUCCESS)
+        MESSAGE( "Warning: loading builtin %s, but native version already present. "
+                 "Expect trouble.\n", filename );
+    RtlFreeUnicodeString( &wstr );
 
     len = GetSystemDirectoryA( NULL, 0 );
-    if (!(fullname = HeapAlloc( GetProcessHeap(), 0, len + strlen(filename) + 1 )))
+    if (!(fullname = RtlAllocateHeap( ntdll_get_process_heap(), 0, len + strlen(filename) + 1 )))
     {
         ERR( "can't load %s\n", filename );
-        SetLastError( ERROR_OUTOFMEMORY );
+        last_status = STATUS_NO_MEMORY;
         return;
     }
     GetSystemDirectoryA( fullname, len );
@@ -128,12 +143,12 @@
     if (!(wm = PE_CreateModule( module, fullname, 0, 0, TRUE )))
     {
         ERR( "can't load %s\n", filename );
-        HeapFree( GetProcessHeap(), 0, fullname );
-        SetLastError( ERROR_OUTOFMEMORY );
+        RtlFreeHeap( ntdll_get_process_heap(), 0, fullname );
+        last_status = STATUS_NO_MEMORY;
         return;
     }
     TRACE( "loaded %s %p %p\n", fullname, wm, module );
-    HeapFree( GetProcessHeap(), 0, fullname );
+    RtlFreeHeap( ntdll_get_process_heap(), 0, fullname );
 
     /* setup relay debugging entry points */
     if (TRACE_ON(relay)) RELAY_SetupDLL( (void *)module );
@@ -151,6 +166,7 @@
     char dllname[20], *p;
     LPCSTR name;
     void *handle;
+    NTSTATUS nts;
 
     /* Fix the name in case we have a full path and extension */
     name = path;
@@ -164,7 +180,8 @@
     if (!p) strcat( dllname, ".dll" );
     for (p = dllname; *p; p++) *p = FILE_tolower(*p);
 
-    if (!(handle = BUILTIN32_dlopen( dllname ))) return STATUS_NO_SUCH_FILE;
+    if ((nts = BUILTIN32_dlopen( dllname, &handle )) != STATUS_SUCCESS)
+        return nts;
 
     if (!((*pwm) = MODULE_FindModule( path ))) *pwm = MODULE_FindModule( dllname );
     if (!*pwm)
@@ -186,20 +203,13 @@
 HMODULE BUILTIN32_LoadExeModule( HMODULE main )
 {
     main_module = main;
+    last_status = STATUS_SUCCESS;
     wine_dll_set_callback( load_library );
     if (!main_module)
         MESSAGE( "No built-in EXE module loaded!  Did you create a .spec file?\n" );
+    if (last_status != STATUS_SUCCESS)
+        MESSAGE( "Error while processing initial modules\n");
+
     return main_module;
 }
 
-
-/***********************************************************************
- *           BUILTIN32_RegisterDLL
- *
- * Register a built-in DLL descriptor.
- */
-void BUILTIN32_RegisterDLL( const IMAGE_NT_HEADERS *header, const char *filename )
-{
-    extern void __wine_dll_register( const IMAGE_NT_HEADERS *header, const char *filename );
-    __wine_dll_register( header, filename );
-}
Common subdirectories: relay3212/CVS and relay32/CVS
diff -u -x '*~' -x '.#*' relay3212/relay386.c relay32/relay386.c
--- relay3212/relay386.c	2003-03-21 19:20:44.000000000 +0100
+++ relay32/relay386.c	2003-03-23 09:17:58.000000000 +0100
@@ -25,12 +25,12 @@
 #include <string.h>
 #include <stdio.h>
 
-#include "windef.h"
 #include "winternl.h"
 #include "stackframe.h"
 #include "module.h"
 #include "wine/unicode.h"
 #include "wine/debug.h"
+#include "ntdll_misc.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(relay);
 WINE_DECLARE_DEBUG_CHANNEL(snoop);
@@ -57,11 +57,11 @@
 
     while ((p = strchr( p, ';' )))
     {
-        count++;
+         count++;
         p++;
     }
     /* allocate count+1 pointers, plus the space for a copy of the string */
-    if ((ret = HeapAlloc( GetProcessHeap(), 0, (count+1) * sizeof(char*) + strlen(buffer) + 1 )))
+    if ((ret = RtlAllocateHeap( ntdll_get_process_heap(), 0, (count+1) * sizeof(char*) + strlen(buffer) + 1 )))
     {
         char *str = (char *)(ret + count + 1);
         char *p = str;
diff -u -x '*~' -x '.#*' relay3212/snoop.c relay32/snoop.c
--- relay3212/snoop.c	2003-03-21 19:20:44.000000000 +0100
+++ relay32/snoop.c	2003-03-23 09:17:35.000000000 +0100
@@ -24,14 +24,12 @@
 #include <assert.h>
 #include <stdio.h>
 #include <string.h>
-#include "winbase.h"
-#include "winnt.h"
 #include "winternl.h"
 #include "snoop.h"
-#include "stackframe.h"
 #include "wine/debug.h"
 #include "wine/exception.h"
 #include "excpt.h"
+#include "ntdll_misc.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(snoop);
 WINE_DECLARE_DEBUG_CHANNEL(seh);
@@ -143,6 +141,8 @@
 SNOOP_RegisterDLL(HMODULE hmod,LPCSTR name,DWORD ordbase,DWORD nrofordinals) {
 	SNOOP_DLL	**dll = &(firstdll);
 	char		*s;
+        void            *addr;
+        SIZE_T          size;
 
     TRACE("hmod=%p, name=%s, ordbase=%ld, nrofordinals=%ld\n",
 	   hmod, name, ordbase, nrofordinals);
@@ -152,25 +152,32 @@
 		if ((*dll)->hmod == hmod)
 		{
 		    /* another dll, loaded at the same address */
-		    VirtualFree((*dll)->funs, (*dll)->nrofordinals*sizeof(SNOOP_FUN), MEM_RELEASE);
+                    addr = (*dll)->funs;
+                    size = (*dll)->nrofordinals * sizeof(SNOOP_FUN);
+                    NtFreeVirtualMemory(GetCurrentProcess(), &addr, &size, MEM_RELEASE);
 		    break;
 		}
 		dll = &((*dll)->next);
 	}
-        *dll = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *dll, sizeof(SNOOP_DLL)+strlen(name));
+        *dll = RtlReAllocateHeap(ntdll_get_process_heap(),
+                                 HEAP_ZERO_MEMORY, *dll, 
+                                 sizeof(SNOOP_DLL) + strlen(name));
 	(*dll)->hmod	= hmod;
 	(*dll)->ordbase = ordbase;
 	(*dll)->nrofordinals = nrofordinals;
 	strcpy( (*dll)->name, name );
 	if ((s=strrchr((*dll)->name,'.')))
 		*s='\0';
-	(*dll)->funs = VirtualAlloc(NULL,nrofordinals*sizeof(SNOOP_FUN),MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
-	memset((*dll)->funs,0,nrofordinals*sizeof(SNOOP_FUN));
-	if (!(*dll)->funs) {
-		HeapFree(GetProcessHeap(),0,*dll);
+        size = nrofordinals * sizeof(SNOOP_FUN);
+        NtAllocateVirtualMemory(GetCurrentProcess(), &addr, NULL, &size, 
+                                MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+	if (!addr) {
+		RtlFreeHeap(ntdll_get_process_heap(),0,*dll);
 		FIXME("out of memory\n");
 		return;
 	}
+        (*dll)->funs = addr;
+	memset((*dll)->funs,0,size);
 }
 
 FARPROC
@@ -201,7 +208,7 @@
 	fun = dll->funs+ordinal;
 	if (!fun->name)
 	  {
-	    fun->name = HeapAlloc(GetProcessHeap(),0,strlen(name)+1);
+	    fun->name = RtlAllocateHeap(ntdll_get_process_heap(),0,strlen(name)+1);
 	    strcpy( fun->name, name );
 	    fun->lcall	= 0xe8;
 	    /* NOTE: origreturn struct member MUST come directly after snoopentry */
@@ -299,7 +306,14 @@
 		rets = &((*rets)->next);
 	}
 	if (!*rets) {
-		*rets = VirtualAlloc(NULL,4096,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
+                SIZE_T size = 4096;
+                VOID* addr;
+
+                NtAllocateVirtualMemory(GetCurrentProcess(), &addr, NULL, &size, 
+                                        MEM_COMMIT | MEM_RESERVE,
+                                        PAGE_EXECUTE_READWRITE);
+                if (!addr) return;
+                *rets = addr;
 		memset(*rets,0,4096);
 		i = 0;	/* entry 0 is free */
 	}
@@ -328,7 +342,8 @@
 			DPRINTF(" ...");
 	} else if (fun->nrofargs<0) {
 		DPRINTF("<unknown, check return>");
-		ret->args = HeapAlloc(GetProcessHeap(),0,16*sizeof(DWORD));
+		ret->args = RtlAllocateHeap(ntdll_get_process_heap(),
+                                            0,16*sizeof(DWORD));
 		memcpy(ret->args,(LPBYTE)(context->Esp + 4),sizeof(DWORD)*16);
 	}
 	DPRINTF(") ret=%08lx\n",(DWORD)ret->origreturn);
@@ -363,7 +378,7 @@
                 }
 		DPRINTF(") retval = %08lx ret=%08lx\n",
 			context->Eax,(DWORD)ret->origreturn );
-		HeapFree(GetProcessHeap(),0,ret->args);
+		RtlFreeHeap(ntdll_get_process_heap(),0,ret->args);
 		ret->args = NULL;
 	} else
 		DPRINTF("%04lx:RET  %s.%ld: %s() retval = %08lx ret=%08lx\n",


More information about the wine-patches mailing list