Mostly minor updates to the source tree for portcls.

Still much work to be done!


svn path=/trunk/; revision=26094
This commit is contained in:
Andrew Greenwood 2007-03-14 19:50:47 +00:00
parent 3738b97003
commit e4cfaf284e
24 changed files with 1446 additions and 171 deletions

View file

@ -23,3 +23,21 @@
<!--<directory name="avtest">
<xi:include href="avtest/avtest.rbuild" />
</directory-->
<!--
Drivers (experimental)
-->
<directory name="mpu401_ks">
<xi:include href="mpu401_ks/mpu401.rbuild" />
</directory>
<directory name="sb16_nt4">
<xi:include href="sb16_nt4/sb16_nt4.rbuild" />
</directory>
<!--directory name="sb16_ks">
<xi:include href="sb16_ks/sb16.rbuild" />
</directory-->

View file

@ -66,12 +66,38 @@ KsAddObjectCreateItemToObjectHeader(
*/
KSDDKAPI NTSTATUS NTAPI
KsAllocateDeviceHeader(
OUT PVOID Header,
OUT KSDEVICE_HEADER* Header,
IN ULONG ItemsCount,
IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
/* Allocates memory for the KSDEVICE_HEADER structure */
if ( ! Header )
return STATUS_INVALID_PARAMETER;
Header = ExAllocatePoolWithTag(PagedPool, sizeof(KSDEVICE_HEADER), 'HDSK');
if ( ! Header )
return STATUS_INSUFFICIENT_RESOURCES;
/* TODO: Actually do something with the header, perhaps? */
return STATUS_SUCCESS;
}
/*
@unimplemented
*/
KSDDKAPI VOID NTAPI
KsFreeDeviceHeader(
IN KSDEVICE_HEADER Header)
{
if ( ! Header )
return;
/* TODO: Free content first */
ExFreePoolWithTag(Header, 'HDSK');
}
/*
@ -89,6 +115,8 @@ KsAllocateExtraData(
/*
@unimplemented
http://www.osronline.com/DDKx/stream/ksfunc_3sc3.htm
*/
KSDDKAPI NTSTATUS NTAPI
KsAllocateObjectCreateItem(
@ -103,6 +131,13 @@ KsAllocateObjectCreateItem(
/*
@unimplemented
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.
http://www.osronline.com/DDKx/stream/ksfunc_0u2b.htm
*/
KSDDKAPI NTSTATUS NTAPI
KsAllocateObjectHeader(
@ -112,10 +147,42 @@ KsAllocateObjectHeader(
IN PIRP Irp,
IN KSDISPATCH_TABLE* Table)
{
/* NOTE: PKSOBJECT_HEADER is not defined yet */
#if 0
PKSOBJECT_HEADER object_header;
/* TODO: Validate parameters */
object_header = ExAllocatePoolWithTag(PagedPool, sizeof(KSOBJECT_HEADER), 'HOSK');
if ( ! object_header )
{
return STATUS_INSUFFICIENT_RESOURCES;
}
(PVOID)(*Header) = object_header;
/* TODO ... */
#endif
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
/*
@unimplemented
*/
KSDDKAPI VOID NTAPI
KsFreeObjectHeader(
IN PVOID Header)
{
ExFreePoolWithTag(Header, 'HOSK');
/* TODO */
UNIMPLEMENTED;
}
/*
@unimplemented
*/
@ -186,15 +253,18 @@ KsDispatchFastReadFailure(
}
/*
@unimplemented
Used in dispatch table entries that aren't handled and need to return
STATUS_INVALID_DEVICE_REQUEST.
*/
KSDDKAPI NTSTATUS NTAPI
KsDispatchInvalidDeviceRequest(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST;
}
/*
@ -205,6 +275,7 @@ KsDispatchIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
/* Calls a dispatch routine corresponding to the function code of the IRP */
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
@ -260,26 +331,6 @@ KsForwardIrp(
return STATUS_UNSUCCESSFUL;
}
/*
@unimplemented
*/
KSDDKAPI VOID NTAPI
KsFreeDeviceHeader(
IN PVOID Header)
{
UNIMPLEMENTED;
}
/*
@unimplemented
*/
KSDDKAPI VOID NTAPI
KsFreeObjectHeader(
IN PVOID Header)
{
UNIMPLEMENTED;
}
/*
@unimplemented
*/
@ -427,6 +478,122 @@ KsSetInformationFile(
return STATUS_UNSUCCESSFUL;
}
/*
IRP handlers
NOT USED
*/
#if 0
static NTAPI
NTSTATUS
KsCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("KS / Create\n");
return STATUS_UNSUCCESSFUL;
}
static NTAPI
NTSTATUS
KsClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("KS / Close\n");
return STATUS_UNSUCCESSFUL;
}
static NTAPI
NTSTATUS
KsDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("KS / DeviceControl\n");
return STATUS_UNSUCCESSFUL;
}
static NTAPI
NTSTATUS
KsRead(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("KS / Read\n");
return STATUS_UNSUCCESSFUL;
}
static NTAPI
NTSTATUS
KsWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("KS / Write\n");
return STATUS_UNSUCCESSFUL;
}
static NTAPI
NTSTATUS
KsFlushBuffers(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("KS / FlushBuffers\n");
return STATUS_UNSUCCESSFUL;
}
static NTAPI
NTSTATUS
KsQuerySecurity(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("KS / QuerySecurity\n");
return STATUS_UNSUCCESSFUL;
}
static NTAPI
NTSTATUS
KsSetSecurity(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("KS / SetSecurity\n");
return STATUS_UNSUCCESSFUL;
}
#endif
static NTAPI
NTSTATUS
KsInternalIrpDispatcher(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
/* TODO - Nothing implemented really yet! */
DPRINT1("KS IRP dispatch function called\n");
PKSDISPATCH_TABLE ks_dispatch_table = NULL;
/* ks_dispatch_table is the first element in a structure pointed to by FsContext */
switch ( IoGetCurrentIrpStackLocation(Irp)->MajorFunction )
{
case IRP_MJ_CREATE :
/* return ks_dispatch_table->Create(DeviceObject, Irp);*/
/* TODO ... */
default :
return STATUS_INVALID_PARAMETER;
};
}
/*
@unimplemented
*/
@ -435,8 +602,31 @@ KsSetMajorFunctionHandler(
IN PDRIVER_OBJECT DriverObject,
IN ULONG MajorFunction)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
/*
Sets a DriverObject's major function handler to point to an internal
function we implement.
TODO: Deal with KSDISPATCH_FASTIO
*/
switch ( MajorFunction )
{
case IRP_MJ_CREATE :
case IRP_MJ_CLOSE :
case IRP_MJ_DEVICE_CONTROL :
case IRP_MJ_READ :
case IRP_MJ_WRITE :
case IRP_MJ_FLUSH_BUFFERS :
case IRP_MJ_QUERY_SECURITY :
case IRP_MJ_SET_SECURITY :
DriverObject->MajorFunction[MajorFunction] = KsInternalIrpDispatcher;
break;
default :
return STATUS_INVALID_PARAMETER; /* is this right? */
};
return STATUS_SUCCESS;
}
/*
@ -464,7 +654,7 @@ KsStreamIo(
@unimplemented
*/
KSDDKAPI NTSTATUS NTAPI
KsWriteFile(
KsWriteFile(
IN PFILE_OBJECT FileObject,
IN PKEVENT Event OPTIONAL,
IN PVOID PortContext OPTIONAL,

View file

@ -1,35 +1,26 @@
/*
ReactOS Kernel Streaming
Port Class API: Adapter initialization
Author: Andrew Greenwood
*/
#include <portcls.h>
NTSTATUS
PcStartIo(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
/* Internal function */
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
PcUnload(
IN PDRIVER_OBJECT DriverObject)
{
/* Internal function */
return STATUS_UNSUCCESSFUL;
}
/*
* @unimplemented
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Kernel Streaming
* FILE: drivers/multimedia/portcls/adapter.c
* PURPOSE: Port Class driver / DriverEntry and IRP handlers
* PROGRAMMER: Andrew Greenwood
*
* HISTORY:
* 27 Jan 07 Created
*/
#include <portcls.h>
#include "private.h"
/*
This is called from DriverEntry so that PortCls can take care of some
IRPs and map some others to the main KS driver. In most cases this will
be the first function called by an audio driver.
First 2 parameters are from DriverEntry.
The AddDevice parameter is a driver-supplied pointer to a function which
typically then calls PcAddAdapterDevice (see below.)
*/
PORTCLASSAPI NTSTATUS NTAPI
PcInitializeAdapterDriver(
IN PDRIVER_OBJECT DriverObject,
@ -37,17 +28,7 @@ PcInitializeAdapterDriver(
IN PDRIVER_ADD_DEVICE AddDevice)
{
/*
This is effectively a common DriverEntry function for PortCls drivers.
So it has similar responsibilities to a normal driver.
First 2 parameters are from DriverEntry.
Installs the supplied AddDevice routine in the driver object?s driver extension and installs the PortCls driver?s IRP handlers in the driver object itself.
*/
DriverObject->DriverExtension->AddDevice = AddDevice;
/*
TODO: (* = implement here, otherwise KS default)
(* = implement here, otherwise KS default)
IRP_MJ_CLOSE
* IRP_MJ_CREATE
IRP_MJ_DEVICE_CONTROL
@ -61,14 +42,53 @@ PcInitializeAdapterDriver(
IRP_MJ_WRITE
*/
UNIMPLEMENTED;
//NTSTATUS status;
//ULONG i;
DPRINT("PcInitializeAdapterDriver\n");
#if 0
/* Set default stub - is this a good idea? */
DPRINT1("Setting IRP stub\n");
for ( i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i ++ )
{
DriverObject->MajorFunction[i] = IrpStub;
}
#endif
/* Our IRP handlers */
DPRINT1("Setting IRP handlers\n");
DriverObject->MajorFunction[IRP_MJ_CREATE] = PcDispatchIrp;
DriverObject->MajorFunction[IRP_MJ_PNP] = PcDispatchIrp;
DriverObject->MajorFunction[IRP_MJ_POWER] = PcDispatchIrp;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = PcDispatchIrp;
/* The driver-supplied AddDevice */
DriverObject->DriverExtension->AddDevice = AddDevice;
/* KS handles these */
DPRINT1("Setting KS function handlers\n");
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_FLUSH_BUFFERS);
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_QUERY_SECURITY);
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_READ);
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_SET_SECURITY);
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_WRITE);
DPRINT1("PortCls has finished initializing the adapter driver\n");
return STATUS_SUCCESS;
}
/*
* @unimplemented
*/
Typically called by a driver's AddDevice function, which is set when
calling PcInitializeAdapterDriver. This performs some common driver
operations, such as creating a device extension.
The StartDevice parameter is a driver-supplied function which gets
called in response to IRP_MJ_PNP / IRP_MN_START_DEVICE.
*/
PORTCLASSAPI NTSTATUS NTAPI
PcAddAdapterDevice(
IN PDRIVER_OBJECT DriverObject,
@ -80,8 +100,70 @@ PcAddAdapterDevice(
/*
Note - after this has been called, we can
handle IRP_MN_START_DEVICE by calling StartDevice
TODO:
Validate DeviceExtensionSize!! (et al...)
*/
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
PDEVICE_OBJECT fdo = NULL;
PCExtension* portcls_ext;
DPRINT1("PcAddAdapterDevice called\n");
if ( ! DriverObject)
{
DPRINT("DriverObject is NULL!\n");
return STATUS_INVALID_PARAMETER;
}
if ( ! PhysicalDeviceObject )
{
DPRINT("PhysicalDeviceObject is NULL!\n");
return STATUS_INVALID_PARAMETER;
}
if ( ! StartDevice )
{
DPRINT("No StartDevice parameter!\n");
return STATUS_INVALID_PARAMETER;
}
/* TODO: Make sure this is right */
if ( DeviceExtensionSize < PORT_CLASS_DEVICE_EXTENSION_SIZE )
{
if ( DeviceExtensionSize != 0 )
{
/* TODO: Error */
DPRINT("DeviceExtensionSize is invalid\n");
return STATUS_INVALID_PARAMETER;
}
}
DPRINT("portcls is creating a device\n");
status = IoCreateDevice(DriverObject,
DeviceExtensionSize,
NULL,
PhysicalDeviceObject->DeviceType, /* FILE_DEVICE_KS ? */
PhysicalDeviceObject->Characteristics, /* TODO: Check */
FALSE,
&fdo);
if ( ! NT_SUCCESS(status) )
{
DPRINT("IoCreateDevice() failed with status 0x$08lx\n", status);
return status;
}
/* Obtain the new device extension */
portcls_ext = (PCExtension*) fdo->DeviceExtension;
ASSERT(portcls_ext);
/* Initialize */
portcls_ext->StartDevice = StartDevice;
DPRINT("PcAddAdapterDriver succeeded\n");
return STATUS_SUCCESS;
}

View file

@ -0,0 +1,252 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS
* FILE: drivers/multimedia/portcls/helpers/ResourceList.c
* PURPOSE: Port Class driver / ResourceList implementation
* PROGRAMMER: Andrew Greenwood
*
* HISTORY:
* 27 Jan 07 Created
*/
#include <portcls.h>
#include <stdunk.h>
typedef struct CResourceList
{
union
{
IUnknown IUnknown;
IResourceList IResourceList;
};
LONG m_ref_count;
PUNKNOWN m_outer_unknown;
PCM_RESOURCE_LIST translated_resources;
PCM_RESOURCE_LIST untranslated_resources;
} CResourceList;
/*
Basic IUnknown methods
*/
STDMETHODCALLTYPE
NTSTATUS
ResourceList_QueryInterface(
IResourceList* this_container,
IN REFIID refiid,
OUT PVOID* output)
{
/* TODO */
return STATUS_SUCCESS;
}
STDMETHODCALLTYPE
ULONG
ResourceList_AddRef(
IResourceList* this_container)
{
struct CUnknown* this = CONTAINING_RECORD(this_container, struct CUnknown, IUnknown);
InterlockedIncrement(&this->m_ref_count);
return this->m_ref_count;
}
STDMETHODCALLTYPE
ULONG
ResourceList_Release(
IResourceList* this_container)
{
struct CUnknown* this = CONTAINING_RECORD(this_container, struct CUnknown, IUnknown);
InterlockedDecrement(&this->m_ref_count);
if ( this->m_ref_count == 0 )
{
ExFreePool(this);
return 0;
}
return this->m_ref_count;
}
/*
IResourceList methods
*/
STDMETHODCALLTYPE
ULONG
ResourceList_NumberOfEntries(IResourceList* this_container)
{
return 0;
}
STDMETHODCALLTYPE
ULONG
ResourceList_NumberOfEntriesOfType(
IResourceList* this_container,
IN CM_RESOURCE_TYPE type)
{
/* I guess the translated and untranslated lists will be same length? */
CResourceList* this = CONTAINING_RECORD(this_container, CResourceList, IResourceList);
ULONG index, count = 0;
for ( index = 0; index < this->translated_resources->Count; index ++ )
{
PCM_FULL_RESOURCE_DESCRIPTOR full_desc = &this->translated_resources->List[index];
ULONG sub_index;
for ( sub_index = 0; sub_index < full_desc->PartialResourceList.Count; sub_index ++ )
{
PCM_PARTIAL_RESOURCE_DESCRIPTOR partial_desc;
partial_desc = &full_desc->PartialResourceList.PartialDescriptors[sub_index];
if ( partial_desc->Type == type )
{
/* Yay! Finally found one that matches! */
count ++;
}
}
}
DPRINT("Found %d\n", count);
return count;
}
STDMETHODCALLTYPE
PCM_PARTIAL_RESOURCE_DESCRIPTOR
ResourceList_FindTranslatedEntry(
IResourceList* this_container,
IN CM_RESOURCE_TYPE Type,
IN ULONG Index)
{
return NULL;
}
STDMETHODCALLTYPE
PCM_PARTIAL_RESOURCE_DESCRIPTOR
ResourceList_FindUntranslatedEntry(
IResourceList* this_container,
IN CM_RESOURCE_TYPE Type,
IN ULONG Index)
{
return NULL;
}
STDMETHODCALLTYPE
NTSTATUS
ResourceList_AddEntry(
IResourceList* this_container,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Translated,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Untranslated)
{
return STATUS_SUCCESS;
}
STDMETHODCALLTYPE
NTSTATUS
ResourceList_AddEntryFromParent(
IResourceList* this_container,
IN IResourceList* Parent,
IN CM_RESOURCE_TYPE Type,
IN ULONG Index)
{
return STATUS_SUCCESS;
}
STDMETHODCALLTYPE
PCM_RESOURCE_LIST
ResourceList_TranslatedList(
IResourceList* this_container)
{
return NULL;
}
STDMETHODCALLTYPE
PCM_RESOURCE_LIST
ResourceList_UntranslatedList(
IResourceList* this_container)
{
return NULL;
}
/*
ResourceList V-Table
*/
static const IResourceListVtbl ResourceListVtbl =
{
/* IUnknown */
ResourceList_QueryInterface,
ResourceList_AddRef,
ResourceList_Release,
/* IResourceList */
ResourceList_NumberOfEntries,
ResourceList_NumberOfEntriesOfType,
ResourceList_FindTranslatedEntry,
ResourceList_FindUntranslatedEntry,
ResourceList_AddEntry,
ResourceList_AddEntryFromParent,
ResourceList_TranslatedList,
ResourceList_UntranslatedList
};
/*
Factory for creating a resource list
*/
PORTCLASSAPI NTSTATUS NTAPI
PcNewResourceList(
OUT PRESOURCELIST* OutResourceList,
IN PUNKNOWN OuterUnknown OPTIONAL,
IN POOL_TYPE PoolType,
IN PCM_RESOURCE_LIST TranslatedResources,
IN PCM_RESOURCE_LIST UntranslatedResources)
{
IResourceList* new_list = NULL;
CResourceList* this = NULL;
/* TODO: Validate parameters */
DPRINT("PcNewResourceList\n");
new_list = ExAllocatePoolWithTag(sizeof(IResourceList), PoolType, 'LRcP');
if ( ! new_list )
{
DPRINT("ExAllocatePoolWithTag failed\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Obtain our private data */
this = CONTAINING_RECORD(new_list, CResourceList, IResourceList);
ASSERT(this);
/* Initialize */
this->m_outer_unknown = OuterUnknown;
this->translated_resources = TranslatedResources;
this->untranslated_resources = UntranslatedResources;
/* Increment our usage count and set the pointer to this object */
*OutResourceList = new_list;
ResourceListVtbl.AddRef(*OutResourceList);
return STATUS_SUCCESS;
}
PORTCLASSAPI NTSTATUS NTAPI
PcNewResourceSublist(
OUT PRESOURCELIST* OutResourceList,
IN PUNKNOWN OuterUnknown OPTIONAL,
IN POOL_TYPE PoolType,
IN PRESOURCELIST ParentList,
IN ULONG MaximumEntries)
{
return STATUS_UNSUCCESSFUL;
}

View file

@ -0,0 +1,273 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS
* FILE: drivers/multimedia/portcls/irp.c
* PURPOSE: Port Class driver / IRP Handling
* PROGRAMMER: Andrew Greenwood
*
* HISTORY:
* 27 Jan 07 Created
*/
#include <portcls.h>
#include "private.h"
/*
A safe place for IRPs to be bounced to, if no handler has been
set. Whether this is a good idea or not...?
*/
#if 0
static NTAPI
NTSTATUS
IrpStub(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
NTSTATUS status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DPRINT1("IRP Stub called\n");
return status;
}
#endif
/*
Handles IRP_MJ_CREATE, which occurs when someone wants to make use of
a device.
*/
NTAPI
NTSTATUS
PortClsCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("PortClsCreate called\n");
/* TODO */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
/*
IRP_MJ_PNP handler
Used for things like IRP_MN_START_DEVICE
*/
NTAPI
NTSTATUS
PortClsPnp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
NTSTATUS status;
PCExtension* portcls_ext;
PIO_STACK_LOCATION irp_stack;
DPRINT1("PortClsPnp called\n");
portcls_ext = (PCExtension*) DeviceObject->DeviceExtension;
irp_stack = IoGetCurrentIrpStackLocation(Irp);
ASSERT(portcls_ext);
/*
if IRP_MN_START_DEVICE, call the driver's customer start device routine.
Before we do so, we must create a ResourceList to pass to the Start
routine.
*/
if ( irp_stack->MinorFunction == IRP_MN_START_DEVICE )
{
IResourceList* resource_list;
DPRINT("IRP_MN_START_DEVICE\n");
/* Create the resource list */
status = PcNewResourceList(
&resource_list,
NULL,
PagedPool,
irp_stack->Parameters.StartDevice.AllocatedResourcesTranslated,
irp_stack->Parameters.StartDevice.AllocatedResources);
if ( ! NT_SUCCESS(status) )
{
DPRINT("PcNewResourceList failed [0x%8x]\n", status);
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
/* Assign the resource list to our extension */
portcls_ext->resources = resource_list;
ASSERT(portcls_ext->StartDevice);
/* Call the StartDevice routine */
DPRINT("Calling StartDevice at 0x%8x\n", portcls_ext->StartDevice);
status = portcls_ext->StartDevice(DeviceObject, Irp, resource_list);
if ( ! NT_SUCCESS(status) )
{
DPRINT("StartDevice returned a failure code [0x%8x]\n", status);
resource_list->lpVtbl->Release(resource_list);
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
else if ( irp_stack->MinorFunction == IRP_MN_REMOVE_DEVICE )
{
DPRINT("IRP_MN_REMOVE_DEVICE\n");
/* Clean up */
portcls_ext->resources->lpVtbl->Release(portcls_ext->resources);
IoDeleteDevice(DeviceObject);
/* Do not complete? */
Irp->IoStatus.Status = STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
/*
Power management. Handles IRP_MJ_POWER
(not implemented)
*/
NTAPI
NTSTATUS
PortClsPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("PortClsPower called\n");
/* TODO */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
/*
System control. Handles IRP_MJ_SYSTEM_CONTROL
(not implemented)
*/
NTAPI
NTSTATUS
PortClsSysControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
DPRINT1("PortClsSysControl called\n");
/* TODO */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
/*
==========================================================================
API EXPORTS
==========================================================================
*/
/*
Drivers may implement their own IRP handlers. If a driver decides to let
PortCls handle the IRP, it can do so by calling this.
*/
PORTCLASSAPI NTSTATUS NTAPI
PcDispatchIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION irp_stack;
DPRINT("PcDispatchIrp called - handling IRP in PortCls\n");
irp_stack = IoGetCurrentIrpStackLocation(Irp);
switch ( irp_stack->MajorFunction )
{
/* PortCls */
case IRP_MJ_CREATE :
return PortClsCreate(DeviceObject, Irp);
case IRP_MJ_PNP :
return PortClsPnp(DeviceObject, Irp);
case IRP_MJ_POWER :
return PortClsPower(DeviceObject, Irp);
case IRP_MJ_SYSTEM_CONTROL :
return PortClsSysControl(DeviceObject, Irp);
/* KS - TODO */
#if 0
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_FLUSH_BUFFERS);
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_QUERY_SECURITY);
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_READ);
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_SET_SECURITY);
KsSetMajorFunctionHandler(DriverObject, IRP_MJ_WRITE);
#endif
default :
break;
};
/* If we reach here, we just complete the IRP */
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
/*
* @unimplemented
*/
PORTCLASSAPI NTSTATUS NTAPI
PcCompleteIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN NTSTATUS Status)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
/*
* @unimplemented
*/
PORTCLASSAPI NTSTATUS NTAPI
PcForwardIrpSynchronous(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}

View file

@ -0,0 +1,32 @@
/*
ReactOS Operating System
Port Class API
IMiniPortMidi Implementation
by Andrew Greenwood
REFERENCE:
http://www.osronline.com/ddkx/stream/audmp-routines_64vn.htm
*/
#include <portcls.h>
NTSTATUS
IMiniport::GetDescription(
OUT PPCFILTER_DESCRIPTOR* Description)
{
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
IMiniport::DataRangeIntersection(
IN ULONG PinId,
IN PKSDATARANGE DataRange,
IN PKSDATARANGE MatchingDataRange,
IN ULONG OutputBufferLength,
OUT PVOID ResultantFormat OPTIONAL,
OUT PULONG ResultantFormatLength)
{
return STATUS_UNSUCCESSFUL;
}

View file

@ -0,0 +1,43 @@
/*
ReactOS Operating System
Port Class API
IMiniPortMidi Implementation
by Andrew Greenwood
REFERENCE:
http://www.osronline.com/ddkx/stream/audmp-routines_1fsj.htm
*/
#include <portcls.h>
NTSTATUS
IMiniportMidi::Init(
IN PUNKNOWN UnknownAdapter,
IN PRESOURCELIST ResourceList,
IN PPORTMIDI Port,
OUT PSERVICEGROUP* ServiceGroup)
{
/* http://www.osronline.com/ddkx/stream/audmp-routines_6jsj.htm */
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
IMiniportMidi::NewStream(
OUT PMINIPORTMIDISTREAM Stream,
IN PUNKNOWN OuterUnknown OPTIONAL,
IN POOL_TYPE PoolType,
IN ULONG Pin,
IN BOOLEAN Capture,
IN PKSDATAFORMAT DataFormat,
OUT PSERVICEGROUP* ServiceGroup)
{
return STATUS_UNSUCCESSFUL;
}
void
IMiniportMidi::Service(void)
{
}

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,55 @@
/*
ReactOS Operating System
Port Class API / IPort Implementation
by Andrew Greenwood
REFERENCE:
http://www.osronline.com/ddkx/stream/audmp-routines_0tgz.htm
NOTE: I'm not sure if this file is even needed...
*/
#if 0
#include <stdunk.h>
#include <portcls.h>
NTSTATUS
IPort::GetDeviceProperty(
IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty,
IN ULONG BufferLength,
OUT PVOID PropertyBuffer,
OUT PULONG ReturnLength)
{
/* http://www.osronline.com/ddkx/stream/audmp-routines_93xv.htm */
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
IPort::Init(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PUNKNOWN UnknownMiniport,
IN PUNKNOWN UnknownAdapter OPTIONAL,
IN PRESOURCELIST ResourceList)
{
/* http://www.osronline.com/ddkx/stream/audmp-routines_7qcz.htm */
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
IPort::NewRegistryKey(
OUT PREGISTRYKEY* OutRegistryKey,
IN PUNKNOWN OuterUnknown OPTIONAL,
IN ULONG RegistryKeyType,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN ULONG CreateOptions OPTIONAL,
OUT PULONG Disposition OPTIONAL)
{
/* http://www.osronline.com/ddkx/stream/audmp-routines_2jhv.htm */
return STATUS_UNSUCCESSFUL;
}
#endif

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,74 @@
/*
ReactOS Operating System
Port Class API / IPortMidi Implementation
by Andrew Greenwood
REFERENCE:
http://www.osronline.com/ddkx/stream/audmp-routines_49pv.htm
NOTES:
IPortMidi inherits from IPort. This file contains specific
extensions.
*/
#include <stdunk.h>
#include <portcls.h>
#include "port.h"
/*
IPort Methods
*/
NTSTATUS
CPortMidi::GetDeviceProperty(
IN DEVICE_REGISTRY_PROPERTY DeviceRegistryProperty,
IN ULONG BufferLength,
OUT PVOID PropertyBuffer,
OUT PULONG ReturnLength)
{
/* http://www.osronline.com/ddkx/stream/audmp-routines_93xv.htm */
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
CPortMidi::Init(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PUNKNOWN UnknownMiniport,
IN PUNKNOWN UnknownAdapter OPTIONAL,
IN PRESOURCELIST ResourceList)
{
/* http://www.osronline.com/ddkx/stream/audmp-routines_7qcz.htm */
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
CPortMidi::NewRegistryKey(
OUT PREGISTRYKEY* OutRegistryKey,
IN PUNKNOWN OuterUnknown OPTIONAL,
IN ULONG RegistryKeyType,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN ULONG CreateOptions OPTIONAL,
OUT PULONG Disposition OPTIONAL)
{
/* http://www.osronline.com/ddkx/stream/audmp-routines_2jhv.htm */
return STATUS_UNSUCCESSFUL;
}
/*
IPortMidi Methods
*/
VOID
CPortMidi::Notify(IN PSERVICEGROUP ServiceGroup OPTIONAL)
{
}
NTSTATUS
CPortMidi::RegisterServiceGroup(IN PSERVICEGROUP ServiceGroup)
{
return STATUS_UNSUCCESSFUL;
}

View file

@ -0,0 +1,3 @@
/*
Inherits from IPort only
*/

View file

@ -0,0 +1,41 @@
/*
ReactOS Operating System
Port Class API / IPort Implementation
by Andrew Greenwood
*/
#include <portcls.h>
NTSTATUS
IPortWaveCyclic::NewMasterDmaChannel(
OUT PDMACHANNEL* DmaChannel,
IN PUNKNOWN OuterUnknown,
IN PRESOURCELIST ResourceList OPTIONAL,
IN ULONG MaximumLength,
IN BOOL Dma32BitAddresses,
IN BOOL Dma64BitAddresses,
IN DMA_WIDTH DmaWidth,
IN DMA_SPEED DmaSpeed)
{
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
IPortWaveCyclic::NewSlaveDmaChannel(
OUT PDMACHANNELSLAVE* DmaChannel,
IN PUNKNOWN OuterUnknown,
IN PRESOURCELIST ResourceList OPTIONAL,
IN ULONG DmaIndex,
IN ULONG MaximumLength,
IN BOOL DemandMode,
IN DMA_SPEED DmaSpeed)
{
return STATUS_UNSUCCESSFUL;
}
VOID
IPortWaveCyclic::Notify(
IN PSERVICEGROUP ServiceGroup)
{
}

View file

@ -0,0 +1,31 @@
/*
ReactOS Operating System
Port Class API / IPort Implementation
by Andrew Greenwood
*/
#include <portcls.h>
NTSTATUS
IPortWavePci::NewMasterDmaChannel(
OUT PDMACHANNEL* DmaChannel,
IN PUNKNOWN OuterUnknown,
IN POOL_TYPE PoolType,
IN PRESOURCELIST ResourceList OPTIONAL,
IN BOOL ScatterGather,
IN BOOL Dma32BitAddresses,
IN BOOL Dma64BitAddresses,
IN DMA_WIDTH DmaWidth,
IN DMA_SPEED DmaSpeed,
IN ULONG MaximumLength,
IN ULONG DmaPort)
{
return STATUS_UNSUCCESSFUL;
}
VOID
IPortWavePci::Notify(
IN PSERVICEGROUP ServiceGroup)
{
}

View file

@ -0,0 +1,58 @@
/*
ReactOS Operating System
Port Class API / Port Factory
by Andrew Greenwood
*/
#include <portcls.h>
#include "port.h"
/*
* @unimplemented
*/
PORTCLASSAPI NTSTATUS NTAPI
PcNewPort(
OUT PPORT* OutPort,
IN REFCLSID ClassId)
{
/*
ClassId can be one of the following:
CLSID_PortDMus -> IPortDMus (dmusicks.h)
CLSID_PortMidi -> IPortMidi
CLSID_PortTopology -> IPortTopology
CLSID_PortWaveCyclic -> IPortWaveCyclic
CLSID_PortWavePci -> IPortWavePci
*/
PPORT new_port = NULL;
if ( ! OutPort )
{
DPRINT("PcNewPort was supplied a NULL OutPort parameter\n");
return STATUS_INVALID_PARAMETER;
}
/* FIXME - do not hack, for it is bad */
//new_port = new PPortMidi;
// STD_CREATE_BODY_(CPortMidi, (PUNKNOWN) &new_port, NULL, 0, PUNKNOWN);
/*
if ( ClassId == CLSID_PortMidi )
new_port = new IPortMidi;
else if ( ClassId == CLSID_PortTopology )
new_port = new IPortTopology;
else if ( ClassId == CLSID_PortWaveCyclic )
new_port = new IPortWaveCyclic;
else if ( ClassId == CLSID_PortWavePci )
new_port = new IPortWavePci;
else
*/
return STATUS_NOT_SUPPORTED;
/* Fill the caller's PPORT* to point to the new port */
*OutPort = new_port;
return STATUS_SUCCESS;
}

View file

@ -0,0 +1,35 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS
* FILE: drivers/multimedia/portcls/port/port.h
* PURPOSE: Port Class driver / Private header for IPort
* PROGRAMMER: Andrew Greenwood
*
* HISTORY:
* 27 Jan 07 Created
*/
/*
Private header for Port implementations
*/
#ifndef PORT_PRIVATE_H
#define PORT_PRIVATE_H
#include <stdunk.h>
#include <portcls.h>
typedef struct CPort
{
union
{
IUnknown IUnknown;
IPort IPort;
};
LONG m_ref_count;
PUNKNOWN m_outer_unknown;
} CPort;
#endif

View file

@ -1,12 +1,25 @@
<module name="portcls" type="exportdriver" installbase="system32/drivers" installname="portcls.sys" allowwarnings="true">
<module name="portcls" type="kernelmodedriver" installbase="system32/drivers" installname="portcls.sys" allowwarnings="true">
<linkerflag>-fno-exceptions</linkerflag>
<linkerflag>-fno-rtti</linkerflag>
<importlibrary definition="portcls.def" />
<define name="__USE_W32API" />
<include base="portcls">../include</include>
<library>ntoskrnl</library>
<library>drmk</library>
<define name="__USE_W32API" />
<include base="portcls">../include</include>
<library>ntoskrnl</library>
<library>ks</library>
<library>drmk</library>
<file>dll.c</file>
<file>adapter.c</file>
<file>drm.c</file>
<file>stubs.c</file>
<file>portcls.rc</file>
<file>adapter.c</file>
<file>irp.c</file>
<file>drm.c</file>
<file>stubs.c</file>
<!-- Probably not the best idea to have this separate -->
<file>../stdunk/stdunk.c</file>
<file>helper/ResourceList.c</file>
<file>port/factory.c</file>
<file>portcls.rc</file>
</module>

View file

@ -0,0 +1,44 @@
/*
PortCls FDO Extension
by Andrew Greenwood
*/
#ifndef PORTCLS_PRIVATE_H
#define PORTCLS_PRIVATE_H
#include <portcls.h>
NTAPI
NTSTATUS
PortClsCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTAPI
NTSTATUS
PortClsPnp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTAPI
NTSTATUS
PortClsPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTAPI
NTSTATUS
PortClsSysControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
typedef struct
{
PCPFNSTARTDEVICE StartDevice;
IResourceList* resources;
} PCExtension;
#endif

View file

@ -1,7 +1,13 @@
/*
Port Class API
Stubbed functions
*/
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS
* FILE: drivers/multimedia/portcls/stubs.c
* PURPOSE: Port Class driver / Stubs
* PROGRAMMER: Andrew Greenwood
*
* HISTORY:
* 27 Jan 07 Created
*/
#include <portcls.h>
@ -51,18 +57,6 @@ PcNewMiniport(
return STATUS_UNSUCCESSFUL;
}
/*
* @unimplemented
*/
PORTCLASSAPI NTSTATUS NTAPI
PcNewPort(
OUT PPORT* OutPort,
IN REFCLSID ClassId)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
/*
* @unimplemented
*/
@ -82,36 +76,6 @@ PcNewRegistryKey(
return STATUS_UNSUCCESSFUL;
}
/*
* @unimplemented
*/
PORTCLASSAPI NTSTATUS NTAPI
PcNewResourceList(
OUT PRESOURCELIST* OutResourceList,
IN PUNKNOWN OuterUnknown OPTIONAL,
IN POOL_TYPE PoolType,
IN PCM_RESOURCE_LIST TranslatedResources,
IN PCM_RESOURCE_LIST UntranslatedResources)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
/*
* @unimplemented
*/
PORTCLASSAPI NTSTATUS NTAPI
PcNewResourceSublist(
OUT PRESOURCELIST* OutResourceList,
IN PUNKNOWN OuterUnknown OPTIONAL,
IN POOL_TYPE PoolType,
IN PRESOURCELIST ParentList,
IN ULONG MaximumEntries)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
/*
* @unimplemented
*/
@ -125,48 +89,6 @@ PcNewServiceGroup(
}
/* ===============================================================
IRP Handling
*/
/*
* @unimplemented
*/
PORTCLASSAPI NTSTATUS NTAPI
PcDispatchIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
/*
* @unimplemented
*/
PORTCLASSAPI NTSTATUS NTAPI
PcCompleteIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN NTSTATUS Status)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
/*
* @unimplemented
*/
PORTCLASSAPI NTSTATUS NTAPI
PcForwardIrpSynchronous(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
/* ===============================================================
Power Management
*/

View file

@ -0,0 +1,103 @@
/*
Undocumented PortCls exports
*/
#include <portcls.h>
PORTCLASSAPI NTSTATUS
KsoDispatchCreateWithGenericFactory(
LONG Unknown,
PIRP Irp)
{
}
PORTCLASSAPI void
KsoGetIrpTargetFromFileObject(
LONG Unknown)
{
}
PORTCLASSAPI void
KsoGetIrpTargetFromIrp(
LONG Unknown)
{
}
PORTCLASSAPI void
PcAcquireFormatResources(
LONG Unknown,
LONG Unknown2,
LONG Unknown3,
LONG Unknown4)
{
}
PORTCLASSAPI
NTSTATUS
PcAddToEventTable(
PVOID Ptr,
LONG Unknown2,
ULONG Length,
LONG Unknown3,
LONG Unknown4,
LONG Unknown5,
LONG Unknown6,
LONG Unknown7)
{
}
PORTCLASSAPI
NTSTATUS
PcAddToPropertyTable(
PVOID Ptr,
LONG Unknown,
LONG Unknown2,
LONG Unknown3,
CHAR Unknown4)
{
}
PORTCLASSAPI
NTSTATUS
PcCaptureFormat(
LONG Unknown,
LONG Unknown2,
LONG Unknown3,
LONG Unknown4)
{
}
PORTCLASSAPI
NTSTATUS
PcCreateSubdeviceDescriptor(
/* TODO */ )
{
}
/* PcDeleteSubdeviceDescriptor */
/* PcDmaMasterDescription */
/* PcDmaSlaveDescription */
/* PcFreeEventTable */
/* PcFreePropertyTable */
/* PcGenerateEventDeferredRoutine */
/* PcGenerateEventList */
/* PcHandleDisableEventWithTable */
/* PcHandleEnableEventWithTable */
/* PcHandlePropertyWithTable */
/* PcPinPropertyHandler */
/* PcTerminateConnection */
/* PcValidateConnectRequest */
/* PcVerifyFilterIsReady */