2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
4 * FILE: dll/directx/ksproxy/ksproxy.c
5 * PURPOSE: ActiveMovie Proxy functions
7 * PROGRAMMERS: Dmitry Chapyshev
8 Johannes Anderwald (janderwald@reactos.org)
14 const GUID CLSID_KsClockForwarder
= {0x877e4351, 0x6fea, 0x11d0, {0xb8, 0x63, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}};
15 const GUID CLSID_KsQualityForwarder
= {0xe05592e4, 0xc0b5, 0x11d0, {0xa4, 0x39, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96}};
19 const GUID CLSID_KsIBasicAudioInterfaceHandler
= {0xb9f8ac3e, 0x0f71, 0x11d2, {0xb7, 0x2c, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d}};
20 const GUID KSPROPSETID_Pin
= {0x8C134960, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
21 const GUID KSINTERFACESETID_Standard
= {STATIC_KSINTERFACESETID_Standard
};
22 const GUID CLSID_Proxy
= {0x17CCA71B, 0xECD7, 0x11D0, {0xB9, 0x08, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
25 static INTERFACE_TABLE InterfaceTable
[] =
27 {&MEDIATYPE_Audio
, CKsDataTypeHandler_Constructor
},
28 {&KSINTERFACESETID_Standard
, CKsInterfaceHandler_Constructor
},
29 {&CLSID_KsClockForwarder
, CKsClockForwarder_Constructor
},
30 {&CLSID_KsQualityForwarder
, CKsQualityForwarder_Constructor
},
31 {&IID_IVPConfig
, CVPConfig_Constructor
},
32 {&IID_IVPVBIConfig
, CVPVBIConfig_Constructor
},
33 {&CLSID_KsIBasicAudioInterfaceHandler
, CKsBasicAudio_Constructor
},
34 {&CLSID_Proxy
, CKsProxy_Constructor
},
41 KsSynchronousDeviceControl(
50 OVERLAPPED Overlapped
;
54 RtlZeroMemory(&Overlapped
, sizeof(OVERLAPPED
));
56 /* create notification event */
57 Overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
59 if (!Overlapped
.hEvent
)
62 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
65 if (!DeviceIoControl(Handle
, IoControl
, InBuffer
, InLength
, OutBuffer
, OutLength
, BytesReturned
, &Overlapped
))
67 /* operation failed */
68 if (GetLastError() != ERROR_IO_PENDING
)
71 CloseHandle(Overlapped
.hEvent
);
72 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
76 /* get result of pending operation */
77 if (!GetOverlappedResult(Handle
, &Overlapped
, &Transferred
, TRUE
))
80 CloseHandle(Overlapped
.hEvent
);
81 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
84 /* store number of bytes transferred */
85 *BytesReturned
= Transferred
;
87 /* close event object */
88 CloseHandle(Overlapped
.hEvent
);
97 KsResolveRequiredAttributes(
98 PKSDATARANGE DataRange
,
99 KSMULTIPLE_ITEM
*Attributes OPTIONAL
)
111 PHANDLE DeviceHandle
)
114 SP_DEVINFO_DATA DeviceInfoData
;
115 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
;
116 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData
;
117 WCHAR Path
[MAX_PATH
+sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
)];
119 /* open device list */
120 hList
= SetupDiGetClassDevsW(&Category
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
122 if (hList
== INVALID_HANDLE_VALUE
)
125 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
128 /* setup parameters */
129 DeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
130 DeviceInterfaceData
.cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA
);
132 if (SetupDiEnumDeviceInterfaces(hList
, NULL
, &Category
, 0, &DeviceInterfaceData
))
134 /* setup interface data struct */
135 DeviceInterfaceDetailData
= (PSP_DEVICE_INTERFACE_DETAIL_DATA_W
)Path
;
136 DeviceInterfaceDetailData
->cbSize
= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
);
138 /* get device interface details */
139 if (SetupDiGetDeviceInterfaceDetailW(hList
, &DeviceInterfaceData
, DeviceInterfaceDetailData
, sizeof(Path
), NULL
, NULL
))
142 *DeviceHandle
= CreateFileW(DeviceInterfaceDetailData
->DevicePath
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
| FILE_ATTRIBUTE_NORMAL
, NULL
);
144 if (*DeviceHandle
!= INVALID_HANDLE_VALUE
)
146 /* operation succeeded */
147 SetupDiDestroyDeviceInfoList(hList
);
153 /* free device list */
154 SetupDiDestroyDeviceInfoList(hList
);
157 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
163 KsGetMultiplePinFactoryItems(
170 ULONG BytesReturned
, NumData
;
173 /* zero pin property */
174 RtlZeroMemory(&Property
, sizeof(KSP_PIN
));
175 Property
.Property
.Set
= KSPROPSETID_Pin
;
176 Property
.Property
.Id
= PropertyId
;
177 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
178 Property
.PinId
= PinFactoryId
;
180 /* query pin factory */
181 hResult
= KsSynchronousDeviceControl(FilterHandle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), NULL
, 0, &BytesReturned
);
183 if (hResult
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_INSUFFICIENT_BUFFER
))
185 /* buffer too small */
186 hResult
= KsSynchronousDeviceControl(FilterHandle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)&NumData
, sizeof(ULONG
), &BytesReturned
);
188 if (SUCCEEDED(hResult
))
190 /* store required data size */
191 BytesReturned
= NumData
;
192 hResult
= MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
);
196 if (hResult
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
))
199 *Items
= CoTaskMemAlloc(BytesReturned
);
204 return E_OUTOFMEMORY
;
207 /* retry querying property */
208 hResult
= KsSynchronousDeviceControl(FilterHandle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)*Items
, BytesReturned
, &BytesReturned
);
210 /* check for success */
214 CoTaskMemFree(*Items
);
228 ULONG
*MediaTypeCount
)
230 PKSMULTIPLE_ITEM MultipleItem
;
233 /* try get contrained data ranges */
234 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_CONSTRAINEDDATARANGES
, (PVOID
*)&MultipleItem
);
236 /* check for failure*/
239 /* try getting default data ranges */
240 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_DATARANGES
, (PVOID
*)&MultipleItem
);
245 /* store number of media types */
246 *MediaTypeCount
= MultipleItem
->Count
;
249 CoTaskMemFree(MultipleItem
);
261 AM_MEDIA_TYPE
*AmMediaType
,
266 PKSMULTIPLE_ITEM ItemList
;
268 PKSDATAFORMAT DataFormat
;
273 // get current supported ranges
274 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_CONSTRAINEDDATARANGES
, (PVOID
*)&ItemList
);
277 // get standard dataranges
278 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_DATARANGES
, (PVOID
*)&ItemList
);
285 if ((ULONG
)Position
>= ItemList
->Count
)
288 CoTaskMemFree(ItemList
);
289 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NO_MORE_ITEMS
);
292 // goto first datarange
293 DataFormat
= (PKSDATAFORMAT
)(ItemList
+ 1);
298 DataFormat
= (PKSDATAFORMAT
)(ULONG_PTR
)(DataFormat
+ DataFormat
->FormatSize
);
303 DataFormat
->FormatSize
-= sizeof(KSDATAFORMAT
);
304 if (DataFormat
->FormatSize
)
306 // copy extra format buffer
307 AmMediaType
->pbFormat
= (BYTE
*)CoTaskMemAlloc(DataFormat
->FormatSize
);
308 if (!AmMediaType
->pbFormat
)
311 CoTaskMemFree(ItemList
);
312 return E_OUTOFMEMORY
;
314 // copy format buffer
315 CopyMemory(AmMediaType
->pbFormat
, (DataFormat
+ 1), DataFormat
->FormatSize
);
316 AmMediaType
->cbFormat
= DataFormat
->FormatSize
;
321 AmMediaType
->pbFormat
= NULL
;
322 AmMediaType
->cbFormat
= 0;
326 CopyMemory(&AmMediaType
->majortype
, &DataFormat
->MajorFormat
, sizeof(GUID
));
327 CopyMemory(&AmMediaType
->subtype
, &DataFormat
->SubFormat
, sizeof(GUID
));
328 CopyMemory(&AmMediaType
->formattype
, &DataFormat
->Specifier
, sizeof(GUID
));
329 AmMediaType
->bTemporalCompression
= FALSE
; //FIXME verify
330 AmMediaType
->pUnk
= NULL
; //FIXME
331 AmMediaType
->lSampleSize
= DataFormat
->SampleSize
;
332 AmMediaType
->bFixedSizeSamples
= (AmMediaType
->lSampleSize
) ? TRUE
: FALSE
;
334 // free dataformat list
335 CoTaskMemFree(ItemList
);
344 DllUnregisterServer(void)
353 DllRegisterServer(void)
367 HRESULT hres
= E_OUTOFMEMORY
;
368 IClassFactory
* pcf
= NULL
;
375 for (i
= 0; InterfaceTable
[i
].riid
; i
++)
377 if (IsEqualIID(*InterfaceTable
[i
].riid
, rclsid
))
379 pcf
= CClassFactory_fnConstructor(InterfaceTable
[i
].lpfnCI
, NULL
, NULL
);
386 return CLASS_E_CLASSNOTAVAILABLE
;
389 hres
= pcf
->QueryInterface(riid
, ppv
);
398 DllCanUnloadNow(void)