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

📄 ntdriver.c

📁 加密硬盘、分区、虚拟盘的程序源码
💻 C
📖 第 1 页 / 共 3 页
字号:
				Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;

				break;
			}

			RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);

			Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = outLength;

			Dump ("name = %ls\n",ntName);
		}
		break;

	case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
		if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNTDEV_UNIQUE_ID))
		{
			Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID);
			Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
		}
		else
		{
			ULONG outLength;
			UCHAR volId[128], tmp[] = { 0,0 };
			PMOUNTDEV_UNIQUE_ID outputBuffer = (PMOUNTDEV_UNIQUE_ID) Irp->AssociatedIrp.SystemBuffer;

			Dump("IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:");

			strcpy (volId, TC_UNIQUE_ID_PREFIX); 
			tmp[0] = 'A' + Extension->nDosDriveNo;
			strcat (volId, tmp);
			
			outputBuffer->UniqueIdLength = (USHORT) strlen(volId);
			outLength = strlen(volId) + sizeof(USHORT);

			if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
			{
				Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID);
				Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
				break;
			}

			RtlCopyMemory ((PCHAR)outputBuffer->UniqueId, volId, strlen(volId));

			Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = outLength;

			Dump ("id = %s\n",volId);
		}
		break;

		case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:
		{
			ULONG outLength;
			UNICODE_STRING ntUnicodeString;
			WCHAR ntName[64];
			PMOUNTDEV_SUGGESTED_LINK_NAME outputBuffer = (PMOUNTDEV_SUGGESTED_LINK_NAME) Irp->AssociatedIrp.SystemBuffer;
			
			Dump("IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:");

			TCGetDosNameFromNumber (ntName, Extension->nDosDriveNo);
			RtlInitUnicodeString (&ntUnicodeString, ntName);

			outLength = FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME,Name) + ntUnicodeString.Length;

			outputBuffer->UseOnlyIfThereAreNoOtherLinks = FALSE;
			outputBuffer->NameLength = ntUnicodeString.Length;

			if(irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength)
			{
				Irp->IoStatus.Information = sizeof (MOUNTDEV_SUGGESTED_LINK_NAME);
				Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
				break;
			}

			RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length);
		
			Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = outLength;

			Dump ("link = %ls\n",ntName);
		}
		break;

	case IOCTL_DISK_GET_MEDIA_TYPES:
	case IOCTL_DISK_GET_DRIVE_GEOMETRY:
		/* Return the drive geometry for the disk.  Note that we
		   return values which were made up to suit the disk size.  */
		if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
		    sizeof (DISK_GEOMETRY))
		{
			Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
			Irp->IoStatus.Information = 0;
		}
		else
		{
			PDISK_GEOMETRY outputBuffer = (PDISK_GEOMETRY)
			Irp->AssociatedIrp.SystemBuffer;

			outputBuffer->MediaType = FixedMedia;
			outputBuffer->Cylinders.QuadPart = Extension->NumberOfCylinders;
			outputBuffer->TracksPerCylinder = Extension->TracksPerCylinder;
			outputBuffer->SectorsPerTrack = Extension->SectorsPerTrack;
			outputBuffer->BytesPerSector = Extension->BytesPerSector;
			Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = sizeof (DISK_GEOMETRY);
		}
		break;

	case IOCTL_DISK_GET_PARTITION_INFO:
		if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
		    sizeof (PARTITION_INFORMATION))
		{
			Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
			Irp->IoStatus.Information = 0;
		}
		else
		{
			PPARTITION_INFORMATION outputBuffer = (PPARTITION_INFORMATION)
			Irp->AssociatedIrp.SystemBuffer;

			outputBuffer->PartitionType = Extension->PartitionType;
			outputBuffer->BootIndicator = FALSE;
			outputBuffer->RecognizedPartition = TRUE;
			outputBuffer->RewritePartition = FALSE;
			outputBuffer->StartingOffset = RtlConvertUlongToLargeInteger (0);
			outputBuffer->PartitionLength.QuadPart= Extension->DiskLength;
			outputBuffer->HiddenSectors = 1L;
			Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION);
		}
		break;
	
	case IOCTL_DISK_GET_LENGTH_INFO:
		if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GET_LENGTH_INFORMATION))
		{
			Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
			Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION);
		}
		else
		{
			PGET_LENGTH_INFORMATION outputBuffer = (PGET_LENGTH_INFORMATION) Irp->AssociatedIrp.SystemBuffer;

			outputBuffer->Length.QuadPart = Extension->DiskLength;
			Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = sizeof (GET_LENGTH_INFORMATION);
		}
		break;

	case IOCTL_DISK_VERIFY:
		{
			PVERIFY_INFORMATION pVerifyInformation;
			pVerifyInformation = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
			irpSp->Parameters.Read.ByteOffset.LowPart =
				pVerifyInformation->StartingOffset.LowPart;
			irpSp->Parameters.Read.ByteOffset.HighPart =
				pVerifyInformation->StartingOffset.HighPart;
			irpSp->Parameters.Read.Length = pVerifyInformation->Length;
			Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = pVerifyInformation->Length;
		}
		break;

	case IOCTL_DISK_CHECK_VERIFY:
		{
			Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = 0;
		}
		break;

	case IOCTL_DISK_IS_WRITABLE:
		{
			if (Extension->bReadOnly == TRUE)
				Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED;
			else
				Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = 0;

		}
		break;

	case DRIVER_VERSION:
		if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < 4)
		{
			Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
			Irp->IoStatus.Information = 0;
		}
		else
		{
			LONG tmp = VERSION_NUM;
			memcpy (Irp->AssociatedIrp.SystemBuffer, &tmp, 4);
			Irp->IoStatus.Information = 4;
			Irp->IoStatus.Status = STATUS_SUCCESS;
		}
		break;

	case OPEN_TEST:
		if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (OPEN_TEST_STRUCT))
		{
			Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
			Irp->IoStatus.Information = 0;
		}
		else
		{
			OPEN_TEST_STRUCT *opentest = (OPEN_TEST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
			OBJECT_ATTRIBUTES ObjectAttributes;
			HANDLE NtFileHandle;
			UNICODE_STRING FullFileName;
			IO_STATUS_BLOCK IoStatus;

			RtlInitUnicodeString (&FullFileName, opentest->wszFileName);

			InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE,
						    NULL, NULL);

			ntStatus = ZwCreateFile (&NtFileHandle,
						 SYNCHRONIZE | GENERIC_READ, &ObjectAttributes, &IoStatus, NULL /* alloc size = none  */ ,
						 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT |
			FILE_NO_INTERMEDIATE_BUFFERING | FILE_RANDOM_ACCESS,
				  NULL /* eabuffer  */ , 0 /* ealength */ );

			if (NT_SUCCESS (ntStatus))
			{
				ZwClose (NtFileHandle);
				Dump ("Open test on file %ls success.\n", opentest->wszFileName);
			}
			else
			{
				Dump ("Open test on file %ls failed NTSTATUS 0x%08x\n", opentest->wszFileName, ntStatus);
			}

			Irp->IoStatus.Information = 0;
			Irp->IoStatus.Status = ntStatus;
		}
		break;

	case WIPE_CACHE:
		KeWaitForMutexObject (&driverMutex, Executive, KernelMode,
				      FALSE, NULL);

		WipeCache ();

		KeReleaseMutex (&driverMutex, FALSE);

		Irp->IoStatus.Status = STATUS_SUCCESS;
		Irp->IoStatus.Information = 0;
		break;

	case CACHE_STATUS:
		Irp->IoStatus.Status = cacheEmpty ? STATUS_PIPE_EMPTY : STATUS_SUCCESS;
		Irp->IoStatus.Information = 0;
		break;

#ifdef DEBUG
	case HALT_SYSTEM:
		KeBugCheck ((ULONG) 0x5050);
		break;
#endif

	case MOUNT_LIST:
		if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_LIST_STRUCT))
		{
			Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
			Irp->IoStatus.Information = 0;
		}
		else
		{
			MOUNT_LIST_STRUCT *list = (MOUNT_LIST_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
			PDEVICE_OBJECT ListDevice;

			list->ulMountedDrives = 0;
			for (ListDevice = DeviceObject->DriverObject->DeviceObject;
			     ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
			{

				PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
				if (ListExtension->bRootDevice == FALSE)
				{
					list->ulMountedDrives |= (1 << ListExtension->nDosDriveNo);
					wcscpy (list->wszVolume[ListExtension->nDosDriveNo], ListExtension->wszVolume);
					list->diskLength[ListExtension->nDosDriveNo] = ListExtension->DiskLength;
					list->cipher[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->cipher;
				}
			}

			Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = sizeof (MOUNT_LIST_STRUCT);
		}
		break;

	case VOLUME_PROPERTIES:
		if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (VOLUME_PROPERTIES_STRUCT))
		{
			Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
			Irp->IoStatus.Information = 0;
		}
		else
		{
			VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
			PDEVICE_OBJECT ListDevice;

			Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
			Irp->IoStatus.Information = 0;

			for (ListDevice = DeviceObject->DriverObject->DeviceObject;
			     ListDevice != (PDEVICE_OBJECT) NULL; ListDevice = ListDevice->NextDevice)
			{

				PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
				if (ListExtension->bRootDevice == FALSE && ListExtension->nDosDriveNo == prop->driveNo)
				{
					wcscpy (prop->wszVolume, ListExtension->wszVolume);
					prop->diskLength = ListExtension->DiskLength;
					prop->cipher = ListExtension->cryptoInfo->cipher;
					prop->pkcs5 = ListExtension->cryptoInfo->pkcs5;
					prop->pkcs5Iterations = ListExtension->cryptoInfo->noIterations;
					prop->volumeCreationTime = ListExtension->cryptoInfo->volume_creation_time;
					prop->headerCreationTime = ListExtension->cryptoInfo->header_creation_time;

					Irp->IoStatus.Status = STATUS_SUCCESS;
					Irp->IoStatus.Information = sizeof (VOLUME_PROPERTIES_STRUCT);
					break;
				}
			}
		}
		break;

	case UNMOUNT_PENDING:
		Extension->bShuttingDown = TRUE;
		Irp->IoStatus.Status = STATUS_NO_MEDIA_IN_DEVICE;
		Irp->IoStatus.Information = 0;
		if (DeviceObject->Vpb && DeviceObject->Vpb->Flags & VPB_MOUNTED)
		{
			IoSetHardErrorOrVerifyDevice (Irp, DeviceObject);
			DeviceObject->Flags |= DO_VERIFY_VOLUME;
		}
		break;

	case UNMOUNT:
		if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (UNMOUNT_STRUCT))
		{
			Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
			Irp->IoStatus.Information = 0;
		}
		else
		{
			UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
			PDEVICE_OBJECT ListDevice;

			unmount->nReturnCode = ERR_DRIVE_NOT_FOUND;

			for (ListDevice = DeviceObject->DriverObject->DeviceObject;
			     ListDevice != (PDEVICE_OBJECT) NULL;
			     ListDevice = ListDevice->NextDevice)
			{

				PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;

				if (ListExtension->bRootDevice == FALSE)
				{
					if (unmount->nDosDriveNo == ListExtension->nDosDriveNo)
					{
						if (ListDevice->Vpb && ListDevice->Vpb->ReferenceCount == 0 && (ListDevice->Vpb->Flags & VPB_MOUNTED) == 0)
						{
							Dump ("Deleting DeviceObject with ref count %ld\n", ListDevice->ReferenceCount);
							ListDevice->ReferenceCount = 0;
							TCDeleteDeviceObject (ListDevice, (PEXTENSION) ListDevice->DeviceExtension);
							unmount->nReturnCode = 0;
							break;
						}
						else
						{
							unmount->nReturnCode = ERR_FILES_OPEN;
							break;
						}
					}	/* if the drive numbers are
						   equal */
				}	/* if it's not the root device */
			}	/* for all the device objects the driver
				   knows about */

			Irp->IoStatus.Information = sizeof (unmount->nReturnCode);
			Irp->IoStatus.Status = STATUS_SUCCESS;
		}
		break;


	case MOUNT:
		if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof (MOUNT_STRUCT))
		{
			Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
			Irp->IoStatus.Information = 0;
		}
		else
		{
			MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer;
			ULONG *outputBuffer = (ULONG *) Irp->AssociatedIrp.SystemBuffer;
			PDEVICE_OBJECT NewDeviceObject;

			/* Make sure the user is asking for a resonable
			   nDosDriveNo */
			if (mount->nDosDriveNo >= 0 && mount->nDosDriveNo <= 25)
			{
				Dump ("Mount request looks valid\n");
			}
			else
			{
				Dump ("WARNING: MOUNT DRIVE LETTER INVALID\n");
				Irp->IoStatus.Information = sizeof (mount->nReturnCode);
				Irp->IoStatus.Status = STATUS_SUCCESS;
				mount->nReturnCode = ERR_BAD_DRIVE_LETTER;
				break;
			}

			ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject,
							mount->nDosDriveNo);
			if (!NT_SUCCESS (ntStatus))
			{
				Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus);
				Irp->IoStatus.Information = 0;
				Irp->IoStatus.Status = ntStatus;
				break;
			}
			else
			{
				PEXTENSION NewExtension = (PEXTENSION) NewDeviceObject->DeviceExtension;
				ntStatus = TCStartThread (NewDeviceObject, NewExtension, mount);
				if (!NT_SUCCESS (ntStatus))
				{
					Dump ("Mount FAILURE NT ERROR, ntStatus = 0x%08x\n", ntStatus);
					Irp->IoStatus.Information = 0;
					Irp->IoStatus.Status = ntStatus;
					TCDeleteDeviceObject (NewDeviceObject, NewExtension);
					break;
				}
				else
				{
					if (mount->nReturnCode == 0)
					{
						Dump ("Mount SUCCESS TC code = 0x%08x READ-ONLY = %d\n", mount->nReturnCode,
						   NewExtension->bReadOnly);
						if (NewExtension->bReadOnly == TRUE)
							NewDeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE;
						NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
					}
					else
					{
						Dump ("Mount FAILURE TC code = 0x%08x\n", mount->nReturnCode);
						TCDeleteDeviceObject (NewDeviceObject, NewExtension);
					}
					Irp->IoStatus.Information = sizeof (mount->nReturnCode);
					Irp->IoStatus.Status = STATUS_SUCCESS;
					break;
				}
			}
		}
		break;
	}

	/* Finish the I/O operation by simply completing the packet and

⌨️ 快捷键说明

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