|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: makecat.cpp
//
// Contents: Microsoft Internet Security Catalog Utilities
//
// Functions: wmain
//
// History: 05-May-1997 pberkman created
//
//--------------------------------------------------------------------------
#include <stdio.h>
#include <windows.h>
#include <io.h>
#include <wchar.h>
#include "unicode.h"
#include "wincrypt.h"
#include "wintrust.h"
#include "mssip.h"
#include "mscat.h"
#include "dbgdef.h"
#include "gendefs.h"
#include "printfu.hxx"
#include "cwargv.hxx"
#include "resource.h"
BOOL fVerbose = FALSE; BOOL fFailAllErrors = FALSE; BOOL fParseError = FALSE; BOOL fTesting = FALSE; DWORD dwExpectedError = 0;
WCHAR *pwszCDFFile = NULL; PrintfU_ *pPrint = NULL;
int iRet = 0;
void WINAPI DisplayParseError(DWORD dwErrorArea, DWORD dwLocalError, WCHAR *wszName);
extern "C" CRYPTCATATTRIBUTE * WINAPI CryptCATCDFEnumAttributesWithCDFTag(CRYPTCATCDF *pCDF, LPWSTR pwszMemberTag, CRYPTCATMEMBER *pMember, CRYPTCATATTRIBUTE *pPrevAttr, PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError);
extern "C" LPWSTR WINAPI CryptCATCDFEnumMembersByCDFTagEx(CRYPTCATCDF *pCDF, LPWSTR pwszPrevCDFTag, PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError, CRYPTCATMEMBER** ppMember, BOOL fContinueOnError, LPVOID pvReserved);
#define DEFAULT_STRING_BUFFER_SIZE 20
char szDefaultBuffer[DEFAULT_STRING_BUFFER_SIZE];
static LPSTR MakeMBSTR(LPWSTR pwsz, BOOL *pfAlloced) { int numChars = 0; LPSTR pszString = NULL;
numChars = WideCharToMultiByte(0, 0, pwsz, -1, NULL, 0, NULL, NULL);
if ((numChars + 1) > DEFAULT_STRING_BUFFER_SIZE) { pszString = new(char[numChars + 1]); WideCharToMultiByte(0, 0, pwsz, -1, pszString, numChars + 1, NULL, NULL); *pfAlloced = TRUE; return pszString; } else { WideCharToMultiByte(0, 0, pwsz, -1, szDefaultBuffer, numChars + 1, NULL, NULL); *pfAlloced = FALSE; return szDefaultBuffer; } }
extern "C" int __cdecl wmain(int argc, WCHAR **wargv) { int cMember; cWArgv_ *pArgs; BOOL fFailed; CRYPTCATCDF *pCDF; CRYPTCATMEMBER *pMember; LPWSTR pwszMemberTag; CRYPTCATATTRIBUTE *pAttr; BOOL fContinueOnError; LPWSTR pwszOutputFile = NULL; HANDLE hOutputFile = INVALID_HANDLE_VALUE; HANDLE hFile = INVALID_HANDLE_VALUE; BOOL fAlloced; LPSTR psz; DWORD dwMinFileSize = 0; DWORD dwFileSize; BOOL fFileTooSmall = FALSE; DWORD dwBytesWritten;
pCDF = NULL;
if (!(pArgs = new cWArgv_((HINSTANCE)GetModuleHandle(NULL), &fFailed))) { goto MemoryError; }
if (fFailed) { goto MemoryError; }
pArgs->AddUsageText(IDS_USAGETEXT_USAGE, IDS_USAGETEXT_OPTIONS, IDS_USAGETEXT_CMDFILE, IDS_USAGETEXT_ADD, IDS_USAGETEXT_OPTPARAM);
pArgs->Add2List(IDS_PARAM_HELP, IDS_PARAMTEXT_HELP, WARGV_VALUETYPE_BOOL, (void *)FALSE); pArgs->Add2List(IDS_PARAM_VERBOSE, IDS_PARAMTEXT_VERBOSE, WARGV_VALUETYPE_BOOL, (void *)FALSE); pArgs->Add2List(IDS_PARAM_FAILALWAYS, IDS_PARAMTEXT_FAILALWAYS, WARGV_VALUETYPE_BOOL, (void *)FALSE); pArgs->Add2List(IDS_PARAM_EXPERROR, IDS_PARAMTEXT_EXPERROR, WARGV_VALUETYPE_DWORDH, NULL, TRUE); pArgs->Add2List(IDS_PARAM_NOSTOPONERROR, IDS_PARAMTEXT_NOSTOPONERROR, WARGV_VALUETYPE_BOOL, (void *)FALSE); pArgs->Add2List(IDS_PARAM_MINSIZE, IDS_PARAMTEXT_MINSIZE, WARGV_VALUETYPE_DWORDD, (void *)0, FALSE); pArgs->Add2List(IDS_PARAM_OUTPUTFILE, IDS_PARAMTEXT_OUTPUTFILE, WARGV_VALUETYPE_WCHAR, NULL, FALSE);
pArgs->Fill(argc, wargv);
if (!(pArgs->Fill(argc, wargv)) || (pArgs->GetValue(IDS_PARAM_HELP))) { wprintf(L"%s", pArgs->GetUsageString()); goto NeededHelp; }
fVerbose = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_VERBOSE)); fFailAllErrors = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_FAILALWAYS)); fContinueOnError = (BOOL)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_NOSTOPONERROR));
if (pArgs->IsSet(IDS_PARAM_EXPERROR)) { dwExpectedError = (DWORD)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_EXPERROR)); fTesting = TRUE; }
if (pArgs->IsSet(IDS_PARAM_MINSIZE)) { dwMinFileSize = (DWORD)((DWORD_PTR)pArgs->GetValue(IDS_PARAM_MINSIZE)); } if (!(pwszCDFFile = pArgs->GetFileName())) { wprintf(L"%s", pArgs->GetUsageString()); goto ParamError; }
if (pArgs->IsSet(IDS_PARAM_OUTPUTFILE)) { pwszOutputFile = (LPWSTR) pArgs->GetValue(IDS_PARAM_OUTPUTFILE); }
pPrint = new PrintfU_;
if (pPrint == NULL) { goto MemoryError; }
SetLastError(0);
if (!(pCDF = CryptCATCDFOpen(pwszCDFFile, DisplayParseError))) { if (fVerbose) { pPrint->Display(IDS_ERROR_FUNCTION, L"CryptCATCDFOpen", GetLastError()); }
goto CDFOpenError; }
if (fVerbose) { pPrint->Display(IDS_STATUS_FMT, pPrint->get_String(IDS_STATUS_OPENED), pwszCDFFile); }
pAttr = NULL;
while (pAttr = CryptCATCDFEnumCatAttributes(pCDF, pAttr, DisplayParseError)) { if (fVerbose) { pPrint->Display(IDS_STATUS_FMT, pPrint->get_String(IDS_STATUS_ATTR), pAttr->pwszReferenceTag); } }
//
// If we are logging the the catalog members, then create the output file
//
if (pwszOutputFile != NULL) { hOutputFile = CreateFileU( pwszOutputFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOutputFile == INVALID_HANDLE_VALUE) { printf("Error creating %S: %x", pwszOutputFile, GetLastError()); goto ErrorReturn; } }
pMember = NULL; pwszMemberTag = NULL; cMember = 0;
while (pwszMemberTag = CryptCATCDFEnumMembersByCDFTagEx(pCDF, pwszMemberTag, DisplayParseError, &pMember, fContinueOnError, NULL)) { //
// Check for continuable error
//
if (GetLastError() != ERROR_SUCCESS) { if (fVerbose) { pPrint->Display(IDS_ERROR_FUNCTION, L"CryptCATCDFEnumMembersByCDFTagEx", GetLastError()); }
if (fFailAllErrors) { iRet = 1; } continue; }
//
// Log to file
//
if (hOutputFile != INVALID_HANDLE_VALUE) { psz = MakeMBSTR(pMember->pwszFileName, &fAlloced); WriteFile(hOutputFile, psz, strlen(psz), &dwBytesWritten, NULL); if (fAlloced) { delete[]psz; }
WriteFile(hOutputFile, " - ", 3, &dwBytesWritten, NULL);
psz = MakeMBSTR(pMember->pwszReferenceTag, &fAlloced);
WriteFile(hOutputFile, psz, strlen(psz), &dwBytesWritten, NULL); if (fAlloced) { delete[]psz; }
WriteFile(hOutputFile, "\n", strlen("\n"), &dwBytesWritten, NULL); }
//
// If we are checking minimun file sizes:
//
if (dwMinFileSize > 0) { hFile = CreateFileU(pMember->pwszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); if (hFile != INVALID_HANDLE_VALUE) { dwFileSize = GetFileSize(hFile, NULL); // I assume that if this function fails, it is because the file
// size won't fit into one DWORD. If it fails for some other
// reason, a small file may slip through the cracks. Oh well.
if ((dwFileSize < dwMinFileSize) && (dwFileSize != INVALID_FILE_SIZE)) { // The file is too small
fFileTooSmall = TRUE; if (fVerbose) { pPrint->Display(IDS_STATUS_FMT, pPrint->get_String(IDS_STATUS_TOO_SMALL), pMember->pwszFileName); } } CloseHandle(hFile); } else { // Couldn't open file to check file size
if (fVerbose) { pPrint->Display(IDS_ERROR_FUNCTION, L"CreateFile", GetLastError()); } if (fFailAllErrors) { iRet = 1; } } }
if (fVerbose) { pPrint->Display(IDS_STATUS_FMT, pPrint->get_String(IDS_STATUS_PROCESSED), pwszMemberTag); } cMember++;
pAttr = NULL; while (pAttr = CryptCATCDFEnumAttributesWithCDFTag(pCDF, pwszMemberTag, pMember, pAttr, DisplayParseError)) { if (fVerbose) { pPrint->Display(IDS_STATUS_FMT, pPrint->get_String(IDS_STATUS_ATTR), pAttr->pwszReferenceTag); } } }
//
// Check lasterror
//
if (GetLastError() != ERROR_SUCCESS) { if (fVerbose) { pPrint->Display(IDS_ERROR_FUNCTION, L"CryptCATCDFEnumMembersByCDFTagEx", GetLastError()); }
iRet = 1; }
//
// Check for empty CDF
//
if ((fVerbose) && (cMember == 0)) { pPrint->Display(IDS_ERROR_FUNCTION, pPrint->get_String(IDS_ERROR_NOMEMBERS), GetLastError()); }
//
// Close the CAT file
//
if (!(CryptCATCDFClose(pCDF))) { if (fVerbose) { pPrint->Display(IDS_ERROR_FUNCTION, L"CryptCATCDFClose", GetLastError()); }
if (fFailAllErrors) { goto CATCloseError; } }
//
// Done with main loop. The CAT file is created.
//
//
// Check for expected errors from closing CAT file
//
if (fTesting) { pPrint->Display(IDS_FILEREF, pwszCDFFile);
if (GetLastError() != dwExpectedError) { iRet = 1; pPrint->Display(IDS_EXPECTED_HRESULT, dwExpectedError, GetLastError()); } else { iRet = 0; pPrint->Display(IDS_SUCCEEDED); } } //
// Check for all standard success measurables
//
else if ((cMember > 0) && (!(fParseError)) && (!(fFileTooSmall)) && (iRet == 0)) { pPrint->Display(IDS_SUCCEEDED); } else { if (fParseError) { pPrint->Display(IDS_ERROR_PARSE); } else if (fFileTooSmall) { pPrint->Display(IDS_ERROR_TOO_SMALL); } else { pPrint->Display(IDS_FAILED, GetLastError(), GetLastError()); } iRet = 1; }
if ((fFailAllErrors) && (cMember == 0) && !(fTesting)) { iRet = 1; }
CommonReturn: DELETE_OBJECT(pArgs); DELETE_OBJECT(pPrint);
if (hOutputFile != INVALID_HANDLE_VALUE) { CloseHandle(hOutputFile); }
return(iRet);
ErrorReturn: iRet = 1; goto CommonReturn;
TRACE_ERROR_EX(DBG_SS_APP, MemoryError); TRACE_ERROR_EX(DBG_SS_APP, ParamError); TRACE_ERROR_EX(DBG_SS_APP, NeededHelp); TRACE_ERROR_EX(DBG_SS_APP, CATCloseError); TRACE_ERROR_EX(DBG_SS_APP, CDFOpenError); }
void WINAPI DisplayParseError(DWORD dwWhichArea, DWORD dwLocalError, WCHAR *pwszLine) { DWORD idErr; DWORD idFmt;
fParseError = TRUE;
switch (dwWhichArea) { case CRYPTCAT_E_AREA_HEADER: idFmt = IDS_PARSE_E_HEADER_FMT; break; case CRYPTCAT_E_AREA_MEMBER: idFmt = IDS_PARSE_E_MEMBER_FMT; break; case CRYPTCAT_E_AREA_ATTRIBUTE: idFmt = IDS_PARSE_E_ATTRIBUTE_FMT; break; default: idFmt = IDS_PARSE_E_ATTRIBUTE_FMT; break; }
switch (dwLocalError) { case CRYPTCAT_E_CDF_MEMBER_FILE_PATH: idErr = IDS_PARSE_ERROR_FILE_PATH; break; case CRYPTCAT_E_CDF_MEMBER_INDIRECTDATA: idErr = IDS_PARSE_ERROR_INDIRECTDATA; break; case CRYPTCAT_E_CDF_MEMBER_FILENOTFOUND: idErr = IDS_PARSE_ERROR_FILENOTFOUND; break; case CRYPTCAT_E_CDF_BAD_GUID_CONV: idErr = IDS_PARSE_ERROR_GUID_CONV; break; case CRYPTCAT_E_CDF_ATTR_TYPECOMBO: idErr = IDS_PARSE_ERROR_TYPECOMBO; break; case CRYPTCAT_E_CDF_ATTR_TOOFEWVALUES: idErr = IDS_PARSE_ERROR_TOOFEWVALUES; break; case CRYPTCAT_E_CDF_UNSUPPORTED: idErr = IDS_PARSE_ERROR_UNSUPPORTED; break; case CRYPTCAT_E_CDF_DUPLICATE: idErr = IDS_PARSE_ERROR_DUPLICATE; break; case CRYPTCAT_E_CDF_TAGNOTFOUND: idErr = IDS_PARSE_ERROR_NOTAG; break; default: idErr = IDS_PARSE_ERROR_UNKNOWN; break; }
pPrint->Display(idFmt, pPrint->get_String(idErr), pwszLine);
if (fFailAllErrors) { iRet = 1; } }
|