Fix a bug in src/winvblock/mainbus/dummyirp.c where such a PDO should really respond directly to an IRP_MJ_PNP:IRP_MN_START_DEVICE. Assign a PDO to the safe hook FDO bus in WvSafeHookPnpQueryDeviceRelations. That way, it's linked for the the later PnP probe for its capabilities, and also linked for its later removal. Fix a bug in WvSafeHookPnpRemoveDevice where a safe hook FDO would try to pass WvlDeleteDevice a null pointer. Add a DummyPdo member to S_WV_SAFE_HOOK_DUMMY_WRAPPER so we can calculate the offset of the dummy IDs relative to the wrapper's beginning. Remove a hack for the old, non-mini-driver safe hook PDOs. Actually create the safe hook PDO in WvlCreateSafeHookDevice, instead of it calling the old, non-mini-driver code.
When queried for BusRelations, a safe hook FDO should probe the previous hook in the chain and create a PDO, if appropriate.
This function doesn't deal with how a bus device responds to a BusRelations query (that's up to each mini-driver), but it does increment or decrement a reference count on the bus device, so each assignment call must be matched by a corresponding unassignment call at some point during the child device's lifetime.
These two new functions are now used by WvlAttachDeviceToDeviceStack and WvlDetachDevice to set and unset the "linked" flag for a device.
Because it's fairly common to accumulate device relations during processing of an IRP_MJ_PNP:IRP_MN_QUERY_DEVICE_RELATIONS, this utility function should help with taking a higher device's list and merging in the current device's list.
Other than the IDs, the SEG16:OFF16 is really the only other piece of what makes a safe hook PDO unique. The IDs could be taken care of by the dummy logic.
A future call to WvDummyAdd should have an aligned ExtraDataOffset argument, so calculate it ahead of time.
The function now takes an optional mini-driver parameter. If it is null, the main bus will own the dummy device. If non-null, the specified mini-driver will own the dummy device.
Remove the NotAvailable member of the WV_S_DEV_EXT structure. Replace part of its use with a new CvWvlDeviceFlagAvailable flag. Introduce a new CvWvlDeviceFlagLinked flag. This flag is set - For PDOs: When they are added to a parent bus - For FDOs: When they are attached to a device stack Introduce a new CvWvlDeviceFlagThread flag. This flag controls whether or not IRPs and work items can be added to the device's IRP queue. The dummy PDO logic now handles a surprise-removal by incrementing the resource usage for the device and decrementing it during the subsequent IRP_MN_REMOVE_DEVICE. This prevents the device's thread from stopping and deleting the device before the removal has been completed. (See below regarding the resource usage.) Device tear-down now works like this: The device's thread always has ultimate responsibility for deleting a device. The thread will accept IRPs and work items until such a time as: - The device is not linked (see explanation above) - The device is no longer available due to WvlDeleteDevice - The device, as a tracked resource, is only being used by the thread If any of these conditions are false, the thread continues to service IRPs and work items. It is up to the IRP dispatcher to allow PnP IRPs to be processed and to disallow other IRPs. (A mini-driver might have special PnP handling or other IOCTLs that it wishes to service, even when a device is on its way to deletion.) WvMainBusAddDevice and WvlAttachDeviceToDeviceStack both link a device. WvMainBusRemoveDevice and WvlDetachDevice both unlink a device.
AoE and HTTPDisk adjusted to add their dummy devices using WvlAddDeviceToMainBus. Removed unused WvDummyRemove function. Removed OldDevice member of S_WVL_DUMMY_PDO. Fixed a bug in WvMainBusPnpRemoveDevice where it was trying to walk a list that was being modified in between steps. Heh. dummyirp.c now uses WvlPassIrpUp instead of IoCompleteRequest. Tried to remove traces of the old style involving "bus nodes" and WV_S_DEV_T. Use WvlCreateDevice instead of IoCreateDevice and use WvlDeleteDevice instead of IoDeleteDevice. Fixed an arithmetic bug in WvMainBusRemoveDevice. TODO: Dummy device removal doesn't quite work.
In preparation for using WvlPassIrpUp, instead.
So it can be accessed by dummyirp.c.
It is starting to more closely resemble WvlCreateDevice, because eventually it will call it. A caller, such as the safe hook mini-driver, could call this function to produce a dummy device with the specified IDs _and_ extend that dummy device with additional safe-hook-specific data. This is actually the goal, since a safe hook PDO only has to carry around a note about where the INT 0x13 hook is. Crazy parameter-checking in this function... A dummy PDO device extension will usually be followed by some dummy IDs, which are always going to be wrapped with an even larger structure of arbitrary size, and then the caller might want more storage beyond all that, and it all has to be aligned properly. Phew.
...is no longer WvDummyAdd's. A dummy device should be possible to add to any bus.
A user-land utility still can, but there's not really a need for a driver to, unless the driver is trying to avoid a dependency on WinVBlock, which seems kind of contrived.
The semantics for adding a dummy device to a bus will eventually be that the caller creates a dummy device, then adds it to whatever bus. Right now, WvDummyAdd does both and chooses the main bus unconditionally, but we don't want that. While things are shuffled around, there will be some hacks just to make the transition smooth. It's good if WinVBlock still works after every commit. In this one WvDummyAdd_ more resembles what the final WvlCreateDummyDevice will look like. It ties all details together into a single device extension which is freed when the device is deleted.