ReactOS  0.4.14-dev-297-g23e575c
ports.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Local Spooler
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Functions related to Ports of the Print Monitors
5  * COPYRIGHT: Copyright 2015-2017 Colin Finck (colin@reactos.org)
6  */
7 
8 #include "precomp.h"
9 
10 // Local Variables
12 
13 
15 FindPort(PCWSTR pwszName)
16 {
17  PLIST_ENTRY pEntry;
18  PLOCAL_PORT pPort;
19 
20  TRACE("FindPort(%S)\n", pwszName);
21 
22  if (!pwszName)
23  return NULL;
24 
25  for (pEntry = _PortList.Flink; pEntry != &_PortList; pEntry = pEntry->Flink)
26  {
27  pPort = CONTAINING_RECORD(pEntry, LOCAL_PORT, Entry);
28 
29  if (_wcsicmp(pPort->pwszName, pwszName) == 0)
30  return pPort;
31  }
32 
33  return NULL;
34 }
35 
36 BOOL
38 {
39  BOOL bReturnValue;
40  DWORD cbNeeded;
41  DWORD cbPortName;
42  DWORD dwErrorCode;
43  DWORD dwReturned;
44  DWORD i;
45  PLOCAL_PORT pPort;
46  PLOCAL_PRINT_MONITOR pPrintMonitor;
47  PLIST_ENTRY pEntry;
49  PPORT_INFO_1W pPortInfo1 = NULL;
50 
51  TRACE("InitializePortList()\n");
52 
53  // Initialize an empty list for our Ports.
55 
56  // Loop through all Print Monitors.
57  for (pEntry = PrintMonitorList.Flink; pEntry != &PrintMonitorList; pEntry = pEntry->Flink)
58  {
59  // Cleanup from the previous run.
60  if (pPortInfo1)
61  {
62  DllFreeSplMem(pPortInfo1);
63  pPortInfo1 = NULL;
64  }
65 
66  pPrintMonitor = CONTAINING_RECORD(pEntry, LOCAL_PRINT_MONITOR, Entry);
67 
68  // Determine the required buffer size for EnumPorts.
69  if (pPrintMonitor->bIsLevel2)
70  bReturnValue = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnEnumPorts(pPrintMonitor->hMonitor, NULL, 1, NULL, 0, &cbNeeded, &dwReturned);
71  else
72  bReturnValue = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnEnumPorts(NULL, 1, NULL, 0, &cbNeeded, &dwReturned);
73 
74  // Check the returned error code.
76  {
77  ERR("Print Monitor \"%S\" failed with error %lu on EnumPorts!\n", pPrintMonitor->pwszName, GetLastError());
78  continue;
79  }
80 
81  // Allocate a buffer large enough.
82  pPortInfo1 = DllAllocSplMem(cbNeeded);
83  if (!pPortInfo1)
84  {
85  dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
86  ERR("DllAllocSplMem failed!\n");
87  goto Cleanup;
88  }
89 
90  // Get the ports handled by this monitor.
91  if (pPrintMonitor->bIsLevel2)
92  bReturnValue = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnEnumPorts(pPrintMonitor->hMonitor, NULL, 1, (PBYTE)pPortInfo1, cbNeeded, &cbNeeded, &dwReturned);
93  else
94  bReturnValue = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnEnumPorts(NULL, 1, (PBYTE)pPortInfo1, cbNeeded, &cbNeeded, &dwReturned);
95 
96  // Check the return value.
97  if (!bReturnValue)
98  {
99  ERR("Print Monitor \"%S\" failed with error %lu on EnumPorts!\n", pPrintMonitor->pwszName, GetLastError());
100  continue;
101  }
102 
103  // Loop through all returned ports.
104  p = pPortInfo1;
105 
106  for (i = 0; i < dwReturned; i++)
107  {
108  cbPortName = (wcslen(p->pName) + 1) * sizeof(WCHAR);
109 
110  // Create a new LOCAL_PORT structure for it.
111  pPort = DllAllocSplMem(sizeof(LOCAL_PORT) + cbPortName);
112  if (!pPort)
113  {
114  dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
115  ERR("DllAllocSplMem failed!\n");
116  goto Cleanup;
117  }
118 
119  pPort->pPrintMonitor = pPrintMonitor;
120  pPort->pwszName = (PWSTR)((PBYTE)pPort + sizeof(LOCAL_PORT));
121  CopyMemory(pPort->pwszName, p->pName, cbPortName);
122 
123  // Insert it into the list and advance to the next port.
124  InsertTailList(&_PortList, &pPort->Entry);
125  p++;
126  }
127  }
128 
129  dwErrorCode = ERROR_SUCCESS;
130 
131 Cleanup:
132  // Inside the loop
133  if (pPortInfo1)
134  DllFreeSplMem(pPortInfo1);
135 
136  SetLastError(dwErrorCode);
137  return (dwErrorCode == ERROR_SUCCESS);
138 }
139 
140 BOOL WINAPI
142 {
143  BOOL bReturnValue = TRUE;
144  DWORD cbCallBuffer;
145  DWORD cbNeeded;
146  DWORD dwReturned;
147  PBYTE pCallBuffer;
148  PLOCAL_PRINT_MONITOR pPrintMonitor;
149  PLIST_ENTRY pEntry;
150 
151  TRACE("LocalEnumPorts(%S, %lu, %p, %lu, %p, %p)\n", pName, Level, pPorts, cbBuf, pcbNeeded, pcReturned);
152 
153  // Begin counting.
154  *pcbNeeded = 0;
155  *pcReturned = 0;
156 
157  // At the beginning, we have the full buffer available.
158  cbCallBuffer = cbBuf;
159  pCallBuffer = pPorts;
160 
161  // Loop through all Print Monitors.
162  for (pEntry = PrintMonitorList.Flink; pEntry != &PrintMonitorList; pEntry = pEntry->Flink)
163  {
164  pPrintMonitor = CONTAINING_RECORD(pEntry, LOCAL_PRINT_MONITOR, Entry);
165 
166  // Call the EnumPorts function of this Print Monitor.
167  cbNeeded = 0;
168  dwReturned = 0;
169 
170  if (pPrintMonitor->bIsLevel2)
171  bReturnValue = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnEnumPorts(pPrintMonitor->hMonitor, pName, Level, pCallBuffer, cbCallBuffer, &cbNeeded, &dwReturned);
172  else
173  bReturnValue = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnEnumPorts(pName, Level, pCallBuffer, cbCallBuffer, &cbNeeded, &dwReturned);
174 
175  // Add the returned counts to the total values.
176  *pcbNeeded += cbNeeded;
177  *pcReturned += dwReturned;
178 
179  // Reduce the available buffer size for the next call without risking an underflow.
180  if (cbNeeded < cbCallBuffer)
181  cbCallBuffer -= cbNeeded;
182  else
183  cbCallBuffer = 0;
184 
185  // Advance the buffer if the caller provided it.
186  if (pCallBuffer)
187  pCallBuffer += cbNeeded;
188  }
189 
190  return bReturnValue;
191 }
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define TRUE
Definition: types.h:120
LIST_ENTRY Entry
Definition: precomp.h:85
PWSTR pwszName
Definition: precomp.h:86
#define ERROR_SUCCESS
Definition: deptool.c:10
uint16_t * PWSTR
Definition: typedefs.h:54
BOOL WINAPI DllFreeSplMem(PVOID pMem)
Definition: memory.c:112
PLOCAL_PRINT_MONITOR pPrintMonitor
Definition: precomp.h:87
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
#define InsertTailList(ListHead, Entry)
struct _LOCAL_PORT LOCAL_PORT
Definition: precomp.h:56
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
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
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:119
#define TRACE(s)
Definition: solgame.cpp:4
static LPSTR pName
Definition: security.c:75
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define WINAPI
Definition: msvc.h:8
#define CopyMemory
Definition: winbase.h:1640
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:409
PLOCAL_PORT FindPort(PCWSTR pwszName)
Definition: ports.c:15
Definition: typedefs.h:117
static const WCHAR Cleanup[]
Definition: register.c:80
#define ERR(fmt,...)
Definition: debug.h:109
BOOL WINAPI LocalEnumPorts(PWSTR pName, DWORD Level, PBYTE pPorts, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
Definition: ports.c:141
static LIST_ENTRY _PortList
Definition: ports.c:11
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3827
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DWORD * PDWORD
Definition: pedump.c:68
LIST_ENTRY PrintMonitorList
Definition: monitors.c:11
struct _MONITOR2 * PMONITOR2
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
Definition: memory.c:95
GLfloat GLfloat p
Definition: glext.h:8902
struct _MONITOREX * LPMONITOREX
BOOL InitializePortList(void)
Definition: ports.c:37
BYTE * PBYTE
Definition: pedump.c:66
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
base of all file and directory entries
Definition: entries.h:82
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10