[PATCH 2/2] winspool+localspl: Move AddPrinterW implementation to localspl

Detlef Riekenberg wine.dev at web.de
Mon Dec 5 12:44:11 CST 2016


We need to move AddPrinter to allow importing CUPS printers
centralized in the spooler service.
 (bug 3507, bug 10358)

localspl will be used from the application (through winspool.drv)
and from the spooler service (through spoolss.dll)

--
bye bye ... Detlef

Signed-off-by: Detlef Riekenberg <wine.dev at web.de>
---
 dlls/localspl/provider.c | 353 ++++++++++++++++++++++++++++++++++++++++++++++-
 dlls/winspool.drv/info.c | 181 +++---------------------
 2 files changed, 373 insertions(+), 161 deletions(-)

diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c
index f359b73..9b12c63 100644
--- a/dlls/localspl/provider.c
+++ b/dlls/localspl/provider.c
@@ -93,13 +93,22 @@ static monitor_t * pm_localport;
 
 static const PRINTPROVIDOR * pprovider = NULL;
 
+static const WCHAR attributesW[] = {'A','t','t','r','i','b','u','t','e','s',0};
 static const WCHAR backslashW[] = {'\\',0};
 static const WCHAR bs_ports_bsW[] = {'\\','P','o','r','t','s','\\',0};
+static const WCHAR commaW[] = {',',0};
 static const WCHAR configuration_fileW[] = {'C','o','n','f','i','g','u','r','a','t','i','o','n',' ','F','i','l','e',0};
 static const WCHAR datatypeW[] = {'D','a','t','a','t','y','p','e',0};
 static const WCHAR data_fileW[] = {'D','a','t','a',' ','F','i','l','e',0};
+static const WCHAR default_devmodeW[] = {'D','e','f','a','u','l','t',' ','D','e','v','M','o','d','e',0}; //
+static const WCHAR default_priorityW[] = {'D','e','f','a','u','l','t',' ','P','r','i','o','r','i','t','y',0};
 static const WCHAR dependent_filesW[] = {'D','e','p','e','n','d','e','n','t',' ','F','i','l','e','s',0};
+static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
+static const WCHAR devicesW[] = {'d','e','v','i','c','e','s',0};
+static const WCHAR dnstimeoutW[] = {'d','n','s','T','i','m','e','o','u','t',0};
+static const WCHAR driver_nt[] = {'w','i','n','e','p','s','.','d','r','v',0};
 static const WCHAR driverW[] = {'D','r','i','v','e','r',0};
+static const WCHAR driversW[] = {'\\','d','r','i','v','e','r','s','\\',0};
 static const WCHAR emptyW[] = {0};
 static const WCHAR fmt_driversW[] = { 'S','y','s','t','e','m','\\',
                                   'C','u', 'r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
@@ -117,6 +126,7 @@ static const WCHAR help_fileW[] = {'H','e','l','p',' ','F','i','l','e',0};
 static const WCHAR ia64_envnameW[] = {'W','i','n','d','o','w','s',' ','I','A','6','4',0};
 static const WCHAR ia64_subdirW[] = {'i','a','6','4',0};
 static const WCHAR localportW[] = {'L','o','c','a','l',' ','P','o','r','t',0};
+static const WCHAR locationW[] = {'L','o','c','a','t','i','o','n',0};
 static const WCHAR monitorW[] = {'M','o','n','i','t','o','r',0};
 static const WCHAR monitorsW[] = {'S','y','s','t','e','m','\\',
                                 'C','u', 'r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
@@ -124,15 +134,29 @@ static const WCHAR monitorsW[] = {'S','y','s','t','e','m','\\',
                                 'P','r','i','n','t','\\',
                                 'M','o','n','i','t','o','r','s','\\',0};
 static const WCHAR monitorUIW[] = {'M','o','n','i','t','o','r','U','I',0};
+static const WCHAR nameW[] = {'N','a','m','e',0};
+static const WCHAR parametersW[] = {'P','a','r','a','m','e','t','e','r','s',0};
+static const WCHAR portW[] = {'P','o','r','t',0};
 static const WCHAR previous_namesW[] = {'P','r','e','v','i','o','u','s',' ','N','a','m','e','s',0};
+static const WCHAR print_processorW[] = {'P','r','i','n','t',' ','P','r','o','c','e','s','s','o','r',0};
+static const WCHAR printerportsW[] = {'P','r','i','n','t','e','r','P','o','r','t','s',0};
 static const WCHAR printersW[] = {'S','y','s','t','e','m','\\',
                                   'C','u', 'r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
                                   'C','o','n','t','r','o','l','\\',
                                   'P','r','i','n','t','\\',
                                   'P','r','i','n','t','e','r','s',0};
-static const WCHAR spoolW[] = {'\\','s','p','o','o','l',0};
-static const WCHAR driversW[] = {'\\','d','r','i','v','e','r','s','\\',0};
+static const WCHAR printer_driverW[] = {'P','r','i','n','t','e','r',' ','D','r','i','v','e','r',0};
+static const WCHAR priorityW[] = {'P','r','i','o','r','i','t','y',0};
+static const WCHAR providerW[] = {'P','r','o','v','i','d','e','r',0};
+static const WCHAR separator_fileW[] = {'S','e','p','a','r','a','t','o','r',' ','F','i','l','e',0};
+static const WCHAR share_nameW[] = {'S','h','a','r','e',' ','N','a','m','e',0};
 static const WCHAR spoolprtprocsW[] = {'\\','s','p','o','o','l','\\','p','r','t','p','r','o','c','s','\\',0};
+static const WCHAR spoolW[] = {'\\','s','p','o','o','l',0};
+static const WCHAR starttimeW[] = {'S','t','a','r','t','T','i','m','e',0};
+static const WCHAR statusW[] = {'S','t','a','t','u','s',0};
+static const WCHAR timeout_15_45[] = {',','1','5',',','4','5',0};
+static const WCHAR txtimeoutW[] = {'t','x','T','i','m','e','o','u','t',0};
+static const WCHAR untiltimeW[] = {'U','n','t','i','l','T','i','m','e',0};
 static const WCHAR version0_regpathW[] = {'\\','V','e','r','s','i','o','n','-','0',0};
 static const WCHAR version0_subdirW[] = {'\\','0',0};
 static const WCHAR version3_regpathW[] = {'\\','V','e','r','s','i','o','n','-','3',0};
@@ -140,12 +164,23 @@ static const WCHAR version3_subdirW[] = {'\\','3',0};
 static const WCHAR versionW[] = {'V','e','r','s','i','o','n',0};
 static const WCHAR win40_envnameW[] = {'W','i','n','d','o','w','s',' ','4','.','0',0};
 static const WCHAR win40_subdirW[] = {'w','i','n','4','0',0};
+static const WCHAR winnt_cv_devicesW[] = {'S','o','f','t','w','a','r','e','\\',
+                                          'M','i','c','r','o','s','o','f','t','\\',
+                                          'W','i','n','d','o','w','s',' ','N','T','\\',
+                                          'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+                                          'D','e','v','i','c','e','s',0};
 static const WCHAR winnt_cv_portsW[] = {'S','o','f','t','w','a','r','e','\\',
                                         'M','i','c','r','o','s','o','f','t','\\',
                                         'W','i','n','d','o','w','s',' ','N','T','\\',
                                         'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
                                         'P','o','r','t','s',0};
+static const WCHAR winnt_cv_printerportsW[] = {'S','o','f','t','w','a','r','e','\\',
+                                               'M','i','c','r','o','s','o','f','t','\\',
+                                               'W','i','n','d','o','w','s',' ','N','T','\\',
+                                               'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+                                               'P','r','i','n','t','e','r','P','o','r','t','s',0};
 static const WCHAR winprintW[] = {'w','i','n','p','r','i','n','t',0};
+static const WCHAR winspooldrvW[] = {'w','i','n','s','p','o','o','l','.','d','r','v',0};
 static const WCHAR x64_envnameW[] = {'W','i','n','d','o','w','s',' ','x','6','4',0};
 static const WCHAR x64_subdirW[] = {'x','6','4',0};
 static const WCHAR x86_envnameW[] = {'W','i','n','d','o','w','s',' ','N','T',' ','x','8','6',0};
@@ -176,6 +211,50 @@ static const DWORD di_sizeof[] = {0, sizeof(DRIVER_INFO_1W), sizeof(DRIVER_INFO_
 
 
 /******************************************************************
+ * set_reg_DWORD [internal]
+ *
+ * Save a DWORD in the registry
+ *
+ */
+static inline DWORD set_reg_DWORD( HKEY hkey, const WCHAR *keyname, const DWORD value )
+{
+    return RegSetValueExW( hkey, keyname, 0, REG_DWORD, (const BYTE*)&value, sizeof(value) );
+}
+
+/******************************************************************
+ * set_reg_szW [internal]
+ *
+ * Save a WSTR to the registry
+ *
+ */
+static inline DWORD set_reg_szW(HKEY hkey, const WCHAR *keyname, const WCHAR *value)
+{
+    if (value)
+        return RegSetValueExW(hkey, keyname, 0, REG_SZ, (const BYTE*)value,
+                              (lstrlenW(value) + 1) * sizeof(WCHAR));
+    else
+        return ERROR_FILE_NOT_FOUND;
+}
+
+/******************************************************************
+ * set_reg_devmode [internal]
+ *
+ * Save a DEVNODEW in the registry
+ *
+ */
+static inline DWORD set_reg_devmode( HKEY key, const WCHAR *name, const DEVMODEW *dm )
+{
+    if (dm)
+    {
+        return RegSetValueExW( key, name, 0, REG_BINARY,
+                              (LPBYTE)dm, dm->dmSize + dm->dmDriverExtra );
+    }
+    else
+        return ERROR_FILE_NOT_FOUND;
+}
+
+
+/******************************************************************
  * strdupW [internal]
  *
  * create a copy of a unicode-string
@@ -1675,6 +1754,274 @@ static BOOL WINAPI fpAddPortEx(LPWSTR pName, DWORD level, LPBYTE pBuffer, LPWSTR
     return res;
 }
 
+/*****************************************************************************
+ * localspl_OpenDriverReg [internal]
+ *
+ * opens the registry for the printer drivers depending on the given input
+ * variable pEnvironment
+ *
+ * RETURNS:
+ *    the opened hkey on success
+ *    NULL on error
+ */
+static HKEY localspl_OpenDriverReg(LPCWSTR pEnvironment)
+{
+    HKEY retval = NULL;
+    LPWSTR buffer;
+    const printenv_t * env;
+
+    TRACE("(%s)\n", debugstr_w(pEnvironment));
+
+    env = validate_envW(pEnvironment);
+    if (!env) return NULL;
+
+    buffer = heap_alloc((strlenW(fmt_driversW) + strlenW(env->envname) + strlenW(env->versionregpath) + 1) * sizeof(WCHAR));
+
+    if(buffer) {
+        wsprintfW(buffer, fmt_driversW, env->envname, env->versionregpath);
+        RegCreateKeyW(HKEY_LOCAL_MACHINE, buffer, &retval);
+        heap_free(buffer);
+    }
+    return retval;
+}
+
+/*****************************************************************************
+ * set_devices_and_printerports [internal]
+ *
+ * set the [Devices] and [PrinterPorts] entries for a printer.
+ *
+ */
+static void set_devices_and_printerports(PRINTER_INFO_2W *pi)
+{
+    DWORD portlen = lstrlenW(pi->pPortName) * sizeof(WCHAR);
+    WCHAR *devline;
+    HKEY  hkey;
+
+    TRACE("(%p) %s\n", pi, debugstr_w(pi->pPrinterName));
+
+    /* FIXME: the driver must change to "winspool" */
+    devline = heap_alloc(sizeof(driver_nt) + portlen + sizeof(timeout_15_45));
+    if (devline) {
+        lstrcpyW(devline, driver_nt);
+        lstrcatW(devline, commaW);
+        lstrcatW(devline, pi->pPortName);
+
+        TRACE("using %s\n", debugstr_w(devline));
+        WriteProfileStringW(devicesW, pi->pPrinterName, devline);
+        if (!RegCreateKeyW(HKEY_CURRENT_USER, winnt_cv_devicesW, &hkey)) {
+            RegSetValueExW(hkey, pi->pPrinterName, 0, REG_SZ, (LPBYTE)devline,
+                            (lstrlenW(devline) + 1) * sizeof(WCHAR));
+            RegCloseKey(hkey);
+        }
+
+        lstrcatW(devline, timeout_15_45);
+        WriteProfileStringW(printerportsW, pi->pPrinterName, devline);
+        if (!RegCreateKeyW(HKEY_CURRENT_USER, winnt_cv_printerportsW, &hkey)) {
+            RegSetValueExW(hkey, pi->pPrinterName, 0, REG_SZ, (LPBYTE)devline,
+                            (lstrlenW(devline) + 1) * sizeof(WCHAR));
+            RegCloseKey(hkey);
+        }
+        heap_free(devline);
+    }
+}
+
+/******************************************************************************
+ * get_default_devmode [internal]
+ *
+ * Get the default DEVMODE from the driver
+ */
+
+static WINAPI DEVMODEW * get_default_devmode(LPWSTR printername, LPWSTR drivername)
+{
+
+    LONG size;
+    HMODULE hwinspool;
+    DEVMODEW * dm = NULL;
+    LONG (WINAPI * pDocumentPropertiesW)(HWND hWnd, HANDLE hPrinter, LPWSTR pDeviceName,
+                                         LPDEVMODEW pDevModeOutput, LPDEVMODEW pDevModeInput, DWORD fMode);
+
+    TRACE("printername: %s, drivername: %s\n", debugstr_w(printername), debugstr_w(drivername));
+
+    hwinspool = LoadLibraryW(winspooldrvW);
+    if (!hwinspool) return NULL;
+
+    pDocumentPropertiesW = (void *) GetProcAddress(hwinspool, "DocumentPropertiesW");
+    if (!pDocumentPropertiesW)
+    {
+        FreeLibrary(hwinspool);
+        return NULL;
+    }
+
+    size = pDocumentPropertiesW(0, 0, printername, NULL, NULL, 0);
+
+    if (size < 0)
+    {
+        FIXME("DocumentPropertiesW on printer %s failed\n", debugstr_w(printername));
+        size = sizeof(DEVMODEW);
+    }
+
+
+    dm = heap_alloc_zero(size );
+    dm->dmSize = size;
+    if (pDocumentPropertiesW(0, 0, printername, dm, NULL, DM_OUT_BUFFER) < 0)
+    {
+        WARN("DocumentPropertiesW on printer %s failed!\n", debugstr_w(printername));
+        heap_free( dm );
+        dm = NULL;
+    }
+    else
+    {
+        /* set devmode to printer name */
+        lstrcpynW( dm->dmDeviceName, printername, CCHDEVICENAME );
+    }
+
+    FreeLibrary(hwinspool);
+    return dm;
+}
+
+/******************************************************************************
+ * fpAddPrinter [exported through PRINTPROVIDOR]
+ *
+ * Install a Printer with various Printer Parameter
+ *
+ * PARAMS
+ *  pName       [I] Servername or NULL (local Computer)
+ *  Level       [I] Level for the supplied PRINTER_INFO_*W struct
+ *  pPrinter    [I] PTR to PRINTER_INFO_*W struct with the Printer Parameter
+ *
+ * RESULTS
+ *  Success: TRUE
+ *  Failure: FALSE
+ *
+ */
+static HANDLE WINAPI fpAddPrinter(LPWSTR pName, DWORD Level, LPBYTE pPrinter)
+{
+    PRINTER_INFO_2W *pi = (PRINTER_INFO_2W *) pPrinter;
+    LPDEVMODEW dm;
+    HANDLE retval;
+    HKEY hkeyPrinter, hkeyPrinters, hkeyDriver, hkeyDrivers;
+
+    TRACE("(%s,%d,%p)\n", debugstr_w(pName), Level, pPrinter);
+
+    if(pName && *pName)
+    {
+        ERR("pName = %s - unsupported\n", debugstr_w(pName));
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return 0;
+    }
+
+    if(Level != 2)
+    {
+        ERR("Level = %d, unsupported!\n", Level);
+        SetLastError(ERROR_INVALID_LEVEL);
+        return 0;
+    }
+
+    if(!pPrinter)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return 0;
+    }
+
+    if(RegCreateKeyW(HKEY_LOCAL_MACHINE, printersW, &hkeyPrinters) != ERROR_SUCCESS) {
+        ERR("Can't create Printers key\n");
+        return 0;
+    }
+
+    if(!RegOpenKeyW(hkeyPrinters, pi->pPrinterName, &hkeyPrinter))
+    {
+        if (!RegQueryValueW(hkeyPrinter, attributesW, NULL, NULL))
+        {
+            SetLastError(ERROR_PRINTER_ALREADY_EXISTS);
+            RegCloseKey(hkeyPrinter);
+            RegCloseKey(hkeyPrinters);
+            return 0;
+        }
+        RegCloseKey(hkeyPrinter);
+    }
+
+    hkeyDrivers = localspl_OpenDriverReg(NULL);
+
+    if(!hkeyDrivers)
+    {
+        ERR("Can't create Drivers key\n");
+        RegCloseKey(hkeyPrinters);
+        return 0;
+    }
+
+    if(RegOpenKeyW(hkeyDrivers, pi->pDriverName, &hkeyDriver) != ERROR_SUCCESS)
+    {
+        WARN("Can't find driver %s\n", debugstr_w(pi->pDriverName));
+        RegCloseKey(hkeyPrinters);
+        RegCloseKey(hkeyDrivers);
+        SetLastError(ERROR_UNKNOWN_PRINTER_DRIVER);
+        return 0;
+    }
+
+    RegCloseKey(hkeyDriver);
+    RegCloseKey(hkeyDrivers);
+
+    if(lstrcmpiW(pi->pPrintProcessor, winprintW)) /* FIXME */
+    {
+        FIXME("Can't find processor %s\n", debugstr_w(pi->pPrintProcessor));
+        SetLastError(ERROR_UNKNOWN_PRINTPROCESSOR);
+        RegCloseKey(hkeyPrinters);
+        return 0;
+    }
+
+    if(RegCreateKeyW(hkeyPrinters, pi->pPrinterName, &hkeyPrinter) != ERROR_SUCCESS)
+    {
+        FIXME("Can't create printer %s\n", debugstr_w(pi->pPrinterName));
+        SetLastError(ERROR_INVALID_PRINTER_NAME);
+        RegCloseKey(hkeyPrinters);
+        return 0;
+    }
+
+    set_reg_DWORD(hkeyPrinter, attributesW, pi->Attributes);
+    set_reg_szW(hkeyPrinter,   datatypeW, pi->pDatatype);
+    set_reg_DWORD(hkeyPrinter, default_priorityW, pi->DefaultPriority);
+    set_reg_szW(hkeyPrinter,   descriptionW, pi->pComment);
+    set_reg_DWORD(hkeyPrinter, dnstimeoutW, 0);
+    set_reg_szW(hkeyPrinter,   locationW, pi->pLocation);
+    set_reg_szW(hkeyPrinter,   nameW, pi->pPrinterName);
+    set_reg_szW(hkeyPrinter,   parametersW, pi->pParameters);
+    set_reg_szW(hkeyPrinter,   portW, pi->pPortName);
+    set_reg_szW(hkeyPrinter,   print_processorW, pi->pPrintProcessor);
+    set_reg_szW(hkeyPrinter,   printer_driverW, pi->pDriverName);
+    set_reg_DWORD(hkeyPrinter, priorityW, pi->Priority);
+    set_reg_szW(hkeyPrinter,   separator_fileW, pi->pSepFile);
+    set_reg_szW(hkeyPrinter,   share_nameW, pi->pShareName);
+    set_reg_DWORD(hkeyPrinter, starttimeW, pi->StartTime);
+    set_reg_DWORD(hkeyPrinter, statusW, pi->Status);
+    set_reg_DWORD(hkeyPrinter, txtimeoutW, 0);
+    set_reg_DWORD(hkeyPrinter, untiltimeW, pi->UntilTime);
+
+    set_devices_and_printerports(pi);
+
+    if(pi->pDevMode)
+        dm = pi->pDevMode;
+    else
+    {
+        dm = get_default_devmode(pi->pPrinterName, pi->pDriverName);
+    }
+
+    set_reg_devmode( hkeyPrinter, default_devmodeW, dm );
+    if(!pi->pDevMode)
+        heap_free( dm );
+
+    RegCloseKey(hkeyPrinter);
+    RegCloseKey(hkeyPrinters);
+
+    retval = printer_alloc_handle(pi->pPrinterName, NULL);
+
+    if(!retval)
+    {
+        ERR("failed to get a handle for AddPrinter(%s, ...)\n", debugstr_w(pi->pPrinterName));
+    }
+    return retval;
+}
+
+
 /******************************************************************************
  * fpAddPrinterDriverEx [exported through PRINTPROVIDOR]
  *
@@ -2350,7 +2697,7 @@ void setup_provider(void)
         NULL,   /* fpSetJob */
         NULL,   /* fpGetJob */
         NULL,   /* fpEnumJobs */
-        NULL,   /* fpAddPrinter */
+        fpAddPrinter,
         NULL,   /* fpDeletePrinter */
         NULL,   /* fpSetPrinter */
         NULL,   /* fpGetPrinter */
diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c
index d13d00a..11268fc 100644
--- a/dlls/winspool.drv/info.c
+++ b/dlls/winspool.drv/info.c
@@ -274,8 +274,6 @@ static const WCHAR windowsW[] = {'w','i','n','d','o','w','s',0};
 static       WCHAR rawW[] = {'R','A','W',0};
 static       WCHAR driver_9x[] = {'w','i','n','e','p','s','1','6','.','d','r','v',0};
 static       WCHAR driver_nt[] = {'w','i','n','e','p','s','.','d','r','v',0};
-static const WCHAR timeout_15_45[] = {',','1','5',',','4','5',0};
-static const WCHAR commaW[] = {',',0};
 static       WCHAR emptyStringW[] = {0};
 
 static const WCHAR May_Delete_Value[] = {'W','i','n','e','M','a','y','D','e','l','e','t','e','M','e',0};
@@ -3113,176 +3111,43 @@ static HKEY WINSPOOL_OpenDriverReg( LPCVOID pEnvironment)
     return retval;
 }
 
-/*****************************************************************************
- * set_devices_and_printerports [internal]
- *
- * set the [Devices] and [PrinterPorts] entries for a printer.
- *
- */
-static void set_devices_and_printerports(PRINTER_INFO_2W *pi)
-{
-    DWORD portlen = lstrlenW(pi->pPortName) * sizeof(WCHAR);
-    WCHAR *devline;
-    HKEY  hkey;
-
-    TRACE("(%p) %s\n", pi, debugstr_w(pi->pPrinterName));
-
-    /* FIXME: the driver must change to "winspool" */
-    devline = HeapAlloc(GetProcessHeap(), 0, sizeof(driver_nt) + portlen + sizeof(timeout_15_45));
-    if (devline) {
-        lstrcpyW(devline, driver_nt);
-        lstrcatW(devline, commaW);
-        lstrcatW(devline, pi->pPortName);
-
-        TRACE("using %s\n", debugstr_w(devline));
-        WriteProfileStringW(devicesW, pi->pPrinterName, devline);
-        if (!RegCreateKeyW(HKEY_CURRENT_USER, user_printers_reg_key, &hkey)) {
-            RegSetValueExW(hkey, pi->pPrinterName, 0, REG_SZ, (LPBYTE)devline,
-                            (lstrlenW(devline) + 1) * sizeof(WCHAR));
-            RegCloseKey(hkey);
-        }
-
-        lstrcatW(devline, timeout_15_45);
-        WriteProfileStringW(PrinterPortsW, pi->pPrinterName, devline);
-        if (!RegCreateKeyW(HKEY_CURRENT_USER, WinNT_CV_PrinterPortsW, &hkey)) {
-            RegSetValueExW(hkey, pi->pPrinterName, 0, REG_SZ, (LPBYTE)devline,
-                            (lstrlenW(devline) + 1) * sizeof(WCHAR));
-            RegCloseKey(hkey);
-        }
-        HeapFree(GetProcessHeap(), 0, devline);
-    }
-}
 
 /*****************************************************************************
  *          AddPrinterW  [WINSPOOL.@]
+ *
+ * Install a Printer with various Printer Parameter
+ *
+ * PARAMS
+ *  pName       [I] Servername or NULL (local Computer)
+ *  Level       [I] Level for the supplied PRINTER_INFO_*W struct
+ *  pPrinter    [I] PTR to PRINTER_INFO_*W struct with the Printer Parameter
+ *
+ * RESULTS
+ *  Success: TRUE
+ *  Failure: FALSE
+ *
  */
 HANDLE WINAPI AddPrinterW(LPWSTR pName, DWORD Level, LPBYTE pPrinter)
 {
-    PRINTER_INFO_2W *pi = (PRINTER_INFO_2W *) pPrinter;
-    LPDEVMODEW dm;
-    HANDLE retval;
-    HKEY hkeyPrinter, hkeyPrinters, hkeyDriver, hkeyDrivers;
-    LONG size;
+    HANDLE backend_printer;
+    HANDLE res = NULL;
 
     TRACE("(%s,%d,%p)\n", debugstr_w(pName), Level, pPrinter);
 
-    if(pName && *pName) {
-        ERR("pName = %s - unsupported\n", debugstr_w(pName));
-	SetLastError(ERROR_INVALID_PARAMETER);
-	return 0;
-    }
-    if(Level != 2) {
-        ERR("Level = %d, unsupported!\n", Level);
-	SetLastError(ERROR_INVALID_LEVEL);
-	return 0;
-    }
-    if(!pPrinter) {
-        SetLastError(ERROR_INVALID_PARAMETER);
-	return 0;
-    }
-    if(RegCreateKeyW(HKEY_LOCAL_MACHINE, PrintersW, &hkeyPrinters) !=
-       ERROR_SUCCESS) {
-        ERR("Can't create Printers key\n");
-	return 0;
-    }
-    if(!RegOpenKeyW(hkeyPrinters, pi->pPrinterName, &hkeyPrinter)) {
-	if (!RegQueryValueW(hkeyPrinter, AttributesW, NULL, NULL)) {
-	    SetLastError(ERROR_PRINTER_ALREADY_EXISTS);
-	    RegCloseKey(hkeyPrinter);
-	    RegCloseKey(hkeyPrinters);
-	    return 0;
-	}
-	RegCloseKey(hkeyPrinter);
-    }
-    hkeyDrivers = WINSPOOL_OpenDriverReg(NULL);
-    if(!hkeyDrivers) {
-        ERR("Can't create Drivers key\n");
-	RegCloseKey(hkeyPrinters);
-	return 0;
-    }
-    if(RegOpenKeyW(hkeyDrivers, pi->pDriverName, &hkeyDriver) !=
-       ERROR_SUCCESS) {
-        WARN("Can't find driver %s\n", debugstr_w(pi->pDriverName));
-	RegCloseKey(hkeyPrinters);
-	RegCloseKey(hkeyDrivers);
-	SetLastError(ERROR_UNKNOWN_PRINTER_DRIVER);
-	return 0;
-    }
-    RegCloseKey(hkeyDriver);
-    RegCloseKey(hkeyDrivers);
-
-    if(lstrcmpiW(pi->pPrintProcessor, WinPrintW)) {  /* FIXME */
-        FIXME("Can't find processor %s\n", debugstr_w(pi->pPrintProcessor));
-	SetLastError(ERROR_UNKNOWN_PRINTPROCESSOR);
-	RegCloseKey(hkeyPrinters);
-	return 0;
-    }
+    if ((backend == NULL)  && !load_backend()) return FALSE;
 
-    if(RegCreateKeyW(hkeyPrinters, pi->pPrinterName, &hkeyPrinter) !=
-       ERROR_SUCCESS) {
-        FIXME("Can't create printer %s\n", debugstr_w(pi->pPrinterName));
-	SetLastError(ERROR_INVALID_PRINTER_NAME);
-	RegCloseKey(hkeyPrinters);
-	return 0;
+    if (pPrinter == NULL) {
+        SetLastError(RPC_X_NULL_REF_POINTER);
+        return FALSE;
     }
 
-    set_devices_and_printerports(pi);
-
-    set_reg_DWORD(hkeyPrinter, AttributesW, pi->Attributes);
-    set_reg_szW(hkeyPrinter, DatatypeW, pi->pDatatype);
-    set_reg_DWORD(hkeyPrinter, Default_PriorityW, pi->DefaultPriority);
-    set_reg_szW(hkeyPrinter, DescriptionW, pi->pComment);
-    set_reg_DWORD(hkeyPrinter, dnsTimeoutW, 0);
-    set_reg_szW(hkeyPrinter, LocationW, pi->pLocation);
-    set_reg_szW(hkeyPrinter, NameW, pi->pPrinterName);
-    set_reg_szW(hkeyPrinter, ParametersW, pi->pParameters);
-    set_reg_szW(hkeyPrinter, PortW, pi->pPortName);
-    set_reg_szW(hkeyPrinter, Print_ProcessorW, pi->pPrintProcessor);
-    set_reg_szW(hkeyPrinter, Printer_DriverW, pi->pDriverName);
-    set_reg_DWORD(hkeyPrinter, PriorityW, pi->Priority);
-    set_reg_szW(hkeyPrinter, Separator_FileW, pi->pSepFile);
-    set_reg_szW(hkeyPrinter, Share_NameW, pi->pShareName);
-    set_reg_DWORD(hkeyPrinter, StartTimeW, pi->StartTime);
-    set_reg_DWORD(hkeyPrinter, StatusW, pi->Status);
-    set_reg_DWORD(hkeyPrinter, txTimeoutW, 0);
-    set_reg_DWORD(hkeyPrinter, UntilTimeW, pi->UntilTime);
-
-    size = DocumentPropertiesW(0, 0, pi->pPrinterName, NULL, NULL, 0);
-
-    if (size < 0)
-    {
-        FIXME("DocumentPropertiesW on printer %s fails\n", debugstr_w(pi->pPrinterName));
-        size = sizeof(DEVMODEW);
-    }
-    if(pi->pDevMode)
-        dm = pi->pDevMode;
-    else
-    {
-        dm = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
-        dm->dmSize = size;
-        if (DocumentPropertiesW(0, 0, pi->pPrinterName, dm, NULL, DM_OUT_BUFFER) < 0)
-        {
-            WARN("DocumentPropertiesW on printer %s failed!\n", debugstr_w(pi->pPrinterName));
-            HeapFree( GetProcessHeap(), 0, dm );
-            dm = NULL;
-        }
-        else
-        {
-            /* set devmode to printer name */
-            lstrcpynW( dm->dmDeviceName, pi->pPrinterName, CCHDEVICENAME );
-        }
-    }
+    backend_printer = backend->fpAddPrinter(pName, Level, pPrinter);
 
-    set_reg_devmode( hkeyPrinter, Default_DevModeW, dm );
-    if (!pi->pDevMode) HeapFree( GetProcessHeap(), 0, dm );
+    if (backend_printer)
+        res = get_opened_printer_entry(pName, NULL, backend_printer);
 
-    RegCloseKey(hkeyPrinter);
-    RegCloseKey(hkeyPrinters);
-    if(!OpenPrinterW(pi->pPrinterName, &retval, NULL)) {
-        ERR("OpenPrinter failing\n");
-	return 0;
-    }
-    return retval;
+    TRACE("returning %p for %s (got %p from backend)\n", res, debugstr_w(pName), backend_printer);
+    return res;
 }
 
 /*****************************************************************************
-- 
2.7.4




More information about the wine-patches mailing list