Source code of Windows XP (NT5)
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.

661 lines
19 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. LPSTR lpszFile = (LPSTR)lpszFilename;
  90. ZeroX(mmInfo);
  91. //There is a problem in mmio that causes somewhat unpredictable behaviour under certain conditions --
  92. //in particular, if using drag-n-drop, it may happen so that mmioOpenA() opens 1 file for reading
  93. //and completely different file for writing, if only the file name is specified.
  94. //So we need to check whether we have only the file name or the path (path will contain a \).
  95. if (strchr(lpszFilename, '\\') == NULL)
  96. {
  97. //Put the current directory before the file name to give the absolute path.
  98. //Apparently mmio doesn't have a problem if given absolute path.
  99. CHAR szFullPath[MAX_PATH];
  100. DWORD dwWritten = GetFullPathNameA(lpszFilename, MAX_PATH, (LPSTR)&szFullPath, NULL);
  101. if (( dwWritten != 0) && (dwWritten <= MAX_PATH))
  102. {
  103. lpszFile = (LPSTR)&szFullPath;
  104. }
  105. }
  106. //There is a problem in mmioOpenA() that makes it leak when the file specified to open for reading
  107. //doesn't exist.
  108. //To avoid the leak, we need to check overselves whether we're opening for reading and
  109. //whether the file exists.
  110. if( nOpenFlags == ( MMIO_READ | MMIO_ALLOCBUF) )
  111. {
  112. HANDLE h = CreateFileA(lpszFile,
  113. GENERIC_READ,
  114. 0,
  115. NULL,
  116. OPEN_EXISTING,
  117. FILE_ATTRIBUTE_NORMAL,
  118. NULL);
  119. if (h == INVALID_HANDLE_VALUE)
  120. {
  121. //set the error code
  122. hres = hresLe(GetLastError());
  123. goto done;
  124. }
  125. else
  126. {
  127. //the file is there; close handle
  128. CloseHandle(h);
  129. }
  130. }
  131. // go ahead and open the file, if we can
  132. hmmio = mmioOpenA(lpszFile, &mmInfo, nOpenFlags);
  133. if(mmInfo.wErrorRet)
  134. {
  135. hres = hresMMIO(mmInfo.wErrorRet);
  136. AssertF(FAILED(hres));
  137. }
  138. // if( nOpenFlags & ( MMIO_READ | MMIO_ALLOCBUF) )
  139. if( nOpenFlags == ( MMIO_READ | MMIO_ALLOCBUF) )
  140. {
  141. if(SUCCEEDED(hres))
  142. {
  143. // locate and descend into FORC RIFF chunk
  144. lpmmck->fccType = FCC_FORCE_EFFECT_RIFF;
  145. hres = RIFF_Descend(hmmio, lpmmck, NULL, MMIO_FINDRIFF);
  146. }
  147. if(SUCCEEDED(hres))
  148. {
  149. GUID GUIDVersion;
  150. //read the guid
  151. hres = RIFF_Read(hmmio, &GUIDVersion, sizeof(GUID));
  152. if(SUCCEEDED(hres))
  153. {
  154. if(IsEqualGUID(&GUIDVersion, &GUID_INTERNALFILEEFFECT))
  155. {
  156. } else
  157. {
  158. hres = hresLe(ERROR_BAD_FORMAT);
  159. }
  160. }
  161. }
  162. }
  163. //else if( nOpenFlags & ( MMIO_WRITE | MMIO_ALLOCBUF) )
  164. else if( nOpenFlags & ( MMIO_WRITE) )
  165. {
  166. // create the FORC RIFF chunk
  167. lpmmck->fccType = FCC_FORCE_EFFECT_RIFF;
  168. hres = RIFF_CreateChunk(hmmio, lpmmck, MMIO_CREATERIFF);
  169. if(SUCCEEDED(hres))
  170. {
  171. //write the version GUID
  172. hres = RIFF_Write(hmmio, (PV)&GUID_INTERNALFILEEFFECT, sizeof(GUID));
  173. }
  174. } else
  175. {
  176. hres = E_FAIL;
  177. }
  178. *phmmio = hmmio;
  179. done:;
  180. return hres;
  181. }
  182. /*****************************************************************************
  183. *
  184. * internal
  185. * RIFF_ReadEffect
  186. *
  187. * Reads a single Effect from a RIFF file
  188. *
  189. * The callee bears the responsibility to free the TypeSpecificParameterBlock
  190. * for the effect.
  191. *
  192. *
  193. *****************************************************************************/
  194. #ifdef _M_IA64
  195. //This is hack to read 32 bit files on ia64, since someone decided to write
  196. //pointers to file.
  197. //Copied from dinput.h and modified.
  198. typedef struct DIEFFECT_FILE32 {
  199. DWORD dwSize; /* sizeof(DIEFFECT) */
  200. DWORD dwFlags; /* DIEFF_* */
  201. DWORD dwDuration; /* Microseconds */
  202. DWORD dwSamplePeriod; /* Microseconds */
  203. DWORD dwGain;
  204. DWORD dwTriggerButton; /* or DIEB_NOTRIGGER */
  205. DWORD dwTriggerRepeatInterval; /* Microseconds */
  206. DWORD cAxes; /* Number of axes */
  207. /*Make sure size is same on both 1386 and ia64.
  208. LPDWORD rgdwAxes;
  209. LPLONG rglDirection;
  210. LPDIENVELOPE lpEnvelope;
  211. */ DWORD rgdwAxes; /* Array of axes */
  212. DWORD rglDirection; /* Array of directions */
  213. DWORD lpEnvelope; /* Optional */
  214. DWORD cbTypeSpecificParams; /* Size of params */
  215. /*Make sure size is same on both 1386 and ia64.
  216. LPVOID lpvTypeSpecificParams;
  217. */ DWORD lpvTypeSpecificParams; /* Pointer to params */
  218. //#if(DIRECTINPUT_VERSION >= 0x0600)//Out since file format does not change.
  219. DWORD dwStartDelay; /* Microseconds */
  220. //#endif /* DIRECTINPUT_VERSION >= 0x0600 *///Out since file format does not change.
  221. } DIEFFECT_FILE32, *LPDIEFFECT_FILE32;
  222. #endif /*_M_IA64*/
  223. HRESULT
  224. RIFF_ReadEffect
  225. (
  226. HMMIO hmmio,
  227. LPDIFILEEFFECT lpDiFileEf
  228. )
  229. {
  230. HRESULT hres = E_FAIL;
  231. MMCKINFO mmckinfoEffectLIST;
  232. MMCKINFO mmckinfoDataCHUNK;
  233. LPDIEFFECT peff = (LPDIEFFECT)lpDiFileEf->lpDiEffect;
  234. // descend into the effect list
  235. mmckinfoEffectLIST.fccType = FCC_EFFECT_LIST;
  236. hres = RIFF_Descend(hmmio, &mmckinfoEffectLIST, NULL, MMIO_FINDLIST);
  237. if(SUCCEEDED(hres))
  238. {
  239. //read the name
  240. hres = RIFF_Read(hmmio, lpDiFileEf->szFriendlyName, MAX_SIZE_SNAME);
  241. }
  242. if(SUCCEEDED(hres))
  243. {
  244. #ifdef _M_IA64
  245. DIEFFECT_FILE32 eff32;
  246. //read the effect structure
  247. hres = RIFF_Read(hmmio, &eff32, sizeof(eff32));
  248. AssertF( eff32.dwSize == sizeof(eff32) );
  249. if( eff32.dwSize != sizeof(eff32) )
  250. {
  251. hres = ERROR_BAD_FORMAT;
  252. }
  253. else
  254. {
  255. peff->dwSize=sizeof(*peff);
  256. peff->dwFlags=eff32.dwFlags;
  257. peff->dwDuration=eff32.dwDuration;
  258. peff->dwSamplePeriod=eff32.dwSamplePeriod;
  259. peff->dwGain=eff32.dwGain;
  260. peff->dwTriggerButton=eff32.dwTriggerButton;
  261. peff->dwTriggerRepeatInterval=eff32.dwTriggerRepeatInterval;
  262. peff->cAxes=eff32.cAxes;
  263. peff->cbTypeSpecificParams=eff32.cbTypeSpecificParams;
  264. peff->lpvTypeSpecificParams=(LPVOID)(DWORD_PTR)eff32.lpvTypeSpecificParams;
  265. peff->dwStartDelay=eff32.dwStartDelay;
  266. }
  267. #else /*_M_IA64*/
  268. // Reading the effect structure will zap out the following,
  269. // so we make a copy before the read.
  270. LPDIENVELOPE lpEnvelope = peff->lpEnvelope;
  271. LPDWORD rgdwAxes = peff->rgdwAxes;
  272. LPLONG rglDirection= peff->rglDirection;
  273. //read the effect structure
  274. hres = RIFF_Read(hmmio, peff, sizeof(DIEFFECT));
  275. AssertF( peff->dwSize == sizeof(DIEFFECT) );
  276. if( peff->dwSize != sizeof(DIEFFECT) )
  277. {
  278. hres = ERROR_BAD_FORMAT;
  279. }
  280. else
  281. {
  282. if(peff->lpEnvelope) peff->lpEnvelope = lpEnvelope;
  283. if(peff->rgdwAxes) peff->rgdwAxes = rgdwAxes;
  284. if(peff->rglDirection) peff->rglDirection = rglDirection;
  285. }
  286. #endif /*_M_IA64*/
  287. if(SUCCEEDED(hres))
  288. {
  289. AssertF(peff->cAxes < DIEFFECT_MAXAXES);
  290. if(peff->cAxes >= DIEFFECT_MAXAXES)
  291. {
  292. hres = ERROR_BAD_FORMAT;
  293. }
  294. }
  295. }
  296. if(SUCCEEDED(hres))
  297. {
  298. // read the Effect GUID
  299. hres = RIFF_Read(hmmio, &lpDiFileEf->GuidEffect, sizeof(GUID));
  300. }
  301. if(SUCCEEDED(hres))
  302. {
  303. UINT nRepeatCount;
  304. //read in the repeat count
  305. hres = RIFF_Read(hmmio, &nRepeatCount, sizeof(nRepeatCount));
  306. }
  307. if(SUCCEEDED(hres) && peff->rgdwAxes)
  308. {
  309. // descend the data chunk
  310. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  311. hres = RIFF_Descend(hmmio, &mmckinfoDataCHUNK, NULL, MMIO_FINDCHUNK);
  312. if(SUCCEEDED(hres))
  313. {
  314. //read the axes
  315. hres = RIFF_Read(hmmio, peff->rgdwAxes, cbX(*peff->rgdwAxes)*(peff->cAxes));
  316. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  317. }
  318. }
  319. if(SUCCEEDED(hres) && peff->rglDirection)
  320. {
  321. //descend the data chunk
  322. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  323. hres = RIFF_Descend(hmmio, &mmckinfoDataCHUNK, NULL, MMIO_FINDCHUNK);
  324. if(SUCCEEDED(hres))
  325. {
  326. //read the direction
  327. hres = RIFF_Read(hmmio, peff->rglDirection, cbX(*peff->rglDirection)*(peff->cAxes));
  328. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  329. }
  330. }
  331. if(SUCCEEDED(hres) && peff->lpEnvelope )
  332. {
  333. //descend the data chunk
  334. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  335. hres = RIFF_Descend(hmmio, &mmckinfoDataCHUNK, NULL, MMIO_FINDCHUNK);
  336. if(SUCCEEDED(hres))
  337. {
  338. hres = RIFF_Read(hmmio, peff->lpEnvelope, sizeof(DIENVELOPE));
  339. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  340. }
  341. }
  342. if(SUCCEEDED(hres) && (peff->cbTypeSpecificParams > 0))
  343. {
  344. // get the param structure, if any
  345. hres = AllocCbPpv( peff->cbTypeSpecificParams, &peff->lpvTypeSpecificParams );
  346. if( SUCCEEDED( hres ) )
  347. {
  348. //descend the data chunk
  349. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  350. hres = RIFF_Descend(hmmio, &mmckinfoDataCHUNK, NULL, MMIO_FINDCHUNK);
  351. if(SUCCEEDED(hres))
  352. {
  353. hres = RIFF_Read(hmmio, peff->lpvTypeSpecificParams, peff->cbTypeSpecificParams);
  354. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  355. }
  356. }
  357. }
  358. if(SUCCEEDED(hres))
  359. {
  360. // ascend the effect chunk
  361. hres = RIFF_Ascend(hmmio, &mmckinfoEffectLIST);
  362. }
  363. return hres;
  364. }
  365. /*
  366. * RIFF_WriteEffect
  367. *
  368. * Writes a single Effect structure to a RIFF file
  369. *
  370. * The effect structure is quite complex. It contains pointers
  371. * to a number of other structures. This function checks for
  372. * valid data before it writes out the effect structure
  373. */
  374. HRESULT RIFF_WriteEffect
  375. (HMMIO hmmio,
  376. LPDIFILEEFFECT lpDiFileEf
  377. )
  378. {
  379. HRESULT hres = E_FAIL;
  380. LPDIEFFECT peff = (LPDIEFFECT)lpDiFileEf->lpDiEffect;
  381. MMCKINFO mmckinfoEffectLIST;
  382. MMCKINFO mmckinfoDataCHUNK;
  383. LPDWORD rgdwAxes = NULL;
  384. LPLONG rglDirection = NULL;
  385. LPDIENVELOPE lpEnvelope = NULL;
  386. LPVOID lpvTypeSpecPar = NULL;
  387. EnterProcI(RIFF_WriteEffect, (_ "xx", hmmio, lpDiFileEf));
  388. // create the effect LIST
  389. mmckinfoEffectLIST.fccType = FCC_EFFECT_LIST;
  390. hres = RIFF_CreateChunk(hmmio, &mmckinfoEffectLIST, MMIO_CREATELIST);
  391. //save the effect ptrs and write flags to the file, instead of ptrs
  392. if (peff->rgdwAxes)
  393. {
  394. rgdwAxes = peff->rgdwAxes;
  395. peff->rgdwAxes = (LPDWORD)DIEP_AXES;
  396. }
  397. if (peff->rglDirection)
  398. {
  399. rglDirection = peff->rglDirection;
  400. peff->rglDirection = (LPLONG)DIEP_DIRECTION;
  401. }
  402. if (peff->lpEnvelope)
  403. {
  404. lpEnvelope = peff->lpEnvelope;
  405. peff->lpEnvelope = (LPDIENVELOPE)DIEP_ENVELOPE;
  406. }
  407. if ((peff->cbTypeSpecificParams > 0) && (peff->lpvTypeSpecificParams != NULL))
  408. {
  409. lpvTypeSpecPar = peff->lpvTypeSpecificParams;
  410. peff->lpvTypeSpecificParams = (LPVOID)DIEP_TYPESPECIFICPARAMS;
  411. }
  412. if(SUCCEEDED(hres))
  413. {
  414. hres = hresFullValidReadStrA(lpDiFileEf->szFriendlyName, MAX_JOYSTRING,1);
  415. if(SUCCEEDED(hres))
  416. {
  417. //write the name, only MAX_SIZE_SNAME characters
  418. hres = RIFF_Write(hmmio, lpDiFileEf->szFriendlyName, MAX_SIZE_SNAME);
  419. }
  420. }
  421. if(SUCCEEDED(hres))
  422. {
  423. hres = (peff && IsBadReadPtr(peff, cbX(DIEFFECT_DX5))) ? E_POINTER : S_OK;
  424. if(SUCCEEDED(hres))
  425. {
  426. hres = (peff && IsBadReadPtr(peff, peff->dwSize)) ? E_POINTER : S_OK;
  427. }
  428. if(SUCCEEDED(hres))
  429. {
  430. //write the effect structure
  431. #ifdef _M_IA64
  432. DIEFFECT_FILE32 eff32;
  433. ZeroMemory(&eff32,sizeof(eff32));
  434. eff32.dwSize=sizeof(eff32);
  435. eff32.dwFlags=peff->dwFlags;
  436. eff32.dwDuration=peff->dwDuration;
  437. eff32.dwSamplePeriod=peff->dwSamplePeriod;
  438. eff32.dwGain=peff->dwGain;
  439. eff32.dwTriggerButton=peff->dwTriggerButton;
  440. eff32.dwTriggerRepeatInterval=peff->dwTriggerRepeatInterval;
  441. eff32.cAxes=peff->cAxes;
  442. eff32.cbTypeSpecificParams=peff->cbTypeSpecificParams;
  443. eff32.lpvTypeSpecificParams=(DWORD)(DWORD_PTR)peff->lpvTypeSpecificParams;
  444. eff32.dwStartDelay=peff->dwStartDelay;
  445. hres = RIFF_Write(hmmio, &eff32, eff32.dwSize);
  446. #else /*_M_IA64*/
  447. hres = RIFF_Write(hmmio, peff, peff->dwSize);
  448. #endif /*_M_IA64*/
  449. }
  450. }
  451. //restore the ptrs
  452. if (rgdwAxes != NULL)
  453. {
  454. peff->rgdwAxes = rgdwAxes;
  455. }
  456. if (rglDirection != NULL)
  457. {
  458. peff->rglDirection = rglDirection;
  459. }
  460. if (lpEnvelope != NULL)
  461. {
  462. peff->lpEnvelope = lpEnvelope;
  463. }
  464. if (lpvTypeSpecPar != NULL)
  465. {
  466. peff->lpvTypeSpecificParams = lpvTypeSpecPar;
  467. }
  468. if(SUCCEEDED(hres))
  469. {
  470. // write the Effect GUID
  471. hres = RIFF_Write(hmmio, &lpDiFileEf->GuidEffect, sizeof(GUID));
  472. }
  473. //write 1 as the repeat count
  474. if(SUCCEEDED(hres))
  475. {
  476. UINT nRepeatCount = 1;
  477. hres = RIFF_Write(hmmio, &nRepeatCount, sizeof(DWORD));
  478. }
  479. if(SUCCEEDED(hres) && rgdwAxes )
  480. {
  481. hres = (IsBadReadPtr(rgdwAxes, (*rgdwAxes)*cbX(peff->cAxes))) ? E_POINTER : S_OK;
  482. if(SUCCEEDED(hres))
  483. {
  484. // create the data CHUNK
  485. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  486. hres = RIFF_CreateChunk(hmmio, &mmckinfoDataCHUNK, 0);
  487. //write the axes
  488. if(SUCCEEDED(hres))
  489. {
  490. hres = RIFF_Write(hmmio, rgdwAxes, sizeof(*rgdwAxes)*(peff->cAxes));
  491. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  492. }
  493. }
  494. }
  495. if(SUCCEEDED(hres) && rglDirection)
  496. {
  497. hres = (IsBadReadPtr(rglDirection, cbX(*rglDirection)*(peff->cAxes))) ? E_POINTER : S_OK;
  498. if(SUCCEEDED(hres))
  499. {
  500. // create the data CHUNK
  501. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  502. hres = RIFF_CreateChunk(hmmio, &mmckinfoDataCHUNK, 0);
  503. if(SUCCEEDED(hres))
  504. {
  505. //write the direction
  506. hres = RIFF_Write(hmmio, rglDirection, sizeof(*rglDirection)*(peff->cAxes));
  507. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  508. }
  509. }
  510. }
  511. //write the envelope, if one is present
  512. if(SUCCEEDED(hres) &&
  513. (lpEnvelope != NULL) )
  514. {
  515. hres = (IsBadReadPtr(lpEnvelope, cbX(*lpEnvelope))) ? E_POINTER : S_OK;
  516. if(SUCCEEDED(hres))
  517. {
  518. // create the data CHUNK
  519. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  520. hres = RIFF_CreateChunk(hmmio, &mmckinfoDataCHUNK, 0);
  521. //write the envelope
  522. if(SUCCEEDED(hres))
  523. {
  524. hres = RIFF_Write(hmmio, lpEnvelope, lpEnvelope->dwSize);
  525. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  526. }
  527. }
  528. }
  529. //write the type-specific
  530. if(SUCCEEDED(hres) &&
  531. (peff->cbTypeSpecificParams > 0) &&
  532. (peff->lpvTypeSpecificParams != NULL) )
  533. {
  534. hres = (IsBadReadPtr(lpvTypeSpecPar, peff->cbTypeSpecificParams)) ? E_POINTER : S_OK;
  535. if(SUCCEEDED(hres))
  536. {
  537. // create the data CHUNK
  538. mmckinfoDataCHUNK.ckid = FCC_DATA_CHUNK;
  539. hres = RIFF_CreateChunk(hmmio, &mmckinfoDataCHUNK, 0);
  540. //write the params
  541. if(SUCCEEDED(hres))
  542. {
  543. hres = RIFF_Write(hmmio, lpvTypeSpecPar, peff->cbTypeSpecificParams);
  544. hres = RIFF_Ascend(hmmio, &mmckinfoDataCHUNK);
  545. }
  546. }
  547. }
  548. if(SUCCEEDED(hres))
  549. {
  550. // ascend the effect chunk
  551. hres = RIFF_Ascend(hmmio, &mmckinfoEffectLIST);
  552. }
  553. ExitOleProc();
  554. return hres;
  555. }