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

  1. /****************************** Module Header ******************************\
  2. * Module Name: utils.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * FEMGRATE utility functions
  7. *
  8. \***************************************************************************/
  9. #include "femgrate.h"
  10. #include <tchar.h>
  11. #ifdef MYDBG
  12. void Print(UINT mask,LPCTSTR pszFormat,...)
  13. {
  14. TCHAR szBuf[512];
  15. va_list arglist;
  16. va_start(arglist,pszFormat);
  17. wvsprintf(szBuf,pszFormat,arglist);
  18. #ifdef DEBUGLOG
  19. lstrcat (szBuf,TEXT("\r\n"));
  20. SetupLogError(DBGTITLE,LogSevInformation);
  21. SetupLogError(szBuf,LogSevInformation);
  22. #else
  23. OutputDebugString(DBGTITLE);
  24. OutputDebugString(szBuf);
  25. #endif
  26. va_end(arglist);
  27. }
  28. #endif
  29. BOOL
  30. ConcatenatePaths(
  31. LPTSTR Target,
  32. LPCTSTR Path,
  33. UINT TargetBufferSize
  34. )
  35. {
  36. UINT TargetLength,PathLength;
  37. BOOL TrailingBackslash,LeadingBackslash;
  38. UINT EndingLength;
  39. TargetLength = lstrlen(Target);
  40. PathLength = lstrlen(Path);
  41. //
  42. // See whether the target has a trailing backslash.
  43. //
  44. if(TargetLength && (Target[TargetLength-1] == TEXT('\\'))) {
  45. TrailingBackslash = TRUE;
  46. TargetLength--;
  47. } else {
  48. TrailingBackslash = FALSE;
  49. }
  50. //
  51. // See whether the path has a leading backshash.
  52. //
  53. if(Path[0] == TEXT('\\')) {
  54. LeadingBackslash = TRUE;
  55. PathLength--;
  56. } else {
  57. LeadingBackslash = FALSE;
  58. }
  59. //
  60. // Calculate the ending length, which is equal to the sum of
  61. // the length of the two strings modulo leading/trailing
  62. // backslashes, plus one path separator, plus a nul.
  63. //
  64. EndingLength = TargetLength + PathLength + 2;
  65. if(!LeadingBackslash && (TargetLength < TargetBufferSize)) {
  66. Target[TargetLength++] = TEXT('\\');
  67. }
  68. if(TargetBufferSize > TargetLength) {
  69. lstrcpyn(Target+TargetLength,Path,TargetBufferSize-TargetLength);
  70. }
  71. //
  72. // Make sure the buffer is nul terminated in all cases.
  73. //
  74. if (TargetBufferSize) {
  75. Target[TargetBufferSize-1] = 0;
  76. }
  77. return(EndingLength <= TargetBufferSize);
  78. }
  79. LPTSTR CheckSlash (LPTSTR lpDir)
  80. {
  81. DWORD dwStrLen;
  82. LPTSTR lpEnd;
  83. lpEnd = lpDir + lstrlen(lpDir);
  84. if (*(lpEnd - 1) != TEXT('\\')) {
  85. *lpEnd = TEXT('\\');
  86. lpEnd++;
  87. *lpEnd = TEXT('\0');
  88. }
  89. return lpEnd;
  90. }
  91. void IntToString( DWORD i, LPTSTR sz)
  92. {
  93. #define CCH_MAX_DEC 12 // Number of chars needed to hold 2^32
  94. TCHAR szTemp[CCH_MAX_DEC];
  95. int iChr;
  96. iChr = 0;
  97. do {
  98. szTemp[iChr++] = TEXT('0') + (TCHAR)(i % 10);
  99. i = i / 10;
  100. } while (i != 0);
  101. do {
  102. iChr--;
  103. *sz++ = szTemp[iChr];
  104. } while (iChr != 0);
  105. *sz++ = TEXT('\0');
  106. }
  107. BOOL DoInstallationFromSection(HINF hInf,LPCTSTR lpszSectionName)
  108. {
  109. HSPFILEQ FileQueue;
  110. PVOID QContext = NULL;
  111. BOOL bRet=FALSE;
  112. if(hInf == INVALID_HANDLE_VALUE) {
  113. DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] Open femgrate.inf failed !\n")));
  114. goto Err0;
  115. }
  116. if ((FileQueue = SetupOpenFileQueue()) == INVALID_HANDLE_VALUE) {
  117. DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupOpenFileQueue failed !\n")));
  118. goto Err0;
  119. }
  120. bRet = SetupInstallFilesFromInfSection(hInf,
  121. NULL,
  122. FileQueue,
  123. lpszSectionName,
  124. NULL,
  125. SP_COPY_NEWER );
  126. if (!bRet) {
  127. DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupInstallFilesFromInfSection failed !\n")));
  128. goto Err1;
  129. }
  130. if (!(QContext = SetupInitDefaultQueueCallback(NULL))) {
  131. bRet = FALSE;
  132. DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupInitDefaultQueueCallback failed !\n")));
  133. goto Err1;
  134. }
  135. bRet = SetupCommitFileQueue(NULL,
  136. FileQueue,
  137. SetupDefaultQueueCallback,
  138. QContext );
  139. if (!bRet) {
  140. DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupCommitFileQueue failed !\n")));
  141. goto Err1;
  142. }
  143. bRet = SetupInstallFromInfSection( NULL,
  144. hInf,
  145. lpszSectionName,
  146. SPINST_ALL & ~SPINST_FILES,
  147. NULL,
  148. NULL,
  149. 0,
  150. NULL,
  151. NULL,
  152. NULL,
  153. NULL );
  154. if (!bRet) {
  155. DebugMsg((DM_VERBOSE,TEXT("[DoInstallationFromSection] SetupInstallFromInfSection failed !\n")));
  156. goto Err1;
  157. }
  158. bRet = TRUE;
  159. Err1:
  160. if ( QContext != NULL)
  161. SetupTermDefaultQueueCallback(QContext);
  162. SetupCloseFileQueue(FileQueue);
  163. Err0:
  164. return bRet;
  165. }
  166. BOOL IsInSetupUpgradeMode()
  167. {
  168. LPCTSTR szKeyName = TEXT("SYSTEM\\Setup");
  169. DWORD dwType, dwSize;
  170. HKEY hKeySetup;
  171. DWORD dwSystemSetupInProgress,dwUpgradeInProcess;
  172. LONG lResult;
  173. if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, szKeyName, 0,
  174. KEY_READ, &hKeySetup) == ERROR_SUCCESS) {
  175. dwSize = sizeof(DWORD);
  176. lResult = RegQueryValueEx (hKeySetup, TEXT("SystemSetupInProgress"), NULL,
  177. &dwType, (LPBYTE) &dwSystemSetupInProgress, &dwSize);
  178. if (lResult == ERROR_SUCCESS) {
  179. dwSize = sizeof(DWORD);
  180. lResult = RegQueryValueEx (hKeySetup, TEXT("UpgradeInProgress"), NULL,
  181. &dwType, (LPBYTE) &dwUpgradeInProcess, &dwSize);
  182. if (lResult == ERROR_SUCCESS) {
  183. DebugMsg((DM_VERBOSE,TEXT("[IsInSetupUpgradeMode] dwSystemSetupInProgress =%, dwUpgradeInProcess=%d !\n"),dwSystemSetupInProgress,dwUpgradeInProcess));
  184. if ((dwSystemSetupInProgress != 0) && (dwUpgradeInProcess != 0)) {
  185. return TRUE;
  186. }
  187. }
  188. else {
  189. DebugMsg((DM_VERBOSE,TEXT("[IsInSetupUpgradeMode] RegQueryValueEx UpgradeInProcess failed !\n")));
  190. }
  191. }
  192. else {
  193. DebugMsg((DM_VERBOSE,TEXT("[IsInSetupUpgradeMode] RegQueryValueEx SystemSetupInProgress failed !\n")));
  194. }
  195. RegCloseKey (hKeySetup);
  196. }
  197. else {
  198. DebugMsg((DM_VERBOSE,TEXT("[IsInSetupUpgradeMode] RegOpenKeyEx failed !\n")));
  199. }
  200. return FALSE ;
  201. }
  202. UINT StrToUInt(
  203. LPTSTR lpszNum)
  204. {
  205. LPTSTR lpszStop;
  206. #ifdef UNICODE
  207. return (wcstoul(lpszNum, &lpszStop, 16));
  208. #else
  209. return (strtoul(lpszNum, &lpszStop, 16));
  210. #endif
  211. }
  212. UINT GetInstallLocale()
  213. {
  214. LONG dwErr;
  215. HKEY hkey;
  216. DWORD dwSize;
  217. TCHAR buffer[512];
  218. LANGID rcLang;
  219. UINT p;
  220. p = 0;
  221. dwErr = RegOpenKeyEx( HKEY_USERS,
  222. TEXT(".DEFAULT\\Control Panel\\International"),
  223. 0,
  224. KEY_READ,
  225. &hkey );
  226. if( dwErr == ERROR_SUCCESS ) {
  227. dwSize = sizeof(buffer);
  228. dwErr = RegQueryValueEx(hkey,
  229. TEXT("Locale"),
  230. NULL, //reserved
  231. NULL, //type
  232. (LPBYTE) buffer,
  233. &dwSize );
  234. if(dwErr == ERROR_SUCCESS) {
  235. p = StrToUInt(buffer);
  236. }
  237. }
  238. return( p );
  239. }
  240. BOOL RegReplaceIfExisting(
  241. HKEY hKey,
  242. LPCTSTR pszOldValName,
  243. LPCTSTR pszNewValName)
  244. /*++
  245. Rename old value name to new value name.
  246. --*/
  247. {
  248. LONG lResult;
  249. DWORD dwType;
  250. DWORD dwSize;
  251. TCHAR szData[MAX_PATH];
  252. dwSize = sizeof(szData);
  253. lResult = RegQueryValueEx (hKey,
  254. pszOldValName,
  255. 0,
  256. &dwType,
  257. (LPBYTE) szData,
  258. &dwSize);
  259. if (lResult != ERROR_SUCCESS) {
  260. DebugMsg((DM_VERBOSE,TEXT("RegReplaceIfExisting: RegQueryValue %s failed. \n"),pszOldValName));
  261. return FALSE;
  262. }
  263. lResult = RegSetValueEx (hKey,
  264. pszNewValName,
  265. 0,
  266. REG_SZ,
  267. (LPBYTE) szData,
  268. (lstrlen(szData) + 1) * sizeof(TCHAR));
  269. if (lResult != ERROR_SUCCESS) {
  270. DebugMsg((DM_VERBOSE,TEXT("RegReplaceIfExisting: RegSetValueEx %s failed. \n"),pszNewValName));
  271. return FALSE;
  272. }
  273. lResult = RegDeleteValue(hKey,
  274. pszOldValName);
  275. if (lResult != ERROR_SUCCESS) {
  276. DebugMsg((DM_VERBOSE,TEXT("RegReplaceIfExisting: RegDelValue %s failed. \n"),pszOldValName));
  277. return FALSE;
  278. }
  279. return TRUE;
  280. }
  281. BOOL ReplaceString(
  282. LPCTSTR lpszOldStr,
  283. LPCTSTR lpszReplaceStr,
  284. LPCTSTR lpszReplacedWithStr,
  285. LPTSTR lpszOutputStr)
  286. {
  287. LPTSTR pszAnchor = NULL;
  288. lstrcpy(lpszOutputStr,lpszOldStr);
  289. pszAnchor = _tcsstr(lpszOutputStr,lpszReplaceStr);
  290. if (!pszAnchor) {
  291. return FALSE;
  292. }
  293. if (lstrcmp(pszAnchor,lpszReplaceStr) != 0) {
  294. return FALSE;
  295. }
  296. lstrcpy(pszAnchor,lpszReplacedWithStr);
  297. return TRUE;
  298. }
  299. BOOL Delnode_Recurse (LPTSTR lpDir)
  300. {
  301. WIN32_FIND_DATA fd;
  302. HANDLE hFile;
  303. //
  304. // Verbose output
  305. //
  306. //DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Entering, lpDir = <%s>\n"), lpDir));
  307. //
  308. // Setup the current working dir
  309. //
  310. if (!SetCurrentDirectory (lpDir)) {
  311. //DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Failed to set current working directory. Error = %d\n"), GetLastError()));
  312. return FALSE;
  313. }
  314. //
  315. // Find the first file
  316. //
  317. hFile = FindFirstFile(c_szStarDotStar, &fd);
  318. if (hFile == INVALID_HANDLE_VALUE) {
  319. if (GetLastError() == ERROR_FILE_NOT_FOUND) {
  320. return TRUE;
  321. } else {
  322. //DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: FindFirstFile failed. Error = %d\n"),
  323. // GetLastError()));
  324. return FALSE;
  325. }
  326. }
  327. do {
  328. //
  329. // Verbose output
  330. //
  331. //DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: FindFile found: <%s>\n"),
  332. // fd.cFileName));
  333. //
  334. // Check for "." and ".."
  335. //
  336. if (!lstrcmpi(fd.cFileName, c_szDot)) {
  337. continue;
  338. }
  339. if (!lstrcmpi(fd.cFileName, c_szDotDot)) {
  340. continue;
  341. }
  342. if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  343. //
  344. // Found a directory.
  345. //
  346. if (!Delnode_Recurse(fd.cFileName)) {
  347. FindClose(hFile);
  348. return FALSE;
  349. }
  350. if (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
  351. fd.dwFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
  352. SetFileAttributes (fd.cFileName, fd.dwFileAttributes);
  353. }
  354. if (!RemoveDirectory (fd.cFileName)) {
  355. // DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Failed to delete directory <%s>. Error = %d\n"),
  356. // fd.cFileName, GetLastError()));
  357. } else {
  358. // DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Successfully delete directory <%s>.\n"),
  359. // fd.cFileName));
  360. }
  361. } else {
  362. //
  363. // We found a file. Set the file attributes,
  364. // and try to delete it.
  365. //
  366. if ((fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ||
  367. (fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) {
  368. SetFileAttributes (fd.cFileName, FILE_ATTRIBUTE_NORMAL);
  369. }
  370. if (!DeleteFile (fd.cFileName)) {
  371. // DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Failed to delete <%s>. Error = %d\n"),
  372. // fd.cFileName, GetLastError()));
  373. }
  374. else {
  375. // DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Successful delete <%s>.\n"),
  376. // fd.cFileName));
  377. }
  378. }
  379. //
  380. // Find the next entry
  381. //
  382. } while (FindNextFile(hFile, &fd));
  383. //
  384. // Close the search handle
  385. //
  386. FindClose(hFile);
  387. //
  388. // Reset the working directory
  389. //
  390. if (!SetCurrentDirectory (c_szDotDot)) {
  391. DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Failed to reset current working directory. Error = %d\n"), GetLastError()));
  392. return FALSE;
  393. }
  394. //
  395. // Success.
  396. //
  397. DebugMsg((DM_VERBOSE, TEXT("Delnode_Recurse: Leaving <%s>\n"), lpDir));
  398. return TRUE;
  399. }
  400. BOOL Delnode (LPTSTR lpDir)
  401. {
  402. TCHAR szCurWorkingDir[MAX_PATH];
  403. if (GetCurrentDirectory(MAX_PATH, szCurWorkingDir)) {
  404. Delnode_Recurse (lpDir);
  405. SetCurrentDirectory (szCurWorkingDir);
  406. if (!RemoveDirectory (lpDir)) {
  407. DebugMsg((DM_VERBOSE, TEXT("Delnode: Failed to delete directory <%s>. Error = %d\n"),
  408. lpDir, GetLastError()));
  409. return FALSE;
  410. }
  411. else {
  412. DebugMsg((DM_VERBOSE, TEXT("Delnode: RemoveDirectory OK <%s>.\n"),lpDir));
  413. }
  414. } else {
  415. DebugMsg((DM_VERBOSE, TEXT("Delnode: Failed to get current working directory. Error = %d\n"), GetLastError()));
  416. return FALSE;
  417. }
  418. return TRUE;
  419. }
  420. BOOL GetProgramsDirectory (BOOL bCommonGroup, LPTSTR lpDirectory)
  421. {
  422. LONG lResult;
  423. HKEY hKey;
  424. DWORD dwType, dwSize;
  425. TCHAR szDirectory[MAX_PATH];
  426. UINT uID;
  427. BOOL bRetVal = FALSE;
  428. //
  429. // Open the User Shell Folders in the registry
  430. //
  431. lResult = RegOpenKeyEx ((bCommonGroup ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER),
  432. USER_SHELL_FOLDER, 0, KEY_READ, &hKey);
  433. if (lResult != ERROR_SUCCESS) {
  434. goto Exit;
  435. }
  436. //
  437. // Now query for the programs directory
  438. //
  439. dwSize = MAX_PATH * sizeof(TCHAR);
  440. szDirectory[0] = TEXT('\0');
  441. if (bCommonGroup) {
  442. lResult = RegQueryValueEx (hKey, TEXT("Common Programs"),
  443. NULL, &dwType, (LPBYTE) szDirectory, &dwSize);
  444. } else {
  445. lResult = RegQueryValueEx (hKey, TEXT("Programs"),
  446. NULL, &dwType, (LPBYTE) szDirectory, &dwSize);
  447. }
  448. RegCloseKey(hKey);
  449. if (lResult != ERROR_SUCCESS) {
  450. goto Exit;
  451. }
  452. //
  453. // Did we find anything?
  454. //
  455. if (szDirectory[0] == TEXT('\0')) {
  456. goto Exit;
  457. }
  458. //
  459. // Save the result
  460. //
  461. if (ExpandEnvironmentStrings(szDirectory, lpDirectory, MAX_PATH)) {
  462. bRetVal = TRUE;
  463. }
  464. Exit:
  465. return bRetVal;
  466. }
  467. BOOL GetGenericUserFolderDirectory (LPCTSTR lpszFolder, LPTSTR lpDirectory)
  468. {
  469. LONG lResult;
  470. HKEY hKey;
  471. DWORD dwType, dwSize;
  472. TCHAR szDirectory[MAX_PATH];
  473. UINT uID;
  474. BOOL bRetVal = FALSE;
  475. //
  476. // Open the User Shell Folders in the registry
  477. //
  478. lResult = RegOpenKeyEx (HKEY_CURRENT_USER,
  479. USER_SHELL_FOLDER, 0, KEY_READ, &hKey);
  480. if (lResult != ERROR_SUCCESS) {
  481. goto Exit;
  482. }
  483. //
  484. // Now query for the programs directory
  485. //
  486. dwSize = MAX_PATH * sizeof(TCHAR);
  487. szDirectory[0] = TEXT('\0');
  488. lResult = RegQueryValueEx (hKey, lpszFolder,
  489. NULL, &dwType, (LPBYTE) szDirectory, &dwSize);
  490. RegCloseKey(hKey);
  491. if (lResult != ERROR_SUCCESS) {
  492. goto Exit;
  493. }
  494. //
  495. // Did we find anything?
  496. //
  497. if (szDirectory[0] == TEXT('\0')) {
  498. goto Exit;
  499. }
  500. //
  501. // Save the result
  502. //
  503. if (ExpandEnvironmentStrings(szDirectory, lpDirectory, MAX_PATH)) {
  504. bRetVal = TRUE;
  505. }
  506. Exit:
  507. return bRetVal;
  508. }
  509. STRING_TO_DATA InfRegSpecTohKey[] = {
  510. TEXT("HKEY_LOCAL_MACHINE"), (UINT)((UINT_PTR)HKEY_LOCAL_MACHINE),
  511. TEXT("HKLM") , (UINT)((UINT_PTR)HKEY_LOCAL_MACHINE),
  512. TEXT("HKEY_CLASSES_ROOT") , (UINT)((UINT_PTR)HKEY_CLASSES_ROOT),
  513. TEXT("HKCR") , (UINT)((UINT_PTR)HKEY_CLASSES_ROOT),
  514. TEXT("HKR") , (UINT)((UINT_PTR)NULL),
  515. TEXT("HKEY_CURRENT_USER") , (UINT)((UINT_PTR)HKEY_CURRENT_USER),
  516. TEXT("HKCU") , (UINT)((UINT_PTR)HKEY_CURRENT_USER),
  517. TEXT("HKEY_USERS") , (UINT)((UINT_PTR)HKEY_USERS),
  518. TEXT("HKU") , (UINT)((UINT_PTR)HKEY_USERS),
  519. TEXT("") , (UINT)((UINT_PTR)NULL)
  520. };
  521. BOOL
  522. LookUpStringInTable(
  523. IN PSTRING_TO_DATA Table,
  524. IN LPCTSTR String,
  525. OUT PUINT Data
  526. )
  527. {
  528. UINT i;
  529. for(i=0; Table[i].String; i++) {
  530. if(!lstrcmpi(Table[i].String,String)) {
  531. *Data = Table[i].Data;
  532. return(TRUE);
  533. }
  534. }
  535. return(FALSE);
  536. }
  537. BOOL INIFile_ChangeSectionName(
  538. LPCTSTR szIniFileName,
  539. LPCTSTR szIniOldSectionName,
  540. LPCTSTR szIniNewSectionName)
  541. {
  542. #define MAX_SIZE 0x7FFFF
  543. LPTSTR pBuf = NULL;
  544. BOOL bRetVal = FALSE;
  545. DWORD dwSizeofBuf;
  546. DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] Calling ,%s,%s,%s ! \n"),
  547. szIniFileName,szIniOldSectionName,szIniNewSectionName));
  548. //
  549. // allocate max size of buffer
  550. //
  551. pBuf = (LPTSTR) malloc(MAX_SIZE);
  552. if (! pBuf) {
  553. DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] memory allocate error ! \n")));
  554. goto Exit1;
  555. }
  556. dwSizeofBuf = GetPrivateProfileSection(
  557. szIniOldSectionName,
  558. pBuf,
  559. MAX_SIZE,
  560. szIniFileName);
  561. if (! dwSizeofBuf) {
  562. //
  563. // this section is not in INI file
  564. //
  565. // do nothing
  566. //
  567. DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] No %s section in %s ! \n"),szIniOldSectionName));
  568. bRetVal = TRUE;
  569. goto Exit2;
  570. }
  571. if (dwSizeofBuf == MAX_SIZE - 2) {
  572. //
  573. // buffer too small
  574. //
  575. bRetVal = FALSE;
  576. DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] memory not enough ! \n"),szIniOldSectionName,szIniFileName));
  577. goto Exit2;
  578. }
  579. bRetVal = WritePrivateProfileSection(
  580. szIniNewSectionName,
  581. pBuf,
  582. szIniFileName);
  583. if (! bRetVal) {
  584. //
  585. // write failure
  586. //
  587. DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] WritePrivateProfileSection ! \n")));
  588. goto Exit2;
  589. }
  590. WritePrivateProfileSection(
  591. szIniOldSectionName,
  592. NULL,
  593. szIniFileName);
  594. //
  595. // at this step, even old section is not deleted, it's still OK
  596. //
  597. bRetVal = TRUE;
  598. Exit2:
  599. if (pBuf) {
  600. free(pBuf);
  601. }
  602. Exit1:
  603. return bRetVal;
  604. }
  605. BOOL INIFile_ChangeKeyName(
  606. LPCTSTR szIniFileName,
  607. LPCTSTR szIniOldSectionName,
  608. LPCTSTR szIniOldKeyName,
  609. LPCTSTR szIniNewKeyName)
  610. {
  611. #define MAX_SIZE 0x7FFFF
  612. LPTSTR pBuf = NULL;
  613. BOOL bRetVal = FALSE;
  614. DWORD dwSizeofBuf;
  615. // DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeKeyName] Calling ,%s,%s,%s %s! \n"),
  616. // szIniFileName,szIniNewSectionName,szIniOldKeyName,szIniNewKeyName));
  617. //
  618. // allocate max size of buffer
  619. //
  620. pBuf = (LPTSTR) malloc(MAX_SIZE);
  621. if (! pBuf) {
  622. // DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] memory allocate error ! \n")));
  623. goto Exit1;
  624. }
  625. dwSizeofBuf = GetPrivateProfileString(
  626. szIniOldSectionName,
  627. szIniOldKeyName,
  628. TEXT(""),
  629. pBuf,
  630. MAX_SIZE,
  631. szIniFileName);
  632. if (! dwSizeofBuf) {
  633. //
  634. // this section is not in INI file
  635. //
  636. // do nothing
  637. //
  638. // DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] No %s section in %s ! \n"),));
  639. bRetVal = TRUE;
  640. goto Exit2;
  641. }
  642. if (dwSizeofBuf == MAX_SIZE - 1) {
  643. //
  644. // buffer too small
  645. //
  646. bRetVal = FALSE;
  647. // DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] memory not enough ! \n"),szIniOldSectionName,szIniFileName));
  648. goto Exit2;
  649. }
  650. bRetVal = WritePrivateProfileString(
  651. szIniOldSectionName,
  652. szIniNewKeyName,
  653. pBuf,
  654. szIniFileName);
  655. if (! bRetVal) {
  656. //
  657. // write failure
  658. //
  659. // DebugMsg((DM_VERBOSE,TEXT("[INIFile_ChangeSectionName] WritePrivateProfileSection ! \n")));
  660. goto Exit2;
  661. }
  662. WritePrivateProfileString(
  663. szIniOldSectionName,
  664. szIniOldKeyName,
  665. NULL,
  666. szIniFileName);
  667. //
  668. // at this step, even old section is not deleted, it's still OK
  669. //
  670. bRetVal = TRUE;
  671. Exit2:
  672. if (pBuf) {
  673. free(pBuf);
  674. }
  675. Exit1:
  676. return bRetVal;
  677. }
  678. UINT CreateNestedDirectory(LPCTSTR lpDirectory, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
  679. {
  680. TCHAR szDirectory[2*MAX_PATH];
  681. LPTSTR lpEnd;
  682. //
  683. // Check for NULL pointer
  684. //
  685. if (!lpDirectory || !(*lpDirectory)) {
  686. return 0;
  687. }
  688. //
  689. // First, see if we can create the directory without having
  690. // to build parent directories.
  691. //
  692. if (CreateDirectory (lpDirectory, lpSecurityAttributes)) {
  693. return 1;
  694. }
  695. //
  696. // If this directory exists already, this is OK too.
  697. //
  698. if (GetLastError() == ERROR_ALREADY_EXISTS) {
  699. return ERROR_ALREADY_EXISTS;
  700. }
  701. //
  702. // No luck, copy the string to a buffer we can munge
  703. //
  704. lstrcpy (szDirectory, lpDirectory);
  705. //
  706. // Find the first subdirectory name
  707. //
  708. lpEnd = szDirectory;
  709. if (szDirectory[1] == TEXT(':')) {
  710. lpEnd += 3;
  711. } else if (szDirectory[1] == TEXT('\\')) {
  712. lpEnd += 2;
  713. while (*lpEnd && *lpEnd != TEXT('\\')) {
  714. lpEnd++;
  715. }
  716. if (!(*lpEnd)) {
  717. return 0;
  718. }
  719. lpEnd++;
  720. while (*lpEnd && *lpEnd != TEXT('\\')) {
  721. lpEnd++;
  722. }
  723. if (!(*lpEnd)) {
  724. return 0;
  725. }
  726. lpEnd++;
  727. } else if (szDirectory[0] == TEXT('\\')) {
  728. lpEnd++;
  729. }
  730. while (*lpEnd) {
  731. while (*lpEnd && *lpEnd != TEXT('\\')) {
  732. lpEnd++;
  733. }
  734. if (*lpEnd == TEXT('\\')) {
  735. *lpEnd = TEXT('\0');
  736. if (!CreateDirectory (szDirectory, NULL)) {
  737. if (GetLastError() != ERROR_ALREADY_EXISTS) {
  738. DebugMsg((DM_VERBOSE, TEXT("CreateNestedDirectory: CreateDirectory failed with %d."), GetLastError()));
  739. return 0;
  740. }
  741. }
  742. *lpEnd = TEXT('\\');
  743. lpEnd++;
  744. }
  745. }
  746. if (CreateDirectory (szDirectory, lpSecurityAttributes)) {
  747. return 1;
  748. }
  749. if (GetLastError() == ERROR_ALREADY_EXISTS) {
  750. return ERROR_ALREADY_EXISTS;
  751. }
  752. DebugMsg((DM_VERBOSE, TEXT("CreateNestedDirectory: Failed to create the directory with error %d."), GetLastError()));
  753. return 0;
  754. }
  755. BOOL (* MYSHGetSpecialFolderPathW) (HWND , LPTSTR , int , BOOL );
  756. BOOL GetApplicationFolderPath(LPTSTR lpszFolder,UINT nLen)
  757. {
  758. HINSTANCE hDll;
  759. BOOL bGotPath = FALSE;
  760. hDll = LoadLibrary(TEXT("shell32.dll"));
  761. if (hDll) {
  762. (FARPROC) MYSHGetSpecialFolderPathW = GetProcAddress(hDll,"SHGetSpecialFolderPathW");
  763. if (MYSHGetSpecialFolderPathW) {
  764. if (MYSHGetSpecialFolderPathW(NULL, lpszFolder, CSIDL_APPDATA , FALSE)){
  765. DebugMsg((DM_VERBOSE,TEXT("[GetApplicationFolder] SHGetSpecialFolderPath %s !\n"),lpszFolder));
  766. bGotPath = TRUE;
  767. } else {
  768. DebugMsg((DM_VERBOSE,TEXT("[GetApplicationFolder] SHGetSpecialFolderPath failed !\n")));
  769. }
  770. } else {
  771. DebugMsg((DM_VERBOSE,TEXT("[GetApplicationFolder] GetProc of SHGetSpecialFolderPath failed !\n")));
  772. }
  773. FreeLibrary(hDll);
  774. } else {
  775. DebugMsg((DM_VERBOSE,TEXT("[GetApplicationFolder] Load shell32.dll failed ! %d\n"),GetLastError()));
  776. }
  777. if (! bGotPath) {
  778. ExpandEnvironmentStrings(TEXT("%userprofile%"),lpszFolder,nLen);
  779. lstrcat(lpszFolder,TEXT("\\Application data"));
  780. }
  781. return TRUE;
  782. }
  783. BOOL GetNewPath(
  784. LPTSTR lpszNewPath,
  785. LPCTSTR lpszFileName,
  786. LPCTSTR lpszClass)
  787. {
  788. BOOL bRet = FALSE;
  789. LPTSTR lpszBaseName;
  790. GetApplicationFolderPath(lpszNewPath,MAX_PATH);
  791. ConcatenatePaths(lpszNewPath, lpszClass,MAX_PATH);
  792. if (! CreateNestedDirectory(lpszNewPath,NULL)) {
  793. DebugMsg((DM_VERBOSE,TEXT("[GetNewPath] CreateDirectory %s ! %X\n"),lpszNewPath,GetLastError()));
  794. }
  795. if ((lpszBaseName = _tcsrchr(lpszFileName,TEXT('\\'))) != NULL) {
  796. ConcatenatePaths(lpszNewPath,lpszBaseName,MAX_PATH);
  797. } else {
  798. ConcatenatePaths(lpszNewPath,lpszFileName,MAX_PATH);
  799. DebugMsg((DM_VERBOSE,TEXT("[GetNewPath] can't find \\ in %s !\n"),lpszFileName));
  800. }
  801. DebugMsg((DM_VERBOSE,TEXT("[GetNewPath] return %s !\n"),lpszNewPath));
  802. bRet = TRUE;
  803. return bRet;
  804. }
  805. BOOL MovePerUserIMEData(
  806. HKEY hCurrentKey,
  807. LPCTSTR szRegPath,
  808. LPCTSTR szRegVal,
  809. LPCTSTR szUserClass,
  810. LPCTSTR szIMEName,
  811. BOOL bCHT)
  812. {
  813. HKEY hKey;
  814. DWORD dwErr,dwSize,dwType;
  815. BOOL bRet;
  816. TCHAR szPath[MAX_PATH],szNewPath[MAX_PATH];
  817. bRet = FALSE;
  818. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] szRegPath = %s !\n"),szRegPath));
  819. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] szRegVal = %s !\n"),szRegVal));
  820. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] szUserClass = %s !\n"),szUserClass));
  821. dwErr = RegOpenKeyEx( hCurrentKey,
  822. szRegPath,
  823. 0,
  824. KEY_READ | KEY_WRITE,
  825. &hKey );
  826. if (dwErr != ERROR_SUCCESS) {
  827. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Open key failed %X!\n"),GetLastError()));
  828. bRet = TRUE;
  829. goto Exit1;
  830. }
  831. dwSize = sizeof(szPath);
  832. dwErr = RegQueryValueEx(hKey,
  833. szRegVal,
  834. NULL,
  835. &dwType,
  836. (LPBYTE) szPath,
  837. &dwSize);
  838. if (dwErr != ERROR_SUCCESS) {
  839. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Value %s doesn't exist !\n"),szRegVal));
  840. bRet = TRUE;
  841. goto Exit2;
  842. }
  843. if (bCHT) {
  844. if (GetFileAttributes(szPath) == 0xFFFFFFFF) {
  845. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] File %s doesn't exist !\n"),szPath));
  846. goto Exit2;
  847. }
  848. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] File %s existing !\n"),szPath));
  849. if (! GetNewPath(szNewPath,szPath,szUserClass)) {
  850. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Get new path name failed !\n")));
  851. goto Exit2;
  852. }
  853. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Get new path name OK,%s !\n"),szNewPath));
  854. if (! CopyFile(szPath,szNewPath,FALSE)) {
  855. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Copy %s to %s failed ! %d\n"),szPath,szNewPath,GetLastError()));
  856. goto Exit2;
  857. }
  858. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Copy %s to %s OK !\n"),szPath,szNewPath));
  859. } else { // in CHS case
  860. lstrcpy(szPath,szIMEName);
  861. lstrcat(szPath,TEXT(".emb"));
  862. if (! GetNewPath(szNewPath,szPath,szUserClass)) {
  863. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Get new path name failed !\n")));
  864. goto Exit2;
  865. }
  866. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Get new path name OK,%s !\n"),szNewPath));
  867. }
  868. #if 1
  869. dwErr = RegSetValueEx(hKey,
  870. szRegVal,
  871. 0,
  872. REG_SZ,
  873. (LPBYTE) szNewPath,
  874. (lstrlen(szNewPath)+1) * sizeof(TCHAR));
  875. if (dwErr != ERROR_SUCCESS) {
  876. DebugMsg((DM_VERBOSE,TEXT("[MovePerUserIMEData] Set Value %s = %s failed !\n"),szRegVal,szNewPath));
  877. goto Exit2;
  878. }
  879. #endif
  880. bRet = TRUE;
  881. Exit2:
  882. RegCloseKey(hKey);
  883. Exit1:
  884. return bRet;
  885. }
  886. BOOL CreateSecurityDirectory(
  887. LPCTSTR pszOldDir,
  888. LPCTSTR pszNewDir)
  889. {
  890. DWORD dwLength,dwLengthNeeded;
  891. PSECURITY_DESCRIPTOR pSD;
  892. BOOL bRet = FALSE;
  893. if (CreateNestedDirectory(pszNewDir,NULL)) {
  894. //
  895. // Copy the ACLs from the old location to the new
  896. //
  897. dwLength = 1024;
  898. pSD = (PSECURITY_DESCRIPTOR)LocalAlloc (LPTR, dwLength);
  899. if (pSD) {
  900. if (GetFileSecurity (pszOldDir,
  901. DACL_SECURITY_INFORMATION,
  902. pSD, dwLength, &dwLengthNeeded)) {
  903. SetFileSecurity (pszNewDir,
  904. DACL_SECURITY_INFORMATION, pSD);
  905. bRet = TRUE;
  906. } else {
  907. DebugMsg((DM_VERBOSE, TEXT("CreateSecurityDirectory: Failed to allocate get security descriptor with %d. dwLengthNeeded = %d"),
  908. GetLastError(), dwLengthNeeded));
  909. }
  910. LocalFree (pSD);
  911. } else {
  912. DebugMsg((DM_VERBOSE, TEXT("CreateSecurityDirectory: Failed to allocate memory for SD with %d."),
  913. GetLastError()));
  914. }
  915. } else {
  916. DebugMsg((DM_VERBOSE,TEXT("CreateSecurityDirectory %s ! %X\n"),pszNewDir,GetLastError()));
  917. }
  918. return bRet;
  919. }
  920. BOOL IsDirExisting(
  921. LPTSTR Dir)
  922. {
  923. LONG lResult = GetFileAttributes(Dir);
  924. DebugMsg((DM_VERBOSE, TEXT("[IsDirExisting] %s lResult:%X\n"),Dir,lResult));
  925. if ((lResult == 0xFFFFFFFF) ||
  926. (!(lResult & FILE_ATTRIBUTE_DIRECTORY))) {
  927. return FALSE;
  928. } else {
  929. return TRUE;
  930. }
  931. }
  932. BOOL IsFileExisting(
  933. LPTSTR File)
  934. {
  935. LONG lResult = GetFileAttributes(File);
  936. DebugMsg((DM_VERBOSE, TEXT("[IsFileExisting] %s lResult:%X\n"),File,lResult));
  937. if ((lResult == 0xFFFFFFFF) ||
  938. ((lResult & FILE_ATTRIBUTE_DIRECTORY))) {
  939. return FALSE;
  940. } else {
  941. return TRUE;
  942. }
  943. }
  944. BOOL RenameDirectory(
  945. LPTSTR OldDir,
  946. LPTSTR NewDir)
  947. {
  948. BOOL bRet=TRUE;
  949. if (!IsDirExisting(OldDir)) {
  950. return FALSE;
  951. }
  952. if (IsDirExisting(NewDir)) {
  953. //
  954. // iF Target directory is already created, then copy files from source to dest dir
  955. //
  956. if (CopyProfileDirectory (OldDir, NewDir, CPD_IGNOREHIVE)) {
  957. DebugMsg((DM_VERBOSE, TEXT("[RenameDirectory] Successfully CopyProfileDirectory \nFrom:%s\nTo :%s\n"),OldDir, NewDir));
  958. if (Delnode (OldDir)) {
  959. DebugMsg((DM_VERBOSE, TEXT("[RenameDirectory] Successfully removed folder:%s\n"),OldDir));
  960. }
  961. else {
  962. DebugMsg((DM_VERBOSE, TEXT("[RenameDirectory] Failed remove folder:\n%s\n"),OldDir));
  963. }
  964. } else {
  965. bRet = FALSE;
  966. DebugMsg((DM_VERBOSE, TEXT("RenameDirectory: Failed to change folder name:\n%s\n%s"),OldDir, NewDir));
  967. }
  968. } else {
  969. //
  970. // iF Target has not been created, then just move source dir to dest dir
  971. //
  972. if (MoveFile(OldDir, NewDir)) {
  973. DebugMsg((DM_VERBOSE, TEXT("[RenameDirectory] Move %s to %s OK !\n"),OldDir, NewDir));
  974. } else {
  975. bRet = FALSE;
  976. DebugMsg((DM_VERBOSE, TEXT("[RenameDirectory] Failed to change folder name:\n%s\n%s\n"),OldDir, NewDir));
  977. }
  978. }
  979. return TRUE;
  980. }
  981. BOOL RenameFile(
  982. LPTSTR OldFile,
  983. LPTSTR NewFile)
  984. {
  985. BOOL bRet=TRUE;
  986. if (!IsFileExisting(OldFile)) {
  987. return FALSE;
  988. }
  989. if (IsFileExisting(NewFile)) {
  990. if (DeleteFile (OldFile)) {
  991. DebugMsg((DM_VERBOSE, TEXT("[RenameFile] Successfully delete %s\n"),OldFile));
  992. } else {
  993. bRet = FALSE;
  994. DebugMsg((DM_VERBOSE, TEXT("[RenameFile] Failed to delete file %s\n"),OldFile));
  995. }
  996. } else {
  997. //
  998. // iF Target has not been created, then just move source dir to dest dir
  999. //
  1000. if (MoveFile(OldFile, NewFile)) {
  1001. DebugMsg((DM_VERBOSE, TEXT("[RenameFile] Move %s to %s OK !\n"),OldFile, NewFile));
  1002. } else {
  1003. bRet = FALSE;
  1004. DebugMsg((DM_VERBOSE, TEXT("[RenameFile] Failed to change File name:%s to %s\n"),OldFile, NewFile));
  1005. }
  1006. }
  1007. return bRet;
  1008. }
  1009. BOOL RenameSectionFiles(
  1010. HINF hInf,
  1011. LPCTSTR SectionName,
  1012. LPCTSTR SourceDirectory,
  1013. LPCTSTR TargetDirectory)
  1014. {
  1015. LONG LineCount,LineNo;
  1016. INFCONTEXT InfContext;
  1017. LPCTSTR pszSrcFile,pszDstFile;
  1018. TCHAR szMediaPath[MAX_PATH];
  1019. if(hInf == INVALID_HANDLE_VALUE) {
  1020. DebugMsg((DM_VERBOSE,TEXT("[RenameSectionFiles] Open femgrate.inf failed !\n")));
  1021. return FALSE;
  1022. }
  1023. LineCount = (UINT)SetupGetLineCount(hInf,SectionName);
  1024. if((LONG)LineCount <= 0) {
  1025. DebugMsg((DM_VERBOSE,TEXT("[RenameSectionFiles] line count == 0 !\n")));
  1026. return FALSE;
  1027. }
  1028. for(LineNo=0; LineNo<LineCount; LineNo++) {
  1029. if ( SetupGetLineByIndex(hInf,SectionName,LineNo,&InfContext)
  1030. && (pszSrcFile = pSetupGetField(&InfContext,1))
  1031. && (pszDstFile = pSetupGetField(&InfContext,2))
  1032. ) {
  1033. TCHAR SourceFile[MAX_PATH];
  1034. TCHAR TargetFile[MAX_PATH];
  1035. lstrcpy(SourceFile,SourceDirectory);
  1036. lstrcpy(TargetFile,TargetDirectory);
  1037. ConcatenatePaths(SourceFile,pszSrcFile,MAX_PATH);
  1038. ConcatenatePaths(TargetFile,pszDstFile,MAX_PATH);
  1039. if (RenameFile(SourceFile, TargetFile)) {
  1040. DebugMsg((DM_VERBOSE, TEXT("[RenameSectionFiles] Rename %s to %s OK !\n"),SourceFile, TargetFile));
  1041. } else {
  1042. DebugMsg((DM_VERBOSE, TEXT("[RenameSectionFiles] Rename %s to %s Failed !\n"),SourceFile, TargetFile));
  1043. }
  1044. }
  1045. }
  1046. return TRUE;
  1047. }
  1048. BOOL RenameSectionRegSZ(
  1049. HINF hInf,
  1050. LPCTSTR SectionName,
  1051. HKEY hRootKey,
  1052. LPCTSTR RegPath)
  1053. {
  1054. LONG LineCount,LineNo;
  1055. INFCONTEXT InfContext;
  1056. LPCTSTR pszSrc,pszDst;
  1057. TCHAR szMediaPath[MAX_PATH];
  1058. HKEY hKey;
  1059. DWORD dwErr;
  1060. DWORD dwType;
  1061. DWORD dwSize;
  1062. if(hInf == INVALID_HANDLE_VALUE) {
  1063. DebugMsg((DM_VERBOSE,TEXT("[RenameSectionRegSZ] Open femgrate.inf failed !\n")));
  1064. return FALSE;
  1065. }
  1066. LineCount = (UINT)SetupGetLineCount(hInf,SectionName);
  1067. if((LONG)LineCount <= 0) {
  1068. DebugMsg((DM_VERBOSE,TEXT("[RenameSectionRegSZ] line count == 0 !\n")));
  1069. return FALSE;
  1070. }
  1071. dwErr = RegOpenKeyEx( hRootKey,
  1072. RegPath,
  1073. 0,
  1074. KEY_READ | KEY_WRITE,
  1075. &hKey );
  1076. if (dwErr != ERROR_SUCCESS) {
  1077. DebugMsg((DM_VERBOSE,TEXT("[RenameSectionRegSZ] Failed RegOpenKeyEx !\n")));
  1078. return FALSE;
  1079. }
  1080. for(LineNo=0; LineNo<LineCount; LineNo++) {
  1081. if ( SetupGetLineByIndex(hInf,SectionName,LineNo,&InfContext)
  1082. && (pszSrc = pSetupGetField(&InfContext,1))
  1083. && (pszDst = pSetupGetField(&InfContext,2))
  1084. ) {
  1085. BYTE Data[5000];
  1086. dwSize = sizeof(Data);
  1087. dwErr = RegQueryValueEx(hKey,
  1088. pszSrc,
  1089. NULL,
  1090. &dwType,
  1091. (LPBYTE) Data,
  1092. &dwSize);
  1093. if (dwErr != ERROR_SUCCESS) {
  1094. DebugMsg((DM_VERBOSE,TEXT("[RenameSectionRegSZ] Failed RegQueryValueEx %s [%X] !\n"), pszSrc,dwErr));
  1095. continue;
  1096. }
  1097. dwErr = RegSetValueEx(hKey,
  1098. pszDst,
  1099. 0,
  1100. dwType,
  1101. (LPBYTE) Data,
  1102. dwSize);
  1103. if (dwErr != ERROR_SUCCESS) {
  1104. DebugMsg((DM_VERBOSE,TEXT("[RenameSectionRegSZ] Failed RegSetValueEx %s [%X] !\n"), pszDst,dwErr));
  1105. continue;
  1106. }
  1107. dwErr = RegDeleteValue(hKey,pszSrc);
  1108. if (dwErr != ERROR_SUCCESS) {
  1109. DebugMsg((DM_VERBOSE,TEXT("[RenameSectionRegSZ] Failed RegDeleteValue %s [%X] !\n"), pszSrc,dwErr));
  1110. continue;
  1111. }
  1112. }
  1113. }
  1114. RegCloseKey(hKey);
  1115. return TRUE;
  1116. }