mirror of
https://github.com/reactos/reactos.git
synced 2024-07-31 00:28:56 +00:00
- Add a dummy winspool.drv SpoolerInit doing an RPC call to a dummy RpcSpoolerInit, which itself passes the call to a dummy spoolss.dll SpoolerInit.
This serves as an example to show how I expect most spooler functions to work. - Implement the publicly exported and fundamental RevertToPrinterSelf and ImpersonatePrinterClient spoolss.dll functions. - Fix WINSPOOL_HANDLE_bind. - Fix build with GCC. svn path=/branches/colins-printing-for-freedom/; revision=67693
This commit is contained in:
parent
26cb1650bc
commit
2ffd28325a
|
@ -2,6 +2,7 @@
|
||||||
spec2def(spoolss spoolss.spec ADD_IMPORTLIB)
|
spec2def(spoolss spoolss.spec ADD_IMPORTLIB)
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
|
context.c
|
||||||
main.c
|
main.c
|
||||||
precomp.h)
|
precomp.h)
|
||||||
|
|
||||||
|
@ -13,6 +14,6 @@ add_library(spoolss SHARED
|
||||||
|
|
||||||
set_module_type(spoolss win32dll UNICODE)
|
set_module_type(spoolss win32dll UNICODE)
|
||||||
target_link_libraries(spoolss wine)
|
target_link_libraries(spoolss wine)
|
||||||
add_importlibs(spoolss kernel32 msvcrt ntdll)
|
add_importlibs(spoolss msvcrt kernel32 advapi32 ntdll)
|
||||||
add_pch(spoolss precomp.h SOURCE)
|
add_pch(spoolss precomp.h SOURCE)
|
||||||
add_cd_file(TARGET spoolss DESTINATION reactos/system32 FOR all)
|
add_cd_file(TARGET spoolss DESTINATION reactos/system32 FOR all)
|
||||||
|
|
62
reactos/win32ss/printing/base/spoolss/context.c
Normal file
62
reactos/win32ss/printing/base/spoolss/context.c
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Spooler Router
|
||||||
|
* LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software Foundation
|
||||||
|
* PURPOSE: Functions related to switching between security contexts
|
||||||
|
* COPYRIGHT: Copyright 2015 Colin Finck <colin@reactos.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precomp.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see RevertToPrinterSelf
|
||||||
|
*/
|
||||||
|
BOOL WINAPI
|
||||||
|
ImpersonatePrinterClient(HANDLE hToken)
|
||||||
|
{
|
||||||
|
if (!hToken)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SetThreadToken(NULL, hToken))
|
||||||
|
{
|
||||||
|
ERR("SetThreadToken failed with error %u!\n", GetLastError());
|
||||||
|
CloseHandle(hToken);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hToken);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RevertToPrinterSelf reverts the security context from the current user's context back to the process context.
|
||||||
|
* As spoolss.dll is used by spoolsv.exe, this is usually the SYSTEM security context.
|
||||||
|
*
|
||||||
|
* Unlike the traditional ImpersonateClient and then RevertToSelf approach, we do it the other way round here,
|
||||||
|
* because spoolss.dll is delay-loaded by spoolsv.exe in the current user's context. Use RevertToPrinterSelf then to
|
||||||
|
* return to the SYSTEM context for specific tasks.
|
||||||
|
*/
|
||||||
|
HANDLE WINAPI
|
||||||
|
RevertToPrinterSelf()
|
||||||
|
{
|
||||||
|
HANDLE hToken;
|
||||||
|
|
||||||
|
// Retrieve our current impersonation token
|
||||||
|
if (!OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE, TRUE, &hToken))
|
||||||
|
{
|
||||||
|
ERR("OpenThreadToken failed with error %u!\n", GetLastError());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell the thread to stop impersonating
|
||||||
|
if (!SetThreadToken(NULL, NULL))
|
||||||
|
{
|
||||||
|
ERR("SetThreadToken failed with error %u!\n", GetLastError());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the token required for reverting back to impersonation in ImpersonatePrinterClient
|
||||||
|
return hToken;
|
||||||
|
}
|
|
@ -67,6 +67,13 @@ StartDocPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI
|
||||||
|
SpoolerInit()
|
||||||
|
{
|
||||||
|
// Nothing to do here yet
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
StartPagePrinter(HANDLE hPrinter)
|
StartPagePrinter(HANDLE hPrinter)
|
||||||
{
|
{
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
@ stdcall GetPrintProcessorDirectoryW(wstr wstr long ptr long ptr)
|
@ stdcall GetPrintProcessorDirectoryW(wstr wstr long ptr long ptr)
|
||||||
@ stub GetServerPolicy
|
@ stub GetServerPolicy
|
||||||
@ stub GetShrinkedSize
|
@ stub GetShrinkedSize
|
||||||
@ stub ImpersonatePrinterClient
|
@ stdcall ImpersonatePrinterClient(long)
|
||||||
@ stdcall InitializeRouter(long)
|
@ stdcall InitializeRouter(long)
|
||||||
@ stub IsNamedPipeRpcCall
|
@ stub IsNamedPipeRpcCall
|
||||||
@ stub LoadDriver
|
@ stub LoadDriver
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
@ stub ReplyOpenPrinter
|
@ stub ReplyOpenPrinter
|
||||||
@ stub ReplyPrinterChangeNotification
|
@ stub ReplyPrinterChangeNotification
|
||||||
@ stub ResetPrinterW
|
@ stub ResetPrinterW
|
||||||
@ stub RevertToPrinterSelf
|
@ stdcall RevertToPrinterSelf()
|
||||||
@ stub RouterAllocBidiMem
|
@ stub RouterAllocBidiMem
|
||||||
@ stub RouterAllocBidiResponseContainer
|
@ stub RouterAllocBidiResponseContainer
|
||||||
@ stub RouterAllocPrinterNotifyInfo
|
@ stub RouterAllocPrinterNotifyInfo
|
||||||
|
@ -161,7 +161,7 @@
|
||||||
@ stub SpoolerFindNextPrinterChangeNotification
|
@ stub SpoolerFindNextPrinterChangeNotification
|
||||||
@ stub SpoolerFreePrinterNotifyInfo
|
@ stub SpoolerFreePrinterNotifyInfo
|
||||||
@ stub SpoolerHasInitialized
|
@ stub SpoolerHasInitialized
|
||||||
@ stub SpoolerInit
|
@ stdcall SpoolerInit()
|
||||||
@ stdcall StartDocPrinterW(long long ptr)
|
@ stdcall StartDocPrinterW(long long ptr)
|
||||||
@ stdcall StartPagePrinter(long)
|
@ stdcall StartPagePrinter(long)
|
||||||
@ stub UndoAlignKMPtr
|
@ stub UndoAlignKMPtr
|
||||||
|
|
|
@ -3,6 +3,7 @@ include_directories(${REACTOS_SOURCE_DIR}/include/reactos/idl)
|
||||||
add_rpc_files(server ${REACTOS_SOURCE_DIR}/include/reactos/idl/winspool.idl)
|
add_rpc_files(server ${REACTOS_SOURCE_DIR}/include/reactos/idl/winspool.idl)
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
|
init.c
|
||||||
main.c
|
main.c
|
||||||
rpcserver.c
|
rpcserver.c
|
||||||
rpcstubs.c
|
rpcstubs.c
|
||||||
|
@ -12,7 +13,7 @@ list(APPEND SOURCE
|
||||||
add_executable(spoolsv ${SOURCE} spoolsv.rc)
|
add_executable(spoolsv ${SOURCE} spoolsv.rc)
|
||||||
set_module_type(spoolsv win32cui UNICODE)
|
set_module_type(spoolsv win32cui UNICODE)
|
||||||
target_link_libraries(spoolsv wine)
|
target_link_libraries(spoolsv wine)
|
||||||
add_importlibs(spoolsv advapi32 kernel32 msvcrt ntdll rpcrt4)
|
|
||||||
add_delay_importlibs(spoolsv spoolss)
|
add_delay_importlibs(spoolsv spoolss)
|
||||||
|
add_importlibs(spoolsv msvcrt kernel32 advapi32 ntdll rpcrt4)
|
||||||
add_pch(spoolsv precomp.h SOURCE)
|
add_pch(spoolsv precomp.h SOURCE)
|
||||||
add_cd_file(TARGET spoolsv DESTINATION reactos/system32 FOR all)
|
add_cd_file(TARGET spoolsv DESTINATION reactos/system32 FOR all)
|
||||||
|
|
33
reactos/win32ss/printing/base/spoolsv/init.c
Normal file
33
reactos/win32ss/printing/base/spoolsv/init.c
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Print Spooler Service
|
||||||
|
* LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
|
||||||
|
* PURPOSE: Various initialization functions
|
||||||
|
* COPYRIGHT: Copyright 2015 Colin Finck <colin@reactos.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precomp.h"
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
_RpcSpoolerInit()
|
||||||
|
{
|
||||||
|
DWORD ErrorCode;
|
||||||
|
|
||||||
|
// Call SpoolerInit in the security context of the client.
|
||||||
|
// This delay-loads spoolss.dll in the user context and all further calls to functions in spoolss.dll will be done in the user context as well.
|
||||||
|
ErrorCode = RpcImpersonateClient(NULL);
|
||||||
|
if (ErrorCode != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
ERR("RpcImpersonateClient failed with status %u!\n", ErrorCode);
|
||||||
|
return ErrorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode = SpoolerInit();
|
||||||
|
if (ErrorCode != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
ERR("SpoolerInit failed with status %u!\n", ErrorCode);
|
||||||
|
RpcRevertToSelf();
|
||||||
|
return ErrorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RpcRevertToSelf();
|
||||||
|
}
|
|
@ -19,4 +19,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(spoolsv);
|
||||||
// rpcserver.c
|
// rpcserver.c
|
||||||
extern DWORD WINAPI RpcThreadProc(LPVOID lpParameter);
|
extern DWORD WINAPI RpcThreadProc(LPVOID lpParameter);
|
||||||
|
|
||||||
|
// Undocumented spoolss
|
||||||
|
DWORD WINAPI SpoolerInit();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -448,13 +448,6 @@ _RpcRemoteFindFirstPrinterChangeNotification(WINSPOOL_PRINTER_HANDLE hPrinter, D
|
||||||
return ERROR_INVALID_FUNCTION;
|
return ERROR_INVALID_FUNCTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
|
||||||
_RpcSpoolerInit()
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return ERROR_INVALID_FUNCTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
_RpcResetPrinterEx()
|
_RpcResetPrinterEx()
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,7 +15,7 @@ WINSPOOL_HANDLE_bind(WINSPOOL_HANDLE wszName)
|
||||||
RPC_STATUS Status;
|
RPC_STATUS Status;
|
||||||
|
|
||||||
// Get us a string binding handle from the supplied connection information
|
// Get us a string binding handle from the supplied connection information
|
||||||
Status = RpcStringBindingComposeW(NULL, L"ncacn_np", wszStringBinding, L"\\pipe\\spoolss", NULL, &wszStringBinding);
|
Status = RpcStringBindingComposeW(NULL, L"ncacn_np", wszName, L"\\pipe\\spoolss", NULL, &wszStringBinding);
|
||||||
if (Status != RPC_S_OK)
|
if (Status != RPC_S_OK)
|
||||||
{
|
{
|
||||||
ERR("RpcStringBindingComposeW failed with status %u!\n", Status);
|
ERR("RpcStringBindingComposeW failed with status %u!\n", Status);
|
||||||
|
@ -209,8 +209,8 @@ OpenPrinterA(LPSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSA pDefaul
|
||||||
if (pDefault->pDevMode)
|
if (pDefault->pDevMode)
|
||||||
{
|
{
|
||||||
// Fixed size strings, so no additional memory needs to be allocated
|
// Fixed size strings, so no additional memory needs to be allocated
|
||||||
MultiByteToWideChar(CP_ACP, 0, pDefault->pDevMode->dmDeviceName, -1, wDevMode.dmDeviceName, sizeof(wDevMode.dmDeviceName) / sizeof(WCHAR));
|
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pDefault->pDevMode->dmDeviceName, -1, wDevMode.dmDeviceName, sizeof(wDevMode.dmDeviceName) / sizeof(WCHAR));
|
||||||
MultiByteToWideChar(CP_ACP, 0, pDefault->pDevMode->dmFormName, -1, wDevMode.dmFormName, sizeof(wDevMode.dmFormName) / sizeof(WCHAR));
|
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pDefault->pDevMode->dmFormName, -1, wDevMode.dmFormName, sizeof(wDevMode.dmFormName) / sizeof(WCHAR));
|
||||||
|
|
||||||
// Use CopyMemory to copy over several structure values in one step
|
// Use CopyMemory to copy over several structure values in one step
|
||||||
CopyMemory(&wDevMode.dmSpecVersion, &pDefault->pDevMode->dmSpecVersion, (ULONG_PTR)&wDevMode.dmCollate - (ULONG_PTR)&wDevMode.dmSpecVersion + sizeof(wDevMode.dmCollate));
|
CopyMemory(&wDevMode.dmSpecVersion, &pDefault->pDevMode->dmSpecVersion, (ULONG_PTR)&wDevMode.dmCollate - (ULONG_PTR)&wDevMode.dmSpecVersion + sizeof(wDevMode.dmCollate));
|
||||||
|
@ -272,6 +272,32 @@ OpenPrinterW(LPWSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSW pDefau
|
||||||
return ReturnValue;
|
return ReturnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI
|
||||||
|
SpoolerInit()
|
||||||
|
{
|
||||||
|
BOOL ReturnValue = FALSE;
|
||||||
|
DWORD ErrorCode;
|
||||||
|
|
||||||
|
// Nothing to initialize here yet, but pass this call to the Spool Service as well.
|
||||||
|
RpcTryExcept
|
||||||
|
{
|
||||||
|
ErrorCode = _RpcSpoolerInit();
|
||||||
|
if (ErrorCode)
|
||||||
|
{
|
||||||
|
ERR("_RpcSpoolerInit failed with error %u!\n", ErrorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue = (ErrorCode == ERROR_SUCCESS);
|
||||||
|
}
|
||||||
|
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
ERR("_RpcSpoolerInit failed with exception code %u!\n", RpcExceptionCode());
|
||||||
|
}
|
||||||
|
RpcEndExcept;
|
||||||
|
|
||||||
|
return ReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD WINAPI
|
DWORD WINAPI
|
||||||
StartDocPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
|
StartDocPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
|
||||||
{
|
{
|
||||||
|
|
|
@ -157,7 +157,7 @@
|
||||||
@ stub SetPrinterW
|
@ stub SetPrinterW
|
||||||
@ stub SplDriverUnloadComplete
|
@ stub SplDriverUnloadComplete
|
||||||
@ stub SpoolerDevQueryPrintW
|
@ stub SpoolerDevQueryPrintW
|
||||||
@ stub SpoolerInit
|
@ stdcall SpoolerInit()
|
||||||
@ stub SpoolerPrinterEvent
|
@ stub SpoolerPrinterEvent
|
||||||
@ stub StartDocDlgA
|
@ stub StartDocDlgA
|
||||||
@ stub StartDocDlgW
|
@ stub StartDocDlgW
|
||||||
|
|
Loading…
Reference in a new issue