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.

669 lines
17 KiB

  1. // BrowseAppCompat.cpp : Defines the entry point for the application.
  2. //
  3. #include "acBrowser.h"
  4. #include "resource.h"
  5. #include <commctrl.h>
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <stdarg.h>
  9. /*
  10. * Global Variables
  11. */
  12. HINSTANCE g_hInstance;
  13. HWND g_hDlg;
  14. HWND g_hwndList;
  15. HFONT g_hFont;
  16. int g_nItems;
  17. BOOL g_bEnable;
  18. BOOL g_bDelete;
  19. #define CHANGE_NOCHANGE 0
  20. #define CHANGE_ENABLE 1
  21. #define CHANGE_DISABLE 2
  22. #define CHANGE_DELETE 3
  23. #define COLUMN_APP 0
  24. #define COLUMN_STATUS 1
  25. #define COLUMN_CHANGE 2
  26. typedef struct tagREGITEM {
  27. char* pszApp;
  28. char* pszShim;
  29. char* pszAttr;
  30. int nItem;
  31. BOOL bShim;
  32. BOOL bEnabled;
  33. int change;
  34. } REGITEM, *PREGITEM;
  35. /*********************************************************************
  36. * LogMsg
  37. *
  38. *********************************************************************/
  39. void LogMsg(
  40. LPSTR pszFmt,
  41. ... )
  42. {
  43. CHAR gszT[1024];
  44. va_list arglist;
  45. va_start(arglist, pszFmt);
  46. _vsnprintf(gszT, 1023, pszFmt, arglist);
  47. gszT[1023] = 0;
  48. va_end(arglist);
  49. OutputDebugString(gszT);
  50. }
  51. /*******************************************************************************
  52. * CenterWindow
  53. *
  54. * This function must be called at the WM_INIDIALOG in order to
  55. * move the dialog window centered in the client area of the
  56. * parent or owner window.
  57. *******************************************************************************/
  58. BOOL CenterWindow(
  59. HWND hWnd)
  60. {
  61. RECT rectWindow, rectParent, rectScreen;
  62. int nCX, nCY;
  63. HWND hParent;
  64. POINT ptPoint;
  65. hParent = GetParent(hWnd);
  66. if (hParent == NULL)
  67. hParent = GetDesktopWindow();
  68. GetWindowRect(hParent, (LPRECT)&rectParent);
  69. GetWindowRect(hWnd, (LPRECT)&rectWindow);
  70. GetWindowRect(GetDesktopWindow(), (LPRECT)&rectScreen);
  71. nCX = rectWindow.right - rectWindow.left;
  72. nCY = rectWindow.bottom - rectWindow.top;
  73. ptPoint.x = ((rectParent.right + rectParent.left) / 2) - (nCX / 2);
  74. ptPoint.y = ((rectParent.bottom + rectParent.top ) / 2) - (nCY / 2);
  75. if (ptPoint.x < rectScreen.left)
  76. ptPoint.x = rectScreen.left;
  77. if (ptPoint.x > rectScreen.right - nCX)
  78. ptPoint.x = rectScreen.right - nCX;
  79. if (ptPoint.y < rectScreen.top)
  80. ptPoint.y = rectScreen.top;
  81. if (ptPoint.y > rectScreen.bottom - nCY)
  82. ptPoint.y = rectScreen.bottom - nCY;
  83. if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
  84. ScreenToClient(hParent, (LPPOINT)&ptPoint);
  85. if (!MoveWindow(hWnd, ptPoint.x, ptPoint.y, nCX, nCY, TRUE))
  86. return FALSE;
  87. return TRUE;
  88. }
  89. /*********************************************************************
  90. * AddShimToList
  91. *
  92. *********************************************************************/
  93. VOID AddShimToList(
  94. char* pszApp,
  95. char* pszShim,
  96. char* pszData,
  97. BOOL bEnabled,
  98. BOOL bShim)
  99. {
  100. char* pszAppAlloc;
  101. char* pszShimAlloc;
  102. char* pszDataAlloc;
  103. char szDisp[128];
  104. PREGITEM pItem;
  105. LVITEM lvi;
  106. pszAppAlloc = (char*)HeapAlloc(GetProcessHeap(), 0, lstrlen(pszApp) + 1);
  107. if (pszAppAlloc == NULL) {
  108. LogMsg("AddApp: error trying to allocate %d bytes\n", lstrlen(pszApp) + 1);
  109. return;
  110. }
  111. lstrcpy(pszAppAlloc, pszApp);
  112. pszShimAlloc = (char*)HeapAlloc(GetProcessHeap(), 0, lstrlen(pszShim) + 1);
  113. if (pszShimAlloc == NULL) {
  114. HeapFree(GetProcessHeap(), 0, pszAppAlloc);
  115. LogMsg("AddApp: error trying to allocate %d bytes\n", lstrlen(pszShim) + 1);
  116. return;
  117. }
  118. lstrcpy(pszShimAlloc, pszShim);
  119. pszDataAlloc = (char*)HeapAlloc(GetProcessHeap(), 0, lstrlen(pszData) + 1);
  120. if (pszDataAlloc == NULL) {
  121. HeapFree(GetProcessHeap(), 0, pszAppAlloc);
  122. HeapFree(GetProcessHeap(), 0, pszShimAlloc);
  123. LogMsg("AddApp: error trying to allocate %d bytes\n", lstrlen(pszData) + 1);
  124. return;
  125. }
  126. lstrcpy(pszDataAlloc, pszData);
  127. pItem = (PREGITEM)HeapAlloc(GetProcessHeap(), 0, sizeof(REGITEM));
  128. if (pItem == NULL) {
  129. HeapFree(GetProcessHeap(), 0, pszAppAlloc);
  130. HeapFree(GetProcessHeap(), 0, pszShimAlloc);
  131. HeapFree(GetProcessHeap(), 0, pszDataAlloc);
  132. LogMsg("AddApp: error trying to allocate %d bytes\n", sizeof(REGITEM));
  133. return;
  134. }
  135. wsprintf(szDisp, "%s (%s)",pszAppAlloc ,pszShimAlloc);
  136. pItem->pszApp = pszAppAlloc;
  137. pItem->pszShim = pszShimAlloc;
  138. pItem->pszAttr = pszDataAlloc;
  139. pItem->bEnabled = bEnabled;
  140. pItem->change = CHANGE_NOCHANGE;
  141. pItem->bShim = bShim;
  142. // Initialize LVITEM members that are common to all items.
  143. lvi.mask = LVIF_TEXT | LVIF_PARAM;
  144. lvi.pszText = szDisp;
  145. lvi.iItem = g_nItems;
  146. lvi.iSubItem = 0;
  147. lvi.lParam = (LPARAM)pItem;
  148. pItem->nItem = ListView_InsertItem(g_hwndList, &lvi);
  149. lvi.mask = LVIF_TEXT;
  150. lvi.iItem = g_nItems++;
  151. lvi.iSubItem = COLUMN_STATUS;
  152. if (bShim) {
  153. lvi.pszText = (bEnabled ? "enabled" : "DISABLED");
  154. } else {
  155. lvi.pszText = "";
  156. }
  157. ListView_SetItem(g_hwndList, &lvi);
  158. }
  159. /*********************************************************************
  160. * InsertColumnIntoListView
  161. *
  162. *********************************************************************/
  163. VOID
  164. InsertColumnIntoListView(
  165. LPSTR lpszColumn,
  166. DWORD dwSubItem,
  167. DWORD widthPercent)
  168. {
  169. LVCOLUMN lvc;
  170. RECT rcClient;
  171. DWORD width;
  172. GetWindowRect(g_hwndList, &rcClient);
  173. width = rcClient.right - rcClient.left -
  174. 4 * GetSystemMetrics(SM_CXBORDER) -
  175. GetSystemMetrics(SM_CXVSCROLL);
  176. width = width * widthPercent / 100;
  177. lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
  178. lvc.fmt = LVCFMT_LEFT;
  179. lvc.iSubItem = dwSubItem;
  180. lvc.cx = width;
  181. lvc.pszText = lpszColumn;
  182. ListView_InsertColumn(g_hwndList, dwSubItem, &lvc);
  183. }
  184. /*********************************************************************
  185. * DoInitDialog
  186. *
  187. *********************************************************************/
  188. VOID
  189. DoInitDialog(
  190. HWND hdlg)
  191. {
  192. g_hDlg = hdlg;
  193. CenterWindow(hdlg);
  194. g_hFont = CreateFont(15,
  195. 0, 0, 0, FW_EXTRALIGHT, 0, 0, 0, 0, 0,
  196. 0, 0, 0, (LPSTR)"Courier New");
  197. g_hwndList = GetDlgItem(hdlg, IDC_LIST);
  198. g_nItems = 0;
  199. SendDlgItemMessage(hdlg, IDC_ATTR_USED, WM_SETFONT, (WPARAM)g_hFont, 0);
  200. SetDlgItemText(hdlg,
  201. IDC_ATTR_USED,
  202. "Select a shim to see what attributes are used to identify the application");
  203. InsertColumnIntoListView("Application", COLUMN_APP, 60);
  204. InsertColumnIntoListView("Status", COLUMN_STATUS, 20);
  205. InsertColumnIntoListView("Change", COLUMN_CHANGE, 20);
  206. g_bEnable = TRUE;
  207. g_bDelete = TRUE;
  208. EnumShimmedApps_Win2000(AddShimToList, FALSE);
  209. }
  210. /*********************************************************************
  211. * DoDeleteListItem
  212. *
  213. *********************************************************************/
  214. VOID
  215. DoDeleteListItem(
  216. LPARAM lParam)
  217. {
  218. LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
  219. if (pnmv->iSubItem == 0) {
  220. PREGITEM pItem = (PREGITEM)pnmv->lParam;
  221. HeapFree(GetProcessHeap(), 0, pItem->pszApp);
  222. HeapFree(GetProcessHeap(), 0, pItem->pszAttr);
  223. if (pItem->pszShim != NULL) {
  224. HeapFree(GetProcessHeap(), 0, pItem->pszShim);
  225. }
  226. pItem->pszApp = NULL;
  227. pItem->pszAttr = NULL;
  228. pItem->pszShim = NULL;
  229. HeapFree(GetProcessHeap(), 0, pItem);
  230. }
  231. }
  232. /*********************************************************************
  233. * DoSelectionChanged
  234. *
  235. *********************************************************************/
  236. VOID
  237. DoSelectionChanged(
  238. HWND hdlg,
  239. LPARAM lParam)
  240. {
  241. LVITEM lvi;
  242. PREGITEM pItem;
  243. int nSel = ListView_GetSelectionMark(g_hwndList);
  244. if (nSel == -1)
  245. return;
  246. lvi.iItem = nSel;
  247. lvi.iSubItem = 0;
  248. lvi.mask = LVIF_PARAM;
  249. ListView_GetItem(g_hwndList, &lvi);
  250. pItem = (PREGITEM)lvi.lParam;
  251. SetDlgItemText(hdlg, IDC_ATTR_USED, pItem->pszAttr);
  252. if (!pItem->bShim) {
  253. EnableWindow(GetDlgItem(hdlg, IDC_ENABLE), FALSE);
  254. EnableWindow(GetDlgItem(hdlg, IDC_DELETE), FALSE);
  255. } else {
  256. EnableWindow(GetDlgItem(hdlg, IDC_ENABLE), TRUE);
  257. EnableWindow(GetDlgItem(hdlg, IDC_DELETE), TRUE);
  258. if (pItem->bEnabled) {
  259. switch (pItem->change) {
  260. case CHANGE_NOCHANGE:
  261. SetDlgItemText(hdlg, IDC_ENABLE, "&Disable");
  262. SetDlgItemText(hdlg, IDC_DELETE, "Dele&te");
  263. g_bEnable = FALSE;
  264. g_bDelete = TRUE;
  265. break;
  266. case CHANGE_DISABLE:
  267. SetDlgItemText(hdlg, IDC_ENABLE, "&Enable");
  268. SetDlgItemText(hdlg, IDC_DELETE, "Dele&te");
  269. g_bEnable = TRUE;
  270. g_bDelete = TRUE;
  271. break;
  272. case CHANGE_DELETE:
  273. SetDlgItemText(hdlg, IDC_ENABLE, "&Disable");
  274. SetDlgItemText(hdlg, IDC_DELETE, "Undo Dele&te");
  275. g_bEnable = FALSE;
  276. g_bDelete = FALSE;
  277. break;
  278. }
  279. } else {
  280. switch (pItem->change) {
  281. case CHANGE_NOCHANGE:
  282. SetDlgItemText(hdlg, IDC_ENABLE, "&Enable");
  283. SetDlgItemText(hdlg, IDC_DELETE, "Dele&te");
  284. g_bEnable = TRUE;
  285. g_bDelete = TRUE;
  286. break;
  287. case CHANGE_ENABLE:
  288. SetDlgItemText(hdlg, IDC_ENABLE, "&Disable");
  289. SetDlgItemText(hdlg, IDC_DELETE, "Dele&te");
  290. g_bEnable = FALSE;
  291. g_bDelete = TRUE;
  292. break;
  293. case CHANGE_DELETE:
  294. SetDlgItemText(hdlg, IDC_ENABLE, "&Enable");
  295. SetDlgItemText(hdlg, IDC_DELETE, "Undo Dele&te");
  296. g_bEnable = TRUE;
  297. g_bDelete = FALSE;
  298. break;
  299. }
  300. }
  301. }
  302. }
  303. /*********************************************************************
  304. * OnEnable
  305. *
  306. *********************************************************************/
  307. VOID
  308. OnEnable(
  309. HWND hdlg)
  310. {
  311. PREGITEM pItem;
  312. int nSel = ListView_GetSelectionMark(g_hwndList);
  313. LVITEM lvi;
  314. lvi.iItem = nSel;
  315. lvi.iSubItem = COLUMN_APP;
  316. lvi.mask = LVIF_PARAM;
  317. ListView_GetItem(g_hwndList, &lvi);
  318. pItem = (PREGITEM)lvi.lParam;
  319. lvi.mask = LVIF_TEXT;
  320. lvi.iItem = nSel;
  321. lvi.iSubItem = COLUMN_CHANGE;
  322. if (g_bEnable) {
  323. lvi.pszText = (pItem->bEnabled ? "" : "enable");
  324. pItem->change = (pItem->bEnabled ? CHANGE_NOCHANGE : CHANGE_ENABLE);
  325. SetDlgItemText(hdlg, IDC_ENABLE, "&Disable");
  326. } else {
  327. lvi.pszText = (pItem->bEnabled ? "disable" : "");
  328. pItem->change = (pItem->bEnabled ? CHANGE_DISABLE : CHANGE_NOCHANGE);
  329. SetDlgItemText(hdlg, IDC_ENABLE, "&Enable");
  330. }
  331. SetDlgItemText(hdlg, IDC_DELETE, "Dele&te");
  332. g_bDelete = TRUE;
  333. g_bEnable = !g_bEnable;
  334. ListView_SetItem(g_hwndList, &lvi);
  335. }
  336. /*********************************************************************
  337. * OnDelete
  338. *
  339. *********************************************************************/
  340. VOID
  341. OnDelete(
  342. HWND hdlg)
  343. {
  344. PREGITEM pItem;
  345. LVITEM lvi;
  346. int nSel = ListView_GetSelectionMark(g_hwndList);
  347. lvi.iItem = nSel;
  348. lvi.iSubItem = COLUMN_APP;
  349. lvi.mask = LVIF_PARAM;
  350. ListView_GetItem(g_hwndList, &lvi);
  351. pItem = (PREGITEM)lvi.lParam;
  352. lvi.mask = LVIF_TEXT;
  353. lvi.iItem = nSel;
  354. lvi.iSubItem = COLUMN_CHANGE;
  355. if (g_bDelete) {
  356. SetDlgItemText(hdlg, IDC_DELETE, "Undo Dele&te");
  357. lvi.pszText = "delete";
  358. pItem->change = CHANGE_DELETE;
  359. } else {
  360. SetDlgItemText(hdlg, IDC_DELETE, "Dele&te");
  361. lvi.pszText = "";
  362. pItem->change = CHANGE_NOCHANGE;
  363. }
  364. if (pItem->bEnabled) {
  365. SetDlgItemText(hdlg, IDC_ENABLE, "&Disable");
  366. }
  367. g_bDelete = !g_bDelete;
  368. ListView_SetItem(g_hwndList, &lvi);
  369. }
  370. /*********************************************************************
  371. * OnShowOnlyShims
  372. *
  373. *********************************************************************/
  374. VOID
  375. OnShowOnlyShims(
  376. HWND hdlg)
  377. {
  378. BOOL bOnlyShims;
  379. bOnlyShims = (SendDlgItemMessage(hdlg,
  380. IDC_ONLY_SHIMS,
  381. BM_GETCHECK,
  382. 0,
  383. 0) == BST_CHECKED);
  384. SendMessage(g_hwndList, WM_SETREDRAW, FALSE, 0);
  385. g_nItems = 0;
  386. ListView_DeleteAllItems(g_hwndList);
  387. g_bEnable = TRUE;
  388. g_bDelete = TRUE;
  389. EnumShimmedApps_Win2000(AddShimToList, bOnlyShims);
  390. SendMessage(g_hwndList, WM_SETREDRAW, TRUE, 0);
  391. }
  392. /*********************************************************************
  393. * OnApply
  394. *
  395. *********************************************************************/
  396. VOID
  397. OnApply(
  398. HWND hdlg)
  399. {
  400. LVITEM lvi;
  401. PREGITEM pItem;
  402. int i;
  403. lvi.iSubItem = COLUMN_APP;
  404. lvi.mask = LVIF_PARAM;
  405. for (i = 0; i < g_nItems; i++) {
  406. lvi.iItem = i;
  407. ListView_GetItem(g_hwndList, &lvi);
  408. pItem = (PREGITEM)lvi.lParam;
  409. if (pItem->change == CHANGE_NOCHANGE)
  410. continue;
  411. switch (pItem->change) {
  412. case CHANGE_ENABLE:
  413. EnableShim_Win2000(pItem->pszApp, pItem->pszShim);
  414. break;
  415. case CHANGE_DISABLE:
  416. DisableShim_Win2000(pItem->pszApp, pItem->pszShim);
  417. break;
  418. case CHANGE_DELETE:
  419. DeleteShim_Win2000(pItem->pszApp, pItem->pszShim);
  420. break;
  421. }
  422. }
  423. SetDlgItemText(hdlg, IDC_DELETE, "Dele&te");
  424. SetDlgItemText(hdlg, IDC_ENABLE, "&Enable");
  425. OnShowOnlyShims(hdlg);
  426. }
  427. /*********************************************************************
  428. * OnPrint
  429. *
  430. *********************************************************************/
  431. char g_szDisplay[1024 * 1024];
  432. VOID
  433. OnDisplayAll(
  434. HWND hdlg)
  435. {
  436. LVITEM lvi;
  437. PREGITEM pItem;
  438. char* pszDisplay = g_szDisplay;
  439. int i;
  440. lvi.iSubItem = COLUMN_APP;
  441. lvi.mask = LVIF_PARAM;
  442. for (i = 0; i < g_nItems; i++) {
  443. lvi.iItem = i;
  444. ListView_GetItem(g_hwndList, &lvi);
  445. pItem = (PREGITEM)lvi.lParam;
  446. lstrcpy(pszDisplay, pItem->pszAttr);
  447. lstrcat(pszDisplay, "\r\n");
  448. pszDisplay += lstrlen(pszDisplay);
  449. }
  450. SetDlgItemText(hdlg, IDC_ATTR_USED, g_szDisplay);
  451. }
  452. /*********************************************************************
  453. * BrowseAppCompatDlgProc
  454. *
  455. *********************************************************************/
  456. INT_PTR CALLBACK
  457. BrowseAppCompatDlgProc(
  458. HWND hdlg,
  459. UINT uMsg,
  460. WPARAM wParam,
  461. LPARAM lParam)
  462. {
  463. int wCode = LOWORD(wParam);
  464. int wNotifyCode = HIWORD(wParam);
  465. switch (uMsg) {
  466. case WM_INITDIALOG:
  467. DoInitDialog(hdlg);
  468. break;
  469. case WM_NOTIFY:
  470. if (wParam == IDC_LIST) {
  471. LPNMHDR pnm = (LPNMHDR)lParam;
  472. switch (pnm->code) {
  473. case LVN_DELETEITEM:
  474. DoDeleteListItem(lParam);
  475. break;
  476. case LVN_ITEMCHANGED:
  477. case NM_CLICK:
  478. DoSelectionChanged(hdlg, lParam);
  479. break;
  480. default:
  481. break;
  482. }
  483. }
  484. break;
  485. case WM_COMMAND:
  486. switch (wCode) {
  487. case IDC_ENABLE:
  488. OnEnable(hdlg);
  489. break;
  490. case IDC_DELETE:
  491. OnDelete(hdlg);
  492. break;
  493. case IDC_APPLY:
  494. OnApply(hdlg);
  495. break;
  496. case IDC_ONLY_SHIMS:
  497. OnShowOnlyShims(hdlg);
  498. break;
  499. case IDC_DISPLAY_ALL:
  500. OnDisplayAll(hdlg);
  501. break;
  502. case IDCANCEL:
  503. EndDialog(hdlg, TRUE);
  504. break;
  505. default:
  506. return FALSE;
  507. }
  508. break;
  509. default:
  510. return FALSE;
  511. }
  512. return TRUE;
  513. }
  514. int APIENTRY WinMain(HINSTANCE hInstance,
  515. HINSTANCE hPrevInstance,
  516. LPSTR lpCmdLine,
  517. int nCmdShow)
  518. {
  519. InitCommonControls();
  520. g_hInstance = hInstance;
  521. DialogBox(hInstance,
  522. MAKEINTRESOURCE(IDD_DIALOG),
  523. GetDesktopWindow(),
  524. BrowseAppCompatDlgProc);
  525. return 0;
  526. }