diff options
Diffstat (limited to 'wpd/WpdWudfSampleDriver/WpdObjectResources.cpp')
| -rw-r--r-- | wpd/WpdWudfSampleDriver/WpdObjectResources.cpp | 944 |
1 files changed, 0 insertions, 944 deletions
diff --git a/wpd/WpdWudfSampleDriver/WpdObjectResources.cpp b/wpd/WpdWudfSampleDriver/WpdObjectResources.cpp deleted file mode 100644 index 6f7955d5..00000000 --- a/wpd/WpdWudfSampleDriver/WpdObjectResources.cpp +++ /dev/null @@ -1,944 +0,0 @@ -#include "stdafx.h" -#include "WpdObjectResources.tmh" - -WpdObjectResources::WpdObjectResources() -{ - -} - -WpdObjectResources::~WpdObjectResources() -{ - -} - -HRESULT WpdObjectResources::Initialize( - _In_ FakeDevice *pFakeDevice) -{ - HRESULT hr = S_OK; - - if(pFakeDevice == NULL) - { - hr = E_POINTER; - CHECK_HR(hr, "Cannot have NULL parameter"); - return hr; - } - m_pFakeDevice = pFakeDevice; - return hr; -} - -HRESULT WpdObjectResources::DispatchWpdMessage( - _In_ REFPROPERTYKEY Command, - _In_ IPortableDeviceValues* pParams, - _In_ IPortableDeviceValues* pResults) -{ - HRESULT hr = S_OK; - - if (hr == S_OK) - { - if (Command.fmtid != WPD_CATEGORY_OBJECT_RESOURCES) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "This object does not support this command category %ws",CComBSTR(Command.fmtid)); - } - } - - if (hr == S_OK) - { - if (IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_RESOURCES_GET_SUPPORTED)) - { - hr = OnGetSupportedResources(pParams, pResults); - CHECK_HR(hr, "Failed to get supported resources"); - } - else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_RESOURCES_GET_ATTRIBUTES)) - { - hr = OnGetAttributes(pParams, pResults); - if(FAILED(hr)) - { - CHECK_HR(hr, "Failed to get resource attributes"); - } - } - else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_RESOURCES_OPEN)) - { - hr = OnOpen(pParams, pResults); - CHECK_HR(hr, "Failed to open resource"); - } - else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_RESOURCES_READ)) - { - hr = OnRead(pParams, pResults); - CHECK_HR(hr, "Failed to read resource data"); - } - else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_RESOURCES_WRITE)) - { - hr = OnWrite(pParams, pResults); - CHECK_HR(hr, "Failed to write resource data"); - } - else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_RESOURCES_CLOSE)) - { - hr = OnClose(pParams, pResults); - CHECK_HR(hr, "Failed to close resource"); - } - else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_RESOURCES_DELETE)) - { - hr = OnDelete(pParams, pResults); - CHECK_HR(hr, "Failed to delete resources"); - } - else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_RESOURCES_CREATE_RESOURCE)) - { - hr = OnCreate(pParams, pResults); - CHECK_HR(hr, "Failed to create resource"); - } - else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_RESOURCES_REVERT)) - { - hr = OnRevert(pParams, pResults); - CHECK_HR(hr, "Failed to revert resource operation"); - } - else if(IsEqualPropertyKey(Command, WPD_COMMAND_OBJECT_RESOURCES_SEEK)) - { - hr = OnSeek(pParams, pResults); - CHECK_HR(hr, "Failed resource seek operation"); - } - else - { - hr = E_NOTIMPL; - CHECK_HR(hr, "This object does not support this command id %d", Command.pid); - } - } - return hr; -} - -/** - * This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_GET_SUPPORTED - * command. - * - * The parameters sent to us are: - * - WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID: identifies the object whose resources we want to return. - * - * The driver should: - * - Return all resources for this object in WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS. - */ -HRESULT WpdObjectResources::OnGetSupportedResources( - _In_ IPortableDeviceValues* pParams, - _In_ IPortableDeviceValues* pResults) -{ - HRESULT hr = S_OK; - LPWSTR pszObjectID = NULL; - - CComPtr<IPortableDeviceKeyCollection> pKeys; - - // Get the Object ID - hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID, &pszObjectID); - if (hr != S_OK) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID"); - } - - // Get the collection of resource keys - if (hr == S_OK) - { - hr = m_pFakeDevice->GetSupportedResources(pszObjectID, &pKeys); - CHECK_HR(hr, "Failed to get resource keys collection on [%ws]", pszObjectID); - } - - if (hr == S_OK) - { - hr = pResults->SetIUnknownValue(WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS, pKeys); - CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS"); - } - - // Free the memory. CoTaskMemFree ignores NULLs so no need to check. - CoTaskMemFree(pszObjectID); - - return hr; -} - -/** - * This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_GET_ATTRIBUTES - * command. - * - * The parameters sent to us are: - * - WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID: identifies the object whose resource attributes we want to return. - * - WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS: a collection of resource keys containing a single value, - * which is the key identifying the specific resource whose attributes we are requested to return. - * - * The driver should: - * - Return the requested resource attributes. If any resource attributes failed to be retrieved, - * the corresponding value should be set to type VT_ERROR with the 'scode' member holding the - * HRESULT reason for the failure. - * - S_OK should be returned if all resource attributes were read successfully. - * - S_FALSE should be returned if any resource attribute failed. - * - Any error return indicates that the driver did not fill in any results, and the caller will - * not attempt to unpack any resource attributes. - */ -HRESULT WpdObjectResources::OnGetAttributes( - _In_ IPortableDeviceValues* pParams, - _In_ IPortableDeviceValues* pResults) -{ - HRESULT hr = S_OK; - LPWSTR pszObjectID = NULL; - PROPERTYKEY Key = {0}; - - CComPtr<IPortableDeviceValues> pAttributeStore; - - // Get the Object ID - hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID, &pszObjectID); - if (hr != S_OK) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID"); - } - - if (hr == S_OK) - { - hr = pParams->GetKeyValue(WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS, &Key); - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS"); - } - - if (hr == S_OK) - { - hr = m_pFakeDevice->GetResourceAttributes(pszObjectID, Key, &pAttributeStore); - CHECK_HR(hr, "Failed to get attributes on [%ws]", pszObjectID); - } - - if (SUCCEEDED(hr)) - { - HRESULT hrTemp = S_OK; - - hrTemp = pResults->SetIUnknownValue(WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_ATTRIBUTES, pAttributeStore); - CHECK_HR(hrTemp, ("Failed to set WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_ATTRIBUTES")); - - if(FAILED(hrTemp)) - { - hr = hrTemp; - } - } - - // Free the memory. CoTaskMemFree ignores NULLs so no need to check. - CoTaskMemFree(pszObjectID); - - return hr; -} - -/** - * This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_OPEN - * command. - * - * The parameters sent to us are: - * - WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID: identifies the object whose resource we are interested in. - * - WPD_PROPERTY_OBJECT_RESOURCES_ACCESS_MODE: specifies the access requested by the caller. It will - * be either STGM_READ or STGM_WRITE. - * - WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS: a collection of resource keys containing a single value, - * which is the key identifying the specific resource the caller is interested in. - * - * The driver should: - * - Create a context associated with this resource. This context will be used by clients when reading/writing - * resource data. Generally, most drivers will also lock the resource here if necessary. - * The context identifier should be a string value returned in WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT. - * - Return the optimal transfer buffer size in WPD_PROPERTY_OBJECT_RESOURCES_OPTIMAL_TRANSFER_BUFFER_SIZE. - */ -HRESULT WpdObjectResources::OnOpen( - _In_ IPortableDeviceValues* pParams, - _In_ IPortableDeviceValues* pResults) -{ - HRESULT hr = S_OK; - LPWSTR pszObjectID = NULL; - PROPERTYKEY Key = {0}; - DWORD dwMode = STGM_READ; - LPWSTR pszContext = NULL; - ContextMap* pContextMap = NULL; - BOOL bSupportsResource = FALSE; - - // Get the Object ID - hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID, &pszObjectID); - if (FAILED(hr)) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID"); - } - - // Get the resource key - if (SUCCEEDED(hr)) - { - hr = pParams->GetKeyValue(WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS, &Key); - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS"); - } - - // Get the access mode - if (SUCCEEDED(hr)) - { - hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_ACCESS_MODE, &dwMode); - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_ACCESS_MODE"); - } - - // Get the context map which the driver stored in pParams for convenience - if (SUCCEEDED(hr)) - { - hr = pParams->GetIUnknownValue(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, (IUnknown**)&pContextMap); - CHECK_HR(hr, "Failed to get PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP"); - } - - // Validate whether this object supports the requested resource - if (SUCCEEDED(hr)) - { - hr = m_pFakeDevice->SupportsResource(pszObjectID, Key, &bSupportsResource); - CHECK_HR(hr, "Failed to check whether object supports resources"); - } - - if (SUCCEEDED(hr) && !bSupportsResource) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "Object does not support this resource"); - } - - // Create the context - if (SUCCEEDED(hr)) - { - hr = CreateResourceContext(pContextMap, pszObjectID, Key, FALSE, &pszContext); - CHECK_HR(hr, "Failed to create resource context for %ws.%d on %ws", CComBSTR(Key.fmtid), Key.pid, pszObjectID); - } - - if (SUCCEEDED(hr)) - { - hr = pResults->SetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT, pszContext); - CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT"); - } - - // Set the optimal buffer size - if (SUCCEEDED(hr)) - { - hr = pResults->SetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_OPTIMAL_TRANSFER_BUFFER_SIZE, OPTIMAL_BUFFER_SIZE); - CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_OPTIMAL_TRANSFER_BUFFER_SIZE value"); - } - - // Free the memory. CoTaskMemFree ignores NULLs so no need to check. - CoTaskMemFree(pszObjectID); - // Free the memory. CoTaskMemFree ignores NULLs so no need to check. - CoTaskMemFree(pszContext); - - SAFE_RELEASE(pContextMap); - - return hr; -} - -/** - * This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_READ - * command. - * - * The parameters sent to us are: - * - WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT: identifies the previsouly opened resource we are going to read from. - * - WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_READ: specifies the next number of bytes to read. - * - * The driver should: - * - Read up to the next WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_READ from the resource. - * - Return the number of bytes actually read in WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_READ. - */ -HRESULT WpdObjectResources::OnRead( - _In_ IPortableDeviceValues* pParams, - _In_ IPortableDeviceValues* pResults) -{ - HRESULT hr = S_OK; - LPWSTR pszContext = NULL; - DWORD dwNumBytesToRead = 0; - DWORD dwNumBytesRead = 0; - BYTE* pBuffer = NULL; - ResourceContext* pContext = NULL; - - // Get the Context - hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT, &pszContext); - if (FAILED(hr)) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT"); - } - - // Get the number of bytes to read - if (SUCCEEDED(hr)) - { - hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_READ, &dwNumBytesToRead); - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_READ"); - } - - // Allocate the destination buffer - if (SUCCEEDED(hr)) - { - pBuffer = reinterpret_cast<BYTE *>(CoTaskMemAlloc(dwNumBytesToRead)); - if (pBuffer == NULL) - { - hr = E_OUTOFMEMORY; - CHECK_HR(hr, "Failed to allocate the destination buffer"); - } - } - - // Get the context for this transfer - if (SUCCEEDED(hr)) - { - hr = GetClientContext(pParams, pszContext, (IUnknown**) &pContext); - CHECK_HR(hr, "Failed to get resource context"); - } - - // Read the next band of data for this transfer request - if (SUCCEEDED(hr) && pBuffer != NULL) - { - hr = m_pFakeDevice->ReadData(pContext->ObjectID, - pContext->Key, - pContext->NumBytesTransfered, - pBuffer, - dwNumBytesToRead, - &dwNumBytesRead); - CHECK_HR(hr, "Failed to read %d bytes from [%ws] on resource {%ws}.%d", dwNumBytesToRead, pContext->ObjectID, CComBSTR(pContext->Key.fmtid), pContext->Key.pid); - if (SUCCEEDED(hr)) - { - pContext->NumBytesTransfered += dwNumBytesRead; - } - } - - if (SUCCEEDED(hr) && pBuffer != NULL) - { - hr = pResults->SetBufferValue(WPD_PROPERTY_OBJECT_RESOURCES_DATA, pBuffer, dwNumBytesRead); - CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_DATA"); - } - - if (SUCCEEDED(hr)) - { - hr = pResults->SetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_READ, dwNumBytesRead); - CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_READ"); - } - - // Free the memory. CoTaskMemFree ignores NULLs so no need to check. - CoTaskMemFree(pszContext); - // Free the memory. CoTaskMemFree ignores NULLs so no need to check. - CoTaskMemFree(pBuffer); - - SAFE_RELEASE(pContext); - - return hr; -} - -/** - * This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_WRITE - * command. - * - * The parameters sent to us are: - * - WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT: identifies the previsouly opened resource we are going to write to. - * - WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_WRITE: specifies the next number of bytes to write. - * - WPD_PROPERTY_OBJECT_RESOURCES_DATA: specifies byte array where the data should be copied from. - * - * The driver should: - * - Write the next WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_WRITE to the resource. - * - Return the number of bytes actually written in WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_WRITTEN. - * It is normally considered an error if this value does not match WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_WRITE. - */ -HRESULT WpdObjectResources::OnWrite( - _In_ IPortableDeviceValues* pParams, - _In_ IPortableDeviceValues* pResults) -{ - HRESULT hr = S_OK; - LPWSTR pszContext = NULL; - DWORD dwNumBytesToWrite = 0; - DWORD dwNumBytesWritten = 0; - BYTE* pBuffer = NULL; - DWORD cbBuffer = 0; - ResourceContext* pContext = NULL; - - // Get the Context string - hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT, &pszContext); - if (FAILED(hr)) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT"); - } - - // Get the number of bytes to write - if (SUCCEEDED(hr)) - { - hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_WRITE, &dwNumBytesToWrite); - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_TO_WRITE"); - } - - // Get the source buffer - if (SUCCEEDED(hr)) - { - hr = pParams->GetBufferValue(WPD_PROPERTY_OBJECT_RESOURCES_DATA, &pBuffer, &cbBuffer); - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_DATA"); - } - - // Get the resource context for this transfer - if (SUCCEEDED(hr)) - { - hr = GetClientContext(pParams, pszContext, (IUnknown**) &pContext); - CHECK_HR(hr, "Faield to get resource context"); - } - - // Write the next band of data for this transfer request - if (SUCCEEDED(hr) && pBuffer != NULL) - { - hr = m_pFakeDevice->WriteData(pContext->ObjectID, - pContext->Key, - pContext->NumBytesTransfered, - pBuffer, - dwNumBytesToWrite, - &dwNumBytesWritten); - CHECK_HR(hr, "Failed to write %d bytes to [%ws] on resource {%ws}.%d", dwNumBytesToWrite, pContext->ObjectID, CComBSTR(pContext->Key.fmtid), pContext->Key.pid); - if (SUCCEEDED(hr)) - { - pContext->NumBytesTransfered += dwNumBytesWritten; - } - } - - if (SUCCEEDED(hr)) - { - hr = pResults->SetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_WRITTEN, dwNumBytesWritten); - CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_NUM_BYTES_WRITTEN"); - } - - // Free the memory. CoTaskMemFree ignores NULLs so no need to check. - CoTaskMemFree(pszContext); - // Free the memory. CoTaskMemFree ignores NULLs so no need to check. - CoTaskMemFree(pBuffer); - - SAFE_RELEASE(pContext); - - return hr; -} - -/** - * This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_CLOSE - * command. - * - * The parameters sent to us are: - * - WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT: identifies the resource context associated with a - * previously opened resource. - * - * The driver should: - * - Unlock the resource if necessary, and release any system and device resources associated with this WPD object resource. - */ -HRESULT WpdObjectResources::OnClose( - _In_ IPortableDeviceValues* pParams, - _In_ IPortableDeviceValues* pResults) -{ - // No results are expected to be returned - UNREFERENCED_PARAMETER(pResults); - - HRESULT hr = S_OK; - LPWSTR pszContext = NULL; - ContextMap* pContextMap = NULL; - ResourceContext* pContext = NULL; - - // Get the Object ID - hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT, &pszContext); - if (FAILED(hr)) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT"); - } - - // Get the context map which the driver stored in pParams for convenience - if (SUCCEEDED(hr)) - { - hr = pParams->GetIUnknownValue(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, (IUnknown**)&pContextMap); - CHECK_HR(hr, "Failed to get PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP"); - } - - // If this was a creation request, enable the resource for the content - if (SUCCEEDED(hr)) - { - // Get the context for this transfer - hr = GetClientContext(pParams, pszContext, (IUnknown**) &pContext); - CHECK_HR(hr, "Failed to get resource context"); - } - - if (SUCCEEDED(hr)) - { - if (pContext->CreateRequest == TRUE) - { - hr = m_pFakeDevice->EnableResource(pContext->ObjectID, pContext->Key); - CHECK_HR(hr, "Failed to enable resource on object [%ws]", pContext->ObjectID); - } - } - - //Free the context - SAFE_RELEASE(pContext); - - if (SUCCEEDED(hr)) - { - hr = DestroyResourceContext(pContextMap, pszContext); - CHECK_HR(hr, "Failed to remove resource context [%ws]", pszContext); - } - - // Free the memory. CoTaskMemFree ignores NULLs so no need to check. - CoTaskMemFree(pszContext); - - SAFE_RELEASE(pContextMap); - - return hr; -} - -/** - * This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_DELETE - * command. - * - * The parameters sent to us are: - * - WPD_PROPERTY_OBJECT_RESOURCES_OBJECT_ID: identifies the object whose resources should be deleted. - * - WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_KEYS: a collection of keys indicating which - * resources to delete. - * - * The driver should: - * - Delete the specified resources from the object. - * - S_OK should be returned if all specified properties were successfully deleted. - * - E_ACCESSDENIED should be returned if the client attempts to delete a resource which is not deletable (i.e. - * WPD_RESOURCE_ATTRIBUTE_CAN_DELETE is FALSE for that resource.) - */ -HRESULT WpdObjectResources::OnDelete( - _In_ IPortableDeviceValues* pParams, - _In_ IPortableDeviceValues* pResults) -{ - HRESULT hr = E_ACCESSDENIED; - - UNREFERENCED_PARAMETER(pParams); - UNREFERENCED_PARAMETER(pResults); - - // This driver has no resources which can be deleted. - return hr; -} - -HRESULT WpdObjectResources::OnCreate( - _In_ IPortableDeviceValues* pParams, - _In_ IPortableDeviceValues* pResults) -{ - HRESULT hr = S_OK; - LPWSTR pszObjectID = NULL; - LPWSTR pszContext = NULL; - ContextMap* pContextMap = NULL; - PROPERTYKEY ResourceKey = WPD_PROPERTY_NULL; - GUID guidObjectFormat = GUID_NULL; - CComPtr<IPortableDeviceValues> pResourceAttributes; - - // Getthe Resource Attributes - hr = pParams->GetIPortableDeviceValuesValue(WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_ATTRIBUTES, &pResourceAttributes); - if (FAILED(hr)) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_RESOURCE_ATTRIBUTES"); - } - - // Get the Resource Key - if (SUCCEEDED(hr)) - { - hr = pResourceAttributes->GetKeyValue(WPD_RESOURCE_ATTRIBUTE_RESOURCE_KEY, &ResourceKey); - if (FAILED(hr)) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "Missing value for WPD_RESOURCE_ATTRIBUTE_RESOURCE_KEY"); - } - } - - if (SUCCEEDED(hr) && !IsEqualPropertyKey(ResourceKey, WPD_RESOURCE_CONTACT_PHOTO)) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "CreateResource is only supported on WPD_RESOURCE_CONTACT_PHOTO"); - } - - if (SUCCEEDED(hr)) - { - // Get the Object ID - hr = pResourceAttributes->GetStringValue(WPD_OBJECT_ID, &pszObjectID); - if (FAILED(hr)) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "Missing value for WPD_OBJECT_ID"); - } - } - - if (SUCCEEDED(hr)) - { - hr = m_pFakeDevice->GetContentFormat(pszObjectID, guidObjectFormat); - CHECK_HR(hr, "Failed to get content object format"); - - if (SUCCEEDED(hr) && !IsEqualGUID(guidObjectFormat, WPD_OBJECT_FORMAT_VCARD2)) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "CreateResource is only supported on contact objects"); - } - } - - // Get the context map which the driver stored in pParams for convenience - if (SUCCEEDED(hr)) - { - hr = pParams->GetIUnknownValue(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, (IUnknown**)&pContextMap); - CHECK_HR(hr, "Failed to get PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP"); - } - - // Create the context - if (SUCCEEDED(hr)) - { - hr = CreateResourceContext(pContextMap, pszObjectID, ResourceKey, TRUE, &pszContext); - CHECK_HR(hr, "Failed to create resource context for %ws.%d on %ws", CComBSTR(ResourceKey.fmtid), ResourceKey.pid, pszObjectID); - } - - if (SUCCEEDED(hr)) - { - hr = pResults->SetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT, pszContext); - CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT"); - } - - // Set the optimal buffer size - if (SUCCEEDED(hr)) - { - hr = pResults->SetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_OPTIMAL_TRANSFER_BUFFER_SIZE, OPTIMAL_BUFFER_SIZE); - CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_OPTIMAL_TRANSFER_BUFFER_SIZE value"); - } - - // Free the memory. CoTaskMemFree ignores NULLs so no need to check. - CoTaskMemFree(pszObjectID); - // Free the memory. CoTaskMemFree ignores NULLs so no need to check. - CoTaskMemFree(pszContext); - - SAFE_RELEASE(pContextMap); - - return hr; -} - -/** - * This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_REVERT - * command. - * - * The parameters sent to us are: - * - WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT: identifies the resource context associated with a - * previously opened resource. - * - * The driver should: - * - Unlock and remove the resource if necessary, and release any system and device resources associated with this WPD object resource. - */ -HRESULT WpdObjectResources::OnRevert( - _In_ IPortableDeviceValues* pParams, - _In_ IPortableDeviceValues* pResults) -{ - // No results are expected to be returned - UNREFERENCED_PARAMETER(pResults); - - HRESULT hr = S_OK; - LPWSTR pszContext = NULL; - ContextMap* pContextMap = NULL; - - // Get the Object ID - hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT, &pszContext); - if (FAILED(hr)) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT"); - } - - // Get the context map which the driver stored in pParams for convenience - if (SUCCEEDED(hr)) - { - hr = pParams->GetIUnknownValue(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, (IUnknown**)&pContextMap); - CHECK_HR(hr, "Failed to get PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP"); - } - - //Free the context - if (SUCCEEDED(hr)) - { - hr = DestroyResourceContext(pContextMap, pszContext); - CHECK_HR(hr, "Failed to remove resource context [%ws]", pszContext); - } - - // Free the memory. CoTaskMemFree ignores NULLs so no need to check. - CoTaskMemFree(pszContext); - - SAFE_RELEASE(pContextMap); - - return hr; -} - -/** - * This method is called when we receive a WPD_COMMAND_OBJECT_RESOURCES_SEEK - * command. - * - * The parameters sent to us are: - * - WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT: identifies the resource context associated with a - * previously opened resource. - * - WPD_PROPERTY_OBJECT_RESOURCES_SEEK_OFFSET: Displacement to be added to the location indicated by the WPD_PROPERTY_OBJECT_RESOURCES_SEEK_ORIGIN_FLAG parameter. - * - WPD_PROPERTY_OBJECT_RESOURCES_SEEK_ORIGIN_FLAG: Specifies the origin of the displacement for the seek operation. Can be one of the following values: - * STREAM_SEEK_SET - Offset is from the beginning of the stream - * STREAM_SEEK_CUR - Offset is from the current position in the stream - * STREAM_SEEK_END - Offset is from the end of the stream - * - * The driver should: - * - Move the seek pointer for the resource to point to the specified position, so that - * subsequent read / write operations occur from the new position. - * - Return the new position as an offset relative to the start of the data stream in WPD_PROPERTY_OBJECT_RESOURCES_POSITION_FROM_START. - */ -HRESULT WpdObjectResources::OnSeek( - _In_ IPortableDeviceValues* pParams, - _In_ IPortableDeviceValues* pResults) -{ - // No results are expected to be returned - UNREFERENCED_PARAMETER(pResults); - - HRESULT hr = S_OK; - LPWSTR pszContext = NULL; - DWORD dwOrigin = 0; - LONGLONG lOffset = 0; - - ResourceContext* pContext = NULL; - - // Get the Object ID - hr = pParams->GetStringValue(WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT, &pszContext); - if (FAILED(hr)) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_CONTEXT"); - } - - // Get the offset - if (SUCCEEDED(hr)) - { - hr = pParams->GetSignedLargeIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_SEEK_OFFSET, &lOffset); - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_SEEK_OFFSET"); - } - - // Get the origin flags - if (SUCCEEDED(hr)) - { - hr = pParams->GetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_SEEK_ORIGIN_FLAG, &dwOrigin); - CHECK_HR(hr, "Missing value for WPD_PROPERTY_OBJECT_RESOURCES_SEEK_ORIGIN_FLAG"); - } - - // Get the context for this transfer - if (SUCCEEDED(hr)) - { - hr = GetClientContext(pParams, pszContext, (IUnknown**) &pContext); - CHECK_HR(hr, "Failed to get resource context"); - } - - // Update the current seek pointer. For this driver, we update the NumBytesTransfered in the context so that subsequent reads/writes start - // at the appropriate place. - if (SUCCEEDED(hr)) - { - ULONG ulSize = 0; - ULONG ulOriginalNumBytesTransfered = pContext->NumBytesTransfered; - CComPtr<IPortableDeviceValues> pResourceAttributes; - - // Get the total size of the resource - hr = m_pFakeDevice->GetResourceAttributes(pContext->ObjectID, pContext->Key, &pResourceAttributes); - CHECK_HR(hr, "Failed to get attributes on [%ws]", pContext->ObjectID); - if (SUCCEEDED(hr)) - { - hr = pResourceAttributes->GetUnsignedIntegerValue(WPD_RESOURCE_ATTRIBUTE_TOTAL_SIZE, &ulSize); - CHECK_HR(hr, "Failed to get WPD_RESOURCE_ATTRIBUTE_TOTAL_SIZE"); - } - - if(dwOrigin == STREAM_SEEK_CUR) - { - pContext->NumBytesTransfered += (LONG) lOffset; - } - else if(dwOrigin == STREAM_SEEK_SET) - { - pContext->NumBytesTransfered = (LONG) lOffset; - } - else - { - pContext->NumBytesTransfered = ulSize + (LONG) lOffset; - } - - // Validate that this is in the correct range - if (SUCCEEDED(hr) && pContext->NumBytesTransfered > ulSize) - { - hr = E_INVALIDARG; - CHECK_HR(hr, "Attempting to seek beyond existing data"); - // Restore the seek pointer to its original value - pContext->NumBytesTransfered = ulOriginalNumBytesTransfered; - } - } - - // Set the return value - if (SUCCEEDED(hr)) - { - hr = pResults->SetUnsignedIntegerValue(WPD_PROPERTY_OBJECT_RESOURCES_POSITION_FROM_START, pContext->NumBytesTransfered); - CHECK_HR(hr, "Failed to set WPD_PROPERTY_OBJECT_RESOURCES_POSITION_FROM_START"); - } - - // Free the memory. CoTaskMemFree ignores NULLs so no need to check. - CoTaskMemFree(pszContext); - - SAFE_RELEASE(pContext); - - return hr; -} - -HRESULT WpdObjectResources::CreateResourceContext( - _In_ ContextMap* pContextMap, - _In_ LPCWSTR pszObjectID, - _In_ REFPROPERTYKEY ResourceKey, - _In_ BOOL bCreateRequest, - _Outptr_ LPWSTR* ppszResourceContext) -{ - HRESULT hr = S_OK; - GUID guidContext = GUID_NULL; - ResourceContext* pContext = NULL; - - if((pContextMap == NULL) || - (pszObjectID == NULL) || - (ppszResourceContext == NULL)) - { - hr = E_POINTER; - CHECK_HR(hr, "Cannot have NULL parameter"); - return hr; - } - - *ppszResourceContext = NULL; - - hr = CoCreateGuid(&guidContext); - CHECK_HR(hr, "Failed to CoCreateGuid used for identifying the resource context"); - - if (SUCCEEDED(hr)) - { - pContext = new ResourceContext(); - if(pContext == NULL) - { - hr = E_OUTOFMEMORY; - CHECK_HR(hr, "Failed to allocate new resource context"); - } - } - - if (SUCCEEDED(hr)) - { - pContext->ObjectID = pszObjectID; - pContext->Key = ResourceKey; - pContext->CreateRequest = bCreateRequest; - - CAtlStringW strKey = CComBSTR(guidContext); - hr = pContextMap->Add(strKey, pContext); - CHECK_HR(hr, "Failed to insert bulk property operation context into our context Map"); - } - - if (SUCCEEDED(hr)) - { - hr = StringFromCLSID(guidContext, ppszResourceContext); - CHECK_HR(hr, "Failed to allocate string from GUID for resource context"); - } - - SAFE_RELEASE(pContext); - - return hr; -} - -HRESULT WpdObjectResources::DestroyResourceContext( - _In_ ContextMap* pContextMap, - _In_ LPCWSTR pszResourceContext) -{ - HRESULT hr = S_OK; - - if(pszResourceContext == NULL) - { - hr = E_POINTER; - CHECK_HR(hr, "Cannot have NULL parameter"); - return hr; - } - - CAtlStringW strKey = pszResourceContext; - pContextMap->Remove(strKey); - - return hr; -} - |
