利用DirectSound实现声卡录音【老毕改版】【Part3】

  1. //--------------------------------------------------------------------------------------
  2. // File: WaveFile.h
  3. //
  4. // Copyright (c) Microsoft Corporation. All rights reserved.
  5. //--------------------------------------------------------------------------------------
  6. #pragma comment(lib, "winmm.lib")
  7. #pragma once
  8. #include <windows.h>
  9. #include <mmsystem.h>
  10. #include <mmreg.h>
  11. #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p) = NULL; } }
  12. #define SAFE_DELETE_ARRAY(p) { if(p) { delete [](p); (p) = NULL; } }
  13. #define SAFE_DELETE(p) { if(p) { delete (p); (p) = NULL; } }
  14. //-----------------------------------------------------------------------------
  15. // Typing macros 
  16. //-----------------------------------------------------------------------------
  17. #define WAVEFILE_READ   1
  18. #define WAVEFILE_WRITE  2
  19. class CWaveFile
  20. {
  21. public:
  22.     WAVEFORMATEX* m_pwfx;        // Pointer to WAVEFORMATEX structure
  23.     HMMIO m_hmmio;       // MM I/O handle for the WAVE
  24.     MMCKINFO m_ck;          // Multimedia RIFF chunk
  25.     MMCKINFO m_ckRiff;      // Use in opening a WAVE file
  26.     DWORD m_dwSize;      // The size of the wave file
  27.     MMIOINFO m_mmioinfoOut;
  28.     DWORD m_dwFlags;
  29.     BOOL m_bIsReadingFromMemory;
  30.     BYTE* m_pbData;
  31.     BYTE* m_pbDataCur;
  32.     ULONG m_ulDataSize;
  33.     CHAR* m_pResourceBuffer;
  34. protected:
  35.     HRESULT ReadMMIO();
  36.     HRESULT WriteMMIO( WAVEFORMATEX* pwfxDest );
  37. public:
  38.     CWaveFile();
  39.     ~CWaveFile();
  40.     HRESULT Open( LPTSTR strFileName, WAVEFORMATEX* pwfx, DWORD dwFlags );
  41.     HRESULT OpenFromMemory( BYTE* pbData, ULONG ulDataSize, WAVEFORMATEX* pwfx, DWORD dwFlags );
  42.     HRESULT Close();
  43.     HRESULT Read( BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead );
  44.     HRESULT Write( UINT nSizeToWrite, BYTE* pbData, UINT* pnSizeWrote );
  45.     DWORD   GetSize();
  46.     HRESULT ResetFile();
  47.     WAVEFORMATEX* GetFormat()
  48.     {
  49.         return m_pwfx;
  50.     };
  51. };
  52. //--------------------------------------------------------------------------------------
  53. // File: WaveFile.cpp
  54. //
  55. // Copyright (c) Microsoft Corporation. All rights reserved.
  56. //--------------------------------------------------------------------------------------
  57. #include "stdafx.h"
  58. #include "WaveFile.h"
  59. //-----------------------------------------------------------------------------
  60. // Name: CWaveFile::CWaveFile()
  61. // Desc: Constructs the class.  Call Open() to open a wave file for reading.
  62. //       Then call Read() as needed.  Calling the destructor or Close()
  63. //       will close the file.
  64. //-----------------------------------------------------------------------------
  65. CWaveFile::CWaveFile()
  66. {
  67.     m_pwfx = NULL;
  68.     m_hmmio = NULL;
  69.     m_pResourceBuffer = NULL;
  70.     m_dwSize = 0;
  71.     m_bIsReadingFromMemory = FALSE;
  72. }
  73. //-----------------------------------------------------------------------------
  74. // Name: CWaveFile::~CWaveFile()
  75. // Desc: Destructs the class
  76. //-----------------------------------------------------------------------------
  77. CWaveFile::~CWaveFile()
  78. {
  79.     Close();
  80.     if( !m_bIsReadingFromMemory )
  81.         SAFE_DELETE_ARRAY( m_pwfx );
  82. }
  83. //-----------------------------------------------------------------------------
  84. // Name: CWaveFile::Open()
  85. // Desc: Opens a wave file for reading
  86. //-----------------------------------------------------------------------------
  87. HRESULT CWaveFile::Open( LPTSTR strFileName, WAVEFORMATEX* pwfx, DWORD dwFlags )
  88. {
  89.     HRESULT hr;
  90.     m_dwFlags = dwFlags;
  91.     m_bIsReadingFromMemory = FALSE;
  92.     if( m_dwFlags == WAVEFILE_READ )
  93.     {
  94.         if( strFileName == NULL )
  95.             return E_INVALIDARG;
  96.         SAFE_DELETE_ARRAY( m_pwfx );
  97.         m_hmmio = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF | MMIO_READ );
  98.         if( NULL == m_hmmio )
  99.         {
  100.             HRSRC hResInfo;
  101.             HGLOBAL hResData;
  102.             DWORD dwSize;
  103.             VOID* pvRes;
  104.             // Loading it as a file failed, so try it as a resource
  105.             if( NULL == ( hResInfo = FindResource( NULL, strFileName, TEXT( "WAVE" ) ) ) )
  106.             {
  107.                 if( NULL == ( hResInfo = FindResource( NULL, strFileName, TEXT( "WAV" ) ) ) )
  108.                     return E_FAIL;
  109.             }
  110.             if( NULL == ( hResData = LoadResource( GetModuleHandle( NULL ), hResInfo ) ) )
  111.                 return E_FAIL;
  112.             if( 0 == ( dwSize = SizeofResource( GetModuleHandle( NULL ), hResInfo ) ) )
  113.                 return E_FAIL;
  114.             if( NULL == ( pvRes = LockResource( hResData ) ) )
  115.                 return E_FAIL;
  116.             m_pResourceBuffer = new CHAR[ dwSize ];
  117.             if( m_pResourceBuffer == NULL )
  118.                 return E_OUTOFMEMORY;
  119.             memcpy( m_pResourceBuffer, pvRes, dwSize );
  120.             MMIOINFO mmioInfo;
  121.             ZeroMemory( &mmioInfo, sizeof( mmioInfo ) );
  122.             mmioInfo.fccIOProc = FOURCC_MEM;
  123.             mmioInfo.cchBuffer = dwSize;
  124.             mmioInfo.pchBuffer = ( CHAR* )m_pResourceBuffer;
  125.             m_hmmio = mmioOpen( NULL, &mmioInfo, MMIO_ALLOCBUF | MMIO_READ );
  126.         }
  127.         if( FAILED( hr = ReadMMIO() ) )
  128.         {
  129.             // ReadMMIO will fail if its an not a wave file
  130.             mmioClose( m_hmmio, 0 );
  131.             return hr;
  132.         }
  133.         if( FAILED( hr = ResetFile() ) )
  134.             return hr;
  135.         // After the reset, the size of the wav file is m_ck.cksize so store it now
  136.         m_dwSize = m_ck.cksize;
  137.     }
  138.     else
  139.     {
  140.         m_hmmio = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF |
  141.             MMIO_READWRITE |
  142.             MMIO_CREATE );
  143.         if( NULL == m_hmmio )
  144.             return E_FAIL;
  145.         if( FAILED( hr = WriteMMIO( pwfx ) ) )
  146.         {
  147.             mmioClose( m_hmmio, 0 );
  148.             return hr;
  149.         }
  150.         if( FAILED( hr = ResetFile() ) )
  151.             return hr;
  152.     }
  153.     return hr;
  154. }
  155. //-----------------------------------------------------------------------------
  156. // Name: CWaveFile::OpenFromMemory()
  157. // Desc: copy data to CWaveFile member variable from memory
  158. //-----------------------------------------------------------------------------
  159. HRESULT CWaveFile::OpenFromMemory( BYTE* pbData, ULONG ulDataSize,
  160.                                   WAVEFORMATEX* pwfx, DWORD dwFlags )
  161. {
  162.     m_pwfx = pwfx;
  163.     m_ulDataSize = ulDataSize;
  164.     m_pbData = pbData;
  165.     m_pbDataCur = m_pbData;
  166.     m_bIsReadingFromMemory = TRUE;
  167.     if( dwFlags != WAVEFILE_READ )
  168.         return E_NOTIMPL;
  169.     return S_OK;
  170. }
  171. //-----------------------------------------------------------------------------
  172. // Name: CWaveFile::ReadMMIO()
  173. // Desc: Support function for reading from a multimedia I/O stream.
  174. //       m_hmmio must be valid before calling.  This function uses it to
  175. //       update m_ckRiff, and m_pwfx.
  176. //-----------------------------------------------------------------------------
  177. HRESULT CWaveFile::ReadMMIO()
  178. {
  179.     MMCKINFO ckIn;           // chunk info. for general use.
  180.     PCMWAVEFORMAT pcmWaveFormat;  // Temp PCM structure to load in.
  181.     m_pwfx = NULL;
  182.     if( ( 0 != mmioDescend( m_hmmio, &m_ckRiff, NULL, 0 ) ) )
  183.         return E_FAIL;
  184.     // Check to make sure this is a valid wave file
  185.     if( ( m_ckRiff.ckid != FOURCC_RIFF ) ||
  186.         ( m_ckRiff.fccType != mmioFOURCC( 'W''A''V''E' ) ) )
  187.         return E_FAIL;
  188.     // Search the input file for for the 'fmt ' chunk.
  189.     ckIn.ckid = mmioFOURCC( 'f''m''t'' ' );
  190.     if( 0 != mmioDescend( m_hmmio, &ckIn, &m_ckRiff, MMIO_FINDCHUNK ) )
  191.         return E_FAIL;
  192.     // Expect the 'fmt' chunk to be at least as large as <PCMWAVEFORMAT>;
  193.     // if there are extra parameters at the end, we'll ignore them
  194.     if( ckIn.cksize < ( LONG )sizeof( PCMWAVEFORMAT ) )
  195.         return E_FAIL;
  196.     // Read the 'fmt ' chunk into <pcmWaveFormat>.
  197.     if( mmioRead( m_hmmio, ( HPSTR )&pcmWaveFormat,
  198.         sizeof( pcmWaveFormat ) ) != sizeof( pcmWaveFormat ) )
  199.         return E_FAIL;
  200.     // Allocate the waveformatex, but if its not pcm format, read the next
  201.     // word, and thats how many extra bytes to allocate.
  202.     if( pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM )
  203.     {
  204.         m_pwfx = ( WAVEFORMATEX* )new CHARsizeof( WAVEFORMATEX ) ];
  205.         if( NULL == m_pwfx )
  206.             return E_FAIL;
  207.         // Copy the bytes from the pcm structure to the waveformatex structure
  208.         memcpy( m_pwfx, &pcmWaveFormat, sizeof( pcmWaveFormat ) );
  209.         m_pwfx->cbSize = 0;
  210.     }
  211.     else
  212.     {
  213.         // Read in length of extra bytes.
  214.         WORD cbExtraBytes = 0L;
  215.         if( mmioRead( m_hmmio, ( CHAR* )&cbExtraBytes, sizeofWORD ) ) != sizeofWORD ) )
  216.             return E_FAIL;
  217.         m_pwfx = ( WAVEFORMATEX* )new CHARsizeof( WAVEFORMATEX ) + cbExtraBytes ];
  218.         if( NULL == m_pwfx )
  219.             return E_FAIL;
  220.         // Copy the bytes from the pcm structure to the waveformatex structure
  221.         memcpy( m_pwfx, &pcmWaveFormat, sizeof( pcmWaveFormat ) );
  222.         m_pwfx->cbSize = cbExtraBytes;
  223.         // Now, read those extra bytes into the structure, if cbExtraAlloc != 0.
  224.         if( mmioRead( m_hmmio, ( CHAR* )( ( ( BYTE* )&( m_pwfx->cbSize ) ) + sizeofWORD ) ),
  225.             cbExtraBytes ) != cbExtraBytes )
  226.         {
  227.             SAFE_DELETE_ARRAY( m_pwfx );
  228.             return E_FAIL;
  229.         }
  230.     }
  231.     // Ascend the input file out of the 'fmt ' chunk.
  232.     if( 0 != mmioAscend( m_hmmio, &ckIn, 0 ) )
  233.     {
  234.         SAFE_DELETE_ARRAY( m_pwfx );
  235.         return E_FAIL;
  236.     }
  237.     return S_OK;
  238. }
  239. //-----------------------------------------------------------------------------
  240. // Name: CWaveFile::GetSize()
  241. // Desc: Retuns the size of the read access wave file
  242. //-----------------------------------------------------------------------------
  243. DWORD CWaveFile::GetSize()
  244. {
  245.     return m_dwSize;
  246. }
  247. //-----------------------------------------------------------------------------
  248. // Name: CWaveFile::ResetFile()
  249. // Desc: Resets the internal m_ck pointer so reading starts from the
  250. //       beginning of the file again
  251. //-----------------------------------------------------------------------------
  252. HRESULT CWaveFile::ResetFile()
  253. {
  254.     if( m_bIsReadingFromMemory )
  255.     {
  256.         m_pbDataCur = m_pbData;
  257.     }
  258.     else
  259.     {
  260.         if( m_hmmio == NULL )
  261.             return CO_E_NOTINITIALIZED;
  262.         if( m_dwFlags == WAVEFILE_READ )
  263.         {
  264.             // Seek to the data
  265.             if( -1 == mmioSeek( m_hmmio, m_ckRiff.dwDataOffset + sizeof( FOURCC ),
  266.                 SEEK_SET ) )
  267.                 return E_FAIL;
  268.             // Search the input file for the 'data' chunk.
  269.             m_ck.ckid = mmioFOURCC( 'd''a''t''a' );
  270.             if( 0 != mmioDescend( m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK ) )
  271.                 return E_FAIL;
  272.         }
  273.         else
  274.         {
  275.             // Create the 'data' chunk that holds the waveform samples.
  276.             m_ck.ckid = mmioFOURCC( 'd''a''t''a' );
  277.             m_ck.cksize = 0;
  278.             if( 0 != mmioCreateChunk( m_hmmio, &m_ck, 0 ) )
  279.                 return E_FAIL;
  280.             if( 0 != mmioGetInfo( m_hmmio, &m_mmioinfoOut, 0 ) )
  281.                 return E_FAIL;
  282.         }
  283.     }
  284.     return S_OK;
  285. }
  286. //-----------------------------------------------------------------------------
  287. // Name: CWaveFile::Read()
  288. // Desc: Reads section of data from a wave file into pBuffer and returns
  289. //       how much read in pdwSizeRead, reading not more than dwSizeToRead.
  290. //       This uses m_ck to determine where to start reading from.  So
  291. //       subsequent calls will be continue where the last left off unless
  292. //       Reset() is called.
  293. //-----------------------------------------------------------------------------
  294. HRESULT CWaveFile::Read( BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead )
  295. {
  296.     if( m_bIsReadingFromMemory )
  297.     {
  298.         if( m_pbDataCur == NULL )
  299.             return CO_E_NOTINITIALIZED;
  300.         if( pdwSizeRead != NULL )
  301.             *pdwSizeRead = 0;
  302.         if( ( BYTE* )( m_pbDataCur + dwSizeToRead ) >
  303.             ( BYTE* )( m_pbData + m_ulDataSize ) )
  304.         {
  305.             dwSizeToRead = m_ulDataSize - ( DWORD )( m_pbDataCur - m_pbData );
  306.         }
  307.         CopyMemory( pBuffer, m_pbDataCur, dwSizeToRead );
  308.         if( pdwSizeRead != NULL )
  309.             *pdwSizeRead = dwSizeToRead;
  310.         return S_OK;
  311.     }
  312.     else
  313.     {
  314.         MMIOINFO mmioinfoIn; // current status of m_hmmio
  315.         if( m_hmmio == NULL )
  316.             return CO_E_NOTINITIALIZED;
  317.         if( pBuffer == NULL || pdwSizeRead == NULL )
  318.             return E_INVALIDARG;
  319.         if( pdwSizeRead != NULL )
  320.             *pdwSizeRead = 0;
  321.         if( 0 != mmioGetInfo( m_hmmio, &mmioinfoIn, 0 ) )
  322.             return E_FAIL;
  323.         UINT cbDataIn = dwSizeToRead;
  324.         if( cbDataIn > m_ck.cksize )
  325.             cbDataIn = m_ck.cksize;
  326.         m_ck.cksize -= cbDataIn;
  327.         forDWORD cT = 0; cT < cbDataIn; cT++ )
  328.         {
  329.             // Copy the bytes from the io to the buffer.
  330.             if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead )
  331.             {
  332.                 if( 0 != mmioAdvance( m_hmmio, &mmioinfoIn, MMIO_READ ) )
  333.                     return E_FAIL;
  334.                 if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead )
  335.                     return E_FAIL;
  336.             }
  337.             // Actual copy.
  338.             *( ( BYTE* )pBuffer + cT ) = *( ( BYTE* )mmioinfoIn.pchNext );
  339.             mmioinfoIn.pchNext++;
  340.         }
  341.         if( 0 != mmioSetInfo( m_hmmio, &mmioinfoIn, 0 ) )
  342.             return E_FAIL;
  343.         if( pdwSizeRead != NULL )
  344.             *pdwSizeRead = cbDataIn;
  345.         return S_OK;
  346.     }
  347. }
  348. //-----------------------------------------------------------------------------
  349. // Name: CWaveFile::Close()
  350. // Desc: Closes the wave file
  351. //-----------------------------------------------------------------------------
  352. HRESULT CWaveFile::Close()
  353. {
  354.     if( m_dwFlags == WAVEFILE_READ )
  355.     {
  356.         mmioClose( m_hmmio, 0 );
  357.         m_hmmio = NULL;
  358.         SAFE_DELETE_ARRAY( m_pResourceBuffer );
  359.     }
  360.     else
  361.     {
  362.         m_mmioinfoOut.dwFlags |= MMIO_DIRTY;
  363.         if( m_hmmio == NULL )
  364.             return CO_E_NOTINITIALIZED;
  365.         if( 0 != mmioSetInfo( m_hmmio, &m_mmioinfoOut, 0 ) )
  366.             return E_FAIL;
  367.         // Ascend the output file out of the 'data' chunk -- this will cause
  368.         // the chunk size of the 'data' chunk to be written.
  369.         if( 0 != mmioAscend( m_hmmio, &m_ck, 0 ) )
  370.             return E_FAIL;
  371.         // Do this here instead...
  372.         if( 0 != mmioAscend( m_hmmio, &m_ckRiff, 0 ) )
  373.             return E_FAIL;
  374.         mmioSeek( m_hmmio, 0, SEEK_SET );
  375.         if( 0 != ( INT )mmioDescend( m_hmmio, &m_ckRiff, NULL, 0 ) )
  376.             return E_FAIL;
  377.         m_ck.ckid = mmioFOURCC( 'f''a''c''t' );
  378.         if( 0 == mmioDescend( m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK ) )
  379.         {
  380.             DWORD dwSamples = 0;
  381.             mmioWrite( m_hmmio, ( HPSTR )&dwSamples, sizeofDWORD ) );
  382.             mmioAscend( m_hmmio, &m_ck, 0 );
  383.         }
  384.         // Ascend the output file out of the 'RIFF' chunk -- this will cause
  385.         // the chunk size of the 'RIFF' chunk to be written.
  386.         if( 0 != mmioAscend( m_hmmio, &m_ckRiff, 0 ) )
  387.             return E_FAIL;
  388.         mmioClose( m_hmmio, 0 );
  389.         m_hmmio = NULL;
  390.     }
  391.     return S_OK;
  392. }
  393. //-----------------------------------------------------------------------------
  394. // Name: CWaveFile::WriteMMIO()
  395. // Desc: Support function for reading from a multimedia I/O stream
  396. //       pwfxDest is the WAVEFORMATEX for this new wave file.
  397. //       m_hmmio must be valid before calling.  This function uses it to
  398. //       update m_ckRiff, and m_ck.
  399. //-----------------------------------------------------------------------------
  400. HRESULT CWaveFile::WriteMMIO( WAVEFORMATEX* pwfxDest )
  401. {
  402.     DWORD dwFactChunk; // Contains the actual fact chunk. Garbage until WaveCloseWriteFile.
  403.     MMCKINFO ckOut1;
  404.     dwFactChunk = ( DWORD )-1;
  405.     // Create the output file RIFF chunk of form type 'WAVE'.
  406.     m_ckRiff.fccType = mmioFOURCC( 'W''A''V''E' );
  407.     m_ckRiff.cksize = 0;
  408.     if( 0 != mmioCreateChunk( m_hmmio, &m_ckRiff, MMIO_CREATERIFF ) )
  409.         return E_FAIL;
  410.     // We are now descended into the 'RIFF' chunk we just created.
  411.     // Now create the 'fmt ' chunk. Since we know the size of this chunk,
  412.     // specify it in the MMCKINFO structure so MMIO doesn't have to seek
  413.     // back and set the chunk size after ascending from the chunk.
  414.     m_ck.ckid = mmioFOURCC( 'f''m''t'' ' );
  415.     m_ck.cksize = sizeof( PCMWAVEFORMAT );
  416.     if( 0 != mmioCreateChunk( m_hmmio, &m_ck, 0 ) )
  417.         return E_FAIL;
  418.     // Write the PCMWAVEFORMAT structure to the 'fmt ' chunk if its that type.
  419.     if( pwfxDest->wFormatTag == WAVE_FORMAT_PCM )
  420.     {
  421.         if( mmioWrite( m_hmmio, ( HPSTR )pwfxDest,
  422.             sizeof( PCMWAVEFORMAT ) ) != sizeof( PCMWAVEFORMAT ) )
  423.             return E_FAIL;
  424.     }
  425.     else
  426.     {
  427.         // Write the variable length size.
  428.         if( ( UINT )mmioWrite( m_hmmio, ( HPSTR )pwfxDest,
  429.             sizeof( *pwfxDest ) + pwfxDest->cbSize ) !=
  430.             ( sizeof( *pwfxDest ) + pwfxDest->cbSize ) )
  431.             return E_FAIL;
  432.     }
  433.     // Ascend out of the 'fmt ' chunk, back into the 'RIFF' chunk.
  434.     if( 0 != mmioAscend( m_hmmio, &m_ck, 0 ) )
  435.         return E_FAIL;
  436.     // Now create the fact chunk, not required for PCM but nice to have.  This is filled
  437.     // in when the close routine is called.
  438.     ckOut1.ckid = mmioFOURCC( 'f''a''c''t' );
  439.     ckOut1.cksize = 0;
  440.     if( 0 != mmioCreateChunk( m_hmmio, &ckOut1, 0 ) )
  441.         return E_FAIL;
  442.     if( mmioWrite( m_hmmio, ( HPSTR )&dwFactChunk, sizeof( dwFactChunk ) ) !=
  443.         sizeof( dwFactChunk ) )
  444.         return E_FAIL;
  445.     // Now ascend out of the fact chunk...
  446.     if( 0 != mmioAscend( m_hmmio, &ckOut1, 0 ) )
  447.         return E_FAIL;
  448.     return S_OK;
  449. }
  450. //-----------------------------------------------------------------------------
  451. // Name: CWaveFile::Write()
  452. // Desc: Writes data to the open wave file
  453. //-----------------------------------------------------------------------------
  454. HRESULT CWaveFile::Write( UINT nSizeToWrite, BYTE* pbSrcData, UINT* pnSizeWrote )
  455. {
  456.     UINT cT;
  457.     if( m_bIsReadingFromMemory )
  458.         return E_NOTIMPL;
  459.     if( m_hmmio == NULL )
  460.         return CO_E_NOTINITIALIZED;
  461.     if( pnSizeWrote == NULL || pbSrcData == NULL )
  462.         return E_INVALIDARG;
  463.     *pnSizeWrote = 0;
  464.     for( cT = 0; cT < nSizeToWrite; cT++ )
  465.     {
  466.         if( m_mmioinfoOut.pchNext == m_mmioinfoOut.pchEndWrite )
  467.         {
  468.             m_mmioinfoOut.dwFlags |= MMIO_DIRTY;
  469.             if( 0 != mmioAdvance( m_hmmio, &m_mmioinfoOut, MMIO_WRITE ) )
  470.                 return E_FAIL;
  471.         }
  472.         *( ( BYTE* )m_mmioinfoOut.pchNext ) = *( ( BYTE* )pbSrcData + cT );
  473.         ( BYTE* )m_mmioinfoOut.pchNext++;
  474.         ( *pnSizeWrote )++;
  475.     }
  476.     return S_OK;
  477. }
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值