/*
- ReactOS Kernel Streaming
- IRP Helpers
-*/
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: drivers/ksfilter/ks/factory.c
+ * PURPOSE: KS Allocator functions
+ * PROGRAMMER: Johannes Anderwald
+ */
+
#include "priv.h"
/*
- @unimplemented
+ @implemented
*/
-KSDDKAPI NTSTATUS NTAPI
-KsAcquireResetValue(
- IN PIRP Irp,
- OUT KSRESET* ResetValue)
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsDispatchQuerySecurity(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
+ PKSOBJECT_CREATE_ITEM CreateItem;
+ PIO_STACK_LOCATION IoStack;
+ NTSTATUS Status;
+ ULONG Length;
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* get create item */
+ CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
+
+ if (!CreateItem || !CreateItem->SecurityDescriptor)
+ {
+ /* no create item */
+ Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_NO_SECURITY_ON_OBJECT;
+ }
+
+
+ /* get input length */
+ Length = IoStack->Parameters.QuerySecurity.Length;
+
+ /* clone the security descriptor */
+ Status = SeQuerySecurityDescriptorInfo(&IoStack->Parameters.QuerySecurity.SecurityInformation, (PSECURITY_DESCRIPTOR)Irp->UserBuffer, &Length, &CreateItem->SecurityDescriptor);
+
+ DPRINT("SeQuerySecurityDescriptorInfo Status %x\n", Status);
+ /* store result */
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = Length;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
}
/*
@implemented
*/
KSDDKAPI
-VOID
+NTSTATUS
NTAPI
-KsAddIrpToCancelableQueue(
- IN OUT PLIST_ENTRY QueueHead,
- IN PKSPIN_LOCK SpinLock,
- IN PIRP Irp,
- IN KSLIST_ENTRY_LOCATION ListLocation,
- IN PDRIVER_CANCEL DriverCancel OPTIONAL)
+KsDispatchSetSecurity(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- PQUEUE_ENTRY Entry;
+ PKSOBJECT_CREATE_ITEM CreateItem;
+ PIO_STACK_LOCATION IoStack;
+ PGENERIC_MAPPING Mapping;
+ PSECURITY_DESCRIPTOR Descriptor;
+ NTSTATUS Status;
- if (!QueueHead || !SpinLock || !Irp)
- return;
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
- Entry = ExAllocatePool(NonPagedPool, sizeof(QUEUE_ENTRY));
- if (!Entry)
- return;
+ /* get create item */
+ CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
- ///FIXME
- // setup cancel routine
- //
+ if (!CreateItem || !CreateItem->SecurityDescriptor)
+ {
+ /* no create item */
+ Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_NO_SECURITY_ON_OBJECT;
+ }
- Entry->Irp = Irp;
+ /* backup old descriptor */
+ Descriptor = CreateItem->SecurityDescriptor;
- if (ListLocation == KsListEntryTail)
- ExInterlockedInsertTailList(QueueHead, &Entry->Entry, SpinLock);
- else
- ExInterlockedInsertHeadList(QueueHead, &Entry->Entry, SpinLock);
+ /* get generic mapping */
+ Mapping = IoGetFileObjectGenericMapping();
+
+ /* change security descriptor */
+ Status = SeSetSecurityDescriptorInfo(NULL, /*FIXME */
+ &IoStack->Parameters.SetSecurity.SecurityInformation,
+ IoStack->Parameters.SetSecurity.SecurityDescriptor,
+ &CreateItem->SecurityDescriptor,
+ NonPagedPool,
+ Mapping);
+
+ if (NT_SUCCESS(Status))
+ {
+ /* free old descriptor */
+ ExFreePool(Descriptor);
+
+ /* mark create item as changed */
+ CreateItem->Flags |= KSCREATE_ITEM_SECURITYCHANGED;
+ }
+
+ /* store result */
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
}
/*
@unimplemented
*/
-KSDDKAPI NTSTATUS NTAPI
-KsAddObjectCreateItemToObjectHeader(
- IN KSOBJECT_HEADER Header,
- IN PDRIVER_DISPATCH Create,
- IN PVOID Context,
- IN PWCHAR ObjectClass,
- IN PSECURITY_DESCRIPTOR SecurityDescriptor)
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsDispatchSpecificMethod(
+ IN PIRP Irp,
+ IN PFNKSHANDLER Handler)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
KSDDKAPI
NTSTATUS
NTAPI
-KsAddObjectCreateItemToDeviceHeader(
- IN KSDEVICE_HEADER DevHeader,
- IN PDRIVER_DISPATCH Create,
- IN PVOID Context,
- IN PWCHAR ObjectClass,
- IN PSECURITY_DESCRIPTOR SecurityDescriptor)
+KsReadFile(
+ IN PFILE_OBJECT FileObject,
+ IN PKEVENT Event OPTIONAL,
+ IN PVOID PortContext OPTIONAL,
+ OUT PIO_STATUS_BLOCK IoStatusBlock,
+ OUT PVOID Buffer,
+ IN ULONG Length,
+ IN ULONG Key OPTIONAL,
+ IN KPROCESSOR_MODE RequestorMode)
{
- PKSIDEVICE_HEADER Header;
- ULONG FreeIndex, Index;
-
- Header = (PKSIDEVICE_HEADER)DevHeader;
+ PDEVICE_OBJECT DeviceObject;
+ PIRP Irp;
+ NTSTATUS Status;
+ BOOLEAN Result;
+ KEVENT LocalEvent;
- DPRINT1("KsAddObjectCreateItemToDeviceHeader entered\n");
+ if (Event)
+ {
+ /* make sure event is reset */
+ KeClearEvent(Event);
+ }
- /* check if a device header has been provided */
- if (!DevHeader)
- return STATUS_INVALID_PARAMETER_1;
+ 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;
- /* check if a create item has been provided */
- if (!Create)
- return STATUS_INVALID_PARAMETER_2;
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Invalid user buffer provided\n");
+ return Status;
+ }
+ }
- /* check if a object class has been provided */
- if (!ObjectClass)
- return STATUS_INVALID_PARAMETER_4;
+ /* get corresponding device object */
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
- FreeIndex = (ULONG)-1;
- /* now scan the list and check for a free item */
- for(Index = 0; Index < Header->MaxItems; Index++)
+ /* fast-io read is only available for kernel mode clients */
+ if (RequestorMode == KernelMode && ExGetPreviousMode() == KernelMode &&
+ DeviceObject->DriverObject->FastIoDispatch->FastIoRead)
{
- if (!Header->ItemList[Index].bCreated)
- {
- if (FreeIndex == (ULONG)-1)
- FreeIndex = Index;
+ /* call fast io write */
+ Result = DeviceObject->DriverObject->FastIoDispatch->FastIoRead(FileObject, &FileObject->CurrentByteOffset, Length, TRUE, Key, Buffer, IoStatusBlock, DeviceObject);
- continue;
- }
- else if (!wcsicmp(ObjectClass, Header->ItemList[Index].CreateItem.ObjectClass.Buffer))
+ if (Result && NT_SUCCESS(IoStatusBlock->Status))
{
- /* the same object class already exists */
- return STATUS_OBJECT_NAME_COLLISION;
+ /* request was handeled and succeeded */
+ return STATUS_SUCCESS;
}
}
- /* found a free index */
- if (FreeIndex == (ULONG)-1)
+
+ /* do the slow way */
+ if (!Event)
{
- /* allocate a new device entry */
- PDEVICE_ITEM Item = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_ITEM) * (Header->MaxItems + 1), TAG_DEVICE_HEADER);
- if (!Item)
- return STATUS_INSUFFICIENT_RESOURCES;
+ /* initialize temp event */
+ KeInitializeEvent(&LocalEvent, NotificationEvent, FALSE);
+ Event = &LocalEvent;
+ }
- RtlMoveMemory(Item, Header->ItemList, Header->MaxItems * sizeof(DEVICE_ITEM));
- ExFreePoolWithTag(Header->ItemList, TAG_DEVICE_HEADER);
-
- Header->ItemList = Item;
- FreeIndex = Header->MaxItems;
- Header->MaxItems++;
- }
-
- /* store the new item */
- Header->ItemList[FreeIndex].bCreated = TRUE;
- Header->ItemList[FreeIndex].CreateItem.Create = Create;
- Header->ItemList[FreeIndex].CreateItem.Context = Context;
- RtlInitUnicodeString(&Header->ItemList[FreeIndex].CreateItem.ObjectClass, ObjectClass);
- Header->ItemList[FreeIndex].CreateItem.SecurityDescriptor = SecurityDescriptor;
- Header->ItemList[FreeIndex].CreateItem.Flags = 0;
- return STATUS_SUCCESS;
+ /* 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;
}
/*
KSDDKAPI
NTSTATUS
NTAPI
-KsAllocateDeviceHeader(
- OUT KSDEVICE_HEADER* OutHeader,
- IN ULONG ItemsCount,
- IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL)
+KsWriteFile(
+ IN PFILE_OBJECT FileObject,
+ IN PKEVENT Event OPTIONAL,
+ IN PVOID PortContext OPTIONAL,
+ OUT PIO_STATUS_BLOCK IoStatusBlock,
+ IN PVOID Buffer,
+ IN ULONG Length,
+ IN ULONG Key OPTIONAL,
+ IN KPROCESSOR_MODE RequestorMode)
{
- ULONG Index = 0;
- PKSIDEVICE_HEADER Header;
-
- if (!OutHeader)
- return STATUS_INVALID_PARAMETER;
+ PDEVICE_OBJECT DeviceObject;
+ PIRP Irp;
+ NTSTATUS Status;
+ BOOLEAN Result;
+ KEVENT LocalEvent;
- /* allocate a device header */
- Header = ExAllocatePoolWithTag(PagedPool, sizeof(KSIDEVICE_HEADER), TAG_DEVICE_HEADER);
+ if (Event)
+ {
+ /* make sure event is reset */
+ KeClearEvent(Event);
+ }
- /* check for success */
- if (!Header)
- return STATUS_INSUFFICIENT_RESOURCES;
+ if (RequestorMode == UserMode)
+ {
+ /* probe the user buffer */
+ _SEH2_TRY
+ {
+ ProbeForRead(Buffer, Length, sizeof(UCHAR));
+ Status = STATUS_SUCCESS;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
- /* clear all memory */
- RtlZeroMemory(Header, sizeof(KSIDEVICE_HEADER));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Invalid user buffer provided\n");
+ return Status;
+ }
+ }
- /* initialize spin lock */
- KeInitializeSpinLock(&Header->ItemListLock);
+ /* get corresponding device object */
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
- /* are there any create items provided */
- if (ItemsCount && ItemsList)
+ /* fast-io write is only available for kernel mode clients */
+ if (RequestorMode == KernelMode && ExGetPreviousMode() == KernelMode &&
+ DeviceObject->DriverObject->FastIoDispatch->FastIoWrite)
{
- /* allocate space for device item list */
- Header->ItemList = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_ITEM) * ItemsCount, TAG_DEVICE_HEADER);
- if (!Header->ItemList)
- {
- ExFreePoolWithTag(Header, TAG_DEVICE_HEADER);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- RtlZeroMemory(Header->ItemList, sizeof(DEVICE_ITEM) * ItemsCount);
+ /* call fast io write */
+ Result = DeviceObject->DriverObject->FastIoDispatch->FastIoWrite(FileObject, &FileObject->CurrentByteOffset, Length, TRUE, Key, Buffer, IoStatusBlock, DeviceObject);
- for(Index = 0; Index < ItemsCount; Index++)
+ if (Result && NT_SUCCESS(IoStatusBlock->Status))
{
- /* copy provided create items */
- RtlMoveMemory(&Header->ItemList[Index].CreateItem, &ItemsList[Index], sizeof(KSOBJECT_CREATE_ITEM));
- if (ItemsList[Index].Create!= NULL)
- {
- Header->ItemList[Index].bCreated = TRUE;
- }
+ /* request was handeled and succeeded */
+ return STATUS_SUCCESS;
}
- Header->MaxItems = ItemsCount;
}
- /* store result */
- *OutHeader = Header;
+ /* do the slow way */
+ if (!Event)
+ {
+ /* initialize temp event */
+ KeInitializeEvent(&LocalEvent, NotificationEvent, FALSE);
+ Event = &LocalEvent;
+ }
- return STATUS_SUCCESS;
+ /* build the irp packet */
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, 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;
}
/*
- @unimplemented
-
- http://www.osronline.com/DDKx/stream/ksfunc_3sc3.htm
+ @implemented
*/
KSDDKAPI
NTSTATUS
NTAPI
-KsAllocateObjectCreateItem(
- IN KSDEVICE_HEADER DevHeader,
- IN PKSOBJECT_CREATE_ITEM CreateItem,
- IN BOOLEAN AllocateEntry,
- IN PFNKSITEMFREECALLBACK ItemFreeCallback OPTIONAL)
+KsQueryInformationFile(
+ IN PFILE_OBJECT FileObject,
+ OUT PVOID FileInformation,
+ IN ULONG Length,
+ IN FILE_INFORMATION_CLASS FileInformationClass)
{
- PKSIDEVICE_HEADER Header;
+ PDEVICE_OBJECT DeviceObject;
+ PFAST_IO_DISPATCH FastIoDispatch;
+ PIRP Irp;
+ PIO_STACK_LOCATION IoStack;
+ IO_STATUS_BLOCK IoStatus;
+ KEVENT Event;
+ LARGE_INTEGER Offset;
+ IO_STATUS_BLOCK StatusBlock;
+ NTSTATUS Status;
- Header = (PKSIDEVICE_HEADER)DevHeader;
+ /* get related file object */
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
- if (!DevHeader)
- return STATUS_INVALID_PARAMETER_1;
+ /* get fast i/o table */
+ FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
- if (!CreateItem)
- return STATUS_INVALID_PARAMETER_2;
+ /* 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);
+ }
+ }
+ }
+ /* clear event */
+ KeClearEvent(&FileObject->Event);
- //FIXME
- //handle ItemFreeCallback
- //
- if (AllocateEntry && ItemFreeCallback)
- DPRINT1("Ignoring ItemFreeCallback\n");
+ /* initialize event */
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
- return KsAddObjectCreateItemToDeviceHeader(DevHeader, CreateItem->Create, CreateItem->Context, CreateItem->ObjectClass.Buffer, CreateItem->SecurityDescriptor);
-}
+ /* set offset to zero */
+ Offset.QuadPart = 0L;
+ /* build the request */
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_INFORMATION, IoGetRelatedDeviceObject(FileObject), NULL, 0, &Offset, &Event, &StatusBlock);
-/*
- @implemented
-*/
-KSDDKAPI
-VOID
-NTAPI
-KsFreeDeviceHeader(
- IN KSDEVICE_HEADER DevHeader)
-{
- PKSIDEVICE_HEADER Header;
+ if (!Irp)
+ return STATUS_INSUFFICIENT_RESOURCES;
- Header = (PKSIDEVICE_HEADER)DevHeader;
+ /* get next stack location */
+ IoStack = IoGetNextIrpStackLocation(Irp);
- if (!DevHeader)
- return;
+ /* setup parameters */
+ IoStack->Parameters.QueryFile.FileInformationClass = FileInformationClass;
+ IoStack->Parameters.QueryFile.Length = Length;
+ Irp->AssociatedIrp.SystemBuffer = FileInformation;
- ExFreePoolWithTag(Header->ItemList, TAG_DEVICE_HEADER);
- ExFreePoolWithTag(Header, TAG_DEVICE_HEADER);
-}
-/*
- @unimplemented
-*/
-KSDDKAPI NTSTATUS NTAPI
-KsAllocateExtraData(
- IN PIRP Irp,
- IN ULONG ExtraSize,
- OUT PVOID* ExtraBuffer)
-{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
-}
+ /* call the driver */
+ Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
-/*
- @unimplemented
+ if (Status == STATUS_PENDING)
+ {
+ /* wait for the operation to complete */
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+
+ /* is object sync */
+ if (FileObject->Flags & FO_SYNCHRONOUS_IO)
+ Status = FileObject->FinalStatus;
+ else
+ Status = StatusBlock.Status;
+ }
- Initialize the required file context header.
- Allocates KSOBJECT_HEADER structure.
- Irp is an IRP_MJ_CREATE structure.
- Driver must allocate KSDISPATCH_TABLE and initialize it first.
+ /* done */
+ return Status;
+}
- http://www.osronline.com/DDKx/stream/ksfunc_0u2b.htm
+/*
+ @implemented
*/
KSDDKAPI
NTSTATUS
NTAPI
-KsAllocateObjectHeader(
- OUT KSOBJECT_HEADER *Header,
- IN ULONG ItemsCount,
- IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL,
- IN PIRP Irp,
- IN KSDISPATCH_TABLE* Table)
+KsSetInformationFile(
+ IN PFILE_OBJECT FileObject,
+ IN PVOID FileInformation,
+ IN ULONG Length,
+ IN FILE_INFORMATION_CLASS FileInformationClass)
{
PIO_STACK_LOCATION IoStack;
- PDEVICE_EXTENSION DeviceExtension;
- PKSIDEVICE_HEADER DeviceHeader;
- PKSIOBJECT_HEADER ObjectHeader;
- WCHAR ObjectClass[50];
-
- if (!Header)
- return STATUS_INVALID_PARAMETER_1;
-
- if (!Irp)
- return STATUS_INVALID_PARAMETER_4;
-
- if (!Table)
- return STATUS_INVALID_PARAMETER_5;
+ PDEVICE_OBJECT DeviceObject;
+ PIRP Irp;
+ PVOID Buffer;
+ KEVENT Event;
+ LARGE_INTEGER Offset;
+ IO_STATUS_BLOCK IoStatus;
+ NTSTATUS Status;
- /* get current stack location */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
- /* get device extension */
- DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
- /* get device header */
- DeviceHeader = DeviceExtension->DeviceHeader;
+ /* get related device object */
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
- ObjectClass[0] = L'\0';
- /* check for an file object */
- if (IoStack->FileObject != NULL)
- {
- /* validate the file name */
- if (IoStack->FileObject->FileName.Length >= 38)
- {
- RtlMoveMemory(ObjectClass, IoStack->FileObject->FileName.Buffer, 38 * sizeof(WCHAR));
- ObjectClass[38] = L'\0';
- DPRINT("ObjectClass %S\n", ObjectClass);
- }
- }
- /* allocate the object header */
- ObjectHeader = ExAllocatePoolWithTag(NonPagedPool, sizeof(KSIOBJECT_HEADER), TAG_DEVICE_HEADER);
- if (!ObjectHeader)
+ /* copy file information */
+ Buffer = AllocateItem(NonPagedPool, Length);
+ if (!Buffer)
return STATUS_INSUFFICIENT_RESOURCES;
- /* initialize object header */
- RtlZeroMemory(ObjectHeader, sizeof(KSIOBJECT_HEADER));
-
- /* do we have a name */
- if (ObjectClass[0])
+ _SEH2_TRY
{
- ObjectHeader->ObjectClass = ExAllocatePoolWithTag(NonPagedPool, 40 * sizeof(WCHAR), TAG_DEVICE_HEADER);
- if (ObjectHeader->ObjectClass)
- {
- wcscpy(ObjectHeader->ObjectClass, ObjectClass);
- }
+ ProbeForRead(Buffer, Length, sizeof(UCHAR));
+ RtlMoveMemory(Buffer, FileInformation, Length);
+ Status = STATUS_SUCCESS;
}
-
- /* copy dispatch table */
- RtlCopyMemory(&ObjectHeader->DispatchTable, Table, sizeof(KSDISPATCH_TABLE));
- /* store create items */
- if (ItemsCount && ItemsList)
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- ObjectHeader->ItemCount = ItemsCount;
- ObjectHeader->CreateItem = ItemsList;
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
}
+ _SEH2_END;
- /* was the request for a pin/clock/node */
- if (IoStack->FileObject)
+ if (!NT_SUCCESS(Status))
{
- /* store the object in the file object */
- ASSERT(IoStack->FileObject->FsContext == NULL);
- IoStack->FileObject->FsContext = ObjectHeader;
+ /* invalid user buffer */
+ FreeItem(Buffer);
+ return Status;
}
- else
+
+ /* 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)
{
- /* the object header is for device */
- ASSERT(DeviceHeader->DeviceIndex < DeviceHeader->MaxItems);
- DeviceHeader->ItemList[DeviceHeader->DeviceIndex].ObjectHeader = ObjectHeader;
+ /* failed to allocate irp */
+ FreeItem(Buffer);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
- /* store result */
- *Header = ObjectHeader;
-
+ /* get next stack location */
+ IoStack = IoGetNextIrpStackLocation(Irp);
- DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectClass, IoStack->FileObject, ObjectHeader);
+ /* 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;
- return STATUS_SUCCESS;
+ /* 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;
}
/*
- @unimplemented
+ @implemented
*/
KSDDKAPI
-VOID
+NTSTATUS
NTAPI
-KsFreeObjectHeader(
- IN PVOID Header)
+KsStreamIo(
+ IN PFILE_OBJECT FileObject,
+ IN PKEVENT Event OPTIONAL,
+ IN PVOID PortContext OPTIONAL,
+ IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
+ IN PVOID CompletionContext OPTIONAL,
+ IN KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL,
+ OUT PIO_STATUS_BLOCK IoStatusBlock,
+ IN OUT PVOID StreamHeaders,
+ IN ULONG Length,
+ IN ULONG Flags,
+ IN KPROCESSOR_MODE RequestorMode)
{
+ PIRP Irp;
+ PIO_STACK_LOCATION IoStack;
+ PDEVICE_OBJECT DeviceObject;
+ NTSTATUS Status;
+ LARGE_INTEGER Offset;
+ PKSIOBJECT_HEADER ObjectHeader;
+ BOOLEAN Ret;
+ /* get related device object */
+ DeviceObject = IoGetRelatedDeviceObject(FileObject);
+ /* sanity check */
+ ASSERT(DeviceObject != NULL);
-}
+ /* is there a event provided */
+ if (Event)
+ {
+ /* reset event */
+ KeClearEvent(Event);
+ }
-/*
- @unimplemented
-*/
-KSDDKAPI VOID NTAPI
-KsCancelIo(
- IN OUT PLIST_ENTRY QueueHead,
- IN PKSPIN_LOCK SpinLock)
-{
- UNIMPLEMENTED;
-}
+ if (RequestorMode || ExGetPreviousMode() == KernelMode)
+ {
+ /* requestor is from kernel land */
+ ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext2;
-/*
- @unimplemented
-*/
-KSDDKAPI VOID NTAPI
-KsCancelRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- UNIMPLEMENTED;
+ if (ObjectHeader)
+ {
+ /* there is a object header */
+ if (Flags == KSSTREAM_READ)
+ {
+ /* is fast read supported */
+ if (ObjectHeader->DispatchTable.FastRead)
+ {
+ /* call fast read dispatch routine */
+ Ret = ObjectHeader->DispatchTable.FastRead(FileObject, NULL, Length, FALSE, 0, StreamHeaders, IoStatusBlock, DeviceObject);
+
+ if (Ret)
+ {
+ /* the request was handeled */
+ return IoStatusBlock->Status;
+ }
+ }
+ }
+ else if (Flags == KSSTREAM_WRITE)
+ {
+ /* is fast write supported */
+ if (ObjectHeader->DispatchTable.FastWrite)
+ {
+ /* call fast write dispatch routine */
+ Ret = ObjectHeader->DispatchTable.FastWrite(FileObject, NULL, Length, FALSE, 0, StreamHeaders, IoStatusBlock, DeviceObject);
+
+ if (Ret)
+ {
+ /* the request was handeled */
+ return IoStatusBlock->Status;
+ }
+ }
+ }
+ }
+ }
+
+ /* clear file object event */
+ KeClearEvent(&FileObject->Event);
+
+ /* set the offset to zero */
+ Offset.QuadPart = 0LL;
+
+ /* now build the irp */
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_DEVICE_CONTROL,
+ DeviceObject, (PVOID)StreamHeaders, Length, &Offset, Event, IoStatusBlock);
+ if (!Irp)
+ {
+ /* not enough memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* setup irp parameters */
+ Irp->RequestorMode = RequestorMode;
+ Irp->Overlay.AsynchronousParameters.UserApcContext = PortContext;
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->UserBuffer = StreamHeaders;
+
+ /* get next irp stack location */
+ IoStack = IoGetNextIrpStackLocation(Irp);
+ /* setup stack parameters */
+ IoStack->FileObject = FileObject;
+ IoStack->Parameters.DeviceIoControl.InputBufferLength = Length;
+ IoStack->Parameters.DeviceIoControl.Type3InputBuffer = StreamHeaders;
+ IoStack->Parameters.DeviceIoControl.IoControlCode = (Flags == KSSTREAM_READ ? IOCTL_KS_READ_STREAM : IOCTL_KS_WRITE_STREAM);
+
+ if (CompletionRoutine)
+ {
+ /* setup completion routine for async processing */
+ IoSetCompletionRoutine(Irp, CompletionRoutine, CompletionContext, (CompletionInvocationFlags & KsInvokeOnSuccess), (CompletionInvocationFlags & KsInvokeOnError), (CompletionInvocationFlags & KsInvokeOnCancel));
+ }
+
+ /* now call the driver */
+ Status = IoCallDriver(DeviceObject, Irp);
+ /* done */
+ return Status;
}
/*
- @unimplemented
+ @implemented
*/
-KSDDKAPI NTSTATUS NTAPI
-KsDefaultDeviceIoCompletion(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsProbeStreamIrp(
+ IN PIRP Irp,
+ IN ULONG ProbeFlags,
+ IN ULONG HeaderSize)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
+ PMDL Mdl;
+ PVOID Buffer;
+ LOCK_OPERATION Operation;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PKSSTREAM_HEADER StreamHeader;
+ PIO_STACK_LOCATION IoStack;
+ ULONG Length;
+ BOOLEAN AllocateMdl = FALSE;
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ Length = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
+
+ if (Irp->RequestorMode == KernelMode || Irp->AssociatedIrp.SystemBuffer)
+ {
+AllocMdl:
+ /* check if alloc mdl flag is passed */
+ if (!(ProbeFlags & KSPROBE_ALLOCATEMDL))
+ {
+ /* nothing more to do */
+ return STATUS_SUCCESS;
+ }
+ if (Irp->MdlAddress)
+ {
+ProbeMdl:
+ if (ProbeFlags & KSPROBE_PROBEANDLOCK)
+ {
+ if (Irp->MdlAddress->MdlFlags & (MDL_PAGES_LOCKED | MDL_SOURCE_IS_NONPAGED_POOL))
+ {
+ if (ProbeFlags & KSPROBE_SYSTEMADDRESS)
+ {
+ _SEH2_TRY
+ {
+ /* loop through all mdls and probe them */
+ Mdl = Irp->MdlAddress;
+ do
+ {
+ /* the mapping can fail */
+ Mdl->MdlFlags |= MDL_MAPPING_CAN_FAIL;
+
+ if (Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL))
+ {
+ /* no need to probe these pages */
+ Buffer = Mdl->MappedSystemVa;
+ }
+ else
+ {
+ /* probe that mdl */
+ Buffer = MmMapLockedPages(Mdl, KernelMode);
+ }
+
+ /* check if the mapping succeeded */
+ if (!Buffer)
+ {
+ /* raise exception we'll catch */
+ ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ /* iterate to next mdl */
+ Mdl = Mdl->Next;
+
+ }while(Mdl);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
+ } _SEH2_END;
+ }
+ }
+ else
+ {
+ _SEH2_TRY
+ {
+ /* loop through all mdls and probe them */
+ Mdl = Irp->MdlAddress;
+
+ /* determine operation */
+ Operation = (ProbeFlags & KSPROBE_STREAMWRITE) ? IoWriteAccess : IoReadAccess;
+
+ do
+ {
+ /* probe the pages */
+ MmProbeAndLockPages(Mdl, Irp->RequestorMode, Operation);
+
+ if (ProbeFlags & KSPROBE_SYSTEMADDRESS)
+ {
+ /* the mapping can fail */
+ Mdl->MdlFlags |= MDL_MAPPING_CAN_FAIL;
+
+ if (Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL))
+ {
+ /* no need to probe these pages */
+ Buffer = Mdl->MappedSystemVa;
+ }
+ else
+ {
+ /* probe that mdl */
+ Buffer = MmMapLockedPages(Mdl, KernelMode);
+ }
+
+ /* check if the mapping succeeded */
+ if (!Buffer)
+ {
+ /* raise exception we'll catch */
+ ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+ }
+ }
+
+ /* iterate to next mdl */
+ Mdl = Mdl->Next;
+
+ }while(Mdl);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
+ } _SEH2_END;
+ }
+ }
+ return Status;
+ }
+
+ /* check all stream headers */
+ StreamHeader = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
+ ASSERT(StreamHeader);
+ _SEH2_TRY
+ {
+ do
+ {
+ if (HeaderSize)
+ {
+ /* does the supplied header size match stream header size and no type changed */
+ if (StreamHeader->Size != HeaderSize && !(StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED))
+ {
+ /* invalid stream header */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+ }
+ else
+ {
+ /* stream must be at least of size KSSTREAM_HEADER and size must be 8-byte block aligned */
+ if (StreamHeader->Size < sizeof(KSSTREAM_HEADER) || (StreamHeader->Size & 7))
+ {
+ /* invalid stream header */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+ }
+
+ if (Length < StreamHeader->Size)
+ {
+ /* length is too short */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ if (ProbeFlags & KSPROBE_STREAMWRITE)
+ {
+ if (StreamHeader->DataUsed > StreamHeader->FrameExtent)
+ {
+ /* frame extend can never be smaller */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ /* is this stream change packet */
+ if (StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED)
+ {
+ if (Length != sizeof(KSSTREAM_HEADER) || (PVOID)StreamHeader != Irp->AssociatedIrp.SystemBuffer)
+ {
+ /* stream changed - must be send in a single packet */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ if (!(ProbeFlags & KSPROBE_ALLOWFORMATCHANGE))
+ {
+ /* caller does not permit format changes */
+ ExRaiseStatus(STATUS_INVALID_PARAMETER);
+ }
+
+ if (StreamHeader->FrameExtent)
+ {
+ /* allocate an mdl */
+ Mdl = IoAllocateMdl(StreamHeader->Data, StreamHeader->FrameExtent, FALSE, TRUE, Irp);
+
+ if (!Mdl)
+ {
+ /* not enough memory */
+ ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ /* break-out to probe for the irp */
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (StreamHeader->DataUsed)
+ {
+ /* DataUsed must be zero for stream read operation */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ if (StreamHeader->OptionsFlags)
+ {
+ /* no flags supported for reading */
+ ExRaiseStatus(STATUS_INVALID_PARAMETER);
+ }
+ }
+
+ if (StreamHeader->FrameExtent)
+ {
+ /* allocate an mdl */
+ Mdl = IoAllocateMdl(StreamHeader->Data, StreamHeader->FrameExtent, Irp->MdlAddress != NULL, TRUE, Irp);
+ if (!Mdl)
+ {
+ /* not enough memory */
+ ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+ }
+ }
+
+ /* move to next stream header */
+ Length -= StreamHeader->Size;
+ StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader + StreamHeader->Size);
+ }while(Length);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
+ }_SEH2_END;
+
+ /* now probe the allocated mdl's */
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Status %x\n", Status);
+ return Status;
+ }
+ else
+ goto ProbeMdl;
+ }
+
+#if 0
+ // HACK for MS PORTCLS
+ HeaderSize = Length;
+#endif
+ /* probe user mode buffers */
+ if (Length && ( (!HeaderSize) || (Length % HeaderSize == 0) || ((ProbeFlags & KSPROBE_ALLOWFORMATCHANGE) && (Length == sizeof(KSSTREAM_HEADER))) ) )
+ {
+ /* allocate stream header buffer */
+ Irp->AssociatedIrp.SystemBuffer = ExAllocatePool(NonPagedPool, Length);
+
+ if (!Irp->AssociatedIrp.SystemBuffer)
+ {
+ /* no memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ _SEH2_TRY
+ {
+ if (ProbeFlags & KSPROBE_STREAMWRITE)
+ {
+ if (ProbeFlags & KSPROBE_MODIFY)
+ ProbeForWrite(Irp->UserBuffer, Length, sizeof(UCHAR));
+ else
+ ProbeForRead(Irp->UserBuffer, Length, sizeof(UCHAR));
+ }
+ else
+ {
+ /* stream reads means writing */
+ ProbeForWrite(Irp->UserBuffer, Length, sizeof(UCHAR));
+ }
+
+ /* copy stream buffer */
+ RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, Irp->UserBuffer, Length);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
+ }_SEH2_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed */
+ return Status;
+ }
+
+ if (ProbeFlags & KSPROBE_ALLOCATEMDL)
+ {
+ /* alloc mdls */
+ goto AllocMdl;
+ }
+
+ /* check all stream headers */
+ StreamHeader = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
+
+ _SEH2_TRY
+ {
+ do
+ {
+ if (HeaderSize)
+ {
+ /* does the supplied header size match stream header size and no type changed */
+ if (StreamHeader->Size != HeaderSize && !(StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED))
+ {
+ /* invalid stream header */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+ }
+ else
+ {
+ /* stream must be at least of size KSSTREAM_HEADER and size must be 8-byte block aligned */
+ if (StreamHeader->Size < sizeof(KSSTREAM_HEADER) || (StreamHeader->Size & 7))
+ {
+ /* invalid stream header */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+ }
+
+ if (Length < StreamHeader->Size)
+ {
+ /* length is too short */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ if (ProbeFlags & KSPROBE_STREAMWRITE)
+ {
+ if (StreamHeader->DataUsed > StreamHeader->FrameExtent)
+ {
+ /* frame extend can never be smaller */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ /* is this stream change packet */
+ if (StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED)
+ {
+ if (Length != sizeof(KSSTREAM_HEADER) || (PVOID)StreamHeader != Irp->AssociatedIrp.SystemBuffer)
+ {
+ /* stream changed - must be send in a single packet */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ if (!(ProbeFlags & KSPROBE_ALLOWFORMATCHANGE))
+ {
+ /* caller does not permit format changes */
+ ExRaiseStatus(STATUS_INVALID_PARAMETER);
+ }
+
+ if (StreamHeader->FrameExtent)
+ {
+ /* allocate an mdl */
+ Mdl = IoAllocateMdl(StreamHeader->Data, StreamHeader->FrameExtent, FALSE, TRUE, Irp);
+
+ if (!Mdl)
+ {
+ /* not enough memory */
+ ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ /* break out to probe for the irp */
+ AllocateMdl = TRUE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (StreamHeader->DataUsed)
+ {
+ /* DataUsed must be zero for stream read operation */
+ ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
+ }
+
+ if (StreamHeader->OptionsFlags)
+ {
+ /* no flags supported for reading */
+ ExRaiseStatus(STATUS_INVALID_PARAMETER);
+ }
+ }
+
+ /* move to next stream header */
+ Length -= StreamHeader->Size;
+ StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader + StreamHeader->Size);
+ }while(Length);
+
+ }_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
+ }_SEH2_END;
+
+ /* now probe the allocated mdl's */
+ if (NT_SUCCESS(Status))
+ goto AllocMdl;
+ else
+ return Status;
+ }
+
+ return STATUS_INVALID_BUFFER_SIZE;
}
/*
- @unimplemented
+ @implemented
*/
-KSDDKAPI BOOLEAN NTAPI
-KsDispatchFastIoDeviceControlFailure(
- IN PFILE_OBJECT FileObject,
- IN BOOLEAN Wait,
- IN PVOID InputBuffer OPTIONAL,
- IN ULONG InputBufferLength,
- OUT PVOID OutputBuffer OPTIONAL,
- IN ULONG OutputBufferLength,
- IN ULONG IoControlCode,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject) /* always return false */
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsAllocateExtraData(
+ IN PIRP Irp,
+ IN ULONG ExtraSize,
+ OUT PVOID* ExtraBuffer)
{
- return FALSE;
+ PIO_STACK_LOCATION IoStack;
+ ULONG Count, Index;
+ PUCHAR Buffer, BufferOrg;
+ PKSSTREAM_HEADER Header;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* sanity check */
+ ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSSTREAM_HEADER));
+
+ /* get total length */
+ Count = IoStack->Parameters.DeviceIoControl.InputBufferLength / sizeof(KSSTREAM_HEADER);
+
+ /* allocate buffer */
+ Buffer = BufferOrg = AllocateItem(NonPagedPool, Count * (sizeof(KSSTREAM_HEADER) + ExtraSize));
+ if (!Buffer)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ _SEH2_TRY
+ {
+ /* get input buffer */
+ Header = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+ for(Index = 0; Index < Count; Index++)
+ {
+ /* copy stream header */
+ RtlMoveMemory(Buffer, Header, sizeof(KSSTREAM_HEADER));
+
+ /* move to next header */
+ Header++;
+ /* increment output buffer offset */
+ Buffer += sizeof(KSSTREAM_HEADER) + ExtraSize;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Exception, get the error code */
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* free buffer on exception */
+ FreeItem(Buffer);
+ return Status;
+ }
+
+ /* store result */
+ *ExtraBuffer = BufferOrg;
+
+ /* done */
+ return STATUS_SUCCESS;
}
/*
- @unimplemented
+ @implemented
*/
-KSDDKAPI BOOLEAN NTAPI
-KsDispatchFastReadFailure(
- IN PFILE_OBJECT FileObject,
- IN PLARGE_INTEGER FileOffset,
- IN ULONG Length,
- IN BOOLEAN Wait,
- IN ULONG LockKey,
- OUT PVOID Buffer,
- OUT PIO_STATUS_BLOCK IoStatus,
- IN PDEVICE_OBJECT DeviceObject) /* always return false */
+KSDDKAPI
+VOID
+NTAPI
+KsNullDriverUnload(
+ IN PDRIVER_OBJECT DriverObject)
{
- return FALSE;
}
/*
- Used in dispatch table entries that aren't handled and need to return
- STATUS_INVALID_DEVICE_REQUEST.
+ @implemented
*/
-KSDDKAPI NTSTATUS NTAPI
+KSDDKAPI
+NTSTATUS
+NTAPI
KsDispatchInvalidDeviceRequest(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
}
/*
- @unimplemented
-*/
-KSDDKAPI NTSTATUS NTAPI
-KsDispatchSpecificMethod(
- IN PIRP Irp,
- IN PFNKSHANDLER Handler)
-{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
-}
-
-/*
- @unimplemented
-*/
-KSDDKAPI NTSTATUS NTAPI
-KsDispatchSpecificProperty(
- IN PIRP Irp,
- IN PFNKSHANDLER Handler)
-{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
-}
-
-/*
- @unimplemented
+ @implemented
*/
-KSDDKAPI NTSTATUS NTAPI
-KsForwardAndCatchIrp(
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsDefaultDeviceIoCompletion(
IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PFILE_OBJECT FileObject,
- IN KSSTACK_USE StackUse)
-{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
-}
-
-/*
- @unimplemented
-*/
-KSDDKAPI NTSTATUS NTAPI
-KsForwardIrp(
- IN PIRP Irp,
- IN PFILE_OBJECT FileObject,
- IN BOOLEAN ReuseStackLocation)
+ IN PIRP Irp)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
-}
+ PIO_STACK_LOCATION IoStack;
+ NTSTATUS Status;
-/*
- @unimplemented
-*/
-KSDDKAPI NTSTATUS NTAPI
-KsGetChildCreateParameter(
- IN PIRP Irp,
- OUT PVOID* CreateParameter)
-{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
-}
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
-/*
- @unimplemented
-*/
-KSDDKAPI NTSTATUS NTAPI
-KsMoveIrpsOnCancelableQueue(
- IN OUT PLIST_ENTRY SourceList,
- IN PKSPIN_LOCK SourceLock,
- IN OUT PLIST_ENTRY DestinationList,
- IN PKSPIN_LOCK DestinationLock OPTIONAL,
- IN KSLIST_ENTRY_LOCATION ListLocation,
- IN PFNKSIRPLISTCALLBACK ListCallback,
- IN PVOID Context)
-{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
-}
+ if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY &&
+ IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_METHOD &&
+ IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
+ {
+ if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE)
+ {
+ /* fake success */
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ /* request unsupported */
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+ }
+ else
+ {
+ /* property / method / event not found */
+ Status = STATUS_PROPSET_NOT_FOUND;
+ }
-/*
- @unimplemented
-*/
-KSDDKAPI NTSTATUS NTAPI
-KsProbeStreamIrp(
- IN PIRP Irp,
- IN ULONG ProbeFlags,
- IN ULONG HeaderSize)
-{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
-}
+ /* complete request */
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
-/*
- @unimplemented
-*/
-KSDDKAPI NTSTATUS NTAPI
-KsQueryInformationFile(
- IN PFILE_OBJECT FileObject,
- OUT PVOID FileInformation,
- IN ULONG Length,
- IN FILE_INFORMATION_CLASS FileInformationClass)
-{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
+
+ return Status;
}
/*
- @unimplemented
+ @implemented
*/
-KSDDKAPI ACCESS_MASK NTAPI
-KsQueryObjectAccessMask(
- IN KSOBJECT_HEADER Header)
+KSDDKAPI
+BOOLEAN
+NTAPI
+KsDispatchFastIoDeviceControlFailure(
+ IN PFILE_OBJECT FileObject,
+ IN BOOLEAN Wait,
+ IN PVOID InputBuffer OPTIONAL,
+ IN ULONG InputBufferLength,
+ OUT PVOID OutputBuffer OPTIONAL,
+ IN ULONG OutputBufferLength,
+ IN ULONG IoControlCode,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
+ return FALSE;
}
/*
- @unimplemented
+ @implemented
*/
-KSDDKAPI PKSOBJECT_CREATE_ITEM NTAPI
-KsQueryObjectCreateItem(
- IN KSOBJECT_HEADER Header)
+KSDDKAPI
+BOOLEAN
+NTAPI
+KsDispatchFastReadFailure(
+ IN PFILE_OBJECT FileObject,
+ IN PLARGE_INTEGER FileOffset,
+ IN ULONG Length,
+ IN BOOLEAN Wait,
+ IN ULONG LockKey,
+ OUT PVOID Buffer,
+ OUT PIO_STATUS_BLOCK IoStatus,
+ IN PDEVICE_OBJECT DeviceObject)
{
- UNIMPLEMENTED;
-/* return STATUS_UNSUCCESSFUL; */
- return NULL;
+ return FALSE;
}
+
/*
- @unimplemented
+ @implemented
*/
-KSDDKAPI NTSTATUS NTAPI
-KsReadFile(
- IN PFILE_OBJECT FileObject,
- IN PKEVENT Event OPTIONAL,
- IN PVOID PortContext OPTIONAL,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- OUT PVOID Buffer,
- IN ULONG Length,
- IN ULONG Key OPTIONAL,
- IN KPROCESSOR_MODE RequestorMode)
+KSDDKAPI
+VOID
+NTAPI
+KsCancelIo(
+ IN OUT PLIST_ENTRY QueueHead,
+ IN PKSPIN_LOCK SpinLock)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
+ PDRIVER_CANCEL OldDriverCancel;
+ PIO_STACK_LOCATION IoStack;
+ PLIST_ENTRY Entry;
+ PLIST_ENTRY NextEntry;
+ PIRP Irp;
+ KIRQL OldLevel;
+
+ /* acquire spinlock */
+ KeAcquireSpinLock(SpinLock, &OldLevel);
+ /* point to first entry */
+ Entry = QueueHead->Flink;
+ /* loop all items */
+ while(Entry != QueueHead)
+ {
+ /* get irp offset */
+ Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
+
+ /* get next entry */
+ NextEntry = Entry->Flink;
+
+ /* set cancelled bit */
+ Irp->Cancel = TRUE;
+
+ /* now set the cancel routine */
+ OldDriverCancel = IoSetCancelRoutine(Irp, NULL);
+ if (OldDriverCancel)
+ {
+ /* this irp hasnt been yet used, so free to cancel */
+ KeReleaseSpinLock(SpinLock, OldLevel);
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* acquire cancel spinlock */
+ IoAcquireCancelSpinLock(&Irp->CancelIrql);
+
+ /* call provided cancel routine */
+ OldDriverCancel(IoStack->DeviceObject, Irp);
+
+ /* re-acquire spinlock */
+ KeAcquireSpinLock(SpinLock, &OldLevel);
+ }
+
+ /* move on to next entry */
+ Entry = NextEntry;
+ }
+
+ /* the irp has already been canceled */
+ KeReleaseSpinLock(SpinLock, OldLevel);
+
}
/*
- @unimplemented
+ @implemented
*/
-KSDDKAPI VOID NTAPI
+KSDDKAPI
+VOID
+NTAPI
KsReleaseIrpOnCancelableQueue(
IN PIRP Irp,
IN PDRIVER_CANCEL DriverCancel OPTIONAL)
{
- UNIMPLEMENTED;
+ PKSPIN_LOCK SpinLock;
+ PDRIVER_CANCEL OldDriverCancel;
+ PIO_STACK_LOCATION IoStack;
+ KIRQL OldLevel;
+
+ /* check for required parameters */
+ if (!Irp)
+ return;
+
+ if (!DriverCancel)
+ {
+ /* default to KsCancelRoutine */
+ DriverCancel = KsCancelRoutine;
+ }
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* get internal queue lock */
+ SpinLock = KSQUEUE_SPINLOCK_IRP_STORAGE(Irp);
+
+ /* acquire spinlock */
+ KeAcquireSpinLock(SpinLock, &OldLevel);
+
+ /* now set the cancel routine */
+ OldDriverCancel = IoSetCancelRoutine(Irp, DriverCancel);
+
+ if (Irp->Cancel && OldDriverCancel == NULL)
+ {
+ /* the irp has already been canceled */
+ KeReleaseSpinLock(SpinLock, OldLevel);
+
+ /* cancel routine requires that cancel spinlock is held */
+ IoAcquireCancelSpinLock(&Irp->CancelIrql);
+
+ /* cancel irp */
+ DriverCancel(IoStack->DeviceObject, Irp);
+ }
+ else
+ {
+ /* done */
+ KeReleaseSpinLock(SpinLock, OldLevel);
+ }
}
/*
IN KSLIST_ENTRY_LOCATION ListLocation,
IN KSIRP_REMOVAL_OPERATION RemovalOperation)
{
- PQUEUE_ENTRY Entry = NULL;
PIRP Irp;
+ PLIST_ENTRY CurEntry;
KIRQL OldIrql;
+ //DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation);
+
+ /* check parameters */
if (!QueueHead || !SpinLock)
return NULL;
+ /* check if parameter ListLocation is valid */
if (ListLocation != KsListEntryTail && ListLocation != KsListEntryHead)
return NULL;
- if (RemovalOperation != KsAcquireOnly && RemovalOperation != KsAcquireAndRemove)
- return NULL;
-
+ /* acquire list lock */
KeAcquireSpinLock(SpinLock, &OldIrql);
- if (!IsListEmpty(QueueHead))
+ /* point to queue head */
+ CurEntry = QueueHead;
+
+ do
{
- if (RemovalOperation == KsAcquireOnly)
+ /* reset irp to null */
+ Irp = NULL;
+
+ /* iterate to next entry */
+ if (ListLocation == KsListEntryHead)
+ CurEntry = CurEntry->Flink;
+ else
+ CurEntry = CurEntry->Blink;
+
+ /* is the end of list reached */
+ if (CurEntry == QueueHead)
{
- if (ListLocation == KsListEntryHead)
- Entry = (PQUEUE_ENTRY)QueueHead->Flink;
- else
- Entry = (PQUEUE_ENTRY)QueueHead->Blink;
+ /* reached end of list */
+ break;
}
- else if (RemovalOperation == KsAcquireAndRemove)
+
+ /* get irp offset */
+ Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
+
+ if (Irp->Cancel)
{
- if (ListLocation == KsListEntryTail)
- Entry = (PQUEUE_ENTRY)RemoveTailList(QueueHead);
- else
- Entry = (PQUEUE_ENTRY)RemoveHeadList(QueueHead);
+ /* irp has been canceled */
+ break;
}
- }
+
+ if (Irp->CancelRoutine)
+ {
+ /* remove cancel routine */
+ Irp->CancelRoutine = NULL;
+
+ if (RemovalOperation == KsAcquireAndRemove || RemovalOperation == KsAcquireAndRemoveOnlySingleItem)
+ {
+ /* remove irp from list */
+ RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+ }
+
+ if (RemovalOperation == KsAcquireAndRemoveOnlySingleItem || RemovalOperation == KsAcquireOnlySingleItem)
+ break;
+ }
+
+ }while(TRUE);
+
+ /* release lock */
KeReleaseSpinLock(SpinLock, OldIrql);
- if (!Entry)
- return NULL;
+ if (!Irp || Irp->CancelRoutine == NULL)
+ {
+ /* either an irp has been acquired or nothing found */
+ return Irp;
+ }
- Irp = Entry->Irp;
+ /* time to remove the canceled irp */
+ IoAcquireCancelSpinLock(&OldIrql);
+ /* acquire list lock */
+ KeAcquireSpinLockAtDpcLevel(SpinLock);
- if (RemovalOperation == KsAcquireAndRemove)
- ExFreePool(Entry);
+ if (RemovalOperation == KsAcquireAndRemove || RemovalOperation == KsAcquireAndRemoveOnlySingleItem)
+ {
+ /* remove it */
+ RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+ }
- return Irp;
-}
+ /* release list lock */
+ KeReleaseSpinLockFromDpcLevel(SpinLock);
-/*
- @unimplemented
-*/
-KSDDKAPI VOID NTAPI
-KsRemoveSpecificIrpFromCancelableQueue(
- IN PIRP Irp)
-{
- UNIMPLEMENTED;
+ /* release cancel spinlock */
+ IoReleaseCancelSpinLock(OldIrql);
+ /* no non canceled irp has been found */
+ return NULL;
}
/*
- @unimplemented
+ @implemented
*/
-KSDDKAPI NTSTATUS NTAPI
-KsSetInformationFile(
- IN PFILE_OBJECT FileObject,
- IN PVOID FileInformation,
- IN ULONG Length,
- IN FILE_INFORMATION_CLASS FileInformationClass)
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsMoveIrpsOnCancelableQueue(
+ IN OUT PLIST_ENTRY SourceList,
+ IN PKSPIN_LOCK SourceLock,
+ IN OUT PLIST_ENTRY DestinationList,
+ IN PKSPIN_LOCK DestinationLock OPTIONAL,
+ IN KSLIST_ENTRY_LOCATION ListLocation,
+ IN PFNKSIRPLISTCALLBACK ListCallback,
+ IN PVOID Context)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
-}
+ KIRQL OldLevel;
+ PLIST_ENTRY SrcEntry;
+ PIRP Irp;
+ NTSTATUS Status = STATUS_SUCCESS;
+ if (!DestinationLock)
+ {
+ /* no destination lock just acquire the source lock */
+ KeAcquireSpinLock(SourceLock, &OldLevel);
+ }
+ else
+ {
+ /* acquire cancel spinlock */
+ IoAcquireCancelSpinLock(&OldLevel);
+ /* now acquire source lock */
+ KeAcquireSpinLockAtDpcLevel(SourceLock);
-NTAPI
-NTSTATUS
-KsCreate(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- //PIO_STACK_LOCATION IoStack;
- PDEVICE_EXTENSION DeviceExtension;
- PKSIDEVICE_HEADER DeviceHeader;
- ULONG Index;
- NTSTATUS Status = STATUS_SUCCESS;
- KIRQL OldLevel;
+ /* now acquire destination lock */
+ KeAcquireSpinLockAtDpcLevel(DestinationLock);
+ }
- DPRINT("KS / CREATE\n");
- /* get current stack location */
- //IoStack = IoGetCurrentIrpStackLocation(Irp);
- /* get device extension */
- DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
- /* get device header */
- DeviceHeader = DeviceExtension->DeviceHeader;
+ /* point to list head */
+ SrcEntry = SourceList;
- /* acquire list lock */
- KeAcquireSpinLock(&DeviceHeader->ItemListLock, &OldLevel);
- /* loop all device items */
- for(Index = 0; Index < DeviceHeader->MaxItems; Index++)
+ /* now move all irps */
+ while(TRUE)
{
- if (DeviceHeader->ItemList[Index].bCreated && DeviceHeader->ItemList[Index].ObjectHeader == NULL)
+ if (ListLocation == KsListEntryTail)
+ {
+ /* move queue downwards */
+ SrcEntry = SrcEntry->Flink;
+ }
+ else
+ {
+ /* move queue upwards */
+ SrcEntry = SrcEntry->Blink;
+ }
+
+ if (SrcEntry == SourceList)
+ {
+ /* eof list reached */
+ break;
+ }
+
+ /* get irp offset */
+ Irp = (PIRP)CONTAINING_RECORD(SrcEntry, IRP, Tail.Overlay.ListEntry);
+
+ /* now check if irp can be moved */
+ Status = ListCallback(Irp, Context);
+
+ /* check if irp can be moved */
+ if (Status == STATUS_SUCCESS)
+ {
+ /* remove irp from src list */
+ RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+
+ if (ListLocation == KsListEntryTail)
+ {
+ /* insert irp end of list */
+ InsertTailList(DestinationList, &Irp->Tail.Overlay.ListEntry);
+ }
+ else
+ {
+ /* insert irp head of list */
+ InsertHeadList(DestinationList, &Irp->Tail.Overlay.ListEntry);
+ }
+
+ /* do we need to update the irp lock */
+ if (DestinationLock)
+ {
+ /* update irp lock */
+ KSQUEUE_SPINLOCK_IRP_STORAGE(Irp) = DestinationLock;
+ }
+ }
+ else
{
- DeviceHeader->DeviceIndex = Index;
- /* set object create item */
- KSCREATE_ITEM_IRP_STORAGE(Irp) = &DeviceHeader->ItemList[Index].CreateItem;
- Status = DeviceHeader->ItemList[Index].CreateItem.Create(DeviceObject, Irp);
-
- /* FIXME IoRegisterDeviceInterface does not support reference strings */
- /* FIXME Check the irp target with the create item's object class */
- if (NT_SUCCESS(Status))
+ if (Status != STATUS_NO_MATCH)
{
- /* release lock */
- KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
- return Status;
+ /* callback decided to stop enumeration */
+ break;
}
+
+ /* reset return value */
+ Status = STATUS_SUCCESS;
}
}
- /* release lock */
- KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
+ if (!DestinationLock)
+ {
+ /* release source lock */
+ KeReleaseSpinLock(SourceLock, OldLevel);
+ }
+ else
+ {
+ /* now release destination lock */
+ KeReleaseSpinLockFromDpcLevel(DestinationLock);
+
+ /* now release source lock */
+ KeReleaseSpinLockFromDpcLevel(SourceLock);
+
+
+ /* now release cancel spinlock */
+ IoReleaseCancelSpinLock(OldLevel);
+ }
+
+ /* done */
return Status;
}
-static NTAPI
-NTSTATUS
-KsClose(
- IN PDEVICE_OBJECT DeviceObject,
+/*
+ @implemented
+*/
+KSDDKAPI
+VOID
+NTAPI
+KsRemoveSpecificIrpFromCancelableQueue(
IN PIRP Irp)
{
+ PKSPIN_LOCK SpinLock;
+ KIRQL OldLevel;
+
+ DPRINT("KsRemoveSpecificIrpFromCancelableQueue %p\n", Irp);
+
+ /* get internal queue lock */
+ SpinLock = KSQUEUE_SPINLOCK_IRP_STORAGE(Irp);
+
+ /* acquire spinlock */
+ KeAcquireSpinLock(SpinLock, &OldLevel);
+
+ /* remove the irp from the list */
+ RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+
+ /* release spinlock */
+ KeReleaseSpinLock(SpinLock, OldLevel);
+}
+
+
+/*
+ @implemented
+*/
+KSDDKAPI
+VOID
+NTAPI
+KsAddIrpToCancelableQueue(
+ IN OUT PLIST_ENTRY QueueHead,
+ IN PKSPIN_LOCK SpinLock,
+ IN PIRP Irp,
+ IN KSLIST_ENTRY_LOCATION ListLocation,
+ IN PDRIVER_CANCEL DriverCancel OPTIONAL)
+{
+ PDRIVER_CANCEL OldDriverCancel;
PIO_STACK_LOCATION IoStack;
- PKSIOBJECT_HEADER ObjectHeader;
+ KIRQL OldLevel;
+
+ DPRINT("KsAddIrpToCancelableQueue QueueHead %p SpinLock %p Irp %p ListLocation %x DriverCancel %p\n", QueueHead, SpinLock, Irp, ListLocation, DriverCancel);
+ /* check for required parameters */
+ if (!QueueHead || !SpinLock || !Irp)
+ return;
+
+ if (!DriverCancel)
+ {
+ /* default to KsCancelRoutine */
+ DriverCancel = KsCancelRoutine;
+ }
- /* get current stack location */
+ /* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
- DPRINT("KS / CLOSE\n");
+ /* acquire spinlock */
+ KeAcquireSpinLock(SpinLock, &OldLevel);
- if (IoStack->FileObject && IoStack->FileObject->FsContext)
+ if (ListLocation == KsListEntryTail)
{
- ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
-
- KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
- return ObjectHeader->DispatchTable.Close(DeviceObject, Irp);
+ /* insert irp to tail of list */
+ InsertTailList(QueueHead, &Irp->Tail.Overlay.ListEntry);
}
else
{
- DPRINT1("Expected Object Header\n");
- return STATUS_SUCCESS;
+ /* insert irp to head of list */
+ InsertHeadList(QueueHead, &Irp->Tail.Overlay.ListEntry);
}
-}
-static NTAPI
-NTSTATUS
-KsDeviceControl(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IoStack;
- PKSIOBJECT_HEADER ObjectHeader;
+ /* store internal queue lock */
+ KSQUEUE_SPINLOCK_IRP_STORAGE(Irp) = SpinLock;
- /* get current stack location */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
+ /* now set the cancel routine */
+ OldDriverCancel = IoSetCancelRoutine(Irp, DriverCancel);
- DPRINT("KS / DeviceControl\n");
- if (IoStack->FileObject && IoStack->FileObject->FsContext)
+ if (Irp->Cancel && OldDriverCancel == NULL)
{
- ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
+ /* the irp has already been canceled */
+ KeReleaseSpinLock(SpinLock, OldLevel);
- KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
- return ObjectHeader->DispatchTable.DeviceIoControl(DeviceObject, Irp);
+ /* cancel routine requires that cancel spinlock is held */
+ IoAcquireCancelSpinLock(&Irp->CancelIrql);
+
+ /* cancel irp */
+ DriverCancel(IoStack->DeviceObject, Irp);
}
else
{
- DPRINT1("Expected Object Header\n");
- KeBugCheckEx(0, 0, 0, 0, 0);
- return STATUS_SUCCESS;
+ /* done */
+ KeReleaseSpinLock(SpinLock, OldLevel);
}
}
-static NTAPI
-NTSTATUS
-KsRead(
+/*
+ @implemented
+*/
+KSDDKAPI
+VOID
+NTAPI
+KsCancelRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- PIO_STACK_LOCATION IoStack;
- PKSIOBJECT_HEADER ObjectHeader;
+ PKSPIN_LOCK SpinLock;
- /* get current stack location */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
+ /* get internal queue lock */
+ SpinLock = KSQUEUE_SPINLOCK_IRP_STORAGE(Irp);
- DPRINT("KS / Read\n");
- if (IoStack->FileObject && IoStack->FileObject->FsContext)
- {
- ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
+ /* acquire spinlock */
+ KeAcquireSpinLockAtDpcLevel(SpinLock);
- KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
- return ObjectHeader->DispatchTable.Read(DeviceObject, Irp);
- }
- else
+ /* sanity check */
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ /* release cancel spinlock */
+ IoReleaseCancelSpinLock(Irp->CancelIrql);
+
+ /* remove the irp from the list */
+ RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+
+ /* release spinlock */
+ KeReleaseSpinLock(SpinLock, Irp->CancelIrql);
+
+ /* has the irp already been canceled */
+ if (Irp->IoStatus.Status != STATUS_CANCELLED)
{
- DPRINT1("Expected Object Header\n");
- KeBugCheckEx(0, 0, 0, 0, 0);
- return STATUS_SUCCESS;
+ /* let's complete it */
+ Irp->IoStatus.Status = STATUS_CANCELLED;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
}
-static NTAPI
NTSTATUS
-KsWrite(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+FindMatchingCreateItem(
+ PLIST_ENTRY ListHead,
+ ULONG BufferSize,
+ LPWSTR Buffer,
+ OUT PCREATE_ITEM_ENTRY *OutCreateItem)
{
- PIO_STACK_LOCATION IoStack;
- PKSIOBJECT_HEADER ObjectHeader;
+ PLIST_ENTRY Entry;
+ PCREATE_ITEM_ENTRY CreateItemEntry;
+ UNICODE_STRING RefString;
- /* get current stack location */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
- DPRINT("KS / Write\n");
- if (IoStack->FileObject && IoStack->FileObject->FsContext)
- {
- ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
+#ifndef MS_KSUSER
+ /* remove '\' slash */
+ Buffer++;
+ BufferSize -= sizeof(WCHAR);
+#endif
- KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
- return ObjectHeader->DispatchTable.Write(DeviceObject, Irp);
+ if (!wcschr(Buffer, L'\\'))
+ {
+ RtlInitUnicodeString(&RefString, Buffer);
}
else
{
- DPRINT1("Expected Object Header %p\n", IoStack->FileObject);
- KeBugCheckEx(0, 0, 0, 0, 0);
- return STATUS_SUCCESS;
+ RefString.Buffer = Buffer;
+ RefString.Length = RefString.MaximumLength = ((ULONG_PTR)wcschr(Buffer, L'\\') - (ULONG_PTR)Buffer);
}
-}
-
-static NTAPI
-NTSTATUS
-KsFlushBuffers(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- PIO_STACK_LOCATION IoStack;
- PKSIOBJECT_HEADER ObjectHeader;
- /* get current stack location */
- IoStack = IoGetCurrentIrpStackLocation(Irp);
+ /* point to first entry */
+ Entry = ListHead->Flink;
- DPRINT("KS / FlushBuffers\n");
- if (IoStack->FileObject && IoStack->FileObject->FsContext)
+ /* loop all device items */
+ while(Entry != ListHead)
{
- ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
+ /* get create item entry */
+ CreateItemEntry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(Entry, CREATE_ITEM_ENTRY, Entry);
- 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;
+ ASSERT(CreateItemEntry->CreateItem);
+
+ if(CreateItemEntry->CreateItem->Flags & KSCREATE_ITEM_WILDCARD)
+ {
+ /* create item is default */
+ *OutCreateItem = CreateItemEntry;
+ return STATUS_SUCCESS;
+ }
+
+ if (!CreateItemEntry->CreateItem->Create)
+ {
+ /* skip free create item */
+ Entry = Entry->Flink;
+ continue;
+ }
+
+ ASSERT(CreateItemEntry->CreateItem->ObjectClass.Buffer);
+
+ DPRINT("CreateItem %S Length %u Request %wZ %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer,
+ CreateItemEntry->CreateItem->ObjectClass.Length,
+ &RefString,
+ BufferSize);
+
+ if (CreateItemEntry->CreateItem->ObjectClass.Length > BufferSize)
+ {
+ /* create item doesnt match in length */
+ Entry = Entry->Flink;
+ continue;
+ }
+
+ /* now check if the object class is the same */
+ if (!RtlCompareUnicodeString(&CreateItemEntry->CreateItem->ObjectClass, &RefString, TRUE))
+ {
+ /* found matching create item */
+ *OutCreateItem = CreateItemEntry;
+ return STATUS_SUCCESS;
+ }
+ /* iterate to next */
+ Entry = Entry->Flink;
}
+
+ return STATUS_NOT_FOUND;
}
-static NTAPI
NTSTATUS
-KsQuerySecurity(
+NTAPI
+KspCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
+ PCREATE_ITEM_ENTRY CreateItemEntry;
PIO_STACK_LOCATION IoStack;
+ PDEVICE_EXTENSION DeviceExtension;
+ PKSIDEVICE_HEADER DeviceHeader;
PKSIOBJECT_HEADER ObjectHeader;
+ NTSTATUS Status;
+
+ DPRINT("KS / CREATE\n");
/* get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
+ /* get device extension */
+ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ /* get device header */
+ DeviceHeader = DeviceExtension->DeviceHeader;
+
- DPRINT("KS / QuerySecurity\n");
- if (IoStack->FileObject && IoStack->FileObject->FsContext)
+ if (IoStack->FileObject->FileName.Buffer == NULL)
{
- ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
+ /* FIXME Pnp-Issue */
+ DPRINT("Using reference string hack\n");
+ Irp->IoStatus.Information = 0;
+ /* set return status */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+
+ if (IoStack->FileObject->RelatedFileObject != NULL)
+ {
+ /* request is to instantiate a pin / node / clock / allocator */
+ ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->RelatedFileObject->FsContext2;
- KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
- return ObjectHeader->DispatchTable.QuerySecurity(DeviceObject, Irp);
+ /* sanity check */
+ ASSERT(ObjectHeader);
+
+ /* find a matching a create item */
+ Status = FindMatchingCreateItem(&ObjectHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry);
}
else
{
- DPRINT1("Expected Object Header\n");
- KeBugCheckEx(0, 0, 0, 0, 0);
- return STATUS_SUCCESS;
+ /* request to create a filter */
+ Status = FindMatchingCreateItem(&DeviceHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry);
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ /* set object create item */
+ KSCREATE_ITEM_IRP_STORAGE(Irp) = CreateItemEntry->CreateItem;
+
+ /* call create function */
+ Status = CreateItemEntry->CreateItem->Create(DeviceObject, Irp);
+
+ if (NT_SUCCESS(Status))
+ {
+ /* increment create item reference count */
+ InterlockedIncrement(&CreateItemEntry->ReferenceCount);
+ }
+ return Status;
}
+
+ Irp->IoStatus.Information = 0;
+ /* set return status */
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_UNSUCCESSFUL;
}
-static NTAPI
NTSTATUS
-KsSetSecurity(
+NTAPI
+KspDispatchIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
+ PDEVICE_EXTENSION DeviceExtension;
PKSIOBJECT_HEADER ObjectHeader;
+ PKSIDEVICE_HEADER DeviceHeader;
+ PDRIVER_DISPATCH Dispatch;
+ NTSTATUS Status;
/* get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
- DPRINT("KS / SetSecurity\n");
- if (IoStack->FileObject && IoStack->FileObject->FsContext)
- {
- ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
+ /* get device extension */
+ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ /* get device header */
+ DeviceHeader = DeviceExtension->DeviceHeader;
- KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
- return ObjectHeader->DispatchTable.SetSecurity(DeviceObject, Irp);
- }
- else
+ ASSERT(IoStack->FileObject);
+
+ /* get object header */
+ ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext2;
+
+ if (!ObjectHeader)
{
- DPRINT1("Expected Object Header\n");
- KeBugCheckEx(0, 0, 0, 0, 0);
+ /* FIXME Pnp-Issue*/
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+ /* complete and forget */
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
-}
-
-/*
- @implemented
-*/
-KSDDKAPI NTSTATUS NTAPI
-KsSetMajorFunctionHandler(
- IN PDRIVER_OBJECT DriverObject,
- IN ULONG MajorFunction)
-{
- /*
- Sets a DriverObject's major function handler to point to an internal
- function we implement.
- TODO: Deal with KSDISPATCH_FASTIO
- */
+ /* sanity check */
+ ASSERT(ObjectHeader);
+ /* store create item */
+ //KSCREATE_ITEM_IRP_STORAGE(Irp) = (PKSOBJECT_CREATE_ITEM)0x12345678; //ObjectHeader->CreateItem;
- switch ( MajorFunction )
+ /* retrieve matching dispatch function */
+ switch(IoStack->MajorFunction)
{
- case IRP_MJ_CREATE:
- DriverObject->MajorFunction[MajorFunction] = KsCreate;
- break;
case IRP_MJ_CLOSE:
- DriverObject->MajorFunction[MajorFunction] = KsClose;
+ Dispatch = ObjectHeader->DispatchTable.Close;
break;
case IRP_MJ_DEVICE_CONTROL:
- DriverObject->MajorFunction[MajorFunction] = KsDeviceControl;
+ Dispatch = ObjectHeader->DispatchTable.DeviceIoControl;
break;
case IRP_MJ_READ:
- DriverObject->MajorFunction[MajorFunction] = KsRead;
+ Dispatch = ObjectHeader->DispatchTable.Read;
break;
case IRP_MJ_WRITE:
- DriverObject->MajorFunction[MajorFunction] = KsWrite;
+ Dispatch = ObjectHeader->DispatchTable.Write;
break;
case IRP_MJ_FLUSH_BUFFERS :
- DriverObject->MajorFunction[MajorFunction] = KsFlushBuffers;
+ Dispatch = ObjectHeader->DispatchTable.Flush;
break;
case IRP_MJ_QUERY_SECURITY:
- DriverObject->MajorFunction[MajorFunction] = KsQuerySecurity;
+ Dispatch = ObjectHeader->DispatchTable.QuerySecurity;
break;
case IRP_MJ_SET_SECURITY:
- DriverObject->MajorFunction[MajorFunction] = KsSetSecurity;
+ Dispatch = ObjectHeader->DispatchTable.SetSecurity;
break;
-
+ case IRP_MJ_PNP:
+ Dispatch = KsDefaultDispatchPnp;
default:
- return STATUS_INVALID_PARAMETER; /* is this right? */
- };
+ Dispatch = NULL;
+ }
- return STATUS_SUCCESS;
+ /* is the request supported */
+ if (Dispatch)
+ {
+ /* now call the dispatch function */
+ Status = Dispatch(DeviceObject, Irp);
+ }
+ else
+ {
+ /* not supported request */
+ Status = KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
+ }
+
+ /* done */
+ return Status;
}
/*
KSDDKAPI
NTSTATUS
NTAPI
-KsDispatchIrp(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
+KsSetMajorFunctionHandler(
+ IN PDRIVER_OBJECT DriverObject,
+ IN ULONG MajorFunction)
{
- PIO_STACK_LOCATION IoStack;
-
- /* Calls a dispatch routine corresponding to the function code of the IRP */
- /*
- First we need to get the dispatch table. An opaque header is pointed to by
- FsContext. The first element points to this table. This table is the key
- to dispatching the IRP correctly.
- */
-
- IoStack = IoGetCurrentIrpStackLocation(Irp);
- DPRINT("KsDispatchIrp %x\n", IoStack->MajorFunction);
+ DPRINT("KsSetMajorFunctionHandler Function %x\n", MajorFunction);
+#if 1
+ // HACK
+ // for MS PORTCLS
+ //
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = KspCreate;
+#endif
- switch (IoStack->MajorFunction)
+ switch ( MajorFunction )
{
case IRP_MJ_CREATE:
- return KsCreate(DeviceObject, Irp);
- case IRP_MJ_CLOSE:
- return KsClose(DeviceObject, Irp);
+ DriverObject->MajorFunction[MajorFunction] = KspCreate;
break;
case IRP_MJ_DEVICE_CONTROL:
- return KsDeviceControl(DeviceObject, Irp);
- break;
+ case IRP_MJ_CLOSE:
case IRP_MJ_READ:
- return KsRead(DeviceObject, Irp);
- break;
case IRP_MJ_WRITE:
- return KsWrite(DeviceObject, Irp);
- break;
- case IRP_MJ_FLUSH_BUFFERS:
- return KsFlushBuffers(DeviceObject, Irp);
- break;
+ case IRP_MJ_FLUSH_BUFFERS :
case IRP_MJ_QUERY_SECURITY:
- return KsQuerySecurity(DeviceObject, Irp);
- break;
case IRP_MJ_SET_SECURITY:
- return KsSetSecurity(DeviceObject, Irp);
+ DriverObject->MajorFunction[MajorFunction] = KspDispatchIrp;
break;
default:
- return STATUS_INVALID_PARAMETER; /* is this right? */
+ DPRINT1("NotSupported %x\n", MajorFunction);
+ return STATUS_INVALID_PARAMETER;
};
-}
+ return STATUS_SUCCESS;
+}
/*
@implemented
KSDDKAPI
NTSTATUS
NTAPI
-KsStreamIo(
- IN PFILE_OBJECT FileObject,
- IN PKEVENT Event OPTIONAL,
- IN PVOID PortContext OPTIONAL,
- IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
- IN PVOID CompletionContext OPTIONAL,
- IN KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- IN OUT PVOID StreamHeaders,
- IN ULONG Length,
- IN ULONG Flags,
- IN KPROCESSOR_MODE RequestorMode)
+KsDispatchIrp(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
{
- PIRP Irp;
PIO_STACK_LOCATION IoStack;
- PDEVICE_OBJECT DeviceObject;
- ULONG Code;
- NTSTATUS Status;
- LARGE_INTEGER Offset;
- PKSIOBJECT_HEADER ObjectHeader;
+ PKSIDEVICE_HEADER DeviceHeader;
+ PDEVICE_EXTENSION DeviceExtension;
+ //DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp);
- if (Flags == KSSTREAM_READ)
- Code = IRP_MJ_READ;
- else if (Flags == KSSTREAM_WRITE)
- Code = IRP_MJ_WRITE;
- else
- return STATUS_INVALID_PARAMETER;
+ /* get device extension */
+ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ /* get device header */
+ DeviceHeader = DeviceExtension->DeviceHeader;
- DeviceObject = IoGetRelatedDeviceObject(FileObject);
- if (!DeviceObject)
- return STATUS_INVALID_PARAMETER;
- if (Event)
- {
- KeResetEvent(Event);
- }
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
- //ASSERT(DeviceObject->DeviceType == FILE_DEVICE_KS);
- ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext;
- ASSERT(ObjectHeader);
- if (Code == IRP_MJ_READ)
+ if (IoStack->MajorFunction <= IRP_MJ_DEVICE_CONTROL)
{
- if (ObjectHeader->DispatchTable.FastRead)
+ if (IoStack->MajorFunction == IRP_MJ_CREATE)
{
- if (ObjectHeader->DispatchTable.FastRead(FileObject, NULL, Length, FALSE, 0, StreamHeaders, IoStatusBlock, DeviceObject))
+ /* check internal type */
+ if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
{
- return STATUS_SUCCESS;
+ /* AVStream client */
+ return IKsDevice_Create(DeviceObject, Irp);
}
+ else
+ {
+ /* external client (portcls) */
+ return KspCreate(DeviceObject, Irp);
+ }
+ }
+
+ switch (IoStack->MajorFunction)
+ {
+ case IRP_MJ_CLOSE:
+ case IRP_MJ_READ:
+ case IRP_MJ_WRITE:
+ case IRP_MJ_FLUSH_BUFFERS:
+ case IRP_MJ_QUERY_SECURITY:
+ case IRP_MJ_SET_SECURITY:
+ case IRP_MJ_PNP:
+ case IRP_MJ_DEVICE_CONTROL:
+ return KspDispatchIrp(DeviceObject, Irp);
+ default:
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
}
- else
+
+ /* dispatch power */
+ if (IoStack->MajorFunction == IRP_MJ_POWER)
{
- if (ObjectHeader->DispatchTable.FastWrite)
+ /* check internal type */
+ if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
{
- if (ObjectHeader->DispatchTable.FastWrite(FileObject, NULL, Length, FALSE, 0, StreamHeaders, IoStatusBlock, DeviceObject))
- {
- return STATUS_SUCCESS;
- }
+ /* AVStream client */
+ return IKsDevice_Power(DeviceObject, Irp);
+ }
+ else
+ {
+ /* external client (portcls) */
+ return KsDefaultDispatchPower(DeviceObject, Irp);
}
}
-
- Offset.QuadPart = 0LL;
- Irp = IoBuildSynchronousFsdRequest(Code, DeviceObject, (PVOID)StreamHeaders, Length, &Offset, Event, IoStatusBlock);
- if (!Irp)
+ else if (IoStack->MajorFunction == IRP_MJ_PNP) /* dispatch pnp */
{
- return STATUS_UNSUCCESSFUL;
+ /* check internal type */
+ if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
+ {
+ /* AVStream client */
+ return IKsDevice_Pnp(DeviceObject, Irp);
+ }
+ else
+ {
+ /* external client (portcls) */
+ return KsDefaultDispatchPnp(DeviceObject, Irp);
+ }
}
-
-
- if (CompletionRoutine)
+ else if (IoStack->MajorFunction == IRP_MJ_SYSTEM_CONTROL)
{
- IoSetCompletionRoutine(Irp,
- CompletionRoutine,
- CompletionContext,
- (CompletionInvocationFlags & KsInvokeOnSuccess),
- (CompletionInvocationFlags & KsInvokeOnError),
- (CompletionInvocationFlags & KsInvokeOnCancel));
+ /* forward irp */
+ return KsDefaultForwardIrp(DeviceObject, Irp);
+ }
+ else
+ {
+ /* not supported */
+ return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
}
-
- IoStack = IoGetNextIrpStackLocation(Irp);
- IoStack->FileObject = FileObject;
-
- Status = IoCallDriver(DeviceObject, Irp);
- return Status;
-}
-
-/*
- @unimplemented
-*/
-KSDDKAPI NTSTATUS NTAPI
-KsWriteFile(
- IN PFILE_OBJECT FileObject,
- IN PKEVENT Event OPTIONAL,
- IN PVOID PortContext OPTIONAL,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- IN PVOID Buffer,
- IN ULONG Length,
- IN ULONG Key OPTIONAL,
- IN KPROCESSOR_MODE RequestorMode)
-{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
}
/*
@unimplemented
*/
-KSDDKAPI NTSTATUS NTAPI
-KsDefaultForwardIrp(
- IN PDEVICE_OBJECT DeviceObject,
+KSDDKAPI
+ULONG
+NTAPI
+KsGetNodeIdFromIrp(
IN PIRP Irp)
{
- UNIMPLEMENTED;
- Irp->IoStatus.Information = 0;
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_UNSUCCESSFUL;
+ UNIMPLEMENTED
+ return KSFILTER_NODE;
}