template <class ITEM> void BlobEncoder::encode(const ITEM &item) { SAFEARRAYBOUND bound[1] = {0, 0}; bound[0].cElements = item.encodedSize(); blob = SafeArrayCreate(VT_UI1, 1, bound); if (S_OK != SafeArrayLock(blob)) { SafeArrayDestroy(blob); blob = 0; throw qpid::Exception("Error locking blob area for persistable item"); } try { qpid::framing::Buffer buff((char *)blob->pvData, bound[0].cElements); item.encode(buff); } catch(...) { SafeArrayUnlock(blob); SafeArrayDestroy(blob); blob = 0; throw; } this->vt = VT_ARRAY | VT_UI1; this->parray = blob; SafeArrayUnlock(blob); }
STDMETHODIMP Profile::put_Languages(SAFEARRAY * newVal) { try { VARTYPE vt = VT_UNKNOWN; SafeArrayGetVartype(newVal, & vt); UINT uiDim = SafeArrayGetDim(newVal); if((uiDim != 1) || (vt != VT_BSTR)) { return AtlReportError(GetObjectCLSID(), L"Array of languages must be single dimension array of strings", GUID_NULL, E_INVALIDARG); } HRESULT hr = SafeArrayLock(newVal); if(FAILED(hr)) { return AtlReportError(GetObjectCLSID(), L"Unable to lock array", GUID_NULL, E_FAIL); } BSTR * pItems = (BSTR *) newVal->pvData; wstring wstrItems; for(ULONG l = 0; l < newVal->rgsabound[0].cElements; l++) { if(l > 0) wstrItems += L" "; wstrItems += pItems[l]; } SafeArrayUnlock(newVal); gSkypeQueue.SetProperty(L"PROFILE", L"", L"LANGUAGES", wstrItems.c_str()); return S_OK; } catch (const WCHAR * err) { return AtlReportError(GetObjectCLSID(), err, GUID_NULL, E_FAIL); } }
SafeByteArray::SafeByteArray(void* data, int sizeInBytes) { pArray = SafeArrayCreateVector(VT_UI1, 0, sizeInBytes); SafeArrayLock(pArray); memcpy(pArray->pvData, data, sizeInBytes); SafeArrayUnlock(pArray); }
HRESULT CKhParser::GetNextHomonym( SAFEARRAY** lpHomonym ) { if (currHom == -1) return S_OK; std::wstring str; if (currHom < homonyms.size()) str = homonyms[currHom].khak; else str = homonyms[currHom % homonyms.size()].rus; long idx, len, start; len = (long)str.length(); SafeArrayLock(*lpHomonym); SafeArrayGetUBound(*lpHomonym, 1, &len); SafeArrayGetLBound(*lpHomonym, 1, &start); short asterisk = L'*'; for (idx = start; idx < len; idx ++) { if (idx == str.length()) { // if (str[idx] == 0x0) { SafeArrayPutElement(*lpHomonym, &idx, &asterisk); break; } SafeArrayPutElement(*lpHomonym, &idx, &str[ idx ]); } SafeArrayUnlock(*lpHomonym); currHom++; return S_OK; }
void CLauncherWindow::LoadNullLoginPage() { auto document = m_webBrowser.GetDocument(); if(!document.IsEmpty()) { auto page = GetNullLoginPage(); HRESULT result = S_OK; BSTR documentText = SysAllocString(page.c_str()); { SAFEARRAYBOUND documentBounds = {}; documentBounds.cElements = 1; documentBounds.lLbound = 0; auto documentArray = SafeArrayCreate(VT_VARIANT, 1, &documentBounds); { result = SafeArrayLock(documentArray); assert(SUCCEEDED(result)); auto& elementVar = reinterpret_cast<VARIANT*>(documentArray->pvData)[0]; elementVar.vt = VT_BSTR; elementVar.bstrVal = documentText; result = SafeArrayUnlock(documentArray); assert(SUCCEEDED(result)); } result = document->write(documentArray); assert(SUCCEEDED(result)); SafeArrayDestroy(documentArray); } SysFreeString(documentText); document->close(); } }
template <> void BlobEncoder::encode(const boost::intrusive_ptr<qpid::broker::PersistableMessage> &item) { // NOTE! If this code changes, verify the recovery code in MessageRecordset SAFEARRAYBOUND bound[1] = {0, 0}; bound[0].cElements = item->encodedSize() + sizeof(uint32_t); blob = SafeArrayCreate(VT_UI1, 1, bound); if (S_OK != SafeArrayLock(blob)) { SafeArrayDestroy(blob); blob = 0; throw qpid::Exception("Error locking blob area for message"); } try { uint32_t headerSize = item->encodedHeaderSize(); qpid::framing::Buffer buff((char *)blob->pvData, bound[0].cElements); buff.putLong(headerSize); item->encode(buff); } catch(...) { SafeArrayUnlock(blob); SafeArrayDestroy(blob); blob = 0; throw; } this->vt = VT_ARRAY | VT_UI1; this->parray = blob; SafeArrayUnlock(blob); }
bool wxSafeArrayBase::Lock() { wxCHECK_MSG( m_array, false, wxS("Uninitialized safe array") ); HRESULT hr = SafeArrayLock(m_array); if ( FAILED(hr) ) { wxLogApiError(wxS("SafeArrayLock()"), hr); return false; } return true; }
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); } }
/************************************************************************* * SafeArrayAccessData (OLEAUT32.23) * * Lock a SafeArray and return a pointer to its data. * * PARAMS * psa [I] Array to get the data pointer from * ppvData [O] Destination for the arrays data pointer * * RETURNS * Success: S_OK. ppvData contains the arrays data pointer, and the array * is locked. * Failure: An HRESULT error code indicating the error. * * NOTES * See SafeArray. */ HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData) { HRESULT hr; TRACE("(%p,%p)\n", psa, ppvData); if(!psa || !ppvData) return E_INVALIDARG; hr = SafeArrayLock(psa); *ppvData = SUCCEEDED(hr) ? psa->pvData : NULL; return hr; }
SAFEARRAY* CGainer::convert(BSTR bstr) { if (!SysStringLen(bstr) || !wcschr(L"IiRr", *bstr)) { return NULL; } bool digital = *bstr == 'R' || *bstr == 'r'; int len = (digital) ? (SysStringLen(bstr) - 1) : (SysStringLen(bstr) - 1) / 2; SAFEARRAYBOUND rgsabound[1]; rgsabound[0].cElements = len; rgsabound[0].lLbound = 0L; #ifdef USE_VARIANT SAFEARRAY* pNewAry = SafeArrayCreate(VT_VARIANT, 1, rgsabound); #else SAFEARRAY* pNewAry = SafeArrayCreate(VT_UI1, 1, rgsabound); #endif SafeArrayLock(pNewAry); #ifdef USE_VARIANT VARIANT* ps = (VARIANT*)pNewAry->pvData; #else LPBYTE ps = (LPBYTE)pNewAry->pvData; #endif for (int i = 0; i < len; i++, ps++) { #ifdef USE_VARIANT VariantInit(ps); if (digital) { ps->vt = VT_UI1; ps->bVal = (byte)xconv(*(bstr + i + 1)); } else { ps->vt = VT_UI1; ps->bVal = (byte)((xconv(*(bstr + i * 2 + 1)) << 4) | xconv(*(bstr + i * 2 + 2))); } #else if (digital) { *ps = (byte)xconv(*(bstr + i + 1)); } else { *ps = (byte)((xconv(*(bstr + i * 2 + 1)) << 4) | xconv(*(bstr + i * 2 + 2))); } #endif } SafeArrayUnlock(pNewAry); return pNewAry; }
template <> void BlobEncoder::encode(const std::string &item) { SAFEARRAYBOUND bound[1] = {0, 0}; bound[0].cElements = item.size(); blob = SafeArrayCreate(VT_UI1, 1, bound); if (S_OK != SafeArrayLock(blob)) { SafeArrayDestroy(blob); blob = 0; throw qpid::Exception("Error locking blob area for string"); } memcpy_s(blob->pvData, item.size(), item.data(), item.size()); this->vt = VT_ARRAY | VT_UI1; this->parray = blob; SafeArrayUnlock(blob); }
static SAFEARRAY * get_locked_safe_array(VALUE val) { struct olevariantdata *pvar; SAFEARRAY *psa = NULL; HRESULT hr; TypedData_Get_Struct(val, struct olevariantdata, &olevariant_datatype, pvar); if (!(V_VT(&(pvar->var)) & VT_ARRAY)) { rb_raise(rb_eTypeError, "variant type is not VT_ARRAY."); } psa = V_ISBYREF(&(pvar->var)) ? *V_ARRAYREF(&(pvar->var)) : V_ARRAY(&(pvar->var)); if (psa == NULL) { return psa; } hr = SafeArrayLock(psa); if (FAILED(hr)) { ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayLock"); } return psa; }
HRESULT STDMETHODCALLTYPE CGainer::WriteAllDigitalOutputs( /* [in] */ SAFEARRAY **NewValue) { if (!m_iothread) return Error(IDS_E_NOTOPENED); if (!NewValue || !*NewValue) return E_POINTER; SAFEARRAY* p = *NewValue; SafeArrayLock(p); LPBYTE pdata = reinterpret_cast<LPBYTE>(p->pvData); char* dst = reinterpret_cast<char*>(_alloca(p->rgsabound[0].cElements + 8)); char* msg = dst; *dst++ = 'D'; for (size_t i = p->rgsabound[0].lLbound; i < p->rgsabound[0].cElements; i++) { dst += sprintf(dst, "%d", *(pdata + i - p->rgsabound[0].lLbound)); } *dst++ = '*'; *dst = '\0'; SafeArrayUnlock(p); notify_message(m_iothread_id, WM_COM_IO, msg); return S_OK; }
STDMETHODIMP Profile::put_ForwardingRules(SAFEARRAY * newVal) { try { VARTYPE vt = VT_UNKNOWN; SafeArrayGetVartype(newVal, & vt); UINT uiDim = SafeArrayGetDim(newVal); if((uiDim != 1) || (vt != VT_RECORD)) { return AtlReportError(GetObjectCLSID(), L"Array of rules must be single dimension array of strings", GUID_NULL, E_INVALIDARG); } HRESULT hr = SafeArrayLock(newVal); if(FAILED(hr)) { return AtlReportError(GetObjectCLSID(), L"Unable to lock array", GUID_NULL, E_FAIL); } wstring wstrItems; ForwardingRule * pItems = (ForwardingRule *) newVal->pvData; for(ULONG l = 0; l < newVal->rgsabound[0].cElements; l++) { WCHAR start[32], end[32]; _ltow_s(pItems[l].StartTime, start, sizeof(start)/sizeof(start[0]), 10); _ltow_s(pItems[l].EndTime, end, sizeof(end)/sizeof(end[0]), 10); if(l > 0) { wstrItems += L" "; } wstrItems += start; wstrItems += L","; wstrItems += end; wstrItems += L","; wstrItems += pItems[l].Handle; } SafeArrayUnlock(newVal); gSkypeQueue.SetProperty(L"PROFILE", L"", L"CALL_FORWARD_RULES", wstrItems.c_str()); return S_OK; } catch (const WCHAR * err) { return AtlReportError(GetObjectCLSID(), err, GUID_NULL, E_FAIL); } }
static NPError _OpenURL(NPP npp, const char *szURL, const char *szTarget, void *pNotifyData, const char *pData, uint32 len, NPBool isFile) { if (!npp) { return NPERR_INVALID_INSTANCE_ERROR; } void *postData = NULL; uint32 postDataLen = 0; if (pData) { if (!isFile) { postData = (void *) pData; postDataLen = len; } else { // TODO read the file specified in the postdata param into memory } } nsPluginHostWnd *pWnd = (nsPluginHostWnd *) npp->ndata; ATLASSERT(pWnd); // Other window targets if (szTarget) { CComPtr<IWebBrowserApp> cpBrowser; pWnd->GetWebBrowserApp(&cpBrowser); if (!cpBrowser) { return NPERR_GENERIC_ERROR; } CComBSTR url(szURL); HRESULT hr; // Test if the input URL has a schema which means it's relative, // otherwise consider it to be relative to the current URL WCHAR szSchema[10]; const DWORD cbSchema = sizeof(szSchema) / sizeof(szSchema[0]); DWORD cbSchemaUsed = 0; memset(szSchema, 0, cbSchema); hr = CoInternetParseUrl(url.m_str, PARSE_SCHEMA, 0, szSchema, cbSchema, &cbSchemaUsed, 0); if (hr != S_OK || cbSchemaUsed == 0) { // Convert relative URLs to absolute, so that they can be loaded // by the Browser CComBSTR bstrCurrentURL; cpBrowser->get_LocationURL(&bstrCurrentURL); if (bstrCurrentURL.Length()) { USES_CONVERSION; DWORD cbNewURL = (url.Length() + bstrCurrentURL.Length() + 1) * sizeof(WCHAR); DWORD cbNewURLUsed = 0; WCHAR *pszNewURL = (WCHAR *) calloc(cbNewURL, 1); ATLASSERT(pszNewURL); CoInternetCombineUrl( bstrCurrentURL.m_str, url.m_str, 0, pszNewURL, cbNewURL, &cbNewURLUsed, 0); ATLASSERT(cbNewURLUsed < cbNewURL); url = pszNewURL; free(pszNewURL); } } CComVariant vFlags; CComVariant vTarget(szTarget); CComVariant vPostData; CComVariant vHeaders; // Initialise postdata if (postData) { // According to the documentation. // The post data specified by PostData is passed as a SAFEARRAY // structure. The variant should be of type VT_ARRAY and point to // a SAFEARRAY. The SAFEARRAY should be of element type VT_UI1, // dimension one, and have an element count equal to the number of // bytes of post data. SAFEARRAYBOUND saBound[1]; saBound[0].lLbound = 0; saBound[0].cElements = len; vPostData.vt = VT_ARRAY | VT_UI1; vPostData.parray = SafeArrayCreate(VT_UI1, 1, saBound); SafeArrayLock(vPostData.parray); memcpy(vPostData.parray->pvData, postData, postDataLen); SafeArrayUnlock(vPostData.parray); } cpBrowser->Navigate(url, &vFlags, &vTarget, &vPostData, &vHeaders); // TODO listen to navigation & send a URL notify to plugin when completed return NPERR_NO_ERROR; } USES_CONVERSION; HRESULT hr = pWnd->OpenURLStream(A2CT(szURL), pNotifyData, postData, postDataLen); return SUCCEEDED(hr) ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR; }
/*! * @brief Convert a variant type to a string and write it to the given buffer. * @param v The variant to convert. * @param buffer Pointer to the buffer to write the value to. * @param bufferSize size of the buffer. * @returns Pointer to the next location in the buffer. * @remarks This attempts to "flatten" a variant, including array types. The implementation is * not 100% complete, but is good enough for the sake of this requirement. Only arrays * of BSTR are currenty supported, more types can be added later if needed. Arbitrary * array depth has been attempted, but no tests have yet found a nested array in the * result set. There's probably bugs in that bit. */ char* variant_to_string(_variant_t& v, char* buffer, DWORD bufferSize) { dprintf("[WMI] preparing to parse variant of type %u (%x), buffer size %u", v.vt, v.vt, bufferSize); switch (v.vt) { case VT_EMPTY: strncpy_s(buffer, bufferSize, "(EMPTY)", bufferSize - 1); break; case VT_NULL: strncpy_s(buffer, bufferSize, "(NULL)", bufferSize - 1); break; case VT_BOOL: strncpy_s(buffer, bufferSize, v.boolVal == VARIANT_TRUE ? "true" : "false", bufferSize - 1); break; case VT_I1: _snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRId8, (CHAR)v); break; case VT_I2: _snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRId16, (SHORT)v); break; case VT_INT: case VT_I4: _snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRId32, (INT)v); break; case VT_INT_PTR: case VT_I8: _snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRId64, (INT_PTR)v); break; case VT_UI1: _snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRIu8, (BYTE)v); break; case VT_UI2: _snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRIu16, (SHORT)v); break; case VT_UINT: case VT_UI4: _snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRIu32, (UINT)v); break; case VT_UINT_PTR: case VT_UI8: _snprintf_s(buffer, bufferSize, bufferSize - 1, "%"PRIu64, (UINT_PTR)v); break; case VT_BSTR: case VT_LPSTR: case VT_LPWSTR: // not sure if this is correct strncpy_s(buffer, bufferSize, (char*)(_bstr_t)v.bstrVal, bufferSize - 1); break; // TODO more types, such as floats, dates, etc. default: if ((v.vt & VT_ARRAY) == VT_ARRAY) { // nested array type, great. dprintf("[WMI] array type found!"); LPSAFEARRAY array = v.parray; HRESULT hResult; if (FAILED(hResult = SafeArrayLock(array))) { dprintf("[WMI] Failed to get array dimension: %x", hResult); break; } dprintf("[WMI] Field name array locked."); LONG* indices = NULL; LONG* bounds = NULL; do { VARTYPE varType; SafeArrayGetVartype(array, &varType); dprintf("[WMI] Array type %u (%x)", (ULONG)varType, (ULONG)varType); dprintf("[WMI] Array dimensions: %u", SafeArrayGetDim(array)); LONG iterations = 1; LONG dim = SafeArrayGetDim(array); indices = (LONG*)malloc(dim * sizeof(LONG)); bounds = (LONG*)malloc(dim * sizeof(LONG) * 2); memset(indices, 0, dim * sizeof(LONG)); memset(bounds, 0, dim * sizeof(LONG) * 2); for (LONG i = 0; i < dim; ++i) { LONG* lBound = bounds + i * 2; LONG* uBound = lBound + 1; if (FAILED(hResult = SafeArrayGetLBound(array, i + 1, lBound)) || FAILED(hResult = SafeArrayGetUBound(array, i + 1, uBound))) { dprintf("[WMI] Failed to get array dimensions: %x", hResult); break; } dprintf("[WMI] Array bounds: %u to %u", *lBound, *uBound); iterations *= *uBound - *lBound; indices[i] = *lBound; } dprintf("[WMI] Array requires %u iterations", iterations); // we're going to wrap our array elements in brackets, and separate with pipes // because we need some kind of array visualisation and this is the best I could // come up with at this time of night. Each dimension nests in a new set of brackets while (iterations-- > 0) { for (LONG i = 0; i < dim; ++i) { if (indices[i] == 0) { // save space for the closing bracket as well bufferSize -= 2; *buffer++ = '{'; dprintf("[WMI] opening bracket for dimension %u", i); } else if(*(buffer - 1) != '|') { --bufferSize; *buffer++ = '|'; } } dprintf("[WMI] extracting value for iteration %u", iterations); switch (varType) { case VT_BSTR: BSTR val; if (SUCCEEDED(SafeArrayGetElement(array, indices, (void*)&val))) { dprintf("[WMI] Value extracted for iteration %u", iterations); char* newBuf = variant_to_string(_variant_t(val), buffer, bufferSize); bufferSize -= (LONG)(newBuf - buffer + 1); buffer = newBuf; dprintf("[WMI] Value added", iterations); } break; default: dprintf("[WMI] Unsupported nested array type %u", (LONG)varType); break; } ++indices[dim - 1]; for (LONG i = dim - 1; i >= 0; --i) { if (indices[i] == bounds[i * 2 + 1]) { dprintf("[WMI] closing bracket for dimension %u", i); *buffer++ = '}'; indices[i] = bounds[i * 2]; if (i > 0) { ++indices[i - 1]; } } } } } while (0); if (indices) { free(indices); } if (bounds) { free(bounds); } SafeArrayUnlock(array); } else { dprintf("[WMI] Unhandled type: %u (%x)", v.vt, v.vt); } // ignore the buffer for other types break; } // return wherever we go to. return buffer + strlen(buffer); }
/*! * @brief Perform a WMI query. * @param lpwRoot Name of the root object that is to be queried against. * @param lpwQuery The filter to use when reading objects (LDAP style). * @param response The response \c Packet to add the results to. */ DWORD wmi_query(LPCWSTR lpwRoot, LPWSTR lpwQuery, Packet* response) { HRESULT hResult; dprintf("[WMI] Initialising COM"); if ((hResult = CoInitializeEx(NULL, COINIT_MULTITHREADED)) == S_OK) { dprintf("[WMI] COM initialised"); IWbemLocator* pLocator = NULL; IWbemServices* pServices = NULL; IEnumWbemClassObject* pEnumerator = NULL; IWbemClassObject* pSuperClass = NULL; IWbemClassObject* pObj = NULL; Tlv* valueTlvs = NULL; char* values = NULL; VARIANT** fields = NULL; do { if (FAILED(hResult = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0))) { dprintf("[WMI] Failed to initialize security: %x", hResult); break; } dprintf("[WMI] Security initialised"); if (FAILED(hResult = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pLocator)))) { dprintf("[WMI] Failed to create WbemLocator: %x", hResult); break; } dprintf("[WMI] WbemLocator created."); if (FAILED(hResult = pLocator->ConnectServer(_bstr_t(lpwRoot), NULL, NULL, NULL, WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pServices))) { dprintf("[WMI] Failed to create WbemServices at %S: %x", lpwRoot, hResult); break; } dprintf("[WMI] WbemServices created."); if (FAILED(hResult = pServices->ExecQuery(L"WQL", lpwQuery, WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator))) { dprintf("[WMI] Failed to create Enumerator for query %S: %x", lpwQuery, hResult); break; } dprintf("[WMI] Enumerated created."); ULONG numFound; if (FAILED(hResult = pEnumerator->Next(ENUM_TIMEOUT, 1, &pObj, &numFound))) { dprintf("[WMI] Failed to get the first query element: %x", lpwQuery, hResult); break; } dprintf("[WMI] First result read. hr=%x p=%p", hResult, pObj); if (hResult == WBEM_S_FALSE) { // this is not an error dprintf("[WMI] No results found!"); break; } // get the names of the fields out of the first object before doing anything else. LPSAFEARRAY pFieldArray = NULL; if (FAILED(hResult = pObj->GetNames(NULL, WBEM_FLAG_ALWAYS, NULL, &pFieldArray))) { dprintf("[WMI] Failed to get field names: %x", hResult); break; } dprintf("[WMI] Field Names extracted. hr=%x p=%p", hResult, pFieldArray); // lock the array if (FAILED(hResult = SafeArrayLock(pFieldArray))) { dprintf("[WMI] Failed to get array dimension: %x", hResult); break; } dprintf("[WMI] Field name array locked."); do { dprintf("[WMI] Array dimensions: %u", SafeArrayGetDim(pFieldArray)); // this array is just one dimension, let's get the bounds of the first dimension LONG lBound, uBound; if (FAILED(hResult = SafeArrayGetLBound(pFieldArray, 1, &lBound)) || FAILED(hResult = SafeArrayGetUBound(pFieldArray, 1, &uBound))) { dprintf("[WMI] Failed to get array dimensions: %x", hResult); break; } dprintf("[WMI] Bounds: %u to %u", lBound, uBound); LONG fieldCount = uBound - lBound - SYSTEM_FIELD_COUNT - 1; dprintf("[WMI] Query results in %u fields", fieldCount); fields = (VARIANT**)malloc(fieldCount * sizeof(VARIANT**)); valueTlvs = (Tlv*)malloc(fieldCount * sizeof(Tlv)); values = (char*)malloc(fieldCount * FIELD_SIZE); memset(fields, 0, fieldCount * sizeof(VARIANT**)); memset(valueTlvs, 0, fieldCount * sizeof(Tlv)); memset(values, 0, fieldCount * FIELD_SIZE); for (LONG i = 0; i < fieldCount; ++i) { LONG indices[1] = { i + SYSTEM_FIELD_COUNT }; char* fieldName = values + (i * FIELD_SIZE); SafeArrayPtrOfIndex(pFieldArray, indices, (void**)&fields[i]); _bstr_t bstr(fields[i]->bstrVal); strncpy_s(fieldName, FIELD_SIZE, (const char*)bstr, FIELD_SIZE - 1); valueTlvs[i].header.type = TLV_TYPE_EXT_WMI_FIELD; valueTlvs[i].header.length = (UINT)strlen(fieldName) + 1; valueTlvs[i].buffer = (PUCHAR)fieldName; dprintf("[WMI] Added header field: %s", fieldName); } dprintf("[WMI] added all field headers"); // add the field names to the packet packet_add_tlv_group(response, TLV_TYPE_EXT_WMI_FIELDS, valueTlvs, fieldCount); dprintf("[WMI] processing values..."); // with that horrible pain out of the way, let's actually grab the data do { if (FAILED(hResult)) { dprintf("[WMI] Loop exited via %x", hResult); break; } memset(valueTlvs, 0, fieldCount * sizeof(Tlv)); memset(values, 0, fieldCount * FIELD_SIZE); for (LONG i = 0; i < fieldCount; ++i) { char* value = values + (i * FIELD_SIZE); valueTlvs[i].header.type = TLV_TYPE_EXT_WMI_VALUE; valueTlvs[i].buffer = (PUCHAR)value; VARIANT varValue; VariantInit(&varValue); _bstr_t field(fields[i]->bstrVal); dprintf("[WMI] Extracting value for %s", (char*)field); if (SUCCEEDED(pObj->Get(field, 0, &varValue, NULL, NULL))) { variant_to_string(_variant_t(varValue), value, FIELD_SIZE); } valueTlvs[i].header.length = (UINT)strlen(value) + 1; dprintf("[WMI] Added value for %s: %s", (char*)_bstr_t(fields[i]->bstrVal), value); } // add the field values to the packet packet_add_tlv_group(response, TLV_TYPE_EXT_WMI_VALUES, valueTlvs, fieldCount); pObj->Release(); pObj = NULL; } while ((hResult = pEnumerator->Next(ENUM_TIMEOUT, 1, &pObj, &numFound)) != WBEM_S_FALSE); } while (0); SafeArrayUnlock(pFieldArray); } while (0); if (fields) { free(fields); } if (values) { free(values); } if (valueTlvs) { free(valueTlvs); } if (pObj) { pObj->Release(); } if (pEnumerator) { pEnumerator->Release(); } if (pServices) { pServices->Release(); } if (pLocator) { pLocator->Release(); } CoUninitialize(); if (SUCCEEDED(hResult)) { hResult = S_OK; dprintf("[WMI] Things appeard to go well!"); } } else { dprintf("[WMI] Failed to initialize COM"); } if (FAILED(hResult)) { // if we failed, we're going to convert the error to a string, add it and still return success, but we'll // also include the hresult. char errorMessage[1024]; memset(errorMessage, 0, 1024); _com_error comError(hResult); _snprintf_s(errorMessage, 1024, 1023, "%s (0x%x)", comError.ErrorMessage(), hResult); dprintf("[WMI] returning error -> %s", errorMessage); packet_add_tlv_string(response, TLV_TYPE_EXT_WMI_ERROR, errorMessage); hResult = S_OK; } return (DWORD)hResult; }
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; }
void SafeVariantArray::lock() { SafeArrayLock(pArray); }
/************************************************************************* * SafeArrayGetElement (OLEAUT32.25) * * Get an item from a SafeArray. * * PARAMS * psa [I] SafeArray to get from * rgIndices [I] Indices to get from * pvData [O] Destination for data * * RETURNS * Success: S_OK. The item data is returned in pvData. * Failure: An HRESULT error code indicating the error. * * NOTES * See SafeArray. */ HRESULT WINAPI SafeArrayGetElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData) { HRESULT hRet; TRACE("(%p,%p,%p)\n", psa, rgIndices, pvData); if (!psa || !rgIndices || !pvData) return E_INVALIDARG; hRet = SafeArrayLock(psa); if (SUCCEEDED(hRet)) { PVOID lpvSrc; hRet = SafeArrayPtrOfIndex(psa, rgIndices, &lpvSrc); if (SUCCEEDED(hRet)) { if (psa->fFeatures & FADF_VARIANT) { VARIANT* lpVariant = lpvSrc; VARIANT* lpDest = pvData; /* The original content of pvData is ignored. */ V_VT(lpDest) = VT_EMPTY; hRet = VariantCopy(lpDest, lpVariant); if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet); } else if (psa->fFeatures & FADF_BSTR) { BSTR* lpBstr = lpvSrc; BSTR* lpDest = pvData; if (*lpBstr) { *lpDest = SysAllocStringByteLen((char*)*lpBstr, SysStringByteLen(*lpBstr)); if (!*lpBstr) hRet = E_OUTOFMEMORY; } else *lpDest = NULL; } else if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) { IUnknown **src_unk = lpvSrc; IUnknown **dest_unk = pvData; if (*src_unk) IUnknown_AddRef(*src_unk); *dest_unk = *src_unk; } else if (psa->fFeatures & FADF_RECORD) { IRecordInfo *record; SafeArrayGetRecordInfo(psa, &record); hRet = IRecordInfo_RecordCopy(record, lpvSrc, pvData); IRecordInfo_Release(record); } else /* Copy the data over */ memcpy(pvData, lpvSrc, psa->cbElements); } SafeArrayUnlock(psa); } return hRet; }
/************************************************************************* * SafeArrayPutElement (OLEAUT32.26) * * Put an item into a SafeArray. * * PARAMS * psa [I] SafeArray to insert into * rgIndices [I] Indices to insert at * pvData [I] Data to insert * * RETURNS * Success: S_OK. The item is inserted * Failure: An HRESULT error code indicating the error. * * NOTES * See SafeArray. */ HRESULT WINAPI SafeArrayPutElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData) { HRESULT hRet; TRACE("(%p,%p,%p)\n", psa, rgIndices, pvData); if (!psa || !rgIndices) return E_INVALIDARG; hRet = SafeArrayLock(psa); if (SUCCEEDED(hRet)) { PVOID lpvDest; hRet = SafeArrayPtrOfIndex(psa, rgIndices, &lpvDest); if (SUCCEEDED(hRet)) { if (psa->fFeatures & FADF_VARIANT) { VARIANT* lpVariant = pvData; VARIANT* lpDest = lpvDest; hRet = VariantCopy(lpDest, lpVariant); if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%x\n", hRet); } else if (psa->fFeatures & FADF_BSTR) { BSTR lpBstr = (BSTR)pvData; BSTR* lpDest = lpvDest; SysFreeString(*lpDest); *lpDest = SysAllocStringByteLen((char*)lpBstr, SysStringByteLen(lpBstr)); if (!*lpDest) hRet = E_OUTOFMEMORY; } else if (psa->fFeatures & (FADF_UNKNOWN|FADF_DISPATCH)) { IUnknown *lpUnknown = pvData; IUnknown **lpDest = lpvDest; if (lpUnknown) IUnknown_AddRef(lpUnknown); if (*lpDest) IUnknown_Release(*lpDest); *lpDest = lpUnknown; } else if (psa->fFeatures & FADF_RECORD) { IRecordInfo *record; SafeArrayGetRecordInfo(psa, &record); hRet = IRecordInfo_RecordCopy(record, pvData, lpvDest); IRecordInfo_Release(record); } else /* Copy the data over */ memcpy(lpvDest, pvData, psa->cbElements); } SafeArrayUnlock(psa); } return hRet; }
/************************************************************************ * SafeArrayRedim (OLEAUT32.40) * * Changes the characteristics of the last dimension of a SafeArray * * PARAMS * psa [I] Array to change * psabound [I] New bound details for the last dimension * * RETURNS * Success: S_OK. psa is updated to reflect the new bounds. * Failure: An HRESULT error code indicating the error. * * NOTES * See SafeArray. */ HRESULT WINAPI SafeArrayRedim(SAFEARRAY *psa, SAFEARRAYBOUND *psabound) { SAFEARRAYBOUND *oldBounds; HRESULT hr; TRACE("(%p,%p)\n", psa, psabound); if (!psa || psa->fFeatures & FADF_FIXEDSIZE || !psabound) return E_INVALIDARG; if (psa->cLocks > 0) return DISP_E_ARRAYISLOCKED; hr = SafeArrayLock(psa); if (FAILED(hr)) return hr; oldBounds = psa->rgsabound; oldBounds->lLbound = psabound->lLbound; if (psabound->cElements != oldBounds->cElements) { if (psabound->cElements < oldBounds->cElements) { /* Shorten the final dimension. */ ULONG ulStartCell = psabound->cElements * (SAFEARRAY_GetCellCount(psa) / oldBounds->cElements); SAFEARRAY_DestroyData(psa, ulStartCell); } else { /* Lengthen the final dimension */ ULONG ulOldSize, ulNewSize; PVOID pvNewData; ulOldSize = SAFEARRAY_GetCellCount(psa) * psa->cbElements; if (ulOldSize) ulNewSize = (ulOldSize / oldBounds->cElements) * psabound->cElements; else { int oldelems = oldBounds->cElements; oldBounds->cElements = psabound->cElements; ulNewSize = SAFEARRAY_GetCellCount(psa) * psa->cbElements; oldBounds->cElements = oldelems; } if (!(pvNewData = SAFEARRAY_Malloc(ulNewSize))) { SafeArrayUnlock(psa); return E_OUTOFMEMORY; } memcpy(pvNewData, psa->pvData, ulOldSize); SAFEARRAY_Free(psa->pvData); psa->pvData = pvNewData; } oldBounds->cElements = psabound->cElements; } SafeArrayUnlock(psa); return S_OK; }