2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS user32.dll
4 * PURPOSE: Dynamic Data Exchange
5 * FILE: win32ss/user/user32/misc/dde.c
11 WINE_DEFAULT_DEBUG_CHANNEL(ddeml
);
13 BOOL FASTCALL
DdeAddPair(HGLOBAL ClientMem
, HGLOBAL ServerMem
);
14 HGLOBAL FASTCALL
DdeGetPair(HGLOBAL ServerMem
);
17 /* description of the data fields that need to be packed along with a sent message */
20 //union packed_structs ps;
26 /* add a data field to a packed message */
27 static inline void push_data( struct packed_message
*data
, const void *ptr
, int size
)
34 /* pack a pointer into a 32/64 portable format */
35 static inline ULONGLONG
pack_ptr( const void *ptr
)
37 return (ULONG_PTR
)ptr
;
40 /* unpack a potentially 64-bit pointer, returning 0 when truncated */
41 static inline void *unpack_ptr( ULONGLONG ptr64
)
43 if ((ULONG_PTR
)ptr64
!= ptr64
) return 0;
44 return (void *)(ULONG_PTR
)ptr64
;
48 /***********************************************************************
53 BOOL
post_dde_message( struct packed_message
*data
, UINT message
, LPARAM lParam
, LPARAM
*lp
)
61 if (!UnpackDDElParam( message
, lParam
, &uiLo
, &uiHi
))
63 ERR("Unpack failed %x\n",message
);
70 /* DDE messages which don't require packing are:
79 /* uiHi should contain a hMem from WM_DDE_EXECUTE */
80 HGLOBAL h
= DdeGetPair( (HANDLE
)uiHi
);
83 hpack
= pack_ptr( h
);
84 /* send back the value of h on the other side */
85 push_data( data
, &hpack
, sizeof(hpack
) );
87 TRACE( "send dde-ack %lx %08lx => %p\n", uiLo
, uiHi
, h
);
92 /* uiHi should contain either an atom or 0 */
93 TRACE( "send dde-ack %lx atom=%lx\n", uiLo
, uiHi
);
94 *lp
= MAKELONG( uiLo
, uiHi
);
103 size
= GlobalSize( (HGLOBAL
)uiLo
) ;
104 TRACE("WM_DDE_A D P size %d\n",size
);
105 if ( (message
== WM_DDE_ADVISE
&& size
< sizeof(DDEADVISE
)) ||
106 (message
== WM_DDE_DATA
&& size
< FIELD_OFFSET(DDEDATA
, Value
)) ||
107 (message
== WM_DDE_POKE
&& size
< FIELD_OFFSET(DDEPOKE
, Value
)) )
110 else if (message
!= WM_DDE_DATA
)
112 TRACE("WM_DDE uiLo 0\n");
119 if ((ptr
= GlobalLock( (HGLOBAL
)uiLo
) ))
121 DDEDATA
*dde_data
= ptr
;
122 TRACE("unused %d, fResponse %d, fRelease %d, fDeferUpd %d, fAckReq %d, cfFormat %d\n",
123 dde_data
->unused
, dde_data
->fResponse
, dde_data
->fRelease
,
124 dde_data
->reserved
, dde_data
->fAckReq
, dde_data
->cfFormat
);
125 push_data( data
, ptr
, size
);
126 hunlock
= (HGLOBAL
)uiLo
;
129 TRACE( "send ddepack %u %lx\n", size
, uiHi
);
134 if ((ptr
= GlobalLock( (HGLOBAL
)lParam
) ))
136 size
= GlobalSize( (HGLOBAL
)lParam
);
137 push_data(data
, ptr
, size
);
138 /* so that the other side can send it back on ACK */
140 hunlock
= (HGLOBAL
)lParam
;
141 TRACE("WM_DDE_EXECUTE text size %d\n",GlobalSize( (HGLOBAL
)lParam
));
147 FreeDDElParam(message
, lParam
);
149 if (hunlock
) GlobalUnlock(hunlock
);
154 /***********************************************************************
157 * Unpack a posted DDE message received from another process.
159 BOOL
unpack_dde_message( HWND hwnd
, UINT message
, LPARAM
*lparam
, PVOID buffer
, int size
)
165 TRACE("udm : Size %d\n",size
);
173 /* hMem is being passed */
174 if (size
!= sizeof(hpack
)) return FALSE
;
175 if (!buffer
) return FALSE
;
177 memcpy( &hpack
, buffer
, size
);
178 hMem
= unpack_ptr( hpack
);
179 uiHi
= (UINT_PTR
)hMem
;
180 TRACE("recv dde-ack %lx mem=%lx[%lx]\n", uiLo
, uiHi
, GlobalSize( hMem
));
184 uiLo
= LOWORD( *lparam
);
185 uiHi
= HIWORD( *lparam
);
186 TRACE("recv dde-ack %lx atom=%lx\n", uiLo
, uiHi
);
188 *lparam
= PackDDElParam( WM_DDE_ACK
, uiLo
, uiHi
);
193 if ((!buffer
) && message
!= WM_DDE_DATA
) return FALSE
;
197 if (!(hMem
= GlobalAlloc( GMEM_MOVEABLE
|GMEM_DDESHARE
, size
)))
199 if ((ptr
= GlobalLock( hMem
)))
201 memcpy( ptr
, buffer
, size
);
202 GlobalUnlock( hMem
);
210 uiLo
= (UINT_PTR
)hMem
;
212 *lparam
= PackDDElParam( message
, uiLo
, uiHi
);
217 if (!buffer
) return FALSE
;
218 if (!(hMem
= GlobalAlloc( GMEM_MOVEABLE
|GMEM_DDESHARE
, size
))) return FALSE
;
219 if ((ptr
= GlobalLock( hMem
)))
221 memcpy( ptr
, buffer
, size
);
222 GlobalUnlock( hMem
);
223 TRACE( "exec: pairing c=%08lx s=%p\n", *lparam
, hMem
);
224 if (!DdeAddPair( (HGLOBAL
)*lparam
, hMem
))
227 TRACE("udm exec: GF 1\n");
234 TRACE("udm exec: GF 2\n");
240 TRACE("udm exec: No Size\n");
244 TRACE( "exec: exit c=%08lx s=%p\n", *lparam
, hMem
);
245 *lparam
= (LPARAM
)hMem
;
252 // DDE Post kernel callback.
256 User32CallDDEPostFromKernel(PVOID Arguments
, ULONG ArgumentLength
)
258 struct packed_message data
;
260 NTSTATUS Status
= STATUS_SUCCESS
;
261 PDDEPOSTGET_CALLBACK_ARGUMENTS Common
= Arguments
;
265 TRACE("DDE Post CB\n");
266 Ret
= post_dde_message( &data
, Common
->message
, Common
->lParam
, &Common
->lParam
);
270 Common
->pvData
= (PVOID
)data
.data
;
271 Common
->size
= data
.size
;
272 TRACE("DDE Post CB size %d\n",data
.size
);
276 ERR("DDE Post CB Return bad msg 0x%x Size %d\n",Common
->message
,Common
->size
);
277 Status
= STATUS_UNSUCCESSFUL
;
280 return ZwCallbackReturn(Arguments
, ArgumentLength
, Status
);
284 // DDE Get/Peek kernel callback.
288 User32CallDDEGetFromKernel(PVOID Arguments
, ULONG ArgumentLength
)
291 NTSTATUS Status
= STATUS_SUCCESS
;
292 PDDEPOSTGET_CALLBACK_ARGUMENTS Common
= Arguments
;
294 TRACE("DDE Get CB size %d\n",Common
->size
);
296 Ret
= unpack_dde_message( Common
->hwnd
, Common
->message
, &Common
->lParam
, Common
->buffer
, Common
->size
);
300 ERR("DDE Get CB Return bad msg 0x%x\n",Common
->message
);
301 Status
= STATUS_UNSUCCESSFUL
;
303 return ZwCallbackReturn(Arguments
, ArgumentLength
, Status
);
310 BOOL WINAPI
DdeGetQualityOfService(HWND hWnd
, DWORD Reserved
, PSECURITY_QUALITY_OF_SERVICE pqosPrev
)