VirtualBox

source: vbox/trunk/src/VBox/GuestHost/installation/VBoxWinDrvStore.cpp@ 107092

Last change on this file since 107092 was 106890, checked in by vboxsync, 3 months ago

Windows driver installation: More cleanup, a few detection fixes. bugref:10762

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.6 KB
Line 
1/* $Id: VBoxWinDrvStore.cpp 106890 2024-11-08 15:15:20Z vboxsync $ */
2/** @file
3 * VBoxWinDrvStore - Windows driver store handling.
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/err.h>
40#include <iprt/ldr.h>
41#include <iprt/list.h>
42#include <iprt/mem.h>
43#include <iprt/once.h>
44#include <iprt/path.h>
45#include <iprt/string.h>
46#include <iprt/system.h>
47#include <iprt/utf16.h>
48
49#ifdef DEBUG
50# include <iprt/stream.h>
51#endif
52
53#include <VBox/GuestHost/VBoxWinDrvDefs.h>
54#include <VBox/GuestHost/VBoxWinDrvStore.h>
55
56#include "VBoxWinDrvCommon.h"
57
58
59/*********************************************************************************************************************************
60* Interface prototypes *
61*********************************************************************************************************************************/
62static DECLCALLBACK(int) vboxWinDrvStoreLegacyImpl_Enumerate(PVBOXWINDRVSTORE pThis);
63
64
65/*********************************************************************************************************************************
66* Implementation *
67*********************************************************************************************************************************/
68
69/** Function pointer for a general Windows driver store enumeration callback. */
70typedef int (*PFNVBOXWINDRVSTORE_ENUM_FILES_CALLBACK)(const char *pszFilePathAbs, void *pvCtx);
71
72/**
73 * Structure for keeping a generic Windows driver store file enumeration context.
74 */
75typedef struct _VBOXWINDRVENUMFILESCTX
76{
77 /** Pointer to driver store instance. */
78 PVBOXWINDRVSTORE pDrvStore;
79 /** Pointer to driver store list to add found files to. */
80 PVBOXWINDRVSTORELIST pList;
81 /** Filter to apply for enumeration. Optional. */
82 VBOXWINDRVSTOREENTRY Filter;
83} VBOXWINDRVENUMFILESCTX;
84/** Pointer to a generic Windows driver store file enumeration context. */
85typedef VBOXWINDRVENUMFILESCTX *PVBOXWINDRVENUMFILESCTX;
86
87
88/**
89 * Creates a Windows driver store entry.
90 *
91 * @returns VBox status code.
92 * @param ppEntry Where to return the created Windows driver store entry on success.
93 */
94int vboxWinDrvStoreEntryCreate(PVBOXWINDRVSTOREENTRY *ppEntry)
95{
96 PVBOXWINDRVSTOREENTRY pEntry = (PVBOXWINDRVSTOREENTRY)RTMemAllocZ(sizeof(VBOXWINDRVSTOREENTRY));
97 AssertPtrReturn(pEntry, VERR_NO_MEMORY);
98
99 *ppEntry = pEntry;
100
101 return VINF_SUCCESS;
102}
103
104/**
105 * Destroys a Windows driver store entry.
106 *
107 * @param pEntry Windows driver store entry to destroy.
108 */
109void vboxWinDrvStoreEntryDestroy(PVBOXWINDRVSTOREENTRY pEntry)
110{
111 if (!pEntry)
112 return;
113
114 RTMemFree(pEntry);
115 pEntry = NULL;
116}
117
118/**
119 * Duplicates a Windows driver store entry.
120 *
121 * @returns Duplicated Windows driver store entry.
122 * @param pEntry Windows driver store list to duplicate.
123 */
124PVBOXWINDRVSTOREENTRY vboxWinDrvStoreEntryDup(PVBOXWINDRVSTOREENTRY pEntry)
125{
126 return (PVBOXWINDRVSTOREENTRY)RTMemDup(pEntry, sizeof(VBOXWINDRVSTOREENTRY));
127}
128
129/**
130 * Initializes a Windows driver store list.
131 *
132 * @param pList Windows driver store list to initialize.
133 */
134void vboxWinDrvStoreListInit(PVBOXWINDRVSTORELIST pList)
135{
136 RT_BZERO(pList, sizeof(VBOXWINDRVSTORELIST));
137
138 RTListInit(&pList->List);
139}
140
141/**
142 * Creates a Windows driver store list.
143 *
144 * @returns VBox status code.
145 * @param ppList Where to return the created Windows driver store list on success.
146 */
147int vboxWinDrvStoreListCreate(PVBOXWINDRVSTORELIST *ppList)
148{
149 PVBOXWINDRVSTORELIST pList = (PVBOXWINDRVSTORELIST)RTMemAlloc(sizeof(VBOXWINDRVSTORELIST));
150 AssertPtrReturn(pList, VERR_NO_MEMORY);
151
152 vboxWinDrvStoreListInit(pList);
153
154 *ppList = pList;
155
156 return VINF_SUCCESS;
157}
158
159/**
160 * Destroys a Windows driver store list.
161 *
162 * @param pList Windows driver store list to destroy.
163 * The pointer will be invalid after return.
164 */
165void vboxWinDrvStoreListDestroy(PVBOXWINDRVSTORELIST pList)
166{
167 if (!pList)
168 return;
169
170 PVBOXWINDRVSTOREENTRY pCur, pNext;
171 RTListForEachSafe(&pList->List, pCur, pNext, VBOXWINDRVSTOREENTRY, Node)
172 {
173 RTListNodeRemove(&pCur->Node);
174 vboxWinDrvStoreEntryDestroy(pCur);
175 }
176}
177
178/**
179 * Free's a Windows driver store list.
180 *
181 * @param pList Windows driver store list to free.
182 * The pointer will be invalid after return.
183 */
184void VBoxWinDrvStoreListFree(PVBOXWINDRVSTORELIST pList)
185{
186 if (!pList)
187 return;
188
189 vboxWinDrvStoreListDestroy(pList);
190 RTMemFree(pList);
191}
192
193/**
194 * Adds an entry to a Windows driver store list.
195 *
196 * @returns VBox status code.
197 * @param pList Windows driver store list to add entry to.
198 * @param pEntry Entry to add.
199 */
200static int vboxWinDrvStoreListAdd(PVBOXWINDRVSTORELIST pList, PVBOXWINDRVSTOREENTRY pEntry)
201{
202 RTListAppend(&pList->List, &pEntry->Node);
203 pList->cEntries++;
204
205 return VINF_SUCCESS;
206}
207
208/**
209 * Enumeration for the driver store list query type.
210 */
211typedef enum VBOXWINDRVSTORELISTQUERYTYPE
212{
213 /** Queries all entries. */
214 VBOXWINDRVSTORELISTQUERYTYPE_ANY = 0,
215 /** Query by PnP (Hardware) ID. */
216 VBOXWINDRVSTORELISTQUERYTYPE_PNP_ID,
217 /** Query by model name. */
218 VBOXWINDRVSTORELISTQUERYTYPE_MODEL_NAME,
219 /** Query by driver name (.sys). */
220 VBOXWINDRVSTORELISTQUERYTYPE_DRIVER_NAME
221} VBOXWINDRVSTORELISTQUERYTYPE;
222
223/**
224 * Queries a driver store list.
225 *
226 * @returns VBox status code.
227 * @param pList Driver store list to query.
228 * @param enmType Query type.
229 * @param pvType Query data. Must match \a enmType.
230 * @param ppListResults Where to return found results on success.
231 * Must be destroyed with VBoxWinDrvStoreListFree().
232 */
233static int vboxWinDrvStoreListQueryEx(PVBOXWINDRVSTORELIST pList, VBOXWINDRVSTORELISTQUERYTYPE enmType, const void *pvType,
234 PVBOXWINDRVSTORELIST *ppListResults)
235{
236 PVBOXWINDRVSTORELIST pListResults;
237 int rc = vboxWinDrvStoreListCreate(&pListResults);
238 AssertRCReturn(rc, rc);
239
240 /* Currently all query types require strings, so do this for all query times for now. */
241 char *pszType = NULL;
242 if (pvType)
243 {
244 AssertReturn(RTStrIsValidEncoding((const char *)pvType), VERR_INVALID_PARAMETER);
245 pszType = RTStrDup((const char *)pvType);
246 AssertPtrReturnStmt(pszType, VBoxWinDrvStoreListFree(pListResults), VERR_NO_MEMORY);
247 }
248
249 PRTUTF16 papszHaystacks[4] = { NULL }; /* Array of haystacks to search in. */
250 size_t cHaystacks = 0; /* Number of haystacks to search in, zero-based. */
251
252 PVBOXWINDRVSTOREENTRY pCur;
253 RTListForEach(&pList->List, pCur, VBOXWINDRVSTOREENTRY, Node)
254 {
255 bool fFound = false;
256 if (pszType == NULL) /* No query type specified? Then directly add the entry to the list. */
257 {
258 fFound = true;
259 }
260 else
261 {
262 switch (enmType)
263 {
264 case VBOXWINDRVSTORELISTQUERYTYPE_PNP_ID:
265 {
266 papszHaystacks[cHaystacks++] = pCur->wszPnpId;
267 break;
268 }
269 case VBOXWINDRVSTORELISTQUERYTYPE_MODEL_NAME:
270 {
271 papszHaystacks[cHaystacks++] = pCur->wszModel;
272 break;
273 }
274 case VBOXWINDRVSTORELISTQUERYTYPE_DRIVER_NAME:
275 {
276 papszHaystacks[cHaystacks++] = pCur->wszDriverName;
277 break;
278 }
279 case VBOXWINDRVSTORELISTQUERYTYPE_ANY:
280 {
281 papszHaystacks[cHaystacks++] = pCur->wszPnpId;
282 papszHaystacks[cHaystacks++] = pCur->wszModel;
283 papszHaystacks[cHaystacks++] = pCur->wszDriverName;
284 break;
285 }
286
287 default:
288 rc = VERR_NOT_IMPLEMENTED;
289 break;
290 }
291
292 if (RT_FAILURE(rc))
293 break;
294
295 for (size_t i = 0; i < cHaystacks; i++)
296 {
297 /* Slow, but does the job for now. */
298 char *pszHaystack;
299 rc = RTUtf16ToUtf8(papszHaystacks[i], &pszHaystack);
300 if (RT_SUCCESS(rc))
301 {
302 /* Convert strings to lowercase first, as RTStrSimplePatternMatch() is case sensitive. */
303 RTStrToLower(pszType);
304 RTStrToLower(pszHaystack);
305
306 fFound = RTStrSimplePatternMatch(pszType, pszHaystack);
307
308 RTStrFree(pszHaystack);
309
310 if (fFound)
311 break;
312 }
313 }
314 }
315
316 if (fFound)
317 {
318 PVBOXWINDRVSTOREENTRY pEntry = vboxWinDrvStoreEntryDup(pCur);
319 if (pEntry)
320 vboxWinDrvStoreListAdd(pListResults, pEntry);
321 else
322 AssertFailedBreakStmt(rc = VERR_NO_MEMORY);
323 }
324
325 cHaystacks = 0;
326 }
327
328 RTStrFree(pszType);
329
330 if (RT_SUCCESS(rc))
331 *ppListResults = pListResults;
332 else
333 VBoxWinDrvStoreListFree(pListResults);
334
335 return rc;
336}
337
338/**
339 * Enumerates files of a given (local) directory.
340 *
341 * @returns VBox status code.
342 * @param pszPathAbs Absolute path to enumerate files for.
343 * @param pszFilter Filter to use for enumeration (NT wildcards supported).
344 * @param pfnCallback Pointer to callback function to invoke for matching files.
345 * @param pvCtx User-supplied pointer to use.
346 */
347static int vboxWinDrvStoreEnumerateFiles(const char *pszPathAbs, const char *pszFilter,
348 PFNVBOXWINDRVSTORE_ENUM_FILES_CALLBACK pfnCallback, void *pvCtx)
349{
350 char szPathWithFilter[RTPATH_MAX];
351 int rc = RTStrCopy(szPathWithFilter, sizeof(szPathWithFilter), pszPathAbs);
352 AssertRCReturn(rc, rc);
353
354 RTDIR hDir = NIL_RTDIR;
355
356 if (pszFilter)
357 {
358 rc = RTPathAppend(szPathWithFilter, sizeof(szPathWithFilter), pszFilter);
359 if (RT_SUCCESS(rc))
360 rc = RTDirOpenFiltered(&hDir, szPathWithFilter, RTDIRFILTER_WINNT, 0);
361 }
362 else
363 rc = RTDirOpen(&hDir, szPathWithFilter);
364
365 if (RT_FAILURE(rc))
366 return rc;
367
368 for (;;)
369 {
370 char szFileAbs[RTPATH_MAX];
371
372 RTDIRENTRY DirEntry;
373 rc = RTDirRead(hDir, &DirEntry, NULL);
374 if (RT_FAILURE(rc))
375 {
376 if (rc == VERR_NO_MORE_FILES)
377 rc = VINF_SUCCESS;
378 break;
379 }
380
381 rc = RTStrCopy(szFileAbs, sizeof(szFileAbs), pszPathAbs);
382 AssertRCBreak(rc);
383 rc = RTPathAppend(szFileAbs, sizeof(szFileAbs), DirEntry.szName);
384 AssertRCBreak(rc);
385
386 rc = pfnCallback(szFileAbs, pvCtx);
387 if (RT_FAILURE(rc))
388 break;
389 }
390
391 RTDirClose(hDir);
392 return rc;
393}
394
395/**
396 * Initializes a driver store entry from a given INF file.
397 *
398 * @returns VBox status code.
399 * @param pEntry Driver store entry to initialize.
400 * @param pszFilePathAbs Absolute path to INF file.
401 */
402static int vboxWinDrvStoreEntryInitFromInf(PVBOXWINDRVSTOREENTRY pEntry, const char *pszFilePathAbs)
403{
404 HINF hInf;
405 int rc = VBoxWinDrvInfOpenUtf8(pszFilePathAbs, &hInf);
406 if (RT_FAILURE(rc))
407 return rc;
408
409 PRTUTF16 pwszFile;
410 rc = RTStrToUtf16(RTPathFilename(pszFilePathAbs), &pwszFile);
411 if (RT_SUCCESS(rc))
412 {
413 rc = RTUtf16Copy(pEntry->wszInfFile, RT_ELEMENTS(pEntry->wszInfFile), pwszFile);
414 if (RT_SUCCESS(rc))
415 {
416 PRTUTF16 pwszMainSection;
417 VBOXWINDRVINFTYPE enmType = VBoxWinDrvInfGetTypeEx(hInf, &pwszMainSection);
418 if (enmType != VBOXWINDRVINFTYPE_INVALID)
419 {
420 PRTUTF16 pwszModel;
421 rc = VBoxWinDrvInfQueryFirstModel(hInf, pwszMainSection, &pwszModel);
422 if (RT_SUCCESS(rc))
423 {
424 rc = RTUtf16Copy(pEntry->wszModel, RT_ELEMENTS(pEntry->wszModel), pwszModel);
425 if (RT_SUCCESS(rc))
426 {
427 /* PnP ID is optional. */
428 PRTUTF16 pwszPnpId;
429 int rc2 = VBoxWinDrvInfQueryFirstPnPId(hInf, pEntry->wszModel, &pwszPnpId);
430 if (RT_SUCCESS(rc2))
431 {
432 rc = RTUtf16Copy(pEntry->wszPnpId, RT_ELEMENTS(pEntry->wszPnpId), pwszPnpId);
433 RTUtf16Free(pwszPnpId);
434 }
435 }
436
437 RTUtf16Free(pwszModel);
438 }
439
440 RTUtf16Free(pwszMainSection);
441 }
442 else
443 rc = VERR_INVALID_PARAMETER;
444 }
445
446 int rc2 = VBoxWinDrvInfQuerySectionVer(hInf, &pEntry->Ver);
447 if (RT_SUCCESS(rc))
448 rc = rc2;
449
450 RTUtf16Free(pwszFile);
451 }
452
453 VBoxWinDrvInfClose(hInf);
454 return rc;
455}
456
457/**
458 * Initializes a driver store.
459 *
460 * @returns VBox status code.
461 * @param pDrvStore Driver store to initialize.
462 */
463static int vboxWinDrvStoreInit(PVBOXWINDRVSTORE pDrvStore)
464{
465 vboxWinDrvStoreListInit(&pDrvStore->lstDrivers);
466
467 int rc = VINF_SUCCESS;
468
469 uint64_t const uNtVer = RTSystemGetNtVersion();
470 if (uNtVer >= RTSYSTEM_MAKE_NT_VERSION(5, 0, 0)) /* for W2K, W7, Vista / 2008 Server and up. */
471 {
472 pDrvStore->Backend.Iface.pfnEnumerate = vboxWinDrvStoreLegacyImpl_Enumerate;
473 }
474 else
475 {
476 rc = VERR_NOT_IMPLEMENTED;
477 }
478
479 if ( RT_SUCCESS(rc)
480 && pDrvStore->Backend.Iface.pfnEnumerate)
481 rc = pDrvStore->Backend.Iface.pfnEnumerate(pDrvStore);
482
483 return rc;
484}
485
486/**
487 * Creates a driver store.
488 *
489 * @returns VBox status code.
490 * @param pDrvStore Where to return the driver store on success.
491 */
492int VBoxWinDrvStoreCreate(PVBOXWINDRVSTORE *ppDrvStore)
493{
494 PVBOXWINDRVSTORE pDrvStore = (PVBOXWINDRVSTORE)RTMemAllocZ(sizeof(VBOXWINDRVSTORE));
495 AssertPtrReturn(pDrvStore, VERR_NO_MEMORY);
496
497 int rc = vboxWinDrvStoreInit(pDrvStore);
498 if (RT_SUCCESS(rc))
499 {
500 *ppDrvStore = pDrvStore;
501 }
502 else
503 RTMemFree(pDrvStore);
504
505 return rc;
506}
507
508/**
509 * Destroys a driver store.
510 *
511 * @param pDrvStore Driver store to destroy.
512 * The pointer will be invalid after return.
513 */
514void VBoxWinDrvStoreDestroy(PVBOXWINDRVSTORE pDrvStore)
515{
516 if (!pDrvStore)
517 return;
518
519 vboxWinDrvStoreListDestroy(&pDrvStore->lstDrivers);
520
521 RTMemFree(pDrvStore);
522 pDrvStore = NULL;
523}
524
525/**
526 * Queries the driver store for a specific pattern.
527 *
528 * @returns VBox status code.
529 * @param pDrvStore Driver store to query.
530 * @param pszPattern Pattern to query for. DOS-style wildcards supported.
531 * @param ppResults Where to return the results list on success.
532 * Must be free'd with VBoxWinDrvStoreListFree().
533 */
534int VBoxWinDrvStoreQueryAny(PVBOXWINDRVSTORE pDrvStore, const char *pszPattern, PVBOXWINDRVSTORELIST *ppResults)
535{
536 return vboxWinDrvStoreListQueryEx(&pDrvStore->lstDrivers, VBOXWINDRVSTORELISTQUERYTYPE_ANY, pszPattern, ppResults);
537}
538
539/**
540 * Queries the driver store for all found entries.
541 *
542 * @returns VBox status code.
543 * @param pDrvStore Driver store to query.
544 * @param ppResults Where to return the results list on success.
545 * Must be free'd with VBoxWinDrvStoreListFree().
546 */
547int VBoxWinDrvStoreQueryAll(PVBOXWINDRVSTORE pDrvStore, PVBOXWINDRVSTORELIST *ppResults)
548{
549 return VBoxWinDrvStoreQueryAny(pDrvStore, NULL /* pszPattern */, ppResults);
550}
551
552/**
553 * Queries the driver store for a PnP ID.
554 *
555 * @returns VBox status code.
556 * @param pDrvStore Driver store to query.
557 * @param pszPnpId PnP ID to query. DOS-style wildcards supported.
558 * @param ppResults Where to return the results list on success.
559 * Must be free'd with VBoxWinDrvStoreListFree().
560 */
561int VBoxWinDrvStoreQueryByPnpId(PVBOXWINDRVSTORE pDrvStore, const char *pszPnpId, PVBOXWINDRVSTORELIST *ppResults)
562{
563 return vboxWinDrvStoreListQueryEx(&pDrvStore->lstDrivers, VBOXWINDRVSTORELISTQUERYTYPE_PNP_ID, (const char *)pszPnpId,
564 ppResults);
565}
566
567/**
568 * Queries the driver store for a model name.
569 *
570 * @returns VBox status code.
571 * @param pDrvStore Driver store to query.
572 * @param pszPnpId Model name to query. DOS-style wildcards supported.
573 * @param ppResults Where to return the results list on success.
574 * Must be free'd with VBoxWinDrvStoreListFree().
575 */
576int VBoxWinDrvStoreQueryByModelName(PVBOXWINDRVSTORE pDrvStore, const char *pszModelName, PVBOXWINDRVSTORELIST *ppResults)
577{
578 return vboxWinDrvStoreListQueryEx(&pDrvStore->lstDrivers, VBOXWINDRVSTORELISTQUERYTYPE_MODEL_NAME, (const char *)pszModelName,
579 ppResults);
580}
581
582/**
583 * Returns the backend's location.
584 *
585 * @returns The backend's location.
586 * @param pDrvStore Driver store to return location for.
587 */
588const char *VBoxWinDrvStoreBackendGetLocation(PVBOXWINDRVSTORE pDrvStore)
589{
590 /* Currently the only type available, so keep it simple for now. */
591 return pDrvStore->Backend.u.LocalFs.szPathAbs;
592}
593
594
595/*********************************************************************************************************************************
596* Leacy driver store implementation *
597*********************************************************************************************************************************/
598
599static DECLCALLBACK(int) vboxWinDrvStoreImplLegacy_OemInfEnumCallback(const char *pszFilePathAbs, void *pvCtx)
600{
601 PVBOXWINDRVENUMFILESCTX pCtx = (PVBOXWINDRVENUMFILESCTX)pvCtx;
602
603 bool fFound = false;
604
605 PVBOXWINDRVSTOREENTRY pEntry = NULL;
606 int rc = vboxWinDrvStoreEntryCreate(&pEntry);
607 if (RT_SUCCESS(rc))
608 {
609 rc = vboxWinDrvStoreEntryInitFromInf(pEntry, pszFilePathAbs);
610 if (RT_SUCCESS(rc))
611 {
612 do
613 {
614 /* Filter by model? */
615 if ( pCtx->Filter.wszModel[0] != '\0'
616 && RTUtf16ICmp(pCtx->Filter.wszModel, pEntry->wszModel))
617 {
618 break;
619 }
620
621 /* Filter by PnP ID? */
622 if ( pCtx->Filter.wszPnpId[0] != '\0'
623 /* Insensitive case compare for GUIDs. */
624 && RTUtf16ICmp(pCtx->Filter.wszPnpId, pEntry->wszPnpId))
625 {
626 break;
627 }
628
629 rc = vboxWinDrvStoreListAdd(pCtx->pList, pEntry);
630 AssertRCBreak(rc);
631 fFound = true;
632
633 } while (0);
634 }
635
636 if ( RT_FAILURE(rc)
637 || !fFound)
638 vboxWinDrvStoreEntryDestroy(pEntry);
639 }
640
641 return VINF_SUCCESS; /* Keep enumeration going. */
642}
643
644static DECLCALLBACK(int) vboxWinDrvStoreLegacyImpl_Enumerate(PVBOXWINDRVSTORE pThis)
645{
646 /* Note1: Do *not* rely on environment variables here due to security reasons. */
647 /* Note2: Do *not* use GetSystemWindowsDirectoryW() here, as this breaks running on W2K (not available there). */
648 RTUTF16 wszWinDir[RTPATH_MAX];
649 UINT cwcWinDir = GetWindowsDirectoryW(wszWinDir, RT_ELEMENTS(wszWinDir));
650 if (cwcWinDir <= 0)
651 return VERR_PATH_NOT_FOUND;
652
653 char *pszWinDir;
654 int rc = RTUtf16ToUtf8(wszWinDir, &pszWinDir);
655 AssertRCReturn(rc, rc);
656
657 rc = RTStrCopy(pThis->Backend.u.LocalFs.szPathAbs, sizeof(pThis->Backend.u.LocalFs.szPathAbs), pszWinDir);
658 if (RT_SUCCESS(rc))
659 rc = RTPathAppend(pThis->Backend.u.LocalFs.szPathAbs, sizeof(pThis->Backend.u.LocalFs.szPathAbs), "INF");
660
661 if (RT_FAILURE(rc))
662 return rc;
663
664 pThis->Backend.enmType = VBOXWINDRVSTOREBACKENDTYPE_LOCAL_FS;
665
666 VBOXWINDRVENUMFILESCTX Ctx;
667 RT_ZERO(Ctx);
668 Ctx.pDrvStore = pThis;
669 Ctx.pList = &pThis->lstDrivers;
670
671 return vboxWinDrvStoreEnumerateFiles(pThis->Backend.u.LocalFs.szPathAbs, "oem*.inf",
672 vboxWinDrvStoreImplLegacy_OemInfEnumCallback, &Ctx);
673}
674
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