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.
 
 
 
 
 
 

1599 lines
48 KiB

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