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)
13 const GUID KSPROPSETID_Pin
= {0x8C134960, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
14 const GUID KSINTERFACESETID_Standard
= {STATIC_KSINTERFACESETID_Standard
};
15 const GUID CLSID_KsClockForwarder
= {0x877e4351, 0x6fea, 0x11d0, {0xb8, 0x63, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}};
16 const GUID CLSID_KsQualityForwarder
= {0xe05592e4, 0xc0b5, 0x11d0, {0xa4, 0x39, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96}};
17 const GUID CLSID_KsIBasicAudioInterfaceHandler
= {0xb9f8ac3e, 0x0f71, 0x11d2, {0xb7, 0x2c, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d}};
18 const GUID CLSID_Proxy
= {0x17CCA71B, 0xECD7, 0x11D0, {0xB9, 0x08, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
21 static INTERFACE_TABLE InterfaceTable
[] =
23 {&MEDIATYPE_Audio
, CKsDataTypeHandler_Constructor
},
24 {&KSINTERFACESETID_Standard
, CKsInterfaceHandler_Constructor
},
25 {&CLSID_KsClockForwarder
, CKsClockForwarder_Constructor
},
26 {&CLSID_KsQualityForwarder
, CKsQualityForwarder_Constructor
},
27 {&IID_IVPConfig
, CVPConfig_Constructor
},
28 {&IID_IVPVBIConfig
, CVPVBIConfig_Constructor
},
29 {&CLSID_KsIBasicAudioInterfaceHandler
, CKsBasicAudio_Constructor
},
30 {&CLSID_Proxy
, CKsProxy_Constructor
},
37 KsSynchronousDeviceControl(
46 OVERLAPPED Overlapped
;
50 RtlZeroMemory(&Overlapped
, sizeof(OVERLAPPED
));
52 /* create notification event */
53 Overlapped
.hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
55 if (!Overlapped
.hEvent
)
58 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
61 if (!DeviceIoControl(Handle
, IoControl
, InBuffer
, InLength
, OutBuffer
, OutLength
, BytesReturned
, &Overlapped
))
63 /* operation failed */
64 if (GetLastError() != ERROR_IO_PENDING
)
67 CloseHandle(Overlapped
.hEvent
);
68 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
72 /* get result of pending operation */
73 if (!GetOverlappedResult(Handle
, &Overlapped
, &Transferred
, TRUE
))
76 CloseHandle(Overlapped
.hEvent
);
77 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
80 /* store number of bytes transferred */
81 *BytesReturned
= Transferred
;
83 /* close event object */
84 CloseHandle(Overlapped
.hEvent
);
93 KsResolveRequiredAttributes(
94 PKSDATARANGE DataRange
,
95 KSMULTIPLE_ITEM
*Attributes OPTIONAL
)
107 PHANDLE DeviceHandle
)
110 SP_DEVINFO_DATA DeviceInfoData
;
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 DeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
126 DeviceInterfaceData
.cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA
);
128 if (SetupDiEnumDeviceInterfaces(hList
, &DeviceInfoData
, &Category
, 0, &DeviceInterfaceData
))
130 /* setup interface data struct */
131 DeviceInterfaceDetailData
= (PSP_DEVICE_INTERFACE_DETAIL_DATA_W
)Path
;
132 DeviceInterfaceDetailData
->cbSize
= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W
);
134 /* get device interface details */
135 if (SetupDiGetDeviceInterfaceDetailW(hList
, &DeviceInterfaceData
, DeviceInterfaceDetailData
, sizeof(Path
), NULL
, NULL
))
138 *DeviceHandle
= CreateFileW(DeviceInterfaceDetailData
->DevicePath
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
| FILE_ATTRIBUTE_NORMAL
, NULL
);
140 if (*DeviceHandle
!= INVALID_HANDLE_VALUE
)
142 /* operation succeeded */
143 SetupDiDestroyDeviceInfoList(hList
);
149 /* free device list */
150 SetupDiDestroyDeviceInfoList(hList
);
153 return MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, GetLastError());
159 KsGetMultiplePinFactoryItems(
166 ULONG BytesReturned
, NumData
;
169 /* zero pin property */
170 RtlZeroMemory(&Property
, sizeof(KSP_PIN
));
171 Property
.Property
.Set
= KSPROPSETID_Pin
;
172 Property
.Property
.Id
= PropertyId
;
173 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
174 Property
.PinId
= PinFactoryId
;
176 /* query pin factory */
177 hResult
= KsSynchronousDeviceControl(FilterHandle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), NULL
, 0, &BytesReturned
);
179 if (hResult
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_INSUFFICIENT_BUFFER
))
181 /* buffer too small */
182 hResult
= KsSynchronousDeviceControl(FilterHandle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)&NumData
, sizeof(ULONG
), &BytesReturned
);
184 if (SUCCEEDED(hResult
))
186 /* store required data size */
187 BytesReturned
= NumData
;
188 hResult
= MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
);
192 if (hResult
== MAKE_HRESULT(SEVERITY_ERROR
, FACILITY_WIN32
, ERROR_MORE_DATA
))
195 *Items
= CoTaskMemAlloc(BytesReturned
);
200 return E_OUTOFMEMORY
;
203 /* retry querying property */
204 hResult
= KsSynchronousDeviceControl(FilterHandle
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSP_PIN
), (PVOID
)*Items
, BytesReturned
, &BytesReturned
);
206 /* check for success */
210 CoTaskMemFree(*Items
);
224 ULONG
*MediaTypeCount
)
226 PKSMULTIPLE_ITEM MultipleItem
;
229 /* try get contrained data ranges */
230 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_CONSTRAINEDDATARANGES
, (PVOID
*)&MultipleItem
);
232 /* check for failure*/
235 /* try getting default data ranges */
236 hr
= KsGetMultiplePinFactoryItems(FilterHandle
, PinFactoryId
, KSPROPERTY_PIN_DATARANGES
, (PVOID
*)&MultipleItem
);
241 /* store number of media types */
242 *MediaTypeCount
= MultipleItem
->Count
;
245 CoTaskMemFree(MultipleItem
);
257 AM_MEDIA_TYPE
*AmMediaType
,
269 DllUnregisterServer(void)
278 DllRegisterServer(void)
292 HRESULT hres
= E_OUTOFMEMORY
;
293 IClassFactory
* pcf
= NULL
;
300 for (i
= 0; InterfaceTable
[i
].riid
; i
++)
302 if (IsEqualIID(InterfaceTable
[i
].riid
, rclsid
))
304 pcf
= CClassFactory_fnConstructor(InterfaceTable
[i
].lpfnCI
, NULL
, NULL
);
311 return CLASS_E_CLASSNOTAVAILABLE
;
314 hres
= pcf
->QueryInterface(riid
, ppv
);
323 DllCanUnloadNow(void)