- modified windows installer to register new shell ext dll for drag/drop.
- stopped release shell ext dll from crashing by initializing ref counting members. - added logging to shell ext dll to debug crash.
This commit is contained in:
parent
bf0204e7c2
commit
501e894d03
|
@ -62,6 +62,7 @@ InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\${product}" ""
|
||||||
Delete "${dir}\launcher.exe"
|
Delete "${dir}\launcher.exe"
|
||||||
Delete "${dir}\synrgyhk.dll"
|
Delete "${dir}\synrgyhk.dll"
|
||||||
Delete "${dir}\synwinhk.dll"
|
Delete "${dir}\synwinhk.dll"
|
||||||
|
Delete "${dir}\synwinxt.dll"
|
||||||
Delete "${dir}\libgcc_s_dw2-1.dll"
|
Delete "${dir}\libgcc_s_dw2-1.dll"
|
||||||
Delete "${dir}\mingwm10.dll"
|
Delete "${dir}\mingwm10.dll"
|
||||||
Delete "${dir}\QtCore4.dll"
|
Delete "${dir}\QtCore4.dll"
|
||||||
|
@ -162,6 +163,7 @@ Section "Server and Client" core
|
||||||
File "${binDir}\Release\synergys.exe"
|
File "${binDir}\Release\synergys.exe"
|
||||||
File "${binDir}\Release\synergyc.exe"
|
File "${binDir}\Release\synergyc.exe"
|
||||||
File "${binDir}\Release\synergyd.exe"
|
File "${binDir}\Release\synergyd.exe"
|
||||||
|
File "${binDir}\Release\synwinxt.dll"
|
||||||
|
|
||||||
; if the hook file exists, skip, assuming it couldn't be deleted
|
; if the hook file exists, skip, assuming it couldn't be deleted
|
||||||
; because it was in use by some process.
|
; because it was in use by some process.
|
||||||
|
@ -175,6 +177,9 @@ Section "Server and Client" core
|
||||||
DetailPrint "Adding firewall exception"
|
DetailPrint "Adding firewall exception"
|
||||||
nsExec::ExecToStack "netsh firewall add allowedprogram $\"$INSTDIR\synergys.exe$\" Synergy ENABLE"
|
nsExec::ExecToStack "netsh firewall add allowedprogram $\"$INSTDIR\synergys.exe$\" Synergy ENABLE"
|
||||||
|
|
||||||
|
; install the windows shell extension
|
||||||
|
ExecWait "regsvr32 /s $\"$INSTDIR\synwinxt.dll$\""
|
||||||
|
|
||||||
; install and run the service
|
; install and run the service
|
||||||
ExecWait "$INSTDIR\synergyd.exe /install"
|
ExecWait "$INSTDIR\synergyd.exe /install"
|
||||||
|
|
||||||
|
@ -221,6 +226,9 @@ Section Uninstall
|
||||||
DeleteRegKey HKLM "SOFTWARE\${product}"
|
DeleteRegKey HKLM "SOFTWARE\${product}"
|
||||||
DeleteRegKey HKLM "${controlPanelReg}\${product}"
|
DeleteRegKey HKLM "${controlPanelReg}\${product}"
|
||||||
|
|
||||||
|
; uninstall the windows shell extension
|
||||||
|
ExecWait "regsvr32 /s /u $\"$INSTDIR\synwinxt.dll$\""
|
||||||
|
|
||||||
; note: edit macro to delete more files.
|
; note: edit macro to delete more files.
|
||||||
!insertmacro DeleteFiles $INSTDIR
|
!insertmacro DeleteFiles $INSTDIR
|
||||||
Delete "$INSTDIR\${uninstall}"
|
Delete "$INSTDIR\${uninstall}"
|
||||||
|
|
|
@ -20,47 +20,64 @@
|
||||||
#include <Shlwapi.h>
|
#include <Shlwapi.h>
|
||||||
|
|
||||||
extern LONG g_refCount;
|
extern LONG g_refCount;
|
||||||
|
extern void outputDebugStringF(const char *str, ...);
|
||||||
|
|
||||||
CClassFactory::CClassFactory()
|
CClassFactory::CClassFactory() :
|
||||||
|
m_refCount(1)
|
||||||
{
|
{
|
||||||
|
outputDebugStringF("synwinxt: > CClassFactory::ctor, g_refCount=%d", g_refCount);
|
||||||
InterlockedIncrement(&g_refCount);
|
InterlockedIncrement(&g_refCount);
|
||||||
|
outputDebugStringF("synwinxt: < CClassFactory::ctor, g_refCount=%d", g_refCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
CClassFactory::~CClassFactory()
|
CClassFactory::~CClassFactory()
|
||||||
{
|
{
|
||||||
|
outputDebugStringF("synwinxt: > CClassFactory::dtor, g_refCount=%d", g_refCount);
|
||||||
InterlockedDecrement(&g_refCount);
|
InterlockedDecrement(&g_refCount);
|
||||||
|
outputDebugStringF("synwinxt: < CClassFactory::dtor, g_refCount=%d", g_refCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE
|
HRESULT STDMETHODCALLTYPE
|
||||||
CClassFactory::QueryInterface(REFIID riid, void **ppvObject)
|
CClassFactory::QueryInterface(REFIID riid, void **ppvObject)
|
||||||
{
|
{
|
||||||
|
outputDebugStringF("synwinxt: > CClassFactory::QueryInterface");
|
||||||
static const QITAB qit[] =
|
static const QITAB qit[] =
|
||||||
{
|
{
|
||||||
QITABENT(CClassFactory, IClassFactory),
|
QITABENT(CClassFactory, IClassFactory),
|
||||||
{ 0 },
|
{ 0 },
|
||||||
};
|
};
|
||||||
return QISearch(this, qit, riid, ppvObject);
|
HRESULT hr = QISearch(this, qit, riid, ppvObject);
|
||||||
|
|
||||||
|
outputDebugStringF("synwinxt: < CClassFactory::QueryInterface, hr=%d", hr);
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE
|
ULONG STDMETHODCALLTYPE
|
||||||
CClassFactory::AddRef()
|
CClassFactory::AddRef()
|
||||||
{
|
{
|
||||||
return InterlockedIncrement(&m_refCount);
|
outputDebugStringF("synwinxt: > CClassFactory::AddRef, m_refCount=%d", m_refCount);
|
||||||
|
LONG r = InterlockedIncrement(&m_refCount);
|
||||||
|
outputDebugStringF("synwinxt: < CClassFactory::AddRef, r=%d, m_refCount=%d", r, m_refCount);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE
|
ULONG STDMETHODCALLTYPE
|
||||||
CClassFactory::Release()
|
CClassFactory::Release()
|
||||||
{
|
{
|
||||||
LONG count = InterlockedDecrement(&m_refCount);
|
outputDebugStringF("synwinxt: > CClassFactory::Release, m_refCount=%d", m_refCount);
|
||||||
if (count == 0) {
|
LONG r = InterlockedDecrement(&m_refCount);
|
||||||
|
if (r == 0) {
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
return count;
|
|
||||||
|
outputDebugStringF("synwinxt: < CClassFactory::Release, r=%d", r);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE
|
HRESULT STDMETHODCALLTYPE
|
||||||
CClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
|
CClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
|
||||||
{
|
{
|
||||||
|
outputDebugStringF("synwinxt: > CClassFactory::CreateInstance");
|
||||||
if (pUnkOuter != NULL) {
|
if (pUnkOuter != NULL) {
|
||||||
return CLASS_E_NOAGGREGATION;
|
return CLASS_E_NOAGGREGATION;
|
||||||
}
|
}
|
||||||
|
@ -71,17 +88,20 @@ CClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject
|
||||||
delete pExtension;
|
delete pExtension;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outputDebugStringF("synwinxt: < CClassFactory::CreateInstance, hr=%d", hr);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE
|
HRESULT STDMETHODCALLTYPE
|
||||||
CClassFactory::LockServer(BOOL fLock)
|
CClassFactory::LockServer(BOOL fLock)
|
||||||
{
|
{
|
||||||
|
outputDebugStringF("synwinxt: > CClassFactory::LockServer, g_refCount=%d", g_refCount);
|
||||||
if (fLock) {
|
if (fLock) {
|
||||||
InterlockedIncrement(&g_refCount);
|
InterlockedIncrement(&g_refCount);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
InterlockedDecrement(&g_refCount);
|
InterlockedDecrement(&g_refCount);
|
||||||
}
|
}
|
||||||
|
outputDebugStringF("synwinxt: < CClassFactory::LockServer, g_refCount=%d", g_refCount);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,58 +24,82 @@ extern GUID g_CLSID;
|
||||||
extern void updateDraggingDir(char*);
|
extern void updateDraggingDir(char*);
|
||||||
extern void outputDebugStringF(const char *str, ...);
|
extern void outputDebugStringF(const char *str, ...);
|
||||||
|
|
||||||
CDataHandlerExtension::CDataHandlerExtension()
|
CDataHandlerExtension::CDataHandlerExtension() :
|
||||||
|
m_refCount(1)
|
||||||
{
|
{
|
||||||
|
outputDebugStringF("synwinxt: > CDataHandlerExtension::ctor, g_refCount=%d", g_refCount);
|
||||||
InterlockedIncrement(&g_refCount);
|
InterlockedIncrement(&g_refCount);
|
||||||
|
outputDebugStringF("synwinxt: < CDataHandlerExtension::ctor, g_refCount=%d", g_refCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
CDataHandlerExtension::~CDataHandlerExtension()
|
CDataHandlerExtension::~CDataHandlerExtension()
|
||||||
{
|
{
|
||||||
|
outputDebugStringF("synwinxt: > CDataHandlerExtension::dtor, g_refCount=%d", g_refCount);
|
||||||
InterlockedDecrement(&g_refCount);
|
InterlockedDecrement(&g_refCount);
|
||||||
|
outputDebugStringF("synwinxt: < CDataHandlerExtension::dtor, g_refCount=%d", g_refCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE
|
HRESULT STDMETHODCALLTYPE
|
||||||
CDataHandlerExtension::QueryInterface(REFIID riid, void **ppvObject)
|
CDataHandlerExtension::QueryInterface(REFIID riid, void **ppvObject)
|
||||||
{
|
{
|
||||||
|
outputDebugStringF("synwinxt: > CDataHandlerExtension::QueryInterface");
|
||||||
static const QITAB qit[] =
|
static const QITAB qit[] =
|
||||||
{
|
{
|
||||||
QITABENT(CDataHandlerExtension, IPersistFile),
|
QITABENT(CDataHandlerExtension, IPersistFile),
|
||||||
QITABENT(CDataHandlerExtension, IDataObject),
|
QITABENT(CDataHandlerExtension, IDataObject),
|
||||||
{ 0 },
|
{ 0 },
|
||||||
};
|
};
|
||||||
return QISearch(this, qit, riid, ppvObject);
|
HRESULT hr = QISearch(this, qit, riid, ppvObject);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
outputDebugStringF("synwinxt: < CDataHandlerExtension::QueryInterface, hr=FAILED");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
outputDebugStringF("synwinxt: < CDataHandlerExtension::QueryInterface, hr=%d", hr);
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE
|
ULONG STDMETHODCALLTYPE
|
||||||
CDataHandlerExtension::AddRef()
|
CDataHandlerExtension::AddRef()
|
||||||
{
|
{
|
||||||
return InterlockedIncrement(&m_refCount);
|
outputDebugStringF("synwinxt: > CDataHandlerExtension::AddRef, m_refCount=%d", m_refCount);
|
||||||
|
LONG r = InterlockedIncrement(&m_refCount);
|
||||||
|
outputDebugStringF("synwinxt: < CDataHandlerExtension::AddRef, r=%d, m_refCount=%d", r, m_refCount);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDMETHODCALLTYPE
|
ULONG STDMETHODCALLTYPE
|
||||||
CDataHandlerExtension::Release()
|
CDataHandlerExtension::Release()
|
||||||
{
|
{
|
||||||
LONG count = InterlockedDecrement(&m_refCount);
|
outputDebugStringF("synwinxt: > CDataHandlerExtension::Release, m_refCount=%d", m_refCount);
|
||||||
if (count == 0) {
|
LONG r = InterlockedDecrement(&m_refCount);
|
||||||
|
if (r == 0) {
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
return count;
|
outputDebugStringF("synwinxt: < CDataHandlerExtension::Release, r=%d", r);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE
|
HRESULT STDMETHODCALLTYPE
|
||||||
CDataHandlerExtension::Load(__RPC__in LPCOLESTR pszFileName, DWORD dwMode)
|
CDataHandlerExtension::Load(__RPC__in LPCOLESTR pszFileName, DWORD dwMode)
|
||||||
{
|
{
|
||||||
|
outputDebugStringF("synwinxt: > CDataHandlerExtension::Load");
|
||||||
|
|
||||||
char selectedFileDir[MAX_PATH];
|
char selectedFileDir[MAX_PATH];
|
||||||
StringCchCopyW(m_selectedFileDir, ARRAYSIZE(m_selectedFileDir), pszFileName);
|
StringCchCopyW(m_selectedFileDir, ARRAYSIZE(m_selectedFileDir), pszFileName);
|
||||||
WideCharToMultiByte(CP_ACP, 0, m_selectedFileDir, -1, selectedFileDir, MAX_PATH, NULL, NULL);
|
WideCharToMultiByte(CP_ACP, 0, m_selectedFileDir, -1, selectedFileDir, MAX_PATH, NULL, NULL);
|
||||||
updateDraggingDir(selectedFileDir);
|
updateDraggingDir(selectedFileDir);
|
||||||
|
|
||||||
|
outputDebugStringF("synwinxt: < CDataHandlerExtension::Load");
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE
|
HRESULT STDMETHODCALLTYPE
|
||||||
CDataHandlerExtension::GetClassID(__RPC__out CLSID *pClassID)
|
CDataHandlerExtension::GetClassID(__RPC__out CLSID *pClassID)
|
||||||
{
|
{
|
||||||
|
outputDebugStringF("synwinxt: > CDataHandlerExtension::GetClassID");
|
||||||
*pClassID = g_CLSID;
|
*pClassID = g_CLSID;
|
||||||
|
outputDebugStringF("synwinxt: < CDataHandlerExtension::GetClassID");
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,199 +43,6 @@ HRESULT registerInprocServer(CHAR* module, const CLSID& clsid, CHAR* threadModel
|
||||||
HRESULT registerShellExtDataHandler(CHAR* fileType, const CLSID& clsid);
|
HRESULT registerShellExtDataHandler(CHAR* fileType, const CLSID& clsid);
|
||||||
HRESULT unregisterShellExtDataHandler(CHAR* fileType, const CLSID& clsid);
|
HRESULT unregisterShellExtDataHandler(CHAR* fileType, const CLSID& clsid);
|
||||||
HRESULT unregisterInprocServer(const CLSID& clsid);
|
HRESULT unregisterInprocServer(const CLSID& clsid);
|
||||||
void outputDebugStringF(const char *str, ...);
|
|
||||||
|
|
||||||
BOOL APIENTRY
|
|
||||||
DllMain(HMODULE module, DWORD reason, LPVOID reserved)
|
|
||||||
{
|
|
||||||
switch (reason) {
|
|
||||||
case DLL_PROCESS_ATTACH:
|
|
||||||
g_instance = module;
|
|
||||||
DisableThreadLibraryCalls(module);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DLL_THREAD_ATTACH:
|
|
||||||
break;
|
|
||||||
case DLL_THREAD_DETACH:
|
|
||||||
break;
|
|
||||||
case DLL_PROCESS_DETACH:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDAPI
|
|
||||||
DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppvObj)
|
|
||||||
{
|
|
||||||
HRESULT hr = E_OUTOFMEMORY;
|
|
||||||
*ppvObj = NULL;
|
|
||||||
|
|
||||||
CClassFactory *classFactory = new CClassFactory();
|
|
||||||
if (classFactory != NULL) {
|
|
||||||
hr = classFactory->QueryInterface(riid, ppvObj);
|
|
||||||
classFactory->Release();
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDAPI
|
|
||||||
DllCanUnloadNow()
|
|
||||||
{
|
|
||||||
return g_refCount > 0 ? S_FALSE : S_OK;
|
|
||||||
}
|
|
||||||
STDAPI
|
|
||||||
DllRegisterServer()
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
CHAR module[MAX_PATH];
|
|
||||||
if (GetModuleFileName(g_instance, module, ARRAYSIZE(module)) == 0) {
|
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register the component.
|
|
||||||
hr = registerInprocServer(
|
|
||||||
module,
|
|
||||||
g_CLSID,
|
|
||||||
"Apartment");
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
hr = registerShellExtDataHandler(
|
|
||||||
"*",
|
|
||||||
g_CLSID);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDAPI
|
|
||||||
DllUnregisterServer()
|
|
||||||
{
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
|
|
||||||
CHAR module[MAX_PATH];
|
|
||||||
if (GetModuleFileName(g_instance, module, ARRAYSIZE(module)) == 0) {
|
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unregister the component.
|
|
||||||
hr = unregisterInprocServer(g_CLSID);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
// Unregister the context menu handler.
|
|
||||||
hr = unregisterShellExtDataHandler("*", g_CLSID);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
registerInprocServer(CHAR* module, const CLSID& clsid, CHAR* threadModel)
|
|
||||||
{
|
|
||||||
if (module == NULL || threadModel == NULL) {
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
WCHAR CLASSID[MAX_PATH];
|
|
||||||
CHAR szCLSID[MAX_PATH];
|
|
||||||
StringFromGUID2(clsid, CLASSID, ARRAYSIZE(CLASSID));
|
|
||||||
WideCharToMultiByte(CP_ACP, 0, CLASSID, -1, szCLSID, MAX_PATH, NULL, NULL);
|
|
||||||
|
|
||||||
CHAR subkey[MAX_PATH];
|
|
||||||
|
|
||||||
// Create the HKCR\CLSID\{<CLSID>}\InprocServer32 key.
|
|
||||||
hr = StringCchPrintf(subkey, ARRAYSIZE(subkey), "CLSID\\%s\\InprocServer32", szCLSID);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
// Set the default value of the InprocServer32 key to the
|
|
||||||
// path of the COM module.
|
|
||||||
HKEY key = CArchMiscWindows::addKey(HKEY_CLASSES_ROOT, subkey);
|
|
||||||
CArchMiscWindows::setValue(key, NULL, module);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
// Set the threading model of the component.
|
|
||||||
CArchMiscWindows::setValue(key, "ThreadingModel", threadModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
unregisterInprocServer(const CLSID& clsid)
|
|
||||||
{
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
|
|
||||||
WCHAR CLASSID[MAX_PATH];
|
|
||||||
CHAR szCLSID[MAX_PATH];
|
|
||||||
StringFromGUID2(clsid, CLASSID, ARRAYSIZE(CLASSID));
|
|
||||||
WideCharToMultiByte(CP_ACP, 0, CLASSID, -1, szCLSID, MAX_PATH, NULL, NULL);
|
|
||||||
|
|
||||||
CHAR subkey[MAX_PATH];
|
|
||||||
|
|
||||||
// Delete the HKCR\CLSID\{<CLSID>} key.
|
|
||||||
hr = StringCchPrintf(subkey, ARRAYSIZE(subkey), "CLSID\\%s", szCLSID);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, subkey));
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
registerShellExtDataHandler(CHAR* fileType, const CLSID& clsid)
|
|
||||||
{
|
|
||||||
if (fileType == NULL) {
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
WCHAR szCLSID[MAX_PATH];
|
|
||||||
CHAR CLASSID[MAX_PATH];
|
|
||||||
StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID));
|
|
||||||
WideCharToMultiByte(CP_ACP, 0, szCLSID, -1, CLASSID, MAX_PATH, NULL, NULL);
|
|
||||||
|
|
||||||
CHAR subkey[MAX_PATH];
|
|
||||||
|
|
||||||
// Create the key HKCR\<File Type>\shellex\DataHandler
|
|
||||||
hr = StringCchPrintf(subkey, ARRAYSIZE(subkey), "%s\\shellex\\DataHandler", fileType);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
// Set the default value of the key.
|
|
||||||
HKEY key = CArchMiscWindows::addKey(HKEY_CLASSES_ROOT, subkey);
|
|
||||||
CArchMiscWindows::setValue(key, NULL, CLASSID);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT
|
|
||||||
unregisterShellExtDataHandler(CHAR* fileType, const CLSID& clsid)
|
|
||||||
{
|
|
||||||
if (fileType == NULL) {
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
WCHAR CLASSID[MAX_PATH];
|
|
||||||
CHAR szCLSID[MAX_PATH];
|
|
||||||
StringFromGUID2(clsid, CLASSID, ARRAYSIZE(CLASSID));
|
|
||||||
WideCharToMultiByte(CP_ACP, 0, CLASSID, -1, szCLSID, MAX_PATH, NULL, NULL);
|
|
||||||
|
|
||||||
CHAR subkey[MAX_PATH];
|
|
||||||
|
|
||||||
// Remove the HKCR\<File Type>\shellex\DataHandler key.
|
|
||||||
hr = StringCchPrintf(subkey, ARRAYSIZE(subkey), "%s\\shellex\\DataHandler", fileType);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, subkey));
|
|
||||||
}
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
outputDebugStringF(const char* str, ...)
|
outputDebugStringF(const char* str, ...)
|
||||||
|
@ -249,15 +56,243 @@ outputDebugStringF(const char* str, ...)
|
||||||
OutputDebugStringA(buf);
|
OutputDebugStringA(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL APIENTRY
|
||||||
|
DllMain(HMODULE module, DWORD reason, LPVOID reserved)
|
||||||
|
{
|
||||||
|
outputDebugStringF("synwinxt: > DllMain, reason=%d", reason);
|
||||||
|
|
||||||
|
switch (reason) {
|
||||||
|
case DLL_PROCESS_ATTACH:
|
||||||
|
g_instance = module;
|
||||||
|
DisableThreadLibraryCalls(module);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DLL_THREAD_ATTACH:
|
||||||
|
break;
|
||||||
|
case DLL_THREAD_DETACH:
|
||||||
|
break;
|
||||||
|
case DLL_PROCESS_DETACH:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
outputDebugStringF("synwinxt: < DllMain");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDAPI
|
||||||
|
DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppvObj)
|
||||||
|
{
|
||||||
|
outputDebugStringF("synwinxt: > DllGetClassObject");
|
||||||
|
|
||||||
|
HRESULT hr = E_OUTOFMEMORY;
|
||||||
|
*ppvObj = NULL;
|
||||||
|
|
||||||
|
CClassFactory *classFactory = new CClassFactory();
|
||||||
|
if (classFactory != NULL) {
|
||||||
|
hr = classFactory->QueryInterface(riid, ppvObj);
|
||||||
|
classFactory->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
outputDebugStringF("synwinxt: < DllGetClassObject, hr=%d", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDAPI
|
||||||
|
DllCanUnloadNow()
|
||||||
|
{
|
||||||
|
outputDebugStringF("synwinxt: > DllCanUnloadNow, g_refCount=%d", g_refCount);
|
||||||
|
int r = g_refCount > 0 ? S_FALSE : S_OK;
|
||||||
|
outputDebugStringF("synwinxt: < DllCanUnloadNow, g_refCount=%d, r=%d", g_refCount, r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
STDAPI
|
||||||
|
DllRegisterServer()
|
||||||
|
{
|
||||||
|
outputDebugStringF("synwinxt: > DllRegisterServer");
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
CHAR module[MAX_PATH];
|
||||||
|
if (GetModuleFileName(g_instance, module, ARRAYSIZE(module)) == 0) {
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
outputDebugStringF("synwinxt: < DllRegisterServer, hr=%d", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = registerInprocServer(
|
||||||
|
module,
|
||||||
|
g_CLSID,
|
||||||
|
"Apartment");
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
hr = registerShellExtDataHandler(
|
||||||
|
"*",
|
||||||
|
g_CLSID);
|
||||||
|
}
|
||||||
|
|
||||||
|
outputDebugStringF("synwinxt: < DllRegisterServer, hr=%d", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDAPI
|
||||||
|
DllUnregisterServer()
|
||||||
|
{
|
||||||
|
outputDebugStringF("synwinxt: > DllUnregisterServer");
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
CHAR module[MAX_PATH];
|
||||||
|
if (GetModuleFileName(g_instance, module, ARRAYSIZE(module)) == 0) {
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
outputDebugStringF("synwinxt: < DllRegisterServer, hr=%d", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = unregisterInprocServer(g_CLSID);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
hr = unregisterShellExtDataHandler("*", g_CLSID);
|
||||||
|
}
|
||||||
|
|
||||||
|
outputDebugStringF("synwinxt: < DllUnregisterServer, hr=%d", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
registerInprocServer(CHAR* module, const CLSID& clsid, CHAR* threadModel)
|
||||||
|
{
|
||||||
|
outputDebugStringF("synwinxt: > registerInprocServer");
|
||||||
|
|
||||||
|
if (module == NULL || threadModel == NULL) {
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
WCHAR CLASSID[MAX_PATH];
|
||||||
|
CHAR szCLSID[MAX_PATH];
|
||||||
|
StringFromGUID2(clsid, CLASSID, ARRAYSIZE(CLASSID));
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, CLASSID, -1, szCLSID, MAX_PATH, NULL, NULL);
|
||||||
|
|
||||||
|
CHAR subkey[MAX_PATH];
|
||||||
|
|
||||||
|
// create the HKCR\CLSID\{<CLSID>}\InprocServer32 key.
|
||||||
|
hr = StringCchPrintf(subkey, ARRAYSIZE(subkey), "CLSID\\%s\\InprocServer32", szCLSID);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
// set the default value of the InprocServer32 key to the
|
||||||
|
// path of the COM module.
|
||||||
|
HKEY key = CArchMiscWindows::addKey(HKEY_CLASSES_ROOT, subkey);
|
||||||
|
CArchMiscWindows::setValue(key, NULL, module);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
// set the threading model of the component.
|
||||||
|
CArchMiscWindows::setValue(key, "ThreadingModel", threadModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outputDebugStringF("synwinxt: < registerInprocServer, hr=%d", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
unregisterInprocServer(const CLSID& clsid)
|
||||||
|
{
|
||||||
|
outputDebugStringF("synwinxt: > unregisterInprocServer");
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
WCHAR CLASSID[MAX_PATH];
|
||||||
|
CHAR szCLSID[MAX_PATH];
|
||||||
|
StringFromGUID2(clsid, CLASSID, ARRAYSIZE(CLASSID));
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, CLASSID, -1, szCLSID, MAX_PATH, NULL, NULL);
|
||||||
|
|
||||||
|
CHAR subkey[MAX_PATH];
|
||||||
|
|
||||||
|
// delete the HKCR\CLSID\{<CLSID>} key.
|
||||||
|
hr = StringCchPrintf(subkey, ARRAYSIZE(subkey), "CLSID\\%s", szCLSID);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, subkey));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
outputDebugStringF("synwinxt: < unregisterInprocServer, hr=FAILED");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
outputDebugStringF("synwinxt: < unregisterInprocServer, hr=%d", hr);
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
registerShellExtDataHandler(CHAR* fileType, const CLSID& clsid)
|
||||||
|
{
|
||||||
|
outputDebugStringF("synwinxt: > registerShellExtDataHandler");
|
||||||
|
|
||||||
|
if (fileType == NULL) {
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
WCHAR szCLSID[MAX_PATH];
|
||||||
|
CHAR CLASSID[MAX_PATH];
|
||||||
|
StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID));
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, szCLSID, -1, CLASSID, MAX_PATH, NULL, NULL);
|
||||||
|
|
||||||
|
CHAR subkey[MAX_PATH];
|
||||||
|
|
||||||
|
// create the key HKCR\<File Type>\shellex\DataHandler
|
||||||
|
hr = StringCchPrintf(subkey, ARRAYSIZE(subkey), "%s\\shellex\\DataHandler", fileType);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
// set the default value of the key.
|
||||||
|
HKEY key = CArchMiscWindows::addKey(HKEY_CLASSES_ROOT, subkey);
|
||||||
|
CArchMiscWindows::setValue(key, NULL, CLASSID);
|
||||||
|
}
|
||||||
|
|
||||||
|
outputDebugStringF("synwinxt: < registerShellExtDataHandler, hr=%d", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
unregisterShellExtDataHandler(CHAR* fileType, const CLSID& clsid)
|
||||||
|
{
|
||||||
|
outputDebugStringF("synwinxt: > unregisterShellExtDataHandler");
|
||||||
|
|
||||||
|
if (fileType == NULL) {
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
WCHAR CLASSID[MAX_PATH];
|
||||||
|
CHAR szCLSID[MAX_PATH];
|
||||||
|
StringFromGUID2(clsid, CLASSID, ARRAYSIZE(CLASSID));
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, CLASSID, -1, szCLSID, MAX_PATH, NULL, NULL);
|
||||||
|
|
||||||
|
CHAR subkey[MAX_PATH];
|
||||||
|
|
||||||
|
// remove the HKCR\<File Type>\shellex\DataHandler key.
|
||||||
|
hr = StringCchPrintf(subkey, ARRAYSIZE(subkey), "%s\\shellex\\DataHandler", fileType);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, subkey));
|
||||||
|
}
|
||||||
|
|
||||||
|
outputDebugStringF("synwinxt: < unregisterShellExtDataHandler, hr=%d", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
updateDraggingDir(char* dir)
|
updateDraggingDir(char* dir)
|
||||||
{
|
{
|
||||||
|
outputDebugStringF("synwinxt: > updateDraggingDir, dir=%s", dir);
|
||||||
memcpy(g_draggingFileDir, dir, MAX_PATH);
|
memcpy(g_draggingFileDir, dir, MAX_PATH);
|
||||||
outputDebugStringF("draggingFileDir: %s", g_draggingFileDir);
|
outputDebugStringF("synwinxt: < updateDraggingDir, g_draggingFileDir=%s", g_draggingFileDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
getDraggingFileDir(char* dir)
|
getDraggingFileDir(char* dir)
|
||||||
{
|
{
|
||||||
|
outputDebugStringF("synwinxt: > getDraggingFileDir");
|
||||||
memcpy(dir, g_draggingFileDir, MAX_PATH);
|
memcpy(dir, g_draggingFileDir, MAX_PATH);
|
||||||
|
outputDebugStringF("synwinxt: < getDraggingFileDir, dir=%s", dir);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue