diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Elevator/Elevator.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Elevator/Elevator.cpp')
-rw-r--r-- | Src/Elevator/Elevator.cpp | 308 |
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, ®ID); + 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 |