summaryrefslogtreecommitdiffstats
path: root/sys/compat/ndis/ntoskrnl_var.h
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2005-02-08 17:23:25 +0000
committerwpaul <wpaul@FreeBSD.org>2005-02-08 17:23:25 +0000
commitdf89b626983fe6b8b3366ad0147e35b1a6a8fd37 (patch)
tree508b01687ab62847ee4114b92f273c0cdbd4da49 /sys/compat/ndis/ntoskrnl_var.h
parent81617011cd4fc0a322fee7174006255fc9f5e82c (diff)
downloadFreeBSD-src-df89b626983fe6b8b3366ad0147e35b1a6a8fd37.zip
FreeBSD-src-df89b626983fe6b8b3366ad0147e35b1a6a8fd37.tar.gz
Next step on the road to IRPs: create and use an imitation of the
Windows DRIVER_OBJECT and DEVICE_OBJECT mechanism so that we can simulate driver stacking. In Windows, each loaded driver image is attached to a DRIVER_OBJECT structure. Windows uses the registry to match up a given vendor/device ID combination with a corresponding DRIVER_OBJECT. When a driver image is first loaded, its DriverEntry() routine is invoked, which sets up the AddDevice() function pointer in the DRIVER_OBJECT and creates a dispatch table (based on IRP major codes). When a Windows bus driver detects a new device, it creates a Physical Device Object (PDO) for it. This is a DEVICE_OBJECT structure, with semantics analagous to that of a device_t in FreeBSD. The Windows PNP manager will invoke the driver's AddDevice() function and pass it pointers to the DRIVER_OBJECT and the PDO. The AddDevice() function then creates a new DRIVER_OBJECT structure of its own. This is known as the Functional Device Object (FDO) and corresponds roughly to a private softc instance. The driver uses IoAttachDeviceToDeviceStack() to add this device object to the driver stack for this PDO. Subsequent drivers (called filter drivers in Windows-speak) can be loaded which add themselves to the stack. When someone issues an IRP to a device, it travel along the stack passing through several possible filter drivers until it reaches the functional driver (which actually knows how to talk to the hardware) at which point it will be completed. This is how Windows achieves driver layering. Project Evil now simulates most of this. if_ndis now has a modevent handler which will use MOD_LOAD and MOD_UNLOAD events to drive the creation and destruction of DRIVER_OBJECTs. (The load event also does the relocation/dynalinking of the image.) We don't have a registry, so the DRIVER_OBJECTS are stored in a linked list for now. Eventually, the list entry will contain the vendor/device ID list extracted from the .INF file. When ndis_probe() is called and detectes a supported device, it will create a PDO for the device instance and attach it to the DRIVER_OBJECT just as in Windows. ndis_attach() will then call our NdisAddDevice() handler to create the FDO. The NDIS miniport block is now a device extension hung off the FDO, just as it is in Windows. The miniport characteristics table is now an extension hung off the DRIVER_OBJECT as well (the characteristics are the same for all devices handled by a given driver, so they don't need to be per-instance.) We also do an IoAttachDeviceToDeviceStack() to put the FDO on the stack for the PDO. There are a couple of fake bus drivers created for the PCI and pccard buses. Eventually, there will be one for USB, which will actually accept USB IRP.s Things should still work just as before, only now we do things in the proper order and maintain the correct framework to support passing IRPs between drivers. Various changes: - corrected the comments about IRQL handling in subr_hal.c to more accurately reflect reality - update ndiscvt to make the drv_data symbol in ndis_driver_data.h a global so that if_ndis_pci.o and/or if_ndis_pccard.o can see it. - Obtain the softc pointer from the miniport block by referencing the PDO rather than a private pointer of our own (nmb_ifp is no longer used) - implement IoAttachDeviceToDeviceStack(), IoDetachDevice(), IoGetAttachedDevice(), IoAllocateDriverObjectExtension(), IoGetDriverObjectExtension(), IoCreateDevice(), IoDeleteDevice(), IoAllocateIrp(), IoReuseIrp(), IoMakeAssociatedIrp(), IoFreeIrp(), IoInitializeIrp() - fix a few mistakes in the driver_object and device_object definitions - add a new module, kern_windrv.c, to handle the driver registration and relocation/dynalinkign duties (which don't really belong in kern_ndis.c). - made ndis_block and ndis_chars in the ndis_softc stucture pointers and modified all references to it - fixed NdisMRegisterMiniport() and NdisInitializeWrapper() so they work correctly with the new driver_object mechanism - changed ndis_attach() to call NdisAddDevice() instead of ndis_load_driver() (which is now deprecated) - used ExAllocatePoolWithTag()/ExFreePool() in lookaside list routines instead of kludged up alloc/free routines - added kern_windrv.c to sys/modules/ndis/Makefile and files.i386.
Diffstat (limited to 'sys/compat/ndis/ntoskrnl_var.h')
-rw-r--r--sys/compat/ndis/ntoskrnl_var.h171
1 files changed, 154 insertions, 17 deletions
diff --git a/sys/compat/ndis/ntoskrnl_var.h b/sys/compat/ndis/ntoskrnl_var.h
index bc1f5f3..f1c0766 100644
--- a/sys/compat/ndis/ntoskrnl_var.h
+++ b/sys/compat/ndis/ntoskrnl_var.h
@@ -194,7 +194,7 @@ struct list_entry {
typedef struct list_entry list_entry;
#define INIT_LIST_HEAD(l) \
- l->nle_flink = l->nle_blink = l
+ (l)->nle_flink = (l)->nle_blink = (l)
#define REMOVE_LIST_ENTRY(e) \
do { \
@@ -236,8 +236,8 @@ typedef struct list_entry list_entry;
b = l->nle_blink; \
e->nle_flink = l; \
e->nle_blink = b; \
- b->nle_flink = e; \
- l->nle_blink = e; \
+ b->nle_flink = (e); \
+ l->nle_blink = (e); \
} while (0)
#define INSERT_LIST_HEAD(l, e) \
@@ -498,10 +498,25 @@ struct driver_extension {
void *dre_adddevicefunc;
uint32_t dre_reinitcnt;
unicode_string dre_srvname;
+
+ /*
+ * Drivers are allowed to add one or more custom extensions
+ * to the driver object, but there's no special pointer
+ * for them. Hang them off here for now.
+ */
+
+ list_entry dre_usrext;
};
typedef struct driver_extension driver_extension;
+struct custom_extension {
+ list_entry ce_list;
+ void *ce_clid;
+};
+
+typedef struct custom_extension custom_extension;
+
/*
* In Windows, there are Physical Device Objects (PDOs) and
* Functional Device Objects (FDOs). Physical Device Objects are
@@ -522,7 +537,7 @@ struct device_object {
uint16_t do_type;
uint16_t do_size;
uint32_t do_refcnt;
- struct device_object *do_drvobj;
+ struct driver_object *do_drvobj;
struct device_object *do_nextdev;
struct device_object *do_attacheddev;
struct irp *do_currirp;
@@ -531,6 +546,7 @@ struct device_object {
uint32_t do_characteristics;
void *do_vpb;
void *do_devext;
+ uint32_t do_devtype;
uint8_t do_stacksize;
union {
list_entry do_listent;
@@ -714,6 +730,8 @@ struct io_status_block {
} u;
register_t isb_info;
};
+#define isb_status u.isb_status
+#define isb_ptr u.isb_ptr
typedef struct io_status_block io_status_block;
@@ -736,6 +754,9 @@ struct kapc {
typedef struct kapc kapc;
+typedef __stdcall uint32_t (*completion_func)(device_object *,
+ struct irp *, void *);
+
struct io_stack_location {
uint8_t isl_major;
uint8_t isl_minor;
@@ -763,7 +784,7 @@ struct io_stack_location {
void *isl_devobj;
void *isl_fileobj;
- void *isl_completionfunc;
+ completion_func isl_completionfunc;
void *isl_completionctx;
};
@@ -797,7 +818,7 @@ struct irp {
uint8_t irp_apcenv;
uint8_t irp_allocflags;
io_status_block *irp_usriostat;
- nt_kevent irp_userevent;
+ nt_kevent *irp_usrevent;
union {
struct {
void *irp_apcfunc;
@@ -839,12 +860,22 @@ struct irp {
typedef struct irp irp;
+#define IoSizeOfIrp(ssize) \
+ ((uint16_t) (sizeof(irp) + ((ssize) * (sizeof(io_stack_location)))))
+
+
#define IoGetCurrentIrpStackLocation(irp) \
(irp)->irp_tail.irp_overlay.irp_csl
#define IoGetNextIrpStackLocation(irp) \
((irp)->irp_tail.irp_overlay.irp_csl - 1)
+#define IoSetNextIrpStackLocation(irp) \
+ do { \
+ irp->irp_currentstackloc--; \
+ irp->irp_tail.irp_overlay.irp_csl--; \
+ } while(0)
+
#define IoSetCompletionRoutine(irp, func, ctx, ok, err, cancel) \
do { \
io_stack_location *s; \
@@ -852,17 +883,14 @@ typedef struct irp irp;
s->isl_completionfunc = (func); \
s->isl_completionctx = (ctx); \
s->isl_ctl = 0; \
- if (ok) irp->ctl = SL_INVOKE_ON_SUCCESS; \
- if (err) irp->ctl |= SL_INVOKE_ON_ERROR; \
- if (cancel) irp->ctl |= SL_INVOKE_ON_CANCEL; \
+ if (ok) s->isl_ctl = SL_INVOKE_ON_SUCCESS; \
+ if (err) s->isl_ctl |= SL_INVOKE_ON_ERROR; \
+ if (cancel) s->isl_ctl |= SL_INVOKE_ON_CANCEL; \
} while(0)
#define IoMarkIrpPending(irp) \
IoGetCurrentIrpStackLocation(irp)->isl_ctl |= SL_PENDING_RETURNED
-#define IoSizeOfIrp(s) \
- ((uint16_t) (sizeof(itp) + ((s) * (sizeof(io_stack_location)))))
-
#define IoCopyCurrentIrpStackLocationToNext(irp) \
do { \
io_stack_location *src, *dst; \
@@ -878,7 +906,7 @@ typedef struct irp irp;
(irp)->irp_tail.irp_overlay.irp_csl++; \
} while(0)
-typedef uint32_t (*driver_dispatch)(device_object *, irp *);
+typedef __stdcall uint32_t (*driver_dispatch)(device_object *, irp *);
/*
* The driver_object is allocated once for each driver that's loaded
@@ -898,14 +926,14 @@ struct driver_object {
void *dro_driverstart;
uint32_t dro_driversize;
void *dro_driversection;
- driver_extension dro_driverext;
+ driver_extension *dro_driverext;
unicode_string dro_drivername;
unicode_string *dro_hwdb;
void *dro_pfastiodispatch;
void *dro_driverinitfunc;
void *dro_driverstartiofunc;
void *dro_driverunloadfunc;
- void *dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1];
+ driver_dispatch dro_dispatch[IRP_MJ_MAXIMUM_FUNCTION + 1];
};
typedef struct driver_object driver_object;
@@ -931,6 +959,81 @@ typedef struct driver_object driver_object;
#define DEVPROP_INSTALL_STATE 0x00000012
#define DEVPROP_REMOVAL_POLICY 0x00000013
+/* Various supported device types (used with IoCreateDevice()) */
+
+#define FILE_DEVICE_BEEP 0x00000001
+#define FILE_DEVICE_CD_ROM 0x00000002
+#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
+#define FILE_DEVICE_CONTROLLER 0x00000004
+#define FILE_DEVICE_DATALINK 0x00000005
+#define FILE_DEVICE_DFS 0x00000006
+#define FILE_DEVICE_DISK 0x00000007
+#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
+#define FILE_DEVICE_FILE_SYSTEM 0x00000009
+#define FILE_DEVICE_INPORT_PORT 0x0000000A
+#define FILE_DEVICE_KEYBOARD 0x0000000B
+#define FILE_DEVICE_MAILSLOT 0x0000000C
+#define FILE_DEVICE_MIDI_IN 0x0000000D
+#define FILE_DEVICE_MIDI_OUT 0x0000000E
+#define FILE_DEVICE_MOUSE 0x0000000F
+#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010
+#define FILE_DEVICE_NAMED_PIPE 0x00000011
+#define FILE_DEVICE_NETWORK 0x00000012
+#define FILE_DEVICE_NETWORK_BROWSER 0x00000013
+#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
+#define FILE_DEVICE_NULL 0x00000015
+#define FILE_DEVICE_PARALLEL_PORT 0x00000016
+#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
+#define FILE_DEVICE_PRINTER 0x00000018
+#define FILE_DEVICE_SCANNER 0x00000019
+#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001A
+#define FILE_DEVICE_SERIAL_PORT 0x0000001B
+#define FILE_DEVICE_SCREEN 0x0000001C
+#define FILE_DEVICE_SOUND 0x0000001D
+#define FILE_DEVICE_STREAMS 0x0000001E
+#define FILE_DEVICE_TAPE 0x0000001F
+#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
+#define FILE_DEVICE_TRANSPORT 0x00000021
+#define FILE_DEVICE_UNKNOWN 0x00000022
+#define FILE_DEVICE_VIDEO 0x00000023
+#define FILE_DEVICE_VIRTUAL_DISK 0x00000024
+#define FILE_DEVICE_WAVE_IN 0x00000025
+#define FILE_DEVICE_WAVE_OUT 0x00000026
+#define FILE_DEVICE_8042_PORT 0x00000027
+#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
+#define FILE_DEVICE_BATTERY 0x00000029
+#define FILE_DEVICE_BUS_EXTENDER 0x0000002A
+#define FILE_DEVICE_MODEM 0x0000002B
+#define FILE_DEVICE_VDM 0x0000002C
+#define FILE_DEVICE_MASS_STORAGE 0x0000002D
+#define FILE_DEVICE_SMB 0x0000002E
+#define FILE_DEVICE_KS 0x0000002F
+#define FILE_DEVICE_CHANGER 0x00000030
+#define FILE_DEVICE_SMARTCARD 0x00000031
+#define FILE_DEVICE_ACPI 0x00000032
+#define FILE_DEVICE_DVD 0x00000033
+#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034
+#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035
+#define FILE_DEVICE_DFS_VOLUME 0x00000036
+#define FILE_DEVICE_SERENUM 0x00000037
+#define FILE_DEVICE_TERMSRV 0x00000038
+#define FILE_DEVICE_KSEC 0x00000039
+#define FILE_DEVICE_FIPS 0x0000003A
+
+/* Device characteristics */
+
+#define FILE_REMOVABLE_MEDIA 0x00000001
+#define FILE_READ_ONLY_DEVICE 0x00000002
+#define FILE_FLOPPY_DISKETTE 0x00000004
+#define FILE_WRITE_ONCE_MEDIA 0x00000008
+#define FILE_REMOTE_DEVICE 0x00000010
+#define FILE_DEVICE_IS_MOUNTED 0x00000020
+#define FILE_VIRTUAL_VOLUME 0x00000040
+#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080
+#define FILE_DEVICE_SECURE_OPEN 0x00000100
+
+/* Status codes */
+
#define STATUS_SUCCESS 0x00000000
#define STATUS_USER_APC 0x000000C0
#define STATUS_KERNEL_APC 0x00000100
@@ -938,12 +1041,25 @@ typedef struct driver_object driver_object;
#define STATUS_TIMEOUT 0x00000102
#define STATUS_INVALID_PARAMETER 0xC000000D
#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010
+#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016
#define STATUS_BUFFER_TOO_SMALL 0xC0000023
#define STATUS_MUTANT_NOT_OWNED 0xC0000046
#define STATUS_INVALID_PARAMETER_2 0xC00000F0
+#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A
#define STATUS_WAIT_0 0x00000000
+/* Memory pool types, for ExAllocatePoolWithTag() */
+
+#define NonPagedPool 0x00000000
+#define PagedPool 0x00000001
+#define NonPagedPoolMustSucceed 0x00000002
+#define DontUseThisType 0x00000003
+#define NonPagedPoolCacheAligned 0x00000004
+#define PagedPoolCacheAligned 0x00000005
+#define NonPagedPoolCacheAlignedMustS 0x00000006
+#define MaxPoolType 0x00000007
+
/*
* FreeBSD's kernel stack is 2 pages in size by default. The
* Windows stack is larger, so we need to give our threads more
@@ -954,6 +1070,16 @@ typedef struct driver_object driver_object;
extern image_patch_table ntoskrnl_functbl[];
__BEGIN_DECLS
+extern int windrv_libinit(void);
+extern int windrv_libfini(void);
+extern driver_object *windrv_lookup(vm_offset_t);
+extern int windrv_load(module_t, vm_offset_t, int);
+extern int windrv_unload(module_t, vm_offset_t, int);
+extern int windrv_create_pdo(driver_object *, device_t);
+extern void windrv_destroy_pdo(driver_object *, device_t);
+extern device_object *windrv_find_pdo(driver_object *, device_t);
+extern int windrv_bus_attach(driver_object *, char *);
+
extern int ntoskrnl_libinit(void);
extern int ntoskrnl_libfini(void);
__stdcall extern void KeInitializeDpc(kdpc *, void *, void *);
@@ -962,8 +1088,7 @@ __stdcall extern uint8_t KeRemoveQueueDpc(kdpc *);
__stdcall extern void KeInitializeTimer(ktimer *);
__stdcall extern void KeInitializeTimerEx(ktimer *, uint32_t);
__stdcall extern uint8_t KeSetTimer(ktimer *, int64_t, kdpc *);
-__stdcall extern uint8_t KeSetTimerEx(ktimer *, int64_t,
- uint32_t, kdpc *);
+__stdcall extern uint8_t KeSetTimerEx(ktimer *, int64_t, uint32_t, kdpc *);
__stdcall extern uint8_t KeCancelTimer(ktimer *);
__stdcall extern uint8_t KeReadStateTimer(ktimer *);
__stdcall extern uint32_t KeWaitForSingleObject(nt_dispatch_header *, uint32_t,
@@ -976,8 +1101,20 @@ __stdcall extern uint32_t KeResetEvent(nt_kevent *);
__fastcall extern void KefAcquireSpinLockAtDpcLevel(REGARGS1(kspin_lock *));
__fastcall extern void KefReleaseSpinLockFromDpcLevel(REGARGS1(kspin_lock *));
__stdcall extern void KeInitializeSpinLock(kspin_lock *);
+__stdcall extern void *ExAllocatePoolWithTag(uint32_t, size_t, uint32_t);
+__stdcall extern void ExFreePool(void *);
+__stdcall extern uint32_t IoAllocateDriverObjectExtension(driver_object *,
+ void *, uint32_t, void **);
+__stdcall extern void *IoGetDriverObjectExtension(driver_object *, void *);
+__stdcall extern uint32_t IoCreateDevice(driver_object *, uint32_t,
+ unicode_string *, uint32_t, uint32_t, uint8_t, device_object **);
+__stdcall extern void IoDeleteDevice(device_object *);
+__stdcall extern device_object *IoGetAttachedDevice(device_object *);
__fastcall extern uint32_t IofCallDriver(REGARGS2(device_object *, irp *));
__fastcall extern void IofCompleteRequest(REGARGS2(irp *, uint8_t));
+__stdcall extern void IoDetachDevice(device_object *);
+__stdcall extern device_object *IoAttachDeviceToDeviceStack(device_object *,
+ device_object *);
#define IoCallDriver(a, b) FASTCALL2(IofCallDriver, a, b)
#define IoCompleteRequest(a, b) FASTCALL2(IofCompleteRequest, a, b)
OpenPOWER on IntegriCloud