*
* 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "plugin.h"
+#include "utils.h"
+
+#include <stdio.h>
#include <comcat.h>
#include <windows.h>
#include <shlwapi.h>
+#include <tchar.h>
+#include <guiddef.h>
+
using namespace std;
#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 THREADING_MODEL "Apartment"
#define MISC_STATUS "131473"
#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
+** MingW headers & libs do not declare those
*/
-extern const CATID CATID_SafeForInitializing;
-extern const CATID CATID_SafeForScripting;
+static DEFINE_GUID(_CATID_InternetAware, 0x0DE86A58, 0x2BAA, 0x11CF, 0xA2, 0x29, 0x00,0xAA,0x00,0x3D,0x73,0x52);
+static DEFINE_GUID(_CATID_SafeForInitializing, 0x7DD95802, 0x9882, 0x11CF, 0x9F, 0xA9, 0x00,0xAA,0x00,0x6C,0x42,0xC4);
+static DEFINE_GUID(_CATID_SafeForScripting, 0x7DD95801, 0x9882, 0x11CF, 0x9F, 0xA9, 0x00,0xAA,0x00,0x6C,0x42,0xC4);
static LONG i_class_ref= 0;
static HINSTANCE h_instance= 0;
+HMODULE DllGetModule()
+{
+ return h_instance;
+};
+
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
*ppv = NULL;
- if( CLSID_VLCPlugin == rclsid )
+ if( (CLSID_VLCPlugin == rclsid )
+ || ( CLSID_VLCPlugin2 == rclsid) )
{
- VLCPluginClass *plugin = new VLCPluginClass(&i_class_ref, h_instance);
+ VLCPluginClass *plugin = new VLCPluginClass(&i_class_ref, h_instance, rclsid);
hr = plugin->QueryInterface(riid, ppv);
plugin->Release();
}
return (0 == i_class_ref) ? S_OK: S_FALSE;
};
-static LPCTSTR TStrFromGUID(REFGUID clsid)
+static inline HKEY keyCreate(HKEY parentKey, LPCTSTR keyName)
{
- 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 )
+ HKEY childKey;
+ if( ERROR_SUCCESS == RegCreateKeyEx(parentKey, keyName, 0, NULL,
+ REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &childKey, NULL) )
{
- pct_CLSID = (char *)CoTaskMemAlloc(len);
- WideCharToMultiByte(CP_ACP, 0, oleStr, -1, pct_CLSID, len, NULL, NULL);
+ return childKey;
}
-#else
- size_t len = MutiByteToWideChar(CP_ACP, 0, oleStr, -1, NULL, 0);
- if( len > 0 )
+ return NULL;
+};
+
+static inline HKEY keySet(HKEY hKey, LPCTSTR valueName, const void *s, size_t len, DWORD dwType = REG_SZ)
+{
+ if( NULL != hKey )
{
- clsidStr = (wchar_t *)CoTaskMemAlloc(len*sizeof(wchar_t));
- WideCharToMultiByte(CP_ACP, 0, oleStr, -1, pct_CLSID, len);
+ RegSetValueEx(hKey, valueName, 0, dwType,
+ (const BYTE*)s, len);
}
-#endif
- CoTaskMemFree(oleStr);
- return pct_CLSID;
+ return hKey;
};
-static HKEY keyCreate(HKEY parentKey, LPCTSTR keyName)
+static inline HKEY keySetDef(HKEY hKey, const void *s, size_t len, DWORD dwType = REG_SZ)
{
- HKEY childKey;
- if( ERROR_SUCCESS == RegCreateKeyEx(parentKey, keyName, 0, NULL,
- REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &childKey, NULL) )
+ return keySet(hKey, NULL, s, len, dwType);
+};
+
+static inline HKEY keySetDef(HKEY hKey, LPCTSTR s)
+{
+ return keySetDef(hKey, s, sizeof(TCHAR)*(_tcslen(s)+1), REG_SZ);
+};
+
+static inline HKEY keyClose(HKEY hKey)
+{
+ if( NULL != hKey )
{
- return childKey;
+ RegCloseKey(hKey);
}
return NULL;
};
+static HRESULT UnregisterProgID(REFCLSID rclsid, unsigned int version)
+{
+ OLECHAR szCLSID[GUID_STRLEN];
+
+ StringFromGUID2(rclsid, szCLSID, GUID_STRLEN);
+
+ TCHAR progId[sizeof(PROGID_STR)+16];
+ _stprintf(progId, TEXT("%s.%u"), TEXT(PROGID_STR), version);
+
+ SHDeleteKey(HKEY_CLASSES_ROOT, progId);
+
+ HKEY hClsIDKey;
+ if( ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_WRITE, &hClsIDKey) )
+ {
+ SHDeleteKey(hClsIDKey, szCLSID);
+ RegCloseKey(hClsIDKey);
+ }
+};
+
STDAPI DllUnregisterServer(VOID)
{
// unregister type lib from the registry
CATID implCategories[] = {
CATID_Control,
CATID_PersistsToPropertyBag,
- CATID_SafeForInitializing,
- CATID_SafeForScripting,
+ _CATID_InternetAware,
+ _CATID_SafeForInitializing,
+ _CATID_SafeForScripting,
};
pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin,
sizeof(implCategories)/sizeof(CATID), implCategories);
+ pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin2,
+ 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);
+ UnregisterProgID(CLSID_VLCPlugin, 2);
+ UnregisterProgID(CLSID_VLCPlugin2, 1);
return S_OK;
};
-STDAPI DllRegisterServer(VOID)
+static HRESULT RegisterClassID(HKEY hParent, REFCLSID rclsid, unsigned int version, BOOL isDefault, LPCTSTR path, size_t pathLen)
{
- DllUnregisterServer();
+ TCHAR progId[sizeof(PROGID_STR)+16];
+ _stprintf(progId, TEXT("%s.%u"), TEXT(PROGID_STR), version);
- char DllPath[MAX_PATH];
- DWORD DllPathLen= GetModuleFileName(h_instance, DllPath, sizeof(DllPath)) ;
- if( 0 == DllPathLen )
- return E_UNEXPECTED;
+ TCHAR description[sizeof(DESCRIPTION)+16];
+ _stprintf(description, TEXT("%s v%u"), TEXT(DESCRIPTION), version);
- LPCTSTR psz_CLSID = TStrFromGUID(CLSID_VLCPlugin);
+ HKEY hClassKey;
+ {
+ OLECHAR szCLSID[GUID_STRLEN];
- if( NULL == psz_CLSID )
- return E_OUTOFMEMORY;
+ StringFromGUID2(rclsid, szCLSID, GUID_STRLEN);
- HKEY hBaseKey;
+ HKEY hProgKey = keyCreate(HKEY_CLASSES_ROOT, progId);
+ if( NULL != hProgKey )
+ {
+ // default key value
+ keySetDef(hProgKey, description);
- if( ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_CREATE_SUB_KEY, &hBaseKey) )
- return SELFREG_E_CLASS;
+ keyClose(keySetDef(keyCreate(hProgKey, TEXT("CLSID")),
+ szCLSID,
+ sizeof(szCLSID)));
- HKEY hClassKey = keyCreate(hBaseKey, psz_CLSID);
+ //hSubKey = keyClose(keyCreate(hBaseKey, "Insertable"));
+
+ RegCloseKey(hProgKey);
+ }
+ if( isDefault )
+ {
+ hProgKey = keyCreate(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));
+ if( NULL != hProgKey )
+ {
+ // default key value
+ keySetDef(hProgKey, description);
+
+ keyClose(keySetDef(keyCreate(hProgKey, TEXT("CLSID")),
+ szCLSID,
+ sizeof(szCLSID)));
+
+ keyClose(keySetDef(keyCreate(hProgKey, TEXT("CurVer")),
+ progId));
+ }
+ }
+ hClassKey = keyCreate(hParent, szCLSID);
+ }
if( NULL != hClassKey )
{
- HKEY hSubKey;
-
// default key value
- RegSetValueEx(hClassKey, NULL, 0, REG_SZ,
- (const BYTE*)DESCRIPTION, sizeof(DESCRIPTION));
+ keySetDef(hClassKey, description);
// Control key value
- hSubKey = keyCreate(hClassKey, TEXT("Control"));
- RegCloseKey(hSubKey);
+ keyClose(keyCreate(hClassKey, TEXT("Control")));
// Insertable key value
- //hSubKey = keyCreate(hClassKey, TEXT("Insertable"));
- //RegCloseKey(hSubKey);
+ //keyClose(keyCreate(hClassKey, TEXT("Insertable")));
// ToolboxBitmap32 key value
- hSubKey = keyCreate(hClassKey, TEXT("ToolboxBitmap32"));
- strcpy(DllPath+DllPathLen, ",1");
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
- (const BYTE*)DllPath, DllPathLen+2);
- DllPath[DllPathLen] = '\0';
- RegCloseKey(hSubKey);
+ {
+ TCHAR iconPath[pathLen+3];
+ memcpy(iconPath, path, sizeof(TCHAR)*pathLen);
+ _tcscpy(iconPath+pathLen, TEXT(",1"));
+ keyClose(keySetDef(keyCreate(hClassKey,
+ TEXT("ToolboxBitmap32")),
+ iconPath, sizeof(iconPath)));
+ }
#ifdef BUILD_LOCALSERVER
// LocalServer32 key value
- hSubKey = keyCreate(hClassKey, TEXT("LocalServer32"));
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
- (const BYTE*)DllPath, DllPathLen);
- RegCloseKey(hSubKey);
+ keyClose(keySetDef(keyCreate(hClassKey,
+ TEXT("LocalServer32"), path, sizeof(TCHAR)*(pathLen+1))));
#else
// 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);
+ {
+ HKEY hSubKey = keySetDef(keyCreate(hClassKey,
+ TEXT("InprocServer32")),
+ path, sizeof(TCHAR)*(pathLen+1));
+ keySet(hSubKey,
+ TEXT("ThreadingModel"),
+ TEXT(THREADING_MODEL), sizeof(TEXT(THREADING_MODEL)));
+ keyClose(hSubKey);
+ }
#endif
// MiscStatus key value
- hSubKey = keyCreate(hClassKey, TEXT("MiscStatus\\1"));
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ, (const BYTE*)MISC_STATUS, sizeof(MISC_STATUS));
- RegCloseKey(hSubKey);
+ keyClose(keySetDef(keyCreate(hClassKey,
+ TEXT("MiscStatus\\1")),
+ TEXT(MISC_STATUS), sizeof(TEXT(MISC_STATUS))));
// Programmable key value
- hSubKey = keyCreate(hClassKey, TEXT("Programmable"));
- RegCloseKey(hSubKey);
+ keyClose(keyCreate(hClassKey, TEXT("Programmable")));
// 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);
+ keyClose(keySetDef(keyCreate(hClassKey,
+ TEXT("ProgID")),
+ progId));
// VersionIndependentProgID key value
- hSubKey = keyCreate(hClassKey, TEXT("VersionIndependentProgID"));
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
- (const BYTE*)PROGID_STR, sizeof(PROGID_STR));
- RegCloseKey(hSubKey);
+ keyClose(keySetDef(keyCreate(hClassKey,
+ TEXT("VersionIndependentProgID")),
+ TEXT(PROGID_STR), sizeof(TEXT(PROGID_STR))));
// Version key value
- hSubKey = keyCreate(hClassKey, TEXT("Version"));
- RegSetValueEx(hSubKey, NULL, 0, REG_SZ,
- (const BYTE*)VERSION_STR, sizeof(VERSION_STR));
- RegCloseKey(hSubKey);
+ keyClose(keySetDef(keyCreate(hClassKey,
+ TEXT("Version")),
+ TEXT("1.0")));
// 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);
- }
+ OLECHAR szLIBID[GUID_STRLEN];
+
+ StringFromGUID2(LIBID_AXVLC, szLIBID, GUID_STRLEN);
+
+ keyClose(keySetDef(keyCreate(hClassKey,
+ TEXT("TypeLib")),
+ szLIBID, sizeof(szLIBID)));
+
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));
+ return S_OK;
+}
- 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);
+STDAPI DllRegisterServer(VOID)
+{
+ DllUnregisterServer();
- 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));
+ TCHAR DllPath[MAX_PATH];
+ DWORD DllPathLen=GetModuleFileName(h_instance, DllPath, MAX_PATH) ;
+ if( 0 == DllPathLen )
+ return E_UNEXPECTED;
- RegCloseKey(hSubKey);
- }
- RegCloseKey(hBaseKey);
- }
+ HKEY 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));
+ if( ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_CREATE_SUB_KEY, &hBaseKey) )
+ return SELFREG_E_CLASS;
- 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);
+ RegisterClassID(hBaseKey, CLSID_VLCPlugin, 1, FALSE, DllPath, DllPathLen);
+ RegisterClassID(hBaseKey, CLSID_VLCPlugin2, 2, TRUE, DllPath, DllPathLen);
- RegCloseKey(hSubKey);
- }
- //hSubKey = keyCreate(hBaseKey, TEXT("Insertable"));
- //RegCloseKey(hSubKey);
-
- RegCloseKey(hBaseKey);
- }
+ RegCloseKey(hBaseKey);
// indicate which component categories we support
ICatRegister *pcr;
CATID implCategories[] = {
CATID_Control,
CATID_PersistsToPropertyBag,
- CATID_SafeForInitializing,
- CATID_SafeForScripting,
+ _CATID_InternetAware,
+ _CATID_SafeForInitializing,
+ _CATID_SafeForScripting,
};
pcr->RegisterClassImplCategories(CLSID_VLCPlugin,
sizeof(implCategories)/sizeof(CATID), implCategories);
+ pcr->RegisterClassImplCategories(CLSID_VLCPlugin2,
+ sizeof(implCategories)/sizeof(CATID), implCategories);
pcr->Release();
}
- // register type lib into the registry
- ITypeLib *typeLib;
-
#ifdef BUILD_LOCALSERVER
// replace .exe by .tlb
- strcpy(DllPath+DllPathLen-4, ".tlb");
-#endif
-
-#ifndef OLE2ANSI
- size_t typeLibPathLen = MultiByteToWideChar(CP_ACP, 0, DllPath, -1, NULL, 0);
- if( typeLibPathLen > 0 )
- {
- LPOLESTR typeLibPath = (LPOLESTR)CoTaskMemAlloc(typeLibPathLen*sizeof(wchar_t));
- MultiByteToWideChar(CP_ACP, 0, DllPath, DllPathLen, typeLibPath, typeLibPathLen);
- if( FAILED(LoadTypeLibEx(typeLibPath, REGKIND_REGISTER, &typeLib)) )
-#ifndef BUILD_LOCALSERVER
- return SELFREG_E_TYPELIB;
- typeLib->Release();
-#endif
- CoTaskMemFree((void *)typeLibPath);
- }
-#else
- if( FAILED(LoadTypeLibEx((LPOLESTR)DllPath, REGKIND_REGISTER, &typeLib)) )
- return SELFREG_E_TYPELIB;
- typeLib->Release();
+ _tcscpy(DllPath+DllPathLen-4, TEXT(".tlb"));
#endif
- CoTaskMemFree((void *)psz_CLSID);
+ // register type lib into the registry
+ ITypeLib *typeLib;
+
+ HRESULT result = LoadTypeLibEx(DllPath, REGKIND_REGISTER, &typeLib);
+ if( SUCCEEDED(result) )
+ typeLib->Release();
- return S_OK;
+ return result;
};
#ifdef BUILD_LOCALSERVER
return 0;
DWORD dwRegisterClassObject;
+ DWORD dwRegisterClassObject2;
if( FAILED(CoRegisterClassObject(CLSID_VLCPlugin, classProc,
CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegisterClassObject)) )
ACTIVEOBJECT_WEAK, &dwRegisterActiveObject)) )
return 0;
+ if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin2,
+ ACTIVEOBJECT_WEAK, &dwRegisterActiveObject2)) )
+ return 0;
+
classProc->Release();
/*
while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
{
if( msg.message == WM_QUIT )
- break; // Leave the PeekMessage while() loop
+ break; // break out PeekMessage loop
/*if(TranslateAccelerator(ghwndApp, ghAccel, &msg))
continue;*/
}
if(msg.message == WM_QUIT)
- break; // Leave the for() loop
+ break; // break out main loop
WaitMessage();
}
if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject, NULL)) )
CoRevokeClassObject(dwRegisterClassObject);
+ if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject2, NULL)) )
+ CoRevokeClassObject(dwRegisterClassObject2);
+
// Reached on WM_QUIT message
- CoUninitialize();
+ OleUninitialize();
return ((int) msg.wParam);
};