Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendriver.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
1.7.6.1
|