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.

579 lines
17 KiB

  1. // General app walking helper routines to be used in 9xapwlk.cpp and ntappwlk.cpp
  2. #include "globals.h"
  3. #include <objidl.h>
  4. CLASS_GeneralAppWalk::CLASS_GeneralAppWalk(kLogFile *Proc, HWND hIn)
  5. {
  6. LogProc=Proc;
  7. gHandleToMainWindow=hIn;
  8. }
  9. BOOL CLASS_GeneralAppWalk::OpenRegistry(void)
  10. {
  11. DWORD Return;
  12. lstrcpy(RootKeyString, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"));
  13. Return=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  14. RootKeyString,
  15. 0,
  16. KEY_READ,
  17. &HandleToUninstallKeyRoot);
  18. if (Return==ERROR_SUCCESS)
  19. {
  20. return TRUE;
  21. }
  22. else
  23. {
  24. return FALSE;
  25. }
  26. return TRUE;
  27. }
  28. BOOL CLASS_GeneralAppWalk::Walk(void)
  29. {
  30. if (OpenRegistry())
  31. {
  32. CurrentKey=0;
  33. LogProc->LogString(",#Uninstall_APPS,,\r\n");
  34. while ( TRUE == NextKey() );
  35. RegCloseKey(HandleToUninstallKeyRoot);
  36. }
  37. return WalkStartMenu();
  38. }
  39. BOOL CLASS_GeneralAppWalk::NextKey(void) {
  40. PTCHAR KeyName = NULL;
  41. DWORD SizeOfName = MAX_PATH * 4;
  42. if(!GetCurrentWinDir())
  43. return FALSE;
  44. KeyName = (PTCHAR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PATH * 4);
  45. if(!KeyName)
  46. return FALSE;
  47. if (ERROR_SUCCESS != RegEnumKeyEx(HandleToUninstallKeyRoot, CurrentKey, KeyName, &SizeOfName, NULL, NULL, NULL, NULL)) {
  48. HeapFree(GetProcessHeap(), NULL, KeyName);
  49. return FALSE;
  50. }
  51. CurrentKey++;
  52. GetUninstallValues(KeyName);
  53. HeapFree(GetProcessHeap(), NULL, KeyName);
  54. return TRUE;
  55. }
  56. BOOL CLASS_GeneralAppWalk::GetUninstallValues(TCHAR *KeyName)
  57. {
  58. HKEY UninstallKey;
  59. char FullKey[1024];
  60. PUCHAR ProductName=(PUCHAR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024*sizeof(TCHAR));
  61. DWORD ProductSize=1024;
  62. DWORD Return=0;
  63. DWORD Type=REG_SZ;
  64. lstrcpy(FullKey, RootKeyString);
  65. lstrcat(FullKey, "\\");
  66. lstrcat(FullKey, KeyName);
  67. Return=RegOpenKeyEx(HKEY_LOCAL_MACHINE, FullKey, 0, KEY_READ, &UninstallKey);
  68. if (ERROR_SUCCESS == Return)
  69. {
  70. Return = RegQueryValueEx(UninstallKey, "DisplayName", NULL, &Type,
  71. ProductName, &ProductSize);
  72. if (ERROR_SUCCESS == Return)
  73. {
  74. LogProc->StripCommas((TCHAR*)ProductName);
  75. // printf("Product = %s\r\n", ProductName);
  76. LogProc->LogString(",%s,\r\n", ProductName);
  77. HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ProductName);
  78. RegCloseKey(UninstallKey);
  79. return TRUE;
  80. }
  81. else
  82. {
  83. // printf("Product = %s\r\n", szName);
  84. LogProc->StripCommas((TCHAR*)KeyName);
  85. LogProc->LogString(",%s,\r\n", KeyName);
  86. HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ProductName);
  87. RegCloseKey(UninstallKey);
  88. return TRUE;
  89. //Check for other ways to get product name
  90. }
  91. }
  92. else
  93. {
  94. HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ProductName);
  95. RegCloseKey(UninstallKey);
  96. return FALSE;
  97. }
  98. HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ProductName);
  99. RegCloseKey(UninstallKey);
  100. return FALSE;
  101. }
  102. BOOL CLASS_GeneralAppWalk::WalkStartMenu(void)
  103. {
  104. LogProc->LogString(",#StartMenu_APPS,,\r\n");
  105. PTCHAR Windir = NULL;
  106. UINT Size = 512;
  107. if(!GetCurrentWinDir())
  108. return FALSE;
  109. Windir = (PTCHAR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PATH * 4);
  110. if(!Windir)
  111. return FALSE;
  112. wsprintf(Windir, "%s\\Start Menu", g_WindowsDirectory);
  113. StartMenuLen = (UINT)lstrlen(Windir);
  114. WalkDir(Windir, NULL);
  115. wsprintf(Windir, "%s\\profiles", g_WindowsDirectory);
  116. StartMenuLen = (UINT)lstrlen(Windir);
  117. WalkDir(Windir, NULL);
  118. wsprintf(Windir, "%s\\Documents and Settings", g_WindowsDirectory);
  119. StartMenuLen = (UINT)lstrlen(Windir);
  120. WalkDir(Windir, NULL);
  121. lstrcpy(Windir, g_WindowsDirectory);
  122. Windir[2]='\0';
  123. lstrcat(Windir, "\\Documents and Settings");
  124. StartMenuLen = (UINT)lstrlen(Windir);
  125. WalkDir(Windir, NULL);
  126. /*
  127. if (S_OK == SHGetFolderPath(NULL, CSIDL_STARTMENU, NULL, SHGFP_TYPE_CURRENT, Windir)) {
  128. StartMenuLen = lstrlen(Windir);
  129. WalkDir(Windir, NULL);
  130. }
  131. if (S_OK == SHGetFolderPath(NULL, CSIDL_COMMON_STARTMENU,NULL, SHGFP_TYPE_CURRENT, Windir)) {
  132. StartMenuLen = lstrlen(Windir);
  133. WalkDir(Windir, NULL);
  134. }
  135. */
  136. HeapFree(GetProcessHeap(), NULL, Windir);
  137. return TRUE;
  138. }
  139. BOOL CLASS_GeneralAppWalk::WalkDir(TCHAR *TempPath, TCHAR *File)
  140. {
  141. WORD PathLen;
  142. PTCHAR Path = NULL;
  143. HANDLE HandleToSearch;
  144. WIN32_FIND_DATA FindFile;
  145. TCHAR CurrentDirectory[MAX_PATH];
  146. Path = (PTCHAR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PATH *4);
  147. if(!Path)
  148. return FALSE;
  149. SetErrorMode (SEM_FAILCRITICALERRORS);
  150. lstrcpy(Path, TempPath);
  151. PathLen = (UINT)lstrlen(Path);
  152. Path = Path + PathLen - 1;
  153. if (Path[0] != '\\')
  154. lstrcat(Path, "\\");
  155. Path = Path - PathLen + 1;
  156. if (File)
  157. lstrcat(Path, File);
  158. if (SetCurrentDirectory(Path))
  159. {
  160. GetCurrentDirectory(MAX_PATH, CurrentDirectory);
  161. HandleToSearch = FindFirstFile("*.*", &FindFile);
  162. if (lstrcmp(FindFile.cFileName,".") && lstrcmp(FindFile.cFileName,".."))
  163. {
  164. if ( FILE_ATTRIBUTE_DIRECTORY == (FindFile.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
  165. {
  166. WalkDir(Path, FindFile.cFileName);
  167. }
  168. else
  169. {
  170. TCHAR *cT1 = (TCHAR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024*sizeof(TCHAR));
  171. TCHAR *cT2 = (TCHAR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024*sizeof(TCHAR));
  172. lstrcpy(cT2, Path);
  173. if (cT2[lstrlen(cT2)-1] != '\\')
  174. lstrcat(cT2, "\\");
  175. lstrcat(cT2, FindFile.cFileName);
  176. if (EndsInLnk(cT2))
  177. ResolveIt(cT2, cT1);
  178. HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, cT1);
  179. HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, cT2);
  180. }
  181. }
  182. while (FindNextFile(HandleToSearch, &FindFile))
  183. {
  184. if (lstrcmp(FindFile.cFileName,".") && lstrcmp(FindFile.cFileName,".."))
  185. {
  186. if(FILE_ATTRIBUTE_DIRECTORY == (FindFile.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
  187. {
  188. PathLen = (UINT)lstrlen(Path);
  189. Path = Path + PathLen - 1;
  190. if (Path[0] != '\\')
  191. lstrcat(Path, "\\");
  192. Path = Path - PathLen + 1;
  193. WalkDir(Path, FindFile.cFileName);
  194. }
  195. else
  196. {
  197. TCHAR *cT1 = (TCHAR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024*sizeof(TCHAR));
  198. TCHAR *cT2 = (TCHAR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024*sizeof(TCHAR));
  199. lstrcpy(cT2, Path);
  200. if (cT2[lstrlen(cT2)-1] != '\\')
  201. lstrcat(cT2, "\\");
  202. lstrcat(cT2, FindFile.cFileName);
  203. if (EndsInLnk(cT2))
  204. {
  205. ResolveIt(cT2, cT1);
  206. }
  207. HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, cT1);
  208. HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, cT2);
  209. }
  210. }
  211. }
  212. FindClose(HandleToSearch);
  213. }
  214. HeapFree(GetProcessHeap(), NULL, Path);
  215. return TRUE;
  216. }
  217. BOOL CLASS_GeneralAppWalk::EndsInLnk(TCHAR *File)
  218. {
  219. TCHAR szTO[1024];
  220. lstrcpy(szTO, File);
  221. if ( (szTO[lstrlen(szTO)-4] == '.') &&
  222. ((szTO[lstrlen(szTO)-3] == 'l') || (szTO[lstrlen(szTO)-3] == 'L')) &&
  223. ((szTO[lstrlen(szTO)-2] == 'n') || (szTO[lstrlen(szTO)-2] == 'N')) &&
  224. ((szTO[lstrlen(szTO)-1] == 'k') || (szTO[lstrlen(szTO)-1] == 'K')) )
  225. {
  226. return TRUE;
  227. }
  228. else return FALSE;
  229. }
  230. HRESULT CLASS_GeneralAppWalk::ResolveIt(LPCSTR LinkFile, LPSTR Path)
  231. {
  232. HRESULT HandleToResult;
  233. IShellLink *ShellLink;
  234. WIN32_FIND_DATA wfd;
  235. UINT uiPrevErrorMode = 0;
  236. #ifdef MAXDEBUG
  237. LogProc->LogString("Working on %s:\r\n", lpszLinkFile);
  238. #endif
  239. *Path = '\0';
  240. HandleToResult = CoInitialize(NULL);
  241. HandleToResult = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
  242. IID_IShellLink, (LPVOID *)&ShellLink );
  243. if (SUCCEEDED(HandleToResult))
  244. {
  245. IPersistFile *ppf;
  246. HandleToResult = ShellLink->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf );
  247. if (SUCCEEDED(HandleToResult))
  248. {
  249. WCHAR wsz[MAX_PATH];
  250. MultiByteToWideChar( CP_ACP, 0, LinkFile, -1, wsz, MAX_PATH ); // Load the file.
  251. HandleToResult = ppf->Load(wsz, STGM_READ );
  252. if (SUCCEEDED(HandleToResult))
  253. {
  254. // HandleToResult = ShellLink->Resolve(g_MainWindow, SLR_ANY_MATCH | SLR_NO_UI);
  255. // if (SUCCEEDED(HandleToResult))
  256. // {
  257. HandleToResult = ShellLink->GetPath(Path, 1024, &wfd, SLGP_SHORTPATH );
  258. // HandleToResult = ShellLink->GetDescription(Path, 1024);
  259. WORD wLen=(UINT)lstrlen(Path);
  260. Path += wLen - 4;
  261. TCHAR szExt[10];
  262. lstrcpy (szExt, Path);
  263. if ( (szExt[0] == '.') &&
  264. ((szExt[1] == 'e') || (szExt[1] == 'E')) &&
  265. ((szExt[2] == 'x') || (szExt[2] == 'X')) &&
  266. ((szExt[3] == 'e') || (szExt[3] == 'E')) )
  267. // if (!lstrcmp(lpszPath, ".EXE"))
  268. {
  269. uiPrevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  270. Path -= wLen - 4;
  271. LinkFile += StartMenuLen + 1;
  272. // LinkFile[strlen(lpszLinkFile)-4]='\0';
  273. TCHAR szTemp[1024];
  274. lstrcpy (szTemp, LinkFile);
  275. szTemp[lstrlen (szTemp) - 4] = '\0';
  276. //crop off preceding \'s
  277. if (szTemp[0] == '\\')
  278. {
  279. TCHAR szTwo[1024];
  280. for (DWORD dwi = 0; dwi<(DWORD)lstrlen (szTemp); dwi++)
  281. {
  282. szTwo[dwi] = szTemp[dwi + 1];
  283. }
  284. szTwo[dwi + 1] = '\0';
  285. lstrcpy (szTemp, szTwo);
  286. }
  287. //crop off preceding \'s
  288. if (szTemp[0] == '\\')
  289. {
  290. TCHAR szTwo[1024];
  291. for (DWORD dwi=0; dwi<(DWORD)lstrlen(szTemp); dwi++)
  292. {
  293. szTwo[dwi]=szTemp[dwi+1];
  294. }
  295. szTwo[dwi+1]='\0';
  296. lstrcpy(szTemp, szTwo);
  297. }
  298. // nuke duplicate \'s in file name
  299. for (DWORD dwArgh = 0; dwArgh < 5; dwArgh++)
  300. {
  301. BOOL Glob1, Glob2, Glob3;
  302. Glob1 = Glob2 = Glob3 =TRUE;
  303. TCHAR szFin[1024];
  304. for (DWORD dw1 = 0; (dw1 < (DWORD)lstrlen(szTemp)) && (Glob1 == TRUE); dw1++)
  305. {
  306. szFin[dw1] = szTemp[dw1];
  307. if (szTemp[dw1] == '\\' && szTemp[dw1+1] == '\\')
  308. {
  309. for (DWORD dwThree = 0; dwThree < (DWORD)lstrlen(szTemp); dwThree++)
  310. {
  311. szFin[dw1 + dwThree] = szTemp[dw1+dwThree + 1];
  312. }
  313. szFin[dwThree + 1] = '\0';
  314. lstrcpy (szTemp, szFin);
  315. Glob1 = FALSE;
  316. }
  317. }
  318. }
  319. LogProc->StripCommas (szTemp);
  320. LogProc->LogString(",%s", szTemp);
  321. #ifdef MAXDEBUG
  322. LogProc->LogString("\r\nGetting version: %s\r\n", lpszLinkFile);
  323. #endif
  324. GetAppVer (Path);
  325. LinkFile -= StartMenuLen;
  326. SetErrorMode(uiPrevErrorMode);
  327. }
  328. else
  329. {
  330. Path -= wLen - 4;
  331. }
  332. // }
  333. }
  334. }
  335. ppf->Release();
  336. }
  337. ShellLink->Release();
  338. return HandleToResult;
  339. }
  340. BOOL CLASS_GeneralAppWalk::GetAppVer(LPSTR AppName)
  341. {
  342. DWORD dwVerInfoSize;
  343. DWORD dwZero;
  344. LPVOID lpvFileInfo;
  345. DWORD dwRetCode;
  346. PDWORD pdwVerBuf;
  347. UINT uLen;
  348. DWORD dwTranslation;
  349. TCHAR szString[MAX_PATH * 4];
  350. TCHAR szFullString[MAX_PATH * 4];
  351. TCHAR szTempString[MAX_PATH * 4];
  352. dwVerInfoSize = GetFileVersionInfoSize(AppName, &dwZero);
  353. if (!dwVerInfoSize) {
  354. LogProc->LogString(",Blank,Blank,Blank,Blank,Blank,\r\n");
  355. return TRUE;
  356. }
  357. lpvFileInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwVerInfoSize);
  358. if(!lpvFileInfo) {
  359. LogProc->LogString(",Blank,Blank,Blank,Blank,Blank,\r\n");
  360. return TRUE;
  361. }
  362. dwRetCode = GetFileVersionInfo(AppName, dwZero, dwVerInfoSize, lpvFileInfo);
  363. if (!dwRetCode)
  364. {
  365. LogProc->LogString(",Blank,Blank,Blank,Blank,Blank,\r\n");
  366. HeapFree(GetProcessHeap(), NULL, lpvFileInfo);
  367. return TRUE;
  368. }
  369. uLen = 0;
  370. pdwVerBuf = 0;
  371. dwRetCode = VerQueryValue(lpvFileInfo, (LPSTR)"\\VarFileInfo\\Translation", (LPVOID*)&pdwVerBuf, &uLen);
  372. if (!dwRetCode || !pdwVerBuf)
  373. {
  374. LogProc->LogString(",Blank,Blank,Blank,Blank,Blank,\r\n");
  375. HeapFree(GetProcessHeap(), NULL, lpvFileInfo);
  376. return TRUE;
  377. }
  378. dwTranslation = *pdwVerBuf;
  379. wsprintf (szString, "\\StringFileInfo\\%04x%04x\\", LOWORD (dwTranslation), HIWORD(dwTranslation));
  380. wsprintf (szFullString, "%sOriginalFileName", szString);
  381. dwRetCode = VerQueryValue(lpvFileInfo, szFullString, (LPVOID*)&pdwVerBuf, &uLen);
  382. if (uLen)
  383. {
  384. lstrcpy (szTempString, (TCHAR *)pdwVerBuf);
  385. if (0 != lstrlen (szTempString) )
  386. {
  387. LogProc->StripCommas(szTempString);
  388. LogProc->LogString(",%s", szTempString);
  389. }
  390. else
  391. {
  392. LogProc->LogString(",Blank");
  393. }
  394. }
  395. else
  396. {
  397. LogProc->LogString(",Blank");
  398. }
  399. wsprintf(szFullString, "%sFileVersion", szString);
  400. dwRetCode = VerQueryValue(lpvFileInfo, szFullString, (LPVOID*)&pdwVerBuf, &uLen);
  401. if (uLen)
  402. {
  403. lstrcpy(szTempString, (TCHAR *)pdwVerBuf);
  404. if (0 != lstrlen(szTempString))
  405. {
  406. LogProc->StripCommas(szTempString);
  407. LogProc->LogString(",%s", szTempString);
  408. }
  409. else
  410. {
  411. LogProc->LogString(",Blank");
  412. }
  413. }
  414. else
  415. {
  416. LogProc->LogString(",Blank");
  417. }
  418. wsprintf(szFullString, "%sProductName", szString);
  419. dwRetCode = VerQueryValue(lpvFileInfo, szFullString, (LPVOID*)&pdwVerBuf, &uLen);
  420. if (uLen)
  421. {
  422. lstrcpy(szTempString, (TCHAR *)pdwVerBuf);
  423. if (0 != lstrlen(szTempString))
  424. {
  425. LogProc->StripCommas(szTempString);
  426. LogProc->LogString(",%s", szTempString);
  427. }
  428. else
  429. {
  430. LogProc->LogString(",Blank");
  431. }
  432. }
  433. else
  434. {
  435. LogProc->LogString(",Blank");
  436. }
  437. wsprintf(szFullString, "%sProductVersion", szString);
  438. dwRetCode = VerQueryValue(lpvFileInfo, szFullString, (LPVOID*)&pdwVerBuf, &uLen);
  439. if (uLen)
  440. {
  441. lstrcpy(szTempString, (TCHAR *)pdwVerBuf);
  442. if (0 != strlen(szTempString))
  443. {
  444. LogProc->StripCommas(szTempString);
  445. LogProc->LogString(",%s", szTempString);
  446. }
  447. else
  448. {
  449. LogProc->LogString(",Blank");
  450. }
  451. }
  452. else
  453. {
  454. LogProc->LogString(",Blank");
  455. }
  456. wsprintf(szFullString, "%sCompanyName", szString);
  457. dwRetCode = VerQueryValue(lpvFileInfo, szFullString, (LPVOID*)&pdwVerBuf, &uLen);
  458. if (uLen)
  459. {
  460. lstrcpy(szTempString, (TCHAR *)pdwVerBuf);
  461. if (lstrlen(szTempString))
  462. {
  463. LogProc->StripCommas(szTempString);
  464. LogProc->LogString(",%s", szTempString);
  465. }
  466. else
  467. {
  468. LogProc->LogString(",Blank");
  469. }
  470. }
  471. else
  472. {
  473. LogProc->LogString(",Blank");
  474. }
  475. LogProc->LogString(",\r\n");
  476. HeapFree(GetProcessHeap(), NULL, lpvFileInfo);
  477. return TRUE;
  478. }
  479. BOOL CLASS_GeneralAppWalk::GetCurrentWinDir(void)
  480. {
  481. HINSTANCE hInst2 = NULL;
  482. LPFNDLLFUNC2 fProc = NULL;
  483. hInst2 = LoadLibraryEx("kernel32.dll", NULL, DONT_RESOLVE_DLL_REFERENCES);
  484. if(hInst2)
  485. fProc = (LPFNDLLFUNC2)GetProcAddress(hInst2, "GetSystemWindowsDirectoryA");
  486. if(fProc) {
  487. if(!fProc(g_WindowsDirectory, MAX_PATH)) {
  488. FreeLibrary(hInst2);
  489. return FALSE;
  490. }
  491. }
  492. else {
  493. if(!GetWindowsDirectory(g_WindowsDirectory, MAX_PATH))
  494. return FALSE;
  495. }
  496. if ( '\\' == g_WindowsDirectory[lstrlen(g_WindowsDirectory) - sizeof(TCHAR)] ) {
  497. g_WindowsDirectory[lstrlen(g_WindowsDirectory) - sizeof(TCHAR)] = '\0';
  498. }
  499. if(hInst2)
  500. FreeLibrary(hInst2);
  501. return TRUE;
  502. }