diff --git a/dlls/gdi32/Makefile.in b/dlls/gdi32/Makefile.in index ce877995ee2..9e6d53dc219 100644 --- a/dlls/gdi32/Makefile.in +++ b/dlls/gdi32/Makefile.in @@ -2,7 +2,7 @@ EXTRADEFS = -D_GDI32_ MODULE = gdi32.dll IMPORTLIB = gdi32 IMPORTS = user32 advapi32 win32u -DELAYIMPORTS = setupapi +DELAYIMPORTS = setupapi winspool C_SRCS = \ dc.c \ diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c index 0cdeff19e05..6ec11650d27 100644 --- a/dlls/gdi32/dc.c +++ b/dlls/gdi32/dc.c @@ -199,8 +199,11 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, UNICODE_STRING device_str, output_str; driver_entry_point entry_point = NULL; const WCHAR *display = NULL, *p; + WCHAR buf[300], *port = NULL; BOOL is_display = FALSE; - WCHAR buf[300]; + HANDLE hspool = NULL; + DC_ATTR *dc_attr; + HDC ret; if (!device || !get_driver_name( device, buf, 300 )) { @@ -212,6 +215,12 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, lstrcpyW(buf, driver); } + if (output) + { + output_str.Length = output_str.MaximumLength = lstrlenW(output) * sizeof(WCHAR); + output_str.Buffer = (WCHAR *)output; + } + if (is_display_device( driver )) { display = driver; @@ -231,6 +240,15 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, ERR( "no driver found for %s\n", debugstr_w(buf) ); return 0; } + else if (!OpenPrinterW( (WCHAR *)device, &hspool, NULL )) + { + return 0; + } + else if (output && !(port = HeapAlloc( GetProcessHeap(), 0, output_str.Length ))) + { + ClosePrinter( hspool ); + return 0; + } if (display) { @@ -247,14 +265,23 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, device_str.Buffer = (WCHAR *)device; } - if (output) + ret = NtGdiOpenDCW( device || display ? &device_str : NULL, devmode, output ? &output_str : NULL, + 0, is_display, entry_point, NULL, NULL ); + + if (ret && hspool && (dc_attr = get_dc_attr( ret ))) { - output_str.Length = output_str.MaximumLength = lstrlenW(output) * sizeof(WCHAR); - output_str.Buffer = (WCHAR *)output; + if (port) + memcpy( port, output, output_str.Length ); + dc_attr->hspool = HandleToULong( hspool ); + dc_attr->output = (ULONG_PTR)port; + } + else if (hspool) + { + ClosePrinter( hspool ); + HeapFree( GetProcessHeap(), 0, port ); } - return NtGdiOpenDCW( device || display ? &device_str : NULL, devmode, output ? &output_str : NULL, - 0, is_display, entry_point, NULL, NULL ); + return ret; } /*********************************************************************** @@ -371,6 +398,10 @@ BOOL WINAPI DeleteDC( HDC hdc ) if (is_meta_dc( hdc )) return METADC_DeleteDC( hdc ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + HeapFree( GetProcessHeap(), 0, (WCHAR *)(ULONG_PTR)dc_attr->output ); + dc_attr->output = 0; + if (dc_attr->hspool) ClosePrinter( ULongToHandle(dc_attr->hspool) ); + dc_attr->hspool = 0; if (dc_attr->emf) EMFDC_DeleteDC( dc_attr ); return NtGdiDeleteObjectApp( hdc ); } @@ -2153,9 +2184,11 @@ BOOL WINAPI CancelDC(HDC hdc) */ INT WINAPI StartDocW( HDC hdc, const DOCINFOW *doc ) { + WCHAR *output = NULL; DC_ATTR *dc_attr; ABORTPROC proc; DOCINFOW info; + INT ret; TRACE("%p %p\n", hdc, doc); @@ -2177,7 +2210,17 @@ INT WINAPI StartDocW( HDC hdc, const DOCINFOW *doc ) proc = (ABORTPROC)(UINT_PTR)dc_attr->abort_proc; if (proc && !proc( hdc, 0 )) return 0; - return NtGdiStartDoc( hdc, &info, NULL, 0 ); + + if (dc_attr->hspool) + { + if (!info.lpszOutput) info.lpszOutput = (const WCHAR *)(ULONG_PTR)dc_attr->output; + output = StartDocDlgW( ULongToHandle( dc_attr->hspool ), &info ); + if (output) info.lpszOutput = output; + } + + ret = NtGdiStartDoc( hdc, &info, NULL, 0 ); + HeapFree( GetProcessHeap(), 0, output ); + return ret; } /*********************************************************************** diff --git a/include/ntgdi.h b/include/ntgdi.h index 24db499c404..1aa5cad468f 100644 --- a/include/ntgdi.h +++ b/include/ntgdi.h @@ -198,6 +198,8 @@ typedef struct DC_ATTR RECTL emf_bounds; UINT64 emf; /* client EMF record pointer */ UINT64 abort_proc; /* AbortProc for printing */ + UINT64 hspool; + UINT64 output; } DC_ATTR; struct font_enum_entry