ReactOS 0.4.15-dev-5666-gc548b97
monitors.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Spooler API
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Functions related to Print Monitors
5 * COPYRIGHT: Copyright 2015-2018 Colin Finck (colin@reactos.org)
6 */
7
8#include "precomp.h"
10
13{
15 INT len;
16 BOOL res;
18 MONITOR_INFO_2W mi2w;
19
20 mi2a = (LPMONITOR_INFO_2A) pMonitors;
21 FIXME("AddMonitorA(%s, %d, %p) : %s %s %s\n", debugstr_a(pName), Level, pMonitors,
22 debugstr_a(mi2a ? mi2a->pName : NULL),
23 debugstr_a(mi2a ? mi2a->pEnvironment : NULL),
24 debugstr_a(mi2a ? mi2a->pDLLName : NULL));
25
26 if (Level != 2)
27 {
28 ERR("Level = %d, unsupported!\n", Level);
30 return FALSE;
31 }
32
33 /* XP: unchanged, win9x: ERROR_INVALID_ENVIRONMENT */
34 if (mi2a == NULL)
35 {
36 return FALSE;
37 }
38
39 if (pName)
40 {
42 nameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
44 }
45
46 memset(&mi2w, 0, sizeof(MONITOR_INFO_2W));
47 if (mi2a->pName)
48 {
49 len = MultiByteToWideChar(CP_ACP, 0, mi2a->pName, -1, NULL, 0);
50 mi2w.pName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
51 MultiByteToWideChar(CP_ACP, 0, mi2a->pName, -1, mi2w.pName, len);
52 }
53 if (mi2a->pEnvironment)
54 {
55 len = MultiByteToWideChar(CP_ACP, 0, mi2a->pEnvironment, -1, NULL, 0);
56 mi2w.pEnvironment = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
58 }
59 if (mi2a->pDLLName)
60 {
61 len = MultiByteToWideChar(CP_ACP, 0, mi2a->pDLLName, -1, NULL, 0);
62 mi2w.pDLLName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
63 MultiByteToWideChar(CP_ACP, 0, mi2a->pDLLName, -1, mi2w.pDLLName, len);
64 }
65
66 res = AddMonitorW(nameW, Level, (LPBYTE) &mi2w);
67
68 if (mi2w.pName) HeapFree(GetProcessHeap(), 0, mi2w.pName);
70 if (mi2w.pDLLName) HeapFree(GetProcessHeap(), 0, mi2w.pDLLName);
72
73 return (res);
74}
75
78{
79 DWORD dwErrorCode;
80 WINSPOOL_MONITOR_CONTAINER MonitorInfoContainer;
81
82 FIXME("AddMonitorW(%S, %lu, %p)\n", pName, Level, pMonitors);
83
84 if (Level != 2)
85 {
86 ERR("Level = %d, unsupported!\n", Level);
88 return FALSE;
89 }
90
91 MonitorInfoContainer.MonitorInfo.pMonitorInfo2 = (WINSPOOL_MONITOR_INFO_2*)pMonitors;
92 MonitorInfoContainer.Level = Level;
93
94 // Do the RPC call
96 {
97 dwErrorCode = _RpcAddMonitor(pName, &MonitorInfoContainer);
98 }
100 {
101 dwErrorCode = RpcExceptionCode();
102 ERR("_RpcAddMonitor failed with exception code %lu!\n", dwErrorCode);
103 }
105FIXME("AddMonitorW Error Code %lu\n", dwErrorCode);
106 SetLastError(dwErrorCode);
107 return (dwErrorCode == ERROR_SUCCESS);
108}
109
111DeleteMonitorA(PSTR pName, PSTR pEnvironment, PSTR pMonitorName)
112{
113 LPWSTR nameW = NULL;
114 LPWSTR EnvironmentW = NULL;
115 LPWSTR MonitorNameW = NULL;
116 BOOL res;
117 INT len;
118
119 TRACE("DeleteMonitorA(%s, %s, %s)\n", pName, pEnvironment, pMonitorName);
120
121 if (pName) {
122 len = MultiByteToWideChar(CP_ACP, 0, pName, -1, NULL, 0);
123 nameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
125 }
126
127 if (pEnvironment) {
128 len = MultiByteToWideChar(CP_ACP, 0, pEnvironment, -1, NULL, 0);
129 EnvironmentW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
130 MultiByteToWideChar(CP_ACP, 0, pEnvironment, -1, EnvironmentW, len);
131 }
132 if (pMonitorName) {
133 len = MultiByteToWideChar(CP_ACP, 0, pMonitorName, -1, NULL, 0);
134 MonitorNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
135 MultiByteToWideChar(CP_ACP, 0, pMonitorName, -1, MonitorNameW, len);
136 }
137
138 res = DeleteMonitorW(nameW, EnvironmentW, MonitorNameW);
139
140 if (MonitorNameW) HeapFree(GetProcessHeap(), 0, MonitorNameW);
141 if (EnvironmentW) HeapFree(GetProcessHeap(), 0, EnvironmentW);
143
144 return (res);
145}
146
148DeleteMonitorW(PWSTR pName, PWSTR pEnvironment, PWSTR pMonitorName)
149{
150 DWORD dwErrorCode;
151
152 FIXME("DeleteMonitorW(%S, %S, %S)\n", pName, pEnvironment, pMonitorName);
153
154 // Do the RPC call
156 {
157 dwErrorCode = _RpcDeleteMonitor(pName, pEnvironment, pMonitorName);
158 }
160 {
161 dwErrorCode = RpcExceptionCode();
162 ERR("_RpcDeleteMonitor failed with exception code %lu!\n", dwErrorCode);
163 }
165
166 SetLastError(dwErrorCode);
167 return (dwErrorCode == ERROR_SUCCESS);
168
169}
170
173{
174 BOOL res;
175 LPBYTE bufferW = NULL;
176 LPWSTR nameW = NULL;
177 DWORD needed = 0;
178 DWORD numentries = 0;
179 INT len;
180
181 FIXME("EnumMonitorsA(%s, %d, %p, %d, %p, %p)\n", debugstr_a(pName), Level, pMonitors, cbBuf, pcbNeeded, pcReturned);
182
183 if ( Level < 1 || Level > 2 )
184 {
185 ERR("Level = %d, unsupported!\n", Level);
187 return FALSE;
188 }
189
190 /* convert servername to unicode */
191 if (pName)
192 {
193 len = MultiByteToWideChar(CP_ACP, 0, pName, -1, NULL, 0);
194 nameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
196 }
197 /* alloc (userbuffersize*sizeof(WCHAR) and try to enum the monitors */
198 needed = cbBuf * sizeof(WCHAR);
199 if (needed) bufferW = HeapAlloc(GetProcessHeap(), 0, needed);
200 res = EnumMonitorsW(nameW, Level, bufferW, needed, pcbNeeded, pcReturned);
201
203 {
204 if (pcbNeeded) needed = *pcbNeeded;
205 /* HeapReAlloc return NULL, when bufferW was NULL */
206 bufferW = (bufferW) ? HeapReAlloc(GetProcessHeap(), 0, bufferW, needed) :
207 HeapAlloc(GetProcessHeap(), 0, needed);
208
209 /* Try again with the large Buffer */
210 res = EnumMonitorsW(nameW, Level, bufferW, needed, pcbNeeded, pcReturned);
211 }
212 numentries = pcReturned ? *pcReturned : 0;
213 needed = 0;
214 /*
215 W2k require the buffersize from EnumMonitorsW also for EnumMonitorsA.
216 We use the smaller Ansi-Size to avoid conflicts with fixed Buffers of old Apps.
217 */
218 if (res)
219 {
220 /* EnumMonitorsW collected all Data. Parse them to calculate ANSI-Size */
221 DWORD entrysize = 0;
222 DWORD index;
223 LPSTR ptr;
226
227 /* MONITOR_INFO_*W and MONITOR_INFO_*A have the same size */
228 entrysize = (Level == 1) ? sizeof(MONITOR_INFO_1A) : sizeof(MONITOR_INFO_2A);
229
230 /* First pass: calculate the size for all Entries */
231 mi2w = (LPMONITOR_INFO_2W) bufferW;
232 mi2a = (LPMONITOR_INFO_2A) pMonitors;
233 index = 0;
234 while (index < numentries)
235 {
236 index++;
237 needed += entrysize; /* MONITOR_INFO_?A */
238 TRACE("%p: parsing #%d (%s)\n", mi2w, index, debugstr_w(mi2w->pName));
239
240 needed += WideCharToMultiByte(CP_ACP, 0, mi2w->pName, -1,
241 NULL, 0, NULL, NULL);
242 if (Level > 1)
243 {
244 needed += WideCharToMultiByte(CP_ACP, 0, mi2w->pEnvironment, -1,
245 NULL, 0, NULL, NULL);
246 needed += WideCharToMultiByte(CP_ACP, 0, mi2w->pDLLName, -1,
247 NULL, 0, NULL, NULL);
248 }
249 /* use LPBYTE with entrysize to avoid double code (MONITOR_INFO_1 + MONITOR_INFO_2) */
250 mi2w = (LPMONITOR_INFO_2W) (((LPBYTE)mi2w) + entrysize);
251 mi2a = (LPMONITOR_INFO_2A) (((LPBYTE)mi2a) + entrysize);
252 }
253
254 /* check for errors and quit on failure */
255 if (cbBuf < needed)
256 {
258 res = FALSE;
259 goto emA_cleanup;
260 }
261 len = entrysize * numentries; /* room for all MONITOR_INFO_?A */
262 ptr = (LPSTR) &pMonitors[len]; /* room for strings */
263 cbBuf -= len ; /* free Bytes in the user-Buffer */
264 mi2w = (LPMONITOR_INFO_2W) bufferW;
265 mi2a = (LPMONITOR_INFO_2A) pMonitors;
266 index = 0;
267 /* Second Pass: Fill the User Buffer (if we have one) */
268 while ((index < numentries) && pMonitors)
269 {
270 index++;
271 TRACE("%p: writing MONITOR_INFO_%dA #%d\n", mi2a, Level, index);
272 mi2a->pName = ptr;
273 len = WideCharToMultiByte(CP_ACP, 0, mi2w->pName, -1,
274 ptr, cbBuf , NULL, NULL);
275 ptr += len;
276 cbBuf -= len;
277 if (Level > 1)
278 {
279 mi2a->pEnvironment = ptr;
281 ptr, cbBuf, NULL, NULL);
282 ptr += len;
283 cbBuf -= len;
284
285 mi2a->pDLLName = ptr;
286 len = WideCharToMultiByte(CP_ACP, 0, mi2w->pDLLName, -1,
287 ptr, cbBuf, NULL, NULL);
288 ptr += len;
289 cbBuf -= len;
290 }
291 /* use LPBYTE with entrysize to avoid double code (MONITOR_INFO_1 + MONITOR_INFO_2) */
292 mi2w = (LPMONITOR_INFO_2W) (((LPBYTE)mi2w) + entrysize);
293 mi2a = (LPMONITOR_INFO_2A) (((LPBYTE)mi2a) + entrysize);
294 }
295 }
296emA_cleanup:
297 if (pcbNeeded) *pcbNeeded = needed;
298 if (pcReturned) *pcReturned = (res) ? numentries : 0;
299
301 if (bufferW) HeapFree(GetProcessHeap(), 0, bufferW);
302
303 FIXME("returning %d with %d (%d byte for %d entries)\n", (res), GetLastError(), needed, numentries);
304
305 return (res);
306
307}
308
311{
312 DWORD dwErrorCode;
313
314 FIXME("EnumMonitorsW(%S, %lu, %p, %lu, %p, %p)\n", pName, Level, pMonitors, cbBuf, pcbNeeded, pcReturned);
315
316 if ( Level < 1 || Level > 2 )
317 {
318 ERR("Level = %d, unsupported!\n", Level);
320 return FALSE;
321 }
322
323 // Do the RPC call
325 {
326 dwErrorCode = _RpcEnumMonitors(pName, Level, pMonitors, cbBuf, pcbNeeded, pcReturned);
327 }
329 {
330 dwErrorCode = RpcExceptionCode();
331 ERR("_RpcEnumMonitors failed with exception code %lu!\n", dwErrorCode);
332 }
334
335 if (dwErrorCode == ERROR_SUCCESS)
336 {
337 // Replace relative offset addresses in the output by absolute pointers.
338 ASSERT(Level >= 1 && Level <= 2);
339 MarshallUpStructuresArray(cbBuf, pMonitors, *pcReturned, pMonitorInfoMarshalling[Level]->pInfo, pMonitorInfoMarshalling[Level]->cbStructureSize, TRUE);
340 }
341
342 SetLastError(dwErrorCode);
343 return (dwErrorCode == ERROR_SUCCESS);
344}
static const WCHAR nameW[]
Definition: main.c:46
#define index(s, c)
Definition: various.h:29
BOOL WINAPI AddMonitorW(PWSTR pName, DWORD Level, PBYTE pMonitors)
Definition: monitors.c:11
BOOL WINAPI EnumMonitorsW(PWSTR pName, DWORD Level, PBYTE pMonitors, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
Definition: monitors.c:77
BOOL WINAPI DeleteMonitorW(PWSTR pName, PWSTR pEnvironment, PWSTR pMonitorName)
Definition: monitors.c:44
DWORD _RpcAddMonitor(WINSPOOL_HANDLE pName, WINSPOOL_MONITOR_CONTAINER *pMonitorContainer)
Definition: monitors.c:12
DWORD _RpcDeleteMonitor(WINSPOOL_HANDLE pName, WCHAR *pEnvironment, WCHAR *pMonitorName)
Definition: monitors.c:31
DWORD _RpcEnumMonitors(WINSPOOL_HANDLE pName, DWORD Level, BYTE *pMonitor, DWORD cbBuf, DWORD *pcbNeeded, DWORD *pcReturned)
Definition: monitors.c:50
BOOL WINAPI DeleteMonitorA(PSTR pName, PSTR pEnvironment, PSTR pMonitorName)
Definition: monitors.c:111
BOOL WINAPI EnumMonitorsA(PSTR pName, DWORD Level, PBYTE pMonitors, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
Definition: monitors.c:172
BOOL WINAPI AddMonitorA(PSTR pName, DWORD Level, PBYTE pMonitors)
Definition: monitors.c:12
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define HeapFree(x, y, z)
Definition: compat.h:735
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint res
Definition: glext.h:9613
GLuint index
Definition: glext.h:6031
GLenum GLsizei len
Definition: glext.h:6722
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
signed char * PSTR
Definition: retypes.h:7
BOOL WINAPI MarshallUpStructuresArray(DWORD cbSize, PVOID pStructuresArray, DWORD cElements, const MARSHALLING_INFO *pInfo, DWORD cbStructureSize, BOOL bSomeBoolean)
Definition: marshalling.c:202
#define ASSERT(a)
Definition: mode.c:44
static PVOID ptr
Definition: dispmode.c:27
static LPSTR pName
Definition: security.c:75
static const MARSHALLING * pMonitorInfoMarshalling[]
Definition: monitors.h:26
BYTE * PBYTE
Definition: pedump.c:66
DWORD * PDWORD
Definition: pedump.c:68
#define RpcEndExcept
Definition: rpc.h:128
#define RpcTryExcept
Definition: rpc.h:126
#define RpcExcept(expr)
Definition: rpc.h:127
#define RpcExceptionCode()
Definition: rpc.h:132
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
LPSTR pEnvironment
Definition: winspool.h:828
LPWSTR pEnvironment
Definition: winspool.h:834
LPWSTR pDLLName
Definition: winspool.h:835
WINSPOOL_MONITOR_INFO_2 * pMonitorInfo2
Definition: winspool.idl:656
union _WINSPOOL_MONITOR_CONTAINER::@3414 MonitorInfo
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
DWORD WINAPI GetLastError(void)
Definition: except.c:1040
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3828
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196
struct _MONITOR_INFO_2A MONITOR_INFO_2A
struct _MONITOR_INFO_2A * LPMONITOR_INFO_2A
struct _MONITOR_INFO_2W * LPMONITOR_INFO_2W
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184