]> git.sesse.net Git - vlc/commitdiff
nsis: compile the nsProcess plugin
authorLudovic Fauvet <etix@videolan.org>
Thu, 28 Nov 2013 12:45:02 +0000 (13:45 +0100)
committerLudovic Fauvet <etix@videolan.org>
Fri, 29 Nov 2013 12:26:16 +0000 (13:26 +0100)
The plugin is a NSIS helper used to find and kill a running process. It
is licensed under the same terms as NSIS (zlib/libpng).

extras/package/win32/NSIS/nsProcess.nsh [new file with mode: 0644]
extras/package/win32/NSIS/nsProcess/api.h [new file with mode: 0644]
extras/package/win32/NSIS/nsProcess/nsProcess.c [new file with mode: 0644]
extras/package/win32/NSIS/nsProcess/nsis_tchar.h [new file with mode: 0644]
extras/package/win32/NSIS/nsProcess/pluginapi.c [new file with mode: 0644]
extras/package/win32/NSIS/nsProcess/pluginapi.h [new file with mode: 0644]
extras/package/win32/package.mak

diff --git a/extras/package/win32/NSIS/nsProcess.nsh b/extras/package/win32/NSIS/nsProcess.nsh
new file mode 100644 (file)
index 0000000..9ef6098
--- /dev/null
@@ -0,0 +1,28 @@
+!define nsProcess::FindProcess `!insertmacro nsProcess::FindProcess`
+
+!macro nsProcess::FindProcess _FILE _ERR
+       nsProcess::_FindProcess /NOUNLOAD `${_FILE}`
+       Pop ${_ERR}
+!macroend
+
+
+!define nsProcess::KillProcess `!insertmacro nsProcess::KillProcess`
+
+!macro nsProcess::KillProcess _FILE _ERR
+       nsProcess::_KillProcess /NOUNLOAD `${_FILE}`
+       Pop ${_ERR}
+!macroend
+
+!define nsProcess::CloseProcess `!insertmacro nsProcess::CloseProcess`
+
+!macro nsProcess::CloseProcess _FILE _ERR
+       nsProcess::_CloseProcess /NOUNLOAD `${_FILE}`
+       Pop ${_ERR}
+!macroend
+
+
+!define nsProcess::Unload `!insertmacro nsProcess::Unload`
+
+!macro nsProcess::Unload
+       nsProcess::_Unload
+!macroend
diff --git a/extras/package/win32/NSIS/nsProcess/api.h b/extras/package/win32/NSIS/nsProcess/api.h
new file mode 100644 (file)
index 0000000..ed014b2
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * apih
+ * 
+ * This file is a part of NSIS.
+ * 
+ * Copyright (C) 1999-2008 Nullsoft and Contributors
+ * 
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ * 
+ * Licence details can be found in the file COPYING.
+ * 
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef _NSIS_EXEHEAD_API_H_
+#define _NSIS_EXEHEAD_API_H_
+
+// Starting with NSIS 2.42, you can check the version of the plugin API in exec_flags->plugin_api_version
+// The format is 0xXXXXYYYY where X is the major version and Y is the minor version (MAKELONG(y,x))
+// When doing version checks, always remember to use >=, ex: if (pX->exec_flags->plugin_api_version >= NSISPIAPIVER_1_0) {}
+
+#define NSISPIAPIVER_1_0 0x00010000
+#define NSISPIAPIVER_CURR NSISPIAPIVER_1_0
+
+// NSIS Plug-In Callback Messages
+enum NSPIM 
+{
+       NSPIM_UNLOAD,    // This is the last message a plugin gets, do final cleanup
+       NSPIM_GUIUNLOAD, // Called after .onGUIEnd
+};
+
+// Prototype for callbacks registered with extra_parameters->RegisterPluginCallback()
+// Return NULL for unknown messages
+// Should always be __cdecl for future expansion possibilities
+typedef UINT_PTR (*NSISPLUGINCALLBACK)(enum NSPIM);
+
+// extra_parameters data structures containing other interesting stuff
+// but the stack, variables and HWND passed on to plug-ins.
+typedef struct
+{
+  int autoclose;
+  int all_user_var;
+  int exec_error;
+  int abort;
+  int exec_reboot; // NSIS_SUPPORT_REBOOT
+  int reboot_called; // NSIS_SUPPORT_REBOOT
+  int XXX_cur_insttype; // depreacted
+  int plugin_api_version; // see NSISPIAPIVER_CURR
+                          // used to be XXX_insttype_changed
+  int silent; // NSIS_CONFIG_SILENT_SUPPORT
+  int instdir_error;
+  int rtl;
+  int errlvl;
+  int alter_reg_view;
+  int status_update;
+} exec_flags_t;
+
+#ifndef NSISCALL
+#  define NSISCALL __stdcall
+#endif
+
+typedef struct {
+  exec_flags_t *exec_flags;
+  int (NSISCALL *ExecuteCodeSegment)(int, HWND);
+  void (NSISCALL *validate_filename)(TCHAR *);
+  BOOL (NSISCALL *RegisterPluginCallback)(HMODULE, NSISPLUGINCALLBACK);
+} extra_parameters;
+
+// Definitions for page showing plug-ins
+// See Ui.c to understand better how they're used
+
+// sent to the outer window to tell it to go to the next inner window
+#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
+
+// custom pages should send this message to let NSIS know they're ready
+#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd)
+
+// sent as wParam with WM_NOTIFY_OUTER_NEXT when user cancels - heed its warning
+#define NOTIFY_BYE_BYE 'x'
+
+#endif /* _PLUGIN_H_ */
diff --git a/extras/package/win32/NSIS/nsProcess/nsProcess.c b/extras/package/win32/NSIS/nsProcess/nsProcess.c
new file mode 100644 (file)
index 0000000..5b2f22a
--- /dev/null
@@ -0,0 +1,422 @@
+/*********************************************************************
+ *               nsProcess NSIS plugin v1.5                          *
+ *                                                                   *
+ * 2006 Shengalts Aleksander aka Instructor (Shengalts@mail.ru)      *
+ *                                                                   *
+ * Licensed under the zlib/libpng license (the "License");           *
+ * you may not use this file except in compliance with the License.  *
+ *                                                                   *
+ * Licence details can be found in the file COPYING.                 *
+ *                                                                   *
+ * This software is provided 'as-is', without any express or implied *
+ * warranty.                                                         *
+ *                                                                   *
+ * Source function FIND_PROC_BY_NAME based                           *
+ *   upon the Ravi Kochhar (kochhar@physiology.wisc.edu) code        *
+ * Thanks iceman_k (FindProcDLL plugin) and                          *
+ *   DITMan (KillProcDLL plugin) for point me up                     *
+ *********************************************************************/
+
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <tlhelp32.h>
+#include "pluginapi.h"
+
+/* Defines */
+#define NSIS_MAX_STRLEN 1024
+
+#define SystemProcessInformation     5
+#define STATUS_SUCCESS               0x00000000L
+#define STATUS_INFO_LENGTH_MISMATCH  0xC0000004L
+
+typedef struct _SYSTEM_THREAD_INFO {
+  FILETIME ftCreationTime;
+  DWORD dwUnknown1;
+  DWORD dwStartAddress;
+  DWORD dwOwningPID;
+  DWORD dwThreadID;
+  DWORD dwCurrentPriority;
+  DWORD dwBasePriority;
+  DWORD dwContextSwitches;
+  DWORD dwThreadState;
+  DWORD dwUnknown2;
+  DWORD dwUnknown3;
+  DWORD dwUnknown4;
+  DWORD dwUnknown5;
+  DWORD dwUnknown6;
+  DWORD dwUnknown7;
+} SYSTEM_THREAD_INFO;
+
+typedef struct _SYSTEM_PROCESS_INFO {
+  DWORD dwOffset;
+  DWORD dwThreadCount;
+  DWORD dwUnkown1[6];
+  FILETIME ftCreationTime;
+  DWORD dwUnkown2;
+  DWORD dwUnkown3;
+  DWORD dwUnkown4;
+  DWORD dwUnkown5;
+  DWORD dwUnkown6;
+  WCHAR *pszProcessName;
+  DWORD dwBasePriority;
+  DWORD dwProcessID;
+  DWORD dwParentProcessID;
+  DWORD dwHandleCount;
+  DWORD dwUnkown7;
+  DWORD dwUnkown8;
+  DWORD dwVirtualBytesPeak;
+  DWORD dwVirtualBytes;
+  DWORD dwPageFaults;
+  DWORD dwWorkingSetPeak;
+  DWORD dwWorkingSet;
+  DWORD dwUnkown9;
+  DWORD dwPagedPool;
+  DWORD dwUnkown10;
+  DWORD dwNonPagedPool;
+  DWORD dwPageFileBytesPeak;
+  DWORD dwPageFileBytes;
+  DWORD dwPrivateBytes;
+  DWORD dwUnkown11;
+  DWORD dwUnkown12;
+  DWORD dwUnkown13;
+  DWORD dwUnkown14;
+  SYSTEM_THREAD_INFO ati[ANYSIZE_ARRAY];
+} SYSTEM_PROCESS_INFO;
+
+
+/* Include conversion functions */
+//#define xatoi
+//#define xitoa
+
+/* Global variables */
+TCHAR szBuf[NSIS_MAX_STRLEN];
+
+/* Funtions prototypes and macros */
+int FIND_PROC_BY_NAME(TCHAR *szProcessName, BOOL bTerminate, BOOL bClose);
+
+/* NSIS functions code */
+void __declspec(dllexport) _FindProcess(HWND hwndParent, int string_size,
+                                      TCHAR *variables, stack_t **stacktop, extra_parameters *extra)
+{
+  EXDLL_INIT();
+  {
+    int nError;
+
+    popstringn(szBuf, NSIS_MAX_STRLEN);
+    nError=FIND_PROC_BY_NAME(szBuf, FALSE, FALSE);
+    pushint(nError);
+  }
+}
+
+void __declspec(dllexport) _KillProcess(HWND hwndParent, int string_size,
+                                      TCHAR *variables, stack_t **stacktop, extra_parameters *extra)
+{
+  EXDLL_INIT();
+  {
+    int nError=0;
+
+    popstringn(szBuf, NSIS_MAX_STRLEN);
+    nError=FIND_PROC_BY_NAME(szBuf, TRUE, FALSE);
+    pushint(nError);
+  }
+}
+
+void __declspec(dllexport) _CloseProcess(HWND hwndParent, int string_size,
+                                      TCHAR *variables, stack_t **stacktop, extra_parameters *extra)
+{
+  EXDLL_INIT();
+  {
+    int nError=0;
+
+    popstringn(szBuf, NSIS_MAX_STRLEN);
+    nError=FIND_PROC_BY_NAME(szBuf, TRUE, TRUE);
+    pushint(nError);
+  }
+}
+
+void __declspec(dllexport) _Unload(HWND hwndParent, int string_size,
+                                      TCHAR *variables, stack_t **stacktop, extra_parameters *extra)
+{
+}
+
+BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
+{
+  return TRUE;
+}
+
+BOOL CALLBACK EnumWindowsProc(          HWND hwnd,
+    LPARAM lParam
+)
+{
+       HANDLE *data = lParam;
+       DWORD pid;
+       GetWindowThreadProcessId(hwnd, &pid);
+       if (pid == data[0])
+       {
+               PostMessage(data[1], WM_CLOSE, 0, 0);
+               data[1] = hwnd;
+       }
+       return TRUE;
+}
+
+void NiceTerminate(DWORD id, BOOL bClose, BOOL *bSuccess, BOOL *bFailed)
+{
+  HANDLE hProc;
+  HANDLE data[2];
+  DWORD ec;
+  BOOL bDone = FALSE;
+  if (hProc=OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, id))
+  {
+       data[0] = id;
+       data[1] = NULL;
+
+       if (bClose)
+               EnumWindows(EnumWindowsProc, data);
+       if (data[1] != NULL)
+       {         
+         if (GetExitCodeProcess(hProc,&ec) && ec == STILL_ACTIVE)
+               if (WaitForSingleObject(hProc, 3000) == WAIT_OBJECT_0)
+               {
+                 *bSuccess = bDone = TRUE;
+               }
+               else;
+         else 
+         {
+                 *bSuccess = bDone = TRUE;
+         }
+       }
+       if (!bDone)
+       {
+            // Open for termination
+              if (TerminateProcess(hProc, 0))
+                *bSuccess=TRUE;
+              else
+                *bFailed=TRUE;
+       }
+    CloseHandle(hProc);
+  }
+}
+
+int FIND_PROC_BY_NAME(TCHAR *szProcessName, BOOL bTerminate, BOOL bClose)
+// Find the process "szProcessName" if it is currently running.
+// This works for Win95/98/ME and also WinNT/2000/XP.
+// The process name is case-insensitive, i.e. "notepad.exe" and "NOTEPAD.EXE"
+// will both work. If bTerminate is TRUE, then process will be terminated.
+//
+// Return codes are as follows:
+//   0   = Success
+//   601 = No permission to terminate process
+//   602 = Not all processes terminated successfully
+//   603 = Process was not currently running
+//   604 = Unable to identify system type
+//   605 = Unsupported OS
+//   606 = Unable to load NTDLL.DLL
+//   607 = Unable to get procedure address from NTDLL.DLL
+//   608 = NtQuerySystemInformation failed
+//   609 = Unable to load KERNEL32.DLL
+//   610 = Unable to get procedure address from KERNEL32.DLL
+//   611 = CreateToolhelp32Snapshot failed
+//
+// Change history:
+//   created  06/23/2000  - Ravi Kochhar (kochhar@physiology.wisc.edu)
+//                            http://www.neurophys.wisc.edu/ravi/software/
+//   modified 03/08/2002  - Ravi Kochhar (kochhar@physiology.wisc.edu)
+//                          - Borland-C compatible if BORLANDC is defined as
+//                            suggested by Bob Christensen
+//   modified 03/10/2002  - Ravi Kochhar (kochhar@physiology.wisc.edu)
+//                          - Removed memory leaks as suggested by
+//                            Jonathan Richard-Brochu (handles to Proc and Snapshot
+//                            were not getting closed properly in some cases)
+//   modified 14/11/2005  - Shengalts Aleksander aka Instructor (Shengalts@mail.ru):
+//                          - Combine functions FIND_PROC_BY_NAME and KILL_PROC_BY_NAME
+//                          - Code has been optimized
+//                          - Now kill all processes with specified name (not only one)
+//                          - Cosmetic improvements
+//                          - Removed error 632 (Invalid process name)
+//                          - Changed error 602 (Unable to terminate process for some other reason)
+//                          - BORLANDC define not needed
+//   modified 04/01/2006  - Shengalts Aleksander aka Instructor (Shengalts@mail.ru):
+//                          - Removed CRT dependency
+//   modified 21/04/2006  - Shengalts Aleksander aka Instructor (Shengalts@mail.ru):
+//                          - Removed memory leak as suggested by {_trueparuex^}
+//                            (handle to hSnapShot was not getting closed properly in some cases)
+//   modified 21/04/2006  - Shengalts Aleksander aka Instructor (Shengalts@mail.ru):
+//                          - Removed memory leak as suggested by {_trueparuex^}
+//                            (handle to hSnapShot was not getting closed properly in some cases)
+//   modified 19/07/2006  - Shengalts Aleksander aka Instructor (Shengalts@mail.ru):
+//                          - Code for WinNT/2000/XP has been rewritten
+//                          - Changed error codes
+//   modified 31/08/2006  - Shengalts Aleksander aka Instructor (Shengalts@mail.ru):
+//                          - Removed memory leak as suggested by Daniel Vanesse
+{
+  TCHAR szName[MAX_PATH];
+  OSVERSIONINFO osvi;
+  HMODULE hLib;
+  HANDLE hProc;
+  ULONG uError;
+  BOOL bFound=FALSE;
+  BOOL bSuccess=FALSE;
+  BOOL bFailed=FALSE;
+
+  // First check what version of Windows we're in
+  osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
+  if (!GetVersionEx(&osvi)) return 604;
+
+  if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT &&
+      osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)
+    return 605;
+
+  if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
+  {
+    // WinNT/2000/XP
+
+    SYSTEM_PROCESS_INFO *spi;
+    SYSTEM_PROCESS_INFO *spiCount;
+    DWORD dwSize=0x4000;
+    DWORD dwData;
+    ULONG (WINAPI *NtQuerySystemInformationPtr)(ULONG, PVOID, LONG, PULONG);
+
+    if (hLib=LoadLibraryW(L"NTDLL.DLL"))
+    {
+      NtQuerySystemInformationPtr=(ULONG(WINAPI *)(ULONG, PVOID, LONG, PULONG))GetProcAddress(hLib, "NtQuerySystemInformation");
+
+      if (NtQuerySystemInformationPtr)
+      {
+        while (1)
+        {
+          if (spi=LocalAlloc(LMEM_FIXED, dwSize))
+          {
+            uError=(*NtQuerySystemInformationPtr)(SystemProcessInformation, spi, dwSize, &dwData);
+
+            if (uError == STATUS_SUCCESS) break;
+
+            LocalFree(spi);
+
+            if (uError != STATUS_INFO_LENGTH_MISMATCH)
+            {
+              uError=608;
+              break;
+            }
+          }
+          else
+          {
+            uError=608;
+            break;
+          }
+          dwSize*=2;
+        }
+      }
+      else uError=607;
+
+      FreeLibrary(hLib);
+    }
+    else uError=606;
+
+    if (uError != STATUS_SUCCESS) return uError;
+
+    spiCount=spi;
+
+    while (1)
+    {
+      if (spiCount->pszProcessName)
+      {
+
+#ifdef UNICODE
+           lstrcpyn(szName, spiCount->pszProcessName, MAX_PATH);
+#else
+           WideCharToMultiByte(CP_ACP, 0, spiCount->pszProcessName, -1, szName, MAX_PATH, NULL, NULL);
+#endif         
+
+        if (!lstrcmpi(szName, szProcessName))
+        {
+          // Process found
+          bFound=TRUE;
+
+          if (bTerminate == TRUE)
+          {
+                         NiceTerminate(spiCount->dwProcessID, bClose, &bSuccess, &bFailed);
+          }
+          else break;
+        }
+      }
+      if (spiCount->dwOffset == 0) break;
+      spiCount=(SYSTEM_PROCESS_INFO *)((char *)spiCount + spiCount->dwOffset);
+    }
+    LocalFree(spi);
+  }
+  else
+  {
+    // Win95/98/ME
+
+    PROCESSENTRY32 pe;
+    char *pName;
+    HANDLE hSnapShot;
+    BOOL bResult;
+    HANDLE (WINAPI *CreateToolhelp32SnapshotPtr)(DWORD, DWORD);
+    BOOL (WINAPI *Process32FirstPtr)(HANDLE, LPPROCESSENTRY32);
+    BOOL (WINAPI *Process32NextPtr)(HANDLE, LPPROCESSENTRY32);
+
+    if (hLib=LoadLibraryA("KERNEL32.DLL"))
+    {
+      CreateToolhelp32SnapshotPtr=(HANDLE(WINAPI *)(DWORD, DWORD)) GetProcAddress(hLib, "CreateToolhelp32Snapshot");
+      Process32FirstPtr=(BOOL(WINAPI *)(HANDLE, LPPROCESSENTRY32)) GetProcAddress(hLib, "Process32First");
+      Process32NextPtr=(BOOL(WINAPI *)(HANDLE, LPPROCESSENTRY32)) GetProcAddress(hLib, "Process32Next");
+
+      if (CreateToolhelp32SnapshotPtr && Process32NextPtr && Process32FirstPtr)
+      {
+        // Get a handle to a Toolhelp snapshot of all the systems processes.
+        if ((hSnapShot=(*CreateToolhelp32SnapshotPtr)(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
+        {
+          // Get the first process' information.
+          pe.dwSize=sizeof(PROCESSENTRY32);
+          bResult=(*Process32FirstPtr)(hSnapShot, &pe);
+
+          // While there are processes, keep looping and checking.
+          while (bResult)
+          {
+            //Get file name
+            for (pName=pe.szExeFile + lstrlen(pe.szExeFile) - 1; *pName != '\\' && *pName != '\0'; --pName);
+
+                       ++pName;
+
+#ifdef UNICODE
+                       MultiByteToWideChar(CP_ACP, 0, pName, lstrlenA(pName)+1, szName, MAX_PATH);
+#else
+                       lstrcpyn(szName, pName, MAX_PATH);
+#endif         
+
+            if (!lstrcmpi(szName, szProcessName))
+            {
+              // Process found
+              bFound=TRUE;
+
+              if (bTerminate == TRUE)
+              {
+                // Open for termination
+                                 NiceTerminate(pe.th32ProcessID, bClose, &bSuccess, &bFailed);
+              }
+              else break;
+            }
+            //Keep looking
+            bResult=(*Process32NextPtr)(hSnapShot, &pe);
+          }
+          CloseHandle(hSnapShot);
+        }
+        else uError=611;
+      }
+      else uError=610;
+
+      FreeLibrary(hLib);
+    }
+    else uError=609;
+  }
+
+  if (bFound == FALSE) return 603;
+  if (bTerminate == TRUE)
+  {
+    if (bSuccess == FALSE) return 601;
+    if (bFailed == TRUE) return 602;
+  }
+  return 0;
+}
diff --git a/extras/package/win32/NSIS/nsProcess/nsis_tchar.h b/extras/package/win32/NSIS/nsProcess/nsis_tchar.h
new file mode 100644 (file)
index 0000000..92025cc
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * nsis_tchar.h
+ * 
+ * This file is a part of NSIS.
+ * 
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ * 
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ *
+ * For Unicode support by Jim Park -- 08/30/2007
+ */
+
+// Jim Park: Only those we use are listed here.
+
+#pragma once
+
+#ifdef _UNICODE
+
+#ifndef _T
+#define __T(x)   L ## x
+#define _T(x)    __T(x)
+#define _TEXT(x) __T(x)
+#endif
+typedef wchar_t TCHAR;
+typedef wchar_t _TUCHAR;
+
+// program
+#define _tmain      wmain
+#define _tWinMain   wWinMain
+#define _tenviron   _wenviron
+#define __targv     __wargv
+
+// printfs
+#define _ftprintf   fwprintf
+#define _sntprintf  _snwprintf
+#define _stprintf   _swprintf
+#define _tprintf    wprintf
+#define _vftprintf  vfwprintf
+#define _vsntprintf _vsnwprintf
+#define _vstprintf  _vswprintf
+
+// scanfs
+#define _tscanf     wscanf
+#define _stscanf    swscanf
+
+// string manipulations
+#define _tcscat     wcscat
+#define _tcschr     wcschr
+#define _tcsclen    wcslen
+#define _tcscpy     wcscpy
+#define _tcsdup     _wcsdup
+#define _tcslen     wcslen
+#define _tcsnccpy   wcsncpy
+#define _tcsncpy    wcsncpy
+#define _tcsrchr    wcsrchr
+#define _tcsstr     wcsstr
+#define _tcstok     wcstok
+
+// string comparisons
+#define _tcscmp     wcscmp
+#define _tcsicmp    _wcsicmp
+#define _tcsncicmp  _wcsnicmp
+#define _tcsncmp    wcsncmp
+#define _tcsnicmp   _wcsnicmp
+
+// upper / lower
+#define _tcslwr     _wcslwr
+#define _tcsupr     _wcsupr
+#define _totlower   towlower
+#define _totupper   towupper
+
+// conversions to numbers
+#define _tcstoi64   _wcstoi64
+#define _tcstol     wcstol
+#define _tcstoul    wcstoul
+#define _tstof      _wtof
+#define _tstoi      _wtoi
+#define _tstoi64    _wtoi64
+#define _ttoi       _wtoi
+#define _ttoi64     _wtoi64
+#define _ttol       _wtol
+
+// conversion from numbers to strings
+#define _itot       _itow
+#define _ltot       _ltow
+#define _i64tot     _i64tow
+#define _ui64tot    _ui64tow
+
+// file manipulations
+#define _tfopen     _wfopen
+#define _topen      _wopen
+#define _tremove    _wremove
+#define _tunlink    _wunlink
+
+// reading and writing to i/o
+#define _fgettc     fgetwc
+#define _fgetts     fgetws
+#define _fputts     fputws
+#define _gettchar   getwchar
+
+// directory
+#define _tchdir     _wchdir
+
+// environment
+#define _tgetenv    _wgetenv
+#define _tsystem    _wsystem
+
+// time
+#define _tcsftime   wcsftime
+
+#else // ANSI
+
+#ifndef _T
+#define _T(x)    x
+#define _TEXT(x) x
+#endif
+typedef char            TCHAR;
+typedef unsigned char   _TUCHAR;
+
+// program
+#define _tmain      main
+#define _tWinMain   WinMain
+#define _tenviron   environ
+#define __targv     __argv
+
+// printfs
+#define _ftprintf   fprintf
+#define _sntprintf  _snprintf
+#define _stprintf   sprintf
+#define _tprintf    printf
+#define _vftprintf  vfprintf
+#define _vsntprintf _vsnprintf
+#define _vstprintf  vsprintf
+
+// scanfs
+#define _tscanf     scanf
+#define _stscanf    sscanf
+
+// string manipulations
+#define _tcscat     strcat
+#define _tcschr     strchr
+#define _tcsclen    strlen
+#define _tcscnlen   strnlen
+#define _tcscpy     strcpy
+#define _tcsdup     _strdup
+#define _tcslen     strlen
+#define _tcsnccpy   strncpy
+#define _tcsrchr    strrchr
+#define _tcsstr     strstr
+#define _tcstok     strtok
+
+// string comparisons
+#define _tcscmp     strcmp
+#define _tcsicmp    _stricmp
+#define _tcsncmp    strncmp
+#define _tcsncicmp  _strnicmp
+#define _tcsnicmp   _strnicmp
+
+// upper / lower
+#define _tcslwr     _strlwr
+#define _tcsupr     _strupr
+
+#define _totupper   toupper
+#define _totlower   tolower
+
+// conversions to numbers
+#define _tcstol     strtol
+#define _tcstoul    strtoul
+#define _tstof      atof
+#define _tstoi      atoi
+#define _tstoi64    _atoi64
+#define _tstoi64    _atoi64
+#define _ttoi       atoi
+#define _ttoi64     _atoi64
+#define _ttol       atol
+
+// conversion from numbers to strings
+#define _i64tot     _i64toa
+#define _itot       _itoa
+#define _ltot       _ltoa
+#define _ui64tot    _ui64toa
+
+// file manipulations
+#define _tfopen     fopen
+#define _topen      _open
+#define _tremove    remove
+#define _tunlink    _unlink
+
+// reading and writing to i/o
+#define _fgettc     fgetc
+#define _fgetts     fgets
+#define _fputts     fputs
+#define _gettchar   getchar
+
+// directory
+#define _tchdir     _chdir
+
+// environment
+#define _tgetenv    getenv
+#define _tsystem    system
+
+// time
+#define _tcsftime   strftime
+
+#endif
+
+// is functions (the same in Unicode / ANSI)
+#define _istgraph   isgraph
+#define _istascii   __isascii
+
+#define __TFILE__ _T(__FILE__)
+#define __TDATE__ _T(__DATE__)
+#define __TTIME__ _T(__TIME__)
diff --git a/extras/package/win32/NSIS/nsProcess/pluginapi.c b/extras/package/win32/NSIS/nsProcess/pluginapi.c
new file mode 100644 (file)
index 0000000..a6562fa
--- /dev/null
@@ -0,0 +1,290 @@
+#include <windows.h>
+
+#include "pluginapi.h"
+
+unsigned int g_stringsize;
+stack_t **g_stacktop;
+TCHAR *g_variables;
+
+// utility functions (not required but often useful)
+
+int NSISCALL popstring(TCHAR *str)
+{
+  stack_t *th;
+  if (!g_stacktop || !*g_stacktop) return 1;
+  th=(*g_stacktop);
+  lstrcpy(str,th->text);
+  *g_stacktop = th->next;
+  GlobalFree((HGLOBAL)th);
+  return 0;
+}
+
+int NSISCALL popstringn(TCHAR *str, int maxlen)
+{
+  stack_t *th;
+  if (!g_stacktop || !*g_stacktop) return 1;
+  th=(*g_stacktop);
+  if (str) lstrcpyn(str,th->text,maxlen?maxlen:g_stringsize);
+  *g_stacktop = th->next;
+  GlobalFree((HGLOBAL)th);
+  return 0;
+}
+
+void NSISCALL pushstring(const TCHAR *str)
+{
+  stack_t *th;
+  if (!g_stacktop) return;
+  th=(stack_t*)GlobalAlloc(GPTR,(sizeof(stack_t)+(g_stringsize)*sizeof(TCHAR)));
+  lstrcpyn(th->text,str,g_stringsize);
+  th->next=*g_stacktop;
+  *g_stacktop=th;
+}
+
+TCHAR * NSISCALL getuservariable(const int varnum)
+{
+  if (varnum < 0 || varnum >= __INST_LAST) return NULL;
+  return g_variables+varnum*g_stringsize;
+}
+
+void NSISCALL setuservariable(const int varnum, const TCHAR *var)
+{
+       if (var != NULL && varnum >= 0 && varnum < __INST_LAST) 
+               lstrcpy(g_variables + varnum*g_stringsize, var);
+}
+
+#ifdef _UNICODE
+int NSISCALL PopStringA(char* ansiStr)
+{
+   wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, g_stringsize*sizeof(wchar_t));
+   int rval = popstring(wideStr);
+   WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
+   GlobalFree((HGLOBAL)wideStr);
+   return rval;
+}
+
+int NSISCALL PopStringNA(char* ansiStr, int maxlen)
+{
+   int realLen = maxlen ? maxlen : g_stringsize;
+   wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, realLen*sizeof(wchar_t));
+   int rval = popstringn(wideStr, realLen);
+   WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, realLen, NULL, NULL);
+   GlobalFree((HGLOBAL)wideStr);
+   return rval;
+}
+
+void NSISCALL PushStringA(const char* ansiStr)
+{
+   wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, g_stringsize*sizeof(wchar_t));
+   MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
+   pushstring(wideStr);
+   GlobalFree((HGLOBAL)wideStr);
+   return;
+}
+
+void NSISCALL GetUserVariableW(const int varnum, wchar_t* wideStr)
+{
+   lstrcpyW(wideStr, getuservariable(varnum));
+}
+
+void NSISCALL GetUserVariableA(const int varnum, char* ansiStr)
+{
+   wchar_t* wideStr = getuservariable(varnum);
+   WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
+}
+
+void NSISCALL SetUserVariableA(const int varnum, const char* ansiStr)
+{
+   if (ansiStr != NULL && varnum >= 0 && varnum < __INST_LAST)
+   {
+      wchar_t* wideStr = g_variables + varnum * g_stringsize;
+      MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
+   }
+}
+
+#else
+// ANSI defs
+int NSISCALL PopStringW(wchar_t* wideStr)
+{
+   char* ansiStr = (char*) GlobalAlloc(GPTR, g_stringsize);
+   int rval = popstring(ansiStr);
+   MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
+   GlobalFree((HGLOBAL)ansiStr);
+   return rval;
+}
+
+int NSISCALL PopStringNW(wchar_t* wideStr, int maxlen)
+{
+   int realLen = maxlen ? maxlen : g_stringsize;
+   char* ansiStr = (char*) GlobalAlloc(GPTR, realLen);
+   int rval = popstringn(ansiStr, realLen);
+   MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, realLen);
+   GlobalFree((HGLOBAL)ansiStr);
+   return rval;
+}
+
+void NSISCALL PushStringW(wchar_t* wideStr)
+{
+   char* ansiStr = (char*) GlobalAlloc(GPTR, g_stringsize);
+   WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
+   pushstring(ansiStr);
+   GlobalFree((HGLOBAL)ansiStr);
+}
+
+void NSISCALL GetUserVariableW(const int varnum, wchar_t* wideStr)
+{
+   char* ansiStr = getuservariable(varnum);
+   MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
+}
+
+void NSISCALL GetUserVariableA(const int varnum, char* ansiStr)
+{
+   lstrcpyA(ansiStr, getuservariable(varnum));
+}
+
+void NSISCALL SetUserVariableW(const int varnum, const wchar_t* wideStr)
+{
+   if (wideStr != NULL && varnum >= 0 && varnum < __INST_LAST)
+   {
+      char* ansiStr = g_variables + varnum * g_stringsize;
+      WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
+   }
+}
+#endif
+
+// playing with integers
+
+int NSISCALL myatoi(const TCHAR *s)
+{
+  int v=0;
+  if (*s == _T('0') && (s[1] == _T('x') || s[1] == _T('X')))
+  {
+    s++;
+    for (;;)
+    {
+      int c=*(++s);
+      if (c >= _T('0') && c <= _T('9')) c-=_T('0');
+      else if (c >= _T('a') && c <= _T('f')) c-=_T('a')-10;
+      else if (c >= _T('A') && c <= _T('F')) c-=_T('A')-10;
+      else break;
+      v<<=4;
+      v+=c;
+    }
+  }
+  else if (*s == _T('0') && s[1] <= _T('7') && s[1] >= _T('0'))
+  {
+    for (;;)
+    {
+      int c=*(++s);
+      if (c >= _T('0') && c <= _T('7')) c-=_T('0');
+      else break;
+      v<<=3;
+      v+=c;
+    }
+  }
+  else
+  {
+    int sign=0;
+    if (*s == _T('-')) sign++; else s--;
+    for (;;)
+    {
+      int c=*(++s) - _T('0');
+      if (c < 0 || c > 9) break;
+      v*=10;
+      v+=c;
+    }
+    if (sign) v = -v;
+  }
+
+  return v;
+}
+
+unsigned NSISCALL myatou(const TCHAR *s)
+{
+  unsigned int v=0;
+
+  for (;;)
+  {
+    unsigned int c=*s++;
+    if (c >= _T('0') && c <= _T('9')) c-=_T('0');
+    else break;
+    v*=10;
+    v+=c;
+  }
+  return v;
+}
+
+int NSISCALL myatoi_or(const TCHAR *s)
+{
+  int v=0;
+  if (*s == _T('0') && (s[1] == _T('x') || s[1] == _T('X')))
+  {
+    s++;
+    for (;;)
+    {
+      int c=*(++s);
+      if (c >= _T('0') && c <= _T('9')) c-=_T('0');
+      else if (c >= _T('a') && c <= _T('f')) c-=_T('a')-10;
+      else if (c >= _T('A') && c <= _T('F')) c-=_T('A')-10;
+      else break;
+      v<<=4;
+      v+=c;
+    }
+  }
+  else if (*s == _T('0') && s[1] <= _T('7') && s[1] >= _T('0'))
+  {
+    for (;;)
+    {
+      int c=*(++s);
+      if (c >= _T('0') && c <= _T('7')) c-=_T('0');
+      else break;
+      v<<=3;
+      v+=c;
+    }
+  }
+  else
+  {
+    int sign=0;
+    if (*s == _T('-')) sign++; else s--;
+    for (;;)
+    {
+      int c=*(++s) - _T('0');
+      if (c < 0 || c > 9) break;
+      v*=10;
+      v+=c;
+    }
+    if (sign) v = -v;
+  }
+
+  // Support for simple ORed expressions
+  if (*s == _T('|')) 
+  {
+      v |= myatoi_or(s+1);
+  }
+
+  return v;
+}
+
+int NSISCALL popint()
+{
+  TCHAR buf[128];
+  if (popstringn(buf,sizeof(buf)/sizeof(TCHAR)))
+    return 0;
+
+  return myatoi(buf);
+}
+
+int NSISCALL popint_or()
+{
+  TCHAR buf[128];
+  if (popstringn(buf,sizeof(buf)/sizeof(TCHAR)))
+    return 0;
+
+  return myatoi_or(buf);
+}
+
+void NSISCALL pushint(int value)
+{
+       TCHAR buffer[1024];
+       wsprintf(buffer, _T("%d"), value);
+       pushstring(buffer);
+}
diff --git a/extras/package/win32/NSIS/nsProcess/pluginapi.h b/extras/package/win32/NSIS/nsProcess/pluginapi.h
new file mode 100644 (file)
index 0000000..b9bfee9
--- /dev/null
@@ -0,0 +1,101 @@
+#ifndef ___NSIS_PLUGIN__H___
+#define ___NSIS_PLUGIN__H___
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "api.h"
+#include "nsis_tchar.h"
+
+#ifndef NSISCALL
+#  define NSISCALL __stdcall
+#endif
+
+#define EXDLL_INIT()           {  \
+        g_stringsize=string_size; \
+        g_stacktop=stacktop;      \
+        g_variables=variables; }
+
+typedef struct _stack_t {
+  struct _stack_t *next;
+  TCHAR text[1]; // this should be the length of string_size
+} stack_t;
+
+enum
+{
+INST_0,         // $0
+INST_1,         // $1
+INST_2,         // $2
+INST_3,         // $3
+INST_4,         // $4
+INST_5,         // $5
+INST_6,         // $6
+INST_7,         // $7
+INST_8,         // $8
+INST_9,         // $9
+INST_R0,        // $R0
+INST_R1,        // $R1
+INST_R2,        // $R2
+INST_R3,        // $R3
+INST_R4,        // $R4
+INST_R5,        // $R5
+INST_R6,        // $R6
+INST_R7,        // $R7
+INST_R8,        // $R8
+INST_R9,        // $R9
+INST_CMDLINE,   // $CMDLINE
+INST_INSTDIR,   // $INSTDIR
+INST_OUTDIR,    // $OUTDIR
+INST_EXEDIR,    // $EXEDIR
+INST_LANG,      // $LANGUAGE
+__INST_LAST
+};
+
+extern unsigned int g_stringsize;
+extern stack_t **g_stacktop;
+extern TCHAR *g_variables;
+
+int NSISCALL popstring(TCHAR *str); // 0 on success, 1 on empty stack
+int NSISCALL popstringn(TCHAR *str, int maxlen); // with length limit, pass 0 for g_stringsize
+int NSISCALL popint(); // pops an integer
+int NSISCALL popint_or(); // with support for or'ing (2|4|8)
+int NSISCALL myatoi(const TCHAR *s); // converts a string to an integer
+unsigned NSISCALL myatou(const TCHAR *s); // converts a string to an unsigned integer, decimal only
+int NSISCALL myatoi_or(const TCHAR *s); // with support for or'ing (2|4|8)
+void NSISCALL pushstring(const TCHAR *str);
+void NSISCALL pushint(int value);
+TCHAR * NSISCALL getuservariable(const int varnum);
+void NSISCALL setuservariable(const int varnum, const TCHAR *var);
+
+#ifdef _UNICODE
+#define PopStringW(x) popstring(x)
+#define PushStringW(x) pushstring(x)
+#define SetUserVariableW(x,y) setuservariable(x,y)
+
+int  NSISCALL PopStringA(char* ansiStr);
+void NSISCALL PushStringA(const char* ansiStr);
+void NSISCALL GetUserVariableW(const int varnum, wchar_t* wideStr);
+void NSISCALL GetUserVariableA(const int varnum, char* ansiStr);
+void NSISCALL SetUserVariableA(const int varnum, const char* ansiStr);
+
+#else
+// ANSI defs
+
+#define PopStringA(x) popstring(x)
+#define PushStringA(x) pushstring(x)
+#define SetUserVariableA(x,y) setuservariable(x,y)
+
+int  NSISCALL PopStringW(wchar_t* wideStr);
+void NSISCALL PushStringW(wchar_t* wideStr);
+void NSISCALL GetUserVariableW(const int varnum, wchar_t* wideStr);
+void NSISCALL GetUserVariableA(const int varnum, char* ansiStr);
+void NSISCALL SetUserVariableW(const int varnum, const wchar_t* wideStr);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif//!___NSIS_PLUGIN__H___
index 7e9159eb78905bfcaee75d5c22cb3dc3536fb8b0..7863036beb93616364449a4fae717a1756bce5a0 100644 (file)
@@ -132,9 +132,18 @@ else
        $(CXX) $^ -D_WIN32_IE=0x0601 -D__forceinline=inline -shared -o $@ -lole32 -static-libstdc++ -static-libgcc
        $(STRIP) $@
 endif
+$(win32_destdir)/NSIS/nsProcess.dll: extras/package/win32/NSIS/nsProcess/nsProcess.c extras/package/win32/NSIS/nsProcess/pluginapi.c
+       mkdir -p "$(win32_destdir)/NSIS/"
+if HAVE_WIN64
+       i686-w64-mingw32-gcc $^ -shared -o $@ -lole32 -static-libgcc
+       i686-w64-mingw32-strip $@
+else
+       $(CC) $^ -D_WIN32_IE=0x0601 -shared -o $@ -lole32 -static-libgcc
+       $(STRIP) $@
+endif
 
 
-package-win32-exe: package-win-strip $(win32_destdir)/NSIS/UAC.dll
+package-win32-exe: package-win-strip $(win32_destdir)/NSIS/UAC.dll $(win32_destdir)/NSIS/nsProcess.dll
 # Script installer
        cp    $(top_builddir)/extras/package/win32/NSIS/vlc.win32.nsi "$(win32_destdir)/"
        cp    $(top_builddir)/extras/package/win32/NSIS/spad.nsi      "$(win32_destdir)/"
@@ -142,6 +151,7 @@ package-win32-exe: package-win-strip $(win32_destdir)/NSIS/UAC.dll
        cp -r $(srcdir)/extras/package/win32/NSIS/helpers      "$(win32_destdir)/"
        mkdir -p "$(win32_destdir)/NSIS/"
        cp "$(top_srcdir)/extras/package/win32/NSIS/UAC.nsh" "$(win32_destdir)/NSIS/"
+       cp "$(top_srcdir)/extras/package/win32/NSIS/nsProcess.nsh" "$(win32_destdir)/NSIS/"
 
 # Create package
        if makensis -VERSION >/dev/null 2>&1; then \