windows-nt/Source/XPSP1/NT/windows/winstate/cobra/modules/sysmod/dbattrib.c
2020-09-26 16:20:57 +08:00

864 lines
18 KiB
C

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
dbattrib.c
Abstract:
This source implements attribute functions used by MigDb
Author:
Calin Negreanu (calinn) 07-Jan-1998
Revision History:
28-May-1999 ovidiut Added SECTIONKEY attribute
22-Apr-1999 jimschm Added UPTOBIN*VER attributes
07-Jan-1999 jimschm Added HASVERSION attribute
18-May-1998 jimschm Added INPARENTDIR attribute
08-Apr-1998 calinn Added two more attributes (ExeType and Description)
29-Jan-1998 calinn Modified CheckSum and FileSize to work with hex numbers
19-Jan-1998 calinn added CheckSum attribute
--*/
#include "pch.h"
#include "logmsg.h"
#include "osfiles.h"
/*++
Macro Expansion List Description:
ATTRIBUTE_FUNCTIONS lists all valid attributes to query for a specific file.
They are used by migdb in it's attempt to locate files.
Line Syntax:
DEFMAC(AttribFn, AttribName, ReqArgs)
Arguments:
AttribFn - This is a boolean function that returnes TRUE if a specified file has
the specified attribute. You must implement a function with this name
and required parameters.
AttribName - This is the string that identifies the attribute function. It should
have the same value as listed in migdb.inf
ReqArgs - Specifies the number of args that are required for the action. Used
by the parser.
Variables Generated From List:
g_AttributeFunctions - do not touch!
For accessing the array there are the following functions:
MigDb_GetAttributeAddr
MigDb_GetAttributeIdx
MigDb_GetAttributeName
MigDb_GetReqArgCount
--*/
#define ATTRIBUTE_FUNCTIONS \
DEFMAC(CompanyName, COMPANYNAME, 1) \
DEFMAC(FileDescription, FILEDESCRIPTION, 1) \
DEFMAC(FileVersion, FILEVERSION, 1) \
DEFMAC(InternalName, INTERNALNAME, 1) \
DEFMAC(LegalCopyright, LEGALCOPYRIGHT, 1) \
DEFMAC(OriginalFilename, ORIGINALFILENAME, 1) \
DEFMAC(ProductName, PRODUCTNAME, 1) \
DEFMAC(ProductVersion, PRODUCTVERSION, 1) \
DEFMAC(FileSize, FILESIZE, 1) \
DEFMAC(IsMsBinary, ISMSBINARY, 0) \
DEFMAC(CheckSum, CHECKSUM, 1) \
DEFMAC(ExeType, EXETYPE, 1) \
DEFMAC(Description, DESCRIPTION, 1) \
DEFMAC(HasVersion, HASVERSION, 0) \
DEFMAC(BinFileVer, BINFILEVER, 1) \
DEFMAC(BinProductVer, BINPRODUCTVER, 1) \
DEFMAC(FileDateHi, FILEDATEHI, 1) \
DEFMAC(FileDateLo, FILEDATELO, 1) \
DEFMAC(FileVerOs, FILEVEROS, 1) \
DEFMAC(FileVerType, FILEVERTYPE, 1) \
DEFMAC(SizeCheckSum, FC, 2) \
DEFMAC(UpToBinProductVer, UPTOBINPRODUCTVER, 1) \
DEFMAC(UpToBinFileVer, UPTOBINFILEVER, 1) \
typedef struct {
PCTSTR AttributeName;
PATTRIBUTE_PROTOTYPE AttributeFunction;
UINT RequiredArgs;
} ATTRIBUTE_STRUCT, *PATTRIBUTE_STRUCT;
//
// Declare the attribute functions
//
#define DEFMAC(fn,id,reqargs) ATTRIBUTE_PROTOTYPE fn;
ATTRIBUTE_FUNCTIONS
#undef DEFMAC
//
// Declare a global array of functions and name identifiers for attribute functions
//
#define DEFMAC(fn,id,regargs) {TEXT(#id), fn, regargs},
static ATTRIBUTE_STRUCT g_AttributeFunctions[] = {
ATTRIBUTE_FUNCTIONS
{NULL, NULL}
};
#undef DEFMAC
BOOL
pAlwaysFalseAttribute (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return FALSE;
}
PATTRIBUTE_PROTOTYPE
MigDb_GetAttributeAddr (
IN INT AttributeIdx
)
/*++
Routine Description:
MigDb_GetAttributeAddr returns the address of the attribute function based on the attribute index
Arguments:
AttributeIdx - Attribute index.
Return value:
Attribute function address. Note that no checking is made so the address returned could be invalid.
This is not a problem since the parsing code did the right job.
--*/
{
if (AttributeIdx == -1) {
return &pAlwaysFalseAttribute;
}
return g_AttributeFunctions[AttributeIdx].AttributeFunction;
}
INT
MigDb_GetAttributeIdx (
IN PCTSTR AttributeName
)
/*++
Routine Description:
MigDb_GetAttributeIdx returns the attribute index based on the attribute name
Arguments:
AttributeName - Attribute name.
Return value:
Attribute index. If the name is not found, the index returned is -1.
--*/
{
PATTRIBUTE_STRUCT p = g_AttributeFunctions;
INT i = 0;
while (p->AttributeName != NULL) {
if (StringIMatch (p->AttributeName, AttributeName)) {
return i;
}
p++;
i++;
}
return -1;
}
PCTSTR
MigDb_GetAttributeName (
IN INT AttributeIdx
)
/*++
Routine Description:
MigDb_GetAttributeName returns the name of an attribute based on the attribute index
Arguments:
AttributeIdx - Attribute index.
Return value:
Attribute name. Note that no checking is made so the returned pointer could be invalid.
This is not a problem since the parsing code did the right job.
--*/
{
if (AttributeIdx == -1) {
return TEXT("nul");
}
return g_AttributeFunctions[AttributeIdx].AttributeName;
}
UINT
MigDb_GetReqArgCount (
IN INT AttributeIndex
)
/*++
Routine Description:
MigDb_GetReqArgCount is called by the migdb parser to get the required
argument count. When the parser sees arguments that lack the required
arguments, it skips them.
Arguments:
Index - Specifies the argument index
Return Value:
The required argument count, which can be zero or more.
--*/
{
if (AttributeIndex == -1) {
return 0;
}
return g_AttributeFunctions[AttributeIndex].RequiredArgs;
}
ULONGLONG
GetBinFileVer (
IN PCTSTR FileName
)
{
VRVALUE_ENUM Version;
ULONGLONG result = 0;
if (VrCreateEnumStruct (&Version, FileName)) {
result = VrGetBinaryFileVersion (&Version);
VrDestroyEnumStruct (&Version);
}
return result;
}
ULONGLONG
GetBinProductVer (
IN PCTSTR FileName
)
{
VRVALUE_ENUM Version;
ULONGLONG result = 0;
if (VrCreateEnumStruct (&Version, FileName)) {
result = VrGetBinaryProductVersion (&Version);
VrDestroyEnumStruct (&Version);
}
return result;
}
DWORD
GetFileDateHi (
IN PCTSTR FileName
)
{
VRVALUE_ENUM Version;
DWORD result = 0;
if (VrCreateEnumStruct (&Version, FileName)) {
result = VrGetBinaryFileDateHi (&Version);
VrDestroyEnumStruct (&Version);
}
return result;
}
DWORD
GetFileDateLo (
IN PCTSTR FileName
)
{
VRVALUE_ENUM Version;
DWORD result = 0;
if (VrCreateEnumStruct (&Version, FileName)) {
result = VrGetBinaryFileDateLo (&Version);
VrDestroyEnumStruct (&Version);
}
return result;
}
DWORD
GetFileVerOs (
IN PCTSTR FileName
)
{
VRVALUE_ENUM Version;
DWORD result = 0;
if (VrCreateEnumStruct (&Version, FileName)) {
result = VrGetBinaryOsVersion (&Version);
VrDestroyEnumStruct (&Version);
}
return result;
}
DWORD
GetFileVerType (
IN PCTSTR FileName
)
{
VRVALUE_ENUM Version;
DWORD result = 0;
if (VrCreateEnumStruct (&Version, FileName)) {
result = VrGetBinaryFileType (&Version);
VrDestroyEnumStruct (&Version);
}
return result;
}
/*++
CompanyName, FileDescription, FileVersion, InternalName, LegalCopyright, OriginalFilename,
ProductName, ProductVersion are attribute functions that are querying the version structure
for their specific entries. They all return TRUE if the specific entry has specific value,
FALSE otherwise.
--*/
BOOL
CompanyName (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("CompanyName"), Args);
}
BOOL
FileDescription (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("FileDescription"), Args);
}
BOOL
FileVersion (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("FileVersion"), Args);
}
BOOL
InternalName (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("InternalName"), Args);
}
BOOL
LegalCopyright (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("LegalCopyright"), Args);
}
BOOL
OriginalFilename (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("OriginalFilename"), Args);
}
BOOL
ProductName (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("ProductName"), Args);
}
BOOL
ProductVersion (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("ProductVersion"), Args);
}
BOOL
FileSize (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
/*++
Routine Description:
FileSize checks for the size of a file.
Arguments:
Params - See definition.
Args - MultiSz. First Sz is the file size we need to check.
Return value:
TRUE - the file size matches Args
FALSE - otherwise
--*/
{
DWORD fileSize;
_stscanf (Args, TEXT("%lx"), &fileSize);
if (fileSize == AttribParams->FileParams->FindData->nFileSizeLow) {
return TRUE;
}
else {
return (_ttoi64 (Args) == AttribParams->FileParams->FindData->nFileSizeLow);
}
}
BOOL
IsMsBinary (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
/*++
Routine Description:
IsMsBinary checks to see if a certain file is Microsoft stuff. For 32 bit modules
we query CompanyName for "Microsoft" somewhere inside. For other modules we are
relying on InWinDir attribute
Arguments:
Params - See definition.
Args - MultiSz. Not used.
Return value:
TRUE - the file is MS stuff
FALSE - otherwise
--*/
{
return VrCheckFileVersion (AttribParams->FileParams->NativeObjectName, TEXT("CompanyName"), TEXT("*Microsoft*"));
}
BOOL
CheckSum (
PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
/*++
Routine Description:
CheckSum returns TRUE if file's checksum equals the value in Args
Arguments:
Params - See definition.
Args - checksum value.
Return value:
TRUE - the file's checksum equals the value in Args
FALSE - otherwise
--*/
{
UINT checkSum = 0;
UINT oldSum = 0;
checkSum = MdGetCheckSum (AttribParams->FileParams->NativeObjectName);
_stscanf (Args, TEXT("%lx"), &oldSum);
if (oldSum == checkSum) {
return TRUE;
}
else {
return (_ttoi64 (Args) == checkSum);
}
}
BOOL
SizeCheckSum (
PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
/*++
Routine Description:
Returns TRUE if file's size equals first arg and checksum equals to the second arg
Arguments:
Params - See definition.
Args - checksum value.
Return value:
TRUE - the file's checksum equals the value in Args
FALSE - otherwise
--*/
{
PCTSTR currArg = Args;
if (!FileSize (AttribParams, currArg)) {
return FALSE;
}
currArg = GetEndOfString (currArg);
if (!currArg) {
return FALSE;
}
currArg = _tcsinc (currArg);
if (!currArg) {
return FALSE;
}
return (CheckSum (AttribParams, currArg));
}
PTSTR g_ExeTypes[] = {
TEXT("NONE"),
TEXT("DOS"),
TEXT("WIN16"),
TEXT("WIN32")
};
BOOL
ExeType (
PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
/*++
Routine Description:
ExeType returns TRUE if file's type is according with Args. This can be:
NONE, DOS, WIN16, WIN32
Arguments:
Params - See definition.
Args - type of module.
Return value:
TRUE - the file's type is the same as Args
FALSE - otherwise
--*/
{
return IsPatternMatch (Args, g_ExeTypes[MdGetModuleType (AttribParams->FileParams->NativeObjectName)]);
}
BOOL
Description (
PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
/*++
Routine Description:
Description returns TRUE if file's description matches Args
Arguments:
Params - See definition.
Args - description
Return value:
TRUE - the file's description matches Args
FALSE - otherwise
--*/
{
PCTSTR descr = NULL;
BOOL result = FALSE;
descr = MdGet16ModuleDescription (AttribParams->FileParams->NativeObjectName);
if (descr != NULL) {
result = IsPatternMatch (Args, descr);
FreePathString (descr);
}
return result;
}
BOOL
HasVersion (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
/*++
Routine Description:
HasVersion determines if a file has any entries in its version
stamp.
Arguments:
Params - Specifies the helper params that give the files to test.
Args - Unused
Return Value:
TRUE if the specified file has an entry in its version stamp,
FALSE otherwsie.
--*/
{
VRVALUE_ENUM Version;
BOOL Result = FALSE;
if (VrCreateEnumStruct (&Version, AttribParams->FileParams->NativeObjectName)) {
Result = TRUE;
VrDestroyEnumStruct (&Version);
}
return Result;
}
BOOL
pHexMatch (
IN DWORD NewValue,
IN PCTSTR Args
)
{
DWORD oldValue;
_stscanf (Args, TEXT("%lx"), &oldValue);
if (oldValue == NewValue) {
return TRUE;
}
else {
return (_ttoi64 (Args) == NewValue);
}
}
BOOL
pConvertDotStringToValue (
IN PCTSTR String,
OUT ULONGLONG *Value
)
{
PWORD valueIdx;
UINT index;
valueIdx = (PWORD) Value + 3;
for (index = 0 ; index < 4 ; index++) {
if (*String == 0) {
*valueIdx = 0xFFFF;
valueIdx--;
continue;
}
*valueIdx = (WORD) _tcstoul (String, &(PTSTR) String, 10);
if (*String && (_tcsnextc (String) != TEXT('.'))) {
return FALSE;
}
String = _tcsinc (String);
valueIdx--;
}
return TRUE;
}
BOOL
pMaskHexMatch (
IN ULONGLONG NewValue,
IN PCTSTR Args
)
{
ULONGLONG oldValue = 0;
ULONGLONG mask = 0;
PWORD maskIdx;
PWORD valueIdx;
UINT index;
maskIdx = (PWORD)&mask + 3;
valueIdx = (PWORD)&oldValue + 3;
index = 0;
while (Args && *Args) {
if (index >= 4) {
return FALSE;
}
*valueIdx = (WORD) _tcstoul ((PTSTR)Args, &((PTSTR)Args), 10);
if (*Args) {
if (_tcsnextc (Args) != TEXT('.')) {
return FALSE;
}
Args = _tcsinc (Args);
}
*maskIdx = 65535;
valueIdx--;
maskIdx--;
index++;
}
NewValue = NewValue & mask;
return (oldValue == NewValue);
}
BOOL
BinFileVer (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return pMaskHexMatch (GetBinFileVer (AttribParams->FileParams->NativeObjectName), Args);
}
BOOL
BinProductVer (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return pMaskHexMatch (GetBinProductVer (AttribParams->FileParams->NativeObjectName), Args);
}
BOOL
FileDateHi (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return pHexMatch (GetFileDateHi (AttribParams->FileParams->NativeObjectName), Args);
}
BOOL
FileDateLo (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return pHexMatch (GetFileDateLo (AttribParams->FileParams->NativeObjectName), Args);
}
BOOL
FileVerOs (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return pHexMatch (GetFileVerOs (AttribParams->FileParams->NativeObjectName), Args);
}
BOOL
FileVerType (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
return pHexMatch (GetFileVerType (AttribParams->FileParams->NativeObjectName), Args);
}
BOOL
UpToBinProductVer (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
VRVALUE_ENUM Version;
ULONGLONG versionStampValue = 0;
ULONGLONG maxValue;
if (VrCreateEnumStruct (&Version, AttribParams->FileParams->NativeObjectName)) {
versionStampValue = VrGetBinaryProductVersion (&Version);
VrDestroyEnumStruct (&Version);
} else {
return FALSE;
}
if (!pConvertDotStringToValue (Args, &maxValue)) {
DEBUGMSG ((DBG_WHOOPS, "Invalid value of %s caused UpToBinProductVer to fail", Args));
return FALSE;
}
return versionStampValue <= maxValue;
}
BOOL
UpToBinFileVer (
IN PDBATTRIB_PARAMS AttribParams,
IN PCTSTR Args
)
{
VRVALUE_ENUM Version;
ULONGLONG versionStampValue = 0;
ULONGLONG maxValue;
if (VrCreateEnumStruct (&Version, AttribParams->FileParams->NativeObjectName)) {
versionStampValue = VrGetBinaryFileVersion (&Version);
VrDestroyEnumStruct (&Version);
} else {
return FALSE;
}
if (!pConvertDotStringToValue (Args, &maxValue)) {
DEBUGMSG ((DBG_WHOOPS, "Invalid value of %s caused UpToBinFileVer to fail", Args));
return FALSE;
}
return versionStampValue <= maxValue;
}