Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1430 lines
36 KiB

/****************************** Module Header ******************************\
* Module Name: utils.c
*
* Copyright (c) 1985 - 1999, Microsoft Corporation
*
* FEMGRATE utility functions
*
\***************************************************************************/
#include "femgrate.h"
#include <tchar.h>
#ifdef MYDBG
void Print(UINT mask,LPCTSTR pszFormat,...)
{
TCHAR szBuf[512];
va_list arglist;
va_start(arglist,pszFormat);
wvsprintf(szBuf,pszFormat,arglist);
#ifdef DEBUGLOG
lstrcat (szBuf,TEXT("\r\n"));
SetupLogError(DBGTITLE,LogSevInformation);
SetupLogError(szBuf,LogSevInformation);
#else
OutputDebugString(DBGTITLE);
OutputDebugString(szBuf);
#endif
va_end(arglist);
}
#endif
BOOL
ConcatenatePaths(
LPTSTR Target,
LPCTSTR Path,
UINT TargetBufferSize
)
{
UINT TargetLength,PathLength;
BOOL TrailingBackslash,LeadingBackslash;
UINT EndingLength;
TargetLength = lstrlen(Target);
PathLength = lstrlen(Path);
//
// See whether the target has a trailing backslash.
//
if(TargetLength && (Target[TargetLength-1] == TEXT('\\'))) {
TrailingBackslash = TRUE;
TargetLength--;
} else {
TrailingBackslash = FALSE;
}
//
// See whether the path has a leading backshash.
//
if(Path[0] == TEXT('\\')) {
LeadingBackslash = TRUE;
PathLength--;
} else {
LeadingBackslash = FALSE;
}
//
// Calculate the ending length, which is equal to the sum of
// the length of the two strings modulo leading/trailing
// backslashes, plus one path separator, plus a nul.
//
EndingLength = TargetLength + PathLength + 2;
if(!LeadingBackslash && (TargetLength < TargetBufferSize)) {
Target[TargetLength++] = TEXT('\\');
}
if(TargetBufferSize > TargetLength) {
lstrcpyn(Target+TargetLength,Path,TargetBufferSize-TargetLength);
}
//
// Make sure the buffer is nul terminated in all cases.
//
if (TargetBufferSize) {
Target[TargetBufferSize-1] = 0;
}
return(EndingLength <= TargetBufferSize);
}
LPTSTR CheckSlash (LPTSTR lpDir)
{
DWORD dwStrLen;
LPTSTR lpEnd;
lpEnd = lpDir + lstrlen(lpDir);
if (*(lpEnd - 1) != TEXT('\\')) {
*lpEnd = TEXT('\\');
lpEnd++;
*lpEnd = TEXT('\0');
}
return lpEnd;
}
void IntToString( DWORD i, LPTSTR sz)
{
#define CCH_MAX_DEC 12 // Number of chars needed to hold 2^32
TCHAR szTemp[CCH_MAX_DEC];
int iChr;
iChr = 0;
do {
szTemp[iChr++] = TEXT('0') + (TCHAR)(i % 10);
i = i / 10;
} while (i != 0);
do {
iChr--;
*sz++ = szTemp[iChr];
} while (iChr != 0);
*sz++ = TEXT('\0');
}
BOOL DoInstallationFromSection(HINF hInf,LPCTSTR lpszSectionName)
{
HSPFILEQ FileQueue;
PVOID QContext = NULL;
BOOL bRet=FALSE;
if(hInf == INVALID_HANDLE_VALUE) {
DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] Open femgrate.inf failed !\n")));
goto Err0;
}
if ((FileQueue = SetupOpenFileQueue()) == INVALID_HANDLE_VALUE) {
DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupOpenFileQueue failed !\n")));
goto Err0;
}
bRet = SetupInstallFilesFromInfSection(hInf,
NULL,
FileQueue,
lpszSectionName,
NULL,
SP_COPY_NEWER );
if (!bRet) {
DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupInstallFilesFromInfSection failed !\n")));
goto Err1;
}
if (!(QContext = SetupInitDefaultQueueCallback(NULL))) {
bRet = FALSE;
DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupInitDefaultQueueCallback failed !\n")));
goto Err1;
}
bRet = SetupCommitFileQueue(NULL,
FileQueue,
SetupDefaultQueueCallback,
QContext );
if (!bRet) {
DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupCommitFileQueue failed !\n")));
goto Err1;
}
bRet = SetupInstallFromInfSection( NULL,
hInf,
lpszSectionName,
SPINST_ALL & ~SPINST_FILES,
NULL,
NULL,
0,
NULL,
NULL,
NULL,
NULL );
if (!bRet) {
DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupInstallFromInfSection failed !\n")));
goto Err1;
}
bRet = TRUE;
Err1:
if ( QContext != NULL)
SetupTermDefaultQueueCallback(QContext);
SetupCloseFileQueue(FileQueue);
Err0:
return bRet;
}
BOOL IsInSetupUpgradeMode()
{
LPCTSTR szKeyName = TEXT("SYSTEM\\Setup");
DWORD dwType, dwSize;
HKEY hKeySetup;
DWORD dwSystemSetupInProgress,dwUpgradeInProcess;
LONG lResult;
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, szKeyName, 0,
KEY_READ, &hKeySetup) == ERROR_SUCCESS) {
dwSize = sizeof(DWORD);
lResult = RegQueryValueEx (hKeySetup, TEXT("SystemSetupInProgress"), NULL,
&dwType, (LPBYTE) &dwSystemSetupInProgress, &dwSize);
if (lResult == ERROR_SUCCESS) {
dwSize = sizeof(DWORD);
lResult = RegQueryValueEx (hKeySetup, TEXT("UpgradeInProgress"), NULL,
&dwType, (LPBYTE) &dwUpgradeInProcess, &dwSize);
if (lResult == ERROR_SUCCESS) {
DebugMsg((DM_VERBOSE,TEXT("[IsInSetupUpgradeMode] dwSystemSetupInProgress =%, dwUpgradeInProcess=%d !\n"),dwSystemSetupInProgress,dwUpgradeInProcess));
if ((dwSystemSetupInProgress != 0) && (dwUpgradeInProcess != 0)) {
return TRUE;
}
}
else {
DebugMsg((DM_VERBOSE,TEXT("[IsInSetupUpgradeMode] RegQueryValueEx UpgradeInProcess failed !\n")));
}
}
else {
DebugMsg((DM_VERBOSE,TEXT("[IsInSetupUpgradeMode] RegQueryValueEx SystemSetupInProgress failed !\n")));
}
RegCloseKey (hKeySetup);
}
else {
DebugMsg((DM_VERBOSE,TEXT("[IsInSetupUpgradeMode] RegOpenKeyEx failed !\n")));
}
return FALSE ;
}
UINT StrToUInt(
LPTSTR lpszNum)
{
LPTSTR lpszStop;
#ifdef UNICODE
return (wcstoul(lpszNum, &lpszStop, 16));
#else
return (strtoul(lpszNum, &lpszStop, 16));
#endif
}
UINT GetInstallLocale()
{
LONG dwErr;
HKEY hkey;
DWORD dwSize;
TCHAR buffer[512];
LANGID rcLang;
UINT p;
p = 0;
dwErr = RegOpenKeyEx( HKEY_USERS,
TEXT(".DEFAULT\\Control Panel\\International"),
0,
KEY_READ,
&hkey );
if( dwErr == ERROR_SUCCESS ) {
dwSize = sizeof(buffer);
dwErr = RegQueryValueEx(hkey,
TEXT("Locale"),
NULL, //reserved
NULL, //type
(LPBYTE) buffer,
&dwSize );
if(dwErr == ERROR_SUCCESS) {
p = StrToUInt(buffer);
}
}
return( p );
}
BOOL RegReplaceIfExisting(
HKEY hKey,
LPCTSTR pszOldValName,
LPCTSTR pszNewValName)
/*++
Rename old value name to new value name.
--*/
{
LONG lResult;
DWORD dwType;
DWORD dwSize;
TCHAR szData[MAX_PATH];
dwSize = sizeof(szData);
lResult = RegQueryValueEx (hKey,
pszOldValName,
0,
&dwType,
(LPBYTE) szData,
&dwSize);
if (lResult != ERROR_SUCCESS) {
DebugMsg((DM_VERBOSE,TEXT("RegReplaceIfExisting: RegQueryValue %s failed. \n"),pszOldValName));
return FALSE;
}
lResult = RegSetValueEx (hKey,
pszNewValName,
0,
REG_SZ,
(LPBYTE) szData,
(lstrlen(szData) + 1) * sizeof(TCHAR));
if (lResult != ERROR_SUCCESS) {
DebugMsg((DM_VERBOSE,TEXT("RegReplaceIfExisting: RegSetValueEx %s failed. \n"),pszNewValName));
return FALSE;
}
lResult = RegDeleteValue(hKey,
pszOldValName);
if (lResult != ERROR_SUCCESS) {
DebugMsg((DM_VERBOSE,TEXT("RegReplaceIfExisting: RegDelValue %s failed. \n"),pszOldValName));
return FALSE;
}
return TRUE;
}
BOOL ReplaceString(
LPCTSTR lpszOldStr,
LPCTSTR lpszReplaceStr,
LPCTSTR lpszReplacedWithStr,
LPTSTR lpszOutputStr)
{
LPTSTR pszAnchor = NULL;
lstrcpy(lpszOutputStr,lpszOldStr);
pszAnchor = _tcsstr(lpszOutputStr,lpszReplaceStr);
if (!pszAnchor) {
return FALSE;
}
if (lstrcmp(pszAnchor,lpszReplaceStr) != 0) {
return FALSE;
}
lstrcpy(pszAnchor,lpszReplacedWithStr);
return TRUE;
}
BOOL Delnode_Recurse (LPTSTR lpDir)
{
WIN32_FIND_DATA fd;
HANDLE hFile;
//
// Verbose output
//
//DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Entering, lpDir = <%s>\n"), lpDir));
//
// Setup the current working dir
//
if (!SetCurrentDirectory (lpDir)) {
//DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Failed to set current working directory. Error = %d\n"), GetLastError()));
return FALSE;
}
//
// Find the first file
//
hFile = FindFirstFile(c_szStarDotStar, &fd);
if (hFile == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
return TRUE;
} else {
//DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: FindFirstFile failed. Error = %d\n"),
// GetLastError()));
return FALSE;
}
}
do {
//
// Verbose output
//
//DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: FindFile found: <%s>\n"),
// fd.cFileName));
//
// Check for "." and ".."
//
if (!lstrcmpi(fd.cFileName, c_szDot)) {
continue;
}
if (!lstrcmpi(fd.cFileName, c_szDotDot)) {
continue;
}
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
//
// Found a directory.
//
if (!Delnode_Recurse(fd.cFileName)) {
FindClose(hFile);
return FALSE;
}
if (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
fd.dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
SetFileAttributes (fd.cFileName, fd.dwFileAttributes);
}
if (!RemoveDirectory (fd.cFileName)) {
// DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Failed to delete directory <%s>. Error = %d\n"),
// fd.cFileName, GetLastError()));
} else {
// DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Successfully delete directory <%s>.\n"),
// fd.cFileName));
}
} else {
//
// We found a file. Set the file attributes,
// and try to delete it.
//
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ||
(fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) {
SetFileAttributes (fd.cFileName, FILE_ATTRIBUTE_NORMAL);
}
if (!DeleteFile (fd.cFileName)) {
// DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Failed to delete <%s>. Error = %d\n"),
// fd.cFileName, GetLastError()));
}
else {
// DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Successful delete <%s>.\n"),
// fd.cFileName));
}
}
//
// Find the next entry
//
} while (FindNextFile(hFile, &fd));
//
// Close the search handle
//
FindClose(hFile);
//
// Reset the working directory
//
if (!SetCurrentDirectory (c_szDotDot)) {
DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Failed to reset current working directory. Error = %d\n"), GetLastError()));
return FALSE;
}
//
// Success.
//
DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Leaving <%s>\n"), lpDir));
return TRUE;
}
BOOL Delnode (LPTSTR lpDir)
{
TCHAR szCurWorkingDir[MAX_PATH];
if (GetCurrentDirectory(MAX_PATH, szCurWorkingDir)) {
Delnode_Recurse (lpDir);
SetCurrentDirectory (szCurWorkingDir);
if (!RemoveDirectory (lpDir)) {
DebugMsg((DM_VERBOSE, TEXT("Delnode: Failed to delete directory <%s>. Error = %d\n"),
lpDir, GetLastError()));
return FALSE;
}
else {
DebugMsg((DM_VERBOSE, TEXT("Delnode: RemoveDirectory OK <%s>.\n"),lpDir));
}
} else {
DebugMsg((DM_VERBOSE, TEXT("Delnode: Failed to get current working directory. Error = %d\n"), GetLastError()));
return FALSE;
}
return TRUE;
}
BOOL GetProgramsDirectory (BOOL bCommonGroup, LPTSTR lpDirectory)
{
LONG lResult;
HKEY hKey;
DWORD dwType, dwSize;
TCHAR szDirectory[MAX_PATH];
UINT uID;
BOOL bRetVal = FALSE;
//
// Open the User Shell Folders in the registry
//
lResult = RegOpenKeyEx ((bCommonGroup ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER),
USER_SHELL_FOLDER, 0, KEY_READ, &hKey);
if (lResult != ERROR_SUCCESS) {
goto Exit;
}
//
// Now query for the programs directory
//
dwSize = MAX_PATH * sizeof(TCHAR);
szDirectory[0] = TEXT('\0');
if (bCommonGroup) {
lResult = RegQueryValueEx (hKey, TEXT("Common Programs"),
NULL, &dwType, (LPBYTE) szDirectory, &dwSize);
} else {
lResult = RegQueryValueEx (hKey, TEXT("Programs"),
NULL, &dwType, (LPBYTE) szDirectory, &dwSize);
}
RegCloseKey(hKey);
if (lResult != ERROR_SUCCESS) {
goto Exit;
}
//
// Did we find anything?
//
if (szDirectory[0] == TEXT('\0')) {
goto Exit;
}
//
// Save the result
//
if (ExpandEnvironmentStrings(szDirectory, lpDirectory, MAX_PATH)) {
bRetVal = TRUE;
}
Exit:
return bRetVal;
}
BOOL GetGenericUserFolderDirectory (LPCTSTR lpszFolder, LPTSTR lpDirectory)
{
LONG lResult;
HKEY hKey;
DWORD dwType, dwSize;
TCHAR szDirectory[MAX_PATH];
UINT uID;
BOOL bRetVal = FALSE;
//
// Open the User Shell Folders in the registry
//
lResult = RegOpenKeyEx (HKEY_CURRENT_USER,
USER_SHELL_FOLDER, 0, KEY_READ, &hKey);
if (lResult != ERROR_SUCCESS) {
goto Exit;
}
//
// Now query for the programs directory
//
dwSize = MAX_PATH * sizeof(TCHAR);
szDirectory[0] = TEXT('\0');
lResult = RegQueryValueEx (hKey, lpszFolder,
NULL, &dwType, (LPBYTE) szDirectory, &dwSize);
RegCloseKey(hKey);
if (lResult != ERROR_SUCCESS) {
goto Exit;
}
//
// Did we find anything?
//
if (szDirectory[0] == TEXT('\0')) {
goto Exit;
}
//
// Save the result
//
if (ExpandEnvironmentStrings(szDirectory, lpDirectory, MAX_PATH)) {
bRetVal = TRUE;
}
Exit:
return bRetVal;
}
STRING_TO_DATA InfRegSpecTohKey[] = {
TEXT("HKEY_LOCAL_MACHINE"), (UINT)((UINT_PTR)HKEY_LOCAL_MACHINE),
TEXT("HKLM") , (UINT)((UINT_PTR)HKEY_LOCAL_MACHINE),
TEXT("HKEY_CLASSES_ROOT") , (UINT)((UINT_PTR)HKEY_CLASSES_ROOT),
TEXT("HKCR") , (UINT)((UINT_PTR)HKEY_CLASSES_ROOT),
TEXT("HKR") , (UINT)((UINT_PTR)NULL),
TEXT("HKEY_CURRENT_USER") , (UINT)((UINT_PTR)HKEY_CURRENT_USER),
TEXT("HKCU") , (UINT)((UINT_PTR)HKEY_CURRENT_USER),
TEXT("HKEY_USERS") , (UINT)((UINT_PTR)HKEY_USERS),
TEXT("HKU") , (UINT)((UINT_PTR)HKEY_USERS),
TEXT("") , (UINT)((UINT_PTR)NULL)
};
BOOL
LookUpStringInTable(
IN PSTRING_TO_DATA Table,
IN LPCTSTR String,
OUT PUINT Data
)
{
UINT i;
for(i=0; Table[i].String; i++) {
if(!lstrcmpi(Table[i].String,String)) {
*Data = Table[i].Data;
return(TRUE);
}
}
return(FALSE);
}
BOOL INIFile_ChangeSectionName(
LPCTSTR szIniFileName,
LPCTSTR szIniOldSectionName,
LPCTSTR szIniNewSectionName)
{
#define MAX_SIZE 0x7FFFF
LPTSTR pBuf = NULL;
BOOL bRetVal = FALSE;
DWORD dwSizeofBuf;
DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] Calling ,%s,%s,%s ! \n"),
szIniFileName,szIniOldSectionName,szIniNewSectionName));
//
// allocate max size of buffer
//
pBuf = (LPTSTR) malloc(MAX_SIZE);
if (! pBuf) {
DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] memory allocate error ! \n")));
goto Exit1;
}
dwSizeofBuf = GetPrivateProfileSection(
szIniOldSectionName,
pBuf,
MAX_SIZE,
szIniFileName);
if (! dwSizeofBuf) {
//
// this section is not in INI file
//
// do nothing
//
DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] No %s section in %s ! \n"),szIniOldSectionName));
bRetVal = TRUE;
goto Exit2;
}
if (dwSizeofBuf == MAX_SIZE - 2) {
//
// buffer too small
//
bRetVal = FALSE;
DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] memory not enough ! \n"),szIniOldSectionName,szIniFileName));
goto Exit2;
}
bRetVal = WritePrivateProfileSection(
szIniNewSectionName,
pBuf,
szIniFileName);
if (! bRetVal) {
//
// write failure
//
DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] WritePrivateProfileSection ! \n")));
goto Exit2;
}
WritePrivateProfileSection(
szIniOldSectionName,
NULL,
szIniFileName);
//
// at this step, even old section is not deleted, it's still OK
//
bRetVal = TRUE;
Exit2:
if (pBuf) {
free(pBuf);
}
Exit1:
return bRetVal;
}
BOOL INIFile_ChangeKeyName(
LPCTSTR szIniFileName,
LPCTSTR szIniOldSectionName,
LPCTSTR szIniOldKeyName,
LPCTSTR szIniNewKeyName)
{
#define MAX_SIZE 0x7FFFF
LPTSTR pBuf = NULL;
BOOL bRetVal = FALSE;
DWORD dwSizeofBuf;
// DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeKeyName] Calling ,%s,%s,%s %s! \n"),
// szIniFileName,szIniNewSectionName,szIniOldKeyName,szIniNewKeyName));
//
// allocate max size of buffer
//
pBuf = (LPTSTR) malloc(MAX_SIZE);
if (! pBuf) {
// DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] memory allocate error ! \n")));
goto Exit1;
}
dwSizeofBuf = GetPrivateProfileString(
szIniOldSectionName,
szIniOldKeyName,
TEXT(""),
pBuf,
MAX_SIZE,
szIniFileName);
if (! dwSizeofBuf) {
//
// this section is not in INI file
//
// do nothing
//
// DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] No %s section in %s ! \n"),));
bRetVal = TRUE;
goto Exit2;
}
if (dwSizeofBuf == MAX_SIZE - 1) {
//
// buffer too small
//
bRetVal = FALSE;
// DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] memory not enough ! \n"),szIniOldSectionName,szIniFileName));
goto Exit2;
}
bRetVal = WritePrivateProfileString(
szIniOldSectionName,
szIniNewKeyName,
pBuf,
szIniFileName);
if (! bRetVal) {
//
// write failure
//
// DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] WritePrivateProfileSection ! \n")));
goto Exit2;
}
WritePrivateProfileString(
szIniOldSectionName,
szIniOldKeyName,
NULL,
szIniFileName);
//
// at this step, even old section is not deleted, it's still OK
//
bRetVal = TRUE;
Exit2:
if (pBuf) {
free(pBuf);
}
Exit1:
return bRetVal;
}
UINT CreateNestedDirectory(LPCTSTR lpDirectory, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
TCHAR szDirectory[2*MAX_PATH];
LPTSTR lpEnd;
//
// Check for NULL pointer
//
if (!lpDirectory || !(*lpDirectory)) {
return 0;
}
//
// First, see if we can create the directory without having
// to build parent directories.
//
if (CreateDirectory (lpDirectory, lpSecurityAttributes)) {
return 1;
}
//
// If this directory exists already, this is OK too.
//
if (GetLastError() == ERROR_ALREADY_EXISTS) {
return ERROR_ALREADY_EXISTS;
}
//
// No luck, copy the string to a buffer we can munge
//
lstrcpy (szDirectory, lpDirectory);
//
// Find the first subdirectory name
//
lpEnd = szDirectory;
if (szDirectory[1] == TEXT(':')) {
lpEnd += 3;
} else if (szDirectory[1] == TEXT('\\')) {
lpEnd += 2;
while (*lpEnd && *lpEnd != TEXT('\\')) {
lpEnd++;
}
if (!(*lpEnd)) {
return 0;
}
lpEnd++;
while (*lpEnd && *lpEnd != TEXT('\\')) {
lpEnd++;
}
if (!(*lpEnd)) {
return 0;
}
lpEnd++;
} else if (szDirectory[0] == TEXT('\\')) {
lpEnd++;
}
while (*lpEnd) {
while (*lpEnd && *lpEnd != TEXT('\\')) {
lpEnd++;
}
if (*lpEnd == TEXT('\\')) {
*lpEnd = TEXT('\0');
if (!CreateDirectory (szDirectory, NULL)) {
if (GetLastError() != ERROR_ALREADY_EXISTS) {
DebugMsg((DM_VERBOSE, TEXT("CreateNestedDirectory: CreateDirectory failed with %d."), GetLastError()));
return 0;
}
}
*lpEnd = TEXT('\\');
lpEnd++;
}
}
if (CreateDirectory (szDirectory, lpSecurityAttributes)) {
return 1;
}
if (GetLastError() == ERROR_ALREADY_EXISTS) {
return ERROR_ALREADY_EXISTS;
}
DebugMsg((DM_VERBOSE, TEXT("CreateNestedDirectory: Failed to create the directory with error %d."), GetLastError()));
return 0;
}
BOOL (* MYSHGetSpecialFolderPathW) (HWND , LPTSTR , int , BOOL );
BOOL GetApplicationFolderPath(LPTSTR lpszFolder,UINT nLen)
{
HINSTANCE hDll;
BOOL bGotPath = FALSE;
hDll = LoadLibrary(TEXT("shell32.dll"));
if (hDll) {
(FARPROC) MYSHGetSpecialFolderPathW = GetProcAddress(hDll,"SHGetSpecialFolderPathW");
if (MYSHGetSpecialFolderPathW) {
if (MYSHGetSpecialFolderPathW(NULL, lpszFolder, CSIDL_APPDATA , FALSE)){
DebugMsg((DM_VERBOSE,TEXT("[GetApplicationFolder] SHGetSpecialFolderPath %s !\n"),lpszFolder));
bGotPath = TRUE;
} else {
DebugMsg((DM_VERBOSE,TEXT("[GetApplicationFolder] SHGetSpecialFolderPath failed !\n")));
}
} else {
DebugMsg((DM_VERBOSE,TEXT("[GetApplicationFolder] GetProc of SHGetSpecialFolderPath failed !\n")));
}
FreeLibrary(hDll);
} else {
DebugMsg((DM_VERBOSE,TEXT("[GetApplicationFolder] Load shell32.dll failed ! %d\n"),GetLastError()));
}
if (! bGotPath) {
ExpandEnvironmentStrings(TEXT("%userprofile%"),lpszFolder,nLen);
lstrcat(lpszFolder,TEXT("\\Application data"));
}
return TRUE;
}
BOOL GetNewPath(
LPTSTR lpszNewPath,
LPCTSTR lpszFileName,
LPCTSTR lpszClass)
{
BOOL bRet = FALSE;
LPTSTR lpszBaseName;
GetApplicationFolderPath(lpszNewPath,MAX_PATH);
ConcatenatePaths(lpszNewPath, lpszClass,MAX_PATH);
if (! CreateNestedDirectory(lpszNewPath,NULL)) {
DebugMsg((DM_VERBOSE,TEXT("[GetNewPath] CreateDirectory %s ! %X\n"),lpszNewPath,GetLastError()));
}
if ((lpszBaseName = _tcsrchr(lpszFileName,TEXT('\\'))) != NULL) {
ConcatenatePaths(lpszNewPath,lpszBaseName,MAX_PATH);
} else {
ConcatenatePaths(lpszNewPath,lpszFileName,MAX_PATH);
DebugMsg((DM_VERBOSE,TEXT("[GetNewPath] can't find \\ in %s !\n"),lpszFileName));
}
DebugMsg((DM_VERBOSE,TEXT("[GetNewPath] return %s !\n"),lpszNewPath));
bRet = TRUE;
return bRet;
}
BOOL MovePerUserIMEData(
HKEY hCurrentKey,
LPCTSTR szRegPath,
LPCTSTR szRegVal,
LPCTSTR szUserClass,
LPCTSTR szIMEName,
BOOL bCHT)
{
HKEY hKey;
DWORD dwErr,dwSize,dwType;
BOOL bRet;
TCHAR szPath[MAX_PATH],szNewPath[MAX_PATH];
bRet = FALSE;
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] szRegPath = %s !\n"),szRegPath));
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] szRegVal = %s !\n"),szRegVal));
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] szUserClass = %s !\n"),szUserClass));
dwErr = RegOpenKeyEx( hCurrentKey,
szRegPath,
0,
KEY_READ | KEY_WRITE,
&hKey );
if (dwErr != ERROR_SUCCESS) {
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Open key failed %X!\n"),GetLastError()));
bRet = TRUE;
goto Exit1;
}
dwSize = sizeof(szPath);
dwErr = RegQueryValueEx(hKey,
szRegVal,
NULL,
&dwType,
(LPBYTE) szPath,
&dwSize);
if (dwErr != ERROR_SUCCESS) {
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Value %s doesn't exist !\n"),szRegVal));
bRet = TRUE;
goto Exit2;
}
if (bCHT) {
if (GetFileAttributes(szPath) == 0xFFFFFFFF) {
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] File %s doesn't exist !\n"),szPath));
goto Exit2;
}
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] File %s existing !\n"),szPath));
if (! GetNewPath(szNewPath,szPath,szUserClass)) {
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Get new path name failed !\n")));
goto Exit2;
}
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Get new path name OK,%s !\n"),szNewPath));
if (! CopyFile(szPath,szNewPath,FALSE)) {
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Copy %s to %s failed ! %d\n"),szPath,szNewPath,GetLastError()));
goto Exit2;
}
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Copy %s to %s OK !\n"),szPath,szNewPath));
} else { // in CHS case
lstrcpy(szPath,szIMEName);
lstrcat(szPath,TEXT(".emb"));
if (! GetNewPath(szNewPath,szPath,szUserClass)) {
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Get new path name failed !\n")));
goto Exit2;
}
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Get new path name OK,%s !\n"),szNewPath));
}
#if 1
dwErr = RegSetValueEx(hKey,
szRegVal,
0,
REG_SZ,
(LPBYTE) szNewPath,
(lstrlen(szNewPath)+1) * sizeof(TCHAR));
if (dwErr != ERROR_SUCCESS) {
DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Set Value %s = %s failed !\n"),szRegVal,szNewPath));
goto Exit2;
}
#endif
bRet = TRUE;
Exit2:
RegCloseKey(hKey);
Exit1:
return bRet;
}
BOOL CreateSecurityDirectory(
LPCTSTR pszOldDir,
LPCTSTR pszNewDir)
{
DWORD dwLength,dwLengthNeeded;
PSECURITY_DESCRIPTOR pSD;
BOOL bRet = FALSE;
if (CreateNestedDirectory(pszNewDir,NULL)) {
//
// Copy the ACLs from the old location to the new
//
dwLength = 1024;
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc (LPTR, dwLength);
if (pSD) {
if (GetFileSecurity (pszOldDir,
DACL_SECURITY_INFORMATION,
pSD, dwLength, &dwLengthNeeded)) {
SetFileSecurity (pszNewDir,
DACL_SECURITY_INFORMATION, pSD);
bRet = TRUE;
} else {
DebugMsg((DM_VERBOSE, TEXT("CreateSecurityDirectory: Failed to allocate get security descriptor with %d. dwLengthNeeded = %d"),
GetLastError(), dwLengthNeeded));
}
LocalFree (pSD);
} else {
DebugMsg((DM_VERBOSE, TEXT("CreateSecurityDirectory: Failed to allocate memory for SD with %d."),
GetLastError()));
}
} else {
DebugMsg((DM_VERBOSE,TEXT("CreateSecurityDirectory %s ! %X\n"),pszNewDir,GetLastError()));
}
return bRet;
}
BOOL IsDirExisting(
LPTSTR Dir)
{
LONG lResult = GetFileAttributes(Dir);
DebugMsg((DM_VERBOSE, TEXT("[IsDirExisting] %s lResult:%X\n"),Dir,lResult));
if ((lResult == 0xFFFFFFFF) ||
(!(lResult & FILE_ATTRIBUTE_DIRECTORY))) {
return FALSE;
} else {
return TRUE;
}
}
BOOL IsFileExisting(
LPTSTR File)
{
LONG lResult = GetFileAttributes(File);
DebugMsg((DM_VERBOSE, TEXT("[IsFileExisting] %s lResult:%X\n"),File,lResult));
if ((lResult == 0xFFFFFFFF) ||
((lResult & FILE_ATTRIBUTE_DIRECTORY))) {
return FALSE;
} else {
return TRUE;
}
}
BOOL RenameDirectory(
LPTSTR OldDir,
LPTSTR NewDir)
{
BOOL bRet=TRUE;
if (!IsDirExisting(OldDir)) {
return FALSE;
}
if (IsDirExisting(NewDir)) {
//
// iF Target directory is already created, then copy files from source to dest dir
//
if (CopyProfileDirectory (OldDir, NewDir, CPD_IGNOREHIVE)) {
DebugMsg((DM_VERBOSE, TEXT("[RenameDirectory] Successfully CopyProfileDirectory \nFrom:%s\nTo :%s\n"),OldDir, NewDir));
if (Delnode (OldDir)) {
DebugMsg((DM_VERBOSE, TEXT("[RenameDirectory] Successfully removed folder:%s\n"),OldDir));
}
else {
DebugMsg((DM_VERBOSE, TEXT("[RenameDirectory] Failed remove folder:\n%s\n"),OldDir));
}
} else {
bRet = FALSE;
DebugMsg((DM_VERBOSE, TEXT("RenameDirectory: Failed to change folder name:\n%s\n%s"),OldDir, NewDir));
}
} else {
//
// iF Target has not been created, then just move source dir to dest dir
//
if (MoveFile(OldDir, NewDir)) {
DebugMsg((DM_VERBOSE, TEXT("[RenameDirectory] Move %s to %s OK !\n"),OldDir, NewDir));
} else {
bRet = FALSE;
DebugMsg((DM_VERBOSE, TEXT("[RenameDirectory] Failed to change folder name:\n%s\n%s\n"),OldDir, NewDir));
}
}
return TRUE;
}
BOOL RenameFile(
LPTSTR OldFile,
LPTSTR NewFile)
{
BOOL bRet=TRUE;
if (!IsFileExisting(OldFile)) {
return FALSE;
}
if (IsFileExisting(NewFile)) {
if (DeleteFile (OldFile)) {
DebugMsg((DM_VERBOSE, TEXT("[RenameFile] Successfully delete %s\n"),OldFile));
} else {
bRet = FALSE;
DebugMsg((DM_VERBOSE, TEXT("[RenameFile] Failed to delete file %s\n"),OldFile));
}
} else {
//
// iF Target has not been created, then just move source dir to dest dir
//
if (MoveFile(OldFile, NewFile)) {
DebugMsg((DM_VERBOSE, TEXT("[RenameFile] Move %s to %s OK !\n"),OldFile, NewFile));
} else {
bRet = FALSE;
DebugMsg((DM_VERBOSE, TEXT("[RenameFile] Failed to change File name:%s to %s\n"),OldFile, NewFile));
}
}
return bRet;
}
BOOL RenameSectionFiles(
HINF hInf,
LPCTSTR SectionName,
LPCTSTR SourceDirectory,
LPCTSTR TargetDirectory)
{
LONG LineCount,LineNo;
INFCONTEXT InfContext;
LPCTSTR pszSrcFile,pszDstFile;
TCHAR szMediaPath[MAX_PATH];
if(hInf == INVALID_HANDLE_VALUE) {
DebugMsg((DM_VERBOSE,TEXT("[RenameSectionFiles] Open femgrate.inf failed !\n")));
return FALSE;
}
LineCount = (UINT)SetupGetLineCount(hInf,SectionName);
if((LONG)LineCount <= 0) {
DebugMsg((DM_VERBOSE,TEXT("[RenameSectionFiles] line count == 0 !\n")));
return FALSE;
}
for(LineNo=0; LineNo<LineCount; LineNo++) {
if ( SetupGetLineByIndex(hInf,SectionName,LineNo,&InfContext)
&& (pszSrcFile = pSetupGetField(&InfContext,1))
&& (pszDstFile = pSetupGetField(&InfContext,2))
) {
TCHAR SourceFile[MAX_PATH];
TCHAR TargetFile[MAX_PATH];
lstrcpy(SourceFile,SourceDirectory);
lstrcpy(TargetFile,TargetDirectory);
ConcatenatePaths(SourceFile,pszSrcFile,MAX_PATH);
ConcatenatePaths(TargetFile,pszDstFile,MAX_PATH);
if (RenameFile(SourceFile, TargetFile)) {
DebugMsg((DM_VERBOSE, TEXT("[RenameSectionFiles] Rename %s to %s OK !\n"),SourceFile, TargetFile));
} else {
DebugMsg((DM_VERBOSE, TEXT("[RenameSectionFiles] Rename %s to %s Failed !\n"),SourceFile, TargetFile));
}
}
}
return TRUE;
}
BOOL RenameSectionRegSZ(
HINF hInf,
LPCTSTR SectionName,
HKEY hRootKey,
LPCTSTR RegPath)
{
LONG LineCount,LineNo;
INFCONTEXT InfContext;
LPCTSTR pszSrc,pszDst;
TCHAR szMediaPath[MAX_PATH];
HKEY hKey;
DWORD dwErr;
DWORD dwType;
DWORD dwSize;
if(hInf == INVALID_HANDLE_VALUE) {
DebugMsg((DM_VERBOSE,TEXT("[RenameSectionRegSZ] Open femgrate.inf failed !\n")));
return FALSE;
}
LineCount = (UINT)SetupGetLineCount(hInf,SectionName);
if((LONG)LineCount <= 0) {
DebugMsg((DM_VERBOSE,TEXT("[RenameSectionRegSZ] line count == 0 !\n")));
return FALSE;
}
dwErr = RegOpenKeyEx( hRootKey,
RegPath,
0,
KEY_READ | KEY_WRITE,
&hKey );
if (dwErr != ERROR_SUCCESS) {
DebugMsg((DM_VERBOSE,TEXT("[RenameSectionRegSZ] Failed RegOpenKeyEx !\n")));
return FALSE;
}
for(LineNo=0; LineNo<LineCount; LineNo++) {
if ( SetupGetLineByIndex(hInf,SectionName,LineNo,&InfContext)
&& (pszSrc = pSetupGetField(&InfContext,1))
&& (pszDst = pSetupGetField(&InfContext,2))
) {
BYTE Data[5000];
dwSize = sizeof(Data);
dwErr = RegQueryValueEx(hKey,
pszSrc,
NULL,
&dwType,
(LPBYTE) Data,
&dwSize);
if (dwErr != ERROR_SUCCESS) {
DebugMsg((DM_VERBOSE,TEXT("[RenameSectionRegSZ] Failed RegQueryValueEx %s [%X] !\n"), pszSrc,dwErr));
continue;
}
dwErr = RegSetValueEx(hKey,
pszDst,
0,
dwType,
(LPBYTE) Data,
dwSize);
if (dwErr != ERROR_SUCCESS) {
DebugMsg((DM_VERBOSE,TEXT("[RenameSectionRegSZ] Failed RegSetValueEx %s [%X] !\n"), pszDst,dwErr));
continue;
}
dwErr = RegDeleteValue(hKey,pszSrc);
if (dwErr != ERROR_SUCCESS) {
DebugMsg((DM_VERBOSE,TEXT("[RenameSectionRegSZ] Failed RegDeleteValue %s [%X] !\n"), pszSrc,dwErr));
continue;
}
}
}
RegCloseKey(hKey);
return TRUE;
}