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

📄 cvolumeimpdrvnt.cpp

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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 + -