[winspool 7/8] Implement GetPrinterDriverA with GetPrinterDriverW, notably using the larger sizes, which fixes a bug in printing with Acrobat Reader 9.2.
Jeremy White
jwhite at winehq.org
Mon Nov 30 17:05:15 CST 2009
---
dlls/winspool.drv/info.c | 216 ++++++++++++++++++++++++++++++++++++----
dlls/winspool.drv/tests/info.c | 1 -
2 files changed, 198 insertions(+), 19 deletions(-)
diff --git a/dlls/winspool.drv/info.c b/dlls/winspool.drv/info.c
index 9ea6443..aa6f305 100644
--- a/dlls/winspool.drv/info.c
+++ b/dlls/winspool.drv/info.c
@@ -1410,6 +1410,188 @@ static void convert_printerinfo_W_to_A(LPBYTE out, LPBYTE pPrintersW,
}
}
+/******************************************************************
+ * convert_driverinfo_W_to_A [internal]
+ *
+ */
+static void convert_driverinfo_W_to_A(LPBYTE out, LPBYTE pDriversW,
+ DWORD level, DWORD outlen, DWORD numentries)
+{
+ DWORD id = 0;
+ LPSTR ptr;
+ INT len;
+
+ TRACE("(%p, %p, %d, %u, %u)\n", out, pDriversW, level, outlen, numentries);
+
+ len = di_sizeof[level] * numentries;
+ ptr = (LPSTR) out + len;
+ outlen -= len;
+
+ /* copy the numbers of all PRINTER_INFO_* first */
+ memcpy(out, pDriversW, len);
+
+#define COPY_STRING(fld) \
+ { if (diW->fld){ \
+ diA->fld = ptr; \
+ len = WideCharToMultiByte(CP_ACP, 0, diW->fld, -1, ptr, outlen, NULL, NULL);\
+ ptr += len; outlen -= len;\
+ }}
+#define COPY_MULTIZ_STRING(fld) \
+ { LPWSTR p = diW->fld; if (p){ \
+ diA->fld = ptr; \
+ do {\
+ len = WideCharToMultiByte(CP_ACP, 0, p, -1, ptr, outlen, NULL, NULL);\
+ ptr += len; outlen -= len; p += len;\
+ }\
+ while(len > 1 && outlen > 0); \
+ }}
+
+ while (id < numentries)
+ {
+ switch (level)
+ {
+ case 1:
+ {
+ DRIVER_INFO_1W * diW = (DRIVER_INFO_1W *) pDriversW;
+ DRIVER_INFO_1A * diA = (DRIVER_INFO_1A *) out;
+
+ TRACE("(%u) #%u: %s\n", level, id, debugstr_w(diW->pName));
+
+ COPY_STRING(pName);
+ break;
+ }
+ case 2:
+ {
+ DRIVER_INFO_2W * diW = (DRIVER_INFO_2W *) pDriversW;
+ DRIVER_INFO_2A * diA = (DRIVER_INFO_2A *) out;
+
+ TRACE("(%u) #%u: %s\n", level, id, debugstr_w(diW->pName));
+
+ COPY_STRING(pName);
+ COPY_STRING(pEnvironment);
+ COPY_STRING(pDriverPath);
+ COPY_STRING(pDataFile);
+ COPY_STRING(pConfigFile);
+ break;
+ }
+ case 3:
+ {
+ DRIVER_INFO_3W * diW = (DRIVER_INFO_3W *) pDriversW;
+ DRIVER_INFO_3A * diA = (DRIVER_INFO_3A *) out;
+
+ TRACE("(%u) #%u: %s\n", level, id, debugstr_w(diW->pName));
+
+ COPY_STRING(pName);
+ COPY_STRING(pEnvironment);
+ COPY_STRING(pDriverPath);
+ COPY_STRING(pDataFile);
+ COPY_STRING(pConfigFile);
+ COPY_STRING(pHelpFile);
+ COPY_MULTIZ_STRING(pDependentFiles);
+ COPY_STRING(pMonitorName);
+ COPY_STRING(pDefaultDataType);
+ break;
+ }
+ case 4:
+ {
+ DRIVER_INFO_4W * diW = (DRIVER_INFO_4W *) pDriversW;
+ DRIVER_INFO_4A * diA = (DRIVER_INFO_4A *) out;
+
+ TRACE("(%u) #%u: %s\n", level, id, debugstr_w(diW->pName));
+
+ COPY_STRING(pName);
+ COPY_STRING(pEnvironment);
+ COPY_STRING(pDriverPath);
+ COPY_STRING(pDataFile);
+ COPY_STRING(pConfigFile);
+ COPY_STRING(pHelpFile);
+ COPY_MULTIZ_STRING(pDependentFiles);
+ COPY_STRING(pMonitorName);
+ COPY_STRING(pDefaultDataType);
+ COPY_MULTIZ_STRING(pszzPreviousNames);
+ break;
+ }
+ case 5:
+ {
+ DRIVER_INFO_5W * diW = (DRIVER_INFO_5W *) pDriversW;
+ DRIVER_INFO_5A * diA = (DRIVER_INFO_5A *) out;
+
+ TRACE("(%u) #%u: %s\n", level, id, debugstr_w(diW->pName));
+
+ COPY_STRING(pName);
+ COPY_STRING(pEnvironment);
+ COPY_STRING(pDriverPath);
+ COPY_STRING(pDataFile);
+ COPY_STRING(pConfigFile);
+ break;
+ }
+ case 6:
+ {
+ DRIVER_INFO_6W * diW = (DRIVER_INFO_6W *) pDriversW;
+ DRIVER_INFO_6A * diA = (DRIVER_INFO_6A *) out;
+
+ TRACE("(%u) #%u: %s\n", level, id, debugstr_w(diW->pName));
+
+ COPY_STRING(pName);
+ COPY_STRING(pEnvironment);
+ COPY_STRING(pDriverPath);
+ COPY_STRING(pDataFile);
+ COPY_STRING(pConfigFile);
+ COPY_STRING(pHelpFile);
+ COPY_MULTIZ_STRING(pDependentFiles);
+ COPY_STRING(pMonitorName);
+ COPY_STRING(pDefaultDataType);
+ COPY_MULTIZ_STRING(pszzPreviousNames);
+ COPY_STRING(pszMfgName);
+ COPY_STRING(pszOEMUrl);
+ COPY_STRING(pszHardwareID);
+ COPY_STRING(pszProvider);
+ break;
+ }
+ case 8:
+ {
+ DRIVER_INFO_8W * diW = (DRIVER_INFO_8W *) pDriversW;
+ DRIVER_INFO_8A * diA = (DRIVER_INFO_8A *) out;
+
+ TRACE("(%u) #%u: %s\n", level, id, debugstr_w(diW->pName));
+
+ COPY_STRING(pName);
+ COPY_STRING(pEnvironment);
+ COPY_STRING(pDriverPath);
+ COPY_STRING(pDataFile);
+ COPY_STRING(pConfigFile);
+ COPY_STRING(pHelpFile);
+ COPY_MULTIZ_STRING(pDependentFiles);
+ COPY_STRING(pMonitorName);
+ COPY_STRING(pDefaultDataType);
+ COPY_MULTIZ_STRING(pszzPreviousNames);
+ COPY_STRING(pszMfgName);
+ COPY_STRING(pszOEMUrl);
+ COPY_STRING(pszHardwareID);
+ COPY_STRING(pszProvider);
+ COPY_STRING(pszPrintProcessor);
+ COPY_STRING(pszVendorSetup);
+ COPY_MULTIZ_STRING(pszzColorProfiles);
+ COPY_STRING(pszInfPath);
+ COPY_MULTIZ_STRING(pszzCoreDriverDependencies);
+ break;
+ }
+
+
+ default:
+ FIXME("for level %u\n", level);
+ }
+
+ pDriversW += di_sizeof[level];
+ out += di_sizeof[level];
+ id++;
+
+ }
+#undef COPY_STRING
+#undef COPY_MULTIZ_STRING
+}
+
+
/***********************************************************
* PRINTER_INFO_2AtoW
* Creates a unicode copy of PRINTER_INFO_2A on heap
@@ -4279,12 +4461,11 @@ static BOOL WINSPOOL_GetDriverInfoFromReg(
}
/*****************************************************************************
- * WINSPOOL_GetPrinterDriver
+ * GetPrinterDriverW [WINSPOOL.@]
*/
-static BOOL WINSPOOL_GetPrinterDriver(HANDLE hPrinter, LPCWSTR pEnvironment,
- DWORD Level, LPBYTE pDriverInfo,
- DWORD cbBuf, LPDWORD pcbNeeded,
- BOOL unicode)
+BOOL WINAPI GetPrinterDriverW(HANDLE hPrinter, LPWSTR pEnvironment,
+ DWORD Level, LPBYTE pDriverInfo,
+ DWORD cbBuf, LPDWORD pcbNeeded)
{
LPCWSTR name;
WCHAR DriverName[100];
@@ -4346,7 +4527,7 @@ static BOOL WINSPOOL_GetPrinterDriver(HANDLE hPrinter, LPCWSTR pEnvironment,
if(!WINSPOOL_GetDriverInfoFromReg(hkeyDrivers, DriverName,
env, Level, pDriverInfo, ptr,
(cbBuf < size) ? 0 : cbBuf - size,
- &needed, unicode)) {
+ &needed, TRUE)) {
RegCloseKey(hkeyDrivers);
return FALSE;
}
@@ -4370,23 +4551,22 @@ BOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment,
BOOL ret;
UNICODE_STRING pEnvW;
PWSTR pwstrEnvW;
+ LPBYTE buf = NULL;
+
+ if (cbBuf)
+ buf = HeapAlloc(GetProcessHeap(), 0, cbBuf);
pwstrEnvW = asciitounicode(&pEnvW, pEnvironment);
- ret = WINSPOOL_GetPrinterDriver(hPrinter, pwstrEnvW, Level, pDriverInfo,
- cbBuf, pcbNeeded, FALSE);
+ ret = GetPrinterDriverW(hPrinter, pwstrEnvW, Level, buf,
+ cbBuf, pcbNeeded);
+ if (ret)
+ convert_driverinfo_W_to_A(pDriverInfo, buf, Level, cbBuf, 1);
+
+ HeapFree(GetProcessHeap(), 0, buf);
+
RtlFreeUnicodeString(&pEnvW);
return ret;
}
-/*****************************************************************************
- * GetPrinterDriverW [WINSPOOL.@]
- */
-BOOL WINAPI GetPrinterDriverW(HANDLE hPrinter, LPWSTR pEnvironment,
- DWORD Level, LPBYTE pDriverInfo,
- DWORD cbBuf, LPDWORD pcbNeeded)
-{
- return WINSPOOL_GetPrinterDriver(hPrinter, pEnvironment, Level,
- pDriverInfo, cbBuf, pcbNeeded, TRUE);
-}
/*****************************************************************************
* GetPrinterDriverDirectoryW [WINSPOOL.@]
diff --git a/dlls/winspool.drv/tests/info.c b/dlls/winspool.drv/tests/info.c
index a927c58..85bcf36 100644
--- a/dlls/winspool.drv/tests/info.c
+++ b/dlls/winspool.drv/tests/info.c
@@ -2348,7 +2348,6 @@ static void test_GetPrinterDriver(void)
{
DWORD double_needed;
ret = pGetPrinterDriverW(hprn, NULL, level, NULL, 0, &double_needed);
- todo_wine
ok(double_needed == needed, "GetPrinterDriverA returned different size %d than GetPrinterDriverW (%d)\n", needed, double_needed);
}
--
1.5.6.5
More information about the wine-patches
mailing list