0

I'm using setup.api in c#. There are all work successfully but SetupDiGetDriverInfoDetail. When the program execute this line, it will pop up the exception message

SetupDiGetDriverInfoDetail' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target.

I think the error is because of the declare signature:

[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
    internal struct SP_DRVINFO_DETAIL_DATA
    {
        public Int32 cbSize;
        public System.Runtime.InteropServices.ComTypes.FILETIME InfDate;
        public Int32 CompatIDsOffset;
        public Int32 CompatIDsLength;
        public IntPtr Reserved;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public String SectionName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public String InfFileName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public String DrvDescription;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)]
        public String HardwareID;
    };



 [DllImport("setupapi.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
    static extern uint SetupDiGetDriverInfoDetail(
        IntPtr DeviceInfoSet,
        SP_DEVINFO_DATA DeviceInfoData,
        SP_DRVINFO_DATA DriverInfoData,
        ref SP_DRVINFO_DETAIL_DATA DriverInfoDetailData,
        Int32 DriverInfoDetailDataSize,
        ref Int32 RequiredSize);

And I use these code from the following:

private string GetDrivInfoDetailHWID()
    {
        SP_DRVINFO_DETAIL_DATA driInfoDetailData = new SP_DRVINFO_DETAIL_DATA();
        Int32 requiredSize = 0;
        driInfoDetailData.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(SP_DRVINFO_DETAIL_DATA));
        while(SetupDiGetDriverInfoDetail(_deviceHandle, _devInfoData, _driInfoData, ref driInfoDetailData, requiredSize, ref requiredSize)==0)
        {
            int e = Marshal.GetLastWin32Error();
        }
        return driInfoDetailData.HardwareID;
    }

Please help me to solve this problem, I'll really appreciate about that.

David Shen
  • 75
  • 1
  • 5
  • The struct should not specify packing and the variable length member is handled wrongly. Can't be marshalled automatically. The function is surely stdcall. We can't see the other struct so don't know if that's wrong. – David Heffernan Aug 06 '15 at 05:47
  • The other structs are work in others setupapi functions. So I think that is not the main problem. Could you show me the correct signature of this struct ? Thanks – David Shen Aug 06 '15 at 05:53
  • There is no "main" problem. You have to fix all the problems. That's the joy of interop. You'll want to pass that variable length struct as IntPtr. Allocate unmanaged memory to do so. Use Marshal.OffsetOf and Marshal.PtrToStructure to do the marshalling. – David Heffernan Aug 06 '15 at 05:59
  • Another problem is that you aren't calling the function the right way. Please read the docs again. My advice is to write C++ code to call it and get a feel for how the API works. You can't translate to pinvoke without a clear understanding of how the function works and you've not got that yet. – David Heffernan Aug 06 '15 at 06:06

0 Answers0