On Sat, Apr 26, 2008 at 1:53 PM, Steven Edwards <[EMAIL PROTECTED]> wrote:
>  >  * have start.exe set an environment variable saying "show graphical error 
> box
>  >  on dll load failure", and clear that before calling executed apps' 
> WinMain()
>  >  (easy)
>
>  So something like start.exe.so in Unix mode would set a variable like
>  VERSBOSE_USERDEBUG or which then we could query in the loader using
>  RtlQueryEnvironmentVariable_U or something that would trigger the
>  MessageBox from the example code I already wrote in ntdll?

So that worked. Comments are welcome!

-- 
Steven Edwards

"There is one thing stronger than all the armies in the world, and
that is an idea whose time has come." - Victor Hugo
From a15c236827afb6a29673ea71c0defcbfc329d466 Mon Sep 17 00:00:00 2001
From: Steven Edwards <[EMAIL PROTECTED]>
Date: Sun, 27 Apr 2008 06:35:36 -0400
Subject: [PATCH] Took a better stab at reporting when a dll is missing so
 users don't click on an application and have nothing happen

---
 dlls/ntdll/loader.c    |   53 ++++++++++++++++++++++++++++++++++++++++++++++++
 programs/start/start.c |    4 +++
 2 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index b0000b8..f5917e7 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -464,6 +464,52 @@ static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *
 
 }
 
+/*************************************************************************
+ *		report_error
+ *
+ * If we are called via start.exe.so from a Unix desktop then WINE_VERBOSE_DEBUG
+ * should be set to TRUE. This way users will not click on a desktop icon and
+ * have nothing happen if a required dll is missing.
+ * FIXME: Add dialog for a missing export for a given dll
+ * FIXME: Make the error dialog tell the user what dll is missing
+ */
+FARPROC pMessageBoxW;
+static NTSTATUS report_error()
+{
+    static WCHAR debug_name[] = {'W','I','N','E','_','V','E','R','B','O','S','E','_','D','E','B','U','G',0};
+    static WCHAR debug_value[] = {'T','R','U','E',0};
+    UNICODE_STRING us_name, us_value;
+    NTSTATUS nts0,nts1,nts2;
+
+    RtlInitUnicodeString( &us_name, debug_name );
+    RtlInitUnicodeString( &us_value, debug_value );
+    nts0 = RtlQueryEnvironmentVariable_U(NULL,&us_name,&us_value);
+
+    if (nts0 == STATUS_SUCCESS)
+    {
+        WCHAR user32[] = {'u','s','e','r','3','2','.','d','l','l',0};
+        UNICODE_STRING wstr;
+        ANSI_STRING str;
+        HMODULE hdll;
+
+        RtlInitUnicodeString( &wstr, user32 );
+        nts1 = LdrLoadDll(0, 0, &wstr, &hdll);
+        if (nts1 != STATUS_SUCCESS)
+        {
+            ERR("couldn't load user32 to display error\n");
+            return nts1;
+        }
+
+        RtlInitAnsiString( &str, "MessageBoxW" );
+        nts2 = LdrGetProcedureAddress( hdll, &str, 0, (void**)&pMessageBoxW );
+        if (nts2 != STATUS_SUCCESS)
+        {
+            ERR("Couldn't import MessageBoxW\n");
+            return nts2;
+        }
+    }
+    return nts0;
+}
 
 /*************************************************************************
  *		import_dll
@@ -514,8 +560,15 @@ static WINE_MODREF *import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *d
     if (status)
     {
         if (status == STATUS_DLL_NOT_FOUND)
+        {
+            WCHAR dll_error[] = {'A',' ','r','e','q','i','u','r','e','d',' ','d','l','l',' ','w','a','s',' ','n','o','t',' ','f','o','u','n','d',0};
+            NTSTATUS nts = report_error();
+            if (nts == STATUS_SUCCESS)
+                pMessageBoxW(NULL,dll_error,NULL,NULL);
+
             ERR("Library %s (which is needed by %s) not found\n",
                 name, debugstr_w(current_modref->ldr.FullDllName.Buffer));
+        }
         else
             ERR("Loading library %s (which is needed by %s) failed (error %x).\n",
                 name, debugstr_w(current_modref->ldr.FullDllName.Buffer), status);
diff --git a/programs/start/start.c b/programs/start/start.c
index c7a4ba4..a66e0ee 100644
--- a/programs/start/start.c
+++ b/programs/start/start.c
@@ -258,10 +258,14 @@ int wmain (int argc, WCHAR *argv[])
 	sei.lpParameters = args;
 
 	if (unix_mode) {
+                WCHAR debug_name[] = {'W','I','N','E','_','V','E','R','B','O','S','E','_','D','E','B','U','G',0};
+                WCHAR debug_value[] = {'T','R','U','E',0};
 		LPWSTR (*wine_get_dos_file_name_ptr)(LPCSTR);
 		char* multibyte_unixpath;
 		int multibyte_unixpath_len;
 
+                SetEnvironmentVariableW (debug_name, debug_value);
+
 		wine_get_dos_file_name_ptr = (void*)GetProcAddress(GetModuleHandle("KERNEL32"), "wine_get_dos_file_name");
 
 		if (!wine_get_dos_file_name_ptr)
-- 
1.5.3.7



Reply via email to