[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