|
|
/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
dosspool.c
Abstract:
Contains the entry points for the functions that live in a separate DLL. The entry points are made available here, but will not load the WINSPOOL.DRV until it is needed.
Contains:
Author:
Congpa You (CongpaY) 22-Jan-1993
Environment:
Notes:
Revision History:
--*/ #include <windows.h>
#include <netdebug.h> // NetpAssert()
#include "dosspool.h"
#include "myspool.h"
/*
* global defines. */
#define WINSPOOL_DLL_NAME TEXT("WINSPOOL.DRV")
/*
* global data. * * here we store handles to the MPRUI dll and pointers to the function * all of below is protect in multi threaded case with MprLoadLibSemaphore. */
HINSTANCE vhWinspoolDll = NULL ;
PF_ClosePrinter pfClosePrinter = NULL ; PF_EnumJobsA pfEnumJobsA = NULL ; PF_EnumPrintersA pfEnumPrintersA = NULL ; PF_GetJobA pfGetJobA = NULL ; PF_GetPrinterA pfGetPrinterA = NULL ; PF_OpenPrinterA pfOpenPrinterA = NULL ; PF_OpenPrinterW pfOpenPrinterW = NULL ; PF_SetJobA pfSetJobA = NULL ; PF_SetPrinterW pfSetPrinterW = NULL ; PF_GetPrinterDriverA pfGetPrinterDriverA = NULL;
/*
* global functions */ BOOL MakeSureDllIsLoaded(void) ;
/*******************************************************************
NAME: GetFileNameA
SYNOPSIS: Gets the filename part from a fully qualified path
HISTORY: MuhuntS 06-Feb-1996 Created
********************************************************************/ LPSTR GetFileNameA( LPSTR pPathName ) { LPSTR pSlash = pPathName, pTemp;
if ( pSlash ) {
while ( pTemp = strchr(pSlash, '\\') ) pSlash = pTemp+1;
if ( !*pSlash ) pSlash = NULL;
NetpAssert(pSlash != NULL); }
return pSlash; }
/*******************************************************************
NAME: GetDependentFileNameA
SYNOPSIS: Gets the dependent filename to send to Win95. Normally just the file name part. But for ICM files this would be Color\<filename>
HISTORY: MuhuntS 23-Apr-1997 Created
********************************************************************/ LPSTR GetDependentFileNameA( LPSTR pPathName ) { LPSTR pRet = GetFileNameA(pPathName), p;
if (pRet) { DWORD dwLen = strlen(pRet);
p = pRet+dwLen-4;
if ( dwLen > 3 && ( !_stricmp(p, ".ICM") || !_stricmp(p, ".ICC") ) && (p = pRet - 7) > pPathName && !_strnicmp(p, "\\Color\\", 7) ) {
pRet = p + 1; } }
return pRet; }
/*******************************************************************
NAME: MyClosePrinter
SYNOPSIS: calls thru to the superset function
HISTORY: CongpaY 22-Jan-1993 Created
********************************************************************/
BOOL MyClosePrinter (HANDLE hPrinter) { PF_ClosePrinter pfTemp;
// if function has not been used before, get its address.
if (pfClosePrinter == NULL) { // make sure DLL Is loaded
if (!MakeSureDllIsLoaded()) { return(FALSE) ; }
pfTemp = (PF_ClosePrinter) GetProcAddress(vhWinspoolDll, "ClosePrinter") ;
if (pfTemp == NULL) { return(FALSE); } else { pfClosePrinter = pfTemp; }
}
return ((*pfClosePrinter)(hPrinter)); }
/*******************************************************************
NAME: MyEnumJobs
SYNOPSIS: calls thru to the superset function
NOTES: This is defined ANSI version. If change to UNICODE version in the future, you should change the code to make it call UNICODE version!!!
HISTORY: CongpaY 22-Jan-1993 Created
********************************************************************/
BOOL MyEnumJobs (HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, LPBYTE pJob, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned) { PF_EnumJobsA pfTemp;
// if function has not been used before, get its address.
if (pfEnumJobsA == NULL) { // make sure DLL Is loaded
if (!MakeSureDllIsLoaded()) { return(FALSE) ; }
pfTemp = (PF_EnumJobsA) GetProcAddress(vhWinspoolDll, "EnumJobsA") ;
if (pfTemp == NULL) { return(FALSE); } else { pfEnumJobsA = pfTemp; } }
return ((*pfEnumJobsA)(hPrinter, FirstJob, NoJobs, Level, pJob, cbBuf, pcbNeeded, pcReturned)); }
/*******************************************************************
NAME: MyEnumPrinters
SYNOPSIS: calls thru to the superset function
HISTORY: CongpaY 22-Jan-1993 Created
********************************************************************/
BOOL MyEnumPrinters(DWORD Flags, LPSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
{ PF_EnumPrintersA pfTemp;
// if function has not been used before, get its address.
if (pfEnumPrintersA == NULL) { // make sure DLL Is loaded
if (!MakeSureDllIsLoaded()) { return(FALSE) ; }
pfTemp = (PF_EnumPrintersA) GetProcAddress(vhWinspoolDll, "EnumPrintersA") ;
if (pfTemp == NULL) { return(TRUE); } else pfEnumPrintersA = pfTemp; }
return ((*pfEnumPrintersA)(Flags, Name, Level, pPrinterEnum, cbBuf, pcbNeeded, pcReturned)); }
/*******************************************************************
NAME: MyGetJobA
SYNOPSIS: calls thru to the superset function
HISTORY: CongpaY 22-Jan-1993 Created
********************************************************************/
BOOL MyGetJobA(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pJob, DWORD cbBuf, LPDWORD pcbNeeded) { PF_GetJobA pfTemp;
// if function has not been used before, get its address.
if (pfGetJobA == NULL) { // make sure DLL Is loaded
if (!MakeSureDllIsLoaded()) { return(FALSE) ; }
pfTemp = (PF_GetJobA) GetProcAddress(vhWinspoolDll, "GetJobA") ;
if (pfTemp == NULL) { return(FALSE); } else pfGetJobA = pfTemp; }
return ((*pfGetJobA)(hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded)); }
/*******************************************************************
NAME: MyGetPrinter
SYNOPSIS: calls thru to the superset function
HISTORY: CongpaY 22-Jan-1993 Created
********************************************************************/
BOOL MyGetPrinter (HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded) { PF_GetPrinterA pfTemp; LPSTR pszDriverName = NULL; DWORD cbDriverName = 0; BOOL bRet;
// if function has not been used before, get its address.
if (pfGetPrinterA == NULL) { // make sure DLL Is loaded
if (!MakeSureDllIsLoaded()) { return(FALSE) ; }
pfTemp = (PF_GetPrinterA) GetProcAddress(vhWinspoolDll, "GetPrinterA") ;
if (pfTemp == NULL) { return(FALSE); } else pfGetPrinterA = pfTemp; }
//
// Win95 driver name could be different than NT. If it is different AND
// the win95 driver with the different name is installed we want to send
// that name to Win9x client
//
if ( Level == 2 ) { DWORD dwNeeded = 0;
// Check the size of the name and make sure that we copy the printer driver name to the
// beginning of the buffer. The previous code would let the GetPrinterDriver call determine
// where to put it which could result in the strcpy copying data from one string on top of another
// if the call used the end of the buffer like we plan on using. We address this by doing an STRNCPY to
// make sure we don't start doing an infinite copy and also make sure our buffers don't overlap with
// an assert.
bRet = MyGetPrinterDriver(hPrinter, WIN95_ENVIRONMENT, 1, NULL, 0, &dwNeeded); if( dwNeeded <= cbBuf ) { if( MyGetPrinterDriver( hPrinter, WIN95_ENVIRONMENT, 1, pPrinter, dwNeeded, pcbNeeded )) { pszDriverName = ((LPDRIVER_INFO_1A)pPrinter)->pName; cbDriverName = (strlen(pszDriverName) + 1) * sizeof(CHAR); NetpAssert( pszDriverName + cbDriverName < pPrinter + cbBuf - cbDriverName ); strncpy((LPSTR)(pPrinter + cbBuf - cbDriverName), pszDriverName, cbDriverName); pszDriverName = (LPSTR)(pPrinter + cbBuf - cbDriverName); } else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER ) { //
// DRIVER_INFO_1 has pDriverName only. So if we fail with
// insufficient buffer GetPrinter is guaranteed to fail too.
// If we use a different level that may not be TRUE
//
cbDriverName = *pcbNeeded - sizeof(DRIVER_INFO_1A); } } else { cbDriverName = dwNeeded - sizeof(DRIVER_INFO_1A); } }
if( cbBuf > cbDriverName ) { bRet = pfGetPrinterA(hPrinter, Level, pPrinter, cbBuf-cbDriverName, pcbNeeded); } else { bRet = pfGetPrinterA(hPrinter, Level, pPrinter, 0, pcbNeeded); }
if ( Level != 2 ) return bRet;
if ( bRet ) {
if ( pszDriverName ) {
((LPPRINTER_INFO_2A)pPrinter)->pDriverName = pszDriverName; *pcbNeeded += cbDriverName; } } else if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
*pcbNeeded += cbDriverName; }
return bRet; }
/*******************************************************************
NAME: MyOpenPrinterA
SYNOPSIS: calls thru to the superset function
HISTORY: CongpaY 22-Jan-1993 Created
********************************************************************/
BOOL MyOpenPrinterA(LPSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSA pDefault)
{ PF_OpenPrinterA pfTemp;
// if function has not been used before, get its address.
if (pfOpenPrinterA == NULL) { // make sure DLL Is loaded
if (!MakeSureDllIsLoaded()) { return(FALSE) ; }
pfTemp = (PF_OpenPrinterA) GetProcAddress(vhWinspoolDll, "OpenPrinterA") ;
if (pfTemp == NULL) { return(FALSE); } else pfOpenPrinterA = pfTemp; }
return ((*pfOpenPrinterA)(pPrinterName, phPrinter, pDefault)); }
/*******************************************************************
NAME: MyOpenPrinterW
SYNOPSIS: calls thru to the superset function
HISTORY: CongpaY 22-Jan-1993 Created
********************************************************************/
BOOL MyOpenPrinterW (LPWSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSW pDefault)
{ PF_OpenPrinterW pfTemp;
// if function has not been used before, get its address.
if (pfOpenPrinterW == NULL) { // make sure DLL Is loaded
if (!MakeSureDllIsLoaded()) { return(FALSE) ; }
pfTemp = (PF_OpenPrinterW) GetProcAddress(vhWinspoolDll, "OpenPrinterW") ;
if (pfTemp == NULL) { return(FALSE); } else pfOpenPrinterW = pfTemp; }
return ((*pfOpenPrinterW)(pPrinterName, phPrinter, pDefault)); } /*******************************************************************
NAME: MySetJobA
SYNOPSIS: calls thru to the superset function
HISTORY: CongpaY 22-Jan-1993 Created AlbertT 24-Mar-1995 AddedLevel and pJob
********************************************************************/
BOOL MySetJobA (HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pJob, DWORD Command)
{ PF_SetJobA pfTemp;
// if function has not been used before, get its address.
if (pfSetJobA == NULL) { // make sure DLL Is loaded
if (!MakeSureDllIsLoaded()) { return(FALSE) ; }
pfTemp = (PF_SetJobA) GetProcAddress(vhWinspoolDll, "SetJobA") ;
if (pfTemp == NULL) { return(FALSE); } else pfSetJobA = pfTemp; }
return ((*pfSetJobA)(hPrinter, JobId, Level, pJob, Command)); }
/*******************************************************************
NAME: MySetPrinterW
SYNOPSIS: calls thru to the superset function
HISTORY: AlbertT 23-Mar-1995 Created
********************************************************************/
BOOL MySetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD Command)
{ PF_SetPrinterW pfTemp;
// if function has not been used before, get its address.
if (pfSetPrinterW == NULL) { // make sure DLL Is loaded
if (!MakeSureDllIsLoaded()) { return(FALSE) ; }
pfTemp = (PF_SetPrinterW) GetProcAddress(vhWinspoolDll, "SetPrinterW") ;
if (pfTemp == NULL) { return(FALSE); } else pfSetPrinterW = pfTemp; }
return ((*pfSetPrinterW)(hPrinter, Level, pPrinter, Command)); }
/*******************************************************************
NAME: MyGetPrinterDriver
SYNOPSIS: calls thru to the superset function
HISTORY: MuhuntS 06-Feb-1996 Created
********************************************************************/
BOOL MyGetPrinterDriver( HANDLE hPrinter, LPSTR pEnvironment, DWORD Level, LPBYTE pDriver, DWORD cbBuf, LPDWORD pcbNeeded ) { //
// if function has not been used before, get its address.
//
if ( !pfGetPrinterDriverA ) {
//
// If dll is not loaded yet load it
//
if ( !MakeSureDllIsLoaded() ) {
return FALSE; }
(FARPROC) pfGetPrinterDriverA = GetProcAddress(vhWinspoolDll, "GetPrinterDriverA");
if ( !pfGetPrinterDriverA ) return FALSE; }
return ((*pfGetPrinterDriverA)(hPrinter, pEnvironment, Level, pDriver, cbBuf, pcbNeeded)); }
/*******************************************************************
NAME: MakeSureDllIsLoaded
SYNOPSIS: loads the WINSPOOL dll if need.
EXIT: returns TRUE if dll already loaded, or loads successfully. Returns false otherwise. Caller should call GetLastError() to determine error.
NOTES: it is up to the caller to call EnterLoadLibCritSect before he calls this.
HISTORY: chuckc 29-Jul-1992 Created congpay 22-Jan-1993 Modified.
********************************************************************/
BOOL MakeSureDllIsLoaded(void) { HINSTANCE handle ;
// if already load, just return TRUE
if (vhWinspoolDll != NULL) return TRUE ;
// load the library. if it fails, it would have done a SetLastError.
handle = LoadLibrary(WINSPOOL_DLL_NAME); if (handle == NULL) return FALSE ;
// we are cool.
vhWinspoolDll = handle ; return TRUE ; }
|