VirtualBox

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

Last change on this file since 107901 was 107901, checked in by vboxsync, 3 weeks ago

Windows driver installation: Fixed incorrect size passed to SetupDiGetINFClassW in VBoxWinDrvInfOpen and RTUtf16Copy+RTUtf16Cat in VBoxWinDrvInfQueryModelEx; tried to fix bogus key+value parsing in VBoxWinDrvInfQuerySectionVerEx. bugref:10762

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