windows - Konvertere volumen GUID-sti til enhedens sti

Indlæg af Hanne Mølgaard Plasc

Problem



Min opgave er at spore tilføje og slette diskdrev fra windows service. Jeg bruger RegisterServiceCtrlHandlerEx og RegisterDeviceNotification til at implementere dette. Min servicekontrolhåndteringsrutine modtager succesfuldt SERVICE\_CONTROL\_DEVICEEVENT kontrolkode og håndterer DBT\_DEVICEARRIVAL og DBT\_DEVICEREMOVECOMPLETE begivenheder til GUID\_DEVINTERFACE\_VOLUME clsss. I øvrigt sender Windows ikke DBT\_DEVICEQUERYREMOVE, DBT\_DEVICEQUERYREMOVEFAILED, DBT\_DEVICEREMOVEPENDING hændelser til min rutine, men nu vil jeg løse et andet problem.


Når jeg modtager DBT\_DEVICEARRIVAL og DBT\_DEVICEREMOVECOMPLETE hændelser, og dbch\_devicetype er DBT\_DEVTYP\_DEVICEINTERFACE kan jeg læse enhedsnavn fra dbcc\_name felt af DEV\_BROADCAST\_DEVICEINTERFACE struktur. Det ser sådan ud: \? \ LAGRING # RemovableMedia # 7 &331a4e33 &0 &RM # {53f5630d-b6bf-11d0-94f2-00a0c91efb8b}


Jeg kan konvertere denne streng til lydstyringsvej ved hjælp af GetVolumeNameForVolumeMountPoint-proceduren kun i DBT\_DEVICEARRIVAL-begivenheden. På DBT\_DEVICEREMOVECOMPLETE begivenhed GetVolumeNameForVolumeMountPoint returnerer fejl 3 (Systemet kan ikke finde den angivne sti).


På den anden side under service start scanner jeg efter alle volumener i systemet med FindFirstVolume/FindNextVolume, som returnerer til mig en liste over volumen GUID-stier i alle volumener.


Så hvis volumen eksisterer, når min service starter, kan jeg modtage volumen GUID-stien. Og hvis det volumen vil blive fjernet, mens min tjeneste kører, vil jeg modtage enhedsnavn (som \? \ STORAGE # RemovableMedia # 7 &331a4e33 &0 &RM # {53f5630d-b6bf-11d0-94f2-00a0c91efb8b}) fra
DBT\_DEVICEREMOVECOMPLETE begivenhed.


Som jeg skrev ovenfor kan jeg ikke bruge GetVolumeNameForVolumeMountPoint under DBT\_DEVICEREMOVECOMPLETE hændelse for at få volumen GUID-sti. Så jeg vil gerne finde en måde at konvertere volumen GUID-sti modtaget fra FindFirstVolume/FindNextVolume til enhedsnavn. Jeg har brug for dette for at opretholde min egen liste over nuværende flytbare diskdrev i systemet.


Vær venlig at give mig nogle råd om dette problem.

Bedste reference


For at opregne enheder til opbygning af din egen enhedsliste kan du bruge SetupAPI: [2]



  Ved at bruge SetupAPI-rutinerne kan du opregne alle enheder i
  specificeret enhed interface klasse og hente enhedens sti til
  apparat.



Du kalder SetupDiGetClassDevs først med en passende GUID til din enhedsklasse, f.eks. GUID\_DEVINTERFACE\_VOLUME, og ring derefter SetupDiEnumDeviceInfo gentagne gange for at gentage enheder. [3] [4] [5]


Eksempelkode viser hvordan man gør det:



  • Videnbaseartikel viser det hele

  • En anden beskrivelse af processen findes her. Se efter sektionen Brug følgende trin til at oprette et filhåndtag til USB-enheden.



De enkelte enheder kan forespørges efter egenskaber (stien er blandt dem) ved hjælp af SetupDiGetDeviceRegistryProperty. [6] [7] [8]

Andre referencer 1


Så jeg fandt ingen måde at hente enhedsveje fra volumen GUID-stier returneret af FindFisrtVolume/FindNextVolume. I stedet erstatter jeg FindFisrtVolume/FindNextVolume med opregning af enhedsinterfaces ved hjælp af SetupApi.


Her er trin til at gøre det:



  1. Ring SetupDiGetClassDevs (&GUID\_DEVINTERFACE\_VOLUME, NULL, NULL, DIGCF\_INTERFACEDEVICE | DIGCF\_PRESENT) for at hente enhedsinfo sæt.

  2. Enum-enhedens grænseflader med SetupDiEnumDeviceInterfaces (devinfoset, NULL, &GUID\_DEVINTERFACE\_VOLUME, idx og devitf).

  3. For hver enhedens grænseflade kalder SetupDiGetDeviceInterfaceDetail for at hente enhedens sti.



Desværre adskiller enhedsvejen hentet på denne måde i tilfælde fra en enhedssti, som Windows passerer i DBT\_DEVICEARRIVAL og DBT\_DEVICEREMOVECOMPLETE events. Så vi skal normalisere enhedsveje, når vi sammenligner dem.