4 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(quartz
);
41 #include "quartz_private.h"
55 typedef struct QUARTZ_CLASSENTRY
58 QUARTZ_pCreateIUnknown pCreateIUnk
;
63 IClassFactory_fnQueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
);
64 static ULONG WINAPI
IClassFactory_fnAddRef(LPCLASSFACTORY iface
);
65 static ULONG WINAPI
IClassFactory_fnRelease(LPCLASSFACTORY iface
);
66 static HRESULT WINAPI
IClassFactory_fnCreateInstance(LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
);
67 static HRESULT WINAPI
IClassFactory_fnLockServer(LPCLASSFACTORY iface
,BOOL dolock
);
69 static ICOM_VTABLE(IClassFactory
) iclassfact
=
71 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
72 IClassFactory_fnQueryInterface
,
73 IClassFactory_fnAddRef
,
74 IClassFactory_fnRelease
,
75 IClassFactory_fnCreateInstance
,
76 IClassFactory_fnLockServer
82 ICOM_VFIELD(IClassFactory
);
84 /* IClassFactory fields */
85 const QUARTZ_CLASSENTRY
* pEntry
;
88 static const QUARTZ_CLASSENTRY QUARTZ_ClassList
[] =
90 { &CLSID_FilterGraph
, &QUARTZ_CreateFilterGraph
},
91 { &CLSID_SystemClock
, &QUARTZ_CreateSystemClock
},
92 { &CLSID_MemoryAllocator
, &QUARTZ_CreateMemoryAllocator
},
93 { &CLSID_SystemDeviceEnum
, &QUARTZ_CreateSystemDeviceEnum
},
94 { &CLSID_FilterMapper
, &QUARTZ_CreateFilterMapper
},
95 { &CLSID_FilterMapper2
, &QUARTZ_CreateFilterMapper2
},
96 { &CLSID_SeekingPassThru
, &QUARTZ_CreateSeekingPassThru
},
97 { &CLSID_AudioRender
, &QUARTZ_CreateAudioRenderer
},
98 { &CLSID_VideoRenderer
, &QUARTZ_CreateVideoRenderer
},
99 { &CLSID_quartzWaveParser
, &QUARTZ_CreateWaveParser
},
100 { &CLSID_AviSplitter
, &QUARTZ_CreateAVISplitter
},
101 { &CLSID_AsyncReader
, &QUARTZ_CreateAsyncReader
},
102 { &CLSID_URLReader
, &QUARTZ_CreateURLReader
},
103 { &CLSID_AVIDec
, &QUARTZ_CreateAVIDec
},
104 { &CLSID_Colour
, &QUARTZ_CreateColour
},
108 /* per-process variables */
109 static CRITICAL_SECTION csHeap
;
110 static DWORD dwClassObjRef
;
111 static HANDLE hDLLHeap
;
113 void* QUARTZ_AllocObj( DWORD dwSize
)
117 EnterCriticalSection( &csHeap
);
119 pv
= HeapAlloc( hDLLHeap
, 0, dwSize
);
122 LeaveCriticalSection( &csHeap
);
127 void QUARTZ_FreeObj( void* pobj
)
129 EnterCriticalSection( &csHeap
);
130 HeapFree( hDLLHeap
, 0, pobj
);
132 LeaveCriticalSection( &csHeap
);
135 void* QUARTZ_AllocMem( DWORD dwSize
)
137 return HeapAlloc( hDLLHeap
, 0, dwSize
);
140 void QUARTZ_FreeMem( void* pMem
)
142 HeapFree( hDLLHeap
, 0, pMem
);
145 void* QUARTZ_ReallocMem( void* pMem
, DWORD dwSize
)
148 return QUARTZ_AllocMem( dwSize
);
150 return HeapReAlloc( hDLLHeap
, 0, pMem
, dwSize
);
154 LPWSTR
QUARTZ_strncpyAtoW( LPWSTR lpwstr
, LPCSTR lpstr
, INT wbuflen
)
158 len
= MultiByteToWideChar( CP_ACP
, 0, lpstr
, -1, lpwstr
, wbuflen
);
165 /************************************************************************/
167 static HRESULT WINAPI
168 IClassFactory_fnQueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
)
170 ICOM_THIS(IClassFactoryImpl
,iface
);
172 TRACE("(%p)->(%p,%p)\n",This
,riid
,ppobj
);
173 if ( ( IsEqualGUID( &IID_IUnknown
, riid
) ) ||
174 ( IsEqualGUID( &IID_IClassFactory
, riid
) ) )
177 IClassFactory_AddRef(iface
);
181 return E_NOINTERFACE
;
184 static ULONG WINAPI
IClassFactory_fnAddRef(LPCLASSFACTORY iface
)
186 ICOM_THIS(IClassFactoryImpl
,iface
);
188 TRACE("(%p)->()\n",This
);
190 return InterlockedExchangeAdd(&(This
->ref
),1) + 1;
193 static ULONG WINAPI
IClassFactory_fnRelease(LPCLASSFACTORY iface
)
195 ICOM_THIS(IClassFactoryImpl
,iface
);
198 TRACE("(%p)->()\n",This
);
199 ref
= InterlockedExchangeAdd(&(This
->ref
),-1) - 1;
203 QUARTZ_FreeObj(This
);
207 static HRESULT WINAPI
IClassFactory_fnCreateInstance(LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
)
209 ICOM_THIS(IClassFactoryImpl
,iface
);
213 TRACE("(%p)->(%p,%s,%p)\n",This
,pOuter
,debugstr_guid(riid
),ppobj
);
217 if ( pOuter
!= NULL
&& !IsEqualGUID( riid
, &IID_IUnknown
) )
218 return CLASS_E_NOAGGREGATION
;
222 hr
= (*This
->pEntry
->pCreateIUnk
)(pOuter
,(void**)&punk
);
226 hr
= IUnknown_QueryInterface(punk
,riid
,ppobj
);
227 IUnknown_Release(punk
);
232 static HRESULT WINAPI
IClassFactory_fnLockServer(LPCLASSFACTORY iface
,BOOL dolock
)
234 ICOM_THIS(IClassFactoryImpl
,iface
);
237 TRACE("(%p)->(%d)\n",This
,dolock
);
239 hr
= IClassFactory_AddRef(iface
);
241 hr
= IClassFactory_Release(iface
);
248 static HRESULT
IClassFactory_Alloc( const CLSID
* pclsid
, void** ppobj
)
250 const QUARTZ_CLASSENTRY
* pEntry
;
251 IClassFactoryImpl
* pImpl
;
253 TRACE( "(%s,%p)\n", debugstr_guid(pclsid
), ppobj
);
255 pEntry
= QUARTZ_ClassList
;
256 while ( pEntry
->pclsid
!= NULL
)
258 if ( IsEqualGUID( pclsid
, pEntry
->pclsid
) )
263 return CLASS_E_CLASSNOTAVAILABLE
;
265 pImpl
= (IClassFactoryImpl
*)QUARTZ_AllocObj( sizeof(IClassFactoryImpl
) );
267 return E_OUTOFMEMORY
;
269 TRACE( "allocated successfully.\n" );
271 ICOM_VTBL(pImpl
) = &iclassfact
;
273 pImpl
->pEntry
= pEntry
;
275 *ppobj
= (void*)pImpl
;
280 /***********************************************************************
281 * QUARTZ_InitProcess (internal)
283 static BOOL
QUARTZ_InitProcess( void )
288 hDLLHeap
= (HANDLE
)NULL
;
289 InitializeCriticalSection( &csHeap
);
291 hDLLHeap
= HeapCreate( 0, 0x10000, 0 );
292 if ( hDLLHeap
== (HANDLE
)NULL
)
298 /***********************************************************************
299 * QUARTZ_UninitProcess (internal)
301 static void QUARTZ_UninitProcess( void )
305 if ( dwClassObjRef
!= 0 )
306 ERR( "you must release some objects allocated from quartz.\n" );
307 if ( hDLLHeap
!= (HANDLE
)NULL
)
309 HeapDestroy( hDLLHeap
);
310 hDLLHeap
= (HANDLE
)NULL
;
312 DeleteCriticalSection( &csHeap
);
315 /***********************************************************************
318 BOOL WINAPI
QUARTZ_DllMain(
323 TRACE("(%08x,%08lx,%p)\n",hInstDLL
,fdwReason
,lpvReserved
);
327 case DLL_PROCESS_ATTACH
:
328 if ( !QUARTZ_InitProcess() )
331 case DLL_PROCESS_DETACH
:
332 QUARTZ_UninitProcess();
334 case DLL_THREAD_ATTACH
:
336 case DLL_THREAD_DETACH
:
344 /***********************************************************************
345 * DllCanUnloadNow (QUARTZ.@)
351 HRESULT WINAPI
QUARTZ_DllCanUnloadNow(void)
355 EnterCriticalSection( &csHeap
);
356 hr
= ( dwClassObjRef
== 0 ) ? S_OK
: S_FALSE
;
357 LeaveCriticalSection( &csHeap
);
362 /***********************************************************************
363 * DllGetClassObject (QUARTZ.@)
365 HRESULT WINAPI
QUARTZ_DllGetClassObject(
366 const CLSID
* pclsid
,const IID
* piid
,void** ppv
)
369 if ( IsEqualCLSID( &IID_IUnknown
, piid
) ||
370 IsEqualCLSID( &IID_IClassFactory
, piid
) )
372 return IClassFactory_Alloc( pclsid
, ppv
);
375 return CLASS_E_CLASSNOTAVAILABLE
;
378 /***********************************************************************
379 * DllRegisterServer (QUARTZ.@)
382 HRESULT WINAPI
QUARTZ_DllRegisterServer( void )
384 FIXME( "(): stub\n" );
388 /***********************************************************************
389 * DllUnregisterServer (QUARTZ.@)
392 HRESULT WINAPI
QUARTZ_DllUnregisterServer( void )
394 FIXME( "(): stub\n" );
398 /**************************************************************************/
399 /**************************************************************************/
401 /* FIXME - all string should be defined in the resource of quartz. */
403 static LPCSTR
hresult_to_string( HRESULT hr
)
407 #define ENTRY(x) case x: return (const char*)#x
408 /* some known codes */
414 ENTRY(E_NOINTERFACE
);
415 ENTRY(E_OUTOFMEMORY
);
416 ENTRY(CLASS_E_CLASSNOTAVAILABLE
);
417 ENTRY(CLASS_E_NOAGGREGATION
);
420 ENTRY(VFW_S_NO_MORE_ITEMS
);
421 ENTRY(VFW_E_BAD_KEY
);
422 ENTRY(VFW_E_INVALIDMEDIATYPE
);
423 ENTRY(VFW_E_INVALIDSUBTYPE
);
424 ENTRY(VFW_E_NEED_OWNER
);
425 ENTRY(VFW_E_ENUM_OUT_OF_SYNC
);
426 ENTRY(VFW_E_ALREADY_CONNECTED
);
427 ENTRY(VFW_E_FILTER_ACTIVE
);
428 ENTRY(VFW_E_NO_TYPES
);
429 ENTRY(VFW_E_NO_ACCEPTABLE_TYPES
);
430 ENTRY(VFW_E_INVALID_DIRECTION
);
431 ENTRY(VFW_E_NOT_CONNECTED
);
432 ENTRY(VFW_E_NO_ALLOCATOR
);
433 ENTRY(VFW_E_RUNTIME_ERROR
);
434 ENTRY(VFW_E_BUFFER_NOTSET
);
435 ENTRY(VFW_E_BUFFER_OVERFLOW
);
436 ENTRY(VFW_E_BADALIGN
);
437 ENTRY(VFW_E_ALREADY_COMMITTED
);
438 ENTRY(VFW_E_BUFFERS_OUTSTANDING
);
439 ENTRY(VFW_E_NOT_COMMITTED
);
440 ENTRY(VFW_E_SIZENOTSET
);
441 ENTRY(VFW_E_NO_CLOCK
);
442 ENTRY(VFW_E_NO_SINK
);
443 ENTRY(VFW_E_NO_INTERFACE
);
444 ENTRY(VFW_E_NOT_FOUND
);
445 ENTRY(VFW_E_CANNOT_CONNECT
);
446 ENTRY(VFW_E_CANNOT_RENDER
);
447 ENTRY(VFW_E_CHANGING_FORMAT
);
448 ENTRY(VFW_E_NO_COLOR_KEY_SET
);
449 ENTRY(VFW_E_NOT_OVERLAY_CONNECTION
);
450 ENTRY(VFW_E_NOT_SAMPLE_CONNECTION
);
451 ENTRY(VFW_E_PALETTE_SET
);
452 ENTRY(VFW_E_COLOR_KEY_SET
);
453 ENTRY(VFW_E_NO_COLOR_KEY_FOUND
);
454 ENTRY(VFW_E_NO_PALETTE_AVAILABLE
);
455 ENTRY(VFW_E_NO_DISPLAY_PALETTE
);
456 ENTRY(VFW_E_TOO_MANY_COLORS
);
457 ENTRY(VFW_E_STATE_CHANGED
);
458 ENTRY(VFW_E_NOT_STOPPED
);
459 ENTRY(VFW_E_NOT_PAUSED
);
460 ENTRY(VFW_E_NOT_RUNNING
);
461 ENTRY(VFW_E_WRONG_STATE
);
462 ENTRY(VFW_E_START_TIME_AFTER_END
);
463 ENTRY(VFW_E_INVALID_RECT
);
464 ENTRY(VFW_E_TYPE_NOT_ACCEPTED
);
465 ENTRY(VFW_E_SAMPLE_REJECTED
);
466 ENTRY(VFW_E_SAMPLE_REJECTED_EOS
);
467 ENTRY(VFW_S_DUPLICATE_NAME
);
468 ENTRY(VFW_E_DUPLICATE_NAME
);
469 ENTRY(VFW_E_TIMEOUT
);
470 ENTRY(VFW_E_INVALID_FILE_FORMAT
);
471 ENTRY(VFW_E_ENUM_OUT_OF_RANGE
);
472 ENTRY(VFW_E_CIRCULAR_GRAPH
);
473 ENTRY(VFW_E_NOT_ALLOWED_TO_SAVE
);
474 ENTRY(VFW_E_TIME_ALREADY_PASSED
);
475 ENTRY(VFW_E_ALREADY_CANCELLED
);
476 ENTRY(VFW_E_CORRUPT_GRAPH_FILE
);
477 ENTRY(VFW_E_ADVISE_ALREADY_SET
);
478 ENTRY(VFW_S_STATE_INTERMEDIATE
);
479 ENTRY(VFW_E_NO_MODEX_AVAILABLE
);
480 ENTRY(VFW_E_NO_ADVISE_SET
);
481 ENTRY(VFW_E_NO_FULLSCREEN
);
482 ENTRY(VFW_E_IN_FULLSCREEN_MODE
);
483 ENTRY(VFW_E_UNKNOWN_FILE_TYPE
);
484 ENTRY(VFW_E_CANNOT_LOAD_SOURCE_FILTER
);
485 ENTRY(VFW_S_PARTIAL_RENDER
);
486 ENTRY(VFW_E_FILE_TOO_SHORT
);
487 ENTRY(VFW_E_INVALID_FILE_VERSION
);
488 ENTRY(VFW_S_SOME_DATA_IGNORED
);
489 ENTRY(VFW_S_CONNECTIONS_DEFERRED
);
490 ENTRY(VFW_E_INVALID_CLSID
);
491 ENTRY(VFW_E_INVALID_MEDIA_TYPE
);
492 ENTRY(VFW_E_SAMPLE_TIME_NOT_SET
);
493 ENTRY(VFW_S_RESOURCE_NOT_NEEDED
);
494 ENTRY(VFW_E_MEDIA_TIME_NOT_SET
);
495 ENTRY(VFW_E_NO_TIME_FORMAT_SET
);
496 ENTRY(VFW_E_MONO_AUDIO_HW
);
497 ENTRY(VFW_S_MEDIA_TYPE_IGNORED
);
498 ENTRY(VFW_E_NO_DECOMPRESSOR
);
499 ENTRY(VFW_E_NO_AUDIO_HARDWARE
);
500 ENTRY(VFW_S_VIDEO_NOT_RENDERED
);
501 ENTRY(VFW_S_AUDIO_NOT_RENDERED
);
504 ENTRY(VFW_E_PROCESSOR_NOT_SUITABLE
);
505 ENTRY(VFW_E_UNSUPPORTED_AUDIO
);
506 ENTRY(VFW_E_UNSUPPORTED_VIDEO
);
507 ENTRY(VFW_E_MPEG_NOT_CONSTRAINED
);
508 ENTRY(VFW_E_NOT_IN_GRAPH
);
509 ENTRY(VFW_S_ESTIMATED
);
510 ENTRY(VFW_E_NO_TIME_FORMAT
);
511 ENTRY(VFW_E_READ_ONLY
);
512 ENTRY(VFW_S_RESERVED
);
513 ENTRY(VFW_E_BUFFER_UNDERFLOW
);
514 ENTRY(VFW_E_UNSUPPORTED_STREAM
);
515 ENTRY(VFW_E_NO_TRANSPORT
);
516 ENTRY(VFW_S_STREAM_OFF
);
517 ENTRY(VFW_S_CANT_CUE
);
518 ENTRY(VFW_E_BAD_VIDEOCD
);
519 ENTRY(VFW_S_NO_STOP_TIME
);
520 ENTRY(VFW_E_OUT_OF_VIDEO_MEMORY
);
521 ENTRY(VFW_E_VP_NEGOTIATION_FAILED
);
522 ENTRY(VFW_E_DDRAW_CAPS_NOT_SUITABLE
);
523 ENTRY(VFW_E_NO_VP_HARDWARE
);
524 ENTRY(VFW_E_NO_CAPTURE_HARDWARE
);
525 ENTRY(VFW_E_DVD_OPERATION_INHIBITED
);
526 ENTRY(VFW_E_DVD_INVALIDDOMAIN
);
527 ENTRY(VFW_E_DVD_NO_BUTTON
);
528 ENTRY(VFW_E_DVD_GRAPHNOTREADY
);
529 ENTRY(VFW_E_DVD_RENDERFAIL
);
530 ENTRY(VFW_E_DVD_DECNOTENOUGH
);
531 ENTRY(VFW_E_DDRAW_VERSION_NOT_SUITABLE
);
532 ENTRY(VFW_E_COPYPROT_FAILED
);
533 ENTRY(VFW_S_NOPREVIEWPIN
);
534 ENTRY(VFW_E_TIME_EXPIRED
);
535 ENTRY(VFW_S_DVD_NON_ONE_SEQUENTIAL
);
536 ENTRY(VFW_E_DVD_WRONG_SPEED
);
537 ENTRY(VFW_E_DVD_MENU_DOES_NOT_EXIST
);
538 ENTRY(VFW_E_DVD_CMD_CANCELLED
);
539 ENTRY(VFW_E_DVD_STATE_WRONG_VERSION
);
540 ENTRY(VFW_E_DVD_STATE_CORRUPT
);
541 ENTRY(VFW_E_DVD_STATE_WRONG_DISC
);
542 ENTRY(VFW_E_DVD_INCOMPATIBLE_REGION
);
543 ENTRY(VFW_E_DVD_NO_ATTRIBUTES
);
544 ENTRY(VFW_E_DVD_NO_GOUP_PGC
);
545 ENTRY(VFW_E_DVD_LOW_PARENTAL_LEVEL
);
546 ENTRY(VFW_E_DVD_NOT_IN_KARAOKE_MODE
);
547 ENTRY(VFW_S_DVD_CHANNEL_CONTENTS_NOT_AVAILABLE
);
548 ENTRY(VFW_S_DVD_NOT_ACCURATE
);
549 ENTRY(VFW_E_FRAME_STEP_UNSUPPORTED
);
550 ENTRY(VFW_E_DVD_STREAM_DISABLED
);
551 ENTRY(VFW_E_DVD_TITLE_UNKNOWN
);
552 ENTRY(VFW_E_DVD_INVALID_DISC
);
553 ENTRY(VFW_E_DVD_NO_RESUME_INFORMATION
);
554 ENTRY(VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD
);
555 ENTRY(VFW_E_PIN_ALREADY_BLOCKED
);
556 ENTRY(VFW_E_CERTIFICATION_FAILURE
);
563 /***********************************************************************
564 * AMGetErrorTextA (quartz.@)
566 DWORD WINAPI
AMGetErrorTextA(HRESULT hr
, LPSTR pszbuf
, DWORD dwBufLen
)
571 lpszRes
= hresult_to_string( hr
);
572 if ( lpszRes
== NULL
)
574 len
= (DWORD
)(strlen(lpszRes
)+1);
575 if ( len
> dwBufLen
)
578 memcpy( pszbuf
, lpszRes
, len
);
582 /***********************************************************************
583 * AMGetErrorTextW (quartz.@)
585 DWORD WINAPI
AMGetErrorTextW(HRESULT hr
, LPWSTR pwszbuf
, DWORD dwBufLen
)
587 CHAR szBuf
[MAX_ERROR_TEXT_LEN
+1];
590 dwLen
= AMGetErrorTextA(hr
,szBuf
,MAX_ERROR_TEXT_LEN
);
595 QUARTZ_strncpyAtoW( pwszbuf
, szBuf
, dwBufLen
);
597 return lstrlenW( pwszbuf
);