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 KSPROPSETID_Pin
= {0x8C134960, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
20 const GUID KSINTERFACESETID_Standard
= {STATIC_KSINTERFACESETID_Standard
};
21 const GUID CLSID_Proxy
= {0x17CCA71B, 0xECD7, 0x11D0, {0xB9, 0x08, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
24 const GUID CLSID_KsIBasicAudioInterfaceHandler
= {0xb9f8ac3e, 0x0f71, 0x11d2, {0xb7, 0x2c, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d}};
26 static INTERFACE_TABLE InterfaceTable
[] =
28 {&MEDIATYPE_Audio
, CKsDataTypeHandler_Constructor
},
29 {&KSINTERFACESETID_Standard
, CKsInterfaceHandler_Constructor
},
30 {&CLSID_KsClockForwarder
, CKsClockForwarder_Constructor
},
31 {&CLSID_KsQualityForwarder
, CKsQualityForwarder_Constructor
},
32 {&IID_IVPConfig
, CVPConfig_Constructor
},
33 {&IID_IVPVBIConfig
, CVPVBIConfig_Constructor
},
34 {&CLSID_KsIBasicAudioInterfaceHandler
, CKsBasicAudio_Constructor
},
35 {&CLSID_Proxy
, CKsProxy_Constructor
},
42 KsSynchronousDeviceControl(
51 OVERLAPPED Overlapped
;
55 RtlZeroMemory(&Overlapped
, sizeof(OVERLAPPED
));
57 /* create notification event */
58 Overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
60 if (!Overlapped
.hEvent
)
63 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
66 if (!DeviceIoControl(Handle
, IoControl
, InBuffer
, InLength
, OutBuffer
, OutLength
, BytesReturned
, &Overlapped
))
68 /* operation failed */
69 if (GetLastError() != ERROR_IO_PENDING
)
72 CloseHandle(Overlapped
.hEvent
);
73 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
77 /* get result of pending operation */
78 if (!GetOverlappedResult(Handle
, &Overlapped
, &Transferred
, TRUE
))
81 CloseHandle(Overlapped
.hEvent
);
82 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
85 /* store number of bytes transferred */
86 *BytesReturned
= Transferred
;
88 /* close event object */
89 CloseHandle(Overlapped
.hEvent
);
98 KsResolveRequiredAttributes(
99 PKSDATARANGE DataRange
,
100 KSMULTIPLE_ITEM
*Attributes OPTIONAL
)
112 PHANDLE DeviceHandle
)
115 SP_DEVINFO_DATA DeviceInfoData
;
116 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
;
117 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData
;
118 WCHAR Path
[MAX_PATH
+sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
)];
120 /* open device list */
121 hList
= SetupDiGetClassDevsW(&Category
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
123 if (hList
== INVALID_HANDLE_VALUE
)
126 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
129 /* setup parameters */
130 DeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
131 DeviceInterfaceData
.cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA
);
133 if (SetupDiEnumDeviceInterfaces(hList
, NULL
, &Category
, 0, &DeviceInterfaceData
))
135 /* setup interface data struct */
136 DeviceInterfaceDetailData
= (PSP_DEVICE_INTERFACE_DETAIL_DATA_W
)Path
;
137 DeviceInterfaceDetailData
->cbSize
= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
);
139 /* get device interface details */
140 if (SetupDiGetDeviceInterfaceDetailW(hList
, &DeviceInterfaceData
, DeviceInterfaceDetailData
, sizeof(Path
), NULL
, NULL
))
143 *DeviceHandle
= CreateFileW(DeviceInterfaceDetailData
->DevicePath
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
| FILE_ATTRIBUTE_NORMAL
, NULL
);
145 if (*DeviceHandle
!= INVALID_HANDLE_VALUE
)
147 /* operation succeeded */
148 SetupDiDestroyDeviceInfoList(hList
);
154 /* free device list */
155 SetupDiDestroyDeviceInfoList(hList
);
158 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
164 KsGetMultiplePinFactoryItems(
171 ULONG BytesReturned
, NumData
;
174 /* zero pin property */
175 RtlZeroMemory(&Property
, sizeof(KSP_PIN
));
176 Property
.Property
.Set
= KSPROPSETID_Pin
;
177 Property
.Property
.Id
= PropertyId
;
178 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
179 Property
.PinId
= PinFactoryId
;
181 /* query pin factory */
182 hResult
= KsSynchronousDeviceControl(FilterHandle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), NULL
, 0, &BytesReturned
);
184 if (hResult
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_INSUFFICIENT_BUFFER
))
186 /* buffer too small */
187 hResult
= KsSynchronousDeviceControl(FilterHandle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)&NumData
, sizeof(ULONG
), &BytesReturned
);
189 if (SUCCEEDED(hResult
))
191 /* store required data size */
192 BytesReturned
= NumData
;
193 hResult
= MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
);
197 if (hResult
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
))
200 *Items
= CoTaskMemAlloc(BytesReturned
);
205 return E_OUTOFMEMORY
;
208 /* retry querying property */
209 hResult
= KsSynchronousDeviceControl(FilterHandle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)*Items
, BytesReturned
, &BytesReturned
);
211 /* check for success */
215 CoTaskMemFree(*Items
);
229 ULONG
*MediaTypeCount
)
231 PKSMULTIPLE_ITEM MultipleItem
;
234 /* try get contrained data ranges */
235 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_CONSTRAINEDDATARANGES
, (PVOID
*)&MultipleItem
);
237 /* check for failure*/
240 /* try getting default data ranges */
241 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_DATARANGES
, (PVOID
*)&MultipleItem
);
246 /* store number of media types */
247 *MediaTypeCount
= MultipleItem
->Count
;
250 CoTaskMemFree(MultipleItem
);
262 AM_MEDIA_TYPE
*AmMediaType
,
267 PKSMULTIPLE_ITEM ItemList
;
269 PKSDATAFORMAT DataFormat
;
274 // get current supported ranges
275 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_CONSTRAINEDDATARANGES
, (PVOID
*)&ItemList
);
278 // get standard dataranges
279 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_DATARANGES
, (PVOID
*)&ItemList
);
286 if ((ULONG
)Position
>= ItemList
->Count
)
289 CoTaskMemFree(ItemList
);
290 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NO_MORE_ITEMS
);
293 // goto first datarange
294 DataFormat
= (PKSDATAFORMAT
)(ItemList
+ 1);
299 DataFormat
= (PKSDATAFORMAT
)(ULONG_PTR
)(DataFormat
+ DataFormat
->FormatSize
);
304 DataFormat
->FormatSize
-= sizeof(KSDATAFORMAT
);
305 if (DataFormat
->FormatSize
)
307 // copy extra format buffer
308 AmMediaType
->pbFormat
= (BYTE
*)CoTaskMemAlloc(DataFormat
->FormatSize
);
309 if (!AmMediaType
->pbFormat
)
312 CoTaskMemFree(ItemList
);
313 return E_OUTOFMEMORY
;
315 // copy format buffer
316 CopyMemory(AmMediaType
->pbFormat
, (DataFormat
+ 1), DataFormat
->FormatSize
);
317 AmMediaType
->cbFormat
= DataFormat
->FormatSize
;
322 AmMediaType
->pbFormat
= NULL
;
323 AmMediaType
->cbFormat
= 0;
327 CopyMemory(&AmMediaType
->majortype
, &DataFormat
->MajorFormat
, sizeof(GUID
));
328 CopyMemory(&AmMediaType
->subtype
, &DataFormat
->SubFormat
, sizeof(GUID
));
329 CopyMemory(&AmMediaType
->formattype
, &DataFormat
->Specifier
, sizeof(GUID
));
330 AmMediaType
->bTemporalCompression
= FALSE
; //FIXME verify
331 AmMediaType
->pUnk
= NULL
; //FIXME
332 AmMediaType
->lSampleSize
= DataFormat
->SampleSize
;
333 AmMediaType
->bFixedSizeSamples
= (AmMediaType
->lSampleSize
) ? TRUE
: FALSE
;
335 // free dataformat list
336 CoTaskMemFree(ItemList
);
345 DllUnregisterServer(void)
352 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, L
"CLSID", 0, KEY_SET_VALUE
, &hClass
) != ERROR_SUCCESS
)
357 hr
= StringFromCLSID(*InterfaceTable
[Index
].riid
, &pStr
);
361 RegDeleteKeyW(hClass
, pStr
);
364 }while(InterfaceTable
[Index
].lpfnCI
!= 0);
374 DllRegisterServer(void)
379 HKEY hClass
, hKey
, hSubKey
;
380 static LPCWSTR ModuleName
= L
"ksproxy.ax";
381 static LPCWSTR ThreadingModel
= L
"Both";
383 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, L
"CLSID", 0, KEY_WRITE
, &hClass
) != ERROR_SUCCESS
)
388 hr
= StringFromCLSID(*InterfaceTable
[Index
].riid
, &pStr
);
392 if (RegCreateKeyExW(hClass
, pStr
, 0, 0, 0, KEY_WRITE
, NULL
, &hKey
, 0) == ERROR_SUCCESS
)
394 if (RegCreateKeyExW(hKey
, L
"InprocServer32", 0, 0, 0, KEY_WRITE
, NULL
, &hSubKey
, 0) == ERROR_SUCCESS
)
396 RegSetValueExW(hSubKey
, 0, 0, REG_SZ
, (const BYTE
*)ModuleName
, (wcslen(ModuleName
) + 1) * sizeof(WCHAR
));
397 RegSetValueExW(hSubKey
, L
"ThreadingModel", 0, REG_SZ
, (const BYTE
*)ThreadingModel
, (wcslen(ThreadingModel
) + 1) * sizeof(WCHAR
));
398 RegCloseKey(hSubKey
);
405 }while(InterfaceTable
[Index
].lpfnCI
!= 0);
420 HRESULT hres
= E_OUTOFMEMORY
;
421 IClassFactory
* pcf
= NULL
;
428 for (i
= 0; InterfaceTable
[i
].riid
; i
++)
430 if (IsEqualIID(*InterfaceTable
[i
].riid
, rclsid
))
432 pcf
= CClassFactory_fnConstructor(InterfaceTable
[i
].lpfnCI
, NULL
, NULL
);
439 return CLASS_E_CLASSNOTAVAILABLE
;
442 hres
= pcf
->QueryInterface(riid
, ppv
);
451 DllCanUnloadNow(void)