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