The DD_MORESURFACECAPS structure is of variable size. It always has a ddsCapsMore member, but it may have zero or more ddsExtendedHeapRestrictions entries. If the driver responds to the GUID_DDMoreSurfaceCaps query, it should return a DD_MORESURFACECAPS structure that contains as many ddsExtendedHeapRestrictions entries as it returned display memory heaps in the DD_HALINFO structure (DirectDraw guarantees that the GUID_DDMoreSurfaceCaps query is made after the driver reports DD_HALINFO.)
The driver should also fill in an appropriate dwSize value in the DD_MORESURFACECAPS structure. The value of dwSize is calculated in this way:
DDMORESURFACECAPS.dwSize = (DWORD) (sizeof(DDMORESURFACECAPS) + (((signed int)DDHALINFO.vmiData.dwNumHeaps) - 1) * sizeof(DDSCAPSEX)*2 );
Note that subtracting 1 from the value of dwNumHeaps is necessary to account for the fact that the DD_MORESURFACECAPS structure has a ddsExtendedHeapRestrictions member that is a one-element array. Only those array elements after the first (that is, from ddsExtendedHeapRestrictions on) should be counted in calculating the total size of the DD_MORESURFACECAPS structure.
The ddsCapsEx and ddsCapsExAlt members are exactly analogous to the ddsCaps and ddsCapsAlt members of the array of VIDEOMEMORY structures returned in the pvmList member of the VIDEOMEMORYINFO structure, which is contained as a member of the DD_HALINFO structure. Any bit set in ddsCapsEx means that surface with that bit set must not be placed in that heap. Any bit set in the ddsCapsExAlt member means that the surface cannot be placed in that heap. When allocating surfaces, DirectDraw first passes through all heaps, and if it finds any heap for which no capability bits in the ddsCaps member of the VIDEOMEMORY structure match with the DDSCAPS bits of the surface, it allocates the surface in that heap. If this pass finds no such heaps, then DirectDraw makes the same pass but checks the ddsCapsEx field. If this pass fails to find any heaps, then the surface cannot be created in any heap.