Leaked source code of windows server 2003
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.
 
 
 
 
 
 

502 lines
15 KiB

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