ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

driver.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS Kernel Streaming
00004  * FILE:            drivers/wdm/audio/legacy/stream/driver.c
00005  * PURPOSE:         WDM Codec Class Driver
00006  * PROGRAMMER:      Johannes Anderwald
00007  */
00008 
00009 #include "stream.h"
00010 
00011 NTSTATUS
00012 NTAPI
00013 StreamClassAddDevice(
00014     IN PDRIVER_OBJECT  DriverObject,
00015     IN PDEVICE_OBJECT  PhysicalDeviceObject)
00016 {
00017     PSTREAM_CLASS_DRIVER_EXTENSION DriverObjectExtension;
00018     PDEVICE_OBJECT DeviceObject, LowerDeviceObject;
00019     PSTREAM_DEVICE_EXTENSION DeviceExtension;
00020     PKSOBJECT_CREATE_ITEM ItemList;
00021     NTSTATUS Status;
00022 
00023     /* Fetch driver object extension */
00024     DriverObjectExtension = IoGetDriverObjectExtension(DriverObject, (PVOID)StreamClassAddDevice);
00025     if (!DriverObjectExtension)
00026     {
00027         /* Failed to get driver extension */
00028         return STATUS_DEVICE_DOES_NOT_EXIST;
00029     }
00030     /* Allocate Create Item */
00031     ItemList = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
00032     if (!ItemList)
00033     {
00034         /* Failed to allocated Create Item */
00035         return STATUS_INSUFFICIENT_RESOURCES;
00036     }
00037 
00038     /* Create the FDO */
00039     Status = IoCreateDevice(DriverObject, DriverObjectExtension->Data.DeviceExtensionSize + sizeof(STREAM_DEVICE_EXTENSION), NULL, FILE_DEVICE_KS, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, 0, &DeviceObject);
00040     if (!NT_SUCCESS(Status))
00041     {
00042         /* Failed to create the FDO */
00043         ExFreePool(ItemList);
00044         return Status;
00045     }
00046 
00047     /* Attach to device stack */
00048     LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
00049     if (!LowerDeviceObject)
00050     {
00051         /* Failed to attach */
00052         IoDeleteDevice(DeviceObject);
00053         return STATUS_UNSUCCESSFUL;
00054     }
00055 
00056     /* Zero Create item */
00057     RtlZeroMemory(ItemList, sizeof(KSOBJECT_CREATE_ITEM));
00058     /* Setup object class */
00059     RtlInitUnicodeString(&ItemList->ObjectClass, L"GLOBAL");
00060     /* Setup CreateDispatch routine */
00061     ItemList->Create = StreamClassCreateFilter;
00062 
00063     /* Get device extension */
00064     DeviceExtension = (PSTREAM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
00065     /* Zero device extension */
00066     RtlZeroMemory(DeviceExtension, sizeof(STREAM_DEVICE_EXTENSION));
00067     /* Initialize Ks streaming */
00068     Status = KsAllocateDeviceHeader(&DeviceExtension->Header, 1, ItemList);
00069     if (!NT_SUCCESS(Status))
00070     {
00071         /* Cleanup resources */
00072         IoDetachDevice(LowerDeviceObject);
00073         IoDeleteDevice(DeviceObject);
00074         ExFreePool(ItemList);
00075         return Status;
00076     }
00077 
00078     /* Store lower device object */
00079     DeviceExtension->LowerDeviceObject = LowerDeviceObject;
00080 
00081     /* Store physical device object */
00082     DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
00083     /* Store driver object extension */
00084     DeviceExtension->DriverExtension = DriverObjectExtension;
00085     /* Initialize memory list */
00086     InitializeListHead(&DeviceExtension->MemoryResourceList);
00087     /* Setup device extension */
00088     DeviceExtension->DeviceExtension = (PVOID) (DeviceExtension + 1);
00089     /* Init interrupt dpc */
00090     KeInitializeDpc(&DeviceExtension->InterruptDpc, StreamClassInterruptDpc, (PVOID)DeviceExtension);
00091 
00092     /* Set device transfer method */
00093     DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
00094     /* Clear init flag */
00095     DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
00096 
00097     return Status;
00098 }
00099 
00100 /*
00101  *@implemented
00102  */
00103 NTSTATUS
00104 STREAMAPI
00105 StreamClassRegisterAdapter(
00106     IN PVOID Argument1,
00107     IN PVOID Argument2,
00108     IN PHW_INITIALIZATION_DATA HwInitializationData)
00109 {
00110     NTSTATUS Status;
00111     PSTREAM_CLASS_DRIVER_EXTENSION DriverObjectExtension;
00112     PDRIVER_OBJECT DriverObject = (PDRIVER_OBJECT)Argument1;
00113 
00114     /* Allocate driver extension */
00115     Status = IoAllocateDriverObjectExtension(DriverObject, (PVOID)StreamClassAddDevice, sizeof(STREAM_CLASS_DRIVER_EXTENSION), (PVOID*)&DriverObjectExtension);
00116     if (!NT_SUCCESS(Status))
00117     {
00118         /* Failed to allocate */
00119         return STATUS_INSUFFICIENT_RESOURCES;
00120     }
00121 
00122     /* Zero driver object extension */
00123     RtlZeroMemory(DriverObjectExtension, sizeof(STREAM_CLASS_DRIVER_EXTENSION));
00124 
00125     /* copy HwInitializationData */
00126     RtlCopyMemory(&DriverObjectExtension->Data, HwInitializationData, sizeof(HW_INITIALIZATION_DATA));
00127 
00128     /* Setup device init methods */
00129     DriverObject->DriverExtension->AddDevice = StreamClassAddDevice;
00130     DriverObject->DriverUnload = KsNullDriverUnload;
00131 
00132     /* Setup irp handlers */
00133     DriverObject->MajorFunction[IRP_MJ_PNP] = StreamClassPnp;
00134     DriverObject->MajorFunction[IRP_MJ_POWER] = StreamClassPower;
00135     DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = StreamClassSystemControl;
00136     DriverObject->MajorFunction[IRP_MJ_CLEANUP] = StreamClassCleanup;
00137     DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = StreamClassFlushBuffers;
00138     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = StreamClassDeviceControl;
00139 
00140     /* Let Ks handle these */
00141     KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CREATE);
00142     KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
00143 
00144     return STATUS_SUCCESS;
00145 }
00146 
00147 /*
00148  *@implemented
00149  */
00150 
00151 VOID
00152 NTAPI
00153 StreamClassReenumerateStreams(
00154     IN PVOID  HwDeviceExtension,
00155     IN ULONG  StreamDescriptorSize)
00156 {
00157     HW_STREAM_REQUEST_BLOCK_EXT RequestBlock;
00158     PSTREAM_DEVICE_EXTENSION DeviceExtension;
00159     PHW_STREAM_DESCRIPTOR StreamDescriptor;
00160 
00161     if (!HwDeviceExtension || !StreamDescriptorSize)
00162         return;
00163 
00164     StreamDescriptor = ExAllocatePool(NonPagedPool, StreamDescriptorSize);
00165     if (!StreamDescriptor)
00166         return;
00167 
00168     /* Zero stream descriptor */
00169     RtlZeroMemory(StreamDescriptor, StreamDescriptorSize);
00170 
00171     /* Get our DeviceExtension */
00172     DeviceExtension = (PSTREAM_DEVICE_EXTENSION) ((ULONG_PTR)HwDeviceExtension - sizeof(STREAM_DEVICE_EXTENSION));
00173     ASSERT(DeviceExtension->DeviceExtension == HwDeviceExtension);
00174 
00175 
00176     /* Zero RequestBlock */
00177     RtlZeroMemory(&RequestBlock, sizeof(HW_STREAM_REQUEST_BLOCK_EXT));
00178 
00179     /* Setup get stream info struct */
00180     RequestBlock.Block.SizeOfThisPacket = sizeof(HW_STREAM_REQUEST_BLOCK);
00181     RequestBlock.Block.Command = SRB_GET_STREAM_INFO;
00182     RequestBlock.Block.CommandData.StreamBuffer = StreamDescriptor;
00183     KeInitializeEvent(&RequestBlock.Event, SynchronizationEvent, FALSE);
00184 
00185     /* FIXME SYNCHRONIZATION */
00186 
00187     /* Send the request */
00188     DeviceExtension->DriverExtension->Data.HwReceivePacket ((PHW_STREAM_REQUEST_BLOCK)&RequestBlock);
00189 
00190     /* Is the device already completed? */
00191     if (RequestBlock.Block.Status == STATUS_PENDING)
00192     {
00193         /* Request is pending, wait for result */
00194         KeWaitForSingleObject(&RequestBlock.Event, Executive, KernelMode, FALSE, NULL);
00195     }
00196 
00197     if (!NT_SUCCESS(RequestBlock.Block.Status))
00198     {
00199         /* Release Stream descriptor */
00200         ExFreePool(StreamDescriptor);
00201     }
00202     else
00203     {
00204         if (DeviceExtension->StreamDescriptor)
00205         {
00206             /* Release old stream descriptor */
00207             ExFreePool(DeviceExtension->StreamDescriptor);
00208         }
00209 
00210         /* Store stream descriptor */
00211         DeviceExtension->StreamDescriptor = StreamDescriptor;
00212         DeviceExtension->StreamDescriptorSize = StreamDescriptorSize;
00213     }
00214 
00215 }
00216 
00217 /*
00218  *@implemented
00219  */
00220 
00221 VOID
00222 NTAPI
00223 StreamClassDebugAssert(
00224     IN PCHAR File,
00225     IN ULONG Line,
00226     IN PCHAR AssertText,
00227     IN ULONG AssertValue)
00228 {
00229 #if DBG
00230     DbgBreakPoint();
00231 #endif
00232 }
00233 
00234 /*
00235  *@implemented
00236  */
00237 VOID
00238 __cdecl
00239 StreamClassDebugPrint(
00240     IN STREAM_DEBUG_LEVEL DebugPrintLevel,
00241     IN PCCHAR DebugMessage,
00242     ...)
00243 {
00244 #if DBG
00245     va_list ap;
00246 
00247     if (DebugPrintLevel <=STREAMDEBUG_LEVEL)
00248     {
00249         va_start(ap, DebugMessage);
00250 
00251         DbgPrint(DebugMessage, ap);
00252 
00253         va_end(ap);
00254     }
00255 #endif
00256 
00257 }
00258 
00259 /*
00260  *@unimplemented
00261  */
00262 VOID
00263 __cdecl
00264 StreamClassDeviceNotification(
00265     IN STREAM_MINIDRIVER_DEVICE_NOTIFICATION_TYPE  NotificationType,
00266     IN PVOID  HwDeviceExtension,
00267     IN PHW_STREAM_REQUEST_BLOCK  pSrb,
00268     IN PKSEVENT_ENTRY  EventEntry,
00269     IN GUID  *EventSet,
00270     IN ULONG  EventId)
00271 {
00272     PHW_STREAM_REQUEST_BLOCK_EXT RequestBlock;
00273     if (NotificationType == DeviceRequestComplete)
00274     {
00275         RequestBlock = (PHW_STREAM_REQUEST_BLOCK_EXT)pSrb;
00276 
00277         KeSetEvent(&RequestBlock->Event, 0, FALSE);
00278         return;
00279     }
00280 
00281     UNIMPLEMENTED
00282 }
00283 
00284 /*
00285  *@implemented
00286  */
00287 PVOID
00288 STREAMAPI
00289 StreamClassGetDmaBuffer(
00290     IN PVOID  HwDeviceExtension)
00291 {
00292     PSTREAM_DEVICE_EXTENSION DeviceExtension;
00293 
00294     /* Get our DeviceExtension */
00295     DeviceExtension = (PSTREAM_DEVICE_EXTENSION) ((ULONG_PTR)HwDeviceExtension - sizeof(STREAM_DEVICE_EXTENSION));
00296     ASSERT(DeviceExtension->DeviceExtension == HwDeviceExtension);
00297 
00298     return DeviceExtension->DmaCommonBuffer;
00299 }
00300 
00301 NTSTATUS
00302 NTAPI
00303 StreamClassRWCompletion(
00304     IN PDEVICE_OBJECT  DeviceObject,
00305     IN PIRP  Irp,
00306     IN PVOID  Context)
00307 {
00308     PIO_STATUS_BLOCK IoStatusBlock = (PIO_STATUS_BLOCK)Context;
00309 
00310     IoStatusBlock->Information = Irp->IoStatus.Information;
00311     IoStatusBlock->Status = Irp->IoStatus.Status;
00312 
00313     return STATUS_SUCCESS;
00314 }
00315 
00316 /*
00317  *@implemented
00318  */
00319 BOOLEAN
00320 STREAMAPI
00321 StreamClassReadWriteConfig(
00322     IN PVOID  HwDeviceExtension,
00323     IN BOOLEAN  Read,
00324     IN PVOID  Buffer,
00325     IN ULONG  OffSet,
00326     IN ULONG  Length)
00327 {
00328     PIRP Irp;
00329     ULONG MajorFunction;
00330     KEVENT Event;
00331     PSTREAM_DEVICE_EXTENSION DeviceExtension;
00332     LARGE_INTEGER Offset;
00333     IO_STATUS_BLOCK StatusBlock;
00334     NTSTATUS Status;
00335 
00336     /* Get our DeviceExtension */
00337     DeviceExtension = (PSTREAM_DEVICE_EXTENSION) ((ULONG_PTR)HwDeviceExtension - sizeof(STREAM_DEVICE_EXTENSION));
00338     ASSERT(DeviceExtension->DeviceExtension == HwDeviceExtension);
00339 
00340     if (Read)
00341     {
00342         /* Zero input buffer */
00343         RtlZeroMemory(Buffer, Length);
00344     }
00345 
00346     /* Set request type */
00347     MajorFunction = (Read ? IRP_MJ_READ : IRP_MJ_WRITE);
00348 
00349     /* Initialize event */
00350     KeInitializeEvent(&Event, NotificationEvent, FALSE);
00351 
00352     /* Set offset */
00353     Offset.QuadPart = OffSet;
00354 
00355     /* Pre-init status block */
00356     StatusBlock.Status = STATUS_NOT_SUPPORTED;
00357 
00358     /* Create Irp */
00359     Irp = IoBuildSynchronousFsdRequest(MajorFunction,
00360                                        DeviceExtension->LowerDeviceObject, /* Verify */
00361                                        Buffer,
00362                                        Length,
00363                                        &Offset,
00364                                        &Event,
00365                                        &StatusBlock);
00366 
00367     if (!Irp)
00368     {
00369         /* Failed to allocate memory */
00370         return FALSE;
00371     }
00372 
00373     /* Setup a completion routine */
00374     IoSetCompletionRoutine(Irp, StreamClassRWCompletion, (PVOID)&Event, TRUE, TRUE, TRUE);
00375 
00376     /* Call driver */
00377     Status = IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
00378 
00379     if (Status == STATUS_PENDING)
00380     {
00381         /* Request is pending, wait for result */
00382         KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
00383         /* Fetch result */
00384         Status = StatusBlock.Status;
00385     }
00386 
00387     if (!NT_SUCCESS(Status))
00388     {
00389         return FALSE;
00390     }
00391 
00392     /* FIXME Handle Length != InputLength */
00393     return TRUE;
00394 }

Generated on Fri May 25 2012 04:17:01 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.