1 /*****************************************************************************
2 * main.cpp: ActiveX control for VLC
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
6 * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program 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
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
37 #define COMPANY_STR "VideoLAN"
38 #define PROGRAM_STR "VLCPlugin"
39 #define DESCRIPTION "VLC ActiveX Plugin and IE Web Plugin"
41 #define THREADING_MODEL "Apartment"
42 #define MISC_STATUS "131473"
44 #define PROGID_STR COMPANY_STR"."PROGRAM_STR
46 #define GUID_STRLEN 39
49 ** MingW headers & libs do not declare those
51 static DEFINE_GUID(_CATID_InternetAware
, \
52 0x0DE86A58, 0x2BAA, 0x11CF, 0xA2, 0x29, 0x00,0xAA,0x00,0x3D,0x73,0x52);
53 static DEFINE_GUID(_CATID_SafeForInitializing
, \
54 0x7DD95802, 0x9882, 0x11CF, 0x9F, 0xA9, 0x00,0xAA,0x00,0x6C,0x42,0xC4);
55 static DEFINE_GUID(_CATID_SafeForScripting
, \
56 0x7DD95801, 0x9882, 0x11CF, 0x9F, 0xA9, 0x00,0xAA,0x00,0x6C,0x42,0xC4);
58 static LONG i_class_ref
= 0;
59 static HINSTANCE h_instance
= 0;
61 HMODULE
DllGetModule()
66 STDAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
68 HRESULT hr
= CLASS_E_CLASSNOTAVAILABLE
;
72 if( (CLSID_VLCPlugin
== rclsid
) || (CLSID_VLCPlugin2
== rclsid
) )
74 VLCPluginClass
*plugin
=
75 new VLCPluginClass(&i_class_ref
, h_instance
, rclsid
);
76 hr
= plugin
->QueryInterface(riid
, ppv
);
82 STDAPI
DllCanUnloadNow(VOID
)
84 return (0 == i_class_ref
) ? S_OK
: S_FALSE
;
87 static inline HKEY
keyCreate(HKEY parentKey
, LPCTSTR keyName
)
90 if( ERROR_SUCCESS
== RegCreateKeyEx(parentKey
, keyName
, 0, NULL
,
91 REG_OPTION_NON_VOLATILE
, KEY_ALL_ACCESS
, NULL
, &childKey
, NULL
) )
98 static inline HKEY
keySet(HKEY hKey
, LPCTSTR valueName
,
99 const void *s
, size_t len
, DWORD dwType
= REG_SZ
)
103 RegSetValueEx(hKey
, valueName
, 0, dwType
, (const BYTE
*)s
, len
);
108 static inline HKEY
keySetDef(HKEY hKey
,
109 const void *s
, size_t len
, DWORD dwType
= REG_SZ
)
111 return keySet(hKey
, NULL
, s
, len
, dwType
);
114 static inline HKEY
keySetDef(HKEY hKey
, LPCTSTR s
)
116 return keySetDef(hKey
, s
, sizeof(TCHAR
)*(_tcslen(s
)+1), REG_SZ
);
119 static inline HKEY
keyClose(HKEY hKey
)
128 static void UnregisterProgID(REFCLSID rclsid
, unsigned int version
)
130 OLECHAR szCLSID
[GUID_STRLEN
];
132 StringFromGUID2(rclsid
, szCLSID
, GUID_STRLEN
);
134 TCHAR progId
[sizeof(PROGID_STR
)+16];
135 _stprintf(progId
, TEXT("%s.%u"), TEXT(PROGID_STR
), version
);
137 SHDeleteKey(HKEY_CLASSES_ROOT
, progId
);
140 if( ERROR_SUCCESS
== RegOpenKeyEx(HKEY_CLASSES_ROOT
, TEXT("CLSID"), 0, KEY_WRITE
, &hClsIDKey
) )
142 SHDeleteKey(hClsIDKey
, szCLSID
);
143 RegCloseKey(hClsIDKey
);
147 STDAPI
DllUnregisterServer(VOID
)
149 // unregister type lib from the registry
150 UnRegisterTypeLib(LIBID_AXVLC
, 1, 0, LOCALE_NEUTRAL
, SYS_WIN32
);
152 // remove component categories we supports
154 if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr
,
155 NULL
, CLSCTX_INPROC_SERVER
, IID_ICatRegister
, (void**)&pcr
)) ) {
156 CATID implCategories
[] = {
158 CATID_PersistsToPropertyBag
,
159 _CATID_InternetAware
,
160 _CATID_SafeForInitializing
,
161 _CATID_SafeForScripting
,
164 pcr
->UnRegisterClassImplCategories(CLSID_VLCPlugin
,
165 sizeof(implCategories
)/sizeof(CATID
), implCategories
);
166 pcr
->UnRegisterClassImplCategories(CLSID_VLCPlugin2
,
167 sizeof(implCategories
)/sizeof(CATID
), implCategories
);
171 SHDeleteKey(HKEY_CLASSES_ROOT
, TEXT(PROGID_STR
));
173 UnregisterProgID(CLSID_VLCPlugin
, 2);
174 UnregisterProgID(CLSID_VLCPlugin2
, 1);
179 static HRESULT
RegisterClassID(HKEY hParent
, REFCLSID rclsid
, unsigned int version
, BOOL isDefault
, LPCTSTR path
, size_t pathLen
)
181 TCHAR progId
[sizeof(PROGID_STR
)+16];
182 _stprintf(progId
, TEXT("%s.%u"), TEXT(PROGID_STR
), version
);
184 TCHAR description
[sizeof(DESCRIPTION
)+16];
185 _stprintf(description
, TEXT("%s v%u"), TEXT(DESCRIPTION
), version
);
189 OLECHAR szCLSID
[GUID_STRLEN
];
191 StringFromGUID2(rclsid
, szCLSID
, GUID_STRLEN
);
193 HKEY hProgKey
= keyCreate(HKEY_CLASSES_ROOT
, progId
);
194 if( NULL
!= hProgKey
)
197 keySetDef(hProgKey
, description
);
199 keyClose(keySetDef(keyCreate(hProgKey
, TEXT("CLSID")),
200 szCLSID
, sizeof(szCLSID
)));
202 //hSubKey = keyClose(keyCreate(hBaseKey, "Insertable"));
204 RegCloseKey(hProgKey
);
208 hProgKey
= keyCreate(HKEY_CLASSES_ROOT
, TEXT(PROGID_STR
));
209 if( NULL
!= hProgKey
)
212 keySetDef(hProgKey
, description
);
214 keyClose(keySetDef(keyCreate(hProgKey
, TEXT("CLSID")),
215 szCLSID
, sizeof(szCLSID
)));
217 keyClose(keySetDef(keyCreate(hProgKey
, TEXT("CurVer")),
221 hClassKey
= keyCreate(hParent
, szCLSID
);
223 if( NULL
!= hClassKey
)
226 keySetDef(hClassKey
, description
);
229 keyClose(keyCreate(hClassKey
, TEXT("Control")));
231 // Insertable key value
232 //keyClose(keyCreate(hClassKey, TEXT("Insertable")));
234 // ToolboxBitmap32 key value
236 TCHAR iconPath
[pathLen
+3];
237 memcpy(iconPath
, path
, sizeof(TCHAR
)*pathLen
);
238 _tcscpy(iconPath
+pathLen
, TEXT(",1"));
239 keyClose(keySetDef(keyCreate(hClassKey
,
240 TEXT("ToolboxBitmap32")),
241 iconPath
, sizeof(iconPath
)));
244 #ifdef BUILD_LOCALSERVER
245 // LocalServer32 key value
246 keyClose(keySetDef(keyCreate(hClassKey
,
247 TEXT("LocalServer32"), path
, sizeof(TCHAR
)*(pathLen
+1))));
249 // InprocServer32 key value
251 HKEY hSubKey
= keySetDef(keyCreate(hClassKey
,
252 TEXT("InprocServer32")),
253 path
, sizeof(TCHAR
)*(pathLen
+1));
255 TEXT("ThreadingModel"),
256 TEXT(THREADING_MODEL
), sizeof(TEXT(THREADING_MODEL
)));
261 // MiscStatus key value
262 keyClose(keySetDef(keyCreate(hClassKey
,TEXT("MiscStatus\\1")),
263 TEXT(MISC_STATUS
), sizeof(TEXT(MISC_STATUS
))));
265 // Programmable key value
266 keyClose(keyCreate(hClassKey
, TEXT("Programmable")));
269 keyClose(keySetDef(keyCreate(hClassKey
,TEXT("ProgID")),progId
));
271 // VersionIndependentProgID key value
272 keyClose(keySetDef(keyCreate(hClassKey
,
273 TEXT("VersionIndependentProgID")),
274 TEXT(PROGID_STR
), sizeof(TEXT(PROGID_STR
))));
277 keyClose(keySetDef(keyCreate(hClassKey
,TEXT("Version")),TEXT("1.0")));
280 OLECHAR szLIBID
[GUID_STRLEN
];
282 StringFromGUID2(LIBID_AXVLC
, szLIBID
, GUID_STRLEN
);
284 keyClose(keySetDef(keyCreate(hClassKey
,TEXT("TypeLib")),
285 szLIBID
, sizeof(szLIBID
)));
287 RegCloseKey(hClassKey
);
292 STDAPI
DllRegisterServer(VOID
)
294 DllUnregisterServer();
296 TCHAR DllPath
[MAX_PATH
];
297 DWORD DllPathLen
=GetModuleFileName(h_instance
, DllPath
, MAX_PATH
) ;
298 if( 0 == DllPathLen
)
300 DllPath
[MAX_PATH
-1] = '\0';
304 if( ERROR_SUCCESS
!= RegOpenKeyEx(HKEY_CLASSES_ROOT
, TEXT("CLSID"),
305 0, KEY_CREATE_SUB_KEY
, &hBaseKey
) )
306 return SELFREG_E_CLASS
;
308 RegisterClassID(hBaseKey
, CLSID_VLCPlugin
, 1, FALSE
, DllPath
, DllPathLen
);
309 RegisterClassID(hBaseKey
, CLSID_VLCPlugin2
, 2, TRUE
, DllPath
, DllPathLen
);
311 RegCloseKey(hBaseKey
);
313 // indicate which component categories we support
315 if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr
,
316 NULL
, CLSCTX_INPROC_SERVER
, IID_ICatRegister
, (void**)&pcr
)) ) {
317 CATID implCategories
[] = {
319 CATID_PersistsToPropertyBag
,
320 _CATID_InternetAware
,
321 _CATID_SafeForInitializing
,
322 _CATID_SafeForScripting
,
325 pcr
->RegisterClassImplCategories(CLSID_VLCPlugin
,
326 sizeof(implCategories
)/sizeof(CATID
), implCategories
);
327 pcr
->RegisterClassImplCategories(CLSID_VLCPlugin2
,
328 sizeof(implCategories
)/sizeof(CATID
), implCategories
);
332 #ifdef BUILD_LOCALSERVER
333 // replace .exe by .tlb
334 _tcscpy(DllPath
+DllPathLen
-4, TEXT(".tlb"));
337 // register type lib into the registry
340 HRESULT result
= LoadTypeLibEx(DllPath
, REGKIND_REGISTER
, &typeLib
);
341 if( SUCCEEDED(result
) )
347 #ifdef BUILD_LOCALSERVER
350 ** easier to debug an application than a DLL on cygwin GDB :)
354 STDAPI_(int) WinMain(HINSTANCE hInst
, HINSTANCE hPrev
, LPSTR szCmdLine
, int sw
)
358 if( FAILED(OleInitialize(NULL
)) )
360 cerr
<< "cannot initialize OLE" << endl
;
366 if( FAILED(DllRegisterServer()) )
368 cerr
<< "cannot register Local Server" << endl
;
372 IUnknown
*classProc
= NULL
;
374 if( FAILED(DllGetClassObject(CLSID_VLCPlugin
, IID_IUnknown
,
375 (LPVOID
*)&classProc
)) )
378 DWORD dwRegisterClassObject
;
379 DWORD dwRegisterClassObject2
;
381 if( FAILED(CoRegisterClassObject(CLSID_VLCPlugin
, classProc
,
382 CLSCTX_LOCAL_SERVER
, REGCLS_MULTIPLEUSE
, &dwRegisterClassObject
)) )
385 DWORD dwRegisterActiveObject
;
387 if( FAILED(RegisterActiveObject(classProc
, CLSID_VLCPlugin
,
388 ACTIVEOBJECT_WEAK
, &dwRegisterActiveObject
)) )
391 if( FAILED(RegisterActiveObject(classProc
, CLSID_VLCPlugin2
,
392 ACTIVEOBJECT_WEAK
, &dwRegisterActiveObject2
)) )
395 classProc
->Release();
398 * Polling messages from event queue
400 while( S_FALSE
== DllCanUnloadNow() )
402 while( PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
) )
404 if( msg
.message
== WM_QUIT
)
405 break; // break out PeekMessage loop
407 /*if(TranslateAccelerator(ghwndApp, ghAccel, &msg))
410 TranslateMessage(&msg
);
411 DispatchMessage(&msg
);
414 if(msg
.message
== WM_QUIT
)
415 break; // break out main loop
420 if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject
, NULL
)) )
421 CoRevokeClassObject(dwRegisterClassObject
);
423 if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject2
, NULL
)) )
424 CoRevokeClassObject(dwRegisterClassObject2
);
426 // Reached on WM_QUIT message
428 return ((int) msg
.wParam
);
433 STDAPI_(BOOL
) DllMain(HANDLE hModule
, DWORD fdwReason
, LPVOID lpReserved
)
437 case DLL_PROCESS_ATTACH
:
438 h_instance
= (HINSTANCE
)hModule
;