Support unrar64.dll
[xy_vsfilter.git] / src / filters / BaseClasses / dllsetup.cpp
blob5592f1c35935e63aa920d0ec6af0451f4f92adeb
1 //------------------------------------------------------------------------------
2 // File: DllSetup.cpp
3 //
4 // Desc: DirectShow base classes.
5 //
6 // Copyright (c) 1992-2002 Microsoft Corporation. All rights reserved.
7 //------------------------------------------------------------------------------
10 #include <streams.h>
12 //---------------------------------------------------------------------------
13 // defines
15 #define MAX_KEY_LEN 260
18 //---------------------------------------------------------------------------
19 // externally defined functions/variable
21 extern int g_cTemplates;
22 extern CFactoryTemplate g_Templates[];
24 //---------------------------------------------------------------------------
26 // EliminateSubKey
28 // Try to enumerate all keys under this one.
29 // if we find anything, delete it completely.
30 // Otherwise just delete it.
32 // note - this was pinched/duplicated from
33 // Filgraph\Mapper.cpp - so should it be in
34 // a lib somewhere?
36 //---------------------------------------------------------------------------
38 STDAPI
39 EliminateSubKey( HKEY hkey, LPTSTR strSubKey )
41 HKEY hk;
42 if (0 == lstrlen(strSubKey) ) {
43 // defensive approach
44 return E_FAIL;
47 LONG lreturn = RegOpenKeyEx( hkey
48 , strSubKey
49 , 0
50 , MAXIMUM_ALLOWED
51 , &hk );
53 ASSERT( lreturn == ERROR_SUCCESS
54 || lreturn == ERROR_FILE_NOT_FOUND
55 || lreturn == ERROR_INVALID_HANDLE );
57 if( ERROR_SUCCESS == lreturn )
59 // Keep on enumerating the first (zero-th)
60 // key and deleting that
62 for( ; ; )
64 TCHAR Buffer[MAX_KEY_LEN];
65 DWORD dw = MAX_KEY_LEN;
66 FILETIME ft;
68 lreturn = RegEnumKeyEx( hk
69 , 0
70 , Buffer
71 , &dw
72 , NULL
73 , NULL
74 , NULL
75 , &ft);
77 ASSERT( lreturn == ERROR_SUCCESS
78 || lreturn == ERROR_NO_MORE_ITEMS );
80 if( ERROR_SUCCESS == lreturn )
82 EliminateSubKey(hk, Buffer);
84 else
86 break;
90 RegCloseKey(hk);
91 RegDeleteKey(hkey, strSubKey);
94 return NOERROR;
98 //---------------------------------------------------------------------------
100 // AMovieSetupRegisterServer()
102 // registers specfied file "szFileName" as server for
103 // CLSID "clsServer". A description is also required.
104 // The ThreadingModel and ServerType are optional, as
105 // they default to InprocServer32 (i.e. dll) and Both.
107 //---------------------------------------------------------------------------
109 STDAPI
110 AMovieSetupRegisterServer( CLSID clsServer
111 , LPCWSTR szDescription
112 , LPCWSTR szFileName
113 , LPCWSTR szThreadingModel = L"Both"
114 , LPCWSTR szServerType = L"InprocServer32" )
116 // temp buffer
118 TCHAR achTemp[MAX_PATH];
120 // convert CLSID uuid to string and write
121 // out subkey as string - CLSID\{}
123 OLECHAR szCLSID[CHARS_IN_GUID];
124 HRESULT hr = StringFromGUID2( clsServer
125 , szCLSID
126 , CHARS_IN_GUID );
127 ASSERT( SUCCEEDED(hr) );
129 // create key
131 HKEY hkey;
132 wsprintf( achTemp, TEXT("CLSID\\%ls"), szCLSID );
133 LONG lreturn = RegCreateKey( HKEY_CLASSES_ROOT
134 , (LPCTSTR)achTemp
135 , &hkey );
136 if( ERROR_SUCCESS != lreturn )
138 return AmHresultFromWin32(lreturn);
141 // set description string
144 wsprintf( achTemp, TEXT("%ls"), szDescription );
145 lreturn = RegSetValue( hkey
146 , (LPCTSTR)NULL
147 , REG_SZ
148 , achTemp
149 , sizeof(achTemp) );
150 if( ERROR_SUCCESS != lreturn )
152 RegCloseKey( hkey );
153 return AmHresultFromWin32(lreturn);
156 // create CLSID\\{"CLSID"}\\"ServerType" key,
157 // using key to CLSID\\{"CLSID"} passed back by
158 // last call to RegCreateKey().
160 HKEY hsubkey;
162 wsprintf( achTemp, TEXT("%ls"), szServerType );
163 lreturn = RegCreateKey( hkey
164 , achTemp
165 , &hsubkey );
166 if( ERROR_SUCCESS != lreturn )
168 RegCloseKey( hkey );
169 return AmHresultFromWin32(lreturn);
172 // set Server string
174 wsprintf( achTemp, TEXT("%ls"), szFileName );
175 lreturn = RegSetValue( hsubkey
176 , (LPCTSTR)NULL
177 , REG_SZ
178 , (LPCTSTR)achTemp
179 , sizeof(TCHAR) * (lstrlen(achTemp)+1) );
180 if( ERROR_SUCCESS != lreturn )
182 RegCloseKey( hkey );
183 RegCloseKey( hsubkey );
184 return AmHresultFromWin32(lreturn);
187 wsprintf( achTemp, TEXT("%ls"), szThreadingModel );
188 lreturn = RegSetValueEx( hsubkey
189 , TEXT("ThreadingModel")
190 , 0L
191 , REG_SZ
192 , (CONST BYTE *)achTemp
193 , sizeof(TCHAR) * (lstrlen(achTemp)+1) );
195 // close hkeys
197 RegCloseKey( hkey );
198 RegCloseKey( hsubkey );
200 // and return
202 return HRESULT_FROM_WIN32(lreturn);
207 //---------------------------------------------------------------------------
209 // AMovieSetupUnregisterServer()
211 // default ActiveMovie dll setup function
212 // - to use must be called from an exported
213 // function named DllRegisterServer()
215 //---------------------------------------------------------------------------
217 STDAPI
218 AMovieSetupUnregisterServer( CLSID clsServer )
220 // convert CLSID uuid to string and write
221 // out subkey CLSID\{}
223 OLECHAR szCLSID[CHARS_IN_GUID];
224 HRESULT hr = StringFromGUID2( clsServer
225 , szCLSID
226 , CHARS_IN_GUID );
227 ASSERT( SUCCEEDED(hr) );
229 TCHAR achBuffer[MAX_KEY_LEN];
230 wsprintf( achBuffer, TEXT("CLSID\\%ls"), szCLSID );
232 // delete subkey
235 hr = EliminateSubKey( HKEY_CLASSES_ROOT, achBuffer );
236 ASSERT( SUCCEEDED(hr) );
238 // return
240 return NOERROR;
244 //---------------------------------------------------------------------------
246 // AMovieSetupRegisterFilter through IFilterMapper2
248 //---------------------------------------------------------------------------
250 STDAPI
251 AMovieSetupRegisterFilter2( const AMOVIESETUP_FILTER * const psetupdata
252 , IFilterMapper2 * pIFM2
253 , BOOL bRegister )
255 DbgLog((LOG_TRACE, 3, TEXT("= AMovieSetupRegisterFilter")));
257 // check we've got data
259 if( NULL == psetupdata ) return S_FALSE;
262 // unregister filter
263 // (as pins are subkeys of filter's CLSID key
264 // they do not need to be removed separately).
266 DbgLog((LOG_TRACE, 3, TEXT("= = unregister filter")));
267 HRESULT hr = pIFM2->UnregisterFilter(
268 0, // default category
269 0, // default instance name
270 *psetupdata->clsID );
273 if( bRegister )
275 REGFILTER2 rf2;
276 rf2.dwVersion = 1;
277 rf2.dwMerit = psetupdata->dwMerit;
278 rf2.cPins = psetupdata->nPins;
279 rf2.rgPins = psetupdata->lpPin;
281 // register filter
283 DbgLog((LOG_TRACE, 3, TEXT("= = register filter")));
284 hr = pIFM2->RegisterFilter(*psetupdata->clsID
285 , psetupdata->strName
286 , 0 // moniker
287 , 0 // category
288 , NULL // instance
289 , &rf2);
292 // handle one acceptable "error" - that
293 // of filter not being registered!
294 // (couldn't find a suitable #define'd
295 // name for the error!)
297 if( 0x80070002 == hr)
298 return NOERROR;
299 else
300 return hr;
304 //---------------------------------------------------------------------------
306 // RegisterAllServers()
308 //---------------------------------------------------------------------------
310 STDAPI
311 RegisterAllServers( LPCWSTR szFileName, BOOL bRegister )
313 HRESULT hr = NOERROR;
315 for( int i = 0; i < g_cTemplates; i++ )
317 // get i'th template
319 const CFactoryTemplate *pT = &g_Templates[i];
321 DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"),
322 (LPCWSTR)pT->m_Name ));
324 // register CLSID and InprocServer32
326 if( bRegister )
328 hr = AMovieSetupRegisterServer( *(pT->m_ClsID)
329 , (LPCWSTR)pT->m_Name
330 , szFileName );
332 else
334 hr = AMovieSetupUnregisterServer( *(pT->m_ClsID) );
337 // check final error for this pass
338 // and break loop if we failed
340 if( FAILED(hr) )
341 break;
344 return hr;
348 //---------------------------------------------------------------------------
350 // AMovieDllRegisterServer2()
352 // default ActiveMovie dll setup function
353 // - to use must be called from an exported
354 // function named DllRegisterServer()
356 // this function is table driven using the
357 // static members of the CFactoryTemplate
358 // class defined in the dll.
360 // it registers the Dll as the InprocServer32
361 // and then calls the IAMovieSetup.Register
362 // method.
364 //---------------------------------------------------------------------------
366 STDAPI
367 AMovieDllRegisterServer2( BOOL bRegister )
369 HRESULT hr = NOERROR;
371 DbgLog((LOG_TRACE, 2, TEXT("AMovieDllRegisterServer2()")));
373 // get file name (where g_hInst is the
374 // instance handle of the filter dll)
376 WCHAR achFileName[MAX_PATH];
378 // WIN95 doesn't support GetModuleFileNameW
381 char achTemp[MAX_PATH];
383 DbgLog((LOG_TRACE, 2, TEXT("- get module file name")));
385 // g_hInst handle is set in our dll entry point. Make sure
386 // DllEntryPoint in dllentry.cpp is called
387 ASSERT(g_hInst != 0);
389 if( 0 == GetModuleFileNameA( g_hInst
390 , achTemp
391 , sizeof(achTemp) ) )
393 // we've failed!
394 DWORD dwerr = GetLastError();
395 return AmHresultFromWin32(dwerr);
398 MultiByteToWideChar( CP_ACP
399 , 0L
400 , achTemp
401 , lstrlenA(achTemp) + 1
402 , achFileName
403 , NUMELMS(achFileName) );
407 // first registering, register all OLE servers
409 if( bRegister )
411 DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers")));
412 hr = RegisterAllServers( achFileName, TRUE );
416 // next, register/unregister all filters
419 if( SUCCEEDED(hr) )
421 // init is ref counted so call just in case
422 // we're being called cold.
424 DbgLog((LOG_TRACE, 2, TEXT("- CoInitialize")));
425 hr = CoInitialize( (LPVOID)NULL );
426 ASSERT( SUCCEEDED(hr) );
428 // get hold of IFilterMapper2
430 DbgLog((LOG_TRACE, 2, TEXT("- obtain IFilterMapper2")));
431 IFilterMapper2 *pIFM2 = 0;
432 IFilterMapper *pIFM = 0;
433 hr = CoCreateInstance( CLSID_FilterMapper2
434 , NULL
435 , CLSCTX_INPROC_SERVER
436 , IID_IFilterMapper2
437 , (void **)&pIFM2 );
438 if(FAILED(hr))
440 DbgLog((LOG_TRACE, 2, TEXT("- trying IFilterMapper instead")));
442 hr = CoCreateInstance(
443 CLSID_FilterMapper,
444 NULL,
445 CLSCTX_INPROC_SERVER,
446 IID_IFilterMapper,
447 (void **)&pIFM);
449 if( SUCCEEDED(hr) )
451 // scan through array of CFactoryTemplates
452 // registering servers and filters.
454 DbgLog((LOG_TRACE, 2, TEXT("- register Filters")));
455 for( int i = 0; i < g_cTemplates; i++ )
457 // get i'th template
459 const CFactoryTemplate *pT = &g_Templates[i];
461 if( NULL != pT->m_pAMovieSetup_Filter )
463 DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"), (LPCWSTR)pT->m_Name ));
465 if(pIFM2)
467 hr = AMovieSetupRegisterFilter2( pT->m_pAMovieSetup_Filter, pIFM2, bRegister );
469 else
471 hr = AMovieSetupRegisterFilter( pT->m_pAMovieSetup_Filter, pIFM, bRegister );
475 // check final error for this pass
476 // and break loop if we failed
478 if( FAILED(hr) )
479 break;
482 // release interface
484 if(pIFM2)
485 pIFM2->Release();
486 else
487 pIFM->Release();
491 // and clear up
493 CoFreeUnusedLibraries();
494 CoUninitialize();
498 // if unregistering, unregister all OLE servers
500 if( SUCCEEDED(hr) && !bRegister )
502 DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers")));
503 hr = RegisterAllServers( achFileName, FALSE );
506 DbgLog((LOG_TRACE, 2, TEXT("- return %0x"), hr));
507 return hr;
511 //---------------------------------------------------------------------------
513 // AMovieDllRegisterServer()
515 // default ActiveMovie dll setup function
516 // - to use must be called from an exported
517 // function named DllRegisterServer()
519 // this function is table driven using the
520 // static members of the CFactoryTemplate
521 // class defined in the dll.
523 // it registers the Dll as the InprocServer32
524 // and then calls the IAMovieSetup.Register
525 // method.
527 //---------------------------------------------------------------------------
530 STDAPI
531 AMovieDllRegisterServer( void )
533 HRESULT hr = NOERROR;
535 // get file name (where g_hInst is the
536 // instance handle of the filter dll)
538 WCHAR achFileName[MAX_PATH];
541 // WIN95 doesn't support GetModuleFileNameW
543 char achTemp[MAX_PATH];
545 if( 0 == GetModuleFileNameA( g_hInst
546 , achTemp
547 , sizeof(achTemp) ) )
549 // we've failed!
550 DWORD dwerr = GetLastError();
551 return AmHresultFromWin32(dwerr);
554 MultiByteToWideChar( CP_ACP
555 , 0L
556 , achTemp
557 , lstrlenA(achTemp) + 1
558 , achFileName
559 , NUMELMS(achFileName) );
562 // scan through array of CFactoryTemplates
563 // registering servers and filters.
565 for( int i = 0; i < g_cTemplates; i++ )
567 // get i'th template
569 const CFactoryTemplate *pT = &g_Templates[i];
571 // register CLSID and InprocServer32
573 hr = AMovieSetupRegisterServer( *(pT->m_ClsID)
574 , (LPCWSTR)pT->m_Name
575 , achFileName );
577 // instantiate all servers and get hold of
578 // IAMovieSetup, if implemented, and call
579 // IAMovieSetup.Register() method
581 if( SUCCEEDED(hr) && (NULL != pT->m_lpfnNew) )
583 // instantiate object
585 PAMOVIESETUP psetup;
586 hr = CoCreateInstance( *(pT->m_ClsID)
588 , CLSCTX_INPROC_SERVER
589 , IID_IAMovieSetup
590 , reinterpret_cast<void**>(&psetup) );
591 if( SUCCEEDED(hr) )
593 hr = psetup->Unregister();
594 if( SUCCEEDED(hr) )
595 hr = psetup->Register();
596 psetup->Release();
598 else
600 if( (E_NOINTERFACE == hr )
601 || (VFW_E_NEED_OWNER == hr ) )
602 hr = NOERROR;
606 // check final error for this pass
607 // and break loop if we failed
609 if( FAILED(hr) )
610 break;
612 } // end-for
614 return hr;
618 //---------------------------------------------------------------------------
620 // AMovieDllUnregisterServer()
622 // default ActiveMovie dll uninstall function
623 // - to use must be called from an exported
624 // function named DllRegisterServer()
626 // this function is table driven using the
627 // static members of the CFactoryTemplate
628 // class defined in the dll.
630 // it calls the IAMovieSetup.Unregister
631 // method and then unregisters the Dll
632 // as the InprocServer32
634 //---------------------------------------------------------------------------
636 STDAPI
637 AMovieDllUnregisterServer()
639 // initialize return code
641 HRESULT hr = NOERROR;
643 // scan through CFactory template and unregister
644 // all OLE servers and filters.
646 for( int i = g_cTemplates; i--; )
648 // get i'th template
650 const CFactoryTemplate *pT = &g_Templates[i];
652 // check method exists
654 if( NULL != pT->m_lpfnNew )
656 // instantiate object
658 PAMOVIESETUP psetup;
659 hr = CoCreateInstance( *(pT->m_ClsID)
661 , CLSCTX_INPROC_SERVER
662 , IID_IAMovieSetup
663 , reinterpret_cast<void**>(&psetup) );
664 if( SUCCEEDED(hr) )
666 hr = psetup->Unregister();
667 psetup->Release();
669 else
671 if( (E_NOINTERFACE == hr )
672 || (VFW_E_NEED_OWNER == hr ) )
673 hr = NOERROR;
677 // unregister CLSID and InprocServer32
679 if( SUCCEEDED(hr) )
681 hr = AMovieSetupUnregisterServer( *(pT->m_ClsID) );
684 // check final error for this pass
685 // and break loop if we failed
687 if( FAILED(hr) )
688 break;
691 return hr;