[PATCH] localspl: Call DrvDriverEvent DRIVER_EVENT_INITIALIZE in AddPrinterDriverEx

Detlef Riekenberg wine.dev at web.de
Sun Dec 28 15:21:40 CST 2008


---
 dlls/localspl/localspl_main.c |  154 +++++++++++++++++++++++++++++++++++++++--
 1 files changed, 149 insertions(+), 5 deletions(-)

diff --git a/dlls/localspl/localspl_main.c b/dlls/localspl/localspl_main.c
index 4483ac8..80295c5 100644
--- a/dlls/localspl/localspl_main.c
+++ b/dlls/localspl/localspl_main.c
@@ -28,8 +28,9 @@
 #include "wingdi.h"
 #include "winreg.h"
 #include "winspool.h"
-#include "ddk/winsplp.h"
 #include "winuser.h"
+#include "ddk/winddiui.h"
+#include "ddk/winsplp.h"
 
 #include "wine/list.h"
 #include "wine/debug.h"
@@ -40,6 +41,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(localspl);
 
 /* ############################### */
 
+static CRITICAL_SECTION driver_handles_cs;
+static CRITICAL_SECTION_DEBUG driver_handles_cs_debug =
+{
+    0, 0, &driver_handles_cs,
+    { &driver_handles_cs_debug.ProcessLocksList, &driver_handles_cs_debug.ProcessLocksList },
+      0, 0, { (DWORD_PTR)(__FILE__ ": driver_handles_cs") }
+};
+static CRITICAL_SECTION driver_handles_cs = { &driver_handles_cs_debug, -1, 0, 0, 0, 0 };
+
 static CRITICAL_SECTION monitor_handles_cs;
 static CRITICAL_SECTION_DEBUG monitor_handles_cs_debug =
 {
@@ -61,6 +71,15 @@ typedef struct {
 } apd_data_t;
 
 typedef struct {
+    struct list entry;
+    LPWSTR      name;
+    LPWSTR      dllname;
+    HMODULE     hdll;
+    DWORD       refcount;
+    BOOL        (WINAPI *pDrvDriverEvent)(DWORD, DWORD, LPBYTE, LPARAM);
+} driver_t;
+
+typedef struct {
     struct list     entry;
     LPWSTR          name;
     LPWSTR          dllname;
@@ -80,8 +99,11 @@ typedef struct {
 } printenv_t;
 
 
+static BOOL WINAPI fpGetPrinterDriverDirectory(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD);
+
 /* ############################### */
 
+static struct list driver_handles = LIST_INIT( driver_handles );
 static struct list monitor_handles = LIST_INIT( monitor_handles );
 static monitor_t * pm_localport;
 
@@ -271,6 +293,119 @@ static LONG copy_servername_from_name(LPCWSTR name, LPWSTR target)
 }
 
 /******************************************************************
+ * driver_unload [internal]
+ *
+ * release a driver and unload it from memory, when needed
+ *
+ */
+static void driver_unload(driver_t * pdrv)
+{
+    if (pdrv == NULL) return;
+    TRACE("%p (refcount: %d) %s\n", pdrv, pdrv->refcount, debugstr_w(pdrv->name));
+
+    EnterCriticalSection(&driver_handles_cs);
+
+    if (pdrv->refcount) pdrv->refcount--;
+
+    if (pdrv->refcount == 0) {
+        list_remove(&pdrv->entry);
+        FreeLibrary(pdrv->hdll);
+        heap_free(pdrv->name);
+        heap_free(pdrv->dllname);
+        heap_free(pdrv);
+    }
+    LeaveCriticalSection(&driver_handles_cs);
+}
+
+/******************************************************************
+ * driver_load [internal]
+ *
+ * load a driver and dump found function-pointers
+ *
+ * On failure, SetLastError() is called and NULL is returned
+ *
+ */
+
+static driver_t * driver_load(const printenv_t * env, LPCWSTR name, LPWSTR dllname)
+{
+    WCHAR fullname[MAX_PATH+MAX_PATH];
+    driver_t * pdrv = NULL;
+    driver_t * cursor;
+    LPWSTR  driver = dllname;
+    DWORD len;    
+
+    TRACE("(%s, %s)\n", debugstr_w(name), debugstr_w(dllname));
+    /* Is the Driver already loaded? */
+    EnterCriticalSection(&driver_handles_cs);
+
+    if (name) {
+        LIST_FOR_EACH_ENTRY(cursor, &driver_handles, driver_t, entry)
+        {
+            if (cursor->name && (lstrcmpW(name, cursor->name) == 0)) {
+                pdrv = cursor;
+                break;
+            }
+        }
+    }
+
+    if (pdrv == NULL) {
+        pdrv = heap_alloc_zero(sizeof(driver_t));
+        if (pdrv == NULL) goto cleanup;
+        list_add_tail(&driver_handles, &pdrv->entry);
+    }
+    pdrv->refcount++;
+
+    if (pdrv->dllname == NULL) {
+        /* Load the driver */
+
+        /* ToDo: Get the driver dll from reg, when needed */ 
+        pdrv->name = strdupW(name);
+        pdrv->dllname = strdupW(driver);
+
+        if (!pdrv->dllname) {
+            driver_unload(pdrv);
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            pdrv = NULL;
+            goto cleanup;
+        }
+
+        /* build the driverdir */
+        len = sizeof(fullname) - sizeof(version3_subdirW) - sizeof(WCHAR);
+        if (!fpGetPrinterDriverDirectory(NULL, (LPWSTR) env->envname, 1,
+                                        (LPBYTE) fullname, len, &len)) {
+            /* Should never Fail */
+            driver_unload(pdrv);
+            SetLastError(ERROR_PATH_NOT_FOUND);
+            pdrv = NULL;
+            goto cleanup;
+        }
+
+        lstrcatW(fullname, env->versionsubdir);
+        lstrcatW(fullname, backslashW);
+        lstrcatW(fullname, driver);
+    
+        pdrv->hdll = LoadLibraryW(fullname);
+        TRACE("%p: LoadLibrary(%s) => %d\n", pdrv->hdll, debugstr_w(fullname), GetLastError());
+
+        if (pdrv->hdll == NULL) {
+            driver_unload(pdrv);
+            SetLastError(ERROR_MOD_NOT_FOUND);
+            pdrv = NULL;
+            goto cleanup;
+        }
+
+        pdrv->pDrvDriverEvent = (void *)GetProcAddress(pdrv->hdll, "DrvDriverEvent");
+        TRACE("%p: DrvDriverEvent\n", pdrv->pDrvDriverEvent);
+    }
+
+cleanup:
+    LeaveCriticalSection(&driver_handles_cs);
+    if (driver != dllname) heap_free(driver);
+    TRACE("=> %p\n", pdrv);
+    return pdrv;
+}
+
+/******************************************************************
  * monitor_unload [internal]
  *
  * release a printmonitor and unload it from memory, when needed
@@ -294,7 +429,6 @@ static void monitor_unload(monitor_t * pm)
     }
     LeaveCriticalSection(&monitor_handles_cs);
 }
-
 /******************************************************************
  * monitor_load [internal]
  *
@@ -735,6 +869,8 @@ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCo
     const printenv_t *env;
     apd_data_t apd;
     DRIVER_INFO_8W di;
+    driver_t *pui;
+    BOOL    res = TRUE;
     LPWSTR  ptr;
     HKEY    hroot;
     HKEY    hdrv;
@@ -873,10 +1009,18 @@ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCo
     if (level > 5) TRACE("level %u for Driver %s is incomplete\n", level, debugstr_w(di.pName));
 
     RegCloseKey(hdrv);
-    TRACE("### DrvDriverEvent(...,DRIVEREVENT_INITIALIZE) not implemented yet\n");
+    pui = driver_load(env, di.pName, di.pConfigFile);
+    if (pui && pui->pDrvDriverEvent) {
+        /* Support for DrvDriverEvent is optional */
+        TRACE("DRIVER_EVENT_INITIALIZE for %s (%s)\n", debugstr_w(di.pName), debugstr_w(di.pConfigFile));
+        /* MSDN: level for DRIVER_INFO is 1 to 3 */
+        res = pui->pDrvDriverEvent(DRIVER_EVENT_INITIALIZE, 3, (LPBYTE) &di, 0);
+        TRACE("got %d from DRIVER_EVENT_INITIALIZE\n", res);
+    }
+    driver_unload(pui);
 
-    TRACE("=> TRUE with %u\n", GetLastError());
-    return TRUE;
+    TRACE("=> %d with %u\n", (lazy) ? TRUE : res, GetLastError());
+    return (lazy) ? TRUE : res;
 
 }
 
-- 
1.5.4.3


--=-9HKLp7cdK6QpY/8PNHb3--




More information about the wine-patches mailing list