Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

main.cpp

00001 /*****************************************************************************
00002  * main.cpp: ActiveX control for VLC
00003  *****************************************************************************
00004  * Copyright (C) 2005 the VideoLAN team
00005  *
00006  * Authors: Damien Fouilleul <[email protected]>
00007  *
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00021  *****************************************************************************/
00022 
00023 #include "plugin.h"
00024 
00025 #include <comcat.h>
00026 #include <windows.h>
00027 #include <shlwapi.h>
00028 
00029 using namespace std;
00030 
00031 #define COMPANY_STR "VideoLAN"
00032 #define PROGRAM_STR "VLCPlugin"
00033 #define VERSION_MAJOR_STR "1"
00034 #define VERSION_MINOR_STR "0"
00035 #define DESCRIPTION "VideoLAN VLC ActiveX Plugin"
00036 
00037 #define THREADING_MODEL "Apartment"
00038 #define MISC_STATUS     "131473"
00039 
00040 #define PROGID_STR COMPANY_STR"."PROGRAM_STR
00041 #define VERS_PROGID_STR COMPANY_STR"."PROGRAM_STR"."VERSION_MAJOR_STR
00042 #define VERSION_STR VERSION_MAJOR_STR"."VERSION_MINOR_STR
00043 
00044 #define GUID_STRLEN 39
00045 
00046 /*
00047 ** MingW headers do not declare those
00048 */
00049 extern const CATID CATID_SafeForInitializing;
00050 extern const CATID CATID_SafeForScripting;
00051 
00052 static LONG i_class_ref= 0;
00053 static HINSTANCE h_instance= 0;
00054 
00055 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
00056 {
00057     HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
00058 
00059     *ppv = NULL;
00060 
00061     if( CLSID_VLCPlugin == rclsid )
00062     {
00063         VLCPluginClass *plugin = new VLCPluginClass(&i_class_ref, h_instance);
00064         hr = plugin->QueryInterface(riid, ppv);
00065         plugin->Release();
00066     }
00067     return hr;
00068 };
00069 
00070 STDAPI DllCanUnloadNow(VOID)
00071 {
00072     return (0 == i_class_ref) ? S_OK: S_FALSE;
00073 };
00074 
00075 static LPCTSTR TStrFromGUID(REFGUID clsid)
00076 {
00077     LPOLESTR oleStr;
00078 
00079     if( FAILED(StringFromIID(clsid, &oleStr)) )
00080         return NULL;
00081 
00082     //check whether TCHAR and OLECHAR are both either ANSI or UNICODE
00083     if( sizeof(TCHAR) == sizeof(OLECHAR) )
00084         return (LPCTSTR)oleStr;
00085 
00086     LPTSTR pct_CLSID = NULL;
00087 #ifndef OLE2ANSI
00088     size_t len = WideCharToMultiByte(CP_ACP, 0, oleStr, -1, NULL, 0, NULL, NULL);
00089     if( len > 0 )
00090     {
00091         pct_CLSID = (char *)CoTaskMemAlloc(len);
00092         WideCharToMultiByte(CP_ACP, 0, oleStr, -1, pct_CLSID, len, NULL, NULL);
00093     }
00094 #else
00095     size_t len = MutiByteToWideChar(CP_ACP, 0, oleStr, -1, NULL, 0);
00096     if( len > 0 )
00097     {
00098         clsidStr = (wchar_t *)CoTaskMemAlloc(len*sizeof(wchar_t));
00099         MultiByteToWideChar(CP_ACP, 0, oleStr, -1, pct_CLSID, len);
00100     }
00101 #endif
00102     CoTaskMemFree(oleStr);
00103     return pct_CLSID;
00104 };
00105 
00106 static HKEY keyCreate(HKEY parentKey, LPCTSTR keyName)
00107 {
00108     HKEY childKey;
00109     if( ERROR_SUCCESS == RegCreateKeyEx(parentKey, keyName, 0, NULL,
00110                 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &childKey, NULL) )
00111     {
00112         return childKey;
00113     }
00114     return NULL;
00115 };
00116 
00117 STDAPI DllUnregisterServer(VOID)
00118 {
00119     // unregister type lib from the registry
00120     UnRegisterTypeLib(LIBID_AXVLC, 1, 0, LOCALE_NEUTRAL, SYS_WIN32);
00121 
00122     // remove component categories we supports
00123     ICatRegister *pcr;
00124     if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr, 
00125             NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {
00126         CATID implCategories[] = {
00127             CATID_Control,
00128             CATID_PersistsToPropertyBag,
00129             CATID_SafeForInitializing,
00130             CATID_SafeForScripting,
00131         };
00132 
00133         pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin,
00134                 sizeof(implCategories)/sizeof(CATID), implCategories);
00135         pcr->Release();
00136     }
00137 
00138     SHDeleteKey(HKEY_CLASSES_ROOT, TEXT(VERS_PROGID_STR));
00139     SHDeleteKey(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));
00140 
00141     LPCTSTR psz_CLSID = TStrFromGUID(CLSID_VLCPlugin);
00142 
00143     if( NULL == psz_CLSID )
00144         return E_OUTOFMEMORY;
00145 
00146     HKEY hClsIDKey;
00147     if( ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_WRITE, &hClsIDKey) )
00148     {
00149         SHDeleteKey(hClsIDKey, psz_CLSID);
00150         RegCloseKey(hClsIDKey);
00151     }
00152     CoTaskMemFree((void *)psz_CLSID);
00153 
00154     return S_OK;
00155 };
00156 
00157 STDAPI DllRegisterServer(VOID)
00158 {
00159     DllUnregisterServer();
00160 
00161     char DllPath[MAX_PATH];
00162     DWORD DllPathLen= GetModuleFileName(h_instance, DllPath, sizeof(DllPath)) ;
00163         if( 0 == DllPathLen )
00164         return E_UNEXPECTED;
00165 
00166     LPCTSTR psz_CLSID = TStrFromGUID(CLSID_VLCPlugin);
00167 
00168     if( NULL == psz_CLSID )
00169         return E_OUTOFMEMORY;
00170 
00171     HKEY hBaseKey;
00172 
00173     if( ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_CREATE_SUB_KEY, &hBaseKey) )
00174         return SELFREG_E_CLASS;
00175 
00176     HKEY hClassKey = keyCreate(hBaseKey, psz_CLSID);
00177     if( NULL != hClassKey )
00178     {
00179         HKEY hSubKey;
00180 
00181         // default key value
00182         RegSetValueEx(hClassKey, NULL, 0, REG_SZ,
00183                 (const BYTE*)DESCRIPTION, sizeof(DESCRIPTION));
00184 
00185         // Control key value
00186         hSubKey = keyCreate(hClassKey, TEXT("Control"));
00187         RegCloseKey(hSubKey);
00188 
00189         // Insertable key value
00190         //hSubKey = keyCreate(hClassKey, TEXT("Insertable"));
00191         //RegCloseKey(hSubKey);
00192 
00193         // ToolboxBitmap32 key value
00194         hSubKey = keyCreate(hClassKey, TEXT("ToolboxBitmap32"));
00195         strcpy(DllPath+DllPathLen, ",1");
00196         RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
00197                 (const BYTE*)DllPath, DllPathLen+2);
00198         DllPath[DllPathLen] = '\0';
00199         RegCloseKey(hSubKey);
00200 
00201 #ifdef BUILD_LOCALSERVER
00202         // LocalServer32 key value
00203         hSubKey = keyCreate(hClassKey, TEXT("LocalServer32"));
00204         RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
00205                 (const BYTE*)DllPath, DllPathLen);
00206         RegCloseKey(hSubKey);
00207 #else
00208         // InprocServer32 key value
00209         hSubKey = keyCreate(hClassKey, TEXT("InprocServer32"));
00210         RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
00211                 (const BYTE*)DllPath, DllPathLen);
00212         RegSetValueEx(hSubKey, TEXT("ThreadingModel"), 0, REG_SZ,
00213                 (const BYTE*)THREADING_MODEL, sizeof(THREADING_MODEL));
00214         RegCloseKey(hSubKey);
00215 #endif
00216 
00217         // MiscStatus key value
00218         hSubKey = keyCreate(hClassKey, TEXT("MiscStatus\\1"));
00219         RegSetValueEx(hSubKey, NULL, 0, REG_SZ, (const BYTE*)MISC_STATUS, sizeof(MISC_STATUS));
00220         RegCloseKey(hSubKey);
00221 
00222         // Programmable key value
00223         hSubKey = keyCreate(hClassKey, TEXT("Programmable"));
00224         RegCloseKey(hSubKey);
00225 
00226         // ProgID key value
00227         hSubKey = keyCreate(hClassKey, TEXT("ProgID"));
00228         RegSetValueEx(hSubKey, NULL, 0, REG_SZ, 
00229                 (const BYTE*)VERS_PROGID_STR, sizeof(VERS_PROGID_STR));
00230         RegCloseKey(hSubKey);
00231 
00232         // VersionIndependentProgID key value
00233         hSubKey = keyCreate(hClassKey, TEXT("VersionIndependentProgID"));
00234         RegSetValueEx(hSubKey, NULL, 0, REG_SZ, 
00235                 (const BYTE*)PROGID_STR, sizeof(PROGID_STR));
00236         RegCloseKey(hSubKey);
00237 
00238         // Version key value
00239         hSubKey = keyCreate(hClassKey, TEXT("Version"));
00240         RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
00241                 (const BYTE*)VERSION_STR, sizeof(VERSION_STR));
00242         RegCloseKey(hSubKey);
00243 
00244         // TypeLib key value
00245         LPCTSTR psz_LIBID = TStrFromGUID(LIBID_AXVLC);
00246         if( NULL != psz_LIBID )
00247         {
00248             hSubKey = keyCreate(hClassKey, TEXT("TypeLib"));
00249             RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
00250                     (const BYTE*)psz_LIBID, sizeof(TCHAR)*GUID_STRLEN);
00251             RegCloseKey(hSubKey);
00252         }
00253         RegCloseKey(hClassKey);
00254     }
00255     RegCloseKey(hBaseKey);
00256 
00257     hBaseKey = keyCreate(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));
00258     if( NULL != hBaseKey )
00259     {
00260         // default key value
00261         RegSetValueEx(hBaseKey, NULL, 0, REG_SZ,
00262                 (const BYTE*)DESCRIPTION, sizeof(DESCRIPTION));
00263 
00264         HKEY hSubKey = keyCreate(hBaseKey, TEXT("CLSID"));
00265         if( NULL != hSubKey )
00266         {
00267             // default key value
00268             RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
00269                     (const BYTE*)psz_CLSID, sizeof(TCHAR)*GUID_STRLEN);
00270 
00271             RegCloseKey(hSubKey);
00272         }
00273         hSubKey = keyCreate(hBaseKey, TEXT("CurVer"));
00274         if( NULL != hSubKey )
00275         {
00276             // default key value
00277             RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
00278                     (const BYTE*)VERS_PROGID_STR, sizeof(VERS_PROGID_STR));
00279 
00280             RegCloseKey(hSubKey);
00281         }
00282         RegCloseKey(hBaseKey);
00283     }
00284 
00285     hBaseKey = keyCreate(HKEY_CLASSES_ROOT, TEXT(VERS_PROGID_STR));
00286     if( NULL != hBaseKey )
00287     {
00288         // default key value
00289         RegSetValueEx(hBaseKey, NULL, 0, REG_SZ,
00290                 (const BYTE*)DESCRIPTION, sizeof(DESCRIPTION));
00291 
00292         HKEY hSubKey = keyCreate(hBaseKey, TEXT("CLSID"));
00293         if( NULL != hSubKey )
00294         {
00295             // default key value
00296             RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
00297                     (const BYTE*)psz_CLSID, sizeof(TCHAR)*GUID_STRLEN);
00298 
00299             RegCloseKey(hSubKey);
00300         }
00301         //hSubKey = keyCreate(hBaseKey, TEXT("Insertable"));
00302         //RegCloseKey(hSubKey);
00303  
00304         RegCloseKey(hBaseKey);
00305     }
00306 
00307     // indicate which component categories we support
00308     ICatRegister *pcr;
00309     if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr, 
00310             NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {
00311         CATID implCategories[] = {
00312             CATID_Control,
00313             CATID_PersistsToPropertyBag,
00314             CATID_SafeForInitializing,
00315             CATID_SafeForScripting,
00316         };
00317 
00318         pcr->RegisterClassImplCategories(CLSID_VLCPlugin,
00319                 sizeof(implCategories)/sizeof(CATID), implCategories);
00320         pcr->Release();
00321     }
00322 
00323     // register type lib into the registry
00324     ITypeLib *typeLib;
00325 
00326 #ifdef BUILD_LOCALSERVER
00327     // replace .exe by .tlb
00328     strcpy(DllPath+DllPathLen-4, ".tlb");
00329 #endif
00330     
00331 #ifndef OLE2ANSI
00332     size_t typeLibPathLen = MultiByteToWideChar(CP_ACP, 0, DllPath, -1, NULL, 0);
00333     if( typeLibPathLen > 0 )
00334     {
00335         LPOLESTR typeLibPath = (LPOLESTR)CoTaskMemAlloc(typeLibPathLen*sizeof(wchar_t));
00336         MultiByteToWideChar(CP_ACP, 0, DllPath, DllPathLen, typeLibPath, typeLibPathLen);
00337         if( FAILED(LoadTypeLibEx(typeLibPath, REGKIND_REGISTER, &typeLib)) )
00338 #ifndef BUILD_LOCALSERVER
00339             return SELFREG_E_TYPELIB;
00340         typeLib->Release();
00341 #endif
00342         CoTaskMemFree((void *)typeLibPath);
00343     }
00344 #else
00345     if( FAILED(LoadTypeLibEx((LPOLESTR)DllPath, REGKIND_REGISTER, &typeLib)) )
00346         return SELFREG_E_TYPELIB;
00347     typeLib->Release();
00348 #endif
00349 
00350     CoTaskMemFree((void *)psz_CLSID);
00351 
00352     return S_OK;
00353 };
00354 
00355 #ifdef BUILD_LOCALSERVER
00356 
00357 /*
00358 ** easier to debug an application than a DLL on cygwin GDB :)
00359 */
00360 #include <iostream>
00361 
00362 STDAPI_(int) WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
00363 {
00364     MSG msg;
00365 
00366     if( FAILED(OleInitialize(NULL)) )
00367     {
00368         cerr << "cannot initialize OLE" << endl;
00369         return 1;
00370     }
00371 
00372     h_instance = hInst;
00373 
00374     if( FAILED(DllRegisterServer()) )
00375     {
00376         cerr << "cannot register Local Server" << endl;
00377         return 1;
00378     }
00379 
00380     IUnknown *classProc = NULL;
00381 
00382     if( FAILED(DllGetClassObject(CLSID_VLCPlugin, IID_IUnknown, (LPVOID *)&classProc)) )
00383         return 0;
00384  
00385     DWORD dwRegisterClassObject;
00386 
00387     if( FAILED(CoRegisterClassObject(CLSID_VLCPlugin, classProc,
00388         CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegisterClassObject)) )
00389         return 0;
00390 
00391     DWORD dwRegisterActiveObject;
00392 
00393     if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin,
00394                     ACTIVEOBJECT_WEAK, &dwRegisterActiveObject)) )
00395         return 0;
00396 
00397     classProc->Release();
00398 
00399     /*
00400     * Polling messages from event queue
00401     */
00402     while( S_FALSE == DllCanUnloadNow() )
00403     {
00404         while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
00405         {
00406             if( msg.message == WM_QUIT )
00407                 break;  // Leave the PeekMessage while() loop
00408 
00409             /*if(TranslateAccelerator(ghwndApp, ghAccel, &msg))
00410                 continue;*/
00411 
00412             TranslateMessage(&msg);
00413             DispatchMessage(&msg);
00414         }
00415 
00416         if(msg.message == WM_QUIT)
00417             break;  // Leave the for() loop
00418 
00419         WaitMessage();
00420     }
00421 
00422     if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject, NULL)) )
00423         CoRevokeClassObject(dwRegisterClassObject);
00424 
00425     // Reached on WM_QUIT message
00426     CoUninitialize();
00427     return ((int) msg.wParam);
00428 };
00429 
00430 #else
00431 
00432 STDAPI_(BOOL) DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved )
00433 {
00434     switch( fdwReason )
00435     {
00436         case DLL_PROCESS_ATTACH:
00437             h_instance = (HINSTANCE)hModule;
00438             break;
00439 
00440         default:
00441             break;
00442     }
00443     return TRUE;
00444 };
00445 
00446 #endif
00447 

Generated on Tue Dec 20 10:14:18 2005 for vlc-0.8.4a by  doxygen 1.4.2