diff options
Diffstat (limited to 'desktop/win32/source')
64 files changed, 7594 insertions, 0 deletions
diff --git a/desktop/win32/source/QuickStart/OOQuickStart.rc b/desktop/win32/source/QuickStart/OOQuickStart.rc new file mode 100755 index 000000000000..9baf7e864f5f --- /dev/null +++ b/desktop/win32/source/QuickStart/OOQuickStart.rc @@ -0,0 +1,130 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS +#include "resource.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// German (Germany) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) +#ifdef _WIN32 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +ICON_ACTIVE ICON DISCARDABLE "icons/ooo3_main_app.ico" +IDI_QUICKSTART ICON DISCARDABLE "icons/ooo3_main_app.ico" +IDI_SMALL ICON DISCARDABLE "icons/ooo3_main_app.ico" +ICON_INACTIVE ICON DISCARDABLE "icons/ooo3_main_app.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDC_QUICKSTART ACCELERATORS MOVEABLE PURE +BEGIN + "?", IDM_ABOUT, ASCII, ALT + "/", IDM_ABOUT, ASCII, ALT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG DISCARDABLE 22, 17, 230, 75 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About" +FONT 8, "System" +BEGIN + ICON IDI_QUICKSTART,IDC_MYICON,14,9,16,16 + LTEXT "QuickStart Version 1.0",IDC_STATIC,49,10,119,8, + SS_NOPREFIX + LTEXT "Copyright (C) 2001",IDC_STATIC,49,20,119,8 + DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""resource.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APP_TITLE "SoQuickStart" + IDC_QUICKSTART "QUICKSTART" + IDS_TOOLTIP "StarOffice 6.0 QuickStart" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_EXIT "Exit" +END + +#endif // German (Germany) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/desktop/win32/source/QuickStart/QuickStart.cpp b/desktop/win32/source/QuickStart/QuickStart.cpp new file mode 100755 index 000000000000..999701da985a --- /dev/null +++ b/desktop/win32/source/QuickStart/QuickStart.cpp @@ -0,0 +1,426 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +// QuickStart.cpp : Defines the entry point for the application. +// + +#include "stdafx.h" +#include "resource.h" +#include <systools/win32/uwinapi.h> +#include <stdio.h> + +#define MY_TASKBAR_NOTIFICATION WM_USER+1 + +#define MAX_LOADSTRING 100 + +// message used to communicate with soffice +#define TERMINATIONVETO_MESSAGE "SO TerminationVeto" +#define TERMINATE_MESSAGE "SO Terminate" +#define LISTENER_WINDOWCLASS "SO Listener Class" +#define KILLTRAY_MESSAGE "SO KillTray" + +static UINT aTerminationVetoMessage = 0x7FFF; +static UINT aTerminateMessage = 0x7FFF; +static HMENU popupMenu = NULL; +static bool bTerminateVeto = true; + +#define UPDATE_TIMER 1 + +// Global Variables: +HINSTANCE hInst; // current instance +TCHAR szTitle[MAX_LOADSTRING]; // The title bar text +TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text + +TCHAR szExitString[MAX_LOADSTRING]; +TCHAR szTooltipString[MAX_LOADSTRING]; + +// Foward declarations of functions included in this code module: +ATOM MyRegisterClass(HINSTANCE hInstance); +BOOL InitInstance(HINSTANCE, int); +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); + +bool SofficeRuns() +{ + // check for soffice by searching the communication window + return ( FindWindowEx( NULL, NULL, LISTENER_WINDOWCLASS, NULL ) == NULL ) ? false : true; +} + +bool launchSoffice( ) +{ + if ( !SofficeRuns() ) + { + // UINT ret = WinExec( "h:\\office60.630b\\program\\swriter.exe -bean", SW_SHOW ); + char filename[_MAX_PATH + 1]; + + filename[_MAX_PATH] = 0; + GetModuleFileName( NULL, filename, _MAX_PATH ); // soffice resides in the same dir + char *p = strrchr( filename, '\\' ); + if ( !p ) + return false; + + strncpy( p+1, "soffice.exe", _MAX_PATH - (p+1 - filename) ); + + char imagename[_MAX_PATH + 1]; + + imagename[_MAX_PATH] = 0; + _snprintf(imagename, _MAX_PATH, "\"%s\" -quickstart", filename ); + + UINT ret = WinExec( imagename, SW_SHOW ); + if ( ret < 32 ) + return false; +/* + // wait until we can communicate + int retry = 30; + while (retry-- && !SofficeRuns() ) + Sleep(1000); + + return SofficeRuns(); + */ + return true; + } + else + return true; +} + +void NotifyListener( HWND hWnd ) +{ + static HICON hIconActive=NULL; + //static HICON hIconInActive=NULL; + + if( !hIconActive ) + { + hIconActive = (HICON)LoadImage( GetModuleHandle( NULL ), MAKEINTRESOURCE( ICON_ACTIVE ), + IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), + LR_DEFAULTCOLOR | LR_SHARED ); + +/* hIconInActive = (HICON)LoadImage( GetModuleHandle( NULL ), MAKEINTRESOURCE( ICON_INACTIVE ), + IMAGE_ICON, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), + LR_DEFAULTCOLOR | LR_SHARED ); + */ + } + + NOTIFYICONDATA nid; + nid.cbSize = sizeof(NOTIFYICONDATA); + nid.hWnd = hWnd; + nid.uID = IDM_QUICKSTART; + nid.szTip[SAL_N_ELEMENTS(nid.szTip) - 1] = 0; +// nid.hIcon = bTerminateVeto ? hIconActive : hIconInActive; +// strncpy(nid.szTip, bTerminateVeto ? STRING_QUICKSTARTACTIVE : STRING_QUICKSTARTINACTIVE, SAL_N_ELEMENTS(nid.szTip) - 1 ); + nid.hIcon = hIconActive; + strncpy(nid.szTip, szTooltipString, SAL_N_ELEMENTS(nid.szTip) - 1); + nid.uFlags = NIF_TIP|NIF_ICON; + + // update systray + Shell_NotifyIcon( NIM_MODIFY, &nid ); + //CheckMenuItem( popupMenu, IDM_QUICKSTART, bTerminateVeto ? MF_CHECKED : MF_UNCHECKED ); + + // notify listener + SendMessage( HWND_BROADCAST, aTerminationVetoMessage, (WORD) bTerminateVeto, 0L ); +} + + + +int APIENTRY WinMain(HINSTANCE hInstance, + HINSTANCE /*hPrevInstance*/, + LPSTR /*lpCmdLine*/, + int nCmdShow) +{ + // Look for -killtray argument + + for ( int i = 1; i < __argc; i++ ) + { + if ( 0 == strcmp( __argv[i], "-killtray" ) ) + { + HWND hwndTray = FindWindow( LISTENER_WINDOWCLASS, NULL ); + + if ( hwndTray ) + { + UINT uMsgKillTray = RegisterWindowMessage( KILLTRAY_MESSAGE ); + SendMessage( hwndTray, uMsgKillTray, 0, 0 ); + } + + return 0; + } + } + + launchSoffice(); + return 0; + + // TODO: Place code here. + MSG msg; + HACCEL hAccelTable; + aTerminationVetoMessage = RegisterWindowMessage( TERMINATIONVETO_MESSAGE ); + aTerminateMessage = RegisterWindowMessage( TERMINATE_MESSAGE ); + + // Initialize global strings + LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); + LoadString(hInstance, IDC_QUICKSTART, szWindowClass, MAX_LOADSTRING); + + LoadString(hInstance, IDS_EXIT, szExitString, MAX_LOADSTRING); + LoadString(hInstance, IDS_TOOLTIP, szTooltipString, MAX_LOADSTRING); + + MyRegisterClass(hInstance); + + // Perform application initialization: + if (!InitInstance (hInstance, nCmdShow)) + { + return FALSE; + } + + hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_QUICKSTART); + + // Main message loop: + while (GetMessage(&msg, NULL, 0, 0)) + { + if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + return msg.wParam; +} + + + +// +// FUNCTION: MyRegisterClass() +// +// PURPOSE: Registers the window class. +// +// COMMENTS: +// +// This function and its usage is only necessary if you want this code +// to be compatible with Win32 systems prior to the 'RegisterClassEx' +// function that was added to Windows 95. It is important to call this function +// so that the application will get 'well formed' small icons associated +// with it. +// +ATOM MyRegisterClass(HINSTANCE hInstance) +{ + WNDCLASSEX wcex; + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = (WNDPROC)WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_QUICKSTART); + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wcex.lpszMenuName = NULL; + wcex.lpszClassName = szWindowClass; + wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); + + return RegisterClassEx(&wcex); +} + +// +// FUNCTION: InitInstance(HANDLE, int) +// +// PURPOSE: Saves instance handle and creates main window +// +// COMMENTS: +// +// In this function, we save the instance handle in a global variable and +// create and display the main program window. +// +BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) +{ + HWND hWnd; + + hInst = hInstance; // Store instance handle in our global variable + + hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); + + if (!hWnd) + { + return FALSE; + } + + nCmdShow = SW_HIDE; // hide main window, we only need the taskbar icon + ShowWindow(hWnd, nCmdShow); + UpdateWindow(hWnd); + + return TRUE; +} + +// +// FUNCTION: WndProc(HWND, unsigned, WORD, LONG) +// +// PURPOSE: Processes messages for the main window. +// +// WM_COMMAND - process the application menu +// WM_PAINT - Paint the main window +// WM_DESTROY - post a quit message and return +// +// +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_CREATE: + { + // make sure soffice runs + if( !launchSoffice() ) + return -1; + + // create popup menu + popupMenu = CreatePopupMenu(); + static int count=0; + + // Add my items + MENUITEMINFO mi; + mi.cbSize = sizeof(MENUITEMINFO); + mi.fMask=MIIM_TYPE|MIIM_STATE|MIIM_ID; + mi.fType=MFT_STRING; + mi.fState=MFS_ENABLED|MFS_DEFAULT; + mi.wID = IDM_QUICKSTART; + mi.hSubMenu=NULL; + mi.hbmpChecked=NULL; + mi.hbmpUnchecked=NULL; + mi.dwItemData=NULL; + mi.dwTypeData = "QuickStart"; + mi.cch = strlen(mi.dwTypeData); +// InsertMenuItem(popupMenu, count++, TRUE, &mi); + + mi.cbSize = sizeof(MENUITEMINFO); + mi.fMask=MIIM_TYPE|MIIM_STATE|MIIM_ID; + mi.fType=MFT_STRING; + mi.fState=MFS_ENABLED; + mi.wID = IDM_ABOUT; + mi.hSubMenu=NULL; + mi.hbmpChecked=NULL; + mi.hbmpUnchecked=NULL; + mi.dwItemData=NULL; + mi.dwTypeData = "Info..."; + mi.cch = strlen(mi.dwTypeData); +// InsertMenuItem(popupMenu, count++, TRUE, &mi); + + mi.cbSize = sizeof(MENUITEMINFO); + mi.fMask=MIIM_TYPE; + mi.fType=MFT_SEPARATOR; + mi.hSubMenu=NULL; + mi.hbmpChecked=NULL; + mi.hbmpUnchecked=NULL; + mi.dwItemData=NULL; +// InsertMenuItem(popupMenu, count++, TRUE, &mi); + + mi.cbSize = sizeof(MENUITEMINFO); + mi.fMask=MIIM_TYPE|MIIM_STATE|MIIM_ID; + mi.fType=MFT_STRING; + mi.fState=MFS_ENABLED; + mi.wID = IDM_EXIT; + mi.hSubMenu=NULL; + mi.hbmpChecked=NULL; + mi.hbmpUnchecked=NULL; + mi.dwItemData=NULL; + mi.dwTypeData = szExitString; + mi.cch = strlen(mi.dwTypeData); + InsertMenuItem(popupMenu, count++, TRUE, &mi); + + // add taskbar icon + NOTIFYICONDATA nid; + nid.cbSize = sizeof(NOTIFYICONDATA); + nid.hWnd = hWnd; + nid.uID = IDM_QUICKSTART; + nid.uFlags = NIF_MESSAGE; + nid.uCallbackMessage=MY_TASKBAR_NOTIFICATION; + Shell_NotifyIcon(NIM_ADD, &nid); + + // and update state + NotifyListener( hWnd ); + + // check for soffice + SetTimer(hWnd, UPDATE_TIMER, 3000, NULL); + } + break; + + case MY_TASKBAR_NOTIFICATION: // message from taskbar + switch(lParam) + { +/* + case WM_LBUTTONDBLCLK: + bTerminateVeto = bTerminateVeto ? false : true; + NotifyListener( hWnd ); + break; + */ + + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + { + POINT pt; + GetCursorPos(&pt); + SetForegroundWindow( hWnd ); + int m = TrackPopupMenuEx(popupMenu, TPM_RETURNCMD|TPM_LEFTALIGN|TPM_RIGHTBUTTON, + pt.x, pt.y, hWnd, NULL); + // BUGFIX: See Q135788 (PRB: Menus for Notification Icons Don't Work Correctly) + PostMessage(hWnd, NULL, 0, 0); + switch(m) + { + case IDM_QUICKSTART: + bTerminateVeto = bTerminateVeto ? false : true; + NotifyListener( hWnd ); + break; + case IDM_ABOUT: + DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); + break; + case IDM_EXIT: + DestroyWindow(hWnd); + break; + } + } + break; + } + break; + + case WM_TIMER: + if( wParam == UPDATE_TIMER ) + { + // update state + NotifyListener( hWnd ); + } + break; + + case WM_DESTROY: + // try to terminate office + SendMessage( HWND_BROADCAST, aTerminateMessage, 0, 0L ); + + // delete taskbar icon + NOTIFYICONDATA nid; + nid.cbSize=sizeof(NOTIFYICONDATA); + nid.hWnd = hWnd; + nid.uID = IDM_QUICKSTART; + Shell_NotifyIcon(NIM_DELETE, &nid); + + PostQuitMessage(0); + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return 0; +} + +// Mesage handler for about box. +LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM) +{ + switch (message) + { + case WM_INITDIALOG: + return TRUE; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) + { + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + break; + } + return FALSE; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/QuickStart/QuickStart.h b/desktop/win32/source/QuickStart/QuickStart.h new file mode 100755 index 000000000000..b61a04075e08 --- /dev/null +++ b/desktop/win32/source/QuickStart/QuickStart.h @@ -0,0 +1,15 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#if !defined(AFX_QUICKSTART_H__7D38EE02_7699_4CF0_AFF9_FD92E05CC009__INCLUDED_) +#define AFX_QUICKSTART_H__7D38EE02_7699_4CF0_AFF9_FD92E05CC009__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "resource.h" + + +#endif // !defined(AFX_QUICKSTART_H__7D38EE02_7699_4CF0_AFF9_FD92E05CC009__INCLUDED_) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/QuickStart/StdAfx.h b/desktop/win32/source/QuickStart/StdAfx.h new file mode 100755 index 000000000000..f5277a01332c --- /dev/null +++ b/desktop/win32/source/QuickStart/StdAfx.h @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) +#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + + +// Windows Header Files: +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#include <shellapi.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +// C RunTime Header Files +#include <stdlib.h> +#include <malloc.h> +#include <memory.h> +#include <tchar.h> + +// Local Header Files + +// TODO: reference additional headers your program requires here + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/QuickStart/makefile.mk b/desktop/win32/source/QuickStart/makefile.mk new file mode 100644 index 000000000000..41242d849dfb --- /dev/null +++ b/desktop/win32/source/QuickStart/makefile.mk @@ -0,0 +1,74 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=sysui +TARGET=quickstart +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE +TARGETTYPE=GUI + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +UWINAPILIB = + +# --- Resources ---------------------------------------------------- + +RCFILES=OOQuickStart.rc + +# --- Files -------------------------------------------------------- + +OBJFILES=$(OBJ)$/QuickStart.obj + +APP1OBJS=$(OBJFILES) +APP1NOSAL=TRUE +APP1TARGET=$(TARGET) +APP1RPATH=BRAND +.IF "$(COM)"=="GCC" +APP1STDLIBS=-luuid +.ELSE +APP1STDLIBS=comsupp.lib +.ENDIF + +APP1STDLIBS+=$(SHELL32LIB)\ + $(OLE32LIB)\ + $(GDI32LIB)\ + $(OLEAUT32LIB)\ + $(COMDLG32LIB)\ + $(KERNEL32LIB)\ + $(OLEAUT32LIB) + +APP1NOSVRES=$(RES)$/$(TARGET).res + + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/desktop/win32/source/QuickStart/resource.h b/desktop/win32/source/QuickStart/resource.h new file mode 100755 index 000000000000..dc4a70ab5193 --- /dev/null +++ b/desktop/win32/source/QuickStart/resource.h @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by QUICKSTART.RC +// +#define IDR_MAINFRAME 128 +#define IDD_QUICKSTART_DIALOG 102 +#define IDD_ABOUTBOX 103 +#define IDS_APP_TITLE 103 +#define IDM_ABOUT 104 +#define IDM_EXIT 105 +#define IDS_HELLO 106 +#define IDI_QUICKSTART 107 +#define IDI_SMALL 108 +#define IDC_QUICKSTART 109 +#define IDM_QUICKSTART 110 +#define IDS_TOOLTIP 111 +#define IDS_EXIT 112 +#define ICON_ACTIVE 1 +#define ICON_INACTIVE 2 +#define IDC_MYICON 3 +#define IDC_STATIC -1 +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS + +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 113 +#endif +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/QuickStart/so/QuickStart.rc b/desktop/win32/source/QuickStart/so/QuickStart.rc new file mode 100755 index 000000000000..732904dc745a --- /dev/null +++ b/desktop/win32/source/QuickStart/so/QuickStart.rc @@ -0,0 +1,130 @@ +//Microsoft Developer Studio generated resource script. +// +#include "../resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS +#include "resource.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// German (Germany) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) +#ifdef _WIN32 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +ICON_ACTIVE ICON DISCARDABLE "icons/so9_main_app.ico" +IDI_QUICKSTART ICON DISCARDABLE "icons/so9_main_app.ico" +IDI_SMALL ICON DISCARDABLE "icons/so9_main_app.ico" +ICON_INACTIVE ICON DISCARDABLE "icons/so9_main_app.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDC_QUICKSTART ACCELERATORS MOVEABLE PURE +BEGIN + "?", IDM_ABOUT, ASCII, ALT + "/", IDM_ABOUT, ASCII, ALT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG DISCARDABLE 22, 17, 230, 75 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About" +FONT 8, "System" +BEGIN + ICON IDI_QUICKSTART,IDC_MYICON,14,9,16,16 + LTEXT "QuickStart Version 1.0",IDC_STATIC,49,10,119,8, + SS_NOPREFIX + LTEXT "Copyright (C) 2001",IDC_STATIC,49,20,119,8 + DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""resource.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APP_TITLE "SoQuickStart" + IDC_QUICKSTART "QUICKSTART" + IDS_TOOLTIP "Oracle Open Office 3.2 QuickStart" +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_EXIT "Exit" +END + +#endif // German (Germany) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/desktop/win32/source/QuickStart/so/makefile.mk b/desktop/win32/source/QuickStart/so/makefile.mk new file mode 100755 index 000000000000..50154c7d50b2 --- /dev/null +++ b/desktop/win32/source/QuickStart/so/makefile.mk @@ -0,0 +1,77 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. + +PRJNAME=sysui +TARGET=soquickstart +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE +TARGETTYPE=GUI + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +UWINAPILIB = + +# --- Resources ---------------------------------------------------- + +.IF "$(LINK_SO)"=="TRUE" + +RCFILES=QuickStart.rc +INCPRE=.. + +# --- Files -------------------------------------------------------- + +OBJFILES=$(OBJ)$/QuickStart.obj + +APP1OBJS=$(OBJFILES) +APP1NOSAL=TRUE +APP1TARGET=$(TARGET) +APP1RPATH=BRAND +.IF "$(COM)"=="GCC" +APP1STDLIBS=-luuid +.ELSE +APP1STDLIBS=comsupp.lib +.ENDIF + +APP1STDLIBS+=$(SHELL32LIB)\ + $(OLE32LIB)\ + $(GDI32LIB)\ + $(OLEAUT32LIB)\ + $(COMDLG32LIB)\ + $(KERNEL32LIB)\ + $(OLEAUT32LIB) + +APP1NOSVRES=$(RES)$/$(TARGET).res + +.ENDIF # "$(LINK_SO)"=="TRUE" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/desktop/win32/source/applauncher/launcher.cxx b/desktop/win32/source/applauncher/launcher.cxx new file mode 100644 index 000000000000..a7a17b59a215 --- /dev/null +++ b/desktop/win32/source/applauncher/launcher.cxx @@ -0,0 +1,147 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#include "launcher.hxx" + + +#ifndef _WINDOWS_ +# define WIN32_LEAN_AND_MEAN +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +# include <windows.h> +# include <shellapi.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#endif + + +#include <stdlib.h> +#include <malloc.h> + + +#ifdef __MINGW32__ +extern "C" int APIENTRY WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) +#else +extern "C" int APIENTRY _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int ) +#endif +{ + // Retreive startup info + + STARTUPINFO aStartupInfo; + + ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) ); + aStartupInfo.cb = sizeof( aStartupInfo ); + GetStartupInfo( &aStartupInfo ); + + // Retrieve command line + + LPTSTR lpCommandLine = GetCommandLine(); + + LPTSTR *ppArguments = NULL; + int nArguments = 0; + + ppArguments = GetArgv( &nArguments ); + + { + lpCommandLine = (LPTSTR)_alloca( sizeof(_TCHAR) * (_tcslen(lpCommandLine) + _tcslen(APPLICATION_SWITCH) + 2) ); + + _tcscpy( lpCommandLine, GetCommandLine() ); + _tcscat( lpCommandLine, _T(" ") ); + _tcscat( lpCommandLine, APPLICATION_SWITCH ); + } + + + // Calculate application name + + TCHAR szApplicationName[MAX_PATH]; + TCHAR szDrive[MAX_PATH]; + TCHAR szDir[MAX_PATH]; + TCHAR szFileName[MAX_PATH]; + TCHAR szExt[MAX_PATH]; + + GetModuleFileName( NULL, szApplicationName, MAX_PATH ); + _tsplitpath( szApplicationName, szDrive, szDir, szFileName, szExt ); + _tmakepath( szApplicationName, szDrive, szDir, OFFICE_IMAGE_NAME, _T(".exe") ); + + PROCESS_INFORMATION aProcessInfo; + + BOOL fSuccess = CreateProcess( + szApplicationName, + lpCommandLine, + NULL, + NULL, + TRUE, + 0, + NULL, + NULL, + &aStartupInfo, + &aProcessInfo ); + + if ( fSuccess ) + { + // Wait for soffice process to be terminated to allow other applications + // to wait for termination of started process + + WaitForSingleObject( aProcessInfo.hProcess, INFINITE ); + + CloseHandle( aProcessInfo.hProcess ); + CloseHandle( aProcessInfo.hThread ); + + return 0; + } + + DWORD dwError = GetLastError(); + + LPVOID lpMsgBuf; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dwError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR)&lpMsgBuf, + 0, + NULL + ); + + // Display the string. + MessageBox( NULL, (LPCTSTR)lpMsgBuf, NULL, MB_OK | MB_ICONERROR ); + + // Free the buffer. + LocalFree( lpMsgBuf ); + + return GetLastError(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/applauncher/launcher.hxx b/desktop/win32/source/applauncher/launcher.hxx new file mode 100644 index 000000000000..46829d67037c --- /dev/null +++ b/desktop/win32/source/applauncher/launcher.hxx @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#pragma once +#ifndef __cplusplus +#error Need C++ to compile +#endif + +#ifndef _INC_TCHAR +# ifdef UNICODE +# define _UNICODE +# endif +# include <tchar.h> +#endif + +#ifdef UNICODE +# define GetArgv( pArgc ) CommandLineToArgvW( GetCommandLine(), pArgc ) +#else +# define GetArgv( pArgc ) (*pArgc = __argc, __argv) +#endif + +#define OFFICE_IMAGE_NAME _T("soffice") + +extern _TCHAR APPLICATION_SWITCH[]; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/applauncher/makefile.mk b/desktop/win32/source/applauncher/makefile.mk new file mode 100755 index 000000000000..d08309bbed24 --- /dev/null +++ b/desktop/win32/source/applauncher/makefile.mk @@ -0,0 +1,150 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=desktop +TARGET=applauncher +LIBTARGET=NO +TARGETTYPE=GUI +UWINAPILIB= + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +CDEFS+=-DUNICODE + + +OBJFILES= \ + $(OBJ)$/launcher.obj \ + $(OBJ)$/swriter.obj \ + $(OBJ)$/scalc.obj \ + $(OBJ)$/sdraw.obj \ + $(OBJ)$/simpress.obj \ + $(OBJ)$/sbase.obj \ + $(OBJ)$/smath.obj \ + $(OBJ)$/sweb.obj + +# SO launcher +.IF "$(LINK_SO)"=="TRUE" +.IF "$(BUILD_SPECIAL)"!="" +APP1DEPN= $(APP1RES) verinfo.rc +APP1TARGET=so$/swriter +APP1NOSAL=TRUE +APP1LINKRES=$(MISC)$/$(TARGET)1.res +APP1ICON=$(SOLARRESDIR)$/icons/so9_writer_app.ico +APP1OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/swriter.obj +APP1STDLIBS = $(SHELL32LIB) +APP1VERINFO=verinfo.rc +APP1PRODUCTDEF+=-DRES_APP_NAME=swriter + +APP2TARGET=so$/scalc +APP2NOSAL=TRUE +APP2LINKRES=$(MISC)$/$(TARGET)2.res +APP2ICON=$(SOLARRESDIR)$/icons/so9_calc_app.ico +APP2OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/scalc.obj +APP2STDLIBS = $(SHELL32LIB) +APP2DEPN=verinfo.rc +APP2VERINFO=verinfo.rc +APP2PRODUCTDEF+=-DRES_APP_NAME=scalc + +APP3TARGET=so$/sdraw +APP3NOSAL=TRUE +APP3LINKRES=$(MISC)$/$(TARGET)3.res +APP3ICON=$(SOLARRESDIR)$/icons/so9_draw_app.ico +APP3OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/sdraw.obj +APP3STDLIBS = $(SHELL32LIB) +APP3DEPN=verinfo.rc +APP3VERINFO=verinfo.rc +APP3PRODUCTDEF+=-DRES_APP_NAME=sdraw + +APP4TARGET=so$/simpress +APP4NOSAL=TRUE +APP4LINKRES=$(MISC)$/$(TARGET)4.res +APP4ICON=$(SOLARRESDIR)$/icons/so9_impress_app.ico +APP4OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/simpress.obj +APP4STDLIBS = $(SHELL32LIB) +APP4DEPN=verinfo.rc +APP4VERINFO=verinfo.rc +APP4PRODUCTDEF+=-DRES_APP_NAME=simpress + +APP5TARGET=so$/sbase +APP5NOSAL=TRUE +APP5LINKRES=$(MISC)$/$(TARGET)5.res +APP5ICON=$(SOLARRESDIR)$/icons/so9_base_app.ico +APP5OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/sbase.obj +APP5STDLIBS = $(SHELL32LIB) +APP5DEPN=verinfo.rc +APP5VERINFO=verinfo.rc +APP5PRODUCTDEF+=-DRES_APP_NAME=sbase + +APP6TARGET=so$/smath +APP6NOSAL=TRUE +APP6LINKRES=$(MISC)$/$(TARGET)6.res +APP6ICON=$(SOLARRESDIR)$/icons/so9_math_app.ico +APP6OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/smath.obj +APP6STDLIBS = $(SHELL32LIB) +APP6DEPN=verinfo.rc +APP6VERINFO=verinfo.rc +APP6PRODUCTDEF+=-DRES_APP_NAME=smath + +APP7TARGET=so$/sweb +APP7NOSAL=TRUE +APP7LINKRES=$(MISC)$/$(TARGET)7.res +APP7ICON=$(SOLARRESDIR)$/icons/so9_writer_app.ico +APP7OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/sweb.obj +APP7STDLIBS = $(SHELL32LIB) +APP7DEPN=verinfo.rc +APP7VERINFO=verinfo.rc +APP7PRODUCTDEF+=-DRES_APP_NAME=sweb + + +.ENDIF # "$(BUILD_SPECIAL)"!="" +.ENDIF # "$(LINK_SO)"=="TRUE" + +# --- Targets ------------------------------------------------------ + + +.INCLUDE : target.mk + diff --git a/desktop/win32/source/applauncher/ooo/makefile.mk b/desktop/win32/source/applauncher/ooo/makefile.mk new file mode 100755 index 000000000000..02f240cce9e0 --- /dev/null +++ b/desktop/win32/source/applauncher/ooo/makefile.mk @@ -0,0 +1,130 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. + +PRJNAME=desktop +TARGET=applauncher +LIBTARGET=NO +TARGETTYPE=GUI +UWINAPILIB= + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +APP1TARGET=swriter +APP1DEPN=verinfo.rc +APP1VERINFO=verinfo.rc +APP1NOSAL=TRUE +APP1LINKRES=$(MISC)$/$(TARGET)1.res +APP1ICON=$(SOLARRESDIR)$/icons/ooo3_writer_app.ico +APP1OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/swriter.obj +APP1STDLIBS = $(SHELL32LIB) +APP1PRODUCTDEF+=-DRES_APP_NAME=$(APP1TARGET) + +APP2TARGET=scalc +APP2DEPN=verinfo.rc +APP2VERINFO=verinfo.rc +APP2NOSAL=TRUE +APP2LINKRES=$(MISC)$/$(TARGET)2.res +APP2ICON=$(SOLARRESDIR)$/icons/ooo3_calc_app.ico +APP2OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/scalc.obj +APP2STDLIBS = $(SHELL32LIB) +APP2PRODUCTDEF+=-DRES_APP_NAME=$(APP2TARGET) + +APP3TARGET=sdraw +APP3DEPN=verinfo.rc +APP3VERINFO=verinfo.rc +APP3NOSAL=TRUE +APP3LINKRES=$(MISC)$/$(TARGET)3.res +APP3ICON=$(SOLARRESDIR)$/icons/ooo3_draw_app.ico +APP3OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/sdraw.obj +APP3STDLIBS = $(SHELL32LIB) +APP3PRODUCTDEF+=-DRES_APP_NAME=$(APP3TARGET) + +APP4TARGET=simpress +APP4DEPN=verinfo.rc +APP4VERINFO=verinfo.rc +APP4NOSAL=TRUE +APP4LINKRES=$(MISC)$/$(TARGET)4.res +APP4ICON=$(SOLARRESDIR)$/icons/ooo3_impress_app.ico +APP4OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/simpress.obj +APP4STDLIBS = $(SHELL32LIB) +APP4PRODUCTDEF+=-DRES_APP_NAME=$(APP4TARGET) + +APP5TARGET=smath +APP5DEPN=verinfo.rc +APP5VERINFO=verinfo.rc +APP5NOSAL=TRUE +APP5LINKRES=$(MISC)$/$(TARGET)5.res +APP5ICON=$(SOLARRESDIR)$/icons/ooo3_math_app.ico +APP5OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/smath.obj +APP5STDLIBS = $(SHELL32LIB) +APP5PRODUCTDEF+=-DRES_APP_NAME=$(APP5TARGET) + +APP6TARGET=sbase +APP6DEPN=verinfo.rc +APP6VERINFO=verinfo.rc +APP6NOSAL=TRUE +APP6LINKRES=$(MISC)$/$(TARGET)6.res +APP6ICON=$(SOLARRESDIR)$/icons/ooo3_base_app.ico +APP6OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/sbase.obj +APP6STDLIBS = $(SHELL32LIB) +APP6PRODUCTDEF+=-DRES_APP_NAME=$(APP6TARGET) + +APP7TARGET=sweb +APP7DEPN=verinfo.rc +APP7VERINFO=verinfo.rc +APP7NOSAL=TRUE +APP7LINKRES=$(MISC)$/$(TARGET)7.res +APP7ICON=$(SOLARRESDIR)$/icons/ooo3_writer_app.ico +APP7OBJS = \ + $(OBJ)$/launcher.obj\ + $(OBJ)$/sweb.obj +APP7STDLIBS = $(SHELL32LIB) +APP7PRODUCTDEF+=-DRES_APP_NAME=$(APP7TARGET) + +# --- Targets ------------------------------------------------------ + + +.INCLUDE : target.mk + diff --git a/desktop/win32/source/applauncher/ooo/verinfo.rc b/desktop/win32/source/applauncher/ooo/verinfo.rc new file mode 100755 index 000000000000..61e9147a4ab6 --- /dev/null +++ b/desktop/win32/source/applauncher/ooo/verinfo.rc @@ -0,0 +1,71 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + *************************************************************************/ + +#define VER_FIRSTYEAR 2009 + +#include <windows.h> +#include "version.hrc" + +// ----------------------------------------------------------------------- +// version information +// ----------------------------------------------------------------------- + +VS_VERSION_INFO versioninfo + fileversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT + productversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT + fileflagsmask 0x3F + fileflags +#if defined(DEBUG) + VS_FF_DEBUG | +#endif +#ifdef VER_PREL + VS_FF_PRERELEASE | +#endif + 0 + fileos VOS_NT_WINDOWS32 + filetype VFT_APP + { + block "StringFileInfo" + { + block "040904E4" + { + // International StringTable + value "CompanyName", "The Document Foundation\0" + value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0" + value "FileVersion", PPS(VER_LEVEL) "\0" + value "ProductVersion", PPS(VER_LEVEL) "\0" + value "OriginalFilename", PPS(RES_APP_NAME) ".exe\0" + value "InternalName", PPS(RES_APP_NAME) "\0" + value "LegalCopyright", S_CRIGHT " Oracle and/or its affiliates. All rights reserved.\0" + } + } + + block "VarFileInfo" + { + value "Translation", 0x0409, 1252 + } + } diff --git a/desktop/win32/source/applauncher/sbase.cxx b/desktop/win32/source/applauncher/sbase.cxx new file mode 100644 index 000000000000..9a1f31d3dce0 --- /dev/null +++ b/desktop/win32/source/applauncher/sbase.cxx @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#include "launcher.hxx" + +_TCHAR APPLICATION_SWITCH[] = _T( "-base" ); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/applauncher/scalc.cxx b/desktop/win32/source/applauncher/scalc.cxx new file mode 100644 index 000000000000..ceca63e14450 --- /dev/null +++ b/desktop/win32/source/applauncher/scalc.cxx @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#include "launcher.hxx" + +_TCHAR APPLICATION_SWITCH[] = _T( "-calc" ); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/applauncher/sdraw.cxx b/desktop/win32/source/applauncher/sdraw.cxx new file mode 100644 index 000000000000..034a7c4f949c --- /dev/null +++ b/desktop/win32/source/applauncher/sdraw.cxx @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#include "launcher.hxx" + +_TCHAR APPLICATION_SWITCH[] = _T( "-draw" ); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/applauncher/simpress.cxx b/desktop/win32/source/applauncher/simpress.cxx new file mode 100644 index 000000000000..cd01d01b346d --- /dev/null +++ b/desktop/win32/source/applauncher/simpress.cxx @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#include "launcher.hxx" + +_TCHAR APPLICATION_SWITCH[] = _T( "-impress" ); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/applauncher/smath.cxx b/desktop/win32/source/applauncher/smath.cxx new file mode 100644 index 000000000000..3e670cd8e692 --- /dev/null +++ b/desktop/win32/source/applauncher/smath.cxx @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#include "launcher.hxx" + +_TCHAR APPLICATION_SWITCH[] = _T( "-math" ); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/applauncher/sweb.cxx b/desktop/win32/source/applauncher/sweb.cxx new file mode 100644 index 000000000000..1c2fd8eabd6c --- /dev/null +++ b/desktop/win32/source/applauncher/sweb.cxx @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#include "launcher.hxx" + +_TCHAR APPLICATION_SWITCH[] = _T( "-web" ); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/applauncher/swriter.cxx b/desktop/win32/source/applauncher/swriter.cxx new file mode 100644 index 000000000000..1909cb97cded --- /dev/null +++ b/desktop/win32/source/applauncher/swriter.cxx @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#include "launcher.hxx" + +_TCHAR APPLICATION_SWITCH[] = _T( "-writer" ); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/applauncher/verinfo.rc b/desktop/win32/source/applauncher/verinfo.rc new file mode 100755 index 000000000000..afb58f3a377c --- /dev/null +++ b/desktop/win32/source/applauncher/verinfo.rc @@ -0,0 +1,76 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + *************************************************************************/ + +#define VER_FIRSTYEAR 2009 + +#include <windows.h> +#include "version_so.hrc" + +// ----------------------------------------------------------------------- +// version information +// ----------------------------------------------------------------------- + +VS_VERSION_INFO versioninfo +#ifndef SUBVERSION + fileversion VERSION, 0, VERVARIANT, VER_COUNT + productversion VERSION, 0, VERVARIANT, VER_COUNT +#else + fileversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT + productversion VERSION, SUBVERSION, VERVARIANT, VER_COUNT +#endif + fileflagsmask 0x3F + fileflags +#if defined(DEBUG) + VS_FF_DEBUG | +#endif +#ifdef VER_PREL + VS_FF_PRERELEASE | +#endif + 0 + fileos VOS_NT_WINDOWS32 + filetype VFT_APP + { + block "StringFileInfo" + { + block "040904E4" + { + // International StringTable + value "CompanyName", "The Document Foundation\0" + value "FileDescription", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\0" + value "FileVersion", PPS(VER_LEVEL) "\0" + value "ProductVersion", PPS(VER_LEVEL) "\0" + value "OriginalFilename", PPS(RES_APP_NAME) ".exe\0" + value "InternalName", PPS(RES_APP_NAME) "\0" + value "LegalCopyright", S_CRIGHT " Oracle and/or its affiliates. All rights reserved.\0" + } + } + + block "VarFileInfo" + { + value "Translation", 0x0409, 1252 + } + } diff --git a/desktop/win32/source/extendloaderenvironment.cxx b/desktop/win32/source/extendloaderenvironment.cxx new file mode 100644 index 000000000000..ee9de7f6099f --- /dev/null +++ b/desktop/win32/source/extendloaderenvironment.cxx @@ -0,0 +1,185 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_desktop.hxx" +#include "sal/config.h" + +#include <cstddef> + +#define WIN32_LEAN_AND_MEAN +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#include <shlwapi.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include "tools/pathutils.hxx" + +#include "extendloaderenvironment.hxx" + +namespace { + +void fail() { + LPWSTR buf = NULL; + FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, + GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL); + MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR); + LocalFree(buf); + TerminateProcess(GetCurrentProcess(), 255); +} + +bool contains(WCHAR const * paths, WCHAR const * path, WCHAR const * pathEnd) { + WCHAR const * q = path; + for (WCHAR const * p = paths;; ++p) { + WCHAR c = *p; + switch (c) { + case L'\0': + return q == pathEnd; + case L';': + if (q == pathEnd) { + return true; + } + q = path; + break; + default: + if (q != NULL) { + if (q != pathEnd && *q == c) { + ++q; + } else { + q = NULL; + } + } + break; + } + } +} + +} + +namespace desktop_win32 { + +void extendLoaderEnvironment(WCHAR * binPath, WCHAR * iniDirectory) { + if (!GetModuleFileNameW(NULL, iniDirectory, MAX_PATH)) { + fail(); + } + WCHAR * iniDirEnd = tools::filename(iniDirectory); + WCHAR name[MAX_PATH + MY_LENGTH(L".bin")]; + // hopefully std::size_t is large enough to not overflow + WCHAR * nameEnd = name; + for (WCHAR * p = iniDirEnd; *p != L'\0'; ++p) { + *nameEnd++ = *p; + } + if (!(nameEnd - name >= 4 && nameEnd[-4] == L'.' && + (nameEnd[-3] == L'E' || nameEnd[-3] == L'e') && + (nameEnd[-2] == L'X' || nameEnd[-2] == L'x') && + (nameEnd[-1] == L'E' || nameEnd[-1] == L'e'))) + { + *nameEnd = L'.'; + nameEnd += 4; + } + nameEnd[-3] = 'b'; + nameEnd[-2] = 'i'; + nameEnd[-1] = 'n'; + tools::buildPath(binPath, iniDirectory, iniDirEnd, name, nameEnd - name); + *iniDirEnd = L'\0'; + WCHAR path[MAX_PATH]; + WCHAR * pathEnd = tools::buildPath( + path, iniDirectory, iniDirEnd, MY_STRING(L"..\\basis-link")); + if (pathEnd == NULL) { + fail(); + } + std::size_t const maxEnv = 32767; + WCHAR pad[2 * MAX_PATH + maxEnv]; + // hopefully std::size_t is large enough to not overflow + WCHAR * padEnd = NULL; + WCHAR env[maxEnv]; + DWORD n = GetEnvironmentVariableW(L"PATH", env, maxEnv); + if (n >= maxEnv || n == 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND) { + fail(); + } + env[n] = L'\0'; + bool exclude1; + pathEnd = tools::resolveLink(path); + if (pathEnd == NULL) { + if (GetLastError() != ERROR_FILE_NOT_FOUND) { + fail(); + } + // This path is only taken by testtool.exe in basis program directory; + // its PATH needs to include the brand program directory: + pathEnd = tools::buildPath( + path, iniDirectory, iniDirEnd, MY_STRING(L"..")); + if (pathEnd == NULL) { + fail(); + } + padEnd = tools::buildPath( + pad, path, pathEnd, MY_STRING(L"\\..\\program")); + if (padEnd == NULL) { + fail(); + } + exclude1 = contains(env, pad, padEnd); + } else { + exclude1 = true; + } + WCHAR * pad2 = exclude1 ? pad : padEnd + 1; + pathEnd = tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")); + if (pathEnd == NULL) { + fail(); + } + pathEnd = tools::resolveLink(path); + if (pathEnd == NULL) { + fail(); + } + padEnd = tools::buildPath(pad2, path, pathEnd, MY_STRING(L"\\bin")); + if (padEnd == NULL) { + fail(); + } + bool exclude2 = contains(env, pad2, padEnd); + if (!(exclude1 && exclude2)) { + if (!(exclude1 || exclude2)) { + pad2[-1] = L';'; + } + WCHAR * p = exclude2 ? pad2 - 1 : padEnd; + if (n != 0) { + *p++ = L';'; + } + for (DWORD i = 0; i <= n; ++i) { + *p++ = env[i]; + } + if (!SetEnvironmentVariableW(L"PATH", pad)) { + fail(); + } + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/extendloaderenvironment.hxx b/desktop/win32/source/extendloaderenvironment.hxx new file mode 100644 index 000000000000..ace91b1a913d --- /dev/null +++ b/desktop/win32/source/extendloaderenvironment.hxx @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_DESKTOP_WIN32_SOURCE_EXTENDLOADERENVIRONMENT_HXX +#define INCLUDED_DESKTOP_WIN32_SOURCE_EXTENDLOADERENVIRONMENT_HXX + +#include "sal/config.h" + +#include <cstddef> + +#include <tchar.h> + +#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1) +#define MY_STRING(s) (s), MY_LENGTH(s) + +namespace desktop_win32 { + +inline WCHAR * commandLineAppend( + WCHAR * buffer, WCHAR const * text, std::size_t length) +{ + wcsncpy(buffer, text, length + 1); // trailing null + return buffer + length; +} + +inline WCHAR * commandLineAppend(WCHAR * buffer, WCHAR const * text) { + return commandLineAppend(buffer, text, wcslen(text)); +} + +inline WCHAR * commandLineAppendEncoded(WCHAR * buffer, WCHAR const * text) { + std::size_t n = 0; + for (;;) { + WCHAR c = *text++; + if (c == L'\0') { + break; + } else if (c == L'$') { + buffer = commandLineAppend(buffer, MY_STRING(L"\\$")); + n = 0; + } else if (c == L'\\') { + buffer = commandLineAppend(buffer, MY_STRING(L"\\\\")); + n += 2; + } else { + *buffer++ = c; + n = 0; + } + } + // The command line will continue with a double quote, so double any + // preceding backslashes as required by Windows: + for (std::size_t i = 0; i < n; ++i) { + *buffer++ = L'\\'; + } + *buffer = L'\0'; + return buffer; +} + +// Set the PATH environment variable in the current (loader) process, so that a +// following CreateProcess has the necessary environment: +// @param binPath +// Must point to an array of size at least MAX_PATH. Is filled with the null +// terminated full path to the "bin" file corresponding to the current +// executable. +// @param iniDirectory +// Must point to an array of size at least MAX_PATH. Is filled with the null +// terminated full directory path (ending in "\") to the "ini" file +// corresponding to the current executable. +void extendLoaderEnvironment(WCHAR * binPath, WCHAR * iniDirectory); + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/guiloader/genericloader.cxx b/desktop/win32/source/guiloader/genericloader.cxx new file mode 100644 index 000000000000..1d2075a65bc8 --- /dev/null +++ b/desktop/win32/source/guiloader/genericloader.cxx @@ -0,0 +1,178 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" +#define UNICODE +#define _UNICODE + +#define WIN32_LEAN_AND_MEAN +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#include <shellapi.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <tchar.h> + +#include <malloc.h> +#include <string.h> +#include <stdlib.h> +#include <systools/win32/uwinapi.h> + +#include "tools/pathutils.hxx" +#include "../extendloaderenvironment.hxx" + +//--------------------------------------------------------------------------- + +static int GenericMain() +{ + TCHAR szTargetFileName[MAX_PATH]; + TCHAR szIniDirectory[MAX_PATH]; + STARTUPINFO aStartupInfo; + + desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory); + + ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) ); + aStartupInfo.cb = sizeof(aStartupInfo); + + GetStartupInfo( &aStartupInfo ); + + DWORD dwExitCode = (DWORD)-1; + + PROCESS_INFORMATION aProcessInfo; + + size_t iniDirLen = wcslen(szIniDirectory); + WCHAR cwd[MAX_PATH]; + DWORD cwdLen = GetCurrentDirectoryW(MAX_PATH, cwd); + if (cwdLen >= MAX_PATH) { + cwdLen = 0; + } + WCHAR redirect[MAX_PATH]; + DWORD dummy; + bool hasRedirect = + tools::buildPath( + redirect, szIniDirectory, szIniDirectory + iniDirLen, + MY_STRING(L"redirect.ini")) != NULL && + (GetBinaryType(redirect, &dummy) || // cheaper check for file existence? + GetLastError() != ERROR_FILE_NOT_FOUND); + LPTSTR cl1 = GetCommandLine(); + WCHAR * cl2 = new WCHAR[ + wcslen(cl1) + + (hasRedirect + ? (MY_LENGTH(L" \"-env:INIFILENAME=vnd.sun.star.pathname:") + + iniDirLen + MY_LENGTH(L"redirect.ini\"")) + : 0) + + MY_LENGTH(L" \"-env:OOO_CWD=2") + 4 * cwdLen + MY_LENGTH(L"\"") + 1]; + // 4 * cwdLen: each char preceded by backslash, each trailing backslash + // doubled + WCHAR * p = desktop_win32::commandLineAppend(cl2, cl1); + if (hasRedirect) { + p = desktop_win32::commandLineAppend( + p, MY_STRING(L" \"-env:INIFILENAME=vnd.sun.star.pathname:")); + p = desktop_win32::commandLineAppend(p, szIniDirectory); + p = desktop_win32::commandLineAppend(p, MY_STRING(L"redirect.ini\"")); + } + p = desktop_win32::commandLineAppend(p, MY_STRING(L" \"-env:OOO_CWD=")); + if (cwdLen == 0) { + p = desktop_win32::commandLineAppend(p, MY_STRING(L"0")); + } else { + p = desktop_win32::commandLineAppend(p, MY_STRING(L"2")); + p = desktop_win32::commandLineAppendEncoded(p, cwd); + } + desktop_win32::commandLineAppend(p, MY_STRING(L"\"")); + + BOOL fSuccess = CreateProcess( + szTargetFileName, + cl2, + NULL, + NULL, + TRUE, + 0, + NULL, + szIniDirectory, + &aStartupInfo, + &aProcessInfo ); + + delete[] cl2; + + if ( fSuccess ) + { + DWORD dwWaitResult; + + do + { + // On Windows XP it seems as the desktop calls WaitForInputIdle after "OpenWidth" so we have to do so + // as if we where processing any messages + + dwWaitResult = MsgWaitForMultipleObjects( 1, &aProcessInfo.hProcess, FALSE, INFINITE, QS_ALLEVENTS ); + + if ( WAIT_OBJECT_0 + 1 == dwWaitResult ) + { + MSG msg; + + PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ); + } + } while ( WAIT_OBJECT_0 + 1 == dwWaitResult ); + + dwExitCode = 0; + GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode ); + + CloseHandle( aProcessInfo.hProcess ); + CloseHandle( aProcessInfo.hThread ); + } + + return dwExitCode; +} + +//--------------------------------------------------------------------------- + +#ifdef __MINGW32__ +int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) +#else +int WINAPI _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int ) +#endif +{ + return GenericMain(); +} + +//--------------------------------------------------------------------------- + +#ifdef __MINGW32__ +int __cdecl main() +#else +int __cdecl _tmain() +#endif +{ + return GenericMain(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/guiloader/makefile.mk b/desktop/win32/source/guiloader/makefile.mk new file mode 100755 index 000000000000..7912471fba13 --- /dev/null +++ b/desktop/win32/source/guiloader/makefile.mk @@ -0,0 +1,66 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=desktop +TARGET=guiloader +LIBTARGET=NO +TARGETTYPE=GUI +UWINAPILIB= + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +APP1TARGET=guiloader +APP1NOSAL=TRUE +APP1ICON=$(SOLARRESDIR)$/icons/ooo-main-app.ico +APP1OBJS=\ + $(OBJ)$/extendloaderenvironment.obj \ + $(OBJ)$/genericloader.obj \ + $(SOLARLIBDIR)$/pathutils-obj.obj +STDLIB1=$(SHLWAPILIB) + +.IF "$(LINK_SO)"=="TRUE" +APP2TARGET=so$/guiloader +APP2NOSAL=TRUE +APP2ICON=$(SOLARRESDIR)$/icons/so9_main_app.ico +APP2OBJS=\ + $(OBJ)$/extendloaderenvironment.obj \ + $(OBJ)$/genericloader.obj \ + $(SOLARLIBDIR)$/pathutils-obj.obj +STDLIB2=$(SHLWAPILIB) +.ENDIF # "$(LINK_SO)"=="TRUE" + +# --- Targets ------------------------------------------------------ + + +.INCLUDE : target.mk + diff --git a/desktop/win32/source/guistdio/guistdio.cxx b/desktop/win32/source/guistdio/guistdio.cxx new file mode 100644 index 000000000000..1c12089818f0 --- /dev/null +++ b/desktop/win32/source/guistdio/guistdio.cxx @@ -0,0 +1,33 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_desktop.hxx" + +#include "guistdio.inc" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/guistdio/guistdio.inc b/desktop/win32/source/guistdio/guistdio.inc new file mode 100755 index 000000000000..05d462d23197 --- /dev/null +++ b/desktop/win32/source/guistdio/guistdio.inc @@ -0,0 +1,454 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#define UNICODE +#define WIN32_LEAN_AND_MEAN +#ifdef _MSC_VER +#pragma warning(push,1) // disable warnings within system headers +#endif +#include <windows.h> +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#define _UNICODE +#include <tchar.h> + +#include <string.h> +#include <stdlib.h> +#include <systools/win32/uwinapi.h> + +#include <stdio.h> +#include <sal/macros.h> + +#ifdef UNOPKG + +DWORD passOutputToConsole(HANDLE readPipe, HANDLE console) +{ + BYTE aBuffer[1024]; + DWORD dwRead = 0; + HANDLE hReadPipe = readPipe; + BOOL fSuccess; + DWORD dwWritten; + + //Indicates that we read an odd number of bytes. That is, we only read half of the last + //wchar_t + bool bIncompleteWchar = false; + //fprintf, fwprintf will both send char data without the terminating zero. + //fwprintf converts the unicode string first. + //We expect here to receive unicode without the terminating zero. + //unopkg and the extension manager code MUST + //use dp_misc::writeConsole instead of using fprintf, etc. + + DWORD dwToRead = sizeof(aBuffer); + BYTE * pBuffer = aBuffer; + while ( ReadFile( hReadPipe, pBuffer, dwToRead, &dwRead, NULL ) ) + { + //If the previous ReadFile call read an odd number of bytes, then the last one was + //put at the front of the buffer. We increase the number of read bytes by one to reflect + //that one byte. + if (bIncompleteWchar) + dwRead++; + //We must make sure that only complete wchar_t|s are written. WriteConsolse takes + //the number of wchar_t|s as argument. ReadFile, however, reads bytes. + bIncompleteWchar = dwRead % 2 ? true : false; + if (bIncompleteWchar) + { + //To test this case, give aBuffer a small odd size, e.g. aBuffer[3] + //The last byte, which is the incomplete wchar_t (half of it), will not be written. + fSuccess = WriteConsoleW( console, aBuffer, + (dwRead - 1) / 2, &dwWritten, NULL ); + + //Move the last byte to the front of the buffer, so that it is the start of the + //next string + aBuffer[0] = aBuffer[dwRead - 1]; + + //Make sure that ReadFile does not overwrite the first byte the next time + dwToRead = sizeof(aBuffer) - 1; + pBuffer = aBuffer + 1; + + } + else + { //We have read an even number of bytes. Therefore, we do not put the last incomplete + //wchar_t at the front of the buffer. We will use the complete buffer the next time + //when ReadFile is called. + dwToRead = sizeof(aBuffer); + pBuffer = aBuffer; + fSuccess = WriteConsoleW( console, + aBuffer, dwRead / 2, &dwWritten, NULL ); + } + } + + return 0; +} + +#endif + +#ifdef UNOPKG +DWORD WINAPI OutputThread( LPVOID pParam ) +{ + return passOutputToConsole((HANDLE)pParam, GetStdHandle( STD_OUTPUT_HANDLE )); +} + +#else +DWORD WINAPI OutputThread( LPVOID pParam ) +{ + BYTE aBuffer[256]; + DWORD dwRead = 0; + HANDLE hReadPipe = (HANDLE)pParam; + while ( ReadFile( hReadPipe, &aBuffer, sizeof(aBuffer), &dwRead, NULL ) ) + { + BOOL fSuccess; + DWORD dwWritten; + + fSuccess = WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), aBuffer, dwRead, &dwWritten, NULL ); + } + + return 0; +} +#endif +//--------------------------------------------------------------------------- +// Thread that reads from child process standard error pipe +//--------------------------------------------------------------------------- + +#ifdef UNOPKG +DWORD WINAPI ErrorThread( LPVOID pParam ) +{ + return passOutputToConsole((HANDLE)pParam, GetStdHandle( STD_ERROR_HANDLE )); +} + +#else +DWORD WINAPI ErrorThread( LPVOID pParam ) +{ + BYTE aBuffer[256]; + DWORD dwRead = 0; + HANDLE hReadPipe = (HANDLE)pParam; + + while ( ReadFile( hReadPipe, &aBuffer, sizeof(aBuffer), &dwRead, NULL ) ) + { + BOOL fSuccess; + DWORD dwWritten; + + fSuccess = WriteFile( GetStdHandle( STD_ERROR_HANDLE ), aBuffer, dwRead, &dwWritten, NULL ); + } + + return 0; +} +#endif +//--------------------------------------------------------------------------- +// Thread that writes to child process standard input pipe +//--------------------------------------------------------------------------- +#ifdef UNOPKG + +DWORD WINAPI InputThread( LPVOID pParam ) +{ + DWORD dwRead = 0; + HANDLE hWritePipe = (HANDLE)pParam; + + //We need to read in the complete input until we encounter a new line before + //converting to Unicode. This is necessary because the input string can use + //characters of one, two, and more bytes. If the last character is not + //complete, then it will not be converted properly. + + //Find out how a new line (0xd 0xa) looks like with the used code page. + //Characters may have one or multiple bytes and different byte ordering + //can be used (little and big endian); + int cNewLine = WideCharToMultiByte( + GetConsoleCP(), 0, L"\r\n", 2, NULL, 0, NULL, NULL); + char * mbBuff = new char[cNewLine]; + WideCharToMultiByte( + GetConsoleCP(), 0, L"\r\n", 2, mbBuff, cNewLine, NULL, NULL); + + const size_t dwBufferSize = 256; + char* readBuf = (char*) malloc(dwBufferSize); + int readAll = 0; + size_t curBufSize = dwBufferSize; + + while ( ReadFile( GetStdHandle( STD_INPUT_HANDLE ), + readBuf + readAll, + curBufSize - readAll, &dwRead, NULL ) ) + { + readAll += dwRead; + int lastBufSize = curBufSize; + //Grow the buffer if necessary + if (readAll > curBufSize * 0.7) + { + curBufSize *= 2; + readBuf = (char *) realloc(readBuf, curBufSize); + } + + //If the buffer was filled completely then + //there could be more input coming. But if we read from the console + //and the console input fits exactly in the buffer, then the next + //ReadFile would block until the users presses return, etc. + //Therefor we check if last character is a new line. + //To test this, set dwBufferSize to 4 and enter "no". This should produce + //4 bytes with most code pages. + if ( readAll == lastBufSize + && memcmp(readBuf + lastBufSize - cNewLine, mbBuff, cNewLine) != 0) + { + //The buffer was completely filled and the last byte(s) are no + //new line, so there is more to come. + continue; + } + //Obtain the size of the buffer for the converted string. + int sizeWBuf = MultiByteToWideChar( + GetConsoleCP(), MB_PRECOMPOSED, readBuf, readAll, NULL, 0); + + wchar_t * wideBuf = new wchar_t[sizeWBuf]; + + //Do the conversion. + MultiByteToWideChar( + GetConsoleCP(), MB_PRECOMPOSED, readBuf, readAll, wideBuf, sizeWBuf); + + BOOL fSuccess; + DWORD dwWritten; + fSuccess = WriteFile( hWritePipe, wideBuf, sizeWBuf * 2, &dwWritten, NULL ); + delete[] wideBuf; + readAll = 0; + } + delete[] mbBuff; + free(readBuf); + return 0; +} +#else +DWORD WINAPI InputThread( LPVOID pParam ) +{ + BYTE aBuffer[256]; + DWORD dwRead = 0; + HANDLE hWritePipe = (HANDLE)pParam; + + while ( ReadFile( GetStdHandle( STD_INPUT_HANDLE ), &aBuffer, sizeof(aBuffer), &dwRead, NULL ) ) + { + BOOL fSuccess; + DWORD dwWritten; + + fSuccess = WriteFile( hWritePipe, aBuffer, dwRead, &dwWritten, NULL ); + } + + return 0; +} +#endif + +//--------------------------------------------------------------------------- +// Thread that waits until child process reached input idle +//--------------------------------------------------------------------------- + +DWORD WINAPI WaitForUIThread( LPVOID pParam ) +{ + HANDLE hProcess = (HANDLE)pParam; + +#ifndef UNOPKG + if ( !_tgetenv( TEXT("UNOPKG") ) ) + WaitForInputIdle( hProcess, INFINITE ); +#endif + + return 0; +} + + +//--------------------------------------------------------------------------- +// Ctrl-Break handler that terminates the child process if Ctrl-C was pressed +//--------------------------------------------------------------------------- + +HANDLE hTargetProcess = INVALID_HANDLE_VALUE; + +BOOL WINAPI CtrlBreakHandler( + DWORD // control signal type +) +{ + TerminateProcess( hTargetProcess, 255 ); + return TRUE; +} + + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- + +#ifdef __MINGW32__ +int main( int, char ** ) +#else +int _tmain( int, _TCHAR ** ) +#endif +{ + TCHAR szTargetFileName[MAX_PATH] = TEXT(""); + STARTUPINFO aStartupInfo; + PROCESS_INFORMATION aProcessInfo; + + ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) ); + aStartupInfo.cb = sizeof(aStartupInfo); + aStartupInfo.dwFlags = STARTF_USESTDHANDLES; + + // Create an output pipe where the write end is inheritable + + HANDLE hOutputRead, hOutputWrite; + + if ( CreatePipe( &hOutputRead, &hOutputWrite, NULL, 0 ) ) + { + HANDLE hTemp; + + DuplicateHandle( GetCurrentProcess(), hOutputWrite, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS ); + CloseHandle( hOutputWrite ); + hOutputWrite = hTemp; + + aStartupInfo.hStdOutput = hOutputWrite; + } + + // Create an error pipe where the write end is inheritable + + HANDLE hErrorRead, hErrorWrite; + + if ( CreatePipe( &hErrorRead, &hErrorWrite, NULL, 0 ) ) + { + HANDLE hTemp; + + DuplicateHandle( GetCurrentProcess(), hErrorWrite, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS ); + CloseHandle( hErrorWrite ); + hErrorWrite = hTemp; + + aStartupInfo.hStdError = hErrorWrite; + } + + // Create an input pipe where the read end is inheritable + + HANDLE hInputRead, hInputWrite; + + if ( CreatePipe( &hInputRead, &hInputWrite, NULL, 0 ) ) + { + HANDLE hTemp; + + DuplicateHandle( GetCurrentProcess(), hInputRead, GetCurrentProcess(), &hTemp, 0, TRUE, DUPLICATE_SAME_ACCESS ); + CloseHandle( hInputRead ); + hInputRead = hTemp; + + aStartupInfo.hStdInput = hInputRead; + } + + // Get image path with same name but with .exe extension + + TCHAR szModuleFileName[MAX_PATH]; + + GetModuleFileName( NULL, szModuleFileName, MAX_PATH ); + _TCHAR *lpLastDot = _tcsrchr( szModuleFileName, '.' ); + if ( lpLastDot && 0 == _tcsicmp( lpLastDot, _T(".COM") ) ) + { + size_t len = lpLastDot - szModuleFileName; + _tcsncpy( szTargetFileName, szModuleFileName, len ); + _tcsncpy( szTargetFileName + len, _T(".EXE"), SAL_N_ELEMENTS(szTargetFileName) - len ); + } + + // Create process with same command line, environment and stdio handles which + // are directed to the created pipes + + BOOL fSuccess = CreateProcess( + szTargetFileName, + GetCommandLine(), + NULL, + NULL, + TRUE, + 0, + NULL, + NULL, + &aStartupInfo, + &aProcessInfo ); + + if ( fSuccess ) + { + // These pipe ends are inherited by the child process and no longer used + CloseHandle( hOutputWrite ); + CloseHandle( hErrorWrite ); + CloseHandle( hInputRead ); + + // Set the Ctrl-Break handler + hTargetProcess = aProcessInfo.hProcess; + SetConsoleCtrlHandler( CtrlBreakHandler, TRUE ); + + // Create threads that redirect remote pipe io to current process's console stdio + + DWORD dwOutputThreadId, dwErrorThreadId, dwInputThreadId; + + HANDLE hOutputThread = CreateThread( NULL, 0, OutputThread, (LPVOID)hOutputRead, 0, &dwOutputThreadId ); + HANDLE hErrorThread = CreateThread( NULL, 0, OutputThread, (LPVOID)hErrorRead, 0, &dwErrorThreadId ); + HANDLE hInputThread = CreateThread( NULL, 0, InputThread, (LPVOID)hInputWrite, 0, &dwInputThreadId ); + + // Create thread that wait until child process entered input idle + + DWORD dwWaitForUIThreadId; + HANDLE hWaitForUIThread = CreateThread( NULL, 0, WaitForUIThread, (LPVOID)aProcessInfo.hProcess, 0, &dwWaitForUIThreadId ); + + DWORD dwWaitResult; + HANDLE hObjects[] = + { + hTargetProcess, + hWaitForUIThread, + hOutputThread, + hErrorThread + }; + + #ifdef UNOPKG + dwWaitResult = WaitForMultipleObjects( SAL_N_ELEMENTS(hObjects), hObjects, TRUE, INFINITE ); + #else + bool bDetach = false; + int nOpenPipes = 2; + do + { + dwWaitResult = WaitForMultipleObjects( SAL_N_ELEMENTS(hObjects), hObjects, FALSE, INFINITE ); + + switch ( dwWaitResult ) + { + case WAIT_OBJECT_0: // The child process has terminated + case WAIT_OBJECT_0 + 1: // The child process entered input idle + bDetach = true; + break; + case WAIT_OBJECT_0 + 2: // The remote end of stdout pipe was closed + case WAIT_OBJECT_0 + 3: // The remote end of stderr pipe was closed + bDetach = --nOpenPipes <= 0; + break; + default: // Something went wrong + bDetach = true; + break; + } + } while( !bDetach ); + +#endif + + CloseHandle( hOutputThread ); + CloseHandle( hErrorThread ); + CloseHandle( hInputThread ); + CloseHandle( hWaitForUIThread ); + + DWORD dwExitCode = 0; + GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode ); + CloseHandle( aProcessInfo.hProcess ); + CloseHandle( aProcessInfo.hThread ); + + return dwExitCode; + } + + return -1; +} diff --git a/desktop/win32/source/guistdio/makefile.mk b/desktop/win32/source/guistdio/makefile.mk new file mode 100755 index 000000000000..660a48bcdca9 --- /dev/null +++ b/desktop/win32/source/guistdio/makefile.mk @@ -0,0 +1,58 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=desktop +TARGET=guistdio +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE +TARGETTYPE=CUI +UWINAPILIB= + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +CFLAGS+= $(LFS_CFLAGS) +CXXFLAGS+= $(LFS_CFLAGS) + +# --- Files -------------------------------------------------------- + +OBJFILES=$(APP1OBJS) $(APP2OBJS) + +APP1NOSAL=TRUE +APP1OBJS=$(OBJ)$/guistdio.obj +APP1TARGET=$(TARGET) + +APP2NOSAL=TRUE +APP2OBJS=$(OBJ)$/unopkgio.obj +APP2TARGET=unopkgio + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/desktop/win32/source/guistdio/unopkgio.cxx b/desktop/win32/source/guistdio/unopkgio.cxx new file mode 100644 index 000000000000..8790cedfe98f --- /dev/null +++ b/desktop/win32/source/guistdio/unopkgio.cxx @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_desktop.hxx" + +#define UNOPKG +#include "guistdio.inc" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/lwrapa.cxx b/desktop/win32/source/lwrapa.cxx new file mode 100644 index 000000000000..eba3059da517 --- /dev/null +++ b/desktop/win32/source/lwrapa.cxx @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" +#define LOCAL +#include "wrapper.h" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/lwrapw.cxx b/desktop/win32/source/lwrapw.cxx new file mode 100644 index 000000000000..90a8b5d88f55 --- /dev/null +++ b/desktop/win32/source/lwrapw.cxx @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" +#define LOCAL +#define UNICODE +#include "wrapper.h" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/main.h b/desktop/win32/source/main.h new file mode 100755 index 000000000000..9e3039da1884 --- /dev/null +++ b/desktop/win32/source/main.h @@ -0,0 +1,15 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +int MainA(); +int MainW(); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/makefile.mk b/desktop/win32/source/makefile.mk new file mode 100755 index 000000000000..564ba319eb56 --- /dev/null +++ b/desktop/win32/source/makefile.mk @@ -0,0 +1,63 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=desktop +TARGET=sowrap +LIBTARGET=NO +AUTOSEG=true + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +UWINAPILIB = + +# --- Files -------------------------------------------------------- + +OBJFILES = \ + $(OBJ)$/wrappera.obj \ + $(OBJ)$/wrapperw.obj \ + $(OBJ)$/lwrapa.obj \ + $(OBJ)$/lwrapw.obj \ + $(OBJ)$/rwrapa.obj \ + $(OBJ)$/rwrapw.obj \ + $(OBJ)$/sowrapper.obj \ + $(OBJ)$/extendloaderenvironment.obj \ + $(OBJ)$/unoinfo.obj + +APP1TARGET = unoinfo +APP1OBJS = $(OBJ)$/unoinfo.obj $(SOLARLIBDIR)$/pathutils-obj.obj +APP1STDLIBS = +APP1RPATH = BRAND + +# --- Targets ------------------------------------------------------ + + +.INCLUDE : target.mk + diff --git a/desktop/win32/source/officeloader/makefile.mk b/desktop/win32/source/officeloader/makefile.mk new file mode 100755 index 000000000000..5609dea25085 --- /dev/null +++ b/desktop/win32/source/officeloader/makefile.mk @@ -0,0 +1,45 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=desktop +TARGET=officeloader +LIBTARGET=NO + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +OBJFILES = \ + $(OBJ)$/officeloader.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/desktop/win32/source/officeloader/officeloader.cxx b/desktop/win32/source/officeloader/officeloader.cxx new file mode 100644 index 000000000000..7a08d7ee64c7 --- /dev/null +++ b/desktop/win32/source/officeloader/officeloader.cxx @@ -0,0 +1,430 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" +#define UNICODE +#define _UNICODE + +#include <cstddef> + +#define WIN32_LEAN_AND_MEAN +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#include <shellapi.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <tchar.h> + +#include <malloc.h> +#include <string.h> +#include <stdlib.h> +#include <systools/win32/uwinapi.h> + +#include "rtl/string.h" +#include <sal/macros.h> + +#include "../../../source/inc/exithelper.hxx" +#include "../extendloaderenvironment.hxx" + +#define PIPE_PREFIX TEXT("\\\\.\\pipe\\OSL_PIPE_") +#define PIPE_POSTFIX TEXT("_SingleOfficeIPC_") +#define PIPE_TERMINATION_SEQUENCE "InternalIPC::ProcessingDone" + +BOOL WINAPI ConvertSidToStringSid( PSID pSid, LPTSTR* StringSid ) +{ + PSID_IDENTIFIER_AUTHORITY psia; + DWORD dwSubAuthorities; + DWORD dwSidRev=SID_REVISION; + DWORD dwCounter; + DWORD dwSidSize; + + // Validate the binary SID. + + if(!IsValidSid(pSid)) return FALSE; + + // Get the identifier authority value from the SID. + + psia = GetSidIdentifierAuthority(pSid); + + // Get the number of subauthorities in the SID. + + dwSubAuthorities = *GetSidSubAuthorityCount(pSid); + + // Compute the buffer length. + // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL + + dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR); + + *StringSid = (LPTSTR)LocalAlloc( LMEM_FIXED, dwSidSize ); + + // Add 'S' prefix and revision number to the string. + + dwSidSize=wsprintf(*StringSid, TEXT("S-%lu-"), dwSidRev ); + + // Add a SID identifier authority to the string. + + if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) + { + dwSidSize+=wsprintf(*StringSid + lstrlen(*StringSid), + TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"), + (USHORT)psia->Value[0], + (USHORT)psia->Value[1], + (USHORT)psia->Value[2], + (USHORT)psia->Value[3], + (USHORT)psia->Value[4], + (USHORT)psia->Value[5]); + } + else + { + dwSidSize+=wsprintf(*StringSid + lstrlen(*StringSid), + TEXT("%lu"), + (ULONG)(psia->Value[5] ) + + (ULONG)(psia->Value[4] << 8) + + (ULONG)(psia->Value[3] << 16) + + (ULONG)(psia->Value[2] << 24) ); + } + + // Add SID subauthorities to the string. + for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++) + { + dwSidSize+=wsprintf(*StringSid + dwSidSize, TEXT("-%lu"), + *GetSidSubAuthority(pSid, dwCounter) ); + } + + return TRUE; +} + + +//--------------------------------------------------------------------------- + +static LPTSTR *GetCommandArgs( int *pArgc ) +{ +#ifdef UNICODE + return CommandLineToArgvW( GetCommandLineW(), pArgc ); +#else + *pArgc = __argc; + return __argv; +#endif +} + +//--------------------------------------------------------------------------- + +namespace { + +bool writeArgument(HANDLE pipe, char prefix, WCHAR const * argument) { + CHAR szBuffer[4096]; + int n = WideCharToMultiByte( + CP_UTF8, 0, argument, -1, szBuffer, sizeof (szBuffer), NULL, NULL); + char b[1 + 2 * ((sizeof szBuffer) - 1)]; // hopefully does not overflow + b[0] = prefix; + char * p = b + 1; + for (int i = 0; i < n - 1; ++i) { // cannot underflow (n >= 0) + char c = szBuffer[i]; + switch (c) { + case '\0': + *p++ = '\\'; + *p++ = '0'; + break; + case ',': + *p++ = '\\'; + *p++ = ','; + break; + case '\\': + *p++ = '\\'; + *p++ = '\\'; + break; + default: + *p++ = c; + break; + } + } + DWORD w; + return WriteFile(pipe, b, p - b, &w, NULL); +} + +} + +#ifdef __MINGW32__ +int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int ) +#else +int WINAPI _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int ) +#endif +{ + TCHAR szTargetFileName[MAX_PATH] = TEXT(""); + TCHAR szIniDirectory[MAX_PATH]; + TCHAR szPerfTuneIniFile[MAX_PATH] = TEXT(""); + STARTUPINFO aStartupInfo; + + desktop_win32::extendLoaderEnvironment(szTargetFileName, szIniDirectory); + + ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) ); + aStartupInfo.cb = sizeof(aStartupInfo); + + GetStartupInfo( &aStartupInfo ); + // Get image path with same name but with .bin extension + + TCHAR szModuleFileName[MAX_PATH]; + + GetModuleFileName( NULL, szModuleFileName, MAX_PATH ); + _TCHAR *lpLastSlash = _tcsrchr( szModuleFileName, '\\' ); + if ( lpLastSlash ) + { + size_t len = lpLastSlash - szModuleFileName + 1; + _tcsncpy( szPerfTuneIniFile, szModuleFileName, len ); + _tcsncpy( szPerfTuneIniFile + len, _T("perftune.ini"), SAL_N_ELEMENTS(szPerfTuneIniFile) - len ); + } + + // Create process with same command line, environment and stdio handles which + // are directed to the created pipes + + DWORD dwExitCode = (DWORD)-1; + + BOOL fSuccess = FALSE; + LPTSTR lpCommandLine = NULL; + int argc = 0; + LPTSTR * argv = NULL; + bool bFirst = true; + WCHAR cwd[MAX_PATH]; + DWORD cwdLen = GetCurrentDirectoryW(MAX_PATH, cwd); + if (cwdLen >= MAX_PATH) { + cwdLen = 0; + } + + do + { + TCHAR szKey[32]; + + GetPrivateProfileString( + TEXT("PerformanceTuning"), + TEXT("FastPipeCommunication"), + TEXT("0"), + szKey, + SAL_N_ELEMENTS(szKey), + szPerfTuneIniFile + ); + + if ( 0 == _tcscmp( szKey, TEXT("1") ) ) + { + HANDLE hProcessToken; + + if ( OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hProcessToken ) ) + { + TCHAR szPipeName[4096]; + + + DWORD dwTokenLength = 0; + + + fSuccess = GetTokenInformation( hProcessToken, TokenUser, NULL, dwTokenLength, &dwTokenLength ); + + PVOID pTokenInfo = _alloca(dwTokenLength); + fSuccess = GetTokenInformation( hProcessToken, TokenUser, pTokenInfo, dwTokenLength, &dwTokenLength ); + CloseHandle( hProcessToken ); + + PSID pSid = ((PTOKEN_USER)pTokenInfo)->User.Sid; + LPTSTR szUserIdent = NULL; + TCHAR szSUPD[11] = TEXT("0"); + + fSuccess = ConvertSidToStringSid( pSid, &szUserIdent ); + + _tcsncpy( szPipeName, PIPE_PREFIX, SAL_N_ELEMENTS(szPipeName) ); + _tcsncat( szPipeName, szUserIdent, SAL_N_ELEMENTS(szPipeName) - _tcslen(szPipeName) - 1 ); + _tcsncat( szPipeName, PIPE_POSTFIX, SAL_N_ELEMENTS(szPipeName) - _tcslen(szPipeName) - 1 ); + _tcsncat( szPipeName, _ultot( SUPD, szSUPD, 10), SAL_N_ELEMENTS(szPipeName) - _tcslen(szPipeName) - 1 ); + + LocalFree( szUserIdent ); + + HANDLE hPipe = CreateFile( + szPipeName, + GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if ( INVALID_HANDLE_VALUE != hPipe ) + { + DWORD dwBytesWritten; + int argc = 0; + LPWSTR *argv = CommandLineToArgvW( GetCommandLine(), &argc ); + + fSuccess = WriteFile( hPipe, RTL_CONSTASCII_STRINGPARAM("InternalIPC::Arguments"), &dwBytesWritten, NULL ); + if (fSuccess) { + if (cwdLen > 0) { + fSuccess = writeArgument(hPipe, '2', cwd); + } else { + fSuccess = WriteFile( + hPipe, RTL_CONSTASCII_STRINGPARAM("0"), + &dwBytesWritten, NULL); + } + } + for ( int argn = 1; fSuccess && argn < argc; argn++ ) + { + fSuccess = writeArgument(hPipe, ',', argv[argn]); + } + + if ( fSuccess ) + { + fSuccess = WriteFile( hPipe, "", 1, &dwBytesWritten, NULL ); + if ( fSuccess ) + { + DWORD dwBytesRead = 0; + char *pBuffer = (char *)_alloca( sizeof(PIPE_TERMINATION_SEQUENCE) ); + fSuccess = ReadFile( hPipe, pBuffer, sizeof(PIPE_TERMINATION_SEQUENCE) - 1, &dwBytesRead, NULL ); + if ( fSuccess ) + { + pBuffer[dwBytesRead] = 0; + if ( 0 != strcmp( PIPE_TERMINATION_SEQUENCE, pBuffer ) ) + fSuccess = FALSE; + } + } + } + + CloseHandle( hPipe ); + + return fSuccess ? 0 : -1; + } + + } + } + + if ( bFirst ) { + argv = GetCommandArgs(&argc); + std::size_t n = wcslen(argv[0]) + 2; + for (int i = 1; i < argc; ++i) { + n += wcslen(argv[i]) + 3; + } + n += MY_LENGTH(L" \"-env:OOO_CWD=2") + 4 * cwdLen + + MY_LENGTH(L"\"") + 1; + // 4 * cwdLen: each char preceded by backslash, each trailing + // backslash doubled + lpCommandLine = new WCHAR[n]; + } + WCHAR * p = desktop_win32::commandLineAppend( + lpCommandLine, MY_STRING(L"\"")); + p = desktop_win32::commandLineAppend(p, argv[0]); + for (int i = 1; i < argc; ++i) { + if (bFirst || ::desktop::ExitHelper::E_NORMAL_RESTART == dwExitCode || wcsncmp(argv[i], MY_STRING(L"-env:")) == 0) { + p = desktop_win32::commandLineAppend(p, MY_STRING(L"\" \"")); + p = desktop_win32::commandLineAppend(p, argv[i]); + } + } + + p = desktop_win32::commandLineAppend( + p, MY_STRING(L"\" \"-env:OOO_CWD=")); + if (cwdLen == 0) { + p = desktop_win32::commandLineAppend(p, MY_STRING(L"0")); + } else { + p = desktop_win32::commandLineAppend(p, MY_STRING(L"2")); + p = desktop_win32::commandLineAppendEncoded(p, cwd); + } + desktop_win32::commandLineAppend(p, MY_STRING(L"\"")); + bFirst = false; + + TCHAR szParentProcessId[64]; // This is more than large enough for a 128 bit decimal value + BOOL bHeadlessMode( FALSE ); + + { + // Check command line arguments for "--headless" parameter. We only + // set the environment variable "ATTACHED_PARENT_PROCESSID" for the headless + // mode as self-destruction of the soffice.bin process can lead to + // certain side-effects (log-off can result in data-loss, ".lock" is not deleted. + // See 138244 for more information. + int argc; + LPTSTR *argv = GetCommandArgs( &argc ); + + if ( argc > 1 ) + { + int n; + + for ( n = 1; n < argc; n++ ) + { + if ( 0 == _tcsnicmp( argv[n], _T("-headless"), 9 ) || + 0 == _tcsnicmp( argv[n], _T("--headless"), 9 ) ) + { + bHeadlessMode = TRUE; + } + } + } + } + + if ( _ltot( (long)GetCurrentProcessId(),szParentProcessId, 10 ) && bHeadlessMode ) + SetEnvironmentVariable( TEXT("ATTACHED_PARENT_PROCESSID"), szParentProcessId ); + + PROCESS_INFORMATION aProcessInfo; + + fSuccess = CreateProcess( + szTargetFileName, + lpCommandLine, + NULL, + NULL, + TRUE, + 0, + NULL, + szIniDirectory, + &aStartupInfo, + &aProcessInfo ); + + if ( fSuccess ) + { + DWORD dwWaitResult; + + do + { + // On Windows XP it seems as the desktop calls WaitForInputIdle after "OpenWidth" so we have to do so + // as if we where processing any messages + + dwWaitResult = MsgWaitForMultipleObjects( 1, &aProcessInfo.hProcess, FALSE, INFINITE, QS_ALLEVENTS ); + + if ( WAIT_OBJECT_0 + 1 == dwWaitResult ) + { + MSG msg; + + PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ); + } + } while ( WAIT_OBJECT_0 + 1 == dwWaitResult ); + + dwExitCode = 0; + GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode ); + + CloseHandle( aProcessInfo.hProcess ); + CloseHandle( aProcessInfo.hThread ); + } + } while ( false ); + delete[] lpCommandLine; + + return fSuccess ? dwExitCode : -1; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/rebase/Resource.h b/desktop/win32/source/rebase/Resource.h new file mode 100755 index 000000000000..a8e23f2eba1d --- /dev/null +++ b/desktop/win32/source/rebase/Resource.h @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _RESOURCE_H +#define _RESOURCE_H + +#define IDS_APP_TITLE 10 +#define IDS_MSG_OPTIMIZED_FOR_CLIENT 11 +#define IDS_MSG_OPTIMIZED_FOR_SERVER 12 +#define IDS_MSG_NO_INSTALLATION_FOUND 13 + +#define IDI_REBASEGUI 99 + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/rebase/makefile.mk b/desktop/win32/source/rebase/makefile.mk new file mode 100755 index 000000000000..724ea0edf465 --- /dev/null +++ b/desktop/win32/source/rebase/makefile.mk @@ -0,0 +1,89 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=desktop +TARGET=rebasegui +LIBTARGET=NO +TARGETTYPE=GUI +UWINAPILIB= + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +OBJFILES = \ + $(OBJ)$/rebase.obj \ + $(OBJ)$/rebasegui.obj + +ULFFILES= rebasegui.ulf + +.IF "$(WITH_LANG)"!="" +ULFDIR:=$(COMMONMISC)$/$(TARGET) +.ELSE # "$(WITH_LANG)"!="" +ULFDIR:=. +.ENDIF # "$(WITH_LANG)"!="" + +RCFILES= $(RES)$/$(TARGET).rc + +# --- Targets ------------------------------------------------------ + +APP1NOSAL= TRUE +APP1TARGET= rebaseoo + +APP1STDLIBS= $(SHELL32LIB) $(SOLARLIBDIR)$/pathutils-obj.obj +.IF "$(COM)"=="GCC" + APP1STDLIBS+=$(PSDK_HOME)$/lib$/imagehlp.lib +.ELSE + APP1STDLIBS+=imagehlp.lib +.ENDIF + +APP1OBJS= $(OBJ)$/rebase.obj + +APP1RPATH= BRAND + +APP2NOSAL= TRUE +APP2TARGET= rebasegui +APP2STDLIBS= $(SHELL32LIB) $(SOLARLIBDIR)$/pathutils-obj.obj + +APP2OBJS= $(OBJ)$/rebasegui.obj + +APP2DEF= $(MISC)$/$(TARGET).def +APP2RPATH= BRAND + +APP2RES= $(RES)$/$(TARGET).res +APP2NOSVRES= $(RES)$/$(TARGET).res + +# --- setup -------------------------------------------------------------- + +.INCLUDE : target.mk + +$(RCFILES) : $(ULFDIR)$/rebasegui.ulf makefile.mk rcfooter.txt rcheader.txt rctmpl.txt + $(LNGCONVEX) -ulf $(ULFDIR)$/rebasegui.ulf -rc $(RCFILES) -rct rctmpl.txt -rch rcheader.txt -rcf rcfooter.txt diff --git a/desktop/win32/source/rebase/rcfooter.txt b/desktop/win32/source/rebase/rcfooter.txt new file mode 100755 index 000000000000..3237729437f5 --- /dev/null +++ b/desktop/win32/source/rebase/rcfooter.txt @@ -0,0 +1,2 @@ + +// The end diff --git a/desktop/win32/source/rebase/rcheader.txt b/desktop/win32/source/rebase/rcheader.txt new file mode 100755 index 000000000000..56afc5377920 --- /dev/null +++ b/desktop/win32/source/rebase/rcheader.txt @@ -0,0 +1,39 @@ +#if defined(_MSC_VER) && (_MSC_VER < 1500) +#include <winres.h> +#else +#define WINVER 0x0500 +#include <winresrc.h> +#define IDC_STATIC (-1) +#endif +#include "resource.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,1,1,0 + PRODUCTVERSION 1,1,1,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x9L +#else + FILEFLAGS 0x8L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + diff --git a/desktop/win32/source/rebase/rctmpl.txt b/desktop/win32/source/rebase/rctmpl.txt new file mode 100755 index 000000000000..97a2775e9b02 --- /dev/null +++ b/desktop/win32/source/rebase/rctmpl.txt @@ -0,0 +1,9 @@ +// String Table + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APP_TITLE %APP_TITLE% + IDS_MSG_OPTIMIZED_FOR_CLIENT %MSG_OPTIMIZED_FOR_CLIENT% + IDS_MSG_OPTIMIZED_FOR_SERVER %MSG_OPTIMIZED_FOR_SERVER% + IDS_MSG_NO_INSTALLATION_FOUND %MSG_NO_INSTALLATION_FOUND% +END diff --git a/desktop/win32/source/rebase/rebase.cxx b/desktop/win32/source/rebase/rebase.cxx new file mode 100644 index 000000000000..ba6c3937227a --- /dev/null +++ b/desktop/win32/source/rebase/rebase.cxx @@ -0,0 +1,191 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_desktop.hxx" +#define UNICODE +#define _UNICODE + +#define WIN32_LEAN_AND_MEAN +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#include <shellapi.h> +#include <imagehlp.h> +#include <wchar.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <time.h> +#include "sal/config.h" +#include <sal/macros.h> +#include "tools/pathutils.hxx" + +#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1) +#define MY_STRING(s) (s), MY_LENGTH(s) + +const int FORMAT_MESSAGE_SIZE = 4096; +const DWORD PE_Signature = 0x00004550; +const DWORD BASEVIRTUALADDRESS = 0x10000000; + +namespace +{ + +bool IsValidHandle( HANDLE handle ) +{ + return ((NULL != handle) && (INVALID_HANDLE_VALUE != handle)); +} + +void fail() +{ + LPWSTR buf = NULL; + FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, + GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL); + MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR); + LocalFree(buf); + TerminateProcess(GetCurrentProcess(), 255); +} + +bool rebaseImage( wchar_t* pszFilePath, ULONG nNewImageBase) +{ + ULONG ulOldImageSize; + ULONG_PTR lpOldImageBase; + ULONG ulNewImageSize; + ULONG_PTR lpNewImageBase = nNewImageBase; + ULONG ulDateTimeStamp = 0; + bool bResult(false); + + char cszFilePath[_MAX_PATH+1] = {0}; + int nResult = WideCharToMultiByte(CP_ACP, 0, pszFilePath, -1, cszFilePath, _MAX_PATH, NULL, NULL); + + if (nResult != 0) + { + BOOL bResult = ReBaseImage( + cszFilePath, + "", + TRUE, + FALSE, + FALSE, + 0, + &ulOldImageSize, + &lpOldImageBase, + &ulNewImageSize, + &lpNewImageBase, + ulDateTimeStamp ); + } + + return bResult; +} + +wchar_t* getBrandPath(wchar_t * path) +{ + DWORD n = GetModuleFileNameW(NULL, path, MAX_PATH); + if (n == 0 || n >= MAX_PATH) { + exit(EXIT_FAILURE); + } + return tools::filename(path); +} + +void rebaseImagesInFolder( wchar_t* pszFolder, DWORD nNewImageBase ) +{ + wchar_t szPattern[MAX_PATH]; + wchar_t *lpLastSlash = wcsrchr( pszFolder, '\\' ); + if ( lpLastSlash ) + { + size_t len = lpLastSlash - pszFolder + 1; + wcsncpy( szPattern, pszFolder, len ); + wcsncpy( szPattern + len, TEXT("*.dll"), SAL_N_ELEMENTS(szPattern) - len ); + } + + WIN32_FIND_DATA aFindFileData; + HANDLE hFind = FindFirstFile( szPattern, &aFindFileData ); + + if ( IsValidHandle(hFind) ) + { + BOOL fSuccess = false; + + do + { + wchar_t szLibFilePath[MAX_PATH]; + wchar_t *lpLastSlash = wcsrchr( pszFolder, '\\' ); + if ( lpLastSlash ) + { + size_t len = lpLastSlash - pszFolder + 1; + wcsncpy( szLibFilePath, pszFolder, len ); + wcsncpy( szLibFilePath + len, aFindFileData.cFileName, SAL_N_ELEMENTS(szLibFilePath) - len ); + } + + rebaseImage( szLibFilePath, nNewImageBase ); + fSuccess = FindNextFile( hFind, &aFindFileData ); + } + while ( fSuccess ); + + FindClose( hFind ); + } +} + +} + +extern "C" int APIENTRY WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) +{ + wchar_t path[MAX_PATH]; + + wchar_t * pathEnd = getBrandPath(path); + + if (tools::buildPath(path, path, pathEnd, MY_STRING(L"")) == NULL) + fail(); + rebaseImagesInFolder(path, BASEVIRTUALADDRESS); + + if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link")) == NULL) + fail(); + pathEnd = tools::resolveLink(path); + + if ( pathEnd == NULL ) + return 0; + + if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\program\\")) == NULL) + fail(); + rebaseImagesInFolder(path, BASEVIRTUALADDRESS); + + if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == NULL) + fail(); + pathEnd = tools::resolveLink(path); + + if ( pathEnd == NULL ) + return 0; + + if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\bin\\")) == NULL) + fail(); + rebaseImagesInFolder(path, BASEVIRTUALADDRESS); + + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/rebase/rebasegui.cxx b/desktop/win32/source/rebase/rebasegui.cxx new file mode 100644 index 000000000000..71b4f1246447 --- /dev/null +++ b/desktop/win32/source/rebase/rebasegui.cxx @@ -0,0 +1,200 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_desktop.hxx" + +#define UNICODE 1 +#define _UNICODE 1 + +#ifndef _WINDOWS_ +# define WIN32_LEAN_AND_MEAN +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +# include <windows.h> +# include <shellapi.h> +# include <wchar.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#endif + +#include "Resource.h" +#include <time.h> +#include "sal/config.h" +#include "tools/pathutils.hxx" + +const DWORD PE_Signature = 0x00004550; + +#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1) +#define MY_STRING(s) (s), MY_LENGTH(s) +#define MAX_STR_CAPTION 256 +#define MAX_TEXT_LENGTH 1024 + +static void failPath(wchar_t* pszAppTitle, wchar_t* pszMsg) +{ + MessageBoxW(NULL, pszMsg, pszAppTitle, MB_OK | MB_ICONERROR); + TerminateProcess(GetCurrentProcess(), 255); +} + +static void fail() +{ + LPWSTR buf = NULL; + FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, + GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL); + MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR); + LocalFree(buf); + TerminateProcess(GetCurrentProcess(), 255); +} + +static LPVOID getVirtualBaseAddress( wchar_t* pszFilePath ) +{ + HANDLE hFile; + HANDLE hFileMapping; + LPVOID lpFileBase = 0; + PIMAGE_DOS_HEADER lpDosHeader; + PIMAGE_NT_HEADERS lpNTHeader; + + hFile = CreateFile(pszFilePath, + GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, + 0); + + if ( hFile == INVALID_HANDLE_VALUE ) + { + return NULL; + } + + hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); + if ( hFileMapping == 0 ) + { + CloseHandle(hFile); + return NULL; + } + + lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0); + if ( lpFileBase == 0 ) + { + CloseHandle(hFileMapping); + CloseHandle(hFile); + return NULL; + } + + lpDosHeader = (PIMAGE_DOS_HEADER)lpFileBase; + if ( lpDosHeader->e_magic == IMAGE_DOS_SIGNATURE ) + { + lpNTHeader = (PIMAGE_NT_HEADERS)((char*)lpDosHeader + lpDosHeader->e_lfanew); + if (lpNTHeader->Signature == PE_Signature ) + lpFileBase = reinterpret_cast<LPVOID>( lpNTHeader->OptionalHeader.ImageBase ); + } + + UnmapViewOfFile(lpFileBase); + CloseHandle(hFileMapping); + CloseHandle(hFile); + + return lpFileBase; +} + +static bool checkImageVirtualBaseAddress(wchar_t* pszFilePath, LPVOID lpVBA) +{ + LPVOID lpImageVBA = getVirtualBaseAddress(pszFilePath); + if ( lpImageVBA == lpVBA ) + return true; + else + return false; +} + +static wchar_t* getBrandPath(wchar_t * pszPath) +{ + DWORD n = GetModuleFileNameW(NULL, pszPath, MAX_PATH); + if (n == 0 || n >= MAX_PATH) { + exit(EXIT_FAILURE); + } + return tools::filename(pszPath); +} + +extern "C" int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int ) +{ + wchar_t* pAppTitle = new wchar_t[ MAX_STR_CAPTION ]; + pAppTitle[0] = '\0'; + LoadString( hInst, IDS_APP_TITLE, pAppTitle, MAX_STR_CAPTION ); + + wchar_t* pTextServer = new wchar_t[ MAX_TEXT_LENGTH ]; + pTextServer[0] = '\0'; + LoadString( hInst, IDS_MSG_OPTIMIZED_FOR_SERVER, pTextServer, MAX_TEXT_LENGTH ); + + wchar_t* pTextClient = new wchar_t[ MAX_TEXT_LENGTH ]; + pTextClient[0] = '\0'; + LoadString( hInst, IDS_MSG_OPTIMIZED_FOR_CLIENT, pTextClient, MAX_TEXT_LENGTH ); + + wchar_t* pTextNoInstallation = new wchar_t[ MAX_TEXT_LENGTH ]; + pTextNoInstallation[0] = '\0'; + LoadString( hInst, IDS_MSG_NO_INSTALLATION_FOUND, pTextNoInstallation, MAX_TEXT_LENGTH ); + + LPVOID VBA = (void*)0x10000000; + wchar_t path[MAX_PATH]; + + wchar_t * pathEnd = getBrandPath(path); + + if (tools::buildPath(path, path, pathEnd, MY_STRING(L"libxml2.dll")) == NULL) + fail(); + bool bFast = checkImageVirtualBaseAddress(path, VBA); + + if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link")) == NULL) + fail(); + pathEnd = tools::resolveLink(path); + + if (pathEnd == NULL) + failPath(pAppTitle, pTextNoInstallation); + + if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\program\\vclmi.dll")) == NULL) + fail(); + bFast &= checkImageVirtualBaseAddress(path, VBA); + + if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == NULL) + fail(); + pathEnd = tools::resolveLink(path); + + if (pathEnd == NULL) + failPath(pAppTitle, pTextNoInstallation); + + if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\bin\\sal3.dll")) == NULL) + fail(); + bFast &= checkImageVirtualBaseAddress(path, VBA); + + const wchar_t* pOutput = pTextClient; + if (!bFast) + pOutput = pTextServer; + + MessageBoxW( NULL, pOutput, pAppTitle, MB_OK ); + + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/rebase/rebasegui.ulf b/desktop/win32/source/rebase/rebasegui.ulf new file mode 100755 index 000000000000..ee6b6e828ac1 --- /dev/null +++ b/desktop/win32/source/rebase/rebasegui.ulf @@ -0,0 +1,11 @@ +[%APP_TITLE%] +en-US = "Installation Status" + +[%MSG_OPTIMIZED_FOR_CLIENT%] +en-US = "Installation is optimized for clients." + +[%MSG_OPTIMIZED_FOR_SERVER%] +en-US = "Installation is optimized for servers." + +[%MSG_NO_INSTALLATION_FOUND%] +en-US = "Cannot find Office installation." diff --git a/desktop/win32/source/rwrapa.cxx b/desktop/win32/source/rwrapa.cxx new file mode 100644 index 000000000000..080cb4e4be05 --- /dev/null +++ b/desktop/win32/source/rwrapa.cxx @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" +#define REMOTE +#include "wrapper.h" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/rwrapw.cxx b/desktop/win32/source/rwrapw.cxx new file mode 100644 index 000000000000..15abc299a341 --- /dev/null +++ b/desktop/win32/source/rwrapw.cxx @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" +#define REMOTE +#define UNICODE +#include "wrapper.h" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/setup/Resource.h b/desktop/win32/source/setup/Resource.h new file mode 100644 index 000000000000..600056d0a8ee --- /dev/null +++ b/desktop/win32/source/setup/Resource.h @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _RESOURCE_H +#define _RESOURCE_H + +#define IDS_APP_TITLE 10 +#define IDS_APP_PROD_TITLE 11 +#define IDS_OUTOFMEM 12 +#define IDS_NOMSI 13 +#define IDS_USER_CANCELLED 14 +#define IDS_REQUIRES_ADMIN_PRIV 15 +#define IDS_FILE_NOT_FOUND 16 +#define IDS_INVALID_PARAM 17 +#define IDS_ALLOW_MSI_UPDATE 18 +#define IDS_USAGE 19 +#define IDS_ALREADY_RUNNING 20 +#define IDS_UNKNOWN_ERROR 21 +#define IDS_INVALID_PROFILE 22 +#define IDS_UNKNOWN_LANG 23 +#define IDS_SETUP_TO_OLD 24 +#define IDS_SETUP_NOT_FOUND 25 +#define IDS_LANGUAGE_ENGLISH 50 +#define IDS_LANGUAGE_SPAIN 51 +#define IDS_LANGUAGE_GERMAN 52 +#define IDS_LANGUAGE_ZH_TW 53 +#define IDS_LANGUAGE_CS 54 +#define IDS_LANGUAGE_DA 55 +#define IDS_LANGUAGE_DE_DE 56 +#define IDS_LANGUAGE_EL 57 +#define IDS_LANGUAGE_EN_US 58 +#define IDS_LANGUAGE_ES 59 +#define IDS_LANGUAGE_FI 60 +#define IDS_LANGUAGE_FR_FR 61 +#define IDS_LANGUAGE_HE 62 +#define IDS_LANGUAGE_HU 63 +#define IDS_LANGUAGE_IT_IT 64 +#define IDS_LANGUAGE_JA 65 +#define IDS_LANGUAGE_KO 66 +#define IDS_LANGUAGE_NL_NL 67 +#define IDS_LANGUAGE_NO_NO 68 +#define IDS_LANGUAGE_PL 69 +#define IDS_LANGUAGE_PT_BR 70 +#define IDS_LANGUAGE_RU 71 +#define IDS_LANGUAGE_SK 72 +#define IDS_LANGUAGE_SV_SE 73 +#define IDS_LANGUAGE_TH 74 +#define IDS_LANGUAGE_TR 75 +#define IDS_LANGUAGE_ET 76 +#define IDS_LANGUAGE_ZH_CN 77 +#define IDS_LANGUAGE_PT_PT 78 + +#define IDI_INSTALLER 99 + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/setup/makefile.mk b/desktop/win32/source/setup/makefile.mk new file mode 100644 index 000000000000..f0c6e0e955fd --- /dev/null +++ b/desktop/win32/source/setup/makefile.mk @@ -0,0 +1,90 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME = desktop +TARGET = loader2 +LIBTARGET = NO +DYNAMIC_CRT = +TARGETTYPE = GUI + +ENABLE_EXCEPTIONS = TRUE + +# --- Settings ------------------------------------------------------------ + +.INCLUDE : settings.mk + +# --- Allgemein ----------------------------------------------------------- + +INCPRE+=$(MFC_INCLUDE) + +.IF "$(USE_DEBUG_RUNTIME)"!="" +CDEFS+=-D_DEBUG +.ENDIF # "$(USE_DEBUG_RUNTIME)"!="" + +RCFILES= $(RES)$/$(TARGET).rc + +ULFFILES= setup.ulf + +.IF "$(WITH_LANG)"!="" +ULFDIR:=$(COMMONMISC)$/$(TARGET) +.ELSE # "$(WITH_LANG)"!="" +ULFDIR:=. +.ENDIF # "$(WITH_LANG)"!="" + +OBJFILES= $(OBJ)$/setup_main.obj \ + $(OBJ)$/setup_w.obj + +# --- Targets ------------------------------------------------------ +# Generate the native Windows resource file +# using lngconvex.exe + +UWINAPILIB= $(0) +LIBSALCPPRT= $(0) + +APP1NOSAL= TRUE +APP1TARGET= loader2 + +APP1STDLIBS= $(GDI32LIB) $(ADVAPI32LIB) $(SHELL32LIB) $(MSILIB) +.IF "$(COM)"!="GCC" +APP1STDLIBS+= libcmt.lib +.ENDIF +APP1OBJS= $(OBJFILES) + +APP1DEF= $(MISC)$/$(TARGET).def + +APP1RES= $(RES)$/$(TARGET).res +APP1NOSVRES= $(RES)$/$(TARGET).res + +# --- setup -------------------------------------------------------------- + +.INCLUDE : target.mk + +$(RCFILES) : $(ULFDIR)$/setup.ulf makefile.mk rcfooter.txt rcheader.txt rctmpl.txt + $(LNGCONVEX) -ulf $(ULFDIR)$/setup.ulf -rc $(RCFILES) -rct rctmpl.txt -rch rcheader.txt -rcf rcfooter.txt + diff --git a/desktop/win32/source/setup/rcfooter.txt b/desktop/win32/source/setup/rcfooter.txt new file mode 100644 index 000000000000..3237729437f5 --- /dev/null +++ b/desktop/win32/source/setup/rcfooter.txt @@ -0,0 +1,2 @@ + +// The end diff --git a/desktop/win32/source/setup/rcheader.txt b/desktop/win32/source/setup/rcheader.txt new file mode 100644 index 000000000000..9a59ad7f6477 --- /dev/null +++ b/desktop/win32/source/setup/rcheader.txt @@ -0,0 +1,43 @@ +#if defined(_MSC_VER) && (_MSC_VER < 1500) +#include <winres.h> +#else +#define WINVER 0x0500 +#include <winresrc.h> +#define LB_ADDSTRING (WM_USER+1) +#define CB_ADDSTRING (WM_USER+3) +#define IDC_STATIC (-1) +#endif +#include "resource.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,1,1,0 + PRODUCTVERSION 1,1,1,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x9L +#else + FILEFLAGS 0x8L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +IDI_INSTALLER ICON "setup.ico" + diff --git a/desktop/win32/source/setup/rctmpl.txt b/desktop/win32/source/setup/rctmpl.txt new file mode 100644 index 000000000000..59f454f70c16 --- /dev/null +++ b/desktop/win32/source/setup/rctmpl.txt @@ -0,0 +1,49 @@ +// String Table + +STRINGTABLE DISCARDABLE +BEGIN + IDS_APP_TITLE %APP_TITLE% + IDS_APP_PROD_TITLE %APP_PROD_TITLE% + IDS_OUTOFMEM %OUTOFMEM% + IDS_NOMSI %NOMSI% + IDS_USER_CANCELLED %USER_CANCELLED% + IDS_REQUIRES_ADMIN_PRIV %REQUIRES_ADMIN_PRIV% + IDS_FILE_NOT_FOUND %FILE_NOT_FOUND% + IDS_INVALID_PARAM %INVALID_PARAM% + IDS_SETUP_TO_OLD %SETUP_TO_OLD% + IDS_SETUP_NOT_FOUND %SETUP_NOT_FOUND% + IDS_USAGE %USAGE% + IDS_ALREADY_RUNNING %ALREADY_RUNNING% + IDS_UNKNOWN_ERROR %UNKNOWN_ERROR% + IDS_INVALID_PROFILE %INVALID_PROFILE% + IDS_UNKNOWN_LANG %UNKNOWN_LANG% + IDS_LANGUAGE_ENGLISH %LANGUAGE_ENGLISH% + IDS_LANGUAGE_SPAIN %LANGUAGE_SPAIN% + IDS_LANGUAGE_GERMAN %LANGUAGE_GERMAN% + IDS_LANGUAGE_ZH_TW %LANGUAGE_ZH_TW% + IDS_LANGUAGE_CS %LANGUAGE_CS% + IDS_LANGUAGE_DA %LANGUAGE_DA% + IDS_LANGUAGE_DE_DE %LANGUAGE_DE_DE% + IDS_LANGUAGE_EL %LANGUAGE_EL% + IDS_LANGUAGE_EN_US %LANGUAGE_EN_US% + IDS_LANGUAGE_ES %LANGUAGE_ES% + IDS_LANGUAGE_FI %LANGUAGE_FI% + IDS_LANGUAGE_FR_FR %LANGUAGE_FR_FR% + IDS_LANGUAGE_HE %LANGUAGE_HE% + IDS_LANGUAGE_HU %LANGUAGE_HU% + IDS_LANGUAGE_IT_IT %LANGUAGE_IT_IT% + IDS_LANGUAGE_JA %LANGUAGE_JA% + IDS_LANGUAGE_KO %LANGUAGE_KO% + IDS_LANGUAGE_NL_NL %LANGUAGE_NL_NL% + IDS_LANGUAGE_NO_NO %LANGUAGE_NO_NO% + IDS_LANGUAGE_PL %LANGUAGE_PL% + IDS_LANGUAGE_PT_BR %LANGUAGE_PT_BR% + IDS_LANGUAGE_RU %LANGUAGE_RU% + IDS_LANGUAGE_SK %LANGUAGE_SK% + IDS_LANGUAGE_SV_SE %LANGUAGE_SV_SE% + IDS_LANGUAGE_TH %LANGUAGE_TH% + IDS_LANGUAGE_TR %LANGUAGE_TR% + IDS_LANGUAGE_ET %LANGUAGE_ET% + IDS_LANGUAGE_ZH_CN %LANGUAGE_ZH_CN% + IDS_LANGUAGE_PT_PT %LANGUAGE_PT_PT% +END diff --git a/desktop/win32/source/setup/setup.cpp b/desktop/win32/source/setup/setup.cpp new file mode 100644 index 000000000000..52746837646c --- /dev/null +++ b/desktop/win32/source/setup/setup.cpp @@ -0,0 +1,2063 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#define WIN // scope W32 API +#define _WIN32_WINNT 0x0501 + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <tchar.h> +#include <assert.h> +#include <shlwapi.h> +#include <new> +#include <time.h> +#include <mbctype.h> +#include <locale.h> +#include <Msiquery.h> +#include <MsiDefs.h> +#include "strsafe.h" + +#include "setup.hxx" + +#include "resource.h" + +//-------------------------------------------------------------------------- + +#define MAX_STR_LENGTH 32000 +#define MAX_TEXT_LENGTH 1024 +#define MAX_LANGUAGE_LEN 80 +#define MAX_STR_CAPTION 256 +#define VERSION_SIZE 80 +#define SECTION_SETUP TEXT( "Setup" ) +#define SECTION_LANGUAGE TEXT( "Languages" ) +#define PRODUCT_NAME_VAR TEXT( "%PRODUCTNAME" ) +#define PRODUCT_VERSION TEXT( "ProductVersion" ) +#define ERROR_SHOW_USAGE -2 +#define ERROR_SETUP_TO_OLD -3 +#define ERROR_SETUP_NOT_FOUND -4 + +#define PARAM_SETUP_USED TEXT( " SETUP_USED=1 " ) +#define PARAM_PACKAGE TEXT( "/I " ) +#define PARAM_MINOR_UPGRADE TEXT( "/FVOMUS " ) +#define PARAM_ADMIN TEXT( "/A " ) +#define PARAM_TRANSFORM TEXT( " TRANSFORMS=" ) +#define PARAM_REBOOT TEXT( " REBOOT=Force" ) +#define PARAM_PATCH TEXT( " /update " ) +#define PARAM_REG_ALL_MSO_TYPES TEXT( "REGISTER_ALL_MSO_TYPES=1 " ) +#define PARAM_REG_NO_MSO_TYPES TEXT( "REGISTER_NO_MSO_TYPES=1 " ) +#define PARAM_SILENTINSTALL TEXT( " /QB" ) + +#define PARAM_RUNNING TEXT( "ignore_running" ) +#define CMDLN_REG_ALL_MSO_TYPES TEXT( "msoreg=1" ) +#define CMDLN_REG_NO_MSO_TYPES TEXT( "msoreg=0" ) + +#define MSI_DLL TEXT( "msi.dll" ) +#define ADVAPI32_DLL TEXT( "advapi32.dll" ) +#define PROFILE_NAME TEXT( "setup.ini" ) + +#define RUNTIME_X64_NAME TEXT( "redist\\vcredist_x64.exe" ) +#define RUNTIME_X86_NAME TEXT( "redist\\vcredist_x86.exe" ) +#define PRODUCTCODE_X86 TEXT( "{1F1C2DFC-2D24-3E06-BCB8-725134ADF989}" ) +#define PRODUCTCODE_X64 TEXT( "{4B6C7001-C7D6-3710-913E-5BC23FCE91E6}" ) + +#define MSIAPI_DllGetVersion "DllGetVersion" +#define ADVAPI32API_CheckTokenMembership "CheckTokenMembership" + +typedef HRESULT (CALLBACK* PFnDllGetVersion)( DLLVERSIONINFO *pdvi); +typedef BOOL (WINAPI* PFnCheckTokenMembership)(HANDLE TokenHandle, PSID SidToCheck, PBOOL IsMember); + +#ifdef DEBUG +inline void OutputDebugStringFormat( LPCTSTR pFormat, ... ) +{ + TCHAR buffer[1024]; + va_list args; + + va_start( args, pFormat ); + StringCchVPrintf( buffer, sizeof(buffer), pFormat, args ); + OutputDebugString( buffer ); +} +#else +static inline void OutputDebugStringFormat( LPCTSTR, ... ) +{ +} +#endif + +//-------------------------------------------------------------------------- + +const TCHAR sInstKey[] = TEXT( "Software\\Microsoft\\Windows\\CurrentVersion\\Installer" ); +const TCHAR sInstLocValue[] = TEXT( "InstallerLocation" ); +const TCHAR sMsiDll[] = TEXT( "\\msi.dll" ); +const TCHAR sMsiExe[] = TEXT( "\\msiexec.exe" ); +const TCHAR sDelayReboot[] = TEXT( " /c:\"msiinst /delayreboot\"" ); +const TCHAR sMsiQuiet[] = TEXT( " /q" ); +const TCHAR sMemMapName[] = TEXT( "Global\\MsiErrorObject" ); + +//-------------------------------------------------------------------------- +SetupAppX::SetupAppX() +{ + m_hInst = NULL; + m_hMapFile = NULL; + m_pAppTitle = NULL; + m_pCmdLine = NULL; + + m_pDatabase = NULL; + m_pReqVersion = NULL; + m_pProductName = NULL; + m_pAdvertise = NULL; + m_pTmpName = NULL; + m_pLogFile = NULL; + m_pModuleFile = NULL; + m_pPatchFiles = NULL; + m_pMSIErrorCode = NULL; + m_pUpgradeKey = NULL; + m_pProductVersion = NULL; + + m_pErrorText = new TCHAR[ MAX_TEXT_LENGTH ]; + m_pErrorText[0] = '\0'; + + m_nLanguageID = 0; + m_nLanguageCount = 0; + m_ppLanguageList = NULL; + + m_bQuiet = false; + m_bRegNoMsoTypes = false; + m_bRegAllMsoTypes = false; + m_bIsMinorUpgrade = false; + m_bSupportsPatch = false; + + m_bIgnoreAlreadyRunning = false; +} + +//-------------------------------------------------------------------------- +SetupAppX::~SetupAppX() +{ + if ( m_ppLanguageList ) + { + for ( int i = 0; i < m_nLanguageCount; i++ ) + if ( m_ppLanguageList[i] ) + delete m_ppLanguageList[ i ]; + delete [] m_ppLanguageList; + } + + time_t aTime; + time( &aTime ); + tm *pTime = localtime( &aTime ); // Convert time to struct tm form + + Log( TEXT( "End: %s\n\r\n\r\n" ), _tasctime( pTime ) ); + + if ( m_pLogFile ) fclose( m_pLogFile ); + + if ( m_pTmpName ) + { + _tremove( m_pTmpName ); + free( m_pTmpName ); + } + + if ( m_pMSIErrorCode ) UnmapViewOfFile( m_pMSIErrorCode ); + if ( m_hMapFile ) CloseHandle( m_hMapFile ); + + if ( m_pAppTitle ) delete [] m_pAppTitle; + if ( m_pDatabase ) delete [] m_pDatabase; + if ( m_pReqVersion ) delete [] m_pReqVersion; + if ( m_pProductName ) delete [] m_pProductName; + if ( m_pAdvertise ) delete [] m_pAdvertise; + if ( m_pLogFile ) delete [] m_pLogFile; + if ( m_pErrorText ) delete [] m_pErrorText; + if ( m_pModuleFile ) delete [] m_pModuleFile; + if ( m_pPatchFiles ) delete [] m_pPatchFiles; + if ( m_pUpgradeKey ) delete [] m_pUpgradeKey; + if ( m_pProductVersion ) delete [] m_pProductVersion; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::Initialize( HINSTANCE hInst ) +{ + m_pCmdLine = WIN::GetCommandLine(); + m_hInst = hInst; + + // Load our AppTitle (caption) + m_pAppTitle = new TCHAR[ MAX_STR_CAPTION ]; + m_pAppTitle[0] = '\0'; + WIN::LoadString( hInst, IDS_APP_TITLE, m_pAppTitle, MAX_STR_CAPTION ); + + // Obtain path we are running from + m_pModuleFile = new TCHAR[ MAX_PATH ]; + m_pModuleFile[ 0 ] = '\0'; + + if ( 0 == WIN::GetModuleFileName( hInst, m_pModuleFile, MAX_PATH ) ) + { + SetError( WIN::GetLastError() ); + return false; + } + + if ( ! GetCmdLineParameters( &m_pCmdLine ) ) + return false; + + m_hMapFile = CreateFileMapping( + INVALID_HANDLE_VALUE, // use paging file + NULL, // default security + PAGE_READWRITE, // read/write access + 0, // max. object size + sizeof( int ), // buffer size + sMemMapName ); + if ( m_hMapFile ) + { + m_pMSIErrorCode = (int*) MapViewOfFile( m_hMapFile, // handle to map object + FILE_MAP_ALL_ACCESS, // read/write permission + 0, + 0, + sizeof( int ) ); + if ( m_pMSIErrorCode ) + *m_pMSIErrorCode = 0; + else + OutputDebugStringFormat( TEXT("Could not map view of file (%d).\n"), GetLastError() ); + } + else + OutputDebugStringFormat( TEXT("Could not create file mapping object (%d).\n"), GetLastError() ); + + Log( TEXT("Starting: %s\r\n"), m_pModuleFile ); + Log( TEXT(" CommandLine=<%s>\r\n"), m_pCmdLine ); + + if ( m_bQuiet ) + Log( TEXT(" Using quiet install mode\r\n") ); + + time_t aTime; + time( &aTime ); + tm* pTime = localtime( &aTime ); + Log( TEXT(" Begin: %s\n"), _tasctime( pTime ) ); + + return true; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::GetProfileSection( LPCTSTR pFileName, LPCTSTR pSection, + DWORD& rSize, LPTSTR *pRetBuf ) +{ + if ( !rSize || !*pRetBuf ) + { + rSize = 10000; + *pRetBuf = new TCHAR[ rSize ]; + } + + DWORD nRet = GetPrivateProfileSection( pSection, *pRetBuf, rSize, pFileName ); + + while ( nRet && ( nRet + 2 >= rSize ) ) // buffer was too small, retry until big enough + { + if (rSize > 1000000) + break; + delete [] (*pRetBuf); + rSize = rSize * 2; + *pRetBuf = new TCHAR[ rSize ]; + + nRet = GetPrivateProfileSection( pSection, *pRetBuf, rSize, pFileName ); + } + + if ( !nRet ) + { + SetError( WIN::GetLastError() ); + + TCHAR sBuf[80]; + StringCchPrintf( sBuf, 80, TEXT("ERROR: GetPrivateProfileSection(): GetLastError returned %u\r\n"), GetError() ); + Log( sBuf ); + return false; + } + else if ( nRet + 2 >= rSize ) + { + SetError( ERROR_OUTOFMEMORY ); + Log( TEXT( "ERROR: GetPrivateProfileSection() out of memory\r\n" ) ); + return false; + } + + Log( TEXT( " GetProfileSection read %s\r\n" ), pSection ); + + return true; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::ReadProfile() +{ + boolean bRet = false; + TCHAR *sProfilePath = 0; + + if ( GetPathToFile( PROFILE_NAME, &sProfilePath ) ) + { + DWORD nSize = 0; + LPTSTR pRetBuf = NULL; + + Log( TEXT( " Open ini file: <%s>\r\n" ), sProfilePath ); + + bRet = GetProfileSection( sProfilePath, SECTION_SETUP, nSize, &pRetBuf ); + + if ( !bRet ) + { + LPTSTR pTmpFile = CopyIniFile( sProfilePath ); + delete [] sProfilePath; + sProfilePath = pTmpFile; + + if ( sProfilePath ) + { + SetError( ERROR_SUCCESS ); + + Log( TEXT( " Could not open inifile, copied ini file to: <%s>\r\n" ), sProfilePath ); + bRet = GetProfileSection( sProfilePath, SECTION_SETUP, nSize, &pRetBuf ); + } + } + + if ( bRet ) + { + LPTSTR pCurLine = pRetBuf; + while ( *pCurLine ) + { + LPTSTR pName = 0; + LPTSTR pValue = 0; + + pCurLine += GetNameValue( pCurLine, &pName, &pValue ); + + if ( lstrcmpi( TEXT( "database" ), pName ) == 0 ) + { + m_pDatabase = pValue; + Log( TEXT( " Database = %s\r\n" ), pValue ); + } + else if ( lstrcmpi( TEXT( "msiversion" ), pName ) == 0 ) + { + m_pReqVersion = pValue; + Log( TEXT( " msiversion = %s\r\n" ), pValue ); + } + else if ( lstrcmpi( TEXT( "productname" ), pName ) == 0 ) + { + m_pProductName = pValue; + Log( TEXT( " productname = %s\r\n" ), pValue ); + m_pAppTitle = SetProdToAppTitle( m_pProductName ); + } + else if ( lstrcmpi( TEXT( "upgradekey" ), pName ) == 0 ) + { + m_pUpgradeKey = pValue; + Log( TEXT( " upgradekey = %s\r\n" ), pValue ); + } + else if ( lstrcmpi( TEXT( "productversion" ), pName ) == 0 ) + { + m_pProductVersion = pValue; + Log( TEXT( " productversion = %s\r\n" ), pValue ); + } + else if ( lstrcmpi( TEXT( "productcode" ), pName ) == 0 ) + { + delete [] pValue; + } + else + { + Log( TEXT( "Warning: unknown entry in profile <%s>\r\n" ), pName ); + delete [] pValue; + } + } + } + + if ( bRet && ( !m_pDatabase || !m_pReqVersion || !m_pProductName ) ) + { + Log( TEXT( "ERROR: incomplete 'Setup' section in profile\r\n" ) ); + SetError( ERROR_INVALID_DATA ); + bRet = false; + } + + if ( bRet ) + bRet = GetProfileSection( sProfilePath, SECTION_LANGUAGE, nSize, &pRetBuf ); + + if ( bRet ) + { + LPTSTR pName = 0; + LPTSTR pValue = 0; + LPTSTR pCurLine = pRetBuf; + LPTSTR pLastChar; + int nNext = 0; + + // first line in this section should be the language count + nNext = GetNameValue( pCurLine, &pName, &pValue ); + if ( lstrcmpi( TEXT( "count" ), pName ) == 0 ) + { + Log( TEXT( " Languages = %s\r\n" ), pValue ); + m_nLanguageCount = _tcstol( pValue, &pLastChar, 10 ); + pCurLine += nNext; + delete [] pValue; + } + + m_ppLanguageList = new LanguageDataX*[ m_nLanguageCount ]; + + for ( int i=0; i < m_nLanguageCount; i++ ) + { + if ( !*pCurLine ) + { + m_nLanguageCount = i; + break; + } + + pCurLine += GetNameValue( pCurLine, &pName, &pValue ); + m_ppLanguageList[ i ] = new LanguageDataX( pValue ); + Log( TEXT( " Language = %s\r\n" ), pValue ); + + if ( m_ppLanguageList[ i ]->m_pTransform ) + Log( TEXT( " Transform = %s\r\n" ), m_ppLanguageList[ i ]->m_pTransform ); + + delete [] pValue; + } + } + + if ( pRetBuf ) + delete [] pRetBuf; + } + + if ( sProfilePath && ! m_pTmpName ) + delete [] sProfilePath; + + return bRet; +} + +//-------------------------------------------------------------------------- +void SetupAppX::AddFileToPatchList( TCHAR* pPath, TCHAR* pFile ) +{ + if ( m_pPatchFiles == NULL ) + { + m_pPatchFiles = new TCHAR[ MAX_STR_LENGTH ]; + StringCchCopy( m_pPatchFiles, MAX_STR_LENGTH, TEXT("\"") ); + } + else + StringCchCat( m_pPatchFiles, MAX_STR_LENGTH, TEXT(";") ); + + StringCchCat( m_pPatchFiles, MAX_STR_LENGTH, pPath ); + StringCchCat( m_pPatchFiles, MAX_STR_LENGTH, pFile ); +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::GetPatches() +{ + boolean bRet = true; + + int nPatternLen = lstrlen( m_pModuleFile ) + 7; // 1 for null terminator, 1 for back slash, 5 for extensions + TCHAR* pPattern = new TCHAR[ nPatternLen ]; + TCHAR* pBaseDir = new TCHAR[ nPatternLen ]; + + // find 'setup.exe' in the path so we can remove it + TCHAR *pFilePart = 0; + if ( 0 == GetFullPathName( m_pModuleFile, nPatternLen, pPattern, &pFilePart ) ) + { + SetError( WIN::GetLastError() ); + bRet = false; + } + else + { + if ( pFilePart ) + *pFilePart = '\0'; + StringCchCopy( pBaseDir, nPatternLen, pPattern ); + StringCchCat( pPattern, nPatternLen, TEXT("*.msp") ); + + WIN32_FIND_DATA aFindFileData; + + HANDLE hFindPatches = FindFirstFile( pPattern, &aFindFileData ); + + if ( hFindPatches != INVALID_HANDLE_VALUE ) + { + if ( ! IsPatchInstalled( pBaseDir, aFindFileData.cFileName ) ) + AddFileToPatchList( pBaseDir, aFindFileData.cFileName ); + + while ( FindNextFile( hFindPatches, &aFindFileData ) ) + { + if ( ! IsPatchInstalled( pBaseDir, aFindFileData.cFileName ) ) + AddFileToPatchList( pBaseDir, aFindFileData.cFileName ); + } + + if ( m_pPatchFiles != NULL ) + StringCchCat( m_pPatchFiles, MAX_STR_LENGTH, TEXT("\"") ); + + FindClose( hFindPatches ); + } + } + + delete [] pPattern; + delete [] pBaseDir; + + return bRet; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::GetPathToFile( TCHAR* pFileName, TCHAR** pPath ) +{ + // generate the path to the file = szModuleFile + FileName + // note: FileName is a relative path + + boolean bRet = true; + + int nTempPath = lstrlen( m_pModuleFile ) + lstrlen( pFileName ) + 2; // 1 for null terminator, 1 for back slash + TCHAR* pTempPath = new TCHAR[ nTempPath ]; + + // find 'setup.exe' in the path so we can remove it + TCHAR *pFilePart = 0; + if ( 0 == GetFullPathName( m_pModuleFile, nTempPath, pTempPath, &pFilePart ) ) + { + SetError( WIN::GetLastError() ); + bRet = false; + } + else + { + if ( pFilePart ) + *pFilePart = '\0'; + + StringCchCat( pTempPath, nTempPath, pFileName ); + + int nPath = 2 * nTempPath; + *pPath = new TCHAR[ nPath ]; + + // normalize the path + int nReturn = GetFullPathName( pTempPath, nPath, *pPath, &pFilePart ); + + if ( nReturn > nPath ) + { + // try again, with larger buffer + delete [] (*pPath); + nPath = nReturn; + *pPath = new TCHAR[ nPath ]; + + nReturn = GetFullPathName( pTempPath, nPath, *pPath, &pFilePart ); + } + + if ( 0 == nReturn ) + { + // error -- invalid path + SetError( WIN::GetLastError() ); + bRet = false; + } + } + + if ( bRet ) // check for the file's existence + { + DWORD dwFileAttrib = GetFileAttributes( *pPath ); + + if (0xFFFFFFFF == dwFileAttrib) + { + StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pFileName ); + SetError( ERROR_FILE_NOT_FOUND ); + bRet = false; + } + } + + delete [] pTempPath; + return bRet; +} + +//-------------------------------------------------------------------------- +int SetupAppX::GetNameValue( TCHAR* pLine, TCHAR** pName, TCHAR** pValue ) +{ + int nRet = lstrlen( pLine ) + 1; + *pValue = 0; + + if ( nRet == 1 ) + return nRet; + + LPTSTR pChar = pLine; + LPTSTR pLast = NULL; + + // Skip leading spaces. + while (' ' == *pChar || '\t' == *pChar) + pChar = CharNext( pChar ); + + *pName = pChar; + + // look for the end of the name + while( *pChar && (' ' != *pChar) && + ( '\t' != *pChar ) && ( '=' != *pChar ) ) + pChar = CharNext( pChar ); + + if ( ! *pChar ) + return nRet; + + pLast = pChar; + pChar = CharNext( pChar ); + *pLast = '\0'; + + // look for the start of the value + while( ( ' ' == *pChar ) || ( '\t' == *pChar ) || + ( '=' == *pChar ) ) + pChar = CharNext( pChar ); + + int nValueLen = lstrlen( pChar ) + 1; + *pValue = new TCHAR[ nValueLen ]; + + if ( *pValue ) + StringCchCopy( *pValue, nValueLen, pChar ); + + return nRet; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::ChooseLanguage( long& rLanguage ) +{ + rLanguage = 0; + + if ( m_bQuiet ) + return true; + + // When there are none or only one language, there is nothing + // to do here + if ( m_nLanguageCount > 1 ) + { + TCHAR *sString = new TCHAR[ MAX_LANGUAGE_LEN ]; + + LANGID nUserDefLang = GetUserDefaultLangID(); + LANGID nSysDefLang = GetSystemDefaultLangID(); + + int nUserPrimary = PRIMARYLANGID( nUserDefLang ); + int nSysPrimary = PRIMARYLANGID( nSysDefLang ); + + long nUserIndex = -1; + long nUserPrimIndex = -1; + long nSystemIndex = -1; + long nSystemPrimIndex = -1; + long nParamIndex = -1; + + for ( long i=0; i<GetLanguageCount(); i++ ) + { + long nLanguage = GetLanguageID( i ); + int nPrimary = PRIMARYLANGID( nLanguage ); + GetLanguageName( nLanguage, sString ); + Log( TEXT( " Info: found Language: %s\r\n" ), sString ); + + if ( nLanguage == nUserDefLang ) + nUserIndex = i; + if ( nPrimary == nUserPrimary ) + nUserPrimIndex = i; + if ( nLanguage == nSysDefLang ) + nSystemIndex = i; + if ( nPrimary == nSysPrimary ) + nSystemPrimIndex = i; + if ( m_nLanguageID && ( nLanguage == m_nLanguageID ) ) + nParamIndex = i; + } + + if ( m_nLanguageID && ( nParamIndex == -1 ) ) + { + Log( TEXT( "Warning: Language chosen with parameter -lang not found.\r\n" ) ); + } + + if ( nParamIndex != -1 ) + { + Log( TEXT( "Info: Found language chosen with parameter -lang.\r\n" ) ); + rLanguage = GetLanguageID( nParamIndex ); + } + else if ( nUserIndex != -1 ) + { + Log( TEXT( "Info: Found user default language.\r\n" ) ); + rLanguage = GetLanguageID( nUserIndex ); + } + else if ( nUserPrimIndex != -1 ) + { + Log( TEXT( "Info: Found user default primary language.\r\n" ) ); + rLanguage = GetLanguageID( nUserPrimIndex ); + } + else if ( nSystemIndex != -1 ) + { + Log( TEXT( "Info: Found system default language.\r\n" ) ); + rLanguage = GetLanguageID( nSystemIndex ); + } + else if ( nSystemPrimIndex != -1 ) + { + Log( TEXT( "Info: Found system default primary language.\r\n" ) ); + rLanguage = GetLanguageID( nSystemPrimIndex ); + } + else + { + Log( TEXT( "Info: Use default language from ini file.\r\n" ) ); + rLanguage = GetLanguageID( 0 ); + } + delete [] sString; + } + + return true; +} + +//-------------------------------------------------------------------------- +HMODULE SetupAppX::LoadMsiLibrary() +{ + HMODULE hMsi = NULL; + HKEY hInstKey = NULL; + + // find registered location of Msi.dll + if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, sInstKey, 0, KEY_READ, &hInstKey ) ) + { + long nRet = ERROR_SUCCESS; + TCHAR *sMsiFolder = new TCHAR[ MAX_PATH + 1 ]; + DWORD dwMsiFolderSize = MAX_PATH + 1; + DWORD dwType = 0; + + if ( ERROR_MORE_DATA == ( nRet = RegQueryValueEx( hInstKey, sInstLocValue, NULL, + &dwType, (BYTE*)sMsiFolder, &dwMsiFolderSize ) ) ) + { + // try again with larger buffer + delete [] sMsiFolder; + sMsiFolder = new TCHAR[ dwMsiFolderSize ]; + + nRet = RegQueryValueEx( hInstKey, sInstLocValue, NULL, &dwType, + (BYTE*)sMsiFolder, &dwMsiFolderSize ); + } + + if ( ERROR_SUCCESS == nRet && dwType == REG_SZ && dwMsiFolderSize > 0 ) + { + // load Msi.dll from registered location + int nLength = lstrlen( sMsiDll ) + dwMsiFolderSize + 1; // use StringCchLength ? + TCHAR *pMsiLocation = new TCHAR[ nLength ]; + + if ( SUCCEEDED( StringCchCopy( pMsiLocation, nLength, sMsiFolder ) ) && + SUCCEEDED( StringCchCat( pMsiLocation, nLength, sMsiDll ) ) ) + { + hMsi = LoadLibrary( pMsiLocation ); + } + } + } + + if ( !hMsi ) // use the default location + { + hMsi = LoadLibrary( sMsiDll ); + } + + return hMsi; +} + +//-------------------------------------------------------------------------- +LPCTSTR SetupAppX::GetPathToMSI() +{ + LPTSTR sMsiPath = NULL; + HKEY hInstKey = NULL; + TCHAR *sMsiFolder = new TCHAR[ MAX_PATH + 1 ]; + DWORD nMsiFolderSize = MAX_PATH + 1; + + sMsiFolder[0] = '\0'; + + // find registered location of Msi.dll + if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, sInstKey, 0, KEY_READ, &hInstKey ) ) + { + LONG nRet = ERROR_SUCCESS; + DWORD dwType = 0; + + if ( ERROR_MORE_DATA == ( nRet = RegQueryValueEx( hInstKey, sInstLocValue, NULL, + &dwType, (BYTE*)sMsiFolder, &nMsiFolderSize ) ) ) + { + // try again with larger buffer + delete [] sMsiFolder; + sMsiFolder = new TCHAR[ nMsiFolderSize ]; + + nRet = RegQueryValueEx( hInstKey, sInstLocValue, NULL, &dwType, + (BYTE*)sMsiFolder, &nMsiFolderSize ); + } + + if ( ERROR_SUCCESS != nRet || dwType != REG_SZ || nMsiFolderSize == 0 ) + sMsiFolder[0] = '\0'; + } + + if ( sMsiFolder[0] == '\0' ) // use the default location + { + Log( TEXT( " Could not find path to msiexec.exe in registry" ) ); + + DWORD nRet = WIN::GetSystemDirectory( sMsiFolder, nMsiFolderSize ); + if ( nRet > nMsiFolderSize ) + { + delete [] sMsiFolder; + sMsiFolder = new TCHAR[ nRet ]; + nMsiFolderSize = nRet; + + nRet = WIN::GetSystemDirectory( sMsiFolder, nMsiFolderSize ); + } + if ( 0 == nRet ) + { + sMsiFolder[0] = '\0'; + SetError( WIN::GetLastError() ); + } + nMsiFolderSize = nRet; + } + + if ( sMsiFolder[0] != '\0' ) + { + int nLength = lstrlen( sMsiExe ) + lstrlen( sMsiFolder ) + 1; + sMsiPath = new TCHAR[ nLength ]; + + if ( FAILED( StringCchCopy( sMsiPath, nLength, sMsiFolder ) ) || + FAILED( StringCchCat( sMsiPath, nLength, sMsiExe ) ) ) + { + delete [] sMsiPath; + sMsiPath = NULL; + } + } + + if ( ! sMsiPath ) + Log( TEXT( "ERROR: Can't build path to msiexec.exe!" ) ); + + return sMsiPath; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::LaunchInstaller( LPCTSTR pParam ) +{ + LPCTSTR sMsiPath = GetPathToMSI(); + + if ( !sMsiPath ) + { + Log( TEXT( "ERROR: msiexec not found!" ) ); + SetError( ERROR_FILE_NOT_FOUND ); + return false; + } + + STARTUPINFO aSUI; + PROCESS_INFORMATION aPI; + + Log( TEXT( " Will install using <%s>\r\n" ), sMsiPath ); + Log( TEXT( " Parameters are: %s\r\n" ), pParam ); + + OutputDebugStringFormat( TEXT( " Will install using <%s>\r\n" ), sMsiPath ); + OutputDebugStringFormat( TEXT( " Parameters are: %s\r\n" ), pParam ); + + ZeroMemory( (void*)&aPI, sizeof( PROCESS_INFORMATION ) ); + ZeroMemory( (void*)&aSUI, sizeof( STARTUPINFO ) ); + + aSUI.cb = sizeof(STARTUPINFO); + aSUI.dwFlags = STARTF_USESHOWWINDOW; + aSUI.wShowWindow = SW_SHOW; + + DWORD nCmdLineLength = lstrlen( sMsiPath ) + lstrlen( pParam ) + 2; + TCHAR *sCmdLine = new TCHAR[ nCmdLineLength ]; + + if ( FAILED( StringCchCopy( sCmdLine, nCmdLineLength, sMsiPath ) ) || + FAILED( StringCchCat( sCmdLine, nCmdLineLength, TEXT( " " ) ) ) || + FAILED( StringCchCat( sCmdLine, nCmdLineLength, pParam ) ) ) + { + delete [] sCmdLine; + SetError( ERROR_INSTALL_FAILURE ); + return false; + } + + if ( !WIN::CreateProcess( NULL, sCmdLine, NULL, NULL, FALSE, + CREATE_DEFAULT_ERROR_MODE, NULL, NULL, + &aSUI, &aPI ) ) + { + Log( TEXT( "ERROR: Could not create process %s.\r\n" ), sCmdLine ); + SetError( WIN::GetLastError() ); + delete [] sCmdLine; + return false; + } + + DWORD nResult = WaitForProcess( aPI.hProcess ); + bool bRet = true; + + if( ERROR_SUCCESS != nResult ) + { + Log( TEXT( "ERROR: While waiting for %s.\r\n" ), sCmdLine ); + SetError( nResult ); + bRet = false; + } + else + { + GetExitCodeProcess( aPI.hProcess, &nResult ); + SetError( nResult ); + + if ( nResult != ERROR_SUCCESS ) + { + TCHAR sBuf[80]; + StringCchPrintf( sBuf, 80, TEXT("Warning: msiexec returned %u.\r\n"), nResult ); + Log( sBuf ); + } + else + Log( TEXT( " Installation completed successfully.\r\n" ) ); + } + + CloseHandle( aPI.hProcess ); + + delete [] sCmdLine; + + return bRet; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::Install( long nLanguage ) +{ + LPTSTR pTransform = NULL; + + if ( nLanguage ) // look for transformation + { + for ( int i = 0; i < m_nLanguageCount; i++ ) + { + if ( m_ppLanguageList[i]->m_nLanguageID == nLanguage ) + { + if ( m_ppLanguageList[i]->m_pTransform ) + { + if ( !GetPathToFile( m_ppLanguageList[i]->m_pTransform, + &pTransform ) ) + { + Log( TEXT( "ERROR: Could not find transform <%s\r\n" ), m_ppLanguageList[i]->m_pTransform ); + return false; + } + } + break; + } + } + } + + TCHAR *pDataBasePath = NULL; + + if ( ! GetPathToFile( m_pDatabase, &pDataBasePath ) ) + { + Log( TEXT( "ERROR: Could not find database <%s\r\n" ), m_pDatabase ); + SetError( ERROR_INSTALL_SOURCE_ABSENT ); + return false; + } + + // we will always use the parameter setup used + int nParLen = lstrlen( PARAM_SETUP_USED ); + + if ( m_bRegNoMsoTypes ) + nParLen += lstrlen( PARAM_REG_NO_MSO_TYPES ); + else if ( m_bRegAllMsoTypes ) + nParLen += lstrlen( PARAM_REG_ALL_MSO_TYPES ); + + if ( m_pAdvertise ) + nParLen += lstrlen( m_pAdvertise ) + 1; // one for the space + else if ( m_bIsMinorUpgrade ) + nParLen += lstrlen( PARAM_MINOR_UPGRADE ); + else + nParLen += lstrlen( PARAM_PACKAGE ); + + nParLen += lstrlen( pDataBasePath ) + 3; // two quotes, one null + + if ( NeedReboot() ) + nParLen += lstrlen( PARAM_REBOOT ); + + if ( m_pPatchFiles ) + { + nParLen += lstrlen( PARAM_PATCH ); + nParLen += lstrlen( m_pPatchFiles ); + } + + if ( pTransform ) + { + nParLen += lstrlen( PARAM_TRANSFORM ); + nParLen += lstrlen( pTransform ) + 2; // two quotes + } + + if ( m_pCmdLine ) + nParLen += lstrlen( m_pCmdLine ) + 1; // one for the space; + + TCHAR *pParams = new TCHAR[ nParLen ]; + + StringCchCopy( pParams, nParLen, PARAM_SETUP_USED ); + + if ( m_bRegNoMsoTypes ) + StringCchCat( pParams, nParLen, PARAM_REG_NO_MSO_TYPES ); + else if ( m_bRegAllMsoTypes ) + StringCchCat( pParams, nParLen, PARAM_REG_ALL_MSO_TYPES ); + + if ( m_pAdvertise ) + StringCchCat( pParams, nParLen, m_pAdvertise ); + else if ( IsAdminInstall() ) + StringCchCat( pParams, nParLen, PARAM_ADMIN ); + else if ( m_bIsMinorUpgrade ) + StringCchCat( pParams, nParLen, PARAM_MINOR_UPGRADE ); + else + StringCchCat( pParams, nParLen, PARAM_PACKAGE ); + + StringCchCat( pParams, nParLen, TEXT( "\"" ) ); + StringCchCat( pParams, nParLen, pDataBasePath ); + StringCchCat( pParams, nParLen, TEXT( "\"" ) ); + + if ( NeedReboot() ) + StringCchCat( pParams, nParLen, PARAM_REBOOT ); + + if ( m_pPatchFiles ) + { + StringCchCat( pParams, nParLen, PARAM_PATCH ); + StringCchCat( pParams, nParLen, m_pPatchFiles ); + } + + if ( pTransform ) + { + StringCchCat( pParams, nParLen, PARAM_TRANSFORM ); + StringCchCat( pParams, nParLen, TEXT( "\"" ) ); + StringCchCat( pParams, nParLen, pTransform ); + StringCchCat( pParams, nParLen, TEXT( "\"" ) ); + } + + if ( m_pCmdLine ) + { + StringCchCat( pParams, nParLen, TEXT( " " ) ); + StringCchCat( pParams, nParLen, m_pCmdLine ); + } + + return LaunchInstaller( pParams ); +} + +//-------------------------------------------------------------------------- +UINT SetupAppX::GetError() const +{ + UINT nErr = 0; + + if ( m_pMSIErrorCode ) + nErr = (UINT) *m_pMSIErrorCode; + + if ( nErr == 0 ) + nErr = m_uiRet; + + if ( nErr != 0 ) + OutputDebugStringFormat( TEXT("Setup will return error (%d).\n"), nErr ); + return nErr; +} + +//-------------------------------------------------------------------------- +void SetupAppX::DisplayError( UINT nErr ) const +{ + TCHAR sError[ MAX_TEXT_LENGTH ] = {0}; + TCHAR sTmp[ MAX_TEXT_LENGTH ] = {0}; + + UINT nMsgType = MB_OK | MB_ICONERROR; + + switch ( nErr ) + { + case ERROR_SUCCESS: break; // 0 + + case ERROR_FILE_NOT_FOUND: // 2 + WIN::LoadString( m_hInst, IDS_FILE_NOT_FOUND, sTmp, MAX_TEXT_LENGTH ); + StringCchPrintf( sError, MAX_TEXT_LENGTH, sTmp, m_pErrorText ); + break; + case ERROR_INVALID_DATA: // 13 + WIN::LoadString( m_hInst, IDS_INVALID_PROFILE, sError, MAX_TEXT_LENGTH ); + break; + case ERROR_OUTOFMEMORY: WIN::LoadString( m_hInst, IDS_OUTOFMEM, sError, MAX_TEXT_LENGTH ); + break; + case ERROR_INSTALL_USEREXIT: + WIN::LoadString( m_hInst, IDS_USER_CANCELLED, sError, MAX_TEXT_LENGTH ); + break; + case ERROR_INSTALL_ALREADY_RUNNING: // 1618 + WIN::LoadString( m_hInst, IDS_ALREADY_RUNNING, sError, MAX_TEXT_LENGTH ); + break; + case ERROR_INSTALL_SOURCE_ABSENT: + WIN::LoadString( m_hInst, IDS_NOMSI, sError, MAX_TEXT_LENGTH ); + break; + case ERROR_DS_INSUFF_ACCESS_RIGHTS: // 8344 + WIN::LoadString( m_hInst, IDS_REQUIRES_ADMIN_PRIV, sError, MAX_TEXT_LENGTH ); + break; + case E_ABORT: WIN::LoadString( m_hInst, IDS_UNKNOWN_ERROR, sError, MAX_TEXT_LENGTH ); + break; + case ERROR_INVALID_PARAMETER: // 87 + WIN::LoadString( m_hInst, IDS_INVALID_PARAM, sTmp, MAX_TEXT_LENGTH ); + StringCchPrintf( sError, MAX_TEXT_LENGTH, sTmp, m_pErrorText ); + break; + + case ERROR_SETUP_TO_OLD: // - 3 + WIN::LoadString( m_hInst, IDS_SETUP_TO_OLD, sTmp, MAX_TEXT_LENGTH ); + StringCchPrintf( sError, MAX_TEXT_LENGTH, sTmp, m_pReqVersion, m_pErrorText ); + break; + case ERROR_SETUP_NOT_FOUND: // - 4 + WIN::LoadString( m_hInst, IDS_SETUP_NOT_FOUND, sTmp, MAX_TEXT_LENGTH ); + StringCchPrintf( sError, MAX_TEXT_LENGTH, sTmp, m_pReqVersion ); + break; + case ERROR_SHOW_USAGE: // - 2 + nMsgType = MB_OK | MB_ICONINFORMATION; + WIN::LoadString( m_hInst, IDS_USAGE, sError, MAX_TEXT_LENGTH ); + break; + + default: WIN::LoadString( m_hInst, IDS_UNKNOWN_ERROR, sError, MAX_TEXT_LENGTH ); + break; + } + + if ( sError[0] ) + { + if ( !m_bQuiet ) + { + ConvertNewline( sError ); + WIN::MessageBox( NULL, sError, m_pAppTitle, nMsgType ); + } + + Log( TEXT( "ERROR: %s\r\n" ), sError ); + } +} + +//-------------------------------------------------------------------------- +long SetupAppX::GetLanguageID( long nIndex ) const +{ + if ( nIndex >=0 && nIndex < m_nLanguageCount ) + return m_ppLanguageList[ nIndex ]->m_nLanguageID; + else + return 0; +} + +//-------------------------------------------------------------------------- +void SetupAppX::GetLanguageName( long nLanguage, LPTSTR sName ) const +{ + switch ( nLanguage ) + { + case 1028: WIN::LoadString( m_hInst, IDS_LANGUAGE_ZH_TW, sName, MAX_LANGUAGE_LEN ); break; + case 1029: WIN::LoadString( m_hInst, IDS_LANGUAGE_CS, sName, MAX_LANGUAGE_LEN ); break; + case 1030: WIN::LoadString( m_hInst, IDS_LANGUAGE_DA, sName, MAX_LANGUAGE_LEN ); break; + case 1031: WIN::LoadString( m_hInst, IDS_LANGUAGE_DE_DE, sName, MAX_LANGUAGE_LEN ); break; + case 1032: WIN::LoadString( m_hInst, IDS_LANGUAGE_EL, sName, MAX_LANGUAGE_LEN ); break; + case 1033: WIN::LoadString( m_hInst, IDS_LANGUAGE_EN_US, sName, MAX_LANGUAGE_LEN ); break; + case 1034: WIN::LoadString( m_hInst, IDS_LANGUAGE_ES, sName, MAX_LANGUAGE_LEN ); break; + case 1035: WIN::LoadString( m_hInst, IDS_LANGUAGE_FI, sName, MAX_LANGUAGE_LEN ); break; + case 1036: WIN::LoadString( m_hInst, IDS_LANGUAGE_FR_FR, sName, MAX_LANGUAGE_LEN ); break; + case 1037: WIN::LoadString( m_hInst, IDS_LANGUAGE_HE, sName, MAX_LANGUAGE_LEN ); break; + case 1038: WIN::LoadString( m_hInst, IDS_LANGUAGE_HU, sName, MAX_LANGUAGE_LEN ); break; + case 1040: WIN::LoadString( m_hInst, IDS_LANGUAGE_IT_IT, sName, MAX_LANGUAGE_LEN ); break; + case 1041: WIN::LoadString( m_hInst, IDS_LANGUAGE_JA, sName, MAX_LANGUAGE_LEN ); break; + case 1042: WIN::LoadString( m_hInst, IDS_LANGUAGE_KO, sName, MAX_LANGUAGE_LEN ); break; + case 1043: WIN::LoadString( m_hInst, IDS_LANGUAGE_NL_NL, sName, MAX_LANGUAGE_LEN ); break; + case 1044: WIN::LoadString( m_hInst, IDS_LANGUAGE_NO_NO, sName, MAX_LANGUAGE_LEN ); break; + case 1045: WIN::LoadString( m_hInst, IDS_LANGUAGE_PL, sName, MAX_LANGUAGE_LEN ); break; + case 1046: WIN::LoadString( m_hInst, IDS_LANGUAGE_PT_BR, sName, MAX_LANGUAGE_LEN ); break; + case 1049: WIN::LoadString( m_hInst, IDS_LANGUAGE_RU, sName, MAX_LANGUAGE_LEN ); break; + case 1051: WIN::LoadString( m_hInst, IDS_LANGUAGE_SK, sName, MAX_LANGUAGE_LEN ); break; + case 1053: WIN::LoadString( m_hInst, IDS_LANGUAGE_SV_SE, sName, MAX_LANGUAGE_LEN ); break; + case 1054: WIN::LoadString( m_hInst, IDS_LANGUAGE_TH, sName, MAX_LANGUAGE_LEN ); break; + case 1055: WIN::LoadString( m_hInst, IDS_LANGUAGE_TR, sName, MAX_LANGUAGE_LEN ); break; + case 1061: WIN::LoadString( m_hInst, IDS_LANGUAGE_ET, sName, MAX_LANGUAGE_LEN ); break; + case 2052: WIN::LoadString( m_hInst, IDS_LANGUAGE_ZH_CN, sName, MAX_LANGUAGE_LEN ); break; + case 2070: WIN::LoadString( m_hInst, IDS_LANGUAGE_PT_PT, sName, MAX_LANGUAGE_LEN ); break; + + default: + { + TCHAR sTmp[ MAX_LANGUAGE_LEN ] = {0}; + + WIN::LoadString( m_hInst, IDS_UNKNOWN_LANG, sTmp, MAX_LANGUAGE_LEN ); + StringCchPrintf( sName, MAX_LANGUAGE_LEN, sTmp, nLanguage ); + } + } +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::CheckVersion() +{ + boolean bRet = false; + HMODULE hMsi = LoadMsiLibrary(); + + Log( TEXT( " Looking for installed MSI with version >= %s\r\n" ), m_pReqVersion ); + + if ( !hMsi ) + { + Log( TEXT( "Error: No MSI found!\r\n" ) ); + SetError( (UINT) ERROR_SETUP_NOT_FOUND ); + } + else + { + PFnDllGetVersion pDllGetVersion = (PFnDllGetVersion) GetProcAddress( hMsi, MSIAPI_DllGetVersion ); + + if ( pDllGetVersion ) + { + DLLVERSIONINFO aInfo; + + aInfo.cbSize = sizeof( DLLVERSIONINFO ); + if ( NOERROR == pDllGetVersion( &aInfo ) ) + { + TCHAR pMsiVersion[ VERSION_SIZE ]; + StringCchPrintf( pMsiVersion, VERSION_SIZE, TEXT("%d.%d.%4d"), + aInfo.dwMajorVersion, + aInfo.dwMinorVersion, + aInfo.dwBuildNumber ); + if ( _tcsncmp( pMsiVersion, m_pReqVersion, _tcslen( pMsiVersion ) ) < 0 ) + { + StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pMsiVersion ); + SetError( (UINT) ERROR_SETUP_TO_OLD ); + Log( TEXT( "Warning: Old MSI version found <%s>, update needed!\r\n" ), pMsiVersion ); + } + else + { + Log( TEXT( " Found MSI version <%s>, no update needed\r\n" ), pMsiVersion ); + bRet = true; + } + if ( aInfo.dwMajorVersion >= 3 ) + m_bSupportsPatch = true; + else + Log( TEXT("Warning: Patching not supported! MSI-Version <%s>\r\n"), pMsiVersion ); + } + } + + FreeLibrary( hMsi ); + } + + return bRet; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::CheckForUpgrade() +{ + // When we have patch files we will never try an Minor upgrade + if ( m_pPatchFiles ) return true; + + if ( !m_pUpgradeKey || ( _tcslen( m_pUpgradeKey ) == 0 ) ) + { + Log( TEXT( " No Upgrade Key Found -> continue with standard installation!\r\n" ) ); + return true; + } + + HKEY hInstKey = NULL; + + if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, m_pUpgradeKey, 0, KEY_READ, &hInstKey ) ) + { + Log( TEXT( " Found Upgrade Key in Registry (HKLM) -> will try minor upgrade!\r\n" ) ); + m_bIsMinorUpgrade = true; + } + else if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_CURRENT_USER, m_pUpgradeKey, 0, KEY_READ, &hInstKey ) ) + { + Log( TEXT( " Found Upgrade Key in Registry (HKCU) -> will try minor upgrade!\r\n" ) ); + m_bIsMinorUpgrade = true; + } + else + { + Log( TEXT( " Didn't Find Upgrade Key in Registry -> continue with standard installation!\r\n" ) ); + return true; + } + + if ( m_pProductVersion && ( _tcslen( m_pProductVersion ) > 0 ) ) + { + TCHAR *sProductVersion = new TCHAR[ MAX_PATH + 1 ]; + DWORD nSize = MAX_PATH + 1; + + sProductVersion[0] = '\0'; + + // get product version + if ( ERROR_SUCCESS == RegQueryValueEx( hInstKey, PRODUCT_VERSION, NULL, NULL, (LPBYTE)sProductVersion, &nSize ) ) + { + if ( lstrcmpi( sProductVersion, m_pProductVersion ) == 0 ) + { + Log( TEXT( " Same Product Version already installed, no minor upgrade!\r\n" ) ); + m_bIsMinorUpgrade = false; + } + } + + delete [] sProductVersion; + } + + return true; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::IsTerminalServerInstalled() const +{ + boolean bIsTerminalServer = false; + + const TCHAR sSearchStr[] = TEXT("Terminal Server"); + const TCHAR sKey[] = TEXT("System\\CurrentControlSet\\Control\\ProductOptions"); + const TCHAR sValue[] = TEXT("ProductSuite"); + + DWORD dwSize = 0; + HKEY hKey = 0; + DWORD dwType = 0; + + if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, sKey, 0, KEY_READ, &hKey ) && + ERROR_SUCCESS == RegQueryValueEx( hKey, sValue, NULL, &dwType, NULL, &dwSize ) && + dwSize > 0 && + REG_MULTI_SZ == dwType ) + { + TCHAR* sSuiteList = new TCHAR[ (dwSize*sizeof(byte)/sizeof(TCHAR)) + 1 ]; + + ZeroMemory(sSuiteList, dwSize); + + if ( ERROR_SUCCESS == RegQueryValueEx( hKey, sValue, NULL, &dwType, (LPBYTE)sSuiteList, &dwSize) ) + { + DWORD nMulti = 0; + DWORD nSrch = lstrlen( sSearchStr ); + const TCHAR *sSubString = sSuiteList; + + while (*sSubString) + { + nMulti = lstrlen( sSubString ); + if ( nMulti == nSrch && 0 == lstrcmp( sSearchStr, sSubString ) ) + { + bIsTerminalServer = true; + break; + } + + sSubString += (nMulti + 1); + } + } + delete [] sSuiteList; + } + + if ( hKey ) + RegCloseKey( hKey ); + + return bIsTerminalServer; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::AlreadyRunning() const +{ + if ( m_bIgnoreAlreadyRunning ) + { + Log( TEXT("Ignoring already running MSI instance!\r\n") ); + return false; + } + + const TCHAR *sMutexName = NULL; + const TCHAR sGUniqueName[] = TEXT( "Global\\_MSISETUP_{EA8130C1-8D3D-4338-9309-1A52D530D846}" ); + const TCHAR sUniqueName[] = TEXT( "_MSISETUP_{EA8130C1-8D3D-4338-9309-1A52D530D846}" ); + + if ( ( GetOSVersion() < 5 ) && ! IsTerminalServerInstalled() ) + sMutexName = sUniqueName; + else + sMutexName = sGUniqueName; + + HANDLE hMutex = 0; + + hMutex = WIN::CreateMutex( NULL, FALSE, sMutexName ); + + if ( !hMutex || ERROR_ALREADY_EXISTS == WIN::GetLastError() ) + { + if ( !hMutex ) + Log( TEXT( "ERROR: AlreadyRunning() could not create mutex!\r\n" ) ); + else + Log( TEXT( "ERROR: There's already a setup running!\r\n" ) ); + + return true; + } + Log( TEXT( " No running Setup found\r\n" ) ); + + return false; +} + +//-------------------------------------------------------------------------- +DWORD SetupAppX::WaitForProcess( HANDLE hHandle ) +{ + DWORD nResult = NOERROR; + boolean bLoop = true; + + MSG aMsg; + ZeroMemory( (void*) &aMsg, sizeof(MSG) ); + + while ( bLoop ) + { + switch ( WIN::MsgWaitForMultipleObjects( 1, &hHandle, false, + INFINITE, QS_ALLINPUT ) ) + { + case WAIT_OBJECT_0: bLoop = false; + break; + + case (WAIT_OBJECT_0 + 1): + { + if ( WIN::PeekMessage( &aMsg, NULL, NULL, NULL, PM_REMOVE ) ) + { + WIN::TranslateMessage( &aMsg ); + WIN::DispatchMessage( &aMsg ); + } + break; + } + + default: + { + nResult = WIN::GetLastError(); + bLoop = false; + } + } + } + + return nResult; +} + +//-------------------------------------------------------------------------- +void SetupAppX::Log( LPCTSTR pMessage, LPCTSTR pText ) const +{ + if ( m_pLogFile ) + { + static boolean bInit = false; + + if ( !bInit ) + { + bInit = true; + _ftprintf( m_pLogFile, TEXT("%c"), 0xfeff ); + + _tsetlocale( LC_ALL, TEXT("") ); + _ftprintf( m_pLogFile, TEXT("\nCodepage=%s\nMultiByte Codepage=[%d]\n"), + _tsetlocale( LC_ALL, NULL ), _getmbcp() ); + } + if ( pText ) + { + _ftprintf( m_pLogFile, pMessage, pText ); + OutputDebugStringFormat( pMessage, pText ); + } + else + { + _ftprintf( m_pLogFile, pMessage ); + OutputDebugStringFormat( pMessage ); + } + + fflush( m_pLogFile ); + } +} + +//-------------------------------------------------------------------------- +DWORD SetupAppX::GetNextArgument( LPCTSTR pStr, LPTSTR *pArg, LPTSTR *pNext, + boolean bStripQuotes ) +{ + boolean bInQuotes = false; + boolean bFoundArgEnd = false; + LPCTSTR pChar = pStr; + LPCTSTR pFirst = NULL; + + if ( NULL == pChar ) + return ERROR_NO_MORE_ITEMS; + + while ( ' ' == (*pChar) || '\t' == (*pChar) ) + pChar = CharNext( pChar ); + + if ( '\0' == (*pChar) ) + return ERROR_NO_MORE_ITEMS; + + int nCount = 1; + pFirst = pChar; + + while ( ! bFoundArgEnd ) + { + if ( '\0' == (*pChar) ) + bFoundArgEnd = true; + else if ( !bInQuotes && ' ' == (*pChar) ) + bFoundArgEnd = true; + else if ( !bInQuotes && '\t' == (*pChar) ) + bFoundArgEnd = true; + else + { + if ( '\"' == (*pChar) ) + { + bInQuotes = !bInQuotes; + if ( bStripQuotes ) + { + if ( pChar == pFirst ) + pFirst = CharNext( pFirst ); + nCount -= 1; + } + } + + pChar = CharNext( pChar ); + nCount += 1; + } + } + + if ( pArg ) + { + *pArg = new TCHAR[ nCount ]; + StringCchCopyN ( *pArg, nCount, pFirst, nCount-1 ); + } + + if ( pNext ) + *pNext = CharNext( pChar ); + + return ERROR_SUCCESS; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::GetCmdLineParameters( LPTSTR *pCmdLine ) +{ + int nRet = ERROR_SUCCESS; + LPTSTR pStart = NULL; + LPTSTR pNext = NULL; + + if ( GetNextArgument( *pCmdLine, NULL, &pNext ) != ERROR_SUCCESS ) + { + SetError( ERROR_NO_MORE_ITEMS ); + return false; + } + + int nSize = lstrlen( *pCmdLine ) + 2; + TCHAR *pNewCmdLine = new TCHAR[ nSize ]; + pNewCmdLine[0] = '\0'; + + while ( GetNextArgument( pNext, &pStart, &pNext ) == ERROR_SUCCESS ) + { + boolean bDeleteStart = true; + + if ( (*pStart) == '/' || (*pStart) == '-' ) + { + LPTSTR pSub = CharNext( pStart ); + if ( (*pSub) == 'l' || (*pSub) == 'L' ) + { + pSub = CharNext( pSub ); + if ( (*pSub) == 'a' || (*pSub) == 'A' ) + { // --- handle the lang parameter --- + LPTSTR pLanguage = NULL; + LPTSTR pLastChar; + if ( GetNextArgument( pNext, &pLanguage, &pNext, true ) != ERROR_SUCCESS ) + { + StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pStart ); + nRet = ERROR_INVALID_PARAMETER; + break; + } + + m_nLanguageID = _tcstol( pLanguage, &pLastChar, 10 ); + delete [] pLanguage; + } + else + { // --- handle the l(og) parameter --- + boolean bAppend = false; + LPTSTR pFileName = NULL; + + while ( *pSub ) + { + if ( *pSub == '+' ) + { + bAppend = true; + break; + } + pSub = CharNext( pSub ); + } + + if ( GetNextArgument( pNext, &pFileName, &pNext, true ) != ERROR_SUCCESS ) + { + StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pStart ); + nRet = ERROR_INVALID_PARAMETER; + break; + } + + if ( FAILED( StringCchCat( pNewCmdLine, nSize, pStart ) ) ) + { + nRet = ERROR_OUTOFMEMORY; + break; + } + // we need to append a '+' otherwise msiexec would overwrite our log file + if ( !bAppend && FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( "+" ) ) ) ) + { + nRet = ERROR_OUTOFMEMORY; + break; + } + if ( FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( " \"" ) ) ) || + FAILED( StringCchCat( pNewCmdLine, nSize, pFileName ) ) || + FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( "\" " ) ) ) ) + { + nRet = ERROR_OUTOFMEMORY; + break; + } + + if ( bAppend ) + m_pLogFile = _tfopen( pFileName, TEXT( "ab" ) ); + else + m_pLogFile = _tfopen( pFileName, TEXT( "wb" ) ); + + delete [] pFileName; + } + } + else if ( (*pSub) == 'q' || (*pSub) == 'Q' ) + { // --- Handle quiet file parameter --- + pSub = CharNext( pSub ); + if ( ! (*pSub) || (*pSub) == 'n' || (*pSub) == 'N' ) + m_bQuiet = true; + + if ( FAILED( StringCchCat( pNewCmdLine, nSize, pStart ) ) || + FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( " " ) ) ) ) + { + nRet = ERROR_OUTOFMEMORY; + break; + } + } + else if ( _tcsnicmp( pSub, PARAM_RUNNING, _tcslen( PARAM_RUNNING ) ) == 0 ) + { + m_bIgnoreAlreadyRunning = true; + } + else if ( _tcsnicmp( pSub, CMDLN_REG_ALL_MSO_TYPES, _tcslen( CMDLN_REG_ALL_MSO_TYPES ) ) == 0 ) + { + m_bRegAllMsoTypes = true; + } + else if ( _tcsnicmp( pSub, CMDLN_REG_NO_MSO_TYPES, _tcslen( CMDLN_REG_NO_MSO_TYPES ) ) == 0 ) + { + m_bRegNoMsoTypes = true; + } + else if ( (*pSub) == 'i' || (*pSub) == 'I' || (*pSub) == 'f' || (*pSub) == 'F' || + (*pSub) == 'p' || (*pSub) == 'P' || (*pSub) == 'x' || (*pSub) == 'X' || + (*pSub) == 'y' || (*pSub) == 'Y' || (*pSub) == 'z' || (*pSub) == 'Z' ) + { + StringCchCopy( m_pErrorText, MAX_TEXT_LENGTH, pStart ); + nRet = ERROR_INVALID_PARAMETER; + break; + } + else if ( (*pSub) == 'a' || (*pSub) == 'A' ) + { // --- Handle Adminstrative Installation --- + SetAdminInstall( true ); + } + else if ( (*pSub) == 'j' || (*pSub) == 'J' ) + { // --- Handle Adminstrative Installation --- + m_pAdvertise = pStart; + m_bQuiet = true; + bDeleteStart = false; + } + else if ( (*pSub) == '?' || (*pSub) == 'h' || (*pSub) == 'H' ) + { // --- Handle Show Usage --- + nRet = ERROR_SHOW_USAGE; + break; + } + else + { + if ( FAILED( StringCchCat( pNewCmdLine, nSize, pStart ) ) || + FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( " " ) ) ) ) + { + nRet = ERROR_OUTOFMEMORY; + break; + } + } + } + else + { + if ( FAILED( StringCchCat( pNewCmdLine, nSize, pStart ) ) || + FAILED( StringCchCat( pNewCmdLine, nSize, TEXT( " " ) ) ) ) + { + nRet = ERROR_OUTOFMEMORY; + break; + } + } + + if ( bDeleteStart ) delete [] pStart; + pStart = NULL; + } + + if ( pStart ) delete [] pStart; + + *pCmdLine = pNewCmdLine; + + if ( nRet != ERROR_SUCCESS ) + { + SetError( nRet ); + return false; + } + else + return true;; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::IsAdmin() +{ + PSID aPsidAdmin; + SID_IDENTIFIER_AUTHORITY aAuthority = SECURITY_NT_AUTHORITY; + + if ( !AllocateAndInitializeSid( &aAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, + &aPsidAdmin ) ) + return false; + + BOOL bIsAdmin = FALSE; + + if ( GetOSVersion() >= 5 ) + { + HMODULE hAdvapi32 = LoadLibrary( ADVAPI32_DLL ); + + if ( !hAdvapi32 ) + bIsAdmin = FALSE; + else + { + PFnCheckTokenMembership pfnCheckTokenMembership = (PFnCheckTokenMembership) GetProcAddress( hAdvapi32, ADVAPI32API_CheckTokenMembership); + if ( !pfnCheckTokenMembership || !pfnCheckTokenMembership( NULL, aPsidAdmin, &bIsAdmin ) ) + bIsAdmin = FALSE; + } + FreeLibrary( hAdvapi32 ); + } + else + { + // NT4, check groups of user + HANDLE hAccessToken = 0; + UCHAR *szInfoBuffer = new UCHAR[ 1024 ]; // may need to resize if TokenInfo too big + DWORD dwInfoBufferSize = 1024; + DWORD dwRetInfoBufferSize = 0; + UINT i=0; + + if ( WIN::OpenProcessToken( WIN::GetCurrentProcess(), TOKEN_READ, &hAccessToken ) ) + { + bool bSuccess = false; + bSuccess = WIN::GetTokenInformation( hAccessToken, TokenGroups, + szInfoBuffer, dwInfoBufferSize, + &dwRetInfoBufferSize ) == TRUE; + + if( dwRetInfoBufferSize > dwInfoBufferSize ) + { + delete [] szInfoBuffer; + szInfoBuffer = new UCHAR[ dwRetInfoBufferSize ]; + dwInfoBufferSize = dwRetInfoBufferSize; + bSuccess = WIN::GetTokenInformation( hAccessToken, TokenGroups, + szInfoBuffer, dwInfoBufferSize, + &dwRetInfoBufferSize ) == TRUE; + } + + WIN::CloseHandle( hAccessToken ); + + if ( bSuccess ) + { + PTOKEN_GROUPS pGroups = (PTOKEN_GROUPS)(UCHAR*) szInfoBuffer; + for( i=0; i<pGroups->GroupCount; i++ ) + { + if( WIN::EqualSid( aPsidAdmin, pGroups->Groups[i].Sid ) ) + { + bIsAdmin = TRUE; + break; + } + } + } + + delete [] szInfoBuffer; + } + } + + WIN::FreeSid( aPsidAdmin ); + + return bIsAdmin ? true : false; +} + +//-------------------------------------------------------------------------- +LPTSTR SetupAppX::CopyIniFile( LPCTSTR pIniFile ) +{ + m_pTmpName = _ttempnam( TEXT( "C:\\" ), TEXT( "Setup" ) ); + + if ( !m_pTmpName ) + { + Log( TEXT( "ERROR: Could not create temp file\n" ) ); + return NULL; + } + + FILE *pOut = _tfopen( m_pTmpName, TEXT( "wb" ) ); + FILE *pIn = _tfopen( pIniFile, TEXT( "rb" ) ); + + if ( pOut && pIn ) + { + size_t nRead, nWritten; + BYTE pBuf[1024]; + + nRead = fread( pBuf, sizeof( BYTE ), 1024, pIn ); + while ( nRead && !ferror( pIn ) ) + { + nWritten = fwrite( pBuf, sizeof( BYTE ), nRead, pOut ); + if ( nWritten != nRead ) + { + Log( TEXT( "ERROR: Could not write all bytes to temp file\n" ) ); + break; + } + nRead = fread( pBuf, sizeof( BYTE ), 1024, pIn ); + } + } + + if ( pOut ) fclose( pOut ); + if ( pIn ) fclose( pIn ); + + return m_pTmpName; +} + +//-------------------------------------------------------------------------- +void SetupAppX::ConvertNewline( LPTSTR pText ) const +{ + int i=0; + + while ( pText[i] != 0 ) + { + if ( ( pText[i] == '\\' ) && ( pText[i+1] == 'n' ) ) + { + pText[i] = 0x0d; + pText[i+1] = 0x0a; + i+=2; + } + else + i+=1; + } +} + +//-------------------------------------------------------------------------- +LPTSTR SetupAppX::SetProdToAppTitle( LPCTSTR pProdName ) +{ + if ( !pProdName ) return m_pAppTitle; + + LPTSTR pAppProdTitle = new TCHAR[ MAX_STR_CAPTION ]; + pAppProdTitle[0] = '\0'; + + WIN::LoadString( m_hInst, IDS_APP_PROD_TITLE, pAppProdTitle, MAX_STR_CAPTION ); + + int nAppLen = lstrlen( pAppProdTitle ); + int nProdLen = lstrlen( pProdName ); + + if ( ( nAppLen == 0 ) || ( nProdLen == 0 ) ) + { + delete [] pAppProdTitle; + return m_pAppTitle; + } + + int nLen = nAppLen + nProdLen + 3; + + if ( nLen > STRSAFE_MAX_CCH ) return m_pAppTitle; + + LPTSTR pIndex = _tcsstr( pAppProdTitle, PRODUCT_NAME_VAR ); + + if ( pIndex ) + { + int nOffset = pIndex - pAppProdTitle; + int nVarLen = lstrlen( PRODUCT_NAME_VAR ); + + LPTSTR pNewTitle = new TCHAR[ nLen ]; + pNewTitle[0] = '\0'; + + if ( nOffset > 0 ) + { + StringCchCopyN( pNewTitle, nLen, pAppProdTitle, nOffset ); + } + + StringCchCat( pNewTitle, nLen, pProdName ); + + if ( nOffset + nVarLen < nAppLen ) + { + StringCchCat( pNewTitle, nLen, pIndex + nVarLen ); + } + + delete [] m_pAppTitle; + m_pAppTitle = pNewTitle; + } + + delete [] pAppProdTitle; + + return m_pAppTitle; +} + + +//-------------------------------------------------------------------------- +boolean SetupAppX::IsPatchInstalled( TCHAR* pBaseDir, TCHAR* pFileName ) +{ + if ( !m_bSupportsPatch ) + return false; + + PMSIHANDLE hSummaryInfo; + int nLen = lstrlen( pBaseDir ) + lstrlen( pFileName ) + 1; + TCHAR *szDatabasePath = new TCHAR [ nLen ]; + TCHAR sBuf[80]; + + StringCchCopy( szDatabasePath, nLen, pBaseDir ); + StringCchCat( szDatabasePath, nLen, pFileName ); + + UINT nRet = MsiGetSummaryInformation( NULL, szDatabasePath, 0, &hSummaryInfo ); + + if ( nRet != ERROR_SUCCESS ) + { + StringCchPrintf( sBuf, 80, TEXT("ERROR: IsPatchInstalled: MsiGetSummaryInformation returned %u.\r\n"), nRet ); + Log( sBuf ); + return false; + } + + UINT uiDataType; + LPTSTR szPatchID = new TCHAR[ 64 ]; + DWORD cchValueBuf = 64; + nRet = MsiSummaryInfoGetProperty( hSummaryInfo, PID_REVNUMBER, &uiDataType, NULL, NULL, szPatchID, &cchValueBuf ); + + if ( nRet != ERROR_SUCCESS ) + { + StringCchPrintf( sBuf, 80, TEXT("ERROR: IsPatchInstalled: MsiSummaryInfoGetProperty returned %u.\r\n"), nRet ); + Log( sBuf ); + return false; + } + + nRet = MsiGetPatchInfo( szPatchID, INSTALLPROPERTY_LOCALPACKAGE, NULL, NULL ); + + StringCchPrintf( sBuf, 80, TEXT(" GetPatchInfo for (%s) returned (%u)\r\n"), szPatchID, nRet ); + Log( sBuf ); + + delete []szPatchID; + + if ( nRet == ERROR_BAD_CONFIGURATION ) + return false; + else if ( nRet == ERROR_INVALID_PARAMETER ) + return false; + else if ( nRet == ERROR_MORE_DATA ) + return true; + else if ( nRet == ERROR_SUCCESS ) + return true; + else if ( nRet == ERROR_UNKNOWN_PRODUCT ) + return false; + else if ( nRet == ERROR_UNKNOWN_PROPERTY ) + return false; + else return false; + + return false; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::InstallRuntimes( TCHAR *sProductCode, TCHAR *sRuntimePath ) +{ + INSTALLSTATE nRet = MsiQueryProductState( sProductCode ); + OutputDebugStringFormat( TEXT( "MsiQueryProductState returned <%d>\r\n" ), nRet ); + if ( nRet == INSTALLSTATE_DEFAULT ) + return true; + + Log( TEXT( " Will install runtime <%s>\r\n" ), sRuntimePath ); + OutputDebugStringFormat( TEXT( " Will install runtime <%s>\r\n" ), sRuntimePath ); + + STARTUPINFO aSUI; + PROCESS_INFORMATION aPI; + + ZeroMemory( (void*)&aPI, sizeof( PROCESS_INFORMATION ) ); + ZeroMemory( (void*)&aSUI, sizeof( STARTUPINFO ) ); + + aSUI.cb = sizeof(STARTUPINFO); + aSUI.dwFlags = STARTF_USESHOWWINDOW; + aSUI.wShowWindow = SW_SHOW; + + DWORD nCmdLineLength = lstrlen( sRuntimePath ) + lstrlen( PARAM_SILENTINSTALL ) + 2; + TCHAR *sCmdLine = new TCHAR[ nCmdLineLength ]; + + if ( FAILED( StringCchCopy( sCmdLine, nCmdLineLength, sRuntimePath ) ) || + FAILED( StringCchCat( sCmdLine, nCmdLineLength, PARAM_SILENTINSTALL ) ) ) + { + delete [] sCmdLine; + SetError( ERROR_INSTALL_FAILURE ); + return false; + } + + if ( !WIN::CreateProcess( NULL, sCmdLine, NULL, NULL, FALSE, + CREATE_DEFAULT_ERROR_MODE, NULL, NULL, + &aSUI, &aPI ) ) + { + Log( TEXT( "ERROR: Could not create process %s.\r\n" ), sCmdLine ); + SetError( WIN::GetLastError() ); + delete [] sCmdLine; + return false; + } + + DWORD nResult = WaitForProcess( aPI.hProcess ); + bool bRet = true; + + if( ERROR_SUCCESS != nResult ) + { + Log( TEXT( "ERROR: While waiting for %s.\r\n" ), sCmdLine ); + SetError( nResult ); + bRet = false; + } + else + { + GetExitCodeProcess( aPI.hProcess, &nResult ); + SetError( nResult ); + + if ( nResult != ERROR_SUCCESS ) + { + TCHAR sBuf[80]; + StringCchPrintf( sBuf, 80, TEXT("Warning: install runtime returned %u.\r\n"), nResult ); + Log( sBuf ); + } + else + Log( TEXT( " Installation of runtime completed successfully.\r\n" ) ); + } + + CloseHandle( aPI.hProcess ); + + delete [] sCmdLine; + + return bRet; +} + +//-------------------------------------------------------------------------- +boolean SetupAppX::InstallRuntimes() +{ + TCHAR *sRuntimePath = 0; + SYSTEM_INFO siSysInfo; + + HMODULE hKernel32 = ::LoadLibrary(_T("Kernel32.dll")); + if ( hKernel32 != NULL ) + { + typedef void (CALLBACK* pfnGetNativeSystemInfo_t)(LPSYSTEM_INFO); + pfnGetNativeSystemInfo_t pfnGetNativeSystemInfo; + pfnGetNativeSystemInfo = (pfnGetNativeSystemInfo_t)::GetProcAddress(hKernel32, "GetNativeSystemInfo"); + if ( pfnGetNativeSystemInfo != NULL ) + { + pfnGetNativeSystemInfo(&siSysInfo); + } + else + { + // GetNativeSystemInfo does not exist. Maybe the code is running under Windows 2000. + // Use GetSystemInfo instead. + GetSystemInfo(&siSysInfo); + } + FreeLibrary(hKernel32); + } + else + { + // Failed to check Kernel32.dll. There may be something wrong. + // Use GetSystemInfo instead anyway. + GetSystemInfo(&siSysInfo); + } + + OutputDebugStringFormat( TEXT( "found architecture<%d>\r\n" ), siSysInfo.wProcessorArchitecture ); + + if ( siSysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ) + { + if ( GetPathToFile( RUNTIME_X64_NAME, &sRuntimePath ) ) + InstallRuntimes( PRODUCTCODE_X64, sRuntimePath ); + else + Log( TEXT( "ERROR: no installer for x64 runtime libraries found!" ) ); + + if ( sRuntimePath ) + { + delete [] sRuntimePath; + sRuntimePath = 0; + } + } + + if ( GetPathToFile( RUNTIME_X86_NAME, &sRuntimePath ) ) + InstallRuntimes( PRODUCTCODE_X86, sRuntimePath ); + else + Log( TEXT( "ERROR: no installer for x86 runtime libraries found!" ) ); + + if ( sRuntimePath ) + delete [] sRuntimePath; + + return true; +} + +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- +LanguageDataX::LanguageDataX( LPTSTR pData ) +{ + m_nLanguageID = 0; + m_pTransform = NULL; + + LPTSTR pLastChar; + + m_nLanguageID = _tcstol( pData, &pLastChar, 10 ); + + if ( *pLastChar == ',' ) + { + pLastChar += 1; + int nLen = lstrlen( pLastChar ) + 1; + m_pTransform = new TCHAR [ nLen ]; + StringCchCopy( m_pTransform, nLen, pLastChar ); + } +} + +//-------------------------------------------------------------------------- +LanguageDataX::~LanguageDataX() +{ + if ( m_pTransform ) delete [] m_pTransform; +} + +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- +SetupApp* Create_SetupAppX() +{ + return new SetupAppX; +} + +//-------------------------------------------------------------------------- + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/setup/setup.hxx b/desktop/win32/source/setup/setup.hxx new file mode 100644 index 000000000000..6eccda100699 --- /dev/null +++ b/desktop/win32/source/setup/setup.hxx @@ -0,0 +1,157 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "setup_main.hxx" + +//-------------------------------------------------------------------------- + +#ifdef SetupAppX + #undef SetupAppX +#endif + +#ifdef Create_SetupAppX + #undef Create_SetupAppX +#endif + +#ifdef LanguageDataX + #undef LanguageDataX +#endif + + +#ifdef UNICODE + #define SetupAppX SetupAppW + #define Create_SetupAppX Create_SetupAppW + #define LanguageDataX LanguageDataW +#else + #define SetupAppX SetupAppA + #define Create_SetupAppX Create_SetupAppA + #define LanguageDataX LanguageDataA +#endif + +//-------------------------------------------------------------------------- + +struct LanguageDataX +{ + long m_nLanguageID; + LPTSTR m_pTransform; + + LanguageDataX( LPTSTR pData ); + ~LanguageDataX(); +}; + +//-------------------------------------------------------------------------- + +class SetupAppX : public SetupApp +{ + HINSTANCE m_hInst; + HANDLE m_hMapFile; + LPTSTR m_pAppTitle; + LPTSTR m_pCmdLine; + LPTSTR m_pDatabase; + LPTSTR m_pReqVersion; + LPTSTR m_pProductName; + LPTSTR m_pAdvertise; + LPTSTR m_pTmpName; + LPTSTR m_pErrorText; + LPTSTR m_pModuleFile; + LPTSTR m_pPatchFiles; + LPCTSTR m_pUpgradeKey; + LPCTSTR m_pProductVersion; + int *m_pMSIErrorCode; + + boolean m_bQuiet : 1; + boolean m_bIgnoreAlreadyRunning : 1; + boolean m_bRegNoMsoTypes :1; + boolean m_bRegAllMsoTypes :1; + boolean m_bIsMinorUpgrade :1; + boolean m_bSupportsPatch :1; + + FILE *m_pLogFile; + + long m_nLanguageID; + long m_nLanguageCount; + LanguageDataX** m_ppLanguageList; + +private: + + boolean GetPathToFile( TCHAR* pFileName, TCHAR **pPath ); + LPCTSTR GetPathToMSI(); + + int GetNameValue( TCHAR* pLine, TCHAR **pName, TCHAR **pValue ); + boolean GetProfileSection( LPCTSTR pFileName, LPCTSTR pSection, + DWORD& rSize, LPTSTR *pRetBuf ); + LPTSTR CopyIniFile( LPCTSTR pIniFile ); + void ConvertNewline( LPTSTR pText ) const; + + boolean LaunchInstaller( LPCTSTR pParam ); + HMODULE LoadMsiLibrary(); + DWORD WaitForProcess( HANDLE hHandle ); + + boolean GetCmdLineParameters( LPTSTR *pCmdLine ); + DWORD GetNextArgument( LPCTSTR pStr, LPTSTR *pArg, + LPTSTR *pNext, boolean bStripQuotes = false ); + boolean IsAdmin(); + + boolean GetCommandLine(); + + boolean IsTerminalServerInstalled() const; + void AddFileToPatchList( TCHAR* pPath, TCHAR* pFile ); + boolean IsPatchInstalled( TCHAR* pBaseDir, TCHAR* pFileName ); + boolean InstallRuntimes( TCHAR* pProductCode, TCHAR* pFileName ); + +public: + SetupAppX(); + ~SetupAppX(); + + virtual boolean Initialize( HINSTANCE hInst ); + virtual boolean AlreadyRunning() const; + virtual boolean ReadProfile(); + virtual boolean GetPatches(); + virtual boolean ChooseLanguage( long& rLanguage ); + virtual boolean CheckVersion(); + virtual boolean CheckForUpgrade(); + virtual boolean InstallRuntimes(); + virtual boolean Install( long nLanguage ); + + virtual UINT GetError() const; + virtual void DisplayError( UINT nErr ) const; + + void Log( LPCTSTR pMessage, LPCTSTR pText = NULL ) const; + + long GetLanguageCount() const { return m_nLanguageCount; } + long GetLanguageID( long nIndex ) const; + void GetLanguageName( long nLanguage, LPTSTR sName ) const; + + LPCTSTR GetAppTitle() const { return m_pAppTitle; } + LPTSTR SetProdToAppTitle( LPCTSTR pProdName ); + HINSTANCE GetHInst() const { return m_hInst; } +}; + +//-------------------------------------------------------------------------- + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/setup/setup.ico b/desktop/win32/source/setup/setup.ico Binary files differnew file mode 100644 index 000000000000..2a7ebda53a25 --- /dev/null +++ b/desktop/win32/source/setup/setup.ico diff --git a/desktop/win32/source/setup/setup.ulf b/desktop/win32/source/setup/setup.ulf new file mode 100644 index 000000000000..85d43f43aa55 --- /dev/null +++ b/desktop/win32/source/setup/setup.ulf @@ -0,0 +1,162 @@ +[%APP_TITLE%] +en-US = "Setup" + + +[%APP_PROD_TITLE%] +en-US = "The %PRODUCTNAME Setup" + + +[%OUTOFMEM%] +en-US = "Out of Memory" + + +[%NOMSI%] +en-US = "Setup was unable to find the msi package." + + +[%USER_CANCELLED%] +en-US = "Setup was cancelled" + + +[%REQUIRES_ADMIN_PRIV%] +en-US = "Administrator privileges are required for upgrading the Windows Installer." + + +[%FILE_NOT_FOUND%] +en-US = "Setup was unable to find the file '%s'." + + +[%INVALID_PARAM%] +en-US = "Invalid command line option '%s'. Please use '/?' for help." + + +[%SETUP_TO_OLD%] +en-US = "This package requires at least the version '%s' of the Windows Installer. \nYou have Windows Installer '%s' on your system!" + +[%SETUP_NOT_FOUND%] +en-US = "This package requires the Windows Installer. \nYou need at least Windows Installer '%s' on your system!" + + +[%USAGE%] +en-US = "Usage:\n /? : Shows this dialog.\n /a : Performs an administrative installation.\n /j[u|m] : Performs an advertising installation.\n /q[n] : Do not show any user interface (silent mode).\n" + + +[%ALREADY_RUNNING%] +en-US = "There is already a setup process running." + + +[%UNKNOWN_ERROR%] +en-US = "An Unknown Error occurred!" + + +[%INVALID_PROFILE%] +en-US = "Invalid or incomplete profile." + + +[%UNKNOWN_LANG%] +en-US = "Unknown Language: %d" + + +[%LANGUAGE_ZH_TW%] +en-US = "Chinese (traditional)" + + +[%LANGUAGE_CS%] +en-US = "Czech" + + +[%LANGUAGE_DA%] +en-US = "Danish" + + +[%LANGUAGE_DE_DE%] +en-US = "German (Germany)" + + +[%LANGUAGE_EL%] +en-US = "Greek" + + +[%LANGUAGE_EN_US%] +en-US = "English (USA)" + + +[%LANGUAGE_ES%] +en-US = "Spanish (Spain)" + + +[%LANGUAGE_FI%] +en-US = "Finnish" + + +[%LANGUAGE_FR_FR%] +en-US = "French (France)" + + +[%LANGUAGE_HE%] +en-US = "Hebrew" + + +[%LANGUAGE_HU%] +en-US = "Hungarian" + + +[%LANGUAGE_IT_IT%] +en-US = "Italian (Italy)" + + +[%LANGUAGE_JA%] +en-US = "Japanese" + + +[%LANGUAGE_KO%] +en-US = "Korean" + + +[%LANGUAGE_NL_NL%] +en-US = "Dutch (Netherlands)" + + +[%LANGUAGE_NO_NO%] +en-US = "Norwegian (Bokmål)" + + +[%LANGUAGE_PL%] +en-US = "Polish" + + +[%LANGUAGE_PT_BR%] +en-US = "Portuguese (Brazil)" + + +[%LANGUAGE_RU%] +en-US = "Russian" + + +[%LANGUAGE_SK%] +en-US = "Slovakian" + + +[%LANGUAGE_SV_SE%] +en-US = "Swedish (Sweden)" + + +[%LANGUAGE_TH%] +en-US = "Thai" + + +[%LANGUAGE_TR%] +en-US = "Turkish" + + +[%LANGUAGE_ET%] +en-US = "Estonian" + + +[%LANGUAGE_ZH_CN%] +en-US = "Chinese (Simplified)" + + +[%LANGUAGE_PT_PT%] +en-US = "Portuguese (Portugal)" + diff --git a/desktop/win32/source/setup/setup_a.cxx b/desktop/win32/source/setup/setup_a.cxx new file mode 100644 index 000000000000..a680673e1729 --- /dev/null +++ b/desktop/win32/source/setup/setup_a.cxx @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#include "setup.cpp" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/setup/setup_help.hxx b/desktop/win32/source/setup/setup_help.hxx new file mode 100644 index 000000000000..1330fa70f191 --- /dev/null +++ b/desktop/win32/source/setup/setup_help.hxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SETUP_HELP_HXX +#define SETUP_HELP_HXX + +//-------------------------------------------------------------------------- + + +#ifdef UNICODE +#else + #define LanguageDataX LanguageDataA +#endif + +//-------------------------------------------------------------------------- + +class SetupHelperX +{ +}; + +//-------------------------------------------------------------------------- + +#endif +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/setup/setup_main.cxx b/desktop/win32/source/setup/setup_main.cxx new file mode 100644 index 000000000000..0fb9aac2533e --- /dev/null +++ b/desktop/win32/source/setup/setup_main.cxx @@ -0,0 +1,142 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <new> + +#include "setup_main.hxx" + +//-------------------------------------------------------------------------- + +void __cdecl newhandler() +{ + throw std::bad_alloc(); + return; +} + +//-------------------------------------------------------------------------- + +SetupApp::SetupApp() +{ + m_uiRet = ERROR_SUCCESS; + + // Get OS version + OSVERSIONINFO sInfoOS; + + ZeroMemory( &sInfoOS, sizeof(OSVERSIONINFO) ); + sInfoOS.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + + GetVersionEx( &sInfoOS ); + + m_nOSVersion = sInfoOS.dwMajorVersion; + m_nMinorVersion = sInfoOS.dwMinorVersion; + m_bNeedReboot = false; + m_bAdministrative = false; +} + +//-------------------------------------------------------------------------- + +SetupApp::~SetupApp() +{ +} + +//-------------------------------------------------------------------------- + +extern "C" int __stdcall WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int ) +{ + // Get OS version + OSVERSIONINFO sInfoOS; + + ZeroMemory( &sInfoOS, sizeof(OSVERSIONINFO) ); + sInfoOS.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + + GetVersionEx( &sInfoOS ); + + SetupApp *pSetup; + + pSetup = Create_SetupAppW(); + + try + { + if ( ! pSetup->Initialize( hInst ) ) + throw pSetup->GetError(); + + if ( pSetup->AlreadyRunning() ) + throw (UINT) ERROR_INSTALL_ALREADY_RUNNING; + + if ( ! pSetup->ReadProfile() ) + throw pSetup->GetError(); + + if ( ! pSetup->CheckVersion() ) + throw pSetup->GetError(); + + if ( ! pSetup->IsAdminInstall() ) + if ( ! pSetup->GetPatches() ) + throw pSetup->GetError(); + + // CheckForUpgrade() has to be called after calling GetPatches()! + if ( ! pSetup->CheckForUpgrade() ) + throw pSetup->GetError(); + + long nLanguage; + + if ( ! pSetup->ChooseLanguage( nLanguage ) ) + throw pSetup->GetError(); + + if ( ! pSetup->InstallRuntimes() ) + throw pSetup->GetError(); + + if ( ! pSetup->Install( nLanguage ) ) + throw pSetup->GetError(); + } + catch ( std::bad_alloc ) + { + pSetup->DisplayError( ERROR_OUTOFMEMORY ); + } + catch ( UINT &nErr ) + { + pSetup->DisplayError( nErr ); + } + + int nRet = pSetup->GetError(); + + delete pSetup; + + return nRet; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/setup/setup_main.hxx b/desktop/win32/source/setup/setup_main.hxx new file mode 100644 index 000000000000..dfcb201e3cd3 --- /dev/null +++ b/desktop/win32/source/setup/setup_main.hxx @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef SETUP_MAIN_HXX +#define SETUP_MAIN_HXX + +class SetupApp +{ + DWORD m_nOSVersion; + DWORD m_nMinorVersion; + boolean m_bNeedReboot : 1; + boolean m_bAdministrative : 1; + +public: + UINT m_uiRet; + + SetupApp(); + virtual ~SetupApp(); + + virtual boolean Initialize( HINSTANCE hInst ) = 0; + virtual boolean AlreadyRunning() const = 0; + virtual boolean ReadProfile() = 0; + virtual boolean GetPatches() = 0; + virtual boolean ChooseLanguage( long& rLanguage ) = 0; + virtual boolean CheckVersion() = 0; + virtual boolean CheckForUpgrade() = 0; + virtual boolean InstallRuntimes() = 0; + virtual boolean Install( long nLanguage ) = 0; + + virtual UINT GetError() const = 0; + virtual void DisplayError( UINT nErr ) const = 0; + + void SetError( UINT nErr ) { m_uiRet = nErr; } + DWORD GetOSVersion() const { return m_nOSVersion; } + DWORD GetMinorVersion() const { return m_nMinorVersion; } + + boolean IsAdminInstall() { return m_bAdministrative; } + void SetAdminInstall( boolean bValue ) { m_bAdministrative = bValue; } + + void SetRebootNeeded( boolean bNeedReboot ) { m_bNeedReboot = bNeedReboot; } + boolean NeedReboot() const { return m_bNeedReboot; } +}; + +SetupApp* Create_SetupAppW(); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/setup/setup_w.cxx b/desktop/win32/source/setup/setup_w.cxx new file mode 100644 index 000000000000..9de15b2e535d --- /dev/null +++ b/desktop/win32/source/setup/setup_w.cxx @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#define UNICODE 1 +#define _UNICODE 1 + +#include "setup.cpp" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/sowrapper.cxx b/desktop/win32/source/sowrapper.cxx new file mode 100644 index 000000000000..f62536a86525 --- /dev/null +++ b/desktop/win32/source/sowrapper.cxx @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include "main.h" + +int APIENTRY WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) +{ + if ( (LONG)GetVersion() < 0 ) + return MainA(); + else + return MainW(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/unoinfo.cxx b/desktop/win32/source/unoinfo.cxx new file mode 100644 index 000000000000..0ce5c98b7215 --- /dev/null +++ b/desktop/win32/source/unoinfo.cxx @@ -0,0 +1,151 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <cstddef> +#include <stdio.h> +#include <stdlib.h> +#include <wchar.h> + +#define WIN32_LEAN_AND_MEAN +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include "tools/pathutils.hxx" + +#define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1) +#define MY_STRING(s) (s), MY_LENGTH(s) + +namespace { + +wchar_t * getBrandPath(wchar_t * path) { + DWORD n = GetModuleFileNameW(NULL, path, MAX_PATH); + if (n == 0 || n >= MAX_PATH) { + exit(EXIT_FAILURE); + } + return tools::filename(path); +} + +void writeNull() { + if (fwrite("\0\0", 1, 2, stdout) != 2) { + exit(EXIT_FAILURE); + } +} + +void writePath( + wchar_t const * frontBegin, wchar_t const * frontEnd, + wchar_t const * backBegin, std::size_t backLength) +{ + wchar_t path[MAX_PATH]; + wchar_t * end = tools::buildPath( + path, frontBegin, frontEnd, backBegin, backLength); + if (end == NULL) { + exit(EXIT_FAILURE); + } + std::size_t n = (end - path) * sizeof (wchar_t); + if (fwrite(path, 1, n, stdout) != n) { + exit(EXIT_FAILURE); + } +} + +} + +#ifdef __MINGW32__ +int main(int argc, char ** argv, char **) { + if (argc == 2 && strcmp(argv[1], "c++") == 0) { +#else +int wmain(int argc, wchar_t ** argv, wchar_t **) { + if (argc == 2 && wcscmp(argv[1], L"c++") == 0) { +#endif + wchar_t path[MAX_PATH]; + wchar_t * pathEnd = getBrandPath(path); + if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link")) + == NULL) + { + exit(EXIT_FAILURE); + } + pathEnd = tools::resolveLink(path); + if (pathEnd == NULL || + (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == + NULL)) + { + exit(EXIT_FAILURE); + } + pathEnd = tools::resolveLink(path); + if (pathEnd == NULL) { + exit(EXIT_FAILURE); + } + writePath(path, pathEnd, MY_STRING(L"\\bin")); +#ifdef __MINGW32__ + } else if (argc == 2 && strcmp(argv[1], "java") == 0) { +#else + } else if (argc == 2 && wcscmp(argv[1], L"java") == 0) { +#endif + if (fwrite("1", 1, 1, stdout) != 1) { + exit(EXIT_FAILURE); + } + wchar_t path[MAX_PATH]; + wchar_t * pathEnd = getBrandPath(path); + writePath(path, pathEnd, MY_STRING(L"")); + if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link")) + == NULL) + { + exit(EXIT_FAILURE); + } + pathEnd = tools::resolveLink(path); + if (pathEnd == NULL) { + exit(EXIT_FAILURE); + } + writeNull(); + writePath(path, pathEnd, MY_STRING(L"\\program\\classes\\unoil.jar")); + if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == + NULL) + { + exit(EXIT_FAILURE); + } + pathEnd = tools::resolveLink(path); + if (pathEnd == NULL) { + exit(EXIT_FAILURE); + } + writeNull(); + writePath(path, pathEnd, MY_STRING(L"\\java\\ridl.jar")); + writeNull(); + writePath(path, pathEnd, MY_STRING(L"\\java\\jurt.jar")); + writeNull(); + writePath(path, pathEnd, MY_STRING(L"\\java\\juh.jar")); + } else { + exit(EXIT_FAILURE); + } + exit(EXIT_SUCCESS); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/wrapper.h b/desktop/win32/source/wrapper.h new file mode 100755 index 000000000000..f0ff5b617f99 --- /dev/null +++ b/desktop/win32/source/wrapper.h @@ -0,0 +1,175 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#pragma once +#ifndef __cplusplus +#error Need C++ to compile +#endif + +#include "main.h" + +#ifndef _WINDOWS_ +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +# include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#endif + + +#ifndef _INC_TCHAR +# ifdef UNICODE +# define _UNICODE +# endif +# include <tchar.h> +#endif + +#ifdef UNICODE +# define Main MainW +# define GetArgv( pArgc ) CommandLineToArgvW( GetCommandLine(), pArgc ) +# define PROCESS_CREATIONFLAGS CREATE_UNICODE_ENVIRONMENT +#else +# define GetArgv( pArgc ) (*pArgc = __argc, __argv) +# define PROCESS_CREATIONFLAGS 0 +# define Main MainA +#endif + +#define BIN_EXT_STR TEXT(".bin") +#define PARAM_LIBPATH_STR TEXT("-libpath=") +#define PARAM_LOCAL_STR TEXT("-local") +#define PARAM_REMOTE_STR TEXT("-remote") + +#if defined( REMOTE ) +#define DEFAULT_LIBPATH TEXT("remote;") +#elif defined( LOCAL ) +#define DEFAULT_LIBPATH TEXT("local;") +#endif + +extern "C" int Main() +{ + // Retreive startup info + + STARTUPINFO aStartupInfo; + + ZeroMemory( &aStartupInfo, sizeof(aStartupInfo) ); + aStartupInfo.cb = sizeof( aStartupInfo ); + GetStartupInfo( &aStartupInfo ); + + // Retrieve command line + + LPTSTR lpCommandLine = GetCommandLine(); + + LPTSTR *ppArguments = NULL; + int nArguments = 0; + + ppArguments = GetArgv( &nArguments ); + + // Calculate application name + + + TCHAR szApplicationName[MAX_PATH]; + TCHAR szDrive[MAX_PATH]; + TCHAR szDir[MAX_PATH]; + TCHAR szFileName[MAX_PATH]; + TCHAR szExt[MAX_PATH]; + + GetModuleFileName( NULL, szApplicationName, MAX_PATH ); + _tsplitpath( szApplicationName, szDrive, szDir, szFileName, szExt ); + _tmakepath( szApplicationName, szDrive, szDir, szFileName, BIN_EXT_STR ); + + // Retreive actual environment + + TCHAR szBuffer[1024]; + TCHAR szPathValue[1024] = TEXT(""); + +#ifdef DEFAULT_LIBPATH + _tmakepath( szPathValue, szDrive, szDir, DEFAULT_LIBPATH, TEXT("") ); +#endif + + for ( int argn = 1; argn < nArguments; argn++ ) + { + if ( 0 == _tcscmp( ppArguments[argn], PARAM_REMOTE_STR ) ) + { + _tmakepath( szPathValue, szDrive, szDir, TEXT("remote;"), TEXT("") ); + break; + } + else if ( 0 == _tcscmp( ppArguments[argn], PARAM_LOCAL_STR ) ) + { + _tmakepath( szPathValue, szDrive, szDir, TEXT("local;"), TEXT("") ); + break; + } + else if ( 0 == _tcsncmp( ppArguments[argn], PARAM_LIBPATH_STR, _tcslen(PARAM_LIBPATH_STR) ) ) + { + LPTSTR pFileSpec = NULL; + + GetFullPathName( ppArguments[argn] + _tcslen(PARAM_LIBPATH_STR), sizeof(szPathValue) / sizeof(TCHAR), szPathValue, &pFileSpec ); + _tcscat( szPathValue, TEXT(";") ); + break; + } + } + + GetEnvironmentVariable( TEXT("PATH"), szBuffer, sizeof(szBuffer) ); + _tcscat( szPathValue, szBuffer ); + SetEnvironmentVariable( TEXT("PATH"), szPathValue); + + LPVOID lpEnvironment = GetEnvironmentStrings(); + + + // Retrieve current directory + + TCHAR szCurrentDirectory[MAX_PATH]; + GetCurrentDirectory( MAX_PATH, szCurrentDirectory ); + + // Set the Flags + + DWORD dwCreationFlags = PROCESS_CREATIONFLAGS; + + PROCESS_INFORMATION aProcessInfo; + + BOOL fSuccess = CreateProcess( + szApplicationName, + lpCommandLine, + NULL, + NULL, + TRUE, + dwCreationFlags, + lpEnvironment, + szCurrentDirectory, + &aStartupInfo, + &aProcessInfo ); + + if ( fSuccess ) + { + DWORD dwExitCode; + + WaitForSingleObject( aProcessInfo.hProcess, INFINITE ); + fSuccess = GetExitCodeProcess( aProcessInfo.hProcess, &dwExitCode ); + + return dwExitCode; + } + + DWORD dwError = GetLastError(); + + LPVOID lpMsgBuf; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dwError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR)&lpMsgBuf, + 0, + NULL + ); + + // Display the string. + MessageBox( NULL, (LPCTSTR)lpMsgBuf, NULL, MB_OK | MB_ICONERROR ); + + // Free the buffer. + LocalFree( lpMsgBuf ); + + return GetLastError(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/wrappera.cxx b/desktop/win32/source/wrappera.cxx new file mode 100644 index 000000000000..0a74b1030a3a --- /dev/null +++ b/desktop/win32/source/wrappera.cxx @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" +#include "wrapper.h" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/win32/source/wrapperw.cxx b/desktop/win32/source/wrapperw.cxx new file mode 100644 index 000000000000..d76ca9b678ad --- /dev/null +++ b/desktop/win32/source/wrapperw.cxx @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" +#define UNICODE +#include "wrapper.h" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |