From 1d0ff8809bda589e1cdf2181a14af42a481141b9 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Tue, 1 Oct 2013 21:11:41 +0200 Subject: [PATCH] Dump memory dialog --- Windows/Debugger/CtrlMemView.cpp | 14 +- Windows/Debugger/DumpMemoryWindow.cpp | 230 ++++++++++++++++++++++++++ Windows/Debugger/DumpMemoryWindow.h | 32 ++++ Windows/PPSSPP.vcxproj | 2 + Windows/PPSSPP.vcxproj.filters | 6 + Windows/ppsspp.rc | 21 +++ Windows/resource.h | 13 +- 7 files changed, 305 insertions(+), 13 deletions(-) create mode 100644 Windows/Debugger/DumpMemoryWindow.cpp create mode 100644 Windows/Debugger/DumpMemoryWindow.h diff --git a/Windows/Debugger/CtrlMemView.cpp b/Windows/Debugger/CtrlMemView.cpp index 3e7919e3e..b28cbf684 100644 --- a/Windows/Debugger/CtrlMemView.cpp +++ b/Windows/Debugger/CtrlMemView.cpp @@ -16,6 +16,7 @@ #include "Debugger_Disasm.h" #include "DebuggerShared.h" #include "CtrlMemView.h" +#include "DumpMemoryWindow.h" wchar_t CtrlMemView::szClassName[] = L"CtrlMemView"; extern HMENU g_hPopupMenus; @@ -421,7 +422,6 @@ void CtrlMemView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) //popup menu? POINT pt; GetCursorPos(&pt); - FILE* outputfile; switch (TrackPopupMenuEx(GetSubMenu(g_hPopupMenus,0),TPM_RIGHTBUTTON|TPM_RETURNCMD,pt.x,pt.y,wnd,0)) { case ID_MEMVIEW_DUMP: @@ -433,16 +433,8 @@ void CtrlMemView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) } else { - outputfile = fopen("Ram.dump", "wb"); // Could also dump Vram, but not useful for now. - if (outputfile != NULL) - { - fwrite(Memory::GetPointer(0x08800000), 1, 0x01800000, outputfile); - fclose(outputfile); - } - else //file could not be opened as "wb" - { - MessageBox(wnd, L"Ram.dump could not be opened with write privileges", 0, 0); - } + DumpMemoryWindow dump(wnd,debugger); + dump.exec(); break; } diff --git a/Windows/Debugger/DumpMemoryWindow.cpp b/Windows/Debugger/DumpMemoryWindow.cpp new file mode 100644 index 000000000..4456eb220 --- /dev/null +++ b/Windows/Debugger/DumpMemoryWindow.cpp @@ -0,0 +1,230 @@ +#include "DumpMemoryWindow.h" +#include "../resource.h" +#include +#include "Core/MemMap.h" +#include "Windows/W32Util/ShellUtil.h" + +DumpMemoryWindow* DumpMemoryWindow::bp; + +INT_PTR CALLBACK DumpMemoryWindow::dlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) +{ + switch (iMsg) + { + case WM_INITDIALOG: + bp->changeMode(hwnd,bp->selectedMode); + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_DUMP_USERMEMORY: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + bp->changeMode(hwnd,MODE_RAM); + break; + } + break; + case IDC_DUMP_VRAM: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + bp->changeMode(hwnd,MODE_VRAM); + break; + } + break; + case IDC_DUMP_SCRATCHPAD: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + bp->changeMode(hwnd,MODE_SCRATCHPAD); + break; + } + break; + case IDC_DUMP_CUSTOMRANGE: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + bp->changeMode(hwnd,MODE_CUSTOM); + break; + } + break; + case IDC_DUMP_BROWSEFILENAME: + switch (HIWORD(wParam)) + { + case BN_CLICKED: + char str[MAX_PATH]; + GetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_FILENAME),str,MAX_PATH); + std::string fn = str; + + bool result = W32Util::BrowseForFileName(false, hwnd, L"Select filename", NULL,NULL,NULL,fn); + if (result) + { + bp->filenameChosen = true; + SetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_FILENAME),fn.c_str()); + } + break; + } + break; + case IDOK: + if (bp->fetchDialogData(hwnd)) + { + FILE* output = fopen(bp->fileName,"wb"); + if (output == NULL) + { + char errorMessage[256]; + sprintf(errorMessage,"Could not open file \"%s\".",bp->fileName); + MessageBoxA(hwnd,errorMessage,"Error",MB_OK); + break; + } + + fwrite(Memory::GetPointer(bp->start), 1, bp->size, output); + fclose(output); + + MessageBoxA(hwnd,"Done.","Error",MB_OK); + EndDialog(hwnd,true); + } + break; + case IDCANCEL: + EndDialog(hwnd,false); + break; + } + + case WM_KEYDOWN: + + break; + } + + return FALSE; +} + +bool isInInterval(u32 start, u32 end, u32 value) +{ + return start <= value && value < end; +} + +bool DumpMemoryWindow::fetchDialogData(HWND hwnd) +{ + char str[256],errorMessage[256]; + PostfixExpression exp; + + // parse start address + GetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_STARTADDRESS),str,256); + if (cpu->initExpression(str,exp) == false + || cpu->parseExpression(exp,start) == false) + { + sprintf(errorMessage,"Invalid address expression \"%s\".",str); + MessageBoxA(hwnd,errorMessage,"Error",MB_OK); + return false; + } + + // parse size + GetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_SIZE),str,256); + if (cpu->initExpression(str,exp) == false + || cpu->parseExpression(exp,size) == false) + { + sprintf(errorMessage,"Invalid size expression \"%s\".",str); + MessageBoxA(hwnd,errorMessage,"Error",MB_OK); + return false; + } + + if (size == 0) + { + MessageBoxA(hwnd,"Invalid size 0.","Error",MB_OK); + return false; + } + + // get filename + GetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_FILENAME),fileName,MAX_PATH); + if (strlen(fileName) == 0) return false; + + // now check if data makes sense... + bool invalidSize = false; + bool invalidAddress = false; + if (isInInterval(PSP_GetScratchpadMemoryBase(),PSP_GetScratchpadMemoryEnd(),start)) + { + invalidSize = !isInInterval(PSP_GetScratchpadMemoryBase(),PSP_GetScratchpadMemoryEnd(),start+size-1); + } else if (isInInterval(PSP_GetVidMemBase(),PSP_GetVidMemEnd(),start)) + { + invalidSize = !isInInterval(PSP_GetVidMemBase(),PSP_GetVidMemEnd(),start+size-1); + } else if (isInInterval(PSP_GetKernelMemoryBase(),PSP_GetUserMemoryEnd(),start)) + { + invalidSize = !isInInterval(PSP_GetKernelMemoryBase(),PSP_GetUserMemoryEnd(),start+size-1); + } else + { + invalidAddress = true; + } + + if (invalidAddress) + { + sprintf(errorMessage,"Invalid address 0x%08X.",start); + MessageBoxA(hwnd,errorMessage,"Error",MB_OK); + return false; + } else if (invalidSize) + { + sprintf(errorMessage,"Invalid end address 0x%08X.",start+size); + MessageBoxA(hwnd,errorMessage,"Error",MB_OK); + return false; + } + + return true; +} + +void DumpMemoryWindow::changeMode(HWND hwnd, Mode newMode) +{ + char buffer[128]; + selectedMode = newMode; + + SendMessage(GetDlgItem(hwnd,IDC_DUMP_USERMEMORY),BM_SETCHECK,selectedMode == MODE_RAM ? BST_CHECKED : BST_UNCHECKED,0); + SendMessage(GetDlgItem(hwnd,IDC_DUMP_VRAM),BM_SETCHECK,selectedMode == MODE_VRAM ? BST_CHECKED : BST_UNCHECKED,0); + SendMessage(GetDlgItem(hwnd,IDC_DUMP_SCRATCHPAD),BM_SETCHECK,selectedMode == MODE_SCRATCHPAD ? BST_CHECKED : BST_UNCHECKED,0); + SendMessage(GetDlgItem(hwnd,IDC_DUMP_CUSTOMRANGE),BM_SETCHECK,selectedMode == MODE_CUSTOM ? BST_CHECKED : BST_UNCHECKED,0); + + if (selectedMode == MODE_CUSTOM) + { + EnableWindow(GetDlgItem(hwnd,IDC_DUMP_STARTADDRESS),TRUE); + EnableWindow(GetDlgItem(hwnd,IDC_DUMP_SIZE),TRUE); + + if (filenameChosen == false) + SetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_FILENAME),"Custom.dump"); + } else { + u32 start, size; + const char* defaultFileName; + + switch (selectedMode) + { + case MODE_RAM: + start = PSP_GetUserMemoryBase(); + size = PSP_GetUserMemoryEnd()-start; + defaultFileName = "RAM.dump"; + break; + case MODE_VRAM: + start = PSP_GetVidMemBase(); + size = PSP_GetVidMemEnd()-start; + defaultFileName = "VRAM.dump"; + break; + case MODE_SCRATCHPAD: + start = PSP_GetScratchpadMemoryBase(); + size = PSP_GetScratchpadMemoryEnd()-start; + defaultFileName = "Scratchpad.dump"; + break; + } + + sprintf(buffer,"0x%08X",start); + SetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_STARTADDRESS),buffer); + EnableWindow(GetDlgItem(hwnd,IDC_DUMP_STARTADDRESS),FALSE); + + sprintf(buffer,"0x%08X",size); + SetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_SIZE),buffer); + EnableWindow(GetDlgItem(hwnd,IDC_DUMP_SIZE),FALSE); + + if (filenameChosen == false) + SetWindowTextA(GetDlgItem(hwnd,IDC_DUMP_FILENAME),defaultFileName); + } +} + +bool DumpMemoryWindow::exec() +{ + bp = this; + bool result = DialogBoxParam(GetModuleHandle(0),MAKEINTRESOURCE(IDD_DUMPMEMORY),parentHwnd,dlgFunc,(LPARAM)this) != 0; + return result; +} diff --git a/Windows/Debugger/DumpMemoryWindow.h b/Windows/Debugger/DumpMemoryWindow.h new file mode 100644 index 000000000..6c808552d --- /dev/null +++ b/Windows/Debugger/DumpMemoryWindow.h @@ -0,0 +1,32 @@ +#pragma once +#include "Common/CommonWindows.h" +#include "Common/CommonTypes.h" +#include "Core/Debugger/DebugInterface.h" + +class DumpMemoryWindow +{ + enum Mode { MODE_RAM, MODE_VRAM, MODE_SCRATCHPAD, MODE_CUSTOM }; + + HWND parentHwnd; + DebugInterface* cpu; + bool filenameChosen; + Mode selectedMode; + + u32 start; + u32 size; + char fileName[MAX_PATH]; + + static DumpMemoryWindow* bp; + void changeMode(HWND hwnd, Mode newMode); + bool fetchDialogData(HWND hwnd); +public: + DumpMemoryWindow(HWND parent, DebugInterface* cpu): cpu(cpu) + { + parentHwnd = parent; + filenameChosen = false; + selectedMode = MODE_RAM; + }; + + static INT_PTR CALLBACK dlgFunc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam); + bool exec(); +}; diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index b5633161d..fd555f0d7 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -279,6 +279,7 @@ + @@ -326,6 +327,7 @@ + diff --git a/Windows/PPSSPP.vcxproj.filters b/Windows/PPSSPP.vcxproj.filters index 81e7307c5..9c944deaa 100644 --- a/Windows/PPSSPP.vcxproj.filters +++ b/Windows/PPSSPP.vcxproj.filters @@ -131,6 +131,9 @@ Windows\GE Debugger + + Windows\Debugger + @@ -236,6 +239,9 @@ Windows\GE Debugger + + Windows\Debugger + diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index c2aa65308..265a88be8 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -261,6 +261,27 @@ BEGIN PUSHBUTTON "Cancel",IDC_BREAKPOINT_CANCEL,186,68,42,14 END +IDD_DUMPMEMORY DIALOGEX 0, 0, 230, 85 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dump memory" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "Start",IDC_STATIC,7,8,27,8 + EDITTEXT IDC_DUMP_STARTADDRESS,41,7,95,14,ES_AUTOHSCROLL + LTEXT "Size",IDC_STATIC,7,27,14,8 + EDITTEXT IDC_DUMP_SIZE,41,25,95,14,ES_AUTOHSCROLL + LTEXT "Filename",IDC_STATIC,7,46,32,8 + EDITTEXT IDC_DUMP_FILENAME,41,43,75,14,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_DUMP_BROWSEFILENAME,119,43,17,14 + GROUPBOX "Location",IDC_STATIC,145,1,76,57 + CONTROL "RAM",IDC_DUMP_USERMEMORY,"Button",BS_AUTORADIOBUTTON,152,10,31,10 + CONTROL "VRAM",IDC_DUMP_VRAM,"Button",BS_AUTORADIOBUTTON,152,22,35,10 + CONTROL "Scratchpad",IDC_DUMP_SCRATCHPAD,"Button",BS_AUTORADIOBUTTON,152,34,52,10 + CONTROL "Custom range",IDC_DUMP_CUSTOMRANGE,"Button",BS_AUTORADIOBUTTON,152,46,61,10 + DEFPUSHBUTTON "OK",IDOK,117,64,50,14 + PUSHBUTTON "Cancel",IDCANCEL,173,64,50,14 +END + ///////////////////////////////////////////////////////////////////////////// // diff --git a/Windows/resource.h b/Windows/resource.h index 17624f910..18ecd558c 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -79,6 +79,7 @@ #define IDD_GEDEBUGGER 250 #define IDD_TABDISPLAYLISTS 251 #define IDD_GEDBG_TAB_VALUES 252 +#define IDD_DUMPMEMORY 253 #define IDC_STOPGO 1001 #define IDC_ADDRESS 1002 @@ -146,6 +147,14 @@ #define IDC_DISASMSTATUSBAR 1180 #define IDC_STACKFRAMES 1181 #define IDC_GEDBG_VALUES 1182 +#define IDC_DUMP_USERMEMORY 1183 +#define IDC_DUMP_VRAM 1184 +#define IDC_DUMP_SCRATCHPAD 1185 +#define IDC_DUMP_CUSTOMRANGE 1186 +#define IDC_DUMP_STARTADDRESS 1187 +#define IDC_DUMP_SIZE 1188 +#define IDC_DUMP_FILENAME 1189 +#define IDC_DUMP_BROWSEFILENAME 1190 // Don't define anything else in the 3000 range. // It's reserved for languages. @@ -286,9 +295,9 @@ // Next default values for new objects #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 253 +#define _APS_NEXT_RESOURCE_VALUE 254 #define _APS_NEXT_COMMAND_VALUE 40130 -#define _APS_NEXT_CONTROL_VALUE 1183 +#define _APS_NEXT_CONTROL_VALUE 1191 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif