1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2018 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Zeev Suraski <zeev@php.net> |
16 * Pierre Joye <pierre@php.net> |
17 +----------------------------------------------------------------------+
18 */
19
20 #include "php.h"
21 #include "winutil.h"
22 #include <bcrypt.h>
23 #include <lmcons.h>
24
php_win32_error_to_msg(HRESULT error)25 PHP_WINUTIL_API char *php_win32_error_to_msg(HRESULT error)
26 {/*{{{*/
27 char *buf = NULL;
28
29 FormatMessage(
30 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
31 NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, 0, NULL
32 );
33
34 return (buf ? (char *) buf : "");
35 }/*}}}*/
36
php_win32_check_trailing_space(const char * path,const size_t path_len)37 int php_win32_check_trailing_space(const char * path, const size_t path_len)
38 {/*{{{*/
39 if (path_len > MAXPATHLEN - 1) {
40 return 1;
41 }
42 if (path) {
43 if (path[0] == ' ' || path[path_len - 1] == ' ') {
44 return 0;
45 } else {
46 return 1;
47 }
48 } else {
49 return 0;
50 }
51 }/*}}}*/
52
53 static BCRYPT_ALG_HANDLE bcrypt_algo;
54 static BOOL has_bcrypt_algo = 0;
55
56 #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
57
58 #ifdef PHP_EXPORTS
php_win32_shutdown_random_bytes(void)59 BOOL php_win32_shutdown_random_bytes(void)
60 {/*{{{*/
61 BOOL ret = TRUE;
62
63 if (has_bcrypt_algo) {
64 ret = NT_SUCCESS(BCryptCloseAlgorithmProvider(bcrypt_algo, 0));
65 has_bcrypt_algo = 0;
66 }
67
68 return ret;
69 }/*}}}*/
70
php_win32_init_random_bytes(void)71 BOOL php_win32_init_random_bytes(void)
72 {/*{{{*/
73 if (has_bcrypt_algo) {
74 return TRUE;
75 }
76
77 has_bcrypt_algo = NT_SUCCESS(BCryptOpenAlgorithmProvider(&bcrypt_algo, BCRYPT_RNG_ALGORITHM, NULL, 0));
78
79 return has_bcrypt_algo;
80 }/*}}}*/
81 #endif
82
php_win32_get_random_bytes(unsigned char * buf,size_t size)83 PHP_WINUTIL_API int php_win32_get_random_bytes(unsigned char *buf, size_t size)
84 { /* {{{ */
85
86 BOOL ret;
87
88 #if 0
89 /* Currently we fail on startup, with CNG API it shows no regressions so far and is secure.
90 Should switch on and try to reinit, if it fails too often on startup. This means also
91 bringing locks back. */
92 if (has_bcrypt_algo == 0) {
93 return FAILURE;
94 }
95 #endif
96
97 /* No sense to loop here, the limit is huge enough. */
98 ret = NT_SUCCESS(BCryptGenRandom(bcrypt_algo, buf, (ULONG)size, 0));
99
100 return ret ? SUCCESS : FAILURE;
101 }
102 /* }}} */
103
104
105 /*
106 * This functions based on the code from the UNIXem project under
107 * the BSD like license. Modified for PHP by ab@php.net
108 *
109 * Home: http://synesis.com.au/software/
110 *
111 * Copyright (c) 2005-2010, Matthew Wilson and Synesis Software
112 */
113
php_win32_code_to_errno(unsigned long w32Err)114 PHP_WINUTIL_API int php_win32_code_to_errno(unsigned long w32Err)
115 {/*{{{*/
116 size_t i;
117
118 struct code_to_errno_map
119 {
120 unsigned long w32Err;
121 int eerrno;
122 };
123
124 static const struct code_to_errno_map errmap[] =
125 {
126 /* 1 */ { ERROR_INVALID_FUNCTION , EINVAL }
127 /* 2 */ , { ERROR_FILE_NOT_FOUND , ENOENT }
128 /* 3 */ , { ERROR_PATH_NOT_FOUND , ENOENT }
129 /* 4 */ , { ERROR_TOO_MANY_OPEN_FILES , EMFILE }
130 /* 5 */ , { ERROR_ACCESS_DENIED , EACCES }
131 /* 6 */ , { ERROR_INVALID_HANDLE , EBADF }
132 /* 7 */ , { ERROR_ARENA_TRASHED , ENOMEM }
133 /* 8 */ , { ERROR_NOT_ENOUGH_MEMORY , ENOMEM }
134 /* 9 */ , { ERROR_INVALID_BLOCK , ENOMEM }
135 /* 10 */ , { ERROR_BAD_ENVIRONMENT , E2BIG }
136 /* 11 */ , { ERROR_BAD_FORMAT , ENOEXEC }
137 /* 12 */ , { ERROR_INVALID_ACCESS , EINVAL }
138 /* 13 */ , { ERROR_INVALID_DATA , EINVAL }
139 /* 14 */ , { ERROR_OUTOFMEMORY , ENOMEM }
140 /* 15 */ , { ERROR_INVALID_DRIVE , ENOENT }
141 /* 16 */ , { ERROR_CURRENT_DIRECTORY , ECURDIR }
142 /* 17 */ , { ERROR_NOT_SAME_DEVICE , EXDEV }
143 /* 18 */ , { ERROR_NO_MORE_FILES , ENOENT }
144 /* 19 */ , { ERROR_WRITE_PROTECT , EROFS }
145 /* 20 */ , { ERROR_BAD_UNIT , ENXIO }
146 /* 21 */ , { ERROR_NOT_READY , EBUSY }
147 /* 22 */ , { ERROR_BAD_COMMAND , EIO }
148 /* 23 */ , { ERROR_CRC , EIO }
149 /* 24 */ , { ERROR_BAD_LENGTH , EIO }
150 /* 25 */ , { ERROR_SEEK , EIO }
151 /* 26 */ , { ERROR_NOT_DOS_DISK , EIO }
152 /* 27 */ , { ERROR_SECTOR_NOT_FOUND , ENXIO }
153 /* 28 */ , { ERROR_OUT_OF_PAPER , EBUSY }
154 /* 29 */ , { ERROR_WRITE_FAULT , EIO }
155 /* 30 */ , { ERROR_READ_FAULT , EIO }
156 /* 31 */ , { ERROR_GEN_FAILURE , EIO }
157 /* 32 */ , { ERROR_SHARING_VIOLATION , EAGAIN }
158 /* 33 */ , { ERROR_LOCK_VIOLATION , EACCES }
159 /* 34 */ , { ERROR_WRONG_DISK , ENXIO }
160 /* 35 */ , { 35 , ENFILE }
161 /* 36 */ , { ERROR_SHARING_BUFFER_EXCEEDED , ENFILE }
162 /* 37 */ , { ERROR_HANDLE_EOF , EINVAL }
163 /* 38 */ , { ERROR_HANDLE_DISK_FULL , ENOSPC }
164 #if 0
165 /* 39 */ , { 0 , 0 }
166 /* 40 */ , { 0 , 0 }
167 /* 41 */ , { 0 , 0 }
168 /* 42 */ , { 0 , 0 }
169 /* 43 */ , { 0 , 0 }
170 /* 44 */ , { 0 , 0 }
171 /* 45 */ , { 0 , 0 }
172 /* 46 */ , { 0 , 0 }
173 /* 47 */ , { 0 , 0 }
174 /* 48 */ , { 0 , 0 }
175 /* 49 */ , { 0 , 0 }
176 #endif
177 /* 50 */ , { ERROR_NOT_SUPPORTED , ENOSYS }
178 #if 0
179 /* 51 */ , { 0 , 0 }
180 /* 52 */ , { 0 , 0 }
181 #endif
182 /* 53 */ , { ERROR_BAD_NETPATH , ENOENT }
183 #if 0
184 /* 54 */ , { 0 , 0 }
185 /* 55 */ , { 0 , 0 }
186 /* 56 */ , { 0 , 0 }
187 /* 57 */ , { 0 , 0 }
188 /* 58 */ , { 0 , 0 }
189 /* 59 */ , { 0 , 0 }
190 /* 60 */ , { 0 , 0 }
191 /* 61 */ , { 0 , 0 }
192 /* 62 */ , { 0 , 0 }
193 /* 63 */ , { 0 , 0 }
194 /* 64 */ , { 0 , 0 }
195 #endif
196 /* 65 */ , { ERROR_NETWORK_ACCESS_DENIED , EACCES }
197 #if 0
198 /* 66 */ , { 0 , 0 }
199 #endif
200 /* 67 */ , { ERROR_BAD_NET_NAME , ENOENT }
201 #if 0
202 /* 68 */ , { 0 , 0 }
203 /* 69 */ , { 0 , 0 }
204 /* 70 */ , { 0 , 0 }
205 /* 71 */ , { 0 , 0 }
206 /* 72 */ , { 0 , 0 }
207 /* 73 */ , { 0 , 0 }
208 /* 74 */ , { 0 , 0 }
209 /* 75 */ , { 0 , 0 }
210 /* 76 */ , { 0 , 0 }
211 /* 77 */ , { 0 , 0 }
212 /* 78 */ , { 0 , 0 }
213 /* 79 */ , { 0 , 0 }
214 #endif
215 /* 80 */ , { ERROR_FILE_EXISTS , EEXIST }
216 #if 0
217 /* 81 */ , { 0 , 0 }
218 #endif
219 /* 82 */ , { ERROR_CANNOT_MAKE , EACCES }
220 /* 83 */ , { ERROR_FAIL_I24 , EACCES }
221 #if 0
222 /* 84 */ , { 0 , 0 }
223 /* 85 */ , { 0 , 0 }
224 /* 86 */ , { 0 , 0 }
225 #endif
226 /* 87 */ , { ERROR_INVALID_PARAMETER , EINVAL }
227 #if 0
228 /* 88 */ , { 0 , 0 }
229 #endif
230 /* 89 */ , { ERROR_NO_PROC_SLOTS , EAGAIN }
231 #if 0
232 /* 90 */ , { 0 , 0 }
233 /* 91 */ , { 0 , 0 }
234 /* 92 */ , { 0 , 0 }
235 /* 93 */ , { 0 , 0 }
236 /* 94 */ , { 0 , 0 }
237 /* 95 */ , { 0 , 0 }
238 /* 96 */ , { 0 , 0 }
239 /* 97 */ , { 0 , 0 }
240 /* 98 */ , { 0 , 0 }
241 /* 99 */ , { 0 , 0 }
242 /* 100 */ , { 0 , 0 }
243 /* 101 */ , { 0 , 0 }
244 /* 102 */ , { 0 , 0 }
245 /* 103 */ , { 0 , 0 }
246 /* 104 */ , { 0 , 0 }
247 /* 105 */ , { 0 , 0 }
248 /* 106 */ , { 0 , 0 }
249 /* 107 */ , { 0 , 0 }
250 #endif
251 /* 108 */ , { ERROR_DRIVE_LOCKED , EACCES }
252 /* 109 */ , { ERROR_BROKEN_PIPE , EPIPE }
253 #if 0
254 /* 110 */ , { 0 , 0 }
255 #endif
256 /* 111 */ , { ERROR_BUFFER_OVERFLOW , ENAMETOOLONG }
257 /* 112 */ , { ERROR_DISK_FULL , ENOSPC }
258 #if 0
259 /* 113 */ , { 0 , 0 }
260 #endif
261 /* 114 */ , { ERROR_INVALID_TARGET_HANDLE , EBADF }
262 #if 0
263 /* 115 */ , { 0 , 0 }
264 /* 116 */ , { 0 , 0 }
265 /* 117 */ , { 0 , 0 }
266 /* 118 */ , { 0 , 0 }
267 /* 119 */ , { 0 , 0 }
268 /* 120 */ , { 0 , 0 }
269 /* 121 */ , { 0 , 0 }
270 #endif
271 /* 122 */ , { ERROR_INSUFFICIENT_BUFFER , ERANGE }
272 /* 123 */ , { ERROR_INVALID_NAME , ENOENT }
273 /* 124 */ , { ERROR_INVALID_HANDLE , EINVAL }
274 #if 0
275 /* 125 */ , { 0 , 0 }
276 #endif
277 /* 126 */ , { ERROR_MOD_NOT_FOUND , ENOENT }
278 /* 127 */ , { ERROR_PROC_NOT_FOUND , ENOENT }
279 /* 128 */ , { ERROR_WAIT_NO_CHILDREN , ECHILD }
280 /* 129 */ , { ERROR_CHILD_NOT_COMPLETE , ECHILD }
281 /* 130 */ , { ERROR_DIRECT_ACCESS_HANDLE , EBADF }
282 /* 131 */ , { ERROR_NEGATIVE_SEEK , EINVAL }
283 /* 132 */ , { ERROR_SEEK_ON_DEVICE , EACCES }
284 #if 0
285 /* 133 */ , { 0 , 0 }
286 /* 134 */ , { 0 , 0 }
287 /* 135 */ , { 0 , 0 }
288 /* 136 */ , { 0 , 0 }
289 /* 137 */ , { 0 , 0 }
290 /* 138 */ , { 0 , 0 }
291 /* 139 */ , { 0 , 0 }
292 /* 140 */ , { 0 , 0 }
293 /* 141 */ , { 0 , 0 }
294 /* 142 */ , { 0 , 0 }
295 /* 143 */ , { 0 , 0 }
296 /* 144 */ , { 0 , 0 }
297 #endif
298 /* 145 */ , { ERROR_DIR_NOT_EMPTY , ENOTEMPTY }
299 #if 0
300 /* 146 */ , { 0 , 0 }
301 /* 147 */ , { 0 , 0 }
302 /* 148 */ , { 0 , 0 }
303 /* 149 */ , { 0 , 0 }
304 /* 150 */ , { 0 , 0 }
305 /* 151 */ , { 0 , 0 }
306 /* 152 */ , { 0 , 0 }
307 /* 153 */ , { 0 , 0 }
308 /* 154 */ , { 0 , 0 }
309 /* 155 */ , { 0 , 0 }
310 /* 156 */ , { 0 , 0 }
311 /* 157 */ , { 0 , 0 }
312 #endif
313 /* 158 */ , { ERROR_NOT_LOCKED , EACCES }
314 #if 0
315 /* 159 */ , { 0 , 0 }
316 /* 160 */ , { 0 , 0 }
317 #endif
318 /* 161 */ , { ERROR_BAD_PATHNAME , ENOENT }
319 #if 0
320 /* 162 */ , { 0 , 0 }
321 /* 163 */ , { 0 , 0 }
322 #endif
323 /* 164 */ , { ERROR_MAX_THRDS_REACHED , EAGAIN }
324 #if 0
325 /* 165 */ , { 0 , 0 }
326 /* 166 */ , { 0 , 0 }
327 #endif
328 /* 167 */ , { ERROR_LOCK_FAILED , EACCES }
329 #if 0
330 /* 168 */ , { 0 , 0 }
331 /* 169 */ , { 0 , 0 }
332 /* 170 */ , { 0 , 0 }
333 /* 171 */ , { 0 , 0 }
334 /* 172 */ , { 0 , 0 }
335 /* 173 */ , { 0 , 0 }
336 /* 174 */ , { 0 , 0 }
337 /* 175 */ , { 0 , 0 }
338 /* 176 */ , { 0 , 0 }
339 /* 177 */ , { 0 , 0 }
340 /* 178 */ , { 0 , 0 }
341 /* 179 */ , { 0 , 0 }
342 /* 180 */ , { 0 , 0 }
343 /* 181 */ , { 0 , 0 }
344 /* 182 */ , { 0 , 0 }
345 #endif
346 /* 183 */ , { ERROR_ALREADY_EXISTS , EEXIST }
347 #if 0
348 /* 184 */ , { 0 , 0 }
349 /* 185 */ , { 0 , 0 }
350 /* 186 */ , { 0 , 0 }
351 /* 187 */ , { 0 , 0 }
352 /* 188 */ , { 0 , 0 }
353 /* 189 */ , { 0 , 0 }
354 /* 190 */ , { 0 , 0 }
355 /* 191 */ , { 0 , 0 }
356 /* 192 */ , { 0 , 0 }
357 /* 193 */ , { 0 , 0 }
358 /* 194 */ , { 0 , 0 }
359 /* 195 */ , { 0 , 0 }
360 /* 196 */ , { 0 , 0 }
361 /* 197 */ , { 0 , 0 }
362 /* 198 */ , { 0 , 0 }
363 /* 199 */ , { 0 , 0 }
364 #endif
365
366 /* 206 */ , { ERROR_FILENAME_EXCED_RANGE , ENAMETOOLONG }
367
368 /* 215 */ , { ERROR_NESTING_NOT_ALLOWED , EAGAIN }
369 /* 258 */ , { WAIT_TIMEOUT, ETIME}
370
371 /* 267 */ , { ERROR_DIRECTORY , ENOTDIR }
372 /* 336 */ , { ERROR_DIRECTORY_NOT_SUPPORTED , EISDIR }
373
374 /* 996 */ , { ERROR_IO_INCOMPLETE , EAGAIN }
375 /* 997 */ , { ERROR_IO_PENDING , EAGAIN }
376
377 /* 1004 */ , { ERROR_INVALID_FLAGS , EINVAL }
378 /* 1113 */ , { ERROR_NO_UNICODE_TRANSLATION , EINVAL }
379 /* 1168 */ , { ERROR_NOT_FOUND , ENOENT }
380 /* 1224 */ , { ERROR_USER_MAPPED_FILE , EACCES }
381 /* 1816 */ , { ERROR_NOT_ENOUGH_QUOTA , ENOMEM }
382 , { ERROR_ABANDONED_WAIT_0 , EIO }
383 };
384
385 for(i = 0; i < sizeof(errmap)/sizeof(struct code_to_errno_map); ++i)
386 {
387 if(w32Err == errmap[i].w32Err)
388 {
389 return errmap[i].eerrno;
390 }
391 }
392
393 assert(!"Unrecognised value");
394
395 return EINVAL;
396 }/*}}}*/
397
php_win32_get_username(void)398 PHP_WINUTIL_API char *php_win32_get_username(void)
399 {/*{{{*/
400 wchar_t unamew[UNLEN + 1];
401 size_t uname_len;
402 char *uname;
403 DWORD unsize = UNLEN;
404
405 GetUserNameW(unamew, &unsize);
406 uname = php_win32_cp_conv_w_to_any(unamew, unsize - 1, &uname_len);
407 if (!uname) {
408 return NULL;
409 }
410
411 /* Ensure the length doesn't overflow. */
412 if (uname_len > UNLEN) {
413 uname[uname_len] = '\0';
414 }
415
416 return uname;
417 }/*}}}*/
418
419 /*
420 * Local variables:
421 * tab-width: 4
422 * c-basic-offset: 4
423 * End:
424 * vim600: sw=4 ts=4 fdm=marker
425 * vim<600: sw=4 ts=4
426 */
427