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.
873 lines
22 KiB
873 lines
22 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 <string.h>
|
|
#include <Shlwapi.h>
|
|
#include "common.h"
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Function: TokenizeMultiSzString
|
|
//
|
|
// Synopsis: Extract array of strings in buffer. Each pointer in array of
|
|
// pointers will point to each string in buffer.
|
|
// Strings in buffer are separated by a single '\0'
|
|
// End of strings array is indicated by two consecutive "\0\0"
|
|
//
|
|
// Returns: Number of strings in the buffer
|
|
// 0 if no strings in the buffer
|
|
// -1 if error occurs
|
|
//
|
|
// History: 02/07/2002 Rerkboos Created
|
|
//
|
|
// Notes: none.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
LONG TokenizeMultiSzString(
|
|
LPCWSTR lpBuffer, // MultiSZ string buffer
|
|
DWORD cchBuffer, // Size of buffer (in WCHAR)
|
|
LPCWSTR lpToken[], // Array of pointer that will point to each SZ
|
|
DWORD dwArrSize // Maximum array size
|
|
)
|
|
{
|
|
DWORD dwTokenIndex;
|
|
DWORD i;
|
|
|
|
if (lpBuffer == NULL || lpToken == NULL)
|
|
{
|
|
// Invalid parameters
|
|
return -1;
|
|
}
|
|
|
|
if (*lpBuffer == TEXT('\0') && *(lpBuffer + 1) == TEXT('\0'))
|
|
{
|
|
// No SZ in buffer
|
|
return 0;
|
|
}
|
|
|
|
dwTokenIndex = 0;
|
|
lpToken[dwTokenIndex] = lpBuffer;
|
|
|
|
for (i = 0 ; i < cchBuffer ; i++)
|
|
{
|
|
if (*(lpBuffer + i) == TEXT('\0'))
|
|
{
|
|
// Reach the end of current string, check the next character in buffer
|
|
i++;
|
|
if (*(lpBuffer + i) == TEXT('\0'))
|
|
{
|
|
// Two consecutive '\0', it is the end of MultiSz string
|
|
// return the number of SZ string in buffer
|
|
return (dwTokenIndex + 1);
|
|
}
|
|
else
|
|
{
|
|
// Beginning of next string, assign the pointer to next string
|
|
dwTokenIndex++;
|
|
|
|
if (dwTokenIndex < dwArrSize)
|
|
{
|
|
// Enough pointer in array to use
|
|
lpToken[dwTokenIndex] = lpBuffer + i;
|
|
}
|
|
else
|
|
{
|
|
// Array of pointer is too small to extract strings from buffer
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Buffer is not null terminated correctly if we reach here
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Function: ExtractTokenString
|
|
//
|
|
// Synopsis: Tokenize the string using caller-supplied separators.
|
|
// Each pointer in pointer array will point to the token in source
|
|
// string, each token is null terminated.
|
|
//
|
|
// Returns: Number of token after tokenized
|
|
// -1 if error occurs
|
|
//
|
|
// History: 02/07/2002 Rerkboos Created
|
|
//
|
|
// Notes: Source string will be modified, caller need to make sure
|
|
// that original source string is backed up.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
LONG ExtractTokenString(
|
|
LPWSTR lpString, // Source string to be tokenized
|
|
LPWSTR lpToken[], // Array of pointers to token
|
|
LPCWSTR lpSep, // List of separator characters
|
|
DWORD nArrSize // Size of token array
|
|
)
|
|
{
|
|
DWORD nTokIndex = 0;
|
|
LPWSTR lpTmpToken;
|
|
|
|
if (NULL == lpString || NULL == lpToken || NULL == lpSep)
|
|
{
|
|
// Invalid parameters
|
|
return -1;
|
|
}
|
|
|
|
// Get first token
|
|
lpTmpToken = wcstok(lpString, lpSep);
|
|
|
|
// Loop until no more token left in the string
|
|
while (NULL != lpTmpToken)
|
|
{
|
|
if (nTokIndex < nArrSize)
|
|
{
|
|
// Enough pointer in array to use, so get next token
|
|
lpToken[nTokIndex] = lpTmpToken;
|
|
nTokIndex++;
|
|
|
|
lpTmpToken = wcstok(NULL, lpSep);
|
|
}
|
|
else
|
|
{
|
|
// Array size is too small to handle all the tokens
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// nTokIndex hold the number of token at this point
|
|
return nTokIndex;
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Function: ConcatFilePath
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 02/07/2002 Rerkboos Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT ConcatFilePath(
|
|
LPCWSTR lpPath,
|
|
LPCWSTR lpFile,
|
|
LPWSTR lpFilePath,
|
|
DWORD cchFilePath
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
DWORD dwPathBackSlashIndex;
|
|
LPCWSTR lpFormat;
|
|
|
|
const WCHAR wszWithSlash[] = TEXT("%s\\%s");
|
|
const WCHAR wszWithoutSlash[] = TEXT("%s%s");
|
|
|
|
if (lpFilePath == NULL)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
dwPathBackSlashIndex = lstrlen(lpPath) - 1;
|
|
|
|
if (*(lpPath + dwPathBackSlashIndex) == TEXT('\\'))
|
|
{
|
|
// Path is already ended with a '\'
|
|
lpFormat = wszWithoutSlash;
|
|
}
|
|
else
|
|
{
|
|
// Path is not ended with a '\', need a '\'
|
|
lpFormat = wszWithSlash;
|
|
}
|
|
|
|
hr = StringCchPrintf(lpFilePath,
|
|
cchFilePath,
|
|
lpFormat,
|
|
lpPath,
|
|
lpFile);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 02/07/2002 Rerkboos Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CopyCompressedFile(
|
|
LPCWSTR lpCabPath,
|
|
LPCWSTR lpCabFile, // Absolute path with CAB file name
|
|
LPCWSTR lpFileInCab, // File name in CAB file
|
|
LPWSTR lpUncompressedFile,
|
|
DWORD cchUncompressedFile
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
BOOL bRet;
|
|
DWORD dwRet;
|
|
WCHAR wszAppName[MAX_PATH];
|
|
WCHAR wszArg[MAX_PATH * 3];
|
|
WCHAR wszFullCabFilePath[MAX_PATH];
|
|
|
|
hr = ConcatFilePath(lpCabPath,
|
|
lpCabFile,
|
|
wszFullCabFilePath,
|
|
ARRAYSIZE(wszFullCabFilePath));
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
if (lpFileInCab == NULL || *lpFileInCab == TEXT('\0'))
|
|
{
|
|
DWORD dwEnd = lstrlen(lpCabFile);
|
|
|
|
if (lpCabFile[dwEnd - 1] == TEXT('_'))
|
|
{
|
|
// Stand alone compressed file
|
|
dwRet = ExpandEnvironmentStrings(TEXT("%SystemRoot%\\system32\\Extrac32.exe"),
|
|
wszAppName,
|
|
ARRAYSIZE(wszAppName));
|
|
if (dwRet > 0)
|
|
{
|
|
hr = ConcatFilePath(g_wszTempFolder,
|
|
lpCabFile,
|
|
lpUncompressedFile,
|
|
cchUncompressedFile);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = StringCchPrintf(wszArg,
|
|
ARRAYSIZE(wszArg),
|
|
TEXT("Extrac32.exe /Y \"%s\" \"%s\""),
|
|
wszFullCabFilePath,
|
|
lpUncompressedFile);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = LaunchProgram(wszAppName, wszArg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Stand alone uncompressed file
|
|
hr = ConcatFilePath(g_wszTempFolder,
|
|
lpCabFile,
|
|
lpUncompressedFile,
|
|
cchUncompressedFile);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
bRet = CopyFile(wszFullCabFilePath,
|
|
lpUncompressedFile,
|
|
FALSE);
|
|
if (bRet)
|
|
{
|
|
SetFileAttributes(lpUncompressedFile, FILE_ATTRIBUTE_NORMAL);
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// CAB file
|
|
dwRet = ExpandEnvironmentStrings(TEXT("%SystemRoot%\\system32\\Expand.exe"),
|
|
wszAppName,
|
|
ARRAYSIZE(wszAppName));
|
|
if (dwRet > 0)
|
|
{
|
|
hr = ConcatFilePath(g_wszTempFolder,
|
|
lpFileInCab,
|
|
lpUncompressedFile,
|
|
cchUncompressedFile);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = StringCchPrintf(wszArg,
|
|
ARRAYSIZE(wszArg),
|
|
TEXT("Expand.exe \"%s\" -F:%s \"%s\""),
|
|
wszFullCabFilePath,
|
|
lpFileInCab,
|
|
g_wszTempFolder);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = LaunchProgram(wszAppName, wszArg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Double check if the file is uncompressed/copied correctly
|
|
//
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
DWORD dwAttr;
|
|
|
|
dwAttr = GetFileAttributes(lpUncompressedFile);
|
|
if (dwAttr == INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 02/07/2002 Rerkboos Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT LaunchProgram(
|
|
LPWSTR lpAppName,
|
|
LPWSTR lpCmdLine
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
BOOL bRet = FALSE;
|
|
STARTUPINFO si;
|
|
PROCESS_INFORMATION pi;
|
|
|
|
// Construct absolute path to Winnt32.exe
|
|
ZeroMemory(&si, sizeof(STARTUPINFO));
|
|
si.cb = sizeof(STARTUPINFO);
|
|
si.wShowWindow = SW_SHOWMINIMIZED;
|
|
|
|
// CreateProcess call conforms to security guideline
|
|
bRet = CreateProcess(lpAppName,
|
|
lpCmdLine,
|
|
NULL,
|
|
NULL,
|
|
FALSE,
|
|
CREATE_NO_WINDOW,
|
|
NULL,
|
|
NULL,
|
|
&si,
|
|
&pi);
|
|
if (bRet)
|
|
{
|
|
// Wait until Expand.exe finished
|
|
hr = S_OK;
|
|
WaitForSingleObject(pi.hProcess, INFINITE);
|
|
CloseHandle(pi.hProcess);
|
|
CloseHandle(pi.hThread);
|
|
}
|
|
else
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 02/07/2002 Rerkboos Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT GetPathFromSourcePathName(
|
|
LPCWSTR lpSrcPathName,
|
|
LPWSTR lpPathBuffer,
|
|
DWORD cchPathBuffer
|
|
)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
DWORD i;
|
|
|
|
if (lpSrcPathName == NULL || lpPathBuffer == NULL)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
for (i = 0 ; i < g_dwSrcCount ; i++)
|
|
{
|
|
if (lstrcmpi(lpSrcPathName, g_SrcPath[i].wszSrcName) == LSTR_EQUAL)
|
|
{
|
|
hr = StringCchCopy(lpPathBuffer,
|
|
cchPathBuffer,
|
|
g_SrcPath[i].wszPath);
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 02/07/2002 Rerkboos Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT GetCabFileName(
|
|
LPCWSTR lpFileToken, // File name token from template file
|
|
LPWSTR lpCab,
|
|
DWORD cchCab,
|
|
LPWSTR lpFileInCab,
|
|
DWORD cchFileInCab
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
LPWSTR lpBuffer;
|
|
LPWSTR lpStart;
|
|
DWORD cbBuffer;
|
|
|
|
if (lpCab == NULL || lpFileInCab == NULL)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
cbBuffer = (lstrlen(lpFileToken) + 1) * sizeof(WCHAR);
|
|
lpBuffer = (LPWSTR) MEMALLOC(cbBuffer);
|
|
if (lpBuffer)
|
|
{
|
|
hr = StringCbCopy(lpBuffer, cbBuffer, lpFileToken);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
lpStart = wcstok(lpBuffer, TEXT("\\"));
|
|
if (lpStart)
|
|
{
|
|
hr = StringCchCopy(lpCab, cchCab, lpStart);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
lpStart = wcstok(NULL, TEXT("\\"));
|
|
if (lpStart)
|
|
{
|
|
hr = StringCchCopy(lpFileInCab, cchFileInCab, lpStart);
|
|
}
|
|
else
|
|
{
|
|
hr = StringCchCopy(lpFileInCab, cchFileInCab, TEXT(""));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
MEMFREE(lpBuffer);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 02/07/2002 Rerkboos Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT GetCabTempDirectory(
|
|
LPCWSTR lpCab
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Function:
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 02/07/2002 Rerkboos Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CreateTempDirectory(
|
|
LPWSTR lpName, // Buffer to store temp path
|
|
DWORD cchName // Size of buffer (in WCHAR)
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
WCHAR wszTempPath[MAX_PATH];
|
|
DWORD cchCopied;
|
|
|
|
if (lpName == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
cchCopied = GetTempPath(cchName, lpName);
|
|
if (cchCopied > 0)
|
|
{
|
|
hr = StringCchCat(lpName, cchName, TEXT_TOKGEN_TEMP_PATH_NAME);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (GetFileAttributes(lpName) == INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
if (!CreateDirectory(lpName, NULL))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Function: LTrim
|
|
//
|
|
// Synopsis: Trim the leading spaces in the string.
|
|
//
|
|
// Returns: none
|
|
//
|
|
// History: 02/07/2002 Rerkboos Created
|
|
//
|
|
// Notes: none
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void LTrim(
|
|
LPWSTR lpBuffer
|
|
)
|
|
{
|
|
int nIndex = 0;
|
|
int nDest = 0;
|
|
|
|
if (NULL == lpBuffer || TEXT('\0') == *lpBuffer)
|
|
return;
|
|
|
|
while (TEXT(' ') == lpBuffer[nIndex] && TEXT('\0') != lpBuffer[nIndex])
|
|
nIndex++;
|
|
|
|
while (TEXT('\0') != lpBuffer[nIndex])
|
|
{
|
|
lpBuffer[nDest] = lpBuffer[nIndex];
|
|
nDest++;
|
|
nIndex++;
|
|
}
|
|
lpBuffer[nDest] = TEXT('\0');
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Function: RTrim
|
|
//
|
|
// Synopsis: Trim the trailing spaces in the string.
|
|
//
|
|
// Returns: none
|
|
//
|
|
// History: 02/07/2002 Rerkboos Created
|
|
//
|
|
// Notes: none
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void RTrim(
|
|
LPWSTR lpBuffer
|
|
)
|
|
{
|
|
int nIndex = 0;
|
|
int nDest = 0;
|
|
|
|
if (NULL == lpBuffer || TEXT('\0') == *lpBuffer)
|
|
return;
|
|
|
|
nIndex = lstrlen(lpBuffer) - 1;
|
|
|
|
while (nIndex >= 0)
|
|
{
|
|
if (lpBuffer[nIndex] != TEXT(' '))
|
|
break;
|
|
|
|
nIndex--;
|
|
}
|
|
|
|
lpBuffer[nIndex + 1] = TEXT('\0');
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Function: Str2KeyPath
|
|
//
|
|
// Synopsis: Convert string value of root key to HKEY value
|
|
//
|
|
// Returns: HKEY value
|
|
//
|
|
// History: 02/07/2002 Rerkboos Created
|
|
//
|
|
// Notes: none
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
BOOL Str2KeyPath(
|
|
LPCWSTR lpHKeyStr,
|
|
PHKEY pHKey,
|
|
LPCWSTR* pSubKeyPath
|
|
)
|
|
{
|
|
int i;
|
|
LPCWSTR lpStart;
|
|
|
|
STRING_TO_DATA InfRegSpecTohKey[] = {
|
|
TEXT("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE,
|
|
TEXT("HKLM") , HKEY_LOCAL_MACHINE,
|
|
TEXT("HKEY_CLASSES_ROOT") , HKEY_CLASSES_ROOT,
|
|
TEXT("HKCR") , HKEY_CLASSES_ROOT,
|
|
TEXT("HKR") , NULL,
|
|
TEXT("HKEY_CURRENT_USER") , HKEY_CURRENT_USER,
|
|
TEXT("HKCU") , HKEY_CURRENT_USER,
|
|
TEXT("HKEY_USERS") , HKEY_USERS,
|
|
TEXT("HKU") , HKEY_USERS,
|
|
TEXT("") , NULL
|
|
};
|
|
|
|
PSTRING_TO_DATA Table = InfRegSpecTohKey;
|
|
|
|
if (NULL == lpHKeyStr)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
for(i = 0 ; Table[i].String[0] != TEXT('\0') ; i++)
|
|
{
|
|
lpStart = wcsstr(lpHKeyStr, Table[i].String);
|
|
if (lpStart == lpHKeyStr)
|
|
{
|
|
*pHKey = Table[i].Data;
|
|
|
|
if (NULL != pSubKeyPath)
|
|
{
|
|
lpStart += lstrlen(Table[i].String);
|
|
if (*lpStart == TEXT('\0'))
|
|
{
|
|
*pSubKeyPath = lpStart;
|
|
}
|
|
else
|
|
{
|
|
*pSubKeyPath = lpStart + 1;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
HRESULT StringSubstitute(
|
|
LPWSTR lpString, // New string buffer
|
|
DWORD cchString, // Size of buffer in WCHAR
|
|
LPCWSTR lpOldString, // Old string
|
|
LPCWSTR lpOldSubStr, // Old sub string to be substituted
|
|
LPCWSTR lpNewSubStr // New sub string
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
LPWSTR lpSubStrBegin;
|
|
|
|
lpSubStrBegin = StrStrI(lpOldString, lpOldSubStr);
|
|
if (lpSubStrBegin)
|
|
{
|
|
// Sub string found in source string
|
|
DWORD cchNewString;
|
|
|
|
cchNewString = lstrlen(lpOldString)
|
|
- lstrlen(lpOldSubStr)
|
|
+ lstrlen(lpNewSubStr);
|
|
if (cchNewString < cchString)
|
|
{
|
|
DWORD dwStartIndex;
|
|
DWORD dwEndIndex;
|
|
DWORD i, j;
|
|
|
|
dwStartIndex = (DWORD) (lpSubStrBegin - lpOldString);
|
|
dwEndIndex = dwStartIndex + lstrlen(lpOldSubStr);
|
|
|
|
for (i = 0 ; i < dwStartIndex ; i++)
|
|
{
|
|
lpString[i] = lpOldString[i];
|
|
}
|
|
|
|
for (j = 0 ; j < (DWORD) lstrlen(lpNewSubStr) ; i++, j++)
|
|
{
|
|
lpString[i] = lpNewSubStr[j];
|
|
}
|
|
|
|
for (j = dwEndIndex ; lpOldString[j] != TEXT('\0') ; i++, j++)
|
|
{
|
|
lpString[i] = lpOldString[j];
|
|
}
|
|
|
|
lpString[i] = TEXT('\0');
|
|
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// sub string not found
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
if (hr == E_FAIL)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT ExtractSubString(
|
|
LPWSTR lpString, // New string buffer
|
|
DWORD cchString, // Size of buffer in WCHAR
|
|
LPCWSTR lpOldString, // Old string
|
|
LPCWSTR lpLeft, // Left delimitor
|
|
LPCWSTR lpRight // Right delimitor
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
LPWSTR lpSubStrBegin, lpSubStrEnd;
|
|
|
|
lpSubStrBegin = StrStrI(lpOldString, lpLeft);
|
|
if (lpSubStrBegin)
|
|
{
|
|
lpSubStrBegin += lstrlen(lpLeft);
|
|
lpSubStrEnd = StrStrI(lpSubStrBegin, lpRight);
|
|
if (lpSubStrEnd && (DWORD)(lpSubStrEnd-lpSubStrBegin) < cchString)
|
|
{
|
|
while (lpSubStrBegin < lpSubStrEnd)
|
|
{
|
|
*lpString = *lpSubStrBegin;
|
|
lpString++;
|
|
lpSubStrBegin++;
|
|
}
|
|
*lpString = (WCHAR)'\0';
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Function: CompareENGString
|
|
//
|
|
// Synopsis: Wrapper of CompareString API, to compare English strings.
|
|
//
|
|
// Returns: Same as CompareString() API
|
|
//
|
|
// History: 05/06/2002 Rerkboos Created
|
|
//
|
|
// Notes: none
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
int CompareEngString(
|
|
LPCTSTR lpString1,
|
|
LPCTSTR lpString2
|
|
)
|
|
{
|
|
return CompareString(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT),
|
|
NORM_IGNORECASE,
|
|
lpString1,
|
|
-1,
|
|
lpString2,
|
|
-1);
|
|
}
|