0

I'm trying to debug some C# P/Invoke problem with 32/64 bit using the SetupDiGetDeviceInterfaceDetail function. This involves analysing the SP_DEVICE_INTERFACE_DETAIL_DATA structure. For this, I tried to write a simple C++ program to see the data that's not documented. My C skills aren't sufficient to read the structure sizes from the definitions.

Here's the code for a new C++ Windows console application created with Visual Studio 2017:

#include "pch.h"
#include <iostream>
#include <Setupapi.h>

int main()
{
    std::cout << "Size: " << sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) << "\n";
}

As soon as I add the third include, I get 1600+ compiler errors about syntax errors within Microsoft files – missing semicolons, type specifiers and other stuff, spreading over several files like setupapi.h, prsht.h, dpa_dsa.h or commctrl.h. That's well outside my capabilities. Looks like Microsoft has delivered a huge mess. Wondering how Visual Studio was compiled if C++ programming is always like this.

What's wrong here? Why can't I just include that header file as suggested in the documentation?

Is there another way to find out what that sizeof expression would resolve to?

4
  • 2
    #include <windows.h> before #include <Setupapi.h> Commented Dec 20, 2019 at 22:57
  • @RichardCritten Thanks, that helped. I could accept it if it was an answer instead of a comment. How should I know this? Commented Dec 20, 2019 at 23:04
  • Am not sure how you should know this (without some research). From experience: all common type definitions are in <windows.h> header file. Additional header files for specific functionality don't redefine the common types they instead need <windows.h> included 1st to provide them. Commented Dec 20, 2019 at 23:07
  • @ygoe ”How should I know this?” By reading output of the compiler. See Output IDE panel, switch the “Show output from” dropdown to “Build”. The first error you’re getting without <windows.h> points to this line in SetupAPI.h: typedef GUID *LPGUID; The GUID identifier has wavy red underline, move mouse there and you’ll see a tooltip saying “identifier GUID is undefined”. Commented Dec 20, 2019 at 23:19

1 Answer 1

1

Here's a fixed version:

#include <iostream>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Setupapi.h>

int main()
{
    std::cout << "Size: " << sizeof( SP_DEVICE_INTERFACE_DETAIL_DATA ) << "\n";
}

It prints 6, however that's not true, unfortunately for you that structure is variable-length. It's defined like this:

#define ANYSIZE_ARRAY 1
struct SP_DEVICE_INTERFACE_DETAIL_DATA_W
{
    DWORD  cbSize;
    WCHAR  DevicePath[ ANYSIZE_ARRAY ];
}

The length varies depending on data.

Sign up to request clarification or add additional context in comments.

1 Comment

That's okay, I need the value of sizeof because that's what must be put in the cbSize field. When using this API from C# I have to convert the relevant structures to managed code that behaves exactly the same, no matter what it means. I wasn't sure if the array counts by content or denotes a pointer. Also, ANYSIZE_ARRAY didn't make sense to me and the value was unclear.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.