diff --git a/sdk/include/reactos/idl/winspool.idl b/sdk/include/reactos/idl/winspool.idl index 558b0302f4e..63c7527d808 100644 --- a/sdk/include/reactos/idl/winspool.idl +++ b/sdk/include/reactos/idl/winspool.idl @@ -834,11 +834,11 @@ typedef [switch_type(DWORD)] union _WINSPOOL_V2_UREPLY_PRINTER } WINSPOOL_V2_UREPLY_PRINTER; -typedef struct _WINSPOOL_FILE_INFO +typedef struct _WINSPOOL_FILE_INFO_1 { - BOOL bInheritHandle; - HANDLE hSpoolFileHandle; - DWORD dwOptions; + BOOL bInheritHandle; + WINSPOOL_HANDLE hSpoolFileHandle; + DWORD dwOptions; } WINSPOOL_FILE_INFO_1; @@ -1575,22 +1575,50 @@ interface winspool { /* TODO */ ); - /* Function 0x5B (TODO) */ + /* Function 0x5B */ DWORD _RpcGetSpoolFileInfo( - /* TODO */ + [in] WINSPOOL_PRINTER_HANDLE hPrinter, + [in] WINSPOOL_HANDLE hProcessHandle, + [in] DWORD Level, + [in] WINSPOOL_FILE_INFO_1* pFileInfo, + [in] DWORD dwSize, + [in] DWORD* dwNeeded ); - /* Function 0x5C (TODO) */ + /* Function 0x5C */ DWORD _RpcCommitSpoolData( - /* TODO */ + [in] WINSPOOL_PRINTER_HANDLE hPrinter, + [in] WINSPOOL_HANDLE hProcessHandle, + [in] DWORD cbCommit, + [in] DWORD Level, + [in] WINSPOOL_FILE_INFO_1* pFileInfo, + [in] DWORD dwSize, + [in] DWORD* dwNeeded ); - /* Function 0x5D (TODO) */ - DWORD _RpcCloseSpoolFileHandle( - /* TODO */ + /* Function 0x5D */ + DWORD _RpcGetSpoolFileInfo2( + [in] WINSPOOL_PRINTER_HANDLE hPrinter, + [in] DWORD dwProcessId, + [in] DWORD Level, + [in] WINSPOOL_FILE_INFO_CONTAINER* pFileInfoContainer ); /* Function 0x5E */ + DWORD _RpcCommitSpoolData2( + [in] WINSPOOL_PRINTER_HANDLE hPrinter, + [in] DWORD dwProcessId, + [in] DWORD cbCommit, + [in] DWORD Level, + [in] WINSPOOL_FILE_INFO_CONTAINER* pFileInfoContainer + ); + + /* Function 0x5F */ + DWORD _RpcCloseSpoolFileHandle( + [in] WINSPOOL_PRINTER_HANDLE hPrinter + ); + + /* Function 0x60 */ DWORD _RpcFlushPrinter( [in] WINSPOOL_PRINTER_HANDLE hPrinter, [in, size_is(cbBuf)] BYTE* pBuf, @@ -1599,7 +1627,7 @@ interface winspool { [in] DWORD cSleep ); - /* Function 0x5F */ + /* Function 0x61 */ DWORD _RpcSendRecvBidiData( [in] WINSPOOL_PRINTER_HANDLE hPrinter, [in, string, unique] const WCHAR* pAction, @@ -1607,7 +1635,7 @@ interface winspool { [out] WINSPOOL_BIDI_RESPONSE_CONTAINER** ppRespData ); - /* Function 0x60 (TODO) */ + /* Function 0x62 (TODO) */ DWORD _RpcAddDriverCatalog( /* TODO */ ); diff --git a/win32ss/printing/base/spoolss/CMakeLists.txt b/win32ss/printing/base/spoolss/CMakeLists.txt index e6c02eab86d..cea56de0879 100644 --- a/win32ss/printing/base/spoolss/CMakeLists.txt +++ b/win32ss/printing/base/spoolss/CMakeLists.txt @@ -12,6 +12,7 @@ list(APPEND SOURCE printerdata.c printers.c printprocessors.c + spoolfile.c tools.c) list(APPEND PCH_SKIP_SOURCE diff --git a/win32ss/printing/base/spoolss/precomp.h b/win32ss/printing/base/spoolss/precomp.h index 3a859aa2d7c..ee373e267d3 100644 --- a/win32ss/printing/base/spoolss/precomp.h +++ b/win32ss/printing/base/spoolss/precomp.h @@ -52,4 +52,12 @@ SPOOLSS_PRINTER_HANDLE, *PSPOOLSS_PRINTER_HANDLE; extern HANDLE hProcessHeap; extern LIST_ENTRY PrintProviderList; +// spoolfile.c +typedef struct _FILE_INFO_1 +{ + BOOL bInheritHandle; + HANDLE hSpoolFileHandle; + DWORD dwOptions; +} FILE_INFO_1, *PFILE_INFO_1; + #endif diff --git a/win32ss/printing/base/spoolss/spoolfile.c b/win32ss/printing/base/spoolss/spoolfile.c new file mode 100644 index 00000000000..5d5aa965fb5 --- /dev/null +++ b/win32ss/printing/base/spoolss/spoolfile.c @@ -0,0 +1,88 @@ +/* + * PROJECT: ReactOS Spooler Router + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Functions related to Spool File + * COPYRIGHT: Copyright 1998-2022 ReactOS + */ + +#include "precomp.h" + +BOOL WINAPI +SplGetSpoolFileInfo( + HANDLE hPrinter, + HANDLE hProcessHandle, + DWORD Level, + PFILE_INFO_1 pFileInfo, + DWORD dwSize, + DWORD* dwNeeded ) +{ + BOOL Ret; + HANDLE hHandle, hSourceProcessHandle; + PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter; + + // Sanity checks. + if (!pHandle) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + hSourceProcessHandle = GetCurrentProcess(); + + // No Local? Ok, what ever... + + Ret = pHandle->pPrintProvider->PrintProvider.fpGetSpoolFileInfo( pHandle->hPrinter, + NULL, + &hHandle, + hProcessHandle, + hSourceProcessHandle ); + if ( Ret ) + { + pFileInfo->hSpoolFileHandle = hHandle; + pFileInfo->bInheritHandle = TRUE; + pFileInfo->dwOptions = DUPLICATE_CLOSE_SOURCE; + } + + return Ret; +} + +BOOL WINAPI +SplCommitSpoolData( + HANDLE hPrinter, + HANDLE hProcessHandle, + DWORD cbCommit, + DWORD Level, + PFILE_INFO_1 pFileInfo, + DWORD dwSize, + DWORD* dwNeeded ) +{ + PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter; + + // Sanity checks. + if (!pHandle) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + pFileInfo->hSpoolFileHandle = INVALID_HANDLE_VALUE; + pFileInfo->bInheritHandle = TRUE; + pFileInfo->dwOptions = DUPLICATE_CLOSE_SOURCE; + + return pHandle->pPrintProvider->PrintProvider.fpCommitSpoolData( hPrinter, cbCommit ); +} + +BOOL WINAPI +SplCloseSpoolFileHandle( HANDLE hPrinter ) +{ + PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter; + + // Sanity checks. + if (!pHandle) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + return pHandle->pPrintProvider->PrintProvider.fpCloseSpoolFileHandle( pHandle->hPrinter ); +} diff --git a/win32ss/printing/base/spoolss/spoolss.spec b/win32ss/printing/base/spoolss/spoolss.spec index 87e136c9a41..2ea70ea4440 100644 --- a/win32ss/printing/base/spoolss/spoolss.spec +++ b/win32ss/printing/base/spoolss/spoolss.spec @@ -142,10 +142,10 @@ @ stdcall SetPrinterDataExW(long wstr wstr long ptr long) @ stdcall SetPrinterDataW(long wstr long ptr long) @ stub SetPrinterW -@ stub SplCloseSpoolFileHandle -@ stub SplCommitSpoolData +@ stdcall SplCloseSpoolFileHandle(ptr) +@ stdcall SplCommitSpoolData(ptr ptr long long ptr long ptr) @ stub SplDriverUnloadComplete -@ stub SplGetSpoolFileInfo +@ stdcall SplGetSpoolFileInfo(ptr ptr long ptr long ptr) @ stdcall SplInitializeWinSpoolDrv(ptr) @ stub SplIsSessionZero @ stdcall SplIsUpgrade() diff --git a/win32ss/printing/base/spoolsv/CMakeLists.txt b/win32ss/printing/base/spoolsv/CMakeLists.txt index d2e8ed1026c..2fadb38a0cb 100644 --- a/win32ss/printing/base/spoolsv/CMakeLists.txt +++ b/win32ss/printing/base/spoolsv/CMakeLists.txt @@ -18,6 +18,7 @@ list(APPEND SOURCE printproviders.c rpcserver.c rpcstubs.c + spoolfile.c xcv.c ${CMAKE_CURRENT_BINARY_DIR}/winspool_s.c) diff --git a/win32ss/printing/base/spoolsv/precomp.h b/win32ss/printing/base/spoolsv/precomp.h index 5ab518a43c6..79febdd6392 100644 --- a/win32ss/printing/base/spoolsv/precomp.h +++ b/win32ss/printing/base/spoolsv/precomp.h @@ -28,4 +28,27 @@ WINE_DEFAULT_DEBUG_CHANNEL(spoolsv); // rpcserver.c DWORD WINAPI LrpcThreadProc(LPVOID lpParameter); +// spoolfile.c +BOOL WINAPI +SplGetSpoolFileInfo( + HANDLE hPrinter, + HANDLE hProcessHandle, + DWORD Level, + WINSPOOL_FILE_INFO_1 *pFileInfo, + DWORD dwSize, + DWORD* dwNeeded ); + +BOOL WINAPI +SplCommitSpoolData( + HANDLE hPrinter, + HANDLE hProcessHandle, + DWORD cbCommit, + DWORD Level, + WINSPOOL_FILE_INFO_1 *pFileInfo, + DWORD dwSize, + DWORD* dwNeeded ); + +BOOL WINAPI +SplCloseSpoolFileHandle( HANDLE hPrinter ); + #endif diff --git a/win32ss/printing/base/spoolsv/rpcstubs.c b/win32ss/printing/base/spoolsv/rpcstubs.c index 41088b6c012..f1a4cabd48d 100644 --- a/win32ss/printing/base/spoolsv/rpcstubs.c +++ b/win32ss/printing/base/spoolsv/rpcstubs.c @@ -105,27 +105,6 @@ _RpcSplOpenPrinter(VOID) return ERROR_INVALID_FUNCTION; } -DWORD -_RpcGetSpoolFileInfo(VOID) -{ - UNIMPLEMENTED; - return ERROR_INVALID_FUNCTION; -} - -DWORD -_RpcCommitSpoolData(VOID) -{ - UNIMPLEMENTED; - return ERROR_INVALID_FUNCTION; -} - -DWORD -_RpcCloseSpoolFileHandle(VOID) -{ - UNIMPLEMENTED; - return ERROR_INVALID_FUNCTION; -} - DWORD _RpcSendRecvBidiData(WINSPOOL_PRINTER_HANDLE hPrinter, const WCHAR* pAction, WINSPOOL_BIDI_REQUEST_CONTAINER* pReqData, WINSPOOL_BIDI_RESPONSE_CONTAINER** ppRespData) { diff --git a/win32ss/printing/base/spoolsv/spoolfile.c b/win32ss/printing/base/spoolsv/spoolfile.c new file mode 100644 index 00000000000..67e808525d0 --- /dev/null +++ b/win32ss/printing/base/spoolsv/spoolfile.c @@ -0,0 +1,120 @@ +/* + * PROJECT: ReactOS Print Spooler Service + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Spool File RPC calls + * COPYRIGHT: Copyright 2020 ReactOS + */ + +#include "precomp.h" + +DWORD +_RpcGetSpoolFileInfo( WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_HANDLE hProcessHandle, DWORD Level, WINSPOOL_FILE_INFO_1* pFileInfo, DWORD dwSize, DWORD* dwNeeded ) +{ + DWORD dwErrorCode; + + dwErrorCode = RpcImpersonateClient(NULL); + if (dwErrorCode != ERROR_SUCCESS) + { + ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); + return dwErrorCode; + } + + if (!SplGetSpoolFileInfo( hPrinter, hProcessHandle, Level, pFileInfo, dwSize, dwNeeded ) ) + dwErrorCode = GetLastError(); + + RpcRevertToSelf(); + return dwErrorCode; +} + +DWORD +_RpcCommitSpoolData( WINSPOOL_PRINTER_HANDLE hPrinter, WINSPOOL_HANDLE hProcessHandle, DWORD cbCommit, DWORD Level, WINSPOOL_FILE_INFO_1* pFileInfo, DWORD dwSize, DWORD* dwNeeded ) +{ + DWORD dwErrorCode; + + dwErrorCode = RpcImpersonateClient(NULL); + if (dwErrorCode != ERROR_SUCCESS) + { + ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); + return dwErrorCode; + } + + if (!SplCommitSpoolData( hPrinter, hProcessHandle, cbCommit, Level, pFileInfo, dwSize, dwNeeded ) ) + dwErrorCode = GetLastError(); + + RpcRevertToSelf(); + return dwErrorCode; +} + +DWORD +_RpcGetSpoolFileInfo2( WINSPOOL_PRINTER_HANDLE hPrinter, DWORD dwProcessId, DWORD Level, WINSPOOL_FILE_INFO_CONTAINER* pFileInfoContainer ) +{ + DWORD dwErrorCode, dwNeeded = 0; + HANDLE hProcessHandle; + + dwErrorCode = RpcImpersonateClient(NULL); + if (dwErrorCode != ERROR_SUCCESS) + { + ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); + return dwErrorCode; + } + + hProcessHandle = OpenProcess( PROCESS_DUP_HANDLE, FALSE, dwProcessId ); + + + if (!SplGetSpoolFileInfo( hPrinter, hProcessHandle, Level, pFileInfoContainer->FileInfo.pFileInfo1, sizeof(WINSPOOL_FILE_INFO_1), &dwNeeded ) ) + dwErrorCode = GetLastError(); + + if ( hProcessHandle ) + { + CloseHandle( hProcessHandle ); + } + + RpcRevertToSelf(); + return dwErrorCode; +} + +DWORD +_RpcCommitSpoolData2( WINSPOOL_PRINTER_HANDLE hPrinter, DWORD dwProcessId, DWORD cbCommit, DWORD Level, WINSPOOL_FILE_INFO_CONTAINER* pFileInfoContainer ) +{ + DWORD dwErrorCode, dwNeeded = 0; + HANDLE hProcessHandle; + + dwErrorCode = RpcImpersonateClient(NULL); + if (dwErrorCode != ERROR_SUCCESS) + { + ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); + return dwErrorCode; + } + + hProcessHandle = OpenProcess( PROCESS_DUP_HANDLE, FALSE, dwProcessId ); + + if (!SplCommitSpoolData( hPrinter, hProcessHandle, cbCommit, Level, pFileInfoContainer->FileInfo.pFileInfo1, sizeof(WINSPOOL_FILE_INFO_1), &dwNeeded ) ) + dwErrorCode = GetLastError(); + + if ( hProcessHandle ) + { + CloseHandle( hProcessHandle ); + } + + RpcRevertToSelf(); + return dwErrorCode; +} + +DWORD +_RpcCloseSpoolFileHandle( WINSPOOL_PRINTER_HANDLE hPrinter ) +{ + DWORD dwErrorCode; + + dwErrorCode = RpcImpersonateClient(NULL); + if (dwErrorCode != ERROR_SUCCESS) + { + ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); + return dwErrorCode; + } + + if (!SplCloseSpoolFileHandle( hPrinter ) ) + dwErrorCode = GetLastError(); + + RpcRevertToSelf(); + return dwErrorCode; +} diff --git a/win32ss/printing/base/winspool/winspool.spec b/win32ss/printing/base/winspool/winspool.spec index 318a2df8ca9..419354dfc32 100644 --- a/win32ss/printing/base/winspool/winspool.spec +++ b/win32ss/printing/base/winspool/winspool.spec @@ -172,7 +172,7 @@ 271 stdcall ResetPrinterA(ptr ptr) 272 stdcall ResetPrinterW(ptr ptr) 273 stdcall ScheduleJob(ptr long) -274 stub SeekPrinter +274 stdcall -stub SeekPrinter(ptr int64 ptr long long) 275 stub SetAllocFailCount 276 stdcall SetFormA(ptr str long str) 277 stdcall SetFormW(ptr str long str) diff --git a/win32ss/printing/providers/localspl/CMakeLists.txt b/win32ss/printing/providers/localspl/CMakeLists.txt index bd6f5e3ca94..b8cd309fc0a 100644 --- a/win32ss/printing/providers/localspl/CMakeLists.txt +++ b/win32ss/printing/providers/localspl/CMakeLists.txt @@ -14,6 +14,7 @@ list(APPEND SOURCE printers.c printingthread.c printprocessors.c + spoolfile.c tools.c) add_library(localspl MODULE diff --git a/win32ss/printing/providers/localspl/main.c b/win32ss/printing/providers/localspl/main.c index 7c39ec2cf09..0a47398ad72 100644 --- a/win32ss/printing/providers/localspl/main.c +++ b/win32ss/printing/providers/localspl/main.c @@ -112,9 +112,9 @@ static const PRINTPROVIDOR _PrintProviderFunctions = { NULL, // fpAddPrinterDriverEx NULL, // fpSplReadPrinter NULL, // fpDriverUnloadComplete - NULL, // fpGetSpoolFileInfo - NULL, // fpCommitSpoolData - NULL, // fpCloseSpoolFileHandle + LocalGetSpoolFileInfo, // fpGetSpoolFileInfo + LocalCommitSpoolData, // fpCommitSpoolData + LocalCloseSpoolFileHandle, // fpCloseSpoolFileHandle NULL, // fpFlushPrinter NULL, // fpSendRecvBidiData NULL, // fpAddDriverCatalog diff --git a/win32ss/printing/providers/localspl/precomp.h b/win32ss/printing/providers/localspl/precomp.h index 1b9a2d55400..91a7f095cb6 100644 --- a/win32ss/printing/providers/localspl/precomp.h +++ b/win32ss/printing/providers/localspl/precomp.h @@ -316,6 +316,11 @@ BOOL WINAPI LocalEnumPrintProcessorDatatypes(LPWSTR pName, LPWSTR pPrintProcesso BOOL WINAPI LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned); BOOL WINAPI LocalGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded); +// spoolfile.c +BOOL WINAPI LocalGetSpoolFileInfo(HANDLE hPrinter,LPWSTR *pSpoolDir,LPHANDLE phFile,HANDLE hSpoolerProcess,HANDLE hAppProcess); +BOOL WINAPI LocalCommitSpoolData(HANDLE hPrinter,DWORD cbCommit); +BOOL WINAPI LocalCloseSpoolFileHandle(HANDLE hPrinter); + // tools.c PWSTR AllocAndRegQueryWSZ(HKEY hKey, PCWSTR pwszValueName); PDEVMODEW DuplicateDevMode(PDEVMODEW pInput); diff --git a/win32ss/printing/providers/localspl/spoolfile.c b/win32ss/printing/providers/localspl/spoolfile.c new file mode 100644 index 00000000000..c919aead2d4 --- /dev/null +++ b/win32ss/printing/providers/localspl/spoolfile.c @@ -0,0 +1,35 @@ +/* + * PROJECT: ReactOS Local Spooler + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Functions related to Spool Files and printing + * COPYRIGHT: Copyright 1998-2020 ReactOS) + */ + +#include "precomp.h" + +BOOL WINAPI +LocalGetSpoolFileInfo( + HANDLE hPrinter, + LPWSTR *pSpoolDir, + LPHANDLE phFile, + HANDLE hSpoolerProcess, + HANDLE hAppProcess ) +{ + FIXME("LocalGetSpoolFileInfo(%p, %S, %p, %p, %p)\n", hPrinter, pSpoolDir, phFile, hSpoolerProcess, hAppProcess); + return FALSE; +} + +BOOL WINAPI +LocalCommitSpoolData( HANDLE hPrinter, DWORD cbCommit) +{ + FIXME("LocalCommitSpoolData(%p, %lu)\n", hPrinter, cbCommit); + return FALSE; +} + +BOOL WINAPI +LocalCloseSpoolFileHandle( HANDLE hPrinter) +{ + FIXME("LocalCloseSpoolFileHandle(%p)\n", hPrinter); + return FALSE; +} +