📄 driverentry.cpp
字号:
result = FALSE;
} // found higher version
else
KdPrint((DRIVERNAME " - Overriding WDMSTUB clone version %d.%2.2d\n", version >> 16, version & 0xFFFF));
} // check version #
else
KdPrint((DRIVERNAME " - IOCTL_INTERNAL_WDMSTUB_GET_VERSION failed to %ws - %X\n", devname, status));
} // send IRP
// Dereference the file object to release our hold on the clone device object
ObDereferenceObject(fop);
} // found a clone
// If there's no device object by this name, remember the index for when we need to create our own
// device object
else if (avail == 0xFFFFFFFF)
avail = index;
} // for each possible driver index
// Check the result of the version comparisons
if (!result)
return FALSE;
// We have decided to stub some functions. Create a dummy device object so
// other clones can find us. Also take an extra reference to the driver object
// to pin us into memory -- some other WDM driver may end up using one of our
// stubs
if (avail == 0xFFFFFFFF)
{
KdPrint((DRIVERNAME " - More than 100 WDMSTUB clones are loaded in this system!\n"));
return FALSE;
}
_snwprintf(namebuf, arraysize(namebuf), L"\\Device\\WDMSTUB%d", avail);
RtlInitUnicodeString(&devname, namebuf);
status = IoCreateDevice(DriverObject, sizeof(DUMMY_DEVICE_EXTENSION), &devname, FILE_DEVICE_UNKNOWN, 0, FALSE, &DummyDeviceObject);
if (!NT_SUCCESS(status))
{
KdPrint((DRIVERNAME " - IoCreateDevice failed - %X\n", status));
return FALSE;
}
ObReferenceObject(DriverObject); // pin this driver into memory forever
// Initialize the dummy device extension so IRP dispatch functions can distinguish between this
// and a layered device object
PDUMMY_DEVICE_EXTENSION ddx = (PDUMMY_DEVICE_EXTENSION) DummyDeviceObject->DeviceExtension;
ddx->flags |= DUMMY_DEVICE_FLAG;
return TRUE;
} // CheckCloneVersions
///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info)
{ // CompleteRequest
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
} // CompleteRequest
NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status)
{ // CompleteRequest
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
} // CompleteRequest
///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE // make no assumptions about pageability of dispatch fcns
NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{ // DispatchAny
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
// Fail any IRPs addressed to the dummy device object other than CREATE and CLOSE
if (pdx->flags & DUMMY_DEVICE_FLAG)
{ // IRP for dummy device
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
if (stack->MajorFunction == IRP_MJ_CREATE || stack->MajorFunction == IRP_MJ_CLOSE)
status = STATUS_SUCCESS;
return CompleteRequest(Irp, status);
} // IRP for dummy device
// Pass down IRPs addressed to the FiDO
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(pdx->LowerDeviceObject, Irp);
} // DispatchAny
///////////////////////////////////////////////////////////////////////////////
NTSTATUS DispatchInternalControl(PDEVICE_OBJECT dummy, PIRP Irp)
{ // DispatchInternalControl
PDUMMY_DEVICE_EXTENSION ddx = (PDUMMY_DEVICE_EXTENSION) dummy->DeviceExtension;
if (!(ddx->flags & DUMMY_DEVICE_FLAG))
{ // not for us
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(((PDEVICE_EXTENSION)(ddx))->LowerDeviceObject, Irp);
} // not for us
NTSTATUS status;
ULONG info = 0;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
switch (code)
{ // process internal control operation
// Version query: return the version number of this driver
case IOCTL_INTERNAL_WDMSTUB_GET_VERSION:
if (cbout < sizeof(ULONG))
{ // wrong output buffer length
status = STATUS_INVALID_PARAMETER;
break;
} // wrong output buffer length
*(PULONG)(Irp->UserBuffer) = (VERMAJOR << 16) | VERMINOR;
info = sizeof(ULONG);
status = STATUS_SUCCESS;
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
} // process internal control operation
return CompleteRequest(Irp, status, info);
} // DispatchInternalControl
///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
NTSTATUS DispatchPower(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{ // DispatchPower
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
PoStartNextPowerIrp(Irp); // must be done while we own the IRP
if (pdx->flags & DUMMY_DEVICE_FLAG)
return CompleteRequest(Irp, STATUS_SUCCESS); // shouldn't happen in the 1st place
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(pdx->LowerDeviceObject, Irp);
} // DispatchPower
///////////////////////////////////////////////////////////////////////////////
#pragma LOCKEDCODE
NTSTATUS DispatchPnp(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{ // DispatchPnp
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
// The dummy device shouldn't get any PnP IRPs
if (pdx->flags & DUMMY_DEVICE_FLAG)
return CompleteRequest(Irp, STATUS_SUCCESS); // don't change Information field
// Pass down PnP request
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
ULONG fcn = stack->MinorFunction;
NTSTATUS status;
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pdx->LowerDeviceObject, Irp);
if (fcn == IRP_MN_REMOVE_DEVICE)
RemoveDevice(fido);
return status;
} // DispatchPnp
///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{ // DriverUnload
PAGED_CODE();
// Delete our dummy device object
if (DummyDeviceObject)
IoDeleteDevice(DummyDeviceObject);
// It should not be possible for this driver to be unloaded if we defined
// any stubs. Don't preclude this, though, because there may be some future
// mechanism that would make this safe.
if (StubsDefined)
UndefineStubs();
} // DriverUnload
///////////////////////////////////////////////////////////////////////////////
#pragma PAGEDCODE
VOID RemoveDevice(IN PDEVICE_OBJECT fdo)
{ // RemoveDevice
PAGED_CODE();
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
ASSERT(!(pdx->flags & DUMMY_DEVICE_FLAG)); // shouldn't be possible
NTSTATUS status;
if (pdx->LowerDeviceObject)
IoDetachDevice(pdx->LowerDeviceObject);
IoDeleteDevice(fdo);
} // RemoveDevice
///////////////////////////////////////////////////////////////////////////////
#pragma INITCODE
BOOLEAN IsWin98()
{ // IsWin98
#ifdef _X86_
// Windows 98 (including 2d ed) supports WDM version 1.0, whereas Win2K
// supports 1.10.
return !IoIsWdmVersionAvailable(1, 0x10);
#else // not _X86_
return FALSE;
#endif // not _X86_
} // IsWin98
#pragma LOCKEDCODE // force inline functions into locked code
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -