From 7aaabc3f14f94be60cf852550bb2b1cdba2fa0bb Mon Sep 17 00:00:00 2001 From: Huw D M Davies Date: Thu, 25 May 2000 23:02:46 +0000 Subject: [PATCH] Move winspool to unicode. Minor bug fixes. --- dlls/winspool/info.c | 1447 ++++++++++++++++++++++++++++-------------- include/winspool.h | 4 +- 2 files changed, 985 insertions(+), 466 deletions(-) diff --git a/dlls/winspool/info.c b/dlls/winspool/info.c index ce0120a45d6..4a71e6c6234 100644 --- a/dlls/winspool/info.c +++ b/dlls/winspool/info.c @@ -3,12 +3,14 @@ * * Copyright 1996 John Harvey * Copyright 1998 Andreas Mohr - * Copyright 1999 Klaas van Gend, Huw D M Davies + * Copyright 1999 Klaas van Gend + * Copyright 1999, 2000 Huw D M Davies */ #include #include #include +#include #include "winspool.h" #include "winbase.h" #include "winerror.h" @@ -16,17 +18,17 @@ #include "debugtools.h" #include "heap.h" #include "commctrl.h" +#include "winnls.h" DEFAULT_DEBUG_CHANNEL(winspool) CRITICAL_SECTION PRINT32_RegistryBlocker; -typedef struct _OPENEDPRINTERA +typedef struct _OPENEDPRINTER { - LPSTR lpsPrinterName; + LPWSTR lpsPrinterName; HANDLE hPrinter; - LPPRINTER_DEFAULTSA lpDefault; -} OPENEDPRINTERA, *LPOPENEDPRINTERA; +} OPENEDPRINTER, *LPOPENEDPRINTER; /* The OpenedPrinter Table dynamic array */ static HDPA pOpenedPrinterDPA = NULL; @@ -36,18 +38,45 @@ extern LPVOID (WINAPI* WINSPOOL_DPA_GetPtr) (const HDPA, INT); extern INT (WINAPI* WINSPOOL_DPA_InsertPtr) (const HDPA, INT, LPVOID); static char Printers[] = - "System\\CurrentControlSet\\control\\Print\\Printers\\"; +"System\\CurrentControlSet\\control\\Print\\Printers\\"; static char Drivers[] = "System\\CurrentControlSet\\control\\Print\\Environments\\Windows 4.0\\Drivers\\"; /* Hmm, well */ +static WCHAR DefaultEnvironmentW[] = {'W','i','n','e',0}; + +static WCHAR Configuration_FileW[] = {'C','o','n','f','i','g','u','r','a','t', + 'i','o','n',' ','F','i','l','e',0}; +static WCHAR DatatypeW[] = {'D','a','t','a','t','y','p','e',0}; +static WCHAR Data_FileW[] = {'D','a','t','a',' ','F','i','l','e',0}; +static WCHAR Default_DevModeW[] = {'D','e','f','a','u','l','t',' ','D','e','v', + 'M','o','d','e',0}; +static WCHAR Dependent_FilesW[] = {'D','e','p','e','n','d','e','n','t',' ','F', + 'i','l','e','s',0}; +static WCHAR DescriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0}; +static WCHAR DriverW[] = {'D','r','i','v','e','r',0}; +static WCHAR Help_FileW[] = {'H','e','l','p',' ','F','i','l','e',0}; +static WCHAR LocationW[] = {'L','o','c','a','t','i','o','n',0}; +static WCHAR MonitorW[] = {'M','o','n','i','t','o','r',0}; +static WCHAR NameW[] = {'N','a','m','e',0}; +static WCHAR ParametersW[] = {'P','a','r','a','m','e','t','e','r','s',0}; +static WCHAR PortW[] = {'P','o','r','t',0}; +static WCHAR Print_ProcessorW[] = {'P','r','i','n','t',' ','P','r','o','c','e', + 's','s','o','r',0}; +static WCHAR Printer_DriverW[] = {'P','r','i','n','t','e','r',' ','D','r','i', + 'v','e','r',0}; +static WCHAR Separator_FileW[] = {'S','e','p','a','r','a','t','o','r',' ','F', + 'i','l','e',0}; +static WCHAR Share_NameW[] = {'S','h','a','r','e',' ','N','a','m','e',0}; +static WCHAR WinPrintW[] = {'W','i','n','P','r','i','n','t',0}; + /****************************************************************** - * WINSPOOL_GetOpenedPrinterEntryA + * WINSPOOL_GetOpenedPrinterEntry * Get the first place empty in the opened printer table */ -static LPOPENEDPRINTERA WINSPOOL_GetOpenedPrinterEntryA() +static LPOPENEDPRINTER WINSPOOL_GetOpenedPrinterEntry() { int i; - LPOPENEDPRINTERA pOpenedPrinter; + LPOPENEDPRINTER pOpenedPrinter; /* * Create the opened printers' handle dynamic array. @@ -59,7 +88,7 @@ static LPOPENEDPRINTERA WINSPOOL_GetOpenedPrinterEntryA() { pOpenedPrinter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(OPENEDPRINTERA)); + sizeof(OPENEDPRINTER)); pOpenedPrinter->hPrinter = -1; WINSPOOL_DPA_InsertPtr(pOpenedPrinterDPA, i, pOpenedPrinter); } @@ -86,7 +115,7 @@ static LPOPENEDPRINTERA WINSPOOL_GetOpenedPrinterEntryA() { pOpenedPrinter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(OPENEDPRINTERA)); + sizeof(OPENEDPRINTER)); pOpenedPrinter->hPrinter = i + 1; WINSPOOL_DPA_InsertPtr(pOpenedPrinterDPA, i, pOpenedPrinter); return pOpenedPrinter; @@ -96,12 +125,12 @@ static LPOPENEDPRINTERA WINSPOOL_GetOpenedPrinterEntryA() } /****************************************************************** - * WINSPOOL_GetOpenedPrinterA + * WINSPOOL_GetOpenedPrinter * Get the pointer to the opened printer referred by the handle */ -static LPOPENEDPRINTERA WINSPOOL_GetOpenedPrinterA(int printerHandle) +static LPOPENEDPRINTER WINSPOOL_GetOpenedPrinter(int printerHandle) { - LPOPENEDPRINTERA pOpenedPrinter; + LPOPENEDPRINTER pOpenedPrinter; if(!pOpenedPrinterDPA) return NULL; if((printerHandle <=0) || @@ -113,6 +142,140 @@ static LPOPENEDPRINTERA WINSPOOL_GetOpenedPrinterA(int printerHandle) return pOpenedPrinter; } +/*********************************************************** + * DEVMODEcpyAtoW + */ +static LPDEVMODEW DEVMODEcpyAtoW(DEVMODEW *dmW, const DEVMODEA *dmA) +{ + BOOL Formname; + ptrdiff_t off_formname = (char *)dmA->dmFormName - (char *)dmA; + DWORD size; + + Formname = (dmA->dmSize > off_formname); + size = dmA->dmSize + CCHDEVICENAME + (Formname ? CCHFORMNAME : 0); + MultiByteToWideChar(CP_ACP, 0, dmA->dmDeviceName, -1, dmW->dmDeviceName, + CCHDEVICENAME); + if(!Formname) { + memcpy(&dmW->dmSpecVersion, &dmA->dmSpecVersion, + dmA->dmSize - CCHDEVICENAME); + } else { + memcpy(&dmW->dmSpecVersion, &dmA->dmSpecVersion, + off_formname - CCHDEVICENAME); + MultiByteToWideChar(CP_ACP, 0, dmA->dmFormName, -1, dmW->dmFormName, + CCHFORMNAME); + memcpy(&dmW->dmLogPixels, &dmA->dmLogPixels, dmA->dmSize - + (off_formname + CCHFORMNAME)); + } + dmW->dmSize = size; + memcpy((char *)dmW + dmW->dmSize, (char *)dmA + dmA->dmSize, + dmA->dmDriverExtra); + return dmW; +} + +/*********************************************************** + * DEVMODEdupAtoW + * Creates a unicode copy of supplied devmode on heap + */ +static LPDEVMODEW DEVMODEdupAtoW(HANDLE heap, const DEVMODEA *dmA) +{ + LPDEVMODEW dmW; + DWORD size; + BOOL Formname; + ptrdiff_t off_formname; + + TRACE("\n"); + if(!dmA) return NULL; + + off_formname = (char *)dmA->dmFormName - (char *)dmA; + Formname = (dmA->dmSize > off_formname); + size = dmA->dmSize + CCHDEVICENAME + (Formname ? CCHFORMNAME : 0); + dmW = HeapAlloc(heap, HEAP_ZERO_MEMORY, size + dmA->dmDriverExtra); + return DEVMODEcpyAtoW(dmW, dmA); +} + +/*********************************************************** + * DEVMODEdupWtoA + * Creates an ascii copy of supplied devmode on heap + */ +static LPDEVMODEA DEVMODEdupWtoA(HANDLE heap, const DEVMODEW *dmW) +{ + LPDEVMODEA dmA; + DWORD size; + BOOL Formname; + ptrdiff_t off_formname = (char *)dmW->dmFormName - (char *)dmW; + + if(!dmW) return NULL; + Formname = (dmW->dmSize > off_formname); + size = dmW->dmSize - CCHDEVICENAME - (Formname ? CCHFORMNAME : 0); + dmA = HeapAlloc(heap, HEAP_ZERO_MEMORY, size + dmW->dmDriverExtra); + WideCharToMultiByte(CP_ACP, 0, dmW->dmDeviceName, -1, dmA->dmDeviceName, + CCHDEVICENAME, NULL, NULL); + if(!Formname) { + memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion, + dmW->dmSize - CCHDEVICENAME * sizeof(WCHAR)); + } else { + memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion, + off_formname - CCHDEVICENAME * sizeof(WCHAR)); + WideCharToMultiByte(CP_ACP, 0, dmW->dmFormName, -1, dmA->dmFormName, + CCHFORMNAME, NULL, NULL); + memcpy(&dmA->dmLogPixels, &dmW->dmLogPixels, dmW->dmSize - + (off_formname + CCHFORMNAME * sizeof(WCHAR))); + } + dmA->dmSize = size; + memcpy((char *)dmA + dmA->dmSize, (char *)dmW + dmW->dmSize, + dmW->dmDriverExtra); + return dmA; +} + +/*********************************************************** + * PRINTER_INFO_2AtoW + * Creates a unicode copy of PRINTER_INFO_2A on heap + */ +static LPPRINTER_INFO_2W PRINTER_INFO_2AtoW(HANDLE heap, LPPRINTER_INFO_2A piA) +{ + LPPRINTER_INFO_2W piW; + if(!piA) return NULL; + piW = HeapAlloc(heap, 0, sizeof(*piW)); + memcpy(piW, piA, sizeof(*piW)); /* copy everything first */ + piW->pServerName = HEAP_strdupAtoW(heap, 0, piA->pServerName); + piW->pPrinterName = HEAP_strdupAtoW(heap, 0, piA->pPrinterName); + piW->pShareName = HEAP_strdupAtoW(heap, 0, piA->pShareName); + piW->pPortName = HEAP_strdupAtoW(heap, 0, piA->pPortName); + piW->pDriverName = HEAP_strdupAtoW(heap, 0, piA->pDriverName); + piW->pComment = HEAP_strdupAtoW(heap, 0, piA->pComment); + piW->pLocation = HEAP_strdupAtoW(heap, 0, piA->pLocation); + piW->pDevMode = DEVMODEdupAtoW(heap, piA->pDevMode); + piW->pSepFile = HEAP_strdupAtoW(heap, 0, piA->pSepFile); + piW->pPrintProcessor = HEAP_strdupAtoW(heap, 0, piA->pPrintProcessor); + piW->pDatatype = HEAP_strdupAtoW(heap, 0, piA->pDatatype); + piW->pParameters = HEAP_strdupAtoW(heap, 0, piA->pParameters); + return piW; +} + +/*********************************************************** + * FREE_PRINTER_INFO_2W + * Free PRINTER_INFO_2W and all strings + */ +static void FREE_PRINTER_INFO_2W(HANDLE heap, LPPRINTER_INFO_2W piW) +{ + if(!piW) return; + + HeapFree(heap,0,piW->pServerName); + HeapFree(heap,0,piW->pPrinterName); + HeapFree(heap,0,piW->pShareName); + HeapFree(heap,0,piW->pPortName); + HeapFree(heap,0,piW->pDriverName); + HeapFree(heap,0,piW->pComment); + HeapFree(heap,0,piW->pLocation); + HeapFree(heap,0,piW->pDevMode); + HeapFree(heap,0,piW->pSepFile); + HeapFree(heap,0,piW->pPrintProcessor); + HeapFree(heap,0,piW->pDatatype); + HeapFree(heap,0,piW->pParameters); + HeapFree(heap,0,piW); + return; +} + /****************************************************************** * DeviceCapabilitiesA [WINSPOOL.151] * @@ -137,15 +300,54 @@ INT WINAPI DeviceCapabilitiesA(LPCSTR pDeivce,LPCSTR pPort, WORD cap, /***************************************************************************** - * DeviceCapabilitiesW + * DeviceCapabilitiesW + * + * Call DeviceCapabilitiesA since we later call 16bit stuff anyway + * */ INT WINAPI DeviceCapabilitiesW(LPCWSTR pDevice, LPCWSTR pPort, WORD fwCapability, LPWSTR pOutput, const DEVMODEW *pDevMode) { - FIXME("(%p,%p,%d,%p,%p): stub\n", - pDevice, pPort, fwCapability, pOutput, pDevMode); - return -1; + LPDEVMODEA dmA = DEVMODEdupWtoA(GetProcessHeap(), pDevMode); + LPSTR pDeviceA = HEAP_strdupWtoA(GetProcessHeap(),0,pDevice); + LPSTR pPortA = HEAP_strdupWtoA(GetProcessHeap(),0,pPort); + INT ret; + + if(pOutput && (fwCapability == DC_BINNAMES || + fwCapability == DC_FILEDEPENDENCIES || + fwCapability == DC_PAPERNAMES)) { + /* These need A -> W translation */ + INT size = 0, i; + LPSTR pOutputA; + ret = DeviceCapabilitiesA(pDeviceA, pPortA, fwCapability, NULL, + dmA); + if(ret == -1) + return ret; + switch(fwCapability) { + case DC_BINNAMES: + size = 24; + break; + case DC_PAPERNAMES: + case DC_FILEDEPENDENCIES: + size = 64; + break; + } + pOutputA = HeapAlloc(GetProcessHeap(), 0, size * ret); + ret = DeviceCapabilitiesA(pDeviceA, pPortA, fwCapability, pOutputA, + dmA); + for(i = 0; i < ret; i++) + MultiByteToWideChar(CP_ACP, 0, pOutputA + (i * size), -1, + pOutput + (i * size), size); + HeapFree(GetProcessHeap(), 0, pOutputA); + } else { + ret = DeviceCapabilitiesA(pDeviceA, pPortA, fwCapability, + (LPSTR)pOutput, dmA); + } + HeapFree(GetProcessHeap(),0,pPortA); + HeapFree(GetProcessHeap(),0,pDeviceA); + HeapFree(GetProcessHeap(),0,dmA); + return ret; } /****************************************************************** @@ -156,25 +358,31 @@ LONG WINAPI DocumentPropertiesA(HWND hWnd,HANDLE hPrinter, LPSTR pDeviceName, LPDEVMODEA pDevModeOutput, LPDEVMODEA pDevModeInput,DWORD fMode ) { - LPOPENEDPRINTERA lpOpenedPrinter; + LPOPENEDPRINTER lpOpenedPrinter; LPSTR lpName = pDeviceName; + LONG ret; TRACE("(%d,%d,%s,%p,%p,%ld)\n", hWnd,hPrinter,pDeviceName,pDevModeOutput,pDevModeInput,fMode ); if(!pDeviceName) { - lpOpenedPrinter = WINSPOOL_GetOpenedPrinterA(hPrinter); + LPWSTR lpNameW; + lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); if(!lpOpenedPrinter) { SetLastError(ERROR_INVALID_HANDLE); return -1; } - lpName = lpOpenedPrinter->lpsPrinterName; + lpNameW = lpOpenedPrinter->lpsPrinterName; + lpName = HEAP_strdupWtoA(GetProcessHeap(),0,lpNameW); } - return GDI_CallExtDeviceMode16(hWnd, pDevModeOutput, lpName, "LPT1:", - pDevModeInput, NULL, fMode); + ret = GDI_CallExtDeviceMode16(hWnd, pDevModeOutput, lpName, "LPT1:", + pDevModeInput, NULL, fMode); + if(!pDeviceName) + HeapFree(GetProcessHeap(),0,lpName); + return ret; } @@ -182,28 +390,73 @@ LONG WINAPI DocumentPropertiesA(HWND hWnd,HANDLE hPrinter, * DocumentPropertiesW */ LONG WINAPI DocumentPropertiesW(HWND hWnd, HANDLE hPrinter, - LPWSTR pDeviceName, - LPDEVMODEW pDevModeOutput, - LPDEVMODEW pDevModeInput, DWORD fMode) + LPWSTR pDeviceName, + LPDEVMODEW pDevModeOutput, + LPDEVMODEW pDevModeInput, DWORD fMode) { - FIXME("(%d,%d,%s,%p,%p,%ld): stub\n", + + LPSTR pDeviceNameA = HEAP_strdupWtoA(GetProcessHeap(),0,pDeviceName); + LPDEVMODEA pDevModeInputA = DEVMODEdupWtoA(GetProcessHeap(),pDevModeInput); + LPDEVMODEA pDevModeOutputA = NULL; + LONG ret; + + TRACE("(%d,%d,%s,%p,%p,%ld)\n", hWnd,hPrinter,debugstr_w(pDeviceName),pDevModeOutput,pDevModeInput, fMode); - return -1; + if(pDevModeOutput) { + ret = DocumentPropertiesA(hWnd, hPrinter, pDeviceNameA, NULL, NULL, 0); + if(ret < 0) return ret; + pDevModeOutputA = HeapAlloc(GetProcessHeap(), 0, ret); + } + ret = DocumentPropertiesA(hWnd, hPrinter, pDeviceNameA, pDevModeOutputA, + pDevModeInputA, fMode); + if(pDevModeOutput) { + DEVMODEcpyAtoW(pDevModeOutput, pDevModeOutputA); + HeapFree(GetProcessHeap(),0,pDevModeOutputA); + } + if(fMode == 0 && ret > 0) + ret += (CCHDEVICENAME + CCHFORMNAME); + HeapFree(GetProcessHeap(),0,pDevModeInputA); + HeapFree(GetProcessHeap(),0,pDeviceNameA); + return ret; } - /****************************************************************** * OpenPrinterA [WINSPOOL.196] * */ BOOL WINAPI OpenPrinterA(LPSTR lpPrinterName,HANDLE *phPrinter, - LPPRINTER_DEFAULTSA pDefault) + LPPRINTER_DEFAULTSA pDefault) { - /* Not implemented: use the DesiredAccess of pDefault to set - the access rights to the printer */ + LPWSTR lpPrinterNameW = HEAP_strdupAtoW(GetProcessHeap(),0,lpPrinterName); + PRINTER_DEFAULTSW DefaultW, *pDefaultW = NULL; + BOOL ret; - LPOPENEDPRINTERA lpOpenedPrinter; + if(pDefault) { + DefaultW.pDatatype = HEAP_strdupAtoW(GetProcessHeap(), 0, + pDefault->pDatatype); + DefaultW.pDevMode = DEVMODEdupAtoW(GetProcessHeap(), + pDefault->pDevMode); + DefaultW.DesiredAccess = pDefault->DesiredAccess; + pDefaultW = &DefaultW; + } + ret = OpenPrinterW(lpPrinterNameW, phPrinter, pDefaultW); + if(pDefault) { + HeapFree(GetProcessHeap(), 0, DefaultW.pDatatype); + HeapFree(GetProcessHeap(), 0, DefaultW.pDevMode); + } + HeapFree(GetProcessHeap(), 0, lpPrinterNameW); + return ret; +} + +/****************************************************************** + * OpenPrinterW [WINSPOOL.197] + * + */ +BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter, + LPPRINTER_DEFAULTSW pDefault) +{ + LPOPENEDPRINTER lpOpenedPrinter; HKEY hkeyPrinters, hkeyPrinter; if (!lpPrinterName) { @@ -212,7 +465,8 @@ BOOL WINAPI OpenPrinterA(LPSTR lpPrinterName,HANDLE *phPrinter, return FALSE; } - TRACE("(printerName: %s, pDefault %p\n", lpPrinterName, pDefault); + TRACE("(printerName: %s, pDefault %p)\n", debugstr_w(lpPrinterName), + pDefault); /* Check Printer exists */ if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) != @@ -222,9 +476,9 @@ BOOL WINAPI OpenPrinterA(LPSTR lpPrinterName,HANDLE *phPrinter, return FALSE; } - if(RegOpenKeyA(hkeyPrinters, lpPrinterName, &hkeyPrinter) + if(RegOpenKeyW(hkeyPrinters, lpPrinterName, &hkeyPrinter) != ERROR_SUCCESS) { - WARN("Can't find printer `%s' in registry\n", lpPrinterName); + WARN("Can't find printer %s in registry\n", debugstr_w(lpPrinterName)); RegCloseKey(hkeyPrinters); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -236,7 +490,7 @@ BOOL WINAPI OpenPrinterA(LPSTR lpPrinterName,HANDLE *phPrinter, return TRUE; /* Get a place in the opened printer buffer*/ - lpOpenedPrinter = WINSPOOL_GetOpenedPrinterEntryA(); + lpOpenedPrinter = WINSPOOL_GetOpenedPrinterEntry(); if(!lpOpenedPrinter) { ERR("Can't allocate printer slot\n"); SetLastError(ERROR_OUTOFMEMORY); @@ -245,39 +499,15 @@ BOOL WINAPI OpenPrinterA(LPSTR lpPrinterName,HANDLE *phPrinter, /* Get the name of the printer */ lpOpenedPrinter->lpsPrinterName = - HEAP_strdupA( GetProcessHeap(), 0, lpPrinterName ); + HEAP_strdupW( GetProcessHeap(), 0, lpPrinterName ); /* Get the unique handle of the printer*/ *phPrinter = lpOpenedPrinter->hPrinter; - if (pDefault != NULL) { - lpOpenedPrinter->lpDefault = - HeapAlloc(GetProcessHeap(), 0, sizeof(PRINTER_DEFAULTSA)); - lpOpenedPrinter->lpDefault->pDevMode = - HeapAlloc(GetProcessHeap(), 0, sizeof(DEVMODEA)); - memcpy(lpOpenedPrinter->lpDefault->pDevMode, pDefault->pDevMode, - sizeof(DEVMODEA)); - lpOpenedPrinter->lpDefault->pDatatype = - HEAP_strdupA( GetProcessHeap(), 0, pDefault->pDatatype ); - lpOpenedPrinter->lpDefault->DesiredAccess = - pDefault->DesiredAccess; - } - + if (pDefault != NULL) + FIXME("Not handling pDefault\n"); + return TRUE; - -} - -/****************************************************************** - * OpenPrinterW [WINSPOOL.197] - * - */ -BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter, - LPPRINTER_DEFAULTSW pDefault) -{ - FIXME("(%s,%p,%p):stub\n",debugstr_w(lpPrinterName), phPrinter, - pDefault); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; } /****************************************************************** @@ -342,9 +572,9 @@ SetPrinterW( LPBYTE pPrinter, DWORD Command) { - FIXME("():stub\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + FIXME("():stub\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /****************************************************************************** @@ -357,9 +587,9 @@ WritePrinter( DWORD cbBuf, LPDWORD pcWritten) { - FIXME("():stub\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + FIXME("():stub\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } /***************************************************************************** @@ -403,19 +633,21 @@ BOOL WINAPI AddJobW(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, } /***************************************************************************** - * AddPrinterA [WINSPOOL.117] + * AddPrinterW [WINSPOOL.122] */ -HANDLE WINAPI AddPrinterA(LPSTR pName, DWORD Level, LPBYTE pPrinter) +HANDLE WINAPI AddPrinterW(LPWSTR pName, DWORD Level, LPBYTE pPrinter) { - PRINTER_INFO_2A *pi = (PRINTER_INFO_2A *) pPrinter; - + PRINTER_INFO_2W *pi = (PRINTER_INFO_2W *) pPrinter; + LPDEVMODEA dmA; + LPDEVMODEW dmW; HANDLE retval; HKEY hkeyPrinter, hkeyPrinters, hkeyDriver, hkeyDrivers; + LONG size; - TRACE("(%s,%ld,%p)\n", pName, Level, pPrinter); + TRACE("(%s,%ld,%p)\n", debugstr_w(pName), Level, pPrinter); if(pName != NULL) { - FIXME("pName = `%s' - unsupported\n", pName); + FIXME("pName = %s - unsupported\n", debugstr_w(pName)); SetLastError(ERROR_INVALID_PARAMETER); return 0; } @@ -433,7 +665,7 @@ HANDLE WINAPI AddPrinterA(LPSTR pName, DWORD Level, LPBYTE pPrinter) ERR("Can't create Printers key\n"); return 0; } - if(RegOpenKeyA(hkeyPrinters, pi->pPrinterName, &hkeyPrinter) == + if(RegOpenKeyW(hkeyPrinters, pi->pPrinterName, &hkeyPrinter) == ERROR_SUCCESS) { SetLastError(ERROR_PRINTER_ALREADY_EXISTS); RegCloseKey(hkeyPrinter); @@ -446,9 +678,9 @@ HANDLE WINAPI AddPrinterA(LPSTR pName, DWORD Level, LPBYTE pPrinter) RegCloseKey(hkeyPrinters); return 0; } - if(RegOpenKeyA(hkeyDrivers, pi->pDriverName, &hkeyDriver) != + if(RegOpenKeyW(hkeyDrivers, pi->pDriverName, &hkeyDriver) != ERROR_SUCCESS) { - WARN("Can't find driver `%s'\n", pi->pDriverName); + WARN("Can't find driver %s\n", debugstr_w(pi->pDriverName)); RegCloseKey(hkeyPrinters); RegCloseKey(hkeyDrivers); SetLastError(ERROR_UNKNOWN_PRINTER_DRIVER); @@ -456,47 +688,81 @@ HANDLE WINAPI AddPrinterA(LPSTR pName, DWORD Level, LPBYTE pPrinter) } RegCloseKey(hkeyDriver); RegCloseKey(hkeyDrivers); - if(strcasecmp(pi->pPrintProcessor, "WinPrint")) { /* FIXME */ - WARN("Can't find processor `%s'\n", pi->pPrintProcessor); + + if(lstrcmpiW(pi->pPrintProcessor, WinPrintW)) { /* FIXME */ + WARN("Can't find processor %s\n", debugstr_w(pi->pPrintProcessor)); SetLastError(ERROR_UNKNOWN_PRINTPROCESSOR); RegCloseKey(hkeyPrinters); return 0; } - if(RegCreateKeyA(hkeyPrinters, pi->pPrinterName, &hkeyPrinter) != + + /* See if we can load the driver. We may need the devmode structure anyway + */ + size = DocumentPropertiesW(0, -1, pi->pPrinterName, NULL, NULL, 0); + if(size < 0) { + WARN("DocumentProperties fails\n"); + SetLastError(ERROR_UNKNOWN_PRINTER_DRIVER); + return 0; + } + if(pi->pDevMode) { + dmW = pi->pDevMode; + } else { + dmW = HeapAlloc(GetProcessHeap(), 0, size); + DocumentPropertiesW(0, -1, pi->pPrinterName, dmW, NULL, DM_OUT_BUFFER); + } + + if(RegCreateKeyW(hkeyPrinters, pi->pPrinterName, &hkeyPrinter) != ERROR_SUCCESS) { - WARN("Can't create printer `%s'\n", pi->pPrinterName); + WARN("Can't create printer %s\n", debugstr_w(pi->pPrinterName)); SetLastError(ERROR_INVALID_PRINTER_NAME); RegCloseKey(hkeyPrinters); + if(!pi->pDevMode) + HeapFree(GetProcessHeap(), 0, dmW); return 0; } RegSetValueExA(hkeyPrinter, "Attributes", 0, REG_DWORD, - (LPSTR)&pi->Attributes, sizeof(DWORD)); - RegSetValueExA(hkeyPrinter, "Default DevMode", 0, REG_BINARY, - (LPSTR)&pi->pDevMode, - pi->pDevMode ? pi->pDevMode->dmSize : 0); - RegSetValueExA(hkeyPrinter, "Description", 0, REG_SZ, pi->pComment, 0); - RegSetValueExA(hkeyPrinter, "Location", 0, REG_SZ, pi->pLocation, 0); - RegSetValueExA(hkeyPrinter, "Name", 0, REG_SZ, pi->pPrinterName, 0); - RegSetValueExA(hkeyPrinter, "Parameters", 0, REG_SZ, pi->pParameters, 0); - RegSetValueExA(hkeyPrinter, "Port", 0, REG_SZ, pi->pPortName, 0); - RegSetValueExA(hkeyPrinter, "Print Processor", 0, REG_SZ, - pi->pPrintProcessor, 0); - RegSetValueExA(hkeyPrinter, "Printer Driver", 0, REG_SZ, pi->pDriverName, + (LPBYTE)&pi->Attributes, sizeof(DWORD)); + RegSetValueExW(hkeyPrinter, DatatypeW, 0, REG_SZ, (LPBYTE)pi->pDatatype, 0); + + /* Write DEVMODEA not DEVMODEW into reg. This is what win9x does + and we support these drivers. NT writes DEVMODEW so somehow + we'll need to distinguish between these when we support NT + drivers */ + dmA = DEVMODEdupWtoA(GetProcessHeap(), dmW); + RegSetValueExA(hkeyPrinter, "Default DevMode", 0, REG_BINARY, (LPBYTE)dmA, + dmA->dmSize + dmA->dmDriverExtra); + HeapFree(GetProcessHeap(), 0, dmA); + if(!pi->pDevMode) + HeapFree(GetProcessHeap(), 0, dmW); + RegSetValueExW(hkeyPrinter, DescriptionW, 0, REG_SZ, (LPBYTE)pi->pComment, + 0); + RegSetValueExW(hkeyPrinter, LocationW, 0, REG_SZ, (LPBYTE)pi->pLocation, + 0); + RegSetValueExW(hkeyPrinter, NameW, 0, REG_SZ, (LPBYTE)pi->pPrinterName, 0); + RegSetValueExW(hkeyPrinter, ParametersW, 0, REG_SZ, + (LPBYTE)pi->pParameters, 0); + RegSetValueExW(hkeyPrinter, PortW, 0, REG_SZ, (LPBYTE)pi->pPortName, 0); + RegSetValueExW(hkeyPrinter, Print_ProcessorW, 0, REG_SZ, + (LPBYTE)pi->pPrintProcessor, 0); + RegSetValueExW(hkeyPrinter, Printer_DriverW, 0, REG_SZ, + (LPBYTE)pi->pDriverName, 0); RegSetValueExA(hkeyPrinter, "Priority", 0, REG_DWORD, - (LPSTR)&pi->Priority, sizeof(DWORD)); - RegSetValueExA(hkeyPrinter, "Separator File", 0, REG_SZ, pi->pSepFile, 0); - RegSetValueExA(hkeyPrinter, "Share Name", 0, REG_SZ, pi->pShareName, 0); - RegSetValueExA(hkeyPrinter, "Start Time", 0, REG_DWORD, - (LPSTR)&pi->StartTime, sizeof(DWORD)); + (LPBYTE)&pi->Priority, sizeof(DWORD)); + RegSetValueExW(hkeyPrinter, Separator_FileW, 0, REG_SZ, + (LPBYTE)pi->pSepFile, 0); + RegSetValueExW(hkeyPrinter, Share_NameW, 0, REG_SZ, (LPBYTE)pi->pShareName, + 0); + RegSetValueExA(hkeyPrinter, "StartTime", 0, REG_DWORD, + (LPBYTE)&pi->StartTime, sizeof(DWORD)); RegSetValueExA(hkeyPrinter, "Status", 0, REG_DWORD, - (LPSTR)&pi->Status, sizeof(DWORD)); - RegSetValueExA(hkeyPrinter, "Until Time", 0, REG_DWORD, - (LPSTR)&pi->UntilTime, sizeof(DWORD)); + (LPBYTE)&pi->Status, sizeof(DWORD)); + RegSetValueExA(hkeyPrinter, "UntilTime", 0, REG_DWORD, + (LPBYTE)&pi->UntilTime, sizeof(DWORD)); RegCloseKey(hkeyPrinter); RegCloseKey(hkeyPrinters); - if(!OpenPrinterA(pi->pPrinterName, &retval, NULL)) { + if(!OpenPrinterW(pi->pPrinterName, &retval, NULL)) { ERR("OpenPrinter failing\n"); return 0; } @@ -504,12 +770,29 @@ HANDLE WINAPI AddPrinterA(LPSTR pName, DWORD Level, LPBYTE pPrinter) } /***************************************************************************** - * AddPrinterW [WINSPOOL.122] + * AddPrinterA [WINSPOOL.117] */ -HANDLE WINAPI AddPrinterW(LPWSTR pName, DWORD Level, LPBYTE pPrinter) +HANDLE WINAPI AddPrinterA(LPSTR pName, DWORD Level, LPBYTE pPrinter) { - FIXME("(%p,%ld,%p): stub\n", pName, Level, pPrinter); - return 0; + WCHAR *pNameW; + PRINTER_INFO_2W *piW; + PRINTER_INFO_2A *piA = (PRINTER_INFO_2A*)pPrinter; + HANDLE ret; + + TRACE("(%s,%ld,%p): stub\n", debugstr_a(pName), Level, pPrinter); + if(Level != 2) { + WARN("Level = %ld\n", Level); + SetLastError(ERROR_INVALID_LEVEL); + return 0; + } + pNameW = HEAP_strdupAtoW(GetProcessHeap(), 0, pName); + piW = PRINTER_INFO_2AtoW(GetProcessHeap(), piA); + + ret = AddPrinterW(pNameW, Level, (LPBYTE)piW); + + FREE_PRINTER_INFO_2W(GetProcessHeap(), piW); + HeapFree(GetProcessHeap(),0,pNameW); + return ret; } @@ -518,7 +801,7 @@ HANDLE WINAPI AddPrinterW(LPWSTR pName, DWORD Level, LPBYTE pPrinter) */ BOOL WINAPI ClosePrinter(HANDLE hPrinter) { - LPOPENEDPRINTERA lpOpenedPrinter; + LPOPENEDPRINTER lpOpenedPrinter; TRACE("Handle %d\n", hPrinter); @@ -527,22 +810,9 @@ BOOL WINAPI ClosePrinter(HANDLE hPrinter) if ((hPrinter != -1) && (hPrinter < (pOpenedPrinterDPA->nItemCount - 1))) { - lpOpenedPrinter = WINSPOOL_GetOpenedPrinterA(hPrinter); + lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); HeapFree(GetProcessHeap(), 0, lpOpenedPrinter->lpsPrinterName); lpOpenedPrinter->lpsPrinterName = NULL; - - /* Free the memory of lpDefault if it has been initialized*/ - if(lpOpenedPrinter->lpDefault != NULL) - { - HeapFree(GetProcessHeap(), 0, - lpOpenedPrinter->lpDefault->pDevMode); - HeapFree(GetProcessHeap(), 0, - lpOpenedPrinter->lpDefault->pDatatype); - HeapFree(GetProcessHeap(), 0, - lpOpenedPrinter->lpDefault); - lpOpenedPrinter->lpDefault = NULL; - } - lpOpenedPrinter->hPrinter = -1; return TRUE; @@ -573,8 +843,30 @@ BOOL WINAPI DeleteFormW(HANDLE hPrinter, LPWSTR pFormName) */ BOOL WINAPI DeletePrinter(HANDLE hPrinter) { - FIXME("(%d): stub\n", hPrinter); - return 1; + LPWSTR lpNameW; + HKEY hkeyPrinters; + + LPOPENEDPRINTER lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); + if(!lpOpenedPrinter) { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + lpNameW = lpOpenedPrinter->lpsPrinterName; + if(RegOpenKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) != + ERROR_SUCCESS) { + ERR("Can't open Printers key\n"); + return 0; + } + + /* This should use a recursive delete see Q142491 or SHDeleteKey */ + if(RegDeleteKeyW(hkeyPrinters, lpNameW) == ERROR_SUCCESS) { + SetLastError(ERROR_PRINTER_NOT_FOUND); /* ?? */ + RegCloseKey(hkeyPrinters); + return 0; + } + + ClosePrinter(hPrinter); + return TRUE; } /***************************************************************************** @@ -679,35 +971,100 @@ BOOL WINAPI ResetPrinterW(HANDLE hPrinter, LPPRINTER_DEFAULTSW pDefault) return FALSE; } +/***************************************************************************** + * WINSPOOL_GetDWORDFromReg + * + * Return DWORD associated with ValueName from hkey. + */ +static DWORD WINSPOOL_GetDWORDFromReg(HKEY hkey, LPCSTR ValueName) +{ + DWORD sz = sizeof(DWORD), type, value = 0; + LONG ret; + + ret = RegQueryValueExA(hkey, ValueName, 0, &type, (LPBYTE)&value, &sz); + + if(ret != ERROR_SUCCESS) { + WARN("Got ret = %ld on name %s\n", ret, ValueName); + return 0; + } + if(type != REG_DWORD) { + ERR("Got type %ld\n", type); + return 0; + } + return value; +} /***************************************************************************** - * WINSPOOL_GetStringFromRegA + * WINSPOOL_GetStringFromReg * - * Get ValueName from hkey storing result in str. buflen is space left in str + * Get ValueName from hkey storing result in ptr. buflen is space left in ptr + * String is stored either as unicode or ascii. + * Bit of a hack here to get the ValueName if we want ascii. */ -static BOOL WINSPOOL_GetStringFromRegA(HKEY hkey, LPCSTR ValueName, LPSTR ptr, - DWORD buflen, DWORD *needed) +static BOOL WINSPOOL_GetStringFromReg(HKEY hkey, LPCWSTR ValueName, LPBYTE ptr, + DWORD buflen, DWORD *needed, + BOOL unicode) { DWORD sz = buflen, type; LONG ret; - ret = RegQueryValueExA(hkey, ValueName, 0, &type, ptr, &sz); - + if(unicode) + ret = RegQueryValueExW(hkey, ValueName, 0, &type, ptr, &sz); + else { + LPSTR ValueNameA = HEAP_strdupWtoA(GetProcessHeap(),0,ValueName); + ret = RegQueryValueExA(hkey, ValueNameA, 0, &type, ptr, &sz); + HeapFree(GetProcessHeap(),0,ValueNameA); + } if(ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA) { - ERR("Got ret = %ld\n", ret); + WARN("Got ret = %ld\n", ret); + *needed = 0; return FALSE; } *needed = sz; return TRUE; } -/********************************************************************* - * WINSPOOL_GetPrinter_2A +/***************************************************************************** + * WINSPOOL_GetDevModeFromReg * - * Fills out a PRINTER_INFO_2A struct storing the strings in buf. + * Get ValueName from hkey storing result in ptr. buflen is space left in ptr + * DevMode is stored either as unicode or ascii. + */ +static BOOL WINSPOOL_GetDevModeFromReg(HKEY hkey, LPCWSTR ValueName, + LPBYTE ptr, + DWORD buflen, DWORD *needed, + BOOL unicode) +{ + DWORD sz = buflen, type; + LONG ret; + + ret = RegQueryValueExW(hkey, ValueName, 0, &type, ptr, &sz); + if(ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA) { + WARN("Got ret = %ld\n", ret); + *needed = 0; + return FALSE; + } + if(unicode) { + sz += (CCHDEVICENAME + CCHFORMNAME); + if(buflen >= sz) { + DEVMODEW *dmW = DEVMODEdupAtoW(GetProcessHeap(), (DEVMODEA*)ptr); + memcpy(ptr, dmW, sz); + HeapFree(GetProcessHeap(),0,dmW); + } + } + *needed = sz; + return TRUE; +} + +/********************************************************************* + * WINSPOOL_GetPrinter_2 + * + * Fills out a PRINTER_INFO_2A|W struct storing the strings in buf. + * The strings are either stored as unicode or ascii. */ -static BOOL WINSPOOL_GetPrinter_2A(HKEY hkeyPrinter, PRINTER_INFO_2A *pi2, - LPBYTE buf, DWORD cbBuf, LPDWORD pcbNeeded) +static BOOL WINSPOOL_GetPrinter_2(HKEY hkeyPrinter, PRINTER_INFO_2W *pi2, + LPBYTE buf, DWORD cbBuf, LPDWORD pcbNeeded, + BOOL unicode) { DWORD size, left = cbBuf; BOOL space = (cbBuf > 0); @@ -715,53 +1072,124 @@ static BOOL WINSPOOL_GetPrinter_2A(HKEY hkeyPrinter, PRINTER_INFO_2A *pi2, *pcbNeeded = 0; - WINSPOOL_GetStringFromRegA(hkeyPrinter, "Name", ptr, left, &size); - if(space && size <= left) { - pi2->pPrinterName = ptr; - ptr += size; - left -= size; - } else - space = FALSE; - *pcbNeeded += size; - - WINSPOOL_GetStringFromRegA(hkeyPrinter, "Port", ptr, left, &size); - if(space && size <= left) { - pi2->pPortName = ptr; - ptr += size; - left -= size; - } else - space = FALSE; - *pcbNeeded += size; - - WINSPOOL_GetStringFromRegA(hkeyPrinter, "Printer Driver", ptr, left, - &size); - if(space && size <= left) { - pi2->pDriverName = ptr; - ptr += size; - left -= size; - } else - space = FALSE; - *pcbNeeded += size; - - WINSPOOL_GetStringFromRegA(hkeyPrinter, "Default DevMode", ptr, left, - &size); - if(space && size <= left) { - pi2->pDevMode = (LPDEVMODEA)ptr; - ptr += size; - left -= size; - } else - space = FALSE; - *pcbNeeded += size; - - WINSPOOL_GetStringFromRegA(hkeyPrinter, "Print Processor", ptr, left, - &size); - if(space && size <= left) { - pi2->pPrintProcessor = ptr; - ptr += size; - left -= size; - } else - space = FALSE; - *pcbNeeded += size; + if(WINSPOOL_GetStringFromReg(hkeyPrinter, NameW, ptr, left, &size, + unicode)) { + if(space && size <= left) { + pi2->pPrinterName = (LPWSTR)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(WINSPOOL_GetStringFromReg(hkeyPrinter, Share_NameW, ptr, left, &size, + unicode)) { + if(space && size <= left) { + pi2->pShareName = (LPWSTR)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(WINSPOOL_GetStringFromReg(hkeyPrinter, PortW, ptr, left, &size, + unicode)) { + if(space && size <= left) { + pi2->pPortName = (LPWSTR)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(WINSPOOL_GetStringFromReg(hkeyPrinter, Printer_DriverW, ptr, left, + &size, unicode)) { + if(space && size <= left) { + pi2->pDriverName = (LPWSTR)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(WINSPOOL_GetStringFromReg(hkeyPrinter, DescriptionW, ptr, left, &size, + unicode)) { + if(space && size <= left) { + pi2->pComment = (LPWSTR)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(WINSPOOL_GetStringFromReg(hkeyPrinter, LocationW, ptr, left, &size, + unicode)) { + if(space && size <= left) { + pi2->pLocation = (LPWSTR)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(WINSPOOL_GetDevModeFromReg(hkeyPrinter, Default_DevModeW, ptr, left, + &size, unicode)) { + if(space && size <= left) { + pi2->pDevMode = (LPDEVMODEW)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(WINSPOOL_GetStringFromReg(hkeyPrinter, Separator_FileW, ptr, left, + &size, unicode)) { + if(space && size <= left) { + pi2->pSepFile = (LPWSTR)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(WINSPOOL_GetStringFromReg(hkeyPrinter, Print_ProcessorW, ptr, left, + &size, unicode)) { + if(space && size <= left) { + pi2->pPrintProcessor = (LPWSTR)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(WINSPOOL_GetStringFromReg(hkeyPrinter, DatatypeW, ptr, left, + &size, unicode)) { + if(space && size <= left) { + pi2->pDatatype = (LPWSTR)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(WINSPOOL_GetStringFromReg(hkeyPrinter, ParametersW, ptr, left, + &size, unicode)) { + if(space && size <= left) { + pi2->pParameters = (LPWSTR)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(pi2) { + pi2->Attributes = WINSPOOL_GetDWORDFromReg(hkeyPrinter, "Attributes"); + pi2->Priority = WINSPOOL_GetDWORDFromReg(hkeyPrinter, "Priority"); + pi2->DefaultPriority = WINSPOOL_GetDWORDFromReg(hkeyPrinter, + "Default Priority"); + pi2->StartTime = WINSPOOL_GetDWORDFromReg(hkeyPrinter, "StartTime"); + pi2->UntilTime = WINSPOOL_GetDWORDFromReg(hkeyPrinter, "UntilTime"); + } if(!space && pi2) /* zero out pi2 if we can't completely fill buf */ memset(pi2, 0, sizeof(*pi2)); @@ -770,12 +1198,13 @@ static BOOL WINSPOOL_GetPrinter_2A(HKEY hkeyPrinter, PRINTER_INFO_2A *pi2, } /********************************************************************* - * WINSPOOL_GetPrinter_4A + * WINSPOOL_GetPrinter_4 * - * Fills out a PRINTER_INFO_4A struct storing the strings in buf. + * Fills out a PRINTER_INFO_4 struct storing the strings in buf. */ -static BOOL WINSPOOL_GetPrinter_4A(HKEY hkeyPrinter, PRINTER_INFO_4A *pi4, - LPBYTE buf, DWORD cbBuf, LPDWORD pcbNeeded) +static BOOL WINSPOOL_GetPrinter_4(HKEY hkeyPrinter, PRINTER_INFO_4W *pi4, + LPBYTE buf, DWORD cbBuf, LPDWORD pcbNeeded, + BOOL unicode) { DWORD size, left = cbBuf; BOOL space = (cbBuf > 0); @@ -783,15 +1212,19 @@ static BOOL WINSPOOL_GetPrinter_4A(HKEY hkeyPrinter, PRINTER_INFO_4A *pi4, *pcbNeeded = 0; - WINSPOOL_GetStringFromRegA(hkeyPrinter, "Name", ptr, left, &size); - if(space && size <= left) { - pi4->pPrinterName = ptr; - ptr += size; - left -= size; - } else - space = FALSE; - - *pcbNeeded += size; + if(WINSPOOL_GetStringFromReg(hkeyPrinter, NameW, ptr, left, &size, + unicode)) { + if(space && size <= left) { + pi4->pPrinterName = (LPWSTR)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(pi4) { + pi4->Attributes = WINSPOOL_GetDWORDFromReg(hkeyPrinter, "Attributes"); + } if(!space && pi4) /* zero out pi4 if we can't completely fill buf */ memset(pi4, 0, sizeof(*pi4)); @@ -800,12 +1233,13 @@ static BOOL WINSPOOL_GetPrinter_4A(HKEY hkeyPrinter, PRINTER_INFO_4A *pi4, } /********************************************************************* - * WINSPOOL_GetPrinter_5A + * WINSPOOL_GetPrinter_5 * - * Fills out a PRINTER_INFO_5A struct storing the strings in buf. + * Fills out a PRINTER_INFO_5 struct storing the strings in buf. */ -static BOOL WINSPOOL_GetPrinter_5A(HKEY hkeyPrinter, PRINTER_INFO_5A *pi5, - LPBYTE buf, DWORD cbBuf, LPDWORD pcbNeeded) +static BOOL WINSPOOL_GetPrinter_5(HKEY hkeyPrinter, PRINTER_INFO_5W *pi5, + LPBYTE buf, DWORD cbBuf, LPDWORD pcbNeeded, + BOOL unicode) { DWORD size, left = cbBuf; BOOL space = (cbBuf > 0); @@ -813,23 +1247,33 @@ static BOOL WINSPOOL_GetPrinter_5A(HKEY hkeyPrinter, PRINTER_INFO_5A *pi5, *pcbNeeded = 0; - WINSPOOL_GetStringFromRegA(hkeyPrinter, "Name", ptr, left, &size); - if(space && size <= left) { - pi5->pPrinterName = ptr; - ptr += size; - left -= size; - } else - space = FALSE; - *pcbNeeded += size; - - WINSPOOL_GetStringFromRegA(hkeyPrinter, "Port", ptr, left, &size); - if(space && size <= left) { - pi5->pPortName = ptr; - ptr += size; - left -= size; - } else - space = FALSE; - *pcbNeeded += size; + if(WINSPOOL_GetStringFromReg(hkeyPrinter, NameW, ptr, left, &size, + unicode)) { + if(space && size <= left) { + pi5->pPrinterName = (LPWSTR)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(WINSPOOL_GetStringFromReg(hkeyPrinter, PortW, ptr, left, &size, + unicode)) { + if(space && size <= left) { + pi5->pPortName = (LPWSTR)ptr; + ptr += size; + left -= size; + } else + space = FALSE; + *pcbNeeded += size; + } + if(pi5) { + pi5->Attributes = WINSPOOL_GetDWORDFromReg(hkeyPrinter, "Attributes"); + pi5->DeviceNotSelectedTimeout = WINSPOOL_GetDWORDFromReg(hkeyPrinter, + "dnsTimeout"); + pi5->TransmissionRetryTimeout = WINSPOOL_GetDWORDFromReg(hkeyPrinter, + "txTimeout"); + } if(!space && pi5) /* zero out pi5 if we can't completely fill buf */ memset(pi5, 0, sizeof(*pi5)); @@ -838,12 +1282,16 @@ static BOOL WINSPOOL_GetPrinter_5A(HKEY hkeyPrinter, PRINTER_INFO_5A *pi5, } /***************************************************************************** - * GetPrinterA [WINSPOOL.187] + * WINSPOOL_GetPrinter + * + * Implementation of GetPrinterA|W. Relies on PRINTER_INFO_*W being + * essentially the same as PRINTER_INFO_*A. i.e. the structure itself is + * just a collection of pointers to strings. */ -BOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, - DWORD cbBuf, LPDWORD pcbNeeded) +static BOOL WINSPOOL_GetPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, + DWORD cbBuf, LPDWORD pcbNeeded, BOOL unicode) { - OPENEDPRINTERA *lpOpenedPrinter; + OPENEDPRINTER *lpOpenedPrinter; DWORD size, needed = 0; LPBYTE ptr = NULL; HKEY hkeyPrinter, hkeyPrinters; @@ -851,7 +1299,7 @@ BOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, TRACE("(%d,%ld,%p,%ld,%p)\n",hPrinter,Level,pPrinter,cbBuf, pcbNeeded); - lpOpenedPrinter = WINSPOOL_GetOpenedPrinterA(hPrinter); + lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); if(!lpOpenedPrinter) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; @@ -861,10 +1309,10 @@ BOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, ERR("Can't create Printers key\n"); return FALSE; } - if(RegOpenKeyA(hkeyPrinters, lpOpenedPrinter->lpsPrinterName, &hkeyPrinter) + if(RegOpenKeyW(hkeyPrinters, lpOpenedPrinter->lpsPrinterName, &hkeyPrinter) != ERROR_SUCCESS) { - ERR("Can't find opened printer `%s' in registry\n", - lpOpenedPrinter->lpsPrinterName); + ERR("Can't find opened printer %s in registry\n", + debugstr_w(lpOpenedPrinter->lpsPrinterName)); RegCloseKey(hkeyPrinters); SetLastError(ERROR_INVALID_PRINTER_NAME); /* ? */ return FALSE; @@ -873,9 +1321,9 @@ BOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, switch(Level) { case 2: { - PRINTER_INFO_2A *pi2 = (PRINTER_INFO_2A *)pPrinter; + PRINTER_INFO_2W *pi2 = (PRINTER_INFO_2W *)pPrinter; - size = sizeof(PRINTER_INFO_2A); + size = sizeof(PRINTER_INFO_2W); if(size <= cbBuf) { ptr = pPrinter + size; cbBuf -= size; @@ -884,16 +1332,17 @@ BOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, pi2 = NULL; cbBuf = 0; } - ret = WINSPOOL_GetPrinter_2A(hkeyPrinter, pi2, ptr, cbBuf, &needed); + ret = WINSPOOL_GetPrinter_2(hkeyPrinter, pi2, ptr, cbBuf, &needed, + unicode); needed += size; break; } case 4: { - PRINTER_INFO_4A *pi4 = (PRINTER_INFO_4A *)pPrinter; + PRINTER_INFO_4W *pi4 = (PRINTER_INFO_4W *)pPrinter; - size = sizeof(PRINTER_INFO_4A); + size = sizeof(PRINTER_INFO_4W); if(size <= cbBuf) { ptr = pPrinter + size; cbBuf -= size; @@ -902,7 +1351,8 @@ BOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, pi4 = NULL; cbBuf = 0; } - ret = WINSPOOL_GetPrinter_4A(hkeyPrinter, pi4, ptr, cbBuf, &needed); + ret = WINSPOOL_GetPrinter_4(hkeyPrinter, pi4, ptr, cbBuf, &needed, + unicode); needed += size; break; } @@ -910,9 +1360,9 @@ BOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, case 5: { - PRINTER_INFO_5A *pi5 = (PRINTER_INFO_5A *)pPrinter; + PRINTER_INFO_5W *pi5 = (PRINTER_INFO_5W *)pPrinter; - size = sizeof(PRINTER_INFO_5A); + size = sizeof(PRINTER_INFO_5W); if(size <= cbBuf) { ptr = pPrinter + size; cbBuf -= size; @@ -922,7 +1372,8 @@ BOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, cbBuf = 0; } - ret = WINSPOOL_GetPrinter_5A(hkeyPrinter, pi5, ptr, cbBuf, &needed); + ret = WINSPOOL_GetPrinter_5(hkeyPrinter, pi5, ptr, cbBuf, &needed, + unicode); needed += size; break; } @@ -938,26 +1389,169 @@ BOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, RegCloseKey(hkeyPrinter); RegCloseKey(hkeyPrinters); + TRACE("returing %d needed = %ld\n", ret, needed); if(pcbNeeded) *pcbNeeded = needed; if(!ret) SetLastError(ERROR_INSUFFICIENT_BUFFER); return ret; } - /***************************************************************************** * GetPrinterW [WINSPOOL.194] */ BOOL WINAPI GetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, - DWORD cbBuf, LPDWORD pcbNeeded) + DWORD cbBuf, LPDWORD pcbNeeded) { - FIXME("(%d,%ld,%p,%ld,%p): stub\n", hPrinter, Level, pPrinter, - cbBuf, pcbNeeded); - return FALSE; + return WINSPOOL_GetPrinter(hPrinter, Level, pPrinter, cbBuf, pcbNeeded, + TRUE); } +/***************************************************************************** + * GetPrinterA [WINSPOOL.187] + */ +BOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, + DWORD cbBuf, LPDWORD pcbNeeded) +{ + return WINSPOOL_GetPrinter(hPrinter, Level, pPrinter, cbBuf, pcbNeeded, + FALSE); +} + +/***************************************************************************** + * WINSPOOL_EnumPrinters + * + * Implementation of EnumPrintersA|W + */ +static BOOL WINSPOOL_EnumPrinters(DWORD dwType, LPWSTR lpszName, + DWORD dwLevel, LPBYTE lpbPrinters, + DWORD cbBuf, LPDWORD lpdwNeeded, + LPDWORD lpdwReturned, BOOL unicode) + +{ + HKEY hkeyPrinters, hkeyPrinter; + WCHAR PrinterName[255]; + DWORD needed = 0, number = 0; + DWORD used, i, left; + PBYTE pi, buf; + + if(lpbPrinters) + memset(lpbPrinters, 0, cbBuf); + if(lpdwReturned) + *lpdwReturned = 0; + + if (!((dwType & PRINTER_ENUM_LOCAL) || (dwType & PRINTER_ENUM_NAME))) { + FIXME("dwType = %08lx\n", dwType); + SetLastError(ERROR_INVALID_FLAGS); + return FALSE; + } + + if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) != + ERROR_SUCCESS) { + ERR("Can't create Printers key\n"); + return FALSE; + } + + if(RegQueryInfoKeyA(hkeyPrinters, NULL, NULL, NULL, &number, NULL, NULL, + NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) { + RegCloseKey(hkeyPrinters); + ERR("Can't query Printers key\n"); + return FALSE; + } + TRACE("Found %ld printers\n", number); + + switch(dwLevel) { + case 1: + RegCloseKey(hkeyPrinters); + if (lpdwReturned) + *lpdwReturned = number; + return TRUE; + + case 2: + used = number * sizeof(PRINTER_INFO_2W); + break; + case 4: + used = number * sizeof(PRINTER_INFO_4W); + break; + case 5: + used = number * sizeof(PRINTER_INFO_5W); + break; + + default: + SetLastError(ERROR_INVALID_LEVEL); + RegCloseKey(hkeyPrinters); + return FALSE; + } + pi = (used <= cbBuf) ? lpbPrinters : NULL; + + for(i = 0; i < number; i++) { + if(RegEnumKeyW(hkeyPrinters, i, PrinterName, sizeof(PrinterName)) != + ERROR_SUCCESS) { + ERR("Can't enum key number %ld\n", i); + RegCloseKey(hkeyPrinters); + return FALSE; + } + TRACE("Printer %ld is %s\n", i, debugstr_w(PrinterName)); + if(RegOpenKeyW(hkeyPrinters, PrinterName, &hkeyPrinter) != + ERROR_SUCCESS) { + ERR("Can't open key %s\n", debugstr_w(PrinterName)); + RegCloseKey(hkeyPrinters); + return FALSE; + } + + if(cbBuf > used) { + buf = lpbPrinters + used; + left = cbBuf - used; + } else { + buf = NULL; + left = 0; + } + + switch(dwLevel) { + case 2: + WINSPOOL_GetPrinter_2(hkeyPrinter, (PRINTER_INFO_2W *)pi, buf, + left, &needed, unicode); + used += needed; + if(pi) pi += sizeof(PRINTER_INFO_2W); + break; + case 4: + WINSPOOL_GetPrinter_4(hkeyPrinter, (PRINTER_INFO_4W *)pi, buf, + left, &needed, unicode); + used += needed; + if(pi) pi += sizeof(PRINTER_INFO_4W); + break; + case 5: + WINSPOOL_GetPrinter_5(hkeyPrinter, (PRINTER_INFO_5W *)pi, buf, + left, &needed, unicode); + used += needed; + if(pi) pi += sizeof(PRINTER_INFO_5W); + break; + default: + ERR("Shouldn't be here!\n"); + RegCloseKey(hkeyPrinter); + RegCloseKey(hkeyPrinters); + return FALSE; + } + RegCloseKey(hkeyPrinter); + } + RegCloseKey(hkeyPrinters); + + if(lpdwNeeded) + *lpdwNeeded = used; + + if(used > cbBuf) { + if(lpbPrinters) + memset(lpbPrinters, 0, cbBuf); + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + if(lpdwReturned) + *lpdwReturned = number; + SetLastError(ERROR_SUCCESS); + return TRUE; +} + + /****************************************************************** - * EnumPrintersA [WINSPOOL.174] + * EnumPrintersW [WINSPOOL.175] * * Enumerates the available printers, print servers and print * providers, depending on the specified flags, name and level. @@ -1006,178 +1600,65 @@ BOOL WINAPI GetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, * - In a regular Wine installation, no registry settings for printers * exist, which makes this function return an empty list. */ -BOOL WINAPI EnumPrintersA( +BOOL WINAPI EnumPrintersW( DWORD dwType, /* Types of print objects to enumerate */ - LPSTR lpszName, /* name of objects to enumerate */ + LPWSTR lpszName, /* name of objects to enumerate */ DWORD dwLevel, /* type of printer info structure */ LPBYTE lpbPrinters, /* buffer which receives info */ DWORD cbBuf, /* max size of buffer in bytes */ LPDWORD lpdwNeeded, /* pointer to var: # bytes used/needed */ LPDWORD lpdwReturned /* number of entries returned */ ) - { - HKEY hkeyPrinters, hkeyPrinter; - char PrinterName[255]; - DWORD needed = 0, number = 0; - DWORD used, i, left; - PBYTE pi, buf; - - if(lpbPrinters) - memset(lpbPrinters, 0, cbBuf); - if(lpdwReturned) - *lpdwReturned = 0; - - if (!((dwType & PRINTER_ENUM_LOCAL) || (dwType & PRINTER_ENUM_NAME))) { - FIXME("dwType = %08lx\n", dwType); - SetLastError(ERROR_INVALID_FLAGS); - return FALSE; - } - - if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) != - ERROR_SUCCESS) { - ERR("Can't create Printers key\n"); - return FALSE; - } - - if(RegQueryInfoKeyA(hkeyPrinters, NULL, NULL, NULL, &number, NULL, NULL, - NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) { - RegCloseKey(hkeyPrinters); - ERR("Can't query Printers key\n"); - return FALSE; - } - TRACE("Found %ld printers\n", number); - - switch(dwLevel) { - case 1: - RegCloseKey(hkeyPrinters); - if (lpdwReturned) - *lpdwReturned = number; - return TRUE; - - case 2: - used = number * sizeof(PRINTER_INFO_2A); - break; - case 4: - used = number * sizeof(PRINTER_INFO_4A); - break; - case 5: - used = number * sizeof(PRINTER_INFO_5A); - break; - - default: - SetLastError(ERROR_INVALID_LEVEL); - RegCloseKey(hkeyPrinters); - return FALSE; - } - pi = (used <= cbBuf) ? lpbPrinters : NULL; - - for(i = 0; i < number; i++) { - if(RegEnumKeyA(hkeyPrinters, i, PrinterName, sizeof(PrinterName)) != - ERROR_SUCCESS) { - ERR("Can't enum key number %ld\n", i); - RegCloseKey(hkeyPrinters); - return FALSE; - } - if(RegOpenKeyA(hkeyPrinters, PrinterName, &hkeyPrinter) != - ERROR_SUCCESS) { - ERR("Can't open key '%s'\n", PrinterName); - RegCloseKey(hkeyPrinters); - return FALSE; - } - - if(cbBuf > used) { - buf = lpbPrinters + used; - left = cbBuf - used; - } else { - buf = NULL; - left = 0; - } - - switch(dwLevel) { - case 2: - WINSPOOL_GetPrinter_2A(hkeyPrinter, (PRINTER_INFO_2A *)pi, buf, - left, &needed); - used += needed; - if(pi) pi += sizeof(PRINTER_INFO_2A); - break; - case 4: - WINSPOOL_GetPrinter_4A(hkeyPrinter, (PRINTER_INFO_4A *)pi, buf, - left, &needed); - used += needed; - if(pi) pi += sizeof(PRINTER_INFO_4A); - break; - case 5: - WINSPOOL_GetPrinter_5A(hkeyPrinter, (PRINTER_INFO_5A *)pi, buf, - left, &needed); - used += needed; - if(pi) pi += sizeof(PRINTER_INFO_5A); - break; - default: - ERR("Shouldn't be here!\n"); - RegCloseKey(hkeyPrinter); - RegCloseKey(hkeyPrinters); - return FALSE; - } - RegCloseKey(hkeyPrinter); - } - RegCloseKey(hkeyPrinters); - - if(lpdwNeeded) - *lpdwNeeded = used; - if(used > cbBuf) { - if(lpbPrinters) - memset(lpbPrinters, 0, cbBuf); - SetLastError(ERROR_INSUFFICIENT_BUFFER); - return FALSE; - } - if(lpdwReturned) - *lpdwReturned = number; - SetLastError(ERROR_SUCCESS); - return TRUE; + return WINSPOOL_EnumPrinters(dwType, lpszName, dwLevel, lpbPrinters, cbBuf, + lpdwNeeded, lpdwReturned, TRUE); } /****************************************************************** - * EnumPrintersW [WINSPOOL.175] + * EnumPrintersA [WINSPOOL.174] * */ -BOOL WINAPI EnumPrintersW(DWORD dwType, LPWSTR lpszName, - DWORD dwLevel, LPBYTE lpbPrinters, - DWORD cbBuf, LPDWORD lpdwNeeded, - LPDWORD lpdwReturned) +BOOL WINAPI EnumPrintersA(DWORD dwType, LPSTR lpszName, + DWORD dwLevel, LPBYTE lpbPrinters, + DWORD cbBuf, LPDWORD lpdwNeeded, + LPDWORD lpdwReturned) { - FIXME("Nearly empty stub\n"); - *lpdwReturned=0; - *lpdwNeeded = 0; - return TRUE; + BOOL ret; + LPWSTR lpszNameW = HEAP_strdupAtoW(GetProcessHeap(),0,lpszName); + + ret = WINSPOOL_EnumPrinters(dwType, lpszNameW, dwLevel, lpbPrinters, cbBuf, + lpdwNeeded, lpdwReturned, FALSE); + HeapFree(GetProcessHeap(),0,lpszNameW); + return ret; } /***************************************************************************** - * GetPrinterDriverA [WINSPOOL.190] + * WINSPOOL_GetPrinterDriver */ -BOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, - DWORD Level, LPBYTE pDriverInfo, - DWORD cbBuf, LPDWORD pcbNeeded) +static BOOL WINSPOOL_GetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, + DWORD Level, LPBYTE pDriverInfo, + DWORD cbBuf, LPDWORD pcbNeeded, + BOOL unicode) { - OPENEDPRINTERA *lpOpenedPrinter; - char DriverName[100]; + OPENEDPRINTER *lpOpenedPrinter; + WCHAR DriverName[100]; DWORD ret, type, size, dw, needed = 0; LPBYTE ptr = NULL; HKEY hkeyPrinter, hkeyPrinters, hkeyDriver, hkeyDrivers; - TRACE("(%d,%s,%ld,%p,%ld,%p)\n",hPrinter,pEnvironment, - Level,pDriverInfo,cbBuf, pcbNeeded); + TRACE("(%d,%s,%ld,%p,%ld,%p)\n",hPrinter,debugstr_w(pEnvironment), + Level,pDriverInfo,cbBuf, pcbNeeded); ZeroMemory(pDriverInfo, cbBuf); - lpOpenedPrinter = WINSPOOL_GetOpenedPrinterA(hPrinter); + lpOpenedPrinter = WINSPOOL_GetOpenedPrinter(hPrinter); if(!lpOpenedPrinter) { SetLastError(ERROR_INVALID_HANDLE); return FALSE; } if(pEnvironment) { - FIXME("pEnvironment = `%s'\n", pEnvironment); + FIXME("pEnvironment = %s\n", debugstr_w(pEnvironment)); SetLastError(ERROR_INVALID_ENVIRONMENT); return FALSE; } @@ -1190,22 +1671,22 @@ BOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, ERR("Can't create Printers key\n"); return FALSE; } - if(RegOpenKeyA(hkeyPrinters, lpOpenedPrinter->lpsPrinterName, &hkeyPrinter) + if(RegOpenKeyW(hkeyPrinters, lpOpenedPrinter->lpsPrinterName, &hkeyPrinter) != ERROR_SUCCESS) { - ERR("Can't find opened printer `%s' in registry\n", - lpOpenedPrinter->lpsPrinterName); + ERR("Can't find opened printer %s in registry\n", + debugstr_w(lpOpenedPrinter->lpsPrinterName)); RegCloseKey(hkeyPrinters); SetLastError(ERROR_INVALID_PRINTER_NAME); /* ? */ return FALSE; } size = sizeof(DriverName); - ret = RegQueryValueExA(hkeyPrinter, "Printer Driver", 0, &type, DriverName, - &size); + ret = RegQueryValueExW(hkeyPrinter, Printer_DriverW, 0, &type, + (LPBYTE)DriverName, &size); RegCloseKey(hkeyPrinter); RegCloseKey(hkeyPrinters); if(ret != ERROR_SUCCESS) { - ERR("Can't get DriverName for printer `%s'\n", - lpOpenedPrinter->lpsPrinterName); + ERR("Can't get DriverName for printer %s\n", + debugstr_w(lpOpenedPrinter->lpsPrinterName)); return FALSE; } if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Drivers, &hkeyDrivers) != @@ -1213,9 +1694,9 @@ BOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, ERR("Can't create Drivers key\n"); return FALSE; } - if(RegOpenKeyA(hkeyDrivers, DriverName, &hkeyDriver) + if(RegOpenKeyW(hkeyDrivers, DriverName, &hkeyDriver) != ERROR_SUCCESS) { - ERR("Can't find driver `%s' in registry\n", DriverName); + ERR("Can't find driver %s in registry\n", debugstr_w(DriverName)); RegCloseKey(hkeyDrivers); SetLastError(ERROR_UNKNOWN_PRINTER_DRIVER); /* ? */ return FALSE; @@ -1223,13 +1704,13 @@ BOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, switch(Level) { case 1: - size = sizeof(DRIVER_INFO_1A); + size = sizeof(DRIVER_INFO_1W); break; case 2: - size = sizeof(DRIVER_INFO_2A); + size = sizeof(DRIVER_INFO_2W); break; case 3: - size = sizeof(DRIVER_INFO_3A); + size = sizeof(DRIVER_INFO_3W); break; default: ERR("Invalid level\n"); @@ -1243,20 +1724,29 @@ BOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, cbBuf = 0; needed = size; - size = strlen(DriverName) + 1; + if(unicode) + size = (lstrlenW(DriverName) + 1) * sizeof(WCHAR); + else + size = WideCharToMultiByte(CP_ACP, 0, DriverName, -1, NULL, 0, NULL, + NULL); + if(size <= cbBuf) { cbBuf -= size; - strcpy(ptr, DriverName); - if(Level == 1) - ((DRIVER_INFO_1A *)pDriverInfo)->pName = ptr; + if(unicode) + lstrcpyW((LPWSTR)ptr, DriverName); else - ((DRIVER_INFO_2A *)pDriverInfo)->pName = ptr; + WideCharToMultiByte(CP_ACP, 0, DriverName, -1, ptr, size, NULL, + NULL); + if(Level == 1) + ((DRIVER_INFO_1W *)pDriverInfo)->pName = (LPWSTR)ptr; + else + ((DRIVER_INFO_2W *)pDriverInfo)->pName = (LPWSTR)ptr; ptr += size; } needed += size; if(Level > 1) { - DRIVER_INFO_2A *di2 = (DRIVER_INFO_2A *)pDriverInfo; + DRIVER_INFO_2W *di2 = (DRIVER_INFO_2W *)pDriverInfo; size = sizeof(dw); if(RegQueryValueExA(hkeyDriver, "Version", 0, &type, (PBYTE)&dw, @@ -1266,77 +1756,93 @@ BOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, else if(cbBuf) di2->cVersion = dw; - size = strlen("Wine") + 1; /* FIXME */ + if(!pEnvironment) + pEnvironment = DefaultEnvironmentW; + if(unicode) + size = (lstrlenW(pEnvironment) + 1) * sizeof(WCHAR); + else + size = WideCharToMultiByte(CP_ACP, 0, pEnvironment, -1, NULL, 0, + NULL, NULL); if(size <= cbBuf) { cbBuf -= size; - strcpy(ptr, "Wine"); - di2->pEnvironment = ptr; + if(unicode) + lstrcpyW((LPWSTR)ptr, pEnvironment); + else + WideCharToMultiByte(CP_ACP, 0, pEnvironment, -1, ptr, size, + NULL, NULL); + di2->pEnvironment = (LPWSTR)ptr; ptr += size; } else cbBuf = 0; needed += size; - WINSPOOL_GetStringFromRegA(hkeyDriver, "Driver", ptr, cbBuf, &size); - if(cbBuf && size <= cbBuf) { - di2->pDriverPath = ptr; - ptr += size; - } else - cbBuf = 0; - needed += size; - - WINSPOOL_GetStringFromRegA(hkeyDriver, "Data File", ptr, cbBuf, &size); - if(cbBuf && size <= cbBuf) { - di2->pDataFile = ptr; - ptr += size; - } else - cbBuf = 0; - needed += size; - - WINSPOOL_GetStringFromRegA(hkeyDriver, "Configuration File", ptr, - cbBuf, &size); - if(cbBuf && size <= cbBuf) { - di2->pConfigFile = ptr; - ptr += size; - } else - cbBuf = 0; - needed += size; + if(WINSPOOL_GetStringFromReg(hkeyDriver, DriverW, ptr, cbBuf, &size, + unicode)) { + if(cbBuf && size <= cbBuf) { + di2->pDriverPath = (LPWSTR)ptr; + ptr += size; + } else + cbBuf = 0; + needed += size; + } + if(WINSPOOL_GetStringFromReg(hkeyDriver, Data_FileW, ptr, cbBuf, &size, + unicode)) { + if(cbBuf && size <= cbBuf) { + di2->pDataFile = (LPWSTR)ptr; + ptr += size; + } else + cbBuf = 0; + needed += size; + } + if(WINSPOOL_GetStringFromReg(hkeyDriver, Configuration_FileW, ptr, + cbBuf, &size, unicode)) { + if(cbBuf && size <= cbBuf) { + di2->pConfigFile = (LPWSTR)ptr; + ptr += size; + } else + cbBuf = 0; + needed += size; + } } - if(Level > 2) { - DRIVER_INFO_3A *di3 = (DRIVER_INFO_3A *)pDriverInfo; + DRIVER_INFO_3W *di3 = (DRIVER_INFO_3W *)pDriverInfo; - WINSPOOL_GetStringFromRegA(hkeyDriver, "Help File", ptr, cbBuf, &size); - if(cbBuf && size <= cbBuf) { - di3->pHelpFile = ptr; - ptr += size; - } else - cbBuf = 0; - needed += size; - - WINSPOOL_GetStringFromRegA(hkeyDriver, "Dependent Files", ptr, cbBuf, - &size); - if(cbBuf && size <= cbBuf) { - di3->pDependentFiles = ptr; - ptr += size; - } else - cbBuf = 0; - needed += size; - - WINSPOOL_GetStringFromRegA(hkeyDriver, "Monitor", ptr, cbBuf, &size); - if(cbBuf && size <= cbBuf) { - di3->pMonitorName = ptr; - ptr += size; - } else - cbBuf = 0; - needed += size; - - WINSPOOL_GetStringFromRegA(hkeyDriver, "DataType", ptr, cbBuf, &size); - if(cbBuf && size <= cbBuf) { - di3->pDefaultDataType = ptr; - ptr += size; - } else - cbBuf = 0; - needed += size; + if(WINSPOOL_GetStringFromReg(hkeyDriver, Help_FileW, ptr, cbBuf, &size, + unicode)) { + if(cbBuf && size <= cbBuf) { + di3->pHelpFile = (LPWSTR)ptr; + ptr += size; + } else + cbBuf = 0; + needed += size; + } + if(WINSPOOL_GetStringFromReg(hkeyDriver, Dependent_FilesW, ptr, cbBuf, + &size, unicode)) { + if(cbBuf && size <= cbBuf) { + di3->pDependentFiles = (LPWSTR)ptr; + ptr += size; + } else + cbBuf = 0; + needed += size; + } + if(WINSPOOL_GetStringFromReg(hkeyDriver, MonitorW, ptr, cbBuf, &size, + unicode)) { + if(cbBuf && size <= cbBuf) { + di3->pMonitorName = (LPWSTR)ptr; + ptr += size; + } else + cbBuf = 0; + needed += size; + } + if(WINSPOOL_GetStringFromReg(hkeyDriver, DatatypeW, ptr, cbBuf, &size, + unicode)) { + if(cbBuf && size <= cbBuf) { + di3->pDefaultDataType = (LPWSTR)ptr; + ptr += size; + } else + cbBuf = 0; + needed += size; + } } RegCloseKey(hkeyDriver); RegCloseKey(hkeyDrivers); @@ -1347,6 +1853,20 @@ BOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, return FALSE; } +/***************************************************************************** + * GetPrinterDriverA [WINSPOOL.190] + */ +BOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, + DWORD Level, LPBYTE pDriverInfo, + DWORD cbBuf, LPDWORD pcbNeeded) +{ + BOOL ret; + LPWSTR pEnvW = HEAP_strdupAtoW(GetProcessHeap(),0,pEnvironment); + ret = WINSPOOL_GetPrinterDriver(hPrinter, pEnvW, Level, pDriverInfo, + cbBuf, pcbNeeded, FALSE); + HeapFree(GetProcessHeap(),0,pEnvW); + return ret; +} /***************************************************************************** * GetPrinterDriverW [WINSPOOL.193] */ @@ -1354,9 +1874,8 @@ BOOL WINAPI GetPrinterDriverW(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded) { - FIXME("(%d,%p,%ld,%p,%ld,%p): stub\n",hPrinter,pEnvironment, - Level,pDriverInfo,cbBuf, pcbNeeded); - return FALSE; + return WINSPOOL_GetPrinterDriver(hPrinter, pEnvironment, Level, + pDriverInfo, cbBuf, pcbNeeded, TRUE); } /***************************************************************************** diff --git a/include/winspool.h b/include/winspool.h index 5aeadd0e88b..4c7bdd9bfd3 100644 --- a/include/winspool.h +++ b/include/winspool.h @@ -417,7 +417,7 @@ typedef struct _PRINTER_INFO_5A { LPSTR pPrinterName; LPSTR pPortName; DWORD Attributes; - DWORD DeviceNotSelectedTimeOut; + DWORD DeviceNotSelectedTimeout; DWORD TransmissionRetryTimeout; } PRINTER_INFO_5A, *PPRINTER_INFO_5A, *LPPRINTER_INFO_5A; @@ -425,7 +425,7 @@ typedef struct _PRINTER_INFO_5W { LPWSTR pPrinterName; LPWSTR pPortName; DWORD Attributes; - DWORD DeviceNotSelectedTimeOut; + DWORD DeviceNotSelectedTimeout; DWORD TransmissionRetryTimeout; } PRINTER_INFO_5W, *PPRINTER_INFO_5W, *LPPRINTER_INFO_5W;