1 /* 2 * PROJECT: ReactOS Print Spooler Service 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Xcv* functions 5 * COPYRIGHT: Copyright 2020 ReactOS 6 */ 7 8 #include "precomp.h" 9 10 static DWORD 11 _HandleAddPort(HANDLE hXcv, PBYTE pInputData, PDWORD pcbOutputNeeded, DWORD* pdwStatus) 12 { 13 DWORD res; 14 PLOCAL_PRINT_MONITOR pPrintMonitor; 15 PLOCAL_XCV_HANDLE pXcv; 16 PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hXcv; 17 PWSTR pPortName = (PWSTR)pInputData; 18 19 FIXME("LocalXcvAddPort : %s\n", debugstr_w( pPortName ) ); 20 21 // Check if this is a printer handle. 22 if (pHandle->HandleType != HandleType_Xcv) 23 { 24 ERR("LocalXcvAddPort : Invalid XCV Handle\n"); 25 res = ERROR_INVALID_HANDLE; 26 goto Cleanup; 27 } 28 29 pXcv = (PLOCAL_XCV_HANDLE)pHandle->pSpecificHandle; 30 31 pPrintMonitor = pXcv->pPrintMonitor; 32 if (!pPrintMonitor ) 33 { 34 res = ERROR_INVALID_PARAMETER; 35 goto Cleanup; 36 } 37 38 // Sanity checks 39 if (!pInputData || !pcbOutputNeeded) 40 { 41 res = ERROR_INVALID_PARAMETER; 42 goto Cleanup; 43 } 44 45 pPrintMonitor->refcount++; 46 if ( pPrintMonitor->bIsLevel2 && ((PMONITOR2)pPrintMonitor->pMonitor)->pfnXcvDataPort ) 47 { 48 res = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnXcvDataPort(pXcv->hXcv, L"AddPort", pInputData, 0, NULL, 0, pcbOutputNeeded); 49 } 50 else if ( !pPrintMonitor->bIsLevel2 && ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnXcvDataPort ) 51 { 52 res = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnXcvDataPort(pXcv->hXcv, L"AddPort", pInputData, 0, NULL, 0, pcbOutputNeeded); 53 } 54 pPrintMonitor->refcount--; 55 56 if ( res == ERROR_SUCCESS ) 57 { 58 CreatePortEntry( pPortName, pPrintMonitor ); 59 } 60 61 FIXME("=> %u\n", res); 62 63 Cleanup: 64 if (pdwStatus) *pdwStatus = res; 65 return res; 66 } 67 68 static DWORD 69 _HandleDeletePort(HANDLE hXcv, PBYTE pInputData, PDWORD pcbOutputNeeded, DWORD* pdwStatus) 70 { 71 DWORD res; 72 PLOCAL_PRINT_MONITOR pPrintMonitor; 73 PLOCAL_XCV_HANDLE pXcv; 74 PLOCAL_PORT pPort; 75 PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hXcv; 76 PWSTR pPortName = (PWSTR)pInputData; 77 78 FIXME("LocalXcvDeletePort : %s\n", debugstr_w( pPortName ) ); 79 80 // Check if this is a printer handle. 81 if (pHandle->HandleType != HandleType_Xcv) 82 { 83 ERR("LocalXcvDeletePort : Invalid XCV Handle\n"); 84 res = ERROR_INVALID_HANDLE; 85 goto Cleanup; 86 } 87 88 pXcv = (PLOCAL_XCV_HANDLE)pHandle->pSpecificHandle; 89 90 pPrintMonitor = pXcv->pPrintMonitor; 91 if (!pPrintMonitor ) 92 { 93 res = ERROR_INVALID_PARAMETER; 94 goto Cleanup; 95 } 96 97 // Sanity checks 98 if (!pInputData || !pcbOutputNeeded) 99 { 100 res = ERROR_INVALID_PARAMETER; 101 goto Cleanup; 102 } 103 104 105 pPrintMonitor->refcount++; 106 // 107 // Call back to monitor, update the Registry and Registry List. 108 // 109 if ( pPrintMonitor->bIsLevel2 && ((PMONITOR2)pPrintMonitor->pMonitor)->pfnXcvDataPort ) 110 { 111 res = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnXcvDataPort(pXcv->hXcv, L"DeletePort", pInputData, 0, NULL, 0, pcbOutputNeeded); 112 } 113 else if ( !pPrintMonitor->bIsLevel2 && ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnXcvDataPort ) 114 { 115 res = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnXcvDataPort(pXcv->hXcv, L"DeletePort", pInputData, 0, NULL, 0, pcbOutputNeeded); 116 } 117 pPrintMonitor->refcount--; 118 // 119 // Now find and remove Local Port data. 120 // 121 if ( res == ERROR_SUCCESS ) 122 { 123 pPort = FindPort( pPortName ); 124 if (pPort ) 125 { 126 FIXME("LocalXcvDeletePort removed Port Entry\n"); 127 RemoveEntryList(&pPort->Entry); 128 129 DllFreeSplMem(pPort); 130 } 131 FIXME("=> %u with %u\n", res, GetLastError() ); 132 } 133 134 Cleanup: 135 if (pdwStatus) *pdwStatus = res; 136 return res; 137 } 138 139 BOOL WINAPI 140 LocalXcvData(HANDLE hXcv, const WCHAR* pszDataName, BYTE* pInputData, DWORD cbInputData, BYTE* pOutputData, DWORD cbOutputData, DWORD* pcbOutputNeeded, DWORD* pdwStatus) 141 { 142 DWORD res; 143 PLOCAL_PRINT_MONITOR pPrintMonitor; 144 PLOCAL_XCV_HANDLE pXcv; 145 PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hXcv; 146 147 FIXME("LocalXcvData(%p, %S, %p, %lu, %p, %lu, %p)\n", hXcv, pszDataName, pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded); 148 149 // Sanity checks 150 if (!pszDataName) 151 { 152 res = ERROR_INVALID_PARAMETER; 153 goto Cleanup; 154 } 155 156 // Call the appropriate handler for the requested data name. 157 if (wcscmp(pszDataName, L"AddPort") == 0) 158 return _HandleAddPort(hXcv, pInputData, pcbOutputNeeded, pdwStatus); 159 160 if (wcscmp(pszDataName, L"DeletePort") == 0) 161 return _HandleDeletePort(hXcv, pInputData, pcbOutputNeeded, pdwStatus); 162 163 // 164 // After the two Intercept Handlers, defer call back to Monitor. 165 // 166 167 // Check if this is a printer handle. 168 if (pHandle->HandleType != HandleType_Xcv) 169 { 170 ERR("LocalXcvData : Invalid XCV Handle\n"); 171 res = ERROR_INVALID_HANDLE; 172 goto Cleanup; 173 } 174 175 pXcv = (PLOCAL_XCV_HANDLE)pHandle->pSpecificHandle; 176 177 pPrintMonitor = pXcv->pPrintMonitor; 178 if (!pPrintMonitor ) 179 { 180 res = ERROR_INVALID_PARAMETER; 181 goto Cleanup; 182 } 183 184 pPrintMonitor->refcount++; 185 if ( pPrintMonitor->bIsLevel2 && ((PMONITOR2)pPrintMonitor->pMonitor)->pfnXcvDataPort ) 186 { 187 res = ((PMONITOR2)pPrintMonitor->pMonitor)->pfnXcvDataPort(pXcv->hXcv, pszDataName, pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded); 188 } 189 else if ( !pPrintMonitor->bIsLevel2 && ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnXcvDataPort ) 190 { 191 res = ((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnXcvDataPort(pXcv->hXcv, pszDataName, pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded); 192 } 193 pPrintMonitor->refcount--; 194 195 Cleanup: 196 SetLastError(res); 197 if (pdwStatus) *pdwStatus = res; 198 return res; 199 } 200