69 return (
wcscmp(pwszA, pwszB) == 0);
105 return A->dwJobID -
B->dwJobID;
125 iComparison =
A->dwPriority -
B->dwPriority;
126 if (iComparison != 0)
132 ERR(
"SystemTimeToFileTime failed for A with error %lu!\n",
GetLastError());
138 ERR(
"SystemTimeToFileTime failed for B with error %lu!\n",
GetLastError());
148 TRACE(
"GetJobFilePath(%S, %lu, %p)\n", pwszExtension, dwJobID, pwszOutput);
163 const WCHAR wszPath[] =
L"\\?????.SHD";
174 TRACE(
"InitializeGlobalJobList()\n");
204 dwJobID =
wcstoul(FindData.cFileName, &
p, 10);
221 ERR(
"InsertElementSkiplist failed for job %lu for the GlobalJobList!\n", pJob->
dwJobID);
229 ERR(
"InsertElementSkiplist failed for job %lu for the Printer's Job List!\n", pJob->
dwJobID);
249 TRACE(
"InitializePrinterJobList(%p)\n", pPrinter);
259 const WCHAR wszDoubleBackslash[] =
L"\\";
260 const DWORD cchDoubleBackslash =
_countof(wszDoubleBackslash) - 1;
262 DWORD cchMachineName;
270 TRACE(
"CreateJob(%p)\n", pPrinterHandle);
277 ERR(
"DllAllocSplMem failed!\n");
299 cchUserName =
UNLEN + 1;
304 ERR(
"GetUserNameW failed with error %lu!\n", dwErrorCode);
315 ERR(
"RpcBindingServerFromClient failed with status %lu!\n", dwErrorCode);
322 ERR(
"RpcBindingToStringBindingW failed with status %lu!\n", dwErrorCode);
329 ERR(
"RpcStringBindingParseW failed with status %lu!\n", dwErrorCode);
333 cchMachineName =
wcslen(pwszMachineName);
342 ERR(
"InsertElementSkiplist failed for job %lu for the GlobalJobList!\n", pJob->
dwJobID);
351 ERR(
"InsertTailElementSkiplist failed for job %lu for the Printer's Job List!\n", pJob->
dwJobID);
357 pPrinterHandle->
pJob = pJob;
390 if (pHandle->
HandleType != HandleType_Printer)
453 DWORD cbDocumentName = 0;
457 DWORD cbUserName = 0;
477 *
pcbNeeded +=
sizeof(
JOB_INFO_1W) + cbDatatype + cbDocumentName + cbMachineName + cbPrinterName + cbStatus + cbUserName;
482 (*ppJobInfo)->JobId = pJob->
dwJobID;
483 (*ppJobInfo)->Status = pJob->
dwStatus;
493 ERR(
"pJob could not be located in the Printer's Job List!\n");
498 ++(*ppJobInfo)->Position;
528 DWORD cbDocumentName = 0;
531 DWORD cbNotifyName = 0;
533 DWORD cbPrintProcessor;
534 DWORD cbPrintProcessorParameters = 0;
536 DWORD cbUserName = 0;
570 *
pcbNeeded +=
sizeof(
JOB_INFO_2W) + cbDatatype + cbDevMode + cbDocumentName + cbDriverName + cbMachineName + cbNotifyName + cbPrinterName + cbPrintProcessor + cbPrintProcessorParameters + cbStatus + cbUserName;
575 (*ppJobInfo)->JobId = pJob->
dwJobID;
576 (*ppJobInfo)->Status = pJob->
dwStatus;
602 ERR(
"pJob could not be located in the Printer's Job List!\n");
607 ++(*ppJobInfo)->Position;
610 FIXME(
"Setting pSecurityDescriptor and Size to 0 for now!\n");
611 (*ppJobInfo)->pSecurityDescriptor =
NULL;
612 (*ppJobInfo)->Size = 0;
615 *ppJobInfoEnd -= cbDevMode;
617 (*ppJobInfo)->pDevMode = (
PDEVMODEW)(*ppJobInfoEnd);
658 PBYTE pEnd = &pStart[cbBuf];
663 TRACE(
"LocalGetJob(%p, %lu, %lu, %p, %lu, %p)\n", hPrinter, JobId,
Level, pStart, cbBuf,
pcbNeeded);
667 if (pHandle->
HandleType != HandleType_Printer)
825 if (!pPrintProcessor)
957 TRACE(
"LocalSetJob(%p, %lu, %lu, %p, %lu)\n", hPrinter, JobId,
Level, pJobInfo,
Command);
961 if (!pHandle || pHandle->
HandleType != HandleType_Printer)
1012 ERR(
"Unimplemented SetJob Command: %lu!\n",
Command);
1033 TRACE(
"LocalEnumJobs(%p, %lu, %lu, %lu, %p, %lu, %p, %p)\n", hPrinter, FirstJob, NoJobs,
Level, pStart, cbBuf,
pcbNeeded, pcReturned);
1037 if (pHandle->
HandleType != HandleType_Printer)
1061 pNode = pFirstJobNode;
1063 while (
i < NoJobs && pNode)
1069 else if (
Level == 2)
1074 pNode = pNode->
Next[0];
1086 pNode = pFirstJobNode;
1089 while (
i < NoJobs && pNode)
1095 else if (
Level == 2)
1100 pNode = pNode->
Next[0];
1122 TRACE(
"LocalScheduleJob(%p, %lu)\n", hPrinter, dwJobID);
1125 if (pHandle->
HandleType != HandleType_Printer)
1171 ERR(
"CreateThread failed with error %lu!\n", dwErrorCode);
1197 PWSTR pwszPrinterName;
1198 PWSTR pwszPrintProcessor;
1200 TRACE(
"ReadJobShadowFile(%S)\n", pwszFilePath);
1206 ERR(
"CreateFileW failed with error %lu for file \"%S\"!\n",
GetLastError(), pwszFilePath);
1215 ERR(
"DllAllocSplMem failed for file \"%S\"!\n", pwszFilePath);
1222 ERR(
"ReadFile failed with error %lu for file \"%S\"!\n",
GetLastError(), pwszFilePath);
1229 ERR(
"Signature or Header Size mismatch for file \"%S\"!\n", pwszFilePath);
1238 ERR(
"Shadow file \"%S\" references a non-existing printer \"%S\"!\n", pwszFilePath, pwszPrinterName);
1245 if (!pPrintProcessor)
1247 ERR(
"Shadow file \"%S\" references a non-existing Print Processor \"%S\"!\n", pwszFilePath, pwszPrintProcessor);
1255 ERR(
"DllAllocSplMem failed for file \"%S\"!\n", pwszFilePath);
1287 pReturnValue = pJob;
1296 return pReturnValue;
1305 DWORD cbDocumentName = 0;
1308 DWORD cbNotifyName = 0;
1312 DWORD cbPrintProcessorParameters = 0;
1313 DWORD cbUserName = 0;
1315 DWORD dwCurrentOffset;
1320 TRACE(
"WriteJobShadowFile(%S, %p)\n", pwszFilePath, pJob);
1326 ERR(
"CreateFileW failed with error %lu for file \"%S\"!\n",
GetLastError(), pwszFilePath);
1343 cbFileSize =
sizeof(
SHD_HEADER) + cbDatatype + cbDocumentName + cbDevMode + cbMachineName + cbNotifyName + cbPrinterDriver + cbPrinterName + cbPrintProcessor + cbPrintProcessorParameters + cbUserName;
1349 ERR(
"DllAllocSplMem failed for file \"%S\"!\n", pwszFilePath);
1377 dwCurrentOffset += cbDatatype;
1381 dwCurrentOffset += cbDevMode;
1386 dwCurrentOffset += cbPrinterDriver;
1390 dwCurrentOffset += cbMachineName;
1394 dwCurrentOffset += cbPrinterName;
1398 dwCurrentOffset += cbPrintProcessor;
1405 dwCurrentOffset += cbDocumentName;
1412 dwCurrentOffset += cbNotifyName;
1415 if (cbPrintProcessorParameters)
1419 dwCurrentOffset += cbPrintProcessorParameters;
1426 dwCurrentOffset += cbUserName;
1430 if (!
WriteFile(hSHDFile, pShadowFile, cbFileSize, &cbWritten,
NULL))
1432 ERR(
"WriteFile failed with error %lu for file \"%S\"!\n",
GetLastError(), pwszFilePath);
1436 bReturnValue =
TRUE;
1448 return bReturnValue;
1456 TRACE(
"FreeJob(%p)\n", pJob);
static DWORD _LocalSetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_INFO_2W pJobInfo)
BOOL WINAPI LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
#define ERROR_SPOOL_FILE_NOT_FOUND
#define ERROR_INVALID_DATATYPE
#define ERROR_INVALID_PARAMETER
static __inline BOOL _EqualStrings(PCWSTR pwszA, PCWSTR pwszB)
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
PWSTR WINAPI AllocSplStr(PCWSTR pwszInput)
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
DWORD(WINAPI * LPTHREAD_START_ROUTINE)(LPVOID)
struct _devicemodeW * PDEVMODEW
BOOL InitializeGlobalJobList(void)
#define JOB_STATUS_PAUSED
BOOL InsertTailElementSkiplist(PSKIPLIST Skiplist, PVOID Element)
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR *String)
static BOOL _GetNextJobID(PDWORD dwJobID)
BOOL WINAPI DllFreeSplMem(PVOID pMem)
#define ERROR_INVALID_HANDLE
#define JOB_STATUS_PAPEROUT
struct _ADDJOB_INFO_1W ADDJOB_INFO_1W
#define JOB_CONTROL_CANCEL
#define ERROR_NOT_ENOUGH_MEMORY
#define INVALID_HANDLE_VALUE
DWORD WINAPI GetLastError(VOID)
DWORD WINAPI PrintingThreadProc(PLOCAL_JOB pJob)
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
static DWORD dwJobInfo2Offsets[]
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
unsigned short * RPC_WSTR
void FreeJob(PLOCAL_JOB pJob)
PSKIPLIST_NODE LookupNodeByIndexSkiplist(PSKIPLIST Skiplist, DWORD ElementIndex)
#define JOB_STATUS_SPOOLING
BOOL WINAPI ReallocSplStr(PWSTR *ppwszString, PCWSTR pwszInput)
void InitializeSkiplist(PSKIPLIST Skiplist, PSKIPLIST_ALLOCATE_ROUTINE AllocateRoutine, PSKIPLIST_COMPARE_ROUTINE CompareRoutine, PSKIPLIST_FREE_ROUTINE FreeRoutine)
void InitializePrinterJobList(PLOCAL_PRINTER pPrinter)
static DWORD _dwLastJobID
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
struct _LOCAL_HANDLE * PLOCAL_HANDLE
PLOCAL_JOB ReadJobShadowFile(PCWSTR pwszFilePath)
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
BOOL InsertElementSkiplist(PSKIPLIST Skiplist, PVOID Element)
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
BOOL WINAPI LocalScheduleJob(HANDLE hPrinter, DWORD dwJobID)
#define JOB_STATUS_OFFLINE
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
PLOCAL_PRINT_PROCESSOR pPrintProcessor
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
DWORD GetJobFilePath(PCWSTR pwszExtension, DWORD dwJobID, PWSTR pwszOutput)
static void _LocalGetJobLevel1(PLOCAL_JOB pJob, PJOB_INFO_1W *ppJobInfo, PBYTE *ppJobInfoEnd, PDWORD pcbNeeded)
BOOL WINAPI LocalGetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded)
BOOL WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob)
RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingServerFromClient(RPC_BINDING_HANDLE ClientBinding, RPC_BINDING_HANDLE *ServerBinding)
PWSTR pwszPrintProcessorParameters
#define FILE_ATTRIBUTE_DIRECTORY
BOOL WINAPI LocalAddJob(HANDLE hPrinter, DWORD Level, PBYTE pData, DWORD cbBuf, PDWORD pcbNeeded)
static void _LocalGetJobLevel2(PLOCAL_JOB pJob, PJOB_INFO_2W *ppJobInfo, PBYTE *ppJobInfoEnd, PDWORD pcbNeeded)
struct _SHD_HEADER SHD_HEADER
VOID WINAPI GetSystemTime(OUT LPSYSTEMTIME lpSystemTime)
RPC_STATUS WINAPI RpcStringBindingParseW(RPC_WSTR StringBinding, RPC_WSTR *ObjUuid, RPC_WSTR *Protseq, RPC_WSTR *NetworkAddr, RPC_WSTR *Endpoint, RPC_WSTR *Options)
BOOL WINAPI GetUserNameW(LPWSTR lpszName, LPDWORD lpSize)
RPC_STATUS WINAPI RpcBindingToStringBindingW(RPC_BINDING_HANDLE Binding, RPC_WSTR *StringBinding)
LONG WINAPI CompareFileTime(IN CONST FILETIME *lpFileTime1, IN CONST FILETIME *lpFileTime2)
_IRQL_requires_same_ _In_ PVOID _In_ PVOID SecondStruct
static int WINAPI _PrinterJobListCompareRoutine(PVOID FirstStruct, PVOID SecondStruct)
#define SHD_WIN2003_SIGNATURE
#define swprintf(buf, format,...)
struct _SKIPLIST_NODE * Next[SKIPLIST_LEVELS]
BOOL FindDatatype(const PLOCAL_PRINT_PROCESSOR pPrintProcessor, PCWSTR pwszDatatype)
#define PRINTER_ATTRIBUTE_DIRECT
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
#define INVALID_FILE_ATTRIBUTES
void(WINAPI * PSKIPLIST_FREE_ROUTINE)(PVOID)
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define JOB_CONTROL_SENT_TO_PRINTER
_IRQL_requires_same_ _In_ PVOID FirstStruct
#define ERROR_INVALID_ACCESS
enum _LOCAL_HANDLE::@4112 HandleType
static const WCHAR Cleanup[]
struct _LOCAL_JOB * PLOCAL_JOB
DWORD WINAPI CreateJob(PLOCAL_PRINTER_HANDLE pPrinterHandle)
PVOID LookupElementSkiplist(PSKIPLIST Skiplist, PVOID Element, PDWORD ElementIndex)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define ERROR_UNKNOWN_PRINTPROCESSOR
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
_In_ DWORD _Out_ PDWORD pcbNeeded
#define IS_VALID_JOB_ID(ID)
PDEVMODEW DuplicateDevMode(PDEVMODEW pInput)
WCHAR wszJobDirectory[MAX_PATH]
#define FIELD_OFFSET(t, f)
static int WINAPI _GlobalJobListCompareRoutine(PVOID FirstStruct, PVOID SecondStruct)
BOOL WINAPI DllFreeSplStr(PWSTR pwszString)
#define ERROR_SPL_NO_ADDJOB
PLOCAL_PRINT_PROCESSOR pPrintProcessor
#define IS_VALID_PRIORITY(P)
PVOID DeleteElementSkiplist(PSKIPLIST Skiplist, PVOID Element)
struct _LOCAL_PRINTER_HANDLE * PLOCAL_PRINTER_HANDLE
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
BOOL WINAPI LocalSetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Command)
#define ERROR_INVALID_LEVEL
PControlPrintProcessor pfnControlPrintProcessor
PLOCAL_PRINT_PROCESSOR FindPrintProcessor(PCWSTR pwszName)
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
static DWORD _LocalSetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_INFO_1W pJobInfo)
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
struct _JOB_INFO_2W JOB_INFO_2W
const WCHAR wszDefaultDocumentName[]
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
static DWORD dwJobInfo1Offsets[]
struct _JOB_INFO_1W JOB_INFO_1W
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
#define ERROR_INSUFFICIENT_BUFFER
BOOL WINAPI FindClose(HANDLE hFindFile)