Remove Control.Parallel*, now in package parallel
[haskell-directory.git] / cbits / Win32Utils.c
1 /* ----------------------------------------------------------------------------
2    (c) The University of Glasgow 2006
3    
4    Useful Win32 bits
5    ------------------------------------------------------------------------- */
6
7 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
8
9 #include "HsBase.h"
10
11 /* This is the error table that defines the mapping between OS error
12    codes and errno values */
13
14 struct errentry {
15         unsigned long oscode;           /* OS return value */
16         int errnocode;  /* System V error code */
17 };
18
19 static struct errentry errtable[] = {
20         {  ERROR_INVALID_FUNCTION,       EINVAL    },  /* 1 */
21         {  ERROR_FILE_NOT_FOUND,         ENOENT    },  /* 2 */
22         {  ERROR_PATH_NOT_FOUND,         ENOENT    },  /* 3 */
23         {  ERROR_TOO_MANY_OPEN_FILES,    EMFILE    },  /* 4 */
24         {  ERROR_ACCESS_DENIED,          EACCES    },  /* 5 */
25         {  ERROR_INVALID_HANDLE,         EBADF     },  /* 6 */
26         {  ERROR_ARENA_TRASHED,          ENOMEM    },  /* 7 */
27         {  ERROR_NOT_ENOUGH_MEMORY,      ENOMEM    },  /* 8 */
28         {  ERROR_INVALID_BLOCK,          ENOMEM    },  /* 9 */
29         {  ERROR_BAD_ENVIRONMENT,        E2BIG     },  /* 10 */
30         {  ERROR_BAD_FORMAT,             ENOEXEC   },  /* 11 */
31         {  ERROR_INVALID_ACCESS,         EINVAL    },  /* 12 */
32         {  ERROR_INVALID_DATA,           EINVAL    },  /* 13 */
33         {  ERROR_INVALID_DRIVE,          ENOENT    },  /* 15 */
34         {  ERROR_CURRENT_DIRECTORY,      EACCES    },  /* 16 */
35         {  ERROR_NOT_SAME_DEVICE,        EXDEV     },  /* 17 */
36         {  ERROR_NO_MORE_FILES,          ENOENT    },  /* 18 */
37         {  ERROR_LOCK_VIOLATION,         EACCES    },  /* 33 */
38         {  ERROR_BAD_NETPATH,            ENOENT    },  /* 53 */
39         {  ERROR_NETWORK_ACCESS_DENIED,  EACCES    },  /* 65 */
40         {  ERROR_BAD_NET_NAME,           ENOENT    },  /* 67 */
41         {  ERROR_FILE_EXISTS,            EEXIST    },  /* 80 */
42         {  ERROR_CANNOT_MAKE,            EACCES    },  /* 82 */
43         {  ERROR_FAIL_I24,               EACCES    },  /* 83 */
44         {  ERROR_INVALID_PARAMETER,      EINVAL    },  /* 87 */
45         {  ERROR_NO_PROC_SLOTS,          EAGAIN    },  /* 89 */
46         {  ERROR_DRIVE_LOCKED,           EACCES    },  /* 108 */
47         {  ERROR_BROKEN_PIPE,            EPIPE     },  /* 109 */
48         {  ERROR_DISK_FULL,              ENOSPC    },  /* 112 */
49         {  ERROR_INVALID_TARGET_HANDLE,  EBADF     },  /* 114 */
50         {  ERROR_INVALID_HANDLE,         EINVAL    },  /* 124 */
51         {  ERROR_WAIT_NO_CHILDREN,       ECHILD    },  /* 128 */
52         {  ERROR_CHILD_NOT_COMPLETE,     ECHILD    },  /* 129 */
53         {  ERROR_DIRECT_ACCESS_HANDLE,   EBADF     },  /* 130 */
54         {  ERROR_NEGATIVE_SEEK,          EINVAL    },  /* 131 */
55         {  ERROR_SEEK_ON_DEVICE,         EACCES    },  /* 132 */
56         {  ERROR_DIR_NOT_EMPTY,          ENOTEMPTY },  /* 145 */
57         {  ERROR_NOT_LOCKED,             EACCES    },  /* 158 */
58         {  ERROR_BAD_PATHNAME,           ENOENT    },  /* 161 */
59         {  ERROR_MAX_THRDS_REACHED,      EAGAIN    },  /* 164 */
60         {  ERROR_LOCK_FAILED,            EACCES    },  /* 167 */
61         {  ERROR_ALREADY_EXISTS,         EEXIST    },  /* 183 */
62         {  ERROR_FILENAME_EXCED_RANGE,   ENOENT    },  /* 206 */
63         {  ERROR_NESTING_NOT_ALLOWED,    EAGAIN    },  /* 215 */
64         {  ERROR_NOT_ENOUGH_QUOTA,       ENOMEM    }    /* 1816 */
65 };
66
67 /* size of the table */
68 #define ERRTABLESIZE (sizeof(errtable)/sizeof(errtable[0]))
69
70 /* The following two constants must be the minimum and maximum
71    values in the (contiguous) range of Exec Failure errors. */
72 #define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
73 #define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
74
75 /* These are the low and high value in the range of errors that are
76    access violations */
77 #define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
78 #define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
79
80 void maperrno (void)
81 {
82         int i;
83         DWORD dwErrorCode;
84
85         dwErrorCode = GetLastError();
86
87         /* check the table for the OS error code */
88         for (i = 0; i < ERRTABLESIZE; ++i)
89         {
90                 if (dwErrorCode == errtable[i].oscode)
91                 {
92                         errno = errtable[i].errnocode;
93                         return;
94                 }
95         }
96
97         /* The error code wasn't in the table.  We check for a range of */
98         /* EACCES errors or exec failure errors (ENOEXEC).  Otherwise   */
99         /* EINVAL is returned.                                          */
100
101         if (dwErrorCode >= MIN_EACCES_RANGE && dwErrorCode <= MAX_EACCES_RANGE)
102                 errno = EACCES;
103         else
104                 if (dwErrorCode >= MIN_EXEC_ERROR && dwErrorCode <= MAX_EXEC_ERROR)
105                         errno = ENOEXEC;
106                 else
107                         errno = EINVAL;
108 }
109
110 HsWord64 getUSecOfDay(void)
111 {
112     HsWord64 t;
113     FILETIME ft;
114     GetSystemTimeAsFileTime(&ft);
115     t = ((HsWord64)ft.dwHighDateTime << 32) | ft.dwLowDateTime;
116     t = t / 10LL;
117     /* FILETIMES are in units of 100ns,
118        so we divide by 10 to get microseconds */
119     return t;
120 }
121
122 #endif
123