344 lines
9.4 KiB
C++
344 lines
9.4 KiB
C++
|
|
/*****************************************************************************\
|
|
* MODULE: custom.cpp
|
|
*
|
|
* PURPOSE: OEM Customization support
|
|
*
|
|
* Copyright (C) 1997-1998 Microsoft Corporation
|
|
*
|
|
* History:
|
|
*
|
|
* 10/10/97 babakj Created
|
|
*
|
|
\*****************************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
#include "oleprn.h"
|
|
#include "asphelp.h"
|
|
|
|
|
|
TCHAR cszEverestVirRoot[] = TEXT("\\web\\printers");
|
|
TCHAR cszManufacturerKey[] = TEXT("PnPData");
|
|
TCHAR cszManufacturerValue[] = TEXT("Manufacturer");
|
|
|
|
#define DEFAULTASPPAGE TEXT("Page1.asp")
|
|
|
|
|
|
//
|
|
// Caller allocs memory for pMonitorname.
|
|
//
|
|
// pMonitorName untouched if failure.
|
|
//
|
|
BOOL Casphelp::GetMonitorName( LPTSTR pMonitorName )
|
|
{
|
|
PPORT_INFO_2 pPortInfo2 = NULL;
|
|
BOOL fRet = FALSE;
|
|
DWORD dwNeeded, dwReturned;
|
|
|
|
|
|
// Now get all ports to find a match from.
|
|
LPTSTR lpszServerName = m_pInfo2 ? m_pInfo2->pServerName : NULL;
|
|
|
|
if( EnumPorts(lpszServerName, 2, NULL, 0, &dwNeeded, &dwReturned) ||
|
|
(GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
|
|
(NULL == (pPortInfo2 = (PPORT_INFO_2)LocalAlloc( LPTR, dwNeeded))) ||
|
|
(!EnumPorts( lpszServerName , 2, (LPBYTE)pPortInfo2, dwNeeded, &dwNeeded, &dwReturned ))) {
|
|
|
|
LocalFree( pPortInfo2 );
|
|
SetAspHelpScriptingError(GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
for( DWORD i=0; i < dwReturned; i++ )
|
|
if( !lstrcmpi( pPortInfo2[i].pPortName, m_pInfo2->pPortName )) {
|
|
// Some monitors (like LPRMON) do not fill in pMonitorName, so we ignore them.
|
|
if( pPortInfo2[i].pMonitorName ) {
|
|
lstrcpy( pMonitorName, pPortInfo2[i].pMonitorName );
|
|
fRet = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
LocalFree( pPortInfo2 );
|
|
|
|
return fRet;
|
|
}
|
|
|
|
//
|
|
// Get the model name (aka driver name) of the printer
|
|
//
|
|
// Caller allocs memory for pModel.
|
|
//
|
|
BOOL Casphelp::GetModel( LPTSTR pModel )
|
|
{
|
|
if (!m_pInfo2)
|
|
{
|
|
Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
|
|
return FALSE;
|
|
}
|
|
|
|
lstrcpy( pModel, m_pInfo2->pDriverName );
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Get the Manufacturer name (aka driver name) of the printer
|
|
//
|
|
// Caller allocs memory for pManufacturer. Assumed to be the size of MAX_PATH * sizeof(TCHAR)
|
|
//
|
|
BOOL Casphelp::GetManufacturer( LPTSTR pManufacturer )
|
|
{
|
|
if (!m_hPrinter)
|
|
{
|
|
Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD dwNeeded, dwType, dwRet;
|
|
|
|
|
|
dwRet = GetPrinterDataEx( m_hPrinter,
|
|
cszManufacturerKey,
|
|
cszManufacturerValue,
|
|
&dwType,
|
|
(LPBYTE) pManufacturer,
|
|
sizeof(TCHAR) * MAX_PATH,
|
|
&dwNeeded);
|
|
|
|
if (dwRet != ERROR_SUCCESS)
|
|
{
|
|
SetAspHelpScriptingError(dwRet);
|
|
return FALSE;
|
|
}
|
|
else
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Returns:
|
|
// bDeviceASP == TRUE: The relative path to the ASP file if the printer has INF-based ASP support.
|
|
// bDeviceASP == FALSE: The relative path to the ASP file if the printer has per-manufacturer ASP support (i.e.
|
|
// ASP support just based on its manufacturer name, rather than per model.
|
|
//
|
|
// Caller allocs memory for pAspPage.
|
|
//
|
|
// - pASPPage untouched if failure.
|
|
//
|
|
BOOL Casphelp::IsCustomASP( BOOL bDeviceASP, LPTSTR pASPPage )
|
|
{
|
|
TCHAR szRelPath [MAX_PATH]; // Path relative to Winnt\web\printers, e.g. HP\LJ4si\page1.asp or .\hp (witout the .\)
|
|
TCHAR szFinalPath [MAX_PATH]; // Absolute path for szRelPath.
|
|
int nLen;
|
|
|
|
|
|
// The Printer virtual dir assumed to be winnt\web\printers. Construct it.
|
|
|
|
if( !GetWindowsDirectory( szFinalPath, COUNTOF(szFinalPath))) // Return value is the length in chars w/o null char.
|
|
return FALSE;
|
|
|
|
// Append web\printers to the end
|
|
|
|
// Fix the use of c-runtime calls later (T version, not W). Yet again, ASPHELP interface is server-side only.
|
|
nLen = wcslen(szFinalPath); // the null char not counted
|
|
wsprintf( &szFinalPath[nLen], L"%ws", cszEverestVirRoot );
|
|
|
|
|
|
// Prepare the relative path.
|
|
|
|
if( !GetManufacturer( szRelPath ))
|
|
return FALSE;
|
|
|
|
if( bDeviceASP ) {
|
|
|
|
// Add a '\' before we add the model name
|
|
nLen = wcslen(szRelPath); // the null char not counted
|
|
wsprintf( &szRelPath[nLen], L"\\" );
|
|
|
|
// Append the Model name
|
|
nLen = wcslen(szRelPath); // the null char not counted
|
|
if( !GetModel( &szRelPath[nLen] ))
|
|
return FALSE;
|
|
}
|
|
|
|
// Append "page1.asp" to the end.
|
|
nLen = wcslen(szRelPath); // the null char not counted
|
|
wsprintf( &szRelPath[nLen], L"\\%ws", DEFAULTASPPAGE );
|
|
|
|
|
|
// At this point, szRelPath should be something like HP\LJ4si\page1.asp or HP\page1.asp.
|
|
|
|
|
|
// Make an absolute path by concatanating szRelPath and szFinalPath
|
|
nLen = wcslen(szFinalPath); // the null char not counted
|
|
wsprintf( &szFinalPath[nLen], L"\\%ws", szRelPath );
|
|
|
|
|
|
// See if the file exists.
|
|
if( (DWORD)(-1) == GetFileAttributes( szFinalPath ))
|
|
return FALSE; // The file does not exist
|
|
else {
|
|
lstrcpy( pASPPage, szRelPath ); // The file exists, so the printer has per device or per manufacturer customization.
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Returns: The relative path to the default ASP file, i.e. page1.asp, if the printer supports RFC 1759.
|
|
//
|
|
// Caller allocs memory for pAspPage.
|
|
//
|
|
// pASPPage untouched if failure.
|
|
//
|
|
BOOL Casphelp::IsSnmpSupportedASP( LPTSTR pASPPage )
|
|
{
|
|
BOOL fIsSNMPSupported;
|
|
HRESULT hr;
|
|
|
|
|
|
hr = get_SNMPSupported( &fIsSNMPSupported );
|
|
|
|
if( FAILED( hr ))
|
|
return FALSE;
|
|
|
|
if( fIsSNMPSupported )
|
|
lstrcpy( pASPPage, DEFAULTASPPAGE );
|
|
else
|
|
*pASPPage = 0; // Return an empty string. Not an error case.
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// Caller allocs memory for pAspPage.
|
|
//
|
|
// pASPPage untouched if failure.
|
|
//
|
|
BOOL Casphelp::GetASPPageForUniversalMonitor( LPTSTR pASPPage )
|
|
{
|
|
if( !IsCustomASP( TRUE, pASPPage )) // Check for device ASP
|
|
if( !IsCustomASP( FALSE, pASPPage )) // Check for manufacturer ASP
|
|
if( !IsSnmpSupportedASP( pASPPage )) // Check for SNMP support
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// Caller allocs memory for pAspPage.
|
|
//
|
|
// pASPPage untouched if failure.
|
|
//
|
|
BOOL Casphelp::GetASPPageForOtherMonitors( LPTSTR pMonitorName, LPTSTR pASPPage )
|
|
{
|
|
TCHAR szRelPath [MAX_PATH]; // Path relative to Winnt\web\printers, e.g. LexmarkMon\page1.asp
|
|
TCHAR szFinalPath [MAX_PATH]; // Absolute path for szRelPath.
|
|
int nLen;
|
|
|
|
|
|
// The Printer virtual dir assumed to be winnt\web\printers. Construct it.
|
|
|
|
if( !GetWindowsDirectory( szFinalPath, COUNTOF(szFinalPath))) // Return value is the length in chars w/o null char.
|
|
return FALSE;
|
|
|
|
// Append web\printers to the end
|
|
|
|
// Fix the use of c-runtime calls later (T version, not W). Yet again, ASPHELP interface is server-side only.
|
|
nLen = wcslen(szFinalPath); // the null char not counted
|
|
wsprintf( &szFinalPath[nLen], L"%ws", cszEverestVirRoot );
|
|
|
|
|
|
// Prepare the relative path.
|
|
|
|
lstrcpy( szRelPath, pMonitorName );
|
|
|
|
// Append "page1.asp" to the end.
|
|
nLen = wcslen(szRelPath); // the null char not counted
|
|
wsprintf( &szRelPath[nLen], L"\\%ws", DEFAULTASPPAGE );
|
|
|
|
|
|
// At this point, szRelPath should be something like LexmarkMon\page1.asp
|
|
|
|
|
|
// Make an absolute path by concatanating szRelPath and szFinalPath
|
|
nLen = wcslen(szFinalPath); // the null char not counted
|
|
wsprintf( &szFinalPath[nLen], L"\\%ws", szRelPath );
|
|
|
|
|
|
// See if the file exists.
|
|
if( (DWORD)(-1) == GetFileAttributes( szFinalPath ))
|
|
return FALSE; // The file does not exist
|
|
else {
|
|
lstrcpy( pASPPage, szRelPath ); // The file exists, so the printer has per device or per manufacturer customization.
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Returns a buffer containing the relative path of the ASP, or an empty string.
|
|
//
|
|
// Caller allocs memory for pAspPage.
|
|
//
|
|
// pASPPage untouched if failure.
|
|
//
|
|
BOOL Casphelp::GetASPPage( LPTSTR pASPPage )
|
|
{
|
|
|
|
if( m_bTCPMonSupported ) {
|
|
// The printer is using the Universal monitor
|
|
if( !GetASPPageForUniversalMonitor( pASPPage ))
|
|
return FALSE;
|
|
}
|
|
else {
|
|
TCHAR szMonitorName[MAX_PATH];
|
|
|
|
if (!GetMonitorName(szMonitorName))
|
|
return FALSE;
|
|
|
|
// The printer is NOT using the Universal monitor
|
|
if( !GetASPPageForOtherMonitors( szMonitorName, pASPPage ))
|
|
return FALSE;
|
|
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// STDMETHODIMP means "HRESULT _stdcall"
|
|
|
|
STDMETHODIMP Casphelp::get_AspPage(DWORD dwPage, BSTR * pbstrVal)
|
|
{
|
|
TCHAR szASPPage[MAX_PATH];
|
|
LPTSTR pUrl;
|
|
|
|
if (!pbstrVal)
|
|
return Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_POINTER);
|
|
|
|
if (m_hPrinter == NULL)
|
|
return Error(IDS_NO_PRINTER_OPEN, IID_Iasphelp, E_HANDLE);
|
|
|
|
if( !GetASPPage( szASPPage ))
|
|
return Error(IDS_DATA_NOT_SUPPORTED, IID_Iasphelp, E_NOTIMPL);
|
|
|
|
// Encode the URL by replacing ' ' with %20, etc.
|
|
if (! (pUrl = EncodeString (szASPPage, TRUE)))
|
|
return Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_POINTER);
|
|
|
|
if (!(*pbstrVal = SysAllocString( pUrl ))) {
|
|
LocalFree (pUrl);
|
|
return Error(IDS_OUT_OF_MEMORY, IID_Iasphelp, E_POINTER);
|
|
}
|
|
|
|
if (pUrl)
|
|
LocalFree (pUrl);
|
|
return S_OK;
|
|
}
|