script.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. /* IDirectMusicScript
  2. *
  3. * Copyright (C) 2003-2004 Rok Mandeljc
  4. * Copyright (C) 2003-2004 Raphael Junqueira
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Library General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. #include "config.h"
  21. #include "wine/port.h"
  22. #ifdef HAVE_UNISTD_H
  23. #include <unistd.h>
  24. #endif
  25. #include "dmscript_private.h"
  26. WINE_DEFAULT_DEBUG_CHANNEL(dmscript);
  27. WINE_DECLARE_DEBUG_CHANNEL(dmfile);
  28. /*****************************************************************************
  29. * IDirectMusicScriptImpl implementation
  30. */
  31. /* IDirectMusicScriptImpl IUnknown part: */
  32. HRESULT WINAPI IDirectMusicScriptImpl_IUnknown_QueryInterface (LPUNKNOWN iface, REFIID riid, LPVOID *ppobj) {
  33. ICOM_THIS_MULTI(IDirectMusicScriptImpl, UnknownVtbl, iface);
  34. TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj);
  35. if (IsEqualIID (riid, &IID_IUnknown)) {
  36. *ppobj = (LPVOID)&This->UnknownVtbl;
  37. IDirectMusicScriptImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
  38. return S_OK;
  39. } else if (IsEqualIID (riid, &IID_IDirectMusicScript)) {
  40. *ppobj = (LPVOID)&This->ScriptVtbl;
  41. IDirectMusicScriptImpl_IDirectMusicScript_AddRef ((LPDIRECTMUSICSCRIPT)&This->ScriptVtbl);
  42. return S_OK;
  43. } else if (IsEqualIID (riid, &IID_IDirectMusicObject)) {
  44. *ppobj = (LPVOID)&This->ObjectVtbl;
  45. IDirectMusicScriptImpl_IDirectMusicObject_AddRef ((LPDIRECTMUSICOBJECT)&This->ObjectVtbl);
  46. return S_OK;
  47. } else if (IsEqualIID (riid, &IID_IPersistStream)) {
  48. *ppobj = (LPVOID)&This->PersistStreamVtbl;
  49. IDirectMusicScriptImpl_IPersistStream_AddRef ((LPPERSISTSTREAM)&This->PersistStreamVtbl);
  50. return S_OK;
  51. }
  52. WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ppobj);
  53. return E_NOINTERFACE;
  54. }
  55. ULONG WINAPI IDirectMusicScriptImpl_IUnknown_AddRef (LPUNKNOWN iface) {
  56. ICOM_THIS_MULTI(IDirectMusicScriptImpl, UnknownVtbl, iface);
  57. ULONG ref = InterlockedIncrement(&This->ref);
  58. TRACE("(%p): AddRef from %ld\n", This, ref - 1);
  59. DMSCRIPT_LockModule();
  60. return ref;
  61. }
  62. ULONG WINAPI IDirectMusicScriptImpl_IUnknown_Release (LPUNKNOWN iface) {
  63. ICOM_THIS_MULTI(IDirectMusicScriptImpl, UnknownVtbl, iface);
  64. ULONG ref = InterlockedDecrement(&This->ref);
  65. TRACE("(%p): ReleaseRef to %ld\n", This, ref);
  66. if (ref == 0) {
  67. HeapFree(GetProcessHeap(), 0, This->pHeader);
  68. HeapFree(GetProcessHeap(), 0, This->pVersion);
  69. HeapFree(GetProcessHeap(), 0, This->pwzLanguage);
  70. HeapFree(GetProcessHeap(), 0, This->pwzSource);
  71. HeapFree(GetProcessHeap(), 0, This);
  72. }
  73. DMSCRIPT_UnlockModule();
  74. return ref;
  75. }
  76. IUnknownVtbl DirectMusicScript_Unknown_Vtbl = {
  77. IDirectMusicScriptImpl_IUnknown_QueryInterface,
  78. IDirectMusicScriptImpl_IUnknown_AddRef,
  79. IDirectMusicScriptImpl_IUnknown_Release
  80. };
  81. /* IDirectMusicScriptImpl IDirectMusicScript part: */
  82. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicScript_QueryInterface (LPDIRECTMUSICSCRIPT iface, REFIID riid, LPVOID *ppobj) {
  83. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ScriptVtbl, iface);
  84. return IDirectMusicScriptImpl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
  85. }
  86. ULONG WINAPI IDirectMusicScriptImpl_IDirectMusicScript_AddRef (LPDIRECTMUSICSCRIPT iface) {
  87. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ScriptVtbl, iface);
  88. return IDirectMusicScriptImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
  89. }
  90. ULONG WINAPI IDirectMusicScriptImpl_IDirectMusicScript_Release (LPDIRECTMUSICSCRIPT iface) {
  91. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ScriptVtbl, iface);
  92. return IDirectMusicScriptImpl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
  93. }
  94. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicScript_Init (LPDIRECTMUSICSCRIPT iface, IDirectMusicPerformance* pPerformance, DMUS_SCRIPT_ERRORINFO* pErrorInfo) {
  95. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ScriptVtbl, iface);
  96. FIXME("(%p, %p, %p): stub\n", This, pPerformance, pErrorInfo);
  97. This->pPerformance = pPerformance;
  98. return S_OK;
  99. }
  100. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicScript_CallRoutine (LPDIRECTMUSICSCRIPT iface, WCHAR* pwszRoutineName, DMUS_SCRIPT_ERRORINFO* pErrorInfo) {
  101. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ScriptVtbl, iface);
  102. FIXME("(%p, %s, %p): stub\n", This, debugstr_w(pwszRoutineName), pErrorInfo);
  103. /*return E_NOTIMPL;*/
  104. return S_OK;
  105. /*return E_FAIL;*/
  106. }
  107. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicScript_SetVariableVariant (LPDIRECTMUSICSCRIPT iface, WCHAR* pwszVariableName, VARIANT varValue, BOOL fSetRef, DMUS_SCRIPT_ERRORINFO* pErrorInfo) {
  108. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ScriptVtbl, iface);
  109. FIXME("(%p, %s, FIXME, %d, %p): stub\n", This, debugstr_w(pwszVariableName),/* varValue,*/ fSetRef, pErrorInfo);
  110. return S_OK;
  111. }
  112. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicScript_GetVariableVariant (LPDIRECTMUSICSCRIPT iface, WCHAR* pwszVariableName, VARIANT* pvarValue, DMUS_SCRIPT_ERRORINFO* pErrorInfo) {
  113. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ScriptVtbl, iface);
  114. FIXME("(%p, %s, %p, %p): stub\n", This, debugstr_w(pwszVariableName), pvarValue, pErrorInfo);
  115. return S_OK;
  116. }
  117. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicScript_SetVariableNumber (LPDIRECTMUSICSCRIPT iface, WCHAR* pwszVariableName, LONG lValue, DMUS_SCRIPT_ERRORINFO* pErrorInfo) {
  118. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ScriptVtbl, iface);
  119. FIXME("(%p, %s, %li, %p): stub\n", This, debugstr_w(pwszVariableName), lValue, pErrorInfo);
  120. return S_OK;
  121. }
  122. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicScript_GetVariableNumber (LPDIRECTMUSICSCRIPT iface, WCHAR* pwszVariableName, LONG* plValue, DMUS_SCRIPT_ERRORINFO* pErrorInfo) {
  123. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ScriptVtbl, iface);
  124. FIXME("(%p, %s, %p, %p): stub\n", This, debugstr_w(pwszVariableName), plValue, pErrorInfo);
  125. return S_OK;
  126. }
  127. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicScript_SetVariableObject (LPDIRECTMUSICSCRIPT iface, WCHAR* pwszVariableName, IUnknown* punkValue, DMUS_SCRIPT_ERRORINFO* pErrorInfo) {
  128. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ScriptVtbl, iface);
  129. FIXME("(%p, %s, %p, %p): stub\n", This, debugstr_w(pwszVariableName), punkValue, pErrorInfo);
  130. return S_OK;
  131. }
  132. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicScript_GetVariableObject (LPDIRECTMUSICSCRIPT iface, WCHAR* pwszVariableName, REFIID riid, LPVOID* ppv, DMUS_SCRIPT_ERRORINFO* pErrorInfo) {
  133. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ScriptVtbl, iface);
  134. FIXME("(%p, %s, %s, %p, %p): stub\n", This, debugstr_w(pwszVariableName), debugstr_dmguid(riid), ppv, pErrorInfo);
  135. return S_OK;
  136. }
  137. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicScript_EnumRoutine (LPDIRECTMUSICSCRIPT iface, DWORD dwIndex, WCHAR* pwszName) {
  138. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ScriptVtbl, iface);
  139. FIXME("(%p, %ld, %p): stub\n", This, dwIndex, pwszName);
  140. return S_OK;
  141. }
  142. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicScript_EnumVariable (LPDIRECTMUSICSCRIPT iface, DWORD dwIndex, WCHAR* pwszName) {
  143. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ScriptVtbl, iface);
  144. FIXME("(%p, %ld, %p): stub\n", This, dwIndex, pwszName);
  145. return S_OK;
  146. }
  147. IDirectMusicScriptVtbl DirectMusicScript_Script_Vtbl = {
  148. IDirectMusicScriptImpl_IDirectMusicScript_QueryInterface,
  149. IDirectMusicScriptImpl_IDirectMusicScript_AddRef,
  150. IDirectMusicScriptImpl_IDirectMusicScript_Release,
  151. IDirectMusicScriptImpl_IDirectMusicScript_Init,
  152. IDirectMusicScriptImpl_IDirectMusicScript_CallRoutine,
  153. IDirectMusicScriptImpl_IDirectMusicScript_SetVariableVariant,
  154. IDirectMusicScriptImpl_IDirectMusicScript_GetVariableVariant,
  155. IDirectMusicScriptImpl_IDirectMusicScript_SetVariableNumber,
  156. IDirectMusicScriptImpl_IDirectMusicScript_GetVariableNumber,
  157. IDirectMusicScriptImpl_IDirectMusicScript_SetVariableObject,
  158. IDirectMusicScriptImpl_IDirectMusicScript_GetVariableObject,
  159. IDirectMusicScriptImpl_IDirectMusicScript_EnumRoutine,
  160. IDirectMusicScriptImpl_IDirectMusicScript_EnumVariable
  161. };
  162. /* IDirectMusicScriptImpl IDirectMusicObject part: */
  163. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface, REFIID riid, LPVOID *ppobj) {
  164. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ObjectVtbl, iface);
  165. return IDirectMusicScriptImpl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
  166. }
  167. ULONG WINAPI IDirectMusicScriptImpl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface) {
  168. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ObjectVtbl, iface);
  169. return IDirectMusicScriptImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
  170. }
  171. ULONG WINAPI IDirectMusicScriptImpl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface) {
  172. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ObjectVtbl, iface);
  173. return IDirectMusicScriptImpl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
  174. }
  175. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
  176. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ObjectVtbl, iface);
  177. TRACE("(%p, %p)\n", This, pDesc);
  178. /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
  179. memcpy (pDesc, This->pDesc, This->pDesc->dwSize);
  180. return S_OK;
  181. }
  182. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
  183. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ObjectVtbl, iface);
  184. TRACE("(%p, %p): setting descriptor:\n%s\n", This, pDesc, debugstr_DMUS_OBJECTDESC (pDesc));
  185. /* According to MSDN, we should copy only given values, not whole struct */
  186. if (pDesc->dwValidData & DMUS_OBJ_OBJECT)
  187. memcpy (&This->pDesc->guidObject, &pDesc->guidObject, sizeof (pDesc->guidObject));
  188. if (pDesc->dwValidData & DMUS_OBJ_CLASS)
  189. memcpy (&This->pDesc->guidClass, &pDesc->guidClass, sizeof (pDesc->guidClass));
  190. if (pDesc->dwValidData & DMUS_OBJ_NAME)
  191. strncpyW (This->pDesc->wszName, pDesc->wszName, DMUS_MAX_NAME);
  192. if (pDesc->dwValidData & DMUS_OBJ_CATEGORY)
  193. strncpyW (This->pDesc->wszCategory, pDesc->wszCategory, DMUS_MAX_CATEGORY);
  194. if (pDesc->dwValidData & DMUS_OBJ_FILENAME)
  195. strncpyW (This->pDesc->wszFileName, pDesc->wszFileName, DMUS_MAX_FILENAME);
  196. if (pDesc->dwValidData & DMUS_OBJ_VERSION)
  197. memcpy (&This->pDesc->vVersion, &pDesc->vVersion, sizeof (pDesc->vVersion));
  198. if (pDesc->dwValidData & DMUS_OBJ_DATE)
  199. memcpy (&This->pDesc->ftDate, &pDesc->ftDate, sizeof (pDesc->ftDate));
  200. if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
  201. memcpy (&This->pDesc->llMemLength, &pDesc->llMemLength, sizeof (pDesc->llMemLength));
  202. memcpy (This->pDesc->pbMemData, pDesc->pbMemData, sizeof (pDesc->pbMemData));
  203. }
  204. if (pDesc->dwValidData & DMUS_OBJ_STREAM) {
  205. /* according to MSDN, we copy the stream */
  206. IStream_Clone (pDesc->pStream, &This->pDesc->pStream);
  207. }
  208. /* add new flags */
  209. This->pDesc->dwValidData |= pDesc->dwValidData;
  210. return S_OK;
  211. }
  212. HRESULT WINAPI IDirectMusicScriptImpl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface, LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc) {
  213. ICOM_THIS_MULTI(IDirectMusicScriptImpl, ObjectVtbl, iface);
  214. DMUS_PRIVATE_CHUNK Chunk;
  215. DWORD StreamSize, StreamCount, ListSize[1], ListCount[1];
  216. LARGE_INTEGER liMove; /* used when skipping chunks */
  217. TRACE("(%p, %p, %p)\n", This, pStream, pDesc);
  218. /* FIXME: should this be determined from stream? */
  219. pDesc->dwValidData |= DMUS_OBJ_CLASS;
  220. memcpy (&pDesc->guidClass, &CLSID_DirectMusicScript, sizeof(CLSID));
  221. IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
  222. TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
  223. switch (Chunk.fccID) {
  224. case FOURCC_RIFF: {
  225. IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
  226. TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
  227. StreamSize = Chunk.dwSize - sizeof(FOURCC);
  228. StreamCount = 0;
  229. if (Chunk.fccID == DMUS_FOURCC_SCRIPT_FORM) {
  230. TRACE_(dmfile)(": script form\n");
  231. do {
  232. IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
  233. StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
  234. TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
  235. switch (Chunk.fccID) {
  236. case DMUS_FOURCC_GUID_CHUNK: {
  237. TRACE_(dmfile)(": GUID chunk\n");
  238. pDesc->dwValidData |= DMUS_OBJ_OBJECT;
  239. IStream_Read (pStream, &pDesc->guidObject, Chunk.dwSize, NULL);
  240. break;
  241. }
  242. case DMUS_FOURCC_VERSION_CHUNK: {
  243. TRACE_(dmfile)(": version chunk\n");
  244. pDesc->dwValidData |= DMUS_OBJ_VERSION;
  245. IStream_Read (pStream, &pDesc->vVersion, Chunk.dwSize, NULL);
  246. break;
  247. }
  248. case DMUS_FOURCC_CATEGORY_CHUNK: {
  249. TRACE_(dmfile)(": category chunk\n");
  250. pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
  251. IStream_Read (pStream, pDesc->wszCategory, Chunk.dwSize, NULL);
  252. break;
  253. }
  254. case FOURCC_LIST: {
  255. IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
  256. TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
  257. ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
  258. ListCount[0] = 0;
  259. switch (Chunk.fccID) {
  260. /* evil M$ UNFO list, which can (!?) contain INFO elements */
  261. case DMUS_FOURCC_UNFO_LIST: {
  262. TRACE_(dmfile)(": UNFO list\n");
  263. do {
  264. IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
  265. ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
  266. TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
  267. switch (Chunk.fccID) {
  268. /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
  269. (though strings seem to be valid unicode) */
  270. case mmioFOURCC('I','N','A','M'):
  271. case DMUS_FOURCC_UNAM_CHUNK: {
  272. TRACE_(dmfile)(": name chunk\n");
  273. pDesc->dwValidData |= DMUS_OBJ_NAME;
  274. IStream_Read (pStream, pDesc->wszName, Chunk.dwSize, NULL);
  275. break;
  276. }
  277. case mmioFOURCC('I','A','R','T'):
  278. case DMUS_FOURCC_UART_CHUNK: {
  279. TRACE_(dmfile)(": artist chunk (ignored)\n");
  280. liMove.QuadPart = Chunk.dwSize;
  281. IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
  282. break;
  283. }
  284. case mmioFOURCC('I','C','O','P'):
  285. case DMUS_FOURCC_UCOP_CHUNK: {
  286. TRACE_(dmfile)(": copyright chunk (ignored)\n");
  287. liMove.QuadPart = Chunk.dwSize;
  288. IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
  289. break;
  290. }
  291. case mmioFOURCC('I','S','B','J'):
  292. case DMUS_FOURCC_USBJ_CHUNK: {
  293. TRACE_(dmfile)(": subject chunk (ignored)\n");
  294. liMove.QuadPart = Chunk.dwSize;
  295. IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
  296. break;
  297. }
  298. case mmioFOURCC('I','C','M','T'):
  299. case DMUS_FOURCC_UCMT_CHUNK: {
  300. TRACE_(dmfile)(": comment chunk (ignored)\n");
  301. liMove.QuadPart = Chunk.dwSize;
  302. IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
  303. break;
  304. }
  305. default: {
  306. TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
  307. liMove.QuadPart = Chunk.dwSize;
  308. IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
  309. break;
  310. }
  311. }
  312. TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
  313. } while (ListCount[0] < ListSize[0]);
  314. break;
  315. }
  316. default: {
  317. TRACE_(dmfile)(": unknown (skipping)\n");
  318. liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
  319. IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
  320. break;
  321. }
  322. }
  323. break;
  324. }
  325. default: {
  326. TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
  327. liMove.QuadPart = Chunk.dwSize;
  328. IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
  329. break;
  330. }
  331. }
  332. TRACE_(dmfile)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount, StreamSize);
  333. } while (StreamCount < StreamSize);
  334. } else {
  335. TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
  336. liMove.QuadPart = StreamSize;
  337. IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
  338. return E_FAIL;
  339. }
  340. TRACE_(dmfile)(": reading finished\n");
  341. break;
  342. }
  343. default: {
  344. TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
  345. liMove.QuadPart = Chunk.dwSize;
  346. IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
  347. return DMUS_E_INVALIDFILE;
  348. }
  349. }
  350. TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc));
  351. return S_OK;
  352. }
  353. IDirectMusicObjectVtbl DirectMusicScript_Object_Vtbl = {
  354. IDirectMusicScriptImpl_IDirectMusicObject_QueryInterface,
  355. IDirectMusicScriptImpl_IDirectMusicObject_AddRef,
  356. IDirectMusicScriptImpl_IDirectMusicObject_Release,
  357. IDirectMusicScriptImpl_IDirectMusicObject_GetDescriptor,
  358. IDirectMusicScriptImpl_IDirectMusicObject_SetDescriptor,
  359. IDirectMusicScriptImpl_IDirectMusicObject_ParseDescriptor
  360. };
  361. /* IDirectMusicScriptImpl IPersistStream part: */
  362. HRESULT WINAPI IDirectMusicScriptImpl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj) {
  363. ICOM_THIS_MULTI(IDirectMusicScriptImpl, PersistStreamVtbl, iface);
  364. return IDirectMusicScriptImpl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
  365. }
  366. ULONG WINAPI IDirectMusicScriptImpl_IPersistStream_AddRef (LPPERSISTSTREAM iface) {
  367. ICOM_THIS_MULTI(IDirectMusicScriptImpl, PersistStreamVtbl, iface);
  368. return IDirectMusicScriptImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
  369. }
  370. ULONG WINAPI IDirectMusicScriptImpl_IPersistStream_Release (LPPERSISTSTREAM iface) {
  371. ICOM_THIS_MULTI(IDirectMusicScriptImpl, PersistStreamVtbl, iface);
  372. return IDirectMusicScriptImpl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
  373. }
  374. HRESULT WINAPI IDirectMusicScriptImpl_IPersistStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID) {
  375. ICOM_THIS_MULTI(IDirectMusicScriptImpl, PersistStreamVtbl, iface);
  376. TRACE("(%p, %p)\n", This, pClassID);
  377. memcpy(pClassID, &CLSID_DirectMusicScript, sizeof(CLSID));
  378. return S_OK;
  379. }
  380. HRESULT WINAPI IDirectMusicScriptImpl_IPersistStream_IsDirty (LPPERSISTSTREAM iface) {
  381. ICOM_THIS_MULTI(IDirectMusicScriptImpl, PersistStreamVtbl, iface);
  382. FIXME("(%p): stub, always S_FALSE\n", This);
  383. return S_FALSE;
  384. }
  385. HRESULT WINAPI IDirectMusicScriptImpl_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm) {
  386. ICOM_THIS_MULTI(IDirectMusicScriptImpl, PersistStreamVtbl, iface);
  387. DMUS_PRIVATE_CHUNK Chunk;
  388. DWORD StreamSize, StreamCount, ListSize[3], ListCount[3];
  389. LARGE_INTEGER liMove; /* used when skipping chunks */
  390. LPDIRECTMUSICGETLOADER pGetLoader = NULL;
  391. LPDIRECTMUSICLOADER pLoader = NULL;
  392. FIXME("(%p, %p): Loading not implemented yet\n", This, pStm);
  393. IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
  394. TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
  395. switch (Chunk.fccID) {
  396. case FOURCC_RIFF: {
  397. IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
  398. TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
  399. StreamSize = Chunk.dwSize - sizeof(FOURCC);
  400. StreamCount = 0;
  401. switch (Chunk.fccID) {
  402. case DMUS_FOURCC_SCRIPT_FORM: {
  403. TRACE_(dmfile)(": script form\n");
  404. do {
  405. IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
  406. StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
  407. TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
  408. switch (Chunk.fccID) {
  409. case DMUS_FOURCC_SCRIPT_CHUNK: {
  410. TRACE_(dmfile)(": script header chunk\n");
  411. This->pHeader = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize);
  412. IStream_Read (pStm, This->pHeader, Chunk.dwSize, NULL);
  413. break;
  414. }
  415. case DMUS_FOURCC_SCRIPTVERSION_CHUNK: {
  416. TRACE_(dmfile)(": script version chunk\n");
  417. This->pVersion = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize);
  418. IStream_Read (pStm, This->pVersion, Chunk.dwSize, NULL);
  419. TRACE_(dmfile)("version: 0x%08lx.0x%08lx \n", This->pVersion->dwVersionMS, This->pVersion->dwVersionLS);
  420. break;
  421. }
  422. case DMUS_FOURCC_SCRIPTLANGUAGE_CHUNK: {
  423. TRACE_(dmfile)(": script language chunk\n");
  424. This->pwzLanguage = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize);
  425. IStream_Read (pStm, This->pwzLanguage, Chunk.dwSize, NULL);
  426. TRACE_(dmfile)("using language: %s \n", debugstr_w(This->pwzLanguage));
  427. break;
  428. }
  429. case DMUS_FOURCC_SCRIPTSOURCE_CHUNK: {
  430. TRACE_(dmfile)(": script source chunk\n");
  431. This->pwzSource = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize);
  432. IStream_Read (pStm, This->pwzSource, Chunk.dwSize, NULL);
  433. if (TRACE_ON(dmscript)) {
  434. int count = WideCharToMultiByte(CP_ACP, 0, This->pwzSource, -1, NULL, 0, NULL, NULL);
  435. LPSTR str = HeapAlloc(GetProcessHeap (), 0, count);
  436. WideCharToMultiByte(CP_ACP, 0, This->pwzSource, -1, str, count, NULL, NULL);
  437. str[count-1] = '\n';
  438. TRACE("source:\n");
  439. write( 2, str, count );
  440. HeapFree(GetProcessHeap(), 0, str);
  441. }
  442. break;
  443. }
  444. case DMUS_FOURCC_GUID_CHUNK: {
  445. TRACE_(dmfile)(": GUID chunk\n");
  446. This->pDesc->dwValidData |= DMUS_OBJ_OBJECT;
  447. IStream_Read (pStm, &This->pDesc->guidObject, Chunk.dwSize, NULL);
  448. break;
  449. }
  450. case DMUS_FOURCC_VERSION_CHUNK: {
  451. TRACE_(dmfile)(": version chunk\n");
  452. This->pDesc->dwValidData |= DMUS_OBJ_VERSION;
  453. IStream_Read (pStm, &This->pDesc->vVersion, Chunk.dwSize, NULL);
  454. break;
  455. }
  456. case DMUS_FOURCC_CATEGORY_CHUNK: {
  457. TRACE_(dmfile)(": category chunk\n");
  458. This->pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
  459. IStream_Read (pStm, This->pDesc->wszCategory, Chunk.dwSize, NULL);
  460. break;
  461. }
  462. case FOURCC_RIFF: {
  463. IDirectMusicObject* pObject = NULL;
  464. DMUS_OBJECTDESC desc;
  465. ZeroMemory ((LPVOID)&desc, sizeof(DMUS_OBJECTDESC));
  466. desc.dwSize = sizeof(DMUS_OBJECTDESC);
  467. desc.dwValidData = DMUS_OBJ_STREAM | DMUS_OBJ_CLASS;
  468. desc.guidClass = CLSID_DirectMusicContainer;
  469. desc.pStream = NULL;
  470. IStream_Clone (pStm, &desc.pStream);
  471. liMove.QuadPart = 0;
  472. liMove.QuadPart -= (sizeof(FOURCC) + sizeof(DWORD));
  473. IStream_Seek (desc.pStream, liMove, STREAM_SEEK_CUR, NULL);
  474. IStream_QueryInterface (pStm, &IID_IDirectMusicGetLoader, (LPVOID*)&pGetLoader);
  475. IDirectMusicGetLoader_GetLoader (pGetLoader, &pLoader);
  476. IDirectMusicGetLoader_Release (pGetLoader);
  477. if (SUCCEEDED(IDirectMusicLoader_GetObject (pLoader, &desc, &IID_IDirectMusicObject, (LPVOID*) &pObject))) {
  478. IDirectMusicObject_Release (pObject);
  479. } else {
  480. ERR_(dmfile)("Error on GetObject while trying to load Scrip SubContainer\n");
  481. }
  482. IDirectMusicLoader_Release (pLoader); pLoader = NULL; /* release loader */
  483. IStream_Release(desc.pStream); desc.pStream = NULL; /* release cloned stream */
  484. liMove.QuadPart = Chunk.dwSize;
  485. IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
  486. /*
  487. IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
  488. TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
  489. ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
  490. ListCount[0] = 0;
  491. switch (Chunk.fccID) {
  492. default: {
  493. TRACE_(dmfile)(": unknown (skipping)\n");
  494. liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
  495. IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
  496. break;
  497. }
  498. }
  499. */
  500. break;
  501. }
  502. case FOURCC_LIST: {
  503. IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
  504. TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
  505. ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
  506. ListCount[0] = 0;
  507. switch (Chunk.fccID) {
  508. case DMUS_FOURCC_UNFO_LIST: {
  509. TRACE_(dmfile)(": UNFO list\n");
  510. do {
  511. IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
  512. ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
  513. TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
  514. switch (Chunk.fccID) {
  515. /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
  516. (though strings seem to be valid unicode) */
  517. case mmioFOURCC('I','N','A','M'):
  518. case DMUS_FOURCC_UNAM_CHUNK: {
  519. TRACE_(dmfile)(": name chunk\n");
  520. This->pDesc->dwValidData |= DMUS_OBJ_NAME;
  521. IStream_Read (pStm, This->pDesc->wszName, Chunk.dwSize, NULL);
  522. break;
  523. }
  524. case mmioFOURCC('I','A','R','T'):
  525. case DMUS_FOURCC_UART_CHUNK: {
  526. TRACE_(dmfile)(": artist chunk (ignored)\n");
  527. liMove.QuadPart = Chunk.dwSize;
  528. IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
  529. break;
  530. }
  531. case mmioFOURCC('I','C','O','P'):
  532. case DMUS_FOURCC_UCOP_CHUNK: {
  533. TRACE_(dmfile)(": copyright chunk (ignored)\n");
  534. liMove.QuadPart = Chunk.dwSize;
  535. IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
  536. break;
  537. }
  538. case mmioFOURCC('I','S','B','J'):
  539. case DMUS_FOURCC_USBJ_CHUNK: {
  540. TRACE_(dmfile)(": subject chunk (ignored)\n");
  541. liMove.QuadPart = Chunk.dwSize;
  542. IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
  543. break;
  544. }
  545. case mmioFOURCC('I','C','M','T'):
  546. case DMUS_FOURCC_UCMT_CHUNK: {
  547. TRACE_(dmfile)(": comment chunk (ignored)\n");
  548. liMove.QuadPart = Chunk.dwSize;
  549. IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
  550. break;
  551. }
  552. default: {
  553. TRACE_(dmfile)(": unknown sub-chunk (irrevelant & skipping)\n");
  554. liMove.QuadPart = Chunk.dwSize;
  555. IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
  556. break;
  557. }
  558. }
  559. TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
  560. } while (ListCount[0] < ListSize[0]);
  561. break;
  562. }
  563. default: {
  564. TRACE_(dmfile)(": unknown (skipping)\n");
  565. liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
  566. IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
  567. break;
  568. }
  569. }
  570. break;
  571. }
  572. default: {
  573. TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
  574. liMove.QuadPart = Chunk.dwSize;
  575. IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
  576. break;
  577. }
  578. }
  579. TRACE_(dmfile)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount, StreamSize);
  580. } while (StreamCount < StreamSize);
  581. break;
  582. }
  583. default: {
  584. TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
  585. liMove.QuadPart = StreamSize;
  586. IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
  587. return E_FAIL;
  588. }
  589. }
  590. TRACE_(dmfile)(": reading finished\n");
  591. break;
  592. }
  593. default: {
  594. TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
  595. liMove.QuadPart = Chunk.dwSize;
  596. IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
  597. return E_FAIL;
  598. }
  599. }
  600. return S_OK;
  601. }
  602. HRESULT WINAPI IDirectMusicScriptImpl_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty) {
  603. return E_NOTIMPL;
  604. }
  605. HRESULT WINAPI IDirectMusicScriptImpl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize) {
  606. return E_NOTIMPL;
  607. }
  608. IPersistStreamVtbl DirectMusicScript_PersistStream_Vtbl = {
  609. IDirectMusicScriptImpl_IPersistStream_QueryInterface,
  610. IDirectMusicScriptImpl_IPersistStream_AddRef,
  611. IDirectMusicScriptImpl_IPersistStream_Release,
  612. IDirectMusicScriptImpl_IPersistStream_GetClassID,
  613. IDirectMusicScriptImpl_IPersistStream_IsDirty,
  614. IDirectMusicScriptImpl_IPersistStream_Load,
  615. IDirectMusicScriptImpl_IPersistStream_Save,
  616. IDirectMusicScriptImpl_IPersistStream_GetSizeMax
  617. };
  618. /* for ClassFactory */
  619. HRESULT WINAPI DMUSIC_CreateDirectMusicScriptImpl (LPCGUID lpcGUID, LPVOID* ppobj, LPUNKNOWN pUnkOuter) {
  620. IDirectMusicScriptImpl* obj;
  621. obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicScriptImpl));
  622. if (NULL == obj) {
  623. *ppobj = NULL;
  624. return E_OUTOFMEMORY;
  625. }
  626. obj->UnknownVtbl = &DirectMusicScript_Unknown_Vtbl;
  627. obj->ScriptVtbl = &DirectMusicScript_Script_Vtbl;
  628. obj->ObjectVtbl = &DirectMusicScript_Object_Vtbl;
  629. obj->PersistStreamVtbl = &DirectMusicScript_PersistStream_Vtbl;
  630. obj->pDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DMUS_OBJECTDESC));
  631. DM_STRUCT_INIT(obj->pDesc);
  632. obj->pDesc->dwValidData |= DMUS_OBJ_CLASS;
  633. memcpy (&obj->pDesc->guidClass, &CLSID_DirectMusicScript, sizeof (CLSID));
  634. obj->ref = 0; /* will be inited by QueryInterface */
  635. return IDirectMusicScriptImpl_IUnknown_QueryInterface ((LPUNKNOWN)&obj->UnknownVtbl, lpcGUID, ppobj);
  636. }