📄 ntdriver.c
字号:
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 + -