/*****************************************************************************\ * MODULE: xcv.cxx * * The module contains routines for handling the authentication dialog * for internet priting * * Copyright (C) 2000 Microsoft Corporation * * History: * 03/31/00 WeihaiC Created * \*****************************************************************************/ #include "precomp.h" #ifdef WINNT32 #include "priv.h" #define SZINETPPUI L"InetppUI.dll" XCV_METHOD gpXcvMethod[] = { {L"MonitorUI", GetMonitorUI}, {L"AddPort", DoAddPort}, {INET_XCV_DELETE_PORT, DoDeletePort}, {INET_XCV_GET_CONFIGURATION, DoGetConfiguration}, {INET_XCV_SET_CONFIGURATION, DoSetConfiguration}, {NULL, NULL} }; BOOL bIsAdmin () { PRINTER_DEFAULTS pd = {NULL, NULL, SERVER_ALL_ACCESS}; HANDLE hServer; BOOL bRet = FALSE; if (OpenPrinter (NULL, &hServer, &pd)) { bRet = TRUE; ClosePrinter (hServer); } return bRet; } DWORD XcvDataPort( PCINETMONPORT pPort, LPCWSTR pszDataName, PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded ) { DWORD dwRet; DWORD i; for(i = 0 ; gpXcvMethod[i].pszMethod && wcscmp(gpXcvMethod[i].pszMethod, pszDataName) ; ++i) ; if (gpXcvMethod[i].pszMethod) { dwRet = (*gpXcvMethod[i].pfn)( pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded, pPort); } else { dwRet = ERROR_INVALID_PARAMETER; } return dwRet; } BOOL PPXcvData( HANDLE hXcv, LPCWSTR pszDataName, PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded, PDWORD pdwStatus) { HANDLE hPort; LPTSTR pszPortName; // // Valid input parameters // if (!pszDataName || IsBadStringPtr (pszDataName, MAX_INET_XCV_NAME_LEN) || IsBadWritePtr (pdwStatus, sizeof (DWORD))) { return ERROR_INVALID_PARAMETER; } DBG_MSG(DBG_LEV_CALLTREE, (TEXT("Call: PPXcvData: Name(%s)"), pszDataName)); semEnterCrit(); if (pszPortName = utlValidateXcvPrinterHandle(hXcv)) { if (hPort = gpInetMon->InetmonFindPort (pszPortName)) { *pdwStatus = XcvDataPort((PCINETMONPORT) hPort, pszDataName, pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded); } else { // // The port may not exit or have been deleted. // *pdwStatus = ERROR_NOT_FOUND; } } else *pdwStatus = ERROR_INVALID_HANDLE; semLeaveCrit(); DBG_MSG(DBG_LEV_CALLTREE, (TEXT("Call: PPXcvData : Return Value(%d), LastError(%d)"), *pdwStatus, GetLastError())); return TRUE; } DWORD ValidateInputParameters ( PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded, CONST DWORD cdwInputDataRequired, CONST DWORD cdwOutputDataRequired) { if (!pInputData || !pcbOutputNeeded || (cdwInputDataRequired > 0 && cbInputData != cdwInputDataRequired) || IsBadReadPtr (pInputData, cbInputData) || (pOutputData && cbOutputData && IsBadWritePtr (pOutputData, cbOutputData)) || (pcbOutputNeeded && IsBadWritePtr (pcbOutputNeeded, sizeof (DWORD)))) { return ERROR_INVALID_PARAMETER; } if (cbOutputData < cdwOutputDataRequired) { *pcbOutputNeeded = cdwOutputDataRequired; return ERROR_INSUFFICIENT_BUFFER; } return ERROR_SUCCESS; } DWORD DoGetConfiguration( PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded, PCINETMONPORT pPort ) { PINET_XCV_GETCONFIGURATION_REQ_DATA pReqData = (PINET_XCV_GETCONFIGURATION_REQ_DATA) pInputData; PBYTE pEncryptedData = NULL; DWORD dwEncryptedDataSize; DWORD dwRet; // // Valid input parameters // dwRet = ValidateInputParameters (pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded, sizeof (INET_XCV_GETCONFIGURATION_REQ_DATA), 0); if (dwRet != ERROR_SUCCESS) { return dwRet; } if (pReqData->dwVersion != 1) { return ERROR_INVALID_PARAMETER; } // // Get Current Configuration // INET_XCV_CONFIGURATION ConfigData; if (pPort->GetCurrentConfiguration (&ConfigData)) { if (EncryptData ((PBYTE) &ConfigData, sizeof (INET_XCV_CONFIGURATION), &pEncryptedData, &dwEncryptedDataSize)) { if (cbOutputData < dwEncryptedDataSize) { *pcbOutputNeeded = dwEncryptedDataSize; dwRet = ERROR_INSUFFICIENT_BUFFER; } else { CopyMemory (pOutputData, pEncryptedData, dwEncryptedDataSize); *pcbOutputNeeded = dwEncryptedDataSize; dwRet = ERROR_SUCCESS; } LocalFree (pEncryptedData); } else dwRet = GetLastError (); } else dwRet = GetLastError (); return dwRet; } DWORD DoSetConfiguration( PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded, PCINETMONPORT pPort ) { PINET_XCV_CONFIGURATION pReqData; DWORD dwRet; PBYTE pDecryptedData; DWORD dwDecryptedDataSize; if (DecryptData (pInputData, cbInputData, &pDecryptedData, &dwDecryptedDataSize)) { // // Valid input parameters // dwRet = ValidateInputParameters (pDecryptedData, dwDecryptedDataSize, pOutputData, cbOutputData, pcbOutputNeeded, sizeof (INET_XCV_CONFIGURATION), sizeof (INET_CONFIGUREPORT_RESPDATA)); if (dwRet == ERROR_SUCCESS) { pReqData = (PINET_XCV_CONFIGURATION) pDecryptedData; if (pReqData->dwVersion != 1) { dwRet = ERROR_INVALID_PARAMETER; } else if (pReqData->bSettingForAll && !bIsAdmin ()) { // // If the setting is for per-port, but the caller is not an admin // dwRet = ERROR_ACCESS_DENIED; } else { // // We need to leave critical section before changing configurations, // before leaving critical section, we need to increase the ref count // so that other people won't delete it // semSafeLeaveCrit (pPort); // // Get Current Configuration // if (pPort->ConfigurePort (pReqData, (PINET_CONFIGUREPORT_RESPDATA) pOutputData, cbOutputData, pcbOutputNeeded)) dwRet = ERROR_SUCCESS; else dwRet = GetLastError (); semSafeEnterCrit (pPort); } } LocalFree (pDecryptedData); } else dwRet = GetLastError (); return dwRet; } DWORD DoDeletePort( PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded, PCINETMONPORT pPort ) { DWORD dwRet = ERROR_SUCCESS; DWORD cbNeeded, dwStatus; BOOL bRet = FALSE; dwRet = ValidateInputParameters (pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded, 0, 0); if (dwRet != ERROR_SUCCESS) { return dwRet; } if (IsBadStringPtr ((LPWSTR) pInputData, cbInputData / sizeof (WCHAR))) return ERROR_INVALID_PARAMETER; if (bIsAdmin ()) { if (!PPDeletePort (NULL, NULL, (LPWSTR) pInputData)) { dwRet = GetLastError (); } } else dwRet = ERROR_ACCESS_DENIED; return dwRet; } DWORD DoAddPort( PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded, PCINETMONPORT pPort ) { // // We don't support AddPort // return ERROR_ACCESS_DENIED; } DWORD GetMonitorUI( PBYTE pInputData, DWORD cbInputData, PBYTE pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded, PCINETMONPORT pPort ) { DWORD dwRet; *pcbOutputNeeded = sizeof( SZINETPPUI ); if (cbOutputData < *pcbOutputNeeded) { dwRet = ERROR_INSUFFICIENT_BUFFER; } else { wcscpy((PWSTR) pOutputData, SZINETPPUI); dwRet = ERROR_SUCCESS; } return dwRet; } #endif