It understands four different types of PureLibrary which are all the ones i know of (IMP, LIB, EDL, LSO, user libraries included), the format of which is different so the displayed output of each type also differs. PureLibrary format is undocumented and I didnt want to waste any of Freds valuable time so i spent all day in hex editor
Feedback welcome!
Sample screenshot, looking at an undocumented function where it has decoded the parameters, after using the Deep-Scan search to instantly find and jump to the function:
Code: Select all
;COMPILE IN ASCII
EnableExplicit
#VERSION$ = "v1.21"
Enumeration FormWindow
#DlgMain
EndEnumeration
Enumeration FormGadget
#lblPath
#txtPath
#btnBrowsePath
#listMainLibs
#txtFind
#btnFindFirst
#btnFindNext
#lblFind
#btnDeepScan
EndEnumeration
Declare ResizeGadgetsDlgMain()
Declare btnFindNext(EventType)
Declare listMainLibs(EventType)
Declare btnFindFirst(EventType)
Declare btnBrowsePath(EventType)
Declare btnDeepScan(EventType)
Procedure OpenDlgMain(x = 0, y = 0, width = 550, height = 380)
OpenWindow(#DlgMain, x, y, width, height, "PureLibrary Explorer v1.01 - Double-click a library...", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
TextGadget(#lblPath, 10, 10, 98, 20, "PureLibraries:")
StringGadget(#txtPath, 110, 10, 396, 20, "", #PB_String_ReadOnly)
SetGadgetColor(#txtPath, #PB_Gadget_BackColor,RGB(255,255,255))
ButtonGadget(#btnBrowsePath, 510, 6, 30, 26, "...")
ListIconGadget(#listMainLibs, 10, 40, 530, 300, "Type", 50, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(#listMainLibs, 1, "File Name", 230)
AddGadgetColumn(#listMainLibs, 2, "Internal", 150)
AddGadgetColumn(#listMainLibs, 3, "File Size", 80)
StringGadget(#txtFind, 60, 350, 200, 20, "")
ButtonGadget(#btnFindFirst, 268, 348, 82, 25, "Find First")
ButtonGadget(#btnFindNext, 353, 348, 82, 25, "Find Next")
TextGadget(#lblFind, 10, 350, 40, 20, "Find:", #PB_Text_Right)
ButtonGadget(#btnDeepScan, 450, 348, 90, 25, "Deep Scan...")
EndProcedure
Procedure ResizeGadgetsDlgMain()
Protected FormWindowWidth, FormWindowHeight
FormWindowWidth = WindowWidth(#DlgMain)
FormWindowHeight = WindowHeight(#DlgMain)
ResizeGadget(#txtPath, 110, 10, FormWindowWidth - 154, 20)
ResizeGadget(#btnBrowsePath, FormWindowWidth - 40, 6, 30, 26)
ResizeGadget(#listMainLibs, 10, 40, FormWindowWidth - 20, FormWindowHeight - 80)
ResizeGadget(#txtFind, 60, FormWindowHeight - 30, FormWindowWidth - 350, 20)
ResizeGadget(#btnFindFirst, FormWindowWidth - 282, FormWindowHeight - 32, 82, 25)
ResizeGadget(#btnFindNext, FormWindowWidth - 197, FormWindowHeight - 32, 82, 25)
ResizeGadget(#lblFind, 10, FormWindowHeight - 30, 40, 20)
ResizeGadget(#btnDeepScan, FormWindowWidth - 100, FormWindowHeight - 32, 90, 25)
EndProcedure
Procedure DlgMain_Events(event)
Select event
Case #PB_Event_SizeWindow
ResizeGadgetsDlgMain()
Case #PB_Event_CloseWindow
ProcedureReturn #False
Case #PB_Event_Menu
Select EventMenu()
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #btnBrowsePath
btnBrowsePath(EventType())
Case #listMainLibs
listMainLibs(EventType())
Case #btnFindFirst
btnFindFirst(EventType())
Case #btnFindNext
btnFindNext(EventType())
Case #btnDeepScan
btnDeepScan(EventType())
EndSelect
EndSelect
ProcedureReturn #True
EndProcedure
Enumeration FormWindow
#DlgViewer
EndEnumeration
Enumeration FormGadget
#listExtLibs
#listPureLibs
#frameFuncs
#lblFlags
#txtData
#txtDesc
#lblParams
#txtParams
#frameExtLibs
#framePureLibs
#listFuncs
EndEnumeration
Declare ResizeGadgetsDlgViewer()
Declare listPureLibs(EventType)
Declare listFuncs(EventType)
Procedure OpenDlgViewer(x = 0, y = 0, width = 490, height = 450)
OpenWindow(#DlgViewer, x, y, width, height, "PureLibrary Explorer", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered | #PB_Window_WindowCentered)
ListViewGadget(#listExtLibs, 20, 30, 210, 70)
ListViewGadget(#listPureLibs, 260, 30, 210, 70)
FrameGadget(#frameFuncs, 10, 120, 470, 320, "Functions: 0")
TextGadget(#lblFlags, 20, 390, 50, 20, "Data:")
StringGadget(#txtData, 80, 390, 390, 20, "")
EditorGadget(#txtDesc, 20, 320, 450, 60, #PB_Editor_ReadOnly | #PB_Editor_WordWrap)
SetGadgetColor(#txtDesc, #PB_Gadget_BackColor,RGB(242,242,242))
TextGadget(#lblParams, 20, 410, 50, 20, "Params:")
StringGadget(#txtParams, 80, 410, 390, 20, "")
FrameGadget(#frameExtLibs, 10, 10, 230, 100, "Library imports: 0")
FrameGadget(#framePureLibs, 250, 10, 230, 100, "PureLib dependencies: 0")
ListIconGadget(#listFuncs, 20, 140, 450, 180, "#", 50, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(#listFuncs, 1, "Params", 60)
AddGadgetColumn(#listFuncs, 2, "Offset", 60)
AddGadgetColumn(#listFuncs, 3, "Name", 270)
EndProcedure
Procedure ResizeGadgetsDlgViewer()
Protected FormWindowWidth, FormWindowHeight
FormWindowWidth = WindowWidth(#DlgViewer)
FormWindowHeight = WindowHeight(#DlgViewer)
ResizeGadget(#listExtLibs, 20, 30, FormWindowWidth - 280, 70)
ResizeGadget(#listPureLibs, FormWindowWidth - 230, 30, 210, 70)
ResizeGadget(#frameFuncs, 10, 120, FormWindowWidth - 20, FormWindowHeight - 130)
ResizeGadget(#lblFlags, 20, FormWindowHeight - 60, 50, 20)
ResizeGadget(#txtData, 80, FormWindowHeight - 60, FormWindowWidth - 100, 20)
ResizeGadget(#txtDesc, 20, FormWindowHeight - 130, FormWindowWidth - 40, 60)
ResizeGadget(#lblParams, 20, FormWindowHeight - 40, 50, 20)
ResizeGadget(#txtParams, 80, FormWindowHeight - 40, FormWindowWidth - 100, 20)
ResizeGadget(#frameExtLibs, 10, 10, FormWindowWidth - 260, 100)
ResizeGadget(#framePureLibs, FormWindowWidth - 240, 10, 230, 100)
ResizeGadget(#listFuncs, 20, 140, FormWindowWidth - 40, FormWindowHeight - 270)
EndProcedure
Procedure DlgViewer_Events(event)
Select event
Case #PB_Event_SizeWindow
ResizeGadgetsDlgViewer()
Case #PB_Event_CloseWindow
ProcedureReturn #False
Case #PB_Event_Menu
Select EventMenu()
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #listPureLibs
listPureLibs(EventType())
Case #listFuncs
listFuncs(EventType())
EndSelect
EndSelect
ProcedureReturn #True
EndProcedure
Enumeration FormWindow
#DlgDeep
EndEnumeration
Enumeration FormGadget
#listDeep
EndEnumeration
Declare ResizeGadgetsDlgDeep()
Declare listDeep(EventType)
Procedure OpenDlgDeep(x = 0, y = 0, width = 560, height = 320)
OpenWindow(#DlgDeep, x, y, width, height, "Deep-Scan Function Names", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered | #PB_Window_WindowCentered)
ListIconGadget(#listDeep, 0, 0, 560, 320, "Type", 60, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(#listDeep, 1, "File", 235)
AddGadgetColumn(#listDeep, 2, "Function", 250)
EndProcedure
Procedure ResizeGadgetsDlgDeep()
Protected FormWindowWidth, FormWindowHeight
FormWindowWidth = WindowWidth(#DlgDeep)
FormWindowHeight = WindowHeight(#DlgDeep)
ResizeGadget(#listDeep, 0, 0, FormWindowWidth - 0, FormWindowHeight - 0)
EndProcedure
Procedure DlgDeep_Events(event)
Select event
Case #PB_Event_SizeWindow
ResizeGadgetsDlgDeep()
Case #PB_Event_CloseWindow
ProcedureReturn #False
Case #PB_Event_Menu
Select EventMenu()
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #listDeep
listDeep(EventType())
EndSelect
EndSelect
ProcedureReturn #True
EndProcedure
Global *gmem, gViewMODE.s, gStrDeepFind.s, gDeepFile.s, gDeepScan.i, sLastSearch.s
Procedure AppEnd()
RemoveKeyboardShortcut(#DlgMain, #PB_Shortcut_Return)
End
EndProcedure
Procedure SafeCloseWindow(targetwnd)
If IsWindow(targetwnd):
CloseWindow(targetwnd):
EndIf
EndProcedure
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
#Slash$ = "\"
CompilerElse
#Slash$ = "/"
CompilerEndIf
Procedure.s DataToHex(*pmem, buflen.i)
If buflen <= 0: ProcedureReturn "": EndIf
Protected i.i, *pchar.ASCII, sOut.s
For *pchar = *pmem To *pmem + buflen-1
sOut + RSet(Hex(*pchar\a),2,"0")
Next
ProcedureReturn sOut
EndProcedure
Procedure.s SetReturns(sTxt.s)
Protected offset.i, *pchar.ASCII = @sTxt + Len(sTxt)-1
Repeat
*pchar - 1
Until *pchar\a = ' '
offset = *pchar - @sTxt
ProcedureReturn Left(sTxt, offset) + " retn " + Right(sTxt, Len(sTxt) - offset - 1)
EndProcedure
Procedure.s ParamDataToHex(*pmem, buflen.i)
Protected i.i, *pchar.ASCII, sOut.s, LastAddr.i, sTmp.s
If buflen <= 0: ProcedureReturn "": EndIf
LastAddr = *pmem + buflen-1
For *pchar = *pmem To LastAddr
Select gViewMODE
Case "LIB":
Select *pchar\a
Case $00: sOut + "Nul"
Case $40: sOut + "Str$"
Case $41: sOut + "*Float"
Case $42: sOut + "*Str"
Case $43: sOut + "*Float/Dbl"
Case $44: sOut + "*Dbl"
Case $20: sOut + "Float"
Case $04: sOut + "*Int"
Case $02,$08: sOut + "Int"
Case $10: sOut + "Str$"
Default:
sOut + RSet(Hex(*pchar\a),2,"0")
EndSelect
Case "EBL", "LSO":
Select *pchar\a
Case $0C: sOut + "Dbl"
Case $15: sOut + "Int"
Default:
sOut + RSet(Hex(*pchar\a),2,"0")
EndSelect
EndSelect
sOut + ", "
Next
If gViewMODE = "EBL" Or gViewMODE = "LSO"
If Len(sOut) > 4
sOut = Left(sOut,2) + ": " + Right(sOut, Len(sOut) - 4)
EndIf
ElseIf gViewMODE = "LIB"
sOut = SetReturns(sOut)
EndIf
ProcedureReturn Left(sOut,Len(sOut)-2)
EndProcedure
Global gFindLib.s, qFindSize.q
Procedure.i EnumDirFilesForSize (path$, pattern$)
Protected id.i, file$, fsize.q, sType.s, lenRootpath.i, sTmpFname.s
lenRootpath = Len(GetGadgetText(#txtPath))
id = ExamineDirectory(#PB_Any, path$, pattern$)
If id = 0: ProcedureReturn 0: EndIf
While NextDirectoryEntry(id)
If DirectoryEntryType(id) & #PB_DirectoryEntry_File
sTmpFname = LCase(DirectoryEntryName(id))
If GetExtensionPart(sTmpFname) <> "imp"
sTmpFname = Left(sTmpFname, Len(sTmpFname) - Len(GetExtensionPart(sTmpFname) ))
If Right(sTmpFname,1) = ".": sTmpFName = Left(sTmpFName, Len(sTmpFName) - 1): EndIf
If sTmpFname = gFindLib
file$ = path$ + DirectoryEntryName(id)
qFindSize = FileSize(file$)
gFindLib = GetExtensionPart(file$)
If gFindLib <> "": gFindLib = " " + gFindLib: EndIf
Break
EndIf
EndIf
EndIf
Wend
FinishDirectory(id)
ProcedureReturn 1
EndProcedure
Procedure.i EnumDirsForSize (path$, pattern$)
Protected id.i, exitCode.i
exitCode = EnumDirFilesForSize(path$, pattern$)
id = ExamineDirectory(#PB_Any, path$, "")
If id = 0: ProcedureReturn 0: EndIf
While (exitCode = 1) And NextDirectoryEntry(id)
If qFindSize <> 0: Break: EndIf
If DirectoryEntryType(id) & #PB_DirectoryEntry_Directory
If FindString("..", DirectoryEntryName(id)) = 0
exitCode = EnumDirsForSize(path$ + DirectoryEntryName(id) + #Slash$, pattern$)
EndIf
EndIf
Wend
FinishDirectory(id)
ProcedureReturn exitCode
EndProcedure
Procedure.s FindLibSize(sLib.s)
Protected sPath.s, sTmpLib.s
sTmpLib = Trim(LCase(sLib))
If GetExtensionPart(sTmpLib) <> ""
sTmpLib = Left(sTmpLib, Len(sTmpLib) - Len(GetExtensionPart(sTmpLib) + 1))
EndIf
gFindLib = Trim(LCase(sTmpLib))
qFindSize = 0
sPath = GetGadgetText(#txtPath)
If Right(sPath,1) <> #Slash$: sPath = sPath + #Slash$: EndIf
EnumDirsForSize(sPath, "*")
If qFindSize > 0: ProcedureReturn " (" + StrF(qFindSize / 1024,1) + "kb" + gFindLib + ")": EndIf
EndProcedure
Procedure.s GetPurelibType(file$)
Protected hFile.i, sMagic.s{5}, sType.s, sInternal.s
hFile = ReadFile(#PB_Any, file$, #PB_File_SharedRead)
If hFile
ReadData(hFile, @sMagic, 4)
If sMagic = "ERUP"
FileSeek(hFile,4)
ReadData(hFile, @sMagic, 4)
If PeekL(@sMagic) = 'EDLL'
sType = "EDL"
FileSeek(hFile,$0D)
ElseIf PeekL(@sMagic) = 'LSO1'
sType = "LSO"
FileSeek(hFile,$0D)
Else
FileSeek(hFile,8)
ReadData(hFile, @sMagic, 4)
sType = Chr(PeekA(@sMagic+3)) + Chr(PeekA(@sMagic+2)) + Chr(PeekA(@sMagic+1))
FileSeek(hFile,$14)
EndIf
sInternal = ReadString(hFile,#PB_Ascii)
CloseFile(hFile)
ProcedureReturn sType + "|" + sInternal
EndIf
EndIf
EndProcedure
Procedure ReadPureLSection(*pPureSect, lSize.l)
If PeekA(*pPureSect+8) <> 3: ProcedureReturn: EndIf
Protected sFunc.s, nParams.a, numfuncs.i, FuncAddr.i
Protected LastAddr = *pPureSect + lSize
Protected *gmem = *pPureSect + 13
Protected sName.s = PeekS(*gmem, -1, #PB_Ascii)
*gmem + Len(sName) + 1
While *gmem < LastAddr
FuncAddr = *gmem - *pPureSect
sFunc = PeekS(*gmem,-1,#PB_Ascii)
If gDeepScan = 1
If FindString(LCase(sFunc), gStrDeepFind) > 0
AddGadgetItem(#listDeep, -1, gViewMODE + #LF$ + gDeepFile + #LF$ + sFunc)
EndIf
EndIf
*gmem + Len(sFunc) + 1
nParams = PeekA(*gmem)
numfuncs + 1
If gDeepScan = 0: AddGadgetItem(#listFuncs, -1, Str(numfuncs) + #LF$ + Str(nParams) + #LF$ + Hex(FuncAddr) + #LF$ + sFunc): EndIf
If PeekA(*gmem+1) > 1: *gmem + nParams: EndIf
*gmem + 2
Wend
EndProcedure
Procedure ReadIMPFunc(*pmem)
Protected sFunc.s, nParams.a, sFunc2.s, sCmt.s, FuncAddr.i, sNew.s
sFunc = PeekS(*pmem,-1,#PB_Ascii)
*pmem + Len(sFunc) + 1
sFunc2 = PeekS(*pmem,-1,#PB_Ascii)
*pmem + Len(sFunc2) + 1
If gDeepScan = 1
If FindString(LCase(sFunc), gStrDeepFind) > 0
AddGadgetItem(#listDeep, -1, gViewMODE + #LF$ + gDeepFile + #LF$ + sFunc)
ElseIf FindString(LCase(sFunc2), gStrDeepFind) > 0
AddGadgetItem(#listDeep, -1, gViewMODE + #LF$ + gDeepFile + #LF$ + sFunc2)
EndIf
ProcedureReturn
EndIf
sCmt = PeekS(*pmem,-1, #PB_Ascii)
*pmem + Len(sCmt) + 1
nParams = PeekA(*pmem+14)
SetGadgetText(#txtDesc, sFunc2 + #CRLF$ + sCmt)
SetGadgetText(#txtParams, DataToHex(*pmem+18,nParams))
sFunc = DataToHex(*pmem,18)
sNew = Left(sFunc,8)+" "+Mid(sFunc,9,8)+" "+Mid(sFunc,17,8)+" "+Right(sFunc,Len(sFunc)-24)
SetGadgetText(#txtData, sNew)
EndProcedure
Procedure ReadPureIMPSection(*pPureSect, lSize.l)
Protected sFunc.s, nParams.a, sFunc2.s, sCmt.s, numfuncs.i, FuncAddr.i
Protected LastAddr.i = *pPureSect + lSize
Protected *pmem = *pPureSect + $14
Protected sLib.s = PeekS(*pmem, -1, #PB_Ascii)
If gDeepScan = 0: AddGadgetItem(#listExtLibs, -1, sLib + FindLibSize(sLib)): EndIf
*pmem + Len(sLib) + 1
While *pmem < LastAddr
FuncAddr = *pmem - *pPureSect
sFunc = PeekS(*pmem,-1,#PB_Ascii)
If gDeepScan = 1
If FindString(LCase(sFunc), gStrDeepFind) > 0
AddGadgetItem(#listDeep, -1, gViewMODE + #LF$ + gDeepFile + #LF$ + sFunc)
EndIf
EndIf
*pmem + Len(sFunc) + 1
sFunc2 = PeekS(*pmem,-1,#PB_Ascii)
*pmem + Len(sFunc2) + 1
sCmt = PeekS(*pmem,-1, #PB_Ascii)
*pmem + Len(sCmt) + 1
nParams = PeekA(*pmem+14)
*pmem + nParams + 18
numfuncs + 1
If gDeepScan = 0: AddGadgetItem(#listFuncs, -1, Str(numfuncs) + #LF$ + Str(nParams) + #LF$ + Hex(FuncAddr) + #LF$ + sFunc): EndIf
Wend
EndProcedure
Procedure ReadPureLIBSection(*pPureSect, lSize.l)
Protected cnt.i, sTmp.s, i.i, LastAddr.i, numfuncs.i, FuncParams.i, FuncAddr.i
Protected sFuncName.s, sFuncDesc.s
Protected *pmem = *pPureSect + 20
Protected sPureLibName.s, sPureInternalName.s
LastAddr = *pPureSect + lSize
sPureLibName = PeekS(*pmem,-1,#PB_Ascii)
*pmem + Len(sPureLibName) + 1
While *pmem < LastAddr
Select PeekA(*pmem)
Case 01:
cnt = PeekA(*pmem+1)
If cnt
*pmem + 2
For i = 1 To cnt
sTmp = PeekS(*pmem,-1,#PB_Ascii)
If gDeepScan = 0: AddGadgetItem(#listExtLibs, -1, sTmp + FindLibSize(sTmp)): EndIf
*pmem + Len(sTmp) + 1
Next i
Else
*pmem + 2
EndIf
Case 02:
*pmem + 1
sPureInternalName = PeekS(*pmem,-1,#PB_Ascii)
*pmem + Len(sPureInternalName)
cnt = PeekA(*pmem+1)
If cnt
*pmem + 2
For i = 1 To cnt
sTmp = PeekS(*pmem,-1,#PB_Ascii)
If gDeepScan = 0: AddGadgetItem(#listPureLibs, -1, sTmp + FindLibSize(sTmp)): EndIf
*pmem + Len(sTmp) + 1
Next i
Else
*pmem + 2
EndIf
While *pmem < LastAddr
FuncAddr = *pmem - *pPureSect
sFuncName = PeekS(*pmem,-1,#PB_Ascii)
If gDeepScan = 1
If FindString(LCase(sFuncName), gStrDeepFind) > 0
AddGadgetItem(#listDeep, -1, gViewMODE + #LF$ + gDeepFile + #LF$ + sFuncName)
EndIf
EndIf
*pmem + Len(sFuncName) + 1
FuncParams = PeekA(*pmem)
*pmem + 5 + FuncParams
sFuncDesc = PeekS(*pmem,-1,#PB_Ascii)
*pmem + Len(sFuncDesc) + 1
numfuncs + 1
If gDeepScan = 0: AddGadgetItem(#listFuncs, -1, Str(numfuncs) + #LF$ + Str(FuncParams) + #LF$ + Hex(FuncAddr) + #LF$ + sFuncName): EndIf
Wend
Break
Default:
If gDeepScan = 0: MessageRequester("Error","Parse error, aborting the rest"): Break: EndIf
EndSelect
Wend
EndProcedure
Procedure.s ReadLIBDesc(qOffset.q)
Protected sFuncName.s, FuncParams.i, sFuncDesc.s, *pmem
*pmem = *gmem + qOffset
sFuncName = PeekS(*pmem,-1,#PB_Ascii)
*pmem + Len(sFuncName) + 1
FuncParams = PeekA(*pmem)
*pmem + 5 + FuncParams
SetGadgetText(#txtData, DataToHex(*pmem-4,4))
sFuncDesc = PeekS(*pmem,-1,#PB_Ascii)
ProcedureReturn Trim(sFuncDesc)
EndProcedure
Procedure ShowPureLibrary(sFile.s, sType.s)
Protected hFile.i, qLof.q
If *gmem
FreeMemory(*gmem): *gmem = 0
EndIf
gDeepScan = 0
hFile = ReadFile(#PB_Any, sFile, #PB_File_SharedRead)
If hFile
gViewMODE = sType
OpenDlgViewer()
qLof = Lof(hFile)
*gmem = AllocateMemory(qLof)
If *gmem
ReadData(hFile, *gmem, qLof)
Else
MessageRequester("Error","AllocateMemory failed"): CloseFile(hFile): ProcedureReturn
EndIf
CloseFile(hFile)
SetWindowTitle(#DlgViewer, "PureLibrary Viewer - " + GetFilePart(sFile) + " [" + gViewMODE + "]")
Select gViewMODE
Case "EDL", "LSO":
DisableGadget(#frameExtLibs,1): DisableGadget(#framePureLibs,1): DisableGadget(#listExtLibs,1): DisableGadget(#listPureLibs,1)
DisableGadget(#txtDesc,1): DisableGadget(#lblFlags,1): DisableGadget(#txtData,1)
SetGadgetText(#frameExtLibs, "Library imports: n/a"): SetGadgetText(#framePureLibs, "PureLib dependencies: n/a")
ReadPureLSection(*gmem, qLof)
Case "IMP":
ReadPureIMPSection(*gmem, qLof)
Case "LIB":
ReadPureLIBSection(*gmem, PeekL(*gmem+4))
EndSelect
SetGadgetText(#frameFuncs, "Functions: " + Str(CountGadgetItems(#listFuncs)))
SetGadgetText(#frameExtLibs, "Library imports: " + Str(CountGadgetItems(#listExtLibs)))
SetGadgetText(#framePureLibs, "PureLib dependencies: " + Str(CountGadgetItems(#listPureLibs)))
Else
MessageRequester("Error","Couldn't open file")
EndIf
EndProcedure
Procedure ScanPureLibrary(sFile.s, sShortFile.s, sType.s)
Protected hFile.i, qLof.q
If *gmem
FreeMemory(*gmem): *gmem = 0
EndIf
hFile = ReadFile(#PB_Any, sFile, #PB_File_SharedRead)
If hFile
gViewMODE = sType
qLof = Lof(hFile)
*gmem = AllocateMemory(qLof)
If *gmem
ReadData(hFile, *gmem, qLof)
Else
CloseFile(hFile):
ProcedureReturn
EndIf
CloseFile(hFile)
gDeepFile = sShortFile
Select gViewMODE
Case "EDL", "LSO":
ReadPureLSection(*gmem, qLof)
Case "IMP":
ReadPureIMPSection(*gmem, qLof)
Case "LIB":
ReadPureLIBSection(*gmem, PeekL(*gmem+4))
EndSelect
EndIf
EndProcedure
Global cntEDL.i, cntIMP.i, cntLIB.i, cntLSO.i, gDeepScan.i
Procedure.i EnumDirFiles (path$, pattern$)
Protected id.i, file$, fsize.q, sType.s, lenRootpath.i
lenRootpath = Len(GetGadgetText(#txtPath))
id = ExamineDirectory(#PB_Any, path$, pattern$)
If id = 0: ProcedureReturn 0: EndIf
While NextDirectoryEntry(id)
If DirectoryEntryType(id) & #PB_DirectoryEntry_File
file$ = path$ + DirectoryEntryName(id)
fsize = FileSize(file$)
If fsize > 0
sType = GetPurelibType(file$)
Select Left(sType,3)
Case "LSO":
cntLSO + 1
Case "EDL":
cntEDL + 1
Case "IMP":
cntIMP + 1
Case "LIB":
cntLIB + 1
Default:
Continue
EndSelect
If gDeepScan = 1
ScanPureLibrary(file$, Right(file$, Len(file$) - lenRootpath), Left(sType,3))
Else
file$ = Right(file$, Len(file$) - lenRootpath)
AddGadgetItem(#listMainLibs,-1, Left(sType,3) + #LF$ + file$ + #LF$ + Right(sType, Len(sType)-4) + #LF$ + Str(fSize))
EndIf
EndIf
EndIf
Wend
FinishDirectory(id)
ProcedureReturn 1
EndProcedure
Procedure.i EnumDirs (path$, pattern$)
Protected id.i, exitCode.i
exitCode = EnumDirFiles(path$, pattern$)
id = ExamineDirectory(#PB_Any, path$, "")
If id = 0: ProcedureReturn 0: EndIf
While (exitCode = 1) And NextDirectoryEntry(id)
If DirectoryEntryType(id) & #PB_DirectoryEntry_Directory
If FindString("..", DirectoryEntryName(id)) = 0
exitCode = EnumDirs(path$ + DirectoryEntryName(id) + #Slash$, pattern$)
EndIf
EndIf
Wend
FinishDirectory(id)
ProcedureReturn exitCode
EndProcedure
Procedure BrowseFolderForPurelibs(sPath.s)
If FileSize(sPath) <> -2
MessageRequester("Error","Not a directory: " + sPath)
Else
ClearGadgetItems(#listMainLibs)
If Right(sPath,1) <> #Slash$: sPath = sPath + #Slash$: EndIf
SetWindowTitle(#DlgMain, "PureLibrary Explorer " + #VERSION$ + " - Scanning " + sPath + " ...")
SetGadgetText(#txtPath, sPath)
cntEDL.i = 0: cntIMP.i = 0: cntLIB.i = 0: cntLSO.i = 0
EnumDirs(sPath, "*")
SetWindowTitle(#DlgMain, "PureLibrary Explorer " + #VERSION$ + " - Found " + Str(cntLIB + cntIMP + cntEDL + cntLSO) + " (" + Str(cntLIB) + " LIB, " + Str(cntIMP) + " IMP, " + Str(cntEDL) + " EDL, " + Str(cntLSO) + " LSO)")
EndIf
EndProcedure
Procedure btnBrowsePath(EventType)
Protected sCurdir.s = GetGadgetText(#txtPath)
Protected sPath.s = PathRequester("Select PureLibraries path...", sCurdir)
If sPath <> ""
BrowseFolderForPurelibs(sPath)
EndIf
EndProcedure
Procedure listFuncs(EventType)
Protected iItem.i, sOffset.s, iOffset.i, sParams.s, sFunc.s, sDesc.s, sHexParams.s
Select EventType
Case #PB_EventType_Change:
iItem = GetGadgetState(#listFuncs)
If iItem < 0: ProcedureReturn: EndIf
sParams = GetGadgetItemText(#listFuncs, iItem, 1)
sOffset = GetGadgetItemText(#listFuncs, iItem, 2)
sFunc = GetGadgetItemText(#listFuncs, iItem, 3)
iOffset = Val("$" + sOffset)
If gViewMODE = "LIB"
If Val(sParams) > 0
If PeekA(*gmem + iOffset + Len(sFunc) + 2) > 1
sHexParams = DataToHex(*gmem + Len(sFunc) + 2 + iOffset, Val(sParams)+1)
SetGadgetText(#txtParams, sHexParams + ": " + ParamDataToHex(*gmem + Len(sFunc) + 2 + iOffset, Val(sParams)+1) )
Else
sHexParams = DataToHex(*gmem + Len(sFunc) + 2 + iOffset, 1)
SetGadgetText(#txtParams, sHexParams + ": " + ParamDataToHex(*gmem + Len(sFunc) + 2 + iOffset, 1))
EndIf
Else
SetGadgetText(#txtParams, "")
EndIf
sDesc = ReadLIBDesc(Val("$"+sOffset))
SetGadgetText(#txtDesc, sDesc)
ElseIf gViewMODE = "IMP"
ReadIMPFunc(*gmem + Val("$"+sOffset))
EndIf
EndSelect
EndProcedure
Procedure listPureLibs(EventType)
Protected sPath.s, sPureLib.s, iPos.i
If EventType = #PB_EventType_LeftDoubleClick
If GetGadgetState(#listPureLibs) < 0: ProcedureReturn: EndIf
sPath = GetGadgetText(#txtPath)
If Right(sPath,1) <> #Slash$: sPath = sPath + #Slash$: EndIf
sPureLib = GetGadgetText(#listPureLibs)
iPos = FindString(sPureLib, " (")
If iPos: sPurelib = Left(sPureLib, iPos-1): EndIf
ShowPureLibrary (sPath + sPureLib, "LIB")
EndIf
EndProcedure
Procedure btnDeepScan(EventType)
OpenDlgDeep()
Protected sPath.s = Trim(GetGadgetText(#txtPath))
If sPath <> ""
gStrDeepFind = LCase(GetGadgetText(#txtFind))
gDeepScan = 1
SetWindowTitle(#DlgDeep, "Deep-Scan Function Names - Scanning...")
EnumDirs(sPath, "*")
SetWindowTitle(#DlgDeep, "Deep-Scan Function Names")
gDeepScan = 0
EndIf
EndProcedure
Procedure listDeep(EventType)
Protected sPath.s, sPureLib.s, sPureType.s, sPureFunc.s, iPos.i, i.i, cnt.i
If EventType = #PB_EventType_LeftDoubleClick
iPos = GetGadgetState(#listDeep)
If iPos < 0: ProcedureReturn: EndIf
sPath = GetGadgetText(#txtPath)
If Right(sPath,1) <> #Slash$: sPath = sPath + #Slash$: EndIf
sPureType = GetGadgetItemText(#listDeep, iPos,0)
sPureLib = GetGadgetItemText(#listDeep, iPos,1)
ShowPureLibrary(sPath + sPureLib, sPureType)
sPureFunc = GetGadgetItemText(#listDeep, iPos,2)
cnt = CountGadgetItems(#listFuncs)
If cnt <= 0: ProcedureReturn: EndIf
For i = 0 To cnt-1
If GetGadgetItemText(#listFuncs,i,3) = sPureFunc
SetGadgetState(#listFuncs,i)
listFuncs(#PB_EventType_Change)
Break
EndIf
Next i
EndIf
EndProcedure
Procedure.i SearchList(listid.i, sFind.s, startpos.i=0)
Protected i.i, cnt.i
cnt = CountGadgetItems(listid)
If cnt <= 0: ProcedureReturn: EndIf
sFind = LCase(sFind)
For i = startpos To cnt-1
If FindString(LCase(GetGadgetItemText(listid,i,1)), sFind) > 0
SetGadgetState(listid,i):
ProcedureReturn i
ElseIf FindString(LCase(GetGadgetItemText(listid,i,2)), sFind) > 0
SetGadgetState(listid,i):
ProcedureReturn i
EndIf
Next i
ProcedureReturn -1
EndProcedure
Procedure btnFindFirst(EventType)
Protected sFind.s
sFind = GetGadgetText(#txtFind)
If sFind = "": ProcedureReturn: EndIf
SetActiveGadget(#btnFindNext)
If SearchList(#listMainLibs, sFind, 0) = -1
If MessageRequester("Find", "Not found. Deep-scan?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
btnDeepScan(0)
EndIf
EndIf
EndProcedure
Procedure btnFindNext(EventType)
Protected sFind.s, curpos.i
sFind = GetGadgetText(#txtFind)
If sFind = "": ProcedureReturn: EndIf
curpos = GetGadgetState(#listMainLibs)
If SearchList(#listMainLibs, sFind, curpos+1) = -1
If sLastSearch = sFind:
MessageRequester("Find", "End of search"):
Else:
MessageRequester("Find", "Not found"):
EndIf
EndIf
sLastSearch = sFind
EndProcedure
Procedure listMainLibs(EventType)
Protected sName.s, curpos.i, sPath.s
If EventType = #PB_EventType_LeftDoubleClick
curpos = GetGadgetState(#listMainLibs)
If curpos < 0: ProcedureReturn: EndIf
sName = GetGadgetItemText(#listMainLibs, curpos, 1)
sPath = GetGadgetText(#txtPath)
If Right(sPath,1) <> #Slash$: sPath = sPath + #Slash$: EndIf
ShowPureLibrary (sPath + sName, GetGadgetItemText(#listMainLibs, curpos, 0))
EndIf
EndProcedure
Procedure AppMain()
Protected eventId.i, eventWnd.i, sPurelibsPath.s
If SizeOf(Character) = 2
MessageRequester("Compile Error","My bad, Unicode not supported - please use Ascii compile"):
End
EndIf
OpenDlgMain()
WindowBounds(#DlgMain, 350, 150, #PB_Ignore, #PB_Ignore)
AddKeyboardShortcut(#DlgMain, #PB_Shortcut_Return, #PB_Key_Return)
sPurelibsPath = #PB_Compiler_Home + "purelibraries"
BrowseFolderForPurelibs(sPurelibsPath)
SetActiveGadget(#txtFind)
Repeat
eventId = WaitWindowEvent()
eventWnd = EventWindow()
Select eventId
Case #PB_Event_Menu
If EventMenu() = #PB_Key_Return
Select GetActiveGadget()
Case #txtFind
btnFindFirst(0)
Case #btnFindFirst
btnFindFirst(0)
Case #btnFindNext
btnFindNext(0)
EndSelect
EndIf
Case #PB_Event_CloseWindow
If eventWnd = #DlgMain
AppEnd()
Else
SafeCloseWindow(eventWnd)
If *gmem: FreeMemory(*gmem): *gmem = 0: EndIf
EndIf
Default:
Select eventWnd
Case #DlgMain
DlgMain_Events(eventId)
Case #DlgViewer
DlgViewer_Events(eventId)
Case #DlgDeep
DlgDeep_Events(eventId)
EndSelect
EndSelect
ForEver
EndProcedure
AppMain()
AppEnd()