ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/util_windows.cpp
Revision: 1.6
Committed: 2006-05-01T10:27:16Z (18 years, 7 months ago) by gbeauche
Branch: MAIN
CVS Tags: nigel-build-19
Changes since 1.5: +116 -0 lines
Log Message:
Add ether "tap" support to the GUI. Also fix "slirp" callback.

File Contents

# Content
1 /*
2 * util_windows.cpp - Miscellaneous utilities for Win32
3 *
4 * Basilisk II (C) 1997-2005 Christian Bauer
5 *
6 * Windows platform specific code copyright (C) Lauri Pesonen
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #include "sysdeps.h"
24 #include "util_windows.h"
25 #include "main.h"
26
27 #include <list>
28 using std::list;
29
30 #include <string>
31 using std::string;
32
33 BOOL exists( const char *path )
34 {
35 HFILE h;
36 bool ret = false;
37
38 h = _lopen( path, OF_READ );
39 if(h != HFILE_ERROR) {
40 ret = true;
41 _lclose(h);
42 }
43 return(ret);
44 }
45
46 BOOL create_file( const char *path, DWORD size )
47 {
48 HANDLE h;
49 bool ok = false;
50
51 h = CreateFile( path,
52 GENERIC_READ | GENERIC_WRITE,
53 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL
54 );
55 if(h != INVALID_HANDLE_VALUE) {
56 if(size == 0) {
57 ok = true;
58 } else if(SetFilePointer( h, size, NULL, FILE_BEGIN) != 0xFFFFFFFF) {
59 if(SetEndOfFile(h)) {
60 ok = true;
61 if(SetFilePointer( h, 0, NULL, FILE_BEGIN) != 0xFFFFFFFF) {
62 DWORD written;
63 DWORD zeroed_size = size;
64 if (zeroed_size > 1024*1024)
65 zeroed_size = 1024*1024;
66 char *b = (char *)malloc(zeroed_size);
67 if(b) {
68 memset( b, 0, zeroed_size );
69 WriteFile( h, b, zeroed_size, &written, NULL );
70 free(b);
71 }
72 }
73 }
74 }
75 CloseHandle(h);
76 }
77 if(!ok) DeleteFile(path);
78 return(ok);
79 }
80
81 int32 get_file_size( const char *path )
82 {
83 HANDLE h;
84 DWORD size = 0;
85
86 h = CreateFile( path,
87 GENERIC_READ,
88 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
89 );
90 if(h != INVALID_HANDLE_VALUE) {
91 size = GetFileSize( h, NULL );
92 CloseHandle(h);
93 }
94 return(size);
95 }
96
97
98 /*
99 * Thread wrappers
100 */
101
102 HANDLE create_thread(LPTHREAD_START_ROUTINE start_routine, void *arg)
103 {
104 DWORD dwThreadId;
105 return CreateThread(NULL, 0, start_routine, arg, 0, &dwThreadId);
106 }
107
108 void wait_thread(HANDLE thread)
109 {
110 WaitForSingleObject(thread, INFINITE);
111 CloseHandle(thread);
112 }
113
114 void kill_thread(HANDLE thread)
115 {
116 TerminateThread(thread, 0);
117 }
118
119
120 /*
121 * Check that drivers are installed
122 */
123
124 bool check_drivers(void)
125 {
126 char path[_MAX_PATH];
127 GetSystemDirectory(path, sizeof(path));
128 strcat(path, "\\drivers\\cdenable.sys");
129
130 if (exists(path)) {
131 int32 size = get_file_size(path);
132 if (size != 6112) {
133 char str[256];
134 sprintf(str, "The CD-ROM driver file \"%s\" is too old or corrupted.", path);
135 ErrorAlert(str);
136 return false;
137 }
138 }
139 else {
140 char str[256];
141 sprintf(str, "The CD-ROM driver file \"%s\" is missing.", path);
142 WarningAlert(str);
143 }
144
145 return true;
146 }
147
148
149 /*
150 * Network control panel helpers
151 */
152
153 struct panel_reg {
154 string name;
155 string guid;
156 };
157
158 static list<panel_reg> network_registry;
159 typedef list<panel_reg>::const_iterator network_registry_iterator;
160
161 #define NETWORK_CONNECTIONS_KEY \
162 "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
163
164 static void get_network_registry(void)
165 {
166 LONG status;
167 HKEY network_connections_key;
168 DWORD len;
169 int i = 0;
170
171 if (network_registry.size() > 0)
172 return;
173
174 status = RegOpenKeyEx(
175 HKEY_LOCAL_MACHINE,
176 NETWORK_CONNECTIONS_KEY,
177 0,
178 KEY_READ,
179 &network_connections_key);
180
181 if (status != ERROR_SUCCESS)
182 return;
183
184 while (true) {
185 char enum_name[256];
186 char connection_string[256];
187 HKEY connection_key;
188 char name_data[256];
189 DWORD name_type;
190 const char name_string[] = "Name";
191
192 len = sizeof (enum_name);
193 status = RegEnumKeyEx(
194 network_connections_key,
195 i,
196 enum_name,
197 &len,
198 NULL,
199 NULL,
200 NULL,
201 NULL);
202 if (status != ERROR_SUCCESS)
203 break;
204
205 snprintf (connection_string, sizeof(connection_string),
206 "%s\\%s\\Connection",
207 NETWORK_CONNECTIONS_KEY, enum_name);
208
209 status = RegOpenKeyEx(
210 HKEY_LOCAL_MACHINE,
211 connection_string,
212 0,
213 KEY_READ,
214 &connection_key);
215
216 if (status == ERROR_SUCCESS) {
217 len = sizeof (name_data);
218 status = RegQueryValueEx(
219 connection_key,
220 name_string,
221 NULL,
222 &name_type,
223 (BYTE *)name_data,
224 &len);
225
226 if (status == ERROR_SUCCESS && name_type == REG_SZ) {
227 panel_reg pr;
228 pr.name = name_data;
229 pr.guid = enum_name;
230 network_registry.push_back(pr);
231 }
232 RegCloseKey (connection_key);
233 }
234 ++i;
235 }
236
237 RegCloseKey (network_connections_key);
238 }
239
240 const char *ether_name_to_guid(const char *name)
241 {
242 get_network_registry();
243
244 for (network_registry_iterator it = network_registry.begin(); it != network_registry.end(); it++) {
245 if (strcmp((*it).name.c_str(), name) == 0)
246 return (*it).guid.c_str();
247 }
248
249 return NULL;
250 }
251
252 const char *ether_guid_to_name(const char *guid)
253 {
254 get_network_registry();
255
256 for (network_registry_iterator it = network_registry.begin(); it != network_registry.end(); it++) {
257 if (strcmp((*it).guid.c_str(), guid) == 0)
258 return (*it).name.c_str();
259 }
260
261 return NULL;
262 }
263
264
265 /*
266 * Get TAP-Win32 adapters
267 */
268
269 #define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
270
271 #define TAP_COMPONENT_ID "tap0801"
272
273 const char *ether_tap_devices(void)
274 {
275 HKEY adapter_key;
276 LONG status;
277 DWORD len;
278 int i = 0;
279
280 status = RegOpenKeyEx(
281 HKEY_LOCAL_MACHINE,
282 ADAPTER_KEY,
283 0,
284 KEY_READ,
285 &adapter_key);
286
287 if (status != ERROR_SUCCESS)
288 return NULL;
289
290 list<string> devices;
291
292 while (true) {
293 char enum_name[256];
294 char unit_string[256];
295 HKEY unit_key;
296 char component_id_string[] = "ComponentId";
297 char component_id[256];
298 char net_cfg_instance_id_string[] = "NetCfgInstanceId";
299 char net_cfg_instance_id[256];
300 DWORD data_type;
301
302 len = sizeof (enum_name);
303 status = RegEnumKeyEx(
304 adapter_key,
305 i,
306 enum_name,
307 &len,
308 NULL,
309 NULL,
310 NULL,
311 NULL);
312 if (status != ERROR_SUCCESS)
313 break;
314
315 snprintf (unit_string, sizeof(unit_string), "%s\\%s",
316 ADAPTER_KEY, enum_name);
317
318 status = RegOpenKeyEx(
319 HKEY_LOCAL_MACHINE,
320 unit_string,
321 0,
322 KEY_READ,
323 &unit_key);
324
325 if (status == ERROR_SUCCESS) {
326 len = sizeof (component_id);
327 status = RegQueryValueEx(
328 unit_key,
329 component_id_string,
330 NULL,
331 &data_type,
332 (BYTE *)component_id,
333 &len);
334
335 if (status == ERROR_SUCCESS && data_type == REG_SZ) {
336 len = sizeof (net_cfg_instance_id);
337 status = RegQueryValueEx(
338 unit_key,
339 net_cfg_instance_id_string,
340 NULL,
341 &data_type,
342 (BYTE *)net_cfg_instance_id,
343 &len);
344
345 if (status == ERROR_SUCCESS && data_type == REG_SZ) {
346 if (!strcmp (component_id, TAP_COMPONENT_ID))
347 devices.push_back(net_cfg_instance_id);
348 }
349 }
350 RegCloseKey (unit_key);
351 }
352 ++i;
353 }
354
355 RegCloseKey (adapter_key);
356
357 if (devices.empty())
358 return NULL;
359
360 // The result is a '\0' separated list of strings
361 list<string>::const_iterator it;
362 len = 0;
363 for (it = devices.begin(); it != devices.end(); it++)
364 len += (*it).length() + 1;
365
366 char *names = (char *)malloc(len);
367 if (names) {
368 char *p = names;
369 for (it = devices.begin(); it != devices.end(); it++) {
370 len = (*it).length();
371 strcpy(p, (*it).c_str());
372 p[len] = '\0';
373 p += len + 1;
374 }
375 }
376
377 return names;
378 }