ReactOS 0.4.15-dev-7924-g5949c20
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
14
15//
16// Default information used to support client impersonation.
17//
19
20typedef struct _DDEIMP
21{
27
28typedef struct _DDE_DATA
29{
31 int cbSize;
34
35typedef struct _DDE_PROP
36{
41
42
43//
44// DDE Posting message callback to user side.
45//
46int
49 IN PWND pWnd,
50 IN UINT Msg,
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
79
80 Status = KeUserModeCallback(USER32_CALLBACK_DDEPOST,
81 Argument,
82 ArgumentLength,
83 &ResultPointer,
85
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//
109BOOL
112 IN PWND pWnd,
113 IN OUT PMSG pMsg,
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
143 Status = KeUserModeCallback(USER32_CALLBACK_DDEGET,
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//
170BOOL
173 IN PWND pWnd,
174 IN UINT Msg,
177 IN OUT LONG_PTR *ExtraInfo)
178{
179 PWND pWndClient;
180 PDDE_DATA pddeData;
181 int size;
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
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
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
428BOOL
431 IN HWND hwndClient,
432 IN HWND hWndServer,
434{
435 STUB
436
437 return 0;
438}
439
440BOOL
443 IN HWND hwndClient,
446{
447 STUB
448
449 return 0;
450}
451
452BOOL
455 HWND hWndClient,
456 HWND hWndServer)
457{
458 STUB
459
460 return 0;
461}
462
463DWORD
466 DWORD Unknown0,
467 DWORD Unknown1,
468 DWORD Unknown2,
471{
472 STUB
473
474 return 0;
475}
476
PRTL_UNICODE_STRING_BUFFER PULONG PULONG Unknown4
NTSTATUS NTAPI KeUserModeCallback(IN ULONG RoutineIndex, IN PVOID Argument, IN ULONG ArgumentLength, OUT PVOID *Result, OUT PULONG ResultLength)
Definition: usercall.c:229
LONG NTSTATUS
Definition: precomp.h:26
#define CF_BITMAP
Definition: constants.h:397
#define CF_PALETTE
Definition: constants.h:404
#define CF_DIB
Definition: constants.h:403
#define ERR(fmt,...)
Definition: debug.h:110
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:103
Definition: bufpool.h:45
struct @1632 Msg[]
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD Unknown3
Definition: conport.c:37
#define WM_DDE_REQUEST
Definition: dde.h:43
#define WM_DDE_DATA
Definition: dde.h:42
#define WM_DDE_POKE
Definition: dde.h:44
#define WM_DDE_ACK
Definition: dde.h:41
#define WM_DDE_EXECUTE
Definition: dde.h:45
#define WM_DDE_INITIATE
Definition: dde.h:37
#define WM_DDE_UNADVISE
Definition: dde.h:40
#define WM_DDE_TERMINATE
Definition: dde.h:38
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define APIENTRY
Definition: api.h:79
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
Status
Definition: gdiplustypes.h:25
GLsizeiptr size
Definition: glext.h:5919
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
#define STUB
Definition: kernel32.h:27
@ SecurityImpersonation
Definition: lsa.idl:57
struct _SECURITY_QUALITY_OF_SERVICE SECURITY_QUALITY_OF_SERVICE
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define FASTCALL
Definition: nt_native.h:50
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
ATOM AtomDDETrack
Definition: ntuser.c:23
HANDLE FASTCALL UserRemoveProp(_In_ PWND Window, _In_ ATOM Atom, _In_ BOOLEAN SystemProp)
#define TRACE(s)
Definition: solgame.cpp:4
Definition: dde.h:57
BYTE Value[1]
Definition: dde.h:60
short cfFormat
Definition: dde.h:59
Definition: dde.h:72
short cfFormat
Definition: dde.h:74
BYTE Value[1]
Definition: dde.h:75
Definition: dde.c:21
WORD cRefConv
Definition: dde.c:25
SECURITY_CLIENT_CONTEXT ClientContext
Definition: dde.c:23
SECURITY_QUALITY_OF_SERVICE qos
Definition: dde.c:22
WORD cRefInit
Definition: dde.c:24
Definition: dde.c:29
int cbSize
Definition: dde.c:31
PVOID pvBuffer
Definition: dde.c:32
LPARAM lParam
Definition: dde.c:30
Definition: dde.c:36
PWND spwnd
Definition: dde.c:37
PWND spwndPartner
Definition: dde.c:38
PDDEIMP pddei
Definition: dde.c:39
PPROCESSINFO ppi
Definition: win32.h:88
Definition: ntuser.h:694
THRDESKHEAD head
Definition: ntuser.h:695
UINT message
Definition: winuser.h:3115
HWND hwnd
Definition: winuser.h:3114
WPARAM wParam
Definition: winuser.h:3116
LPARAM lParam
Definition: winuser.h:3117
#define LONG_PTR
Definition: treelist.c:79
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define UserEnterCo
Definition: ntuser.h:3
#define UserLeaveCo
Definition: ntuser.h:4
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:122
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
BOOL NTAPI GreSetObjectOwner(HGDIOBJ hobj, ULONG ulOwner)
Definition: gdiobj.c:1255
struct _DDEPOSTGET_CALLBACK_ARGUMENTS * PDDEPOSTGET_CALLBACK_ARGUMENTS
struct _DDEPOSTGET_CALLBACK_ARGUMENTS DDEPOSTGET_CALLBACK_ARGUMENTS
PVOID FASTCALL IntCbAllocateMemory(ULONG Size)
Definition: callback.c:27
VOID FASTCALL IntCbFreeMemory(PVOID Data)
Definition: callback.c:50
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
struct _DDE_DATA * PDDE_DATA
DWORD APIENTRY NtUserDdeInitialize(DWORD Unknown0, DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
Definition: dde.c:465
struct _DDEIMP DDEIMP
SECURITY_QUALITY_OF_SERVICE gqosDefault
Definition: dde.c:18
int APIENTRY IntDDEPostCallback(IN PWND pWnd, IN UINT Msg, IN WPARAM wParam, IN OUT LPARAM *lParam, IN OUT PVOID *Buffer)
Definition: dde.c:48
BOOL APIENTRY NtUserImpersonateDdeClientWindow(HWND hWndClient, HWND hWndServer)
Definition: dde.c:454
BOOL APIENTRY IntDdeGetMessageHook(PMSG pMsg, LONG_PTR ExtraInfo)
Definition: dde.c:326
BOOL APIENTRY NtUserDdeSetQualityOfService(IN HWND hwndClient, IN PSECURITY_QUALITY_OF_SERVICE pqosNew, OUT PSECURITY_QUALITY_OF_SERVICE pqosPrev)
Definition: dde.c:442
struct _DDE_PROP DDE_PROP
struct _DDE_PROP * PDDE_PROP
BOOL FASTCALL IntDdeSendMessageHook(PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: dde.c:386
BOOL APIENTRY IntDDEGetCallback(IN PWND pWnd, IN OUT PMSG pMsg, IN PVOID Buffer, IN int size)
Definition: dde.c:111
BOOL APIENTRY NtUserDdeGetQualityOfService(IN HWND hwndClient, IN HWND hWndServer, OUT PSECURITY_QUALITY_OF_SERVICE pqosPrev)
Definition: dde.c:430
struct _DDE_DATA DDE_DATA
struct _DDEIMP * PDDEIMP
HANDLE FASTCALL UserGetProp(_In_ PWND Window, _In_ ATOM Atom, _In_ BOOLEAN SystemProp)
Definition: prop.c:46
#define USERTAG_DDE1
Definition: tags.h:211
#define USERTAG_DDE5
Definition: tags.h:214
#define USERTAG_DDE
Definition: tags.h:223
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
#define NT_ASSERT
Definition: rtlfuncs.h:3310
#define SECURITY_STATIC_TRACKING
Definition: setypes.h:104