Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
97f646ed
Commit
97f646ed
authored
Jan 29, 2020
by
Nikolay Sivov
Committed by
Alexandre Julliard
Jan 29, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mfplat: Add support for local MFT registration.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
be45be2d
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
288 additions
and
33 deletions
+288
-33
main.c
dlls/mfplat/main.c
+182
-32
mfplat.spec
dlls/mfplat/mfplat.spec
+1
-1
mfplat.c
dlls/mfplat/tests/mfplat.c
+104
-0
mfapi.h
include/mfapi.h
+1
-0
No files found.
dlls/mfplat/main.c
View file @
97f646ed
...
...
@@ -43,6 +43,27 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
mfplat
);
static
HRESULT
heap_strdupW
(
const
WCHAR
*
str
,
WCHAR
**
dest
)
{
HRESULT
hr
=
S_OK
;
if
(
str
)
{
unsigned
int
size
;
size
=
(
lstrlenW
(
str
)
+
1
)
*
sizeof
(
WCHAR
);
*
dest
=
heap_alloc
(
size
);
if
(
*
dest
)
memcpy
(
*
dest
,
str
,
size
);
else
hr
=
E_OUTOFMEMORY
;
}
else
*
dest
=
NULL
;
return
hr
;
}
static
LONG
platform_lock
;
struct
local_handler
...
...
@@ -65,6 +86,24 @@ static CRITICAL_SECTION local_handlers_section = { NULL, -1, 0, 0, 0, 0 };
static
struct
list
local_scheme_handlers
=
LIST_INIT
(
local_scheme_handlers
);
static
struct
list
local_bytestream_handlers
=
LIST_INIT
(
local_bytestream_handlers
);
struct
local_mft
{
struct
list
entry
;
IClassFactory
*
factory
;
CLSID
clsid
;
GUID
category
;
WCHAR
*
name
;
DWORD
flags
;
MFT_REGISTER_TYPE_INFO
*
input_types
;
UINT32
input_types_count
;
MFT_REGISTER_TYPE_INFO
*
output_types
;
UINT32
output_types_count
;
};
static
CRITICAL_SECTION
local_mfts_section
=
{
NULL
,
-
1
,
0
,
0
,
0
,
0
};
static
struct
list
local_mfts
=
LIST_INIT
(
local_mfts
);
struct
transform_activate
{
struct
attributes
attributes
;
...
...
@@ -736,34 +775,166 @@ HRESULT WINAPI MFTRegister(CLSID clsid, GUID category, LPWSTR name, UINT32 flags
return
hr
;
}
HRESULT
WINAPI
MFTRegisterLocal
(
IClassFactory
*
factory
,
REFGUID
category
,
LPCWSTR
name
,
UINT32
flags
,
UINT32
cinput
,
const
MFT_REGISTER_TYPE_INFO
*
input_types
,
UINT32
coutput
,
const
MFT_REGISTER_TYPE_INFO
*
output_types
)
static
void
release_local_mft
(
struct
local_mft
*
mft
)
{
FIXME
(
"(%p, %s, %s, %x, %u, %p, %u, %p)
\n
"
,
factory
,
debugstr_guid
(
category
),
debugstr_w
(
name
),
flags
,
cinput
,
input_types
,
coutput
,
output_types
);
if
(
mft
->
factory
)
IClassFactory_Release
(
mft
->
factory
);
heap_free
(
mft
->
name
);
heap_free
(
mft
->
input_types
);
heap_free
(
mft
->
output_types
);
heap_free
(
mft
);
}
return
S_OK
;
static
HRESULT
mft_register_local
(
IClassFactory
*
factory
,
REFCLSID
clsid
,
REFGUID
category
,
LPCWSTR
name
,
UINT32
flags
,
UINT32
input_count
,
const
MFT_REGISTER_TYPE_INFO
*
input_types
,
UINT32
output_count
,
const
MFT_REGISTER_TYPE_INFO
*
output_types
)
{
struct
local_mft
*
mft
,
*
cur
,
*
unreg_mft
=
NULL
;
HRESULT
hr
;
if
(
!
factory
&&
!
clsid
)
{
WARN
(
"Can't register without factory or CLSID.
\n
"
);
return
E_FAIL
;
}
mft
=
heap_alloc_zero
(
sizeof
(
*
mft
));
if
(
!
mft
)
return
E_OUTOFMEMORY
;
mft
->
factory
=
factory
;
if
(
mft
->
factory
)
IClassFactory_AddRef
(
mft
->
factory
);
if
(
clsid
)
mft
->
clsid
=
*
clsid
;
mft
->
category
=
*
category
;
mft
->
flags
=
flags
;
if
(
FAILED
(
hr
=
heap_strdupW
(
name
,
&
mft
->
name
)))
goto
failed
;
if
(
input_count
&&
input_types
)
{
mft
->
input_types_count
=
input_count
;
if
(
!
(
mft
->
input_types
=
heap_calloc
(
mft
->
input_types_count
,
sizeof
(
*
input_types
))))
{
hr
=
E_OUTOFMEMORY
;
goto
failed
;
}
memcpy
(
mft
->
input_types
,
input_types
,
mft
->
input_types_count
*
sizeof
(
*
input_types
));
}
if
(
output_count
&&
output_types
)
{
mft
->
output_types_count
=
output_count
;
if
(
!
(
mft
->
output_types
=
heap_calloc
(
mft
->
output_types_count
,
sizeof
(
*
output_types
))))
{
hr
=
E_OUTOFMEMORY
;
goto
failed
;
}
memcpy
(
mft
->
output_types
,
output_types
,
mft
->
output_types_count
*
sizeof
(
*
output_types
));
}
EnterCriticalSection
(
&
local_mfts_section
);
LIST_FOR_EACH_ENTRY
(
cur
,
&
local_mfts
,
struct
local_mft
,
entry
)
{
if
(
cur
->
factory
==
factory
)
{
unreg_mft
=
cur
;
list_remove
(
&
cur
->
entry
);
break
;
}
}
list_add_tail
(
&
local_mfts
,
&
mft
->
entry
);
LeaveCriticalSection
(
&
local_mfts_section
);
if
(
unreg_mft
)
release_local_mft
(
unreg_mft
);
failed:
if
(
FAILED
(
hr
))
release_local_mft
(
mft
);
return
hr
;
}
HRESULT
WINAPI
MFTRegisterLocal
ByCLSID
(
REFCLSID
clsid
,
REFGUID
category
,
LPCWSTR
name
,
UINT32
flags
,
HRESULT
WINAPI
MFTRegisterLocal
(
IClassFactory
*
factory
,
REFGUID
category
,
LPCWSTR
name
,
UINT32
flags
,
UINT32
input_count
,
const
MFT_REGISTER_TYPE_INFO
*
input_types
,
UINT32
output_count
,
const
MFT_REGISTER_TYPE_INFO
*
output_types
)
{
TRACE
(
"%p, %s, %s, %#x, %u, %p, %u, %p.
\n
"
,
factory
,
debugstr_guid
(
category
),
debugstr_w
(
name
),
flags
,
input_count
,
input_types
,
output_count
,
output_types
);
return
mft_register_local
(
factory
,
NULL
,
category
,
name
,
flags
,
input_count
,
input_types
,
output_count
,
output_types
);
}
FIXME
(
"%s, %s, %s, %#x, %u, %p, %u, %p.
\n
"
,
debugstr_guid
(
clsid
),
debugstr_guid
(
category
),
debugstr_w
(
name
),
flags
,
HRESULT
WINAPI
MFTRegisterLocalByCLSID
(
REFCLSID
clsid
,
REFGUID
category
,
LPCWSTR
name
,
UINT32
flags
,
UINT32
input_count
,
const
MFT_REGISTER_TYPE_INFO
*
input_types
,
UINT32
output_count
,
const
MFT_REGISTER_TYPE_INFO
*
output_types
)
{
TRACE
(
"%s, %s, %s, %#x, %u, %p, %u, %p.
\n
"
,
debugstr_guid
(
clsid
),
debugstr_guid
(
category
),
debugstr_w
(
name
),
flags
,
input_count
,
input_types
,
output_count
,
output_types
);
return
E_NOTIMPL
;
return
mft_register_local
(
NULL
,
clsid
,
category
,
name
,
flags
,
input_count
,
input_types
,
output_count
,
output_types
)
;
}
HRESULT
WINAPI
MFTUnregisterLocal
(
IClassFactory
*
factory
)
static
HRESULT
mft_unregister_local
(
IClassFactory
*
factory
,
REFCLSID
clsid
)
{
FIXME
(
"(%p)
\n
"
,
factory
);
struct
local_mft
*
cur
,
*
cur2
;
BOOL
unregister_all
=
!
factory
&&
!
clsid
;
struct
list
unreg
;
list_init
(
&
unreg
);
EnterCriticalSection
(
&
local_mfts_section
);
LIST_FOR_EACH_ENTRY_SAFE
(
cur
,
cur2
,
&
local_mfts
,
struct
local_mft
,
entry
)
{
if
(
!
unregister_all
)
{
if
((
factory
&&
cur
->
factory
==
factory
)
||
IsEqualCLSID
(
&
cur
->
clsid
,
clsid
))
{
list_remove
(
&
cur
->
entry
);
list_add_tail
(
&
unreg
,
&
cur
->
entry
);
break
;
}
}
else
{
list_remove
(
&
cur
->
entry
);
list_add_tail
(
&
unreg
,
&
cur
->
entry
);
}
}
LeaveCriticalSection
(
&
local_mfts_section
);
if
(
!
unregister_all
&&
list_empty
(
&
unreg
))
return
HRESULT_FROM_WIN32
(
ERROR_NOT_FOUND
);
LIST_FOR_EACH_ENTRY_SAFE
(
cur
,
cur2
,
&
unreg
,
struct
local_mft
,
entry
)
{
list_remove
(
&
cur
->
entry
);
release_local_mft
(
cur
);
}
return
S_OK
;
}
HRESULT
WINAPI
MFTUnregisterLocalByCLSID
(
CLSID
clsid
)
{
TRACE
(
"%s.
\n
"
,
debugstr_guid
(
&
clsid
));
return
mft_unregister_local
(
NULL
,
&
clsid
);
}
HRESULT
WINAPI
MFTUnregisterLocal
(
IClassFactory
*
factory
)
{
TRACE
(
"%p.
\n
"
,
factory
);
return
mft_unregister_local
(
factory
,
NULL
);
}
MFTIME
WINAPI
MFGetSystemTime
(
void
)
{
MFTIME
mf
;
...
...
@@ -7683,27 +7854,6 @@ static const IMFAsyncCallbackVtbl async_create_file_callback_vtbl =
async_create_file_callback_Invoke
,
};
static
HRESULT
heap_strdupW
(
const
WCHAR
*
str
,
WCHAR
**
dest
)
{
HRESULT
hr
=
S_OK
;
if
(
str
)
{
unsigned
int
size
;
size
=
(
lstrlenW
(
str
)
+
1
)
*
sizeof
(
WCHAR
);
*
dest
=
heap_alloc
(
size
);
if
(
*
dest
)
memcpy
(
*
dest
,
str
,
size
);
else
hr
=
E_OUTOFMEMORY
;
}
else
*
dest
=
NULL
;
return
hr
;
}
/***********************************************************************
* MFBeginCreateFile (mfplat.@)
*/
...
...
dlls/mfplat/mfplat.spec
View file @
97f646ed
...
...
@@ -150,7 +150,7 @@
@ stdcall MFTRegisterLocalByCLSID(ptr ptr wstr long long ptr long ptr)
@ stdcall MFTUnregister(int128)
@ stdcall MFTUnregisterLocal(ptr)
@ st
ub MFTUnregisterLocalByCLSID
@ st
dcall MFTUnregisterLocalByCLSID(int128)
@ stub MFTraceError
@ stub MFTraceFuncEnter
@ stub MFUnblockThread
...
...
dlls/mfplat/tests/mfplat.c
View file @
97f646ed
...
...
@@ -78,6 +78,14 @@ static HRESULT (WINAPI *pMFRegisterLocalByteStreamHandler)(const WCHAR *extensio
IMFActivate
*
activate
);
static
HRESULT
(
WINAPI
*
pMFRegisterLocalSchemeHandler
)(
const
WCHAR
*
scheme
,
IMFActivate
*
activate
);
static
HRESULT
(
WINAPI
*
pMFCreateTransformActivate
)(
IMFActivate
**
activate
);
static
HRESULT
(
WINAPI
*
pMFTRegisterLocal
)(
IClassFactory
*
factory
,
REFGUID
category
,
LPCWSTR
name
,
UINT32
flags
,
UINT32
cinput
,
const
MFT_REGISTER_TYPE_INFO
*
input_types
,
UINT32
coutput
,
const
MFT_REGISTER_TYPE_INFO
*
output_types
);
static
HRESULT
(
WINAPI
*
pMFTRegisterLocalByCLSID
)(
REFCLSID
clsid
,
REFGUID
category
,
LPCWSTR
name
,
UINT32
flags
,
UINT32
input_count
,
const
MFT_REGISTER_TYPE_INFO
*
input_types
,
UINT32
output_count
,
const
MFT_REGISTER_TYPE_INFO
*
output_types
);
static
HRESULT
(
WINAPI
*
pMFTUnregisterLocal
)(
IClassFactory
*
factory
);
static
HRESULT
(
WINAPI
*
pMFTUnregisterLocalByCLSID
)(
CLSID
clsid
);
static
const
WCHAR
mp4file
[]
=
{
't'
,
'e'
,
's'
,
't'
,
'.'
,
'm'
,
'p'
,
'4'
,
0
};
static
const
WCHAR
fileschemeW
[]
=
{
'f'
,
'i'
,
'l'
,
'e'
,
':'
,
'/'
,
'/'
,
0
};
...
...
@@ -529,6 +537,10 @@ static void init_functions(void)
X
(
MFRegisterLocalSchemeHandler
);
X
(
MFRemovePeriodicCallback
);
X
(
MFCreateTransformActivate
);
X
(
MFTRegisterLocal
);
X
(
MFTRegisterLocalByCLSID
);
X
(
MFTUnregisterLocal
);
X
(
MFTUnregisterLocalByCLSID
);
#undef X
if
((
mod
=
LoadLibraryA
(
"d3d11.dll"
)))
...
...
@@ -3823,6 +3835,97 @@ static void test_MFCreateTransformActivate(void)
IMFActivate_Release
(
activate
);
}
static
HRESULT
WINAPI
test_mft_factory_QueryInterface
(
IClassFactory
*
iface
,
REFIID
riid
,
void
**
obj
)
{
if
(
IsEqualIID
(
riid
,
&
IID_IClassFactory
)
||
IsEqualIID
(
riid
,
&
IID_IUnknown
))
{
*
obj
=
iface
;
IClassFactory_AddRef
(
iface
);
return
S_OK
;
}
*
obj
=
NULL
;
return
E_NOINTERFACE
;
}
static
ULONG
WINAPI
test_mft_factory_AddRef
(
IClassFactory
*
iface
)
{
return
2
;
}
static
ULONG
WINAPI
test_mft_factory_Release
(
IClassFactory
*
iface
)
{
return
1
;
}
static
HRESULT
WINAPI
test_mft_factory_CreateInstance
(
IClassFactory
*
iface
,
IUnknown
*
outer
,
REFIID
riid
,
void
**
obj
)
{
ok
(
0
,
"Unexpected call.
\n
"
);
return
E_NOTIMPL
;
}
static
HRESULT
WINAPI
test_mft_factory_LockServer
(
IClassFactory
*
iface
,
BOOL
fLock
)
{
return
S_OK
;
}
static
const
IClassFactoryVtbl
test_mft_factory_vtbl
=
{
test_mft_factory_QueryInterface
,
test_mft_factory_AddRef
,
test_mft_factory_Release
,
test_mft_factory_CreateInstance
,
test_mft_factory_LockServer
,
};
static
void
test_MFTRegisterLocal
(
void
)
{
IClassFactory
test_factory
=
{
&
test_mft_factory_vtbl
};
MFT_REGISTER_TYPE_INFO
input_types
[
1
];
HRESULT
hr
;
if
(
!
pMFTRegisterLocal
)
{
win_skip
(
"MFTRegisterLocal() is not available.
\n
"
);
return
;
}
input_types
[
0
].
guidMajorType
=
MFMediaType_Audio
;
input_types
[
0
].
guidSubtype
=
MFAudioFormat_PCM
;
hr
=
pMFTRegisterLocal
(
&
test_factory
,
&
MFT_CATEGORY_OTHER
,
L"Local MFT name"
,
0
,
1
,
input_types
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"Failed to register MFT, hr %#x.
\n
"
,
hr
);
hr
=
pMFTRegisterLocal
(
&
test_factory
,
&
MFT_CATEGORY_OTHER
,
L"Local MFT name"
,
0
,
1
,
input_types
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"Failed to register MFT, hr %#x.
\n
"
,
hr
);
hr
=
pMFTUnregisterLocal
(
&
test_factory
);
ok
(
hr
==
S_OK
,
"Failed to unregister MFT, hr %#x.
\n
"
,
hr
);
hr
=
pMFTUnregisterLocal
(
&
test_factory
);
ok
(
hr
==
HRESULT_FROM_WIN32
(
ERROR_NOT_FOUND
),
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
pMFTUnregisterLocal
(
NULL
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
pMFTRegisterLocalByCLSID
(
&
MFT_CATEGORY_OTHER
,
&
MFT_CATEGORY_OTHER
,
L"Local MFT name 2"
,
0
,
1
,
input_types
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"Failed to register MFT, hr %#x.
\n
"
,
hr
);
hr
=
pMFTUnregisterLocal
(
NULL
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
pMFTUnregisterLocalByCLSID
(
MFT_CATEGORY_OTHER
);
ok
(
hr
==
HRESULT_FROM_WIN32
(
ERROR_NOT_FOUND
),
"Unexpected hr %#x.
\n
"
,
hr
);
hr
=
pMFTRegisterLocalByCLSID
(
&
MFT_CATEGORY_OTHER
,
&
MFT_CATEGORY_OTHER
,
L"Local MFT name 2"
,
0
,
1
,
input_types
,
0
,
NULL
);
ok
(
hr
==
S_OK
,
"Failed to register MFT, hr %#x.
\n
"
,
hr
);
hr
=
pMFTUnregisterLocalByCLSID
(
MFT_CATEGORY_OTHER
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#x.
\n
"
,
hr
);
}
START_TEST
(
mfplat
)
{
CoInitialize
(
NULL
);
...
...
@@ -3862,6 +3965,7 @@ START_TEST(mfplat)
test_create_property_store
();
test_dxgi_device_manager
();
test_MFCreateTransformActivate
();
test_MFTRegisterLocal
();
CoUninitialize
();
}
include/mfapi.h
View file @
97f646ed
...
...
@@ -451,6 +451,7 @@ HRESULT WINAPI MFUnlockPlatform(void);
HRESULT
WINAPI
MFUnlockWorkQueue
(
DWORD
queue
);
HRESULT
WINAPI
MFTUnregister
(
CLSID
clsid
);
HRESULT
WINAPI
MFTUnregisterLocal
(
IClassFactory
*
factory
);
HRESULT
WINAPI
MFTUnregisterLocalByCLSID
(
CLSID
clsid
);
HRESULT
WINAPI
MFGetPluginControl
(
IMFPluginControl
**
);
HRESULT
WINAPI
MFWrapMediaType
(
IMFMediaType
*
original
,
REFGUID
major
,
REFGUID
subtype
,
IMFMediaType
**
wrapped
);
HRESULT
WINAPI
MFUnwrapMediaType
(
IMFMediaType
*
wrapped
,
IMFMediaType
**
original
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment