You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
491 lines
15 KiB
491 lines
15 KiB
/*++
|
|
|
|
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"
|
|
#define AMD64_ENVIRONMENT L"Windows NT AMD64"
|
|
|
|
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_AMD64:
|
|
bRet = !_wcsicmp(pszEnvironment, AMD64_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 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:
|
|
|
|
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)
|
|
{
|
|
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;
|
|
}
|
|
|