Set.cpp (5718B)
1 /* 2 * Module : Set.cpp 3 * Purpose: NSIS Plug-in for setting shortcut ApplicationID property 4 * Created: 27/12/2009 5 * Original code Copyright (c) 2009 Mike Anchor. 6 */ 7 8 /* 9 * Additional Mozilla contributions: 10 * Unicode support 11 * Jump list deletion on uninstall 12 * Pinned item removal on uninstall 13 * contrib: <jmathies@mozilla.com> 14 */ 15 16 #define INITGUID 17 18 #include <windows.h> 19 #include <shlobj.h> 20 #include <propvarutil.h> 21 #include <propkey.h> 22 #include <stdio.h> 23 24 #pragma comment (lib, "shlwapi.lib") 25 26 #define MAX_STRLEN 1024 27 28 typedef struct _stack_t { 29 struct _stack_t *next; 30 TCHAR text[MAX_PATH]; 31 } stack_t; 32 33 stack_t **g_stacktop; 34 unsigned int g_stringsize; 35 TCHAR *g_variables; 36 37 // Indicates that an application supports dual desktop and immersive modes. In Windows 8, this property is only applicable for web browsers. 38 DEFINE_PROPERTYKEY(PKEY_AppUserModel_IsDualMode, 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3, 11); 39 40 int popstring(TCHAR *str, int len); 41 void pushstring(const TCHAR *str, int len); 42 43 extern "C" void __declspec(dllexport) Set(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop) 44 { 45 g_stringsize = string_size; 46 g_stacktop = stacktop; 47 g_variables = variables; 48 49 { 50 IPropertyStore *m_pps = NULL; 51 WCHAR wszPath[MAX_PATH]; 52 WCHAR wszAppID[MAX_PATH]; 53 TCHAR szPath[MAX_PATH]; 54 TCHAR szAppID[MAX_PATH]; 55 TCHAR szDualMode[MAX_PATH]; 56 bool success = false; 57 58 ZeroMemory(wszPath, sizeof(wszPath)); 59 ZeroMemory(wszAppID, sizeof(wszAppID)); 60 ZeroMemory(szPath, sizeof(szPath)); 61 ZeroMemory(szAppID, sizeof(szAppID)); 62 ZeroMemory(szDualMode, sizeof(szDualMode)); 63 64 popstring(szPath, MAX_PATH); 65 popstring(szAppID, MAX_PATH); 66 bool dualMode = (popstring(szDualMode, MAX_PATH) == 0); // optional 67 #if !defined(UNICODE) 68 MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH); 69 MultiByteToWideChar(CP_ACP, 0, szAppID, -1, wszAppID, MAX_PATH); 70 if (dualMode && stricmp(szDualMode, "true") != 0) { 71 dualMode = false; 72 } 73 #else 74 wcscpy_s(wszPath, szPath); 75 wcscpy_s(wszAppID, szAppID); 76 if (dualMode && _wcsicmp(szDualMode, L"true") != 0) { 77 dualMode = false; 78 } 79 #endif 80 81 CoInitialize(NULL); 82 83 if (SUCCEEDED(SHGetPropertyStoreFromParsingName(wszPath, NULL, GPS_READWRITE, IID_PPV_ARGS(&m_pps)))) 84 { 85 PROPVARIANT propvar; 86 if (SUCCEEDED(InitPropVariantFromString(wszAppID, &propvar))) { 87 if (SUCCEEDED(m_pps->SetValue(PKEY_AppUserModel_ID, propvar))) { 88 if (dualMode) { 89 InitPropVariantFromBoolean(true, &propvar); 90 m_pps->SetValue(PKEY_AppUserModel_IsDualMode, propvar); 91 } 92 if (SUCCEEDED(m_pps->Commit())) { 93 success = true; 94 } 95 } 96 } 97 } 98 if (m_pps != NULL) 99 m_pps->Release(); 100 101 CoUninitialize(); 102 103 pushstring(success == true ? TEXT("0") : TEXT("-1"), MAX_PATH); 104 } 105 } 106 107 extern "C" void __declspec(dllexport) UninstallJumpLists(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop) 108 { 109 g_stringsize = string_size; 110 g_stacktop = stacktop; 111 g_variables = variables; 112 113 ICustomDestinationList *m_cdl = NULL; 114 WCHAR wszAppID[MAX_PATH]; 115 TCHAR szAppID[MAX_PATH]; 116 bool success = false; 117 118 ZeroMemory(wszAppID, sizeof(wszAppID)); 119 ZeroMemory(szAppID, sizeof(szAppID)); 120 121 popstring(szAppID, MAX_PATH); 122 123 #if !defined(UNICODE) 124 MultiByteToWideChar(CP_ACP, 0, szAppID, -1, wszAppID, MAX_PATH); 125 #else 126 wcscpy_s(wszAppID, szAppID); 127 #endif 128 129 CoInitialize(NULL); 130 131 CoCreateInstance(CLSID_DestinationList, NULL, CLSCTX_INPROC_SERVER, 132 IID_ICustomDestinationList, (void**)&m_cdl); 133 134 if (m_cdl) { 135 if (SUCCEEDED(m_cdl->DeleteList(wszAppID))) { 136 success = true; 137 } 138 } 139 140 if (m_cdl) 141 m_cdl->Release(); 142 143 CoUninitialize(); 144 145 pushstring(success == true ? TEXT("0") : TEXT("-1"), MAX_PATH); 146 } 147 148 extern "C" void __declspec(dllexport) UninstallPinnedItem(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop) 149 { 150 g_stringsize = string_size; 151 g_stacktop = stacktop; 152 g_variables = variables; 153 154 IShellItem *pItem = NULL; 155 IStartMenuPinnedList *pPinnedList = NULL; 156 WCHAR wszPath[MAX_PATH]; 157 TCHAR szPath[MAX_PATH]; 158 bool success = false; 159 160 ZeroMemory(wszPath, sizeof(wszPath)); 161 ZeroMemory(szPath, sizeof(szPath)); 162 163 popstring(szPath, MAX_PATH); 164 165 #if !defined(UNICODE) 166 MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH); 167 #else 168 wcscpy_s(wszPath, szPath); 169 #endif 170 171 CoInitialize(NULL); 172 173 HRESULT hr; 174 hr = SHCreateItemFromParsingName(wszPath, NULL, IID_PPV_ARGS(&pItem)); 175 176 if (SUCCEEDED(hr)) { 177 178 hr = CoCreateInstance(CLSID_StartMenuPin, 179 NULL, 180 CLSCTX_INPROC_SERVER, 181 IID_PPV_ARGS(&pPinnedList)); 182 183 if (SUCCEEDED(hr)) { 184 hr = pPinnedList->RemoveFromList(pItem); 185 pPinnedList->Release(); 186 success = true; 187 } 188 189 pItem->Release(); 190 } 191 192 CoUninitialize(); 193 194 pushstring(success == true ? TEXT("0") : TEXT("-1"), MAX_PATH); 195 } 196 197 //Function: Removes the element from the top of the NSIS stack and puts it in the buffer 198 int popstring(TCHAR *str, int len) 199 { 200 stack_t *th; 201 if (!g_stacktop || !*g_stacktop) return 1; 202 th=(*g_stacktop); 203 lstrcpyn(str,th->text, len); 204 *g_stacktop=th->next; 205 GlobalFree((HGLOBAL)th); 206 return 0; 207 } 208 209 //Function: Adds an element to the top of the NSIS stack 210 void pushstring(const TCHAR *str, int len) 211 { 212 stack_t *th; 213 214 if (!g_stacktop) return; 215 th=(stack_t*)GlobalAlloc(GPTR, sizeof(stack_t) + len); 216 lstrcpyn(th->text, str, len); 217 th->next=*g_stacktop; 218 *g_stacktop=th; 219 }