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