OSDN Git Service

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