Всем доброго! Встретил такую запись: Код (Text): RtlCopyMemory( nextIrpSp, irpSp, FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); это кусок макроса, я не могу понять FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine), какой IRP именно принадлежит CompletionRoutine. Грубого говоря: RtlCopyMemory( nextIrpSp, irpSp, FIELD_OFFSET(IO_STACK_LOCATION,nextIrpSp->CompletionRoutine или irpSp->CompletionRoutine)); заранее, спасибо!
// // Calculate the byte offset of a field in a structure of type type. // #define FIELD_OFFSET(type, field) ((LONG)(LONG_PTR)&(((type *)0)->field)) т.е это макрос просто вычисляет смещение от начала структуры до указанного поля. Приведенный код копирует часть структуры IO_STACK_LOCATION до поля, задающего функцию завершения запроса. По сему Ваш вопрос не имеет ответа
"Вспомните, что при передаче IRP нижестоящему драйверу, драйвер kbdclass скопировал свой блок стека в следующий, использую макрос IoCopyCurrentIrpStackLocationToNext. Однако этот макрос не копирует поля связанные с процедурой завершения. Если бы он этого не сделал, то указатель на нашу процедуру завершения (он находится в блоке стека драйвера kbdclass) попал бы в блок стека драйвера i8042prt, и наша процедура завершения была бы вызвана дважды. В стародавние времена, когда ещё не было макроса IoCopyCurrentIrpStackLocationToNext, программисты вручную копировали блоки стека, иногда забывая обнулить поля связанные с процедурой завершения, что приводило к трудно находимым багам." Остальное в статье: http://wasm.ru/article.php?article=drvw2k15 Там также можно узнать, что IRP не принадлежит CompletionRoutine. Скорее наоборот, а ещё точнее в каждом IO_STACK_LOCATION может быть указатель на CompletionRoutine и эти процедуры принадлежат разным драйверам.
TarasCo, спасибо. Это понятно что идет расчет длины копируемых данных, просто как то(лично для меня) не привычно, видить такие записи. В тоже время как выясняется IO_STACK_LOCATION, может иметь 2 различные по содержанию структуры, отсюда и такой сопсоб вычисления длины компируемых данных. Four-F, столько информации сразу, что в голове сплошная каша. Спасибо.
Тут у меня еще возник вопрос или точнее, я опять в замешательстве... Вот структура: Код (Text): typedef struct _SPY_COMPLETION_CONTEXT_W2K { SPY_COMPLETION_CONTEXT; WORK_QUEUE_ITEM WorkItem; PDEVICE_OBJECT DeviceObject; PIRP Irp; PDEVICE_OBJECT NewDeviceObject; } SPY_COMPLETION_CONTEXT_W2K, *PSPY_COMPLETION_CONTEXT_W2K; как понимать SPY_COMPLETION_CONTEXT; ????? пример взят из ddk\filespy
вот еще: Код (Text): #define IoMarkIrpPending( Irp ) ( \ IoGetCurrentIrpStackLocation( (Irp) )->Control |= SL_PENDING_RETURNED ) Control, тут без хорошей помощи вовсе не обойтись. Four-F, на сколько я понял из твоих исходников Код (Text): это (Irp)->Control есть mov eax, (_IRP PTR [eax]).Tail.Overlay.CurrentStackLocation (IO_STACK_LOCATION PTR [eax]).Control или PIO_STACK_LOCATION((Irp)->Tail.Overlay.CurrentStackLocation)->control верно?
<font color="gray][ LuckyDevil</font><!--color--><font color="gray]: В тоже время как выясняется IO_STACK_LOCATION, может иметь 2 различные по содержанию структуры, отсюда и такой сопсоб вычисления длины компируемых данных. ]</font><!--color--> IO_STACK_LOCATION является объединением намного бОльшего чем 2 числа структур, а способ вычисления длины компируемых данных такой совсем не поэтому. Сколько бы членов в объединении IO_STACK_LOCATION.Parameters не было, его размер определяется членом имеющим максимальным размер и смещение поля CompletionRoutine будет фиксированным. <font color="gray][ LuckyDevil</font><!--color--><font color="gray]: как понимать SPY_COMPLETION_CONTEXT; ]</font><!--color--> Это вложенная структура. Просто у члена нет имени и можно обращаться к членам SPY_COMPLETION_CONTEXT напрямую. Код (Text): typedef struct _A { DWORD dw; } A; typedef struct _B { A; } B; A a; B b; a.dw = 0; b.dw = 0; <font color="gray][ LuckyDevil</font><!--color--><font color="gray]: верно? ]</font><!--color--> Да.
Код (Text): Это вложенная структура. Просто у члена нет имени и можно обращаться к членам SPY_COMPLETION_CONTEXT напрямую. Four-F, ну надо же какие чудеса ))), дял меня это новость, Си то я не так хорошо знаю, спасибо за информацию!!!!! а если я так напишу это будет тоже самое ? Four-F, Развивая эту тему: Код (Text): typedef struct _SPY_COMPLETION_CONTEXT { PRECORD_LIST RecordList; } SPY_COMPLETION_CONTEXT, *PSPY_COMPLETION_CONTEXT; typedef struct _SPY_COMPLETION_CONTEXT_W2K { SPY_COMPLETION_CONTEXT AA; WORK_QUEUE_ITEM WorkItem; PDEVICE_OBJECT DeviceObject; PIRP Irp; PDEVICE_OBJECT NewDeviceObject; } SPY_COMPLETION_CONTEXT_W2K, *PSPY_COMPLETION_CONTEXT_W2K; ... PSPY_COMPLETION_CONTEXT_W2K BB; ... BB->AA.RecordList