mirror of
https://github.com/debauchee/barrier.git
synced 2025-07-15 15:45:38 +02:00
298 lines
7.6 KiB
C++
298 lines
7.6 KiB
C++
/*
|
|
* synergy -- mouse and keyboard sharing utility
|
|
* Copyright (C) 2013 Bolton Software Ltd.
|
|
*
|
|
* This package is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* found in the file COPYING that should have accompanied this file.
|
|
*
|
|
* This package 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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "synwinxt.h"
|
|
#include "CClassFactory.h"
|
|
#include "CArchMiscWindows.h"
|
|
#include <strsafe.h>
|
|
#include <Windows.h>
|
|
|
|
#pragma comment(lib, "Shlwapi.lib")
|
|
|
|
#if defined(_MSC_VER)
|
|
#pragma comment(linker, "-section:sharedData,rws")
|
|
#pragma data_seg("sharedData")
|
|
#endif
|
|
|
|
static BYTE g_draggingFilename[MAX_PATH] = { 0 };
|
|
|
|
#if defined(_MSC_VER)
|
|
#pragma data_seg()
|
|
#endif
|
|
|
|
// {1BE208B1-BC21-4E39-8BB6-A5DC3F51479E}
|
|
GUID g_CLSID = {0x1be208b1, 0xbc21, 0x4e39, {0x8b, 0xb6, 0xa5, 0xdc, 0x3f, 0x51, 0x47, 0x9e}};
|
|
LONG g_refCount = 0;
|
|
HINSTANCE g_instance = NULL;
|
|
|
|
HRESULT registerInprocServer(CHAR* module, const CLSID& clsid, CHAR* threadModel);
|
|
HRESULT registerShellExtDataHandler(CHAR* fileType, const CLSID& clsid);
|
|
HRESULT unregisterShellExtDataHandler(CHAR* fileType, const CLSID& clsid);
|
|
HRESULT unregisterInprocServer(const CLSID& clsid);
|
|
|
|
void
|
|
outputDebugStringF(const char* str, ...)
|
|
{
|
|
char buf[2048];
|
|
|
|
va_list ptr;
|
|
va_start(ptr,str);
|
|
vsprintf_s(buf,str,ptr);
|
|
|
|
OutputDebugStringA(buf);
|
|
}
|
|
|
|
BOOL APIENTRY
|
|
DllMain(HMODULE module, DWORD reason, LPVOID reserved)
|
|
{
|
|
outputDebugStringF("synwinxt: > DllMain, reason=%d\n", 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\n");
|
|
return TRUE;
|
|
}
|
|
|
|
STDAPI
|
|
DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppvObj)
|
|
{
|
|
outputDebugStringF("synwinxt: > DllGetClassObject\n");
|
|
|
|
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\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDAPI
|
|
DllCanUnloadNow()
|
|
{
|
|
outputDebugStringF("synwinxt: > DllCanUnloadNow, g_refCount=%d\n", g_refCount);
|
|
int r = g_refCount > 0 ? S_FALSE : S_OK;
|
|
outputDebugStringF("synwinxt: < DllCanUnloadNow, g_refCount=%d, r=%d\n", g_refCount, r);
|
|
return r;
|
|
}
|
|
STDAPI
|
|
DllRegisterServer()
|
|
{
|
|
outputDebugStringF("synwinxt: > DllRegisterServer\n");
|
|
|
|
HRESULT hr;
|
|
|
|
CHAR module[MAX_PATH];
|
|
if (GetModuleFileName(g_instance, module, ARRAYSIZE(module)) == 0) {
|
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
|
outputDebugStringF("synwinxt: < DllRegisterServer, hr=%d\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
hr = registerInprocServer(
|
|
module,
|
|
g_CLSID,
|
|
"Apartment");
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
hr = registerShellExtDataHandler(
|
|
"*",
|
|
g_CLSID);
|
|
}
|
|
|
|
outputDebugStringF("synwinxt: < DllRegisterServer, hr=%d\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDAPI
|
|
DllUnregisterServer()
|
|
{
|
|
outputDebugStringF("synwinxt: > DllUnregisterServer\n");
|
|
|
|
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\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
hr = unregisterInprocServer(g_CLSID);
|
|
if (SUCCEEDED(hr)) {
|
|
hr = unregisterShellExtDataHandler("*", g_CLSID);
|
|
}
|
|
|
|
outputDebugStringF("synwinxt: < DllUnregisterServer, hr=%d\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
registerInprocServer(CHAR* module, const CLSID& clsid, CHAR* threadModel)
|
|
{
|
|
outputDebugStringF("synwinxt: > registerInprocServer\n");
|
|
|
|
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\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
unregisterInprocServer(const CLSID& clsid)
|
|
{
|
|
outputDebugStringF("synwinxt: > unregisterInprocServer\n");
|
|
|
|
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\n");
|
|
}
|
|
else {
|
|
outputDebugStringF("synwinxt: < unregisterInprocServer, hr=%d\n", hr);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
registerShellExtDataHandler(CHAR* fileType, const CLSID& clsid)
|
|
{
|
|
outputDebugStringF("synwinxt: > registerShellExtDataHandler\n");
|
|
|
|
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\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
unregisterShellExtDataHandler(CHAR* fileType, const CLSID& clsid)
|
|
{
|
|
outputDebugStringF("synwinxt: > unregisterShellExtDataHandler\n");
|
|
|
|
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\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
void
|
|
setDraggingFilename(const char* filename)
|
|
{
|
|
outputDebugStringF("synwinxt: > setDraggingFilename, filename=%s\n", filename);
|
|
memcpy(g_draggingFilename, filename, MAX_PATH);
|
|
outputDebugStringF("synwinxt: < setDraggingFilename, g_draggingFilename=%s\n", g_draggingFilename);
|
|
}
|
|
|
|
void
|
|
getDraggingFilename(char* filename)
|
|
{
|
|
outputDebugStringF("synwinxt: > getDraggingFilename\n");
|
|
memcpy(filename, g_draggingFilename, MAX_PATH);
|
|
outputDebugStringF("synwinxt: < getDraggingFilename, filename=%s\n", filename);
|
|
}
|