[AUDIO-BRINGUP]

- Move software bus functions into swenum.c
- Add missing #undef INTERFACE in ksiface.h
- Partly implement KsRemoveBusEnumInterface
- Implement KsServiceBusEnumPnpRequest, KsServiceBusEnumCreateRequest, KsIsBusEnumChildDevice, KsInstallBusEnumInterface, KsGetBusEnumPnpDeviceObject, KsCreateBusEnumObject, KsGetBusEnumParentFDOFromChildPDO, KsGetBusEnumIdentifier
- KS now supports the software bus driver
- As a side effect, ks.sys now fully works in Windows XP
- Tested with VBox+WINXP SP3+

svn path=/branches/audio-bringup/; revision=50067
This commit is contained in:
Johannes Anderwald 2010-12-20 02:45:18 +00:00
parent 219cbd064d
commit 8baebdbded
6 changed files with 2047 additions and 452 deletions

View file

@ -1723,147 +1723,8 @@ KsCompletePendingRequest(
}
/*
@implemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsCreateBusEnumObject(
IN PWCHAR BusIdentifier,
IN PDEVICE_OBJECT BusDeviceObject,
IN PDEVICE_OBJECT PhysicalDeviceObject,
IN PDEVICE_OBJECT PnpDeviceObject OPTIONAL,
IN REFGUID InterfaceGuid OPTIONAL,
IN PWCHAR ServiceRelativePath OPTIONAL)
{
ULONG Length;
NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING ServiceKeyPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\");
PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
PDEVICE_EXTENSION DeviceExtension;
DPRINT1("KsCreateBusEnumObject %S\n", ServiceRelativePath);
DbgBreakPoint();
/* calculate sizeof bus enum device extension */
Length = wcslen(BusIdentifier) * sizeof(WCHAR);
Length += sizeof(BUS_ENUM_DEVICE_EXTENSION);
BusDeviceExtension = AllocateItem(NonPagedPool, Length);
if (!BusDeviceExtension)
{
/* not enough memory */
return STATUS_INSUFFICIENT_RESOURCES;
}
/* zero device extension */
RtlZeroMemory(BusDeviceExtension, sizeof(BUS_ENUM_DEVICE_EXTENSION));
/* store bus device extension */
*((PVOID*)BusDeviceObject->DeviceExtension) = BusDeviceExtension;
/* initialize bus device extension */
wcscpy(BusDeviceExtension->BusIdentifier, BusIdentifier);
/* allocate service path string */
Length = ServiceKeyPath.MaximumLength;
Length += BusDeviceObject->DriverObject->DriverExtension->ServiceKeyName.MaximumLength;
if (ServiceRelativePath)
{
/* relative path for devices */
Length += (wcslen(ServiceRelativePath) + 2) * sizeof(WCHAR);
}
BusDeviceExtension->ServicePath.Length = 0;
BusDeviceExtension->ServicePath.MaximumLength = Length;
BusDeviceExtension->ServicePath.Buffer = AllocateItem(NonPagedPool, Length);
if (!BusDeviceExtension->ServicePath.Buffer)
{
/* not enough memory */
FreeItem(BusDeviceExtension);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlAppendUnicodeStringToString(&BusDeviceExtension->ServicePath, &ServiceKeyPath);
RtlAppendUnicodeStringToString(&BusDeviceExtension->ServicePath, &BusDeviceObject->DriverObject->DriverExtension->ServiceKeyName);
if (ServiceRelativePath)
{
RtlAppendUnicodeToString(&BusDeviceExtension->ServicePath, L"\\");
RtlAppendUnicodeToString(&BusDeviceExtension->ServicePath, ServiceRelativePath);
}
if (InterfaceGuid)
{
/* register an device interface */
Status = IoRegisterDeviceInterface(PhysicalDeviceObject, InterfaceGuid, NULL, &BusDeviceExtension->SymbolicLinkName);
/* check for success */
if (!NT_SUCCESS(Status))
{
FreeItem(BusDeviceExtension->ServicePath.Buffer);
FreeItem(BusDeviceExtension);
return Status;
}
/* now enable device interface */
Status = IoSetDeviceInterfaceState(&BusDeviceExtension->SymbolicLinkName, TRUE);
if (!NT_SUCCESS(Status))
{
FreeItem(BusDeviceExtension->ServicePath.Buffer);
FreeItem(BusDeviceExtension);
return Status;
}
/* set state enabled */
BusDeviceExtension->Enabled = TRUE;
}
/* store device objects */
BusDeviceExtension->BusDeviceObject = BusDeviceObject;
BusDeviceExtension->PnpDeviceObject = PnpDeviceObject;
BusDeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
if (!PnpDeviceObject)
{
BusDeviceExtension->PnpDeviceObject = IoAttachDeviceToDeviceStack(BusDeviceObject, PhysicalDeviceObject);
if (!BusDeviceExtension->PnpDeviceObject)
{
/* failed to attach device */
if (BusDeviceExtension->Enabled)
{
IoSetDeviceInterfaceState(&BusDeviceExtension->SymbolicLinkName, FALSE);
RtlFreeUnicodeString(&BusDeviceExtension->SymbolicLinkName);
}
/* free device extension */
FreeItem(BusDeviceExtension->ServicePath.Buffer);
FreeItem(BusDeviceExtension);
return STATUS_DEVICE_REMOVED;
}
}
else
{
/* directly attach */
BusDeviceExtension->PnpDeviceObject = PnpDeviceObject;
}
/* attach device extension */
DeviceExtension = (PDEVICE_EXTENSION)BusDeviceObject->DeviceExtension;
DeviceExtension->DeviceHeader = (PKSIDEVICE_HEADER)BusDeviceExtension;
/* FIXME scan bus and invalidate device relations */
return Status;
}
NTSTATUS
NTAPI
KspSetGetBusDataCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
@ -1990,130 +1851,6 @@ KsDeviceRegisterAdapterObject(
}
/*
@implemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsGetBusEnumIdentifier(
IN PIRP Irp)
{
PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
PIO_STACK_LOCATION IoStack;
ULONG Length;
NTSTATUS Status;
LPWSTR Buffer;
/* get stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* sanity checks */
ASSERT(IoStack->DeviceObject);
ASSERT(IoStack->DeviceObject->DeviceExtension);
/* get bus device extension */
BusDeviceExtension = *(PBUS_ENUM_DEVICE_EXTENSION*)(IoStack->DeviceObject->DeviceExtension);
if (!BusDeviceExtension)
{
/* invalid parameter */
return STATUS_INVALID_PARAMETER;
}
/* get length */
Length = (wcslen(BusDeviceExtension->BusIdentifier)+1) * sizeof(WCHAR);
/* is there an output buffer provided */
if (IoStack->Parameters.DeviceIoControl.InputBufferLength)
{
if (Length > IoStack->Parameters.DeviceIoControl.InputBufferLength)
{
/* buffer is too small */
return STATUS_BUFFER_TOO_SMALL;
}
/* now allocate buffer */
Buffer = AllocateItem(NonPagedPool, Length);
if (!Buffer)
{
/* no memory */
Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
/* copy bus identifier */
wcscpy(Buffer, BusDeviceExtension->BusIdentifier);
/* store buffer */
Irp->AssociatedIrp.SystemBuffer = Buffer;
/* set flag that buffer gets copied back */
Irp->Flags |= IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER | IRP_INPUT_OPERATION;
/* done */
Status = STATUS_SUCCESS;
}
}
else
{
/* no buffer provided */
Status = STATUS_BUFFER_OVERFLOW;
}
/* done */
return Status;
}
/*
@unimplemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsGetBusEnumParentFDOFromChildPDO(
IN PDEVICE_OBJECT DeviceObject,
OUT PDEVICE_OBJECT *FunctionalDeviceObject)
{
DPRINT1("KsGetBusEnumParentFDOFromChildPDO\n");
DbgBreakPoint();
return STATUS_UNSUCCESSFUL;
}
/*
@implemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsGetBusEnumPnpDeviceObject(
IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT *PnpDeviceObject)
{
PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
if (!DeviceObject->DeviceExtension)
{
/* invalid parameter */
return STATUS_INVALID_PARAMETER;
}
/* get bus device extension */
BusDeviceExtension = *(PBUS_ENUM_DEVICE_EXTENSION*)(DeviceObject->DeviceExtension);
if (!BusDeviceExtension)
{
/* invalid parameter */
return STATUS_INVALID_PARAMETER;
}
/* store result */
*PnpDeviceObject = BusDeviceExtension->PnpDeviceObject;
/* done */
return STATUS_SUCCESS;
}
/*
@implemented
@ -2155,37 +1892,6 @@ KsGetNextSibling(
return (PVOID)BasicHeader->Next.Pin;
}
/*
@unimplemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsInstallBusEnumInterface(
PIRP Irp)
{
UNIMPLEMENTED
DPRINT1("KsInstallBusEnumInterface\n");
DbgBreakPoint();
return STATUS_UNSUCCESSFUL;
}
/*
@unimplemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsIsBusEnumChildDevice(
IN PDEVICE_OBJECT DeviceObject,
OUT PBOOLEAN ChildDevice)
{
UNIMPLEMENTED
DPRINT1("KsIsBusEnumChildDevice\n");
DbgBreakPoint();
return STATUS_UNSUCCESSFUL;
}
ULONG
KspCountMethodSets(
IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL,
@ -2696,154 +2402,6 @@ cleanup:
return STATUS_INSUFFICIENT_RESOURCES;
}
/*
@unimplemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsServiceBusEnumCreateRequest(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp)
{
UNIMPLEMENTED
DPRINT1("KsServiceBusEnumCreateRequest\n");
DbgBreakPoint();
return STATUS_UNSUCCESSFUL;
}
/*
@unimplemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsServiceBusEnumPnpRequest(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp)
{
UNIMPLEMENTED
DPRINT1("KsServiceBusEnumPnpRequest\n");
DbgBreakPoint();
/*
KsServiceBusEnumPnpRequest services the following Plug and Play IRPs for an FDO or parent device:
*
IRP_MN_START_DEVICE
IRP_MN_QUERY_BUS_INFORMATION OK
IRP_MN_QUERY_DEVICE_RELATIONS
IRP_MN_QUERY_STOP_DEVICE
IRP_MN_QUERY_REMOVE_DEVICE
IRP_MN_CANCEL_STOP_DEVICE
IRP_MN_CANCEL_REMOVE_DEVICE
IRP_MN_STOP_DEVICE
IRP_MN_REMOVE_DEVICE
*/
/*
Plug and Play IRPs for a PDO or child device:
*
IRP_MN_START_DEVICE
IRP_MN_QUERY_STOP_DEVICE
IRP_MN_QUERY_REMOVE_DEVICE
IRP_MN_STOP_DEVICE
IRP_MN_REMOVE_DEVICE
IRP_MN_QUERY_DEVICE_RELATIONS (TargetDeviceRelations)
IRP_MN_QUERY_PNP_DEVICE_STATE
IRP_MN_QUERY_ID
IRP_MN_QUERY_INTERFACE
IRP_MN_QUERY_RESOURCES NOP
IRP_MN_QUERY_RESOURCE_REQUIREMENTS NOP
IRP_MN_READ_CONFIG
IRP_MN_WRITE_CONFIG
IRP_MN_QUERY_CAPABILITIES
*/
/**
Request: IRP_MN_QUERY_BUS_INFORMATION
: GUID PNP_BUS_INFORMATION
BusTypeGuid: KSMEDIUMSETID_Standard
LegacyBusType: InterfaceTypeUndefined
BusNumber: 0
*/
return STATUS_UNSUCCESSFUL;
}
VOID
NTAPI
KspRemoveBusInterface(
PVOID Ctx)
{
PKSREMOVE_BUS_INTERFACE_CTX Context =(PKSREMOVE_BUS_INTERFACE_CTX)Ctx;
/* TODO
* get SWENUM_INSTALL_INTERFACE struct
* open device key and delete the keys
*/
UNIMPLEMENTED
/* set status */
Context->Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
/* signal completion */
KeSetEvent(&Context->Event, IO_NO_INCREMENT, FALSE);
}
/*
@unimplemented
*/
KSDDKAPI
NTSTATUS
NTAPI
KsRemoveBusEnumInterface(
IN PIRP Irp)
{
KPROCESSOR_MODE Mode;
LUID luid;
KSREMOVE_BUS_INTERFACE_CTX Ctx;
WORK_QUEUE_ITEM WorkItem;
DPRINT1("KsRemoveBusEnumInterface\n");
DbgBreakPoint();
/* get previous mode */
Mode = ExGetPreviousMode();
/* convert to luid */
luid = RtlConvertUlongToLuid(SE_LOAD_DRIVER_PRIVILEGE);
/* perform access check */
if (!SeSinglePrivilegeCheck(luid, Mode))
{
/* insufficient privileges */
return STATUS_PRIVILEGE_NOT_HELD;
}
/* initialize event */
KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);
/* store irp in ctx */
Ctx.Irp = Irp;
/* initialize work item */
ExInitializeWorkItem(&WorkItem, KspRemoveBusInterface, (PVOID)&Ctx);
/* now queue the work item */
ExQueueWorkItem(&WorkItem, DelayedWorkQueue);
/* wait for completion */
KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);
/* return result */
return Ctx.Irp->IoStatus.Status;
}
/*
@unimplemented
*/

View file

@ -32,4 +32,5 @@
<file>unknown.c</file>
<file>worker.c</file>
<file>kcom.c</file>
<file>swenum.c</file>
</module>

View file

@ -307,3 +307,5 @@ DECLARE_INTERFACE_(IKsDevice, IUnknown)
STDMETHOD_(NTSTATUS, CheckIoCapability)(THIS_
IN ULONG Unknown)PURE;
};
#undef INTERFACE

View file

@ -134,12 +134,6 @@ typedef struct
PIO_WORKITEM WorkItem;
}PNP_POSTSTART_CONTEXT, *PPNP_POSTSTART_CONTEXT;
typedef struct
{
PIRP Irp;
KEVENT Event;
}KSREMOVE_BUS_INTERFACE_CTX, *PKSREMOVE_BUS_INTERFACE_CTX;
typedef struct
{
PLIST_ENTRY List;
@ -150,20 +144,97 @@ typedef struct
typedef BOOLEAN (NTAPI *PKSEVENT_SYNCHRONIZED_ROUTINE)(PKSEVENT_CTX Context);
struct __BUS_ENUM_DEVICE_EXTENSION__;
struct BUS_DEVICE_ENTRY;
typedef struct
{
BOOLEAN Enabled;
LIST_ENTRY Entry;
ULONG IsBus;
union
{
PDEVICE_OBJECT DeviceObject;
ULONG DeviceReferenceCount;
};
union
{
PVOID DeviceEntry;
ULONG Dummy1;
};
struct __BUS_ENUM_DEVICE_EXTENSION__ *BusDeviceExtension;
ULONG DeviceObjectReferenceCount;
}COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
PDEVICE_OBJECT PnpDeviceObject;
typedef struct
{
PCOMMON_DEVICE_EXTENSION Ext;
}DEV_EXTENSION, *PDEV_EXTENSION;
typedef struct
{
LIST_ENTRY Entry;
GUID InterfaceGuid;
UNICODE_STRING SymbolicLink;
}BUS_INSTANCE_ENTRY, *PBUS_INSTANCE_ENTRY;
typedef enum
{
NotStarted = 0, // Not started yet
Started, // Device has received the START_DEVICE IRP
StopPending, // Device has received the QUERY_STOP IRP
Stopped, // Device has received the STOP_DEVICE IRP
RemovePending, // Device has received the QUERY_REMOVE IRP
SurpriseRemovePending, // Device has received the SURPRISE_REMOVE IRP
Deleted
}DEVICE_STATE;
typedef struct
{
LIST_ENTRY Entry;
LIST_ENTRY DeviceInterfaceList;
LIST_ENTRY IrpPendingList;
PDEVICE_OBJECT PDO;
DEVICE_STATE DeviceState;
GUID DeviceGuid;
LPWSTR PDODeviceName;
LPWSTR DeviceName;
LPWSTR BusId;
LARGE_INTEGER TimeCreated;
LARGE_INTEGER TimeExpired;
LPWSTR Instance;
}BUS_DEVICE_ENTRY, *PBUS_DEVICE_ENTRY;
typedef struct __BUS_ENUM_DEVICE_EXTENSION__
{
COMMON_DEVICE_EXTENSION Common;
KSPIN_LOCK Lock;
KEVENT Event;
UNICODE_STRING DeviceInterfaceLink;
PDEVICE_OBJECT PhysicalDeviceObject;
PDEVICE_OBJECT PnpDeviceObject;
PDEVICE_OBJECT BusDeviceObject;
ULONG PdoCreated;
KTIMER Timer;
KDPC Dpc;
WORK_QUEUE_ITEM WorkItem;
ULONG DeviceAttached;
UNICODE_STRING ServicePath;
UNICODE_STRING SymbolicLinkName;
WCHAR BusIdentifier[1];
}BUS_ENUM_DEVICE_EXTENSION, *PBUS_ENUM_DEVICE_EXTENSION;
typedef struct
{
PIRP Irp;
PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
KEVENT Event;
NTSTATUS Status;
WORK_QUEUE_ITEM WorkItem;
}BUS_INSTALL_ENUM_CONTEXT, *PBUS_INSTALL_ENUM_CONTEXT;
typedef struct
{
PUCHAR FilterData;

View file

@ -19,6 +19,8 @@
#include "ksmedia.h"
#include "bdamedia.h"
#include <swenum.h>
#define TAG_DEVICE_HEADER 'KSDH'
#define REG_PINFLAG_B_MANY 0x4 /* strmif.h */

1961
drivers/ksfilter/ks/swenum.c Normal file

File diff suppressed because it is too large Load diff