Domanda

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?

È stato utile?

Soluzione

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);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top