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