[Printing] Update and Add Functions
[reactos.git] / win32ss / printing / base / spoolss / ports.c
1 /*
2 * PROJECT: ReactOS Spooler Router
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 BOOL WINAPI
11 AddPortExW(PWSTR pName, DWORD Level, PBYTE lpBuffer, PWSTR lpMonitorName)
12 {
13 BOOL bReturnValue = TRUE;
14 DWORD dwErrorCode = MAXDWORD;
15 PSPOOLSS_PRINT_PROVIDER pPrintProvider;
16 PLIST_ENTRY pEntry;
17
18 FIXME("AddPortEx(%S, %lu, %p, %s)\n", pName, Level, lpBuffer, debugstr_w(lpMonitorName));
19
20 // Loop through all Print Provider.
21 for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
22 {
23 pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
24
25 // Check if this Print Provider provides the function.
26 if (!pPrintProvider->PrintProvider.fpAddPortEx)
27 continue;
28
29 bReturnValue = pPrintProvider->PrintProvider.fpAddPortEx(pName, Level, lpBuffer, lpMonitorName);
30
31 if ( !bReturnValue )
32 {
33 dwErrorCode = GetLastError();
34 }
35
36 // dwErrorCode shall not be overwritten if a previous call already succeeded.
37 if (dwErrorCode != ERROR_SUCCESS)
38 dwErrorCode = GetLastError();
39 }
40
41 SetLastError(dwErrorCode);
42 return (dwErrorCode == ERROR_SUCCESS);
43 }
44
45 BOOL WINAPI
46 AddPortW(PWSTR pName, HWND hWnd, PWSTR pMonitorName)
47 {
48 BOOL bReturnValue = TRUE;
49 DWORD dwErrorCode = MAXDWORD;
50 PSPOOLSS_PRINT_PROVIDER pPrintProvider;
51 PLIST_ENTRY pEntry;
52
53 FIXME("AddPort(%S, %p, %s)\n", pName, hWnd, debugstr_w(pMonitorName));
54
55 // Loop through all Print Provider.
56 for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
57 {
58 pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
59
60 // Check if this Print Provider provides the function.
61 if (!pPrintProvider->PrintProvider.fpAddPort)
62 continue;
63
64 bReturnValue = pPrintProvider->PrintProvider.fpAddPort(pName, hWnd, pMonitorName);
65
66 if ( !bReturnValue )
67 {
68 dwErrorCode = GetLastError();
69 }
70
71 // dwErrorCode shall not be overwritten if a previous call already succeeded.
72 if (dwErrorCode != ERROR_SUCCESS)
73 dwErrorCode = GetLastError();
74 }
75
76 SetLastError(dwErrorCode);
77 return (dwErrorCode == ERROR_SUCCESS);
78 }
79
80 BOOL WINAPI
81 ConfigurePortW(PWSTR pName, HWND hWnd, PWSTR pPortName)
82 {
83 BOOL bReturnValue = TRUE;
84 DWORD dwErrorCode = MAXDWORD;
85 PSPOOLSS_PRINT_PROVIDER pPrintProvider;
86 PLIST_ENTRY pEntry;
87
88 // Loop through all Print Provider.
89 for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
90 {
91 pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
92
93 // Check if this Print Provider provides the function.
94 if (!pPrintProvider->PrintProvider.fpConfigurePort)
95 continue;
96
97 bReturnValue = pPrintProvider->PrintProvider.fpConfigurePort(pName, hWnd, pPortName);
98
99 if ( !bReturnValue )
100 {
101 dwErrorCode = GetLastError();
102 }
103
104 // dwErrorCode shall not be overwritten if a previous call already succeeded.
105 if (dwErrorCode != ERROR_SUCCESS)
106 dwErrorCode = GetLastError();
107 }
108
109 SetLastError(dwErrorCode);
110 return (dwErrorCode == ERROR_SUCCESS);
111 }
112
113 BOOL WINAPI
114 DeletePortW(PWSTR pName, HWND hWnd, PWSTR pPortName)
115 {
116 BOOL bReturnValue = TRUE;
117 DWORD dwErrorCode = MAXDWORD;
118 PSPOOLSS_PRINT_PROVIDER pPrintProvider;
119 PLIST_ENTRY pEntry;
120
121 // Loop through all Print Provider.
122 for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
123 {
124 pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
125
126 // Check if this Print Provider provides the function.
127 if (!pPrintProvider->PrintProvider.fpDeletePort)
128 continue;
129
130 bReturnValue = pPrintProvider->PrintProvider.fpDeletePort(pName, hWnd, pPortName);
131
132 if ( !bReturnValue )
133 {
134 dwErrorCode = GetLastError();
135 }
136
137 // dwErrorCode shall not be overwritten if a previous call already succeeded.
138 if (dwErrorCode != ERROR_SUCCESS)
139 dwErrorCode = GetLastError();
140 }
141
142 SetLastError(dwErrorCode);
143 return (dwErrorCode == ERROR_SUCCESS);
144 }
145
146 BOOL WINAPI
147 EnumPortsW(PWSTR pName, DWORD Level, PBYTE pPorts, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
148 {
149 BOOL bReturnValue = TRUE;
150 DWORD cbCallBuffer;
151 DWORD cbNeeded;
152 DWORD dwReturned;
153 DWORD dwErrorCode = MAXDWORD;
154 PBYTE pCallBuffer;
155 PSPOOLSS_PRINT_PROVIDER pPrintProvider;
156 PLIST_ENTRY pEntry;
157
158 // Sanity checks.
159 if (cbBuf && !pPorts)
160 {
161 SetLastError(ERROR_INVALID_USER_BUFFER);
162 return FALSE;
163 }
164
165 // Begin counting.
166 *pcbNeeded = 0;
167 *pcReturned = 0;
168
169 // At the beginning, we have the full buffer available.
170 cbCallBuffer = cbBuf;
171 pCallBuffer = pPorts;
172
173 // Loop through all Print Provider.
174 for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
175 {
176 pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
177
178 // Check if this Print Provider provides an EnumPorts function.
179 if (!pPrintProvider->PrintProvider.fpEnumPorts)
180 continue;
181
182 // Call the EnumPorts function of this Print Provider.
183 cbNeeded = 0;
184 dwReturned = 0;
185 bReturnValue = pPrintProvider->PrintProvider.fpEnumPorts(pName, Level, pCallBuffer, cbCallBuffer, &cbNeeded, &dwReturned);
186
187 if ( !bReturnValue )
188 {
189 dwErrorCode = GetLastError();
190 }
191
192 // Add the returned counts to the total values.
193 *pcbNeeded += cbNeeded;
194 *pcReturned += dwReturned;
195
196 // Reduce the available buffer size for the next call without risking an underflow.
197 if (cbNeeded < cbCallBuffer)
198 cbCallBuffer -= cbNeeded;
199 else
200 cbCallBuffer = 0;
201
202 // Advance the buffer if the caller provided it.
203 if (pCallBuffer)
204 pCallBuffer += cbNeeded;
205
206 // dwErrorCode shall not be overwritten if a previous EnumPrinters call already succeeded.
207 if (dwErrorCode != ERROR_SUCCESS)
208 dwErrorCode = GetLastError();
209 }
210
211 SetLastError(dwErrorCode);
212 return (dwErrorCode == ERROR_SUCCESS);
213 }
214
215 BOOL WINAPI
216 SetPortW(PWSTR pName, PWSTR pPortName, DWORD dwLevel, PBYTE pPortInfo)
217 {
218 BOOL bReturnValue = TRUE;
219 DWORD dwErrorCode = MAXDWORD;
220 PSPOOLSS_PRINT_PROVIDER pPrintProvider;
221 PLIST_ENTRY pEntry;
222
223 // Loop through all Print Provider.
224 for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
225 {
226 pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
227
228 // Check if this Print Provider provides the function.
229 if (!pPrintProvider->PrintProvider.fpSetPort)
230 continue;
231
232 bReturnValue = pPrintProvider->PrintProvider.fpSetPort(pName, pPortName, dwLevel, pPortInfo);
233
234 if ( !bReturnValue )
235 {
236 dwErrorCode = GetLastError();
237 }
238
239 // dwErrorCode shall not be overwritten if a previous call already succeeded.
240 if (dwErrorCode != ERROR_SUCCESS)
241 dwErrorCode = GetLastError();
242 }
243
244 SetLastError(dwErrorCode);
245 return (dwErrorCode == ERROR_SUCCESS);
246 }