VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/win/VBoxGuestInst.cpp

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
Line 
1/* $Id: VBoxGuestInst.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * Small tool to (un)install the VBoxGuest device driver (for testing).
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include <iprt/win/windows.h>
42
43#include <VBox/VBoxGuest.h> /* for VBOXGUEST_SERVICE_NAME */
44#include <iprt/errcore.h>
45#include <iprt/message.h>
46#include <iprt/stream.h>
47#include <iprt/utf16.h>
48
49
50
51
52static RTEXITCODE installDriver(bool fStartIt)
53{
54 /*
55 * Assume it didn't exist, so we'll create the service.
56 */
57 SC_HANDLE hSMgrCreate = OpenSCManagerW(NULL, NULL, SERVICE_CHANGE_CONFIG);
58 if (!hSMgrCreate)
59 return RTMsgErrorExitFailure("OpenSCManager(,,create) failed: %u", GetLastError());
60
61 const wchar_t *pwszSlashName = L"\\VBoxGuest.sys";
62 wchar_t wszDriver[MAX_PATH * 2];
63 GetCurrentDirectoryW(MAX_PATH, wszDriver);
64 RTUtf16Cat(wszDriver, RT_ELEMENTS(wszDriver), pwszSlashName);
65 if (GetFileAttributesW(wszDriver) == INVALID_FILE_ATTRIBUTES)
66 {
67 GetSystemDirectoryW(wszDriver, MAX_PATH);
68 RTUtf16Cat(wszDriver, RT_ELEMENTS(wszDriver), L"\\drivers");
69 RTUtf16Cat(wszDriver, RT_ELEMENTS(wszDriver), pwszSlashName);
70
71 /* Try FAT name abbreviation. */
72 if (GetFileAttributesW(wszDriver) == INVALID_FILE_ATTRIBUTES)
73 {
74 pwszSlashName = L"\\VBoxGst.sys";
75 GetCurrentDirectoryW(MAX_PATH, wszDriver);
76 RTUtf16Cat(wszDriver, RT_ELEMENTS(wszDriver), pwszSlashName);
77 if (GetFileAttributesW(wszDriver) == INVALID_FILE_ATTRIBUTES)
78 {
79 GetSystemDirectoryW(wszDriver, MAX_PATH);
80 RTUtf16Cat(wszDriver, RT_ELEMENTS(wszDriver), L"\\drivers");
81 RTUtf16Cat(wszDriver, RT_ELEMENTS(wszDriver), pwszSlashName);
82 }
83 }
84 }
85
86 RTEXITCODE rcExit;
87 SC_HANDLE hService = CreateServiceW(hSMgrCreate,
88 RT_CONCAT(L,VBOXGUEST_SERVICE_NAME),
89 L"VBoxGuest Support Driver",
90 SERVICE_QUERY_STATUS | (fStartIt ? SERVICE_START : 0),
91 SERVICE_KERNEL_DRIVER,
92 SERVICE_BOOT_START,
93 SERVICE_ERROR_NORMAL,
94 wszDriver,
95 L"System",
96 NULL, NULL, NULL, NULL);
97 if (hService)
98 {
99 RTMsgInfo("Successfully created service '%s' for driver '%ls'.\n", VBOXGUEST_SERVICE_NAME, wszDriver);
100 rcExit = RTEXITCODE_SUCCESS;
101 if (fStartIt)
102 {
103 if (StartService(hService, 0, NULL))
104 RTMsgInfo("successfully started driver '%ls'\n", wszDriver);
105 else
106 rcExit = RTMsgErrorExitFailure("StartService failed: %u", GetLastError());
107 }
108 CloseServiceHandle(hService);
109 }
110 else
111 rcExit = RTMsgErrorExitFailure("CreateService failed! %u (wszDriver=%ls)\n", GetLastError(), wszDriver);
112 CloseServiceHandle(hSMgrCreate);
113 return rcExit;
114}
115
116
117static RTEXITCODE uninstallDriver(void)
118{
119 SC_HANDLE hSMgr = OpenSCManagerW(NULL, NULL, SERVICE_CHANGE_CONFIG);
120 if (!hSMgr)
121 return RTMsgErrorExitFailure("OpenSCManager(,,change_config) failed: %u", GetLastError());
122
123 RTEXITCODE rcExit;
124 SC_HANDLE hService = OpenServiceW(hSMgr, RT_CONCAT(L, VBOXGUEST_SERVICE_NAME), SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE);
125 if (hService)
126 {
127 /*
128 * Try stop it if it's running.
129 */
130 SERVICE_STATUS Status = { 0, 0, 0, 0, 0, 0, 0 };
131 QueryServiceStatus(hService, &Status);
132 if (Status.dwCurrentState == SERVICE_STOPPED)
133 rcExit = RTEXITCODE_SUCCESS;
134 else if (ControlService(hService, SERVICE_CONTROL_STOP, &Status))
135 {
136 int iWait = 100;
137 while (Status.dwCurrentState == SERVICE_STOP_PENDING && iWait-- > 0)
138 {
139 Sleep(100);
140 QueryServiceStatus(hService, &Status);
141 }
142 if (Status.dwCurrentState == SERVICE_STOPPED)
143 rcExit = RTEXITCODE_SUCCESS;
144 else
145 rcExit = RTMsgErrorExitFailure("Failed to stop service! Service status: %u (%#x)\n",
146 Status.dwCurrentState, Status.dwCurrentState);
147 }
148 else
149 rcExit = RTMsgErrorExitFailure("ControlService failed: %u, Service status: %u (%#x)",
150 GetLastError(), Status.dwCurrentState, Status.dwCurrentState);
151
152 /*
153 * Delete the service.
154 */
155 if (rcExit == RTEXITCODE_SUCCESS)
156 {
157 if (DeleteService(hService))
158 RTMsgInfo("Successfully deleted the %s service\n", VBOXGUEST_SERVICE_NAME);
159 else
160 rcExit = RTMsgErrorExitFailure("DeleteService failed: %u", GetLastError());
161 }
162
163 CloseServiceHandle(hService);
164 }
165 else if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
166 {
167 RTMsgInfo("Nothing to do, the service %s does not exist.\n", VBOXGUEST_SERVICE_NAME);
168 rcExit = RTEXITCODE_SUCCESS;
169 }
170 else
171 rcExit = RTMsgErrorExitFailure("OpenService failed: %u", GetLastError());
172
173 CloseServiceHandle(hSMgr);
174 return rcExit;
175}
176
177
178static RTEXITCODE performTest(void)
179{
180 HANDLE hDevice = CreateFileW(RT_CONCAT(L,VBOXGUEST_DEVICE_NAME), // Win2k+: VBOXGUEST_DEVICE_NAME_GLOBAL
181 GENERIC_READ | GENERIC_WRITE,
182 FILE_SHARE_READ | FILE_SHARE_WRITE,
183 NULL,
184 OPEN_EXISTING,
185 FILE_ATTRIBUTE_NORMAL,
186 NULL);
187 if (hDevice != INVALID_HANDLE_VALUE)
188 {
189 CloseHandle(hDevice);
190 RTMsgInfo("Test succeeded\n");
191 return RTEXITCODE_SUCCESS;
192 }
193 return RTMsgErrorExitFailure("Test failed! Unable to open driver (CreateFileW -> %u).", GetLastError());
194}
195
196
197static RTEXITCODE usage(const char *pszProgName)
198{
199 RTPrintf("\n"
200 "Usage: %s [install|uninstall|test]\n", pszProgName);
201 return RTEXITCODE_SYNTAX;
202}
203
204
205int main(int argc, char **argv)
206{
207 if (argc != 2)
208 {
209 RTMsgError(argc < 2 ? "Too few arguments! Expected one." : "Too many arguments! Expected only one.");
210 return usage(argv[0]);
211 }
212
213 RTEXITCODE rcExit;
214 if (strcmp(argv[1], "install") == 0)
215 rcExit = installDriver(true);
216 else if (strcmp(argv[1], "uninstall") == 0)
217 rcExit = uninstallDriver();
218 else if (strcmp(argv[1], "test") == 0)
219 rcExit = performTest();
220 else
221 {
222 RTMsgError("Unknown argument: '%s'", argv[1]);
223 rcExit = usage(argv[0]);
224 }
225 return rcExit;
226}
227
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use