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"
34 WINE_DEFAULT_DEBUG_CHANNEL(mfplat
);
36 extern const GUID CLSID_FileSchemePlugin
;
38 struct activate_object
40 IMFActivate IMFActivate_iface
;
42 IMFAttributes
*attributes
;
44 const struct activate_funcs
*funcs
;
48 static struct activate_object
*impl_from_IMFActivate(IMFActivate
*iface
)
50 return CONTAINING_RECORD(iface
, struct activate_object
, IMFActivate_iface
);
53 static HRESULT WINAPI
activate_object_QueryInterface(IMFActivate
*iface
, REFIID riid
, void **obj
)
55 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
57 if (IsEqualIID(riid
, &IID_IMFActivate
) ||
58 IsEqualIID(riid
, &IID_IMFAttributes
) ||
59 IsEqualIID(riid
, &IID_IUnknown
))
62 IMFActivate_AddRef(iface
);
66 WARN("Unsupported %s.\n", debugstr_guid(riid
));
71 static ULONG WINAPI
activate_object_AddRef(IMFActivate
*iface
)
73 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
74 ULONG refcount
= InterlockedIncrement(&activate
->refcount
);
76 TRACE("%p, refcount %lu.\n", iface
, refcount
);
81 static ULONG WINAPI
activate_object_Release(IMFActivate
*iface
)
83 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
84 ULONG refcount
= InterlockedDecrement(&activate
->refcount
);
86 TRACE("%p, refcount %lu.\n", iface
, refcount
);
90 if (activate
->funcs
->free_private
)
91 activate
->funcs
->free_private(activate
->context
);
93 IUnknown_Release(activate
->object
);
94 IMFAttributes_Release(activate
->attributes
);
101 static HRESULT WINAPI
activate_object_GetItem(IMFActivate
*iface
, REFGUID key
, PROPVARIANT
*value
)
103 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
105 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
107 return IMFAttributes_GetItem(activate
->attributes
, key
, value
);
110 static HRESULT WINAPI
activate_object_GetItemType(IMFActivate
*iface
, REFGUID key
, MF_ATTRIBUTE_TYPE
*type
)
112 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
114 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), type
);
116 return IMFAttributes_GetItemType(activate
->attributes
, key
, type
);
119 static HRESULT WINAPI
activate_object_CompareItem(IMFActivate
*iface
, REFGUID key
, REFPROPVARIANT value
, BOOL
*result
)
121 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
123 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, result
);
125 return IMFAttributes_CompareItem(activate
->attributes
, key
, value
, result
);
128 static HRESULT WINAPI
activate_object_Compare(IMFActivate
*iface
, IMFAttributes
*theirs
, MF_ATTRIBUTES_MATCH_TYPE type
,
131 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
133 TRACE("%p, %p, %d, %p.\n", iface
, theirs
, type
, result
);
135 return IMFAttributes_Compare(activate
->attributes
, theirs
, type
, result
);
138 static HRESULT WINAPI
activate_object_GetUINT32(IMFActivate
*iface
, REFGUID key
, UINT32
*value
)
140 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
142 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
144 return IMFAttributes_GetUINT32(activate
->attributes
, key
, value
);
147 static HRESULT WINAPI
activate_object_GetUINT64(IMFActivate
*iface
, REFGUID key
, UINT64
*value
)
149 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
151 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
153 return IMFAttributes_GetUINT64(activate
->attributes
, key
, value
);
156 static HRESULT WINAPI
activate_object_GetDouble(IMFActivate
*iface
, REFGUID key
, double *value
)
158 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
160 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
162 return IMFAttributes_GetDouble(activate
->attributes
, key
, value
);
165 static HRESULT WINAPI
activate_object_GetGUID(IMFActivate
*iface
, REFGUID key
, GUID
*value
)
167 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
169 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
171 return IMFAttributes_GetGUID(activate
->attributes
, key
, value
);
174 static HRESULT WINAPI
activate_object_GetStringLength(IMFActivate
*iface
, REFGUID key
, UINT32
*length
)
176 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
178 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), length
);
180 return IMFAttributes_GetStringLength(activate
->attributes
, key
, length
);
183 static HRESULT WINAPI
activate_object_GetString(IMFActivate
*iface
, REFGUID key
, WCHAR
*value
,
184 UINT32 size
, UINT32
*length
)
186 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
188 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_guid(key
), value
, size
, length
);
190 return IMFAttributes_GetString(activate
->attributes
, key
, value
, size
, length
);
193 static HRESULT WINAPI
activate_object_GetAllocatedString(IMFActivate
*iface
, REFGUID key
,
194 WCHAR
**value
, UINT32
*length
)
196 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
198 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), value
, length
);
200 return IMFAttributes_GetAllocatedString(activate
->attributes
, key
, value
, length
);
203 static HRESULT WINAPI
activate_object_GetBlobSize(IMFActivate
*iface
, REFGUID key
, UINT32
*size
)
205 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
207 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), size
);
209 return IMFAttributes_GetBlobSize(activate
->attributes
, key
, size
);
212 static HRESULT WINAPI
activate_object_GetBlob(IMFActivate
*iface
, REFGUID key
, UINT8
*buf
,
213 UINT32 bufsize
, UINT32
*blobsize
)
215 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
217 TRACE("%p, %s, %p, %d, %p.\n", iface
, debugstr_guid(key
), buf
, bufsize
, blobsize
);
219 return IMFAttributes_GetBlob(activate
->attributes
, key
, buf
, bufsize
, blobsize
);
222 static HRESULT WINAPI
activate_object_GetAllocatedBlob(IMFActivate
*iface
, REFGUID key
, UINT8
**buf
, UINT32
*size
)
224 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
226 TRACE("%p, %s, %p, %p.\n", iface
, debugstr_guid(key
), buf
, size
);
228 return IMFAttributes_GetAllocatedBlob(activate
->attributes
, key
, buf
, size
);
231 static HRESULT WINAPI
activate_object_GetUnknown(IMFActivate
*iface
, REFGUID key
, REFIID riid
, void **ppv
)
233 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
235 TRACE("%p, %s, %s, %p.\n", iface
, debugstr_guid(key
), debugstr_guid(riid
), ppv
);
237 return IMFAttributes_GetUnknown(activate
->attributes
, key
, riid
, ppv
);
240 static HRESULT WINAPI
activate_object_SetItem(IMFActivate
*iface
, REFGUID key
, REFPROPVARIANT value
)
242 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
244 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
246 return IMFAttributes_SetItem(activate
->attributes
, key
, value
);
249 static HRESULT WINAPI
activate_object_DeleteItem(IMFActivate
*iface
, REFGUID key
)
251 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
253 TRACE("%p, %s.\n", iface
, debugstr_guid(key
));
255 return IMFAttributes_DeleteItem(activate
->attributes
, key
);
258 static HRESULT WINAPI
activate_object_DeleteAllItems(IMFActivate
*iface
)
260 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
262 TRACE("%p.\n", iface
);
264 return IMFAttributes_DeleteAllItems(activate
->attributes
);
267 static HRESULT WINAPI
activate_object_SetUINT32(IMFActivate
*iface
, REFGUID key
, UINT32 value
)
269 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
271 TRACE("%p, %s, %d.\n", iface
, debugstr_guid(key
), value
);
273 return IMFAttributes_SetUINT32(activate
->attributes
, key
, value
);
276 static HRESULT WINAPI
activate_object_SetUINT64(IMFActivate
*iface
, REFGUID key
, UINT64 value
)
278 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
280 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), wine_dbgstr_longlong(value
));
282 return IMFAttributes_SetUINT64(activate
->attributes
, key
, value
);
285 static HRESULT WINAPI
activate_object_SetDouble(IMFActivate
*iface
, REFGUID key
, double value
)
287 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
289 TRACE("%p, %s, %f.\n", iface
, debugstr_guid(key
), value
);
291 return IMFAttributes_SetDouble(activate
->attributes
, key
, value
);
294 static HRESULT WINAPI
activate_object_SetGUID(IMFActivate
*iface
, REFGUID key
, REFGUID value
)
296 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
298 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_guid(value
));
300 return IMFAttributes_SetGUID(activate
->attributes
, key
, value
);
303 static HRESULT WINAPI
activate_object_SetString(IMFActivate
*iface
, REFGUID key
, const WCHAR
*value
)
305 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
307 TRACE("%p, %s, %s.\n", iface
, debugstr_guid(key
), debugstr_w(value
));
309 return IMFAttributes_SetString(activate
->attributes
, key
, value
);
312 static HRESULT WINAPI
activate_object_SetBlob(IMFActivate
*iface
, REFGUID key
, const UINT8
*buf
, UINT32 size
)
314 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
316 TRACE("%p, %s, %p, %d.\n", iface
, debugstr_guid(key
), buf
, size
);
318 return IMFAttributes_SetBlob(activate
->attributes
, key
, buf
, size
);
321 static HRESULT WINAPI
activate_object_SetUnknown(IMFActivate
*iface
, REFGUID key
, IUnknown
*unknown
)
323 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
325 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(key
), unknown
);
327 return IMFAttributes_SetUnknown(activate
->attributes
, key
, unknown
);
330 static HRESULT WINAPI
activate_object_LockStore(IMFActivate
*iface
)
332 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
334 TRACE("%p.\n", iface
);
336 return IMFAttributes_LockStore(activate
->attributes
);
339 static HRESULT WINAPI
activate_object_UnlockStore(IMFActivate
*iface
)
341 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
343 TRACE("%p.\n", iface
);
345 return IMFAttributes_UnlockStore(activate
->attributes
);
348 static HRESULT WINAPI
activate_object_GetCount(IMFActivate
*iface
, UINT32
*count
)
350 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
352 TRACE("%p, %p.\n", iface
, count
);
354 return IMFAttributes_GetCount(activate
->attributes
, count
);
357 static HRESULT WINAPI
activate_object_GetItemByIndex(IMFActivate
*iface
, UINT32 index
, GUID
*key
, PROPVARIANT
*value
)
359 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
361 TRACE("%p, %u, %p, %p.\n", iface
, index
, key
, value
);
363 return IMFAttributes_GetItemByIndex(activate
->attributes
, index
, key
, value
);
366 static HRESULT WINAPI
activate_object_CopyAllItems(IMFActivate
*iface
, IMFAttributes
*dest
)
368 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
370 TRACE("%p, %p.\n", iface
, dest
);
372 return IMFAttributes_CopyAllItems(activate
->attributes
, dest
);
375 static HRESULT WINAPI
activate_object_ActivateObject(IMFActivate
*iface
, REFIID riid
, void **obj
)
377 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
381 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
383 if (!activate
->object
)
385 if (FAILED(hr
= activate
->funcs
->create_object((IMFAttributes
*)iface
, activate
->context
, &object
)))
388 if (InterlockedCompareExchangePointer((void **)&activate
->object
, object
, NULL
))
389 IUnknown_Release(object
);
392 return IUnknown_QueryInterface(activate
->object
, riid
, obj
);
395 static HRESULT WINAPI
activate_object_ShutdownObject(IMFActivate
*iface
)
397 struct activate_object
*activate
= impl_from_IMFActivate(iface
);
400 TRACE("%p.\n", iface
);
402 if ((object
= InterlockedCompareExchangePointer((void **)&activate
->object
, NULL
, activate
->object
)))
404 activate
->funcs
->shutdown_object(activate
->context
, object
);
405 IUnknown_Release(object
);
411 static HRESULT WINAPI
activate_object_DetachObject(IMFActivate
*iface
)
413 TRACE("%p.\n", iface
);
418 static const IMFActivateVtbl activate_object_vtbl
=
420 activate_object_QueryInterface
,
421 activate_object_AddRef
,
422 activate_object_Release
,
423 activate_object_GetItem
,
424 activate_object_GetItemType
,
425 activate_object_CompareItem
,
426 activate_object_Compare
,
427 activate_object_GetUINT32
,
428 activate_object_GetUINT64
,
429 activate_object_GetDouble
,
430 activate_object_GetGUID
,
431 activate_object_GetStringLength
,
432 activate_object_GetString
,
433 activate_object_GetAllocatedString
,
434 activate_object_GetBlobSize
,
435 activate_object_GetBlob
,
436 activate_object_GetAllocatedBlob
,
437 activate_object_GetUnknown
,
438 activate_object_SetItem
,
439 activate_object_DeleteItem
,
440 activate_object_DeleteAllItems
,
441 activate_object_SetUINT32
,
442 activate_object_SetUINT64
,
443 activate_object_SetDouble
,
444 activate_object_SetGUID
,
445 activate_object_SetString
,
446 activate_object_SetBlob
,
447 activate_object_SetUnknown
,
448 activate_object_LockStore
,
449 activate_object_UnlockStore
,
450 activate_object_GetCount
,
451 activate_object_GetItemByIndex
,
452 activate_object_CopyAllItems
,
453 activate_object_ActivateObject
,
454 activate_object_ShutdownObject
,
455 activate_object_DetachObject
,
458 HRESULT
create_activation_object(void *context
, const struct activate_funcs
*funcs
, IMFActivate
**ret
)
460 struct activate_object
*object
;
463 if (!(object
= calloc(1, sizeof(*object
))))
464 return E_OUTOFMEMORY
;
466 object
->IMFActivate_iface
.lpVtbl
= &activate_object_vtbl
;
467 object
->refcount
= 1;
468 if (FAILED(hr
= MFCreateAttributes(&object
->attributes
, 0)))
473 object
->funcs
= funcs
;
474 object
->context
= context
;
476 *ret
= &object
->IMFActivate_iface
;
483 IClassFactory IClassFactory_iface
;
484 HRESULT (*create_instance
)(REFIID riid
, void **obj
);
487 static inline struct class_factory
*impl_from_IClassFactory(IClassFactory
*iface
)
489 return CONTAINING_RECORD(iface
, struct class_factory
, IClassFactory_iface
);
492 static HRESULT WINAPI
class_factory_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **obj
)
494 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
496 if (IsEqualGUID(riid
, &IID_IClassFactory
) ||
497 IsEqualGUID(riid
, &IID_IUnknown
))
500 IClassFactory_AddRef(iface
);
504 WARN("%s is not supported.\n", debugstr_guid(riid
));
506 return E_NOINTERFACE
;
509 static ULONG WINAPI
class_factory_AddRef(IClassFactory
*iface
)
514 static ULONG WINAPI
class_factory_Release(IClassFactory
*iface
)
519 static HRESULT WINAPI
class_factory_CreateInstance(IClassFactory
*iface
, IUnknown
*outer
, REFIID riid
, void **obj
)
521 struct class_factory
*factory
= impl_from_IClassFactory(iface
);
523 TRACE("%p, %p, %s, %p.\n", iface
, outer
, debugstr_guid(riid
), obj
);
528 return CLASS_E_NOAGGREGATION
;
531 return factory
->create_instance(riid
, obj
);
534 static HRESULT WINAPI
class_factory_LockServer(IClassFactory
*iface
, BOOL dolock
)
536 FIXME("%d.\n", dolock
);
541 static const IClassFactoryVtbl class_factory_vtbl
=
543 class_factory_QueryInterface
,
544 class_factory_AddRef
,
545 class_factory_Release
,
546 class_factory_CreateInstance
,
547 class_factory_LockServer
,
550 struct file_scheme_handler_result
553 IMFAsyncResult
*result
;
554 MF_OBJECT_TYPE obj_type
;
558 struct file_scheme_handler
560 IMFSchemeHandler IMFSchemeHandler_iface
;
561 IMFAsyncCallback IMFAsyncCallback_iface
;
563 IMFSourceResolver
*resolver
;
568 static struct file_scheme_handler
*impl_from_IMFSchemeHandler(IMFSchemeHandler
*iface
)
570 return CONTAINING_RECORD(iface
, struct file_scheme_handler
, IMFSchemeHandler_iface
);
573 static struct file_scheme_handler
*impl_from_IMFAsyncCallback(IMFAsyncCallback
*iface
)
575 return CONTAINING_RECORD(iface
, struct file_scheme_handler
, IMFAsyncCallback_iface
);
578 static HRESULT WINAPI
file_scheme_handler_QueryInterface(IMFSchemeHandler
*iface
, REFIID riid
, void **obj
)
580 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
582 if (IsEqualIID(riid
, &IID_IMFSchemeHandler
) ||
583 IsEqualIID(riid
, &IID_IUnknown
))
586 IMFSchemeHandler_AddRef(iface
);
590 WARN("Unsupported %s.\n", debugstr_guid(riid
));
592 return E_NOINTERFACE
;
595 static ULONG WINAPI
file_scheme_handler_AddRef(IMFSchemeHandler
*iface
)
597 struct file_scheme_handler
*handler
= impl_from_IMFSchemeHandler(iface
);
598 ULONG refcount
= InterlockedIncrement(&handler
->refcount
);
600 TRACE("%p, refcount %lu.\n", handler
, refcount
);
605 static ULONG WINAPI
file_scheme_handler_Release(IMFSchemeHandler
*iface
)
607 struct file_scheme_handler
*handler
= impl_from_IMFSchemeHandler(iface
);
608 ULONG refcount
= InterlockedDecrement(&handler
->refcount
);
609 struct file_scheme_handler_result
*result
, *next
;
611 TRACE("%p, refcount %lu.\n", iface
, refcount
);
615 LIST_FOR_EACH_ENTRY_SAFE(result
, next
, &handler
->results
, struct file_scheme_handler_result
, entry
)
617 list_remove(&result
->entry
);
618 IMFAsyncResult_Release(result
->result
);
620 IUnknown_Release(result
->object
);
623 DeleteCriticalSection(&handler
->cs
);
624 if (handler
->resolver
)
625 IMFSourceResolver_Release(handler
->resolver
);
632 struct create_object_context
634 IUnknown IUnknown_iface
;
637 IPropertyStore
*props
;
642 static struct create_object_context
*impl_from_IUnknown(IUnknown
*iface
)
644 return CONTAINING_RECORD(iface
, struct create_object_context
, IUnknown_iface
);
647 static HRESULT WINAPI
create_object_context_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
649 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
651 if (IsEqualIID(riid
, &IID_IUnknown
))
654 IUnknown_AddRef(iface
);
658 WARN("Unsupported %s.\n", debugstr_guid(riid
));
660 return E_NOINTERFACE
;
663 static ULONG WINAPI
create_object_context_AddRef(IUnknown
*iface
)
665 struct create_object_context
*context
= impl_from_IUnknown(iface
);
666 ULONG refcount
= InterlockedIncrement(&context
->refcount
);
668 TRACE("%p, refcount %lu.\n", iface
, refcount
);
673 static ULONG WINAPI
create_object_context_Release(IUnknown
*iface
)
675 struct create_object_context
*context
= impl_from_IUnknown(iface
);
676 ULONG refcount
= InterlockedDecrement(&context
->refcount
);
678 TRACE("%p, refcount %lu.\n", iface
, refcount
);
683 IPropertyStore_Release(context
->props
);
691 static const IUnknownVtbl create_object_context_vtbl
=
693 create_object_context_QueryInterface
,
694 create_object_context_AddRef
,
695 create_object_context_Release
,
698 static HRESULT WINAPI
file_scheme_handler_BeginCreateObject(IMFSchemeHandler
*iface
, const WCHAR
*url
, DWORD flags
,
699 IPropertyStore
*props
, IUnknown
**cancel_cookie
, IMFAsyncCallback
*callback
, IUnknown
*state
)
701 struct file_scheme_handler
*handler
= impl_from_IMFSchemeHandler(iface
);
702 struct create_object_context
*context
;
703 IMFAsyncResult
*caller
, *item
;
706 TRACE("%p, %s, %#lx, %p, %p, %p, %p.\n", iface
, debugstr_w(url
), flags
, props
, cancel_cookie
, callback
, state
);
709 *cancel_cookie
= NULL
;
711 if (FAILED(hr
= MFCreateAsyncResult(NULL
, callback
, state
, &caller
)))
714 if (!(context
= malloc(sizeof(*context
))))
716 IMFAsyncResult_Release(caller
);
717 return E_OUTOFMEMORY
;
720 context
->IUnknown_iface
.lpVtbl
= &create_object_context_vtbl
;
721 context
->refcount
= 1;
722 context
->props
= props
;
724 IPropertyStore_AddRef(context
->props
);
725 context
->flags
= flags
;
726 context
->url
= wcsdup(url
);
729 IMFAsyncResult_Release(caller
);
730 IUnknown_Release(&context
->IUnknown_iface
);
731 return E_OUTOFMEMORY
;
734 hr
= MFCreateAsyncResult(&context
->IUnknown_iface
, &handler
->IMFAsyncCallback_iface
, (IUnknown
*)caller
, &item
);
735 IUnknown_Release(&context
->IUnknown_iface
);
738 if (SUCCEEDED(hr
= MFPutWorkItemEx(MFASYNC_CALLBACK_QUEUE_IO
, item
)))
742 *cancel_cookie
= (IUnknown
*)caller
;
743 IUnknown_AddRef(*cancel_cookie
);
747 IMFAsyncResult_Release(item
);
749 IMFAsyncResult_Release(caller
);
754 static HRESULT WINAPI
file_scheme_handler_EndCreateObject(IMFSchemeHandler
*iface
, IMFAsyncResult
*result
,
755 MF_OBJECT_TYPE
*obj_type
, IUnknown
**object
)
757 struct file_scheme_handler
*handler
= impl_from_IMFSchemeHandler(iface
);
758 struct file_scheme_handler_result
*found
= NULL
, *cur
;
761 TRACE("%p, %p, %p, %p.\n", iface
, result
, obj_type
, object
);
763 EnterCriticalSection(&handler
->cs
);
765 LIST_FOR_EACH_ENTRY(cur
, &handler
->results
, struct file_scheme_handler_result
, entry
)
767 if (result
== cur
->result
)
769 list_remove(&cur
->entry
);
775 LeaveCriticalSection(&handler
->cs
);
779 *obj_type
= found
->obj_type
;
780 *object
= found
->object
;
781 hr
= IMFAsyncResult_GetStatus(found
->result
);
782 IMFAsyncResult_Release(found
->result
);
787 *obj_type
= MF_OBJECT_INVALID
;
789 hr
= MF_E_UNEXPECTED
;
795 static HRESULT WINAPI
file_scheme_handler_CancelObjectCreation(IMFSchemeHandler
*iface
, IUnknown
*cancel_cookie
)
797 struct file_scheme_handler
*handler
= impl_from_IMFSchemeHandler(iface
);
798 struct file_scheme_handler_result
*found
= NULL
, *cur
;
800 TRACE("%p, %p.\n", iface
, cancel_cookie
);
802 EnterCriticalSection(&handler
->cs
);
804 LIST_FOR_EACH_ENTRY(cur
, &handler
->results
, struct file_scheme_handler_result
, entry
)
806 if (cancel_cookie
== (IUnknown
*)cur
->result
)
808 list_remove(&cur
->entry
);
814 LeaveCriticalSection(&handler
->cs
);
818 IMFAsyncResult_Release(found
->result
);
820 IUnknown_Release(found
->object
);
824 return found
? S_OK
: MF_E_UNEXPECTED
;
827 static const IMFSchemeHandlerVtbl file_scheme_handler_vtbl
=
829 file_scheme_handler_QueryInterface
,
830 file_scheme_handler_AddRef
,
831 file_scheme_handler_Release
,
832 file_scheme_handler_BeginCreateObject
,
833 file_scheme_handler_EndCreateObject
,
834 file_scheme_handler_CancelObjectCreation
,
837 static HRESULT WINAPI
file_scheme_handler_callback_QueryInterface(IMFAsyncCallback
*iface
, REFIID riid
, void **obj
)
839 if (IsEqualIID(riid
, &IID_IMFAsyncCallback
) ||
840 IsEqualIID(riid
, &IID_IUnknown
))
843 IMFAsyncCallback_AddRef(iface
);
847 WARN("Unsupported %s.\n", debugstr_guid(riid
));
849 return E_NOINTERFACE
;
852 static ULONG WINAPI
file_scheme_handler_callback_AddRef(IMFAsyncCallback
*iface
)
854 struct file_scheme_handler
*handler
= impl_from_IMFAsyncCallback(iface
);
855 return IMFSchemeHandler_AddRef(&handler
->IMFSchemeHandler_iface
);
858 static ULONG WINAPI
file_scheme_handler_callback_Release(IMFAsyncCallback
*iface
)
860 struct file_scheme_handler
*handler
= impl_from_IMFAsyncCallback(iface
);
861 return IMFSchemeHandler_Release(&handler
->IMFSchemeHandler_iface
);
864 static HRESULT WINAPI
file_scheme_handler_callback_GetParameters(IMFAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
869 static HRESULT
file_scheme_handler_get_resolver(struct file_scheme_handler
*handler
, IMFSourceResolver
**resolver
)
873 if (!handler
->resolver
)
875 IMFSourceResolver
*resolver
;
877 if (FAILED(hr
= MFCreateSourceResolver(&resolver
)))
880 if (InterlockedCompareExchangePointer((void **)&handler
->resolver
, resolver
, NULL
))
881 IMFSourceResolver_Release(resolver
);
884 *resolver
= handler
->resolver
;
885 IMFSourceResolver_AddRef(*resolver
);
890 static HRESULT WINAPI
file_scheme_handler_callback_Invoke(IMFAsyncCallback
*iface
, IMFAsyncResult
*result
)
892 static const WCHAR schemeW
[] = {'f','i','l','e',':','/','/'};
893 struct file_scheme_handler
*handler
= impl_from_IMFAsyncCallback(iface
);
894 struct file_scheme_handler_result
*handler_result
;
895 MF_OBJECT_TYPE obj_type
= MF_OBJECT_INVALID
;
896 IUnknown
*object
= NULL
, *context_object
;
897 struct create_object_context
*context
;
898 IMFSourceResolver
*resolver
;
899 IMFAsyncResult
*caller
;
900 IMFByteStream
*stream
;
904 caller
= (IMFAsyncResult
*)IMFAsyncResult_GetStateNoAddRef(result
);
906 if (FAILED(hr
= IMFAsyncResult_GetObject(result
, &context_object
)))
908 WARN("Expected context set for callee result.\n");
912 context
= impl_from_IUnknown(context_object
);
914 /* Strip from scheme, MFCreateFile() won't be expecting it. */
916 if (!wcsnicmp(context
->url
, schemeW
, ARRAY_SIZE(schemeW
)))
917 url
+= ARRAY_SIZE(schemeW
);
919 hr
= MFCreateFile(context
->flags
& MF_RESOLUTION_WRITE
? MF_ACCESSMODE_READWRITE
: MF_ACCESSMODE_READ
,
920 MF_OPENMODE_FAIL_IF_NOT_EXIST
, MF_FILEFLAGS_NONE
, url
, &stream
);
923 if (context
->flags
& MF_RESOLUTION_MEDIASOURCE
)
925 if (SUCCEEDED(hr
= file_scheme_handler_get_resolver(handler
, &resolver
)))
927 hr
= IMFSourceResolver_CreateObjectFromByteStream(resolver
, stream
, context
->url
, context
->flags
,
928 context
->props
, &obj_type
, &object
);
929 IMFSourceResolver_Release(resolver
);
930 IMFByteStream_Release(stream
);
935 object
= (IUnknown
*)stream
;
936 obj_type
= MF_OBJECT_BYTESTREAM
;
940 handler_result
= malloc(sizeof(*handler_result
));
943 handler_result
->result
= caller
;
944 IMFAsyncResult_AddRef(handler_result
->result
);
945 handler_result
->obj_type
= obj_type
;
946 handler_result
->object
= object
;
948 EnterCriticalSection(&handler
->cs
);
949 list_add_tail(&handler
->results
, &handler_result
->entry
);
950 LeaveCriticalSection(&handler
->cs
);
955 IUnknown_Release(object
);
959 IUnknown_Release(&context
->IUnknown_iface
);
961 IMFAsyncResult_SetStatus(caller
, hr
);
962 MFInvokeCallback(caller
);
967 static const IMFAsyncCallbackVtbl file_scheme_handler_callback_vtbl
=
969 file_scheme_handler_callback_QueryInterface
,
970 file_scheme_handler_callback_AddRef
,
971 file_scheme_handler_callback_Release
,
972 file_scheme_handler_callback_GetParameters
,
973 file_scheme_handler_callback_Invoke
,
976 static HRESULT
file_scheme_handler_construct(REFIID riid
, void **obj
)
978 struct file_scheme_handler
*handler
;
981 TRACE("%s, %p.\n", debugstr_guid(riid
), obj
);
983 if (!(handler
= calloc(1, sizeof(*handler
))))
984 return E_OUTOFMEMORY
;
986 handler
->IMFSchemeHandler_iface
.lpVtbl
= &file_scheme_handler_vtbl
;
987 handler
->IMFAsyncCallback_iface
.lpVtbl
= &file_scheme_handler_callback_vtbl
;
988 handler
->refcount
= 1;
989 list_init(&handler
->results
);
990 InitializeCriticalSection(&handler
->cs
);
992 hr
= IMFSchemeHandler_QueryInterface(&handler
->IMFSchemeHandler_iface
, riid
, obj
);
993 IMFSchemeHandler_Release(&handler
->IMFSchemeHandler_iface
);
998 static struct class_factory file_scheme_handler_factory
= { { &class_factory_vtbl
}, file_scheme_handler_construct
};
1000 static const struct class_object
1003 IClassFactory
*factory
;
1007 { &CLSID_FileSchemePlugin
, &file_scheme_handler_factory
.IClassFactory_iface
},
1010 /*******************************************************************************
1011 * DllGetClassObject (mf.@)
1013 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, void **obj
)
1017 TRACE("%s, %s, %p.\n", debugstr_guid(rclsid
), debugstr_guid(riid
), obj
);
1019 for (i
= 0; i
< ARRAY_SIZE(class_objects
); ++i
)
1021 if (IsEqualGUID(class_objects
[i
].clsid
, rclsid
))
1022 return IClassFactory_QueryInterface(class_objects
[i
].factory
, riid
, obj
);
1025 WARN("%s: class not found.\n", debugstr_guid(rclsid
));
1026 return CLASS_E_CLASSNOTAVAILABLE
;
1029 static HRESULT
prop_string_vector_append(PROPVARIANT
*vector
, unsigned int *capacity
, BOOL unique
, const WCHAR
*str
)
1036 for (i
= 0; i
< vector
->calpwstr
.cElems
; ++i
)
1038 if (!lstrcmpW(vector
->calpwstr
.pElems
[i
], str
))
1043 if (!*capacity
|| *capacity
- 1 < vector
->calpwstr
.cElems
)
1045 unsigned int new_count
;
1048 new_count
= *capacity
? *capacity
* 2 : 10;
1049 ptr
= CoTaskMemRealloc(vector
->calpwstr
.pElems
, new_count
* sizeof(*vector
->calpwstr
.pElems
));
1051 return E_OUTOFMEMORY
;
1052 vector
->calpwstr
.pElems
= ptr
;
1053 *capacity
= new_count
;
1056 len
= lstrlenW(str
);
1057 if (!(vector
->calpwstr
.pElems
[vector
->calpwstr
.cElems
] = ptrW
= CoTaskMemAlloc((len
+ 1) * sizeof(WCHAR
))))
1058 return E_OUTOFMEMORY
;
1060 lstrcpyW(ptrW
, str
);
1061 vector
->calpwstr
.cElems
++;
1066 static int __cdecl
qsort_string_compare(const void *a
, const void *b
)
1068 const WCHAR
*left
= *(const WCHAR
**)a
, *right
= *(const WCHAR
**)b
;
1069 return lstrcmpW(left
, right
);
1072 static HRESULT
mf_get_handler_strings(const WCHAR
*path
, WCHAR filter
, unsigned int maxlen
, PROPVARIANT
*dst
)
1074 static const HKEY hkey_roots
[2] = { HKEY_CURRENT_USER
, HKEY_LOCAL_MACHINE
};
1075 unsigned int capacity
= 0, count
;
1081 if (!(buffW
= calloc(maxlen
, sizeof(*buffW
))))
1082 return E_OUTOFMEMORY
;
1084 memset(dst
, 0, sizeof(*dst
));
1085 dst
->vt
= VT_VECTOR
| VT_LPWSTR
;
1087 for (i
= 0; i
< ARRAY_SIZE(hkey_roots
); ++i
)
1091 if (RegOpenKeyW(hkey_roots
[i
], path
, &hkey
))
1096 count
= dst
->calpwstr
.cElems
;
1097 while (!RegEnumKeyExW(hkey
, index
++, buffW
, &size
, NULL
, NULL
, NULL
, NULL
))
1099 if (filter
&& !wcschr(buffW
, filter
))
1102 if (FAILED(hr
= prop_string_vector_append(dst
, &capacity
, i
> 0, buffW
)))
1107 /* Sort last pass results. */
1108 qsort(&dst
->calpwstr
.pElems
[count
], dst
->calpwstr
.cElems
- count
, sizeof(*dst
->calpwstr
.pElems
),
1109 qsort_string_compare
);
1115 PropVariantClear(dst
);
1122 /***********************************************************************
1123 * MFGetSupportedMimeTypes (mf.@)
1125 HRESULT WINAPI
MFGetSupportedMimeTypes(PROPVARIANT
*dst
)
1127 unsigned int maxlen
;
1129 TRACE("%p.\n", dst
);
1134 /* According to RFC4288 it's 127/127 characters. */
1135 maxlen
= 127 /* type */ + 1 /* / */ + 127 /* subtype */ + 1;
1136 return mf_get_handler_strings(L
"Software\\Microsoft\\Windows Media Foundation\\ByteStreamHandlers", '/',
1140 /***********************************************************************
1141 * MFGetSupportedSchemes (mf.@)
1143 HRESULT WINAPI
MFGetSupportedSchemes(PROPVARIANT
*dst
)
1145 TRACE("%p.\n", dst
);
1150 return mf_get_handler_strings(L
"Software\\Microsoft\\Windows Media Foundation\\SchemeHandlers", 0, 64, dst
);
1153 /***********************************************************************
1154 * MFGetService (mf.@)
1156 HRESULT WINAPI
MFGetService(IUnknown
*object
, REFGUID service
, REFIID riid
, void **obj
)
1161 TRACE("(%p, %s, %s, %p)\n", object
, debugstr_guid(service
), debugstr_guid(riid
), obj
);
1166 if (FAILED(hr
= IUnknown_QueryInterface(object
, &IID_IMFGetService
, (void **)&gs
)))
1169 hr
= IMFGetService_GetService(gs
, service
, riid
, obj
);
1170 IMFGetService_Release(gs
);
1174 /***********************************************************************
1175 * MFShutdownObject (mf.@)
1177 HRESULT WINAPI
MFShutdownObject(IUnknown
*object
)
1179 IMFShutdown
*shutdown
;
1181 TRACE("%p.\n", object
);
1183 if (object
&& SUCCEEDED(IUnknown_QueryInterface(object
, &IID_IMFShutdown
, (void **)&shutdown
)))
1185 IMFShutdown_Shutdown(shutdown
);
1186 IMFShutdown_Release(shutdown
);
1192 /***********************************************************************
1193 * MFEnumDeviceSources (mf.@)
1195 HRESULT WINAPI
MFEnumDeviceSources(IMFAttributes
*attributes
, IMFActivate
***sources
, UINT32
*count
)
1197 FIXME("%p, %p, %p.\n", attributes
, sources
, count
);
1199 if (!attributes
|| !sources
|| !count
)
1200 return E_INVALIDARG
;
1207 struct simple_type_handler
1209 IMFMediaTypeHandler IMFMediaTypeHandler_iface
;
1211 IMFMediaType
*media_type
;
1212 CRITICAL_SECTION cs
;
1215 static struct simple_type_handler
*impl_from_IMFMediaTypeHandler(IMFMediaTypeHandler
*iface
)
1217 return CONTAINING_RECORD(iface
, struct simple_type_handler
, IMFMediaTypeHandler_iface
);
1220 static HRESULT WINAPI
simple_type_handler_QueryInterface(IMFMediaTypeHandler
*iface
, REFIID riid
, void **obj
)
1222 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
1224 if (IsEqualIID(riid
, &IID_IMFMediaTypeHandler
) ||
1225 IsEqualIID(riid
, &IID_IUnknown
))
1228 IMFMediaTypeHandler_AddRef(iface
);
1233 return E_NOINTERFACE
;
1236 static ULONG WINAPI
simple_type_handler_AddRef(IMFMediaTypeHandler
*iface
)
1238 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
1239 ULONG refcount
= InterlockedIncrement(&handler
->refcount
);
1241 TRACE("%p, refcount %lu.\n", iface
, refcount
);
1246 static ULONG WINAPI
simple_type_handler_Release(IMFMediaTypeHandler
*iface
)
1248 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
1249 ULONG refcount
= InterlockedDecrement(&handler
->refcount
);
1251 TRACE("%p, refcount %lu.\n", iface
, refcount
);
1255 if (handler
->media_type
)
1256 IMFMediaType_Release(handler
->media_type
);
1257 DeleteCriticalSection(&handler
->cs
);
1264 static HRESULT WINAPI
simple_type_handler_IsMediaTypeSupported(IMFMediaTypeHandler
*iface
, IMFMediaType
*in_type
,
1265 IMFMediaType
**out_type
)
1267 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
1271 TRACE("%p, %p, %p.\n", iface
, in_type
, out_type
);
1276 EnterCriticalSection(&handler
->cs
);
1277 if (!handler
->media_type
)
1278 hr
= MF_E_UNEXPECTED
;
1281 if (SUCCEEDED(hr
= IMFMediaType_IsEqual(handler
->media_type
, in_type
, &flags
)))
1282 hr
= (flags
& (MF_MEDIATYPE_EQUAL_MAJOR_TYPES
| MF_MEDIATYPE_EQUAL_FORMAT_TYPES
)) ==
1283 (MF_MEDIATYPE_EQUAL_MAJOR_TYPES
| MF_MEDIATYPE_EQUAL_FORMAT_TYPES
) ? S_OK
: E_FAIL
;
1285 LeaveCriticalSection(&handler
->cs
);
1290 static HRESULT WINAPI
simple_type_handler_GetMediaTypeCount(IMFMediaTypeHandler
*iface
, DWORD
*count
)
1292 TRACE("%p, %p.\n", iface
, count
);
1302 static HRESULT WINAPI
simple_type_handler_GetMediaTypeByIndex(IMFMediaTypeHandler
*iface
, DWORD index
,
1303 IMFMediaType
**type
)
1305 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
1307 TRACE("%p, %lu, %p.\n", iface
, index
, type
);
1310 return MF_E_NO_MORE_TYPES
;
1312 EnterCriticalSection(&handler
->cs
);
1313 *type
= handler
->media_type
;
1315 IMFMediaType_AddRef(*type
);
1316 LeaveCriticalSection(&handler
->cs
);
1321 static HRESULT WINAPI
simple_type_handler_SetCurrentMediaType(IMFMediaTypeHandler
*iface
, IMFMediaType
*media_type
)
1323 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
1325 TRACE("%p, %p.\n", iface
, media_type
);
1327 EnterCriticalSection(&handler
->cs
);
1328 if (handler
->media_type
)
1329 IMFMediaType_Release(handler
->media_type
);
1330 handler
->media_type
= media_type
;
1331 if (handler
->media_type
)
1332 IMFMediaType_AddRef(handler
->media_type
);
1333 LeaveCriticalSection(&handler
->cs
);
1338 static HRESULT WINAPI
simple_type_handler_GetCurrentMediaType(IMFMediaTypeHandler
*iface
, IMFMediaType
**media_type
)
1340 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
1342 TRACE("%p, %p.\n", iface
, media_type
);
1347 EnterCriticalSection(&handler
->cs
);
1348 *media_type
= handler
->media_type
;
1350 IMFMediaType_AddRef(*media_type
);
1351 LeaveCriticalSection(&handler
->cs
);
1356 static HRESULT WINAPI
simple_type_handler_GetMajorType(IMFMediaTypeHandler
*iface
, GUID
*type
)
1358 struct simple_type_handler
*handler
= impl_from_IMFMediaTypeHandler(iface
);
1361 TRACE("%p, %p.\n", iface
, type
);
1363 EnterCriticalSection(&handler
->cs
);
1364 if (handler
->media_type
)
1365 hr
= IMFMediaType_GetGUID(handler
->media_type
, &MF_MT_MAJOR_TYPE
, type
);
1367 hr
= MF_E_NOT_INITIALIZED
;
1368 LeaveCriticalSection(&handler
->cs
);
1373 static const IMFMediaTypeHandlerVtbl simple_type_handler_vtbl
=
1375 simple_type_handler_QueryInterface
,
1376 simple_type_handler_AddRef
,
1377 simple_type_handler_Release
,
1378 simple_type_handler_IsMediaTypeSupported
,
1379 simple_type_handler_GetMediaTypeCount
,
1380 simple_type_handler_GetMediaTypeByIndex
,
1381 simple_type_handler_SetCurrentMediaType
,
1382 simple_type_handler_GetCurrentMediaType
,
1383 simple_type_handler_GetMajorType
,
1386 HRESULT WINAPI
MFCreateSimpleTypeHandler(IMFMediaTypeHandler
**handler
)
1388 struct simple_type_handler
*object
;
1390 TRACE("%p.\n", handler
);
1392 if (!(object
= calloc(1, sizeof(*object
))))
1393 return E_OUTOFMEMORY
;
1395 object
->IMFMediaTypeHandler_iface
.lpVtbl
= &simple_type_handler_vtbl
;
1396 object
->refcount
= 1;
1397 InitializeCriticalSection(&object
->cs
);
1399 *handler
= &object
->IMFMediaTypeHandler_iface
;
1404 HRESULT WINAPI
MFRequireProtectedEnvironment(IMFPresentationDescriptor
*pd
)
1406 BOOL selected
, protected = FALSE
;
1407 unsigned int i
= 0, value
;
1408 IMFStreamDescriptor
*sd
;
1412 while (SUCCEEDED(IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd
, i
++, &selected
, &sd
)))
1415 protected = SUCCEEDED(IMFStreamDescriptor_GetUINT32(sd
, &MF_SD_PROTECTED
, &value
)) && value
;
1416 IMFStreamDescriptor_Release(sd
);
1417 if (protected) break;
1420 return protected ? S_OK
: S_FALSE
;