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"
57 typedef struct QUARTZ_CLASSENTRY
60 QUARTZ_pCreateIUnknown pCreateIUnk
;
65 IClassFactory_fnQueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
);
66 static ULONG WINAPI
IClassFactory_fnAddRef(LPCLASSFACTORY iface
);
67 static ULONG WINAPI
IClassFactory_fnRelease(LPCLASSFACTORY iface
);
68 static HRESULT WINAPI
IClassFactory_fnCreateInstance(LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
);
69 static HRESULT WINAPI
IClassFactory_fnLockServer(LPCLASSFACTORY iface
,BOOL dolock
);
71 static ICOM_VTABLE(IClassFactory
) iclassfact
=
73 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
74 IClassFactory_fnQueryInterface
,
75 IClassFactory_fnAddRef
,
76 IClassFactory_fnRelease
,
77 IClassFactory_fnCreateInstance
,
78 IClassFactory_fnLockServer
84 ICOM_VFIELD(IClassFactory
);
86 /* IClassFactory fields */
87 const QUARTZ_CLASSENTRY
* pEntry
;
90 static const QUARTZ_CLASSENTRY QUARTZ_ClassList
[] =
92 { &CLSID_FilterGraph
, &QUARTZ_CreateFilterGraph
},
93 { &CLSID_FilterGraphNoThread
, &QUARTZ_CreateFilterGraph
}, /* FIXME? */
94 { &CLSID_SystemClock
, &QUARTZ_CreateSystemClock
},
95 { &CLSID_MemoryAllocator
, &QUARTZ_CreateMemoryAllocator
},
96 { &CLSID_SystemDeviceEnum
, &QUARTZ_CreateSystemDeviceEnum
},
97 { &CLSID_FilterMapper
, &QUARTZ_CreateFilterMapper
},
98 { &CLSID_FilterMapper2
, &QUARTZ_CreateFilterMapper2
},
99 { &CLSID_SeekingPassThru
, &QUARTZ_CreateSeekingPassThru
},
100 { &CLSID_CaptureGraphBuilder
, &QUARTZ_CreateCaptureGraph
},
102 { &CLSID_AudioRender
, &QUARTZ_CreateAudioRenderer
},
103 { &CLSID_VideoRenderer
, &QUARTZ_CreateVideoRenderer
},
104 { &CLSID_quartzWaveParser
, &QUARTZ_CreateWaveParser
},
105 { &CLSID_AviSplitter
, &QUARTZ_CreateAVISplitter
},
106 { &CLSID_MPEG1Splitter
, &QUARTZ_CreateMPEG1Splitter
},
107 { &CLSID_AsyncReader
, &QUARTZ_CreateAsyncReader
},
108 { &CLSID_URLReader
, &QUARTZ_CreateURLReader
},
109 { &CLSID_AVIDec
, &QUARTZ_CreateAVIDec
},
110 { &CLSID_Colour
, &QUARTZ_CreateColour
},
111 { &CLSID_ACMWrapper
, &QUARTZ_CreateACMWrapper
},
112 { &CLSID_FileWriter
, &QUARTZ_CreateFileWriter
},
116 /* per-process variables */
117 static CRITICAL_SECTION csHeap
;
118 static DWORD dwClassObjRef
;
119 static HANDLE hDLLHeap
;
121 void* QUARTZ_AllocObj( DWORD dwSize
)
125 EnterCriticalSection( &csHeap
);
127 pv
= HeapAlloc( hDLLHeap
, 0, dwSize
);
130 LeaveCriticalSection( &csHeap
);
135 void QUARTZ_FreeObj( void* pobj
)
137 EnterCriticalSection( &csHeap
);
138 HeapFree( hDLLHeap
, 0, pobj
);
140 LeaveCriticalSection( &csHeap
);
143 void* QUARTZ_AllocMem( DWORD dwSize
)
145 return HeapAlloc( hDLLHeap
, 0, dwSize
);
148 void QUARTZ_FreeMem( void* pMem
)
150 HeapFree( hDLLHeap
, 0, pMem
);
153 void* QUARTZ_ReallocMem( void* pMem
, DWORD dwSize
)
156 return QUARTZ_AllocMem( dwSize
);
158 return HeapReAlloc( hDLLHeap
, 0, pMem
, dwSize
);
162 LPWSTR
QUARTZ_strncpyAtoW( LPWSTR lpwstr
, LPCSTR lpstr
, INT wbuflen
)
166 len
= MultiByteToWideChar( CP_ACP
, 0, lpstr
, -1, lpwstr
, wbuflen
);
173 /************************************************************************/
175 static HRESULT WINAPI
176 IClassFactory_fnQueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
)
178 ICOM_THIS(IClassFactoryImpl
,iface
);
180 TRACE("(%p)->(%p,%p)\n",This
,riid
,ppobj
);
181 if ( ( IsEqualGUID( &IID_IUnknown
, riid
) ) ||
182 ( IsEqualGUID( &IID_IClassFactory
, riid
) ) )
185 IClassFactory_AddRef(iface
);
189 return E_NOINTERFACE
;
192 static ULONG WINAPI
IClassFactory_fnAddRef(LPCLASSFACTORY iface
)
194 ICOM_THIS(IClassFactoryImpl
,iface
);
196 TRACE("(%p)->()\n",This
);
198 return InterlockedExchangeAdd(&(This
->ref
),1) + 1;
201 static ULONG WINAPI
IClassFactory_fnRelease(LPCLASSFACTORY iface
)
203 ICOM_THIS(IClassFactoryImpl
,iface
);
206 TRACE("(%p)->()\n",This
);
207 ref
= InterlockedExchangeAdd(&(This
->ref
),-1) - 1;
211 QUARTZ_FreeObj(This
);
215 static HRESULT WINAPI
IClassFactory_fnCreateInstance(LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
)
217 ICOM_THIS(IClassFactoryImpl
,iface
);
221 TRACE("(%p)->(%p,%s,%p)\n",This
,pOuter
,debugstr_guid(riid
),ppobj
);
225 if ( pOuter
!= NULL
&& !IsEqualGUID( riid
, &IID_IUnknown
) )
226 return CLASS_E_NOAGGREGATION
;
230 hr
= (*This
->pEntry
->pCreateIUnk
)(pOuter
,(void**)&punk
);
234 hr
= IUnknown_QueryInterface(punk
,riid
,ppobj
);
235 IUnknown_Release(punk
);
240 static HRESULT WINAPI
IClassFactory_fnLockServer(LPCLASSFACTORY iface
,BOOL dolock
)
242 ICOM_THIS(IClassFactoryImpl
,iface
);
245 TRACE("(%p)->(%d)\n",This
,dolock
);
247 hr
= IClassFactory_AddRef(iface
);
249 hr
= IClassFactory_Release(iface
);
256 static HRESULT
IClassFactory_Alloc( const CLSID
* pclsid
, void** ppobj
)
258 const QUARTZ_CLASSENTRY
* pEntry
;
259 IClassFactoryImpl
* pImpl
;
261 TRACE( "(%s,%p)\n", debugstr_guid(pclsid
), ppobj
);
263 pEntry
= QUARTZ_ClassList
;
264 while ( pEntry
->pclsid
!= NULL
)
266 if ( IsEqualGUID( pclsid
, pEntry
->pclsid
) )
271 return CLASS_E_CLASSNOTAVAILABLE
;
273 pImpl
= (IClassFactoryImpl
*)QUARTZ_AllocObj( sizeof(IClassFactoryImpl
) );
275 return E_OUTOFMEMORY
;
277 TRACE( "allocated successfully.\n" );
279 ICOM_VTBL(pImpl
) = &iclassfact
;
281 pImpl
->pEntry
= pEntry
;
283 *ppobj
= (void*)pImpl
;
288 /***********************************************************************
289 * QUARTZ_InitProcess (internal)
291 static BOOL
QUARTZ_InitProcess( void )
296 hDLLHeap
= (HANDLE
)NULL
;
297 InitializeCriticalSection( &csHeap
);
299 hDLLHeap
= HeapCreate( 0, 0x10000, 0 );
300 if ( hDLLHeap
== (HANDLE
)NULL
)
306 /***********************************************************************
307 * QUARTZ_UninitProcess (internal)
309 static void QUARTZ_UninitProcess( void )
313 if ( dwClassObjRef
!= 0 )
314 ERR( "you must release some objects allocated from quartz.\n" );
315 if ( hDLLHeap
!= (HANDLE
)NULL
)
317 HeapDestroy( hDLLHeap
);
318 hDLLHeap
= (HANDLE
)NULL
;
320 DeleteCriticalSection( &csHeap
);
323 /***********************************************************************
326 BOOL WINAPI
QUARTZ_DllMain(
331 TRACE("(%08x,%08lx,%p)\n",hInstDLL
,fdwReason
,lpvReserved
);
335 case DLL_PROCESS_ATTACH
:
336 if ( !QUARTZ_InitProcess() )
339 case DLL_PROCESS_DETACH
:
340 QUARTZ_UninitProcess();
342 case DLL_THREAD_ATTACH
:
344 case DLL_THREAD_DETACH
:
352 /***********************************************************************
353 * DllCanUnloadNow (QUARTZ.@)
359 HRESULT WINAPI
QUARTZ_DllCanUnloadNow(void)
363 EnterCriticalSection( &csHeap
);
364 hr
= ( dwClassObjRef
== 0 ) ? S_OK
: S_FALSE
;
365 LeaveCriticalSection( &csHeap
);
370 /***********************************************************************
371 * DllGetClassObject (QUARTZ.@)
373 HRESULT WINAPI
QUARTZ_DllGetClassObject(
374 const CLSID
* pclsid
,const IID
* piid
,void** ppv
)
377 if ( IsEqualCLSID( &IID_IUnknown
, piid
) ||
378 IsEqualCLSID( &IID_IClassFactory
, piid
) )
380 return IClassFactory_Alloc( pclsid
, ppv
);
383 return CLASS_E_CLASSNOTAVAILABLE
;
386 /***********************************************************************
387 * DllRegisterServer (QUARTZ.@)
390 HRESULT WINAPI
QUARTZ_DllRegisterServer( void )
392 FIXME( "(): stub\n" );
396 /***********************************************************************
397 * DllUnregisterServer (QUARTZ.@)
400 HRESULT WINAPI
QUARTZ_DllUnregisterServer( void )
402 FIXME( "(): stub\n" );
406 /**************************************************************************/
407 /**************************************************************************/
409 /* FIXME - all string should be defined in the resource of quartz. */
411 static LPCSTR
hresult_to_string( HRESULT hr
)
415 #define ENTRY(x) case x: return (const char*)#x
416 /* some known codes */
422 ENTRY(E_NOINTERFACE
);
423 ENTRY(E_OUTOFMEMORY
);
424 ENTRY(CLASS_E_CLASSNOTAVAILABLE
);
425 ENTRY(CLASS_E_NOAGGREGATION
);
428 ENTRY(VFW_S_NO_MORE_ITEMS
);
429 ENTRY(VFW_E_BAD_KEY
);
430 ENTRY(VFW_E_INVALIDMEDIATYPE
);
431 ENTRY(VFW_E_INVALIDSUBTYPE
);
432 ENTRY(VFW_E_NEED_OWNER
);
433 ENTRY(VFW_E_ENUM_OUT_OF_SYNC
);
434 ENTRY(VFW_E_ALREADY_CONNECTED
);
435 ENTRY(VFW_E_FILTER_ACTIVE
);
436 ENTRY(VFW_E_NO_TYPES
);
437 ENTRY(VFW_E_NO_ACCEPTABLE_TYPES
);
438 ENTRY(VFW_E_INVALID_DIRECTION
);
439 ENTRY(VFW_E_NOT_CONNECTED
);
440 ENTRY(VFW_E_NO_ALLOCATOR
);
441 ENTRY(VFW_E_RUNTIME_ERROR
);
442 ENTRY(VFW_E_BUFFER_NOTSET
);
443 ENTRY(VFW_E_BUFFER_OVERFLOW
);
444 ENTRY(VFW_E_BADALIGN
);
445 ENTRY(VFW_E_ALREADY_COMMITTED
);
446 ENTRY(VFW_E_BUFFERS_OUTSTANDING
);
447 ENTRY(VFW_E_NOT_COMMITTED
);
448 ENTRY(VFW_E_SIZENOTSET
);
449 ENTRY(VFW_E_NO_CLOCK
);
450 ENTRY(VFW_E_NO_SINK
);
451 ENTRY(VFW_E_NO_INTERFACE
);
452 ENTRY(VFW_E_NOT_FOUND
);
453 ENTRY(VFW_E_CANNOT_CONNECT
);
454 ENTRY(VFW_E_CANNOT_RENDER
);
455 ENTRY(VFW_E_CHANGING_FORMAT
);
456 ENTRY(VFW_E_NO_COLOR_KEY_SET
);
457 ENTRY(VFW_E_NOT_OVERLAY_CONNECTION
);
458 ENTRY(VFW_E_NOT_SAMPLE_CONNECTION
);
459 ENTRY(VFW_E_PALETTE_SET
);
460 ENTRY(VFW_E_COLOR_KEY_SET
);
461 ENTRY(VFW_E_NO_COLOR_KEY_FOUND
);
462 ENTRY(VFW_E_NO_PALETTE_AVAILABLE
);
463 ENTRY(VFW_E_NO_DISPLAY_PALETTE
);
464 ENTRY(VFW_E_TOO_MANY_COLORS
);
465 ENTRY(VFW_E_STATE_CHANGED
);
466 ENTRY(VFW_E_NOT_STOPPED
);
467 ENTRY(VFW_E_NOT_PAUSED
);
468 ENTRY(VFW_E_NOT_RUNNING
);
469 ENTRY(VFW_E_WRONG_STATE
);
470 ENTRY(VFW_E_START_TIME_AFTER_END
);
471 ENTRY(VFW_E_INVALID_RECT
);
472 ENTRY(VFW_E_TYPE_NOT_ACCEPTED
);
473 ENTRY(VFW_E_SAMPLE_REJECTED
);
474 ENTRY(VFW_E_SAMPLE_REJECTED_EOS
);
475 ENTRY(VFW_S_DUPLICATE_NAME
);
476 ENTRY(VFW_E_DUPLICATE_NAME
);
477 ENTRY(VFW_E_TIMEOUT
);
478 ENTRY(VFW_E_INVALID_FILE_FORMAT
);
479 ENTRY(VFW_E_ENUM_OUT_OF_RANGE
);
480 ENTRY(VFW_E_CIRCULAR_GRAPH
);
481 ENTRY(VFW_E_NOT_ALLOWED_TO_SAVE
);
482 ENTRY(VFW_E_TIME_ALREADY_PASSED
);
483 ENTRY(VFW_E_ALREADY_CANCELLED
);
484 ENTRY(VFW_E_CORRUPT_GRAPH_FILE
);
485 ENTRY(VFW_E_ADVISE_ALREADY_SET
);
486 ENTRY(VFW_S_STATE_INTERMEDIATE
);
487 ENTRY(VFW_E_NO_MODEX_AVAILABLE
);
488 ENTRY(VFW_E_NO_ADVISE_SET
);
489 ENTRY(VFW_E_NO_FULLSCREEN
);
490 ENTRY(VFW_E_IN_FULLSCREEN_MODE
);
491 ENTRY(VFW_E_UNKNOWN_FILE_TYPE
);
492 ENTRY(VFW_E_CANNOT_LOAD_SOURCE_FILTER
);
493 ENTRY(VFW_S_PARTIAL_RENDER
);
494 ENTRY(VFW_E_FILE_TOO_SHORT
);
495 ENTRY(VFW_E_INVALID_FILE_VERSION
);
496 ENTRY(VFW_S_SOME_DATA_IGNORED
);
497 ENTRY(VFW_S_CONNECTIONS_DEFERRED
);
498 ENTRY(VFW_E_INVALID_CLSID
);
499 ENTRY(VFW_E_INVALID_MEDIA_TYPE
);
500 ENTRY(VFW_E_SAMPLE_TIME_NOT_SET
);
501 ENTRY(VFW_S_RESOURCE_NOT_NEEDED
);
502 ENTRY(VFW_E_MEDIA_TIME_NOT_SET
);
503 ENTRY(VFW_E_NO_TIME_FORMAT_SET
);
504 ENTRY(VFW_E_MONO_AUDIO_HW
);
505 ENTRY(VFW_S_MEDIA_TYPE_IGNORED
);
506 ENTRY(VFW_E_NO_DECOMPRESSOR
);
507 ENTRY(VFW_E_NO_AUDIO_HARDWARE
);
508 ENTRY(VFW_S_VIDEO_NOT_RENDERED
);
509 ENTRY(VFW_S_AUDIO_NOT_RENDERED
);
512 ENTRY(VFW_E_PROCESSOR_NOT_SUITABLE
);
513 ENTRY(VFW_E_UNSUPPORTED_AUDIO
);
514 ENTRY(VFW_E_UNSUPPORTED_VIDEO
);
515 ENTRY(VFW_E_MPEG_NOT_CONSTRAINED
);
516 ENTRY(VFW_E_NOT_IN_GRAPH
);
517 ENTRY(VFW_S_ESTIMATED
);
518 ENTRY(VFW_E_NO_TIME_FORMAT
);
519 ENTRY(VFW_E_READ_ONLY
);
520 ENTRY(VFW_S_RESERVED
);
521 ENTRY(VFW_E_BUFFER_UNDERFLOW
);
522 ENTRY(VFW_E_UNSUPPORTED_STREAM
);
523 ENTRY(VFW_E_NO_TRANSPORT
);
524 ENTRY(VFW_S_STREAM_OFF
);
525 ENTRY(VFW_S_CANT_CUE
);
526 ENTRY(VFW_E_BAD_VIDEOCD
);
527 ENTRY(VFW_S_NO_STOP_TIME
);
528 ENTRY(VFW_E_OUT_OF_VIDEO_MEMORY
);
529 ENTRY(VFW_E_VP_NEGOTIATION_FAILED
);
530 ENTRY(VFW_E_DDRAW_CAPS_NOT_SUITABLE
);
531 ENTRY(VFW_E_NO_VP_HARDWARE
);
532 ENTRY(VFW_E_NO_CAPTURE_HARDWARE
);
533 ENTRY(VFW_E_DVD_OPERATION_INHIBITED
);
534 ENTRY(VFW_E_DVD_INVALIDDOMAIN
);
535 ENTRY(VFW_E_DVD_NO_BUTTON
);
536 ENTRY(VFW_E_DVD_GRAPHNOTREADY
);
537 ENTRY(VFW_E_DVD_RENDERFAIL
);
538 ENTRY(VFW_E_DVD_DECNOTENOUGH
);
539 ENTRY(VFW_E_DDRAW_VERSION_NOT_SUITABLE
);
540 ENTRY(VFW_E_COPYPROT_FAILED
);
541 ENTRY(VFW_S_NOPREVIEWPIN
);
542 ENTRY(VFW_E_TIME_EXPIRED
);
543 ENTRY(VFW_S_DVD_NON_ONE_SEQUENTIAL
);
544 ENTRY(VFW_E_DVD_WRONG_SPEED
);
545 ENTRY(VFW_E_DVD_MENU_DOES_NOT_EXIST
);
546 ENTRY(VFW_E_DVD_CMD_CANCELLED
);
547 ENTRY(VFW_E_DVD_STATE_WRONG_VERSION
);
548 ENTRY(VFW_E_DVD_STATE_CORRUPT
);
549 ENTRY(VFW_E_DVD_STATE_WRONG_DISC
);
550 ENTRY(VFW_E_DVD_INCOMPATIBLE_REGION
);
551 ENTRY(VFW_E_DVD_NO_ATTRIBUTES
);
552 ENTRY(VFW_E_DVD_NO_GOUP_PGC
);
553 ENTRY(VFW_E_DVD_LOW_PARENTAL_LEVEL
);
554 ENTRY(VFW_E_DVD_NOT_IN_KARAOKE_MODE
);
555 ENTRY(VFW_S_DVD_CHANNEL_CONTENTS_NOT_AVAILABLE
);
556 ENTRY(VFW_S_DVD_NOT_ACCURATE
);
557 ENTRY(VFW_E_FRAME_STEP_UNSUPPORTED
);
558 ENTRY(VFW_E_DVD_STREAM_DISABLED
);
559 ENTRY(VFW_E_DVD_TITLE_UNKNOWN
);
560 ENTRY(VFW_E_DVD_INVALID_DISC
);
561 ENTRY(VFW_E_DVD_NO_RESUME_INFORMATION
);
562 ENTRY(VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD
);
563 ENTRY(VFW_E_PIN_ALREADY_BLOCKED
);
564 ENTRY(VFW_E_CERTIFICATION_FAILURE
);
571 /***********************************************************************
572 * AMGetErrorTextA (quartz.@)
574 DWORD WINAPI
AMGetErrorTextA(HRESULT hr
, LPSTR pszbuf
, DWORD dwBufLen
)
579 lpszRes
= hresult_to_string( hr
);
580 if ( lpszRes
== NULL
)
582 len
= (DWORD
)(strlen(lpszRes
)+1);
583 if ( len
> dwBufLen
)
586 memcpy( pszbuf
, lpszRes
, len
);
590 /***********************************************************************
591 * AMGetErrorTextW (quartz.@)
593 DWORD WINAPI
AMGetErrorTextW(HRESULT hr
, LPWSTR pwszbuf
, DWORD dwBufLen
)
595 CHAR szBuf
[MAX_ERROR_TEXT_LEN
+1];
598 dwLen
= AMGetErrorTextA(hr
,szBuf
,MAX_ERROR_TEXT_LEN
);
603 QUARTZ_strncpyAtoW( pwszbuf
, szBuf
, dwBufLen
);
605 return lstrlenW( pwszbuf
);