home *** CD-ROM | disk | FTP | other *** search
- ' EXE Signature for different operating systems
-
- Global Const IMAGE_DOS_SIGNATURE = &H5A4D ' MZ
- Global Const IMAGE_OS2_SIGNATURE = &H454E ' NE
- Global Const IMAGE_OS2_SIGNATURE_LE = &H454C ' LE
- Global Const IMAGE_NT_SIGNATURE = &H4550 ' PE(00)
-
- ' Header appearing at the beginning of all DOS executables.
-
- Type DOSEXEHEADER
-
- usSignature As Integer ' EXE signature
- cbExtra As Integer ' Bytes on last page of file
- cPages As Integer ' Pages in file
- cRelocItems As Integer ' Relocations
- cphHeader As Integer ' Size of header in paragraphs
- cphMinAlloc As Integer ' Minimum extra paragraphs needed
- cphMaxAlloc As Integer ' Maximum extra paragraphs needed
- usInitSS As Integer ' Initial (relative SS value
- usInitSP As Integer ' Initial SP value
- usCheckSum As Integer ' Checksum
- usInitIP As Integer ' Initial IP value
- usInitCS As Integer ' Initial (relative CS value
- usRelocTable As Integer ' File address of relocation table
- usOverlayNumber As Integer ' Overlay number
- rgchReserved1 As String * 8 ' Reserved bytes
- usOEMID As Integer ' OEM identifier (for usoeminfo
- usOEMInfo As Integer ' OEM information As Integer usoemid specific
- rgchReserved2 As String * 20 ' Reserved bytes
- offlNewHeader As Long ' File address of new exe header
-
- End Type
-
- ' New Header within all Windows executables.
- ' This header appears at the offset specified in the
- ' offlNewHeader of DOSEXEHEADER.
-
- Type NEHEADER
-
- usSignature As Integer ' NE signature
- bLinkerVersion As String * 1 ' Linker version number
- bLinkerRevision As String * 1 ' Linker revision number
- offusEntryTable As Integer ' Offset to the entry table
- cbEntryTable As Integer ' Size of the entry table
- rgchReserved1 As String * 4 ' Reserved
- usContents As Integer ' Bit-field describing the contents
- usAutoDSNum As Integer ' Automatic data segment number
- cbInitHeapSize As Integer ' Initial local heap size
- cbInitStackSize As Integer ' Initial stack size
- dwCSIP As Long ' CS:IP
- dwSSSP As Long ' SS:SP
- cSegmentEntries As Integer ' Number of entries in the segment table
- cModRefEntries As Integer ' Number of entries in the module reference table
- cNonResNameEntries As Integer ' Number of entries in the non-resident name table
- offusSegTable As Integer ' Offset to the segment table
- offusResTable As Integer ' Offset to the resource table
- offusResNameTable As Integer ' Offset to the resident name table
- offusModRefTable As Integer ' Offset to the module reference table
- offusImpNameTable As Integer ' Offset to the imported name table
- offusNonResNameTable As Integer ' Offset to the non-resident name table
- cMovEntryPoints As Integer ' Number of moveable entry points
-
- ' The rest of the header information has not been included.
-
- End Type
-
- ' Resource Types
-
- Const RT_CURSOR = 1
- Const RT_BITMAP = 2
- Const RT_ICON = 3
- Const RT_MENU = 4
- Const RT_DIALOG = 5
- Const RT_STRING = 6
- Const RT_FONTDIR = 7
- Const RT_FONT = 8
- Const RT_ACCELERATOR = 9
- Const RT_RCDATA = 10
- Const RT_GROUP_CURSOR = 12
- Const RT_GROUP_ICON = 14
-
- ' Structure describing a resource type in the
- ' resource table.
-
- Type RESTYPEINFO
-
- usType As Integer ' Resource type
- cEntries As Integer ' Number of entries of this resource type
- Reserved1 As String * 4 ' Reserved
-
- End Type
-
- Type RESNAMEINFO
-
- offusData As Integer ' Offset to resource data
- cbLen As Integer ' Length of resource data
- usFlags As Integer ' Resource flags
- id As Integer ' Resource ID
- handle As Integer ' Reserved for run-time
- cUsage As Integer ' Reserved for run-time
-
- End Type
-
- ' Error base code
- Const GATERR_BASE = 32000
-
- Global Const GATERR_NOTDOSEXE = GATERR_BASE + 0 ' Not a DOS executable
- Global Const GATERR_NOTWINEXE = GATERR_BASE + 1 ' Not a Windows executable
- Global Const GATERR_NOTVBEXE = GATERR_BASE + 2 ' Not a Visual Basic application
-
- Global Const GATERR_FIRST = GATERR_BASE
- Global Const GATERR_LAST = GATERR_BASE + 20
-
- Function GetAppTitle (ByVal sFileName As String) As String
-
- Dim hfile As Integer
- Dim deh As DOSEXEHEADER
- Dim neh As NEHEADER
- Dim usShiftCount As Integer
- Dim lAlignment As Long
- Dim rti As RESTYPEINFO
- Dim rni As RESNAMEINFO
- Dim I As Integer
- Dim sData As String
- Dim cchTitle As Integer
-
- hfile = FreeFile
-
- ' Check to see if the file exists at first. This
- ' is important because attempting to open a non-
- ' existant file in Binary mode will actually
- ' create it.
-
- If Dir$(sFileName) = "" Then
- Error 53
- End If
-
- Open sFileName For Binary As hfile
-
- ' Get the DOS executable header.
- Get hfile, , deh
-
- ' Make sure we are dealing with at least a DOS executable.
- ' All Windows executables begin with a DOS header, so this
- ' will be our first check.
-
- If deh.usSignature <> IMAGE_DOS_SIGNATURE Then
- Error GATERR_NOTDOSEXE
- End If
-
- ' Next make sure that we are dealing with a Windows
- ' executable, and therefore not only a DOS one.
-
- If deh.usRelocTable < &H40 Then
- Error GATERR_NOTWINEXE
- End If
-
- ' Go and read the new executable header found in
- ' Windows executables.
- Seek hfile, deh.offlNewHeader + 1
- Get hfile, , neh
-
- ' Go to the table of the resources. The resource table
- ' offset is relative to the beginning of the new
- ' executable header, thus the addition below.
-
- Seek hfile, deh.offlNewHeader + neh.offusResTable + 1
-
- ' Retrieve the shift count found at the beginning
- ' of the resource table. This is used to adjust the
- ' offsets and sizes in the resource entries.
-
- Get hfile, , usShiftCount
- lAlignment = 2 ^ usShiftCount
-
- ' Loop that walks through all the resource types
- ' like icons, bitmaps, dialog boxes, user-defined, etc.
- Do
-
- ' Get the resource type information.
- Get hfile, , rti
-
- ' If we're at the end of the table then break
- ' out of the loop. If this occurs, it usually
- ' implies that no App.Title string was found
- ' for the executable. This may happen if the
- ' executable is not a VB 3.0 application.
-
- If rti.usType = 0 Then Exit Do
-
- ' Walk through all the entries of the current
- ' resource type.
- For I = 1 To rti.cEntries
-
- ' Get the resource name information entry.
- Get hfile, , rni
-
- ' Are we dealing with a raw data resource here?
- ' Because that is what we're interested in.
- If rti.usType = (&H8000 Or RT_RCDATA) Then
-
- ' Is the integer Id of this resource 1?
- If rni.id = &H8001 Then
-
- ' Good, we've found the resource we
- ' wanted.
-
- ' Now go to the offset where its data
- ' can be found. Remember that offsets
- ' and sizes in the resource table need
- ' to be re-aligned.
-
- Seek hfile, rni.offusData * lAlignment + 1
-
- ' Allocate space to receive the resource
- ' data and then read it in. Note that we
- ' only read in the first 256 bytes in case
- ' the resource runs longer. This is because
- ' it is pointless to read the entire
- ' resource (as it can be as big as 4K on
- ' certain large projects) when the App.Title
- ' string appears somewhere in the beginning.
- ' This will also make the function faster
- ' and less memory hungary.
-
- sData = Space(Min(rni.cbLen * lAlignment, 256))
- Get hfile, , sData
-
- ' The length of the title string is at offset
- ' &H15 in the resource (it includes the null-
- ' terminator, but we substract it).
-
- cchTitle = Asc(Mid$(sData, 16, 1)) - 1
-
- ' Just a safety guard. App.Title cannot be
- ' longer than 40 characters.
-
- If cchTitle > 40 Then
- Exit Do
- End If
-
- ' OK, the App.Title string should be at offset
- ' &H13 of the resource data.
-
- If cchTitle > 0 Then
- GetAppTitle = Mid$(sData, 20, cchTitle)
- End If
-
- ' We don't need to process any further. We've
- ' found the required item, so close the file
- ' and exit.
-
- Close hfile
- Exit Function
-
- End If
-
- End If
-
- Next I
-
- Loop
-
- Close hfile
-
- ' We didn't find the resource we were looking for
- ' when it should usually be there for all VB generated
- ' executables. So treat this as a case of error.
- Error GATERR_NOTVBEXE
-
- End Function
-
- Function Min (ByVal A As Variant, ByVal B As Variant)
-
- ' NOTE: We don't use the IIf function here instead
- ' because that pulls in an extra DLL---the
- ' MSAFINX.DLL).
-
- If A < B Then
- Min = A
- Else
- Min = B
- End If
-
- End Function
-
-