Leaked source code of windows server 2003
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.

6121 lines
167 KiB

  1. /*++
  2. Copyright (c) 1989-2001 Microsoft Corporation
  3. Module Name:
  4. wizard.cpp
  5. Abstract:
  6. Code for the Fix Wizard
  7. Author:
  8. kinshu created July 2, 2001
  9. Notes:
  10. 1. Whenever we are using Delete*****, please make sure that after return the
  11. arg passed is nulled as well.
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. //////////////////////// Extern variables /////////////////////////////////////
  16. extern HINSTANCE g_hInstance;
  17. extern HIMAGELIST g_hImageList;
  18. extern struct DataBase GlobalDataBase;
  19. ///////////////////////////////////////////////////////////////////////////////
  20. //////////////////////// Defines //////////////////////////////////////////////
  21. // The tree in the matching file page of the wizard has its own imagelist. This is the index of
  22. // the attribute image in that imagelist
  23. #define IMAGE_ATTRIBUTE_MATCHTREE 1;
  24. // These are the various pages of the wizard
  25. // The first page, we get the app info here
  26. #define PAGE_APPNAME 0
  27. // The second page, we get the layers to be applied here
  28. #define PAGE_LAYERS 1
  29. // The third page, we get the shims to be applied here
  30. #define PAGE_SHIMS 2
  31. // The fourth page, we get the mathcing files for the entry here
  32. #define PAGE_MATCH 3
  33. // Total number of pages in the wizard
  34. #define NUM_PAGES 4
  35. // The first column in the get params dialog list view. The type of module, include or exclude
  36. #define COLUMN_TYPE 0
  37. // The second column in the get params dialog. The name of the module
  38. #define COLUMN_NAME 1
  39. //
  40. // maximum number of matching files that we should be considered. Note that this does
  41. // not mean that an entry can have MAX_FILES matching files. From MAX_FILES files we will
  42. // select the largest MAX_AUTO_MATCH files
  43. #define MAX_FILES 100
  44. // The length of the module name in chars. This does not include the terminating NULL
  45. #define MAX_MODULE_NAME (MAX_PATH - 1)
  46. // The length of the command line in chars. This does not include the terminating NULL
  47. #define MAX_COMMAND_LINE (511)
  48. ///////////////////////////////////////////////////////////////////////////////
  49. //////////////////////// Global Variables /////////////////////////////////////
  50. //
  51. // Should we test for the checking off of the check boxes? We do it only if this variable is TRUE
  52. // Otherwise when we show all the items in ShowItems(), we might get the prompt even then
  53. // This is a hack and needs to be corrected <TODO>
  54. BOOL g_bNowTest = FALSE;
  55. /*++
  56. WARNING: Do not change the position of these strings, they should match
  57. with the dialog IDD_LAYERS radio buttons
  58. --*/
  59. // The names of the various OS layers as they are in the system db: sysmain.sdb
  60. TCHAR *s_arszOsLayers[] = {
  61. TEXT("Win95"),
  62. TEXT("NT4SP5"),
  63. TEXT("Win98"),
  64. TEXT("Win2000")
  65. };
  66. // The layers have changed since the last time we have populated the shims list
  67. BOOL g_bLayersChanged = FALSE;
  68. //
  69. // The LUA layer needs to be treated specially - when the user selects it
  70. // on the select layer page, we only check the checkbox but really add the
  71. // shims in the layer to the shim fix list instead of add the layer to the
  72. // layer fix list. This allows us to later change the lua data around in
  73. // the DBENTRY without affect the layer globally.
  74. BOOL g_bIsLUALayerSelected = FALSE;
  75. //
  76. // Used for indicating whether the LUA wizard should start when the app fix wizard
  77. // is completed
  78. BOOL g_bShouldStartLUAWizard = FALSE;
  79. // The pointer to the current wizard object
  80. CShimWizard* g_pCurrentWizard = NULL;
  81. // The handle to the matching file tree
  82. static HWND s_hwndTree = NULL;
  83. // The handle to the tool tip control associated with the list view in the shims page
  84. static HWND s_hwndToolTipList;
  85. // The image list for the tree in the matching files page
  86. static HIMAGELIST s_hMatchingFileImageList;
  87. // This will be true if we change some stuff in the shim page.
  88. static BOOL s_bLayerPageRefresh;
  89. // The handle to the layer list view in the second wizard page
  90. static HWND s_hwndLayerList;
  91. // The handle to the fixes list view in the second wizard page
  92. static HWND s_hwndShimList;
  93. // Are we showing all the shims or only the selected shims
  94. static BOOL s_bAllShown = TRUE;
  95. ///////////////////////////////////////////////////////////////////////////////
  96. //////////////////////// Function Declarations ////////////////////////////////
  97. INT_PTR
  98. GetAppNameDlgOnCommand(
  99. HWND hDlg,
  100. WPARAM wParam
  101. );
  102. INT_PTR
  103. GetAppNameDlgOnInitDialog(
  104. HWND hDlg
  105. );
  106. INT_PTR
  107. GetAppNameDlgOnNotify(
  108. HWND hDlg,
  109. LPARAM lParam
  110. );
  111. INT_PTR
  112. SelectLayerDlgOnCommand(
  113. HWND hDlg,
  114. WPARAM wParam
  115. );
  116. INT_PTR
  117. SelectLayerDlgOnDestroy(
  118. void
  119. );
  120. INT_PTR
  121. SelectLayerDlgOnNotify(
  122. HWND hDlg,
  123. LPARAM lParam
  124. );
  125. INT_PTR
  126. SelectLayerDlgOnInitDialog(
  127. HWND hDlg
  128. );
  129. INT_PTR
  130. SelectShimsDlgOnNotify(
  131. HWND hDlg,
  132. LPARAM lParam
  133. );
  134. INT_PTR
  135. SelectShimsDlgOnInitDialog(
  136. HWND hDlg
  137. );
  138. INT_PTR
  139. SelectFilesDlgOnInitDialog(
  140. HWND hDlg
  141. );
  142. INT_PTR
  143. SelectFilesDlgOnCommand(
  144. HWND hDlg,
  145. WPARAM wParam
  146. );
  147. INT_PTR
  148. SelectFilesDlgOnMatchingTreeRefresh(
  149. IN HWND hDlg
  150. );
  151. INT_PTR
  152. SelectFilesDlgOnNotify(
  153. HWND hDlg,
  154. LPARAM lParam
  155. );
  156. INT_PTR
  157. SelectShimsDlgOnCommand(
  158. HWND hDlg,
  159. WPARAM wParam
  160. );
  161. INT_PTR
  162. SelectShimsDlgOnTimer(
  163. HWND hDlg
  164. );
  165. INT_PTR
  166. SelectShimsDlgOnDestroy(
  167. void
  168. );
  169. BOOL
  170. AddLuaShimsInEntry(
  171. PDBENTRY pEntry,
  172. CSTRINGLIST* pstrlShimsAdded = NULL
  173. );
  174. void
  175. ShowParams(
  176. HWND hDlg,
  177. HWND hwndList
  178. );
  179. void
  180. AddMatchingFileToTree(
  181. HWND hwndTree,
  182. PMATCHINGFILE pMatch,
  183. BOOL bAddToMatchingList
  184. );
  185. INT_PTR
  186. CALLBACK
  187. SelectShims(
  188. HWND hDlg,
  189. UINT uMsg,
  190. WPARAM wParam,
  191. LPARAM lParam
  192. );
  193. void
  194. HandleShowAllAtrr(
  195. HWND hdlg
  196. );
  197. void
  198. ChangeShimIcon(
  199. LPCTSTR pszItem
  200. );
  201. void
  202. HandleAddMatchingFile(
  203. HWND hdlg,
  204. CSTRING& strFilename,
  205. CSTRING& strRelativePath,
  206. DWORD dwMask = DEFAULT_MASK
  207. );
  208. BOOL
  209. HandleAttributeTreeNotification(
  210. HWND hdlg,
  211. LPARAM lParam
  212. );
  213. ///////////////////////////////////////////////////////////////////////////////
  214. BOOL
  215. LayerPresent(
  216. IN PLAYER_FIX plf,
  217. IN PDBENTRY pEntry,
  218. OUT PLAYER_FIX_LIST* ppLayerFixList
  219. )
  220. /*++
  221. LayerPresent
  222. Desc: Checks if the entry pEntry is fixed with layer plf.
  223. If yes and ppLayerFixList is not NULL, stores the corresponding pointer to layer-fix
  224. list for plf in pEntry in ppLayerFixList
  225. Params:
  226. IN PLAYER_FIX plf : The layer to search
  227. IN PDBENTRY pEntry : The entry in which to search
  228. OUT PLAYER_FIX_LIST* ppLayerFixList : If the layer is present in pEntry and
  229. ppLayerFixList is not NULL, stores the corresponding pointer to layer-fix
  230. list for plf in pEntry in ppLayerFixList
  231. Return:
  232. TRUE : pEntry is fixed with plf
  233. FALSE : Otherwise
  234. --*/
  235. {
  236. if (pEntry == NULL) {
  237. assert(FALSE);
  238. return FALSE;
  239. }
  240. PLAYER_FIX_LIST plfl = pEntry->pFirstLayer;
  241. //
  242. // For all layers applied to this entry, check if one of them is the one that we
  243. // are looking for
  244. //
  245. while (plfl) {
  246. if (plfl->pLayerFix == plf) {
  247. if (ppLayerFixList) {
  248. *ppLayerFixList = plfl;
  249. }
  250. return TRUE;
  251. }
  252. plfl = plfl->pNext;
  253. }
  254. return FALSE;
  255. }
  256. BOOL
  257. ShimPresent(
  258. IN PSHIM_FIX psf,
  259. IN PDBENTRY pEntry,
  260. OUT PSHIM_FIX_LIST* ppShimFixList
  261. )
  262. /*++
  263. ShimPresent
  264. Desc: Checks if the entry pEntry is fixed with shim psf.
  265. If yes and ppShimFixList is not NULL, stores the corresponding pointer to shim-fix
  266. list for psf in pEntry in ppShimFixList
  267. Params:
  268. IN PSHIM_FIX psf: The shim to search
  269. IN PDBENTRY pEntry: The entry in which to search
  270. OUT PSHIM_FIX_LIST* ppShimFixList: If the shim is present in pEntry and
  271. ppShimFixList is not NULL, stores the corresponding pointer to shim-fix
  272. list for psf in pEntry in ppShimFixList
  273. Return:
  274. TRUE: pEntry is fixed with psf
  275. FALSE: Otherwise
  276. --*/
  277. {
  278. if (pEntry == NULL) {
  279. assert(FALSE);
  280. return FALSE;
  281. }
  282. PSHIM_FIX_LIST psfList = pEntry->pFirstShim;
  283. //
  284. // For all the shims applied to this entry check if,one of them is the one we are lookign for
  285. //
  286. while (psfList) {
  287. if (psfList->pShimFix)
  288. if (psfList->pShimFix == psf) {
  289. if (ppShimFixList) {
  290. *ppShimFixList = psfList;
  291. }
  292. return TRUE;
  293. }
  294. psfList = psfList->pNext;
  295. }
  296. return FALSE;
  297. }
  298. BOOL
  299. FlagPresent(
  300. IN PFLAG_FIX pff,
  301. IN PDBENTRY pEntry,
  302. OUT PFLAG_FIX_LIST* ppFlagFixList
  303. )
  304. /*++
  305. FlagPresent
  306. Desc: Checks if the entry pEntry is fixed with flag pff.
  307. If yes and ppFlagFixList is not NULL, stores the corresponding pointer to flag-fix
  308. list for pff in pEntry in ppFlagFixList
  309. Params:
  310. IN PFLAG_FIX pff: The flag to search
  311. IN PDBENTRY pEntry: The entry in which to search
  312. OUT PFLAG_FIX_LIST* ppFlagFixList: If the flag is present in pEntry and
  313. ppFlagFixList is not NULL, stores the corresponding pointer to flag-fix
  314. list for pff in pEntry in ppFlagFixList
  315. Return:
  316. TRUE : pEntry is fixed with pff
  317. FALSE : Otherwise
  318. --*/
  319. {
  320. if (pEntry == NULL) {
  321. assert(FALSE);
  322. return FALSE;
  323. }
  324. PFLAG_FIX_LIST pffList = pEntry->pFirstFlag;
  325. //
  326. // For all the flags applied to this entry check if,one of them is the one
  327. // we are looking for
  328. //
  329. while (pffList) {
  330. if (pffList->pFlagFix)
  331. if (pffList->pFlagFix == pff) {
  332. if (ppFlagFixList) {
  333. *ppFlagFixList = pffList;
  334. }
  335. return TRUE;
  336. }
  337. pffList = pffList->pNext;
  338. }
  339. return FALSE;
  340. }
  341. CShimWizard::CShimWizard()
  342. /*++
  343. CShimWizard::CShimWizard
  344. Desc: Constructor for CShimWizard
  345. --*/
  346. {
  347. dwMaskOfMainEntry = DEFAULT_MASK;
  348. }
  349. BOOL
  350. CShimWizard::CheckAndSetLongFilename(
  351. IN HWND hDlg,
  352. IN INT iStrID
  353. )
  354. /*++
  355. CShimWizard::CheckAndSetLongFilename
  356. Desc: If we do not have the complete path of the present entry being fixed,
  357. prompts for that and pops up a open common dialog box to select the file, and
  358. to get the complete path
  359. Params:
  360. IN HWND hDlg: Parent for the open common dialog or any messagebox
  361. IN INT iStrID: String resource id for the prompt message asking for
  362. the complete path of the file being fixed
  363. Return:
  364. TRUE: The complete path has been successfully set
  365. FALSE: Otherwise
  366. --*/
  367. {
  368. TCHAR chTemp;
  369. CSTRING strFilename;
  370. CSTRING strExename;
  371. TCHAR szBuffer[512] = TEXT("");
  372. if (g_pCurrentWizard->m_Entry.strFullpath.Length() == 0) {
  373. g_pCurrentWizard->m_Entry.strFullpath = TEXT("XXXXXX");
  374. }
  375. if (g_pCurrentWizard->m_Entry.strFullpath.GetChar(1, &chTemp)) {
  376. if (chTemp != TEXT(':')) {
  377. //
  378. // Check if the file is on a network. filenames will begin with "\\"
  379. //
  380. if (chTemp == TEXT('\\')) {
  381. g_pCurrentWizard->m_Entry.strFullpath.GetChar(0, &chTemp);
  382. if (chTemp == TEXT('\\')) {
  383. return TRUE;
  384. }
  385. }
  386. //
  387. // We do not have the complete path.
  388. //
  389. MessageBox(hDlg,
  390. CSTRING(iStrID),
  391. g_szAppName,
  392. MB_OK | MB_ICONINFORMATION);
  393. //
  394. // Get the long file name. The g_pCurrentWizard->m_Entry.strFullpath has been
  395. // set in the first page. So if we are editing and we do not have the complete
  396. // path, g_pCurrentWizard->m_Entry.strFullpath will have at least have
  397. // the exe name
  398. //
  399. strExename = g_pCurrentWizard->m_Entry.strFullpath;
  400. strExename.ShortFilename();
  401. GetString(IDS_EXEFILTER, szBuffer, ARRAYSIZE(szBuffer));
  402. //
  403. // Prompt the user to give us the complete path for the file being fixed
  404. // We need the complete path, so that we can get the relative paths for
  405. // any matching files that we might add
  406. //
  407. while (1) {
  408. if (GetFileName(hDlg,
  409. CSTRING(IDS_GETLONGNAME),
  410. szBuffer,
  411. TEXT(""),
  412. CSTRING(IDS_EXE_EXT),
  413. OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST,
  414. TRUE,
  415. strFilename)) {
  416. CSTRING strTemp = strFilename;
  417. strTemp.ShortFilename();
  418. if (strExename != strTemp) {
  419. //
  420. // The user gave us the path of some file, whose file and exe components
  421. // do not match the program file being fixed
  422. //
  423. MessageBox(hDlg,
  424. CSTRING(IDS_DOESNOTMATCH),
  425. g_szAppName,
  426. MB_ICONWARNING);
  427. //
  428. // So we ask the user to try again
  429. //
  430. continue;
  431. }
  432. //
  433. // We now have the complete path for the file being fixed
  434. //
  435. m_Entry.strFullpath = strFilename;
  436. return TRUE;
  437. } else {
  438. return FALSE;
  439. }
  440. }
  441. }
  442. } else {
  443. //
  444. // There was some error
  445. //
  446. assert(FALSE);
  447. return FALSE;
  448. }
  449. return TRUE;
  450. }
  451. BOOL
  452. IsOsLayer(
  453. IN PCTSTR pszLayerName
  454. )
  455. /*++
  456. IsOsLayer
  457. Desc: Is the passed layer name an OS layer?
  458. Params:
  459. IN TCHAR *pszLayerName: The layer name to check for
  460. Return:
  461. TRUE: If this is the name of an OS layer
  462. FALSE: Otherwise
  463. --*/
  464. {
  465. INT iTotalOsLayers = sizeof (s_arszOsLayers) / sizeof(s_arszOsLayers[0]);
  466. for (int iIndex = 0;
  467. iIndex < iTotalOsLayers;
  468. ++iIndex) {
  469. if (lstrcmpi(s_arszOsLayers[iIndex], pszLayerName) == 0) {
  470. return TRUE;
  471. }
  472. }
  473. return FALSE;
  474. }
  475. BOOL
  476. CShimWizard::BeginWizard(
  477. IN HWND hParent,
  478. IN PDBENTRY pEntry,
  479. IN PDATABASE pDatabase,
  480. IN PBOOL pbShouldStartLUAWizard
  481. )
  482. /*++
  483. CShimWizard::BeginWizard
  484. Desc: Starts up the wizard
  485. Params:
  486. IN HWND hParent: The parent of the wizard
  487. IN PDBENTRY pEntry: The entry which has to be editted. If this is NULL, then we
  488. want to create a new fix entry.
  489. IN PDATABASE pDatabase: The present database.
  490. Return:
  491. TRUE: If the user presses FINISH
  492. FALSE: Otherwise
  493. --*/
  494. {
  495. PROPSHEETPAGE Pages[11] = {0};
  496. g_bIsLUALayerSelected = FALSE;
  497. g_bShouldStartLUAWizard = FALSE;
  498. m_pDatabase = pDatabase;
  499. ZeroMemory(Pages, sizeof(Pages));
  500. if (pEntry == NULL) {
  501. //
  502. // Create a new fix.
  503. //
  504. ZeroMemory(&m_Entry, sizeof(m_Entry));
  505. GUID Guid;
  506. CoCreateGuid(&Guid);
  507. StringCchPrintf(m_Entry.szGUID,
  508. ARRAYSIZE(m_Entry.szGUID),
  509. TEXT("{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"),
  510. Guid.Data1,
  511. Guid.Data2,
  512. Guid.Data3,
  513. Guid.Data4[0],
  514. Guid.Data4[1],
  515. Guid.Data4[2],
  516. Guid.Data4[3],
  517. Guid.Data4[4],
  518. Guid.Data4[5],
  519. Guid.Data4[6],
  520. Guid.Data4[7]);
  521. m_bEditing = FALSE;
  522. } else {
  523. //
  524. // Edit the passed fix.
  525. //
  526. m_bEditing = TRUE;
  527. //
  528. // Make a copy of the fix that we are going to edit
  529. //
  530. m_Entry = *pEntry;
  531. }
  532. //
  533. // Setup wizard variables
  534. //
  535. g_pCurrentWizard = this;
  536. //
  537. // We are in fix wizard and not in AppHelp wizard
  538. //
  539. m_uType = TYPE_FIXWIZARD;
  540. //
  541. // Begin the wizard
  542. //
  543. PROPSHEETHEADER Header = {0};
  544. Header.dwSize = sizeof(PROPSHEETHEADER);
  545. Header.dwFlags = PSH_WIZARD97 | PSH_HEADER | PSH_WATERMARK | PSH_PROPSHEETPAGE;
  546. Header.hwndParent = hParent;
  547. Header.hInstance = g_hInstance;
  548. Header.nStartPage = 0;
  549. Header.ppsp = Pages;
  550. Header.nPages = NUM_PAGES;
  551. Header.pszbmHeader = MAKEINTRESOURCE(IDB_WIZBMP);
  552. Header.pszbmWatermark = MAKEINTRESOURCE(IDB_TOOL);
  553. if (m_bEditing) {
  554. Header.dwFlags |= PSH_WIZARDHASFINISH;
  555. }
  556. Pages[PAGE_APPNAME].dwSize = sizeof(PROPSHEETPAGE);
  557. Pages[PAGE_APPNAME].dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE ;
  558. Pages[PAGE_APPNAME].hInstance = g_hInstance;
  559. Pages[PAGE_APPNAME].pszTemplate = MAKEINTRESOURCE(IDD_FIXWIZ_APPINFO);
  560. Pages[PAGE_APPNAME].pfnDlgProc = GetAppName;
  561. Pages[PAGE_APPNAME].pszHeaderTitle = MAKEINTRESOURCE(IDS_GIVEAPPINFO);
  562. Pages[PAGE_APPNAME].pszHeaderSubTitle = MAKEINTRESOURCE(IDS_GIVEAPPINFOSUBHEADING);
  563. Pages[PAGE_LAYERS].dwSize = sizeof(PROPSHEETPAGE);
  564. Pages[PAGE_LAYERS].dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  565. Pages[PAGE_LAYERS].hInstance = g_hInstance;
  566. Pages[PAGE_LAYERS].pszTemplate = MAKEINTRESOURCE(IDD_FIXWIZ_MODES);
  567. Pages[PAGE_LAYERS].pfnDlgProc = SelectLayer;
  568. Pages[PAGE_LAYERS].pszHeaderTitle = MAKEINTRESOURCE(IDS_SELECTLAYERS);
  569. Pages[PAGE_LAYERS].pszHeaderSubTitle = MAKEINTRESOURCE(IDS_SELECTLAYERS_SUBHEADING);
  570. Pages[PAGE_SHIMS].dwSize = sizeof(PROPSHEETPAGE);
  571. Pages[PAGE_SHIMS].dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  572. Pages[PAGE_SHIMS].hInstance = g_hInstance;
  573. Pages[PAGE_SHIMS].pszTemplate = MAKEINTRESOURCE(IDD_FIXWIZ_SHIMS);
  574. Pages[PAGE_SHIMS].pfnDlgProc = SelectShims;
  575. Pages[PAGE_SHIMS].pszHeaderTitle = MAKEINTRESOURCE(IDS_COMPATFIXES);
  576. Pages[PAGE_SHIMS].pszHeaderSubTitle = MAKEINTRESOURCE(IDS_SELECTSHIMS_SUBHEADING);
  577. Pages[PAGE_MATCH].dwSize = sizeof(PROPSHEETPAGE);
  578. Pages[PAGE_MATCH].dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  579. Pages[PAGE_MATCH].hInstance = g_hInstance;
  580. Pages[PAGE_MATCH].pszTemplate = MAKEINTRESOURCE(IDD_FIXWIZ_MATCHINGINFO);
  581. Pages[PAGE_MATCH].pfnDlgProc = SelectFiles;
  582. Pages[PAGE_MATCH].pszHeaderTitle = MAKEINTRESOURCE(IDS_MATCHINFO);
  583. Pages[PAGE_MATCH].pszHeaderSubTitle = MAKEINTRESOURCE(IDS_MATCHINFO_SUBHEADING);
  584. BOOL bReturn = FALSE;
  585. if (0 < PropertySheet(&Header)) {
  586. //
  587. // The user pressed finish in the wizard
  588. //
  589. bReturn = TRUE;
  590. } else {
  591. //
  592. // The user pressed cancel in the wizard
  593. //
  594. bReturn = FALSE;
  595. }
  596. ENABLEWINDOW(g_hDlg, TRUE);
  597. *pbShouldStartLUAWizard = g_bShouldStartLUAWizard;
  598. return bReturn;
  599. }
  600. INT_PTR
  601. CALLBACK
  602. GetAppName(
  603. IN HWND hDlg,
  604. IN UINT uMsg,
  605. IN WPARAM wParam,
  606. IN LPARAM lParam
  607. )
  608. /*++
  609. GetAppName
  610. Desc: Dialog proc for the first page of the wizard. Gets the app info and also sets the
  611. Full path of the entry
  612. Params: Standard dialog handler parameters
  613. IN HWND hDlg
  614. IN UINT uMsg
  615. IN WPARAM wParam
  616. IN LPARAM lParam
  617. Return: Standard dialog handler return
  618. --*/
  619. {
  620. INT_PTR ipReturn = 0;
  621. switch (uMsg) {
  622. case WM_INITDIALOG:
  623. ipReturn = GetAppNameDlgOnInitDialog(hDlg);
  624. break;
  625. case WM_NOTIFY:
  626. ipReturn = GetAppNameDlgOnNotify(hDlg, lParam);
  627. break;
  628. case WM_COMMAND:
  629. ipReturn = GetAppNameDlgOnCommand(hDlg, wParam);
  630. break;
  631. default: ipReturn = 0;
  632. }
  633. return ipReturn;
  634. }
  635. INT_PTR
  636. CALLBACK
  637. SelectLayer(
  638. IN HWND hDlg,
  639. IN UINT uMsg,
  640. IN WPARAM wParam,
  641. IN LPARAM lParam
  642. )
  643. /*++
  644. SelectLayer
  645. Desc: Dialog proc for the second page of the wizard. Gets the layers that have to be
  646. applied to the entry
  647. Params: Standard dialog handler parameters
  648. IN HWND hDlg
  649. IN UINT uMsg
  650. IN WPARAM wParam
  651. IN LPARAM lParam
  652. Return: Standard dialog handler return
  653. --*/
  654. {
  655. INT_PTR ipReturn = 0;
  656. switch (uMsg) {
  657. case WM_INITDIALOG:
  658. ipReturn = SelectLayerDlgOnInitDialog(hDlg);
  659. break;
  660. case WM_DESTROY:
  661. ipReturn = SelectLayerDlgOnDestroy();
  662. break;
  663. case WM_COMMAND:
  664. ipReturn = SelectLayerDlgOnCommand(hDlg, wParam);
  665. break;
  666. case WM_NOTIFY:
  667. ipReturn = SelectLayerDlgOnNotify(hDlg, lParam);
  668. break;
  669. default: ipReturn = FALSE;
  670. }
  671. return ipReturn;
  672. }
  673. BOOL
  674. CALLBACK
  675. SelectShims(
  676. IN HWND hDlg,
  677. IN UINT uMsg,
  678. IN WPARAM wParam,
  679. IN LPARAM lParam
  680. )
  681. /*++
  682. SelectShims
  683. Desc: Dialog proc for the third page of the wizard. Gets the shims that have to be
  684. applied to the entry
  685. Params: Standard dialog handler parameters
  686. IN HWND hDlg
  687. IN UINT uMsg
  688. IN WPARAM wParam
  689. IN LPARAM lParam
  690. Return: Standard dialog handler return
  691. --*/
  692. {
  693. INT_PTR ipReturn = 0;
  694. switch (uMsg) {
  695. case WM_INITDIALOG:
  696. ipReturn = SelectShimsDlgOnInitDialog(hDlg);
  697. break;
  698. case WM_COMMAND:
  699. ipReturn = SelectShimsDlgOnCommand(hDlg, wParam);
  700. break;
  701. case WM_TIMER:
  702. ipReturn = SelectShimsDlgOnTimer(hDlg);
  703. break;
  704. case WM_DESTROY:
  705. ipReturn = SelectShimsDlgOnDestroy();
  706. break;
  707. case WM_NOTIFY:
  708. ipReturn = SelectShimsDlgOnNotify(hDlg, lParam);
  709. break;
  710. default:
  711. return FALSE;
  712. }
  713. return ipReturn;
  714. }
  715. INT_PTR
  716. CALLBACK
  717. SelectFiles(
  718. IN HWND hDlg,
  719. IN UINT uMsg,
  720. IN WPARAM wParam,
  721. IN LPARAM lParam
  722. )
  723. /*++
  724. SelectFiles
  725. Desc: Dialog proc for the matching files page of the wizard. This page is
  726. common to both the fix wizard and the apphelp wizard
  727. Params: Standard dialog handler parameters
  728. IN HWND hDlg
  729. IN UINT uMsg
  730. IN WPARAM wParam
  731. IN LPARAM lParam
  732. Return: Standard dialog handler return
  733. --*/
  734. {
  735. INT ipReturn = 0;
  736. switch (uMsg) {
  737. case WM_INITDIALOG:
  738. ipReturn = SelectFilesDlgOnInitDialog(hDlg);
  739. break;
  740. case WM_DESTROY:
  741. ImageList_Destroy(s_hMatchingFileImageList);
  742. s_hMatchingFileImageList = NULL;
  743. ipReturn = TRUE;
  744. break;
  745. case WM_USER_MATCHINGTREE_REFRESH:
  746. ipReturn = SelectFilesDlgOnMatchingTreeRefresh(hDlg);
  747. break;
  748. case WM_NOTIFY:
  749. ipReturn = SelectFilesDlgOnNotify(hDlg, lParam);
  750. break;
  751. case WM_COMMAND:
  752. ipReturn = SelectFilesDlgOnCommand(hDlg, wParam);
  753. break;
  754. default:
  755. return FALSE;
  756. }
  757. return ipReturn;
  758. }
  759. void
  760. FileTreeToggleCheckState(
  761. IN HWND hwndTree,
  762. IN HTREEITEM hItem
  763. )
  764. /*++
  765. FileTreeToggleCheckState
  766. Desc: Changes the check state on the attributes tree.
  767. Params:
  768. IN HWND hwndTree: The handle to the attribute tree (In the matching files page)
  769. IN HTREEITEM hItem: The tree item whose check state we want to change
  770. IN int uMode:
  771. --*/
  772. {
  773. BOOL bSate = TreeView_GetCheckState(hwndTree, hItem) ? TRUE:FALSE;
  774. TreeView_SetCheckState(hwndTree, hItem, !bSate);
  775. }
  776. void
  777. AddMatchingFileToTree(
  778. IN HWND hwndTree,
  779. IN PMATCHINGFILE pMatch,
  780. IN BOOL bAddToMatchingList
  781. )
  782. /*++
  783. AddMatchingFileToTree
  784. Desc: Creates a new tree item for pMatch and adds it to the matching tree. If bAddToMatchingList
  785. is TRUE, also adds it to the PMATCHINGFLE for the entry
  786. Params:
  787. IN HWND hwndTree: The matching tree
  788. IN PMATCHINGFILE pMatch: The PMATCHINGFILE to add to the tree
  789. IN BOOL bAddToMatchingList: This will be false, when we are
  790. populating for edit. The pMatch is already in the list and we do not want to
  791. add it again
  792. Return:
  793. void
  794. --*/
  795. {
  796. TVINSERTSTRUCT is;
  797. TCHAR* pszFileNameForImage = NULL;
  798. if (g_pCurrentWizard == NULL || pMatch == NULL) {
  799. assert(FALSE);
  800. return;
  801. }
  802. if (bAddToMatchingList) {
  803. //
  804. // Now add this pMatch to the list for this entry.
  805. //
  806. pMatch->pNext = g_pCurrentWizard->m_Entry.pFirstMatchingFile;
  807. g_pCurrentWizard->m_Entry.pFirstMatchingFile = pMatch;
  808. }
  809. if (g_pCurrentWizard->m_Entry.strFullpath.Length()
  810. && (pMatch->strFullName == g_pCurrentWizard->m_Entry.strFullpath)) {
  811. pMatch->strMatchName = TEXT("*");
  812. }
  813. is.hParent = TVI_ROOT;
  814. is.item.lParam = (LPARAM)pMatch;
  815. is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  816. if (pMatch->strMatchName == TEXT("*")) {
  817. TCHAR szTemp[MAX_PATH + 100]; // 100 is for any text that we might need to add to the file. Such as "Program being fixed"
  818. *szTemp = 0;
  819. StringCchPrintf(szTemp,
  820. ARRAYSIZE(szTemp),
  821. TEXT("%s ( %s )"),
  822. GetString(IDS_MAINEXE),
  823. g_pCurrentWizard->m_Entry.strExeName.pszString);
  824. is.item.pszText = szTemp;
  825. is.hInsertAfter = TVI_FIRST;
  826. if (pMatch->strFullName.Length()) {
  827. pszFileNameForImage = pMatch->strFullName.pszString;
  828. } else {
  829. pszFileNameForImage = g_pCurrentWizard->m_Entry.strExeName.pszString;
  830. }
  831. } else {
  832. is.item.pszText = pMatch->strMatchName;
  833. is.hInsertAfter = TVI_LAST;
  834. if (pMatch->strFullName.Length()) {
  835. pszFileNameForImage = pMatch->strFullName.pszString;
  836. } else {
  837. pszFileNameForImage = pMatch->strMatchName.pszString;
  838. }
  839. }
  840. is.item.iImage = LookupFileImage(s_hMatchingFileImageList,
  841. pszFileNameForImage,
  842. 0,
  843. 0,
  844. 0);
  845. is.item.iSelectedImage = is.item.iImage;
  846. HTREEITEM hParent = TreeView_InsertItem(hwndTree, &is);
  847. is.hInsertAfter = TVI_LAST;
  848. is.hParent = hParent;
  849. is.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_STATE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  850. is.item.iSelectedImage = is.item.iImage = IMAGE_ATTRIBUTE_MATCHTREE;
  851. TCHAR szItem[260];
  852. PATTRINFO_NEW pAttr = pMatch->attributeList.pAttribute;
  853. for (DWORD dwIndex = 0; dwIndex < ATTRIBUTE_COUNT; ++dwIndex) {
  854. *szItem = 0;
  855. if (pAttr[dwIndex].dwFlags & ATTRIBUTE_AVAILABLE) {
  856. if (!SdbFormatAttribute(&pAttr[dwIndex], szItem, ARRAYSIZE(szItem))) {
  857. continue;
  858. }
  859. int iPos = TagToIndex(pAttr[dwIndex].tAttrID);
  860. if (iPos == -1) {
  861. continue;
  862. }
  863. if (pMatch->dwMask & (1 << (iPos + 1))) {
  864. is.item.state = INDEXTOSTATEIMAGEMASK(2); //Selected
  865. } else {
  866. is.item.state = INDEXTOSTATEIMAGEMASK(1); //Unselected
  867. }
  868. is.item.stateMask = TVIS_STATEIMAGEMASK;
  869. is.item.pszText = szItem;
  870. is.item.lParam = pAttr[dwIndex].tAttrID;
  871. is.item.iImage = is.item.iSelectedImage = IMAGE_ATTRIBUTE_MATCHTREE;
  872. TreeView_InsertItem(hwndTree, &is);
  873. }
  874. }
  875. TreeView_Expand(hwndTree, hParent, TVE_EXPAND);
  876. TreeView_SelectItem(hwndTree, hParent);
  877. }
  878. PMATCHINGFILE
  879. GetMatchingFileFromAttributes(
  880. IN CSTRING& strFullPath,
  881. IN CSTRING& strRelativePath,
  882. IN PATTRINFO pAttrInfo
  883. )
  884. /*++
  885. GetMatchingFileFromAttributes
  886. Desc: This function takes a PATTRINFO and makes a PMATCHINGFILE out of it and returns that
  887. Params:
  888. IN CSTRING &strFullPath: The full path of the matching file
  889. IN CSTRING &strRelativePath: The relative path of the matching file w.r.t the program
  890. file being fixed
  891. IN PATTRINFO pAttrInfo: The pointer to the array of attributes
  892. Return:
  893. The newly created PMATCHINGFILE if successful
  894. NULL otherwise
  895. --*/
  896. {
  897. PMATCHINGFILE pMatch = new MATCHINGFILE;
  898. if (pMatch == NULL) {
  899. MEM_ERR;
  900. goto error_handler;
  901. }
  902. pMatch->strFullName = strFullPath;
  903. pMatch->strMatchName = strRelativePath;
  904. pMatch->attributeList = pAttrInfo;
  905. return pMatch;
  906. error_handler:
  907. if (pMatch) {
  908. delete pMatch;
  909. }
  910. return NULL;
  911. }
  912. void
  913. HandleAddMatchingFile(
  914. IN HWND hdlg,
  915. IN CSTRING& strFilename,
  916. IN CSTRING& strRelativePath,
  917. IN DWORD dwMask //(DEFAULT_MASK)
  918. )
  919. /*++
  920. HandleAddMatchingFile
  921. Desc: This is the interface function that should be called when we have a matching file and
  922. want to add it.
  923. This routine calls SdbGetFileAttributes() to get the attributes for
  924. the file and then calls GetMatchingFileFromAttributes() to get a PMATCHINGFILE
  925. and AddMatchingFileToTree() to add this PMATCHINGFILE to the tree and to the entry.
  926. Params:
  927. IN HWND hdlg: The matching file wizard page
  928. IN CSTRING &strFilename: The complete path of the matching file
  929. IN CSTRING &strRelativePath: The relative path w.r.t to the program file being fixed
  930. IN DWORD dwMask (DEFAULT_MASK): This is helpful when we are updating the
  931. attributes (showing all attributes) during editing.
  932. This then will contain the previous flags and once the attribute tree is refreshed,
  933. will help us in selecting them,
  934. Return:
  935. void
  936. --*/
  937. {
  938. DWORD dwAttrCount;
  939. BOOL bAlreadyExists = FALSE;
  940. HWND hwndTree = GetDlgItem(hdlg, IDC_FILELIST);
  941. PMATCHINGFILE pMatch = NULL;
  942. PATTRINFO pAttrInfo = NULL;
  943. CSTRING strMessage;
  944. if (g_pCurrentWizard == NULL) {
  945. assert(NULL);
  946. return;
  947. }
  948. pMatch = g_pCurrentWizard->m_Entry.pFirstMatchingFile;
  949. while (pMatch) {
  950. if (pMatch->strMatchName == strRelativePath) {
  951. //
  952. // Already exists .. do not allow
  953. //
  954. bAlreadyExists = TRUE;
  955. break;
  956. } else if (pMatch->strMatchName == TEXT("*")
  957. && strFilename == g_pCurrentWizard->m_Entry.strFullpath) {
  958. //
  959. // This function is also called to add the matching file info for the
  960. // program file being fixed. So we do not make a check in the beginning
  961. // if the full path is same as the the program being fixed
  962. //
  963. bAlreadyExists = TRUE;
  964. break;
  965. }
  966. pMatch = pMatch->pNext;
  967. }
  968. if (bAlreadyExists == TRUE) {
  969. MessageBox(hdlg,
  970. CSTRING(IDS_MATCHFILEEXISTS),
  971. g_szAppName,
  972. MB_ICONWARNING);
  973. return;
  974. }
  975. //
  976. // Call the attribute manager to get all the attributes for this file.
  977. //
  978. if (SdbGetFileAttributes(strFilename, &pAttrInfo, &dwAttrCount)) {
  979. pMatch = GetMatchingFileFromAttributes(strFilename,
  980. strRelativePath,
  981. pAttrInfo);
  982. if (pMatch) {
  983. pMatch->dwMask = dwMask;
  984. } else {
  985. assert(FALSE);
  986. }
  987. if (pAttrInfo) {
  988. SdbFreeFileAttributes(pAttrInfo);
  989. }
  990. SendMessage(s_hwndTree, WM_SETREDRAW, FALSE, 0);
  991. AddMatchingFileToTree(hwndTree, pMatch, TRUE);
  992. SendMessage(s_hwndTree, WM_SETREDRAW, TRUE, 0);
  993. } else {
  994. //
  995. // We could not get the Attributes... Probably the file was deleted
  996. //
  997. strMessage.Sprintf(GetString(IDS_MATCHINGFILE_DELETED), (LPCTSTR)strFilename);
  998. MessageBox(hdlg, (LPCTSTR) strMessage, g_szAppName, MB_ICONWARNING);
  999. }
  1000. }
  1001. BOOL
  1002. HandleAttributeTreeNotification(
  1003. IN HWND hdlg,
  1004. IN LPARAM lParam
  1005. )
  1006. /*++
  1007. HandleAttributeTreeNotification
  1008. Desc: Handle all the notifications we care about for the matching file tree.
  1009. Params:
  1010. IN HWND hdlg: The mathching file wizard page
  1011. IN LPARAM lParam: the lParam that comes with WM_NOTIFY
  1012. Return:
  1013. void
  1014. --*/
  1015. {
  1016. HWND hwndTree = GetDlgItem(hdlg, IDC_FILELIST);
  1017. LPNMHDR pnm = (LPNMHDR)lParam;
  1018. HWND hwndButton;
  1019. switch (pnm->code) {
  1020. case NM_CLICK:
  1021. {
  1022. TVHITTESTINFO HitTest;
  1023. HTREEITEM hItem;
  1024. GetCursorPos(&HitTest.pt);
  1025. ScreenToClient(hwndTree, &HitTest.pt);
  1026. TreeView_HitTest(hwndTree, &HitTest);
  1027. if (HitTest.flags & TVHT_ONITEMSTATEICON) {
  1028. FileTreeToggleCheckState(hwndTree, HitTest.hItem);
  1029. } else if (HitTest.flags & TVHT_ONITEMLABEL) {
  1030. hItem = TreeView_GetParent(hwndTree, HitTest.hItem);
  1031. //
  1032. // Enable Remove Files button only if we are on a matching file item and not on
  1033. // an attribute item
  1034. //
  1035. ENABLEWINDOW(GetDlgItem(hdlg, IDC_REMOVEFILES),
  1036. hItem == NULL);
  1037. }
  1038. break;
  1039. }
  1040. case TVN_KEYDOWN:
  1041. {
  1042. LPNMTVKEYDOWN lpKeyDown = (LPNMTVKEYDOWN)lParam;
  1043. HTREEITEM hItem;
  1044. if (lpKeyDown->wVKey == VK_SPACE) {
  1045. hItem = TreeView_GetSelection(hwndTree);
  1046. if (hItem != NULL) {
  1047. FileTreeToggleCheckState(hwndTree, hItem);
  1048. }
  1049. }
  1050. break;
  1051. }
  1052. default:
  1053. return FALSE;
  1054. }
  1055. return TRUE;
  1056. }
  1057. void
  1058. CShimWizard::WipeEntry(
  1059. IN BOOL bMatching,
  1060. IN BOOL bShims,
  1061. IN BOOL bLayer,
  1062. IN BOOL bFlags
  1063. )
  1064. /*++
  1065. WipeEntry
  1066. Desc: Removes stuff from m_Entry
  1067. Params:
  1068. IN BOOL bMatching: Should we remove all the matching files from m_Entry
  1069. IN BOOL bShims: Should we remove all the shims from m_Entry
  1070. IN BOOL bLayer: Should we remove all the layers from m_Entry
  1071. IN BOOL bFlags: Should we remove all the flags from m_Entry
  1072. Return:
  1073. void
  1074. --*/
  1075. {
  1076. //
  1077. // Delete mathcing files, if asked to
  1078. //
  1079. if (bMatching) {
  1080. DeleteMatchingFiles(m_Entry.pFirstMatchingFile);
  1081. m_Entry.pFirstMatchingFile = NULL;
  1082. }
  1083. //
  1084. // Delete shims, if asked to
  1085. //
  1086. if (bShims) {
  1087. DeleteShimFixList(m_Entry.pFirstShim);
  1088. m_Entry.pFirstShim = NULL;
  1089. }
  1090. //
  1091. // Delete layers, if asked to
  1092. //
  1093. if (bLayer) {
  1094. DeleteLayerFixList(m_Entry.pFirstLayer);
  1095. m_Entry.pFirstLayer = NULL;
  1096. }
  1097. //
  1098. // Delete flags, if asked to
  1099. //
  1100. if (bFlags) {
  1101. DeleteFlagFixList(m_Entry.pFirstFlag);
  1102. m_Entry.pFirstFlag = NULL;
  1103. }
  1104. }
  1105. void
  1106. AddToMatchingFilesList(
  1107. IN OUT PMATCHINGFILE* ppMatchListHead,
  1108. IN CSTRING& strFileName,
  1109. IN CSTRING& strRelativePath
  1110. )
  1111. /*++
  1112. AddToMatchingFilesList
  1113. Desc: Adds a PMATCHINGFILE for strFileName, strRelativePath and adds it to ppMatchListHead
  1114. Params:
  1115. IN OUT PMATCHINGFILE *ppMatchListHead: Pointer to head of a list of PMATCHINGFILE
  1116. IN CSTRING &strFileName: Full path of the matching file
  1117. IN CSTRING &strRelativePath: Relative path of the matching file w.r.t
  1118. to the program file being fixed
  1119. Notes: This function is used, when we are using the auto-generate feature.
  1120. The WalkDirectory(..) gets the different files from the various directories
  1121. and then calls this function.
  1122. This function creates a PMATCHINGFILE from the name of the file and then it
  1123. adds the PMATCHINGFILE to a list. The list is sorted on the basis of the
  1124. non-inc. size of the matching file found.
  1125. When WalkDirectory finally returns to GrabMatchingInfo, it takes the first n number of
  1126. PMATCHINGFILE (they are the largest ones) and adds them to the tree.
  1127. --*/
  1128. {
  1129. PATTRINFO pAttrInfo = NULL;
  1130. DWORD dwAttrCount = 0;
  1131. PMATCHINGFILE pMatch = NULL;
  1132. PATTRINFO_NEW pAttr = NULL;
  1133. DWORD dwSize = 0;
  1134. DWORD dwSizeOther = 0;
  1135. PMATCHINGFILE pMatchPrev = NULL;
  1136. PMATCHINGFILE pMatchTemp = NULL;
  1137. if (!SdbGetFileAttributes(strFileName, &pAttrInfo, &dwAttrCount)) {
  1138. ASSERT(FALSE);
  1139. return;
  1140. }
  1141. pMatch = GetMatchingFileFromAttributes(strFileName,
  1142. strRelativePath,
  1143. pAttrInfo);
  1144. if (pMatch == NULL) {
  1145. return;
  1146. }
  1147. pAttr = pMatch->attributeList.pAttribute;
  1148. //
  1149. // Get the size attribute, we need this so that we can sort files based on their size
  1150. //
  1151. GET_SIZE_ATTRIBUTE(pAttr, dwAttrCount, dwSize);
  1152. //
  1153. // Is the list empty ?
  1154. //
  1155. if (*ppMatchListHead == NULL) {
  1156. *ppMatchListHead = pMatch;
  1157. return;
  1158. }
  1159. //
  1160. // Is the first element in the list smaller than this one ?
  1161. //
  1162. pAttr = (*ppMatchListHead)->attributeList.pAttribute;
  1163. GET_SIZE_ATTRIBUTE(pAttr, dwAttrCount, dwSizeOther);
  1164. if (dwSize > dwSizeOther) {
  1165. pMatch->pNext = *ppMatchListHead;
  1166. *ppMatchListHead = pMatch;
  1167. return;
  1168. }
  1169. //
  1170. // Else insert at the proper position.
  1171. //
  1172. pMatchPrev = *ppMatchListHead;
  1173. pMatchTemp = pMatchPrev->pNext;
  1174. //
  1175. // Look at all the matching files in the list headed by *ppMatchListHead
  1176. // and add this matching file in its correct position so that the list is
  1177. // sorted in non-increasing order of size
  1178. //
  1179. while (pMatchTemp) {
  1180. pAttr = pMatchTemp->attributeList.pAttribute;
  1181. GET_SIZE_ATTRIBUTE(pAttr, dwAttrCount, dwSizeOther);
  1182. if (dwSize > dwSizeOther) {
  1183. //
  1184. // We have found the position where we need to insert.
  1185. //
  1186. break;
  1187. }
  1188. pMatchPrev = pMatchTemp;
  1189. pMatchTemp = pMatchTemp->pNext;
  1190. }
  1191. pMatch->pNext = pMatchTemp;
  1192. pMatchPrev->pNext = pMatch;
  1193. }
  1194. void
  1195. CShimWizard::WalkDirectory(
  1196. IN OUT PMATCHINGFILE* ppMatchListHead,
  1197. IN LPCTSTR pszDir,
  1198. IN int nDepth
  1199. )
  1200. /*++
  1201. CShimWizard::WalkDirectory
  1202. Desc: Walks the specified directory and gets matching files when using the AutoGenerate feature
  1203. Takes a pointer to pointer to a PMATCHING and pouplates it with the matching files found.
  1204. This function is called only by GrabMatchingInfo
  1205. Params:
  1206. IN OUT PMATCHINGFILE* ppMatchListHead: Pointer to head of a list of PMATCHINGFILE
  1207. IN LPCTSTR pszDir: The dir from where we should start
  1208. IN int nDepth The depth of sub-directories to look into
  1209. Return:
  1210. void
  1211. Notes: We restrict the depth till where we should recurse and so there will be no stack overflow
  1212. --*/
  1213. {
  1214. HANDLE hFile;
  1215. WIN32_FIND_DATA Data;
  1216. TCHAR szCurrentDir[MAX_PATH_BUFFSIZE + 1];
  1217. TCHAR szDirectory[MAX_PATH];
  1218. CSTRING szShortName;
  1219. CSTRING strFileName;
  1220. CSTRING strRelativePath;
  1221. int nFiles = 0;
  1222. DWORD dwResult = 0;
  1223. *szCurrentDir = *szDirectory = 0;
  1224. SafeCpyN(szDirectory, pszDir, ARRAYSIZE(szDirectory));
  1225. ADD_PATH_SEPARATOR(szDirectory, ARRAYSIZE(szDirectory));
  1226. //
  1227. // This is to allow recursion and only look into only 2 level subdirs.
  1228. //
  1229. if (nDepth >= 2) {
  1230. return;
  1231. }
  1232. szShortName = m_Entry.strFullpath;
  1233. szShortName.ShortFilename();
  1234. //
  1235. // Save the current directory
  1236. //
  1237. dwResult = GetCurrentDirectory(MAX_PATH, szCurrentDir);
  1238. if (dwResult == 0 || dwResult >= MAX_PATH) {
  1239. assert(FALSE);
  1240. Dbg(dlError, "WalkDirectory", "GetCurrentDirectory returned %d", dwResult);
  1241. return;
  1242. }
  1243. ADD_PATH_SEPARATOR(szCurrentDir, ARRAYSIZE(szCurrentDir));
  1244. //
  1245. // Set to the new directory
  1246. //
  1247. SetCurrentDirectory(szDirectory);
  1248. hFile = FindFirstFile(TEXT("*.*"), &Data);
  1249. if (INVALID_HANDLE_VALUE == hFile) {
  1250. SetCurrentDirectory(szCurrentDir);
  1251. return;
  1252. }
  1253. //
  1254. // Generate automated matching file information.
  1255. //
  1256. do {
  1257. if (0 == (Data.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))) {
  1258. //
  1259. // Hidden or system files are not included when we do a auto-generate matching info
  1260. //
  1261. if (FILE_ATTRIBUTE_DIRECTORY == (Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
  1262. //
  1263. // We found a directory
  1264. //
  1265. if (TEXT('.') != Data.cFileName[0]) {
  1266. //
  1267. // Let us get the matching files from this directory
  1268. //
  1269. WalkDirectory(ppMatchListHead, Data.cFileName, nDepth + 1);
  1270. }
  1271. } else {
  1272. //
  1273. // This is a file and we should now try to add it
  1274. //
  1275. ++nFiles;
  1276. if (nFiles >= MAX_FILES) {
  1277. //
  1278. // We have found enough files, later we should take the largest MAX_AUTO_MATCH from these
  1279. //
  1280. break;
  1281. }
  1282. if (0 == (Data.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))) {
  1283. if (szDirectory[0] == TEXT('.')) {
  1284. strFileName.Sprintf(TEXT("%s%s"),
  1285. szCurrentDir,
  1286. Data.cFileName);
  1287. } else {
  1288. strFileName.Sprintf(TEXT("%s%s%s"),
  1289. szCurrentDir,
  1290. szDirectory,
  1291. Data.cFileName);
  1292. }
  1293. strRelativePath = strFileName;
  1294. strRelativePath.RelativeFile(g_pCurrentWizard->m_Entry.strFullpath);
  1295. //
  1296. // The main exe has been added before calling WalkDirectory()
  1297. //
  1298. if (strFileName != g_pCurrentWizard->m_Entry.strFullpath) {
  1299. //
  1300. // Add this to the list of matching files. Finally we will choose the
  1301. // largest MAX_AUTO_MATCH from them, to serve as the matching files for the present
  1302. // entry
  1303. //
  1304. AddToMatchingFilesList(ppMatchListHead,
  1305. strFileName,
  1306. strRelativePath);
  1307. }
  1308. }
  1309. }
  1310. }
  1311. } while (FindNextFile(hFile, &Data));
  1312. FindClose(hFile);
  1313. //
  1314. // Restore old directory
  1315. //
  1316. SetCurrentDirectory(szCurrentDir);
  1317. }
  1318. void
  1319. CShimWizard::GrabMatchingInfo(
  1320. IN HWND hdlg
  1321. )
  1322. /*++
  1323. CShimWizard::GrabMatchingInfo
  1324. Desc: Handles the pressinG of "Auto-Generate button. Removes all the existing matching files
  1325. for m_Entry
  1326. Params:
  1327. IN HWND hdlg: The matching file wizard page
  1328. Return:
  1329. void
  1330. --*/
  1331. {
  1332. PMATCHINGFILE pMatchTemp;
  1333. PMATCHINGFILE pMatchNext;
  1334. TCHAR* pchTemp;
  1335. TCHAR szCurrentDir[MAX_PATH];
  1336. TCHAR szDir[MAX_PATH]; // The directory of the file being fixed
  1337. PMATCHINGFILE pMatchingFileHead = NULL;
  1338. int iCount = 0;
  1339. DWORD dwResult = 0;
  1340. *szCurrentDir = *szDir = 0;
  1341. dwResult = GetCurrentDirectory(ARRAYSIZE(szCurrentDir), szCurrentDir);
  1342. if (dwResult == 0 || dwResult >= ARRAYSIZE(szCurrentDir)) {
  1343. assert(FALSE);
  1344. Dbg(dlError, "[CShimWizard::GrabMatchingInfo]: GetCurrentDirectory failed");
  1345. return;
  1346. }
  1347. //
  1348. // Get the complete path of the program file being fixed, so that
  1349. // we can generate relative file paths for the matching files
  1350. //
  1351. if (g_pCurrentWizard->CheckAndSetLongFilename(hdlg, IDS_GETCOMPLETEPATH) == FALSE) {
  1352. return;
  1353. }
  1354. //
  1355. // Remove any matching if present.
  1356. //
  1357. TreeDeleteAll(s_hwndTree);
  1358. g_pCurrentWizard->WipeEntry(TRUE, FALSE, FALSE, FALSE);
  1359. *szDir = 0;
  1360. SafeCpyN(szDir, (LPCTSTR)g_pCurrentWizard->m_Entry.strFullpath, ARRAYSIZE(szDir));
  1361. pchTemp = _tcsrchr(szDir, TEXT('\\'));
  1362. if (pchTemp) {
  1363. //
  1364. // Make sure that we get the trailing slash. Otherwise we migth have problems if we haev file
  1365. // names as c:\abc.exe
  1366. //
  1367. *pchTemp = 0;
  1368. } else {
  1369. //
  1370. // g_pCurrentWizard->m_Entry.strFullpath did not have a complete path!!
  1371. // We should not have come in this function in the first place
  1372. //
  1373. assert(FALSE);
  1374. Dbg(dlError, "[CShimWizard::GrabMatchingInfo]: Did not have a complete path for g_pCurrentWizard->m_Entry.strFullpath");
  1375. return;
  1376. }
  1377. SetCurrentDirectory(szDir);
  1378. //
  1379. // Generate automated matching file information. pMatchingFileHead will
  1380. // be the head of a linked list of all the matching files that we found
  1381. //
  1382. WalkDirectory(&pMatchingFileHead, TEXT("."), 0);
  1383. //
  1384. // Now, take the first MAX_AUTO_MATCH entries and discard the rest.
  1385. //
  1386. SendMessage(s_hwndTree, WM_SETREDRAW, FALSE, 0);
  1387. while (iCount < MAX_AUTO_MATCH && pMatchingFileHead) {
  1388. pMatchNext = pMatchingFileHead->pNext;
  1389. //
  1390. // NOTE: AddMatchingFileToTree() will change the pMatchingFileHead->pNext,
  1391. // when it adds it to the list of matching files for the entry !!!.
  1392. // So we have saved the pMatchingFileHead->pNext earlier.
  1393. //
  1394. AddMatchingFileToTree(s_hwndTree, pMatchingFileHead, TRUE);
  1395. ++iCount;
  1396. pMatchingFileHead = pMatchNext;
  1397. }
  1398. SendMessage(s_hwndTree, WM_SETREDRAW, TRUE, 0);
  1399. //
  1400. // Remove the other ones.
  1401. //
  1402. while (pMatchingFileHead) {
  1403. pMatchTemp = pMatchingFileHead->pNext;
  1404. delete pMatchingFileHead;
  1405. pMatchingFileHead = pMatchTemp;
  1406. }
  1407. if (g_pCurrentWizard) {
  1408. //
  1409. // Add the file being fixed.
  1410. //
  1411. HandleAddMatchingFile(hdlg,
  1412. g_pCurrentWizard->m_Entry.strFullpath,
  1413. g_pCurrentWizard->m_Entry.strExeName);
  1414. }
  1415. SetCurrentDirectory(szCurrentDir);
  1416. }
  1417. void
  1418. AddModuleToListView(
  1419. IN PTSTR pszModuleName,
  1420. IN UINT uOption,
  1421. IN HWND hwndModuleList
  1422. )
  1423. /*++
  1424. AddModuleToListView
  1425. Desc: Adds the specified module to the list view.
  1426. Params:
  1427. IN PTSTR pszModuleName: Name of the module to be included or excluded
  1428. IN UINT uOption: Either INCLUDE or EXCLUDE
  1429. IN HWND hwndModuleList: Handle to the list view
  1430. Return;
  1431. void
  1432. --*/
  1433. {
  1434. LVITEM lvi;
  1435. int nIndex;
  1436. lvi.mask = LVIF_TEXT | LVIF_PARAM;
  1437. lvi.lParam = uOption == INCLUDE ? 1 : 0;
  1438. lvi.pszText = uOption == INCLUDE ? GetString(IDS_INCLUDE) : GetString(IDS_EXCLUDE);
  1439. lvi.iItem = ListView_GetItemCount(hwndModuleList);
  1440. lvi.iSubItem = COLUMN_TYPE;
  1441. nIndex = ListView_InsertItem(hwndModuleList, &lvi);
  1442. ListView_SetItemText(hwndModuleList,
  1443. nIndex,
  1444. COLUMN_NAME,
  1445. pszModuleName);
  1446. }
  1447. void
  1448. HandleModuleListNotification(
  1449. IN HWND hdlg,
  1450. IN LPARAM lParam
  1451. )
  1452. /*++
  1453. HandleModuleListNotification
  1454. Desc: Handle all the notifications we care about for the list in the params
  1455. dialog
  1456. Params:
  1457. IN HWND hdlg: The handle to the Params Dialog Box
  1458. IN LPARAM lParam: lParam that comes with WM_NOTIFY
  1459. Return:
  1460. void
  1461. --*/
  1462. {
  1463. LPNMHDR pnm = (LPNMHDR)lParam;
  1464. HWND hwndModuleList = GetDlgItem(hdlg, IDC_MOD_LIST);
  1465. switch (pnm->code) {
  1466. case NM_CLICK:
  1467. {
  1468. LVHITTESTINFO lvhti;
  1469. GetCursorPos(&lvhti.pt);
  1470. ScreenToClient(hwndModuleList, &lvhti.pt);
  1471. ListView_HitTest(hwndModuleList, &lvhti);
  1472. //
  1473. // If the user clicked on a list view item,
  1474. // enable the Remove button
  1475. //
  1476. if (lvhti.flags & LVHT_ONITEMLABEL) {
  1477. ENABLEWINDOW(GetDlgItem(hdlg, IDC_REMOVEFROMLIST), TRUE);
  1478. } else {
  1479. ENABLEWINDOW(GetDlgItem(hdlg, IDC_REMOVEFROMLIST), FALSE);
  1480. }
  1481. break;
  1482. }
  1483. default:
  1484. break;
  1485. }
  1486. }
  1487. INT_PTR CALLBACK
  1488. ParamsDlgProc(
  1489. IN HWND hdlg,
  1490. IN UINT uMsg,
  1491. IN WPARAM wParam,
  1492. IN LPARAM lParam
  1493. )
  1494. /*++
  1495. OptionsDlgProc
  1496. Description: Handles messages for the options dialog.
  1497. Params: Standard dialog handler parameters
  1498. IN HWND hDlg
  1499. IN UINT uMsg
  1500. IN WPARAM wParam
  1501. IN LPARAM lParam
  1502. Return: Standard dialog handler return
  1503. --*/
  1504. {
  1505. TCHAR szTitle[MAX_PATH];
  1506. int wCode = LOWORD(wParam);
  1507. int wNotifyCode = HIWORD(wParam);
  1508. static TYPE s_type = TYPE_UNKNOWN;
  1509. HWND hwndModuleList = GetDlgItem(hdlg, IDC_MOD_LIST);
  1510. switch (uMsg) {
  1511. case WM_INITDIALOG:
  1512. {
  1513. s_type = ConvertLparam2Type(lParam);
  1514. SetWindowLongPtr(hdlg, DWLP_USER, lParam);
  1515. ENABLEWINDOW(GetDlgItem(hdlg, IDC_REMOVEFROMLIST), FALSE);
  1516. InsertColumnIntoListView(hwndModuleList, GetString(IDS_TYPE), COLUMN_TYPE, 30);
  1517. InsertColumnIntoListView(hwndModuleList, GetString(IDS_MODULENAME), COLUMN_NAME, 70);
  1518. ListView_SetExtendedListViewStyle(hwndModuleList, LVS_EX_LABELTIP |LVS_EX_FULLROWSELECT);
  1519. //
  1520. // Restrict the length of the command line to MAX_COMMAND_LINE chars
  1521. //
  1522. SendMessage(GetDlgItem(hdlg, IDC_SHIM_CMD_LINE),
  1523. EM_LIMITTEXT,
  1524. (WPARAM)MAX_COMMAND_LINE,
  1525. (LPARAM)0);
  1526. //
  1527. // Restrict the length of the module name to MAX_MODULE_NAME
  1528. //
  1529. SendMessage(GetDlgItem(hdlg, IDC_MOD_NAME),
  1530. EM_LIMITTEXT,
  1531. (WPARAM)MAX_MODULE_NAME,
  1532. (LPARAM)0);
  1533. if (s_type == FIX_LIST_SHIM) {
  1534. PSHIM_FIX_LIST psfl = (PSHIM_FIX_LIST)lParam;
  1535. if (psfl->pShimFix == NULL) {
  1536. assert(FALSE);
  1537. break;
  1538. }
  1539. StringCchPrintf(szTitle,
  1540. ARRAYSIZE(szTitle),
  1541. GetString(IDS_OPTIONS),
  1542. psfl->pShimFix->strName);
  1543. SetWindowText(hdlg, szTitle);
  1544. if (psfl->strCommandLine.Length()) {
  1545. SetDlgItemText(hdlg, IDC_SHIM_CMD_LINE, psfl->strCommandLine);
  1546. }
  1547. CheckDlgButton(hdlg, IDC_INCLUDE, BST_CHECKED);
  1548. //
  1549. // Add any modules to the list view
  1550. //
  1551. PSTRLIST strlTemp = psfl->strlInExclude.m_pHead;
  1552. while (strlTemp) {
  1553. AddModuleToListView(strlTemp->szStr,
  1554. strlTemp->data,
  1555. hwndModuleList);
  1556. strlTemp = strlTemp->pNext;
  1557. }
  1558. } else {
  1559. PFLAG_FIX_LIST pffl = (PFLAG_FIX_LIST)lParam;
  1560. if (pffl->pFlagFix == NULL) {
  1561. assert(FALSE);
  1562. break;
  1563. }
  1564. StringCchPrintf(szTitle,
  1565. ARRAYSIZE(szTitle),
  1566. GetString(IDS_PRAMS_DLGCAPTION),
  1567. pffl->pFlagFix->strName);
  1568. SetWindowText(hdlg, szTitle);
  1569. if (pffl->strCommandLine.Length()) {
  1570. SetDlgItemText(hdlg, IDC_SHIM_CMD_LINE, pffl->strCommandLine);
  1571. }
  1572. ENABLEWINDOW(GetDlgItem(hdlg, IDC_MOD_NAME), FALSE);
  1573. ENABLEWINDOW(GetDlgItem(hdlg, IDC_INCLUDE), FALSE);
  1574. ENABLEWINDOW(GetDlgItem(hdlg, IDC_EXCLUDE), FALSE);
  1575. ENABLEWINDOW(GetDlgItem(hdlg, IDC_ADDTOLIST), FALSE);
  1576. ENABLEWINDOW(GetDlgItem(hdlg, IDC_REMOVEFROMLIST), FALSE);
  1577. }
  1578. SendMessage(hdlg,
  1579. WM_COMMAND,
  1580. MAKEWPARAM(IDC_MOD_NAME, EN_CHANGE),
  1581. 0);
  1582. break;
  1583. }
  1584. case WM_NOTIFY:
  1585. HandleModuleListNotification(hdlg, lParam);
  1586. break;
  1587. case WM_COMMAND:
  1588. switch (wCode) {
  1589. case IDC_MOD_NAME:
  1590. {
  1591. if (EN_CHANGE == HIWORD(wParam)) {
  1592. TCHAR szModName[MAX_MODULE_NAME + 1];
  1593. GetDlgItemText(hdlg, IDC_MOD_NAME, szModName, ARRAYSIZE(szModName));
  1594. if (CSTRING::Trim(szModName)) {
  1595. ENABLEWINDOW(GetDlgItem(hdlg, IDC_ADDTOLIST), TRUE);
  1596. } else {
  1597. ENABLEWINDOW(GetDlgItem(hdlg, IDC_ADDTOLIST), FALSE);
  1598. }
  1599. }
  1600. break;
  1601. }
  1602. case IDC_ADDTOLIST:
  1603. {
  1604. TCHAR szModName[MAX_MODULE_NAME + 1] = _T("");
  1605. UINT uInclude, uExclude;
  1606. GetDlgItemText(hdlg, IDC_MOD_NAME, szModName, ARRAYSIZE(szModName));
  1607. CSTRING::Trim(szModName);
  1608. uInclude = IsDlgButtonChecked(hdlg, IDC_INCLUDE);
  1609. uExclude = IsDlgButtonChecked(hdlg, IDC_EXCLUDE);
  1610. if ((BST_CHECKED == uInclude) || (BST_CHECKED == uExclude)) {
  1611. AddModuleToListView(szModName, uInclude, hwndModuleList);
  1612. SetDlgItemText(hdlg, IDC_MOD_NAME, _T(""));
  1613. SetFocus(GetDlgItem(hdlg, IDC_MOD_NAME));
  1614. } else {
  1615. SetFocus(GetDlgItem(hdlg, IDC_INCLUDE));
  1616. }
  1617. break;
  1618. }
  1619. case IDC_REMOVEFROMLIST:
  1620. {
  1621. int nIndex;
  1622. nIndex = ListView_GetSelectionMark(hwndModuleList);
  1623. ListView_DeleteItem(hwndModuleList, nIndex);
  1624. ENABLEWINDOW(GetDlgItem(hdlg, IDC_REMOVEFROMLIST), FALSE);
  1625. SetFocus(GetDlgItem(hdlg, IDC_MOD_NAME));
  1626. break;
  1627. }
  1628. case IDOK:
  1629. {
  1630. //
  1631. // Now add the commandline
  1632. //
  1633. if (s_type == FIX_LIST_SHIM) {
  1634. PSHIM_FIX_LIST psfl = (PSHIM_FIX_LIST)GetWindowLongPtr(hdlg, DWLP_USER);
  1635. TCHAR szTemp[MAX_COMMAND_LINE + 1];
  1636. psfl->strCommandLine.Release();
  1637. psfl->strlInExclude.DeleteAll();
  1638. *szTemp = 0;
  1639. GetDlgItemText(hdlg,
  1640. IDC_SHIM_CMD_LINE,
  1641. szTemp,
  1642. ARRAYSIZE(szTemp));
  1643. if (CSTRING::Trim(szTemp)) {
  1644. psfl->strCommandLine = szTemp;
  1645. }
  1646. //
  1647. // Add the InExclude
  1648. //
  1649. int iTotal = ListView_GetItemCount(hwndModuleList);
  1650. for (int iIndex = 0; iIndex < iTotal; ++iIndex) {
  1651. LVITEM lvi;
  1652. lvi.mask = LVIF_PARAM;
  1653. lvi.iItem = iIndex;
  1654. lvi.iSubItem = 0;
  1655. if (!ListView_GetItem(hwndModuleList, &lvi)) {
  1656. assert(FALSE);
  1657. continue;
  1658. }
  1659. ListView_GetItemText(hwndModuleList, iIndex, 1, szTemp, ARRAYSIZE(szTemp));
  1660. if (CSTRING::Trim(szTemp)) {
  1661. psfl->strlInExclude.AddString(szTemp, lvi.lParam);
  1662. }
  1663. }
  1664. } else {
  1665. PFLAG_FIX_LIST pffl = (PFLAG_FIX_LIST)GetWindowLongPtr(hdlg, DWLP_USER);
  1666. TCHAR szTemp[MAX_COMMAND_LINE + 1];
  1667. pffl->strCommandLine.Release();
  1668. *szTemp = 0;
  1669. GetDlgItemText(hdlg,
  1670. IDC_SHIM_CMD_LINE,
  1671. szTemp,
  1672. ARRAYSIZE(szTemp));
  1673. if (CSTRING::Trim(szTemp)) {
  1674. pffl->strCommandLine = szTemp;
  1675. }
  1676. }
  1677. EndDialog(hdlg, TRUE);
  1678. break;
  1679. }
  1680. case IDCANCEL:
  1681. EndDialog(hdlg, FALSE);
  1682. break;
  1683. default:
  1684. return FALSE;
  1685. }
  1686. break;
  1687. default:
  1688. return FALSE;
  1689. }
  1690. return TRUE;
  1691. }
  1692. void
  1693. ShowParams(
  1694. IN HWND hDlg,
  1695. IN HWND hwndList
  1696. )
  1697. /*++
  1698. ShowParams
  1699. Desc: Pops up the params dialog
  1700. Params:
  1701. IN HWND hDlg: The dialog box that contains the list box that shows the params
  1702. IN HWND hwndList: The list box that shows the params
  1703. Notes: The same function is called for both configuring the params in the shim wizard and
  1704. the custom layer proc
  1705. We can show and customize params only in the expert mode
  1706. Return:
  1707. void
  1708. --*/
  1709. {
  1710. if (!g_bExpert) {
  1711. return;
  1712. }
  1713. int iSelected = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
  1714. if (iSelected == -1) {
  1715. return;
  1716. }
  1717. LVITEM lvi;
  1718. lvi.mask = LVIF_PARAM;
  1719. lvi.iItem = iSelected;
  1720. lvi.iSubItem = 0;
  1721. if (!ListView_GetItem(hwndList, &lvi)) {
  1722. return;
  1723. }
  1724. if (lvi.lParam == NULL) {
  1725. assert(FALSE);
  1726. return;
  1727. }
  1728. TYPE type = ((PDS_TYPE)lvi.lParam)->type;
  1729. //
  1730. // We want to process this only for shims and flags.
  1731. //
  1732. PSHIM_FIX_LIST psfl = NULL;
  1733. PFLAG_FIX_LIST pffl = NULL;
  1734. if (type == FIX_LIST_SHIM) {
  1735. psfl = (PSHIM_FIX_LIST)lvi.lParam;
  1736. } else if (type == FIX_LIST_FLAG) {
  1737. pffl = (PFLAG_FIX_LIST)lvi.lParam;
  1738. } else {
  1739. assert(FALSE);
  1740. return;
  1741. }
  1742. if (DialogBoxParam(g_hInstance,
  1743. MAKEINTRESOURCE(IDD_OPTIONS),
  1744. hDlg,
  1745. ParamsDlgProc,
  1746. (LPARAM)lvi.lParam)) {
  1747. if (type == FIX_LIST_SHIM) {
  1748. ListView_SetItemText(hwndList, iSelected, 1, psfl->strCommandLine);
  1749. if (psfl->strlInExclude.IsEmpty()) {
  1750. ListView_SetItemText(hwndList, iSelected, 2, GetString(IDS_NO));
  1751. } else {
  1752. ListView_SetItemText(hwndList, iSelected, 2, GetString(IDS_YES));
  1753. }
  1754. } else {
  1755. ListView_SetItemText(hwndList, iSelected, 1, pffl->strCommandLine);
  1756. ListView_SetItemText(hwndList, iSelected, 2, GetString(IDS_NO));
  1757. }
  1758. }
  1759. }
  1760. void
  1761. HandleShowAllAtrr(
  1762. IN HWND hdlg
  1763. )
  1764. /*++
  1765. HandleShowAllAtrr
  1766. Desc: Shows all the attributes of all the matching files.
  1767. When we save a database, only the attributes that are in selected are in the XML
  1768. So we might need to see all the other attributes if we wish to add some new
  1769. attributes
  1770. Params:
  1771. IN HWND hdlg: The matching file wizard page
  1772. Return:
  1773. void
  1774. --*/
  1775. {
  1776. TCHAR szDir[MAX_PATH];
  1777. PMATCHINGFILE pMatchTemp;
  1778. HWND hwndTree = GetDlgItem(hdlg, IDC_FILELIST);
  1779. PATTRINFO pAttrInfo;
  1780. PTCHAR pchTemp = NULL;
  1781. //
  1782. // Get the long file name of the file being fixed.
  1783. //
  1784. if (g_pCurrentWizard->CheckAndSetLongFilename(hdlg, IDS_GETCOMPLETEPATH) == FALSE) {
  1785. //
  1786. // User pressed cancel there or there was some error
  1787. //
  1788. return;
  1789. }
  1790. //
  1791. // Get the directory of the exe being fixed
  1792. //
  1793. *szDir = 0;
  1794. SafeCpyN(szDir, g_pCurrentWizard->m_Entry.strFullpath, ARRAYSIZE(szDir));
  1795. pchTemp = _tcsrchr(szDir, TEXT('\\'));
  1796. if (pchTemp && pchTemp < (szDir + ARRAYSIZE(szDir) - 1)) {
  1797. *(++pchTemp) = 0;
  1798. }
  1799. TreeDeleteAll(hwndTree);
  1800. pMatchTemp = g_pCurrentWizard->m_Entry.pFirstMatchingFile;
  1801. //
  1802. // For all the matching files that are associated with the entry,
  1803. // get their complete attributes
  1804. //
  1805. while (pMatchTemp) {
  1806. CSTRING strFullName = szDir;
  1807. //
  1808. // Get the full path of the matching file
  1809. //
  1810. strFullName.Strcat(pMatchTemp->strMatchName);
  1811. if (pMatchTemp->strMatchName == TEXT("*")) {
  1812. pMatchTemp->strFullName = g_pCurrentWizard->m_Entry.strFullpath;
  1813. } else {
  1814. pMatchTemp->strFullName = strFullName;
  1815. }
  1816. if (SdbGetFileAttributes(pMatchTemp->strFullName, &pAttrInfo, NULL)) {
  1817. //
  1818. // SdbGetFileAttributes can fail if the file does not exist on the target
  1819. // machine
  1820. //
  1821. pMatchTemp->attributeList = pAttrInfo;
  1822. }
  1823. pMatchTemp = pMatchTemp->pNext;
  1824. }
  1825. //
  1826. // Refresh the list now.
  1827. //
  1828. SendMessage(hdlg, WM_USER_MATCHINGTREE_REFRESH, 0, 0);
  1829. }
  1830. void
  1831. SetMask(
  1832. IN HWND hwndTree
  1833. )
  1834. /*++
  1835. SetMask
  1836. Desc: Checks which attributes are selected in the matching files tree and sets the
  1837. dwMask of PMATCHINGFILE accordingly
  1838. Params:
  1839. IN HWND hwndTree: The matching file tree
  1840. --*/
  1841. {
  1842. LPARAM lParam;
  1843. HTREEITEM hItemMatch = TreeView_GetRoot(hwndTree), hItemAttr;
  1844. PMATCHINGFILE pMatch = NULL;
  1845. while (hItemMatch) {
  1846. TVITEM Item;
  1847. Item.mask = TVIF_PARAM;
  1848. Item.hItem = hItemMatch;
  1849. if (!TreeView_GetItem(hwndTree, &Item)) {
  1850. assert(FALSE);
  1851. goto Next_Match;
  1852. }
  1853. lParam = Item.lParam;
  1854. pMatch = (PMATCHINGFILE)lParam;
  1855. pMatch->dwMask = 0;
  1856. //
  1857. // Now Traverse this tree and then set the mask properly
  1858. //
  1859. hItemAttr = TreeView_GetChild(hwndTree, hItemMatch);
  1860. while (hItemAttr) {
  1861. Item.mask = TVIF_PARAM;
  1862. Item.hItem = hItemAttr;
  1863. if (!TreeView_GetItem(hwndTree, &Item)) {
  1864. assert(FALSE);
  1865. goto Next_Attr;
  1866. }
  1867. lParam = Item.lParam;
  1868. int iPos = TagToIndex((TAG)lParam);
  1869. if (iPos != -1 && TreeView_GetCheckState(hwndTree, hItemAttr) == 1) {
  1870. pMatch->dwMask |= 1 << (iPos + 1);
  1871. }
  1872. Next_Attr:
  1873. hItemAttr = TreeView_GetNextSibling(hwndTree, hItemAttr);
  1874. }
  1875. Next_Match:
  1876. hItemMatch = TreeView_GetNextSibling(hwndTree, hItemMatch);
  1877. }
  1878. }
  1879. BOOL
  1880. HandleLayersNext(
  1881. IN HWND hdlg,
  1882. IN BOOL bCheckAndAddLua,
  1883. OUT CSTRINGLIST* pstrlAddedLuaShims //(NULL)
  1884. )
  1885. /*++
  1886. HandleLayersNext
  1887. Desc: Handles the pressing of Next/Finish button for the layers wizard page
  1888. Params:
  1889. IN HWND hdlg: The layers wizard page
  1890. IN BOOL bCheckAndAddLua: Should we check if the user has selected LUA layer and add
  1891. the shims if he has.
  1892. OUT CSTRINGLIST* pstrlShimsAdded(NULL): This is passed to AddLuaShimsInEntry. See the description
  1893. in that routine to see how this is used
  1894. Return:
  1895. FALSE: If there is some error, or the entry contains no shim, flag or layer
  1896. TRUE: Otherwise
  1897. --*/
  1898. {
  1899. g_bIsLUALayerSelected = FALSE;
  1900. g_pCurrentWizard->WipeEntry(FALSE, FALSE, TRUE, FALSE);
  1901. HWND hwndRadio = GetDlgItem(hdlg, IDC_RADIO_NONE);
  1902. //
  1903. // Get the Selected Layers
  1904. //
  1905. if (SendMessage(hwndRadio, BM_GETCHECK, 0, 0) != BST_CHECKED) {
  1906. PLAYER_FIX_LIST plfl = new LAYER_FIX_LIST;
  1907. if (plfl == NULL) {
  1908. MEM_ERR;
  1909. return FALSE;
  1910. }
  1911. hwndRadio = GetDlgItem(hdlg, IDC_RADIO_95);
  1912. if (SendMessage(hwndRadio, BM_GETCHECK, 0, 0) == BST_CHECKED) {
  1913. plfl->pLayerFix = (PLAYER_FIX)FindFix(s_arszOsLayers[0], FIX_LAYER);
  1914. goto LAYER_RADIO_DONE;
  1915. }
  1916. hwndRadio = GetDlgItem(hdlg, IDC_RADIO_NT);
  1917. if (SendMessage(hwndRadio, BM_GETCHECK, 0, 0) == BST_CHECKED) {
  1918. plfl->pLayerFix = (PLAYER_FIX)FindFix(s_arszOsLayers[1], FIX_LAYER);
  1919. goto LAYER_RADIO_DONE;
  1920. }
  1921. hwndRadio = GetDlgItem(hdlg, IDC_RADIO_98);
  1922. if (SendMessage(hwndRadio, BM_GETCHECK, 0, 0) == BST_CHECKED) {
  1923. plfl->pLayerFix = (PLAYER_FIX)FindFix(s_arszOsLayers[2], FIX_LAYER);
  1924. goto LAYER_RADIO_DONE;
  1925. }
  1926. hwndRadio = GetDlgItem(hdlg, IDC_RADIO_2K);
  1927. if (SendMessage(hwndRadio, BM_GETCHECK, 0, 0) == BST_CHECKED) {
  1928. plfl->pLayerFix = (PLAYER_FIX)FindFix(s_arszOsLayers[3], FIX_LAYER);
  1929. goto LAYER_RADIO_DONE;
  1930. }
  1931. LAYER_RADIO_DONE:
  1932. //
  1933. // Add the selected Layer
  1934. //
  1935. g_pCurrentWizard->m_Entry.pFirstLayer = plfl;
  1936. }
  1937. //
  1938. // Now add the layers selected in the List View
  1939. //
  1940. UINT uIndex;
  1941. UINT uLayerCount = ListView_GetItemCount(s_hwndLayerList);
  1942. PLAYER_FIX_LIST plflInList = NULL;
  1943. for (uIndex = 0 ; uIndex < uLayerCount; ++uIndex) {
  1944. LVITEM Item;
  1945. Item.mask = LVIF_PARAM;
  1946. Item.iItem = uIndex;
  1947. Item.iSubItem = 0;
  1948. if (!ListView_GetItem(s_hwndLayerList, &Item)) {
  1949. assert(FALSE);
  1950. continue;
  1951. }
  1952. if (ListView_GetCheckState(s_hwndLayerList, uIndex)) {
  1953. plflInList = (PLAYER_FIX_LIST)Item.lParam;
  1954. assert(plflInList);
  1955. //
  1956. // If the layer is LUA, we need to add the shims individually because
  1957. // when we pass a PDBENTRY around, we don't want to change the PLUADATA
  1958. // in the shim of the layer (which will be global).
  1959. //
  1960. if (plflInList->pLayerFix->strName == TEXT("LUA")) {
  1961. g_bIsLUALayerSelected = TRUE;
  1962. } else {
  1963. PLAYER_FIX_LIST plfl = new LAYER_FIX_LIST;
  1964. if (plfl == NULL) {
  1965. MEM_ERR;
  1966. return FALSE;
  1967. }
  1968. plfl->pLayerFix = plflInList->pLayerFix;
  1969. plfl->pNext = g_pCurrentWizard->m_Entry.pFirstLayer;
  1970. g_pCurrentWizard->m_Entry.pFirstLayer = plfl;
  1971. }
  1972. }
  1973. }
  1974. //
  1975. // If have seleted LUA layer and we have pressed the Finish button, that means
  1976. // that we are in editing mode and we want to add LUA layer and close the dialog
  1977. // In this case we must check if the LUA shims exist and if not then we must add
  1978. // the lua shims ourselves
  1979. //
  1980. if (g_bIsLUALayerSelected && bCheckAndAddLua) {
  1981. AddLuaShimsInEntry(&g_pCurrentWizard->m_Entry, pstrlAddedLuaShims);
  1982. }
  1983. PDBENTRY pEntry = &g_pCurrentWizard->m_Entry;
  1984. if (pEntry && pEntry->pFirstFlag || pEntry->pFirstLayer || pEntry->pFirstShim) {
  1985. //
  1986. // The entry contains some fix or layer
  1987. //
  1988. return TRUE;
  1989. }
  1990. return FALSE;
  1991. }
  1992. BOOL
  1993. HandleShimsNext(
  1994. IN HWND hdlg
  1995. )
  1996. /*++
  1997. HandleShimsNext
  1998. Desc: Handles the pressing of Next/Finish button for the shims wizard page
  1999. Params:
  2000. IN HWND hdlg: The shims wizard page
  2001. Return:
  2002. FALSE: If there is some error, or the entry contains no shim, flag or layer
  2003. TRUE: Otherwise
  2004. --*/
  2005. {
  2006. PLAYER_FIX_LIST plfl = NULL;
  2007. HWND hwndShimList = NULL;
  2008. UINT uShimCount = 0;
  2009. g_pCurrentWizard->WipeEntry(FALSE, TRUE, FALSE, TRUE);
  2010. hwndShimList = GetDlgItem(hdlg, IDC_SHIMLIST);
  2011. uShimCount = ListView_GetItemCount(hwndShimList);
  2012. for (UINT uIndex = 0 ; uIndex < uShimCount; ++uIndex) {
  2013. LVITEM Item;
  2014. Item.lParam = 0;
  2015. Item.mask = LVIF_PARAM;
  2016. Item.iItem = uIndex;
  2017. Item.iSubItem = 0;
  2018. if (!ListView_GetItem(hwndShimList, &Item)) {
  2019. assert(FALSE);
  2020. }
  2021. if (ListView_GetCheckState(hwndShimList, uIndex)) {
  2022. TYPE type = ((PDS_TYPE)Item.lParam)->type;
  2023. if (type == FIX_LIST_SHIM) {
  2024. PSHIM_FIX_LIST psfl= (PSHIM_FIX_LIST)Item.lParam;
  2025. assert(psfl);
  2026. //
  2027. // Check if this is already part of some layer.
  2028. //
  2029. plfl = g_pCurrentWizard->m_Entry.pFirstLayer;
  2030. while (plfl) {
  2031. if (IsShimInlayer(plfl->pLayerFix, psfl->pShimFix, &psfl->strCommandLine, &psfl->strlInExclude)) {
  2032. break;
  2033. }
  2034. plfl = plfl->pNext;
  2035. }
  2036. if (plfl) {
  2037. //
  2038. // This shim is a part of some mode
  2039. //
  2040. continue;
  2041. }
  2042. PSHIM_FIX_LIST psflNew = new SHIM_FIX_LIST;
  2043. if (psflNew == NULL) {
  2044. MEM_ERR;
  2045. return FALSE;
  2046. }
  2047. psflNew->pShimFix = psfl->pShimFix;
  2048. psflNew->strCommandLine = psfl->strCommandLine;
  2049. psflNew->strlInExclude = psfl->strlInExclude;
  2050. if (psfl->pLuaData) {
  2051. psflNew->pLuaData = new LUADATA;
  2052. if (psflNew->pLuaData) {
  2053. psflNew->pLuaData->Copy(psfl->pLuaData);
  2054. }
  2055. }
  2056. psflNew->pNext = g_pCurrentWizard->m_Entry.pFirstShim;
  2057. g_pCurrentWizard->m_Entry.pFirstShim = psflNew;
  2058. } else if (type == FIX_LIST_FLAG) {
  2059. PFLAG_FIX_LIST pffl = (PFLAG_FIX_LIST)Item.lParam;
  2060. assert(pffl);
  2061. plfl = g_pCurrentWizard->m_Entry.pFirstLayer;
  2062. while (plfl) {
  2063. if (IsFlagInlayer(plfl->pLayerFix, pffl->pFlagFix, &pffl->strCommandLine)) {
  2064. break;
  2065. }
  2066. plfl = plfl->pNext;
  2067. }
  2068. if (plfl) {
  2069. //
  2070. // This flag is a part of some layer
  2071. //
  2072. continue;
  2073. }
  2074. PFLAG_FIX_LIST pfflNew = new FLAG_FIX_LIST;
  2075. if (pfflNew == NULL) {
  2076. MEM_ERR;
  2077. return FALSE;
  2078. }
  2079. pfflNew->pFlagFix = pffl->pFlagFix;
  2080. pfflNew->strCommandLine = pffl->strCommandLine;
  2081. pfflNew->pNext = g_pCurrentWizard->m_Entry.pFirstFlag;
  2082. g_pCurrentWizard->m_Entry.pFirstFlag = pfflNew;
  2083. }
  2084. }
  2085. }
  2086. PDBENTRY pEntry = &g_pCurrentWizard->m_Entry;
  2087. if (pEntry->pFirstFlag || pEntry->pFirstLayer || pEntry->pFirstShim) {
  2088. return TRUE;
  2089. }
  2090. return FALSE;
  2091. }
  2092. void
  2093. ShowSelected(
  2094. IN HWND hdlg
  2095. )
  2096. /*++
  2097. ShowSelected
  2098. Desc: Show only the checked shims/flags. Deletes the shims/flags that are not checked.
  2099. This function is called from the SelectShims(...)
  2100. Params:
  2101. IN HWND hdlg: The shims wizard page
  2102. --*/
  2103. {
  2104. HWND hwndShimList = GetDlgItem(hdlg, IDC_SHIMLIST);
  2105. UINT uShimCount = ListView_GetItemCount(hwndShimList);
  2106. INT uCheckedCount = 0;
  2107. LVITEM lvi = {0};
  2108. uCheckedCount = uShimCount;
  2109. SendMessage(hwndShimList, WM_SETREDRAW, FALSE, 0);
  2110. for (INT iIndex = uShimCount - 1 ; iIndex >= 0 ; --iIndex) {
  2111. LVITEM Item;
  2112. Item.lParam = 0;
  2113. Item.mask = LVIF_PARAM;
  2114. Item.iItem = iIndex;
  2115. Item.iSubItem = 0;
  2116. if (!ListView_GetItem(hwndShimList, &Item)) {
  2117. assert(FALSE);
  2118. }
  2119. if (!ListView_GetCheckState(hwndShimList, iIndex)) {
  2120. TYPE type = ((PDS_TYPE)Item.lParam)->type;
  2121. if (type == FIX_LIST_SHIM) {
  2122. DeleteShimFixList((PSHIM_FIX_LIST)Item.lParam);
  2123. } else if (type == FIX_LIST_FLAG) {
  2124. DeleteFlagFixList((PFLAG_FIX_LIST)Item.lParam);
  2125. }
  2126. ListView_DeleteItem(hwndShimList, iIndex);
  2127. --uCheckedCount;
  2128. }
  2129. }
  2130. SendMessage(hwndShimList, WM_SETREDRAW, TRUE, 0);
  2131. UpdateWindow(hwndShimList);
  2132. s_bAllShown = FALSE;
  2133. SetDlgItemText(hdlg, IDC_SHOW, GetString(IDS_SHOW_BUTTON_ALL));
  2134. if (ListView_GetSelectedCount(hwndShimList) > 0) {
  2135. ENABLEWINDOW(GetDlgItem(hdlg, IDC_PARAMS), TRUE);
  2136. } else {
  2137. ENABLEWINDOW(GetDlgItem(hdlg, IDC_PARAMS), FALSE);
  2138. }
  2139. //
  2140. // Select the first item.
  2141. //
  2142. if (uCheckedCount) {
  2143. //
  2144. // If the first shim is part of a layer, then the parms button will
  2145. // get disabled in the handler for LVN_ITEMCHANGED.
  2146. //
  2147. ListView_SetSelectionMark(hwndShimList, 0);
  2148. ListView_SetItemState(hwndShimList,
  2149. 0,
  2150. LVIS_FOCUSED | LVIS_SELECTED ,
  2151. LVIS_FOCUSED | LVIS_SELECTED);
  2152. lvi.mask = LVIF_IMAGE;
  2153. lvi.iItem = 0;
  2154. lvi.iSubItem = 0;
  2155. //
  2156. // The above does not work always. We will disable the param button if the shim is part of
  2157. // a layer
  2158. //
  2159. if (ListView_GetItem(hwndShimList, &lvi)) {
  2160. if (lvi.iImage == IMAGE_SHIM) {
  2161. //
  2162. // This shim is not part of a layer
  2163. //
  2164. ENABLEWINDOW(GetDlgItem(hdlg, IDC_PARAMS), TRUE);
  2165. } else {
  2166. //
  2167. // This shim is part of a layer, we must now allow to change paramters for this
  2168. //
  2169. ENABLEWINDOW(GetDlgItem(hdlg, IDC_PARAMS), FALSE);
  2170. }
  2171. } else {
  2172. ENABLEWINDOW(GetDlgItem(hdlg, IDC_PARAMS), FALSE);
  2173. }
  2174. } else {
  2175. //
  2176. // There are no shims, better disable the params button.
  2177. //
  2178. ENABLEWINDOW(GetDlgItem(hdlg, IDC_PARAMS), FALSE);
  2179. }
  2180. }
  2181. void
  2182. ShowItems(
  2183. IN HWND hdlg
  2184. )
  2185. /*++
  2186. ShowItems
  2187. Desc: Populates the fixes list view in the shims wizard page
  2188. Params:
  2189. IN HWND hdlg: The shims wizard page
  2190. Return:
  2191. void
  2192. --*/
  2193. {
  2194. g_bNowTest = FALSE;
  2195. HWND hwndList = GetDlgItem(hdlg, IDC_SHIMLIST);
  2196. PSHIM_FIX psf = GlobalDataBase.pShimFixes;
  2197. SendMessage(hwndList, WM_SETREDRAW, FALSE, 0);
  2198. SetCursor(LoadCursor(NULL, IDC_WAIT));
  2199. //
  2200. // Read the shims.
  2201. //
  2202. LVFINDINFO lvfind;
  2203. LVITEM lvi;
  2204. UINT uCount = 0;
  2205. while (psf) {
  2206. if (psf->bGeneral || g_bExpert) {
  2207. PSHIM_FIX_LIST psflAsInLayer = NULL;
  2208. BOOL bShimInLayer = ShimPresentInLayersOfEntry(&g_pCurrentWizard->m_Entry,
  2209. psf,
  2210. &psflAsInLayer);
  2211. BOOL bLUAShimInLayer =
  2212. (g_bIsLUALayerSelected &&
  2213. (psf->strName == TEXT("LUARedirectFS") ||
  2214. psf->strName == TEXT("LUARedirectReg")));
  2215. //
  2216. // Check if the shim is already present in the list.
  2217. //
  2218. lvfind.flags = LVFI_STRING;
  2219. lvfind.psz = psf->strName.pszString;
  2220. INT iIndex = ListView_FindItem(hwndList, -1, &lvfind);
  2221. if (-1 == iIndex) {
  2222. PSHIM_FIX_LIST pShimFixList = new SHIM_FIX_LIST;
  2223. if (pShimFixList == NULL) {
  2224. MEM_ERR;
  2225. break;
  2226. }
  2227. //
  2228. // This will contain a ptr to the shimlist, if there is a layer
  2229. // that has this shim and the layer has been applied to the entry
  2230. //
  2231. pShimFixList->pShimFix = psf;
  2232. //
  2233. // If this is present in some selected layer, set the param for this just as they are in the layer
  2234. //
  2235. if (psflAsInLayer) {
  2236. pShimFixList->strCommandLine= psflAsInLayer->strCommandLine;
  2237. pShimFixList->strlInExclude = psflAsInLayer->strlInExclude;
  2238. }
  2239. ZeroMemory(&lvi, sizeof(lvi));
  2240. lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
  2241. lvi.pszText = psf->strName;
  2242. lvi.iItem = uCount;
  2243. lvi.iSubItem = 0;
  2244. lvi.iImage = (bShimInLayer || bLUAShimInLayer) ? IMAGE_LAYERS : IMAGE_SHIM;
  2245. lvi.lParam = (LPARAM)pShimFixList;
  2246. iIndex = ListView_InsertItem(hwndList, &lvi);
  2247. ListView_SetCheckState(hwndList,
  2248. iIndex,
  2249. bShimInLayer || bLUAShimInLayer);
  2250. //
  2251. // If we are in edit mode, then select the used ones and set the params appropriately
  2252. //
  2253. PSHIM_FIX_LIST psflFound = NULL; // the pshimfix list found in the entry. This is used for populating the previous commandline etc.
  2254. if (g_pCurrentWizard->m_bEditing && ShimPresent(psf, &g_pCurrentWizard->m_Entry, &psflFound)) {
  2255. ListView_SetCheckState(hwndList, iIndex, TRUE);
  2256. //
  2257. // Add the commandline for this shim
  2258. //
  2259. if (psflFound && psflFound->strCommandLine.Length() > 0) {
  2260. pShimFixList->strCommandLine = psflFound->strCommandLine;
  2261. }
  2262. //
  2263. // Add the include exclude for this shim
  2264. //
  2265. if (psflFound && !psflFound->strlInExclude.IsEmpty()) {
  2266. pShimFixList->strlInExclude = psflFound->strlInExclude;
  2267. }
  2268. //
  2269. // Add the LUA data for this shim
  2270. //
  2271. if (psflFound && psflFound->pLuaData) {
  2272. pShimFixList->pLuaData = new LUADATA;
  2273. if (pShimFixList->pLuaData) {
  2274. pShimFixList->pLuaData->Copy(psflFound->pLuaData);
  2275. } else {
  2276. MEM_ERR;
  2277. }
  2278. }
  2279. }
  2280. if (g_bExpert) {
  2281. ListView_SetItemText(hwndList, iIndex, 1, pShimFixList->strCommandLine);
  2282. CSTRING strModulePresent;
  2283. strModulePresent= pShimFixList->strlInExclude.IsEmpty() ? GetString(IDS_NO) : GetString(IDS_YES);
  2284. ListView_SetItemText(hwndList, iIndex, 2, strModulePresent);
  2285. }
  2286. } else {
  2287. PSHIM_FIX_LIST pShimFixList = NULL;
  2288. //
  2289. // We might need to change the state of some of the existing shims.
  2290. //
  2291. ZeroMemory(&lvi, sizeof(lvi));
  2292. lvi.mask = LVIF_IMAGE | LVIF_PARAM;
  2293. lvi.iItem = iIndex;
  2294. lvi.iSubItem = 0;
  2295. if (!ListView_GetItem(hwndList, &lvi)) {
  2296. assert(FALSE);
  2297. return;
  2298. }
  2299. pShimFixList = (PSHIM_FIX_LIST)lvi.lParam;
  2300. if (pShimFixList == NULL) {
  2301. assert(FALSE);
  2302. return;
  2303. }
  2304. INT iPrevImage = lvi.iImage, iNewImage = 0;
  2305. iNewImage = lvi.iImage = (bShimInLayer || bLUAShimInLayer) ? IMAGE_LAYERS : IMAGE_SHIM;
  2306. ListView_SetItem(hwndList, &lvi);
  2307. //
  2308. // If this is present in some selected layer, set the param for this just as they are in the layer
  2309. //
  2310. if (bShimInLayer) {
  2311. if (psflAsInLayer) {
  2312. pShimFixList->strCommandLine= psflAsInLayer->strCommandLine;
  2313. pShimFixList->strlInExclude = psflAsInLayer->strlInExclude;
  2314. } else {
  2315. assert(FALSE);
  2316. }
  2317. }
  2318. if (iPrevImage != iNewImage) {
  2319. ListView_SetCheckState(hwndList,
  2320. iIndex,
  2321. bShimInLayer || bLUAShimInLayer);
  2322. //
  2323. // if this shim was earlier a part of layer, we must change the param. Remove All
  2324. //
  2325. if (iPrevImage != IMAGE_SHIM) {
  2326. pShimFixList->strCommandLine = TEXT("");
  2327. pShimFixList->strlInExclude.DeleteAll();
  2328. }
  2329. }
  2330. //
  2331. // Must now refresh the params in the list box.
  2332. //
  2333. if (g_bExpert) {
  2334. ListView_SetItemText(hwndList, iIndex, 1, pShimFixList->strCommandLine);
  2335. CSTRING strModulePresent;
  2336. strModulePresent= pShimFixList->strlInExclude.IsEmpty() ? GetString(IDS_NO) : GetString(IDS_YES);
  2337. ListView_SetItemText(hwndList, iIndex, 2, strModulePresent);
  2338. }
  2339. }
  2340. ++uCount;
  2341. }
  2342. psf = psf->pNext;
  2343. }
  2344. //
  2345. // Now read in the flags as well.
  2346. //
  2347. PFLAG_FIX pff = GlobalDataBase.pFlagFixes;
  2348. while (pff) {
  2349. if (pff->bGeneral || g_bExpert) {
  2350. PFLAG_FIX_LIST pfflAsInLayer = NULL;
  2351. BOOL bFlagInLayer = FlagPresentInLayersOfEntry(&g_pCurrentWizard->m_Entry,
  2352. pff,
  2353. &pfflAsInLayer);
  2354. //
  2355. // Check if the flag is already present in the list.
  2356. //
  2357. lvfind.flags = LVFI_STRING;
  2358. lvfind.psz = pff->strName.pszString;
  2359. INT iIndex = ListView_FindItem(hwndList, -1, &lvfind);
  2360. if (-1 == iIndex) {
  2361. PFLAG_FIX_LIST pFlagFixList = new FLAG_FIX_LIST;
  2362. if (pFlagFixList == NULL) {
  2363. MEM_ERR;
  2364. break;
  2365. }
  2366. pFlagFixList->pFlagFix = pff;
  2367. ZeroMemory(&lvi, sizeof(lvi));
  2368. lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
  2369. lvi.pszText = pff->strName;
  2370. lvi.iItem = uCount;
  2371. lvi.iSubItem = 0;
  2372. lvi.iImage = bFlagInLayer ? IMAGE_LAYERS : IMAGE_SHIM;
  2373. lvi.lParam = (LPARAM)pFlagFixList;
  2374. INT iIndexInserted = ListView_InsertItem(hwndList, &lvi);
  2375. ListView_SetCheckState(hwndList, iIndexInserted, bFlagInLayer);
  2376. ListView_SetItemText(hwndList, iIndexInserted, 2, GetString(IDS_NO));
  2377. //
  2378. // If we are in edit mode, then select the used ones and set the params appropritely
  2379. //
  2380. //
  2381. // the pflagfix list found in the entry. This is used for populating the previous commandline etc.
  2382. //
  2383. PFLAG_FIX_LIST pfflFound = NULL;
  2384. if (g_pCurrentWizard->m_bEditing && FlagPresent(pff,
  2385. &g_pCurrentWizard->m_Entry,
  2386. &pfflFound)) {
  2387. ListView_SetCheckState(hwndList, iIndexInserted, TRUE);
  2388. //
  2389. // Add the commandline for this flag
  2390. //
  2391. if (pfflFound && pfflFound->strCommandLine.Length() > 0) {
  2392. pFlagFixList->strCommandLine = pfflFound->strCommandLine;
  2393. }
  2394. //
  2395. // Refresh the command-line for this flag in the list view
  2396. //
  2397. if (g_bExpert) {
  2398. ListView_SetItemText(hwndList, iIndexInserted, 1, pFlagFixList->strCommandLine);
  2399. ListView_SetItemText(hwndList, iIndexInserted, 2, GetString(IDS_NO));
  2400. }
  2401. }
  2402. } else {
  2403. //
  2404. // We might need to change the state of some of the existing flags.
  2405. //
  2406. PFLAG_FIX_LIST pFlagFixList = NULL;
  2407. ZeroMemory(&lvi, sizeof(lvi));
  2408. lvi.mask = LVIF_IMAGE | LVIF_PARAM;
  2409. lvi.iItem = iIndex;
  2410. lvi.iSubItem = 0;
  2411. if (!ListView_GetItem(hwndList, &lvi)) {
  2412. assert(FALSE);
  2413. return;
  2414. }
  2415. pFlagFixList = (PFLAG_FIX_LIST)lvi.lParam;
  2416. if (pFlagFixList == NULL) {
  2417. assert(FALSE);
  2418. return;
  2419. }
  2420. INT iPrevImage = lvi.iImage, iNewImage = 0;
  2421. iNewImage = lvi.iImage = (bFlagInLayer) ? IMAGE_LAYERS : IMAGE_SHIM;
  2422. ListView_SetItem(hwndList, &lvi);
  2423. //
  2424. // Set the commandline for this flag appropriately
  2425. //
  2426. if (bFlagInLayer) {
  2427. pFlagFixList->strCommandLine= pfflAsInLayer->strCommandLine;
  2428. }
  2429. if (iPrevImage != iNewImage) {
  2430. ListView_SetCheckState(hwndList, iIndex, bFlagInLayer);
  2431. //
  2432. // if this flag was earlier a part of layer, we must change the param. Remove it.
  2433. //
  2434. if (iPrevImage != IMAGE_SHIM) {
  2435. pFlagFixList->strCommandLine = TEXT("");
  2436. }
  2437. }
  2438. //
  2439. // Refresh the command-line for this flag in the list view
  2440. //
  2441. if (g_bExpert) {
  2442. ListView_SetItemText(hwndList, iIndex, 1, pFlagFixList->strCommandLine);
  2443. ListView_SetItemText(hwndList, iIndex, 2, GetString(IDS_NO));
  2444. }
  2445. }
  2446. ++uCount;
  2447. }
  2448. pff = pff->pNext;
  2449. }
  2450. SetCursor(LoadCursor(NULL, IDC_ARROW));
  2451. SendMessage(hwndList, WM_SETREDRAW, TRUE, 0);
  2452. UpdateWindow(hwndList);
  2453. s_bAllShown = TRUE;
  2454. SetDlgItemText(hdlg, IDC_SHOW, GetString(IDS_SHOW_BUTTON_SEL));
  2455. if (ListView_GetSelectionMark(hwndList) != -1) {
  2456. ENABLEWINDOW(GetDlgItem(hdlg, IDC_PARAMS), TRUE);
  2457. } else {
  2458. ENABLEWINDOW(GetDlgItem(hdlg, IDC_PARAMS), FALSE);
  2459. }
  2460. //
  2461. // Set the column width of the last column in the list view appropriately to
  2462. // cover the width of the list view
  2463. // Assumption: The list view has only one column or 3 cloumns depending upon
  2464. // whether we are in expert mode or not.
  2465. //
  2466. if (g_bExpert) {
  2467. ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE_USEHEADER);
  2468. } else {
  2469. ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE_USEHEADER);
  2470. }
  2471. g_bNowTest = TRUE;
  2472. }
  2473. BOOL
  2474. ShimPresentInLayersOfEntry(
  2475. IN PDBENTRY pEntry,
  2476. IN PSHIM_FIX psf,
  2477. OUT PSHIM_FIX_LIST* ppsfList, // (NULL)
  2478. OUT PLAYER_FIX_LIST* pplfList // (NULL)
  2479. )
  2480. /*++
  2481. ShimPresentInLayersOfEntry
  2482. Desc: Checks if the shim psf occurs in any any of the layers that have
  2483. been applied to pEntry.
  2484. Params:
  2485. IN PDBENTRY pEntry: The entry for which the check has to be made
  2486. IN PSHIM_FIX psf: The shim to check for
  2487. OUT PSHIM_FIX_LIST* ppsfList (NULL): Pointer to the shim fix list in the layer
  2488. So that we might get the params for this shim in the layer
  2489. OUT PLAYER_FIX_LIST* pplfList (NULL): Pointer to the layer fix list
  2490. --*/
  2491. {
  2492. PLAYER_FIX_LIST plfl = pEntry->pFirstLayer;
  2493. PLAYER_FIX plf;
  2494. PSHIM_FIX_LIST psfl;
  2495. while (plfl) {
  2496. plf = plfl->pLayerFix;
  2497. psfl = plf->pShimFixList;
  2498. while (psfl) {
  2499. if (psfl->pShimFix == psf) {
  2500. if (ppsfList) {
  2501. *ppsfList = psfl;
  2502. }
  2503. if (pplfList) {
  2504. *pplfList = plfl;
  2505. }
  2506. return TRUE;
  2507. }
  2508. psfl = psfl->pNext;
  2509. }
  2510. plfl = plfl->pNext;
  2511. }
  2512. return FALSE;
  2513. }
  2514. BOOL
  2515. FlagPresentInLayersOfEntry(
  2516. IN PDBENTRY pEntry,
  2517. IN PFLAG_FIX pff,
  2518. OUT PFLAG_FIX_LIST* ppffList, // (NULL)
  2519. OUT PLAYER_FIX_LIST* pplfl // (NULL)
  2520. )
  2521. /*++
  2522. FlagPresentInLayersOfEntry
  2523. Desc: Checks if the flag psf occurs in any any of the layers that have
  2524. been applied to pEntry.
  2525. Params:
  2526. IN PDBENTRY pEntry: The entry for which the check has to be made
  2527. IN PFLAG_FIX pff: The flag to check for
  2528. OUT PFLAG_FIX_LIST* ppffList (NULL): Pointer to the flag fix list in the layer
  2529. So that we might get the params for this flag in the layer
  2530. OUT PLAYER_FIX_LIST* pplfList (NULL): Pointer to the layer fix list
  2531. --*/
  2532. {
  2533. PLAYER_FIX_LIST plfl = pEntry->pFirstLayer;
  2534. PLAYER_FIX plf;
  2535. PFLAG_FIX_LIST pffl;
  2536. while (plfl) {
  2537. plf = plfl->pLayerFix;
  2538. pffl = plf->pFlagFixList;
  2539. while (pffl) {
  2540. if (pffl->pFlagFix == pff) {
  2541. if (ppffList) {
  2542. *ppffList = pffl;
  2543. }
  2544. if (pplfl) {
  2545. *pplfl = plfl;
  2546. }
  2547. return TRUE;
  2548. }
  2549. pffl = pffl->pNext;
  2550. }
  2551. plfl = plfl->pNext;
  2552. }
  2553. return FALSE;
  2554. }
  2555. void
  2556. CheckLayers(
  2557. IN HWND hDlg
  2558. )
  2559. /*++
  2560. CheckLayers
  2561. Desc: Deselects all the radio buttons and then checks the one that is appropriate.
  2562. For the layers in the list view, only checks the layers that have been
  2563. applied for the present entry.
  2564. Params:
  2565. IN HWND hDlg: The layer wizard page
  2566. Return:
  2567. void
  2568. --*/
  2569. {
  2570. INT id = -1;
  2571. LVFINDINFO lvfind;
  2572. HWND hwndList = GetDlgItem(hDlg, IDC_LAYERLIST);
  2573. PLAYER_FIX_LIST plfl = g_pCurrentWizard->m_Entry.pFirstLayer;
  2574. INT iTotal = ListView_GetItemCount(hwndList);
  2575. INT iIndex = 0;
  2576. CheckDlgButton(hDlg, IDC_RADIO_95, BST_UNCHECKED);
  2577. CheckDlgButton(hDlg, IDC_RADIO_NT, BST_UNCHECKED);
  2578. CheckDlgButton(hDlg, IDC_RADIO_98, BST_UNCHECKED);
  2579. CheckDlgButton(hDlg, IDC_RADIO_2K, BST_UNCHECKED);
  2580. CheckDlgButton(hDlg, IDC_RADIO_NONE, BST_UNCHECKED);
  2581. for (iIndex = 0; iIndex < iTotal; ++ iIndex) {
  2582. ListView_SetCheckState(hwndList, iIndex, FALSE);
  2583. }
  2584. ZeroMemory(&lvfind, sizeof(lvfind));
  2585. lvfind.flags = LVFI_STRING;
  2586. id = -1;
  2587. //
  2588. // Take care of the LUA layer first.
  2589. //
  2590. if (g_bIsLUALayerSelected) {
  2591. lvfind.psz = TEXT("LUA");
  2592. if ((iIndex = ListView_FindItem(hwndList, -1, &lvfind)) != -1) {
  2593. ListView_SetCheckState(hwndList, iIndex, TRUE);
  2594. }
  2595. }
  2596. while (plfl) {
  2597. assert(plfl->pLayerFix);
  2598. if (id == -1) {
  2599. if (lstrcmpi(plfl->pLayerFix->strName, s_arszOsLayers[0]) == 0) {
  2600. id = IDC_RADIO_95;
  2601. } else if (lstrcmpi(plfl->pLayerFix->strName, s_arszOsLayers[1]) == 0) {
  2602. id = IDC_RADIO_NT;
  2603. } else if (lstrcmpi(plfl->pLayerFix->strName, s_arszOsLayers[2]) == 0) {
  2604. id = IDC_RADIO_98;
  2605. } else if (lstrcmpi(plfl->pLayerFix->strName, s_arszOsLayers[3]) == 0) {
  2606. id = IDC_RADIO_2K;
  2607. }
  2608. if (id != -1) {
  2609. CheckDlgButton(hDlg, id, BST_CHECKED);
  2610. goto Next_loop;
  2611. }
  2612. }
  2613. lvfind.flags = LVFI_STRING;
  2614. lvfind.psz = plfl->pLayerFix->strName;
  2615. iIndex = ListView_FindItem(hwndList, -1, &lvfind);
  2616. if (iIndex != -1) {
  2617. ListView_SetCheckState(hwndList, iIndex, TRUE);
  2618. }
  2619. Next_loop:
  2620. plfl = plfl->pNext;
  2621. }
  2622. if (id == -1) {
  2623. //
  2624. // None of the OS layers were selected
  2625. //
  2626. CheckDlgButton(hDlg, IDC_RADIO_NONE, BST_CHECKED);
  2627. }
  2628. }
  2629. BOOL
  2630. HandleLayerListNotification(
  2631. IN HWND hdlg,
  2632. IN LPARAM lParam
  2633. )
  2634. /*++
  2635. HandleLayerListNotification
  2636. Params:
  2637. IN HWND hdlg: The layers wizard page
  2638. IN LPARAM lParam: The lParam that comes with WM_NOTIFY
  2639. Desc: Handles the notification messages for the layer list.
  2640. Return: TRUE: If the message was handled
  2641. FALSE: Otherwise
  2642. --*/
  2643. {
  2644. HWND hwndList = GetDlgItem(hdlg, IDC_LAYERLIST);
  2645. LPNMHDR pnm = (LPNMHDR)lParam;
  2646. switch (pnm->code) {
  2647. case NM_CLICK:
  2648. {
  2649. LVHITTESTINFO lvhti;
  2650. GetCursorPos(&lvhti.pt);
  2651. ScreenToClient(s_hwndLayerList, &lvhti.pt);
  2652. ListView_HitTest(s_hwndLayerList, &lvhti);
  2653. //
  2654. // If the check box state has changed toggle the selection
  2655. //
  2656. if (lvhti.flags & LVHT_ONITEMSTATEICON) {
  2657. INT iPos = ListView_GetSelectionMark(s_hwndLayerList);
  2658. if (iPos != -1) {
  2659. //
  2660. // De-select it.
  2661. //
  2662. ListView_SetItemState(s_hwndLayerList,
  2663. iPos,
  2664. 0,
  2665. LVIS_FOCUSED | LVIS_SELECTED);
  2666. }
  2667. }
  2668. ListView_SetItemState(s_hwndLayerList,
  2669. lvhti.iItem,
  2670. LVIS_FOCUSED | LVIS_SELECTED,
  2671. LVIS_FOCUSED | LVIS_SELECTED);
  2672. ListView_SetSelectionMark(s_hwndLayerList, lvhti.iItem);
  2673. break;
  2674. }
  2675. default: return FALSE;
  2676. }
  2677. return TRUE;
  2678. }
  2679. BOOL
  2680. HandleShimDeselect(
  2681. IN HWND hdlg,
  2682. IN INT iIndex
  2683. )
  2684. /*++
  2685. HandleShimDeselect
  2686. Desc: This function prompts the user if he is unchecking a shim that is part of
  2687. some mode. If the user selects OK then we remove all the layers that
  2688. have this shim and for all the shims in all those layes, we change their icons
  2689. Params:
  2690. IN HWND hdlg: The shims wizard page
  2691. IN INT iIndex: The index of the list view item where all the action is
  2692. Return: TRUE, if the user agrees to remove the previous layer.
  2693. FALSE, otherwise
  2694. --*/
  2695. {
  2696. HWND hwndList = GetDlgItem(hdlg, IDC_SHIMLIST);
  2697. LVITEM lvi;
  2698. PSHIM_FIX psf = NULL;
  2699. PSHIM_FIX_LIST psfl = NULL;
  2700. PFLAG_FIX_LIST pffl = NULL;
  2701. PLAYER_FIX_LIST plfl = NULL;
  2702. TYPE type;
  2703. BOOL bFoundInLayer = FALSE;
  2704. ZeroMemory(&lvi, sizeof(lvi));
  2705. lvi.mask = LVIF_PARAM | LVIF_IMAGE;
  2706. lvi.iItem = iIndex;
  2707. lvi.iSubItem = 0;
  2708. if (ListView_GetItem(hwndList, &lvi)) {
  2709. type = ConvertLparam2Type(lvi.lParam);
  2710. } else {
  2711. assert(FALSE);
  2712. return FALSE;
  2713. }
  2714. if (lvi.iImage != IMAGE_LAYERS) {
  2715. return TRUE;
  2716. }
  2717. if (type == FIX_LIST_FLAG) {
  2718. pffl = (PFLAG_FIX_LIST) lvi.lParam;
  2719. } else if (type == FIX_LIST_SHIM) {
  2720. psfl = (PSHIM_FIX_LIST) lvi.lParam;
  2721. }
  2722. if (psfl) {
  2723. psf = psfl->pShimFix;
  2724. //
  2725. // We take care of it here if it's a LUA shim because we didn't add it to
  2726. // the layer fix list.
  2727. //
  2728. if (psf->strName == TEXT("LUARedirectFS") ||
  2729. psf->strName == TEXT("LUARedirectReg")) {
  2730. if (g_bIsLUALayerSelected) {
  2731. if (IDYES == MessageBox(hdlg, GetString(IDS_SHIMINLAYER), g_szAppName, MB_ICONWARNING | MB_YESNO)) {
  2732. //
  2733. // The only thing we need to do is changing the icon back to the shim
  2734. // icon. We need to change this for both shims in the layer.
  2735. //
  2736. ChangeShimIcon(TEXT("LUARedirectFS"));
  2737. ChangeShimIcon(TEXT("LUARedirectReg"));
  2738. g_bIsLUALayerSelected = FALSE;
  2739. } else {
  2740. return FALSE;
  2741. }
  2742. }
  2743. return TRUE;
  2744. }
  2745. //
  2746. // Othewise just go through the normal path.
  2747. //
  2748. bFoundInLayer = ShimPresentInLayersOfEntry(&g_pCurrentWizard->m_Entry,
  2749. psf,
  2750. NULL,
  2751. &plfl);
  2752. } else if (pffl) {
  2753. bFoundInLayer = FlagPresentInLayersOfEntry(&g_pCurrentWizard->m_Entry,
  2754. pffl->pFlagFix,
  2755. NULL,
  2756. &plfl);
  2757. }
  2758. if (bFoundInLayer) {
  2759. if (IDYES == MessageBox(hdlg, GetString(IDS_SHIMINLAYER), g_szAppName, MB_ICONWARNING | MB_YESNO)) {
  2760. s_bLayerPageRefresh = TRUE;
  2761. //
  2762. // For all the layers that have this shim,
  2763. // 1. Change the icons,
  2764. // 2. As for now, we retain the params just as the that in the layer
  2765. // 3. Remove the layer from the entry
  2766. //
  2767. PLAYER_FIX_LIST plflTemp = g_pCurrentWizard->m_Entry.pFirstLayer;
  2768. PLAYER_FIX_LIST plflTempPrev = NULL;
  2769. PLAYER_FIX_LIST plflTempNext = NULL;
  2770. //
  2771. // Go to the first layer that has this shim or flag
  2772. //
  2773. while (plflTemp) {
  2774. if (plflTemp == plfl) {
  2775. break;
  2776. } else {
  2777. plflTempPrev = plflTemp;
  2778. }
  2779. plflTemp = plflTemp->pNext;
  2780. }
  2781. while (plflTemp) {
  2782. //
  2783. // Now for all the layers following and including this layer,
  2784. // check if it has the selected shim or flag.
  2785. // If it has then, we change the icons of all the shims and flags that are present in this layer
  2786. // and remove it from the list of layers applied to this entry
  2787. //
  2788. bFoundInLayer = FALSE;
  2789. if (psfl) {
  2790. bFoundInLayer = IsShimInlayer(plflTemp->pLayerFix, psfl->pShimFix, NULL, NULL);
  2791. } else if (pffl) {
  2792. bFoundInLayer = IsFlagInlayer(plflTemp->pLayerFix, pffl->pFlagFix, NULL);
  2793. }
  2794. if (bFoundInLayer) {
  2795. ChangeShimFlagIcons(hdlg, plflTemp);
  2796. if (plflTempPrev == NULL) {
  2797. g_pCurrentWizard->m_Entry.pFirstLayer = plflTemp->pNext;
  2798. } else {
  2799. plflTempPrev->pNext = plflTemp->pNext;
  2800. }
  2801. plflTempNext = plflTemp->pNext;
  2802. //
  2803. // Do not do a DeleteLayerFixList here as this will remove
  2804. // all layer fix lists following this as well.
  2805. //
  2806. delete plflTemp;
  2807. plflTemp = plflTempNext;
  2808. } else {
  2809. plflTempPrev = plflTemp;
  2810. plflTemp = plflTemp->pNext;
  2811. }
  2812. }
  2813. } else {
  2814. return FALSE;
  2815. }
  2816. }
  2817. return TRUE;
  2818. }
  2819. void
  2820. ChangeShimIcon(
  2821. IN LPCTSTR pszItem
  2822. )
  2823. /*++
  2824. ChangeShimIcon
  2825. Desc: Changes the icon of the shim/flag with the name pszItem to a shim icon.
  2826. Params:
  2827. IN LPCTSTR pszItem: The name of the shim or flag
  2828. --*/
  2829. {
  2830. LVFINDINFO lvfind;
  2831. LVITEM lvi;
  2832. INT iIndex = -1;
  2833. ZeroMemory(&lvfind, sizeof(lvfind));
  2834. lvfind.flags = LVFI_STRING;
  2835. lvfind.psz = pszItem;
  2836. if ((iIndex = ListView_FindItem(s_hwndShimList, -1, &lvfind)) != -1) {
  2837. ZeroMemory(&lvi, sizeof(lvi));
  2838. lvi.mask = LVIF_IMAGE;
  2839. lvi.iItem = iIndex;
  2840. lvi.iSubItem = 0;
  2841. lvi.iImage = IMAGE_SHIM;
  2842. ListView_SetItem(s_hwndShimList, &lvi);
  2843. }
  2844. }
  2845. void
  2846. ChangeShimFlagIcons(
  2847. IN HWND hdlg,
  2848. IN PLAYER_FIX_LIST plfl
  2849. )
  2850. /*++
  2851. ChangeShimFlagIcons
  2852. Desc: For All the shims and flags that are present in plfl,
  2853. this routine changes their icons to indicate that they
  2854. are no longer part of some layer
  2855. Params:
  2856. IN HWND hdlg: The shims wizard page
  2857. IN PLAYER_FIX_LIST plfl: The layer for which is abou to be removed, so we need to
  2858. change the icons for all the shims and flags that are part of this layer.
  2859. Return:
  2860. void
  2861. --*/
  2862. {
  2863. PSHIM_FIX_LIST psfl = plfl->pLayerFix->pShimFixList;
  2864. PFLAG_FIX_LIST pffl = plfl->pLayerFix->pFlagFixList;
  2865. //
  2866. // First for the shims
  2867. //
  2868. while (psfl) {
  2869. assert(psfl->pShimFix);
  2870. ChangeShimIcon(psfl->pShimFix->strName.pszString);
  2871. psfl= psfl->pNext;
  2872. }
  2873. //
  2874. // Now for the flags
  2875. //
  2876. while (pffl) {
  2877. assert(pffl->pFlagFix);
  2878. ChangeShimIcon(pffl->pFlagFix->strName.pszString);
  2879. pffl = pffl->pNext;
  2880. }
  2881. }
  2882. BOOL
  2883. AddLuaShimsInEntry(
  2884. IN PDBENTRY pEntry,
  2885. OUT CSTRINGLIST* pstrlShimsAdded //(NULL)
  2886. )
  2887. /*++
  2888. AddLuaShimsInEntry
  2889. Desc: Adds the lua shims which are present in LUA layer to an entry. First checks
  2890. if the shim is already present, if yes does not add it.
  2891. Params:
  2892. IN PDBENTRY pEntry: The entry to which we want to add the lua shims
  2893. OUT CSTRINGLIST* pstrlShimsAdded(NULL): The names of the lua shims that this routine has added
  2894. We need this because if we are doing a test run then after the test-run is over, we
  2895. will have to remove these shims
  2896. Return:
  2897. TRUE: Success
  2898. FALSE: Otherwise
  2899. --*/
  2900. {
  2901. PLAYER_FIX plfLua = NULL;
  2902. PSHIM_FIX_LIST psflInLua = NULL;
  2903. PSHIM_FIX_LIST psflNew = NULL;
  2904. if (pEntry == NULL) {
  2905. assert(FALSE);
  2906. return FALSE;
  2907. }
  2908. plfLua = (PLAYER_FIX)FindFix(TEXT("LUA"), FIX_LAYER, &GlobalDataBase);
  2909. if (plfLua == NULL) {
  2910. assert(FALSE);
  2911. return FALSE;
  2912. } else {
  2913. //
  2914. // For all the shims in LUA add them to this entry. But first check if that
  2915. // shim is already present in the entry
  2916. //
  2917. psflInLua = plfLua->pShimFixList;
  2918. while (psflInLua) {
  2919. //
  2920. // Do not add a shim that is already present
  2921. //
  2922. if (!IsShimInEntry(psflInLua->pShimFix->strName,
  2923. pEntry)) {
  2924. psflNew = new SHIM_FIX_LIST;
  2925. if (psflNew == NULL) {
  2926. MEM_ERR;
  2927. break;
  2928. }
  2929. psflNew->pShimFix = psflInLua->pShimFix;
  2930. //
  2931. // Add this to the entry
  2932. //
  2933. psflNew->pNext = pEntry->pFirstShim;
  2934. pEntry->pFirstShim = psflNew;
  2935. //
  2936. // Keep track of what lua shims we have added
  2937. //
  2938. if (pstrlShimsAdded) {
  2939. pstrlShimsAdded->AddString(psflInLua->pShimFix->strName);
  2940. }
  2941. }
  2942. psflInLua = psflInLua->pNext;
  2943. }
  2944. }
  2945. return TRUE;
  2946. }
  2947. INT_PTR
  2948. GetAppNameDlgOnInitDialog(
  2949. IN HWND hDlg
  2950. )
  2951. /*++
  2952. GetAppNameDlgOnInitDialog
  2953. Desc: The handler of WM_INITDIALOG for the first wizard page
  2954. Params:
  2955. IN HWND hDlg: The first wizard page
  2956. Return:
  2957. TRUE
  2958. --*/
  2959. {
  2960. HWND hwndParent = GetParent(hDlg);
  2961. //
  2962. // Center the wizard window with respect to the main app window
  2963. //
  2964. CenterWindow(GetParent(hwndParent), hwndParent);
  2965. if (g_pCurrentWizard->m_bEditing
  2966. && (g_pCurrentWizard->m_Entry.pFirstFlag
  2967. || g_pCurrentWizard->m_Entry.pFirstLayer
  2968. || g_pCurrentWizard->m_Entry.pFirstShim
  2969. || g_pCurrentWizard->m_Entry.pFirstPatch)) {
  2970. //
  2971. // Edit an application fix. Some fixes already exist.
  2972. //
  2973. SetWindowText(hwndParent, CSTRING(IDS_WIZ_EDITFIX));
  2974. } else if (g_pCurrentWizard->m_bEditing) {
  2975. //
  2976. // There are no fixes but still we are editting. This means the entry contains
  2977. // an apphelp. We have to "add" a fix
  2978. //
  2979. SetWindowText(hwndParent, CSTRING(IDS_WIZ_ADDFIX));
  2980. } else {
  2981. //
  2982. // Create a new fix
  2983. //
  2984. SetWindowText(hwndParent, CSTRING(IDS_WIZ_CREATEFIX));
  2985. }
  2986. SendMessage(GetDlgItem(hDlg, IDC_NAME), EM_LIMITTEXT, (WPARAM)LIMIT_APP_NAME, (LPARAM)0);
  2987. SendMessage(GetDlgItem(hDlg, IDC_VENDOR), EM_LIMITTEXT, (WPARAM)LIMIT_APP_NAME, (LPARAM)0);
  2988. SendMessage(GetDlgItem(hDlg, IDC_EXEPATH), EM_LIMITTEXT, (WPARAM)MAX_PATH-1, (LPARAM)0);
  2989. SHAutoComplete(GetDlgItem(hDlg, IDC_EXEPATH), AUTOCOMPLETE);
  2990. if (g_pCurrentWizard->m_bEditing) {
  2991. //
  2992. // Make the App. text field and the exe name read only
  2993. //
  2994. SendMessage(GetDlgItem(hDlg, IDC_NAME),
  2995. EM_SETREADONLY,
  2996. TRUE,
  2997. 0);
  2998. SendMessage(GetDlgItem(hDlg, IDC_EXEPATH),
  2999. EM_SETREADONLY,
  3000. TRUE,
  3001. 0);
  3002. ENABLEWINDOW(GetDlgItem(hDlg, IDC_BROWSE), FALSE);
  3003. }
  3004. if (0 == g_pCurrentWizard->m_Entry.strAppName.Length()) {
  3005. g_pCurrentWizard->m_Entry.strAppName = GetString(IDS_DEFAULT_APP_NAME);
  3006. }
  3007. SetDlgItemText(hDlg, IDC_NAME, g_pCurrentWizard->m_Entry.strAppName);
  3008. if (g_pCurrentWizard->m_Entry.strVendor.Length() == 0) {
  3009. g_pCurrentWizard->m_Entry.strVendor = GetString(IDS_DEFAULT_VENDOR_NAME);
  3010. }
  3011. SetDlgItemText(hDlg, IDC_VENDOR, g_pCurrentWizard->m_Entry.strVendor);
  3012. if (g_pCurrentWizard->m_bEditing) {
  3013. SetDlgItemText(hDlg, IDC_EXEPATH, g_pCurrentWizard->m_Entry.strExeName);
  3014. }
  3015. SendMessage(GetDlgItem(hDlg, IDC_NAME), EM_SETSEL, 0,-1);
  3016. //
  3017. // Force proper Next button state.
  3018. //
  3019. SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDC_NAME, EN_CHANGE), 0);
  3020. return TRUE;
  3021. }
  3022. INT_PTR
  3023. GetAppNameDlgOnNotifyOnFinish_Next(
  3024. IN HWND hDlg
  3025. )
  3026. /*++
  3027. GetAppNameDlgOnNotifyOnFinish_Next
  3028. Desc: Handles the pressing of the next or the finish button in the first page of the wizard
  3029. Params:
  3030. IN HWND hDlg: The first page of the wizard
  3031. Return:
  3032. -1: Do not allow to comlete finish or navigate away from this page
  3033. There was some error (No shims, flags or layers have been selected)
  3034. 0: Otherwise
  3035. --*/
  3036. {
  3037. TCHAR szTemp[MAX_PATH];
  3038. INT_PTR ipReturn = 0;
  3039. CSTRING strTemp;
  3040. GetDlgItemText(hDlg, IDC_NAME, szTemp, ARRAYSIZE(szTemp));
  3041. CSTRING::Trim(szTemp);
  3042. if (!IsValidAppName(szTemp)) {
  3043. //
  3044. // The app name contains invalid chars
  3045. //
  3046. DisplayInvalidAppNameMessage(hDlg);
  3047. SetFocus(GetDlgItem(hDlg, IDC_NAME));
  3048. SetWindowLongPtr(hDlg, DWLP_MSGRESULT,-1);
  3049. ipReturn = -1;
  3050. goto End;
  3051. }
  3052. g_pCurrentWizard->m_Entry.strAppName = szTemp;
  3053. GetDlgItemText(hDlg, IDC_EXEPATH, szTemp, MAX_PATH);
  3054. strTemp = szTemp;
  3055. CSTRING::Trim(szTemp);
  3056. //
  3057. // Set the exe name and the long file name
  3058. //
  3059. if (!g_pCurrentWizard->m_bEditing) {
  3060. //
  3061. // Test if the file exists
  3062. //
  3063. HANDLE hFile = CreateFile(szTemp,
  3064. 0,
  3065. 0,
  3066. NULL,
  3067. OPEN_EXISTING,
  3068. FILE_ATTRIBUTE_NORMAL,
  3069. NULL);
  3070. if (INVALID_HANDLE_VALUE == hFile) {
  3071. //
  3072. // The file name could not be located
  3073. //
  3074. MessageBox(hDlg,
  3075. GetString(IDS_INVALIDEXE),
  3076. g_szAppName,
  3077. MB_ICONWARNING);
  3078. //
  3079. // We do not allow to go to the next page
  3080. //
  3081. SetWindowLongPtr(hDlg, DWLP_MSGRESULT,-1);
  3082. ipReturn = -1;
  3083. goto End;
  3084. }
  3085. CloseHandle(hFile);
  3086. //
  3087. // Set the full path
  3088. //
  3089. g_pCurrentWizard->m_Entry.strFullpath = szTemp;
  3090. g_pCurrentWizard->m_Entry.strFullpath.ConvertToLongFileName();
  3091. //
  3092. // Set the default mask for the matching attributes to be used
  3093. //
  3094. g_pCurrentWizard->dwMaskOfMainEntry = DEFAULT_MASK;
  3095. //
  3096. // Set the exe name that will be written in the xml
  3097. //
  3098. SafeCpyN(szTemp, (LPCTSTR)g_pCurrentWizard->m_Entry.strFullpath, ARRAYSIZE(szTemp));
  3099. PathStripPath(szTemp);
  3100. g_pCurrentWizard->m_Entry.strExeName= szTemp;
  3101. } else if (g_pCurrentWizard->m_Entry.strFullpath.Length() == 0) {
  3102. //
  3103. // This SDB was loaded from the disk
  3104. //
  3105. g_pCurrentWizard->m_Entry.strFullpath = szTemp;
  3106. }
  3107. //
  3108. // Set the vendor information
  3109. //
  3110. GetDlgItemText(hDlg, IDC_VENDOR, szTemp, ARRAYSIZE(szTemp));
  3111. if (CSTRING::Trim(szTemp)) {
  3112. g_pCurrentWizard->m_Entry.strVendor = szTemp;
  3113. } else {
  3114. g_pCurrentWizard->m_Entry.strVendor = GetString(IDS_DEFAULT_VENDOR_NAME);
  3115. }
  3116. End:
  3117. return ipReturn;
  3118. }
  3119. INT_PTR
  3120. GetAppNameDlgOnNotify(
  3121. IN HWND hDlg,
  3122. IN LPARAM lParam
  3123. )
  3124. /*++
  3125. GetAppNameDlgOnNotify
  3126. Desc: The handler of WM_NOTIFY for the first wizard page
  3127. Params:
  3128. IN HWND hDlg: The first wizard page
  3129. IN LPARAM lParam: The lParam that comes with WM_NOTIFY
  3130. Return: Please see the return types for the notification messages
  3131. Handler for PSN_* messages return -1 if the message should not be accepted
  3132. and 0 if the message has been handled properly
  3133. For other notification messages we return TRUE if we processed the message, FALSE otherwise
  3134. --*/
  3135. {
  3136. NMHDR* pHdr = (NMHDR*)lParam;
  3137. INT_PTR ipReturn = FALSE;
  3138. if (pHdr == NULL) {
  3139. return FALSE;
  3140. }
  3141. switch (pHdr->code) {
  3142. case PSN_SETACTIVE:
  3143. SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDC_NAME, EN_CHANGE), 0);
  3144. ipReturn = 0;
  3145. break;
  3146. case PSN_WIZFINISH:
  3147. case PSN_WIZNEXT:
  3148. ipReturn = GetAppNameDlgOnNotifyOnFinish_Next(hDlg);
  3149. break;
  3150. default: ipReturn = 0;
  3151. }
  3152. return ipReturn;
  3153. }
  3154. INT_PTR
  3155. GetAppNameDlgOnCommand(
  3156. IN HWND hDlg,
  3157. IN WPARAM wParam
  3158. )
  3159. /*++
  3160. GetAppNameDlgOnCommand
  3161. Desc: The handler of WM_COMMAND for the first wizard page
  3162. Params:
  3163. IN HWND hDlg: The first wizard page
  3164. IN WPARAM wParam: The wParam that comes with WM_COMMAND
  3165. Return:
  3166. TRUE: We processed the message
  3167. FALSE: Otherwise
  3168. --*/
  3169. {
  3170. INT_PTR ipReturn = TRUE;
  3171. switch (LOWORD(wParam)) {
  3172. case IDC_VENDOR:
  3173. case IDC_NAME:
  3174. case IDC_EXEPATH:
  3175. if (EN_CHANGE == HIWORD(wParam)) {
  3176. TCHAR szText[MAX_PATH_BUFFSIZE];
  3177. DWORD dwFlags;
  3178. BOOL bEnable;
  3179. *szText = 0;
  3180. GetWindowText(GetDlgItem(hDlg, IDC_NAME), szText, ARRAYSIZE(szText));
  3181. bEnable = ValidInput(szText);
  3182. GetWindowText(GetDlgItem(hDlg, IDC_EXEPATH), szText, MAX_PATH);
  3183. bEnable &= ValidInput(szText);
  3184. dwFlags = 0;
  3185. if (bEnable) {
  3186. dwFlags |= PSWIZB_NEXT;
  3187. if (g_pCurrentWizard->m_bEditing) {
  3188. dwFlags |= PSWIZB_FINISH;
  3189. }
  3190. } else {
  3191. if (g_pCurrentWizard->m_bEditing) {
  3192. dwFlags |= PSWIZB_DISABLEDFINISH;
  3193. }
  3194. }
  3195. SendMessage(GetParent(hDlg), PSM_SETWIZBUTTONS, 0, dwFlags);
  3196. }
  3197. break;
  3198. case IDC_BROWSE:
  3199. {
  3200. CSTRING szFilename;
  3201. HWND hwndFocus = GetFocus();
  3202. TCHAR szBuffer[512] = TEXT("");
  3203. GetString(IDS_EXEFILTER, szBuffer, ARRAYSIZE(szBuffer));
  3204. if (GetFileName(hDlg,
  3205. CSTRING(IDS_FINDEXECUTABLE),
  3206. szBuffer,
  3207. TEXT(""),
  3208. GetString(IDS_EXE_EXT),
  3209. OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST,
  3210. TRUE,
  3211. szFilename)) {
  3212. SetDlgItemText(hDlg, IDC_EXEPATH, szFilename);
  3213. //
  3214. // Force proper Next button state.
  3215. //
  3216. SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDC_EXEPATH, EN_CHANGE), 0);
  3217. }
  3218. SetFocus(hwndFocus);
  3219. break;
  3220. }
  3221. default: ipReturn = FALSE;
  3222. }
  3223. return ipReturn;
  3224. }
  3225. INT_PTR
  3226. SelectLayerDlgOnInitDialog(
  3227. IN HWND hDlg
  3228. )
  3229. /*++
  3230. SelectLayerDlgOnInitDialog
  3231. Desc: The handler of WM_INITDIALOG for the second wizard page
  3232. Params:
  3233. IN HWND hDlg: The second wizard page
  3234. Return:
  3235. TRUE: Message Handled
  3236. FALSE: There was some error. (Memory could not be allocated)
  3237. --*/
  3238. {
  3239. HWND hwndRadio;
  3240. //
  3241. // If we are creating a new fix then we choose WIN 95 layer by default
  3242. //
  3243. if (g_pCurrentWizard->m_bEditing == FALSE) {
  3244. hwndRadio = GetDlgItem(hDlg, IDC_RADIO_95);
  3245. } else {
  3246. hwndRadio = GetDlgItem(hDlg, IDC_RADIO_NONE);
  3247. }
  3248. SendMessage(hwndRadio, BM_SETCHECK, BST_CHECKED, 0);
  3249. s_hwndLayerList = GetDlgItem(hDlg, IDC_LAYERLIST);
  3250. ListView_SetImageList(s_hwndLayerList, g_hImageList, LVSIL_SMALL);
  3251. ListView_SetExtendedListViewStyleEx(s_hwndLayerList,
  3252. 0,
  3253. LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP | LVS_EX_CHECKBOXES);
  3254. //
  3255. // Add the Sytem Layers.
  3256. //
  3257. InsertColumnIntoListView(s_hwndLayerList, 0, 0, 100);
  3258. LVITEM lvi;
  3259. lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
  3260. lvi.iSubItem = 0;
  3261. lvi.iImage = IMAGE_LAYERS;
  3262. UINT uCount = 0;
  3263. PLAYER_FIX plf = GlobalDataBase.pLayerFixes;
  3264. while (plf) {
  3265. if (!IsOsLayer(plf->strName)) {
  3266. PLAYER_FIX_LIST plfl = new LAYER_FIX_LIST;
  3267. if (plfl == NULL) {
  3268. MEM_ERR;
  3269. return FALSE;
  3270. }
  3271. plfl->pLayerFix = plf;
  3272. lvi.pszText = plf->strName;
  3273. lvi.iItem = uCount;
  3274. lvi.lParam = (LPARAM)plfl;
  3275. INT iIndex = ListView_InsertItem(s_hwndLayerList, &lvi);
  3276. if (g_pCurrentWizard->m_bEditing) {
  3277. PLAYER_FIX_LIST plflExists = NULL;
  3278. if (LayerPresent (plf, &g_pCurrentWizard->m_Entry, &plflExists)) {
  3279. assert(plflExists);
  3280. ListView_SetCheckState(s_hwndLayerList, iIndex, TRUE);
  3281. }
  3282. }
  3283. uCount++;
  3284. } else if (g_pCurrentWizard->m_bEditing) {
  3285. if (LayerPresent (plf, &g_pCurrentWizard->m_Entry, NULL)) {
  3286. //
  3287. // Set the correct Radio Button
  3288. //
  3289. INT id = 0;
  3290. //
  3291. // DeSelect All
  3292. //
  3293. CheckDlgButton(hDlg, IDC_RADIO_95, BST_UNCHECKED);
  3294. CheckDlgButton(hDlg, IDC_RADIO_NT, BST_UNCHECKED);
  3295. CheckDlgButton(hDlg, IDC_RADIO_98, BST_UNCHECKED);
  3296. CheckDlgButton(hDlg, IDC_RADIO_2K, BST_UNCHECKED);
  3297. CheckDlgButton(hDlg, IDC_RADIO_NONE, BST_UNCHECKED);
  3298. if (lstrcmpi(plf->strName, s_arszOsLayers[0]) == 0) {
  3299. id = IDC_RADIO_95;
  3300. } else if (lstrcmpi(plf->strName, s_arszOsLayers[1]) == 0) {
  3301. id = IDC_RADIO_NT;
  3302. } else if (lstrcmpi(plf->strName, s_arszOsLayers[2]) == 0) {
  3303. id = IDC_RADIO_98;
  3304. } else if (lstrcmpi(plf->strName, s_arszOsLayers[3]) == 0) {
  3305. id = IDC_RADIO_2K;
  3306. }
  3307. CheckDlgButton(hDlg, id, BST_CHECKED);
  3308. }
  3309. }
  3310. plf = plf->pNext;
  3311. }
  3312. //
  3313. // Add the Custom Layers
  3314. //
  3315. plf = (g_pCurrentWizard->m_pDatabase->type == DATABASE_TYPE_WORKING) ?
  3316. g_pCurrentWizard->m_pDatabase->pLayerFixes : NULL;
  3317. while (plf) {
  3318. PLAYER_FIX_LIST plfl = new LAYER_FIX_LIST;
  3319. if (plfl == NULL) {
  3320. MEM_ERR;
  3321. return FALSE;
  3322. }
  3323. plfl->pLayerFix = plf;
  3324. lvi.pszText = plf->strName;
  3325. lvi.iItem = uCount;
  3326. lvi.lParam = (LPARAM)plfl;
  3327. INT iIndex = ListView_InsertItem(s_hwndLayerList, &lvi);
  3328. PLAYER_FIX_LIST plflExists = NULL;
  3329. if (g_pCurrentWizard->m_bEditing && LayerPresent(plf,
  3330. &g_pCurrentWizard->m_Entry,
  3331. &plflExists)) {
  3332. assert(plflExists);
  3333. ListView_SetCheckState(s_hwndLayerList, iIndex, TRUE);
  3334. }
  3335. uCount++;
  3336. plf = plf->pNext;
  3337. }
  3338. return TRUE;
  3339. }
  3340. INT_PTR
  3341. SelectLayerDlgOnDestroy(
  3342. void
  3343. )
  3344. /*++
  3345. SelectLayerDlgOnDestroy
  3346. Desc: The handler of WM_DESTROY for the second wizard page
  3347. The list view of this page contains pointers to LAYER_FIX_LIST objects
  3348. and these have to be freed here
  3349. Params:
  3350. IN HWND hDlg: The second wizard page
  3351. Return:
  3352. TRUE
  3353. --*/
  3354. {
  3355. UINT uCount = ListView_GetItemCount(s_hwndLayerList);
  3356. for (UINT uIndex = 0; uIndex < uCount; ++uIndex) {
  3357. LVITEM Item;
  3358. Item.mask = LVIF_PARAM;
  3359. Item.iItem = uIndex;
  3360. Item.iSubItem = 0;
  3361. if (!ListView_GetItem(s_hwndLayerList, &Item)) {
  3362. assert(FALSE);
  3363. continue;
  3364. }
  3365. TYPE type = ((PDS_TYPE)Item.lParam)->type ;
  3366. if (type == FIX_LIST_LAYER) {
  3367. delete ((PLAYER_FIX_LIST)Item.lParam);
  3368. } else {
  3369. assert(FALSE);
  3370. }
  3371. }
  3372. return TRUE;
  3373. }
  3374. void
  3375. DoLayersTestRun(
  3376. IN HWND hDlg
  3377. )
  3378. /*++
  3379. DoLayersTestRun
  3380. Desc: Does the test run when we are on the layers page
  3381. Params:
  3382. IN HWND hDlg: The layer page in the wizard
  3383. Return:
  3384. void
  3385. --*/
  3386. {
  3387. CSTRINGLIST strlAddedLuaShims;
  3388. PSHIM_FIX_LIST psfl = NULL;
  3389. PSHIM_FIX_LIST psflNext = NULL;
  3390. PSHIM_FIX_LIST psflPrev = NULL;
  3391. INT iCountAddedLuaShims = 0;
  3392. if (g_bAdmin == FALSE) {
  3393. //
  3394. // Test run will need to call sdbinst.exe which will not run if we are
  3395. // not an admin
  3396. //
  3397. MessageBox(hDlg,
  3398. GetString(IDS_ERRORNOTADMIN),
  3399. g_szAppName,
  3400. MB_ICONINFORMATION);
  3401. goto End;
  3402. }
  3403. if (!HandleLayersNext(hDlg, TRUE, &strlAddedLuaShims)) {
  3404. //
  3405. // There were no layers, shims, patches for this entry
  3406. //
  3407. MessageBox(hDlg, CSTRING(IDS_SELECTFIX), g_szAppName, MB_ICONWARNING);
  3408. goto End;
  3409. }
  3410. //
  3411. // Invoke test run dialog. Please make sure that this function does not return till the
  3412. // app has finished executing.
  3413. //
  3414. TestRun(&g_pCurrentWizard->m_Entry,
  3415. &g_pCurrentWizard->m_Entry.strFullpath,
  3416. NULL,
  3417. hDlg);
  3418. //
  3419. // <HACK>This is a hack!!!. TestRun launches a process using CreateProcess
  3420. // and then the modal wizard starts behaving like a modeless wizard
  3421. //
  3422. ENABLEWINDOW(g_hDlg, FALSE);
  3423. //
  3424. // Now test run is over. So we should now check if we had to add any lua shims
  3425. // and if yes, we must remove those shims
  3426. //
  3427. for (PSTRLIST pslist = strlAddedLuaShims.m_pHead;
  3428. pslist != NULL;
  3429. pslist = pslist->pNext) {
  3430. psfl = g_pCurrentWizard->m_Entry.pFirstShim;
  3431. psflPrev = NULL;
  3432. //
  3433. // For all the shims that are in the entry, check if it is
  3434. // same as the one in pslist, if yes remove it
  3435. //
  3436. while (psfl) {
  3437. if (psfl->pShimFix->strName == pslist->szStr) {
  3438. //
  3439. // Found. We have to remove this shim list from this entry
  3440. //
  3441. if (psflPrev == NULL) {
  3442. g_pCurrentWizard->m_Entry.pFirstShim = psfl->pNext;
  3443. } else {
  3444. psflPrev->pNext = psfl->pNext;
  3445. }
  3446. delete psfl;
  3447. break;
  3448. } else {
  3449. //
  3450. // Keep looking
  3451. //
  3452. psflPrev = psfl;
  3453. psfl = psfl->pNext;
  3454. }
  3455. }
  3456. }
  3457. End:
  3458. SetActiveWindow(hDlg);
  3459. SetFocus(hDlg);
  3460. }
  3461. INT_PTR
  3462. SelectLayerDlgOnCommand(
  3463. IN HWND hDlg,
  3464. IN WPARAM wParam
  3465. )
  3466. /*++
  3467. SelectLayerDlgOnCommand
  3468. Desc: The handler of WM_COMMAND for the second wizard page
  3469. Params:
  3470. IN HWND hDlg: The second wizard page
  3471. IN WPARAM wParam: The wParam that comes with WM_COMMAND
  3472. Return:
  3473. TRUE: We processed the message
  3474. FALSE: Otherwise
  3475. --*/
  3476. {
  3477. INT_PTR ipReturn = TRUE;
  3478. switch (LOWORD(wParam)) {
  3479. case IDC_TESTRUN:
  3480. DoLayersTestRun(hDlg);
  3481. break;
  3482. default: ipReturn = FALSE;
  3483. }
  3484. return ipReturn;
  3485. }
  3486. INT_PTR
  3487. SelectLayerDlgOnNotify(
  3488. IN HWND hDlg,
  3489. IN LPARAM lParam
  3490. )
  3491. /*++
  3492. SelectLayerDlgOnNotify
  3493. Desc: The handler of WM_NOTIFY for the second wizard page
  3494. Params:
  3495. IN HWND hDlg: The second wizard page
  3496. IN LPARAM lParam: The lParam that comes with WM_NOTIFY
  3497. Return: Please see the return types for the notification messages
  3498. Handler for PSN_* messages return -1 if the message should not be accepted
  3499. and 0 if the message has been handled properly
  3500. For other notification messages we return TRUE if we processed the message,
  3501. FALSE otherwise
  3502. --*/
  3503. {
  3504. NMHDR* pHdr = (NMHDR*)lParam;
  3505. LPARAM buttons = 0;
  3506. INT_PTR ipRet = 0;
  3507. if (pHdr->hwndFrom == s_hwndLayerList) {
  3508. return HandleLayerListNotification(hDlg, lParam);
  3509. }
  3510. switch (pHdr->code) {
  3511. case PSN_SETACTIVE:
  3512. buttons = PSWIZB_BACK | PSWIZB_NEXT;
  3513. SendMessage(GetParent(hDlg), PSM_SETWIZBUTTONS, 0, buttons);
  3514. if (s_bLayerPageRefresh) {
  3515. CheckLayers(hDlg);
  3516. }
  3517. s_bLayerPageRefresh = FALSE;
  3518. ipRet = 0;
  3519. break;
  3520. case PSN_WIZFINISH:
  3521. HandleLayersNext(hDlg, TRUE);
  3522. if (g_pCurrentWizard->m_Entry.pFirstLayer == NULL
  3523. && g_pCurrentWizard->m_Entry.pFirstShim == NULL
  3524. && g_pCurrentWizard->m_Entry.pFirstFlag == NULL) {
  3525. //
  3526. // No fix has been selected
  3527. //
  3528. MessageBox(hDlg,
  3529. CSTRING(IDS_SELECTFIX),
  3530. g_szAppName,
  3531. MB_ICONWARNING);
  3532. SetWindowLongPtr(hDlg, DWLP_MSGRESULT,-1);
  3533. ipRet = -1;
  3534. } else {
  3535. ipRet = 0;
  3536. }
  3537. break;
  3538. case PSN_WIZNEXT:
  3539. HandleLayersNext(hDlg, FALSE);
  3540. g_bLayersChanged = TRUE;
  3541. ipRet= 0;
  3542. break;
  3543. default: ipRet = FALSE;
  3544. }
  3545. return ipRet;
  3546. }
  3547. INT_PTR
  3548. SelectShimsDlgOnInitDialog(
  3549. IN HWND hDlg
  3550. )
  3551. /*++
  3552. SelectShimsDlgOnInitDialog
  3553. Desc: The handler of WM_INITDIALOG for the third wizard page
  3554. Params:
  3555. IN HWND hDlg: The third wizard page
  3556. Return:
  3557. TRUE
  3558. --*/
  3559. {
  3560. UINT uCount = 0;
  3561. LPARAM uTime = 32767;
  3562. s_bAllShown = TRUE;
  3563. s_hwndShimList = GetDlgItem(hDlg, IDC_SHIMLIST);
  3564. ListView_SetImageList(GetDlgItem(hDlg, IDC_SHIMLIST), g_hImageList, LVSIL_SMALL);
  3565. ListView_SetExtendedListViewStyleEx(s_hwndShimList,
  3566. 0,
  3567. LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP | LVS_EX_CHECKBOXES);
  3568. //
  3569. // Add the columns
  3570. //
  3571. InsertColumnIntoListView(s_hwndShimList,
  3572. CSTRING(IDS_COL_FIXNAME),
  3573. 0,
  3574. g_bExpert ? 50 : 100);
  3575. if (g_bExpert) {
  3576. InsertColumnIntoListView(s_hwndShimList, CSTRING(IDS_COL_CMDLINE), 1, 30);
  3577. InsertColumnIntoListView(s_hwndShimList, CSTRING(IDS_COL_MODULE), 2, 20);
  3578. } else {
  3579. ShowWindow(GetDlgItem(hDlg, IDC_PARAMS), SW_HIDE);
  3580. }
  3581. ShowItems(hDlg);
  3582. SetTimer(hDlg, 0, 100, NULL);
  3583. s_hwndToolTipList = ListView_GetToolTips(s_hwndShimList);
  3584. SendMessage(s_hwndToolTipList, TTM_SETDELAYTIME, TTDT_AUTOPOP, (LPARAM)MAKELONG(uTime, 0));
  3585. SendMessage(s_hwndToolTipList, TTM_SETDELAYTIME, TTDT_INITIAL, (LPARAM)0);
  3586. SendMessage(s_hwndToolTipList, TTM_SETMAXTIPWIDTH, 0, 100);
  3587. return TRUE;
  3588. }
  3589. void
  3590. DoShimTestRun(
  3591. IN HWND hDlg
  3592. )
  3593. /*++
  3594. DoShimTestRun
  3595. Desc: Does the test run when we are on the shims page
  3596. Params:
  3597. IN HWND hDlg: The shim page in the wizard
  3598. Return:
  3599. void
  3600. --*/
  3601. {
  3602. PSHIM_FIX_LIST psflInEntry = NULL;
  3603. if (g_bAdmin == FALSE) {
  3604. //
  3605. // Only admins can do a test run because we need to call sdbinst.exe, which
  3606. // can run only in admin mode
  3607. //
  3608. MessageBox(hDlg,
  3609. GetString(IDS_ERRORNOTADMIN),
  3610. g_szAppName,
  3611. MB_ICONINFORMATION);
  3612. goto End;
  3613. }
  3614. //
  3615. // We need to save the shims that have been applied to the entry
  3616. // before we do a test run. Because we add the shims to the entry during test run,
  3617. // when we will end doing test run we will wish to revert to the shims that were
  3618. // present in the entry. Otherwise if the user clears some of the shims and goes
  3619. // to the layers page then we will still have the shims applied to the entry
  3620. //
  3621. if (g_pCurrentWizard->m_Entry.pFirstShim) {
  3622. //
  3623. // Get the applied shims
  3624. //
  3625. CopyShimFixList(&psflInEntry, &g_pCurrentWizard->m_Entry.pFirstShim);
  3626. }
  3627. if (!HandleShimsNext(hDlg)) {
  3628. //
  3629. // No fixes have been selected
  3630. //
  3631. MessageBox(hDlg,
  3632. CSTRING(IDS_SELECTFIX),
  3633. g_szAppName,
  3634. MB_ICONWARNING);
  3635. goto End;
  3636. }
  3637. TestRun(&g_pCurrentWizard->m_Entry,
  3638. &g_pCurrentWizard->m_Entry.strFullpath,
  3639. NULL,
  3640. hDlg);
  3641. //
  3642. // <HACK>This is a hack!!!. TestRun launches a process using CreateProcess
  3643. // and then the modal wizard starts behaving like a modeless wizard
  3644. //
  3645. ENABLEWINDOW(g_hDlg, FALSE);
  3646. SetActiveWindow(hDlg);
  3647. SetFocus(hDlg);
  3648. //
  3649. // Revert to the shims that were actually applied before we did a test run
  3650. //
  3651. CopyShimFixList(&g_pCurrentWizard->m_Entry.pFirstShim, &psflInEntry);
  3652. End:
  3653. if (psflInEntry) {
  3654. //
  3655. // Some shims were already applied to this entry (g_pCurrentWizard->m_Entry)
  3656. // and we psflInEntry has
  3657. // been populated with them, we must free this linked list as we no longer
  3658. // need it
  3659. //
  3660. DeleteShimFixList(psflInEntry);
  3661. psflInEntry = NULL;
  3662. }
  3663. }
  3664. INT_PTR
  3665. SelectShimsDlgOnCommand(
  3666. IN HWND hDlg,
  3667. IN WPARAM wParam
  3668. )
  3669. /*++
  3670. SelectShimsDlgOnCommand
  3671. Desc: The handler of WM_COMMAND for the second wizard page
  3672. Params:
  3673. IN HWND hDlg: The second wizard page
  3674. IN WPARAM wParam: The wParam that comes with WM_COMMAND
  3675. Return:
  3676. TRUE: We processed the message
  3677. FALSE: Otherwise
  3678. --*/
  3679. {
  3680. UINT uCount = ListView_GetItemCount(s_hwndShimList);
  3681. INT_PTR ipReturn = TRUE;
  3682. switch (LOWORD(wParam)) {
  3683. case IDC_CLEARALL:
  3684. for (UINT uIndex = 0; uIndex < uCount; ++uIndex) {
  3685. ListView_SetCheckState(s_hwndShimList, uIndex, FALSE);
  3686. }
  3687. SetTimer(hDlg, 0, 100, NULL);
  3688. break;
  3689. case IDC_SHOW:
  3690. {
  3691. if (s_bAllShown) {
  3692. //
  3693. // Now show only the selected shims
  3694. //
  3695. ShowSelected(hDlg);
  3696. } else {
  3697. //
  3698. // Now show all the shims
  3699. //
  3700. ShowItems(hDlg);
  3701. }
  3702. //
  3703. // Select the first item. We need to do this so that, we can disable
  3704. // the params button if the shim is a part of a layer.
  3705. //
  3706. SetFocus(s_hwndShimList);
  3707. ListView_SetSelectionMark(s_hwndShimList, 0);
  3708. LVITEM lvi;
  3709. lvi.mask = LVIF_STATE;
  3710. lvi.iItem = 0;
  3711. lvi.iSubItem = 0;
  3712. lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
  3713. lvi.state = LVIS_FOCUSED | LVIS_SELECTED;
  3714. ListView_SetItem(s_hwndShimList, &lvi);
  3715. SetTimer(hDlg, 0, 100, NULL);
  3716. break;
  3717. }
  3718. case IDC_PARAMS:
  3719. ShowParams(hDlg, GetDlgItem(hDlg, IDC_SHIMLIST));
  3720. break;
  3721. case IDC_TESTRUN:
  3722. DoShimTestRun(hDlg);
  3723. break;
  3724. default: ipReturn = FALSE;
  3725. }
  3726. return ipReturn;
  3727. }
  3728. INT_PTR
  3729. SelectShimsDlgOnTimer(
  3730. IN HWND hDlg
  3731. )
  3732. /*++
  3733. SelectShimsDlgOnTimer
  3734. Desc: Handles the WM_TIMER Message and shows the count of all the shims that have
  3735. been selected
  3736. Params:
  3737. IN HWND hDlg: The shim selection page. This is the third wizard page
  3738. Return: TRUE
  3739. --*/
  3740. {
  3741. UINT uTotal = 0;
  3742. UINT uSelected = 0;
  3743. UINT uCount = 0;
  3744. CSTRING szText;
  3745. DWORD dwFlags;
  3746. KillTimer(hDlg, 0);
  3747. //
  3748. // Count the selected shims
  3749. //
  3750. uCount = ListView_GetItemCount(s_hwndShimList);
  3751. for (UINT uIndex = 0; uIndex < uCount; ++uIndex) {
  3752. if (ListView_GetCheckState(s_hwndShimList, uIndex)) {
  3753. ++uSelected;
  3754. }
  3755. }
  3756. ENABLEWINDOW(GetDlgItem(hDlg, IDC_CLEARALL),
  3757. uSelected == 0 ? FALSE : TRUE);
  3758. szText.Sprintf(TEXT("%s %d of %d"), GetString(IDS_SELECTED), uSelected, uCount);
  3759. SetWindowText(GetDlgItem(hDlg, IDC_STATUS),(LPCTSTR)szText);
  3760. dwFlags = PSWIZB_BACK | PSWIZB_NEXT;
  3761. if (0 == uSelected && !g_pCurrentWizard->m_Entry.pFirstLayer) {
  3762. dwFlags &= ~PSWIZB_NEXT;
  3763. }
  3764. SendMessage(GetParent(hDlg), PSM_SETWIZBUTTONS, 0, dwFlags);
  3765. return TRUE;
  3766. }
  3767. INT_PTR
  3768. SelectShimsDlgOnDestroy(
  3769. void
  3770. )
  3771. /*++
  3772. SelectShimsDlgOnDestroy
  3773. Desc: The handler of WM_DESTROY for the third wizard page
  3774. The list view of this page contains pointers to SHIM_FIX_LIST and
  3775. FLAG_FIX_LIST objects and these have to be freed here
  3776. Params:
  3777. IN HWND hDlg: The third wizard page
  3778. Return:
  3779. TRUE
  3780. --*/
  3781. {
  3782. UINT uCount = ListView_GetItemCount(s_hwndShimList);
  3783. TYPE type;
  3784. LVITEM Item;
  3785. for (UINT uIndex = 0; uIndex < uCount; ++uIndex) {
  3786. Item.mask = LVIF_PARAM;
  3787. Item.iItem = uIndex;
  3788. Item.iSubItem = 0;
  3789. if (!ListView_GetItem(s_hwndShimList, &Item)) {
  3790. assert(FALSE);
  3791. continue;
  3792. }
  3793. type = ((PDS_TYPE)Item.lParam)->type ;
  3794. if (type == FIX_LIST_SHIM) {
  3795. DeleteShimFixList((PSHIM_FIX_LIST)Item.lParam);
  3796. } else if (type == FIX_LIST_FLAG) {
  3797. DeleteFlagFixList((PFLAG_FIX_LIST)Item.lParam);
  3798. }
  3799. }
  3800. return TRUE;
  3801. }
  3802. INT_PTR
  3803. SelectShimsDlgOnNotifyFinish_Next(
  3804. IN HWND hDlg
  3805. )
  3806. /*++
  3807. SelectShimsDlgOnNotifyFinish_Next
  3808. Desc: Handles the pressing of the next or finish button in the shim page
  3809. Params:
  3810. IN HWND hdlg: The shim page in the wizard
  3811. Return:
  3812. -1: Do not allow to comlete finish or navigate away from this page
  3813. There was some error (No shims, flags or layers have been selected)
  3814. 0: Otherwise
  3815. --*/
  3816. {
  3817. INT ipReturn = 0;
  3818. HandleShimsNext(hDlg);
  3819. if (g_pCurrentWizard->m_Entry.pFirstLayer == NULL &&
  3820. g_pCurrentWizard->m_Entry.pFirstShim == NULL &&
  3821. g_pCurrentWizard->m_Entry.pFirstFlag == NULL) {
  3822. //
  3823. // No shim, flags or layers have been selected
  3824. //
  3825. MessageBox(hDlg,
  3826. CSTRING(IDS_SELECTFIX),
  3827. g_szAppName,
  3828. MB_ICONWARNING);
  3829. SetWindowLongPtr(hDlg, DWLP_MSGRESULT,-1);
  3830. ipReturn = -1;
  3831. goto End;
  3832. } else {
  3833. ipReturn = 0;
  3834. }
  3835. End:
  3836. return ipReturn;
  3837. }
  3838. INT_PTR
  3839. SelectShimsDlgOnNotifyOnSetActive(
  3840. IN HWND hDlg
  3841. )
  3842. /*++
  3843. SelectShimsDlgOnNotifyOnSetActive
  3844. Desc: Handles the PSN_SETACTIVE notification in the shim page. Sets the focus
  3845. to the list view and selects the first item in that.
  3846. Params:
  3847. IN HWND hdlg: The shim page in the wizard
  3848. Return:
  3849. 0
  3850. --*/
  3851. {
  3852. INT_PTR ipReturn = 0;
  3853. //
  3854. // If we are coming from the layers page, then we might need to again refresh
  3855. // the list of shims, as it is possible that some of them might have been in the
  3856. // layers chosen. (Some might get removed as well, because the layer was de-selected)
  3857. //
  3858. if (g_bLayersChanged) {
  3859. SetCursor(LoadCursor(NULL, IDC_WAIT));
  3860. ShowItems(hDlg);
  3861. SetTimer(hDlg, 0, 100, NULL);
  3862. SetCursor(LoadCursor(NULL, IDC_ARROW));
  3863. }
  3864. LPARAM buttons = PSWIZB_BACK | PSWIZB_NEXT;
  3865. SendMessage(GetParent(hDlg), PSM_SETWIZBUTTONS, 0, buttons);
  3866. //
  3867. // Select the first item. We need to do this so that, we can disable
  3868. // the params button if the shim is a part of a layer.
  3869. //
  3870. SetFocus(s_hwndShimList);
  3871. ListView_SetSelectionMark(s_hwndShimList, 0);
  3872. LVITEM lvi;
  3873. lvi.mask = LVIF_STATE;
  3874. lvi.iItem = 0;
  3875. lvi.iSubItem = 0;
  3876. lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
  3877. lvi.state = LVIS_FOCUSED | LVIS_SELECTED;
  3878. ListView_SetItem(s_hwndShimList, &lvi);
  3879. return ipReturn;
  3880. }
  3881. INT_PTR
  3882. SelectShimsDlgOnNotifyOnClick(
  3883. IN HWND hDlg
  3884. )
  3885. /*++
  3886. SelectShimsDlgOnNotifyOnClick
  3887. Desc: Handles the NM_CLICK notification in the shim page. This actually changes
  3888. the state of the check box in in the shim list view
  3889. Params:
  3890. IN HWND hdlg: The shim page in the wizard
  3891. Return:
  3892. TRUE
  3893. --*/
  3894. {
  3895. INT_PTR ipReturn = TRUE;
  3896. LVHITTESTINFO lvhti;
  3897. GetCursorPos(&lvhti.pt);
  3898. ScreenToClient(s_hwndShimList, &lvhti.pt);
  3899. ListView_HitTest(s_hwndShimList, &lvhti);
  3900. //
  3901. // If the check box state has changed,
  3902. // toggle the selection.
  3903. //
  3904. if (lvhti.flags & LVHT_ONITEMSTATEICON) {
  3905. INT iPos = ListView_GetSelectionMark(s_hwndShimList);
  3906. if (iPos != -1) {
  3907. //
  3908. // De-select it.
  3909. //
  3910. ListView_SetItemState(s_hwndShimList,
  3911. iPos,
  3912. 0,
  3913. LVIS_FOCUSED | LVIS_SELECTED);
  3914. }
  3915. }
  3916. ListView_SetItemState(s_hwndShimList,
  3917. lvhti.iItem,
  3918. LVIS_FOCUSED | LVIS_SELECTED,
  3919. LVIS_FOCUSED | LVIS_SELECTED);
  3920. ListView_SetSelectionMark(s_hwndShimList, lvhti.iItem);
  3921. SetTimer(hDlg, 0, 100, NULL);
  3922. if (ListView_GetSelectedCount(s_hwndShimList) == 0) {
  3923. ENABLEWINDOW(GetDlgItem(hDlg, IDC_PARAMS), FALSE);
  3924. }
  3925. ipReturn = TRUE;
  3926. return ipReturn;
  3927. }
  3928. INT_PTR
  3929. SelectShimsDlgOnNotifyOnLVItemChanged(
  3930. IN HWND hDlg,
  3931. IN LPARAM lParam
  3932. )
  3933. /*++
  3934. SelectShimsDlgOnNotifyOnLVItemChanged
  3935. Desc: Handles the LVN_ITEMCHANGED notification in the shim page. We handle
  3936. this mesage so that we can enable disable the 'Parameters'button that
  3937. is visible when we are in expert mode
  3938. Params:
  3939. IN HWND hdlg: The shim page in the wizard
  3940. IN LPARAM lParam: The lParam that comes with WM_NOTIFY. This is typecasted
  3941. to a LPNMLISTVIEW.
  3942. Return:
  3943. TRUE
  3944. --*/
  3945. {
  3946. LPNMLISTVIEW lpnmlv;
  3947. INT_PTR ipReturn = 0;
  3948. if (s_hwndToolTipList) {
  3949. SendMessage(s_hwndToolTipList, TTM_UPDATE, 0, 0);
  3950. }
  3951. lpnmlv = (LPNMLISTVIEW)lParam;
  3952. if (lpnmlv && (lpnmlv->uChanged & LVIF_STATE)) {
  3953. if (lpnmlv->uNewState & LVIS_SELECTED) {
  3954. //
  3955. // For Shims or flags that are part of layers we should not be
  3956. // able to customize the parameters.
  3957. // We check if it is a part of a layer by checking the icon
  3958. // If the icon type is IMAGE_SHIM then that is not a part of a layer
  3959. //
  3960. LVITEM lvi;
  3961. lvi.mask = LVIF_IMAGE;
  3962. lvi.iItem = lpnmlv->iItem;
  3963. lvi.iSubItem = 0;
  3964. if (ListView_GetItem(s_hwndShimList, &lvi)) {
  3965. if (lvi.iImage == IMAGE_SHIM) {
  3966. ENABLEWINDOW(GetDlgItem(hDlg, IDC_PARAMS), TRUE);
  3967. } else {
  3968. ENABLEWINDOW(GetDlgItem(hDlg, IDC_PARAMS), FALSE);
  3969. }
  3970. } else {
  3971. assert(FALSE);
  3972. ENABLEWINDOW(GetDlgItem(hDlg, IDC_PARAMS), FALSE);
  3973. }
  3974. }
  3975. if ((lpnmlv->uChanged & LVIF_STATE)
  3976. && (((lpnmlv->uNewState ^ lpnmlv->uOldState) >> 12) != 0)
  3977. && !ListView_GetCheckState(s_hwndShimList, lpnmlv->iItem)
  3978. && g_bNowTest) {
  3979. if (!HandleShimDeselect(hDlg, lpnmlv->iItem)) {
  3980. ListView_SetCheckState(s_hwndShimList, lpnmlv->iItem, TRUE);
  3981. }
  3982. }
  3983. }
  3984. ipReturn = TRUE;
  3985. return ipReturn;
  3986. }
  3987. INT_PTR
  3988. SelectShimsDlgOnNotifyOnLV_Tip(
  3989. IN HWND hDlg,
  3990. IN LPARAM lParam
  3991. )
  3992. /*++
  3993. SelectShimsDlgOnNotifyOnLV_Tip
  3994. Desc: Handles the LVN_GETINFOTIP notification in the shim page. Generates the
  3995. tool tip showing the description of the shim or flag
  3996. Params:
  3997. IN HWND hdlg: The shim page in the wizard
  3998. IN LPARAM lParam: The lParam that comes with WM_NOTIFY. This is typecasted
  3999. to a LPNMLVGETINFOTIP.
  4000. Return:
  4001. TRUE
  4002. --*/
  4003. {
  4004. LPNMLVGETINFOTIP lpGetInfoTip = (LPNMLVGETINFOTIP)lParam;
  4005. INT_PTR ipReturn = TRUE;
  4006. TCHAR szText[256];
  4007. LVITEM lvItem;
  4008. CSTRING strToolTip;
  4009. *szText = 0;
  4010. if (lpGetInfoTip) {
  4011. //
  4012. // Get the lParam and the text of the item.
  4013. //
  4014. lvItem.mask = LVIF_PARAM | LVIF_TEXT;
  4015. lvItem.iItem = lpGetInfoTip->iItem;
  4016. lvItem.iSubItem = 0;
  4017. lvItem.pszText = szText;
  4018. lvItem.cchTextMax = ARRAYSIZE(szText);
  4019. if (!ListView_GetItem(s_hwndShimList, &lvItem)) {
  4020. assert(FALSE);
  4021. goto End;
  4022. }
  4023. GetDescriptionString(lvItem.lParam,
  4024. strToolTip,
  4025. s_hwndToolTipList,
  4026. lvItem.pszText,
  4027. NULL,
  4028. s_hwndShimList,
  4029. lpGetInfoTip->iItem);
  4030. if (strToolTip.Length() > 0) {
  4031. SafeCpyN(lpGetInfoTip->pszText,
  4032. strToolTip.pszString,
  4033. lpGetInfoTip->cchTextMax);
  4034. }
  4035. }
  4036. End:
  4037. ipReturn = TRUE;
  4038. return ipReturn;
  4039. }
  4040. INT_PTR
  4041. SelectShimsDlgOnNotify(
  4042. IN HWND hDlg,
  4043. IN LPARAM lParam
  4044. )
  4045. /*++
  4046. SelectShimsDlgOnNotify
  4047. Desc: The handler of WM_NOTIFY for the second wizard page
  4048. Params:
  4049. IN HWND hDlg: The second wizard page
  4050. IN LPARAM lParam: The lParam that comes with WM_NOTIFY
  4051. Return: Please see the return types for the notification messages
  4052. Handler for PSN_* messages return -1 if the message should not be accepted
  4053. and 0 if the message has been handled properly
  4054. For other notification messages we return TRUE if we processed the message,
  4055. FALSE otherwise
  4056. --*/
  4057. {
  4058. NMHDR* pHdr = (NMHDR*)lParam;
  4059. INT_PTR ipReturn = FALSE;
  4060. switch (pHdr->code) {
  4061. case PSN_WIZFINISH:
  4062. case PSN_WIZNEXT:
  4063. ipReturn = SelectShimsDlgOnNotifyFinish_Next(hDlg);
  4064. g_bLayersChanged = FALSE;
  4065. break;
  4066. case PSN_SETACTIVE:
  4067. ipReturn = SelectShimsDlgOnNotifyOnSetActive(hDlg);
  4068. break;
  4069. case NM_CLICK:
  4070. ipReturn = SelectShimsDlgOnNotifyOnClick(hDlg);
  4071. break;
  4072. case LVN_KEYDOWN:
  4073. {
  4074. LPNMLVKEYDOWN plvkd = (LPNMLVKEYDOWN)lParam ;
  4075. if (plvkd->wVKey == VK_SPACE) {
  4076. SetTimer(hDlg, 0, 100, NULL);
  4077. }
  4078. ipReturn = TRUE;
  4079. break;
  4080. }
  4081. case LVN_ITEMCHANGED:
  4082. ipReturn = SelectShimsDlgOnNotifyOnLVItemChanged(hDlg, lParam);
  4083. break;
  4084. case LVN_GETINFOTIP:
  4085. ipReturn = SelectShimsDlgOnNotifyOnLV_Tip(hDlg, lParam);
  4086. break;
  4087. default:
  4088. ipReturn = FALSE;
  4089. }
  4090. return ipReturn;
  4091. }
  4092. INT_PTR
  4093. SelectFilesDlgOnInitDialog(
  4094. IN HWND hDlg
  4095. )
  4096. /*++
  4097. SelectFilesDlgOnInitDialog
  4098. Desc: The handler of WM_INITDIALOG for the matching files wizard page.
  4099. This page is shared both by the fix wizard and the app help wizard
  4100. Also initializes s_hwndTree to the handle of the matching files tree
  4101. Params:
  4102. IN HWND hDlg: The matching files wizard page
  4103. Return:
  4104. TRUE
  4105. --*/
  4106. {
  4107. s_hwndTree = GetDlgItem(hDlg, IDC_FILELIST);
  4108. s_hMatchingFileImageList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 7, 1);
  4109. ImageList_AddIcon(s_hMatchingFileImageList,
  4110. LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_FILE)));
  4111. ImageList_AddIcon(s_hMatchingFileImageList,
  4112. LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ATTRIBUTE)));
  4113. TreeView_SetImageList(s_hwndTree, s_hMatchingFileImageList, TVSIL_NORMAL);
  4114. HIMAGELIST hImage = ImageList_LoadImage(g_hInstance,
  4115. MAKEINTRESOURCE(IDB_CHECK),
  4116. 16,
  4117. 0,
  4118. CLR_DEFAULT,
  4119. IMAGE_BITMAP,
  4120. LR_LOADTRANSPARENT);
  4121. if (hImage != NULL) {
  4122. TreeView_SetImageList(s_hwndTree,
  4123. hImage,
  4124. TVSIL_STATE);
  4125. }
  4126. PostMessage(hDlg, WM_USER_MATCHINGTREE_REFRESH, 0, 0);
  4127. //
  4128. // The "Show all attributes" button should be visible only if we are
  4129. // in editing mode
  4130. //
  4131. ShowWindow(GetDlgItem(hDlg, IDC_SHOWALLATTR),
  4132. (g_pCurrentWizard->m_bEditing) ? SW_SHOW : SW_HIDE);
  4133. return TRUE;
  4134. }
  4135. INT_PTR
  4136. CheckLUADlgOnNotifyOnFinish(
  4137. IN HWND hDlg
  4138. )
  4139. /*++
  4140. CheckLUADlgOnNotifyOnFinish
  4141. Desc: Handles the pressing of the finish button in the fifth page of the wizard
  4142. Params:
  4143. IN HWND hDlg: The fifth page of the wizard
  4144. Return:
  4145. -1: Do not allow to comlete finish or navigate away from this page
  4146. 0: Otherwise
  4147. --*/
  4148. {
  4149. INT_PTR ipReturn = 0;
  4150. if (IsDlgButtonChecked(hDlg, IDC_FIXWIZ_CHECKLUA_YES) == BST_CHECKED) {
  4151. g_bShouldStartLUAWizard = TRUE;
  4152. }
  4153. return ipReturn;
  4154. }
  4155. INT_PTR
  4156. CheckLUADlgOnNotify(
  4157. IN HWND hDlg,
  4158. IN LPARAM lParam
  4159. )
  4160. /*++
  4161. CheckLUADlgOnNotify
  4162. Desc: The handler of WM_NOTIFY for the fifth wizard page
  4163. Params:
  4164. IN HWND hDlg: The fifth wizard page
  4165. IN LPARAM lParam: The lParam that comes with WM_NOTIFY
  4166. Return: Please see the return types for the notification messages
  4167. Handler for PSN_* messages return -1 if the message should not be accepted
  4168. and 0 if the message has been handled properly
  4169. For other notification messages we return TRUE if we processed the message, FALSE otherwise
  4170. --*/
  4171. {
  4172. NMHDR* pHdr = (NMHDR*)lParam;
  4173. INT_PTR ipReturn = FALSE;
  4174. if (pHdr == NULL) {
  4175. return FALSE;
  4176. }
  4177. switch (pHdr->code) {
  4178. case PSN_SETACTIVE:
  4179. {
  4180. LPARAM buttons = PSWIZB_BACK | PSWIZB_FINISH;
  4181. SendMessage(GetParent(hDlg), PSM_SETWIZBUTTONS, 0, buttons);
  4182. //
  4183. // We processed the message and everything is OK. The value should be FALSE
  4184. //
  4185. ipReturn = 0;
  4186. }
  4187. break;
  4188. case PSN_WIZFINISH:
  4189. ipReturn = CheckLUADlgOnNotifyOnFinish(hDlg);
  4190. break;
  4191. default: ipReturn = 0;
  4192. }
  4193. return ipReturn;
  4194. }
  4195. INT_PTR
  4196. CALLBACK
  4197. CheckLUA(
  4198. IN HWND hDlg,
  4199. IN UINT uMsg,
  4200. IN WPARAM wParam,
  4201. IN LPARAM lParam
  4202. )
  4203. /*++
  4204. CheckLUA
  4205. Desc: Dialog proc for the last page of the wizard.
  4206. Params: Standard dialog handler parameters
  4207. IN HWND hDlg
  4208. IN UINT uMsg
  4209. IN WPARAM wParam
  4210. IN LPARAM lParam
  4211. Return: Standard dialog handler return
  4212. --*/
  4213. {
  4214. INT_PTR ipReturn = 0;
  4215. switch (uMsg) {
  4216. case WM_INITDIALOG:
  4217. //
  4218. // We want to set the default to Yes because we want the user to customize LUA now.
  4219. //
  4220. CheckDlgButton(hDlg, IDC_FIXWIZ_CHECKLUA_YES, BST_CHECKED);
  4221. return TRUE;
  4222. case WM_NOTIFY:
  4223. CheckLUADlgOnNotify(hDlg, lParam);
  4224. break;
  4225. default: ipReturn = 0;
  4226. }
  4227. return ipReturn;
  4228. }
  4229. BOOL
  4230. AddCheckLUAPage(
  4231. HWND hwndWizard
  4232. )
  4233. {
  4234. PROPSHEETPAGE PageCheckLUA;
  4235. ZeroMemory(&PageCheckLUA, sizeof(PROPSHEETPAGE));
  4236. PageCheckLUA.dwSize = sizeof(PROPSHEETPAGE);
  4237. PageCheckLUA.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
  4238. PageCheckLUA.hInstance = g_hInstance;
  4239. PageCheckLUA.pszTemplate = MAKEINTRESOURCE(IDD_FIXWIZ_CHECKLUA);
  4240. PageCheckLUA.pfnDlgProc = CheckLUA;
  4241. PageCheckLUA.pszHeaderTitle = MAKEINTRESOURCE(IDS_CHECKLUA);
  4242. PageCheckLUA.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_CHECKLUASUBHEADING);
  4243. HPROPSHEETPAGE hPage = CreatePropertySheetPage(&PageCheckLUA);
  4244. if (hPage == NULL) {
  4245. return FALSE;
  4246. } else {
  4247. return PropSheet_AddPage(hwndWizard, hPage);
  4248. }
  4249. }
  4250. INT_PTR
  4251. SelectFilesDlgOnNotify(
  4252. IN HWND hDlg,
  4253. IN LPARAM lParam
  4254. )
  4255. /*++
  4256. SelectFilesDlgOnNotify
  4257. Desc: The handler of WM_NOTIFY for the matching files wizard page
  4258. Params:
  4259. IN HWND hDlg: The matching files wizard page
  4260. IN LPARAM lParam: The lParam that comes with WM_NOTIFY
  4261. Return: Please see the return types for the notification messages
  4262. Handler for PSN_* messages return -1 if the message should not be accepted
  4263. and 0 if the message has been handled properly
  4264. For other notification messages we return TRUE if we processed the message,
  4265. FALSE otherwise
  4266. --*/
  4267. {
  4268. NMHDR* pHdr = (NMHDR*)lParam;
  4269. INT_PTR ipReturn = FALSE;
  4270. static BOOL s_bIsLUARedirectFSPresent;
  4271. if (pHdr->idFrom == IDC_FILELIST) {
  4272. //
  4273. // Messages for the matching files tree
  4274. //
  4275. return HandleAttributeTreeNotification(hDlg, lParam);
  4276. }
  4277. switch (pHdr->code) {
  4278. case PSN_SETACTIVE:
  4279. {
  4280. SendMessage(hDlg, WM_USER_MATCHINGTREE_REFRESH, 0, 0);
  4281. LPARAM buttons = PSWIZB_BACK;
  4282. s_bIsLUARedirectFSPresent = FALSE;
  4283. if (TYPE_APPHELPWIZARD == g_pCurrentWizard->m_uType) {
  4284. buttons |= PSWIZB_NEXT;
  4285. } else {
  4286. //
  4287. // Check if the user has selected either the LUA layer or the LUARedirectFS
  4288. // shim; if so we need to ask if he wants to customize LUA settings now.
  4289. //
  4290. if (IsLUARedirectFSPresent(&g_pCurrentWizard->m_Entry)) {
  4291. buttons |= PSWIZB_NEXT;
  4292. s_bIsLUARedirectFSPresent = TRUE;
  4293. } else {
  4294. buttons |= PSWIZB_FINISH;
  4295. }
  4296. }
  4297. SendMessage(GetParent(hDlg), PSM_SETWIZBUTTONS, 0, buttons);
  4298. //
  4299. // We processed the message and everything is OK. The value should be FALSE
  4300. //
  4301. ipReturn = FALSE;
  4302. }
  4303. break;
  4304. case PSN_WIZBACK:
  4305. {
  4306. CSTRING szFile = g_pCurrentWizard->m_Entry.strFullpath;
  4307. szFile.ShortFilename();
  4308. SetMask(s_hwndTree);
  4309. //
  4310. // Remove the matching info for the current file if it exists. Otherwise,
  4311. // it's possible that if the file is changed, we'll have bogus information
  4312. // about it.
  4313. //
  4314. PMATCHINGFILE pWalk = g_pCurrentWizard->m_Entry.pFirstMatchingFile;
  4315. PMATCHINGFILE pPrev = NULL;
  4316. while (NULL != pWalk && !g_pCurrentWizard->m_bEditing) { // Only if not in editing mode
  4317. if (pWalk->strMatchName == szFile || pWalk->strMatchName == TEXT("*")) {
  4318. //
  4319. // Remove this entry.
  4320. //
  4321. if (pWalk == g_pCurrentWizard->m_Entry.pFirstMatchingFile) {
  4322. g_pCurrentWizard->m_Entry.pFirstMatchingFile = g_pCurrentWizard->m_Entry.pFirstMatchingFile->pNext;
  4323. } else {
  4324. assert(pPrev);
  4325. pPrev->pNext = pWalk->pNext;
  4326. }
  4327. g_pCurrentWizard->dwMaskOfMainEntry = pWalk->dwMask;
  4328. delete (pWalk);
  4329. break;
  4330. }
  4331. pPrev = pWalk;
  4332. pWalk = pWalk->pNext;
  4333. }
  4334. ipReturn = FALSE;
  4335. }
  4336. break;
  4337. case PSN_WIZFINISH:
  4338. case PSN_WIZNEXT:
  4339. {
  4340. PMATCHINGFILE pMatch = NULL;
  4341. ipReturn = FALSE;
  4342. //
  4343. // Set the mask for all the matching files.
  4344. //
  4345. SetMask(s_hwndTree);
  4346. if (TYPE_APPHELPWIZARD == g_pCurrentWizard->m_uType) {
  4347. ipReturn = TRUE;
  4348. break;
  4349. }
  4350. if (s_bIsLUARedirectFSPresent) {
  4351. ipReturn = !AddCheckLUAPage(pHdr->hwndFrom);
  4352. }
  4353. break;
  4354. }
  4355. }
  4356. return ipReturn;
  4357. }
  4358. INT_PTR
  4359. SelectFilesDlgOnCommand(
  4360. IN HWND hDlg,
  4361. IN WPARAM wParam
  4362. )
  4363. /*++
  4364. SelectFilesDlgOnCommand
  4365. Desc: The handler of WM_COMMAND for the matching files wizard page
  4366. Params:
  4367. IN HWND hDlg: The matching files wizard page
  4368. IN WPARAM wParam: The wParam that comes with WM_COMMAND
  4369. Return:
  4370. TRUE: We processed the message
  4371. FALSE: Otherwise
  4372. --*/
  4373. {
  4374. INT_PTR ipReturn = TRUE;
  4375. switch (LOWORD(wParam)) {
  4376. case IDC_GENERATE:
  4377. {
  4378. HCURSOR hRestore;
  4379. hRestore = SetCursor(LoadCursor(NULL, IDC_WAIT));
  4380. //
  4381. // Do the actual task of generating the matching files
  4382. //
  4383. g_pCurrentWizard->GrabMatchingInfo(hDlg);
  4384. SetCursor(hRestore);
  4385. break;
  4386. }
  4387. case IDC_ADDFILES:
  4388. {
  4389. CSTRING szFilename;
  4390. HWND hwndFocus = GetFocus();
  4391. TCHAR szBuffer[512] = TEXT("");
  4392. GetString(IDS_EXEALLFILTER, szBuffer, ARRAYSIZE(szBuffer));
  4393. if (g_pCurrentWizard->CheckAndSetLongFilename(hDlg, IDS_GETPATH_ADD) == FALSE) {
  4394. break;
  4395. }
  4396. if (GetFileName(hDlg,
  4397. CSTRING(IDS_FINDMATCHINGFILE),
  4398. szBuffer,
  4399. TEXT(""),
  4400. GetString(IDS_EXE_EXT),
  4401. OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST,
  4402. TRUE,
  4403. szFilename)) {
  4404. szFilename.ConvertToLongFileName();
  4405. CSTRING szCheck = szFilename;
  4406. //
  4407. // Is this on the same drive as the original file
  4408. //
  4409. if (szCheck.RelativeFile(g_pCurrentWizard->m_Entry.strFullpath) == FALSE) {
  4410. //
  4411. // The matching file is not on the same drive as the program
  4412. // file being fixed
  4413. //
  4414. MessageBox(hDlg,
  4415. GetString(IDS_NOTSAMEDRIVE),
  4416. g_szAppName,
  4417. MB_ICONWARNING);
  4418. break;
  4419. }
  4420. HandleAddMatchingFile(hDlg, szFilename, szCheck);
  4421. }
  4422. SetFocus(hwndFocus);
  4423. }
  4424. break;
  4425. case IDC_REMOVEALL:
  4426. {
  4427. PMATCHINGFILE pMatch = NULL;
  4428. TVITEM Item;
  4429. HTREEITEM hItem;
  4430. HTREEITEM hItemNext;
  4431. g_pCurrentWizard->m_Entry.pFirstMatchingFile;
  4432. SendMessage(s_hwndTree, WM_SETREDRAW, FALSE, 0);
  4433. hItem = TreeView_GetChild(s_hwndTree, TVI_ROOT), hItemNext;
  4434. while (hItem) {
  4435. hItemNext = TreeView_GetNextSibling(s_hwndTree, hItem);
  4436. Item.mask = TVIF_PARAM;
  4437. Item.hItem = hItem;
  4438. if (!TreeView_GetItem(s_hwndTree, &Item)) {
  4439. assert(FALSE);
  4440. goto Next;
  4441. }
  4442. pMatch = (PMATCHINGFILE)Item.lParam;
  4443. if (pMatch == NULL) {
  4444. assert(FALSE);
  4445. Dbg(dlError, "SelectFilesDlgOnCommand", "pMatch == NULL");
  4446. break;
  4447. }
  4448. if (pMatch->strMatchName != TEXT("*")) {
  4449. //
  4450. // Must not delete the entry for the exe being fixed
  4451. //
  4452. TreeView_SelectItem(s_hwndTree, hItem);
  4453. SendMessage(hDlg, WM_COMMAND, IDC_REMOVEFILES, 0);
  4454. }
  4455. Next:
  4456. hItem = hItemNext;
  4457. }
  4458. SendMessage(s_hwndTree, WM_SETREDRAW, TRUE, 0);
  4459. }
  4460. break;
  4461. case IDC_REMOVEFILES:
  4462. {
  4463. PMATCHINGFILE pWalk;
  4464. PMATCHINGFILE pHold;
  4465. PMATCHINGFILE pMatch;
  4466. HTREEITEM hItem = TreeView_GetSelection(GetDlgItem(hDlg, IDC_FILELIST));
  4467. TVITEM Item;
  4468. //
  4469. // To be a matching file an item should be a root element,
  4470. // otherwise it is an attribute
  4471. //
  4472. if (NULL != hItem && TreeView_GetParent(s_hwndTree, hItem) == NULL) {
  4473. Item.mask = TVIF_PARAM;
  4474. Item.hItem = hItem;
  4475. if (!TreeView_GetItem(GetDlgItem(hDlg, IDC_FILELIST), &Item)) {
  4476. break;
  4477. }
  4478. pMatch = (PMATCHINGFILE)Item.lParam;
  4479. assert(pMatch);
  4480. if (pMatch->strMatchName == TEXT("*")) {
  4481. //
  4482. // This is the program file being fixed. This cannot be removed
  4483. //
  4484. MessageBox(hDlg,
  4485. CSTRING(IDS_REQUIREDFORMATCHING),
  4486. g_szAppName,
  4487. MB_ICONINFORMATION);
  4488. break;
  4489. }
  4490. pWalk = g_pCurrentWizard->m_Entry.pFirstMatchingFile;
  4491. //
  4492. // NOTE: The lparam for the items in the tree should be to the corresponding PMATCHINGFILE
  4493. //
  4494. while (NULL != pWalk) {
  4495. if (pWalk == (PMATCHINGFILE)Item.lParam) {
  4496. break;
  4497. }
  4498. pHold = pWalk;
  4499. pWalk = pWalk->pNext;
  4500. }
  4501. if (pWalk == g_pCurrentWizard->m_Entry.pFirstMatchingFile) {
  4502. //
  4503. // Delete first matching file
  4504. //
  4505. g_pCurrentWizard->m_Entry.pFirstMatchingFile = pWalk->pNext;
  4506. } else {
  4507. pHold->pNext = pWalk->pNext;
  4508. }
  4509. delete pWalk;
  4510. TreeView_DeleteItem(s_hwndTree, hItem);
  4511. } else {
  4512. //
  4513. // No matching file has been selected, need to select one for deletion
  4514. //
  4515. MessageBox(hDlg,
  4516. CSTRING(IDS_SELECTMATCHFIRST),
  4517. g_szAppName,
  4518. MB_ICONWARNING);
  4519. }
  4520. }
  4521. break;
  4522. case IDC_SELECTALL:
  4523. case IDC_UNSELECTALL:
  4524. {
  4525. BOOL bSelect = (LOWORD(wParam) == IDC_SELECTALL);
  4526. HTREEITEM hItem = TreeView_GetSelection(s_hwndTree);
  4527. HTREEITEM hItemParent;
  4528. if (hItem == NULL) {
  4529. //
  4530. // No matching file has been selected
  4531. //
  4532. MessageBox(hDlg,
  4533. CSTRING(IDS_SELECTMATCHFIRST),
  4534. g_szAppName,
  4535. MB_ICONWARNING);
  4536. break;
  4537. }
  4538. hItemParent = TreeView_GetParent(s_hwndTree, hItem);
  4539. if (hItemParent != NULL) {
  4540. hItem = hItemParent;
  4541. }
  4542. hItemParent = hItem; // So that we can expand this one.
  4543. //
  4544. // Now for all the attributes of this matching file
  4545. //
  4546. hItem = TreeView_GetChild(s_hwndTree, hItem);
  4547. while (hItem) {
  4548. TreeView_SetCheckState(s_hwndTree, hItem, bSelect);
  4549. hItem = TreeView_GetNextSibling(s_hwndTree, hItem);
  4550. }
  4551. TreeView_Expand(s_hwndTree, hItemParent, TVM_EXPAND);
  4552. }
  4553. break;
  4554. case IDC_SHOWALLATTR:
  4555. if (!g_pCurrentWizard->m_bEditing) {
  4556. break;
  4557. }
  4558. //
  4559. // Show all the attributes of all the files
  4560. //
  4561. HandleShowAllAtrr(hDlg);
  4562. break;
  4563. default:
  4564. ipReturn = FALSE;
  4565. }
  4566. return ipReturn;
  4567. }
  4568. INT_PTR
  4569. SelectFilesDlgOnMatchingTreeRefresh(
  4570. IN HWND hDlg
  4571. )
  4572. /*++
  4573. SelectFilesDlgOnMatchingTreeRefresh
  4574. Desc: Refreshes the matching tree
  4575. Params:
  4576. IN HWND hDlg: The matching files wizard page
  4577. Return:
  4578. TRUE
  4579. --*/
  4580. {
  4581. PMATCHINGFILE pMatch = g_pCurrentWizard->m_Entry.pFirstMatchingFile;
  4582. BOOL bMainFound = FALSE;
  4583. SendMessage(s_hwndTree, WM_SETREDRAW, FALSE, 0);
  4584. TreeView_DeleteAllItems(s_hwndTree);
  4585. while (NULL != pMatch) {
  4586. if (pMatch->strMatchName == TEXT("*")) {
  4587. bMainFound = TRUE;
  4588. }
  4589. AddMatchingFileToTree(s_hwndTree, pMatch, FALSE);
  4590. pMatch = pMatch->pNext;
  4591. }
  4592. if (bMainFound == FALSE) {
  4593. //
  4594. // The matching file for program being fixed is not there, let us add it
  4595. //
  4596. HandleAddMatchingFile(hDlg,
  4597. g_pCurrentWizard->m_Entry.strFullpath,
  4598. g_pCurrentWizard->m_Entry.strExeName,
  4599. g_pCurrentWizard->dwMaskOfMainEntry);
  4600. }
  4601. SendMessage(s_hwndTree, WM_SETREDRAW, TRUE, 0);
  4602. return TRUE;
  4603. }