xref: /reactos/win32ss/printing/base/spoolss/ports.c (revision 682f85ad)
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 }
247