ReactOS 0.4.15-dev-7842-g558ab78
precomp.h File Reference
#include <limits.h>
#include <stdlib.h>
#include <wchar.h>
#include <lmcons.h>
#include <rpc.h>
#include <strsafe.h>
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
#include <winreg.h>
#include <winspool.h>
#include <winsplp.h>
#include <winddiui.h>
#include <dsrole.h>
#include <secext.h>
#include <ndk/rtlfuncs.h>
#include <skiplist.h>
#include <spoolss.h>
#include <wine/debug.h>
Include dependency graph for precomp.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _LOCAL_PRINT_MONITOR
 
struct  _LOCAL_PORT
 
struct  _LOCAL_PRINT_PROCESSOR
 
struct  _LOCAL_PRINTER
 
struct  _LOCAL_JOB
 
struct  _LOCAL_PRINTER_HANDLE
 
struct  _LOCAL_PORT_HANDLE
 
struct  _LOCAL_XCV_HANDLE
 
struct  _LOCAL_HANDLE
 
struct  _SHD_HEADER
 
struct  _PRINTENV_T
 

Macros

#define WIN32_NO_STATUS
 
#define SKIPLIST_LEVELS   16
 
#define IS_VALID_JOB_ID(ID)   (ID >= 1 && ID <= 99999)
 
#define IS_VALID_PRIORITY(P)   (P >= MIN_PRIORITY && P <= MAX_PRIORITY)
 
#define SHD_WIN2003_SIGNATURE   0x4968
 

Typedefs

typedef BOOL(WINAPIPClosePrintProcessor) (HANDLE)
 
typedef BOOL(WINAPIPControlPrintProcessor) (HANDLE, DWORD)
 
typedef BOOL(WINAPIPEnumPrintProcessorDatatypesW) (LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD)
 
typedef DWORD(WINAPIPGetPrintProcessorCapabilities) (LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD)
 
typedef HANDLE(WINAPIPOpenPrintProcessor) (LPWSTR, PPRINTPROCESSOROPENDATA)
 
typedef BOOL(WINAPIPPrintDocumentOnPrintProcessor) (HANDLE, LPWSTR)
 
typedef LPMONITOREX(WINAPIPInitializePrintMonitor) (PWSTR)
 
typedef LPMONITOR2(WINAPIPInitializePrintMonitor2) (PMONITORINIT, PHANDLE)
 
typedef PMONITORUI(WINAPIPInitializePrintMonitorUI) (VOID)
 
typedef struct _LOCAL_HANDLE LOCAL_HANDLE
 
typedef struct _LOCAL_HANDLEPLOCAL_HANDLE
 
typedef struct _LOCAL_JOB LOCAL_JOB
 
typedef struct _LOCAL_JOBPLOCAL_JOB
 
typedef struct _LOCAL_PORT LOCAL_PORT
 
typedef struct _LOCAL_PORTPLOCAL_PORT
 
typedef struct _LOCAL_PORT_HANDLE LOCAL_PORT_HANDLE
 
typedef struct _LOCAL_PORT_HANDLEPLOCAL_PORT_HANDLE
 
typedef struct _LOCAL_PRINT_MONITOR LOCAL_PRINT_MONITOR
 
typedef struct _LOCAL_PRINT_MONITORPLOCAL_PRINT_MONITOR
 
typedef struct _LOCAL_PRINT_PROCESSOR LOCAL_PRINT_PROCESSOR
 
typedef struct _LOCAL_PRINT_PROCESSORPLOCAL_PRINT_PROCESSOR
 
typedef struct _LOCAL_PRINTER LOCAL_PRINTER
 
typedef struct _LOCAL_PRINTERPLOCAL_PRINTER
 
typedef struct _LOCAL_PRINTER_HANDLE LOCAL_PRINTER_HANDLE
 
typedef struct _LOCAL_PRINTER_HANDLEPLOCAL_PRINTER_HANDLE
 
typedef struct _LOCAL_XCV_HANDLE LOCAL_XCV_HANDLE
 
typedef struct _LOCAL_XCV_HANDLEPLOCAL_XCV_HANDLE
 
typedef struct _SHD_HEADER SHD_HEADER
 
typedef struct _SHD_HEADERPSHD_HEADER
 
typedef struct _PRINTENV_T PRINTENV_T
 
typedef struct _PRINTENV_TPPRINTENV_T
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (localspl)
 
BOOL InitializeFormList (VOID)
 
BOOL WINAPI LocalAddForm (HANDLE hPrinter, DWORD Level, PBYTE pForm)
 
BOOL WINAPI LocalDeleteForm (HANDLE hPrinter, PWSTR pFormName)
 
BOOL WINAPI LocalEnumForms (HANDLE hPrinter, DWORD Level, PBYTE pForm, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
 
BOOL WINAPI LocalGetForm (HANDLE hPrinter, PWSTR pFormName, DWORD Level, PBYTE pForm, DWORD cbBuf, PDWORD pcbNeeded)
 
BOOL WINAPI LocalSetForm (HANDLE hPrinter, PWSTR pFormName, DWORD Level, PBYTE pForm)
 
DWORD WINAPI CreateJob (PLOCAL_PRINTER_HANDLE pPrinterHandle)
 
void FreeJob (PLOCAL_JOB pJob)
 
DWORD GetJobFilePath (PCWSTR pwszExtension, DWORD dwJobID, PWSTR pwszOutput)
 
BOOL InitializeGlobalJobList (VOID)
 
void InitializePrinterJobList (PLOCAL_PRINTER pPrinter)
 
BOOL WINAPI LocalAddJob (HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeeded)
 
BOOL WINAPI LocalEnumJobs (HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 
BOOL WINAPI LocalGetJob (HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded)
 
BOOL WINAPI LocalScheduleJob (HANDLE hPrinter, DWORD dwJobID)
 
BOOL WINAPI LocalSetJob (HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Command)
 
PLOCAL_JOB ReadJobShadowFile (PCWSTR pwszFilePath)
 
BOOL WriteJobShadowFile (PWSTR pwszFilePath, const PLOCAL_JOB pJob)
 
PLOCAL_PRINT_MONITOR FindPrintMonitor (PCWSTR pwszName)
 
BOOL InitializePrintMonitorList (void)
 
BOOL WINAPI LocalEnumMonitors (PWSTR pName, DWORD Level, PBYTE pMonitors, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
 
BOOL WINAPI LocalAddMonitor (PWSTR pName, DWORD Level, PBYTE pMonitors)
 
BOOL WINAPI LocalDeleteMonitor (PWSTR pName, PWSTR pEnvironment, PWSTR pMonitorName)
 
PLOCAL_PORT FindPort (PCWSTR pwszName)
 
BOOL InitializePortList (void)
 
BOOL WINAPI LocalEnumPorts (PWSTR pName, DWORD Level, PBYTE pPorts, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
 
BOOL WINAPI LocalAddPortEx (PWSTR pName, DWORD Level, PBYTE lpBuffer, PWSTR lpMonitorName)
 
BOOL WINAPI LocalAddPort (LPWSTR pName, HWND hWnd, LPWSTR pMonitorName)
 
BOOL WINAPI LocalConfigurePort (PWSTR pName, HWND hWnd, PWSTR pPortName)
 
BOOL WINAPI LocalDeletePort (PWSTR pName, HWND hWnd, PWSTR pPortName)
 
BOOL WINAPI LocalSetPort (PWSTR pName, PWSTR pPortName, DWORD dwLevel, PBYTE pPortInfo)
 
BOOL CreatePortEntry (PCWSTR pwszName, PLOCAL_PRINT_MONITOR pPrintMonitor)
 
DWORD WINAPI LocalGetPrinterData (HANDLE hPrinter, PWSTR pValueName, PDWORD pType, PBYTE pData, DWORD nSize, PDWORD pcbNeeded)
 
DWORD WINAPI LocalGetPrinterDataEx (HANDLE hPrinter, PCWSTR pKeyName, PCWSTR pValueName, PDWORD pType, PBYTE pData, DWORD nSize, PDWORD pcbNeeded)
 
DWORD WINAPI LocalSetPrinterData (HANDLE hPrinter, PWSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData)
 
DWORD WINAPI LocalSetPrinterDataEx (HANDLE hPrinter, LPCWSTR pKeyName, LPCWSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData)
 
BOOL InitializePrinterDrivers (VOID)
 
BOOL WINAPI LocalAddPrinterDriver (LPWSTR pName, DWORD level, LPBYTE pDriverInfo)
 
BOOL WINAPI LocalAddPrinterDriverEx (LPWSTR pName, DWORD level, LPBYTE pDriverInfo, DWORD dwFileCopyFlags)
 
BOOL WINAPI LocalGetPrinterDriver (HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded)
 
BOOL WINAPI LocalGetPrinterDriverDirectory (PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverDirectory, DWORD cbBuf, PDWORD pcbNeeded)
 
BOOL WINAPI LocalGetPrinterDriverEx (HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded, DWORD dwClientMajorVersion, DWORD dwClientMinorVersion, PDWORD pdwServerMajorVersion, PDWORD pdwServerMinorVersion)
 
BOOL WINAPI LocalEnumPrinterDrivers (PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
 
PPRINTENV_T validate_envW (LPCWSTR env)
 
BOOL InitializePrinterList (void)
 
BOOL WINAPI LocalEnumPrinters (DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 
BOOL WINAPI LocalGetPrinter (HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded)
 
BOOL WINAPI LocalOpenPrinter (PWSTR lpPrinterName, HANDLE *phPrinter, PPRINTER_DEFAULTSW pDefault)
 
DWORD WINAPI LocalPrinterMessageBox (HANDLE hPrinter, DWORD Error, HWND hWnd, LPWSTR pText, LPWSTR pCaption, DWORD dwType)
 
BOOL WINAPI LocalReadPrinter (HANDLE hPrinter, PVOID pBuf, DWORD cbBuf, PDWORD pNoBytesRead)
 
DWORD WINAPI LocalStartDocPrinter (HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
 
BOOL WINAPI LocalStartPagePrinter (HANDLE hPrinter)
 
BOOL WINAPI LocalWritePrinter (HANDLE hPrinter, LPVOID pBuf, DWORD cbBuf, LPDWORD pcWritten)
 
BOOL WINAPI LocalEndPagePrinter (HANDLE hPrinter)
 
BOOL WINAPI LocalEndDocPrinter (HANDLE hPrinter)
 
BOOL WINAPI LocalClosePrinter (HANDLE hPrinter)
 
VOID BroadcastChange (PLOCAL_HANDLE pHandle)
 
DWORD WINAPI PrintingThreadProc (PLOCAL_JOB pJob)
 
BOOL FindDatatype (const PLOCAL_PRINT_PROCESSOR pPrintProcessor, PCWSTR pwszDatatype)
 
PLOCAL_PRINT_PROCESSOR FindPrintProcessor (PCWSTR pwszName)
 
BOOL InitializePrintProcessorList (void)
 
BOOL WINAPI LocalEnumPrintProcessorDatatypes (LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 
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)
 
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)
 
PWSTR AllocAndRegQueryWSZ (HKEY hKey, PCWSTR pwszValueName)
 
PDEVMODEW DuplicateDevMode (PDEVMODEW pInput)
 
LONG copy_servername_from_name (LPCWSTR name, LPWSTR target)
 
BOOL WINAPI LocalXcvData (HANDLE hXcv, const WCHAR *pszDataName, BYTE *pInputData, DWORD cbInputData, BYTE *pOutputData, DWORD cbOutputData, DWORD *pcbOutputNeeded, DWORD *pdwStatus)
 

Variables

SKIPLIST GlobalJobList
 
const WCHAR wszCurrentEnvironment []
 
const DWORD cbCurrentEnvironment
 
const DWORD dwSpoolerMajorVersion
 
const DWORD dwSpoolerMinorVersion
 
const WCHAR wszDefaultDocumentName []
 
HKEY hPrintKey
 
HKEY hPrintersKey
 
PCWSTR wszPrintProviderInfo [3]
 
WCHAR wszJobDirectory [MAX_PATH]
 
DWORD cchJobDirectory
 
WCHAR wszSpoolDirectory [MAX_PATH]
 
DWORD cchSpoolDirectory
 
LIST_ENTRY PrintMonitorList
 
SKIPLIST PrinterList
 

Macro Definition Documentation

◆ IS_VALID_JOB_ID

#define IS_VALID_JOB_ID (   ID)    (ID >= 1 && ID <= 99999)

Definition at line 38 of file precomp.h.

◆ IS_VALID_PRIORITY

#define IS_VALID_PRIORITY (   P)    (P >= MIN_PRIORITY && P <= MAX_PRIORITY)

Definition at line 39 of file precomp.h.

◆ SHD_WIN2003_SIGNATURE

#define SHD_WIN2003_SIGNATURE   0x4968

Definition at line 42 of file precomp.h.

◆ SKIPLIST_LEVELS

#define SKIPLIST_LEVELS   16

Definition at line 30 of file precomp.h.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 11 of file precomp.h.

Typedef Documentation

◆ LOCAL_HANDLE

Definition at line 56 of file precomp.h.

◆ LOCAL_JOB

Definition at line 57 of file precomp.h.

◆ LOCAL_PORT

Definition at line 58 of file precomp.h.

◆ LOCAL_PORT_HANDLE

Definition at line 59 of file precomp.h.

◆ LOCAL_PRINT_MONITOR

Definition at line 60 of file precomp.h.

◆ LOCAL_PRINT_PROCESSOR

Definition at line 61 of file precomp.h.

◆ LOCAL_PRINTER

Definition at line 62 of file precomp.h.

◆ LOCAL_PRINTER_HANDLE

Definition at line 63 of file precomp.h.

◆ LOCAL_XCV_HANDLE

Definition at line 64 of file precomp.h.

◆ PClosePrintProcessor

typedef BOOL(WINAPI * PClosePrintProcessor) (HANDLE)

Definition at line 45 of file precomp.h.

◆ PControlPrintProcessor

typedef BOOL(WINAPI * PControlPrintProcessor) (HANDLE, DWORD)

Definition at line 46 of file precomp.h.

◆ PEnumPrintProcessorDatatypesW

typedef BOOL(WINAPI * PEnumPrintProcessorDatatypesW) (LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD)

Definition at line 47 of file precomp.h.

◆ PGetPrintProcessorCapabilities

typedef DWORD(WINAPI * PGetPrintProcessorCapabilities) (LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD)

Definition at line 48 of file precomp.h.

◆ PInitializePrintMonitor

typedef LPMONITOREX(WINAPI * PInitializePrintMonitor) (PWSTR)

Definition at line 51 of file precomp.h.

◆ PInitializePrintMonitor2

typedef LPMONITOR2(WINAPI * PInitializePrintMonitor2) (PMONITORINIT, PHANDLE)

Definition at line 52 of file precomp.h.

◆ PInitializePrintMonitorUI

typedef PMONITORUI(WINAPI * PInitializePrintMonitorUI) (VOID)

Definition at line 53 of file precomp.h.

◆ PLOCAL_HANDLE

Definition at line 56 of file precomp.h.

◆ PLOCAL_JOB

Definition at line 57 of file precomp.h.

◆ PLOCAL_PORT

Definition at line 58 of file precomp.h.

◆ PLOCAL_PORT_HANDLE

Definition at line 59 of file precomp.h.

◆ PLOCAL_PRINT_MONITOR

Definition at line 60 of file precomp.h.

◆ PLOCAL_PRINT_PROCESSOR

Definition at line 61 of file precomp.h.

◆ PLOCAL_PRINTER

Definition at line 62 of file precomp.h.

◆ PLOCAL_PRINTER_HANDLE

Definition at line 63 of file precomp.h.

◆ PLOCAL_XCV_HANDLE

Definition at line 64 of file precomp.h.

◆ POpenPrintProcessor

typedef HANDLE(WINAPI * POpenPrintProcessor) (LPWSTR, PPRINTPROCESSOROPENDATA)

Definition at line 49 of file precomp.h.

◆ PPrintDocumentOnPrintProcessor

typedef BOOL(WINAPI * PPrintDocumentOnPrintProcessor) (HANDLE, LPWSTR)

Definition at line 50 of file precomp.h.

◆ PPRINTENV_T

◆ PRINTENV_T

◆ PSHD_HEADER

Definition at line 65 of file precomp.h.

◆ SHD_HEADER

Definition at line 65 of file precomp.h.

Function Documentation

◆ AllocAndRegQueryWSZ()

PWSTR AllocAndRegQueryWSZ ( HKEY  hKey,
PCWSTR  pwszValueName 
)

Definition at line 26 of file tools.c.

27{
28 DWORD cbNeeded;
29 LONG lStatus;
30 PWSTR pwszValue;
31
32 // Determine the size of the required buffer.
33 lStatus = RegQueryValueExW(hKey, pwszValueName, NULL, NULL, NULL, &cbNeeded);
34 if (lStatus != ERROR_SUCCESS)
35 {
36 ERR("RegQueryValueExW failed with status %ld!\n", lStatus);
37 return NULL;
38 }
39
40 // Allocate it.
41 pwszValue = DllAllocSplMem(cbNeeded);
42 if (!pwszValue)
43 {
44 ERR("DllAllocSplMem failed!\n");
45 return NULL;
46 }
47
48 // Now get the actual value.
49 lStatus = RegQueryValueExW(hKey, pwszValueName, NULL, NULL, (PBYTE)pwszValue, &cbNeeded);
50 if (lStatus != ERROR_SUCCESS)
51 {
52 ERR("RegQueryValueExW failed with status %ld!\n", lStatus);
53 DllFreeSplMem(pwszValue);
54 return NULL;
55 }
56
57 return pwszValue;
58}
#define ERR(fmt,...)
Definition: debug.h:110
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
BYTE * PBYTE
Definition: pedump.c:66
long LONG
Definition: pedump.c:60
uint16_t * PWSTR
Definition: typedefs.h:56
_In_z_ PCWSTR pwszValueName
Definition: ntuser.h:42
BOOL WINAPI DllFreeSplMem(PVOID pMem)
Definition: memory.c:112
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
Definition: memory.c:95

Referenced by InitializePrinterList(), and InitializePrintMonitorList().

◆ BroadcastChange()

VOID BroadcastChange ( PLOCAL_HANDLE  pHandle)

Definition at line 350 of file printers.c.

351{
352 PLOCAL_PRINTER pPrinter;
353 PSKIPLIST_NODE pNode;
354 DWORD cchMachineName = 0;
355 WCHAR wszMachineName[MAX_PATH] = {0}; // if not local, use Machine Name then Printer Name... pPrinter->pJob->pwszMachineName?
356
357 for (pNode = PrinterList.Head.Next[0]; pNode; pNode = pNode->Next[0])
358 {
359 pPrinter = (PLOCAL_PRINTER)pNode->Element;
360
361 StringCchCopyW( &wszMachineName[cchMachineName], sizeof(wszMachineName), pPrinter->pwszPrinterName );
362
363 PostMessageW( HWND_BROADCAST, WM_DEVMODECHANGE, 0, (LPARAM)&wszMachineName );
364 }
365}
#define MAX_PATH
Definition: compat.h:34
SKIPLIST PrinterList
Definition: printers.c:11
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
PWSTR pwszPrinterName
Definition: precomp.h:119
struct _SKIPLIST_NODE * Next[SKIPLIST_LEVELS]
Definition: skiplist.h:30
PVOID Element
Definition: skiplist.h:31
SKIPLIST_NODE Head
Definition: skiplist.h:37
struct _LOCAL_PRINTER * PLOCAL_PRINTER
Definition: precomp.h:62
LONG_PTR LPARAM
Definition: windef.h:208
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define HWND_BROADCAST
Definition: winuser.h:1204
#define WM_DEVMODECHANGE
Definition: winuser.h:1631
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by LocalAddForm(), LocalDeleteForm(), and LocalSetForm().

◆ copy_servername_from_name()

LONG copy_servername_from_name ( LPCWSTR  name,
LPWSTR  target 
)

Definition at line 89 of file tools.c.

90{
92 LPWSTR ptr;
94 DWORD len;
95 DWORD serverlen;
96
97 if (target) *target = '\0';
98
99 if (name == NULL) return 0;
100 if ((name[0] != '\\') || (name[1] != '\\')) return 0;
101
102 server = &name[2];
103 /* skip over both backslash, find separator '\' */
104 ptr = wcschr(server, '\\');
105 serverlen = (ptr) ? ptr - server : lstrlenW(server);
106
107 /* servername is empty */
108 if (serverlen == 0) return 0;
109
110 FIXME("found %s\n", debugstr_wn(server, serverlen));
111
112 if (serverlen > MAX_COMPUTERNAME_LENGTH) return -(LONG)serverlen;
113
114 if (target)
115 {
116 memcpy(target, server, serverlen * sizeof(WCHAR));
117 target[serverlen] = '\0';
118 }
119
122 {
123 if ((serverlen == len) && (_wcsnicmp(server, buffer, len) == 0))
124 {
125 /* The requested Servername is our computername */
126 return 0;
127 }
128 }
129 return serverlen;
130}
#define FIXME(fmt,...)
Definition: debug.h:111
BOOL WINAPI GetComputerNameW(LPWSTR lpBuffer, LPDWORD lpnSize)
Definition: compname.c:446
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define wcschr
Definition: compat.h:17
#define lstrlenW
Definition: compat.h:750
GLuint buffer
Definition: glext.h:5915
GLenum GLsizei len
Definition: glext.h:6722
GLenum target
Definition: glext.h:7315
#define debugstr_wn
Definition: kernel32.h:33
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
Definition: name.c:39
static rfbScreenInfoPtr server
Definition: vnc.c:74
#define MAX_COMPUTERNAME_LENGTH
Definition: winbase.h:243
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by LocalAddMonitor(), LocalAddPort(), LocalAddPortEx(), LocalAddPrinterDriver(), LocalAddPrinterDriverEx(), LocalConfigurePort(), LocalDeleteMonitor(), LocalDeletePort(), and LocalSetPort().

◆ CreateJob()

DWORD WINAPI CreateJob ( PLOCAL_PRINTER_HANDLE  pPrinterHandle)

Definition at line 257 of file jobs.c.

258{
259 const WCHAR wszDoubleBackslash[] = L"\\";
260 const DWORD cchDoubleBackslash = _countof(wszDoubleBackslash) - 1;
261
262 DWORD cchMachineName;
263 DWORD cchUserName;
264 DWORD dwErrorCode;
265 PLOCAL_JOB pJob;
266 RPC_BINDING_HANDLE hServerBinding = NULL;
267 RPC_WSTR pwszBinding = NULL;
268 RPC_WSTR pwszMachineName = NULL;
269
270 TRACE("CreateJob(%p)\n", pPrinterHandle);
271
272 // Create a new job.
273 pJob = DllAllocSplMem(sizeof(LOCAL_JOB));
274 if (!pJob)
275 {
276 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
277 ERR("DllAllocSplMem failed!\n");
278 goto Cleanup;
279 }
280
281 // Reserve an ID for this job.
282 if (!_GetNextJobID(&pJob->dwJobID))
283 {
284 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
285 goto Cleanup;
286 }
287
288 // Copy over defaults to the LOCAL_JOB structure.
289 pJob->pPrinter = pPrinterHandle->pPrinter;
290 pJob->pPrintProcessor = pPrinterHandle->pPrinter->pPrintProcessor;
291 pJob->dwPriority = DEF_PRIORITY;
293 pJob->pwszDatatype = AllocSplStr(pPrinterHandle->pwszDatatype);
295 pJob->pDevMode = DuplicateDevMode(pPrinterHandle->pDevMode);
297
298 // Get the user name for the Job.
299 cchUserName = UNLEN + 1;
300 pJob->pwszUserName = DllAllocSplMem(cchUserName * sizeof(WCHAR));
301 if (!GetUserNameW(pJob->pwszUserName, &cchUserName))
302 {
303 dwErrorCode = GetLastError();
304 ERR("GetUserNameW failed with error %lu!\n", dwErrorCode);
305 goto Cleanup;
306 }
307
308 // FIXME: For now, pwszNotifyName equals pwszUserName.
310
311 // Get the name of the machine that submitted the Job over RPC.
312 dwErrorCode = RpcBindingServerFromClient(NULL, &hServerBinding);
313 if (dwErrorCode != RPC_S_OK)
314 {
315 ERR("RpcBindingServerFromClient failed with status %lu!\n", dwErrorCode);
316 goto Cleanup;
317 }
318
319 dwErrorCode = RpcBindingToStringBindingW(hServerBinding, &pwszBinding);
320 if (dwErrorCode != RPC_S_OK)
321 {
322 ERR("RpcBindingToStringBindingW failed with status %lu!\n", dwErrorCode);
323 goto Cleanup;
324 }
325
326 dwErrorCode = RpcStringBindingParseW(pwszBinding, NULL, NULL, &pwszMachineName, NULL, NULL);
327 if (dwErrorCode != RPC_S_OK)
328 {
329 ERR("RpcStringBindingParseW failed with status %lu!\n", dwErrorCode);
330 goto Cleanup;
331 }
332
333 cchMachineName = wcslen(pwszMachineName);
334 pJob->pwszMachineName = DllAllocSplMem((cchMachineName + cchDoubleBackslash + 1) * sizeof(WCHAR));
335 CopyMemory(pJob->pwszMachineName, wszDoubleBackslash, cchDoubleBackslash * sizeof(WCHAR));
336 CopyMemory(&pJob->pwszMachineName[cchDoubleBackslash], pwszMachineName, (cchMachineName + 1) * sizeof(WCHAR));
337
338 // Add the job to the Global Job List.
340 {
341 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
342 ERR("InsertElementSkiplist failed for job %lu for the GlobalJobList!\n", pJob->dwJobID);
343 goto Cleanup;
344 }
345
346 // Add the job at the end of the Printer's Job List.
347 // As all new jobs are created with default priority, we can be sure that it would always be inserted at the end.
348 if (!InsertTailElementSkiplist(&pJob->pPrinter->JobList, pJob))
349 {
350 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
351 ERR("InsertTailElementSkiplist failed for job %lu for the Printer's Job List!\n", pJob->dwJobID);
352 goto Cleanup;
353 }
354
355 // We were successful!
356 pPrinterHandle->bStartedDoc = TRUE;
357 pPrinterHandle->pJob = pJob;
358 dwErrorCode = ERROR_SUCCESS;
359
360 // Don't let the cleanup routine free this.
361 pJob = NULL;
362
363Cleanup:
364 if (pJob)
365 DllFreeSplMem(pJob);
366
367 if (pwszMachineName)
368 RpcStringFreeW(&pwszMachineName);
369
370 if (pwszBinding)
371 RpcStringFreeW(&pwszBinding);
372
373 if (hServerBinding)
374 RpcBindingFree(&hServerBinding);
375
376 return dwErrorCode;
377}
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define TRUE
Definition: types.h:120
BOOL WINAPI GetUserNameW(LPWSTR lpszName, LPDWORD lpSize)
Definition: misc.c:291
VOID WINAPI GetSystemTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:327
static const WCHAR Cleanup[]
Definition: register.c:80
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define L(x)
Definition: ntvdm.h:50
SKIPLIST GlobalJobList
Definition: jobs.c:11
static BOOL _GetNextJobID(PDWORD dwJobID)
Definition: jobs.c:73
RPC_STATUS WINAPI RpcBindingFree(RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:787
RPC_STATUS WINAPI RpcStringBindingParseW(RPC_WSTR StringBinding, RPC_WSTR *ObjUuid, RPC_WSTR *Protseq, RPC_WSTR *NetworkAddr, RPC_WSTR *Endpoint, RPC_WSTR *Options)
Definition: rpc_binding.c:676
RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingServerFromClient(RPC_BINDING_HANDLE ClientBinding, RPC_BINDING_HANDLE *ServerBinding)
Definition: rpc_binding.c:1646
RPC_STATUS WINAPI RpcBindingToStringBindingW(RPC_BINDING_HANDLE Binding, RPC_WSTR *StringBinding)
Definition: rpc_binding.c:947
unsigned short * RPC_WSTR
Definition: rpcdce.h:46
#define RPC_S_OK
Definition: rpcnterr.h:22
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR *String)
Definition: rpcrt4_main.c:175
BOOL InsertTailElementSkiplist(PSKIPLIST Skiplist, PVOID Element)
Definition: skiplist.c:308
BOOL InsertElementSkiplist(PSKIPLIST Skiplist, PVOID Element)
Definition: skiplist.c:250
#define _countof(array)
Definition: sndvol32.h:68
#define TRACE(s)
Definition: solgame.cpp:4
#define UNLEN
Definition: sspi.c:28
DWORD dwStatus
Definition: precomp.h:159
DWORD dwPriority
Definition: precomp.h:146
SYSTEMTIME stSubmitted
Definition: precomp.h:147
DWORD dwJobID
Definition: precomp.h:140
PLOCAL_PRINTER pPrinter
Definition: precomp.h:144
PWSTR pwszMachineName
Definition: precomp.h:160
PLOCAL_PRINT_PROCESSOR pPrintProcessor
Definition: precomp.h:145
PDEVMODEW pDevMode
Definition: precomp.h:161
PWSTR pwszDatatype
Definition: precomp.h:151
PWSTR pwszUserName
Definition: precomp.h:148
PWSTR pwszNotifyName
Definition: precomp.h:149
PWSTR pwszDocumentName
Definition: precomp.h:150
PLOCAL_PRINTER pPrinter
Definition: precomp.h:171
PLOCAL_JOB pJob
Definition: precomp.h:172
PDEVMODEW pDevMode
Definition: precomp.h:174
PLOCAL_PRINT_PROCESSOR pPrintProcessor
Definition: precomp.h:128
SKIPLIST JobList
Definition: precomp.h:130
PWSTR WINAPI AllocSplStr(PCWSTR pwszInput)
Definition: memory.c:56
const WCHAR wszDefaultDocumentName[]
Definition: main.c:25
PDEVMODEW DuplicateDevMode(PDEVMODEW pInput)
Definition: tools.c:61
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CopyMemory
Definition: winbase.h:1710
#define JOB_STATUS_SPOOLING
Definition: winspool.h:341
#define DEF_PRIORITY
Definition: winspool.h:230

Referenced by LocalAddJob(), and LocalStartDocPrinter().

◆ CreatePortEntry()

BOOL CreatePortEntry ( PCWSTR  pwszName,
PLOCAL_PRINT_MONITOR  pPrintMonitor 
)

Definition at line 37 of file ports.c.

38{
39 PLOCAL_PORT pPort;
40 DWORD cbPortName = (wcslen( pwszName ) + 1) * sizeof(WCHAR);
41
42 // Create a new LOCAL_PORT structure for it.
43 pPort = DllAllocSplMem(sizeof(LOCAL_PORT) + cbPortName);
44 if (!pPort)
45 {
47 return FALSE;
48 }
49
50 pPort->pPrintMonitor = pPrintMonitor;
51 pPort->pwszName = wcscpy( (PWSTR)(pPort+1), pwszName );
52
53 // Insert it into the list and advance to the next port.
55
56 return TRUE;
57}
#define FALSE
Definition: types.h:117
#define SetLastError(x)
Definition: compat.h:752
#define InsertTailList(ListHead, Entry)
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
PWSTR pwszName
Definition: precomp.h:90
LIST_ENTRY Entry
Definition: precomp.h:89
PLOCAL_PRINT_MONITOR pPrintMonitor
Definition: precomp.h:91
static LIST_ENTRY _PortList
Definition: ports.c:11

Referenced by _HandleAddPort(), LocalAddPort(), and LocalAddPortEx().

◆ DuplicateDevMode()

PDEVMODEW DuplicateDevMode ( PDEVMODEW  pInput)

Definition at line 61 of file tools.c.

62{
63 PDEVMODEW pOutput;
64
65 // Allocate a buffer for this DevMode.
66 pOutput = DllAllocSplMem(pInput->dmSize + pInput->dmDriverExtra);
67 if (!pOutput)
68 {
69 ERR("DllAllocSplMem failed!\n");
70 return NULL;
71 }
72
73 // Copy it.
74 CopyMemory(pOutput, pInput, pInput->dmSize + pInput->dmDriverExtra);
75
76 return pOutput;
77}
WORD dmDriverExtra
Definition: wingdi.h:1621
WORD dmSize
Definition: wingdi.h:1620

Referenced by _LocalOpenPrinterHandle(), CreateJob(), and ReadJobShadowFile().

◆ FindDatatype()

BOOL FindDatatype ( const PLOCAL_PRINT_PROCESSOR  pPrintProcessor,
PCWSTR  pwszDatatype 
)

Definition at line 80 of file printprocessors.c.

81{
82 DWORD i;
83 PDATATYPES_INFO_1W pCurrentDatatype = pPrintProcessor->pDatatypesInfo1;
84
85 TRACE("FindDatatype(%p, %S)\n", pPrintProcessor, pwszDatatype);
86
87 if (!pwszDatatype)
88 return FALSE;
89
90 for (i = 0; i < pPrintProcessor->dwDatatypeCount; i++)
91 {
92 if (wcsicmp(pCurrentDatatype->pName, pwszDatatype) == 0)
93 return TRUE;
94
95 ++pCurrentDatatype;
96 }
97
98 return FALSE;
99}
#define wcsicmp
Definition: compat.h:15
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
Definition: glfuncs.h:248
PDATATYPES_INFO_1W pDatatypesInfo1
Definition: precomp.h:102

Referenced by _LocalOpenPrinterHandle(), _LocalSetJobLevel1(), _LocalSetJobLevel2(), InitializePrinterList(), and LocalStartDocPrinter().

◆ FindPort()

PLOCAL_PORT FindPort ( PCWSTR  pwszName)

Definition at line 15 of file ports.c.

16{
18 PLOCAL_PORT pPort;
19
20 TRACE("FindPort(%S)\n", pwszName);
21
22 if (!pwszName)
23 return NULL;
24
26 {
28
29 if (_wcsicmp(pPort->pwszName, pwszName) == 0)
30 return pPort;
31 }
32
33 return NULL;
34}
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by _HandleDeletePort(), _LocalOpenPortHandle(), _LocalOpenXcvHandle(), InitializePrinterList(), LocalAddPort(), LocalAddPortEx(), LocalConfigurePort(), LocalDeletePort(), and LocalSetPort().

◆ FindPrintMonitor()

PLOCAL_PRINT_MONITOR FindPrintMonitor ( PCWSTR  pwszName)

Definition at line 28 of file monitors.c.

29{
31 PLOCAL_PRINT_MONITOR pPrintMonitor;
32
33 TRACE("FindPrintMonitor(%S)\n", pwszName);
34
35 if (!pwszName)
36 return NULL;
37
39 {
41
42 if (_wcsicmp(pPrintMonitor->pwszName, pwszName) == 0)
43 return pPrintMonitor;
44 }
45
46 return NULL;
47}
LIST_ENTRY PrintMonitorList
Definition: monitors.c:11

Referenced by _LocalOpenXcvHandle(), LocalAddPort(), LocalAddPortEx(), and LocalDeleteMonitor().

◆ FindPrintProcessor()

PLOCAL_PRINT_PROCESSOR FindPrintProcessor ( PCWSTR  pwszName)

Definition at line 102 of file printprocessors.c.

103{
105 PLOCAL_PRINT_PROCESSOR pPrintProcessor;
106
107 TRACE("FindPrintProcessor(%S)\n", pwszName);
108
109 if (!pwszName)
110 return NULL;
111
113 {
115
116 if (wcsicmp(pPrintProcessor->pwszName, pwszName) == 0)
117 return pPrintProcessor;
118 }
119
120 return NULL;
121}
static LIST_ENTRY _PrintProcessorList

Referenced by _LocalSetJobLevel2(), InitializePrinterList(), LocalEnumPrintProcessorDatatypes(), and ReadJobShadowFile().

◆ FreeJob()

void FreeJob ( PLOCAL_JOB  pJob)

Definition at line 1452 of file jobs.c.

1453{
1454 PWSTR pwszSHDFile;
1455
1456 TRACE("FreeJob(%p)\n", pJob);
1457
1458 // Remove the Job from both Job Lists.
1459 DeleteElementSkiplist(&pJob->pPrinter->JobList, pJob);
1461
1462 // Try to delete the corresponding .SHD file.
1463 pwszSHDFile = DllAllocSplMem(GetJobFilePath(L"SHD", 0, NULL));
1464 if (pwszSHDFile && GetJobFilePath(L"SHD", pJob->dwJobID, pwszSHDFile))
1465 DeleteFileW(pwszSHDFile);
1466
1467 // Free memory for the mandatory fields.
1468 DllFreeSplMem(pJob->pDevMode);
1474
1475 // Free memory for the optional fields if they are present.
1476 if (pJob->pwszOutputFile)
1478
1481
1482 if (pJob->pwszStatus)
1484
1485 // Finally free the job structure itself.
1486 DllFreeSplMem(pJob);
1487}
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
DWORD GetJobFilePath(PCWSTR pwszExtension, DWORD dwJobID, PWSTR pwszOutput)
Definition: jobs.c:146
PVOID DeleteElementSkiplist(PSKIPLIST Skiplist, PVOID Element)
Definition: skiplist.c:146
PWSTR pwszStatus
Definition: precomp.h:154
PWSTR pwszOutputFile
Definition: precomp.h:152
PWSTR pwszPrintProcessorParameters
Definition: precomp.h:153
BOOL WINAPI DllFreeSplStr(PWSTR pwszString)
Definition: memory.c:130

Referenced by _LocalClosePrinterHandle(), and LocalSetJob().

◆ GetJobFilePath()

DWORD GetJobFilePath ( PCWSTR  pwszExtension,
DWORD  dwJobID,
PWSTR  pwszOutput 
)

Definition at line 146 of file jobs.c.

147{
148 TRACE("GetJobFilePath(%S, %lu, %p)\n", pwszExtension, dwJobID, pwszOutput);
149
150 if (pwszOutput)
151 {
152 CopyMemory(pwszOutput, wszJobDirectory, cchJobDirectory * sizeof(WCHAR));
153 swprintf(&pwszOutput[cchJobDirectory], L"\\%05lu.%s", dwJobID, pwszExtension);
154 }
155
156 // pwszExtension may be L"SPL" or L"SHD", same length for both!
157 return (cchJobDirectory + sizeof("\\?????.SPL")) * sizeof(WCHAR);
158}
#define swprintf
Definition: precomp.h:40
DWORD cchJobDirectory
Definition: main.c:14
WCHAR wszJobDirectory[MAX_PATH]
Definition: main.c:13

Referenced by _LocalOpenPrinterHandle(), FreeJob(), InitializeGlobalJobList(), LocalAddJob(), LocalScheduleJob(), LocalSetJob(), and PrintingThreadProc().

◆ InitializeFormList()

BOOL InitializeFormList ( VOID  )

Definition at line 228 of file forms.c.

229{
230 DWORD dwErrorCode;
231 PFORM_INFO_LIST pfil;
233
234 FIXME("InitializeFormList\n");
235
237 L"SYSTEM\\CurrentControlSet\\Control\\Print\\Forms",
238 0,
239 NULL,
242 NULL,
243 &hFormCKey,
244 NULL ); // KEY_OPENED_EXISTING_KEY );
245
246 if ( dwErrorCode != ERROR_SUCCESS && dwErrorCode != ERROR_ALREADY_EXISTS )
247 {
248 ERR("RegCreateKeyExW failed for the Forms with error %lu!\n", dwErrorCode);
249 goto Cleanup;
250 }
251
252 // Open some registry keys and leave them open. We need them multiple times throughout the Local Spooler.
253 dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Print\\Forms", 0, KEY_ALL_ACCESS, &hFormsKey);
254 if (dwErrorCode != ERROR_SUCCESS)
255 {
256 ERR("RegOpenKeyExW failed for \"Forms\" with error %lu!\n", dwErrorCode);
257 goto Cleanup;
258 }
259
260 _dwLastForm = 1;
261
263
264 {
265 int i = 0, Size;
266 while ( BuiltInForms[ i ].pName != NULL )
267 {
268 TRACE("InitializeFormList L s %S\n",BuiltInForms[ i ].pName );
269
270 Size = sizeof(FORM_INFO_LIST) + ((wcslen(BuiltInForms[ i ].pName) + 1) * sizeof(WCHAR));
271
272 pfil = DllAllocSplMem( Size );
273
274 pfil->pName = wcscpy( (PWSTR)(pfil+1), BuiltInForms[ i ].pName );
275 pfil->Flags = BuiltInForms[ i ].Flags;
276 pfil->Size = BuiltInForms[ i ].Size;
277 pfil->ImageableArea = BuiltInForms[ i ].ImageableArea;
278 pfil->Sig = FORMINFOSIG;
279 pfil->Index = _dwLastForm++;
280 pfil->pKeyword = NULL;
281 pfil->StringType = STRING_NONE;
282 pfil->pMuiDll = NULL;
283 pfil->dwResourceId = 0;
284 pfil->pDisplayName = NULL;
285 pfil->wLangId = 0;
286
287 InsertTailList( &FormList, &pfil->List );
288
289 rfi.Size = pfil->Size;
290 rfi.ImageableArea = pfil->ImageableArea;
291 rfi.Index = pfil->Index;
292 rfi.Flags = pfil->Flags;
293
294 dwErrorCode = RegSetValueExW( hFormsKey, pfil->pName, 0, REG_BINARY, (PBYTE)&rfi, sizeof( rfi ) );
295 if ( dwErrorCode == ERROR_SUCCESS )
296 {
297 TRACE("Init : RQVEW : %S added\n",pfil->pName);
298 }
299
300 i++;
301 }
302 }
303
304Cleanup:
305 return TRUE;
306}
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
static LPSTR pName
Definition: security.c:75
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define DWORD
Definition: nt_native.h:44
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define FORMINFOSIG
Definition: forms.c:10
LIST_ENTRY FormList
Definition: forms.c:21
struct _FORM_INFO_LIST FORM_INFO_LIST
static DWORD _dwLastForm
Definition: forms.c:22
HKEY hFormsKey
Definition: forms.c:225
HKEY hFormCKey
Definition: forms.c:224
FORM_INFO_1W BuiltInForms[]
Definition: forms.c:160
DWORD Flags
Definition: winspool.h:633
RECTL ImageableArea
Definition: winspool.h:636
SIZEL Size
Definition: winspool.h:635
DWORD Index
Definition: forms.c:17
DWORD Sig
Definition: forms.c:16
LIST_ENTRY List
Definition: forms.c:15
RECTL ImageableArea
Definition: forms.c:219
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define STRING_NONE
Definition: winspool.h:672

Referenced by _InitializeLocalSpooler().

◆ InitializeGlobalJobList()

BOOL InitializeGlobalJobList ( VOID  )

Definition at line 161 of file jobs.c.

162{
163 const WCHAR wszPath[] = L"\\?????.SHD";
164 const DWORD cchPath = _countof(wszPath) - 1;
165
166 DWORD dwErrorCode;
167 DWORD dwJobID;
168 HANDLE hFind;
169 PLOCAL_JOB pJob = NULL;
170 PWSTR p;
171 WCHAR wszFullPath[MAX_PATH];
172 WIN32_FIND_DATAW FindData;
173
174 TRACE("InitializeGlobalJobList()\n");
175
176 // This one is incremented in _GetNextJobID.
177 _dwLastJobID = 0;
178
179 // Initialize an empty list for all jobs of all local printers.
180 // We will search it by Job ID (supply a pointer to a DWORD in LookupElementSkiplist).
182
183 // Construct the full path search pattern.
184 CopyMemory(wszFullPath, wszJobDirectory, cchJobDirectory * sizeof(WCHAR));
185 CopyMemory(&wszFullPath[cchJobDirectory], wszPath, (cchPath + 1) * sizeof(WCHAR));
186
187 // Use the search pattern to look for unfinished jobs serialized in shadow files (.SHD)
188 hFind = FindFirstFileW(wszFullPath, &FindData);
189 if (hFind == INVALID_HANDLE_VALUE)
190 {
191 // No unfinished jobs found.
192 dwErrorCode = ERROR_SUCCESS;
193 goto Cleanup;
194 }
195
196 do
197 {
198 // Skip possible subdirectories.
199 if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
200 continue;
201
202 // Extract the Job ID and verify the file name format at the same time.
203 // This includes all valid names (like "00005.SHD") and excludes invalid ones (like "10ABC.SHD").
204 dwJobID = wcstoul(FindData.cFileName, &p, 10);
205 if (!IS_VALID_JOB_ID(dwJobID))
206 continue;
207
208 if (wcsicmp(p, L".SHD") != 0)
209 continue;
210
211 // This shadow file has a valid name. Construct the full path and try to load it.
212 GetJobFilePath(L"SHD", dwJobID, wszFullPath);
213 pJob = ReadJobShadowFile(wszFullPath);
214 if (!pJob)
215 continue;
216
217 // Add it to the Global Job List.
219 {
220 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
221 ERR("InsertElementSkiplist failed for job %lu for the GlobalJobList!\n", pJob->dwJobID);
222 goto Cleanup;
223 }
224
225 // Add it to the Printer's Job List.
226 if (!InsertElementSkiplist(&pJob->pPrinter->JobList, pJob))
227 {
228 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
229 ERR("InsertElementSkiplist failed for job %lu for the Printer's Job List!\n", pJob->dwJobID);
230 goto Cleanup;
231 }
232 }
233 while (FindNextFileW(hFind, &FindData));
234
235 dwErrorCode = ERROR_SUCCESS;
236
237Cleanup:
238 // Outside the loop
239 if (hFind)
240 FindClose(hFind);
241
242 SetLastError(dwErrorCode);
243 return (dwErrorCode == ERROR_SUCCESS);
244}
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
GLfloat GLfloat p
Definition: glext.h:8902
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
static int WINAPI _GlobalJobListCompareRoutine(PVOID FirstStruct, PVOID SecondStruct)
Definition: jobs.c:100
static DWORD _dwLastJobID
Definition: jobs.c:14
PLOCAL_JOB ReadJobShadowFile(PCWSTR pwszFilePath)
Definition: jobs.c:1187
void InitializeSkiplist(PSKIPLIST Skiplist, PSKIPLIST_ALLOCATE_ROUTINE AllocateRoutine, PSKIPLIST_COMPARE_ROUTINE CompareRoutine, PSKIPLIST_FREE_ROUTINE FreeRoutine)
Definition: skiplist.c:220
void(WINAPI * PSKIPLIST_FREE_ROUTINE)(PVOID)
Definition: skiplist.h:24
#define IS_VALID_JOB_ID(ID)
Definition: precomp.h:38

Referenced by _InitializeLocalSpooler().

◆ InitializePortList()

BOOL InitializePortList ( void  )

Definition at line 60 of file ports.c.

61{
62 BOOL bReturnValue;
63 DWORD cbNeeded;
64 DWORD cbPortName;
65 DWORD dwErrorCode;
66 DWORD dwReturned;
67 DWORD i;
68 PLOCAL_PORT pPort;
69 PLOCAL_PRINT_MONITOR pPrintMonitor;
72 PPORT_INFO_1W pPortInfo1 = NULL;
73
74 TRACE("InitializePortList()\n");
75
76 // Initialize an empty list for our Ports.
78
79 // Loop through all Print Monitors.
81 {
82 // Cleanup from the previous run.
83 if (pPortInfo1)
84 {
85 DllFreeSplMem(pPortInfo1);
86 pPortInfo1 = NULL;
87 }
88
90
91 // Determine the required buffer size for EnumPorts.
92 if (pPrintMonitor->bIsLevel2)
93 bReturnValue = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnEnumPorts(pPrintMonitor->hMonitor, NULL, 1, NULL, 0, &cbNeeded, &dwReturned);
94 else
95 bReturnValue = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnEnumPorts(NULL, 1, NULL, 0, &cbNeeded, &dwReturned);
96
97 // Check the returned error code.
99 {
100 ERR("Print Monitor \"%S\" failed with error %lu on EnumPorts!\n", pPrintMonitor->pwszName, GetLastError());
101 continue;
102 }
103
104 // Allocate a buffer large enough.
105 pPortInfo1 = DllAllocSplMem(cbNeeded);
106 if (!pPortInfo1)
107 {
108 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
109 ERR("DllAllocSplMem failed!\n");
110 goto Cleanup;
111 }
112
113 // Get the ports handled by this monitor.
114 if (pPrintMonitor->bIsLevel2)
115 bReturnValue = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnEnumPorts(pPrintMonitor->hMonitor, NULL, 1, (PBYTE)pPortInfo1, cbNeeded, &cbNeeded, &dwReturned);
116 else
117 bReturnValue = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnEnumPorts(NULL, 1, (PBYTE)pPortInfo1, cbNeeded, &cbNeeded, &dwReturned);
118
119 // Check the return value.
120 if (!bReturnValue)
121 {
122 ERR("Print Monitor \"%S\" failed with error %lu on EnumPorts!\n", pPrintMonitor->pwszName, GetLastError());
123 continue;
124 }
125
126 // Loop through all returned ports.
127 p = pPortInfo1;
128
129 for (i = 0; i < dwReturned; i++)
130 {
131 cbPortName = (wcslen(p->pName) + 1) * sizeof(WCHAR);
132
133 // Create a new LOCAL_PORT structure for it.
134 pPort = DllAllocSplMem(sizeof(LOCAL_PORT) + cbPortName);
135 if (!pPort)
136 {
137 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
138 ERR("DllAllocSplMem failed!\n");
139 goto Cleanup;
140 }
141
142 pPort->pPrintMonitor = pPrintMonitor;
143 pPort->pwszName = (PWSTR)((PBYTE)pPort + sizeof(LOCAL_PORT));
144 CopyMemory(pPort->pwszName, p->pName, cbPortName);
145
146 // Insert it into the list and advance to the next port.
147 InsertTailList(&_PortList, &pPort->Entry);
148 p++;
149 }
150 }
151
152 dwErrorCode = ERROR_SUCCESS;
153
154Cleanup:
155 // Inside the loop
156 if (pPortInfo1)
157 DllFreeSplMem(pPortInfo1);
158
159 SetLastError(dwErrorCode);
160 return (dwErrorCode == ERROR_SUCCESS);
161}
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define LOCAL_PORT
Definition: dhcpd.h:112
unsigned int BOOL
Definition: ntddk_ex.h:94
struct _MONITOR2 * PMONITOR2
struct _MONITOREX * LPMONITOREX

Referenced by _InitializeLocalSpooler().

◆ InitializePrinterDrivers()

BOOL InitializePrinterDrivers ( VOID  )

Definition at line 77 of file printerdrivers.c.

78{
79 WCHAR szSysDir[MAX_PATH];
80 DWORD cbBuf;
81
83 return TRUE;
84
85 if (!GetSystemDirectoryW(szSysDir, _countof(szSysDir)))
86 {
87 ERR("GetSystemDirectoryW failed\n");
88 return FALSE;
89 }
90
92 StringCbCatW(wszLocalSplFile, sizeof(wszLocalSplFile), L"\\localspl.dll");
93
95 StringCbCatW(wszPrintUiFile, sizeof(wszPrintUiFile), L"\\printui.dll");
96
97 if (!LocalGetPrinterDriverDirectory(NULL, (PWSTR)wszCurrentEnvironment, 1, (PBYTE)szSysDir, (DWORD)sizeof(szSysDir), &cbBuf))
98 {
99 ERR("LocalGetPrinterDriverDirectory failed\n");
100 return FALSE;
101 }
102
103 StringCbCopyW(wszDriverPath, sizeof(wszDriverPath), szSysDir);
106
107 // HAX! need to get it from the Reg Key L"Driver"!
108 StringCbCatW(wszDriverPath, sizeof(wszDriverPath), L"UniDrv.dll");
109
110 FIXME("DriverPath : %S\n",wszDriverPath);
111
112 return TRUE;
113}
const WCHAR wszCurrentEnvironment[]
Definition: prtprocenv.h:11
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
static WCHAR wszDriverPath[MAX_PATH]
static WCHAR wszLocalSplFile[MAX_PATH]
static const WCHAR version3_subdirW[]
static WCHAR wszPrintUiFile[MAX_PATH]
static const WCHAR backslashW[]
BOOL WINAPI LocalGetPrinterDriverDirectory(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverDirectory, DWORD cbBuf, PDWORD pcbNeeded)
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:342

Referenced by _InitializeLocalSpooler().

◆ InitializePrinterJobList()

void InitializePrinterJobList ( PLOCAL_PRINTER  pPrinter)

Definition at line 247 of file jobs.c.

248{
249 TRACE("InitializePrinterJobList(%p)\n", pPrinter);
250
251 // Initialize an empty list for this printer's jobs.
252 // This one is only for sorting the jobs. If you need to lookup a job, search the GlobalJobList by Job ID.
254}
static int WINAPI _PrinterJobListCompareRoutine(PVOID FirstStruct, PVOID SecondStruct)
Definition: jobs.c:115

Referenced by InitializePrinterList().

◆ InitializePrinterList()

BOOL InitializePrinterList ( void  )

Definition at line 107 of file printers.c.

108{
109 DWORD cbData;
110 DWORD cchPrinterName;
111 DWORD dwErrorCode;
112 DWORD dwSubKeys;
113 DWORD i;
114 HKEY hSubKey = NULL;
115 PLOCAL_PORT pPort;
116 PLOCAL_PRINTER pPrinter = NULL;
117 PLOCAL_PRINT_PROCESSOR pPrintProcessor;
118 PWSTR pwszPort = NULL;
119 PWSTR pwszPrintProcessor = NULL;
120 WCHAR wszPrinterName[MAX_PRINTER_NAME + 1];
121
122 TRACE("InitializePrinterList()\n");
123
124 // Initialize an empty list for our printers.
126
127 // Get the number of subkeys of the printers registry key. Each subkey is a local printer there.
128 dwErrorCode = (DWORD)RegQueryInfoKeyW(hPrintersKey, NULL, NULL, NULL, &dwSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
129 if (dwErrorCode != ERROR_SUCCESS)
130 {
131 ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
132 goto Cleanup;
133 }
134
135 // Loop through all available local printers.
136 for (i = 0; i < dwSubKeys; i++)
137 {
138 // Cleanup tasks from the previous run
139 if (hSubKey)
140 {
141 RegCloseKey(hSubKey);
142 hSubKey = NULL;
143 }
144
145 if (pPrinter)
146 {
147 if (pPrinter->pDefaultDevMode)
149
150 if (pPrinter->pwszDefaultDatatype)
152
153 if (pPrinter->pwszDescription)
155
156 if (pPrinter->pwszPrinterDriver)
158
159 if (pPrinter->pwszPrinterName)
161
162 DllFreeSplMem(pPrinter);
163 pPrinter = NULL;
164 }
165
166 if (pwszPrintProcessor)
167 {
168 DllFreeSplStr(pwszPrintProcessor);
169 pwszPrintProcessor = NULL;
170 }
171
172 // Get the name of this printer.
173 cchPrinterName = _countof(wszPrinterName);
174 dwErrorCode = (DWORD)RegEnumKeyExW(hPrintersKey, i, wszPrinterName, &cchPrinterName, NULL, NULL, NULL, NULL);
175 if (dwErrorCode == ERROR_MORE_DATA)
176 {
177 // This printer name exceeds the maximum length and is invalid.
178 continue;
179 }
180 else if (dwErrorCode != ERROR_SUCCESS)
181 {
182 ERR("RegEnumKeyExW failed for iteration %lu with status %lu!\n", i, dwErrorCode);
183 continue;
184 }
185
186 // Open this Printer's registry key.
187 dwErrorCode = (DWORD)RegOpenKeyExW(hPrintersKey, wszPrinterName, 0, KEY_READ, &hSubKey);
188 if (dwErrorCode != ERROR_SUCCESS)
189 {
190 ERR("RegOpenKeyExW failed for Printer \"%S\" with status %lu!\n", wszPrinterName, dwErrorCode);
191 continue;
192 }
193
194 // Get the Print Processor.
195 pwszPrintProcessor = AllocAndRegQueryWSZ(hSubKey, L"Print Processor");
196 if (!pwszPrintProcessor)
197 continue;
198
199 // Try to find it in the Print Processor List.
200 pPrintProcessor = FindPrintProcessor(pwszPrintProcessor);
201 if (!pPrintProcessor)
202 {
203 ERR("Invalid Print Processor \"%S\" for Printer \"%S\"!\n", pwszPrintProcessor, wszPrinterName);
204 continue;
205 }
206
207 // Get the Port.
208 pwszPort = AllocAndRegQueryWSZ(hSubKey, L"Port");
209 if (!pwszPort)
210 continue;
211
212 // Try to find it in the Port List.
213 pPort = FindPort(pwszPort);
214 if (!pPort)
215 {
216 ERR("Invalid Port \"%S\" for Printer \"%S\"!\n", pwszPort, wszPrinterName);
217 continue;
218 }
219
220 // Create a new LOCAL_PRINTER structure for it.
221 pPrinter = DllAllocSplMem(sizeof(LOCAL_PRINTER));
222 if (!pPrinter)
223 {
224 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
225 ERR("DllAllocSplMem failed!\n");
226 goto Cleanup;
227 }
228
229 pPrinter->pwszPrinterName = AllocSplStr(wszPrinterName);
230 pPrinter->pPrintProcessor = pPrintProcessor;
231 pPrinter->pPort = pPort;
232 InitializePrinterJobList(pPrinter);
233
234 // Get the location.
235 pPrinter->pwszLocation = AllocAndRegQueryWSZ(hSubKey, L"Location");
236 if (!pPrinter->pwszLocation)
237 continue;
238
239 // Get the printer driver.
240 pPrinter->pwszPrinterDriver = AllocAndRegQueryWSZ(hSubKey, L"Printer Driver");
241 if (!pPrinter->pwszPrinterDriver)
242 continue;
243
244 // Get the description.
245 pPrinter->pwszDescription = AllocAndRegQueryWSZ(hSubKey, L"Description");
246 if (!pPrinter->pwszDescription)
247 continue;
248
249 // Get the default datatype.
250 pPrinter->pwszDefaultDatatype = AllocAndRegQueryWSZ(hSubKey, L"Datatype");
251 if (!pPrinter->pwszDefaultDatatype)
252 continue;
253
254 // Verify that it's valid.
255 if (!FindDatatype(pPrintProcessor, pPrinter->pwszDefaultDatatype))
256 {
257 ERR("Invalid default datatype \"%S\" for Printer \"%S\"!\n", pPrinter->pwszDefaultDatatype, wszPrinterName);
258 continue;
259 }
260
261 // Determine the size of the DevMode.
262 dwErrorCode = (DWORD)RegQueryValueExW(hSubKey, L"Default DevMode", NULL, NULL, NULL, &cbData);
263 if (dwErrorCode != ERROR_SUCCESS)
264 {
265 ERR("Couldn't query the size of the DevMode for Printer \"%S\", status is %lu, cbData is %lu!\n", wszPrinterName, dwErrorCode, cbData);
266 continue;
267 }
268
269 // Allocate enough memory for the DevMode.
270 pPrinter->pDefaultDevMode = DllAllocSplMem(cbData);
271 if (!pPrinter->pDefaultDevMode)
272 {
273 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
274 ERR("DllAllocSplMem failed!\n");
275 goto Cleanup;
276 }
277
278 // Get the default DevMode.
279 dwErrorCode = (DWORD)RegQueryValueExW(hSubKey, L"Default DevMode", NULL, NULL, (PBYTE)pPrinter->pDefaultDevMode, &cbData);
280 if (dwErrorCode != ERROR_SUCCESS)
281 {
282 ERR("Couldn't query a DevMode for Printer \"%S\", status is %lu, cbData is %lu!\n", wszPrinterName, dwErrorCode, cbData);
283 continue;
284 }
285
286 // Get the Attributes.
287 cbData = sizeof(DWORD);
288 dwErrorCode = (DWORD)RegQueryValueExW(hSubKey, L"Attributes", NULL, NULL, (PBYTE)&pPrinter->dwAttributes, &cbData);
289 if (dwErrorCode != ERROR_SUCCESS)
290 {
291 ERR("Couldn't query Attributes for Printer \"%S\", status is %lu!\n", wszPrinterName, dwErrorCode);
292 continue;
293 }
294
295 // Get the Status.
296 cbData = sizeof(DWORD);
297 dwErrorCode = (DWORD)RegQueryValueExW(hSubKey, L"Status", NULL, NULL, (PBYTE)&pPrinter->dwStatus, &cbData);
298 if (dwErrorCode != ERROR_SUCCESS)
299 {
300 ERR("Couldn't query Status for Printer \"%S\", status is %lu!\n", wszPrinterName, dwErrorCode);
301 continue;
302 }
303
304 // Add this printer to the printer list.
305 if (!InsertElementSkiplist(&PrinterList, pPrinter))
306 {
307 ERR("InsertElementSkiplist failed for Printer \"%S\"!\n", pPrinter->pwszPrinterName);
308 goto Cleanup;
309 }
310
311 // Don't let the cleanup routines free this.
312 pPrinter = NULL;
313 }
314
315 dwErrorCode = ERROR_SUCCESS;
316
317Cleanup:
318 // Inside the loop
319 if (hSubKey)
320 RegCloseKey(hSubKey);
321
322 if (pPrinter)
323 {
324 if (pPrinter->pDefaultDevMode)
326
327 if (pPrinter->pwszDefaultDatatype)
329
330 if (pPrinter->pwszDescription)
332
333 if (pPrinter->pwszPrinterDriver)
335
336 if (pPrinter->pwszPrinterName)
338
339 DllFreeSplMem(pPrinter);
340 }
341
342 if (pwszPrintProcessor)
343 DllFreeSplStr(pwszPrintProcessor);
344
345 SetLastError(dwErrorCode);
346 return (dwErrorCode == ERROR_SUCCESS);
347}
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_MORE_DATA
Definition: dderror.h:13
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2504
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3662
#define MAX_PRINTER_NAME
Definition: fpSetJob.c:25
#define KEY_READ
Definition: nt_native.h:1023
void InitializePrinterJobList(PLOCAL_PRINTER pPrinter)
Definition: jobs.c:247
static int WINAPI _PrinterListCompareRoutine(PVOID FirstStruct, PVOID SecondStruct)
Definition: printers.c:91
PWSTR pwszDefaultDatatype
Definition: precomp.h:126
PLOCAL_PORT pPort
Definition: precomp.h:129
PWSTR pwszPrinterDriver
Definition: precomp.h:124
DWORD dwAttributes
Definition: precomp.h:121
PWSTR pwszLocation
Definition: precomp.h:123
PWSTR pwszDescription
Definition: precomp.h:125
PDEVMODEW pDefaultDevMode
Definition: precomp.h:127
DWORD dwStatus
Definition: precomp.h:122
HKEY hPrintersKey
Definition: main.c:12
PLOCAL_PORT FindPort(PCWSTR pwszName)
Definition: ports.c:15
PLOCAL_PRINT_PROCESSOR FindPrintProcessor(PCWSTR pwszName)
BOOL FindDatatype(const PLOCAL_PRINT_PROCESSOR pPrintProcessor, PCWSTR pwszDatatype)
PWSTR AllocAndRegQueryWSZ(HKEY hKey, PCWSTR pwszValueName)
Definition: tools.c:26

Referenced by _InitializeLocalSpooler().

◆ InitializePrintMonitorList()

BOOL InitializePrintMonitorList ( void  )

Definition at line 126 of file monitors.c.

127{
128 const WCHAR wszMonitorsPath[] = L"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors";
129 const DWORD cchMonitorsPath = _countof(wszMonitorsPath) - 1;
130
131 DWORD cchMaxSubKey;
132 DWORD cchPrintMonitorName;
133 DWORD dwErrorCode;
134 DWORD dwSubKeys;
135 DWORD i;
136 HINSTANCE hinstPrintMonitor = NULL;
137 HKEY hKey = NULL;
138 HKEY hSubKey = NULL;
139 MONITORINIT MonitorInit;
140 PInitializePrintMonitor pfnInitializePrintMonitor;
141 PInitializePrintMonitor2 pfnInitializePrintMonitor2;
142 PLOCAL_PRINT_MONITOR pPrintMonitor = NULL;
143 PWSTR pwszRegistryPath = NULL;
144
145 TRACE("InitializePrintMonitorList()\n");
146
147 // Initialize an empty list for our Print Monitors.
149
150 // Open the key containing Print Monitors.
151 dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszMonitorsPath, 0, KEY_READ, &hKey);
152 if (dwErrorCode != ERROR_SUCCESS)
153 {
154 ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
155 goto Cleanup;
156 }
157
158 // Get the number of Print Providers and maximum sub key length.
159 dwErrorCode = (DWORD)RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwSubKeys, &cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
160 if (dwErrorCode != ERROR_SUCCESS)
161 {
162 ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
163 goto Cleanup;
164 }
165
166 // Loop through all available Print Providers.
167 for (i = 0; i < dwSubKeys; i++)
168 {
169 // Cleanup tasks from the previous run
170 if (hSubKey)
171 {
172 RegCloseKey(hSubKey);
173 hSubKey = NULL;
174 }
175
176 if (pwszRegistryPath)
177 {
178 DllFreeSplMem(pwszRegistryPath);
179 pwszRegistryPath = NULL;
180 }
181
182 if (pPrintMonitor)
183 {
184 if (pPrintMonitor->pwszFileName)
185 DllFreeSplMem(pPrintMonitor->pwszFileName);
186
187 if (pPrintMonitor->pwszName)
188 DllFreeSplMem(pPrintMonitor->pwszName);
189
190 DllFreeSplMem(pPrintMonitor);
191 pPrintMonitor = NULL;
192 }
193
194 // Create a new LOCAL_PRINT_MONITOR structure for it.
195 pPrintMonitor = DllAllocSplMem(sizeof(LOCAL_PRINT_MONITOR));
196 if (!pPrintMonitor)
197 {
198 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
199 ERR("DllAllocSplMem failed!\n");
200 goto Cleanup;
201 }
202
203 memset( pPrintMonitor, 0, sizeof(LOCAL_PRINT_MONITOR));
204
205 // Allocate memory for the Print Monitor Name.
206 pPrintMonitor->pwszName = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
207 if (!pPrintMonitor->pwszName)
208 {
209 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
210 ERR("DllAllocSplMem failed!\n");
211 goto Cleanup;
212 }
213
214 // Get the name of this Print Monitor.
215 cchPrintMonitorName = cchMaxSubKey + 1;
216 dwErrorCode = (DWORD)RegEnumKeyExW(hKey, i, pPrintMonitor->pwszName, &cchPrintMonitorName, NULL, NULL, NULL, NULL);
217 if (dwErrorCode != ERROR_SUCCESS)
218 {
219 ERR("RegEnumKeyExW failed for iteration %lu with status %lu!\n", i, dwErrorCode);
220 continue;
221 }
222
223 // Open this Print Monitor's registry key.
224 dwErrorCode = (DWORD)RegOpenKeyExW(hKey, pPrintMonitor->pwszName, 0, KEY_READ, &hSubKey);
225 if (dwErrorCode != ERROR_SUCCESS)
226 {
227 ERR("RegOpenKeyExW failed for Print Provider \"%S\" with status %lu!\n", pPrintMonitor->pwszName, dwErrorCode);
228 continue;
229 }
230
231 // Get the file name of the Print Monitor.
232 pPrintMonitor->pwszFileName = AllocAndRegQueryWSZ(hSubKey, L"Driver");
233 if (!pPrintMonitor->pwszFileName)
234 continue;
235
236 // Try to load it.
237 hinstPrintMonitor = LoadLibraryW(pPrintMonitor->pwszFileName);
238 if (!hinstPrintMonitor)
239 {
240 ERR("LoadLibraryW failed for \"%S\" with error %lu!\n", pPrintMonitor->pwszFileName, GetLastError());
241 continue;
242 }
243
244 pPrintMonitor->hModule = hinstPrintMonitor;
245
246 // Try to find a Level 2 initialization routine first.
247 pfnInitializePrintMonitor2 = (PInitializePrintMonitor2)GetProcAddress(hinstPrintMonitor, "InitializePrintMonitor2");
248 if (pfnInitializePrintMonitor2)
249 {
250 // Prepare a MONITORINIT structure.
251 MonitorInit.cbSize = sizeof(MONITORINIT);
252 MonitorInit.bLocal = TRUE;
253
254 // TODO: Fill the other fields.
255 MonitorInit.hckRegistryRoot = hKey;
256 MonitorInit.pMonitorReg = &MonReg;
257
258 // Call the Level 2 initialization routine.
259 pPrintMonitor->pMonitor = (PMONITOR2)pfnInitializePrintMonitor2(&MonitorInit, &pPrintMonitor->hMonitor);
260 if (!pPrintMonitor->pMonitor)
261 {
262 ERR("InitializePrintMonitor2 failed for \"%S\" with error %lu!\n", pPrintMonitor->pwszFileName, GetLastError());
263 continue;
264 }
265 FIXME("InitializePrintMonitor2 loaded.\n");
266 pPrintMonitor->bIsLevel2 = TRUE;
267 }
268 else
269 {
270 // Try to find a Level 1 initialization routine then.
271 pfnInitializePrintMonitor = (PInitializePrintMonitor)GetProcAddress(hinstPrintMonitor, "InitializePrintMonitor");
272 if (pfnInitializePrintMonitor)
273 {
274 // Construct the registry path.
275 pwszRegistryPath = DllAllocSplMem((cchMonitorsPath + 1 + cchPrintMonitorName + 1) * sizeof(WCHAR));
276 if (!pwszRegistryPath)
277 {
278 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
279 ERR("DllAllocSplMem failed!\n");
280 goto Cleanup;
281 }
282
283 CopyMemory(pwszRegistryPath, wszMonitorsPath, cchMonitorsPath * sizeof(WCHAR));
284 pwszRegistryPath[cchMonitorsPath] = L'\\';
285 CopyMemory(&pwszRegistryPath[cchMonitorsPath + 1], pPrintMonitor->pwszName, (cchPrintMonitorName + 1) * sizeof(WCHAR));
286
287 // Call the Level 1 initialization routine.
288 pPrintMonitor->pMonitor = (LPMONITOREX)pfnInitializePrintMonitor(pwszRegistryPath);
289 if (!pPrintMonitor->pMonitor)
290 {
291 ERR("InitializePrintMonitor failed for \"%S\" with error %lu!\n", pPrintMonitor->pwszFileName, GetLastError());
292 continue;
293 }
294 }
295 else
296 {
297 ERR("No initialization routine found for \"%S\"!\n", pPrintMonitor->pwszFileName);
298 continue;
299 }
300 }
301
302 // Add this Print Monitor to the list.
303 InsertTailList(&PrintMonitorList, &pPrintMonitor->Entry);
304 FIXME("InitializePrintMonitorList Handle %p\n",pPrintMonitor->hMonitor);
305 pPrintMonitor->refcount++;
306
307 // Don't let the cleanup routine free this.
308 pPrintMonitor = NULL;
309 }
310
311 dwErrorCode = ERROR_SUCCESS;
312
313Cleanup:
314 // Inside the loop
315 if (hSubKey)
316 RegCloseKey(hSubKey);
317
318 if (pwszRegistryPath)
319 DllFreeSplMem(pwszRegistryPath);
320
321 if (pPrintMonitor)
322 {
323 if (pPrintMonitor->pwszFileName)
324 DllFreeSplMem(pPrintMonitor->pwszFileName);
325
326 if (pPrintMonitor->pwszName)
327 DllFreeSplMem(pPrintMonitor->pwszName);
328
329 DllFreeSplMem(pPrintMonitor);
330 }
331
332 // Outside the loop
333 if (hKey)
335
336 SetLastError(dwErrorCode);
337 return (dwErrorCode == ERROR_SUCCESS);
338}
#define GetProcAddress(x, y)
Definition: compat.h:753
#define LoadLibraryW(x)
Definition: compat.h:747
static MONITORREG MonReg
Definition: monitors.c:110
struct _MONITORINIT MONITORINIT
#define memset(x, y, z)
Definition: compat.h:39
LIST_ENTRY Entry
Definition: precomp.h:73
BOOL bLocal
Definition: winsplp.h:750
DWORD cbSize
Definition: winsplp.h:746
HKEYMONITOR hckRegistryRoot
Definition: winsplp.h:748
PMONITORREG pMonitorReg
Definition: winsplp.h:749
LPMONITOR2(WINAPI * PInitializePrintMonitor2)(PMONITORINIT, PHANDLE)
Definition: precomp.h:52
LPMONITOREX(WINAPI * PInitializePrintMonitor)(PWSTR)
Definition: precomp.h:51

Referenced by _InitializeLocalSpooler().

◆ InitializePrintProcessorList()

BOOL InitializePrintProcessorList ( void  )

Definition at line 129 of file printprocessors.c.

130{
131 DWORD cbDatatypes;
132 DWORD cbFileName;
133 DWORD cchPrintProcessorPath;
134 DWORD cchMaxSubKey;
135 DWORD cchPrintProcessorName;
136 DWORD dwErrorCode;
137 DWORD dwSubKeys;
138 DWORD i;
139 HINSTANCE hinstPrintProcessor;
140 HKEY hKey = NULL;
141 HKEY hSubKey = NULL;
142 HKEY hSubSubKey = NULL;
143 PLOCAL_PRINT_PROCESSOR pPrintProcessor = NULL;
145 WCHAR wszPrintProcessorPath[MAX_PATH];
146
147 TRACE("InitializePrintProcessorList()\n");
148
149 // Initialize an empty list for our Print Processors.
151
152 // Prepare the path to the Print Processor directory.
153 if (!LocalGetPrintProcessorDirectory(NULL, (PWSTR)wszCurrentEnvironment, 1, (PBYTE)wszPrintProcessorPath, sizeof(wszPrintProcessorPath), &cchPrintProcessorPath))
154 {
155 dwErrorCode = GetLastError();
156 goto Cleanup;
157 }
158
159 // LocalGetPrintProcessorDirectory returns the number of copied bytes. Convert this into a number of characters without the terminating null-character.
160 cchPrintProcessorPath /= sizeof(WCHAR);
161 --cchPrintProcessorPath;
162
163 // Append a trailing backslash.
164 wszPrintProcessorPath[cchPrintProcessorPath] = L'\\';
165 ++cchPrintProcessorPath;
166
167 // Open the environment registry key.
169 if (dwErrorCode != ERROR_SUCCESS)
170 goto Cleanup;
171
172 // Open the "Print Processors" subkey.
173 dwErrorCode = (DWORD)RegOpenKeyExW(hKey, L"Print Processors", 0, KEY_READ, &hSubKey);
174 if (dwErrorCode != ERROR_SUCCESS)
175 {
176 ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
177 goto Cleanup;
178 }
179
180 // Get the number of Print Processors and maximum sub key length.
181 dwErrorCode = (DWORD)RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &dwSubKeys, &cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
182 if (dwErrorCode != ERROR_SUCCESS)
183 {
184 ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
185 goto Cleanup;
186 }
187
188 // Loop through all available local Print Processors.
189 for (i = 0; i < dwSubKeys; i++)
190 {
191 // Cleanup tasks from the previous run
192 if (hSubSubKey)
193 {
194 RegCloseKey(hSubSubKey);
195 hSubSubKey = NULL;
196 }
197
198 if (pPrintProcessor)
199 {
200 if (pPrintProcessor->pwszName)
201 DllFreeSplStr(pPrintProcessor->pwszName);
202
203 if (pPrintProcessor->pDatatypesInfo1)
204 DllFreeSplMem(pPrintProcessor->pDatatypesInfo1);
205
206 DllFreeSplMem(pPrintProcessor);
207 pPrintProcessor = NULL;
208 }
209
210 // Create a new LOCAL_PRINT_PROCESSOR structure for it.
211 pPrintProcessor = DllAllocSplMem(sizeof(LOCAL_PRINT_PROCESSOR));
212 if (!pPrintProcessor)
213 {
214 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
215 ERR("DllAllocSplMem failed!\n");
216 goto Cleanup;
217 }
218
219 // Allocate memory for the Print Monitor Name.
220 pPrintProcessor->pwszName = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
221 if (!pPrintProcessor->pwszName)
222 {
223 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
224 ERR("DllAllocSplMem failed!\n");
225 goto Cleanup;
226 }
227
228 // Get the name of this Print Processor.
229 cchPrintProcessorName = cchMaxSubKey + 1;
230 dwErrorCode = (DWORD)RegEnumKeyExW(hSubKey, i, pPrintProcessor->pwszName, &cchPrintProcessorName, NULL, NULL, NULL, NULL);
231 if (dwErrorCode != ERROR_SUCCESS)
232 {
233 ERR("RegEnumKeyExW failed with status %ld!\n", dwErrorCode);
234 continue;
235 }
236
237 // Open this Print Processor's registry key.
238 dwErrorCode = (DWORD)RegOpenKeyExW(hSubKey, pPrintProcessor->pwszName, 0, KEY_READ, &hSubSubKey);
239 if (dwErrorCode != ERROR_SUCCESS)
240 {
241 ERR("RegOpenKeyExW failed for Print Processor \"%S\" with status %lu!\n", pPrintProcessor->pwszName, dwErrorCode);
242 continue;
243 }
244
245 // Get the file name of the Print Processor.
246 cbFileName = sizeof(wszFileName);
247 dwErrorCode = (DWORD)RegQueryValueExW(hSubSubKey, L"Driver", NULL, NULL, (PBYTE)wszFileName, &cbFileName);
248 if (dwErrorCode != ERROR_SUCCESS)
249 {
250 ERR("RegQueryValueExW failed for Print Processor \"%S\" with status %lu!\n", pPrintProcessor->pwszName, dwErrorCode);
251 continue;
252 }
253
254 // Verify that our buffer is large enough.
255 if (cchPrintProcessorPath + cbFileName / sizeof(WCHAR) > MAX_PATH)
256 {
257 ERR("Print Processor directory \"%S\" for Print Processor \"%S\" is too long!\n", wszFileName, pPrintProcessor->pwszName);
258 continue;
259 }
260
261 // Construct the full path to the Print Processor.
262 CopyMemory(&wszPrintProcessorPath[cchPrintProcessorPath], wszFileName, cbFileName);
263
264 // Try to load it.
265 hinstPrintProcessor = LoadLibraryW(wszPrintProcessorPath);
266 if (!hinstPrintProcessor)
267 {
268 ERR("LoadLibraryW failed for \"%S\" with error %lu!\n", wszPrintProcessorPath, GetLastError());
269 continue;
270 }
271
272 // Get and verify all its function pointers.
273 pPrintProcessor->pfnClosePrintProcessor = (PClosePrintProcessor)GetProcAddress(hinstPrintProcessor, "ClosePrintProcessor");
274 if (!pPrintProcessor->pfnClosePrintProcessor)
275 {
276 ERR("Print Processor \"%S\" exports no ClosePrintProcessor!\n", wszPrintProcessorPath);
277 continue;
278 }
279
280 pPrintProcessor->pfnControlPrintProcessor = (PControlPrintProcessor)GetProcAddress(hinstPrintProcessor, "ControlPrintProcessor");
281 if (!pPrintProcessor->pfnControlPrintProcessor)
282 {
283 ERR("Print Processor \"%S\" exports no ControlPrintProcessor!\n", wszPrintProcessorPath);
284 continue;
285 }
286
287 pPrintProcessor->pfnEnumPrintProcessorDatatypesW = (PEnumPrintProcessorDatatypesW)GetProcAddress(hinstPrintProcessor, "EnumPrintProcessorDatatypesW");
288 if (!pPrintProcessor->pfnEnumPrintProcessorDatatypesW)
289 {
290 ERR("Print Processor \"%S\" exports no EnumPrintProcessorDatatypesW!\n", wszPrintProcessorPath);
291 continue;
292 }
293
294 pPrintProcessor->pfnGetPrintProcessorCapabilities = (PGetPrintProcessorCapabilities)GetProcAddress(hinstPrintProcessor, "GetPrintProcessorCapabilities");
295 if (!pPrintProcessor->pfnGetPrintProcessorCapabilities)
296 {
297 ERR("Print Processor \"%S\" exports no GetPrintProcessorCapabilities!\n", wszPrintProcessorPath);
298 continue;
299 }
300
301 pPrintProcessor->pfnOpenPrintProcessor = (POpenPrintProcessor)GetProcAddress(hinstPrintProcessor, "OpenPrintProcessor");
302 if (!pPrintProcessor->pfnOpenPrintProcessor)
303 {
304 ERR("Print Processor \"%S\" exports no OpenPrintProcessor!\n", wszPrintProcessorPath);
305 continue;
306 }
307
308 pPrintProcessor->pfnPrintDocumentOnPrintProcessor = (PPrintDocumentOnPrintProcessor)GetProcAddress(hinstPrintProcessor, "PrintDocumentOnPrintProcessor");
309 if (!pPrintProcessor->pfnPrintDocumentOnPrintProcessor)
310 {
311 ERR("Print Processor \"%S\" exports no PrintDocumentOnPrintProcessor!\n", wszPrintProcessorPath);
312 continue;
313 }
314
315 // Get all supported datatypes.
316 pPrintProcessor->pfnEnumPrintProcessorDatatypesW(NULL, NULL, 1, NULL, 0, &cbDatatypes, &pPrintProcessor->dwDatatypeCount);
317 pPrintProcessor->pDatatypesInfo1 = DllAllocSplMem(cbDatatypes);
318 if (!pPrintProcessor->pDatatypesInfo1)
319 {
320 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
321 ERR("DllAllocSplMem failed!\n");
322 goto Cleanup;
323 }
324
325 if (!pPrintProcessor->pfnEnumPrintProcessorDatatypesW(NULL, NULL, 1, (PBYTE)pPrintProcessor->pDatatypesInfo1, cbDatatypes, &cbDatatypes, &pPrintProcessor->dwDatatypeCount))
326 {
327 ERR("EnumPrintProcessorDatatypesW failed for Print Processor \"%S\" with error %lu!\n", wszPrintProcessorPath, GetLastError());
328 continue;
329 }
330
331 // Add the Print Processor to the list.
332 InsertTailList(&_PrintProcessorList, &pPrintProcessor->Entry);
333
334 // Don't let the cleanup routines free this.
335 pPrintProcessor = NULL;
336 }
337
338 dwErrorCode = ERROR_SUCCESS;
339
340Cleanup:
341 // Inside the loop
342 if (hSubSubKey)
343 RegCloseKey(hSubSubKey);
344
345 if (pPrintProcessor)
346 {
347 if (pPrintProcessor->pwszName)
348 DllFreeSplStr(pPrintProcessor->pwszName);
349
350 if (pPrintProcessor->pDatatypesInfo1)
351 DllFreeSplMem(pPrintProcessor->pDatatypesInfo1);
352
353 DllFreeSplMem(pPrintProcessor);
354 }
355
356 // Outside the loop
357 if (hSubKey)
358 RegCloseKey(hSubKey);
359
360 if (hKey)
362
363 SetLastError(dwErrorCode);
364 return (dwErrorCode == ERROR_SUCCESS);
365}
BOOL(WINAPI * PEnumPrintProcessorDatatypesW)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD)
static WCHAR wszFileName[MAX_PATH]
Definition: wordpad.c:71
BOOL WINAPI LocalGetPrintProcessorDirectory(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
static DWORD _OpenEnvironment(PCWSTR pEnvironment, PHKEY hKey)
PEnumPrintProcessorDatatypesW pfnEnumPrintProcessorDatatypesW
Definition: precomp.h:106
LIST_ENTRY Entry
Definition: precomp.h:100
PGetPrintProcessorCapabilities pfnGetPrintProcessorCapabilities
Definition: precomp.h:107
PControlPrintProcessor pfnControlPrintProcessor
Definition: precomp.h:105
PPrintDocumentOnPrintProcessor pfnPrintDocumentOnPrintProcessor
Definition: precomp.h:109
PClosePrintProcessor pfnClosePrintProcessor
Definition: precomp.h:104
POpenPrintProcessor pfnOpenPrintProcessor
Definition: precomp.h:108
BOOL(WINAPI * PControlPrintProcessor)(HANDLE, DWORD)
Definition: precomp.h:46
BOOL(WINAPI * PClosePrintProcessor)(HANDLE)
Definition: precomp.h:45
DWORD(WINAPI * PGetPrintProcessorCapabilities)(LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD)
Definition: precomp.h:48
BOOL(WINAPI * PPrintDocumentOnPrintProcessor)(HANDLE, LPWSTR)
Definition: precomp.h:50
HANDLE(WINAPI * POpenPrintProcessor)(LPWSTR, PPRINTPROCESSOROPENDATA)
Definition: precomp.h:49

Referenced by _InitializeLocalSpooler().

◆ LocalAddForm()

BOOL WINAPI LocalAddForm ( HANDLE  hPrinter,
DWORD  Level,
PBYTE  pForm 
)

Definition at line 409 of file forms.c.

410{
411 DWORD dwErrorCode, Size, cbNeeded;
412 PFORM_INFO_LIST pfil;
413 PLOCAL_HANDLE pHandle;
415 PFORM_INFO_1W pfi1w = (PFORM_INFO_1W)pForm;
416 PFORM_INFO_2W pfi2w = (PFORM_INFO_2W)pForm;
417
418 FIXME("AddForm(%p, %lu, %p)\n", hPrinter, Level, pForm);
419
420 // Check if this is a printer handle.
421 pHandle = (PLOCAL_HANDLE)hPrinter;
422 if (pHandle->HandleType != HandleType_Printer)
423 {
424 dwErrorCode = ERROR_INVALID_HANDLE;
425 goto Cleanup;
426 }
427
428 // Only support 1 & 2
429 if (Level < 1 || Level > 2)
430 {
431 // The caller supplied an invalid level.
432 dwErrorCode = ERROR_INVALID_LEVEL;
433 goto Cleanup;
434 }
435
436 pfil = FindForm( pfi1w->pName, NULL );
437 if ( pfil )
438 {
439 dwErrorCode = ERROR_FILE_EXISTS;
440 goto Cleanup;
441 }
442
443 dwErrorCode = RegQueryValueExW( hFormsKey, pfi1w->pName, NULL, NULL, NULL, &cbNeeded );
444 if ( dwErrorCode == ERROR_SUCCESS )
445 {
446 dwErrorCode = ERROR_FILE_EXISTS;
447 goto Cleanup;
448 }
449
450 if ( wcslen(pfi1w->pName) > FORMMAXNAMESIZE ) // Limit REG Name size.
451 {
452 dwErrorCode = ERROR_INVALID_PARAMETER;
453 goto Cleanup;
454 }
455
456 Size = sizeof(FORM_INFO_LIST) + ((MAX_PATH + 1) * sizeof(WCHAR));
457
458 pfil = DllAllocSplMem( Size );
459 if ( !pfil )
460 {
461 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
462 goto Cleanup;
463 }
464
465 pfil->Sig = FORMINFOSIG;
466 pfil->Index = _dwLastForm++;
467 pfil->pName = wcscpy( (PWSTR)(pfil+1), pfi1w->pName );
468 pfil->Flags = pfi1w->Flags;
469 pfil->Size = pfi1w->Size;
470 pfil->ImageableArea = pfi1w->ImageableArea;
471 pfil->StringType = STRING_NONE;
472
473 if ( Level > 1 )
474 {
475 pfil->pKeyword = pfi2w->pKeyword;
476 pfil->pMuiDll = pfi2w->pMuiDll;
477 pfil->pDisplayName = pfi2w->pDisplayName;
478 pfil->StringType = pfi2w->StringType;
479 pfil->dwResourceId = pfi2w->dwResourceId;
480 }
481
482 rfi.Size = pfil->Size;
483 rfi.ImageableArea = pfil->ImageableArea;
484 rfi.Index = pfil->Index;
485 rfi.Flags = pfil->Flags;
486
487 dwErrorCode = RegSetValueExW( hFormsKey, pfil->pName, 0, REG_BINARY, (PBYTE)&rfi, sizeof( rfi ) );
488
489 BroadcastChange(pHandle);
490
491 InsertTailList( &FormList, &pfil->List );
492
493Cleanup:
494 SetLastError(dwErrorCode);
495 return (dwErrorCode == ERROR_SUCCESS);
496}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
PFORM_INFO_LIST FASTCALL FindForm(WCHAR *pFormName, WCHAR *pKeyword)
Definition: forms.c:310
#define FORMMAXNAMESIZE
Definition: forms.c:11
LPWSTR pName
Definition: winspool.h:634
LPCWSTR pMuiDll
Definition: winspool.h:663
DWORD dwResourceId
Definition: winspool.h:664
LPCWSTR pDisplayName
Definition: winspool.h:665
LPCSTR pKeyword
Definition: winspool.h:661
DWORD StringType
Definition: winspool.h:662
enum _LOCAL_HANDLE::@5119 HandleType
VOID BroadcastChange(PLOCAL_HANDLE pHandle)
Definition: printers.c:350
struct _LOCAL_HANDLE * PLOCAL_HANDLE
Definition: precomp.h:56
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
struct _FORM_INFO_2W * PFORM_INFO_2W
struct _FORM_INFO_1W * PFORM_INFO_1W
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56

◆ LocalAddJob()

BOOL WINAPI LocalAddJob ( HANDLE  hPrinter,
DWORD  Level,
LPBYTE  pData,
DWORD  cbBuf,
LPDWORD  pcbNeeded 
)

◆ LocalAddMonitor()

BOOL WINAPI LocalAddMonitor ( PWSTR  pName,
DWORD  Level,
PBYTE  pMonitors 
)

Definition at line 636 of file monitors.c.

637{
640 HKEY hroot = NULL;
641 HKEY hentry = NULL;
642 DWORD disposition;
643 BOOL res = FALSE;
644 const WCHAR wszMonitorsPath[] = L"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors\\";
645
646 mi2w = (LPMONITOR_INFO_2W) pMonitors;
647
648 FIXME("LocalAddMonitor(%s, %d, %p): %s %s %s\n", debugstr_w(pName), Level, pMonitors,
650
652 {
653 FIXME("server %s not supported\n", debugstr_w(pName));
655 return FALSE;
656 }
657
658 if (!mi2w->pName || (!mi2w->pName[0]) )
659 {
660 FIXME("pName not valid : %s\n", debugstr_w(mi2w->pName));
662 return FALSE;
663 }
664
666 if (!env)
667 return FALSE; /* ERROR_INVALID_ENVIRONMENT */
668
669 if (!mi2w->pDLLName || (!mi2w->pDLLName[0]) )
670 {
671 FIXME("pDLLName not valid : %s\n", debugstr_w(mi2w->pDLLName));
673 return FALSE;
674 }
675
676 if (RegCreateKeyW(HKEY_LOCAL_MACHINE, wszMonitorsPath, &hroot) != ERROR_SUCCESS) {
677 ERR("unable to create key %s\n", debugstr_w(wszMonitorsPath));
678 return FALSE;
679 }
680
681 if (RegCreateKeyExW(hroot, mi2w->pName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_QUERY_VALUE, NULL, &hentry, &disposition) == ERROR_SUCCESS)
682 {
683 /* Some installers set options for the port before calling AddMonitor.
684 We query the "Driver" entry to verify that the monitor is installed,
685 before we return an error.
686 When a user installs two print monitors at the same time with the
687 same name, a race condition is possible but silently ignored. */
688
689 DWORD namesize = 0;
690
691 if ((disposition == REG_OPENED_EXISTING_KEY) &&
692 (RegQueryValueExW(hentry, L"Driver", NULL, NULL, NULL, &namesize) == ERROR_SUCCESS))
693 {
694 FIXME("monitor %s already exists\n", debugstr_w(mi2w->pName));
695 /* 9x use ERROR_ALREADY_EXISTS */
697 }
698 else
699 {
700 INT len = (lstrlenW(mi2w->pDLLName) +1) * sizeof(WCHAR);
701
702 res = (RegSetValueExW(hentry, L"Driver", 0, REG_SZ, (LPBYTE) mi2w->pDLLName, len) == ERROR_SUCCESS);
703
704 /* Load and initialize the monitor. SetLastError() is called on failure */
705
706 res = AddPrintMonitorList( mi2w->pName, mi2w->pDLLName );
707
708 if ( !res )
709 {
710 RegDeleteKeyW(hroot, mi2w->pName);
711 }
712 else
713 SetLastError(ERROR_SUCCESS); /* Monitor installer depends on this */
714 }
715
716 RegCloseKey(hentry);
717 }
718
719 RegCloseKey(hroot);
720 return res;
721}
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
GLuint res
Definition: glext.h:9613
#define debugstr_w
Definition: kernel32.h:32
#define REG_SZ
Definition: layer.c:22
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define KEY_WRITE
Definition: nt_native.h:1031
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
BOOL AddPrintMonitorList(LPCWSTR pName, LPWSTR DllName)
Definition: monitors.c:457
LPWSTR pEnvironment
Definition: winspool.h:834
LPWSTR pDLLName
Definition: winspool.h:835
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
LONG copy_servername_from_name(LPCWSTR name, LPWSTR target)
Definition: tools.c:89
PPRINTENV_T validate_envW(LPCWSTR env)
#define ERROR_PRINT_MONITOR_ALREADY_INSTALLED
Definition: winerror.h:1211
struct _MONITOR_INFO_2W * LPMONITOR_INFO_2W

◆ LocalAddPort()

BOOL WINAPI LocalAddPort ( LPWSTR  pName,
HWND  hWnd,
LPWSTR  pMonitorName 
)

Definition at line 286 of file ports.c.

287{
288 DWORD lres;
289 BOOL res = FALSE;
290 PLOCAL_PRINT_MONITOR pPrintMonitor;
291
292 FIXME("LocalAddPort(%S, %p, %s)\n", pName, hWnd, debugstr_w(pMonitorName));
293
295 if (lres)
296 {
297 FIXME("server %s not supported\n", debugstr_w(pName));
299 return FALSE;
300 }
301
302 /* an empty Monitorname is Invalid */
303 if (!pMonitorName[0])
304 {
306 return FALSE;
307 }
308
309 pPrintMonitor = FindPrintMonitor( pMonitorName );
310 if (!pPrintMonitor )
311 {
313 return FALSE;
314 }
315
316 if ( pPrintMonitor->bIsLevel2 && ((PMONITOR2)pPrintMonitor->pMonitor)->pfnAddPort )
317 {
318 res = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnAddPort(pPrintMonitor->hMonitor, pName, hWnd, pMonitorName);
319 }
320 else if ( !pPrintMonitor->bIsLevel2 && ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnAddPort )
321 {
322 res = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnAddPort(pName, hWnd, pMonitorName);
323 }
324 else
325 {
327 }
328
329 if ( res )
330 {
331 DWORD cbNeeded, cReturned, i;
332 PPORT_INFO_1 pPorts;
333
334 //
335 // Play it safe,,, we know its Monitor2.... This is ReactOS.
336 //
337 if ( LocalEnumPorts( pName, 1, NULL, 0, &cbNeeded, &cReturned ) )
338 {
339 pPorts = DllAllocSplMem( cbNeeded );
340 if (pPorts)
341 {
342 if ( LocalEnumPorts( pName, 1, (PBYTE)pPorts, cbNeeded, &cbNeeded, &cReturned ) )
343 {
344 for ( i = 0; i < cReturned; i++ )
345 {
346 if ( !FindPort( pPorts[i].pName ) )
347 {
348 CreatePortEntry( pPorts[i].pName, pPrintMonitor );
349 }
350 }
351 }
352 DllFreeSplMem( pPorts );
353 }
354 }
355 }
356
357 return res;
358}
HWND hWnd
Definition: settings.c:17
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
PLOCAL_PRINT_MONITOR FindPrintMonitor(PCWSTR pwszName)
Definition: monitors.c:28
@ Monitor
Definition: video.h:270
BOOL CreatePortEntry(PCWSTR pwszName, PLOCAL_PRINT_MONITOR pPrintMonitor)
Definition: ports.c:37
BOOL WINAPI LocalEnumPorts(PWSTR pName, DWORD Level, PBYTE pPorts, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
Definition: ports.c:164

◆ LocalAddPortEx()

BOOL WINAPI LocalAddPortEx ( PWSTR  pName,
DWORD  Level,
PBYTE  lpBuffer,
PWSTR  lpMonitorName 
)

Definition at line 217 of file ports.c.

218{
219 DWORD lres;
220 BOOL res = FALSE;
221 PLOCAL_PORT pPort;
222 PLOCAL_PRINT_MONITOR pPrintMonitor;
224
225 FIXME("LocalAddPortEx(%S, %lu, %p, %S)\n", pName, Level, lpBuffer, lpMonitorName);
226
228 if ( lres )
229 {
230 FIXME("server %s not supported\n", debugstr_w(pName));
232 return FALSE;
233 }
234
235 if ( Level != 1 )
236 {
238 return FALSE;
239 }
240
241 if ((!pi) || (!lpMonitorName) || (!lpMonitorName[0]))
242 {
244 return FALSE;
245 }
246
247 pPrintMonitor = FindPrintMonitor( lpMonitorName );
248 if (!pPrintMonitor )
249 {
251 return FALSE;
252 }
253
254 pPort = FindPort( pi->pName );
255 if ( pPort )
256 {
258 return FALSE;
259 }
260
261 if ( pPrintMonitor->bIsLevel2 && ((PMONITOR2)pPrintMonitor->pMonitor)->pfnAddPortEx )
262 {
263 res = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnAddPortEx(pPrintMonitor->hMonitor, pName, Level, lpBuffer, lpMonitorName);
264 }
265 else if ( !pPrintMonitor->bIsLevel2 && ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnAddPortEx )
266 {
267 res = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnAddPortEx(pName, Level, lpBuffer, lpMonitorName);
268 }
269 else
270 {
272 }
273
274 if ( res )
275 {
276 res = CreatePortEntry( pi->pName, pPrintMonitor );
277 }
278
279 return res;
280}
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
static refpint_t pi[]
Definition: server.c:96

◆ LocalAddPrinterDriver()

BOOL WINAPI LocalAddPrinterDriver ( LPWSTR  pName,
DWORD  level,
LPBYTE  pDriverInfo 
)

Definition at line 1133 of file printerdrivers.c.

1134{
1135 LONG lres;
1136
1137 TRACE("(%s, %d, %p, 0x%x)\n", debugstr_w(pName), level, pDriverInfo);
1138
1140
1141 if (lres)
1142 {
1143 FIXME("server %s not supported\n", debugstr_w(pName));
1145 return FALSE;
1146 }
1147
1148 // Should be APD_COPY_NEW_FILES. Cheap wine.
1149
1150 return myAddPrinterDriverEx(level, pDriverInfo, APD_COPY_NEW_FILES, TRUE);
1151}
GLint level
Definition: gl.h:1546
BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCopyFlags, BOOL lazy)
#define APD_COPY_NEW_FILES
Definition: winspool.h:606

◆ LocalAddPrinterDriverEx()

BOOL WINAPI LocalAddPrinterDriverEx ( LPWSTR  pName,
DWORD  level,
LPBYTE  pDriverInfo,
DWORD  dwFileCopyFlags 
)

Definition at line 1110 of file printerdrivers.c.

1111{
1112 LONG lres;
1113
1114 TRACE("(%s, %d, %p, 0x%x)\n", debugstr_w(pName), level, pDriverInfo, dwFileCopyFlags);
1115
1117
1118 if (lres)
1119 {
1120 FIXME("server %s not supported\n", debugstr_w(pName));
1122 return FALSE;
1123 }
1124
1125 if ((dwFileCopyFlags & ~APD_COPY_FROM_DIRECTORY) != APD_COPY_ALL_FILES)
1126 {
1127 TRACE("Flags 0x%x ignored (using APD_COPY_ALL_FILES)\n", dwFileCopyFlags & ~APD_COPY_FROM_DIRECTORY);
1128 }
1129
1130 return myAddPrinterDriverEx(level, pDriverInfo, dwFileCopyFlags, TRUE);
1131}
#define APD_COPY_ALL_FILES
Definition: winspool.h:605
#define APD_COPY_FROM_DIRECTORY
Definition: winspool.h:607

◆ LocalClosePrinter()

BOOL WINAPI LocalClosePrinter ( HANDLE  hPrinter)

Definition at line 1960 of file printers.c.

1961{
1962 PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter;
1963
1964 FIXME("LocalClosePrinter(%p)\n", hPrinter);
1965
1966 if (!pHandle)
1967 {
1969 return FALSE;
1970 }
1971
1972 if (pHandle->HandleType == HandleType_Port)
1973 {
1975 }
1976 else if (pHandle->HandleType == HandleType_Printer)
1977 {
1979 }
1980 else if (pHandle->HandleType == HandleType_PrintServer)
1981 {
1982 // Nothing to do.
1983 }
1984 else if (pHandle->HandleType == HandleType_Xcv)
1985 {
1987 }
1988 FIXME("LocalClosePrinter 1\n");
1989 // Free memory for the handle and the specific handle (if any).
1990 if (pHandle->pSpecificHandle)
1992 FIXME("LocalClosePrinter 2\n");
1993 DllFreeSplMem(pHandle);
1994 FIXME("LocalClosePrinter 3\n");
1995 return TRUE;
1996}
static void _LocalClosePrinterHandle(PLOCAL_PRINTER_HANDLE pPrinterHandle)
Definition: printers.c:1937
static void _LocalCloseXcvHandle(PLOCAL_XCV_HANDLE pXcvHandle)
Definition: printers.c:1950
static void _LocalClosePortHandle(PLOCAL_PORT_HANDLE pPortHandle)
Definition: printers.c:1926
PVOID pSpecificHandle
Definition: precomp.h:208

◆ LocalCloseSpoolFileHandle()

BOOL WINAPI LocalCloseSpoolFileHandle ( HANDLE  hPrinter)

Definition at line 30 of file spoolfile.c.

31{
32 FIXME("LocalCloseSpoolFileHandle(%p)\n", hPrinter);
33 return FALSE;
34}

◆ LocalCommitSpoolData()

BOOL WINAPI LocalCommitSpoolData ( HANDLE  hPrinter,
DWORD  cbCommit 
)

Definition at line 23 of file spoolfile.c.

24{
25 FIXME("LocalCommitSpoolData(%p, %lu)\n", hPrinter, cbCommit);
26 return FALSE;
27}

◆ LocalConfigurePort()

BOOL WINAPI LocalConfigurePort ( PWSTR  pName,
HWND  hWnd,
PWSTR  pPortName 
)

Definition at line 361 of file ports.c.

362{
363 LONG lres;
364 DWORD res;
365 PLOCAL_PORT pPrintPort;
366 PLOCAL_PRINT_MONITOR pPrintMonitor;
367
368 FIXME("LocalConfigurePort(%S, %p, %S)\n", pName, hWnd, pPortName);
369
371 if (lres)
372 {
373 FIXME("server %s not supported\n", debugstr_w(pName));
375 return FALSE;
376 }
377
378 /* an empty Portname is Invalid, but can popup a Dialog */
379 if (!pPortName[0])
380 {
382 return FALSE;
383 }
384
385 pPrintPort = FindPort(pPortName);
386 if (!pPrintPort )
387 {
389 return FALSE;
390 }
391
392 pPrintMonitor = pPrintPort->pPrintMonitor;
393
394 if ( pPrintMonitor->bIsLevel2 && ((PMONITOR2)pPrintMonitor->pMonitor)->pfnConfigurePort )
395 {
396 res = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnConfigurePort(pPrintMonitor->hMonitor, pName, hWnd, pPortName);
397 }
398 else if ( !pPrintMonitor->bIsLevel2 && ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnConfigurePort )
399 {
400 res = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnConfigurePort(pName, hWnd, pPortName);
401 }
402 else
403 {
405 }
406
407 return res;
408}
#define ERROR_INVALID_NAME
Definition: compat.h:103

◆ LocalDeleteForm()

BOOL WINAPI LocalDeleteForm ( HANDLE  hPrinter,
PWSTR  pFormName 
)

Definition at line 499 of file forms.c.

500{
501 DWORD dwErrorCode, cbNeeded;
502 PFORM_INFO_LIST pfil;
504 PLOCAL_HANDLE pHandle;
505
506 FIXME("DeleteForm(%p, %S)\n", hPrinter, pFormName);
507
508 // Check if this is a printer handle.
509 pHandle = (PLOCAL_HANDLE)hPrinter;
510 if (pHandle->HandleType != HandleType_Printer)
511 {
512 dwErrorCode = ERROR_INVALID_HANDLE;
513 goto Cleanup;
514 }
515
516 pfil = FindForm( pFormName, NULL );
517 if ( !pfil )
518 {
519 dwErrorCode = ERROR_INVALID_PARAMETER;
520 goto Cleanup;
521 }
522
523 dwErrorCode = RegQueryValueExW( hFormsKey, pFormName, NULL, NULL, (PBYTE)&rfi, &cbNeeded );
524 if ( dwErrorCode != ERROR_SUCCESS )
525 {
526 goto Cleanup;
527 }
528
529 dwErrorCode = RegDeleteValueW(hFormsKey, pFormName);
530 if ( dwErrorCode != ERROR_SUCCESS )
531 {
532 goto Cleanup;
533 }
534
535 RemoveEntryList(&pfil->List);
536
537 DllFreeSplMem(pfil);
538
539 BroadcastChange(pHandle);
540
541 dwErrorCode = ERROR_SUCCESS;
542
543Cleanup:
544 SetLastError(dwErrorCode);
545 return (dwErrorCode == ERROR_SUCCESS);
546}
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986

◆ LocalDeleteMonitor()

BOOL WINAPI LocalDeleteMonitor ( PWSTR  pName,
PWSTR  pEnvironment,
PWSTR  pMonitorName 
)

Definition at line 724 of file monitors.c.

725{
726 HKEY hroot = NULL;
727 LONG lres;
728 PLOCAL_PRINT_MONITOR pPrintMonitor;
729 const WCHAR wszMonitorsPath[] = L"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors\\";
730
731 FIXME("LocalDeleteMonitor(%s, %s, %s)\n",debugstr_w(pName),debugstr_w(pEnvironment),
732 debugstr_w(pMonitorName));
733
735 if (lres)
736 {
737 FIXME("server %s not supported\n", debugstr_w(pName));
739 return FALSE;
740 }
741
742 /* pEnvironment is ignored in Windows for the local Computer */
743 if (!pMonitorName || !pMonitorName[0])
744 {
745 ERR("pMonitorName %s is invalid\n", debugstr_w(pMonitorName));
747 return FALSE;
748 }
749
750 pPrintMonitor = FindPrintMonitor( pMonitorName );
751 if ( pPrintMonitor )
752 {
753 if ( pPrintMonitor->refcount ) pPrintMonitor->refcount--;
754
755 if ( pPrintMonitor->refcount == 0 )
756 { /* Unload the monitor if it's loaded */
757 RemoveEntryList(&pPrintMonitor->Entry);
758
759 if ( pPrintMonitor->bIsLevel2 )
760 {
761 PMONITOR2 pm2 = pPrintMonitor->pMonitor;
762 if ( pm2 && pm2->pfnShutdown )
763 {
764 pm2->pfnShutdown(pPrintMonitor->hMonitor);
765 }
766 }
767
768 if ( pPrintMonitor->hModule )
769 FreeLibrary(pPrintMonitor->hModule);
770
771 if (pPrintMonitor->pwszFileName)
772 DllFreeSplStr(pPrintMonitor->pwszFileName);
773
774 if (pPrintMonitor->pwszName)
775 DllFreeSplStr(pPrintMonitor->pwszName);
776
777 DllFreeSplMem(pPrintMonitor);
778 pPrintMonitor = NULL;
779 }
780 }
781 else
782 {
783 FIXME("Could not find %s\n", debugstr_w(pMonitorName));
784 }
785
786 if (RegCreateKeyW(HKEY_LOCAL_MACHINE, wszMonitorsPath, &hroot) != ERROR_SUCCESS)
787 {
788 ERR("unable to create key %s\n", debugstr_w(wszMonitorsPath));
789 return FALSE;
790 }
791
792 if (RegDeleteTreeW(hroot, pMonitorName) == ERROR_SUCCESS)
793 {
794 FIXME("%s deleted\n", debugstr_w(pMonitorName));
795 RegCloseKey(hroot);
796 return TRUE;
797 }
798
799 FIXME("%s does not exist\n", debugstr_w(pMonitorName));
800 RegCloseKey(hroot);
801
802 /* NT: ERROR_UNKNOWN_PRINT_MONITOR (3000), 9x: ERROR_INVALID_PARAMETER (87) */
804 return FALSE;
805}
LSTATUS WINAPI RegDeleteTreeW(_In_ HKEY, _In_opt_ LPCWSTR)
#define FreeLibrary(x)
Definition: compat.h:748
static LPMONITOR2 pm2
Definition: localmon.c:46
#define ERROR_UNKNOWN_PRINT_MONITOR
Definition: winerror.h:1205

◆ LocalDeletePort()

BOOL WINAPI LocalDeletePort ( PWSTR  pName,
HWND  hWnd,
PWSTR  pPortName 
)

Definition at line 411 of file ports.c.

412{
413 LONG lres;
414 DWORD res = FALSE;
415 PLOCAL_PORT pPrintPort;
416 PLOCAL_PRINT_MONITOR pPrintMonitor;
417
418 FIXME("LocalDeletePort(%S, %p, %S)\n", pName, hWnd, pPortName);
419
421 if (lres)
422 {
423 FIXME("server %s not supported\n", debugstr_w(pName));
425 return FALSE;
426 }
427
428 if (!pPortName[0])
429 {
431 return FALSE;
432 }
433
434 pPrintPort = FindPort(pPortName);
435 if (!pPrintPort )
436 {
438 return FALSE;
439 }
440
441 pPrintMonitor = pPrintPort->pPrintMonitor;
442
443 if ( pPrintMonitor->bIsLevel2 && ((PMONITOR2)pPrintMonitor->pMonitor)->pfnDeletePort )
444 {
445 res = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnDeletePort(pPrintMonitor->hMonitor, pName, hWnd, pPortName);
446 }
447 else if ( !pPrintMonitor->bIsLevel2 && ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnDeletePort )
448 {
449 res = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnDeletePort(pName, hWnd, pPortName);
450 }
451
452 RemoveEntryList(&pPrintPort->Entry);
453
454 DllFreeSplMem(pPrintPort);
455
456 return res;
457}

◆ LocalEndDocPrinter()

BOOL WINAPI LocalEndDocPrinter ( HANDLE  hPrinter)

Definition at line 1857 of file printers.c.

1858{
1859 BOOL bReturnValue;
1860 DWORD dwErrorCode;
1861 PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter;
1862 PLOCAL_PORT_HANDLE pPortHandle;
1863 PLOCAL_PRINTER_HANDLE pPrinterHandle;
1864
1865 TRACE("LocalEndDocPrinter(%p)\n", hPrinter);
1866
1867 // Sanity checks.
1868 if (!pHandle)
1869 {
1870 dwErrorCode = ERROR_INVALID_HANDLE;
1871 goto Cleanup;
1872 }
1873
1874 // Port handles are an entirely different thing.
1875 if (pHandle->HandleType == HandleType_Port)
1876 {
1877 pPortHandle = (PLOCAL_PORT_HANDLE)pHandle->pSpecificHandle;
1878
1879 // Call the monitor's EndDocPort function.
1880 if (pPortHandle->pPort->pPrintMonitor->bIsLevel2)
1881 bReturnValue = ((PMONITOR2)pPortHandle->pPort->pPrintMonitor->pMonitor)->pfnEndDocPort(pPortHandle->hPort);
1882 else
1883 bReturnValue = ((LPMONITOREX)pPortHandle->pPort->pPrintMonitor->pMonitor)->Monitor.pfnEndDocPort(pPortHandle->hPort);
1884
1885 if (!bReturnValue)
1886 {
1887 // The EndDocPort function failed. Return its last error.
1888 dwErrorCode = GetLastError();
1889 goto Cleanup;
1890 }
1891
1892 // We were successful!
1893 dwErrorCode = ERROR_SUCCESS;
1894 goto Cleanup;
1895 }
1896
1897 // The remaining function deals with Printer handles only.
1898 if (pHandle->HandleType != HandleType_Printer)
1899 {
1900 dwErrorCode = ERROR_INVALID_HANDLE;
1901 goto Cleanup;
1902 }
1903
1904 pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle;
1905
1906 // We require StartDocPrinter or AddJob to be called first.
1907 if (!pPrinterHandle->bStartedDoc)
1908 {
1909 dwErrorCode = ERROR_SPL_NO_STARTDOC;
1910 goto Cleanup;
1911 }
1912
1913 // TODO: Something like ScheduleJob
1914
1915 // Finish the job.
1916 pPrinterHandle->bStartedDoc = FALSE;
1917 pPrinterHandle->pJob = NULL;
1918 dwErrorCode = ERROR_SUCCESS;
1919
1920Cleanup:
1921 SetLastError(dwErrorCode);
1922 return (dwErrorCode == ERROR_SUCCESS);
1923}
if(dx< 0)
Definition: linetemp.h:194
PLOCAL_PORT pPort
Definition: precomp.h:183
struct _LOCAL_PORT_HANDLE * PLOCAL_PORT_HANDLE
Definition: precomp.h:59
struct _LOCAL_PRINTER_HANDLE * PLOCAL_PRINTER_HANDLE
Definition: precomp.h:63
#define ERROR_SPL_NO_STARTDOC
Definition: winerror.h:1208

◆ LocalEndPagePrinter()

BOOL WINAPI LocalEndPagePrinter ( HANDLE  hPrinter)

Definition at line 1834 of file printers.c.

1835{
1836 DWORD dwErrorCode;
1837 PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter;
1838
1839 TRACE("LocalEndPagePrinter(%p)\n", hPrinter);
1840
1841 // Sanity checks.
1842 if (!pHandle || pHandle->HandleType != HandleType_Printer)
1843 {
1844 dwErrorCode = ERROR_INVALID_HANDLE;
1845 goto Cleanup;
1846 }
1847
1848 // This function doesn't do anything else for now.
1849 dwErrorCode = ERROR_SUCCESS;
1850
1851Cleanup:
1852 SetLastError(dwErrorCode);
1853 return (dwErrorCode == ERROR_SUCCESS);
1854}

◆ LocalEnumForms()

BOOL WINAPI LocalEnumForms ( HANDLE  hPrinter,
DWORD  Level,
PBYTE  pForm,
DWORD  cbBuf,
PDWORD  pcbNeeded,
PDWORD  pcReturned 
)

Definition at line 549 of file forms.c.

550{
551 DWORD dwErrorCode;
552 PFORM_INFO_LIST pfil = NULL;
553 PBYTE pEnd = &pForm[cbBuf];
554 PLOCAL_HANDLE pHandle;
555 PLIST_ENTRY ListEntry;
556
557 FIXME("EnumForms(%p, %lu, %p, %lu, %p, %p)\n", hPrinter, Level, pForm, cbBuf, pcbNeeded, pcReturned);
558
559 // Check if this is a printer handle.
560 pHandle = (PLOCAL_HANDLE)hPrinter;
561 if (pHandle->HandleType != HandleType_Printer)
562 {
563 dwErrorCode = ERROR_INVALID_HANDLE;
564 goto Cleanup;
565 }
566
567 // Only support 1 & 2
568 if (Level < 1 || Level > 2)
569 {
570 // The caller supplied an invalid level.
571 dwErrorCode = ERROR_INVALID_LEVEL;
572 goto Cleanup;
573 }
574
575 // Count the required buffer size.
576 *pcbNeeded = 0;
577
578 ListEntry = FormList.Flink;
579
580 if (IsListEmpty(ListEntry))
581 {
582 dwErrorCode = ERROR_INVALID_PARAMETER;
583 goto Cleanup;
584 }
585
586 while ( ListEntry != &FormList )
587 {
588 pfil = CONTAINING_RECORD(ListEntry, FORM_INFO_LIST, List);
589 ListEntry = ListEntry->Flink;
590
592 }
593
594 // Check if the supplied buffer is large enough.
595 if (cbBuf < *pcbNeeded)
596 {
597 ERR("Insuffisient Buffer size\n");
598 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
599 goto Cleanup;
600 }
601
602 // Copy over the information.
603 pEnd = &pForm[*pcbNeeded];
604
605 ListEntry = FormList.Flink;
606
607 while ( ListEntry != &FormList )
608 {
609 pfil = CONTAINING_RECORD(ListEntry, FORM_INFO_LIST, List);
610 ListEntry = ListEntry->Flink;
611
612 pfnGetFormLevels[Level](pfil, &pForm, &pEnd, NULL);
613 (*pcReturned)++;
614 }
615
616 dwErrorCode = ERROR_SUCCESS;
617
618Cleanup:
619 SetLastError(dwErrorCode);
620 return (dwErrorCode == ERROR_SUCCESS);
621}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
static const PLocalGetFormLevelFunc pfnGetFormLevels[]
Definition: forms.c:399
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3828

◆ LocalEnumJobs()

BOOL WINAPI LocalEnumJobs ( HANDLE  hPrinter,
DWORD  FirstJob,
DWORD  NoJobs,
DWORD  Level,
PBYTE  pStart,
DWORD  cbBuf,
LPDWORD  pcbNeeded,
LPDWORD  pcReturned 
)

Definition at line 1022 of file jobs.c.

1023{
1024 DWORD dwErrorCode;
1025 DWORD i;
1026 PBYTE pEnd;
1027 PLOCAL_HANDLE pHandle;
1028 PLOCAL_JOB pJob;
1029 PSKIPLIST_NODE pFirstJobNode;
1030 PSKIPLIST_NODE pNode;
1031 PLOCAL_PRINTER_HANDLE pPrinterHandle;
1032
1033 TRACE("LocalEnumJobs(%p, %lu, %lu, %lu, %p, %lu, %p, %p)\n", hPrinter, FirstJob, NoJobs, Level, pStart, cbBuf, pcbNeeded, pcReturned);
1034
1035 // Check if this is a printer handle.
1036 pHandle = (PLOCAL_HANDLE)hPrinter;
1037 if (pHandle->HandleType != HandleType_Printer)
1038 {
1039 dwErrorCode = ERROR_INVALID_HANDLE;
1040 goto Cleanup;
1041 }
1042
1043 pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle;
1044
1045 // Check the level.
1046 if (Level > 2)
1047 {
1048 dwErrorCode = ERROR_INVALID_LEVEL;
1049 goto Cleanup;
1050 }
1051
1052 // Begin counting.
1053 *pcbNeeded = 0;
1054 *pcReturned = 0;
1055
1056 // Lookup the node of the first job requested by the caller in the Printer's Job List.
1057 pFirstJobNode = LookupNodeByIndexSkiplist(&pPrinterHandle->pPrinter->JobList, FirstJob);
1058
1059 // Count the required buffer size and the number of jobs.
1060 i = 0;
1061 pNode = pFirstJobNode;
1062
1063 while (i < NoJobs && pNode)
1064 {
1065 pJob = (PLOCAL_JOB)pNode->Element;
1066
1067 if (Level == 1)
1069 else if (Level == 2)
1071
1072 // We stop either when there are no more jobs in the list or when the caller didn't request more, whatever comes first.
1073 i++;
1074 pNode = pNode->Next[0];
1075 }
1076
1077 // Check if the supplied buffer is large enough.
1078 if (cbBuf < *pcbNeeded)
1079 {
1080 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
1081 goto Cleanup;
1082 }
1083
1084 // Copy over the Job information.
1085 i = 0;
1086 pNode = pFirstJobNode;
1087 pEnd = &pStart[*pcbNeeded];
1088
1089 while (i < NoJobs && pNode)
1090 {
1091 pJob = (PLOCAL_JOB)pNode->Element;
1092
1093 if (Level == 1)
1094 _LocalGetJobLevel1(pJob, (PJOB_INFO_1W*)&pStart, &pEnd, NULL);
1095 else if (Level == 2)
1096 _LocalGetJobLevel2(pJob, (PJOB_INFO_2W*)&pStart, &pEnd, NULL);
1097
1098 // We stop either when there are no more jobs in the list or when the caller didn't request more, whatever comes first.
1099 i++;
1100 pNode = pNode->Next[0];
1101 }
1102
1103 *pcReturned = i;
1104 dwErrorCode = ERROR_SUCCESS;
1105
1106Cleanup:
1107 SetLastError(dwErrorCode);
1108 return (dwErrorCode == ERROR_SUCCESS);
1109}
static void _LocalGetJobLevel1(PLOCAL_JOB pJob, PJOB_INFO_1W *ppJobInfo, PBYTE *ppJobInfoEnd, PDWORD pcbNeeded)
Definition: jobs.c:450
static void _LocalGetJobLevel2(PLOCAL_JOB pJob, PJOB_INFO_2W *ppJobInfo, PBYTE *ppJobInfoEnd, PDWORD pcbNeeded)
Definition: jobs.c:524
PSKIPLIST_NODE LookupNodeByIndexSkiplist(PSKIPLIST Skiplist, DWORD ElementIndex)
Definition: skiplist.c:412
struct _LOCAL_JOB * PLOCAL_JOB
Definition: precomp.h:57

◆ LocalEnumMonitors()

BOOL WINAPI LocalEnumMonitors ( PWSTR  pName,
DWORD  Level,
PBYTE  pMonitors,
DWORD  cbBuf,
PDWORD  pcbNeeded,
PDWORD  pcReturned 
)

Definition at line 396 of file monitors.c.

397{
398 DWORD dwErrorCode;
399 PBYTE pMonitorInfoEnd;
401 PLOCAL_PRINT_MONITOR pPrintMonitor;
402
403 TRACE("LocalEnumMonitors(%S, %lu, %p, %lu, %p, %p)\n", pName, Level, pMonitors, cbBuf, pcbNeeded, pcReturned);
404
405 // Sanity checks.
406 if (Level > 2)
407 {
408 dwErrorCode = ERROR_INVALID_LEVEL;
409 goto Cleanup;
410 }
411
412 // Begin counting.
413 *pcbNeeded = 0;
414 *pcReturned = 0;
415
416 // Count the required buffer size and the number of monitors.
418 {
420
421 if (Level == 1)
422 _LocalGetMonitorLevel1(pPrintMonitor, NULL, NULL, pcbNeeded);
423 else if (Level == 2)
424 _LocalGetMonitorLevel2(pPrintMonitor, NULL, NULL, pcbNeeded);
425 }
426
427 // Check if the supplied buffer is large enough.
428 if (cbBuf < *pcbNeeded)
429 {
430 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
431 goto Cleanup;
432 }
433
434 // Copy over the Monitor information.
435 pMonitorInfoEnd = &pMonitors[*pcbNeeded];
436
438 {
440
441 if (Level == 1)
442 _LocalGetMonitorLevel1(pPrintMonitor, (PMONITOR_INFO_1W*)&pMonitors, &pMonitorInfoEnd, NULL);
443 else if (Level == 2)
444 _LocalGetMonitorLevel2(pPrintMonitor, (PMONITOR_INFO_2W*)&pMonitors, &pMonitorInfoEnd, NULL);
445
446 (*pcReturned)++;
447 }
448
449 dwErrorCode = ERROR_SUCCESS;
450
451Cleanup:
452 SetLastError(dwErrorCode);
453 return (dwErrorCode == ERROR_SUCCESS);
454}
static void _LocalGetMonitorLevel2(PLOCAL_PRINT_MONITOR pPrintMonitor, PMONITOR_INFO_2W *ppMonitorInfo, PBYTE *ppMonitorInfoEnd, PDWORD pcbNeeded)
Definition: monitors.c:365
static void _LocalGetMonitorLevel1(PLOCAL_PRINT_MONITOR pPrintMonitor, PMONITOR_INFO_1W *ppMonitorInfo, PBYTE *ppMonitorInfoEnd, PDWORD pcbNeeded)
Definition: monitors.c:342

◆ LocalEnumPorts()

BOOL WINAPI LocalEnumPorts ( PWSTR  pName,
DWORD  Level,
PBYTE  pPorts,
DWORD  cbBuf,
PDWORD  pcbNeeded,
PDWORD  pcReturned 
)

Definition at line 164 of file ports.c.

165{
166 BOOL bReturnValue = TRUE;
167 DWORD cbCallBuffer;
168 DWORD cbNeeded;
169 DWORD dwReturned;
170 PBYTE pCallBuffer;
171 PLOCAL_PRINT_MONITOR pPrintMonitor;
173
174 TRACE("LocalEnumPorts(%S, %lu, %p, %lu, %p, %p)\n", pName, Level, pPorts, cbBuf, pcbNeeded, pcReturned);
175
176 // Begin counting.
177 *pcbNeeded = 0;
178 *pcReturned = 0;
179
180 // At the beginning, we have the full buffer available.
181 cbCallBuffer = cbBuf;
182 pCallBuffer = pPorts;
183
184 // Loop through all Print Monitors.
186 {
188
189 // Call the EnumPorts function of this Print Monitor.
190 cbNeeded = 0;
191 dwReturned = 0;
192
193 if (pPrintMonitor->bIsLevel2)
194 bReturnValue = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnEnumPorts(pPrintMonitor->hMonitor, pName, Level, pCallBuffer, cbCallBuffer, &cbNeeded, &dwReturned);
195 else
196 bReturnValue = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnEnumPorts(pName, Level, pCallBuffer, cbCallBuffer, &cbNeeded, &dwReturned);
197
198 // Add the returned counts to the total values.
199 *pcbNeeded += cbNeeded;
200 *pcReturned += dwReturned;
201
202 // Reduce the available buffer size for the next call without risking an underflow.
203 if (cbNeeded < cbCallBuffer)
204 cbCallBuffer -= cbNeeded;
205 else
206 cbCallBuffer = 0;
207
208 // Advance the buffer if the caller provided it.
209 if (pCallBuffer)
210 pCallBuffer += cbNeeded;
211 }
212
213 return bReturnValue;
214}

Referenced by LocalAddPort().

◆ LocalEnumPrinterDrivers()

BOOL WINAPI LocalEnumPrinterDrivers ( PWSTR  pName,
PWSTR  pEnvironment,
DWORD  Level,
PBYTE  pDriverInfo,
DWORD  cbBuf,
PDWORD  pcbNeeded,
PDWORD  pcReturned 
)

Definition at line 600 of file printerdrivers.c.

601{
602 DWORD dwErrorCode;
603 PSKIPLIST_NODE pNode;
604 PBYTE pEnd;
605 PLOCAL_PRINTER pPrinter;
606
607 FIXME("LocalEnumPrinterDrivers(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded, pcReturned);
608
609 // Only support 8 levels and not 7
610 if (Level < 1 || Level == 7 || Level > 8)
611 {
612 // The caller supplied an invalid level.
613 dwErrorCode = ERROR_INVALID_LEVEL;
614 goto Cleanup;
615 }
616
617 // Count the required buffer size.
618 *pcbNeeded = 0;
619
620 // Count the required buffer size and the number of printers.
621 for (pNode = PrinterList.Head.Next[0]; pNode; pNode = pNode->Next[0])
622 {
623 pPrinter = (PLOCAL_PRINTER)pNode->Element;
624
626 }
627
628 // Check if the supplied buffer is large enough.
629 if (cbBuf < *pcbNeeded)
630 {
631 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
632 goto Cleanup;
633 }
634
635 // Copy over the Printer information.
636 pEnd = &pDriverInfo[*pcbNeeded];
637
638 for (pNode = PrinterList.Head.Next[0]; pNode; pNode = pNode->Next[0])
639 {
640 pPrinter = (PLOCAL_PRINTER)pNode->Element;
641
642 pfnPrinterDriverLevels[Level](pPrinter, &pDriverInfo, &pEnd, NULL);
643 (*pcReturned)++;
644 }
645
646 dwErrorCode = ERROR_SUCCESS;
647
648Cleanup:
649 SetLastError(dwErrorCode);
650 return (dwErrorCode == ERROR_SUCCESS);
651}
static const PLocalPrinterDriverLevelFunc pfnPrinterDriverLevels[]
SKIPLIST PrinterList
Definition: printers.c:11

◆ LocalEnumPrinters()

BOOL WINAPI LocalEnumPrinters ( DWORD  Flags,
LPWSTR  Name,
DWORD  Level,
LPBYTE  pPrinterEnum,
DWORD  cbBuf,
LPDWORD  pcbNeeded,
LPDWORD  pcReturned 
)

Definition at line 884 of file printers.c.

885{
886 DWORD cchComputerName = 0;
887 DWORD dwErrorCode;
888 PBYTE pPrinterInfoEnd;
889 PSKIPLIST_NODE pNode;
890 WCHAR wszComputerName[2 + MAX_COMPUTERNAME_LENGTH + 1 + 1] = { 0 };
891 PLOCAL_PRINTER pPrinter;
892
893 FIXME("LocalEnumPrinters(%lu, %S, %lu, %p, %lu, %p, %p)\n", Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
894
895 // Do no sanity checks or assertions for pcbNeeded and pcReturned here.
896 // This is verified and required by localspl_apitest!
897
898 // Begin counting.
899 *pcbNeeded = 0;
900 *pcReturned = 0;
901
903 {
904 // If the flags for the Network Print Provider are given, bail out with ERROR_INVALID_NAME.
905 // This is the internal way for a Print Provider to signal that it doesn't handle this request.
906 dwErrorCode = ERROR_INVALID_NAME;
907 goto Cleanup;
908 }
909
911 {
912 // The Local Print Provider is the right destination for the request, but without any of these flags,
913 // there is no information that can be returned.
914 // So just signal a successful request.
915 dwErrorCode = ERROR_SUCCESS;
916 goto Cleanup;
917 }
918
919 if (Level == 3 || Level > 5)
920 {
921 // The caller supplied an invalid level for EnumPrinters.
922 dwErrorCode = ERROR_INVALID_LEVEL;
923 goto Cleanup;
924 }
925
926 if (Level == 1 && Flags & PRINTER_ENUM_NAME && !Name)
927 {
928 // The caller wants information about this Print Provider.
929 // spoolss packs this into an array of information about all Print Providers.
930 dwErrorCode = _DumpLevel1PrintProviderInformation(pPrinterEnum, cbBuf, pcbNeeded, pcReturned);
931 goto Cleanup;
932 }
933
934 // Check the supplied Name parameter (if any).
935 // This may return a Computer Name string we later prepend to the output.
936 dwErrorCode = _LocalEnumPrintersCheckName(Flags, Name, wszComputerName, &cchComputerName);
937 if (dwErrorCode != ERROR_SUCCESS)
938 goto Cleanup;
939
940 // Count the required buffer size and the number of printers.
941 for (pNode = PrinterList.Head.Next[0]; pNode; pNode = pNode->Next[0])
942 {
943 pPrinter = (PLOCAL_PRINTER)pNode->Element;
944
945 // TODO: If PRINTER_ENUM_SHARED is given, add this Printer if it's shared instead of just ignoring it.
947 {
948 FIXME("Printer Sharing is not supported yet, returning no printers!\n");
949 continue;
950 }
951
952 pfnGetPrinterLevels[Level](pPrinter, NULL, NULL, pcbNeeded, cchComputerName, wszComputerName);
953 }
954
955 // Check if the supplied buffer is large enough.
956 if (cbBuf < *pcbNeeded)
957 {
958 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
959 goto Cleanup;
960 }
961
962 // Copy over the Printer information.
963 pPrinterInfoEnd = &pPrinterEnum[*pcbNeeded];
964
965 for (pNode = PrinterList.Head.Next[0]; pNode; pNode = pNode->Next[0])
966 {
967 pPrinter = (PLOCAL_PRINTER)pNode->Element;
968
969 // TODO: If PRINTER_ENUM_SHARED is given, add this Printer if it's shared instead of just ignoring it.
971 continue;
972
973 pfnGetPrinterLevels[Level](pPrinter, &pPrinterEnum, &pPrinterInfoEnd, NULL, cchComputerName, wszComputerName);
974 (*pcReturned)++;
975 }
976
977 dwErrorCode = ERROR_SUCCESS;
978
979Cleanup:
980 SetLastError(dwErrorCode);
981 return (dwErrorCode == ERROR_SUCCESS);
982}
static DWORD _DumpLevel1PrintProviderInformation(PBYTE pPrinterEnum, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
Definition: printers.c:486
static const PLocalGetPrinterLevelFunc pfnGetPrinterLevels[]
Definition: printers.c:28
static DWORD _LocalEnumPrintersCheckName(DWORD Flags, PCWSTR Name, PWSTR pwszComputerName, PDWORD pcchComputerName)
Definition: printers.c:391
#define PRINTER_ENUM_SHARED
Definition: winspool.h:901
#define PRINTER_ENUM_LOCAL
Definition: winspool.h:896
#define PRINTER_ENUM_NETWORK
Definition: winspool.h:902
#define PRINTER_ENUM_NAME
Definition: winspool.h:899
#define PRINTER_ENUM_REMOTE
Definition: winspool.h:900
#define PRINTER_ENUM_CONNECTIONS
Definition: winspool.h:897
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

◆ LocalEnumPrintProcessorDatatypes()

BOOL WINAPI LocalEnumPrintProcessorDatatypes ( LPWSTR  pName,
LPWSTR  pPrintProcessorName,
DWORD  Level,
LPBYTE  pDatatypes,
DWORD  cbBuf,
LPDWORD  pcbNeeded,
LPDWORD  pcReturned 
)

Definition at line 402 of file printprocessors.c.

403{
404 DWORD dwErrorCode;
405 PLOCAL_PRINT_PROCESSOR pPrintProcessor;
406
407 TRACE("LocalEnumPrintProcessorDatatypes(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
408
409 // Sanity checks
410 if (Level != 1)
411 {
412 dwErrorCode = ERROR_INVALID_LEVEL;
413 goto Cleanup;
414 }
415
416 // Try to find the Print Processor.
417 pPrintProcessor = FindPrintProcessor(pPrintProcessorName);
418 if (!pPrintProcessor)
419 {
420 dwErrorCode = ERROR_UNKNOWN_PRINTPROCESSOR;
421 goto Cleanup;
422 }
423
424 // Call its EnumPrintProcessorDatatypesW function.
425 if (pPrintProcessor->pfnEnumPrintProcessorDatatypesW(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned))
426 dwErrorCode = ERROR_SUCCESS;
427 else
428 dwErrorCode = GetLastError();
429
430Cleanup:
431 SetLastError(dwErrorCode);
432 return (dwErrorCode == ERROR_SUCCESS);
433}
PLOCAL_PRINT_PROCESSOR FindPrintProcessor(PCWSTR pwszName)
#define ERROR_UNKNOWN_PRINTPROCESSOR
Definition: winerror.h:1105

◆ LocalEnumPrintProcessors()

BOOL WINAPI LocalEnumPrintProcessors ( LPWSTR  pName,
LPWSTR  pEnvironment,
DWORD  Level,
LPBYTE  pPrintProcessorInfo,
DWORD  cbBuf,
LPDWORD  pcbNeeded,
LPDWORD  pcReturned 
)

Definition at line 471 of file printprocessors.c.

472{
473 DWORD cchMaxSubKey;
474 DWORD cchPrintProcessor;
475 DWORD dwErrorCode;
476 DWORD dwPrintProcessorCount;
477 DWORD i;
478 HKEY hKey = NULL;
479 HKEY hSubKey = NULL;
480 PBYTE pCurrentOutputPrintProcessor;
481 PBYTE pCurrentOutputPrintProcessorInfo;
482 PRINTPROCESSOR_INFO_1W PrintProcessorInfo1;
483 PWSTR pwszTemp = NULL;
484
485 TRACE("LocalEnumPrintProcessors(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
486
487 // Sanity checks
488 if (Level != 1)
489 {
490 dwErrorCode = ERROR_INVALID_LEVEL;
491 goto Cleanup;
492 }
493
494 if (!pcbNeeded || !pcReturned)
495 {
496 // This error is also caught by RPC and returned as RPC_X_NULL_REF_POINTER.
497 dwErrorCode = ERROR_INVALID_PARAMETER;
498 goto Cleanup;
499 }
500
501 // Verify pEnvironment and open its registry key.
502 // We use the registry and not the PrintProcessorList here, because the caller may request information about a different environment.
503 dwErrorCode = _OpenEnvironment(pEnvironment, &hKey);
504 if (dwErrorCode != ERROR_SUCCESS)
505 goto Cleanup;
506
507 // Open the "Print Processors" subkey.
508 dwErrorCode = (DWORD)RegOpenKeyExW(hKey, L"Print Processors", 0, KEY_READ, &hSubKey);
509 if (dwErrorCode != ERROR_SUCCESS)
510 {
511 ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
512 goto Cleanup;
513 }
514
515 // Get the number of Print Processors and maximum sub key length.
516 dwErrorCode = (DWORD)RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &dwPrintProcessorCount, &cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
517 if (dwErrorCode != ERROR_SUCCESS)
518 {
519 ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
520 goto Cleanup;
521 }
522
523 // Allocate a temporary buffer to let RegEnumKeyExW succeed.
524 pwszTemp = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
525 if (!pwszTemp)
526 {
527 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
528 ERR("DllAllocSplMem failed!\n");
529 goto Cleanup;
530 }
531
532 // Determine the required size of the output buffer.
533 *pcbNeeded = 0;
534
535 for (i = 0; i < dwPrintProcessorCount; i++)
536 {
537 // RegEnumKeyExW sucks! Unlike similar API functions, it only returns the actual numbers of characters copied when you supply a buffer large enough.
538 // So use pwszTemp with its size cchMaxSubKey for this.
539 cchPrintProcessor = cchMaxSubKey + 1;
540 dwErrorCode = (DWORD)RegEnumKeyExW(hSubKey, i, pwszTemp, &cchPrintProcessor, NULL, NULL, NULL, NULL);
541 if (dwErrorCode != ERROR_SUCCESS)
542 {
543 ERR("RegEnumKeyExW failed with status %lu!\n", dwErrorCode);
544 goto Cleanup;
545 }
546
547 *pcbNeeded += sizeof(PRINTPROCESSOR_INFO_1W) + (cchPrintProcessor + 1) * sizeof(WCHAR);
548 }
549
550 // Check if the supplied buffer is large enough.
551 if (cbBuf < *pcbNeeded)
552 {
553 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
554 goto Cleanup;
555 }
556
557 // Put the Print Processor strings right after the last PRINTPROCESSOR_INFO_1W structure.
558 pCurrentOutputPrintProcessorInfo = pPrintProcessorInfo;
559 pCurrentOutputPrintProcessor = pPrintProcessorInfo + dwPrintProcessorCount * sizeof(PRINTPROCESSOR_INFO_1W);
560
561 // Copy over all Print Processors.
562 for (i = 0; i < dwPrintProcessorCount; i++)
563 {
564 // This isn't really correct, but doesn't cause any harm, because we've extensively checked the size of the supplied buffer above.
565 cchPrintProcessor = cchMaxSubKey + 1;
566
567 // Copy the Print Processor name.
568 dwErrorCode = (DWORD)RegEnumKeyExW(hSubKey, i, (PWSTR)pCurrentOutputPrintProcessor, &cchPrintProcessor, NULL, NULL, NULL, NULL);
569 if (dwErrorCode != ERROR_SUCCESS)
570 {
571 ERR("RegEnumKeyExW failed with status %lu!\n", dwErrorCode);
572 goto Cleanup;
573 }
574
575 // Fill and copy the PRINTPROCESSOR_INFO_1W structure belonging to this Print Processor.
576 PrintProcessorInfo1.pName = (PWSTR)pCurrentOutputPrintProcessor;
577 CopyMemory(pCurrentOutputPrintProcessorInfo, &PrintProcessorInfo1, sizeof(PRINTPROCESSOR_INFO_1W));
578
579 // Advance to the next PRINTPROCESSOR_INFO_1W location and string location in the output buffer.
580 pCurrentOutputPrintProcessor += (cchPrintProcessor + 1) * sizeof(WCHAR);
581 pCurrentOutputPrintProcessorInfo += sizeof(PRINTPROCESSOR_INFO_1W);
582 }
583
584 // We've finished successfully!
585 *pcReturned = dwPrintProcessorCount;
586 dwErrorCode = ERROR_SUCCESS;
587
588Cleanup:
589 if (pwszTemp)
590 DllFreeSplMem(pwszTemp);
591
592 if (hSubKey)
593 RegCloseKey(hSubKey);
594
595 if (hKey)
597
598 SetLastError(dwErrorCode);
599 return (dwErrorCode == ERROR_SUCCESS);
600}
struct _PRINTPROCESSOR_INFO_1W PRINTPROCESSOR_INFO_1W

◆ LocalGetForm()

BOOL WINAPI LocalGetForm ( HANDLE  hPrinter,
PWSTR  pFormName,
DWORD  Level,
PBYTE  pForm,
DWORD  cbBuf,
PDWORD  pcbNeeded 
)

Definition at line 624 of file forms.c.

625{
626 DWORD dwErrorCode;
627 PFORM_INFO_LIST pfil;
628 PBYTE pEnd = &pForm[cbBuf];
629 PLOCAL_HANDLE pHandle;
630
631 FIXME("GetForm(%p, %S, %lu, %p, %lu, %p)\n", hPrinter, pFormName, Level, pForm, cbBuf, pcbNeeded);
632
633 // Check if this is a printer handle.
634 pHandle = (PLOCAL_HANDLE)hPrinter;
635 if (pHandle->HandleType != HandleType_Printer)
636 {
637 dwErrorCode = ERROR_INVALID_HANDLE;
638 goto Cleanup;
639 }
640
641 // Only support 1 & 2
642 if (Level < 1 || Level > 2)
643 {
644 // The caller supplied an invalid level.
645 dwErrorCode = ERROR_INVALID_LEVEL;
646 goto Cleanup;
647 }
648
649 pfil = FindForm( pFormName, NULL );
650 if ( !pfil )
651 {
652 dwErrorCode = ERROR_INVALID_PARAMETER;
653 goto Cleanup;
654 }
655
656 // Count the required buffer size.
657 *pcbNeeded = 0;
658
660
661 // Check if the supplied buffer is large enough.
662 if (cbBuf < *pcbNeeded)
663 {
664 ERR("Insuffisient Buffer size\n");
665 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
666 goto Cleanup;
667 }
668
669 // Copy over the information.
670 pEnd = &pForm[*pcbNeeded];
671
672 pfnGetFormLevels[Level](pfil, &pForm, &pEnd, NULL);
673
674 dwErrorCode = ERROR_SUCCESS;
675
676Cleanup:
677 SetLastError(dwErrorCode);
678 return (dwErrorCode == ERROR_SUCCESS);
679}

◆ LocalGetJob()

BOOL WINAPI LocalGetJob ( HANDLE  hPrinter,
DWORD  JobId,
DWORD  Level,
PBYTE  pStart,
DWORD  cbBuf,
LPDWORD  pcbNeeded 
)

Definition at line 655 of file jobs.c.

656{
657 DWORD dwErrorCode;
658 PBYTE pEnd = &pStart[cbBuf];
659 PLOCAL_HANDLE pHandle;
660 PLOCAL_JOB pJob;
661 PLOCAL_PRINTER_HANDLE pPrinterHandle;
662
663 TRACE("LocalGetJob(%p, %lu, %lu, %p, %lu, %p)\n", hPrinter, JobId, Level, pStart, cbBuf, pcbNeeded);
664
665 // Check if this is a printer handle.
666 pHandle = (PLOCAL_HANDLE)hPrinter;
667 if (pHandle->HandleType != HandleType_Printer)
668 {
669 dwErrorCode = ERROR_INVALID_HANDLE;
670 goto Cleanup;
671 }
672
673 pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle;
674
675 // Get the desired job.
676 pJob = LookupElementSkiplist(&GlobalJobList, &JobId, NULL);
677 if (!pJob || pJob->pPrinter != pPrinterHandle->pPrinter)
678 {
679 dwErrorCode = ERROR_INVALID_PARAMETER;
680 goto Cleanup;
681 }
682
683 if (Level > 2)
684 {
685 // The caller supplied an invalid level for GetJob.
686 dwErrorCode = ERROR_INVALID_LEVEL;
687 goto Cleanup;
688 }
689
690 // Count the required buffer size.
691 *pcbNeeded = 0;
692
693 if (Level == 1)
695 else if (Level == 2)
697
698 // Check if the supplied buffer is large enough.
699 if (cbBuf < *pcbNeeded)
700 {
701 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
702 goto Cleanup;
703 }
704
705 // Copy over the Job information.
706 pEnd = &pStart[*pcbNeeded];
707
708 if (Level == 1)
709 _LocalGetJobLevel1(pJob, (PJOB_INFO_1W*)&pStart, &pEnd, NULL);
710 else if (Level == 2)
711 _LocalGetJobLevel2(pJob, (PJOB_INFO_2W*)&pStart, &pEnd, NULL);
712
713 dwErrorCode = ERROR_SUCCESS;
714
715Cleanup:
716 SetLastError(dwErrorCode);
717 return (dwErrorCode == ERROR_SUCCESS);
718}
PVOID LookupElementSkiplist(PSKIPLIST Skiplist, PVOID Element, PDWORD ElementIndex)
Definition: skiplist.c:357

◆ LocalGetPrinter()

BOOL WINAPI LocalGetPrinter ( HANDLE  hPrinter,
DWORD  Level,
LPBYTE  pPrinter,
DWORD  cbBuf,
LPDWORD  pcbNeeded 
)

Definition at line 985 of file printers.c.

986{
987 // We never prepend a Computer Name to the output, but need to provide an empty string,
988 // because this variable is passed to StringCbCopyExW.
989 const WCHAR wszDummyComputerName[] = L"";
990
991 DWORD dwErrorCode;
992 PBYTE pPrinterEnd;
993 PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter;
994 PLOCAL_PRINTER_HANDLE pPrinterHandle;
995
996 TRACE("LocalGetPrinter(%p, %lu, %p, %lu, %p)\n", hPrinter, Level, pPrinter, cbBuf, pcbNeeded);
997
998 // Sanity checks.
999 if (!pHandle)
1000 {
1001 dwErrorCode = ERROR_INVALID_HANDLE;
1002 goto Cleanup;
1003 }
1004
1005 // Check if this is a printer handle.
1006 if (pHandle->HandleType != HandleType_Printer)
1007 {
1008 dwErrorCode = ERROR_INVALID_HANDLE;
1009 goto Cleanup;
1010 }
1011
1012 pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle;
1013
1014 if (Level > 9)
1015 {
1016 // The caller supplied an invalid level for GetPrinter.
1017 dwErrorCode = ERROR_INVALID_LEVEL;
1018 goto Cleanup;
1019 }
1020
1021 // Count the required buffer size.
1022 *pcbNeeded = 0;
1023 pfnGetPrinterLevels[Level](pPrinterHandle->pPrinter, NULL, NULL, pcbNeeded, 0, wszDummyComputerName);
1024
1025 // Check if the supplied buffer is large enough.
1026 if (cbBuf < *pcbNeeded)
1027 {
1028 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
1029 goto Cleanup;
1030 }
1031
1032 // Copy over the Printer information.
1033 pPrinterEnd = &pPrinter[*pcbNeeded];
1034 pfnGetPrinterLevels[Level](pPrinterHandle->pPrinter, &pPrinter, &pPrinterEnd, NULL, 0, wszDummyComputerName);
1035 dwErrorCode = ERROR_SUCCESS;
1036
1037Cleanup:
1038 SetLastError(dwErrorCode);
1039 return (dwErrorCode == ERROR_SUCCESS);
1040}

◆ LocalGetPrinterData()

DWORD WINAPI LocalGetPrinterData ( HANDLE  hPrinter,
PWSTR  pValueName,
PDWORD  pType,
PBYTE  pData,
DWORD  nSize,
PDWORD  pcbNeeded 
)

Definition at line 11 of file printerdata.c.

12{
13 TRACE("LocalGetPrinterData(%p, %S, %p, %p, %lu, %p)\n", hPrinter, pValueName, pType, pData, nSize, pcbNeeded);
14
15 // The ReactOS Printing Stack forwards all GetPrinterData calls to GetPrinterDataEx as soon as possible.
16 // This function may only be called if localspl.dll is used together with Windows Printing Stack components.
17 WARN("This function should never be called!\n");
18 return LocalGetPrinterDataEx(hPrinter, L"PrinterDriverData", pValueName, pType, pData, nSize, pcbNeeded);
19}
#define WARN(fmt,...)
Definition: debug.h:112
DWORD WINAPI LocalGetPrinterDataEx(HANDLE hPrinter, PCWSTR pKeyName, PCWSTR pValueName, PDWORD pType, PBYTE pData, DWORD nSize, PDWORD pcbNeeded)
Definition: printerdata.c:314
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2084

◆ LocalGetPrinterDataEx()

DWORD WINAPI LocalGetPrinterDataEx ( HANDLE  hPrinter,
PCWSTR  pKeyName,
PCWSTR  pValueName,
PDWORD  pType,
PBYTE  pData,
DWORD  nSize,
PDWORD  pcbNeeded 
)

Definition at line 314 of file printerdata.c.

315{
316 BYTE Temp;
317 DWORD dwErrorCode;
318 DWORD dwTemp;
319 PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter;
320
321 TRACE("LocalGetPrinterDataEx(%p, %S, %S, %p, %p, %lu, %p)\n", hPrinter, pKeyName, pValueName, pType, pData, nSize, pcbNeeded);
322
323 // Even if GetPrinterDataExW in winspool ensures that the RPC function is never called without a valid pointer for pType,
324 // it's officially optional. Windows' fpGetPrinterDataEx also works with NULL for pType!
325 // Ensure here that it is always set to simplify the code later.
326 if (!pType)
327 pType = &dwTemp;
328
329 // pData is later fed to RegQueryValueExW in many cases. When calling it with zero buffer size, RegQueryValueExW returns a
330 // different error code based on whether pData is NULL or something else.
331 // Ensure here that ERROR_MORE_DATA is always returned.
332 if (!pData)
333 pData = &Temp;
334
335 if (!pHandle)
336 {
337 dwErrorCode = ERROR_INVALID_HANDLE;
338 }
339 else if (!pcbNeeded)
340 {
341 dwErrorCode = ERROR_INVALID_PARAMETER;
342 }
343 else if (pHandle->HandleType == HandleType_Printer)
344 {
345 dwErrorCode = _LocalGetPrinterHandleData(pHandle->pSpecificHandle, pKeyName, pValueName, pType, pData, nSize, pcbNeeded);
346 }
347 else if (pHandle->HandleType == HandleType_PrintServer)
348 {
349 dwErrorCode = _LocalGetPrintServerHandleData(pValueName, pType, pData, nSize, pcbNeeded);
350 }
351 else
352 {
353 dwErrorCode = ERROR_INVALID_HANDLE;
354 }
355
356 SetLastError(dwErrorCode);
357 return dwErrorCode;
358}
static DWORD _LocalGetPrintServerHandleData(PCWSTR pValueName, PDWORD pType, PBYTE pData, DWORD nSize, PDWORD pcbNeeded)
Definition: printerdata.c:82
static DWORD _LocalGetPrinterHandleData(PLOCAL_PRINTER_HANDLE pPrinterHandle, PCWSTR pKeyName, PCWSTR pValueName, PDWORD pType, PBYTE pData, DWORD nSize, PDWORD pcbNeeded)
Definition: printerdata.c:49
unsigned char BYTE
Definition: xxhash.c:193

Referenced by LocalGetPrinterData().

◆ LocalGetPrinterDriver()

BOOL WINAPI LocalGetPrinterDriver ( HANDLE  hPrinter,
LPWSTR  pEnvironment,
DWORD  Level,
LPBYTE  pDriverInfo,
DWORD  cbBuf,
LPDWORD  pcbNeeded 
)

Definition at line 530 of file printerdrivers.c.

531{
532 DWORD dwErrorCode;
533 PBYTE pEnd = &pDriverInfo[cbBuf];
534 PLOCAL_HANDLE pHandle;
535 PLOCAL_PRINTER_HANDLE pPrinterHandle;
536
537 TRACE("LocalGetPrinterDriver(%p, %lu, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded);
538
539 // Check if this is a printer handle.
540 pHandle = (PLOCAL_HANDLE)hPrinter;
541 if (pHandle->HandleType != HandleType_Printer)
542 {
543 dwErrorCode = ERROR_INVALID_HANDLE;
544 goto Cleanup;
545 }
546
547 pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle;
548
549 // Only support 8 levels and not 7
550 if (Level < 1 || Level == 7 || Level > 8)
551 {
552 // The caller supplied an invalid level.
553 dwErrorCode = ERROR_INVALID_LEVEL;
554 goto Cleanup;
555 }
556
557 // Count the required buffer size.
558 *pcbNeeded = 0;
559
561
562 // Check if the supplied buffer is large enough.
563 if (cbBuf < *pcbNeeded)
564 {
565 ERR("Insuffisient Buffer size\n");
566 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
567 goto Cleanup;
568 }
569
570 // Copy over the information.
571 pEnd = &pDriverInfo[*pcbNeeded];
572
573 pfnPrinterDriverLevels[Level](pPrinterHandle->pPrinter, &pDriverInfo, &pEnd, NULL);
574
575 dwErrorCode = ERROR_SUCCESS;
576
577Cleanup:
578 SetLastError(dwErrorCode);
579 return (dwErrorCode == ERROR_SUCCESS);
580}

Referenced by LocalGetPrinterDriverEx().

◆ LocalGetPrinterDriverDirectory()

BOOL WINAPI LocalGetPrinterDriverDirectory ( PWSTR  pName,
PWSTR  pEnvironment,
DWORD  Level,
PBYTE  pDriverDirectory,
DWORD  cbBuf,
PDWORD  pcbNeeded 
)

Definition at line 778 of file printerdrivers.c.

779{
780 DWORD needed;
781 const PRINTENV_T * env = NULL;
782 WCHAR * const dir = (WCHAR *)pDriverDirectory;
783
784 FIXME("LocalGetPrinterDriverDirectory(%S, %S, %lu, %p, %lu, %p)\n", pName, pEnvironment, Level, pDriverDirectory, cbBuf, pcbNeeded);
785
786 if (pName != NULL && pName[0])
787 {
788 FIXME("server %s not supported\n", debugstr_w(pName));
790 return FALSE;
791 }
792
793 env = validate_envW(pEnvironment);
794 if (!env) return FALSE; /* pEnvironment invalid or unsupported */
795
796 /* GetSystemDirectoryW returns number of WCHAR including the '\0' */
797 needed = GetSystemDirectoryW(NULL, 0);
798 /* add the Size for the Subdirectories */
799 needed += lstrlenW(spoolW);
800 needed += lstrlenW(driversW);
801 needed += lstrlenW(env->subdir);
802 needed *= sizeof(WCHAR); /* return-value is size in Bytes */
803
804 *pcbNeeded = needed;
805
806 if (needed > cbBuf)
807 {
809 return FALSE;
810 }
811
812 if (dir == NULL)
813 {
814 /* ERROR_INVALID_USER_BUFFER is NT, ERROR_INVALID_PARAMETER is win9x */
816 return FALSE;
817 }
818
819 GetSystemDirectoryW( dir, cbBuf / sizeof(WCHAR) );
820 /* add the Subdirectories */
821 lstrcatW( dir, spoolW );
825 lstrcatW( dir, env->subdir );
827
828 FIXME( "=> %s\n", debugstr_w( dir ) );
829 return TRUE;
830}
unsigned int dir
Definition: maze.c:112
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
static const WCHAR spoolW[]
static const WCHAR driversW[]
PPRINTENV_T validate_envW(LPCWSTR env)
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091

Referenced by driver_load(), InitializePrinterDrivers(), and myAddPrinterDriverEx().

◆ LocalGetPrinterDriverEx()

BOOL WINAPI LocalGetPrinterDriverEx ( HANDLE  hPrinter,
LPWSTR  pEnvironment,
DWORD  Level,
LPBYTE  pDriverInfo,
DWORD  cbBuf,
LPDWORD  pcbNeeded,
DWORD  dwClientMajorVersion,
DWORD  dwClientMinorVersion,
PDWORD  pdwServerMajorVersion,
PDWORD  pdwServerMinorVersion 
)

Definition at line 582 of file printerdrivers.c.

593{
594 FIXME("LocalGetPrinterDriverEx(%p, %lu, %lu, %p, %lu, %p, %lu, %lu, %p, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMajorVersion, pdwServerMinorVersion);
596 return LocalGetPrinterDriver( hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded );
597}
BOOL WINAPI LocalGetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded)

◆ LocalGetPrintProcessorDirectory()

BOOL WINAPI LocalGetPrintProcessorDirectory ( LPWSTR  pName,
LPWSTR  pEnvironment,
DWORD  Level,
LPBYTE  pPrintProcessorInfo,
DWORD  cbBuf,
LPDWORD  pcbNeeded 
)

◆ LocalGetSpoolFileInfo()

BOOL WINAPI LocalGetSpoolFileInfo ( HANDLE  hPrinter,
LPWSTR pSpoolDir,
LPHANDLE  phFile,
HANDLE  hSpoolerProcess,
HANDLE  hAppProcess 
)

Definition at line 11 of file spoolfile.c.

17{
18 FIXME("LocalGetSpoolFileInfo(%p, %S, %p, %p, %p)\n", hPrinter, pSpoolDir, phFile, hSpoolerProcess, hAppProcess);
19 return FALSE;
20}

◆ LocalOpenPrinter()

BOOL WINAPI LocalOpenPrinter ( PWSTR  lpPrinterName,
HANDLE phPrinter,
PPRINTER_DEFAULTSW  pDefault 
)

Definition at line 1398 of file printers.c.

1399{
1400 DWORD cchComputerName;
1401 DWORD cchFirstParameter;
1402 DWORD dwErrorCode;
1403 PWSTR p = lpPrinterName;
1404 PWSTR pwszFirstParameter = NULL;
1405 PWSTR pwszSecondParameter;
1406 WCHAR wszComputerName[MAX_COMPUTERNAME_LENGTH + 1];
1407
1408 TRACE("LocalOpenPrinter(%S, %p, %p)\n", lpPrinterName, phPrinter, pDefault);
1409
1410 ASSERT(phPrinter);
1411 *phPrinter = NULL;
1412
1413 if (!lpPrinterName)
1414 {
1415 // The caller wants a Print Server handle and provided a NULL string.
1416 dwErrorCode = _LocalOpenPrintServerHandle(phPrinter);
1417 goto Cleanup;
1418 }
1419
1420 // Skip any server name in the first parameter.
1421 // Does lpPrinterName begin with two backslashes to indicate a server name?
1422 if (lpPrinterName[0] == L'\\' && lpPrinterName[1] == L'\\')
1423 {
1424 // Skip these two backslashes.
1425 lpPrinterName += 2;
1426
1427 // Look for the terminating null character or closing backslash.
1428 p = lpPrinterName;
1429 while (*p != L'\0' && *p != L'\\')
1430 p++;
1431
1432 // Get the local computer name for comparison.
1433 cchComputerName = _countof(wszComputerName);
1434 if (!GetComputerNameW(wszComputerName, &cchComputerName))
1435 {
1436 dwErrorCode = GetLastError();
1437 ERR("GetComputerNameW failed with error %lu!\n", dwErrorCode);
1438 goto Cleanup;
1439 }
1440
1441 // Now compare this string excerpt with the local computer name.
1442 // The input parameter may not be writable, so we can't null-terminate the input string at this point.
1443 // This print provider only supports local printers, so both strings have to match.
1444 if (p - lpPrinterName != cchComputerName || _wcsnicmp(lpPrinterName, wszComputerName, cchComputerName) != 0)
1445 {
1446 dwErrorCode = ERROR_INVALID_NAME;
1447 goto Cleanup;
1448 }
1449
1450 // If lpPrinterName is only "\\COMPUTERNAME" with nothing more, the caller wants a handle to the local Print Server.
1451 if (!*p)
1452 {
1453 // The caller wants a Print Server handle and provided a string like:
1454 // "\\COMPUTERNAME"
1455 dwErrorCode = _LocalOpenPrintServerHandle(phPrinter);
1456 goto Cleanup;
1457 }
1458
1459 // We have checked the server name and don't need it anymore.
1460 lpPrinterName = p + 1;
1461 }
1462
1463 // Look for a comma. If it exists, it indicates the end of the first parameter.
1464 pwszSecondParameter = wcschr(lpPrinterName, L',');
1465 if (pwszSecondParameter)
1466 cchFirstParameter = pwszSecondParameter - p;
1467 else
1468 cchFirstParameter = wcslen(lpPrinterName);
1469
1470 // We must have at least one parameter.
1471 if (!cchFirstParameter && !pwszSecondParameter)
1472 {
1473 dwErrorCode = ERROR_INVALID_NAME;
1474 goto Cleanup;
1475 }
1476
1477 // Do we have a first parameter?
1478 if (cchFirstParameter)
1479 {
1480 // Yes, extract it.
1481 // No null-termination is necessary here, because DllAllocSplMem returns a zero-initialized buffer.
1482 pwszFirstParameter = DllAllocSplMem((cchFirstParameter + 1) * sizeof(WCHAR));
1483 CopyMemory(pwszFirstParameter, lpPrinterName, cchFirstParameter * sizeof(WCHAR));
1484 }
1485
1486 // Do we have a second parameter?
1487 if (pwszSecondParameter)
1488 {
1489 // Yes, skip the comma at the beginning.
1490 ++pwszSecondParameter;
1491
1492 // Skip whitespace as well.
1493 while (*pwszSecondParameter == L' ')
1494 ++pwszSecondParameter;
1495 }
1496
1497 // Now we can finally check the type of handle actually requested.
1498 if (pwszFirstParameter && pwszSecondParameter && wcsncmp(pwszSecondParameter, L"Port", 4) == 0)
1499 {
1500 // The caller wants a port handle and provided a string like:
1501 // "LPT1:, Port"
1502 // "\\COMPUTERNAME\LPT1:, Port"
1503 dwErrorCode = _LocalOpenPortHandle(pwszFirstParameter, phPrinter);
1504 }
1505 else if (!pwszFirstParameter && pwszSecondParameter && wcsncmp(pwszSecondParameter, L"Xcv", 3) == 0)
1506 {
1507 // The caller wants an Xcv handle and provided a string like:
1508 // ", XcvMonitor Local Port"
1509 // "\\COMPUTERNAME\, XcvMonitor Local Port"
1510 // ", XcvPort LPT1:"
1511 // "\\COMPUTERNAME\, XcvPort LPT1:"
1512 FIXME("OpenXcvHandle : %S\n",pwszSecondParameter);
1513 dwErrorCode = _LocalOpenXcvHandle(pwszSecondParameter, phPrinter);
1514 }
1515 else
1516 {
1517 // The caller wants a Printer or Printer Job handle and provided a string like:
1518 // "HP DeskJet"
1519 // "\\COMPUTERNAME\HP DeskJet"
1520 // "HP DeskJet, Job 5"
1521 // "\\COMPUTERNAME\HP DeskJet, Job 5"
1522 dwErrorCode = _LocalOpenPrinterHandle(pwszFirstParameter, pwszSecondParameter, phPrinter, pDefault);
1523 }
1524
1525Cleanup:
1526 if (pwszFirstParameter)
1527 DllFreeSplMem(pwszFirstParameter);
1528
1529 SetLastError(dwErrorCode);
1530 return (dwErrorCode == ERROR_SUCCESS);
1531}
#define ASSERT(a)
Definition: mode.c:44
static DWORD _LocalOpenPortHandle(PWSTR pwszPortName, PHANDLE phPrinter)
Definition: printers.c:1043
static DWORD _LocalOpenPrinterHandle(PWSTR pwszPrinterName, PWSTR pwszJobParameter, PHANDLE phPrinter, PPRINTER_DEFAULTSW pDefault)
Definition: printers.c:1117
static DWORD _LocalOpenPrintServerHandle(PHANDLE phPrinter)
Definition: printers.c:1258
static DWORD _LocalOpenXcvHandle(PWSTR pwszParameter, PHANDLE phPrinter)
Definition: printers.c:1280
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)

◆ LocalPrinterMessageBox()

DWORD WINAPI LocalPrinterMessageBox ( HANDLE  hPrinter,
DWORD  Error,
HWND  hWnd,
LPWSTR  pText,
LPWSTR  pCaption,
DWORD  dwType 
)

Definition at line 1391 of file printers.c.

1392{
1394 return 0;
1395}

◆ LocalReadPrinter()

BOOL WINAPI LocalReadPrinter ( HANDLE  hPrinter,
PVOID  pBuf,
DWORD  cbBuf,
PDWORD  pNoBytesRead 
)

Definition at line 1534 of file printers.c.

1535{
1536 BOOL bReturnValue;
1537 DWORD dwErrorCode;
1538 PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter;
1539 PLOCAL_PORT_HANDLE pPortHandle;
1540 PLOCAL_PRINTER_HANDLE pPrinterHandle;
1541
1542 TRACE("LocalReadPrinter(%p, %p, %lu, %p)\n", hPrinter, pBuf, cbBuf, pNoBytesRead);
1543
1544 // Sanity checks.
1545 if (!pHandle)
1546 {
1547 dwErrorCode = ERROR_INVALID_HANDLE;
1548 goto Cleanup;
1549 }
1550
1551 // Port handles are an entirely different thing.
1552 if (pHandle->HandleType == HandleType_Port)
1553 {
1554 pPortHandle = (PLOCAL_PORT_HANDLE)pHandle->pSpecificHandle;
1555
1556 // Call the monitor's ReadPort function.
1557 if (pPortHandle->pPort->pPrintMonitor->bIsLevel2)
1558 bReturnValue = ((PMONITOR2)pPortHandle->pPort->pPrintMonitor->pMonitor)->pfnReadPort(pPortHandle->hPort, pBuf, cbBuf, pNoBytesRead);
1559 else
1560 bReturnValue = ((LPMONITOREX)pPortHandle->pPort->pPrintMonitor->pMonitor)->Monitor.pfnReadPort(pPortHandle->hPort, pBuf, cbBuf, pNoBytesRead);
1561
1562 if (!bReturnValue)
1563 {
1564 // The ReadPort function failed. Return its last error.
1565 dwErrorCode = GetLastError();
1566 goto Cleanup;
1567 }
1568
1569 // We were successful!
1570 dwErrorCode = ERROR_SUCCESS;
1571 goto Cleanup;
1572 }
1573
1574 // The remaining function deals with Printer handles only.
1575 if (pHandle->HandleType != HandleType_Printer)
1576 {
1577 dwErrorCode = ERROR_INVALID_HANDLE;
1578 goto Cleanup;
1579 }
1580
1581 pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle;
1582
1583 // ReadPrinter needs an opened SPL file to work.
1584 // This only works if a Printer Job Handle was requested in OpenPrinter.
1585 if (pPrinterHandle->hSPLFile == INVALID_HANDLE_VALUE)
1586 {
1587 dwErrorCode = ERROR_INVALID_HANDLE;
1588 goto Cleanup;
1589 }
1590
1591 // Pass the parameters to ReadFile.
1592 if (!ReadFile(pPrinterHandle->hSPLFile, pBuf, cbBuf, pNoBytesRead, NULL))
1593 {
1594 dwErrorCode = GetLastError();
1595 ERR("ReadFile failed with error %lu!\n", dwErrorCode);
1596 goto Cleanup;
1597 }
1598
1599 dwErrorCode = ERROR_SUCCESS;
1600
1601Cleanup:
1602 SetLastError(dwErrorCode);
1603 return (dwErrorCode == ERROR_SUCCESS);
1604}
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742

◆ LocalScheduleJob()

BOOL WINAPI LocalScheduleJob ( HANDLE  hPrinter,
DWORD  dwJobID 
)

Definition at line 1112 of file jobs.c.

1113{
1115 DWORD dwErrorCode;
1117 PLOCAL_JOB pJob;
1118 PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter;
1119 PLOCAL_PRINTER_HANDLE pPrinterHandle;
1120 WCHAR wszFullPath[MAX_PATH];
1121
1122 TRACE("LocalScheduleJob(%p, %lu)\n", hPrinter, dwJobID);
1123
1124 // Check if this is a printer handle.
1125 if (pHandle->HandleType != HandleType_Printer)
1126 {
1127 dwErrorCode = ERROR_INVALID_HANDLE;
1128 goto Cleanup;
1129 }
1130
1131 pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle;
1132
1133 // Check if the Job ID is valid.
1134 pJob = LookupElementSkiplist(&GlobalJobList, &dwJobID, NULL);
1135 if (!pJob || pJob->pPrinter != pPrinterHandle->pPrinter)
1136 {
1137 dwErrorCode = ERROR_INVALID_PARAMETER;
1138 goto Cleanup;
1139 }
1140
1141 // Check if this Job was started with AddJob.
1142 if (!pJob->bAddedJob)
1143 {
1144 dwErrorCode = ERROR_SPL_NO_ADDJOB;
1145 goto Cleanup;
1146 }
1147
1148 // Construct the full path to the spool file.
1149 GetJobFilePath(L"SPL", dwJobID, wszFullPath);
1150
1151 // Check if it exists.
1152 dwAttributes = GetFileAttributesW(wszFullPath);
1154 {
1155 dwErrorCode = ERROR_SPOOL_FILE_NOT_FOUND;
1156 goto Cleanup;
1157 }
1158
1159 // Spooling is finished at this point.
1160 pJob->dwStatus &= ~JOB_STATUS_SPOOLING;
1161
1162 // Write the job data into the shadow file.
1163 wcscpy(wcsrchr(wszFullPath, L'.'), L".SHD");
1164 WriteJobShadowFile(wszFullPath, pJob);
1165
1166 // Create the thread for performing the printing process.
1168 if (!hThread)
1169 {
1170 dwErrorCode = GetLastError();
1171 ERR("CreateThread failed with error %lu!\n", dwErrorCode);
1172 goto Cleanup;
1173 }
1174
1175 // We don't need the thread handle. Keeping it open blocks the thread from terminating.
1177
1178 // ScheduleJob has done its job. The rest happens inside the thread.
1179 dwErrorCode = ERROR_SUCCESS;
1180
1181Cleanup:
1182 SetLastError(dwErrorCode);
1183 return (dwErrorCode == ERROR_SUCCESS);
1184}
#define CloseHandle
Definition: compat.h:739
#define wcsrchr
Definition: compat.h:16
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
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)
Definition: thread.c:137
HANDLE hThread
Definition: wizard.c:28
BOOL WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob)
Definition: jobs.c:1300
BOOL bAddedJob
Definition: precomp.h:142
DWORD dwAttributes
Definition: vdmdbg.h:34
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
DWORD WINAPI PrintingThreadProc(PLOCAL_JOB pJob)
DWORD(WINAPI * LPTHREAD_START_ROUTINE)(LPVOID)
Definition: winbase.h:729
#define ERROR_SPOOL_FILE_NOT_FOUND
Definition: winerror.h:1207
#define ERROR_SPL_NO_ADDJOB
Definition: winerror.h:1209

◆ LocalSetForm()

BOOL WINAPI LocalSetForm ( HANDLE  hPrinter,
PWSTR  pFormName,
DWORD  Level,
PBYTE  pForm 
)

Definition at line 682 of file forms.c.

683{
684 DWORD dwErrorCode, cbNeeded;
685 PFORM_INFO_LIST pfil;
687 PLOCAL_HANDLE pHandle;
688 PFORM_INFO_1W pfi1w = (PFORM_INFO_1W)pForm;
689 PFORM_INFO_2W pfi2w = (PFORM_INFO_2W)pForm;
690
691 FIXME("SetFormW(%p, %S, %lu, %p)\n", hPrinter, pFormName, Level, pForm);
692
693 // Check if this is a printer handle.
694 pHandle = (PLOCAL_HANDLE)hPrinter;
695 if (pHandle->HandleType != HandleType_Printer)
696 {
697 dwErrorCode = ERROR_INVALID_HANDLE;
698 goto Cleanup;
699 }
700
701 // Only support 1 & 2
702 if (Level < 1 || Level > 2)
703 {
704 // The caller supplied an invalid level.
705 dwErrorCode = ERROR_INVALID_LEVEL;
706 goto Cleanup;
707 }
708
709 pfil = FindForm( pFormName, NULL );
710 if ( !pfil )
711 {
712 dwErrorCode = ERROR_INVALID_PARAMETER;
713 goto Cleanup;
714 }
715
716 dwErrorCode = RegQueryValueExW( hFormsKey, pFormName, NULL, NULL, (PBYTE)&rfi, &cbNeeded) ;
717 if ( dwErrorCode != ERROR_SUCCESS )
718 {
719 goto Cleanup;
720 }
721
722 pfil->Flags = pfi1w->Flags;
723 pfil->Size = pfi1w->Size;
724 pfil->ImageableArea = pfi1w->ImageableArea;
725
726 if ( Level > 1 )
727 {
728 pfil->pKeyword = pfi2w->pKeyword;
729 pfil->pMuiDll = pfi2w->pMuiDll;
730 pfil->pDisplayName = pfi2w->pDisplayName;
731 pfil->StringType = pfi2w->StringType;
732 pfil->dwResourceId = pfi2w->dwResourceId;
733 }
734
735 rfi.Size = pfil->Size;
736 rfi.ImageableArea = pfil->ImageableArea;
737 rfi.Flags = pfil->Flags;
738
739 dwErrorCode = RegSetValueExW( hFormsKey, pfil->pName, 0, REG_BINARY, (PBYTE)&rfi, sizeof( rfi ) );
740
741 BroadcastChange(pHandle);
742
743Cleanup:
744 SetLastError(dwErrorCode);
745 return (dwErrorCode == ERROR_SUCCESS);
746}

◆ LocalSetJob()

BOOL WINAPI LocalSetJob ( HANDLE  hPrinter,
DWORD  JobId,
DWORD  Level,
PBYTE  pJobInfo,
DWORD  Command 
)

Definition at line 949 of file jobs.c.

950{
951 DWORD dwErrorCode = ERROR_SUCCESS;
952 PLOCAL_HANDLE pHandle;
953 PLOCAL_JOB pJob;
954 PLOCAL_PRINTER_HANDLE pPrinterHandle;
955 WCHAR wszFullPath[MAX_PATH];
956
957 TRACE("LocalSetJob(%p, %lu, %lu, %p, %lu)\n", hPrinter, JobId, Level, pJobInfo, Command);
958
959 // Check if this is a printer handle.
960 pHandle = (PLOCAL_HANDLE)hPrinter;
961 if (!pHandle || pHandle->HandleType != HandleType_Printer)
962 {
963 dwErrorCode = ERROR_INVALID_HANDLE;
964 goto Cleanup;
965 }
966
967 pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle;
968
969 // Get the desired job.
970 pJob = LookupElementSkiplist(&GlobalJobList, &JobId, NULL);
971 if (!pJob || pJob->pPrinter != pPrinterHandle->pPrinter)
972 {
973 dwErrorCode = ERROR_INVALID_PARAMETER;
974 goto Cleanup;
975 }
976
977 // Set new job information if a valid level was given.
978 if (Level == 1)
979 dwErrorCode = _LocalSetJobLevel1(pPrinterHandle, pJob, (PJOB_INFO_1W)pJobInfo);
980 else if (Level == 2)
981 dwErrorCode = _LocalSetJobLevel2(pPrinterHandle, pJob, (PJOB_INFO_2W)pJobInfo);
982
983 if (dwErrorCode != ERROR_SUCCESS)
984 goto Cleanup;
985
986 // If we do spooled printing, the job information is written down into a shadow file.
987 if (!(pPrinterHandle->pPrinter->dwAttributes & PRINTER_ATTRIBUTE_DIRECT))
988 {
989 // Write the job data into the shadow file.
990 GetJobFilePath(L"SHD", JobId, wszFullPath);
991 WriteJobShadowFile(wszFullPath, pJob);
992 }
993
994 // Perform an additional command if desired.
995 if (Command)
996 {
998 {
999 // This indicates the end of the Print Job.
1000
1001 // Cancel the Job at the Print Processor.
1002 if (pJob->hPrintProcessor)
1004
1005 FreeJob(pJob);
1006
1007 // TODO: All open handles associated with the job need to be invalidated.
1008 // This certainly needs handle tracking...
1009 }
1010 else
1011 {
1012 ERR("Unimplemented SetJob Command: %lu!\n", Command);
1013 }
1014 }
1015
1016Cleanup:
1017 SetLastError(dwErrorCode);
1018 return (dwErrorCode == ERROR_SUCCESS);
1019}
static DWORD _LocalSetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_INFO_2W pJobInfo)
Definition: jobs.c:818
static DWORD _LocalSetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_INFO_1W pJobInfo)
Definition: jobs.c:721
void FreeJob(PLOCAL_JOB pJob)
Definition: jobs.c:1452
Definition: shell.h:41
HANDLE hPrintProcessor
Definition: precomp.h:143
#define JOB_CONTROL_CANCEL
Definition: winspool.h:332
#define PRINTER_ATTRIBUTE_DIRECT
Definition: winspool.h:209
#define JOB_CONTROL_SENT_TO_PRINTER
Definition: winspool.h:335

◆ LocalSetPort()

BOOL WINAPI LocalSetPort ( PWSTR  pName,
PWSTR  pPortName,
DWORD  dwLevel,
PBYTE  pPortInfo 
)

Definition at line 460 of file ports.c.

461{
462 LONG lres;
463 DWORD res = 0;
464 PPORT_INFO_3W ppi3w = (PPORT_INFO_3W)pPortInfo;
465 PLOCAL_PORT pPrintPort;
466
467 TRACE("LocalSetPort(%S, %S, %lu, %p)\n", pName, pPortName, dwLevel, pPortInfo);
468
470 if (lres)
471 {
472 FIXME("server %s not supported\n", debugstr_w(pName));
474 return FALSE;
475 }
476
477 if ((dwLevel < 1) || (dwLevel > 2))
478 {
480 return FALSE;
481 }
482
483 if ( !ppi3w )
484 {
486 return FALSE;
487 }
488
489 pPrintPort = FindPort(pPortName);
490 if ( !pPrintPort )
491 {
493 return FALSE;
494 }
495
496 FIXME("Add Status Support to Local Ports!\n");
497
498 return res;
499}
#define ERROR_UNKNOWN_PORT
Definition: winerror.h:1103
struct _PORT_INFO_3W * PPORT_INFO_3W

◆ LocalSetPrinterData()

DWORD WINAPI LocalSetPrinterData ( HANDLE  hPrinter,
PWSTR  pValueName,
DWORD  Type,
PBYTE  pData,
DWORD  cbData 
)

Definition at line 361 of file printerdata.c.

362{
363 TRACE("LocalSetPrinterData(%p, %S, %lu, %p, %lu)\n", hPrinter, pValueName, Type, pData, cbData);
364
365 // The ReactOS Printing Stack forwards all SetPrinterData calls to SetPrinterDataEx as soon as possible.
366 // This function may only be called if localspl.dll is used together with Windows Printing Stack components.
367 WARN("This function should never be called!\n");
368 return LocalSetPrinterDataEx(hPrinter, L"PrinterDriverData", pValueName, Type, pData, cbData);
369}
Type
Definition: Type.h:7
DWORD WINAPI LocalSetPrinterDataEx(HANDLE hPrinter, PCWSTR pKeyName, PCWSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData)
Definition: printerdata.c:450

◆ LocalSetPrinterDataEx()

DWORD WINAPI LocalSetPrinterDataEx ( HANDLE  hPrinter,
LPCWSTR  pKeyName,
LPCWSTR  pValueName,
DWORD  Type,
LPBYTE  pData,
DWORD  cbData 
)

◆ LocalStartDocPrinter()

DWORD WINAPI LocalStartDocPrinter ( HANDLE  hPrinter,
DWORD  Level,
LPBYTE  pDocInfo 
)

◆ LocalStartPagePrinter()

BOOL WINAPI LocalStartPagePrinter ( HANDLE  hPrinter)

Definition at line 1724 of file printers.c.

1725{
1726 DWORD dwErrorCode;
1727 PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter;
1728 PLOCAL_PRINTER_HANDLE pPrinterHandle;
1729
1730 TRACE("LocalStartPagePrinter(%p)\n", hPrinter);
1731
1732 // Sanity checks.
1733 if (!pHandle || pHandle->HandleType != HandleType_Printer)
1734 {
1735 dwErrorCode = ERROR_INVALID_HANDLE;
1736 goto Cleanup;
1737 }
1738
1739 pPrinterHandle = (PLOCAL_PRINTER_HANDLE)pHandle->pSpecificHandle;
1740
1741 // We require StartDocPrinter or AddJob to be called first.
1742 if (!pPrinterHandle->bStartedDoc)
1743 {
1744 dwErrorCode = ERROR_SPL_NO_STARTDOC;
1745 goto Cleanup;
1746 }
1747
1748 // Increase the page count.
1749 ++pPrinterHandle->pJob->dwTotalPages;
1750 dwErrorCode = ERROR_SUCCESS;
1751
1752Cleanup:
1753 SetLastError(dwErrorCode);
1754 return (dwErrorCode == ERROR_SUCCESS);
1755}
DWORD dwTotalPages
Definition: precomp.h:155

◆ LocalWritePrinter()

BOOL WINAPI LocalWritePrinter ( HANDLE  hPrinter,
LPVOID  pBuf,
DWORD  cbBuf,
LPDWORD  pcWritten 
)

◆ LocalXcvData()

BOOL WINAPI LocalXcvData ( HANDLE  hXcv,
const WCHAR pszDataName,
BYTE pInputData,
DWORD  cbInputData,
BYTE pOutputData,
DWORD  cbOutputData,
DWORD pcbOutputNeeded,
DWORD pdwStatus 
)

Definition at line 140 of file xcv.c.

141{
142 DWORD res;
143 PLOCAL_PRINT_MONITOR pPrintMonitor;
146
147 FIXME("LocalXcvData(%p, %S, %p, %lu, %p, %lu, %p)\n", hXcv, pszDataName, pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded);
148
149 // Sanity checks
150 if (!pszDataName)
151 {
153 goto Cleanup;
154 }
155
156 // Call the appropriate handler for the requested data name.
157 if (wcscmp(pszDataName, L"AddPort") == 0)
158 return _HandleAddPort(hXcv, pInputData, pcbOutputNeeded, pdwStatus);
159
160 if (wcscmp(pszDataName, L"DeletePort") == 0)
161 return _HandleDeletePort(hXcv, pInputData, pcbOutputNeeded, pdwStatus);
162
163 //
164 // After the two Intercept Handlers, defer call back to Monitor.
165 //
166
167 // Check if this is a printer handle.
168 if (pHandle->HandleType != HandleType_Xcv)
169 {
170 ERR("LocalXcvData : Invalid XCV Handle\n");
172 goto Cleanup;
173 }
174
175 pXcv = (PLOCAL_XCV_HANDLE)pHandle->pSpecificHandle;
176
177 pPrintMonitor = pXcv->pPrintMonitor;
178 if (!pPrintMonitor )
179 {
181 goto Cleanup;
182 }
183
184 pPrintMonitor->refcount++;
185 if ( pPrintMonitor->bIsLevel2 && ((PMONITOR2)pPrintMonitor->pMonitor)->pfnXcvDataPort )
186 {
187 res = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnXcvDataPort(pXcv->hXcv, pszDataName, pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded);
188 }
189 else if ( !pPrintMonitor->bIsLevel2 && ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnXcvDataPort )
190 {
191 res = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnXcvDataPort(pXcv->hXcv, pszDataName, pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded);
192 }
193 pPrintMonitor->refcount--;
194
195Cleanup:
197 if (pdwStatus) *pdwStatus = res;
198 return res;
199}
static HANDLE hXcv
Definition: localmon.c:73
static DWORD _HandleDeletePort(PLOCALMON_XCV pXcv, PBYTE pInputData, PDWORD pcbOutputNeeded)
Definition: xcv.c:167
static DWORD _HandleAddPort(PLOCALMON_XCV pXcv, PBYTE pInputData, PDWORD pcbOutputNeeded)
Definition: xcv.c:11
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
PLOCAL_PRINT_MONITOR pPrintMonitor
Definition: precomp.h:192
struct _LOCAL_XCV_HANDLE * PLOCAL_XCV_HANDLE
Definition: precomp.h:64

◆ PrintingThreadProc()

DWORD WINAPI PrintingThreadProc ( PLOCAL_JOB  pJob)

Definition at line 11 of file printingthread.c.

12{
13 const DWORD cchMaxJobIdDigits = 5; // Job ID is limited to 5 decimal digits, see IS_VALID_JOB_ID
14 const WCHAR wszJobAppendix[] = L", Job ";
15 const DWORD cchJobAppendix = _countof(wszJobAppendix) - 1;
16 const WCHAR wszPortAppendix[] = L", Port";
17
18 DWORD cchPortName;
19 DWORD cchPrinterName;
20 DWORD dwErrorCode;
21 HANDLE hPrintProcessor = NULL;
22 PLOCAL_PRINT_PROCESSOR pPrintProcessor = pJob->pPrintProcessor;
24 PWSTR pwszPrinterAndJob = NULL;
25 PWSTR pwszPrinterPort = NULL;
26 PWSTR pwszSPLFile = NULL;
27
28 TRACE("PrintingThreadProc(%p)\n", pJob);
29
30 // Prepare the pPrinterName parameter.
31 // This is the string for LocalOpenPrinter to open a port (e.g. "LPT1:, Port").
32 cchPortName = wcslen(pJob->pPrinter->pPort->pwszName);
33 pwszPrinterPort = DllAllocSplMem(cchPortName * sizeof(WCHAR) + sizeof(wszPortAppendix));
34 if (!pwszPrinterPort)
35 {
36 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
37 ERR("DllAllocSplMem failed!\n");
38 goto Cleanup;
39 }
40
41 CopyMemory(pwszPrinterPort, pJob->pPrinter->pPort->pwszName, cchPortName * sizeof(WCHAR));
42 CopyMemory(&pwszPrinterPort[cchPortName], wszPortAppendix, sizeof(wszPortAppendix));
43
44 // Prepare the pPrintProcessorOpenData parameter.
45 OpenData.JobId = pJob->dwJobID;
46 OpenData.pDatatype = pJob->pwszDatatype;
47 OpenData.pDevMode = pJob->pDevMode;
48 OpenData.pDocumentName = pJob->pwszDocumentName;
49 OpenData.pOutputFile = NULL;
51 OpenData.pPrinterName = pJob->pPrinter->pwszPrinterName;
52
53 // Associate our job to the port. The next port handle created through LocalOpenPrinter will pick this up.
54 // LocalStartDocPrinter needs this information to call StartDocPort of the Print Monitor, but as the parameters
55 // for LocalOpenPrinter and LocalStartDocPrinter are fixed, we can only pass over the information this way.
56 pJob->pPrinter->pPort->pNextJobToProcess = pJob;
57
58 // Open a handle to the Print Processor.
59 hPrintProcessor = pPrintProcessor->pfnOpenPrintProcessor(pwszPrinterPort, &OpenData);
60 if (!hPrintProcessor)
61 {
62 dwErrorCode = GetLastError();
63 ERR("OpenPrintProcessor failed with error %lu!\n", dwErrorCode);
64 goto Cleanup;
65 }
66
67 // Let other functions use the Print Processor as well while it's opened.
68 pJob->hPrintProcessor = hPrintProcessor;
69
70 // Prepare the pDocumentName parameter.
71 cchPrinterName = wcslen(OpenData.pPrinterName);
72 pwszPrinterAndJob = DllAllocSplMem((cchPrinterName + cchJobAppendix + cchMaxJobIdDigits + 1) * sizeof(WCHAR));
73 if (!pwszPrinterAndJob)
74 {
75 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
76 ERR("DllAllocSplMem failed!\n");
77 goto Cleanup;
78 }
79
80 CopyMemory(pwszPrinterAndJob, OpenData.pPrinterName, cchPrinterName * sizeof(WCHAR));
81 CopyMemory(&pwszPrinterAndJob[cchPrinterName], wszJobAppendix, cchJobAppendix * sizeof(WCHAR));
82 _ultow(OpenData.JobId, &pwszPrinterAndJob[cchPrinterName + cchJobAppendix], 10);
83
84 // Printing starts here.
86
87 // Print the document.
88 // Note that pJob is freed after this function, so we may not access it anymore.
89 if (!pPrintProcessor->pfnPrintDocumentOnPrintProcessor(hPrintProcessor, pwszPrinterAndJob))
90 {
91 dwErrorCode = GetLastError();
92 ERR("PrintDocumentOnPrintProcessor failed with error %lu!\n", dwErrorCode);
93 goto Cleanup;
94 }
95
96 // Close the Print Processor.
97 pPrintProcessor->pfnClosePrintProcessor(hPrintProcessor);
98 hPrintProcessor = NULL;
99
100 // Delete the spool file.
101 pwszSPLFile = DllAllocSplMem(GetJobFilePath(L"SPL", 0, NULL));
102 if (!pwszSPLFile)
103 {
104 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
105 ERR("DllAllocSplMem failed!\n");
106 goto Cleanup;
107 }
108
109 GetJobFilePath(L"SPL", OpenData.JobId, pwszSPLFile);
110 DeleteFileW(pwszSPLFile);
111
112 // We were successful!
113 dwErrorCode = ERROR_SUCCESS;
114
115Cleanup:
116 if (hPrintProcessor)
117 pPrintProcessor->pfnClosePrintProcessor(hPrintProcessor);
118
119 if (pwszPrinterPort)
120 DllFreeSplMem(pwszPrinterPort);
121
122 if (pwszPrinterAndJob)
123 DllFreeSplMem(pwszPrinterAndJob);
124
125 if (pwszSPLFile)
126 DllFreeSplMem(pwszSPLFile);
127
128 return dwErrorCode;
129}
_CRTIMP wchar_t *__cdecl _ultow(_In_ unsigned long _Value, _Pre_notnull_ _Post_z_ wchar_t *_Dest, _In_ int _Radix)
PLOCAL_JOB pNextJobToProcess
Definition: precomp.h:92
#define JOB_STATUS_PRINTING
Definition: winspool.h:342

Referenced by LocalScheduleJob().

◆ ReadJobShadowFile()

PLOCAL_JOB ReadJobShadowFile ( PCWSTR  pwszFilePath)

Definition at line 1187 of file jobs.c.

1188{
1189 DWORD cbFileSize;
1190 DWORD cbRead;
1192 PLOCAL_JOB pJob;
1193 PLOCAL_JOB pReturnValue = NULL;
1194 PLOCAL_PRINTER pPrinter;
1195 PLOCAL_PRINT_PROCESSOR pPrintProcessor;
1196 PSHD_HEADER pShadowFile = NULL;
1197 PWSTR pwszPrinterName;
1198 PWSTR pwszPrintProcessor;
1199
1200 TRACE("ReadJobShadowFile(%S)\n", pwszFilePath);
1201
1202 // Try to open the file.
1205 {
1206 ERR("CreateFileW failed with error %lu for file \"%S\"!\n", GetLastError(), pwszFilePath);
1207 goto Cleanup;
1208 }
1209
1210 // Get its file size (small enough for a single DWORD) and allocate memory for all of it.
1211 cbFileSize = GetFileSize(hFile, NULL);
1212 pShadowFile = DllAllocSplMem(cbFileSize);
1213 if (!pShadowFile)
1214 {
1215 ERR("DllAllocSplMem failed for file \"%S\"!\n", pwszFilePath);
1216 goto Cleanup;
1217 }
1218
1219 // Read the entire file.
1220 if (!ReadFile(hFile, pShadowFile, cbFileSize, &cbRead, NULL))
1221 {
1222 ERR("ReadFile failed with error %lu for file \"%S\"!\n", GetLastError(), pwszFilePath);
1223 goto Cleanup;
1224 }
1225
1226 // Check signature and header size.
1227 if (pShadowFile->dwSignature != SHD_WIN2003_SIGNATURE || pShadowFile->cbHeader != sizeof(SHD_HEADER))
1228 {
1229 ERR("Signature or Header Size mismatch for file \"%S\"!\n", pwszFilePath);
1230 goto Cleanup;
1231 }
1232
1233 // Retrieve the associated printer from the list.
1234 pwszPrinterName = (PWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offPrinterName);
1235 pPrinter = LookupElementSkiplist(&PrinterList, &pwszPrinterName, NULL);
1236 if (!pPrinter)
1237 {
1238 ERR("Shadow file \"%S\" references a non-existing printer \"%S\"!\n", pwszFilePath, pwszPrinterName);
1239 goto Cleanup;
1240 }
1241
1242 // Retrieve the associated Print Processor from the list.
1243 pwszPrintProcessor = (PWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offPrintProcessor);
1244 pPrintProcessor = FindPrintProcessor(pwszPrintProcessor);
1245 if (!pPrintProcessor)
1246 {
1247 ERR("Shadow file \"%S\" references a non-existing Print Processor \"%S\"!\n", pwszFilePath, pwszPrintProcessor);
1248 goto Cleanup;
1249 }
1250
1251 // Create a new job structure and copy over the relevant fields.
1252 pJob = DllAllocSplMem(sizeof(LOCAL_JOB));
1253 if (!pJob)
1254 {
1255 ERR("DllAllocSplMem failed for file \"%S\"!\n", pwszFilePath);
1256 goto Cleanup;
1257 }
1258
1259 pJob->dwJobID = pShadowFile->dwJobID;
1260 pJob->dwPriority = pShadowFile->dwPriority;
1261 pJob->dwStartTime = pShadowFile->dwStartTime;
1262 pJob->dwTotalPages = pShadowFile->dwTotalPages;
1263 pJob->dwUntilTime = pShadowFile->dwUntilTime;
1264 pJob->pPrinter = pPrinter;
1265 pJob->pPrintProcessor = pPrintProcessor;
1266 pJob->pDevMode = DuplicateDevMode((PDEVMODEW)((ULONG_PTR)pShadowFile + pShadowFile->offDevMode));
1267 pJob->pwszDatatype = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offDatatype));
1268 pJob->pwszMachineName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offMachineName));
1269 CopyMemory(&pJob->stSubmitted, &pShadowFile->stSubmitted, sizeof(SYSTEMTIME));
1270
1271 // Copy the optional values.
1272 if (pShadowFile->offDocumentName)
1273 pJob->pwszDocumentName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offDocumentName));
1274
1275 if (pShadowFile->offNotifyName)
1276 pJob->pwszNotifyName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offNotifyName));
1277
1278 if (pShadowFile->offPrintProcessorParameters)
1280
1281 if (pShadowFile->offUserName)
1282 pJob->pwszUserName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offUserName));
1283
1284 // Jobs read from shadow files were always added using AddJob.
1285 pJob->bAddedJob = TRUE;
1286
1287 pReturnValue = pJob;
1288
1289Cleanup:
1290 if (pShadowFile)
1291 DllFreeSplMem(pShadowFile);
1292
1295
1296 return pReturnValue;
1297}
#define OPEN_EXISTING
Definition: compat.h:775
#define GENERIC_READ
Definition: compat.h:135
#define CreateFileW
Definition: compat.h:741
#define FILE_SHARE_READ
Definition: compat.h:136
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
_In_ HANDLE hFile
Definition: mswsock.h:90
DWORD dwStartTime
Definition: precomp.h:157
DWORD dwUntilTime
Definition: precomp.h:158
DWORD dwTotalPages
Definition: precomp.h:238
DWORD dwJobID
Definition: precomp.h:222
DWORD offUserName
Definition: precomp.h:224
DWORD offMachineName
Definition: precomp.h:244
DWORD offDocumentName
Definition: precomp.h:226
DWORD offDatatype
Definition: precomp.h:232
DWORD dwPriority
Definition: precomp.h:223
DWORD offPrinterName
Definition: precomp.h:228
DWORD offPrintProcessor
Definition: precomp.h:231
DWORD cbHeader
Definition: precomp.h:219
DWORD offPrintProcessorParameters
Definition: precomp.h:233
DWORD dwSignature
Definition: precomp.h:218
DWORD offDevMode
Definition: precomp.h:230
DWORD dwUntilTime
Definition: precomp.h:236
DWORD dwStartTime
Definition: precomp.h:235
SYSTEMTIME stSubmitted
Definition: precomp.h:234
DWORD offNotifyName
Definition: precomp.h:225
const uint16_t * PCWSTR
Definition: typedefs.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define SHD_WIN2003_SIGNATURE
Definition: precomp.h:42

Referenced by InitializeGlobalJobList().

◆ validate_envW()

PPRINTENV_T validate_envW ( LPCWSTR  env)

Definition at line 687 of file printerdrivers.c.

688{
690 unsigned int i;
691
692 TRACE("(%s)\n", debugstr_w(env));
693 if (env && env[0])
694 {
695 for (i = 0; i < ARRAYSIZE(all_printenv); i++)
696 {
697 if (lstrcmpiW(env, all_printenv[i]->envname) == 0)
698 {
700 break;
701 }
702 }
703 if (result == NULL)
704 {
705 FIXME("unsupported Environment: %s\n", debugstr_w(env));
707 }
708 /* on win9x, only "Windows 4.0" is allowed, but we ignore this */
709 }
710 else
711 {
712 result = (GetVersion() & 0x80000000) ? &env_win40 : &env_x86;
713 }
714
715 TRACE("=> using %p: %s\n", result, debugstr_w(result ? result->envname : NULL));
716 return result;
717}
GLuint64EXT * result
Definition: glext.h:11304
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
static PRINTENV_T env_win40
static PPRINTENV_T all_printenv[]
static PRINTENV_T env_x86
DWORD WINAPI GetVersion()
Definition: redirtest.c:5
#define ERROR_INVALID_ENVIRONMENT
Definition: winerror.h:1112

Referenced by LocalAddMonitor(), LocalGetPrinterDriverDirectory(), myAddPrinterDriverEx(), and open_driver_reg().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( localspl  )

◆ WriteJobShadowFile()

BOOL WriteJobShadowFile ( PWSTR  pwszFilePath,
const PLOCAL_JOB  pJob 
)

Definition at line 1300 of file jobs.c.

1301{
1302 BOOL bReturnValue = FALSE;
1303 DWORD cbDatatype = (wcslen(pJob->pwszDatatype) + 1) * sizeof(WCHAR);
1304 DWORD cbDevMode = pJob->pDevMode->dmSize + pJob->pDevMode->dmDriverExtra;
1305 DWORD cbDocumentName = 0;
1306 DWORD cbFileSize;
1307 DWORD cbMachineName = (wcslen(pJob->pwszMachineName) + 1) * sizeof(WCHAR);
1308 DWORD cbNotifyName = 0;
1309 DWORD cbPrinterDriver = (wcslen(pJob->pPrinter->pwszPrinterDriver) + 1) * sizeof(WCHAR);
1310 DWORD cbPrinterName = (wcslen(pJob->pPrinter->pwszPrinterName) + 1) * sizeof(WCHAR);
1311 DWORD cbPrintProcessor = (wcslen(pJob->pPrintProcessor->pwszName) + 1) * sizeof(WCHAR);
1312 DWORD cbPrintProcessorParameters = 0;
1313 DWORD cbUserName = 0;
1314 DWORD cbWritten;
1315 DWORD dwCurrentOffset;
1316 HANDLE hSHDFile = INVALID_HANDLE_VALUE;
1317 HANDLE hSPLFile = INVALID_HANDLE_VALUE;
1318 PSHD_HEADER pShadowFile = NULL;
1319
1320 TRACE("WriteJobShadowFile(%S, %p)\n", pwszFilePath, pJob);
1321
1322 // Try to open the SHD file.
1323 hSHDFile = CreateFileW(pwszFilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
1324 if (hSHDFile == INVALID_HANDLE_VALUE)
1325 {
1326 ERR("CreateFileW failed with error %lu for file \"%S\"!\n", GetLastError(), pwszFilePath);
1327 goto Cleanup;
1328 }
1329
1330 // Calculate the lengths of the optional values and the total size of the shadow file.
1331 if (pJob->pwszDocumentName)
1332 cbDocumentName = (wcslen(pJob->pwszDocumentName) + 1) * sizeof(WCHAR);
1333
1334 if (pJob->pwszNotifyName)
1335 cbNotifyName = (wcslen(pJob->pwszNotifyName) + 1) * sizeof(WCHAR);
1336
1338 cbPrintProcessorParameters = (wcslen(pJob->pwszPrintProcessorParameters) + 1) * sizeof(WCHAR);
1339
1340 if (pJob->pwszUserName)
1341 cbUserName = (wcslen(pJob->pwszUserName) + 1) * sizeof(WCHAR);
1342
1343 cbFileSize = sizeof(SHD_HEADER) + cbDatatype + cbDocumentName + cbDevMode + cbMachineName + cbNotifyName + cbPrinterDriver + cbPrinterName + cbPrintProcessor + cbPrintProcessorParameters + cbUserName;
1344
1345 // Allocate memory for it.
1346 pShadowFile = DllAllocSplMem(cbFileSize);
1347 if (!pShadowFile)
1348 {
1349 ERR("DllAllocSplMem failed for file \"%S\"!\n", pwszFilePath);
1350 goto Cleanup;
1351 }
1352
1353 // Fill out the shadow file header information.
1354 pShadowFile->dwSignature = SHD_WIN2003_SIGNATURE;
1355 pShadowFile->cbHeader = sizeof(SHD_HEADER);
1356
1357 // Copy the values.
1358 pShadowFile->dwJobID = pJob->dwJobID;
1359 pShadowFile->dwPriority = pJob->dwPriority;
1360 pShadowFile->dwStartTime = pJob->dwStartTime;
1361 pShadowFile->dwTotalPages = pJob->dwTotalPages;
1362 pShadowFile->dwUntilTime = pJob->dwUntilTime;
1363 CopyMemory(&pShadowFile->stSubmitted, &pJob->stSubmitted, sizeof(SYSTEMTIME));
1364
1365 // Determine the file size of the .SPL file
1366 wcscpy(wcsrchr(pwszFilePath, L'.'), L".SPL");
1368 if (hSPLFile != INVALID_HANDLE_VALUE)
1369 pShadowFile->dwSPLSize = GetFileSize(hSPLFile, NULL);
1370
1371 // Add the extra values that are stored as offsets in the shadow file.
1372 // The first value begins right after the shadow file header.
1373 dwCurrentOffset = sizeof(SHD_HEADER);
1374
1375 CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszDatatype, cbDatatype);
1376 pShadowFile->offDatatype = dwCurrentOffset;
1377 dwCurrentOffset += cbDatatype;
1378
1379 CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pDevMode, cbDevMode);
1380 pShadowFile->offDevMode = dwCurrentOffset;
1381 dwCurrentOffset += cbDevMode;
1382
1383 // offDriverName is only written, but automatically determined through offPrinterName when reading.
1384 CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pPrinter->pwszPrinterDriver, cbPrinterDriver);
1385 pShadowFile->offDriverName = dwCurrentOffset;
1386 dwCurrentOffset += cbPrinterDriver;
1387
1388 CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszMachineName, cbMachineName);
1389 pShadowFile->offMachineName = dwCurrentOffset;
1390 dwCurrentOffset += cbMachineName;
1391
1392 CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pPrinter->pwszPrinterName, cbPrinterName);
1393 pShadowFile->offPrinterName = dwCurrentOffset;
1394 dwCurrentOffset += cbPrinterName;
1395
1396 CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pPrintProcessor->pwszName, cbPrintProcessor);
1397 pShadowFile->offPrintProcessor = dwCurrentOffset;
1398 dwCurrentOffset += cbPrintProcessor;
1399
1400 // Copy the optional values.
1401 if (cbDocumentName)
1402 {
1403 CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszDocumentName, cbDocumentName);
1404 pShadowFile->offDocumentName = dwCurrentOffset;
1405 dwCurrentOffset += cbDocumentName;
1406 }
1407
1408 if (cbNotifyName)
1409 {
1410 CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszNotifyName, cbNotifyName);
1411 pShadowFile->offNotifyName = dwCurrentOffset;
1412 dwCurrentOffset += cbNotifyName;
1413 }
1414
1415 if (cbPrintProcessorParameters)
1416 {
1417 CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszPrintProcessorParameters, cbPrintProcessorParameters);
1418 pShadowFile->offPrintProcessorParameters = dwCurrentOffset;
1419 dwCurrentOffset += cbPrintProcessorParameters;
1420 }
1421
1422 if (cbUserName)
1423 {
1424 CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszUserName, cbUserName);
1425 pShadowFile->offUserName = dwCurrentOffset;
1426 dwCurrentOffset += cbUserName;
1427 }
1428
1429 // Write the file.
1430 if (!WriteFile(hSHDFile, pShadowFile, cbFileSize, &cbWritten, NULL))
1431 {
1432 ERR("WriteFile failed with error %lu for file \"%S\"!\n", GetLastError(), pwszFilePath);
1433 goto Cleanup;
1434 }
1435
1436 bReturnValue = TRUE;
1437
1438Cleanup:
1439 if (pShadowFile)
1440 DllFreeSplMem(pShadowFile);
1441
1442 if (hSHDFile != INVALID_HANDLE_VALUE)
1443 CloseHandle(hSHDFile);
1444
1445 if (hSPLFile != INVALID_HANDLE_VALUE)
1446 CloseHandle(hSPLFile);
1447
1448 return bReturnValue;
1449}
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
#define CREATE_ALWAYS
Definition: disk.h:72
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define GENERIC_WRITE
Definition: nt_native.h:90
DWORD offDriverName
Definition: precomp.h:229
DWORD dwSPLSize
Definition: precomp.h:245
struct _SHD_HEADER SHD_HEADER
Definition: precomp.h:65

Referenced by LocalScheduleJob(), and LocalSetJob().

Variable Documentation

◆ cbCurrentEnvironment

const DWORD cbCurrentEnvironment
extern

◆ cchJobDirectory

DWORD cchJobDirectory
extern

Definition at line 14 of file main.c.

Referenced by _InitializeLocalSpooler(), GetJobFilePath(), and InitializeGlobalJobList().

◆ cchSpoolDirectory

DWORD cchSpoolDirectory
extern

Definition at line 16 of file main.c.

Referenced by _InitializeLocalSpooler(), and LocalGetPrintProcessorDirectory().

◆ dwSpoolerMajorVersion

const DWORD dwSpoolerMajorVersion
extern

This is what the Spooler of Windows Server 2003 returns (for example using GetPrinterDataExW, SPLREG_MAJOR_VERSION/SPLREG_MINOR_VERSION)

Definition at line 22 of file main.c.

Referenced by _LocalGetPrintServerHandleData().

◆ dwSpoolerMinorVersion

const DWORD dwSpoolerMinorVersion
extern

Definition at line 23 of file main.c.

Referenced by _LocalGetPrintServerHandleData().

◆ GlobalJobList

◆ hPrintersKey

◆ hPrintKey

HKEY hPrintKey
extern

◆ PrinterList

◆ PrintMonitorList

◆ wszCurrentEnvironment

const WCHAR wszCurrentEnvironment[]
extern

Definition at line 11 of file prtprocenv.h.

◆ wszDefaultDocumentName

const WCHAR wszDefaultDocumentName[]
extern

Definition at line 25 of file main.c.

Referenced by CreateJob().

◆ wszJobDirectory

WCHAR wszJobDirectory[MAX_PATH]
extern

Definition at line 13 of file main.c.

Referenced by _InitializeLocalSpooler(), GetJobFilePath(), and InitializeGlobalJobList().

◆ wszPrintProviderInfo

◆ wszSpoolDirectory

WCHAR wszSpoolDirectory[MAX_PATH]
extern

Definition at line 15 of file main.c.

Referenced by _InitializeLocalSpooler(), and LocalGetPrintProcessorDirectory().