739
744
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
741
% NTGhostscriptDLL() obtains the path to the latest Ghostscript DLL. The
742
% method returns MagickFalse if a value is not obtained.
746
% NTGhostscriptDLL() returns the path to the most recent Ghostscript version
747
% DLL. The method returns TRUE on success otherwise FALSE.
744
749
% The format of the NTGhostscriptDLL method is:
746
% int NTGhostscriptDLL(char *path, int length)
751
% int NTGhostscriptDLL(char *path,int length)
748
753
% A description of each parameter follows:
750
% o path: Pointer to buffer in which to return result.
752
% o length: Length of buffer
756
#define GS_PRODUCT_AFPL "AFPL Ghostscript"
757
#define GS_PRODUCT_ALADDIN "Aladdin Ghostscript"
758
#define GS_PRODUCT_GNU "GNU Ghostscript"
759
#define GS_PRODUCT_GPL "GPL Ghostscript"
760
#define GS_MINIMUM_VERSION 550
763
Get Ghostscript versions for given product.
764
Store results starting at pver + 1 + offset.
765
Returns total number of versions in pver.
767
static int NTGhostscriptProductVersions(int *pver,int offset,
768
const char *gs_productfamily)
755
% o path: return the Ghostscript DLL path here.
757
% o length: the buffer length.
761
static int NTGetRegistryValue(HKEY root,const char *key,const char *name,
762
char *value,int *length)
785
(void) FormatMagickString(key,MaxTextExtent,"Software\\%s",gs_productfamily);
786
hkeyroot = HKEY_LOCAL_MACHINE;
787
if (RegOpenKeyExA(hkeyroot,key,0,KEY_READ,&hkey) == ERROR_SUCCESS)
790
Now enumerate the keys.
792
cbData = sizeof(key) / sizeof(char);
793
while (RegEnumKeyA(hkey,n,key,cbData) == ERROR_SUCCESS)
798
while (*p && (*p!='.')) {
799
ver = (ver * 10) + (*p - '0')*100;
811
if ((n+offset) < pver[0])
819
/* Query registry to find which versions of Ghostscript are installed.
820
* Return version numbers in an integer array.
821
* On entry, the first element in the array must be the array size
823
* If all is well, TRUE is returned.
824
* On exit, the first element is set to the number of Ghostscript
825
* versions installed, and subsequent elements to the version
826
* numbers of Ghostscript.
827
* e.g. on entry {5, 0, 0, 0, 0}, on exit {3, 550, 600, 596, 0}
828
* Returned version numbers may not be sorted.
830
* If Ghostscript is not installed at all, return FALSE
831
* and set pver[0] to 0.
832
* If the array is not large enough, return FALSE
833
* and set pver[0] to the number of Ghostscript versions installed.
836
static int NTGhostscriptEnumerateVersions(int *pver)
841
assert(pver != (int *) NULL);
842
n=NTGhostscriptProductVersions(pver,0,GS_PRODUCT_AFPL);
843
n=NTGhostscriptProductVersions(pver,n,GS_PRODUCT_ALADDIN);
844
n=NTGhostscriptProductVersions(pver,n,GS_PRODUCT_GNU);
845
n=NTGhostscriptProductVersions(pver,n,GS_PRODUCT_GPL);
849
return(FALSE); /* too small */
854
return(FALSE); /* not installed */
861
Get a named registry value.
862
Key = hkeyroot\\key, named value = name.
863
name, ptr, plen and return values are the same as in gp_getenv();
865
static int NTGetRegistryValue(HKEY hkeyroot,const char *key,const char *name,
882
if (RegOpenKeyExA(hkeyroot,key,0,KEY_READ,&hkey) == ERROR_SUCCESS)
886
if (bptr == (BYTE *)NULL)
887
bptr=(&b); /* Registry API won't return ERROR_MORE_DATA */
889
rc=RegQueryValueExA(hkey,(char *) name,0,&keytype,bptr,&cbData);
891
if (rc == ERROR_SUCCESS)
894
return 0; /* found environment variable and copied it */
895
} else if (rc == ERROR_MORE_DATA) {
896
/* buffer wasn't large enough */
779
Get a registry value: key = root\\key, named value = name.
781
if (RegOpenKeyExA(root,key,0,KEY_READ,&hkey) != ERROR_SUCCESS)
782
return(1); /* no match */
786
if (p == (BYTE *) NULL)
787
p=(&byte); /* ERROR_MORE_DATA only if value is NULL */
788
status=RegQueryValueExA(hkey,(char *) name,0,&type,p,&extent);
790
if (status == ERROR_SUCCESS)
793
return(0); /* return the match */
795
if (status == ERROR_MORE_DATA)
798
return(-1); /* buffer not large enough */
901
800
return(1); /* not found */
904
static int NTGhostscriptGetProductString(int gs_revision,const char *name,
905
char *ptr,int len,const char *gs_productfamily)
907
/* If using Win32, look in the registry for a value with
908
* the given name. The registry value will be under the key
909
* HKEY_CURRENT_USER\Software\AFPL Ghostscript\N.NN
910
* or if that fails under the key
911
* HKEY_LOCAL_MACHINE\Software\AFPL Ghostscript\N.NN
912
* where "AFPL Ghostscript" is actually gs_productfamily
913
* and N.NN is obtained from gs_revision.
803
static int NTLocateGhostscript(const char **product_family,int *major_version,
818
"Aladdin Ghostscript"
822
Find the most recent version of Ghostscript.
825
*product_family=NULL;
827
*minor_version=49; /* min version of Ghostscript is 5.50 */
828
for (i=0; i < (long) (sizeof(products)/sizeof(products[0])); i++)
840
(void) FormatMagickString(key,MaxTextExtent,"SOFTWARE\\%s",products[i]);
841
root=HKEY_LOCAL_MACHINE;
843
#if defined(KEY_WOW64_32KEY)
844
mode|=KEY_WOW64_32KEY;
846
if (RegOpenKeyExA(root,key,0,mode,&hkey) == ERROR_SUCCESS)
855
Now enumerate the keys.
857
extent=sizeof(key)/sizeof(char);
858
for (j=0; RegEnumKeyA(hkey,j,key,extent) == ERROR_SUCCESS; j++)
866
if (sscanf(key,"%d.%d",&major,&minor) != 2)
868
if ((major > *major_version) || ((major == *major_version) &&
869
(minor > *minor_version)))
871
*product_family=products[i];
872
*major_version=major;
873
*minor_version=minor;
877
(void) RegCloseKey(hkey);
880
if (status == MagickFalse)
885
(void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"Ghostscript (%s) "
886
"version %d.%02d",*product_family,*major_version,*minor_version);
890
static int NTGhostscriptGetString(const char *name,char *value,
917
dotversion[MaxTextExtent],
918
894
key[MaxTextExtent];
924
DWORD version = GetVersion();
926
if (((HIWORD(version) & 0x8000) != 0) && ((HIWORD(version) & 0x4000) == 0))
931
(void) FormatMagickString(dotversion,MaxTextExtent,"%d.%02d",(int)
932
(gs_revision/100),(int) (gs_revision % 100));
933
(void) FormatMagickString(key,MaxTextExtent,"Software\\%s\\%s",
934
gs_productfamily,dotversion);
936
code = NTGetRegistryValue(HKEY_CURRENT_USER, key, name, ptr, &length);
938
return TRUE; /* found it */
940
code = NTGetRegistryValue(HKEY_LOCAL_MACHINE, key, name, ptr, &length);
942
return TRUE; /* found it */
946
static int NTGhostscriptGetString(int gs_revision,const char *name,char *ptr,
949
if (NTGhostscriptGetProductString(gs_revision,name,ptr,len,GS_PRODUCT_AFPL))
951
if (NTGhostscriptGetProductString(gs_revision,name,ptr,len,GS_PRODUCT_ALADDIN))
953
if (NTGhostscriptGetProductString(gs_revision,name,ptr,len,GS_PRODUCT_GNU))
955
if (NTGhostscriptGetProductString(gs_revision,name,ptr,len,GS_PRODUCT_GPL))
960
static int NTGetLatestGhostscript( void )
968
DWORD version = GetVersion();
969
if ( ((HIWORD(version) & 0x8000)!=0) && ((HIWORD(version) & 0x4000)==0) )
970
return FALSE; /* win32s */
973
NTGhostscriptEnumerateVersions(&count);
976
ver=(int *) AcquireQuantumMemory(count+1UL,sizeof(*ver));
977
if (ver == (int *)NULL)
901
*product_family = (const char *) NULL;
917
{ HKEY_CURRENT_USER, "HKEY_CURRENT_USER" },
918
{ HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }
922
Get a string from the installed Ghostscript.
925
if (product_family == NULL)
926
(void) NTLocateGhostscript(&product_family,&major_version,&minor_version);
927
if (product_family == NULL)
980
if (!NTGhostscriptEnumerateVersions(ver))
982
ver=(int *) RelinquishMagickMemory(ver);
986
for (i=1; i<=ver[0]; i++) {
929
(void) FormatMagickString(key,MaxTextExtent,"SOFTWARE\\%s\\%d.%02d",
930
product_family,major_version,minor_version);
931
for (i=0; i < (long) (sizeof(hkeys)/sizeof(hkeys[0])); i++)
934
if (NTGetRegistryValue(hkeys[i].hkey,key,name,value,&extent) == 0)
936
(void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
937
"registry: \"%s\\%s\\%s\"=\"%s\"",hkeys[i].name,key,name,value);
940
(void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
941
"registry: \"%s\\%s\\%s\" (failed)",hkeys[i].name,key,name);
990
ver=(int *) RelinquishMagickMemory(ver);
996
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1000
% N T G h o s t s c r i p t D L L %
1004
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1006
% NTGhostscriptDLL() obtains the path to the latest Ghostscript DLL. The
1007
% method returns MagickFalse if a value is not obtained.
1009
% The format of the NTGhostscriptDLL method is:
1011
% int NTGhostscriptDLL( char *path, int length)
1013
% A description of each parameter follows:
1015
% o path: Pointer to path buffer to update
1017
% o length: Allocation size of path buffer.
1020
MagickExport int NTGhostscriptDLL(char *path, int length)
946
MagickExport int NTGhostscriptDLL(char *path,int length)
949
dll[MaxTextExtent] = { "" };
1029
gsver = NTGetLatestGhostscript();
1030
if ((gsver == FALSE) || (gsver < GS_MINIMUM_VERSION))
1033
if (!NTGhostscriptGetString(gsver, "GS_DLL", buf, sizeof(buf)))
1036
(void) CopyMagickString(path,buf,length+1);
952
if ((*dll == '\0') &&
953
(NTGhostscriptGetString("GS_DLL",dll,sizeof(dll)) == FALSE))
955
(void) CopyMagickString(path,dll,length);
1197
1107
MagickExport int NTGhostscriptLoadDLL(void)
1200
module_path[MaxTextExtent];
1110
path[MaxTextExtent];
1202
if (gs_dll_handle != (void *) NULL)
1204
if (NTGhostscriptDLL(module_path,sizeof(module_path)) == MagickFalse)
1205
return(MagickFalse);
1206
gs_dll_handle=NTOpenLibrary(module_path);
1207
if (gs_dll_handle == (void *) NULL)
1208
return(MagickFalse);
1209
(void) ResetMagickMemory((void *) &gs_vectors,0,sizeof(GhostscriptVectors));
1210
gs_vectors.exit=(int (MagickDLLCall *)
1211
(gs_main_instance *)) NTGetLibrarySymbol(gs_dll_handle,"gsapi_exit");
1212
gs_vectors.init_with_args=(int (MagickDLLCall *)
1213
(gs_main_instance *,int,char **))
1214
(NTGetLibrarySymbol(gs_dll_handle,"gsapi_init_with_args"));
1215
gs_vectors.new_instance=(int (MagickDLLCall *) (gs_main_instance **,void *))
1216
(NTGetLibrarySymbol(gs_dll_handle,"gsapi_new_instance"));
1217
gs_vectors.run_string=(int (MagickDLLCall *)
1218
(gs_main_instance *,const char *,int,int *))
1219
(NTGetLibrarySymbol(gs_dll_handle,"gsapi_run_string"));
1220
gs_vectors.delete_instance=(void (MagickDLLCall *)(gs_main_instance *))
1221
(NTGetLibrarySymbol(gs_dll_handle,"gsapi_delete_instance"));
1222
if ((gs_vectors.exit == NULL) ||
1223
(gs_vectors.init_with_args == NULL) ||
1224
(gs_vectors.new_instance == NULL) ||
1225
(gs_vectors.run_string == NULL) ||
1226
(gs_vectors.delete_instance == NULL))
1227
return(MagickFalse);
1112
if (ghost_handle != (void *) NULL)
1114
if (NTGhostscriptDLL(path,sizeof(path)) == FALSE)
1116
ghost_handle=lt_dlopen(path);
1117
if (ghost_handle == (void *) NULL)
1119
(void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
1120
ghost_info.exit=(int (MagickDLLCall *)(gs_main_instance*))
1121
lt_dlsym(ghost_handle,"gsapi_exit");
1122
ghost_info.init_with_args=(int (MagickDLLCall *)(gs_main_instance *,int,
1123
char **)) (lt_dlsym(ghost_handle,"gsapi_init_with_args"));
1124
ghost_info.new_instance=(int (MagickDLLCall *)(gs_main_instance **,void *)) (
1125
lt_dlsym(ghost_handle,"gsapi_new_instance"));
1126
ghost_info.run_string=(int (MagickDLLCall *)(gs_main_instance *,const char *,
1127
int,int *)) (lt_dlsym(ghost_handle,"gsapi_run_string"));
1128
ghost_info.delete_instance=(void (MagickDLLCall *) (gs_main_instance *)) (
1129
lt_dlsym(ghost_handle,"gsapi_delete_instance"));
1130
if ((ghost_info.exit == NULL) || (ghost_info.init_with_args == NULL) ||
1131
(ghost_info.new_instance == NULL) || (ghost_info.run_string == NULL) ||
1132
(ghost_info.delete_instance == NULL))