1 /* 2 * PROJECT: ReactOS Spooler API 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Functions related to Print Processors 5 * COPYRIGHT: Copyright 2015-2018 Colin Finck (colin@reactos.org) 6 */ 7 8 #include "precomp.h" 9 #include <marshalling/printprocessors.h> 10 #include <prtprocenv.h> 11 12 BOOL WINAPI 13 AddPrintProcessorA(PSTR pName, PSTR pEnvironment, PSTR pPathName, PSTR pPrintProcessorName) 14 { 15 TRACE("AddPrintProcessorA(%s, %s, %s, %s)\n", pName, pEnvironment, pPathName, pPrintProcessorName); 16 UNIMPLEMENTED; 17 return FALSE; 18 } 19 20 BOOL WINAPI 21 AddPrintProcessorW(PWSTR pName, PWSTR pEnvironment, PWSTR pPathName, PWSTR pPrintProcessorName) 22 { 23 TRACE("AddPrintProcessorW(%S, %S, %S, %S)\n", pName, pEnvironment, pPathName, pPrintProcessorName); 24 UNIMPLEMENTED; 25 return FALSE; 26 } 27 28 BOOL WINAPI 29 DeletePrintProcessorA(PSTR pName, PSTR pEnvironment, PSTR pPrintProcessorName) 30 { 31 TRACE("DeletePrintProcessorA(%s, %s, %s)\n", pName, pEnvironment, pPrintProcessorName); 32 UNIMPLEMENTED; 33 return FALSE; 34 } 35 36 BOOL WINAPI 37 DeletePrintProcessorW(PWSTR pName, PWSTR pEnvironment, PWSTR pPrintProcessorName) 38 { 39 TRACE("DeletePrintProcessorW(%S, %S, %S)\n", pName, pEnvironment, pPrintProcessorName); 40 UNIMPLEMENTED; 41 return FALSE; 42 } 43 44 BOOL WINAPI 45 EnumPrintProcessorDatatypesA(PSTR pName, LPSTR pPrintProcessorName, DWORD Level, PBYTE pDatatypes, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned) 46 { 47 TRACE("EnumPrintProcessorDatatypesA(%s, %s, %lu, %p, %lu, %p, %p)\n", pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned); 48 UNIMPLEMENTED; 49 return FALSE; 50 } 51 52 BOOL WINAPI 53 EnumPrintProcessorDatatypesW(PWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, PBYTE pDatatypes, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned) 54 { 55 DWORD dwErrorCode; 56 57 TRACE("EnumPrintProcessorDatatypesW(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned); 58 59 // Sanity checks 60 if (Level != 1) 61 { 62 dwErrorCode = ERROR_INVALID_LEVEL; 63 goto Cleanup; 64 } 65 66 // Do the RPC call 67 RpcTryExcept 68 { 69 dwErrorCode = _RpcEnumPrintProcessorDatatypes(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned); 70 } 71 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 72 { 73 dwErrorCode = RpcExceptionCode(); 74 ERR("_RpcEnumPrintProcessorDatatypes failed with exception code %lu!\n", dwErrorCode); 75 } 76 RpcEndExcept; 77 78 if (dwErrorCode == ERROR_SUCCESS) 79 { 80 // Replace relative offset addresses in the output by absolute pointers. 81 MarshallUpStructuresArray(cbBuf, pDatatypes, *pcReturned, DatatypesInfo1Marshalling.pInfo, DatatypesInfo1Marshalling.cbStructureSize, TRUE); 82 } 83 84 Cleanup: 85 SetLastError(dwErrorCode); 86 return (dwErrorCode == ERROR_SUCCESS); 87 } 88 89 BOOL WINAPI 90 EnumPrintProcessorsA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned) 91 { 92 TRACE("EnumPrintProcessorsA(%s, %s, %lu, %p, %lu, %p, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned); 93 UNIMPLEMENTED; 94 return FALSE; 95 } 96 97 BOOL WINAPI 98 EnumPrintProcessorsW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned) 99 { 100 DWORD dwErrorCode; 101 102 TRACE("EnumPrintProcessorsW(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned); 103 104 // Choose our current environment if the caller didn't give any. 105 if (!pEnvironment) 106 pEnvironment = (PWSTR)wszCurrentEnvironment; 107 108 // Do the RPC call 109 RpcTryExcept 110 { 111 dwErrorCode = _RpcEnumPrintProcessors(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned); 112 } 113 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 114 { 115 dwErrorCode = RpcExceptionCode(); 116 } 117 RpcEndExcept; 118 119 if (dwErrorCode == ERROR_SUCCESS) 120 { 121 // Replace relative offset addresses in the output by absolute pointers. 122 MarshallUpStructuresArray(cbBuf, pPrintProcessorInfo, *pcReturned, PrintProcessorInfo1Marshalling.pInfo, PrintProcessorInfo1Marshalling.cbStructureSize, TRUE); 123 } 124 125 SetLastError(dwErrorCode); 126 return (dwErrorCode == ERROR_SUCCESS); 127 } 128 129 BOOL WINAPI 130 GetPrintProcessorDirectoryA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded) 131 { 132 BOOL bReturnValue = FALSE; 133 DWORD cch; 134 PWSTR pwszName = NULL; 135 PWSTR pwszEnvironment = NULL; 136 PWSTR pwszPrintProcessorInfo = NULL; 137 138 TRACE("GetPrintProcessorDirectoryA(%s, %s, %lu, %p, %lu, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded); 139 140 if (pName) 141 { 142 // Convert pName to a Unicode string pwszName. 143 cch = strlen(pName); 144 145 pwszName = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); 146 if (!pwszName) 147 { 148 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 149 ERR("HeapAlloc failed!\n"); 150 goto Cleanup; 151 } 152 153 MultiByteToWideChar(CP_ACP, 0, pName, -1, pwszName, cch + 1); 154 } 155 156 if (pEnvironment) 157 { 158 // Convert pEnvironment to a Unicode string pwszEnvironment. 159 cch = strlen(pEnvironment); 160 161 pwszEnvironment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); 162 if (!pwszEnvironment) 163 { 164 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 165 ERR("HeapAlloc failed!\n"); 166 goto Cleanup; 167 } 168 169 MultiByteToWideChar(CP_ACP, 0, pEnvironment, -1, pwszEnvironment, cch + 1); 170 } 171 172 if (cbBuf && pPrintProcessorInfo) 173 { 174 // Allocate a temporary buffer for the Unicode result. 175 // We can just go with cbBuf here. The user should have set it based on pcbNeeded returned in a previous call and our 176 // pcbNeeded is the same for the A and W functions. 177 pwszPrintProcessorInfo = HeapAlloc(hProcessHeap, 0, cbBuf); 178 if (!pwszPrintProcessorInfo) 179 { 180 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 181 ERR("HeapAlloc failed!\n"); 182 goto Cleanup; 183 } 184 } 185 186 bReturnValue = GetPrintProcessorDirectoryW(pwszName, pwszEnvironment, Level, (PBYTE)pwszPrintProcessorInfo, cbBuf, pcbNeeded); 187 188 if (bReturnValue) 189 { 190 // Convert pwszPrintProcessorInfo to an ANSI string pPrintProcessorInfo. 191 WideCharToMultiByte(CP_ACP, 0, pwszPrintProcessorInfo, -1, (PSTR)pPrintProcessorInfo, cbBuf, NULL, NULL); 192 } 193 194 Cleanup: 195 if (pwszName) 196 HeapFree(hProcessHeap, 0, pwszName); 197 198 if (pwszEnvironment) 199 HeapFree(hProcessHeap, 0, pwszEnvironment); 200 201 if (pwszPrintProcessorInfo) 202 HeapFree(hProcessHeap, 0, pwszPrintProcessorInfo); 203 204 return bReturnValue; 205 } 206 207 BOOL WINAPI 208 GetPrintProcessorDirectoryW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded) 209 { 210 DWORD dwErrorCode; 211 212 TRACE("GetPrintProcessorDirectoryW(%S, %S, %lu, %p, %lu, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded); 213 214 // Sanity checks 215 if (Level != 1) 216 { 217 dwErrorCode = ERROR_INVALID_LEVEL; 218 goto Cleanup; 219 } 220 221 // Choose our current environment if the caller didn't give any. 222 if (!pEnvironment) 223 pEnvironment = (PWSTR)wszCurrentEnvironment; 224 225 // Do the RPC call 226 RpcTryExcept 227 { 228 dwErrorCode = _RpcGetPrintProcessorDirectory(pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded); 229 } 230 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 231 { 232 dwErrorCode = RpcExceptionCode(); 233 } 234 RpcEndExcept; 235 236 Cleanup: 237 SetLastError(dwErrorCode); 238 return (dwErrorCode == ERROR_SUCCESS); 239 } 240