Results 1 to 4 of 4

Thread: Digging Through a VB6 Project ... A "Working" Thread

  1. #1

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,936

    Digging Through a VB6 Project ... A "Working" Thread

    I've put this thread over here because it's not really a question.

    When it's all done, I might clean it all up and make a CodeBank entry ... we'll see.

    My idea is to develop code for digging through all the Modules, Procedures, & Arguments of a VB6 project. And I'd like this to work equally well when running in the IDE as compiled.

    This is not any attempt to disassemble a compiled VB6 EXE, although some of the concepts will be the same.

    My primary purpose is to develop some tools that can be useful within a VB6 project we're developing. Just as an example, in my recently developed CallBack-in-COM code, it'd be nice if I could validate that the CallBack procedure's arguments are either ByRef or 4-byte ByVal. But that's rather far down the road from where this is starting.

    I'll start with an exploration of the ObjectTable structure, but I haven't even put together a good example of that yet. That'll be my first order of business.

    Also, I'll attempt to provide definitions of all the structures (i.e., UDTs) as we go.

    ---------------

    Anyone is invited to contribute/participate in this thread.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  2. #2
    Hyperactive Member
    Join Date
    Jun 2016
    Location
    EspaƱa
    Posts
    508

    Re: Digging Through a VB6 Project ... A "Working" Thread

    I prefer in the other sections of the codebank forum.
    I don't usually have much time to browse sub forums.
    You will also have more visibility in the main forums.
    I am very interested in this topic, even if I don't understand it

    greeting

  3. #3

    Thread Starter
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    9,936

    Re: Digging Through a VB6 Project ... A "Working" Thread

    Ok, here's the start of it.

    Goes in a BAS module:
    Code:
    
    Option Explicit
    '
    Private Enum PTR: [__PTR]: End Enum ' Just to declare a PTR as a Long.
    '
    Private Declare Function GetMem4 Lib "msvbvm60" (ByRef Source As Any, ByRef Dest As Any) As Long
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Dest As Any, ByRef Source As Any, ByVal Length As Long)
    Private Declare Sub EbGetExecutingProj Lib "vba6" (ByRef pProject As IUnknown)
    
    
    Public Type ObjectTableType
        ' This is about as high a level structure as you can get that's
        ' applicable during both IDE running and compiled running.
        lpHeapLink         As Long      ' &h00 Unused after compilation, always 0.
        lpExecProj         As Long      ' &h04 Pointer to VB Project Exec COM Object.
        lpProjectInfo2     As Long      ' &h08 Secondary Project Information.
        dwReserved         As Long      ' &h0C Always set to -1 after compiling. Unused.
        dwNull             As Long      ' &h10 Not used in compiled mode.
        lpProjectObject    As Long      ' &h14 Pointer to in-memory Project Data.
        uuidObject(15)     As Byte      ' &h18 GUID of the Object Table.
        fCompileState      As Integer   ' &h28 Internal flag used during compilation.
        dwTotalObjects     As Integer   ' &h2A Total objects present in Project.
        dwCompiledObjects  As Integer   ' &h2C Equal to above after compiling.
        dwObjectsInUse     As Integer   ' &h2E Usually equal to above after compile.
        lpObjectArray      As Long      ' &h30 Pointer to array of Object Descriptors (PublicObjectDescriptor).
        fIdeFlag           As Long      ' &h34 Flag/Pointer used in IDE only.
        lpIdeData          As Long      ' &h38 Flag/Pointer used in IDE only.
        lpIdeData2         As Long      ' &h3C Flag/Pointer used in IDE only.
        lpszProjectName    As Long      ' &h40 Pointer to Project Name.
        dwLcid             As Long      ' &h44 LCID of Project.
        dwLcid2            As Long      ' &h48 Alternate LCID of Project.
        lpIdeData3         As Long      ' &h4C Flag/Pointer used in IDE only.
        dwIdentifier       As Long      ' &h50 Template Version of Structure.
    End Type                            ' &h54 Size.
    
    Public Function GetObjectTable() As ObjectTableType     ' Thanks to The Trick for working this out.
        Dim bIsInIDE As Boolean: Debug.Assert MakeTrue(bIsInIDE)
        Dim pObjTable As PTR
        If bIsInIDE Then
            Dim cProj       As IUnknown
            Dim pExecProj   As PTR
            EbGetExecutingProj cProj                        ' Reference to the entire project within the IDE.
            GetMem4 ByVal ObjPtr(cProj) + &HCBC&, pExecProj ' The Trick's magic, pointing to MoreTrickMagic structure.
            GetMem4 ByVal pExecProj + &HC&, pObjTable       ' Pointer to ObjectTable structure from MoreTrickMagic.
        Else
            Dim pProj       As PTR
            Dim pVBHdr      As PTR
            Dim pProjInfo   As PTR
            GetMem4 ByVal ObjPtr([Global]) + &H34&, pProj
            GetMem4 ByVal pProj + &H10&, pVBHdr             ' Pointer to VBHeader structure, which is available once compiled to EXE.
            GetMem4 ByVal pVBHdr + &H30&, pProjInfo         ' Pointer to ProjectInfo structure from VBHeader, which is available once compiled to EXE.
            GetMem4 ByVal pProjInfo + &H4&, pObjTable       ' Pointer to ObjectTable structure from ProjectInfo.
        End If
        ' Now, we've got a pointer to the ObjectTable, which is available in both the IDE and compiled.
        CopyMemory GetObjectTable, ByVal pObjTable, LenB(GetObjectTable)
    End Function
    
    
    
    
    Private Function MakeTrue(ByRef b As Boolean) As Boolean
        MakeTrue = True: b = True
    End Function
    
    
    Just as a test, I picked on the dwTotalObjects item. I tested both EXE compiled and IDE running, and it correctly reports in both. This is your total BAS and COM (Form, Class, UC, PropPage, DataReport) objects in the project ... basically the count of things you see in your Project window (excluding "Related Documents").

    Test for Form1:
    Code:
    
    Option Explicit
    
    
    Private Sub Form_Load()
    
    
        Dim uObjectTable As ObjectTableType
        uObjectTable = GetObjectTable
    
    
        MsgBox uObjectTable.dwTotalObjects
    
    
        Unload Me
    End Sub
    
    
    
    
    From here, I'll be exploring what I can get of the procedures in these modules.
    Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.

  4. #4
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Digging Through a VB6 Project ... A "Working" Thread

    As before, let me know if you want me to move the thread. Also, I could pluck out certain posts to build a 'cleaner' thread, if you'd like.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width