397 lines
9.5 KiB
C++
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
|