Windows2000/private/windbg64/windbg/wrkspace.c
2020-09-30 17:12:32 +02:00

2249 lines
54 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
WrkSpace.c
Abstract:
This module contains the support for Windbg's workspaces.
Author:
Ramon J. San Andres (ramonsa) 07-July-1992
Griffith Wm. Kadnier (v-griffk) 15-Jan-1993
Carlos Klapp (a-caklap) 15-July-98
Environment:
Win32, User Mode
--*/
#include "precomp.h"
#pragma hdrstop
#include "dbugexcp.h"
#include "include\cntxthlp.h"
// Variables
char SrcFileDirectory[ MAX_PATH ];
char ExeFileDirectory[ MAX_PATH ];
char DocFileDirectory[ MAX_PATH ];
char UserDllDirectory[ MAX_PATH ];
CFinal_Windbg_WKSP g_Windbg_WkSp;
CGlobalPreferences_WKSP &g_contGlobalPreferences_WkSp = g_Windbg_WkSp.m_contGlobalPreferences;
CAll_Exceptions_WKSP &g_contExceptionsMasterList_WkSp = g_contGlobalPreferences_WkSp.m_dynacontAllExceptionsMasterList;
CUser_WM_Messages_WKSP &g_contUser_WM_Messages_WkSp = g_contGlobalPreferences_WkSp.m_contUser_WM_Messages;
CAll_TLs_WKSP &g_dynacontAll_TLs_WkSp = g_contGlobalPreferences_WkSp.m_dynacont_All_TLs;
CAll_Debuggees_WKSP &g_contAllDebuggees_WkSp = g_Windbg_WkSp.m_contAllDebuggees;
CDebuggee_WKSP &g_contDebuggee_WkSp = g_contAllDebuggees_WkSp.m_contDebuggee;
CWorkSpace_WKSP &g_contWorkspace_WkSp = g_contDebuggee_WkSp.m_contWorkSpace;
CAll_Exceptions_WKSP &g_dynacontAllExceptions_WkSp = g_contWorkspace_WkSp.m_dynacontAllExceptions;
CPaths_WKSP &g_contPaths_WkSp = g_contWorkspace_WkSp.m_contPaths;
CKernel_Debugging_WKSP &g_contKernelDbgPreferences_WkSp = g_contWorkspace_WkSp.m_contKernelDbgPreferences;
CAllWindowLayouts_WKSP &g_contAllWinLayouts_WkSp = g_Windbg_WkSp.m_contAllWinLayouts;
CWinLayout_WKSP &g_contWinLayout_WkSp = g_contAllWinLayouts_WkSp.m_contWinLayout;
CIndivWinLayout_WKSP &g_contFrameWindow = g_contWinLayout_WkSp.m_contFrameWindows;
CAllChildWindows_WKSP &g_dynacontAllChildWindows = g_contWinLayout_WkSp.m_dynacontChildWindows;
BOOL
WKSP_Initialize()
{
// We initialize it this so that its parent is 'g_Windbg_WkSp'
// and that it has a name, but we want to be able to load/save all
// of the debuggees and workspaces separately of from the one the debugger
// is using.
// We do it here so that we
g_contDebuggee_WkSp.SetRegistryName(CBase_Windbg_WKSP::m_pszNoProgramLoaded);
g_contWorkspace_WkSp.SetRegistryName(CBase_Windbg_WKSP::m_pszUntitledWorkSpaceName);
g_contWinLayout_WkSp.SetRegistryName(CBase_Windbg_WKSP::m_pszDefaultWinLayout);
// Make sure the mirrored flags are correctly set.
g_Windbg_WkSp.SetMirrorFlagForChildren();
return TRUE;
}
// Function prototypes
INT_PTR
CALLBACK
DlgProc_WindowLayout_SaveAs(
HWND hDlg,
UINT msg,
WPARAM wParam,
LPARAM lParam
);
INT_PTR
CALLBACK
DlgProc_WindowLayout_Manage(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
INT_PTR
CALLBACK
DlgProc_WorkSpace_Manage(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
INT_PTR
CALLBACK
DlgProc_WorkSpace_SaveAs(
HWND hDlg,
UINT msg,
WPARAM wParam,
LPARAM lParam
);
// Code
BOOL
SetTransportLayer(
PSTR pszTL_Name,
CAll_TLs_WKSP * pCAll_TLs_WrkSpc
)
/*++
Routine Description:
Sets the name of the selected transport and warns user
if pipes are not supported on this platform.
Arguments:
pszTL_Name - Name of the selected transport
--*/
{
Assert(pszTL_Name);
Assert(pCAll_TLs_WrkSpc);
// Make sure that we warn the user that he is using a transport layer
// that requires named pipes and they are not supported on win9x
static OSVERSIONINFO osi = {0};
if (0 == osi.dwOSVersionInfoSize) {
osi.dwOSVersionInfoSize = sizeof(osi);
Assert(GetVersionEx(&osi));
}
TListEntry<CIndiv_TL_WKSP *> * pContEntry =
pCAll_TLs_WrkSpc->m_listConts.
Find(pszTL_Name, WKSP_Generic_CmpRegName);
if (!pContEntry) {
return FALSE;
}
CIndiv_TL_WKSP * pIndTl = pContEntry->m_tData;
AssertType(*pIndTl, CIndiv_TL_WKSP);
if (VER_PLATFORM_WIN32_NT != osi.dwPlatformId && !_stricmp(pIndTl->m_pszDll, "tlpipe.dll")) {
InformationBox(ERR_Pipes_Not_Supported_On_Win9x, pIndTl->m_pszDescription, "tlpipe.dll");
}
if (g_contWorkspace_WkSp.m_pszSelectedTL) {
free(g_contWorkspace_WkSp.m_pszSelectedTL);
}
g_contWorkspace_WkSp.m_pszSelectedTL = _strdup(pszTL_Name);
return TRUE;
} /* SetDllKey() */
BOOL
ValidateAllTransportLayers(
HWND hwndParent,
CAll_TLs_WKSP * pCAll_TLs_WrkSpc
)
/*++
Routine Description:
Verify that all of the TLs are valid.
Arguments:
hDlg - Supplies window handle for dialog
Returns:
TRUE if DLL is valid or user said use it anyway; FALSE otherwise
--*/
{
HMODULE hDll;
CIndiv_TL_WKSP * pIndTl;
TListEntry<CIndiv_TL_WKSP *> * pContEntry = pCAll_TLs_WrkSpc->m_listConts.FirstEntry();
for (; pContEntry != pCAll_TLs_WrkSpc->m_listConts.Stop();
pContEntry = pContEntry->Flink) {
pIndTl = pContEntry->m_tData;
AssertType(*pIndTl, CIndiv_TL_WKSP);
if (hDll = LoadHelperDll(pIndTl->m_pszDll, "TL", FALSE)) {
FreeLibrary(hDll);
} else {
int nRes = VarMsgBox(hwndParent,
DBG_Bad_DLL_YESNO,
MB_YESNO
| MB_ICONQUESTION
| (NULL == hwndParent ? MB_TASKMODAL : 0),
pIndTl->m_pszDescription ? pIndTl->m_pszDescription : ""
);
if (nRes == IDNO) {
return FALSE;
}
}
}
return TRUE;
}
BOOL
SYSetProfileString(
LPCTSTR szName,
LPCTSTR szValue
)
{
return FALSE;
}
BOOL
SYGetProfileString(
LPCTSTR szName,
LPTSTR szValue,
ULONG cbValue,
ULONG * pcbRet
)
{
ULONG cb;
cb = ModListGetSearchPath(NULL, cbValue);
if (cb <= cbValue) {
*pcbRet = ModListGetSearchPath(szValue, cbValue);
return TRUE;
}
*pcbRet = cb;
return FALSE;
}
BOOL
Get_TL_ModuleInfo(
TCHAR szModuleName[MAX_PATH],
TCHAR szParams[MAX_PATH]
)
{
PCTSTR pszTmp;
if (!szModuleName && !szParams) {
return FALSE;
}
if (szModuleName) {
pszTmp = g_Windbg_WkSp.GetSelected_TL_Dll_Name();
if (!pszTmp) {
return FALSE;
}
_tcscpy(szModuleName, pszTmp);
}
if (szParams) {
pszTmp = g_Windbg_WkSp.GetSelected_TL_Params();
if (!pszTmp) {
return FALSE;
}
_tcscpy(szParams, pszTmp);
}
return TRUE;
}
void
WKSPSetupTL(
HTL htl
)
{
TLSS tlss;
tlss.fRMAttached = FALSE;
tlss.fLoad = TRUE;
//tlss.lParam = 0;
tlss.pfnGetModuleInfo = Get_TL_ModuleInfo;
OSDTLSetup(htl, &tlss);
}
BOOL
Get_EM_ModuleInfo(
TCHAR szModuleName[MAX_PATH],
TCHAR szParams[MAX_PATH]
)
{
if (!szModuleName && !szParams) {
return FALSE;
}
// Get the module name
if (szModuleName) {
if (!g_contWorkspace_WkSp.m_bKernelDebugger) {
_tcscpy(szModuleName, _T("DM.DLL") );
} else {
switch (g_contKernelDbgPreferences_WkSp.m_mptPlatform) {
case mptix86:
_tcscpy(szModuleName, _T("DMKDX86.DLL ") );
break;
#if 0
case mptmips:
_tcscpy(szModuleName, _T("DMKDMIP.DLL ") );
break;
#endif
case mptdaxp:
_tcscpy(szModuleName, _T("DMKDALP.DLL ") );
break;
case mptia64:
_tcscpy(szModuleName, _T("DMKDI64.DLL ") );
break;
#if 0
case mptntppc:
_tcscpy(szModuleName, _T("DMKDPPC.DLL ") );
break;
#endif
default:
_tcscpy(szModuleName, _T("") );
// This should not have happened.
Assert(0);
}
}
}
// Get the parameters
if (szParams) {
if (!g_contWorkspace_WkSp.m_bKernelDebugger) {
_tcscpy(szParams, _T("") );
} else {
FormatKdParams(szParams);
}
}
return TRUE;
}
void
WKSPSetupEM(
HEM hem
)
{
EMSS emss;
emss.fLoad = TRUE;
emss.fSave = FALSE;
//emss.lParam = NULL;
emss.pfnGetModuleInfo = Get_EM_ModuleInfo;
OSDEMSetup(hem, &emss);
}
// External variables
extern char DebuggerName[];
extern LPSTR LpszCommandLine;
extern CXF CxfIp;
extern LPSTR LpszCommandLineTransportDll;
// External functions
extern HWND GetLocalHWND(void);
extern HWND GetFloatHWND(void);
extern HWND GetWatchHWND(void);
extern HWND GetCpuHWND(void);
extern HWND GetCallsHWND(void);
extern LRESULT SendMessageNZ (HWND,UINT,WPARAM,LPARAM);
// Global variables
BOOL bProgramLoaded = FALSE;
//char szCurrentWorkSpaceName[ MAX_PATH ];
//char szCurrentProgramName[ MAX_PATH ];
EXCEPTION_LIST *DefaultExceptionList = NULL;
// Root for windbg
CFinal_Windbg_WKSP::
CFinal_Windbg_WKSP()
{
m_CurrentExePath = _strdup(m_pszNoProgramLoaded);
}
CFinal_Windbg_WKSP::
~CFinal_Windbg_WKSP()
{
FREE_STR(m_CurrentExePath);
}
void
CFinal_Windbg_WKSP::
SetCurrentProgramName(
PCSTR pszProgPath
)
/*++
Description
Set the name of an executable and loads the appropriate workspace.
--*/
{
Assert(pszProgPath);
TCHAR szExe[_MAX_PATH];
// Store the complete path of the EXE so that it can be loaded
m_CurrentExePath = _strdup(pszProgPath);
// Get the name of the exe to use as the workspace key
_tsplitpath(pszProgPath, NULL, NULL, szExe, NULL);
// string is blank
if ( !*szExe ) {
return;
}
if ( !_tcsicmp(szExe, NT_ALT_KERNEL_NAME)
|| !_tcsicmp(szExe, NT_ALT_KRNLMP_NAME)
|| !_tcsicmp(szExe, NT_KERNEL_NAME)
|| !_tcsicmp(szExe, NT_KRNLMP_NAME)
) {
g_contWorkspace_WkSp.m_bKernelDebugger = TRUE;
}
if ( _tcsicmp(szExe, g_contDebuggee_WkSp.m_pszRegistryName) ) {
g_contDebuggee_WkSp.CloseRegistryKeys();
g_contDebuggee_WkSp.SetRegistryName(szExe);
}
}
void
CFinal_Windbg_WKSP::
SetCurrentWorkSpaceName(
PCSTR pszWkSpName
)
/*++
Description
Set the name of an executable and loads the appropriate workspace.
--*/
{
Assert(pszWkSpName);
PSTR pszTmp;
// Skip over white space and remove any trailing white space
pszWkSpName = CPSkipWhitespace(pszWkSpName);
pszTmp = _strdup(pszWkSpName);
CPRemoveTrailingWhitespace(pszTmp);
// string is blank
if ( !*pszTmp ) {
goto CLEANUP;
}
if ( _tcsicmp(pszTmp, g_contWorkspace_WkSp.m_pszRegistryName) ) {
g_contWorkspace_WkSp.CloseRegistryKeys();
g_contWorkspace_WkSp.SetRegistryName(pszTmp);
}
CLEANUP:
FREE_STR(pszTmp);
}
const char *
CFinal_Windbg_WKSP::
GetCurrentProgramName(
BOOL bReturnUntitled
)
/*++
Routine Description:
Returns current program name
Arguments:
bReturnUntitled -
If a program has been loaded:
The value does not matter and the name of the program is returned.
If a program is NOT loaded:
TRUE - the default name will be returned.
FALSE - NULL is returned.
Return Value:
LPSTR - Current program Name or NULL.
--*/
{
if ( _tcsicmp(m_CurrentExePath, m_pszNoProgramLoaded) ) {
// A program has been loaded
return m_CurrentExePath;
} else {
// No program loaded
if (bReturnUntitled) {
return m_pszNoProgramLoaded;
} else {
return NULL;
}
}
}
int
CFinal_Windbg_WKSP::
Save_WkSp_Prompt()
{
int nRes = IDNO;
BOOL bSave = FALSE;
if (!g_contGlobalPreferences_WkSp.m_bAlwaysSaveWorkspace) {
bSave = FALSE;
} else {
if (g_contGlobalPreferences_WkSp.m_bPromptBeforeSavingWorkspace) {
// Ask user whether to save or not
nRes = QuestionBox(DLG_AskToSaveWorkspace, MB_YESNOCANCEL);
bSave = (IDYES == nRes);
} else {
bSave = TRUE;
}
}
if (bSave) {
g_Windbg_WkSp.Save(FALSE, FALSE);
} else {
// Only save out the mirrored information.
g_Windbg_WkSp.Save(TRUE, FALSE);
}
return nRes;
}
void
CFinal_Windbg_WKSP::
SaveAs_WinLayout_Prompt()
{
INT_PTR nRes = StartDialog( DLG_WINDOW_LAYOUT_SAVEAS, DlgProc_WindowLayout_SaveAs );
if (-1 == nRes) {
PTSTR pszErr = WKSP_FormatLastErrorMessage();
if (!pszErr) {
pszErr = "Unable to obtain last error code.";
}
ErrorBox(ERR_Cannot_Create_Dlg, pszErr);
}
}
void
CFinal_Windbg_WKSP::
Manage_WinLayout_Prompt()
{
INT_PTR nRes = StartDialog( IDD_DLG_MNG_WINLAYOUT, DlgProc_WindowLayout_Manage );
if (-1 == nRes) {
PTSTR pszErr = WKSP_FormatLastErrorMessage();
if (!pszErr) {
pszErr = "Unable to obtain last error code.";
}
ErrorBox(ERR_Cannot_Create_Dlg, pszErr);
}
}
void
CFinal_Windbg_WKSP::
SaveAs_WkSp_Prompt()
{
INT_PTR nRes = StartDialog( DLG_WRKSPC_SAVEAS, DlgProc_WorkSpace_SaveAs );
if (-1 == nRes) {
PTSTR pszErr = WKSP_FormatLastErrorMessage();
if (!pszErr) {
pszErr = "Unable to obtain last error code.";
}
ErrorBox(ERR_Cannot_Create_Dlg, pszErr);
}
}
void
CFinal_Windbg_WKSP::
New_WkSp_Prompt(
BOOL bPrompt
)
{
Assert( ExitingDebugger || !(LptdCur && LptdCur->tstate == tsRunning));
if ( bPrompt ) {
if ( IDNO == QuestionBox(SYS_New_Workspace_Prompt, MB_YESNO) ) {
return;
}
}
CFinal_Windbg_WKSP * pTmp = new CFinal_Windbg_WKSP;
Duplicate(*pTmp);
delete(pTmp);
}
void
CFinal_Windbg_WKSP::
Manage_WkSp_Prompt()
{
INT_PTR nRes = StartDialog(IDD_DLG_MNG_WRKSPC, DlgProc_WorkSpace_Manage);
if (-1 == nRes) {
PTSTR pszErr = WKSP_FormatLastErrorMessage();
if (!pszErr) {
pszErr = "Unable to obtain last error code.";
}
ErrorBox(ERR_Cannot_Create_Dlg, pszErr);
}
}
CDebuggee_WKSP *
CFinal_Windbg_WKSP::
DoesDebuggeeExist(
LPSTR pszProgramName
)
/*++
Routine Description:
Determines if a workspace exists
Arguments:
pszProgramName - Supplies name of program. NULL for debugger default
WorkSpace - Supplies name of workspace. NULL ONLY for the
debugger default (NOT for program default)
NOTE: Either
Return Value:
BOOL - TRUE if default exists
--*/
{
Assert(pszProgramName);
// Find executable first
TListEntry<CDebuggee_WKSP *> * pDebuggee_ListEntry =
g_contAllDebuggees_WkSp.m_listConts.
Find(pszProgramName, WKSP_Generic_CmpRegName);
if (pDebuggee_ListEntry) {
// Found
Assert(pDebuggee_ListEntry->m_tData);
return pDebuggee_ListEntry->m_tData;
} else {
// Not found
return NULL;
}
}
CWorkSpace_WKSP *
CFinal_Windbg_WKSP::
DoesWorkSpaceExist(
CDebuggee_WKSP * pCDebuggee,
LPSTR pszWorkSpace
)
/*++
Routine Description:
Determines if a workspace exists
Arguments:
pszProgramName - Supplies name of program. NULL for debugger default
WorkSpace - Supplies name of workspace. NULL ONLY for the
debugger default (NOT for program default)
NOTE: Either
Return Value:
BOOL - TRUE if default exists
--*/
{
Assert(pCDebuggee);
Assert(pszWorkSpace);
Assert(*pszWorkSpace);
TListEntry<CWorkSpace_WKSP *> * pWorkSpace_ListEntry = pCDebuggee->
m_listConts.Find(pszWorkSpace, WKSP_Generic_CmpRegName);
if (pWorkSpace_ListEntry) {
// Found
return pWorkSpace_ListEntry->m_tData;
} else {
return NULL;
}
}
void
CFinal_Windbg_WKSP::
Save_File_MRU_List()
/*++
Routine Description:
Saves the MRU list to the registry.
Arguments:
Hkey - Supplies the registry key
MruName - Supplies the MRU name
WhatFile - Supplies the kind of file (Editor/Project)
Return Value:
BOOL - TRUE if MRU list loaded
--*/
{
/*
char *s;
ULONG i;
LPSTR List = NULL;
DWORD ListLength = 0;
BOOL Ok = TRUE;
// Get current MRU list
for ( i = nbFilesKept[ WhatFile ]; Ok && (i > 0); i-- ) {
Dbg(s = (LPSTR)GlobalLock( hFileKept[ WhatFile ][ i-1 ] ) );
Ok = AddToMultiString( &List, &ListLength, s );
Dbg(GlobalUnlock ( hFileKept[ WhatFile ][ i-1 ] ) == FALSE);
}
// Save the List in the registry
if ( Ok && List ) {
if ( RegSetValueEx(Hkey, MruName, 0, REG_MULTI_SZ, (PUCHAR) List, ListLength) != NO_ERROR ) {
Ok = FALSE;
}
}
if ( List ) {
DeallocateMultiString( List );
}
*/
}
void
CFinal_Windbg_WKSP::
Load_File_MRU_List()
/*++
Routine Description:
Loads an MRU list from the registry.
Arguments:
Hkey - Supplies the registry key
MruName - Supplies the MRU name
WhatFile - Supplies the kind of file (Editor/Project)
WhatMenu - Supplies the kind of menu
WhatPosition- Supplies the position
Return Value:
BOOL - TRUE if MRU list loaded
--*/
{
/*
LPSTR Name;
LPSTR List;
DWORD DataSize;
BOOL Ok = FALSE;
DWORD Next = 0;
if ( List = LoadMultiString( Hkey, MruName, &DataSize ) ) {
while ( Name = GetNextStringFromMultiString(List, DataSize, &Next ) ) {
// Add the entries to the MRU list
InsertKeptFileNames( (WORD)WhatFile, (int)WhatMenu, Name );
}
Ok = TRUE;
DeallocateMultiString( List );
}
return Ok;
*/
}
PCSTR
CFinal_Windbg_WKSP::
GetSelected_TL_Dll_Name()
{
// Make sure that the TL exists
if (!g_contWorkspace_WkSp.m_pszSelectedTL) {
return NULL;
} else {
Assert(*g_contWorkspace_WkSp.m_pszSelectedTL);
// Find the specified TL
TListEntry<CIndiv_TL_WKSP *> * pContEntry
= g_dynacontAll_TLs_WkSp.m_listConts.
Find(g_contWorkspace_WkSp.m_pszSelectedTL, WKSP_Generic_CmpRegName);
if (!pContEntry) {
return NULL;
} else {
CIndiv_TL_WKSP * pTL = pContEntry->m_tData;
Assert(pTL);
return pTL->m_pszDll;
}
}
}
PCSTR
CFinal_Windbg_WKSP::
GetSelected_TL_Params()
{
// Make sure that the TL exists
if (!g_contWorkspace_WkSp.m_pszSelectedTL) {
return NULL;
} else {
Assert(*g_contWorkspace_WkSp.m_pszSelectedTL);
// Find the specified TL
TListEntry<CIndiv_TL_WKSP *> * pContEntry
= g_dynacontAll_TLs_WkSp.m_listConts.
Find(g_contWorkspace_WkSp.m_pszSelectedTL, WKSP_Generic_CmpRegName);
if (!pContEntry) {
return NULL;
} else {
CIndiv_TL_WKSP * pTL = pContEntry->m_tData;
Assert(pTL);
return pTL->m_pszParams;
}
}
}
PSTR
CFinal_Windbg_WKSP::
GetDefaultWorkSpaceForDebuggee(
PSTR pszDebuggeeName
)
{
return NULL;
}
BOOL
CFinal_Windbg_WKSP::
ShuttingDown()
{
Assert( ExitingDebugger || !(LptdCur && LptdCur->tstate == tsRunning));
BOOL bCancel = TRUE;
Assert( ExitingDebugger || !(LptdCur && LptdCur->tstate == tsRunning));
bCancel = IDCANCEL == Save_WkSp_Prompt();
return bCancel;
}
void
CFinal_Windbg_WKSP::
Restore(
BOOL bOnlyItems
)
{
CBase_Windbg_WKSP::Restore(bOnlyItems);
LoadAllWindows();
// Put the wrkspc info into the debugger
// Set the root name mappings
SetRootNameMappings(g_contPaths_WkSp.m_pszRootMappingPairs,
WKSP_MultiStrSize(g_contPaths_WkSp.m_pszRootMappingPairs)
);
// Breakpoints
if (g_contWorkspace_WkSp.m_pszBreakPoints) {
PTSTR pszBrkPt = g_contWorkspace_WkSp.m_pszBreakPoints;
for(; *pszBrkPt; pszBrkPt += _tcslen(pszBrkPt) +1) {
BPSTATUS bpstatus;
BOOL bDisabled;
HBPT hBpt;
Assert(_tcslen(pszBrkPt) >= 3);
bDisabled = (_T('D') == *pszBrkPt);
// skip over the enabled and instantiated chars
pszBrkPt += 3;
bpstatus = BPParse( &hBpt, pszBrkPt, NULL, NULL,
LppdCur ? LppdCur->hpid : 0);
if ((BPNOERROR == bpstatus) && BPNOERROR == BPAddToList(hBpt, -1)) {
if ( bDisabled ) {
BPDisable(hBpt);
} else if ( DebuggeeActive() ) {
BPBindHbpt( hBpt, NULL );
}
Dbg(BPCommit() == BPNOERROR);
}
}
}
// Exceptions
{
EXCEPTION_LIST *pExceptionList = NULL;
TListEntry<CIndiv_Excep_WKSP *> * pContEntry;
// Add exceptions from the master list
pContEntry = g_contExceptionsMasterList_WkSp.m_listConts.FirstEntry();
for (; pContEntry != g_contExceptionsMasterList_WkSp.m_listConts.Stop();
pContEntry = pContEntry->Flink) {
if (!g_dynacontAllExceptions_WkSp.m_listConts.
Find(pContEntry->m_tData->m_pszRegistryName, WKSP_Generic_CmpRegName)) {
// This exception wasn't in this list. Add it.
CIndiv_Excep_WKSP * pIndExc = new CIndiv_Excep_WKSP;
pIndExc->Init(&g_dynacontAllExceptions_WkSp, NULL);
// Duplicate will copy all of the necessary values
pIndExc->Duplicate(*pContEntry->m_tData);
pIndExc->m_bMirror = g_dynacontAllExceptions_WkSp.m_bMirror;
}
}
// Add all exception to the list
pContEntry = g_dynacontAllExceptions_WkSp.m_listConts.FirstEntry();
for (; pContEntry != g_dynacontAllExceptions_WkSp.m_listConts.Stop();
pContEntry = pContEntry->Flink) {
CIndiv_Excep_WKSP * pIndExc = pContEntry->m_tData;
EXCEPTION_LIST * pException = (EXCEPTION_LIST *)
calloc( sizeof( EXCEPTION_LIST), 1 );
pException->dwExceptionCode = strtoul(pIndExc->m_pszRegistryName, NULL, 16);
pException->efd = (_EXCEPTION_FILTER_DEFAULT) pIndExc->m_dwAction;
if (pIndExc->m_pszName) {
pException->lpName = _strdup(pIndExc->m_pszName);
}
if (pIndExc->m_pszFirstCmd) {
pException->lpCmd = _strdup(pIndExc->m_pszFirstCmd);
}
if (pIndExc->m_pszSecondCmd) {
pException->lpCmd2 = _strdup(pIndExc->m_pszSecondCmd);
}
InsertException( &pExceptionList, pException );
}
// If there was an error getting the new list, let's just use
// the current list. Potential errors can arrive from not being
// able to parse the exception string, or bad data in the registry
if (pExceptionList) {
// Do we have a valid exception?
if (0 == pExceptionList->dwExceptionCode || 0 == pExceptionList->next) {
// Bad exception
free(pExceptionList);
pExceptionList = NULL;
} else {
// Now that we have a new list, let's update the default one
// Free current default exception list.
while( DefaultExceptionList ) {
EXCEPTION_LIST *pException = DefaultExceptionList;
DefaultExceptionList = DefaultExceptionList->next;
FREE_STR( pException->lpName );
FREE_STR( pException->lpCmd );
FREE_STR( pException->lpCmd2 );
ZeroMemory(pException, sizeof(EXCEPTION_LIST));
free( pException );
}
DefaultExceptionList = pExceptionList;
// The exception list may already be in use by process 0. This scenario
// occurs when you attach to a process, then load a workspace. We have
// to reset the exception lists for the all of the processes
if (DebuggeeActive()) {
LPPD lppdTmp = GetLppdHead();
Assert(lppdTmp != NULL);
for ( ;lppdTmp != NULL; lppdTmp = lppdTmp->lppdNext) {
if (lppdTmp->pstate == psDestroyed) {
continue;
}
ClearProcessExceptions(lppdTmp);
SetProcessExceptions(lppdTmp);
}
}
}
}
}
}
void
CFinal_Windbg_WKSP::
Save(
BOOL bOnlySaveMirror,
BOOL bOnlyItems
)
{
// Breakpoints
{
_TCHAR sz[2000]; // This should be big enough to hold any breakpoint
HBPT hBpt = NULL;
FREE_STR(g_contWorkspace_WkSp.m_pszBreakPoints);
Dbg(BPNextHbpt(&hBpt, bptNext) == BPNOERROR);
while (hBpt != NULL) {
Dbg(BPFormatHbpt( hBpt, sz, sizeof(sz),
BPFCF_WNDPROC | BPFCF_WRKSPACE ) == BPNOERROR);
WKSP_AppendStrToMultiStr(g_contWorkspace_WkSp.m_pszBreakPoints, sz);
Dbg(BPNextHbpt(&hBpt, bptNext) == BPNOERROR);
}
}
// Exceptions
{
// Note that we only save one exception list: The default
// exception list. This exception list corresponds to
// process 0. If other processes have different exception
// lists, they will be lost.
EXCEPTION_LIST *pExceptionList = DefaultExceptionList;
//TListEntry<CIndiv_Excep_WKSP *> * pContEntry;
// Delete the old list of exceptions
g_dynacontAllExceptions_WkSp.m_listConts.ClearList();
// If we don't have an exception list, we must load the EM and
// initialize the default exception list.
if ( !LppdCur && !DefaultExceptionList ) {
if ( GetDefaultExceptionList() ) {
pExceptionList = DefaultExceptionList;
}
}
for (; pExceptionList; pExceptionList = pExceptionList->next) {
// Rebuild the list
_TCHAR szRegName[9] = {0};
CIndiv_Excep_WKSP * pIndExc;
pIndExc = new CIndiv_Excep_WKSP();
pIndExc->Init(&g_dynacontAllExceptions_WkSp, NULL);
_ultot(pExceptionList->dwExceptionCode, szRegName, 16);
Assert(_tcslen(szRegName) * sizeof(_TCHAR) < sizeof(szRegName));
pIndExc->SetRegistryName(_tcsdup(szRegName));
pIndExc->m_dwAction = pExceptionList->efd;
if (pExceptionList->lpName) {
pIndExc->m_pszName = _strdup(pExceptionList->lpName);
}
if (pExceptionList->lpCmd) {
pIndExc->m_pszFirstCmd = _strdup(pExceptionList->lpCmd);
}
if (pExceptionList->lpCmd2) {
pIndExc->m_pszSecondCmd = _strdup(pExceptionList->lpCmd2);
}
// Make sure the main exception list contains any new exceptions
if (!g_contExceptionsMasterList_WkSp.m_listConts.
Find(pIndExc->m_pszRegistryName, WKSP_Generic_CmpRegName)) {
// This exception wasn't in this list. Add it.
CIndiv_Excep_WKSP * pIndExcCopy = new CIndiv_Excep_WKSP;
// Add it to the list
pIndExcCopy->Init(&g_contExceptionsMasterList_WkSp, NULL);
// Duplicate will copy all of the necessary values
pIndExcCopy->Duplicate(*pIndExc);
pIndExcCopy->m_bMirror = g_contExceptionsMasterList_WkSp.m_bMirror;
}
}
}
SaveAllWindows();
CBase_Windbg_WKSP::Save(bOnlySaveMirror, bOnlyItems);
}
HTREEITEM
AddItemToTree(
HWND hwndTV,
LPSTR lpszItem,
int nLevel,
LPARAM lparam
)
/*++
Description
Adds items to a tree view control.
Arguments
hwndTV - handle to the tree view control.
lpszItem - text of the item to add.
nLevel - level at which to add the item. Only levels 1-3 are supported
1 - root
2 - level 1
3 - level 2
Returns
the handle to the newly added item.
--*/
{
TVITEM tvi;
TVINSERTSTRUCT tvins;
static HTREEITEM hPrev = (HTREEITEM) TVI_FIRST;
static HTREEITEM hPrevRootItem = NULL;
static HTREEITEM hPrevLev2Item = NULL;
HTREEITEM hti;
tvi.mask = TVIF_TEXT | TVIF_PARAM;
// Set the text of the item.
tvi.pszText = lpszItem;
tvi.cchTextMax = lstrlen(lpszItem);
tvi.lParam = (LPARAM) lparam;
tvins.item = tvi;
tvins.hInsertAfter = hPrev;
// Set the parent item based on the specified level.
if (nLevel == 1) {
tvins.hParent = TVI_ROOT;
} else if (nLevel == 2) {
tvins.hParent = hPrevRootItem;
} else {
tvins.hParent = hPrevLev2Item;
}
// Add the item to the tree view control.
hPrev = (HTREEITEM) SendMessage(hwndTV,
TVM_INSERTITEM,
0,
(LPARAM) (LPTVINSERTSTRUCT) &tvins);
// Save the handle to the item.
if (nLevel == 1) {
hPrevRootItem = hPrev;
} else if (nLevel == 2) {
hPrevLev2Item = hPrev;
}
return hPrev;
}
void
PopulateWindowLayoutTree(
HWND hwndTree
)
{
HKEY hkey;
CRegEntry *pRegEntry;
CRegEntry *pWS_RegEntry; // work space
TList< CRegEntry* > list;
// Delete the contents of the tree
TreeView_DeleteAllItems(hwndTree);
hkey = g_contAllWinLayouts_WkSp.GetRegistryKey();
if ( !hkey ) {
return;
}
if ( !WKSP_RegEnumerate(hkey, &list, NULL, TRUE) ) {
return;
}
while ( !list.IsEmpty() ) {
pRegEntry = list.GetHeadData();
list.RemoveHead();
// Add item at the root level
AddItemToTree(hwndTree,
pRegEntry->m_pszName,
1,
NULL
);
// Delete it without cleaning up since we'll do this manually
pRegEntry->CleanUp();
delete pRegEntry;
}
}
void
PopulateExeWorkspaceTree(
HWND hwndTree
)
{
HKEY hkey;
CRegEntry *pExe_RegEntry;
CRegEntry *pWS_RegEntry; // work space
TList< CRegEntry* > listExes;
TList< CRegEntry* > listWrkSpcs;
// Delete the contents of the tree
TreeView_DeleteAllItems(hwndTree);
hkey = g_contAllDebuggees_WkSp.GetRegistryKey();
if ( !hkey ) {
return;
}
if ( !WKSP_RegEnumerate(hkey, &listExes, NULL, TRUE) ) {
return;
}
while ( !listExes.IsEmpty() ) {
pExe_RegEntry = listExes.GetHeadData();
listExes.RemoveHead();
// Add item at the root level
AddItemToTree(hwndTree,
pExe_RegEntry->m_pszName,
1,
NULL
);
// Get the WrkSpc list
if ( WKSP_RegEnumerate(pExe_RegEntry->m_hkey, &listWrkSpcs, NULL, TRUE) ) {
while ( !listWrkSpcs.IsEmpty() ) {
pWS_RegEntry = listWrkSpcs.GetHeadData();
listWrkSpcs.RemoveHead();
// Add item at the level 2
AddItemToTree(hwndTree,
pWS_RegEntry->m_pszName,
2,
NULL
);
pWS_RegEntry->CleanUp();
delete pWS_RegEntry;
}
}
// Delete it without cleaning up since we'll do this manually
pExe_RegEntry->CleanUp();
delete pExe_RegEntry;
}
}
INT_PTR
CALLBACK
DlgProc_WorkSpace_Manage(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
/*++
Description:
Used to manage workspaces. Rename, delete, copy and paste workspaces from to EXE.
See description for dlg procs.
--*/
{
#if 0 // Not yet enabled
static DWORD HelpArray[]=
{
IDC_LIST1, IDH_TRANSPORT,
IDC_STEXT_SELECT, IDH_TLSELECT,
IDC_BUT_SELECT, IDH_TLSELECT,
IDC_BUT_ADD, IDH_TLADD,
IDC_BUT_EDIT, IDH_TLEDIT,
IDC_BUT_DELETE, IDH_TLDEL,
0, 0
};
static DWORD NOEDIT_HelpArray[]=
{
IDC_LIST1, IDH_TRANSPORT_DISABLED,
IDC_STEXT_SELECT, IDH_TRANSPORT_DISABLED,
IDC_BUT_SELECT, IDH_TRANSPORT_DISABLED,
IDC_BUT_ADD, IDH_TRANSPORT_DISABLED,
IDC_BUT_EDIT, IDH_TRANSPORT_DISABLED,
IDC_BUT_DELETE, IDH_TRANSPORT_DISABLED,
0, 0
};
#endif
HWND hwndTree = GetDlgItem(hDlg, IDC_TREE_WRKSPC);
switch (uMsg) {
default:
return FALSE;
#if 0 // Not yet enabled
case WM_HELP:
WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle,
"windbg.hlp",
HELP_WM_HELP,
(ULONG_PTR) pdwHelpArray );
return TRUE;
case WM_CONTEXTMENU:
WinHelp((HWND) wParam,
"windbg.hlp",
HELP_CONTEXTMENU,
(ULONG_PTR) pdwHelpArray );
return TRUE;
#endif
case WM_INITDIALOG:
PopulateExeWorkspaceTree(hwndTree);
return TRUE;
case WM_COMMAND:
{
WORD wNotifyCode = HIWORD(wParam); // notification code
WORD wID = LOWORD(wParam); // item, control, or accelerator identifier
HWND hwndCtl = (HWND) lParam; // handle of control
TCHAR szExeName[_MAX_PATH];
TCHAR szWrkSpcName[_MAX_PATH];
HTREEITEM htiSel = NULL;
HTREEITEM htiParent = NULL;
CDebuggee_WKSP *pTmpDebuggee_WkSp = NULL;
CWorkSpace_WKSP *pTmpWorkspace_WkSp = NULL;
// Whack any garbage
*szExeName = NULL;
*szWrkSpcName = NULL;
// Get the name of the currently selected EXE and set the name of
// the WORKSPACE to NULL
// or
// Get the name of the currently slected WORKSPACE and get the name of
// parent EXE the
htiSel = TreeView_GetSelection(hwndTree) ;
if ( htiSel ) {
// Success, but what has been selected? An EXE or a WORKSPACE?
TVITEM tvi;
// Assume we are retrieving the name of a workspace
tvi.mask = TVIF_HANDLE | TVIF_TEXT;
tvi.hItem = htiSel;
tvi.pszText = szWrkSpcName;
tvi.cchTextMax = _tsizeof(szWrkSpcName);
TreeView_GetItem(hwndTree, &tvi);
// Get it's parent if it has one
htiParent = TreeView_GetParent(hwndTree, htiSel);
if ( !htiParent ) {
// No parent then we have an EXE
_tcscpy(szExeName, szWrkSpcName);
*szWrkSpcName = NULL;
} else {
// If it has a parent then it's a WORKSPACE, get the EXE name
tvi.mask = TVIF_HANDLE | TVIF_TEXT;
tvi.hItem = htiParent;
tvi.pszText = szExeName;
tvi.cchTextMax = _tsizeof(szExeName);
TreeView_GetItem(hwndTree, &tvi);
}
}
switch (wID) {
default:
return FALSE;
case IDOK:
// Open a workspace
if ( !*szWrkSpcName || !*szExeName ) {
// Must have a WORKSPACE & EXE selected
return TRUE;
}
g_contWorkspace_WkSp.CloseRegistryKeys();
if ( !_tcsicmp(szExeName, g_contDebuggee_WkSp.m_pszRegistryName) ) {
g_contWorkspace_WkSp.SetRegistryName(szWrkSpcName);
g_contWorkspace_WkSp.Restore(FALSE);
} else {
pTmpDebuggee_WkSp = new CDebuggee_WKSP;
pTmpDebuggee_WkSp->SetRegistryName(szExeName);
pTmpDebuggee_WkSp->SetParent( &g_contAllDebuggees_WkSp );
pTmpWorkspace_WkSp = &pTmpDebuggee_WkSp->m_contWorkSpace;
pTmpWorkspace_WkSp->SetRegistryName(szWrkSpcName);
pTmpWorkspace_WkSp->Restore(TRUE);
g_contWorkspace_WkSp.Duplicate( *pTmpWorkspace_WkSp );
delete pTmpDebuggee_WkSp;
}
// Fall through
case IDCANCEL:
// Resave the mirrored info since we have overwritten by the changes we've made
{
HCURSOR hcurOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
g_Windbg_WkSp.Save(TRUE, FALSE);
SetCursor(hcurOld);
}
EndDialog(hDlg, wID); // Return whatever the user pressed.
return TRUE;
case IDC_BUT_COPY:
InformationBox(ERR_Not_YetImplemented);
if ( !*szWrkSpcName && !*szExeName ) {
// Must have a EXE or WORKSPACE or EXE selected
return TRUE;
}
return TRUE;
case IDC_BUT_PASTE:
InformationBox(ERR_Not_YetImplemented);
return TRUE;
case IDC_BUT_RENAME:
InformationBox(ERR_Not_YetImplemented);
return TRUE;
case IDC_BUT_DELETE:
{
HKEY hkeyParent;
HKEY hkeyExe;
HKEY hkeyWS;
if ( !*szWrkSpcName && !*szExeName ) {
// Must have a WORKSPACE or EXE selected
return TRUE;
}
hkeyParent = g_contAllDebuggees_WkSp.GetRegistryKey();
if ( !hkeyParent ) {
return TRUE;
}
// Close all registry keys just to be on the safe side
g_contDebuggee_WkSp.CloseRegistryKeys();
if ( !*szWrkSpcName ) {
// Delete the EXE
if ( !WKSP_RegDeleteKey(hkeyParent, szExeName)
|| !TreeView_DeleteItem(hwndTree, htiSel) ) {
ErrorBox(ERR_Deleting_Registry_Key);
// All bets are off, repopulate the tree
PopulateExeWorkspaceTree(hwndTree);
}
} else {
// Delete the workspace
LONG lRes;
// Open the EXE
lRes = RegOpenKeyEx(hkeyParent, szExeName, 0, KEY_ALL_ACCESS, &hkeyExe);
if (ERROR_SUCCESS != lRes) {
// All bets are off, repopulate the tree
PopulateExeWorkspaceTree(hwndTree);
return FALSE;
}
// Delete the workspace
if ( !WKSP_RegDeleteKey(hkeyExe, szWrkSpcName)
|| !TreeView_DeleteItem(hwndTree, htiSel) ) {
ErrorBox(ERR_Deleting_Registry_Key);
// All bets are off, repopulate the tree
PopulateExeWorkspaceTree(hwndTree);
}
RegCloseKey(hkeyExe);
}
}
return TRUE;
case IDC_BUT_MAKE_DEFAULT:
// Make the currently selected workspace the default one for this EXE
if ( !*szWrkSpcName || !*szExeName ) {
// Must have a WORKSPACE & EXE selected
return TRUE;
}
// Is it for this EXE?
if ( !_tcsicmp(szExeName, g_contDebuggee_WkSp.m_pszRegistryName) ) {
FREE_STR(g_contDebuggee_WkSp.m_pszNameOfPreferredWorkSpace);
g_contDebuggee_WkSp.m_pszNameOfPreferredWorkSpace = _tcsdup(szExeName);
// Save change, also save to the mirror, but only the data items
g_contDebuggee_WkSp.Save(FALSE, TRUE);
} else {
pTmpDebuggee_WkSp = new CDebuggee_WKSP;
pTmpDebuggee_WkSp->SetRegistryName(szExeName);
pTmpDebuggee_WkSp->SetParent( &g_contAllDebuggees_WkSp );
pTmpDebuggee_WkSp->Restore(TRUE);
FREE_STR(pTmpDebuggee_WkSp->m_pszNameOfPreferredWorkSpace);
pTmpDebuggee_WkSp->m_pszNameOfPreferredWorkSpace = _tcsdup(szExeName);
// Save change, also save to the mirror.
// but only save the data items
pTmpDebuggee_WkSp->Save(FALSE, TRUE);
// Let's reset the mirror to our stuff.
g_contDebuggee_WkSp.Save(FALSE, TRUE);
}
return TRUE;
case IDC_BUT_NEW:
InformationBox(ERR_Not_YetImplemented);
return TRUE;
}
}
}
}
INT_PTR
CALLBACK
DlgProc_WindowLayout_Manage(
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
/*++
Description:
Used to manage workspaces. Rename, delete, copy and paste workspaces from to EXE.
See description for dlg procs.
--*/
{
#if 0 // Not yet enabled
static DWORD HelpArray[]=
{
IDC_LIST1, IDH_TRANSPORT,
IDC_STEXT_SELECT, IDH_TLSELECT,
IDC_BUT_SELECT, IDH_TLSELECT,
IDC_BUT_ADD, IDH_TLADD,
IDC_BUT_EDIT, IDH_TLEDIT,
IDC_BUT_DELETE, IDH_TLDEL,
0, 0
};
static DWORD NOEDIT_HelpArray[]=
{
IDC_LIST1, IDH_TRANSPORT_DISABLED,
IDC_STEXT_SELECT, IDH_TRANSPORT_DISABLED,
IDC_BUT_SELECT, IDH_TRANSPORT_DISABLED,
IDC_BUT_ADD, IDH_TRANSPORT_DISABLED,
IDC_BUT_EDIT, IDH_TRANSPORT_DISABLED,
IDC_BUT_DELETE, IDH_TRANSPORT_DISABLED,
0, 0
};
#endif
HWND hwndTree = GetDlgItem(hDlg, IDC_TREE_WRKSPC);
switch (uMsg) {
default:
return FALSE;
#if 0 // Not yet enabled
case WM_HELP:
WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle,
"windbg.hlp",
HELP_WM_HELP,
(ULONG_PTR) pdwHelpArray );
return TRUE;
case WM_CONTEXTMENU:
WinHelp((HWND) wParam,
"windbg.hlp",
HELP_CONTEXTMENU,
(ULONG_PTR) pdwHelpArray );
return TRUE;
#endif
case WM_INITDIALOG:
// Set the extended style
PopulateWindowLayoutTree(hwndTree);
return TRUE;
case WM_COMMAND:
{
WORD wNotifyCode = HIWORD(wParam); // notification code
WORD wID = LOWORD(wParam); // item, control, or accelerator identifier
HWND hwndCtl = (HWND) lParam; // handle of control
TCHAR szLayoutName[_MAX_PATH];
CWinLayout_WKSP *pTmpWinLayout = NULL;
HTREEITEM htiSel;
// Whack any garbage
*szLayoutName = NULL;
// Get the name of the currently selected EXE and set the name of
// the WORKSPACE to NULL
// or
// Get the name of the currently slected WORKSPACE and get the name of
// parent EXE the
htiSel = TreeView_GetSelection(hwndTree) ;
if ( htiSel ) {
// Success, but what has been selected? An EXE or a WORKSPACE?
TVITEM tvi;
// Assume we are retrieving the name of a workspace
tvi.mask = TVIF_HANDLE | TVIF_TEXT;
tvi.hItem = htiSel;
tvi.pszText = szLayoutName;
tvi.cchTextMax = _tsizeof(szLayoutName);
TreeView_GetItem(hwndTree, &tvi);
}
switch (wID) {
default:
return FALSE;
case IDOK:
// Open a window layout
g_contWinLayout_WkSp.CloseRegistryKeys();
if ( !_tcsicmp(szLayoutName, g_contWinLayout_WkSp.m_pszRegistryName) ) {
g_contWinLayout_WkSp.Restore(FALSE);
LoadAllWindows();
} else {
g_contWinLayout_WkSp.SetRegistryName(szLayoutName);
g_contWinLayout_WkSp.Restore(FALSE);
LoadAllWindows();
}
// Fall through
case IDCANCEL:
EndDialog(hDlg, wID); // Return whatever the user pressed.
return TRUE;
case IDC_BUT_COPY:
InformationBox(ERR_Not_YetImplemented);
return TRUE;
case IDC_BUT_PASTE:
InformationBox(ERR_Not_YetImplemented);
return TRUE;
case IDC_BUT_RENAME:
InformationBox(ERR_Not_YetImplemented);
return TRUE;
case IDC_BUT_DELETE:
if ( *szLayoutName ) {
HKEY hkeyParent;
HKEY hkeyExe;
HKEY hkeyWS;
hkeyParent = g_contAllWinLayouts_WkSp.GetRegistryKey();
if ( !hkeyParent ) {
return TRUE;
}
// Close all registry keys just to be on the safe side
g_contWinLayout_WkSp.CloseRegistryKeys();
if ( !*szLayoutName ) {
// Delete the EXE
if ( !WKSP_RegDeleteKey(hkeyParent, szLayoutName)
|| !TreeView_DeleteItem(hwndTree, htiSel) ) {
ErrorBox(ERR_Deleting_Registry_Key);
// All bets are off, repopulate the tree
PopulateWindowLayoutTree(hwndTree);
}
}
}
return TRUE;
case IDC_BUT_MAKE_DEFAULT:
// Make the currently selected workspace the default one for this EXE
InformationBox(ERR_Not_YetImplemented);
return TRUE;
if ( !*szLayoutName ) {
// Must have a WORKSPACE & EXE selected
return TRUE;
}
/*
// Is it for this EXE?
if ( !_tcsicmp(szLayoutName, g_contWinLayout_WkSp.m_pszRegistryName) ) {
FREE_STR(m_pszLastUsedWinLayout.m_pszNameOfPreferredWorkSpace);
g_contWinLayout_WkSp.m_pszNameOfPreferredWorkSpace = _tcsdup(szLayoutName);
// Save change, also save to the mirror, but only the data items
g_contWinLayout_WkSp.Save(FALSE, TRUE);
} else {
pTmpDebuggee_WkSp = new CWinLayout_WKSP;
pTmpDebuggee_WkSp->SetRegistryName(szLayoutName);
pTmpDebuggee_WkSp->SetParent( &g_contAllDebuggees_WkSp );
pTmpDebuggee_WkSp->Restore(TRUE);
FREE_STR(pTmpDebuggee_WkSp->m_pszNameOfPreferredWorkSpace);
pTmpDebuggee_WkSp->m_pszNameOfPreferredWorkSpace = _tcsdup(szLayoutName);
// Save change, also save to the mirror.
// but only save the data items
pTmpDebuggee_WkSp->Save(FALSE, TRUE);
// Let's reset the mirror to our stuff.
g_contWinLayout_WkSp.Save(FALSE, TRUE);
}
*/
return TRUE;
case IDC_BUT_NEW:
InformationBox(ERR_Not_YetImplemented);
return TRUE;
}
}
}
}
INT_PTR
CALLBACK
DlgProc_WorkSpace_SaveAs(
HWND hDlg,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
/*++
Routine Description:
Code for the Program.Load Work Space dialog
Arguments:
Std. dialog args.
Return Value:
None
--*/
{
TCHAR szBuf[1024];
static DWORD HelpArray[]=
{
ID_SAVEAS_NAME, IDH_WKSPNAME,
ID_SAVEAS_MAKEDEFAULT, IDH_DEFWKSP,
0, 0
};
Unreferenced( lParam );
switch( msg ) {
case WM_INITDIALOG:
SetDlgItemText(hDlg,
ID_SAVEAS_NAME,
g_contWorkspace_WkSp.m_pszRegistryName
);
SendDlgItemMessage(hDlg,
ID_SAVEAS_NAME,
EM_SETLIMITTEXT,
_tsizeof(szBuf) -1, // leave room for the terminating zero
0
);
CheckDlgButton(hDlg,
ID_SAVEAS_MAKEDEFAULT,
BM_SETCHECK
);
return TRUE;
case WM_HELP:
WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, "windbg.hlp", HELP_WM_HELP,
(LPARAM)(LPVOID) HelpArray );
return TRUE;
case WM_CONTEXTMENU:
WinHelp ((HWND) wParam, "windbg.hlp", HELP_CONTEXTMENU,
(LPARAM)(LPVOID) HelpArray );
return TRUE;
case WM_COMMAND:
{
WORD wNotifyCode = HIWORD(wParam); // notification code
WORD wID = LOWORD(wParam); // item, control, or accelerator identifier
HWND hwndCtl = (HWND) lParam; // handle of control
switch( wID ) {
case IDOK:
{
PTSTR psz;
BOOL bMakeDefault;
GetDlgItemText(hDlg,
ID_SAVEAS_NAME,
szBuf,
_tsizeof(szBuf)
);
szBuf[_tsizeof(szBuf) -1] = 0;
psz = CPSkipWhitespace(szBuf);
if ( !*psz ) {
ErrorBox(ERR_Must_Supply_WrkSpc_Name);
return TRUE;
}
g_contWorkspace_WkSp.SetRegistryName(psz);
// Close existing handles to the registry and
// create new ones since we now have a new name.
g_contWorkspace_WkSp.CloseRegistryKeys();
bMakeDefault = BM_SETCHECK == IsDlgButtonChecked(hDlg, ID_SAVEAS_MAKEDEFAULT );
if (bMakeDefault) {
FREE_STR(g_contDebuggee_WkSp.m_pszNameOfPreferredWorkSpace);
g_contDebuggee_WkSp.m_pszNameOfPreferredWorkSpace =
_strdup(g_contWorkspace_WkSp.m_pszRegistryName);
}
}
g_contWorkspace_WkSp.Save(FALSE, FALSE);
// Fall thru
case IDCANCEL:
EndDialog(hDlg, wID); // Return whatever the user pressed.
return TRUE;
}
}
break;
}
return FALSE;
}
INT_PTR
CALLBACK
DlgProc_WindowLayout_SaveAs(
HWND hDlg,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
/*++
Routine Description:
Code for the Program.Load Work Space dialog
Arguments:
Std. dialog args.
Return Value:
None
--*/
{
TCHAR szBuf[1024];
/*
static DWORD HelpArray[]=
{
ID_SAVEAS_NAME, IDH_WKSPNAME,
ID_SAVEAS_MAKEDEFAULT, IDH_DEFWKSP,
0, 0
};
*/
Unreferenced( lParam );
switch( msg ) {
case WM_INITDIALOG:
SetDlgItemText(hDlg,
ID_SAVEAS_NAME,
g_contWinLayout_WkSp.m_pszRegistryName
);
SendDlgItemMessage(hDlg,
ID_SAVEAS_NAME,
EM_SETLIMITTEXT,
_tsizeof(szBuf) -1, // leave room for the terminating zero
0
);
CheckDlgButton(hDlg,
ID_SAVEAS_MAKEDEFAULT,
BM_SETCHECK
);
return TRUE;
/*
case WM_HELP:
WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, "windbg.hlp", HELP_WM_HELP,
(DWORD)(LPVOID) HelpArray );
return TRUE;
case WM_CONTEXTMENU:
WinHelp ((HWND) wParam, "windbg.hlp", HELP_CONTEXTMENU,
(DWORD)(LPVOID) HelpArray );
return TRUE;
*/
case WM_COMMAND:
{
WORD wNotifyCode = HIWORD(wParam); // notification code
WORD wID = LOWORD(wParam); // item, control, or accelerator identifier
HWND hwndCtl = (HWND) lParam; // handle of control
switch( wID ) {
case IDOK:
{
PTSTR psz;
BOOL bMakeDefault;
GetDlgItemText(hDlg,
ID_SAVEAS_NAME,
szBuf,
_tsizeof(szBuf)
);
szBuf[_tsizeof(szBuf) -1] = 0;
psz = CPSkipWhitespace(szBuf);
if ( !*psz ) {
ErrorBox(ERR_Must_Supply_WrkSpc_Name);
return TRUE;
}
g_contWinLayout_WkSp.SetRegistryName(psz);
// Close existing handles to the registry and
// create new ones since we now have a new name.
g_contWinLayout_WkSp.CloseRegistryKeys();
bMakeDefault = BM_SETCHECK == IsDlgButtonChecked(hDlg, ID_SAVEAS_MAKEDEFAULT );
/*if (bMakeDefault) {
FREE_STR(g_contWinLayout_WkSp.m_pszNameOfPreferredWorkSpace);
g_contWinLayout_WkSp.m_pszNameOfPreferredWorkSpace =
_strdup(g_contWorkspace_WkSp.m_pszRegistryName);
}*/
}
SaveAllWindows();
g_contWinLayout_WkSp.Save(FALSE, FALSE);
// Fall thru
case IDCANCEL:
EndDialog( hDlg, wID );
break;
}
}
break;
}
return FALSE;
}