[Compuware Corporation] [Compuware NuMega home page] [NuMega Lab] [teal] [DriverStudio] [Image][Image] · Home [Driver Products] Driver Technical Tips · DriverStudio Using File Objects in NT Drivers · DriverBundle · Previews Device driver writers know that applications access devices using · Compatibility Win32 file I/O calls: CreateFile, ReadFile, WriteFile, [Downloads] · DeviceIoControl, and CloseHandle. What is sometimes overlooked is that device drivers have access to the data structure that the Wizards system uses to manage the file handle of an open device. This · Utilities data structure, called a File Object, plays a central role in · NT source File System Drivers, but can very useful in ordinary device examples drivers as well. This week's tip looks at a couple of ways device · VxD source drivers can take advantage of File Objects. examples · WDM source The system creates the File Object when an application calls examples CreateFile on a device object. Duping an existing handle does not [Resources] · create a new File Object. The definition of the File Object Technical papers structure is found in ntddk.h: · Useful links · Technical tips typedef struct _FILE_OBJECT { [Support] · CSHORT Type; CSHORT Size; Support PDEVICE_OBJECT DeviceObject; · Knowledge base PVPB Vpb; · Problem PVOID FsContext; submission PVOID FsContext2; · Product PSECTION_OBJECT_POINTERS SectionObjectPointer; registration PVOID PrivateCacheMap; · Release notes NTSTATUS FinalStatus; [Shop NuMega] · struct _FILE_OBJECT *RelatedFileObject; Buy it! BOOLEAN LockOperation; · Price list BOOLEAN DeletePending; · How to buy BOOLEAN ReadAccess; · Sales offices BOOLEAN WriteAccess; BOOLEAN DeleteAccess; BOOLEAN SharedRead; [Y2K Compliance] BOOLEAN SharedWrite; BOOLEAN SharedDelete; ULONG Flags; [More information] UNICODE_STRING FileName; LARGE_INTEGER CurrentByteOffset; ULONG Waiters; ULONG Busy; PVOID LastLock; KEVENT Lock; KEVENT Event; PIO_COMPLETION_CONTEXT CompletionContext; } FILE_OBJECT; When an application opens or calls a device driver, the system stores a pointer to the File Object corresponding to the caller's file handle in the IRP that is passed to the driver. More precisely, the pointer appears in the IO_STACK_LOCATION. Here is the code you would use to obtain the File Object pointer, given an IRP pointed to by variable pIrp. PIRP pIrp; PIO_STACK_LOCATION pIoStack; PFILE_OBJECT pFile; pIoStack = IoGetCurrentStackLocation(pIrp); pFile= pIoStack->FileObject; Using DriverWorks, it looks like this: KIrp I; PFILE_OBJECT pFile = I.FileObject(CURRENT); So why would you want to get the File Object pointer? Suppose you had a device with multiple "subdevices". An example would be a USB device with several pipes, or certain kinds of streaming devices that maintain several channels of data. Instead of creating separate device objects or symbolic links for each of the device components, the application can distinguish the components by supplying a file name. For example, an application typically opens a device with no file name: hDevice = CreateFile(L"\\\\.\\MyDevice", . . . But it can specify a particular component of the device by supplying a file name: hDevice = CreateFile(L"\\\\.\\MyDevice\\Stream1", . . . The driver then receives IRP_MJ_CREATE, and can examine the path name that the application supplied in field FileName of the File Object. What the name actually means is entirely up to the driver. Once the driver has determined the supplied file name, it needs a way to remember how the application opened the device, in order to respond correctly to future calls on the same handle. To solve this problem, the File Object structure provides two 32-bit fields for use by the driver: FsContext and FsContext2. The driver can store values or pointers in these locations, and can recall them in later calls (e.g. IRP_MJ_READ or IRP_MJ_DEVICE_CONTROL), by accessing the File Object in an identical manner. In fact, the context fields are extremely useful in other situations, regardless of if a file name was used to open the driver. These fields enable the driver to store information specific to a particular file handle. Since the system always closes open handles when a process terminates, the context fields give the driver a means to correctly manage the resources that allocated for a particular process. For example, if a driver maps physical memory into a process's address space, it can use the context field to connect the mapping to the file handle. When the process terminates, the driver receives IRP_MJ_CLOSE, retrieves the File Object, locates the mapping information, and destroys the mapping. Note that drivers in a layered stack of drivers cannot safely use the context fields of the File Object, unless it is absolutely certain that only a single driver is using each of the two context fields. Back to technical tip start page. DriverCentral · DriverStudio · Free downloads · Resources · Support and Services · Shop NuMega Compuware NuMega · Tel: +1 603 578-8400 · Updated: 9 August 1999 · Problems? Contact our webmaster.