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

876 lines
25 KiB
C++

/*****************************************************************************\
* MODULE: msw3prt.cxx
*
* The module contains routines to implement the ISAPI interface.
*
* PURPOSE Windows HTTP/HTML printer interface
*
* Copyright (C) 1996-1997 Microsoft Corporation
*
* History:
* 01/16/96 eriksn Created based on ISAPI sample DLL
* 07/15/96 babakj Ported to NT
* 02/04/97 weihaic Enabled Unicode mode
*
\*****************************************************************************/
#include "pch.h"
/*****************************************************************************\
* GetClientInfo
*
* Returns a DWORD representation of the client architecture/ver information.
*
\*****************************************************************************/
DWORD GetClientInfo(
PALLINFO pAllInfo)
{
DWORD dwCliInfo = 0;
LPSTR lpszPtr;
if (pAllInfo->pECB->cbAvailable) {
if (lpszPtr = (LPSTR)pAllInfo->pECB->lpbData) {
while (*lpszPtr && (*lpszPtr != '='))
lpszPtr++;
if (*lpszPtr)
dwCliInfo = atoi(++lpszPtr);
}
} else {
if (lpszPtr = pAllInfo->pECB->lpszQueryString) {
while (*lpszPtr && (*lpszPtr != '&'))
lpszPtr++;
if (*lpszPtr)
dwCliInfo = atoi(++lpszPtr);
}
}
return dwCliInfo;
}
/*****************************************************************************\
* GetIppReq
*
* Returns the request-type of the IPP-stream.
*
\*****************************************************************************/
WORD GetIppReq(
PALLINFO pAllInfo)
{
LPWORD pwPtr;
WORD wValue = 0;
if (pAllInfo->pECB->cbAvailable >= sizeof(DWORD)) {
if (pwPtr = (LPWORD)pAllInfo->pECB->lpbData) {
CopyMemory (&wValue, pwPtr + 1, sizeof (WORD));
return ntohs(wValue);
}
}
return 0;
}
/*****************************************************************************\
* IsSecureReq
*
* Returns whether the request comes from a secure https channel.
*
\*****************************************************************************/
BOOL IsSecureReq(
EXTENSION_CONTROL_BLOCK *pECB)
{
BOOL bRet;
DWORD cbBuf;
CHAR szBuf[10];
cbBuf = 10;
bRet = pECB->GetServerVariable(pECB->ConnID,
"HTTPS",
&szBuf,
&cbBuf);
if (bRet && (cbBuf <= 4)) {
if (lstrcmpiA(szBuf, "on") == 0)
return TRUE;
}
return FALSE;
}
/*****************************************************************************\
* GetPrinterName
*
* Get the printer name from the path
*
\*****************************************************************************/
LPTSTR GetPrinterName (LPTSTR lpszPathInfo)
{
// The only format we support is "/printers/ShareName|Encoded Printer Name/.printer"
static TCHAR szPrinter[] = TEXT ("/.printer");
static TCHAR szPrinters[] = TEXT ("/printers/");
LPTSTR lpPtr = NULL;
LPTSTR lpPathInfo = NULL;
LPTSTR lpPrinterName = NULL;
LPTSTR lpSuffix = NULL;
DWORD dwLen;
// Make a copy of lpszPathInfo
if (! (lpPathInfo = lpPtr = AllocStr (lpszPathInfo)))
return NULL;
// Verify the prefix
if (_tcsnicmp (lpPathInfo, szPrinters, COUNTOF (szPrinters) - 1)) {
goto Cleanup;
}
lpPathInfo += COUNTOF (szPrinters) - 1;
dwLen = lstrlen (lpPathInfo);
// Compare the length of the printer name with .printer suffix
if (dwLen <= COUNTOF (szPrinter) - 1) {
goto Cleanup;
}
lpSuffix = lpPathInfo + dwLen - COUNTOF (szPrinter) + 1;
//lpszStr should point to .printer
// Verify the suffix.
if (lstrcmpi(lpSuffix, szPrinter)) {
goto Cleanup;
}
*lpSuffix = TEXT('\0'); // Terminate string
lpPrinterName = AllocStr (lpPathInfo);
Cleanup:
LocalFree(lpPtr);
return lpPrinterName;
}
/*****************************************************************************\
* DllMain
*
*
\*****************************************************************************/
BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason,
LPVOID lpvReserved)
{
BOOL bRet = TRUE;
if (fdwReason == DLL_PROCESS_ATTACH)
{
g_hInstance = hinstDLL;
// Init debug support in spllib.lib
bSplLibInit( NULL );
__try {
InitializeCriticalSection(&SplCritSect);
InitializeCriticalSection(&TagCritSect);
// Initialize the CAB generation crit-sect for web-pnp.
//
InitCABCrit();
}
__except (1) {
bRet = FALSE;
SetLastError (ERROR_INVALID_HANDLE);
}
if (bRet) {
// Initializa the sleeper, which is used to cleanup the pritner jobs
InitSleeper ();
// We don't care about fdwReason==DLL_THREAD_ATTACH or _DETACH
DisableThreadLibraryCalls(hinstDLL);
srand( (UINT)time( NULL ) );
}
}
if (fdwReason == DLL_PROCESS_DETACH)
{
// Terminate the additional cleanup thread
ExitSleeper ();
DeleteCriticalSection(&SplCritSect);
DeleteCriticalSection(&TagCritSect);
// Free our web-pnp crit-sect.
//
FreeCABCrit();
// Free debug support in spllib.lib
vSplLibFree();
}
// Do any other required initialize/deinitialize here.
return bRet;
}
/*****************************************************************************\
* GetExtensionVersion
*
* Required ISAPI export function.
*
\*****************************************************************************/
BOOL WINAPI GetExtensionVersion(
HSE_VERSION_INFO *pVer)
{
pVer->dwExtensionVersion = MAKELONG( HSE_VERSION_MINOR, HSE_VERSION_MAJOR );
TCHAR szBuf[80];
szBuf[0] = TEXT('\0');
LoadString(g_hInstance, IDS_ISAPI_DESCRIPTION, szBuf, sizeof(szBuf) / sizeof (TCHAR));
// Convert szBuf to ANSI
// Weihaic
if (UnicodeToAnsiString (szBuf, (LPSTR) szBuf, NULL)) {
lstrcpynA( pVer->lpszExtensionDesc, (LPSTR) szBuf,
HSE_MAX_EXT_DLL_NAME_LEN );
return TRUE;
}
else
return FALSE;
} // GetExtensionVersion()
/*****************************************************************************\
* GetServerName
*
* Get the server name and convert it to the unicode string.
*
\*****************************************************************************/
BOOL GetServerName (EXTENSION_CONTROL_BLOCK *pECB)
{
static char c_szServerName[] = "SERVER_NAME";
DWORD dwSize;
char szAnsiHttpServerName[INTERNET_MAX_HOST_NAME_LENGTH + 1];
BOOL bRet = FALSE;
DWORD dwClusterState;
BOOL bCluster = FALSE;
dwSize = sizeof (szAnsiHttpServerName);
if (pECB->GetServerVariable (pECB->ConnID, c_szServerName, szAnsiHttpServerName, &dwSize)) {
AnsiToUnicodeString(szAnsiHttpServerName, g_szHttpServerName, 0);
// Now, the computer name becomes the server name. In case of the intranet, it is the computer
// name, in case of internet, it is either the IP address or the DNS name
if (!lstrcmpi (g_szHttpServerName, TEXT ("localhost")) ||
!lstrcmpi (g_szHttpServerName, TEXT ("127.0.0.1"))) {
dwSize = ARRAY_COUNT (g_szHttpServerName);
bRet = GetComputerName( g_szHttpServerName, &dwSize);
}
else
bRet = TRUE;
}
if (bRet) {
bRet = FALSE;
// Now let's get the printer server name
//
// Check if we are running in a cluster node
//
if (GetNodeClusterState (NULL, &dwClusterState) == ERROR_SUCCESS &&
(dwClusterState & ClusterStateRunning)) {
bCluster = TRUE;
}
//
// If we are running in the cluster mode, we have to use the ServerName referred in the HTTP header.
// Otherwise, we can use the computer name directly.
//
if (bCluster) {
lstrcpy (g_szPrintServerName, g_szHttpServerName);
bRet = TRUE;
}
else {
dwSize = ARRAY_COUNT (g_szPrintServerName);
bRet = GetComputerName( g_szPrintServerName, &dwSize);
}
}
return bRet;
}
/*****************************************************************************\
* ParseQueryString
*
* ParseQueryString converts the query string into a sequence of arguments.
* The main command is converted to a command ID. Subsequent arguments are
* converted to strings or DWORDs.
*
* Format: Command & Arg1 & Arg2 & Arg3 ...
* Each arg is either a number or a string in quotes.
*
* returns FALSE if the query string exists but is invalid
*
\*****************************************************************************/
BOOL ParseQueryString(PALLINFO pAllInfo)
{
LPTSTR pszQueryString, pszTmp, pszTmp2, pszTmp3;
int iNumArgs = 0;
pszQueryString = pAllInfo->lpszQueryString;
if (!pszQueryString || (*pszQueryString == 0)) {
// Chceck if the method is post
if (!lstrcmp (pAllInfo->lpszMethod, TEXT ("POST"))) {
// also check here for content-type application/ipp ???
//
pAllInfo->iQueryCommand = CMD_IPP; // can we use the NULL cmd ???
}
else {
pAllInfo->iQueryCommand = CMD_WebUI; // redirect to webui
}
return TRUE;
}
// Get a copy of the string to do surgery on it in this routine and save pieces of it as other info.
// Save it too so it can be freed later.
// This line is bogus. 1. It leads to a memory leak. To, it can fail and the
// return value is unchecked.....
pszQueryString = AllocStr ( pszQueryString );
if (pszQueryString != NULL) {
// We will find and replace the first '&' with NULL. This it to isolate the first
// piece of the query string and examine it.
// pszQueryString then points to this first piece (command), pszTmp to the rest.
if( pszTmp = _tcschr( pszQueryString, TEXT('&'))) {
*pszTmp = TEXT('\0');
pszTmp++;
}
// Search for main command
pAllInfo->iQueryCommand = CMD_Invalid;
// If we had {WinPrint.PrinterCommandURL}?/myfile.htm&bla1&bla2&bla3.....
// or {WinPrint.PrinterCommandURL}?/bla1/bla2/.../blaN/myfile.htm&aaa&bbb&ccc...
// then pszQueryString is pointing to a NULL we inserted in place of '/', so it is OK.
// So just attempt to find a iQueryCommand only if pszQueryString is pointing to a non-NULL char.
if( *pszQueryString ) {
for (int i=0; i<iNumQueryMap; i++) {
if (!lstrcmpi(rgQueryMap[i].pszCommand, pszQueryString)) {
pAllInfo->iQueryCommand = rgQueryMap[i].iCommandID;
break;
}
}
if( pAllInfo->iQueryCommand == CMD_Invalid )
return FALSE; // No command found. Bad query string.
}
// At this point we continue with pszTmp for the arguments.
// We take at most MAX_Q_ARG arguments to avoid memory corruption
while( (NULL != pszTmp) && (*pszTmp) && iNumArgs < MAX_Q_ARG) {
pszTmp2 = pszTmp;
pszTmp = _tcschr( pszTmp, TEXT('&'));
if (pszTmp != NULL) {
*pszTmp = 0;
pszTmp ++;
}
if (*pszTmp2 >= TEXT('0') && *pszTmp2 <= TEXT('9')) {
// DWORD integer value
pAllInfo->fQueryArgIsNum[iNumArgs] = TRUE;
pAllInfo->QueryArgValue[iNumArgs] = (DWORD)_ttoi(pszTmp2);
}
else {
// Pointer to string
pAllInfo->fQueryArgIsNum[iNumArgs] = FALSE;
pAllInfo->QueryArgValue[iNumArgs] = (UINT_PTR)pszTmp2;
}
iNumArgs ++;
}
pAllInfo->iNumQueryArgs = iNumArgs;
DBGMSG(DBG_INFO, ("ParseQueryString: %d query arguments\r\n", iNumArgs));
LocalFree( pszQueryString );
return TRUE;
}
return FALSE;
}
#if 0
/*****************************************************************************\
* ParsePathInfo
*
* Take the PATH_INFO string and figure out what to do with it.
*
\*****************************************************************************/
DWORD ParsePathInfo(PALLINFO pAllInfo)
{
// The only format we support is "/ShareName|Encoded Printer Name/.printer"
static TCHAR szPrinter[] = TEXT ("/.printer");
DWORD dwRet = HSE_STATUS_ERROR;
LPTSTR lpPtr = NULL;
LPTSTR lpszStr;
LPTSTR lpPrinterName = NULL;
DWORD dwLen;
// Make a copy of lpszPathInfo
if (! (lpPrinterName = lpPtr = AllocStr (pAllInfo->lpszPathInfo)))
return HSE_STATUS_ERROR;
// First remove the "/" prefix
if (*lpPrinterName++ != TEXT ('/') ) {
goto Cleanup;
}
dwLen = lstrlen (lpPrinterName);
// Compare the length of the printer name with .printer suffix
if (dwLen <= COUNTOF (szPrinter) - 1) {
goto Cleanup;
}
lpszStr = lpPrinterName + dwLen - COUNTOF (szPrinter) + 1;
//lpszStr should point to .printer
// Verify the suffix.
if (lstrcmpi(lpszStr, TEXT("/.printer"))) {
goto Cleanup;
}
*lpszStr = TEXT('\0'); // Terminate string
if( !ParseQueryString( pAllInfo ))
goto Cleanup;
dwRet = ShowPrinterPage(pAllInfo, lpPrinterName);
Cleanup:
LocalFree(lpPtr);
return dwRet;
}
#endif
/*****************************************************************************\
* CreateExe
*
*
\*****************************************************************************/
DWORD CreateExe(PALLINFO pAllInfo, PPRINTERPAGEINFO pPageInfo, DWORD dwCliInfo)
{
LPTSTR lpPortName = NULL;
LPTSTR lpExeName = NULL;
LPTSTR lpFriendlyName = NULL;
DWORD dwRet = HSE_STATUS_ERROR ;
DWORD dwLen = 0;
DWORD dwLastError = ERROR_INVALID_DATA;
BOOL bSecure = IsSecureReq (pAllInfo->pECB);
GetWebpnpUrl (g_szHttpServerName, pPageInfo->pPrinterInfo->pShareName, NULL, bSecure, NULL, &dwLen);
if (GetLastError () != ERROR_INSUFFICIENT_BUFFER)
goto Cleanup;
if (! (lpPortName = (LPTSTR)LocalAlloc(LPTR, dwLen * sizeof (*lpPortName))))
goto Cleanup;
if (!GetWebpnpUrl (g_szHttpServerName, pPageInfo->pPrinterInfo->pShareName, NULL, bSecure, lpPortName, &dwLen))
goto Cleanup;
lpExeName = (LPTSTR)LocalAlloc(LPTR, MAX_PATH * sizeof (*lpExeName));
if (!lpExeName)
goto Cleanup;
lpFriendlyName = (LPTSTR)LocalAlloc(LPTR, (lstrlen(pPageInfo->pszFriendlyName)+1) * sizeof (*lpFriendlyName));
if (!lpFriendlyName)
goto Cleanup;
lstrcpy(lpFriendlyName, pPageInfo->pszFriendlyName);
dwRet = GenerateCAB(lpFriendlyName,
lpPortName,
dwCliInfo,
lpExeName,
IsSecureReq(pAllInfo->pECB));
if (dwRet == HSE_STATUS_SUCCESS) {
LPTSTR lpEncodedExeName = EncodeString (lpExeName, TRUE);
if (!lpEncodedExeName) {
dwRet = HSE_STATUS_ERROR;
goto Cleanup;
}
htmlSendRedirect (pAllInfo, lpEncodedExeName);
LocalFree (lpEncodedExeName);
}
else {
dwLastError = GetLastError ();
if (dwLastError == ERROR_FILE_NOT_FOUND) {
dwLastError = ERROR_DRIVER_NOT_FOUND;
}
if (dwLastError == ERROR_DISK_FULL) {
dwLastError = ERROR_SERVER_DISK_FULL;
}
}
Cleanup:
LocalFree(lpPortName);
LocalFree(lpExeName);
LocalFree(lpFriendlyName);
if (dwRet != HSE_STATUS_SUCCESS)
return ProcessErrorMessage (pAllInfo, dwLastError);
else
return dwRet;
}
/*****************************************************************************\
* ProcessRequest
*
* Process the incoming request
*
\*****************************************************************************/
DWORD ProcessRequest(PALLINFO pAllInfo, LPTSTR lpszPrinterName)
{
DWORD dwRet = HSE_STATUS_ERROR;
PPRINTER_INFO_2 pPrinterInfo = NULL;
HANDLE hPrinter = NULL;
DWORD iQueryCommand;
LPTSTR lpszFriendlyName;
DWORD dwCliInfo;
WORD wIppReq = 0;
LPTSTR pszDecodedName = NULL;
DWORD dwSize = 0;
PRINTER_DEFAULTS pd = {NULL, NULL, PRINTER_ACCESS_USE};
LPTSTR lpszWebUIUrl = NULL;
LPTSTR pszOpenName = NULL;
LPTSTR pszTmpName = NULL;
iQueryCommand = pAllInfo->iQueryCommand;
DBGMSG(DBG_INFO, ("ShowPrinterPage for printer \"%ws\"\n", lpszPrinterName));
// Open the printer and get printer info level 2.
DecodePrinterName (lpszPrinterName, NULL, &dwSize);
if (! (pszDecodedName = (LPTSTR) LocalAlloc (LPTR, sizeof (TCHAR) * dwSize)))
return ProcessErrorMessage (pAllInfo, GetLastError ());
if (!DecodePrinterName (lpszPrinterName, pszDecodedName, &dwSize)) {
dwRet = ProcessErrorMessage (pAllInfo, GetLastError ());
goto Cleanup;
}
if (*pszDecodedName != TEXT ('\\') ) {
// There is no server name before the printer name, append the server name
if (! (pszOpenName = pszTmpName = (LPTSTR) LocalAlloc (LPTR, sizeof (TCHAR) * (lstrlen (pszDecodedName)
+ lstrlen (g_szPrintServerName) + 4 ))))
goto Cleanup;
lstrcpy (pszOpenName, TEXT ("\\\\"));
lstrcat (pszOpenName, g_szPrintServerName);
lstrcat (pszOpenName, TEXT ("\\"));
lstrcat (pszOpenName, pszDecodedName);
}
else {
pszOpenName = pszDecodedName;
}
if (! OpenPrinter(pszOpenName, &hPrinter, &pd)) {
dwRet = ProcessErrorMessage (pAllInfo, GetLastError ());
goto Cleanup;
}
// Get a PRINTER_INFO_2 structure filled up
dwSize = 0;
GetPrinter(hPrinter, 2, NULL, 0, &dwSize);
if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
(NULL == (pPrinterInfo = (PPRINTER_INFO_2)LocalAlloc(LPTR, dwSize))) ||
(!GetPrinter(hPrinter, 2, (byte *)pPrinterInfo, dwSize, &dwSize))) {
dwRet = ProcessErrorMessage (pAllInfo, GetLastError ());
goto Cleanup;
}
if (! (pPrinterInfo->Attributes & PRINTER_ATTRIBUTE_SHARED)) {
// If the printer is not shared, return access denied
dwRet = ProcessErrorMessage (pAllInfo, ERROR_ACCESS_DENIED);
goto Cleanup;
}
// Find printer friendly name.
// If we opened with UNC path we need to remove server name
if (pPrinterInfo->pPrinterName) {
lpszFriendlyName = _tcsrchr (pPrinterInfo->pPrinterName, TEXT('\\'));
if (lpszFriendlyName)
lpszFriendlyName ++;
else
lpszFriendlyName = pPrinterInfo->pPrinterName;
}
// We've got an open printer and some printer info. Ready to go.
// Fill in structure of info for whatever function we call
PRINTERPAGEINFO ppi;
ZeroMemory(&ppi, sizeof(ppi));
ppi.pszFriendlyName = lpszFriendlyName;
ppi.pPrinterInfo = pPrinterInfo;
ppi.hPrinter = hPrinter;
// Do appropriate action based on query string
switch (iQueryCommand) {
case CMD_WebUI:
// Construct a URL to redirect
dwSize = 0;
if (GetWebUIUrl (NULL, pszDecodedName, lpszWebUIUrl, &dwSize))
goto Cleanup;
if (GetLastError () != ERROR_INSUFFICIENT_BUFFER)
goto Cleanup;
if (!(lpszWebUIUrl = (LPTSTR)LocalAlloc(LPTR, dwSize * sizeof (TCHAR))))
goto Cleanup;
if (! GetWebUIUrl (NULL, pszDecodedName, lpszWebUIUrl, &dwSize))
goto Cleanup;
dwRet = htmlSendRedirect (pAllInfo, lpszWebUIUrl);
break;
case CMD_IPP:
if (wIppReq = GetIppReq(pAllInfo)) {
dwRet = SplIppJob(wIppReq, pAllInfo, &ppi);
} else {
DBGMSG(DBG_WARN, ("ShowPrinterPage: Warn : Invalid IPP Stream.\n"));
if (IsClientHttpProvider (pAllInfo)){
// To improve the perfomance for the internet provider by returning something really quick
LPTSTR pszContent = GetString(pAllInfo, IDS_ERROR_200CONTENT);
htmlSendHeader (pAllInfo, TEXT ("200 OK"), pszContent);
dwRet = HSE_STATUS_SUCCESS;
}
if (INVALID_HANDLE_VALUE != hPrinter)
ClosePrinter(hPrinter);
break;
}
break;
case CMD_CreateExe:
DBGMSG(DBG_TRACE, ("Calling CreateExe.\n"));
if (dwCliInfo = GetClientInfo(pAllInfo)) {
dwRet = CreateExe(pAllInfo, &ppi, dwCliInfo);
} else {
dwRet = ProcessErrorMessage (pAllInfo, ERROR_NOT_SUPPORTED);
goto Cleanup;
}
break;
default:
dwRet = ProcessErrorMessage (pAllInfo, ERROR_INVALID_PRINTER_COMMAND);
break;
}
Cleanup:
// Clean up our stuff
if (dwRet != HSE_STATUS_ERROR)
pAllInfo->pECB->dwHttpStatusCode=200; // 200 OK
LocalFree (lpszWebUIUrl);
LocalFree (pszDecodedName);
LocalFree (pszTmpName);
LocalFree (pPrinterInfo);
// For any commands other than CMD_IPP commands, we can close the
// printer-handle. Otherwise, we rely on the Spool*() routines
// to handle this for us after we're done reading and processing
// the entire print-job.
//
if (hPrinter && (iQueryCommand != CMD_IPP))
ClosePrinter(hPrinter);
return dwRet;
}
/*****************************************************************************\
* GetString
*
*
\*****************************************************************************/
LPTSTR GetString(PALLINFO pAllInfo, UINT iStringID)
{
LPTSTR lpszBuf = pAllInfo->szStringBuf;
lpszBuf[0] = TEXT('\0');
LoadString(g_hInstance, iStringID, lpszBuf, STRBUFSIZE);
SPLASSERT(lpszBuf[0] != TEXT('\0'));
return lpszBuf;
}
/*****************************************************************************\
* HttpExtensionProc
*
* Main entrypoint for HTML generation.
*
\*****************************************************************************/
DWORD WINAPI HttpExtensionProc(
EXTENSION_CONTROL_BLOCK *pECB)
{
DWORD dwRet = HSE_STATUS_ERROR;
PALLINFO pAllInfo = NULL; // This structure contains all relevant info for this connection
LPTSTR pPrinterName = NULL;
// Assume failure
if(!pECB) return HSE_STATUS_ERROR;
pECB->dwHttpStatusCode = HTTP_STATUS_NOT_SUPPORTED;
// Get the server name and convert it to the unicode string.
if (!GetServerName (pECB))
return HSE_STATUS_ERROR;
if (!(pAllInfo = (PALLINFO) LocalAlloc (LPTR, sizeof (ALLINFO))))
return HSE_STATUS_ERROR;
// Initialize pAllInfo
ZeroMemory(pAllInfo, sizeof(ALLINFO));
pAllInfo->pECB = pECB;
// Convert the ANSI string in ECB to Unicode
// weihaic
// pAllInfo->lpszQueryString = AllocateUnicodeString(DecodeStringA (pECB->lpszQueryString));
// We can not decode now becuase the decoded string will bring troubles in parsing
//
pAllInfo->lpszQueryString = AllocateUnicodeString(pECB->lpszQueryString);
pAllInfo->lpszMethod = AllocateUnicodeString(pECB->lpszMethod);
pAllInfo->lpszPathInfo = AllocateUnicodeString(pECB->lpszPathInfo);
pAllInfo->lpszPathTranslated = AllocateUnicodeString(pECB->lpszPathTranslated);
if (!pAllInfo->lpszQueryString ||
!pAllInfo->lpszMethod ||
!pAllInfo->lpszPathInfo ||
!pAllInfo->lpszPathTranslated ) {
goto Cleanup;
}
// weihaic
// The query string contain user entered text such as printer location
// priner description, etc. These strings are case sensitive, so we
// could not convert them to upper case at the very beginning
// CharUpper (pAllInfo->lpszQueryString);
//
CharUpper (pAllInfo->lpszMethod);
CharUpper (pAllInfo->lpszPathInfo);
CharUpper (pAllInfo->lpszPathTranslated);
if (! (pPrinterName = GetPrinterName (pAllInfo->lpszPathInfo))) {
// This is a wrong URL, return error code
dwRet = ProcessErrorMessage (pAllInfo, ERROR_INVALID_DATA);
goto Cleanup;
}
if (! ParseQueryString (pAllInfo))
goto Cleanup;
dwRet = ProcessRequest (pAllInfo, pPrinterName); // We always hit Cleanup anyway
//dwRet = ParsePathInfo(pAllInfo);
#if 0
if (dwRet == HSE_STATUS_ERROR) {
LPTSTR pszErrorContent = GetString(pAllInfo, IDS_ERROR_501CONTENT);
LPSTR pszAnsiErrorContent = (LPSTR)pszErrorContent;
UnicodeToAnsiString(pszErrorContent, pszAnsiErrorContent, 0);
DWORD dwSize = strlen (pszAnsiErrorContent);
pECB->ServerSupportFunction(pECB->ConnID,
HSE_REQ_SEND_RESPONSE_HEADER,
"501 Function not supported",
&dwSize,
(LPDWORD) pszAnsiErrorContent);
}
#endif
Cleanup:
LocalFree (pPrinterName);
LocalFree (pAllInfo->lpszQueryString);
LocalFree (pAllInfo->lpszMethod);
LocalFree (pAllInfo->lpszPathInfo);
LocalFree (pAllInfo->lpszPathTranslated);
LocalFree (pAllInfo);
return dwRet;
} // HttpExtensionProc()