Environment: Windows NT 4.0/2000 only, VC6 SP3, NT4 DDK
Overview and usage
FileObjectInfo is a tool which lets you take a look at Windows NT's
file objects. In contrast to NTHandleEx from
www.sysinternals.com
and EnTeHandle article from Fred Forester
(contributed here at CodeGuru)
it also shows some of the corresponding device object properties,
like the actual device name.
FileObjectInfo walks the systems handle table and looks for all handles
which refer to file objects. In Windows NT not only files which reside on
disk are represented by a file object. File objects are also used to access
communication devices, input/output devices and so on. FileObjectInfo
shows information about the file objects and the device they belong to.
This is especially useful, if the file object is unnamed, e.g. in case
of the serial communication ports (see screenshot below).
(continued)
Each file object is shown in one line, listing its owners process id
and name, the device type/name of the device which it refers to and
the actual file name (or "no name" if it is unnamed). To allow easy
viewing and browsing of all file objects, you can group and sort the
display columns. To group by a column use the main menus
view --> group by... items. This will group all file objects
with the same group name into a node of a tree view (see [6]
for more information on the treeview list control used). To sort just click
one of the column headings. In case you want to refresh the display, i.e.
reread the systems handle table, you can use view --> refresh.
Personally i am using FileObjectInfo to find answers to questions like:
"What process has opened COM1?" (Try it yourself: group by "device type"
and expand the tree node FILE_DEVICE_SERIAL_PORT!).
For some notes on installing and running FileObjectInfo, see the end of
this article.
Inner Workings
FileObjectInfo actually consists of two components: an application which
uses some undocumented functions to get information about the systems handles
and a kernel mode driver, which is responsible for peeking around in NT's
internals.
The following picture shows what happens inside the application/driver combo.
The user mode application uses a few undocumented calls into NTDLL.DLL
(NtQuerySystemInformation, see [2]) to get information about
all open handles and all running processes. Each entry (SYSTEM_HANDLE) of the
handle list (shown as SystemHandleList in the picture above) contains some
information about the handle. Of particular interest are:
ProcessID: Used to display the owners process name
ObjectType: Type of Object (e.g. OB_TYPE_FILE == File-Object)
*pObject: Address of the kernel mode data structure for this object
To get further information about the object which the handle refers to, i
looked for a way to peek at the address provided by *pObject. However,
this address is in the kermel mode address space, which cannot be accessed
by user mode applications. Therfore i wrote a kernel mode device driver.
The application just passes the kernel mode address to the driver and
the driver peeks at the object referenced by this address.
In case of a file object (FILE_OBJECT, which is fortunately documented (!)
in the DDK, see [3]) the driver uses the embedded pointer
*pDeviceObject to get the refering DEVICE_OBJECT. Using this pointer it builds
a structure containing the device objects name (using the officially undocumented
ObQueryNameString, but see [5]) and the type of the device
object. This structure is then returned to the user mode application and
gets displayed in the GUI.
Some special stuff
Undocumented information classes
I mixed the information and source codes from [2] and
[4] and build some new classes to easily use the undocumented
NtQuerySystemInformation function. There is a common base class NtSystemInformation
from which the following two classes are derived:
NtSystemHandleInformation: read the systems handle table
NtSystemProcessInformation: read the systems process table
Of generic interest might be the NtSystemProcessInformation class. It provides
a fast and easy to use method to get a list of all processes (PID and name)
running on the machine without using the (slow) performance counter approach
or using the psapi-dll.
Embedded dynamic loaded driver
I do not like the idea of having multiple files for a small application.
However, FileObjectInfo actually consists of two components: the application
executable and the kernel mode device driver. Help came from an article in the
Microsoft System Journal (see [1]), which described a method
to embed a device driver image into the resource section of an application.
On startup FileObjectInfo extracts the driver image from its ressources and
writes it to a temporary file on the hard disk. It then registers and starts
the driver and removes the temporary file. From now on the driver can be used
normally. When FileObjectInfo is closed (an thus the driver is no longer used)
it stops and unregisters the driver.
All functions for dynamically loading and unloading a driver are contained
in the file "dynamic.cpp".
Addtional ideas
At the moment, FileObjectInfo (as its name implies) is restricted to show
additional information for file objects only. However, the application as well
as the driver can easily be expanded to support other object types. Maybe it
could be expanded to show system data structures like WinDBG or SoftIce
without having to actually use a debugger.
Resources
[1] James Finnegan, Pop Open a Privileged Set of APIs with Windows NT Kernel Mode Drivers, Microsoft System Journal, March 1998
In order to make FileObjectInfo work on Windows 2000 and Windows NT, the device
driver has to be built using the NT4 DDK. The supplied Visual C++ 6 workspace
will work correctly, if you set the environment variable BASEDIR to the
root directory of your NT4 DDK installation.
Note: As i did not get Visual C++ to recognize the dependencies between
the two projects (driver and gui) right, you should build the driver first, then
build the gui.
Installing and running FileObjectInfo
To install FileObjectInfo, just copy its executable "FileObjectInfo.exe"
to a directory on your local hard disk. It will not run from a network locatiton
nor will it run from a location where you don't have write access (it will
create a temporary file in the same directory where it is installed).
As it has to register and start a kernel mode driver, you need administrative
privileges to run FileObjectInfo.
WARNING: This is experimental software which uses undocumented functions,
installs a kernel mode driver and peeks around in your systems internals.
Although this software works very well for me, i can't guarantee it will work
this way for every possible hardware/software kombination out there.
Be warned and don't blame me, if it bluescreens...
Version History
August 7, 2000
Initial posting
February 9, 2001
Enhanced GUI
Some minor bug fixes
Created a single source and executable for both NT 4 and NT 2000
Add www.codeguru.com to your favorites Add www.codeguru.com to your browser search box IE 7 | Firefox 2.0 | Firefox 1.5.xReceive news via our XML/RSS feed
RATE THIS ARTICLE:
Excellent Very Good Average Below Average Poor
(You must be signed in to rank an article. Not a member? Click here to register)