Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1872 lines
59 KiB

  1. #include "compatadmin.h"
  2. #ifndef __WIZARD_H
  3. #include "wizard.h"
  4. #endif
  5. #include "xmldialog.h"
  6. CShimWizard * g_pCurrentWizard = NULL;
  7. #define MAX_DESC_LENGTH 40
  8. #define PAGE_INTRO 0
  9. #define PAGE_APPNAME 1
  10. #define PAGE_LAYERNAME 2
  11. #define PAGE_SELFILES1 3
  12. #define PAGE_DONE 3
  13. #define PAGE_SHIMS 4
  14. #define PAGE_SHIMNAME 5
  15. #define PAGE_SELECTFILES 6
  16. BOOL CShimWizard::BeginWizard(HWND hParent)
  17. {
  18. PROPSHEETPAGE Pages[11];
  19. ZeroMemory(&m_Record,sizeof(m_Record));
  20. CoCreateGuid(&m_Record.guidID);
  21. // Setup wizard variables
  22. g_pCurrentWizard = this;
  23. // Set default application settings
  24. m_uType = TYPE_LAYER;
  25. // begin the wizard
  26. PROPSHEETHEADER Header;
  27. Header.dwSize = sizeof(PROPSHEETHEADER);
  28. Header.dwFlags = PSH_WIZARD97 | PSH_PROPSHEETPAGE | PSH_HEADER;
  29. Header.hwndParent = hParent;
  30. Header.hInstance = g_hInstance;
  31. Header.pszCaption = /*"Create an application fix";//*/MAKEINTRESOURCE(IDS_WIZARD);
  32. Header.nStartPage = 0;
  33. Header.ppsp = Pages;
  34. Header.nPages = 7;
  35. Header.pszbmHeader = MAKEINTRESOURCE(IDB_WIZBMP);
  36. Pages[PAGE_INTRO].dwSize = sizeof(PROPSHEETPAGE);
  37. Pages[PAGE_INTRO].dwFlags = PSP_USEHEADERSUBTITLE;
  38. Pages[PAGE_INTRO].hInstance = g_hInstance;
  39. Pages[PAGE_INTRO].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD);
  40. Pages[PAGE_INTRO].pfnDlgProc = (DLGPROC)EntryPoint;
  41. Pages[PAGE_INTRO].pszHeaderSubTitle = TEXT("Select method");
  42. Pages[PAGE_APPNAME].dwSize = sizeof(PROPSHEETPAGE);
  43. Pages[PAGE_APPNAME].dwFlags = PSP_USEHEADERSUBTITLE;
  44. Pages[PAGE_APPNAME].hInstance = g_hInstance;
  45. Pages[PAGE_APPNAME].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD3);
  46. Pages[PAGE_APPNAME].pfnDlgProc = (DLGPROC)GetAppName;
  47. Pages[PAGE_APPNAME].pszHeaderSubTitle = TEXT("Enter an application name");
  48. Pages[PAGE_LAYERNAME].dwSize = sizeof(PROPSHEETPAGE);
  49. Pages[PAGE_LAYERNAME].dwFlags = PSP_USEHEADERSUBTITLE;
  50. Pages[PAGE_LAYERNAME].hInstance = g_hInstance;
  51. Pages[PAGE_LAYERNAME].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD2);
  52. Pages[PAGE_LAYERNAME].pfnDlgProc = (DLGPROC)SelectLayer;
  53. Pages[PAGE_LAYERNAME].pszHeaderSubTitle = TEXT("Select the files and compatibility mode");
  54. /*
  55. Pages[PAGE_SELFILES1].dwSize = sizeof(PROPSHEETPAGE);
  56. Pages[PAGE_SELFILES1].dwFlags = PSP_USEHEADERSUBTITLE;
  57. Pages[PAGE_SELFILES1].hInstance = g_hInstance;
  58. Pages[PAGE_SELFILES1].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD4);
  59. Pages[PAGE_SELFILES1].pfnDlgProc = SelectMatching;
  60. Pages[PAGE_SELFILES1].pszHeaderSubTitle = "How would you like to identify the application?";
  61. */
  62. Pages[PAGE_DONE].dwSize = sizeof(PROPSHEETPAGE);
  63. Pages[PAGE_DONE].dwFlags = PSP_USEHEADERSUBTITLE;
  64. Pages[PAGE_DONE].hInstance = g_hInstance;
  65. Pages[PAGE_DONE].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARDDONE);
  66. Pages[PAGE_DONE].pfnDlgProc = (DLGPROC)WizardDone;
  67. Pages[PAGE_DONE].pszHeaderSubTitle = TEXT("You have successfully created an application fix");
  68. Pages[PAGE_SHIMS].dwSize = sizeof(PROPSHEETPAGE);
  69. Pages[PAGE_SHIMS].dwFlags = PSP_USEHEADERSUBTITLE;
  70. Pages[PAGE_SHIMS].hInstance = g_hInstance;
  71. Pages[PAGE_SHIMS].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD5);
  72. Pages[PAGE_SHIMS].pfnDlgProc = (DLGPROC)SelectShims;
  73. Pages[PAGE_SHIMS].pszHeaderSubTitle = TEXT("Select the fixes to apply to the application");
  74. Pages[PAGE_SHIMNAME].dwSize = sizeof(PROPSHEETPAGE);
  75. Pages[PAGE_SHIMNAME].dwFlags = PSP_USEHEADERSUBTITLE;
  76. Pages[PAGE_SHIMNAME].hInstance = g_hInstance;
  77. Pages[PAGE_SHIMNAME].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD6);
  78. Pages[PAGE_SHIMNAME].pfnDlgProc = (DLGPROC)SelectLayer;
  79. Pages[PAGE_SHIMNAME].pszHeaderSubTitle = TEXT("Select the file to create the fix for");
  80. Pages[PAGE_SELECTFILES].dwSize = sizeof(PROPSHEETPAGE);
  81. Pages[PAGE_SELECTFILES].dwFlags = PSP_USEHEADERSUBTITLE;
  82. Pages[PAGE_SELECTFILES].hInstance = g_hInstance;
  83. Pages[PAGE_SELECTFILES].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD7);
  84. Pages[PAGE_SELECTFILES].pfnDlgProc = (DLGPROC)SelectFiles;
  85. Pages[PAGE_SELECTFILES].pszHeaderSubTitle = TEXT("Select files used for application identification");
  86. if ( 0 < PropertySheet(&Header) ) {
  87. PDBRECORD pRecord = new DBRECORD;
  88. if ( NULL != pRecord ) {
  89. ZeroMemory(pRecord,sizeof(DBRECORD));
  90. pRecord->szEXEName = m_Record.szEXEName;
  91. pRecord->szAppName = m_Record.szAppName;
  92. pRecord->szLayerName = m_Record.szLayerName;
  93. pRecord->guidID = m_Record.guidID;
  94. pRecord->pEntries = m_Record.pEntries;
  95. g_theApp.GetDBLocal().InsertRecord(pRecord);
  96. return TRUE;
  97. }
  98. }
  99. return FALSE;
  100. }
  101. BOOL CALLBACK EntryPoint(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  102. {
  103. switch ( uMsg ) {
  104. case WM_INITDIALOG:
  105. {
  106. HWND hParent = GetParent(hDlg);
  107. SetWindowText(hParent,TEXT("Create an application fix"));
  108. if ( TYPE_LAYER == g_pCurrentWizard->m_uType )
  109. SendDlgItemMessage(hDlg,IDC_LAYERS,BM_SETCHECK,BST_CHECKED,0);
  110. if ( TYPE_SHIM == g_pCurrentWizard->m_uType )
  111. SendDlgItemMessage(hDlg,IDC_SHIM,BM_SETCHECK,BST_CHECKED,0);
  112. if ( TYPE_APPHELP == g_pCurrentWizard->m_uType )
  113. SendDlgItemMessage(hDlg,IDC_APPHELP,BM_SETCHECK,BST_CHECKED,0);
  114. }
  115. break;
  116. case WM_NOTIFY:
  117. {
  118. NMHDR * pHdr = (NMHDR *) lParam;
  119. switch ( pHdr->code ) {
  120. case PSN_SETACTIVE:
  121. SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT);
  122. break;
  123. case PSN_WIZNEXT:
  124. {
  125. if ( BST_CHECKED == SendDlgItemMessage(hDlg,IDC_LAYERS,BM_GETCHECK,0,0) ) {
  126. if ( g_pCurrentWizard->m_uType != TYPE_LAYER )
  127. g_pCurrentWizard->WipeRecord(TRUE,TRUE,TRUE);
  128. g_pCurrentWizard->m_uType = TYPE_LAYER;
  129. }
  130. if ( BST_CHECKED == SendDlgItemMessage(hDlg,IDC_SHIM,BM_GETCHECK,0,0) ) {
  131. if ( g_pCurrentWizard->m_uType != TYPE_SHIM )
  132. g_pCurrentWizard->WipeRecord(TRUE,TRUE,TRUE);
  133. g_pCurrentWizard->m_uType = TYPE_SHIM;
  134. }
  135. }
  136. break;
  137. }
  138. }
  139. break;
  140. }
  141. return FALSE;
  142. }
  143. #define FRIENDLY_NAME TEXT("My Application Fix")
  144. BOOL CALLBACK GetAppName(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  145. {
  146. switch ( uMsg ) {
  147. case WM_INITDIALOG:
  148. {
  149. SendMessage(
  150. GetDlgItem(hDlg,IDC_NAME), // handle to destination window
  151. EM_LIMITTEXT, // message to send
  152. (WPARAM) LIMIT_APP_NAME, // text length
  153. (LPARAM) 0
  154. );
  155. SHAutoComplete(GetDlgItem(hDlg,IDC_NAME), AUTOCOMPLETE);
  156. if ( 0 == g_pCurrentWizard->m_Record.szAppName.Length() )
  157. g_pCurrentWizard->m_Record.szAppName = FRIENDLY_NAME;
  158. SetDlgItemText(hDlg,IDC_NAME, g_pCurrentWizard->m_Record.szAppName);
  159. if ( g_pCurrentWizard->m_Record.szAppName == FRIENDLY_NAME )
  160. SendMessage(GetDlgItem(hDlg,IDC_NAME),EM_SETSEL,0,-1);
  161. // Force proper Next button state.
  162. SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_NAME,EN_CHANGE),0);
  163. }
  164. break;
  165. case WM_NOTIFY:
  166. {
  167. NMHDR * pHdr = (NMHDR *) lParam;
  168. switch ( pHdr->code ) {
  169. case PSN_SETACTIVE:
  170. {
  171. SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_NAME,EN_CHANGE),0);
  172. if ( TYPE_LAYER == g_pCurrentWizard->m_uType )
  173. SetWindowText(GetDlgItem(hDlg,IDC_TITLE),TEXT("Enter the name of the application to create a compatibility layer for"));
  174. else
  175. SetWindowText(GetDlgItem(hDlg,IDC_TITLE),TEXT("Enter the name of the application to create a fix for"));
  176. }
  177. break;
  178. case PSN_WIZNEXT:
  179. {
  180. TCHAR szTemp[MAX_STRING_SIZE];
  181. GetDlgItemText(hDlg,IDC_NAME,szTemp,MAX_STRING_SIZE);
  182. CSTRING::Trim(szTemp);
  183. g_pCurrentWizard->m_Record.szAppName = szTemp;
  184. if ( TYPE_SHIM == g_pCurrentWizard->m_uType ) {
  185. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD6);
  186. return IDD_ADDWIZARD6;
  187. }
  188. }
  189. break;
  190. }
  191. }
  192. break;
  193. case WM_COMMAND:
  194. switch ( LOWORD(wParam) ) {
  195. case IDC_NAME:
  196. if ( EN_CHANGE == HIWORD(wParam) ) {
  197. TCHAR szText[MAX_PATH_BUFFSIZE];
  198. GetWindowText(GetDlgItem(hDlg,IDC_NAME),szText,MAX_PATH);
  199. BOOL bEnable = ( CSTRING::Trim(szText) > 0) ? TRUE:FALSE;
  200. DWORD dwFlags = PSWIZB_BACK;
  201. if ( bEnable )
  202. dwFlags |= PSWIZB_NEXT;
  203. SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS,0, dwFlags);
  204. }
  205. break;
  206. }
  207. }
  208. return FALSE;
  209. }
  210. BOOL CALLBACK SelectLayer(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  211. {
  212. switch ( uMsg ) {
  213. case WM_INITDIALOG:
  214. {
  215. SendMessage(
  216. GetDlgItem(hDlg,IDC_NAME), // handle to destination window
  217. EM_LIMITTEXT, // message to send
  218. (WPARAM) MAX_PATH, // text length
  219. (LPARAM) 0
  220. );
  221. SetDlgItemText(hDlg,IDC_NAME,g_pCurrentWizard->m_szLongName);
  222. SHAutoComplete(GetDlgItem(hDlg,IDC_NAME), AUTOCOMPLETE);
  223. // Force proper Next button state.
  224. SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_NAME,EN_CHANGE),0);
  225. }
  226. break;
  227. case WM_NOTIFY:
  228. {
  229. NMHDR * pHdr = (NMHDR *) lParam;
  230. switch ( pHdr->code ) {
  231. case PSN_SETACTIVE:
  232. {
  233. if ( TYPE_LAYER == g_pCurrentWizard->m_uType ) {
  234. int nSelIndex = -1;
  235. // Remove all strings.
  236. //g_pCurrentWizard->WipeRecord(TRUE,TRUE,FALSE);
  237. while ( CB_ERR != SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_DELETESTRING,0,0) );
  238. // Re-add the strings.
  239. PDBLAYER pWalk = g_theApp.GetDBGlobal().m_pLayerList;
  240. for ( int iLoop = 0 ; iLoop <= 1 ; ++ iLoop ){
  241. //
  242. // Do both for the local and the global Databases
  243. //
  244. while ( NULL != pWalk ) {
  245. if ( CB_ERR == SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_FINDSTRINGEXACT,0,(LPARAM)(LPCTSTR)pWalk->szLayerName) ) {
  246. int nIndex;
  247. nIndex = SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_ADDSTRING,0,(LPARAM)(LPTSTR)pWalk->szLayerName);
  248. if ( CB_ERR != nIndex ) {
  249. SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_SETITEMDATA,nIndex,(LPARAM)pWalk);
  250. // Select this index if it's the current layer name.
  251. /*
  252. if (0 == lstrcmp(g_pCurrentWizard->m_Record.szLayerName,(LPSTR)pWalk->szLayerName))
  253. nSelIndex = nIndex;
  254. */
  255. }
  256. }
  257. pWalk = pWalk->pNext;
  258. }
  259. pWalk = g_theApp.GetDBLocal().m_pLayerList;
  260. } //for
  261. nSelIndex = SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_FINDSTRINGEXACT,0,(LPARAM)(LPCTSTR)g_pCurrentWizard->m_Record.szLayerName);
  262. if ( -1 != nSelIndex )
  263. SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_SETCURSEL,nSelIndex,0);
  264. }
  265. SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_NAME,EN_CHANGE),0);
  266. }
  267. break;
  268. case PSN_WIZNEXT:
  269. {
  270. TCHAR szTemp[MAX_STRING_SIZE];
  271. GetDlgItemText(hDlg,IDC_NAME,szTemp,MAX_PATH);
  272. CSTRING::Trim(szTemp);
  273. HANDLE hFile = CreateFile (szTemp,0,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  274. if ( INVALID_HANDLE_VALUE == hFile ) {
  275. MessageBox(hDlg,TEXT("Unable to locate specified file"),TEXT("Invalid file name"),MB_OK);
  276. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,-1);
  277. return -1;
  278. }
  279. CloseHandle(hFile);
  280. DWORD dwExeType;
  281. GetBinaryType(szTemp, &dwExeType);
  282. BOOL bExe = FALSE;// Is this an .exe file
  283. CSTRING strTemp = szTemp;
  284. if ( strTemp.EndsWith(TEXT(".exe")) ) bExe = TRUE;
  285. //
  286. // Check if this is "shimmable"
  287. //
  288. CSTRING msg;
  289. if ( (dwExeType & SCS_DOS_BINARY) && bExe )
  290. msg = TEXT("This is a DOS Application\n");
  291. else if ( (dwExeType & SCS_WOW_BINARY) && bExe)
  292. msg = TEXT("This is a 16 bit Windows Application\n");
  293. else if ((dwExeType & SCS_PIF_BINARY) && bExe )
  294. msg = TEXT("This is a PIF Binary Application\n");
  295. else if ( (dwExeType & SCS_POSIX_BINARY) && bExe)
  296. msg = msg = TEXT("This is a POSIX Binary Application\n");
  297. else if ( (dwExeType & SCS_OS216_BINARY) && bExe)
  298. msg = TEXT("This is a OS2 16 bit Application\n");
  299. if (msg.Length() > 0) {
  300. //
  301. //So this application cannot be fixed
  302. //
  303. MessageBox(hDlg,
  304. msg.strcat( TEXT("The fix may not get applied properly for this application") ),
  305. TEXT("Warning!"),
  306. MB_ICONWARNING
  307. );
  308. //SetWindowLongPtr(hDlg,DWLP_MSGRESULT,-1);
  309. //return -1;
  310. }
  311. ////check - out
  312. if (strTemp != g_pCurrentWizard->m_szLongName) {
  313. //
  314. //The file name was changed. Either this is the first time that the user has come here, or has moved back and changed the file name
  315. // Remove all the mathcing info
  316. g_pCurrentWizard->WipeRecord(TRUE, FALSE, FALSE);
  317. }
  318. ////
  319. g_pCurrentWizard->m_szLongName = szTemp;
  320. g_pCurrentWizard->m_Record.szEXEName = g_pCurrentWizard->ShortFile(g_pCurrentWizard->m_szLongName);
  321. if ( TYPE_LAYER == g_pCurrentWizard->m_uType ) {
  322. int nIndex;
  323. nIndex = SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_GETCURSEL,0,0);
  324. SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_GETLBTEXT,nIndex,(LPARAM)szTemp);
  325. g_pCurrentWizard->m_Record.szLayerName = szTemp;
  326. } else {
  327. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD5);
  328. return IDD_ADDWIZARD6;
  329. }
  330. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD7);
  331. return IDD_ADDWIZARD7;
  332. }
  333. break;
  334. case PSN_WIZBACK:
  335. {
  336. TCHAR szTemp[MAX_STRING_SIZE];
  337. GetDlgItemText(hDlg,IDC_NAME,szTemp,MAX_STRING_SIZE);
  338. CSTRING::Trim(szTemp);
  339. g_pCurrentWizard->m_szLongName = szTemp;
  340. if ( TYPE_LAYER == g_pCurrentWizard->m_uType ) {
  341. int nIndex;
  342. nIndex = SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_GETCURSEL,0,0);
  343. SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_GETLBTEXT,nIndex,(LPARAM)szTemp);
  344. g_pCurrentWizard->m_Record.szLayerName = szTemp;
  345. } else {
  346. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD3);
  347. return IDD_ADDWIZARD3;
  348. }
  349. }
  350. break;
  351. }
  352. }
  353. break;
  354. case WM_COMMAND:
  355. switch ( LOWORD(wParam) ) {
  356. case IDC_LAYERLIST:
  357. {
  358. if ( CBN_SELCHANGE == HIWORD(wParam) )
  359. SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_NAME,EN_CHANGE),0);
  360. }
  361. break;
  362. case IDC_NAME:
  363. if ( EN_CHANGE == HIWORD(wParam) ) {
  364. TCHAR szText[MAX_PATH_BUFFSIZE];
  365. GetWindowText(GetDlgItem(hDlg,IDC_NAME),szText,MAX_PATH);
  366. BOOL bEnable = (CSTRING::Trim(szText) > 0) ? TRUE:FALSE;
  367. DWORD dwFlags = PSWIZB_BACK;
  368. if ( bEnable )
  369. dwFlags |= PSWIZB_NEXT;
  370. HWND hLayer = GetDlgItem(hDlg,IDC_LAYERLIST);
  371. if ( NULL != hLayer ) {
  372. // A layer must be selected as well.
  373. int nSel = SendMessage(hLayer,CB_GETCURSEL,0,0);
  374. if ( CB_ERR == nSel )
  375. dwFlags &= ~PSWIZB_NEXT;
  376. }
  377. SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS,0, dwFlags);
  378. }
  379. break;
  380. case IDC_BROWSE:
  381. {
  382. CSTRING szFilename;
  383. HWND hwndFocus = GetFocus();
  384. if ( g_theApp.GetFilename(TEXT("Find executable"),TEXT("EXE File (*.EXE)\0*.EXE\0All files (*.*)\0*.*\0\0"),TEXT(""),TEXT("EXE"),OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST,TRUE,szFilename) ) {
  385. g_pCurrentWizard->m_Record.szEXEName = g_pCurrentWizard->ShortFile(szFilename);
  386. SetDlgItemText(hDlg, IDC_NAME, szFilename);
  387. SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_NAME,EN_CHANGE),0);
  388. }
  389. SetFocus( hwndFocus );
  390. }
  391. break;
  392. }
  393. break;
  394. }
  395. return FALSE;
  396. }
  397. BOOL CALLBACK SelectMatching(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  398. {
  399. switch ( uMsg ) {
  400. case WM_INITDIALOG:
  401. {
  402. SendDlgItemMessage(hDlg,IDC_GENERATE,BM_SETCHECK,BST_CHECKED,0);
  403. }
  404. break;
  405. case WM_NOTIFY:
  406. {
  407. NMHDR * pHdr = (NMHDR *) lParam;
  408. switch ( pHdr->code ) {
  409. case PSN_SETACTIVE:
  410. SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS, 0, PSWIZB_BACK | PSWIZB_NEXT);
  411. break;
  412. case PSN_WIZNEXT:
  413. {
  414. if ( BST_CHECKED == SendDlgItemMessage(hDlg,IDC_GENERATE,BM_GETCHECK,0,0) ) {
  415. HCURSOR hRestore;
  416. CSTRING szFile = g_pCurrentWizard->m_szLongName;
  417. LPTSTR szWalk = _tcsrchr( (LPTSTR)szFile, TEXT('\\'));
  418. //
  419. // current directory extraction from the szFile
  420. //
  421. if (NULL == szWalk) {
  422. // ?
  423. } else {
  424. *szWalk = 0;
  425. }
  426. SetCurrentDirectory(szFile);
  427. g_pCurrentWizard->m_bManualMatch = FALSE;
  428. hRestore = SetCursor(LoadCursor(NULL,IDC_WAIT));
  429. g_pCurrentWizard->GrabMatchingInfo();
  430. SetCursor(hRestore);
  431. }
  432. if ( BST_CHECKED == SendDlgItemMessage(hDlg,IDC_MANUAL,BM_GETCHECK,0,0) ) {
  433. WIN32_FIND_DATA Data;
  434. HANDLE hFile;
  435. PMATCHENTRY pMatch = NULL;
  436. g_pCurrentWizard->m_bManualMatch = TRUE;
  437. hFile = FindFirstFile(g_pCurrentWizard->m_szLongName,&Data);
  438. if ( INVALID_HANDLE_VALUE != hFile ) {
  439. g_pCurrentWizard->AddMatchFile(&pMatch,g_pCurrentWizard->m_szLongName);
  440. g_pCurrentWizard->GetFileAttributes(pMatch);
  441. if ( !g_pCurrentWizard->InsertMatchingInfo(pMatch) )
  442. delete pMatch;
  443. //pMatch->Entry.pNext = g_pCurrentWizard->m_Record.pEntries;
  444. //g_pCurrentWizard->m_Record.pEntries = (PDBENTRY) pMatch;
  445. }
  446. }
  447. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD7);
  448. return IDD_ADDWIZARD7;
  449. }
  450. break;
  451. case PSN_WIZBACK:
  452. {
  453. if ( TYPE_LAYER == g_pCurrentWizard->m_uType ) {
  454. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD2);
  455. return IDD_ADDWIZARD2;
  456. } else
  457. if ( TYPE_SHIM == g_pCurrentWizard->m_uType ) {
  458. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD5);
  459. return IDD_ADDWIZARD5;
  460. }
  461. }
  462. break;
  463. }
  464. }
  465. break;
  466. }
  467. return FALSE;
  468. }
  469. BOOL CALLBACK WizardDone(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  470. {
  471. switch ( uMsg ) {
  472. case WM_NOTIFY:
  473. {
  474. NMHDR * pHdr = (NMHDR *) lParam;
  475. switch ( pHdr->code ) {
  476. case PSN_WIZBACK:
  477. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD7);
  478. return IDD_ADDWIZARD7;
  479. case PSN_SETACTIVE:
  480. SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS, 0, PSWIZB_BACK | PSWIZB_FINISH);
  481. }
  482. }
  483. break;
  484. case WM_COMMAND:
  485. switch ( LOWORD(wParam) ) {
  486. case IDC_VIEWXML:
  487. {
  488. CXMLDialog XML;
  489. XML.BeginXMLView(&g_pCurrentWizard->m_Record,hDlg,FALSE,FALSE,TRUE);
  490. }
  491. break;
  492. case IDC_TESTRUN:
  493. {
  494. HWND hndFocus = GetFocus();
  495. g_theApp.TestRun(&g_pCurrentWizard->m_Record,&g_pCurrentWizard->m_szLongName,NULL,hDlg);
  496. SetFocus(hndFocus);
  497. }
  498. break;
  499. }
  500. break;
  501. }
  502. return FALSE;
  503. }
  504. void SelectShims_TreeDoubleClicked(HWND hDlg);
  505. BOOL CALLBACK SelectShims(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  506. {
  507. switch ( uMsg ) {
  508. case WM_INITDIALOG:
  509. {
  510. TVINSERTSTRUCT Item;
  511. PSHIMDESC pWalk = g_theApp.GetDBGlobal().m_pShimList;
  512. Item.hParent = TVI_ROOT;
  513. Item.hInsertAfter = TVI_LAST;
  514. Item.item.mask = TVIF_TEXT | TVIF_PARAM;
  515. while ( NULL != pWalk ) {
  516. if ( pWalk->bGeneral ) {
  517. PSHIMENTRY pNew = new SHIMENTRY;
  518. if ( NULL != pNew ) {
  519. pNew->Entry.uType = ENTRY_SHIM;
  520. pNew->Entry.uIconID = 0;
  521. pNew->Entry.pNext = NULL;
  522. pNew->szShimName = pWalk->szShimName;
  523. pNew->szCmdLine = pWalk->szShimCommandLine;
  524. pNew->pDesc = pWalk;
  525. Item.item.pszText = (LPTSTR) pWalk->szShimName;
  526. Item.item.cchTextMax = lstrlen(Item.item.pszText);
  527. Item.item.lParam = (LPARAM) pNew;
  528. TreeView_InsertItem(GetDlgItem(hDlg,IDC_SHIMLIST),&Item);
  529. }
  530. }
  531. pWalk = pWalk->pNext;
  532. }
  533. SetTimer(hDlg,0,100,NULL);
  534. }
  535. break;
  536. case WM_COMMAND:
  537. {
  538. switch ( LOWORD(wParam) ) {
  539. case IDC_CLEARALL:
  540. {
  541. HTREEITEM hItem;
  542. HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
  543. hItem = TreeView_GetRoot(hTree);
  544. while ( NULL != hItem ) {
  545. TVITEM Item;
  546. Item.mask = TVIF_STATE;
  547. Item.hItem = hItem;
  548. TreeView_GetItem(hTree,&Item);
  549. if ( 0 != (Item.state & 0x2000) ) {
  550. Item.state &= 0xFFFFDFFF;
  551. Item.state |= 0x1000;
  552. TreeView_SetItemState(hTree,hItem,Item.state,0xFFFFFFFF);
  553. }
  554. hItem = TreeView_GetNextSibling(hTree,hItem);
  555. }
  556. // Recount
  557. SetTimer(hDlg,0,100,NULL);
  558. }
  559. break;
  560. }
  561. }
  562. break;
  563. case WM_TIMER:
  564. {
  565. UINT uTotal = 0;
  566. UINT uSelected = 0;
  567. HTREEITEM hItem;
  568. HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
  569. CSTRING szText;
  570. KillTimer(hDlg,0);
  571. // Count the selected shims
  572. hItem = TreeView_GetRoot(hTree);
  573. while ( NULL != hItem ) {
  574. TVITEM Item;
  575. Item.mask = TVIF_STATE;
  576. Item.hItem = hItem;
  577. TreeView_GetItem(hTree,&Item);
  578. if ( 0 != (Item.state & 0x2000) )
  579. ++uSelected;
  580. ++uTotal;
  581. hItem = TreeView_GetNextSibling(hTree,hItem);
  582. }
  583. szText.sprintf(TEXT("Selected %d of %d"),uSelected,uTotal);
  584. SetWindowText(GetDlgItem(hDlg,IDC_STATUS),(LPCTSTR)szText);
  585. DWORD dwFlags = PSWIZB_BACK | PSWIZB_NEXT;
  586. if ( 0 == uSelected )
  587. dwFlags &= ~PSWIZB_NEXT;
  588. SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS,0, dwFlags);
  589. }
  590. break;
  591. case WM_DESTROY:
  592. {
  593. HTREEITEM hItem;
  594. HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
  595. hItem = TreeView_GetRoot(hTree);
  596. while ( NULL != hItem ) {
  597. TVITEM Item;
  598. Item.mask = TVIF_STATE | TVIF_PARAM;
  599. Item.hItem = hItem;
  600. TreeView_GetItem(hTree,&Item);
  601. PSHIMENTRY pEntry = (PSHIMENTRY) Item.lParam;
  602. PDBENTRY pWalk = g_pCurrentWizard->m_Record.pEntries;
  603. while ( NULL != pWalk ) {
  604. if ( pWalk == (PDBENTRY)pEntry )
  605. break;
  606. pWalk = pWalk->pNext;
  607. }
  608. if ( NULL == pWalk )
  609. delete pEntry;
  610. hItem = TreeView_GetNextSibling(hTree,hItem);
  611. }
  612. }
  613. break;
  614. case WM_NOTIFY:
  615. {
  616. NMHDR * pHdr = (NMHDR *) lParam;
  617. switch ( pHdr->code ) {
  618. case NM_RETURN:{
  619. SelectShims_TreeDoubleClicked(hDlg);
  620. return TRUE;
  621. }
  622. case PSN_SETACTIVE:
  623. SetTimer(hDlg,0,100,NULL);
  624. break;
  625. case NM_DBLCLK:
  626. {
  627. SelectShims_TreeDoubleClicked(hDlg);
  628. }//case NM_DBLCLK:
  629. break;
  630. case NM_CLICK:
  631. {
  632. TVHITTESTINFO ht;
  633. HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
  634. GetCursorPos(&ht.pt);
  635. ScreenToClient(hTree, &ht.pt);
  636. TreeView_HitTest(hTree,&ht);
  637. if ( 0 != ht.hItem )
  638. TreeView_SelectItem(hTree,ht.hItem);
  639. SetTimer(hDlg,0,100,NULL);
  640. }
  641. break;
  642. case PSN_WIZBACK:
  643. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD6);
  644. return IDD_ADDWIZARD6;
  645. case PSN_WIZNEXT:
  646. {
  647. // Build the shim list.
  648. HTREEITEM hItem;
  649. HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
  650. // Wipe shims and layers, but not matching info.
  651. g_pCurrentWizard->WipeRecord(FALSE,TRUE,TRUE);
  652. hItem = TreeView_GetRoot(hTree);
  653. while ( NULL != hItem ) {
  654. TVITEM Item;
  655. Item.mask = TVIF_STATE | TVIF_PARAM;
  656. Item.hItem = hItem;
  657. TreeView_GetItem(hTree,&Item);
  658. PSHIMENTRY pEntry = (PSHIMENTRY) Item.lParam;
  659. pEntry->Entry.pNext = NULL;
  660. if ( 0 != (Item.state & 0x2000) ) {
  661. pEntry->Entry.pNext = g_pCurrentWizard->m_Record.pEntries;
  662. g_pCurrentWizard->m_Record.pEntries = (PDBENTRY) pEntry;
  663. }
  664. hItem = TreeView_GetNextSibling(hTree,hItem);
  665. }
  666. //SetWindowLong(hDlg,DWL_MSGRESULT,IDD_ADDWIZARD4);
  667. //return IDD_ADDWIZARD4;
  668. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD7);
  669. return IDD_ADDWIZARD7;
  670. }
  671. break;
  672. case TVN_KEYDOWN:{
  673. LPNMTVKEYDOWN pTvkd = (LPNMTVKEYDOWN) lParam ;
  674. HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
  675. if (pTvkd->wVKey == VK_SPACE ) {
  676. if (TreeView_GetSelection(hTree) != NULL ){
  677. SetTimer(hDlg,0,100,NULL);
  678. }
  679. }
  680. break;
  681. }
  682. case TVN_SELCHANGED:
  683. {
  684. LPNMTREEVIEW pTree = (LPNMTREEVIEW) lParam;
  685. PSHIMENTRY pEntry = (PSHIMENTRY) pTree->itemOld.lParam;
  686. TCHAR szCmdLine[MAX_PATH_BUFFSIZE];
  687. /* K BUG why is this required !
  688. if ( NULL != pEntry ) {
  689. GetWindowText(GetDlgItem(hDlg,IDC_CMDLINE),szCmdLine,MAX_PATH);
  690. pEntry->szCmdLine = szCmdLine;
  691. }
  692. */
  693. pEntry = (PSHIMENTRY) pTree->itemNew.lParam;
  694. PSHIMDESC pDesc = (PSHIMDESC) pEntry->pDesc;
  695. SetWindowText(GetDlgItem(hDlg,IDC_SHIMDESC),(LPCTSTR) pDesc->szShimDesc);
  696. SetWindowText(GetDlgItem(hDlg,IDC_CMDLINE),(LPCTSTR) pEntry->szCmdLine);
  697. }
  698. break;
  699. }
  700. }
  701. break;
  702. }
  703. return FALSE;
  704. }
  705. BOOL CALLBACK SelectFiles(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  706. {
  707. switch ( uMsg ) {
  708. case WM_INITDIALOG:
  709. {
  710. PostMessage(hDlg,WM_USER+1024,0,0);
  711. }
  712. break;
  713. case WM_USER+1024:
  714. {
  715. PDBENTRY pWalk;
  716. TreeView_DeleteAllItems(GetDlgItem(hDlg,IDC_FILELIST));
  717. pWalk = g_pCurrentWizard->m_Record.pEntries;
  718. TVINSERTSTRUCT Item;
  719. ZeroMemory(&Item,sizeof(TVINSERTSTRUCT));
  720. Item.hParent = TVI_ROOT;
  721. Item.hInsertAfter = TVI_LAST;
  722. Item.item.mask = TVIF_TEXT | TVIF_PARAM;
  723. Item.item.lParam = (LPARAM) NULL;
  724. Item.item.pszText = g_pCurrentWizard->m_Record.szEXEName;
  725. Item.item.cchTextMax = lstrlen(Item.item.pszText);
  726. TreeView_InsertItem(GetDlgItem(hDlg,IDC_FILELIST),&Item);
  727. while ( NULL != pWalk ) {
  728. if ( ENTRY_MATCH == pWalk->uType ) {
  729. TVINSERTSTRUCT Item;
  730. PMATCHENTRY pMatch = (PMATCHENTRY) pWalk;
  731. if ( pMatch->szMatchName != TEXT("*") ) {
  732. ZeroMemory(&Item,sizeof(TVINSERTSTRUCT));
  733. Item.hParent = TVI_ROOT;
  734. Item.hInsertAfter = TVI_LAST;
  735. Item.item.mask = TVIF_TEXT | TVIF_PARAM;
  736. Item.item.lParam = (LPARAM) pMatch;
  737. Item.item.pszText = pMatch->szMatchName;
  738. Item.item.cchTextMax = lstrlen(Item.item.pszText);
  739. TreeView_InsertItem(GetDlgItem(hDlg,IDC_FILELIST),&Item);
  740. }
  741. }
  742. pWalk = pWalk->pNext;
  743. }
  744. }
  745. break;
  746. case WM_NOTIFY:
  747. {
  748. NMHDR * pHdr = (NMHDR *) lParam;
  749. switch ( pHdr->code ) {
  750. case PSN_SETACTIVE:
  751. {
  752. SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS, 0, PSWIZB_BACK | PSWIZB_NEXT);
  753. // Force refresh of files in list.
  754. PostMessage(hDlg,WM_USER+1024,0,0);
  755. }
  756. break;
  757. case PSN_WIZBACK:
  758. {
  759. PMATCHENTRY pWalk = (PMATCHENTRY) g_pCurrentWizard->m_Record.pEntries;
  760. PMATCHENTRY pPrev;
  761. CSTRING szFile = g_pCurrentWizard->m_szLongName;
  762. szFile.ShortFilename();
  763. // Remove the matching info for the current file if it exists. Otherwise,
  764. // it's possible that if the file is changed, we'll have bogus information
  765. // about it.
  766. while ( NULL != pWalk ) {
  767. if ( ENTRY_MATCH == pWalk->Entry.uType )
  768. if ( pWalk->szMatchName == szFile || pWalk->szMatchName == TEXT("*") ) {
  769. // Remove this entry.
  770. if ( pWalk == (PMATCHENTRY) g_pCurrentWizard->m_Record.pEntries )
  771. g_pCurrentWizard->m_Record.pEntries = g_pCurrentWizard->m_Record.pEntries->pNext;
  772. else
  773. pPrev->Entry.pNext = pWalk->Entry.pNext;
  774. delete pWalk;
  775. break;
  776. }
  777. pPrev = pWalk;
  778. pWalk = (PMATCHENTRY) pWalk->Entry.pNext;
  779. }
  780. if ( TYPE_LAYER == g_pCurrentWizard->m_uType ) {
  781. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD2);
  782. return IDD_ADDWIZARD2;
  783. } else if ( TYPE_SHIM == g_pCurrentWizard->m_uType ) {
  784. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD5);
  785. return IDD_ADDWIZARD5;
  786. }
  787. else if (TYPE_APPHELP == g_pCurrentWizard->m_uType ) {
  788. return IDD_APPHELP1;
  789. }
  790. }
  791. break;
  792. case PSN_WIZNEXT:
  793. {
  794. PMATCHENTRY pMatch = NULL;
  795. // Add self. Self should always be included here.
  796. g_pCurrentWizard->AddMatchFile(&pMatch,g_pCurrentWizard->m_szLongName);
  797. g_pCurrentWizard->GetFileAttributes(pMatch);
  798. if ( !g_pCurrentWizard->InsertMatchingInfo(pMatch) )
  799. delete pMatch;
  800. //pMatch->Entry.pNext = g_pCurrentWizard->m_Record.pEntries;
  801. //g_pCurrentWizard->m_Record.pEntries = (PDBENTRY) pMatch;
  802. if (TYPE_APPHELP == g_pCurrentWizard->m_uType)
  803. return TRUE;
  804. SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARDDONE);
  805. }
  806. return IDD_ADDWIZARDDONE;
  807. }
  808. }
  809. break;
  810. case WM_COMMAND:
  811. switch ( LOWORD(wParam) ) {
  812. case IDC_GENERATE:
  813. {
  814. HCURSOR hRestore;
  815. CSTRING szFile = g_pCurrentWizard->m_szLongName;
  816. LPTSTR szWalk = (LPTSTR) szFile + szFile.Length() - 1;
  817. while ( TEXT('\\') != *szWalk )
  818. --szWalk;
  819. ++szWalk;
  820. *szWalk = 0;
  821. SetCurrentDirectory(szFile);
  822. g_pCurrentWizard->m_bManualMatch = FALSE;
  823. hRestore = SetCursor(LoadCursor(NULL,IDC_WAIT));
  824. g_pCurrentWizard->GrabMatchingInfo();
  825. SetCursor(hRestore);
  826. PostMessage(hDlg,WM_USER+1024,0,0);
  827. }
  828. break;
  829. case IDC_ADDFILES:
  830. {
  831. CSTRING szFilename;
  832. HWND hwndFocus = GetFocus();
  833. if ( g_theApp.GetFilename(TEXT("Find Matching File"),TEXT("EXE File (*.EXE)\0*.EXE\0All Files(*.*)\0*.*\0\0"),TEXT(""),TEXT(""),OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST,TRUE,szFilename) ) {
  834. CSTRING szCheck = szFilename;
  835. szCheck.ShortFilename();
  836. PDBENTRY pWalk;
  837. pWalk = g_pCurrentWizard->m_Record.pEntries;
  838. while ( NULL != pWalk ) {
  839. if ( ENTRY_MATCH == pWalk->uType ) {
  840. PMATCHENTRY pTest = (PMATCHENTRY) pWalk;
  841. CSTRING szShort = pTest->szMatchName;
  842. szShort.ShortFilename();
  843. if ( szShort == szCheck ) {
  844. MessageBox(hDlg,TEXT("This file is already being used for matching information. To update, please remove and re-add it."),TEXT("File matching error"),MB_OK);
  845. return FALSE;
  846. }
  847. }
  848. pWalk = pWalk->pNext;
  849. }
  850. //WIN32_FIND_DATA Data;
  851. //HANDLE hFile;
  852. //hFile = FindFirstFile(szFilename,&Data);
  853. //if (INVALID_HANDLE_VALUE != hFile)
  854. {
  855. PMATCHENTRY pMatch = NULL;
  856. g_pCurrentWizard->AddMatchFile(&pMatch,szFilename);
  857. g_pCurrentWizard->GetFileAttributes(pMatch);
  858. if ( !g_pCurrentWizard->InsertMatchingInfo(pMatch) )
  859. delete pMatch;
  860. //pMatch->Entry.pNext = g_pCurrentWizard->m_Record.pEntries;
  861. //g_pCurrentWizard->m_Record.pEntries = (PDBENTRY) pMatch;
  862. //FindClose(hFile);
  863. PostMessage(hDlg,WM_USER+1024,0,0);
  864. }
  865. }
  866. SetFocus( hwndFocus );
  867. }
  868. break;
  869. case IDC_REMOVEALL:
  870. {
  871. PDBENTRY pWalk;
  872. PDBENTRY pHold;
  873. pWalk = g_pCurrentWizard->m_Record.pEntries;
  874. while ( NULL != pWalk ) {
  875. if ( ENTRY_MATCH == pWalk->uType ) {
  876. if ( g_pCurrentWizard->m_Record.pEntries == pWalk ) {
  877. g_pCurrentWizard->m_Record.pEntries = pWalk->pNext;
  878. pHold = g_pCurrentWizard->m_Record.pEntries;
  879. } else
  880. pHold->pNext = pWalk->pNext;
  881. delete pWalk;
  882. pWalk = pHold;
  883. } else {
  884. pHold = pWalk;
  885. pWalk = pWalk->pNext;
  886. }
  887. }
  888. PostMessage(hDlg,WM_USER+1024,0,0);
  889. }
  890. break;
  891. case IDC_REMOVEFILES:
  892. {
  893. HTREEITEM hItem = TreeView_GetSelection(GetDlgItem(hDlg,IDC_FILELIST));
  894. if ( NULL != hItem ) {
  895. TVITEM Item;
  896. Item.mask = TVIF_PARAM;
  897. Item.hItem = hItem;
  898. TreeView_GetItem(GetDlgItem(hDlg,IDC_FILELIST),&Item);
  899. PDBENTRY pWalk;
  900. PDBENTRY pHold;
  901. if ( NULL == Item.lParam ) {
  902. MessageBeep(MB_OK);
  903. MessageBox(NULL,TEXT("This file is required for file matching"),TEXT("Matching error"),MB_OK);
  904. break;
  905. }
  906. pWalk = g_pCurrentWizard->m_Record.pEntries;
  907. while ( NULL != pWalk ) {
  908. if ( pWalk == (PDBENTRY) Item.lParam )
  909. break;
  910. pHold = pWalk;
  911. pWalk = pWalk->pNext;
  912. }
  913. if ( pWalk == g_pCurrentWizard->m_Record.pEntries )
  914. g_pCurrentWizard->m_Record.pEntries = pWalk->pNext;
  915. else
  916. pHold->pNext = pWalk->pNext;
  917. delete pWalk;
  918. PostMessage(hDlg,WM_USER+1024,0,0);
  919. }
  920. }
  921. break;
  922. }
  923. break;
  924. }
  925. return FALSE;
  926. }
  927. void CShimWizard::WipeRecord(BOOL bMatching, BOOL bShims, BOOL bLayer, BOOL bAppHelp)
  928. {
  929. //BUGBUG : Deletion not done correctly.
  930. //
  931. // Matching files are deleted, shims are not ??
  932. //
  933. PDBENTRY pWalk = m_Record.pEntries;
  934. PDBENTRY pPrev = pWalk;//prefast
  935. while ( NULL != pWalk ) {
  936. PDBENTRY pHold = pWalk->pNext;
  937. BOOL bRemove = FALSE;
  938. if ( ENTRY_SHIM == pWalk->uType && bShims )
  939. bRemove = TRUE;
  940. else
  941. if ( ENTRY_MATCH == pWalk->uType && bMatching ) {
  942. bRemove = TRUE;
  943. delete pWalk;
  944. }
  945. #ifdef _DEBUG
  946. if ( bRemove ) {
  947. if ( m_Record.pEntries != pWalk )
  948. if ( pPrev == pHold )
  949. __asm int 3;
  950. }
  951. #endif
  952. if ( bRemove ) {
  953. if ( m_Record.pEntries == pWalk )
  954. m_Record.pEntries = pHold;
  955. else
  956. pPrev->pNext = pHold;
  957. } else
  958. pPrev = pWalk;
  959. pWalk = pHold;
  960. }
  961. if ( bLayer )
  962. m_Record.szLayerName = TEXT("");
  963. }
  964. typedef struct tagATTRINFO2 {
  965. TAG tAttrID; // tag for this attribute (includes type)
  966. DWORD dwFlags; // flags : such as "not avail" or "not there yet"
  967. union { // anonymous union with values
  968. ULONGLONG ullAttr; // QWORD value (TAG_TYPE_QWORD)
  969. DWORD dwAttr; // DWORD value (TAG_TYPE_DWORD)
  970. TCHAR* lpAttr; // WCHAR* value (TAG_TYPE_STRINGREF)
  971. };
  972. } ATTRINFO2, *PATTRINFO2;
  973. void CShimWizard::GetFileAttributes(PMATCHENTRY pNew)
  974. {
  975. PATTRINFO2 pAttribs;
  976. DWORD dwAttribCount;
  977. CSTRING szFile = pNew->szFullName;
  978. BOOL bIs16Bit = FALSE;
  979. /*
  980. DWORD dwType;
  981. GetBinaryType(szFile,&dwType);
  982. if (SCS_WOW_BINARY == dwType)
  983. bIs16Bit = TRUE;
  984. */
  985. if ( szFile.Length() == 0 ) {
  986. MEM_ERR;
  987. return;
  988. }
  989. if ( SdbGetFileAttributes((LPCTSTR)szFile,(PATTRINFO *)&pAttribs,&dwAttribCount) ) {
  990. UINT uCount;
  991. for ( uCount=0; uCount<dwAttribCount; ++uCount ) {
  992. if ( 0 != (pAttribs[uCount].dwFlags & ATTRIBUTE_AVAILABLE) ) {
  993. switch ( pAttribs[uCount].tAttrID ) {
  994. case TAG_COMPANY_NAME:
  995. pNew->szCompanyName = (LPCTSTR)pAttribs[uCount].lpAttr;
  996. break;
  997. case TAG_PRODUCT_VERSION:
  998. pNew->szProductVersion = (LPCTSTR)pAttribs[uCount].lpAttr;
  999. break;
  1000. case TAG_FILE_DESCRIPTION:
  1001. pNew->szDescription = (LPCTSTR)pAttribs[uCount].lpAttr;
  1002. break;
  1003. case TAG_FILE_VERSION:
  1004. pNew->szFileVersion = (LPCTSTR)pAttribs[uCount].lpAttr;
  1005. break;
  1006. case TAG_CHECKSUM:
  1007. pNew->dwChecksum = pAttribs[uCount].dwAttr;
  1008. break;
  1009. case TAG_BIN_FILE_VERSION:
  1010. {
  1011. if ( !bIs16Bit )
  1012. pNew->FileVersion.QuadPart = pAttribs[uCount].ullAttr;
  1013. }
  1014. break;
  1015. case TAG_BIN_PRODUCT_VERSION:
  1016. {
  1017. if ( !bIs16Bit )
  1018. pNew->ProductVersion.QuadPart = pAttribs[uCount].ullAttr;
  1019. }
  1020. break;
  1021. }
  1022. }
  1023. }
  1024. SdbFreeFileAttributes((PATTRINFO)pAttribs);
  1025. }
  1026. }
  1027. void CShimWizard::AddMatchFile(PPMATCHENTRY ppHead, CSTRING & szFilename)
  1028. {
  1029. PMATCHENTRY pNew;
  1030. PMATCHENTRY pWalk;
  1031. PMATCHENTRY pHold;
  1032. BOOL bInsertHead=FALSE;
  1033. CSTRING szFile; // = RelativePath();
  1034. //TCHAR szCurrentPath[MAX_PATH_BUFFSIZE];
  1035. pNew = new MATCHENTRY;
  1036. if ( NULL == pNew )
  1037. return;
  1038. ZeroMemory(pNew,sizeof(MATCHENTRY));
  1039. //GetCurrentDirectory(MAX_PATH,szCurrentPath);
  1040. //if (lstrlen(szCurrentPath) == 3)
  1041. //szCurrentPath[2] = 0;
  1042. //szFile.sprintf("%s\\%s",szCurrentPath,pData->cFileName);
  1043. //szFile = szCurrentPath;
  1044. ///szFile.strcat(pData->cFileName);
  1045. //pNew->szFullName.sprintf("%s\\%s",szCurrentPath,pData->cFileName);
  1046. pNew->szFullName = szFilename;
  1047. //szFile.strcat(pData->cFileName);
  1048. szFile = pNew->szFullName;
  1049. szFile.RelativeFile(m_szLongName);
  1050. pNew->Entry.uType = ENTRY_MATCH;
  1051. pNew->szMatchName = szFile;
  1052. HANDLE hFile = CreateFile((LPCTSTR) szFilename,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  1053. if ( INVALID_HANDLE_VALUE != hFile ) {
  1054. //pNew->dwSize = pData->nFileSizeLow;
  1055. pNew->dwSize = GetFileSize(hFile,NULL);
  1056. CloseHandle(hFile);
  1057. }
  1058. pWalk = *ppHead;
  1059. // Walk the list to determine where to insert it.
  1060. while ( NULL != pWalk ) {
  1061. if ( pWalk->dwSize < pNew->dwSize )
  1062. break;
  1063. pHold = pWalk;
  1064. pWalk = (PMATCHENTRY) pWalk->Entry.pNext;
  1065. }
  1066. // Insert it into the head if the head is NULL, OR if this file is
  1067. // the same as the file being fixed.
  1068. CSTRING szShort = szFilename;
  1069. if ( szShort.Length() == 0 ) {
  1070. MEM_ERR;
  1071. return;
  1072. }
  1073. szShort.ShortFilename();
  1074. if ( NULL == *ppHead || 0 == lstrcmpi(szShort,m_Record.szEXEName) ) {//0 == lstrcmpi(pData->cFileName,m_Record.szEXEName))
  1075. bInsertHead = TRUE;
  1076. //if (0 == lstrcmpi(pData->cFileName,m_Record.szEXEName))
  1077. if ( 0 == lstrcmpi(szShort,m_Record.szEXEName) )
  1078. pNew->szMatchName = TEXT("*");
  1079. } else
  1080. if ( *ppHead == pWalk )
  1081. bInsertHead = TRUE;
  1082. if ( NULL != pWalk && pWalk->szMatchName == pNew->szMatchName ) {
  1083. // Duplicate here. Refuse.
  1084. delete pNew;
  1085. return;
  1086. }
  1087. if ( bInsertHead ) {
  1088. if ( NULL != *ppHead && 0 == lstrcmpi(pNew->szMatchName,TEXT("*")) ) {
  1089. // If the file to fix has aleady been added at the head, special
  1090. // case this insert.
  1091. pNew->Entry.pNext = (*ppHead)->Entry.pNext;
  1092. (*ppHead)->Entry.pNext = (PDBENTRY) pNew;
  1093. } else {
  1094. // Standard head insert.
  1095. pNew->Entry.pNext = (PDBENTRY) *ppHead;
  1096. *ppHead = pNew;
  1097. }
  1098. } else {
  1099. pNew->Entry.pNext = (PDBENTRY) pWalk;
  1100. pHold->Entry.pNext =(PDBENTRY) pNew;
  1101. }
  1102. }
  1103. void CShimWizard::WalkDirectory(PMATCHENTRY * ppHead, LPCTSTR szDirectory, int nDepth)
  1104. {
  1105. HANDLE hFile;
  1106. WIN32_FIND_DATA Data;
  1107. TCHAR szCurrentDir[MAX_PATH_BUFFSIZE] = TEXT("");
  1108. int nFiles=0;
  1109. if ( 2 <= nDepth )
  1110. return;
  1111. CSTRING szShortName = m_szLongName;
  1112. szShortName.ShortFilename();
  1113. // Save the current directory
  1114. GetCurrentDirectory(MAX_PATH,szCurrentDir);
  1115. // Set to the new directory
  1116. SetCurrentDirectory(szDirectory);
  1117. // Generate automated matching file information.
  1118. hFile = FindFirstFile(TEXT("*.*"),&Data);
  1119. if ( INVALID_HANDLE_VALUE == hFile ) {
  1120. SetCurrentDirectory(szCurrentDir);
  1121. return;
  1122. }
  1123. do {
  1124. if ( 0 == (Data.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) )
  1125. if ( FILE_ATTRIBUTE_DIRECTORY == (Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
  1126. if ( TEXT('.') != Data.cFileName[0] )
  1127. WalkDirectory(ppHead,Data.cFileName,nDepth+1);
  1128. } else {
  1129. ++nFiles;
  1130. if ( nFiles >= 100 )
  1131. break;
  1132. if ( 0 != lstrcmpi(szShortName,Data.cFileName) )
  1133. if ( 0 == (Data.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) ) {
  1134. CSTRING szFilename;
  1135. if ( lstrlen(szCurrentDir) > 3 )
  1136. szFilename.sprintf(TEXT("%s\\%s\\%s"),szCurrentDir,szDirectory,Data.cFileName);
  1137. else
  1138. szFilename.sprintf(TEXT("%s%s\\%s"),szCurrentDir,szDirectory,Data.cFileName);
  1139. AddMatchFile(ppHead,szFilename);
  1140. }
  1141. }
  1142. }
  1143. while ( FindNextFile(hFile,&Data) );
  1144. FindClose(hFile);
  1145. // Restore old directory
  1146. SetCurrentDirectory(szCurrentDir);
  1147. }
  1148. CSTRING CShimWizard::ShortFile(CSTRING & szStr)
  1149. {
  1150. LPTSTR szTemp = szStr;
  1151. CSTRING szRet;
  1152. LPTSTR szWalk = szTemp;
  1153. while ( 0 != *szWalk ) {
  1154. if ( TEXT('\\') == *szWalk )
  1155. szTemp = szWalk+1;
  1156. ++szWalk;
  1157. }
  1158. szRet = szTemp;
  1159. return szRet;
  1160. }
  1161. void CShimWizard::GrabMatchingInfo(void)
  1162. {
  1163. PMATCHENTRY pHead = NULL;
  1164. // Delete any matching info which might have already been bound to the record.
  1165. PDBENTRY pEntry = m_Record.pEntries;
  1166. PDBENTRY pPrev = m_Record.pEntries;
  1167. while ( NULL != pEntry ) {
  1168. PDBENTRY pHold = pEntry->pNext;
  1169. if ( ENTRY_MATCH == pEntry->uType ) {
  1170. delete pEntry;
  1171. if ( pEntry == m_Record.pEntries ) {
  1172. m_Record.pEntries = pHold;
  1173. pPrev = m_Record.pEntries;
  1174. } else
  1175. pPrev->pNext = pHold;
  1176. } else
  1177. pPrev = pEntry;
  1178. pEntry = pHold;
  1179. }
  1180. // Generate automated matching file information.
  1181. WalkDirectory(&pHead,TEXT("."),0);
  1182. // Now, take the first X entries and discard the rest.
  1183. int nCount = MAX_AUTO_MATCH;
  1184. PMATCHENTRY pWalk = pHead;
  1185. PMATCHENTRY pTerm = NULL;
  1186. while ( NULL != pWalk ) {
  1187. if ( 0 >= nCount ) {
  1188. PMATCHENTRY pHold = (PMATCHENTRY) pWalk->Entry.pNext;
  1189. delete pWalk;
  1190. pWalk = pHold;
  1191. } else {
  1192. --nCount;
  1193. if ( 1 == nCount )
  1194. pTerm = (PMATCHENTRY) pWalk->Entry.pNext;
  1195. pWalk = (PMATCHENTRY) pWalk->Entry.pNext;
  1196. }
  1197. }
  1198. if ( NULL != pTerm )
  1199. pTerm->Entry.pNext = NULL;
  1200. pWalk = pHead;
  1201. while ( NULL != pWalk ) {
  1202. GetFileAttributes(pWalk);
  1203. pWalk = (PMATCHENTRY)pWalk->Entry.pNext;
  1204. }
  1205. // Bind this data to the record.
  1206. pWalk = pHead;
  1207. // Find the end....
  1208. while ( NULL != pWalk && NULL != pWalk->Entry.pNext ) {
  1209. PMATCHENTRY pHold = (PMATCHENTRY) pWalk->Entry.pNext;
  1210. GetFileAttributes(pWalk);
  1211. if ( !InsertMatchingInfo(pWalk) )
  1212. delete pWalk;
  1213. pWalk = pHold;
  1214. }
  1215. }
  1216. BOOL CShimWizard::InsertMatchingInfo(PMATCHENTRY pNew)
  1217. {
  1218. PDBENTRY pWalk = m_Record.pEntries;
  1219. PDBENTRY pHold;
  1220. while ( NULL != pWalk ) {
  1221. if ( ENTRY_MATCH == pWalk->uType ) {
  1222. PMATCHENTRY pThis = (PMATCHENTRY) pWalk;
  1223. if ( pThis->szMatchName == pNew->szMatchName )
  1224. return FALSE;
  1225. if ( 0 < lstrcmpi(pThis->szMatchName,pNew->szMatchName) )
  1226. break;
  1227. }
  1228. pHold = pWalk;
  1229. pWalk = pWalk->pNext;
  1230. }
  1231. if ( pWalk == m_Record.pEntries ) {
  1232. pNew->Entry.pNext = m_Record.pEntries;
  1233. m_Record.pEntries = (PDBENTRY) pNew;
  1234. } else {
  1235. pNew->Entry.pNext = pWalk;
  1236. pHold->pNext = (PDBENTRY) pNew;
  1237. }
  1238. return TRUE;
  1239. }
  1240. INT_PTR CALLBACK
  1241. EditCmdLineDlgProc(
  1242. HWND hdlg,
  1243. UINT uMsg,
  1244. WPARAM wParam,
  1245. LPARAM lParam
  1246. )
  1247. /*++
  1248. EditCmdLineDlgProc
  1249. Description: Handles messages for the edit control.
  1250. --*/
  1251. {
  1252. int wCode = LOWORD(wParam);
  1253. int wNotifyCode = HIWORD(wParam);
  1254. switch (uMsg) {
  1255. case WM_INITDIALOG:
  1256. {
  1257. SendMessage(
  1258. GetDlgItem(hdlg,IDC_SHIM_CMD_LINE), // handle to destination window
  1259. EM_LIMITTEXT, // message to send
  1260. (WPARAM) 256, // text length
  1261. (LPARAM) 0
  1262. );
  1263. SHAutoComplete(GetDlgItem(hdlg,IDC_SHIM_CMD_LINE), AUTOCOMPLETE);
  1264. PSHIMENTRY pShimEntry;
  1265. pShimEntry = (PSHIMENTRY)lParam;
  1266. SetWindowLongPtr(hdlg, DWLP_USER, lParam);
  1267. SetDlgItemText(hdlg, IDC_SHIM_NAME, pShimEntry->szShimName);
  1268. if ( pShimEntry->szCmdLine.Length() > 0 ) {
  1269. SetDlgItemText(hdlg, IDC_SHIM_CMD_LINE, pShimEntry->szCmdLine);
  1270. }
  1271. break;
  1272. }
  1273. case WM_COMMAND:
  1274. switch (wCode) {
  1275. case IDOK:
  1276. {
  1277. PSHIMENTRY pShimEntry;
  1278. TCHAR szCmdLine[1024] = _T("");
  1279. pShimEntry = ( PSHIMENTRY)GetWindowLongPtr(hdlg, DWLP_USER);
  1280. GetDlgItemText(hdlg, IDC_SHIM_CMD_LINE, szCmdLine, sizeof(szCmdLine)/sizeof(TCHAR));
  1281. if (*szCmdLine != 0) {
  1282. pShimEntry->szCmdLine = szCmdLine;
  1283. } else {
  1284. pShimEntry->szCmdLine.Release();
  1285. }
  1286. EndDialog(hdlg, TRUE);
  1287. break;
  1288. }
  1289. case IDCANCEL:
  1290. EndDialog(hdlg, FALSE);
  1291. break;
  1292. default:
  1293. return FALSE;
  1294. }
  1295. break;
  1296. default:
  1297. return FALSE;
  1298. }
  1299. return TRUE;
  1300. }
  1301. void SelectShims_TreeDoubleClicked(HWND hDlg)
  1302. {
  1303. HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
  1304. HTREEITEM hItem;
  1305. TVITEM tvi;
  1306. hItem = TreeView_GetSelection(hTree);
  1307. if (hItem == NULL) return;
  1308. tvi.hItem = hItem;
  1309. tvi.mask = TVIF_HANDLE | TVIF_PARAM;
  1310. TreeView_GetItem(hTree, &tvi);
  1311. PSHIMENTRY pEntry = (PSHIMENTRY) tvi.lParam;
  1312. ///////
  1313. if (DialogBoxParam(g_hInstance,
  1314. MAKEINTRESOURCE(IDD_CMD_LINE),
  1315. hDlg,
  1316. EditCmdLineDlgProc,
  1317. (LPARAM)pEntry)) {
  1318. TCHAR szText[1024];
  1319. tvi.mask = TVIF_HANDLE | TVIF_TEXT;
  1320. if ( pEntry->szCmdLine.Length() == 0 ) {
  1321. tvi.pszText = pEntry->szShimName;
  1322. } else {
  1323. wsprintf(szText, _T("%s - (%s)"), (LPCTSTR)pEntry->szShimName, (LPCTSTR)pEntry->szCmdLine);
  1324. tvi.pszText = szText;
  1325. }
  1326. TreeView_SetItem(hTree, &tvi);
  1327. }
  1328. ///////
  1329. }//void SelectShims_TreeDoubleClicked(HWND hDlg)