windows-nt/Source/XPSP1/NT/printscan/print/spooler/inetpp2/server/xcv.cxx
2020-09-26 16:20:57 +08:00

397 lines
9.5 KiB
C++

/*****************************************************************************\
* 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