windows-nt/Source/XPSP1/NT/windows/appcompat/tools/appsearch/shiminfo.cpp
2020-09-26 16:20:57 +08:00

238 lines
6.3 KiB
C++

// AppSearch
//
// Tool for searching a user's hard drives and locating
// applications that can be patched
//
// Author: t-michkr (9 June 2000)
//
// shiminfo.cpp
// Display information on the shims used by an app.
#include <windows.h>
extern "C"
{
#include <shimdb.h>
}
#include <assert.h>
#include <tchar.h>
#include "main.h"
#include "resource.h"
HSDB g_hSDBx;
struct SShimInfo
{
TCHAR* szName;
TCHAR* szDesc;
SShimInfo() : szName(0), szDesc(0) {}
~SShimInfo()
{
if(szName)
delete szName;
if(szDesc)
delete szDesc;
szName = szDesc = 0;
}
};
const int c_nMaxShimList = 16;
static int nNumShims = 0;
static SShimInfo* apShimInfo[c_nMaxShimList];
// Shim dialog proc.
BOOL CALLBACK ShimInfoDialogProc(HWND hwnd, UINT uiMsg, WPARAM wParam,
LPARAM lParam);
// Shim dialog message handlers.
BOOL HandleShimInfoInitDialog(HWND hwnd, TCHAR* szAppPath);
void HandleShimInfoCommand(HWND hwnd, UINT uiCtrl, UINT uiNotify);
// ShowShimInfo
// Display dialog box showing which shims are imported by an app.
void ShowShimInfo(HWND hwnd, TCHAR* szAppPath)
{
if((g_hSDBx = SdbInitDatabase(0, NULL)) == NULL)
return;
DialogBoxParam(g_hinst, MAKEINTRESOURCE(IDD_SHIMINFO), hwnd,
ShimInfoDialogProc, reinterpret_cast<LPARAM>(szAppPath));
for(int i = 0; i < nNumShims; i++)
{
if(apShimInfo[i])
delete apShimInfo[i];
}
nNumShims = 0;
SdbReleaseDatabase(g_hSDBx);
}
// Dialog proc for shim info dialog.
BOOL CALLBACK ShimInfoDialogProc(HWND hwnd, UINT uiMsg, WPARAM wParam,
LPARAM lParam)
{
switch(uiMsg)
{
case WM_INITDIALOG:
return HandleShimInfoInitDialog(hwnd, reinterpret_cast<TCHAR*>(lParam));
break;
case WM_COMMAND:
HandleShimInfoCommand(hwnd, LOWORD(wParam), HIWORD(wParam));
break;
default:
return FALSE;
}
return TRUE;
}
// Init dialog, add all shims used by app.
BOOL HandleShimInfoInitDialog(HWND hwnd, TCHAR* szAppPath)
{
DWORD dwNumExes = 0;
assert(szAppPath);
TCHAR szBuffer[c_nMaxStringLength];
GetWindowText(hwnd, szBuffer, c_nMaxStringLength);
lstrcat(szBuffer, TEXT(" - "));
if(_tcsrchr(szAppPath, TEXT('\\')))
lstrcat(szBuffer, _tcsrchr(szAppPath, TEXT('\\'))+1);
else
lstrcat(szBuffer, szAppPath);
SetWindowText(hwnd, szBuffer);
// Find the EXE in the database
SDBQUERYRESULT sdbQuery;
ZeroMemory(&sdbQuery, sizeof(SDBQUERYRESULT));
SdbGetMatchingExe(g_hSDBx, szAppPath, NULL, NULL, SDBGMEF_IGNORE_ENVIRONMENT, &sdbQuery);
for (dwNumExes = 0; dwNumExes < SDB_MAX_EXES; ++dwNumExes) {
if (sdbQuery.atrExes[dwNumExes] == TAGREF_NULL) {
break;
}
}
if (dwNumExes)
{
//
// for now, just get the info for the last exe in the list, which will
// be the one with specific info for this app.
// BUGBUG -- is this the right thing to do? dmunsil
//
TAGREF trExe = sdbQuery.atrExes[dwNumExes - 1];
// Get all shims used by this app.
TAGREF trShimDLL = SdbFindFirstTagRef(g_hSDBx, trExe, TAG_SHIM_REF);
while(trShimDLL)
{
// Get the name of the shim.
TCHAR szBuffer[c_nMaxStringLength];
TAGREF trName = SdbFindFirstTagRef(g_hSDBx, trShimDLL, TAG_NAME);
if(SdbReadStringTagRef(g_hSDBx, trName, szBuffer, c_nMaxStringLength))
{
SShimInfo* pShim = new SShimInfo;
if(!pShim)
return FALSE;
pShim->szName = new TCHAR[lstrlen(szBuffer)+1];
if(!pShim->szName)
{
delete pShim;
return FALSE;
}
lstrcpy(pShim->szName, szBuffer);
// Have to read description from
// actual DLL entry, not the reference.
TAGREF trRealDLL = SdbGetShimFromShimRef(g_hSDBx, trShimDLL);
if(trRealDLL)
{
TAGREF trDesc = SdbFindFirstTagRef(g_hSDBx, trRealDLL, TAG_DESCRIPTION);
if(SdbReadStringTagRef(g_hSDBx, trDesc, szBuffer, c_nMaxStringLength))
{
pShim->szDesc = new TCHAR[lstrlen(szBuffer)+1];
if(!pShim->szDesc)
{
delete pShim;
return FALSE;
}
lstrcpy(pShim->szDesc, szBuffer);
}
}
// Add the shim to the list
HWND hwList = GetDlgItem(hwnd, IDC_SHIMLIST);
if(hwList)
{
int i = SendMessage(hwList, LB_ADDSTRING, 0,
reinterpret_cast<LPARAM>(pShim->szName));
if(i != LB_ERR)
{
SendMessage(hwList, LB_SETITEMDATA, i, nNumShims);
apShimInfo[nNumShims] = pShim;
nNumShims++;
}
else
delete pShim;
}
}
// Move to next shim.
trShimDLL = SdbFindNextTagRef(g_hSDBx, trExe, trShimDLL);
}
}
return TRUE;
}
// Handle command messages
void HandleShimInfoCommand(HWND hwnd, UINT uiCtrl, UINT uiNotify)
{
HWND hwList, hwDesc;
int iItem, iShim;
switch(uiCtrl)
{
case IDOK:
EndDialog(hwnd, 0);
break;
case IDC_SHIMLIST:
switch(uiNotify)
{
case LBN_SELCHANGE:
// On a sel change, show the new shim description.
hwList = GetDlgItem(hwnd, IDC_SHIMLIST);
iItem = SendMessage(hwList, LB_GETCURSEL, 0, 0);
if(iItem == LB_ERR)
break;
iShim = SendMessage(hwList, LB_GETITEMDATA, iItem, 0);
if(iShim == LB_ERR)
break;
hwDesc = GetDlgItem(hwnd, IDC_SHIMDESC);
SetWindowText(hwDesc, apShimInfo[iShim]->szDesc);
break;
}
break;
}
}