//+------------------------------------------------------------------------- // // 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 #include #include #include #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; } }