VirtualBox

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

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

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