Как корректно выгрузить драйвер F, чтобы не было разрыва цепочки, то есть чтобы после выгрузки драйвера F, стек драйверов состоял из драйвера B (который на верху) и драйвера A, то есть чтобы IRP идущий к драйверу A проходил через драйвер B и доходил до драйвера A ?
Корректно нельзя,
1)система при присоединении DEVICE_OBJECT
сохраняет указатель на нижележащий в закрытых структурах DEVICE_OBJECT, то есть указывать указатель там будет на отсутствующий объект.
2) Также надо будет править указатель AttachedDevice у нижележащего DEVICE_OBJECT.
3) Надо будет изменить StackCount у верних DEVICE_OBJECT(драйвер B), вычесть 1.
4)Надо убедится, что все запросы к F от B и из F к A завершены. Ни одного незавершенного запроса не должно быть на стеке, то есть B должен пендить все запросы в очередь и надо ждать завершения всех предыдущих запросов(не забывай про IoCompletion- там есть следы от драйвера F).
Все пункты, кроме 1 осуществимы, хотя и опасны так как желательно захватывать спин блокировки при изменении стека девайсов, а эти спин блокировки не экспортируются из ядра. Для осуществления пункта 1 надо или отсоединить девайс, а потом присоединить(небезопасная операция, если нет поддержки системы), или менять недокументированную структуру.