4 * hidenori@a2.ctktv.ne.jp
16 #include "wine/obj_oleaut.h"
22 #include "debugtools.h"
23 DEFAULT_DEBUG_CHANNEL(quartz
);
25 #include "quartz_private.h"
35 typedef struct QUARTZ_CLASSENTRY
38 QUARTZ_pCreateIUnknown pCreateIUnk
;
43 IClassFactory_fnQueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
);
44 static ULONG WINAPI
IClassFactory_fnAddRef(LPCLASSFACTORY iface
);
45 static ULONG WINAPI
IClassFactory_fnRelease(LPCLASSFACTORY iface
);
46 static HRESULT WINAPI
IClassFactory_fnCreateInstance(LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
);
47 static HRESULT WINAPI
IClassFactory_fnLockServer(LPCLASSFACTORY iface
,BOOL dolock
);
49 static ICOM_VTABLE(IClassFactory
) iclassfact
=
51 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
52 IClassFactory_fnQueryInterface
,
53 IClassFactory_fnAddRef
,
54 IClassFactory_fnRelease
,
55 IClassFactory_fnCreateInstance
,
56 IClassFactory_fnLockServer
62 ICOM_VFIELD(IClassFactory
);
64 /* IClassFactory fields */
65 const QUARTZ_CLASSENTRY
* pEntry
;
68 static const QUARTZ_CLASSENTRY QUARTZ_ClassList
[] =
70 { &CLSID_FilterGraph
, &QUARTZ_CreateFilterGraph
},
71 { &CLSID_SystemClock
, &QUARTZ_CreateSystemClock
},
72 { &CLSID_MemoryAllocator
, &QUARTZ_CreateMemoryAllocator
},
73 { &CLSID_SystemDeviceEnum
, &QUARTZ_CreateSystemDeviceEnum
},
74 { &CLSID_FilterMapper
, &QUARTZ_CreateFilterMapper
},
75 { &CLSID_FilterMapper2
, &QUARTZ_CreateFilterMapper2
},
76 { &CLSID_SeekingPassThru
, &QUARTZ_CreateSeekingPassThru
},
80 /* per-process variables */
81 static CRITICAL_SECTION csHeap
;
82 static DWORD dwClassObjRef
;
83 static HANDLE hDLLHeap
;
85 void* QUARTZ_AllocObj( DWORD dwSize
)
89 EnterCriticalSection( &csHeap
);
91 pv
= HeapAlloc( hDLLHeap
, 0, dwSize
);
94 LeaveCriticalSection( &csHeap
);
99 void QUARTZ_FreeObj( void* pobj
)
101 EnterCriticalSection( &csHeap
);
102 HeapFree( hDLLHeap
, 0, pobj
);
104 LeaveCriticalSection( &csHeap
);
107 void* QUARTZ_AllocMem( DWORD dwSize
)
109 return HeapAlloc( hDLLHeap
, 0, dwSize
);
112 void QUARTZ_FreeMem( void* pMem
)
114 HeapFree( hDLLHeap
, 0, pMem
);
117 void* QUARTZ_ReallocMem( void* pMem
, DWORD dwSize
)
120 return QUARTZ_AllocMem( dwSize
);
122 return HeapReAlloc( hDLLHeap
, 0, pMem
, dwSize
);
126 LPWSTR
QUARTZ_strncpyAtoW( LPWSTR lpwstr
, LPCSTR lpstr
, INT wbuflen
)
130 len
= MultiByteToWideChar( CP_ACP
, 0, lpstr
, -1, lpwstr
, wbuflen
);
137 /************************************************************************/
139 static HRESULT WINAPI
140 IClassFactory_fnQueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
)
142 ICOM_THIS(IClassFactoryImpl
,iface
);
144 TRACE("(%p)->(%p,%p)\n",This
,riid
,ppobj
);
145 if ( ( IsEqualGUID( &IID_IUnknown
, riid
) ) ||
146 ( IsEqualGUID( &IID_IClassFactory
, riid
) ) )
149 IClassFactory_AddRef(iface
);
153 return E_NOINTERFACE
;
156 static ULONG WINAPI
IClassFactory_fnAddRef(LPCLASSFACTORY iface
)
158 ICOM_THIS(IClassFactoryImpl
,iface
);
160 TRACE("(%p)->()\n",This
);
162 return InterlockedExchangeAdd(&(This
->ref
),1) + 1;
165 static ULONG WINAPI
IClassFactory_fnRelease(LPCLASSFACTORY iface
)
167 ICOM_THIS(IClassFactoryImpl
,iface
);
170 TRACE("(%p)->()\n",This
);
171 ref
= InterlockedExchangeAdd(&(This
->ref
),-1) - 1;
175 QUARTZ_FreeObj(This
);
179 static HRESULT WINAPI
IClassFactory_fnCreateInstance(LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
)
181 ICOM_THIS(IClassFactoryImpl
,iface
);
185 TRACE("(%p)->(%p,%s,%p)\n",This
,pOuter
,debugstr_guid(riid
),ppobj
);
189 if ( pOuter
!= NULL
&& !IsEqualGUID( riid
, &IID_IUnknown
) )
190 return CLASS_E_NOAGGREGATION
;
194 hr
= (*This
->pEntry
->pCreateIUnk
)(pOuter
,(void**)&punk
);
198 hr
= IUnknown_QueryInterface(punk
,riid
,ppobj
);
199 IUnknown_Release(punk
);
204 static HRESULT WINAPI
IClassFactory_fnLockServer(LPCLASSFACTORY iface
,BOOL dolock
)
206 ICOM_THIS(IClassFactoryImpl
,iface
);
209 TRACE("(%p)->(%d)\n",This
,dolock
);
211 hr
= IClassFactory_AddRef(iface
);
213 hr
= IClassFactory_Release(iface
);
220 static HRESULT
IClassFactory_Alloc( const CLSID
* pclsid
, void** ppobj
)
222 const QUARTZ_CLASSENTRY
* pEntry
;
223 IClassFactoryImpl
* pImpl
;
225 TRACE( "(%s,%p)\n", debugstr_guid(pclsid
), ppobj
);
227 pEntry
= QUARTZ_ClassList
;
228 while ( pEntry
->pclsid
!= NULL
)
230 if ( IsEqualGUID( pclsid
, pEntry
->pclsid
) )
235 return CLASS_E_CLASSNOTAVAILABLE
;
237 pImpl
= (IClassFactoryImpl
*)QUARTZ_AllocObj( sizeof(IClassFactoryImpl
) );
239 return E_OUTOFMEMORY
;
241 TRACE( "allocated successfully.\n" );
243 ICOM_VTBL(pImpl
) = &iclassfact
;
245 pImpl
->pEntry
= pEntry
;
247 *ppobj
= (void*)pImpl
;
252 /***********************************************************************
253 * QUARTZ_InitProcess (internal)
255 static BOOL
QUARTZ_InitProcess( void )
260 hDLLHeap
= (HANDLE
)NULL
;
261 InitializeCriticalSection( &csHeap
);
263 hDLLHeap
= HeapCreate( 0, 0x10000, 0 );
264 if ( hDLLHeap
== (HANDLE
)NULL
)
270 /***********************************************************************
271 * QUARTZ_UninitProcess (internal)
273 static void QUARTZ_UninitProcess( void )
277 if ( dwClassObjRef
!= 0 )
278 ERR( "you must release some objects allocated from quartz.\n" );
279 if ( hDLLHeap
!= (HANDLE
)NULL
)
281 HeapDestroy( hDLLHeap
);
282 hDLLHeap
= (HANDLE
)NULL
;
284 DeleteCriticalSection( &csHeap
);
287 /***********************************************************************
290 BOOL WINAPI
QUARTZ_DllMain(
297 case DLL_PROCESS_ATTACH
:
298 if ( !QUARTZ_InitProcess() )
301 case DLL_PROCESS_DETACH
:
302 QUARTZ_UninitProcess();
304 case DLL_THREAD_ATTACH
:
306 case DLL_THREAD_DETACH
:
314 /***********************************************************************
315 * DllCanUnloadNow (QUARTZ.@)
321 HRESULT WINAPI
QUARTZ_DllCanUnloadNow(void)
325 EnterCriticalSection( &csHeap
);
326 hr
= ( dwClassObjRef
== 0 ) ? S_OK
: S_FALSE
;
327 LeaveCriticalSection( &csHeap
);
332 /***********************************************************************
333 * DllGetClassObject (QUARTZ.@)
335 HRESULT WINAPI
QUARTZ_DllGetClassObject(
336 const CLSID
* pclsid
,const IID
* piid
,void** ppv
)
339 if ( IsEqualCLSID( &IID_IUnknown
, piid
) ||
340 IsEqualCLSID( &IID_IClassFactory
, piid
) )
342 return IClassFactory_Alloc( pclsid
, ppv
);
345 return CLASS_E_CLASSNOTAVAILABLE
;
348 /***********************************************************************
349 * DllRegisterServer (QUARTZ.@)
352 HRESULT WINAPI
QUARTZ_DllRegisterServer( void )
354 FIXME( "(): stub\n" );
358 /***********************************************************************
359 * DllUnregisterServer (QUARTZ.@)
362 HRESULT WINAPI
QUARTZ_DllUnregisterServer( void )
364 FIXME( "(): stub\n" );
368 /**************************************************************************/
369 /**************************************************************************/
371 /* FIXME - all string should be defined in the resource of quartz. */
373 static LPCSTR
hresult_to_string( HRESULT hr
)
377 #define ENTRY(x) case x: return (const char*)#x
378 /* some known codes */
384 ENTRY(E_NOINTERFACE
);
385 ENTRY(E_OUTOFMEMORY
);
386 ENTRY(CLASS_E_CLASSNOTAVAILABLE
);
387 ENTRY(CLASS_E_NOAGGREGATION
);
390 ENTRY(VFW_S_NO_MORE_ITEMS
);
391 ENTRY(VFW_E_BAD_KEY
);
392 ENTRY(VFW_E_INVALIDMEDIATYPE
);
393 ENTRY(VFW_E_INVALIDSUBTYPE
);
394 ENTRY(VFW_E_NEED_OWNER
);
395 ENTRY(VFW_E_ENUM_OUT_OF_SYNC
);
396 ENTRY(VFW_E_ALREADY_CONNECTED
);
397 ENTRY(VFW_E_FILTER_ACTIVE
);
398 ENTRY(VFW_E_NO_TYPES
);
399 ENTRY(VFW_E_NO_ACCEPTABLE_TYPES
);
400 ENTRY(VFW_E_INVALID_DIRECTION
);
401 ENTRY(VFW_E_NOT_CONNECTED
);
402 ENTRY(VFW_E_NO_ALLOCATOR
);
403 ENTRY(VFW_E_RUNTIME_ERROR
);
404 ENTRY(VFW_E_BUFFER_NOTSET
);
405 ENTRY(VFW_E_BUFFER_OVERFLOW
);
406 ENTRY(VFW_E_BADALIGN
);
407 ENTRY(VFW_E_ALREADY_COMMITTED
);
408 ENTRY(VFW_E_BUFFERS_OUTSTANDING
);
409 ENTRY(VFW_E_NOT_COMMITTED
);
410 ENTRY(VFW_E_SIZENOTSET
);
411 ENTRY(VFW_E_NO_CLOCK
);
412 ENTRY(VFW_E_NO_SINK
);
413 ENTRY(VFW_E_NO_INTERFACE
);
414 ENTRY(VFW_E_NOT_FOUND
);
415 ENTRY(VFW_E_CANNOT_CONNECT
);
416 ENTRY(VFW_E_CANNOT_RENDER
);
417 ENTRY(VFW_E_CHANGING_FORMAT
);
418 ENTRY(VFW_E_NO_COLOR_KEY_SET
);
419 ENTRY(VFW_E_NOT_OVERLAY_CONNECTION
);
420 ENTRY(VFW_E_NOT_SAMPLE_CONNECTION
);
421 ENTRY(VFW_E_PALETTE_SET
);
422 ENTRY(VFW_E_COLOR_KEY_SET
);
423 ENTRY(VFW_E_NO_COLOR_KEY_FOUND
);
424 ENTRY(VFW_E_NO_PALETTE_AVAILABLE
);
425 ENTRY(VFW_E_NO_DISPLAY_PALETTE
);
426 ENTRY(VFW_E_TOO_MANY_COLORS
);
427 ENTRY(VFW_E_STATE_CHANGED
);
428 ENTRY(VFW_E_NOT_STOPPED
);
429 ENTRY(VFW_E_NOT_PAUSED
);
430 ENTRY(VFW_E_NOT_RUNNING
);
431 ENTRY(VFW_E_WRONG_STATE
);
432 ENTRY(VFW_E_START_TIME_AFTER_END
);
433 ENTRY(VFW_E_INVALID_RECT
);
434 ENTRY(VFW_E_TYPE_NOT_ACCEPTED
);
435 ENTRY(VFW_E_SAMPLE_REJECTED
);
436 ENTRY(VFW_E_SAMPLE_REJECTED_EOS
);
437 ENTRY(VFW_S_DUPLICATE_NAME
);
438 ENTRY(VFW_E_DUPLICATE_NAME
);
439 ENTRY(VFW_E_TIMEOUT
);
440 ENTRY(VFW_E_INVALID_FILE_FORMAT
);
441 ENTRY(VFW_E_ENUM_OUT_OF_RANGE
);
442 ENTRY(VFW_E_CIRCULAR_GRAPH
);
443 ENTRY(VFW_E_NOT_ALLOWED_TO_SAVE
);
444 ENTRY(VFW_E_TIME_ALREADY_PASSED
);
445 ENTRY(VFW_E_ALREADY_CANCELLED
);
446 ENTRY(VFW_E_CORRUPT_GRAPH_FILE
);
447 ENTRY(VFW_E_ADVISE_ALREADY_SET
);
448 ENTRY(VFW_S_STATE_INTERMEDIATE
);
449 ENTRY(VFW_E_NO_MODEX_AVAILABLE
);
450 ENTRY(VFW_E_NO_ADVISE_SET
);
451 ENTRY(VFW_E_NO_FULLSCREEN
);
452 ENTRY(VFW_E_IN_FULLSCREEN_MODE
);
453 ENTRY(VFW_E_UNKNOWN_FILE_TYPE
);
454 ENTRY(VFW_E_CANNOT_LOAD_SOURCE_FILTER
);
455 ENTRY(VFW_S_PARTIAL_RENDER
);
456 ENTRY(VFW_E_FILE_TOO_SHORT
);
457 ENTRY(VFW_E_INVALID_FILE_VERSION
);
458 ENTRY(VFW_S_SOME_DATA_IGNORED
);
459 ENTRY(VFW_S_CONNECTIONS_DEFERRED
);
460 ENTRY(VFW_E_INVALID_CLSID
);
461 ENTRY(VFW_E_INVALID_MEDIA_TYPE
);
462 ENTRY(VFW_E_SAMPLE_TIME_NOT_SET
);
463 ENTRY(VFW_S_RESOURCE_NOT_NEEDED
);
464 ENTRY(VFW_E_MEDIA_TIME_NOT_SET
);
465 ENTRY(VFW_E_NO_TIME_FORMAT_SET
);
466 ENTRY(VFW_E_MONO_AUDIO_HW
);
467 ENTRY(VFW_S_MEDIA_TYPE_IGNORED
);
468 ENTRY(VFW_E_NO_DECOMPRESSOR
);
469 ENTRY(VFW_E_NO_AUDIO_HARDWARE
);
470 ENTRY(VFW_S_VIDEO_NOT_RENDERED
);
471 ENTRY(VFW_S_AUDIO_NOT_RENDERED
);
474 ENTRY(VFW_E_PROCESSOR_NOT_SUITABLE
);
475 ENTRY(VFW_E_UNSUPPORTED_AUDIO
);
476 ENTRY(VFW_E_UNSUPPORTED_VIDEO
);
477 ENTRY(VFW_E_MPEG_NOT_CONSTRAINED
);
478 ENTRY(VFW_E_NOT_IN_GRAPH
);
479 ENTRY(VFW_S_ESTIMATED
);
480 ENTRY(VFW_E_NO_TIME_FORMAT
);
481 ENTRY(VFW_E_READ_ONLY
);
482 ENTRY(VFW_S_RESERVED
);
483 ENTRY(VFW_E_BUFFER_UNDERFLOW
);
484 ENTRY(VFW_E_UNSUPPORTED_STREAM
);
485 ENTRY(VFW_E_NO_TRANSPORT
);
486 ENTRY(VFW_S_STREAM_OFF
);
487 ENTRY(VFW_S_CANT_CUE
);
488 ENTRY(VFW_E_BAD_VIDEOCD
);
489 ENTRY(VFW_S_NO_STOP_TIME
);
490 ENTRY(VFW_E_OUT_OF_VIDEO_MEMORY
);
491 ENTRY(VFW_E_VP_NEGOTIATION_FAILED
);
492 ENTRY(VFW_E_DDRAW_CAPS_NOT_SUITABLE
);
493 ENTRY(VFW_E_NO_VP_HARDWARE
);
494 ENTRY(VFW_E_NO_CAPTURE_HARDWARE
);
495 ENTRY(VFW_E_DVD_OPERATION_INHIBITED
);
496 ENTRY(VFW_E_DVD_INVALIDDOMAIN
);
497 ENTRY(VFW_E_DVD_NO_BUTTON
);
498 ENTRY(VFW_E_DVD_GRAPHNOTREADY
);
499 ENTRY(VFW_E_DVD_RENDERFAIL
);
500 ENTRY(VFW_E_DVD_DECNOTENOUGH
);
501 ENTRY(VFW_E_DDRAW_VERSION_NOT_SUITABLE
);
502 ENTRY(VFW_E_COPYPROT_FAILED
);
503 ENTRY(VFW_S_NOPREVIEWPIN
);
504 ENTRY(VFW_E_TIME_EXPIRED
);
505 ENTRY(VFW_S_DVD_NON_ONE_SEQUENTIAL
);
506 ENTRY(VFW_E_DVD_WRONG_SPEED
);
507 ENTRY(VFW_E_DVD_MENU_DOES_NOT_EXIST
);
508 ENTRY(VFW_E_DVD_CMD_CANCELLED
);
509 ENTRY(VFW_E_DVD_STATE_WRONG_VERSION
);
510 ENTRY(VFW_E_DVD_STATE_CORRUPT
);
511 ENTRY(VFW_E_DVD_STATE_WRONG_DISC
);
512 ENTRY(VFW_E_DVD_INCOMPATIBLE_REGION
);
513 ENTRY(VFW_E_DVD_NO_ATTRIBUTES
);
514 ENTRY(VFW_E_DVD_NO_GOUP_PGC
);
515 ENTRY(VFW_E_DVD_LOW_PARENTAL_LEVEL
);
516 ENTRY(VFW_E_DVD_NOT_IN_KARAOKE_MODE
);
517 ENTRY(VFW_S_DVD_CHANNEL_CONTENTS_NOT_AVAILABLE
);
518 ENTRY(VFW_S_DVD_NOT_ACCURATE
);
519 ENTRY(VFW_E_FRAME_STEP_UNSUPPORTED
);
520 ENTRY(VFW_E_DVD_STREAM_DISABLED
);
521 ENTRY(VFW_E_DVD_TITLE_UNKNOWN
);
522 ENTRY(VFW_E_DVD_INVALID_DISC
);
523 ENTRY(VFW_E_DVD_NO_RESUME_INFORMATION
);
524 ENTRY(VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD
);
525 ENTRY(VFW_E_PIN_ALREADY_BLOCKED
);
526 ENTRY(VFW_E_CERTIFICATION_FAILURE
);
533 /***********************************************************************
534 * AMGetErrorTextA (quartz.@)
536 DWORD WINAPI
AMGetErrorTextA(HRESULT hr
, LPSTR pszbuf
, DWORD dwBufLen
)
541 lpszRes
= hresult_to_string( hr
);
542 if ( lpszRes
== NULL
)
544 len
= (DWORD
)(strlen(lpszRes
)+1);
545 if ( len
> dwBufLen
)
548 memcpy( pszbuf
, lpszRes
, len
);
552 /***********************************************************************
553 * AMGetErrorTextW (quartz.@)
555 DWORD WINAPI
AMGetErrorTextW(HRESULT hr
, LPWSTR pwszbuf
, DWORD dwBufLen
)
557 CHAR szBuf
[MAX_ERROR_TEXT_LEN
+1];
560 dwLen
= AMGetErrorTextA(hr
,szBuf
,MAX_ERROR_TEXT_LEN
);
565 QUARTZ_strncpyAtoW( pwszbuf
, szBuf
, dwBufLen
);
567 return lstrlenW( pwszbuf
);