evmar / retrowin32

windows emulator
https://evmar.github.io/retrowin32/
Apache License 2.0
582 stars 26 forks source link

implement GetWindowPlacement #67

Closed LinusU closed 1 month ago

LinusU commented 2 months ago

Opening this to get some discussion around how to implement variable length structs 🤔

According to MSDN:

[...] Before calling GetWindowPlacement, set the length member to sizeof(WINDOWPLACEMENT). GetWindowPlacement fails if lpwndpl->length is not set correctly.

ref

The problem is that my program (Pocoman) doesn't seem to initialize the length property at all. From looking at Ghidra I think that the variable simply isn't initialized at all, so it has the value of whatever happened to be in that stack position previously. (note that I don't have much experience with this so I could absolutely be wrong)

Here is what dbg!(&wndpl); prints:

&wndpl = WINDOWPLACEMENT {
    length: 50078,
    flags: 4265673,
    showCmd: 4379564,
    ptMinPosition: POINT {
        x: 4260799,
        y: 4,
    },
    ptMaxPosition: POINT {
        x: 4,
        y: 4,
    },
    rcNormalPosition: RECT {
        left: 0,
        top: 50078,
        right: 4247973,
        bottom: 1183232,
    },
    rcDevice: RECT {
        left: 63,
        top: 5,
        right: 16,
        bottom: 4194304,
    },
}

I'm not really sure what to do here. I'm guessing that the input characteristics of length was introduced in a later version, in order to add rcDevice in a backwards compatible way. But I don't understand how that could be since presumable it has been called with uninitialized data for length before that 🤔

evmar commented 2 months ago

I think for now it's fine to just assume it's the size we expect, it looks like wine does this anyway. But I'd fill in length anyway just to be sure.

LinusU commented 1 month ago

@evmar Updated 👍

it seems like the larger size (rcDevice field) is only for old (pre-intel) Mac 😅