661 lines
19 KiB
C
661 lines
19 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1994 - 1995 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
version.c
|
||
|
|
||
|
Abstract:
|
||
|
This module contains code that determines what the driver major
|
||
|
version is.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Krishna Ganugapati (KrishnaG) 15-Mar-1994
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include <precomp.h>
|
||
|
|
||
|
#define X86_ENVIRONMENT L"Windows NT x86"
|
||
|
#define IA64_ENVIRONMENT L"Windows IA64"
|
||
|
#define MIPS_ENVIRONMENT L"Windows NT R4000"
|
||
|
#define ALPHA_ENVIRONMENT L"Windows NT Alpha_AXP"
|
||
|
#define PPC_ENVIRONMENT L"Windows NT PowerPC"
|
||
|
#define WIN95_ENVIRONMENT L"Windows 4.0"
|
||
|
|
||
|
DWORD
|
||
|
GetDriverMajorVersion(
|
||
|
LPWSTR pFileName
|
||
|
)
|
||
|
{
|
||
|
DWORD dwSize = 0;
|
||
|
LPVOID pFileVersion;
|
||
|
UINT uLen = 0;
|
||
|
LPVOID pMem;
|
||
|
DWORD dwFileOS;
|
||
|
DWORD dwFileVersionMS;
|
||
|
DWORD dwFileVersionLS;
|
||
|
DWORD dwProductVersionMS;
|
||
|
DWORD dwProductVersionLS;
|
||
|
|
||
|
|
||
|
if (!(dwSize = GetFileVersionInfoSize(pFileName, 0))) {
|
||
|
DBGMSG(DBG_TRACE, ("Error: GetFileVersionInfoSize failed with %d\n", GetLastError()));
|
||
|
DBGMSG(DBG_TRACE, ("Returning back a version # 0\n"));
|
||
|
return(0);
|
||
|
}
|
||
|
if (!(pMem = AllocSplMem(dwSize))) {
|
||
|
DBGMSG(DBG_TRACE, ("AllocMem failed \n"));
|
||
|
DBGMSG(DBG_TRACE, ("Returning back a version # 0\n"));
|
||
|
return(0);
|
||
|
}
|
||
|
if (!GetFileVersionInfo(pFileName, 0, dwSize, pMem)) {
|
||
|
FreeSplMem(pMem);
|
||
|
DBGMSG(DBG_TRACE, ("GetFileVersionInfo failed\n"));
|
||
|
DBGMSG(DBG_TRACE, ("Returning back a version # 0\n"));
|
||
|
return(0);
|
||
|
}
|
||
|
if (!VerQueryValue(pMem, L"\\",
|
||
|
&pFileVersion, &uLen)) {
|
||
|
FreeSplMem(pMem);
|
||
|
DBGMSG(DBG_TRACE, ("VerQueryValue failed \n"));
|
||
|
DBGMSG(DBG_TRACE, ("Returning back a version # 0\n"));
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// We could determine the Version Information
|
||
|
//
|
||
|
|
||
|
DBGMSG(DBG_TRACE, ("dwFileVersionMS = %d\n", ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileVersionMS));
|
||
|
DBGMSG(DBG_TRACE, ("dwFileVersionLS = %d\n", ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileVersionLS));
|
||
|
|
||
|
DBGMSG(DBG_TRACE, ("dwProductVersionMS = %d\n", ((VS_FIXEDFILEINFO *)pFileVersion)->dwProductVersionMS));
|
||
|
DBGMSG(DBG_TRACE, ("dwProductVersionLS = %d\n", ((VS_FIXEDFILEINFO *)pFileVersion)->dwProductVersionLS));
|
||
|
|
||
|
dwFileOS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileOS;
|
||
|
dwFileVersionMS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileVersionMS;
|
||
|
dwFileVersionLS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileVersionLS;
|
||
|
|
||
|
dwProductVersionMS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwProductVersionMS;
|
||
|
dwProductVersionLS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwProductVersionLS;
|
||
|
|
||
|
FreeSplMem(pMem);
|
||
|
|
||
|
if (dwFileOS != VOS_NT_WINDOWS32) {
|
||
|
DBGMSG(DBG_TRACE,("Returning back a version # 0\n"));
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
if (dwProductVersionMS == dwFileVersionMS) {
|
||
|
|
||
|
//
|
||
|
// This means this hold for all dlls Pre-Daytona
|
||
|
// after Daytona, printer driver writers must support
|
||
|
// version control or we'll dump them as Version 0
|
||
|
// drivers
|
||
|
|
||
|
|
||
|
DBGMSG(DBG_TRACE,("Returning back a version # 0\n"));
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Bug-Bug: suppose a third-party vendor uses a different system
|
||
|
// methinks we should use the lower dword to have specific value
|
||
|
// which implies he/she supports spooler version -- check with MattFe
|
||
|
|
||
|
DBGMSG(DBG_TRACE,("Returning back a version # %d\n", dwFileVersionMS));
|
||
|
|
||
|
return(dwFileVersionMS);
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
GetPrintDriverVersion(
|
||
|
IN LPCWSTR pszFileName,
|
||
|
OUT LPDWORD pdwFileMajorVersion,
|
||
|
OUT LPDWORD pdwFileMinorVersion
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Name:
|
||
|
|
||
|
GetPrintDriverVersion
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Gets version information about an executable file.
|
||
|
If the file is not an executable, it will return 0
|
||
|
for both major and minor version.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pszFileName - file name
|
||
|
pdwFileMajorVersion - pointer to major version
|
||
|
pdwFileMinorVersion - pointer to minor version
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE if success.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DWORD dwSize = 0;
|
||
|
LPVOID pFileVersion = NULL;
|
||
|
UINT uLen = 0;
|
||
|
LPVOID pMem = NULL;
|
||
|
DWORD dwFileVersionLS;
|
||
|
DWORD dwFileVersionMS;
|
||
|
DWORD dwProductVersionMS;
|
||
|
DWORD dwProductVersionLS;
|
||
|
DWORD dwFileOS, dwFileType, dwFileSubType;
|
||
|
BOOL bRetValue = FALSE;
|
||
|
|
||
|
if (pdwFileMajorVersion)
|
||
|
{
|
||
|
*pdwFileMajorVersion = 0;
|
||
|
}
|
||
|
|
||
|
if (pdwFileMinorVersion)
|
||
|
{
|
||
|
*pdwFileMinorVersion = 0;
|
||
|
}
|
||
|
|
||
|
try
|
||
|
{
|
||
|
if (pszFileName && *pszFileName)
|
||
|
{
|
||
|
dwSize = GetFileVersionInfoSize((LPWSTR)pszFileName, 0);
|
||
|
|
||
|
if (dwSize == 0)
|
||
|
{
|
||
|
//
|
||
|
// Return version 0 for files without a version resource
|
||
|
//
|
||
|
bRetValue = TRUE;
|
||
|
}
|
||
|
else if ((pMem = AllocSplMem(dwSize)) &&
|
||
|
GetFileVersionInfo((LPWSTR)pszFileName, 0, dwSize, pMem) &&
|
||
|
VerQueryValue(pMem, L"\\", &pFileVersion, &uLen))
|
||
|
{
|
||
|
dwFileOS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileOS;
|
||
|
dwFileType = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileType;
|
||
|
dwFileSubType = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileSubtype;
|
||
|
dwFileVersionMS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileVersionMS;
|
||
|
dwFileVersionLS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileVersionLS;
|
||
|
dwProductVersionMS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwProductVersionMS;
|
||
|
dwProductVersionLS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwProductVersionLS;
|
||
|
|
||
|
//
|
||
|
// Return versions for drivers designed for Windows NT/Windows 2000,
|
||
|
// marked as printer drivers.
|
||
|
// Hold for all dlls Pre-Daytona.
|
||
|
// After Daytona, printer driver writers must support
|
||
|
// version control or we'll dump them as Version 0 drivers.
|
||
|
//
|
||
|
if (dwFileOS == VOS_NT_WINDOWS32)
|
||
|
{
|
||
|
if (dwFileType == VFT_DRV &&
|
||
|
dwFileSubType == VFT2_DRV_VERSIONED_PRINTER)
|
||
|
{
|
||
|
if (pdwFileMinorVersion)
|
||
|
{
|
||
|
*pdwFileMinorVersion = dwFileVersionLS;
|
||
|
}
|
||
|
|
||
|
if (pdwFileMajorVersion)
|
||
|
{
|
||
|
*pdwFileMajorVersion = dwFileVersionMS;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pdwFileMajorVersion)
|
||
|
{
|
||
|
if (dwProductVersionMS == dwFileVersionMS)
|
||
|
{
|
||
|
//
|
||
|
// Hold for all dlls Pre-Daytona.
|
||
|
// After Daytona, printer driver writers must support
|
||
|
// version control or we'll dump them as Version 0
|
||
|
// drivers.
|
||
|
//
|
||
|
*pdwFileMajorVersion = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*pdwFileMajorVersion = dwFileVersionMS;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bRetValue = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
FreeSplMem(pMem);
|
||
|
}
|
||
|
|
||
|
return bRetValue;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
CheckFilePlatform(
|
||
|
IN LPWSTR pszFileName,
|
||
|
IN LPWSTR pszEnvironment
|
||
|
)
|
||
|
{
|
||
|
HANDLE hFile, hMapping;
|
||
|
LPVOID BaseAddress = NULL;
|
||
|
PIMAGE_NT_HEADERS pImgHdr;
|
||
|
BOOL bRet = FALSE;
|
||
|
|
||
|
try {
|
||
|
|
||
|
hFile = CreateFile(pszFileName,
|
||
|
GENERIC_READ,
|
||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||
|
NULL,
|
||
|
OPEN_EXISTING,
|
||
|
FILE_ATTRIBUTE_NORMAL,
|
||
|
NULL);
|
||
|
|
||
|
if ( hFile == INVALID_HANDLE_VALUE )
|
||
|
leave;
|
||
|
|
||
|
hMapping = CreateFileMapping(hFile,
|
||
|
NULL,
|
||
|
PAGE_READONLY,
|
||
|
0,
|
||
|
0,
|
||
|
NULL);
|
||
|
|
||
|
if ( !hMapping )
|
||
|
leave;
|
||
|
|
||
|
BaseAddress = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
|
||
|
|
||
|
CloseHandle(hMapping);
|
||
|
|
||
|
if ( !BaseAddress )
|
||
|
leave;
|
||
|
|
||
|
pImgHdr = RtlImageNtHeader(BaseAddress);
|
||
|
|
||
|
if ( !pImgHdr ) {
|
||
|
|
||
|
//
|
||
|
// This happens for Win95 drivers. The second part of || is for
|
||
|
// any environments we may add in the future
|
||
|
//
|
||
|
bRet = !_wcsicmp(pszEnvironment, WIN95_ENVIRONMENT) ||
|
||
|
!( _wcsicmp(pszEnvironment, X86_ENVIRONMENT) &&
|
||
|
_wcsicmp(pszEnvironment, IA64_ENVIRONMENT) &&
|
||
|
_wcsicmp(pszEnvironment, ALPHA_ENVIRONMENT) &&
|
||
|
_wcsicmp(pszEnvironment, PPC_ENVIRONMENT) &&
|
||
|
_wcsicmp(pszEnvironment, MIPS_ENVIRONMENT) );
|
||
|
leave;
|
||
|
}
|
||
|
|
||
|
switch (pImgHdr->FileHeader.Machine) {
|
||
|
|
||
|
case IMAGE_FILE_MACHINE_I386:
|
||
|
bRet = !_wcsicmp(pszEnvironment, X86_ENVIRONMENT);
|
||
|
break;
|
||
|
|
||
|
case IMAGE_FILE_MACHINE_ALPHA:
|
||
|
bRet = !_wcsicmp(pszEnvironment, ALPHA_ENVIRONMENT);
|
||
|
break;
|
||
|
|
||
|
case IMAGE_FILE_MACHINE_IA64:
|
||
|
bRet = !_wcsicmp(pszEnvironment, IA64_ENVIRONMENT);
|
||
|
break;
|
||
|
|
||
|
case IMAGE_FILE_MACHINE_POWERPC:
|
||
|
bRet = !_wcsicmp(pszEnvironment, PPC_ENVIRONMENT);
|
||
|
break;
|
||
|
|
||
|
case IMAGE_FILE_MACHINE_R3000:
|
||
|
case IMAGE_FILE_MACHINE_R4000:
|
||
|
case IMAGE_FILE_MACHINE_R10000:
|
||
|
bRet = !_wcsicmp(pszEnvironment, MIPS_ENVIRONMENT);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
//
|
||
|
// For any environments we may add in the future.
|
||
|
//
|
||
|
bRet = !(_wcsicmp(pszEnvironment, X86_ENVIRONMENT) &&
|
||
|
_wcsicmp(pszEnvironment, IA64_ENVIRONMENT) &&
|
||
|
_wcsicmp(pszEnvironment, ALPHA_ENVIRONMENT) &&
|
||
|
_wcsicmp(pszEnvironment, PPC_ENVIRONMENT) &&
|
||
|
_wcsicmp(pszEnvironment, MIPS_ENVIRONMENT) );
|
||
|
}
|
||
|
|
||
|
} finally {
|
||
|
|
||
|
if ( hFile != INVALID_HANDLE_VALUE ) {
|
||
|
|
||
|
if ( BaseAddress )
|
||
|
UnmapViewOfFile(BaseAddress);
|
||
|
CloseHandle(hFile);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Name:
|
||
|
|
||
|
GetBinaryVersion
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Gets version information about an executable file.
|
||
|
If the file is not an executable, it will return 0
|
||
|
for both major and minor version. This function does
|
||
|
not are if the file is a printer driver or anything
|
||
|
else as long as it has a resource.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pszFileName - file name
|
||
|
pdwFileMajorVersion - pointer to major version
|
||
|
pdwFileMinorVersion - pointer to minor version
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE if success.
|
||
|
|
||
|
--*/
|
||
|
BOOL
|
||
|
GetBinaryVersion(
|
||
|
IN PCWSTR pszFileName,
|
||
|
OUT PDWORD pdwFileMajorVersion,
|
||
|
OUT PDWORD pdwFileMinorVersion
|
||
|
)
|
||
|
{
|
||
|
DWORD dwSize = 0;
|
||
|
LPVOID pFileVersion = NULL;
|
||
|
UINT uLen = 0;
|
||
|
LPVOID pMem = NULL;
|
||
|
DWORD dwFileVersionLS;
|
||
|
DWORD dwFileVersionMS;
|
||
|
BOOL bRetValue = FALSE;
|
||
|
|
||
|
if (pdwFileMajorVersion && pdwFileMinorVersion && pszFileName && *pszFileName)
|
||
|
{
|
||
|
*pdwFileMajorVersion = 0;
|
||
|
*pdwFileMinorVersion = 0;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
dwSize = GetFileVersionInfoSize((LPWSTR)pszFileName, 0);
|
||
|
|
||
|
if (dwSize == 0)
|
||
|
{
|
||
|
//
|
||
|
// Return version 0 for files without a version resource
|
||
|
//
|
||
|
bRetValue = TRUE;
|
||
|
}
|
||
|
else if ((pMem = AllocSplMem(dwSize)) &&
|
||
|
GetFileVersionInfo((LPWSTR)pszFileName, 0, dwSize, pMem) &&
|
||
|
VerQueryValue(pMem, L"\\", &pFileVersion, &uLen))
|
||
|
{
|
||
|
dwFileVersionMS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileVersionMS;
|
||
|
dwFileVersionLS = ((VS_FIXEDFILEINFO *)pFileVersion)->dwFileVersionLS;
|
||
|
|
||
|
*pdwFileMinorVersion = dwFileVersionLS;
|
||
|
*pdwFileMajorVersion = dwFileVersionMS;
|
||
|
|
||
|
bRetValue = TRUE;
|
||
|
}
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
FreeSplMem(pMem);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||
|
}
|
||
|
|
||
|
return bRetValue;
|
||
|
}
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
PCWSTR pszDriver;
|
||
|
DWORD DrvMajor;
|
||
|
DWORD DrvMinor;
|
||
|
PCWSTR pszProc;
|
||
|
DWORD ProcMajor;
|
||
|
DWORD ProcMinor;
|
||
|
} SPECIALDRIVER;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
PCWSTR pszPrintProcFile;
|
||
|
DWORD PrintProcMajVer;
|
||
|
DWORD PrintProcMinVer;
|
||
|
} NOIMPERSONATEPRINTPROCS;
|
||
|
|
||
|
|
||
|
NOIMPERSONATEPRINTPROCS NoImpPrintProcs[] =
|
||
|
{
|
||
|
{L"lxaspp.dll", 0x00010000, 0x00000001},
|
||
|
{L"lxarpp.dll", 0x00010000, 0x00000001},
|
||
|
{L"lxampp.dll", 0x00010000, 0x00000001},
|
||
|
{L"lxaupp.dll", 0x00010000, 0x00000001},
|
||
|
{L"lxatpp.dll", 0x00010000, 0x00000001},
|
||
|
{L"lxacpp.dll", 0x00010000, 0x00000001},
|
||
|
{L"lxaapp.dll", 0x00010000, 0x00000001},
|
||
|
{L"lxaepp.dll", 0x00010000, 0x00000001},
|
||
|
{L"lxadpp.dll", 0x00010000, 0x00000001},
|
||
|
{L"lxcapp.dll", 0x00010000, 0x00000001},
|
||
|
{L"lexepp.dll", 0x00010000, 0x00000001},
|
||
|
{L"lexfpp.dll", 0x00010000, 0x00000001},
|
||
|
{L"jw61pp.dll", 0x00010000, 0x00000001},
|
||
|
{L"fxj4pp.dll", 0x00010000, 0x00000001},
|
||
|
{L"lxalpp5c.dll", 0x00020000, 0x00020000},
|
||
|
{L"lxalpp5c.dll", 0x00010000, 0x00060000},
|
||
|
{L"lxalpp5c.dll", 0x00020000, 0x00010000},
|
||
|
{L"lxalpp5c.dll", 0x00010000, 0x00050000},
|
||
|
{L"lxakpp5c.dll", 0x00020000, 0x00010000},
|
||
|
{L"lxakpp5c.dll", 0x00010000, 0x00050001},
|
||
|
{L"lxazpp5c.dll", 0x00010000, 0x00040002},
|
||
|
{L"lxazpp5c.dll", 0x00010000, 0x00050001},
|
||
|
{L"lxaxpp5c.dll", 0x00010000, 0x00060008},
|
||
|
{L"lxaipp5c.dll", 0x00020000, 0x00020002},
|
||
|
{L"lxaipp5c.dll", 0x00030000, 0x00020001},
|
||
|
{L"lxajpp5c.dll", 0x00030000, 0x00010000},
|
||
|
{L"lxajpp5c.dll", 0x00010000, 0x00020001},
|
||
|
{L"lxavpp5c.dll", 0x00010000, 0x000A0000},
|
||
|
{L"lxavpp5c.dll", 0x00010000, 0x00060000},
|
||
|
{L"lg24pp5c.dll", 0x00010000, 0x00010008},
|
||
|
{L"lg24pp5c.dll", 0x00010000, 0x00070002},
|
||
|
{L"lgl2pp5c.dll", 0x00010000, 0x00010006},
|
||
|
{L"lgaxpp5c.dll", 0x00010000, 0x00020001},
|
||
|
{L"smaxpp5c.dll", 0x00010000, 0x00030000},
|
||
|
{L"smazpp5c.dll", 0x00010000, 0x00020000},
|
||
|
{L"lxbhpp5c.dll", 0x00010000, 0x00050000},
|
||
|
};
|
||
|
|
||
|
|
||
|
PCWSTR ArraySpecialDriversInbox[] =
|
||
|
{
|
||
|
L"Lexmark 3200 Color Jetprinter",
|
||
|
L"Lexmark 5700 Color Jetprinter",
|
||
|
L"Lexmark Z11 Color Jetprinter",
|
||
|
L"Lexmark Z12 Color Jetprinter",
|
||
|
L"Lexmark Z22-Z32 Color Jetprinter",
|
||
|
L"Lexmark Z31 Color Jetprinter",
|
||
|
L"Lexmark Z42 Color Jetprinter",
|
||
|
L"Lexmark Z51 Color Jetprinter",
|
||
|
L"Lexmark Z52 Color Jetprinter",
|
||
|
L"Compaq IJ300 Inkjet Printer",
|
||
|
L"Compaq IJ600 Inkjet Printer",
|
||
|
L"Compaq IJ700 Inkjet Printer",
|
||
|
L"Compaq IJ750 Inkjet Printer",
|
||
|
L"Compaq IJ900 Inkjet Printer",
|
||
|
L"Compaq IJ1200 Inkjet Printer"
|
||
|
};
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Name:
|
||
|
|
||
|
FillInVersionInfo
|
||
|
|
||
|
Description:
|
||
|
|
||
|
We have the following 2 DWORD fields in INIDRIVER: DriverFileMajorVersion and DriverFileMinorVersion
|
||
|
They are not filled in when a driver is added or when the spooler starts. The reason for the
|
||
|
existence of these 2 fields is that we cannot always rely on the informatin in dwlDriverVersion
|
||
|
(part of driver-info_6). Not all driver packages supply this information.
|
||
|
|
||
|
So when we print for the first time using a certain INIDRIVER, we call this function to look at
|
||
|
the resource of the driver DLL and populate DriverFileMajorVersion and DriverFileMinorVersion.
|
||
|
The numbers come from VS_FIXEDFILEINFO.FileVer
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pIniDriver - pinidriver to fill in the major and minor versions
|
||
|
pIniSpooler - pinispooler to which the driver belongs
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Win32 error code
|
||
|
|
||
|
--*/
|
||
|
DWORD
|
||
|
FillInVersionInfo(
|
||
|
IN PINIDRIVER pIniDriver,
|
||
|
IN PINISPOOLER pIniSpooler
|
||
|
)
|
||
|
{
|
||
|
DWORD Error = ERROR_INVALID_ENVIRONMENT;
|
||
|
WCHAR szPath[MAX_PATH];
|
||
|
DWORD cbNeeded;
|
||
|
PINIENVIRONMENT pIniEnvironment;
|
||
|
|
||
|
EnterSplSem();
|
||
|
|
||
|
pIniEnvironment = FindEnvironment(LOCAL_ENVIRONMENT, pIniSpooler);
|
||
|
|
||
|
if (pIniEnvironment)
|
||
|
{
|
||
|
Error = StrNCatBuff(szPath,
|
||
|
MAX_PATH,
|
||
|
pIniSpooler->pDir,
|
||
|
L"\\",
|
||
|
szDriverDir,
|
||
|
L"\\",
|
||
|
pIniEnvironment->pDirectory,
|
||
|
L"\\3\\",
|
||
|
pIniDriver->pDriverFile,
|
||
|
NULL);
|
||
|
}
|
||
|
|
||
|
LeaveSplSem();
|
||
|
|
||
|
if (Error == ERROR_SUCCESS)
|
||
|
{
|
||
|
Error = GetBinaryVersion(szPath,
|
||
|
&pIniDriver->DriverFileMajorVersion,
|
||
|
&pIniDriver->DriverFileMinorVersion) ? ERROR_SUCCESS : GetLastError();
|
||
|
}
|
||
|
|
||
|
SPLASSERT(Error == ERROR_SUCCESS);
|
||
|
|
||
|
return Error;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Name:
|
||
|
|
||
|
IsSpecialDriver
|
||
|
|
||
|
Description:
|
||
|
|
||
|
Checks whether a printer driver (and print processor) needs to be special
|
||
|
cased. Some print processors want to be loaded in local system context.
|
||
|
The are listed in the tables above. some are inbox, some are IHV.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pIniDriver - pinidriver for the current job
|
||
|
pIniProc - piniprintproc for the current job
|
||
|
pIniSpooler - pinispooler for current job
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE - this print processor needs to be loaded in local system context
|
||
|
FALSE - load print processor in impersonation context
|
||
|
|
||
|
--*/
|
||
|
BOOL
|
||
|
IsSpecialDriver(
|
||
|
IN PINIDRIVER pIniDriver,
|
||
|
IN PINIPRINTPROC pIniProc,
|
||
|
IN PINISPOOLER pIniSpooler
|
||
|
)
|
||
|
{
|
||
|
BOOL bSpecial = FALSE;
|
||
|
DWORD i;
|
||
|
|
||
|
//
|
||
|
// Check if it is an inbox driver that needs to be special cased
|
||
|
//
|
||
|
for (i = 0; i < COUNTOF(ArraySpecialDriversInbox); i++)
|
||
|
{
|
||
|
if (!_wcsicmp(pIniDriver->pName, ArraySpecialDriversInbox[i]))
|
||
|
{
|
||
|
bSpecial = TRUE;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Check if it is an IHV driver that needs to be special cased
|
||
|
//
|
||
|
if (!bSpecial)
|
||
|
{
|
||
|
if (pIniDriver->DriverFileMajorVersion == 0 && pIniDriver->DriverFileMinorVersion == 0)
|
||
|
{
|
||
|
//
|
||
|
// We fill in on demand the major and minor file version
|
||
|
//
|
||
|
FillInVersionInfo(pIniDriver, pIniSpooler);
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < COUNTOF(NoImpPrintProcs); i++)
|
||
|
{
|
||
|
if (!_wcsicmp(pIniProc->pDLLName, NoImpPrintProcs[i].pszPrintProcFile) &&
|
||
|
pIniProc->FileMajorVersion == NoImpPrintProcs[i].PrintProcMajVer &&
|
||
|
pIniProc->FileMinorVersion == NoImpPrintProcs[i].PrintProcMinVer)
|
||
|
{
|
||
|
bSpecial = TRUE;
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bSpecial;
|
||
|
}
|