#COMPILE EXE #DIM ALL $EXE = "xdmgr - ExeData Manager" $VER = "v0.1" '------------------------------------------------------------------------------ ' ** Includes ** '------------------------------------------------------------------------------ #RESOURCE "res\xdmgr.pbr" #INCLUDE ONCE "WIN32API.INC" #INCLUDE ONCE "inc\GdiPlus.inc" #INCLUDE ONCE "inc\xdata.inc" '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** Constants ** '------------------------------------------------------------------------------ %IDC_LBL_DUM = 1001 %IDC_LBL_NFO = 1002 %IDC_LBL_EXE = 1003 %IDC_BTN_EXE = 1004 %IDC_LVW_LST = 1005 %IDC_BTN_ADD = 1006 %IDC_BTN_RM1 = 1007 %IDC_BTN_RMA = 1008 %IDC_BTN_PVW = 1009 %IDC_BTN_XT1 = 1010 %IDC_BTN_XTA = 1011 '------------------------------------------------------------------------------ GLOBAL myExe AS STRING GLOBAL myNfo AS STRING GLOBAL xd() AS ExeData '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** Main Application Entry Point ** '------------------------------------------------------------------------------ FUNCTION PBMAIN() ' Initialize GDI+ library GdipInitialize() ' Clean previous session KILL EXE.PATH$ + "temp.img" ' Treat arguments IF INSTR(LCASE$(COMMAND$), ".exe") > 0 THEN myExe = TRIM$(COMMAND$, $DQ) ' Show main dialog MainShow %HWND_DESKTOP END FUNCTION '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ SUB LogMe(s AS STRING) END SUB '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ MACRO RefreshControls LISTVIEW RESET CB.HNDL, %IDC_LVW_LST REDIM xd(-1) CONTROL SET TEXT CB.HNDL, %IDC_LBL_EXE, myExe IF myExe <> "" THEN CONTROL ENABLE CB.HNDL, %IDC_BTN_ADD CONTROL SET COLOR CB.HNDL, %IDC_LBL_EXE, -1, %WHITE END IF ParseExeData myExe, xd() FOR i = UBOUND(xd) TO LBOUND(xd) STEP -1 LISTVIEW INSERT ITEM CB.HNDL, %IDC_LVW_LST, 1, %NULL, FORMAT$(i) LISTVIEW SET TEXT CB.HNDL, %IDC_LVW_LST, 1, 2, xd(i).desc LISTVIEW SET TEXT CB.HNDL, %IDC_LVW_LST, 1, 3, IIF$(INSTR(GetExeData(myExe,xd(i)),CHR$(0)),"Binary","Text") LISTVIEW SET TEXT CB.HNDL, %IDC_LVW_LST, 1, 4, FORMAT$(xd(i).length,"#,") & " B" LISTVIEW SET TEXT CB.HNDL, %IDC_LVW_LST, 1, 5, "@ " & FORMAT$(xd(i).address,"#,") NEXT IF UBOUND(xd) >= 1 THEN LISTVIEW SELECT CB.HNDL, %IDC_LVW_LST, 1 CONTROL ENABLE CB.HNDL, %IDC_BTN_PVW CONTROL ENABLE CB.HNDL, %IDC_BTN_XT1 CONTROL ENABLE CB.HNDL, %IDC_BTN_XTA CONTROL ENABLE CB.HNDL, %IDC_BTN_RM1 CONTROL ENABLE CB.HNDL, %IDC_BTN_RMA ELSE CONTROL DISABLE CB.HNDL, %IDC_BTN_PVW CONTROL DISABLE CB.HNDL, %IDC_BTN_XT1 CONTROL DISABLE CB.HNDL, %IDC_BTN_XTA CONTROL DISABLE CB.HNDL, %IDC_BTN_RM1 CONTROL DISABLE CB.HNDL, %IDC_BTN_RMA END IF i = MAX(0,UBOUND(xd)) CONTROL SET TEXT CB.HNDL, %IDC_LBL_NFO, FORMAT$(i) & " chunk" & IIF$(i>1,"s","") & " of data detected:" DIALOG REDRAW CB.HNDL END MACRO '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ SUB ExtractOne_xd (BYVAL hDlg AS LONG, BYVAL xdId AS LONG) LOCAL dat AS STRING LOCAL typ AS STRING LOCAL tgt AS STRING typ = LCASE$(xd(xdID).desc) DISPLAY SAVEFILE hDlg, -100, 0, "Save As", _ $NUL, CHR$("All files (*.*)", 0, "*.*", 0), LEFT$(myExe,-3)+"xdata."+typ, _ "", %OFN_PATHMUSTEXIST OR %OFN_OVERWRITEPROMPT TO tgt IF tgt = "" THEN EXIT SUB dat = GetExeData(myExe, xd(xdID)) SetFile dat, tgt MessageBox hDlg, "ExeData successfully saved as:"+$CR+tgt, EXE.NAME$, %MB_ICONINFORMATION END SUB '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ SUB ExtractAll_xd (BYVAL hDlg AS LONG) LOCAL dat AS STRING LOCAL typ AS STRING LOCAL tgt AS STRING LOCAL i AS LONG LOCAL res AS STRING FOR i = UBOUND(xd) TO LBOUND(xd) STEP -1 typ = LCASE$(xd(i).desc) tgt = LEFT$(myExe,-3)+"xdata."+typ dat = GetExeData(myExe, xd(i)) SetFile dat, tgt res += "- " + MID$(tgt,INSTR(-1,tgt,"\")+1) + $CR NEXT MessageBox hDlg, "ExeData successfully saved as:"+$CR+res _ +"in folder "+$DQ+LEFT$(myExe,INSTR(-1,tgt,"\")-1)+$DQ, _ EXE.NAME$, %MB_ICONINFORMATION END SUB '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ SUB Preview_xd (BYVAL hParent AS LONG, BYVAL xdID AS LONG) LOCAL hD AS LONG LOCAL dat AS STRING LOCAL isBin AS LONG LOCAL hDib AS DWORD LOCAL hFont AS DWORD LOCAL w, h AS LONG dat = GetExeData(myExe, xd(xdID)) isBin = INSTR(dat, CHR$(0)) DIALOG NEW PIXELS, hParent, "xdmgr - viewer", -120, -70, _ 640, 320, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR _ %WS_CAPTION OR %WS_SYSMENU OR %WS_CLIPSIBLINGS OR _ %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _ %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING, TO hD DIALOG SET ICON hD, "ICO1" IF ISTRUE isBin THEN ' Picture.. or other? SetFile dat, EXE.PATH$ + "temp.img" GdipLoadImageFromFile UCODE$(EXE.PATH$ + "temp.img"), hDib IF ISTRUE hDib THEN CONTROL ADD GRAPHIC, hD, 1001, "", 2, 2, 636, 316, _ %WS_VISIBLE OR %WS_CHILD OR %SS_SUNKEN GRAPHIC ATTACH hD, 1001 GRAPHIC CLEAR %RGB_LIGHTGRAY GdipGetImageWidth hDib, w GdipGetImageHeight hDib, h GdipDrawImageRect hGdip(), hDib, 0, 0, w, h DIALOG SHOW MODAL hD GdipDisposeImage hDib KILL EXE.PATH$ + "temp.img" EXIT SUB END IF KILL EXE.PATH$ + "temp.img" END IF ' Text CONTROL ADD TEXTBOX, hD, 1001, "", 2, 2, 636, 316, _ %ES_MULTILINE OR %WS_BORDER OR %ES_READONLY OR _ %ES_WANTRETURN OR %WS_VSCROLL OR %ES_AUTOVSCROLL, _ %WS_EX_CLIENTEDGE OR %WS_EX_LEFT CONTROL SET COLOR hD, 1001, %BLACK, %WHITE CONTROL POST hD, 1001, %EM_SETSEL, -1, 0 FONT NEW "Courier New", 10 TO hFont CONTROL SET FONT hD, 1001, hFont IF ISFALSE isBin THEN CONTROL SET TEXT hD, 1001, dat ELSE dat = LEFT$(dat,2048) LOCAL s AS STRING FOR w = 1 TO LEN(dat) s += HEX$(ASC(dat,w),2)+$SPC NEXT s += $CRLF+"[...] (Truncated)" CONTROL SET TEXT hD, 1001, s END IF DIALOG SHOW MODAL hD FONT END hFont END SUB '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ FUNCTION AskDescriptor (BYVAL hParent AS DWORD) AS STRING ' Return descriptor of data chunk on 3 bytes, different from any existing one LOCAL hD AS DWORD DIALOG NEW PIXELS, hParent, "xdmgr - add exedata", , _ , 200, 80, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR _ %WS_CAPTION OR %WS_SYSMENU OR %WS_CLIPSIBLINGS OR _ %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _ %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hD DIALOG SET ICON hD, "ICO1" CONTROL ADD LABEL, hD, %IDC_LBL_DUM, _ "Alphanumeric 3-character description:", 8, 6, 200-16, 16 CONTROL ADD TEXTBOX, hD, %IDC_LBL_NFO, "", 70, 24, 60, 22, _ %ES_UPPERCASE OR %WS_BORDER OR %WS_TABSTOP OR %ES_AUTOHSCROLL, _ %WS_EX_CLIENTEDGE OR %WS_EX_LEFT CONTROL ADD BUTTON, hD, %IDCANCEL, "Cancel", 8, 50, 60, 24 CONTROL ADD BUTTON, hD, %IDOK, "OK", 200-8-60, 50, 60, 24 myNfo = "" DIALOG SHOW MODAL hD CALL AskDeskProc FUNCTION = myNfo END FUNCTION '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** CallBacks ** '------------------------------------------------------------------------------ CALLBACK FUNCTION AskDeskProc() LOCAL e AS STRING LOCAL i, found AS LONG IF CB.MSG = %WM_COMMAND THEN IF CB.CTL = %IDCANCEL THEN DIALOG END CB.HNDL ELSEIF CB.CTL = %IDOK THEN CONTROL GET TEXT CB.HNDL, %IDC_LBL_NFO TO e e = UCASE$(TRIM$(e)) IF LEN(e) <> 3 THEN MessageBox CB.HNDL, "Invalid descriptor!"+$CR _ +"Please type only 3 characters among A-Z and 0-9.", "xdmgr - error", %MB_ICONERROR CONTROL SET TEXT CB.HNDL, %IDC_LBL_NFO, "" CONTROL SET FOCUS CB.HNDL, %IDC_LBL_NFO EXIT FUNCTION END IF FOR i = LBOUND(xd) TO UBOUND(xd) IF xd(i).desc = e THEN found = i : EXIT FOR NEXT IF ISTRUE found THEN MessageBox CB.HNDL, "This descriptor is already in use!"+$CR _ +"Please choose another one...", "xdmgr - error", %MB_ICONERROR CONTROL SET TEXT CB.HNDL, %IDC_LBL_NFO, "" CONTROL SET FOCUS CB.HNDL, %IDC_LBL_NFO EXIT FUNCTION END IF ' We're good to go! myNfo = e DIALOG END CB.HNDL END IF END IF END FUNCTION '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ CALLBACK FUNCTION MainProc() LOCAL i, j AS LONG LOCAL res, desc AS STRING SELECT CASE AS LONG CB.MSG CASE %WM_INITDIALOG ' Initialization handler RefreshControls CASE %WM_COMMAND ' Process control notifications SELECT CASE AS LONG CB.CTL CASE %IDC_BTN_EXE ' Open EXE ... IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN DISPLAY OPENFILE CB.HNDL, -50, -100, "Select Program", $NUL, _ CHR$("Windows Executable", 0, "*.exe", 0), $NUL, "*.EXE", _ %OFN_FILEMUSTEXIST TO myExe IF myExe <> "" THEN RefreshControls END IF END IF CASE %IDC_BTN_ADD ' Add ExeData IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN DISPLAY OPENFILE CB.HNDL, -50, -100, "Select resource", $NUL, _ CHR$("All files (*.*)", 0, "*.*", 0), $NUL, $NUL, _ %OFN_FILEMUSTEXIST TO res IF res <> "" THEN desc = AskDescriptor(CB.HNDL) IF desc <> "" THEN res = AddExeData(myExe, desc, GetFile(res)) SetFile res, myExe RefreshControls END IF END IF END IF CASE %IDC_BTN_RM1 ' Remove One IF MessageBox(CB.HNDL, "Are you sure?", "xdmgr - remove one", _ %MB_ICONQUESTION OR %MB_YESNO) = %IDYES THEN LISTVIEW GET SELECT CB.HNDL, %IDC_LVW_LST TO i res = GetFile(myExe) IF i = UBOUND(xd) THEN j = LEN(res)+1 ELSE j = xd(i+1).address res = LEFT$(res, xd(i).address - 1) + MID$(res, j) SetFile res, myExe RefreshControls END IF CASE %IDC_BTN_RMA ' Remove All IF MessageBox(CB.HNDL, "Are you sure?", "xdmgr - remove all", _ %MB_ICONQUESTION OR %MB_YESNO) = %IDYES THEN SetFile ClearExeData(myExe), myExe RefreshControls END IF CASE %IDC_BTN_PVW ' Preview IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN LISTVIEW GET SELECT CB.HNDL, %IDC_LVW_LST TO i Preview_xd CB.HNDL, i END IF CASE %IDC_BTN_XT1 ' Extract One IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN LISTVIEW GET SELECT CB.HNDL, %IDC_LVW_LST TO i ExtractOne_xd CB.HNDL, i END IF CASE %IDC_BTN_XTA ' Extract All IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN ExtractAll_xd CB.HNDL END IF END SELECT END SELECT END FUNCTION '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ ' ** Dialogs ** '------------------------------------------------------------------------------ FUNCTION MainShow(BYVAL hParent AS DWORD) AS LONG LOCAL lRslt,lStyle AS LONG LOCAL hDlg AS DWORD DIALOG NEW PIXELS, hParent, $EXE+$SPC+$VER, , _ , 400, 246, %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR _ %WS_CAPTION OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR %WS_CLIPSIBLINGS OR _ %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _ %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _ %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg DIALOG SET ICON hDlg, "ICO1" CONTROL ADD LABEL, hDlg, %IDC_LBL_DUM, "Exe:", 8, 9, 40, 16 CONTROL ADD LABEL, hDlg, %IDC_LBL_EXE, "", 48, 8, 312, 16, _ %WS_CHILD OR %WS_VISIBLE OR %SS_LEFT OR %SS_SUNKEN OR %SS_PATHELLIPSIS, _ %WS_EX_STATICEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING CONTROL ADD BUTTON, hDlg, %IDC_BTN_EXE, "...", 360, 7, 32, 18 CONTROL ADD LABEL, hDlg, %IDC_LBL_NFO, "0 chunk of data detected:", 8, 30, 272, 16 CONTROL ADD LISTVIEW, hDlg, %IDC_LVW_LST, "", 8, 48, 384, 132 LISTVIEW INSERT COLUMN hDlg, %IDC_LVW_LST, 1, "#", 24, %SS_LEFT LISTVIEW INSERT COLUMN hDlg, %IDC_LVW_LST, 2, "ID", 70, %SS_LEFT LISTVIEW INSERT COLUMN hDlg, %IDC_LVW_LST, 3, "Type", 60, %SS_LEFT LISTVIEW INSERT COLUMN hDlg, %IDC_LVW_LST, 4, "Size", 90, %SS_LEFT LISTVIEW INSERT COLUMN hDlg, %IDC_LVW_LST, 5, "Offset", 100, %SS_LEFT LISTVIEW GET STYLEXX hDlg, %IDC_LVW_LST TO lStyle LISTVIEW SET STYLEXX hDlg, %IDC_LVW_LST, lStyle OR %LVS_EX_FULLROWSELECT OR %LVS_EX_GRIDLINES CONTROL ADD BUTTON, hDlg, %IDC_BTN_ADD, "Add ExeData", 129, 186, 80, 24, _ %WS_CHILD OR %WS_VISIBLE OR %WS_DISABLED OR %WS_TABSTOP OR %BS_TEXT _ OR %BS_PUSHBUTTON OR %BS_CENTER OR %BS_VCENTER, %WS_EX_LEFT OR _ %WS_EX_LTRREADING CONTROL ADD BUTTON, hDlg, %IDC_BTN_RM1, "Remove One", 220, 186, 80, 24, _ %WS_CHILD OR %WS_VISIBLE OR %WS_DISABLED OR %WS_TABSTOP OR %BS_TEXT _ OR %BS_PUSHBUTTON OR %BS_CENTER OR %BS_VCENTER, %WS_EX_LEFT OR _ %WS_EX_LTRREADING CONTROL ADD BUTTON, hDlg, %IDC_BTN_RMA, "Remove All", 312, 186, 80, 24, _ %WS_CHILD OR %WS_VISIBLE OR %WS_DISABLED OR %WS_TABSTOP OR %BS_TEXT _ OR %BS_PUSHBUTTON OR %BS_CENTER OR %BS_VCENTER, %WS_EX_LEFT OR _ %WS_EX_LTRREADING CONTROL ADD BUTTON, hDlg, %IDC_BTN_PVW, "Preview", 129, 216, 80, 24, _ %WS_CHILD OR %WS_VISIBLE OR %WS_DISABLED OR %WS_TABSTOP OR %BS_TEXT _ OR %BS_PUSHBUTTON OR %BS_CENTER OR %BS_VCENTER, %WS_EX_LEFT OR _ %WS_EX_LTRREADING CONTROL ADD BUTTON, hDlg, %IDC_BTN_XT1, "Extract One", 220, 216, 80, 24, _ %WS_CHILD OR %WS_VISIBLE OR %WS_DISABLED OR %WS_TABSTOP OR %BS_TEXT _ OR %BS_PUSHBUTTON OR %BS_CENTER OR %BS_VCENTER, %WS_EX_LEFT OR _ %WS_EX_LTRREADING CONTROL ADD BUTTON, hDlg, %IDC_BTN_XTA, "Extract All", 312, 216, 80, 24, _ %WS_CHILD OR %WS_VISIBLE OR %WS_DISABLED OR %WS_TABSTOP OR %BS_TEXT _ OR %BS_PUSHBUTTON OR %BS_CENTER OR %BS_VCENTER, %WS_EX_LEFT OR _ %WS_EX_LTRREADING DIALOG SHOW MODAL hDlg, CALL MainProc TO lRslt FUNCTION = lRslt END FUNCTION '------------------------------------------------------------------------------