void Parse_MTP::mtp_do_storage(bool clear) { IPortableDevice *pd; IPortableDeviceValues *pdv; IPortableDeviceContent *pdc = NULL; HRESULT hr; hr = CoCreateInstance(CLSID_PortableDevice, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDevice, (VOID**)&pd); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("mtp_do_storage: Failed to create IPortableDevice: %1") .arg(hr, 0, 16)); return; } hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**)&pdv); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("mtp_do_storage: Failed to create IPortableDeviceValues: %1") .arg(hr, 0, 16)); return; } for (int i = 0; i < mtp_devices.size(); i++) { // after this we're creating objects which need to be cleaned up. hr = pd->Open(mtp_devices[i], pdv); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("mtp_do_storage: Failed to open IPortableDevice: %1") .arg(hr, 0, 16)); goto mtp_do_storage_cleanup; } hr = pd->Content(&pdc); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("mtp_do_storage: Failed to retrieve content from IPortableDevice: %1") .arg(hr, 0, 16)); goto mtp_do_storage_cleanup; } mtp_recurse_storage(WPD_DEVICE_OBJECT_ID, pdc, clear); mtp_do_storage_cleanup: if (pdc) { pdc->Release(); pdc = NULL; } if (pdv) { pdv->Release(); pdv = NULL; } pd->Close(); } }
/////////////////////////////////////////////////////////////////////////////// // // CSensorManagerEvents::ChangeSensitivity // // Description of function/method: // Tweaks the sensors sensitivity // // Parameters: // ISensor* pSensor: Sensor to be set // // Return Values: // S_OK on success, else an error // /////////////////////////////////////////////////////////////////////////////// HRESULT CSensorManagerEvents::ChangeSensitivity(ISensor* pSensor) { HRESULT hr = S_OK; IPortableDeviceValues* pPropsToSet = NULL; // Input IPortableDeviceValues* pPropsReturn = NULL; // Output // Create the input object. hr = CoCreateInstance(__uuidof(PortableDeviceValues), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pPropsToSet)); if(SUCCEEDED(hr)) { // Add the current report interval property. hr = pPropsToSet->SetUnsignedIntegerValue(SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, 30); } if(SUCCEEDED(hr)) { // Only setting a single property, here. hr = pSensor->SetProperties(pPropsToSet, &pPropsReturn); } // Test for failure. if(hr == S_FALSE) { HRESULT hrError = S_OK; // Check results for failure. hr = pPropsReturn->GetErrorValue(SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, &hrError); if(SUCCEEDED(hr)) { // Print an error message. WCHAR szBuffer[256]; // Print an error message. swprintf_s(szBuffer,256,L"\nSetting current report interval failed with error 0x%X\n", hrError); OutputDebugString(szBuffer); // Return the error code. hr = hrError; } } else if(hr == E_ACCESSDENIED) { // No permission. Take appropriate action. } pPropsToSet->Release(); pPropsReturn->Release(); return hr; }
PyObject* get_storage_info(IPortableDevice *device) { // {{{ HRESULT hr, hr2; IPortableDeviceContent *content = NULL; IEnumPortableDeviceObjectIDs *objects = NULL; IPortableDeviceProperties *properties = NULL; IPortableDeviceKeyCollection *storage_properties = NULL; IPortableDeviceValues *values = NULL; PyObject *ans = NULL, *storage = NULL, *so = NULL, *desc = NULL, *soid = NULL; DWORD fetched, i; PWSTR object_ids[10]; GUID guid; ULONGLONG capacity, free_space, capacity_objects, free_objects; ULONG access, storage_type = WPD_STORAGE_TYPE_UNDEFINED; LPWSTR storage_desc = NULL, st = NULL; storage = PyList_New(0); if (storage == NULL) { PyErr_NoMemory(); goto end; } Py_BEGIN_ALLOW_THREADS; hr = device->Content(&content); Py_END_ALLOW_THREADS; if (FAILED(hr)) {hresult_set_exc("Failed to get content interface from device", hr); goto end;} Py_BEGIN_ALLOW_THREADS; hr = content->Properties(&properties); Py_END_ALLOW_THREADS; if (FAILED(hr)) {hresult_set_exc("Failed to get properties interface", hr); goto end;} Py_BEGIN_ALLOW_THREADS; hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&storage_properties)); Py_END_ALLOW_THREADS; if (FAILED(hr)) {hresult_set_exc("Failed to create storage properties collection", hr); goto end;} Py_BEGIN_ALLOW_THREADS; hr = storage_properties->Add(WPD_OBJECT_CONTENT_TYPE); hr = storage_properties->Add(WPD_FUNCTIONAL_OBJECT_CATEGORY); hr = storage_properties->Add(WPD_STORAGE_DESCRIPTION); hr = storage_properties->Add(WPD_STORAGE_CAPACITY); hr = storage_properties->Add(WPD_STORAGE_CAPACITY_IN_OBJECTS); hr = storage_properties->Add(WPD_STORAGE_FREE_SPACE_IN_BYTES); hr = storage_properties->Add(WPD_STORAGE_FREE_SPACE_IN_OBJECTS); hr = storage_properties->Add(WPD_STORAGE_ACCESS_CAPABILITY); hr = storage_properties->Add(WPD_STORAGE_FILE_SYSTEM_TYPE); hr = storage_properties->Add(WPD_STORAGE_TYPE); hr = storage_properties->Add(WPD_OBJECT_NAME); Py_END_ALLOW_THREADS; if (FAILED(hr)) {hresult_set_exc("Failed to create collection of properties for storage query", hr); goto end; } Py_BEGIN_ALLOW_THREADS; hr = content->EnumObjects(0, WPD_DEVICE_OBJECT_ID, NULL, &objects); Py_END_ALLOW_THREADS; if (FAILED(hr)) {hresult_set_exc("Failed to get objects from device", hr); goto end;} hr = S_OK; while (hr == S_OK) { Py_BEGIN_ALLOW_THREADS; hr = objects->Next(10, object_ids, &fetched); Py_END_ALLOW_THREADS; if (SUCCEEDED(hr)) { for(i = 0; i < fetched; i++) { Py_BEGIN_ALLOW_THREADS; hr2 = properties->GetValues(object_ids[i], storage_properties, &values); Py_END_ALLOW_THREADS; if SUCCEEDED(hr2) { if ( SUCCEEDED(values->GetGuidValue(WPD_OBJECT_CONTENT_TYPE, &guid)) && IsEqualGUID(guid, WPD_CONTENT_TYPE_FUNCTIONAL_OBJECT) && SUCCEEDED(values->GetGuidValue(WPD_FUNCTIONAL_OBJECT_CATEGORY, &guid)) && IsEqualGUID(guid, WPD_FUNCTIONAL_CATEGORY_STORAGE) ) { capacity = 0; capacity_objects = 0; free_space = 0; free_objects = 0; values->GetUnsignedLargeIntegerValue(WPD_STORAGE_CAPACITY, &capacity); values->GetUnsignedLargeIntegerValue(WPD_STORAGE_CAPACITY_IN_OBJECTS, &capacity_objects); values->GetUnsignedLargeIntegerValue(WPD_STORAGE_FREE_SPACE_IN_BYTES, &free_space); values->GetUnsignedLargeIntegerValue(WPD_STORAGE_FREE_SPACE_IN_OBJECTS, &free_objects); values->GetUnsignedIntegerValue(WPD_STORAGE_TYPE, &storage_type); desc = Py_False; if (SUCCEEDED(values->GetUnsignedIntegerValue(WPD_STORAGE_ACCESS_CAPABILITY, &access)) && access == WPD_STORAGE_ACCESS_CAPABILITY_READWRITE) desc = Py_True; soid = PyUnicode_FromWideChar(object_ids[i], wcslen(object_ids[i])); if (soid == NULL) { PyErr_NoMemory(); goto end; } so = Py_BuildValue("{s:K, s:K, s:K, s:K, s:O, s:N}", "capacity", capacity, "capacity_objects", capacity_objects, "free_space", free_space, "free_objects", free_objects, "rw", desc, "id", soid); if (so == NULL) { PyErr_NoMemory(); goto end; } if (SUCCEEDED(values->GetStringValue(WPD_STORAGE_DESCRIPTION, &storage_desc))) { desc = PyUnicode_FromWideChar(storage_desc, wcslen(storage_desc)); if (desc != NULL) { PyDict_SetItemString(so, "description", desc); Py_DECREF(desc);} CoTaskMemFree(storage_desc); storage_desc = NULL; } if (SUCCEEDED(values->GetStringValue(WPD_OBJECT_NAME, &storage_desc))) { desc = PyUnicode_FromWideChar(storage_desc, wcslen(storage_desc)); if (desc != NULL) { PyDict_SetItemString(so, "name", desc); Py_DECREF(desc);} CoTaskMemFree(storage_desc); storage_desc = NULL; } if (SUCCEEDED(values->GetStringValue(WPD_STORAGE_FILE_SYSTEM_TYPE, &storage_desc))) { desc = PyUnicode_FromWideChar(storage_desc, wcslen(storage_desc)); if (desc != NULL) { PyDict_SetItemString(so, "filesystem", desc); Py_DECREF(desc);} CoTaskMemFree(storage_desc); storage_desc = NULL; } switch(storage_type) { case WPD_STORAGE_TYPE_REMOVABLE_RAM: st = L"removable_ram"; break; case WPD_STORAGE_TYPE_REMOVABLE_ROM: st = L"removable_rom"; break; case WPD_STORAGE_TYPE_FIXED_RAM: st = L"fixed_ram"; break; case WPD_STORAGE_TYPE_FIXED_ROM: st = L"fixed_rom"; break; default: st = L"unknown_unknown"; } desc = PyUnicode_FromWideChar(st, wcslen(st)); if (desc != NULL) {PyDict_SetItemString(so, "type", desc); Py_DECREF(desc);} desc = NULL; PyList_Append(storage, so); Py_DECREF(so); } } } for (i = 0; i < fetched; i ++) { CoTaskMemFree(object_ids[i]); object_ids[i] = NULL;} }// if(SUCCEEDED(hr)) } ans = storage; end: if (content != NULL) content->Release(); if (objects != NULL) objects->Release(); if (properties != NULL) properties->Release(); if (storage_properties != NULL) storage_properties->Release(); if (values != NULL) values->Release(); return ans; } // }}}
PyObject* get_device_information(IPortableDevice *device, IPortableDevicePropertiesBulk **pb) { // {{{ IPortableDeviceContent *content = NULL; IPortableDeviceProperties *properties = NULL; IPortableDevicePropertiesBulk *properties_bulk = NULL; IPortableDeviceKeyCollection *keys = NULL; IPortableDeviceValues *values = NULL; IPortableDeviceCapabilities *capabilities = NULL; IPortableDevicePropVariantCollection *categories = NULL; HRESULT hr; DWORD num_of_categories, i; LPWSTR temp; ULONG ti; PyObject *t, *ans = NULL, *storage = NULL; const char *type = NULL; Py_BEGIN_ALLOW_THREADS; hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&keys)); Py_END_ALLOW_THREADS; if (FAILED(hr)) {hresult_set_exc("Failed to create IPortableDeviceKeyCollection", hr); goto end;} Py_BEGIN_ALLOW_THREADS; hr = keys->Add(WPD_DEVICE_PROTOCOL); // Despite the MSDN documentation, this does not exist in PortableDevice.h // hr = keys->Add(WPD_DEVICE_TRANSPORT); hr = keys->Add(WPD_DEVICE_FRIENDLY_NAME); hr = keys->Add(WPD_DEVICE_MANUFACTURER); hr = keys->Add(WPD_DEVICE_MODEL); hr = keys->Add(WPD_DEVICE_SERIAL_NUMBER); hr = keys->Add(WPD_DEVICE_FIRMWARE_VERSION); hr = keys->Add(WPD_DEVICE_TYPE); Py_END_ALLOW_THREADS; if (FAILED(hr)) {hresult_set_exc("Failed to add keys to IPortableDeviceKeyCollection", hr); goto end;} Py_BEGIN_ALLOW_THREADS; hr = device->Content(&content); Py_END_ALLOW_THREADS; if (FAILED(hr)) {hresult_set_exc("Failed to get IPortableDeviceContent", hr); goto end; } Py_BEGIN_ALLOW_THREADS; hr = content->Properties(&properties); Py_END_ALLOW_THREADS; if (FAILED(hr)) {hresult_set_exc("Failed to get IPortableDeviceProperties", hr); goto end; } Py_BEGIN_ALLOW_THREADS; hr = properties->GetValues(WPD_DEVICE_OBJECT_ID, keys, &values); Py_END_ALLOW_THREADS; if(FAILED(hr)) {hresult_set_exc("Failed to get device info", hr); goto end; } Py_BEGIN_ALLOW_THREADS; hr = device->Capabilities(&capabilities); Py_END_ALLOW_THREADS; if(FAILED(hr)) {hresult_set_exc("Failed to get device capabilities", hr); goto end; } Py_BEGIN_ALLOW_THREADS; hr = capabilities->GetFunctionalCategories(&categories); Py_END_ALLOW_THREADS; if(FAILED(hr)) {hresult_set_exc("Failed to get device functional categories", hr); goto end; } Py_BEGIN_ALLOW_THREADS; hr = categories->GetCount(&num_of_categories); Py_END_ALLOW_THREADS; if(FAILED(hr)) {hresult_set_exc("Failed to get device functional categories number", hr); goto end; } ans = PyDict_New(); if (ans == NULL) {PyErr_NoMemory(); goto end;} if (SUCCEEDED(values->GetStringValue(WPD_DEVICE_PROTOCOL, &temp))) { t = PyUnicode_FromWideChar(temp, wcslen(temp)); if (t != NULL) {PyDict_SetItemString(ans, "protocol", t); Py_DECREF(t);} CoTaskMemFree(temp); } // if (SUCCEEDED(values->GetUnsignedIntegerValue(WPD_DEVICE_TRANSPORT, &ti))) { // PyDict_SetItemString(ans, "isusb", (ti == WPD_DEVICE_TRANSPORT_USB) ? Py_True : Py_False); // t = PyLong_FromUnsignedLong(ti); // } if (SUCCEEDED(values->GetUnsignedIntegerValue(WPD_DEVICE_TYPE, &ti))) { switch (ti) { case WPD_DEVICE_TYPE_CAMERA: type = "camera"; break; case WPD_DEVICE_TYPE_MEDIA_PLAYER: type = "media player"; break; case WPD_DEVICE_TYPE_PHONE: type = "phone"; break; case WPD_DEVICE_TYPE_VIDEO: type = "video"; break; case WPD_DEVICE_TYPE_PERSONAL_INFORMATION_MANAGER: type = "personal information manager"; break; case WPD_DEVICE_TYPE_AUDIO_RECORDER: type = "audio recorder"; break; default: type = "unknown"; } #if PY_MAJOR_VERSION >= 3 t = PyUnicode_FromString(type); #else t = PyString_FromString(type); #endif if (t != NULL) { PyDict_SetItemString(ans, "type", t); Py_DECREF(t); } } if (SUCCEEDED(values->GetStringValue(WPD_DEVICE_FRIENDLY_NAME, &temp))) { t = PyUnicode_FromWideChar(temp, wcslen(temp)); if (t != NULL) {PyDict_SetItemString(ans, "friendly_name", t); Py_DECREF(t);} CoTaskMemFree(temp); } if (SUCCEEDED(values->GetStringValue(WPD_DEVICE_MANUFACTURER, &temp))) { t = PyUnicode_FromWideChar(temp, wcslen(temp)); if (t != NULL) {PyDict_SetItemString(ans, "manufacturer_name", t); Py_DECREF(t);} CoTaskMemFree(temp); } if (SUCCEEDED(values->GetStringValue(WPD_DEVICE_MODEL, &temp))) { t = PyUnicode_FromWideChar(temp, wcslen(temp)); if (t != NULL) {PyDict_SetItemString(ans, "model_name", t); Py_DECREF(t);} CoTaskMemFree(temp); } if (SUCCEEDED(values->GetStringValue(WPD_DEVICE_SERIAL_NUMBER, &temp))) { t = PyUnicode_FromWideChar(temp, wcslen(temp)); if (t != NULL) {PyDict_SetItemString(ans, "serial_number", t); Py_DECREF(t);} CoTaskMemFree(temp); } if (SUCCEEDED(values->GetStringValue(WPD_DEVICE_FIRMWARE_VERSION, &temp))) { t = PyUnicode_FromWideChar(temp, wcslen(temp)); if (t != NULL) {PyDict_SetItemString(ans, "device_version", t); Py_DECREF(t);} CoTaskMemFree(temp); } t = Py_False; for (i = 0; i < num_of_categories; i++) { PROPVARIANT pv; PropVariantInit(&pv); if (SUCCEEDED(categories->GetAt(i, &pv)) && pv.puuid != NULL) { if (IsEqualGUID(WPD_FUNCTIONAL_CATEGORY_STORAGE, *pv.puuid)) { t = Py_True; } } PropVariantClear(&pv); if (t == Py_True) break; } PyDict_SetItemString(ans, "has_storage", t); if (t == Py_True) { storage = get_storage_info(device); if (storage == NULL) { PyObject *exc_type, *exc_value, *exc_tb; PyErr_Fetch(&exc_type, &exc_value, &exc_tb); if (exc_type != NULL && exc_value != NULL) { PyErr_NormalizeException(&exc_type, &exc_value, &exc_tb); PyDict_SetItemString(ans, "storage_error", exc_value); Py_DECREF(exc_value); exc_value = NULL; } Py_XDECREF(exc_type); Py_XDECREF(exc_value); Py_XDECREF(exc_tb); goto end; } PyDict_SetItemString(ans, "storage", storage); } Py_BEGIN_ALLOW_THREADS; hr = properties->QueryInterface(IID_PPV_ARGS(&properties_bulk)); Py_END_ALLOW_THREADS; PyDict_SetItemString(ans, "has_bulk_properties", (FAILED(hr)) ? Py_False: Py_True); if (pb != NULL) *pb = (SUCCEEDED(hr)) ? properties_bulk : NULL; end: if (keys != NULL) keys->Release(); if (values != NULL) values->Release(); if (properties != NULL) properties->Release(); if (properties_bulk != NULL && pb == NULL) properties_bulk->Release(); if (content != NULL) content->Release(); if (capabilities != NULL) capabilities->Release(); if (categories != NULL) categories->Release(); return ans; } // }}}
VOID HealthThermometerServiceContent::TemperatureMeasurementEvent( _In_ BTH_LE_GATT_EVENT_TYPE EventType, _In_ PVOID EventOutParameter ) { HRESULT hr = S_OK; PBLUETOOTH_GATT_VALUE_CHANGED_EVENT ValueChangedEventParameters = NULL; TEMPERATURE_MEASUREMENT Measurement = {0}; IPortableDeviceValues * pEventParams = NULL; BYTE* pBuffer = NULL; DWORD cbBuffer = 0; if (CharacteristicValueChangedEvent != EventType) { return; } ValueChangedEventParameters = (PBLUETOOTH_GATT_VALUE_CHANGED_EVENT)EventOutParameter; // // Our value is at least 5 bytes // if (5 > ValueChangedEventParameters->CharacteristicValue->DataSize) { hr = E_FAIL; CHECK_HR(hr, "Invalid data size: %d, expencting at least 5 bytes", ValueChangedEventParameters->CharacteristicValue->DataSize); } if (SUCCEEDED(hr)) { ULONG mantissa = 0; LONG exponent = 0; mantissa = (ULONG)(((ULONG)ValueChangedEventParameters->CharacteristicValue->Data[3] << (ULONG)16) | ((ULONG)ValueChangedEventParameters->CharacteristicValue->Data[2] << (ULONG)8) | ((ULONG)ValueChangedEventParameters->CharacteristicValue->Data[1] << (ULONG)0)); exponent = 0xFFFFFF00 | (LONG)ValueChangedEventParameters->CharacteristicValue->Data[4]; Measurement.Value = (double)mantissa * pow((double)10.0, (double)exponent); TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FLAG_DEVICE, "Received a value change event, new value [%.2f]", Measurement.Value); } // // Get the timestamp // if (SUCCEEDED(hr)) { FILETIME fTime; GetSystemTimeAsFileTime(&fTime); ConvertFileTimeToUlonglong(&fTime, &Measurement.TimeStamp); } // // CoCreate a collection to store the property set event parameters. // if (SUCCEEDED(hr)) { hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**) &pEventParams); CHECK_HR(hr, "Failed to CoCreateInstance CLSID_PortableDeviceValues"); } if (SUCCEEDED(hr)) { hr = pEventParams->SetGuidValue(WPD_EVENT_PARAMETER_EVENT_ID, EVENT_HealthThermometerService_TemperatureMeasurement); CHECK_HR(hr, "Failed to add WPD_EVENT_PARAMETER_EVENT_ID"); } // // Set the timestamp // if (SUCCEEDED(hr)) { hr = pEventParams->SetUnsignedLargeIntegerValue(EVENT_PARAMETER_HealthTemperatureService_Measurement_TimeStamp, Measurement.TimeStamp); CHECK_HR(hr, "Failed to add EVENT_PARAMETER_HealthTemperatureService_Measurement_TimeStamp"); } // // Set the measurement Value // if (SUCCEEDED(hr)) { hr = pEventParams->SetFloatValue(EVENT_PARAMETER_HealthTemperatureService_Measurement_Value, (float)Measurement.Value); CHECK_HR(hr, "Failed to add EVENT_PARAMETER_HealthTemperatureService_Measurement_Value"); } // // Adding this event parameter will allow WPD to scope this event to the container functional object // if (SUCCEEDED(hr)) { hr = pEventParams->SetStringValue(WPD_EVENT_PARAMETER_OBJECT_PARENT_PERSISTENT_UNIQUE_ID, ParentPersistentUniqueID); CHECK_HR(hr, "Failed to add WPD_EVENT_PARAMETER_OBJECT_PARENT_PERSISTENT_UNIQUE_ID"); } // // Adding this event parameter will allow WPD to scope this event to the container functional object // if (SUCCEEDED(hr)) { hr = pEventParams->SetStringValue(WPD_OBJECT_CONTAINER_FUNCTIONAL_OBJECT_ID, SERVICE_OBJECT_ID); CHECK_HR(hr, "Failed to add WPD_OBJECT_CONTAINER_FUNCTIONAL_OBJECT_ID"); } // // Create a buffer with the serialized parameters // if (SUCCEEDED(hr)) { hr = m_pWpdSerializer->GetBufferFromIPortableDeviceValues(pEventParams, &pBuffer, &cbBuffer); CHECK_HR(hr, "Failed to get buffer from IPortableDeviceValues"); } if (SUCCEEDED(hr) && NULL == pBuffer) { hr = E_FAIL; CHECK_HR(hr, "pBuffer is NULL"); } // // Send the event // if (SUCCEEDED(hr)) { hr = m_pDevice->PostEvent(WPD_EVENT_NOTIFICATION, WdfEventBroadcast, pBuffer, cbBuffer); CHECK_HR(hr, "Failed to post WPD (broadcast) event"); } // // Cleanup // if (NULL != pBuffer) { CoTaskMemFree(pBuffer); pBuffer = NULL; } if (NULL != pEventParams) { pEventParams->Release(); pEventParams = NULL; } }
void Parse_MTP::mtp_get_metadata(PCWSTR object_id, IPortableDeviceContent *pdc, bool clear) { IPortableDeviceValues *pdv; IPortableDeviceKeyCollection *pdkc; IPortableDeviceProperties *pdp = NULL; HRESULT hr; scrob_entry new_entry; LPWSTR album = NULL; LPWSTR artist = NULL; LPWSTR name = NULL; ULONG usecount; ULONG skipcount; ULONG tracknum; ULONGLONG duration; PROPVARIANT date; new_entry.length = 0; hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**)&pdv); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("mtp_get_metadata: Failed to create IPortableDeviceValues: %1") .arg(hr, 0, 16)); return; } hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceKeyCollection, (VOID**)&pdkc); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("mtp_get_metadata: Failed to create IPortableDeviceKeyCollection: %1") .arg(hr, 0, 16)); return; } hr = pdc->Properties(&pdp); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("mtp_get_metadata: Failed to get properties from IPortableDeviceContent: %1") .arg(hr, 0, 16)); goto mtp_get_metadata_cleanup; } hr = pdkc->Add(WPD_MEDIA_USE_COUNT); //VT_UI4 hr = pdkc->Add(WPD_MEDIA_SKIP_COUNT); //VT_UI4 hr = pdkc->Add(WPD_MEDIA_LAST_ACCESSED_TIME); //VT_DATE hr = pdkc->Add(WPD_MUSIC_ALBUM); //VT_LPWSTR hr = pdkc->Add(WPD_MUSIC_TRACK); //VT_UI4 hr = pdkc->Add(WPD_MEDIA_DURATION); //VT_UI8, in milliseconds hr = pdkc->Add(WPD_OBJECT_NAME); //VT_LPWSTR hr = pdkc->Add(WPD_MEDIA_ARTIST); //VT_LPWSTR if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("mtp_get_metadata: Failed to add to IPortableDeviceKeyCollection: %1") .arg(hr, 0, 16)); goto mtp_get_metadata_cleanup; } hr = pdp->GetValues(object_id, pdkc, &pdv); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("mtp_get_metadata: Failed to get values from IPortableDeviceProperties: %1") .arg(hr, 0, 16)); goto mtp_get_metadata_cleanup; } hr = pdv->GetStringValue(WPD_MUSIC_ALBUM, &album); if (SUCCEEDED(hr)) new_entry.album = QString::fromStdWString(album); hr = pdv->GetStringValue(WPD_MEDIA_ARTIST, &artist); if (SUCCEEDED(hr)) new_entry.artist = QString::fromStdWString(artist); hr = pdv->GetStringValue(WPD_OBJECT_NAME, &name); if (SUCCEEDED(hr)) new_entry.title = QString::fromStdWString(name); hr = pdv->GetUnsignedIntegerValue(WPD_MEDIA_USE_COUNT, &usecount); hr = pdv->GetUnsignedIntegerValue(WPD_MEDIA_SKIP_COUNT, &skipcount); hr = pdv->GetUnsignedIntegerValue(WPD_MUSIC_TRACK, &tracknum); if (SUCCEEDED(hr)) new_entry.tracknum = tracknum; hr = pdv->GetUnsignedLargeIntegerValue(WPD_MEDIA_DURATION, &duration); if (SUCCEEDED(hr)) new_entry.length = duration/1000; hr = pdv->GetValue(WPD_MEDIA_LAST_ACCESSED_TIME, &date); if (SUCCEEDED(hr)) { SYSTEMTIME st; VariantTimeToSystemTime(date.date, &st); PropVariantClear(&date); QDate d = QDate(st.wYear, st.wMonth, st.wDay); QTime t = QTime(st.wHour, st.wMinute, st.wSecond); new_entry.when = QDateTime(d, t).toTime_t() - tz_offset; // Not all MTP devices provide a valid result for // WPD_MEDIA_LAST_ACCESSED_TIME, so sanity check it // are we within (+/-) 30 days? long offset = new_entry.when - QDateTime::currentDateTime().toTime_t(); if (abs(offset) > 2592000) new_entry.when = 0; } emit add_log(LOG_TRACE, QString("%1 : %2 : %3 : %4 : %5 : %6 : %7") .arg(new_entry.artist) .arg(new_entry.title) .arg(new_entry.album) .arg(new_entry.tracknum) .arg(new_entry.length) .arg(usecount) .arg(skipcount) ); tracks++; if (usecount > 0 && new_entry.artist.length() && new_entry.title.length()) { if (clear) { IPortableDeviceValues *pdv_clear = NULL; hr = pdv->Clear(); hr = pdv->SetUnsignedIntegerValue(WPD_MEDIA_USE_COUNT, 0); hr = pdp->SetValues(object_id, pdv, &pdv_clear); if (SUCCEEDED(hr)) { if (pdv_clear != NULL) pdv_clear->Clear(); pdv_clear = NULL; } } else { playcounts++; new_entry.played = 'L'; for (ULONG i = 0; i < usecount; i++) { entries++; // Only use the last playcount for one instance // we'll recalc the rest afterwards // via Scrobble::check_timestamps() if (i > 1) new_entry.when = 0; emit entry(new_entry); } } } mtp_get_metadata_cleanup: if (album) CoTaskMemFree(album); if (artist) CoTaskMemFree(artist); if (name) CoTaskMemFree(name); if (pdp) { pdp->Release(); pdp = NULL; } if (pdv) { pdv->Release(); pdv = NULL; } }
bool Parse_MTP::is_device_mtp(DWORD index, LPCWSTR device_id) { bool is_mtp = false; IPortableDevice *pd; IPortableDeviceValues *pdv; IPortableDeviceKeyCollection *pdkc; IPortableDeviceProperties *pdp = NULL; IPortableDeviceContent *pdc = NULL; HRESULT hr; LPWSTR dev_protocol = NULL; QString mtp; hr = CoCreateInstance(CLSID_PortableDevice, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDevice, (VOID**)&pd); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("is_device_mtp: Failed to create IPortableDevice: %1") .arg(hr, 0, 16)); return false; } hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**)&pdv); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("is_device_mtp: Failed to create IPortableDeviceValues: %1") .arg(hr, 0, 16)); return false; } hr = CoCreateInstance(CLSID_PortableDeviceKeyCollection, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceKeyCollection, (VOID**)&pdkc); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("is_device_mtp: Failed to create IPortableDeviceKeyCollection: %1") .arg(hr, 0, 16)); return false; } // after this we're creating objects which need to be cleaned up. hr = pd->Open(device_id, pdv); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("is_device_mtp: Failed to open IPortableDevice: %1") .arg(hr, 0, 16)); goto is_mtp_cleanup; } hr = pd->Content(&pdc); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("is_device_mtp: Failed to retrieve content from IPortableDevice: %1") .arg(hr, 0, 16)); goto is_mtp_cleanup; } hr = pdc->Properties(&pdp); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("is_device_mtp: Failed to get properties from IPortableDeviceContent: %1") .arg(hr, 0, 16)); goto is_mtp_cleanup; } hr = pdkc->Add(WPD_DEVICE_PROTOCOL); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("is_device_mtp: Failed to add to IPortableDeviceKeyCollection: %1") .arg(hr, 0, 16)); goto is_mtp_cleanup; } // WPD_DEVICE_OBJECT_ID is the top level object hr = pdp->GetValues(WPD_DEVICE_OBJECT_ID, pdkc, &pdv); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("is_device_mtp: Failed to get values from IPortableDeviceProperties: %1") .arg(hr, 0, 16)); goto is_mtp_cleanup; } hr = pdv->GetStringValue(WPD_DEVICE_PROTOCOL, &dev_protocol); if (FAILED(hr)) { emit add_log(LOG_ERROR, QString("is_device_mtp: Failed to GetStringValue: %1") .arg(hr, 0, 16)); goto is_mtp_cleanup; } mtp = QString::fromStdWString(dev_protocol); emit add_log(LOG_INFO, QString("Device %1: %2").arg(index).arg(mtp)); if (mtp.startsWith("MTP")) { is_mtp = true; emit add_log(LOG_INFO, QString("Device %1: Is a MTP device").arg(index)); } is_mtp_cleanup: if (dev_protocol) CoTaskMemFree(dev_protocol); if (pdc) { pdc->Release(); pdc = NULL; } if (pdp) { pdp->Release(); pdp = NULL; } if (pdv) { pdv->Release(); pdv = NULL; } return is_mtp; }
JNIEXPORT jstring JNICALL Java_jmtp_PortableDeviceContentImplWin32_createObjectWithPropertiesAndData (JNIEnv* env, jobject obj, jobject jobjValues, jobject jobjFile) { //variabelen HRESULT hr; IPortableDeviceContent* pDeviceContent; IPortableDeviceValues* pDeviceObjectValues; jobject jobjValuesReference; jstring jsFileLocation; LPWSTR wszFileLocation; DWORD dwBufferSize; CComPtr<IStream> pFileStream; CComPtr<IStream> pDeviceStream; CComPtr<IPortableDeviceDataStream> pDeviceDataStream; STATSTG fileStats; BYTE* pBuffer; DWORD dwReadFromStream; LPWSTR wszObjectID; jstring jsObjectID; jmethodID mid; //Methode implementatie pDeviceContent = GetPortableDeviceContent(env, obj); jobjValuesReference = RetrieveCOMReferenceFromCOMReferenceable(env, jobjValues); pDeviceObjectValues = (IPortableDeviceValues*)ConvertComReferenceToPointer(env, jobjValuesReference); //COM stream object aanmaken mid = env->GetMethodID(env->FindClass("java/io/File"), "getAbsolutePath", "()Ljava/lang/String;"); jsFileLocation = (jstring)env->CallObjectMethod(jobjFile, mid); wszFileLocation = (WCHAR*)env->GetStringChars(jsFileLocation, NULL); hr = SHCreateStreamOnFileW(wszFileLocation, STGM_READ, &pFileStream); env->ReleaseStringChars(jsFileLocation, (jchar*)wszFileLocation); //string resources terug vrijgeven if(SUCCEEDED(hr)) { //groote van het bestand bepalen //(door een beperking in java op het gebied van unsigned integers, moeten we het wel in c++ doen) pFileStream->Stat(&fileStats, STATFLAG_NONAME); pDeviceObjectValues->SetUnsignedLargeIntegerValue(WPD_OBJECT_SIZE, fileStats.cbSize.QuadPart); hr = pDeviceContent->CreateObjectWithPropertiesAndData(pDeviceObjectValues, &pDeviceStream, &dwBufferSize, NULL); if(SUCCEEDED(hr)) { pDeviceStream->QueryInterface(IID_IPortableDeviceDataStream, (void**)&pDeviceDataStream); //data kopieren pBuffer = new BYTE[dwBufferSize]; dwReadFromStream = 0; do { pFileStream->Read(pBuffer, dwBufferSize, &dwReadFromStream); pDeviceDataStream->Write(pBuffer, dwReadFromStream, NULL); } while(dwReadFromStream > 0); delete[] pBuffer; hr = pDeviceDataStream->Commit(STGC_DEFAULT); if(SUCCEEDED(hr)) { pDeviceDataStream->GetObjectID(&wszObjectID); jsObjectID = (jstring)env->NewString((jchar*)wszObjectID, wcslen(wszObjectID)); CoTaskMemFree(wszObjectID); return jsObjectID; } else { ThrowCOMException(env, L"Couldn't commit the data to the portable device", hr); } } else { ThrowCOMException(env, L"Couldn't create a COM stream object to the portable device", hr); } } else { ThrowCOMException(env, L"Couldn't create a COM stream object to the file", hr); } return NULL; }
VOID HealthBloodPressureServiceContent::BloodPressureMeasurementEvent( _In_ BTH_LE_GATT_EVENT_TYPE EventType, _In_ PVOID EventOutParameter ) { HRESULT hr = S_OK; PBLUETOOTH_GATT_VALUE_CHANGED_EVENT ValueChangedEventParameters = NULL; USHORT temp = 0; BLOODPRESSURE_MEASUREMENT Measurement = {0}; IPortableDeviceValues * pEventParams = NULL; BYTE* pBuffer = NULL; DWORD cbBuffer = 0; if (CharacteristicValueChangedEvent != EventType) { return; } ValueChangedEventParameters = (PBLUETOOTH_GATT_VALUE_CHANGED_EVENT)EventOutParameter; // // Our value is at least 7 bytes long // if (7 > ValueChangedEventParameters->CharacteristicValue->DataSize) { hr = E_FAIL; CHECK_HR(hr, "Invalid data size"); } if (SUCCEEDED(hr)) { // // The first byte is the Flag field // Measurement.Flags = ValueChangedEventParameters->CharacteristicValue->Data[0]; // // Systolic // RtlRetrieveUshort(&temp, &ValueChangedEventParameters->CharacteristicValue->Data[1]); Measurement.Systolic = UshortToFloat(temp); // // Diastolic // RtlRetrieveUshort(&temp, &ValueChangedEventParameters->CharacteristicValue->Data[3]); Measurement.Diastolic = UshortToFloat(temp); // // Mean Arterial Pressure // RtlRetrieveUshort(&temp, &ValueChangedEventParameters->CharacteristicValue->Data[5]); Measurement.MeanArterialPressure = UshortToFloat(temp); } // // Get the timestamp // if (SUCCEEDED(hr)) { BOOL isTimeProcessed = FALSE; // // If the time is provided by the BloodPressureMeasurement, use it. // If this flag is set, the value must be at least 14 bytes long // if ((0x02 == (Measurement.Flags & 0x02)) && (14 <= ValueChangedEventParameters->CharacteristicValue->DataSize)) { SYSTEMTIME systemTime = {0}; FILETIME fTime = {0}; // // This value is expressed in the org.bluetooth.characteristic.date_time format. // // // Year (2 bytes) // RtlRetrieveUshort(&temp, &ValueChangedEventParameters->CharacteristicValue->Data[7]); systemTime.wYear = temp; // // Month (1 byte) // systemTime.wMonth = ValueChangedEventParameters->CharacteristicValue->Data[9]; // // Day (1 byte) // systemTime.wDay = ValueChangedEventParameters->CharacteristicValue->Data[10]; // // Hours (1 byte) // systemTime.wHour = ValueChangedEventParameters->CharacteristicValue->Data[11]; // // Minutes (1 byte) // systemTime.wMinute = ValueChangedEventParameters->CharacteristicValue->Data[12]; // // Seconds (1 byte) // systemTime.wSecond = ValueChangedEventParameters->CharacteristicValue->Data[13]; // // Convert into FILETIME // if (SystemTimeToFileTime(&systemTime, &fTime)) { ConvertFileTimeToUlonglong(&fTime, &Measurement.TimeStamp); isTimeProcessed = TRUE; } } // // If the measurement didn't contain a timestamp or we failed to process it, // generate it based on the current time. // if (!isTimeProcessed) { FILETIME fTime; GetSystemTimeAsFileTime(&fTime); ConvertFileTimeToUlonglong(&fTime, &Measurement.TimeStamp); } } // // CoCreate a collection to store the property set event parameters. // if (SUCCEEDED(hr)) { hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**) &pEventParams); CHECK_HR(hr, "Failed to CoCreateInstance CLSID_PortableDeviceValues"); } if (SUCCEEDED(hr)) { hr = pEventParams->SetGuidValue(WPD_EVENT_PARAMETER_EVENT_ID, EVENT_HealthBloodPressureService_Measurement); CHECK_HR(hr, "Failed to add WPD_EVENT_PARAMETER_EVENT_ID"); } // // Set the timestamp // if (SUCCEEDED(hr)) { hr = pEventParams->SetUnsignedLargeIntegerValue(EVENT_PARAMETER_HealthBloodPressureService_Measurement_TimeStamp, Measurement.TimeStamp); CHECK_HR(hr, "Failed to add EVENT_PARAMETER_HealthBloodPressureService_Measurement_TimeStamp"); } // // Set the measurement type // if (SUCCEEDED(hr)) { if (0x01 == (Measurement.Flags & 0x01)) { hr = pEventParams->SetStringValue(EVENT_PARAMETER_HealthBloodPressureService_Measurement_Type, L"kPa"); } else { hr = pEventParams->SetStringValue(EVENT_PARAMETER_HealthBloodPressureService_Measurement_Type, L"mmHg"); } CHECK_HR(hr, "Failed to add EVENT_PARAMETER_HealthBloodPressureService_Measurement_Type"); } // // Set the Systolic value // if (SUCCEEDED(hr)) { float ftemp = (float)Measurement.Systolic; hr = pEventParams->SetFloatValue(EVENT_PARAMETER_HealthBloodPressureService_Measurement_Systolic, ftemp); CHECK_HR(hr, "Failed to add EVENT_PARAMETER_HealthBloodPressureService_Measurement_Systolic"); } // // Set the Diastolic value // if (SUCCEEDED(hr)) { float ftemp = (float)Measurement.Diastolic; hr = pEventParams->SetFloatValue(EVENT_PARAMETER_HealthBloodPressureService_Measurement_Diastolic, ftemp); CHECK_HR(hr, "Failed to add EVENT_PARAMETER_HealthBloodPressureService_Measurement_Diastolic"); } // // Set the Mean Arterial Pressure value // if (SUCCEEDED(hr)) { float ftemp = (float)Measurement.MeanArterialPressure; hr = pEventParams->SetFloatValue(EVENT_PARAMETER_HealthBloodPressureService_Measurement_MeanArterialPressure, ftemp); CHECK_HR(hr, "Failed to add EVENT_PARAMETER_HealthBloodPressureService_Measurement_MeanArterialPressure"); } // // Adding this event parameter will allow WPD to scope this event to the container functional object // if (SUCCEEDED(hr)) { hr = pEventParams->SetStringValue(WPD_EVENT_PARAMETER_OBJECT_PARENT_PERSISTENT_UNIQUE_ID, ParentPersistentUniqueID); CHECK_HR(hr, "Failed to add WPD_EVENT_PARAMETER_OBJECT_PARENT_PERSISTENT_UNIQUE_ID"); } // // Adding this event parameter will allow WPD to scope this event to the container functional object // if (SUCCEEDED(hr)) { hr = pEventParams->SetStringValue(WPD_OBJECT_CONTAINER_FUNCTIONAL_OBJECT_ID, SERVICE_OBJECT_ID); CHECK_HR(hr, "Failed to add WPD_OBJECT_CONTAINER_FUNCTIONAL_OBJECT_ID"); } // // Create a buffer with the serialized parameters // if (SUCCEEDED(hr)) { hr = m_pWpdSerializer->GetBufferFromIPortableDeviceValues(pEventParams, &pBuffer, &cbBuffer); CHECK_HR(hr, "Failed to get buffer from IPortableDeviceValues"); } if (SUCCEEDED(hr) && NULL == pBuffer) { hr = E_FAIL; CHECK_HR(hr, "pBuffer is NULL"); } // // Send the event // if (SUCCEEDED(hr)) { hr = m_pDevice->PostEvent(WPD_EVENT_NOTIFICATION, WdfEventBroadcast, pBuffer, cbBuffer); CHECK_HR(hr, "Failed to post WPD (broadcast) event"); } // // Cleanup // if (NULL != pBuffer) { CoTaskMemFree(pBuffer); pBuffer = NULL; } if (NULL != pEventParams) { pEventParams->Release(); pEventParams = NULL; } }