Alexandre Julliard : user32: Pack the various owner-draw structures in messages to allow crossing 32/ 64 boundaries.

Alexandre Julliard julliard at winehq.org
Wed Mar 31 10:04:48 CDT 2010


Module: wine
Branch: master
Commit: 9b5b55d9de6d864303f675f343ae4355f6c27304
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9b5b55d9de6d864303f675f343ae4355f6c27304

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Mar 30 20:28:32 2010 +0200

user32: Pack the various owner-draw structures in messages to allow crossing 32/64 boundaries.

---

 dlls/user32/message.c |  181 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 170 insertions(+), 11 deletions(-)

diff --git a/dlls/user32/message.c b/dlls/user32/message.c
index cab4113..6650080 100644
--- a/dlls/user32/message.c
+++ b/dlls/user32/message.c
@@ -76,12 +76,69 @@ struct packed_CREATESTRUCTW
     DWORD         __pad3;
 };
 
+struct packed_DRAWITEMSTRUCT
+{
+    UINT          CtlType;
+    UINT          CtlID;
+    UINT          itemID;
+    UINT          itemAction;
+    UINT          itemState;
+    user_handle_t hwndItem;
+    DWORD         __pad1;
+    user_handle_t hDC;
+    DWORD         __pad2;
+    RECT          rcItem;
+    ULONGLONG     itemData;
+};
+
+struct packed_MEASUREITEMSTRUCT
+{
+    UINT          CtlType;
+    UINT          CtlID;
+    UINT          itemID;
+    UINT          itemWidth;
+    UINT          itemHeight;
+    ULONGLONG     itemData;
+};
+
+struct packed_DELETEITEMSTRUCT
+{
+    UINT          CtlType;
+    UINT          CtlID;
+    UINT          itemID;
+    user_handle_t hwndItem;
+    DWORD         __pad;
+    ULONGLONG     itemData;
+};
+
+struct packed_COMPAREITEMSTRUCT
+{
+    UINT          CtlType;
+    UINT          CtlID;
+    user_handle_t hwndItem;
+    DWORD         __pad1;
+    UINT          itemID1;
+    ULONGLONG     itemData1;
+    UINT          itemID2;
+    ULONGLONG     itemData2;
+    DWORD         dwLocaleId;
+    DWORD         __pad2;
+};
+
 /* the structures are unpacked on top of the packed ones, so make sure they fit */
 C_ASSERT( sizeof(struct packed_CREATESTRUCTW) >= sizeof(CREATESTRUCTW) );
+C_ASSERT( sizeof(struct packed_DRAWITEMSTRUCT) >= sizeof(DRAWITEMSTRUCT) );
+C_ASSERT( sizeof(struct packed_MEASUREITEMSTRUCT) >= sizeof(MEASUREITEMSTRUCT) );
+C_ASSERT( sizeof(struct packed_DELETEITEMSTRUCT) >= sizeof(DELETEITEMSTRUCT) );
+C_ASSERT( sizeof(struct packed_COMPAREITEMSTRUCT) >= sizeof(COMPAREITEMSTRUCT) );
 
 union packed_structs
 {
     struct packed_CREATESTRUCTW cs;
+    struct packed_DRAWITEMSTRUCT dis;
+    struct packed_MEASUREITEMSTRUCT mis;
+    struct packed_DELETEITEMSTRUCT dls;
+    struct packed_COMPAREITEMSTRUCT cis;
 };
 
 /* description of the data fields that need to be packed along with a sent message */
@@ -621,17 +678,57 @@ static size_t pack_message( HWND hwnd, UINT message, WPARAM wparam, LPARAM lpara
         push_data( data, (MINMAXINFO *)lparam, sizeof(MINMAXINFO) );
         return sizeof(MINMAXINFO);
     case WM_DRAWITEM:
-        push_data( data, (DRAWITEMSTRUCT *)lparam, sizeof(DRAWITEMSTRUCT) );
+    {
+        DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lparam;
+        data->ps.dis.CtlType    = dis->CtlType;
+        data->ps.dis.CtlID      = dis->CtlID;
+        data->ps.dis.itemID     = dis->itemID;
+        data->ps.dis.itemAction = dis->itemAction;
+        data->ps.dis.itemState  = dis->itemState;
+        data->ps.dis.hwndItem   = wine_server_user_handle( dis->hwndItem );
+        data->ps.dis.hDC        = wine_server_user_handle( dis->hDC );  /* FIXME */
+        data->ps.dis.rcItem     = dis->rcItem;
+        data->ps.dis.itemData   = dis->itemData;
+        push_data( data, &data->ps.dis, sizeof(data->ps.dis) );
         return 0;
+    }
     case WM_MEASUREITEM:
-        push_data( data, (MEASUREITEMSTRUCT *)lparam, sizeof(MEASUREITEMSTRUCT) );
-        return sizeof(MEASUREITEMSTRUCT);
+    {
+        MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lparam;
+        data->ps.mis.CtlType    = mis->CtlType;
+        data->ps.mis.CtlID      = mis->CtlID;
+        data->ps.mis.itemID     = mis->itemID;
+        data->ps.mis.itemWidth  = mis->itemWidth;
+        data->ps.mis.itemHeight = mis->itemHeight;
+        data->ps.mis.itemData   = mis->itemData;
+        push_data( data, &data->ps.mis, sizeof(data->ps.mis) );
+        return sizeof(data->ps.mis);
+    }
     case WM_DELETEITEM:
-        push_data( data, (DELETEITEMSTRUCT *)lparam, sizeof(DELETEITEMSTRUCT) );
+    {
+        DELETEITEMSTRUCT *dls = (DELETEITEMSTRUCT *)lparam;
+        data->ps.dls.CtlType    = dls->CtlType;
+        data->ps.dls.CtlID      = dls->CtlID;
+        data->ps.dls.itemID     = dls->itemID;
+        data->ps.dls.hwndItem   = wine_server_user_handle( dls->hwndItem );
+        data->ps.dls.itemData   = dls->itemData;
+        push_data( data, &data->ps.dls, sizeof(data->ps.dls) );
         return 0;
+    }
     case WM_COMPAREITEM:
-        push_data( data, (COMPAREITEMSTRUCT *)lparam, sizeof(COMPAREITEMSTRUCT) );
+    {
+        COMPAREITEMSTRUCT *cis = (COMPAREITEMSTRUCT *)lparam;
+        data->ps.cis.CtlType    = cis->CtlType;
+        data->ps.cis.CtlID      = cis->CtlID;
+        data->ps.cis.hwndItem   = wine_server_user_handle( cis->hwndItem );
+        data->ps.cis.itemID1    = cis->itemID1;
+        data->ps.cis.itemData1  = cis->itemData1;
+        data->ps.cis.itemID2    = cis->itemID2;
+        data->ps.cis.itemData2  = cis->itemData2;
+        data->ps.cis.dwLocaleId = cis->dwLocaleId;
+        push_data( data, &data->ps.cis, sizeof(data->ps.cis) );
         return 0;
+    }
     case WM_WINDOWPOSCHANGING:
     case WM_WINDOWPOSCHANGED:
         push_data( data, (WINDOWPOS *)lparam, sizeof(WINDOWPOS) );
@@ -885,17 +982,61 @@ static BOOL unpack_message( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lpa
         minsize = sizeof(MINMAXINFO);
         break;
     case WM_DRAWITEM:
-        minsize = sizeof(DRAWITEMSTRUCT);
+    {
+        DRAWITEMSTRUCT dis;
+        if (size < sizeof(ps->dis)) return FALSE;
+        dis.CtlType    = ps->dis.CtlType;
+        dis.CtlID      = ps->dis.CtlID;
+        dis.itemID     = ps->dis.itemID;
+        dis.itemAction = ps->dis.itemAction;
+        dis.itemState  = ps->dis.itemState;
+        dis.hwndItem   = wine_server_ptr_handle( ps->dis.hwndItem );
+        dis.hDC        = wine_server_ptr_handle( ps->dis.hDC );
+        dis.rcItem     = ps->dis.rcItem;
+        dis.itemData   = (ULONG_PTR)unpack_ptr( ps->dis.itemData );
+        memcpy( &ps->dis, &dis, sizeof(dis) );
         break;
+    }
     case WM_MEASUREITEM:
-        minsize = sizeof(MEASUREITEMSTRUCT);
+    {
+        MEASUREITEMSTRUCT mis;
+        if (size < sizeof(ps->mis)) return FALSE;
+        mis.CtlType    = ps->mis.CtlType;
+        mis.CtlID      = ps->mis.CtlID;
+        mis.itemID     = ps->mis.itemID;
+        mis.itemWidth  = ps->mis.itemWidth;
+        mis.itemHeight = ps->mis.itemHeight;
+        mis.itemData   = (ULONG_PTR)unpack_ptr( ps->mis.itemData );
+        memcpy( &ps->mis, &mis, sizeof(mis) );
         break;
+    }
     case WM_DELETEITEM:
-        minsize = sizeof(DELETEITEMSTRUCT);
+    {
+        DELETEITEMSTRUCT dls;
+        if (size < sizeof(ps->dls)) return FALSE;
+        dls.CtlType    = ps->dls.CtlType;
+        dls.CtlID      = ps->dls.CtlID;
+        dls.itemID     = ps->dls.itemID;
+        dls.hwndItem   = wine_server_ptr_handle( ps->dls.hwndItem );
+        dls.itemData   = (ULONG_PTR)unpack_ptr( ps->dls.itemData );
+        memcpy( &ps->dls, &dls, sizeof(dls) );
         break;
+    }
     case WM_COMPAREITEM:
-        minsize = sizeof(COMPAREITEMSTRUCT);
+    {
+        COMPAREITEMSTRUCT cis;
+        if (size < sizeof(ps->cis)) return FALSE;
+        cis.CtlType    = ps->cis.CtlType;
+        cis.CtlID      = ps->cis.CtlID;
+        cis.hwndItem   = wine_server_ptr_handle( ps->cis.hwndItem );
+        cis.itemID1    = ps->cis.itemID1;
+        cis.itemData1  = (ULONG_PTR)unpack_ptr( ps->cis.itemData1 );
+        cis.itemID2    = ps->cis.itemID2;
+        cis.itemData2  = (ULONG_PTR)unpack_ptr( ps->cis.itemData2 );
+        cis.dwLocaleId = ps->cis.dwLocaleId;
+        memcpy( &ps->cis, &cis, sizeof(cis) );
         break;
+    }
     case WM_WINDOWPOSCHANGING:
     case WM_WINDOWPOSCHANGED:
     case WM_WINE_SETWINDOWPOS:
@@ -1147,8 +1288,17 @@ static void pack_reply( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,
         push_data( data, (MINMAXINFO *)lparam, sizeof(MINMAXINFO) );
         break;
     case WM_MEASUREITEM:
-        push_data( data, (MEASUREITEMSTRUCT *)lparam, sizeof(MEASUREITEMSTRUCT) );
+    {
+        MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lparam;
+        data->ps.mis.CtlType    = mis->CtlType;
+        data->ps.mis.CtlID      = mis->CtlID;
+        data->ps.mis.itemID     = mis->itemID;
+        data->ps.mis.itemWidth  = mis->itemWidth;
+        data->ps.mis.itemHeight = mis->itemHeight;
+        data->ps.mis.itemData   = mis->itemData;
+        push_data( data, &data->ps.mis, sizeof(data->ps.mis) );
         break;
+    }
     case WM_WINDOWPOSCHANGING:
     case WM_WINDOWPOSCHANGED:
         push_data( data, (WINDOWPOS *)lparam, sizeof(WINDOWPOS) );
@@ -1245,7 +1395,16 @@ static void unpack_reply( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam,
         memcpy( (MINMAXINFO *)lparam, buffer, min( sizeof(MINMAXINFO), size ));
         break;
     case WM_MEASUREITEM:
-        memcpy( (MEASUREITEMSTRUCT *)lparam, buffer, min( sizeof(MEASUREITEMSTRUCT), size ));
+        if (size >= sizeof(ps->mis))
+        {
+            MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lparam;
+            mis->CtlType    = ps->mis.CtlType;
+            mis->CtlID      = ps->mis.CtlID;
+            mis->itemID     = ps->mis.itemID;
+            mis->itemWidth  = ps->mis.itemWidth;
+            mis->itemHeight = ps->mis.itemHeight;
+            mis->itemData   = (ULONG_PTR)unpack_ptr( ps->mis.itemData );
+        }
         break;
     case WM_WINDOWPOSCHANGING:
     case WM_WINDOWPOSCHANGED:




More information about the wine-cvs mailing list