Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ddemlcli.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: ddemlcli.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * DDE Manager main client side module 00007 * 00008 * Created: 10/3/91 Sanford Staab 00009 * 00010 \***************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 // DDEML globals 00016 00017 PCL_INSTANCE_INFO pciiList = NULL; 00018 RTL_CRITICAL_SECTION gcsDDEML; 00019 #if DBG 00020 PVOID gpDDEMLHeap; 00021 #endif 00022 00023 /***************************************************************************\ 00024 * DdeInitialize (DDEML API) 00025 * 00026 * Description: 00027 * Used two different ways: 00028 * 1) First time call (*pidInst == 0) - causes a DDEML instance to be 00029 * created for the calling process/thread. Creates a server side 00030 * event window, server side instance structure, DDE Access Object, 00031 * and client side instance structure. The callback function address 00032 * and filter flags (afCmd) are placed into these structures. 00033 * 2) Subsequent call (*pidInst == hInst) - updates filter flags in 00034 * client and server side structures. 00035 * 00036 * History: 00037 * 11-1-91 sanfords Created. 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 // only allow certain bits to be changed on reinitialize call 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 // *pcii->plaNameService = 0; // zero init takes care of this 00113 pcii->cNameServiceAlloc = 1; 00114 00115 00116 /* 00117 * Flag this window as being create from a diff hmod as the app so 00118 * hotkeys don't take it as the first window created in the app and 00119 * assign it as the hotkey. 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 // pcii->LastError = DMLERR_NO_ERROR; // zero init 00134 pcii->tid = GetCurrentThreadId(); 00135 // pcii->aServerLookup = NULL; // zero init 00136 // pcii->cServerLookupAlloc = 0; // zero init 00137 // pcii->ConvStartupState = 0; // zero init - Not blocked. 00138 // pcii->flags = 0; // zero init 00139 // pcii->cInDDEMLCallback = 0; // zero init 00140 // pcii->pLinkCounts = NULL; // zero init 00141 00142 // Do this last when the client side is ready for whatever events 00143 // flying around may come charging in. 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 * DdeUninitialize (DDEML API) 00189 * 00190 * Description: 00191 * Shuts down a DDEML instance and frees all associated resources. 00192 * 00193 * History: 00194 * 11-12-91 sanfords Created. 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 * If this thread is in the middle of a synchronous transaction or 00213 * a callback, we need to back out of those first. 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 // unlink pcii from pciiList 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 * DdeNameService (DDEML API) 00265 * 00266 * Description: 00267 * Registers, and Unregisters service names and sets the Initiate filter 00268 * state for an instance. 00269 * 00270 * History: 00271 * 11-1-91 sanfords Created. 00272 \***************************************************************************/ 00273 HDDEDATA DdeNameService( 00274 DWORD idInst, 00275 HSZ hsz1, // service name 00276 HSZ hsz2, // reserved for future enhancements 00277 UINT afCmd) // DNS_ flags. 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 * registering NULL is not allowed! 00321 */ 00322 SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER); 00323 fRet = FALSE; 00324 goto Exit; 00325 } 00326 00327 /* 00328 * unregistering NULL is just like unregistering each 00329 * registered name. 00330 * 00331 * 10/19/90 - made this a synchronous event so that hsz 00332 * can be freed by calling app after this call completes 00333 * without us having to keep a copy around forever. 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)); // NameService copy 00362 plaNameService[pcii->cNameServiceAlloc - 2] = LATOM_FROM_HSZ(hsz1); 00363 plaNameService[pcii->cNameServiceAlloc - 1] = 0; 00364 00365 } else { // DNS_UNREGISTER 00366 plaNameService = pcii->plaNameService; 00367 while (*plaNameService != 0 && *plaNameService != LATOM_FROM_HSZ(hsz1)) { 00368 plaNameService++; 00369 } 00370 if (*plaNameService == 0) { 00371 goto Exit; // not found just exit 00372 } 00373 // 00374 // fill empty slot with last entry and fill last entry with 0 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 * DdeGetLastError (DDEML API) 00398 * 00399 * Description: 00400 * Returns last error code set for the instance given. 00401 * 00402 * History: 00403 * 11-12-91 sanfords Created. 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 * DdeImpersonateClient() 00430 * 00431 * Description: 00432 * Does security impersonation for DDEML server apps. 00433 * This API should only be called with server side hConvs; 00434 * 00435 * History: 00436 * 5-4-92 sanfords Created. 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 }

Generated on Sat May 15 19:39:39 2004 for test by doxygen 1.3.7