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.

1722 lines
50 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <userenv.h>
  5. #include <userenvp.h>
  6. #include <setupapi.h>
  7. #include <regstr.h>
  8. #include <shlwapi.h>
  9. #define NO_FUNCTION 0xFF
  10. #define DM_VERBOSE 2
  11. #ifndef UNICODE
  12. #define A2I atoi
  13. #define STRSTR strstr
  14. #else
  15. #define A2I _wtoi
  16. #define STRSTR wcsstr
  17. #endif
  18. enum FunctionType {
  19. FUNC_PatchInLogon,
  20. FUNC_PatchInSetup,
  21. FUNC_PatchTest,
  22. FUNC_NumofFunctions
  23. };
  24. typedef struct _FUNC_DIR {
  25. char cFunc;
  26. int nID;
  27. } FUNC_DIR;
  28. FUNC_DIR FuncDir[FUNC_NumofFunctions] = {
  29. {'l',FUNC_PatchInLogon},
  30. {'s',FUNC_PatchInSetup},
  31. {'t',FUNC_PatchTest},
  32. };
  33. HINSTANCE ghInst=NULL;
  34. //
  35. // Function Declaration
  36. //
  37. //#define MYDBG
  38. #ifdef MYDBG
  39. #define DebugMsg(_parameter) Print _parameter
  40. #define DBGTITLE TEXT("FEMGRATE :")
  41. void Print(UINT mask,LPCTSTR pszFormat,...)
  42. {
  43. TCHAR szBuf[255];
  44. va_list arglist;
  45. va_start(arglist,pszFormat);
  46. wvsprintf(szBuf,pszFormat,arglist);
  47. OutputDebugString(DBGTITLE);
  48. OutputDebugString(szBuf);
  49. va_end(arglist);
  50. }
  51. #else
  52. #define DebugMsg(_parameter)
  53. #endif
  54. BOOL
  55. ConcatenatePaths(
  56. IN OUT LPTSTR Target,
  57. IN LPCTSTR Path,
  58. IN UINT TargetBufferSize
  59. )
  60. {
  61. UINT TargetLength,PathLength;
  62. BOOL TrailingBackslash,LeadingBackslash;
  63. UINT EndingLength;
  64. TargetLength = lstrlen(Target);
  65. PathLength = lstrlen(Path);
  66. //
  67. // See whether the target has a trailing backslash.
  68. //
  69. if(TargetLength && (Target[TargetLength-1] == TEXT('\\'))) {
  70. TrailingBackslash = TRUE;
  71. TargetLength--;
  72. } else {
  73. TrailingBackslash = FALSE;
  74. }
  75. //
  76. // See whether the path has a leading backshash.
  77. //
  78. if(Path[0] == TEXT('\\')) {
  79. LeadingBackslash = TRUE;
  80. PathLength--;
  81. } else {
  82. LeadingBackslash = FALSE;
  83. }
  84. //
  85. // Calculate the ending length, which is equal to the sum of
  86. // the length of the two strings modulo leading/trailing
  87. // backslashes, plus one path separator, plus a nul.
  88. //
  89. EndingLength = TargetLength + PathLength + 2;
  90. if(!LeadingBackslash && (TargetLength < TargetBufferSize)) {
  91. Target[TargetLength++] = TEXT('\\');
  92. }
  93. if(TargetBufferSize > TargetLength) {
  94. lstrcpyn(Target+TargetLength,Path,TargetBufferSize-TargetLength);
  95. }
  96. //
  97. // Make sure the buffer is nul terminated in all cases.
  98. //
  99. if (TargetBufferSize) {
  100. Target[TargetBufferSize-1] = 0;
  101. }
  102. return(EndingLength <= TargetBufferSize);
  103. }
  104. //
  105. // Max size of a value's data
  106. //
  107. //
  108. // Max number of Functions NO_FUNCTION - 1
  109. //
  110. UINT GetFunctions(
  111. int *pCmdList,
  112. int nNum)
  113. {
  114. int i,j;
  115. int nMaxNum;
  116. int nCommands;
  117. if ((__argc <=1) || nNum < 2)
  118. return 0;
  119. //
  120. // reserved one cell for terminiator
  121. //
  122. nMaxNum = (__argc-1 > nNum-1) ? nNum-1 : __argc-1;
  123. for (nCommands = 0,i=1; i <= nMaxNum; i++) {
  124. if (__argv[i][0] != '-') {
  125. continue;
  126. }
  127. for (j=0; j<FUNC_NumofFunctions ; j++) {
  128. if (FuncDir[j].cFunc == __argv[i][1]) {
  129. pCmdList[nCommands++] = FuncDir[j].nID;
  130. }
  131. }
  132. }
  133. pCmdList[nCommands] = NO_FUNCTION;
  134. return nCommands;
  135. }
  136. LPTSTR CheckSlash (LPTSTR lpDir)
  137. {
  138. DWORD dwStrLen;
  139. LPTSTR lpEnd;
  140. lpEnd = lpDir + lstrlen(lpDir);
  141. if (*(lpEnd - 1) != TEXT('\\')) {
  142. *lpEnd = TEXT('\\');
  143. lpEnd++;
  144. *lpEnd = TEXT('\0');
  145. }
  146. return lpEnd;
  147. }
  148. #define CCH_MAX_DEC 12 // Number of chars needed to hold 2^32
  149. void IntToString( DWORD i, LPTSTR sz) {
  150. TCHAR szTemp[CCH_MAX_DEC];
  151. int iChr;
  152. iChr = 0;
  153. do {
  154. szTemp[iChr++] = TEXT('0') + (TCHAR)(i % 10);
  155. i = i / 10;
  156. } while (i != 0);
  157. do {
  158. iChr--;
  159. *sz++ = szTemp[iChr];
  160. } while (iChr != 0);
  161. *sz++ = TEXT('\0');
  162. }
  163. #define USER_SHELL_FOLDER TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders")
  164. BOOL GetProgramsDirectory (BOOL bCommonGroup, LPTSTR lpDirectory)
  165. {
  166. LONG lResult;
  167. HKEY hKey;
  168. DWORD dwType, dwSize;
  169. TCHAR szDirectory[MAX_PATH];
  170. UINT uID;
  171. BOOL bRetVal = FALSE;
  172. //
  173. // Open the User Shell Folders in the registry
  174. //
  175. lResult = RegOpenKeyEx ((bCommonGroup ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER),
  176. USER_SHELL_FOLDER, 0, KEY_READ, &hKey);
  177. if (lResult != ERROR_SUCCESS) {
  178. goto Exit;
  179. }
  180. //
  181. // Now query for the programs directory
  182. //
  183. dwSize = MAX_PATH * sizeof(TCHAR);
  184. szDirectory[0] = TEXT('\0');
  185. if (bCommonGroup) {
  186. lResult = RegQueryValueEx (hKey, TEXT("Common Programs"),
  187. NULL, &dwType, (LPBYTE) szDirectory, &dwSize);
  188. } else {
  189. lResult = RegQueryValueEx (hKey, TEXT("Programs"),
  190. NULL, &dwType, (LPBYTE) szDirectory, &dwSize);
  191. }
  192. RegCloseKey(hKey);
  193. if (lResult != ERROR_SUCCESS) {
  194. goto Exit;
  195. }
  196. //
  197. // Did we find anything?
  198. //
  199. if (szDirectory[0] == TEXT('\0')) {
  200. goto Exit;
  201. }
  202. //
  203. // Save the result
  204. //
  205. if (ExpandEnvironmentStrings(szDirectory, lpDirectory, MAX_PATH)) {
  206. bRetVal = TRUE;
  207. }
  208. Exit:
  209. return bRetVal;
  210. }
  211. const TCHAR c_szDot[] = TEXT(".");
  212. const TCHAR c_szDotDot[] = TEXT("..");
  213. const TCHAR c_szStarDotStar[] =TEXT("*.*");
  214. BOOL Delnode_Recurse (LPTSTR lpDir)
  215. {
  216. WIN32_FIND_DATA fd;
  217. HANDLE hFile;
  218. //
  219. // Verbose output
  220. //
  221. //DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Entering, lpDir = <%s>\n"), lpDir));
  222. //
  223. // Setup the current working dir
  224. //
  225. if (!SetCurrentDirectory (lpDir)) {
  226. //DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Failed to set current working directory. Error = %d\n"), GetLastError()));
  227. return FALSE;
  228. }
  229. //
  230. // Find the first file
  231. //
  232. hFile = FindFirstFile(c_szStarDotStar, &fd);
  233. if (hFile == INVALID_HANDLE_VALUE) {
  234. if (GetLastError() == ERROR_FILE_NOT_FOUND) {
  235. return TRUE;
  236. } else {
  237. //DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: FindFirstFile failed. Error = %d\n"),
  238. // GetLastError()));
  239. return FALSE;
  240. }
  241. }
  242. do {
  243. //
  244. // Verbose output
  245. //
  246. //DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: FindFile found: <%s>\n"),
  247. // fd.cFileName));
  248. //
  249. // Check for "." and ".."
  250. //
  251. if (!lstrcmpi(fd.cFileName, c_szDot)) {
  252. continue;
  253. }
  254. if (!lstrcmpi(fd.cFileName, c_szDotDot)) {
  255. continue;
  256. }
  257. if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  258. //
  259. // Found a directory.
  260. //
  261. if (!Delnode_Recurse(fd.cFileName)) {
  262. FindClose(hFile);
  263. return FALSE;
  264. }
  265. if (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
  266. fd.dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
  267. SetFileAttributes (fd.cFileName, fd.dwFileAttributes);
  268. }
  269. if (!RemoveDirectory (fd.cFileName)) {
  270. // DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Failed to delete directory <%s>. Error = %d\n"),
  271. // fd.cFileName, GetLastError()));
  272. } else {
  273. // DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Successfully delete directory <%s>.\n"),
  274. // fd.cFileName));
  275. }
  276. } else {
  277. //
  278. // We found a file. Set the file attributes,
  279. // and try to delete it.
  280. //
  281. if ((fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ||
  282. (fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) {
  283. SetFileAttributes (fd.cFileName, FILE_ATTRIBUTE_NORMAL);
  284. }
  285. if (!DeleteFile (fd.cFileName)) {
  286. // DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Failed to delete <%s>. Error = %d\n"),
  287. // fd.cFileName, GetLastError()));
  288. }
  289. else {
  290. // DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Successful delete <%s>.\n"),
  291. // fd.cFileName));
  292. }
  293. }
  294. //
  295. // Find the next entry
  296. //
  297. } while (FindNextFile(hFile, &fd));
  298. //
  299. // Close the search handle
  300. //
  301. FindClose(hFile);
  302. //
  303. // Reset the working directory
  304. //
  305. if (!SetCurrentDirectory (c_szDotDot)) {
  306. DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Failed to reset current working directory. Error = %d\n"), GetLastError()));
  307. return FALSE;
  308. }
  309. //
  310. // Success.
  311. //
  312. DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Leaving <%s>"), lpDir));
  313. return TRUE;
  314. }
  315. BOOL Delnode (LPTSTR lpDir)
  316. {
  317. TCHAR szCurWorkingDir[MAX_PATH];
  318. if (GetCurrentDirectory(MAX_PATH, szCurWorkingDir)) {
  319. Delnode_Recurse (lpDir);
  320. SetCurrentDirectory (szCurWorkingDir);
  321. if (!RemoveDirectory (lpDir)) {
  322. DebugMsg((DM_VERBOSE, TEXT("Delnode: Failed to delete directory <%s>. Error = %d\n"),
  323. lpDir, GetLastError()));
  324. return FALSE;
  325. }
  326. else {
  327. DebugMsg((DM_VERBOSE, TEXT("Delnode: RemoveDirectory OK <%s>. retcode = %d\n"),
  328. lpDir, GetLastError()));
  329. }
  330. } else {
  331. DebugMsg((DM_VERBOSE, TEXT("Delnode: Failed to get current working directory. Error = %d\n"), GetLastError()));
  332. return FALSE;
  333. }
  334. return TRUE;
  335. }
  336. LPCTSTR pSetupGetField(PINFCONTEXT Context,DWORD FieldIndex);
  337. BOOL RenameFolder(
  338. BOOL bCommonGroup,
  339. LPCTSTR ObjSrcName,
  340. LPCTSTR ObjDstName)
  341. {
  342. TCHAR szSrcPath[MAX_PATH];
  343. TCHAR szDstPath[MAX_PATH];
  344. LONG lResult;
  345. BOOL bRet=FALSE;
  346. DebugMsg((DM_VERBOSE,TEXT("[RenameFolder]\nOld = %s\nNew = %s\n"),ObjSrcName,ObjDstName));
  347. GetProgramsDirectory(bCommonGroup,szSrcPath);
  348. GetProgramsDirectory(bCommonGroup,szDstPath);
  349. ConcatenatePaths(szSrcPath,ObjSrcName,MAX_PATH);
  350. ConcatenatePaths(szDstPath,ObjDstName,MAX_PATH);
  351. lResult = GetFileAttributes(szSrcPath);
  352. if (lResult == 0xFFFFFFFF) {
  353. //
  354. // Directory does not exist.
  355. //
  356. DebugMsg((DM_VERBOSE, TEXT("[RenameFolder] Directory is not existed [%s] !\n"),szSrcPath));
  357. goto err1;
  358. }
  359. if (!(lResult & FILE_ATTRIBUTE_DIRECTORY)) {
  360. //
  361. // this is not a directory.
  362. //
  363. DebugMsg((DM_VERBOSE, TEXT("[RenameFolder] This is not a directory [%s] !\n"),szSrcPath));
  364. goto err1;
  365. }
  366. if (CopyProfileDirectory (szSrcPath, szDstPath, CPD_IGNOREHIVE)) {
  367. DebugMsg((DM_VERBOSE, TEXT("[RenameFolder] Successfully changed folder name:\n%s\n%s"),szSrcPath,szDstPath));
  368. if (! DeleteGroup(ObjSrcName,bCommonGroup)) {
  369. DebugMsg((DM_VERBOSE, TEXT("[RenameFolder] Delete old folder (%s) failed !"), ObjSrcName));
  370. } else {
  371. DebugMsg((DM_VERBOSE, TEXT("[RenameFolder] Delete old folder (%s) successfully !"), ObjSrcName));
  372. }
  373. }
  374. else {
  375. DebugMsg((DM_VERBOSE, TEXT("[RenameFolder] Convert Folder: Failed to change group name with error %d\n.%s\n%s\n"), GetLastError(),szSrcPath,szDstPath));
  376. goto err1;
  377. }
  378. bRet = TRUE;
  379. err1:
  380. return bRet;
  381. }
  382. BOOL RenameLink(
  383. BOOL bCommonGroup,
  384. LPCTSTR ObjSrcName,
  385. LPCTSTR ObjDstName,
  386. LPCTSTR ObjPath)
  387. {
  388. TCHAR szSrcPath[MAX_PATH];
  389. TCHAR szDstPath[MAX_PATH];
  390. LONG lResult;
  391. BOOL bRet=FALSE;
  392. DebugMsg((DM_VERBOSE,TEXT("[RenameFolder] \nOld = %s\nNew = %s\nPath = %s\n"),ObjSrcName,ObjDstName,ObjPath));
  393. GetProgramsDirectory(bCommonGroup,szSrcPath);
  394. GetProgramsDirectory(bCommonGroup,szDstPath);
  395. if (ObjPath && *ObjPath) {
  396. ConcatenatePaths(szSrcPath,ObjPath,MAX_PATH);
  397. ConcatenatePaths(szDstPath,ObjPath,MAX_PATH);
  398. }
  399. ConcatenatePaths(szSrcPath,ObjSrcName,MAX_PATH);
  400. ConcatenatePaths(szDstPath,ObjDstName,MAX_PATH);
  401. lstrcat(szSrcPath,TEXT(".lnk"));
  402. lstrcat(szDstPath,TEXT(".lnk"));
  403. lResult = GetFileAttributes(szSrcPath);
  404. if (lResult == 0xFFFFFFFF) {
  405. //
  406. // Directory does not exist.
  407. //
  408. DebugMsg((DM_VERBOSE, TEXT("[RenameLink] File is not existed [%s] !\n"),szSrcPath));
  409. goto err1;
  410. }
  411. if (lResult & FILE_ATTRIBUTE_DIRECTORY) {
  412. //
  413. // this is a directory, but we want a file.
  414. //
  415. DebugMsg((DM_VERBOSE, TEXT("[RenameLink] This is a directory [%s] !\n"),szSrcPath));
  416. goto err1;
  417. }
  418. //
  419. // if destination file existed, it's not good !
  420. //
  421. lResult = GetFileAttributes(szDstPath);
  422. if (lResult == 0xFFFFFFFF) {
  423. if (MoveFile (szSrcPath, szDstPath)) {
  424. DebugMsg((DM_VERBOSE, TEXT("[RenameLink] Successfully changed link name:\n%s\n%s\n"),szSrcPath,szDstPath));
  425. }
  426. else {
  427. DebugMsg((DM_VERBOSE, TEXT("[RenameLink] Failed to change link name with error %d.\n%s\n%s\n"), GetLastError(),szSrcPath,szDstPath));
  428. goto err1;
  429. }
  430. }
  431. else {
  432. DebugMsg((DM_VERBOSE, TEXT("[RenameLink] Destination file existed, maybe we don't want to overwrite ,%s\n"),szDstPath));
  433. goto err1;
  434. }
  435. bRet = TRUE;
  436. err1:
  437. return bRet;
  438. }
  439. BOOL RenameProgramFolderOrLink(HINF hInf,BOOL bCommon)
  440. {
  441. BOOL bRet = FALSE;
  442. INFCONTEXT InfContext;
  443. UINT LineCount,LineNo;
  444. LPCTSTR szSectionName = TEXT("StartMenu.ObjectToRename");
  445. LPCTSTR ObjectType;
  446. LPCTSTR ObjectSrcName;
  447. LPCTSTR ObjectDstName;
  448. LPCTSTR ObjectPath;
  449. LPCTSTR GroupAttribute;
  450. BOOL CommonGroup;
  451. BOOL IsMenuItem;
  452. if(hInf == INVALID_HANDLE_VALUE) {
  453. DebugMsg((DM_VERBOSE,TEXT("FEGRPCV: Open femgrate.inf failed !\n")));
  454. return FALSE;
  455. }
  456. LineCount = (UINT)SetupGetLineCount(hInf,szSectionName);
  457. if((LONG)LineCount <= 0) {
  458. goto err1;
  459. }
  460. for(LineNo=0; LineNo<LineCount; LineNo++) {
  461. if(SetupGetLineByIndex(hInf,szSectionName,LineNo,&InfContext)
  462. && (ObjectType = pSetupGetField(&InfContext,1))
  463. && (ObjectSrcName = pSetupGetField(&InfContext,2))
  464. && (ObjectDstName = pSetupGetField(&InfContext,3))
  465. && (GroupAttribute = pSetupGetField(&InfContext,5))) {
  466. ObjectPath = pSetupGetField(&InfContext,4);
  467. IsMenuItem = A2I(ObjectType);
  468. CommonGroup = A2I(GroupAttribute);
  469. if ((bCommon && (CommonGroup == 0)) ||
  470. (!bCommon && (CommonGroup == 1))) {
  471. // DebugMsg((DM_VERBOSE,TEXT("Eject this line(%d) .....................................\n"),LineNo));
  472. // DebugMsg((DM_VERBOSE,TEXT("ObjectType = %s\n"),ObjectType));
  473. // DebugMsg((DM_VERBOSE,TEXT("ObjectSrcName = %s\n"),ObjectSrcName));
  474. // DebugMsg((DM_VERBOSE,TEXT("ObjectDstName = %s\n"),ObjectDstName));
  475. // DebugMsg((DM_VERBOSE,TEXT("GroupAttribute= %s\n"),GroupAttribute));
  476. // DebugMsg((DM_VERBOSE,TEXT("bCommon = %d\n"),bCommon));
  477. continue;
  478. }
  479. if (IsMenuItem) {
  480. // DebugMsg((DM_VERBOSE,TEXT("RenameLink (%d).....................................\n"),LineNo));
  481. // DebugMsg((DM_VERBOSE,TEXT("ObjectType = %s\n"),ObjectType));
  482. // DebugMsg((DM_VERBOSE,TEXT("ObjectSrcName = %s\n"),ObjectSrcName));
  483. // DebugMsg((DM_VERBOSE,TEXT("ObjectDstName = %s\n"),ObjectDstName));
  484. // DebugMsg((DM_VERBOSE,TEXT("GroupAttribute= %s\n"),GroupAttribute));
  485. // DebugMsg((DM_VERBOSE,TEXT("bCommon = %d\n"),bCommon));
  486. RenameLink(bCommon,ObjectSrcName,ObjectDstName,ObjectPath);
  487. }
  488. else {
  489. // DebugMsg((DM_VERBOSE,TEXT("RenameFolder (%d) .....................................\n"),LineNo));
  490. // DebugMsg((DM_VERBOSE,TEXT("ObjectType = %s\n"),ObjectType));
  491. // DebugMsg((DM_VERBOSE,TEXT("ObjectSrcName = %s\n"),ObjectSrcName));
  492. // DebugMsg((DM_VERBOSE,TEXT("ObjectDstName = %s\n"),ObjectDstName));
  493. // DebugMsg((DM_VERBOSE,TEXT("GroupAttribute= %s\n"),GroupAttribute));
  494. // DebugMsg((DM_VERBOSE,TEXT("bCommon = %d\n"),bCommon));
  495. RenameFolder(bCommon,ObjectSrcName,ObjectDstName);
  496. }
  497. }
  498. }
  499. bRet = TRUE;
  500. err1:
  501. return bRet;
  502. }
  503. BOOL ReplaceString(
  504. LPCTSTR lpszOldStr,
  505. LPCTSTR lpszReplaceStr,
  506. LPCTSTR lpszReplacedWithStr,
  507. LPTSTR lpszOutputStr)
  508. {
  509. LPTSTR pszAnchor = NULL;
  510. lstrcpy(lpszOutputStr,lpszOldStr);
  511. pszAnchor = STRSTR(lpszOutputStr,lpszReplaceStr);
  512. if (!pszAnchor) {
  513. return FALSE;
  514. }
  515. if (lstrcmp(pszAnchor,lpszReplaceStr) != 0) {
  516. return FALSE;
  517. }
  518. lstrcpy(pszAnchor,lpszReplacedWithStr);
  519. return TRUE;
  520. }
  521. BOOL FixUserFolders(HINF hInf)
  522. {
  523. BOOL bRet = FALSE;
  524. INFCONTEXT InfContext;
  525. UINT LineCount,LineNo;
  526. LPCTSTR szSectionName = TEXT("Folder.ObjectToRename");
  527. LPCTSTR RegName;
  528. LPCTSTR NT4Name;
  529. LPCTSTR NT5Name;
  530. LPCTSTR MoveIt;
  531. TCHAR szUSFRegKey[MAX_PATH];
  532. TCHAR szNT4USF[MAX_PATH];
  533. TCHAR szExpNT4USF[MAX_PATH];
  534. TCHAR szExpNT5USF[MAX_PATH];
  535. DWORD dwSize, dwType;
  536. LONG lResult;
  537. UINT uiCount;
  538. HKEY hKey;
  539. if(hInf == INVALID_HANDLE_VALUE) {
  540. DebugMsg((DM_VERBOSE,TEXT("[FixUserFolders] Open femgrate.inf failed !\n")));
  541. return FALSE;
  542. }
  543. LineCount = (UINT)SetupGetLineCount(hInf,szSectionName);
  544. if((LONG)LineCount <= 0) {
  545. DebugMsg((DM_VERBOSE,TEXT("[FixUserFolders] line count == 0 !\n")));
  546. goto err1;
  547. }
  548. for(LineNo=0; LineNo<LineCount; LineNo++) {
  549. if (SetupGetLineByIndex(hInf,szSectionName,LineNo,&InfContext)
  550. && (RegName = pSetupGetField(&InfContext,1))
  551. && (NT4Name = pSetupGetField(&InfContext,2))
  552. && (NT5Name = pSetupGetField(&InfContext,3))
  553. && (MoveIt = pSetupGetField(&InfContext,4))) {
  554. DebugMsg((DM_VERBOSE,TEXT("FEGRPCV: RegName = %s !\n"),RegName));
  555. DebugMsg((DM_VERBOSE,TEXT("FEGRPCV: NT4Name = %s !\n"),NT4Name));
  556. DebugMsg((DM_VERBOSE,TEXT("FEGRPCV: NT5Name = %s !\n"),NT5Name));
  557. DebugMsg((DM_VERBOSE,TEXT("FEGRPCV: MoveIt = %s !\n"),MoveIt));
  558. //
  559. // Query for the user's current "Folder" location.
  560. //
  561. DebugMsg((DM_VERBOSE,TEXT("[FixUserFolders] FixUserFolder, [%d] !\n"),LineNo));
  562. lResult = RegOpenKeyEx (HKEY_CURRENT_USER,
  563. USER_SHELL_FOLDER,
  564. 0,
  565. KEY_READ | KEY_WRITE,
  566. &hKey);
  567. if (lResult != ERROR_SUCCESS) {
  568. DebugMsg((DM_VERBOSE,TEXT("[FixUserFolders] , Open User Shell Folders failed!\n")));
  569. continue;
  570. }
  571. lstrcpy(szUSFRegKey,RegName);
  572. dwSize = sizeof(szNT4USF);
  573. lResult = RegQueryValueEx (hKey,
  574. szUSFRegKey,
  575. NULL,
  576. &dwType,
  577. (LPBYTE) szNT4USF,
  578. &dwSize);
  579. DebugMsg((DM_VERBOSE,TEXT("FEGRPCV: Current Value (%s) = %s !\n"),szUSFRegKey,szNT4USF));
  580. if (lResult != ERROR_SUCCESS) {
  581. DebugMsg((DM_VERBOSE,TEXT("[FixUserFolders] Query User Shell Folders failed!\n")));
  582. RegCloseKey (hKey);
  583. continue;
  584. }
  585. if (lstrcmpi(NT4Name, szNT4USF) != 0) {
  586. DebugMsg((DM_VERBOSE, TEXT("[FixUserFolders] NT4Name <> szFolder :\n%s\n"),szExpNT4USF));
  587. RegCloseKey (hKey);
  588. continue;
  589. }
  590. //
  591. // MoveIt == 1, we want move it to new folder
  592. // else, we just update registry
  593. //
  594. if (lstrcmp(MoveIt,TEXT("1")) == 0) {
  595. ExpandEnvironmentStrings (NT4Name, szExpNT4USF, MAX_PATH);
  596. ExpandEnvironmentStrings (NT5Name, szExpNT5USF, MAX_PATH);
  597. if (CopyProfileDirectory (szExpNT4USF, szExpNT5USF, CPD_IGNOREHIVE)) {
  598. DebugMsg((DM_VERBOSE, TEXT("Fix Folder: Successfully changed folder name:\n%s\n%s"),szExpNT4USF,szExpNT5USF));
  599. if (Delnode (szExpNT4USF)) {
  600. DebugMsg((DM_VERBOSE, TEXT("[FixUserFolders] Successfully remove folder:\n%s\n"),szExpNT4USF));
  601. }
  602. else {
  603. DebugMsg((DM_VERBOSE, TEXT("[FixUserFolders] Failed remove folder:\n%s\n"),szExpNT4USF));
  604. }
  605. }
  606. else {
  607. DebugMsg((DM_VERBOSE, TEXT("[FixUserFolders] Failed to change folder name:\n%s\n%s"),szExpNT4USF,szExpNT5USF));
  608. }
  609. }
  610. //
  611. // Set CSIDL_PERSONAL to point to this directory.
  612. //
  613. lResult = RegSetValueEx (hKey, szUSFRegKey, 0, REG_EXPAND_SZ,
  614. (LPBYTE) NT5Name, (lstrlen(NT5Name) + 1) * sizeof(TCHAR));
  615. if (lResult != ERROR_SUCCESS) {
  616. DebugMsg((DM_VERBOSE, TEXT("[FixUserFolders] Set Registry faile, %s,%s\n"),szUSFRegKey,NT5Name));
  617. }
  618. RegCloseKey (hKey);
  619. }
  620. }
  621. bRet = TRUE;
  622. err1:
  623. return bRet;
  624. }
  625. BOOL FixSpecificFolder(HINF hInf)
  626. {
  627. BOOL bRet = FALSE;
  628. INFCONTEXT InfContext;
  629. UINT LineCount,LineNo;
  630. LPCTSTR szSectionName = TEXT("Folder.SpecificObjectToRename");
  631. LPCTSTR RegName;
  632. LPCTSTR NT4Name;
  633. LPCTSTR NT5Name;
  634. LPCTSTR MoveIt;
  635. TCHAR szUSFRegKey[MAX_PATH];
  636. TCHAR szNTUSF[MAX_PATH];
  637. TCHAR szExpNT4USF[MAX_PATH];
  638. TCHAR szExpNT5USF[MAX_PATH];
  639. DWORD dwSize, dwType;
  640. LONG lResult;
  641. UINT uiCount;
  642. HKEY hKey;
  643. if(hInf == INVALID_HANDLE_VALUE) {
  644. DebugMsg((DM_VERBOSE,TEXT("[FixSpecificFolder] Open femgrate.inf failed !\n")));
  645. return FALSE;
  646. }
  647. LineCount = (UINT)SetupGetLineCount(hInf,szSectionName);
  648. if((LONG)LineCount <= 0) {
  649. DebugMsg((DM_VERBOSE,TEXT("[FixSpecificFolder] line count == 0 !\n")));
  650. goto err1;
  651. }
  652. for(LineNo=0; LineNo<LineCount; LineNo++) {
  653. if (SetupGetLineByIndex(hInf,szSectionName,LineNo,&InfContext)
  654. && (RegName = pSetupGetField(&InfContext,1))
  655. && (NT4Name = pSetupGetField(&InfContext,2))
  656. && (NT5Name = pSetupGetField(&InfContext,3))) {
  657. DebugMsg((DM_VERBOSE,TEXT("FixSpecificFolder: RegName = %s !\n"),RegName));
  658. DebugMsg((DM_VERBOSE,TEXT("FixSpecificFolder: NT4Name = %s !\n"),NT4Name));
  659. DebugMsg((DM_VERBOSE,TEXT("FixSpecificFolder: NT5Name = %s !\n"),NT5Name));
  660. //
  661. // Query for the user's current "Folder" location.
  662. //
  663. DebugMsg((DM_VERBOSE,TEXT("[FixSpecificFolder] FixUserFolder, [%d] !\n"),LineNo));
  664. lResult = RegOpenKeyEx (HKEY_CURRENT_USER,
  665. USER_SHELL_FOLDER,
  666. 0,
  667. KEY_READ,
  668. &hKey);
  669. if (lResult != ERROR_SUCCESS) {
  670. DebugMsg((DM_VERBOSE,TEXT("[FixSpecificFolder] , Open User Shell Folders failed!\n")));
  671. continue;
  672. }
  673. lstrcpy(szUSFRegKey,RegName);
  674. dwSize = sizeof(szNTUSF);
  675. lResult = RegQueryValueEx (hKey,
  676. szUSFRegKey,
  677. NULL,
  678. &dwType,
  679. (LPBYTE) szNTUSF,
  680. &dwSize);
  681. DebugMsg((DM_VERBOSE,TEXT("FixSpecificFolder: Current Value (%s) = %s !\n"),szUSFRegKey,szNTUSF));
  682. if (lResult != ERROR_SUCCESS) {
  683. DebugMsg((DM_VERBOSE,TEXT("[FixUserFolders] Query User Shell Folders failed!\n")));
  684. RegCloseKey (hKey);
  685. continue;
  686. }
  687. ExpandEnvironmentStrings (szNTUSF, szExpNT4USF, MAX_PATH);
  688. ExpandEnvironmentStrings (szNTUSF, szExpNT5USF, MAX_PATH);
  689. ConcatenatePaths(szExpNT4USF,NT4Name,MAX_PATH);
  690. ConcatenatePaths(szExpNT5USF,NT5Name,MAX_PATH);
  691. lResult = GetFileAttributes(szExpNT4USF);
  692. if (lResult == 0xFFFFFFFF) {
  693. //
  694. // Directory does not exist.
  695. //
  696. DebugMsg((DM_VERBOSE, TEXT("[FixSpecificFolder] - File is not existed [%s] !\n"),szExpNT4USF));
  697. } else if ((lResult & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) {
  698. //
  699. // this isn't a directory
  700. //
  701. DebugMsg((DM_VERBOSE, TEXT("[FixSpecificFolder] This is a directory [%s] !\n"),szExpNT4USF));
  702. } else if (MoveFile(szExpNT4USF, szExpNT5USF)) {
  703. DebugMsg((DM_VERBOSE, TEXT("[FixSpecificFolder] Move %s to %s OK !\n"),szExpNT4USF, szExpNT5USF));
  704. }
  705. else {
  706. DebugMsg((DM_VERBOSE, TEXT("[FixSpecificFolder] Failed to change folder name:\n%s\n%s"),szExpNT4USF,szExpNT5USF));
  707. }
  708. RegCloseKey (hKey);
  709. }
  710. }
  711. bRet = TRUE;
  712. err1:
  713. return bRet;
  714. }
  715. BOOL FixFoldersInSetup(HINF hInf,BOOL bCommonGroup)
  716. {
  717. BOOL bRet = FALSE;
  718. INFCONTEXT InfContext;
  719. UINT LineCount,LineNo;
  720. LPCTSTR szSectionName = TEXT("Folder.ObjectToRenameInSetup");
  721. LPCTSTR RegName;
  722. LPCTSTR NT4Name;
  723. LPCTSTR NT5Name;
  724. TCHAR szUSFRegKey[MAX_PATH];
  725. TCHAR szNT5USF[MAX_PATH];
  726. TCHAR szNT4USF[MAX_PATH];
  727. TCHAR szExpNT4USF[MAX_PATH];
  728. TCHAR szExpNT5USF[MAX_PATH];
  729. DWORD dwSize, dwType;
  730. LONG lResult;
  731. HKEY hKey;
  732. if(hInf == INVALID_HANDLE_VALUE) {
  733. DebugMsg((DM_VERBOSE,TEXT("[FixFoldersInSetup] Open femgrate.inf failed !\n")));
  734. return FALSE;
  735. }
  736. LineCount = (UINT)SetupGetLineCount(hInf,szSectionName);
  737. if((LONG)LineCount <= 0) {
  738. DebugMsg((DM_VERBOSE,TEXT("[FixFoldersInSetup] line count == 0 !\n")));
  739. goto err1;
  740. }
  741. for(LineNo=0; LineNo<LineCount; LineNo++) {
  742. if (SetupGetLineByIndex(hInf,szSectionName,LineNo,&InfContext)
  743. && (RegName = pSetupGetField(&InfContext,1))
  744. && (NT4Name = pSetupGetField(&InfContext,2))
  745. && (NT5Name = pSetupGetField(&InfContext,3))) {
  746. DebugMsg((DM_VERBOSE,TEXT("[FixFoldersInSetup] Line# [%d] !\n"),LineNo));
  747. DebugMsg((DM_VERBOSE,TEXT("[FixFoldersInSetup] RegName = %s !\n"),RegName));
  748. DebugMsg((DM_VERBOSE,TEXT("[FixFoldersInSetup] NT4Name = %s !\n"),NT4Name));
  749. DebugMsg((DM_VERBOSE,TEXT("[FixFoldersInSetup] NT5Name = %s !\n"),NT5Name));
  750. //
  751. // Query for the user's current "Folder" location.
  752. //
  753. lResult = RegOpenKeyEx ((bCommonGroup ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER),
  754. USER_SHELL_FOLDER, 0, KEY_READ | KEY_WRITE, &hKey);
  755. if (lResult != ERROR_SUCCESS) {
  756. DebugMsg((DM_VERBOSE,TEXT("[FixFoldersInSetup] FixSpecialFolder, Open User Shell Folders failed!\n")));
  757. continue;
  758. }
  759. if (bCommonGroup) {
  760. lstrcpy (szUSFRegKey,TEXT("Common "));
  761. lstrcat (szUSFRegKey,RegName);
  762. } else {
  763. lstrcpy (szUSFRegKey,RegName);
  764. }
  765. dwSize = sizeof(szNT5USF);
  766. lResult = RegQueryValueEx (hKey,
  767. szUSFRegKey,
  768. NULL,
  769. &dwType,
  770. (LPBYTE) szNT5USF,
  771. &dwSize);
  772. DebugMsg((DM_VERBOSE,TEXT("[FixFoldersInSetup] Current Registry Value (%s) = %s !\n"),szUSFRegKey,szNT5USF));
  773. if (lResult != ERROR_SUCCESS) {
  774. DebugMsg((DM_VERBOSE,TEXT("[FixFoldersInSetup] Query User Shell Folders failed!\n")));
  775. RegCloseKey(hKey);
  776. continue;
  777. }
  778. if (ReplaceString(szNT5USF,NT5Name,NT4Name,szNT4USF)) {
  779. ExpandEnvironmentStrings (szNT4USF, szExpNT4USF, MAX_PATH);
  780. ExpandEnvironmentStrings (szNT5USF, szExpNT5USF, MAX_PATH);
  781. DebugMsg((DM_VERBOSE, TEXT("[FixFoldersInSetup] szExpNT4USF = %s\n"),szExpNT4USF));
  782. DebugMsg((DM_VERBOSE, TEXT("[FixFoldersInSetup] szExpNT5USF = %s\n"),szExpNT5USF));
  783. }
  784. else {
  785. DebugMsg((DM_VERBOSE, TEXT("[FixFoldersInSetup] The replace string got error \n")));
  786. DebugMsg((DM_VERBOSE, TEXT("[FixFoldersInSetup] %s\n %s\n %s\n%s\n"),szNT5USF,NT5Name,NT4Name,szNT4USF));
  787. }
  788. if (CopyProfileDirectory (szExpNT4USF, szExpNT5USF, CPD_IGNOREHIVE)) {
  789. DebugMsg((DM_VERBOSE, TEXT("[FixFoldersInSetup] Successfully copied folder\nFrom:%s\nTo :%s\n"),szExpNT4USF,szExpNT5USF));
  790. if (Delnode (szExpNT4USF)) {
  791. DebugMsg((DM_VERBOSE, TEXT("[FixFoldersInSetup] Successfully removed folder:%s\n"),szExpNT4USF));
  792. }
  793. else {
  794. DebugMsg((DM_VERBOSE, TEXT("Fix Folder: Failed remove folder:\n%s\n"),szExpNT4USF));
  795. }
  796. }
  797. else {
  798. DebugMsg((DM_VERBOSE, TEXT("Fix Folder: Failed to change folder name:\n%s\n%s"),szExpNT4USF,szExpNT5USF));
  799. }
  800. RegCloseKey (hKey);
  801. }
  802. }
  803. bRet = TRUE;
  804. err1:
  805. return bRet;
  806. }
  807. BOOL FixCommon(HINF hInf)
  808. {
  809. TCHAR szCommon[MAX_PATH];
  810. TCHAR szProgramFolderPath[MAX_PATH];
  811. TCHAR szExpProgramFolderPath[MAX_PATH];
  812. BOOL bRet = FALSE;
  813. HANDLE hFile;
  814. DWORD RequiredSize;
  815. WIN32_FIND_DATA fd;
  816. UINT nCommon, nFileName;
  817. LPTSTR lpTag, lpEnd, lpEnd2;
  818. //
  819. // Loop through all the program groups in the All Users profile
  820. // and remove the " (Common)" tag.
  821. //
  822. if(hInf == INVALID_HANDLE_VALUE) {
  823. DebugMsg((DM_VERBOSE,TEXT("[FixCommon] Open femgrate.inf failed !\n")));
  824. return FALSE;
  825. }
  826. if (! SetupGetLineText(NULL,
  827. hInf,
  828. TEXT("Misc"),
  829. TEXT("Common"),
  830. szCommon,
  831. sizeof(szCommon),
  832. &RequiredSize)) {
  833. goto err1;
  834. }
  835. nCommon = lstrlen(szCommon);
  836. GetProgramsDirectory(TRUE,szProgramFolderPath);
  837. ExpandEnvironmentStrings (szProgramFolderPath, szExpProgramFolderPath, MAX_PATH);
  838. lstrcpy(szProgramFolderPath,szExpProgramFolderPath);
  839. //
  840. // From here, szProgramFolderPath used for Folder name without "Common"
  841. //
  842. lpEnd = CheckSlash (szExpProgramFolderPath);
  843. lpEnd2 = CheckSlash (szProgramFolderPath);
  844. lstrcpy (lpEnd, c_szStarDotStar);
  845. hFile = FindFirstFile (szExpProgramFolderPath, &fd);
  846. DebugMsg((DM_VERBOSE, TEXT("[FixCommon] Find %s\n"),szExpProgramFolderPath));
  847. if (hFile != INVALID_HANDLE_VALUE) {
  848. do {
  849. if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  850. nFileName = lstrlen (fd.cFileName);
  851. DebugMsg((DM_VERBOSE, TEXT("Find %s\n"),fd.cFileName));
  852. if (nFileName > nCommon) {
  853. lpTag = fd.cFileName + nFileName - nCommon;
  854. DebugMsg((DM_VERBOSE, TEXT("[FixCommon] lpTag=%s szCommon=%s\n"),lpTag, szCommon));
  855. if (!lstrcmpi(lpTag, szCommon)) {
  856. lstrcpy (lpEnd, fd.cFileName);
  857. *lpTag = TEXT('\0');
  858. lstrcpy (lpEnd2, fd.cFileName);
  859. if (CopyProfileDirectory (szExpProgramFolderPath, szProgramFolderPath, CPD_IGNOREHIVE)) {
  860. DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : Successfully changed group name:\n")));
  861. DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : Orginial: %s\n"), szExpProgramFolderPath));
  862. DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : New: %s\n"), szProgramFolderPath));
  863. if (Delnode (szExpProgramFolderPath)) {
  864. DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : Successfully remove folder:\n%s\n"),szExpProgramFolderPath));
  865. }
  866. else {
  867. DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : Failed remove folder:\n%s\n"),szExpProgramFolderPath));
  868. }
  869. } else {
  870. DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : Failed to change group name with error %d.\n"), GetLastError()));
  871. DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : Orginial: %s\n"), szExpProgramFolderPath));
  872. DebugMsg((DM_VERBOSE, TEXT("[FixCommon] : New: %s\n"), szProgramFolderPath));
  873. }
  874. }
  875. }
  876. }
  877. } while (FindNextFile(hFile, &fd));
  878. FindClose (hFile);
  879. }
  880. bRet = TRUE;
  881. err1:
  882. return bRet;
  883. }
  884. BOOL FixAppearanceScheme(HINF hInf)
  885. {
  886. HKEY hAppearanceKey,hSchemeKey;
  887. LONG lResult;
  888. LPCTSTR szSectionName = TEXT("Apperance Scheme");
  889. TCHAR szCurrentScheme[MAX_PATH];
  890. LPCTSTR NT4SchemeName;
  891. LPCTSTR NT5SchemeName;
  892. LONG LineCount,LineNo;
  893. DWORD dwSize,dwType;
  894. INFCONTEXT InfContext;
  895. BOOL bRet = FALSE;
  896. if(hInf == INVALID_HANDLE_VALUE) {
  897. DebugMsg((DM_VERBOSE,TEXT("[FixAppearanceScheme] Open femgrate.inf failed !\n")));
  898. goto Err0;
  899. }
  900. lResult = RegOpenKeyEx (HKEY_CURRENT_USER,
  901. REGSTR_PATH_APPEARANCE,
  902. 0,
  903. KEY_ALL_ACCESS,
  904. &hAppearanceKey);
  905. if (lResult != ERROR_SUCCESS) {
  906. DebugMsg((DM_VERBOSE,TEXT("[FixAppearanceScheme] Open REGSTR_PATH_APPEARANCE failed !\n")));
  907. goto Err0;
  908. }
  909. //
  910. // Now query for the programs directory
  911. //
  912. dwSize = MAX_PATH * sizeof(TCHAR);
  913. szCurrentScheme[0] = TEXT('\0');
  914. lResult = RegQueryValueEx (hAppearanceKey,
  915. TEXT("Current"),
  916. NULL,
  917. &dwType,
  918. (LPBYTE) szCurrentScheme,
  919. &dwSize);
  920. if (lResult != ERROR_SUCCESS) {
  921. //
  922. // this case is fine
  923. //
  924. szCurrentScheme[0] = TEXT('\0');
  925. }
  926. lResult = RegOpenKeyEx (HKEY_CURRENT_USER,
  927. REGSTR_PATH_LOOKSCHEMES,
  928. 0,
  929. KEY_ALL_ACCESS,
  930. &hSchemeKey);
  931. if (lResult != ERROR_SUCCESS) {
  932. DebugMsg((DM_VERBOSE,TEXT("[FixAppearanceScheme] Open REGSTR_PATH_APPEARANCE failed !\n")));
  933. goto Err1;
  934. }
  935. LineCount = (UINT)SetupGetLineCount(hInf,szSectionName);
  936. if((LONG)LineCount <= 0) {
  937. DebugMsg((DM_VERBOSE,TEXT("[FixAppearanceScheme] line count == 0 !\n")));
  938. goto Err2;
  939. }
  940. for(LineNo=0; LineNo<LineCount; LineNo++) {
  941. if (SetupGetLineByIndex(hInf,szSectionName,LineNo,&InfContext)
  942. && (NT4SchemeName = pSetupGetField(&InfContext,1))) {
  943. if (szCurrentScheme[0] != '\0') {
  944. if (lstrcmp(szCurrentScheme,NT4SchemeName) == 0) {
  945. if (NT5SchemeName = pSetupGetField(&InfContext,2)) {
  946. lResult = RegSetValueEx(hAppearanceKey,
  947. TEXT("Current"),
  948. 0,
  949. REG_SZ,
  950. (LPBYTE) NT5SchemeName,
  951. (lstrlen(NT5SchemeName)+1)*sizeof(TCHAR));
  952. if (lResult != ERROR_SUCCESS) {
  953. DebugMsg((DM_VERBOSE,TEXT("[FixAppearanceScheme] Set Appearance current scheme fail ! \n")));
  954. }
  955. }
  956. else {
  957. DebugMsg((DM_VERBOSE,TEXT("[FixAppearanceScheme] NT5's scheme missed!\n")));
  958. }
  959. }
  960. }
  961. lResult = RegDeleteValue(hSchemeKey,
  962. NT4SchemeName);
  963. if (lResult != ERROR_SUCCESS) {
  964. DebugMsg((DM_VERBOSE,TEXT("[FixAppearanceScheme] Delete scheme %s failed !\n"),NT4SchemeName));
  965. }
  966. }
  967. }
  968. bRet = TRUE;
  969. Err2:
  970. RegCloseKey(hSchemeKey);
  971. Err1:
  972. RegCloseKey(hAppearanceKey);
  973. Err0:
  974. return bRet;
  975. }
  976. BOOL DoInstallationFromSection(HINF hInf,LPCTSTR lpszSectionName)
  977. {
  978. HSPFILEQ FileQueue;
  979. PVOID QContext;
  980. BOOL bRet=FALSE;
  981. if(hInf == INVALID_HANDLE_VALUE) {
  982. DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] Open femgrate.inf failed !\n")));
  983. goto Err0;
  984. }
  985. if ((FileQueue = SetupOpenFileQueue()) == INVALID_HANDLE_VALUE) {
  986. DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupOpenFileQueue failed !\n")));
  987. goto Err0;
  988. }
  989. bRet = SetupInstallFilesFromInfSection(hInf,
  990. NULL,
  991. FileQueue,
  992. lpszSectionName,
  993. NULL,
  994. SP_COPY_NEWER );
  995. if (!bRet) {
  996. DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupInstallFilesFromInfSection failed !\n")));
  997. goto Err1;
  998. }
  999. if (!(QContext = SetupInitDefaultQueueCallback(NULL))) {
  1000. bRet = FALSE;
  1001. DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupInitDefaultQueueCallback failed !\n")));
  1002. goto Err1;
  1003. }
  1004. bRet = SetupCommitFileQueue(NULL,
  1005. FileQueue,
  1006. SetupDefaultQueueCallback,
  1007. QContext );
  1008. if (!bRet) {
  1009. DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupCommitFileQueue failed !\n")));
  1010. goto Err1;
  1011. }
  1012. bRet = SetupInstallFromInfSection( NULL,
  1013. hInf,
  1014. lpszSectionName,
  1015. SPINST_ALL & ~SPINST_FILES,
  1016. NULL,
  1017. NULL,
  1018. 0,
  1019. NULL,
  1020. NULL,
  1021. NULL,
  1022. NULL );
  1023. if (!bRet) {
  1024. DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupInstallFromInfSection failed !\n")));
  1025. goto Err1;
  1026. }
  1027. bRet = TRUE;
  1028. Err1:
  1029. SetupTermDefaultQueueCallback(QContext);
  1030. SetupCloseFileQueue(FileQueue);
  1031. Err0:
  1032. return bRet;
  1033. }
  1034. TCHAR szBuf[300];
  1035. BOOL SoundMapSBtoDBKana(HINF hInf,LPCTSTR lpszSectionName,LPTSTR lpszSoundName)
  1036. {
  1037. LPCTSTR szSBKana,szDBKana;
  1038. LONG LineCount,LineNo;
  1039. DWORD dwSize,dwType;
  1040. INFCONTEXT InfContext;
  1041. if(hInf == INVALID_HANDLE_VALUE) {
  1042. DebugMsg((DM_VERBOSE,TEXT("[IsInSoundSBKanaList] Open femgrate.inf failed !\n")));
  1043. return FALSE;
  1044. }
  1045. LineCount = (UINT)SetupGetLineCount(hInf,lpszSectionName);
  1046. if((LONG)LineCount <= 0) {
  1047. DebugMsg((DM_VERBOSE,TEXT("[SoundMapSBtoDBKana] line count == 0 !\n")));
  1048. return FALSE;
  1049. }
  1050. for(LineNo=0; LineNo<LineCount; LineNo++) {
  1051. if (SetupGetLineByIndex(hInf,lpszSectionName,LineNo,&InfContext)
  1052. && (szSBKana = pSetupGetField(&InfContext,1))) {
  1053. if (lstrcmpi(szSBKana,lpszSoundName) == 0) {
  1054. if (szDBKana = pSetupGetField(&InfContext,2)) {
  1055. lstrcpy(lpszSoundName,szDBKana);
  1056. return TRUE;
  1057. }
  1058. else {
  1059. //
  1060. // inf error, no second data
  1061. //
  1062. return FALSE;
  1063. }
  1064. }
  1065. }
  1066. }
  1067. return FALSE;
  1068. }
  1069. BOOL SoundDoAppsNameSubstitution(HINF hInf,LPTSTR lpszOrgSoundName)
  1070. {
  1071. TCHAR szMediaDir[] = TEXT("%SystemRoot%\\Media\\");
  1072. TCHAR szExpMediaDir[MAX_PATH];
  1073. LPTSTR lpszAnchor;
  1074. TCHAR szOnlySoundName[MAX_PATH];
  1075. if (StrStrI(lpszOrgSoundName,TEXT("\\"))) {
  1076. if (ExpandEnvironmentStrings(szMediaDir,szExpMediaDir,MAX_PATH) == 0) {
  1077. return FALSE;
  1078. }
  1079. lpszAnchor = StrStrI(lpszOrgSoundName,szExpMediaDir);
  1080. if ((lpszAnchor == NULL ) || (lpszAnchor != lpszOrgSoundName)) {
  1081. return FALSE;
  1082. }
  1083. lstrcpy(szOnlySoundName,lpszAnchor+lstrlen(szExpMediaDir));
  1084. DebugMsg((DM_VERBOSE,TEXT("We want to find %s !\n"),szOnlySoundName));
  1085. if (SoundMapSBtoDBKana(hInf,TEXT("Sound.Files"),szOnlySoundName)) {
  1086. lstrcpy(lpszAnchor+lstrlen(szExpMediaDir),szOnlySoundName);
  1087. return TRUE;
  1088. }
  1089. }
  1090. else {
  1091. if (SoundMapSBtoDBKana(hInf,TEXT("Sound.Files"),lpszOrgSoundName)) {
  1092. return TRUE;
  1093. }
  1094. }
  1095. return FALSE;
  1096. }
  1097. BOOL EnumSoundSchemeApps(HKEY hKey,HINF hInf)
  1098. {
  1099. HKEY hSubKey;
  1100. DWORD dwIndex;
  1101. DWORD dwKeyNameSize;
  1102. TCHAR szKeyName[MAX_PATH];
  1103. DWORD dwSoundValue;
  1104. TCHAR szSoundValue[MAX_PATH];
  1105. LONG lResult;
  1106. dwKeyNameSize = sizeof(szKeyName);
  1107. for (dwIndex = 0;
  1108. RegEnumKey(hKey, dwIndex, szKeyName, dwKeyNameSize) == ERROR_SUCCESS;
  1109. dwIndex++) {
  1110. lResult = RegOpenKey(hKey,
  1111. szKeyName,
  1112. &hSubKey);
  1113. if (lResult == ERROR_SUCCESS) {
  1114. EnumSoundSchemeApps(hSubKey,hInf);
  1115. RegCloseKey(hSubKey);
  1116. }
  1117. }
  1118. //
  1119. // no sub-key, then just get the value
  1120. //
  1121. if (dwIndex == 0) {
  1122. dwSoundValue = sizeof(szSoundValue);
  1123. lResult = RegQueryValue(hKey,
  1124. NULL,
  1125. szSoundValue,
  1126. &dwSoundValue);
  1127. if (lResult == ERROR_SUCCESS) {
  1128. if (szSoundValue[0]) {
  1129. if (SoundDoAppsNameSubstitution(hInf,szSoundValue)) {
  1130. RegSetValue(hKey,
  1131. NULL,
  1132. REG_SZ,
  1133. szSoundValue,
  1134. (lstrlen(szSoundValue)+1)*sizeof(TCHAR));
  1135. }
  1136. }
  1137. }
  1138. }
  1139. return TRUE;
  1140. }
  1141. BOOL FixSoundRegValue(HINF hInf)
  1142. {
  1143. LONG lResult;
  1144. BOOL bRet=FALSE;
  1145. HKEY hKey;
  1146. if(hInf == INVALID_HANDLE_VALUE) {
  1147. DebugMsg((DM_VERBOSE,TEXT("[FixSoundRegValue] Open femgrate.inf failed !\n")));
  1148. goto Err0;
  1149. }
  1150. lResult = RegOpenKeyEx (HKEY_CURRENT_USER,
  1151. REGSTR_PATH_APPS,
  1152. 0,
  1153. KEY_ALL_ACCESS,
  1154. &hKey);
  1155. if (lResult != ERROR_SUCCESS) {
  1156. DebugMsg((DM_VERBOSE,TEXT("[FixAppearanceScheme] Open REGSTR_PATH_APPEARANCE failed !\n")));
  1157. goto Err0;
  1158. }
  1159. EnumSoundSchemeApps(hKey,hInf);
  1160. if (! DoInstallationFromSection(hInf, TEXT("Sound.Reg.Update"))) {
  1161. DebugMsg((DM_VERBOSE,TEXT("[FixSoundRegValue] DoInstallationFromSection failed !\n")));
  1162. goto Err1;
  1163. }
  1164. bRet = TRUE;
  1165. Err1:
  1166. RegCloseKey(hKey);
  1167. Err0:
  1168. return bRet;
  1169. }
  1170. BOOL FixSoundFiles(HINF hInf)
  1171. {
  1172. if (! DoInstallationFromSection(hInf, TEXT("Sound.Files.Delete"))) {
  1173. DebugMsg((DM_VERBOSE,TEXT("[FixSoundFiles] DeleteSBKanaSoundFiles failed !\n")));
  1174. }
  1175. return TRUE;
  1176. }
  1177. BOOL IsInSetupUpgradeMode()
  1178. {
  1179. LPCTSTR szKeyName = TEXT("SYSTEM\\Setup");
  1180. DWORD dwType, dwSize;
  1181. HKEY hKeySetup;
  1182. DWORD dwSystemSetupInProgress,dwUpgradeInProcess;
  1183. LONG lResult;
  1184. if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, szKeyName, 0,
  1185. KEY_READ, &hKeySetup) == ERROR_SUCCESS) {
  1186. dwSize = sizeof(DWORD);
  1187. lResult = RegQueryValueEx (hKeySetup, TEXT("SystemSetupInProgress"), NULL,
  1188. &dwType, (LPBYTE) &dwSystemSetupInProgress, &dwSize);
  1189. if (lResult == ERROR_SUCCESS) {
  1190. lResult = RegQueryValueEx (hKeySetup, TEXT("UpgradeInProgress"), NULL,
  1191. &dwType, (LPBYTE) &dwUpgradeInProcess, &dwSize);
  1192. if (lResult == ERROR_SUCCESS) {
  1193. DebugMsg((DM_VERBOSE,TEXT("[IsInSetupUpgradeMode] dwSystemSetupInProgress =%, dwUpgradeInProcess=%d !\n"),dwSystemSetupInProgress,dwUpgradeInProcess));
  1194. if ((dwSystemSetupInProgress != 0) && (dwUpgradeInProcess != 0)) {
  1195. return TRUE;
  1196. }
  1197. }
  1198. else {
  1199. DebugMsg((DM_VERBOSE,TEXT("[IsInSetupUpgradeMode] RegQueryValueEx UpgradeInProcess failed !\n")));
  1200. }
  1201. }
  1202. else {
  1203. DebugMsg((DM_VERBOSE,TEXT("[IsInSetupUpgradeMode] RegQueryValueEx SystemSetupInProgress failed !\n")));
  1204. }
  1205. RegCloseKey (hKeySetup);
  1206. }
  1207. else {
  1208. DebugMsg((DM_VERBOSE,TEXT("[IsInSetupUpgradeMode] RegOpenKeyEx failed !\n")));
  1209. }
  1210. return FALSE ;
  1211. }
  1212. int WINAPI WinMain(
  1213. HINSTANCE hInstance,
  1214. HINSTANCE hPrevInstance,
  1215. LPSTR lpCmdLine,
  1216. int nCmdShow)
  1217. {
  1218. int Cmds[FUNC_NumofFunctions + 1];
  1219. int i;
  1220. HINF hMigrateInf;
  1221. DebugMsg((DM_VERBOSE,TEXT("FEGRPCV: Start Executing....\n")));
  1222. ghInst = hInstance;
  1223. if (GetFunctions(Cmds,FUNC_NumofFunctions+1) == 0) {
  1224. DebugMsg((DM_VERBOSE,TEXT("FEGRPCV: There are no valid commands. \n")));
  1225. return (1);
  1226. }
  1227. //
  1228. // Open INF file first !
  1229. //
  1230. hMigrateInf = SetupOpenInfFile(
  1231. TEXT("femgrate.inf"),
  1232. NULL,
  1233. INF_STYLE_WIN4,
  1234. NULL);
  1235. if(hMigrateInf == INVALID_HANDLE_VALUE) {
  1236. DebugMsg((DM_VERBOSE,TEXT("[FixCommon] Open femgrate.inf failed !\n")));
  1237. return 0;
  1238. }
  1239. for (i=0; Cmds[i] != NO_FUNCTION && i < FUNC_NumofFunctions+1; i++) {
  1240. switch(Cmds[i]) {
  1241. case FUNC_PatchInSetup:
  1242. if (IsInSetupUpgradeMode() == FALSE) {
  1243. DebugMsg((DM_VERBOSE,TEXT("This is NOT upgrade \n")));
  1244. break;
  1245. }
  1246. DebugMsg((DM_VERBOSE,TEXT("..................This is upgrade \n")));
  1247. if (FixFoldersInSetup(hMigrateInf,TRUE)) {
  1248. if (FixCommon(hMigrateInf)) {
  1249. if (RenameProgramFolderOrLink(hMigrateInf,TRUE)) {
  1250. DebugMsg((DM_VERBOSE,TEXT("All Users, RenameProgramFolderOrLink() ok ! \n")));
  1251. }
  1252. else {
  1253. DebugMsg((DM_VERBOSE,TEXT("All Users, RenameProgramFolderOrLink() failed ! \n")));
  1254. }
  1255. }
  1256. else {
  1257. DebugMsg((DM_VERBOSE,TEXT("All Users, FixCommon() failed ! \n")));
  1258. }
  1259. }
  1260. else {
  1261. DebugMsg((DM_VERBOSE,TEXT("All Users, FixFoldersInSetup() failed ! \n")));
  1262. }
  1263. if (FixFoldersInSetup(hMigrateInf,FALSE)) {
  1264. if (RenameProgramFolderOrLink(hMigrateInf,FALSE)) {
  1265. DebugMsg((DM_VERBOSE,TEXT("Default User, RenameProgramFolderOrLink() ok ! \n")));
  1266. }
  1267. else {
  1268. DebugMsg((DM_VERBOSE,TEXT("Default User, RenameProgramFolderOrLink() failed ! \n")));
  1269. }
  1270. }
  1271. else {
  1272. DebugMsg((DM_VERBOSE,TEXT("Default User, FixFoldersInSetup() failed ! \n")));
  1273. }
  1274. if (FixSoundFiles(hMigrateInf) && FixSoundRegValue(hMigrateInf)) {
  1275. DebugMsg((DM_VERBOSE,TEXT("Fix Sound Settings OK ! \n")));
  1276. }
  1277. else {
  1278. DebugMsg((DM_VERBOSE,TEXT("Fix Sound Settings failed ! \n")));
  1279. }
  1280. if (FixSoundRegValue(hMigrateInf)) {
  1281. DebugMsg((DM_VERBOSE,TEXT("FixSoundRegValue OK ! \n")));
  1282. }
  1283. else {
  1284. DebugMsg((DM_VERBOSE,TEXT("FixSoundRegValue failed ! \n")));
  1285. }
  1286. break;
  1287. case FUNC_PatchInLogon:
  1288. if (FixUserFolders(hMigrateInf)) {
  1289. if (RenameProgramFolderOrLink(hMigrateInf,FALSE)) {
  1290. DebugMsg((DM_VERBOSE,TEXT("Current User, RenameProgramFolderOrLink() ok ! \n")));
  1291. }
  1292. else {
  1293. DebugMsg((DM_VERBOSE,TEXT("Current User, RenameProgramFolderOrLink() failed ! \n")));
  1294. }
  1295. }
  1296. else {
  1297. DebugMsg((DM_VERBOSE,TEXT("Current User, FixFoldersInSetup() failed ! \n")));
  1298. }
  1299. if (FixSpecificFolder(hMigrateInf)) {
  1300. DebugMsg((DM_VERBOSE,TEXT("Current User, FixSpecificFolder() ok ! \n")));
  1301. } else {
  1302. DebugMsg((DM_VERBOSE,TEXT("Current User, FixSpecificFolder() failed ! \n")));
  1303. }
  1304. if (FixSoundRegValue(hMigrateInf)) {
  1305. DebugMsg((DM_VERBOSE,TEXT("FixSoundRegValue OK ! \n")));
  1306. }
  1307. else {
  1308. DebugMsg((DM_VERBOSE,TEXT("FixSoundRegValue failed ! \n")));
  1309. }
  1310. break;
  1311. case FUNC_PatchTest:
  1312. // if (FixUserFolders()) {
  1313. // if (RenameProgramFolderOrLink(hMigrateInf,FALSE)) {
  1314. // }
  1315. // else {
  1316. // DebugMsg((DM_VERBOSE,TEXT("Current User, RenameProgramFolderOrLink() failed ! \n")));
  1317. // }
  1318. // }
  1319. // else {
  1320. // DebugMsg((DM_VERBOSE,TEXT("Current User, FixFoldersInSetup() failed ! \n")));
  1321. // }
  1322. // FixAppearanceScheme(hMigrateInf);
  1323. // FixSoundFiles(hMigrateInf);
  1324. // FixSoundRegValue(hMigrateInf);
  1325. // FixSpecificFolder(hMigrateInf);
  1326. break;
  1327. default:
  1328. DebugMsg((DM_VERBOSE,TEXT("No such function\n")));
  1329. }
  1330. }
  1331. SetupCloseInfFile(hMigrateInf);
  1332. return (0);
  1333. }