CFGCODE.C
// --cfgcode.c------------------------------------------------------------------ 
// 
//  Program to take a .INI file containing property values as input, and create  
//  a file containing packed configuration data as output. 
// 
// Copyright (C) Microsoft Corp. 1986-1996.  All Rights Reserved. 
// ----------------------------------------------------------------------------- 
 
#include "edk.h" 
#include "cfgcode.chk" 
#include "cfgcodem.h" 
#include <io.h> 
#include <sys/stat.h> 
 
// 
// Command Line Argument Names 
// 
 
#define ARG_PROGRAM_NAME        "CFGCODE" 
#define ARG_INPUT_FILE          "InFile" 
#define ARG_OUTPUT_FILE         "OutFile" 
#define ARG_SECTION             "SECTION" 
#define ARG_CONFIG_NAME         "NAME" 
#define ARG_HELP1               "?" 
#define ARG_HELP2               "HELP" 
 
static char * rgpszArgArray[] = 
{ 
ARG_PROGRAM_NAME, 
ARG_INPUT_FILE, 
ARG_OUTPUT_FILE, 
ARG_SECTION, 
ARG_CONFIG_NAME, 
ARG_HELP1, 
ARG_HELP2, 
}; 
 
// 
// Command Line Argument Variables 
// 
 
static TCHAR    szInputFile[MAX_PATH+1]  = {0}; 
static TCHAR    szOutputFile[MAX_PATH+1] = {0}; 
static TCHAR    szSection[MAX_PATH+1]    = {0}; 
static TCHAR    szConfigName[MAX_PATH+1] = {0}; 
static BOOL     fPrintHelp               = FALSE; 
static BOOL     fPrintUsage              = FALSE; 
 
// 
// Function Declarations 
// 
 
static VOID PrintUsage(void); 
 
static VOID PrintHelp(void); 
 
static HRESULT HrParseCommandLine( 
IN      int                     argc, 
IN      char *                  argv[]); 
 
static HRESULT HrReadPropsFromINIFile( 
IN      LPTSTR                  pszInputFile, 
IN      LPTSTR                  pszSection, 
OUT     ULONG *                 pcProps, 
OUT     LPSPropValue *  ppProps); 
 
static HRESULT HrParsePropValue( 
    IN      LPTSTR                  pszFullLine, 
IN      ULONG                   ulPropTag, 
IN      LPTSTR                  pszValueText, 
IN      LPVOID                  pBaseObject, 
OUT     LPSPropValue            pProp); 
 
static HRESULT HrCreateBinaryDataFile( 
IN      LPTSTR                  pszOutputFile, 
IN      ULONG                   cbData, 
IN      LPBYTE                  pbData); 
 
// 
// Functions 
// 
 
//$--main----------------------------------------------------------------------- 
//  Main function that performs file conversion. 
// ----------------------------------------------------------------------------- 
int main(                               // RETURNS: exit code 
IN      int                 argc,   // number of arguments on command line 
IN      char *              argv[]) // array of command line arguments 
{ 
HRESULT                 hr                      = NOERROR; 
BOOL                    fMAPIInitialized        = FALSE; 
MAPIINIT_0              MapiInit                = { 0 }; 
BOOL                    fPrintResult            = FALSE; 
ULONG                   cProps                  = 0; 
LPSPropValue            pProps                  = NULL; 
ULONG                   cbConfigData            = 0; 
LPBYTE                  pbConfigData            = NULL; 
BOOL                    fEventLogOpen           = FALSE; 
 
DEBUGPUBLIC("main()\n"); 
 
hr = CHK_main(argc, argv); 
if (FAILED(hr)) 
return _nEcFromHr(EC_EDK_E_FAIL); 
 
    printf( "\n" ); 
 
// Parse the command line arguments. 
 
hr = HrParseCommandLine(argc, argv); 
if (FAILED(hr)) 
goto cleanup; 
 
// If they requested a usage message (i.e. no arguments) then  
// print a usage message and exit. 
 
if (fPrintUsage) 
{ 
PrintUsage(); 
goto cleanup; 
} 
 
// If they requested help then print a help message and exit. 
 
if (fPrintHelp) 
{ 
PrintHelp(); 
goto cleanup; 
} 
 
// Open the event log. 
 
hr = HrEventOpenLog( 
    TEXT("EDK CFGCODE"), NULL, NULL, NULL, NULL, NULL); 
 
if (FAILED(hr)) 
{ 
fprintf(stderr, "ERROR: Can't open event log.\n"); 
goto cleanup; 
} 
fEventLogOpen = TRUE; 
 
// After this point we print the result of the operation and number  
// of events logged. 
 
fPrintResult = TRUE; 
 
// Initialize MAPI. 
 
    MapiInit.ulVersion = MAPI_INIT_VERSION; 
 
    hr = MAPIInitialize(&MapiInit); 
    if (FAILED(hr)) 
{ 
EventLogMsg( 
EDKEVENT_CANNOT_INIT_MAPI,  
0,  
0); 
goto cleanup; 
} 
 
fMAPIInitialized = TRUE; 
 
// If the input file name is not a full path then add the current  
// directory to the front of the name. 
 
if (strchr(szInputFile,':') == NULL && strchr(szInputFile,'\\') == NULL) 
{ 
TCHAR szCurrentDir[MAX_PATH+1] = {0}; 
ULONG cchCurrentDir = 0; 
 
cchCurrentDir = GetCurrentDirectory(MAX_PATH, szCurrentDir); 
if (cchCurrentDir == 0) 
{ 
EventLogMsg( 
CFGCODE_CANNOT_GET_CURRENT_DIR,  
0,  
1, GetLastError()); 
hr = HR_LOG(E_FAIL); 
goto cleanup; 
} 
 
if ( 
szCurrentDir[cchCurrentDir - 1] != ':' &&  
szCurrentDir[cchCurrentDir - 1] != '\\') 
{ 
strcat(szCurrentDir, "\\"); 
} 
strcat(szCurrentDir, szInputFile); 
strcpy(szInputFile, szCurrentDir); 
} 
 
// Do the operation. 
 
hr = HrReadPropsFromINIFile(szInputFile, szSection, &cProps, &pProps); 
if (FAILED(hr)) 
{ 
goto cleanup; 
} 
 
hr = HrCfgPackData( 
szConfigName, cProps, pProps, &cbConfigData, &pbConfigData); 
if (FAILED(hr)) 
{ 
EventLogMsg( 
CFGCODE_CANNOT_PACK_CONFIG_INFO,  
0,  
0); 
goto cleanup; 
} 
 
hr = HrCreateBinaryDataFile(szOutputFile, cbConfigData, pbConfigData); 
if (FAILED(hr)) 
{ 
goto cleanup; 
} 
 
cleanup: 
// Print the results of the operation if we got that far. 
 
if (fPrintResult) 
{ 
if (SUCCEEDED(hr)) 
{ 
printf("File created.\n"); 
} 
else 
{ 
HRESULT hrT = NOERROR; 
EDKEVENTCOUNT sEventCount = {0}; 
 
hrT = HrEventGetCounts(&sEventCount); 
if (FAILED(hrT) ||  
(sEventCount.cError == 0 && sEventCount.cWarning == 0)) 
{ 
fprintf(stderr, "ERROR: operation failed.\n"); 
} 
 
// Print the number of errors logged. 
 
if (sEventCount.cError == 1) 
{ 
fprintf(stderr,  
"ERROR: 1 error written to NT event log.\n"); 
} 
else if (sEventCount.cError > 1) 
{ 
fprintf(stderr,  
"ERROR: %d errors written to NT event log.\n"); 
} 
 
// Print the number of warnings logged. 
 
if (sEventCount.cWarning == 1) 
{ 
fprintf(stderr,  
"WARNING: 1 warning written to NT event log.\n"); 
} 
else if (sEventCount.cWarning > 1) 
{ 
fprintf(stderr,  
"WARNING: %d warnings written to NT event log.\n"); 
} 
} 
} 
 
// Free up everything. 
 
if (fMAPIInitialized) 
{ 
MAPIFREEBUFFER(pProps); 
MAPIFREEBUFFER(pbConfigData); 
MAPIUninitialize(); 
} 
 
// Close event logging. 
 
if (fEventLogOpen) 
{ 
(void)HrEventCloseLog(); 
fEventLogOpen = FALSE; 
} 
 
    // return exit code 
    return _nEcFromHr(hr); 
 
} 
 
 
 
//$--PrintUsage----------------------------------------------------------------- 
//  Print brief message about how to use this program. 
// ----------------------------------------------------------------------------- 
static VOID PrintUsage(void)                    // RETURNS: nothing 
{ 
DEBUGPRIVATE("PrintUsage()\n"); 
 
printf("USAGE: CFGCODE InFile OutFile [Flags]\n"); 
printf("\n"); 
printf("  [Flags]        Enter CFGCODE /? for details\n"); 
} 
 
 
 
//$--PrintHelp------------------------------------------------------------------ 
//  Print more detailed message about how to use this program. 
// ----------------------------------------------------------------------------- 
static VOID PrintHelp(void)                             // RETURNS: nothing 
{ 
DEBUGPRIVATE("PrintHelp()\n"); 
 
printf("Utility to create a packed configuration data file from a .INI " 
"file.\n"); 
printf("\n"); 
printf("USAGE: CFGCODE InFile OutFile [Flags]\n"); 
printf("\n"); 
printf("  InFile         Input .INI file containing MAPI properties\n"); 
printf("  OutFile        Output file to write packed configuration data\n"); 
printf("  /SECTION=      Name of the [Section] in the .INI file\n"); 
printf("  /NAME=         Configuration name for packed data\n"); 
printf("  /HELP or /?    Display help screen\n"); 
} 
 
 
 
//$--HrParseCommandLine--------------------------------------------------------- 
//  Parse the command line arguments and put their values in the appropriate  
//  variables. 
// ----------------------------------------------------------------------------- 
static HRESULT HrParseCommandLine(              // RETURNS: HRESULT 
IN      int                             argc,                   // number of arguments on command line 
IN      char *                  argv[])                 // array of command line arguments 
{ 
HRESULT         hr                              = NOERROR; 
HRESULT         hrT                             = NOERROR; 
int                     i                               = 0; 
char *          pszArgument             = NULL; 
char *          pszValue                = NULL; 
int                     cNonFlagArgs    = 0; 
 
DEBUGPRIVATE("HrParseCommandLine()\n"); 
 
hr = CHK_main(argc, argv); 
if (FAILED(hr)) 
RETURN(hr); 
 
// If there are no flags on the command line then just print usage message. 
 
if (argc < 2) 
{ 
fPrintUsage = TRUE; 
goto cleanup; 
} 
 
// Do an initial check for /? or /HELP.  If found, don't do any other  
// parsing. 
 
for (i = 1; i < argc; i++) 
{ 
hrT = _HrExpandCommandLineArgument( 
argv[i], rgpszArgArray, ARRAY_CNT(rgpszArgArray), NULL,  
&pszArgument, &pszValue); 
 
if (SUCCEEDED(hrT) && pszArgument &&  
(!_stricmp(pszArgument,ARG_HELP1) ||  
!_stricmp(pszArgument,ARG_HELP2))) 
{ 
fPrintHelp = TRUE; 
goto cleanup; 
} 
} 
 
// Loop through and parse all the command line arguments. 
 
for (i = 1; i < argc; i++) 
{ 
 hr = _HrExpandCommandLineArgument( 
argv[i], rgpszArgArray, ARRAY_CNT(rgpszArgArray), NULL,  
&pszArgument, &pszValue); 
if (FAILED(hr)) 
{ 
fprintf(stderr, "ERROR: unable to parse command line flags.\n"); 
goto cleanup; 
} 
 
// Parse non-flag arguments. 
 
if (pszArgument == NULL && pszValue != NULL) 
{ 
switch (++cNonFlagArgs) 
{ 
case 1:         // Input File 
STRNCPY(szInputFile, pszValue); 
break; 
 
case 2:         // Output File 
STRNCPY(szOutputFile, pszValue); 
break; 
 
default:        // Too many arguments!!! 
fprintf(stderr, "ERROR: unknown argument %s\n", argv[i]); 
hr = HR_LOG(E_FAIL); 
} 
} 
 
// Parse flag arguments that don't take a value. 
 
else if (pszArgument != NULL && pszValue == NULL) 
{ 
fprintf(stderr, "ERROR: flag /%s requires a value\n",  
pszArgument); 
hr = HR_LOG(E_FAIL); 
} 
 
// Parse flag arguments that take a value. 
 
else if (pszArgument != NULL && pszValue != NULL) 
{ 
if (!_stricmp(pszArgument,ARG_SECTION)) 
{ 
STRNCPY(szSection, pszValue); 
} 
else 
if (!_stricmp(pszArgument,ARG_CONFIG_NAME)) 
{ 
STRNCPY(szConfigName, pszValue); 
} 
else 
{ 
fprintf(stderr, "ERROR: flag /%s does not take a value\n",  
pszArgument); 
hr = HR_LOG(E_FAIL); 
} 
} 
 
// Catch unknown flags. 
 
else 
{ 
fprintf(stderr, "ERROR: unknown flag %s\n", argv[i]); 
hr = HR_LOG(E_FAIL); 
} 
} 
 
// Now make sure that all the flags are valid. 
 
if (*szInputFile == 0) 
{ 
fprintf(stderr, "ERROR: please specify %s\n", ARG_INPUT_FILE); 
hr = HR_LOG(E_FAIL); 
} 
 
if (*szOutputFile == 0) 
{ 
fprintf(stderr, "ERROR: please specify %s\n", ARG_OUTPUT_FILE); 
hr = HR_LOG(E_FAIL); 
} 
 
if (*szSection == 0) 
{ 
fprintf(stderr, "ERROR: please specify /%s\n", ARG_SECTION); 
hr = HR_LOG(E_FAIL); 
} 
 
if (*szConfigName == 0) 
{ 
fprintf(stderr, "ERROR: please specify /%s\n", ARG_CONFIG_NAME); 
hr = HR_LOG(E_FAIL); 
} 
 
cleanup: 
 
RETURN(hr); 
} 
 
 
 
//$--HrReadPropsFromINIFile----------------------------------------------------- 
//  Read a set of MAPI properties from a .INI file. 
// 
//  Properties are stored with the property tags as hex values, as follows: 
// 
//  [Section_Name] 
//  <property_tag>=<value> 
//  <property_tag>=<value> 
//  <property_tag>=<value> 
// ----------------------------------------------------------------------------- 
static HRESULT HrReadPropsFromINIFile(  // RETURNS: HRESULT 
IN      LPTSTR                  pszInputFile,   // name of file to read properties from 
IN      LPTSTR                  pszSection,             // name of section in file 
OUT     ULONG *                 pcProps,                // number of properties read from file 
OUT     LPSPropValue *  ppProps)                // array of properties read from file 
{ 
HRESULT                 hr                                      = NOERROR; 
LPTSTR                  pszSectionBuffer        = NULL; 
ULONG                   cchSectionBuffer        = 2048; 
ULONG                   cchActualSize           = 0; 
LPTSTR                  psz                                     = NULL; 
LPTSTR                  pszFullLine                     = NULL; 
ULONG                   iProp                           = 0; 
ULONG                   cProps                          = 0; 
LPSPropValue    pProps                          = NULL; 
ULONG                   ulPropTag                       = 0; 
ULONG                   ulError                         = ERROR_SUCCESS; 
 
DEBUGPRIVATE("HrReadPropsFromINIFile()\n"); 
 
hr = CHK_HrReadPropsFromINIFile( 
pszInputFile,  
pszSection,  
pcProps,  
ppProps); 
if (FAILED(hr)) 
RETURN(hr); 
 
// Read the entire section from the .INI file into the buffer. 
// If the buffer is too small then double its size and keep trying. 
 
while (TRUE) 
{ 
// Get the memory for the buffer to read in the section. 
 
hr = MAPIAllocateBuffer(cchSectionBuffer, &pszSectionBuffer); 
if (FAILED(hr)) 
{ 
EventLogMsg( 
EDKEVENT_ERROR,  
0,  
1, ERROR_OUTOFMEMORY); 
goto cleanup; 
} 
ZeroMemory(pszSectionBuffer, cchSectionBuffer); 
 
// Read in the section data. 
 
SetLastError(ERROR_SUCCESS); 
cchActualSize = GetPrivateProfileSection( 
pszSection,  
pszSectionBuffer,  
cchSectionBuffer,  
pszInputFile); 
ulError = GetLastError(); 
if (ulError != ERROR_SUCCESS) 
{ 
    if (ulError == ERROR_FILE_NOT_FOUND) 
    { 
EventLogMsg( 
CFGCODE_CANNOT_READ_PROFILE_SECTION_FNF,  
2, pszSection, pszInputFile,  
0); 
    } 
    else 
    { 
EventLogMsg( 
CFGCODE_CANNOT_READ_PROFILE_SECTION,  
2, pszSection, pszInputFile,  
1, GetLastError()); 
    } 
hr = HR_LOG(E_FAIL); 
goto cleanup; 
} 
 
// If the buffer was big enough then we're done.  If the buffer is  
// not big enough then the return value is the buffer size minus  
// two (see GetPrivateProfileSection() documentation). 
 
if (cchActualSize < (cchSectionBuffer - 2)) 
break; 
 
// Otherwise, add 2K to the buffer size and try again. 
 
MAPIFREEBUFFER(pszSectionBuffer); 
 
cchSectionBuffer += 2048; 
} 
 
// Count the number of properties we've read. 
 
for (psz = pszSectionBuffer; *psz; psz += (lstrlen(psz) + 1)) 
{ 
cProps++; 
} 
 
// Allocate an array of SPropValue's big enough to hold all the properties. 
 
hr = MAPIAllocateBuffer(cProps * sizeof(SPropValue), &pProps); 
if (FAILED(hr)) 
{ 
EventLogMsg( 
EDKEVENT_ERROR,  
0,  
1, ERROR_OUTOFMEMORY); 
goto cleanup; 
} 
 
// Read in the data and store it in the allocated array.  We may also need  
// to allocate other pieces of memory to put the values of data items. 
 
for ( 
psz = pszSectionBuffer, iProp = 0;  
*psz;  
psz += (lstrlen(psz) + 1), iProp++) 
{ 
ASSERTERROR(iProp < cProps, "iProp >= cProps: array overflow!"); 
 
// Save pointer to original string in case we have to log an error. 
 
pszFullLine = psz; 
 
// Get the property tag. 
 
ulPropTag = strtol(psz, &psz, 16); 
if (psz == pszFullLine) 
{ 
EventLogMsg( 
CFGCODE_NO_PROP_TAG,  
1, pszFullLine,  
0); 
hr = HR_LOG(E_FAIL); 
goto cleanup; 
} 
 
// Make sure there's an equal sign. 
 
if (*psz++ != '=') 
{ 
EventLogMsg( 
CFGCODE_PROP_TAG_WITHOUT_EQUALS,  
1, pszFullLine,  
0); 
hr = HR_LOG(E_FAIL); 
goto cleanup; 
} 
 
// Get the value based on the property type. 
 
hr = HrParsePropValue(pszFullLine, ulPropTag, psz, pProps, &pProps[iProp]); 
if (FAILED(hr)) 
goto cleanup; 
 
} // end for 
 
// Set the output parameters. 
 
*pcProps = cProps; 
*ppProps = pProps; 
 
cleanup: 
MAPIFREEBUFFER(pszSectionBuffer); 
if (FAILED(hr)) 
{ 
MAPIFREEBUFFER(pProps); 
} 
 
RETURN(hr); 
} 
 
 
 
//$--HrParsePropValue----------------------------------------------------------- 
//  Takes a text version of a property value and fills in an SPropValue  
//  structure.  If memory needs to be allocated, it is allocated using  
//  MAPIAllocateMore() based on the object passed in pBaseObject. 
// 
//  Valid property value formats for property types are as follows (and do  
//  not include the quotes): 
// 
//  PT_BINARY   a series of two digit hex numbers separated by spaces 
//              (e.g. "01 fe 2a 00 1c") 
// 
//  PT_BOOLEAN  the value 1 or 0 (1=True, 0=False) 
// 
//  PT_LONG     a decimal or hex constant (e.g. "127" or "0x0fff0003") 
// 
//  PT_STRING8  any string of characters (e.g. "This is fun!") 
// 
//  PT_SYSTIME  a date in the format "yyyy/mm/dd hh:mm:ss"  
//              (e.g. "1995/12/31 23:59:59") 
// ----------------------------------------------------------------------------- 
static HRESULT HrParsePropValue(                // RETURNS: HRESULT 
    IN  LPTSTR          pszFullLine,    // the full line (for error logging) 
IN      ULONG                   ulPropTag,              // property tag of this property 
IN      LPTSTR                  pszValueText,   // text of property value to parse 
IN      LPVOID                  pBaseObject,    // base object for MAPIAllocateMore() 
OUT     LPSPropValue    pProp)                  // structure to write results 
{ 
HRESULT                 hr                              = NOERROR; 
LPTSTR          psz             = NULL; 
LPTSTR          pszPrev         = NULL; 
 
DEBUGPRIVATE("HrParsePropValue()\n"); 
 
hr = CHK_HrParsePropValue( 
pszFullLine,  
ulPropTag,  
pszValueText,  
pBaseObject,  
pProp); 
if (FAILED(hr)) 
RETURN(hr); 
 
switch (PROP_TYPE(ulPropTag)) 
{ 
case PT_BINARY: 
{ 
ULONG cb = 0; 
ULONG ib = 0; 
LPBYTE pb = NULL; 
LONG lNumber = 0; 
 
// Count the bytes and check that all the bytes are valid. 
 
psz = pszValueText; 
while (*psz) 
{ 
if (isspace(*psz)) 
psz++; 
else 
{ 
pszPrev = psz; 
lNumber = strtol(psz, &psz, 16); 
if (psz == pszPrev || lNumber > 255 || lNumber < 0) 
    { 
hr = HR_LOG(E_FAIL); 
EventLogMsg( 
CFGCODE_ILLEGAL_BINARY_VALUE,  
1, pszFullLine,  
0); 
goto cleanup; 
    } 
cb++; 
} 
} 
 
// Allocate a buffer big enough for the number of bytes. 
 
hr = MAPIAllocateMore(cb, pBaseObject, &pProp->Value.bin.lpb); 
if (FAILED(hr)) 
{ 
EventLogMsg( 
EDKEVENT_ERROR,  
0,  
1, ERROR_OUTOFMEMORY); 
goto cleanup; 
} 
pProp->Value.bin.cb = cb; 
 
// Write the bytes into the buffer. 
 
psz = pszValueText; 
for (ib = 0, pb = pProp->Value.bin.lpb; ib < cb; ib++, pb++) 
{ 
*pb = (BYTE)strtol(psz, &psz, 16); 
} 
 
break; 
} 
 
case PT_BOOLEAN: 
    psz = pszValueText; 
 
    while (isspace(*psz)) 
psz++; 
 
    pszPrev = psz; 
pProp->Value.l = strtol(psz, &psz, 0); 
 
    while (isspace(*psz)) 
psz++; 
 
    if (psz == pszPrev || *psz ||  
(pProp->Value.l != 0 && pProp->Value.l != 1)) 
    { 
hr = HR_LOG(E_FAIL); 
EventLogMsg( 
CFGCODE_ILLEGAL_BOOLEAN_VALUE,  
1, pszFullLine,  
0); 
goto cleanup; 
    } 
break; 
 
case PT_LONG: 
    psz = pszValueText; 
 
    while (isspace(*psz)) 
psz++; 
 
    pszPrev = psz; 
pProp->Value.l = strtol(psz, &psz, 0); 
 
    while (isspace(*psz)) 
psz++; 
 
    if (psz == pszPrev || *psz) 
    { 
hr = HR_LOG(E_FAIL); 
EventLogMsg( 
CFGCODE_ILLEGAL_LONG_VALUE,  
1, pszFullLine,  
0); 
goto cleanup; 
    } 
break; 
 
case PT_STRING8: 
{ 
ULONG cb = strlen(pszValueText) + 1; 
 
hr = MAPIAllocateMore(cb, pBaseObject, &pProp->Value.lpszA); 
if (FAILED(hr)) 
{ 
hr = HR_LOG(E_FAIL); 
EventLogMsg( 
EDKEVENT_ERROR,  
0,  
1, ERROR_OUTOFMEMORY); 
goto cleanup; 
} 
MoveMemory(pProp->Value.lpszA, pszValueText, cb); 
break; 
} 
 
case PT_SYSTIME: 
{ 
SYSTEMTIME st = {0}; 
    CHAR chBogus = 0; 
int lReturn = 0; 
BOOL fItWorked = TRUE; 
 
lReturn = sscanf( 
pszValueText,  
" %hd/%hd/%hd %hd:%hd:%hd %c",  
&st.wYear,  
&st.wMonth,  
&st.wDay,  
&st.wHour,  
&st.wMinute,  
&st.wSecond,  
&chBogus); 
if (lReturn == 0 || lReturn == EOF || chBogus) 
{ 
hr = HR_LOG(E_FAIL); 
EventLogMsg( 
CFGCODE_ILLEGAL_SYSTIME_VALUE,  
1, pszFullLine,  
0); 
goto cleanup; 
} 
 
fItWorked = SystemTimeToFileTime(&st, &pProp->Value.ft); 
if (!fItWorked) 
{ 
hr = HR_LOG(E_FAIL); 
EventLogMsg( 
CFGCODE_CANNOT_CONVERT_TIME,  
1, pszFullLine,  
1, GetLastError()); 
goto cleanup; 
} 
 
break; 
} 
 
default: 
{ 
TCHAR szPropType[9] = {0}; 
 
wsprintf(szPropType, TEXT("%08lx"), PROP_TYPE(ulPropTag)); 
 
hr = HR_LOG(E_NOTIMPL); 
EventLogMsg( 
CFGCODE_UNSUPPORTED_PROPERTY_TYPE,  
1, pszFullLine,  
0); 
goto cleanup; 
} 
} 
 
pProp->ulPropTag = ulPropTag; 
 
cleanup: 
RETURN(hr); 
} 
 
 
 
//$--HrCreateBinaryDataFile----------------------------------------------------- 
//  Create a file and write binary data to it. 
// ----------------------------------------------------------------------------- 
static HRESULT HrCreateBinaryDataFile(  // RETURNS: HRESULT 
IN      LPTSTR                  pszOutputFile,  // name of file to create 
IN      ULONG                   cbData,                 // number of bytes to write to file 
IN      LPBYTE                  pbData)                 // binary data to write to file 
{ 
HRESULT                 hr                              = NOERROR; 
HANDLE                  hOutputFile             = INVALID_HANDLE_VALUE; 
BOOL                    fItWorked               = TRUE; 
DWORD                   cbBytesWritten  = 0; 
 
DEBUGPRIVATE("HrCreateBinaryDataFile()\n"); 
 
hr = CHK_HrCreateBinaryDataFile( 
pszOutputFile,  
cbData,  
pbData); 
if (FAILED(hr)) 
RETURN(hr); 
 
hOutputFile = CreateFile( 
pszOutputFile,                                  // file name 
GENERIC_WRITE,                                  // open for write 
0,                                                              // no sharing 
NULL,                                                   // default security 
CREATE_ALWAYS,                                  // overwrite existing file 
FILE_ATTRIBUTE_NORMAL,                  // normal file 
NULL);                                                  // no template file 
if (hOutputFile == INVALID_HANDLE_VALUE) 
{ 
EventLogMsg( 
CFGCODE_COULD_NOT_CREATE_FILE,  
1, pszOutputFile,  
1, GetLastError()); 
hr = HR_LOG(E_FAIL); 
goto cleanup; 
} 
 
fItWorked = WriteFile( 
hOutputFile,                                    // file handle 
pbData,                                                 // buffer to write 
cbData,                                                 // number of bytes to write 
&cbBytesWritten,                                // number of bytes actually written 
NULL);                                                  // no overlapped 
if (!fItWorked || cbBytesWritten != cbData) 
{ 
EventLogMsg( 
CFGCODE_COULD_NOT_WRITE_FILE,  
1, pszOutputFile,  
1, GetLastError()); 
hr = HR_LOG(E_FAIL); 
goto cleanup; 
} 
 
fItWorked = CloseHandle(hOutputFile); 
if (!fItWorked) 
{ 
EventLogMsg( 
CFGCODE_COULD_NOT_CLOSE_FILE,  
1, pszOutputFile,  
1, GetLastError()); 
hr = HR_LOG(E_FAIL); 
goto cleanup; 
} 
hOutputFile = INVALID_HANDLE_VALUE; 
 
cleanup: 
if (FAILED(hr) && hOutputFile != INVALID_HANDLE_VALUE) 
{ 
CloseHandle(hOutputFile); 
DeleteFile(pszOutputFile); 
} 
 
RETURN(hr); 
}