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

connectivity.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 doxygen 1.7.6.1

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