VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp@ 49150

Last change on this file since 49150 was 49150, checked in by vboxsync, 11 years ago

SUPR3: Use NtDeviceIoControlFile instead of DeviceIoControl to avoid wasting precious ticks on silly API conversions.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.0 KB
Line 
1/* $Id: SUPLib-win.cpp 49150 2013-10-17 07:22:02Z vboxsync $ */
2/** @file
3 * VirtualBox Support Library - Windows NT specific parts.
4 */
5
6/*
7 * Copyright (C) 2006-2012 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#define LOG_GROUP LOG_GROUP_SUP
31#ifdef IN_SUP_HARDENED_R3
32# undef DEBUG /* Warning: disables RT_STRICT */
33# define LOG_DISABLED
34 /** @todo RTLOGREL_DISABLED */
35# include <iprt/log.h>
36# undef LogRelIt
37# define LogRelIt(pvInst, fFlags, iGroup, fmtargs) do { } while (0)
38#endif
39
40#define USE_NT_DEVICE_IO_CONTROL_FILE
41#ifdef USE_NT_DEVICE_IO_CONTROL_FILE
42# include <iprt/nt/nt-and-windows.h>
43#else
44# include <Windows.h>
45#endif
46
47#include <VBox/sup.h>
48#include <VBox/types.h>
49#include <VBox/err.h>
50#include <VBox/param.h>
51#include <VBox/log.h>
52#include <iprt/assert.h>
53#include <iprt/path.h>
54#include <iprt/string.h>
55#include "../SUPLibInternal.h"
56#include "../SUPDrvIOC.h"
57
58
59/*******************************************************************************
60* Defined Constants And Macros *
61*******************************************************************************/
62/** The support service name. */
63#define SERVICE_NAME "VBoxDrv"
64/** Win32 Device name - system. */
65#define DEVICE_NAME_SYS "\\\\.\\VBoxDrv"
66/** Win32 Device name - user. */
67#define DEVICE_NAME_USR "\\\\.\\VBoxDrvU"
68/** NT Device name. */
69#define DEVICE_NAME_NT L"\\Device\\VBoxDrv"
70/** Win32 Symlink name. */
71#define DEVICE_NAME_DOS L"\\DosDevices\\VBoxDrv"
72
73
74/*******************************************************************************
75* Internal Functions *
76*******************************************************************************/
77static int suplibOsCreateService(void);
78//unused: static int suplibOsUpdateService(void);
79static int suplibOsDeleteService(void);
80static int suplibOsStartService(void);
81static int suplibOsStopService(void);
82#ifdef USE_NT_DEVICE_IO_CONTROL_FILE
83static int suplibConvertNtStatus(NTSTATUS rcNt);
84#else
85static int suplibConvertWin32Err(int);
86#endif
87
88
89
90
91int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
92{
93 /*
94 * Nothing to do if pre-inited.
95 */
96 if (fPreInited)
97 return VINF_SUCCESS;
98
99 /*
100 * Try open the device.
101 */
102 HANDLE hDevice = CreateFile(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR,
103 GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
104 NULL,
105 OPEN_EXISTING,
106 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
107 NULL);
108 if (hDevice == INVALID_HANDLE_VALUE)
109 {
110#ifndef IN_SUP_HARDENED_R3
111 /*
112 * Try start the service and retry opening it.
113 */
114 suplibOsStartService();
115
116 hDevice = CreateFile(fUnrestricted ? DEVICE_NAME_SYS : DEVICE_NAME_USR,
117 GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
118 NULL,
119 OPEN_EXISTING,
120 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
121 NULL);
122 if (hDevice == INVALID_HANDLE_VALUE)
123#endif /* !IN_SUP_HARDENED_R3 */
124 {
125 int rc = GetLastError();
126 switch (rc)
127 {
128 /** @todo someone must test what is actually returned. */
129 case ERROR_DEV_NOT_EXIST:
130 case ERROR_DEVICE_NOT_CONNECTED:
131 case ERROR_BAD_DEVICE:
132 case ERROR_DEVICE_REMOVED:
133 case ERROR_DEVICE_NOT_AVAILABLE:
134 return VERR_VM_DRIVER_LOAD_ERROR;
135 case ERROR_PATH_NOT_FOUND:
136 case ERROR_FILE_NOT_FOUND:
137 return VERR_VM_DRIVER_NOT_INSTALLED;
138 case ERROR_ACCESS_DENIED:
139 case ERROR_SHARING_VIOLATION:
140 return VERR_VM_DRIVER_NOT_ACCESSIBLE;
141 default:
142 return VERR_VM_DRIVER_OPEN_ERROR;
143 }
144
145 return -1 /** @todo define proper error codes for suplibOsInit failure. */;
146 }
147 }
148
149 /*
150 * We're done.
151 */
152 pThis->hDevice = hDevice;
153 pThis->fUnrestricted = fUnrestricted;
154 return VINF_SUCCESS;
155}
156
157
158#ifndef IN_SUP_HARDENED_R3
159
160int suplibOsInstall(void)
161{
162 return suplibOsCreateService();
163}
164
165
166int suplibOsUninstall(void)
167{
168 int rc = suplibOsStopService();
169 if (!rc)
170 rc = suplibOsDeleteService();
171 return rc;
172}
173
174
175/**
176 * Creates the service.
177 *
178 * @returns 0 on success.
179 * @returns -1 on failure.
180 */
181static int suplibOsCreateService(void)
182{
183 /*
184 * Assume it didn't exist, so we'll create the service.
185 */
186 SC_HANDLE hSMgrCreate = OpenSCManager(NULL, NULL, SERVICE_CHANGE_CONFIG);
187 DWORD LastError = GetLastError(); NOREF(LastError);
188 AssertMsg(hSMgrCreate, ("OpenSCManager(,,create) failed rc=%d\n", LastError));
189 if (hSMgrCreate)
190 {
191 char szDriver[RTPATH_MAX];
192 int rc = RTPathExecDir(szDriver, sizeof(szDriver) - sizeof("\\VBoxDrv.sys"));
193 if (RT_SUCCESS(rc))
194 {
195 strcat(szDriver, "\\VBoxDrv.sys");
196 SC_HANDLE hService = CreateService(hSMgrCreate,
197 SERVICE_NAME,
198 "VBox Support Driver",
199 SERVICE_QUERY_STATUS,
200 SERVICE_KERNEL_DRIVER,
201 SERVICE_DEMAND_START,
202 SERVICE_ERROR_NORMAL,
203 szDriver,
204 NULL, NULL, NULL, NULL, NULL);
205 DWORD LastError = GetLastError(); NOREF(LastError);
206 AssertMsg(hService, ("CreateService failed! LastError=%Rwa szDriver=%s\n", LastError, szDriver));
207 CloseServiceHandle(hService);
208 CloseServiceHandle(hSMgrCreate);
209 return hService ? 0 : -1;
210 }
211 CloseServiceHandle(hSMgrCreate);
212 return rc;
213 }
214 return -1;
215}
216
217
218/**
219 * Stops a possibly running service.
220 *
221 * @returns 0 on success.
222 * @returns -1 on failure.
223 */
224static int suplibOsStopService(void)
225{
226 /*
227 * Assume it didn't exist, so we'll create the service.
228 */
229 int rc = -1;
230 SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_STOP | SERVICE_QUERY_STATUS);
231 DWORD LastError = GetLastError(); NOREF(LastError);
232 AssertMsg(hSMgr, ("OpenSCManager(,,delete) failed rc=%d\n", LastError));
233 if (hSMgr)
234 {
235 SC_HANDLE hService = OpenService(hSMgr, SERVICE_NAME, SERVICE_STOP | SERVICE_QUERY_STATUS);
236 if (hService)
237 {
238 /*
239 * Stop the service.
240 */
241 SERVICE_STATUS Status;
242 QueryServiceStatus(hService, &Status);
243 if (Status.dwCurrentState == SERVICE_STOPPED)
244 rc = 0;
245 else if (ControlService(hService, SERVICE_CONTROL_STOP, &Status))
246 {
247 int iWait = 100;
248 while (Status.dwCurrentState == SERVICE_STOP_PENDING && iWait-- > 0)
249 {
250 Sleep(100);
251 QueryServiceStatus(hService, &Status);
252 }
253 if (Status.dwCurrentState == SERVICE_STOPPED)
254 rc = 0;
255 else
256 AssertMsgFailed(("Failed to stop service. status=%d\n", Status.dwCurrentState));
257 }
258 else
259 {
260 DWORD LastError = GetLastError(); NOREF(LastError);
261 AssertMsgFailed(("ControlService failed with LastError=%Rwa. status=%d\n", LastError, Status.dwCurrentState));
262 }
263 CloseServiceHandle(hService);
264 }
265 else if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
266 rc = 0;
267 else
268 {
269 DWORD LastError = GetLastError(); NOREF(LastError);
270 AssertMsgFailed(("OpenService failed LastError=%Rwa\n", LastError));
271 }
272 CloseServiceHandle(hSMgr);
273 }
274 return rc;
275}
276
277
278/**
279 * Deletes the service.
280 *
281 * @returns 0 on success.
282 * @returns -1 on failure.
283 */
284int suplibOsDeleteService(void)
285{
286 /*
287 * Assume it didn't exist, so we'll create the service.
288 */
289 int rc = -1;
290 SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_CHANGE_CONFIG);
291 DWORD LastError = GetLastError(); NOREF(LastError);
292 AssertMsg(hSMgr, ("OpenSCManager(,,delete) failed rc=%d\n", LastError));
293 if (hSMgr)
294 {
295 SC_HANDLE hService = OpenService(hSMgr, SERVICE_NAME, DELETE);
296 if (hService)
297 {
298 /*
299 * Delete the service.
300 */
301 if (DeleteService(hService))
302 rc = 0;
303 else
304 {
305 DWORD LastError = GetLastError(); NOREF(LastError);
306 AssertMsgFailed(("DeleteService failed LastError=%Rwa\n", LastError));
307 }
308 CloseServiceHandle(hService);
309 }
310 else if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
311 rc = 0;
312 else
313 {
314 DWORD LastError = GetLastError(); NOREF(LastError);
315 AssertMsgFailed(("OpenService failed LastError=%Rwa\n", LastError));
316 }
317 CloseServiceHandle(hSMgr);
318 }
319 return rc;
320}
321
322#if 0
323/**
324 * Creates the service.
325 *
326 * @returns 0 on success.
327 * @returns -1 on failure.
328 */
329static int suplibOsUpdateService(void)
330{
331 /*
332 * Assume it didn't exist, so we'll create the service.
333 */
334 SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_CHANGE_CONFIG);
335 DWORD LastError = GetLastError(); NOREF(LastError);
336 AssertMsg(hSMgr, ("OpenSCManager(,,delete) failed LastError=%Rwa\n", LastError));
337 if (hSMgr)
338 {
339 SC_HANDLE hService = OpenService(hSMgr, SERVICE_NAME, SERVICE_CHANGE_CONFIG);
340 if (hService)
341 {
342 char szDriver[RTPATH_MAX];
343 int rc = RTPathExecDir(szDriver, sizeof(szDriver) - sizeof("\\VBoxDrv.sys"));
344 if (RT_SUCCESS(rc))
345 {
346 strcat(szDriver, "\\VBoxDrv.sys");
347
348 SC_LOCK hLock = LockServiceDatabase(hSMgr);
349 if (ChangeServiceConfig(hService,
350 SERVICE_KERNEL_DRIVER,
351 SERVICE_DEMAND_START,
352 SERVICE_ERROR_NORMAL,
353 szDriver,
354 NULL, NULL, NULL, NULL, NULL, NULL))
355 {
356
357 UnlockServiceDatabase(hLock);
358 CloseServiceHandle(hService);
359 CloseServiceHandle(hSMgr);
360 return 0;
361 }
362 else
363 {
364 DWORD LastError = GetLastError(); NOREF(LastError);
365 AssertMsgFailed(("ChangeServiceConfig failed LastError=%Rwa\n", LastError));
366 }
367 }
368 UnlockServiceDatabase(hLock);
369 CloseServiceHandle(hService);
370 }
371 else
372 {
373 DWORD LastError = GetLastError(); NOREF(LastError);
374 AssertMsgFailed(("OpenService failed LastError=%Rwa\n", LastError));
375 }
376 CloseServiceHandle(hSMgr);
377 }
378 return -1;
379}
380#endif
381
382
383/**
384 * Attempts to start the service, creating it if necessary.
385 *
386 * @returns 0 on success.
387 * @returns -1 on failure.
388 * @param fRetry Indicates retry call.
389 */
390static int suplibOsStartService(void)
391{
392 /*
393 * Check if the driver service is there.
394 */
395 SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_QUERY_STATUS | SERVICE_START);
396 if (hSMgr == NULL)
397 {
398 AssertMsgFailed(("couldn't open service manager in SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS mode!\n"));
399 return -1;
400 }
401
402 /*
403 * Try open our service to check it's status.
404 */
405 SC_HANDLE hService = OpenService(hSMgr, SERVICE_NAME, SERVICE_QUERY_STATUS | SERVICE_START);
406 if (!hService)
407 {
408 /*
409 * Create the service.
410 */
411 int rc = suplibOsCreateService();
412 if (rc)
413 return rc;
414
415 /*
416 * Try open the service.
417 */
418 hService = OpenService(hSMgr, SERVICE_NAME, SERVICE_QUERY_STATUS | SERVICE_START);
419 }
420
421 /*
422 * Check if open and on demand create succeeded.
423 */
424 int rc = -1;
425 if (hService)
426 {
427
428 /*
429 * Query service status to see if we need to start it or not.
430 */
431 SERVICE_STATUS Status;
432 BOOL fRc = QueryServiceStatus(hService, &Status);
433 Assert(fRc);
434 if ( Status.dwCurrentState != SERVICE_RUNNING
435 && Status.dwCurrentState != SERVICE_START_PENDING)
436 {
437 /*
438 * Start it.
439 */
440 fRc = StartService(hService, 0, NULL);
441 DWORD LastError = GetLastError(); NOREF(LastError);
442 AssertMsg(fRc, ("StartService failed with LastError=%Rwa\n", LastError));
443 }
444
445 /*
446 * Wait for the service to finish starting.
447 * We'll wait for 10 seconds then we'll give up.
448 */
449 QueryServiceStatus(hService, &Status);
450 if (Status.dwCurrentState == SERVICE_START_PENDING)
451 {
452 int iWait;
453 for (iWait = 100; iWait > 0 && Status.dwCurrentState == SERVICE_START_PENDING; iWait--)
454 {
455 Sleep(100);
456 QueryServiceStatus(hService, &Status);
457 }
458 DWORD LastError = GetLastError(); NOREF(LastError);
459 AssertMsg(Status.dwCurrentState != SERVICE_RUNNING,
460 ("Failed to start. LastError=%Rwa iWait=%d status=%d\n",
461 LastError, iWait, Status.dwCurrentState));
462 }
463
464 if (Status.dwCurrentState == SERVICE_RUNNING)
465 rc = 0;
466
467 /*
468 * Close open handles.
469 */
470 CloseServiceHandle(hService);
471 }
472 else
473 {
474 DWORD LastError = GetLastError(); NOREF(LastError);
475 AssertMsgFailed(("OpenService failed! LastError=%Rwa\n", LastError));
476 }
477 if (!CloseServiceHandle(hSMgr))
478 AssertFailed();
479
480 return rc;
481}
482
483
484int suplibOsTerm(PSUPLIBDATA pThis)
485{
486 /*
487 * Check if we're inited at all.
488 */
489 if (pThis->hDevice != NULL)
490 {
491 if (!CloseHandle((HANDLE)pThis->hDevice))
492 AssertFailed();
493 pThis->hDevice = NIL_RTFILE; /* yes, that's right */
494 }
495
496 return VINF_SUCCESS;
497}
498
499
500int suplibOsIOCtl(PSUPLIBDATA pThis, uintptr_t uFunction, void *pvReq, size_t cbReq)
501{
502 /*
503 * Issue the device I/O control.
504 */
505 PSUPREQHDR pHdr = (PSUPREQHDR)pvReq;
506 Assert(cbReq == RT_MAX(pHdr->cbIn, pHdr->cbOut));
507# ifdef USE_NT_DEVICE_IO_CONTROL_FILE
508 IO_STATUS_BLOCK Ios;
509 Ios.Status = -1;
510 Ios.Information = 0;
511 NTSTATUS rcNt = NtDeviceIoControlFile((HANDLE)pThis->hDevice, NULL /*hEvent*/, NULL /*pfnApc*/, NULL /*pvApcCtx*/, &Ios,
512 (ULONG)uFunction,
513 pvReq /*pvInput */, pHdr->cbIn /* cbInput */,
514 pvReq /*pvOutput*/, pHdr->cbOut /* cbOutput */);
515 if (NT_SUCCESS(rcNt))
516 {
517 if (NT_SUCCESS(Ios.Status))
518 return VINF_SUCCESS;
519 rcNt = Ios.Status;
520 }
521 return suplibConvertNtStatus(rcNt);
522
523# else
524 DWORD cbReturned = (ULONG)pHdr->cbOut;
525 if (DeviceIoControl((HANDLE)pThis->hDevice, uFunction, pvReq, pHdr->cbIn, pvReq, cbReturned, &cbReturned, NULL))
526 return 0;
527 return suplibConvertWin32Err(GetLastError());
528# endif
529}
530
531
532int suplibOsIOCtlFast(PSUPLIBDATA pThis, uintptr_t uFunction, uintptr_t idCpu)
533{
534 /*
535 * Issue device I/O control.
536 */
537# ifdef USE_NT_DEVICE_IO_CONTROL_FILE
538 IO_STATUS_BLOCK Ios;
539 Ios.Status = -1;
540 Ios.Information = 0;
541 NTSTATUS rcNt = NtDeviceIoControlFile((HANDLE)pThis->hDevice, NULL /*hEvent*/, NULL /*pfnApc*/, NULL /*pvApcCtx*/, &Ios,
542 (ULONG)uFunction,
543 (PVOID)idCpu /*pvInput */, 0 /* cbInput */,
544 NULL /*pvOutput*/, 0 /* cbOutput */);
545 if (NT_SUCCESS(rcNt))
546 {
547 if (NT_SUCCESS(Ios.Status))
548 return VINF_SUCCESS;
549 rcNt = Ios.Status;
550 }
551 return suplibConvertNtStatus(rcNt);
552# else
553 DWORD cbReturned = 0;
554 if (DeviceIoControl((HANDLE)pThis->hDevice, uFunction, NULL, 0, (LPVOID)idCpu, 0, &cbReturned, NULL))
555 return VINF_SUCCESS;
556 return suplibConvertWin32Err(GetLastError());
557# endif
558}
559
560
561int suplibOsPageAlloc(PSUPLIBDATA pThis, size_t cPages, void **ppvPages)
562{
563 NOREF(pThis);
564 *ppvPages = VirtualAlloc(NULL, (size_t)cPages << PAGE_SHIFT, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
565 if (*ppvPages)
566 return VINF_SUCCESS;
567 return RTErrConvertFromWin32(GetLastError());
568}
569
570
571int suplibOsPageFree(PSUPLIBDATA pThis, void *pvPages, size_t /* cPages */)
572{
573 NOREF(pThis);
574 if (VirtualFree(pvPages, 0, MEM_RELEASE))
575 return VINF_SUCCESS;
576 return RTErrConvertFromWin32(GetLastError());
577}
578
579
580# ifndef USE_NT_DEVICE_IO_CONTROL_FILE
581/**
582 * Converts a supdrv win32 error code to an IPRT status code.
583 *
584 * @returns corresponding IPRT error code.
585 * @param rc Win32 error code.
586 */
587static int suplibConvertWin32Err(int rc)
588{
589 /* Conversion program (link with ntdll.lib from ddk):
590 #define _WIN32_WINNT 0x0501
591 #include <windows.h>
592 #include <ntstatus.h>
593 #include <winternl.h>
594 #include <stdio.h>
595
596 int main()
597 {
598 #define CONVERT(a) printf(#a " %#x -> %d\n", a, RtlNtStatusToDosError((a)))
599 CONVERT(STATUS_SUCCESS);
600 CONVERT(STATUS_NOT_SUPPORTED);
601 CONVERT(STATUS_INVALID_PARAMETER);
602 CONVERT(STATUS_UNKNOWN_REVISION);
603 CONVERT(STATUS_INVALID_HANDLE);
604 CONVERT(STATUS_INVALID_ADDRESS);
605 CONVERT(STATUS_NOT_LOCKED);
606 CONVERT(STATUS_IMAGE_ALREADY_LOADED);
607 CONVERT(STATUS_ACCESS_DENIED);
608 CONVERT(STATUS_REVISION_MISMATCH);
609
610 return 0;
611 }
612 */
613
614 switch (rc)
615 {
616 //case 0: return STATUS_SUCCESS;
617 case 0: return VINF_SUCCESS;
618 case ERROR_NOT_SUPPORTED: return VERR_GENERAL_FAILURE;
619 case ERROR_INVALID_PARAMETER: return VERR_INVALID_PARAMETER;
620 case ERROR_UNKNOWN_REVISION: return VERR_INVALID_MAGIC;
621 case ERROR_INVALID_HANDLE: return VERR_INVALID_HANDLE;
622 case ERROR_UNEXP_NET_ERR: return VERR_INVALID_POINTER;
623 case ERROR_NOT_LOCKED: return VERR_LOCK_FAILED;
624 case ERROR_SERVICE_ALREADY_RUNNING: return VERR_ALREADY_LOADED;
625 case ERROR_ACCESS_DENIED: return VERR_PERMISSION_DENIED;
626 case ERROR_REVISION_MISMATCH: return VERR_VERSION_MISMATCH;
627 }
628
629 /* fall back on the default conversion. */
630 return RTErrConvertFromWin32(rc);
631}
632# else
633/**
634 * Reverse of VBoxDrvNtErr2NtStatus
635 * returns VBox status code.
636 * @param rcNt NT status code.
637 */
638static int suplibConvertNtStatus(NTSTATUS rcNt)
639{
640 switch (rcNt)
641 {
642 case STATUS_SUCCESS: return VINF_SUCCESS;
643 case STATUS_NOT_SUPPORTED: return VERR_GENERAL_FAILURE;
644 case STATUS_INVALID_PARAMETER: return VERR_INVALID_PARAMETER;
645 case STATUS_UNKNOWN_REVISION: return VERR_INVALID_MAGIC;
646 case STATUS_INVALID_HANDLE: return VERR_INVALID_HANDLE;
647 case STATUS_INVALID_ADDRESS: return VERR_INVALID_POINTER;
648 case STATUS_NOT_LOCKED: return VERR_LOCK_FAILED;
649 case STATUS_IMAGE_ALREADY_LOADED: return VERR_ALREADY_LOADED;
650 case STATUS_ACCESS_DENIED: return VERR_PERMISSION_DENIED;
651 case STATUS_REVISION_MISMATCH: return VERR_VERSION_MISMATCH;
652 }
653
654 /* Fall back on IPRT for the rest. */
655 return RTErrConvertFromNtStatus(rcNt);
656}
657# endif
658
659#endif /* !IN_SUP_HARDENED_R3 */
660
Note: See TracBrowser for help on using the repository browser.

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