ReactOS  0.4.14-dev-115-g4576127
dde.c
Go to the documentation of this file.
1 /*
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
6  * PROGRAMER:
7  */
8 
9 #include <user32.h>
10 
12 
13 BOOL FASTCALL DdeAddPair(HGLOBAL ClientMem, HGLOBAL ServerMem);
15 
16 
17 /* description of the data fields that need to be packed along with a sent message */
19 {
20  //union packed_structs ps;
21  int count;
22  const void *data;
23  int size;
24 };
25 
26 /* add a data field to a packed message */
27 static inline void push_data( struct packed_message *data, const void *ptr, int size )
28 {
29  data->data = ptr;
30  data->size = size;
31  data->count++;
32 }
33 
34 /* pack a pointer into a 32/64 portable format */
35 static inline ULONGLONG pack_ptr( const void *ptr )
36 {
37  return (ULONG_PTR)ptr;
38 }
39 
40 /* unpack a potentially 64-bit pointer, returning 0 when truncated */
41 static inline void *unpack_ptr( ULONGLONG ptr64 )
42 {
43  if ((ULONG_PTR)ptr64 != ptr64) return 0;
44  return (void *)(ULONG_PTR)ptr64;
45 }
46 
47 
48 /***********************************************************************
49  * post_dde_message
50  *
51  * Post a DDE message
52  */
54 {
55  void* ptr = NULL;
56  int size = 0;
57  UINT_PTR uiLo, uiHi;
58  HGLOBAL hunlock = 0;
59  ULONGLONG hpack;
60 
61  if (!UnpackDDElParam( message, lParam, &uiLo, &uiHi ))
62  {
63  ERR("Unpack failed %x\n",message);
64  return FALSE;
65  }
66 
67  *lp = lParam;
68  switch (message)
69  {
70  /* DDE messages which don't require packing are:
71  * WM_DDE_INITIATE
72  * WM_DDE_TERMINATE
73  * WM_DDE_REQUEST
74  * WM_DDE_UNADVISE
75  */
76  case WM_DDE_ACK:
77  if (HIWORD(uiHi))
78  {
79  /* uiHi should contain a hMem from WM_DDE_EXECUTE */
80  HGLOBAL h = DdeGetPair( (HANDLE)uiHi );
81  if (h)
82  {
83  hpack = pack_ptr( h );
84  /* send back the value of h on the other side */
85  push_data( data, &hpack, sizeof(hpack) );
86  *lp = uiLo;
87  TRACE( "send dde-ack %lx %08lx => %p\n", uiLo, uiHi, h );
88  }
89  }
90  else
91  {
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 );
95  }
96  break;
97  case WM_DDE_ADVISE:
98  case WM_DDE_DATA:
99  case WM_DDE_POKE:
100  size = 0;
101  if (uiLo)
102  {
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)) ||
108  return FALSE;
109  }
110  else if (message != WM_DDE_DATA)
111  {
112  TRACE("WM_DDE uiLo 0\n");
113  return FALSE;
114  }
115 
116  *lp = uiHi;
117  if (uiLo)
118  {
119  if ((ptr = GlobalLock( (HGLOBAL)uiLo) ))
120  {
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;
127  }
128  }
129  TRACE( "send ddepack %u %lx\n", size, uiHi );
130  break;
131  case WM_DDE_EXECUTE:
132  if (lParam)
133  {
134  if ((ptr = GlobalLock( (HGLOBAL)lParam) ))
135  {
137  push_data(data, ptr, size);
138  /* so that the other side can send it back on ACK */
139  *lp = lParam;
140  hunlock = (HGLOBAL)lParam;
141  TRACE("WM_DDE_EXECUTE text size %d\n",GlobalSize( (HGLOBAL)lParam ));
142  }
143  }
144  break;
145  }
146 
148 
149  if (hunlock) GlobalUnlock(hunlock);
150 
151  return TRUE;
152 }
153 
154 /***********************************************************************
155  * unpack_dde_message
156  *
157  * Unpack a posted DDE message received from another process.
158  */
160 {
161  UINT_PTR uiLo, uiHi;
162  HGLOBAL hMem = 0;
163  void* ptr;
164 
165  TRACE("udm : Size %d\n",size);
166 
167  switch (message)
168  {
169  case WM_DDE_ACK:
170  if (size)
171  {
172  ULONGLONG hpack;
173  /* hMem is being passed */
174  if (size != sizeof(hpack)) return FALSE;
175  if (!buffer) return FALSE;
176  uiLo = *lparam;
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 ));
181  }
182  else
183  {
184  uiLo = LOWORD( *lparam );
185  uiHi = HIWORD( *lparam );
186  TRACE("recv dde-ack %lx atom=%lx\n", uiLo, uiHi);
187  }
188  *lparam = PackDDElParam( WM_DDE_ACK, uiLo, uiHi );
189  break;
190  case WM_DDE_ADVISE:
191  case WM_DDE_DATA:
192  case WM_DDE_POKE:
193  if ((!buffer) && message != WM_DDE_DATA) return FALSE;
194  uiHi = *lparam;
195  if (size)
196  {
197  if (!(hMem = GlobalAlloc( GMEM_MOVEABLE|GMEM_DDESHARE, size )))
198  return FALSE;
199  if ((ptr = GlobalLock( hMem )))
200  {
201  memcpy( ptr, buffer, size );
202  GlobalUnlock( hMem );
203  }
204  else
205  {
206  GlobalFree( hMem );
207  return FALSE;
208  }
209  }
210  uiLo = (UINT_PTR)hMem;
211 
212  *lparam = PackDDElParam( message, uiLo, uiHi );
213  break;
214  case WM_DDE_EXECUTE:
215  if (size)
216  {
217  if (!buffer) return FALSE;
218  if (!(hMem = GlobalAlloc( GMEM_MOVEABLE|GMEM_DDESHARE, size ))) return FALSE;
219  if ((ptr = GlobalLock( hMem )))
220  {
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 ))
225  {
226  GlobalFree( hMem );
227  TRACE("udm exec: GF 1\n");
228  return FALSE;
229  }
230  }
231  else
232  {
233  GlobalFree( hMem );
234  TRACE("udm exec: GF 2\n");
235  return FALSE;
236  }
237  }
238  else
239  {
240  TRACE("udm exec: No Size\n");
241  return FALSE;
242  }
243 
244  TRACE( "exec: exit c=%08lx s=%p\n", *lparam, hMem );
245  *lparam = (LPARAM)hMem;
246  break;
247  }
248  return TRUE;
249 }
250 
251 //
252 // DDE Post kernel callback.
253 //
254 NTSTATUS
255 WINAPI
256 User32CallDDEPostFromKernel(PVOID Arguments, ULONG ArgumentLength)
257 {
258  struct packed_message data;
259  BOOL Ret;
261  PDDEPOSTGET_CALLBACK_ARGUMENTS Common = Arguments;
262 
263  data.data = 0;
264  data.size = 0;
265  TRACE("DDE Post CB\n");
266  Ret = post_dde_message( &data, Common->message, Common->lParam, &Common->lParam);
267 
268  if (Ret)
269  {
270  Common->pvData = (PVOID)data.data;
271  Common->size = data.size;
272  TRACE("DDE Post CB size %d\n",data.size);
273  }
274  else
275  {
276  ERR("DDE Post CB Return bad msg 0x%x Size %d\n",Common->message,Common->size);
278  }
279 
280  return ZwCallbackReturn(Arguments, ArgumentLength, Status);
281 }
282 
283 //
284 // DDE Get/Peek kernel callback.
285 //
286 NTSTATUS
287 WINAPI
288 User32CallDDEGetFromKernel(PVOID Arguments, ULONG ArgumentLength)
289 {
290  BOOL Ret;
292  PDDEPOSTGET_CALLBACK_ARGUMENTS Common = Arguments;
293 
294  TRACE("DDE Get CB size %d\n",Common->size);
295 
296  Ret = unpack_dde_message( Common->hwnd, Common->message, &Common->lParam, Common->buffer, Common->size );
297 
298  if (!Ret)
299  {
300  ERR("DDE Get CB Return bad msg 0x%x\n",Common->message);
302  }
303  return ZwCallbackReturn(Arguments, ArgumentLength, Status);
304 }
305 
306 
307 /*
308  * @unimplemented
309  */
311 {
313  return FALSE;
314 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
unsigned short reserved
Definition: dde.h:58
unsigned __int3264 UINT_PTR
Definition: activex.cpp:275
HANDLE HGLOBAL
Definition: windef.h:243
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
Definition: tftpd.h:59
#define TRUE
Definition: types.h:120
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
static ULONGLONG pack_ptr(const void *ptr)
Definition: dde.c:35
unsigned short fRelease
Definition: dde.h:58
static void * unpack_ptr(ULONGLONG ptr64)
Definition: dde.c:41
Definition: dde.h:71
LONG NTSTATUS
Definition: precomp.h:26
BOOL post_dde_message(struct packed_message *data, UINT message, LPARAM lParam, LPARAM *lp)
Definition: dde.c:53
HWND hWnd
Definition: settings.c:17
Definition: dde.h:64
GLuint buffer
Definition: glext.h:5915
LPARAM WINAPI PackDDElParam(UINT, UINT_PTR, UINT_PTR)
Definition: ddemisc.c:63
short cfFormat
Definition: dde.h:59
static void push_data(struct packed_message *data, const void *ptr, int size)
Definition: dde.c:27
unsigned short fAckReq
Definition: dde.h:58
#define FASTCALL
Definition: nt_native.h:50
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSYSAPI NTSTATUS NTAPI ZwCallbackReturn(_In_ PVOID Result, _In_ ULONG ResultLength, _In_ NTSTATUS Status)
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
unsigned int BOOL
Definition: ntddk_ex.h:94
#define WM_DDE_DATA
Definition: dde.h:42
static UINT WPARAM LPARAM lparam
Definition: combo.c:716
static PVOID ptr
Definition: dispmode.c:27
#define MAKELONG(a, b)
Definition: typedefs.h:248
smooth NULL
Definition: ftsmooth.c:416
HGLOBAL FASTCALL DdeGetPair(HGLOBAL ServerMem)
Definition: message.c:230
LONG_PTR LPARAM
Definition: windef.h:208
int size
Definition: dde.c:23
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
NTSTATUS WINAPI User32CallDDEPostFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: dde.c:256
void * PVOID
Definition: retypes.h:9
Definition: dde.h:56
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
uint64_t ULONGLONG
Definition: typedefs.h:65
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define WM_DDE_POKE
Definition: dde.h:44
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
BOOL WINAPI FreeDDElParam(UINT, LPARAM)
Definition: ddemisc.c:147
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Status
Definition: gdiplustypes.h:24
BOOL WINAPI UnpackDDElParam(UINT, LPARAM, PUINT_PTR, PUINT_PTR)
Definition: ddemisc.c:105
#define ERR(fmt,...)
Definition: debug.h:109
WINE_DEFAULT_DEBUG_CHANNEL(ddeml)
const void * data
Definition: dde.c:22
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int UINT
Definition: ndis.h:50
unsigned short unused
Definition: dde.h:58
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
#define GMEM_DDESHARE
Definition: winbase.h:295
int count
Definition: dde.c:21
BOOL FASTCALL DdeAddPair(HGLOBAL ClientMem, HGLOBAL ServerMem)
Definition: message.c:180
#define WM_DDE_ACK
Definition: dde.h:41
#define HIWORD(l)
Definition: typedefs.h:246
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
#define ULONG_PTR
Definition: config.h:101
unsigned short fResponse
Definition: dde.h:58
#define WM_DDE_ADVISE
Definition: dde.h:39
BOOL WINAPI DdeGetQualityOfService(HWND hWnd, DWORD Reserved, PSECURITY_QUALITY_OF_SERVICE pqosPrev)
Definition: dde.c:310
NTSTATUS WINAPI User32CallDDEGetFromKernel(PVOID Arguments, ULONG ArgumentLength)
Definition: dde.c:288
BOOL unpack_dde_message(HWND hwnd, UINT message, LPARAM *lparam, PVOID buffer, int size)
Definition: dde.c:159
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define WM_DDE_EXECUTE
Definition: dde.h:45
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
#define GMEM_MOVEABLE
Definition: winbase.h:291