Hello,
I am currently porting a pseudo disk driver to NT from Unix of which one
aspect of its operation is to perform a mirrored write. The manner in
which it performs the mirrored write is to clone the original IRP for
each mirror and then issue the cloned IRPs to the primary and secondary
devices. During the mirrored write the original IRP is stalled. After
the cloned requests complete, the original IRP is eventually completed.
If I only clone the IRP once and issue the clone to the primary device
the driver seems to work well (as evidenced by a data integrity tool
I'm using).
However, if I instruct the driver to perform mirroring, the data sent
to the primary device is always corrupted (I am currently unable to
verify the secondary as it is not written in the original format).
Here's is the gist of my IRP clone operation. After calling the
cloning macro a cloned IRP is further modiefied to point to the
correct device by directly setting the DeviceObject field in the IRP.
Also, the IRPs are hand made and set up by IoInitializeIrp() rather
than by IoAllocateIrp().
It's probably worth admitting that while I have programmed drivers for
Unix for many years I've only been working with NT for a month or so.
I would greatly appreciate any insight into how to solve this problem
correctly. I have scoured this list and the web for similar examples
but haven't found anything relevant thus far.
Thanks!
Greg
#define CLONE_IRP(src, dst, zoffset) \
do { \
IO_STACK_LOCATION *srcstk, *dststk; \
srcstk = IoGetCurrentIrpStackLocation(src); \
dststk = IoGetCurrentIrpStackLocation(dst); \
*dststk = *srcstk; \
dststk->Context = (void *)0; \
(dst)->MdlAddress = IoAllocateMdl( \
MmGetMdlVirtualAddress((src)->MdlAddress), \
MmGetMdlByteCount((src)->MdlAddress), \
FALSE, FALSE, (IRP *)0); \
IoBuildPartialMdl((src)->MdlAddress, (dst)->MdlAddress, \
(char *)MmGetMdlVirtualAddress((src)->MdlAddress) + \
(zoffset), (unsigned long)0); \
(dst)->Tail.Overlay.Thread = (src)->Tail.Overlay.Thread; \
} while (0)