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: dwdll.c 9043 2008-08-28 22:48:19Z giles $ */
15 
16 /* dwdll.c */
17 
18 #define STRICT
19 #include <windows.h>
20 #include <string.h>
21 #include <stdio.h>
22 
23 #include "stdpre.h"
24 #include "gpgetenv.h"
25 #include "gscdefs.h"
26 #define GSREVISION gs_revision
27 
28 #define GSDLLEXPORT
29 #define GSDLLAPI CALLBACK
30 #define GSDLLCALL
31 
32 #include "dwdll.h"
33 
34 static const char name[] = "gsdll32.dll";
35 
load_dll(GSDLL * gsdll,char * last_error,int len)36 int load_dll(GSDLL *gsdll, char *last_error, int len)
37 {
38 char fullname[1024];
39 char *p;
40 int length;
41 gsapi_revision_t rv;
42 
43     /* Don't load if already loaded */
44     if (gsdll->hmodule)
45 	return 0;
46 
47     /* First try to load DLL from the same directory as EXE */
48     GetModuleFileName(GetModuleHandle(NULL), fullname, sizeof(fullname));
49     if ((p = strrchr(fullname,'\\')) != (char *)NULL)
50 	p++;
51     else
52 	p = fullname;
53     *p = '\0';
54     strcat(fullname, name);
55     gsdll->hmodule = LoadLibrary(fullname);
56 
57     /* Next try to load DLL with name in registry or environment variable */
58     if (gsdll->hmodule < (HINSTANCE)HINSTANCE_ERROR) {
59 	length = sizeof(fullname);
60 	if (gp_getenv("GS_DLL", fullname, &length) == 0)
61 	    gsdll->hmodule = LoadLibrary(fullname);
62     }
63 
64     /* Finally try the system search path */
65     if (gsdll->hmodule < (HINSTANCE)HINSTANCE_ERROR)
66         gsdll->hmodule = LoadLibrary(name);
67 
68     if (gsdll->hmodule < (HINSTANCE)HINSTANCE_ERROR) {
69 	/* Failed */
70 	DWORD err = GetLastError();
71 	sprintf(fullname, "Can't load DLL, LoadLibrary error code %ld", err);
72 	strncpy(last_error, fullname, len-1);
73 	gsdll->hmodule = (HINSTANCE)0;
74 	return 1;
75     }
76 
77     /* DLL is now loaded */
78     /* Get pointers to functions */
79     gsdll->revision = (PFN_gsapi_revision) GetProcAddress(gsdll->hmodule,
80 	"gsapi_revision");
81     if (gsdll->revision == NULL) {
82 	strncpy(last_error, "Can't find gsapi_revision\n", len-1);
83 	unload_dll(gsdll);
84 	return 1;
85     }
86     /* check DLL version */
87     if (gsdll->revision(&rv, sizeof(rv)) != 0) {
88 	sprintf(fullname, "Unable to identify Ghostscript DLL revision - it must be newer than needed.\n");
89 	strncpy(last_error, fullname, len-1);
90 	unload_dll(gsdll);
91 	return 1;
92     }
93     if (rv.revision != GSREVISION) {
94 	sprintf(fullname, "Wrong version of DLL found.\n  Found version %ld\n  Need version  %ld\n", rv.revision, GSREVISION);
95 	strncpy(last_error, fullname, len-1);
96 	unload_dll(gsdll);
97 	return 1;
98     }
99 
100     /* continue loading other functions */
101     gsdll->new_instance = (PFN_gsapi_new_instance) GetProcAddress(gsdll->hmodule,
102 	"gsapi_new_instance");
103     if (gsdll->new_instance == NULL) {
104 	strncpy(last_error, "Can't find gsapi_new_instance\n", len-1);
105 	unload_dll(gsdll);
106 	return 1;
107     }
108 
109     gsdll->delete_instance = (PFN_gsapi_delete_instance) GetProcAddress(gsdll->hmodule,
110 	"gsapi_delete_instance");
111     if (gsdll->delete_instance == NULL) {
112 	strncpy(last_error, "Can't find gsapi_delete_instance\n", len-1);
113 	unload_dll(gsdll);
114 	return 1;
115     }
116 
117     gsdll->set_stdio = (PFN_gsapi_set_stdio) GetProcAddress(gsdll->hmodule,
118 	"gsapi_set_stdio");
119     if (gsdll->set_stdio == NULL) {
120 	strncpy(last_error, "Can't find gsapi_set_stdio\n", len-1);
121 	unload_dll(gsdll);
122 	return 1;
123     }
124 
125     gsdll->set_poll = (PFN_gsapi_set_poll) GetProcAddress(gsdll->hmodule,
126 	"gsapi_set_poll");
127     if (gsdll->set_poll == NULL) {
128 	strncpy(last_error, "Can't find gsapi_set_poll\n", len-1);
129 	unload_dll(gsdll);
130 	return 1;
131     }
132 
133     gsdll->set_display_callback = (PFN_gsapi_set_display_callback)
134 	GetProcAddress(gsdll->hmodule, "gsapi_set_display_callback");
135     if (gsdll->set_display_callback == NULL) {
136 	strncpy(last_error, "Can't find gsapi_set_display_callback\n", len-1);
137 	unload_dll(gsdll);
138 	return 1;
139     }
140 
141     gsdll->init_with_args = (PFN_gsapi_init_with_args)
142 	GetProcAddress(gsdll->hmodule, "gsapi_init_with_args");
143     if (gsdll->init_with_args == NULL) {
144 	strncpy(last_error, "Can't find gsapi_init_with_args\n", len-1);
145 	unload_dll(gsdll);
146 	return 1;
147     }
148 
149     gsdll->run_string = (PFN_gsapi_run_string) GetProcAddress(gsdll->hmodule,
150 	"gsapi_run_string");
151     if (gsdll->run_string == NULL) {
152 	strncpy(last_error, "Can't find gsapi_run_string\n", len-1);
153 	unload_dll(gsdll);
154 	return 1;
155     }
156 
157     gsdll->exit = (PFN_gsapi_exit) GetProcAddress(gsdll->hmodule,
158 	"gsapi_exit");
159     if (gsdll->exit == NULL) {
160 	strncpy(last_error, "Can't find gsapi_exit\n", len-1);
161 	unload_dll(gsdll);
162 	return 1;
163     }
164 
165     gsdll->set_visual_tracer = (PFN_gsapi_set_visual_tracer)
166         GetProcAddress(gsdll->hmodule, "gsapi_set_visual_tracer");
167     if (gsdll->set_visual_tracer == NULL) {
168 	strncpy(last_error, "Can't find gsapi_set_visual_tracer\n", len-1);
169 	unload_dll(gsdll);
170 	return 1;
171     }
172 
173     return 0;
174 }
175 
unload_dll(GSDLL * gsdll)176 void unload_dll(GSDLL *gsdll)
177 {
178     /* Set functions to NULL to prevent use */
179     gsdll->revision = NULL;
180     gsdll->new_instance = NULL;
181     gsdll->delete_instance = NULL;
182     gsdll->init_with_args = NULL;
183     gsdll->run_string = NULL;
184     gsdll->exit = NULL;
185     gsdll->set_stdio = NULL;
186     gsdll->set_poll = NULL;
187     gsdll->set_display_callback = NULL;
188     gsdll->set_visual_tracer = NULL;
189 
190     if (gsdll->hmodule != (HINSTANCE)NULL)
191 	    FreeLibrary(gsdll->hmodule);
192     gsdll->hmodule = NULL;
193 }
194 
195 
196