1 /* 2 * Include file for WIN32_NATIVE version of CLISP 3 * Bruno Haible 1997-2008, 2017 4 * Sam Steingold 1999-2011, 2017 5 */ 6 7 /* control characters constants */ 8 9 #define BEL 7 /* bell */ 10 /* define NL 10 -- new line, see LISPBIBL.D */ 11 #define RUBOUT 127 /* Rubout = Delete */ 12 #define CRLFstring "\r\n" /* C-String - CR/LF */ 13 14 /* Declaration of operating system functions */ 15 #define WIN32_LEAN_AND_MEAN /* avoid including junk */ 16 #undef unused /* `unused' is used in function declarations. */ 17 #ifdef __MINGW32__ 18 #define ULONGLONG OS_ULONGLONG 19 #define ULONG OS_ULONG 20 #include <windows.h> 21 #undef ULONG 22 #undef ULONGLONG 23 #define unused_void (void) 24 #else 25 #include <windows.h> 26 #define unused_void 27 #endif 28 29 /* Shell object handling for shell link resolution */ 30 #include <objbase.h> 31 #include <shlobj.h> 32 33 /* ShellExecute declaration */ 34 #include <shellapi.h> 35 #define unused unused_void /* restore the unused declaration */ 36 37 /* NtQueryInformationFile http://msdn.microsoft.com/en-us/library/ff567052.aspx 38 It uses IO_STATUS_BLOCK http://msdn.microsoft.com/en-us/library/ff567052.aspx 39 which uses NTSTATUS https://msdn.microsoft.com/en-us/library/ff565436.aspx */ 40 #include <winternl.h> 41 #include <ntstatus.h> 42 43 /* Table of system error messages */ 44 #include <winerror.h> 45 /* extern DWORD GetLastError (void); 46 extern void SetLastError (DWORD ErrCode); 47 extern DWORD FormatMessage (DWORD Flags, LPCVOID Source, DWORD MessageId, DWORD LanguageId, LPTSTR Buffer, DWORD Size, va_list* Arguments); 48 extern int WSAGetLastError (void); */ 49 #define OS_errno GetLastError() 50 #define OS_set_errno(e) SetLastError(e) 51 /* used by error.d, spvw.d, stream.d, pathname.d, socket.d */ 52 53 #define HAVE_STRERROR 1 54 /* used by errunix.d */ 55 56 /* Getting memory. */ 57 #include <malloc.h> 58 extern void* malloc (size_t size); 59 extern void free (void* memblock); 60 /* used by spvw.d */ 61 62 /* Abrupt program termination */ 63 /* win32aux.d overwrites abort() */ 64 extern _Noreturn void abort (void); 65 /* used by spvw.d, debug.d, eval.d, io.d */ 66 67 /* Type of a file handle */ 68 #define Handle HANDLE 69 #define INVALID_HANDLE INVALID_HANDLE_VALUE 70 #define FOREIGN_HANDLE /* box them */ 71 72 /* File handles of standard input, standard output, standard error */ 73 extern Handle stdin_handle; 74 extern Handle stdout_handle; /* see win32aux.d */ 75 extern Handle stderr_handle; 76 extern void init_win32 (void); 77 extern void done_win32 (void); 78 /* used by spvw.d, stream.d */ 79 80 /* Signal handling 81 extern BOOL SetConsoleCtrlHandler (BOOL (*) (DWORD CtrlType), BOOL add); 82 extern HANDLE CreateEvent (SECURITY_ATTRIBUTES* EventAttributes, BOOL ManualReset, BOOL InitialState, LPCTSTR Name); 83 extern BOOL PulseEvent (HANDLE Event); 84 extern HANDLE CreateThread (SECURITY_ATTRIBUTES* ThreadAttributes, DWORD StackSize, THREAD_START_ROUTINE* StartAddress, void* Parameter, DWORD CreationFlags, DWORD* ThreadId); 85 extern DWORD WaitForSingleObject (HANDLE Handle, DWORD Milliseconds); 86 extern DWORD WaitForMultipleObjects (DWORD Count, CONST HANDLE * Handles, BOOL WaitAll, DWORD Milliseconds); 87 extern BOOL TerminateThread (HANDLE Thread, DWORD ExitCode); 88 extern BOOL GetExitCodeThread (HANDLE Thread, DWORD* ExitCode); 89 extern DWORD SuspendThread (HANDLE Thread); 90 extern DWORD ResumeThread (HANDLE Thread); 91 extern BOOL GetThreadContext (HANDLE Thread, LPCONTEXT Context); 92 extern BOOL SetThreadContext (HANDLE Thread, CONST CONTEXT * Context); 93 extern HANDLE GetCurrentProcess (void); 94 extern HANDLE GetCurrentThread (void); 95 extern BOOL DuplicateHandle (HANDLE SourceProcessHandle, HANDLE SourceHandle, HANDLE TargetProcessHandle, LPHANDLE TargetHandle, DWORD DesiredAccess, BOOL InheritHandle, DWORD Options); 96 used by win32aux.d 97 This is the Ctrl-C handler. It is executed in the main thread and must 98 not return! */ 99 extern void interrupt_handler (void); 100 /* Install our intelligent Ctrl-C handler. 101 This should be called only once, and only from the main thread. */ 102 extern void install_sigint_handler (void); 103 /* used by spvw.d */ 104 105 /* Locale definition function */ 106 extern_C char *setlocale (int category, const char *locale); 107 /* used by spvw_ctype.d */ 108 109 /* Character set conversion 110 extern BOOL CharToOem (LPCTSTR Str, LPSTR Dst); 111 extern BOOL OemToChar (LPCTSTR Str, LPSTR Dst); 112 used by win32aux.d */ 113 114 /* Set working directory 115 extern BOOL SetCurrentDirectory (LPCTSTR PathName); 116 used by pathname.d */ 117 118 /* Retrieve working directory 119 extern DWORD GetCurrentDirectory (DWORD BufferLength, LPTSTR Buffer); 120 extern DWORD GetFullPathName (LPCTSTR FileName, DWORD BufferLength, LPTSTR Buffer, LPTSTR* FilePart); 121 The actual value of _MAX_PATH is irrelevant, because we retry the calls to 122 GetCurrentDirectory() and GetFullPathName() if the buffer is too small. */ 123 #ifndef _MAX_PATH 124 #define _MAX_PATH 1024 125 #endif 126 #ifndef MAXPATHLEN 127 #define MAXPATHLEN _MAX_PATH 128 #endif 129 /* used by pathname.d */ 130 131 /* Retrieve information about a file 132 extern DWORD GetLogicalDrives (void); // broken! 133 extern UINT GetDriveType (LPCTSTR RootPathName); 134 extern DWORD GetFileAttributes (LPCTSTR FileName); 135 extern DWORD GetFileType (HANDLE File); 136 extern DWORD GetFileSize (HANDLE File, LPDWORD FileSizeHigh); 137 extern BOOL GetFileInformationByHandle (HANDLE File, BY_HANDLE_FILE_INFORMATION* FileInformation); 138 used by pathname.d, stream.d */ 139 140 struct file_id { /* Unique ID for an open file on this machine */ 141 DWORD nFileIndexHigh; 142 DWORD nFileIndexLow; 143 }; 144 typedef DWORD os_error_code_t; 145 /* fill FI for an exiting namestring */ 146 extern os_error_code_t namestring_file_id(char *namestring,struct file_id *fi); 147 /* fill FI for an existing file handle */ 148 extern os_error_code_t handle_file_id (HANDLE fh, struct file_id *fi); 149 /* if the file IDs are identical, return 1, otherwise return 0 */ 150 extern int file_id_eq (struct file_id *fi1, struct file_id *fi2); 151 152 /* Delete a file 153 extern BOOL DeleteFile (LPCTSTR FileName); 154 used by pathname.d */ 155 156 /* Rename a file 157 extern BOOL MoveFile (LPCTSTR ExistingFileName, LPCTSTR NewFileName); 158 used by pathname.d */ 159 160 /* Directory search 161 extern HANDLE FindFirstFile (LPCTSTR FileName, LPWIN32_FIND_DATA FindFileData); 162 extern BOOL FindNextFile (HANDLE FindFile, LPWIN32_FIND_DATA FindFileData); 163 extern BOOL FindClose (HANDLE FindFile); 164 used by pathname.d */ 165 166 /* Create a directory 167 extern BOOL CreateDirectory (LPCTSTR PathName, SECURITY_ATTRIBUTES* SecurityAttributes); 168 used by pathname.d */ 169 170 /* Delete a directory 171 extern BOOL RemoveDirectory (LPCTSTR PathName); 172 used by pathname.d */ 173 174 /* Working with open files 175 extern HANDLE CreateFile (LPCTSTR FileName, DWORD DesiredAccess, DWORD ShareMode, SECURITY_ATTRIBUTES* SecurityAttributes, DWORD CreationDistribution, DWORD FlagsAndAttributes, HANDLE TemplateFile); 176 extern HANDLE GetStdHandle (DWORD StdHandle); 177 extern DWORD GetFileSize (HANDLE File, LPDWORD FileSizeHigh); 178 extern DWORD SetFilePointer (HANDLE File, LONG DistanceToMove, LONG* DistanceToMoveHigh, DWORD MoveMethod); 179 extern BOOL ReadFile (HANDLE File, void* Buffer, DWORD BytesToRead, DWORD* BytesRead, OVERLAPPED* Overlapped); 180 extern BOOL WriteFile (HANDLE File, const void* Buffer, DWORD BytesToWrite, DWORD* BytesWritten, OVERLAPPED* Overlapped); 181 extern BOOL GetConsoleMode (HANDLE ConsoleHandle, LPDWORD Mode); 182 extern BOOL ReadConsole (HANDLE ConsoleInput, void* Buffer, DWORD BytesToRead, DWORD* BytesRead, void* Reserved); 183 extern BOOL GetNumberOfConsoleInputEvents (HANDLE ConsoleInput, LPDWORD NumberOfEvents); 184 extern BOOL PeekConsoleInput (HANDLE ConsoleInput, PINPUT_RECORD Buffer, DWORD Length, LPDWORD NumberOfEventsRead); 185 extern BOOL ReadConsoleInput (HANDLE ConsoleInput, PINPUT_RECORD Buffer, DWORD Length, LPDWORD NumberOfEventsRead); 186 extern BOOL WriteConsoleInput (HANDLE ConsoleInput, CONST INPUT_RECORD * Buffer, DWORD Length, LPDWORD NumberOfEventsWritten); 187 extern BOOL WriteConsole (HANDLE ConsoleOutput, const void* Buffer, DWORD BytesToWrite, DWORD* BytesWritten, void* Reserved); 188 extern HANDLE CreateEvent (SECURITY_ATTRIBUTES* EventAttributes, BOOL ManualReset, BOOL InitialState, LPCTSTR Name); 189 extern BOOL ResetEvent (HANDLE Event); 190 extern BOOL GetOverlappedResult (HANDLE File, OVERLAPPED* Overlapped, DWORD* NumberOfBytesTransferred, BOOL Wait); 191 extern BOOL CloseHandle (HANDLE Object); 192 //extern BOOL DuplicateHandle (HANDLE SourceProcessHandle, HANDLE SourceHandle, HANDLE TargetProcessHandle, HANDLE* TargetHandle, DWORD DesiredAccess, BOOL InheritHandle, DWORD Options); 193 //extern BOOL FlushFileBuffers (HANDLE File); 194 extern BOOL PeekNamedPipe (HANDLE NamedPipe, void* Buffer, DWORD BufferSize, DWORD* BytesRead, DWORD* TotalBytesAvail, DWORD* BytesLeftThisMessage); 195 extern BOOL PurgeComm (HANDLE File, DWORD Flags); 196 extern BOOL FlushConsoleInputBuffer (HANDLE ConsoleInput); */ 197 #define uAsciiChar uChar.AsciiChar 198 /* used by spvw.d, stream.d, pathname.d, win32aux.d 199 My private error code when Ctrl-C has been pressed. */ 200 #define ERROR_SIGINT ERROR_SUCCESS 201 /* Like ReadConsoleInput with Length==1, but is interruptible by Ctrl-C. */ 202 extern BOOL ReadConsoleInput1 (HANDLE ConsoleInput, PINPUT_RECORD Buffer, LPDWORD NumberOfEventsRead); 203 /* The following functions deal with all kinds of file/pipe/console handles */ 204 extern int fd_read_wont_hang_p (HANDLE fd); 205 #ifdef MICROSOFT 206 typedef long ssize_t; 207 #endif 208 extern ssize_t fd_read (HANDLE fd, void* buf, size_t nbyte, perseverance_t persev); 209 extern ssize_t fd_write (HANDLE fd, const void* buf, size_t nbyte, perseverance_t persev); 210 #define safe_read(fd,buf,nbyte) fd_read(fd,buf,nbyte,persev_partial) 211 #define full_read(fd,buf,nbyte) fd_read(fd,buf,nbyte,persev_full) 212 #define safe_write(fd,buf,nbyte) fd_write(fd,buf,nbyte,persev_partial) 213 #define full_write(fd,buf,nbyte) fd_write(fd,buf,nbyte,persev_full) 214 /* Changing the position within a file. */ 215 /* _off_t is sint32, but the Win32 APIs support 64-bit file offsets. */ 216 #define off_t sint64 217 #undef SIZEOF_OFF_T /* on mingw, it was defined in config.h */ 218 #define SIZEOF_OFF_T 8 219 #ifdef __MINGW32__ 220 #include <io.h> 221 #undef lseek 222 #define lseek clisp_lseek /* avoid collision with prototype in <mingw/io.h> */ 223 #endif 224 extern off_t lseek (HANDLE fd, off_t offset, DWORD mode); 225 #undef SEEK_SET 226 #undef SEEK_CUR 227 #undef SEEK_END 228 #define SEEK_SET FILE_BEGIN 229 #define SEEK_CUR FILE_CURRENT 230 #define SEEK_END FILE_END 231 /* used by spvw.d, stream.d */ 232 233 /* Socket connections */ 234 #ifdef __MINGW32__ 235 /* this kills a warning in </usr/include/w32api/winsock.h> 236 and </usr/include/w32api/winsock2.h>: 237 "fd_set and associated macros have been defined in sys/types. 238 This may cause runtime problems with W32 sockets" 239 Bruno said: 240 I think this warning means that read(), write() don't work on sockets 241 in mingw32. Like on BeOS. CLISP already handles this. 242 See the #ifs around stream.d:low_write_unbuffered_socket() etc. */ 243 #define USE_SYS_TYPES_FD_SET 244 #endif 245 246 #include <winsock2.h> 247 #include <ws2tcpip.h> 248 249 #ifdef __MINGW32__ 250 #undef USE_SYS_TYPES_FD_SET 251 #endif 252 /* extern int WSAStartup (WORD VersionRequested, WSADATA* WSAData); 253 extern int WSAGetLastError (void); 254 extern void WSASetLastError (int Error); 255 extern int WSACancelBlockingCall (void); */ 256 #ifndef socklen_t 257 #define socklen_t int 258 #endif 259 260 /* Reading and writing from a socket */ 261 extern int sock_read (SOCKET fd, void* buf, size_t nbyte, perseverance_t persev); 262 extern int sock_write (SOCKET fd, const void* buf, size_t nbyte, perseverance_t persev); 263 /* Interruptible wait for something on socket */ 264 typedef enum { socket_wait_read, socket_wait_write, socket_wait_except } socket_wait_event; 265 extern int interruptible_socket_wait (SOCKET socket_handle, socket_wait_event waitwhat, struct timeval * timeout_ptr); 266 /* Wrapping and unwrapping of a socket in a Lisp object */ 267 #define allocate_socket(fd) allocate_handle((Handle)(fd)) 268 #define TheSocket(obj) (SOCKET)TheHandle(obj) 269 /* Autoconfiguration macros */ 270 #define HAVE_GETHOSTNAME 271 #ifndef MAXHOSTNAMELEN 272 #define MAXHOSTNAMELEN 64 273 #endif 274 #define HAVE_GETHOSTBYNAME 275 #define HAVE_IPV4 1 276 #define HAVE_IPV6 1 277 #undef HAVE_NETINET_TCP_H 278 #define SETSOCKOPT_CONST const 279 #define SETSOCKOPT_ARG_T char* 280 #define SETSOCKOPT_OPTLEN_T int 281 #define HAVE_SHUTDOWN 282 /* Do not define HAVE_SELECT because select() works on sockets only. 283 used by error.d, misc.d, socket.d, stream.d 284 requires linking with wsock32.lib */ 285 286 /* Hacking the terminal */ 287 #ifdef __MINGW32__ 288 /* #include <io.h> */ 289 #define isatty clisp_isatty /* avoid collision with prototype in <mingw/io.h> */ 290 #endif 291 extern int isatty (HANDLE handle); /* see win32aux.d */ 292 /* used by stream.d */ 293 294 /* Date and time 295 Don't use GetSystemTime(), because it's unreliable. (See comment in 296 MSVC4.0 crt/src/time.c.) Better use GetLocalTime(). 297 //extern void GetLocalTime (SYSTEMTIME* SystemTime); 298 But GetLocalTime() ignores the TZ environment variable, so use _ftime(). */ 299 #include <sys/timeb.h> 300 #ifdef MICROSOFT 301 #define timeb _timeb 302 #define ftime _ftime 303 #endif 304 /* extern void ftime (struct timeb *); */ 305 #include <time.h> 306 /* extern struct tm * localtime (time_t*); 307 extern struct tm * gmtime (time_t*); 308 extern BOOL FileTimeToLocalFileTime (const FILETIME* FileTime, FILETIME* LocalFileTime); 309 extern BOOL FileTimeToSystemTime (const FILETIME* LocalFileTime, SYSTEMTIME* LocalSystemTime); 310 used by time.d */ 311 312 /* Pausing 313 extern void Sleep (DWORD Milliseconds); 314 used by win32aux.d 315 Sleep a certain time. 316 Return true after normal termination, false if interrupted by Ctrl-C. */ 317 extern BOOL msleep (DWORD milliseconds); 318 extern unsigned int sleep (unsigned int seconds); 319 /* used by time.d, socket.d */ 320 321 /* Calling programs 322 extern BOOL CreateProcess (LPCTSTR ApplicationName, LPTSTR CommandLine, 323 LPSECURITY_ATTRIBUTES ProcessAttributes, 324 LPSECURITY_ATTRIBUTES ThreadAttributes, 325 BOOL InheritHandles, DWORD CreationFlags, LPVOID Environment, 326 LPCTSTR CurrentDirectory, LPSTARTUPINFO StartupInfo, 327 LPPROCESS_INFORMATION ProcessInformation); 328 extern BOOL GetExitCodeProcess (HANDLE Process, LPDWORD ExitCode); 329 extern BOOL CreatePipe (PHANDLE ReadPipe, PHANDLE WritePipe, 330 LPSECURITY_ATTRIBUTES PipeAttributes, DWORD Size); 331 extern BOOL DuplicateHandle (HANDLE SourceProcessHandle, HANDLE SourceHandle, 332 HANDLE TargetProcessHandle, LPHANDLE TargetHandle, 333 DWORD DesiredAccess, BOOL InheritHandle, DWORD Options); 334 used by win32aux.d, pathname.d, stream.d */ 335 extern BOOL MyCreateProcess (LPTSTR CommandLine, HANDLE StdInput, 336 HANDLE StdOutput, HANDLE StdError, 337 LPPROCESS_INFORMATION ProcessInformation); 338 /* used by pathname.d, stream.d */ 339 340 /* Getting more information about the machine. 341 extern LONG RegOpenKeyEx (HKEY Key, LPCTSTR SubKey, DWORD Options, REGSAM Desired, PHKEY Result); 342 extern LONG RegQueryValueEx (HKEY Key, LPTSTR ValueName, LPDWORD Reserved, LPDWORD Type, LPBYTE Data, LPDWORD cbData); 343 extern LONG RegCloseKey (HKEY Key); 344 used by misc.d 345 requires linking with advapi32.lib */ 346 347 /* Examining the memory map. 348 extern DWORD VirtualQuery (LPCVOID Address, PMEMORY_BASIC_INFORMATION Buffer, DWORD Length); */ 349 extern void DumpProcessMemoryMap (FILE* out); /* see win32aux.d */ 350 /* used by spvw.d */ 351 352 /* Getting virtual memory 353 //extern void GetSystemInfo (LPSYSTEM_INFO SystemInfo); 354 extern LPVOID VirtualAlloc (LPVOID Address, DWORD Size, DWORD AllocationType, DWORD Protect); 355 extern BOOL VirtualFree (LPVOID Address, DWORD Size, DWORD FreeType); 356 extern BOOL VirtualProtect (LPVOID Address, DWORD Size, DWORD NewProtect, PDWORD OldProtect); 357 //extern HANDLE CreateFileMapping (HANDLE File, LPSECURITY_ATTRIBUTES FileMappingAttributes, DWORD Protect, DWORD MaximumSizeHigh, DWORD MaximumSizeLow, LPCTSTR Name); 358 //extern LPVOID MapViewOfFileEx (HANDLE FileMappingObject, DWORD DesiredAccess, DWORD FileOffsetHigh, DWORD FileOffsetLow, DWORD NumberOfBytesToMap, LPVOID BaseAddress); 359 //extern BOOL UnmapViewOfFile (LPCVOID BaseAddress); */ 360 #define HAVE_WIN32_VM 361 /* So you can write munmap() and mprotect() write by your own. mmap() is 362 emulated, because MapViewOfFileEx() has too many disadvantages. 363 See spvw.d. */ 364 /* #define HAVE_MMAP */ 365 #define HAVE_MUNMAP 366 #define HAVE_WORKING_MPROTECT 367 #if defined(HAVE_MPROTECT) /* mprotect from libgcc uses Unix constants */ 368 #define PROT_NONE 0 369 #define PROT_READ 1 370 #define PROT_READ_WRITE 3 371 #else 372 #define PROT_NONE PAGE_NOACCESS 373 #define PROT_READ PAGE_READONLY 374 #define PROT_READ_WRITE PAGE_READWRITE 375 #endif 376 /* PROT_WRITE, PROT_EXEC not used 377 used by spvw.d */ 378 379 #ifdef FIONBIO /* */ 380 /* for socket.d: non-blocking I/O a la BSD 4.2 */ 381 #define NO_BLOCK_DECL() \ 382 int non_blocking_io = 1 383 #define START_NO_BLOCK(handle, on_fail) \ 384 if (ioctl(handle,FIONBIO,&non_blocking_io)) { on_fail; } 385 #define END_NO_BLOCK(handle, on_fail) do { \ 386 non_blocking_io = 0; \ 387 if (ioctl(handle,FIONBIO,&non_blocking_io)) { on_fail; } \ 388 } while (0) 389 #endif 390