Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenconnectivity.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/ksfilter/ks/connectivity.c 00005 * PURPOSE: KS Pin functions 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 00010 #include "priv.h" 00011 00012 KSPIN_INTERFACE StandardPinInterface = 00013 { 00014 {STATIC_KSINTERFACESETID_Standard}, 00015 KSINTERFACE_STANDARD_STREAMING, 00016 0 00017 }; 00018 00019 KSPIN_MEDIUM StandardPinMedium = 00020 { 00021 {STATIC_KSMEDIUMSETID_Standard}, 00022 KSMEDIUM_TYPE_ANYINSTANCE, 00023 0 00024 }; 00025 00026 const GUID KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT = {0xf4aeb342, 0x0329, 0x4fdd, {0xa8, 0xfd, 0x4a, 0xff, 0x49, 0x26, 0xc9, 0x78}}; 00027 00028 /* 00029 @implemented 00030 */ 00031 KSDDKAPI 00032 NTSTATUS 00033 NTAPI 00034 KsCreatePin( 00035 IN HANDLE FilterHandle, 00036 IN PKSPIN_CONNECT Connect, 00037 IN ACCESS_MASK DesiredAccess, 00038 OUT PHANDLE ConnectionHandle) 00039 { 00040 UINT ConnectSize = sizeof(KSPIN_CONNECT); 00041 00042 PKSDATAFORMAT_WAVEFORMATEX Format = (PKSDATAFORMAT_WAVEFORMATEX)(Connect + 1); 00043 if (Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) || 00044 Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX)) 00045 { 00046 ConnectSize += Format->DataFormat.FormatSize; 00047 } 00048 00049 return KspCreateObjectType(FilterHandle, 00050 KSSTRING_Pin, 00051 (PVOID)Connect, 00052 ConnectSize, 00053 DesiredAccess, 00054 ConnectionHandle); 00055 } 00056 00057 NTSTATUS 00058 KspValidateConnectRequest( 00059 IN PIRP Irp, 00060 IN ULONG DescriptorsCount, 00061 IN PVOID Descriptors, 00062 IN ULONG DescriptorSize, 00063 OUT PKSPIN_CONNECT* Connect) 00064 { 00065 PKSPIN_CONNECT ConnectDetails; 00066 PKSPIN_INTERFACE Interface; 00067 PKSPIN_MEDIUM Medium; 00068 ULONG Size; 00069 NTSTATUS Status; 00070 ULONG Index; 00071 ULONG Count; 00072 BOOLEAN Found; 00073 PKSPIN_DESCRIPTOR Descriptor; 00074 00075 /* did the caller miss the connect parameter */ 00076 if (!Connect) 00077 return STATUS_INVALID_PARAMETER; 00078 00079 /* set create param size */ 00080 Size = sizeof(KSPIN_CONNECT); 00081 00082 /* fetch create parameters */ 00083 Status = KspCopyCreateRequest(Irp, 00084 KSSTRING_Pin, 00085 &Size, 00086 (PVOID*)&ConnectDetails); 00087 00088 /* check for success */ 00089 if (!NT_SUCCESS(Status)) 00090 return Status; 00091 00092 /* is pin id out of bounds */ 00093 if (ConnectDetails->PinId >= DescriptorsCount) 00094 return STATUS_INVALID_PARAMETER; 00095 00096 if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR)) 00097 { 00098 /* standard pin descriptor */ 00099 Descriptor = (PKSPIN_DESCRIPTOR)((ULONG_PTR)Descriptors + sizeof(KSPIN_DESCRIPTOR) * ConnectDetails->PinId); 00100 } 00101 else 00102 { 00103 /* extended / variable pin descriptor */ 00104 Descriptor = &((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + DescriptorSize * ConnectDetails->PinId))->PinDescriptor; 00105 } 00106 00107 00108 /* does the pin have interface details filled in */ 00109 if (Descriptor->InterfacesCount && Descriptor->Interfaces) 00110 { 00111 /* use provided pin interface count */ 00112 Count = Descriptor->InterfacesCount; 00113 Interface = (PKSPIN_INTERFACE)Descriptor->Interfaces; 00114 } 00115 else 00116 { 00117 /* use standard pin interface */ 00118 Count = 1; 00119 Interface = &StandardPinInterface; 00120 } 00121 00122 /* now check the interface */ 00123 Found = FALSE; 00124 Index = 0; 00125 do 00126 { 00127 UNICODE_STRING GuidString, GuidString2; 00128 RtlStringFromGUID(&Interface[Index].Set, &GuidString); 00129 RtlStringFromGUID(&ConnectDetails->Interface.Set, &GuidString2); 00130 00131 DPRINT("Driver Interface %S Id %u\n", GuidString.Buffer, Interface[Index].Id); 00132 DPRINT("Connect Interface %S Id %u\n", GuidString2.Buffer, ConnectDetails->Interface.Id); 00133 00134 if (IsEqualGUIDAligned(&Interface[Index].Set, &ConnectDetails->Interface.Set) && 00135 Interface[Index].Id == ConnectDetails->Interface.Id) 00136 { 00137 /* found a matching interface */ 00138 Found = TRUE; 00139 break; 00140 } 00141 /* iterate to next interface */ 00142 Index++; 00143 }while(Index < Count); 00144 00145 if (!Found) 00146 { 00147 /* pin doesnt support this interface */ 00148 return STATUS_NO_MATCH; 00149 } 00150 00151 /* does the pin have medium details filled in */ 00152 if (Descriptor->MediumsCount && Descriptor->Mediums) 00153 { 00154 /* use provided pin interface count */ 00155 Count = Descriptor->MediumsCount; 00156 Medium = (PKSPIN_MEDIUM)Descriptor->Mediums; 00157 } 00158 else 00159 { 00160 /* use standard pin interface */ 00161 Count = 1; 00162 Medium = &StandardPinMedium; 00163 } 00164 00165 /* now check the interface */ 00166 Found = FALSE; 00167 Index = 0; 00168 do 00169 { 00170 UNICODE_STRING GuidString, GuidString2; 00171 RtlStringFromGUID(&Medium[Index].Set, &GuidString); 00172 RtlStringFromGUID(&ConnectDetails->Medium.Set, &GuidString2); 00173 00174 DPRINT("Driver Medium %S Id %u\n", GuidString.Buffer, Medium[Index].Id); 00175 DPRINT("Connect Medium %S Id %u\n", GuidString2.Buffer, ConnectDetails->Medium.Id); 00176 00177 00178 if (IsEqualGUIDAligned(&Medium[Index].Set, &ConnectDetails->Medium.Set) && 00179 Medium[Index].Id == ConnectDetails->Medium.Id) 00180 { 00181 /* found a matching interface */ 00182 Found = TRUE; 00183 break; 00184 } 00185 00186 00187 00188 /* iterate to next medium */ 00189 Index++; 00190 }while(Index < Count); 00191 00192 if (!Found) 00193 { 00194 /* pin doesnt support this medium */ 00195 return STATUS_NO_MATCH; 00196 } 00197 00200 00201 *Connect = ConnectDetails; 00202 return STATUS_SUCCESS; 00203 } 00204 00205 /* 00206 @implemented 00207 */ 00208 KSDDKAPI 00209 NTSTATUS 00210 NTAPI 00211 KsValidateConnectRequest( 00212 IN PIRP Irp, 00213 IN ULONG DescriptorsCount, 00214 IN KSPIN_DESCRIPTOR* Descriptor, 00215 OUT PKSPIN_CONNECT* Connect) 00216 { 00217 return KspValidateConnectRequest(Irp, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR), Connect); 00218 } 00219 00220 NTSTATUS 00221 KspReadMediaCategory( 00222 IN LPGUID Category, 00223 PKEY_VALUE_PARTIAL_INFORMATION *OutInformation) 00224 { 00225 UNICODE_STRING MediaPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories\\"); 00226 UNICODE_STRING Name = RTL_CONSTANT_STRING(L"Name"); 00227 UNICODE_STRING GuidString, Path; 00228 NTSTATUS Status; 00229 OBJECT_ATTRIBUTES ObjectAttributes; 00230 HANDLE hKey; 00231 ULONG Size; 00232 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo; 00233 00234 /* convert the guid to string */ 00235 Status = RtlStringFromGUID(Category, &GuidString); 00236 if (!NT_SUCCESS(Status)) 00237 return Status; 00238 00239 /* allocate buffer for the registry key */ 00240 Path.Length = 0; 00241 Path.MaximumLength = MediaPath.MaximumLength + GuidString.MaximumLength; 00242 Path.Buffer = AllocateItem(NonPagedPool, Path.MaximumLength); 00243 if (!Path.Buffer) 00244 { 00245 /* not enough memory */ 00246 RtlFreeUnicodeString(&GuidString); 00247 return STATUS_INSUFFICIENT_RESOURCES; 00248 } 00249 00250 RtlAppendUnicodeStringToString(&Path, &MediaPath); 00251 RtlAppendUnicodeStringToString(&Path, &GuidString); 00252 00253 /* free guid string */ 00254 RtlFreeUnicodeString(&GuidString); 00255 00256 /* initialize object attributes */ 00257 InitializeObjectAttributes(&ObjectAttributes, &Path, OBJ_CASE_INSENSITIVE, NULL, NULL); 00258 00259 /* open the key */ 00260 Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes); 00261 00262 DPRINT("ZwOpenKey() status 0x%08lx %wZ\n", Status, &Path); 00263 00264 /* free path buffer */ 00265 FreeItem(Path.Buffer); 00266 00267 /* check for success */ 00268 if (!NT_SUCCESS(Status)) 00269 { 00270 DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status); 00271 return Status; 00272 } 00273 00274 /* query the name size */ 00275 Status = ZwQueryValueKey(hKey, &Name, KeyValuePartialInformation, NULL, 0, &Size); 00276 if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL) 00277 { 00278 /* failed to query for name key */ 00279 ZwClose(hKey); 00280 return Status; 00281 } 00282 00283 /* allocate buffer to read key info */ 00284 KeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION) AllocateItem(NonPagedPool, Size); 00285 if (!KeyInfo) 00286 { 00287 /* not enough memory */ 00288 ZwClose(hKey); 00289 return STATUS_INSUFFICIENT_RESOURCES; 00290 } 00291 00292 /* now read the info */ 00293 Status = ZwQueryValueKey(hKey, &Name, KeyValuePartialInformation, (PVOID)KeyInfo, Size, &Size); 00294 00295 /* close the key */ 00296 ZwClose(hKey); 00297 00298 if (!NT_SUCCESS(Status)) 00299 { 00300 /* failed to read key */ 00301 FreeItem(KeyInfo); 00302 return Status; 00303 } 00304 00305 /* store key information */ 00306 *OutInformation = KeyInfo; 00307 return Status; 00308 } 00309 00310 KSDDKAPI 00311 NTSTATUS 00312 NTAPI 00313 KspPinPropertyHandler( 00314 IN PIRP Irp, 00315 IN PKSPROPERTY Property, 00316 IN OUT PVOID Data, 00317 IN ULONG DescriptorsCount, 00318 IN const KSPIN_DESCRIPTOR* Descriptors, 00319 IN ULONG DescriptorSize) 00320 { 00321 KSP_PIN * Pin; 00322 KSMULTIPLE_ITEM * Item; 00323 PIO_STACK_LOCATION IoStack; 00324 ULONG Size, Index; 00325 PVOID Buffer; 00326 PKSDATARANGE_AUDIO *WaveFormatOut; 00327 PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn; 00328 PKEY_VALUE_PARTIAL_INFORMATION KeyInfo; 00329 const KSPIN_DESCRIPTOR *Descriptor; 00330 NTSTATUS Status = STATUS_NOT_SUPPORTED; 00331 ULONG Count; 00332 const PKSDATARANGE* DataRanges; 00333 LPGUID Guid; 00334 00335 IoStack = IoGetCurrentIrpStackLocation(Irp); 00336 Buffer = Data; 00337 00338 //DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount, Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id); 00339 00340 /* convert to PKSP_PIN */ 00341 Pin = (KSP_PIN*)Property; 00342 00343 if (Property->Id != KSPROPERTY_PIN_CTYPES) 00344 { 00345 if (Pin->PinId >= DescriptorsCount) 00346 { 00347 /* invalid parameter */ 00348 return STATUS_INVALID_PARAMETER; 00349 } 00350 } 00351 00352 if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR)) 00353 { 00354 /* it is simple pin descriptor */ 00355 Descriptor = &Descriptors[Pin->PinId]; 00356 } 00357 else 00358 { 00359 /* get offset to pin descriptor */ 00360 Descriptor = &(((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + Pin->PinId * DescriptorSize))->PinDescriptor); 00361 } 00362 00363 switch(Property->Id) 00364 { 00365 case KSPROPERTY_PIN_CTYPES: 00366 (*(PULONG)Buffer) = DescriptorsCount; 00367 Irp->IoStatus.Information = sizeof(ULONG); 00368 Status = STATUS_SUCCESS; 00369 break; 00370 case KSPROPERTY_PIN_DATAFLOW: 00371 00372 Size = sizeof(KSPIN_DATAFLOW); 00373 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size) 00374 { 00375 Irp->IoStatus.Information = Size; 00376 Status = STATUS_BUFFER_TOO_SMALL; 00377 break; 00378 } 00379 00380 *((KSPIN_DATAFLOW*)Buffer) = Descriptor->DataFlow; 00381 Irp->IoStatus.Information = sizeof(KSPIN_DATAFLOW); 00382 Status = STATUS_SUCCESS; 00383 break; 00384 00385 case KSPROPERTY_PIN_DATARANGES: 00386 case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: 00387 00388 Size = sizeof(KSMULTIPLE_ITEM); 00389 DPRINT("Id %lu PinId %lu DataRangesCount %lu ConstrainedDataRangesCount %lu\n", Property->Id, Pin->PinId, Descriptor->DataRangesCount, Descriptor->ConstrainedDataRangesCount); 00390 00391 if (Property->Id == KSPROPERTY_PIN_DATARANGES || Descriptor->ConstrainedDataRangesCount == 0) 00392 { 00393 DataRanges = Descriptor->DataRanges; 00394 Count = Descriptor->DataRangesCount; 00395 } 00396 else 00397 { 00398 DataRanges = Descriptor->ConstrainedDataRanges; 00399 Count = Descriptor->ConstrainedDataRangesCount; 00400 } 00401 00402 for (Index = 0; Index < Count; Index++) 00403 { 00404 Size += ((DataRanges[Index]->FormatSize + 0x7) & ~0x7); 00405 } 00406 00407 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0) 00408 { 00409 /* buffer too small */ 00410 Irp->IoStatus.Information = Size; 00411 Status = STATUS_BUFFER_OVERFLOW; 00412 break; 00413 } 00414 00415 Item = (KSMULTIPLE_ITEM*)Buffer; 00416 00417 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(ULONG)) 00418 { 00419 /* store the result size */ 00420 Item->Size = Size; 00421 Irp->IoStatus.Information = sizeof(ULONG); 00422 Status = STATUS_SUCCESS; 00423 break; 00424 } 00425 00426 /* store descriptor size */ 00427 Item->Size = Size; 00428 Item->Count = Count; 00429 00430 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(KSMULTIPLE_ITEM)) 00431 { 00432 Irp->IoStatus.Information = sizeof(KSMULTIPLE_ITEM); 00433 Status = STATUS_SUCCESS; 00434 break; 00435 } 00436 00437 /* now copy all dataranges */ 00438 Data = (PUCHAR)(Item +1); 00439 00440 /* alignment assert */ 00441 ASSERT(((ULONG_PTR)Data & 0x7) == 0); 00442 00443 for (Index = 0; Index < Count; Index++) 00444 { 00445 UNICODE_STRING GuidString; 00446 /* convert the guid to string */ 00447 RtlStringFromGUID(&DataRanges[Index]->MajorFormat, &GuidString); 00448 DPRINT("Index %lu MajorFormat %S\n", Index, GuidString.Buffer); 00449 RtlStringFromGUID(&DataRanges[Index]->SubFormat, &GuidString); 00450 DPRINT("Index %lu SubFormat %S\n", Index, GuidString.Buffer); 00451 RtlStringFromGUID(&DataRanges[Index]->Specifier, &GuidString); 00452 DPRINT("Index %lu Specifier %S\n", Index, GuidString.Buffer); 00453 RtlStringFromGUID(&DataRanges[Index]->Specifier, &GuidString); 00454 DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index, 00455 DataRanges[Index]->FormatSize, DataRanges[Index]->Flags, DataRanges[Index]->SampleSize, DataRanges[Index]->Reserved, sizeof(KSDATAFORMAT)); 00456 00457 RtlMoveMemory(Data, DataRanges[Index], DataRanges[Index]->FormatSize); 00458 Data = ((PUCHAR)Data + DataRanges[Index]->FormatSize); 00459 /* alignment assert */ 00460 ASSERT(((ULONG_PTR)Data & 0x7) == 0); 00461 Data = (PVOID)(((ULONG_PTR)Data + 0x7) & ~0x7); 00462 } 00463 00464 Status = STATUS_SUCCESS; 00465 Irp->IoStatus.Information = Size; 00466 break; 00467 case KSPROPERTY_PIN_INTERFACES: 00468 00469 if (Descriptor->Interfaces) 00470 { 00471 /* use mediums provided by driver */ 00472 return KsHandleSizedListQuery(Irp, Descriptor->InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor->Interfaces); 00473 } 00474 else 00475 { 00476 /* use standard medium */ 00477 return KsHandleSizedListQuery(Irp, 1, sizeof(KSPIN_INTERFACE), &StandardPinInterface); 00478 } 00479 break; 00480 00481 case KSPROPERTY_PIN_MEDIUMS: 00482 00483 if (Descriptor->MediumsCount) 00484 { 00485 /* use mediums provided by driver */ 00486 return KsHandleSizedListQuery(Irp, Descriptor->MediumsCount, sizeof(KSPIN_MEDIUM), Descriptor->Mediums); 00487 } 00488 else 00489 { 00490 /* use standard medium */ 00491 return KsHandleSizedListQuery(Irp, 1, sizeof(KSPIN_MEDIUM), &StandardPinMedium); 00492 } 00493 break; 00494 00495 case KSPROPERTY_PIN_COMMUNICATION: 00496 00497 Size = sizeof(KSPIN_COMMUNICATION); 00498 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size) 00499 { 00500 Irp->IoStatus.Information = Size; 00501 Status = STATUS_BUFFER_TOO_SMALL; 00502 break; 00503 } 00504 00505 *((KSPIN_COMMUNICATION*)Buffer) = Descriptor->Communication; 00506 00507 Status = STATUS_SUCCESS; 00508 Irp->IoStatus.Information = Size; 00509 break; 00510 00511 case KSPROPERTY_PIN_CATEGORY: 00512 00513 if (!Descriptor->Category) 00514 { 00515 /* no pin category */ 00516 return STATUS_NOT_FOUND; 00517 } 00518 00519 /* check size */ 00520 Size = sizeof(GUID); 00521 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size) 00522 { 00523 /* buffer too small */ 00524 Irp->IoStatus.Information = Size; 00525 Status = STATUS_BUFFER_TOO_SMALL; 00526 break; 00527 } 00528 00529 /* copy category guid */ 00530 RtlMoveMemory(Buffer, Descriptor->Category, sizeof(GUID)); 00531 00532 /* save result */ 00533 Status = STATUS_SUCCESS; 00534 Irp->IoStatus.Information = Size; 00535 break; 00536 00537 case KSPROPERTY_PIN_NAME: 00538 00539 if (Descriptor->Name) 00540 { 00541 /* use pin name */ 00542 Guid = (LPGUID)Descriptor->Name; 00543 } 00544 else 00545 { 00546 /* use pin category as fallback */ 00547 Guid = (LPGUID)Descriptor->Category; 00548 } 00549 00550 if (!Guid) 00551 { 00552 /* no friendly name available */ 00553 return STATUS_NOT_FOUND; 00554 } 00555 00556 /* read friendly name category name */ 00557 Status = KspReadMediaCategory(Guid, &KeyInfo); 00558 if (!NT_SUCCESS(Status)) 00559 { 00560 /* failed to read category */ 00561 Irp->IoStatus.Information = 0; 00562 break; 00563 } 00564 00565 /* store required length */ 00566 Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR); 00567 00568 /* check if buffer is too small */ 00569 if (KeyInfo->DataLength + sizeof(WCHAR) > IoStack->Parameters.DeviceIoControl.OutputBufferLength) 00570 { 00571 /* buffer too small */ 00572 Status = STATUS_BUFFER_OVERFLOW; 00573 FreeItem(KeyInfo); 00574 break; 00575 } 00576 00577 /* copy result */ 00578 RtlMoveMemory(Irp->UserBuffer, &KeyInfo->Data, KeyInfo->DataLength); 00579 00580 /* null terminate name */ 00581 ((LPWSTR)Irp->UserBuffer)[KeyInfo->DataLength / sizeof(WCHAR)] = L'\0'; 00582 00583 /* free key info */ 00584 FreeItem(KeyInfo); 00585 break; 00586 case KSPROPERTY_PIN_PROPOSEDATAFORMAT: 00587 Size = sizeof(KSDATAFORMAT); 00588 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size) 00589 { 00590 Irp->IoStatus.Information = Size; 00591 Status = STATUS_BUFFER_TOO_SMALL; 00592 break; 00593 } 00594 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(KSDATAFORMAT_WAVEFORMATEX)) 00595 { 00596 UNIMPLEMENTED 00597 Status = STATUS_NOT_IMPLEMENTED; 00598 Irp->IoStatus.Information = 0; 00599 break; 00600 } 00601 00602 WaveFormatIn = (PKSDATAFORMAT_WAVEFORMATEX)Buffer; 00603 if (!Descriptor->DataRanges || !Descriptor->DataRangesCount) 00604 { 00605 Status = STATUS_UNSUCCESSFUL; 00606 Irp->IoStatus.Information = 0; 00607 break; 00608 } 00609 WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor->DataRanges; 00610 for(Index = 0; Index < Descriptor->DataRangesCount; Index++) 00611 { 00612 if (WaveFormatOut[Index]->DataRange.FormatSize != sizeof(KSDATARANGE_AUDIO)) 00613 { 00614 UNIMPLEMENTED 00615 continue; 00616 } 00617 00618 if (WaveFormatOut[Index]->MinimumSampleFrequency > WaveFormatIn->WaveFormatEx.nSamplesPerSec || 00619 WaveFormatOut[Index]->MaximumSampleFrequency < WaveFormatIn->WaveFormatEx.nSamplesPerSec || 00620 WaveFormatOut[Index]->MinimumBitsPerSample > WaveFormatIn->WaveFormatEx.wBitsPerSample || 00621 WaveFormatOut[Index]->MaximumBitsPerSample < WaveFormatIn->WaveFormatEx.wBitsPerSample || 00622 WaveFormatOut[Index]->MaximumChannels < WaveFormatIn->WaveFormatEx.nChannels) 00623 { 00624 Irp->IoStatus.Status = STATUS_NO_MATCH; 00625 Irp->IoStatus.Information = 0; 00626 return STATUS_NO_MATCH; 00627 } 00628 else 00629 { 00630 Irp->IoStatus.Status = STATUS_SUCCESS; 00631 Irp->IoStatus.Information = 0; 00632 return STATUS_SUCCESS; 00633 } 00634 } 00635 Status = STATUS_NO_MATCH; 00636 Irp->IoStatus.Information = 0; 00637 break; 00638 default: 00639 DPRINT1("Unhandled property request %x\n", Property->Id); 00640 Status = STATUS_NOT_IMPLEMENTED; 00641 Irp->IoStatus.Information = 0; 00642 } 00643 00644 return Status; 00645 } 00646 00647 /* 00648 @implemented 00649 */ 00650 KSDDKAPI 00651 NTSTATUS 00652 NTAPI 00653 KsPinPropertyHandler( 00654 IN PIRP Irp, 00655 IN PKSPROPERTY Property, 00656 IN OUT PVOID Data, 00657 IN ULONG DescriptorsCount, 00658 IN const KSPIN_DESCRIPTOR* Descriptor) 00659 { 00660 return KspPinPropertyHandler(Irp, Property, Data, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR)); 00661 } 00662 00663 /* 00664 @unimplemented 00665 */ 00666 KSDDKAPI NTSTATUS NTAPI 00667 KsPinDataIntersectionEx( 00668 IN PIRP Irp, 00669 IN PKSP_PIN Pin, 00670 OUT PVOID Data, 00671 IN ULONG DescriptorsCount, 00672 IN const KSPIN_DESCRIPTOR* Descriptor, 00673 IN ULONG DescriptorSize, 00674 IN PFNKSINTERSECTHANDLEREX IntersectHandler OPTIONAL, 00675 IN PVOID HandlerContext OPTIONAL) 00676 { 00677 UNIMPLEMENTED; 00678 return STATUS_UNSUCCESSFUL; 00679 } 00680 00681 /* 00682 @implemented 00683 */ 00684 KSDDKAPI 00685 NTSTATUS 00686 NTAPI 00687 KsPinDataIntersection( 00688 IN PIRP Irp, 00689 IN PKSP_PIN Pin, 00690 OUT PVOID Data, 00691 IN ULONG DescriptorsCount, 00692 IN const KSPIN_DESCRIPTOR* Descriptor, 00693 IN PFNKSINTERSECTHANDLER IntersectHandler) 00694 { 00695 KSMULTIPLE_ITEM * Item; 00696 KSDATARANGE * DataRange; 00697 PIO_STACK_LOCATION IoStack; 00698 ULONG Size; 00699 ULONG Index; 00700 NTSTATUS Status; 00701 00702 /* get current irp stack location */ 00703 IoStack = IoGetCurrentIrpStackLocation(Irp); 00704 00705 /* calculate minimum data size */ 00706 Size = sizeof(KSP_PIN) + sizeof(KSMULTIPLE_ITEM) + sizeof(KSDATARANGE); 00707 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < Size) 00708 { 00709 /* buffer too small */ 00710 Irp->IoStatus.Information = Size; 00711 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 00712 return STATUS_BUFFER_TOO_SMALL; 00713 } 00714 /* is pin id out of bounds */ 00715 if (Pin->PinId >= DescriptorsCount) 00716 { 00717 /* it is */ 00718 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 00719 Irp->IoStatus.Information = 0; 00720 return STATUS_INVALID_PARAMETER; 00721 } 00722 00723 /* get start item */ 00724 Item = (KSMULTIPLE_ITEM*)(Pin + 1); 00725 /* get first data range */ 00726 DataRange = (KSDATARANGE*)(Item + 1); 00727 /* iterate through all data ranges */ 00728 for(Index = 0; Index < Item->Count; Index++, DataRange++) 00729 { 00730 /* call intersect handler */ 00731 Status = IntersectHandler(Irp, Pin, DataRange, Data); 00732 if (NT_SUCCESS(Status)) 00733 { 00734 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < DataRange->FormatSize) 00735 { 00736 /* buffer is too small */ 00737 Irp->IoStatus.Information = DataRange->FormatSize; 00738 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 00739 return STATUS_BUFFER_TOO_SMALL; 00740 } 00741 RtlMoveMemory(Irp->UserBuffer, DataRange, sizeof(KSDATARANGE)); 00742 Irp->IoStatus.Information = sizeof(KSDATARANGE); 00743 Irp->IoStatus.Status = STATUS_SUCCESS; 00744 return STATUS_SUCCESS; 00745 } 00746 00747 } 00748 00749 Irp->IoStatus.Information = 0; 00750 Irp->IoStatus.Status = STATUS_NO_MATCH; 00751 return STATUS_NO_MATCH; 00752 } 00753 00754 /* 00755 @implemented 00756 */ 00757 00758 KSDDKAPI 00759 NTSTATUS 00760 NTAPI 00761 KsHandleSizedListQuery( 00762 IN PIRP Irp, 00763 IN ULONG DataItemsCount, 00764 IN ULONG DataItemSize, 00765 IN const VOID* DataItems) 00766 { 00767 ULONG Size; 00768 PIO_STACK_LOCATION IoStack; 00769 PKSMULTIPLE_ITEM Item; 00770 00771 /* get current irp stack location */ 00772 IoStack = IoGetCurrentIrpStackLocation(Irp); 00773 00774 /* calculate size */ 00775 Size = DataItemSize * DataItemsCount + sizeof(KSMULTIPLE_ITEM); 00776 00777 /* get multiple item */ 00778 Item = (PKSMULTIPLE_ITEM)Irp->AssociatedIrp.SystemBuffer; 00779 00780 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0) 00781 { 00782 /* buffer too small */ 00783 Irp->IoStatus.Information = Size; 00784 00785 return STATUS_BUFFER_OVERFLOW; 00786 } 00787 00788 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(ULONG)) 00789 { 00790 /* store just the size */ 00791 Item->Size = Size; 00792 Irp->IoStatus.Information = sizeof(ULONG); 00793 00794 return STATUS_SUCCESS; 00795 } 00796 00797 00798 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSMULTIPLE_ITEM)) 00799 { 00800 /* buffer too small */ 00801 return STATUS_BUFFER_TOO_SMALL; 00802 } 00803 00804 Item->Count = DataItemsCount; 00805 Item->Size = DataItemSize; 00806 00807 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(KSMULTIPLE_ITEM)) 00808 { 00809 /* buffer can only hold the length descriptor */ 00810 Irp->IoStatus.Information = sizeof(KSMULTIPLE_ITEM); 00811 return STATUS_SUCCESS; 00812 } 00813 00814 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= Size) 00815 { 00816 /* copy items */ 00817 RtlMoveMemory((PVOID)(Item + 1), DataItems, DataItemSize * DataItemsCount); 00818 /* store result */ 00819 Irp->IoStatus.Information = Size; 00820 /* done */ 00821 return STATUS_SUCCESS; 00822 } 00823 else 00824 { 00825 /* buffer too small */ 00826 return STATUS_BUFFER_TOO_SMALL; 00827 } 00828 } 00829 Generated on Sun May 27 2012 04:27:51 for ReactOS by
1.7.6.1
|