VirtualBox

source: vbox/trunk/src/VBox/GuestHost/installation/VBoxWinDrvCommon.cpp@ 107395

Last change on this file since 107395 was 107395, checked in by vboxsync, 8 weeks ago

Windows driver installation: Added a few certificate-based Windows error codes to resolve.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.4 KB
Line 
1/* $Id: VBoxWinDrvCommon.cpp 107395 2024-12-20 12:46:46Z vboxsync $ */
2/** @file
3 * VBoxWinDrvCommon - Common Windows driver functions.
4 */
5
6/*
7 * Copyright (C) 2024 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 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#include <iprt/win/windows.h>
33#include <iprt/win/setupapi.h>
34#include <newdev.h> /* For INSTALLFLAG_XXX. */
35#include <cfgmgr32.h> /* For MAX_DEVICE_ID_LEN. */
36
37#include <iprt/assert.h>
38#include <iprt/dir.h>
39#include <iprt/ldr.h>
40#include <iprt/list.h>
41#include <iprt/mem.h>
42#include <iprt/once.h>
43#include <iprt/path.h>
44#include <iprt/string.h>
45#include <iprt/system.h>
46#include <iprt/utf16.h>
47
48#include <VBox/err.h> /* For VERR_PLATFORM_ARCH_NOT_SUPPORTED.*/
49
50#include "VBoxWinDrvCommon.h"
51
52
53/*********************************************************************************************************************************
54* Defines *
55*********************************************************************************************************************************/
56
57
58/*********************************************************************************************************************************
59* Defined Constants And Macros *
60*********************************************************************************************************************************/
61
62
63/*********************************************************************************************************************************
64* Prototypes *
65*********************************************************************************************************************************/
66static int vboxWinDrvInfQueryContext(HINF hInf, LPCWSTR pwszSection, LPCWSTR pwszKey, PINFCONTEXT pCtx);
67
68
69/**
70 * Returns the type of an INF file.
71 *
72 * @returns Type of the INF file.
73 * @param hInf INF handle to use.
74 * @param ppwszSection Where to return main section of the driver.
75 * Optional and can be NULL.
76 */
77VBOXWINDRVINFTYPE VBoxWinDrvInfGetTypeEx(HINF hInf, PRTUTF16 *ppwszSection)
78{
79 /*
80 * Regular driver?
81 */
82
83 /* Sorted by most likely-ness. */
84 static PRTUTF16 s_apwsManufacturerSections[] =
85 {
86 /* Most likely (and doesn't have a decoration). */
87 L"Manufacturer",
88 L"Manufacturer" VBOXWINDRVINF_DOT_NT_NATIVE_ARCH_STR,
89 };
90
91 int rc;
92
93 INFCONTEXT InfCtx;
94 size_t i;
95
96 PCRTUTF16 pwszManufacturerSection = NULL;
97 for (i = 0; i < RT_ELEMENTS(s_apwsManufacturerSections); i++)
98 {
99 rc = vboxWinDrvInfQueryContext(hInf, s_apwsManufacturerSections[i], NULL, &InfCtx);
100 if (RT_SUCCESS(rc))
101 {
102 pwszManufacturerSection = s_apwsManufacturerSections[i];
103 break;
104 }
105 }
106
107 /*
108 * Primitive driver?
109 */
110
111 /* Sorted by most likely-ness. */
112 static PRTUTF16 s_apwszPrimitiveSections[] =
113 {
114 /* Most likely (and doesn't have a decoration). */
115 L"DefaultInstall",
116 L"DefaultInstall" VBOXWINDRVINF_DOT_NT_NATIVE_ARCH_STR,
117 /** @todo Handle more specific decorations like "NTAMD64.6.3..10622". */
118 };
119
120 PCRTUTF16 pwszPrimitiveSection = NULL;
121 for (i = 0; i < RT_ELEMENTS(s_apwszPrimitiveSections); i++)
122 {
123 rc = vboxWinDrvInfQueryContext(hInf, s_apwszPrimitiveSections[i], NULL, &InfCtx);
124 if (RT_SUCCESS(rc))
125 {
126 pwszPrimitiveSection = s_apwszPrimitiveSections[i];
127 break;
128 }
129 }
130
131 /* If both sections are present, consider this INF file as being invalid.
132 * Only one or the other has to be present. */
133 if ( pwszManufacturerSection
134 && pwszPrimitiveSection)
135 {
136 return VBOXWINDRVINFTYPE_INVALID;
137 }
138 else if (pwszManufacturerSection)
139 {
140 if (ppwszSection)
141 *ppwszSection = RTUtf16Dup(pwszManufacturerSection);
142
143 return VBOXWINDRVINFTYPE_NORMAL;
144 }
145 else if (pwszPrimitiveSection)
146 {
147 if (ppwszSection)
148 *ppwszSection = RTUtf16Dup(pwszPrimitiveSection);
149
150 return VBOXWINDRVINFTYPE_PRIMITIVE;
151 }
152
153 return VBOXWINDRVINFTYPE_INVALID;
154}
155
156/**
157 * Returns the type of an INF file.
158 *
159 * @returns Type of the INF file.
160 * @param hInf INF handle to use.
161 */
162VBOXWINDRVINFTYPE VBoxWinDrvInfGetType(HINF hInf)
163{
164 return VBoxWinDrvInfGetTypeEx(hInf, NULL);
165}
166
167/**
168 * Queries an INF context from an INF handle.
169 *
170 * @returns VBox status code.
171 * @param hInf INF handle to use.
172 * @param pwszSection Section name to query context for.
173 * @param pwszKey Key to query context for.
174 * @param pCtx Where to return the INF context on success.
175 */
176static int vboxWinDrvInfQueryContext(HINF hInf, LPCWSTR pwszSection, LPCWSTR pwszKey, PINFCONTEXT pCtx)
177{
178 if (!SetupFindFirstLineW(hInf, pwszSection, pwszKey, pCtx))
179 return VERR_NOT_FOUND;
180
181 return VINF_SUCCESS;
182}
183
184/**
185 * Queries a value from an INF context.
186 *
187 * @returns VBox status code.
188 * @param pCtx INF context to use.
189 * @param iValue Index to query.
190 * @param ppwszValue Where to return the value on success.
191 * @param pcwcValue Where to return the number of characters for \a ppwszValue. Optional an can be NULL.
192 */
193int VBoxWinDrvInfQueryKeyValue(PINFCONTEXT pCtx, DWORD iValue, PRTUTF16 *ppwszValue, PDWORD pcwcValue)
194{
195 *ppwszValue = NULL;
196 if (pcwcValue)
197 *pcwcValue = 0;
198
199 DWORD cwcValue;
200 if (!SetupGetStringFieldW(pCtx, iValue, NULL, 0, &cwcValue))
201 {
202 DWORD const dwErr = GetLastError();
203 if (dwErr != ERROR_INSUFFICIENT_BUFFER)
204 return VBoxWinDrvInstErrorFromWin32(dwErr);
205 }
206
207 LPWSTR pwszValue = (LPWSTR)RTMemAlloc(cwcValue * sizeof(pwszValue[0]));
208 AssertPtrReturn(pwszValue, VERR_NO_MEMORY);
209
210 if (!SetupGetStringFieldW(pCtx, iValue, pwszValue, cwcValue, &cwcValue))
211 {
212 RTMemFree(pwszValue);
213 return VBoxWinDrvInstErrorFromWin32(GetLastError());
214 }
215
216 *ppwszValue = pwszValue;
217 if (pcwcValue)
218 *pcwcValue = cwcValue;
219
220 return VINF_SUCCESS;
221}
222
223/**
224 * Queries a model name from an INF section.
225 *
226 * @returns VBox status code.
227 * @retval VERR_NOT_FOUND if no model has been found.
228 * @param hInf INF handle to use.
229 * @param pwszSection Section to query model for.
230 * @param uIndex Index of model to query.
231 * Currently only the first model (index 0) is supported.
232 * @param ppwszValue Where to return the model name on success.
233 * @param pcwcValue Where to return the number of characters for \a ppwszValue. Optional an can be NULL.
234 */
235int VBoxWinDrvInfQueryModelEx(HINF hInf, PCRTUTF16 pwszSection, unsigned uIndex, PRTUTF16 *ppwszValue, PDWORD pcwcValue)
236{
237 AssertPtrReturn(pwszSection, VERR_INVALID_POINTER);
238 AssertReturn(uIndex == 0, VERR_INVALID_PARAMETER);
239
240 *ppwszValue = NULL;
241 if (pcwcValue)
242 *pcwcValue = 0;
243
244 int rc = VINF_SUCCESS;
245
246 INFCONTEXT InfCtx;
247 rc = vboxWinDrvInfQueryContext(hInf, pwszSection, NULL, &InfCtx);
248 if (RT_FAILURE(rc))
249 return rc;
250
251 PRTUTF16 pwszModel;
252 DWORD cwcModels;
253 rc = VBoxWinDrvInfQueryKeyValue(&InfCtx, 1, &pwszModel, &cwcModels);
254 if (RT_FAILURE(rc))
255 return rc;
256
257 PRTUTF16 pwszResult = NULL;
258 DWORD cwcResult = 0;
259
260 PRTUTF16 pwszPlatform = NULL;
261 DWORD cwcPlatform;
262 rc = VBoxWinDrvInfQueryKeyValue(&InfCtx, 2, &pwszPlatform, &cwcPlatform);
263 if (RT_SUCCESS(rc)) /* Platform is optional. */
264 {
265 /* Convert to uppercase first so that RTUtf16FindAscii() below works. */
266 RTUtf16ToUpper(pwszPlatform);
267
268 /* Note! The platform can be more specific, e.g. "NTAMD64.6.0". */
269 if (RTUtf16FindAscii(pwszPlatform, VBOXWINDRVINF_NT_NATIVE_ARCH_STR) == 0)
270 {
271 RTUTF16 wszSection[VBOXWINDRVINF_MAX_SECTION_NAME_LEN];
272 rc = RTUtf16Copy(wszSection, sizeof(wszSection), pwszModel);
273 if (RT_SUCCESS(rc))
274 {
275 rc = RTUtf16Cat(wszSection, sizeof(wszSection), VBOXWINDRVINF_DECORATION_SEP_UTF16_STR);
276 if (RT_SUCCESS(rc))
277 {
278 rc = RTUtf16Cat(wszSection, sizeof(wszSection), pwszPlatform);
279 if (RT_SUCCESS(rc))
280 {
281 pwszResult = RTUtf16Dup(wszSection);
282 if (pwszResult)
283 {
284 cwcResult = (DWORD)RTUtf16Len(wszSection);
285 }
286 else
287 rc = VERR_NO_MEMORY;
288 }
289 }
290 }
291 }
292 else
293 rc = VERR_PLATFORM_ARCH_NOT_SUPPORTED;
294 }
295 else /* Model w/o platform. */
296 {
297 pwszResult = pwszModel;
298 cwcResult = cwcModels;
299 pwszModel = NULL;
300
301 rc = VINF_SUCCESS;
302 }
303
304 RTMemFree(pwszModel);
305 RTMemFree(pwszPlatform);
306
307 if (RT_SUCCESS(rc))
308 {
309 *ppwszValue = pwszResult;
310 if (pcwcValue)
311 *pcwcValue = cwcResult;
312 }
313
314 return rc;
315}
316
317int VBoxWinDrvInfQueryInstallSectionEx(HINF hInf, PCRTUTF16 pwszModel, PRTUTF16 *ppwszValue, PDWORD pcwcValue)
318{
319 INFCONTEXT InfCtx;
320 int rc = vboxWinDrvInfQueryContext(hInf, pwszModel, NULL, &InfCtx);
321 if (RT_FAILURE(rc))
322 return rc;
323
324 return VBoxWinDrvInfQueryKeyValue(&InfCtx, 1, ppwszValue, pcwcValue);
325}
326
327int VBoxWinDrvInfQueryInstallSection(HINF hInf, PCRTUTF16 pwszModel, PRTUTF16 *ppwszValue)
328{
329 return VBoxWinDrvInfQueryInstallSectionEx(hInf, pwszModel, ppwszValue, NULL);
330}
331
332/**
333 * Queries the "Version" section of an INF file, extended version.
334 *
335 * @returns VBox status code.
336 * @param hInf INF handle to use.
337 * @param uIndex Index of version information to query. Usually 0.
338 * @param pVer Where to return the Version section information on success.
339 */
340int VBoxWinDrvInfQuerySectionVerEx(HINF hInf, UINT uIndex, PVBOXWINDRVINFSEC_VERSION pVer)
341{
342 DWORD dwSize = 0;
343 bool fRc = SetupGetInfInformationW(hInf, INFINFO_INF_SPEC_IS_HINF, NULL, 0, &dwSize);
344 if (!fRc || !dwSize)
345 return VERR_NOT_FOUND;
346
347 int rc = VINF_SUCCESS;
348
349 PSP_INF_INFORMATION pInfo = (PSP_INF_INFORMATION)RTMemAlloc(dwSize);
350 AssertPtrReturn(pInfo, VERR_NO_MEMORY);
351 fRc = SetupGetInfInformationW(hInf, INFINFO_INF_SPEC_IS_HINF, pInfo, dwSize, NULL);
352 if (fRc)
353 {
354 if (pInfo->InfStyle == INF_STYLE_WIN4)
355 {
356 dwSize = 0;
357 fRc = SetupQueryInfVersionInformationW(pInfo, uIndex, NULL /* Key, NULL means all */,
358 NULL, 0, &dwSize);
359 if (fRc)
360 {
361 PRTUTF16 pwszInfo = (PRTUTF16)RTMemAlloc(dwSize * sizeof(RTUTF16));
362 if (pwszInfo)
363 {
364 fRc = SetupQueryInfVersionInformationW(pInfo, uIndex, NULL /* Key, NULL means all */,
365 pwszInfo, dwSize, NULL);
366
367/** Macro to find a specific key and assign its value to the given string. */
368#define GET_VALUE(a_Key, a_String) \
369 if (!RTUtf16ICmp(pwsz, a_Key)) \
370 { \
371 rc = RTUtf16Printf(a_String, RT_ELEMENTS(a_String), "%ls", pwsz + cch + 1 /* SKip key + terminator */); \
372 AssertRCBreak(rc); \
373 }
374 PRTUTF16 pwsz = pwszInfo;
375 while (dwSize)
376 {
377 size_t const cch = RTUtf16Len(pwsz);
378
379 GET_VALUE(L"DriverVer", pVer->wszDriverVer);
380 GET_VALUE(L"Provider", pVer->wszProvider);
381 GET_VALUE(L"CatalogFile", pVer->wszCatalogFile);
382
383 dwSize -= (DWORD)cch + 1;
384 pwsz += cch + 1;
385 }
386 Assert(dwSize == 0);
387#undef GET_VALUE
388 RTMemFree(pwszInfo);
389 }
390 else
391 rc = VERR_NO_MEMORY;
392 }
393 else
394 rc = VBoxWinDrvInstErrorFromWin32(GetLastError());
395 }
396 else /* Legacy INF files are not supported. */
397 rc = VERR_NOT_SUPPORTED;
398 }
399 else
400 rc = VBoxWinDrvInstErrorFromWin32(GetLastError());
401
402 RTMemFree(pInfo);
403 return rc;
404}
405
406/**
407 * Queries the "Version" section of an INF file.
408 *
409 * @returns VBox status code.
410 * @param hInf INF handle to use.
411 * @param pVer Where to return the Version section information on success.
412 */
413int VBoxWinDrvInfQuerySectionVer(HINF hInf, PVBOXWINDRVINFSEC_VERSION pVer)
414{
415 return VBoxWinDrvInfQuerySectionVerEx(hInf, 0 /* uIndex */, pVer);
416}
417
418/**
419 * Opens an INF file, extended version.
420 *
421 * @returns VBox status code.
422 * @param pwszInfFile Path to INF file to open.
423 * @param pwszClassName Class name to use.
424 * @param phInf Where to return the INF handle on success.
425 */
426int VBoxWinDrvInfOpenEx(PCRTUTF16 pwszInfFile, PRTUTF16 pwszClassName, HINF *phInf)
427{
428 HINF hInf = SetupOpenInfFileW(pwszInfFile, pwszClassName, INF_STYLE_WIN4, NULL /*__in PUINT ErrorLine */);
429 if (hInf == INVALID_HANDLE_VALUE)
430 return VBoxWinDrvInstErrorFromWin32(GetLastError());
431
432 *phInf = hInf;
433
434 return VINF_SUCCESS;
435}
436
437/**
438 * Opens an INF file, wide char version.
439 *
440 * @returns VBox status code.
441 * @param pwszInfFile Path to INF file to open.
442 * @param phInf Where to return the INF handle on success.
443 *
444 * @note Queryies the class name automatically from the given INF file.
445 */
446int VBoxWinDrvInfOpen(PCRTUTF16 pwszInfFile, HINF *phInf)
447{
448 int rc;
449
450 GUID guid = {};
451 RTUTF16 pwszClassName[MAX_CLASS_NAME_LEN] = { };
452 if (SetupDiGetINFClassW(pwszInfFile, &guid, &(pwszClassName[0]), sizeof(pwszClassName), NULL))
453 {
454 rc = VBoxWinDrvInfOpenEx(pwszInfFile, pwszClassName, phInf);
455 }
456 else
457 rc = VBoxWinDrvInstErrorFromWin32(GetLastError());
458
459 return rc;
460}
461
462/**
463 * Opens an INF file.
464 *
465 * @returns VBox status code.
466 * @param pszInfFile Path to INF file to open.
467 * @param phInf Where to return the INF handle on success.
468 *
469 * @note Queryies the class name automatically from the given INF file.
470 */
471int VBoxWinDrvInfOpenUtf8(const char *pszInfFile, HINF *phInf)
472{
473 PRTUTF16 pwszInfFile;
474 int rc = RTStrToUtf16(pszInfFile, &pwszInfFile);
475 AssertRCReturn(rc, rc);
476
477 rc = VBoxWinDrvInfOpen(pwszInfFile, phInf);
478
479 RTUtf16Free(pwszInfFile);
480 return rc;
481}
482
483/**
484 * Closes an INF file.
485 *
486 * @returns VBox status code.
487 * @param hInf INF handle to use.
488 */
489int VBoxWinDrvInfClose(HINF hInf)
490{
491 SetupCloseInfFile(hInf);
492
493 return VINF_SUCCESS;
494}
495
496/**
497 * Queries the first (device) model from an INF file.
498 *
499 * @returns VBox status code.
500 * @retval VERR_NOT_FOUND if no model has been found.
501 * @param hInf INF handle to use.
502 * @param pwszSection Section to query model for.
503 * @param ppwszModel Where to return the model on success.
504 * Needs to be free'd by RTUtf16Free().
505 */
506int VBoxWinDrvInfQueryFirstModel(HINF hInf, PCRTUTF16 pwszSection, PRTUTF16 *ppwszModel)
507{
508 *ppwszModel = NULL;
509
510 return VBoxWinDrvInfQueryModelEx(hInf, pwszSection, 0 /* Index */, ppwszModel, NULL);
511}
512
513/**
514 * Queries the first PnP ID from an INF file.
515 *
516 * @returns VBox status code.
517 * @retval VERR_NOT_FOUND if no PnP ID has been found.
518 * @param hInf INF handle to use.
519 * @param pwszModel Model to query PnP ID for.
520 * @param ppwszPnPId Where to return the PnP ID on success.
521 * Needs to be free'd by RTUtf16Free().
522 */
523int VBoxWinDrvInfQueryFirstPnPId(HINF hInf, PRTUTF16 pwszModel, PRTUTF16 *ppwszPnPId)
524{
525 if (!pwszModel) /* No model given? Bail out early. */
526 return VERR_NOT_FOUND;
527
528 *ppwszPnPId = NULL;
529
530 PRTUTF16 pwszPnPId = NULL;
531 INFCONTEXT InfCtx;
532 int rc = vboxWinDrvInfQueryContext(hInf, pwszModel, NULL, &InfCtx);
533 if (RT_SUCCESS(rc))
534 {
535 rc = VBoxWinDrvInfQueryKeyValue(&InfCtx, 2, &pwszPnPId, NULL);
536 if (RT_SUCCESS(rc))
537 *ppwszPnPId = pwszPnPId;
538 }
539
540 return rc;
541}
542
543
544/**
545 * Returns a Setup API error as a string.
546 *
547 * Needded to get at least a minimally meaningful error string back from Setup API.
548 *
549 * @returns Setup API error as a string, or NULL if not found.
550 * @param dwErr Error code to return as a string.
551 *
552 * @note Keep this sorted for easier lookup.
553 */
554const char *VBoxWinDrvSetupApiErrToStr(const DWORD dwErr)
555{
556 switch (dwErr)
557 {
558 RT_CASE_RET_STR(ERROR_AUTHENTICODE_DISALLOWED );
559 RT_CASE_RET_STR(ERROR_AUTHENTICODE_PUBLISHER_NOT_TRUSTED);
560 RT_CASE_RET_STR(ERROR_AUTHENTICODE_TRUST_NOT_ESTABLISHED);
561 RT_CASE_RET_STR(ERROR_AUTHENTICODE_TRUSTED_PUBLISHER );
562 RT_CASE_RET_STR(ERROR_BAD_INTERFACE_INSTALLSECT );
563 RT_CASE_RET_STR(ERROR_BAD_SECTION_NAME_LINE );
564 RT_CASE_RET_STR(ERROR_BAD_SERVICE_INSTALLSECT );
565 RT_CASE_RET_STR(ERROR_CANT_LOAD_CLASS_ICON );
566 RT_CASE_RET_STR(ERROR_CANT_REMOVE_DEVINST );
567 RT_CASE_RET_STR(ERROR_CLASS_MISMATCH );
568 RT_CASE_RET_STR(ERROR_DEVICE_INSTALL_BLOCKED );
569 RT_CASE_RET_STR(ERROR_DEVICE_INSTALLER_NOT_READY );
570 RT_CASE_RET_STR(ERROR_DEVICE_INTERFACE_ACTIVE );
571 RT_CASE_RET_STR(ERROR_DEVICE_INTERFACE_REMOVED );
572 RT_CASE_RET_STR(ERROR_DEVINFO_DATA_LOCKED );
573 RT_CASE_RET_STR(ERROR_DEVINFO_LIST_LOCKED );
574 RT_CASE_RET_STR(ERROR_DEVINFO_NOT_REGISTERED );
575 RT_CASE_RET_STR(ERROR_DEVINST_ALREADY_EXISTS );
576 RT_CASE_RET_STR(ERROR_DEVINSTALL_QUEUE_NONNATIVE );
577 RT_CASE_RET_STR(ERROR_DI_BAD_PATH );
578 RT_CASE_RET_STR(ERROR_DI_DO_DEFAULT );
579 RT_CASE_RET_STR(ERROR_DI_DONT_INSTALL );
580 RT_CASE_RET_STR(ERROR_DI_FUNCTION_OBSOLETE );
581 RT_CASE_RET_STR(ERROR_DI_NOFILECOPY );
582 RT_CASE_RET_STR(ERROR_DI_POSTPROCESSING_REQUIRED );
583 RT_CASE_RET_STR(ERROR_DRIVER_INSTALL_BLOCKED );
584 RT_CASE_RET_STR(ERROR_DRIVER_NONNATIVE );
585 RT_CASE_RET_STR(ERROR_DRIVER_STORE_ADD_FAILED );
586 RT_CASE_RET_STR(ERROR_DRIVER_STORE_DELETE_FAILED );
587 RT_CASE_RET_STR(ERROR_DUPLICATE_FOUND );
588 RT_CASE_RET_STR(ERROR_EXPECTED_SECTION_NAME );
589 RT_CASE_RET_STR(ERROR_FILE_HASH_NOT_IN_CATALOG );
590 RT_CASE_RET_STR(ERROR_FILEQUEUE_LOCKED );
591 RT_CASE_RET_STR(ERROR_GENERAL_SYNTAX ); /* Also when INF file is empty. */
592 RT_CASE_RET_STR(ERROR_IN_WOW64 );
593 RT_CASE_RET_STR(ERROR_INF_IN_USE_BY_DEVICES );
594 RT_CASE_RET_STR(ERROR_INVALID_CLASS );
595 RT_CASE_RET_STR(ERROR_INVALID_CLASS_INSTALLER );
596 RT_CASE_RET_STR(ERROR_INVALID_COINSTALLER );
597 RT_CASE_RET_STR(ERROR_INVALID_DEVINST_NAME );
598 RT_CASE_RET_STR(ERROR_INVALID_FILTER_DRIVER );
599 RT_CASE_RET_STR(ERROR_INVALID_HWPROFILE );
600 RT_CASE_RET_STR(ERROR_INVALID_INF_LOGCONFIG );
601 RT_CASE_RET_STR(ERROR_INVALID_MACHINENAME );
602 RT_CASE_RET_STR(ERROR_INVALID_PROPPAGE_PROVIDER );
603 RT_CASE_RET_STR(ERROR_INVALID_REFERENCE_STRING );
604 RT_CASE_RET_STR(ERROR_INVALID_REG_PROPERTY );
605 RT_CASE_RET_STR(ERROR_INVALID_TARGET );
606 RT_CASE_RET_STR(ERROR_KEY_DOES_NOT_EXIST );
607 RT_CASE_RET_STR(ERROR_LINE_NOT_FOUND );
608 RT_CASE_RET_STR(ERROR_MACHINE_UNAVAILABLE );
609 RT_CASE_RET_STR(ERROR_NO_ASSOCIATED_CLASS );
610 RT_CASE_RET_STR(ERROR_NO_ASSOCIATED_SERVICE );
611 RT_CASE_RET_STR(ERROR_NO_AUTHENTICODE_CATALOG );
612 RT_CASE_RET_STR(ERROR_NO_BACKUP );
613 RT_CASE_RET_STR(ERROR_NO_CATALOG_FOR_OEM_INF );
614 RT_CASE_RET_STR(ERROR_NO_CLASS_DRIVER_LIST );
615 RT_CASE_RET_STR(ERROR_NO_CLASSINSTALL_PARAMS );
616 RT_CASE_RET_STR(ERROR_NO_COMPAT_DRIVERS );
617 RT_CASE_RET_STR(ERROR_NO_CONFIGMGR_SERVICES );
618 RT_CASE_RET_STR(ERROR_NO_DEFAULT_DEVICE_INTERFACE );
619 RT_CASE_RET_STR(ERROR_NO_DEVICE_ICON );
620 RT_CASE_RET_STR(ERROR_NO_DEVICE_SELECTED );
621 RT_CASE_RET_STR(ERROR_NO_DRIVER_SELECTED );
622 RT_CASE_RET_STR(ERROR_NO_INF );
623 RT_CASE_RET_STR(ERROR_NO_SUCH_DEVICE_INTERFACE );
624 RT_CASE_RET_STR(ERROR_NO_SUCH_DEVINST );
625 RT_CASE_RET_STR(ERROR_NO_SUCH_INTERFACE_CLASS );
626 RT_CASE_RET_STR(ERROR_NON_WINDOWS_DRIVER );
627 RT_CASE_RET_STR(ERROR_NON_WINDOWS_NT_DRIVER );
628 RT_CASE_RET_STR(ERROR_NOT_AN_INSTALLED_OEM_INF );
629 RT_CASE_RET_STR(ERROR_NOT_DISABLEABLE );
630 RT_CASE_RET_STR(ERROR_NOT_INSTALLED );
631 RT_CASE_RET_STR(ERROR_ONLY_VALIDATE_VIA_AUTHENTICODE );
632 RT_CASE_RET_STR(ERROR_PNP_REGISTRY_ERROR );
633 RT_CASE_RET_STR(ERROR_REMOTE_COMM_FAILURE );
634 RT_CASE_RET_STR(ERROR_REMOTE_REQUEST_UNSUPPORTED );
635 RT_CASE_RET_STR(ERROR_SCE_DISABLED );
636 RT_CASE_RET_STR(ERROR_SECTION_NAME_TOO_LONG );
637 RT_CASE_RET_STR(ERROR_SECTION_NOT_FOUND );
638 RT_CASE_RET_STR(ERROR_SET_SYSTEM_RESTORE_POINT );
639 RT_CASE_RET_STR(ERROR_SIGNATURE_OSATTRIBUTE_MISMATCH );
640 RT_CASE_RET_STR(ERROR_UNKNOWN_EXCEPTION );
641 RT_CASE_RET_STR(ERROR_WRONG_INF_STYLE );
642 RT_CASE_RET_STR(ERROR_WRONG_INF_TYPE );
643 default:
644 break;
645 }
646
647 return NULL;
648}
649
650/**
651 * Returns a winerr.h error as a string.
652 *
653 * Needded to get at least a minimally meaningful error string back.
654 *
655 * @returns Error as a string, or NULL if not found.
656 * @param dwErr Error code to return as a string.
657 */
658const char *VBoxWinDrvWinErrToStr(const DWORD dwErr)
659{
660 switch (dwErr)
661 {
662 RT_CASE_RET_STR(ERROR_BADKEY );
663 RT_CASE_RET_STR(ERROR_SERVICE_MARKED_FOR_DELETE );
664 RT_CASE_RET_STR(CERT_E_EXPIRED );
665 RT_CASE_RET_STR(CERT_E_UNTRUSTEDTESTROOT );
666 RT_CASE_RET_STR(CERT_E_CHAINING );
667 RT_CASE_RET_STR(CERT_E_REVOKED );
668 RT_CASE_RET_STR(CERT_E_WRONG_USAGE );
669 default:
670 break;
671 }
672
673 return NULL;
674}
675
676/**
677 * Translates a native Windows error code to a VBox one.
678 *
679 * @returns VBox status code.
680 * @retval VERR_UNRESOLVED_ERROR if no translation was possible.
681 * @retval VERR_INSTALLATION_FAILED if a Setup API or a specific Windows error code occurred not handled
682 * within IPRT's error resolving function.
683 * @param uNativeCode Native Windows error code to translate.
684 */
685int VBoxWinDrvInstErrorFromWin32(unsigned uNativeCode)
686{
687 const char *pszErr = VBoxWinDrvSetupApiErrToStr(uNativeCode);
688 if (!pszErr)
689 pszErr = VBoxWinDrvWinErrToStr(uNativeCode);
690
691 /* All we can do here is to return VERR_INSTALLATION_FAILED if the above calls returned something,
692 * as we don't have IPRT equivalents for all those (Windows- / SetupAPI-)specific error codes.
693 *
694 * For anything else not (yet) handled we want to get a debug assertion, however. */
695 int rc = VERR_INSTALLATION_FAILED;
696 if (!pszErr)
697 {
698 rc = RTErrConvertFromWin32(uNativeCode);
699 if (rc == VERR_UNRESOLVED_ERROR)
700 AssertMsgFailed(("Unhandled error %u (%#x): %s\n", uNativeCode, uNativeCode, pszErr ? pszErr : "<Unknown>"));
701 }
702
703 return rc;
704}
705
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