IWMDMStorage::SendOpaqueCommand 方法 (mswmdm.h)

SendOpaqueCommand 方法通过 Windows Media 设备管理器将命令发送到存储,而无需处理它。

语法

HRESULT SendOpaqueCommand(
  [in, out] OPAQUECOMMAND *pCommand
);

参数

[in, out] pCommand

指向包含要执行的命令的 OPAQUECOMMAND 结构的指针。 可以通过两种方式将数据传递:从应用程序传递到设备,以及从设备传回应用程序(当调用完成时)。

返回值

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

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

注解

此方法适用于不影响 Windows Media 设备管理器操作的存储媒体命令,应通过未更改传递。

示例

以下 C++ 代码调用 SendOpaqueCommand 以对设备执行简单的自定义身份验证步骤。 调用方将其证书和 MAC 发送到设备,设备将发送回自己的证书和 MAC。 应用程序将检索到的证书与其存储的证书进行比较,如果它们与 (匹配并且 MAC) 正确,则会将 bExtraCertified 设置为 TRUE


    // Call SendOpaqueCommand to exchange extended authentication information.
    {
        HMAC           hMAC;
        OPAQUECOMMAND  Command;
        CERTINFOEX    *pCertInfoEx;
        DWORD          cbData_App   = sizeof(bCertInfoEx_App)/sizeof(bCertInfoEx_App[0]);
        DWORD          cbData_SP    = sizeof(bCertInfoEx_SP)/sizeof(bCertInfoEx_SP[0]);
        DWORD          cbData_Send  = sizeof(CERTINFOEX) + cbData_App;

        // Fill opaque command structure with the application's certificate.
        memcpy(&(Command.guidCommand), &guidCertInfoEx, sizeof(GUID));

        Command.pData = (BYTE *)CoTaskMemAlloc(cbData_Send);
        if (!Command.pData)
        {
            ExitOnFail(hr = E_OUTOFMEMORY);
        }
        Command.dwDataLen = cbData_Send;

        // Map the data in the opaque command to a CERTINFOEX structure, and
        // fill in the cert info to send.
        pCertInfoEx = (CERTINFOEX *)Command.pData;
        pCertInfoEx->hr     = S_OK;
        pCertInfoEx->cbCert = cbData_App;
        memcpy(pCertInfoEx->pbCert, bCertInfoEx_App, cbData_App);

        // Compute MAC on the data, and add to the OPAQUECOMMAND struct.
        g_cWmdm.m_pSAC->MACInit(&hMAC);
        g_cWmdm.m_pSAC->MACUpdate(hMAC, (BYTE*)(&(Command.guidCommand)), sizeof(GUID));
        g_cWmdm.m_pSAC->MACUpdate(hMAC, (BYTE*)(&(Command.dwDataLen)), sizeof(Command.dwDataLen));
        if (Command.pData)
        {
            g_cWmdm.m_pSAC->MACUpdate(hMAC, Command.pData, Command.dwDataLen);
        }
        g_cWmdm.m_pSAC->MACFinal(hMAC, Command.abMAC);

        // Send the opaque command.
        hr = pDevice->SendOpaqueCommand(&Command);
        if (SUCCEEDED(hr))
        {
            // Now verify the retrieved MAC.
            BYTE abMACVerify2[ WMDM_MAC_LENGTH ];
            g_cWmdm.m_pSAC->MACInit(&hMAC);
            g_cWmdm.m_pSAC->MACUpdate(hMAC, (BYTE*)(&(Command.guidCommand)), sizeof(GUID));
            g_cWmdm.m_pSAC->MACUpdate(hMAC, (BYTE*)(&(Command.dwDataLen)), sizeof(Command.dwDataLen));
            if (Command.pData)
            {
                g_cWmdm.m_pSAC->MACUpdate(hMAC, Command.pData, Command.dwDataLen);
            }
            g_cWmdm.m_pSAC->MACFinal(hMAC, abMACVerify2);

            // Verify MAC matches.
            if (memcmp(abMACVerify2, Command.abMAC, WMDM_MAC_LENGTH) == 0)
            {
                 // They match; verify the retrieved certificate.
                // Map the data in the opaque command to a CERTINFOEX structure
                //
                pCertInfoEx = (CERTINFOEX *)Command.pData;

                // In this simple extended authentication scheme, the callee must
                // provide the exact certificate information.
                //
                if ((pCertInfoEx->cbCert != cbData_SP) &&
                    (memcmp(pCertInfoEx->pbCert, bCertInfoEx_SP, cbData_SP) == 0))
                {
                    bExtraCertified = TRUE;
                }
            }
        }

        if (Command.pData)
        {
            CoTaskMemFree(Command.pData);
        }
    }

要求

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

另请参阅

IWMDMStorage 接口