gdi32: Get printer output file name in StartDoc.

This commit is contained in:
Piotr Caban 2022-11-21 12:45:33 +01:00 committed by Alexandre Julliard
parent 4e527045d5
commit 1cf1412a12
3 changed files with 53 additions and 8 deletions

View file

@ -2,7 +2,7 @@ EXTRADEFS = -D_GDI32_
MODULE = gdi32.dll MODULE = gdi32.dll
IMPORTLIB = gdi32 IMPORTLIB = gdi32
IMPORTS = user32 advapi32 win32u IMPORTS = user32 advapi32 win32u
DELAYIMPORTS = setupapi DELAYIMPORTS = setupapi winspool
C_SRCS = \ C_SRCS = \
dc.c \ dc.c \

View file

@ -199,8 +199,11 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
UNICODE_STRING device_str, output_str; UNICODE_STRING device_str, output_str;
driver_entry_point entry_point = NULL; driver_entry_point entry_point = NULL;
const WCHAR *display = NULL, *p; const WCHAR *display = NULL, *p;
WCHAR buf[300], *port = NULL;
BOOL is_display = FALSE; BOOL is_display = FALSE;
WCHAR buf[300]; HANDLE hspool = NULL;
DC_ATTR *dc_attr;
HDC ret;
if (!device || !get_driver_name( device, buf, 300 )) if (!device || !get_driver_name( device, buf, 300 ))
{ {
@ -212,6 +215,12 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
lstrcpyW(buf, driver); 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 )) if (is_display_device( driver ))
{ {
display = 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) ); ERR( "no driver found for %s\n", debugstr_w(buf) );
return 0; 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) if (display)
{ {
@ -247,14 +265,23 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
device_str.Buffer = (WCHAR *)device; 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); if (port)
output_str.Buffer = (WCHAR *)output; 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, return ret;
0, is_display, entry_point, NULL, NULL );
} }
/*********************************************************************** /***********************************************************************
@ -371,6 +398,10 @@ BOOL WINAPI DeleteDC( HDC hdc )
if (is_meta_dc( hdc )) return METADC_DeleteDC( hdc ); if (is_meta_dc( hdc )) return METADC_DeleteDC( hdc );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; 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 ); if (dc_attr->emf) EMFDC_DeleteDC( dc_attr );
return NtGdiDeleteObjectApp( hdc ); return NtGdiDeleteObjectApp( hdc );
} }
@ -2153,9 +2184,11 @@ BOOL WINAPI CancelDC(HDC hdc)
*/ */
INT WINAPI StartDocW( HDC hdc, const DOCINFOW *doc ) INT WINAPI StartDocW( HDC hdc, const DOCINFOW *doc )
{ {
WCHAR *output = NULL;
DC_ATTR *dc_attr; DC_ATTR *dc_attr;
ABORTPROC proc; ABORTPROC proc;
DOCINFOW info; DOCINFOW info;
INT ret;
TRACE("%p %p\n", hdc, doc); 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; proc = (ABORTPROC)(UINT_PTR)dc_attr->abort_proc;
if (proc && !proc( hdc, 0 )) return 0; 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;
} }
/*********************************************************************** /***********************************************************************

View file

@ -198,6 +198,8 @@ typedef struct DC_ATTR
RECTL emf_bounds; RECTL emf_bounds;
UINT64 emf; /* client EMF record pointer */ UINT64 emf; /* client EMF record pointer */
UINT64 abort_proc; /* AbortProc for printing */ UINT64 abort_proc; /* AbortProc for printing */
UINT64 hspool;
UINT64 output;
} DC_ATTR; } DC_ATTR;
struct font_enum_entry struct font_enum_entry