rminnichinitial1fcdf7916 years agoHistory
1309 lines · 32.7 KB · C++
RawDownload
/* Copyright (C) 1999-2003, Ghostgum Software Pty Ltd.  All rights reserved.    This software is provided AS-IS with no warranty, either express or  implied.    This software is distributed under license and may not be copied,  modified or distributed except as expressly authorized under the terms  of the license contained in the file LICENSE in this distribution.    For more information about licensing, please refer to  http://www.ghostscript.com/licensing/. For information on  commercial licensing, go to http://www.artifex.com/licensing/ or  contact Artifex Software, Inc., 101 Lucas Valley Road #110,  San Rafael, CA  94903, U.S.A., +1(415)492-9861.*/ // $Id: dwsetup.cpp,v 1.11 2005/03/04 21:58:55 ghostgum Exp $////// This is the setup program for Win32 AFPL Ghostscript//// The starting point is a self extracting zip archive// with the following contents://   setupgs.exe//   uninstgs.exe//   filelist.txt      (contains list of program files)//   fontlist.txt      (contains list of font files)//   gs#.##\*          (files listed in filelist.txt)//   fonts\*           (fonts listed in fontlist.txt)// This is the same as the zip file created by Aladdin Enterprises,// with the addition of setupgs.exe, uninstgs.exe, filelist.txt and // fontlist.txt.//// The first line of the files filelist.txt and fontlist.txt// contains the uninstall name to be used.  // The second line contains name of the main directory where // uninstall log files are to be placed.  // Subsequent lines contain files to be copied (but not directories).// For example, filelist.txt might contain://   AFPL Ghostscript 6.50//   gs6.50//   gs6.50\bin\gsdll32.dll//   gs6.50\lib\gs_init.ps// The file fontlist.txt might contain://   AFPL Ghostscript Fonts//   fonts//   fonts\n019003l.pfb//   fonts\n019023l.pfb//// The default install directory is c:\gs.// The default Start Menu Folder is Ghostscript.// These are set in the resources.// The setup program will create the following uninstall log files//   c:\gs\gs#.##\uninstal.txt//   c:\gs\fonts\uninstal.txt// The uninstall program (accessed through control panel) will not // remove directories nor will it remove itself.//// If the install directory is the same as the current file // location, no files will be copied, but the existence of each file // will be checked.  This allows the archive to be unzipped, then// configured in its current location.  Running the uninstall will not // remove uninstgs.exe, setupgs.exe, filelist.txt or fontlist.txt.  #define STRICT#include <windows.h>#include <shellapi.h>#include <objbase.h>#include <shlobj.h>#include <stdio.h>#include <direct.h> #ifdef MAX_PATH#define MAXSTR MAX_PATH#else#define MAXSTR 256#endif #include "dwsetup.h"#include "dwinst.h" extern "C" {typedef HRESULT (WINAPI *PFN_SHGetFolderPath)(  HWND hwndOwner,  int nFolder,  HANDLE hToken,  DWORD dwFlags,  LPSTR pszPath); typedef BOOL (WINAPI *PFN_SHGetSpecialFolderPath)(  HWND hwndOwner,  LPTSTR lpszPath,  int nFolder,  BOOL fCreate);} //#define DEBUG #define UNINSTALLPROG "uninstgs.exe"  /////////////////////////////////// Globals CInstall cinst; // TRUE = Place Start Menu items in All Users.// FALSE = Current UserBOOL g_bUseCommon; // TRUE = Destination is the same as Source, so don't copy files.BOOL g_bNoCopy; // Source directory, usually a temporary directory created by// unzip self extractor.CHAR g_szSourceDir[MAXSTR]; // Target directory for program and fonts.// Default loaded from resourcesCHAR g_szTargetDir[MAXSTR]; // Target Group for shortcut.// Default loaded from resourcesCHAR g_szTargetGroup[MAXSTR]; // Setup application name, loaded from resourcesCHAR g_szAppName[MAXSTR]; BOOL g_bInstallFonts = TRUE;BOOL g_bCJKFonts = FALSE;BOOL g_bAllUsers = FALSE;  HWND g_hMain;		// Main install dialogHWND g_hWndText;	// Install log dialogHINSTANCE g_hInstance; // If a directory is listed on the command line, g_bBatch will// be TRUE and a silent install will occur.BOOL g_bBatch = FALSE;	 BOOL g_bQuit = FALSE;	// TRUE = Get out of message loop.BOOL g_bError = FALSE;	// TRUE = Install was not successfulBOOL is_winnt = FALSE;	// Disable "All Users" if not NT. #ifdef _WIN64#define DLGRETURN INT_PTR#else#define DLGRETURN BOOL#endif // PrototypesDLGRETURN CALLBACK MainDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);void gs_addmess_count(const char *str, int count);void gs_addmess(const char *str);void gs_addmess_update(void);BOOL init();BOOL install_all();BOOL install_prog();BOOL install_fonts();BOOL make_filelist(int argc, char *argv[]);int get_font_path(char *path, unsigned int pathlen);BOOL write_cidfmap(const char *gspath, const char *cidpath);BOOL GetProgramFiles(LPTSTR path);  //////////////////////////////////////////////////////////////////////// Entry point////////////////////////////////////////////////////////////////////// int APIENTRY WinMain(HINSTANCE hInstance,                     HINSTANCE hPrevInstance,                     LPSTR     lpCmdLine,                     int       nCmdShow){	MSG msg;	g_hInstance = hInstance;		if (!init()) {		MessageBox(HWND_DESKTOP, "Initialisation failed", 			g_szAppName, MB_OK);		return 1;	}		if (!g_bBatch) {		while (GetMessage(&msg, (HWND)NULL, 0, 0)) {			if (!IsDialogMessage(g_hWndText, &msg) && 				!IsDialogMessage(g_hMain, &msg)) {				TranslateMessage(&msg);				DispatchMessage(&msg);			}		}		DestroyWindow(g_hMain);	}		return (g_bError ? 1 : 0);}    //////////////////////////////////////////////////////////////////////// Text log window//////////////////////////////////////////////////////////////////////  #define TWLENGTH 32768#define TWSCROLL 1024char twbuf[TWLENGTH];int twend; // Modeless Dialog BoxDLGRETURN CALLBACK TextWinDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){    switch(message) {	case WM_INITDIALOG:		EnableWindow(g_hMain, FALSE);		return TRUE;	case WM_COMMAND:		switch(LOWORD(wParam)) {		case IDC_TEXTWIN_COPY:			{HGLOBAL hglobal;			LPSTR p;			DWORD result;			int start, end;			result = SendDlgItemMessage(hwnd, IDC_TEXTWIN_MLE, EM_GETSEL, (WPARAM)0, (LPARAM)0);			start = LOWORD(result);			end   = HIWORD(result);			if (start == end) {				start = 0;				end = twend;			}			hglobal = GlobalAlloc(GHND | GMEM_SHARE, end-start+1);			if (hglobal == (HGLOBAL)NULL) {				MessageBeep(-1);				return(FALSE);			}			p = (char *)GlobalLock(hglobal);			if (p == (LPSTR)NULL) {				MessageBeep(-1);				return(FALSE);			}			lstrcpyn(p, twbuf+start, end-start);			GlobalUnlock(hglobal);			OpenClipboard(hwnd);			EmptyClipboard();			SetClipboardData(CF_TEXT, hglobal);			CloseClipboard();			}			break;		case IDCANCEL:			g_bQuit = TRUE;			DestroyWindow(hwnd);			return TRUE;		}		break;	case WM_CLOSE:			DestroyWindow(hwnd);			return TRUE;	case WM_DESTROY:			g_bQuit = TRUE;			g_hWndText = (HWND)NULL;			EnableWindow(g_hMain, TRUE);			PostQuitMessage(0);			break;	}	return FALSE;}   // Add string to log windowvoidgs_addmess_count(const char *str, int count){	const char *s;	char *p;	int i, lfcount;	MSG msg;		// we need to add \r after each \n, so count the \n's	lfcount = 0;	s = str;	for (i=0; i<count; i++) {		if (*s == '\n')			lfcount++;		s++;	}		if (count + lfcount >= TWSCROLL)		return;		// too large	if (count + lfcount + twend >= TWLENGTH-1) {		// scroll buffer		twend -= TWSCROLL;		memmove(twbuf, twbuf+TWSCROLL, twend);	}	p = twbuf+twend;	for (i=0; i<count; i++) {		if (*str == '\n') {			*p++ = '\r';		}		*p++ = *str++;	}	twend += (count + lfcount);	*(twbuf+twend) = '\0';			// Update the dialog box	if (g_bBatch)		return;		gs_addmess_update();	while (PeekMessage(&msg, (HWND)NULL, 0, 0, PM_REMOVE)) {		if (!IsDialogMessage(g_hWndText, &msg) && 			!IsDialogMessage(g_hMain, &msg)) {			TranslateMessage(&msg);			DispatchMessage(&msg);		}	}} voidgs_addmess(const char *str){	gs_addmess_count(str, lstrlen(str));	}  voidgs_addmess_update(void){	HWND hwndmess = g_hWndText;		if (g_bBatch)		return;		if (IsWindow(hwndmess)) {		HWND hwndtext = GetDlgItem(hwndmess, IDC_TEXTWIN_MLE);		DWORD linecount;		SendMessage(hwndtext, WM_SETREDRAW, FALSE, 0);		SetDlgItemText(hwndmess, IDC_TEXTWIN_MLE, twbuf);		linecount = SendDlgItemMessage(hwndmess, IDC_TEXTWIN_MLE, EM_GETLINECOUNT, (WPARAM)0, (LPARAM)0);		SendDlgItemMessage(hwndmess, IDC_TEXTWIN_MLE, EM_LINESCROLL, (WPARAM)0, (LPARAM)linecount-14);		SendMessage(hwndtext, WM_SETREDRAW, TRUE, 0);		InvalidateRect(hwndtext, (LPRECT)NULL, TRUE);		UpdateWindow(hwndtext);	}}  //////////////////////////////////////////////////////////////////////// Browse dialog box ////////////////////////////////////////////////////////////////////// // nasty GLOBALSchar szFolderName[MAXSTR];char szDirName[MAXSTR]; DLGRETURN CALLBACK DirDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){	WORD notify_message;		switch(message) {	case WM_INITDIALOG:		DlgDirList(hwnd, szDirName, IDC_FILES, IDC_FOLDER, 			DDL_DRIVES | DDL_DIRECTORY);		SetDlgItemText(hwnd, IDC_TARGET, szFolderName);		return FALSE;    case WM_COMMAND:		notify_message = HIWORD(wParam);		switch (LOWORD(wParam)) {		case IDC_FILES:			if (notify_message == LBN_DBLCLK) {				CHAR szPath[MAXSTR];				DlgDirSelectEx(hwnd, szPath, sizeof(szPath), IDC_FILES);				DlgDirList(hwnd, szPath, IDC_FILES, IDC_FOLDER, 					DDL_DRIVES | DDL_DIRECTORY);			}			return FALSE;		case IDOK:			GetDlgItemText(hwnd, IDC_FOLDER, szDirName, sizeof(szDirName));			GetDlgItemText(hwnd, IDC_TARGET, szFolderName, sizeof(szFolderName));			EndDialog(hwnd, TRUE);			return TRUE;		case IDCANCEL:			EndDialog(hwnd, FALSE);			return TRUE;		}		return FALSE;	}	return FALSE;}  //////////////////////////////////////////////////////////////////////// Initialisation and Main dialog box////////////////////////////////////////////////////////////////////// voidmessage_box(const char *str){	MessageBox(HWND_DESKTOP, str, g_szAppName, MB_OK);}  BOOLinit(){	DWORD dwVersion = GetVersion();	// get source directory	GetCurrentDirectory(sizeof(g_szSourceDir), g_szSourceDir);		// load strings	LoadString(g_hInstance, IDS_APPNAME, g_szAppName, sizeof(g_szAppName));	LoadString(g_hInstance, IDS_TARGET_GROUP, 		g_szTargetGroup, sizeof(g_szTargetGroup));		if (LOBYTE(LOWORD(dwVersion)) < 4) {        MessageBox(HWND_DESKTOP, 			"This install program needs Windows 4.0 or later",			g_szAppName, MB_OK);		return FALSE;	}	if ( (HIWORD(dwVersion) & 0x8000) == 0)		is_winnt = TRUE;			cinst.SetMessageFunction(message_box); #define MAXCMDTOKENS 128 	int argc;	LPSTR argv[MAXCMDTOKENS];	LPSTR p;	char command[256];	char *args;	char *d, *e;     	p = GetCommandLine(); 	argc = 0;	args = (char *)malloc(lstrlen(p)+1);	if (args == (char *)NULL)		return 1;       	// Parse command line handling quotes.	d = args;	while (*p) {		// for each argument 		if (argc >= MAXCMDTOKENS - 1)			break; 		e = d;		while ((*p) && (*p != ' ')) {			if (*p == '\042') {				// Remove quotes, skipping over embedded spaces.				// Doesn't handle embedded quotes.				p++;				while ((*p) && (*p != '\042'))					*d++ =*p++;			}			else 				*d++ = *p;			if (*p)				p++;		}		*d++ = '\0';		argv[argc++] = e; 		while ((*p) && (*p == ' '))			p++;	// Skip over trailing spaces	}	argv[argc] = NULL; 	if (strlen(argv[0]) == 0) {		GetModuleFileName(g_hInstance, command, sizeof(command)-1);		argv[0] = command;	} 	if (argc > 2) {		// Probably creating filelist.txt		return make_filelist(argc, argv);	}  	// check if batch mode requested	// get location of target directory from command line as argv[1]	if (argc == 2) {		strncpy(g_szTargetDir, argv[1], sizeof(g_szTargetDir));		g_bBatch = TRUE;		if (is_winnt)			g_bAllUsers = TRUE;	}	if (g_bBatch) {		if (!install_all()) {

Lines 1–500 of 1309.