1 /* Copyright (C) 1996-2000 Ghostgum Software Pty Ltd.  All rights reserved.
2 
3   This program is free software; you can redistribute it and/or modify it
4   under the terms of the GNU General Public License as published by the
5   Free Software Foundation; either version 2 of the License, or (at your
6   option) any later version.
7 
8   This program is distributed in the hope that it will be useful, but
9   WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   General Public License for more details.
12 
13   You should have received a copy of the GNU General Public License along
14   with this program; if not, write to the Free Software Foundation, Inc.,
15   59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16 
17 */
18 
19 /* $Id: dwdll.c,v 1.2.2.1.2.1 2003/01/17 00:49:00 giles Exp $ */
20 
21 /* dwdll.c */
22 
23 #define STRICT
24 #include <windows.h>
25 #include <string.h>
26 #include <stdio.h>
27 
28 #include "stdpre.h"
29 #include "gpgetenv.h"
30 #include "gscdefs.h"
31 #define GSREVISION gs_revision
32 
33 #define GSDLLEXPORT
34 #define GSDLLAPI CALLBACK
35 #define GSDLLCALL
36 
37 #include "dwdll.h"
38 
39 static const char name[] = "gsdll32.dll";
40 
load_dll(GSDLL * gsdll,char * last_error,int len)41 int load_dll(GSDLL *gsdll, char *last_error, int len)
42 {
43 char fullname[1024];
44 char *p;
45 long version;
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     return 0;
172 }
173 
unload_dll(GSDLL * gsdll)174 void unload_dll(GSDLL *gsdll)
175 {
176     /* Set functions to NULL to prevent use */
177     gsdll->revision = NULL;
178     gsdll->new_instance = NULL;
179     gsdll->delete_instance = NULL;
180     gsdll->init_with_args = NULL;
181     gsdll->run_string = NULL;
182     gsdll->exit = NULL;
183     gsdll->set_stdio = NULL;
184     gsdll->set_poll = NULL;
185     gsdll->set_display_callback = NULL;
186 
187     if (gsdll->hmodule != (HINSTANCE)NULL)
188 	    FreeLibrary(gsdll->hmodule);
189     gsdll->hmodule = NULL;
190 }
191 
192 
193