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.
 
 
 
 
 
 

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);
}