📄 crashfinderdoc.cpp
字号:
LPTSTR szFileTitle = new TCHAR[ MAXFILEOPENSIZE ] ;
szFileTitle[ 0 ] = _T ( '\0' ) ;
cFD.m_ofn.lpstrFileTitle = szFileTitle ;
cFD.m_ofn.nMaxFileTitle = MAXFILEOPENSIZE ;
// Prompt the user.
if ( IDOK == cFD.DoModal ( ) )
{
// Loop through get each file.
CString sFinalList ;
CString sCurr ;
POSITION pos = cFD.GetStartPosition ( ) ;
while ( NULL != pos )
{
// Get the file name.
sCurr = cFD.GetNextPathName ( pos ) ;
sCurr.MakeUpper();
// Allocate the individual file information.
CBinaryImage * pImage = new CBinaryImage ( sCurr ) ;
// Only do the work if the image is valid.
if ( TRUE == pImage->IsValidImage ( ) )
{
// Load and show the image.
if ( FALSE == LoadAndShowImage ( pImage ) )
{
delete pImage ;
bRet = FALSE ;
}
else
{
// Load this image 's dlls
CMapStringToPtr moduleList ;
CString strDllImageName ;
LPVOID pPtr ;
if ( TRUE == pImage->GetModules ( sCurr ,
moduleList ) )
{
// GetModules will add sCurr into the moduleList
// for ensuring sCurr will not be reload later.
// remove it here
moduleList.RemoveKey ( sCurr ) ;
POSITION mlPos=moduleList.GetStartPosition ( ) ;
while ( NULL != mlPos )
{
moduleList.GetNextAssoc ( mlPos ,
strDllImageName ,
pPtr );
CBinaryImage* pDllImage =
new CBinaryImage(strDllImageName);
// Load and show the image. Note that I
// will not show any message boxes for
// duplicate items here.
if ( FALSE == LoadAndShowImage ( pDllImage ,
TRUE ,
TRUE ))
{
delete pDllImage ;
//bRet = FALSE ;
}
}
}
}
}
else
{
delete pImage ;
bRet = FALSE ;
}
}
}
else
{
bRet = FALSE ;
}
// Get rid of the memory we allocated for the file buffer.
delete szFileName ;
delete szFileTitle ;
return ( bRet ) ;
}
void CCrashFinderDoc :: OnEditRemoveImage ( )
{
ASSERT ( this ) ;
ASSERT ( NULL != m_pcTreeControl ) ;
// A general scratch buffer.
CString sMsg ;
// Make sure something is selected.
HTREEITEM hItem = m_pcTreeControl->GetSelectedItem ( ) ;
ASSERT ( NULL != hItem ) ;
// Get the CBinaryImage out of the tree node extra data.
CBinaryImage * pImage =
(CBinaryImage *)m_pcTreeControl->GetItemData ( hItem ) ;
ASSERT ( NULL != pImage ) ;
if ( NULL == pImage )
{
VERIFY ( sMsg.LoadString ( IDS_CATASTROPHICFAILURE ) ) ;
AfxMessageBox ( sMsg ) ;
return ;
}
// Am I supposed to confirm deletions?
CCrashFinderApp * pApp = (CCrashFinderApp *)AfxGetApp ( ) ;
ASSERT ( NULL != pApp ) ;
if ( TRUE == pApp->ConfirmDeletions ( ) )
{
sMsg.FormatMessage ( IDS_CONFIRMREMOVE ,
pImage->GetFullName ( ) ) ;
if ( IDNO == AfxMessageBox ( sMsg , MB_YESNO ) )
{
// Get out now.
return ;
}
}
// Loop through each item in the data array until I find this item.
int iCount = m_cDataArray.GetSize ( ) ;
int iIndex = 0 ;
for ( ; iIndex < iCount ; iIndex++ )
{
if ( pImage == m_cDataArray[ iIndex ] )
{
break ;
}
}
ASSERT ( iIndex < iCount ) ;
if ( iIndex == iCount )
{
VERIFY ( sMsg.LoadString ( IDS_CATASTROPHICFAILURE ) ) ;
AfxMessageBox ( sMsg ) ;
return ;
}
// Remove this image from the symbol engine.
BOOL bRet;
if ( TRUE == pImage->GetExtraData ( ) )
{
bRet= m_cSymEng.SymUnloadModule ( pImage->GetLoadAddress ( ) );
}
// Remove this item from the data structure.
delete pImage ;
m_cDataArray.RemoveAt ( iIndex ) ;
// Now remove this item from the tree.
bRet = m_pcTreeControl->DeleteItem ( hItem ) ;
ASSERT ( TRUE == bRet ) ;
// Set the selected item to the top item in the list.
hItem = m_pcTreeControl->GetRootItem ( ) ;
if ( NULL != hItem )
{
m_pcTreeControl->SelectItem ( hItem ) ;
}
// Mark the document as dirty.
SetModifiedFlag ( ) ;
}
void CCrashFinderDoc :: OnEditImageProperties ( )
{
ASSERT ( this ) ;
// Make sure something is selected.
HTREEITEM hItem = m_pcTreeControl->GetSelectedItem ( ) ;
ASSERT ( NULL != hItem ) ;
// Get the CBinaryImage out of the tree node extra data.
CBinaryImage * pImage =
(CBinaryImage *)m_pcTreeControl->GetItemData ( hItem ) ;
if ( NULL == pImage )
{
//Get the parent item then.
hItem = m_pcTreeControl->GetParentItem ( hItem ) ;
pImage = (CBinaryImage *)m_pcTreeControl->GetItemData ( hItem );
ASSERT ( NULL != pImage ) ;
}
// Make a copy of the binary image so I don't screw anything up.
CBinaryImage cTemp ( *pImage ) ;
// Now ask the CBinaryImage to take care of it's own properties.
// However, to make sure that the user does not accidentally cause
// a load address conflict, I watch the new value and make sure not
// to let it happen.
DWORD dwOldAddr = cTemp.GetLoadAddress ( ) ;
if ( TRUE == cTemp.SetProperties ( ) )
{
BOOL bGood = FALSE ;
do
{
int iIndex ;
if ( FALSE ==
IsConflictingLoadAddress(cTemp.GetLoadAddress ( ),
iIndex ))
{
bGood = TRUE ;
break ;
}
else
{
// Force the old address back and see if the user wants
// to reset the properties.
CString sMsg ;
sMsg.FormatMessage
( IDS_DUPLICATELOADADDR ,
cTemp.GetFullName ( ) ,
((CBinaryImage*)m_cDataArray[iIndex])->GetFullName());
if ( IDYES == AfxMessageBox ( sMsg , MB_YESNO ) )
{
cTemp.SetLoadAddress ( dwOldAddr ) ;
if ( FALSE == cTemp.SetProperties ( ) )
{
break ;
}
}
else
{
break ;
}
}
} while ( FALSE == bGood ) ;
// If everything is copacetic, do the actual change.
if ( TRUE == bGood )
{
BOOL bRet ;
BOOL bOriginalGoodLoad = pImage->GetExtraData ( ) ;
// Remove this image from the symbol engine if they were
// loaded in the first place.
if ( TRUE == pImage->GetExtraData ( ) )
{
bRet =
m_cSymEng.SymUnloadModule(pImage->GetLoadAddress());
ASSERT ( FALSE != bRet ) ;
}
// Overwrite the item with the new data.
*pImage = cTemp ;
// Reload the symbol information with the new base address.
bRet =
m_cSymEng.SymLoadModule(NULL ,
(PSTR)(LPCSTR)pImage->GetFullName(),
NULL ,
pImage->GetLoadAddress ( ) ,
0 );
ASSERT ( FALSE != bRet ) ;
// Set the item image based on how the symbol load went.
int iState = STATE_NOTVALID ;
if ( FALSE != bRet )
{
// Set the extra data value to show the symbol load.
pImage->SetExtraData ( TRUE ) ;
iState = STATE_VALIDATED ;
}
else
{
// No symbols loaded.
pImage->SetExtraData ( FALSE ) ;
}
m_pcTreeControl->SetItemImage ( hItem , iState , iState ) ;
bRet = m_cTreeDisplay.UpdateImageStats ( hItem ,
pImage ,
bOriginalGoodLoad);
ASSERT ( TRUE == bRet ) ;
}
}
}
void CCrashFinderDoc :: OnUpdateEditRemoveImage ( CCmdUI * pCmdUI )
{
ASSERT ( this ) ;
// You can only remove an item when the tree view is active.
CTreeView * pView = (CTreeView *)GetCurrentView ( ) ;
BOOL bEnable = FALSE ;
if ( pView == m_pcTreeView )
{
if ( m_pcTreeControl->GetCount ( ) > 0 )
{
bEnable = TRUE ;
}
}
pCmdUI->Enable ( bEnable ) ;
}
void CCrashFinderDoc :: OnUpdateEditImageProperties ( CCmdUI * pCmdUI )
{
ASSERT ( this ) ;
// 1. The tree view has to be active.
// 2. An item has to be selected.
// 3. That item must be properly loaded.
CTreeView * pView = (CTreeView *)GetCurrentView ( ) ;
BOOL bEnable = FALSE ;
if ( pView == m_pcTreeView )
{
HTREEITEM hItem = m_pcTreeControl->GetSelectedItem ( ) ;
if ( NULL != hItem )
{
CBinaryImage * pImage = (CBinaryImage *)
m_pcTreeControl->GetItemData ( hItem );
if ( NULL == pImage )
{
hItem = m_pcTreeControl->GetParentItem ( hItem ) ;
pImage = (CBinaryImage *)
m_pcTreeControl->GetItemData ( hItem );
if ( NULL != pImage )
{
bEnable = pImage->GetExtraData ( ) ;
}
}
else
{
bEnable = pImage->GetExtraData ( ) ;
}
}
}
pCmdUI->Enable ( bEnable ) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -