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

#include "compatadmin.h"
#ifndef __WIZARD_H
#include "wizard.h"
#endif
#include "xmldialog.h"
CShimWizard * g_pCurrentWizard = NULL;
#define MAX_DESC_LENGTH 40
#define PAGE_INTRO 0
#define PAGE_APPNAME 1
#define PAGE_LAYERNAME 2
#define PAGE_SELFILES1 3
#define PAGE_DONE 3
#define PAGE_SHIMS 4
#define PAGE_SHIMNAME 5
#define PAGE_SELECTFILES 6
BOOL CShimWizard::BeginWizard(HWND hParent)
{
PROPSHEETPAGE Pages[11];
ZeroMemory(&m_Record,sizeof(m_Record));
CoCreateGuid(&m_Record.guidID);
// Setup wizard variables
g_pCurrentWizard = this;
// Set default application settings
m_uType = TYPE_LAYER;
// begin the wizard
PROPSHEETHEADER Header;
Header.dwSize = sizeof(PROPSHEETHEADER);
Header.dwFlags = PSH_WIZARD97 | PSH_PROPSHEETPAGE | PSH_HEADER;
Header.hwndParent = hParent;
Header.hInstance = g_hInstance;
Header.pszCaption = /*"Create an application fix";//*/MAKEINTRESOURCE(IDS_WIZARD);
Header.nStartPage = 0;
Header.ppsp = Pages;
Header.nPages = 7;
Header.pszbmHeader = MAKEINTRESOURCE(IDB_WIZBMP);
Pages[PAGE_INTRO].dwSize = sizeof(PROPSHEETPAGE);
Pages[PAGE_INTRO].dwFlags = PSP_USEHEADERSUBTITLE;
Pages[PAGE_INTRO].hInstance = g_hInstance;
Pages[PAGE_INTRO].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD);
Pages[PAGE_INTRO].pfnDlgProc = (DLGPROC)EntryPoint;
Pages[PAGE_INTRO].pszHeaderSubTitle = TEXT("Select method");
Pages[PAGE_APPNAME].dwSize = sizeof(PROPSHEETPAGE);
Pages[PAGE_APPNAME].dwFlags = PSP_USEHEADERSUBTITLE;
Pages[PAGE_APPNAME].hInstance = g_hInstance;
Pages[PAGE_APPNAME].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD3);
Pages[PAGE_APPNAME].pfnDlgProc = (DLGPROC)GetAppName;
Pages[PAGE_APPNAME].pszHeaderSubTitle = TEXT("Enter an application name");
Pages[PAGE_LAYERNAME].dwSize = sizeof(PROPSHEETPAGE);
Pages[PAGE_LAYERNAME].dwFlags = PSP_USEHEADERSUBTITLE;
Pages[PAGE_LAYERNAME].hInstance = g_hInstance;
Pages[PAGE_LAYERNAME].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD2);
Pages[PAGE_LAYERNAME].pfnDlgProc = (DLGPROC)SelectLayer;
Pages[PAGE_LAYERNAME].pszHeaderSubTitle = TEXT("Select the files and compatibility mode");
/*
Pages[PAGE_SELFILES1].dwSize = sizeof(PROPSHEETPAGE);
Pages[PAGE_SELFILES1].dwFlags = PSP_USEHEADERSUBTITLE;
Pages[PAGE_SELFILES1].hInstance = g_hInstance;
Pages[PAGE_SELFILES1].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD4);
Pages[PAGE_SELFILES1].pfnDlgProc = SelectMatching;
Pages[PAGE_SELFILES1].pszHeaderSubTitle = "How would you like to identify the application?";
*/
Pages[PAGE_DONE].dwSize = sizeof(PROPSHEETPAGE);
Pages[PAGE_DONE].dwFlags = PSP_USEHEADERSUBTITLE;
Pages[PAGE_DONE].hInstance = g_hInstance;
Pages[PAGE_DONE].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARDDONE);
Pages[PAGE_DONE].pfnDlgProc = (DLGPROC)WizardDone;
Pages[PAGE_DONE].pszHeaderSubTitle = TEXT("You have successfully created an application fix");
Pages[PAGE_SHIMS].dwSize = sizeof(PROPSHEETPAGE);
Pages[PAGE_SHIMS].dwFlags = PSP_USEHEADERSUBTITLE;
Pages[PAGE_SHIMS].hInstance = g_hInstance;
Pages[PAGE_SHIMS].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD5);
Pages[PAGE_SHIMS].pfnDlgProc = (DLGPROC)SelectShims;
Pages[PAGE_SHIMS].pszHeaderSubTitle = TEXT("Select the fixes to apply to the application");
Pages[PAGE_SHIMNAME].dwSize = sizeof(PROPSHEETPAGE);
Pages[PAGE_SHIMNAME].dwFlags = PSP_USEHEADERSUBTITLE;
Pages[PAGE_SHIMNAME].hInstance = g_hInstance;
Pages[PAGE_SHIMNAME].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD6);
Pages[PAGE_SHIMNAME].pfnDlgProc = (DLGPROC)SelectLayer;
Pages[PAGE_SHIMNAME].pszHeaderSubTitle = TEXT("Select the file to create the fix for");
Pages[PAGE_SELECTFILES].dwSize = sizeof(PROPSHEETPAGE);
Pages[PAGE_SELECTFILES].dwFlags = PSP_USEHEADERSUBTITLE;
Pages[PAGE_SELECTFILES].hInstance = g_hInstance;
Pages[PAGE_SELECTFILES].pszTemplate = MAKEINTRESOURCE(IDD_ADDWIZARD7);
Pages[PAGE_SELECTFILES].pfnDlgProc = (DLGPROC)SelectFiles;
Pages[PAGE_SELECTFILES].pszHeaderSubTitle = TEXT("Select files used for application identification");
if ( 0 < PropertySheet(&Header) ) {
PDBRECORD pRecord = new DBRECORD;
if ( NULL != pRecord ) {
ZeroMemory(pRecord,sizeof(DBRECORD));
pRecord->szEXEName = m_Record.szEXEName;
pRecord->szAppName = m_Record.szAppName;
pRecord->szLayerName = m_Record.szLayerName;
pRecord->guidID = m_Record.guidID;
pRecord->pEntries = m_Record.pEntries;
g_theApp.GetDBLocal().InsertRecord(pRecord);
return TRUE;
}
}
return FALSE;
}
BOOL CALLBACK EntryPoint(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch ( uMsg ) {
case WM_INITDIALOG:
{
HWND hParent = GetParent(hDlg);
SetWindowText(hParent,TEXT("Create an application fix"));
if ( TYPE_LAYER == g_pCurrentWizard->m_uType )
SendDlgItemMessage(hDlg,IDC_LAYERS,BM_SETCHECK,BST_CHECKED,0);
if ( TYPE_SHIM == g_pCurrentWizard->m_uType )
SendDlgItemMessage(hDlg,IDC_SHIM,BM_SETCHECK,BST_CHECKED,0);
if ( TYPE_APPHELP == g_pCurrentWizard->m_uType )
SendDlgItemMessage(hDlg,IDC_APPHELP,BM_SETCHECK,BST_CHECKED,0);
}
break;
case WM_NOTIFY:
{
NMHDR * pHdr = (NMHDR *) lParam;
switch ( pHdr->code ) {
case PSN_SETACTIVE:
SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT);
break;
case PSN_WIZNEXT:
{
if ( BST_CHECKED == SendDlgItemMessage(hDlg,IDC_LAYERS,BM_GETCHECK,0,0) ) {
if ( g_pCurrentWizard->m_uType != TYPE_LAYER )
g_pCurrentWizard->WipeRecord(TRUE,TRUE,TRUE);
g_pCurrentWizard->m_uType = TYPE_LAYER;
}
if ( BST_CHECKED == SendDlgItemMessage(hDlg,IDC_SHIM,BM_GETCHECK,0,0) ) {
if ( g_pCurrentWizard->m_uType != TYPE_SHIM )
g_pCurrentWizard->WipeRecord(TRUE,TRUE,TRUE);
g_pCurrentWizard->m_uType = TYPE_SHIM;
}
}
break;
}
}
break;
}
return FALSE;
}
#define FRIENDLY_NAME TEXT("My Application Fix")
BOOL CALLBACK GetAppName(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch ( uMsg ) {
case WM_INITDIALOG:
{
SendMessage(
GetDlgItem(hDlg,IDC_NAME), // handle to destination window
EM_LIMITTEXT, // message to send
(WPARAM) LIMIT_APP_NAME, // text length
(LPARAM) 0
);
SHAutoComplete(GetDlgItem(hDlg,IDC_NAME), AUTOCOMPLETE);
if ( 0 == g_pCurrentWizard->m_Record.szAppName.Length() )
g_pCurrentWizard->m_Record.szAppName = FRIENDLY_NAME;
SetDlgItemText(hDlg,IDC_NAME, g_pCurrentWizard->m_Record.szAppName);
if ( g_pCurrentWizard->m_Record.szAppName == FRIENDLY_NAME )
SendMessage(GetDlgItem(hDlg,IDC_NAME),EM_SETSEL,0,-1);
// Force proper Next button state.
SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_NAME,EN_CHANGE),0);
}
break;
case WM_NOTIFY:
{
NMHDR * pHdr = (NMHDR *) lParam;
switch ( pHdr->code ) {
case PSN_SETACTIVE:
{
SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_NAME,EN_CHANGE),0);
if ( TYPE_LAYER == g_pCurrentWizard->m_uType )
SetWindowText(GetDlgItem(hDlg,IDC_TITLE),TEXT("Enter the name of the application to create a compatibility layer for"));
else
SetWindowText(GetDlgItem(hDlg,IDC_TITLE),TEXT("Enter the name of the application to create a fix for"));
}
break;
case PSN_WIZNEXT:
{
TCHAR szTemp[MAX_STRING_SIZE];
GetDlgItemText(hDlg,IDC_NAME,szTemp,MAX_STRING_SIZE);
CSTRING::Trim(szTemp);
g_pCurrentWizard->m_Record.szAppName = szTemp;
if ( TYPE_SHIM == g_pCurrentWizard->m_uType ) {
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD6);
return IDD_ADDWIZARD6;
}
}
break;
}
}
break;
case WM_COMMAND:
switch ( LOWORD(wParam) ) {
case IDC_NAME:
if ( EN_CHANGE == HIWORD(wParam) ) {
TCHAR szText[MAX_PATH_BUFFSIZE];
GetWindowText(GetDlgItem(hDlg,IDC_NAME),szText,MAX_PATH);
BOOL bEnable = ( CSTRING::Trim(szText) > 0) ? TRUE:FALSE;
DWORD dwFlags = PSWIZB_BACK;
if ( bEnable )
dwFlags |= PSWIZB_NEXT;
SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS,0, dwFlags);
}
break;
}
}
return FALSE;
}
BOOL CALLBACK SelectLayer(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch ( uMsg ) {
case WM_INITDIALOG:
{
SendMessage(
GetDlgItem(hDlg,IDC_NAME), // handle to destination window
EM_LIMITTEXT, // message to send
(WPARAM) MAX_PATH, // text length
(LPARAM) 0
);
SetDlgItemText(hDlg,IDC_NAME,g_pCurrentWizard->m_szLongName);
SHAutoComplete(GetDlgItem(hDlg,IDC_NAME), AUTOCOMPLETE);
// Force proper Next button state.
SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_NAME,EN_CHANGE),0);
}
break;
case WM_NOTIFY:
{
NMHDR * pHdr = (NMHDR *) lParam;
switch ( pHdr->code ) {
case PSN_SETACTIVE:
{
if ( TYPE_LAYER == g_pCurrentWizard->m_uType ) {
int nSelIndex = -1;
// Remove all strings.
//g_pCurrentWizard->WipeRecord(TRUE,TRUE,FALSE);
while ( CB_ERR != SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_DELETESTRING,0,0) );
// Re-add the strings.
PDBLAYER pWalk = g_theApp.GetDBGlobal().m_pLayerList;
for ( int iLoop = 0 ; iLoop <= 1 ; ++ iLoop ){
//
// Do both for the local and the global Databases
//
while ( NULL != pWalk ) {
if ( CB_ERR == SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_FINDSTRINGEXACT,0,(LPARAM)(LPCTSTR)pWalk->szLayerName) ) {
int nIndex;
nIndex = SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_ADDSTRING,0,(LPARAM)(LPTSTR)pWalk->szLayerName);
if ( CB_ERR != nIndex ) {
SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_SETITEMDATA,nIndex,(LPARAM)pWalk);
// Select this index if it's the current layer name.
/*
if (0 == lstrcmp(g_pCurrentWizard->m_Record.szLayerName,(LPSTR)pWalk->szLayerName))
nSelIndex = nIndex;
*/
}
}
pWalk = pWalk->pNext;
}
pWalk = g_theApp.GetDBLocal().m_pLayerList;
} //for
nSelIndex = SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_FINDSTRINGEXACT,0,(LPARAM)(LPCTSTR)g_pCurrentWizard->m_Record.szLayerName);
if ( -1 != nSelIndex )
SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_SETCURSEL,nSelIndex,0);
}
SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_NAME,EN_CHANGE),0);
}
break;
case PSN_WIZNEXT:
{
TCHAR szTemp[MAX_STRING_SIZE];
GetDlgItemText(hDlg,IDC_NAME,szTemp,MAX_PATH);
CSTRING::Trim(szTemp);
HANDLE hFile = CreateFile (szTemp,0,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if ( INVALID_HANDLE_VALUE == hFile ) {
MessageBox(hDlg,TEXT("Unable to locate specified file"),TEXT("Invalid file name"),MB_OK);
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,-1);
return -1;
}
CloseHandle(hFile);
DWORD dwExeType;
GetBinaryType(szTemp, &dwExeType);
BOOL bExe = FALSE;// Is this an .exe file
CSTRING strTemp = szTemp;
if ( strTemp.EndsWith(TEXT(".exe")) ) bExe = TRUE;
//
// Check if this is "shimmable"
//
CSTRING msg;
if ( (dwExeType & SCS_DOS_BINARY) && bExe )
msg = TEXT("This is a DOS Application\n");
else if ( (dwExeType & SCS_WOW_BINARY) && bExe)
msg = TEXT("This is a 16 bit Windows Application\n");
else if ((dwExeType & SCS_PIF_BINARY) && bExe )
msg = TEXT("This is a PIF Binary Application\n");
else if ( (dwExeType & SCS_POSIX_BINARY) && bExe)
msg = msg = TEXT("This is a POSIX Binary Application\n");
else if ( (dwExeType & SCS_OS216_BINARY) && bExe)
msg = TEXT("This is a OS2 16 bit Application\n");
if (msg.Length() > 0) {
//
//So this application cannot be fixed
//
MessageBox(hDlg,
msg.strcat( TEXT("The fix may not get applied properly for this application") ),
TEXT("Warning!"),
MB_ICONWARNING
);
//SetWindowLongPtr(hDlg,DWLP_MSGRESULT,-1);
//return -1;
}
////check - out
if (strTemp != g_pCurrentWizard->m_szLongName) {
//
//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
// Remove all the mathcing info
g_pCurrentWizard->WipeRecord(TRUE, FALSE, FALSE);
}
////
g_pCurrentWizard->m_szLongName = szTemp;
g_pCurrentWizard->m_Record.szEXEName = g_pCurrentWizard->ShortFile(g_pCurrentWizard->m_szLongName);
if ( TYPE_LAYER == g_pCurrentWizard->m_uType ) {
int nIndex;
nIndex = SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_GETCURSEL,0,0);
SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_GETLBTEXT,nIndex,(LPARAM)szTemp);
g_pCurrentWizard->m_Record.szLayerName = szTemp;
} else {
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD5);
return IDD_ADDWIZARD6;
}
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD7);
return IDD_ADDWIZARD7;
}
break;
case PSN_WIZBACK:
{
TCHAR szTemp[MAX_STRING_SIZE];
GetDlgItemText(hDlg,IDC_NAME,szTemp,MAX_STRING_SIZE);
CSTRING::Trim(szTemp);
g_pCurrentWizard->m_szLongName = szTemp;
if ( TYPE_LAYER == g_pCurrentWizard->m_uType ) {
int nIndex;
nIndex = SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_GETCURSEL,0,0);
SendDlgItemMessage(hDlg,IDC_LAYERLIST,CB_GETLBTEXT,nIndex,(LPARAM)szTemp);
g_pCurrentWizard->m_Record.szLayerName = szTemp;
} else {
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD3);
return IDD_ADDWIZARD3;
}
}
break;
}
}
break;
case WM_COMMAND:
switch ( LOWORD(wParam) ) {
case IDC_LAYERLIST:
{
if ( CBN_SELCHANGE == HIWORD(wParam) )
SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_NAME,EN_CHANGE),0);
}
break;
case IDC_NAME:
if ( EN_CHANGE == HIWORD(wParam) ) {
TCHAR szText[MAX_PATH_BUFFSIZE];
GetWindowText(GetDlgItem(hDlg,IDC_NAME),szText,MAX_PATH);
BOOL bEnable = (CSTRING::Trim(szText) > 0) ? TRUE:FALSE;
DWORD dwFlags = PSWIZB_BACK;
if ( bEnable )
dwFlags |= PSWIZB_NEXT;
HWND hLayer = GetDlgItem(hDlg,IDC_LAYERLIST);
if ( NULL != hLayer ) {
// A layer must be selected as well.
int nSel = SendMessage(hLayer,CB_GETCURSEL,0,0);
if ( CB_ERR == nSel )
dwFlags &= ~PSWIZB_NEXT;
}
SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS,0, dwFlags);
}
break;
case IDC_BROWSE:
{
CSTRING szFilename;
HWND hwndFocus = GetFocus();
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) ) {
g_pCurrentWizard->m_Record.szEXEName = g_pCurrentWizard->ShortFile(szFilename);
SetDlgItemText(hDlg, IDC_NAME, szFilename);
SendMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_NAME,EN_CHANGE),0);
}
SetFocus( hwndFocus );
}
break;
}
break;
}
return FALSE;
}
BOOL CALLBACK SelectMatching(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch ( uMsg ) {
case WM_INITDIALOG:
{
SendDlgItemMessage(hDlg,IDC_GENERATE,BM_SETCHECK,BST_CHECKED,0);
}
break;
case WM_NOTIFY:
{
NMHDR * pHdr = (NMHDR *) lParam;
switch ( pHdr->code ) {
case PSN_SETACTIVE:
SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS, 0, PSWIZB_BACK | PSWIZB_NEXT);
break;
case PSN_WIZNEXT:
{
if ( BST_CHECKED == SendDlgItemMessage(hDlg,IDC_GENERATE,BM_GETCHECK,0,0) ) {
HCURSOR hRestore;
CSTRING szFile = g_pCurrentWizard->m_szLongName;
LPTSTR szWalk = _tcsrchr( (LPTSTR)szFile, TEXT('\\'));
//
// current directory extraction from the szFile
//
if (NULL == szWalk) {
// ?
} else {
*szWalk = 0;
}
SetCurrentDirectory(szFile);
g_pCurrentWizard->m_bManualMatch = FALSE;
hRestore = SetCursor(LoadCursor(NULL,IDC_WAIT));
g_pCurrentWizard->GrabMatchingInfo();
SetCursor(hRestore);
}
if ( BST_CHECKED == SendDlgItemMessage(hDlg,IDC_MANUAL,BM_GETCHECK,0,0) ) {
WIN32_FIND_DATA Data;
HANDLE hFile;
PMATCHENTRY pMatch = NULL;
g_pCurrentWizard->m_bManualMatch = TRUE;
hFile = FindFirstFile(g_pCurrentWizard->m_szLongName,&Data);
if ( INVALID_HANDLE_VALUE != hFile ) {
g_pCurrentWizard->AddMatchFile(&pMatch,g_pCurrentWizard->m_szLongName);
g_pCurrentWizard->GetFileAttributes(pMatch);
if ( !g_pCurrentWizard->InsertMatchingInfo(pMatch) )
delete pMatch;
//pMatch->Entry.pNext = g_pCurrentWizard->m_Record.pEntries;
//g_pCurrentWizard->m_Record.pEntries = (PDBENTRY) pMatch;
}
}
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD7);
return IDD_ADDWIZARD7;
}
break;
case PSN_WIZBACK:
{
if ( TYPE_LAYER == g_pCurrentWizard->m_uType ) {
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD2);
return IDD_ADDWIZARD2;
} else
if ( TYPE_SHIM == g_pCurrentWizard->m_uType ) {
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD5);
return IDD_ADDWIZARD5;
}
}
break;
}
}
break;
}
return FALSE;
}
BOOL CALLBACK WizardDone(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch ( uMsg ) {
case WM_NOTIFY:
{
NMHDR * pHdr = (NMHDR *) lParam;
switch ( pHdr->code ) {
case PSN_WIZBACK:
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD7);
return IDD_ADDWIZARD7;
case PSN_SETACTIVE:
SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS, 0, PSWIZB_BACK | PSWIZB_FINISH);
}
}
break;
case WM_COMMAND:
switch ( LOWORD(wParam) ) {
case IDC_VIEWXML:
{
CXMLDialog XML;
XML.BeginXMLView(&g_pCurrentWizard->m_Record,hDlg,FALSE,FALSE,TRUE);
}
break;
case IDC_TESTRUN:
{
HWND hndFocus = GetFocus();
g_theApp.TestRun(&g_pCurrentWizard->m_Record,&g_pCurrentWizard->m_szLongName,NULL,hDlg);
SetFocus(hndFocus);
}
break;
}
break;
}
return FALSE;
}
void SelectShims_TreeDoubleClicked(HWND hDlg);
BOOL CALLBACK SelectShims(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch ( uMsg ) {
case WM_INITDIALOG:
{
TVINSERTSTRUCT Item;
PSHIMDESC pWalk = g_theApp.GetDBGlobal().m_pShimList;
Item.hParent = TVI_ROOT;
Item.hInsertAfter = TVI_LAST;
Item.item.mask = TVIF_TEXT | TVIF_PARAM;
while ( NULL != pWalk ) {
if ( pWalk->bGeneral ) {
PSHIMENTRY pNew = new SHIMENTRY;
if ( NULL != pNew ) {
pNew->Entry.uType = ENTRY_SHIM;
pNew->Entry.uIconID = 0;
pNew->Entry.pNext = NULL;
pNew->szShimName = pWalk->szShimName;
pNew->szCmdLine = pWalk->szShimCommandLine;
pNew->pDesc = pWalk;
Item.item.pszText = (LPTSTR) pWalk->szShimName;
Item.item.cchTextMax = lstrlen(Item.item.pszText);
Item.item.lParam = (LPARAM) pNew;
TreeView_InsertItem(GetDlgItem(hDlg,IDC_SHIMLIST),&Item);
}
}
pWalk = pWalk->pNext;
}
SetTimer(hDlg,0,100,NULL);
}
break;
case WM_COMMAND:
{
switch ( LOWORD(wParam) ) {
case IDC_CLEARALL:
{
HTREEITEM hItem;
HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
hItem = TreeView_GetRoot(hTree);
while ( NULL != hItem ) {
TVITEM Item;
Item.mask = TVIF_STATE;
Item.hItem = hItem;
TreeView_GetItem(hTree,&Item);
if ( 0 != (Item.state & 0x2000) ) {
Item.state &= 0xFFFFDFFF;
Item.state |= 0x1000;
TreeView_SetItemState(hTree,hItem,Item.state,0xFFFFFFFF);
}
hItem = TreeView_GetNextSibling(hTree,hItem);
}
// Recount
SetTimer(hDlg,0,100,NULL);
}
break;
}
}
break;
case WM_TIMER:
{
UINT uTotal = 0;
UINT uSelected = 0;
HTREEITEM hItem;
HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
CSTRING szText;
KillTimer(hDlg,0);
// Count the selected shims
hItem = TreeView_GetRoot(hTree);
while ( NULL != hItem ) {
TVITEM Item;
Item.mask = TVIF_STATE;
Item.hItem = hItem;
TreeView_GetItem(hTree,&Item);
if ( 0 != (Item.state & 0x2000) )
++uSelected;
++uTotal;
hItem = TreeView_GetNextSibling(hTree,hItem);
}
szText.sprintf(TEXT("Selected %d of %d"),uSelected,uTotal);
SetWindowText(GetDlgItem(hDlg,IDC_STATUS),(LPCTSTR)szText);
DWORD dwFlags = PSWIZB_BACK | PSWIZB_NEXT;
if ( 0 == uSelected )
dwFlags &= ~PSWIZB_NEXT;
SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS,0, dwFlags);
}
break;
case WM_DESTROY:
{
HTREEITEM hItem;
HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
hItem = TreeView_GetRoot(hTree);
while ( NULL != hItem ) {
TVITEM Item;
Item.mask = TVIF_STATE | TVIF_PARAM;
Item.hItem = hItem;
TreeView_GetItem(hTree,&Item);
PSHIMENTRY pEntry = (PSHIMENTRY) Item.lParam;
PDBENTRY pWalk = g_pCurrentWizard->m_Record.pEntries;
while ( NULL != pWalk ) {
if ( pWalk == (PDBENTRY)pEntry )
break;
pWalk = pWalk->pNext;
}
if ( NULL == pWalk )
delete pEntry;
hItem = TreeView_GetNextSibling(hTree,hItem);
}
}
break;
case WM_NOTIFY:
{
NMHDR * pHdr = (NMHDR *) lParam;
switch ( pHdr->code ) {
case NM_RETURN:{
SelectShims_TreeDoubleClicked(hDlg);
return TRUE;
}
case PSN_SETACTIVE:
SetTimer(hDlg,0,100,NULL);
break;
case NM_DBLCLK:
{
SelectShims_TreeDoubleClicked(hDlg);
}//case NM_DBLCLK:
break;
case NM_CLICK:
{
TVHITTESTINFO ht;
HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
GetCursorPos(&ht.pt);
ScreenToClient(hTree, &ht.pt);
TreeView_HitTest(hTree,&ht);
if ( 0 != ht.hItem )
TreeView_SelectItem(hTree,ht.hItem);
SetTimer(hDlg,0,100,NULL);
}
break;
case PSN_WIZBACK:
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD6);
return IDD_ADDWIZARD6;
case PSN_WIZNEXT:
{
// Build the shim list.
HTREEITEM hItem;
HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
// Wipe shims and layers, but not matching info.
g_pCurrentWizard->WipeRecord(FALSE,TRUE,TRUE);
hItem = TreeView_GetRoot(hTree);
while ( NULL != hItem ) {
TVITEM Item;
Item.mask = TVIF_STATE | TVIF_PARAM;
Item.hItem = hItem;
TreeView_GetItem(hTree,&Item);
PSHIMENTRY pEntry = (PSHIMENTRY) Item.lParam;
pEntry->Entry.pNext = NULL;
if ( 0 != (Item.state & 0x2000) ) {
pEntry->Entry.pNext = g_pCurrentWizard->m_Record.pEntries;
g_pCurrentWizard->m_Record.pEntries = (PDBENTRY) pEntry;
}
hItem = TreeView_GetNextSibling(hTree,hItem);
}
//SetWindowLong(hDlg,DWL_MSGRESULT,IDD_ADDWIZARD4);
//return IDD_ADDWIZARD4;
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD7);
return IDD_ADDWIZARD7;
}
break;
case TVN_KEYDOWN:{
LPNMTVKEYDOWN pTvkd = (LPNMTVKEYDOWN) lParam ;
HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
if (pTvkd->wVKey == VK_SPACE ) {
if (TreeView_GetSelection(hTree) != NULL ){
SetTimer(hDlg,0,100,NULL);
}
}
break;
}
case TVN_SELCHANGED:
{
LPNMTREEVIEW pTree = (LPNMTREEVIEW) lParam;
PSHIMENTRY pEntry = (PSHIMENTRY) pTree->itemOld.lParam;
TCHAR szCmdLine[MAX_PATH_BUFFSIZE];
/* K BUG why is this required !
if ( NULL != pEntry ) {
GetWindowText(GetDlgItem(hDlg,IDC_CMDLINE),szCmdLine,MAX_PATH);
pEntry->szCmdLine = szCmdLine;
}
*/
pEntry = (PSHIMENTRY) pTree->itemNew.lParam;
PSHIMDESC pDesc = (PSHIMDESC) pEntry->pDesc;
SetWindowText(GetDlgItem(hDlg,IDC_SHIMDESC),(LPCTSTR) pDesc->szShimDesc);
SetWindowText(GetDlgItem(hDlg,IDC_CMDLINE),(LPCTSTR) pEntry->szCmdLine);
}
break;
}
}
break;
}
return FALSE;
}
BOOL CALLBACK SelectFiles(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch ( uMsg ) {
case WM_INITDIALOG:
{
PostMessage(hDlg,WM_USER+1024,0,0);
}
break;
case WM_USER+1024:
{
PDBENTRY pWalk;
TreeView_DeleteAllItems(GetDlgItem(hDlg,IDC_FILELIST));
pWalk = g_pCurrentWizard->m_Record.pEntries;
TVINSERTSTRUCT Item;
ZeroMemory(&Item,sizeof(TVINSERTSTRUCT));
Item.hParent = TVI_ROOT;
Item.hInsertAfter = TVI_LAST;
Item.item.mask = TVIF_TEXT | TVIF_PARAM;
Item.item.lParam = (LPARAM) NULL;
Item.item.pszText = g_pCurrentWizard->m_Record.szEXEName;
Item.item.cchTextMax = lstrlen(Item.item.pszText);
TreeView_InsertItem(GetDlgItem(hDlg,IDC_FILELIST),&Item);
while ( NULL != pWalk ) {
if ( ENTRY_MATCH == pWalk->uType ) {
TVINSERTSTRUCT Item;
PMATCHENTRY pMatch = (PMATCHENTRY) pWalk;
if ( pMatch->szMatchName != TEXT("*") ) {
ZeroMemory(&Item,sizeof(TVINSERTSTRUCT));
Item.hParent = TVI_ROOT;
Item.hInsertAfter = TVI_LAST;
Item.item.mask = TVIF_TEXT | TVIF_PARAM;
Item.item.lParam = (LPARAM) pMatch;
Item.item.pszText = pMatch->szMatchName;
Item.item.cchTextMax = lstrlen(Item.item.pszText);
TreeView_InsertItem(GetDlgItem(hDlg,IDC_FILELIST),&Item);
}
}
pWalk = pWalk->pNext;
}
}
break;
case WM_NOTIFY:
{
NMHDR * pHdr = (NMHDR *) lParam;
switch ( pHdr->code ) {
case PSN_SETACTIVE:
{
SendMessage(GetParent(hDlg),PSM_SETWIZBUTTONS, 0, PSWIZB_BACK | PSWIZB_NEXT);
// Force refresh of files in list.
PostMessage(hDlg,WM_USER+1024,0,0);
}
break;
case PSN_WIZBACK:
{
PMATCHENTRY pWalk = (PMATCHENTRY) g_pCurrentWizard->m_Record.pEntries;
PMATCHENTRY pPrev;
CSTRING szFile = g_pCurrentWizard->m_szLongName;
szFile.ShortFilename();
// Remove the matching info for the current file if it exists. Otherwise,
// it's possible that if the file is changed, we'll have bogus information
// about it.
while ( NULL != pWalk ) {
if ( ENTRY_MATCH == pWalk->Entry.uType )
if ( pWalk->szMatchName == szFile || pWalk->szMatchName == TEXT("*") ) {
// Remove this entry.
if ( pWalk == (PMATCHENTRY) g_pCurrentWizard->m_Record.pEntries )
g_pCurrentWizard->m_Record.pEntries = g_pCurrentWizard->m_Record.pEntries->pNext;
else
pPrev->Entry.pNext = pWalk->Entry.pNext;
delete pWalk;
break;
}
pPrev = pWalk;
pWalk = (PMATCHENTRY) pWalk->Entry.pNext;
}
if ( TYPE_LAYER == g_pCurrentWizard->m_uType ) {
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD2);
return IDD_ADDWIZARD2;
} else if ( TYPE_SHIM == g_pCurrentWizard->m_uType ) {
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARD5);
return IDD_ADDWIZARD5;
}
else if (TYPE_APPHELP == g_pCurrentWizard->m_uType ) {
return IDD_APPHELP1;
}
}
break;
case PSN_WIZNEXT:
{
PMATCHENTRY pMatch = NULL;
// Add self. Self should always be included here.
g_pCurrentWizard->AddMatchFile(&pMatch,g_pCurrentWizard->m_szLongName);
g_pCurrentWizard->GetFileAttributes(pMatch);
if ( !g_pCurrentWizard->InsertMatchingInfo(pMatch) )
delete pMatch;
//pMatch->Entry.pNext = g_pCurrentWizard->m_Record.pEntries;
//g_pCurrentWizard->m_Record.pEntries = (PDBENTRY) pMatch;
if (TYPE_APPHELP == g_pCurrentWizard->m_uType)
return TRUE;
SetWindowLongPtr(hDlg,DWLP_MSGRESULT,IDD_ADDWIZARDDONE);
}
return IDD_ADDWIZARDDONE;
}
}
break;
case WM_COMMAND:
switch ( LOWORD(wParam) ) {
case IDC_GENERATE:
{
HCURSOR hRestore;
CSTRING szFile = g_pCurrentWizard->m_szLongName;
LPTSTR szWalk = (LPTSTR) szFile + szFile.Length() - 1;
while ( TEXT('\\') != *szWalk )
--szWalk;
++szWalk;
*szWalk = 0;
SetCurrentDirectory(szFile);
g_pCurrentWizard->m_bManualMatch = FALSE;
hRestore = SetCursor(LoadCursor(NULL,IDC_WAIT));
g_pCurrentWizard->GrabMatchingInfo();
SetCursor(hRestore);
PostMessage(hDlg,WM_USER+1024,0,0);
}
break;
case IDC_ADDFILES:
{
CSTRING szFilename;
HWND hwndFocus = GetFocus();
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) ) {
CSTRING szCheck = szFilename;
szCheck.ShortFilename();
PDBENTRY pWalk;
pWalk = g_pCurrentWizard->m_Record.pEntries;
while ( NULL != pWalk ) {
if ( ENTRY_MATCH == pWalk->uType ) {
PMATCHENTRY pTest = (PMATCHENTRY) pWalk;
CSTRING szShort = pTest->szMatchName;
szShort.ShortFilename();
if ( szShort == szCheck ) {
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);
return FALSE;
}
}
pWalk = pWalk->pNext;
}
//WIN32_FIND_DATA Data;
//HANDLE hFile;
//hFile = FindFirstFile(szFilename,&Data);
//if (INVALID_HANDLE_VALUE != hFile)
{
PMATCHENTRY pMatch = NULL;
g_pCurrentWizard->AddMatchFile(&pMatch,szFilename);
g_pCurrentWizard->GetFileAttributes(pMatch);
if ( !g_pCurrentWizard->InsertMatchingInfo(pMatch) )
delete pMatch;
//pMatch->Entry.pNext = g_pCurrentWizard->m_Record.pEntries;
//g_pCurrentWizard->m_Record.pEntries = (PDBENTRY) pMatch;
//FindClose(hFile);
PostMessage(hDlg,WM_USER+1024,0,0);
}
}
SetFocus( hwndFocus );
}
break;
case IDC_REMOVEALL:
{
PDBENTRY pWalk;
PDBENTRY pHold;
pWalk = g_pCurrentWizard->m_Record.pEntries;
while ( NULL != pWalk ) {
if ( ENTRY_MATCH == pWalk->uType ) {
if ( g_pCurrentWizard->m_Record.pEntries == pWalk ) {
g_pCurrentWizard->m_Record.pEntries = pWalk->pNext;
pHold = g_pCurrentWizard->m_Record.pEntries;
} else
pHold->pNext = pWalk->pNext;
delete pWalk;
pWalk = pHold;
} else {
pHold = pWalk;
pWalk = pWalk->pNext;
}
}
PostMessage(hDlg,WM_USER+1024,0,0);
}
break;
case IDC_REMOVEFILES:
{
HTREEITEM hItem = TreeView_GetSelection(GetDlgItem(hDlg,IDC_FILELIST));
if ( NULL != hItem ) {
TVITEM Item;
Item.mask = TVIF_PARAM;
Item.hItem = hItem;
TreeView_GetItem(GetDlgItem(hDlg,IDC_FILELIST),&Item);
PDBENTRY pWalk;
PDBENTRY pHold;
if ( NULL == Item.lParam ) {
MessageBeep(MB_OK);
MessageBox(NULL,TEXT("This file is required for file matching"),TEXT("Matching error"),MB_OK);
break;
}
pWalk = g_pCurrentWizard->m_Record.pEntries;
while ( NULL != pWalk ) {
if ( pWalk == (PDBENTRY) Item.lParam )
break;
pHold = pWalk;
pWalk = pWalk->pNext;
}
if ( pWalk == g_pCurrentWizard->m_Record.pEntries )
g_pCurrentWizard->m_Record.pEntries = pWalk->pNext;
else
pHold->pNext = pWalk->pNext;
delete pWalk;
PostMessage(hDlg,WM_USER+1024,0,0);
}
}
break;
}
break;
}
return FALSE;
}
void CShimWizard::WipeRecord(BOOL bMatching, BOOL bShims, BOOL bLayer, BOOL bAppHelp)
{
//BUGBUG : Deletion not done correctly.
//
// Matching files are deleted, shims are not ??
//
PDBENTRY pWalk = m_Record.pEntries;
PDBENTRY pPrev = pWalk;//prefast
while ( NULL != pWalk ) {
PDBENTRY pHold = pWalk->pNext;
BOOL bRemove = FALSE;
if ( ENTRY_SHIM == pWalk->uType && bShims )
bRemove = TRUE;
else
if ( ENTRY_MATCH == pWalk->uType && bMatching ) {
bRemove = TRUE;
delete pWalk;
}
#ifdef _DEBUG
if ( bRemove ) {
if ( m_Record.pEntries != pWalk )
if ( pPrev == pHold )
__asm int 3;
}
#endif
if ( bRemove ) {
if ( m_Record.pEntries == pWalk )
m_Record.pEntries = pHold;
else
pPrev->pNext = pHold;
} else
pPrev = pWalk;
pWalk = pHold;
}
if ( bLayer )
m_Record.szLayerName = TEXT("");
}
typedef struct tagATTRINFO2 {
TAG tAttrID; // tag for this attribute (includes type)
DWORD dwFlags; // flags : such as "not avail" or "not there yet"
union { // anonymous union with values
ULONGLONG ullAttr; // QWORD value (TAG_TYPE_QWORD)
DWORD dwAttr; // DWORD value (TAG_TYPE_DWORD)
TCHAR* lpAttr; // WCHAR* value (TAG_TYPE_STRINGREF)
};
} ATTRINFO2, *PATTRINFO2;
void CShimWizard::GetFileAttributes(PMATCHENTRY pNew)
{
PATTRINFO2 pAttribs;
DWORD dwAttribCount;
CSTRING szFile = pNew->szFullName;
BOOL bIs16Bit = FALSE;
/*
DWORD dwType;
GetBinaryType(szFile,&dwType);
if (SCS_WOW_BINARY == dwType)
bIs16Bit = TRUE;
*/
if ( szFile.Length() == 0 ) {
MEM_ERR;
return;
}
if ( SdbGetFileAttributes((LPCTSTR)szFile,(PATTRINFO *)&pAttribs,&dwAttribCount) ) {
UINT uCount;
for ( uCount=0; uCount<dwAttribCount; ++uCount ) {
if ( 0 != (pAttribs[uCount].dwFlags & ATTRIBUTE_AVAILABLE) ) {
switch ( pAttribs[uCount].tAttrID ) {
case TAG_COMPANY_NAME:
pNew->szCompanyName = (LPCTSTR)pAttribs[uCount].lpAttr;
break;
case TAG_PRODUCT_VERSION:
pNew->szProductVersion = (LPCTSTR)pAttribs[uCount].lpAttr;
break;
case TAG_FILE_DESCRIPTION:
pNew->szDescription = (LPCTSTR)pAttribs[uCount].lpAttr;
break;
case TAG_FILE_VERSION:
pNew->szFileVersion = (LPCTSTR)pAttribs[uCount].lpAttr;
break;
case TAG_CHECKSUM:
pNew->dwChecksum = pAttribs[uCount].dwAttr;
break;
case TAG_BIN_FILE_VERSION:
{
if ( !bIs16Bit )
pNew->FileVersion.QuadPart = pAttribs[uCount].ullAttr;
}
break;
case TAG_BIN_PRODUCT_VERSION:
{
if ( !bIs16Bit )
pNew->ProductVersion.QuadPart = pAttribs[uCount].ullAttr;
}
break;
}
}
}
SdbFreeFileAttributes((PATTRINFO)pAttribs);
}
}
void CShimWizard::AddMatchFile(PPMATCHENTRY ppHead, CSTRING & szFilename)
{
PMATCHENTRY pNew;
PMATCHENTRY pWalk;
PMATCHENTRY pHold;
BOOL bInsertHead=FALSE;
CSTRING szFile; // = RelativePath();
//TCHAR szCurrentPath[MAX_PATH_BUFFSIZE];
pNew = new MATCHENTRY;
if ( NULL == pNew )
return;
ZeroMemory(pNew,sizeof(MATCHENTRY));
//GetCurrentDirectory(MAX_PATH,szCurrentPath);
//if (lstrlen(szCurrentPath) == 3)
//szCurrentPath[2] = 0;
//szFile.sprintf("%s\\%s",szCurrentPath,pData->cFileName);
//szFile = szCurrentPath;
///szFile.strcat(pData->cFileName);
//pNew->szFullName.sprintf("%s\\%s",szCurrentPath,pData->cFileName);
pNew->szFullName = szFilename;
//szFile.strcat(pData->cFileName);
szFile = pNew->szFullName;
szFile.RelativeFile(m_szLongName);
pNew->Entry.uType = ENTRY_MATCH;
pNew->szMatchName = szFile;
HANDLE hFile = CreateFile((LPCTSTR) szFilename,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if ( INVALID_HANDLE_VALUE != hFile ) {
//pNew->dwSize = pData->nFileSizeLow;
pNew->dwSize = GetFileSize(hFile,NULL);
CloseHandle(hFile);
}
pWalk = *ppHead;
// Walk the list to determine where to insert it.
while ( NULL != pWalk ) {
if ( pWalk->dwSize < pNew->dwSize )
break;
pHold = pWalk;
pWalk = (PMATCHENTRY) pWalk->Entry.pNext;
}
// Insert it into the head if the head is NULL, OR if this file is
// the same as the file being fixed.
CSTRING szShort = szFilename;
if ( szShort.Length() == 0 ) {
MEM_ERR;
return;
}
szShort.ShortFilename();
if ( NULL == *ppHead || 0 == lstrcmpi(szShort,m_Record.szEXEName) ) {//0 == lstrcmpi(pData->cFileName,m_Record.szEXEName))
bInsertHead = TRUE;
//if (0 == lstrcmpi(pData->cFileName,m_Record.szEXEName))
if ( 0 == lstrcmpi(szShort,m_Record.szEXEName) )
pNew->szMatchName = TEXT("*");
} else
if ( *ppHead == pWalk )
bInsertHead = TRUE;
if ( NULL != pWalk && pWalk->szMatchName == pNew->szMatchName ) {
// Duplicate here. Refuse.
delete pNew;
return;
}
if ( bInsertHead ) {
if ( NULL != *ppHead && 0 == lstrcmpi(pNew->szMatchName,TEXT("*")) ) {
// If the file to fix has aleady been added at the head, special
// case this insert.
pNew->Entry.pNext = (*ppHead)->Entry.pNext;
(*ppHead)->Entry.pNext = (PDBENTRY) pNew;
} else {
// Standard head insert.
pNew->Entry.pNext = (PDBENTRY) *ppHead;
*ppHead = pNew;
}
} else {
pNew->Entry.pNext = (PDBENTRY) pWalk;
pHold->Entry.pNext =(PDBENTRY) pNew;
}
}
void CShimWizard::WalkDirectory(PMATCHENTRY * ppHead, LPCTSTR szDirectory, int nDepth)
{
HANDLE hFile;
WIN32_FIND_DATA Data;
TCHAR szCurrentDir[MAX_PATH_BUFFSIZE] = TEXT("");
int nFiles=0;
if ( 2 <= nDepth )
return;
CSTRING szShortName = m_szLongName;
szShortName.ShortFilename();
// Save the current directory
GetCurrentDirectory(MAX_PATH,szCurrentDir);
// Set to the new directory
SetCurrentDirectory(szDirectory);
// Generate automated matching file information.
hFile = FindFirstFile(TEXT("*.*"),&Data);
if ( INVALID_HANDLE_VALUE == hFile ) {
SetCurrentDirectory(szCurrentDir);
return;
}
do {
if ( 0 == (Data.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) )
if ( FILE_ATTRIBUTE_DIRECTORY == (Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) {
if ( TEXT('.') != Data.cFileName[0] )
WalkDirectory(ppHead,Data.cFileName,nDepth+1);
} else {
++nFiles;
if ( nFiles >= 100 )
break;
if ( 0 != lstrcmpi(szShortName,Data.cFileName) )
if ( 0 == (Data.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) ) {
CSTRING szFilename;
if ( lstrlen(szCurrentDir) > 3 )
szFilename.sprintf(TEXT("%s\\%s\\%s"),szCurrentDir,szDirectory,Data.cFileName);
else
szFilename.sprintf(TEXT("%s%s\\%s"),szCurrentDir,szDirectory,Data.cFileName);
AddMatchFile(ppHead,szFilename);
}
}
}
while ( FindNextFile(hFile,&Data) );
FindClose(hFile);
// Restore old directory
SetCurrentDirectory(szCurrentDir);
}
CSTRING CShimWizard::ShortFile(CSTRING & szStr)
{
LPTSTR szTemp = szStr;
CSTRING szRet;
LPTSTR szWalk = szTemp;
while ( 0 != *szWalk ) {
if ( TEXT('\\') == *szWalk )
szTemp = szWalk+1;
++szWalk;
}
szRet = szTemp;
return szRet;
}
void CShimWizard::GrabMatchingInfo(void)
{
PMATCHENTRY pHead = NULL;
// Delete any matching info which might have already been bound to the record.
PDBENTRY pEntry = m_Record.pEntries;
PDBENTRY pPrev = m_Record.pEntries;
while ( NULL != pEntry ) {
PDBENTRY pHold = pEntry->pNext;
if ( ENTRY_MATCH == pEntry->uType ) {
delete pEntry;
if ( pEntry == m_Record.pEntries ) {
m_Record.pEntries = pHold;
pPrev = m_Record.pEntries;
} else
pPrev->pNext = pHold;
} else
pPrev = pEntry;
pEntry = pHold;
}
// Generate automated matching file information.
WalkDirectory(&pHead,TEXT("."),0);
// Now, take the first X entries and discard the rest.
int nCount = MAX_AUTO_MATCH;
PMATCHENTRY pWalk = pHead;
PMATCHENTRY pTerm = NULL;
while ( NULL != pWalk ) {
if ( 0 >= nCount ) {
PMATCHENTRY pHold = (PMATCHENTRY) pWalk->Entry.pNext;
delete pWalk;
pWalk = pHold;
} else {
--nCount;
if ( 1 == nCount )
pTerm = (PMATCHENTRY) pWalk->Entry.pNext;
pWalk = (PMATCHENTRY) pWalk->Entry.pNext;
}
}
if ( NULL != pTerm )
pTerm->Entry.pNext = NULL;
pWalk = pHead;
while ( NULL != pWalk ) {
GetFileAttributes(pWalk);
pWalk = (PMATCHENTRY)pWalk->Entry.pNext;
}
// Bind this data to the record.
pWalk = pHead;
// Find the end....
while ( NULL != pWalk && NULL != pWalk->Entry.pNext ) {
PMATCHENTRY pHold = (PMATCHENTRY) pWalk->Entry.pNext;
GetFileAttributes(pWalk);
if ( !InsertMatchingInfo(pWalk) )
delete pWalk;
pWalk = pHold;
}
}
BOOL CShimWizard::InsertMatchingInfo(PMATCHENTRY pNew)
{
PDBENTRY pWalk = m_Record.pEntries;
PDBENTRY pHold;
while ( NULL != pWalk ) {
if ( ENTRY_MATCH == pWalk->uType ) {
PMATCHENTRY pThis = (PMATCHENTRY) pWalk;
if ( pThis->szMatchName == pNew->szMatchName )
return FALSE;
if ( 0 < lstrcmpi(pThis->szMatchName,pNew->szMatchName) )
break;
}
pHold = pWalk;
pWalk = pWalk->pNext;
}
if ( pWalk == m_Record.pEntries ) {
pNew->Entry.pNext = m_Record.pEntries;
m_Record.pEntries = (PDBENTRY) pNew;
} else {
pNew->Entry.pNext = pWalk;
pHold->pNext = (PDBENTRY) pNew;
}
return TRUE;
}
INT_PTR CALLBACK
EditCmdLineDlgProc(
HWND hdlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
/*++
EditCmdLineDlgProc
Description: Handles messages for the edit control.
--*/
{
int wCode = LOWORD(wParam);
int wNotifyCode = HIWORD(wParam);
switch (uMsg) {
case WM_INITDIALOG:
{
SendMessage(
GetDlgItem(hdlg,IDC_SHIM_CMD_LINE), // handle to destination window
EM_LIMITTEXT, // message to send
(WPARAM) 256, // text length
(LPARAM) 0
);
SHAutoComplete(GetDlgItem(hdlg,IDC_SHIM_CMD_LINE), AUTOCOMPLETE);
PSHIMENTRY pShimEntry;
pShimEntry = (PSHIMENTRY)lParam;
SetWindowLongPtr(hdlg, DWLP_USER, lParam);
SetDlgItemText(hdlg, IDC_SHIM_NAME, pShimEntry->szShimName);
if ( pShimEntry->szCmdLine.Length() > 0 ) {
SetDlgItemText(hdlg, IDC_SHIM_CMD_LINE, pShimEntry->szCmdLine);
}
break;
}
case WM_COMMAND:
switch (wCode) {
case IDOK:
{
PSHIMENTRY pShimEntry;
TCHAR szCmdLine[1024] = _T("");
pShimEntry = ( PSHIMENTRY)GetWindowLongPtr(hdlg, DWLP_USER);
GetDlgItemText(hdlg, IDC_SHIM_CMD_LINE, szCmdLine, sizeof(szCmdLine)/sizeof(TCHAR));
if (*szCmdLine != 0) {
pShimEntry->szCmdLine = szCmdLine;
} else {
pShimEntry->szCmdLine.Release();
}
EndDialog(hdlg, TRUE);
break;
}
case IDCANCEL:
EndDialog(hdlg, FALSE);
break;
default:
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
void SelectShims_TreeDoubleClicked(HWND hDlg)
{
HWND hTree = GetDlgItem(hDlg,IDC_SHIMLIST);
HTREEITEM hItem;
TVITEM tvi;
hItem = TreeView_GetSelection(hTree);
if (hItem == NULL) return;
tvi.hItem = hItem;
tvi.mask = TVIF_HANDLE | TVIF_PARAM;
TreeView_GetItem(hTree, &tvi);
PSHIMENTRY pEntry = (PSHIMENTRY) tvi.lParam;
///////
if (DialogBoxParam(g_hInstance,
MAKEINTRESOURCE(IDD_CMD_LINE),
hDlg,
EditCmdLineDlgProc,
(LPARAM)pEntry)) {
TCHAR szText[1024];
tvi.mask = TVIF_HANDLE | TVIF_TEXT;
if ( pEntry->szCmdLine.Length() == 0 ) {
tvi.pszText = pEntry->szShimName;
} else {
wsprintf(szText, _T("%s - (%s)"), (LPCTSTR)pEntry->szShimName, (LPCTSTR)pEntry->szCmdLine);
tvi.pszText = szText;
}
TreeView_SetItem(hTree, &tvi);
}
///////
}//void SelectShims_TreeDoubleClicked(HWND hDlg)