Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The messaging function, WpdBaseDriver::DispatchWpdMessage, handles the distribution of messages to the appropriate driver component. If you've programmed Windows before, you can think of the DispatchWpdMessage function as being analogous to a Windows-based application's WindowProc function.
The WpdBaseDriver::DispatchWpdMessage function examines the WPD_Command category to determine where it should send a given message. It then passes this message on to the appropriate component (the enumeration, property, resource, or capabilities components found in the driver).
The pParams argument points to an IPortableDeviceValues collection that contains de-serialized parameters for the given command.
The pResults argument points to an empty collection of IPortableDeviceValues which the function populates after the given command is processed.
The following excerpt from the sample driver contains the code for WpdBaseDriver::DispatchWpdMessage.
HRESULT WpdBaseDriver::DispatchWpdMessage(IPortableDeviceValues* pParams,
IPortableDeviceValues* pResults)
{
HRESULT hr = S_OK;
GUID guidCommandCategory = {0};
DWORD dwCommandID = 0;
PROPERTYKEY CommandKey = WPD_PROPERTY_NULL;
if (hr == S_OK)
{
hr = pParams->GetGuidValue(WPD_PROPERTY_COMMON_COMMAND_CATEGORY, &guidCommandCategory);
CHECK_HR(hr, "Failed to get WPD_PROPERTY_COMMON_COMMAND_CATEGORY from input parameters");
}
if (hr == S_OK)
{
hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_COMMON_COMMAND_ID, &dwCommandID);
CHECK_HR(hr, "Failed to get WPD_PROPERTY_COMMON_COMMAND_ID from input parameters");
}
// If WPD_PROPERTY_COMMON_COMMAND_CATEGORY or WPD_PROPERTY_COMMON_COMMAND_ID could not be extracted
// properly then we should return E_INVALIDARG to the client.
if (FAILED(hr))
{
hr = E_INVALIDARG;
CHECK_HR(hr, "Failed to get WPD_PROPERTY_COMMON_COMMAND_CATEGORY or WPD_PROPERTY_COMMON_COMMAND_ID from input parameters");
}
if (hr == S_OK)
{
CommandKey.fmtid = guidCommandCategory;
CommandKey.pid = dwCommandID;
if (CommandKey.fmtid == WPD_CATEGORY_OBJECT_ENUMERATION)
{
hr = m_ObjectEnum.DispatchWpdMessage(CommandKey, pParams, pResults);
}
else if (CommandKey.fmtid == WPD_CATEGORY_OBJECT_PROPERTIES)
{
hr = m_ObjectProperties.DispatchWpdMessage(CommandKey, pParams, pResults);
}
else if (CommandKey.fmtid == WPD_CATEGORY_OBJECT_RESOURCES)
{
hr = m_ObjectResources.DispatchWpdMessage(CommandKey, pParams, pResults);
}
else if (CommandKey.fmtid == WPD_CATEGORY_CAPABILITIES)
{
hr = m_Capabilities.DispatchWpdMessage(CommandKey, pParams, pResults);
}
else if (IsEqualPropertyKey(CommandKey, WPD_COMMAND_COMMON_GET_OBJECT_IDS_FROM_PERSISTENT_UNIQUE_IDS))
{
hr = OnGetObjectIDsFromPersistentUniqueIDs(pParams, pResults);
}
else
{
hr = E_NOTIMPL;
CHECK_HR(hr, "Unknown command %ws.%d received",CComBSTR(CommandKey.fmtid), CommandKey.pid);
}
}
HRESULT hrTemp = pResults->SetErrorValue(WPD_PROPERTY_COMMON_HRESULT, hr);
CHECK_HR(hrTemp, ("Failed to set WPD_PROPERTY_COMMON_HRESULT"));
// Set to a success code, to indicate that the message was received.
// the return code for the actual command's results is stored in the
// WPD_PROPERTY_COMMON_HRESULT property.
hr = S_OK;
return hr;
}