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 "VideoLAN VLC ActiveX 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, 0x0DE86A58, 0x2BAA, 0x11CF, 0xA2, 0x29, 0x00,0xAA,0x00,0x3D,0x73,0x52);
52
static DEFINE_GUID(_CATID_SafeForInitializing, 0x7DD95802, 0x9882, 0x11CF, 0x9F, 0xA9, 0x00,0xAA,0x00,0x6C,0x42,0xC4);
53
static DEFINE_GUID(_CATID_SafeForScripting, 0x7DD95801, 0x9882, 0x11CF, 0x9F, 0xA9, 0x00,0xAA,0x00,0x6C,0x42,0xC4);
55
static LONG i_class_ref= 0;
56
static HINSTANCE h_instance= 0;
58
HMODULE DllGetModule()
63
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
65
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
69
if( (CLSID_VLCPlugin == rclsid )
70
|| ( CLSID_VLCPlugin2 == rclsid) )
72
VLCPluginClass *plugin = new VLCPluginClass(&i_class_ref, h_instance, rclsid);
73
hr = plugin->QueryInterface(riid, ppv);
79
STDAPI DllCanUnloadNow(VOID)
81
return (0 == i_class_ref) ? S_OK: S_FALSE;
84
static inline HKEY keyCreate(HKEY parentKey, LPCTSTR keyName)
87
if( ERROR_SUCCESS == RegCreateKeyEx(parentKey, keyName, 0, NULL,
88
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &childKey, NULL) )
95
static inline HKEY keySet(HKEY hKey, LPCTSTR valueName, const void *s, size_t len, DWORD dwType = REG_SZ)
99
RegSetValueEx(hKey, valueName, 0, dwType,
100
(const BYTE*)s, len);
105
static inline HKEY keySetDef(HKEY hKey, const void *s, size_t len, DWORD dwType = REG_SZ)
107
return keySet(hKey, NULL, s, len, dwType);
110
static inline HKEY keySetDef(HKEY hKey, LPCTSTR s)
112
return keySetDef(hKey, s, sizeof(TCHAR)*(_tcslen(s)+1), REG_SZ);
115
static inline HKEY keyClose(HKEY hKey)
124
static void UnregisterProgID(REFCLSID rclsid, unsigned int version)
126
OLECHAR szCLSID[GUID_STRLEN];
128
StringFromGUID2(rclsid, szCLSID, GUID_STRLEN);
130
TCHAR progId[sizeof(PROGID_STR)+16];
131
_stprintf(progId, TEXT("%s.%u"), TEXT(PROGID_STR), version);
133
SHDeleteKey(HKEY_CLASSES_ROOT, progId);
136
if( ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_WRITE, &hClsIDKey) )
138
SHDeleteKey(hClsIDKey, szCLSID);
139
RegCloseKey(hClsIDKey);
143
STDAPI DllUnregisterServer(VOID)
145
// unregister type lib from the registry
146
UnRegisterTypeLib(LIBID_AXVLC, 1, 0, LOCALE_NEUTRAL, SYS_WIN32);
148
// remove component categories we supports
150
if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr,
151
NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {
152
CATID implCategories[] = {
154
CATID_PersistsToPropertyBag,
155
_CATID_InternetAware,
156
_CATID_SafeForInitializing,
157
_CATID_SafeForScripting,
160
pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin,
161
sizeof(implCategories)/sizeof(CATID), implCategories);
162
pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin2,
163
sizeof(implCategories)/sizeof(CATID), implCategories);
167
SHDeleteKey(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));
169
UnregisterProgID(CLSID_VLCPlugin, 2);
170
UnregisterProgID(CLSID_VLCPlugin2, 1);
175
static HRESULT RegisterClassID(HKEY hParent, REFCLSID rclsid, unsigned int version, BOOL isDefault, LPCTSTR path, size_t pathLen)
177
TCHAR progId[sizeof(PROGID_STR)+16];
178
_stprintf(progId, TEXT("%s.%u"), TEXT(PROGID_STR), version);
180
TCHAR description[sizeof(DESCRIPTION)+16];
181
_stprintf(description, TEXT("%s v%u"), TEXT(DESCRIPTION), version);
185
OLECHAR szCLSID[GUID_STRLEN];
187
StringFromGUID2(rclsid, szCLSID, GUID_STRLEN);
189
HKEY hProgKey = keyCreate(HKEY_CLASSES_ROOT, progId);
190
if( NULL != hProgKey )
193
keySetDef(hProgKey, description);
195
keyClose(keySetDef(keyCreate(hProgKey, TEXT("CLSID")),
199
//hSubKey = keyClose(keyCreate(hBaseKey, "Insertable"));
201
RegCloseKey(hProgKey);
205
hProgKey = keyCreate(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));
206
if( NULL != hProgKey )
209
keySetDef(hProgKey, description);
211
keyClose(keySetDef(keyCreate(hProgKey, TEXT("CLSID")),
215
keyClose(keySetDef(keyCreate(hProgKey, TEXT("CurVer")),
219
hClassKey = keyCreate(hParent, szCLSID);
221
if( NULL != hClassKey )
224
keySetDef(hClassKey, description);
227
keyClose(keyCreate(hClassKey, TEXT("Control")));
229
// Insertable key value
230
//keyClose(keyCreate(hClassKey, TEXT("Insertable")));
232
// ToolboxBitmap32 key value
234
TCHAR iconPath[pathLen+3];
235
memcpy(iconPath, path, sizeof(TCHAR)*pathLen);
236
_tcscpy(iconPath+pathLen, TEXT(",1"));
237
keyClose(keySetDef(keyCreate(hClassKey,
238
TEXT("ToolboxBitmap32")),
239
iconPath, sizeof(iconPath)));
242
#ifdef BUILD_LOCALSERVER
243
// LocalServer32 key value
244
keyClose(keySetDef(keyCreate(hClassKey,
245
TEXT("LocalServer32"), path, sizeof(TCHAR)*(pathLen+1))));
247
// InprocServer32 key value
249
HKEY hSubKey = keySetDef(keyCreate(hClassKey,
250
TEXT("InprocServer32")),
251
path, sizeof(TCHAR)*(pathLen+1));
253
TEXT("ThreadingModel"),
254
TEXT(THREADING_MODEL), sizeof(TEXT(THREADING_MODEL)));
259
// MiscStatus key value
260
keyClose(keySetDef(keyCreate(hClassKey,
261
TEXT("MiscStatus\\1")),
262
TEXT(MISC_STATUS), sizeof(TEXT(MISC_STATUS))));
264
// Programmable key value
265
keyClose(keyCreate(hClassKey, TEXT("Programmable")));
268
keyClose(keySetDef(keyCreate(hClassKey,
272
// VersionIndependentProgID key value
273
keyClose(keySetDef(keyCreate(hClassKey,
274
TEXT("VersionIndependentProgID")),
275
TEXT(PROGID_STR), sizeof(TEXT(PROGID_STR))));
278
keyClose(keySetDef(keyCreate(hClassKey,
283
OLECHAR szLIBID[GUID_STRLEN];
285
StringFromGUID2(LIBID_AXVLC, szLIBID, GUID_STRLEN);
287
keyClose(keySetDef(keyCreate(hClassKey,
289
szLIBID, sizeof(szLIBID)));
291
RegCloseKey(hClassKey);
296
STDAPI DllRegisterServer(VOID)
298
DllUnregisterServer();
300
TCHAR DllPath[MAX_PATH];
301
DWORD DllPathLen=GetModuleFileName(h_instance, DllPath, MAX_PATH) ;
302
if( 0 == DllPathLen )
307
if( ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_CREATE_SUB_KEY, &hBaseKey) )
308
return SELFREG_E_CLASS;
310
RegisterClassID(hBaseKey, CLSID_VLCPlugin, 1, FALSE, DllPath, DllPathLen);
311
RegisterClassID(hBaseKey, CLSID_VLCPlugin2, 2, TRUE, DllPath, DllPathLen);
313
RegCloseKey(hBaseKey);
315
// indicate which component categories we support
317
if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr,
318
NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {
319
CATID implCategories[] = {
321
CATID_PersistsToPropertyBag,
322
_CATID_InternetAware,
323
_CATID_SafeForInitializing,
324
_CATID_SafeForScripting,
327
pcr->RegisterClassImplCategories(CLSID_VLCPlugin,
328
sizeof(implCategories)/sizeof(CATID), implCategories);
329
pcr->RegisterClassImplCategories(CLSID_VLCPlugin2,
330
sizeof(implCategories)/sizeof(CATID), implCategories);
334
#ifdef BUILD_LOCALSERVER
335
// replace .exe by .tlb
336
_tcscpy(DllPath+DllPathLen-4, TEXT(".tlb"));
339
// register type lib into the registry
342
HRESULT result = LoadTypeLibEx(DllPath, REGKIND_REGISTER, &typeLib);
343
if( SUCCEEDED(result) )
349
#ifdef BUILD_LOCALSERVER
352
** easier to debug an application than a DLL on cygwin GDB :)
356
STDAPI_(int) WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
360
if( FAILED(OleInitialize(NULL)) )
362
cerr << "cannot initialize OLE" << endl;
368
if( FAILED(DllRegisterServer()) )
370
cerr << "cannot register Local Server" << endl;
374
IUnknown *classProc = NULL;
376
if( FAILED(DllGetClassObject(CLSID_VLCPlugin, IID_IUnknown, (LPVOID *)&classProc)) )
379
DWORD dwRegisterClassObject;
380
DWORD dwRegisterClassObject2;
382
if( FAILED(CoRegisterClassObject(CLSID_VLCPlugin, classProc,
383
CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegisterClassObject)) )
386
DWORD dwRegisterActiveObject;
388
if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin,
389
ACTIVEOBJECT_WEAK, &dwRegisterActiveObject)) )
392
if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin2,
393
ACTIVEOBJECT_WEAK, &dwRegisterActiveObject2)) )
396
classProc->Release();
399
* Polling messages from event queue
401
while( S_FALSE == DllCanUnloadNow() )
403
while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
405
if( msg.message == WM_QUIT )
406
break; // break out PeekMessage loop
408
/*if(TranslateAccelerator(ghwndApp, ghAccel, &msg))
411
TranslateMessage(&msg);
412
DispatchMessage(&msg);
415
if(msg.message == WM_QUIT)
416
break; // break out main loop
421
if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject, NULL)) )
422
CoRevokeClassObject(dwRegisterClassObject);
424
if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject2, NULL)) )
425
CoRevokeClassObject(dwRegisterClassObject2);
427
// Reached on WM_QUIT message
429
return ((int) msg.wParam);
434
STDAPI_(BOOL) DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved )
438
case DLL_PROCESS_ATTACH:
439
h_instance = (HINSTANCE)hModule;