"Fossies" - the Fresh Open Source Software Archive

Member "pstoedit-3.78/othersrc/gsdllinc/wgsver.c" (7 Nov 2021, 12787 Bytes) of package /linux/misc/pstoedit-3.78.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "wgsver.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.77_vs_3.78.

    1 /* Copyright (C) 2001-2003, Ghostgum Software Pty Ltd.  All rights reserved.
    2  *
    3  * Permission is hereby granted, free of charge, to any person
    4  * obtaining a copy of this software and associated documentation
    5  * files (the "Software"), to deal in the Software without
    6  * restriction, including without limitation the rights to use, copy,
    7  * modify, merge, publish, distribute, sublicense, and/or sell copies
    8  * of the Software, and to permit persons to whom the Software is
    9  * furnished to do so, subject to the following conditions:
   10  *
   11  * The above copyright notice and this permission notice shall be
   12  * included in all copies or substantial portions of the Software.
   13  *
   14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   17  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   18  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   19  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   21  * SOFTWARE.
   22  */
   23 
   24 /* 
   25  * This file is part of GSview.  The above notice applies only 
   26  * to this file.  It does NOT apply to any other file in GSview
   27  * unless that file includes the above copyright notice.
   28  */
   29 
   30 /* $Id: wgsver.c,v 1.1.2.4 2003/07/14 08:03:09 ghostgum Exp $ */
   31 /* Obtain details of copies of Ghostscript installed under Windows */
   32 
   33 /* To compile as a demo program, define DUMP_GSVER */
   34 /* #define DUMP_GSVER */
   35 
   36 #include <windows.h>
   37 #include <stdio.h>
   38 #include <stdio.h>
   39 #include <stdlib.h>
   40 #include "wgsver.h"
   41 #include "cppcomp.h"
   42 
   43 /* Ghostscript may be known in the Windows Registry by
   44  * the following names.
   45  */
   46 static const char * const gs_products[] = {
   47 /* #define GS_PRODUCT_AFPL      */ "AFPL Ghostscript",
   48 /* #define GS_PRODUCT_ALADDIN   */ "Aladdin Ghostscript",
   49 /* #define GS_PRODUCT_GPL       */ "GPL Ghostscript",
   50 /* #define GS_PRODUCT_GNU       */ "GNU Ghostscript",
   51     0};
   52 
   53 
   54 /* Get Ghostscript versions for given product.
   55  * Store results starting at pver + 1 + offset.
   56  * Returns total number of versions in pver.
   57  */
   58 static int get_gs_versions_product(int *pver, int offset, 
   59     HKEY hkeyroot, REGSAM regopenflags,
   60     const char *gs_productfamily, const char *gsregbase,
   61     int verbose, const char * const debug_info)
   62 {
   63   HKEY hkey;
   64   DWORD cbData;
   65   
   66   char key[256];
   67   int ver;
   68   char *p;
   69   int n = 0;
   70 
   71   if (strlen(gsregbase))
   72     sprintf_s(TARGETWITHLEN(key,256) , "Software\\%s\\%s", gsregbase, gs_productfamily);
   73   else
   74     sprintf_s(TARGETWITHLEN(key,256) , "Software\\%s", gs_productfamily);
   75 
   76 #ifdef OS_WIN32_WCE
   77   const long regtestresult = RegOpenKeyEx(hkeyroot, LPSTRtoLPWSTR(key).c_str(), 0, KEY_READ|regopenflags , &hkey);
   78 #else
   79   const long regtestresult = RegOpenKeyExA(hkeyroot, key, 0, KEY_READ|regopenflags , &hkey);
   80 #endif
   81   if (verbose) fprintf(stdout, " return code for \"%s\" %s is %d\n", key, debug_info, regtestresult);
   82   if (regtestresult == ERROR_SUCCESS) {
   83     /* Now enumerate the keys */
   84     cbData = sizeof(key) / sizeof(char);
   85 #ifdef OS_WIN32_WCE
   86     while (RegEnumKeyEx(hkey, n, (LPWSTR)LPSTRtoLPWSTR(key).c_str(), &cbData, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) 
   87 #else
   88     while (RegEnumKeyA(hkey, n, key, cbData) == ERROR_SUCCESS)
   89 #endif
   90     {
   91       if (verbose) fprintf(stdout, " enumerate gs versions: \"%s\" is number %d ", key, n+offset);
   92       n++;
   93       ver = 0;
   94       p = key;
   95       int major = 0;
   96       while (*p && (*p!='.')) {
   97             major *= 10;
   98             major += (*p - '0');
   99           p++;
  100       }
  101       if (*p == '.') {
  102             int minor = 0;
  103             p++;
  104             while (*p && (*p != '.')) {
  105                 minor *= 10;
  106                 minor += (*p - '0');
  107                 p++;
  108             }
  109             int pl = 0;
  110             if (*p == '.') {
  111                 // new scheme nn.nn.PL
  112                 p++;
  113                 while (*p) {
  114                     pl *= 10;
  115                     pl += (*p - '0');
  116                     p++;
  117                 }
  118             }
  119             ver = major * 10000 + minor * 100 + pl;
  120       } else {
  121          // not expected, but ...
  122          ver = major * 10000;
  123       }
  124 
  125       if (n + offset < pver[0]) {  /* the pver[0] item contains the lenght of the pver vector */
  126                                    /* this function is called also just for counting purposes */
  127             pver[n+offset] = ver;
  128       }
  129       if (verbose) fprintf(stdout, "mapped to %d\n", ver);
  130     }
  131   } 
  132   return n+offset;
  133 }
  134 
  135 /* Query registry to find which versions of Ghostscript are installed.
  136  * Return version numbers in an integer array.   
  137  * On entry, the first element in the array must be the array size 
  138  * in elements.
  139  * If all is well, TRUE is returned.
  140  * On exit, the first element is set to the number of Ghostscript
  141  * versions installed, and subsequent elements to the version
  142  * numbers of Ghostscript.
  143  * e.g. on entry {5, 0, 0, 0, 0}, on exit {3, 550, 600, 596, 0}
  144  * Returned version numbers may not be sorted.
  145  *
  146  * If Ghostscript is not installed at all, return FALSE
  147  * and set pver[0] to 0.
  148  * If the array is not large enough, return FALSE 
  149  * and set pver[0] to the number of Ghostscript versions installed.
  150  */
  151 BOOL get_gs_versions(int *pver, const char *gsregbase, int verbose)
  152 {
  153     int n=0;
  154     if (pver == nullptr)
  155         return FALSE;
  156     const char * const * productptr = &gs_products[0];
  157     while (productptr && *productptr) {
  158         n = get_gs_versions_product(pver, n, HKEY_LOCAL_MACHINE, 0,                 *productptr, gsregbase, verbose,"HKEY_LOCAL_MACHINE, 0");
  159         n = get_gs_versions_product(pver, n, HKEY_CURRENT_USER,  0,                 *productptr, gsregbase, verbose,"HKEY_CURRENT_USER,  0");
  160         n = get_gs_versions_product(pver, n, HKEY_LOCAL_MACHINE, KEY_WOW64_64KEY,   *productptr, gsregbase, verbose,"HKEY_LOCAL_MACHINE, KEY_WOW64_64KEY");
  161         n = get_gs_versions_product(pver, n, HKEY_CURRENT_USER,  KEY_WOW64_64KEY,   *productptr, gsregbase, verbose,"HKEY_CURRENT_USER,  KEY_WOW64_64KEY");
  162         productptr++;
  163     }
  164 
  165     if (n >= pver[0]) {
  166         pver[0] = n;
  167         return FALSE;   /* too small */
  168     }
  169 
  170     if (n == 0) {
  171         pver[0] = 0;
  172         return FALSE;   /* not installed */
  173     }
  174     pver[0] = n;
  175     return TRUE;
  176 }
  177 
  178  
  179 /*
  180  * Get a named registry value.
  181  * Key = hkeyroot\\key, named value = name.
  182  * name, ptr, plen and return values are the same as in gp_getenv();
  183  */
  184 
  185 static int 
  186 gp_getenv_registry(HKEY hkeyroot, REGSAM regopenflags, const char *key, const char *name, 
  187     char *ptr, int len, int verbose, const char * debug_info)
  188 {
  189   HKEY hkey;
  190   DWORD cbData, keytype;
  191   BYTE b;
  192   LONG rc;
  193   BYTE *bptr = (BYTE *)ptr;
  194   int rsl = 1;  /* not found */;
  195 
  196 #ifdef OS_WIN32_WCE
  197   if (RegOpenKeyEx(hkeyroot, LPSTRtoLPWSTR(key).c_str(), 0, KEY_READ |  regopenflags , &hkey)   == ERROR_SUCCESS) 
  198 #else
  199   if (RegOpenKeyExA(hkeyroot, key, 0, KEY_READ |  regopenflags , &hkey) == ERROR_SUCCESS) 
  200 #endif
  201   {
  202     keytype = REG_SZ;
  203     cbData = len;
  204     if (bptr == (BYTE *)NULL)
  205         bptr = &b;  /* Registry API won't return ERROR_MORE_DATA */
  206             /* if ptr is NULL */
  207 #ifdef OS_WIN32_WCE
  208     rc = RegQueryValueEx(hkey, LPSTRtoLPWSTR((char *)name).c_str(), 0, &keytype, bptr, &cbData);
  209 #else
  210     rc = RegQueryValueExA(hkey, (char *)name, 0, &keytype, bptr, &cbData);
  211 #endif
  212     (void)RegCloseKey(hkey);
  213 
  214     if (rc == ERROR_SUCCESS) {
  215 //      *plen = cbData;
  216         rsl = 0;    /* found environment variable and copied it */
  217     } else if (rc == ERROR_MORE_DATA) {
  218         /* buffer wasn't large enough */
  219 //      *plen = cbData;
  220         rsl = -1;
  221     }
  222   }
  223   if (verbose) {
  224     fprintf(stdout, "checking key %s %s (%s) -> %d\n", key, name, debug_info, rsl);
  225   }
  226   return rsl;
  227 }
  228 
  229 
  230 static BOOL get_gs_string_product(int gs_revision, const char *name, 
  231     char *ptr, int len, const char *gs_productfamily, const char *gsregbase, int verbose)
  232 {
  233     /* If using Win32, look in the registry for a value with
  234      * the given name.  The registry value will be under the key
  235      * HKEY_CURRENT_USER\Software\AFPL Ghostscript\N.NN
  236      * or if that fails under the key
  237      * HKEY_LOCAL_MACHINE\Software\AFPL Ghostscript\N.NN
  238      * where "AFPL Ghostscript" is actually gs_productfamily
  239      * and N.NN is obtained from gs_revision.
  240      */
  241 
  242     /* new since Rel 9.93.0: We have also a PL 
  243       hence all gs_revision is 99300 in this case
  244       for older relases we use then 99200
  245     */
  246     
  247     char key[256];
  248     char dotversion[16];
  249 
  250 #if 0
  251     const DWORD version = GetVersion();
  252     // hope we do not need this anymore
  253     if (((HIWORD(version) & 0x8000) != 0)
  254       && ((HIWORD(version) & 0x4000) == 0)) {
  255     /* Win32s */
  256     return FALSE;
  257     }
  258 #endif
  259 
  260     if (gs_revision < 95300) {
  261         sprintf_s(TARGETWITHLEN(dotversion, 16), "%d.%02d",
  262             (int)(gs_revision / 10000), 
  263             (int)(gs_revision % 10000)/100);
  264     } else {
  265         const int major = gs_revision / 10000;
  266         const int minor = (gs_revision - major * 10000) / 100;
  267         const int pl    = (gs_revision - major * 10000) % 100;
  268         sprintf_s(TARGETWITHLEN(dotversion, 16), "%d.%02d.%d",
  269             major, 
  270             minor,
  271             pl
  272         );
  273     }
  274     if (verbose) fprintf(stdout, "DOT: %s\n", dotversion);
  275     
  276     if (strlen(gsregbase))
  277       sprintf_s(TARGETWITHLEN(key,256), "Software\\%s\\%s\\%s", gsregbase, gs_productfamily, dotversion);
  278     else
  279       sprintf_s(TARGETWITHLEN(key,256), "Software\\%s\\%s", gs_productfamily, dotversion);
  280     
  281     if ( 
  282         (gp_getenv_registry(HKEY_CURRENT_USER,  0,               key, name, ptr, len, verbose, "HKEY_CURRENT_USER,  0") == 0) ||
  283         (gp_getenv_registry(HKEY_LOCAL_MACHINE, 0,               key, name, ptr, len, verbose, "HKEY_LOCAL_MACHINE, 0") == 0) ||
  284         (gp_getenv_registry(HKEY_CURRENT_USER,  KEY_WOW64_64KEY, key, name, ptr, len, verbose, "HKEY_CURRENT_USER,  KEY_WOW64_64KEY") == 0) ||
  285         (gp_getenv_registry(HKEY_LOCAL_MACHINE, KEY_WOW64_64KEY, key, name, ptr, len, verbose, "HKEY_LOCAL_MACHINE, KEY_WOW64_64KEY") == 0)
  286        ) {
  287       return true;
  288     } else {
  289       return false;
  290     }
  291 }
  292 
  293 BOOL get_gs_string(int gs_revision, const char *name, char *ptr, int len, 
  294   const char *gsregbase, int verbose)
  295 {
  296     const char * const * productptr = &gs_products[0];
  297     while (productptr && *productptr) {
  298         if (get_gs_string_product(gs_revision, name, ptr, len, *productptr, gsregbase, verbose))
  299         return TRUE;
  300         productptr++;
  301     }
  302     return FALSE;
  303 }
  304 
  305 
  306 
  307 /* Set the latest Ghostscript EXE or DLL from the registry */
  308 BOOL
  309 find_gs(char *gspath, int len, int minver, BOOL bDLL, const char *gsregbase, int verbose)
  310 {
  311 #if 0
  312     // win32s no longer supported
  313     const DWORD version = GetVersion();
  314     if (((HIWORD(version) & 0x8000) != 0) && ((HIWORD(version) & 0x4000) == 0)) {
  315       return FALSE;  // win32s
  316     }
  317 #endif
  318     //if (verbose) fprintf(stdout, "find_gs - counting\n");
  319     
  320     int count = 1;
  321     (void)get_gs_versions(&count, gsregbase, false /* verbose */);  // first call for counting
  322     if (count < 1) {
  323       return FALSE;
  324     }
  325     
  326     int* ver = new int[count + 1]; 
  327     if (!ver) {
  328         return FALSE;
  329     }
  330     //if (verbose) fprintf(stdout, "find_gs - collecting\n");
  331     ver[0] = count+1;
  332     if (!get_gs_versions(ver, gsregbase, verbose)) {
  333         delete[] ver; // free(ver);
  334         return FALSE;
  335     }
  336     
  337     int maxversion = 10000000;
  338     const char * gsvmax = getenv("GS_V_MAX");
  339     if (gsvmax) {
  340         maxversion = atoi(gsvmax);
  341     }
  342     int gsver = 0;
  343     // find latest/max version
  344     for (int i=1; i<=ver[0]; i++) {
  345         if ((ver[i] > gsver) && (ver[i] <= maxversion)) {
  346             gsver = ver[i];
  347         }
  348     }
  349     delete[] ver; // free(ver);
  350     if (gsver < minver) {   // minimum version (e.g. for gsprint)
  351         return FALSE;
  352     }
  353     
  354     char buf[1000];
  355     if (!get_gs_string(gsver, "GS_DLL", buf, sizeof(buf), gsregbase, verbose)) {
  356          return FALSE;
  357     }
  358     
  359     if (bDLL) {
  360         strncpy_s(gspath, len, buf, len-1);
  361         return TRUE;
  362     } else {
  363         char * p = strrchr(buf, '\\');
  364         if (p) {
  365             p++;
  366             *p = 0;
  367 #ifdef _WIN64
  368             strncpy_s(p,sizeof(buf)-1-strlen(buf), "gswin64c.exe", sizeof(buf)-1-strlen(buf));
  369 #else
  370             strncpy_s(p,sizeof(buf)-1-strlen(buf), "gswin32c.exe", sizeof(buf)-1-strlen(buf));
  371 #endif
  372             strncpy_s(gspath,len, buf, len-1);
  373             return TRUE;
  374         }
  375         return FALSE;
  376     }
  377 }
  378 
  379 
  380 #ifdef DUMP_GSVER
  381 #define ENTRYPOINT main(int argc, char *argv[], char *gsregbase)
  382 #else
  383 #define ENTRYPOINT dumpgsvers(const char *gsregbase, int verbose)
  384 #endif
  385 
  386 /* This is an example of how you can use the above functions */
  387 int ENTRYPOINT
  388 {
  389     int ver[10];
  390     char buf[256];
  391 
  392     if (find_gs(buf, sizeof(buf), 550, TRUE, gsregbase, verbose)) {
  393         fprintf(stderr, "Latest GS DLL is %s\n", buf);
  394     }
  395     
  396     if (find_gs(buf, sizeof(buf), 550, FALSE, gsregbase, verbose)) {
  397         fprintf(stderr, "Latest GS EXE is %s\n", buf);
  398     }
  399 
  400     ver[0] = sizeof(ver) / sizeof(int);
  401     const BOOL flag = get_gs_versions(ver, gsregbase, verbose);
  402     fprintf(stderr,"Versions: %d\n", ver[0]);
  403 
  404     if (flag == FALSE) {
  405       fprintf(stderr,"get_gs_versions failed, need %d\n", ver[0]);
  406       return 1;
  407     }
  408 
  409     for (int i=1; i <= ver[0]; i++) {
  410       fprintf(stderr," %d\n", ver[i]);
  411       if (get_gs_string(ver[i], "GS_DLL", buf, sizeof(buf), gsregbase, verbose)) {
  412         fprintf(stderr,"   GS_DLL=%s\n", buf);
  413       }
  414       if (get_gs_string(ver[i], "GS_LIB", buf, sizeof(buf), gsregbase, verbose)) {
  415         fprintf(stderr,"   GS_LIB=%s\n", buf);
  416       }
  417     }
  418     return 0;
  419 }
  420