VirtualBox

source: kBuild/trunk/src/lib/nt/nthlpcore.c@ 2702

Last change on this file since 2702 was 2702, checked in by bird, 11 years ago

kmk/WindowsNT: Avoiding unnecessary stat() calls. Reimplemented stat(), lstat(), fstat(), opendir(), readdir(), and closedir() using native NT APIs.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 16.0 KB
Line 
1/* $Id: nthlpcore.c 2702 2013-11-21 00:11:08Z bird $ */
2/** @file
3 * MSC + NT core helpers functions and globals.
4 */
5
6/*
7 * Copyright (c) 2005-2013 knut st. osmundsen <[email protected]>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * IN THE SOFTWARE.
26 *
27 * Alternatively, the content of this file may be used under the terms of the
28 * GPL version 2 or later, or LGPL version 2.1 or later.
29 */
30
31/*******************************************************************************
32* Header Files *
33*******************************************************************************/
34#include <errno.h>
35#include "nthlp.h"
36#if 1
37# include <stdio.h>
38#endif
39
40
41/*******************************************************************************
42* Global Variables *
43*******************************************************************************/
44MY_NTSTATUS (WINAPI *g_pfnNtClose)(HANDLE);
45MY_NTSTATUS (WINAPI *g_pfnNtCreateFile)(PHANDLE, MY_ACCESS_MASK, MY_OBJECT_ATTRIBUTES *, MY_IO_STATUS_BLOCK *,
46 PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG);
47MY_NTSTATUS (WINAPI *g_pfnNtQueryInformationFile)(HANDLE, MY_IO_STATUS_BLOCK *, PVOID, LONG, MY_FILE_INFORMATION_CLASS);
48MY_NTSTATUS (WINAPI *g_pfnNtQueryVolumeInformationFile)(HANDLE, MY_IO_STATUS_BLOCK *, PVOID, LONG, MY_FS_INFORMATION_CLASS);
49MY_NTSTATUS (WINAPI *g_pfnNtQueryDirectoryFile)(HANDLE, HANDLE, MY_IO_APC_ROUTINE *, PVOID, MY_IO_STATUS_BLOCK *,
50 PVOID, ULONG, MY_FILE_INFORMATION_CLASS, BOOLEAN,
51 MY_UNICODE_STRING *, BOOLEAN);
52BOOLEAN (WINAPI *g_pfnRtlDosPathNameToNtPathName_U)(PCWSTR, MY_UNICODE_STRING *, PCWSTR *, MY_RTL_RELATIVE_NAME_U *);
53MY_NTSTATUS (WINAPI *g_pfnRtlAnsiStringToUnicodeString)(MY_UNICODE_STRING *, MY_ANSI_STRING const *, BOOLEAN);
54
55
56static struct
57{
58 FARPROC *ppfn;
59 const char *pszName;
60} const g_apfnDynamicNtdll[] =
61{
62 { (FARPROC *)&g_pfnNtClose, "NtClose" },
63 { (FARPROC *)&g_pfnNtCreateFile, "NtCreateFile" },
64 { (FARPROC *)&g_pfnNtQueryInformationFile, "NtQueryInformationFile" },
65 { (FARPROC *)&g_pfnNtQueryVolumeInformationFile, "NtQueryVolumeInformationFile" },
66 { (FARPROC *)&g_pfnNtQueryDirectoryFile, "NtQueryDirectoryFile" },
67 { (FARPROC *)&g_pfnRtlDosPathNameToNtPathName_U, "RtlDosPathNameToNtPathName_U" },
68 { (FARPROC *)&g_pfnRtlAnsiStringToUnicodeString, "RtlAnsiStringToUnicodeString" },
69};
70/** Set to 1 if we've successfully resolved the imports, otherwise 0. */
71int g_fResolvedNtImports = 0;
72
73
74
75void birdResolveImportsWorker(void)
76{
77 HMODULE hMod = LoadLibraryW(L"ntdll.dll");
78 int i = sizeof(g_apfnDynamicNtdll) / sizeof(g_apfnDynamicNtdll[0]);
79 while (i-- > 0)
80 {
81 const char *pszSym = g_apfnDynamicNtdll[i].pszName;
82 FARPROC pfn;
83 *g_apfnDynamicNtdll[i].ppfn = pfn = GetProcAddress(hMod, pszSym);
84 if (!pfn)
85 {
86 /* Write short message and die. */
87 static const char s_szMsg[] = "\r\nFatal error resolving NTDLL.DLL symbols!\r\nSymbol: ";
88 DWORD cbWritten;
89 if ( !WriteFile(GetStdHandle(STD_ERROR_HANDLE), s_szMsg, sizeof(s_szMsg) - 1, &cbWritten, NULL)
90 || !WriteFile(GetStdHandle(STD_ERROR_HANDLE), pszSym, (DWORD)strlen(pszSym), &cbWritten, NULL)
91 || !WriteFile(GetStdHandle(STD_ERROR_HANDLE), "\r\n", sizeof("\r\n") - 1, &cbWritten, NULL)
92 )
93 *(void **)i = NULL;
94 ExitProcess(127);
95 }
96 }
97
98 g_fResolvedNtImports = 1;
99}
100
101
102void *birdTmpAlloc(size_t cb)
103{
104 return malloc(cb);
105}
106
107
108void birdTmpFree(void *pv)
109{
110 if (pv)
111 free(pv);
112}
113
114
115void *birdMemAlloc(size_t cb)
116{
117 return malloc(cb);
118}
119
120
121void *birdMemAllocZ(size_t cb)
122{
123 return calloc(cb, 1);
124}
125
126
127void birdMemFree(void *pv)
128{
129 if (pv)
130 free(pv);
131}
132
133
134int birdErrnoFromNtStatus(MY_NTSTATUS rcNt)
135{
136 switch (rcNt)
137 {
138 /* EPERM = 1 */
139 /* ENOENT = 2 */
140 case STATUS_NOT_FOUND:
141 case STATUS_OBJECT_NAME_NOT_FOUND:
142 case STATUS_OBJECT_PATH_NOT_FOUND:
143 case STATUS_OBJECT_NAME_INVALID:
144 case STATUS_INVALID_COMPUTER_NAME:
145 case STATUS_VARIABLE_NOT_FOUND:
146 case STATUS_MESSAGE_NOT_FOUND:
147 case STATUS_DLL_NOT_FOUND:
148 case STATUS_ORDINAL_NOT_FOUND:
149 case STATUS_ENTRYPOINT_NOT_FOUND:
150 case STATUS_PATH_NOT_COVERED:
151 case STATUS_BAD_NETWORK_PATH:
152 case STATUS_DFS_EXIT_PATH_FOUND:
153 case RPC_NT_OBJECT_NOT_FOUND:
154 return ENOENT;
155 /* ESRCH = 3 */
156 case STATUS_PROCESS_NOT_IN_JOB:
157 return ESRCH;
158 /* EINTR = 4 */
159 case STATUS_ALERTED:
160 case STATUS_USER_APC:
161 return EINTR;
162 /* EIO = 5 */
163 /* ENXIO = 6 */
164 /* E2BIG = 7 */
165 /* ENOEXEC = 8 */
166 case STATUS_INVALID_IMAGE_FORMAT:
167 case STATUS_INVALID_IMAGE_NE_FORMAT:
168 case STATUS_INVALID_IMAGE_LE_FORMAT:
169 case STATUS_INVALID_IMAGE_NOT_MZ:
170 case STATUS_INVALID_IMAGE_PROTECT:
171 case STATUS_INVALID_IMAGE_WIN_16:
172 case STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT:
173 case STATUS_IMAGE_CHECKSUM_MISMATCH:
174 case STATUS_IMAGE_MP_UP_MISMATCH:
175 case STATUS_IMAGE_MACHINE_TYPE_MISMATCH:
176 case STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE:
177 case STATUS_SYSTEM_IMAGE_BAD_SIGNATURE:
178 case STATUS_SECTION_NOT_IMAGE:
179 case STATUS_INVALID_IMAGE_WIN_32:
180 case STATUS_INVALID_IMAGE_WIN_64:
181 case STATUS_INVALID_IMAGE_HASH:
182 case STATUS_IMAGE_CERT_REVOKED:
183 return ENOEXEC;
184 /* EBADF = 9 */
185 case STATUS_INVALID_HANDLE:
186 case STATUS_PORT_CLOSED:
187 case STATUS_OPLOCK_HANDLE_CLOSED:
188 case STATUS_HANDLES_CLOSED:
189 case STATUS_FILE_FORCED_CLOSED:
190 return EBADF;
191 /* ECHILD = 10 */
192 /* EAGAIN = 11 */
193 case STATUS_WMI_TRY_AGAIN:
194 case STATUS_GRAPHICS_TRY_AGAIN_LATER:
195 case STATUS_GRAPHICS_TRY_AGAIN_NOW:
196 return EAGAIN;
197 /* ENOMEM = 12 */
198 case STATUS_NO_MEMORY:
199 case STATUS_HV_INSUFFICIENT_MEMORY:
200 case STATUS_INSUFFICIENT_RESOURCES:
201 case STATUS_REMOTE_RESOURCES:
202 case STATUS_INSUFF_SERVER_RESOURCES:
203 return ENOMEM;
204 /* EACCES = 13 */
205 case STATUS_ACCESS_DENIED:
206 case STATUS_NETWORK_ACCESS_DENIED:
207 case RPC_NT_PROXY_ACCESS_DENIED:
208 case STATUS_CTX_SHADOW_DENIED:
209 case STATUS_CTX_WINSTATION_ACCESS_DENIED:
210 return EACCES;
211 /* EFAULT = 14 */
212 case STATUS_ACCESS_VIOLATION:
213 case STATUS_HARDWARE_MEMORY_ERROR:
214 return EFAULT;
215 /* EBUSY = 16 */
216 case STATUS_PIPE_BUSY:
217 case STATUS_RESOURCE_IN_USE:
218 return EBUSY;
219 /* EEXIST = 17 */
220 case STATUS_OBJECT_NAME_EXISTS:
221 case STATUS_OBJECT_NAME_COLLISION:
222 case STATUS_DUPLICATE_NAME:
223 return EEXIST;
224 /* EXDEV = 18 */
225 /* ENODEV = 19 */
226 /* ENOTDIR = 20 */
227 case STATUS_NOT_A_DIRECTORY:
228 case STATUS_DIRECTORY_IS_A_REPARSE_POINT:
229 case STATUS_OBJECT_PATH_SYNTAX_BAD:
230 case STATUS_OBJECT_PATH_INVALID:
231 case STATUS_OBJECT_TYPE_MISMATCH:
232 return ENOTDIR;
233 /* EISDIR = 21 */
234 case STATUS_FILE_IS_A_DIRECTORY:
235 return EISDIR;
236 /* EINVAL = 22 */
237 case STATUS_INVALID_PARAMETER:
238 case STATUS_INVALID_PARAMETER_1:
239 case STATUS_INVALID_PARAMETER_2:
240 case STATUS_INVALID_PARAMETER_3:
241 case STATUS_INVALID_PARAMETER_4:
242 case STATUS_INVALID_PARAMETER_5:
243 case STATUS_INVALID_PARAMETER_6:
244 case STATUS_INVALID_PARAMETER_7:
245 case STATUS_INVALID_PARAMETER_8:
246 case STATUS_INVALID_PARAMETER_9:
247 case STATUS_INVALID_PARAMETER_10:
248 case STATUS_INVALID_PARAMETER_11:
249 case STATUS_INVALID_PARAMETER_12:
250 case STATUS_INVALID_PARAMETER_MIX:
251 return EINVAL;
252 /* ENFILE = 23 */
253 /* EMFILE = 24 */
254 case STATUS_TOO_MANY_OPENED_FILES:
255 return EMFILE;
256 /* ENOTTY = 25 */
257 /* EFBIG = 27 */
258 /* ENOSPC = 28 */
259 case STATUS_DISK_FULL:
260 return ENOSPC;
261 /* ESPIPE = 29 */
262 /* EROFS = 30 */
263 /* EMLINK = 31 */
264 /* EPIPE = 32 */
265 case STATUS_PIPE_BROKEN:
266 case RPC_NT_PIPE_CLOSED:
267 return EPIPE;
268 /* EDOM = 33 */
269 /* ERANGE = 34 */
270 /* EDEADLK = 36 */
271 case STATUS_POSSIBLE_DEADLOCK:
272 return EDEADLK;
273 /* ENAMETOOLONG = 38 */
274 case STATUS_NAME_TOO_LONG:
275 return ENAMETOOLONG;
276 /* ENOLCK = 39 */
277 /* ENOSYS = 40 */
278 case STATUS_NOT_SUPPORTED:
279 return ENOSYS;
280 /* ENOTEMPTY = 41 */
281 case STATUS_DIRECTORY_NOT_EMPTY:
282 return ENOTEMPTY;
283 /* EILSEQ = 42 */
284 /* EADDRINUSE = 100 */
285 /* EADDRNOTAVAIL = 101 */
286 /* EAFNOSUPPORT = 102 */
287 /* EALREADY = 103 */
288 case STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED:
289 case STATUS_DEVICE_ALREADY_ATTACHED:
290 case STATUS_PORT_ALREADY_SET:
291 case STATUS_IMAGE_ALREADY_LOADED:
292 case STATUS_TOKEN_ALREADY_IN_USE:
293 case STATUS_IMAGE_ALREADY_LOADED_AS_DLL:
294 case STATUS_ADDRESS_ALREADY_EXISTS:
295 case STATUS_ADDRESS_ALREADY_ASSOCIATED:
296 return EALREADY;
297 /* EBADMSG = 104 */
298 /* ECANCELED = 105 */
299 /* ECONNABORTED = 106 */
300 /* ECONNREFUSED = 107 */
301 /* ECONNRESET = 108 */
302 /* EDESTADDRREQ = 109 */
303 /* EHOSTUNREACH = 110 */
304 case STATUS_HOST_UNREACHABLE:
305 return EHOSTUNREACH;
306 /* EIDRM = 111 */
307 /* EINPROGRESS = 112 */
308 /* EISCONN = 113 */
309 /* ELOOP = 114 */
310 /* EMSGSIZE = 115 */
311 /* ENETDOWN = 116 */
312 /* ENETRESET = 117 */
313 /* ENETUNREACH = 118 */
314 case STATUS_NETWORK_UNREACHABLE:
315 return ENETUNREACH;
316 /* ENOBUFS = 119 */
317 /* ENODATA = 120 */
318 /* ENOLINK = 121 */
319 /* ENOMSG = 122 */
320 /* ENOPROTOOPT = 123 */
321 /* ENOSR = 124 */
322 /* ENOSTR = 125 */
323 /* ENOTCONN = 126 */
324 /* ENOTRECOVERABLE = 127 */
325 /* ENOTSOCK = 128 */
326 /* ENOTSUP = 129 */
327 /* EOPNOTSUPP = 130 */
328 /* EOTHER = 131 */
329 /* EOVERFLOW = 132 */
330 /* EOWNERDEAD = 133 */
331 /* EPROTO = 134 */
332 /* EPROTONOSUPPORT = 135 */
333 /* EPROTOTYPE = 136 */
334 /* ETIME = 137 */
335 /* ETIMEDOUT = 138 */
336 case STATUS_VIRTUAL_CIRCUIT_CLOSED:
337 case STATUS_TIMEOUT:
338 return ETIMEDOUT;
339
340 /* ETXTBSY = 139 */
341 case STATUS_SHARING_VIOLATION:
342 return ETXTBSY;
343 /* EWOULDBLOCK = 140 */
344 }
345
346#if 1
347 __debugbreak();
348 fprintf(stderr, "rcNt=%#x (%d)\n", rcNt, rcNt);
349#endif
350 return EINVAL;
351}
352
353
354int birdSetErrnoFromNt(MY_NTSTATUS rcNt)
355{
356 errno = birdErrnoFromNtStatus(rcNt);
357 return -1;
358}
359
360
361int birdSetErrnoFromWin32(DWORD dwErr)
362{
363 switch (dwErr)
364 {
365 default:
366 case ERROR_INVALID_FUNCTION: errno = EINVAL; break;
367 case ERROR_FILE_NOT_FOUND: errno = ENOENT; break;
368 case ERROR_PATH_NOT_FOUND: errno = ENOENT; break;
369 case ERROR_TOO_MANY_OPEN_FILES: errno = EMFILE; break;
370 case ERROR_ACCESS_DENIED: errno = EACCES; break;
371 case ERROR_INVALID_HANDLE: errno = EBADF; break;
372 case ERROR_ARENA_TRASHED: errno = ENOMEM; break;
373 case ERROR_NOT_ENOUGH_MEMORY: errno = ENOMEM; break;
374 case ERROR_INVALID_BLOCK: errno = ENOMEM; break;
375 case ERROR_BAD_ENVIRONMENT: errno = E2BIG; break;
376 case ERROR_BAD_FORMAT: errno = ENOEXEC; break;
377 case ERROR_INVALID_ACCESS: errno = EINVAL; break;
378 case ERROR_INVALID_DATA: errno = EINVAL; break;
379 case ERROR_INVALID_DRIVE: errno = ENOENT; break;
380 case ERROR_CURRENT_DIRECTORY: errno = EACCES; break;
381 case ERROR_NOT_SAME_DEVICE: errno = EXDEV; break;
382 case ERROR_NO_MORE_FILES: errno = ENOENT; break;
383 case ERROR_LOCK_VIOLATION: errno = EACCES; break;
384 case ERROR_BAD_NETPATH: errno = ENOENT; break;
385 case ERROR_NETWORK_ACCESS_DENIED: errno = EACCES; break;
386 case ERROR_BAD_NET_NAME: errno = ENOENT; break;
387 case ERROR_FILE_EXISTS: errno = EEXIST; break;
388 case ERROR_CANNOT_MAKE: errno = EACCES; break;
389 case ERROR_FAIL_I24: errno = EACCES; break;
390 case ERROR_INVALID_PARAMETER: errno = EINVAL; break;
391 case ERROR_NO_PROC_SLOTS: errno = EAGAIN; break;
392 case ERROR_DRIVE_LOCKED: errno = EACCES; break;
393 case ERROR_BROKEN_PIPE: errno = EPIPE; break;
394 case ERROR_DISK_FULL: errno = ENOSPC; break;
395 case ERROR_INVALID_TARGET_HANDLE: errno = EBADF; break;
396 case ERROR_WAIT_NO_CHILDREN: errno = ECHILD; break;
397 case ERROR_CHILD_NOT_COMPLETE: errno = ECHILD; break;
398 case ERROR_DIRECT_ACCESS_HANDLE: errno = EBADF; break;
399 case ERROR_NEGATIVE_SEEK: errno = EINVAL; break;
400 case ERROR_SEEK_ON_DEVICE: errno = EACCES; break;
401 case ERROR_DIR_NOT_EMPTY: errno = ENOTEMPTY; break;
402 case ERROR_NOT_LOCKED: errno = EACCES; break;
403 case ERROR_BAD_PATHNAME: errno = ENOENT; break;
404 case ERROR_MAX_THRDS_REACHED: errno = EAGAIN; break;
405 case ERROR_LOCK_FAILED: errno = EACCES; break;
406 case ERROR_ALREADY_EXISTS: errno = EEXIST; break;
407 case ERROR_FILENAME_EXCED_RANGE: errno = ENOENT; break;
408 case ERROR_NESTING_NOT_ALLOWED: errno = EAGAIN; break;
409#ifdef EMLINK
410 case ERROR_TOO_MANY_LINKS: errno = EMLINK; break;
411#endif
412 }
413
414 return -1;
415}
416
417
418int birdSetErrnoToNoMem(void)
419{
420 errno = ENOMEM;
421 return -1;
422}
423
424
425int birdSetErrnoToInvalidArg(void)
426{
427 errno = EINVAL;
428 return -1;
429}
430
431
432int birdSetErrnoToBadFileNo(void)
433{
434 errno = EBADF;
435 return -1;
436}
437
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette