📄 cvolumeimpdrvnt.cpp
字号:
IO_STATUS_BLOCK ioStatus;
LARGE_INTEGER bigPos;
bigPos.QuadPart = pos * BlockSize();
error.err = ZwWriteFile(mVolumeHandle, NULL, NULL, NULL, &ioStatus,
const_cast<void *>(buf), nBlocks * BlockSize(), &bigPos, NULL);
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_VolumeOpFailed;
return error;
}
CComboError
CVolumeImpDrvNT::MakeDeviceStrings(
const char *deviceName,
const char *linkName,
CUnicodeString& fullDevName,
CUnicodeString& fullLinkName) const
{
pgpAssertStrValid(deviceName);
pgpAssertStrValid(linkName);
CComboError error;
error = fullDevName.Status();
if (error.IsntError())
error = fullLinkName.Status();
if (error.IsntError())
error = fullDevName.Assign(deviceName);
if (error.IsntError())
error = fullDevName.Prepend('\\');
if (error.IsntError())
error = fullDevName.Prepend(DriverAPI::kPGPdiskDeviceDir);
if (error.IsntError())
error = fullDevName.Prepend(kNTDevicePathPrefix);
if (error.IsntError())
error = fullLinkName.Assign(linkName);
if (error.IsntError())
error = fullLinkName.Prepend(kNTDosDevicesPrefix);
if (error.IsntError())
{
if (strlen(linkName) == 3)
error = fullLinkName.Resize(fullLinkName.Length() - 1);
}
return error;
}
#if (_WIN32_WINNT >= 0x0500)
CComboError
CVolumeImpDrvNT::GetVolumeStrings(
const char *deviceName,
CUnicodeString& volId,
CUnicodeString& curLink) const
{
pgpAssertStrValid(deviceName);
CComboError error;
error = volId.Status();
if (error.IsntError())
error = curLink.Status();
if (error.IsntError())
{
error = CDriverSubsystemsDrvNT::DeviceCache().GetEntryCurLink(
deviceName, curLink);
}
if (error.IsntError())
{
error = CDriverSubsystemsDrvNT::DeviceCache().GetEntryVolId(
deviceName, volId);
}
if (error.IsntError())
error = volId.Append('\\');
return error;
}
CComboError
CVolumeImpDrvNT::OpenMountMgr()
{
pgpAssert(!mMountMgr.IsAttached());
CComboError error;
CUnicodeString mpDevName(kMountPointDeviceName);
error = mpDevName.Status();
if (error.IsntError())
error = mpDevName.Prepend(kNTDevicePathPrefix);
if (error.IsntError())
error = mMountMgr.Attach(mpDevName);
return error;
}
void
CVolumeImpDrvNT::CloseMountMgr()
{
pgpAssert(mMountMgr.IsAttached());
mMountMgr.Detach();
}
CComboError
CVolumeImpDrvNT::OpenMountPointDir(const CUnicodeString& fullDirName)
{
pgpAssert(!mDirDevice.IsAttached());
CComboError error;
IO_STATUS_BLOCK ioStatus;
OBJECT_ATTRIBUTES objAttribs;
InitializeObjectAttributes(&objAttribs, const_cast<UNICODE_STRING *>(
fullDirName.Get()), OBJ_CASE_INSENSITIVE, NULL, NULL);
error.err = ZwCreateFile(&mDirHandle, FILE_GENERIC_READ |
FILE_GENERIC_WRITE | SYNCHRONIZE, &objAttribs, &ioStatus, NULL,
FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN, FILE_OPEN_REPARSE_POINT | FILE_OPEN_FOR_BACKUP_INTENT |
FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_CantOpenFile;
// Get file object from this handle.
if (error.IsntError())
{
error.err = ObReferenceObjectByHandle(mDirHandle, FILE_READ_DATA,
NULL, KernelMode, reinterpret_cast<void **>(&mDirFileObject),
NULL);
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_NTDrvObjectOpFailed;
// Get device object from this file object.
if (error.IsntError())
{
error = mDirDevice.Attach(IoGetRelatedDeviceObject(
mDirFileObject));
if (error.IsntError())
mDirDevice.UseThisFileObject(mDirFileObject);
if (error.IsError())
{
ObDereferenceObject(mDirFileObject);
mDirFileObject = NULL;
}
}
if (error.IsError())
{
ZwClose(mDirHandle);
mDirHandle = NULL;
}
}
return error;
}
void
CVolumeImpDrvNT::CloseMountPointDir()
{
pgpAssert(mDirDevice.IsAttached());
ObDereferenceObject(mDirFileObject);
mDirFileObject = NULL;
mDirDevice.Detach();
ZwClose(mDirHandle);
mDirHandle = NULL;
}
CComboError
CVolumeImpDrvNT::AnnounceWin2kArrival(const CUnicodeString& fullDevName)
{
pgpAssert(mMountMgr.IsAttached());
CArray<PGPByte> sendBytes(kPGPdiskMaxPathLength * 3);
CComboError error;
error = sendBytes.Status();
if (error.IsntError())
{
MOUNTMGR_TARGET_NAME *pMTN = reinterpret_cast<
MOUNTMGR_TARGET_NAME *>(sendBytes.Get());
pgpClearMemory(pMTN, sizeof(*pMTN));
pMTN->DeviceNameLength = fullDevName.Length() * sizeof(WCHAR);
pgpCopyMemory(fullDevName.Get()->Buffer, &pMTN->DeviceName,
pMTN->DeviceNameLength);
error = mMountMgr.SendIoctlRequest(
IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION, pMTN,
sendBytes.Size(), NULL, NULL);
}
return error;
}
CComboError
CVolumeImpDrvNT::CreateMountPoint(
const CUnicodeString& volId,
const CUnicodeString& fullDevName,
const CUnicodeString& fullLinkName)
{
CArray<PGPByte> sendBytes(kPGPdiskMaxPathLength * 3);
CComboError error;
error = sendBytes.Status();
if (error.IsntError())
{
if (fullLinkName.LastWChar() == ':')
{
pgpAssert(mMountMgr.IsAttached());
// Make a drive letter link.
MOUNTMGR_CREATE_POINT_INPUT *pMCPI = reinterpret_cast<
MOUNTMGR_CREATE_POINT_INPUT *>(sendBytes.Get());
pgpClearMemory(pMCPI, sizeof(*pMCPI));
pMCPI->SymbolicLinkNameOffset = sizeof(
MOUNTMGR_CREATE_POINT_INPUT);
pMCPI->SymbolicLinkNameLength = fullLinkName.Length() *
sizeof(WCHAR);
pgpCopyMemory(fullLinkName.Get()->Buffer,
sendBytes.Get() + pMCPI->SymbolicLinkNameOffset,
pMCPI->SymbolicLinkNameLength);
pMCPI->DeviceNameOffset = pMCPI->SymbolicLinkNameOffset +
pMCPI->SymbolicLinkNameLength;
pMCPI->DeviceNameLength = fullDevName.Length() * sizeof(WCHAR);
pgpCopyMemory(fullDevName.Get()->Buffer,
sendBytes.Get() + pMCPI->DeviceNameOffset,
pMCPI->DeviceNameLength);
error = mMountMgr.SendIoctlRequest(IOCTL_MOUNTMGR_CREATE_POINT,
pMCPI, sendBytes.Size(), NULL, NULL);
}
else
{
pgpAssert(!mDirDevice.IsAttached());
error = OpenMountPointDir(fullLinkName);
if (error.IsntError())
{
// Make a folder link.
REPARSE_GUID_DATA_BUFFER *pRGDB = reinterpret_cast<
REPARSE_GUID_DATA_BUFFER *>(sendBytes.Get());
sendBytes.Wipe();
pRGDB->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
pRGDB->ReparseDataLength = 0x6e;
pRGDB->ReparseGuid.Data1 = 0x00620000;
pRGDB->ReparseGuid.Data2 = 0x0064;
pRGDB->ReparseGuid.Data3 = 0;
pgpCopyMemory(volId.Get()->Buffer, pRGDB->ReparseGuid.Data4,
volId.Length() * sizeof(WCHAR));
error = mDirDevice.SendFsctlRequest(IRP_MN_USER_FS_REQUEST,
FSCTL_SET_REPARSE_POINT, pRGDB, 0x76);
}
}
}
return error;
}
CComboError
CVolumeImpDrvNT::DeleteMountPoint(
const CUnicodeString& volId,
const CUnicodeString& fullDevName,
const CUnicodeString& fullLinkName)
{
CComboError error;
CArray<PGPByte> sendBytes(kPGPdiskMaxPathLength * 3);
CArray<PGPByte> recvBytes(kPGPdiskMaxPathLength * 3);
error = sendBytes.Status();
if (error.IsntError())
error = recvBytes.Status();
if (error.IsntError())
{
if (fullLinkName.LastWChar() == ':')
{
pgpAssert(mMountMgr.IsAttached());
// Delete a drive letter link.
MOUNTMGR_MOUNT_POINT *pMMP = reinterpret_cast<
MOUNTMGR_MOUNT_POINT *>(sendBytes.Get());
pgpClearMemory(pMMP, sizeof(*pMMP));
pMMP->SymbolicLinkNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
pMMP->SymbolicLinkNameLength = fullLinkName.Length() *
sizeof(WCHAR);
pgpCopyMemory(fullLinkName.Get()->Buffer, sendBytes.Get() +
pMMP->SymbolicLinkNameOffset, pMMP->SymbolicLinkNameLength);
error = mMountMgr.SendIoctlRequest(IOCTL_MOUNTMGR_DELETE_POINTS,
pMMP, sendBytes.Size(), recvBytes.Get(), recvBytes.Size());
}
else
{
pgpAssert(mDirDevice.IsAttached());
// Delete a folder link.
REPARSE_GUID_DATA_BUFFER *pRGDB = reinterpret_cast<
REPARSE_GUID_DATA_BUFFER *>(sendBytes.Get());
sendBytes.Wipe();
error = mDirDevice.SendFsctlRequest(IRP_MN_USER_FS_REQUEST,
FSCTL_GET_REPARSE_POINT, NULL, 0, pRGDB, sendBytes.Size());
if (error.IsntError())
{
pRGDB->ReparseDataLength = 0;
error = mDirDevice.SendFsctlRequest(IRP_MN_USER_FS_REQUEST,
FSCTL_DELETE_REPARSE_POINT,pRGDB, 8);
}
if (error.IsntError())
CloseMountPointDir();
}
}
return error;
}
#endif // (_WIN32_WINNT < 0x0500)
CComboError
CVolumeImpDrvNT::GetGeometry(DISK_GEOMETRY& geom)
{
CComboError error;
PGPBoolean weOpenedVolume = FALSE;
if (!IsVolumeHandleOpened())
{
error = OpenVolumeHandle();
weOpenedVolume = error.IsntError();
}
if (error.IsntError())
{
error = mVHDevice.SendIoctlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL, 0, &geom, sizeof(geom));
}
if (weOpenedVolume)
CloseVolumeHandle();
return error;
}
CComboError
CVolumeImpDrvNT::GetPartitionInfo(PARTITION_INFORMATION& partInfo)
{
CComboError error;
PGPBoolean weOpenedVolume = FALSE;
if (!IsVolumeHandleOpened())
{
error = OpenVolumeHandle();
weOpenedVolume = error.IsntError();
}
if (error.IsntError())
{
error = mVHDevice.SendIoctlRequest(IOCTL_DISK_GET_PARTITION_INFO,
NULL, 0, &partInfo, sizeof(partInfo));
}
if (weOpenedVolume)
CloseVolumeHandle();
return error;
}
CComboError
CVolumeImpDrvNT::FillInBlockInfo()
{
CComboError error;
DISK_GEOMETRY geom;
PARTITION_INFORMATION partInfo;
error = GetGeometry(geom);
if (error.IsntError())
error = GetPartitionInfo(partInfo);
if (error.IsntError())
{
mBlockSize = static_cast<PGPUInt32>(geom.BytesPerSector);
mTotalBlocks = partInfo.PartitionLength.QuadPart;
}
return error;
}
CComboError
CVolumeImpDrvNT::OpenVolumeHandle()
{
pgpAssert(!IsVolumeHandleOpened());
CComboError error;
CUnicodeString linkName;
error = linkName.Status();
if (error.IsntError())
{
// If root is mount point on directory, use volume ID.
if (mRoot.Length() > 3)
{
error = CDriverSubsystemsDrvNT::DeviceCache().GetEntryVolId(
DeviceName(), linkName);
}
else
{
error = linkName.Assign(mRoot);
if (error.IsntError())
error = linkName.Resize(linkName.Length() - 1); // lose slash
if (error.IsntError())
error = linkName.Prepend(kNTLinkPathPrefix);
}
}
if (error.IsntError())
{
IO_STATUS_BLOCK ioStatus;
OBJECT_ATTRIBUTES objectAttributes;
// Get handle to root of volume.
InitializeObjectAttributes(&objectAttributes, const_cast<
UNICODE_STRING *>(linkName.Get()), OBJ_CASE_INSENSITIVE, NULL,
NULL);
error.err = ZwCreateFile(&mVolumeHandle, FILE_GENERIC_READ |
FILE_GENERIC_WRITE | SYNCHRONIZE, &objectAttributes, &ioStatus,
NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_VolumeOpFailed; // NETABUG has open files/forced unmount?
if (error.IsntError())
{
// Get file object from this handle.
error.err = ObReferenceObjectByHandle(mVolumeHandle,
FILE_READ_DATA, NULL, KernelMode,
reinterpret_cast<void **>(&mVHFileObject), NULL);
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_NTDrvObjectOpFailed;
if (error.IsntError())
{
// Get device object from this file object.
error = mVHDevice.Attach(
IoGetRelatedDeviceObject(mVHFileObject));
if (error.IsntError())
mVHDevice.UseThisFileObject(mVHFileObject);
if (error.IsError())
{
ObDereferenceObject(mVHFileObject);
mVHFileObject = NULL;
}
}
if (error.IsError())
{
ZwClose(mVolumeHandle);
mVolumeHandle = NULL;
}
}
}
return error;
}
void
CVolumeImpDrvNT::CloseVolumeHandle()
{
pgpAssert(IsVolumeHandleOpened());
ObDereferenceObject(mVHFileObject);
mVHFileObject = NULL;
mVHDevice.Detach();
ZwClose(mVolumeHandle);
mVolumeHandle = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -