Here is an excerpt from ntdddisk.h

typedef struct _DISK_GEOMETRY_EX {
        DISK_GEOMETRY Geometry;                                 // Standard disk geometry: may be faked by driver.
        LARGE_INTEGER DiskSize;                                 // Must always be correct
        UCHAR Data[1];                                                  // Partition, Detect info
} DISK_GEOMETRY_EX, *PDISK_GEOMETRY_EX;

What is the point of UCHAR Data[1];? Why not just UCHAR Data; ? And there are a lot of structures in DDK which have arrays of one element in declarations.

Thanks, thats clear now. The one thing is not clear the implementation of offsetof. It's defined as

#ifdef  _WIN64
#define offsetof(s,m)   (size_t)( (ptrdiff_t)&(((s *)0)->m) )
#else
#define offsetof(s,m)   (size_t)&(((s *)0)->m)
#endif

How this works: ((s *)0)->m ???

This

(size_t)&((DISK_GEOMETRY_EX *)0)->Data 

is like

sizeof (DISK_GEOMETRY) + sizeof( LARGE_INTEGER);

But there is two additional questions:

1) What type is this? And why we should use & for this?

((DISK_GEOMETRY_EX *)0)->Data

2) ((DISK_GEOMETRY_EX *)0)

This gives me 00000000. Is it convering to the address alignment? interpret it like an address?

有帮助吗?

解决方案

Very common in the winapi as well, these are variable length structures. The array is always the last element in the structure and it always includes a field that indicates the actual array size. A bitmap for example is declared that way:

typedef struct tagBITMAPINFO {
    BITMAPINFOHEADER    bmiHeader;
    RGBQUAD             bmiColors[1];
} BITMAPINFO, FAR *LPBITMAPINFO, *PBITMAPINFO;

The color table has a variable number of entries, 2 for a monochrome bitmap, 16 for a 4bpp and 256 for a 8bpp bitmap. Since the actual length of the structure varies, you cannot declare a variable of that type. The compiler won't reserve enough space for it. So you always need the free store to allocate it using code like this:

#include <stddef.h>   // for offsetof() macro
....

    size_t len = offsetof(BITMAPINFO, bmiColors) + 256 * sizeof(RGBQUAD);
    BITMAPINFO* bmp = (BITMAPINFO*)malloc(len);
    bmp->bmiHeader.biClrUsed = 256;
    // etc...
    //...
    free(bmp);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top