ReactOS  0.4.13-dev-464-g6b95727
dde.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Win32k subsystem
4  * PURPOSE: Dynamic Data Exchange
5  * FILE: win32ss/user/ntuser/dde.c
6  * PROGRAMER:
7  */
8 
9 #include <win32k.h>
10 
11 #include <dde.h>
12 
13 DBG_DEFAULT_CHANNEL(UserMisc);
14 
15 //
16 // Default information used to support client impersonation.
17 //
19 
20 typedef struct _DDEIMP
21 {
26 } DDEIMP, *PDDEIMP;
27 
28 typedef struct _DDE_DATA
29 {
31  int cbSize;
34 
35 typedef struct _DDE_PROP
36 {
41 
42 
43 //
44 // DDE Posting message callback to user side.
45 //
46 int
49  IN PWND pWnd,
50  IN UINT Msg,
53  IN OUT PVOID *Buffer)
54 {
56  ULONG ArgumentLength, ResultLength;
57  PVOID Argument, ResultPointer;
59  int size = 0;
60  ResultPointer = NULL;
61  ResultLength = ArgumentLength = sizeof(DDEPOSTGET_CALLBACK_ARGUMENTS);
62 
63  Argument = IntCbAllocateMemory(ArgumentLength);
64  if (NULL == Argument)
65  {
66  return FALSE;
67  }
68 
69  Common = (PDDEPOSTGET_CALLBACK_ARGUMENTS) Argument;
70 
71  Common->pvData = 0;
72  Common->size = 0;
73  Common->hwnd = UserHMGetHandle(pWnd);
74  Common->message = Msg;
75  Common->wParam = wParam;
76  Common->lParam = *lParam;
77 
78  UserLeaveCo();
79 
81  Argument,
82  ArgumentLength,
83  &ResultPointer,
84  &ResultLength);
85 
86  UserEnterCo();
87 
88  if (!NT_SUCCESS(Status) || ResultPointer == NULL )
89  {
90  ERR("DDE Post callback failed!\n");
91  IntCbFreeMemory(Argument);
92  return 0;
93  }
94 
95  RtlCopyMemory(Common, ResultPointer, ArgumentLength);
96 
97  size = Common->size;
98  *lParam = Common->lParam;
99  *Buffer = Common->pvData;
100 
101  IntCbFreeMemory(Argument);
102 
103  return size ? size : -1;
104 }
105 
106 //
107 // DDE Get/Peek message callback to user side.
108 //
109 BOOL
110 APIENTRY
112  IN PWND pWnd,
113  IN OUT PMSG pMsg,
114  IN PVOID Buffer,
115  IN int size)
116 {
118  ULONG ArgumentLength, ResultLength;
119  PVOID Argument, ResultPointer;
121 
122  ResultPointer = NULL;
123  ResultLength = ArgumentLength = sizeof(DDEPOSTGET_CALLBACK_ARGUMENTS)+size;
124 
125  Argument = IntCbAllocateMemory(ArgumentLength);
126  if (NULL == Argument)
127  {
128  return FALSE;
129  }
130 
131  Common = (PDDEPOSTGET_CALLBACK_ARGUMENTS) Argument;
132 
133  Common->size = size;
134  Common->hwnd = pMsg->hwnd;
135  Common->message = pMsg->message;
136  Common->wParam = pMsg->wParam;
137  Common->lParam = pMsg->lParam;
138 
139  if (size && Buffer) RtlCopyMemory(&Common->buffer, Buffer, size);
140 
141  UserLeaveCo();
142 
144  Argument,
145  ArgumentLength,
146  &ResultPointer,
147  &ResultLength);
148 
149  UserEnterCo();
150 
151  if (!NT_SUCCESS(Status) || ResultPointer == NULL )
152  {
153  ERR("DDE Get callback failed!\n");
154  IntCbFreeMemory(Argument);
155  return FALSE;
156  }
157 
158  RtlMoveMemory(Common, ResultPointer, ArgumentLength);
159 
160  pMsg->lParam = Common->lParam;
161 
162  IntCbFreeMemory(Argument);
163 
164  return TRUE;
165 }
166 
167 //
168 // DDE Post message hook, intercept DDE messages before going on to the target Processes Thread queue.
169 //
170 BOOL
171 APIENTRY
173  IN PWND pWnd,
174  IN UINT Msg,
175  IN WPARAM wParam,
176  IN OUT LPARAM *lParam,
177  IN OUT LONG_PTR *ExtraInfo)
178 {
179  PWND pWndClient;
180  PDDE_DATA pddeData;
181  int size;
182  HGDIOBJ Object = NULL;
183  PVOID userBuf = NULL;
184  PVOID Buffer = NULL;
185  LPARAM lp = *lParam;
186 
187  if (pWnd->head.pti->ppi != gptiCurrent->ppi)
188  {
189  TRACE("Posting long DDE 0x%x\n",Msg);
190  // Initiate is sent only across borders.
191  if (Msg == WM_DDE_INITIATE)
192  {
193  return FALSE;
194  }
195 
196  pWndClient = UserGetWindowObject((HWND)wParam);
197  if (pWndClient == NULL)
198  {
199  // This is terminating so post it.
200  if ( Msg == WM_DDE_TERMINATE)
201  {
202  TRACE("DDE Posted WM_DDE_TERMINATE\n");
203  return TRUE;
204  }
205  TRACE("Invalid DDE Client Window handle\n");
206  return FALSE;
207  }
208 
209  if ( Msg == WM_DDE_REQUEST || Msg == WM_DDE_UNADVISE )
210  {
211  // Do not bother to callback after validation.
212  return TRUE;
213  }
214 
215  if ( Msg == WM_DDE_TERMINATE )
216  {
218 
219  // Do not bother to callback.
220  return TRUE;
221  }
222 
223  if ( Msg == WM_DDE_EXECUTE && *lParam == 0)
224  {
225  // Do not bother to do a callback.
226  TRACE("DDE Post EXECUTE lParam 0\n");
227  return FALSE;
228  }
229 
230  // Callback.
231  if ((size = IntDDEPostCallback(pWnd, Msg, wParam, &lp, &userBuf)) == 0)
232  {
233  ERR("DDE Post Callback return 0 0x%x\n", Msg);
234  return FALSE;
235  }
236 
237  // No error HACK.
238  if (size == -1)
239  {
240  size = 0;
241  }
242  else
243  {
244  // Set buffer with users data size.
246  if (Buffer == NULL)
247  {
248  ERR("Failed to allocate %i bytes.\n", size);
249  return FALSE;
250  }
251  // No SEH? Yes, the user memory is freed after the Acknowledgment or at Termination.
252  RtlCopyMemory(Buffer, userBuf, size);
253  }
254 
255  TRACE("DDE Post size %d 0x%x\n",size, Msg);
256 
257  switch(Msg)
258  {
259  case WM_DDE_POKE:
260  {
261  DDEPOKE *pddePoke = Buffer;
262  NT_ASSERT(pddePoke != NULL);
263  switch(pddePoke->cfFormat)
264  {
265  case CF_BITMAP:
266  case CF_DIB:
267  case CF_PALETTE:
268  RtlCopyMemory(&Object, pddePoke->Value, sizeof(HGDIOBJ));
269  break;
270  default:
271  break;
272  }
273  break;
274  }
275  case WM_DDE_DATA:
276  {
277  DDEDATA *pddeData2 = Buffer;
278  NT_ASSERT(pddeData2 != NULL);
279  switch(pddeData2->cfFormat)
280  {
281  case CF_BITMAP:
282  case CF_DIB:
283  case CF_PALETTE:
284  RtlCopyMemory(&Object, pddeData2->Value, sizeof(HGDIOBJ));
285  break;
286  default:
287  break;
288  }
289  break;
290  }
291  default:
292  break;
293  }
294 
295  if (Object)
296  {
297  // Give gdi object to the other process.
298  GreSetObjectOwner(Object, pWnd->head.pti->ppi->W32Pid);
299  }
300 
302  if (pddeData == NULL)
303  {
304  ERR("Failed to allocate DDE_DATA\n");
306  return FALSE;
307  }
308 
309  pddeData->cbSize = size;
310  pddeData->pvBuffer = Buffer;
311  pddeData->lParam = lp;
312 
313  TRACE("DDE Post lParam c=%08lx\n",lp);
314  *lParam = lp;
315 
316  // Attach this data packet to the user message.
317  *ExtraInfo = (LONG_PTR)pddeData;
318  }
319  return TRUE;
320 }
321 
322 //
323 // DDE Get/Peek message hook, take preprocessed information and recombined it for the current Process Thread.
324 //
327 {
328  PWND pWnd, pWndClient;
329  PDDE_DATA pddeData;
330  PDDE_PROP pddeProp;
331  BOOL Ret;
332 
333  pWnd = UserGetWindowObject(pMsg->hwnd);
334  if (pWnd == NULL)
335  {
336  ERR("DDE Get Window is dead. %p\n", pMsg->hwnd);
337  return TRUE;
338  }
339 
340  if (pMsg->message == WM_DDE_TERMINATE)
341  {
342  pddeProp = (PDDE_PROP)UserGetProp(pWnd, AtomDDETrack, TRUE);
343  if (pddeProp)
344  {
345  pWndClient = UserGetWindowObject((HWND)pMsg->wParam);
346  if (pWndClient == NULL)
347  {
348  ERR("DDE Get Client WM_DDE_TERMINATE\n");
349  }
350 
352  ExFreePoolWithTag(pddeProp, USERTAG_DDE1);
353  }
354  return TRUE;
355  }
356 
357  TRACE("DDE Get Msg 0x%x\n",pMsg->message);
358 
359  pddeData = (PDDE_DATA)ExtraInfo;
360 
361  if ( pddeData )
362  {
363  TRACE("DDE Get size %d lParam c=%08lx lp c=%08lx\n",pddeData->cbSize, pMsg->lParam, pddeData->lParam);
364 
365  // Callback.
366  Ret = IntDDEGetCallback( pWnd, pMsg, pddeData->pvBuffer, pddeData->cbSize);
367  if (!Ret)
368  {
369  ERR("DDE Get CB failed\n");
370  }
371 
372  if (pddeData->pvBuffer) ExFreePoolWithTag(pddeData->pvBuffer, USERTAG_DDE);
373 
374  ExFreePoolWithTag(pddeData, USERTAG_DDE5);
375 
376  return Ret;
377  }
378  TRACE("DDE Get No DDE Data found!\n");
379  return TRUE;
380 }
381 
382 //
383 // DDE Send message hook, intercept DDE messages and associate them in a partnership with property.
384 //
387 {
388  PWND pWndServer;
389  PDDE_PROP pddeProp;
390 
391  if (pWnd->head.pti->ppi != gptiCurrent->ppi)
392  {
393  TRACE("Sending long DDE 0x%x\n",Msg);
394 
395  // Allow only Acknowledge and Initiate to be sent across borders.
396  if (Msg != WM_DDE_ACK )
397  {
398  if (Msg == WM_DDE_INITIATE) return TRUE;
399  return FALSE;
400  }
401 
402  TRACE("Sending long WM_DDE_ACK\n");
403 
404  pWndServer = UserGetWindowObject((HWND)wParam);
405  if (pWndServer == NULL)
406  {
407  ERR("Invalid DDE Server Window handle\n");
408  return FALSE;
409  }
410 
411  // Setup property so this conversation can be tracked.
413  if (pddeProp == NULL)
414  {
415  ERR("failed to allocate DDE_PROP\n");
416  return FALSE;
417  }
418 
419  pddeProp->spwnd = pWndServer;
420  pddeProp->spwndPartner = pWnd;
421 
422  UserSetProp(pWndServer, AtomDDETrack, (HANDLE)pddeProp, TRUE);
423  }
424  return TRUE;
425 }
426 
427 
428 BOOL
429 APIENTRY
431  IN HWND hwndClient,
432  IN HWND hWndServer,
434 {
435  STUB
436 
437  return 0;
438 }
439 
440 BOOL
441 APIENTRY
443  IN HWND hwndClient,
446 {
447  STUB
448 
449  return 0;
450 }
451 
452 BOOL
453 APIENTRY
455  HWND hWndClient,
456  HWND hWndServer)
457 {
458  STUB
459 
460  return 0;
461 }
462 
463 DWORD
464 APIENTRY
466  DWORD Unknown0,
467  DWORD Unknown1,
468  DWORD Unknown2,
469  DWORD Unknown3,
470  DWORD Unknown4)
471 {
472  STUB
473 
474  return 0;
475 }
476 
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
NTSTATUS NTAPI KeUserModeCallback(IN ULONG RoutineIndex, IN PVOID Argument, IN ULONG ArgumentLength, OUT PVOID *Result, OUT PULONG ResultLength)
Definition: stubs.c:100
struct _DDE_DATA * PDDE_DATA
#define IN
Definition: typedefs.h:38
#define LONG_PTR
Definition: treelist.c:79
BOOL NTAPI GreSetObjectOwner(HGDIOBJ hobj, ULONG ulOwner)
Definition: gdiobj.c:1252
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD Unknown3
Definition: conport.c:35
#define WM_DDE_UNADVISE
Definition: dde.h:40
VOID FASTCALL IntCbFreeMemory(PVOID Data)
Definition: callback.c:49
PVOID pvBuffer
Definition: dde.c:32
SECURITY_QUALITY_OF_SERVICE qos
Definition: dde.c:22
#define USERTAG_DDE
Definition: tags.h:222
Definition: dde.h:71
SECURITY_CLIENT_CONTEXT ClientContext
Definition: dde.c:23
LONG NTSTATUS
Definition: precomp.h:26
WPARAM wParam
Definition: winuser.h:3069
BOOL APIENTRY IntDdePostMessageHook(IN PWND pWnd, IN UINT Msg, IN WPARAM wParam, IN OUT LPARAM *lParam, IN OUT LONG_PTR *ExtraInfo)
Definition: dde.c:172
UINT_PTR WPARAM
Definition: windef.h:207
#define USERTAG_DDE1
Definition: tags.h:210
int APIENTRY IntDDEPostCallback(IN PWND pWnd, IN UINT Msg, IN WPARAM wParam, IN OUT LPARAM *lParam, IN OUT PVOID *Buffer)
Definition: dde.c:48
short cfFormat
Definition: dde.h:59
PDDEIMP pddei
Definition: dde.c:39
#define WM_DDE_REQUEST
Definition: dde.h:43
#define FASTCALL
Definition: nt_native.h:50
#define USER32_CALLBACK_DDEGET
Definition: callback.h:18
BOOL APIENTRY NtUserDdeSetQualityOfService(IN HWND hwndClient, IN PSECURITY_QUALITY_OF_SERVICE pqosNew, OUT PSECURITY_QUALITY_OF_SERVICE pqosPrev)
Definition: dde.c:442
WPARAM wParam
Definition: combotst.c:138
short cfFormat
Definition: dde.h:74
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define USERTAG_DDE5
Definition: tags.h:213
struct @1571 Msg[]
PPROCESSINFO ppi
Definition: win32.h:87
LPARAM lParam
Definition: dde.c:30
BOOL APIENTRY NtUserDdeGetQualityOfService(IN HWND hwndClient, IN HWND hWndServer, OUT PSECURITY_QUALITY_OF_SERVICE pqosPrev)
Definition: dde.c:430
WORD cRefInit
Definition: dde.c:24
unsigned int BOOL
Definition: ntddk_ex.h:94
#define WM_DDE_TERMINATE
Definition: dde.h:38
PRTL_UNICODE_STRING_BUFFER PULONG PULONG Unknown4
#define WM_DDE_DATA
Definition: dde.h:42
#define UserLeaveCo
Definition: ntuser.h:10
THRDESKHEAD head
Definition: ntuser.h:659
#define CF_BITMAP
Definition: constants.h:397
struct _DDEIMP DDEIMP
smooth NULL
Definition: ftsmooth.c:416
WORD cRefConv
Definition: dde.c:25
LPARAM lParam
Definition: winuser.h:3070
LONG_PTR LPARAM
Definition: windef.h:208
Definition: bufpool.h:45
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:103
BYTE Value[1]
Definition: dde.h:75
Definition: dde.c:20
PVOID FASTCALL IntCbAllocateMemory(ULONG Size)
Definition: callback.c:27
Definition: dde.h:56
#define UserHMGetHandle(obj)
Definition: ntuser.h:208
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
struct _DDE_PROP * PDDE_PROP
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DWORD APIENTRY NtUserDdeInitialize(DWORD Unknown0, DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
Definition: dde.c:465
HANDLE FASTCALL UserGetProp(_In_ PWND Window, _In_ ATOM Atom, _In_ BOOLEAN SystemProp)
Definition: prop.c:46
Definition: dde.c:35
unsigned short WORD
Definition: ntddk_ex.h:93
BOOL APIENTRY IntDdeGetMessageHook(PMSG pMsg, LONG_PTR ExtraInfo)
Definition: dde.c:326
unsigned long DWORD
Definition: ntddk_ex.h:95
#define UserEnterCo
Definition: ntuser.h:9
struct _DDEPOSTGET_CALLBACK_ARGUMENTS * PDDEPOSTGET_CALLBACK_ARGUMENTS
ATOM AtomDDETrack
Definition: ntuser.c:23
static IUnknown Object
Definition: main.c:512
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
SECURITY_QUALITY_OF_SERVICE gqosDefault
Definition: dde.c:18
DBG_DEFAULT_CHANNEL(UserMisc)
#define WM_DDE_POKE
Definition: dde.h:44
#define USER32_CALLBACK_DDEPOST
Definition: callback.h:17
BOOL APIENTRY IntDDEGetCallback(IN PWND pWnd, IN OUT PMSG pMsg, IN PVOID Buffer, IN int size)
Definition: dde.c:111
BOOL APIENTRY NtUserImpersonateDdeClientWindow(HWND hWndClient, HWND hWndServer)
Definition: dde.c:454
#define CF_PALETTE
Definition: constants.h:404
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
Definition: ntuser.h:657
BOOL FASTCALL IntDdeSendMessageHook(PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: dde.c:386
struct _DDEPOSTGET_CALLBACK_ARGUMENTS DDEPOSTGET_CALLBACK_ARGUMENTS
struct _DDE_PROP DDE_PROP
#define STUB
Definition: kernel32.h:27
Definition: dde.c:28
#define SECURITY_STATIC_TRACKING
Definition: setypes.h:104
struct _SECURITY_QUALITY_OF_SERVICE SECURITY_QUALITY_OF_SERVICE
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
struct _DDE_DATA DDE_DATA
unsigned int UINT
Definition: ndis.h:50
HWND hwnd
Definition: winuser.h:3067
#define WM_DDE_INITIATE
Definition: dde.h:37
#define OUT
Definition: typedefs.h:39
#define WM_DDE_ACK
Definition: dde.h:41
unsigned int ULONG
Definition: retypes.h:1
PWND spwndPartner
Definition: dde.c:38
int cbSize
Definition: dde.c:31
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PWND spwnd
Definition: dde.c:37
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
struct _DDEIMP * PDDEIMP
UINT message
Definition: winuser.h:3068
HANDLE FASTCALL UserRemoveProp(_In_ PWND Window, _In_ ATOM Atom, _In_ BOOLEAN SystemProp)
#define WM_DDE_EXECUTE
Definition: dde.h:45
LPARAM lParam
Definition: combotst.c:139
#define APIENTRY
Definition: api.h:79
#define NT_ASSERT
Definition: rtlfuncs.h:3312
BYTE Value[1]
Definition: dde.h:60
#define CF_DIB
Definition: constants.h:403