~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to src/dwuninst.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2001-2006 Artifex Software, Inc.
2
 
   All Rights Reserved.
3
 
  
4
 
   This software is provided AS-IS with no warranty, either express or
5
 
   implied.
6
 
 
7
 
   This software is distributed under license and may not be copied, modified
8
 
   or distributed except as expressly authorized under the terms of that
9
 
   license.  Refer to licensing information at http://www.artifex.com/
10
 
   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11
 
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12
 
*/
13
 
 
14
 
// $Id: dwuninst.cpp 8037 2007-06-10 01:51:33Z alexcher $
15
 
 
16
 
#define STRICT
17
 
#include <windows.h>
18
 
#include <objbase.h>
19
 
#include <shlobj.h>
20
 
#include <shellapi.h>
21
 
#include <stdio.h>
22
 
#include <string.h>
23
 
#include <stdlib.h>
24
 
#include <ctype.h>
25
 
#include <direct.h>
26
 
#include "dwuninst.h"
27
 
 
28
 
 
29
 
#ifdef _MSC_VER
30
 
#define _export
31
 
#define chdir(x) _chdir(x)
32
 
#define mkdir(x) _mkdir(x)
33
 
#endif
34
 
#define DELAY_STEP 500
35
 
#define DELAY_FILE 0
36
 
#define MAXSTR 256
37
 
#define UNINSTALLKEY TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall")
38
 
 
39
 
HWND hDlgModeless;
40
 
HWND hText1;
41
 
HWND hText2;
42
 
char path[MAXSTR];
43
 
int language = 0;
44
 
BOOL is_win4 = FALSE;
45
 
HINSTANCE phInstance;
46
 
char szSection[] = "////////////////////////////////";
47
 
BOOL bQuit = FALSE;
48
 
BOOL gError = FALSE;    // set TRUE if an uninstall was not successful 
49
 
BOOL bSilent = FALSE;
50
 
 
51
 
char szTitle[MAXSTR];
52
 
char szLogFile[MAXSTR];
53
 
char szLine[MAXSTR];
54
 
FILE *fLog;
55
 
 
56
 
void do_message(void);
57
 
BOOL dofiles(void);
58
 
BOOL registry_delete(void);
59
 
BOOL registry_import(void);
60
 
BOOL shell_new(void);
61
 
BOOL shell_old(void);
62
 
BOOL doEOF(void);
63
 
 
64
 
#ifdef _WIN64
65
 
#define DLGRETURN INT_PTR
66
 
#else
67
 
#define DLGRETURN BOOL
68
 
#endif
69
 
 
70
 
// #define gs_addmess(str) fputs(str, stdout)   // for debug 
71
 
#define gs_addmess(str)
72
 
 
73
 
int message_box(LPCTSTR message, LPCTSTR title, int nType)
74
 
{
75
 
    if (bSilent)
76
 
        return 0;
77
 
    return MessageBox(HWND_DESKTOP, message, title, nType);
78
 
}
79
 
 
80
 
// linked list for deleting registry entries in reverse order
81
 
typedef struct tagKEY {
82
 
    long index;
83
 
    struct tagKEY *previous;
84
 
} KEY;
85
 
KEY *last_key = NULL;
86
 
 
87
 
 
88
 
// read a line from the log, removing trailing new line character
89
 
BOOL GetLine(void)
90
 
{
91
 
    BOOL err = TRUE;
92
 
    int i;
93
 
    szLine[0] = '\0';
94
 
    if (fLog)
95
 
        err = (fgets(szLine, sizeof(szLine)-1, fLog) == NULL);
96
 
    i = strlen(szLine) - 1;
97
 
    if ( (szLine[0] != '\0') && (szLine[i] == '\n'))
98
 
                szLine[i] = '\0';
99
 
    return !err;
100
 
}
101
 
 
102
 
BOOL IsSection(void)
103
 
{
104
 
    return (strncmp(szLine, szSection, strlen(szSection)) == 0);
105
 
}
106
 
 
107
 
BOOL
108
 
NextSection(void)
109
 
{
110
 
    while (GetLine()) {
111
 
                do_message();
112
 
                if (bQuit)
113
 
                        return FALSE;
114
 
                if (IsSection())
115
 
                        return TRUE;
116
 
        }
117
 
 
118
 
        return TRUE;
119
 
}
120
 
 
121
 
BOOL ReadSection(void)
122
 
{
123
 
        do_message();
124
 
        if (bQuit)
125
 
                return FALSE;
126
 
        GetLine();
127
 
        if (strlen(szLine) == 0) {
128
 
                doEOF();
129
 
                return TRUE;
130
 
        }
131
 
        else if (strcmp(szLine, "FileNew")==0) {
132
 
                SetWindowText(hText1, "Removing Files");
133
 
                if (!bSilent)
134
 
                    Sleep(DELAY_STEP);
135
 
                if (!dofiles())
136
 
                        return FALSE;
137
 
                SetWindowText(hText1, "");
138
 
                return TRUE;
139
 
        }
140
 
        else if (strcmp(szLine, "RegistryNew")==0) {
141
 
                SetWindowText(hText1, "Removing Registry entries");
142
 
                if (!bSilent)
143
 
                    Sleep(DELAY_STEP);
144
 
                if (!registry_delete())
145
 
                        return FALSE;
146
 
                SetWindowText(hText1, "");
147
 
                return TRUE;
148
 
        }
149
 
        else if (strcmp(szLine, "RegistryOld")==0) {
150
 
                SetWindowText(hText1, "Restoring Registry entries");
151
 
                if (!bSilent)
152
 
                    Sleep(DELAY_STEP);
153
 
                if (!registry_import())
154
 
                        return FALSE;
155
 
                SetWindowText(hText1, "");
156
 
                return TRUE;
157
 
        }
158
 
        else if (strcmp(szLine, "ShellNew")==0) {
159
 
                SetWindowText(hText1, "Removing Start Menu items");
160
 
                if (!bSilent)
161
 
                    Sleep(DELAY_STEP);
162
 
                if (!shell_new())
163
 
                        return FALSE;
164
 
                SetWindowText(hText1, "");
165
 
                return TRUE;
166
 
        }
167
 
        else if (strcmp(szLine, "ShellOld")==0) {
168
 
                SetWindowText(hText1, "Restoring Start Menu items");
169
 
                if (!bSilent)
170
 
                    Sleep(DELAY_STEP);
171
 
                if (!shell_old())
172
 
                        return FALSE;
173
 
                SetWindowText(hText1, "");
174
 
                return TRUE;
175
 
        }
176
 
        return FALSE;
177
 
}
178
 
 
179
 
 
180
 
BOOL
181
 
dofiles(void)
182
 
{
183
 
    while (GetLine()) {
184
 
        do_message();
185
 
        if (bQuit)
186
 
            return FALSE;
187
 
        if (IsSection()) {
188
 
            SetWindowText(hText2, "");
189
 
            return TRUE;
190
 
        }
191
 
        if (szLine[0] != '\0') {
192
 
            SetWindowText(hText2, szLine);
193
 
            if (!bSilent)
194
 
                Sleep(DELAY_FILE);
195
 
            gs_addmess("Deleting File: ");
196
 
            gs_addmess(szLine);
197
 
            gs_addmess("\n");
198
 
            DeleteFile(szLine);
199
 
        }
200
 
    }
201
 
    return FALSE;
202
 
}
203
 
 
204
 
BOOL
205
 
doEOF(void)
206
 
{
207
 
    fclose(fLog);
208
 
    fLog = NULL;
209
 
    unlink(szLogFile);
210
 
    PostMessage(hDlgModeless, WM_COMMAND, IDC_DONE, 0L);
211
 
        bQuit = TRUE;
212
 
    return TRUE;
213
 
}
214
 
 
215
 
 
216
 
BOOL
217
 
registry_delete_key(void)
218
 
{
219
 
char keyname[MAXSTR];
220
 
HKEY hkey = HKEY_CLASSES_ROOT;
221
 
HKEY hrkey = HKEY_CLASSES_ROOT;
222
 
char *rkey, *skey;
223
 
char *name;
224
 
DWORD dwResult;
225
 
    keyname[0] = '\0';
226
 
    while (GetLine()) {
227
 
        if ((szLine[0] == '\0') || (szLine[0] == '\r') || (szLine[0] == '\n'))
228
 
            break;
229
 
        if (szLine[0] == '[') {
230
 
            // key name
231
 
            rkey = strtok(szLine+1, "\\]\n\r");
232
 
            if (rkey == (char *)NULL)
233
 
                return FALSE;
234
 
            skey = strtok(NULL, "]\n\r");
235
 
            if (strcmp(rkey, "HKEY_CLASSES_ROOT")==0)
236
 
                hrkey = HKEY_CLASSES_ROOT;
237
 
            else if (strcmp(rkey, "HKEY_CURRENT_USER")==0)
238
 
                hrkey = HKEY_CURRENT_USER;
239
 
            else if (strcmp(rkey, "HKEY_LOCAL_MACHINE")==0)
240
 
                hrkey = HKEY_LOCAL_MACHINE;
241
 
            else if (strcmp(rkey, "HKEY_USERS")==0)
242
 
                hrkey = HKEY_USERS;
243
 
            else
244
 
                return FALSE;
245
 
            if (skey == (char *)NULL)
246
 
                return FALSE;
247
 
            gs_addmess("Opening registry key\n   ");
248
 
            gs_addmess(rkey);
249
 
            gs_addmess("\\");
250
 
            gs_addmess(skey);
251
 
            gs_addmess("\n");
252
 
            if (RegCreateKeyEx(hrkey, skey, 0, "", 0, KEY_ALL_ACCESS, 
253
 
                NULL, &hkey, &dwResult)
254
 
                != ERROR_SUCCESS)
255
 
                return FALSE;
256
 
            strcpy(keyname, skey);
257
 
        }
258
 
        else if (szLine[0] == '@') {
259
 
            // default value
260
 
            RegDeleteValue(hkey, NULL);
261
 
            gs_addmess("Deleting registry default value\n");
262
 
        }
263
 
        else if (szLine[0] == '\042') {
264
 
            // named value
265
 
            name = strtok(szLine+1, "\042\r\n");
266
 
            RegDeleteValue(hkey, name);
267
 
            gs_addmess("Deleting registry named value\n   ");
268
 
            gs_addmess(name);
269
 
            gs_addmess("\n");
270
 
        }
271
 
    }
272
 
 
273
 
    // Find out if key has subkeys or values
274
 
    TCHAR szClass[MAXSTR];
275
 
    DWORD cchClass;
276
 
    DWORD cSubKeys;
277
 
    DWORD cchMaxSubKey;
278
 
    DWORD cchMaxClass;
279
 
    DWORD cValues;
280
 
    DWORD cchMaxValueName;
281
 
    DWORD cbMaxValueData;
282
 
    DWORD cbSecurityDescriptor;
283
 
    FILETIME ftLastWriteTime;
284
 
    cchClass = sizeof(szClass) / sizeof(TCHAR);
285
 
    cSubKeys = 0;
286
 
    cValues = 0;
287
 
    RegQueryInfoKey(hkey, szClass, &cchClass, NULL,
288
 
        &cSubKeys, &cchMaxSubKey, &cchMaxClass, 
289
 
        &cValues, &cchMaxValueName, &cbMaxValueData,
290
 
        &cbSecurityDescriptor, &ftLastWriteTime);
291
 
 
292
 
    // close key
293
 
    if (hkey != HKEY_CLASSES_ROOT)
294
 
        RegCloseKey(hkey);
295
 
    // delete the key
296
 
    if ((cSubKeys != 0) || (cValues != 0)) {
297
 
        gs_addmess("Not deleting non empty registry key\n   ");
298
 
        gs_addmess(keyname);
299
 
        gs_addmess("\n");
300
 
    }
301
 
    else if (strlen(keyname)) {
302
 
        gs_addmess("Deleting registry key\n   ");
303
 
        gs_addmess(keyname);
304
 
        gs_addmess("\n");
305
 
        RegOpenKeyEx(hrkey, NULL, 0, 0, &hkey);
306
 
        RegDeleteKey(hkey, keyname);
307
 
        RegCloseKey(hkey);
308
 
    }
309
 
    return TRUE;
310
 
}
311
 
 
312
 
BOOL
313
 
registry_delete()
314
 
{
315
 
    long logindex;
316
 
    KEY *key;
317
 
        
318
 
    // scan log file
319
 
    // so we can remove keys in reverse order
320
 
    logindex = 0;
321
 
    while (GetLine() && !IsSection()) {
322
 
        KEY *key;
323
 
        if (szLine[0] == '[') {
324
 
                if ((key = (KEY *)malloc(sizeof(KEY)))
325
 
                        != (KEY *)NULL) {
326
 
                        key->previous = last_key;
327
 
                        key->index = logindex;
328
 
                        last_key = key;
329
 
                }
330
 
        }
331
 
        logindex = ftell(fLog);
332
 
    }
333
 
        
334
 
    // Remove keys
335
 
    for (key = last_key; key != NULL; key = key->previous) {
336
 
        if (key != last_key)
337
 
                free(last_key);
338
 
        fseek(fLog, key->index, SEEK_SET);
339
 
        registry_delete_key();
340
 
        last_key = key;
341
 
    }
342
 
    free(last_key);
343
 
        
344
 
    fseek(fLog, logindex, SEEK_SET);
345
 
        GetLine();
346
 
    return TRUE;
347
 
}
348
 
 
349
 
 
350
 
 
351
 
void
352
 
registry_unquote(char *line)
353
 
{
354
 
char *s, *d;
355
 
int value;
356
 
    s = d = line;
357
 
    while (*s) {
358
 
        if (*s != '\\') {
359
 
            *d++ = *s;
360
 
        }
361
 
        else {
362
 
            s++;
363
 
            if (*s == '\\')
364
 
                *d++ = *s;
365
 
            else {
366
 
                value = 0;
367
 
                if (*s) {
368
 
                    value = *s++ - '0';
369
 
                }
370
 
                if (*s) {
371
 
                    value <<= 3;
372
 
                    value += *s++ - '0';
373
 
                }
374
 
                if (*s) {
375
 
                    value <<= 3;
376
 
                    value += *s - '0';
377
 
                }
378
 
                *d++ = (char)value;
379
 
            }
380
 
        }
381
 
        s++;
382
 
    }
383
 
    *d = '\0';
384
 
}
385
 
 
386
 
BOOL
387
 
registry_import()
388
 
{
389
 
    HKEY hkey = HKEY_CLASSES_ROOT;
390
 
    HKEY hrkey;
391
 
    char *rkey, *skey;
392
 
    char *value;
393
 
    char *name;
394
 
    DWORD dwResult;
395
 
    GetLine();
396
 
    if (strncmp(szLine, "REGEDIT4", 8) != 0)
397
 
        return FALSE;
398
 
        
399
 
    while (GetLine()) {
400
 
        if (IsSection())
401
 
            break;
402
 
        if ((szLine[0] == '\0') || (szLine[0] == '\r') || (szLine[0] == '\n'))
403
 
            continue;
404
 
        if (szLine[0] == '[') {
405
 
            // key name
406
 
            if (hkey != HKEY_CLASSES_ROOT) {
407
 
                    RegCloseKey(hkey);
408
 
                    hkey = HKEY_CLASSES_ROOT;
409
 
            }
410
 
            rkey = strtok(szLine+1, "\\]\n\r");
411
 
            if (rkey == (char *)NULL)
412
 
                    return FALSE;
413
 
            skey = strtok(NULL, "]\n\r");
414
 
            if (strcmp(rkey, "HKEY_CLASSES_ROOT")==0)
415
 
                    hrkey = HKEY_CLASSES_ROOT;
416
 
            else if (strcmp(rkey, "HKEY_CURRENT_USER")==0)
417
 
                    hrkey = HKEY_CURRENT_USER;
418
 
            else if (strcmp(rkey, "HKEY_LOCAL_MACHINE")==0)
419
 
                    hrkey = HKEY_LOCAL_MACHINE;
420
 
            else if (strcmp(rkey, "HKEY_USERS")==0)
421
 
                    hrkey = HKEY_USERS;
422
 
            else
423
 
                    return FALSE;
424
 
            if (skey == (char *)NULL)
425
 
                    return FALSE;
426
 
            gs_addmess("Creating registry key\n   ");
427
 
            gs_addmess(rkey);
428
 
            gs_addmess("\\");
429
 
            gs_addmess("skey");
430
 
            gs_addmess("\n");
431
 
            if (RegCreateKeyEx(hrkey, skey, 0, "", 0, KEY_ALL_ACCESS, 
432
 
                    NULL, &hkey, &dwResult)
433
 
                    != ERROR_SUCCESS)
434
 
                    return FALSE;
435
 
        }
436
 
        else if (szLine[0] == '@') {
437
 
            // default value
438
 
            if (strlen(szLine) < 4)
439
 
                    return FALSE;
440
 
            value = strtok(szLine+3, "\042\r\n");
441
 
            if (value) {
442
 
                    registry_unquote(value);
443
 
                    gs_addmess("Setting registry key value\n   ");
444
 
                    gs_addmess(value);
445
 
                    gs_addmess("\n");
446
 
                    if (RegSetValueEx(hkey, NULL, 0, REG_SZ, 
447
 
                            (CONST BYTE *)value, strlen(value)+1)
448
 
                            != ERROR_SUCCESS)
449
 
                            return FALSE;
450
 
            }
451
 
        }
452
 
        else if (szLine[0] == '\042') {
453
 
            // named value
454
 
            name = strtok(szLine+1, "\042\r\n");
455
 
            strtok(NULL, "\042\r\n");
456
 
            value = strtok(NULL, "\042\r\n");
457
 
            registry_unquote(value);
458
 
            gs_addmess("Setting registry key value\n   ");
459
 
            gs_addmess(name);
460
 
            gs_addmess("=");
461
 
            gs_addmess(value);
462
 
            gs_addmess("\n");
463
 
            if (RegSetValueEx(hkey, name, 0, REG_SZ, (CONST BYTE *)value, 
464
 
                strlen(value)+1) != ERROR_SUCCESS)
465
 
                return FALSE;
466
 
        }
467
 
    }
468
 
    if (hkey != HKEY_CLASSES_ROOT)
469
 
                RegCloseKey(hkey);
470
 
    return TRUE;
471
 
}
472
 
 
473
 
// recursive mkdir
474
 
// requires a full path to be specified, so ignores root \ 
475
 
// apart from root \, must not contain trailing \ 
476
 
// Examples:
477
 
//  c:\          (OK, but useless)
478
 
//  c:\gstools   (OK)
479
 
//  c:\gstools\  (incorrect)
480
 
//  c:gstools    (incorrect)
481
 
//  gstools      (incorrect)
482
 
// The following UNC names should work,
483
 
// but didn't under Win3.1 because gs_chdir wouldn't accept UNC names
484
 
// Needs to be tested under Windows 95.
485
 
//  \\server\sharename\gstools    (OK)
486
 
//  \\server\sharename\           (OK, but useless)
487
 
//
488
 
 
489
 
BOOL MakeDir(char *dirname)
490
 
{
491
 
char newdir[MAXSTR];
492
 
char *p;
493
 
    if (strlen(dirname) < 3)
494
 
        return -1;
495
 
 
496
 
    gs_addmess("Making Directory\n  ");
497
 
    gs_addmess(dirname);
498
 
    gs_addmess("\n");
499
 
    if (isalpha(dirname[0]) && dirname[1]==':' && dirname[2]=='\\') {
500
 
        // drive mapped path
501
 
        p = dirname+3;
502
 
    }
503
 
    else if (dirname[1]=='\\' && dirname[1]=='\\') {
504
 
        // UNC path
505
 
        p = strchr(dirname+2, '\\');    // skip servername
506
 
        if (p == NULL)
507
 
            return -1;
508
 
        p++;
509
 
        p = strchr(p, '\\');            // skip sharename
510
 
        if (p == NULL)
511
 
            return -1;
512
 
    }
513
 
    else {
514
 
        // not full path so error
515
 
        return -1;
516
 
    }
517
 
 
518
 
    while (1) {
519
 
        strncpy(newdir, dirname, (int)(p-dirname));
520
 
        newdir[(int)(p-dirname)] = '\0';
521
 
        if (chdir(newdir)) {
522
 
            if (mkdir(newdir))
523
 
                return -1;
524
 
        }
525
 
        p++;
526
 
        if (p >= dirname + strlen(dirname))
527
 
            break;              // all done
528
 
        p = strchr(p, '\\');
529
 
        if (p == NULL)
530
 
            p = dirname + strlen(dirname);
531
 
    }
532
 
 
533
 
    return SetCurrentDirectory(dirname);
534
 
}
535
 
 
536
 
 
537
 
BOOL shell_new(void)
538
 
{
539
 
 
540
 
    char *p, *q;
541
 
    char group[MAXSTR];
542
 
    // remove shell items added by Ghostscript
543
 
    // We can only delete one group with this code
544
 
    group[0] = '\0';
545
 
    while (GetLine()) {
546
 
        if (IsSection()) {
547
 
            if (strlen(group) != 0) {
548
 
                    gs_addmess("Removing shell folder\n  ");
549
 
                    gs_addmess(group);
550
 
                    gs_addmess("\n");
551
 
                    RemoveDirectory(group);
552
 
            }
553
 
            return TRUE;
554
 
        }
555
 
        p = strtok(szLine, "=");
556
 
        q = strtok(NULL, "");
557
 
        if (p == NULL) {
558
 
            continue;
559
 
        }
560
 
        else if (strcmp(p, "Group")==0) {
561
 
            if (q)
562
 
                strncpy(group, q, sizeof(group)-1);
563
 
            // defer this until we have remove contents
564
 
        }
565
 
        else if (strcmp(p, "Name") == 0) {
566
 
            if (q) {
567
 
                gs_addmess("Removing shell link\n  ");
568
 
                gs_addmess(q);
569
 
                gs_addmess("\n");
570
 
                DeleteFile(q);
571
 
            }
572
 
        }
573
 
    }
574
 
 
575
 
    return TRUE;
576
 
}
577
 
 
578
 
 
579
 
BOOL CreateShellLink(LPCSTR name, LPCSTR description, LPCSTR program, 
580
 
        LPCSTR arguments, LPCSTR directory, LPCSTR icon, int nIconIndex)
581
 
{
582
 
    HRESULT hres;    
583
 
    IShellLink* psl;
584
 
 
585
 
    // Ensure string is UNICODE.
586
 
    WCHAR wsz[MAX_PATH];
587
 
    MultiByteToWideChar(CP_ACP, 0, name, -1, wsz, MAX_PATH);
588
 
 
589
 
    // Save new shell link
590
 
 
591
 
    // Get a pointer to the IShellLink interface.
592
 
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
593
 
            IID_IShellLink, (void **)&psl);
594
 
    if (SUCCEEDED(hres))    {
595
 
        IPersistFile* ppf;
596
 
        // Query IShellLink for the IPersistFile interface for 
597
 
        // saving the shell link in persistent storage.
598
 
        hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
599
 
        if (SUCCEEDED(hres)) {            
600
 
            gs_addmess("Adding shell link\n  ");
601
 
            gs_addmess(name);
602
 
            gs_addmess("\n");
603
 
 
604
 
            // Set the path to the shell link target.
605
 
            hres = psl->SetPath(program);         
606
 
            if (!SUCCEEDED(hres)) {
607
 
                    gs_addmess("SetPath failed!");
608
 
                    gError = TRUE;
609
 
            }
610
 
            // Set the description of the shell link.
611
 
            hres = psl->SetDescription(description);         
612
 
            if (!SUCCEEDED(hres)) {
613
 
                    gs_addmess("SetDescription failed!");
614
 
                    gError = TRUE;
615
 
            }
616
 
            if ((arguments != (LPCSTR)NULL) && *arguments) {
617
 
                    // Set the arguments of the shell link target.
618
 
                    hres = psl->SetArguments(arguments);         
619
 
                    if (!SUCCEEDED(hres)) {
620
 
                            gs_addmess("SetArguments failed!");
621
 
                            gError = TRUE;
622
 
                    }
623
 
            }
624
 
            if ((directory != (LPCSTR)NULL) && *directory) {
625
 
                    // Set the arguments of the shell link target.
626
 
                    hres = psl->SetWorkingDirectory(directory);         
627
 
                    if (!SUCCEEDED(hres)) {
628
 
                            gs_addmess("SetWorkingDirectory failed!");
629
 
                            gError = TRUE;
630
 
                    }
631
 
            }
632
 
            if ((icon != (LPCSTR)NULL) && *icon) {
633
 
                    // Set the arguments of the shell link target.
634
 
                    hres = psl->SetIconLocation(icon, nIconIndex);         
635
 
                    if (!SUCCEEDED(hres)) {
636
 
                            gs_addmess("SetIconLocation failed!");
637
 
                            gError = TRUE;
638
 
                    }
639
 
            }
640
 
 
641
 
            // Save the link via the IPersistFile::Save method.
642
 
            hres = ppf->Save(wsz, TRUE);    
643
 
            // Release pointer to IPersistFile.         
644
 
            ppf->Release();
645
 
        }
646
 
        // Release pointer to IShellLink.       
647
 
        psl->Release();    
648
 
    }
649
 
 
650
 
    return (hres == 0);
651
 
}
652
 
 
653
 
 
654
 
 
655
 
BOOL shell_old(void)
656
 
{
657
 
    // Add shell items removed by Ghostscript
658
 
    char *p, *q;
659
 
    char name[MAXSTR];
660
 
    char description[MAXSTR];
661
 
    char program[MAXSTR];
662
 
    char arguments[MAXSTR];
663
 
    char directory[MAXSTR];
664
 
    char icon[MAXSTR];
665
 
    int nIconIndex;
666
 
    // Remove shell items added by Ghostscript
667
 
    name[0] = description[0] = program[0] = arguments[0] 
668
 
            = directory[0] = icon[0] = '\0';
669
 
    nIconIndex = 0;
670
 
    
671
 
    while (GetLine()) {
672
 
        if (IsSection())
673
 
                return TRUE;
674
 
        p = strtok(szLine, "=");
675
 
        q = strtok(NULL, "");
676
 
        if (strlen(szLine) == 0) {
677
 
                if (name[0] != '\0') {
678
 
                        // add start menu item
679
 
                        CreateShellLink(name, description, program, arguments, 
680
 
                                directory, icon, nIconIndex);
681
 
                }
682
 
                name[0] = description[0] = program[0] = arguments[0] 
683
 
                        = directory[0] = icon[0] = '\0';
684
 
                nIconIndex = 0;
685
 
                continue;
686
 
        }
687
 
        else if (p == (char *)NULL) {
688
 
                continue;
689
 
        }
690
 
        else if (strcmp(p, "Group")==0) {
691
 
                MakeDir(q);
692
 
        }
693
 
        else if (strcmp(p, "Name") == 0)
694
 
                strncpy(name, q, sizeof(name)-1);
695
 
        else if (strcmp(p, "Description") == 0)
696
 
                strncpy(description, q, sizeof(description)-1);
697
 
        else if (strcmp(p, "Program") == 0)
698
 
                strncpy(program, q, sizeof(program)-1);
699
 
        else if (strcmp(p, "Arguments") == 0)
700
 
                strncpy(arguments, q, sizeof(arguments)-1);
701
 
        else if (strcmp(p, "Directory") == 0)
702
 
                strncpy(directory, q, sizeof(directory)-1);
703
 
        else if (strcmp(p, "IconLocation") == 0)
704
 
                strncpy(icon, q, sizeof(icon)-1);
705
 
        else if (strcmp(p, "IconIndex") == 0)
706
 
                nIconIndex = atoi(q);
707
 
    }
708
 
    
709
 
    return TRUE;
710
 
}
711
 
 
712
 
 
713
 
 
714
 
#ifdef __BORLANDC__
715
 
#pragma argsused
716
 
#endif
717
 
DLGRETURN CALLBACK _export
718
 
RemoveDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
719
 
{
720
 
  switch(message) {
721
 
    case WM_INITDIALOG:
722
 
            SetWindowText(hwnd, szTitle);
723
 
            if (bSilent)
724
 
                PostMessage(hwnd, WM_COMMAND, IDOK, 0);
725
 
            return TRUE;
726
 
        case WM_COMMAND:
727
 
            switch(LOWORD(wParam)) {
728
 
                case IDC_DONE:
729
 
                    // delete registry entries for uninstall
730
 
                        if (is_win4) {
731
 
                                HKEY hkey;
732
 
                                if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
733
 
                                        UNINSTALLKEY, 0, KEY_ALL_ACCESS, &hkey) 
734
 
                                        == ERROR_SUCCESS) {
735
 
                                        RegDeleteKey(hkey, szTitle);
736
 
                                        RegCloseKey(hkey);
737
 
                                }
738
 
                        }
739
 
 
740
 
                    SetWindowText(hText1, "Uninstall successful");
741
 
                    SetWindowText(hText2, "");
742
 
                    EnableWindow(GetDlgItem(hwnd, IDOK), FALSE);
743
 
                    EnableWindow(GetDlgItem(hwnd, IDCANCEL), TRUE);
744
 
                    SetDlgItemText(hwnd, IDCANCEL, "Exit");
745
 
                    SetFocus(GetDlgItem(hwnd, IDCANCEL));
746
 
                    if (bSilent)
747
 
                        PostMessage(hwnd, WM_COMMAND, IDCANCEL, 0);
748
 
                    return TRUE;
749
 
                case IDOK:
750
 
                    // Start removal
751
 
                    EnableWindow(GetDlgItem(hwnd, IDOK), FALSE);
752
 
                        EnableWindow(GetDlgItem(hwnd, IDC_PRESSOK), FALSE);
753
 
                    while (!bQuit) {
754
 
                        do_message();
755
 
                        if (!ReadSection()) {
756
 
                            SetWindowText(hText1, "Uninstall FAILED");
757
 
                            SetWindowText(hText2, "");
758
 
                            EnableWindow(GetDlgItem(hwnd, IDOK), FALSE);
759
 
                            EnableWindow(GetDlgItem(hwnd, IDCANCEL), TRUE);
760
 
                            SetDlgItemText(hwnd, IDCANCEL, "Exit");
761
 
                            SetFocus(GetDlgItem(hwnd, IDCANCEL));
762
 
                                bQuit = TRUE;
763
 
                        }
764
 
                    }
765
 
                    return TRUE;
766
 
                case IDCANCEL:
767
 
                    bQuit = TRUE;
768
 
                    DestroyWindow(hwnd);
769
 
                    hDlgModeless = 0;
770
 
                    return TRUE;
771
 
            }
772
 
        case WM_CLOSE:
773
 
            DestroyWindow(hwnd);
774
 
            hDlgModeless = 0;
775
 
            return TRUE;
776
 
    }
777
 
    return FALSE;
778
 
}
779
 
 
780
 
void
781
 
do_message(void)
782
 
{
783
 
MSG msg;
784
 
    while (hDlgModeless && PeekMessage(&msg, (HWND)NULL, 0, 0, PM_REMOVE)) {
785
 
        if ((hDlgModeless == 0) || !IsDialogMessage(hDlgModeless, &msg)) {
786
 
            TranslateMessage(&msg);
787
 
            DispatchMessage(&msg);
788
 
        }
789
 
    }
790
 
}
791
 
 
792
 
 
793
 
 
794
 
BOOL
795
 
init(void)
796
 
{
797
 
    DWORD version = GetVersion();
798
 
    char *p, *s;
799
 
    int len;
800
 
    BOOL inquote = FALSE;
801
 
    // get location of uninstall log from command line as argv[1]
802
 
    p = GetCommandLine();
803
 
    s = p;
804
 
    if (*s == '\042') {
805
 
            // skip over program name
806
 
            s++;
807
 
            while (*s && *s!='\042')
808
 
                    s++;
809
 
            if (*s)
810
 
                    s++;
811
 
    }
812
 
    else if (*s != ' ') {
813
 
            // skip over program name
814
 
            s++;
815
 
            while (*s && *s!=' ')
816
 
                    s++;
817
 
            if (*s)
818
 
                    s++;
819
 
    }
820
 
    while (*s && *s==' ')
821
 
            s++;
822
 
    if (*s == '\042') {
823
 
        s++;
824
 
        inquote = TRUE;
825
 
    }
826
 
    p = s;
827
 
    if (inquote) {
828
 
        while (*s && (*s != '\042'))
829
 
            s++;
830
 
    }
831
 
    else {
832
 
        while (*s && (*s != ' '))
833
 
            s++;
834
 
    }
835
 
    len = s - p;
836
 
    strncpy(szLogFile, p, min(len, (int)sizeof(szLogFile)-1));
837
 
    szLogFile[len] = '\0';
838
 
    if (inquote && (*s == '\042')) {
839
 
        s++;
840
 
        inquote = FALSE;
841
 
    }
842
 
 
843
 
    if (strlen(szLogFile) == 0) {
844
 
            message_box("Usage: uninstgs logfile.txt [-q]", 
845
 
                    "GPL Ghostscript Uninstall", MB_OK);
846
 
            return FALSE;
847
 
    }
848
 
 
849
 
    while (*s && *s==' ')
850
 
            s++;
851
 
    if (strncmp(s, "-q", 2) == 0)
852
 
        bSilent = TRUE;
853
 
    
854
 
    // read first few lines of file to get title
855
 
    fLog = fopen(szLogFile, "r");
856
 
    if (fLog == (FILE *)NULL) {
857
 
            message_box(szLogFile, "Can't find file", MB_OK);
858
 
            return FALSE;
859
 
    }
860
 
    GetLine();
861
 
    if (!IsSection()) {
862
 
            message_box(szLogFile, "Not valid uninstall log", MB_OK);
863
 
            return FALSE;
864
 
    }
865
 
    GetLine();
866
 
    if (strcmp(szLine, "UninstallName") != 0) {
867
 
            message_box(szLogFile, "Not valid uninstall log", MB_OK);
868
 
            return FALSE;
869
 
    }
870
 
    GetLine();
871
 
    strcpy(szTitle, szLine);
872
 
    
873
 
    NextSection();
874
 
    
875
 
    if (LOBYTE(LOWORD(version)) >= 4)
876
 
        is_win4 = TRUE;
877
 
    return TRUE;
878
 
}
879
 
 
880
 
#ifdef __BORLANDC__
881
 
#pragma argsused
882
 
#endif
883
 
int PASCAL 
884
 
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int cmdShow)
885
 
{
886
 
MSG msg;
887
 
 
888
 
    phInstance = hInstance;
889
 
    if (!init())
890
 
        return 1;
891
 
 
892
 
 
893
 
    CoInitialize(NULL);
894
 
 
895
 
    hDlgModeless = CreateDialogParam(hInstance, 
896
 
            MAKEINTRESOURCE(IDD_UNSET),
897
 
            HWND_DESKTOP, RemoveDlgProc, (LPARAM)NULL);
898
 
    hText1 = GetDlgItem(hDlgModeless, IDC_T1);
899
 
    hText2 = GetDlgItem(hDlgModeless, IDC_T2);
900
 
 
901
 
    SetWindowPos(hDlgModeless, HWND_TOP, 0, 0, 0, 0, 
902
 
        (bSilent ? SWP_HIDEWINDOW : SWP_SHOWWINDOW) | SWP_NOMOVE | SWP_NOSIZE);
903
 
 
904
 
    while (hDlgModeless && GetMessage(&msg, (HWND)NULL, 0, 0)) {
905
 
        if ((hDlgModeless == 0) || !IsDialogMessage(hDlgModeless, &msg)) {
906
 
            TranslateMessage(&msg);
907
 
            DispatchMessage(&msg);
908
 
        }
909
 
    }
910
 
 
911
 
    if (fLog)
912
 
        fclose(fLog);
913
 
 
914
 
    CoUninitialize();
915
 
 
916
 
    return 0;
917
 
}
918