Find all statically linked libraries required before your process can start

There’s some code in this post What external code does your EXE depend on? that determines all the statically linked libraries and function calls of a particular EXE. VFP9.EXE links to about 18 modules. However, there are about 83 modules loaded when VFP is up and running. Much of this is due to these 18 modules depending on other modules.

To get all statically linked libraries from all modules, the code needs to recur: for each module, find its dependent modules.

Below is code that finds a tree of 78 statically linked modules and the almost 10,000 functions that need to be loaded for the first line of VFP9.exe code to execute.

The code uses LoadLibrary and GetModuleFileName to get the module full path name because the module may not be on the path.

DECLARE integer GetModuleFileName IN WIN32API integer hModule, string @ lpfilename, integer nSize

DECLARE integer LoadLibrary IN WIN32API string FileName

DECLARE integer FreeLibrary IN WIN32API integer hModule

CREATE CURSOR imports (Parent c(40), Module c(40),address c(10),FuncName c(40))

CREATE CURSOR modules (module c(40),Level i)

INDEX on UPPER(module) TAG module

GetImports(_vfp.FullName, 1)

*GetImports("kernel32.dll",1)

PROCEDURE GetImports(Parent as String,nLevel as Integer)

          LOCAL i,mybat,nLines,aa[1],Module,cLine,Address,FuncName

          hm = LoadLibrary(parent)

          IF hm=0

                   ?"Can't load "+parent

          ELSE

                   cStr=SPACE(260)

                   nLen=GetModuleFileName(hm,@cStr,LEN(cStr))

                   Parent=LEFT(cStr,nLen)

                   FreeLibrary(hm)

                   INSERT INTO modules VALUES (UPPER(JUSTFNAME(Parent)), nLevel)

                   cVars=LOCFILE("c:\Program Files\Microsoft Visual Studio 8\Vc\bin\vcvars32.bat") && VS2005

* cVars=LOCFILE("c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\bin\vcvars32.bat") && VS2003

                   TEXT TO mybat TEXTMERGE NOSHOW

                             call "<<cVars>>"

                             dumpbin /imports "<<Parent>>" > c:\t.txt

                   ENDTEXT

                   STRTOFILE(mybat,"t.bat")

                   !cmd /c t.bat

                   nLines=ALINES(aa,FILETOSTR("c:\t.txt"))

                   FOR i = 1 TO nLines

                             cLine=aaIdea [I]

                             IF cLine=" Summary"

                                      EXIT

                             ENDIF

                             IF cLine = "DUMPBIN : fatal error " OR cLine=" Bound to"

                                      ?cLine

                                      EXIT

                             ENDIF

                             IF !EMPTY(cLine) AND LEFT(cLine,4)=" "

* ?cLine

                                      IF SUBSTR(cLine,5)!=' '

                                                m.Module=ALLTRIM(cline)

                                                ?m.Module

                                                IF !SEEK(UPPER(m.Module),"modules")

                                                          GetImports(m.Module,nLevel+1) &&Recur!

                                                ENDIF

                                      ELSE

                                                IF LEFT(cline,8) = SPACE(8)

                                                          m.Address = GETWORDNUM(cline,1)

                                                          m.FuncName = GETWORDNUM(cline,2)

                                                          IF m.FuncName != "Import" AND "0" != m.address

                                                                   INSERT INTO imports FROM MEMVAR

                                                          ENDIF

                                                ENDIF

                                      ENDIF

                             ENDIF

                   ENDFOR

          ENDIF

          RETURN