2 * Copyright (C) 2015 Austin English
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "mf_private.h"
31 #include "wine/debug.h"
32 #include "wine/list.h"
33 #include "wine/mfinternal.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(mfplat
);
37 extern const GUID CLSID_FileSchemePlugin
;
39 struct activate_object
41 IMFActivate IMFActivate_iface
;
43 IMFAttributes
*attributes
;
45 const struct activate_funcs
*funcs
;
49 static struct activate_object
*impl_from_IMFActivate(IMFActivate
*iface
)
51 return CONTAINING_RECORD(iface
, struct activate_object
, IMFActivate_iface
);
54 static HRESULT WINAPI
activate_object_QueryInterface(IMFActivate
*iface
, REFIID riid
, void **obj
)
56 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
58 if (IsEqualIID(riid
, &IID_IMFActivate
) ||
59 IsEqualIID(riid
, &IID_IMFAttributes
) ||
60 IsEqualIID(riid
, &IID_IUnknown
))
63 IMFActivate_AddRef(iface
);
67 WARN("Unsupported %s.\n", debugstr_guid(riid
));
72 static ULONG WINAPI
activate_object_AddRef(IMFActivate
*iface
)
74 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
75 ULONG refcount
= InterlockedIncrement(&activate
->refcount
);
77 TRACE("%p, refcount %lu.\n", iface
, refcount
);
82 static ULONG WINAPI
activate_object_Release(IMFActivate
*iface
)
84 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
85 ULONG refcount
= InterlockedDecrement(&activate
->refcount
);
87 TRACE("%p, refcount %lu.\n", iface
, refcount
);
91 if (activate
->funcs
->free_private
)
92 activate
->funcs
->free_private(activate
->context
);
94 IUnknown_Release(activate
->object
);
95 IMFAttributes_Release(activate
->attributes
);
102 static HRESULT WINAPI
activate_object_GetItem(IMFActivate
*iface
, REFGUID key
, PROPVARIANT
*value
)
104 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
106 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
108 return IMFAttributes_GetItem(activate
->attributes
, key
, value
);
111 static HRESULT WINAPI
activate_object_GetItemType(IMFActivate
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
113 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
115 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), type
);
117 return IMFAttributes_GetItemType(activate
->attributes
, key
, type
);
120 static HRESULT WINAPI
activate_object_CompareItem(IMFActivate
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
122 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
124 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, result
);
126 return IMFAttributes_CompareItem(activate
->attributes
, key
, value
, result
);
129 static HRESULT WINAPI
activate_object_Compare(IMFActivate
*iface
, IMFAttributes
*theirs
, MF_ATTRIBUTES_MATCH_TYPE type
,
132 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
134 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, type
, result
);
136 return IMFAttributes_Compare(activate
->attributes
, theirs
, type
, result
);
139 static HRESULT WINAPI
activate_object_GetUINT32(IMFActivate
*iface
, REFGUID key
, UINT32
*value
)
141 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
143 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
145 return IMFAttributes_GetUINT32(activate
->attributes
, key
, value
);
148 static HRESULT WINAPI
activate_object_GetUINT64(IMFActivate
*iface
, REFGUID key
, UINT64
*value
)
150 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
152 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
154 return IMFAttributes_GetUINT64(activate
->attributes
, key
, value
);
157 static HRESULT WINAPI
activate_object_GetDouble(IMFActivate
*iface
, REFGUID key
, double *value
)
159 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
161 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
163 return IMFAttributes_GetDouble(activate
->attributes
, key
, value
);
166 static HRESULT WINAPI
activate_object_GetGUID(IMFActivate
*iface
, REFGUID key
, GUID
*value
)
168 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
170 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
172 return IMFAttributes_GetGUID(activate
->attributes
, key
, value
);
175 static HRESULT WINAPI
activate_object_GetStringLength(IMFActivate
*iface
, REFGUID key
, UINT32
*length
)
177 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
179 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), length
);
181 return IMFAttributes_GetStringLength(activate
->attributes
, key
, length
);
184 static HRESULT WINAPI
activate_object_GetString(IMFActivate
*iface
, REFGUID key
, WCHAR
*value
,
185 UINT32 size
, UINT32
*length
)
187 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
189 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_guid(key
), value
, size
, length
);
191 return IMFAttributes_GetString(activate
->attributes
, key
, value
, size
, length
);
194 static HRESULT WINAPI
activate_object_GetAllocatedString(IMFActivate
*iface
, REFGUID key
,
195 WCHAR
**value
, UINT32
*length
)
197 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
199 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, length
);
201 return IMFAttributes_GetAllocatedString(activate
->attributes
, key
, value
, length
);
204 static HRESULT WINAPI
activate_object_GetBlobSize(IMFActivate
*iface
, REFGUID key
, UINT32
*size
)
206 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
208 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), size
);
210 return IMFAttributes_GetBlobSize(activate
->attributes
, key
, size
);
213 static HRESULT WINAPI
activate_object_GetBlob(IMFActivate
*iface
, REFGUID key
, UINT8
*buf
,
214 UINT32 bufsize
, UINT32
*blobsize
)
216 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
218 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_guid(key
), buf
, bufsize
, blobsize
);
220 return IMFAttributes_GetBlob(activate
->attributes
, key
, buf
, bufsize
, blobsize
);
223 static HRESULT WINAPI
activate_object_GetAllocatedBlob(IMFActivate
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
225 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
227 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), buf
, size
);
229 return IMFAttributes_GetAllocatedBlob(activate
->attributes
, key
, buf
, size
);
232 static HRESULT WINAPI
activate_object_GetUnknown(IMFActivate
*iface
, REFGUID key
, REFIID riid
, void **ppv
)
234 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
236 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_guid(key
), debugstr_guid(riid
), ppv
);
238 return IMFAttributes_GetUnknown(activate
->attributes
, key
, riid
, ppv
);
241 static HRESULT WINAPI
activate_object_SetItem(IMFActivate
*iface
, REFGUID key
, REFPROPVARIANT value
)
243 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
245 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
247 return IMFAttributes_SetItem(activate
->attributes
, key
, value
);
250 static HRESULT WINAPI
activate_object_DeleteItem(IMFActivate
*iface
, REFGUID key
)
252 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
254 TRACE("%p, %s.\n", iface
, debugstr_guid(key
));
256 return IMFAttributes_DeleteItem(activate
->attributes
, key
);
259 static HRESULT WINAPI
activate_object_DeleteAllItems(IMFActivate
*iface
)
261 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
263 TRACE("%p.\n", iface
);
265 return IMFAttributes_DeleteAllItems(activate
->attributes
);
268 static HRESULT WINAPI
activate_object_SetUINT32(IMFActivate
*iface
, REFGUID key
, UINT32 value
)
270 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
272 TRACE("%p, %s, %d.\n", iface
, debugstr_guid(key
), value
);
274 return IMFAttributes_SetUINT32(activate
->attributes
, key
, value
);
277 static HRESULT WINAPI
activate_object_SetUINT64(IMFActivate
*iface
, REFGUID key
, UINT64 value
)
279 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
281 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), wine_dbgstr_longlong(value
));
283 return IMFAttributes_SetUINT64(activate
->attributes
, key
, value
);
286 static HRESULT WINAPI
activate_object_SetDouble(IMFActivate
*iface
, REFGUID key
, double value
)
288 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
290 TRACE("%p, %s, %f.\n", iface
, debugstr_guid(key
), value
);
292 return IMFAttributes_SetDouble(activate
->attributes
, key
, value
);
295 static HRESULT WINAPI
activate_object_SetGUID(IMFActivate
*iface
, REFGUID key
, REFGUID value
)
297 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
299 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_guid(value
));
301 return IMFAttributes_SetGUID(activate
->attributes
, key
, value
);
304 static HRESULT WINAPI
activate_object_SetString(IMFActivate
*iface
, REFGUID key
, const WCHAR
*value
)
306 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
308 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_w(value
));
310 return IMFAttributes_SetString(activate
->attributes
, key
, value
);
313 static HRESULT WINAPI
activate_object_SetBlob(IMFActivate
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
315 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
317 TRACE("%p, %s, %p, %d.\n", iface
, debugstr_guid(key
), buf
, size
);
319 return IMFAttributes_SetBlob(activate
->attributes
, key
, buf
, size
);
322 static HRESULT WINAPI
activate_object_SetUnknown(IMFActivate
*iface
, REFGUID key
, IUnknown
*unknown
)
324 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
326 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(key
), unknown
);
328 return IMFAttributes_SetUnknown(activate
->attributes
, key
, unknown
);
331 static HRESULT WINAPI
activate_object_LockStore(IMFActivate
*iface
)
333 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
335 TRACE("%p.\n", iface
);
337 return IMFAttributes_LockStore(activate
->attributes
);
340 static HRESULT WINAPI
activate_object_UnlockStore(IMFActivate
*iface
)
342 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
344 TRACE("%p.\n", iface
);
346 return IMFAttributes_UnlockStore(activate
->attributes
);
349 static HRESULT WINAPI
activate_object_GetCount(IMFActivate
*iface
, UINT32
*count
)
351 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
353 TRACE("%p, %p.\n", iface
, count
);
355 return IMFAttributes_GetCount(activate
->attributes
, count
);
358 static HRESULT WINAPI
activate_object_GetItemByIndex(IMFActivate
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
360 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
362 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
364 return IMFAttributes_GetItemByIndex(activate
->attributes
, index
, key
, value
);
367 static HRESULT WINAPI
activate_object_CopyAllItems(IMFActivate
*iface
, IMFAttributes
*dest
)
369 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
371 TRACE("%p, %p.\n", iface
, dest
);
373 return IMFAttributes_CopyAllItems(activate
->attributes
, dest
);
376 static HRESULT WINAPI
activate_object_ActivateObject(IMFActivate
*iface
, REFIID riid
, void **obj
)
378 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
382 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
384 if (!activate
->object
)
386 if (FAILED(hr
= activate
->funcs
->create_object((IMFAttributes
*)iface
, activate
->context
, &object
)))
389 if (InterlockedCompareExchangePointer((void **)&activate
->object
, object
, NULL
))
390 IUnknown_Release(object
);
393 return IUnknown_QueryInterface(activate
->object
, riid
, obj
);
396 static HRESULT WINAPI
activate_object_ShutdownObject(IMFActivate
*iface
)
398 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
401 TRACE("%p.\n", iface
);
403 if ((object
= InterlockedCompareExchangePointer((void **)&activate
->object
, NULL
, activate
->object
)))
405 activate
->funcs
->shutdown_object(activate
->context
, object
);
406 IUnknown_Release(object
);
412 static HRESULT WINAPI
activate_object_DetachObject(IMFActivate
*iface
)
414 TRACE("%p.\n", iface
);
419 static const IMFActivateVtbl activate_object_vtbl
=
421 activate_object_QueryInterface
,
422 activate_object_AddRef
,
423 activate_object_Release
,
424 activate_object_GetItem
,
425 activate_object_GetItemType
,
426 activate_object_CompareItem
,
427 activate_object_Compare
,
428 activate_object_GetUINT32
,
429 activate_object_GetUINT64
,
430 activate_object_GetDouble
,
431 activate_object_GetGUID
,
432 activate_object_GetStringLength
,
433 activate_object_GetString
,
434 activate_object_GetAllocatedString
,
435 activate_object_GetBlobSize
,
436 activate_object_GetBlob
,
437 activate_object_GetAllocatedBlob
,
438 activate_object_GetUnknown
,
439 activate_object_SetItem
,
440 activate_object_DeleteItem
,
441 activate_object_DeleteAllItems
,
442 activate_object_SetUINT32
,
443 activate_object_SetUINT64
,
444 activate_object_SetDouble
,
445 activate_object_SetGUID
,
446 activate_object_SetString
,
447 activate_object_SetBlob
,
448 activate_object_SetUnknown
,
449 activate_object_LockStore
,
450 activate_object_UnlockStore
,
451 activate_object_GetCount
,
452 activate_object_GetItemByIndex
,
453 activate_object_CopyAllItems
,
454 activate_object_ActivateObject
,
455 activate_object_ShutdownObject
,
456 activate_object_DetachObject
,
459 HRESULT
create_activation_object(void *context
, const struct activate_funcs
*funcs
, IMFActivate
**ret
)
461 struct activate_object
*object
;
464 if (!(object
= calloc(1, sizeof(*object
))))
465 return E_OUTOFMEMORY
;
467 object
->IMFActivate_iface
.lpVtbl
= &activate_object_vtbl
;
468 object
->refcount
= 1;
469 if (FAILED(hr
= MFCreateAttributes(&object
->attributes
, 0)))
474 object
->funcs
= funcs
;
475 object
->context
= context
;
477 *ret
= &object
->IMFActivate_iface
;
484 IClassFactory IClassFactory_iface
;
485 HRESULT (*create_instance
)(REFIID riid
, void **obj
);
488 static inline struct class_factory
*impl_from_IClassFactory(IClassFactory
*iface
)
490 return CONTAINING_RECORD(iface
, struct class_factory
, IClassFactory_iface
);
493 static HRESULT WINAPI
class_factory_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **obj
)
495 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
497 if (IsEqualGUID(riid
, &IID_IClassFactory
) ||
498 IsEqualGUID(riid
, &IID_IUnknown
))
501 IClassFactory_AddRef(iface
);
505 WARN("%s is not supported.\n", debugstr_guid(riid
));
507 return E_NOINTERFACE
;
510 static ULONG WINAPI
class_factory_AddRef(IClassFactory
*iface
)
515 static ULONG WINAPI
class_factory_Release(IClassFactory
*iface
)
520 static HRESULT WINAPI
class_factory_CreateInstance(IClassFactory
*iface
, IUnknown
*outer
, REFIID riid
, void **obj
)
522 struct class_factory
*factory
= impl_from_IClassFactory(iface
);
524 TRACE("%p, %p, %s, %p.\n", iface
, outer
, debugstr_guid(riid
), obj
);
529 return CLASS_E_NOAGGREGATION
;
532 return factory
->create_instance(riid
, obj
);
535 static HRESULT WINAPI
class_factory_LockServer(IClassFactory
*iface
, BOOL dolock
)
537 FIXME("%d.\n", dolock
);
542 static const IClassFactoryVtbl class_factory_vtbl
=
544 class_factory_QueryInterface
,
545 class_factory_AddRef
,
546 class_factory_Release
,
547 class_factory_CreateInstance
,
548 class_factory_LockServer
,
551 static struct class_factory file_scheme_handler_factory
= { { &class_factory_vtbl
}, file_scheme_handler_construct
};
552 static struct class_factory urlmon_scheme_handler_factory
= { { &class_factory_vtbl
}, urlmon_scheme_handler_construct
};
554 static const struct class_object
557 IClassFactory
*factory
;
561 { &CLSID_FileSchemePlugin
, &file_scheme_handler_factory
.IClassFactory_iface
},
562 { &CLSID_UrlmonSchemePlugin
, &urlmon_scheme_handler_factory
.IClassFactory_iface
},
565 /*******************************************************************************
566 * DllGetClassObject (mf.@)
568 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, void **obj
)
572 TRACE("%s, %s, %p.\n", debugstr_guid(rclsid
), debugstr_guid(riid
), obj
);
574 for (i
= 0; i
< ARRAY_SIZE(class_objects
); ++i
)
576 if (IsEqualGUID(class_objects
[i
].clsid
, rclsid
))
577 return IClassFactory_QueryInterface(class_objects
[i
].factory
, riid
, obj
);
580 WARN("%s: class not found.\n", debugstr_guid(rclsid
));
581 return CLASS_E_CLASSNOTAVAILABLE
;
584 static HRESULT
prop_string_vector_append(PROPVARIANT
*vector
, unsigned int *capacity
, BOOL unique
, const WCHAR
*str
)
591 for (i
= 0; i
< vector
->calpwstr
.cElems
; ++i
)
593 if (!lstrcmpW(vector
->calpwstr
.pElems
[i
], str
))
598 if (!*capacity
|| *capacity
- 1 < vector
->calpwstr
.cElems
)
600 unsigned int new_count
;
603 new_count
= *capacity
? *capacity
* 2 : 10;
604 ptr
= CoTaskMemRealloc(vector
->calpwstr
.pElems
, new_count
* sizeof(*vector
->calpwstr
.pElems
));
606 return E_OUTOFMEMORY
;
607 vector
->calpwstr
.pElems
= ptr
;
608 *capacity
= new_count
;
612 if (!(vector
->calpwstr
.pElems
[vector
->calpwstr
.cElems
] = ptrW
= CoTaskMemAlloc((len
+ 1) * sizeof(WCHAR
))))
613 return E_OUTOFMEMORY
;
616 vector
->calpwstr
.cElems
++;
621 static int __cdecl
qsort_string_compare(const void *a
, const void *b
)
623 const WCHAR
*left
= *(const WCHAR
**)a
, *right
= *(const WCHAR
**)b
;
624 return lstrcmpW(left
, right
);
627 static HRESULT
mf_get_handler_strings(const WCHAR
*path
, WCHAR filter
, unsigned int maxlen
, PROPVARIANT
*dst
)
629 static const HKEY hkey_roots
[2] = { HKEY_CURRENT_USER
, HKEY_LOCAL_MACHINE
};
630 unsigned int capacity
= 0, count
;
636 if (!(buffW
= calloc(maxlen
, sizeof(*buffW
))))
637 return E_OUTOFMEMORY
;
639 memset(dst
, 0, sizeof(*dst
));
640 dst
->vt
= VT_VECTOR
| VT_LPWSTR
;
642 for (i
= 0; i
< ARRAY_SIZE(hkey_roots
); ++i
)
646 if (RegOpenKeyW(hkey_roots
[i
], path
, &hkey
))
651 count
= dst
->calpwstr
.cElems
;
652 while (!RegEnumKeyExW(hkey
, index
++, buffW
, &size
, NULL
, NULL
, NULL
, NULL
))
654 if (filter
&& !wcschr(buffW
, filter
))
657 if (FAILED(hr
= prop_string_vector_append(dst
, &capacity
, i
> 0, buffW
)))
662 /* Sort last pass results. */
663 qsort(&dst
->calpwstr
.pElems
[count
], dst
->calpwstr
.cElems
- count
, sizeof(*dst
->calpwstr
.pElems
),
664 qsort_string_compare
);
670 PropVariantClear(dst
);
677 /***********************************************************************
678 * MFGetSupportedMimeTypes (mf.@)
680 HRESULT WINAPI
MFGetSupportedMimeTypes(PROPVARIANT
*dst
)
689 /* According to RFC4288 it's 127/127 characters. */
690 maxlen
= 127 /* type */ + 1 /* / */ + 127 /* subtype */ + 1;
691 return mf_get_handler_strings(L
"Software\\Microsoft\\Windows Media Foundation\\ByteStreamHandlers", '/',
695 /***********************************************************************
696 * MFGetSupportedSchemes (mf.@)
698 HRESULT WINAPI
MFGetSupportedSchemes(PROPVARIANT
*dst
)
705 return mf_get_handler_strings(L
"Software\\Microsoft\\Windows Media Foundation\\SchemeHandlers", 0, 64, dst
);
708 /***********************************************************************
709 * MFGetService (mf.@)
711 HRESULT WINAPI
MFGetService(IUnknown
*object
, REFGUID service
, REFIID riid
, void **obj
)
716 TRACE("(%p, %s, %s, %p)\n", object
, debugstr_guid(service
), debugstr_guid(riid
), obj
);
721 if (FAILED(hr
= IUnknown_QueryInterface(object
, &IID_IMFGetService
, (void **)&gs
)))
724 hr
= IMFGetService_GetService(gs
, service
, riid
, obj
);
725 IMFGetService_Release(gs
);
729 /***********************************************************************
730 * MFShutdownObject (mf.@)
732 HRESULT WINAPI
MFShutdownObject(IUnknown
*object
)
734 IMFShutdown
*shutdown
;
736 TRACE("%p.\n", object
);
738 if (object
&& SUCCEEDED(IUnknown_QueryInterface(object
, &IID_IMFShutdown
, (void **)&shutdown
)))
740 IMFShutdown_Shutdown(shutdown
);
741 IMFShutdown_Release(shutdown
);
747 /***********************************************************************
748 * MFEnumDeviceSources (mf.@)
750 HRESULT WINAPI
MFEnumDeviceSources(IMFAttributes
*attributes
, IMFActivate
***sources
, UINT32
*count
)
752 FIXME("%p, %p, %p.\n", attributes
, sources
, count
);
754 if (!attributes
|| !sources
|| !count
)
762 struct simple_type_handler
764 IMFMediaTypeHandler IMFMediaTypeHandler_iface
;
766 IMFMediaType
*media_type
;
770 static struct simple_type_handler
*impl_from_IMFMediaTypeHandler(IMFMediaTypeHandler
*iface
)
772 return CONTAINING_RECORD(iface
, struct simple_type_handler
, IMFMediaTypeHandler_iface
);
775 static HRESULT WINAPI
simple_type_handler_QueryInterface(IMFMediaTypeHandler
*iface
, REFIID riid
, void **obj
)
777 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
779 if (IsEqualIID(riid
, &IID_IMFMediaTypeHandler
) ||
780 IsEqualIID(riid
, &IID_IUnknown
))
783 IMFMediaTypeHandler_AddRef(iface
);
788 return E_NOINTERFACE
;
791 static ULONG WINAPI
simple_type_handler_AddRef(IMFMediaTypeHandler
*iface
)
793 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
794 ULONG refcount
= InterlockedIncrement(&handler
->refcount
);
796 TRACE("%p, refcount %lu.\n", iface
, refcount
);
801 static ULONG WINAPI
simple_type_handler_Release(IMFMediaTypeHandler
*iface
)
803 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
804 ULONG refcount
= InterlockedDecrement(&handler
->refcount
);
806 TRACE("%p, refcount %lu.\n", iface
, refcount
);
810 if (handler
->media_type
)
811 IMFMediaType_Release(handler
->media_type
);
812 DeleteCriticalSection(&handler
->cs
);
819 static HRESULT WINAPI
simple_type_handler_IsMediaTypeSupported(IMFMediaTypeHandler
*iface
, IMFMediaType
*in_type
,
820 IMFMediaType
**out_type
)
822 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
826 TRACE("%p, %p, %p.\n", iface
, in_type
, out_type
);
831 EnterCriticalSection(&handler
->cs
);
832 if (!handler
->media_type
)
833 hr
= MF_E_UNEXPECTED
;
836 if (SUCCEEDED(hr
= IMFMediaType_IsEqual(handler
->media_type
, in_type
, &flags
)))
837 hr
= (flags
& (MF_MEDIATYPE_EQUAL_MAJOR_TYPES
| MF_MEDIATYPE_EQUAL_FORMAT_TYPES
)) ==
838 (MF_MEDIATYPE_EQUAL_MAJOR_TYPES
| MF_MEDIATYPE_EQUAL_FORMAT_TYPES
) ? S_OK
: E_FAIL
;
840 LeaveCriticalSection(&handler
->cs
);
845 static HRESULT WINAPI
simple_type_handler_GetMediaTypeCount(IMFMediaTypeHandler
*iface
, DWORD
*count
)
847 TRACE("%p, %p.\n", iface
, count
);
857 static HRESULT WINAPI
simple_type_handler_GetMediaTypeByIndex(IMFMediaTypeHandler
*iface
, DWORD index
,
860 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
862 TRACE("%p, %lu, %p.\n", iface
, index
, type
);
865 return MF_E_NO_MORE_TYPES
;
867 EnterCriticalSection(&handler
->cs
);
868 *type
= handler
->media_type
;
870 IMFMediaType_AddRef(*type
);
871 LeaveCriticalSection(&handler
->cs
);
876 static HRESULT WINAPI
simple_type_handler_SetCurrentMediaType(IMFMediaTypeHandler
*iface
, IMFMediaType
*media_type
)
878 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
880 TRACE("%p, %p.\n", iface
, media_type
);
882 EnterCriticalSection(&handler
->cs
);
883 if (handler
->media_type
)
884 IMFMediaType_Release(handler
->media_type
);
885 handler
->media_type
= media_type
;
886 if (handler
->media_type
)
887 IMFMediaType_AddRef(handler
->media_type
);
888 LeaveCriticalSection(&handler
->cs
);
893 static HRESULT WINAPI
simple_type_handler_GetCurrentMediaType(IMFMediaTypeHandler
*iface
, IMFMediaType
**media_type
)
895 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
897 TRACE("%p, %p.\n", iface
, media_type
);
902 EnterCriticalSection(&handler
->cs
);
903 *media_type
= handler
->media_type
;
905 IMFMediaType_AddRef(*media_type
);
906 LeaveCriticalSection(&handler
->cs
);
911 static HRESULT WINAPI
simple_type_handler_GetMajorType(IMFMediaTypeHandler
*iface
, GUID
*type
)
913 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
916 TRACE("%p, %p.\n", iface
, type
);
918 EnterCriticalSection(&handler
->cs
);
919 if (handler
->media_type
)
920 hr
= IMFMediaType_GetGUID(handler
->media_type
, &MF_MT_MAJOR_TYPE
, type
);
922 hr
= MF_E_NOT_INITIALIZED
;
923 LeaveCriticalSection(&handler
->cs
);
928 static const IMFMediaTypeHandlerVtbl simple_type_handler_vtbl
=
930 simple_type_handler_QueryInterface
,
931 simple_type_handler_AddRef
,
932 simple_type_handler_Release
,
933 simple_type_handler_IsMediaTypeSupported
,
934 simple_type_handler_GetMediaTypeCount
,
935 simple_type_handler_GetMediaTypeByIndex
,
936 simple_type_handler_SetCurrentMediaType
,
937 simple_type_handler_GetCurrentMediaType
,
938 simple_type_handler_GetMajorType
,
941 /*******************************************************************************
942 * MFCreateSimpleTypeHandler (mf.@)
944 HRESULT WINAPI
MFCreateSimpleTypeHandler(IMFMediaTypeHandler
**handler
)
946 struct simple_type_handler
*object
;
948 TRACE("%p.\n", handler
);
950 if (!(object
= calloc(1, sizeof(*object
))))
951 return E_OUTOFMEMORY
;
953 object
->IMFMediaTypeHandler_iface
.lpVtbl
= &simple_type_handler_vtbl
;
954 object
->refcount
= 1;
955 InitializeCriticalSection(&object
->cs
);
957 *handler
= &object
->IMFMediaTypeHandler_iface
;
962 /*******************************************************************************
963 * MFRequireProtectedEnvironment (mf.@)
965 HRESULT WINAPI
MFRequireProtectedEnvironment(IMFPresentationDescriptor
*pd
)
967 BOOL selected
, protected = FALSE
;
968 unsigned int i
= 0, value
;
969 IMFStreamDescriptor
*sd
;
973 while (SUCCEEDED(IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd
, i
++, &selected
, &sd
)))
976 protected = SUCCEEDED(IMFStreamDescriptor_GetUINT32(sd
, &MF_SD_PROTECTED
, &value
)) && value
;
977 IMFStreamDescriptor_Release(sd
);
978 if (protected) break;
981 return protected ? S_OK
: S_FALSE
;
984 static HRESULT
create_media_sink(const CLSID
*clsid
, IMFByteStream
*stream
, IMFMediaType
*video_type
,
985 IMFMediaType
*audio_type
, IMFMediaSink
**sink
)
987 IMFSinkClassFactory
*factory
;
990 if (FAILED(hr
= CoCreateInstance(clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFSinkClassFactory
, (void **)&factory
)))
993 hr
= IMFSinkClassFactory_CreateMediaSink(factory
, stream
, video_type
, audio_type
, sink
);
994 IMFSinkClassFactory_Release(factory
);
999 /*******************************************************************************
1000 * MFCreate3GPMediaSink (mf.@)
1002 HRESULT WINAPI
MFCreate3GPMediaSink(IMFByteStream
*stream
, IMFMediaType
*video_type
,
1003 IMFMediaType
*audio_type
, IMFMediaSink
**sink
)
1005 TRACE("%p, %p, %p, %p.\n", stream
, video_type
, audio_type
, sink
);
1007 return create_media_sink(&CLSID_MF3GPSinkClassFactory
, stream
, video_type
, audio_type
, sink
);
1010 /*******************************************************************************
1011 * MFCreateAC3MediaSink (mf.@)
1013 HRESULT WINAPI
MFCreateAC3MediaSink(IMFByteStream
*stream
, IMFMediaType
*audio_type
, IMFMediaSink
**sink
)
1015 TRACE("%p, %p, %p.\n", stream
, audio_type
, sink
);
1017 return create_media_sink(&CLSID_MFAC3SinkClassFactory
, stream
, NULL
, audio_type
, sink
);
1020 /*******************************************************************************
1021 * MFCreateADTSMediaSink (mf.@)
1023 HRESULT WINAPI
MFCreateADTSMediaSink(IMFByteStream
*stream
, IMFMediaType
*audio_type
, IMFMediaSink
**sink
)
1025 TRACE("%p, %p, %p.\n", stream
, audio_type
, sink
);
1027 return create_media_sink(&CLSID_MFADTSSinkClassFactory
, stream
, NULL
, audio_type
, sink
);
1030 /*******************************************************************************
1031 * MFCreateMP3MediaSink (mf.@)
1033 HRESULT WINAPI
MFCreateMP3MediaSink(IMFByteStream
*stream
, IMFMediaSink
**sink
)
1035 TRACE("%p, %p.\n", stream
, sink
);
1037 return create_media_sink(&CLSID_MFMP3SinkClassFactory
, stream
, NULL
, NULL
, sink
);
1040 /*******************************************************************************
1041 * MFCreateMPEG4MediaSink (mf.@)
1043 HRESULT WINAPI
MFCreateMPEG4MediaSink(IMFByteStream
*stream
, IMFMediaType
*video_type
,
1044 IMFMediaType
*audio_type
, IMFMediaSink
**sink
)
1046 TRACE("%p, %p, %p, %p.\n", stream
, video_type
, audio_type
, sink
);
1048 return create_media_sink(&CLSID_MFMPEG4SinkClassFactory
, stream
, video_type
, audio_type
, sink
);
1051 /*******************************************************************************
1052 * MFCreateFMPEG4MediaSink (mf.@)
1054 HRESULT WINAPI
MFCreateFMPEG4MediaSink(IMFByteStream
*stream
, IMFMediaType
*video_type
,
1055 IMFMediaType
*audio_type
, IMFMediaSink
**sink
)
1057 TRACE("%p, %p, %p, %p.\n", stream
, video_type
, audio_type
, sink
);
1059 return create_media_sink(&CLSID_MFFMPEG4SinkClassFactory
, stream
, video_type
, audio_type
, sink
);