VirtualBox

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

Last change on this file since 52356 was 52356, checked in by vboxsync, 10 years ago

SUP: Manual imports.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.3 KB
Line 
1/* $Id: SUPLib-win.cpp 52356 2014-08-11 19:24:00Z vboxsync $ */
2/** @file
3 * VirtualBox Support Library - Windows NT specific parts.
4 */
5
6/*
7 * Copyright (C) 2006-2013 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# undef LOG_DISABLED
34# define LOG_DISABLED
35 /** @todo RTLOGREL_DISABLED */
36# include <iprt/log.h>
37# undef LogRelIt
38# define LogRelIt(pvInst, fFlags, iGroup, fmtargs) do { } while (0)
39#endif
40
41#define USE_NT_DEVICE_IO_CONTROL_FILE
42#include <iprt/nt/nt-and-windows.h>
43
44#include <VBox/sup.h>
45#include <VBox/types.h>
46#include <VBox/err.h>
47#include <VBox/param.h>
48#include <VBox/log.h>
49#include <iprt/assert.h>
50#include <iprt/path.h>
51#include <iprt/string.h>
52#include "../SUPLibInternal.h"
53#include "../SUPDrvIOC.h"
54#ifdef VBOX_WITH_HARDENING
55# include "win/SUPHardenedVerify-win.h"
56#endif
57
58
59/*******************************************************************************
60* Defined Constants And Macros *
61*******************************************************************************/
62/** The support service name. */
63#define SERVICE_NAME "VBoxDrv"
64
65
66/*******************************************************************************
67* Internal Functions *
68*******************************************************************************/
69#ifndef IN_SUP_HARDENED_R3
70static int suplibOsCreateService(void);
71//unused: static int suplibOsUpdateService(void);
72static int suplibOsDeleteService(void);
73static int suplibOsStartService(void);
74static int suplibOsStopService(void);
75#endif
76#ifdef USE_NT_DEVICE_IO_CONTROL_FILE
77static int suplibConvertNtStatus(NTSTATUS rcNt);
78#else
79static int suplibConvertWin32Err(int);
80#endif
81
82/*******************************************************************************
83* Global Variables *
84*******************************************************************************/
85static bool g_fHardenedVerifyInited = false;
86
87
88int suplibOsHardenedVerifyInit(void)
89{
90 if (!g_fHardenedVerifyInited)
91 {
92#if defined(VBOX_WITH_HARDENING) && !defined(IN_SUP_HARDENED_R3) && !defined(IN_SUP_R3_STATIC)
93 supR3HardenedWinInitVersion();
94 int rc = supHardenedWinInitImageVerifier(NULL);
95 if (RT_FAILURE(rc))
96 return rc;
97 supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation(NULL);
98#endif
99 g_fHardenedVerifyInited = true;
100 }
101 return VINF_SUCCESS;
102}
103
104
105int suplibOsHardenedVerifyTerm(void)
106{
107 /** @todo free resources... */
108 return VINF_SUCCESS;
109}
110
111
112int suplibOsInit(PSUPLIBDATA pThis, bool fPreInited, bool fUnrestricted)
113{
114 /*
115 * Make sure the image verifier is fully initialized.
116 */
117 int rc = suplibOsHardenedVerifyInit();
118 if (RT_FAILURE(rc))
119 return rc;
120
121 /*
122 * Done if of pre-inited.
123 */
124 if (fPreInited)
125 {
126#if defined(VBOX_WITH_HARDENING) && !defined(IN_SUP_HARDENED_R3)
127# ifdef IN_SUP_R3_STATIC
128 return VERR_NOT_SUPPORTED;
129# else
130 return VINF_SUCCESS;
131# endif
132#else
133 return VINF_SUCCESS;
134#endif
135 }
136
137 /*
138 * Try open the device.
139 */
140#ifndef IN_SUP_HARDENED_R3
141 uint32_t cTry = 0;
142#endif
143 HANDLE hDevice;
144 for (;;)
145 {
146 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
147
148 static const WCHAR s_wszName[] = L"\\Device\\VBoxDrvU";
149 UNICODE_STRING NtName;
150 NtName.Buffer = (PWSTR)s_wszName;
151 NtName.Length = sizeof(s_wszName) - sizeof(WCHAR) * (fUnrestricted ? 2 : 1);
152 NtName.MaximumLength = NtName.Length;
153
154 OBJECT_ATTRIBUTES ObjAttr;
155 InitializeObjectAttributes(&ObjAttr, &NtName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
156
157 hDevice = RTNT_INVALID_HANDLE_VALUE;
158
159 NTSTATUS rcNt = NtCreateFile(&hDevice,
160 GENERIC_READ | GENERIC_WRITE,
161 &ObjAttr,
162 &Ios,
163 NULL /* Allocation Size*/,
164 FILE_ATTRIBUTE_NORMAL,
165 FILE_SHARE_READ | FILE_SHARE_WRITE,
166 FILE_OPEN,
167 FILE_NON_DIRECTORY_FILE,
168 NULL /*EaBuffer*/,
169 0 /*EaLength*/);
170 if (NT_SUCCESS(rcNt))
171 rcNt = Ios.Status;
172 if (!NT_SUCCESS(rcNt))
173 {
174#ifndef IN_SUP_HARDENED_R3
175 /*
176 * Failed to open, try starting the service and reopen the device
177 * exactly once.
178 */
179 if (cTry == 0 && !NT_SUCCESS(rcNt))
180 {
181 cTry++;
182 suplibOsStartService();
183 continue;
184 }
185#endif
186 switch (rcNt)
187 {
188 /** @todo someone must test what is actually returned. */
189 case STATUS_DEVICE_DOES_NOT_EXIST:
190 case STATUS_DEVICE_NOT_CONNECTED:
191 //case ERROR_BAD_DEVICE:
192 case STATUS_DEVICE_REMOVED:
193 //case ERROR_DEVICE_NOT_AVAILABLE:
194 return VERR_VM_DRIVER_LOAD_ERROR;
195 case STATUS_OBJECT_PATH_NOT_FOUND:
196 case STATUS_NO_SUCH_DEVICE:
197 case STATUS_NO_SUCH_FILE:
198 case STATUS_OBJECT_NAME_NOT_FOUND:
199 return VERR_VM_DRIVER_NOT_INSTALLED;
200 case STATUS_ACCESS_DENIED:
201 case STATUS_SHARING_VIOLATION:
202 return VERR_VM_DRIVER_NOT_ACCESSIBLE;
203 case STATUS_UNSUCCESSFUL:
204 return VERR_SUPLIB_NT_PROCESS_UNTRUSTED_0;
205 case STATUS_TRUST_FAILURE:
206 return VERR_SUPLIB_NT_PROCESS_UNTRUSTED_1;
207 case STATUS_TOO_LATE:
208 return VERR_SUPDRV_HARDENING_EVIL_HANDLE;
209 default:
210 if (SUP_NT_STATUS_IS_VBOX(rcNt)) /* See VBoxDrvNtErr2NtStatus. */
211 return SUP_NT_STATUS_TO_VBOX(rcNt);
212 return VERR_VM_DRIVER_OPEN_ERROR;
213 }
214 }
215 break;
216 }
217
218 /*
219 * We're done.
220 */
221 pThis->hDevice = hDevice;
222 pThis->fUnrestricted = fUnrestricted;
223 return VINF_SUCCESS;
224}
225
226
227#ifndef IN_SUP_HARDENED_R3
228
229int suplibOsInstall(void)
230{
231 int rc = suplibOsCreateService();
232 if (RT_SUCCESS(rc))
233 {
234 int rc2 = suplibOsStartService();
235 if (rc2 != VINF_SUCCESS)
236 rc = rc2;
237 }
238 return rc;
239}
240
241
242int suplibOsUninstall(void)
243{
244 int rc = suplibOsStopService();
245 if (RT_SUCCESS(rc))
246 rc = suplibOsDeleteService();
247 return rc;
248}
249
250
251/**
252 * Creates the service.
253 *
254 * @returns VBox status code.
255 * @retval VWRN_ALREADY_EXISTS if it already exists.
256 */
257static int suplibOsCreateService(void)
258{
259 /*
260 * Assume it didn't exist, so we'll create the service.
261 */
262 int rc;
263 SC_HANDLE hSMgrCreate = OpenSCManager(NULL, NULL, SERVICE_CHANGE_CONFIG);
264 DWORD dwErr = GetLastError();
265 AssertMsg(hSMgrCreate, ("OpenSCManager(,,create) failed dwErr=%d\n", dwErr));
266 if (hSMgrCreate != NULL)
267 {
268 char szDriver[RTPATH_MAX];
269 rc = RTPathExecDir(szDriver, sizeof(szDriver) - sizeof("\\VBoxDrv.sys"));
270 if (RT_SUCCESS(rc))
271 {
272 strcat(szDriver, "\\VBoxDrv.sys");
273 SC_HANDLE hService = CreateService(hSMgrCreate,
274 SERVICE_NAME,
275 "VBox Support Driver",
276 SERVICE_QUERY_STATUS,
277 SERVICE_KERNEL_DRIVER,
278 SERVICE_DEMAND_START,
279 SERVICE_ERROR_NORMAL,
280 szDriver,
281 NULL, NULL, NULL, NULL, NULL);
282 dwErr = GetLastError();
283 if (hService)
284 {
285 CloseServiceHandle(hService);
286 rc = VINF_SUCCESS;
287 }
288 else if (dwErr == ERROR_SERVICE_EXISTS)
289 rc = VWRN_ALREADY_EXISTS;
290 else
291 {
292 AssertMsgFailed(("CreateService failed! dwErr=%Rwa szDriver=%s\n", dwErr, szDriver));
293 rc = RTErrConvertFromWin32(dwErr);
294 }
295 }
296 CloseServiceHandle(hSMgrCreate);
297 }
298 else
299 rc = RTErrConvertFromWin32(GetLastError());
300 return rc;
301}
302
303
304/**
305 * Stops a possibly running service.
306 *
307 * @returns VBox status code.
308 */
309static int suplibOsStopService(void)
310{
311 /*
312 * Assume it didn't exist, so we'll create the service.
313 */
314 int rc;
315 SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_STOP | SERVICE_QUERY_STATUS);
316 DWORD dwErr = GetLastError();
317 AssertMsg(hSMgr, ("OpenSCManager(,,delete) failed dwErr=%d\n", dwErr));
318 if (hSMgr)
319 {
320 SC_HANDLE hService = OpenService(hSMgr, SERVICE_NAME, SERVICE_STOP | SERVICE_QUERY_STATUS);
321 if (hService)
322 {
323 /*
324 * Stop the service.
325 */
326 SERVICE_STATUS Status;
327 QueryServiceStatus(hService, &Status);
328 if (Status.dwCurrentState == SERVICE_STOPPED)
329 rc = VINF_SUCCESS;
330 else if (ControlService(hService, SERVICE_CONTROL_STOP, &Status))
331 {
332 int iWait = 100;
333 while (Status.dwCurrentState == SERVICE_STOP_PENDING && iWait-- > 0)
334 {
335 Sleep(100);
336 QueryServiceStatus(hService, &Status);
337 }
338 if (Status.dwCurrentState == SERVICE_STOPPED)
339 rc = VINF_SUCCESS;
340 else
341 {
342 AssertMsgFailed(("Failed to stop service. status=%d\n", Status.dwCurrentState));
343 rc = VERR_GENERAL_FAILURE;
344 }
345 }
346 else
347 {
348 dwErr = GetLastError();
349 AssertMsgFailed(("ControlService failed with dwErr=%Rwa. status=%d\n", dwErr, Status.dwCurrentState));
350 rc = RTErrConvertFromWin32(dwErr);
351 }
352 CloseServiceHandle(hService);
353 }
354 else
355 {
356 dwErr = GetLastError();
357 if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
358 rc = VINF_SUCCESS;
359 else
360 {
361 AssertMsgFailed(("OpenService failed dwErr=%Rwa\n", dwErr));
362 rc = RTErrConvertFromWin32(dwErr);
363 }
364 }
365 CloseServiceHandle(hSMgr);
366 }
367 return rc;
368}
369
370
371/**
372 * Deletes the service.
373 *
374 * @returns VBox status code.
375 */
376int suplibOsDeleteService(void)
377{
378 /*
379 * Assume it didn't exist, so we'll create the service.
380 */
381 int rc;
382 SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_CHANGE_CONFIG);
383 DWORD dwErr = GetLastError();
384 AssertMsg(hSMgr, ("OpenSCManager(,,delete) failed rc=%d\n", dwErr));
385 if (hSMgr)
386 {
387 SC_HANDLE hService = OpenService(hSMgr, SERVICE_NAME, DELETE);
388 if (hService)
389 {
390 /*
391 * Delete the service.
392 */
393 if (DeleteService(hService))
394 rc = VINF_SUCCESS;
395 else
396 {
397 dwErr = GetLastError();
398 AssertMsgFailed(("DeleteService failed dwErr=%Rwa\n", dwErr));
399 rc = RTErrConvertFromWin32(dwErr);
400 }
401 CloseServiceHandle(hService);
402 }
403 else
404 {
405 dwErr = GetLastError();
406 if (dwErr == ERROR_SERVICE_DOES_NOT_EXIST)
407 rc = VINF_SUCCESS;
408 else
409 {
410 AssertMsgFailed(("OpenService failed dwErr=%Rwa\n", dwErr));
411 rc = RTErrConvertFromWin32(dwErr);
412 }
413 }
414 CloseServiceHandle(hSMgr);
415 }
416 return rc;
417}
418
419#if 0
420/**
421 * Creates the service.
422 *
423 * @returns 0 on success.
424 * @returns -1 on failure.
425 */
426static int suplibOsUpdateService(void)
427{
428 /*
429 * Assume it didn't exist, so we'll create the service.
430 */
431 SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_CHANGE_CONFIG);
432 DWORD LastError = GetLastError(); NOREF(LastError);
433 AssertMsg(hSMgr, ("OpenSCManager(,,delete) failed LastError=%Rwa\n", LastError));
434 if (hSMgr)
435 {
436 SC_HANDLE hService = OpenService(hSMgr, SERVICE_NAME, SERVICE_CHANGE_CONFIG);
437 if (hService)
438 {
439 char szDriver[RTPATH_MAX];
440 int rc = RTPathExecDir(szDriver, sizeof(szDriver) - sizeof("\\VBoxDrv.sys"));
441 if (RT_SUCCESS(rc))
442 {
443 strcat(szDriver, "\\VBoxDrv.sys");
444
445 SC_LOCK hLock = LockServiceDatabase(hSMgr);
446 if (ChangeServiceConfig(hService,
447 SERVICE_KERNEL_DRIVER,
448 SERVICE_DEMAND_START,
449 SERVICE_ERROR_NORMAL,
450 szDriver,
451 NULL, NULL, NULL, NULL, NULL, NULL))
452 {
453
454 UnlockServiceDatabase(hLock);
455 CloseServiceHandle(hService);
456 CloseServiceHandle(hSMgr);
457 return 0;
458 }
459 else
460 {
461 DWORD LastError = GetLastError(); NOREF(LastError);
462 AssertMsgFailed(("ChangeServiceConfig failed LastError=%Rwa\n", LastError));
463 }
464 }
465 UnlockServiceDatabase(hLock);
466 CloseServiceHandle(hService);
467 }
468 else
469 {
470 DWORD LastError = GetLastError(); NOREF(LastError);
471 AssertMsgFailed(("OpenService failed LastError=%Rwa\n", LastError));
472 }
473 CloseServiceHandle(hSMgr);
474 }
475 return -1;
476}
477#endif
478
479
480/**
481 * Attempts to start the service, creating it if necessary.
482 *
483 * @returns VBox status code.
484 */
485static int suplibOsStartService(void)
486{
487 /*
488 * Check if the driver service is there.
489 */
490 SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_QUERY_STATUS | SERVICE_START);
491 if (hSMgr == NULL)
492 {
493 DWORD dwErr = GetLastError();
494 AssertMsgFailed(("couldn't open service manager in SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS mode! (dwErr=%d)\n", dwErr));
495 return RTErrConvertFromWin32(dwErr);
496 }
497
498 /*
499 * Try open our service to check it's status.
500 */
501 SC_HANDLE hService = OpenService(hSMgr, SERVICE_NAME, SERVICE_QUERY_STATUS | SERVICE_START);
502 if (!hService)
503 {
504 /*
505 * Create the service.
506 */
507 int rc = suplibOsCreateService();
508 if (RT_FAILURE(rc))
509 return rc;
510
511 /*
512 * Try open the service.
513 */
514 hService = OpenService(hSMgr, SERVICE_NAME, SERVICE_QUERY_STATUS | SERVICE_START);
515 }
516
517 /*
518 * Check if open and on demand create succeeded.
519 */
520 int rc;
521 if (hService)
522 {
523
524 /*
525 * Query service status to see if we need to start it or not.
526 */
527 SERVICE_STATUS Status;
528 BOOL fRc = QueryServiceStatus(hService, &Status);
529 Assert(fRc);
530 if (Status.dwCurrentState == SERVICE_RUNNING)
531 rc = VINF_ALREADY_INITIALIZED;
532 else
533 {
534 if (Status.dwCurrentState == SERVICE_START_PENDING)
535 rc = VINF_SUCCESS;
536 else
537 {
538 /*
539 * Start it.
540 */
541 if (StartService(hService, 0, NULL))
542 rc = VINF_SUCCESS;
543 else
544 {
545 DWORD dwErr = GetLastError();
546 AssertMsg(fRc, ("StartService failed with dwErr=%Rwa\n", dwErr));
547 rc = RTErrConvertFromWin32(dwErr);
548 }
549 }
550
551 /*
552 * Wait for the service to finish starting.
553 * We'll wait for 10 seconds then we'll give up.
554 */
555 QueryServiceStatus(hService, &Status);
556 if (Status.dwCurrentState == SERVICE_START_PENDING)
557 {
558 int iWait;
559 for (iWait = 100; iWait > 0 && Status.dwCurrentState == SERVICE_START_PENDING; iWait--)
560 {
561 Sleep(100);
562 QueryServiceStatus(hService, &Status);
563 }
564 DWORD dwErr = GetLastError(); NOREF(dwErr);
565 AssertMsg(Status.dwCurrentState != SERVICE_RUNNING,
566 ("Failed to start. dwErr=%Rwa iWait=%d status=%d\n", dwErr, iWait, Status.dwCurrentState));
567 }
568
569 if (Status.dwCurrentState == SERVICE_RUNNING)
570 rc = VINF_SUCCESS;
571 else if (RT_SUCCESS_NP(rc))
572 rc = VERR_GENERAL_FAILURE;
573 }
574
575 /*
576 * Close open handles.
577 */
578 CloseServiceHandle(hService);
579 }
580 else
581 {
582 DWORD dwErr = GetLastError();
583 AssertMsgFailed(("OpenService failed! LastError=%Rwa\n", dwErr));
584 rc = RTErrConvertFromWin32(dwErr);
585 }
586 if (!CloseServiceHandle(hSMgr))
587 AssertFailed();
588
589 return rc;
590}
591
592
593int suplibOsTerm(PSUPLIBDATA pThis)
594{
595 /*
596 * Check if we're inited at all.
597 */
598 if (pThis->hDevice != NULL)
599 {
600 if (!CloseHandle((HANDLE)pThis->hDevice))
601 AssertFailed();
602 pThis->hDevice = NIL_RTFILE; /* yes, that's right */
603 }
604
605 return VINF_SUCCESS;
606}
607
608
609int suplibOsIOCtl(PSUPLIBDATA pThis, uintptr_t uFunction, void *pvReq, size_t cbReq)
610{
611 /*
612 * Issue the device I/O control.
613 */
614 PSUPREQHDR pHdr = (PSUPREQHDR)pvReq;
615 Assert(cbReq == RT_MAX(pHdr->cbIn, pHdr->cbOut));
616# ifdef USE_NT_DEVICE_IO_CONTROL_FILE
617 IO_STATUS_BLOCK Ios;
618 Ios.Status = -1;
619 Ios.Information = 0;
620 NTSTATUS rcNt = NtDeviceIoControlFile((HANDLE)pThis->hDevice, NULL /*hEvent*/, NULL /*pfnApc*/, NULL /*pvApcCtx*/, &Ios,
621 (ULONG)uFunction,
622 pvReq /*pvInput */, pHdr->cbIn /* cbInput */,
623 pvReq /*pvOutput*/, pHdr->cbOut /* cbOutput */);
624 if (NT_SUCCESS(rcNt))
625 {
626 if (NT_SUCCESS(Ios.Status))
627 return VINF_SUCCESS;
628 rcNt = Ios.Status;
629 }
630 return suplibConvertNtStatus(rcNt);
631
632# else
633 DWORD cbReturned = (ULONG)pHdr->cbOut;
634 if (DeviceIoControl((HANDLE)pThis->hDevice, uFunction, pvReq, pHdr->cbIn, pvReq, cbReturned, &cbReturned, NULL))
635 return 0;
636 return suplibConvertWin32Err(GetLastError());
637# endif
638}
639
640
641int suplibOsIOCtlFast(PSUPLIBDATA pThis, uintptr_t uFunction, uintptr_t idCpu)
642{
643 /*
644 * Issue device I/O control.
645 */
646# ifdef USE_NT_DEVICE_IO_CONTROL_FILE
647 IO_STATUS_BLOCK Ios;
648 Ios.Status = -1;
649 Ios.Information = 0;
650 NTSTATUS rcNt = NtDeviceIoControlFile((HANDLE)pThis->hDevice, NULL /*hEvent*/, NULL /*pfnApc*/, NULL /*pvApcCtx*/, &Ios,
651 (ULONG)uFunction,
652 NULL /*pvInput */, 0 /* cbInput */,
653 (PVOID)idCpu /*pvOutput*/, 0 /* cbOutput */);
654 if (NT_SUCCESS(rcNt))
655 {
656 if (NT_SUCCESS(Ios.Status))
657 return VINF_SUCCESS;
658 rcNt = Ios.Status;
659 }
660 return suplibConvertNtStatus(rcNt);
661# else
662 DWORD cbReturned = 0;
663 if (DeviceIoControl((HANDLE)pThis->hDevice, uFunction, NULL, 0, (LPVOID)idCpu, 0, &cbReturned, NULL))
664 return VINF_SUCCESS;
665 return suplibConvertWin32Err(GetLastError());
666# endif
667}
668
669
670int suplibOsPageAlloc(PSUPLIBDATA pThis, size_t cPages, void **ppvPages)
671{
672 NOREF(pThis);
673 *ppvPages = VirtualAlloc(NULL, (size_t)cPages << PAGE_SHIFT, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
674 if (*ppvPages)
675 return VINF_SUCCESS;
676 return RTErrConvertFromWin32(GetLastError());
677}
678
679
680int suplibOsPageFree(PSUPLIBDATA pThis, void *pvPages, size_t /* cPages */)
681{
682 NOREF(pThis);
683 if (VirtualFree(pvPages, 0, MEM_RELEASE))
684 return VINF_SUCCESS;
685 return RTErrConvertFromWin32(GetLastError());
686}
687
688
689# ifndef USE_NT_DEVICE_IO_CONTROL_FILE
690/**
691 * Converts a supdrv win32 error code to an IPRT status code.
692 *
693 * @returns corresponding IPRT error code.
694 * @param rc Win32 error code.
695 */
696static int suplibConvertWin32Err(int rc)
697{
698 /* Conversion program (link with ntdll.lib from ddk):
699 #define _WIN32_WINNT 0x0501
700 #include <windows.h>
701 #include <ntstatus.h>
702 #include <winternl.h>
703 #include <stdio.h>
704
705 int main()
706 {
707 #define CONVERT(a) printf(#a " %#x -> %d\n", a, RtlNtStatusToDosError((a)))
708 CONVERT(STATUS_SUCCESS);
709 CONVERT(STATUS_NOT_SUPPORTED);
710 CONVERT(STATUS_INVALID_PARAMETER);
711 CONVERT(STATUS_UNKNOWN_REVISION);
712 CONVERT(STATUS_INVALID_HANDLE);
713 CONVERT(STATUS_INVALID_ADDRESS);
714 CONVERT(STATUS_NOT_LOCKED);
715 CONVERT(STATUS_IMAGE_ALREADY_LOADED);
716 CONVERT(STATUS_ACCESS_DENIED);
717 CONVERT(STATUS_REVISION_MISMATCH);
718
719 return 0;
720 }
721 */
722
723 switch (rc)
724 {
725 //case 0: return STATUS_SUCCESS;
726 case 0: return VINF_SUCCESS;
727 case ERROR_NOT_SUPPORTED: return VERR_GENERAL_FAILURE;
728 case ERROR_INVALID_PARAMETER: return VERR_INVALID_PARAMETER;
729 case ERROR_UNKNOWN_REVISION: return VERR_INVALID_MAGIC;
730 case ERROR_INVALID_HANDLE: return VERR_INVALID_HANDLE;
731 case ERROR_UNEXP_NET_ERR: return VERR_INVALID_POINTER;
732 case ERROR_NOT_LOCKED: return VERR_LOCK_FAILED;
733 case ERROR_SERVICE_ALREADY_RUNNING: return VERR_ALREADY_LOADED;
734 case ERROR_ACCESS_DENIED: return VERR_PERMISSION_DENIED;
735 case ERROR_REVISION_MISMATCH: return VERR_VERSION_MISMATCH;
736 }
737
738 /* fall back on the default conversion. */
739 return RTErrConvertFromWin32(rc);
740}
741# else
742/**
743 * Reverse of VBoxDrvNtErr2NtStatus
744 * returns VBox status code.
745 * @param rcNt NT status code.
746 */
747static int suplibConvertNtStatus(NTSTATUS rcNt)
748{
749 switch (rcNt)
750 {
751 case STATUS_SUCCESS: return VINF_SUCCESS;
752 case STATUS_NOT_SUPPORTED: return VERR_GENERAL_FAILURE;
753 case STATUS_INVALID_PARAMETER: return VERR_INVALID_PARAMETER;
754 case STATUS_UNKNOWN_REVISION: return VERR_INVALID_MAGIC;
755 case STATUS_INVALID_HANDLE: return VERR_INVALID_HANDLE;
756 case STATUS_INVALID_ADDRESS: return VERR_INVALID_POINTER;
757 case STATUS_NOT_LOCKED: return VERR_LOCK_FAILED;
758 case STATUS_IMAGE_ALREADY_LOADED: return VERR_ALREADY_LOADED;
759 case STATUS_ACCESS_DENIED: return VERR_PERMISSION_DENIED;
760 case STATUS_REVISION_MISMATCH: return VERR_VERSION_MISMATCH;
761 }
762
763 /* See VBoxDrvNtErr2NtStatus. */
764 if (SUP_NT_STATUS_IS_VBOX(rcNt))
765 return SUP_NT_STATUS_TO_VBOX(rcNt);
766
767 /* Fall back on IPRT for the rest. */
768 return RTErrConvertFromNtStatus(rcNt);
769}
770# endif
771
772#endif /* !IN_SUP_HARDENED_R3 */
773
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