VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibIdc-win.cpp@ 68550

Last change on this file since 68550 was 68550, checked in by vboxsync, 7 years ago

merging vbglioc r117689: Initial VBoxGuest I/O control changes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1/* $Id: VBoxGuestR0LibIdc-win.cpp 68550 2017-08-31 12:09:41Z vboxsync $ */
2/** @file
3 * VBoxGuestLib - Ring-0 Support Library for VBoxGuest, IDC, Windows specific.
4 */
5
6/*
7 * Copyright (C) 2008-2017 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/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include "VBoxGuestR0LibInternal.h"
32#include <VBox/VBoxGuest.h>
33#include <VBox/err.h>
34#include <VBox/log.h>
35
36
37/**
38 * Implementation of a IO_COMPLETION_ROUTINE.
39 *
40 * @returns STATUS_MORE_PROCESSING_REQUIRED
41 * @param pDeviceObject The device object.
42 * @param pIrp The request.
43 * @param pvUser The event object.
44 */
45static NTSTATUS vbglR0NtDriverIoCtlCompletion(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID pvUser)
46{
47 PKEVENT pEvent = (PKEVENT )pvUser;
48 Log(("vbglR0NtDriverIoCtlCompletion: pIrp=%p pEvent=%p\n", pIrp, pEvent));
49 RT_NOREF2(pDeviceObject, pIrp);
50
51 KeSetEvent(pEvent, IO_NO_INCREMENT, FALSE /*fWait*/);
52 return STATUS_MORE_PROCESSING_REQUIRED;
53}
54
55
56/**
57 * Internal I/O Control call worker.
58 *
59 * @returns VBox status code.
60 * @param pDeviceObject The device object to call.
61 * @param pFileObject The file object for the connection.
62 * @param uReq The request.
63 * @param pReq The request packet.
64 */
65static int vbglR0IdcNtCallInternal(PDEVICE_OBJECT pDeviceObject, PFILE_OBJECT pFileObject, uint32_t uReq, PVBGLREQHDR pReq)
66{
67 int rc;
68 IO_STATUS_BLOCK IoStatusBlock;
69 KEVENT Event;
70 PIRP pIrp;
71 NTSTATUS rcNt;
72
73 /*
74 * Build the request.
75 */
76 KeInitializeEvent(&Event, NotificationEvent, FALSE);
77 pIrp = IoBuildDeviceIoControlRequest(uReq, /* IoControlCode */
78 pDeviceObject,
79 pReq, /* InputBuffer */
80 pReq->cbIn, /* InputBufferLength */
81 pReq, /* OutputBuffer */
82 pReq->cbOut, /* OutputBufferLength */
83 TRUE, /* InternalDeviceIoControl (=> IRP_MJ_INTERNAL_DEVICE_CONTROL) */
84 &Event, /* Event */
85 &IoStatusBlock); /* IoStatusBlock */
86 if (pIrp)
87 {
88 IoGetNextIrpStackLocation(pIrp)->FileObject = pFileObject;
89
90 /* A completion routine is required to signal the Event. */
91 IoSetCompletionRoutine(pIrp, vbglR0NtDriverIoCtlCompletion, &Event,
92 TRUE /* InvokeOnSuccess */, TRUE /* InvokeOnError */, TRUE /* InvokeOnCancel */);
93
94 /*
95 * Call the driver, wait for an async request to complete (should never happen).
96 */
97 rcNt = IoCallDriver(pDeviceObject, pIrp);
98 if (rcNt == STATUS_PENDING)
99 {
100 rcNt = KeWaitForSingleObject(&Event, /* Object */
101 Executive, /* WaitReason */
102 KernelMode, /* WaitMode */
103 FALSE, /* Alertable */
104 NULL); /* TimeOut */
105 rcNt = IoStatusBlock.Status;
106 }
107 if (NT_SUCCESS(rcNt))
108 rc = pReq->rc;
109 else
110 rc = RTErrConvertFromNtStatus(rcNt);
111 }
112 else
113 rc = VERR_NO_MEMORY;
114 return rc;
115}
116
117
118int VBOXCALL vbglR0IdcNativeOpen(PVBGLIDCHANDLE pHandle, PVBGLIOCIDCCONNECT pReq)
119{
120 PDEVICE_OBJECT pDeviceObject = NULL;
121 PFILE_OBJECT pFileObject = NULL;
122 UNICODE_STRING wszDeviceName;
123 NTSTATUS rcNt;
124 int rc;
125
126 /*
127 * Get the device object pointer.
128 */
129 RtlInitUnicodeString(&wszDeviceName, VBOXGUEST_DEVICE_NAME_NT);
130 rcNt = IoGetDeviceObjectPointer(&wszDeviceName, FILE_ALL_ACCESS, &pFileObject, &pDeviceObject);
131 if (NT_SUCCESS(rcNt))
132 {
133 /*
134 * Make the connection call.
135 */
136 rc = vbglR0IdcNtCallInternal(pDeviceObject, pFileObject, VBGL_IOCTL_IDC_CONNECT, &pReq->Hdr);
137 if (RT_SUCCESS(rc))
138 {
139 pHandle->s.pDeviceObject = pDeviceObject;
140 pHandle->s.pFileObject = pFileObject;
141 return rc;
142 }
143
144 /* only the file object. */
145 ObDereferenceObject(pFileObject);
146 }
147 else
148 rc = RTErrConvertFromNtStatus(rcNt);
149
150 pHandle->s.pDeviceObject = NULL;
151 pHandle->s.pFileObject = NULL;
152 return rc;
153}
154
155
156int VBOXCALL vbglR0IdcNativeClose(PVBGLIDCHANDLE pHandle, PVBGLIOCIDCDISCONNECT pReq)
157{
158 PFILE_OBJECT pFileObject = pHandle->s.pFileObject;
159 int rc = vbglR0IdcNtCallInternal(pHandle->s.pDeviceObject, pFileObject, VBGL_IOCTL_IDC_DISCONNECT, &pReq->Hdr);
160 if (RT_SUCCESS(rc))
161 {
162 pHandle->s.pDeviceObject = NULL;
163 pHandle->s.pFileObject = NULL;
164 ObDereferenceObject(pFileObject);
165 }
166
167 return rc;
168}
169
170
171/**
172 * Makes an IDC call, returning only the I/O control status code.
173 *
174 * @returns VBox status code (the I/O control failure status).
175 * @param pHandle The IDC handle.
176 * @param uReq The request number.
177 * @param pReqHdr The request header.
178 * @param cbReq The request size.
179 */
180DECLR0VBGL(int) VbglR0IdcCallRaw(PVBGLIDCHANDLE pHandle, size_t uReq, PVBGLREQHDR pReqHdr, uint32_t cbReq)
181{
182 NOREF(cbReq);
183 return vbglR0IdcNtCallInternal(pHandle->s.pDeviceObject, pHandle->s.pFileObject, (uint32_t)uReq, pReqHdr);
184}
185
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