📄 ntvol.c
字号:
/* Check to make sure the DeviceObject passed in is actually ours! */
if (Extension->lMagicNumber != 0xabfeacde)
KeBugCheck ((ULONG) 0xabfeacde);
ASSERT (Extension->nDosDriveNo >= 0 && Extension->nDosDriveNo <= 0x19);
#ifdef USE_KERNEL_MUTEX
KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode,
FALSE, NULL);
#endif
#if EXTRA_INFO
Dump ("Completing IRP...BEGIN\n");
Dump ("COMPLETION USER BUFFER IS 0x%08x MDL ADDRESS IS 0x%08x\n", Irp->UserBuffer, Irp->MdlAddress);
Dump ("COMPLETION Irp->Tail.Overlay.OriginalFileObject = 0x%08x\n", Irp->Tail.Overlay.OriginalFileObject);
Dump ("Completing DeviceObject 0x%08x Irp 0x%08x\n", DeviceObject, Irp);
#endif
/* Note: The Irp stack location we get back here is our one, we setup
the next stack location with a copy of this stack data in the send
function... here we always get back our own stack location, so
it's possible to use Read.Key to store extra pointers if needed. */
irpSp = IoGetCurrentIrpStackLocation (Irp);
ntStatus = Irp->IoStatus.Status;
if (ntStatus == STATUS_TOO_LATE)
KeBugCheck ((ULONG) 0x50ff);
if (Irp->PendingReturned) /* From Windows NT File System
Internals */
IoMarkIrpPending (Irp);
if (Extension->bRawDevice == FALSE)
{
/* Note: For some reason even though we used DIRECT_IO
sometimes the Irp's come back to use with MDLs !! if we
get an MDL here we need to free it up otherwise later when
we call IoFreeIrp the system will trap */
PMDL pMdl, pNextMdl;
pMdl = Irp->MdlAddress;
while (pMdl != NULL)
{
pNextMdl = pMdl->Next;
MmUnmapLockedPages (MmGetSystemAddressForMdlSafe (pMdl, HighPagePriority), pMdl);
MmUnlockPages (pMdl);
IoFreeMdl (pMdl);
pMdl = pNextMdl;
}
}
if (NT_SUCCESS (Irp->IoStatus.Status) && irpSp->MajorFunction == IRP_MJ_READ)
{
__int64 tmpOffset = irpSp->Parameters.Read.ByteOffset.QuadPart;
ULONG tmpLength = irpSp->Parameters.Read.Length;
PUCHAR CurrentAddress;
if (Extension->bRawDevice == TRUE)
CurrentAddress = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, HighPagePriority);
else
CurrentAddress = Irp->UserBuffer;
if (tmpLength > 0)
{
/* Decrypt the data on read */
Extension->cryptoInfo->decrypt_sector ((ULONG *) CurrentAddress,
tmpOffset / SECTOR_SIZE,
tmpLength / SECTOR_SIZE,
&Extension->cryptoInfo->ks[0],
Extension->cryptoInfo->iv,
Extension->cryptoInfo->cipher);
}
if (Extension->bRawDevice == FALSE)
{
PIRP OldIrp = (PIRP) pUserBuffer;
PUCHAR OriginalAddress;
CurrentAddress = Irp->UserBuffer;
OriginalAddress = MmGetSystemAddressForMdlSafe (OldIrp->MdlAddress, HighPagePriority);
memcpy (OriginalAddress, CurrentAddress, Irp->IoStatus.Information);
}
}
if (NT_SUCCESS (Irp->IoStatus.Status) && irpSp->MajorFunction == IRP_MJ_WRITE)
{
PUCHAR CurrentAddress;
PUCHAR OriginalAddress;
if (Extension->bRawDevice == TRUE)
{
CurrentAddress = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, HighPagePriority);
OriginalAddress = MmGetSystemAddressForMdlSafe ((PMDL) pUserBuffer, HighPagePriority);
}
else
{
PIRP OldIrp = (PIRP) pUserBuffer;
CurrentAddress = Irp->UserBuffer;
OriginalAddress = MmGetSystemAddressForMdlSafe (OldIrp->MdlAddress, HighPagePriority);
}
//if (NT_SUCCESS (Irp->IoStatus.Status))
//{
// __int64 tmpOffset = irpSp->Parameters.Read.ByteOffset.QuadPart;
//}
}
if (Extension->bRawDevice == TRUE && irpSp->MajorFunction == IRP_MJ_WRITE)
{
PUCHAR tmpBuffer = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, HighPagePriority);
/* Free the temp buffer we allocated */
TCfree (tmpBuffer);
/* Free the Mdl we allocated */
IoFreeMdl (Irp->MdlAddress);
/* Reset the Irp */
Irp->MdlAddress = pUserBuffer;
}
if (Extension->bRawDevice == TRUE && irpSp->MajorFunction == IRP_MJ_READ)
{
/* Nothing to do */
}
#if EXTRA_INFO
Dump ("COMPLETION OLD USER BUFFER IS 0x%08x MDL ADDRESS IS 0x%08x\n", Irp->UserBuffer, Irp->MdlAddress);
Dump ("COMPLETION OLD Irp->Tail.Overlay.OriginalFileObject = 0x%08x\n", Irp->Tail.Overlay.OriginalFileObject);
Dump ("Completing IRP 0x%08x NTSTATUS 0x%08x information %lu END\n", (ULONG) irpSp->MajorFunction,
Irp->IoStatus.Status, Irp->IoStatus.Information);
#endif
if (Extension->bRawDevice == FALSE)
{
PIRP OldIrp = (PIRP) pUserBuffer;
PVOID tmpBuffer = Irp->UserBuffer;
BOOL bFreeBuffer = irpSp->MajorFunction == IRP_MJ_WRITE || irpSp->MajorFunction == IRP_MJ_READ;
OldIrp->IoStatus.Status = Irp->IoStatus.Status;
OldIrp->IoStatus.Information = Irp->IoStatus.Information;
IoCompleteRequest (OldIrp, IO_DISK_INCREMENT);
#if EXTRA_INFO
Dump ("About to free allocated IRP\n");
#endif
Irp->UserBuffer = NULL;
/* Free the allocated IRP. Note: This must be done before we
free tmpBuffer! */
IoFreeIrp (Irp);
/* Note: From here on we cannot touch the Irp or irpSp */
#if EXTRA_INFO
Dump ("Free allocated buffer = %d\n", bFreeBuffer);
#endif
if (bFreeBuffer == TRUE)
TCfree (tmpBuffer);
ntStatus = STATUS_MORE_PROCESSING_REQUIRED;
}
#ifdef USE_KERNEL_MUTEX
KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
return ntStatus;
}
NTSTATUS
TCReadWrite (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp)
{
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
PUCHAR tmpBuffer = NULL;/* Remove compiler warning */
NTSTATUS ntStatus;
// Dump ("TCReadWrite BEGIN\n");
/* Check for invalid parameters. It is an error for the starting
offset + length to go past the end of the buffer, or for the
length to not be a proper multiple of the sector size. Others are
possible, but we don't check them since we trust the file system
and they aren't deadly. */
if (irpSp->Parameters.Read.ByteOffset.QuadPart + irpSp->Parameters.Read.Length > Extension->DiskLength
|| (irpSp->Parameters.Read.Length & (Extension->BytesPerSector - 1)))
{
return COMPLETE_IRP (DeviceObject, Irp, STATUS_INVALID_PARAMETER, 0);
}
else
{
if (irpSp->Parameters.Read.Length == 0)
{
return COMPLETE_IRP (DeviceObject, Irp, STATUS_INVALID_PARAMETER, 0);
}
}
#if EXTRA_INFO
Dump ("USER BUFFER IS 0x%08x MDL ADDRESS IS 0x%08x\n", Irp->UserBuffer, Irp->MdlAddress);
Dump ("Irp->Tail.Overlay.OriginalFileObject = 0x%08x\n", Irp->Tail.Overlay.OriginalFileObject);
Dump ("irpSp->FileObject = 0x%08x\n", irpSp->FileObject);
if (Irp->Tail.Overlay.OriginalFileObject != NULL)
{
if (Irp->Tail.Overlay.OriginalFileObject->FileName.Length != 0)
Dump ("Irp->Tail.Overlay.OriginalFileObject = %ls\n", Irp->Tail.Overlay.OriginalFileObject->FileName.Buffer);
else
Dump ("Irp->Tail.Overlay.OriginalFileObject = %ls\n", WIDE ("null value"));
}
if (irpSp->FileObject != NULL)
{
if (irpSp->FileObject->FileName.Length != 0)
Dump ("irpSp->FileObject = %ls\n", irpSp->FileObject->FileName.Buffer);
else
Dump ("irpSp->FileObject = %ls\n", WIDE ("null value"));
}
#endif
if (Extension->bReadOnly == TRUE && irpSp->MajorFunction == IRP_MJ_WRITE)
return COMPLETE_IRP (DeviceObject, Irp, STATUS_MEDIA_WRITE_PROTECTED, 0);
if (Extension->bRawDevice == FALSE || irpSp->MajorFunction == IRP_MJ_WRITE)
{
tmpBuffer = TCalloc (irpSp->Parameters.Read.Length);
if (tmpBuffer == NULL)
return COMPLETE_IRP (DeviceObject, Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
}
if (irpSp->MajorFunction == IRP_MJ_READ)
{
// Dump ("Read: 0x%08x for %lu bytes...\n", irpSp->Parameters.Read.ByteOffset.LowPart,
// irpSp->Parameters.Read.Length);
/* Fixup the parameters to handle this particular volume type */
irpSp->Parameters.Read.ByteOffset.QuadPart += SECTOR_SIZE;
if (Extension->bRawDevice == TRUE)
ntStatus = TCSendIRP_RawDevice (DeviceObject, Extension,
NULL, IRP_READ_OPERATION | IRP_NOCACHE,
irpSp->MajorFunction,
Irp);
else
ntStatus = TCSendIRP_FileDevice (DeviceObject, Extension,
tmpBuffer, IRP_READ_OPERATION | IRP_NOCACHE,
irpSp->MajorFunction,
Irp);
}
else
{
PUCHAR CurrentAddress;
// Dump ("Write: 0x%08x for %lu bytes...\n", irpSp->Parameters.Read.ByteOffset.LowPart,
// irpSp->Parameters.Read.Length);
CurrentAddress = (PUCHAR) MmGetSystemAddressForMdlSafe (Irp->MdlAddress, HighPagePriority);
/* Fixup the parameters to handle this particular volume type */
irpSp->Parameters.Read.ByteOffset.QuadPart += SECTOR_SIZE;
memcpy (tmpBuffer, CurrentAddress, irpSp->Parameters.Read.Length);
/* Encrypt the data */
Extension->cryptoInfo->encrypt_sector ((ULONG *) tmpBuffer,
irpSp->Parameters.Read.ByteOffset.QuadPart / SECTOR_SIZE,
irpSp->Parameters.Read.Length / SECTOR_SIZE,
&Extension->cryptoInfo->ks[0],
Extension->cryptoInfo->iv,
Extension->cryptoInfo->cipher);
if (Extension->bRawDevice == TRUE)
{
PMDL tmpBufferMdl = IoAllocateMdl (tmpBuffer, irpSp->Parameters.Read.Length, FALSE, FALSE, NULL);
PMDL pTrueMdl = Irp->MdlAddress;
if (tmpBufferMdl == NULL)
{
TCfree (tmpBuffer);
return COMPLETE_IRP (DeviceObject, Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
}
MmBuildMdlForNonPagedPool (tmpBufferMdl);
Irp->MdlAddress = tmpBufferMdl;
#if EXTRA_INFO
Dump ("NEW MDL ADDRESS IS 0x%08x UserBuffer = 0x%08x\n", Irp->MdlAddress, Irp->UserBuffer);
#endif
ntStatus = TCSendIRP_RawDevice (DeviceObject, Extension,
pTrueMdl, IRP_WRITE_OPERATION | IRP_NOCACHE,
irpSp->MajorFunction,
Irp);
}
else
{
ntStatus = TCSendIRP_FileDevice (DeviceObject, Extension,
tmpBuffer, IRP_WRITE_OPERATION | IRP_NOCACHE,
irpSp->MajorFunction,
Irp);
}
}
// Dump ("TCReadWrite END\n");
return ntStatus;
}
NTSTATUS
TCSendDeviceIoControlRequest (PDEVICE_OBJECT DeviceObject,
PEXTENSION Extension,
ULONG IoControlCode,
char *OutputBuffer,
int OutputBufferSize)
{
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS ntStatus;
PIRP Irp;
if (DeviceObject); /* Remove compiler warning */
KeClearEvent (&Extension->keVolumeEvent);
Irp = IoBuildDeviceIoControlRequest (IoControlCode,
Extension->pFsdDevice,
NULL, 0,
OutputBuffer, OutputBufferSize,
FALSE,
&Extension->keVolumeEvent,
&IoStatusBlock);
if (Irp == NULL)
{
Dump ("IRP allocation failed\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
ntStatus = IoCallDriver (Extension->pFsdDevice, Irp);
if (ntStatus == STATUS_PENDING)
{
KeWaitForSingleObject (&Extension->keVolumeEvent, UserRequest, UserMode, FALSE, NULL);
ntStatus = IoStatusBlock.Status;
}
return ntStatus;
}
NTSTATUS
COMPLETE_IRP (PDEVICE_OBJECT DeviceObject,
PIRP Irp,
NTSTATUS IrpStatus,
ULONG IrpInformation)
{
Irp->IoStatus.Status = IrpStatus;
Irp->IoStatus.Information = IrpInformation;
if (DeviceObject); /* Remove compiler warning */
#ifdef _DEBUG
if (!NT_SUCCESS (IrpStatus))
{
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
Dump ("COMPLETE_IRP FAILING IRP %ls Flags 0x%08x vpb 0x%08x NTSTATUS 0x%08x\n", TCTranslateCode (irpSp->MajorFunction),
(ULONG) DeviceObject->Flags, (ULONG) DeviceObject->Vpb->Flags, IrpStatus);
}
//else
//{
// PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
// Dump ("COMPLETE_IRP SUCCESS IRP %ls Flags 0x%08x vpb 0x%08x NTSTATUS 0x%08x\n", TCTranslateCode (irpSp->MajorFunction),
// (ULONG) DeviceObject->Flags, (ULONG) DeviceObject->Vpb->Flags, IrpStatus);
//}
#endif
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return IrpStatus;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -