Detlef Riekenberg : winspool: Implement AddMonitor.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Apr 12 04:52:10 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: ed1161f993ecfba6bdb3e7f89667b0ea0cb95c77
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=ed1161f993ecfba6bdb3e7f89667b0ea0cb95c77

Author: Detlef Riekenberg <wine.dev at web.de>
Date:   Tue Apr 11 20:42:18 2006 +0200

winspool: Implement AddMonitor.

---

 dlls/winspool/info.c |  141 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 132 insertions(+), 9 deletions(-)

diff --git a/dlls/winspool/info.c b/dlls/winspool/info.c
index 124970b..c33072b 100644
--- a/dlls/winspool/info.c
+++ b/dlls/winspool/info.c
@@ -1318,9 +1318,59 @@ BOOL WINAPI OpenPrinterW(LPWSTR lpPrinte
  */
 BOOL WINAPI AddMonitorA(LPSTR pName, DWORD Level, LPBYTE pMonitors)
 {
-    FIXME("(%s,0x%08lx,%p), stub!\n", debugstr_a(pName), Level, pMonitors);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    LPWSTR  nameW = NULL;
+    INT     len;
+    BOOL    res;
+    LPMONITOR_INFO_2A mi2a;
+    MONITOR_INFO_2W mi2w;
+
+    mi2a = (LPMONITOR_INFO_2A) pMonitors;
+    TRACE("(%s, %ld, %p) :  %s %s %s\n", debugstr_a(pName), Level, pMonitors, 
+            mi2a ? debugstr_a(mi2a->pName) : NULL,
+            mi2a ? debugstr_a(mi2a->pEnvironment) : NULL,
+            mi2a ? debugstr_a(mi2a->pDLLName) : NULL);
+
+    if  (Level != 2) {
+        SetLastError(ERROR_INVALID_LEVEL);
+        return FALSE;
+    }
+
+    /* XP: unchanged, win9x: ERROR_INVALID_ENVIRONMENT */
+    if (mi2a == NULL) {
+        return FALSE;
+    }
+
+    if (pName) {
+        len = MultiByteToWideChar(CP_ACP, 0, pName, -1, NULL, 0);
+        nameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        MultiByteToWideChar(CP_ACP, 0, pName, -1, nameW, len);
+    }
+
+    memset(&mi2w, 0, sizeof(MONITOR_INFO_2W));
+    if (mi2a->pName) {
+        len = MultiByteToWideChar(CP_ACP, 0, mi2a->pName, -1, NULL, 0);
+        mi2w.pName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        MultiByteToWideChar(CP_ACP, 0, mi2a->pName, -1, mi2w.pName, len);
+    }
+    if (mi2a->pEnvironment) {
+        len = MultiByteToWideChar(CP_ACP, 0, mi2a->pEnvironment, -1, NULL, 0);
+        mi2w.pEnvironment = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        MultiByteToWideChar(CP_ACP, 0, mi2a->pEnvironment, -1, mi2w.pEnvironment, len);
+    }
+    if (mi2a->pDLLName) {
+        len = MultiByteToWideChar(CP_ACP, 0, mi2a->pDLLName, -1, NULL, 0);
+        mi2w.pDLLName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        MultiByteToWideChar(CP_ACP, 0, mi2a->pDLLName, -1, mi2w.pDLLName, len);
+    }
+
+    res = AddMonitorW(nameW, Level, (LPBYTE) &mi2w);
+
+    HeapFree(GetProcessHeap(), 0, mi2w.pName); 
+    HeapFree(GetProcessHeap(), 0, mi2w.pEnvironment); 
+    HeapFree(GetProcessHeap(), 0, mi2w.pDLLName); 
+
+    HeapFree(GetProcessHeap(), 0, nameW); 
+    return (res);
 }
 
 /******************************************************************************
@@ -1340,15 +1390,88 @@ BOOL WINAPI AddMonitorA(LPSTR pName, DWO
  * NOTES
  *  All Files for the Monitor must already be copied to %winsysdir% ("%SystemRoot%\system32")
  *
- * BUGS
- *  only a Stub
- *
  */
 BOOL WINAPI AddMonitorW(LPWSTR pName, DWORD Level, LPBYTE pMonitors)
 {
-    FIXME("(%s,0x%08lx,%p), stub!\n",debugstr_w(pName), Level, pMonitors);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    LPMONITOR_INFO_2W mi2w;
+    HKEY    hroot = NULL;
+    HKEY    hentry = NULL;
+    HMODULE hdll = NULL;
+    DWORD   disposition;
+    BOOL    res = FALSE;
+
+    mi2w = (LPMONITOR_INFO_2W) pMonitors;
+    TRACE("(%s, %ld, %p) :  %s %s %s\n", debugstr_w(pName), Level, pMonitors, 
+            mi2w ? debugstr_w(mi2w->pName) : NULL,
+            mi2w ? debugstr_w(mi2w->pEnvironment) : NULL,
+            mi2w ? debugstr_w(mi2w->pDLLName) : NULL);
+
+    if (Level != 2) {
+        SetLastError(ERROR_INVALID_LEVEL);
+        return FALSE;
+    }
+
+    /* XP: unchanged, win9x: ERROR_INVALID_ENVIRONMENT */
+    if (mi2w == NULL) {
+        return FALSE;
+    }
+
+    if (pName && (pName[0])) {
+        FIXME("for server %s not implemented\n", debugstr_w(pName));
+        SetLastError(ERROR_ACCESS_DENIED);
+        return FALSE;
+    }
+
+
+    if (!mi2w->pName || (! mi2w->pName[0])) {
+        WARN("pName not valid : %s \n", debugstr_w(mi2w->pName));
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+    if (!mi2w->pEnvironment || lstrcmpW(mi2w->pEnvironment, envname_x86W)) {
+        WARN("Environment %s requested (we support only %s)\n", 
+                debugstr_w(mi2w->pEnvironment), debugstr_w(envname_x86W));
+        SetLastError(ERROR_INVALID_ENVIRONMENT);
+        return FALSE;
+    }
+
+    if (!mi2w->pDLLName || (! mi2w->pDLLName[0])) {
+        WARN("pDLLName not valid : %s \n", debugstr_w(mi2w->pDLLName));
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    if ((hdll = LoadLibraryW(mi2w->pDLLName)) == NULL) {
+        return FALSE;
+    }
+    FreeLibrary(hdll);
+
+    if(RegCreateKeyW(HKEY_LOCAL_MACHINE, MonitorsW, &hroot) != ERROR_SUCCESS) {
+        ERR("unable to create key %s\n", debugstr_w(MonitorsW));
+        return FALSE;
+    }
+
+    if(RegCreateKeyExW(hroot, mi2w->pName, 0, NULL, REG_OPTION_NON_VOLATILE,
+                 KEY_WRITE, NULL, &hentry, &disposition) == ERROR_SUCCESS) {
+
+        if (disposition == REG_OPENED_EXISTING_KEY) {
+            TRACE("monitor %s already exists\n", debugstr_w(mi2w->pName));
+            /* NT: ERROR_PRINT_MONITOR_ALREADY_INSTALLED (3006)
+               9x: ERROR_ALREADY_EXISTS (183) */
+            SetLastError(ERROR_PRINT_MONITOR_ALREADY_INSTALLED);
+        }
+        else
+        {
+               INT len;
+               len = (lstrlenW(mi2w->pDLLName) +1) * sizeof(WCHAR);
+               res = (RegSetValueExW(hentry, DriverW, 0,
+                      REG_SZ, (LPBYTE) mi2w->pDLLName, len) == ERROR_SUCCESS);
+        }
+        RegCloseKey(hentry);
+    }
+
+    RegCloseKey(hroot);
+    return (res);
 }
 
 /******************************************************************




More information about the wine-cvs mailing list