iWMDMOperation::TransferObjectData 方法 (mswmdm.h)

调用 TransferObjectData 方法以允许应用程序向计算机或从计算机传输数据块。

语法

HRESULT TransferObjectData(
  BYTE     *pData,
  DWORD    *pdwSize,
  BYTE [8] abMac
);

参数

pData

指向包含数据的缓冲区的指针。 此缓冲区始终由 Windows Media 设备管理器分配和释放。 应用程序绝不应分配或释放此缓冲区。

BeginRead[in] 在从设备读取期间,必须使用 CSecureChannelClient::D ecryptParam 方法解密的传入数据。 应用程序不需要解除分配缓冲区。

BeginWrite[in, out] 在写入设备期间,输入时是一个由 Windows Media 设备管理器分配的内存缓冲区 pdwSize 字节。 应用程序应使用已使用 CSecureChannelClient::EncryptParam 方法加密的数据填充此缓冲区。

pdwSize

指向指定传输缓冲区大小的 DWORD 的指针。

BeginRead[in, out] 输入时, pData 中传入数据的大小。 在输出中,应用程序实际读取的数据量。

BeginWriteOn 输入, 即 pData 缓冲区的大小。 输出时,发送的数据的实际大小。

abMac

字节数组,指定此方法的参数数据的消息身份验证代码。

BeginRead[in] 从 pDatapdwSize 生成的 MAC,应用程序应在解密 pData 后检查,以验证数据是否尚未修改。

BeginWrite[out] 加密 pData之前从 pData 和 pdwSize 生成的 MAC。

返回值

应用程序应返回以下 HRESULT 值之一。

返回代码 说明
S_OK
读取操作应继续。
WMDM_E_USER_CANCELLED
应取消读取操作而不完成。
E_FAIL
发生未指定的错误,应取消读取操作而不完成。

注解

应用程序可以通过监视是否在调用此方法之前调用 BeginReadBeginWrite 来确定是否正在从设备读取或写入数据。

示例

以下 C++ 代码演示应用程序如何实现 TransferObjectData 来处理文件传输本身。 显示的代码处理从设备读取数据和将数据写入设备。 数据流的方向由 成员变量m_OperationStatus指示,该变量在对 BeginReadBeginWrite 的先前调用中设置。


HRESULT TransferObjectData(BYTE* pData, DWORD* pdwSize, BYTE* pMac)
{
    HRESULT hr = S_OK;

    // Verify parameters.
    if (pData == NULL || pdwSize == NULL || pMac == NULL || m_File == INVALID_HANDLE_VALUE) 
    {
        // TODO: Display the message: "Invalid argument in SetObjectTotalSize."
        return E_INVALIDARG;
    }
    if ((m_OperationStatus != OPERATION_READ) && (m_OperationStatus != OPERATION_WRITE))
    {
        // TODO: Display the message: "Unable to determine direction of data transfer."
        return E_FAIL;
    }

    //////////////////////////////////////////////////////////////////////////
// Sending data to the device.
//////////////////////////////////////////////////////////////////////////
    if (m_OperationStatus == OPERATION_WRITE)
    {
        DWORD   dwReadLen;
        // The SAC is used to encrypt the data sent to the device.
        if (m_pSAC == NULL) 
        {
               // TODO: Display the message: "SAC not initialized in TransferObjectData."
            return E_FAIL;
        }

        // Read pdwSize bytes from the file into pData.
        dwReadLen = *pdwSize;
        if (ReadFile(m_File, pData, dwReadLen, pdwSize, NULL) == FALSE) 
        {
               // TODO: Display the message: "Couldn't read the file in TransferObjectData."
            return E_FAIL;
        }

        // If there is no more data, terminate the transfer.
        if (*pdwSize == 0)
        {
            return S_FALSE;
        }

        // Create the MAC to return to Windows Media Device Manager.
        HMAC hMAC;
        hr = m_pSAC->MACInit(&hMAC);
        hr = m_pSAC->MACUpdate(hMAC, (BYTE*)(pData), *pdwSize);
        hr = m_pSAC->MACUpdate(hMAC, (BYTE*)(pdwSize), sizeof(DWORD));
        hr = m_pSAC->MACFinal(hMAC, (BYTE*)pMac);
        if (hr != S_OK) return E_FAIL;

        // Encrypt the data to send to the service provider/device.
        hr = m_pSAC->EncryptParam((BYTE*)(pData), *pdwSize);
        if (hr != S_OK) 
        {
            return E_FAIL;
        }
    }
    //////////////////////////////////////////////////////////////////////////
// Receiving data from the device.
//////////////////////////////////////////////////////////////////////////
    else 
    {
        // Copy the data to a temporary file for decryption.
        BYTE *pTmpData = new BYTE [*pdwSize];
        if (pTmpData == NULL)
        {
            return E_OUTOFMEMORY;
        }
        memcpy(pTmpData, pData, *pdwSize);

        // Decrypt the pData Parameter
        hr = m_pSAC->DecryptParam(pTmpData, *pdwSize);
        
        // Verify the MAC of the decrypted data.
        HMAC hMAC;
        BYTE pTestMac[WMDM_MAC_LENGTH];
        hr = m_pSAC->MACInit(&hMAC);
        hr = m_pSAC->MACUpdate(hMAC, (BYTE*)(pTmpData), *pdwSize);
        hr = m_pSAC->MACUpdate(hMAC, (BYTE*)(pdwSize), sizeof(*pdwSize));
        hr = m_pSAC->MACFinal(hMAC, pTestMac);
        if ((memcmp(pMac, pTestMac, WMDM_MAC_LENGTH) != 0) || (hr != S_OK))
        {
            delete [] pTmpData;
            return WMDM_E_MAC_CHECK_FAILED;
        }

        // Write the data to file, and record the amount of data written.
        DWORD dwWritten = 0;
        if (WriteFile(m_File,pTmpData,*pdwSize,&dwWritten,NULL))
        {
            hr = S_OK;
            *pdwSize = dwWritten;
        }
        else 
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
        }
        if (pTmpData)
        {
            delete [] pTmpData;
        }
    }
    return hr;
}

要求

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

另请参阅

加密和解密

手动处理文件传输

IWMDMOperation 接口

使用经过安全身份验证的通道