home *** CD-ROM | disk | FTP | other *** search
- FINDEXEC.EXE (VERSION 1.1) Copyright (c) 1993 Douglas Boling
- -------------------------------------------------------------------------
- First Published in PC Magazine August 1993 (Utilities)
- -------------------------------------------------------------------------
- FINDEXEC BY DOUGLAS BOLING
-
- FINDEX.EXE lets you search all drives/directories on the system
- PATH for a program and reports the location of its executable files.
- Under Windows or OS/2, FINDEXEC also reports the requisite dynamic link
- libraries (DLLs). FINDEXEC is a chararcter-mode application but is
- operating-system neutral. You can run it from a DOS or OS/2 command line
- or from a Windows DOS box.
-
- Version 1.1 fixes a number of small bugs and adds one feature.
- The new feature allows FINDEXEC to perform a Windows type search outside
- of a Windows DOS box by looking in the PATH for the file WIN.COM.
- The directory of WIN.COM is then assumed to be the Windows directory.
- -------------------------------------------------------------------------
-
- Have you ever entered a program name at the command prompt only to
- find yourself running a different application than you expected? The same
- DOS PATH variable that lets you run programs without specifying their
- directories can necessitate a tedious search if you have to track down a
- same-named application located somewhere earlier on the PATH than the
- program you intended to execute.
-
- FINDEXEC, does the searching for you. It prints out the location
- of a program without executing it. The utility is unusual in that it
- is operating-system neutral: You can run it from a DOS or OS/2 command
- line or from a Windows DOS box and it will adjust its search method for
- the operating system in use. (The one restriction is that since FINDEXEC
- is a character-mode application, you must be in character mode rather
- than in graphics mode.) Because Windows and OS/2 programs usually
- require dynamic link libraries (DLLs), FINDEXEC also reports the
- locations of any libraries needed to run those programs.
-
- Compiling the FINDEXEC source is a little more involved than is
- usual for PC Magazine utilities, so I'll discuss this issue toward the
- end of the article.
-
- USING FINDEXEC
-
- Whether you run FINDEXEC under DOS, OS/2 1.x, OS/2 2.x, or from a
- Windows DOS box, its syntax is the same:
-
- FINDEXEC [/W] [/V /Ln] [/?] program_name
-
- For example, when I enter
-
- FINDEXEC COMMAND
-
- at my DOS prompt FINDEXEC returns the line
-
- DOS program: C:\DOS50\COMMAND.COM
-
- FINDEXEC generally defaults to the search method used by the
- operating system in use. I'll discuss these in some detail below.
- In the case of Windows, the FINDEXEC default uses the DOS search
- procedure, since many times you may want a conventional DOS check from
- a Windows DOS box. By using the /W command line switch, however, you can
- tell FINDEXEC to use the specific Windows search method instead. In that
- case, FINDEXEC depends on the windir= environment variable to locate the
- Windows directory. Since this environment variable is present only in a
- Windows DOS box, the /W switch should not be used anywhere else.
- If the /W switch is used when Windows is not running, FINDEXEC displays
- an error message.
-
- A FINDEXEC search under Windows or OS/2 does not end with the finding
- of a designated Windows or OS/2 program. Rather, FINDEXEC goes on to
- examine the .EXE file to determine which DLLs are required to run the
- program properly. FINDEXEC then searches for and reports the locations
- of these additional necessary files.
-
- Again using my machine to illustrate, the command
-
-
- FINDEXEC klondike
-
-
- when executed from an OS/2 window, reports the following:
-
- OS/2 2.x Program: C:\OS2\APPS\KLONDIKE.EXE
- Loads:
- OS/2 DLL: DOSCALLS
- OS/2 2.x DLL: C:\OS2\DLL\PMGPI.DLL
- OS/2 2.x DLL: C:\OS2\DLL\PMWIN.DLL
- OS/2 2.x DLL: C:\OS2\DLL\PMSHAPI.DLL
- OS/2 2.x DLL: C:\OS2\DLL\HELPMGR.DLL
-
- Notice in the above list that KLONDIKE must load a DLL called
- DOSCALLS, but that FINDEXEC did not report its path. The reason is that
- there is actually no such file, so there is no path to it. When OS/2
- starts, it loads its main operating system DLL by reading from one of a
- set of DLLs. Once in memory, the resulting DLL is simply called DOSCALLS,
- and FINDEXEC does all that it can by indicating that the program needs
- this unusual DLL.
-
- A similar situation arises with Windows programs. Once Windows is
- loaded, KERNEL.DLL and DISPLAY.DLL are in memory, but there are no
- actual files named KERNEL or DISPLAY for FINDEXEC to locate. So again,
- the utility simply prints out a line indicating that the program requires
- these DLLs.
-
- Fortunately, it doesn't matter that FINDEXEC can't print a path to
- these particular DLLs. Since Windows can't run without KERNEL and
- DISPLAY, and OS/2 requires DOSCALLS, if Windows or OS/2 can run, the
- requisite DLLs are available. (Windows can't run without other DLLs
- such as USER and GDI. Remember, though, that the problem isn't that
- KERNEL and DISPLAY are required files, the problem is that there is
- no file called KERNEL.DLL or DISPLAY.DLL.)
-
- Dynamic link libraries under Windows or OS/2 may require DLLs of
- their own in order to run. Thus, since there may be a DLL that cannot
- load because one of its necessary DLLs is missing, FINDEXEC can also
- search for every DLL required by every DLL! The /Ln and /V switches
- control how much information FINDEXEC prints for each of the required
- DLLs.
-
- The /Ln switch tells FINDEXEC to descend to level n before ending
- its search. Using the switch /L3 will cause FINDEXEC to display all
- the DLLs required by the executable file, its required DLLs, their
- required DLLs, and their required DLLs!
-
- For example, on my system, entering the following line
-
-
- FINDEXEC /L3 /w notepad
-
- in a Windows DOS box returns the listing shown (below) in Figure 1. In
- this rather extensive list you'll notice that many of the DLLs are
- repeated. This simply means that some of the DLLs NOTEPAD loads depend
- on the same lower-level DLLs.
-
- The /V (verbose) switch goes even further by telling FINDEXEC to
- continue searching until it has listed every file required by every
- DLL. Especially under OS/2, using the /V switch can result in hundreds
- of lines of library listings. In most cases, checking one or two levels
- is enough, but if you want the complete rundown for all libraries,
- the /V switch will provide it .
-
- FINDEXEC's final switch parameter, /?, brings up a help screen that
- explains the program's full syntax.
-
- FINDING A PROGRAM
-
- As indicated earlier, depending on the operating system in use,
- FINDEXEC employs the same search methods used by DOS, Windows, or OS/2
- to find an executable file. Since these search methods differ somewhat,
- however, it may be useful to discuss them in detail.
-
- The search for DOS executable files is actually performed by
- COMMAND.COM. If the user enters a path along with the desired program
- name, COMMAND.COM looks no further than the specified directory for the
- file. If no extension is specified, COMMAND.COM looks first for a .COM
- file, then for an .EXE file, and finally for a .BAT file that matches
- the filename. Under DOS versions earlier than 4.0, even a user-specified
- file extension is ignored and the .COM-.EXE-.BAT search order is imposed.
- When a matching file is found, COMMAND.COM uses DOS's Exec function
- (Int 21 function 4Bh) to execute the file.
-
- If the user does not enter a path along with the program name,
- COMMAND.COM starts by looking for the file in the current directory.
- Here again, if the user does not specify an extension (or even if he
- does, under DOS versions prior to 4.0), DOS follows the .COM-.EXE-.BAT
- order in looking for the file. If no matching file is found, COMMAND.COM
- then searches for it successively in each of the directories listed in
- the PATH environment variable. The .COM-.EXE-.BAT sequence is followed
- within each directory, but a batch file with a .BAT extension will be
- executed instead of a program with a .COM extension if the .BAT file is
- in a directory listed earlier in the PATH.
-
- The DOS APPEND program can modify the program search order.
- If APPEND is loaded with the /X:ON switch specified, COMMAND.COM looks
- in the APPENDed directories before it turns its attention to any path
- directories. Indeed, if both the /PATH:ON and /X:ON switches are set
- on APPEND, COMMAND.COM will load a program from the APPENDed directories
- even if the user specifies a path along with the program name. Thus,
- the effect of APPEND is to make COMMAND.COM (and any other DOS program)
- think that all the files in the APPENDed directories are located in
- the current directory. Since the current directory is checked before
- PATH directories, files in the APPENDed directories are executed before
- programs in the path.
-
- The Windows search method is more complex. It is used by Windows
- when a program is launched from the File|Run menu item in the Program
- Manager or when a path is not included for an icon in the Program
- Manager window. Actually, the Program Manager doesn't perform the
- search for the program; Windows does. Windows uses its search method
- for any program (including the Program Manger) that uses WinExec, the
- Windows API function, to launch a program.
-
- Thus, there is a fundamental difference between DOS and Windows
- file searches. In DOS, it is COMMAND.COM that determines the order of
- the search. In Windows, it is the WinExec API call that determines the
- search order. Any program that uses WinExec, such as my own WinCmd
- interpreter (which appeared in the April 27, 1993, Utilities column),
- automatically ends up using the Windows search method. The equivalent
- DOS API--that is, Exec (Int 21 Function 4Bh)--performs no searches.
- The Exec function works only if the program specified is in the
- current directory or if a path is specified along with the program
- name. As with a DOS search, a Windows search depends on whether a path
- is specified with the filename. If so, then the search for the file
- is restricted to the directory specified. If a filename is entered by
- itself, Windows starts its search with the working directory, just as
- in DOS. DOS users know the working directory as the current directory.
-
- If the program name sent to WinExec includes an extension, Windows
- looks only for a file that matches the name and extension. If an
- extension is not specified, however, Windows does not restrict itself
- to the familiar .COM, .EXE, and .BAT DOS extensions. Instead, Windows
- looks for files with extensions that are listed in the Programs= item
- in the [Windows] section of WIN.INI. By default, these extensions are
- .COM, .EXE, .BAT, and .PIF, but other extensions can be added. For
- example, an .SCR extension is often added to the Programs= list so
- that Windows will look for screen savers. Windows uses the extensions
- in the order they are listed in Programs=. The default order looks
- like the DOS extension order with the .PIF extension added. In
- Windows, PIF (program information file) files are used to customize
- a DOS program's execution.
-
- After looking for the file in the current directory, Windows turns
- to the Windows directory. The Windows directory is where files such
- as WIN.COM, WIN.INI, and SYSTEM.INI are stored. Next, Windows looks
- in its system directory. This is the directory that holds such files
- as GDI.EXE and USER.EXE, along with the driver files that Windows uses.
-
- If the file has still not been found, Windows looks next in
- the directory that holds the program calling WinExec. This directory
- may be different from the current or working directory. For example,
- if the calling program is launched from C:\DATA, but the Windows
- program itself is located in the C:\PROGRAMS directory, the current
- directory is C:\DATA, but the directory containing the executable file
- for the current task is C:\PROGRAMS. After checking the calling
- program's directory, Windows looks successively in each of the
- directories that are listed in the PATH. If the program is not found
- there, Windows examines any network directories that have been mapped.
-
- When a Windows program requires a DLL, Windows checks to see
- whether another program has already loaded the same DLL. If so,
- Windows simply directs any calls to the DLL to the already-loaded copy.
- If the DLL is not in memory, Windows looks for it in the same directories
- that were scanned in the original program search. The only difference
- is that in this search Windows looks only for files with a .DLL
- extension. (Windows driver files with a .DRV extension are also DLLs,
- but they will already have been loaded at the time Windows was
- started.)
-
- OS/2's method for searching for programs is closer to that of DOS
- than to that of Windows. The search is performed by CMD.EXE, which is
- OS/2's version of DOS's COMMAND.COM. If no path is specified with the
- program name, CMD.EXE looks in the current directory, then in each one
- of the directories listed on the PATH. CMD.EXE looks for the files with
- the extensions .COM, .EXE, .CMD, and .BAT, in that order. (CMD files
- are OS/2's equivalent of DOS batch files.)
-
- As with DOS 4.0 and later, and as with Windows, the user can restrict
- the search by specifying the program's extension. Thus, if the user asks
- for PROG.EXE, CMD.EXE will ignore a program called PROG.COM even if the
- latter is in the same directory. OS/2 is intelligent enough to launch
- a Presentation Manager or DOS application from the OS/2 command line if
- the program found is a PM or DOS application. By contrast, attempting
- to execute a Windows program from a Windows DOS box results in the
- silly message, ``This program requires Microsoft Windows.''
-
- Like Windows programs, OS/2 programs frequently require DLLs in order
- to run. When trying to locate a DLL, OS/2 looks first in the directories
- specified in the LIBPATH parameter of CONFIG.SYS. If the DLL is not found
- in one of the LIBPATH directories, the directory containing the program
- is searched. Unlike the program search, the search for DLLs is performed
- by the OS/2 system, not by CMD.EXE. That's because DLLs are used by all
- OS/2 programs, not just by those launched by CMD.EXE.
-
- FINDEXEC SEARCHES
-
- Simply put, FINDEXEC itself uses the same rules to hunt for programs
- as do DOS, Windows, and OS/2. For DOS and OS/2, FINDEXEC looks in the
- current directory, then checks each directory listed in the PATH
- statement. The Windows search is a bit more complex, since the Windows
- and Windows system directories must be checked. FINDEXEC performs all
- these searches by brute force, using the DosFindFirst API function to
- locate the first file with a proper extension.
-
- FINDEXEC's real work comes after an OS/2 or Windows executable file
- is found during a Windows or OS/2 search. In these cases, FINDEXEC must
- determine whether the program requires any DLLs and, if so, it must then
- locate those DLLs. And to know what DLLs a program needs, FINDEXEC must
- know a little about the format of the executable file.
-
- The structure of Windows .EXE and OS/2 1.x .EXE files is quite
- similar; both use the New Executable (NE) .EXE format. NE format
- programs are actually two programs bundled into one. The file begins
- with a standard (old) DOS .EXE header and a small DOS stub program.
- When run under DOS, the DOS Exec function sees the DOS .EXE header
- and loads the small DOS stub. Normally, the stub program simply prints
- out a message, such as ``This program requires OS/2,'' or ``This program
- requires Microsoft Windows.'' However, a pointer in the old .EXE header
- contains the offset in the file of the real .EXE header for the program.
- Both OS/2 and Windows look for this new header, which they use in loading
- the program.
-
- The NE header is much more complex than the old, standard DOS header.
- The NE header begins with a signature word--the ASCII characters NE--that
- serves to identify it. The header itself contains pointers and offsets
- to various tables for resources, entry points into the program, and--what
- FINDEXEC is interested in--the list of the program's required DLLs.
- The NE header is documented both in the Windows Software Development Kit
- and in Appendix D of Ray Duncan's Advanced OS/2 Programming
- (Microsoft Press, 1991).
-
- Enhanced-mode Windows applications, OS/2 2.x applications, and
- Windows/NT applications use different and mutually incompatible .EXE
- file formats. All that these formats have in common are the real-mode
- DOS stub program idea and a format-identifying signature in the first
- 2 or 4 bytes at the start of their new .EXE headers.
-
- The alphabet soup of .EXE formats includes the LX format for
- OS/2 2.x programs, the LE format for Windows VxD drivers, and the PE
- format for Windows/NT programs. A detailed explanation of these formats
- is beyond the scope of this article, but Ray Duncan has discussed each
- of them (in the February 9, March 16, and March 30, 1993, Power
- Programming columns).
-
- For each supported .EXE type, FINDEXEC determines the type of .EXE
- and then reads in the list of required DLLs. The code for determining
- the .EXE type is shown (below) in Figure 2. Briefly summarized, the
- GetEXEType routine opens the file and reads in the DOS .EXE header.
- If the value at offset 18 hex is greater than 40 hex, the file contains
- one of the new header types. A pointer to the new header is located at
- offset 3C hex in the old header. GetEXEType reads in the header and then
- uses the signature bytes at the start of the new header to determine the
- .EXE type.
-
- A FAPI APPLICATION
-
- How can one program be both a DOS application and an OS/2 application
- at the same time? If you browse through the FINDEXEC source code,
- you'll find that there are a number of calls to the OS/2 API but none
- to DOS. In fact, FINDEXEC is an OS/2 1.x program that uses a subset of
- the OS/2 1.x character-mode API. So, how can FINDEXEC run under DOS
- when it is an OS/2 program?
-
- The answer is that FINDEXEC is compiled, linked, and bound into what
- is called a Family Application. A Family Application uses a limited part
- of the OS/2 API that can be translated into DOS calls by means of a
- special binding layer when the program is run under DOS.
-
- With all the conflicts over PC operating systems these days, I find
- it amazing that the character-mode OS/2 1.x API is supported by all the
- new operating systems. You'd expect that IBM's OS/2 2.x would be
- backward-compatible with OS/2 1.x, but even Microsoft's Windows/NT
- supports OS/2 1.x character-mode applications. Add the ability of a
- Family Application to run under DOS, and you end up with an application
- that will execute under every mainstream operating system running on the
- PC today!
-
- The set of Family API (FAPI) functions is listed (below) in Figure 3.
- To an OS/2 programmer the list will look rather sparse, but a DOS
- programmer will find a veritable feast of powerful functions. The
- only glaring omission is a set of mouse functions. To handle a mouse,
- FAPI programs must use MOUSE.COM's Int 33 calls when run under DOS and
- OS/2 MouXXX calls when run under OS/2 or Windows NT.
-
- Family Applications must be written as OS/2 apps, with none of the
- straight-to-the-hardware practices normally found in DOS programs.
- Further, since a FAPI program executes in protected mode under OS/2,
- strict segment discipline must be maintained. That means no accessing
- of unallocated memory locations and no segment arithmetic beyond what
- is allowed when dealing with huge pointers. Unfortunately, when executing
- under DOS, FAPI applications are subject to the DOS real-mode limit of
- 640K of total RAM.
-
- Though FAPI applications are supported by the current operating
- systems, actually creating one is an exercise in technological
- archeology. The problem is that neither OS/2 1.x nor the FAPI concept
- ever really caught on. To compile a FAPI application, you need both
- a compiler that supports OS/2 1.x and the BIND.EXE program that was
- bundled with the OS/2 1.x Software Development Kit. Microsoft's C 5.1
- and 6.0 compilers represent another source for the OS/2 1.x libraries
- and for BIND. Unfortunately, Microsoft removed OS/2 support and
- BIND.EXE from its C 7.0 product, so if you upgraded and deleted all
- the old compiler files, you're out of luck. IBM is not much help
- either; the OS/2 2.0 Software Development Kit can't be used to create
- OS/2 1.x applications. And although IBM has kept the OS/2 1.x SDK in
- its product list, it may be a chore actually getting hold of such an
- old product. My advice is to hunt through your old compiler files or
- give your compiler vendor a call.
-
- FAPI applications are compiled as OS/2 character-mode applications.
- The compiler and linker must support OS/2 1.x. The OS/2 resource compiler
- is also necessary to set the appropriate flags in the EXE header.
- Finally, the BIND program is necessary to turn the OS/2 application into
- a FAPI application.
-
- BIND.EXE is the key to the FAPI concept. When BIND is run against
- an OS/2 1.x character-mode application, it replaces the standard DOS stub
- program with a set of libraries that translate the OS/2 API calls into
- DOS calls. For example, if a FAPI program called the OS/2 function
- DosFindFirst, BIND would hook in a routine that would translate the
- DosFindFirst call into DOS's Find First call (Int 21h Function 4Eh).
- On the other hand, when the FAPI program is executed in protected mode,
- the DOS API translation program that BIND hooked in is skipped in favor
- of the native protected-mode code.
-
- Once the real-mode routines have been hooked into an OS/2
- application, that application will run under DOS and OS/2 without
- requiring any special files. In fact, without looking at the structure
- of the .EXE file itself, you won't be able to tell a FAPI application
- from a DOS or OS/2 character-mode application.
-
- If the FAPI concept is so attractive, why isn't every DOS application
- a FAPI application? The answer lies in the commercial fate of
- OS/2 1.x. Faced with a lack of user enthusiasm for OS/2, the
- software industry saw no need to write applications that were compatible
- with both DOS and with the tiny OS/2 1.x market. When IBM then released
- OS/2 2.0, with its excellent DOS emulation, FAPI was again deemed
- unnecessary, for now OS/2 could run almost every DOS application
- automatically.
-
- Despite industry indifference, however, there is still a place
- for FAPI. It's the perfect format for utility programs such as
- FINDEXEC. Utilities tend to be simple, but they must find a place
- under DOS, OS/2, and, in the future, Windows/NT. One FAPI utility
- can take the place of DOS, OS/2, and Windows utilities and ensure
- that you won't have the wrong utility when you boot up a different
- operating system. FAPI utilities are also needed on OS/2 systems
- whose DOS emulation has been disabled with the PROTECTONLY switch.
-
- FINDEXEC is a handy utility that works in all kinds of environments.
- Its services are useful on the smallest 256K PC as well as on the biggest
- server running OS/2. So stop guessing exactly what program actually ran
- and where it is; let FINDEXEC tell you.
- ----------------------------------------------------------------------------
- DOUGLAS BOLING IS A CONTRIBUTING EDITOR TO PC MAGAZINE.
- ===========================================================================
-
- Release History:
-
- Version 1.0 Initial Release PC Mag Vol 12, No 14.
-
- Version 1.1 Increased read buff to 16384 for big reference
- tables.
-
- Save/Restored Program directory in recursive
- calls to GetxxRefs.
-
- If WinDir not found, check for WIN.COM in PATH
- ---------------------------------------------------------------------------
-
- Sample FINDEXEC Output
-
-
- Windows Program: C:\WINDOWS\NOTEPAD.EXE
- Loads:
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\GDI.EXE
- Windows DLL KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\USER.EXE
- Windows DLL: KERNEL
- Windows DLL: CT:\WINDOWS\SYSTEM\GDI.EXE
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\SYSTEM.DRV
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\KEYBOARD.DRV
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\MOUSE.DRV
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\SYSTEM.DRV
- Windows DLL: DISPLAY
- Windows DLL: C:\WINDOWS\SYSTEM\SOUND.DRV
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\COMM.DRV
- Windows DLL: C:\WINDOWS\SYSTEM\SYSTEM.DRV
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\KEYBOARD.DRV
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\COMMDLG.DLL
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\GDI.EXE
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\USER.EXE
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\GDI.EXE
- Windows DLL: C:\WINDOWS\SYSTEM\SYSTEM.DRV
- Windows DLL: C:\WINDOWS\SYSTEM\KEYBOARD.DRV
- Windows DLL: C:\WINDOWS\SYSTEM\MOUSE.DRV
- Windows DLL: DISPLAY
- Windows DLL: C:\WINDOWS\SYSTEM\SOUND.DRV
- Windows DLL: C:\WINDOWS\SYSTEM\COMM.DRV
- Windows DLL: C:\WINDOWS\SYSTEM\KEYBOARD.DRV
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\SHELL.DLL
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\GDI.EXE
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\USER.EXE
- Windows DLL: KERNEL
- Windows DLL: C:\WINDOWS\SYSTEM\GDI.EXE
- Windows DLL: C:\WINDOWS\SYSTEM\SYSTEM.DRV
- Windows DLL: C:\WINDOWS\SYSTEM\KEYBOARD.DRV
- Windows DLL: C:\WINDOWS\SYSTEM\MOUSE.DRV
- Windows DLL: DISPLAY
- Windows DLL: C:\WINDOWS\SYSTEM\SOUND.DRV
- Windows DLL: C:\WINDOWS\SYSTEM\COMM
-
- Figure 1: The FINDEXEC /Ln switch sets the number of levels of DLL
- information that are reported. To get this output, the
- switch was set to /L3 on the author's machine.
- ===========================================================================
- FINDEXEC.C
-
- Partial Listing
-
-
- // GetEXEType - Loads a file and returns its operating system.
- //-------------------------------------------------------------------
- INT GetEXEType (char *szFName, INT *psNumRefEnt, LONG *plFPtr) {
-
- PBYTE lpbData;
- USHORT usSel, usBytesRead;
- INT sTargOS;
- HFILE hFile;
-
- if (DosAllocSeg (BUFFSIZE, &usSel, 0))
- return ERR_OUTOFMEM;
- lpbData = MAKEP (usSel, 0);
-
- hFile = FileOpen (szFName);
- if (hFile == -1) {
- DosFreeSeg (usSel);
- return (ERR_NOOPENEXE);
- }
- DosRead (hFile, lpbData, BUFFSIZE, &usBytesRead);
- if (usBytesRead < 0x40) {
- FileClose (hFile);
- DosFreeSeg (usSel);
- return 0;
- }
- //Check for "MZ"
- if (*(PUSHORT)lpbData != 0x5a4d) {
- FileClose (hFile);
- sTargOS = 0; //DOS
- if (*(PLONG)(lpbData+0x171) == 0x5243494d)
- sTargOS = 7; //Window PIF
- DosFreeSeg (usSel);
- return sTargOS;
- }
- //Check for New EXE header
- if (*((PSHORT)(lpbData+0x18)) < 0x40) {
- FileClose (hFile);
- DosFreeSeg (usSel);
- return 0;
- }
- //Read New EXE header
- *plFPtr = (LONG) *((PLONG)(lpbData+0x3C));
- DosChgFilePtr (hFile, (LONG) *plFPtr, 0, plFPtr);
-
- DosRead (hFile, lpbData, BUFFSIZE, &usBytesRead);
- FileClose (hFile);
-
- switch (*(PUSHORT)lpbData) {
-
- //Check for NewEXE (NE)
- case 0x454E:
- if (*(lpbData+0x36) & 2)
- sTargOS = 1; //Windows
- else if (*(lpbData+0x36) & 1)
- sTargOS = 2; //OS/2 1.x
-
- if (*(PUSHORT)(lpbData+0x0C) & 0x8000)
- sTargOS += 0x100; //Library
-
- if (psNumRefEnt != 0)
- *psNumRefEnt = *((PSHORT)(lpbData+0x1E));
- if (plFPtr != 0)
- *plFPtr += (LONG) *((PUINT)(lpbData+0x28));
-
- break;
-
- //Check for LinearEXE (LE)
- case 0x454C:
- sTargOS = 3; //Win 3.x Enh mode
- if (*(PULONG)(lpbData+0x10) & 0x8000)
- sTargOS += 0x100; //Library
-
- if (psNumRefEnt != 0)
- *psNumRefEnt = (INT) *((PULONG)(lpbData+0x74));
- if (plFPtr != 0)
- *plFPtr += (LONG) *((PULONG)(lpbData+0x70));
- break;
-
- //Check for LinearEXE (LX)
- case 0x584C:
- sTargOS = 4; //OS/2 2.x
- if (*(PULONG)(lpbData+0x10) & 0x8000)
- sTargOS += 0x100; //Library
-
- if (psNumRefEnt != 0)
- *psNumRefEnt = (INT) *((PULONG)(lpbData+0x74));
- if (plFPtr != 0)
- *plFPtr += (LONG) *((PULONG)(lpbData+0x70));
- break;
-
- //Check for LinearEXE (PE)
- case 0x4550:
- sTargOS = 5; //Win/NT
- if (psNumRefEnt != 0)
- *psNumRefEnt = 0;
- break;
-
- }
- DosFreeSeg (usSel);
- return sTargOS;
- }
-
-
- Figure 2: The GetEXEType routine in FINDEXEC is used to determine the
- target operating system of an executable.
- ===========================================================================
- File, Memory, and Operating System Functions
-
- Function Description
-
- DosAllocHuge Allocates huge memory block greater than 64KB
- DosAllocSeg Allocates memory block
- DosBeep Generates tone
- DosBufReset Flushes file buffers, updates directory
- DosCaseMap Translates ASCII string in place
- DosChDir Selects current directory
- DosChgFilePtr Sets file pointer position
- DosCLIAccess Notifies intent to use CLI and STI
- DosClose Closes file, pipe, or device
- DosCreateCSAlias Obtains executable alias for data segment
- DosDelete Deletes file
- DosDevConfig Returns system hardware configuration
- DosDevIOCtl Device-specific commands and information
- DosDupHandle Duplicates or redirects handle
- DosErrClass Returns information about error code
- DosError Disables or enables system critical error handler
- DosExecPgm Creates child process
- DosExit Terminates thread or process
- DosFileLocks Locks or unlocks file region
- DosFindClose Releases directory search handle
- DosFindFirst Searches for first matching file
- DosFindNext Searches for additional matching files
- DosFreeSeg Releases selector
- DosGetCollate Returns collating sequence table
- DosGetCp Returns current code page identifier
- DosGetCtryInfo Returns internationalization information
- DosGetDateTime Returns current time, date, and day of week
- DosGetDBCSEv Returns table of double-byte character-set codes
- DosGetEnv Returns selector for process's environment
- DosGetHugeShift Returns increment value for huge memory block
- selectors
- DosGetMachineMode Returns flag indicating real or protected mode
- DosGetMessage Retrieves message from disk file
- DosGetVersion Returns DOS or OS/2 version number
- DosHoldSignal Suspends signal processing for current process
- DosInsMessage Inserts variable text into body of message
- DosMkDir Creates directory
- DosMove Renames and/or moves file
- DosNewSize Changes size of file
- DosOpen Opens, replaces, or creates file, or opens device
- DosPortAccess Notifies intent to use range of I/O ports
- DosPutMessage Sends message to file, pipe, or device
- DosQCurDir Returns current directory
- DosQCurDir Returns current directory
- DosQCurDisk Returns current disk drive
- DosQFHState Returns file handle sharing and access
- characteristics
- DosQFileInfo Returns file size, attributes, and date and time
- stamps
- DosQFileMode Returns file attributes
- DosQFSInfo Returns file system information or volume label
- DosQVerify Returns state of read-after-write flag
- DosRead Reads data from file, pipe, or device
- DosReallocHuge Resizes huge memory block
- DosReallocSeg Resizes normal memory block
- DosRmDir Deletes directory
- DosOpen Opens, replaces, or creates file, or opens device
- DosPortAccess Notifies intent to use range of I/O ports
- DosPutMessage Sends message to file, pipe, or device
- DosQCurDir Returns current directory
- DosQCurDisk Returns current disk drive
- DosQFHState Returns file handle sharing and access
- characteristics
- DosQFileInfo Returns file size, attributes, and date and time
- stamps
- DosQFileMode Returns file attributes
- DosQFSInfo Returns file system information or volume label
- DosQVerify Returns state of read-after-write flag
- DosRead Reads data from file, pipe, or device
- DosReallocHuge Resizes huge memory block
- DosReallocSeg Resizes normal memory block
- DosRmDir Deletes directory
- DosSelectDisk Selects current disk drive
- DosSetDateTime Sets current date and time
- DosSetFHState Sets file handle characteristics
- DosSetFileInfo Sets file time and date stamps
- DosSetFileMode Sets file attributes
- DosSetFSInfo Adds or changes volume label
- DosSetSigHandler Registers signal handler
- DosSetVec Registers handler for hardware exception
- DosSetVerify Sets system read-after-write flag
- DosSleep Suspends requesting thread for specified interval
- DosSubAlloc Allocates memory from local heap
- DosSubFree Releases memory in local heap
- DosSubSet Initializes local heap
- DosWrite Writes to file, pipe, or device
-
- Keyboard functions
-
-
- KbdCharIn Returns keyboard character and scan code
- KbdFlushBuffer Discards waiting keyboard characters
- KbdGetStatus Returns logical keyboard status
- KbdPeek Returns character-waiting status
- KbdSetStatus Sets logical keyboard characteristics
- KbdStringIn Reads buffered line from keyboard
-
-
- Video functions|
-
-
- VioGetBuf Returns address of logical video buffer
- VioGetConfig Returns hardware characteristics of video adapter
- VioGetCurPos Returns cursor position
- VioGetCurType Returns cursor shape, size, and attribute
- VioGetMode Returns characteristics of current display mode
- VioGetPhysBuf Returns selector for physical video display buffer
- VioReadCellStr Reads string of character-attribute pairs
- VioReadCharStr Retrieves character string from display buffer
- VioScrLock Locks physical display for I/O
- VioScrollDn Scrolls display down
- VioScrollLf Scrolls display left
- VioScrollRt Scrolls display right
- VioScrollUp Scrolls display up
- VioScrUnLock Releases lock on physical display
- VioSetCurPos Sets cursor position
- VioSetCurType Sets cursor shape, size, and attribute
- VioSetMode Selects display mode
- VioShowBuf Updates physical display from logical display
- buffer
- VioWrtCellStr Writes character-attribute pairs to display
- VioWrtCharStr Writes character string to display
- VioWrtCharStrAtt Writes character string with specified attribute
- to display
- VioWrtNAttr Changes attributes of one or more characters on
- display
- VioWrtNCell Writes one or more character-attribute pairs
- VioWrtNChar Writes one or more characters
- VioWrtTTY Writes character string to display in teletype mode
-
- Figure 3: Here is a list of the OS/2 Family Application functions.
- =============================================================================