On Tue, Apr 29, 2008 at 1:28 PM, Peter Beutner <[EMAIL PROTECTED]> wrote:
>  And the msg box will pop up.

Your right. I see unless report_missing_dll_verbose is unset then its
going to spam on every dependent dll load failure for LoadLibrary.
Here is your and my patch combined.

Julliard: Can you comment please?

Thanks
-- 
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 dfe53258c683c449087928707c3aeebb93a2f4dd Mon Sep 17 00:00:00 2001
From: Steven Edwards <[EMAIL PROTECTED]>
Date: Sun, 27 Apr 2008 06:35:36 -0400
Subject: [PATCH] Graphically Report an error via a message box when
 an application is started from the Desktop environment.

Thanks to Peter Beutner <[EMAIL PROTECTED]>
for making the messagebox show something usable and
not reporting a error everytime a dependant library
called from LoadLibrary failed
---
 dlls/ntdll/loader.c    |   70 ++++++++++++++++++++++++++++++++++++++++++++++++
 programs/start/start.c |    4 +++
 2 files changed, 74 insertions(+), 0 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index b0000b8..677a146 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -24,6 +24,7 @@
 
 #include <assert.h>
 #include <stdarg.h>
+#include <stdio.h>
 #ifdef HAVE_SYS_MMAN_H
 # include <sys/mman.h>
 #endif
@@ -96,6 +97,7 @@ struct builtin_load_info
 static struct builtin_load_info default_load_info;
 static struct builtin_load_info *builtin_load_info = &default_load_info;
 
+static int report_missing_dll_verbose;      /* display msgbox if importing a dll fails */
 static HANDLE main_exe_file;
 static UINT tls_module_count;      /* number of modules with TLS directory */
 static UINT tls_total_size;        /* total size of TLS storage */
@@ -464,6 +466,68 @@ static FARPROC find_named_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *
 
 }
 
+/*************************************************************************
+ *		get_msgbox_func
+ *
+ * FIXME: We need to do something similar to this in exception.c
+ * so that a present dll with a missing export will also get a messaebox
+ */
+static FARPROC get_msgbox_func(void)
+{
+    WCHAR user32[] = {'u','s','e','r','3','2','.','d','l','l',0};
+    NTSTATUS status;
+    HMODULE hdll;
+    ANSI_STRING str;
+    UNICODE_STRING wstr;
+    FARPROC pMessageBoxA;
+
+    RtlInitUnicodeString( &wstr, user32 );
+    status = LdrLoadDll(0, 0, &wstr, &hdll);
+    if (status != STATUS_SUCCESS)
+        return NULL;
+
+    RtlInitAnsiString( &str, "MessageBoxA" );
+    status = LdrGetProcedureAddress( hdll, &str, 0, (void**)&pMessageBoxA );
+    if (status != STATUS_SUCCESS)
+        return NULL;
+
+    return pMessageBoxA;
+}
+
+
+/*************************************************************************
+ *		report_missing_dll
+ *
+ * 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.
+ */
+/* don't want to include winuser.h */
+#define MB_ICONERROR     0x00000010
+static void report_missing_dll(const char *dll, WCHAR* imported_by)
+{
+    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;
+    FARPROC pMessageBoxA;
+    char msg[MAX_PATH];
+    NTSTATUS nts0;
+
+    RtlInitUnicodeString( &us_name, debug_name );
+    RtlInitUnicodeString( &us_value, debug_value );
+    nts0 = RtlQueryEnvironmentVariable_U(NULL,&us_name,&us_value);
+
+    if (nts0 == STATUS_SUCCESS)
+    {
+        pMessageBoxA = get_msgbox_func();
+        if(report_missing_dll_verbose && pMessageBoxA) {
+            snprintf(msg, MAX_PATH, "Library %s (which is needed by %s) not found\n",
+                    dll,  debugstr_w(imported_by));
+            pMessageBoxA(NULL, msg, "Error: Failed to start application", MB_ICONERROR);
+        }
+    }
+}
+
 
 /*************************************************************************
  *		import_dll
@@ -514,8 +578,12 @@ static WINE_MODREF *import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *d
     if (status)
     {
         if (status == STATUS_DLL_NOT_FOUND)
+        {
             ERR("Library %s (which is needed by %s) not found\n",
                 name, debugstr_w(current_modref->ldr.FullDllName.Buffer));
+
+            report_missing_dll(name, 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);
@@ -2414,7 +2482,9 @@ void WINAPI LdrInitializeThunk( ULONG unknown1, ULONG unknown2, ULONG unknown3,
 
     actctx_init();
     load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
+    report_missing_dll_verbose = 1;
     if ((status = fixup_imports( wm, load_path )) != STATUS_SUCCESS) goto error;
+    report_missing_dll_verbose = 0;
     if ((status = alloc_process_tls()) != STATUS_SUCCESS) goto error;
     if ((status = alloc_thread_tls()) != STATUS_SUCCESS) goto error;
 
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