IWMDMStorageControl3::Insert3 方法 (mswmdm.h)

Insert3 方法将内容放入存储中/旁边。 此方法通过允许应用程序显式指定所发送对象的元数据和类型来扩展 IWMDMStorageControl2::Insert2

语法

HRESULT Insert3(
  [in]  UINT           fuMode,
  [in]  UINT           fuType,
  [in]  LPWSTR         pwszFileSource,
  [in]  LPWSTR         pwszFileDest,
  [in]  IWMDMOperation *pOperation,
  [in]  IWMDMProgress  *pProgress,
  [in]  IWMDMMetaData  *pMetaData,
  [in]  IUnknown       *pUnknown,
  [out] IWMDMStorage   **ppNewObject
);

参数

[in] fuMode

用于 Insert3 操作的处理模式。 下表列出了可在 fuMode 参数中指定的处理模式。 必须指定前两种模式之一、STORAGECONTROL 模式之一和 CONTENT 模式之一。 如果同时指定WMDM_MODE_BLOCK和WMDM_MODE_THREAD,则使用块模式。 在此函数中指定 WMDM_FILE_ATTR* 标志比先调用此函数更高效,然后在创建或发送文件后在文件上设置这些属性。

组合 “模式” 说明
恰好是以下项之一: WMDM_MODE_BLOCK 该操作是使用块模式处理执行的。 在操作完成之前,调用不会返回。
- WMDM_MODE_THREAD 该操作是使用线程模式处理执行的。 调用将立即返回,并且操作在后台线程中执行。
可选 WMDM_MODE_QUERY 执行测试以确定插入操作是否可以成功,但不会执行插入。
恰好是以下项之一: WMDM_STORAGECONTROL_INSERTBEFORE 对象插入到目标对象之前。
- WMDM_STORAGECONTROL_INSERTAFTER 对象插入到目标对象之后。
- WMDM_STORAGECONTROL_INSERTINTO 对象插入到当前对象中。 仅当当前对象是文件夹时,此操作才起作用。
可选 WMDM_FILE_CREATE_OVERWRITE 对象将替换目标对象。
恰好是以下项之一: WMDM_CONTENT_FILE 要插入的内容是文件。
- WMDM_CONTENT_FOLDER 要插入的内容是一个文件夹。 这不会传输文件夹的内容。
可选 WMDM_CONTENT_OPERATIONINTERFACE 应用程序正在传入 IWMDMOperation 接口来控制数据传输。
零个或多个: WMDM_FILE_ATTR_READONLY 应在设备上将存储设置为只读。
- WMDM_FILE_ATTR_HIDDEN 存储应设置为在设备上隐藏。
- WMDM_FILE_ATTR_SYSTEM 存储应设置为设备上的系统。
可选 WMDM_MODE_PROGRESS 插入正在进行中。
可选选项之一: WMDM_MODE_TRANSFER_PROTECTED 插入处于受保护的传输模式。
- WMDM_MODE_TRANSFER_UNPROTECTED 插入处于不受保护的传输模式。

[in] fuType

以下类型之一,指定当前存储。

说明
WMDM_FILE_ATTR_FILE 当前存储是一个文件。
WMDM_FILE_ATTR_FOLDER 当前存储是一个文件夹。

[in] pwszFileSource

指向宽字符、 以 null 结尾的字符串的指针,指示在何处查找插入操作的内容。 如果在 fuMode 中指定了WMDM_CONTENT_OPERATIONINTERFACE,此参数必须为 NULL。 如果正在创建播放列表或专辑,此参数可以为 NULL

[in] pwszFileDest

设备上文件的可选名称。 如果未指定,并且应用程序将 IWMDMOperation 指针传递给 pOperation,Windows Media 设备管理器将通过调用 IWMDMOperation::GetObjectName 来请求目标名称。 如果未指定并且应用程序不使用 pOperation,则原始文件名和扩展名 (不使用路径) 。

[in] pOperation

指向 IWMDMOperation 接口的 可选指针,用于控制内容到媒体设备的传输。 如果指定, 则 fuMode 必须包含 WMDM_CONTENT_OPERATIONINTERFACE 标志。 如果在 fuMode 中指定了WMDM_CONTENT_FILE或WMDM_CONTENT_FOLDER,此参数必须为 NULL

[in] pProgress

指向 IWMDMProgress 接口的可选指针,用于将操作进度报告回应用程序。 此参数可以为 NULL。

[in] pMetaData

指向元数据对象的可选指针。 通过调用 IWMDMStorage3::CreateEmptyMetadataObject 创建新的元数据对象。 此参数允许应用程序指定元数据 (包括在设备上创建对象期间在设备上设置的格式) ,这比之后设置元数据更高效。 必须设置g_wszWMDMFormatCode) 指定的文件格式 (。 如果使用此方法时未指定文件的格式代码,则 MTP 设备不会在其用户界面中显示文件,并且非 MTP 设备的行为将不可预知。

[in] pUnknown

要传递给安全内容提供程序的任何自定义 COM 对象的可选 IUnknown 指针。 这样,如果应用程序具有有关安全内容提供程序的足够信息,则有可能将自定义信息传递给安全内容提供程序。

[out] ppNewObject

指向将包含新内容的 IWMDMStorage 接口的指针。 调用方在完成此接口后必须释放它。

返回值

该方法返回 HRESULT。 Windows Media 设备管理器 中的所有接口方法都可以返回以下任一类错误代码:

  • 标准 COM 错误代码
  • 转换为 HRESULT 值的 Windows 错误代码
  • Windows Media 设备管理器错误代码
有关可能错误代码的广泛列表,请参阅 错误代码

注解

尽管可以在将元数据发送到设备后在存储上设置元数据,但在此方法的 pMetaData 参数中设置此信息会更有效。 这样做会向设备提供其他信息,使其能够适当地 (传输和处理文件,例如,将文件存储在正确的位置) 或显示有用的信息 (,例如用户编写的图片说明) 。

若要设置 Windows Portable Devices (WPD) 设备的属性,应用程序将创建 IPortableDeviceValues 对象并将每个属性设置为此集合。 然后,应用程序会将集合序列化为 BLOB) (二进制大型对象。 序列化数据后,应用程序将使用g_wszWPDPassthroughPropertyValues元数据常量将其添加到 pMetadata 参数引用的 IWMDMMetaData

如果指定了WMDM_MODE_THREAD标志,则应通过调用 IWMDMProgress2::End2IWMDMProgress3::End3 获取完成状态。 这些方法将确保操作完成,并将返回包含成功或失败信息的 HRESULT。

如果应用程序使用 WMDM_MODE_THREAD 并传递非 nullpProgress 参数,则应用程序必须确保在读取操作完成之前不会销毁 pProgress 所属的对象,因为 Windows Media 设备管理器 将向此对象发送进度通知。 此对象只有在收到结束通知后才能销毁。 如果不这样做,将导致访问冲突。

创建播放列表或其他引用对象时,“插入”的对象实际上不包含任何数据,而只是作为一组对其他对象的元数据引用存储在设备上, (如音乐文件) 。 在设备上创建播放列表中介绍了在播放列表上 创建此类“抽象”对象。

示例

以下 C++ 函数将文件发送到设备。 作为传输的一部分,它必须将元数据添加到存储以指定新的存储类型。


HRESULT mySendFile(LPCWSTR pwszFileName, IWMDMStorage* pStorage, IWMDMOperation* pOperation)
{
   HRESULT hr = S_OK;

   // A dummy loop to handle unrecoverable errors. When we hit an error we
   // can't handle or don't like, we just use a 'break' statement.
   // The custom BREAK_HR macro checks for failed HRESULT values and does this.
   do
   {
      if (pwszFileName == NULL || pStorage == NULL)
      {
         BREAK_HR(E_POINTER,"","Bad pointer passed in.");
         return E_POINTER;
      }

      // Make sure the destination is a folder.
      DWORD attributes = 0;
      _WAVEFORMATEX format;
      hr = pStorage->GetAttributes(&attributes, &format);
      if (!(attributes | WMDM_FILE_ATTR_FOLDER))
      {
         BREAK_HR(E_FAIL, "", "Storage submitted to mySendFile is not a folder.");
         return E_FAIL;
      }

      // Transcode the file
      hr = myTranscodeMethod(pwszFileName);
      BREAK_HR(hr, "Couldn't transcode the file in mySendFile.", "Transcoded the file in mySendFile.");
      //
      // Let's set some metadata in the storage.
      //
      CComPtr<IWMDMStorage3> pStorage3;
      hr = pStorage->QueryInterface(__uuidof(IWMDMStorage3), (void**)(&pStorage3));
      BREAK_HR(hr, "Got an IWMDMStorage3 interface in mySendFile.","Couldn't get an IWMDMStorage3 in mySendFile.");

      // First create the IWMDMMetaData interface.
      IWMDMMetaData* pMetadata;
      hr = pStorage3->CreateEmptyMetadataObject(&pMetadata);
      BREAK_HR(hr,"Created an IWMDMMetaData interface in mySendFile.","Couldn't create an IWMDMMetaData interface in mySendFile.");

      //
      // Set the file format.
      //
      WMDM_FORMATCODE fileFormat = myGetWMDM_FORMATCODE(pwszFileName);
      hr = pMetadata->AddItem(WMDM_TYPE_DWORD, g_wszWMDMFormatCode, (BYTE*)&fileFormat, sizeof(WMDM_TYPE_DWORD));


      //
      // Get the proper interface and transfer the file.
      //
      CComPtr<IWMDMStorageControl3> pStgCtl3;
      CComPtr<IWMDMStorage> pNewStorage;
      hr = pStorage->QueryInterface(__uuidof(IWMDMStorageControl3),(void**)(&pStgCtl3));

      // Get the simple file name to use for the destination file.
      wstring destFile = pwszFileName;
      destFile = destFile.substr(destFile.find_last_of(L"\\") + 1);

      // Get a progress indicator.
      CComQIPtr<IWMDMProgress> pProgress(this);

      // Set the flags for the operation.
      UINT flags = WMDM_MODE_BLOCK | // Synchronous call. 
         WMDM_STORAGECONTROL_INSERTINTO | // Insert it into the destination folder.
         WMDM_CONTENT_FILE | // We're inserting a file.
         WMDM_FILE_CREATE_OVERWRITE; // Overwrite existing files.
      if (pOperation != NULL)
         flags |= WMDM_CONTENT_OPERATIONINTERFACE;

      // Send the file and metadata.
      hr = pStgCtl3->Insert3(
         flags,
         WMDM_FILE_ATTR_FOLDER, // The current storage is a folder.
         const_cast<WCHAR*>(pwszFileName), // Source file.
         NULL, // Destination file name.
         pOperation, // Null to allow Windows Media Device Manager to read 
                     // the file; non-null to present raw data bytes to 
                     // Windows Media Device Manager.
         pProgress, // Interface to send simple progress notifications.
         pMetadata, // IWMDMMetaData interface previously created and filled.
         NULL, 
         &pNewStorage);
      if (FAILED(hr))
         m_pLogger->LogDword(WMDM_LOG_SEV_ERROR, NULL, "Error calling Insert3 in mySendFile: %lX", hr);
      BREAK_HR(hr, "Wrote a file to the device in mySendFile", "Couldn't write to the device in mySendFile.");

   } while (FALSE); // End of dummy loop

   return hr;
}

要求

要求
目标平台 Windows
标头 mswmdm.h
Library Mssachlp.lib

另请参阅

在设备上创建播放列表

IWMDMDevice::GetStatus

IWMDMMetaData 接口

IWMDMOperation 接口

IWMDMProgress 接口

IWMDMStorage 接口

IWMDMStorageControl2::Insert2

IWMDMStorageControl3 接口

将文件写入设备