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, 1 month 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

# User Rev Content
1 gbeauche 1.1 /*
2     * util_windows.cpp - Miscellaneous utilities for Win32
3     *
4 gbeauche 1.3 * Basilisk II (C) 1997-2005 Christian Bauer
5 gbeauche 1.1 *
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 gbeauche 1.4 #include "main.h"
26 gbeauche 1.1
27 gbeauche 1.5 #include <list>
28     using std::list;
29    
30     #include <string>
31     using std::string;
32    
33 gbeauche 1.1 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 gbeauche 1.5 DWORD written;
63     DWORD zeroed_size = size;
64     if (zeroed_size > 1024*1024)
65     zeroed_size = 1024*1024;
66 gbeauche 1.1 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 gbeauche 1.2
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 gbeauche 1.4
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 gbeauche 1.5
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 gbeauche 1.6
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     }