Пример #1
0
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;
} 
Пример #3
0
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;
} // }}}
Пример #4
0
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;
    }
}
Пример #6
0
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;
    }
}
Пример #7
0
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;
}
Пример #8
0
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;
    }
}