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

📄 ntdriver.c

📁 一个提供档案及Partition作加解密的程式支援以下的加密演算法AESBlowfishCAST5SerpentTriple DESTwofishAES-BlowfishAES-TwofishAES-
💻 C
📖 第 1 页 / 共 4 页
字号:
	NTSTATUS ntStatus;

	Dump ("TCDeleteDeviceObject BEGIN\n");

	if (Extension->bRootDevice == TRUE)
	{
		RtlInitUnicodeString (&Win32NameString, (LPWSTR) DOS_ROOT_PREFIX);
		ntStatus = IoDeleteSymbolicLink (&Win32NameString);
		if (!NT_SUCCESS (ntStatus))
			Dump ("IoDeleteSymbolicLink failed ntStatus = 0x%08x\n", ntStatus);
	}
	else
	{
		if (Extension->peThread != NULL)
			TCStopThread (DeviceObject, Extension);
	}

	DeviceObject = DeviceObject->NextDevice;
	IoDeleteDevice (OldDeviceObject);

	Dump ("TCDeleteDeviceObject END\n");
	return DeviceObject;
}


VOID
TCUnloadDriver (PDRIVER_OBJECT DriverObject)
{
	PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;

	Dump ("TCUnloadDriver BEGIN\n");

	UnmountAllDevices (DeviceObject, TRUE);

	/* Now walk the list of driver objects and get rid of them */
	while (DeviceObject != (PDEVICE_OBJECT) NULL)
	{
		DeviceObject = TCDeleteDeviceObject (DeviceObject,
				(PEXTENSION) DeviceObject->DeviceExtension);
	}

	Dump ("TCUnloadDriver END\n");
}


NTSTATUS
TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode,
				   void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
{
	IO_STATUS_BLOCK ioStatusBlock;
	NTSTATUS ntStatus;
	PIRP irp;
	PFILE_OBJECT fileObject;
	PDEVICE_OBJECT deviceObject;
	KEVENT event;
	UNICODE_STRING name;

	RtlInitUnicodeString(&name, deviceName);
    ntStatus = IoGetDeviceObjectPointer(&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject);

	if (ntStatus != STATUS_SUCCESS)
		return ntStatus;

	KeInitializeEvent(&event, NotificationEvent, FALSE);

	irp = IoBuildDeviceIoControlRequest (IoControlCode,
					     deviceObject,
					     InputBuffer, InputBufferSize,
					     OutputBuffer, OutputBufferSize,
					     FALSE,
					     &event,
					     &ioStatusBlock);

	if (irp == NULL)
	{
		Dump ("IRP allocation failed\n");
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	ntStatus = IoCallDriver (deviceObject, irp);
	if (ntStatus == STATUS_PENDING)
	{
		KeWaitForSingleObject (&event, UserRequest, UserMode, FALSE, NULL);
		ntStatus = ioStatusBlock.Status;
	}

	return ntStatus;
}


// Opens a mounted TC volume on filesystem level
NTSTATUS
TCOpenFsVolume (PEXTENSION Extension, PHANDLE volumeHandle, PFILE_OBJECT * fileObject)
{
	NTSTATUS ntStatus;
	OBJECT_ATTRIBUTES objectAttributes;
	UNICODE_STRING fullFileName;
	IO_STATUS_BLOCK ioStatus;
	WCHAR volumeName[64];

	TCGetDosNameFromNumber (volumeName, Extension->nDosDriveNo);
	RtlInitUnicodeString (&fullFileName, volumeName);
	InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);

	ntStatus = ZwCreateFile (volumeHandle,
		SYNCHRONIZE | GENERIC_READ,
		&objectAttributes,
		&ioStatus,
		NULL,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		FILE_OPEN,
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,
		0);

	Dump ("Volume %ls open NTSTATUS 0x%08x\n", volumeName, ntStatus);

	if (!NT_SUCCESS (ntStatus))
		return ntStatus;

	ntStatus = ObReferenceObjectByHandle (*volumeHandle,
		FILE_READ_DATA,
		NULL,
		KernelMode,
		fileObject,
		NULL);

	Dump ("ObReferenceObjectByHandle NTSTATUS 0x%08x\n", ntStatus);

	if (!NT_SUCCESS (ntStatus))
	{
		ZwClose(*volumeHandle);
		return ntStatus;
	}

	return ntStatus;
}


void
TCCloseFsVolume (HANDLE volumeHandle, PFILE_OBJECT fileObject)
{
	ObDereferenceObject (fileObject);
	ZwClose (volumeHandle);
}


NTSTATUS
TCFsctlCall (PFILE_OBJECT fileObject, LONG IoControlCode,
	void *InputBuffer, int InputBufferSize, void *OutputBuffer, int OutputBufferSize)
{
	IO_STATUS_BLOCK ioStatusBlock;
	NTSTATUS ntStatus;
	PIRP irp;
	KEVENT event;
	PIO_STACK_LOCATION stack;
	PDEVICE_OBJECT deviceObject = IoGetRelatedDeviceObject (fileObject);

	Dump ("IoGetRelatedDeviceObject = 0x%08x\n", deviceObject);

	KeInitializeEvent(&event, NotificationEvent, FALSE);

	irp = IoBuildDeviceIoControlRequest (IoControlCode,
					     deviceObject,
					     InputBuffer, InputBufferSize,
					     OutputBuffer, OutputBufferSize,
					     FALSE,
					     &event,
					     &ioStatusBlock);

	if (irp == NULL)
	{
		Dump ("IRP allocation failed\n");
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	stack = IoGetNextIrpStackLocation(irp);
	
	stack->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
	stack->MinorFunction = IRP_MN_USER_FS_REQUEST;
	stack->FileObject = fileObject;

	Dump("TCFsctlCall IoCallDriver\n");

	ntStatus = IoCallDriver (deviceObject, irp);
	if (ntStatus == STATUS_PENDING)
	{
		KeWaitForSingleObject (&event, UserRequest, UserMode, FALSE, NULL);
		ntStatus = ioStatusBlock.Status;
	}

	return ntStatus;
}


NTSTATUS
CreateDriveLink (int nDosDriveNo)
{
	WCHAR dev[64], link[64];
	UNICODE_STRING deviceName, symLink;
	NTSTATUS ntStatus;

	TCGetNTNameFromNumber (dev, nDosDriveNo);
	TCGetDosNameFromNumber (link, nDosDriveNo);

	RtlInitUnicodeString (&deviceName, dev);
	RtlInitUnicodeString (&symLink, link);

	ntStatus = IoCreateSymbolicLink (&symLink, &deviceName);
	Dump ("IoCreateSymbolicLink returned %X\n", ntStatus);
	return ntStatus;
}


NTSTATUS
RemoveDriveLink (int nDosDriveNo)
{
	WCHAR link[64];
	UNICODE_STRING symLink;
	NTSTATUS ntStatus;

	TCGetDosNameFromNumber (link, nDosDriveNo);
	RtlInitUnicodeString (&symLink, link);

	ntStatus = IoDeleteSymbolicLink (&symLink);
	Dump ("IoDeleteSymbolicLink returned %X\n", ntStatus);
	return ntStatus;
}


NTSTATUS
MountManagerMount (MOUNT_STRUCT *mount)
{
	NTSTATUS ntStatus; 
	WCHAR arrVolume[64];
	char buf[200];
	PMOUNTMGR_TARGET_NAME in = (PMOUNTMGR_TARGET_NAME) buf;
	PMOUNTMGR_CREATE_POINT_INPUT point = (PMOUNTMGR_CREATE_POINT_INPUT) buf;
	UNICODE_STRING symName, devName;

	TCGetNTNameFromNumber (arrVolume, mount->nDosDriveNo);
	in->DeviceNameLength = (USHORT) wcslen (arrVolume) * 2;
	wcscpy(in->DeviceName, arrVolume);

	ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
		in, sizeof (in->DeviceNameLength) + wcslen (arrVolume) * 2, 0, 0);

	memset (buf, 0, sizeof buf);
	TCGetDosNameFromNumber ((PWSTR) &point[1], mount->nDosDriveNo);

	point->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT);
	point->SymbolicLinkNameLength = (USHORT) wcslen ((PWSTR) &point[1]) * 2;

	RtlInitUnicodeString(&symName, (PWSTR) (buf + point->SymbolicLinkNameOffset));

	point->DeviceNameOffset = point->SymbolicLinkNameOffset + point->SymbolicLinkNameLength;
	TCGetNTNameFromNumber ((PWSTR) (buf + point->DeviceNameOffset), mount->nDosDriveNo);
	point->DeviceNameLength = (USHORT) wcslen ((PWSTR) (buf + point->DeviceNameOffset)) * 2;

	RtlInitUnicodeString(&devName, (PWSTR) (buf + point->DeviceNameOffset));

	ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_CREATE_POINT, point,
		point->DeviceNameOffset + point->DeviceNameLength, 0, 0);

	return ntStatus;
}


NTSTATUS
MountManagerUnmount (int nDosDriveNo)
{
	NTSTATUS ntStatus; 
	WCHAR drive[] = {(WCHAR) nDosDriveNo + 'A', 0};
	char buf[64], out[300];
	PMOUNTMGR_MOUNT_POINT in = (PMOUNTMGR_MOUNT_POINT) buf;

	memset (buf, 0, sizeof buf);

	TCGetDosNameFromNumber ((PWSTR) &in[1], nDosDriveNo);

	in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT);
	in->SymbolicLinkNameLength = (USHORT) wcslen ((PWCHAR) &in[1]) * 2;

	ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_DELETE_POINTS,
		in, sizeof(MOUNTMGR_MOUNT_POINT) + in->SymbolicLinkNameLength, out, sizeof out);

	Dump ("IOCTL_MOUNTMGR_DELETE_POINTS returned 0x%08x\n", ntStatus);

	return ntStatus;
}


NTSTATUS
MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount)
{
	PDEVICE_OBJECT NewDeviceObject;
	NTSTATUS ntStatus;

	/* 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");
		return ERR_BAD_DRIVE_LETTER;
	}

	ntStatus = TCCreateDeviceObject (DeviceObject->DriverObject, &NewDeviceObject,
		mount);
	if (!NT_SUCCESS (ntStatus))
	{
		Dump ("Mount CREATE DEVICE ERROR, ntStatus = 0x%08x\n", ntStatus);
		return ntStatus;
	}
	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);
			TCDeleteDeviceObject (NewDeviceObject, NewExtension);
			return ntStatus;
		}
		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;

				if (mount->bMountManager)
					MountManagerMount (mount);

				NewExtension->bMountManager = mount->bMountManager;

				// We create symbolic link even if mount manager is notified of
				// arriving volume as it apparently sometimes fails to create the link
				CreateDriveLink (mount->nDosDriveNo);
			}
			else
			{
				Dump ("Mount FAILURE TC code = 0x%08x\n", mount->nReturnCode);
				TCDeleteDeviceObject (NewDeviceObject, NewExtension);
			}
			
			return STATUS_SUCCESS;
		}
	}
}

NTSTATUS
UnmountDevice (PDEVICE_OBJECT deviceObject, BOOL ignoreOpenFiles)
{
	PEXTENSION extension = deviceObject->DeviceExtension;
	NTSTATUS ntStatus;
	HANDLE volumeHandle;
	PFILE_OBJECT volumeFileObject;

	ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject);

	if (!NT_SUCCESS (ntStatus))
	{
		// User may have deleted symbolic link
		CreateDriveLink (extension->nDosDriveNo);

		ntStatus = TCOpenFsVolume (extension, &volumeHandle, &volumeFileObject);

		if (!NT_SUCCESS (ntStatus))
			return ntStatus;
	}

	// Lock volume
	ntStatus = TCFsctlCall (volumeFileObject, FSCTL_LOCK_VOLUME, 0, 0, 0, 0);
	Dump ("FSCTL_LOCK_VOLUME returned %X\n", ntStatus);

	if (!NT_SUCCESS (ntStatus) && !ignoreOpenFiles)
	{
		TCCloseFsVolume (volumeHandle, volumeFileObject);
		return ERR_FILES_OPEN;
	}

	// Dismount volume
	ntStatus = TCFsctlCall (volumeFileObject, FSCTL_DISMOUNT_VOLUME, 0, 0, 0, 0);
	Dump ("FSCTL_DISMOUNT_VOLUME returned %X\n", ntStatus);

	extension->bShuttingDown = TRUE;
	if (deviceObject->Vpb && deviceObject->Vpb->Flags & VPB_MOUNTED)
	{
		deviceObject->Flags |= DO_VERIFY_VOLUME;
	}

	if (extension->bMountManager)
		MountManagerUnmount (extension->nDosDriveNo);
	
	// We always remove symbolic link as mount manager might fail to do so
	RemoveDriveLink (extension->nDosDriveNo);

	TCCloseFsVolume (volumeHandle, volumeFileObject);

	Dump ("Deleting DeviceObject with ref count %ld\n", deviceObject->ReferenceCount);
	deviceObject->ReferenceCount = 0;
	TCDeleteDeviceObject (deviceObject, (PEXTENSION) deviceObject->DeviceExtension);

	return 0;
}

NTSTATUS
UnmountAllDevices (PDEVICE_OBJECT DeviceObject, BOOL ignoreOpenFiles)
{
	NTSTATUS status = 0;
	PDEVICE_OBJECT ListDevice;

	Dump ("Unmounting all volumes\n");

	DriverMutexWait ();

	for (ListDevice = DeviceObject->DriverObject->DeviceObject;
		ListDevice != (PDEVICE_OBJECT) NULL;
		ListDevice = ListDevice->NextDevice)
	{
		PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension;
		if (ListExtension->bRootDevice == FALSE && !ListExtension->bShuttingDown)
		{
			NTSTATUS ntStatus = UnmountDevice (ListDevice, ignoreOpenFiles);
			status = ntStatus == 0 ? status : ntStatus;
		}
	}

	DriverMutexRelease ();

	return status;
}

// Resolves symbolic link name to its target name
NTSTATUS
SymbolicLinkToTarget (PWSTR symlinkName, PWSTR targetName, USHORT maxTargetNameLength)
{
	NTSTATUS ntStatus;
	OBJECT_ATTRIBUTES objectAttributes;
	UNICODE_STRING fullFileName;
	HANDLE handle;

	RtlInitUnicodeString (&fullFileName, symlinkName);
	InitializeObjectAttributes (&objectAttributes, &fullFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);

	ntStatus = ZwOpenSymbolicLinkObject (&handle, GENERIC_READ, &objectAttributes);

	if (NT_SUCCESS (ntStatus))
	{
		UNICODE_STRING target;
		target.Buffer = targetName;
		target.Length = 0;
		target.MaximumLength = maxTargetNameLength;
		memset (targetName, 0, maxTargetNameLength);

		ntStatus = ZwQuerySymbolicLinkObject (handle, &target, NULL);

		ZwClose (handle);
	}

	return ntStatus;
}

⌨️ 快捷键说明

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