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