Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

615 lines
18 KiB

  1. /****************************************************************************
  2. MODULE: RIFF.CPP
  3. Tab settings: Every 4 spaces
  4. Copyright 1996, Microsoft Corporation, All Rights Reserved.
  5. PURPOSE: Classes for reading and writing RIFF files
  6. CLASSES:
  7. CRIFFFile Encapsulates common RIFF file functionality
  8. Author(s): Name:
  9. ---------- ----------------
  10. DMS Daniel M. Sangster
  11. Revision History:
  12. -----------------
  13. Version Date Author Comments
  14. 1.0 25-Jul-96 DMS Created
  15. COMMENTS:
  16. ****************************************************************************/
  17. #include "dinputpr.h"
  18. #define sqfl sqflDev
  19. /*
  20. * This function converts MMIO errors to HRESULTS
  21. */
  22. HRESULT INLINE hresMMIO(UINT mmioErr)
  23. {
  24. switch(mmioErr)
  25. {
  26. case 0x0: return S_OK;
  27. case MMIOERR_FILENOTFOUND: return hresLe(ERROR_FILE_NOT_FOUND);/* file not found */
  28. case MMIOERR_OUTOFMEMORY: return hresLe(ERROR_OUTOFMEMORY); /* out of memory */
  29. case MMIOERR_CANNOTOPEN: return hresLe(ERROR_OPEN_FAILED); /* cannot open */
  30. case MMIOERR_CANNOTCLOSE: return S_FALSE; /* cannot close */
  31. case MMIOERR_CANNOTREAD: return hresLe(ERROR_READ_FAULT); /* cannot read */
  32. case MMIOERR_CANNOTWRITE: return hresLe(ERROR_WRITE_FAULT); /* cannot write */
  33. case MMIOERR_CANNOTSEEK: return hresLe(ERROR_SEEK); /* cannot seek */
  34. case MMIOERR_CANNOTEXPAND: return hresLe(ERROR_SEEK); /* cannot expand file */
  35. case MMIOERR_CHUNKNOTFOUND: return hresLe(ERROR_SECTOR_NOT_FOUND); /* chunk not found */
  36. case MMIOERR_UNBUFFERED: return E_FAIL;
  37. case MMIOERR_PATHNOTFOUND: return hresLe(ERROR_PATH_NOT_FOUND);/* path incorrect */
  38. case MMIOERR_ACCESSDENIED: return hresLe(ERROR_ACCESS_DENIED); /* file was protected */
  39. case MMIOERR_SHARINGVIOLATION: return hresLe(ERROR_SHARING_VIOLATION); /* file in use */
  40. case MMIOERR_NETWORKERROR: return hresLe(ERROR_UNEXP_NET_ERR); /* network not responding */
  41. case MMIOERR_TOOMANYOPENFILES: return hresLe(ERROR_TOO_MANY_OPEN_FILES); /* no more file handles */
  42. case MMIOERR_INVALIDFILE: return hresLe(ERROR_BAD_FORMAT); /* default error file error */
  43. default: return E_FAIL;
  44. }
  45. }
  46. HRESULT INLINE RIFF_Ascend(HMMIO hmmio, LPMMCKINFO lpmmckinfo)
  47. {
  48. return hresMMIO( mmioAscend(hmmio, lpmmckinfo, 0) );
  49. }
  50. HRESULT INLINE RIFF_Descend(HMMIO hmmio, LPMMCKINFO lpmmckinfo, LPMMCKINFO lpmmckinfoParent, UINT nFlags)
  51. {
  52. return hresMMIO(mmioDescend(hmmio, lpmmckinfo, lpmmckinfoParent, nFlags));
  53. }
  54. HRESULT INLINE RIFF_CreateChunk(HMMIO hmmio, LPMMCKINFO lpmmckinfo, UINT nFlags)
  55. {
  56. // set cksize to zero to overcome a bug in release version of mmioAscend
  57. // which does not correctly write back the size of the chunk
  58. lpmmckinfo->cksize = 0;
  59. return hresMMIO(mmioCreateChunk(hmmio, lpmmckinfo, nFlags));
  60. }
  61. HRESULT INLINE RIFF_Read(HMMIO hmmio, LPVOID pBuf, LONG nCount)
  62. {
  63. return (nCount == mmioRead(hmmio, (char*)pBuf, nCount)) ? S_OK: hresLe(ERROR_READ_FAULT);
  64. }
  65. HRESULT INLINE RIFF_Write(HMMIO hmmio, const LPVOID pBuf, LONG nCount)
  66. {
  67. return ( nCount == mmioWrite(hmmio, (char*)pBuf, nCount)) ? S_OK : hresLe(ERROR_WRITE_FAULT);
  68. }
  69. HRESULT RIFF_Close(HMMIO hmmio, UINT nFlags)
  70. {
  71. return hresMMIO(mmioClose(hmmio, nFlags));
  72. }
  73. /*
  74. * Opens a RIFF file for read / write
  75. * Reads/Writes a GUID that servers as our signature
  76. */
  77. HRESULT RIFF_Open
  78. (
  79. LPCSTR lpszFilename,
  80. UINT nOpenFlags,
  81. PHANDLE phmmio,
  82. LPMMCKINFO lpmmck,
  83. PDWORD pdwEffectSz
  84. )
  85. {
  86. HRESULT hres = S_OK;
  87. MMIOINFO mmInfo;
  88. HMMIO hmmio;
  89. ZeroX(mmInfo);
  90. // go ahead and open the file, if we can
  91. hmmio = mmioOpenA((LPSTR)lpszFilename, &mmInfo, nOpenFlags);
  92. if(mmInfo.wErrorRet)
  93. {
  94. hres = hresMMIO(mmInfo.wErrorRet);
  95. AssertF(FAILED(hres));
  96. }
  97. // if( nOpenFlags & ( MMIO_READ | MMIO_ALLOCBUF) )
  98. if( nOpenFlags == ( MMIO_READ | MMIO_ALLOCBUF) )
  99. {
  100. if(SUCCEEDED(hres))
  101. {
  102. // locate and descend into FORC RIFF chunk
  103. lpmmck->fccType = FCC_FORCE_EFFECT_RIFF;
  104. hres = RIFF_Descend(hmmio, lpmmck, NULL, MMIO_FINDRIFF);
  105. }
  106. if(SUCCEEDED(hres))
  107. {
  108. GUID GUIDVersion;
  109. //read the guid
  110. hres = RIFF_Read(hmmio, &GUIDVersion, sizeof(GUID));
  111. if(SUCCEEDED(hres))
  112. {
  113. if(IsEqualGUID(&GUIDVersion, &GUID_INTERNALFILEEFFECT))
  114. {
  115. } else
  116. {
  117. hres = hresLe(ERROR_BAD_FORMAT);
  118. }
  119. }
  120. }
  121. }
  122. //else if( nOpenFlags & ( MMIO_WRITE | MMIO_ALLOCBUF) )
  123. else if( nOpenFlags & ( MMIO_WRITE) )
  124. {
  125. // create the FORC RIFF chunk
  126. lpmmck->fccType = FCC_FORCE_EFFECT_RIFF;
  127. hres = RIFF_CreateChunk(hmmio, lpmmck, MMIO_CREATERIFF);
  128. if(SUCCEEDED(hres))
  129. {
  130. //write the version GUID
  131. hres = RIFF_Write(hmmio, (PV)&GUID_INTERNALFILEEFFECT, sizeof(GUID));
  132. }
  133. } else
  134. {
  135. hres = E_FAIL;
  136. }
  137. *phmmio = hmmio;
  138. return hres;
  139. }
  140. /*****************************************************************************
  141. *
  142. * internal
  143. * RIFF_ReadEffect
  144. *
  145. * Reads a single Effect from a RIFF file
  146. *
  147. * The callee bears the responsibility to free the TypeSpecificParameterBlock
  148. * for the effect.
  149. *
  150. *
  151. *****************************************************************************/
  152. #ifdef _M_IA64
  153. //This is hack to read 32 bit files on ia64, since someone decided to write
  154. //pointers to file.
  155. //Copied from dinput.h and modified.
  156. typedef struct DIEFFECT_FILE32 {
  157. DWORD dwSize; /* sizeof(DIEFFECT) */
  158. DWORD dwFlags; /* DIEFF_* */
  159. DWORD dwDuration; /* Microseconds */
  160. DWORD dwSamplePeriod; /* Microseconds */
  161. DWORD dwGain;
  162. DWORD dwTriggerButton; /* or DIEB_NOTRIGGER */
  163. DWORD dwTriggerRepeatInterval; /* Microseconds */
  164. DWORD cAxes; /* Number of axes */
  165. /*Make sure size is same on both 1386 and ia64.
  166. LPDWORD rgdwAxes;
  167. LPLONG rglDirection;
  168. LPDIENVELOPE lpEnvelope;
  169. */ DWORD rgdwAxes; /* Array of axes */
  170. DWORD rglDirection; /* Array of directions */
  171. DWORD lpEnvelope; /* Optional */
  172. DWORD cbTypeSpecificParams; /* Size of params */
  173. /*Make sure size is same on both 1386 and ia64.
  174. LPVOID lpvTypeSpecificParams;
  175. */ DWORD lpvTypeSpecificParams; /* Pointer to params */
  176. //#if(DIRECTINPUT_VERSION >= 0x0600)//Out since file format does not change.
  177. DWORD dwStartDelay; /* Microseconds */
  178. //#endif /* DIRECTINPUT_VERSION >= 0x0600 *///Out since file format does not change.
  179. } DIEFFECT_FILE32, *LPDIEFFECT_FILE32;
  180. #endif /*_M_IA64*/
  181. HRESULT
  182. RIFF_ReadEffect
  183. (
  184. HMMIO hmmio,
  185. LPDIFILEEFFECT lpDiFileEf
  186. )
  187. {
  188. HRESULT hres = E_FAIL;
  189. MMCKINFO mmckinfoEffectLIST;
  190. MMCKINFO mmckinfoDataCHUNK;
  191. LPDIEFFECT peff = (LPDIEFFECT)lpDiFileEf->lpDiEffect;
  192. // descend into the effect list
  193. mmckinfoEffectLIST.fccType = FCC_EFFECT_LIST;
  194. hres = RIFF_Descend(hmmio, &mmckinfoEffectLIST, NULL, MMIO_FINDLIST);
  195. if(SUCCEEDED(hres))
  196. {
  197. //read the name
  198. hres = RIFF_Read(hmmio, lpDiFileEf->szFriendlyName, MAX_SIZE_SNAME);
  199. }
  200. if(SUCCEEDED(hres))
  201. {
  202. #ifdef _M_IA64
  203. DIEFFECT_FILE32 eff32;
  204. //read the effect structure
  205. hres = RIFF_Read(hmmio, &eff32, sizeof(eff32));
  206. AssertF( eff32.dwSize == sizeof(eff32) );
  207. if( eff32.dwSize != sizeof(eff32) )
  208. {
  209. hres = ERROR_BAD_FORMAT;
  210. }
  211. else
  212. {
  213. peff->dwSize=sizeof(*peff);
  214. peff->dwFlags=eff32.dwFlags;
  215. peff->dwDuration=eff32.dwDuration;
  216. peff->dwSamplePeriod=eff32.dwSamplePeriod;
  217. peff->dwGain=eff32.dwGain;
  218. peff->dwTriggerButton=eff32.dwTriggerButton;
  219. peff->dwTriggerRepeatInterval=eff32.dwTriggerRepeatInterval;
  220. peff->cAxes=eff32.cAxes;
  221. peff->cbTypeSpecificParams=eff32.cbTypeSpecificParams;
  222. peff->lpvTypeSpecificParams=(LPVOID)(DWORD_PTR)eff32.lpvTypeSpecificParams;
  223. peff->dwStartDelay=eff32.dwStartDelay;
  224. }
  225. #else /*_M_IA64*/
  226. // Reading the effect structure will zap out the following,
  227. // so we make a copy before the read.
  228. LPDIENVELOPE lpEnvelope = peff->lpEnvelope;
  229. LPDWORD rgdwAxes = peff->rgdwAxes;
  230. LPLONG rglDirection= peff->rglDirection;
  231. //read the effect structure
  232. hres = RIFF_Read(hmmio, peff, sizeof(DIEFFECT));
  233. AssertF( peff->dwSize == sizeof(DIEFFECT) );
  234. if( peff->dwSize != sizeof(DIEFFECT) )
  235. {
  236. hres = ERROR_BAD_FORMAT;
  237. }
  238. else
  239. {
  240. if(peff->lpEnvelope) peff->lpEnvelope = lpEnvelope;
  241. if(peff->rgdwAxes) peff->rgdwAxes = rgdwAxes;
  242. if(peff->rglDirection) peff->rglDirection = rglDirection;
  243. }
  244. #endif /*_M_IA64*/
  245. if(SUCCEEDED(hres))
  246. {
  247. AssertF(peff->cAxes < DIEFFECT_MAXAXES);
  248. if(peff->cAxes >= DIEFFECT_MAXAXES)
  249. {
  250. hres = ERROR_BAD_FORMAT;
  251. }
  252. }
  253. }
  254. if(SUCCEEDED(hres))
  255. {
  256. // read the Effect GUID
  257. hres = RIFF_Read(hmmio, &lpDiFileEf->GuidEffect, sizeof(GUID));
  258. }
  259. if(SUCCEEDED(hres))
  260. {
  261. UINT nRepeatCount;
  262. //read in the repeat count
  263. hres = RIFF_Read(hmmio, &nRepeatCount, sizeof(nRepeatCount));
  264. }
  265. if(SUCCEEDED(hres) && peff->rgdwAxes)
  266. {
  267. // descend the data chunk
  268. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  269. hres = RIFF_Descend(hmmio, &mmckinfoDataCHUNK, NULL, MMIO_FINDCHUNK);
  270. if(SUCCEEDED(hres))
  271. {
  272. //read the axes
  273. hres = RIFF_Read(hmmio, peff->rgdwAxes, cbX(*peff->rgdwAxes)*(peff->cAxes));
  274. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  275. }
  276. }
  277. if(SUCCEEDED(hres) && peff->rglDirection)
  278. {
  279. //descend the data chunk
  280. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  281. hres = RIFF_Descend(hmmio, &mmckinfoDataCHUNK, NULL, MMIO_FINDCHUNK);
  282. if(SUCCEEDED(hres))
  283. {
  284. //read the direction
  285. hres = RIFF_Read(hmmio, peff->rglDirection, cbX(*peff->rglDirection)*(peff->cAxes));
  286. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  287. }
  288. }
  289. if(SUCCEEDED(hres) && peff->lpEnvelope )
  290. {
  291. //descend the data chunk
  292. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  293. hres = RIFF_Descend(hmmio, &mmckinfoDataCHUNK, NULL, MMIO_FINDCHUNK);
  294. if(SUCCEEDED(hres))
  295. {
  296. hres = RIFF_Read(hmmio, peff->lpEnvelope, sizeof(DIENVELOPE));
  297. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  298. }
  299. }
  300. if(SUCCEEDED(hres) && (peff->cbTypeSpecificParams > 0))
  301. {
  302. // get the param structure, if any
  303. hres = AllocCbPpv( peff->cbTypeSpecificParams, &peff->lpvTypeSpecificParams );
  304. if( SUCCEEDED( hres ) )
  305. {
  306. //descend the data chunk
  307. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  308. hres = RIFF_Descend(hmmio, &mmckinfoDataCHUNK, NULL, MMIO_FINDCHUNK);
  309. if(SUCCEEDED(hres))
  310. {
  311. hres = RIFF_Read(hmmio, peff->lpvTypeSpecificParams, peff->cbTypeSpecificParams);
  312. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  313. }
  314. }
  315. }
  316. if(SUCCEEDED(hres))
  317. {
  318. // ascend the effect chunk
  319. hres = RIFF_Ascend(hmmio, &mmckinfoEffectLIST);
  320. }
  321. return hres;
  322. }
  323. /*
  324. * RIFF_WriteEffect
  325. *
  326. * Writes a single Effect structure to a RIFF file
  327. *
  328. * The effect structure is quite complex. It contains pointers
  329. * to a number of other structures. This function checks for
  330. * valid data before it writes out the effect structure
  331. */
  332. HRESULT RIFF_WriteEffect
  333. (HMMIO hmmio,
  334. LPDIFILEEFFECT lpDiFileEf
  335. )
  336. {
  337. HRESULT hres = E_FAIL;
  338. LPDIEFFECT peff = (LPDIEFFECT)lpDiFileEf->lpDiEffect;
  339. MMCKINFO mmckinfoEffectLIST;
  340. MMCKINFO mmckinfoDataCHUNK;
  341. LPDWORD rgdwAxes = NULL;
  342. LPLONG rglDirection = NULL;
  343. LPDIENVELOPE lpEnvelope = NULL;
  344. LPVOID lpvTypeSpecPar = NULL;
  345. EnterProcI(RIFF_WriteEffect, (_ "xx", hmmio, lpDiFileEf));
  346. // create the effect LIST
  347. mmckinfoEffectLIST.fccType = FCC_EFFECT_LIST;
  348. hres = RIFF_CreateChunk(hmmio, &mmckinfoEffectLIST, MMIO_CREATELIST);
  349. //save the effect ptrs and write flags to the file, instead of ptrs
  350. if (peff->rgdwAxes)
  351. {
  352. rgdwAxes = peff->rgdwAxes;
  353. peff->rgdwAxes = (LPDWORD)DIEP_AXES;
  354. }
  355. if (peff->rglDirection)
  356. {
  357. rglDirection = peff->rglDirection;
  358. peff->rglDirection = (LPLONG)DIEP_DIRECTION;
  359. }
  360. if (peff->lpEnvelope)
  361. {
  362. lpEnvelope = peff->lpEnvelope;
  363. peff->lpEnvelope = (LPDIENVELOPE)DIEP_ENVELOPE;
  364. }
  365. if ((peff->cbTypeSpecificParams > 0) && (peff->lpvTypeSpecificParams != NULL))
  366. {
  367. lpvTypeSpecPar = peff->lpvTypeSpecificParams;
  368. peff->lpvTypeSpecificParams = (LPVOID)DIEP_TYPESPECIFICPARAMS;
  369. }
  370. if(SUCCEEDED(hres))
  371. {
  372. hres = hresFullValidReadStrA(lpDiFileEf->szFriendlyName, MAX_JOYSTRING,1);
  373. if(SUCCEEDED(hres))
  374. {
  375. //write the name, only MAX_SIZE_SNAME characters
  376. hres = RIFF_Write(hmmio, lpDiFileEf->szFriendlyName, MAX_SIZE_SNAME);
  377. }
  378. }
  379. if(SUCCEEDED(hres))
  380. {
  381. hres = (peff && IsBadReadPtr(peff, cbX(DIEFFECT_DX5))) ? E_POINTER : S_OK;
  382. if(SUCCEEDED(hres))
  383. {
  384. hres = (peff && IsBadReadPtr(peff, peff->dwSize)) ? E_POINTER : S_OK;
  385. }
  386. if(SUCCEEDED(hres))
  387. {
  388. //write the effect structure
  389. #ifdef _M_IA64
  390. DIEFFECT_FILE32 eff32;
  391. ZeroMemory(&eff32,sizeof(eff32));
  392. eff32.dwSize=sizeof(eff32);
  393. eff32.dwFlags=peff->dwFlags;
  394. eff32.dwDuration=peff->dwDuration;
  395. eff32.dwSamplePeriod=peff->dwSamplePeriod;
  396. eff32.dwGain=peff->dwGain;
  397. eff32.dwTriggerButton=peff->dwTriggerButton;
  398. eff32.dwTriggerRepeatInterval=peff->dwTriggerRepeatInterval;
  399. eff32.cAxes=peff->cAxes;
  400. eff32.cbTypeSpecificParams=peff->cbTypeSpecificParams;
  401. eff32.lpvTypeSpecificParams=(DWORD)(DWORD_PTR)peff->lpvTypeSpecificParams;
  402. eff32.dwStartDelay=peff->dwStartDelay;
  403. hres = RIFF_Write(hmmio, &eff32, eff32.dwSize);
  404. #else /*_M_IA64*/
  405. hres = RIFF_Write(hmmio, peff, peff->dwSize);
  406. #endif /*_M_IA64*/
  407. }
  408. }
  409. //restore the ptrs
  410. if (rgdwAxes != NULL)
  411. {
  412. peff->rgdwAxes = rgdwAxes;
  413. }
  414. if (rglDirection != NULL)
  415. {
  416. peff->rglDirection = rglDirection;
  417. }
  418. if (lpEnvelope != NULL)
  419. {
  420. peff->lpEnvelope = lpEnvelope;
  421. }
  422. if (lpvTypeSpecPar != NULL)
  423. {
  424. peff->lpvTypeSpecificParams = lpvTypeSpecPar;
  425. }
  426. if(SUCCEEDED(hres))
  427. {
  428. // write the Effect GUID
  429. hres = RIFF_Write(hmmio, &lpDiFileEf->GuidEffect, sizeof(GUID));
  430. }
  431. //write 1 as the repeat count
  432. if(SUCCEEDED(hres))
  433. {
  434. UINT nRepeatCount = 1;
  435. hres = RIFF_Write(hmmio, &nRepeatCount, sizeof(DWORD));
  436. }
  437. if(SUCCEEDED(hres) && rgdwAxes )
  438. {
  439. hres = (IsBadReadPtr(rgdwAxes, (*rgdwAxes)*cbX(peff->cAxes))) ? E_POINTER : S_OK;
  440. if(SUCCEEDED(hres))
  441. {
  442. // create the data CHUNK
  443. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  444. hres = RIFF_CreateChunk(hmmio, &mmckinfoDataCHUNK, 0);
  445. //write the axes
  446. if(SUCCEEDED(hres))
  447. {
  448. hres = RIFF_Write(hmmio, rgdwAxes, sizeof(*rgdwAxes)*(peff->cAxes));
  449. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  450. }
  451. }
  452. }
  453. if(SUCCEEDED(hres) && rglDirection)
  454. {
  455. hres = (IsBadReadPtr(rglDirection, cbX(*rglDirection)*(peff->cAxes))) ? E_POINTER : S_OK;
  456. if(SUCCEEDED(hres))
  457. {
  458. // create the data CHUNK
  459. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  460. hres = RIFF_CreateChunk(hmmio, &mmckinfoDataCHUNK, 0);
  461. if(SUCCEEDED(hres))
  462. {
  463. //write the direction
  464. hres = RIFF_Write(hmmio, rglDirection, sizeof(*rglDirection)*(peff->cAxes));
  465. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  466. }
  467. }
  468. }
  469. //write the envelope, if one is present
  470. if(SUCCEEDED(hres) &&
  471. (lpEnvelope != NULL) )
  472. {
  473. hres = (IsBadReadPtr(lpEnvelope, cbX(*lpEnvelope))) ? E_POINTER : S_OK;
  474. if(SUCCEEDED(hres))
  475. {
  476. // create the data CHUNK
  477. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  478. hres = RIFF_CreateChunk(hmmio, &mmckinfoDataCHUNK, 0);
  479. //write the envelope
  480. if(SUCCEEDED(hres))
  481. {
  482. hres = RIFF_Write(hmmio, lpEnvelope, lpEnvelope->dwSize);
  483. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  484. }
  485. }
  486. }
  487. //write the type-specific
  488. if(SUCCEEDED(hres) &&
  489. (peff->cbTypeSpecificParams > 0) &&
  490. (peff->lpvTypeSpecificParams != NULL) )
  491. {
  492. hres = (IsBadReadPtr(lpvTypeSpecPar, peff->cbTypeSpecificParams)) ? E_POINTER : S_OK;
  493. if(SUCCEEDED(hres))
  494. {
  495. // create the data CHUNK
  496. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  497. hres = RIFF_CreateChunk(hmmio, &mmckinfoDataCHUNK, 0);
  498. //write the params
  499. if(SUCCEEDED(hres))
  500. {
  501. hres = RIFF_Write(hmmio, lpvTypeSpecPar, peff->cbTypeSpecificParams);
  502. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  503. }
  504. }
  505. }
  506. if(SUCCEEDED(hres))
  507. {
  508. // ascend the effect chunk
  509. hres = RIFF_Ascend(hmmio, &mmckinfoEffectLIST);
  510. }
  511. ExitOleProc();
  512. return hres;
  513. }