ReactOS  0.4.15-dev-1068-g467feb9
monitors.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Spooler Router
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Functions related to Print Monitors
5  * COPYRIGHT: Copyright 2015-2017 Colin Finck (colin@reactos.org)
6  */
7 
8 #include "precomp.h"
9 
12 {
13  BOOL bReturnValue = TRUE;
14  DWORD dwErrorCode = MAXDWORD;
15  PSPOOLSS_PRINT_PROVIDER pPrintProvider;
16  PLIST_ENTRY pEntry;
17 
18  // Loop through all Print Provider.
19  for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
20  {
21  pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
22 
23  // Check if this Print Provider provides the function.
24  if (!pPrintProvider->PrintProvider.fpAddMonitor)
25  continue;
26 
27  bReturnValue = pPrintProvider->PrintProvider.fpAddMonitor(pName, Level, pMonitors);
28 
29  if ( !bReturnValue )
30  {
31  dwErrorCode = GetLastError();
32  }
33 
34  // dwErrorCode shall not be overwritten if a previous call already succeeded.
35  if (dwErrorCode != ERROR_SUCCESS)
36  dwErrorCode = GetLastError();
37  }
38 
39  SetLastError(dwErrorCode);
40  return (dwErrorCode == ERROR_SUCCESS);
41 }
42 
44 DeleteMonitorW(PWSTR pName, PWSTR pEnvironment, PWSTR pMonitorName)
45 {
46  BOOL bReturnValue = TRUE;
47  DWORD dwErrorCode = MAXDWORD;
48  PSPOOLSS_PRINT_PROVIDER pPrintProvider;
49  PLIST_ENTRY pEntry;
50 
51  // Loop through all Print Provider.
52  for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
53  {
54  pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
55 
56  // Check if this Print Provider provides the function.
57  if (!pPrintProvider->PrintProvider.fpDeleteMonitor)
58  continue;
59 
60  bReturnValue = pPrintProvider->PrintProvider.fpDeleteMonitor(pName, pEnvironment, pMonitorName);
61 
62  if ( !bReturnValue )
63  {
64  dwErrorCode = GetLastError();
65  }
66 
67  // dwErrorCode shall not be overwritten if a previous call already succeeded.
68  if (dwErrorCode != ERROR_SUCCESS)
69  dwErrorCode = GetLastError();
70  }
71 
72  SetLastError(dwErrorCode);
73  return (dwErrorCode == ERROR_SUCCESS);
74 }
75 
78 {
79  BOOL bReturnValue = TRUE;
80  DWORD cbCallBuffer;
81  DWORD cbNeeded;
82  DWORD dwReturned;
83  DWORD dwErrorCode = MAXDWORD;
84  PBYTE pCallBuffer;
85  PSPOOLSS_PRINT_PROVIDER pPrintProvider;
86  PLIST_ENTRY pEntry;
87 
88  // Sanity checks.
89  if (cbBuf && !pMonitors)
90  {
92  return FALSE;
93  }
94 
95  // Begin counting.
96  *pcbNeeded = 0;
97  *pcReturned = 0;
98 
99  // At the beginning, we have the full buffer available.
100  cbCallBuffer = cbBuf;
101  pCallBuffer = pMonitors;
102 
103  // Loop through all Print Provider.
104  for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
105  {
106  pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
107 
108  // Check if this Print Provider provides an EnumMonitors function.
109  if (!pPrintProvider->PrintProvider.fpEnumMonitors)
110  continue;
111 
112  // Call the EnumMonitors function of this Print Provider.
113  cbNeeded = 0;
114  dwReturned = 0;
115  bReturnValue = pPrintProvider->PrintProvider.fpEnumMonitors(pName, Level, pCallBuffer, cbCallBuffer, &cbNeeded, &dwReturned);
116 
117  if ( !bReturnValue )
118  {
119  dwErrorCode = GetLastError();
120  }
121 
122  // Add the returned counts to the total values.
123  *pcbNeeded += cbNeeded;
124  *pcReturned += dwReturned;
125 
126  // Reduce the available buffer size for the next call without risking an underflow.
127  if (cbNeeded < cbCallBuffer)
128  cbCallBuffer -= cbNeeded;
129  else
130  cbCallBuffer = 0;
131 
132  // Advance the buffer if the caller provided it.
133  if (pCallBuffer)
134  pCallBuffer += cbNeeded;
135 
136  // dwErrorCode shall not be overwritten if a previous EnumPrinters call already succeeded.
137  if (dwErrorCode != ERROR_SUCCESS)
138  dwErrorCode = GetLastError();
139  }
140 
141  SetLastError(dwErrorCode);
142  return (dwErrorCode == ERROR_SUCCESS);
143 }
#define ERROR_SUCCESS
Definition: deptool.c:10
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define MAXDWORD
BOOL WINAPI EnumMonitorsW(PWSTR pName, DWORD Level, PBYTE pMonitors, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
Definition: monitors.c:77
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
static LPSTR pName
Definition: security.c:75
#define WINAPI
Definition: msvc.h:6
LIST_ENTRY PrintProviderList
Definition: main.c:12
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:500
Definition: typedefs.h:119
BOOL WINAPI AddMonitorW(PWSTR pName, DWORD Level, PBYTE pMonitors)
Definition: monitors.c:11
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3827
DWORD * PDWORD
Definition: pedump.c:68
PRINTPROVIDOR PrintProvider
Definition: precomp.h:36
BYTE * PBYTE
Definition: pedump.c:66
BOOL WINAPI DeleteMonitorW(PWSTR pName, PWSTR pEnvironment, PWSTR pMonitorName)
Definition: monitors.c:44
base of all file and directory entries
Definition: entries.h:82