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.

1074 lines
31 KiB

  1. #include "compatadmin.h"
  2. #include "dbsearch.h"
  3. // Taken from sdbp.h
  4. #define PDB_MAIN 0x00000000
  5. #define PDB_TEST 0x10000000
  6. #define PDB_LOCAL 0x20000000
  7. #define TAGREF_STRIP_TAGID 0x0FFFFFFF
  8. #define TAGREF_STRIP_PDB 0xF0000000
  9. HANDLE g_hSearchThread = NULL;
  10. CDBSearch * g_pSearch = NULL;
  11. HWND g_hUpdateWnd;
  12. HWND g_hListWnd;
  13. CRITICAL_SECTION g_CritSect;
  14. DWORD g_dwMainThread;
  15. BOOL g_bAbort;
  16. typedef struct {
  17. TCHAR szDrive[MAX_PATH_BUFFSIZE];
  18. BOOL bSearch;
  19. } DRIVELIST, *PDRIVELIST;
  20. #define MAX_DRIVES 128
  21. DRIVELIST g_SearchDrives[MAX_DRIVES];
  22. TCHAR g_szWildcard[MAX_PATH_BUFFSIZE];
  23. BOOL PopulateFromExes (PSEARCHLIST pNew, TAGID ID,PDB pDB, TAGREF tagref);
  24. BOOL PopulateFromLayers (PSEARCHLIST pNew, TAGID ID,PDB pDB, TAGREF tagref, CSTRING strLayersInExes[]);
  25. CDBSearch::CDBSearch()
  26. {
  27. m_pList = NULL;
  28. m_hListView = NULL;
  29. InitializeCriticalSection(&g_CritSect);
  30. g_dwMainThread = GetCurrentThreadId();
  31. }
  32. BOOL CDBSearch::Initialize(void)
  33. {
  34. if ( !Create( TEXT("DBViewClass"),
  35. TEXT("Search View"),//Not displayed, used for diagnostics with SPY++
  36. 0,0,
  37. 10,10,
  38. &g_theApp,
  39. (HMENU)VIEW_DATABASE,
  40. 0,
  41. WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN) ) {
  42. return FALSE;
  43. }
  44. m_hMenu = LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_SEARCHMENU));
  45. m_hListView = CreateWindowEx( 0,
  46. WC_LISTVIEW,
  47. TEXT(""),
  48. WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPSIBLINGS | LVS_REPORT | LVS_OWNERDRAWFIXED,
  49. 0,0,
  50. 10,10,
  51. m_hWnd,
  52. NULL,
  53. g_hInstance,
  54. NULL);
  55. g_hListWnd = m_hListView;
  56. LONG uStyle = ListView_GetExtendedListViewStyle(m_hListView);
  57. ListView_SetExtendedListViewStyle(m_hListView,LVS_EX_FULLROWSELECT | uStyle);
  58. // Add the list view columns
  59. LV_COLUMN Col;
  60. Col.mask = LVCF_TEXT | LVCF_WIDTH;
  61. Col.pszText = TEXT("Affected File");
  62. Col.cchTextMax = lstrlen(Col.pszText);
  63. Col.cx = 200;
  64. ListView_InsertColumn(m_hListView,0,&Col);
  65. Col.pszText = TEXT("Application");
  66. Col.cchTextMax = lstrlen(Col.pszText);
  67. Col.cx = 150;
  68. ListView_InsertColumn(m_hListView,1,&Col);
  69. Col.pszText = TEXT("Action");
  70. Col.cchTextMax = lstrlen(Col.pszText);
  71. Col.cx = 100;
  72. ListView_InsertColumn(m_hListView,2,&Col);
  73. Col.pszText = TEXT("Database");
  74. Col.cchTextMax = lstrlen(Col.pszText);
  75. Col.cx = 100;
  76. ListView_InsertColumn(m_hListView,3,&Col);
  77. /*
  78. // This was for the settings field
  79. Col.pszText = TEXT("Settings");
  80. Col.cchTextMax = lstrlen(Col.pszText);
  81. Col.cx = 100;
  82. ListView_InsertColumn(m_hListView,4,&Col);
  83. */
  84. /*
  85. Col.pszText = "Local Setting";
  86. Col.cchTextMax = lstrlen(Col.pszText);
  87. Col.cx = 100;
  88. ListView_InsertColumn(m_hListView,5,&Col);
  89. */
  90. m_hFillBrush = CreateSolidBrush(RGB(235,235,235));
  91. return TRUE;
  92. }
  93. void CDBSearch::Update(BOOL fNotUsed)
  94. {
  95. while ( NULL != m_pList ) {
  96. PSEARCHLIST pHold = m_pList->pNext;
  97. delete m_pList;
  98. m_pList = pHold;
  99. }
  100. ListView_DeleteAllItems(m_hListView);
  101. g_pSearch = this;
  102. PostMessage(m_hWnd,WM_USER+1024,0,0);
  103. // Add everything to the list view.
  104. }
  105. BOOL CDBSearch::Activate(BOOL fNotUsed)
  106. {
  107. //K if (NULL == m_pList)
  108. Update(fNotUsed);
  109. return TRUE;
  110. }
  111. void CDBSearch::msgCommand(UINT uID, HWND hSender)
  112. {
  113. switch ( uID ) {
  114. case ID_SEARCH_NEWSEARCH:
  115. {
  116. Update();
  117. }
  118. break;
  119. }
  120. }
  121. void CDBSearch::msgResize(UINT uWidth, UINT uHeight)
  122. {
  123. MoveWindow(m_hListView,0,0,uWidth,uHeight,TRUE);
  124. InvalidateRect(m_hListView,NULL,TRUE);
  125. UpdateWindow(m_hListView);
  126. Refresh();
  127. }
  128. LRESULT CDBSearch::MsgProc(UINT uMsg,WPARAM wParam, LPARAM lParam)
  129. {
  130. switch ( uMsg ) {
  131. case WM_USER+1024:
  132. {
  133. g_hListWnd = m_hWnd;
  134. // Enumerate the drives and ask for query
  135. if ( 0 != DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_DRIVELIST),m_hWnd,(DLGPROC)SelectDrivesProc) )
  136. PostMessage(m_hWnd,WM_USER+1025,0,0);
  137. }
  138. break;
  139. case WM_USER+1025:
  140. {
  141. UINT uCount;
  142. for ( uCount=0; uCount<MAX_DRIVES; ++uCount ) {
  143. if ( g_SearchDrives[uCount].bSearch )
  144. DialogBoxParam(g_hInstance,MAKEINTRESOURCE(IDD_SEARCH),m_hWnd,(DLGPROC)SearchProc,(LPARAM)g_SearchDrives[uCount].szDrive);
  145. }
  146. }
  147. // DON'T BREAK. Allow a natural update.
  148. case WM_USER+1026:
  149. {
  150. // Now add everything we've found to the list view.
  151. EnterCriticalSection(&g_CritSect);
  152. ListView_DeleteAllItems(m_hListView);
  153. PSEARCHLIST pWalk = m_pList;
  154. int nItem = 0;
  155. while ( NULL != pWalk ) {
  156. LV_ITEM Item;
  157. Item.mask = TVIF_TEXT | TVIF_PARAM;
  158. Item.iItem = nItem;
  159. Item.iSubItem = 0;
  160. Item.pszText = pWalk->szFilename;
  161. Item.cchTextMax = lstrlen(Item.pszText);
  162. Item.lParam = (LPARAM) pWalk;
  163. ListView_InsertItem(m_hListView,&Item);
  164. Item.mask = TVIF_TEXT;
  165. Item.iItem = nItem;
  166. Item.iSubItem = 1;
  167. Item.pszText = pWalk->szApplication;
  168. Item.cchTextMax = lstrlen(Item.pszText);
  169. Item.lParam = (LPARAM) pWalk;
  170. ListView_InsertItem(m_hListView,&Item);
  171. ++nItem;
  172. pWalk = pWalk->pNext;
  173. }
  174. LeaveCriticalSection(&g_CritSect);
  175. }
  176. break;
  177. case WM_DRAWITEM:
  178. {
  179. LPDRAWITEMSTRUCT pDraw = (LPDRAWITEMSTRUCT) lParam;
  180. HDC hDC = CreateCompatibleDC(pDraw->hDC);
  181. HBITMAP hBmp = CreateCompatibleBitmap(pDraw->hDC,pDraw->rcItem.right - pDraw->rcItem.left,pDraw->rcItem.bottom - pDraw->rcItem.top);
  182. HBITMAP hOldBmp = (HBITMAP) SelectObject(hDC,hBmp);
  183. HFONT hFont = (HFONT) SendMessage(m_hListView,WM_GETFONT,0,0);
  184. PSEARCHLIST pList;
  185. LVITEM Item;
  186. RECT rBmpRect;
  187. hFont = (HFONT) SelectObject(hDC,hFont);
  188. SetRect(&rBmpRect,0,0,pDraw->rcItem.right - pDraw->rcItem.left,pDraw->rcItem.bottom - pDraw->rcItem.top);
  189. Item.mask = LVIF_PARAM;
  190. Item.iItem = pDraw->itemID;
  191. Item.iSubItem = 0;
  192. LV_COLUMN Col;
  193. Col.mask = LVCF_WIDTH;
  194. ListView_GetColumn(m_hListView,0,&Col);
  195. Col.cx = pDraw->rcItem.right;
  196. ListView_GetItem(m_hListView,&Item);
  197. if ( 0 != (pDraw->itemState & ODS_FOCUS) ) {
  198. FillRect(hDC,&rBmpRect,GetSysColorBrush(COLOR_HIGHLIGHT));
  199. SetBkColor(hDC,GetSysColor(COLOR_HIGHLIGHT));
  200. } else{
  201. FillRect(hDC,&rBmpRect,(HBRUSH) GetStockObject(WHITE_BRUSH));
  202. SetBkColor(hDC,RGB(255,255,255));
  203. }
  204. MoveToEx(hDC,Col.cx-1,0,NULL);
  205. //LineTo(hDC,Col.cx-1,rBmpRect.bottom);
  206. MoveToEx(hDC,0,rBmpRect.bottom-1,NULL);
  207. //LineTo(hDC,rBmpRect.right,rBmpRect.bottom-1);
  208. // Draw the actual name.
  209. pList = (PSEARCHLIST) Item.lParam;
  210. LPTSTR szText = pList->Record.szEXEName;
  211. RECT rClipRect = rBmpRect;
  212. rClipRect.left = 20;
  213. rClipRect.right = Col.cx - 2;
  214. --rClipRect.bottom;
  215. // Icon
  216. SHFILEINFO Info;
  217. ZeroMemory(&Info,sizeof(Info));
  218. SHGetFileInfo(pList->szFilename,FILE_ATTRIBUTE_NORMAL,&Info,sizeof(Info),SHGFI_ICON | SHGFI_SMALLICON);
  219. // NOTE: We don't use ImageList_Draw because it cannot stretch.
  220. DrawIconEx(hDC,5,0,Info.hIcon,rBmpRect.bottom,rBmpRect.bottom,0,NULL,DI_NORMAL);
  221. // Filename
  222. ExtTextOut( hDC,
  223. 10 + rBmpRect.bottom, 0,
  224. ETO_OPAQUE | ETO_CLIPPED,
  225. &rClipRect,
  226. szText, lstrlen(szText),
  227. NULL);
  228. // App name.
  229. Col.mask = LVCF_WIDTH;
  230. ListView_GetColumn(m_hListView,0,&Col);
  231. rClipRect.left = Col.cx;
  232. ListView_GetColumn(m_hListView,1,&Col);
  233. rClipRect.right = rClipRect.left + Col.cx;
  234. CSTRING strText;
  235. strText.sprintf(TEXT("%s"),TEXT(" "));
  236. if ( ! pList->Record.szAppName.isNULL() )
  237. strText.strcat( pList->Record.szAppName );
  238. ExtTextOut( hDC,
  239. rClipRect.left, 0,
  240. ETO_OPAQUE | ETO_CLIPPED,
  241. &rClipRect,
  242. strText, strText.Length(),
  243. NULL);
  244. Col.mask = LVCF_WIDTH;
  245. ListView_GetColumn(m_hListView,2,&Col);
  246. rClipRect.left = rClipRect.right;
  247. rClipRect.right = rClipRect.left + Col.cx;
  248. CSTRING szTemp;
  249. if ( pList->Record.szLayerName.Length() > 0 )
  250. szTemp.sprintf(TEXT("Layer: %s;"),(LPCTSTR) pList->Record.szLayerName);
  251. PDBENTRY pEntry = pList->Record.pEntries;
  252. BOOL bShim = FALSE, bAppHelp = FALSE, bPatchFlag = FALSE;
  253. while ( NULL != pEntry ) {
  254. if ( ENTRY_SHIM == pEntry->uType ){
  255. bShim = TRUE;
  256. }
  257. else if ( ENTRY_APPHELP == pEntry->uType ){
  258. bAppHelp = TRUE;
  259. }
  260. else if (ENTRY_MATCH != pEntry->uType) {
  261. bPatchFlag = TRUE;
  262. }
  263. pEntry = pEntry->pNext;
  264. }
  265. if (bShim) {
  266. szTemp.strcat(TEXT("Custom Fix"));
  267. szTemp.strcat(TEXT(";"));
  268. }
  269. if (bAppHelp) {
  270. szTemp.strcat(TEXT("AppHelp"));
  271. szTemp.strcat(TEXT(";"));
  272. }
  273. if (bPatchFlag) {
  274. szTemp.strcat(TEXT("Patch/Flag"));
  275. szTemp.strcat(TEXT(";"));
  276. }
  277. if(szTemp.Length() == 0 ){
  278. szTemp = TEXT("Patch/Flag;");
  279. }
  280. szTemp.SetChar(szTemp.Length()-1, TEXT('\0'));
  281. strText.sprintf(TEXT("%s"),TEXT(" "));
  282. if ( !szTemp.isNULL() )
  283. strText.strcat( szTemp );
  284. ExtTextOut( hDC,
  285. rClipRect.left, 0,
  286. ETO_OPAQUE | ETO_CLIPPED,
  287. &rClipRect,
  288. strText, strText.Length(),
  289. NULL);
  290. Col.mask = LVCF_WIDTH;
  291. ListView_GetColumn(m_hListView,3,&Col);
  292. rClipRect.left = rClipRect.right;
  293. rClipRect.right = rClipRect.left + Col.cx;
  294. strText.sprintf(TEXT("%s"),TEXT(" "));
  295. if ( ! pList->szDatabase.isNULL() )
  296. strText.strcat( pList->szDatabase );
  297. ExtTextOut( hDC,
  298. rClipRect.left, 0,
  299. ETO_OPAQUE | ETO_CLIPPED,
  300. &rClipRect,
  301. strText, strText.Length(),
  302. NULL);
  303. /* This was for the settings field.
  304. Col.mask = LVCF_WIDTH;
  305. ListView_GetColumn(m_hListView,4,&Col);
  306. rClipRect.left = rClipRect.right;
  307. rClipRect.right = rClipRect.left + Col.cx;
  308. if ( 0 == pList->Record.dwGlobalFlags )
  309. szText = TEXT("Enabled");
  310. else
  311. szText = TEXT("Disabled");
  312. strText.sprintf(TEXT("%s %s"),TEXT(" "),szText );
  313. ExtTextOut( hDC,
  314. rClipRect.left, 0,
  315. ETO_OPAQUE | ETO_CLIPPED,
  316. &rClipRect,
  317. strText, strText.Length(),
  318. NULL);
  319. */
  320. Col.mask = LVCF_WIDTH;
  321. ListView_GetColumn(m_hListView,5,&Col);
  322. rClipRect.left = rClipRect.right;
  323. rClipRect.right = rClipRect.left + Col.cx;
  324. BitBlt( pDraw->hDC,
  325. pDraw->rcItem.left,
  326. pDraw->rcItem.top,
  327. (pDraw->rcItem.right - pDraw->rcItem.left),
  328. (pDraw->rcItem.bottom - pDraw->rcItem.top)+1,
  329. hDC,
  330. 0,0,
  331. SRCCOPY);
  332. SelectObject(hDC,hOldBmp);
  333. SelectObject(hDC,hFont);
  334. DeleteObject(hBmp);
  335. DeleteDC(hDC);
  336. }
  337. break;
  338. }
  339. return CView::MsgProc(uMsg,wParam,lParam);
  340. }
  341. void SearchDrive(LPCTSTR szDir)
  342. {
  343. HANDLE hFile;
  344. WIN32_FIND_DATA Data;
  345. TCHAR szCurrentDir[MAX_PATH_BUFFSIZE];
  346. BOOL bAbort = FALSE;
  347. GetCurrentDirectory(sizeof(szCurrentDir)/sizeof(TCHAR),szCurrentDir);
  348. // Make a check here. This can fail if removable media is not present and
  349. // user selects cancel.
  350. if ( !SetCurrentDirectory(szDir) )
  351. return;
  352. SetWindowText(g_hUpdateWnd,szDir);
  353. hFile = FindFirstFile(g_szWildcard,&Data);
  354. if ( INVALID_HANDLE_VALUE != hFile ) {
  355. do {
  356. CSTRING szStr;
  357. szStr.sprintf(TEXT("%s"),szDir);
  358. if ( TEXT('\\') != szDir[lstrlen(szDir)-1] )
  359. szStr.strcat(TEXT("\\"));
  360. szStr.strcat(Data.cFileName);
  361. SDBQUERYRESULT Res;
  362. ZeroMemory(&Res,sizeof(SDBQUERYRESULT));
  363. // Determine if this file is affected in any way.
  364. if ( 0 == (Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
  365. if ( SdbGetMatchingExe(g_hSDB, (LPCTSTR)szStr,NULL, NULL, SDBGMEF_IGNORE_ENVIRONMENT, &Res) ) {
  366. // Yes, it is. Add it to the list of managed files.
  367. TAGID ID;
  368. PDB pDB;
  369. //
  370. //First read in the exes
  371. //
  372. CSTRING strLayersInExes[SDB_MAX_EXES];
  373. for (int nExeLoop = 0; nExeLoop < SDB_MAX_EXES; ++nExeLoop) {
  374. if (Res.atrExes[nExeLoop] ) {
  375. SdbTagRefToTagID(g_hSDB,Res.atrExes[nExeLoop],&pDB,&ID);
  376. PSEARCHLIST pNew = new SEARCHLIST;
  377. if (pNew == NULL) {
  378. MEM_ERR;
  379. return;
  380. }
  381. pNew->szFilename = szStr;
  382. PopulateFromExes(pNew,ID,pDB,Res.atrExes[nExeLoop]);
  383. strLayersInExes[nExeLoop] = pNew->Record.szLayerName;
  384. }
  385. }
  386. //
  387. //Now look for the layers.
  388. //
  389. for (int nLayerLoop = 0; nLayerLoop < SDB_MAX_LAYERS; ++nLayerLoop) {
  390. if (Res.atrLayers[nLayerLoop] ) {
  391. SdbTagRefToTagID(g_hSDB,Res.atrLayers[nLayerLoop],&pDB,&ID);
  392. PSEARCHLIST pNew = new SEARCHLIST;
  393. if (pNew == NULL) {
  394. MEM_ERR;
  395. return;
  396. }
  397. pNew->szFilename = szStr;
  398. PopulateFromLayers(pNew,ID,pDB,Res.atrLayers[nLayerLoop], strLayersInExes);
  399. }
  400. }
  401. // NOTE: SendNotifyMessage is thread safe.
  402. SendNotifyMessage(g_hListWnd,WM_USER+1026,0,0);
  403. }
  404. }
  405. EnterCriticalSection(&g_CritSect);
  406. bAbort = g_bAbort;
  407. LeaveCriticalSection(&g_CritSect);
  408. }
  409. while ( FindNextFile(hFile,&Data) && !bAbort );
  410. FindClose(hFile);
  411. }//if (INVALID_HANDLE_VALUE != hFile)
  412. // Now go through separately and walk the sub-directories.
  413. hFile = FindFirstFile(TEXT("*.*"),&Data);
  414. if ( INVALID_HANDLE_VALUE != hFile ) {
  415. do {
  416. if ( 0 != (Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
  417. BOOL bForbidden = FALSE;
  418. if ( TEXT('.') == Data.cFileName[0] )
  419. bForbidden = TRUE;
  420. if ( 0 == lstrcmp(TEXT("LocalService"),Data.cFileName) )
  421. bForbidden = TRUE;
  422. if ( 0 == lstrcmp(TEXT("NetworkService"),Data.cFileName) )
  423. bForbidden = TRUE;
  424. if ( 0 == lstrcmp(TEXT("System Volume Information"),Data.cFileName) )
  425. bForbidden = TRUE;
  426. if ( !bForbidden ) {
  427. TCHAR szPath[MAX_PATH_BUFFSIZE];
  428. lstrcpy(szPath,szDir);
  429. if ( lstrlen(szPath) > 3 )
  430. lstrcat(szPath,TEXT("\\"));
  431. lstrcat(szPath,Data.cFileName);
  432. SearchDrive(szPath);
  433. }
  434. }
  435. EnterCriticalSection(&g_CritSect);
  436. bAbort = g_bAbort;
  437. LeaveCriticalSection(&g_CritSect);
  438. }
  439. while ( FindNextFile(hFile,&Data) && !bAbort );
  440. FindClose(hFile);
  441. }
  442. SetCurrentDirectory(szCurrentDir);
  443. }
  444. DWORD WINAPI SearchThread(LPVOID pParam)
  445. {
  446. SearchDrive((LPCTSTR)pParam);
  447. return 0;
  448. }
  449. BOOL CALLBACK SearchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  450. {
  451. switch ( uMsg ) {
  452. case WM_INITDIALOG:
  453. {
  454. DWORD dwID;
  455. SetTimer(hDlg,0,1,NULL);
  456. g_hUpdateWnd = GetDlgItem(hDlg,IDC_SEARCHTEXT);
  457. // Begin searching the drive on a separate thread.
  458. g_hSearchThread = CreateThread(NULL, 0, SearchThread, (PVOID)lParam, 0, &dwID);
  459. }
  460. return TRUE;
  461. case WM_TIMER:
  462. {
  463. // Done searching? If not, wait
  464. if ( NULL != g_hSearchThread ) {
  465. if ( WAIT_OBJECT_0 == WaitForSingleObject(g_hSearchThread,0) ) {
  466. CloseHandle(g_hSearchThread);
  467. g_hSearchThread = NULL;
  468. }
  469. } else
  470. EndDialog(hDlg,0);
  471. }
  472. break;
  473. case WM_COMMAND:
  474. {
  475. switch ( LOWORD(wParam) ) {
  476. case IDCANCEL:
  477. {
  478. EnterCriticalSection(&g_CritSect);
  479. g_bAbort = TRUE;
  480. LeaveCriticalSection(&g_CritSect);
  481. }
  482. break;
  483. }
  484. }
  485. break;
  486. }
  487. return FALSE;
  488. }
  489. BOOL CALLBACK SelectDrivesProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  490. {
  491. switch ( uMsg ) {
  492. case WM_INITDIALOG:
  493. {
  494. SendMessage(
  495. GetDlgItem(hWnd,IDC_WILDCARD), // handle to destination window
  496. EM_LIMITTEXT, // message to send
  497. (WPARAM) MAX_PATH, // text length
  498. (LPARAM) 0
  499. );
  500. TCHAR szDrives[4096];
  501. *szDrives = 0;
  502. LPTSTR szWalk = szDrives;
  503. int nCount = 0;
  504. TCHAR szIcons[MAX_PATH_BUFFSIZE];
  505. g_bAbort = FALSE;
  506. GetSystemDirectory(szIcons,MAX_PATH);
  507. lstrcat(szIcons,TEXT("\\shell32.dll"));
  508. HIMAGELIST hImage = ImageList_Create(16,16,ILC_COLORDDB | ILC_MASK,0,1);
  509. HICON hIcon;
  510. // Floppy: 0
  511. ExtractIconEx(szIcons,6,NULL,&hIcon,1);
  512. ImageList_AddIcon(hImage,hIcon);
  513. // Fixed disk: 1
  514. ExtractIconEx(szIcons,8,NULL,&hIcon,1);
  515. ImageList_AddIcon(hImage,hIcon);
  516. // Network: 2
  517. ExtractIconEx(szIcons,9,NULL,&hIcon,1);
  518. ImageList_AddIcon(hImage,hIcon);
  519. // CD ROM: 3
  520. ExtractIconEx(szIcons,11,NULL,&hIcon,1);
  521. ImageList_AddIcon(hImage,hIcon);
  522. // RAM Disk: 4
  523. ExtractIconEx(szIcons,12,NULL,&hIcon,1);
  524. ImageList_AddIcon(hImage,hIcon);
  525. TreeView_SetImageList(GetDlgItem(hWnd,IDC_DRIVELIST),hImage,TVSIL_NORMAL);
  526. SetWindowText(GetDlgItem(hWnd,IDC_WILDCARD),TEXT("*.EXE"));
  527. GetLogicalDriveStrings(sizeof(szDrives)/sizeof(TCHAR),szDrives);
  528. while ( lstrlen(szWalk) > 0 ) { //Can be replaced by while(*szWalk).
  529. TVINSERTSTRUCT Item;
  530. TCHAR szString[MAX_PATH_BUFFSIZE];
  531. UINT uType = GetDriveType(szWalk);
  532. if ( DRIVE_REMOVABLE != uType && DRIVE_NO_ROOT_DIR != uType ) {
  533. TCHAR szVolume[MAX_PATH_BUFFSIZE];
  534. TCHAR szDriveFormat[MAX_PATH_BUFFSIZE];
  535. DWORD dwSerial;
  536. DWORD dwLen;
  537. DWORD dwFlags;
  538. szVolume[0] = 0;
  539. szDriveFormat[0] = 0;
  540. GetVolumeInformation(szWalk,
  541. szVolume,
  542. sizeof(szVolume)/sizeof(TCHAR),
  543. &dwSerial,
  544. &dwLen,
  545. &dwFlags,
  546. szDriveFormat,
  547. sizeof(szDriveFormat)/sizeof(TCHAR));
  548. if ( lstrlen(szVolume) == 0 )
  549. lstrcpy(szVolume,TEXT("No Volume"));
  550. _snwprintf(szString,sizeof(szString)/sizeof(TCHAR), TEXT("%s - %s"),szWalk,szVolume);
  551. } else
  552. lstrcpy(szString,szWalk);
  553. Item.hParent = TVI_ROOT;
  554. Item.hInsertAfter = TVI_LAST;
  555. Item.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  556. Item.item.pszText = szString;
  557. Item.item.cchTextMax = lstrlen(Item.item.pszText);
  558. switch ( uType ) {
  559. case DRIVE_REMOVABLE:
  560. Item.item.iImage = 0;
  561. Item.item.iSelectedImage = 0;
  562. break;
  563. case DRIVE_FIXED:
  564. Item.item.iImage = 1;
  565. Item.item.iSelectedImage = 1;
  566. break;
  567. case DRIVE_REMOTE:
  568. Item.item.iImage = 2;
  569. Item.item.iSelectedImage = 2;
  570. break;
  571. case DRIVE_CDROM:
  572. Item.item.iImage = 3;
  573. Item.item.iSelectedImage = 3;
  574. break;
  575. case DRIVE_RAMDISK:
  576. Item.item.iImage = 4;
  577. Item.item.iSelectedImage = 4;
  578. break;
  579. }
  580. Item.item.lParam = nCount;
  581. lstrcpy(g_SearchDrives[nCount].szDrive,szWalk);
  582. g_SearchDrives[nCount].bSearch = FALSE;
  583. nCount++;
  584. TreeView_InsertItem(GetDlgItem(hWnd,IDC_DRIVELIST),&Item);
  585. szWalk += lstrlen(szWalk) + 1;
  586. }
  587. }
  588. return TRUE;
  589. case WM_NOTIFY:
  590. {
  591. NMHDR * pHdr = (NMHDR *) lParam;
  592. switch ( pHdr->code ) {
  593. case NM_CLICK:
  594. {
  595. TVHITTESTINFO ht;
  596. HWND hTree = GetDlgItem(hWnd,IDC_DRIVELIST);
  597. GetCursorPos(&ht.pt);
  598. ScreenToClient(hTree, &ht.pt);
  599. TreeView_HitTest(hTree,&ht);
  600. if ( 0 != ht.hItem )
  601. TreeView_SelectItem(hTree,ht.hItem);
  602. }
  603. break;
  604. /*
  605. case TVN_SELCHANGED:
  606. HWND hTree = GetDlgItem(hWnd,IDC_DRIVELIST);
  607. LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) lParam;
  608. //((pnmtv->itemNew).state & TVIS_SELECTED) ?
  609. TreeView_SelectItem(hTree,(pnmtv->itemNew).hItem);
  610. break;
  611. */
  612. }//switch(pHdr->code)
  613. }
  614. break;
  615. case WM_COMMAND:
  616. switch ( LOWORD(wParam) ) {
  617. case IDCANCEL:
  618. EndDialog(hWnd,0);
  619. break;
  620. case IDOK:
  621. {
  622. HTREEITEM hItem;
  623. HWND hTree = GetDlgItem(hWnd,IDC_DRIVELIST);
  624. GetWindowText(GetDlgItem(hWnd,IDC_WILDCARD),g_szWildcard,MAX_PATH);
  625. hItem = TreeView_GetRoot(hTree);
  626. //EFF: Probably we can make the change that when we select or click the
  627. //Tree control, then we can make toggle g_SearchDrives[Item.lParam].bSearch
  628. while ( NULL != hItem ) {
  629. TVITEM Item;
  630. Item.mask = TVIF_STATE | TVIF_PARAM;
  631. Item.hItem = hItem;
  632. TreeView_GetItem(hTree,&Item);
  633. if ( 0 != (Item.state & 0x2000) )
  634. g_SearchDrives[Item.lParam].bSearch = TRUE;
  635. hItem = TreeView_GetNextSibling(hTree,hItem);
  636. }
  637. EndDialog(hWnd,1);
  638. }
  639. break;
  640. }
  641. }
  642. return FALSE;
  643. }
  644. void CDBSearch::msgChar(TCHAR ch)
  645. {
  646. SendMessage(this->m_hListView,WM_CHAR,(WPARAM)ch, 0x8000 );
  647. }
  648. BOOL PopulateFromExes(PSEARCHLIST pNew, TAGID ID,PDB pDB, TAGREF tagref)
  649. {
  650. //
  651. //We have to populate the pNew->szFileName before calling this function.
  652. //
  653. BOOL valid = CDatabase::ReadRecord(ID,&pNew->Record,pDB);
  654. switch ( tagref & TAGREF_STRIP_PDB ) {
  655. case PDB_MAIN:
  656. pNew->szDatabase = TEXT("Global");
  657. break;
  658. case PDB_TEST:
  659. pNew->szDatabase = TEXT("Test");
  660. break;
  661. case PDB_LOCAL:
  662. pNew->szDatabase = TEXT("Local");
  663. break;
  664. }
  665. pNew->pNext = g_pSearch->m_pList;
  666. pNew->Record.szEXEName = pNew->szFilename;
  667. EnterCriticalSection(&g_CritSect);
  668. g_pSearch->m_pList = pNew;
  669. LeaveCriticalSection(&g_CritSect);
  670. return valid;
  671. }
  672. BOOL PopulateFromLayers(PSEARCHLIST pNew, TAGID ID,PDB pDB, TAGREF tagref, CSTRING strLayersInExes[] )
  673. {
  674. //
  675. //We have to populate the pNew->szFileName before calling this function.
  676. //
  677. //
  678. //For those global entries which do not have layers but shims etc.
  679. //
  680. BOOL valid = CDatabase::ReadRecord(ID,&pNew->Record,pDB);
  681. pNew->Record.szLayerName = pNew->Record.szEXEName;
  682. pNew->Record.szEXEName = pNew->szFilename;
  683. pNew->Record.pEntries = NULL;
  684. if (pNew->Record.szLayerName.isNULL() ) {
  685. return TRUE;
  686. }
  687. //
  688. //We are looking for the layers and must not add a layer that has already been found
  689. //
  690. for (int nLoop = 0; nLoop < SDB_MAX_EXES; ++nLoop ){
  691. if (strLayersInExes[nLoop] == pNew->Record.szLayerName) {
  692. return FALSE;
  693. }
  694. }//for (int nLoop = 0; nLoop < MAX_EXES, ++nLoop)
  695. switch ( tagref & TAGREF_STRIP_PDB ) {
  696. case PDB_MAIN:
  697. pNew->szDatabase = TEXT("Global");
  698. break;
  699. case PDB_TEST:
  700. pNew->szDatabase = TEXT("Test");
  701. break;
  702. case PDB_LOCAL:
  703. pNew->szDatabase = TEXT("Local");
  704. break;
  705. }
  706. pNew->pNext = g_pSearch->m_pList;
  707. pNew->Record.szEXEName = pNew->szFilename;
  708. pNew->Record.szAppName = TEXT("<No name available: Fix possibly created using Compatibility Wizard>");
  709. EnterCriticalSection(&g_CritSect);
  710. g_pSearch->m_pList = pNew;
  711. LeaveCriticalSection(&g_CritSect);
  712. return TRUE;
  713. }