From 9f2512d836cc62204c7ef61b661a02682ecb34c0 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Wed, 17 Jun 2020 13:22:43 +0800 Subject: [PATCH] prntvpt: Add initial implementation of PTGetPrintCapabilities. Signed-off-by: Dmitry Timoshkov Signed-off-by: Alexandre Julliard --- dlls/prntvpt/main.c | 12 ++ dlls/prntvpt/prntvpt.spec | 2 +- dlls/prntvpt/prntvpt_private.h | 1 + dlls/prntvpt/ticket.c | 281 +++++++++++++++++++++++++++++++++ include/prntvpt.h | 1 + 5 files changed, 296 insertions(+), 1 deletion(-) diff --git a/dlls/prntvpt/main.c b/dlls/prntvpt/main.c index 2c27dc66893..197fb54022c 100644 --- a/dlls/prntvpt/main.c +++ b/dlls/prntvpt/main.c @@ -33,6 +33,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(prntvpt); +static WCHAR *heap_strdupW(const WCHAR *src) +{ + WCHAR *dst; + size_t len; + if (!src) return NULL; + len = (wcslen(src) + 1) * sizeof(WCHAR); + if ((dst = heap_alloc(len))) memcpy(dst, src, len); + return dst; +} + BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) { TRACE("(%p, %d, %p)\n", hinst, reason, reserved); @@ -70,6 +80,7 @@ HRESULT WINAPI PTCloseProvider(HPTPROVIDER provider) return E_HANDLE; prov->owner = 0; + heap_free(prov->name); ClosePrinter(prov->hprn); heap_free(prov); @@ -105,6 +116,7 @@ HRESULT WINAPI PTOpenProviderEx(const WCHAR *printer, DWORD max_version, DWORD p return HRESULT_FROM_WIN32(GetLastError()); } + prov->name = heap_strdupW(printer); prov->owner = GetCurrentThreadId(); *provider = (HPTPROVIDER)prov; *used_version = 1; diff --git a/dlls/prntvpt/prntvpt.spec b/dlls/prntvpt/prntvpt.spec index 9563d9ae370..95470143745 100644 --- a/dlls/prntvpt/prntvpt.spec +++ b/dlls/prntvpt/prntvpt.spec @@ -3,7 +3,7 @@ @ stdcall PTOpenProviderEx(wstr long long ptr ptr) @ stdcall PTCloseProvider(ptr) @ stub BindPTProviderThunk -@ stub PTGetPrintCapabilities +@ stdcall PTGetPrintCapabilities(ptr ptr ptr ptr) @ stdcall PTMergeAndValidatePrintTicket(ptr ptr ptr long ptr ptr) @ stdcall PTConvertPrintTicketToDevMode(ptr ptr long long ptr ptr ptr) @ stdcall PTConvertDevModeToPrintTicket(ptr long ptr long ptr) diff --git a/dlls/prntvpt/prntvpt_private.h b/dlls/prntvpt/prntvpt_private.h index c8d1c5ef34f..857b92f2024 100644 --- a/dlls/prntvpt/prntvpt_private.h +++ b/dlls/prntvpt/prntvpt_private.h @@ -19,6 +19,7 @@ struct prn_provider { DWORD owner; + WCHAR *name; HANDLE hprn; }; diff --git a/dlls/prntvpt/ticket.c b/dlls/prntvpt/ticket.c index 42cdec6ec07..132a117a249 100644 --- a/dlls/prntvpt/ticket.c +++ b/dlls/prntvpt/ticket.c @@ -845,6 +845,16 @@ static HRESULT create_ParameterRef(IXMLDOMElement *root, const WCHAR *name, IXML return add_attribute(*child, L"name", name); } +static HRESULT create_ParameterDef(IXMLDOMElement *root, const WCHAR *name, IXMLDOMElement **child) +{ + HRESULT hr; + + hr = create_element(root, L"psf:ParameterDef", child); + if (hr != S_OK) return hr; + + return add_attribute(*child, L"name", name); +} + static HRESULT create_ScoredProperty(IXMLDOMElement *root, const WCHAR *name, IXMLDOMElement **child) { HRESULT hr; @@ -1255,3 +1265,274 @@ HRESULT WINAPI PTMergeAndValidatePrintTicket(HPTPROVIDER provider, IStream *base hr = write_ticket(result, &ticket, scope); return hr ? hr : S_PT_NO_CONFLICT; } + +static HRESULT write_PageMediaSize_caps(const WCHAR *device, IXMLDOMElement *root) +{ + HRESULT hr = S_OK; + int count, i; + POINT *pt; + IXMLDOMElement *feature = NULL; + + FIXME("stub\n"); + + count = DeviceCapabilitiesW(device, NULL, DC_PAPERSIZE, NULL, NULL); + if (count <= 0) + return HRESULT_FROM_WIN32(GetLastError()); + + pt = heap_alloc(count * sizeof(*pt)); + if (!pt) return E_OUTOFMEMORY; + + count = DeviceCapabilitiesW(device, NULL, DC_PAPERSIZE, (LPWSTR)pt, NULL); + if (count <= 0) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto fail; + } + + hr = create_Feature(root, L"psk:PageMediaSize", &feature); + if (hr != S_OK) goto fail; + + for (i = 0; i < count; i++) + { + } + +fail: + if (feature) IXMLDOMElement_Release(feature); + heap_free(pt); + return hr; +} + +static HRESULT write_PageOutputColor_caps(const WCHAR *device, IXMLDOMElement *root) +{ + HRESULT hr = S_OK; + int color; + IXMLDOMElement *feature = NULL; + + FIXME("stub\n"); + + color = DeviceCapabilitiesW(device, NULL, DC_COLORDEVICE, NULL, NULL); + TRACE("DC_COLORDEVICE: %d\n", color); + + hr = create_Feature(root, L"psk:PageOutputColor", &feature); + if (hr != S_OK) goto fail; + +fail: + if (feature) IXMLDOMElement_Release(feature); + return hr; +} + +static HRESULT write_PageScaling_caps(const WCHAR *device, IXMLDOMElement *root) +{ + HRESULT hr = S_OK; + IXMLDOMElement *feature = NULL; + + FIXME("stub\n"); + + hr = create_Feature(root, L"psk:PageScaling", &feature); + if (hr != S_OK) goto fail; + +fail: + if (feature) IXMLDOMElement_Release(feature); + return hr; +} + +static HRESULT write_PageResolution_caps(const WCHAR *device, IXMLDOMElement *root) +{ + HRESULT hr = S_OK; + int count, i; + struct + { + LONG x; + LONG y; + } *res; + IXMLDOMElement *feature = NULL; + + FIXME("stub\n"); + + count = DeviceCapabilitiesW(device, NULL, DC_ENUMRESOLUTIONS, NULL, NULL); + if (count <= 0) + return HRESULT_FROM_WIN32(GetLastError()); + + res = heap_alloc(count * sizeof(*res)); + if (!res) return E_OUTOFMEMORY; + + count = DeviceCapabilitiesW(device, NULL, DC_ENUMRESOLUTIONS, (LPWSTR)res, NULL); + if (count <= 0) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto fail; + } + + hr = create_Feature(root, L"psk:PageResolution", &feature); + if (hr != S_OK) goto fail; + + for (i = 0; i < count; i++) + { + } + +fail: + if (feature) IXMLDOMElement_Release(feature); + heap_free(res); + return hr; +} + +static HRESULT write_PageOrientation_caps(const WCHAR *device, IXMLDOMElement *root) +{ + HRESULT hr = S_OK; + int landscape; + IXMLDOMElement *feature = NULL; + + FIXME("stub\n"); + + landscape = DeviceCapabilitiesW(device, NULL, DC_ORIENTATION, NULL, NULL); + TRACE("DC_ORIENTATION: %d\n", landscape); + + hr = create_Feature(root, L"psk:PageOrientation", &feature); + if (hr != S_OK) goto fail; + +fail: + if (feature) IXMLDOMElement_Release(feature); + return hr; +} + +static HRESULT write_DocumentCollate_caps(const WCHAR *device, IXMLDOMElement *root) +{ + HRESULT hr = S_OK; + int collate; + IXMLDOMElement *feature = NULL; + + FIXME("stub\n"); + + collate = DeviceCapabilitiesW(device, NULL, DC_COLLATE, NULL, NULL); + TRACE("DC_COLLATE: %d\n", collate); + + hr = create_Feature(root, L"psk:DocumentCollate", &feature); + if (hr != S_OK) goto fail; + +fail: + if (feature) IXMLDOMElement_Release(feature); + return hr; +} + +static HRESULT write_JobInputBin_caps(const WCHAR *device, IXMLDOMElement *root) +{ + HRESULT hr = S_OK; + int count, i; + WORD *bin; + IXMLDOMElement *feature = NULL; + + FIXME("stub\n"); + + count = DeviceCapabilitiesW(device, NULL, DC_BINS, NULL, NULL); + if (count <= 0) + return HRESULT_FROM_WIN32(GetLastError()); + + bin = heap_alloc(count * sizeof(*bin)); + if (!bin) return E_OUTOFMEMORY; + + count = DeviceCapabilitiesW(device, NULL, DC_BINS, (LPWSTR)bin, NULL); + if (count <= 0) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + goto fail; + } + + hr = create_Feature(root, L"psk:JobInputBin", &feature); + if (hr != S_OK) goto fail; + + for (i = 0; i < count; i++) + { + } + +fail: + if (feature) IXMLDOMElement_Release(feature); + heap_free(bin); + return hr; +} + +static HRESULT write_JobCopies_caps(const WCHAR *device, IXMLDOMElement *root) +{ + HRESULT hr = S_OK; + int copies; + IXMLDOMElement *feature = NULL; + + FIXME("stub\n"); + + copies = DeviceCapabilitiesW(device, NULL, DC_COPIES, NULL, NULL); + TRACE("DC_COPIES: %d\n", copies); + + hr = create_ParameterDef(root, L"psk:JobCopiesAllDocuments", &feature); + if (hr != S_OK) goto fail; + +fail: + if (feature) IXMLDOMElement_Release(feature); + return hr; +} + +static HRESULT write_print_capabilities(const WCHAR *device, IStream *stream) +{ + static const char xmldecl[] = "\r\n"; + HRESULT hr; + IXMLDOMDocument *doc; + IXMLDOMElement *root = NULL; + VARIANT var; + + hr = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, + &IID_IXMLDOMDocument, (void **)&doc); + if (hr != S_OK) return hr; + + hr = IXMLDOMDocument_createElement(doc, (BSTR)L"psf:PrintCapabilities", &root); + if (hr != S_OK) goto fail; + + hr = IXMLDOMDocument_appendChild(doc, (IXMLDOMNode *)root, NULL); + if (hr != S_OK) goto fail; + + hr = write_attributes(root); + if (hr != S_OK) goto fail; + + hr = write_PageMediaSize_caps(device, root); + if (hr != S_OK) goto fail; + hr = write_PageOutputColor_caps(device, root); + if (hr != S_OK) goto fail; + hr = write_PageScaling_caps(device, root); + if (hr != S_OK) goto fail; + hr = write_PageResolution_caps(device, root); + if (hr != S_OK) goto fail; + hr = write_PageOrientation_caps(device, root); + if (hr != S_OK) goto fail; + hr = write_DocumentCollate_caps(device, root); + if (hr != S_OK) goto fail; + hr = write_JobInputBin_caps(device, root); + if (hr != S_OK) goto fail; + hr = write_JobCopies_caps(device, root); + if (hr != S_OK) goto fail; + + hr = IStream_Write(stream, xmldecl, strlen(xmldecl), NULL); + if (hr != S_OK) goto fail; + + V_VT(&var) = VT_UNKNOWN; + V_UNKNOWN(&var) = (IUnknown *)stream; + hr = IXMLDOMDocument_save(doc, var); + +fail: + if (root) IXMLDOMElement_Release(root); + IXMLDOMDocument_Release(doc); + return hr; +} + +HRESULT WINAPI PTGetPrintCapabilities(HPTPROVIDER provider, IStream *stream, IStream *caps, BSTR *error) +{ + struct prn_provider *prov = (struct prn_provider *)provider; + struct ticket ticket; + HRESULT hr; + + TRACE("%p,%p,%p,%p\n", provider, stream, caps, error); + + if (!is_valid_provider(provider) || !stream || !caps) + return E_INVALIDARG; + + hr = parse_ticket(stream, kPTJobScope, &ticket); + if (hr != S_OK) return hr; + + return write_print_capabilities(prov->name, caps); +} diff --git a/include/prntvpt.h b/include/prntvpt.h index 94b047d8c76..e060a26190a 100644 --- a/include/prntvpt.h +++ b/include/prntvpt.h @@ -47,6 +47,7 @@ HRESULT WINAPI PTOpenProviderEx(const WCHAR *printer, DWORD max_version, DWORD p HRESULT WINAPI PTCloseProvider(HPTPROVIDER); HRESULT WINAPI PTConvertDevModeToPrintTicket(HPTPROVIDER, ULONG, PDEVMODEW, EPrintTicketScope, IStream *); HRESULT WINAPI PTConvertPrintTicketToDevMode(HPTPROVIDER, IStream *, EDefaultDevmodeType, EPrintTicketScope, ULONG *, PDEVMODEW *, BSTR *); +HRESULT WINAPI PTGetPrintCapabilities(HPTPROVIDER, IStream *, IStream *, BSTR *); HRESULT WINAPI PTMergeAndValidatePrintTicket(HPTPROVIDER, IStream *, IStream *, EPrintTicketScope, IStream *, BSTR *); HRESULT WINAPI PTReleaseMemory(PVOID);