#include #include #include #include #include #include #include #include #define NO_FUNCTION 0xFF #define DM_VERBOSE 2 #ifndef UNICODE #define A2I atoi #define STRSTR strstr #else #define A2I _wtoi #define STRSTR wcsstr #endif enum FunctionType { FUNC_PatchInLogon, FUNC_PatchInSetup, FUNC_PatchTest, FUNC_NumofFunctions }; typedef struct _FUNC_DIR { char cFunc; int nID; } FUNC_DIR; FUNC_DIR FuncDir[FUNC_NumofFunctions] = { {'l',FUNC_PatchInLogon}, {'s',FUNC_PatchInSetup}, {'t',FUNC_PatchTest}, }; HINSTANCE ghInst=NULL; // // Function Declaration // //#define MYDBG #ifdef MYDBG #define DebugMsg(_parameter) Print _parameter #define DBGTITLE TEXT("FEMGRATE :") void Print(UINT mask,LPCTSTR pszFormat,...) { TCHAR szBuf[255]; va_list arglist; va_start(arglist,pszFormat); wvsprintf(szBuf,pszFormat,arglist); OutputDebugString(DBGTITLE); OutputDebugString(szBuf); va_end(arglist); } #else #define DebugMsg(_parameter) #endif BOOL ConcatenatePaths( IN OUT LPTSTR Target, IN LPCTSTR Path, IN 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); } // // Max size of a value's data // // // Max number of Functions NO_FUNCTION - 1 // UINT GetFunctions( int *pCmdList, int nNum) { int i,j; int nMaxNum; int nCommands; if ((__argc <=1) || nNum < 2) return 0; // // reserved one cell for terminiator // nMaxNum = (__argc-1 > nNum-1) ? nNum-1 : __argc-1; for (nCommands = 0,i=1; i <= nMaxNum; i++) { if (__argv[i][0] != '-') { continue; } for (j=0; j\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>"), 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>. retcode = %d\n"), lpDir, GetLastError())); } } else { DebugMsg((DM_VERBOSE, TEXT("Delnode: Failed to get current working directory. Error = %d\n"), GetLastError())); return FALSE; } return TRUE; } LPCTSTR pSetupGetField(PINFCONTEXT Context,DWORD FieldIndex); BOOL RenameFolder( BOOL bCommonGroup, LPCTSTR ObjSrcName, LPCTSTR ObjDstName) { TCHAR szSrcPath[MAX_PATH]; TCHAR szDstPath[MAX_PATH]; LONG lResult; BOOL bRet=FALSE; DebugMsg((DM_VERBOSE,TEXT("[RenameFolder]\nOld = %s\nNew = %s\n"),ObjSrcName,ObjDstName)); GetProgramsDirectory(bCommonGroup,szSrcPath); GetProgramsDirectory(bCommonGroup,szDstPath); ConcatenatePaths(szSrcPath,ObjSrcName,MAX_PATH); ConcatenatePaths(szDstPath,ObjDstName,MAX_PATH); lResult = GetFileAttributes(szSrcPath); if (lResult == 0xFFFFFFFF) { // // Directory does not exist. // DebugMsg((DM_VERBOSE, TEXT("[RenameFolder] Directory is not existed [%s] !\n"),szSrcPath)); goto err1; } if (!(lResult & FILE_ATTRIBUTE_DIRECTORY)) { // // this is not a directory. // DebugMsg((DM_VERBOSE, TEXT("[RenameFolder] This is not a directory [%s] !\n"),szSrcPath)); goto err1; } if (CopyProfileDirectory (szSrcPath, szDstPath, CPD_IGNOREHIVE)) { DebugMsg((DM_VERBOSE, TEXT("[RenameFolder] Successfully changed folder name:\n%s\n%s"),szSrcPath,szDstPath)); if (! DeleteGroup(ObjSrcName,bCommonGroup)) { DebugMsg((DM_VERBOSE, TEXT("[RenameFolder] Delete old folder (%s) failed !"), ObjSrcName)); } else { DebugMsg((DM_VERBOSE, TEXT("[RenameFolder] Delete old folder (%s) successfully !"), ObjSrcName)); } } else { DebugMsg((DM_VERBOSE, TEXT("[RenameFolder] Convert Folder: Failed to change group name with error %d\n.%s\n%s\n"), GetLastError(),szSrcPath,szDstPath)); goto err1; } bRet = TRUE; err1: return bRet; } BOOL RenameLink( BOOL bCommonGroup, LPCTSTR ObjSrcName, LPCTSTR ObjDstName, LPCTSTR ObjPath) { TCHAR szSrcPath[MAX_PATH]; TCHAR szDstPath[MAX_PATH]; LONG lResult; BOOL bRet=FALSE; DebugMsg((DM_VERBOSE,TEXT("[RenameFolder] \nOld = %s\nNew = %s\nPath = %s\n"),ObjSrcName,ObjDstName,ObjPath)); GetProgramsDirectory(bCommonGroup,szSrcPath); GetProgramsDirectory(bCommonGroup,szDstPath); if (ObjPath && *ObjPath) { ConcatenatePaths(szSrcPath,ObjPath,MAX_PATH); ConcatenatePaths(szDstPath,ObjPath,MAX_PATH); } ConcatenatePaths(szSrcPath,ObjSrcName,MAX_PATH); ConcatenatePaths(szDstPath,ObjDstName,MAX_PATH); lstrcat(szSrcPath,TEXT(".lnk")); lstrcat(szDstPath,TEXT(".lnk")); lResult = GetFileAttributes(szSrcPath); if (lResult == 0xFFFFFFFF) { // // Directory does not exist. // DebugMsg((DM_VERBOSE, TEXT("[RenameLink] File is not existed [%s] !\n"),szSrcPath)); goto err1; } if (lResult & FILE_ATTRIBUTE_DIRECTORY) { // // this is a directory, but we want a file. // DebugMsg((DM_VERBOSE, TEXT("[RenameLink] This is a directory [%s] !\n"),szSrcPath)); goto err1; } // // if destination file existed, it's not good ! // lResult = GetFileAttributes(szDstPath); if (lResult == 0xFFFFFFFF) { if (MoveFile (szSrcPath, szDstPath)) { DebugMsg((DM_VERBOSE, TEXT("[RenameLink] Successfully changed link name:\n%s\n%s\n"),szSrcPath,szDstPath)); } else { DebugMsg((DM_VERBOSE, TEXT("[RenameLink] Failed to change link name with error %d.\n%s\n%s\n"), GetLastError(),szSrcPath,szDstPath)); goto err1; } } else { DebugMsg((DM_VERBOSE, TEXT("[RenameLink] Destination file existed, maybe we don't want to overwrite ,%s\n"),szDstPath)); goto err1; } bRet = TRUE; err1: return bRet; } BOOL RenameProgramFolderOrLink(HINF hInf,BOOL bCommon) { BOOL bRet = FALSE; INFCONTEXT InfContext; UINT LineCount,LineNo; LPCTSTR szSectionName = TEXT("StartMenu.ObjectToRename"); LPCTSTR ObjectType; LPCTSTR ObjectSrcName; LPCTSTR ObjectDstName; LPCTSTR ObjectPath; LPCTSTR GroupAttribute; BOOL CommonGroup; BOOL IsMenuItem; if(hInf == INVALID_HANDLE_VALUE) { DebugMsg((DM_VERBOSE,TEXT("FEGRPCV: Open femgrate.inf failed !\n"))); return FALSE; } LineCount = (UINT)SetupGetLineCount(hInf,szSectionName); if((LONG)LineCount <= 0) { goto err1; } for(LineNo=0; LineNo szFolder :\n%s\n"),szExpNT4USF)); RegCloseKey (hKey); continue; } // // MoveIt == 1, we want move it to new folder // else, we just update registry // if (lstrcmp(MoveIt,TEXT("1")) == 0) { ExpandEnvironmentStrings (NT4Name, szExpNT4USF, MAX_PATH); ExpandEnvironmentStrings (NT5Name, szExpNT5USF, MAX_PATH); if (CopyProfileDirectory (szExpNT4USF, szExpNT5USF, CPD_IGNOREHIVE)) { DebugMsg((DM_VERBOSE, TEXT("Fix Folder: Successfully changed folder name:\n%s\n%s"),szExpNT4USF,szExpNT5USF)); if (Delnode (szExpNT4USF)) { DebugMsg((DM_VERBOSE, TEXT("[FixUserFolders] Successfully remove folder:\n%s\n"),szExpNT4USF)); } else { DebugMsg((DM_VERBOSE, TEXT("[FixUserFolders] Failed remove folder:\n%s\n"),szExpNT4USF)); } } else { DebugMsg((DM_VERBOSE, TEXT("[FixUserFolders] Failed to change folder name:\n%s\n%s"),szExpNT4USF,szExpNT5USF)); } } // // Set CSIDL_PERSONAL to point to this directory. // lResult = RegSetValueEx (hKey, szUSFRegKey, 0, REG_EXPAND_SZ, (LPBYTE) NT5Name, (lstrlen(NT5Name) + 1) * sizeof(TCHAR)); if (lResult != ERROR_SUCCESS) { DebugMsg((DM_VERBOSE, TEXT("[FixUserFolders] Set Registry faile, %s,%s\n"),szUSFRegKey,NT5Name)); } RegCloseKey (hKey); } } bRet = TRUE; err1: return bRet; } BOOL FixSpecificFolder(HINF hInf) { BOOL bRet = FALSE; INFCONTEXT InfContext; UINT LineCount,LineNo; LPCTSTR szSectionName = TEXT("Folder.SpecificObjectToRename"); LPCTSTR RegName; LPCTSTR NT4Name; LPCTSTR NT5Name; LPCTSTR MoveIt; TCHAR szUSFRegKey[MAX_PATH]; TCHAR szNTUSF[MAX_PATH]; TCHAR szExpNT4USF[MAX_PATH]; TCHAR szExpNT5USF[MAX_PATH]; DWORD dwSize, dwType; LONG lResult; UINT uiCount; HKEY hKey; if(hInf == INVALID_HANDLE_VALUE) { DebugMsg((DM_VERBOSE,TEXT("[FixSpecificFolder] Open femgrate.inf failed !\n"))); return FALSE; } LineCount = (UINT)SetupGetLineCount(hInf,szSectionName); if((LONG)LineCount <= 0) { DebugMsg((DM_VERBOSE,TEXT("[FixSpecificFolder] line count == 0 !\n"))); goto err1; } for(LineNo=0; LineNo nCommon) { lpTag = fd.cFileName + nFileName - nCommon; DebugMsg((DM_VERBOSE, TEXT("[FixCommon] lpTag=%s szCommon=%s\n"),lpTag, szCommon)); if (!lstrcmpi(lpTag, szCommon)) { lstrcpy (lpEnd, fd.cFileName); *lpTag = TEXT('\0'); lstrcpy (lpEnd2, fd.cFileName); if (CopyProfileDirectory (szExpProgramFolderPath, szProgramFolderPath, CPD_IGNOREHIVE)) { DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : Successfully changed group name:\n"))); DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : Orginial: %s\n"), szExpProgramFolderPath)); DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : New: %s\n"), szProgramFolderPath)); if (Delnode (szExpProgramFolderPath)) { DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : Successfully remove folder:\n%s\n"),szExpProgramFolderPath)); } else { DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : Failed remove folder:\n%s\n"),szExpProgramFolderPath)); } } else { DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : Failed to change group name with error %d.\n"), GetLastError())); DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : Orginial: %s\n"), szExpProgramFolderPath)); DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : New: %s\n"), szProgramFolderPath)); } } } } } while (FindNextFile(hFile, &fd)); FindClose (hFile); } bRet = TRUE; err1: return bRet; } BOOL FixAppearanceScheme(HINF hInf) { HKEY hAppearanceKey,hSchemeKey; LONG lResult; LPCTSTR szSectionName = TEXT("Apperance Scheme"); TCHAR szCurrentScheme[MAX_PATH]; LPCTSTR NT4SchemeName; LPCTSTR NT5SchemeName; LONG LineCount,LineNo; DWORD dwSize,dwType; INFCONTEXT InfContext; BOOL bRet = FALSE; if(hInf == INVALID_HANDLE_VALUE) { DebugMsg((DM_VERBOSE,TEXT("[FixAppearanceScheme] Open femgrate.inf failed !\n"))); goto Err0; } lResult = RegOpenKeyEx (HKEY_CURRENT_USER, REGSTR_PATH_APPEARANCE, 0, KEY_ALL_ACCESS, &hAppearanceKey); if (lResult != ERROR_SUCCESS) { DebugMsg((DM_VERBOSE,TEXT("[FixAppearanceScheme] Open REGSTR_PATH_APPEARANCE failed !\n"))); goto Err0; } // // Now query for the programs directory // dwSize = MAX_PATH * sizeof(TCHAR); szCurrentScheme[0] = TEXT('\0'); lResult = RegQueryValueEx (hAppearanceKey, TEXT("Current"), NULL, &dwType, (LPBYTE) szCurrentScheme, &dwSize); if (lResult != ERROR_SUCCESS) { // // this case is fine // szCurrentScheme[0] = TEXT('\0'); } lResult = RegOpenKeyEx (HKEY_CURRENT_USER, REGSTR_PATH_LOOKSCHEMES, 0, KEY_ALL_ACCESS, &hSchemeKey); if (lResult != ERROR_SUCCESS) { DebugMsg((DM_VERBOSE,TEXT("[FixAppearanceScheme] Open REGSTR_PATH_APPEARANCE failed !\n"))); goto Err1; } LineCount = (UINT)SetupGetLineCount(hInf,szSectionName); if((LONG)LineCount <= 0) { DebugMsg((DM_VERBOSE,TEXT("[FixAppearanceScheme] line count == 0 !\n"))); goto Err2; } for(LineNo=0; LineNo