[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-windows
Subject:    [PATCH] kdecore crashes LoadLibrary calls
From:       Patrick Spendrin <ps_ml () gmx ! de>
Date:       2009-03-25 9:23:21
Message-ID: 49C9F809.9050605 () gmx ! de
[Download RAW message or body]

Hi,

I have a small patch here which fixes a problem I recently got aware of:
if you try to make a regsvr32 kdecore.dll it will fail saying that
LoadLibrary was not achieved (simply try it). The correct error message
would have been a missing entrypoint for DllRegisterServer though.
After searching for quite a while I found the problem:
When you load kdecore linked to an executable, the image will be located
at the address 0x0040000. When you load kdecore directly via regsvr32,
the image will have the address 0x10000000 (0x1 0x0) instead.
When trying to read from the first one then you will obviously get a
"crash". As I am unable to find out where our image is (this is the
address of the HINSTANCE parameter in the DllMain) as the constructor of
the static class will be called before running the DllMain, I have now
changed it so that the code will be called from the DllMain with the
parameter.

As this patch might change the behaviour of your debug output, please
check if it works for you | comment it.

regards,
Patrick

-- 
web:                 http://windows.kde.org
mailing list:        kde-windows@kde.org
irc:                 #kde-windows (irc.freenode.net)

["0151-kdecore-loadLibraryProof.diff" (text/x-patch)]

Index: kdecore/kernel/kkernel_win.cpp
===================================================================
--- kdecore/kernel/kkernel_win.cpp	(revision 942889)
+++ kdecore/kernel/kkernel_win.cpp	(working copy)
@@ -90,6 +90,70 @@
   return kde4Prefix ? *kde4Prefix : QString::fromUtf16((ushort*) kde4prefixUtf16);
 }
 
+#include <streambuf>
+
+/** 
+  ios related debug message printer for win32
+*/
+class debug_streambuf: public std::streambuf
+{
+    public:
+        debug_streambuf(char *prefix)
+        {
+            strcpy(buf,prefix);
+            index = rindex = strlen(buf);
+        }
+
+    protected:
+        virtual int overflow(int c = EOF)
+        {
+            if (c != EOF)
+            {
+                char cc = traits_type::to_char_type(c);
+                // @TODO: buffer size checking
+                buf[index++] = cc;
+                if (cc == '\n')
+                {
+                    buf[index] = '\0';
+                    OutputDebugStringA((LPCSTR)buf);
+                    index = rindex;
+                }
+            }
+            return traits_type::not_eof(c);
+        }
+    private:
+        char buf[4096];
+        int index, rindex;
+};
+
+static class kMessageOutputInstaller {
+    public:
+        kMessageOutputInstaller() 
+            : stdoutBuffer("stdout:")
+            , stderrBuffer("stderr:")
+            , oldStdoutBuffer(0)
+            , oldStderrBuffer(0)
+        {
+        }
+
+        ~kMessageOutputInstaller()
+        {
+            if (oldStdoutBuffer) 
+                std::cout.rdbuf(oldStdoutBuffer);
+            if (oldStderrBuffer) 
+                std::cerr.rdbuf(oldStderrBuffer);
+        }
+    
+        void registerHandler(HINSTANCE hInst);
+
+    private:
+        debug_streambuf stdoutBuffer;
+        debug_streambuf stderrBuffer;
+        std::streambuf* oldStdoutBuffer;
+        std::streambuf* oldStderrBuffer;
+
+} kMessageOutputInstallerInstance;
+
 /**
  * The dll entry point - get the instance handle for GetModuleFleNameW
  * Maybe also some special initialization / cleanup can be done here
@@ -99,6 +163,7 @@
 {
     switch ( fdwReason ) {
     case DLL_PROCESS_ATTACH:
+        kMessageOutputInstallerInstance.registerHandler(hinstDLL);
         kdecoreDllInstance = hinstDLL;
         initKde4prefixUtf16();
         kde4Prefix = new QString( QString::fromUtf16((ushort*) kde4prefixUtf16) );
@@ -302,53 +367,17 @@
     ios::sync_with_stdio();
 }
 
-#include <streambuf>
-
-/** 
-  ios related debug message printer for win32
-*/
-class debug_streambuf: public std::streambuf
-{
-    public:
-        debug_streambuf(char *prefix)
-        {
-            strcpy(buf,prefix);
-            index = rindex = strlen(buf);
-        }
-
-    protected:
-        virtual int overflow(int c = EOF)
-        {
-            if (c != EOF)
-            {
-                char cc = traits_type::to_char_type(c);
-                // @TODO: buffer size checking
-                buf[index++] = cc;
-                if (cc == '\n')
-                {
-                    buf[index] = '\0';
-                    OutputDebugStringA((LPCSTR)buf);
-                    index = rindex;
-                }
-            }
-            return traits_type::not_eof(c);
-        }
-    private:
-        char buf[4096];
-        int index, rindex;
-};
-
 /**
   retrieve type of win32 subsystem from the executable header 
   \return type of win32 subsystem - the subsystem types are defined at \
                http://msdn.microsoft.com/en-us/library/ms680339(VS.85).aspx 
 */
-static int subSystem()
+static int subSystem(HINSTANCE hInst)
 {
     static int subSystem = -1;
     if (subSystem > -1)
         return subSystem; 
 
-    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)0x00400000;
+    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hInst;
     PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS) ((char *)dosHeader + \
dosHeader->e_lfanew);  if (ntHeader->Signature != 0x00004550) 
     {
@@ -385,59 +414,41 @@
 /**
  setup up debug output 
 */ 
-static class kMessageOutputInstaller {
-    public:
-        kMessageOutputInstaller() : stdoutBuffer("stdout:"), \
                stderrBuffer("stderr:"), oldStdoutBuffer(0), oldStderrBuffer(0)
-        {
-            if (subSystem() == IMAGE_SUBSYSTEM_WINDOWS_CUI) {
-                if (attachToConsole()) {
-                    // setup kde and qt level 
-                    qInstallMsgHandler(kMessageOutputFileIO);
-                    // redirect ios and file io to console
-                    redirectToConsole();
-                }
-                else {
-                    // setup kde and qt level 
-                    qInstallMsgHandler(kMessageOutputDebugString);
-                    // redirect ios to debug message port 
-                    oldStdoutBuffer = std::cout.rdbuf(&stdoutBuffer);
-                    oldStderrBuffer = std::cerr.rdbuf(&stderrBuffer);
-                }
-            }
-            else if (subSystem() == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
-                // setup kde and qt level 
-                qInstallMsgHandler(kMessageOutputDebugString);
-                // try to get a console
-                if (attachToConsole()) {
-                    redirectToConsole();
-                }
-                else {
-                    // redirect ios to debug message port
-                    oldStdoutBuffer = std::cout.rdbuf(&stdoutBuffer);
-                    oldStderrBuffer = std::cerr.rdbuf(&stderrBuffer);
-                    // TODO: redirect FILE * level to console, no idea how to do yet
-                }
-            }
-            else
-                qWarning("unknown subsystem %d detected, could not setup qt message \
handler",subSystem()); +void kMessageOutputInstaller::registerHandler(HINSTANCE \
hInst) +{
+    if (subSystem(hInst) == IMAGE_SUBSYSTEM_WINDOWS_CUI) {
+        if (attachToConsole()) {
+            // setup kde and qt level 
+            qInstallMsgHandler(kMessageOutputFileIO);
+            // redirect ios and file io to console
+            redirectToConsole();
         }
-        ~kMessageOutputInstaller()
-        {
-            if (oldStdoutBuffer) 
-                std::cout.rdbuf(oldStdoutBuffer);
-            if (oldStderrBuffer) 
-                std::cerr.rdbuf(oldStderrBuffer);
+        else {
+            // setup kde and qt level 
+            qInstallMsgHandler(kMessageOutputDebugString);
+            // redirect ios to debug message port 
+            oldStdoutBuffer = std::cout.rdbuf(&stdoutBuffer);
+            oldStderrBuffer = std::cerr.rdbuf(&stderrBuffer);
         }
-    
-    private:
-        debug_streambuf stdoutBuffer;
-        debug_streambuf stderrBuffer;
-        std::streambuf* oldStdoutBuffer;
-        std::streambuf* oldStderrBuffer;
+    }
+    else if (subSystem(hInst) == IMAGE_SUBSYSTEM_WINDOWS_GUI) {
+        // setup kde and qt level 
+        qInstallMsgHandler(kMessageOutputDebugString);
+        // try to get a console
+        if (attachToConsole()) {
+            redirectToConsole();
+        }
+        else {
+            // redirect ios to debug message port
+            oldStdoutBuffer = std::cout.rdbuf(&stdoutBuffer);
+            oldStderrBuffer = std::cerr.rdbuf(&stderrBuffer);
+            // TODO: redirect FILE * level to console, no idea how to do yet
+        }
+    }
+    else
+        qWarning("unknown subsystem %d detected, could not setup qt message \
handler",subSystem(hInst)); +}
 
-} kMessageOutputInstallerInstance;
-
-
 bool isExecutable(const QString &file)
 {
   return ( file.endsWith( QLatin1String( ".exe" ) ) ||



_______________________________________________
Kde-windows mailing list
Kde-windows@kde.org
https://mail.kde.org/mailman/listinfo/kde-windows


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic