From dcef05b6f1efc9d43825e8f1de6c0e9ad06c8537 Mon Sep 17 00:00:00 2001 From: Vitaly Perov Date: Thu, 23 Sep 2010 15:53:21 +0300 Subject: [PATCH] comdlg32: Add basic implementation of PrintDlgExA. --- dlls/comdlg32/printdlg.c | 89 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 4 deletions(-) diff --git a/dlls/comdlg32/printdlg.c b/dlls/comdlg32/printdlg.c index 0bb3a7bc603..05d94010941 100644 --- a/dlls/comdlg32/printdlg.c +++ b/dlls/comdlg32/printdlg.c @@ -5,6 +5,7 @@ * Copyright 1996 Albrecht Kleine * Copyright 1999 Klaas van Gend * Copyright 2000 Huw D M Davies + * Copyright 2010 Vitaly Perov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -3752,14 +3753,94 @@ BOOL WINAPI PageSetupDlgW(LPPAGESETUPDLGW setupdlg) */ HRESULT WINAPI PrintDlgExA(LPPRINTDLGEXA lppd) { + DWORD ret = E_FAIL; + LPVOID ptr; - FIXME("(%p) stub\n", lppd); - if ((lppd == NULL) || (lppd->lStructSize != sizeof(PRINTDLGEXA))) { + FIXME("(%p) not fully implemented\n", lppd); + if ((lppd == NULL) || (lppd->lStructSize != sizeof(PRINTDLGEXA))) return E_INVALIDARG; - } - if (!IsWindow(lppd->hwndOwner)) { + if (!IsWindow(lppd->hwndOwner)) return E_HANDLE; + + if (lppd->Flags & PD_RETURNDEFAULT) + { + PRINTER_INFO_2A *pbuf; + DRIVER_INFO_2A *dbuf; + HANDLE hprn; + DWORD needed = 1024; + BOOL bRet; + + if (lppd->hDevMode || lppd->hDevNames) + { + WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n"); + COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); + return E_INVALIDARG; + } + if (!PRINTDLG_OpenDefaultPrinter(&hprn)) + { + WARN("Can't find default printer\n"); + COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); + return E_FAIL; + } + + pbuf = HeapAlloc(GetProcessHeap(), 0, needed); + bRet = GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed); + if (!bRet && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) + { + HeapFree(GetProcessHeap(), 0, pbuf); + pbuf = HeapAlloc(GetProcessHeap(), 0, needed); + bRet = GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed); + } + if (!bRet) + { + HeapFree(GetProcessHeap(), 0, pbuf); + ClosePrinter(hprn); + return E_FAIL; + } + + needed = 1024; + dbuf = HeapAlloc(GetProcessHeap(), 0, needed); + bRet = GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed); + if (!bRet && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) + { + HeapFree(GetProcessHeap(), 0, dbuf); + dbuf = HeapAlloc(GetProcessHeap(), 0, needed); + bRet = GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed); + } + if (!bRet) + { + ERR("GetPrinterDriverŠ failed, last error %d, fix your config for printer %s!\n", + GetLastError(), pbuf->pPrinterName); + HeapFree(GetProcessHeap(), 0, dbuf); + HeapFree(GetProcessHeap(), 0, pbuf); + COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); + ClosePrinter(hprn); + return E_FAIL; + } + ClosePrinter(hprn); + + PRINTDLG_CreateDevNames(&(lppd->hDevNames), + dbuf->pDriverPath, + pbuf->pPrinterName, + pbuf->pPortName); + lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize + + pbuf->pDevMode->dmDriverExtra); + if (lppd->hDevMode) + { + ptr = GlobalLock(lppd->hDevMode); + if (ptr) + { + memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize + + pbuf->pDevMode->dmDriverExtra); + GlobalUnlock(lppd->hDevMode); + ret = S_OK; + } + } + HeapFree(GetProcessHeap(), 0, pbuf); + HeapFree(GetProcessHeap(), 0, dbuf); + + return ret; } return E_NOTIMPL; -- 2.11.4.GIT