2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
4 * FILE: dll/directx/ksproxy/ksproxy.cpp
5 * PURPOSE: ActiveMovie Proxy functions
7 * PROGRAMMERS: Dmitry Chapyshev
8 Johannes Anderwald (johannes.anderwald@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}};
22 static INTERFACE_TABLE InterfaceTable
[] =
24 {&MEDIATYPE_Audio
, CKsDataTypeHandler_Constructor
},
25 {&KSINTERFACESETID_Standard
, CKsInterfaceHandler_Constructor
},
26 {&CLSID_KsClockForwarder
, CKsClockForwarder_Constructor
},
27 {&CLSID_KsQualityForwarder
, CKsQualityForwarder_Constructor
},
28 {&IID_IVPConfig
, CVPConfig_Constructor
},
29 {&IID_IVPVBIConfig
, CVPVBIConfig_Constructor
},
30 {&CLSID_KsIBasicAudioInterfaceHandler
, CKsBasicAudio_Constructor
},
31 {&CLSID_Proxy
, CKsProxy_Constructor
},
38 KsSynchronousDeviceControl(
47 OVERLAPPED Overlapped
;
51 RtlZeroMemory(&Overlapped
, sizeof(OVERLAPPED
));
53 /* create notification event */
54 Overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
56 if (!Overlapped
.hEvent
)
59 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
62 if (!DeviceIoControl(Handle
, IoControl
, InBuffer
, InLength
, OutBuffer
, OutLength
, BytesReturned
, &Overlapped
))
64 /* operation failed */
65 if (GetLastError() != ERROR_IO_PENDING
)
68 CloseHandle(Overlapped
.hEvent
);
69 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
73 /* get result of pending operation */
74 if (!GetOverlappedResult(Handle
, &Overlapped
, &Transferred
, TRUE
))
77 CloseHandle(Overlapped
.hEvent
);
78 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
81 /* store number of bytes transferred */
82 *BytesReturned
= Transferred
;
84 /* close event object */
85 CloseHandle(Overlapped
.hEvent
);
94 KsResolveRequiredAttributes(
95 PKSDATARANGE DataRange
,
96 KSMULTIPLE_ITEM
*Attributes OPTIONAL
)
108 PHANDLE DeviceHandle
)
111 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
;
112 PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData
;
113 WCHAR Path
[MAX_PATH
+sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
)];
115 /* open device list */
116 hList
= SetupDiGetClassDevsW(&Category
, NULL
, NULL
, DIGCF_DEVICEINTERFACE
| DIGCF_PRESENT
);
118 if (hList
== INVALID_HANDLE_VALUE
)
121 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
124 /* setup parameters */
125 DeviceInterfaceData
.cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA
);
127 if (SetupDiEnumDeviceInterfaces(hList
, NULL
, &Category
, 0, &DeviceInterfaceData
))
129 /* setup interface data struct */
130 DeviceInterfaceDetailData
= (PSP_DEVICE_INTERFACE_DETAIL_DATA_W
)Path
;
131 DeviceInterfaceDetailData
->cbSize
= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
);
133 /* get device interface details */
134 if (SetupDiGetDeviceInterfaceDetailW(hList
, &DeviceInterfaceData
, DeviceInterfaceDetailData
, sizeof(Path
), NULL
, NULL
))
137 *DeviceHandle
= CreateFileW(DeviceInterfaceDetailData
->DevicePath
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
| FILE_ATTRIBUTE_NORMAL
, NULL
);
139 if (*DeviceHandle
!= INVALID_HANDLE_VALUE
)
141 /* operation succeeded */
142 SetupDiDestroyDeviceInfoList(hList
);
148 /* free device list */
149 SetupDiDestroyDeviceInfoList(hList
);
152 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
158 KsGetMultiplePinFactoryItems(
165 ULONG BytesReturned
, NumData
;
168 /* zero pin property */
169 RtlZeroMemory(&Property
, sizeof(KSP_PIN
));
170 Property
.Property
.Set
= KSPROPSETID_Pin
;
171 Property
.Property
.Id
= PropertyId
;
172 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
173 Property
.PinId
= PinFactoryId
;
175 /* query pin factory */
176 hResult
= KsSynchronousDeviceControl(FilterHandle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), NULL
, 0, &BytesReturned
);
178 if (hResult
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_INSUFFICIENT_BUFFER
))
180 /* buffer too small */
181 hResult
= KsSynchronousDeviceControl(FilterHandle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)&NumData
, sizeof(ULONG
), &BytesReturned
);
183 if (SUCCEEDED(hResult
))
185 /* store required data size */
186 BytesReturned
= NumData
;
187 hResult
= MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
);
191 if (hResult
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
))
194 *Items
= CoTaskMemAlloc(BytesReturned
);
199 return E_OUTOFMEMORY
;
202 /* retry querying property */
203 hResult
= KsSynchronousDeviceControl(FilterHandle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)*Items
, BytesReturned
, &BytesReturned
);
205 /* check for success */
209 CoTaskMemFree(*Items
);
223 ULONG
*MediaTypeCount
)
225 PKSMULTIPLE_ITEM MultipleItem
;
228 /* try get constrained data ranges */
229 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_CONSTRAINEDDATARANGES
, (PVOID
*)&MultipleItem
);
231 /* check for failure*/
234 /* try getting default data ranges */
235 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_DATARANGES
, (PVOID
*)&MultipleItem
);
240 /* store number of media types */
241 *MediaTypeCount
= MultipleItem
->Count
;
244 CoTaskMemFree(MultipleItem
);
256 AM_MEDIA_TYPE
*AmMediaType
,
261 PKSMULTIPLE_ITEM ItemList
;
263 PKSDATAFORMAT DataFormat
;
268 // get current supported ranges
269 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_CONSTRAINEDDATARANGES
, (PVOID
*)&ItemList
);
272 // get standard dataranges
273 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_DATARANGES
, (PVOID
*)&ItemList
);
280 if ((ULONG
)Position
>= ItemList
->Count
)
283 CoTaskMemFree(ItemList
);
284 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_NO_MORE_ITEMS
);
287 // goto first datarange
288 DataFormat
= (PKSDATAFORMAT
)(ItemList
+ 1);
293 DataFormat
= (PKSDATAFORMAT
)(ULONG_PTR
)(DataFormat
+ DataFormat
->FormatSize
);
298 DataFormat
->FormatSize
-= sizeof(KSDATAFORMAT
);
299 if (DataFormat
->FormatSize
)
301 // copy extra format buffer
302 AmMediaType
->pbFormat
= (BYTE
*)CoTaskMemAlloc(DataFormat
->FormatSize
);
303 if (!AmMediaType
->pbFormat
)
306 CoTaskMemFree(ItemList
);
307 return E_OUTOFMEMORY
;
309 // copy format buffer
310 CopyMemory(AmMediaType
->pbFormat
, (DataFormat
+ 1), DataFormat
->FormatSize
);
311 AmMediaType
->cbFormat
= DataFormat
->FormatSize
;
316 AmMediaType
->pbFormat
= NULL
;
317 AmMediaType
->cbFormat
= 0;
321 CopyMemory(&AmMediaType
->majortype
, &DataFormat
->MajorFormat
, sizeof(GUID
));
322 CopyMemory(&AmMediaType
->subtype
, &DataFormat
->SubFormat
, sizeof(GUID
));
323 CopyMemory(&AmMediaType
->formattype
, &DataFormat
->Specifier
, sizeof(GUID
));
324 AmMediaType
->bTemporalCompression
= FALSE
; //FIXME verify
325 AmMediaType
->pUnk
= NULL
; //FIXME
326 AmMediaType
->lSampleSize
= DataFormat
->SampleSize
;
327 AmMediaType
->bFixedSizeSamples
= (AmMediaType
->lSampleSize
) ? TRUE
: FALSE
;
329 // free dataformat list
330 CoTaskMemFree(ItemList
);
339 DllUnregisterServer(void)
346 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, L
"CLSID", 0, KEY_SET_VALUE
, &hClass
) != ERROR_SUCCESS
)
351 hr
= StringFromCLSID(*InterfaceTable
[Index
].riid
, &pStr
);
355 RegDeleteKeyW(hClass
, pStr
);
358 }while(InterfaceTable
[Index
].lpfnCI
!= 0);
368 DllRegisterServer(void)
373 HKEY hClass
, hKey
, hSubKey
;
374 static LPCWSTR ModuleName
= L
"ksproxy.ax";
375 static LPCWSTR ThreadingModel
= L
"Both";
377 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, L
"CLSID", 0, KEY_WRITE
, &hClass
) != ERROR_SUCCESS
)
382 hr
= StringFromCLSID(*InterfaceTable
[Index
].riid
, &pStr
);
386 if (RegCreateKeyExW(hClass
, pStr
, 0, 0, 0, KEY_WRITE
, NULL
, &hKey
, 0) == ERROR_SUCCESS
)
388 if (RegCreateKeyExW(hKey
, L
"InprocServer32", 0, 0, 0, KEY_WRITE
, NULL
, &hSubKey
, 0) == ERROR_SUCCESS
)
390 RegSetValueExW(hSubKey
, 0, 0, REG_SZ
, (const BYTE
*)ModuleName
, (wcslen(ModuleName
) + 1) * sizeof(WCHAR
));
391 RegSetValueExW(hSubKey
, L
"ThreadingModel", 0, REG_SZ
, (const BYTE
*)ThreadingModel
, (wcslen(ThreadingModel
) + 1) * sizeof(WCHAR
));
392 RegCloseKey(hSubKey
);
399 }while(InterfaceTable
[Index
].lpfnCI
!= 0);
414 HRESULT hres
= E_OUTOFMEMORY
;
415 IClassFactory
* pcf
= NULL
;
422 for (i
= 0; InterfaceTable
[i
].riid
; i
++)
424 if (IsEqualIID(*InterfaceTable
[i
].riid
, rclsid
))
426 pcf
= CClassFactory_fnConstructor(InterfaceTable
[i
].lpfnCI
, NULL
, NULL
);
433 return CLASS_E_CLASSNOTAVAILABLE
;
436 hres
= pcf
->QueryInterface(riid
, ppv
);
445 DllCanUnloadNow(void)