diff --git a/win32ss/printing/base/winspool/printers.c b/win32ss/printing/base/winspool/printers.c index 0e7729408b..42eec7141a 100644 --- a/win32ss/printing/base/winspool/printers.c +++ b/win32ss/printing/base/winspool/printers.c @@ -202,12 +202,93 @@ DocumentEvent( HANDLE hPrinter, HDC hdc, int iEsc, ULONG cbIn, PVOID pvIn, ULONG return DOCUMENTEVENT_UNSUPPORTED; } +static PRINTER_INFO_9A * get_devmodeA(HANDLE hprn) +{ + PRINTER_INFO_9A *pi9 = NULL; + DWORD needed = 0; + BOOL res; + + res = GetPrinterA(hprn, 9, NULL, 0, &needed); + if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) + { + pi9 = HeapAlloc(hProcessHeap, 0, needed); + res = GetPrinterA(hprn, 9, (LPBYTE)pi9, needed, &needed); + } + + if (res) + return pi9; + + ERR("GetPrinterA failed with %u\n", GetLastError()); + HeapFree(hProcessHeap, 0, pi9); + return NULL; +} + LONG WINAPI DocumentPropertiesA(HWND hWnd, HANDLE hPrinter, LPSTR pDeviceName, PDEVMODEA pDevModeOutput, PDEVMODEA pDevModeInput, DWORD fMode) { + HANDLE hUseHandle = NULL; + PRINTER_INFO_9A *pi9 = NULL; + LONG Result = -1, Length; + TRACE("DocumentPropertiesA(%p, %p, %s, %p, %p, %lu)\n", hWnd, hPrinter, pDeviceName, pDevModeOutput, pDevModeInput, fMode); - UNIMPLEMENTED; - return -1; + + if (hPrinter) + { + hUseHandle = hPrinter; + } + else if (!OpenPrinterA(pDeviceName, &hUseHandle, NULL)) + { + ERR("No handle, and no usable printer name passed in\n"); + return -1; + } + + pi9 = get_devmodeA(hUseHandle); + + if (pi9) + { + Length = pi9->pDevMode->dmSize + pi9->pDevMode->dmDriverExtra; + // See wineps.drv PSDRV_ExtDeviceMode + if (fMode) + { + Result = 1; /* IDOK */ + + if (fMode & DM_IN_BUFFER) + { + FIXME("Merge pDevModeInput with pi9, write back to driver!\n"); + // See wineps.drv PSDRV_MergeDevmodes + } + + if (fMode & DM_IN_PROMPT) + { + FIXME("Show property sheet!\n"); + Result = 2; /* IDCANCEL */ + } + + if (fMode & (DM_OUT_BUFFER | DM_OUT_DEFAULT)) + { + if (pDevModeOutput) + { + memcpy(pDevModeOutput, pi9->pDevMode, pi9->pDevMode->dmSize + pi9->pDevMode->dmDriverExtra); + } + else + { + ERR("No pDevModeOutput\n"); + Result = -1; + } + } + } + else + { + Result = Length; + } + + HeapFree(hProcessHeap, 0, pi9); + } + + if (hUseHandle && !hPrinter) + ClosePrinter(hUseHandle); + return Result; + } static PRINTER_INFO_9W * get_devmodeW(HANDLE hprn) @@ -1031,17 +1112,778 @@ Cleanup: BOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded) { + PPRINTER_INFO_1A ppi1a = (PPRINTER_INFO_1A)pPrinter; + PPRINTER_INFO_1W ppi1w = (PPRINTER_INFO_1W)pPrinter; + PPRINTER_INFO_2A ppi2a = (PPRINTER_INFO_2A)pPrinter; + PPRINTER_INFO_2W ppi2w = (PPRINTER_INFO_2W)pPrinter; + PPRINTER_INFO_4A ppi4a = (PPRINTER_INFO_4A)pPrinter; + PPRINTER_INFO_4W ppi4w = (PPRINTER_INFO_4W)pPrinter; + PPRINTER_INFO_5A ppi5a = (PPRINTER_INFO_5A)pPrinter; + PPRINTER_INFO_5W ppi5w = (PPRINTER_INFO_5W)pPrinter; + PPRINTER_INFO_7A ppi7a = (PPRINTER_INFO_7A)pPrinter; + PPRINTER_INFO_7W ppi7w = (PPRINTER_INFO_7W)pPrinter; + DWORD cch; + BOOL bReturnValue = FALSE; + TRACE("GetPrinterA(%p, %lu, %p, %lu, %p)\n", hPrinter, Level, pPrinter, cbBuf, pcbNeeded); - if(pcbNeeded) *pcbNeeded = 0; - return FALSE; + + // Check for invalid levels here for early error return. Should be 1-9. + if (Level < 1 || Level > 9) + { + SetLastError(ERROR_INVALID_LEVEL); + ERR("Invalid Level!\n"); + goto Cleanup; + } + + bReturnValue = GetPrinterW(hPrinter, Level, pPrinter, cbBuf, pcbNeeded); + + if (!bReturnValue) + { + TRACE("GetPrinterW failed!\n"); + goto Cleanup; + } + + switch (Level) + { + case 1: + { + if (ppi1w->pDescription) + { + PSTR pszDescription; + + // Convert Unicode pDescription to a ANSI string pszDescription. + cch = wcslen(ppi1w->pDescription); + + pszDescription = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszDescription) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi1w->pDescription, -1, pszDescription, cch + 1, NULL, NULL); + StringCchCopyA(ppi1a->pDescription, cch + 1, pszDescription); + + HeapFree(hProcessHeap, 0, pszDescription); + } + + if (ppi1w->pName) + { + PSTR pszName; + + // Convert Unicode pName to a ANSI string pszName. + cch = wcslen(ppi1w->pName); + + pszName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi1w->pName, -1, pszName, cch + 1, NULL, NULL); + StringCchCopyA(ppi1a->pName, cch + 1, pszName); + + HeapFree(hProcessHeap, 0, pszName); + } + + if (ppi1w->pComment) + { + PSTR pszComment; + + // Convert Unicode pComment to a ANSI string pszComment. + cch = wcslen(ppi1w->pComment); + + pszComment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszComment) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi1w->pComment, -1, pszComment, cch + 1, NULL, NULL); + StringCchCopyA(ppi1a->pComment, cch + 1, pszComment); + + HeapFree(hProcessHeap, 0, pszComment); + } + break; + } + + case 2: + { + if (ppi2w->pServerName) + { + PSTR pszServerName; + + // Convert Unicode pServerName to a ANSI string pszServerName. + cch = wcslen(ppi2w->pServerName); + + pszServerName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszServerName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi2w->pServerName, -1, pszServerName, cch + 1, NULL, NULL); + StringCchCopyA(ppi2a->pServerName, cch + 1, pszServerName); + + HeapFree(hProcessHeap, 0, pszServerName); + } + + if (ppi2w->pPrinterName) + { + PSTR pszPrinterName; + + // Convert Unicode pPrinterName to a ANSI string pszPrinterName. + cch = wcslen(ppi2w->pPrinterName); + + pszPrinterName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszPrinterName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi2w->pPrinterName, -1, pszPrinterName, cch + 1, NULL, NULL); + StringCchCopyA(ppi2a->pPrinterName, cch + 1, pszPrinterName); + + HeapFree(hProcessHeap, 0, pszPrinterName); + } + + if (ppi2w->pShareName) + { + PSTR pszShareName; + + // Convert Unicode pShareName to a ANSI string pszShareName. + cch = wcslen(ppi2w->pShareName); + + pszShareName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszShareName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi2w->pShareName, -1, pszShareName, cch + 1, NULL, NULL); + StringCchCopyA(ppi2a->pShareName, cch + 1, pszShareName); + + HeapFree(hProcessHeap, 0, pszShareName); + } + + if (ppi2w->pPortName) + { + PSTR pszPortName; + + // Convert Unicode pPortName to a ANSI string pszPortName. + cch = wcslen(ppi2w->pPortName); + + pszPortName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszPortName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi2w->pPortName, -1, pszPortName, cch + 1, NULL, NULL); + StringCchCopyA(ppi2a->pPortName, cch + 1, pszPortName); + + HeapFree(hProcessHeap, 0, pszPortName); + } + + if (ppi2w->pDriverName) + { + PSTR pszDriverName; + + // Convert Unicode pDriverName to a ANSI string pszDriverName. + cch = wcslen(ppi2w->pDriverName); + + pszDriverName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszDriverName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi2w->pDriverName, -1, pszDriverName, cch + 1, NULL, NULL); + StringCchCopyA(ppi2a->pDriverName, cch + 1, pszDriverName); + + HeapFree(hProcessHeap, 0, pszDriverName); + } + + if (ppi2w->pComment) + { + PSTR pszComment; + + // Convert Unicode pComment to a ANSI string pszComment. + cch = wcslen(ppi2w->pComment); + + pszComment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszComment) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi2w->pComment, -1, pszComment, cch + 1, NULL, NULL); + StringCchCopyA(ppi2a->pComment, cch + 1, pszComment); + + HeapFree(hProcessHeap, 0, pszComment); + } + + if (ppi2w->pLocation) + { + PSTR pszLocation; + + // Convert Unicode pLocation to a ANSI string pszLocation. + cch = wcslen(ppi2w->pLocation); + + pszLocation = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszLocation) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi2w->pLocation, -1, pszLocation, cch + 1, NULL, NULL); + StringCchCopyA(ppi2a->pLocation, cch + 1, pszLocation); + + HeapFree(hProcessHeap, 0, pszLocation); + } + + if (ppi2w->pSepFile) + { + PSTR pszSepFile; + + // Convert Unicode pSepFile to a ANSI string pszSepFile. + cch = wcslen(ppi2w->pSepFile); + + pszSepFile = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszSepFile) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi2w->pSepFile, -1, pszSepFile, cch + 1, NULL, NULL); + StringCchCopyA(ppi2a->pSepFile, cch + 1, pszSepFile); + + HeapFree(hProcessHeap, 0, pszSepFile); + } + + if (ppi2w->pPrintProcessor) + { + PSTR pszPrintProcessor; + + // Convert Unicode pPrintProcessor to a ANSI string pszPrintProcessor. + cch = wcslen(ppi2w->pPrintProcessor); + + pszPrintProcessor = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszPrintProcessor) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi2w->pPrintProcessor, -1, pszPrintProcessor, cch + 1, NULL, NULL); + StringCchCopyA(ppi2a->pPrintProcessor, cch + 1, pszPrintProcessor); + + HeapFree(hProcessHeap, 0, pszPrintProcessor); + } + + if (ppi2w->pDatatype) + { + PSTR pszDatatype; + + // Convert Unicode pDatatype to a ANSI string pszDatatype. + cch = wcslen(ppi2w->pDatatype); + + pszDatatype = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszDatatype) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi2w->pDatatype, -1, pszDatatype, cch + 1, NULL, NULL); + StringCchCopyA(ppi2a->pDatatype, cch + 1, pszDatatype); + + HeapFree(hProcessHeap, 0, pszDatatype); + } + + if (ppi2w->pParameters) + { + PSTR pszParameters; + + // Convert Unicode pParameters to a ANSI string pszParameters. + cch = wcslen(ppi2w->pParameters); + + pszParameters = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszParameters) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi2w->pParameters, -1, pszParameters, cch + 1, NULL, NULL); + StringCchCopyA(ppi2a->pParameters, cch + 1, pszParameters); + + HeapFree(hProcessHeap, 0, pszParameters); + } + break; + } + + case 4: + { + if (ppi4w->pPrinterName) + { + PSTR pszPrinterName; + + // Convert Unicode pPrinterName to a ANSI string pszPrinterName. + cch = wcslen(ppi4w->pPrinterName); + + pszPrinterName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszPrinterName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi4w->pPrinterName, -1, pszPrinterName, cch + 1, NULL, NULL); + StringCchCopyA(ppi4a->pPrinterName, cch + 1, pszPrinterName); + + HeapFree(hProcessHeap, 0, pszPrinterName); + } + + if (ppi4w->pServerName) + { + PSTR pszServerName; + + // Convert Unicode pServerName to a ANSI string pszServerName. + cch = wcslen(ppi4w->pServerName); + + pszServerName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszServerName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi4w->pServerName, -1, pszServerName, cch + 1, NULL, NULL); + StringCchCopyA(ppi4a->pServerName, cch + 1, pszServerName); + + HeapFree(hProcessHeap, 0, pszServerName); + } + break; + } + + case 5: + { + if (ppi5w->pPrinterName) + { + PSTR pszPrinterName; + + // Convert Unicode pPrinterName to a ANSI string pszPrinterName. + cch = wcslen(ppi5w->pPrinterName); + + pszPrinterName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszPrinterName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi5w->pPrinterName, -1, pszPrinterName, cch + 1, NULL, NULL); + StringCchCopyA(ppi5a->pPrinterName, cch + 1, pszPrinterName); + + HeapFree(hProcessHeap, 0, pszPrinterName); + } + + if (ppi5w->pPortName) + { + PSTR pszPortName; + + // Convert Unicode pPortName to a ANSI string pszPortName. + cch = wcslen(ppi5w->pPortName); + + pszPortName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszPortName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi5w->pPortName, -1, pszPortName, cch + 1, NULL, NULL); + StringCchCopyA(ppi5a->pPortName, cch + 1, pszPortName); + + HeapFree(hProcessHeap, 0, pszPortName); + } + break; + } + + case 7: + { + if (ppi7w->pszObjectGUID) + { + PSTR pszaObjectGUID; + + // Convert Unicode pszObjectGUID to a ANSI string pszaObjectGUID. + cch = wcslen(ppi7w->pszObjectGUID); + + pszaObjectGUID = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszaObjectGUID) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, ppi7w->pszObjectGUID, -1, pszaObjectGUID, cch + 1, NULL, NULL); + StringCchCopyA(ppi7a->pszObjectGUID, cch + 1, pszaObjectGUID); + + HeapFree(hProcessHeap, 0, pszaObjectGUID); + } + } + } // switch + +Cleanup: + + return bReturnValue; } BOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded) { + PDRIVER_INFO_1A pdi1a = (PDRIVER_INFO_1A)pDriverInfo; + PDRIVER_INFO_1W pdi1w = (PDRIVER_INFO_1W)pDriverInfo; + PDRIVER_INFO_4A pdi4a = (PDRIVER_INFO_4A)pDriverInfo; + PDRIVER_INFO_4W pdi4w = (PDRIVER_INFO_4W)pDriverInfo; + PWSTR pwszEnvironment = NULL; + DWORD cch; + + BOOL bReturnValue = FALSE; + TRACE("GetPrinterDriverA(%p, %s, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded); - if(pcbNeeded) *pcbNeeded = 0; - return FALSE; + + // Check for invalid levels here for early error return. Should be 1-6 or 8. + if (Level < 1 || Level > 8 || Level == 7) + { + SetLastError(ERROR_INVALID_LEVEL); + ERR("Invalid Level!\n"); + goto Cleanup; + } + + if (pEnvironment) + { + // Convert pEnvironment to a Unicode string pwszEnvironment. + cch = strlen(pEnvironment); + + pwszEnvironment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); + if (!pwszEnvironment) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + MultiByteToWideChar(CP_ACP, 0, pEnvironment, -1, pwszEnvironment, cch + 1); + } + + bReturnValue = GetPrinterDriverW(hPrinter, pwszEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded); + TRACE("*pcbNeeded is '%d' and bReturnValue is '%d' and GetLastError is '%ld'.\n", *pcbNeeded, bReturnValue, GetLastError()); + + if (pwszEnvironment) + { + HeapFree(hProcessHeap, 0, pwszEnvironment); + } + + if (!bReturnValue) + { + TRACE("GetPrinterDriverW failed!\n"); + goto Cleanup; + } + + switch (Level) + { + case 1: + { + if (pdi1w->pName) + { + PSTR pszName; + + // Convert Unicode pName to a ANSI string pszName. + cch = wcslen(pdi1w->pName); + + pszName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, pdi1w->pName, -1, pszName, cch + 1, NULL, NULL); + StringCchCopyA(pdi1a->pName, cch + 1, pszName); + + HeapFree(hProcessHeap, 0, pszName); + } + break; + } + + case 2: + case 3: + case 4: + { + if (pdi4w->pName) + { + PSTR pszName; + + // Convert Unicode pName to a ANSI string pszName. + cch = wcslen(pdi4w->pName); + + pszName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, pdi4w->pName, -1, pszName, cch + 1, NULL, NULL); + StringCchCopyA(pdi4a->pName, cch + 1, pszName); + + HeapFree(hProcessHeap, 0, pszName); + } + + if (pdi4w->pEnvironment) + { + PSTR pszEnvironment; + + // Convert Unicode pPrinterName to a ANSI string pszPrinterName. + cch = wcslen(pdi4w->pEnvironment); + + pszEnvironment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszEnvironment) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, pdi4w->pEnvironment, -1, pszEnvironment, cch + 1, NULL, NULL); + StringCchCopyA(pdi4a->pEnvironment, cch + 1, pszEnvironment); + + HeapFree(hProcessHeap, 0, pszEnvironment); + } + + if (pdi4w->pDriverPath) + { + PSTR pszDriverPath; + + // Convert Unicode pShareName to a ANSI string pszShareName. + cch = wcslen(pdi4w->pDriverPath); + + pszDriverPath = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszDriverPath) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, pdi4w->pDriverPath, -1, pszDriverPath, cch + 1, NULL, NULL); + StringCchCopyA(pdi4a->pDriverPath, cch + 1, pszDriverPath); + + HeapFree(hProcessHeap, 0, pszDriverPath); + } + + if (pdi4w->pDataFile) + { + PSTR pszDataFile; + + // Convert Unicode pPortName to a ANSI string pszPortName. + cch = wcslen(pdi4w->pDataFile); + + pszDataFile = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszDataFile) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, pdi4w->pDataFile, -1, pszDataFile, cch + 1, NULL, NULL); + StringCchCopyA(pdi4a->pDataFile, cch + 1, pszDataFile); + + HeapFree(hProcessHeap, 0, pszDataFile); + } + + if (pdi4w->pConfigFile) + { + PSTR pszConfigFile; + + // Convert Unicode pDriverName to a ANSI string pszDriverName. + cch = wcslen(pdi4w->pConfigFile); + + pszConfigFile = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszConfigFile) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, pdi4w->pConfigFile, -1, pszConfigFile, cch + 1, NULL, NULL); + StringCchCopyA(pdi4a->pConfigFile, cch + 1, pszConfigFile); + + HeapFree(hProcessHeap, 0, pszConfigFile); + } + + if (Level == 2) + { + break; + } + + if (pdi4w->pHelpFile) + { + PSTR pszHelpFile; + + // Convert Unicode pComment to a ANSI string pszComment. + cch = wcslen(pdi4w->pHelpFile); + + pszHelpFile = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszHelpFile) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, pdi4w->pHelpFile, -1, pszHelpFile, cch + 1, NULL, NULL); + StringCchCopyA(pdi4a->pHelpFile, cch + 1, pszHelpFile); + + HeapFree(hProcessHeap, 0, pszHelpFile); + } + + if (pdi4w->pDependentFiles) + { + PSTR pszDependentFiles; + + // Convert Unicode pLocation to a ANSI string pszLocation. + cch = wcslen(pdi4w->pDependentFiles); + + pszDependentFiles = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszDependentFiles) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, pdi4w->pDependentFiles, -1, pszDependentFiles, cch + 1, NULL, NULL); + StringCchCopyA(pdi4a->pDependentFiles, cch + 1, pszDependentFiles); + + HeapFree(hProcessHeap, 0, pszDependentFiles); + } + + if (pdi4w->pMonitorName) + { + PSTR pszMonitorName; + + // Convert Unicode pSepFile to a ANSI string pszSepFile. + cch = wcslen(pdi4w->pMonitorName); + + pszMonitorName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszMonitorName) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, pdi4w->pMonitorName, -1, pszMonitorName, cch + 1, NULL, NULL); + StringCchCopyA(pdi4a->pMonitorName, cch + 1, pszMonitorName); + + HeapFree(hProcessHeap, 0, pszMonitorName); + } + + if (pdi4w->pDefaultDataType) + { + PSTR pszDefaultDataType; + + // Convert Unicode pPrintProcessor to a ANSI string pszPrintProcessor. + cch = wcslen(pdi4w->pDefaultDataType); + + pszDefaultDataType = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszDefaultDataType) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, pdi4w->pDefaultDataType, -1, pszDefaultDataType, cch + 1, NULL, NULL); + StringCchCopyA(pdi4a->pDefaultDataType, cch + 1, pszDefaultDataType); + + HeapFree(hProcessHeap, 0, pszDefaultDataType); + } + + if (Level == 3) + { + break; + } + + if (pdi4w->pszzPreviousNames) + { + PSTR pszzPreviousNames; + + // Convert Unicode pPrintProcessor to a ANSI string pszPrintProcessor. + cch = wcslen(pdi4w->pszzPreviousNames); + + pszzPreviousNames = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(CHAR)); + if (!pszzPreviousNames) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + ERR("HeapAlloc failed!\n"); + goto Cleanup; + } + + WideCharToMultiByte(CP_ACP, 0, pdi4w->pszzPreviousNames, -1, pszzPreviousNames, cch + 1, NULL, NULL); + StringCchCopyA(pdi4a->pszzPreviousNames, cch + 1, pszzPreviousNames); + + HeapFree(hProcessHeap, 0, pszzPreviousNames); + } + break; + } + + default: + { + if (pcbNeeded) *pcbNeeded = 0; + ERR("Level '%d' is not implemented!\n", Level); + } // case + } // switch + +Cleanup: + + return bReturnValue; } BOOL WINAPI @@ -1050,7 +1892,7 @@ GetPrinterDriverW(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDri DWORD dwErrorCode; PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter; - ERR("GetPrinterDriverW(%p, %S, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded); + TRACE("GetPrinterDriverW(%p, %S, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded); // Sanity checks. if (!pHandle)