ReactOS  0.4.13-dev-259-g5ca9c9c
connectivity.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Kernel Streaming
4  * FILE: drivers/ksfilter/ks/connectivity.c
5  * PURPOSE: KS Pin functions
6  * PROGRAMMER: Johannes Anderwald
7  */
8 
9 #include "precomp.h"
10 
11 #define NDEBUG
12 #include <debug.h>
13 
15 {
18  0
19 };
20 
22 {
25  0
26 };
27 
28 const GUID KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT = {0xf4aeb342, 0x0329, 0x4fdd, {0xa8, 0xfd, 0x4a, 0xff, 0x49, 0x26, 0xc9, 0x78}};
29 
30 /*
31  @implemented
32 */
35 NTAPI
37  IN HANDLE FilterHandle,
41 {
42  UINT ConnectSize = sizeof(KSPIN_CONNECT);
43 
45  if (Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) ||
46  Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX))
47  {
48  ConnectSize += Format->DataFormat.FormatSize;
49  }
50 
51  return KspCreateObjectType(FilterHandle,
53  (PVOID)Connect,
54  ConnectSize,
57 }
58 
61  IN PIRP Irp,
62  IN ULONG DescriptorsCount,
63  IN PVOID Descriptors,
64  IN ULONG DescriptorSize,
66 {
67  PKSPIN_CONNECT ConnectDetails;
69  PKSPIN_MEDIUM Medium;
70  ULONG Size;
72  ULONG Index;
73  ULONG Count;
74  BOOLEAN Found;
75  PKSPIN_DESCRIPTOR Descriptor;
76  UNICODE_STRING GuidString2;
77 
78  /* did the caller miss the connect parameter */
79  if (!Connect)
81 
82  /* set create param size */
83  Size = sizeof(KSPIN_CONNECT);
84 
85  /* fetch create parameters */
88  &Size,
89  (PVOID*)&ConnectDetails);
90 
91  /* check for success */
92  if (!NT_SUCCESS(Status))
93  return Status;
94 
95  /* is pin id out of bounds */
96  if (ConnectDetails->PinId >= DescriptorsCount)
97  {
98  FreeItem(ConnectDetails);
100  }
101 
102  if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR))
103  {
104  /* standard pin descriptor */
105  Descriptor = (PKSPIN_DESCRIPTOR)((ULONG_PTR)Descriptors + sizeof(KSPIN_DESCRIPTOR) * ConnectDetails->PinId);
106  }
107  else
108  {
109  /* extended / variable pin descriptor */
110  Descriptor = &((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + DescriptorSize * ConnectDetails->PinId))->PinDescriptor;
111  }
112 
113 
114  /* does the pin have interface details filled in */
115  if (Descriptor->InterfacesCount && Descriptor->Interfaces)
116  {
117  /* use provided pin interface count */
118  Count = Descriptor->InterfacesCount;
119  Interface = (PKSPIN_INTERFACE)Descriptor->Interfaces;
120  }
121  else
122  {
123  /* use standard pin interface */
124  Count = 1;
126  }
127 
128  /* now check the interface */
129  Found = FALSE;
130  Index = 0;
131  RtlStringFromGUID(&ConnectDetails->Interface.Set, &GuidString2);
132  do
133  {
136 
137  DPRINT("Driver Interface %S Id %u\n", GuidString.Buffer, Interface[Index].Id);
138  DPRINT("Connect Interface %S Id %u\n", GuidString2.Buffer, ConnectDetails->Interface.Id);
139 
141 
142  if (IsEqualGUIDAligned(&Interface[Index].Set, &ConnectDetails->Interface.Set) &&
143  Interface[Index].Id == ConnectDetails->Interface.Id)
144  {
145  /* found a matching interface */
146  Found = TRUE;
147  break;
148  }
149  /* iterate to next interface */
150  Index++;
151  }while(Index < Count);
152  RtlFreeUnicodeString(&GuidString2);
153 
154  if (!Found)
155  {
156  /* pin doesnt support this interface */
157  FreeItem(ConnectDetails);
158  return STATUS_NO_MATCH;
159  }
160 
161  /* does the pin have medium details filled in */
162  if (Descriptor->MediumsCount && Descriptor->Mediums)
163  {
164  /* use provided pin interface count */
165  Count = Descriptor->MediumsCount;
166  Medium = (PKSPIN_MEDIUM)Descriptor->Mediums;
167  }
168  else
169  {
170  /* use standard pin interface */
171  Count = 1;
172  Medium = &StandardPinMedium;
173  }
174 
175  /* now check the interface */
176  Found = FALSE;
177  Index = 0;
178  RtlStringFromGUID(&ConnectDetails->Medium.Set, &GuidString2);
179  do
180  {
183 
184  DPRINT("Driver Medium %S Id %u\n", GuidString.Buffer, Medium[Index].Id);
185  DPRINT("Connect Medium %S Id %u\n", GuidString2.Buffer, ConnectDetails->Medium.Id);
186 
188 
189  if (IsEqualGUIDAligned(&Medium[Index].Set, &ConnectDetails->Medium.Set) &&
190  Medium[Index].Id == ConnectDetails->Medium.Id)
191  {
192  /* found a matching interface */
193  Found = TRUE;
194  break;
195  }
196 
197  /* iterate to next medium */
198  Index++;
199  }while(Index < Count);
200  RtlFreeUnicodeString(&GuidString2);
201 
202  if (!Found)
203  {
204  /* pin doesnt support this medium */
205  FreeItem(ConnectDetails);
206  return STATUS_NO_MATCH;
207  }
208 
211 
212  *Connect = ConnectDetails;
213  return STATUS_SUCCESS;
214 }
215 
216 /*
217  @implemented
218 */
219 KSDDKAPI
220 NTSTATUS
221 NTAPI
223  IN PIRP Irp,
224  IN ULONG DescriptorsCount,
225  IN KSPIN_DESCRIPTOR* Descriptor,
227 {
228  return KspValidateConnectRequest(Irp, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR), Connect);
229 }
230 
231 NTSTATUS
233  IN LPGUID Category,
234  PKEY_VALUE_PARTIAL_INFORMATION *OutInformation)
235 {
236  UNICODE_STRING MediaPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories\\");
241  HANDLE hKey;
242  ULONG Size;
244 
245  /* convert the guid to string */
246  Status = RtlStringFromGUID(Category, &GuidString);
247  if (!NT_SUCCESS(Status))
248  return Status;
249 
250  /* allocate buffer for the registry key */
251  Path.Length = 0;
252  Path.MaximumLength = MediaPath.MaximumLength + GuidString.MaximumLength;
253  Path.Buffer = AllocateItem(NonPagedPool, Path.MaximumLength);
254  if (!Path.Buffer)
255  {
256  /* not enough memory */
259  }
260 
261  RtlAppendUnicodeStringToString(&Path, &MediaPath);
263 
264  /* free guid string */
266 
267  /* initialize object attributes */
269 
270  /* open the key */
271  Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes);
272 
273  DPRINT("ZwOpenKey() status 0x%08lx %wZ\n", Status, &Path);
274 
275  /* free path buffer */
276  FreeItem(Path.Buffer);
277 
278  /* check for success */
279  if (!NT_SUCCESS(Status))
280  {
281  DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
282  return Status;
283  }
284 
285  /* query the name size */
286  Status = ZwQueryValueKey(hKey, &Name, KeyValuePartialInformation, NULL, 0, &Size);
288  {
289  /* failed to query for name key */
290  ZwClose(hKey);
291  return Status;
292  }
293 
294  /* allocate buffer to read key info */
296  if (!KeyInfo)
297  {
298  /* not enough memory */
299  ZwClose(hKey);
301  }
302 
303  /* now read the info */
304  Status = ZwQueryValueKey(hKey, &Name, KeyValuePartialInformation, (PVOID)KeyInfo, Size, &Size);
305 
306  /* close the key */
307  ZwClose(hKey);
308 
309  if (!NT_SUCCESS(Status))
310  {
311  /* failed to read key */
312  FreeItem(KeyInfo);
313  return Status;
314  }
315 
316  /* store key information */
317  *OutInformation = KeyInfo;
318  return Status;
319 }
320 
321 KSDDKAPI
322 NTSTATUS
323 NTAPI
325  IN PIRP Irp,
327  IN OUT PVOID Data,
328  IN ULONG DescriptorsCount,
329  IN const KSPIN_DESCRIPTOR* Descriptors,
330  IN ULONG DescriptorSize)
331 {
332  KSP_PIN * Pin;
333  KSMULTIPLE_ITEM * Item;
334  PIO_STACK_LOCATION IoStack;
335  ULONG Size, Index;
336  PVOID Buffer;
337  PKSDATARANGE_AUDIO *WaveFormatOut;
338  PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn;
340  const KSPIN_DESCRIPTOR *Descriptor;
342  ULONG Count;
343  const PKSDATARANGE* DataRanges;
344  LPGUID Guid;
345 
347  Buffer = Data;
348 
349  //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);
350 
351  /* convert to PKSP_PIN */
352  Pin = (KSP_PIN*)Property;
353 
354  if (Property->Id != KSPROPERTY_PIN_CTYPES)
355  {
356  if (Pin->PinId >= DescriptorsCount)
357  {
358  /* invalid parameter */
360  }
361  }
362  else
363  {
364  (*(PULONG)Buffer) = DescriptorsCount;
365  Irp->IoStatus.Information = sizeof(ULONG);
366  return STATUS_SUCCESS;
367  }
368 
369 
370  if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR))
371  {
372  /* it is simple pin descriptor */
373  Descriptor = &Descriptors[Pin->PinId];
374  }
375  else
376  {
377  /* get offset to pin descriptor */
378  Descriptor = &(((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + Pin->PinId * DescriptorSize))->PinDescriptor);
379  }
380 
381  switch(Property->Id)
382  {
384 
385  Size = sizeof(KSPIN_DATAFLOW);
386  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
387  {
388  Irp->IoStatus.Information = Size;
390  break;
391  }
392 
393  *((KSPIN_DATAFLOW*)Buffer) = Descriptor->DataFlow;
394  Irp->IoStatus.Information = sizeof(KSPIN_DATAFLOW);
396  break;
397 
400 
401  Size = sizeof(KSMULTIPLE_ITEM);
402  DPRINT("Id %lu PinId %lu DataRangesCount %lu ConstrainedDataRangesCount %lu\n", Property->Id, Pin->PinId, Descriptor->DataRangesCount, Descriptor->ConstrainedDataRangesCount);
403 
404  if (Property->Id == KSPROPERTY_PIN_DATARANGES || Descriptor->ConstrainedDataRangesCount == 0)
405  {
406  DataRanges = Descriptor->DataRanges;
407  Count = Descriptor->DataRangesCount;
408  }
409  else
410  {
411  DataRanges = Descriptor->ConstrainedDataRanges;
412  Count = Descriptor->ConstrainedDataRangesCount;
413  }
414 
415  for (Index = 0; Index < Count; Index++)
416  {
417  Size += ((DataRanges[Index]->FormatSize + 0x7) & ~0x7);
418  }
419 
420  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0)
421  {
422  /* buffer too small */
423  Irp->IoStatus.Information = Size;
425  break;
426  }
427 
428  Item = (KSMULTIPLE_ITEM*)Buffer;
429 
430  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(ULONG))
431  {
432  /* store the result size */
433  Item->Size = Size;
434  Irp->IoStatus.Information = sizeof(ULONG);
436  break;
437  }
438 
439  /* store descriptor size */
440  Item->Size = Size;
441  Item->Count = Count;
442 
443  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(KSMULTIPLE_ITEM))
444  {
445  Irp->IoStatus.Information = sizeof(KSMULTIPLE_ITEM);
447  break;
448  }
449 
450  /* now copy all dataranges */
451  Data = (PUCHAR)(Item +1);
452 
453  /* alignment assert */
454  ASSERT(((ULONG_PTR)Data & 0x7) == 0);
455 
456  for (Index = 0; Index < Count; Index++)
457  {
459  /* convert the guid to string */
460  RtlStringFromGUID(&DataRanges[Index]->MajorFormat, &GuidString);
461  DPRINT("Index %lu MajorFormat %S\n", Index, GuidString.Buffer);
462  RtlStringFromGUID(&DataRanges[Index]->SubFormat, &GuidString);
463  DPRINT("Index %lu SubFormat %S\n", Index, GuidString.Buffer);
464  RtlStringFromGUID(&DataRanges[Index]->Specifier, &GuidString);
465  DPRINT("Index %lu Specifier %S\n", Index, GuidString.Buffer);
466  RtlStringFromGUID(&DataRanges[Index]->Specifier, &GuidString);
467  DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index,
468  DataRanges[Index]->FormatSize, DataRanges[Index]->Flags, DataRanges[Index]->SampleSize, DataRanges[Index]->Reserved, sizeof(KSDATAFORMAT));
469 
470  RtlMoveMemory(Data, DataRanges[Index], DataRanges[Index]->FormatSize);
471  Data = ((PUCHAR)Data + DataRanges[Index]->FormatSize);
472  /* alignment assert */
473  ASSERT(((ULONG_PTR)Data & 0x7) == 0);
474  Data = (PVOID)(((ULONG_PTR)Data + 0x7) & ~0x7);
475  }
476 
478  Irp->IoStatus.Information = Size;
479  break;
481 
482  if (Descriptor->Interfaces)
483  {
484  /* use mediums provided by driver */
485  return KsHandleSizedListQuery(Irp, Descriptor->InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor->Interfaces);
486  }
487  else
488  {
489  /* use standard medium */
491  }
492  break;
493 
495 
496  if (Descriptor->MediumsCount)
497  {
498  /* use mediums provided by driver */
499  return KsHandleSizedListQuery(Irp, Descriptor->MediumsCount, sizeof(KSPIN_MEDIUM), Descriptor->Mediums);
500  }
501  else
502  {
503  /* use standard medium */
505  }
506  break;
507 
509 
510  Size = sizeof(KSPIN_COMMUNICATION);
511  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
512  {
513  Irp->IoStatus.Information = Size;
515  break;
516  }
517 
518  *((KSPIN_COMMUNICATION*)Buffer) = Descriptor->Communication;
519 
521  Irp->IoStatus.Information = Size;
522  break;
523 
525 
526  if (!Descriptor->Category)
527  {
528  /* no pin category */
529  return STATUS_NOT_FOUND;
530  }
531 
532  /* check size */
533  Size = sizeof(GUID);
534  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
535  {
536  /* buffer too small */
537  Irp->IoStatus.Information = Size;
539  break;
540  }
541 
542  /* copy category guid */
543  RtlMoveMemory(Buffer, Descriptor->Category, sizeof(GUID));
544 
545  /* save result */
547  Irp->IoStatus.Information = Size;
548  break;
549 
550  case KSPROPERTY_PIN_NAME:
551 
552  if (Descriptor->Name)
553  {
554  /* use pin name */
555  Guid = (LPGUID)Descriptor->Name;
556  }
557  else
558  {
559  /* use pin category as fallback */
560  Guid = (LPGUID)Descriptor->Category;
561  }
562 
563  if (!Guid)
564  {
565  /* no friendly name available */
566  return STATUS_NOT_FOUND;
567  }
568 
569  /* read friendly name category name */
570  Status = KspReadMediaCategory(Guid, &KeyInfo);
571  if (!NT_SUCCESS(Status))
572  {
573  /* failed to read category */
574  Irp->IoStatus.Information = 0;
575  break;
576  }
577 
578  /* store required length */
579  Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR);
580 
581  /* check if buffer is too small */
582  if (KeyInfo->DataLength + sizeof(WCHAR) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
583  {
584  /* buffer too small */
586  FreeItem(KeyInfo);
587  break;
588  }
589 
590  /* copy result */
591  RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, &KeyInfo->Data, KeyInfo->DataLength);
592 
593  /* null terminate name */
594  ((LPWSTR)Irp->AssociatedIrp.SystemBuffer)[KeyInfo->DataLength / sizeof(WCHAR)] = L'\0';
595 
596  /* free key info */
597  FreeItem(KeyInfo);
598  break;
600  Size = sizeof(KSDATAFORMAT);
601  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
602  {
603  Irp->IoStatus.Information = Size;
605  break;
606  }
607  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(KSDATAFORMAT_WAVEFORMATEX))
608  {
611  Irp->IoStatus.Information = 0;
612  break;
613  }
614 
615  WaveFormatIn = (PKSDATAFORMAT_WAVEFORMATEX)Buffer;
616  if (!Descriptor->DataRanges || !Descriptor->DataRangesCount)
617  {
619  Irp->IoStatus.Information = 0;
620  break;
621  }
622  WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor->DataRanges;
623  for(Index = 0; Index < Descriptor->DataRangesCount; Index++)
624  {
625  if (WaveFormatOut[Index]->DataRange.FormatSize != sizeof(KSDATARANGE_AUDIO))
626  {
628  continue;
629  }
630 
631  if (WaveFormatOut[Index]->MinimumSampleFrequency > WaveFormatIn->WaveFormatEx.nSamplesPerSec ||
632  WaveFormatOut[Index]->MaximumSampleFrequency < WaveFormatIn->WaveFormatEx.nSamplesPerSec ||
633  WaveFormatOut[Index]->MinimumBitsPerSample > WaveFormatIn->WaveFormatEx.wBitsPerSample ||
634  WaveFormatOut[Index]->MaximumBitsPerSample < WaveFormatIn->WaveFormatEx.wBitsPerSample ||
635  WaveFormatOut[Index]->MaximumChannels < WaveFormatIn->WaveFormatEx.nChannels)
636  {
637  Irp->IoStatus.Status = STATUS_NO_MATCH;
638  Irp->IoStatus.Information = 0;
639  return STATUS_NO_MATCH;
640  }
641  else
642  {
643  Irp->IoStatus.Status = STATUS_SUCCESS;
644  Irp->IoStatus.Information = 0;
645  return STATUS_SUCCESS;
646  }
647  }
649  Irp->IoStatus.Information = 0;
650  break;
651  default:
652  DPRINT1("Unhandled property request %x\n", Property->Id);
654  Irp->IoStatus.Information = 0;
655  }
656 
657  return Status;
658 }
659 
660 /*
661  @implemented
662 */
663 KSDDKAPI
664 NTSTATUS
665 NTAPI
667  IN PIRP Irp,
669  IN OUT PVOID Data,
670  IN ULONG DescriptorsCount,
671  IN const KSPIN_DESCRIPTOR* Descriptor)
672 {
673  return KspPinPropertyHandler(Irp, Property, Data, DescriptorsCount, Descriptor, sizeof(KSPIN_DESCRIPTOR));
674 }
675 
676 /*
677  @unimplemented
678 */
681  IN PIRP Irp,
682  IN PKSP_PIN Pin,
683  OUT PVOID Data,
684  IN ULONG DescriptorsCount,
685  IN const KSPIN_DESCRIPTOR* Descriptor,
686  IN ULONG DescriptorSize,
687  IN PFNKSINTERSECTHANDLEREX IntersectHandler OPTIONAL,
688  IN PVOID HandlerContext OPTIONAL)
689 {
691  return STATUS_UNSUCCESSFUL;
692 }
693 
694 /*
695  @implemented
696 */
697 KSDDKAPI
698 NTSTATUS
699 NTAPI
701  IN PIRP Irp,
702  IN PKSP_PIN Pin,
703  OUT PVOID Data,
704  IN ULONG DescriptorsCount,
705  IN const KSPIN_DESCRIPTOR* Descriptor,
706  IN PFNKSINTERSECTHANDLER IntersectHandler)
707 {
708  KSMULTIPLE_ITEM * Item;
709  KSDATARANGE * DataRange;
710  PIO_STACK_LOCATION IoStack;
711  ULONG Size;
712  ULONG Index;
714 
715  /* get current irp stack location */
717 
718  /* calculate minimum data size */
719  Size = sizeof(KSP_PIN) + sizeof(KSMULTIPLE_ITEM) + sizeof(KSDATARANGE);
720  if (IoStack->Parameters.DeviceIoControl.InputBufferLength < Size)
721  {
722  /* buffer too small */
723  Irp->IoStatus.Information = Size;
724  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
726  }
727  /* is pin id out of bounds */
728  if (Pin->PinId >= DescriptorsCount)
729  {
730  /* it is */
731  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
732  Irp->IoStatus.Information = 0;
734  }
735 
736  /* get start item */
737  Item = (KSMULTIPLE_ITEM*)(Pin + 1);
738  /* get first data range */
739  DataRange = (KSDATARANGE*)(Item + 1);
740  /* iterate through all data ranges */
741  for(Index = 0; Index < Item->Count; Index++, DataRange++)
742  {
743  /* call intersect handler */
744  Status = IntersectHandler(Irp, Pin, DataRange, Data);
745  if (NT_SUCCESS(Status))
746  {
747  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < DataRange->FormatSize)
748  {
749  /* buffer is too small */
750  Irp->IoStatus.Information = DataRange->FormatSize;
751  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
753  }
754  RtlMoveMemory(Irp->UserBuffer, DataRange, sizeof(KSDATARANGE));
755  Irp->IoStatus.Information = sizeof(KSDATARANGE);
756  Irp->IoStatus.Status = STATUS_SUCCESS;
757  return STATUS_SUCCESS;
758  }
759 
760  }
761 
762  Irp->IoStatus.Information = 0;
763  Irp->IoStatus.Status = STATUS_NO_MATCH;
764  return STATUS_NO_MATCH;
765 }
766 
767 /*
768  @implemented
769 */
770 
771 KSDDKAPI
772 NTSTATUS
773 NTAPI
775  IN PIRP Irp,
776  IN ULONG DataItemsCount,
777  IN ULONG DataItemSize,
778  IN const VOID* DataItems)
779 {
780  ULONG Size;
781  PIO_STACK_LOCATION IoStack;
782  PKSMULTIPLE_ITEM Item;
783 
784  /* get current irp stack location */
786 
787  /* calculate size */
788  Size = DataItemSize * DataItemsCount + sizeof(KSMULTIPLE_ITEM);
789 
790  /* get multiple item */
791  Item = (PKSMULTIPLE_ITEM)Irp->AssociatedIrp.SystemBuffer;
792 
793  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0)
794  {
795  /* buffer too small */
796  Irp->IoStatus.Information = Size;
797 
798  return STATUS_BUFFER_OVERFLOW;
799  }
800 
801  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(ULONG))
802  {
803  /* store just the size */
804  Item->Size = Size;
805  Irp->IoStatus.Information = sizeof(ULONG);
806 
807  return STATUS_SUCCESS;
808  }
809 
810 
811  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSMULTIPLE_ITEM))
812  {
813  /* buffer too small */
815  }
816 
817  Item->Count = DataItemsCount;
818  Item->Size = DataItemSize;
819 
820  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(KSMULTIPLE_ITEM))
821  {
822  /* buffer can only hold the length descriptor */
823  Irp->IoStatus.Information = sizeof(KSMULTIPLE_ITEM);
824  return STATUS_SUCCESS;
825  }
826 
827  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= Size)
828  {
829  /* copy items */
830  RtlMoveMemory((PVOID)(Item + 1), DataItems, DataItemSize * DataItemsCount);
831  /* store result */
832  Irp->IoStatus.Information = Size;
833  /* done */
834  return STATUS_SUCCESS;
835  }
836  else
837  {
838  /* buffer too small */
840  }
841 }
842 
ULONG Count
Definition: ks.h:2010
KSPIN_INTERFACE StandardPinInterface
Definition: connectivity.c:14
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
static PWSTR GuidString
Definition: apphelp.c:91
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PKSPIN_CONNECT Connect
Definition: ks.h:4565
union KSDATAFORMAT KSDATARANGE
ULONG Size
Definition: ks.h:2009
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSTATUS NTAPI KspCreateObjectType(IN HANDLE ParentHandle, IN LPWSTR ObjectType, PVOID CreateParameters, UINT CreateParametersSize, IN ACCESS_MASK DesiredAccess, OUT PHANDLE NodeHandle)
Definition: topology.c:16
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
ULONG MaximumBitsPerSample
Definition: ksmedia.h:582
unsigned char * PUCHAR
Definition: retypes.h:3
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
#define KSSTRING_Pin
Definition: ks.h:48
LONG NTSTATUS
Definition: precomp.h:26
KSDDKAPI NTSTATUS NTAPI KsHandleSizedListQuery(IN PIRP Irp, IN ULONG DataItemsCount, IN ULONG DataItemSize, IN const VOID *DataItems)
Definition: connectivity.c:774
#define STATIC_KSMEDIUMSETID_Standard
Definition: ks.h:333
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
NTSTATUS KspReadMediaCategory(IN LPGUID Category, PKEY_VALUE_PARTIAL_INFORMATION *OutInformation)
Definition: connectivity.c:232
KSIDENTIFIER * PKSPIN_INTERFACE
Definition: ks.h:273
#define KSDDKAPI
Definition: ks.h:40
NTSTATUS KspCopyCreateRequest(IN PIRP Irp, IN LPWSTR ObjectClass, IN OUT PULONG Size, OUT PVOID *Result)
Definition: misc.c:101
static BOOL Set
Definition: pageheap.c:10
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:233
uint32_t ULONG_PTR
Definition: typedefs.h:63
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
WORD wBitsPerSample
Definition: audioclient.idl:45
unsigned char BOOLEAN
static GUID * Guid
Definition: apphelp.c:93
smooth NULL
Definition: ftsmooth.c:416
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
void DPRINT(...)
Definition: polytest.cpp:61
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
Definition: bufpool.h:45
return Found
Definition: dirsup.c:1270
void * PVOID
Definition: retypes.h:9
NTSTATUS KspValidateConnectRequest(IN PIRP Irp, IN ULONG DescriptorsCount, IN PVOID Descriptors, IN ULONG DescriptorSize, OUT PKSPIN_CONNECT *Connect)
Definition: connectivity.c:60
KSPIN_DATAFLOW
Definition: ks.h:1278
const GUID KSDATAFORMAT_SUBTYPE_BDA_MPEG2_TRANSPORT
Definition: connectivity.c:28
DWORD nSamplesPerSec
Definition: audioclient.idl:42
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
#define STATUS_NOT_FOUND
Definition: shellext.h:67
Definition: ks.h:672
ULONG Id
Definition: dmksctrl.h:77
if(!(yy_init))
Definition: macro.lex.yy.c:714
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:415
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
static const UCHAR Index[8]
Definition: usbohci.c:18
ULONG MaximumChannels
Definition: ksmedia.h:580
KSDDKAPI NTSTATUS NTAPI KsPinPropertyHandler(IN PIRP Irp, IN PKSPROPERTY Property, IN OUT PVOID Data, IN ULONG DescriptorsCount, IN const KSPIN_DESCRIPTOR *Descriptor)
Definition: connectivity.c:666
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
KSDDKAPI NTSTATUS NTAPI KsCreatePin(IN HANDLE FilterHandle, IN PKSPIN_CONNECT Connect, IN ACCESS_MASK DesiredAccess, OUT PHANDLE ConnectionHandle)
Definition: connectivity.c:36
KSDDKAPI NTSTATUS NTAPI KsPinDataIntersection(IN PIRP Irp, IN PKSP_PIN Pin, OUT PVOID Data, IN ULONG DescriptorsCount, IN const KSPIN_DESCRIPTOR *Descriptor, IN PFNKSINTERSECTHANDLER IntersectHandler)
Definition: connectivity.c:700
WAVEFORMATEX WaveFormatEx
Definition: ksmedia.h:532
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static const WCHAR L[]
Definition: oid.c:1250
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
struct KSMULTIPLE_ITEM * PKSMULTIPLE_ITEM
#define GENERIC_READ
Definition: compat.h:124
KSIDENTIFIER * PKSPIN_MEDIUM
Definition: ks.h:274
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
Status
Definition: gdiplustypes.h:24
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
struct _GUID GUID
struct KSDATAFORMAT_WAVEFORMATEX * PKSDATAFORMAT_WAVEFORMATEX
KSPIN_COMMUNICATION
Definition: ks.h:1283
PRTL_UNICODE_STRING_BUFFER Path
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
#define KSMEDIUM_TYPE_ANYINSTANCE
Definition: ks.h:331
ULONG MaximumSampleFrequency
Definition: ksmedia.h:584
#define STATUS_NO_MATCH
Definition: ntstatus.h:737
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
unsigned int * PULONG
Definition: retypes.h:1
unsigned int UINT
Definition: ndis.h:50
#define STATIC_KSINTERFACESETID_Standard
Definition: ks.h:307
#define DPRINT1
Definition: precomp.h:8
ULONG MinimumBitsPerSample
Definition: ksmedia.h:581
#define OUT
Definition: typedefs.h:39
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
KSPIN_MEDIUM StandardPinMedium
Definition: connectivity.c:21
#define UNIMPLEMENTED
Definition: debug.h:114
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PKSPIN_CONNECT _In_ ACCESS_MASK _Out_ PHANDLE ConnectionHandle
Definition: ks.h:4565
WCHAR * LPWSTR
Definition: xmlstorage.h:184
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2745
KSDDKAPI NTSTATUS NTAPI KsValidateConnectRequest(IN PIRP Irp, IN ULONG DescriptorsCount, IN KSPIN_DESCRIPTOR *Descriptor, OUT PKSPIN_CONNECT *Connect)
Definition: connectivity.c:222
ULONG ACCESS_MASK
Definition: nt_native.h:40
KSDDKAPI NTSTATUS NTAPI KsPinDataIntersectionEx(IN PIRP Irp, IN PKSP_PIN Pin, OUT PVOID Data, IN ULONG DescriptorsCount, IN const KSPIN_DESCRIPTOR *Descriptor, IN ULONG DescriptorSize, IN PFNKSINTERSECTHANDLEREX IntersectHandler OPTIONAL, IN PVOID HandlerContext OPTIONAL)
Definition: connectivity.c:680
KSDDKAPI NTSTATUS NTAPI KspPinPropertyHandler(IN PIRP Irp, IN PKSPROPERTY Property, IN OUT PVOID Data, IN ULONG DescriptorsCount, IN const KSPIN_DESCRIPTOR *Descriptors, IN ULONG DescriptorSize)
Definition: connectivity.c:324
GUID * LPGUID
Definition: guiddef.h:76
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68