OSDN Git Service

import nethack-3.6.0
[jnethack/source.git] / sys / winnt / winnt.c
1 /* NetHack 3.6  winnt.c $NHDT-Date: 1431737068 2015/05/16 00:44:28 $  $NHDT-Branch: master $:$NHDT-Revision: 1.26 $ */
2 /* Copyright (c) NetHack PC Development Team 1993, 1994 */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /*
6  *  WIN32 system functions.
7  *
8  *  Initial Creation: Michael Allison - January 31/93
9  *
10  */
11
12 #define NEED_VARARGS
13 #include "hack.h"
14 #include <dos.h>
15 #ifndef __BORLANDC__
16 #include <direct.h>
17 #endif
18 #include <ctype.h>
19 #include "win32api.h"
20 #include "wintty.h"
21 #ifdef WIN32
22
23 /*
24  * The following WIN32 API routines are used in this file.
25  *
26  * GetDiskFreeSpace
27  * GetVolumeInformation
28  * GetUserName
29  * FindFirstFile
30  * FindNextFile
31  * FindClose
32  *
33  */
34
35 /* globals required within here */
36 HANDLE ffhandle = (HANDLE) 0;
37 WIN32_FIND_DATA ffd;
38
39 /* The function pointer nt_kbhit contains a kbhit() equivalent
40  * which varies depending on which window port is active.
41  * For the tty port it is tty_kbhit() [from nttty.c]
42  * For the win32 port it is win32_kbhit() [from winmain.c]
43  * It is initialized to point to def_kbhit [in here] for safety.
44  */
45
46 int def_kbhit(void);
47 int (*nt_kbhit)() = def_kbhit;
48
49 char
50 switchar()
51 {
52     /* Could not locate a WIN32 API call for this- MJA */
53     return '-';
54 }
55
56 long
57 freediskspace(path)
58 char *path;
59 {
60     char tmppath[4];
61     DWORD SectorsPerCluster = 0;
62     DWORD BytesPerSector = 0;
63     DWORD FreeClusters = 0;
64     DWORD TotalClusters = 0;
65
66     tmppath[0] = *path;
67     tmppath[1] = ':';
68     tmppath[2] = '\\';
69     tmppath[3] = '\0';
70     GetDiskFreeSpace(tmppath, &SectorsPerCluster, &BytesPerSector,
71                      &FreeClusters, &TotalClusters);
72     return (long) (SectorsPerCluster * BytesPerSector * FreeClusters);
73 }
74
75 /*
76  * Functions to get filenames using wildcards
77  */
78 int
79 findfirst(path)
80 char *path;
81 {
82     if (ffhandle) {
83         FindClose(ffhandle);
84         ffhandle = (HANDLE) 0;
85     }
86     ffhandle = FindFirstFile(path, &ffd);
87     return (ffhandle == INVALID_HANDLE_VALUE) ? 0 : 1;
88 }
89
90 int
91 findnext()
92 {
93     return FindNextFile(ffhandle, &ffd) ? 1 : 0;
94 }
95
96 char *
97 foundfile_buffer()
98 {
99     return &ffd.cFileName[0];
100 }
101
102 long
103 filesize(file)
104 char *file;
105 {
106     if (findfirst(file)) {
107         return ((long) ffd.nFileSizeLow);
108     } else
109         return -1L;
110 }
111
112 /*
113  * Chdrive() changes the default drive.
114  */
115 void
116 chdrive(str)
117 char *str;
118 {
119     char *ptr;
120     char drive;
121     if ((ptr = index(str, ':')) != (char *) 0) {
122         drive = toupper(*(ptr - 1));
123         _chdrive((drive - 'A') + 1);
124     }
125 }
126
127 static int
128 max_filename()
129 {
130     DWORD maxflen;
131     int status = 0;
132
133     status = GetVolumeInformation((LPTSTR) 0, (LPTSTR) 0, 0, (LPDWORD) 0,
134                                   &maxflen, (LPDWORD) 0, (LPTSTR) 0, 0);
135     if (status)
136         return maxflen;
137     else
138         return 0;
139 }
140
141 int
142 def_kbhit()
143 {
144     return 0;
145 }
146
147 /*
148  * Strip out troublesome file system characters.
149  */
150
151 void nt_regularize(s) /* normalize file name */
152 register char *s;
153 {
154     register unsigned char *lp;
155
156     for (lp = s; *lp; lp++)
157         if (*lp == '?' || *lp == '"' || *lp == '\\' || *lp == '/'
158             || *lp == '>' || *lp == '<' || *lp == '*' || *lp == '|'
159             || *lp == ':' || (*lp > 127))
160             *lp = '_';
161 }
162
163 /*
164  * This is used in nhlan.c to implement some of the LAN_FEATURES.
165  */
166 char *
167 get_username(lan_username_size)
168 int *lan_username_size;
169 {
170     static TCHAR username_buffer[BUFSZ];
171     unsigned int status;
172     DWORD i = BUFSZ - 1;
173
174     /* i gets updated with actual size */
175     status = GetUserName(username_buffer, &i);
176     if (status)
177         username_buffer[i] = '\0';
178     else
179         Strcpy(username_buffer, "NetHack");
180     if (lan_username_size)
181         *lan_username_size = strlen(username_buffer);
182     return username_buffer;
183 }
184
185 #if 0
186 char *getxxx()
187 {
188 char     szFullPath[MAX_PATH] = "";
189 HMODULE  hInst = NULL;          /* NULL gets the filename of this module */
190
191 GetModuleFileName(hInst, szFullPath, sizeof(szFullPath));
192 return &szFullPath[0];
193 }
194 #endif
195
196 /* fatal error */
197 /*VARARGS1*/
198 void error
199 VA_DECL(const char *, s)
200 {
201     char buf[BUFSZ];
202     VA_START(s);
203     VA_INIT(s, const char *);
204     /* error() may get called before tty is initialized */
205     if (iflags.window_inited)
206         end_screen();
207     if (!strncmpi(windowprocs.name, "tty", 3)) {
208         buf[0] = '\n';
209         (void) vsprintf(&buf[1], s, VA_ARGS);
210         Strcat(buf, "\n");
211         msmsg(buf);
212     } else {
213         (void) vsprintf(buf, s, VA_ARGS);
214         Strcat(buf, "\n");
215         raw_printf(buf);
216     }
217     VA_END();
218     exit(EXIT_FAILURE);
219 }
220
221 void
222 Delay(int ms)
223 {
224     (void) Sleep(ms);
225 }
226
227 extern void NDECL(backsp);
228
229 void
230 win32_abort()
231 {
232     if (wizard) {
233         int c, ci, ct;
234
235         if (!iflags.window_inited)
236             c = 'n';
237         ct = 0;
238         msmsg("Execute debug breakpoint wizard?");
239         while ((ci = nhgetch()) != '\n') {
240             if (ct > 0) {
241                 backsp(); /* \b is visible on NT */
242                 (void) putchar(' ');
243                 backsp();
244                 ct = 0;
245                 c = 'n';
246             }
247             if (ci == 'y' || ci == 'n' || ci == 'Y' || ci == 'N') {
248                 ct = 1;
249                 c = ci;
250                 msmsg("%c", c);
251             }
252         }
253         if (c == 'y')
254             DebugBreak();
255     }
256     abort();
257 }
258
259 static char interjection_buf[INTERJECTION_TYPES][1024];
260 static int interjection[INTERJECTION_TYPES];
261
262 void
263 interject_assistance(num, interjection_type, ptr1, ptr2)
264 int num;
265 int interjection_type;
266 genericptr_t ptr1;
267 genericptr_t ptr2;
268 {
269     switch (num) {
270     case 1: {
271         char *panicmsg = (char *) ptr1;
272         char *datadir = (char *) ptr2;
273         char *tempdir = nh_getenv("TEMP");
274         interjection_type = INTERJECT_PANIC;
275         interjection[INTERJECT_PANIC] = 1;
276         /*
277          * ptr1 = the panic message about to be delivered.
278          * ptr2 = the directory prefix of the dungeon file
279          *        that failed to open.
280          * Check to see if datadir matches tempdir or a
281          * common windows temp location. If it does, inform
282          * the user that they are probably trying to run the
283          * game from within their unzip utility, so the required
284          * files really don't exist at the location. Instruct
285          * them to unpack them first.
286          */
287         if (panicmsg && datadir) {
288             if (!strncmpi(datadir, "C:\\WINDOWS\\TEMP", 15)
289                 || strstri(datadir, "TEMP")
290                 || (tempdir && strstri(datadir, tempdir))) {
291                 (void) strncpy(
292                     interjection_buf[INTERJECT_PANIC],
293                     "\nOne common cause of this error is attempting to "
294                     "execute\n"
295                     "the game by double-clicking on it while it is "
296                     "displayed\n"
297                     "inside an unzip utility.\n\n"
298                     "You have to unzip the contents of the zip file into a\n"
299                     "folder on your system, and then run \"NetHack.exe\" or "
300                     "\n"
301                     "\"NetHackW.exe\" from there.\n\n"
302                     "If that is not the situation, you are encouraged to\n"
303                     "report the error as shown above.\n\n",
304                     1023);
305             }
306         }
307     } break;
308     }
309 }
310
311 void
312 interject(interjection_type)
313 int interjection_type;
314 {
315     if (interjection_type >= 0 && interjection_type < INTERJECTION_TYPES)
316         msmsg(interjection_buf[interjection_type]);
317 }
318
319 #ifdef RUNTIME_PORT_ID
320 /*
321  * _M_IX86 is Defined for x86 processors. This is not defined for x64
322  * processors.
323  * _M_X64  is Defined for x64 processors.
324  * _M_IA64 is Defined for Itanium Processor Family 64-bit processors.
325  * _WIN64  is Defined for applications for Win64.
326  */
327 #ifndef _M_IX86
328 #ifdef _M_X64
329 #define TARGET_PORT "(x64) "
330 #endif
331 #ifdef _M_IA64
332 #define TARGET_PORT "(IA64) "
333 #endif
334 #endif
335
336 #ifndef TARGET_PORT
337 #define TARGET_PORT "(x86) "
338 #endif
339
340 void
341 append_port_id(buf)
342 char *buf;
343 {
344     char *portstr = TARGET_PORT;
345     Sprintf(eos(buf), " %s", portstr);
346 }
347 #endif /* RUNTIME_PORT_ID */
348
349 #endif /* WIN32 */
350
351 /*winnt.c*/