00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include "precomp.h"
00013
#pragma hdrstop
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 HDDEDATA
DoCallback(
00025
PCL_INSTANCE_INFO pcii,
00026 WORD wType,
00027 WORD wFmt,
00028 HCONV hConv,
00029 HSZ hsz1,
00030 HSZ hsz2,
00031 HDDEDATA hData,
00032 ULONG_PTR dw1,
00033 ULONG_PTR dw2)
00034 {
00035 HDDEDATA hDataRet;
00036
PCLIENTINFO pci;
00037
00038
CheckDDECritIn;
00039
00040
00041
00042
00043
00044
if (hConv &&
TypeFromHandle(hConv) ==
HTYPE_ZOMBIE_CONVERSATION) {
00045
return(0);
00046 }
00047
00048 pci =
GetClientInfo();
00049 pci->
cInDDEMLCallback++;
00050
00051 pcii->
cInDDEMLCallback++;
00052
LeaveDDECrit;
00053
CheckDDECritOut;
00054
00055
00056
00057
00058
00059
00060 hDataRet =
UserCallDDECallback(*pcii->
pfnCallback, (
UINT)wType, (
UINT)wFmt, hConv, hsz1, hsz2,
00061 hData, dw1, dw2);
00062
00063
EnterDDECrit;
00064 pcii->
cInDDEMLCallback--;
00065 pci->
cInDDEMLCallback--;
00066
00067
if (!(pcii->
afCmd & APPCLASS_MONITOR) && pcii->
MonitorFlags & MF_CALLBACKS) {
00068
PEVENT_PACKET pep;
00069
00070
pep = (
PEVENT_PACKET)
DDEMLAlloc(
sizeof(
EVENT_PACKET) -
sizeof(
DWORD) +
00071
sizeof(MONCBSTRUCT));
00072
if (
pep !=
NULL) {
00073
00074
pep->EventType = MF_CALLBACKS;
00075
pep->fSense =
TRUE;
00076
pep->cbEventData =
sizeof(MONCBSTRUCT);
00077
00078
#define pcbs ((MONCBSTRUCT *)&pep->Data)
00079
pcbs->cb =
sizeof(MONCBSTRUCT);
00080
pcbs->dwTime =
NtGetTickCount();
00081
pcbs->hTask = (HANDLE)LongToHandle( pcii->
tid );
00082
pcbs->dwRet = HandleToUlong(hDataRet);
00083
pcbs->wType = wType;
00084
pcbs->wFmt = wFmt;
00085
pcbs->hConv = hConv;
00086
pcbs->hsz1 = (HSZ)
LocalToGlobalAtom(
LATOM_FROM_HSZ(hsz1));
00087
pcbs->hsz2 = (HSZ)
LocalToGlobalAtom(
LATOM_FROM_HSZ(hsz2));
00088
pcbs->hData = hData;
00089
pcbs->dwData1 = dw1;
00090
pcbs->dwData2 = dw2;
00091
if (((wType == XTYP_CONNECT) || (wType == XTYP_WILDCONNECT)) && dw1) {
00092 RtlCopyMemory(&
pcbs->cc, (PVOID)dw1,
sizeof(CONVCONTEXT));
00093 }
00094
00095
LeaveDDECrit;
00096
00097
if (wType & XCLASS_DATA) {
00098
if (hDataRet && hDataRet != CBR_BLOCK) {
00099
pcbs->cbData =
DdeGetData(hDataRet, (LPBYTE)
pcbs->Data, 32, 0);
00100 }
00101 }
else if (hData) {
00102
pcbs->cbData =
DdeGetData(hData, (LPBYTE)
pcbs->Data, 32, 0);
00103 }
00104
00105
Event(
pep);
00106
00107
EnterDDECrit;
00108
00109 GlobalDeleteAtom(
LATOM_FROM_HSZ(
pcbs->hsz1));
00110 GlobalDeleteAtom(
LATOM_FROM_HSZ(
pcbs->hsz2));
00111
DDEMLFree(
pep);
00112
#undef pcbs
00113
}
00114 }
00115
return (hDataRet);
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 DWORD _ClientEventCallback(
00130
PCL_INSTANCE_INFO pcii,
00131
PEVENT_PACKET pep)
00132 {
00133 HDDEDATA hData;
00134
00135
EnterDDECrit;
00136
00137
switch (
pep->EventType) {
00138
case 0:
00139 pcii->
MonitorFlags =
pep->Data;
00140
break;
00141
00142
case MF_CALLBACKS:
00143 {
00144 MONCBSTRUCT mcb;
00145
00146 mcb = *((MONCBSTRUCT *)&
pep->Data);
00147 mcb.hsz1 =
NORMAL_HSZ_FROM_LATOM(
GlobalToLocalAtom((
GATOM)(ULONG_PTR)mcb.hsz1));
00148 mcb.hsz2 =
NORMAL_HSZ_FROM_LATOM(
GlobalToLocalAtom((
GATOM)(ULONG_PTR)mcb.hsz2));
00149
if ( mcb.wType == XTYP_REGISTER ||
00150 mcb.wType == XTYP_UNREGISTER) {
00151 mcb.hsz2 =
INST_SPECIFIC_HSZ_FROM_LATOM((
LATOM)(ULONG_PTR)mcb.hsz2);
00152 }
00153 hData =
InternalCreateDataHandle(pcii, (LPSTR)&mcb,
00154
pep->cbEventData, 0,
00155 HDATA_NOAPPFREE | HDATA_READONLY | HDATA_EXECUTE, 0, 0);
00156
if (hData) {
00157
DoCallback(pcii, (WORD)XTYP_MONITOR, 0, 0, 0, 0, hData, 0
L,
00158
pep->EventType);
00159
InternalFreeDataHandle((HDDEDATA)hData,
TRUE);
00160 DeleteAtom(
LATOM_FROM_HSZ(mcb.hsz1));
00161 DeleteAtom(
LATOM_FROM_HSZ(mcb.hsz2));
00162 }
00163 }
00164
break;
00165
00166
case MF_LINKS:
00167 {
00168 MONLINKSTRUCT ml;
00169
00170 ml = *((MONLINKSTRUCT *)&
pep->Data);
00171 ml.hszSvc =
NORMAL_HSZ_FROM_LATOM(
GlobalToLocalAtom((
GATOM)(ULONG_PTR)ml.hszSvc));
00172 ml.hszTopic =
NORMAL_HSZ_FROM_LATOM(
GlobalToLocalAtom((
GATOM)(ULONG_PTR)ml.hszTopic));
00173 ml.hszItem =
NORMAL_HSZ_FROM_LATOM(
GlobalToLocalAtom((
GATOM)(ULONG_PTR)ml.hszItem));
00174 hData =
InternalCreateDataHandle(pcii, (LPSTR)&ml,
00175
pep->cbEventData, 0,
00176 HDATA_NOAPPFREE | HDATA_READONLY | HDATA_EXECUTE, 0, 0);
00177
if (hData) {
00178
DoCallback(pcii, (WORD)XTYP_MONITOR, 0, 0, 0, 0, hData, 0
L,
00179
pep->EventType);
00180
InternalFreeDataHandle((HDDEDATA)hData,
TRUE);
00181 DeleteAtom(
LATOM_FROM_HSZ(ml.hszSvc));
00182 DeleteAtom(
LATOM_FROM_HSZ(ml.hszTopic));
00183 DeleteAtom(
LATOM_FROM_HSZ(ml.hszItem));
00184 }
00185 }
00186
break;
00187
00188
case MF_CONV:
00189 {
00190 MONCONVSTRUCT mc;
00191
00192 mc = *((MONCONVSTRUCT *)&
pep->Data);
00193 mc.hszSvc =
NORMAL_HSZ_FROM_LATOM(
GlobalToLocalAtom((
GATOM)(ULONG_PTR)mc.hszSvc));
00194 mc.hszTopic =
NORMAL_HSZ_FROM_LATOM(
GlobalToLocalAtom((
GATOM)(ULONG_PTR)mc.hszTopic));
00195 hData =
InternalCreateDataHandle(pcii, (LPSTR)&mc,
00196
pep->cbEventData, 0,
00197 HDATA_NOAPPFREE | HDATA_READONLY | HDATA_EXECUTE, 0, 0);
00198
if (hData) {
00199
DoCallback(pcii, (WORD)XTYP_MONITOR, 0, 0, 0, 0, hData, 0
L,
00200
pep->EventType);
00201
InternalFreeDataHandle((HDDEDATA)hData,
TRUE);
00202 DeleteAtom(
LATOM_FROM_HSZ(mc.hszSvc));
00203 DeleteAtom(
LATOM_FROM_HSZ(mc.hszTopic));
00204 }
00205 }
00206
break;
00207
00208
case MF_HSZ_INFO:
00209
if (!(pcii->
flags &
IIF_UNICODE)) {
00210 LPSTR pszAnsi;
00211
00212
00213
00214
if (WCSToMB(((PMONHSZSTRUCT)&
pep->Data)->str,
00215 ((
int)
pep->cbEventData - (
int)((PMONHSZSTRUCT)&
pep->Data)->cb) /
sizeof(WCHAR),
00216 &pszAnsi,
00217 (
int)
pep->cbEventData - (
int)((PMONHSZSTRUCT)&
pep->Data)->cb,
00218
TRUE)) {
00219 strcpy(((PMONHSZSTRUCTA)&
pep->Data)->str, pszAnsi);
00220
UserLocalFree(pszAnsi);
00221 }
00222 ((PMONHSZSTRUCT)&
pep->Data)->cb =
sizeof(MONHSZSTRUCTA);
00223 }
00224
00225
case MF_SENDMSGS:
00226
case MF_POSTMSGS:
00227
if (
pep->EventType == MF_POSTMSGS) {
00228 PMONMSGSTRUCT pmms = (PMONMSGSTRUCT)&
pep->Data;
00229
BYTE buf[32];
00230
00231
00232
00233
00234
00235
00236
if (pmms->wMsg == WM_DDE_EXECUTE) {
00237
BOOL fUnicodeText;
00238
int flags;
00239
00240 flags = (IS_TEXT_UNICODE_UNICODE_MASK |
00241 IS_TEXT_UNICODE_REVERSE_MASK |
00242 (IS_TEXT_UNICODE_NOT_UNICODE_MASK &
00243 (~IS_TEXT_UNICODE_ILLEGAL_CHARS)) |
00244 IS_TEXT_UNICODE_NOT_ASCII_MASK);
00245
#ifdef ISTEXTUNICODE_WORKS
00246
fUnicodeText =
RtlIsTextUnicode(pmms->dmhd.Data,
00247
min(32, pmms->dmhd.cbData), &flags);
00248
#else
00249
fUnicodeText = (*(LPSTR)pmms->dmhd.Data ==
'\0');
00250
#endif
00251
00252
if (pcii->
flags &
IIF_UNICODE && !fUnicodeText) {
00253
00254
RtlMultiByteToUnicodeN((LPWSTR)buf, 32,
NULL,
00255 (LPSTR)&pmms->dmhd.Data,
00256
min(32, pmms->dmhd.cbData));
00257 RtlCopyMemory(&pmms->dmhd.Data, buf, 32);
00258 }
else if (!(pcii->
flags &
IIF_UNICODE) && fUnicodeText) {
00259
00260
RtlUnicodeToMultiByteN((LPSTR)buf, 32,
NULL,
00261 (LPWSTR)&pmms->dmhd.Data,
00262
min(32, pmms->dmhd.cbData));
00263 RtlCopyMemory(&pmms->dmhd.Data, buf, 32);
00264 }
00265 }
00266 }
00267
case MF_ERRORS:
00268 hData =
InternalCreateDataHandle(pcii, (LPSTR)&
pep->Data,
00269
pep->cbEventData, 0,
00270 HDATA_NOAPPFREE | HDATA_READONLY | HDATA_EXECUTE, 0, 0);
00271
if (hData) {
00272
DoCallback(pcii, (WORD)XTYP_MONITOR, 0, 0, 0, 0, hData, 0
L,
00273
pep->EventType);
00274
InternalFreeDataHandle((HDDEDATA)hData,
TRUE);
00275 }
00276
break;
00277 }
00278
00279
LeaveDDECrit;
00280
return (0);
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 BOOL EnableEnumProc(
00296 HWND hwnd,
00297
PENABLE_ENUM_STRUCT pees)
00298 {
00299
PCONV_INFO pcoi;
00300
00301
for (pcoi = (
PCONV_INFO)
GetWindowLongPtr(hwnd,
GWLP_PCI);
00302 pcoi !=
NULL; pcoi = pcoi->
next) {
00303 pcoi->
cLocks++;
00304 *pees->
pfRet |=
SetEnableState(pcoi, pees->
wCmd);
00305
if (pees->
wCmd2) {
00306
00307
00308
00309
00310
00311
if (
SetEnableState(pcoi, pees->
wCmd2) &&
00312 pees->
wCmd2 == EC_CHECKQUEUEONCE) {
00313 pees->
wCmd2 = 0;
00314 }
00315 }
00316 pcoi->
cLocks--;
00317
if (pcoi->
cLocks == 0 && pcoi->
state & ST_FREE_CONV_RES_NOW) {
00318
FreeConversationResources(pcoi);
00319
break;
00320 }
00321 }
00322
return (
TRUE);
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 BOOL DdeEnableCallback(
00336 DWORD idInst,
00337 HCONV hConv,
00338 UINT wCmd)
00339 {
00340
BOOL fRet =
FALSE;
00341
PCL_INSTANCE_INFO pcii;
00342
PCONV_INFO pcoi;
00343
ENABLE_ENUM_STRUCT ees;
00344
00345
EnterDDECrit;
00346
00347 pcii = (
PCL_INSTANCE_INFO)
ValidateInstance((HANDLE)LongToHandle( idInst ));
00348
if (pcii ==
NULL) {
00349
BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
00350
goto Exit;
00351 }
00352
00353
switch (wCmd) {
00354
case EC_QUERYWAITING:
00355
case EC_DISABLE:
00356
case EC_ENABLEONE:
00357
case EC_ENABLEALL:
00358
break;
00359
00360
default:
00361
SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
00362
goto Exit;
00363 }
00364
00365
if (hConv) {
00366 pcoi = (
PCONV_INFO)
ValidateCHandle((HANDLE)hConv,
00367
HTYPE_CLIENT_CONVERSATION,
InstFromHandle(idInst));
00368
if (pcoi ==
NULL) {
00369 pcoi = (
PCONV_INFO)
ValidateCHandle((HANDLE)hConv,
00370
HTYPE_SERVER_CONVERSATION,
InstFromHandle(idInst));
00371 }
00372
if (pcoi ==
NULL) {
00373
SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
00374
goto Exit;
00375 }
00376 pcoi->
cLocks++;
00377 fRet =
SetEnableState(pcoi, wCmd);
00378
switch (wCmd) {
00379
case EC_ENABLEALL:
00380
case EC_ENABLEONE:
00381
CheckForQueuedMessages(pcoi);
00382 }
00383 pcoi->
cLocks--;
00384
if (pcoi->
cLocks == 0 && pcoi->
state & ST_FREE_CONV_RES_NOW) {
00385
FreeConversationResources(pcoi);
00386 }
00387 }
else {
00388
if (wCmd == EC_ENABLEONE) {
00389 wCmd = EC_ENABLEONEOFALL;
00390 }
00391
switch (wCmd) {
00392
case EC_ENABLEONEOFALL:
00393 pcii->
ConvStartupState = ST_BLOCKNEXT | ST_BLOCKALLNEXT;
00394
break;
00395
00396
case EC_DISABLE:
00397 pcii->
ConvStartupState = ST_BLOCKED;
00398
break;
00399
00400
case EC_ENABLEALL:
00401 pcii->
ConvStartupState = 0;
00402
break;
00403 }
00404 ees.
pfRet = &fRet;
00405 ees.
wCmd = (WORD)wCmd;
00406
switch (wCmd) {
00407
case EC_ENABLEALL:
00408 ees.
wCmd2 = EC_CHECKQUEUE;
00409
break;
00410
00411
case EC_ENABLEONEOFALL:
00412 ees.
wCmd2 = EC_CHECKQUEUEONCE;
00413
break;
00414
00415
default:
00416 ees.
wCmd2 = 0;
00417 }
00418
EnumChildWindows(pcii->
hwndMother, (WNDENUMPROC)
EnableEnumProc,
00419 (LPARAM)&ees);
00420 }
00421
00422 Exit:
00423
LeaveDDECrit;
00424
return (fRet);
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441 BOOL SetEnableState(
00442
PCONV_INFO pcoi,
00443 UINT wCmd)
00444 {
00445
BOOL fRet =
TRUE;
00446
00447
switch (wCmd) {
00448
case EC_CHECKQUEUEONCE:
00449
case EC_CHECKQUEUE:
00450 fRet =
CheckForQueuedMessages(pcoi);
00451
break;
00452
00453
case EC_QUERYWAITING:
00454 fRet = !(pcoi->
dmqOut ==
NULL ||
00455 (pcoi->
dmqOut->
next ==
NULL &&
00456
GetClientInfo()->CI_flags &
CI_PROCESSING_QUEUE));
00457
break;
00458
00459
case EC_DISABLE:
00460 pcoi->
state |= ST_BLOCKED;
00461 pcoi->
state &= ~(ST_BLOCKNEXT | ST_BLOCKALLNEXT);
00462
break;
00463
00464
case EC_ENABLEONE:
00465 pcoi->
state &= ~ST_BLOCKED;
00466 pcoi->
state |= ST_BLOCKNEXT;
00467
break;
00468
00469
case EC_ENABLEONEOFALL:
00470 pcoi->
state &= ~ST_BLOCKED;
00471 pcoi->
state |= (ST_BLOCKNEXT | ST_BLOCKALLNEXT);
00472
break;
00473
00474
case EC_ENABLEALL:
00475 pcoi->
state &= ~(ST_BLOCKED | ST_BLOCKNEXT | ST_BLOCKALLNEXT);
00476
break;
00477
00478
default:
00479
return(
FALSE);
00480 }
00481
return (fRet);
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 DWORD _ClientGetDDEHookData(
00501 UINT message,
00502 LPARAM lParam,
00503 PDDEML_MSG_HOOK_DATA pdmhd)
00504 {
00505
PBYTE pb;
00506 HANDLE hDDE;
00507
00508
UnpackDDElParam(message, lParam, &pdmhd->uiLo, &pdmhd->uiHi);
00509
switch (message) {
00510
case WM_DDE_DATA:
00511
case WM_DDE_POKE:
00512
case WM_DDE_ADVISE:
00513 hDDE = (HANDLE)pdmhd->uiLo;
00514
break;
00515
00516
case WM_DDE_EXECUTE:
00517 hDDE = (HANDLE)pdmhd->uiHi;
00518
break;
00519
00520
case WM_DDE_ACK:
00521
case WM_DDE_REQUEST:
00522
case WM_DDE_UNADVISE:
00523
case WM_DDE_TERMINATE:
00524 pdmhd->cbData = 0;
00525
return (1);
00526 }
00527
00528 pdmhd->cbData = (
DWORD)
UserGlobalSize(hDDE);
00529
if (pdmhd->cbData) {
00530
USERGLOBALLOCK(hDDE, pb);
00531
if (pb ==
NULL) {
00532 pdmhd->cbData = 0;
00533 }
else {
00534 RtlCopyMemory(&pdmhd->Data, pb,
min(pdmhd->cbData,
00535
sizeof(DDEML_MSG_HOOK_DATA) -
00536 FIELD_OFFSET(DDEML_MSG_HOOK_DATA, Data)));
00537
USERGLOBALUNLOCK(hDDE);
00538 }
00539 }
00540
return (1);
00541 }