/*virtual*/ long DataPacker::pack_analytics(DataPacker::contract_vector &contracts, LPSAFEARRAY &data){ CComRecPtr<IRisksFullInfo, &LIBID_PRICEPROVIDERSLib> RisksFullInfo; RisksFullInfo.Init(); IRisksFullInfo* array_item = NULL; long array_size = static_cast<long>(contracts.size()); SAFEARRAYBOUND array_bound = {array_size, 0}; data = SafeArrayCreateEx(VT_RECORD, 1, &array_bound, (PVOID)RisksFullInfo.GetRecordInfo()); SafeArrayAccessData(data, (void**)&array_item); memset(array_item, 0, array_size * sizeof(IRisksFullInfo)); int j = 0; CAbstractContract* base_contract = 0; typedef std::vector<CAbstractContract*> container; container::iterator it = contracts.begin(); container::iterator it_end = contracts.end(); for (; it != it_end; it++) { CAbstractContract* contract = *it; if (contract->m_spBaseContract) { base_contract = dynamic_cast<CAbstractContract*>(contract->m_spBaseContract.GetInterfacePtr()); if (base_contract) { base_contract->GetTicker()->CopyTo(array_item[j].BaseTicker); }; } else { array_item[j].BaseTicker.Symbol = _com_util::ConvertStringToBSTR(""); array_item[j].BaseTicker.Exchange = _com_util::ConvertStringToBSTR(""); array_item[j].BaseTicker.Type = enSTK; }; contract->m_spRisks->CopyTo(array_item[j].Risks); contract->GetTicker()->CopyTo(array_item[j].Ticker); j++; }; ::SafeArrayUnaccessData(data); return j; };
STDMETHODIMP Profile::get_Languages(SAFEARRAY ** pVal) { try { WCHAR * pResult = gSkypeQueue.RetrieveProperty(L"PROFILE", L"", L"LANGUAGES"); long lTotal=0, lCtr=0; HRESULT hr; BSTR * pItems; for(int i = 0; i < 2; i++) { WCHAR *next_token = NULL; WCHAR * pItem = wcstok_s(pResult, L" ", &next_token); while(pItem != NULL) { if(wcslen(pItem) > 0) { if(i == 0) { lTotal++; } else { pItems[lCtr++] = SysAllocString(pItem); } } pItem = wcstok_s(NULL, L" ", &next_token); } if(i == 0) { SAFEARRAYBOUND sba; sba.cElements = lTotal; sba.lLbound = 0; *pVal = SafeArrayCreateEx(VT_BSTR, 1, & sba, NULL); if((*pVal) == NULL) { return AtlReportError(GetObjectCLSID(), L"Unable to create array", GUID_NULL, E_FAIL); } hr = SafeArrayLock(*pVal); if(FAILED(hr)) { return AtlReportError(GetObjectCLSID(), L"Unable to lock array", GUID_NULL, E_FAIL); } pItems = (BSTR *) (*pVal)->pvData; } else { hr = SafeArrayUnlock(*pVal); if(FAILED(hr)) { return AtlReportError(GetObjectCLSID(), L"Unable to unlock array", GUID_NULL, E_FAIL); } } } free(pResult); return S_OK; } catch (const WCHAR * err) { return AtlReportError(GetObjectCLSID(), err, GUID_NULL, E_FAIL); } }
unsigned char * WINAPI LPSAFEARRAY_UserUnmarshal(unsigned long *pFlags, unsigned char *Buffer, LPSAFEARRAY *ppsa) { ULONG_PTR ptr; wireSAFEARRAY wiresa; ULONG cDims; HRESULT hr; SF_TYPE sftype; ULONG cell_count; GUID guid; VARTYPE vt; SAFEARRAYBOUND *wiresab; TRACE("("); dump_user_flags(pFlags); TRACE(", %p, %p\n", Buffer, ppsa); ALIGN_POINTER(Buffer, 3); ptr = *(ULONG_PTR *)Buffer; Buffer += sizeof(ULONG_PTR); if (!ptr) { *ppsa = NULL; TRACE("NULL safe array unmarshaled\n"); return Buffer; } cDims = *(ULONG *)Buffer; Buffer += sizeof(ULONG); wiresa = (wireSAFEARRAY)Buffer; Buffer += FIELD_OFFSET(struct _wireSAFEARRAY, uArrayStructs); if (cDims != wiresa->cDims) RpcRaiseException(RPC_S_INVALID_BOUND); /* FIXME: there should be a limit on how large cDims can be */ vt = HIWORD(wiresa->cLocks); sftype = *(ULONG *)Buffer; Buffer += sizeof(ULONG); cell_count = *(ULONG *)Buffer; Buffer += sizeof(ULONG); ptr = *(ULONG_PTR *)Buffer; Buffer += sizeof(ULONG_PTR); if (sftype == SF_HAVEIID) { memcpy(&guid, Buffer, sizeof(guid)); Buffer += sizeof(guid); } wiresab = (SAFEARRAYBOUND *)Buffer; Buffer += sizeof(wiresab[0]) * wiresa->cDims; *ppsa = SafeArrayCreateEx(vt, wiresa->cDims, wiresab, NULL); if (!*ppsa) RpcRaiseException(E_OUTOFMEMORY); /* be careful about which flags we set since they could be a security * risk */ (*ppsa)->fFeatures &= FADF_AUTOSETFLAGS; (*ppsa)->fFeatures |= (wiresa->fFeatures & ~(FADF_AUTOSETFLAGS)); /* FIXME: there should be a limit on how large wiresa->cbElements can be */ (*ppsa)->cbElements = wiresa->cbElements; (*ppsa)->cLocks = LOWORD(wiresa->cLocks); hr = SafeArrayAllocData(*ppsa); if (FAILED(hr)) RpcRaiseException(hr); if ((*(ULONG *)Buffer != cell_count) || (SAFEARRAY_GetCellCount(*ppsa) != cell_count)) RpcRaiseException(RPC_S_INVALID_BOUND); Buffer += sizeof(ULONG); if (ptr) { switch (sftype) { case SF_BSTR: { BSTR* lpBstr; for (lpBstr = (BSTR*)(*ppsa)->pvData; cell_count; cell_count--, lpBstr++) Buffer = BSTR_UserUnmarshal(pFlags, Buffer, lpBstr); break; } case SF_DISPATCH: case SF_UNKNOWN: case SF_HAVEIID: FIXME("marshal interfaces\n"); break; case SF_VARIANT: { VARIANT* lpVariant; for (lpVariant = (VARIANT*)(*ppsa)->pvData; cell_count; cell_count--, lpVariant++) Buffer = VARIANT_UserUnmarshal(pFlags, Buffer, lpVariant); break; } case SF_RECORD: { FIXME("set record info\n"); break; } case SF_I8: ALIGN_POINTER(Buffer, 7); /* fallthrough */ case SF_I1: case SF_I2: case SF_I4: /* Just copy the data over */ memcpy((*ppsa)->pvData, Buffer, cell_count * (*ppsa)->cbElements); Buffer += cell_count * (*ppsa)->cbElements; break; default: break; } } TRACE("safe array unmarshaled: %p\n", *ppsa); return Buffer; }
STDMETHODIMP Profile::get_ForwardingRules(SAFEARRAY ** pVal) { try { WCHAR * pResult = gSkypeQueue.RetrieveProperty(L"PROFILE", L"", L"CALL_FORWARD_RULES"); size_t sz = wcslen(pResult) + 1; WCHAR * pCopy = new WCHAR[sz]; long lTotal=0, lCtr=0; HRESULT hr; ForwardingRule * pItems; for(int i = 0; i < 2; i++) { wcscpy_s(pCopy, sz, pResult); WCHAR *next_token = NULL; WCHAR * pItem = wcstok_s(pCopy, L" ", &next_token); while(pItem != NULL) { size_t iLen = wcslen(pItem); if(iLen > 0) { LONG start; LONG end; WCHAR * name = new WCHAR[iLen]; bool bValid = swscanf_s(pItem, L"%d,%d,%s", & start, & end, name, iLen) == 3; if(bValid) { if(i == 0) { lTotal++; } else { pItems[lCtr].StartTime = start; pItems[lCtr].EndTime = end; pItems[lCtr].Handle = SysAllocString(name); lCtr++; } } delete(name); } pItem = wcstok_s(NULL, L" ", &next_token); } if(i == 0) { SAFEARRAYBOUND sba; sba.cElements = lTotal; sba.lLbound = 0; CComPtr<IRecordInfo> *ptrRecInfo; hr = GetRecordInfoFromGuids(CAtlModule::m_libid, 1, 0, 0x409, __uuidof(ForwardingRule), (IRecordInfo**) & ptrRecInfo); if(FAILED(hr)) { return AtlReportError(GetObjectCLSID(), L"Unable to retrieve structure info", GUID_NULL, E_FAIL); } *pVal = SafeArrayCreateEx(VT_RECORD, 1, & sba, ptrRecInfo); if((*pVal) == NULL) { return AtlReportError(GetObjectCLSID(), L"Unable to create array", GUID_NULL, E_FAIL); } hr = SafeArrayLock(*pVal); if(FAILED(hr)) { return AtlReportError(GetObjectCLSID(), L"Unable to lock array", GUID_NULL, E_FAIL); } pItems = (ForwardingRule *) (*pVal)->pvData; } else { hr = SafeArrayUnlock(*pVal); if(FAILED(hr)) { return AtlReportError(GetObjectCLSID(), L"Unable to unlock array", GUID_NULL, E_FAIL); } } } free(pResult); return S_OK; } catch (const WCHAR * err) { return AtlReportError(GetObjectCLSID(), err, GUID_NULL, E_FAIL); } return S_OK; }