1623 lines
51 KiB
C++
1623 lines
51 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 2001, Microsoft Corporation All rights reserved.
|
|
//
|
|
// Module Name:
|
|
//
|
|
// infparser.cpp
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This file contains the entry point of the infparser.exe utility.
|
|
//
|
|
// Revision History:
|
|
//
|
|
// 2001-06-20 lguindon Created.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Includes Files.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#include "stdafx.h"
|
|
#include "infparser.h"
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Global variable.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
BOOL bSilence = TRUE;
|
|
DWORD dwComponentCounter = 0;
|
|
DWORD dwDirectoryCounter = 1;
|
|
WORD gBuildNumber = 0;
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Prototypes.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
BOOL DirectoryExist(LPSTR dirPath);
|
|
BOOL ValidateLanguage(LPSTR dirPath, LPSTR langName, DWORD binType);
|
|
WORD ConvertLanguage(LPSTR dirPath, LPSTR langName);
|
|
int ListContents(LPSTR filename, LPSTR dirPath, LPSTR lang, DWORD flavor, DWORD binType);
|
|
int ListComponents(FileList *dirList, LPSTR dirPath, LPSTR lang, DWORD flavor, DWORD binType);
|
|
int ListMuiFiles(FileList *dirList, LPSTR dirPath, LPSTR lang, DWORD flavor, DWORD binType);
|
|
void PrintFileList(FileList* list, HANDLE hFile, BOOL compressed, BOOL bWinDir);
|
|
BOOL PrintLine(HANDLE hFile, LPCSTR lpLine);
|
|
HANDLE CreateOutputFile(LPSTR filename);
|
|
VOID removeSpace(LPSTR src, LPSTR dest);
|
|
DWORD TransNum(LPTSTR lpsz);
|
|
void Usage();
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Main entry point.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
int __cdecl main(int argc, char* argv[])
|
|
{
|
|
LPSTR sLangName = NULL;
|
|
LPSTR sDirPath = NULL;
|
|
DWORD dwFlavor = FLV_UNDEFINED;
|
|
DWORD dwBinType = BIN_UNDEFINED;
|
|
DWORD dwArg = ARG_UNDEFINED;
|
|
WORD wLangID = 0;
|
|
HANDLE hFile;
|
|
int argIndex = 1;
|
|
LPSTR lpFileName = NULL;
|
|
|
|
|
|
//
|
|
// Check if we have the minimal number of arguments.
|
|
//
|
|
if (argc < 6)
|
|
{
|
|
Usage();
|
|
return (-1);
|
|
}
|
|
|
|
//
|
|
// Parse the command line.
|
|
//
|
|
while (argIndex < argc)
|
|
{
|
|
if (*argv[argIndex] == '/')
|
|
{
|
|
switch(*(argv[argIndex]+1))
|
|
{
|
|
case('b'):
|
|
case('B'):
|
|
{
|
|
//
|
|
// Binairy i386 or ia64
|
|
//
|
|
if ((*(argv[argIndex]+3) == '3') && (*(argv[argIndex]+4) == '2'))
|
|
{
|
|
dwBinType = BIN_32;
|
|
}
|
|
else if ((*(argv[argIndex]+3) == '6') && (*(argv[argIndex]+4) == '4'))
|
|
{
|
|
dwBinType = BIN_64;
|
|
}
|
|
else
|
|
{
|
|
return (argIndex);
|
|
}
|
|
|
|
dwArg |= ARG_BINARY;
|
|
break;
|
|
}
|
|
case('l'):
|
|
case('L'):
|
|
{
|
|
//
|
|
// Language
|
|
//
|
|
sLangName = (argv[argIndex]+3);
|
|
dwArg |= ARG_LANG;
|
|
break;
|
|
}
|
|
case('f'):
|
|
case('F'):
|
|
{
|
|
//
|
|
// Flavor requested
|
|
//
|
|
switch(*(argv[argIndex]+3))
|
|
{
|
|
case('c'):
|
|
case('C'):
|
|
{
|
|
dwFlavor = FLV_CORE;
|
|
break;
|
|
}
|
|
case('p'):
|
|
case('P'):
|
|
{
|
|
dwFlavor = FLV_PROFESSIONAL;
|
|
break;
|
|
}
|
|
case('s'):
|
|
case('S'):
|
|
{
|
|
dwFlavor = FLV_SERVER;
|
|
break;
|
|
}
|
|
case('a'):
|
|
case('A'):
|
|
{
|
|
dwFlavor = FLV_ADVSERVER;
|
|
break;
|
|
}
|
|
case('d'):
|
|
case('D'):
|
|
{
|
|
dwFlavor = FLV_DATACENTER;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
return (argIndex);
|
|
}
|
|
}
|
|
|
|
dwArg |= ARG_FLAVOR;
|
|
break;
|
|
}
|
|
case('s'):
|
|
case('S'):
|
|
{
|
|
//
|
|
// Binairy location
|
|
//
|
|
sDirPath = (argv[argIndex]+3);
|
|
dwArg |= ARG_DIR;
|
|
break;
|
|
}
|
|
case('o'):
|
|
case('O'):
|
|
{
|
|
//
|
|
// Output filename
|
|
//
|
|
/*
|
|
if ((hFile = CreateOutputFile(argv[argIndex]+3)) == INVALID_HANDLE_VALUE)
|
|
{
|
|
return (argIndex);
|
|
}
|
|
*/
|
|
|
|
lpFileName = argv[argIndex]+3;
|
|
|
|
dwArg |= ARG_OUT;
|
|
break;
|
|
}
|
|
case('v'):
|
|
case('V'):
|
|
{
|
|
//
|
|
// Verbose mode
|
|
//
|
|
bSilence = FALSE;
|
|
dwArg |= ARG_SILENT;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
Usage();
|
|
return (argIndex);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Usage();
|
|
return (-1);
|
|
}
|
|
|
|
//
|
|
// Next argument
|
|
//
|
|
argIndex++;
|
|
}
|
|
|
|
//
|
|
// Validate arguments passed. Should have all five basic argument in order
|
|
// to continue.
|
|
//
|
|
if ((dwArg == ARG_UNDEFINED) ||
|
|
!((dwArg & ARG_BINARY) &&
|
|
(dwArg & ARG_LANG) &&
|
|
(dwArg & ARG_DIR) &&
|
|
(dwArg & ARG_OUT) &&
|
|
(dwArg & ARG_FLAVOR)))
|
|
{
|
|
Usage();
|
|
return (-1);
|
|
}
|
|
|
|
//
|
|
// Validate Source directory
|
|
//
|
|
if (!DirectoryExist(sDirPath))
|
|
{
|
|
return (-2);
|
|
}
|
|
|
|
//
|
|
// Validate Language
|
|
//
|
|
if (!ValidateLanguage(sDirPath, sLangName, dwBinType))
|
|
{
|
|
return (-3);
|
|
}
|
|
|
|
//
|
|
// Get LANGID from the language
|
|
//
|
|
if ( (gBuildNumber = ConvertLanguage(sDirPath, sLangName)) == 0x0000)
|
|
{
|
|
return (-4);
|
|
}
|
|
|
|
//
|
|
// Generate the file list
|
|
//
|
|
if ((dwArg & ARG_OUT) && lpFileName)
|
|
{
|
|
return ListContents(lpFileName, sDirPath, sLangName, dwFlavor, dwBinType);
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ListContents()
|
|
//
|
|
// Generate the file list contents.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
int ListContents(LPSTR filename, LPSTR dirPath, LPSTR lang, DWORD flavor, DWORD binType)
|
|
{
|
|
int iRet = 0;
|
|
Uuid* uuid;
|
|
CHAR schemaPath[MAX_PATH] = {0};
|
|
CHAR outputString[4096] = {0};
|
|
FileList fileList;
|
|
HANDLE outputFile = CreateOutputFile(filename);
|
|
|
|
if (outputFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
iRet = -1;
|
|
goto ListContents_EXIT;
|
|
}
|
|
|
|
//
|
|
// Create a UUID for this module and the schema path
|
|
//
|
|
uuid = new Uuid();
|
|
sprintf(schemaPath, "%s\\control\\MmSchema.xml", dirPath);
|
|
|
|
//
|
|
// Print module header.
|
|
//
|
|
PrintLine(outputFile, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
|
|
sprintf(outputString, "<Module Name=\"MUI MSI File Content\" Id=\"%s\" Language=\"0\" Version=\"1.0\" xmlns=\"%s\">", uuid->getString(), schemaPath);
|
|
PrintLine(outputFile, outputString);
|
|
delete uuid;
|
|
uuid = new Uuid();
|
|
sprintf(outputString, " <Package Id=\"%s\"", uuid->getString());
|
|
PrintLine(outputFile, outputString);
|
|
delete uuid;
|
|
PrintLine(outputFile, " Description=\"Content module\"");
|
|
PrintLine(outputFile, " Platforms=\"Intel\"");
|
|
PrintLine(outputFile, " Languages=\"0\"");
|
|
PrintLine(outputFile, " InstallerVersion=\"100\"");
|
|
PrintLine(outputFile, " Manufacturer=\"Microsoft Corporation\"");
|
|
PrintLine(outputFile, " Keywords=\"MergeModule, MSI, Database\"");
|
|
PrintLine(outputFile, " Comments=\"This merge module contains all the MUI file content\"");
|
|
PrintLine(outputFile, " ShortNames=\"yes\" Compressed=\"yes\"");
|
|
PrintLine(outputFile, "/>");
|
|
|
|
//
|
|
// Generate components file list
|
|
//
|
|
if ( (iRet = ListComponents(&fileList, dirPath, lang, flavor, binType)) != 0)
|
|
{
|
|
goto ListContents_EXIT;
|
|
}
|
|
|
|
//
|
|
// Generate Mui file list
|
|
//
|
|
if ((iRet =ListMuiFiles(&fileList, dirPath, lang, flavor, binType)) != 0)
|
|
{
|
|
goto ListContents_EXIT;
|
|
}
|
|
|
|
//
|
|
// Print compressed directory structure.
|
|
//
|
|
PrintLine(outputFile, "<Directory Name=\"SOURCEDIR\">TARGETDIR");
|
|
if (fileList.isDirId(TRUE))
|
|
{
|
|
PrintLine(outputFile, " <Directory Name=\"Windows\">WindowsFolder");
|
|
PrintFileList(&fileList, outputFile, TRUE, TRUE);
|
|
PrintLine(outputFile, " </Directory>");
|
|
}
|
|
if (fileList.isDirId(FALSE))
|
|
{
|
|
PrintLine(outputFile, " <Directory Name=\"ProgramFilesFolder\">ProgramFilesFolder");
|
|
PrintFileList(&fileList, outputFile, TRUE, FALSE);
|
|
PrintLine(outputFile, " </Directory>");
|
|
}
|
|
PrintLine(outputFile, "</Directory>");
|
|
|
|
//
|
|
// Print module footer.
|
|
//
|
|
PrintLine(outputFile, "</Module>");
|
|
|
|
ListContents_EXIT:
|
|
if (outputFile)
|
|
CloseHandle(outputFile);
|
|
|
|
return (iRet);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ListComponents()
|
|
//
|
|
// Generate the file list of each components.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
int ListComponents(FileList *dirList, LPSTR dirPath, LPSTR lang, DWORD flavor, DWORD binType)
|
|
{
|
|
HINF hFile;
|
|
CHAR muiFilePath[MAX_PATH];
|
|
UINT lineCount, lineNum;
|
|
INFCONTEXT context;
|
|
ComponentList componentList;
|
|
Component* component;
|
|
|
|
//
|
|
// Used only in core flavor
|
|
//
|
|
if (flavor != FLV_CORE)
|
|
{
|
|
return (0);
|
|
}
|
|
|
|
//
|
|
// Create the path to open the mui.inf file
|
|
//
|
|
sprintf(muiFilePath, "%s\\mui.inf", dirPath);
|
|
|
|
//
|
|
// Open the MUI.INF file.
|
|
//
|
|
hFile = SetupOpenInfFile(muiFilePath, NULL, INF_STYLE_WIN4, NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
return (-1);
|
|
}
|
|
|
|
//
|
|
// Get the number of component.
|
|
//
|
|
lineCount = (UINT)SetupGetLineCount(hFile, TEXT("Components"));
|
|
if (lineCount > 0)
|
|
{
|
|
//
|
|
// Go through all component of the list.
|
|
//
|
|
CHAR componentName[MAX_PATH];
|
|
CHAR componentFolder[MAX_PATH];
|
|
CHAR componentInf[MAX_PATH];
|
|
CHAR componentInst[MAX_PATH];
|
|
for (lineNum = 0; lineNum < lineCount; lineNum++)
|
|
{
|
|
if (SetupGetLineByIndex(hFile, TEXT("Components"), lineNum, &context) &&
|
|
SetupGetStringField(&context, 0, componentName, MAX_PATH, NULL) &&
|
|
SetupGetStringField(&context, 1, componentFolder, MAX_PATH, NULL) &&
|
|
SetupGetStringField(&context, 2, componentInf, MAX_PATH, NULL) &&
|
|
SetupGetStringField(&context, 3, componentInst, MAX_PATH, NULL))
|
|
{
|
|
//
|
|
// Create the components
|
|
//
|
|
if( (component = new Component( componentName,
|
|
componentFolder,
|
|
componentInf,
|
|
componentInst)) != NULL)
|
|
{
|
|
componentList.add(component);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Close inf handle
|
|
//
|
|
SetupCloseInfFile(hFile);
|
|
|
|
//
|
|
// Output component information
|
|
//
|
|
component = componentList.getFirst();
|
|
while (component != NULL)
|
|
{
|
|
CHAR componentInfPath[MAX_PATH];
|
|
CHAR componentPath[MAX_PATH];
|
|
int fieldCount, fieldCount2;
|
|
INFCONTEXT context2;
|
|
INFCONTEXT context3;
|
|
File* file;
|
|
|
|
//
|
|
// Compute the component inf path.
|
|
//
|
|
if (binType == BIN_32)
|
|
{
|
|
sprintf( componentInfPath,
|
|
"%s\\%s\\i386.uncomp\\%s\\%s",
|
|
dirPath,
|
|
lang,
|
|
component->getFolderName(),
|
|
component->getInfName());
|
|
sprintf( componentPath,
|
|
"%s\\%s\\i386.uncomp\\%s",
|
|
dirPath,
|
|
lang,
|
|
component->getFolderName());
|
|
}
|
|
else
|
|
{
|
|
sprintf( componentInfPath,
|
|
"%s\\%s\\ia64.uncomp\\%s\\%s",
|
|
dirPath,
|
|
lang,
|
|
component->getFolderName(),
|
|
component->getInfName());
|
|
sprintf( componentPath,
|
|
"%s\\%s\\ai64.uncomp\\%s",
|
|
dirPath,
|
|
lang,
|
|
component->getFolderName());
|
|
}
|
|
|
|
//
|
|
// Open the component inf file.
|
|
//
|
|
hFile = SetupOpenInfFile(componentInfPath, NULL, INF_STYLE_WIN4, NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
return (-1);
|
|
}
|
|
|
|
//
|
|
// Search for the CopyFiles section
|
|
//
|
|
if (SetupFindFirstLine( hFile,
|
|
component->getInfInstallSectionName(),
|
|
"CopyFiles",
|
|
&context ) &&
|
|
(fieldCount = SetupGetFieldCount(&context)))
|
|
{
|
|
CHAR instSectionName[MAX_PATH];
|
|
INT destDirId;
|
|
CHAR destDirSubFolder[MAX_PATH];
|
|
CHAR destFileName[MAX_PATH];
|
|
CHAR srcFileName[MAX_PATH];
|
|
|
|
for (int fieldIdx = 1; fieldIdx <= fieldCount; fieldIdx++)
|
|
{
|
|
//
|
|
// Get the install section Names and search for the
|
|
// corresponding DestinationDirs.
|
|
//
|
|
if (SetupGetStringField(&context, fieldIdx, instSectionName, MAX_PATH, NULL) &&
|
|
SetupFindFirstLine(hFile, "DestinationDirs", instSectionName, &context2))
|
|
{
|
|
//
|
|
// Get the destination directory information for this
|
|
// installation section
|
|
//
|
|
if (SetupGetIntField(&context2, 1, &destDirId))
|
|
{
|
|
//
|
|
// Possible that no sub directory
|
|
//
|
|
if(!SetupGetStringField(&context2, 2, destDirSubFolder, MAX_PATH, NULL))
|
|
{
|
|
destDirSubFolder[0] = '\0';
|
|
}
|
|
|
|
//
|
|
// Scan the section for file
|
|
//
|
|
if ((lineCount = (UINT)SetupGetLineCount(hFile, instSectionName)) > 0)
|
|
{
|
|
for (lineNum = 0; lineNum < lineCount; lineNum++)
|
|
{
|
|
if (SetupGetLineByIndex(hFile, instSectionName, lineNum, &context3) &&
|
|
(fieldCount2 = SetupGetFieldCount(&context3)))
|
|
{
|
|
if (fieldCount2 > 1)
|
|
{
|
|
if (SetupGetStringField(&context3, 1, destFileName, MAX_PATH, NULL) &&
|
|
SetupGetStringField(&context3, 2, srcFileName, MAX_PATH, NULL))
|
|
{
|
|
//
|
|
// Create the components
|
|
//
|
|
if ((file = new File(destDirSubFolder,
|
|
destFileName,
|
|
componentPath,
|
|
srcFileName,
|
|
destDirId)) != NULL)
|
|
{
|
|
dirList->add(file);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( SetupGetStringField(&context3, 0, destFileName, MAX_PATH, NULL))
|
|
{
|
|
//
|
|
// Create the components
|
|
//
|
|
if( (file = new File(destDirSubFolder,
|
|
destFileName,
|
|
componentPath,
|
|
destFileName,
|
|
destDirId)) != NULL)
|
|
{
|
|
dirList->add(file);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// Next Component
|
|
//
|
|
component = component->getNext();
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ListMuiFiles()
|
|
//
|
|
// Generate the file list for MUI.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
int ListMuiFiles(FileList *dirList, LPSTR dirPath, LPSTR lang, DWORD flavor, DWORD binType)
|
|
{
|
|
HINF hFile;
|
|
CHAR muiFilePath[MAX_PATH];
|
|
CHAR muiFileSearchPath[MAX_PATH];
|
|
int lineCount, lineNum, fieldCount;
|
|
INFCONTEXT context;
|
|
FileLayoutExceptionList exceptionList;
|
|
WIN32_FIND_DATA findData;
|
|
HANDLE fileHandle;
|
|
File* file;
|
|
|
|
//
|
|
// Create the path to open the mui.inf file
|
|
//
|
|
sprintf(muiFilePath, "%s\\mui.inf", dirPath);
|
|
|
|
//
|
|
// Open the MUI.INF file.
|
|
//
|
|
hFile = SetupOpenInfFile(muiFilePath, NULL, INF_STYLE_WIN4, NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
return (-1);
|
|
}
|
|
|
|
//
|
|
// Get the number of file exception.
|
|
//
|
|
lineCount = (UINT)SetupGetLineCount(hFile, TEXT("File_Layout"));
|
|
if (lineCount > 0)
|
|
{
|
|
//
|
|
// Go through all file exception of the list.
|
|
//
|
|
CHAR originFilename[MAX_PATH];
|
|
CHAR destFilename[MAX_PATH];
|
|
CHAR fileFlavor[30];
|
|
DWORD dwFlavor;
|
|
for (lineNum = 0; lineNum < lineCount; lineNum++)
|
|
{
|
|
if (SetupGetLineByIndex(hFile, TEXT("File_Layout"), lineNum, &context) &&
|
|
(fieldCount = SetupGetFieldCount(&context)))
|
|
{
|
|
if (SetupGetStringField(&context, 0, originFilename, MAX_PATH, NULL) &&
|
|
SetupGetStringField(&context, 1, destFilename, MAX_PATH, NULL))
|
|
{
|
|
FileLayout* fileException;
|
|
|
|
dwFlavor = 0;
|
|
for(int fieldId = 2; fieldId <= fieldCount; fieldId++)
|
|
{
|
|
if(SetupGetStringField(&context, fieldId, fileFlavor, MAX_PATH, NULL))
|
|
{
|
|
switch(*fileFlavor)
|
|
{
|
|
case('p'):
|
|
case('P'):
|
|
{
|
|
dwFlavor |= FLV_PROFESSIONAL;
|
|
break;
|
|
}
|
|
case('s'):
|
|
case('S'):
|
|
{
|
|
dwFlavor |= FLV_SERVER;
|
|
break;
|
|
}
|
|
case('d'):
|
|
case('D'):
|
|
{
|
|
dwFlavor |= FLV_DATACENTER;
|
|
break;
|
|
}
|
|
case('a'):
|
|
case('A'):
|
|
{
|
|
dwFlavor |= FLV_ENTERPRISE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
// Add only information needed for this specific flavor.
|
|
//
|
|
fileException = new FileLayout(originFilename, destFilename, dwFlavor);
|
|
exceptionList.insert(fileException);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Close inf handle
|
|
//
|
|
SetupCloseInfFile(hFile);
|
|
|
|
//
|
|
// Compute the binary source path.
|
|
//
|
|
if (binType == BIN_32)
|
|
{
|
|
sprintf( muiFileSearchPath, "%s\\%s\\i386.uncomp", dirPath, lang);
|
|
sprintf( muiFilePath, "%s\\%s\\i386.uncomp\\*.*", dirPath, lang);
|
|
}
|
|
else
|
|
{
|
|
sprintf( muiFileSearchPath, "%s\\%s\\ia64.uncomp", dirPath, lang);
|
|
sprintf( muiFilePath, "%s\\%s\\ia64.uncomp\\*.*", dirPath, lang);
|
|
}
|
|
|
|
//
|
|
// Scan uncomp source directory for file information
|
|
//
|
|
if ((fileHandle = FindFirstFile(muiFilePath, &findData)) != INVALID_HANDLE_VALUE)
|
|
{
|
|
//
|
|
// Look for files
|
|
//
|
|
do
|
|
{
|
|
LPSTR extensionPtr;
|
|
INT dirIdentifier = 0;
|
|
CHAR destDirectory[MAX_PATH] = {0};
|
|
CHAR destName[MAX_PATH] = {0};
|
|
FileLayout* fileException = NULL;
|
|
|
|
//
|
|
// Scan only files at this level.
|
|
//
|
|
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Search the extension to determine the destination location and possibly
|
|
// exclude file destined for Personal.
|
|
//
|
|
if ((extensionPtr = strrchr(findData.cFileName, '.')) != NULL)
|
|
{
|
|
if( (_tcsicmp(extensionPtr, TEXT(".chm")) == 0) ||
|
|
(_tcsicmp(extensionPtr, TEXT(".chq")) == 0) ||
|
|
(_tcsicmp(extensionPtr, TEXT(".cnt")) == 0) ||
|
|
(_tcsicmp(extensionPtr, TEXT(".hlp")) == 0))
|
|
{
|
|
dirIdentifier = 18;
|
|
sprintf(destDirectory, "MUI\\%04x", gBuildNumber);
|
|
}
|
|
else if (_tcsicmp(extensionPtr, TEXT(".mfl")) == 0)
|
|
{
|
|
dirIdentifier = 11;
|
|
sprintf(destDirectory, "wbem\\MUI\\%04x", gBuildNumber);
|
|
}
|
|
else if (_tcsicmp(findData.cFileName, TEXT("hhctrlui.dll")) == 0)
|
|
{
|
|
dirIdentifier = 11;
|
|
sprintf(destDirectory, "MUI\\%04x", gBuildNumber);
|
|
}
|
|
else
|
|
{
|
|
dirIdentifier = 10;
|
|
sprintf(destDirectory, "MUI\\FALLBACK\\%04x", gBuildNumber);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Search for different destination name in the exception list.
|
|
//
|
|
if ((fileException = exceptionList.search(findData.cFileName)) != NULL )
|
|
{
|
|
//
|
|
// Verify it's the needed flavor
|
|
//
|
|
if (fileException->isFlavor(flavor))
|
|
{
|
|
sprintf(destName, "%s", fileException->getDestFileName());
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Skip the file. Not need in this flavor.
|
|
//
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (((extensionPtr = strrchr(findData.cFileName, '.')) != NULL) &&
|
|
((*(extensionPtr-1) == 'P') || (*(extensionPtr-1) == 'p')))
|
|
{
|
|
continue;
|
|
}
|
|
else if (flavor != FLV_CORE)
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
sprintf(destName, "%s", findData.cFileName);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Create a file
|
|
//
|
|
if (file = new File(destDirectory,
|
|
destName,
|
|
muiFileSearchPath,
|
|
findData.cFileName,
|
|
dirIdentifier))
|
|
{
|
|
dirList->add(file);
|
|
}
|
|
}
|
|
while (FindNextFile(fileHandle, &findData));
|
|
|
|
FindClose(fileHandle);
|
|
}
|
|
|
|
//
|
|
// Add Specific MuiSetup files.
|
|
//
|
|
file = new File( TEXT("MUI"),
|
|
TEXT("Muisetup.exe"),
|
|
dirPath,
|
|
TEXT("Muisetup.exe"),
|
|
10);
|
|
dirList->add(file);
|
|
file = new File( TEXT("MUI"),
|
|
TEXT("Muisetup.hlp"),
|
|
dirPath,
|
|
TEXT("Muisetup.hlp"),
|
|
10);
|
|
dirList->add(file);
|
|
file = new File( TEXT("MUI"),
|
|
TEXT("Eula.txt"),
|
|
dirPath,
|
|
TEXT("Eula.txt"),
|
|
10);
|
|
dirList->add(file);
|
|
file = new File( TEXT("MUI"),
|
|
TEXT("Relnotes.txt"),
|
|
dirPath,
|
|
TEXT("Relnotes.txt"),
|
|
10);
|
|
dirList->add(file);
|
|
file = new File( TEXT("MUI"),
|
|
TEXT("Readme.txt"),
|
|
dirPath,
|
|
TEXT("Readme.txt"),
|
|
10);
|
|
dirList->add(file);
|
|
file = new File( TEXT("MUI"),
|
|
TEXT("Mui.inf"),
|
|
dirPath,
|
|
TEXT("Mui.inf"),
|
|
10);
|
|
dirList->add(file);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ValidateLanguage()
|
|
//
|
|
// Verify if the language given is valid and checks is the files are
|
|
// available.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
BOOL ValidateLanguage(LPSTR dirPath, LPSTR langName, DWORD binType)
|
|
{
|
|
CHAR langPath[MAX_PATH] = {0};
|
|
|
|
//
|
|
// Check if the binary type in order to determine the right path.
|
|
//
|
|
if (binType == BIN_32)
|
|
{
|
|
sprintf(langPath, "%s\\%s\\i386.uncomp", dirPath, langName);
|
|
}
|
|
else
|
|
{
|
|
sprintf(langPath, "%s\\%s\\ia64.uncomp", dirPath, langName);
|
|
}
|
|
|
|
return (DirectoryExist(langPath));
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DirectoryExist()
|
|
//
|
|
// Verify if the given directory exists and contains files.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
BOOL DirectoryExist(LPSTR dirPath)
|
|
{
|
|
WIN32_FIND_DATA FindData;
|
|
HANDLE FindHandle;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
if (dirPath == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// See if the language group directory exists.
|
|
//
|
|
FindHandle = FindFirstFile(dirPath, &FindData);
|
|
if (FindHandle != INVALID_HANDLE_VALUE)
|
|
{
|
|
FindClose(FindHandle);
|
|
if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
//
|
|
// Return success.
|
|
//
|
|
return (TRUE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Return failure.
|
|
//
|
|
if (!bSilence)
|
|
{
|
|
printf("ERR[%s]: No files found in the directory.\n", dirPath);
|
|
}
|
|
|
|
return (FALSE);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ConvertLanguage()
|
|
//
|
|
// Look into mui.inf file for the corresponding language identifier.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
WORD ConvertLanguage(LPSTR dirPath, LPSTR langName)
|
|
{
|
|
HINF hFile;
|
|
CHAR muiFilePath[MAX_PATH];
|
|
CHAR muiLang[30];
|
|
UINT lineCount, lineNum;
|
|
INFCONTEXT context;
|
|
DWORD langId = 0x00000000;
|
|
|
|
//
|
|
// Create the path to open the mui.inf file
|
|
//
|
|
sprintf(muiFilePath, "%s\\mui.inf", dirPath);
|
|
sprintf(muiLang, "%s.MUI", langName);
|
|
|
|
//
|
|
// Open the MUI.INF file.
|
|
//
|
|
hFile = SetupOpenInfFile(muiFilePath, NULL, INF_STYLE_WIN4, NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
return (0x0000);
|
|
}
|
|
|
|
//
|
|
// Get the number of Language.
|
|
//
|
|
lineCount = (UINT)SetupGetLineCount(hFile, TEXT("Languages"));
|
|
if (lineCount > 0)
|
|
{
|
|
//
|
|
// Go through all language of the list to find a .
|
|
//
|
|
CHAR langID[MAX_PATH];
|
|
CHAR name[MAX_PATH];
|
|
for (lineNum = 0; lineNum < lineCount; lineNum++)
|
|
{
|
|
if (SetupGetLineByIndex(hFile, TEXT("Languages"), lineNum, &context) &&
|
|
SetupGetStringField(&context, 0, langID, MAX_PATH, NULL) &&
|
|
SetupGetStringField(&context, 1, name, MAX_PATH, NULL))
|
|
{
|
|
if ( _tcsicmp(name, muiLang) == 0)
|
|
{
|
|
langId = TransNum(langID);
|
|
SetupCloseInfFile(hFile);
|
|
return (WORD)(langId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Close inf handle
|
|
//
|
|
SetupCloseInfFile(hFile);
|
|
|
|
return (0x0000);
|
|
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PrintFileList
|
|
//
|
|
// Print a file list in XML format.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void PrintFileList(FileList* list, HANDLE hFile, BOOL compressed, BOOL bWinDir)
|
|
{
|
|
if (compressed)
|
|
{
|
|
File* item;
|
|
CHAR itemDescription[4096];
|
|
CHAR spaces[30];
|
|
int j;
|
|
|
|
item = list->getFirst();
|
|
while (item != NULL)
|
|
{
|
|
LPSTR refDirPtr = NULL;
|
|
LPSTR dirPtr = NULL;
|
|
CHAR dirName[MAX_PATH];
|
|
CHAR dirName2[MAX_PATH];
|
|
LPSTR dirPtr2 = NULL;
|
|
LPSTR dirLvlPtr = NULL;
|
|
INT dirLvlCnt = 0;
|
|
BOOL componentInit = FALSE;
|
|
BOOL directoryInit = FALSE;
|
|
Uuid* uuid;
|
|
File* toBeRemoved;
|
|
CHAR fileObjectName[MAX_PATH];
|
|
UINT matchCount;
|
|
|
|
|
|
//
|
|
// Check destination directory.
|
|
//
|
|
if (item->isWindowsDir() != bWinDir)
|
|
{
|
|
item = item->getNext();
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Check is the destination is base dir
|
|
//
|
|
if (*(item->getDirectoryDestination()) == '\0')
|
|
{
|
|
//
|
|
// Component
|
|
//
|
|
uuid = new Uuid();
|
|
for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s<Component Id='%s'>Content%i", spaces, uuid->getString(), dwComponentCounter);
|
|
delete uuid;
|
|
PrintLine(hFile, itemDescription);
|
|
|
|
//
|
|
// File
|
|
//
|
|
for (j = -1; j < dirLvlCnt+2; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
removeSpace(item->getName(), fileObjectName);
|
|
sprintf( itemDescription,
|
|
"%s<File Name=\"%s\" LongName=\"%s\" Compressed='yes' src=\"%s\\%s\">%s.%i</File>",
|
|
spaces,
|
|
item->getName(),
|
|
item->getName(),
|
|
item->getSrcDir(),
|
|
item->getSrcName(),
|
|
fileObjectName,
|
|
dwComponentCounter);
|
|
PrintLine(hFile, itemDescription);
|
|
|
|
//
|
|
// </Component>
|
|
//
|
|
for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s</Component>", spaces);
|
|
PrintLine(hFile, itemDescription);
|
|
dwComponentCounter++;
|
|
|
|
toBeRemoved = item;
|
|
item = item->getNext();
|
|
list->remove(toBeRemoved);
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Print directory
|
|
//
|
|
sprintf(dirName, "%s",item->getDirectoryDestination());
|
|
dirPtr = dirName;
|
|
refDirPtr = dirPtr;
|
|
while (dirPtr != NULL)
|
|
{
|
|
dirLvlPtr = strchr(dirPtr, '\\');
|
|
if (dirLvlPtr != NULL)
|
|
{
|
|
*dirLvlPtr = '\0';
|
|
for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s<Directory Name=\"%s\">%s%i", spaces, dirPtr, dirPtr, dwDirectoryCounter);
|
|
dwDirectoryCounter++;
|
|
PrintLine(hFile, itemDescription);
|
|
dirPtr = dirLvlPtr + 1;
|
|
dirLvlCnt++;
|
|
|
|
//
|
|
// Print all file under this specific directory
|
|
//
|
|
sprintf( dirName2, "%s", item->getDirectoryDestination());
|
|
dirName2[dirLvlPtr-refDirPtr] = '\0';
|
|
File* sameLvlItem = NULL;
|
|
matchCount = 0;
|
|
while((sameLvlItem = list->search(item, dirName2)) != NULL)
|
|
{
|
|
/* //
|
|
// Directory
|
|
//
|
|
if (!directoryInit)
|
|
{
|
|
for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s<Directory Name=\"%s\">%s%i", spaces, dirPtr, dirPtr, dwDirectoryCounter);
|
|
dwDirectoryCounter++;
|
|
PrintLine(hFile, itemDescription);
|
|
dirLvlCnt++;
|
|
directoryInit = TRUE;
|
|
}
|
|
*/
|
|
//
|
|
// Component
|
|
//
|
|
if (!componentInit)
|
|
{
|
|
uuid = new Uuid();
|
|
for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s<Component Id='%s'>Content%i", spaces, uuid->getString(), dwComponentCounter);
|
|
delete uuid;
|
|
PrintLine(hFile, itemDescription);
|
|
dwComponentCounter++;
|
|
componentInit = TRUE;
|
|
}
|
|
|
|
//
|
|
// File
|
|
//
|
|
matchCount++;
|
|
for (j = -1; j < dirLvlCnt+2; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
removeSpace(sameLvlItem->getName(), fileObjectName);
|
|
sprintf( itemDescription,
|
|
"%s<File Name=\"%s\" LongName=\"%s\" Compressed='yes' src=\"%s\\%s\">%s.%i</File>",
|
|
spaces,
|
|
sameLvlItem->getName(),
|
|
sameLvlItem->getName(),
|
|
sameLvlItem->getSrcDir(),
|
|
sameLvlItem->getSrcName(),
|
|
fileObjectName,
|
|
dwComponentCounter);
|
|
PrintLine(hFile, itemDescription);
|
|
|
|
list->remove(sameLvlItem);
|
|
}
|
|
|
|
if (matchCount)
|
|
{
|
|
//
|
|
// File
|
|
//
|
|
for (j = -1; j < dirLvlCnt+2; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
removeSpace(item->getName(), fileObjectName);
|
|
sprintf( itemDescription,
|
|
"%s<File Name=\"%s\" LongName=\"%s\" Compressed='yes' src=\"%s\\%s\">%s.%i</File>",
|
|
spaces,
|
|
item->getName(),
|
|
item->getName(),
|
|
item->getSrcDir(),
|
|
item->getSrcName(),
|
|
fileObjectName,
|
|
dwComponentCounter);
|
|
PrintLine(hFile, itemDescription);
|
|
dirPtr = NULL;
|
|
}
|
|
|
|
//
|
|
// Close component
|
|
//
|
|
if (componentInit)
|
|
{
|
|
for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s</Component>", spaces);
|
|
PrintLine(hFile, itemDescription);
|
|
componentInit = FALSE;
|
|
}
|
|
|
|
//
|
|
// Close directory
|
|
//
|
|
if (directoryInit)
|
|
{
|
|
dirLvlCnt--;
|
|
for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s</Directory>", spaces);
|
|
PrintLine(hFile, itemDescription);
|
|
directoryInit = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!directoryInit)
|
|
{
|
|
for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s<Directory Name=\"%s\">%s%i", spaces, dirPtr, dirPtr, dwDirectoryCounter);
|
|
dwDirectoryCounter++;
|
|
PrintLine(hFile, itemDescription);
|
|
dirLvlCnt++;
|
|
directoryInit = TRUE;
|
|
}
|
|
|
|
//
|
|
// Component
|
|
//
|
|
if (!componentInit)
|
|
{
|
|
uuid = new Uuid();
|
|
for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s<Component Id='%s'>Content%i", spaces, uuid->getString(), dwComponentCounter);
|
|
delete uuid;
|
|
PrintLine(hFile, itemDescription);
|
|
componentInit = TRUE;
|
|
}
|
|
|
|
//
|
|
// Print all file under this specific directory
|
|
//
|
|
File* sameLvlItem;
|
|
while((sameLvlItem = list->search(item, item->getDirectoryDestination())) != NULL)
|
|
{
|
|
//
|
|
// File
|
|
//
|
|
for (j = -1; j < dirLvlCnt+2; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
removeSpace(sameLvlItem->getName(), fileObjectName);
|
|
sprintf( itemDescription,
|
|
"%s<File Name=\"%s\" LongName=\"%s\" Compressed='yes' src=\"%s\\%s\">%s.%i</File>",
|
|
spaces,
|
|
sameLvlItem->getName(),
|
|
sameLvlItem->getName(),
|
|
sameLvlItem->getSrcDir(),
|
|
sameLvlItem->getSrcName(),
|
|
fileObjectName,
|
|
dwComponentCounter);
|
|
PrintLine(hFile, itemDescription);
|
|
|
|
list->remove(sameLvlItem);
|
|
}
|
|
|
|
//
|
|
// File
|
|
//
|
|
for (j = -1; j < dirLvlCnt+2; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
removeSpace(item->getName(), fileObjectName);
|
|
sprintf( itemDescription,
|
|
"%s<File Name=\"%s\" LongName=\"%s\" Compressed='yes' src=\"%s\\%s\">%s.%i</File>",
|
|
spaces,
|
|
item->getName(),
|
|
item->getName(),
|
|
item->getSrcDir(),
|
|
item->getSrcName(),
|
|
fileObjectName,
|
|
dwComponentCounter);
|
|
PrintLine(hFile, itemDescription);
|
|
dwComponentCounter++;
|
|
dirPtr = NULL;
|
|
|
|
//
|
|
// Close component
|
|
//
|
|
if (componentInit)
|
|
{
|
|
for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s</Component>", spaces);
|
|
PrintLine(hFile, itemDescription);
|
|
componentInit = FALSE;
|
|
}
|
|
|
|
//
|
|
// Close directory
|
|
//
|
|
if (directoryInit)
|
|
{
|
|
dirLvlCnt--;
|
|
for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s</Directory>", spaces);
|
|
PrintLine(hFile, itemDescription);
|
|
directoryInit = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i = dirLvlCnt; i > 0; i--)
|
|
{
|
|
spaces[i] = '\0';
|
|
sprintf( itemDescription, "%s</Directory>", spaces);
|
|
PrintLine(hFile, itemDescription);
|
|
}
|
|
|
|
if (list->getFileNumber() > 1)
|
|
{
|
|
if (item->getNext() != NULL)
|
|
{
|
|
item = item->getNext();
|
|
list->remove(item->getPrevious());
|
|
}
|
|
else
|
|
{
|
|
list->remove(item);
|
|
item = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
list->remove(item);
|
|
item = NULL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
File* item;
|
|
CHAR itemDescription[4096];
|
|
CHAR spaces[30];
|
|
int j;
|
|
|
|
item = list->getFirst();
|
|
while (item != NULL)
|
|
{
|
|
LPSTR dirPtr = NULL;
|
|
LPSTR dirLvlPtr = NULL;
|
|
INT dirLvlCnt = 0;
|
|
|
|
//
|
|
// Print directory
|
|
//
|
|
dirPtr = item->getDirectoryDestination();
|
|
while (dirPtr != NULL)
|
|
{
|
|
dirLvlPtr = strchr(dirPtr, '\\');
|
|
if (dirLvlPtr != NULL)
|
|
{
|
|
*dirLvlPtr = '\0';
|
|
for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s<Directory Name=\"%s\">%s%i", spaces, dirPtr, dirPtr, dwDirectoryCounter);
|
|
dwDirectoryCounter++;
|
|
PrintLine(hFile, itemDescription);
|
|
dirPtr = dirLvlPtr + 1;
|
|
dirLvlCnt++;
|
|
}
|
|
else
|
|
{
|
|
Uuid* uuid = new Uuid();
|
|
|
|
for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s<Directory Name=\"%s\">%s%i", spaces, dirPtr, dirPtr, dwDirectoryCounter);
|
|
dwDirectoryCounter++;
|
|
PrintLine(hFile, itemDescription);
|
|
dirLvlCnt++;
|
|
|
|
//
|
|
// Component
|
|
//
|
|
for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s<Component Id='%s'>Content%i", spaces, uuid->getString(), dwComponentCounter);
|
|
delete uuid;
|
|
PrintLine(hFile, itemDescription);
|
|
|
|
//
|
|
// File
|
|
//
|
|
for (j = -1; j < dirLvlCnt+2; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription,
|
|
"%s<File Name=\"%s\" LongName=\"%s\" Compressed='yes' src=\"%s\\%s\">%s.%i</File>",
|
|
spaces,
|
|
item->getName(),
|
|
item->getName(),
|
|
item->getSrcDir(),
|
|
item->getSrcName(),
|
|
item->getName(),
|
|
dwComponentCounter);
|
|
PrintLine(hFile, itemDescription);
|
|
dwComponentCounter++;
|
|
dirPtr = NULL;
|
|
}
|
|
}
|
|
|
|
for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
|
|
sprintf( itemDescription, "%s</Component>", spaces);
|
|
PrintLine(hFile, itemDescription);
|
|
for (int i = dirLvlCnt; i > 0; i--)
|
|
{
|
|
spaces[i] = '\0';
|
|
sprintf( itemDescription, "%s</Directory>", spaces);
|
|
PrintLine(hFile, itemDescription);
|
|
}
|
|
|
|
item = item->getNext();
|
|
}
|
|
}
|
|
/****************** DEBUG ******************
|
|
File* item;
|
|
CHAR itemDescription[4096];
|
|
|
|
item = list->getFirst();
|
|
while (item != NULL)
|
|
{
|
|
//
|
|
// Item description
|
|
//
|
|
sprintf(itemDescription,
|
|
" Source: %s\\%s",
|
|
item->getSrcDir(),
|
|
item->getSrcName());
|
|
PrintLine(hFile, itemDescription);
|
|
sprintf(itemDescription,
|
|
" Destination: %s\\%s",
|
|
item->getDirectoryDestination(),
|
|
item->getName());
|
|
PrintLine(hFile, itemDescription);
|
|
PrintLine(hFile, "");
|
|
|
|
item = item->getNext();
|
|
}
|
|
****************** DEBUG ******************/
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PrintLine
|
|
//
|
|
// Add a line at the end of the file.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL PrintLine(HANDLE hFile, LPCSTR lpLine)
|
|
{
|
|
DWORD dwBytesWritten;
|
|
|
|
SetFilePointer(hFile, 0, NULL, FILE_END);
|
|
|
|
WriteFile( hFile,
|
|
lpLine,
|
|
_tcslen(lpLine) * sizeof(TCHAR),
|
|
&dwBytesWritten,
|
|
NULL );
|
|
|
|
SetFilePointer(hFile, 0, NULL, FILE_END);
|
|
|
|
WriteFile( hFile,
|
|
TEXT("\r\n"),
|
|
_tcslen(TEXT("\r\n")) * sizeof(TCHAR),
|
|
&dwBytesWritten,
|
|
NULL );
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CreateOutputFile()
|
|
//
|
|
// Create the file that would received the package file contents.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
HANDLE CreateOutputFile(LPSTR filename)
|
|
{
|
|
SECURITY_ATTRIBUTES SecurityAttributes;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
if (filename == NULL)
|
|
{
|
|
return INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
//
|
|
// Create a security descriptor the output file.
|
|
//
|
|
SecurityAttributes.nLength = sizeof(SecurityAttributes);
|
|
SecurityAttributes.lpSecurityDescriptor = NULL;
|
|
SecurityAttributes.bInheritHandle = FALSE;
|
|
|
|
//
|
|
// Create the file.
|
|
//
|
|
return CreateFile( filename,
|
|
GENERIC_WRITE,
|
|
0,
|
|
&SecurityAttributes,
|
|
OPEN_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL );
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// removeSpace
|
|
//
|
|
// Remove all space from a string.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
VOID removeSpace(LPSTR src, LPSTR dest)
|
|
{
|
|
LPSTR strSrcPtr = src;
|
|
LPSTR strDestPtr = dest;
|
|
|
|
while (*strSrcPtr != '\0')
|
|
{
|
|
if (*strSrcPtr != ' ')
|
|
{
|
|
*strDestPtr = *strSrcPtr;
|
|
strDestPtr++;
|
|
}
|
|
strSrcPtr++;
|
|
}
|
|
*strDestPtr = '\0';
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// TransNum
|
|
//
|
|
// Converts a number string to a dword value (in hex).
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
DWORD TransNum(LPTSTR lpsz)
|
|
{
|
|
DWORD dw = 0L;
|
|
TCHAR c;
|
|
|
|
while (*lpsz)
|
|
{
|
|
c = *lpsz++;
|
|
|
|
if (c >= TEXT('A') && c <= TEXT('F'))
|
|
{
|
|
c -= TEXT('A') - 0xa;
|
|
}
|
|
else if (c >= TEXT('0') && c <= TEXT('9'))
|
|
{
|
|
c -= TEXT('0');
|
|
}
|
|
else if (c >= TEXT('a') && c <= TEXT('f'))
|
|
{
|
|
c -= TEXT('a') - 0xa;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
dw *= 0x10;
|
|
dw += c;
|
|
}
|
|
return (dw);
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Usage
|
|
//
|
|
// Print the fonction usage.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void Usage()
|
|
{
|
|
printf("Create filecontents_CORE.wxm, filecontents_PRO.wxm and filecontents_SRV.wxm\n");
|
|
printf("Usage: infparser /b:[32|64] /l:<lang> /f:[p|s|a|d] /s:<dir> /o:<file> /v\n");
|
|
printf(" where\n");
|
|
printf(" /b means the binary.\n");
|
|
printf(" 32: i386\n");
|
|
printf(" 64: ia64\n");
|
|
printf(" /l means the language flag.\n");
|
|
printf(" <lang>: is the target language\n");
|
|
printf(" /f means the flavor.\n");
|
|
printf(" p: Professional\n");
|
|
printf(" s: Server\n");
|
|
printf(" a: Advanced Server\n");
|
|
printf(" d: Data Center\n");
|
|
printf(" /s means the location of the binairy data.\n");
|
|
printf(" <dir>: Fully qualified path\n");
|
|
printf(" /o means the xml file contents of specific flavor.\n");
|
|
printf(" <file>: Fully qualified path\n");
|
|
printf(" /v means the verbose mode [optional].\n");
|
|
}
|