|
|
/*++
Copyright (c) 2002 Microsoft Corporation
Module Name:
engine.c
Abstract:
Token Generator for Cross Language Migration Tool
Author:
Rerkboon Suwanasuk 01-May-2002 Created
Revision History:
<alias> <date> <comments>
--*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setupapi.h>
#include <shlwapi.h>
#include "Common.h"
//-----------------------------------------------------------------------------
//
// Function: GenerateTokenFile
//
// Synopsis: Entry function for our program.
//
// Returns: HRESULT
//
// History: 02/07/2002 Rerkboos Created
//
// Notes: none
//
//-----------------------------------------------------------------------------
HRESULT GenerateTokenFile(VOID) { HRESULT hr; BOOL bRet; HINF hTemplateFile; HANDLE hFile; WCHAR wszFullTemplateFilePath[MAX_PATH]; WCHAR wszFullOutputFilePath[MAX_PATH]; WCHAR wszLCIDSectionName[32]; LPWSTR lpOutputFileBuffer = NULL; LPWSTR lpFileName; size_t cbOutputFileBuffer;
//
// Set some private environment variables for use in our program
//
if (!SetPrivateEnvironmentVar()) { wprintf(TEXT("Error! Cannot set private environment variables.\n")); return E_FAIL; }
hTemplateFile = SetupOpenInfFile(g_wszTemplateFile, NULL, INF_STYLE_OLDNT, NULL); if (hTemplateFile != INVALID_HANDLE_VALUE) { //
// Read the [SourcePath] section from template INF file
//
hr = ReadSourcePathData(hTemplateFile); if (SUCCEEDED(hr)) { hr = InitOutputFile(g_wszOutputFile, wszLCIDSectionName, ARRAYSIZE(wszLCIDSectionName)); if (SUCCEEDED(hr)) { //
// Resolve generic strings
//
hr = ResolveStringsSection(hTemplateFile, TEXT("Strings")); if (FAILED(hr)) { goto EXIT; }
//
// Resolve lang-specific strings
//
hr = ResolveStringsSection(hTemplateFile, wszLCIDSectionName); if (FAILED(hr)) { goto EXIT; }
//
// Remove unneeded sub string
//
hr = RemoveUnneededStrings(hTemplateFile); if (FAILED(hr)) { goto EXIT; }
//
// Extract sub string
//
hr = ExtractStrings(hTemplateFile); if (FAILED(hr)) { goto EXIT; } } } else { wprintf( TEXT("Error! Cannot read [SourcePath] section\n") ); }
SetupCloseInfFile(hTemplateFile); } else { wprintf(TEXT("Error! Cannot open template file: %s\n"), g_wszTemplateFile); hr = HRESULT_FROM_WIN32(GetLastError()); }
EXIT: return hr; }
//-----------------------------------------------------------------------------
//
// Function: ReadSourcePathData
//
// Synopsis: Read [SourcePath] section from template INF file,
// then store all the source paths into the structure.
// This structure will be used to find the location of
// resource files.
//
// Returns: HRESULT
//
// History: 02/07/2002 Rerkboos Created
//
// Notes: none
//
//-----------------------------------------------------------------------------
HRESULT ReadSourcePathData( HINF hTemplateFile ) { HRESULT hr = E_FAIL; BOOL bRet; size_t nLineIndex; WCHAR wszValue[MAX_PATH]; WCHAR wszSrcPathSection[32]; INFCONTEXT InfContext;
if (hTemplateFile == INVALID_HANDLE_VALUE) { return E_INVALIDARG; }
hr = StringCchPrintf(wszSrcPathSection, ARRAYSIZE(wszSrcPathSection), TEXT("SourcePath.%.4x"), g_lcidTarget); if (FAILED(hr)) { return hr; }
//
// Extract the source paths from INF and save to global structure
//
g_dwSrcCount = SetupGetLineCount(hTemplateFile, wszSrcPathSection);
for (nLineIndex = 0 ; nLineIndex < g_dwSrcCount ; nLineIndex++) { bRet = SetupGetLineByIndex(hTemplateFile, wszSrcPathSection, nLineIndex, &InfContext); if (bRet) { //
// Get the name of each source path
//
bRet = SetupGetStringField(&InfContext, 0, wszValue, ARRAYSIZE(wszValue), NULL); if (bRet) { hr = StringCchCopy(g_SrcPath[nLineIndex].wszSrcName, ARRAYSIZE(g_SrcPath[nLineIndex].wszSrcName), wszValue); if (SUCCEEDED(hr)) { //
// Get the path associated to the source name
//
if (SetupGetStringField(&InfContext, 1, wszValue, ARRAYSIZE(wszValue), NULL)) { hr = StringCchCopy(g_SrcPath[nLineIndex].wszPath, ARRAYSIZE(g_SrcPath[nLineIndex].wszPath), wszValue); } } } else { hr = HRESULT_FROM_WIN32(GetLastError()); } } else { hr = HRESULT_FROM_WIN32(GetLastError()); }
if (FAILED(hr)) { break; } }
return hr; }
//-----------------------------------------------------------------------------
//
// Function: ResolveStringsSection
//
// Synopsis: Resolve all strings under specified section name in template
// file, then write the resolved strings to output file.
//
// Returns: HRESULT
//
// History: 03/27/2002 Rerkboos Created
//
// Notes:
//
//-----------------------------------------------------------------------------
HRESULT ResolveStringsSection( HINF hTemplateFile, // Handle to template file
LPCWSTR lpSectionName // Section name in template file to resolve
) { HRESULT hr = E_FAIL; BOOL bRet; LONG lLineCount;
if (hTemplateFile == INVALID_HANDLE_VALUE || lpSectionName == NULL) { return E_INVALIDARG; }
wprintf(TEXT("Start resolving strings in section [%s]:\n"), lpSectionName);
lLineCount = SetupGetLineCount(hTemplateFile, lpSectionName); if (lLineCount >= 0) { INFCONTEXT context; LONG lLineIndex; LPWSTR lpKey; LPWSTR lpValue; DWORD cchKey; DWORD cchValue; DWORD cbWritten;
//
// Resolve strings under string section
//
for (lLineIndex = 0 ; lLineIndex < lLineCount ; lLineIndex++) { bRet = SetupGetLineByIndex(hTemplateFile, lpSectionName, lLineIndex, &context); if (bRet) { hr = ResolveLine(&context, &lpKey, &cchKey, &lpValue, &cchValue); if (SUCCEEDED(hr)) { hr = WriteToOutputFile(g_wszOutputFile, lpKey, lpValue); if (FAILED(hr)) { wprintf(TEXT("[FAIL] - Cannot write to output file\n")); break; }
MEMFREE(lpKey); MEMFREE(lpValue); } else { wprintf(TEXT("[FAIL] - Cannot process line %d in template file\n"), lLineIndex); hr = HRESULT_FROM_WIN32(GetLastError()); break; } } else { hr = HRESULT_FROM_WIN32(GetLastError()); break; } } } else { hr = HRESULT_FROM_WIN32(GetLastError()); }
wprintf(TEXT("Finish resolving strings in section [%s]: hr = 0x%X\n\n"), lpSectionName, hr);
return hr; }
//-----------------------------------------------------------------------------
//
// Function: ResolveLine
//
// Synopsis: Resolve a string value from input INF context.
//
// Returns: HRESULT
//
// History: 03/27/2002 Rerkboos Created
//
// Notes: This function will allocate memory for lplpKey and lplpValue,
// Caller needs to free memory using HeapFree().
//
//-----------------------------------------------------------------------------
HRESULT ResolveLine( PINFCONTEXT lpContext, // INF line context
LPWSTR *lplpKey, // Pointer to newly allocated buffer for Key name
LPDWORD lpcchKey, // Size of allocated buffer for Key name
LPWSTR *lplpValue, // Pointer to newly allocated buffer for Value
LPDWORD lpcchValue // Size of allocated buffer for Value
) { HRESULT hr = E_FAIL; BOOL bRet; DWORD cchKey; DWORD cchRequired;
if (lplpKey == NULL || lpcchKey == NULL || lplpValue == NULL || lpcchValue == NULL) { return E_INVALIDARG; }
bRet = SetupGetStringField(lpContext, 0, NULL, 0, &cchKey); if (bRet) { *lplpKey = MEMALLOC(cchKey * sizeof(WCHAR)); if (*lplpKey) { *lpcchKey = cchKey;
SetupGetStringField(lpContext, 0, *lplpKey, cchKey, &cchRequired);
hr = ResolveValue(lpContext, lplpValue, lpcchValue); if (FAILED(hr)) { wprintf(TEXT("[FAIL] Cannot resolve Key [%s], hr = 0x%X\n"), *lplpKey, hr); MEMFREE(*lplpKey); } } } else { hr = HRESULT_FROM_WIN32(GetLastError()); }
return hr; }
//-----------------------------------------------------------------------------
//
// Function: InitOutputFile
//
// Synopsis: Initialize output file. Output file is always a Unicode text
// file. This function will create a section name [Strings.XXXX]
// where XXXX is locale ID that user put in command line
//
// Returns: S_OK if succeeded
//
// History: 03/27/2002 Rerkboos Created
//
// Notes:
//
//-----------------------------------------------------------------------------
HRESULT InitOutputFile( LPCWSTR lpFileName, // Output file name to be created
LPWSTR lpSectionName, // Buffer to store destination section name
DWORD cchSectionName // Size of buffer in WCHAR
) { HRESULT hr = S_OK; BOOL bRet; HANDLE hFile;
if (lpSectionName == NULL) { return E_INVALIDARG; }
hFile = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { DWORD cbWritten; WCHAR wszSectionHeader[32];
// Unicode BOM = 0xFEFF
wszSectionHeader[0] = 0xFEFF;
// Create a section name - [Strings.XXXX] where XXXX is locale ID in Hex
hr = StringCchPrintf(wszSectionHeader + 1, ARRAYSIZE(wszSectionHeader) - 1, TEXT("[Strings.%.4x]\r\n"), g_lcidTarget); if (SUCCEEDED(hr)) { // Write Unicode BOM and String section header to output file
bRet = WriteFile(hFile, wszSectionHeader, lstrlen(wszSectionHeader) * sizeof(WCHAR), &cbWritten, NULL); if (!bRet) { hr = HRESULT_FROM_WIN32(GetLastError()); } }
CloseHandle(hFile); } else { hr = HRESULT_FROM_WIN32(GetLastError()); }
// If no error occurred, return target String section back to caller
if (SUCCEEDED(hr)) { hr = StringCchPrintf(lpSectionName, cchSectionName, TEXT("Strings.%.4x"), g_lcidTarget); }
return hr; }
//-----------------------------------------------------------------------------
//
// Function: WriteToOutputFile
//
// Synopsis: Write Key and Value to output file
//
// Returns: S_OK if succeeded
//
// History: 03/27/2002 Rerkboos Created
//
// Notes:
//
//-----------------------------------------------------------------------------
HRESULT WriteToOutputFile( LPCWSTR lpFileName, // Output file name
LPCWSTR lpKey, // Key name
LPCWSTR lpValue // Value name
) { HRESULT hr = S_OK; BOOL bRet; LPWSTR lpQuoted; DWORD cchQuoted;
static WCHAR wszOutputLCIDSection[32];
//
// Create the target string section name in output file
//
if (wszOutputLCIDSection[0] == TEXT('\0')) { hr = StringCchPrintf(wszOutputLCIDSection, ARRAYSIZE(wszOutputLCIDSection), TEXT("Strings.%.4x"), g_lcidTarget); if (FAILED(hr)) { return hr; } }
//
// Write the key and value to output file
//
cchQuoted = lstrlen(lpValue) + lstrlen(TEXT("\"\"")) + 1; lpQuoted = (LPWSTR) MEMALLOC(cchQuoted * sizeof(WCHAR)); if (lpQuoted) { hr = StringCchPrintf(lpQuoted, cchQuoted, TEXT("\"%s\""), lpValue); if (SUCCEEDED(hr)) { bRet = WritePrivateProfileString(wszOutputLCIDSection, lpKey, lpQuoted, lpFileName); if (!bRet) { hr = HRESULT_FROM_WIN32(GetLastError()); } }
MEMFREE(lpQuoted); } else { hr = E_OUTOFMEMORY; }
return hr; }
//-----------------------------------------------------------------------------
//
// Function: ResolveValue
//
// Synopsis: Resolve the string value from various resource.
// Following is the format in template file
//
// Key = INF, [Src], [INF File], [Section], [Key Name]
// Key = DLL, [Src], [DLL File], [Resource ID]
// Key = MSG, [Src], [DLL File], [Message ID]
// Key = STR, [String value]
//
// Returns: HRESULT
//
// History: 02/07/2002 Rerkboos Created
//
// Notes: Caller need to free the allocated buffer.
//
//-----------------------------------------------------------------------------
HRESULT ResolveValue( PINFCONTEXT pInfContext, // INF line context of template file
LPWSTR *lplpValue, // Address of pointer to newly allocated Value buffer
LPDWORD lpcchValue // Address of pionter to size of Value buffer in WCHAR
) { HRESULT hr = E_FAIL; BOOL bRet; LPWSTR lpToken[8]; LONG lTokenCount; DWORD cchRequired; DWORD cchBuffer; LPWSTR lpBuffer; WCHAR wszSourceFile[MAX_PATH];
if (lplpValue == NULL || lpcchValue == NULL) { return E_INVALIDARG; }
// Query the required size of buffer to store the data
bRet = SetupGetMultiSzField(pInfContext, 1, NULL, 0, &cchRequired); if (!bRet) { return HRESULT_FROM_WIN32(GetLastError()); }
// Allocate the buffer to store a line from INF
cchBuffer = cchRequired; lpBuffer = (LPWSTR) MEMALLOC(cchBuffer * sizeof(WCHAR)); if (lpBuffer) { // Get the data from field 1 to the end of line to allocated buffer
bRet = SetupGetMultiSzField(pInfContext, 1, lpBuffer, cchBuffer, &cchRequired); if (bRet) { lTokenCount = TokenizeMultiSzString(lpBuffer, cchBuffer, lpToken, 8); if (lTokenCount >= 0) { if (CompareEngString(lpToken[0], TEXT_INF) == CSTR_EQUAL) { // INF, [Src], [INF File], [Section], [Key Name]
// [0] [1] [2] [3] [4]
if (lTokenCount == 5) { hr = ResolveSourceFile(lpToken[1], lpToken[2], wszSourceFile, ARRAYSIZE(wszSourceFile)); if (SUCCEEDED(hr)) { hr = GetStringFromINF(wszSourceFile, // Inf file name
lpToken[3], // Section name in Inf
lpToken[4], // Key name
lplpValue, lpcchValue); } } else { // Data format is invalid
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } } else if (CompareEngString(lpToken[0], TEXT_DLL) == CSTR_EQUAL) { // DLL, [Src], [DLL File], [Resource ID]
// [0] [1] [2] [3]
if (lTokenCount == 4) { hr = ResolveSourceFile(lpToken[1], lpToken[2], wszSourceFile, ARRAYSIZE(wszSourceFile)); if (SUCCEEDED(hr)) { hr = GetStringFromDLL(wszSourceFile, // Dll file name
_wtoi(lpToken[3]), lplpValue, lpcchValue); } } else { // Data format is invalid
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } } else if (CompareEngString(lpToken[0], TEXT_MSG) == CSTR_EQUAL) { // MSG, [Src], [DLL File], [Message ID]
// [0] [1] [2] [3]
if (lTokenCount == 4) { hr = ResolveSourceFile(lpToken[1], lpToken[2], wszSourceFile, ARRAYSIZE(wszSourceFile)); if (SUCCEEDED(hr)) { hr = GetStringFromMSG(wszSourceFile, // File name
_wtoi(lpToken[3]), // Message ID
g_lcidTarget, lplpValue, lpcchValue); } } else { // Data format is invalid
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } } else if (CompareEngString(lpToken[0], TEXT_STR) == CSTR_EQUAL) { // STR, [String]
// [0] [1]
if (lTokenCount == 2) { hr = GetStringFromSTR(lpToken[1], lplpValue, lpcchValue); } else { // Data format is invalid
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } } else { *lplpValue = NULL; *lpcchValue = 0; hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } } }
MEMFREE(lpBuffer); } else { hr = E_OUTOFMEMORY; }
return hr; }
HRESULT ResolveSourceFile( LPCWSTR lpSrcPathName, LPCWSTR lpSrcFileName, LPWSTR lpFullOutputPath, DWORD cchFullOutputPath ) { HRESULT hr; WCHAR wszCabPath[MAX_PATH]; WCHAR wszCab[MAX_PATH]; WCHAR wszFileInCab[MAX_PATH]; WCHAR wszExpandedCabPath[MAX_PATH]; DWORD dwErr;
if (lpFullOutputPath == NULL) { return E_INVALIDARG; }
//
// Resolve source file name and directory
//
hr = GetPathFromSourcePathName(lpSrcPathName, wszCabPath, ARRAYSIZE(wszCabPath)); if (SUCCEEDED(hr)) { hr = GetCabFileName(lpSrcFileName, wszCab, ARRAYSIZE(wszCab), wszFileInCab, ARRAYSIZE(wszFileInCab)); if (SUCCEEDED(hr)) { dwErr = ExpandEnvironmentStrings(wszCabPath, wszExpandedCabPath, ARRAYSIZE(wszExpandedCabPath)); if (dwErr > 0) { hr = CopyCompressedFile(wszCabPath, wszCab, wszFileInCab, lpFullOutputPath, cchFullOutputPath); } else { hr = HRESULT_FROM_WIN32(GetLastError()); } } }
return hr; }
//-----------------------------------------------------------------------------
//
// Function: GetStringFromINF
//
// Synopsis: Extract the string value from INF file
//
// Returns: HRESULT
//
// History: 02/07/2002 Rerkboos Created
//
// Notes: Caller need to free the allocated buffer (HeapFree)
//
//-----------------------------------------------------------------------------
HRESULT GetStringFromINF( LPCWSTR lpInfFile, // Full path name to Inf file
LPCWSTR lpSection, // Section name
LPCWSTR lpKey, // Key name
LPWSTR *lplpValue, // Address of pointer to point to the allocated buffer
LPDWORD lpcchValue //
) { HRESULT hr = E_FAIL; BOOL bRet; WCHAR wszFullPath[MAX_PATH]; HINF hInf; DWORD dwCharCount;
if (lplpValue == NULL) { return E_INVALIDARG; } *lplpValue = NULL; *lpcchValue = 0;
hInf = SetupOpenInfFile(lpInfFile, NULL, INF_STYLE_WIN4, NULL); if (hInf != INVALID_HANDLE_VALUE) { // Find out the size of buffer needed to store the string
bRet = SetupGetLineText(NULL, hInf, lpSection, lpKey, NULL, // No returned buffer
0, // No returned buffer size
lpcchValue); // Required size including null terminator
if (bRet) { // Allocate memory to store the string
*lplpValue = (LPWSTR) MEMALLOC(*lpcchValue * sizeof(WCHAR)); if (*lplpValue != NULL) { //
// Read the string from INF file
//
bRet = SetupGetLineText(NULL, hInf, lpSection, lpKey, *lplpValue, *lpcchValue, NULL); if (bRet) { hr = S_OK; } } else { SetLastError(ERROR_OUTOFMEMORY); } }
SetupCloseInfFile(hInf); }
// If something was wrong, clean up
if (hr != S_OK) { hr = HRESULT_FROM_WIN32(GetLastError()); *lpcchValue = 0; if (*lplpValue != NULL) { MEMFREE(*lplpValue); } }
return hr; }
//-----------------------------------------------------------------------------
//
// Function: GetStringFromDLL
//
// Synopsis: Extract the string value from String resource in DLL
//
// Returns: HRESULT
//
// History: 02/07/2002 Rerkboos Created
//
// Notes: Caller need to free the allocated buffer
//
//-----------------------------------------------------------------------------
HRESULT GetStringFromDLL( LPCWSTR lpDLLFile, // Full path to Dll file
UINT uStrID, // String ID
LPWSTR *lplpValue, // Address of pointer to point to the allocated buffer
LPDWORD lpcchValue //
) { HRESULT hr = E_FAIL; BOOL bRet; HMODULE hDLL; int cchCopied;
if (lplpValue == NULL || lpcchValue == NULL) { return E_INVALIDARG; }
*lplpValue = NULL; *lpcchValue = 0;
// Load resource DLL
hDLL = LoadLibraryEx(lpDLLFile, NULL, LOAD_LIBRARY_AS_DATAFILE); if (hDLL) { // Allocate memory to store the string
// There is no function to calculate buffer size needed, maximum is 65535 (from MSDN)
// Initially allocate 1024 WCHARs, Reallocate again if it's not big enough
*lpcchValue = 1024; *lplpValue = (LPWSTR) MEMALLOC(*lpcchValue * sizeof(WCHAR)); if (*lplpValue != NULL) { //
// Load the string from DLL
//
cchCopied = LoadString(hDLL, uStrID, *lplpValue, (int) *lpcchValue); if (cchCopied > 0) { hr = S_OK;
while (cchCopied == (int) (*lpcchValue - 1)) { // Allocated buffer is too small, reallocate more
LPWSTR lpOldBuffer;
lpOldBuffer = *lplpValue; *lpcchValue += 1024;
*lplpValue = MEMREALLOC(lpOldBuffer, *lpcchValue); if (*lplpValue == NULL) { // Error reallocating more memory
*lplpValue = lpOldBuffer; SetLastError(ERROR_OUTOFMEMORY); hr = E_FAIL; break; } else { hr = S_OK; }
cchCopied = LoadString(hDLL, uStrID, *lplpValue, (int) *lpcchValue); } } } else { SetLastError(ERROR_OUTOFMEMORY); }
FreeLibrary(hDLL); }
// If something was wrong, clean up
if (hr != S_OK) { hr = HRESULT_FROM_WIN32(GetLastError()); *lpcchValue = 0; if (*lplpValue != NULL) { MEMFREE(*lplpValue); } }
return hr; }
//-----------------------------------------------------------------------------
//
// Function: GetStringFromMSG
//
// Synopsis: Extract the string value from message table
//
// Returns: HRESULT
//
// History: 02/07/2002 Rerkboos Created
//
// Notes: Caller need to free the allocated buffer
//
//-----------------------------------------------------------------------------
HRESULT GetStringFromMSG( LPCWSTR lpDLLFile, // Full path to resource DLL
DWORD dwMsgID, // Message ID
DWORD dwLangID, // Language ID
LPWSTR *lplpValue, //
LPDWORD lpcchValue //
) { HRESULT hr = E_FAIL; BOOL bRet; WCHAR wszFullPath[MAX_PATH]; HMODULE hDLL; LPWSTR lpTmpBuffer; int nRet;
if (lplpValue == NULL || lpcchValue == NULL) { return E_INVALIDARG; }
*lplpValue = NULL; *lpcchValue = 0;
// Load the resource DLL
hDLL = LoadLibraryEx(lpDLLFile, NULL, DONT_RESOLVE_DLL_REFERENCES); if (hDLL != NULL) { // Load the string from message table in DLL
// FormatMessage will allocate buffer for the data using LocalAlloc()
// need to free with LocalFree()
bRet = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, hDLL, dwMsgID, dwLangID, (LPWSTR) &lpTmpBuffer, 0, // use 0 to query the required buffer size
NULL); if (bRet) { // Trim all unnecessary leading and trailing spaces
RTrim(lpTmpBuffer);
// Allocate the buffer for returned data
*lpcchValue = lstrlen(lpTmpBuffer) + 1; *lplpValue = (LPWSTR) MEMALLOC(*lpcchValue * sizeof(WCHAR)); if (*lplpValue) { hr = StringCchCopy(*lplpValue, *lpcchValue, lpTmpBuffer); } else { SetLastError(ERROR_OUTOFMEMORY); }
LocalFree(lpTmpBuffer); }
FreeLibrary(hDLL); }
// If something was wrong, clean up
if (hr != S_OK) { hr = HRESULT_FROM_WIN32(GetLastError()); *lpcchValue = 0; if (*lplpValue != NULL) { MEMFREE(*lplpValue); } }
return hr; }
//-----------------------------------------------------------------------------
//
// Function: GetStringFromSTR
//
// Synopsis: Copy the hardcoded string into the newly allocated buffer
//
// Returns: HRESULT
//
// History: 02/07/2002 Rerkboos Created
//
// Notes: Caller need to free the allocated buffer
//
//-----------------------------------------------------------------------------
HRESULT GetStringFromSTR( LPCWSTR lpString, LPWSTR *lplpValue, //
LPDWORD lpcchValue //
) { HRESULT hr = E_FAIL;
if (lplpValue == NULL || lpcchValue == NULL) { return E_INVALIDARG; }
// Allocate buffer and copy string to buffer
*lpcchValue = lstrlen(lpString) + 1; *lplpValue = (LPWSTR) MEMALLOC(*lpcchValue * sizeof(WCHAR)); if (*lplpValue) { hr = StringCchCopy(*lplpValue, *lpcchValue, lpString); }
// If something was wrong, clean up
if (hr != S_OK) { hr = HRESULT_FROM_WIN32(GetLastError());
*lpcchValue = 0; if (*lplpValue != NULL) { MEMFREE(*lplpValue); } }
return hr; }
//-----------------------------------------------------------------------------
//
// Function: SetPrivateEnvironmentVar
//
// Synopsis: Set private environment variables to use within our program
//
// Returns: TRUE if succeeded, FALSE otherwise
//
// History: 02/07/2002 Rerkboos Created
//
// Notes: none
//
//-----------------------------------------------------------------------------
BOOL SetPrivateEnvironmentVar() { HRESULT hr; BOOL bRet; WCHAR wszValue[MAX_PATH];
//
// Set LANGID_DEC to decimal value of the system default UI language
//
hr = StringCchPrintf(wszValue, ARRAYSIZE(wszValue), TEXT("%04d"), g_lcidTarget); if (SUCCEEDED(hr)) { bRet = SetEnvironmentVariable(TEXT("LANGID_DEC"), wszValue); }
//
// Set LANGID_HEX to hexadecimal value of the system default UI language
//
hr = StringCchPrintf(wszValue, ARRAYSIZE(wszValue), TEXT("%04x"), g_lcidTarget); if (SUCCEEDED(hr)) { bRet = SetEnvironmentVariable(TEXT("LANGID_HEX"), wszValue); }
return bRet; }
//-----------------------------------------------------------------------------
//
// Function: RemoveUnneededStrings
//
// Synopsis: Remove all unneeded sub strings from the value of
// specified keys under [Remove] section
//
// Returns: HRESULT
//
// History: 02/07/2002 Rerkboos Created
//
// Notes: Caller need to free the allocated buffer
//
//-----------------------------------------------------------------------------
HRESULT RemoveUnneededStrings( HINF hTemplateFile // Handle of template file
) { HRESULT hr = E_FAIL; BOOL bRet; LONG lLineCount; LONG lLineIndex;
lLineCount = SetupGetLineCount(hTemplateFile, TEXT("Remove")); for (lLineIndex = 0 ; lLineIndex < lLineCount ; lLineIndex++) { INFCONTEXT Context;
bRet = SetupGetLineByIndex(hTemplateFile, TEXT("Remove"), lLineIndex, &Context); if (bRet) { WCHAR wszKey[64]; WCHAR wszType[8]; WCHAR wszValue[MAX_PATH]; DWORD cchRequired;
// Get type of unneeded string
bRet = SetupGetStringField(&Context, 0, wszKey, ARRAYSIZE(wszKey), &cchRequired) && SetupGetStringField(&Context, 1, wszType, ARRAYSIZE(wszType), &cchRequired) && SetupGetStringField(&Context, 2, wszValue, ARRAYSIZE(wszValue), &cchRequired); if (bRet) { if (CompareEngString(wszType, TEXT("STR")) == CSTR_EQUAL) { // STR type
hr = RemoveUnneededString(wszKey, wszValue); } else if (CompareEngString(wszType, TEXT("EXP")) == CSTR_EQUAL) { // EXP type
WCHAR wszUnneededString[MAX_PATH];
hr = GetExpString(wszUnneededString, ARRAYSIZE(wszUnneededString), wszValue); if (SUCCEEDED(hr)) { hr = RemoveUnneededString(wszKey, wszUnneededString); } } else { SetLastError(ERROR_INVALID_DATA); } } } }
if (hr == E_FAIL) { hr = HRESULT_FROM_WIN32(GetLastError()); }
return hr; }
//-----------------------------------------------------------------------------
//
// Function: RemoveUnneededString
//
// Synopsis: Remove an unneeded sub string from the value of specified key
//
// Returns: HRESULT
//
// History: 02/07/2002 Rerkboos Created
//
// Notes: Caller need to free the allocated buffer
//
//-----------------------------------------------------------------------------
HRESULT RemoveUnneededString( LPCWSTR lpKey, // Key name
LPCWSTR lpUnneededString // Unneeded sub string
) { HRESULT hr = E_FAIL; BOOL bRet; WCHAR wszOldValue[MAX_PATH]; WCHAR wszNewValue[MAX_PATH]; DWORD cchCopied;
cchCopied = GetPrivateProfileString(g_wszTargetLCIDSection, lpKey, TEXT(""), wszOldValue, ARRAYSIZE(wszOldValue), g_wszOutputFile); if (cchCopied > 0) { if (StrStrI(wszOldValue, lpUnneededString)) { // Unneeded string found
hr = StringSubstitute(wszNewValue, ARRAYSIZE(wszNewValue), wszOldValue, lpUnneededString, TEXT("")); if (SUCCEEDED(hr)) { WCHAR wszQuoted[MAX_PATH];
hr = StringCchPrintf(wszQuoted, ARRAYSIZE(wszQuoted), TEXT("\"%s\""), wszNewValue); if (SUCCEEDED(hr)) { bRet = WritePrivateProfileString(g_wszTargetLCIDSection, lpKey, wszQuoted, g_wszOutputFile); if (bRet) { hr = S_OK; } else { hr = HRESULT_FROM_WIN32(GetLastError()); } } } } else { // Unneeded string not found
hr = S_FALSE; } } else { hr = HRESULT_FROM_WIN32(GetLastError()); }
return hr; }
//-----------------------------------------------------------------------------
//
// Function: ExtractStrings
//
// Synopsis: Extract sub strings from the value of
// specified keys under [Extract] section
//
// Returns: HRESULT
//
// History: 08/01/2002 Geoffguo Created
//
// Notes: Caller need to free the allocated buffer
//
//-----------------------------------------------------------------------------
HRESULT ExtractStrings( HINF hTemplateFile // Handle of template file
) { HRESULT hr = E_FAIL; BOOL bRet; LONG lLineCount; LONG lLineIndex; WCHAR wszKey[64]; WCHAR wszValueName[64]; WCHAR wszMatch[64]; WCHAR wszLeftDelimitor[8]; WCHAR wszRightDelimitor[8]; DWORD cchRequired;
lLineCount = SetupGetLineCount(hTemplateFile, TEXT("Extract")); for (lLineIndex = 0 ; lLineIndex < lLineCount ; lLineIndex++) { INFCONTEXT Context;
bRet = SetupGetLineByIndex(hTemplateFile, TEXT("Extract"), lLineIndex, &Context); if (bRet) { // Get type of unneeded string
bRet = SetupGetStringField(&Context, 0, wszValueName, ARRAYSIZE(wszValueName), &cchRequired) && SetupGetStringField(&Context, 1, wszKey, ARRAYSIZE(wszKey), &cchRequired) && SetupGetStringField(&Context, 2, wszMatch, ARRAYSIZE(wszMatch), &cchRequired) && SetupGetStringField(&Context, 3, wszLeftDelimitor, ARRAYSIZE(wszLeftDelimitor), &cchRequired) && SetupGetStringField(&Context, 4, wszRightDelimitor, ARRAYSIZE(wszRightDelimitor), &cchRequired); hr = ExtractString(wszKey, wszValueName, wszMatch, wszLeftDelimitor, wszRightDelimitor); } }
bRet = WritePrivateProfileString(g_wszTargetLCIDSection, wszKey, NULL, g_wszOutputFile); if (bRet) hr = S_OK;
if (hr == E_FAIL) { hr = HRESULT_FROM_WIN32(GetLastError()); }
return hr; }
//-----------------------------------------------------------------------------
//
// Function: RemoveUnneededString
//
// Synopsis: Remove an unneeded sub string from the value of specified key
//
// Returns: HRESULT
//
// History: 02/07/2002 Rerkboos Created
//
// Notes: Caller need to free the allocated buffer
//
//-----------------------------------------------------------------------------
HRESULT ExtractString( LPCWSTR lpKey, // Key name
LPCWSTR lpValueName, LPCWSTR lpMatch, LPCWSTR lpLeftDelimitor, LPCWSTR lpRightDelimitor) { HRESULT hr = E_FAIL; BOOL bRet; LPWSTR lpMatchedStr; WCHAR wszOldValue[MAX_PATH*20]; WCHAR wszNewValue[MAX_PATH]; DWORD cchCopied;
cchCopied = GetPrivateProfileString(g_wszTargetLCIDSection, lpKey, TEXT(""), wszOldValue, ARRAYSIZE(wszOldValue), g_wszOutputFile); if (cchCopied > 0) { if (lpMatchedStr = StrStrI(wszOldValue, lpMatch)) { hr = ExtractSubString(wszNewValue, ARRAYSIZE(wszNewValue), lpMatchedStr, lpLeftDelimitor, lpRightDelimitor); if (SUCCEEDED(hr)) { WCHAR wszQuoted[MAX_PATH];
hr = StringCchPrintf(wszQuoted, ARRAYSIZE(wszQuoted), TEXT("\"%s\""), wszNewValue); if (SUCCEEDED(hr)) { bRet = WritePrivateProfileString(g_wszTargetLCIDSection, lpValueName, wszQuoted, g_wszOutputFile); if (bRet) { hr = S_OK; } else { hr = HRESULT_FROM_WIN32(GetLastError()); } } } } else { // Unneeded string not found
hr = S_FALSE; } } else { hr = HRESULT_FROM_WIN32(GetLastError()); }
return hr; }
HRESULT GetExpString( LPWSTR lpUnneededString, // Returned buffer
DWORD cchUnneededString, // Size of buffer in WCHAR
LPCWSTR lpString // String with %Key%
) { HRESULT hr = E_FAIL; LPCWSTR lpBegin; LPCWSTR lpEnd;
if (lpUnneededString == NULL || lpString == NULL) { return E_INVALIDARG; }
//
// Find the key name from Source string
//
lpBegin = StrChr(lpString, TEXT('%')); if (lpBegin) { // Begin of key name
lpBegin++;
// End of key name
lpEnd = StrChr(lpBegin, TEXT('%')); if (lpEnd) { DWORD cchLen; WCHAR wszKey[MAX_PATH];
cchLen = (DWORD) (lpEnd - lpBegin); if (cchLen >= cchUnneededString) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); } else { // Got the key name, needs one more char for a '\0'
if (lstrcpyn(wszKey, lpBegin, cchLen + 1)) { WCHAR wszOldSubStr[MAX_PATH]; WCHAR wszNewSubStr[MAX_PATH]; DWORD cchCopied;
// Get the value of key name from output file
cchCopied = GetPrivateProfileString(g_wszTargetLCIDSection, wszKey, TEXT(""), wszNewSubStr, ARRAYSIZE(wszNewSubStr), g_wszOutputFile); if (cchCopied > 0) { hr = StringCchPrintf(wszOldSubStr, ARRAYSIZE(wszOldSubStr), TEXT("%%%s%%"), wszKey); if (SUCCEEDED(hr)) { // Substitute %Key% with the new value
hr = StringSubstitute(lpUnneededString, cchUnneededString, lpString, wszOldSubStr, wszNewSubStr); } } } } } }
if (hr == E_FAIL) { hr = HRESULT_FROM_WIN32(GetLastError()); }
return hr; }
|