Added a framework for testing CreateProcess and a few tests.
[wine] / dlls / quartz / seekpass.c
1 /*
2  *      Implementation of CLSID_SeekingPassThru
3  *
4  *      FIXME - not tested yet.
5  *
6  * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include "config.h"
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "winerror.h"
30 #include "strmif.h"
31 #include "control.h"
32 #include "uuids.h"
33
34 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
36
37 #include "quartz_private.h"
38 #include "seekpass.h"
39
40
41 /***************************************************************************
42  *
43  *      CSeekingPassThru::ISeekingPassThru
44  *
45  */
46
47 static HRESULT WINAPI
48 ISeekingPassThru_fnQueryInterface(ISeekingPassThru* iface,REFIID riid,void** ppobj)
49 {
50         CSeekingPassThru_THIS(iface,seekpass);
51
52         TRACE("(%p)->()\n",This);
53
54         return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
55 }
56
57 static ULONG WINAPI
58 ISeekingPassThru_fnAddRef(ISeekingPassThru* iface)
59 {
60         CSeekingPassThru_THIS(iface,seekpass);
61
62         TRACE("(%p)->()\n",This);
63
64         return IUnknown_AddRef(This->unk.punkControl);
65 }
66
67 static ULONG WINAPI
68 ISeekingPassThru_fnRelease(ISeekingPassThru* iface)
69 {
70         CSeekingPassThru_THIS(iface,seekpass);
71
72         TRACE("(%p)->()\n",This);
73
74         return IUnknown_Release(This->unk.punkControl);
75 }
76
77 static HRESULT WINAPI
78 ISeekingPassThru_fnInit(ISeekingPassThru* iface,BOOL bRendering,IPin* pPin)
79 {
80         CSeekingPassThru_THIS(iface,seekpass);
81
82         TRACE("(%p)->(%d,%p)\n",This,bRendering,pPin);
83
84         if ( pPin == NULL )
85                 return E_POINTER;
86         if ( bRendering )
87         {
88                 WARN("bRendering != FALSE\n");
89         }
90
91         /* Why is 'bRendering' given as an argument?? */
92         EnterCriticalSection( &This->cs );
93
94         if ( This->passthru.pPin != NULL )
95                 IPin_Release( This->passthru.pPin );
96         This->passthru.pPin = pPin; IPin_AddRef( pPin );
97
98         LeaveCriticalSection( &This->cs );
99
100         return NOERROR;
101 }
102
103
104 static ICOM_VTABLE(ISeekingPassThru) iseekingpassthru =
105 {
106         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
107         /* IUnknown fields */
108         ISeekingPassThru_fnQueryInterface,
109         ISeekingPassThru_fnAddRef,
110         ISeekingPassThru_fnRelease,
111         /* ISeekingPassThru fields */
112         ISeekingPassThru_fnInit,
113 };
114
115 static
116 HRESULT CSeekingPassThru_InitISeekingPassThru(CSeekingPassThru* This)
117 {
118         TRACE("(%p)\n",This);
119         ICOM_VTBL(&This->seekpass) = &iseekingpassthru;
120         This->passthru.punk = This->unk.punkControl;
121         This->passthru.pPin = NULL;
122         InitializeCriticalSection( &This->cs );
123
124         return NOERROR;
125 }
126
127 static
128 void CSeekingPassThru_UninitISeekingPassThru(CSeekingPassThru* This)
129 {
130         TRACE("(%p)\n",This);
131         if ( This->passthru.pPin != NULL )
132         {
133                 IPin_Release( This->passthru.pPin );
134                 This->passthru.pPin = NULL;
135         }
136         DeleteCriticalSection( &This->cs );
137 }
138
139 /***************************************************************************
140  *
141  *      new/delete for CLSID_SeekingPassThru.
142  *
143  */
144
145 /* can I use offsetof safely? - FIXME? */
146 static QUARTZ_IFEntry IFEntries[] =
147 {
148   { &IID_ISeekingPassThru, offsetof(CSeekingPassThru,seekpass)-offsetof(CSeekingPassThru,unk) },
149   { &IID_IMediaPosition, offsetof(CSeekingPassThru,passthru.mpos)-offsetof(CSeekingPassThru,unk) },
150   { &IID_IMediaSeeking, offsetof(CSeekingPassThru,passthru.mseek)-offsetof(CSeekingPassThru,unk) },
151 };
152
153
154 static void QUARTZ_DestroySeekingPassThru(IUnknown* punk)
155 {
156         CSeekingPassThru_THIS(punk,unk);
157
158         TRACE("(%p)\n",This);
159
160         CPassThruImpl_UninitIMediaSeeking( &This->passthru );
161         CPassThruImpl_UninitIMediaPosition( &This->passthru );
162         CSeekingPassThru_UninitISeekingPassThru(This);
163 }
164
165 HRESULT QUARTZ_CreateSeekingPassThru(IUnknown* punkOuter,void** ppobj)
166 {
167         HRESULT hr;
168         CSeekingPassThru*       This;
169
170         TRACE("(%p,%p)\n",punkOuter,ppobj);
171
172         hr = QUARTZ_CreateSeekingPassThruInternal(punkOuter,&This,FALSE,NULL);
173         if ( hr != S_OK )
174                 return hr;
175
176         ppobj = (void*)(&This->unk);
177
178         return NOERROR;
179 }
180
181 HRESULT QUARTZ_CreateSeekingPassThruInternal(IUnknown* punkOuter,CSeekingPassThru** ppobj,BOOL bRendering,IPin* pPin)
182 {
183         CSeekingPassThru*       This;
184         HRESULT hr;
185
186         TRACE("(%p,%p,%d,%p)\n",punkOuter,ppobj,(int)bRendering,pPin);
187
188         This = (CSeekingPassThru*)QUARTZ_AllocObj( sizeof(CSeekingPassThru) );
189         if ( This == NULL )
190                 return E_OUTOFMEMORY;
191
192         QUARTZ_IUnkInit( &This->unk, punkOuter );
193         hr = CSeekingPassThru_InitISeekingPassThru(This);
194         if ( SUCCEEDED(hr) )
195         {
196                 hr = CPassThruImpl_InitIMediaPosition( &This->passthru );
197                 if ( SUCCEEDED(hr) )
198                 {
199                         hr = CPassThruImpl_InitIMediaSeeking( &This->passthru );
200                         if ( FAILED(hr) )
201                         {
202                                 CPassThruImpl_UninitIMediaPosition( &This->passthru );
203                         }
204                 }
205                 else
206                 {
207                         CSeekingPassThru_UninitISeekingPassThru(This);
208                 }
209         }
210
211         if ( FAILED(hr) )
212         {
213                 QUARTZ_FreeObj( This );
214                 return hr;
215         }
216
217         This->unk.pEntries = IFEntries;
218         This->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
219         This->unk.pOnFinalRelease = QUARTZ_DestroySeekingPassThru;
220
221         *ppobj = This;
222
223         if ( pPin != NULL )
224         {
225                 hr = ISeekingPassThru_Init((ISeekingPassThru*)(&This->seekpass),bRendering,pPin);
226                 if ( FAILED(hr) )
227                 {
228                         IUnknown_Release(This->unk.punkControl);
229                         return hr;
230                 }
231         }
232
233         return S_OK;
234 }
235
236
237
238
239 /***************************************************************************
240  *
241  *      CPassThruImpl Helper methods.
242  *
243  */
244
245 static
246 HRESULT CPassThruImpl_GetConnected( CPassThruImpl* pImpl, IPin** ppPin )
247 {
248         return IPin_ConnectedTo( pImpl->pPin, ppPin );
249 }
250
251 HRESULT CPassThruImpl_QueryPosPass(
252         CPassThruImpl* pImpl, IMediaPosition** ppPosition )
253 {
254         IPin*   pPin;
255         HRESULT hr;
256
257         hr = CPassThruImpl_GetConnected( pImpl, &pPin );
258         if ( FAILED(hr) )
259                 return hr;
260         hr = IPin_QueryInterface(pPin,&IID_IMediaPosition,(void**)ppPosition);
261         IPin_Release(pPin);
262
263         return hr;
264 }
265
266 HRESULT CPassThruImpl_QuerySeekPass(
267         CPassThruImpl* pImpl, IMediaSeeking** ppSeeking )
268 {
269         IPin*   pPin;
270         HRESULT hr;
271
272         hr = CPassThruImpl_GetConnected( pImpl, &pPin );
273         if ( FAILED(hr) )
274                 return hr;
275         hr = IPin_QueryInterface(pPin,&IID_IMediaSeeking,(void**)ppSeeking);
276         IPin_Release(pPin);
277
278         return hr;
279 }
280
281 /***************************************************************************
282  *
283  *      An implementation for CPassThruImpl::IMediaPosition.
284  *
285  */
286
287
288 #define QUERYPOSPASS \
289         IMediaPosition* pPos = NULL; \
290         HRESULT hr; \
291         hr = CPassThruImpl_QueryPosPass( This, &pPos ); \
292         if ( FAILED(hr) ) return hr;
293
294 static HRESULT WINAPI
295 IMediaPosition_fnQueryInterface(IMediaPosition* iface,REFIID riid,void** ppobj)
296 {
297         CPassThruImpl_THIS(iface,mpos);
298
299         TRACE("(%p)->()\n",This);
300
301         return IUnknown_QueryInterface(This->punk,riid,ppobj);
302 }
303
304 static ULONG WINAPI
305 IMediaPosition_fnAddRef(IMediaPosition* iface)
306 {
307         CPassThruImpl_THIS(iface,mpos);
308
309         TRACE("(%p)->()\n",This);
310
311         return IUnknown_AddRef(This->punk);
312 }
313
314 static ULONG WINAPI
315 IMediaPosition_fnRelease(IMediaPosition* iface)
316 {
317         CPassThruImpl_THIS(iface,mpos);
318
319         TRACE("(%p)->()\n",This);
320
321         return IUnknown_Release(This->punk);
322 }
323
324 static HRESULT WINAPI
325 IMediaPosition_fnGetTypeInfoCount(IMediaPosition* iface,UINT* pcTypeInfo)
326 {
327         CPassThruImpl_THIS(iface,mpos);
328
329         FIXME("(%p)->() stub!\n",This);
330
331         return E_NOTIMPL;
332 }
333
334 static HRESULT WINAPI
335 IMediaPosition_fnGetTypeInfo(IMediaPosition* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
336 {
337         CPassThruImpl_THIS(iface,mpos);
338
339         FIXME("(%p)->() stub!\n",This);
340
341         return E_NOTIMPL;
342 }
343
344 static HRESULT WINAPI
345 IMediaPosition_fnGetIDsOfNames(IMediaPosition* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
346 {
347         CPassThruImpl_THIS(iface,mpos);
348
349         FIXME("(%p)->() stub!\n",This);
350
351         return E_NOTIMPL;
352 }
353
354 static HRESULT WINAPI
355 IMediaPosition_fnInvoke(IMediaPosition* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
356 {
357         CPassThruImpl_THIS(iface,mpos);
358
359         FIXME("(%p)->() stub!\n",This);
360
361         return E_NOTIMPL;
362 }
363
364
365 static HRESULT WINAPI
366 IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime)
367 {
368         CPassThruImpl_THIS(iface,mpos);
369         QUERYPOSPASS
370
371         TRACE("(%p)->()\n",This);
372
373         hr = IMediaPosition_get_Duration(pPos,prefTime);
374         IMediaPosition_Release(pPos);
375         return hr;
376 }
377
378 static HRESULT WINAPI
379 IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime)
380 {
381         CPassThruImpl_THIS(iface,mpos);
382         QUERYPOSPASS
383
384         TRACE("(%p)->()\n",This);
385
386         hr = IMediaPosition_put_CurrentPosition(pPos,refTime);
387         IMediaPosition_Release(pPos);
388         return hr;
389 }
390
391 static HRESULT WINAPI
392 IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime)
393 {
394         CPassThruImpl_THIS(iface,mpos);
395         QUERYPOSPASS
396
397         TRACE("(%p)->()\n",This);
398
399         hr = IMediaPosition_get_CurrentPosition(pPos,prefTime);
400         IMediaPosition_Release(pPos);
401         return hr;
402 }
403
404 static HRESULT WINAPI
405 IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime)
406 {
407         CPassThruImpl_THIS(iface,mpos);
408         QUERYPOSPASS
409
410         TRACE("(%p)->()\n",This);
411
412         hr = IMediaPosition_get_StopTime(pPos,prefTime);
413         IMediaPosition_Release(pPos);
414         return hr;
415 }
416
417 static HRESULT WINAPI
418 IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime)
419 {
420         CPassThruImpl_THIS(iface,mpos);
421         QUERYPOSPASS
422
423         TRACE("(%p)->()\n",This);
424
425         hr = IMediaPosition_put_StopTime(pPos,refTime);
426         IMediaPosition_Release(pPos);
427         return hr;
428 }
429
430 static HRESULT WINAPI
431 IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime)
432 {
433         CPassThruImpl_THIS(iface,mpos);
434         QUERYPOSPASS
435
436         TRACE("(%p)->()\n",This);
437
438         hr = IMediaPosition_get_PrerollTime(pPos,prefTime);
439         IMediaPosition_Release(pPos);
440         return hr;
441 }
442
443 static HRESULT WINAPI
444 IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime)
445 {
446         CPassThruImpl_THIS(iface,mpos);
447         QUERYPOSPASS
448
449         TRACE("(%p)->()\n",This);
450
451         hr = IMediaPosition_put_PrerollTime(pPos,refTime);
452         IMediaPosition_Release(pPos);
453         return hr;
454 }
455
456 static HRESULT WINAPI
457 IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate)
458 {
459         CPassThruImpl_THIS(iface,mpos);
460         QUERYPOSPASS
461
462         TRACE("(%p)->()\n",This);
463
464         hr = IMediaPosition_put_Rate(pPos,dblRate);
465         IMediaPosition_Release(pPos);
466         return hr;
467 }
468
469 static HRESULT WINAPI
470 IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate)
471 {
472         CPassThruImpl_THIS(iface,mpos);
473         QUERYPOSPASS
474
475         TRACE("(%p)->()\n",This);
476
477         hr = IMediaPosition_get_Rate(pPos,pdblRate);
478         IMediaPosition_Release(pPos);
479         return hr;
480 }
481
482 static HRESULT WINAPI
483 IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek)
484 {
485         CPassThruImpl_THIS(iface,mpos);
486         QUERYPOSPASS
487
488         TRACE("(%p)->()\n",This);
489
490         hr = IMediaPosition_CanSeekForward(pPos,pCanSeek);
491         IMediaPosition_Release(pPos);
492         return hr;
493 }
494
495 static HRESULT WINAPI
496 IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek)
497 {
498         CPassThruImpl_THIS(iface,mpos);
499         QUERYPOSPASS
500
501         TRACE("(%p)->()\n",This);
502
503         hr = IMediaPosition_CanSeekBackward(pPos,pCanSeek);
504         IMediaPosition_Release(pPos);
505         return hr;
506 }
507
508
509 static ICOM_VTABLE(IMediaPosition) impos =
510 {
511         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
512         /* IUnknown fields */
513         IMediaPosition_fnQueryInterface,
514         IMediaPosition_fnAddRef,
515         IMediaPosition_fnRelease,
516         /* IDispatch fields */
517         IMediaPosition_fnGetTypeInfoCount,
518         IMediaPosition_fnGetTypeInfo,
519         IMediaPosition_fnGetIDsOfNames,
520         IMediaPosition_fnInvoke,
521         /* IMediaPosition fields */
522         IMediaPosition_fnget_Duration,
523         IMediaPosition_fnput_CurrentPosition,
524         IMediaPosition_fnget_CurrentPosition,
525         IMediaPosition_fnget_StopTime,
526         IMediaPosition_fnput_StopTime,
527         IMediaPosition_fnget_PrerollTime,
528         IMediaPosition_fnput_PrerollTime,
529         IMediaPosition_fnput_Rate,
530         IMediaPosition_fnget_Rate,
531         IMediaPosition_fnCanSeekForward,
532         IMediaPosition_fnCanSeekBackward,
533 };
534
535
536 HRESULT CPassThruImpl_InitIMediaPosition( CPassThruImpl* pImpl )
537 {
538         TRACE("(%p)\n",pImpl);
539         ICOM_VTBL(&pImpl->mpos) = &impos;
540
541         return NOERROR;
542 }
543
544 void CPassThruImpl_UninitIMediaPosition( CPassThruImpl* pImpl )
545 {
546         TRACE("(%p)\n",pImpl);
547 }
548
549 #undef QUERYPOSPASS
550
551
552 /***************************************************************************
553  *
554  *      An implementation for CPassThruImpl::IMediaSeeking.
555  *
556  */
557
558 #define QUERYSEEKPASS \
559         IMediaSeeking* pSeek = NULL; \
560         HRESULT hr; \
561         hr = CPassThruImpl_QuerySeekPass( This, &pSeek ); \
562         if ( FAILED(hr) ) return hr;
563
564
565 static HRESULT WINAPI
566 IMediaSeeking_fnQueryInterface(IMediaSeeking* iface,REFIID riid,void** ppobj)
567 {
568         CPassThruImpl_THIS(iface,mseek);
569
570         TRACE("(%p)->()\n",This);
571
572         return IUnknown_QueryInterface(This->punk,riid,ppobj);
573 }
574
575 static ULONG WINAPI
576 IMediaSeeking_fnAddRef(IMediaSeeking* iface)
577 {
578         CPassThruImpl_THIS(iface,mseek);
579
580         TRACE("(%p)->()\n",This);
581
582         return IUnknown_AddRef(This->punk);
583 }
584
585 static ULONG WINAPI
586 IMediaSeeking_fnRelease(IMediaSeeking* iface)
587 {
588         CPassThruImpl_THIS(iface,mseek);
589
590         TRACE("(%p)->()\n",This);
591
592         return IUnknown_Release(This->punk);
593 }
594
595
596 static HRESULT WINAPI
597 IMediaSeeking_fnGetCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
598 {
599         CPassThruImpl_THIS(iface,mseek);
600         QUERYSEEKPASS
601
602         TRACE("(%p)->()\n",This);
603
604         hr = IMediaSeeking_GetCapabilities(pSeek,pdwCaps);
605         IMediaSeeking_Release(pSeek);
606         return hr;
607 }
608
609 static HRESULT WINAPI
610 IMediaSeeking_fnCheckCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
611 {
612         CPassThruImpl_THIS(iface,mseek);
613         QUERYSEEKPASS
614
615         TRACE("(%p)->()\n",This);
616
617         hr = IMediaSeeking_CheckCapabilities(pSeek,pdwCaps);
618         IMediaSeeking_Release(pSeek);
619         return hr;
620 }
621
622 static HRESULT WINAPI
623 IMediaSeeking_fnIsFormatSupported(IMediaSeeking* iface,const GUID* pidFormat)
624 {
625         CPassThruImpl_THIS(iface,mseek);
626         QUERYSEEKPASS
627
628         TRACE("(%p)->()\n",This);
629
630         hr = IMediaSeeking_IsFormatSupported(pSeek,pidFormat);
631         IMediaSeeking_Release(pSeek);
632         return hr;
633 }
634
635 static HRESULT WINAPI
636 IMediaSeeking_fnQueryPreferredFormat(IMediaSeeking* iface,GUID* pidFormat)
637 {
638         CPassThruImpl_THIS(iface,mseek);
639         QUERYSEEKPASS
640
641         TRACE("(%p)->()\n",This);
642
643         hr = IMediaSeeking_QueryPreferredFormat(pSeek,pidFormat);
644         IMediaSeeking_Release(pSeek);
645         return hr;
646 }
647
648 static HRESULT WINAPI
649 IMediaSeeking_fnGetTimeFormat(IMediaSeeking* iface,GUID* pidFormat)
650 {
651         CPassThruImpl_THIS(iface,mseek);
652         QUERYSEEKPASS
653
654         TRACE("(%p)->()\n",This);
655
656         hr = IMediaSeeking_GetTimeFormat(pSeek,pidFormat);
657         IMediaSeeking_Release(pSeek);
658         return hr;
659 }
660
661 static HRESULT WINAPI
662 IMediaSeeking_fnIsUsingTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
663 {
664         CPassThruImpl_THIS(iface,mseek);
665         QUERYSEEKPASS
666
667         TRACE("(%p)->()\n",This);
668
669         hr = IMediaSeeking_IsUsingTimeFormat(pSeek,pidFormat);
670         IMediaSeeking_Release(pSeek);
671         return hr;
672 }
673
674 static HRESULT WINAPI
675 IMediaSeeking_fnSetTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
676 {
677         CPassThruImpl_THIS(iface,mseek);
678         QUERYSEEKPASS
679
680         TRACE("(%p)->()\n",This);
681
682         hr = IMediaSeeking_SetTimeFormat(pSeek,pidFormat);
683         IMediaSeeking_Release(pSeek);
684         return hr;
685 }
686
687 static HRESULT WINAPI
688 IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration)
689 {
690         CPassThruImpl_THIS(iface,mseek);
691         QUERYSEEKPASS
692
693         TRACE("(%p)->()\n",This);
694
695         hr = IMediaSeeking_GetDuration(pSeek,pllDuration);
696         IMediaSeeking_Release(pSeek);
697         return hr;
698 }
699
700 static HRESULT WINAPI
701 IMediaSeeking_fnGetStopPosition(IMediaSeeking* iface,LONGLONG* pllPos)
702 {
703         CPassThruImpl_THIS(iface,mseek);
704         QUERYSEEKPASS
705
706         TRACE("(%p)->()\n",This);
707
708         hr = IMediaSeeking_GetStopPosition(pSeek,pllPos);
709         IMediaSeeking_Release(pSeek);
710         return hr;
711 }
712
713 static HRESULT WINAPI
714 IMediaSeeking_fnGetCurrentPosition(IMediaSeeking* iface,LONGLONG* pllPos)
715 {
716         CPassThruImpl_THIS(iface,mseek);
717         QUERYSEEKPASS
718
719         TRACE("(%p)->()\n",This);
720
721         hr = IMediaSeeking_GetCurrentPosition(pSeek,pllPos);
722         IMediaSeeking_Release(pSeek);
723         return hr;
724 }
725
726 static HRESULT WINAPI
727 IMediaSeeking_fnConvertTimeFormat(IMediaSeeking* iface,LONGLONG* pllOut,const GUID* pidFmtOut,LONGLONG llIn,const GUID* pidFmtIn)
728 {
729         CPassThruImpl_THIS(iface,mseek);
730         QUERYSEEKPASS
731
732         TRACE("(%p)->()\n",This);
733
734         hr = IMediaSeeking_ConvertTimeFormat(pSeek,pllOut,pidFmtOut,llIn,pidFmtIn);
735         IMediaSeeking_Release(pSeek);
736         return hr;
737 }
738
739 static HRESULT WINAPI
740 IMediaSeeking_fnSetPositions(IMediaSeeking* iface,LONGLONG* pllCur,DWORD dwCurFlags,LONGLONG* pllStop,DWORD dwStopFlags)
741 {
742         CPassThruImpl_THIS(iface,mseek);
743         QUERYSEEKPASS
744
745         TRACE("(%p)->()\n",This);
746
747         hr = IMediaSeeking_SetPositions(pSeek,pllCur,dwCurFlags,pllStop,dwStopFlags);
748         IMediaSeeking_Release(pSeek);
749         return hr;
750 }
751
752 static HRESULT WINAPI
753 IMediaSeeking_fnGetPositions(IMediaSeeking* iface,LONGLONG* pllCur,LONGLONG* pllStop)
754 {
755         CPassThruImpl_THIS(iface,mseek);
756         QUERYSEEKPASS
757
758         TRACE("(%p)->()\n",This);
759
760         hr = IMediaSeeking_GetPositions(pSeek,pllCur,pllStop);
761         IMediaSeeking_Release(pSeek);
762         return hr;
763 }
764
765 static HRESULT WINAPI
766 IMediaSeeking_fnGetAvailable(IMediaSeeking* iface,LONGLONG* pllFirst,LONGLONG* pllLast)
767 {
768         CPassThruImpl_THIS(iface,mseek);
769         QUERYSEEKPASS
770
771         TRACE("(%p)->()\n",This);
772
773         hr = IMediaSeeking_GetAvailable(pSeek,pllFirst,pllLast);
774         IMediaSeeking_Release(pSeek);
775         return hr;
776 }
777
778 static HRESULT WINAPI
779 IMediaSeeking_fnSetRate(IMediaSeeking* iface,double dblRate)
780 {
781         CPassThruImpl_THIS(iface,mseek);
782         QUERYSEEKPASS
783
784         TRACE("(%p)->()\n",This);
785
786         hr = IMediaSeeking_SetRate(pSeek,dblRate);
787         IMediaSeeking_Release(pSeek);
788         return hr;
789 }
790
791 static HRESULT WINAPI
792 IMediaSeeking_fnGetRate(IMediaSeeking* iface,double* pdblRate)
793 {
794         CPassThruImpl_THIS(iface,mseek);
795         QUERYSEEKPASS
796
797         TRACE("(%p)->()\n",This);
798
799         hr = IMediaSeeking_GetRate(pSeek,pdblRate);
800         IMediaSeeking_Release(pSeek);
801         return hr;
802 }
803
804 static HRESULT WINAPI
805 IMediaSeeking_fnGetPreroll(IMediaSeeking* iface,LONGLONG* pllPreroll)
806 {
807         CPassThruImpl_THIS(iface,mseek);
808         QUERYSEEKPASS
809
810         TRACE("(%p)->()\n",This);
811
812         hr = IMediaSeeking_GetPreroll(pSeek,pllPreroll);
813         IMediaSeeking_Release(pSeek);
814         return hr;
815 }
816
817
818
819
820 static ICOM_VTABLE(IMediaSeeking) imseek =
821 {
822         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
823         /* IUnknown fields */
824         IMediaSeeking_fnQueryInterface,
825         IMediaSeeking_fnAddRef,
826         IMediaSeeking_fnRelease,
827         /* IMediaSeeking fields */
828         IMediaSeeking_fnGetCapabilities,
829         IMediaSeeking_fnCheckCapabilities,
830         IMediaSeeking_fnIsFormatSupported,
831         IMediaSeeking_fnQueryPreferredFormat,
832         IMediaSeeking_fnGetTimeFormat,
833         IMediaSeeking_fnIsUsingTimeFormat,
834         IMediaSeeking_fnSetTimeFormat,
835         IMediaSeeking_fnGetDuration,
836         IMediaSeeking_fnGetStopPosition,
837         IMediaSeeking_fnGetCurrentPosition,
838         IMediaSeeking_fnConvertTimeFormat,
839         IMediaSeeking_fnSetPositions,
840         IMediaSeeking_fnGetPositions,
841         IMediaSeeking_fnGetAvailable,
842         IMediaSeeking_fnSetRate,
843         IMediaSeeking_fnGetRate,
844         IMediaSeeking_fnGetPreroll,
845 };
846
847
848
849 HRESULT CPassThruImpl_InitIMediaSeeking( CPassThruImpl* pImpl )
850 {
851         TRACE("(%p)\n",pImpl);
852         ICOM_VTBL(&pImpl->mseek) = &imseek;
853
854         return NOERROR;
855 }
856
857 void CPassThruImpl_UninitIMediaSeeking( CPassThruImpl* pImpl )
858 {
859         TRACE("(%p)\n",pImpl);
860 }
861
862 #undef QUERYSEEKPASS