📄 cdevice.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: CDevice.cpp,v 1.5 2002/08/06 20:10:50 dallen Exp $
____________________________________________________________________________*/
#include "pgpClassesConfig.h"
#include "UDebug.h"
#include "CDevice.h"
#include "CEvent.h"
_USING_PGP
// Class CDevice member functions
CDevice::CDevice()
: mIsAttached(FALSE), mWeCreated(FALSE), mDeviceObject(NULL),
mFileObjectToUse(NULL), mDispatchFunc(NULL), mRefPtr(NULL),
mWeLinked(FALSE)
{
Status() = mDeviceName.Status();
if (Status().IsntError())
Status() = mLinkName.Status();
}
CDevice::~CDevice()
{
if (IsAttached())
{
if (WeCreated())
Delete();
else
Detach();
}
}
void
CDevice::UseThisFileObject(PFILE_OBJECT fObj)
{
pgpAssert(IsAttached());
pgpAssertAddrValid(fObj, FILE_OBJECT);
// For requests to volumes, we need to specify a file object
// corresponding to an open logical volume handle.
mFileObjectToUse = fObj;
}
void
CDevice::UpdateRefPtr(void *refPtr)
{
mRefPtr = refPtr;
}
CComboError
CDevice::Attach(const CUnicodeString& deviceName)
{
pgpAssert(!IsAttached());
CComboError error;
PFILE_OBJECT pFileObject;
if (error.IsntError())
error = mDeviceName.Assign(deviceName);
if (error.IsntError())
{
error.err = IoGetDeviceObjectPointer(const_cast<UNICODE_STRING *>(
deviceName.Get()), FILE_READ_DATA, &pFileObject, &mDeviceObject);
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_NTDrvObjectOpFailed;
}
if (error.IsntError())
{
ObDereferenceObject(pFileObject);
mIsAttached = TRUE;
mWeCreated = FALSE;
}
return error;
}
CComboError
CDevice::Attach(PDEVICE_OBJECT pDeviceObject)
{
pgpAssert(!IsAttached());
pgpAssertAddrValid(pDeviceObject, DEVICE_OBJECT);
CComboError error;
mDeviceObject = pDeviceObject;
mIsAttached = TRUE;
mWeCreated = FALSE;
return error;
}
void
CDevice::Detach()
{
pgpAssert(IsAttached());
pgpAssert(!WeCreated());
mDeviceObject = NULL;
mFileObjectToUse = NULL;
mIsAttached = FALSE;
}
CComboError
CDevice::Reference()
{
pgpAssert(IsAttached());
CComboError error;
error.err = ObReferenceObjectByPointer(mDeviceObject, FILE_READ_ACCESS,
NULL, KernelMode);
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_NTDrvObjectOpFailed;
return error;
}
void
CDevice::Dereference()
{
pgpAssert(IsAttached());
ObDereferenceObject(mDeviceObject);
}
CComboError
CDevice::Read(void *buf, PGPUInt64 pos, PGPUInt32 nBytes) const
{
pgpAssert(IsAttached());
pgpAssertAddrValid(buf, VoidAlign);
CComboError error;
CEvent event;
CIrp irp;
IO_STATUS_BLOCK ioStatus;
// Build the request.
error = irp.BuildSynchronousFsdRequest(IRP_MJ_READ, mDeviceObject, buf,
nBytes, pos, event, ioStatus);
if (error.IsntError())
{
// Call down the request.
irp.UseNextStackLocation();
irp.FileObject() = mFileObjectToUse;
error.err = CallDriver(irp);
if (error.err == STATUS_PENDING)
{
event.Wait();
error.err = ioStatus.Status;
}
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_NTDrvIopOpFailed;
}
return error;
}
CComboError
CDevice::Write(const void *buf, PGPUInt64 pos, PGPUInt32 nBytes) const
{
pgpAssert(IsAttached());
pgpAssertAddrValid(buf, VoidAlign);
CComboError error;
CEvent event;
CIrp irp;
IO_STATUS_BLOCK ioStatus;
// Build the request.
error = irp.BuildSynchronousFsdRequest(IRP_MJ_WRITE, mDeviceObject, buf,
nBytes, pos, event, ioStatus);
if (error.IsntError())
{
// Call down the request.
irp.UseNextStackLocation();
irp.FileObject() = mFileObjectToUse;
error.err = CallDriver(irp);
if (error.err == STATUS_PENDING)
{
event.Wait();
error.err = ioStatus.Status;
}
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_NTDrvIopOpFailed;
}
return error;
}
CComboError
CDevice::SendIoctlRequest(
PGPUInt32 ioctlCode,
const void *inBuf,
PGPUInt32 sizeInBuf,
void *outBuf,
PGPUInt32 sizeOutBuf,
PGPBoolean isInternal) const
{
pgpAssert(IsAttached());
CComboError error;
CEvent event;
CIrp irp;
IO_STATUS_BLOCK ioStatus;
// Build the request.
error = irp.BuildDeviceIoControlRequest(ioctlCode, mDeviceObject, inBuf,
sizeInBuf, outBuf, sizeOutBuf, isInternal, event, ioStatus);
if (error.IsntError())
{
// Call down the request.
irp.UseNextStackLocation();
irp.FileObject() = mFileObjectToUse;
error.err = CallDriver(irp);
if (error.err == STATUS_PENDING)
{
event.Wait();
error.err = ioStatus.Status;
}
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_NTDrvIopOpFailed;
}
return error;
}
CComboError
CDevice::SendFsctlRequest(
PGPUInt32 minorFunc,
PGPUInt32 fsctlCode,
const void *inBuf,
PGPUInt32 sizeInBuf,
void *outBuf,
PGPUInt32 sizeOutBuf) const
{
pgpAssert(IsAttached());
CComboError error;
CEvent event;
CIrp irp;
IO_STATUS_BLOCK ioStatus;
// Build the request.
error = irp.BuildDeviceIoControlRequest(fsctlCode, mDeviceObject, inBuf,
sizeInBuf, outBuf, sizeOutBuf, FALSE, event, ioStatus);
if (error.IsntError())
{
// Call down the request.
irp.UseNextStackLocation();
irp.MajorFunction() = IRP_MJ_FILE_SYSTEM_CONTROL;
irp.MinorFunction() = minorFunc;
irp.FileObject() = mFileObjectToUse;
error.err = CallDriver(irp);
if (error.err == STATUS_PENDING)
{
event.Wait();
error.err = ioStatus.Status;
}
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_NTDrvIopOpFailed;
}
return error;
}
CComboError
CDevice::Create(
PDRIVER_OBJECT pDriverObject,
const CUnicodeString& deviceName,
DEVICE_TYPE deviceType,
PGPUInt32 deviceChars,
PGPBoolean exclusive,
IrpDispatchFunc dispatchFunc,
void *refPtr)
{
pgpAssert(!IsAttached());
pgpAssertAddrValid(dispatchFunc, IrpDispatchFunc);
CComboError error;
error = mDeviceName.Assign(deviceName);
if (error.IsntError())
{
error.err = IoCreateDevice(pDriverObject, 0, const_cast<
UNICODE_STRING *>(deviceName.Get()), deviceType, deviceChars,
exclusive, &mDeviceObject);
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_NTDrvObjectOpFailed;
}
if (error.IsntError())
{
mDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
mDeviceObject->Flags |= DO_DIRECT_IO;
mDeviceObject->DeviceExtension = this;
mIsAttached = TRUE;
mWeCreated = TRUE;
mDispatchFunc = dispatchFunc;
mRefPtr = refPtr;
}
return error;
}
void
CDevice::Delete()
{
pgpAssert(IsAttached());
pgpAssert(WeCreated());
pgpAssert(!WeLinked());
IoDeleteDevice(mDeviceObject);
mDeviceName.Empty();
mIsAttached = FALSE;
mDeviceObject = NULL;
mDispatchFunc = NULL;
mRefPtr = NULL;
}
CComboError
CDevice::Link(const CUnicodeString& linkName)
{
pgpAssert(IsAttached());
pgpAssert(WeCreated());
pgpAssert(!WeLinked());
CComboError error;
error = mLinkName.Assign(linkName);
if (error.IsntError())
{
error.err = IoCreateSymbolicLink(const_cast<UNICODE_STRING *>(
linkName.Get()), const_cast<UNICODE_STRING *>(
DeviceName().Get()));
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_NTDrvObjectOpFailed;
}
if (error.IsntError())
mWeLinked = TRUE;
return error;
}
CComboError
CDevice::Unlink()
{
pgpAssert(IsAttached());
pgpAssert(WeCreated());
pgpAssert(WeLinked());
CComboError error;
error.err = IoDeleteSymbolicLink(const_cast<UNICODE_STRING *>(
LinkName().Get()));
if (error.HaveNonPGPError())
error.pgpErr = kPGPError_NTDrvObjectOpFailed;
if (error.IsntError())
mWeLinked = FALSE;
return error;
}
NTSTATUS
CDevice::CallDriver(CIrp& irp) const
{
pgpAssert(IsAttached());
return IoCallDriver(mDeviceObject, irp);
}
NTSTATUS
CDevice::DispatchIrp(CIrp& irp, PGPBoolean& isIrpCompleted)
{
pgpAssert(IsAttached());
pgpAssert(WeCreated());
return mDispatchFunc(this, irp, mRefPtr, isIrpCompleted);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -