⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntvol.c

📁 加密硬盘、分区、虚拟盘的程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* 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 + -