-/*****************************************************************************\r
- * main.cpp: ActiveX control for VLC\r
- *****************************************************************************\r
- * Copyright (C) 2005 VideoLAN\r
- *\r
- * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.\r
- *****************************************************************************/\r
-\r
-#include "plugin.h"\r
-\r
-#include <comcat.h>\r
-#include <windows.h>\r
-#include <shlwapi.h>\r
-\r
-using namespace std;\r
-\r
-#define THREADING_MODEL "Both"\r
-#define COMPANY_STR "VideoLAN"\r
-#define PROGRAM_STR "VLCPlugin"\r
-#define VERSION_MAJOR_STR "1"\r
-#define VERSION_MINOR_STR "0"\r
-#define DESCRIPTION "VideoLAN VLC ActiveX Plugin"\r
-\r
-#define PROGID_STR COMPANY_STR"."PROGRAM_STR\r
-#define VERS_PROGID_STR COMPANY_STR"."PROGRAM_STR"."VERSION_MAJOR_STR\r
-#define VERSION_STR VERSION_MAJOR_STR"."VERSION_MINOR_STR\r
-\r
-#define GUID_STRLEN 39\r
-\r
-/*\r
-** MingW headers do not declare those\r
-*/\r
-extern const CATID CATID_SafeForInitializing;\r
-extern const CATID CATID_SafeForScripting;\r
-\r
-static LONG i_class_ref= 0;\r
-static HINSTANCE h_instance= 0;\r
-\r
-STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)\r
-{\r
- HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;\r
-\r
- *ppv = NULL;\r
-\r
- if( CLSID_VLCPlugin == rclsid )\r
- {\r
- VLCPluginClass *plugin = new VLCPluginClass(&i_class_ref, h_instance);\r
- hr = plugin->QueryInterface(riid, ppv);\r
- plugin->Release();\r
- }\r
- return hr;\r
-};\r
-\r
-STDAPI DllCanUnloadNow(VOID)\r
-{\r
- return (0 == i_class_ref) ? S_OK: S_FALSE;\r
-};\r
-\r
-static LPCTSTR TStrFromGUID(REFGUID clsid) {\r
- LPOLESTR oleStr;\r
-\r
- if( FAILED(StringFromIID(clsid, &oleStr)) )\r
- return NULL;\r
-\r
- //check whether TCHAR and OLECHAR are both either ANSI or UNICODE\r
- if( sizeof(TCHAR) == sizeof(OLECHAR) )\r
- return (LPCTSTR)oleStr;\r
-\r
- LPTSTR pct_CLSID = NULL;\r
-#ifndef OLE2ANSI\r
- size_t len = WideCharToMultiByte(CP_ACP, 0, oleStr, -1, NULL, 0, NULL, NULL);\r
- if( len > 0 )\r
- {\r
- pct_CLSID = (char *)CoTaskMemAlloc(len);\r
- WideCharToMultiByte(CP_ACP, 0, oleStr, -1, pct_CLSID, len, NULL, NULL);\r
- }\r
-#else\r
- size_t len = MutiByteToWideChar(CP_ACP, 0, oleStr, -1, NULL, 0);\r
- if( len > 0 )\r
- {\r
- clsidStr = (wchar_t *)CoTaskMemAlloc(len*sizeof(wchar_t));\r
- WideCharToMultiByte(CP_ACP, 0, oleStr, -1, pct_CLSID, len);\r
- }\r
-#endif\r
- CoTaskMemFree(oleStr);\r
- return pct_CLSID;\r
-};\r
-\r
-static HKEY keyCreate(HKEY parentKey, LPCTSTR keyName)\r
-{\r
- HKEY childKey;\r
- if( ERROR_SUCCESS == RegCreateKeyEx(parentKey, keyName, 0, NULL,\r
- REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &childKey, NULL) )\r
- {\r
- return childKey;\r
- }\r
- return NULL;\r
-};\r
-\r
-STDAPI DllUnregisterServer(VOID)\r
-{\r
- // unregister type lib from the registry\r
- UnRegisterTypeLib(LIBID_AXVLC, 1, 0, LOCALE_NEUTRAL, SYS_WIN32);\r
-\r
- // remove component categories we supports\r
- ICatRegister *pcr;\r
- if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr, \r
- NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {\r
- CATID implCategories[] = {\r
- CATID_Control,\r
- CATID_PersistsToPropertyBag,\r
- CATID_SafeForInitializing,\r
- CATID_SafeForScripting,\r
- };\r
-\r
- pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin,\r
- sizeof(implCategories)/sizeof(CATID), implCategories);\r
- pcr->Release();\r
- }\r
-\r
- SHDeleteKey(HKEY_CLASSES_ROOT, TEXT(VERS_PROGID_STR));\r
- SHDeleteKey(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));\r
-\r
- LPCTSTR psz_CLSID = TStrFromGUID(CLSID_VLCPlugin);\r
-\r
- if( NULL == psz_CLSID )\r
- return E_OUTOFMEMORY;\r
-\r
- HKEY hClsIDKey;\r
- if( ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_WRITE, &hClsIDKey) )\r
- {\r
- SHDeleteKey(hClsIDKey, psz_CLSID);\r
- RegCloseKey(hClsIDKey);\r
- }\r
- CoTaskMemFree((void *)psz_CLSID);\r
-\r
- return S_OK;\r
-};\r
-\r
-STDAPI DllRegisterServer(VOID)\r
-{\r
- DllUnregisterServer();\r
-\r
- char DllPath[MAX_PATH];\r
- DWORD DllPathLen= GetModuleFileName(h_instance, DllPath, sizeof(DllPath)) ;\r
- if( 0 == DllPathLen )\r
- return E_FAIL;\r
-\r
- LPCTSTR psz_CLSID = TStrFromGUID(CLSID_VLCPlugin);\r
-\r
- if( NULL == psz_CLSID )\r
- return E_OUTOFMEMORY;\r
-\r
- HKEY hBaseKey;\r
-\r
- if( ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_CREATE_SUB_KEY, &hBaseKey) )\r
- return E_FAIL;\r
-\r
- HKEY hClassKey = keyCreate(hBaseKey, psz_CLSID);\r
- if( NULL != hClassKey )\r
- {\r
- HKEY hSubKey;\r
-\r
- // default key value\r
- RegSetValueEx(hClassKey, NULL, 0, REG_SZ,\r
- (const BYTE*)DESCRIPTION, sizeof(DESCRIPTION));\r
-\r
- // Control key value\r
- hSubKey = keyCreate(hClassKey, TEXT("Control"));\r
- RegCloseKey(hSubKey);\r
-\r
- // InprocServer32 key value\r
- hSubKey = keyCreate(hClassKey, TEXT("InprocServer32"));\r
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ,\r
- (const BYTE*)DllPath, DllPathLen);\r
- RegSetValueEx(hSubKey, TEXT("ThreadingModel"), 0, REG_SZ,\r
- (const BYTE*)THREADING_MODEL, sizeof(THREADING_MODEL));\r
- RegCloseKey(hSubKey);\r
-\r
- // MiscStatus key value\r
- hSubKey = keyCreate(hClassKey, TEXT("MiscStatus\\1"));\r
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ, (const BYTE*)"131473", sizeof("131473"));\r
- RegCloseKey(hSubKey);\r
-\r
- // Programmable key value\r
- hSubKey = keyCreate(hClassKey, TEXT("Programmable"));\r
- RegCloseKey(hSubKey);\r
-\r
- // ProgID key value\r
- hSubKey = keyCreate(hClassKey, TEXT("ProgID"));\r
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ, \r
- (const BYTE*)VERS_PROGID_STR, sizeof(VERS_PROGID_STR));\r
- RegCloseKey(hSubKey);\r
-\r
- // VersionIndependentProgID key value\r
- hSubKey = keyCreate(hClassKey, TEXT("VersionIndependentProgID"));\r
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ, \r
- (const BYTE*)PROGID_STR, sizeof(PROGID_STR));\r
- RegCloseKey(hSubKey);\r
-\r
- // Version key value\r
- hSubKey = keyCreate(hClassKey, TEXT("Version"));\r
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ,\r
- (const BYTE*)VERSION_STR, sizeof(VERSION_STR));\r
- RegCloseKey(hSubKey);\r
-\r
- // TypeLib key value\r
- LPCTSTR psz_LIBID = TStrFromGUID(LIBID_AXVLC);\r
- if( NULL != psz_LIBID )\r
- {\r
- hSubKey = keyCreate(hClassKey, TEXT("TypeLib"));\r
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ,\r
- (const BYTE*)psz_LIBID, sizeof(TCHAR)*GUID_STRLEN);\r
- RegCloseKey(hSubKey);\r
- }\r
- RegCloseKey(hClassKey);\r
- }\r
- RegCloseKey(hBaseKey);\r
-\r
- hBaseKey = keyCreate(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));\r
- if( NULL != hBaseKey )\r
- {\r
- // default key value\r
- RegSetValueEx(hBaseKey, NULL, 0, REG_SZ,\r
- (const BYTE*)DESCRIPTION, sizeof(DESCRIPTION));\r
-\r
- HKEY hSubKey = keyCreate(hBaseKey, TEXT("CLSID"));\r
- if( NULL != hSubKey )\r
- {\r
- // default key value\r
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ,\r
- (const BYTE*)psz_CLSID, sizeof(TCHAR)*GUID_STRLEN);\r
-\r
- RegCloseKey(hSubKey);\r
- }\r
- hSubKey = keyCreate(hBaseKey, TEXT("CurVer"));\r
- if( NULL != hSubKey )\r
- {\r
- // default key value\r
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ,\r
- (const BYTE*)VERS_PROGID_STR, sizeof(VERS_PROGID_STR));\r
-\r
- RegCloseKey(hSubKey);\r
- }\r
- RegCloseKey(hBaseKey);\r
- }\r
-\r
- hBaseKey = keyCreate(HKEY_CLASSES_ROOT, TEXT(VERS_PROGID_STR));\r
- if( NULL != hBaseKey )\r
- {\r
- // default key value\r
- RegSetValueEx(hBaseKey, NULL, 0, REG_SZ,\r
- (const BYTE*)DESCRIPTION, sizeof(DESCRIPTION));\r
-\r
- HKEY hSubKey = keyCreate(hBaseKey, TEXT("CLSID"));\r
- if( NULL != hSubKey )\r
- {\r
- // default key value\r
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ,\r
- (const BYTE*)psz_CLSID, sizeof(TCHAR)*GUID_STRLEN);\r
-\r
- RegCloseKey(hSubKey);\r
- }\r
- RegCloseKey(hBaseKey);\r
- }\r
-\r
- // indicate which component categories we support\r
- ICatRegister *pcr;\r
- if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr, \r
- NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {\r
- CATID implCategories[] = {\r
- CATID_Control,\r
- CATID_PersistsToPropertyBag,\r
- CATID_SafeForInitializing,\r
- CATID_SafeForScripting,\r
- };\r
-\r
- pcr->RegisterClassImplCategories(CLSID_VLCPlugin,\r
- sizeof(implCategories)/sizeof(CATID), implCategories);\r
- pcr->Release();\r
- }\r
-\r
- // register type lib into the registry\r
- ITypeLib *typeLib;\r
-#ifndef OLE2ANSI\r
- size_t typeLibPathLen = MultiByteToWideChar(CP_ACP, 0, DllPath, DllPathLen, NULL, 0);\r
- if( typeLibPathLen > 0 )\r
- {\r
- LPOLESTR typeLibPath = (LPOLESTR)CoTaskMemAlloc(typeLibPathLen*sizeof(wchar_t));\r
- MultiByteToWideChar(CP_ACP, 0, DllPath, DllPathLen, typeLibPath, typeLibPathLen);\r
- if( SUCCEEDED(LoadTypeLibEx(typeLibPath, REGKIND_REGISTER, &typeLib)) )\r
- typeLib->Release();\r
- CoTaskMemFree((void *)typeLibPath);\r
- }\r
-#else\r
- if( SUCCEEDED(LoadTypeLibEx((LPOLESTR)DllPath, REGKIND_REGISTER, &typeLib)) )\r
- typeLib->Release();\r
-#endif\r
-\r
- CoTaskMemFree((void *)psz_CLSID);\r
-\r
- return S_OK;\r
-};\r
-\r
-#ifdef BUILD_LOCALSERVER\r
-\r
-/*\r
-** easier to debug an application than a DLL on cygwin GDB :)\r
-*/\r
-#include <iostream>\r
-\r
-STDAPI_(int) WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)\r
-{\r
- MSG msg;\r
-\r
- if( FAILED(OleInitialize(NULL)) )\r
- {\r
- cerr << "cannot initialize OLE" << endl;\r
- return 1;\r
- }\r
-\r
- IUnknown *classProc = NULL;\r
-\r
- if( FAILED(DllGetClassObject(CLSID_VLCPlugin, IID_IUnknown, (LPVOID *)&classProc)) )\r
- return 0;\r
- \r
- DWORD dwRegisterClassObject;\r
-\r
- if( FAILED(CoRegisterClassObject(CLSID_VLCPlugin, classProc,\r
- CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegisterClassObject)) )\r
- return 0;\r
-\r
- DWORD dwRegisterActiveObject;\r
-\r
- if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin,\r
- ACTIVEOBJECT_WEAK, &dwRegisterActiveObject)) )\r
- return 0;\r
-\r
- classProc->Release();\r
-\r
- /*\r
- * Polling messages from event queue\r
- */\r
- while( S_FALSE == DllCanUnloadNow() )\r
- {\r
- while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )\r
- {\r
- if( msg.message == WM_QUIT )\r
- break; // Leave the PeekMessage while() loop\r
-\r
- /*if(TranslateAccelerator(ghwndApp, ghAccel, &msg))\r
- continue;*/\r
-\r
- TranslateMessage(&msg);\r
- DispatchMessage(&msg);\r
- }\r
-\r
- if(msg.message == WM_QUIT)\r
- break; // Leave the for() loop\r
-\r
- WaitMessage();\r
- }\r
-\r
- if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject, NULL)) )\r
- CoRevokeClassObject(dwRegisterClassObject);\r
-\r
- // Reached on WM_QUIT message\r
- CoUninitialize();\r
- return ((int) msg.wParam);\r
-};\r
-\r
-#else\r
-\r
-STDAPI_(BOOL) DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved )\r
-{\r
- switch( fdwReason )\r
- {\r
- case DLL_PROCESS_ATTACH:\r
- h_instance = (HINSTANCE)hModule;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- return TRUE;\r
-};\r
-\r
-#endif\r
-\r
+/*****************************************************************************
+ * main.cpp: ActiveX control for VLC
+ *****************************************************************************
+ * Copyright (C) 2005 VideoLAN
+ *
+ * Authors: Damien Fouilleul <Damien.Fouilleul@laposte.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#include "plugin.h"
+
+#include <comcat.h>
+#include <windows.h>
+#include <shlwapi.h>
+
+using namespace std;
+
+#define THREADING_MODEL "Both"
+#define COMPANY_STR "VideoLAN"
+#define PROGRAM_STR "VLCPlugin"
+#define VERSION_MAJOR_STR "1"
+#define VERSION_MINOR_STR "0"
+#define DESCRIPTION "VideoLAN VLC ActiveX Plugin"
+
+#define PROGID_STR COMPANY_STR"."PROGRAM_STR
+#define VERS_PROGID_STR COMPANY_STR"."PROGRAM_STR"."VERSION_MAJOR_STR
+#define VERSION_STR VERSION_MAJOR_STR"."VERSION_MINOR_STR
+
+#define GUID_STRLEN 39
+
+/*
+** MingW headers do not declare those
+*/
+extern const CATID CATID_SafeForInitializing;
+extern const CATID CATID_SafeForScripting;
+
+static LONG i_class_ref= 0;
+static HINSTANCE h_instance= 0;
+
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+ HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
+
+ *ppv = NULL;
+
+ if( CLSID_VLCPlugin == rclsid )
+ {
+ VLCPluginClass *plugin = new VLCPluginClass(&i_class_ref, h_instance);
+ hr = plugin->QueryInterface(riid, ppv);
+ plugin->Release();
+ }
+ return hr;
+};
+
+STDAPI DllCanUnloadNow(VOID)
+{
+ return (0 == i_class_ref) ? S_OK: S_FALSE;
+};
+
+static LPCTSTR TStrFromGUID(REFGUID clsid) {
+ LPOLESTR oleStr;
+
+ if( FAILED(StringFromIID(clsid, &oleStr)) )
+ return NULL;
+
+ //check whether TCHAR and OLECHAR are both either ANSI or UNICODE
+ if( sizeof(TCHAR) == sizeof(OLECHAR) )
+ return (LPCTSTR)oleStr;
+
+ LPTSTR pct_CLSID = NULL;
+#ifndef OLE2ANSI
+ size_t len = WideCharToMultiByte(CP_ACP, 0, oleStr, -1, NULL, 0, NULL, NULL);
+ if( len > 0 )
+ {
+ pct_CLSID = (char *)CoTaskMemAlloc(len);
+ WideCharToMultiByte(CP_ACP, 0, oleStr, -1, pct_CLSID, len, NULL, NULL);
+ }
+#else
+ size_t len = MutiByteToWideChar(CP_ACP, 0, oleStr, -1, NULL, 0);
+ if( len > 0 )
+ {
+ clsidStr = (wchar_t *)CoTaskMemAlloc(len*sizeof(wchar_t));
+ WideCharToMultiByte(CP_ACP, 0, oleStr, -1, pct_CLSID, len);
+ }
+#endif
+ CoTaskMemFree(oleStr);
+ return pct_CLSID;
+};
+
+static HKEY keyCreate(HKEY parentKey, LPCTSTR keyName)
+{
+ HKEY childKey;
+ if( ERROR_SUCCESS == RegCreateKeyEx(parentKey, keyName, 0, NULL,
+ REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &childKey, NULL) )
+ {
+ return childKey;
+ }
+ return NULL;
+};
+
+STDAPI DllUnregisterServer(VOID)
+{
+ // unregister type lib from the registry
+ UnRegisterTypeLib(LIBID_AXVLC, 1, 0, LOCALE_NEUTRAL, SYS_WIN32);
+
+ // remove component categories we supports
+ ICatRegister *pcr;
+ if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr,
+ NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {
+ CATID implCategories[] = {
+ CATID_Control,
+ CATID_PersistsToPropertyBag,
+ CATID_SafeForInitializing,
+ CATID_SafeForScripting,
+ };
+
+ pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin,
+ sizeof(implCategories)/sizeof(CATID), implCategories);
+ pcr->Release();
+ }
+
+ SHDeleteKey(HKEY_CLASSES_ROOT, TEXT(VERS_PROGID_STR));
+ SHDeleteKey(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));
+
+ LPCTSTR psz_CLSID = TStrFromGUID(CLSID_VLCPlugin);
+
+ if( NULL == psz_CLSID )
+ return E_OUTOFMEMORY;
+
+ HKEY hClsIDKey;
+ if( ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_WRITE, &hClsIDKey) )
+ {
+ SHDeleteKey(hClsIDKey, psz_CLSID);
+ RegCloseKey(hClsIDKey);
+ }
+ CoTaskMemFree((void *)psz_CLSID);
+
+ return S_OK;
+};
+
+STDAPI DllRegisterServer(VOID)
+{
+ DllUnregisterServer();
+
+ char DllPath[MAX_PATH];
+ DWORD DllPathLen= GetModuleFileName(h_instance, DllPath, sizeof(DllPath)) ;
+ if( 0 == DllPathLen )
+ return E_FAIL;
+
+ LPCTSTR psz_CLSID = TStrFromGUID(CLSID_VLCPlugin);
+
+ if( NULL == psz_CLSID )
+ return E_OUTOFMEMORY;
+
+ HKEY hBaseKey;
+
+ if( ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_CREATE_SUB_KEY, &hBaseKey) )
+ return E_FAIL;
+
+ HKEY hClassKey = keyCreate(hBaseKey, psz_CLSID);
+ if( NULL != hClassKey )
+ {
+ HKEY hSubKey;
+
+ // default key value
+ RegSetValueEx(hClassKey, NULL, 0, REG_SZ,
+ (const BYTE*)DESCRIPTION, sizeof(DESCRIPTION));
+
+ // Control key value
+ hSubKey = keyCreate(hClassKey, TEXT("Control"));
+ RegCloseKey(hSubKey);
+
+ // InprocServer32 key value
+ hSubKey = keyCreate(hClassKey, TEXT("InprocServer32"));
+ RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
+ (const BYTE*)DllPath, DllPathLen);
+ RegSetValueEx(hSubKey, TEXT("ThreadingModel"), 0, REG_SZ,
+ (const BYTE*)THREADING_MODEL, sizeof(THREADING_MODEL));
+ RegCloseKey(hSubKey);
+
+ // MiscStatus key value
+ hSubKey = keyCreate(hClassKey, TEXT("MiscStatus\\1"));
+ RegSetValueEx(hSubKey, NULL, 0, REG_SZ, (const BYTE*)"131473", sizeof("131473"));
+ RegCloseKey(hSubKey);
+
+ // Programmable key value
+ hSubKey = keyCreate(hClassKey, TEXT("Programmable"));
+ RegCloseKey(hSubKey);
+
+ // ProgID key value
+ hSubKey = keyCreate(hClassKey, TEXT("ProgID"));
+ RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
+ (const BYTE*)VERS_PROGID_STR, sizeof(VERS_PROGID_STR));
+ RegCloseKey(hSubKey);
+
+ // VersionIndependentProgID key value
+ hSubKey = keyCreate(hClassKey, TEXT("VersionIndependentProgID"));
+ RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
+ (const BYTE*)PROGID_STR, sizeof(PROGID_STR));
+ RegCloseKey(hSubKey);
+
+ // Version key value
+ hSubKey = keyCreate(hClassKey, TEXT("Version"));
+ RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
+ (const BYTE*)VERSION_STR, sizeof(VERSION_STR));
+ RegCloseKey(hSubKey);
+
+ // TypeLib key value
+ LPCTSTR psz_LIBID = TStrFromGUID(LIBID_AXVLC);
+ if( NULL != psz_LIBID )
+ {
+ hSubKey = keyCreate(hClassKey, TEXT("TypeLib"));
+ RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
+ (const BYTE*)psz_LIBID, sizeof(TCHAR)*GUID_STRLEN);
+ RegCloseKey(hSubKey);
+ }
+ RegCloseKey(hClassKey);
+ }
+ RegCloseKey(hBaseKey);
+
+ hBaseKey = keyCreate(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));
+ if( NULL != hBaseKey )
+ {
+ // default key value
+ RegSetValueEx(hBaseKey, NULL, 0, REG_SZ,
+ (const BYTE*)DESCRIPTION, sizeof(DESCRIPTION));
+
+ HKEY hSubKey = keyCreate(hBaseKey, TEXT("CLSID"));
+ if( NULL != hSubKey )
+ {
+ // default key value
+ RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
+ (const BYTE*)psz_CLSID, sizeof(TCHAR)*GUID_STRLEN);
+
+ RegCloseKey(hSubKey);
+ }
+ hSubKey = keyCreate(hBaseKey, TEXT("CurVer"));
+ if( NULL != hSubKey )
+ {
+ // default key value
+ RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
+ (const BYTE*)VERS_PROGID_STR, sizeof(VERS_PROGID_STR));
+
+ RegCloseKey(hSubKey);
+ }
+ RegCloseKey(hBaseKey);
+ }
+
+ hBaseKey = keyCreate(HKEY_CLASSES_ROOT, TEXT(VERS_PROGID_STR));
+ if( NULL != hBaseKey )
+ {
+ // default key value
+ RegSetValueEx(hBaseKey, NULL, 0, REG_SZ,
+ (const BYTE*)DESCRIPTION, sizeof(DESCRIPTION));
+
+ HKEY hSubKey = keyCreate(hBaseKey, TEXT("CLSID"));
+ if( NULL != hSubKey )
+ {
+ // default key value
+ RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
+ (const BYTE*)psz_CLSID, sizeof(TCHAR)*GUID_STRLEN);
+
+ RegCloseKey(hSubKey);
+ }
+ RegCloseKey(hBaseKey);
+ }
+
+ // indicate which component categories we support
+ ICatRegister *pcr;
+ if( SUCCEEDED(CoCreateInstance(CLSID_StdComponentCategoriesMgr,
+ NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr)) ) {
+ CATID implCategories[] = {
+ CATID_Control,
+ CATID_PersistsToPropertyBag,
+ CATID_SafeForInitializing,
+ CATID_SafeForScripting,
+ };
+
+ pcr->RegisterClassImplCategories(CLSID_VLCPlugin,
+ sizeof(implCategories)/sizeof(CATID), implCategories);
+ pcr->Release();
+ }
+
+ // register type lib into the registry
+ ITypeLib *typeLib;
+#ifndef OLE2ANSI
+ size_t typeLibPathLen = MultiByteToWideChar(CP_ACP, 0, DllPath, DllPathLen, NULL, 0);
+ if( typeLibPathLen > 0 )
+ {
+ LPOLESTR typeLibPath = (LPOLESTR)CoTaskMemAlloc(typeLibPathLen*sizeof(wchar_t));
+ MultiByteToWideChar(CP_ACP, 0, DllPath, DllPathLen, typeLibPath, typeLibPathLen);
+ if( SUCCEEDED(LoadTypeLibEx(typeLibPath, REGKIND_REGISTER, &typeLib)) )
+ typeLib->Release();
+ CoTaskMemFree((void *)typeLibPath);
+ }
+#else
+ if( SUCCEEDED(LoadTypeLibEx((LPOLESTR)DllPath, REGKIND_REGISTER, &typeLib)) )
+ typeLib->Release();
+#endif
+
+ CoTaskMemFree((void *)psz_CLSID);
+
+ return S_OK;
+};
+
+#ifdef BUILD_LOCALSERVER
+
+/*
+** easier to debug an application than a DLL on cygwin GDB :)
+*/
+#include <iostream>
+
+STDAPI_(int) WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
+{
+ MSG msg;
+
+ if( FAILED(OleInitialize(NULL)) )
+ {
+ cerr << "cannot initialize OLE" << endl;
+ return 1;
+ }
+
+ IUnknown *classProc = NULL;
+
+ if( FAILED(DllGetClassObject(CLSID_VLCPlugin, IID_IUnknown, (LPVOID *)&classProc)) )
+ return 0;
+
+ DWORD dwRegisterClassObject;
+
+ if( FAILED(CoRegisterClassObject(CLSID_VLCPlugin, classProc,
+ CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegisterClassObject)) )
+ return 0;
+
+ DWORD dwRegisterActiveObject;
+
+ if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin,
+ ACTIVEOBJECT_WEAK, &dwRegisterActiveObject)) )
+ return 0;
+
+ classProc->Release();
+
+ /*
+ * Polling messages from event queue
+ */
+ while( S_FALSE == DllCanUnloadNow() )
+ {
+ while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
+ {
+ if( msg.message == WM_QUIT )
+ break; // Leave the PeekMessage while() loop
+
+ /*if(TranslateAccelerator(ghwndApp, ghAccel, &msg))
+ continue;*/
+
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ if(msg.message == WM_QUIT)
+ break; // Leave the for() loop
+
+ WaitMessage();
+ }
+
+ if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject, NULL)) )
+ CoRevokeClassObject(dwRegisterClassObject);
+
+ // Reached on WM_QUIT message
+ CoUninitialize();
+ return ((int) msg.wParam);
+};
+
+#else
+
+STDAPI_(BOOL) DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved )
+{
+ switch( fdwReason )
+ {
+ case DLL_PROCESS_ATTACH:
+ h_instance = (HINSTANCE)hModule;
+ break;
+
+ default:
+ break;
+ }
+ return TRUE;
+};
+
+#endif
+