Bloqueada Get Device Driver INF File API

  • domingo, 11 de marzo de 2012 19:06
     
     
    I seem to recall that there is an API which will return the INF file associated with a device driver but I'm drawing a blank.  I want to get the path to the INF File, File Name Section Name and File Date.  Could someone please refresh my memory.

Todas las respuestas

  • domingo, 11 de marzo de 2012 19:43
     
     Respondida
    The SP_DRVINFO_DETAIL_DATA structure contains that information. It's returned from a call to SetupDiGetDriverInfoDetail.

    Armin

  • domingo, 11 de marzo de 2012 22:26
     
      Tiene código

    Thanks for the assist.  I think I got it.  Would you be so kind as to take a look at my declare and structure.  I had to figure it out the hard way, as I could not find a pinvoke example online.  Here are my imports:

    	<DllImport("SetupAPI.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    	<ReliabilityContract(Consistency.WillNotCorruptState, Cer.None)> _
    	Public Function SetupDiEnumDeviceInfo(<[In]()> ByVal hDeviceInfoSet As IntPtr, <[In]()> ByVal index As Integer, <Out()> ByRef devInfoData As DeviceInstanceInfo) As <MarshalAs(UnmanagedType.Bool)> Boolean
    	End Function
    	<DllImport("setupapi.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    	<ReliabilityContract(Consistency.WillNotCorruptState, Cer.None)> _
    	Public Function SetupDiGetDriverInfoDetail(<[In]()> ByVal hDeviceInfoSet As IntPtr, <[In]()> ByVal DeviceInfoData As DeviceDriverInfo, <[In]()> ByVal DriverInfoData As DeviceDriverInfo, <Out()> ByRef DriverInfoDetailData As DeviceDriverInfoDetailData, <[In]()> ByVal DriverInfoDetailDataSize As Int32, <Out()> ByRef RequiredSize As Int32) As Boolean
    	End Function

    Here are my structures:

    <StructLayout(LayoutKind.Sequential, Pack:=4, CharSet:=CharSet.Unicode)> _
    Public Structure DeviceDriverInfo
    	Public Size As Integer
    	<MarshalAs(UnmanagedType.U4)> _
    	Public DriverType As DeviceDriverType
    	Public Reserved As IntPtr
    	<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
    	Public Description As String
    	<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
    	Public Manufacturer As String
    	<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
    	Public Provider As String
    	Public ReleaseDate As Long
    	Public Version As Long
    End Structure
    <StructLayout(LayoutKind.Sequential, Pack:=4, CharSet:=CharSet.Unicode)> _
    Public Structure DeviceDriverInfoDetailData
    	Public cbSize As Int32
    	Public InfDate As System.Runtime.InteropServices.ComTypes.FILETIME
    	Public CompatIDsOffset As Int32
    	Public CompatIDsLength As Int32
    	Public Reserved As IntPtr
    	<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
    	Public SectionName As [String]
    	<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
    	Public InfFileName As [String]
    	<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
    	Public DrvDescription As [String]
    	<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
    	Public HardwareID As [String]
    End Structure

    Thanks for the help
  • lunes, 12 de marzo de 2012 22:19
     
     Respondida Tiene código

    I'm sorry for answering late. Just saw your new thread. My problem is that you use different names instead of SP_DRVINFO_DATA etc, so it's a bit hard for me to handle because I always have to find the appropriate types in the SDK first. In addition, I haven't figured out yet how to handle the last member in DeviceDriverInfoDetailData (HardwareID) which has a dynamic length.

    I don't make long comments now but post my versions instead. You can see yourself what I've changed: (several things had to be corrected)

       Public Const LINE_LEN As UInteger = 256
       Public Const MAX_PATH As UInteger = 260
       Public Const ANYSIZE_ARRAY As UInteger = 1
    
       <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
       Public Structure SP_DRVINFO_DATA
          Public Size As UInt32
          <MarshalAs(UnmanagedType.U4)> Public DriverType As DeviceDriverType
          Public Reserved As IntPtr
          <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> Public Description As String
          <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> Public Manufacturer As String
          <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> Public Provider As String
          Public ReleaseDate As ComTypes.FILETIME
          Public Version As UInt64
       End Structure
    
       <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
       Public Structure SP_DRVINFO_DETAIL_DATA
          Public cbSize As UInt32
          Public InfDate As ComTypes.FILETIME
          Public CompatIDsOffset As UInt32
          Public CompatIDsLength As UInt32
          Public Reserved As UIntPtr
          <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=LINE_LEN)> Public SectionName As String
          <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_PATH)> Public InfFileName As String
          <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=LINE_LEN)> Public DrvDescription As String
          <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=ANYSIZE_ARRAY)> Public HardwareID As String
       End Structure
    
    
    
       <StructLayout(LayoutKind.Sequential)> _
       Structure SP_DEVINFO_DATA
          Public cbSize As UInt32
          Public ClassGuid As Guid
          Public DevInst As UInt32
          Public Reserved As UIntPtr
       End Structure
    
    
       Public Declare Auto Function SetupDiEnumDeviceInfo Lib "setupapi.dll" ( _
          ByVal hDevInfo As IntPtr, _
          ByVal MemberIndex As UInt32, _
          <[In](), Out()> ByRef DeviceInfoData As SP_DEVINFO_DATA) _
          As Boolean
    
    
       Public Declare Auto Function SetupDiGetDriverInfoDetail Lib "setupapi.dll" ( _
          ByVal hDeviceInfoSet As IntPtr, _
          <[In]()> ByRef DeviceInfoData As SP_DEVINFO_DATA, _
          <[In]()> ByRef DriverInfoData As SP_DRVINFO_DATA, _
          <Out()> ByRef DriverInfoDetailData As SP_DRVINFO_DETAIL_DATA, _
          ByVal DriverInfoDetailDataSize As Int32, _
          ByRef RequiredSize As Int32) As Boolean

  • lunes, 12 de marzo de 2012 22:38
     
     

    Thanks for your reply and your patience with me.  I'm sorry my naming conventions cause problems for you.  I do this to try and make the names a little more meaningful for me.  I'm not a big fan of C or the notations used.  It's all to crypitic for me.  VB isn't cryptic and I try to make these things fit into that.  In the future I will try to remember to include a notation of the C name of any typedefs I change.  I tried as best I could to translate the C code into the correct VB code.   I am a bit confused as to how you code the Import when a parameter is in/out.  Would that be<[In]()><Out()>?  I knew the import wasn't coded quite right and the structure was equally confusing.

    Thanks for the help

  • jueves, 15 de marzo de 2012 16:20
     
     

    Shane,

    I already had a library with some native declarations (related to driver installation), but not the ones in question. In addition, I have a managed wrapper for an object-oriented view of the same stuff. That's why I'm currently integrating the missing part in my Dlls before I can test it and finally post a solution. That's why it takes a bit longer, but I'm currently at it.


    Armin

  • jueves, 15 de marzo de 2012 16:23
     
     
    Thank you Armin, I appreciate your help with this.
  • jueves, 15 de marzo de 2012 18:18
     
      Tiene código

    Currently I'm calling SetupDiEnumDriverInfo. The call works but it always returns False and native error  is ERROR_NO_MORE_ITEMS. I've tried it for the device information set and for all devices but I never get driver information. Hmmm....   ...Ok, solved. SetupDiBuildDriverInfoList has to be called before. In case anyone will read this. Oooh, yes, that takes a while to build the list.

    ...

    Now I'm getting ERROR_INVALID_USER_BUFFER at SetupDiEnumDriverInfo. I've verified everything again and again but don't see an error. The structure and the function seem to be correct. Maybe you see something wrong:  (turning the tables... ;-) )

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
    Public Structure SP_DRVINFO_DATA
       Public Size As UInt32
       Public DriverType As DriverType
       Public Reserved As UIntPtr
       <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=AZ.Win32.Constants.LINE_LEN)> Public Description As String
       <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=AZ.Win32.Constants.LINE_LEN)> Public MfgName As String
       <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=AZ.Win32.Constants.LINE_LEN)> Public ProviderName As String
       Public DriverDate As AZ.Win32.FILETIME 'ComTypes.FILETIME 
       Public DriverVersion As UInt64
    End Structure
    
    Public Enum DriverType As UInt32
       NoDriver = 0
       ClassDriver = 1
       CompatDriver = 2
    End Enum
    
    
       Public Declare Auto Function SetupDiEnumDriverInfo Lib "setupapi.dll" ( _
          ByVal DeviceInfoSet As IntPtr, _
          ByVal DeviceInfoData As IntPtr, _
          ByVal DriverType As DriverType, _
          ByVal MemberIndex As UInt32, _
          <[In](), Out()> ByRef DriverInfoData As SP_DRVINFO_DATA _
          ) As Boolean
    
    
    Public Enum DriverType As UInt32
       NoDriver = 0
       ClassDriver = 1
       CompatDriver = 2
    End Enum
    
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure FILETIME
       Public LowDateTime As UInteger
       Public HighDateTime As UInteger
    End Structure
    
    
       Public Const LINE_LEN As Integer = 256

    I'm only declare the version of SetupDiEnumDriverInfo here where I pass IntPtr.Zero as the 2nd argument.

    The value of the structure size is 1568 at run time on 64 bits here. Should be correct, but obviously it isn't


    Armin



  • jueves, 15 de marzo de 2012 18:38
     
      Tiene código

    Armin

    Here are my structures for DeviceDriverInfo:

    <StructLayout(LayoutKind.Sequential, Pack:=4, CharSet:=CharSet.Unicode)> _
    Public Structure DeviceDriverInfo
    	Public Size As Integer
    	<MarshalAs(UnmanagedType.U4)> _
    	Public DriverType As DeviceDriverType
    	Public Reserved As IntPtr
    	<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
    	Public Description As String
    	<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
    	Public Manufacturer As String
    	<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
    	Public Provider As String
    	Public ReleaseDate As Long
    	Public Version As Long
    End Structure
    Public Enum DeviceDriverType As Integer
        Unknown
        DeviceClass
        Compatible
    End Enum

    These work fine for me in my program as I am able to return the properties without any problem.  I dont have a structure for FileTime. My code manipulates and converts the value directly.  Hope this helps you out a bit.

  • jueves, 15 de marzo de 2012 18:54
     
     
    Which value du you get for the Size field (with Marshal.Sizeof)?

    Armin

  • jueves, 15 de marzo de 2012 19:04
     
     
    Public Size As Integer is my size variable yours is  Public Size As UInt32. Can't see how this would be a problem in your code.

  • jueves, 15 de marzo de 2012 19:21
     
     

    That's not a value, it's the declaration. ;) My wrong value was 1568, the correct value is 1564.

    Meanwhile I figured it out: It works with Pack:=4. The offsets in a 32 bit process are:

    without pack:

    0000: Size
    0004: DriverType
    0008: Reserved
    0012: Description
    0524: MfgName
    1036: ProviderName
    1548: DriverDate
    1560: DriverVersion

    with pack = 4

    0000: Size
    0004: DriverType
    0008: Reserved
    0012: Description
    0524: MfgName
    1036: ProviderName
    1548: DriverDate
    1556: DriverVersion

    Obviously, without explicitly specifying pack, pack=8 is used. That's why DriverVersion is aligned at 1560, which is divisible by 8 whereas 1556 is not. However, it's a 32 bit process, so I'm not sure why the marshaller aligns at 8.


    Armin

  • jueves, 15 de marzo de 2012 19:41
     
     
    Sorry I misunderstood your question.  My processor is 64 Bit.  So I should be using Pack 4 right?  I'm still trying to understand some of this stuff.
  • jueves, 15 de marzo de 2012 20:38
     
     

    By default, the default packing alignment is used, which I expect to be 4 in a 32 bit process and 8 in a 64 bit process. But obviously I was wrong. IMO, you do not have to specify the pack value. It should work despite. Though, in this case, it's necessary, yet I don't know why.

    I think the sentence in the documentation "Therefore, data fields will start on offsets that are multiples of the requested packing value" is only partially true. Actually two offsets are calculated when aligning a field:

    - The next multiple of the pack value
    - The next multiple of the size of the field to be aligned

    The field is aligned to the smaller one of both values.


    Armin

  • jueves, 15 de marzo de 2012 20:44
     
     
    OK I think I understand what you're saying.  I never thought that dealing with unmanaged APIs would be so complicated now I'm starting to understand why the safegards are put in place.  I guess even if I don't like dealing with C I'm still dealing with it.
  • jueves, 15 de marzo de 2012 20:45
     
      Tiene código

    Example:

       <StructLayout(LayoutKind.Sequential, pack:=4)> _
       Structure S
          Public f1 As Byte
          Public f2 As Long
       End Structure

    Offsets are:
    00: f1
    04: f2

    Same structure with pack = 8, offsets are:
    00: f1
    08: f2

    That's how I expect it to work - even though not correctly described in the documentation. However, what I'm surprised about is the same structure with pack = 0 (=default) in a 32 bit process:

    00: f1
    08: f2

    So, pack also seems to be 8 in a 32 bit process. Something learned today...

    EDIT: Ok, maybe I got the documentation wrong: "default packing size for the current platform" does not mean at multiples of 4 in a 32 bit process and multiples of 8 in a 64 bit process. Instead it means "only at multiples of the size of the field to be aligned". Can anyone confirm this? (even though it's not the Interop group)


    Armin


  • viernes, 16 de marzo de 2012 1:18
     
     

    I think my first message was the answer to the initial question, so I think this thread can be closed. Just trying to keep an overview. I'm gonna answer about SetupDiGetDriverInfoDetail in your other thread: http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/43b55963-9d01-441c-a2f2-911ad6ec5b13

    Solution is on it's way, but I have to eat, drink, watch football and do other essentail stuff in the meantime, too. :)


    Armin

  • viernes, 16 de marzo de 2012 1:25
     
     
    Yeah I understand Armin, I am taking a break too.  Eating some pizza and watching some TV, Steven Segal Under Seige with Story Notes.   I'm working on getting some of the program output working and displaying the proper information in the meantime.  I really appreciate all the help.  Thanks so much, it's a pleasure to work with someone who truly wants to help other people and doesn't look down on them just because the don't fully understand a particular concept or idea.  Thanks so much.