📄 cpgpdiskimpdrvnt.cpp
字号:
// Return drive geometry.
if (irp.IoctlOutputBufferLength() < sizeof(DISK_GEOMETRY))
error.err = STATUS_INVALID_PARAMETER;
if (error.IsntError())
{
PDISK_GEOMETRY pGeom = static_cast<PDISK_GEOMETRY>(
irp.IoctlInputBuffer());
pgpAssertAddrValid(pGeom, DISK_GEOMETRY);
CalcNTFakeGeometry(pGeom);
error.err = STATUS_SUCCESS;
irp.Information() = sizeof(DISK_GEOMETRY);
}
break;
case IOCTL_DISK_GET_DRIVE_LAYOUT:
// Return drive geometry.
if (irp.IoctlOutputBufferLength() < sizeof(DRIVE_LAYOUT_INFORMATION))
error.err = STATUS_INVALID_PARAMETER;
if (error.IsntError())
{
PDRIVE_LAYOUT_INFORMATION pDLI =
static_cast<PDRIVE_LAYOUT_INFORMATION>(
irp.IoctlInputBuffer());
pgpAssertAddrValid(pDLI, DRIVE_LAYOUT_INFORMATION);
CalcNTFakeDriveLayout(pDLI);
error.err = STATUS_SUCCESS;
irp.Information() = sizeof(DRIVE_LAYOUT_INFORMATION);
}
break;
case IOCTL_DISK_GET_PARTITION_INFO:
// Return information about the partition.
if (irp.IoctlOutputBufferLength() < sizeof(PARTITION_INFORMATION))
error.err = STATUS_INVALID_PARAMETER;
if (error.IsntError())
{
PPARTITION_INFORMATION pPartInfo =
(PPARTITION_INFORMATION) irp.IoctlInputBuffer();
pgpAssertAddrValid(pPartInfo, PARTITION_INFORMATION);
CalcNTFakePartitionInfo(pPartInfo);
error.err = STATUS_SUCCESS;
irp.Information() = sizeof(PARTITION_INFORMATION);
}
break;
case IOCTL_DISK_CHECK_VERIFY:
case IOCTL_STORAGE_CHECK_VERIFY:
// Do we have optional media change buffer?
if (irp.IoctlOutputBufferLength() > 0)
{
if (irp.IoctlOutputBufferLength() < sizeof(ULONG))
error.err = STATUS_INFO_LENGTH_MISMATCH;
if (error.IsntError())
{
ULONG *pChange = static_cast<ULONG *>(
irp.IoctlInputBuffer());
*pChange = 0;
irp.Information() = sizeof(ULONG);
}
}
if (error.IsntError())
error.err = STATUS_SUCCESS;
break;
case IOCTL_DISK_VERIFY:
// Verify disk extent.
if (irp.IoctlInputBufferLength() < sizeof(VERIFY_INFORMATION))
error.err = STATUS_INVALID_PARAMETER;
if (error.IsntError())
{
PVERIFY_INFORMATION pVI = static_cast<PVERIFY_INFORMATION>(
irp.IoctlInputBuffer());
pgpAssertAddrValid(pVI, PVERIFY_INFORMATION);
// Do freak-all...
error.err = STATUS_SUCCESS;
irp.Information() = pVI->Length;
}
break;
#if (_WIN32_WINNT >= 0x0500)
// Added by WJB for Windows XP
// IOCTL_DISK_GET_LENGTH_INFO must be defined for mounting on XP
case IOCTL_DISK_GET_LENGTH_INFO:
{
PGET_LENGTH_INFORMATION lengthInfo;
if (irp.IoctlOutputBufferLength() < sizeof(GET_LENGTH_INFORMATION))
error.err = STATUS_INVALID_PARAMETER;
if (error.IsntError())
{
lengthInfo = (PGET_LENGTH_INFORMATION)irp.IoctlInputBuffer();
lengthInfo->Length.QuadPart = TotalBlocks() * kPGPdiskBlockSize;
irp.Information() = sizeof(GET_LENGTH_INFORMATION);
error.err = STATUS_SUCCESS;
}
break;
}
/*
// The rest of these IOCTLs are not implemented but code is left for reference
case IOCTL_DISK_GET_PARTITION_INFO_EX:
{
if (irp.IoctlOutputBufferLength() < sizeof(PARTITION_INFORMATION_EX))
error.err = STATUS_INVALID_PARAMETER;
if (error.IsntError())
{
PPARTITION_INFORMATION_EX pPartInfo =
(PPARTITION_INFORMATION_EX) irp.IoctlInputBuffer();
// pgpAssertAddrValid(pPartInfo, PARTITION_INFORMATION_EX);
pPartInfo->PartitionStyle = PARTITION_STYLE_MBR;
pPartInfo->StartingOffset.QuadPart = kPGPdiskBlockSize;
pPartInfo->PartitionLength.QuadPart = TotalBlocks() * kPGPdiskBlockSize;
pPartInfo->PartitionNumber = 1;
pPartInfo->RewritePartition = FALSE;
pPartInfo->Mbr.PartitionType = PARTITION_ENTRY_UNUSED; // like I know
pPartInfo->Mbr.BootIndicator = FALSE;
pPartInfo->Mbr.RecognizedPartition = TRUE;
pPartInfo->Mbr.HiddenSectors = 0;
error.err = STATUS_SUCCESS;
irp.Information() = sizeof(PARTITION_INFORMATION_EX);
}
break;
}
case IOCTL_STORAGE_GET_HOTPLUG_INFO:
{
if (irp.IoctlOutputBufferLength() < sizeof(STORAGE_HOTPLUG_INFO))
error.err = STATUS_INVALID_PARAMETER;
if (error.IsntError())
{
PSTORAGE_HOTPLUG_INFO pPartInfo =
(PSTORAGE_HOTPLUG_INFO) irp.IoctlInputBuffer();
// pgpAssertAddrValid(pPartInfo, PARTITION_INFORMATION_EX);
pPartInfo->Size=sizeof(STORAGE_HOTPLUG_INFO);
pPartInfo->MediaRemovable=FALSE; // ie. zip, jaz, cdrom, mo, etc. vs hdd
pPartInfo->MediaHotplug=FALSE; // ie. does the device succeed a lock even though its not lockable media?
pPartInfo->DeviceHotplug=FALSE; // ie. 1394, USB, etc.
pPartInfo->WriteCacheEnableOverride=FALSE; // This field should not be relied upon because it is no longer used
error.err = STATUS_SUCCESS;
irp.Information() = sizeof(STORAGE_HOTPLUG_INFO);
}
break;
}
case FT_BALANCED_READ_MODE:
{
error.err = STATUS_INVALID_PARAMETER;
irp.Information() = 0;
break;
}
case IOCTL_VOLUME_GET_GPT_ATTRIBUTES:
{
if (irp.IoctlOutputBufferLength() < sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION))
error.err = STATUS_INVALID_PARAMETER;
if (error.IsntError())
{
PVOLUME_GET_GPT_ATTRIBUTES_INFORMATION pPartInfo =
(PVOLUME_GET_GPT_ATTRIBUTES_INFORMATION) irp.IoctlInputBuffer();
// pgpAssertAddrValid(pPartInfo, PARTITION_INFORMATION_EX);
pPartInfo->GptAttributes=0;
error.err = STATUS_SUCCESS;
irp.Information() = sizeof(VOLUME_GET_GPT_ATTRIBUTES_INFORMATION);
}
break;
}
case IOCTL_VOLUME_ONLINE:
{
error.err = STATUS_SUCCESS;
irp.Information() = 0;
break;
}
case IOCTL_MOUNTDEV_QUERY_STABLE_GUID:
{
if (irp.IoctlOutputBufferLength() < sizeof(MOUNTDEV_STABLE_GUID))
error.err = STATUS_INVALID_PARAMETER;
irp.Information() = 0;
if (error.IsntError())
{
PMOUNTDEV_STABLE_GUID pPartInfo =
(PMOUNTDEV_STABLE_GUID) irp.IoctlInputBuffer();
// pgpAssertAddrValid(pPartInfo, PARTITION_INFORMATION_EX);
// pPartInfo->StableGuid=0;
error.err = STATUS_SUCCESS;
irp.Information() = sizeof(MOUNTDEV_STABLE_GUID);
}
break;
}
case IOCTL_STORAGE_GET_DEVICE_NUMBER:
{
if (irp.IoctlOutputBufferLength() < sizeof(STORAGE_DEVICE_NUMBER))
error.err = STATUS_INVALID_PARAMETER;
if (error.IsntError())
{
PSTORAGE_DEVICE_NUMBER pPartInfo =
(PSTORAGE_DEVICE_NUMBER) irp.IoctlInputBuffer();
// pgpAssertAddrValid(pPartInfo, PARTITION_INFORMATION_EX);
pPartInfo->DeviceType=FILE_DEVICE_UNKNOWN;
pPartInfo->DeviceNumber=0;
pPartInfo->PartitionNumber=1;
error.err = STATUS_SUCCESS;
irp.Information() = sizeof(STORAGE_DEVICE_NUMBER);
}
break;
}
*/
// end WJB for XP
case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
// Return PGPdisk device name.
if (irp.IoctlOutputBufferLength() < sizeof(MOUNTDEV_NAME))
error.err = STATUS_INVALID_PARAMETER;
if (error.IsntError())
{
CUnicodeString deviceName(DeviceName());
error = deviceName.Status();
if (error.IsntError())
error = deviceName.Prepend('\\');
if (error.IsntError())
error = deviceName.Prepend(DriverAPI::kPGPdiskDeviceDir);
if (error.IsntError())
error = deviceName.Prepend(kNTDevicePathPrefix);
if (error.IsntError())
{
PMOUNTDEV_NAME pMN = static_cast<PMOUNTDEV_NAME>(
irp.IoctlInputBuffer());
pMN->NameLength = deviceName.Length() * sizeof(WCHAR);
if (irp.IoctlOutputBufferLength() < pMN->NameLength +
sizeof(WCHAR))
{
error.err = STATUS_BUFFER_OVERFLOW;
irp.Information() = sizeof(MOUNTDEV_NAME);
}
if (error.IsntError())
{
pgpCopyMemory(deviceName.Get()->Buffer, pMN->Name,
pMN->NameLength);
error.err = STATUS_SUCCESS;
irp.Information() = sizeof(WCHAR) + pMN->NameLength;
}
}
}
break;
case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
// Return unique ID for the PGPdisk.
if (irp.IoctlOutputBufferLength() < sizeof(MOUNTDEV_UNIQUE_ID))
error.err = STATUS_INVALID_PARAMETER;
if (error.IsntError())
{
// Just use device name.
CUnicodeString deviceName(DeviceName());
error = deviceName.Status();
if (error.IsntError())
{
PMOUNTDEV_UNIQUE_ID pUI = static_cast<PMOUNTDEV_UNIQUE_ID>(
irp.IoctlInputBuffer());
pUI->UniqueIdLength = deviceName.Length() * sizeof(WCHAR);
if (irp.IoctlOutputBufferLength() <
(pUI->UniqueIdLength + sizeof(WCHAR)))
{
error.err = STATUS_BUFFER_OVERFLOW;
irp.Information() = sizeof(MOUNTDEV_UNIQUE_ID);
}
if (error.IsntError())
{
pgpCopyMemory(deviceName.Get()->Buffer, pUI->UniqueId,
pUI->UniqueIdLength);
error.err = STATUS_SUCCESS;
irp.Information() = sizeof(WCHAR) + pUI->UniqueIdLength;
}
}
}
break;
case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:
// Return link name for the PGPdisk.
if (irp.IoctlOutputBufferLength() <
sizeof(MOUNTDEV_SUGGESTED_LINK_NAME))
{
error.err = STATUS_INVALID_PARAMETER;
}
if (error.IsntError())
{
// Return the root specified.
CUnicodeString linkName(Root());
error = linkName.Status();
if (error.IsntError())
error = linkName.Prepend(kNTDosDevicesPrefix);
if (error.IsntError())
linkName.Resize(linkName.Length() - 1);
if (error.IsntError())
{
PMOUNTDEV_SUGGESTED_LINK_NAME pSugName = static_cast<
PMOUNTDEV_SUGGESTED_LINK_NAME>(irp.IoctlInputBuffer());
pSugName->UseOnlyIfThereAreNoOtherLinks = TRUE;
pSugName->NameLength = linkName.Length() * sizeof(WCHAR);
irp.Information() =
FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME, Name) +
pSugName->NameLength;
if (irp.IoctlOutputBufferLength() < irp.Information())
{
error.err = STATUS_BUFFER_OVERFLOW;
irp.Information() = sizeof(MOUNTDEV_SUGGESTED_LINK_NAME);
}
if (error.IsntError())
{
pgpCopyMemory(linkName.Get()->Buffer, pSugName->Name,
pSugName->NameLength);
error.err = STATUS_SUCCESS;
// Information set from above.
}
}
}
break;
case IOCTL_MOUNTDEV_LINK_CREATED:
// Store information about volume ID/link name.
if (irp.IoctlInputBufferLength() < sizeof(MOUNTDEV_NAME))
error.err = STATUS_INVALID_PARAMETER;
if (error.IsntError())
{
PMOUNTDEV_NAME pMN = static_cast<PMOUNTDEV_NAME>(
irp.IoctlInputBuffer());
UNICODE_STRING temp;
temp.Length = temp.MaximumLength = pMN->NameLength;
temp.Buffer = pMN->Name;
CUnicodeString link(temp);
error = link.Status();
if (error.IsntError())
{
if ((link[4] == 'V') && (link[5] == 'o') &&
(link[6] == 'l'))
{
// It's a volume ID.
CDriverSubsystemsDrvNT::DeviceCache().SetEntryVolId(
DeviceName(), link);
}
else
{
// It's a drive letter.
CDriverSubsystemsDrvNT::DeviceCache().SetEntryCurLink(
DeviceName(), link);
}
}
error.err = STATUS_SUCCESS;
}
break;
case IOCTL_MOUNTDEV_LINK_DELETED:
// Delete information about link name.
if (irp.IoctlInputBufferLength() < sizeof(MOUNTDEV_NAME))
error.err = STATUS_INVALID_PARAMETER;
if (error.IsntError())
{
CUnicodeString empty;
error = empty.Status();
CDriverSubsystemsDrvNT::DeviceCache().SetEntryCurLink(
DeviceName(), empty);
error.err = STATUS_SUCCESS;
}
break;
#endif // _WIN32_WINNT >= 0x5000
default:
error.err = STATUS_INVALID_DEVICE_REQUEST;
break;
}
return error.err;
}
PGPUInt32
CPGPdiskImpDrvNT::ProcessExternalIo(
void *ioPacket,
PGPBoolean& wasCompleted)
{
// This is going to be an IRP.
CComboError error;
CIrp irp(static_cast<PIRP>(ioPacket));
PGPUInt8 majorFunc = irp.MajorFunction();
PGPUInt32 irpAddress = reinterpret_cast<PGPUInt32>(ioPacket);
UDebug::DebugOut("PGPdisk: Seeing an %s address %X.",
UConstantNamesDrvNT::NameIrpMajorFunction(majorFunc), irpAddress);
irp.Information() = 0;
switch (majorFunc)
{
case IRP_MJ_CLOSE:
case IRP_MJ_CREATE:
case IRP_MJ_FLUSH_BUFFERS:
case IRP_MJ_SHUTDOWN:
error.err = STATUS_SUCCESS;
break;
case IRP_MJ_DEVICE_CONTROL:
// Don't queue device controls.
error.err = ProcessExtIrpMjDeviceControl(irp);
break;
case IRP_MJ_READ:
case IRP_MJ_WRITE:
// Queue the IRP to the thread.
irp.MarkPending();
error = QueueIrpToIoThread(irp);
if (error.IsntError())
{
error.err = STATUS_PENDING;
}
else
{
error.err = STATUS_INSUFFICIENT_RESOURCES;
irp.UnmarkPending();
}
break;
default:
error.err = STATUS_NOT_IMPLEMENTED;
break;
}
// Complete if not pending.
if (error.err == STATUS_PENDING)
{
UDebug::DebugOut("PGPdisk: Scheduled an %s address %X.",
UConstantNamesDrvNT::NameIrpMajorFunction(majorFunc),
irpAddress);
}
else
{
irp.Complete(error.err);
wasCompleted = TRUE;
UDebug::DebugOut("PGPdisk: Completed an %s address %X status "
"%X.", UConstantNamesDrvNT::NameIrpMajorFunction(majorFunc),
irpAddress, static_cast<PGPUInt32>(error.err));
}
return error.err;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -