windows-nt/Source/XPSP1/NT/ds/security/cryptoapi/pkitrust/mscat32/mscatctl.cpp

911 lines
23 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: mscatctl.cpp
//
// Contents: Microsoft Internet Security Catalog Utilities
// implements the Certificate Trust List & persistent storage
//
// Functions: CatalogLoadFileData
// CatalogSaveP7UData
// CatalogSaveP7SData
// IsCatalogFile
//
// *** local functions ***
// CatalogLoadData
// CatalogFillCatStore
// CatalogFillCTL
// CatalogFillCTLAttr
// CatalogFreeCTL
// CatalogFreeCTLAttr
// CatalogFillCatMember
// CatalogFillMemAttr
// CatalogFillCatAttr
// CatalogFillCatLevelAttr
//
// History: 05-May-1997 pberkman created
//
//--------------------------------------------------------------------------
#include "global.hxx"
#include "mscat32.h"
//
// for each member, we have at minimum two authenticated attributes.
// 1 = Indirect Data
// 2 = Subject Guid
//
#define CAT_RESERVE_CTL_ATTR 2
// WARNING: this function allocates pbData -- you must delete!
BOOL CatalogLoadData(WCHAR *pwszCatFile, DWORD *cbData, BYTE **pbData);
BOOL CatalogFillCatStore(CRYPTCATSTORE *pCat, PCTL_INFO pCTLInfo);
BOOL CatalogFreeCTL(CTL_INFO *pCTL);
BOOL CatalogFreeCTLAttr(CRYPT_ATTRIBUTE *pCryptAttr);
BOOL CatalogFillCTL(CRYPTCATSTORE *pCat, CTL_INFO *pCTL);
BOOL CatalogFillCatAttr(CRYPTCATSTORE *pCat, CERT_EXTENSION *pAttr);
BOOL CatalogFillCatLevelAttr(CRYPTCATSTORE *pCatStore, CRYPTCATATTRIBUTE *pAttr,
CERT_EXTENSION *pCertAttr);
BOOL CatalogFillCTLAttr(CRYPTCATSTORE *pCatStore, CRYPTCATATTRIBUTE *pAttr,
PCRYPT_ATTRIBUTE pCryptAttr);
CRYPTCATMEMBER *CatalogFillCatMember(CRYPTCATSTORE *pCat, CTL_ENTRY *pEntry);
BOOL CatalogFillMemAttr(CRYPTCATSTORE *pCat, CRYPTCATMEMBER *pMember, CRYPT_ATTRIBUTE *pAttr);
static const char *pszOID = szOID_CATALOG_LIST;
BOOL CatalogLoadFileData(CRYPTCATSTORE *pCat)
{
BOOL fRet;
DWORD cbData;
BYTE *pbData;
cbData = 0;
pbData = NULL;
if (!(CatalogLoadData(pCat->pwszP7File, &cbData, &pbData)))
{
return(FALSE);
}
if (cbData < 1)
{
if (pbData)
{
UnmapViewOfFile(pbData);
}
//
// not signed and we are probably creating it!
//
return(TRUE);
}
PCCTL_CONTEXT pCTLContext;
pCTLContext = (PCCTL_CONTEXT) CertCreateContext(
CERT_STORE_CTL_CONTEXT,
pCat->dwEncodingType,
pbData,
cbData,
CERT_CREATE_CONTEXT_NOCOPY_FLAG |
CERT_CREATE_CONTEXT_NO_HCRYPTMSG_FLAG,
NULL // pCreatePara
);
if (pCTLContext)
{
//
// got it... fill our arrays!
//
fRet = CatalogFillCatStore(pCat, pCTLContext->pCtlInfo);
CertFreeCTLContext(pCTLContext);
} else
fRet = FALSE;
UnmapViewOfFile(pbData);
return(fRet);
}
BOOL CatalogSaveP7SData(CRYPTCATSTORE *pCat, CTL_CONTEXT *pCTLContext)
{
assert(0); // should never be called!
return(TRUE);
}
BOOL CatalogSaveP7UData(CRYPTCATSTORE *pCat)
{
CMSG_SIGNED_ENCODE_INFO sSignInfo;
CTL_INFO sCTLInfo;
DWORD cbEncoded;
BYTE *pbEncoded;
Stack_ *pStack;
//
// sort the data...
//
if (pCat->hReserved) // member stack_
{
pStack = (Stack_ *)pCat->hReserved;
pStack->Sort(WVT_OFFSETOF(CRYPTCATMEMBER, pwszReferenceTag), sizeof(WCHAR *), STACK_SORTTYPE_PWSZ);
}
memset(&sSignInfo, 0x00, sizeof(CMSG_SIGNED_ENCODE_INFO));
sSignInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
if (CatalogFillCTL(pCat, &sCTLInfo))
{
cbEncoded = 0;
CryptMsgEncodeAndSignCTL( pCat->dwEncodingType,
&sCTLInfo,
&sSignInfo,
0,
NULL,
&cbEncoded);
if (cbEncoded > 0)
{
BOOL fRet;
if (!(pbEncoded = (BYTE *)CatalogNew(cbEncoded)))
{
CatalogFreeCTL(&sCTLInfo);
return(FALSE);
}
fRet = CryptMsgEncodeAndSignCTL( pCat->dwEncodingType,
&sCTLInfo,
&sSignInfo,
0,
pbEncoded,
&cbEncoded);
CatalogFreeCTL(&sCTLInfo);
if (fRet)
{
HANDLE hFile;
DWORD lErr;
lErr = GetLastError();
if ((hFile = CreateFileU(pCat->pwszP7File,
GENERIC_WRITE | GENERIC_READ,
0, // no sharing!!
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL)) != INVALID_HANDLE_VALUE)
{
DWORD cbWritten;
if (!(WriteFile(hFile, pbEncoded, cbEncoded, &cbWritten, NULL)) ||
(cbEncoded != cbWritten))
{
fRet = FALSE;
}
CloseHandle(hFile);
if (fRet)
{
SetLastError(lErr);
}
}
}
delete pbEncoded;
return(fRet);
}
CatalogFreeCTL(&sCTLInfo);
}
return(FALSE);
}
BOOL CatalogLoadData(WCHAR *pwszCatFile, DWORD *cbData, BYTE **pbData)
{
HANDLE hFile;
*cbData = 0;
if ((hFile = CreateFileU(pwszCatFile,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
NULL)) == INVALID_HANDLE_VALUE)
{
return(FALSE);
}
if ((*cbData = GetFileSize(hFile, NULL)) == 0xffffffff)
{
*cbData = 0;
CloseHandle(hFile);
return(FALSE);
}
if (*cbData < 10)
{
//
// just created file....
//
*cbData = 0;
CloseHandle(hFile);
return(TRUE);
}
HANDLE hMappedFile;
hMappedFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (!(hMappedFile) || (hMappedFile == INVALID_HANDLE_VALUE))
{
*cbData = 0;
CloseHandle(hFile);
return(FALSE);
}
*pbData = (BYTE *)MapViewOfFile(hMappedFile, FILE_MAP_READ, 0, 0, 0);
CloseHandle(hMappedFile);
CloseHandle(hFile);
if ((*pbData) == NULL)
{
return(FALSE);
}
return(TRUE);
}
BOOL CatalogFillCatStore(CRYPTCATSTORE *pCat, CTL_INFO *pCTL)
{
int iAttr;
if (pCTL->cCTLEntry > 0)
{
for (iAttr = 0; iAttr < (int)pCTL->cExtension; iAttr++)
{
if (!(CatalogFillCatAttr(pCat, &pCTL->rgExtension[iAttr])))
{
return(FALSE);
}
}
CRYPTCATMEMBER *pMember;
for (int iEntry = 0; iEntry < (int)pCTL->cCTLEntry; iEntry++)
{
pMember = CatalogFillCatMember(pCat, &pCTL->rgCTLEntry[iEntry]);
if (!(pMember))
{
return(FALSE);
}
if (pCTL->rgCTLEntry[iEntry].cAttribute > 0)
{
for (iAttr = 0; iAttr < (int)pCTL->rgCTLEntry[iEntry].cAttribute; iAttr++)
{
if (!(CatalogFillMemAttr(pCat, pMember,
&pCTL->rgCTLEntry[iEntry].rgAttribute[iAttr])))
{
return(FALSE);
}
}
}
}
return(TRUE);
}
return(TRUE);
}
CRYPTCATMEMBER *CatalogFillCatMember(CRYPTCATSTORE *pCat, CTL_ENTRY *pEntry)
{
if (!(pEntry))
{
return(NULL);
}
Stack_ *pStack;
CRYPTCATMEMBER *pCatMember;
if (!(pCat->hReserved))
{
pStack = new Stack_(&MSCAT_CriticalSection);
if (!(pStack))
{
assert(0);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return(NULL);
}
pCat->hReserved = (HANDLE)pStack;
}
pStack = (Stack_ *)pCat->hReserved;
if (!(pCatMember = (CRYPTCATMEMBER *)pStack->Add(sizeof(CRYPTCATMEMBER))))
{
return(NULL);
}
memset(pCatMember, 0x00, sizeof(CRYPTCATMEMBER));
pCatMember->cbStruct = sizeof(CRYPTCATMEMBER);
// pwszFileName
// pwszReferenceTag
if (!(pCatMember->pwszReferenceTag = (LPWSTR)CatalogNew(pEntry->SubjectIdentifier.cbData)))
{
return(NULL);
}
memcpy(pCatMember->pwszReferenceTag, pEntry->SubjectIdentifier.pbData,
pEntry->SubjectIdentifier.cbData);
// pIndirectData (will be filled in while getting attributes!
// gSubjectType (will be filled in while getting attributes!
return(pCatMember);
}
BOOL CatalogFillCatAttr(CRYPTCATSTORE *pCat, CERT_EXTENSION *pAttr)
{
if (!(pAttr))
{
return(FALSE);
}
Stack_ *pStack;
CRYPTCATATTRIBUTE *pCatAttr;
if (!(pCat->hAttrs))
{
pStack = new Stack_(&MSCAT_CriticalSection);
if (!(pStack))
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return(FALSE);
}
pCat->hAttrs = (HANDLE)pStack;
}
pStack = (Stack_ *)pCat->hAttrs;
if (!(pCatAttr = (CRYPTCATATTRIBUTE *)pStack->Add(sizeof(CRYPTCATATTRIBUTE))))
{
return(FALSE);
}
memset(pCatAttr, 0x00, sizeof(CRYPTCATATTRIBUTE));
pCatAttr->cbStruct = sizeof(CRYPTCATATTRIBUTE);
CRYPT_ATTRIBUTE sCryptAttr;
CatalogCertExt2CryptAttr(pAttr, &sCryptAttr);
if (!(CatalogDecodeNameValue(pCat, &sCryptAttr, pCatAttr)))
{
return(FALSE);
}
return(TRUE);
}
BOOL CatalogFillMemAttr(CRYPTCATSTORE *pCat, CRYPTCATMEMBER *pMember, CRYPT_ATTRIBUTE *pAttr)
{
if (!(pAttr))
{
return(FALSE);
}
if (strcmp(pAttr->pszObjId, SPC_INDIRECT_DATA_OBJID) == 0)
{
return(CatalogDecodeIndirectData(pCat, pMember, pAttr));
}
if (strcmp(pAttr->pszObjId, CAT_MEMBERINFO_OBJID) == 0)
{
return(CatalogDecodeMemberInfo(pCat, pMember, pAttr));
}
Stack_ *pStack;
CRYPTCATATTRIBUTE *pCatAttr;
if (!(pMember->hReserved))
{
pStack = new Stack_(&MSCAT_CriticalSection);
if (!(pStack))
{
assert(0);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return(FALSE);
}
pMember->hReserved = (HANDLE)pStack;
}
pStack = (Stack_ *)pMember->hReserved;
if (!(pCatAttr = (CRYPTCATATTRIBUTE *)pStack->Add(sizeof(CRYPTCATATTRIBUTE))))
{
return(FALSE);
}
memset(pCatAttr, 0x00, sizeof(CRYPTCATATTRIBUTE));
pCatAttr->cbStruct = sizeof(CRYPTCATATTRIBUTE);
if (!(CatalogDecodeNameValue(pCat, pAttr, pCatAttr)))
{
return(FALSE);
}
return(TRUE);
}
BOOL CatalogFillCTL(CRYPTCATSTORE *pCat, CTL_INFO *pCTL)
{
typedef HRESULT (WINAPI *pfnCoCreateGuid)(GUID FAR *pguid);
HINSTANCE hOLE;
pfnCoCreateGuid pfnCreateGuid;
memset(pCTL, 0x00, sizeof(CTL_INFO));
// dwVersion
pCTL->dwVersion = CTL_V1;
// SubjectUsage
pCTL->SubjectUsage.cUsageIdentifier = 1;
pCTL->SubjectUsage.rgpszUsageIdentifier = (char **)&pszOID;
// ListIdentifier
if (hOLE = LoadLibraryA("OLE32.DLL"))
{
if (pfnCreateGuid = (pfnCoCreateGuid)GetProcAddress(hOLE, "CoCreateGuid"))
{
if (pCTL->ListIdentifier.pbData = (BYTE *)CatalogNew(sizeof(GUID)))
{
pCTL->ListIdentifier.cbData = sizeof(GUID);
(*pfnCreateGuid)((GUID *)pCTL->ListIdentifier.pbData);
}
}
FreeLibrary(hOLE);
}
// SequenceNumber
// optional!
// ThisUpdate
GetSystemTimeAsFileTime(&pCTL->ThisUpdate);
// NextUpdate
// optional!
// SubjectAlgorithm
pCTL->SubjectAlgorithm.pszObjId = szOID_CATALOG_LIST_MEMBER;
Stack_ *pStackMember;
Stack_ *pStackAttr;
CRYPTCATMEMBER *pMember;
CRYPTCATATTRIBUTE *pAttr;
DWORD dwAttr;
// cCTLEntry & rgCTLEntry
if (pCat->hReserved)
{
pStackMember = (Stack_ *)pCat->hReserved;
// cCTLEntry
pCTL->cCTLEntry = pStackMember->Count();
if (pCTL->cCTLEntry > 0)
{
if (!(pCTL->rgCTLEntry = (PCTL_ENTRY)CatalogNew(sizeof(CTL_ENTRY) *
pStackMember->Count())))
{
return(FALSE);
}
memset(pCTL->rgCTLEntry, 0x00, sizeof(CTL_ENTRY) * pStackMember->Count());
}
DWORD dwMember;
DWORD dwSize;
CTL_ENTRY *pCTLEntry;
//
// copy the members to the ctl_entry
//
dwMember = 0;
while (dwMember < pStackMember->Count())
{
if (!(pMember = (CRYPTCATMEMBER *)pStackMember->Get(dwMember)))
{
return(FALSE);
}
//
// Subject Identifier
//
dwSize = (wcslen(pMember->pwszReferenceTag) + 1) * sizeof(WCHAR);
pCTLEntry = &pCTL->rgCTLEntry[dwMember];
if (!(pCTLEntry->SubjectIdentifier.pbData =
(BYTE *)CatalogNew(dwSize)))
{
return(FALSE);
}
memcpy(pCTLEntry->SubjectIdentifier.pbData,
pMember->pwszReferenceTag,dwSize);
pCTLEntry->SubjectIdentifier.cbData = dwSize;
//
// rgAttribute
// +1 for Indirect Data
// +1 for Subject Guid
//
if (pMember->hReserved)
{
pStackAttr = (Stack_ *)pMember->hReserved;
pCTLEntry->cAttribute = pStackAttr->Count() + CAT_RESERVE_CTL_ATTR;
}
else
{
pCTLEntry->cAttribute = CAT_RESERVE_CTL_ATTR;
}
if (!(pCTLEntry->rgAttribute =
(PCRYPT_ATTRIBUTE)CatalogNew(sizeof(CRYPT_ATTRIBUTE) *
pCTLEntry->cAttribute)))
{
return(FALSE);
}
memset(pCTLEntry->rgAttribute, 0x00,
sizeof(CRYPT_ATTRIBUTE) * pCTLEntry->cAttribute);
//
// put our indirect data in an authenticated attribute
//
if (!(pMember->pIndirectData))
{
CatalogReallyDecodeIndirectData(pCat, pMember, &pMember->sEncodedIndirectData);
}
CatalogEncodeIndirectData(pCat, pMember, &pCTLEntry->rgAttribute[0]);
//
// put our subject guid in an authenticated attribute
//
if ((pMember->gSubjectType.Data1 == 0) &&
(pMember->gSubjectType.Data2 == 0) &&
(pMember->gSubjectType.Data3 == 0))
{
CatalogReallyDecodeMemberInfo(pCat, pMember, &pMember->sEncodedMemberInfo);
}
CatalogEncodeMemberInfo(pCat, pMember, &pCTLEntry->rgAttribute[1]);
if (pMember->hReserved)
{
dwAttr = 0;
while (dwAttr < pStackAttr->Count())
{
pAttr = (CRYPTCATATTRIBUTE *)pStackAttr->Get(dwAttr);
CatalogFillCTLAttr(pCat, pAttr,
&pCTLEntry->rgAttribute[dwAttr + CAT_RESERVE_CTL_ATTR]);
//
// increment our attribute counter!
//
dwAttr++;
}
}
//
// increment our member counter!
//
dwMember++;
}
}
//
// cExtension
// rgExtension
//
if (pCat->hAttrs)
{
pStackAttr = (Stack_ *)pCat->hAttrs;
pCTL->cExtension = pStackAttr->Count();
if (!(pCTL->rgExtension =
(CERT_EXTENSION *)CatalogNew(sizeof(CERT_EXTENSION) * pCTL->cExtension)))
{
return(FALSE);
}
memset(pCTL->rgExtension, 0x00, sizeof(CERT_EXTENSION) * pCTL->cExtension);
dwAttr = 0;
while (dwAttr < pStackAttr->Count())
{
pAttr = (CRYPTCATATTRIBUTE *)pStackAttr->Get(dwAttr);
if (pAttr)
{
CatalogFillCatLevelAttr(pCat, pAttr, &pCTL->rgExtension[dwAttr]);
}
dwAttr++;
}
}
return(TRUE);
}
BOOL CatalogFillCatLevelAttr(CRYPTCATSTORE *pCatStore, CRYPTCATATTRIBUTE *pAttr, CERT_EXTENSION *pCertAttr)
{
CRYPT_ATTR_BLOB sAttrBlob;
CRYPT_ATTRIBUTE sCryptAttr;
memset(&sAttrBlob, 0x00, sizeof(CRYPT_ATTR_BLOB));
memset(&sCryptAttr, 0x00, sizeof(CRYPT_ATTRIBUTE));
sCryptAttr.cValue = 1;
sCryptAttr.rgValue = &sAttrBlob;
if (!(CatalogEncodeNameValue(pCatStore, pAttr, &sCryptAttr)))
{
return(FALSE);
}
CatalogCryptAttr2CertExt(&sCryptAttr, pCertAttr);
return(TRUE);
}
BOOL CatalogFillCTLAttr(CRYPTCATSTORE *pCatStore, CRYPTCATATTRIBUTE *pAttr, PCRYPT_ATTRIBUTE pCryptAttr)
{
if (!(pCryptAttr->rgValue = (PCRYPT_ATTR_BLOB)CatalogNew(sizeof(CRYPT_ATTR_BLOB))))
{
return(FALSE);
}
pCryptAttr->cValue = 1;
memset(pCryptAttr->rgValue, 0x00, sizeof(CRYPT_ATTR_BLOB));
if (!(CatalogEncodeNameValue(pCatStore, pAttr, pCryptAttr)))
{
return(FALSE);
}
return(TRUE);
}
BOOL CatalogFreeCTL(CTL_INFO *pCTL)
{
DWORD dwEntries;
DWORD dwAttributes;
CTL_ENTRY *pCTLEntry;
DELETE_OBJECT(pCTL->ListIdentifier.pbData);
dwEntries = pCTL->cCTLEntry;
while (dwEntries > 0)
{
pCTLEntry = &pCTL->rgCTLEntry[dwEntries - 1];
DELETE_OBJECT(pCTLEntry->SubjectIdentifier.pbData);
dwAttributes = pCTLEntry->cAttribute;
while (dwAttributes > 0)
{
CatalogFreeCTLAttr(&pCTLEntry->rgAttribute[dwAttributes - 1]);
dwAttributes--;
}
DELETE_OBJECT(pCTLEntry->rgAttribute);
dwEntries--;
}
DELETE_OBJECT(pCTL->rgCTLEntry);
for (dwEntries = 0; dwEntries < pCTL->cExtension; dwEntries++)
{
DELETE_OBJECT(pCTL->rgExtension[dwEntries].Value.pbData);
}
DELETE_OBJECT(pCTL->rgExtension);
return(TRUE);
}
BOOL CatalogFreeCTLAttr(CRYPT_ATTRIBUTE *pCryptAttr)
{
if (!(pCryptAttr))
{
return(FALSE);
}
if (pCryptAttr->rgValue)
{
DELETE_OBJECT(pCryptAttr->rgValue->pbData);
DELETE_OBJECT(pCryptAttr->rgValue);
}
return(TRUE);
}
BOOL WINAPI IsCatalogFile(HANDLE hFile, WCHAR *pwszCatalogFile)
{
char *pszCatalogListUsageOID = szOID_CATALOG_LIST;
BOOL fCloseFile;
BOOL fRet;
DWORD cbRead;
DWORD cbFile;
BYTE *pbFile;
PCCTL_CONTEXT pCTLContext;
//
// put a try-except around everything in case there is problems with the
// memory mapped file
//
__try {
pCTLContext = NULL;
pbFile = NULL;
fCloseFile = FALSE;
fRet = FALSE;
if ((hFile == NULL) || (hFile == INVALID_HANDLE_VALUE))
{
if (!(pwszCatalogFile))
{
goto IsCatInvalidParam;
}
if ((hFile = CreateFileU(pwszCatalogFile, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
NULL)) == INVALID_HANDLE_VALUE)
{
goto IsCatFileError;
}
fCloseFile = TRUE;
}
HANDLE hMappedFile;
hMappedFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (!(hMappedFile) || (hMappedFile == INVALID_HANDLE_VALUE))
{
goto CreateFileMapFailed;
}
pbFile = (BYTE *)MapViewOfFile(hMappedFile, FILE_MAP_READ, 0, 0, 0);
CloseHandle(hMappedFile);
if (!(pbFile))
{
goto MapViewFailed;
}
if (((cbFile = GetFileSize(hFile, NULL)) == 0xffffffff) ||
(cbFile < 1))
{
goto FileSizeError;
}
if (pbFile[0] != (BYTE)0x30)
{
goto IsCatNotCatalog;
}
pCTLContext = (PCCTL_CONTEXT) CertCreateContext(
CERT_STORE_CTL_CONTEXT,
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
pbFile,
cbFile,
CERT_CREATE_CONTEXT_NOCOPY_FLAG |
CERT_CREATE_CONTEXT_NO_HCRYPTMSG_FLAG |
CERT_CREATE_CONTEXT_NO_ENTRY_FLAG,
NULL // pCreatePara
);
if (pCTLContext)
{
if (pCTLContext->pCtlInfo->SubjectUsage.cUsageIdentifier)
{
if (strcmp(pCTLContext->pCtlInfo->SubjectUsage.rgpszUsageIdentifier[0],
pszCatalogListUsageOID) == 0)
{
fRet = TRUE;
goto CommonReturn;
}
}
}
goto IsCatNotCatalog;
} __except(EXCEPTION_EXECUTE_HANDLER) {
SetLastError(GetExceptionCode());
goto ErrorReturn;
}
CommonReturn:
if (pCTLContext)
{
CertFreeCTLContext(pCTLContext);
}
if (pbFile)
{
UnmapViewOfFile(pbFile);
}
if (fCloseFile)
{
CloseHandle(hFile);
}
return(fRet);
ErrorReturn:
fRet = FALSE;
goto CommonReturn;
TRACE_ERROR_EX(DBG_SS, IsCatNotCatalog);
TRACE_ERROR_EX(DBG_SS, IsCatFileError);
TRACE_ERROR_EX(DBG_SS, CreateFileMapFailed);
TRACE_ERROR_EX(DBG_SS, MapViewFailed);
SET_ERROR_VAR_EX(DBG_SS, IsCatInvalidParam, ERROR_INVALID_PARAMETER);
SET_ERROR_VAR_EX(DBG_SS, FileSizeError, ERROR_INVALID_PARAMETER);
}