Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy * FILE: dll/directx/ksproxy/ksproxy.cpp * PURPOSE: ActiveMovie Proxy functions * * PROGRAMMERS: Dmitry Chapyshev Johannes Anderwald (johannes.anderwald@reactos.org) */
#include "precomp.h"
const GUID CLSID_KsClockForwarder = {0x877e4351, 0x6fea, 0x11d0, {0xb8, 0x63, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}};const GUID CLSID_KsQualityForwarder = {0xe05592e4, 0xc0b5, 0x11d0, {0xa4, 0x39, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96}};const GUID CLSID_KsIBasicAudioInterfaceHandler = {0xb9f8ac3e, 0x0f71, 0x11d2, {0xb7, 0x2c, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d}};
static INTERFACE_TABLE InterfaceTable[] ={ {&MEDIATYPE_Audio, CKsDataTypeHandler_Constructor}, {&KSINTERFACESETID_Standard, CKsInterfaceHandler_Constructor}, {&CLSID_KsClockForwarder, CKsClockForwarder_Constructor}, {&CLSID_KsQualityForwarder, CKsQualityForwarder_Constructor}, {&IID_IVPConfig, CVPConfig_Constructor}, {&IID_IVPVBIConfig, CVPVBIConfig_Constructor}, {&CLSID_KsIBasicAudioInterfaceHandler, CKsBasicAudio_Constructor}, {&CLSID_Proxy, CKsProxy_Constructor}, {NULL, NULL}};
KSDDKAPIHRESULTWINAPIKsSynchronousDeviceControl( HANDLE Handle, ULONG IoControl, PVOID InBuffer, ULONG InLength, PVOID OutBuffer, ULONG OutLength, PULONG BytesReturned){ OVERLAPPED Overlapped; DWORD Transferred;
/* zero overlapped */ RtlZeroMemory(&Overlapped, sizeof(OVERLAPPED));
/* create notification event */ Overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
if (!Overlapped.hEvent) { /* failed */ return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); }
if (!DeviceIoControl(Handle, IoControl, InBuffer, InLength, OutBuffer, OutLength, BytesReturned, &Overlapped)) { /* operation failed */ if (GetLastError() != ERROR_IO_PENDING) { /* failed */ CloseHandle(Overlapped.hEvent); return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); } }
/* get result of pending operation */ if (!GetOverlappedResult(Handle, &Overlapped, &Transferred, TRUE)) { /* failed */ CloseHandle(Overlapped.hEvent); return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); }
/* store number of bytes transferred */ *BytesReturned = Transferred;
/* close event object */ CloseHandle(Overlapped.hEvent);
/* done */ return NOERROR;}
KSDDKAPIHRESULTWINAPIKsResolveRequiredAttributes( PKSDATARANGE DataRange, KSMULTIPLE_ITEM *Attributes OPTIONAL){ //UNIMPLEMENTED return NOERROR;}
KSDDKAPIHRESULTWINAPIKsOpenDefaultDevice( REFGUID Category, ACCESS_MASK Access, PHANDLE DeviceHandle){ HDEVINFO hList; SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData; WCHAR Path[MAX_PATH+sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W)];
/* open device list */ hList = SetupDiGetClassDevsW(&Category, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
if (hList == INVALID_HANDLE_VALUE) { /* failed */ return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); }
/* setup parameters */ DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if (SetupDiEnumDeviceInterfaces(hList, NULL, &Category, 0, &DeviceInterfaceData)) { /* setup interface data struct */ DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)Path; DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
/* get device interface details */ if (SetupDiGetDeviceInterfaceDetailW(hList, &DeviceInterfaceData, DeviceInterfaceDetailData, sizeof(Path), NULL, NULL)) { /* open device */ *DeviceHandle = CreateFileW(DeviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, NULL);
if (*DeviceHandle != INVALID_HANDLE_VALUE) { /* operation succeeded */ SetupDiDestroyDeviceInfoList(hList); return NOERROR; } } }
/* free device list */ SetupDiDestroyDeviceInfoList(hList);
/* failed */ return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());}
KSDDKAPIHRESULTWINAPIKsGetMultiplePinFactoryItems( HANDLE FilterHandle, ULONG PinFactoryId, ULONG PropertyId, PVOID *Items){ KSP_PIN Property; ULONG BytesReturned, NumData; HRESULT hResult;
/* zero pin property */ RtlZeroMemory(&Property, sizeof(KSP_PIN)); Property.Property.Set = KSPROPSETID_Pin; Property.Property.Id = PropertyId; Property.Property.Flags = KSPROPERTY_TYPE_GET; Property.PinId = PinFactoryId;
/* query pin factory */ hResult = KsSynchronousDeviceControl(FilterHandle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
if (hResult == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_INSUFFICIENT_BUFFER)) { /* buffer too small */ hResult = KsSynchronousDeviceControl(FilterHandle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)&NumData, sizeof(ULONG), &BytesReturned);
if (SUCCEEDED(hResult)) { /* store required data size */ BytesReturned = NumData; hResult = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_MORE_DATA); } }
if (hResult == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_MORE_DATA)) { /* allocate data */ *Items = CoTaskMemAlloc(BytesReturned);
if (!*Items) { /* no memory */ return E_OUTOFMEMORY; }
/* retry querying property */ hResult = KsSynchronousDeviceControl(FilterHandle, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSP_PIN), (PVOID)*Items, BytesReturned, &BytesReturned);
/* check for success */ if (FAILED(hResult)) { /* free memory */ CoTaskMemFree(*Items); } }
/* done */ return hResult;}
KSDDKAPIHRESULTWINAPIKsGetMediaTypeCount( HANDLE FilterHandle, ULONG PinFactoryId, ULONG *MediaTypeCount){ PKSMULTIPLE_ITEM MultipleItem; HRESULT hr;
/* try get constrained data ranges */ hr = KsGetMultiplePinFactoryItems(FilterHandle, PinFactoryId, KSPROPERTY_PIN_CONSTRAINEDDATARANGES, (PVOID*)&MultipleItem);
/* check for failure*/ if (FAILED(hr)) { /* try getting default data ranges */ hr = KsGetMultiplePinFactoryItems(FilterHandle, PinFactoryId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&MultipleItem); }
if (SUCCEEDED(hr)) { /* store number of media types */ *MediaTypeCount = MultipleItem->Count;
/* free memory */ CoTaskMemFree(MultipleItem); }
/* done */ return hr;}
KSDDKAPIHRESULTWINAPIKsGetMediaType( int Position, AM_MEDIA_TYPE *AmMediaType, HANDLE FilterHandle, ULONG PinFactoryId){ HRESULT hr; PKSMULTIPLE_ITEM ItemList; int i = 0; PKSDATAFORMAT DataFormat;
if (Position < 0) return E_INVALIDARG;
// get current supported ranges hr = KsGetMultiplePinFactoryItems(FilterHandle, PinFactoryId, KSPROPERTY_PIN_CONSTRAINEDDATARANGES, (PVOID*)&ItemList); if (FAILED(hr)) { // get standard dataranges hr = KsGetMultiplePinFactoryItems(FilterHandle, PinFactoryId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&ItemList);
//check for success if (FAILED(hr)) return hr; }
if ((ULONG)Position >= ItemList->Count) { // out of bounds CoTaskMemFree(ItemList); return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_NO_MORE_ITEMS); }
// goto first datarange DataFormat = (PKSDATAFORMAT)(ItemList + 1);
while(i != Position) { // goto next format; DataFormat = (PKSDATAFORMAT)(ULONG_PTR)(DataFormat + DataFormat->FormatSize); i++; }
DataFormat->FormatSize -= sizeof(KSDATAFORMAT); if (DataFormat->FormatSize) { // copy extra format buffer AmMediaType->pbFormat = (BYTE*)CoTaskMemAlloc(DataFormat->FormatSize); if (!AmMediaType->pbFormat) { // not enough memory CoTaskMemFree(ItemList); return E_OUTOFMEMORY; } // copy format buffer CopyMemory(AmMediaType->pbFormat, (DataFormat + 1), DataFormat->FormatSize); AmMediaType->cbFormat = DataFormat->FormatSize; } else { // no format buffer AmMediaType->pbFormat = NULL; AmMediaType->cbFormat = 0; }
// copy type info CopyMemory(&AmMediaType->majortype, &DataFormat->MajorFormat, sizeof(GUID)); CopyMemory(&AmMediaType->subtype, &DataFormat->SubFormat, sizeof(GUID)); CopyMemory(&AmMediaType->formattype, &DataFormat->Specifier, sizeof(GUID)); AmMediaType->bTemporalCompression = FALSE; //FIXME verify AmMediaType->pUnk = NULL; //FIXME AmMediaType->lSampleSize = DataFormat->SampleSize; AmMediaType->bFixedSizeSamples = (AmMediaType->lSampleSize) ? TRUE : FALSE;
// free dataformat list CoTaskMemFree(ItemList);
return NOERROR;}
extern "C"KSDDKAPIHRESULTWINAPIDllUnregisterServer(void){ ULONG Index = 0; LPOLESTR pStr; HRESULT hr = S_OK; HKEY hClass;
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_SET_VALUE, &hClass) != ERROR_SUCCESS) return E_FAIL;
do { hr = StringFromCLSID(*InterfaceTable[Index].riid, &pStr); if (FAILED(hr)) break;
RegDeleteKeyW(hClass, pStr); CoTaskMemFree(pStr); Index++; }while(InterfaceTable[Index].lpfnCI != 0);
RegCloseKey(hClass); return hr;}
extern "C"KSDDKAPIHRESULTWINAPIDllRegisterServer(void){ ULONG Index = 0; LPOLESTR pStr; HRESULT hr = S_OK; HKEY hClass, hKey, hSubKey; static LPCWSTR ModuleName = L"ksproxy.ax"; static LPCWSTR ThreadingModel = L"Both";
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID", 0, KEY_WRITE, &hClass) != ERROR_SUCCESS) return E_FAIL;
do { hr = StringFromCLSID(*InterfaceTable[Index].riid, &pStr); if (FAILED(hr)) break;
if (RegCreateKeyExW(hClass, pStr, 0, 0, 0, KEY_WRITE, NULL, &hKey, 0) == ERROR_SUCCESS) { if (RegCreateKeyExW(hKey, L"InprocServer32", 0, 0, 0, KEY_WRITE, NULL, &hSubKey, 0) == ERROR_SUCCESS) { RegSetValueExW(hSubKey, 0, 0, REG_SZ, (const BYTE*)ModuleName, (wcslen(ModuleName) + 1) * sizeof(WCHAR)); RegSetValueExW(hSubKey, L"ThreadingModel", 0, REG_SZ, (const BYTE*)ThreadingModel, (wcslen(ThreadingModel) + 1) * sizeof(WCHAR)); RegCloseKey(hSubKey); } RegCloseKey(hKey); }
CoTaskMemFree(pStr); Index++; }while(InterfaceTable[Index].lpfnCI != 0);
RegCloseKey(hClass); return hr;}
KSDDKAPIHRESULTWINAPIDllGetClassObject( REFCLSID rclsid, REFIID riid, LPVOID *ppv){ UINT i; HRESULT hres = E_OUTOFMEMORY; IClassFactory * pcf = NULL;
if (!ppv) return E_INVALIDARG;
*ppv = NULL;
for (i = 0; InterfaceTable[i].riid; i++) { if (IsEqualIID(*InterfaceTable[i].riid, rclsid)) { pcf = CClassFactory_fnConstructor(InterfaceTable[i].lpfnCI, NULL, NULL); break; } }
if (!pcf) { return CLASS_E_CLASSNOTAVAILABLE; }
hres = pcf->QueryInterface(riid, ppv); pcf->Release();
return hres;}
KSDDKAPIHRESULTWINAPIDllCanUnloadNow(void){ return S_OK;}