diff options
Diffstat (limited to 'other-licenses/nsis/Contrib/ApplicationID/Set.cpp')
-rw-r--r-- | other-licenses/nsis/Contrib/ApplicationID/Set.cpp | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/other-licenses/nsis/Contrib/ApplicationID/Set.cpp b/other-licenses/nsis/Contrib/ApplicationID/Set.cpp new file mode 100644 index 000000000..82cb77e16 --- /dev/null +++ b/other-licenses/nsis/Contrib/ApplicationID/Set.cpp @@ -0,0 +1,219 @@ +/* + * Module : Set.cpp + * Purpose: NSIS Plug-in for setting shortcut ApplicationID property + * Created: 27/12/2009 + * Original code Copyright (c) 2009 Mike Anchor. + */ + +/* + * Additional Mozilla contributions: + * Unicode support + * Jump list deletion on uninstall + * Pinned item removal on uninstall + * contrib: <jmathies@mozilla.com> + */ + +#define INITGUID + +#include <windows.h> +#include <shlobj.h> +#include <propvarutil.h> +#include <propkey.h> +#include <stdio.h> + +#pragma comment (lib, "shlwapi.lib") + +#define MAX_STRLEN 1024 + +typedef struct _stack_t { + struct _stack_t *next; + TCHAR text[MAX_PATH]; +} stack_t; + +stack_t **g_stacktop; +unsigned int g_stringsize; +TCHAR *g_variables; + +// Indicates that an application supports dual desktop and immersive modes. In Windows 8, this property is only applicable for web browsers. +DEFINE_PROPERTYKEY(PKEY_AppUserModel_IsDualMode, 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3, 11); + +int popstring(TCHAR *str, int len); +void pushstring(const TCHAR *str, int len); + +extern "C" void __declspec(dllexport) Set(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop) +{ + g_stringsize = string_size; + g_stacktop = stacktop; + g_variables = variables; + + { + IPropertyStore *m_pps = NULL; + WCHAR wszPath[MAX_PATH]; + WCHAR wszAppID[MAX_PATH]; + TCHAR szPath[MAX_PATH]; + TCHAR szAppID[MAX_PATH]; + TCHAR szDualMode[MAX_PATH]; + bool success = false; + + ZeroMemory(wszPath, sizeof(wszPath)); + ZeroMemory(wszAppID, sizeof(wszAppID)); + ZeroMemory(szPath, sizeof(szPath)); + ZeroMemory(szAppID, sizeof(szAppID)); + ZeroMemory(szDualMode, sizeof(szDualMode)); + + popstring(szPath, MAX_PATH); + popstring(szAppID, MAX_PATH); + bool dualMode = (popstring(szDualMode, MAX_PATH) == 0); // optional +#if !defined(UNICODE) + MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH); + MultiByteToWideChar(CP_ACP, 0, szAppID, -1, wszAppID, MAX_PATH); + if (dualMode && stricmp(szDualMode, "true") != 0) { + dualMode = false; + } +#else + wcscpy_s(wszPath, szPath); + wcscpy_s(wszAppID, szAppID); + if (dualMode && _wcsicmp(szDualMode, L"true") != 0) { + dualMode = false; + } +#endif + + CoInitialize(NULL); + + if (SUCCEEDED(SHGetPropertyStoreFromParsingName(wszPath, NULL, GPS_READWRITE, IID_PPV_ARGS(&m_pps)))) + { + PROPVARIANT propvar; + if (SUCCEEDED(InitPropVariantFromString(wszAppID, &propvar))) { + if (SUCCEEDED(m_pps->SetValue(PKEY_AppUserModel_ID, propvar))) { + if (dualMode) { + InitPropVariantFromBoolean(true, &propvar); + m_pps->SetValue(PKEY_AppUserModel_IsDualMode, propvar); + } + if (SUCCEEDED(m_pps->Commit())) { + success = true; + } + } + } + } + if (m_pps != NULL) + m_pps->Release(); + + CoUninitialize(); + + pushstring(success == true ? TEXT("0") : TEXT("-1"), MAX_PATH); + } +} + +extern "C" void __declspec(dllexport) UninstallJumpLists(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop) +{ + g_stringsize = string_size; + g_stacktop = stacktop; + g_variables = variables; + + ICustomDestinationList *m_cdl = NULL; + WCHAR wszAppID[MAX_PATH]; + TCHAR szAppID[MAX_PATH]; + bool success = false; + + ZeroMemory(wszAppID, sizeof(wszAppID)); + ZeroMemory(szAppID, sizeof(szAppID)); + + popstring(szAppID, MAX_PATH); + +#if !defined(UNICODE) + MultiByteToWideChar(CP_ACP, 0, szAppID, -1, wszAppID, MAX_PATH); +#else + wcscpy_s(wszAppID, szAppID); +#endif + + CoInitialize(NULL); + + CoCreateInstance(CLSID_DestinationList, NULL, CLSCTX_INPROC_SERVER, + IID_ICustomDestinationList, (void**)&m_cdl); + + if (m_cdl) { + if (SUCCEEDED(m_cdl->DeleteList(wszAppID))) { + success = true; + } + } + + if (m_cdl) + m_cdl->Release(); + + CoUninitialize(); + + pushstring(success == true ? TEXT("0") : TEXT("-1"), MAX_PATH); +} + +extern "C" void __declspec(dllexport) UninstallPinnedItem(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop) +{ + g_stringsize = string_size; + g_stacktop = stacktop; + g_variables = variables; + + IShellItem *pItem = NULL; + IStartMenuPinnedList *pPinnedList = NULL; + WCHAR wszPath[MAX_PATH]; + TCHAR szPath[MAX_PATH]; + bool success = false; + + ZeroMemory(wszPath, sizeof(wszPath)); + ZeroMemory(szPath, sizeof(szPath)); + + popstring(szPath, MAX_PATH); + +#if !defined(UNICODE) + MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH); +#else + wcscpy_s(wszPath, szPath); +#endif + + CoInitialize(NULL); + + HRESULT hr; + hr = SHCreateItemFromParsingName(wszPath, NULL, IID_PPV_ARGS(&pItem)); + + if (SUCCEEDED(hr)) { + + hr = CoCreateInstance(CLSID_StartMenuPin, + NULL, + CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&pPinnedList)); + + if (SUCCEEDED(hr)) { + hr = pPinnedList->RemoveFromList(pItem); + pPinnedList->Release(); + success = true; + } + + pItem->Release(); + } + + CoUninitialize(); + + pushstring(success == true ? TEXT("0") : TEXT("-1"), MAX_PATH); +} + +//Function: Removes the element from the top of the NSIS stack and puts it in the buffer +int popstring(TCHAR *str, int len) +{ + stack_t *th; + if (!g_stacktop || !*g_stacktop) return 1; + th=(*g_stacktop); + lstrcpyn(str,th->text, len); + *g_stacktop=th->next; + GlobalFree((HGLOBAL)th); + return 0; +} + +//Function: Adds an element to the top of the NSIS stack +void pushstring(const TCHAR *str, int len) +{ + stack_t *th; + + if (!g_stacktop) return; + th=(stack_t*)GlobalAlloc(GPTR, sizeof(stack_t) + len); + lstrcpyn(th->text, str, len); + th->next=*g_stacktop; + *g_stacktop=th; +} |