mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
- Rewrite KsDefaultDispatchPnp to make it actually work
- Implement KsDefaultDispatchPower, KsDefaultForwardIrp - Return the correct device object in KsQueryDevicePnpObject - Implement KsReadFile, KsSetInformationFile and partly KsQueryInformationFile - Remove KspClose, KspRead, KspWrite, KspFlushBuffers, KspQuerySecurity, KspSetSecurity and all these IOCTL in KspDispatchIrp - Rewrite KsDispatchIrp to handle IRP_MJ_CREATE & IRP_MJ_POWER, IRP_MJ_PNP for AV Stream minidrivers and forward IRP_MJ_SYSTEM_CONTROL requests to the registered pnp base object - Unsupported IOCTLs are now completed with KsDispatchInvalidDeviceRequest (previously leaked) svn path=/trunk/; revision=42117
This commit is contained in:
parent
de33ea571e
commit
4725a4fd9c
5 changed files with 463 additions and 277 deletions
|
@ -65,9 +65,8 @@ KsReleaseDeviceSecurityLock(
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@unimplemented
|
@implemented
|
||||||
*/
|
*/
|
||||||
|
|
||||||
KSDDKAPI
|
KSDDKAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -75,46 +74,54 @@ KsDefaultDispatchPnp(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
|
PDEVICE_EXTENSION DeviceExtension;
|
||||||
|
PKSIDEVICE_HEADER DeviceHeader;
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
PDEVICE_OBJECT PnpDeviceObject;
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG MinorFunction;
|
||||||
|
|
||||||
|
/* get current irp stack */
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
//FIXME
|
/* caller wants to add the target device */
|
||||||
//REWRITE
|
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
DPRINT1("KsDefaultDispatchPnp entered with func %x\n", IoStack->MinorFunction);
|
/* get device header */
|
||||||
|
DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
|
||||||
|
|
||||||
switch(IoStack->MinorFunction)
|
/* backup PnpBaseObject */
|
||||||
|
PnpDeviceObject = DeviceHeader->PnpDeviceObject;
|
||||||
|
|
||||||
|
|
||||||
|
/* backup minor function code */
|
||||||
|
MinorFunction = IoStack->MinorFunction;
|
||||||
|
|
||||||
|
if(MinorFunction == IRP_MN_REMOVE_DEVICE)
|
||||||
{
|
{
|
||||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
/* remove the device */
|
||||||
Irp->IoStatus.Information = 0;
|
KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader);
|
||||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
case IRP_MN_REMOVE_DEVICE:
|
|
||||||
// FIXME
|
|
||||||
// destroy device header, detach device and delete device
|
|
||||||
case IRP_MN_START_DEVICE:
|
|
||||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
|
||||||
case IRP_MN_CANCEL_STOP_DEVICE:
|
|
||||||
case IRP_MN_SURPRISE_REMOVAL:
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
default:
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
//Status = IoCallDriver(NULL /* PnpBaseObject */, Irp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* skip current irp stack */
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* call attached pnp device object */
|
||||||
|
Status = IoCallDriver(PnpDeviceObject, Irp);
|
||||||
|
|
||||||
|
if (MinorFunction == IRP_MN_REMOVE_DEVICE)
|
||||||
|
{
|
||||||
|
/* time is over */
|
||||||
|
IoDetachDevice(PnpDeviceObject);
|
||||||
|
/* delete device */
|
||||||
|
IoDeleteDevice(DeviceObject);
|
||||||
|
}
|
||||||
|
/* done */
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@unimplemented
|
@implemented
|
||||||
*/
|
*/
|
||||||
KSDDKAPI
|
KSDDKAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -123,16 +130,59 @@ KsDefaultDispatchPower(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PDEVICE_EXTENSION DeviceExtension;
|
||||||
|
PKSIDEVICE_HEADER DeviceHeader;
|
||||||
|
PKSIOBJECT_HEADER ObjectHeader;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PLIST_ENTRY ListEntry;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
/* get current irp stack */
|
||||||
Irp->IoStatus.Information = 0;
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
/* caller wants to add the target device */
|
||||||
|
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* get device header */
|
||||||
|
DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
|
||||||
|
|
||||||
|
/* FIXME locks */
|
||||||
|
|
||||||
|
/* loop our power dispatch list and call registered notification functions */
|
||||||
|
ListEntry = DeviceHeader->PowerDispatchList.Flink;
|
||||||
|
/* let's go */
|
||||||
|
while(ListEntry != &DeviceHeader->PowerDispatchList)
|
||||||
|
{
|
||||||
|
/* get object header */
|
||||||
|
ObjectHeader = (PKSIOBJECT_HEADER)CONTAINING_RECORD(ListEntry, KSIOBJECT_HEADER, PowerDispatchEntry);
|
||||||
|
|
||||||
|
/* does it have still a cb */
|
||||||
|
if (ObjectHeader->PowerDispatch)
|
||||||
|
{
|
||||||
|
/* call the power cb */
|
||||||
|
Status = ObjectHeader->PowerDispatch(ObjectHeader->PowerContext, Irp);
|
||||||
|
ASSERT(NT_SUCCESS(Status));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* iterate to next entry */
|
||||||
|
ListEntry = ListEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start next power irp */
|
||||||
|
PoStartNextPowerIrp(Irp);
|
||||||
|
|
||||||
|
/* skip current irp stack location */
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* let's roll */
|
||||||
|
Status = PoCallDriver(DeviceHeader->PnpDeviceObject, Irp);
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@unimplemented
|
@implemented
|
||||||
*/
|
*/
|
||||||
KSDDKAPI
|
KSDDKAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -141,11 +191,24 @@ KsDefaultForwardIrp(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PDEVICE_EXTENSION DeviceExtension;
|
||||||
Irp->IoStatus.Information = 0;
|
PKSIDEVICE_HEADER DeviceHeader;
|
||||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
PIO_STACK_LOCATION IoStack;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
NTSTATUS Status;
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
|
/* get current irp stack */
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* caller wants to add the target device */
|
||||||
|
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
|
/* get device header */
|
||||||
|
DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
|
||||||
|
|
||||||
|
/* forward the request to the PDO */
|
||||||
|
Status = IoCallDriver(DeviceHeader->PnpDeviceObject, Irp);
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -161,8 +224,8 @@ KsSetDevicePnpAndBaseObject(
|
||||||
{
|
{
|
||||||
PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
|
PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
|
||||||
|
|
||||||
DeviceHeader->PhysicalDeviceObject = PnpDeviceObject;
|
DeviceHeader->PnpDeviceObject = PnpDeviceObject;
|
||||||
DeviceHeader->NextDeviceObject = BaseDevice;
|
DeviceHeader->BaseDevice = BaseDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -176,8 +239,8 @@ KsQueryDevicePnpObject(
|
||||||
{
|
{
|
||||||
PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
|
PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
|
||||||
|
|
||||||
/* return next device header */
|
/* return PnpDeviceObject */
|
||||||
return DeviceHeader->NextDeviceObject;
|
return DeviceHeader->PnpDeviceObject;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -607,11 +607,6 @@ IKsDevice_Create(
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@unimplemented
|
@unimplemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -169,7 +169,7 @@ KsDispatchSpecificMethod(
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@unimplemented
|
@implemented
|
||||||
*/
|
*/
|
||||||
KSDDKAPI
|
KSDDKAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -184,8 +184,88 @@ KsReadFile(
|
||||||
IN ULONG Key OPTIONAL,
|
IN ULONG Key OPTIONAL,
|
||||||
IN KPROCESSOR_MODE RequestorMode)
|
IN KPROCESSOR_MODE RequestorMode)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
return STATUS_UNSUCCESSFUL;
|
PIRP Irp;
|
||||||
|
NTSTATUS Status;
|
||||||
|
BOOLEAN Result;
|
||||||
|
KEVENT LocalEvent;
|
||||||
|
|
||||||
|
if (Event)
|
||||||
|
{
|
||||||
|
/* make sure event is reset */
|
||||||
|
KeClearEvent(Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RequestorMode == UserMode)
|
||||||
|
{
|
||||||
|
/* probe the user buffer */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(Buffer, Length, sizeof(UCHAR));
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Exception, get the error code */
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Invalid user buffer provided\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get corresponding device object */
|
||||||
|
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||||
|
|
||||||
|
/* fast-io read is only available for kernel mode clients */
|
||||||
|
if (RequestorMode == KernelMode && ExGetPreviousMode() == KernelMode &&
|
||||||
|
DeviceObject->DriverObject->FastIoDispatch->FastIoRead)
|
||||||
|
{
|
||||||
|
/* call fast io write */
|
||||||
|
Result = DeviceObject->DriverObject->FastIoDispatch->FastIoRead(FileObject, &FileObject->CurrentByteOffset, Length, TRUE, Key, Buffer, IoStatusBlock, DeviceObject);
|
||||||
|
|
||||||
|
if (Result && NT_SUCCESS(IoStatusBlock->Status))
|
||||||
|
{
|
||||||
|
/* request was handeled and succeeded */
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do the slow way */
|
||||||
|
if (!Event)
|
||||||
|
{
|
||||||
|
/* initialize temp event */
|
||||||
|
KeInitializeEvent(&LocalEvent, NotificationEvent, FALSE);
|
||||||
|
Event = &LocalEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build the irp packet */
|
||||||
|
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, Buffer, Length, &FileObject->CurrentByteOffset, Event, IoStatusBlock);
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
/* not enough resources */
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send the packet */
|
||||||
|
Status = IoCallDriver(DeviceObject, Irp);
|
||||||
|
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* operation is pending, is sync file object */
|
||||||
|
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
|
||||||
|
{
|
||||||
|
/* it is so wait */
|
||||||
|
KeWaitForSingleObject(Event, Executive, RequestorMode, FALSE, NULL);
|
||||||
|
Status = IoStatusBlock->Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* return result */
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -256,7 +336,6 @@ KsWriteFile(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do the slow way */
|
/* do the slow way */
|
||||||
|
|
||||||
if (!Event)
|
if (!Event)
|
||||||
{
|
{
|
||||||
/* initialize temp event */
|
/* initialize temp event */
|
||||||
|
@ -301,12 +380,45 @@ KsQueryInformationFile(
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
IN FILE_INFORMATION_CLASS FileInformationClass)
|
IN FILE_INFORMATION_CLASS FileInformationClass)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
PFAST_IO_DISPATCH FastIoDispatch;
|
||||||
|
IO_STATUS_BLOCK IoStatus;
|
||||||
|
|
||||||
|
/* get related file object */
|
||||||
|
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||||
|
|
||||||
|
/* get fast i/o table */
|
||||||
|
FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
|
||||||
|
|
||||||
|
/* is there a fast table */
|
||||||
|
if (FastIoDispatch)
|
||||||
|
{
|
||||||
|
/* check the class */
|
||||||
|
if (FileInformationClass == FileBasicInformation)
|
||||||
|
{
|
||||||
|
/* use FastIoQueryBasicInfo routine */
|
||||||
|
if (FastIoDispatch->FastIoQueryBasicInfo)
|
||||||
|
{
|
||||||
|
return FastIoDispatch->FastIoQueryBasicInfo(FileObject, TRUE, (PFILE_BASIC_INFORMATION)FileInformation, &IoStatus, DeviceObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (FileInformationClass == FileStandardInformation)
|
||||||
|
{
|
||||||
|
/* use FastIoQueryBasicInfo routine */
|
||||||
|
if (FastIoDispatch->FastIoQueryBasicInfo)
|
||||||
|
{
|
||||||
|
return FastIoDispatch->FastIoQueryStandardInfo(FileObject, TRUE, (PFILE_STANDARD_INFORMATION)FileInformation, &IoStatus, DeviceObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implement Me */
|
||||||
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@unimplemented
|
@implemented
|
||||||
*/
|
*/
|
||||||
KSDDKAPI
|
KSDDKAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -317,8 +429,84 @@ KsSetInformationFile(
|
||||||
IN ULONG Length,
|
IN ULONG Length,
|
||||||
IN FILE_INFORMATION_CLASS FileInformationClass)
|
IN FILE_INFORMATION_CLASS FileInformationClass)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PIO_STACK_LOCATION IoStack;
|
||||||
return STATUS_UNSUCCESSFUL;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
PIRP Irp;
|
||||||
|
PVOID Buffer;
|
||||||
|
KEVENT Event;
|
||||||
|
LARGE_INTEGER Offset;
|
||||||
|
IO_STATUS_BLOCK IoStatus;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* get related device object */
|
||||||
|
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||||
|
|
||||||
|
/* copy file information */
|
||||||
|
Buffer = AllocateItem(NonPagedPool, Length);
|
||||||
|
if (!Buffer)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
ProbeForRead(Buffer, Length, sizeof(UCHAR));
|
||||||
|
RtlMoveMemory(Buffer, FileInformation, Length);
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Exception, get the error code */
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* invalid user buffer */
|
||||||
|
FreeItem(Buffer);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize the event */
|
||||||
|
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||||
|
|
||||||
|
/* zero offset */
|
||||||
|
Offset.QuadPart = 0LL;
|
||||||
|
|
||||||
|
/* build the irp */
|
||||||
|
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SET_INFORMATION, DeviceObject, NULL, 0, &Offset, &Event, &IoStatus);
|
||||||
|
|
||||||
|
if (!Irp)
|
||||||
|
{
|
||||||
|
/* failed to allocate irp */
|
||||||
|
FreeItem(Buffer);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get next stack location */
|
||||||
|
IoStack = IoGetNextIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* set irp parameters */
|
||||||
|
IoStack->Parameters.SetFile.FileInformationClass = FileInformationClass;
|
||||||
|
IoStack->Parameters.SetFile.Length = Length;
|
||||||
|
IoStack->Parameters.SetFile.FileObject = FileObject;
|
||||||
|
Irp->AssociatedIrp.SystemBuffer = Buffer;
|
||||||
|
Irp->UserBuffer = FileInformation;
|
||||||
|
|
||||||
|
/* dispatch the irp */
|
||||||
|
Status = IoCallDriver(DeviceObject, Irp);
|
||||||
|
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* wait untill the operation has completed */
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
/* is a sync file object */
|
||||||
|
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
|
||||||
|
Status = FileObject->FinalStatus;
|
||||||
|
else
|
||||||
|
Status = IoStatus.Status;
|
||||||
|
}
|
||||||
|
/* done */
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -843,57 +1031,6 @@ KspCreate(
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTAPI
|
|
||||||
NTSTATUS
|
|
||||||
KspClose(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIRP Irp)
|
|
||||||
{
|
|
||||||
PIO_STACK_LOCATION IoStack;
|
|
||||||
PKSIOBJECT_HEADER ObjectHeader;
|
|
||||||
PDEVICE_EXTENSION DeviceExtension;
|
|
||||||
PKSIDEVICE_HEADER DeviceHeader;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
/* get current stack location */
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
/* get device extension */
|
|
||||||
DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
|
|
||||||
/* get device header */
|
|
||||||
DeviceHeader = DeviceExtension->DeviceHeader;
|
|
||||||
|
|
||||||
|
|
||||||
DPRINT("KS / CLOSE\n");
|
|
||||||
|
|
||||||
if (IoStack->FileObject && IoStack->FileObject->FsContext)
|
|
||||||
{
|
|
||||||
/* get object header */
|
|
||||||
ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
|
|
||||||
/* store create item */
|
|
||||||
KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
|
|
||||||
/* call object close method */
|
|
||||||
Status = ObjectHeader->DispatchTable.Close(DeviceObject, Irp);
|
|
||||||
/* FIXME decrease reference count on original create item */
|
|
||||||
|
|
||||||
/* return result */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
DPRINT1("Expected Object Header FileObject %p FsContext %p\n", IoStack->FileObject, IoStack->FileObject->FsContext);
|
|
||||||
KeBugCheckEx(0, 0, 0, 0, 0);
|
|
||||||
#else
|
|
||||||
DPRINT("Using reference string hack\n");
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
||||||
Irp->IoStatus.Information = 0;
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
#endif
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NTAPI
|
NTAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
KspDeviceControl(
|
KspDeviceControl(
|
||||||
|
@ -910,14 +1047,14 @@ KspDeviceControl(
|
||||||
/* get current stack location */
|
/* get current stack location */
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* get device extension */
|
||||||
|
DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
|
||||||
|
/* get device header */
|
||||||
|
DeviceHeader = DeviceExtension->DeviceHeader;
|
||||||
|
|
||||||
/* hack for bug 4566 */
|
/* hack for bug 4566 */
|
||||||
if (IoStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_OBJECT_CLASS)
|
if (IoStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_OBJECT_CLASS)
|
||||||
{
|
{
|
||||||
/* get device extension */
|
|
||||||
DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
|
|
||||||
/* get device header */
|
|
||||||
DeviceHeader = DeviceExtension->DeviceHeader;
|
|
||||||
|
|
||||||
/* retrieve all available reference strings registered */
|
/* retrieve all available reference strings registered */
|
||||||
Length = 0;
|
Length = 0;
|
||||||
|
|
||||||
|
@ -978,142 +1115,87 @@ KspDeviceControl(
|
||||||
|
|
||||||
NTAPI
|
NTAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
KspRead(
|
KspDispatchIrp(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PDEVICE_EXTENSION DeviceExtension;
|
||||||
PKSIOBJECT_HEADER ObjectHeader;
|
PKSIOBJECT_HEADER ObjectHeader;
|
||||||
|
PKSIDEVICE_HEADER DeviceHeader;
|
||||||
|
PDRIVER_DISPATCH Dispatch;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* get current stack location */
|
/* get current stack location */
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
DPRINT("KS / Read\n");
|
/* get device extension */
|
||||||
if (IoStack->FileObject && IoStack->FileObject->FsContext)
|
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
{
|
/* get device header */
|
||||||
ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
|
DeviceHeader = DeviceExtension->DeviceHeader;
|
||||||
|
|
||||||
KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
|
/* get object header */
|
||||||
return ObjectHeader->DispatchTable.Read(DeviceObject, Irp);
|
ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
|
||||||
|
|
||||||
|
if (!ObjectHeader)
|
||||||
|
{
|
||||||
|
/* hack for bug 4566 */
|
||||||
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
/* complete and forget */
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
ASSERT(ObjectHeader);
|
||||||
|
/* store create item */
|
||||||
|
KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
|
||||||
|
|
||||||
|
/* retrieve matching dispatch function */
|
||||||
|
switch(IoStack->MajorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MJ_CLOSE:
|
||||||
|
Dispatch = ObjectHeader->DispatchTable.Close;
|
||||||
|
break;
|
||||||
|
case IRP_MJ_DEVICE_CONTROL:
|
||||||
|
Dispatch = ObjectHeader->DispatchTable.DeviceIoControl;
|
||||||
|
break;
|
||||||
|
case IRP_MJ_READ:
|
||||||
|
Dispatch = ObjectHeader->DispatchTable.Read;
|
||||||
|
break;
|
||||||
|
case IRP_MJ_WRITE:
|
||||||
|
Dispatch = ObjectHeader->DispatchTable.Write;
|
||||||
|
break;
|
||||||
|
case IRP_MJ_FLUSH_BUFFERS :
|
||||||
|
Dispatch = ObjectHeader->DispatchTable.Flush;
|
||||||
|
break;
|
||||||
|
case IRP_MJ_QUERY_SECURITY:
|
||||||
|
Dispatch = ObjectHeader->DispatchTable.QuerySecurity;
|
||||||
|
break;
|
||||||
|
case IRP_MJ_SET_SECURITY:
|
||||||
|
Dispatch = ObjectHeader->DispatchTable.SetSecurity;
|
||||||
|
break;
|
||||||
|
case IRP_MJ_PNP:
|
||||||
|
Dispatch = KsDefaultDispatchPnp;
|
||||||
|
default:
|
||||||
|
Dispatch = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* is the request supported */
|
||||||
|
if (Dispatch)
|
||||||
|
{
|
||||||
|
/* now call the dispatch function */
|
||||||
|
Status = Dispatch(DeviceObject, Irp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT1("Expected Object Header\n");
|
/* not supported request */
|
||||||
KeBugCheckEx(0, 0, 0, 0, 0);
|
Status = KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
NTAPI
|
/* done */
|
||||||
NTSTATUS
|
return Status;
|
||||||
KspWrite(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIRP Irp)
|
|
||||||
{
|
|
||||||
PIO_STACK_LOCATION IoStack;
|
|
||||||
PKSIOBJECT_HEADER ObjectHeader;
|
|
||||||
|
|
||||||
/* get current stack location */
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
|
|
||||||
DPRINT("KS / Write\n");
|
|
||||||
if (IoStack->FileObject && IoStack->FileObject->FsContext)
|
|
||||||
{
|
|
||||||
ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
|
|
||||||
|
|
||||||
KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
|
|
||||||
return ObjectHeader->DispatchTable.Write(DeviceObject, Irp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("Expected Object Header %p\n", IoStack->FileObject);
|
|
||||||
KeBugCheckEx(0, 0, 0, 0, 0);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NTAPI
|
|
||||||
NTSTATUS
|
|
||||||
KspFlushBuffers(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIRP Irp)
|
|
||||||
{
|
|
||||||
PIO_STACK_LOCATION IoStack;
|
|
||||||
PKSIOBJECT_HEADER ObjectHeader;
|
|
||||||
|
|
||||||
/* get current stack location */
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
|
|
||||||
DPRINT("KS / FlushBuffers\n");
|
|
||||||
if (IoStack->FileObject && IoStack->FileObject->FsContext)
|
|
||||||
{
|
|
||||||
ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
|
|
||||||
|
|
||||||
KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
|
|
||||||
return ObjectHeader->DispatchTable.Flush(DeviceObject, Irp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("Expected Object Header\n");
|
|
||||||
KeBugCheckEx(0, 0, 0, 0, 0);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NTAPI
|
|
||||||
NTSTATUS
|
|
||||||
KspQuerySecurity(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIRP Irp)
|
|
||||||
{
|
|
||||||
PIO_STACK_LOCATION IoStack;
|
|
||||||
PKSIOBJECT_HEADER ObjectHeader;
|
|
||||||
|
|
||||||
/* get current stack location */
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
|
|
||||||
DPRINT("KS / QuerySecurity\n");
|
|
||||||
if (IoStack->FileObject && IoStack->FileObject->FsContext)
|
|
||||||
{
|
|
||||||
ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
|
|
||||||
|
|
||||||
KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
|
|
||||||
return ObjectHeader->DispatchTable.QuerySecurity(DeviceObject, Irp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("Expected Object Header\n");
|
|
||||||
KeBugCheckEx(0, 0, 0, 0, 0);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NTAPI
|
|
||||||
NTSTATUS
|
|
||||||
KspSetSecurity(
|
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
|
||||||
IN PIRP Irp)
|
|
||||||
{
|
|
||||||
PIO_STACK_LOCATION IoStack;
|
|
||||||
PKSIOBJECT_HEADER ObjectHeader;
|
|
||||||
|
|
||||||
/* get current stack location */
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
|
||||||
|
|
||||||
DPRINT("KS / SetSecurity\n");
|
|
||||||
if (IoStack->FileObject && IoStack->FileObject->FsContext)
|
|
||||||
{
|
|
||||||
ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
|
|
||||||
|
|
||||||
KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
|
|
||||||
return ObjectHeader->DispatchTable.SetSecurity(DeviceObject, Irp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("Expected Object Header\n");
|
|
||||||
KeBugCheckEx(0, 0, 0, 0, 0);
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1131,28 +1213,18 @@ KsSetMajorFunctionHandler(
|
||||||
case IRP_MJ_CREATE:
|
case IRP_MJ_CREATE:
|
||||||
DriverObject->MajorFunction[MajorFunction] = KspCreate;
|
DriverObject->MajorFunction[MajorFunction] = KspCreate;
|
||||||
break;
|
break;
|
||||||
case IRP_MJ_CLOSE:
|
|
||||||
DriverObject->MajorFunction[MajorFunction] = KspClose;
|
|
||||||
break;
|
break;
|
||||||
case IRP_MJ_DEVICE_CONTROL:
|
case IRP_MJ_DEVICE_CONTROL:
|
||||||
DriverObject->MajorFunction[MajorFunction] = KspDeviceControl;
|
DriverObject->MajorFunction[MajorFunction] = KspDeviceControl;
|
||||||
break;
|
break;
|
||||||
|
case IRP_MJ_CLOSE:
|
||||||
case IRP_MJ_READ:
|
case IRP_MJ_READ:
|
||||||
DriverObject->MajorFunction[MajorFunction] = KspRead;
|
|
||||||
break;
|
|
||||||
case IRP_MJ_WRITE:
|
case IRP_MJ_WRITE:
|
||||||
DriverObject->MajorFunction[MajorFunction] = KspWrite;
|
|
||||||
break;
|
|
||||||
case IRP_MJ_FLUSH_BUFFERS :
|
case IRP_MJ_FLUSH_BUFFERS :
|
||||||
DriverObject->MajorFunction[MajorFunction] = KspFlushBuffers;
|
|
||||||
break;
|
|
||||||
case IRP_MJ_QUERY_SECURITY:
|
case IRP_MJ_QUERY_SECURITY:
|
||||||
DriverObject->MajorFunction[MajorFunction] = KspQuerySecurity;
|
|
||||||
break;
|
|
||||||
case IRP_MJ_SET_SECURITY:
|
case IRP_MJ_SET_SECURITY:
|
||||||
DriverObject->MajorFunction[MajorFunction] = KspSetSecurity;
|
DriverObject->MajorFunction[MajorFunction] = KspDispatchIrp;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
};
|
};
|
||||||
|
@ -1171,37 +1243,93 @@ KsDispatchIrp(
|
||||||
IN PIRP Irp)
|
IN PIRP Irp)
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PKSIDEVICE_HEADER DeviceHeader;
|
||||||
|
PDEVICE_EXTENSION DeviceExtension;
|
||||||
|
|
||||||
|
/* get device extension */
|
||||||
|
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||||
|
/* get device header */
|
||||||
|
DeviceHeader = DeviceExtension->DeviceHeader;
|
||||||
|
|
||||||
|
|
||||||
/* get current irp stack */
|
/* get current irp stack */
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
//FIXME REWRITE
|
if (IoStack->MajorFunction <= IRP_MJ_DEVICE_CONTROL)
|
||||||
|
|
||||||
switch (IoStack->MajorFunction)
|
|
||||||
{
|
{
|
||||||
case IRP_MJ_CREATE:
|
if (IoStack->MajorFunction == IRP_MJ_CREATE)
|
||||||
return KspCreate(DeviceObject, Irp);
|
{
|
||||||
case IRP_MJ_CLOSE:
|
/* check internal type */
|
||||||
return KspClose(DeviceObject, Irp);
|
if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */
|
||||||
break;
|
{
|
||||||
case IRP_MJ_DEVICE_CONTROL:
|
/* AVStream client */
|
||||||
|
return IKsDevice_Create(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* external client (portcls) */
|
||||||
|
return KspCreate(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IoStack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
|
||||||
|
{
|
||||||
|
/* handle device requests */
|
||||||
return KspDeviceControl(DeviceObject, Irp);
|
return KspDeviceControl(DeviceObject, Irp);
|
||||||
break;
|
}
|
||||||
case IRP_MJ_READ:
|
|
||||||
return KspRead(DeviceObject, Irp);
|
switch (IoStack->MajorFunction)
|
||||||
break;
|
{
|
||||||
case IRP_MJ_WRITE:
|
case IRP_MJ_CLOSE:
|
||||||
return KspWrite(DeviceObject, Irp);
|
case IRP_MJ_READ:
|
||||||
break;
|
case IRP_MJ_WRITE:
|
||||||
case IRP_MJ_FLUSH_BUFFERS:
|
case IRP_MJ_FLUSH_BUFFERS:
|
||||||
return KspFlushBuffers(DeviceObject, Irp);
|
case IRP_MJ_QUERY_SECURITY:
|
||||||
break;
|
case IRP_MJ_SET_SECURITY:
|
||||||
case IRP_MJ_QUERY_SECURITY:
|
case IRP_MJ_PNP:
|
||||||
return KspQuerySecurity(DeviceObject, Irp);
|
return KspDispatchIrp(DeviceObject, Irp);
|
||||||
break;
|
default:
|
||||||
case IRP_MJ_SET_SECURITY:
|
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
|
||||||
return KspSetSecurity(DeviceObject, Irp);
|
}
|
||||||
break;
|
}
|
||||||
default:
|
|
||||||
return STATUS_INVALID_PARAMETER; /* is this right? */
|
/* dispatch power */
|
||||||
};
|
if (IoStack->MajorFunction == IRP_MJ_POWER)
|
||||||
|
{
|
||||||
|
/* check internal type */
|
||||||
|
if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */
|
||||||
|
{
|
||||||
|
/* AVStream client */
|
||||||
|
return IKsDevice_Power(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* external client (portcls) */
|
||||||
|
return KsDefaultDispatchPower(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (IoStack->MajorFunction == IRP_MJ_PNP) /* dispatch pnp */
|
||||||
|
{
|
||||||
|
/* check internal type */
|
||||||
|
if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */
|
||||||
|
{
|
||||||
|
/* AVStream client */
|
||||||
|
return IKsDevice_Pnp(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* external client (portcls) */
|
||||||
|
return KsDefaultDispatchPnp(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (IoStack->MajorFunction == IRP_MJ_SYSTEM_CONTROL)
|
||||||
|
{
|
||||||
|
/* forward irp */
|
||||||
|
return KsDefaultForwardIrp(DeviceObject, Irp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* not supported */
|
||||||
|
return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,8 @@ typedef struct
|
||||||
ULONG DeviceIndex;
|
ULONG DeviceIndex;
|
||||||
KSPIN_LOCK ItemListLock;
|
KSPIN_LOCK ItemListLock;
|
||||||
|
|
||||||
PDEVICE_OBJECT PhysicalDeviceObject;
|
PDEVICE_OBJECT PnpDeviceObject;
|
||||||
PDEVICE_OBJECT NextDeviceObject;
|
PDEVICE_OBJECT BaseDevice;
|
||||||
|
|
||||||
KSTARGET_STATE TargetState;
|
KSTARGET_STATE TargetState;
|
||||||
LIST_ENTRY TargetDeviceList;
|
LIST_ENTRY TargetDeviceList;
|
||||||
|
|
|
@ -70,7 +70,7 @@ KspForwardIrpSynchronous(
|
||||||
IoSetCompletionRoutine(Irp, KspForwardIrpSynchronousCompletion, (PVOID)&Event, TRUE, TRUE, TRUE);
|
IoSetCompletionRoutine(Irp, KspForwardIrpSynchronousCompletion, (PVOID)&Event, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
/* now call the driver */
|
/* now call the driver */
|
||||||
Status = IoCallDriver(DeviceHeader->NextDeviceObject, Irp);
|
Status = IoCallDriver(DeviceHeader->BaseDevice, Irp);
|
||||||
/* did the request complete yet */
|
/* did the request complete yet */
|
||||||
if (Status == STATUS_PENDING)
|
if (Status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue