📄 comlib.cpp
字号:
{ VARIANT * var = reinterpret_cast<VARIANT *> (pArrayDesc->arrayData.pvData); for (index = 0; index < pArrayDesc->dataCount; index++) { /* Check if this variant contains an array */ if (V_VT (&(var [index])) & VT_ARRAY) { DestroyArray (SA2MSA(V_ARRAY(&(var [index])))); } else { VariantClear (&(var [index])); } } } break; case VT_BSTR: { BSTR * pBstr = reinterpret_cast<BSTR *> (pArrayDesc->arrayData.pvData); for (index = 0; index < pArrayDesc->dataCount; index++) { if (pBstr [index] != NULL) { ::SysFreeString (pBstr [index]); } } } break; case VT_UNKNOWN: { IUnknown ** ppUnk = reinterpret_cast<IUnknown **> (pArrayDesc->arrayData.pvData); for (index = 0; index < pArrayDesc->dataCount; index++) { if (ppUnk [index] != NULL) { ppUnk [index]->Release (); } } } break; } pArrayDesc->signature = 0; pArrayDesc->pMutex->unlock (); delete pArrayDesc->pMutex; COM_MEM_FREE (pArrayDesc->arrayData.pvData); COM_MEM_FREE (pArrayDesc); }/**************************************************************************** SafeArrayDestroy - Destroys an existing array descriptor.* Destroys an existing array descriptor and all of the * data in the array. If complex types are stored in the* array the appropriate destruction will be performed.** RETURNS:* \is* \i S_OK* On success* \i DISP_E_ARRAYISLOCKED* If the SAFEARRAY is locked* \i E_INVALIDARG * If one of the arguments is invalid.* \ie*/HRESULT SafeArrayDestroy ( SAFEARRAY * psa /* Pointer to an array descriptor created */ /* by SafeArrayCreate */ ) { MEM_SAFEARRAY * pArrayDesc; ARRAY_LIST as; /* This is only required in the case where */ /* we have to unlock the mutexs if the */ /* fails. Mutexs are unlocked as part of */ /* the recursive delete otherwise. */ HRESULT hr; /* Check descriptor is valid */ if (psa == NULL) { return E_INVALIDARG; } pArrayDesc = SA2MSA(psa); hr = CheckArray (pArrayDesc, as); if (FAILED (hr)) { /* release all locks */ ArrayElement * ptr; while (!as.isEmpty ()) { ptr = as.popHead (); ptr->unlock (); delete ptr; } return hr; } DestroyArray (pArrayDesc); as.destroyList (); return S_OK; }/**************************************************************************** SafeArrayLock - Increment the lock count of a SAFEARRAY.** This function increments the lock count of a SAFEARRAY. ** RETURNS:* \is* \i S_OK* On success* \i E_INVALIDARG* If the SAFEARRAY is invalid.* \ie*/HRESULT SafeArrayLock ( SAFEARRAY * psa /* Pointer to an array descriptor created by */ /* SafeArrayCreate. */ ) { MEM_SAFEARRAY * pArrayDesc; if (psa == NULL) { return E_INVALIDARG; } pArrayDesc = SA2MSA(psa); /* Quick sanity check, if this passes but the mutex is invalid */ /* we'll get a VxDCOM Assert. */ if (pArrayDesc->signature != SAFEARRAY_SIG) { return E_INVALIDARG; } pArrayDesc->pMutex->lock (); /* Check sig again just incase we're being woken up after SA has been */ /* deleted. */ if (pArrayDesc->signature != SAFEARRAY_SIG) { return E_INVALIDARG; } /* This is all OK so increment the lock */ pArrayDesc->arrayData.cLocks++; pArrayDesc->pMutex->unlock (); return S_OK; }/**************************************************************************** SafeArrayUnlock - Decrement the lock count of a SAFEARRAY.** This function decrements the lock count of a SAFEARRAY. ** RETURNS:* \is* \i S_OK* On success* \i E_INVALIDARG * If the SAFEARARAY is invalid.* \i E_UNEXPECTED* If and attempt is made to decrement the lock count when it is zero.* \ie*/HRESULT SafeArrayUnlock ( SAFEARRAY * psa /* Pointer to an array descriptor created by */ /* SafeArrayCreate. */ ) { MEM_SAFEARRAY * pArrayDesc; HRESULT hr = S_OK; if (psa == NULL) { return E_INVALIDARG; } pArrayDesc = SA2MSA(psa); /* Quick sanity check, if this passes but the mutex is invalid */ /* we'll get a VxDCOM Assert. */ if (pArrayDesc->signature != SAFEARRAY_SIG) { return E_INVALIDARG; } pArrayDesc->pMutex->lock (); /* Check sig again just incase we're being woken up after SA has been */ /* deleted. */ if (pArrayDesc->signature != SAFEARRAY_SIG) { pArrayDesc->pMutex->unlock (); return E_INVALIDARG; } /* This is all OK so increment the lock */ if (pArrayDesc->arrayData.cLocks) { pArrayDesc->arrayData.cLocks--; } else { hr = E_UNEXPECTED; } pArrayDesc->pMutex->unlock (); return hr; }/*************************************************************************** * ArrayPos - Calculates the address of an array element.* This calculates the position of an element in the array based on the* following formula:** p = i [0] + (d [0] * i [1]) + (d [0] * d [1] * i [2]) + ...** RETURNS: S_OK on success, DISP_E_BADINDEX on failure.*.NOMANUAL*/HRESULT ArrayPos ( SAFEARRAY * psa, /* Array descriptor */ long * rgIndices, /* Index into array */ void ** pv /* pointer to array dlement */ ) { LONG inner; LONG outer; LONG sum = rgIndices [0] - psa->rgsabound [0].lLbound; *pv = NULL; /* Check that the index is in range since this is a Safearray */ if ((rgIndices [0] < psa->rgsabound [0].lLbound) || ((rgIndices [0] - psa->rgsabound [0].lLbound) > (LONG)psa->rgsabound [0].cElements)) { return DISP_E_BADINDEX; } for (outer = 1; outer < psa->cDims; outer++) { LONG mul = 1; /* Check that the index is in range since this is a Safearray */ if ((rgIndices [outer] < psa->rgsabound [outer].lLbound) || ((rgIndices [outer] - psa->rgsabound [outer].lLbound) > (LONG)psa->rgsabound [outer].cElements)) { return DISP_E_BADINDEX; } /* Do the d [0] + d [1] + ... bit */ for (inner = 0; inner < outer; inner++) { mul *= psa->rgsabound [inner].cElements; } /* Multiply by the current index */ mul *= (rgIndices [outer] - psa->rgsabound [outer].lLbound); /* Add to the cumulative offset */ sum += mul; } /* Multiply the offset by the element size to get to the right position */ /* without having to typecast anything. */ sum *= psa->cbElements; /* Set the data position. */ *pv = reinterpret_cast<void *>(reinterpret_cast<BYTE *>(psa->pvData) + sum); return S_OK; }/**************************************************************************** SafeArrayPutElement - Stores a copy of the data at a given location.** This function assigns a single element to the array. This function * calls SafeArrayLock and SafeArrayUnlock before and after assigning * the element. If the data element is a string, object, or variant, * the function copies it correctly. If the existing element is a string, * object, or variant, it is cleared correctly.** RETURNS:* \is* \i S_OK* Success. * \i DISP_E_BADINDEX* The specified index was invalid. * \i E_INVALIDARG* One of the arguments is invalid. * \i E_OUTOFMEMORY* Memory could not be allocated for the element. * \ie*/HRESULT SafeArrayPutElement ( SAFEARRAY * psa, /* Pointer to an array descriptor created by */ /* SafeArrayCreate. */ long * rgIndicies, /* Pointer to a vector of indices for each */ /* dimension of the array. */ void * pv /* Pointer to the data to assign. */ ) { void * ptr; HRESULT hr = S_OK; hr = SafeArrayLock (psa); if (FAILED (hr)) { return hr; } /* get a pointer to the appropriate area of memory */ hr = ArrayPos (psa, rgIndicies, &ptr); if (SUCCEEDED (hr)) { switch (SA2MSA(psa)->vt) { case VT_ERROR: case VT_UI1: case VT_I2: case VT_I4: case VT_R4: case VT_R8: case VT_CY: case VT_DATE: case VT_BOOL: memcpy (ptr, pv, psa->cbElements); break; case VT_UNKNOWN: { IUnknown ** iPtr = reinterpret_cast<IUnknown **>(ptr); if (*iPtr != NULL) { (*iPtr)->Release (); *iPtr = NULL; } if (reinterpret_cast<IUnknown *>(pv) != NULL) { hr = (reinterpret_cast<IUnknown *>(pv))-> QueryInterface(IID_IUnknown, (void **)iPtr); } } break; case VT_BSTR: { BSTR * bPtr = reinterpret_cast<BSTR *>(ptr); if (*bPtr != NULL) { hr = ::SysFreeString (*bPtr); *bPtr = NULL; } if (SUCCEEDED (hr) && (pv != NULL)) { *bPtr = ::SysAllocString ((BSTR)pv); } } break; case VT_VARIANT: hr = VariantClear (reinterpret_cast<VARIANT *>(ptr)); if (SUCCEEDED (hr)) { hr = VariantCopy (reinterpret_cast<VARIANT *>(ptr), reinterpret_cast<VARIANT *>(pv)); } break; } } HRESULT hr2 = SafeArrayUnlock (psa); if (FAILED (hr2)) { return hr2; } return hr; }/**************************************************************************** SafeArrayGetElement - Retrieves a single element of the array. ** Retrieves a single element of the array. This function calls * SafeArrayLock and SafeArrayUnlock automatically, before and * after retrieving the element. The caller must provide a storage * area of the correct size to receive the data. If the data element * is a string, object, or variant, the function copies the element * in the correct way. ** RETURNS:* \is* \i S_OK* Success. * \i DISP_E_BADINDEX* The specified index was invalid. * \i E_INVALIDARG* One of the arguments is invalid. * \i E_OUTOFMEMORY* Memory could not be allocated for the element. * \ie*/HRESULT SafeArrayGetElement ( SAFEARRAY * psa, /* Pointer to an array descriptor created by */ /* SafeArrayCreate. */ long * rgIndicies, /* Pointer to a vector of indices for each */ /* dimension of the array. */ void * pv /* Pointer to the returned data. */ ) { HRESULT hr = S_OK; void * ptr; if (pv == NULL) { return E_INVALIDARG; } hr = SafeArrayLock (psa); if (FAILED (hr)) { return hr; } /* get a pointer to the appropriate area of memory */ hr = ArrayPos (psa, rgIndicies, &ptr); if (SUCCEEDED (hr)) { switch (SA2MSA(psa)->vt) { case VT_ERROR: case VT_UI1: case VT_I2: case VT_I4: case VT_R4: case VT_R8: case VT_CY: case VT_DATE: case VT_BOOL: memcpy (pv, ptr, psa->cbElements); break; case VT_UNKNOWN: if (*reinterpret_cast<IUnknown **>(ptr)) { hr = (*reinterpret_cast<IUnknown **>(ptr))-> QueryInterface(IID_IUnknown, reinterpret_cast<void **>(pv)); } else { *reinterpret_cast<IUnknown **>(pv) = NUL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -