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)
1160 pJob->
dwStatus &= ~JOB_STATUS_SPOOLING;
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);
#define ERROR_NOT_ENOUGH_MEMORY
#define ERROR_INSUFFICIENT_BUFFER
BOOL WINAPI GetUserNameW(LPWSTR lpszName, LPDWORD lpSize)
#define ERROR_INVALID_PARAMETER
#define ReadFile(a, b, c, d, e)
#define INVALID_HANDLE_VALUE
#define ERROR_INVALID_HANDLE
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
BOOL WINAPI FindClose(HANDLE hFindFile)
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)
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)
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
LONG WINAPI CompareFileTime(IN CONST FILETIME *lpFileTime1, IN CONST FILETIME *lpFileTime2)
VOID WINAPI GetSystemTime(OUT LPSYSTEMTIME lpSystemTime)
static const WCHAR Cleanup[]
__in WDFDMATRANSACTION __out NTSTATUS * pStatus
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
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define FILE_ATTRIBUTE_DIRECTORY
static DWORD _LocalSetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_INFO_2W pJobInfo)
BOOL WINAPI LocalGetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded)
BOOL InitializeGlobalJobList(void)
DWORD WINAPI CreateJob(PLOCAL_PRINTER_HANDLE pPrinterHandle)
BOOL WINAPI LocalScheduleJob(HANDLE hPrinter, DWORD dwJobID)
static DWORD dwJobInfo2Offsets[]
static void _LocalGetJobLevel1(PLOCAL_JOB pJob, PJOB_INFO_1W *ppJobInfo, PBYTE *ppJobInfoEnd, PDWORD pcbNeeded)
BOOL WINAPI LocalSetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Command)
void InitializePrinterJobList(PLOCAL_PRINTER pPrinter)
BOOL WINAPI LocalAddJob(HANDLE hPrinter, DWORD Level, PBYTE pData, DWORD cbBuf, PDWORD pcbNeeded)
static int WINAPI _GlobalJobListCompareRoutine(PVOID FirstStruct, PVOID SecondStruct)
BOOL WINAPI LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
static BOOL _GetNextJobID(PDWORD dwJobID)
static int WINAPI _PrinterJobListCompareRoutine(PVOID FirstStruct, PVOID SecondStruct)
static DWORD _dwLastJobID
static void _LocalGetJobLevel2(PLOCAL_JOB pJob, PJOB_INFO_2W *ppJobInfo, PBYTE *ppJobInfoEnd, PDWORD pcbNeeded)
DWORD GetJobFilePath(PCWSTR pwszExtension, DWORD dwJobID, PWSTR pwszOutput)
BOOL WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob)
static DWORD dwJobInfo1Offsets[]
static DWORD _LocalSetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_INFO_1W pJobInfo)
void FreeJob(PLOCAL_JOB pJob)
PLOCAL_JOB ReadJobShadowFile(PCWSTR pwszFilePath)
static __inline BOOL _EqualStrings(PCWSTR pwszA, PCWSTR pwszB)
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
RPC_STATUS WINAPI RpcStringBindingParseW(RPC_WSTR StringBinding, RPC_WSTR *ObjUuid, RPC_WSTR *Protseq, RPC_WSTR *NetworkAddr, RPC_WSTR *Endpoint, RPC_WSTR *Options)
RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingServerFromClient(RPC_BINDING_HANDLE ClientBinding, RPC_BINDING_HANDLE *ServerBinding)
RPC_STATUS WINAPI RpcBindingToStringBindingW(RPC_BINDING_HANDLE Binding, RPC_WSTR *StringBinding)
unsigned short * RPC_WSTR
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR *String)
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
BOOL InsertTailElementSkiplist(PSKIPLIST Skiplist, PVOID Element)
PVOID LookupElementSkiplist(PSKIPLIST Skiplist, PVOID Element, PDWORD ElementIndex)
PSKIPLIST_NODE LookupNodeByIndexSkiplist(PSKIPLIST Skiplist, DWORD ElementIndex)
BOOL InsertElementSkiplist(PSKIPLIST Skiplist, PVOID Element)
PVOID DeleteElementSkiplist(PSKIPLIST Skiplist, PVOID Element)
void InitializeSkiplist(PSKIPLIST Skiplist, PSKIPLIST_ALLOCATE_ROUTINE AllocateRoutine, PSKIPLIST_COMPARE_ROUTINE CompareRoutine, PSKIPLIST_FREE_ROUTINE FreeRoutine)
void(WINAPI * PSKIPLIST_FREE_ROUTINE)(PVOID)
enum _LOCAL_HANDLE::@5120 HandleType
PLOCAL_PRINT_PROCESSOR pPrintProcessor
PWSTR pwszPrintProcessorParameters
PLOCAL_PRINT_PROCESSOR pPrintProcessor
PControlPrintProcessor pfnControlPrintProcessor
struct _SKIPLIST_NODE * Next[SKIPLIST_LEVELS]
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
#define FIELD_OFFSET(t, f)
#define INVALID_FILE_ATTRIBUTES
BOOL WINAPI DllFreeSplMem(PVOID pMem)
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
BOOL WINAPI DllFreeSplStr(PWSTR pwszString)
PWSTR WINAPI AllocSplStr(PCWSTR pwszInput)
BOOL WINAPI ReallocSplStr(PWSTR *ppwszString, PCWSTR pwszInput)
const WCHAR wszDefaultDocumentName[]
WCHAR wszJobDirectory[MAX_PATH]
struct _SHD_HEADER SHD_HEADER
DWORD WINAPI PrintingThreadProc(PLOCAL_JOB pJob)
#define SHD_WIN2003_SIGNATURE
PDEVMODEW DuplicateDevMode(PDEVMODEW pInput)
PLOCAL_PRINT_PROCESSOR FindPrintProcessor(PCWSTR pwszName)
struct _LOCAL_PRINTER_HANDLE * PLOCAL_PRINTER_HANDLE
BOOL FindDatatype(const PLOCAL_PRINT_PROCESSOR pPrintProcessor, PCWSTR pwszDatatype)
struct _LOCAL_JOB * PLOCAL_JOB
#define IS_VALID_JOB_ID(ID)
#define IS_VALID_PRIORITY(P)
struct _LOCAL_HANDLE * PLOCAL_HANDLE
DWORD WINAPI GetLastError(void)
DWORD(WINAPI * LPTHREAD_START_ROUTINE)(LPVOID)
_In_ DWORD _Out_ PDWORD pcbNeeded
#define ERROR_INVALID_DATATYPE
#define ERROR_INVALID_LEVEL
#define ERROR_UNKNOWN_PRINTPROCESSOR
#define ERROR_INVALID_ACCESS
#define ERROR_SPOOL_FILE_NOT_FOUND
#define ERROR_SPL_NO_ADDJOB
struct _devicemodeW * PDEVMODEW
#define JOB_STATUS_SPOOLING
struct _JOB_INFO_1W JOB_INFO_1W
#define JOB_STATUS_PAPEROUT
struct _JOB_INFO_2W JOB_INFO_2W
struct _ADDJOB_INFO_1W ADDJOB_INFO_1W
#define JOB_CONTROL_CANCEL
#define JOB_STATUS_OFFLINE
#define PRINTER_ATTRIBUTE_DIRECT
#define JOB_STATUS_PAUSED
#define JOB_CONTROL_SENT_TO_PRINTER
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
_IRQL_requires_same_ _In_ PVOID _In_ PVOID SecondStruct
_IRQL_requires_same_ _In_ PVOID FirstStruct