diff options
author | Lyubomir Marinov <lyubomir.marinov@jitsi.org> | 2011-03-31 14:44:20 +0000 |
---|---|---|
committer | Lyubomir Marinov <lyubomir.marinov@jitsi.org> | 2011-03-31 14:44:20 +0000 |
commit | ce1dcb1daf05e2865d2707719b043baf3b93443c (patch) | |
tree | 6cae7db2f0308744c3bad0b803c865430efada6b /src/native/windows/setup | |
parent | 7339e33f87ba229e9f76eb6efba78d474e2f6b15 (diff) | |
download | jitsi-ce1dcb1daf05e2865d2707719b043baf3b93443c.zip jitsi-ce1dcb1daf05e2865d2707719b043baf3b93443c.tar.gz jitsi-ce1dcb1daf05e2865d2707719b043baf3b93443c.tar.bz2 |
Adds debug output to the error dialog of setup.exe in order to easier locate the sources of the reproted errors in the source file (such as the 'Class does not exist' reported on the dev mailing list).
Diffstat (limited to 'src/native/windows/setup')
-rw-r--r-- | src/native/windows/setup/Makefile | 7 | ||||
-rw-r--r-- | src/native/windows/setup/lasterror.c | 65 | ||||
-rw-r--r-- | src/native/windows/setup/lasterror.h | 19 | ||||
-rw-r--r-- | src/native/windows/setup/setup.c | 151 | ||||
-rw-r--r-- | src/native/windows/setup/setup.h | 1 | ||||
-rw-r--r-- | src/native/windows/setup/setup.rc | 1 |
6 files changed, 232 insertions, 12 deletions
diff --git a/src/native/windows/setup/Makefile b/src/native/windows/setup/Makefile index 1356b37..af6029a 100644 --- a/src/native/windows/setup/Makefile +++ b/src/native/windows/setup/Makefile @@ -21,9 +21,10 @@ CC = $(MINGW_HOME)/bin/gcc CPPFLAGS = \
-O2 \
-Wall -Wreturn-type \
+ -DPRODUCTNAME='"$(PRODUCTNAME)"' \
-DWINVER=0x0502 -D_WIN32_WINNT=0x0502
LDFLAGS = -mwindows
-LIBS =
+LIBS = -lole32 -lshell32
MACHINE = $(shell $(CC) -dumpmachine)
WINDRES = $(MINGW_HOME)/bin/windres
@@ -33,8 +34,8 @@ ifeq ($(wildcard $(MINGW_HOME)/bin/$(MACHINE)-windres.*),$(MINGW_HOME)/bin/$(MAC endif
endif
-$(cygwin.target.dir)/$(TARGET_BASENAME).exe: setup.c $(cygwin.target.dir)/setup.res
- $(CC) $(CPPFLAGS) setup.c "$(target.dir)/setup.res" $(LDFLAGS) -o "$(target.dir)/$(TARGET_BASENAME).exe" $(LIBS)
+$(cygwin.target.dir)/$(TARGET_BASENAME).exe: lasterror.c setup.c $(cygwin.target.dir)/setup.res
+ $(CC) $(CPPFLAGS) lasterror.c setup.c "$(target.dir)/setup.res" $(LDFLAGS) -o "$(target.dir)/$(TARGET_BASENAME).exe" $(LIBS)
-$(MINGW_HOME)/$(MACHINE)/bin/strip "$(target.dir)/$(TARGET_BASENAME).exe"
$(cygwin.target.dir)/setup.res: setup.rc
diff --git a/src/native/windows/setup/lasterror.c b/src/native/windows/setup/lasterror.c new file mode 100644 index 0000000..96b7ad5 --- /dev/null +++ b/src/native/windows/setup/lasterror.c @@ -0,0 +1,65 @@ +/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+#include "lasterror.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+static DWORD _LastError_error = ERROR_SUCCESS;
+static LPTSTR _LastError_file = NULL;
+static int _LastError_line = 0;
+
+DWORD
+LastError_error()
+{
+ return _LastError_error;
+}
+
+LPCTSTR
+LastError_file()
+{
+ return _LastError_file;
+}
+
+int
+LastError_line()
+{
+ return _LastError_line;
+}
+
+void
+LastError_setLastError(DWORD error, LPCTSTR file, int line)
+{
+ size_t fileLength;
+
+ _LastError_error = error;
+
+ /* Make sure that LastError_file is large enough to receive file. */
+ fileLength = _tcslen(file);
+ if (!_LastError_file || (_tcslen(_LastError_file) < fileLength))
+ {
+ LPTSTR newLastErrorFile
+ = realloc(_LastError_file, sizeof(TCHAR) * (fileLength + 1));
+
+ if (newLastErrorFile)
+ {
+ *newLastErrorFile = 0;
+ _LastError_file = newLastErrorFile;
+ }
+ else if (_LastError_file)
+ {
+ free(_LastError_file);
+ _LastError_file = NULL;
+ }
+ }
+ /* Copy file into LastError_file. */
+ if (_LastError_file)
+ _tcsncpy(_LastError_file, file, fileLength + 1);
+
+ _LastError_line = line;
+}
diff --git a/src/native/windows/setup/lasterror.h b/src/native/windows/setup/lasterror.h new file mode 100644 index 0000000..7fc3c7a --- /dev/null +++ b/src/native/windows/setup/lasterror.h @@ -0,0 +1,19 @@ +/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+#ifndef _NET_JAVA_SIP_COMMUNICATOR_WINDOWS_SETUP_LASTERROR_H_
+#define _NET_JAVA_SIP_COMMUNICATOR_WINDOWS_SETUP_LASTERROR_H_
+
+#include <tchar.h>
+#include <windows.h>
+
+DWORD LastError_error();
+LPCTSTR LastError_file();
+int LastError_line();
+void LastError_setLastError(DWORD error, LPCTSTR file, int line);
+
+#endif /* #ifndef _NET_JAVA_SIP_COMMUNICATOR_WINDOWS_SETUP_LASTERROR_H_ */
diff --git a/src/native/windows/setup/setup.c b/src/native/windows/setup/setup.c index e68d284..d21c5b8 100644 --- a/src/native/windows/setup/setup.c +++ b/src/native/windows/setup/setup.c @@ -5,12 +5,15 @@ * See terms of license at gnu.org.
*/
+#include "lasterror.h"
#include "setup.h"
#include <ctype.h> /* isspace */
+#include <stdlib.h>
#include <string.h>
#include <tchar.h>
+#include <objbase.h>
#ifndef ERROR_RESOURCE_ENUM_USER_STOP
#define ERROR_RESOURCE_ENUM_USER_STOP 0x3B02
#endif /* #ifndef ERROR_RESOURCE_ENUM_USER_STOP */
@@ -73,16 +76,28 @@ Setup_enumResNameProc( error = Setup_extractAndExecuteMsi(ptr, size);
}
else
+ {
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
}
else
+ {
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
}
else
+ {
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
}
else
+ {
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
}
if (param)
*((DWORD *) param) = error;
@@ -109,6 +124,7 @@ Setup_executeMsi(LPCTSTR path) else
{
error = ERROR_OUTOFMEMORY;
+ LastError_setLastError(error, __FILE__, __LINE__);
return error;
}
p2 = L"\" ";
@@ -147,6 +163,13 @@ Setup_executeMsi(LPCTSTR path) sei.lpFile = L"msiexec.exe";
sei.lpParameters = parameters;
sei.nShow = SW_SHOWNORMAL;
+
+ /*
+ * MSDN says it is good practice to always initialize COM before using
+ * ShellExecuteEx.
+ */
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+
if (ShellExecuteExW(&sei) && (((int) (sei.hInstApp)) > 32))
{
if (sei.hProcess)
@@ -159,6 +182,7 @@ Setup_executeMsi(LPCTSTR path) if (WAIT_FAILED == event)
{
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
break;
}
}
@@ -167,12 +191,18 @@ Setup_executeMsi(LPCTSTR path) }
}
else
+ {
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
free(parameters);
}
else
+ {
error = ERROR_OUTOFMEMORY;
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
if (((LPVOID) p1) != ((LPVOID) path))
free(p1);
@@ -191,7 +221,10 @@ Setup_extractAndExecuteMsi(LPVOID ptr, DWORD size) if (tempPathLength)
{
if (tempPathLength > pathSize)
+ {
error = ERROR_NOT_ENOUGH_MEMORY;
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
else
{
LPCTSTR fileName = Setup_getFileName();
@@ -239,6 +272,7 @@ Setup_extractAndExecuteMsi(LPVOID ptr, DWORD size) path))
{
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
}
else
{
@@ -256,7 +290,10 @@ Setup_extractAndExecuteMsi(LPVOID ptr, DWORD size) free(tempPath);
}
else
+ {
error = ERROR_OUTOFMEMORY;
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
}
if (INVALID_HANDLE_VALUE != file)
@@ -267,6 +304,7 @@ Setup_extractAndExecuteMsi(LPVOID ptr, DWORD size) || (written != size))
{
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
CloseHandle(file);
}
else
@@ -283,7 +321,10 @@ Setup_extractAndExecuteMsi(LPVOID ptr, DWORD size) }
}
else
+ {
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
return error;
}
@@ -357,7 +398,10 @@ Setup_getParentProcess(DWORD *ppid, LPTSTR *fileName) snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE)
+ {
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
else
{
PROCESSENTRY32 entry;
@@ -383,12 +427,17 @@ Setup_getParentProcess(DWORD *ppid, LPTSTR *fileName) if (!Process32Next(snapshot, &entry))
{
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
break;
}
}
while (1);
- } else
+ }
+ else
+ {
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
if ((ERROR_SUCCESS == error) && fileName && ppid && *ppid)
{
if (Process32First(snapshot, &entry))
@@ -399,18 +448,26 @@ Setup_getParentProcess(DWORD *ppid, LPTSTR *fileName) {
*fileName = _tcsdup(entry.szExeFile);
if (NULL == *fileName)
+ {
error = ERROR_OUTOFMEMORY;
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
break;
}
if (!Process32Next(snapshot, &entry))
{
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
break;
}
}
while (1);
- } else
+ }
+ else
+ {
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
}
CloseHandle(snapshot);
}
@@ -422,7 +479,6 @@ Setup_getProductName() {
if (!Setup_productName)
{
- /* TODO Auto-generated method stub */
LPCTSTR fileName = Setup_getFileName();
if (fileName)
@@ -579,7 +635,10 @@ Setup_parseCommandLine(LPSTR cmdLine) {
commandLine = Setup_str2wstr(cmdLine);
if (!commandLine)
+ {
error = ERROR_OUTOFMEMORY;
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
}
else
commandLine = NULL;
@@ -611,7 +670,8 @@ Setup_parseCommandLine(LPSTR cmdLine) if (!up2date && !noAllowElevationCommandLineLength)
{
- DWORD envVarValueSize = (sizeof(envVarValue) / sizeof(TCHAR)) - 2 /* "" */;
+ DWORD envVarValueSize
+ = (sizeof(envVarValue) / sizeof(TCHAR)) - 2 /* "" */;
DWORD envVarValueLength
= GetEnvironmentVariable(
_T("SIP_COMMUNICATOR_AUTOUPDATE_INSTALLDIR"),
@@ -621,7 +681,10 @@ Setup_parseCommandLine(LPSTR cmdLine) if (envVarValueLength)
{
if (envVarValueLength > envVarValueSize)
+ {
error = ERROR_NOT_ENOUGH_MEMORY;
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
else
{
if ((envVarValueLength >= 2)
@@ -647,7 +710,10 @@ Setup_parseCommandLine(LPSTR cmdLine) DWORD envVarError = GetLastError();
if (ERROR_ENVVAR_NOT_FOUND != envVarError)
+ {
error = envVarError;
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
}
}
@@ -660,7 +726,10 @@ Setup_parseCommandLine(LPSTR cmdLine) #else
commandLineW = Setup_str2wstr(noAllowElevationCommandLine);
if (!commandLineW)
+ {
error = ERROR_OUTOFMEMORY;
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
#endif /* #ifdef _UNICODE */
if (commandLineW)
@@ -713,13 +782,21 @@ Setup_parseCommandLine(LPSTR cmdLine) *(str + propertyEndLength) = 0;
}
else
+ {
error = ERROR_OUTOFMEMORY;
+ LastError_setLastError(
+ error,
+ __FILE__, __LINE__);
+ }
}
}
LocalFree(argv);
}
else
+ {
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
if (((LPVOID) commandLineW)
!= ((LPVOID) noAllowElevationCommandLine))
@@ -763,7 +840,10 @@ Setup_parseCommandLine(LPSTR cmdLine) }
}
else
+ {
error = ERROR_OUTOFMEMORY;
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
}
if (commandLine != cmdLine)
@@ -837,11 +917,17 @@ Setup_terminateUp2DateExe() if (parentProcess)
{
if (!TerminateProcess(parentProcess, 0))
+ {
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
CloseHandle(parentProcess);
}
else
+ {
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
}
}
return error;
@@ -869,6 +955,7 @@ Setup_waitForParentProcess() if (WAIT_FAILED == event)
{
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
break;
}
}
@@ -876,7 +963,10 @@ Setup_waitForParentProcess() CloseHandle(parentProcess);
}
else
+ {
error = GetLastError();
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
}
return error;
}
@@ -905,7 +995,10 @@ WinMain( if ((ERROR_SUCCESS != enumResourceNamesError)
&& (ERROR_RESOURCE_ENUM_USER_STOP != enumResourceNamesError))
+ {
error = enumResourceNamesError;
+ LastError_setLastError(error, __FILE__, __LINE__);
+ }
}
if (ERROR_SUCCESS != error)
@@ -923,11 +1016,51 @@ WinMain( if (messageLength)
{
- MessageBox(
- NULL,
- message,
- Setup_getProductName(),
- MB_ICONERROR | MB_OK);
+ LPCTSTR lastErrorFile = LastError_file();
+ LPCTSTR productName = Setup_getProductName();
+
+ if (lastErrorFile)
+ {
+ TCHAR lastErrorFormat[1024];
+ int lastErrorFormatLength
+ = LoadString(
+ GetModuleHandle(NULL),
+ IDS_LASTERRORFORMAT,
+ lastErrorFormat,
+ sizeof(lastErrorFormat) / sizeof(TCHAR));
+
+ if (lastErrorFormatLength)
+ {
+ LPTSTR lastErrorMessage;
+ DWORD_PTR lastErrorArguments[]
+ = {
+ (DWORD_PTR) productName,
+ (DWORD_PTR) error,
+ (DWORD_PTR) lastErrorFile,
+ (DWORD_PTR) LastError_line(),
+ (DWORD_PTR) message
+ };
+ DWORD lastErrorMessageLength
+ = FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_ARGUMENT_ARRAY
+ | FORMAT_MESSAGE_FROM_STRING,
+ lastErrorFormat,
+ 0,
+ LANG_USER_DEFAULT,
+ (LPTSTR) &lastErrorMessage,
+ 0,
+ (va_list *) lastErrorArguments);
+
+ if (lastErrorMessageLength)
+ {
+ LocalFree(message);
+ message = lastErrorMessage;
+ }
+ }
+ }
+
+ MessageBox(NULL, message, productName, MB_ICONERROR | MB_OK);
LocalFree(message);
}
}
diff --git a/src/native/windows/setup/setup.h b/src/native/windows/setup/setup.h index cefc92b..3dfaa5f 100644 --- a/src/native/windows/setup/setup.h +++ b/src/native/windows/setup/setup.h @@ -12,5 +12,6 @@ #define IDS_ISWOW64ACCEPTABLE2 2
#define IDS_ISWOW64ACCEPTABLE3 3
+#define IDS_LASTERRORFORMAT 4
#endif /* #ifndef _NET_JAVA_SIP_COMMUNICATOR_WINDOWS_SETUP_H_ */
diff --git a/src/native/windows/setup/setup.rc b/src/native/windows/setup/setup.rc index 2b7b6bc..458c5b0 100644 --- a/src/native/windows/setup/setup.rc +++ b/src/native/windows/setup/setup.rc @@ -13,6 +13,7 @@ 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."
+ IDS_LASTERRORFORMAT "%1!s! has encountered error %2!d! in file %3!s! at line %4!d!:\012\012%5!s!"
END
1 VERSIONINFO
|