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