aboutsummaryrefslogtreecommitdiff
path: root/Src/Elevator/Elevator.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Elevator/Elevator.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Elevator/Elevator.cpp')
-rw-r--r--Src/Elevator/Elevator.cpp308
1 files changed, 308 insertions, 0 deletions
diff --git a/Src/Elevator/Elevator.cpp b/Src/Elevator/Elevator.cpp
new file mode 100644
index 00000000..24e3ee92
--- /dev/null
+++ b/Src/Elevator/Elevator.cpp
@@ -0,0 +1,308 @@
+// Elevator.cpp : Implementation of WinMain
+
+#include "stdafx.h"
+#include "resource1.h"
+#include "FileTypeRegistrar.h"
+#include "ElevatorFactory.h"
+#include <sddl.h>
+#include <strsafe.h>
+
+HRESULT RegisterServer(HINSTANCE hInstance);
+HRESULT UnregisterServer(HINSTANCE hInstance);
+
+DWORD g_allLocks = 0;
+int APIENTRY WinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+ if (lpCmdLine == NULL || !*lpCmdLine)
+ {
+ MSGBOXPARAMSW msgbx = {sizeof(MSGBOXPARAMS),0};
+ msgbx.lpszText = L"Winamp Elevator\nCopyright © 2008-2014 Winamp SA";
+ msgbx.lpszCaption = L"About...";
+ msgbx.lpszIcon = MAKEINTRESOURCEW(IDI_ICON1);
+ msgbx.hInstance = GetModuleHandle(0);
+ msgbx.dwStyle = MB_USERICON;
+ MessageBoxIndirectW(&msgbx);
+ return 0;
+ }
+
+ if ( lpCmdLine != NULL && ( _strcmpi( lpCmdLine, "/RegServer" ) == 0
+ || _strcmpi( lpCmdLine, "-RegServer" ) == 0 )) {
+ RegisterServer(hInstance);
+ return 0;
+ }
+
+ if ( lpCmdLine != NULL && ( _strcmpi( lpCmdLine, "/UnregServer" ) == 0
+ || _strcmpi( lpCmdLine, "-UnregServer" ) == 0 )) {
+ UnregisterServer(hInstance);
+ return 0;
+ }
+ CoInitialize(NULL);
+
+ if(lpCmdLine && (strstr(lpCmdLine, "/Embedding") || strstr(lpCmdLine, "-Embedding")))
+ {
+ ElevatorFactory cf;
+ DWORD regID = 0;
+ CoRegisterClassObject(CLSID_WFileTypeRegistrar,(IClassFactory*)&cf, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &regID);
+ MSG ms;
+ while(GetMessage(&ms, 0, 0, 0))
+ {
+ TranslateMessage(&ms);
+ DispatchMessage(&ms);
+ }
+
+ CoRevokeClassObject(regID);
+ }
+
+ CoUninitialize();
+ return 0;
+}
+
+extern FileTypeRegistrar registrar;
+
+void Lock()
+{
+ ++g_allLocks;
+}
+
+void UnLock()
+{
+ --g_allLocks;
+ if(g_allLocks == 0 )//&& registrar.refCount == 0/* benski> a hack, for now */)
+ {
+ PostQuitMessage(0);
+ }
+}
+
+static BOOL GetAccessPermissionsForLUAServer(SECURITY_DESCRIPTOR **ppSD)
+{
+// Local call permissions to IU, SY
+ LPWSTR lpszSDDL = L"O:BAG:BAD:(A;;0x3;;;IU)(A;;0x3;;;SY)";
+ SECURITY_DESCRIPTOR *pSD;
+ *ppSD = NULL;
+
+ if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR *)&pSD, NULL))
+ {
+ *ppSD = pSD;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// hKey is the HKCR\AppID\{GUID} key
+static BOOL SetAccessPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD)
+{
+ BOOL bResult = FALSE;
+ DWORD dwLen = GetSecurityDescriptorLength(pSD);
+ LONG lResult;
+ lResult = RegSetValueExA(hkey,
+ "AccessPermission",
+ 0,
+ REG_BINARY,
+ (BYTE*)pSD,
+ dwLen);
+ if (lResult != ERROR_SUCCESS) goto done;
+ bResult = TRUE;
+done:
+ return bResult;
+}
+
+static BOOL GetLaunchActPermissionsWithIL (SECURITY_DESCRIPTOR **ppSD)
+{
+ // Allow World Local Launch/Activation permissions. Label the SD for LOW IL Execute UP
+ LPWSTR lpszSDDL = L"O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)";
+ SECURITY_DESCRIPTOR *pSD;
+ if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR *)&pSD, NULL))
+ {
+ *ppSD = pSD;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static BOOL SetLaunchActPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD)
+{
+ BOOL bResult = FALSE;
+ DWORD dwLen = GetSecurityDescriptorLength(pSD);
+ LONG lResult;
+ lResult = RegSetValueExA(hkey,
+ "LaunchPermission",
+ 0,
+ REG_BINARY,
+ (BYTE*)pSD,
+ dwLen);
+ if (lResult != ERROR_SUCCESS) goto done;
+ bResult = TRUE;
+done:
+ return bResult;
+};
+
+static HRESULT UnregisterComponent(const CLSID &clsid, LPCWSTR pszVersionIndProgId, LPCWSTR pszProgId);
+static HRESULT RegisterComponent(HMODULE hModule, const CLSID &clsid, LPCWSTR pszFriendlyName, LPCWSTR pszVersionIndProgId, LPCWSTR pszProgId);
+
+static const WCHAR szComponentFriendlyName[] = L"Winamp Elevator";
+static const WCHAR szVersionIndependentProgId[] = L"Elevator.WFileTypeRegistrar2";
+static const WCHAR szProgId[] = L"Elevator.WFileTypeRegistrar2.1";
+
+HRESULT RegisterServer(HINSTANCE hInstance)
+{
+ HRESULT hr(S_OK);
+ hr = RegisterComponent(hInstance, CLSID_WFileTypeRegistrar, szComponentFriendlyName, szVersionIndependentProgId, szProgId);
+ return hr;
+}
+
+HRESULT UnregisterServer(HINSTANCE hInstance)
+{
+ HRESULT hr(S_OK);
+ hr = UnregisterComponent(CLSID_WFileTypeRegistrar, szVersionIndependentProgId, szProgId);
+ return hr;
+}
+
+static BOOL WriteRegKey(HKEY hKeyParent, LPCWSTR pszKey, LPCWSTR pszValue, HKEY *phKey = NULL)
+{
+ HKEY hKey;
+ LONG result;
+ result = RegCreateKeyExW(hKeyParent, pszKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
+ if (ERROR_SUCCESS != result || !hKey) return FALSE;
+ if (pszValue)
+ {
+ result = RegSetValueExW(hKey, NULL, 0, REG_SZ, (BYTE*)pszValue, (DWORD)(sizeof(wchar_t)*(1 + lstrlenW(pszValue))));
+ }
+ if (!phKey) RegCloseKey(hKey);
+ else *phKey = hKey;
+
+ return (ERROR_SUCCESS == result);
+}
+
+static BOOL WriteRegValue(HKEY hKeyParent, LPCWSTR pszKey, LPCWSTR pszEntry, LPCWSTR pszValue)
+{
+ HKEY hKey;
+ LONG result;
+ result = RegOpenKeyExW(hKeyParent, pszKey, 0, KEY_SET_VALUE, &hKey);
+ if (ERROR_SUCCESS != result || !hKey) return FALSE;
+ if (pszValue)
+ {
+ result = RegSetValueEx(hKey, pszEntry, 0, REG_SZ, (BYTE*)pszValue, (DWORD)(sizeof(wchar_t)*(1 + lstrlenW(pszValue))));
+ }
+ RegCloseKey(hKey);
+ return (ERROR_SUCCESS == result);
+}
+
+static BOOL WriteRegValue(HKEY hKeyParent, LPCWSTR pszKey, LPCWSTR pszEntry, DWORD pszValue)
+{
+ HKEY hKey;
+ LONG result;
+ result = RegOpenKeyExW(hKeyParent, pszKey, 0, KEY_SET_VALUE, &hKey);
+ if (ERROR_SUCCESS != result || !hKey) return FALSE;
+ if (pszValue)
+ {
+ result = RegSetValueEx(hKey, pszEntry, 0, REG_DWORD, (BYTE*)&pszValue, sizeof(DWORD));
+ }
+ RegCloseKey(hKey);
+ return (ERROR_SUCCESS == result);
+}
+
+static LONG DeleteRegKey(HKEY hKeyParent, LPCWSTR pszKey)
+{
+ HKEY hKey;
+ LONG result;
+ FILETIME time = {0};
+ WCHAR szBuffer[512] = {0};
+ DWORD dwSize = sizeof(szBuffer)/sizeof(WCHAR);
+
+ result = RegOpenKeyExW(hKeyParent, pszKey, 0, KEY_SET_VALUE | KEY_ENUMERATE_SUB_KEYS , &hKey);
+ if (ERROR_SUCCESS != result) return result;
+ while (ERROR_SUCCESS == RegEnumKeyExW(hKey, 0, szBuffer, &dwSize, NULL, NULL, NULL, &time))
+ {
+ if (ERROR_SUCCESS != (result = DeleteRegKey(hKey, szBuffer)))
+ {
+ RegCloseKey(hKey);
+ return result;
+ }
+ dwSize = sizeof(szBuffer)/sizeof(WCHAR);
+ }
+
+ RegCloseKey(hKey);
+ return RegDeleteKeyW(hKeyParent, pszKey);
+}
+
+HRESULT RegisterComponent(HMODULE hModule, const CLSID &clsid, LPCWSTR pszFriendlyName, LPCWSTR pszVersionIndProgId, LPCWSTR pszProgId)
+{
+ SECURITY_DESCRIPTOR *sd;
+ HKEY hKey, hKey2, hKey3;
+ BOOL br;
+ WCHAR szBuffer[MAX_PATH] = {0}, szCLSID[64] = {0};
+
+ if (!StringFromGUID2(clsid, szCLSID, sizeof(szCLSID)/sizeof(WCHAR))) return E_OUTOFMEMORY;
+ StringCchPrintfW(szBuffer, sizeof(szBuffer)/sizeof(WCHAR), L"SOFTWARE\\Classes\\CLSID\\%s", szCLSID);
+
+ if (!WriteRegKey(HKEY_LOCAL_MACHINE, szBuffer, pszFriendlyName, &hKey)) return S_FALSE;
+
+ if (!GetModuleFileNameW(hModule, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) return S_FALSE;
+
+ RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\AppID\\{3B29AB5C-52CB-4a36-9314-E3FEE0BA7468}", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey3, NULL);
+ if (GetAccessPermissionsForLUAServer(&sd))
+ SetAccessPermissions(hKey3, sd);
+ if (GetLaunchActPermissionsWithIL(&sd))
+ SetLaunchActPermissions(hKey3, sd);
+ WriteRegValue(hKey3, NULL, NULL, szBuffer);
+ RegCloseKey(hKey3);
+
+ RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Classes\\AppID\\elevator.exe", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey3, NULL);
+ WriteRegValue(hKey3, NULL, L"AppID", L"{3B29AB5C-52CB-4a36-9314-E3FEE0BA7468}");
+ RegCloseKey(hKey3);
+
+ wchar_t localizedString[MAX_PATH+15] = {0};
+ StringCbPrintf(localizedString, sizeof(localizedString), L"@%s,-%u", szBuffer, IDS_WINAMP);
+
+ br = (WriteRegKey(hKey, L"LocalServer32" , szBuffer, &hKey2) &&
+ WriteRegValue(hKey2, NULL, L"ThreadingModel", L"Both") &&
+ WriteRegKey(hKey, L"ProgID", pszProgId) &&
+ WriteRegKey(hKey, L"VersionIndependentProgID", pszVersionIndProgId)
+ && WriteRegValue(hKey, NULL, L"LocalizedString", localizedString)
+ && WriteRegValue(hKey, NULL, L"AppId", L"{3B29AB5C-52CB-4a36-9314-E3FEE0BA7468}")
+ && WriteRegKey(hKey, L"Elevation", 0)
+ //&& WriteRegValue(hKey, L"Elevation", L"IconReference",
+ && WriteRegValue(hKey, L"Elevation", L"Enabled", 1)
+ );
+ RegCloseKey(hKey);
+ if (hKey2) RegCloseKey(hKey2);
+ if (!br) return S_FALSE;
+
+ if (!WriteRegKey(HKEY_CLASSES_ROOT, pszVersionIndProgId, pszFriendlyName, &hKey)) return S_FALSE;
+ br = (WriteRegKey(hKey, L"CLSID", szCLSID) &&
+ WriteRegKey(hKey, L"CurVer", pszProgId));
+ RegCloseKey(hKey);
+ if (!br) return S_FALSE;
+
+ if (!WriteRegKey(HKEY_CLASSES_ROOT, pszProgId, pszFriendlyName, &hKey)) return S_FALSE;
+ br = WriteRegKey(hKey, L"CLSID", szCLSID);
+
+ RegCloseKey(hKey);
+
+ if (!br) return S_FALSE;
+
+ return S_OK;
+}
+
+static HRESULT UnregisterComponent(const CLSID &clsid, LPCWSTR pszVersionIndProgId, LPCWSTR pszProgId)
+{
+ LONG result;
+ WCHAR szBuffer[MAX_PATH] = {0}, szCLSID[64] = {0};
+ if (!StringFromGUID2(clsid, szCLSID, sizeof(szCLSID)/sizeof(WCHAR))) return E_OUTOFMEMORY;
+ StringCchPrintfW(szBuffer, sizeof(szBuffer)/sizeof(WCHAR), L"CLSID\\%s", szCLSID);
+
+ result = DeleteRegKey(HKEY_CLASSES_ROOT, szBuffer);
+ if (ERROR_SUCCESS != result && ERROR_FILE_NOT_FOUND != result) return S_FALSE;
+
+ result = DeleteRegKey(HKEY_CLASSES_ROOT, pszVersionIndProgId);
+ if (ERROR_SUCCESS != result && ERROR_FILE_NOT_FOUND != result) return S_FALSE;
+
+ result = DeleteRegKey(HKEY_CLASSES_ROOT, pszProgId);
+ if (ERROR_SUCCESS != result && ERROR_FILE_NOT_FOUND != result) return S_FALSE;
+
+ return S_OK;
+} \ No newline at end of file