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

📄 ntdriver.c

📁 一个提供档案及Partition作加解密的程式支援以下的加密演算法AESBlowfishCAST5SerpentTriple DESTwofishAES-BlowfishAES-TwofishAES-
💻 C
📖 第 1 页 / 共 4 页
字号:
/* The source code contained in this file has been derived from the source code
   of Encryption for the Masses 2.02a by Paul Le Roux. Modifications and
   additions to that source code contained in this file are Copyright (c) 2004-2005
   TrueCrypt Foundation and Copyright (c) 2004 TrueCrypt Team. Unmodified
   parts are Copyright (c) 1998-99 Paul Le Roux. This is a TrueCrypt Foundation
   release. Please see the file license.txt for full license details. */

#include "TCdefs.h"
#include "crypto.h"
#include "fat.h"

#include "apidrvr.h"
#include "ntdriver.h"
#include "ntvol.h"
#include "ntrawdv.h"
#include "ntfiledv.h"
#include "cache.h"

#include <tchar.h>
#include <initguid.h>
#include <mountmgr.h>
#include <mountdev.h>
#include <ntddvol.h>

/* Init section, which is thrown away as soon as DriverEntry returns */
#pragma alloc_text(INIT,DriverEntry)
#pragma alloc_text(INIT,TCCreateRootDeviceObject)

/* Sync mutex for the entire driver */
KMUTEX driverMutex;

/* DriverEntry initialize's the dispatch addresses to be passed back to NT.
   RUNS AT IRQL = PASSIVE_LEVEL(0) */
NTSTATUS
DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
	if (RegistryPath);	/* Remove warning */

	DriverObject->MajorFunction[IRP_MJ_CREATE] = TCDispatchQueueIRP;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = TCDispatchQueueIRP;
	DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TCDispatchQueueIRP;
	DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = TCDispatchQueueIRP;
	DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = TCDispatchQueueIRP;
	DriverObject->MajorFunction[IRP_MJ_READ] = TCDispatchQueueIRP;
	DriverObject->MajorFunction[IRP_MJ_WRITE] = TCDispatchQueueIRP;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TCDispatchQueueIRP;

	DriverObject->DriverUnload = TCUnloadDriver;

	KeInitializeMutex (&driverMutex, 1);

	return TCCreateRootDeviceObject (DriverObject);
}

#ifdef _DEBUG
// Dumps a memory region to debug output
void DumpMem(void *mem, int len)
{
	unsigned char str[20];
	unsigned char *m = mem;
	int i,j;

	for (j=0; j<len/8; j++)
	{
		memset (str,0,sizeof str);
		for (i=0; i<8; i++) 
		{
			if (m[i] > ' ' && m[i] < '~')
				str[i]=m[i];
			else
				str[i]='.';
		}

		Dump ("0x%08x  %02x %02x %02x %02x %02x %02x %02x %02x  %s\n",
			m, m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], str);

		m+=8;
	}
}
#endif

/* TCDispatchQueueIRP queues any IRP's so that they can be processed later
   by the thread -- or in some cases handles them immediately! */
NTSTATUS
TCDispatchQueueIRP (PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
	PEXTENSION Extension = (PEXTENSION) DeviceObject->DeviceExtension;
	PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
	NTSTATUS ntStatus;

#ifdef USE_KERNEL_MUTEX
	if (Extension->bRootDevice == FALSE)
		KeWaitForMutexObject (&Extension->KernelMutex, Executive, KernelMode,
				      FALSE, NULL);
#endif

#ifdef _DEBUG
	if (irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
		Dump ("TCDispatchQueueIRP BEGIN MajorFunction = %ls 0x%08x IoControlCode = %ls 0x%08x\n",
		      TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction,
		      TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode),
		      (int) irpSp->Parameters.DeviceIoControl.IoControlCode);
	//else
	//	Dump ("TCDispatchQueueIRP BEGIN MajorFunction = %ls 0x%08x\n",
	//	      TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction);
#endif

	if (Extension->bRootDevice == FALSE)
	{
		if (irpSp->MajorFunction == IRP_MJ_READ || irpSp->MajorFunction == IRP_MJ_WRITE ||
		    irpSp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
		{
			if ((DeviceObject->Flags & DO_VERIFY_VOLUME))
			{
				if (!(irpSp->Flags & SL_OVERRIDE_VERIFY_VOLUME))
				{
					Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
					Irp->IoStatus.Information = 0;
					if (!NT_SUCCESS (Irp->IoStatus.Status) &&
					    IoIsErrorUserInduced (Irp->IoStatus.Status))
					{
						IoSetHardErrorOrVerifyDevice (Irp, DeviceObject);
					}
					ntStatus = Irp->IoStatus.Status;
					IoCompleteRequest (Irp, IO_NO_INCREMENT);
					//Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus);
#ifdef USE_KERNEL_MUTEX
					if (Extension->bRootDevice == FALSE)
						KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
					return ntStatus;
				}
				else if (Extension->bShuttingDown == TRUE)
				{
					Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
					Irp->IoStatus.Information = 0;
					if (!NT_SUCCESS (Irp->IoStatus.Status) &&
					    IoIsErrorUserInduced (Irp->IoStatus.Status))
					{
						IoSetHardErrorOrVerifyDevice (Irp, DeviceObject);
					}
					ntStatus = Irp->IoStatus.Status;
					IoCompleteRequest (Irp, IO_NO_INCREMENT);
					//Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus);
#ifdef USE_KERNEL_MUTEX
					if (Extension->bRootDevice == FALSE)
						KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
					return ntStatus;
				}
			}
			else if (Extension->bShuttingDown == TRUE)
			{
				if (DeviceObject->Vpb && DeviceObject->Vpb->Flags & VPB_MOUNTED)
				{
					Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
					Irp->IoStatus.Information = 0;
					if (!NT_SUCCESS (Irp->IoStatus.Status) &&
					    IoIsErrorUserInduced (Irp->IoStatus.Status))
					{
						IoSetHardErrorOrVerifyDevice (Irp, DeviceObject);
					}
					DeviceObject->Flags |= DO_VERIFY_VOLUME;
				}
				else
				{
					Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
					Irp->IoStatus.Information = 0;
				}

				ntStatus = Irp->IoStatus.Status;
				IoCompleteRequest (Irp, IO_NO_INCREMENT);
				//Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus);
#ifdef USE_KERNEL_MUTEX
				if (Extension->bRootDevice == FALSE)
					KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
				return ntStatus;
			}
		}
		else if ((DeviceObject->Flags & DO_VERIFY_VOLUME))
		{		/* If shutting down or media removed */
			if (Extension->bShuttingDown == TRUE)
			{
				Irp->IoStatus.Status = STATUS_VERIFY_REQUIRED;
				Irp->IoStatus.Information = 0;
				if (!NT_SUCCESS (Irp->IoStatus.Status) &&
				IoIsErrorUserInduced (Irp->IoStatus.Status))
				{
					IoSetHardErrorOrVerifyDevice (Irp, DeviceObject);
				}
				ntStatus = Irp->IoStatus.Status;
				IoCompleteRequest (Irp, IO_NO_INCREMENT);
				//Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus);
#ifdef USE_KERNEL_MUTEX
				if (Extension->bRootDevice == FALSE)
					KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
				return ntStatus;
			}
			else
			{
				Irp->IoStatus.Status = STATUS_IO_DEVICE_ERROR;
				Irp->IoStatus.Information = 0;
				ntStatus = Irp->IoStatus.Status;
				IoCompleteRequest (Irp, IO_NO_INCREMENT);
				//Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus);
#ifdef USE_KERNEL_MUTEX
				if (Extension->bRootDevice == FALSE)
					KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
				return ntStatus;
			}
		}
	}

	switch (irpSp->MajorFunction)
	{
	case IRP_MJ_CLOSE:
	case IRP_MJ_CREATE:
	case IRP_MJ_CLEANUP:
#ifdef USE_KERNEL_MUTEX
		if (Extension->bRootDevice == FALSE)
			KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
		return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);

	case IRP_MJ_SHUTDOWN:
#ifdef USE_KERNEL_MUTEX
		if (Extension->bRootDevice == FALSE)
			KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
		if (Extension->bRootDevice == TRUE)
			UnmountAllDevices (DeviceObject, TRUE);

		return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);

	case IRP_MJ_FLUSH_BUFFERS:
	case IRP_MJ_READ:
	case IRP_MJ_WRITE:
	case IRP_MJ_DEVICE_CONTROL:
		if (Extension->bRootDevice == FALSE)
		{
			ASSERT (Extension->bShuttingDown == FALSE);

			IoMarkIrpPending (Irp);

			ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL ||
				KeGetCurrentIrql ()== APC_LEVEL);

			ExInterlockedInsertTailList (
						      &Extension->ListEntry,
					       &Irp->Tail.Overlay.ListEntry,
						  &Extension->ListSpinLock);

			ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL ||
				KeGetCurrentIrql ()== APC_LEVEL);

			KeReleaseSemaphore (
					       &Extension->RequestSemaphore,
						   (KPRIORITY) 0,
						   1,
						   FALSE);

			//Dump ("TCDispatchQueueIRP STATUS_PENDING END\n");
#ifdef USE_KERNEL_MUTEX
			if (Extension->bRootDevice == FALSE)
				KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
			return STATUS_PENDING;
		}
		else
		{
			if (irpSp->Parameters.DeviceIoControl.IoControlCode >= TC_FIRST_PRIVATE &&
			    irpSp->Parameters.DeviceIoControl.IoControlCode <= TC_LAST_PRIVATE)
			{
				ntStatus = TCDeviceControl (DeviceObject, Extension, Irp);
				//Dump ("TCDispatchQueueIRP NTSTATUS = 0x%08x END\n", ntStatus);
#ifdef USE_KERNEL_MUTEX
				if (Extension->bRootDevice == FALSE)
					KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
				return ntStatus;
			}

			if (irpSp->MajorFunction == IRP_MJ_FLUSH_BUFFERS)
			{
#ifdef USE_KERNEL_MUTEX
				if (Extension->bRootDevice == FALSE)
					KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
				return COMPLETE_IRP (DeviceObject, Irp, STATUS_SUCCESS, 0);
			}
		}

#ifdef USE_KERNEL_MUTEX
		if (Extension->bRootDevice == FALSE)
			KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif

		return COMPLETE_IRP (DeviceObject, Irp, STATUS_DRIVER_INTERNAL_ERROR, 0);
	}

#ifdef _DEBUG
	Dump ("ERROR: Unknown irpSp->MajorFunction in TCDispatchQueueIRP %ls 0x%08x END\n",
	TCTranslateCode (irpSp->MajorFunction), (int) irpSp->MajorFunction);
#endif

#ifdef USE_KERNEL_MUTEX
	if (Extension->bRootDevice == FALSE)
		KeReleaseMutex (&Extension->KernelMutex, FALSE);
#endif
	return COMPLETE_IRP (DeviceObject, Irp, STATUS_DRIVER_INTERNAL_ERROR, 0);
}

NTSTATUS
TCCreateRootDeviceObject (PDRIVER_OBJECT DriverObject)
{
	UNICODE_STRING Win32NameString, ntUnicodeString;
	WCHAR dosname[32], ntname[32];
	PDEVICE_OBJECT DeviceObject;
	NTSTATUS ntStatus;
	BOOL *bRootExtension;

	Dump ("TCCreateRootDeviceObject BEGIN\n");

	wcscpy (dosname, (LPWSTR) DOS_ROOT_PREFIX);
	wcscpy (ntname, (LPWSTR) NT_ROOT_PREFIX);
	RtlInitUnicodeString (&ntUnicodeString, ntname);
	RtlInitUnicodeString (&Win32NameString, dosname);

	Dump ("Creating root device nt=%ls dos=%ls\n", ntname, dosname);
	
	ntStatus = IoCreateDevice (
					  DriverObject,		/* Our Driver Object */
					  sizeof (BOOL),	/* Size of state information */
					  &ntUnicodeString,	/* Device name "\Device\Name" */
					  FILE_DEVICE_UNKNOWN, /* Device type */
					  0,				/* Device characteristics */
					  FALSE,			/* Exclusive device */
					  &DeviceObject);	/* Returned ptr to Device Object */

	if (!NT_SUCCESS (ntStatus))
	{
		Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
		return ntStatus;/* Failed to create DeviceObject */
	}

	DeviceObject->Flags |= DO_DIRECT_IO;
	DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;

	/* Setup the device extension */
	bRootExtension = (BOOL *) DeviceObject->DeviceExtension;
	*bRootExtension = TRUE;

	/* The symlinks for mount devices are created from user-mode */
	ntStatus = IoCreateSymbolicLink (&Win32NameString, &ntUnicodeString);

	if (!NT_SUCCESS (ntStatus))
	{
		Dump ("TCCreateRootDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
		IoDeleteDevice (DeviceObject);
		return ntStatus;
	}

	IoRegisterShutdownNotification (DeviceObject);

	ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
	Dump ("TCCreateRootDeviceObject STATUS_SUCCESS END\n");
	return STATUS_SUCCESS;
}

NTSTATUS
TCCreateDeviceObject (PDRIVER_OBJECT DriverObject,
		       PDEVICE_OBJECT * ppDeviceObject,
		       MOUNT_STRUCT * mount)
{
	UNICODE_STRING Win32NameString, ntUnicodeString;
	WCHAR dosname[32], ntname[32];
	PEXTENSION Extension;
	NTSTATUS ntStatus;
	ULONG devChars = 0;

	Dump ("TCCreateDeviceObject BEGIN\n");

	TCGetDosNameFromNumber (dosname, mount->nDosDriveNo);
	TCGetNTNameFromNumber (ntname, mount->nDosDriveNo);
	RtlInitUnicodeString (&ntUnicodeString, ntname);
	RtlInitUnicodeString (&Win32NameString, dosname);

	devChars = mount->bMountReadOnly ? FILE_READ_ONLY_DEVICE : 0;
	devChars |= mount->bMountRemovable ? FILE_REMOVABLE_MEDIA : 0;

	Dump ("Creating device nt=%ls dos=%ls\n", ntname, dosname);

	ntStatus = IoCreateDevice (
					  DriverObject,			/* Our Driver Object */
					  sizeof (EXTENSION),	/* Size of state information */
					  &ntUnicodeString,		/* Device name "\Device\Name" */
					  FILE_DEVICE_DISK,		/* Device type */
					  devChars,				/* Device characteristics */
					  FALSE,				/* Exclusive device */
					  ppDeviceObject);		/* Returned ptr to Device Object */

	if (!NT_SUCCESS (ntStatus))
	{
		Dump ("TCCreateDeviceObject NTSTATUS = 0x%08x END\n", ntStatus);
		return ntStatus;/* Failed to create DeviceObject */
	}
	/* Initialize device object and extension. */

	(*ppDeviceObject)->Flags |= DO_DIRECT_IO;
	(*ppDeviceObject)->AlignmentRequirement = FILE_WORD_ALIGNMENT;

	/* Setup the device extension */
	Extension = (PEXTENSION) (*ppDeviceObject)->DeviceExtension;
	memset (Extension, 0, sizeof (EXTENSION));

	Extension->lMagicNumber = 0xabfeacde;
	Extension->nDosDriveNo = mount->nDosDriveNo;
	Extension->bRemovable = mount->bMountRemovable;

	KeInitializeEvent (&Extension->keCreateEvent, SynchronizationEvent, FALSE);
	KeInitializeSemaphore (&Extension->RequestSemaphore, 0L, MAXLONG);
#ifdef USE_KERNEL_MUTEX
	KeInitializeMutex (&Extension->KernelMutex, 1);
#endif
	KeInitializeSpinLock (&Extension->ListSpinLock);
	InitializeListHead (&Extension->ListEntry);

	ASSERT (KeGetCurrentIrql ()== PASSIVE_LEVEL);
	Dump ("TCCreateDeviceObject STATUS_SUCCESS END\n");

	return STATUS_SUCCESS;
}


void DriverMutexWait ()
{
	KeWaitForMutexObject (&driverMutex, Executive, KernelMode, FALSE, NULL);
}


void DriverMutexRelease ()
{
	KeReleaseMutex (&driverMutex, FALSE);
}


/* TCDeviceControl handles certain requests from NT, these are needed for NT
   to recognize the drive, also this function handles our device specific
   function codes, such as mount/unmount */
NTSTATUS
TCDeviceControl (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp)
{
	PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp);
	NTSTATUS ntStatus;

#ifdef _DEBUG
	 Dump ("TCDeviceControl BEGIN IoControlCode = %ls 0x%08x\n",
	 TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode),
	      irpSp->Parameters.DeviceIoControl.IoControlCode);
#endif

	Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;	/* Assume failure. */

	/* Determine which I/O control code was specified.  */
	switch (irpSp->Parameters.DeviceIoControl.IoControlCode)
	{

	case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -