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