00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include "precomp.h"
00013
#pragma hdrstop
00014
00015
00016
00017 PCL_INSTANCE_INFO pciiList =
NULL;
00018 RTL_CRITICAL_SECTION
gcsDDEML;
00019
#if DBG
00020
PVOID gpDDEMLHeap;
00021
#endif
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 UINT DdeInitializeA(
00040 LPDWORD pidInst,
00041 PFNCALLBACK pfnCallback,
00042 DWORD afCmd,
00043 DWORD ulRes)
00044 {
00045
if (ulRes != 0) {
00046
return (DMLERR_INVALIDPARAMETER);
00047 }
00048
return (
InternalDdeInitialize(pidInst, pfnCallback, afCmd, 0));
00049 }
00050
00051
00052 UINT DdeInitializeW(
00053 LPDWORD pidInst,
00054 PFNCALLBACK pfnCallback,
00055 DWORD afCmd,
00056 DWORD ulRes)
00057 {
00058
if (ulRes != 0) {
00059
return (DMLERR_INVALIDPARAMETER);
00060 }
00061
return (
InternalDdeInitialize(pidInst, pfnCallback, afCmd, 1));
00062 }
00063
00064
00065 UINT InternalDdeInitialize(
00066 LPDWORD pidInst,
00067 PFNCALLBACK pfnCallback,
00068 DWORD afCmd,
00069 BOOL fUnicode)
00070 {
00071
UINT uiRet = DMLERR_MEMORY_ERROR;
00072
register PCL_INSTANCE_INFO pcii;
00073
00074
if (afCmd & APPCLASS_MONITOR) {
00075 afCmd |= CBF_MONMASK;
00076 }
00077
00078
if (afCmd & APPCMD_CLIENTONLY) {
00079 afCmd |= CBF_FAIL_CONNECTIONS;
00080 }
00081
00082
EnterDDECrit;
00083
00084
if (*pidInst != 0) {
00085 pcii =
ValidateInstance((HANDLE)LongToHandle( *pidInst ));
00086
if (pcii ==
NULL) {
00087 uiRet = DMLERR_INVALIDPARAMETER;
00088
goto Exit;
00089 }
00090
00091
00092
00093 pcii->
afCmd = (pcii->
afCmd & ~(CBF_MASK | MF_MASK)) |
00094 (afCmd & (CBF_MASK | MF_MASK));
00095
00096
LeaveDDECrit;
00097
NtUserUpdateInstance(pcii->
hInstServer, &pcii->
MonitorFlags, afCmd);
00098
return (DMLERR_NO_ERROR);
00099 }
00100
00101 pcii = (
PCL_INSTANCE_INFO)
DDEMLAlloc(
sizeof(
CL_INSTANCE_INFO));
00102
if (pcii ==
NULL) {
00103 uiRet = DMLERR_MEMORY_ERROR;
00104
goto Exit;
00105 }
00106
00107 pcii->
plaNameService = (
LATOM *)
DDEMLAlloc(
sizeof(
LATOM));
00108
if (pcii->
plaNameService ==
NULL) {
00109 uiRet = DMLERR_MEMORY_ERROR;
00110
goto Backout3;
00111 }
00112
00113 pcii->
cNameServiceAlloc = 1;
00114
00115
00116
00117
00118
00119
00120
00121 pcii->
hwndMother =
_CreateWindowEx(0, (LPTSTR)(
gpsi->
atomSysClass[
ICLS_DDEMLMOTHER]),
L"",
00122 WS_POPUP, 0, 0, 0, 0, (HWND)0,
00123 (HMENU)0, 0, (
LPVOID)
NULL,
CW_FLAGS_DIFFHMOD);
00124
00125
if (pcii->
hwndMother == 0) {
00126 uiRet = DMLERR_SYS_ERROR;
00127
goto Backout2;
00128 }
00129
SetWindowLongPtr(pcii->
hwndMother,
GWLP_INSTANCE_INFO, (LONG_PTR)pcii);
00130
00131 pcii->afCmd = afCmd | APPCMD_FILTERINITS;
00132 pcii->pfnCallback = pfnCallback;
00133
00134 pcii->tid = GetCurrentThreadId();
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
LeaveDDECrit;
00146 uiRet =
NtUserDdeInitialize(&pcii->hInstServer,
00147 &pcii->hwndEvent,
00148 &pcii->MonitorFlags,
00149 pcii->afCmd,
00150 pcii);
00151
EnterDDECrit;
00152
00153
if (uiRet != DMLERR_NO_ERROR) {
00154 Backout:
00155
NtUserDestroyWindow(pcii->hwndMother);
00156 Backout2:
00157
DDEMLFree(pcii->plaNameService);
00158 Backout3:
00159
DDEMLFree(pcii);
00160
goto Exit;
00161 }
00162 pcii->hInstClient =
AddInstance(pcii->hInstServer);
00163 *pidInst = HandleToUlong(pcii->hInstClient);
00164
if (pcii->hInstClient == 0) {
00165
LeaveDDECrit;
00166
NtUserCallOneParam((ULONG_PTR)pcii->hInstServer, SFI__CSDDEUNINITIALIZE);
00167
EnterDDECrit;
00168 uiRet = DMLERR_MEMORY_ERROR;
00169
goto Backout;
00170 }
00171
SetHandleData(pcii->hInstClient, (ULONG_PTR)pcii);
00172
00173 pcii->next =
pciiList;
00174
pciiList = pcii;
00175
if (fUnicode) {
00176 pcii->
flags |=
IIF_UNICODE;
00177 }
00178 uiRet = DMLERR_NO_ERROR;
00179
00180 Exit:
00181
LeaveDDECrit;
00182
return (uiRet);
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 BOOL DdeUninitialize(
00197 DWORD idInst)
00198 {
00199
PCL_INSTANCE_INFO pcii, pciiPrev;
00200
BOOL fRet =
FALSE;
00201
00202
CheckDDECritOut;
00203
EnterDDECrit;
00204
00205 pcii =
ValidateInstance((HANDLE)LongToHandle( idInst ));
00206
if (pcii ==
NULL) {
00207
BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
00208
goto Exit;
00209 }
00210
00211
00212
00213
00214
00215
if ((pcii->
flags &
IIF_IN_SYNC_XACT) || pcii->
cInDDEMLCallback) {
00216 pcii->
afCmd |= APPCMD_UNINIT_ASAP;
00217 fRet =
TRUE;
00218
goto Exit;
00219 }
00220
00221
ApplyFunctionToObjects(
HTYPE_CONVERSATION_LIST,
InstFromHandle(pcii->
hInstClient),
00222 (
PFNHANDLEAPPLY)
DdeDisconnectList);
00223
ApplyFunctionToObjects(
HTYPE_CLIENT_CONVERSATION,
InstFromHandle(pcii->
hInstClient),
00224 (
PFNHANDLEAPPLY)
DdeDisconnect);
00225
ApplyFunctionToObjects(
HTYPE_SERVER_CONVERSATION,
InstFromHandle(pcii->
hInstClient),
00226 (
PFNHANDLEAPPLY)
DdeDisconnect);
00227
ApplyFunctionToObjects(
HTYPE_ZOMBIE_CONVERSATION,
InstFromHandle(pcii->
hInstClient),
00228 (
PFNHANDLEAPPLY)
WaitForZombieTerminate);
00229
ApplyFunctionToObjects(
HTYPE_DATA_HANDLE,
InstFromHandle(pcii->
hInstClient),
00230 (
PFNHANDLEAPPLY)
ApplyFreeDataHandle);
00231
00232
LeaveDDECrit;
00233
NtUserCallOneParam((ULONG_PTR)pcii->
hInstServer, SFI__CSDDEUNINITIALIZE);
00234
NtUserDestroyWindow(pcii->
hwndMother);
00235
EnterDDECrit;
00236
00237
DDEMLFree(pcii->
plaNameService);
00238
DestroyInstance(pcii->
hInstClient);
00239
00240
00241
00242
if (
pciiList == pcii) {
00243
pciiList =
pciiList->
next;
00244 }
else {
00245
for (pciiPrev =
pciiList; pciiPrev !=
NULL && pciiPrev->
next != pcii;
00246 pciiPrev = pciiPrev->
next) {
00247 ;
00248 }
00249
if (pciiPrev !=
NULL) {
00250 pciiPrev->
next = pcii->
next;
00251 }
00252 }
00253
DDEMLFree(pcii);
00254 fRet =
TRUE;
00255
00256 Exit:
00257
LeaveDDECrit;
00258
return (fRet);
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 HDDEDATA
DdeNameService(
00274 DWORD idInst,
00275 HSZ hsz1,
00276 HSZ hsz2,
00277 UINT afCmd)
00278 {
00279
BOOL fRet =
TRUE;
00280
LATOM *plaNameService;
00281
PCL_INSTANCE_INFO pcii;
00282
00283
EnterDDECrit;
00284
00285 pcii =
ValidateInstance((HANDLE)LongToHandle( idInst ));
00286
if (pcii ==
NULL) {
00287
BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
00288 fRet =
FALSE;
00289
goto Exit;
00290 }
00291
00292
if ((hsz1 &&
ValidateHSZ(hsz1) ==
HSZT_INVALID) || hsz2 != 0) {
00293
SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
00294 fRet =
FALSE;
00295
goto Exit;
00296 }
00297
00298
if (afCmd & DNS_FILTERON && !(pcii->
afCmd & APPCMD_FILTERINITS)) {
00299 pcii->
afCmd |= APPCMD_FILTERINITS;
00300
NtUserUpdateInstance(pcii->
hInstServer, &pcii->
MonitorFlags, pcii->
afCmd);
00301 }
00302
if (afCmd & DNS_FILTEROFF && (pcii->
afCmd & APPCMD_FILTERINITS)) {
00303 pcii->
afCmd &= ~APPCMD_FILTERINITS;
00304
NtUserUpdateInstance(pcii->
hInstServer, &pcii->
MonitorFlags, pcii->
afCmd);
00305 }
00306
00307
if (afCmd & (DNS_REGISTER | DNS_UNREGISTER)) {
00308
GATOM ga;
00309
00310
if (pcii->
afCmd & APPCMD_CLIENTONLY) {
00311
SetLastDDEMLError(pcii, DMLERR_DLL_USAGE);
00312 fRet =
FALSE;
00313
goto Exit;
00314 }
00315
00316
if (hsz1 == 0) {
00317
if (afCmd & DNS_REGISTER) {
00318
00319
00320
00321
00322
SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
00323 fRet =
FALSE;
00324
goto Exit;
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 plaNameService = pcii->
plaNameService;
00336
while (*plaNameService != 0) {
00337 ga =
LocalToGlobalAtom(*plaNameService);
00338 DeleteAtom(*plaNameService);
00339
LeaveDDECrit;
00340
RegisterService(
FALSE, ga, pcii->
hwndMother);
00341
EnterDDECrit;
00342 GlobalDeleteAtom(ga);
00343 plaNameService++;
00344 }
00345 pcii->
cNameServiceAlloc = 1;
00346 *pcii->
plaNameService = 0;
00347
goto Exit;
00348 }
00349
00350
if (afCmd & DNS_REGISTER) {
00351 plaNameService = (
LATOM *)
DDEMLReAlloc(pcii->
plaNameService,
00352
sizeof(
LATOM) * ++pcii->
cNameServiceAlloc);
00353
if (plaNameService ==
NULL) {
00354
SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
00355 pcii->
cNameServiceAlloc--;
00356 fRet =
FALSE;
00357
goto Exit;
00358 }
else {
00359 pcii->
plaNameService = plaNameService;
00360 }
00361
IncLocalAtomCount(
LATOM_FROM_HSZ(hsz1));
00362 plaNameService[pcii->
cNameServiceAlloc - 2] =
LATOM_FROM_HSZ(hsz1);
00363 plaNameService[pcii->
cNameServiceAlloc - 1] = 0;
00364
00365 }
else {
00366 plaNameService = pcii->
plaNameService;
00367
while (*plaNameService != 0 && *plaNameService !=
LATOM_FROM_HSZ(hsz1)) {
00368 plaNameService++;
00369 }
00370
if (*plaNameService == 0) {
00371
goto Exit;
00372 }
00373
00374
00375
00376 pcii->
cNameServiceAlloc--;
00377 *plaNameService = pcii->
plaNameService[pcii->
cNameServiceAlloc - 1];
00378 pcii->
plaNameService[pcii->
cNameServiceAlloc - 1] = 0;
00379 }
00380
00381 ga =
LocalToGlobalAtom(
LATOM_FROM_HSZ(hsz1));
00382
LeaveDDECrit;
00383
RegisterService((afCmd & DNS_REGISTER) ?
TRUE :
FALSE, ga,
00384 pcii->
hwndMother);
00385
EnterDDECrit;
00386 GlobalDeleteAtom(ga);
00387 }
00388
00389 Exit:
00390
LeaveDDECrit;
00391
return ((HDDEDATA)IntToPtr( fRet ));
00392 }
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 UINT DdeGetLastError(
00406 DWORD idInst)
00407 {
00408
UINT uiRet = 0;
00409
PCL_INSTANCE_INFO pcii;
00410
00411
EnterDDECrit;
00412
00413 pcii =
ValidateInstance((HANDLE)LongToHandle( idInst ));
00414
if (pcii ==
NULL) {
00415 uiRet = DMLERR_INVALIDPARAMETER;
00416
goto Exit;
00417 }
00418 uiRet = pcii->
LastError;
00419 pcii->
LastError = DMLERR_NO_ERROR;
00420
00421 Exit:
00422
LeaveDDECrit;
00423
return (uiRet);
00424 }
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 BOOL DdeImpersonateClient(
00439 HCONV hConv)
00440 {
00441
PCONV_INFO pcoi;
00442
PCL_INSTANCE_INFO pcii;
00443
BOOL fRet =
FALSE;
00444
00445
EnterDDECrit;
00446
00447 pcoi = (
PCONV_INFO)
ValidateCHandle((HANDLE)hConv,
00448
HTYPE_SERVER_CONVERSATION,
HINST_ANY);
00449
if (pcoi ==
NULL) {
00450
BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
00451
goto Exit;
00452 }
00453 pcii =
PciiFromHandle((HANDLE)hConv);
00454
if (pcii ==
NULL) {
00455
BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
00456
goto Exit;
00457 }
00458
00459 fRet =
NtUserImpersonateDdeClientWindow(pcoi->
hwndPartner, pcoi->
hwndConv);
00460 Exit:
00461
LeaveDDECrit;
00462
return (fRet);
00463 }