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_SystemClock
, &QUARTZ_CreateSystemClock
},
94 { &CLSID_MemoryAllocator
, &QUARTZ_CreateMemoryAllocator
},
95 { &CLSID_SystemDeviceEnum
, &QUARTZ_CreateSystemDeviceEnum
},
96 { &CLSID_FilterMapper
, &QUARTZ_CreateFilterMapper
},
97 { &CLSID_FilterMapper2
, &QUARTZ_CreateFilterMapper2
},
98 { &CLSID_SeekingPassThru
, &QUARTZ_CreateSeekingPassThru
},
99 { &CLSID_CaptureGraphBuilder
, &QUARTZ_CreateCaptureGraph
},
100 { &CLSID_CaptureGraphBuilder2
, &QUARTZ_CreateCaptureGraph
},
102 { &CLSID_AudioRender
, &QUARTZ_CreateAudioRenderer
},
103 { &CLSID_VideoRenderer
, &QUARTZ_CreateVideoRenderer
},
104 { &CLSID_quartzWaveParser
, &QUARTZ_CreateWaveParser
},
105 { &CLSID_AviSplitter
, &QUARTZ_CreateAVISplitter
},
106 { &CLSID_AsyncReader
, &QUARTZ_CreateAsyncReader
},
107 { &CLSID_URLReader
, &QUARTZ_CreateURLReader
},
108 { &CLSID_AVIDec
, &QUARTZ_CreateAVIDec
},
109 { &CLSID_Colour
, &QUARTZ_CreateColour
},
110 { &CLSID_FileWriter
, &QUARTZ_CreateFileWriter
},
114 /* per-process variables */
115 static CRITICAL_SECTION csHeap
;
116 static DWORD dwClassObjRef
;
117 static HANDLE hDLLHeap
;
119 void* QUARTZ_AllocObj( DWORD dwSize
)
123 EnterCriticalSection( &csHeap
);
125 pv
= HeapAlloc( hDLLHeap
, 0, dwSize
);
128 LeaveCriticalSection( &csHeap
);
133 void QUARTZ_FreeObj( void* pobj
)
135 EnterCriticalSection( &csHeap
);
136 HeapFree( hDLLHeap
, 0, pobj
);
138 LeaveCriticalSection( &csHeap
);
141 void* QUARTZ_AllocMem( DWORD dwSize
)
143 return HeapAlloc( hDLLHeap
, 0, dwSize
);
146 void QUARTZ_FreeMem( void* pMem
)
148 HeapFree( hDLLHeap
, 0, pMem
);
151 void* QUARTZ_ReallocMem( void* pMem
, DWORD dwSize
)
154 return QUARTZ_AllocMem( dwSize
);
156 return HeapReAlloc( hDLLHeap
, 0, pMem
, dwSize
);
160 LPWSTR
QUARTZ_strncpyAtoW( LPWSTR lpwstr
, LPCSTR lpstr
, INT wbuflen
)
164 len
= MultiByteToWideChar( CP_ACP
, 0, lpstr
, -1, lpwstr
, wbuflen
);
171 /************************************************************************/
173 static HRESULT WINAPI
174 IClassFactory_fnQueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
)
176 ICOM_THIS(IClassFactoryImpl
,iface
);
178 TRACE("(%p)->(%p,%p)\n",This
,riid
,ppobj
);
179 if ( ( IsEqualGUID( &IID_IUnknown
, riid
) ) ||
180 ( IsEqualGUID( &IID_IClassFactory
, riid
) ) )
183 IClassFactory_AddRef(iface
);
187 return E_NOINTERFACE
;
190 static ULONG WINAPI
IClassFactory_fnAddRef(LPCLASSFACTORY iface
)
192 ICOM_THIS(IClassFactoryImpl
,iface
);
194 TRACE("(%p)->()\n",This
);
196 return InterlockedExchangeAdd(&(This
->ref
),1) + 1;
199 static ULONG WINAPI
IClassFactory_fnRelease(LPCLASSFACTORY iface
)
201 ICOM_THIS(IClassFactoryImpl
,iface
);
204 TRACE("(%p)->()\n",This
);
205 ref
= InterlockedExchangeAdd(&(This
->ref
),-1) - 1;
209 QUARTZ_FreeObj(This
);
213 static HRESULT WINAPI
IClassFactory_fnCreateInstance(LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
)
215 ICOM_THIS(IClassFactoryImpl
,iface
);
219 TRACE("(%p)->(%p,%s,%p)\n",This
,pOuter
,debugstr_guid(riid
),ppobj
);
223 if ( pOuter
!= NULL
&& !IsEqualGUID( riid
, &IID_IUnknown
) )
224 return CLASS_E_NOAGGREGATION
;
228 hr
= (*This
->pEntry
->pCreateIUnk
)(pOuter
,(void**)&punk
);
232 hr
= IUnknown_QueryInterface(punk
,riid
,ppobj
);
233 IUnknown_Release(punk
);
238 static HRESULT WINAPI
IClassFactory_fnLockServer(LPCLASSFACTORY iface
,BOOL dolock
)
240 ICOM_THIS(IClassFactoryImpl
,iface
);
243 TRACE("(%p)->(%d)\n",This
,dolock
);
245 hr
= IClassFactory_AddRef(iface
);
247 hr
= IClassFactory_Release(iface
);
254 static HRESULT
IClassFactory_Alloc( const CLSID
* pclsid
, void** ppobj
)
256 const QUARTZ_CLASSENTRY
* pEntry
;
257 IClassFactoryImpl
* pImpl
;
259 TRACE( "(%s,%p)\n", debugstr_guid(pclsid
), ppobj
);
261 pEntry
= QUARTZ_ClassList
;
262 while ( pEntry
->pclsid
!= NULL
)
264 if ( IsEqualGUID( pclsid
, pEntry
->pclsid
) )
269 return CLASS_E_CLASSNOTAVAILABLE
;
271 pImpl
= (IClassFactoryImpl
*)QUARTZ_AllocObj( sizeof(IClassFactoryImpl
) );
273 return E_OUTOFMEMORY
;
275 TRACE( "allocated successfully.\n" );
277 ICOM_VTBL(pImpl
) = &iclassfact
;
279 pImpl
->pEntry
= pEntry
;
281 *ppobj
= (void*)pImpl
;
286 /***********************************************************************
287 * QUARTZ_InitProcess (internal)
289 static BOOL
QUARTZ_InitProcess( void )
294 hDLLHeap
= (HANDLE
)NULL
;
295 InitializeCriticalSection( &csHeap
);
297 hDLLHeap
= HeapCreate( 0, 0x10000, 0 );
298 if ( hDLLHeap
== (HANDLE
)NULL
)
304 /***********************************************************************
305 * QUARTZ_UninitProcess (internal)
307 static void QUARTZ_UninitProcess( void )
311 if ( dwClassObjRef
!= 0 )
312 ERR( "you must release some objects allocated from quartz.\n" );
313 if ( hDLLHeap
!= (HANDLE
)NULL
)
315 HeapDestroy( hDLLHeap
);
316 hDLLHeap
= (HANDLE
)NULL
;
318 DeleteCriticalSection( &csHeap
);
321 /***********************************************************************
324 BOOL WINAPI
QUARTZ_DllMain(
329 TRACE("(%08x,%08lx,%p)\n",hInstDLL
,fdwReason
,lpvReserved
);
333 case DLL_PROCESS_ATTACH
:
334 if ( !QUARTZ_InitProcess() )
337 case DLL_PROCESS_DETACH
:
338 QUARTZ_UninitProcess();
340 case DLL_THREAD_ATTACH
:
342 case DLL_THREAD_DETACH
:
350 /***********************************************************************
351 * DllCanUnloadNow (QUARTZ.@)
357 HRESULT WINAPI
QUARTZ_DllCanUnloadNow(void)
361 EnterCriticalSection( &csHeap
);
362 hr
= ( dwClassObjRef
== 0 ) ? S_OK
: S_FALSE
;
363 LeaveCriticalSection( &csHeap
);
368 /***********************************************************************
369 * DllGetClassObject (QUARTZ.@)
371 HRESULT WINAPI
QUARTZ_DllGetClassObject(
372 const CLSID
* pclsid
,const IID
* piid
,void** ppv
)
375 if ( IsEqualCLSID( &IID_IUnknown
, piid
) ||
376 IsEqualCLSID( &IID_IClassFactory
, piid
) )
378 return IClassFactory_Alloc( pclsid
, ppv
);
381 return CLASS_E_CLASSNOTAVAILABLE
;
384 /***********************************************************************
385 * DllRegisterServer (QUARTZ.@)
388 HRESULT WINAPI
QUARTZ_DllRegisterServer( void )
390 FIXME( "(): stub\n" );
394 /***********************************************************************
395 * DllUnregisterServer (QUARTZ.@)
398 HRESULT WINAPI
QUARTZ_DllUnregisterServer( void )
400 FIXME( "(): stub\n" );
404 /**************************************************************************/
405 /**************************************************************************/
407 /* FIXME - all string should be defined in the resource of quartz. */
409 static LPCSTR
hresult_to_string( HRESULT hr
)
413 #define ENTRY(x) case x: return (const char*)#x
414 /* some known codes */
420 ENTRY(E_NOINTERFACE
);
421 ENTRY(E_OUTOFMEMORY
);
422 ENTRY(CLASS_E_CLASSNOTAVAILABLE
);
423 ENTRY(CLASS_E_NOAGGREGATION
);
426 ENTRY(VFW_S_NO_MORE_ITEMS
);
427 ENTRY(VFW_E_BAD_KEY
);
428 ENTRY(VFW_E_INVALIDMEDIATYPE
);
429 ENTRY(VFW_E_INVALIDSUBTYPE
);
430 ENTRY(VFW_E_NEED_OWNER
);
431 ENTRY(VFW_E_ENUM_OUT_OF_SYNC
);
432 ENTRY(VFW_E_ALREADY_CONNECTED
);
433 ENTRY(VFW_E_FILTER_ACTIVE
);
434 ENTRY(VFW_E_NO_TYPES
);
435 ENTRY(VFW_E_NO_ACCEPTABLE_TYPES
);
436 ENTRY(VFW_E_INVALID_DIRECTION
);
437 ENTRY(VFW_E_NOT_CONNECTED
);
438 ENTRY(VFW_E_NO_ALLOCATOR
);
439 ENTRY(VFW_E_RUNTIME_ERROR
);
440 ENTRY(VFW_E_BUFFER_NOTSET
);
441 ENTRY(VFW_E_BUFFER_OVERFLOW
);
442 ENTRY(VFW_E_BADALIGN
);
443 ENTRY(VFW_E_ALREADY_COMMITTED
);
444 ENTRY(VFW_E_BUFFERS_OUTSTANDING
);
445 ENTRY(VFW_E_NOT_COMMITTED
);
446 ENTRY(VFW_E_SIZENOTSET
);
447 ENTRY(VFW_E_NO_CLOCK
);
448 ENTRY(VFW_E_NO_SINK
);
449 ENTRY(VFW_E_NO_INTERFACE
);
450 ENTRY(VFW_E_NOT_FOUND
);
451 ENTRY(VFW_E_CANNOT_CONNECT
);
452 ENTRY(VFW_E_CANNOT_RENDER
);
453 ENTRY(VFW_E_CHANGING_FORMAT
);
454 ENTRY(VFW_E_NO_COLOR_KEY_SET
);
455 ENTRY(VFW_E_NOT_OVERLAY_CONNECTION
);
456 ENTRY(VFW_E_NOT_SAMPLE_CONNECTION
);
457 ENTRY(VFW_E_PALETTE_SET
);
458 ENTRY(VFW_E_COLOR_KEY_SET
);
459 ENTRY(VFW_E_NO_COLOR_KEY_FOUND
);
460 ENTRY(VFW_E_NO_PALETTE_AVAILABLE
);
461 ENTRY(VFW_E_NO_DISPLAY_PALETTE
);
462 ENTRY(VFW_E_TOO_MANY_COLORS
);
463 ENTRY(VFW_E_STATE_CHANGED
);
464 ENTRY(VFW_E_NOT_STOPPED
);
465 ENTRY(VFW_E_NOT_PAUSED
);
466 ENTRY(VFW_E_NOT_RUNNING
);
467 ENTRY(VFW_E_WRONG_STATE
);
468 ENTRY(VFW_E_START_TIME_AFTER_END
);
469 ENTRY(VFW_E_INVALID_RECT
);
470 ENTRY(VFW_E_TYPE_NOT_ACCEPTED
);
471 ENTRY(VFW_E_SAMPLE_REJECTED
);
472 ENTRY(VFW_E_SAMPLE_REJECTED_EOS
);
473 ENTRY(VFW_S_DUPLICATE_NAME
);
474 ENTRY(VFW_E_DUPLICATE_NAME
);
475 ENTRY(VFW_E_TIMEOUT
);
476 ENTRY(VFW_E_INVALID_FILE_FORMAT
);
477 ENTRY(VFW_E_ENUM_OUT_OF_RANGE
);
478 ENTRY(VFW_E_CIRCULAR_GRAPH
);
479 ENTRY(VFW_E_NOT_ALLOWED_TO_SAVE
);
480 ENTRY(VFW_E_TIME_ALREADY_PASSED
);
481 ENTRY(VFW_E_ALREADY_CANCELLED
);
482 ENTRY(VFW_E_CORRUPT_GRAPH_FILE
);
483 ENTRY(VFW_E_ADVISE_ALREADY_SET
);
484 ENTRY(VFW_S_STATE_INTERMEDIATE
);
485 ENTRY(VFW_E_NO_MODEX_AVAILABLE
);
486 ENTRY(VFW_E_NO_ADVISE_SET
);
487 ENTRY(VFW_E_NO_FULLSCREEN
);
488 ENTRY(VFW_E_IN_FULLSCREEN_MODE
);
489 ENTRY(VFW_E_UNKNOWN_FILE_TYPE
);
490 ENTRY(VFW_E_CANNOT_LOAD_SOURCE_FILTER
);
491 ENTRY(VFW_S_PARTIAL_RENDER
);
492 ENTRY(VFW_E_FILE_TOO_SHORT
);
493 ENTRY(VFW_E_INVALID_FILE_VERSION
);
494 ENTRY(VFW_S_SOME_DATA_IGNORED
);
495 ENTRY(VFW_S_CONNECTIONS_DEFERRED
);
496 ENTRY(VFW_E_INVALID_CLSID
);
497 ENTRY(VFW_E_INVALID_MEDIA_TYPE
);
498 ENTRY(VFW_E_SAMPLE_TIME_NOT_SET
);
499 ENTRY(VFW_S_RESOURCE_NOT_NEEDED
);
500 ENTRY(VFW_E_MEDIA_TIME_NOT_SET
);
501 ENTRY(VFW_E_NO_TIME_FORMAT_SET
);
502 ENTRY(VFW_E_MONO_AUDIO_HW
);
503 ENTRY(VFW_S_MEDIA_TYPE_IGNORED
);
504 ENTRY(VFW_E_NO_DECOMPRESSOR
);
505 ENTRY(VFW_E_NO_AUDIO_HARDWARE
);
506 ENTRY(VFW_S_VIDEO_NOT_RENDERED
);
507 ENTRY(VFW_S_AUDIO_NOT_RENDERED
);
510 ENTRY(VFW_E_PROCESSOR_NOT_SUITABLE
);
511 ENTRY(VFW_E_UNSUPPORTED_AUDIO
);
512 ENTRY(VFW_E_UNSUPPORTED_VIDEO
);
513 ENTRY(VFW_E_MPEG_NOT_CONSTRAINED
);
514 ENTRY(VFW_E_NOT_IN_GRAPH
);
515 ENTRY(VFW_S_ESTIMATED
);
516 ENTRY(VFW_E_NO_TIME_FORMAT
);
517 ENTRY(VFW_E_READ_ONLY
);
518 ENTRY(VFW_S_RESERVED
);
519 ENTRY(VFW_E_BUFFER_UNDERFLOW
);
520 ENTRY(VFW_E_UNSUPPORTED_STREAM
);
521 ENTRY(VFW_E_NO_TRANSPORT
);
522 ENTRY(VFW_S_STREAM_OFF
);
523 ENTRY(VFW_S_CANT_CUE
);
524 ENTRY(VFW_E_BAD_VIDEOCD
);
525 ENTRY(VFW_S_NO_STOP_TIME
);
526 ENTRY(VFW_E_OUT_OF_VIDEO_MEMORY
);
527 ENTRY(VFW_E_VP_NEGOTIATION_FAILED
);
528 ENTRY(VFW_E_DDRAW_CAPS_NOT_SUITABLE
);
529 ENTRY(VFW_E_NO_VP_HARDWARE
);
530 ENTRY(VFW_E_NO_CAPTURE_HARDWARE
);
531 ENTRY(VFW_E_DVD_OPERATION_INHIBITED
);
532 ENTRY(VFW_E_DVD_INVALIDDOMAIN
);
533 ENTRY(VFW_E_DVD_NO_BUTTON
);
534 ENTRY(VFW_E_DVD_GRAPHNOTREADY
);
535 ENTRY(VFW_E_DVD_RENDERFAIL
);
536 ENTRY(VFW_E_DVD_DECNOTENOUGH
);
537 ENTRY(VFW_E_DDRAW_VERSION_NOT_SUITABLE
);
538 ENTRY(VFW_E_COPYPROT_FAILED
);
539 ENTRY(VFW_S_NOPREVIEWPIN
);
540 ENTRY(VFW_E_TIME_EXPIRED
);
541 ENTRY(VFW_S_DVD_NON_ONE_SEQUENTIAL
);
542 ENTRY(VFW_E_DVD_WRONG_SPEED
);
543 ENTRY(VFW_E_DVD_MENU_DOES_NOT_EXIST
);
544 ENTRY(VFW_E_DVD_CMD_CANCELLED
);
545 ENTRY(VFW_E_DVD_STATE_WRONG_VERSION
);
546 ENTRY(VFW_E_DVD_STATE_CORRUPT
);
547 ENTRY(VFW_E_DVD_STATE_WRONG_DISC
);
548 ENTRY(VFW_E_DVD_INCOMPATIBLE_REGION
);
549 ENTRY(VFW_E_DVD_NO_ATTRIBUTES
);
550 ENTRY(VFW_E_DVD_NO_GOUP_PGC
);
551 ENTRY(VFW_E_DVD_LOW_PARENTAL_LEVEL
);
552 ENTRY(VFW_E_DVD_NOT_IN_KARAOKE_MODE
);
553 ENTRY(VFW_S_DVD_CHANNEL_CONTENTS_NOT_AVAILABLE
);
554 ENTRY(VFW_S_DVD_NOT_ACCURATE
);
555 ENTRY(VFW_E_FRAME_STEP_UNSUPPORTED
);
556 ENTRY(VFW_E_DVD_STREAM_DISABLED
);
557 ENTRY(VFW_E_DVD_TITLE_UNKNOWN
);
558 ENTRY(VFW_E_DVD_INVALID_DISC
);
559 ENTRY(VFW_E_DVD_NO_RESUME_INFORMATION
);
560 ENTRY(VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD
);
561 ENTRY(VFW_E_PIN_ALREADY_BLOCKED
);
562 ENTRY(VFW_E_CERTIFICATION_FAILURE
);
569 /***********************************************************************
570 * AMGetErrorTextA (quartz.@)
572 DWORD WINAPI
AMGetErrorTextA(HRESULT hr
, LPSTR pszbuf
, DWORD dwBufLen
)
577 lpszRes
= hresult_to_string( hr
);
578 if ( lpszRes
== NULL
)
580 len
= (DWORD
)(strlen(lpszRes
)+1);
581 if ( len
> dwBufLen
)
584 memcpy( pszbuf
, lpszRes
, len
);
588 /***********************************************************************
589 * AMGetErrorTextW (quartz.@)
591 DWORD WINAPI
AMGetErrorTextW(HRESULT hr
, LPWSTR pwszbuf
, DWORD dwBufLen
)
593 CHAR szBuf
[MAX_ERROR_TEXT_LEN
+1];
596 dwLen
= AMGetErrorTextA(hr
,szBuf
,MAX_ERROR_TEXT_LEN
);
601 QUARTZ_strncpyAtoW( pwszbuf
, szBuf
, dwBufLen
);
603 return lstrlenW( pwszbuf
);