mirror of https://github.com/sipwise/jitsi.git
parent
e1a985a203
commit
e05a78a346
@ -0,0 +1,21 @@
|
||||
<?xml encoding="UTF-8" standalone="yes" version="1.0" ?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
language="*"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
processorArchitecture="X86"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
type="win32"
|
||||
version="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
</assembly>
|
||||
@ -1,3 +0,0 @@
|
||||
mkdir "%UserProfile%/.sip-communicator/log"
|
||||
set PATH=%PATH%;native
|
||||
start run.exe
|
||||
@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency><dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity></dependentAssembly></dependency>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"><security><requestedPrivileges><requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel></requestedPrivileges></security></trustInfo>
|
||||
</assembly>
|
||||
Binary file not shown.
@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency><dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity></dependentAssembly></dependency>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"><security><requestedPrivileges><requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel></requestedPrivileges></security></trustInfo>
|
||||
</assembly>
|
||||
@ -1,369 +0,0 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <shellapi.h> /* ShellExecute */
|
||||
#include <tlhelp32.h> /* CreateToolhelp32Snapshot */
|
||||
|
||||
#include <ctype.h> /* isspace */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tchar.h> /* _istspace */
|
||||
|
||||
#ifndef ERROR_ELEVATION_REQUIRED
|
||||
#define ERROR_ELEVATION_REQUIRED 740
|
||||
#endif
|
||||
|
||||
#ifndef _tcsncicmp
|
||||
#ifdef _UNICODE
|
||||
#define _tcsncicmp _wcsnicmp
|
||||
#else
|
||||
#define _tcsncicmp _strnicmp
|
||||
#endif
|
||||
#endif
|
||||
|
||||
DWORD up2date_createProcess(LPCTSTR);
|
||||
DWORD up2date_displayError(DWORD error);
|
||||
LPTSTR up2date_getAllowElevation(LPTSTR, BOOL *);
|
||||
LPTSTR up2date_getBoolArg(LPCTSTR, LPTSTR, BOOL *);
|
||||
DWORD up2date_getExePath(LPTSTR, DWORD);
|
||||
DWORD up2date_getParentProcessId(DWORD *);
|
||||
LPTSTR up2date_getWaitParent(LPTSTR, BOOL *);
|
||||
LPTSTR up2date_skipWhitespace(LPTSTR);
|
||||
LPWSTR up2date_str2wstr(LPCSTR);
|
||||
DWORD up2date_waitParent();
|
||||
|
||||
int WINAPI
|
||||
WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, int cmdShow) {
|
||||
LPTSTR commandLine;
|
||||
|
||||
LPWSTR wCommandLine;
|
||||
LPWSTR *argv;
|
||||
int argc;
|
||||
LPWSTR wDir;
|
||||
LPWSTR run;
|
||||
|
||||
#ifdef _UNICODE
|
||||
commandLine = up2date_str2wstr(cmdLine);
|
||||
#else
|
||||
commandLine = cmdLine;
|
||||
#endif
|
||||
if (commandLine) {
|
||||
BOOL waitParent;
|
||||
LPTSTR noWaitParentCommandLine;
|
||||
BOOL allowElevation;
|
||||
LPTSTR noAllowElevationCommandLine;
|
||||
DWORD error;
|
||||
|
||||
waitParent = FALSE;
|
||||
noWaitParentCommandLine
|
||||
= up2date_getWaitParent(commandLine, &waitParent);
|
||||
if (waitParent)
|
||||
up2date_waitParent();
|
||||
|
||||
allowElevation = FALSE;
|
||||
noAllowElevationCommandLine
|
||||
= up2date_getAllowElevation(
|
||||
noWaitParentCommandLine, &allowElevation);
|
||||
|
||||
error = up2date_createProcess(noAllowElevationCommandLine);
|
||||
if ((ERROR_ELEVATION_REQUIRED == error) && allowElevation) {
|
||||
TCHAR exePath[MAX_PATH + 1];
|
||||
|
||||
if (!up2date_getExePath(exePath, MAX_PATH + 1)) {
|
||||
SHELLEXECUTEINFO ShExecInfo;
|
||||
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
|
||||
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
||||
ShExecInfo.hwnd = NULL;
|
||||
ShExecInfo.lpVerb = TEXT("runas");
|
||||
ShExecInfo.lpFile = exePath;
|
||||
ShExecInfo.lpParameters = noAllowElevationCommandLine;
|
||||
ShExecInfo.lpDirectory = NULL;
|
||||
ShExecInfo.nShow = SW_HIDE;
|
||||
ShExecInfo.hInstApp = NULL;
|
||||
ShellExecuteEx(&ShExecInfo);
|
||||
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
|
||||
|
||||
#ifdef _UNICODE
|
||||
wCommandLine = commandLine;
|
||||
#else
|
||||
wCommandLine = up2date_str2wstr(commandLine);
|
||||
if (!wCommandLine)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
#endif
|
||||
|
||||
argv = CommandLineToArgvW(wCommandLine, &argc);
|
||||
if (argv)
|
||||
{
|
||||
wDir = *(argv + 3);
|
||||
LPWSTR runExe = L"\\run.exe";
|
||||
int len = wcslen(wDir);
|
||||
run = (wchar_t*)(malloc(sizeof(wchar_t) * (len +
|
||||
wcslen(runExe) + 1)));
|
||||
wcscpy(run, wDir);
|
||||
wcscpy(run + len, runExe);
|
||||
|
||||
ShellExecuteW(NULL, L"open", run,
|
||||
NULL, NULL, SW_SHOWDEFAULT);
|
||||
|
||||
error = GetLastError();
|
||||
if (error)
|
||||
up2date_displayError(error);
|
||||
|
||||
free(run);
|
||||
}
|
||||
}
|
||||
} else if (error)
|
||||
up2date_displayError(error);
|
||||
|
||||
if (((LPVOID) commandLine) != ((LPVOID) cmdLine))
|
||||
free(commandLine);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD
|
||||
up2date_createProcess(LPCTSTR commandLine) {
|
||||
LPWSTR *argv;
|
||||
LPWSTR wCommandLine;
|
||||
int argc;
|
||||
DWORD error;
|
||||
|
||||
#ifdef _UNICODE
|
||||
wCommandLine = commandLine;
|
||||
#else
|
||||
wCommandLine = up2date_str2wstr(commandLine);
|
||||
if (!wCommandLine)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
#endif
|
||||
|
||||
argv = CommandLineToArgvW(wCommandLine, &argc);
|
||||
if (argv) {
|
||||
|
||||
switch (argc) {
|
||||
case 2: {
|
||||
LPWSTR environmentVariableName
|
||||
= up2date_str2wstr("SIP_COMMUNICATOR_AUTOUPDATE_INSTALLDIR");
|
||||
|
||||
if (!environmentVariableName)
|
||||
{
|
||||
error = ERROR_NOT_ENOUGH_MEMORY;
|
||||
break;
|
||||
}
|
||||
if (!SetEnvironmentVariableW(
|
||||
environmentVariableName,
|
||||
*(argv + 1))) {
|
||||
error = GetLastError();
|
||||
free(environmentVariableName);
|
||||
break;
|
||||
}
|
||||
free(environmentVariableName);
|
||||
}
|
||||
case 1: {
|
||||
STARTUPINFOW si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
|
||||
if (CreateProcessW(NULL, *argv, NULL, NULL, FALSE, 0, NULL, NULL,
|
||||
&si, &pi))
|
||||
{
|
||||
error = 0;
|
||||
WaitForSingleObject( pi.hProcess, INFINITE );
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
else
|
||||
error = GetLastError();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
LocalFree((HLOCAL) argv);
|
||||
} else
|
||||
error = GetLastError();
|
||||
|
||||
if (((LPVOID) wCommandLine) != ((LPVOID) commandLine))
|
||||
free(wCommandLine);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
DWORD
|
||||
up2date_displayError(DWORD error) {
|
||||
LPTSTR message;
|
||||
DWORD ret;
|
||||
|
||||
if (FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
0,
|
||||
error,
|
||||
0,
|
||||
(LPTSTR) &message,
|
||||
0,
|
||||
NULL)) {
|
||||
TCHAR caption[MAX_PATH + 1];
|
||||
|
||||
MessageBox(
|
||||
NULL,
|
||||
message,
|
||||
up2date_getExePath(caption, MAX_PATH + 1) ? NULL : caption,
|
||||
MB_ICONERROR);
|
||||
LocalFree((HLOCAL) message);
|
||||
ret = 0;
|
||||
} else
|
||||
ret = GetLastError();
|
||||
return ret;
|
||||
}
|
||||
|
||||
LPTSTR
|
||||
up2date_getAllowElevation(LPTSTR commandLine, BOOL *allowElevation) {
|
||||
return
|
||||
up2date_getBoolArg(
|
||||
TEXT("--allow-elevation"),
|
||||
commandLine,
|
||||
allowElevation);
|
||||
}
|
||||
|
||||
LPTSTR
|
||||
up2date_getBoolArg(LPCTSTR argName, LPTSTR commandLine, BOOL *boolValue) {
|
||||
size_t argNameLength;
|
||||
BOOL argValue;
|
||||
|
||||
argNameLength = _tcslen(argName);
|
||||
commandLine = up2date_skipWhitespace(commandLine);
|
||||
if (0 == _tcsncicmp(commandLine, argName, argNameLength)) {
|
||||
argValue = TRUE;
|
||||
commandLine
|
||||
= up2date_skipWhitespace(commandLine + argNameLength);
|
||||
} else
|
||||
argValue = FALSE;
|
||||
if (boolValue)
|
||||
*boolValue = argValue;
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
DWORD
|
||||
up2date_getExePath(LPTSTR exePath, DWORD exePathSize) {
|
||||
return
|
||||
GetModuleFileName(NULL, (LPTSTR) exePath, exePathSize)
|
||||
? 0
|
||||
: GetLastError();
|
||||
}
|
||||
|
||||
DWORD
|
||||
up2date_getParentProcessId(DWORD *ppid) {
|
||||
HANDLE snapshot;
|
||||
DWORD error;
|
||||
|
||||
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (snapshot == INVALID_HANDLE_VALUE)
|
||||
error = GetLastError();
|
||||
else {
|
||||
PROCESSENTRY32 entry;
|
||||
|
||||
entry.dwSize = sizeof(PROCESSENTRY32);
|
||||
if (Process32First(snapshot, &entry)) {
|
||||
DWORD pid;
|
||||
|
||||
error = 0;
|
||||
pid = GetCurrentProcessId();
|
||||
if (ppid)
|
||||
*ppid = 0;
|
||||
|
||||
do {
|
||||
if (entry.th32ProcessID == pid) {
|
||||
if (ppid)
|
||||
*ppid = entry.th32ParentProcessID;
|
||||
break;
|
||||
}
|
||||
if (!Process32Next(snapshot, &entry)) {
|
||||
error = GetLastError();
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
} else
|
||||
error = GetLastError();
|
||||
CloseHandle(snapshot);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
LPTSTR
|
||||
up2date_getWaitParent(LPTSTR commandLine, BOOL *waitParent) {
|
||||
return
|
||||
up2date_getBoolArg(
|
||||
TEXT("--wait-parent"),
|
||||
commandLine,
|
||||
waitParent);
|
||||
}
|
||||
|
||||
LPTSTR
|
||||
up2date_skipWhitespace(LPTSTR str) {
|
||||
TCHAR ch;
|
||||
|
||||
while ((ch = *str) && _istspace(ch))
|
||||
++str;
|
||||
return str;
|
||||
}
|
||||
|
||||
LPWSTR
|
||||
up2date_str2wstr(LPCSTR str) {
|
||||
int tstrSize;
|
||||
LPWSTR tstr;
|
||||
|
||||
tstrSize =
|
||||
MultiByteToWideChar(CP_THREAD_ACP, 0, str, -1, NULL, 0);
|
||||
if (tstrSize) {
|
||||
tstr = (LPWSTR) malloc(tstrSize * sizeof(WCHAR));
|
||||
if (tstr) {
|
||||
tstrSize
|
||||
= MultiByteToWideChar(CP_THREAD_ACP, 0, str, -1, tstr, tstrSize);
|
||||
if (!tstrSize) {
|
||||
free(tstr);
|
||||
tstr = NULL;
|
||||
}
|
||||
} else
|
||||
tstr = NULL;
|
||||
} else
|
||||
tstr = NULL;
|
||||
return tstr;
|
||||
}
|
||||
|
||||
DWORD
|
||||
up2date_waitParent() {
|
||||
DWORD error;
|
||||
DWORD ppid;
|
||||
|
||||
error = up2date_getParentProcessId(&ppid);
|
||||
if (!error) {
|
||||
HANDLE parentProcess;
|
||||
|
||||
parentProcess = OpenProcess(SYNCHRONIZE, FALSE, ppid);
|
||||
if (parentProcess) {
|
||||
DWORD event;
|
||||
|
||||
error = 0;
|
||||
|
||||
do {
|
||||
event = WaitForSingleObject(parentProcess, INFINITE);
|
||||
if (WAIT_FAILED == event) {
|
||||
error = GetLastError();
|
||||
break;
|
||||
}
|
||||
} while (WAIT_TIMEOUT == event);
|
||||
CloseHandle(parentProcess);
|
||||
} else
|
||||
error = GetLastError();
|
||||
}
|
||||
return error;
|
||||
}
|
||||
Binary file not shown.
@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<dependency><dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity></dependentAssembly></dependency>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"><security><requestedPrivileges><requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel></requestedPrivileges></security></trustInfo>
|
||||
</assembly>
|
||||
@ -0,0 +1,27 @@
|
||||
MINGW_HOME ?= C:/mingw
|
||||
TARGET_BASENAME ?= setup
|
||||
TARGET_DIR ?= ../../../../release/windows/tmp
|
||||
|
||||
CC = $(MINGW_HOME)/bin/gcc
|
||||
CPPFLAGS = \
|
||||
-O2 \
|
||||
-Wall -Wreturn-type \
|
||||
-DWINVER=0x0502 -D_WIN32_WINNT=0x0502
|
||||
LDFLAGS = -mwindows
|
||||
LIBS =
|
||||
TARGET ?= $(TARGET_DIR)/$(TARGET_BASENAME).exe
|
||||
|
||||
MACHINE = $(shell $(CC) -dumpmachine)
|
||||
WINDRES = $(MINGW_HOME)/bin/windres
|
||||
ifneq ("x$(MACHINE)","x")
|
||||
ifeq ($(wildcard $(MINGW_HOME)/bin/$(MACHINE)-windres.*),$(MINGW_HOME)/bin/$(MACHINE)-windres.exe)
|
||||
WINDRES = $(MINGW_HOME)/bin/$(MACHINE)-windres
|
||||
endif
|
||||
endif
|
||||
|
||||
$(TARGET): setup.c $(TARGET_DIR)/setup.res
|
||||
$(CC) $(CPPFLAGS) $^ $(LDFLAGS) -o $@ $(LIBS)
|
||||
-$(MINGW_HOME)/$(MACHINE)/bin/strip $(TARGET)
|
||||
|
||||
$(TARGET_DIR)/setup.res: setup.rc
|
||||
$(WINDRES) -I../../../../resources/install/windows $^ -O coff -o $@
|
||||
@ -0,0 +1,941 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <ctype.h> /* isspace */
|
||||
#include <string.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#ifndef ERROR_RESOURCE_ENUM_USER_STOP
|
||||
#define ERROR_RESOURCE_ENUM_USER_STOP 0x3B02
|
||||
#endif /* #ifndef ERROR_RESOURCE_ENUM_USER_STOP */
|
||||
#include <shellapi.h>
|
||||
#ifndef SEE_MASK_NOASYNC
|
||||
#define SEE_MASK_NOASYNC 0x00000100
|
||||
#endif /* #ifndef SEE_MASK_NOASYNC */
|
||||
#include <tlhelp32.h> /* CreateToolhelp32Snapshot */
|
||||
|
||||
static LPWSTR Setup_commandLine = NULL;
|
||||
static LPTSTR Setup_fileName = NULL;
|
||||
static LPTSTR Setup_productName = NULL;
|
||||
static BOOL Setup_waitForParentProcess_ = FALSE;
|
||||
|
||||
BOOL CALLBACK Setup_enumResNameProc(HMODULE module, LPCTSTR type, LPTSTR name, LONG_PTR param);
|
||||
static DWORD Setup_executeMsi(LPCTSTR path);
|
||||
static DWORD Setup_extractAndExecuteMsi(LPVOID ptr, DWORD size);
|
||||
static LPTSTR Setup_getBoolArg(LPCTSTR argName, LPTSTR commandLine, BOOL *boolValue);
|
||||
static LPCTSTR Setup_getFileName();
|
||||
static DWORD Setup_getParentProcess(DWORD *ppid, LPTSTR *fileName);
|
||||
static LPCTSTR Setup_getProductName();
|
||||
static int Setup_isWow64Acceptable();
|
||||
LRESULT CALLBACK Setup_isWow64AcceptableMessageBoxCallWndRetProc(int code, WPARAM wParam, LPARAM lParam);
|
||||
static DWORD Setup_parseCommandLine(LPSTR cmdLine);
|
||||
static LPTSTR Setup_skipWhitespace(LPTSTR str);
|
||||
static LPWSTR Setup_str2wstr(LPCSTR str);
|
||||
static DWORD Setup_terminateUp2DateExe();
|
||||
static DWORD Setup_waitForParentProcess();
|
||||
|
||||
BOOL CALLBACK
|
||||
Setup_enumResNameProc(
|
||||
HMODULE module,
|
||||
LPCTSTR type, LPTSTR name,
|
||||
LONG_PTR param)
|
||||
{
|
||||
BOOL proceed = TRUE;
|
||||
DWORD error = ERROR_SUCCESS;
|
||||
|
||||
if (!IS_INTRESOURCE(name)
|
||||
&& (_tcslen(name) > 3)
|
||||
&& (_tcsnicmp(name, _T("MSI"), 3) == 0))
|
||||
{
|
||||
HRSRC rsrc = FindResource(module, name, type);
|
||||
|
||||
if (rsrc)
|
||||
{
|
||||
DWORD size = SizeofResource(module, rsrc);
|
||||
|
||||
if (size)
|
||||
{
|
||||
HGLOBAL global = LoadResource(module, rsrc);
|
||||
|
||||
if (global)
|
||||
{
|
||||
LPVOID ptr = LockResource(global);
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
proceed = FALSE;
|
||||
error = Setup_extractAndExecuteMsi(ptr, size);
|
||||
}
|
||||
else
|
||||
error = GetLastError();
|
||||
}
|
||||
else
|
||||
error = GetLastError();
|
||||
}
|
||||
else
|
||||
error = GetLastError();
|
||||
}
|
||||
else
|
||||
error = GetLastError();
|
||||
}
|
||||
if (param)
|
||||
*((DWORD *) param) = error;
|
||||
return proceed;
|
||||
}
|
||||
|
||||
static DWORD
|
||||
Setup_executeMsi(LPCTSTR path)
|
||||
{
|
||||
DWORD error = ERROR_SUCCESS;
|
||||
LPWSTR p0, p1, p2, p3;
|
||||
size_t p0Length, p1Length, p2Length, p3Length;
|
||||
LPWSTR parameters;
|
||||
|
||||
p0 = L"/i \"";
|
||||
p0Length = wcslen(p0);
|
||||
#ifdef _UNICODE
|
||||
p1 = path;
|
||||
#else
|
||||
p1 = Setup_str2wstr(path);
|
||||
#endif /* #ifdef _UNICODE */
|
||||
if (p1)
|
||||
p1Length = wcslen(p1);
|
||||
else
|
||||
{
|
||||
error = ERROR_OUTOFMEMORY;
|
||||
return error;
|
||||
}
|
||||
p2 = L"\" ";
|
||||
p2Length = wcslen(p2);
|
||||
p3 = Setup_commandLine;
|
||||
p3Length = p3 ? wcslen(p3) : 0;
|
||||
|
||||
parameters
|
||||
= (LPWSTR)
|
||||
malloc(
|
||||
sizeof(wchar_t)
|
||||
* (p0Length + p1Length + p2Length + p3Length + 1));
|
||||
if (parameters)
|
||||
{
|
||||
LPWSTR str = parameters;
|
||||
SHELLEXECUTEINFOW sei;
|
||||
|
||||
wcsncpy(str, p0, p0Length);
|
||||
str += p0Length;
|
||||
wcsncpy(str, p1, p1Length);
|
||||
str += p1Length;
|
||||
wcsncpy(str, p2, p2Length);
|
||||
str += p2Length;
|
||||
if (p3Length)
|
||||
{
|
||||
wcsncpy(str, p3, p3Length);
|
||||
str += p3Length;
|
||||
}
|
||||
*str = 0;
|
||||
|
||||
ZeroMemory(&sei, sizeof(sei));
|
||||
sei.cbSize = sizeof(sei);
|
||||
sei.fMask
|
||||
= SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI;
|
||||
sei.lpVerb = L"open";
|
||||
sei.lpFile = L"msiexec.exe";
|
||||
sei.lpParameters = parameters;
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
if (ShellExecuteExW(&sei) && (((int) (sei.hInstApp)) > 32))
|
||||
{
|
||||
if (sei.hProcess)
|
||||
{
|
||||
DWORD event;
|
||||
|
||||
do
|
||||
{
|
||||
event = WaitForSingleObject(sei.hProcess, INFINITE);
|
||||
if (WAIT_FAILED == event)
|
||||
{
|
||||
error = GetLastError();
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (WAIT_TIMEOUT == event);
|
||||
CloseHandle(sei.hProcess);
|
||||
}
|
||||
}
|
||||
else
|
||||
error = GetLastError();
|
||||
|
||||
free(parameters);
|
||||
}
|
||||
else
|
||||
error = ERROR_OUTOFMEMORY;
|
||||
|
||||
if (((LPVOID) p1) != ((LPVOID) path))
|
||||
free(p1);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static DWORD
|
||||
Setup_extractAndExecuteMsi(LPVOID ptr, DWORD size)
|
||||
{
|
||||
TCHAR path[MAX_PATH + 1];
|
||||
DWORD pathSize = sizeof(path) / sizeof(TCHAR);
|
||||
DWORD tempPathLength = GetTempPath(pathSize, path);
|
||||
DWORD error = ERROR_SUCCESS;
|
||||
|
||||
if (tempPathLength)
|
||||
{
|
||||
if (tempPathLength > pathSize)
|
||||
error = ERROR_NOT_ENOUGH_MEMORY;
|
||||
else
|
||||
{
|
||||
LPCTSTR fileName = Setup_getFileName();
|
||||
HANDLE file = INVALID_HANDLE_VALUE;
|
||||
|
||||
if (fileName)
|
||||
{
|
||||
size_t fileNameLength = _tcslen(fileName);
|
||||
|
||||
if ((fileNameLength > 4 /* .exe */)
|
||||
&& (tempPathLength + fileNameLength + 1 <= pathSize))
|
||||
{
|
||||
LPTSTR str = path + tempPathLength;
|
||||
|
||||
_tcsncpy(str, fileName, fileNameLength - 4);
|
||||
str += (fileNameLength - 4);
|
||||
_tcsncpy(str, _T(".msi"), 4);
|
||||
*(str + 4) = 0;
|
||||
|
||||
file
|
||||
= CreateFile(
|
||||
path,
|
||||
GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_NEW,
|
||||
FILE_ATTRIBUTE_TEMPORARY,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (INVALID_HANDLE_VALUE == file)
|
||||
{
|
||||
LPTSTR tempPath;
|
||||
|
||||
path[tempPathLength] = 0;
|
||||
tempPath = _tcsdup(path);
|
||||
|
||||
if (tempPath)
|
||||
{
|
||||
if (0
|
||||
== GetTempFileName(
|
||||
tempPath,
|
||||
_T("MSI"),
|
||||
0,
|
||||
path))
|
||||
{
|
||||
error = GetLastError();
|
||||
}
|
||||
else
|
||||
{
|
||||
file
|
||||
= CreateFile(
|
||||
path,
|
||||
GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_TEMPORARY,
|
||||
NULL);
|
||||
}
|
||||
|
||||
free(tempPath);
|
||||
}
|
||||
else
|
||||
error = ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (INVALID_HANDLE_VALUE != file)
|
||||
{
|
||||
DWORD written;
|
||||
|
||||
if ((FALSE == WriteFile(file, ptr, size, &written, NULL))
|
||||
|| (written != size))
|
||||
{
|
||||
error = GetLastError();
|
||||
CloseHandle(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Setup_waitForParentProcess_)
|
||||
Setup_waitForParentProcess();
|
||||
|
||||
CloseHandle(file);
|
||||
error = Setup_executeMsi(path);
|
||||
}
|
||||
DeleteFile(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
error = GetLastError();
|
||||
return error;
|
||||
}
|
||||
|
||||
static LPTSTR
|
||||
Setup_getBoolArg(LPCTSTR argName, LPTSTR commandLine, BOOL *boolValue)
|
||||
{
|
||||
size_t argNameLength;
|
||||
BOOL argValue;
|
||||
|
||||
argNameLength = _tcslen(argName);
|
||||
commandLine = Setup_skipWhitespace(commandLine);
|
||||
if (0 == _tcsnicmp(commandLine, argName, argNameLength))
|
||||
{
|
||||
argValue = TRUE;
|
||||
commandLine = Setup_skipWhitespace(commandLine + argNameLength);
|
||||
}
|
||||
else
|
||||
argValue = FALSE;
|
||||
if (boolValue)
|
||||
*boolValue = argValue;
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
static LPCTSTR
|
||||
Setup_getFileName()
|
||||
{
|
||||
if (!Setup_fileName)
|
||||
{
|
||||
TCHAR moduleFileName[MAX_PATH + 1];
|
||||
DWORD moduleFileNameSize = sizeof(moduleFileName) / sizeof(TCHAR);
|
||||
DWORD moduleFileNameLength
|
||||
= GetModuleFileName(NULL, moduleFileName, moduleFileNameSize);
|
||||
|
||||
if (moduleFileNameLength)
|
||||
{
|
||||
TCHAR *fileNameEnd = moduleFileName + moduleFileNameLength - 1;
|
||||
TCHAR *fileNameBegin = fileNameEnd;
|
||||
size_t fileNameLength;
|
||||
LPTSTR fileName;
|
||||
|
||||
for (; fileNameBegin >= moduleFileName; fileNameBegin--)
|
||||
{
|
||||
TCHAR c = *fileNameBegin;
|
||||
|
||||
if (('\\' == c) || ('/' == c))
|
||||
break;
|
||||
}
|
||||
fileNameBegin
|
||||
= (fileNameBegin == fileNameEnd)
|
||||
? moduleFileName
|
||||
: (fileNameBegin + 1);
|
||||
|
||||
fileNameLength = (fileNameEnd - fileNameBegin) + 1;
|
||||
fileName = (LPTSTR) malloc((fileNameLength + 1) * sizeof(TCHAR));
|
||||
if (fileName)
|
||||
{
|
||||
_tcsncpy(fileName, fileNameBegin, fileNameLength);
|
||||
*(fileName + fileNameLength) = 0;
|
||||
Setup_fileName = fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Setup_fileName;
|
||||
}
|
||||
|
||||
static DWORD
|
||||
Setup_getParentProcess(DWORD *ppid, LPTSTR *fileName)
|
||||
{
|
||||
HANDLE snapshot;
|
||||
DWORD error;
|
||||
|
||||
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (snapshot == INVALID_HANDLE_VALUE)
|
||||
error = GetLastError();
|
||||
else
|
||||
{
|
||||
PROCESSENTRY32 entry;
|
||||
|
||||
entry.dwSize = sizeof(PROCESSENTRY32);
|
||||
if (Process32First(snapshot, &entry))
|
||||
{
|
||||
DWORD pid;
|
||||
|
||||
error = ERROR_SUCCESS;
|
||||
pid = GetCurrentProcessId();
|
||||
if (ppid)
|
||||
*ppid = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if (entry.th32ProcessID == pid)
|
||||
{
|
||||
if (ppid)
|
||||
*ppid = entry.th32ParentProcessID;
|
||||
break;
|
||||
}
|
||||
if (!Process32Next(snapshot, &entry))
|
||||
{
|
||||
error = GetLastError();
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
} else
|
||||
error = GetLastError();
|
||||
if ((ERROR_SUCCESS == error) && fileName && ppid && *ppid)
|
||||
{
|
||||
if (Process32First(snapshot, &entry))
|
||||
{
|
||||
do
|
||||
{
|
||||
if (entry.th32ProcessID == *ppid)
|
||||
{
|
||||
*fileName = _tcsdup(entry.szExeFile);
|
||||
if (NULL == *fileName)
|
||||
error = ERROR_OUTOFMEMORY;
|
||||
break;
|
||||
}
|
||||
if (!Process32Next(snapshot, &entry))
|
||||
{
|
||||
error = GetLastError();
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
} else
|
||||
error = GetLastError();
|
||||
}
|
||||
CloseHandle(snapshot);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static LPCTSTR
|
||||
Setup_getProductName()
|
||||
{
|
||||
if (!Setup_productName)
|
||||
{
|
||||
/* TODO Auto-generated method stub */
|
||||
LPCTSTR fileName = Setup_getFileName();
|
||||
|
||||
if (fileName)
|
||||
{
|
||||
int fileNameLength = _tcslen(fileName);
|
||||
|
||||
if ((fileNameLength > 4)
|
||||
&& (_tcsnicmp(fileName + fileNameLength - 4, _T(".exe"), 4)
|
||||
== 0))
|
||||
{
|
||||
LPTSTR productName;
|
||||
|
||||
fileNameLength -= 4;
|
||||
productName
|
||||
= (LPTSTR) malloc((fileNameLength + 1) * sizeof(TCHAR));
|
||||
if (productName)
|
||||
{
|
||||
_tcsncpy(productName, fileName, fileNameLength);
|
||||
*(productName + fileNameLength) = 0;
|
||||
Setup_productName = productName;
|
||||
}
|
||||
}
|
||||
if (!Setup_productName)
|
||||
Setup_productName = (LPTSTR) fileName;
|
||||
}
|
||||
}
|
||||
return Setup_productName;
|
||||
}
|
||||
|
||||
static int
|
||||
Setup_isWow64Acceptable()
|
||||
{
|
||||
HMODULE kernel32 = GetModuleHandle(_T("kernel32"));
|
||||
int answer = IDYES;
|
||||
|
||||
if (kernel32)
|
||||
{
|
||||
typedef BOOL (WINAPI *LPISWOW64PROCESS)(HANDLE, PBOOL);
|
||||
|
||||
LPISWOW64PROCESS isWow64Process
|
||||
= (LPISWOW64PROCESS) GetProcAddress(kernel32, _T("IsWow64Process"));
|
||||
BOOL wow64Process = FALSE;
|
||||
|
||||
if (isWow64Process
|
||||
&& isWow64Process(GetCurrentProcess(), &wow64Process)
|
||||
&& wow64Process)
|
||||
{
|
||||
TCHAR fileName[MAX_PATH + 1];
|
||||
|
||||
if (GetModuleFileName(NULL, fileName, sizeof(fileName) / sizeof(TCHAR)))
|
||||
{
|
||||
UINT questionId;
|
||||
UINT buttonType;
|
||||
DWORD questionLength;
|
||||
TCHAR question[1024];
|
||||
|
||||
#ifdef X64_SETUP_URL
|
||||
HHOOK hook
|
||||
= SetWindowsHookEx(
|
||||
WH_CALLWNDPROCRET,
|
||||
(HOOKPROC) Setup_isWow64AcceptableMessageBoxCallWndRetProc,
|
||||
NULL,
|
||||
GetCurrentThreadId());
|
||||
|
||||
if (hook)
|
||||
{
|
||||
questionId = IDS_ISWOW64ACCEPTABLE3;
|
||||
buttonType = MB_YESNOCANCEL | MB_DEFBUTTON3;
|
||||
}
|
||||
else
|
||||
#endif /* #ifdef X64_SETUP_URL */
|
||||
{
|
||||
questionId = IDS_ISWOW64ACCEPTABLE2;
|
||||
buttonType = MB_YESNO;
|
||||
}
|
||||
|
||||
questionLength
|
||||
= LoadString(
|
||||
GetModuleHandle(NULL),
|
||||
questionId,
|
||||
question,
|
||||
sizeof(question) / sizeof(TCHAR));
|
||||
if (questionLength)
|
||||
{
|
||||
answer
|
||||
= MessageBox(
|
||||
NULL,
|
||||
question,
|
||||
fileName,
|
||||
MB_ICONQUESTION | buttonType);
|
||||
LocalFree(question);
|
||||
}
|
||||
|
||||
#ifdef X64_SETUP_URL
|
||||
if (hook)
|
||||
{
|
||||
UnhookWindowsHookEx(hook);
|
||||
|
||||
switch (answer)
|
||||
{
|
||||
case IDNO: // Continue
|
||||
answer = IDYES;
|
||||
break;
|
||||
case IDYES: // Download
|
||||
answer = IDNO;
|
||||
ShellExecute(
|
||||
NULL,
|
||||
_T("open"),
|
||||
_T(X64_SETUP_URL),
|
||||
NULL,
|
||||
NULL,
|
||||
SW_SHOWNORMAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* #ifdef X64_SETUP_URL */
|
||||
}
|
||||
}
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK
|
||||
Setup_isWow64AcceptableMessageBoxCallWndRetProc(
|
||||
int code,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
CWPRETSTRUCT *cwprs = (CWPRETSTRUCT *) lParam;
|
||||
|
||||
if (cwprs && (WM_INITDIALOG == cwprs->message))
|
||||
{
|
||||
HWND yes, no;
|
||||
|
||||
yes = GetDlgItem(cwprs->hwnd, IDYES);
|
||||
if (yes)
|
||||
SendMessage(yes, WM_SETTEXT, 0, (LPARAM) _T("&Download"));
|
||||
|
||||
no = GetDlgItem(cwprs->hwnd, IDNO);
|
||||
if (no)
|
||||
SendMessage(no, WM_SETTEXT, 0, (LPARAM) _T("&Continue"));
|
||||
}
|
||||
return CallNextHookEx(NULL, code, wParam, lParam);
|
||||
}
|
||||
|
||||
static DWORD
|
||||
Setup_parseCommandLine(LPSTR cmdLine)
|
||||
{
|
||||
LPTSTR commandLine;
|
||||
DWORD error = ERROR_SUCCESS;
|
||||
|
||||
#ifdef _UNICODE
|
||||
if (cmdLine)
|
||||
{
|
||||
commandLine = Setup_str2wstr(cmdLine);
|
||||
if (!commandLine)
|
||||
error = ERROR_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
commandLine = NULL;
|
||||
#else
|
||||
commandLine = cmdLine;
|
||||
#endif /* #ifdef _UNICODE */
|
||||
|
||||
if (commandLine)
|
||||
{
|
||||
LPTSTR noWaitParentCommandLine
|
||||
= Setup_getBoolArg(
|
||||
_T("--wait-parent"),
|
||||
commandLine,
|
||||
&Setup_waitForParentProcess_);
|
||||
/*
|
||||
* The command line argument --allow-elevation is up2date legacy which
|
||||
* has to be taken into account by removing it in order to prevent it
|
||||
* from breaking msiexec.
|
||||
*/
|
||||
BOOL up2date;
|
||||
LPTSTR noAllowElevationCommandLine
|
||||
= Setup_getBoolArg(
|
||||
_T("--allow-elevation"),
|
||||
noWaitParentCommandLine,
|
||||
&up2date);
|
||||
size_t noAllowElevationCommandLineLength
|
||||
= _tcslen(noAllowElevationCommandLine);
|
||||
TCHAR envVarValue[1 /* " */ + MAX_PATH + 1 /* " */ + 1];
|
||||
|
||||
if (!up2date && !noAllowElevationCommandLineLength)
|
||||
{
|
||||
DWORD envVarValueSize = (sizeof(envVarValue) / sizeof(TCHAR)) - 2 /* "" */;
|
||||
DWORD envVarValueLength
|
||||
= GetEnvironmentVariable(
|
||||
_T("SIP_COMMUNICATOR_AUTOUPDATE_INSTALLDIR"),
|
||||
&(envVarValue[1]),
|
||||
envVarValueSize);
|
||||
|
||||
if (envVarValueLength)
|
||||
{
|
||||
if (envVarValueLength > envVarValueSize)
|
||||
error = ERROR_NOT_ENOUGH_MEMORY;
|
||||
else
|
||||
{
|
||||
if ((envVarValueLength >= 2)
|
||||
&& ('\"' == envVarValue[1])
|
||||
&& ('\"' == envVarValue[1 + envVarValueLength - 1]))
|
||||
{
|
||||
noAllowElevationCommandLine = &(envVarValue[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
envVarValue[0] = '\"';
|
||||
envVarValue[1 + envVarValueLength] = '\"';
|
||||
envVarValue[1 + envVarValueLength + 1] = 0;
|
||||
envVarValueLength += 2;
|
||||
noAllowElevationCommandLine = envVarValue;
|
||||
}
|
||||
noAllowElevationCommandLineLength = envVarValueLength;
|
||||
up2date = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD envVarError = GetLastError();
|
||||
|
||||
if (ERROR_ENVVAR_NOT_FOUND != envVarError)
|
||||
error = envVarError;
|
||||
}
|
||||
}
|
||||
|
||||
if (up2date && noAllowElevationCommandLineLength)
|
||||
{
|
||||
LPWSTR commandLineW;
|
||||
|
||||
#ifdef _UNICODE
|
||||
commandLineW = noAllowElevationCommandLine;
|
||||
#else
|
||||
commandLineW = Setup_str2wstr(noAllowElevationCommandLine);
|
||||
if (!commandLineW)
|
||||
error = ERROR_OUTOFMEMORY;
|
||||
#endif /* #ifdef _UNICODE */
|
||||
|
||||
if (commandLineW)
|
||||
{
|
||||
int argc;
|
||||
LPWSTR *argv = CommandLineToArgvW(commandLineW, &argc);
|
||||
|
||||
if (argv)
|
||||
{
|
||||
if ((1 == argc) || (2 == argc))
|
||||
{
|
||||
LPWSTR argv1 = *(argv + (argc - 1));
|
||||
size_t argv1Length = wcslen(argv1);
|
||||
|
||||
if ((argv1Length >= 2)
|
||||
&& (L'\"' == argv1[0])
|
||||
&& (L'\"' == argv1[argv1Length - 1]))
|
||||
{
|
||||
argv1++;
|
||||
argv1Length -= 2;
|
||||
}
|
||||
if (argv1Length)
|
||||
{
|
||||
LPCWSTR propertyBegin
|
||||
= L"SIP_COMMUNICATOR_AUTOUPDATE_INSTALLDIR=\"";
|
||||
size_t propertyBeginLength = wcslen(propertyBegin);
|
||||
LPCWSTR propertyEnd = L"\"";
|
||||
size_t propertyEndLength = wcslen(propertyEnd);
|
||||
|
||||
Setup_commandLine
|
||||
= (LPWSTR)
|
||||
malloc(
|
||||
sizeof(wchar_t)
|
||||
* (propertyBeginLength
|
||||
+ argv1Length
|
||||
+ propertyEndLength
|
||||
+ 1));
|
||||
if (Setup_commandLine)
|
||||
{
|
||||
LPWSTR str = Setup_commandLine;
|
||||
|
||||
wcsncpy(
|
||||
str,
|
||||
propertyBegin,
|
||||
propertyBeginLength);
|
||||
str += propertyBeginLength;
|
||||
wcsncpy(str, argv1, argv1Length);
|
||||
str += argv1Length;
|
||||
wcsncpy(str, propertyEnd, propertyEndLength);
|
||||
*(str + propertyEndLength) = 0;
|
||||
}
|
||||
else
|
||||
error = ERROR_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
LocalFree(argv);
|
||||
}
|
||||
else
|
||||
error = GetLastError();
|
||||
|
||||
if (((LPVOID) commandLineW)
|
||||
!= ((LPVOID) noAllowElevationCommandLine))
|
||||
free(commandLineW);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If up2date.exe is running while the MSI is being installed, the MSI
|
||||
* will display a dialog notifying of the fact and asking the user to
|
||||
* either let it close the application in question (and it will not be
|
||||
* able to if the user actually chooses the option) or reboot.
|
||||
*/
|
||||
if (up2date)
|
||||
Setup_terminateUp2DateExe();
|
||||
|
||||
if (!up2date && noAllowElevationCommandLineLength)
|
||||
{
|
||||
#ifdef _UNICODE
|
||||
Setup_commandLine = _wcsdup(noAllowElevationCommandLine);
|
||||
#else
|
||||
Setup_commandLine = Setup_str2wstr(noAllowElevationCommandLine);
|
||||
#endif /* #ifdef _UNICODE */
|
||||
if (Setup_commandLine)
|
||||
{
|
||||
/*
|
||||
* At the time of this writing, we expect a single property to
|
||||
* pass on to msiexec which wants it in the format
|
||||
* PROPERTY="VALUE" if value contains spaces. Unfortunately,
|
||||
* ProcessBuilder on the Java side will break it by quoting the
|
||||
* whole command line argument.
|
||||
*/
|
||||
size_t commandLineLength = wcslen(Setup_commandLine);
|
||||
|
||||
if ((commandLineLength > 3)
|
||||
&& (L'"' == *Setup_commandLine)
|
||||
&& (L'"' == *(Setup_commandLine + (commandLineLength - 2)))
|
||||
&& (L'"' == *(Setup_commandLine + (commandLineLength - 1))))
|
||||
{
|
||||
*(Setup_commandLine + (commandLineLength - 1)) = 0;
|
||||
Setup_commandLine++;
|
||||
}
|
||||
}
|
||||
else
|
||||
error = ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (commandLine != cmdLine)
|
||||
free(commandLine);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static LPTSTR
|
||||
Setup_skipWhitespace(LPTSTR str)
|
||||
{
|
||||
TCHAR c;
|
||||
|
||||
while ((c = *str) && _istspace(c))
|
||||
++str;
|
||||
return str;
|
||||
}
|
||||
|
||||
static LPWSTR
|
||||
Setup_str2wstr(LPCSTR str)
|
||||
{
|
||||
int tstrSize;
|
||||
LPWSTR tstr;
|
||||
|
||||
tstrSize = MultiByteToWideChar(CP_THREAD_ACP, 0, str, -1, NULL, 0);
|
||||
if (tstrSize)
|
||||
{
|
||||
tstr = (LPWSTR) malloc(tstrSize * sizeof(WCHAR));
|
||||
if (tstr)
|
||||
{
|
||||
tstrSize
|
||||
= MultiByteToWideChar(CP_THREAD_ACP, 0, str, -1, tstr, tstrSize);
|
||||
if (!tstrSize)
|
||||
{
|
||||
free(tstr);
|
||||
tstr = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
tstr = NULL;
|
||||
}
|
||||
else
|
||||
tstr = NULL;
|
||||
return tstr;
|
||||
}
|
||||
|
||||
static DWORD
|
||||
Setup_terminateUp2DateExe()
|
||||
{
|
||||
DWORD error;
|
||||
DWORD ppid = 0;
|
||||
LPTSTR ppFileName = NULL;
|
||||
|
||||
error = Setup_getParentProcess(&ppid, &ppFileName);
|
||||
if ((ERROR_SUCCESS == error) && ppFileName)
|
||||
{
|
||||
size_t ppFileNameLength = _tcslen(ppFileName);
|
||||
LPCTSTR up2DateExe = _T("up2date.exe");
|
||||
size_t up2DateExeLength = _tcslen(up2DateExe);
|
||||
|
||||
if ((ppFileNameLength >= up2DateExeLength)
|
||||
&& (_tcsncmp(
|
||||
ppFileName + (ppFileNameLength - up2DateExeLength),
|
||||
up2DateExe,
|
||||
up2DateExeLength)
|
||||
== 0))
|
||||
{
|
||||
HANDLE parentProcess
|
||||
= OpenProcess(PROCESS_TERMINATE, FALSE, ppid);
|
||||
|
||||
if (parentProcess)
|
||||
{
|
||||
if (!TerminateProcess(parentProcess, 0))
|
||||
error = GetLastError();
|
||||
CloseHandle(parentProcess);
|
||||
}
|
||||
else
|
||||
error = GetLastError();
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static DWORD
|
||||
Setup_waitForParentProcess()
|
||||
{
|
||||
DWORD error;
|
||||
DWORD ppid = 0;
|
||||
|
||||
error = Setup_getParentProcess(&ppid, NULL);
|
||||
if (ERROR_SUCCESS == error)
|
||||
{
|
||||
HANDLE parentProcess = OpenProcess(SYNCHRONIZE, FALSE, ppid);
|
||||
|
||||
if (parentProcess)
|
||||
{
|
||||
DWORD event;
|
||||
|
||||
error = ERROR_SUCCESS;
|
||||
do
|
||||
{
|
||||
event = WaitForSingleObject(parentProcess, INFINITE);
|
||||
if (WAIT_FAILED == event)
|
||||
{
|
||||
error = GetLastError();
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (WAIT_TIMEOUT == event);
|
||||
CloseHandle(parentProcess);
|
||||
}
|
||||
else
|
||||
error = GetLastError();
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
int CALLBACK
|
||||
WinMain(
|
||||
HINSTANCE instance, HINSTANCE prevInstance,
|
||||
LPSTR cmdLine,
|
||||
int cmdShow)
|
||||
{
|
||||
DWORD error = ERROR_SUCCESS;
|
||||
|
||||
Setup_parseCommandLine(cmdLine);
|
||||
|
||||
if ((ERROR_SUCCESS == error)
|
||||
&& (IDYES == Setup_isWow64Acceptable())
|
||||
&& (FALSE
|
||||
== EnumResourceNames(
|
||||
NULL,
|
||||
RT_RCDATA,
|
||||
Setup_enumResNameProc,
|
||||
(LONG_PTR) &error))
|
||||
&& (ERROR_SUCCESS == error))
|
||||
{
|
||||
DWORD enumResourceNamesError = GetLastError();
|
||||
|
||||
if ((ERROR_SUCCESS != enumResourceNamesError)
|
||||
&& (ERROR_RESOURCE_ENUM_USER_STOP != enumResourceNamesError))
|
||||
error = enumResourceNamesError;
|
||||
}
|
||||
|
||||
if (ERROR_SUCCESS != error)
|
||||
{
|
||||
LPTSTR message;
|
||||
DWORD messageLength
|
||||
= FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
error,
|
||||
LANG_USER_DEFAULT,
|
||||
(LPTSTR) &message,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (messageLength)
|
||||
{
|
||||
MessageBox(
|
||||
NULL,
|
||||
message,
|
||||
Setup_getProductName(),
|
||||
MB_ICONERROR | MB_OK);
|
||||
LocalFree(message);
|
||||
}
|
||||
}
|
||||
|
||||
if (Setup_productName && (Setup_productName != Setup_fileName))
|
||||
free(Setup_productName);
|
||||
if (Setup_fileName)
|
||||
free(Setup_fileName);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
#ifndef _NET_JAVA_SIP_COMMUNICATOR_WINDOWS_SETUP_H_
|
||||
#define _NET_JAVA_SIP_COMMUNICATOR_WINDOWS_SETUP_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define IDS_ISWOW64ACCEPTABLE2 2
|
||||
#define IDS_ISWOW64ACCEPTABLE3 3
|
||||
|
||||
#endif /* #ifndef _NET_JAVA_SIP_COMMUNICATOR_WINDOWS_SETUP_H_ */
|
||||
@ -0,0 +1,34 @@
|
||||
#include "setup.h"
|
||||
|
||||
SCLogoIcon ICON sc-logo.ico
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_ISWOW64ACCEPTABLE2 "The version of this file is x86 (32-bit) and the version of Windows you're running is x64 (64-bit). It is recommended to install the x64 (64-bit) version of the program.\012\012Continue anyway?"
|
||||
IDS_ISWOW64ACCEPTABLE3 "The version of this file is x86 (32-bit) and the version of Windows you're running is x64 (64-bit). It is recommended to install the x64 (64-bit) version of the program."
|
||||
END
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION 0,0,0,0
|
||||
FILETYPE VFT_APP
|
||||
PRODUCTVERSION 0,0,0,0
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "Comments", ""
|
||||
VALUE "CompanyName", "SIP Communicator"
|
||||
VALUE "FileDescription", "SIP Communicator Setup"
|
||||
VALUE "FileVersion", "0.0.0.0"
|
||||
VALUE "InternalName", "setup"
|
||||
VALUE "OriginalFilename", "setup.exe"
|
||||
VALUE "ProductName", "SIP Communicator"
|
||||
VALUE "ProductVersion", "0.0.0.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0409, 1252
|
||||
END
|
||||
END
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue