Hi!
This is the best! Good work Timo! I love the api testing system too! It
is getting to the point of ROX STAR! status! I know only two of them in
the project!
Timo Kreuzer wrote:
I agree with the complete structure itself, but I have
some issues with
the way it is implemented atm.
1.) the member ulOffsetTM:
If it is an offset one would guess it would be an offset from the
beginning of the struct, but it isn't. It's relative to dwFontType.
I would interpret it more as a cbSize member of an internal variable
size struct., that comes before dwFlags (see below) / textmetric
2.) The current definition has a member enfdi, wich follows after a
variable size struct. IMO this member should be removed, as it doesn't have
a constant offset. It implies that you can simply access it, but you
cannot, if the designvektor has any entries. It should be commented out to
prevent misuse.
3.) The enfdi struct doesn't really make sense to me. The dwReserved
members are not like axlReserved a constant. It looks more like some
flags or it might be code page related. With this structure the OffsetTm
member points to a substruct of a struct, that doesn't seem right to me.
So here is my version:
I also use INT versions of structs with a [0] array, so it matches the
data, when no additional stuff is present
But as we always have to consider our structs as variable length we do
not really need them. In any case we have to parse through the struct.
We can then typecast the pointers to the original structs and all's well.
typedef struct _AXELISTINTW
{
DWORD axlReserved;
DWORD axlNumAxes;
AXISINFOW axlAxesInfo[0];
} AXELISTINTW, *PAXELISTINTW;
typedef struct _ENUMTEXTMETRICINTW
{
NEWTEXTMETRICEXW etmNewTextMetricEx;
AXELISTINTW etmAxesList;
} ENUMTEXTMETRICINTW, *PENUMTEXTMETRICINTW;
typedef struct
{
DWORD cbSize;
DWORD dwFontType;
ENUMLOGFONTEXW elfex;
DESIGNVECTORINT dv;
// variable position, might be dv.dvValues[0], if DESIGNVECTORINT was
declared with dvValues[1]
// I didn't yet manage to get info with dvNumAxes > 0
// DWORD dwReserved;
} ENUMFONTDATAINTW, *PENUMFONTDATAINTW;
typedef struct _ENUMFONTDATAW
{
DWORD cbSize;
ENUMFONTDATAINTW efdi;
// Those are not real members as they don't have a constant pos in the
struct
// DWORD dwFlags;
// ENUMTEXTMETRICINTW etmi;
} ENUMFONTDATAW, *PENUMFONTDATAW;
This is what I did! Using wine gdi tests I added and modified the call back to
display the address
of the callback args. They all point back to the return structure when in unicode (W)
mode. I confirmed that:
dword ?
dword ?
dword FontType
dword ENUMLOGFONTEXW
"
"
dword NEWTEXTMETRICEXW
I taken the address of &FontType - 8 + 4 = the questionable Offset + (&FontType -
8 = start) =
(&NEWTEXTMETRICEXW - 8)! &ENUMLOGFONTEXW is at 4 more than &FontType.
LOL the call back return the address of NEWTEXTMETRICEXW. Offset + start is 8 less than
&NEWTEXTMETRICEXW. I saved the start value to check against the next start value to
make sure it was
the real size number. Yes it is the size. [struct 1.....][struct 2....] etc.
So I confirmed the size, offset, fonttype and ENUMLOGFONTEXW pointers worked. The text
metric
floated around as it should with the type of test I used at work. I found out that
Truefonts are the
best test to use, it's a bitch to setup but the results are great.
Now for the structure. It's hard to tell. I only confirmed the first 4 are fixed and I
agree that we
have to parse through the structure. I also confirmed that XP callback uses
ENUMLOGFONTEXDV and
ENUMTEXTMETRIC. In your discovered structure the axes structures are var in size based on
the type
of truefont we use and going through hundred structures are a pain. If your structure
works lets use it.
This test data is right I think. After ENUMLOGFONTEXW and NEWTEXTMETRICW the axes are
variable in size.
typedef struct _ENUMFONTDATAW
{
LONG cbSize; // 0x0000 (4)
LONG cbOffsetTm; // 0x0004 (4)
LONG dwType; // 0x0008 (4)
ENUMLOGFONTEXW EnumLogFontEx;// 0x000c (0x15c)
DWORD unknown168;
DWORD unknown16c;
DWORD unknown170; // 0x0170 (4)
DWORD unknown174; // 0x0174 (4)
NEWTEXTMETRICW NewTextMetric;// 0x0178 (0x4c)
DWORD dw1;
DWORD dw2;
DWORD dw3;
DWORD dw4;
DWORD dw5;
DWORD dw6;
DWORD dw7;
DWORD dw8;
// 0x01e4
} ENUMFONTDATAW, *PENUMFONTDATAW;
Timo! This is your structure and is looks correct based on the numbers used in the
callback. We need
to test (App test)<-->gdi32<--->Win32k and have all the pointers checked
through out.
Good Work!
James