other-licenses/nsis/Contrib/ApplicationID/Set.cpp

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     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  */
     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  */
    16 #define INITGUID
    18 #include <windows.h>
    19 #include <shlobj.h>
    20 #include <propvarutil.h>
    21 #include <propkey.h>
    22 #include <stdio.h>
    24 #pragma comment (lib, "shlwapi.lib")
    26 #define MAX_STRLEN 1024
    28 typedef struct _stack_t {
    29   struct _stack_t *next;
    30   TCHAR text[MAX_PATH];
    31 } stack_t;
    33 stack_t **g_stacktop;
    34 unsigned int g_stringsize;
    35 TCHAR *g_variables;
    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);
    40 int popstring(TCHAR *str, int len);
    41 void pushstring(const TCHAR *str, int len);
    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;
    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;
    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));
    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
    81     CoInitialize(NULL);
    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();
   101     CoUninitialize();
   103     pushstring(success == true ? TEXT("0") : TEXT("-1"), MAX_PATH);
   104   }
   105 }
   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;
   113   ICustomDestinationList *m_cdl = NULL;
   114   WCHAR wszAppID[MAX_PATH];
   115   TCHAR szAppID[MAX_PATH];
   116   bool success = false;
   118   ZeroMemory(wszAppID, sizeof(wszAppID));
   119   ZeroMemory(szAppID, sizeof(szAppID));
   121   popstring(szAppID, MAX_PATH);
   123 #if !defined(UNICODE)
   124   MultiByteToWideChar(CP_ACP, 0, szAppID, -1, wszAppID, MAX_PATH);
   125 #else
   126   wcscpy_s(wszAppID, szAppID);
   127 #endif
   129   CoInitialize(NULL);
   131   CoCreateInstance(CLSID_DestinationList, NULL, CLSCTX_INPROC_SERVER,
   132                    IID_ICustomDestinationList, (void**)&m_cdl);
   134   if (m_cdl) {
   135     if (SUCCEEDED(m_cdl->DeleteList(wszAppID))) {
   136       success = true;
   137     }
   138   }
   140   if (m_cdl)
   141     m_cdl->Release();
   143   CoUninitialize();
   145   pushstring(success == true ? TEXT("0") : TEXT("-1"), MAX_PATH);
   146 }
   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;
   154   IShellItem *pItem = NULL;
   155   IStartMenuPinnedList *pPinnedList = NULL;
   156   WCHAR wszPath[MAX_PATH];
   157   TCHAR szPath[MAX_PATH];
   158   bool success = false;
   160   ZeroMemory(wszPath, sizeof(wszPath));
   161   ZeroMemory(szPath, sizeof(szPath));
   163   popstring(szPath, MAX_PATH);
   165 #if !defined(UNICODE)
   166   MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH);
   167 #else
   168   wcscpy_s(wszPath, szPath);
   169 #endif
   171   CoInitialize(NULL);
   173   HRESULT hr;
   174   hr = SHCreateItemFromParsingName(wszPath, NULL, IID_PPV_ARGS(&pItem));
   176   if (SUCCEEDED(hr)) {
   178       hr = CoCreateInstance(CLSID_StartMenuPin, 
   179                             NULL, 
   180                             CLSCTX_INPROC_SERVER, 
   181                             IID_PPV_ARGS(&pPinnedList));
   183       if (SUCCEEDED(hr)) {
   184           hr = pPinnedList->RemoveFromList(pItem);
   185           pPinnedList->Release();
   186           success = true;
   187       }
   189       pItem->Release();
   190   }
   192   CoUninitialize();
   194   pushstring(success == true ? TEXT("0") : TEXT("-1"), MAX_PATH);
   195 }
   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 }
   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;
   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 }

mercurial