|
|
#include "acBrowser.h"
#include "resource.h"
#include <commctrl.h>
#include <commdlg.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
extern PDBENTRY g_pEntries;
#define SHOW_W_SHIMS 0x00000001
#define SHOW_W_FLAGS 0x00000002
#define SHOW_W_LAYERS 0x00000004
#define SHOW_W_PATCHES 0x00000008
#define SHOW_W_APPHELP 0x00000010
#define SHOW_WO_SHIMS 0x00000100
#define SHOW_WO_FLAGS 0x00000200
#define SHOW_WO_LAYERS 0x00000400
#define SHOW_WO_PATCHES 0x00000800
#define SHOW_WO_APPHELP 0x00001000
//
// These flags cannot occur simultaneously.
//
#define SHOW_MORETHAN5 0x00010000
#define SHOW_NOMATCHING 0x00020000
#define SHOW_DISABLED_ONLY 0x80000000
#define ID_SHOW_CONTENT 1234
//
// Global Variables
//
HINSTANCE g_hInstance; HWND g_hDlg;
HWND g_hwndList;
HWND g_hwndEntryTree;
int g_nItems;
BOOL g_bSortAppAsc; BOOL g_bSortExeAsc;
PDBENTRY g_pSelEntry;
char g_szBinary[MAX_PATH];
DWORD g_dwCrtShowFlags = 0xFFFFFFFF;
#define COLUMN_APP 0
#define COLUMN_EXE 1
char* g_szSeverity[] = { "NONE", "NOBLOCK", "HARDBLOCK", "MINORPROBLEM", "REINSTALL", "VERSIONSUB", "SHIM"};
#define IDQ_ALL 0
#define IDQ_MORETHAN5 1
#define IDQ_NOMATCHING 2
char* g_aszQueries[] = { "All entries", "Entries with more than 5 extra matching files", "Entries with no extra matching files", "" };
void LogMsg( LPSTR pszFmt, ... ) { CHAR gszT[1024]; va_list arglist;
va_start(arglist, pszFmt); _vsnprintf(gszT, 1023, pszFmt, arglist); gszT[1023] = 0; va_end(arglist); OutputDebugString(gszT); }
/*******************************************************************************
* CenterWindow * * This function must be called at the WM_INIDIALOG in order to * move the dialog window centered in the client area of the * parent or owner window. *******************************************************************************/ BOOL CenterWindow( HWND hWnd) { RECT rectWindow, rectParent, rectScreen; int nCX, nCY; HWND hParent; POINT ptPoint;
hParent = GetParent(hWnd); if (hParent == NULL) hParent = GetDesktopWindow();
GetWindowRect(hParent, (LPRECT)&rectParent); GetWindowRect(hWnd, (LPRECT)&rectWindow); GetWindowRect(GetDesktopWindow(), (LPRECT)&rectScreen);
nCX = rectWindow.right - rectWindow.left; nCY = rectWindow.bottom - rectWindow.top;
ptPoint.x = ((rectParent.right + rectParent.left) / 2) - (nCX / 2); ptPoint.y = ((rectParent.bottom + rectParent.top ) / 2) - (nCY / 2);
if (ptPoint.x < rectScreen.left) ptPoint.x = rectScreen.left; if (ptPoint.x > rectScreen.right - nCX) ptPoint.x = rectScreen.right - nCX; if (ptPoint.y < rectScreen.top) ptPoint.y = rectScreen.top; if (ptPoint.y > rectScreen.bottom - nCY) ptPoint.y = rectScreen.bottom - nCY;
if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) ScreenToClient(hParent, (LPPOINT)&ptPoint);
if (!MoveWindow(hWnd, ptPoint.x, ptPoint.y, nCX, nCY, TRUE)) return FALSE;
return TRUE; }
void AddEntryToList( PDBENTRY pEntry ) { LVITEM lvi; lvi.mask = LVIF_TEXT | LVIF_PARAM; lvi.pszText = pEntry->pszAppName; lvi.iItem = g_nItems; lvi.iSubItem = COLUMN_APP; lvi.lParam = (LPARAM)pEntry;
ListView_InsertItem(g_hwndList, &lvi); ListView_SetItemText(g_hwndList, g_nItems, COLUMN_EXE, pEntry->pszExeName); g_nItems++; }
void InsertColumnIntoListView( LPSTR lpszColumn, DWORD dwSubItem, DWORD widthPercent ) { LVCOLUMN lvc; RECT rcClient; DWORD width;
GetWindowRect(g_hwndList, &rcClient); width = rcClient.right - rcClient.left - 4 * GetSystemMetrics(SM_CXBORDER) - GetSystemMetrics(SM_CXVSCROLL); width = width * widthPercent / 100; lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; lvc.fmt = LVCFMT_LEFT; lvc.iSubItem = dwSubItem; lvc.cx = width; lvc.pszText = lpszColumn; ListView_InsertColumn(g_hwndList, dwSubItem, &lvc); }
void UpdateEntryTreeView( PDBENTRY pEntry ) { HTREEITEM hItemExe; HTREEITEM hMatchItem; HTREEITEM hItemMatchingFiles; PMATCHINGFILE pMatch; PFIXLIST pFixList; TV_INSERTSTRUCT is; char szText[256]; TreeView_DeleteAllItems(g_hwndEntryTree);
wsprintf(szText, "%s - %s", pEntry->pszExeName, pEntry->szGUID); is.hParent = TVI_ROOT; is.hInsertAfter = TVI_LAST; is.item.mask = TVIF_TEXT | TVIF_PARAM; is.item.lParam = 0; is.item.pszText = szText; hItemExe = TreeView_InsertItem(g_hwndEntryTree, &is); if (pEntry->appHelp.bPresent) { wsprintf(szText, "AppHelp - %s", g_szSeverity[pEntry->appHelp.severity]); is.hParent = hItemExe; is.item.pszText = szText;
TreeView_InsertItem(g_hwndEntryTree, &is); } if (pEntry->pFirstShim) { HTREEITEM hItemShims; is.hParent = hItemExe; is.hInsertAfter = TVI_SORT; is.item.lParam = 0; is.item.pszText = "Compatibility Fixes";
hItemShims = TreeView_InsertItem(g_hwndEntryTree, &is); is.hParent = hItemShims; pFixList = pEntry->pFirstShim;
while (pFixList) { is.item.lParam = (LPARAM)pFixList->pFix->pszDescription; is.item.pszText = pFixList->pFix->pszName; TreeView_InsertItem(g_hwndEntryTree, &is);
pFixList = pFixList->pNext; } TreeView_Expand(g_hwndEntryTree, hItemShims, TVE_EXPAND); } if (pEntry->pFirstPatch) { HTREEITEM hItemPatches; is.hParent = hItemExe; is.hInsertAfter = TVI_SORT; is.item.lParam = 0; is.item.pszText = "Compatibility Patches";
hItemPatches = TreeView_InsertItem(g_hwndEntryTree, &is); is.hParent = hItemPatches; pFixList = pEntry->pFirstPatch;
while (pFixList) { is.item.lParam = (LPARAM)pFixList->pFix->pszDescription; is.item.pszText = pFixList->pFix->pszName; TreeView_InsertItem(g_hwndEntryTree, &is);
pFixList = pFixList->pNext; } TreeView_Expand(g_hwndEntryTree, hItemPatches, TVE_EXPAND); } if (pEntry->pFirstFlag) { HTREEITEM hItemFlags; is.hParent = hItemExe; is.hInsertAfter = TVI_SORT; is.item.lParam = 0; is.item.pszText = "Compatibility Flags";
hItemFlags = TreeView_InsertItem(g_hwndEntryTree, &is); is.hParent = hItemFlags; pFixList = pEntry->pFirstFlag;
while (pFixList) { is.item.lParam = (LPARAM)pFixList->pFix->pszDescription; is.item.pszText = pFixList->pFix->pszName; TreeView_InsertItem(g_hwndEntryTree, &is);
pFixList = pFixList->pNext; } TreeView_Expand(g_hwndEntryTree, hItemFlags, TVE_EXPAND); } if (pEntry->pFirstLayer) { HTREEITEM hItemLayers; is.hParent = hItemExe; is.hInsertAfter = TVI_SORT; is.item.lParam = 0; is.item.pszText = "Compatibility Layers";
hItemLayers = TreeView_InsertItem(g_hwndEntryTree, &is); is.hParent = hItemLayers; pFixList = pEntry->pFirstLayer;
while (pFixList) { is.item.lParam = (LPARAM)pFixList->pFix->pszDescription; is.item.pszText = pFixList->pFix->pszName; TreeView_InsertItem(g_hwndEntryTree, &is);
pFixList = pFixList->pNext; } TreeView_Expand(g_hwndEntryTree, hItemLayers, TVE_EXPAND); }
pMatch = pEntry->pFirstMatchingFile;
is.hParent = hItemExe; is.item.lParam = 0; is.item.pszText = "Matching Files";
hItemMatchingFiles = TreeView_InsertItem(g_hwndEntryTree, &is); while (pMatch) { PATTRIBUTE pAttr; is.hInsertAfter = TVI_SORT; is.hParent = hItemMatchingFiles; is.item.pszText = pMatch->pszName;
hMatchItem = TreeView_InsertItem(g_hwndEntryTree, &is);
pAttr = pMatch->pFirstAttribute;
while (pAttr) { is.hParent = hMatchItem; is.hInsertAfter = TVI_SORT; is.item.pszText = pAttr->pszText;
TreeView_InsertItem(g_hwndEntryTree, &is); pAttr = pAttr->pNext; }
pMatch = pMatch->pNext; }
TreeView_Expand(g_hwndEntryTree, hItemMatchingFiles, TVE_EXPAND);
TreeView_Expand(g_hwndEntryTree, hItemExe, TVE_EXPAND); }
void AppSelectedChanged( HWND hdlg, int nSel ) { LVITEM lvi; PDBENTRY pEntry;
if (nSel == -1) return;
lvi.iItem = nSel; lvi.iSubItem = 0; lvi.mask = LVIF_PARAM;
ListView_GetItem(g_hwndList, &lvi);
pEntry = (PDBENTRY)lvi.lParam;
g_pSelEntry = pEntry;
//
// Update the entry tree view
//
UpdateEntryTreeView(pEntry); SendDlgItemMessage(hdlg, IDC_PER_USER, BM_SETCHECK, (pEntry->bDisablePerUser ? BST_CHECKED : BST_UNCHECKED), 0);
SendDlgItemMessage(hdlg, IDC_PER_MACHINE, BM_SETCHECK, (pEntry->bDisablePerMachine ? BST_CHECKED : BST_UNCHECKED), 0); }
int CALLBACK CompareItems( LPARAM lParam1, LPARAM lParam2, LPARAM column) { PDBENTRY pItem1 = (PDBENTRY)lParam1; PDBENTRY pItem2 = (PDBENTRY)lParam2; int nVal = 0;
if (column == COLUMN_APP) { if (g_bSortAppAsc) { nVal = lstrcmpi(pItem1->pszAppName, pItem2->pszAppName); } else { nVal = lstrcmpi(pItem2->pszAppName, pItem1->pszAppName); } }
if (column == COLUMN_EXE) { if (g_bSortExeAsc) { nVal = lstrcmpi(pItem1->pszExeName, pItem2->pszExeName); } else { nVal = lstrcmpi(pItem2->pszExeName, pItem1->pszExeName); } } return nVal; } void ShowFixes( HWND hdlg, DWORD dwShowFlags ) { PDBENTRY pEntry; char szEntries[128]; BOOL bDontShow; if (dwShowFlags == g_dwCrtShowFlags) { return; } g_nItems = 0;
SendMessage(g_hwndList, WM_SETREDRAW, FALSE, 0); ListView_DeleteAllItems(g_hwndList); pEntry = g_pEntries;
while (pEntry != NULL) { bDontShow = (pEntry->pFirstShim == NULL && (dwShowFlags & SHOW_W_SHIMS) || pEntry->appHelp.bPresent == FALSE && (dwShowFlags & SHOW_W_APPHELP) || pEntry->pFirstFlag == NULL && (dwShowFlags & SHOW_W_FLAGS) || pEntry->pFirstPatch == NULL && (dwShowFlags & SHOW_W_PATCHES) || pEntry->pFirstLayer == NULL && (dwShowFlags & SHOW_W_LAYERS));
bDontShow = bDontShow || (pEntry->pFirstShim && (dwShowFlags & SHOW_WO_SHIMS) || pEntry->appHelp.bPresent && (dwShowFlags & SHOW_WO_APPHELP) || pEntry->pFirstFlag && (dwShowFlags & SHOW_WO_FLAGS) || pEntry->pFirstPatch && (dwShowFlags & SHOW_WO_PATCHES) || pEntry->pFirstLayer && (dwShowFlags & SHOW_WO_LAYERS)); if ((dwShowFlags & SHOW_DISABLED_ONLY) && !pEntry->bDisablePerMachine && !pEntry->bDisablePerUser) {
bDontShow = TRUE; }
if (dwShowFlags & SHOW_MORETHAN5) { if (pEntry->nMatchingFiles < 6) { bDontShow = TRUE; } } if (dwShowFlags & SHOW_NOMATCHING) { if (pEntry->nMatchingFiles > 1) { bDontShow = TRUE; } } if (!bDontShow) { AddEntryToList(pEntry); }
pEntry = pEntry->pNext; } ListView_SortItems(g_hwndList, CompareItems, COLUMN_APP); wsprintf(szEntries, "%d entries. Use the headers to sort them.", g_nItems); SetDlgItemText(hdlg, IDC_ALL_ENTRIES, szEntries); SendMessage(g_hwndList, WM_SETREDRAW, TRUE, 0);
g_dwCrtShowFlags = dwShowFlags; }
void DoInitDialog( HWND hdlg ) { HICON hIcon; int i; g_hDlg = hdlg;
CenterWindow(hdlg);
g_hwndList = GetDlgItem(hdlg, IDC_LIST); ListView_SetExtendedListViewStyle(g_hwndList, 0x20);
g_hwndEntryTree = GetDlgItem(hdlg, IDC_ENTRY); g_nItems = 0;
InsertColumnIntoListView("Application", COLUMN_APP, 60); InsertColumnIntoListView("Main Binary", COLUMN_EXE, 40); g_bSortAppAsc = TRUE; g_bSortExeAsc = FALSE;
//
// Show the app icon.
//
hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_APPICON));
SetClassLongPtr(hdlg, GCLP_HICON, (LONG_PTR)hIcon); SendDlgItemMessage(hdlg, IDC_DC_APPHELP, BM_SETCHECK, BST_CHECKED, 0); SendDlgItemMessage(hdlg, IDC_DC_SHIMS, BM_SETCHECK, BST_CHECKED, 0); SendDlgItemMessage(hdlg, IDC_DC_FLAGS, BM_SETCHECK, BST_CHECKED, 0); SendDlgItemMessage(hdlg, IDC_DC_PATCHES, BM_SETCHECK, BST_CHECKED, 0); SendDlgItemMessage(hdlg, IDC_DC_LAYERS, BM_SETCHECK, BST_CHECKED, 0);
//
// Populate the statistics queries
//
for (i = 0; *g_aszQueries[i] != 0; i++) { SendDlgItemMessage(hdlg, IDC_STATISTICS, CB_ADDSTRING, 0, (LPARAM)g_aszQueries[i]); } SetCursor(NULL); SetTimer(hdlg, ID_SHOW_CONTENT, 100, NULL); }
void FilterAndShow( HWND hdlg ) { DWORD dwShowFlags = 0;
if (SendDlgItemMessage(hdlg, IDC_W_APPHELP, BM_GETCHECK, 0, 0) == BST_CHECKED) { dwShowFlags |= SHOW_W_APPHELP; } else if (SendDlgItemMessage(hdlg, IDC_WO_APPHELP, BM_GETCHECK, 0, 0) == BST_CHECKED) { dwShowFlags |= SHOW_WO_APPHELP; }
if (SendDlgItemMessage(hdlg, IDC_W_SHIMS, BM_GETCHECK, 0, 0) == BST_CHECKED) { dwShowFlags |= SHOW_W_SHIMS; } else if (SendDlgItemMessage(hdlg, IDC_WO_SHIMS, BM_GETCHECK, 0, 0) == BST_CHECKED) { dwShowFlags |= SHOW_WO_SHIMS; }
if (SendDlgItemMessage(hdlg, IDC_W_PATCHES, BM_GETCHECK, 0, 0) == BST_CHECKED) { dwShowFlags |= SHOW_W_PATCHES; } else if (SendDlgItemMessage(hdlg, IDC_WO_PATCHES, BM_GETCHECK, 0, 0) == BST_CHECKED) { dwShowFlags |= SHOW_WO_PATCHES; }
if (SendDlgItemMessage(hdlg, IDC_W_FLAGS, BM_GETCHECK, 0, 0) == BST_CHECKED) { dwShowFlags |= SHOW_W_FLAGS; } else if (SendDlgItemMessage(hdlg, IDC_WO_FLAGS, BM_GETCHECK, 0, 0) == BST_CHECKED) { dwShowFlags |= SHOW_WO_FLAGS; }
if (SendDlgItemMessage(hdlg, IDC_W_LAYERS, BM_GETCHECK, 0, 0) == BST_CHECKED) { dwShowFlags |= SHOW_W_LAYERS; } else if (SendDlgItemMessage(hdlg, IDC_WO_LAYERS, BM_GETCHECK, 0, 0) == BST_CHECKED) { dwShowFlags |= SHOW_WO_LAYERS; }
if (SendDlgItemMessage(hdlg, IDC_DISABLED_ONLY, BM_GETCHECK, 0, 0) == BST_CHECKED) { dwShowFlags |= SHOW_DISABLED_ONLY; }
SendDlgItemMessage(hdlg, IDC_PER_USER, BM_SETCHECK, BST_UNCHECKED, 0); SendDlgItemMessage(hdlg, IDC_PER_MACHINE, BM_SETCHECK, BST_UNCHECKED, 0); ShowFixes(hdlg, dwShowFlags); TreeView_DeleteAllItems(g_hwndEntryTree); }
void OnSubmitChanges( HWND hdlg ) { BOOL bPerUser, bPerMachine; if (g_pSelEntry == NULL) { return; }
bPerUser = (SendDlgItemMessage(hdlg, IDC_PER_USER, BM_GETCHECK, 0, 0) == BST_CHECKED); bPerMachine = (SendDlgItemMessage(hdlg, IDC_PER_MACHINE, BM_GETCHECK, 0, 0) == BST_CHECKED);
UpdateFixStatus(g_pSelEntry->szGUID, bPerUser, bPerMachine);
g_pSelEntry->bDisablePerUser = bPerUser; g_pSelEntry->bDisablePerMachine = bPerMachine; }
INT_PTR CALLBACK BrowseAppCompatDlgProc( HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { int wCode = LOWORD(wParam); int wNotifyCode = HIWORD(wParam);
switch (uMsg) { case WM_INITDIALOG: DoInitDialog(hdlg); break;
case WM_TIMER: if (wParam == ID_SHOW_CONTENT) { KillTimer(hdlg, ID_SHOW_CONTENT); //
// Read the database
//
GetDatabaseEntries();
ShowFixes(hdlg, 0); SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW))); } break;
case WM_NOTIFY: if (wParam == IDC_LIST) { LPNMHDR pnm = (LPNMHDR)lParam;
switch (pnm->code) { case LVN_COLUMNCLICK: { LPNMLISTVIEW pnmlv = (LPNMLISTVIEW)lParam;
if (pnmlv->iSubItem == COLUMN_APP) { g_bSortAppAsc = !g_bSortAppAsc; }
if (pnmlv->iSubItem == COLUMN_EXE) { g_bSortExeAsc = !g_bSortExeAsc; } ListView_SortItems(g_hwndList, CompareItems, pnmlv->iSubItem); break; } case LVN_ITEMCHANGED: { int nSel = ListView_GetSelectionMark(g_hwndList); AppSelectedChanged(hdlg, nSel); break; }
case NM_CLICK: { LVHITTESTINFO ht; int nSel;
GetCursorPos(&ht.pt); ScreenToClient(g_hwndList, &ht.pt);
nSel = ListView_SubItemHitTest(g_hwndList, &ht); if (nSel != -1) { ListView_SetItemState(g_hwndList, nSel, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); } AppSelectedChanged(hdlg, nSel); break; } default: break; } } else if (wParam == IDC_ENTRY) { LPNMHDR pnm = (LPNMHDR)lParam;
switch (pnm->code) { case TVN_GETINFOTIP: { LPNMTVGETINFOTIP lpGetInfoTip = (LPNMTVGETINFOTIP)lParam;
if (lpGetInfoTip->lParam != 0) { lstrcpy(lpGetInfoTip->pszText, (char*)lpGetInfoTip->lParam); }
break; } } } break;
case WM_COMMAND: if (wNotifyCode == CBN_SELCHANGE) { int nSel;
nSel = (int)SendDlgItemMessage(hdlg, IDC_STATISTICS, CB_GETCURSEL, 0, 0);
switch (nSel) { case IDQ_ALL: ShowFixes(hdlg, (g_dwCrtShowFlags & ~(SHOW_MORETHAN5 | SHOW_NOMATCHING))); break; case IDQ_MORETHAN5: ShowFixes(hdlg, ((g_dwCrtShowFlags | SHOW_MORETHAN5) & ~SHOW_NOMATCHING)); break; case IDQ_NOMATCHING: ShowFixes(hdlg, ((g_dwCrtShowFlags | SHOW_NOMATCHING) & ~SHOW_MORETHAN5)); break; } } switch (wCode) { case IDC_PER_USER: case IDC_PER_MACHINE: OnSubmitChanges(hdlg); break; case IDC_W_APPHELP: case IDC_W_SHIMS: case IDC_W_FLAGS: case IDC_W_LAYERS: case IDC_W_PATCHES: case IDC_WO_APPHELP: case IDC_WO_SHIMS: case IDC_WO_FLAGS: case IDC_WO_LAYERS: case IDC_WO_PATCHES: case IDC_DC_APPHELP: case IDC_DC_SHIMS: case IDC_DC_FLAGS: case IDC_DC_LAYERS: case IDC_DC_PATCHES: case IDC_DISABLED_ONLY: FilterAndShow(hdlg); break; case IDCANCEL: EndDialog(hdlg, TRUE); break;
default: return FALSE; } break;
default: return FALSE; }
return TRUE; }
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { InitCommonControls();
g_hInstance = hInstance;
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), GetDesktopWindow(), BrowseAppCompatDlgProc);
return 0; }
|