VirtualBox

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

Last change on this file since 107051 was 107051, checked in by vboxsync, 2 months ago

Windows driver installation: Sorted VBoxWinDrvSetupApiErrToStr(). Added ERROR_GENERAL_SYNTAX .bugref:10762

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