- correct return value of SHGetPathFromIDList[AW]() for virtual
[wine] / dlls / dmusic / helper.c
1 /* Helper functions for dmusic file handling
2  *
3  * Copyright (C) 2003 Rok Mandeljc
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19 #if 0
20 #include <stdarg.h>
21
22 #include "windef.h"
23 #include "winbase.h"
24 #include "winuser.h"
25 #include "wingdi.h"
26 #include "wine/debug.h"
27 #include "wine/unicode.h"
28
29 #include "dmusic_private.h"
30
31 /* used while still in testing */
32 WINE_DEFAULT_DEBUG_CHANNEL(dmfile);
33 WINE_DECLARE_DEBUG_CHANNEL(dmfiledat);
34
35 /******************************************************************************
36  * DMUSIC_FillUNFOFromFileHandle: 
37  *      - fills a UNFO_List struct (dmusic_private.h) with data from file handle. 
38  *      - IMPORTANT: it expects a LIST chunk at beginning, so if you are calling it 
39  *                   from another DMUSIC_Fill* function, make sure pointer is at
40  *               correct place!
41  */
42 HRESULT WINAPI DMUSIC_FillUNFOFromFileHandle (UNFO_List UNFO, HANDLE fd)
43 {
44         rawChunk chunk;
45         DWORD BytesRead, ListCount = 0, ListSize;
46
47         TRACE("reading 'LIST' chunk...\n");
48         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read 'LIST' */
49         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'LIST' chunk */
50         if (chunk.id == FOURCC_LIST &&  ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_UNFO_LIST) {
51                 TRACE("'UNFO': UNFO list\n");
52                 ListSize = chunk.size - sizeof(FOURCC); /* list contents size is same as size of LIST chunk - size of following field ID*/
53                 do {
54                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following field */
55                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of following field */
56                         ListCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
57                         switch (chunk.id)
58                         {
59                                 case DMUS_FOURCC_UNAM_CHUNK: {
60                                         TRACE("'UNAM': name\n");
61                                         UNFO.name = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
62                                         ReadFile (fd, UNFO.name, chunk.size, &BytesRead, NULL);
63                                         TRACE_(dmfiledat)("=> name = %s\n", debugstr_w(UNFO.name));
64                                         break;
65                                 } case DMUS_FOURCC_UART_CHUNK: {
66                                         TRACE("'UART': artist\n");
67                                         UNFO.artist = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
68                                         ReadFile (fd, UNFO.artist, chunk.size, &BytesRead, NULL);
69                                         TRACE_(dmfiledat)("artist = %s\n", debugstr_w(UNFO.artist));
70                                         break;
71                                 } case DMUS_FOURCC_UCOP_CHUNK: {
72                                         TRACE("'UCOP': copyright\n");
73                                         UNFO.copyright = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
74                                         ReadFile (fd, UNFO.copyright, chunk.size, &BytesRead, NULL);
75                                         TRACE_(dmfiledat)("=> copyright = %s\n", debugstr_w(UNFO.copyright));
76                                         break;
77                                 } case DMUS_FOURCC_USBJ_CHUNK:{
78                                         TRACE("'USBJ': subject\n");
79                                         UNFO.subject = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
80                                         ReadFile (fd, UNFO.subject, chunk.size, &BytesRead, NULL);
81                                         TRACE_(dmfiledat)("=> subject = %s\n", debugstr_w(UNFO.subject));
82                                         break;
83                                 } case DMUS_FOURCC_UCMT_CHUNK: {
84                                         TRACE("'UCMT': comment\n");
85                                         UNFO.comment = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
86                                         ReadFile (fd, UNFO.comment, chunk.size, &BytesRead, NULL);
87                                         TRACE_(dmfiledat)("=> comment = %s\n", debugstr_w(UNFO.comment));
88                                         break;
89                                 } default: {
90                                         WARN("invalid chunk (only 'UNAM', 'UART', 'UCOP', 'USBJ', 'UCMT' allowed)\n");
91                                         break;
92                                 }
93                         }
94                         TRACE("ListCount (%ld) < ListSize(%ld)\n", ListCount, ListSize);
95                 } while (ListCount < ListSize);
96         } else {
97                 WARN("'UNFO' not found: not an UNFO list\n");
98         }               
99         return S_OK;    
100 }
101
102 /******************************************************************************
103  * DMUSIC_FillReferenceFromFileHandle: 
104  *      - fills a Reference struct (dmusic_private.h) with data from file handle. 
105  *      - IMPORTANT: it expects a LIST chunk at beginning, so if you are calling it 
106  *                   from another DMUSIC_Fill* function, make sure pointer is at
107  *               correct place!
108  */
109 HRESULT WINAPI DMUSIC_FillReferenceFromFileHandle (Reference reference, HANDLE fd)
110 {
111         rawChunk chunk;
112         DWORD BytesRead, ListCount = 0, ListSize;
113
114         TRACE("reading 'LIST' chunk...\n");
115         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read 'LIST' */
116         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'LIST' chunk */
117         if (chunk.id == FOURCC_LIST &&  ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_REF_LIST) {
118                 TRACE("'DMRF': reference list\n");
119                 ListSize = chunk.size - sizeof(FOURCC); /* list contents size is same as size of LIST chunk - size of following field ID*/
120                 do {
121                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following field */
122                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of following field */                         
123                         ListCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
124                         switch (chunk.id)
125                         {
126                                 case DMUS_FOURCC_REF_CHUNK: {
127                                         TRACE("'refh': reference header\n");
128                                         ReadFile (fd, &reference.header, chunk.size, &BytesRead, NULL);
129                                         TRACE_(dmfiledat)("=> guidClassID = %s; dwValidData = %ld\n", debugstr_guid (&reference.header.guidClassID), reference.header.dwValidData);
130                                         break;
131                                 } case DMUS_FOURCC_GUID_CHUNK: {
132                                         TRACE("'guid': GUID\n");
133                                         ReadFile (fd, &reference.guid, chunk.size, &BytesRead, NULL);
134                                         TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid (&reference.guid));
135                                         break;
136                                 } case DMUS_FOURCC_DATE_CHUNK: {
137                                         TRACE("'date': file date\n");
138                                         ReadFile (fd, &reference.date, chunk.size, &BytesRead, NULL);
139                                         TRACE_(dmfiledat)("=> file date = %ld%ld\n", reference.date.dwHighDateTime, reference.date.dwLowDateTime);
140                                         break;
141                                 } case DMUS_FOURCC_NAME_CHUNK: {
142                                         TRACE("'name': name\n");
143                                         reference.name = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size);
144                                         ReadFile (fd, reference.name, chunk.size, &BytesRead, NULL);
145                                         TRACE_(dmfiledat)("=> name = %s\n", debugstr_w (reference.name));
146                                         break;
147                                 } case DMUS_FOURCC_FILE_CHUNK: {
148                                         TRACE("'file': file name\n");
149                                         reference.file = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size);
150                                         ReadFile (fd, reference.file, chunk.size, &BytesRead, NULL);
151                                         TRACE_(dmfiledat)("=> file name = %s\n", debugstr_w (reference.file));
152                                         break;
153                                 } case DMUS_FOURCC_CATEGORY_CHUNK: {
154                                         TRACE("'catg': category\n");
155                                         reference.category = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size);
156                                         ReadFile (fd, reference.category, chunk.size, &BytesRead, NULL);
157                                         TRACE_(dmfiledat)("=> category = %s\n", debugstr_w (reference.category));
158                                         break;
159                                 } case DMUS_FOURCC_VERSION_CHUNK: {
160                                         TRACE("'vers': version\n");
161                                         ReadFile (fd, &reference.version, sizeof(DMUS_IO_VERSION), &BytesRead, NULL);
162                                         TRACE_(dmfiledat)("=> version = %ld%ld\n", reference.version.dwVersionMS, reference.version.dwVersionLS);                               
163                                         break;
164                                 } default: {
165                                         WARN("invalid chunk (only 'refh, 'guid', 'date', 'name', 'file', 'catg', 'vers' allowed\n");
166                                         break;
167                                 }       
168                         }
169                         TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
170                 } while (ListCount < ListSize); 
171         }
172         
173         return S_OK;
174 }
175
176 /******************************************************************************
177  * DMUSIC_FillBandFromFileHandle: 
178  *      - fills a IDirectMusicBandImpl struct with data from file handle. 
179  *      - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it 
180  *                   from another DMUSIC_Fill* function, make sure pointer is at
181  *               correct place!
182  *      - TODO: replace data in function with data in IDirectMusicBandImpl
183  */
184 HRESULT WINAPI DMUSIC_FillBandFromFileHandle (IDirectMusicBandImpl *band, HANDLE fd)
185 {
186         rawChunk chunk;
187         DWORD BytesRead, ListCount = 0, ListSize, ListCount2 = 0, ListSize2, FileCount = 0, FileSize;
188         /* FIXME: Replace stuff located below with the stuff in band */
189         UNFO_List UNFO;
190         DMUS_IO_VERSION version;
191         GUID guid;
192         /* only in singular form for time being */
193         DMUS_IO_INSTRUMENT header;
194         Reference reference;
195         
196         TRACE("reading 'RIFF' chunk...\n");
197         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read 'RIFF' */
198         if (chunk.id == FOURCC_RIFF) {
199                 TRACE("'RIFF': RIFF file\n");
200                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
201                 FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
202                 TRACE("reading chunks ...\n");
203                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */
204                 if (chunk.id == DMUS_FOURCC_BAND_FORM) {
205                         TRACE("'DMBD': band form\n");
206                         do {
207                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
208                                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
209                                 FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
210                                 switch (chunk.id)
211                                 {
212                                         case DMUS_FOURCC_GUID_CHUNK: {
213                                                 TRACE("'guid': GUID\n");
214                                                 ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
215                                                 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
216                                                 break;
217                                         } case DMUS_FOURCC_VERSION_CHUNK: {
218                                                 TRACE("'vers': version\n");
219                                                 ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
220                                                 TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
221                                                 break;                  
222                                         } case FOURCC_LIST:{
223                                                 TRACE("'LIST': list chunk (size = %ld)\n", chunk.size);
224                                                 ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
225                                                 ListCount = 0; /* reset */
226                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read list ID  */
227                                                 switch (chunk.id)
228                                                 {
229                                                         case DMUS_FOURCC_UNFO_LIST: {
230                                                                 TRACE("'UNFO': UNFO list (content size = %ld)\n", ListSize);
231                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* set pointer at beginning of list */
232                                                                 DMUSIC_FillUNFOFromFileHandle (UNFO, fd); /* forward to DMUSIC_FillUNFOFromFileHandle */
233                                                                 break;                                                          
234                                                         } case DMUS_FOURCC_INSTRUMENTS_LIST: {
235                                                                 TRACE("'lbil': instrumets list (content size = %ld)\n", ListSize);
236                                                                 do {
237                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
238                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
239                                                                         ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;       
240                                                                         if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_INSTRUMENT_LIST) {
241                                                                                 ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
242                                                                                 ListCount2 = 0; /* reset */
243                                                                                 TRACE("'lbin': instrument (size = %ld)\n", ListSize2);
244                                                                                 do {
245                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
246                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
247                                                                                         ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
248                                                                                         switch (chunk.id)
249                                                                                         {
250                                                                                                 case DMUS_FOURCC_INSTRUMENT_CHUNK: {
251                                                                                                         TRACE("'bins': instrument header\n");
252                                                                                                         ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
253                                                                                                         TRACE_(dmfiledat)("=> dwPatch = %ld; dwAssignPatch = %ld; dwPChannel = %ld; dwFlags = %ld; bPan = %i; bVolume = %i; nTranspose = %i; dwChannelPriority = %ld; nPitchBendRange = %i", \
254                                                                                                                 header.dwPatch, header.dwAssignPatch, header.dwPChannel, header.dwFlags, header.bPan, header.bVolume, header.nTranspose, header.dwChannelPriority, header.nPitchBendRange);
255                                                                                                         break;
256                                                                                                 } case FOURCC_LIST: {
257                                                                                                         TRACE("'LIST': list chunk (size = %ld)\n", chunk.size);
258                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
259                                                                                                         if (chunk.id == DMUS_FOURCC_REF_LIST) {
260                                                                                                                 TRACE("'DMRF': reference list (size = %ld)\n", chunk.size - 4); /* set pointer at beginning of list */
261                                                                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT);
262                                                                                                                 DMUSIC_FillReferenceFromFileHandle (reference, fd); /* forward to DMUSIC_FillReferenceFromFileHandle */
263                                                                                                         } else WARN("invalid chunk (only 'DMRF' chunk allowed\n");                                              
264                                                                                                         break;                                                                                          
265                                                                                                 } default: {
266                                                                                                         WARN("invalid chunk (only 'bins' and 'LIST' chunks allowed\n");
267                                                                                                         break;
268                                                                                                 }
269                                                                                         }
270                                                                                         TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);                                                   
271                                                                                 } while (ListCount2 < ListSize2);
272                                                                         } else WARN("invalid chunk (only 'lbin' chunk allowed)\n");
273                                                                         TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);                                                       
274                                                                 } while (ListCount < ListSize);
275                                                                 break;
276                                                         } default: {
277                                                                 WARN("invalid chunk (only 'UNFO' and 'lbil' chunks allowed\n");
278                                                                 break;
279                                                         }
280                                                 }
281                                                 break;
282                                         } default: {
283                                                 WARN("invalid chunk (only 'guid', 'vers' and 'LIST' chunks allowed)\n");
284                                                 break;
285                                         }
286                                 }
287                                 TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);                               
288                         } while (FileCount < FileSize);
289                 }
290         } else {
291                 WARN("'RIFF' not found: not a RIFF file\n");
292         }
293         
294         return S_OK;
295 }
296
297 /******************************************************************************
298  * DMUSIC_FillTrackFromFileHandle: 
299  *      - fills a IDirectMusicTrack8Impl struct with data from file handle. 
300  *      - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it 
301  *                   from another DMUSIC_Fill* function, make sure pointer is at
302  *               correct place!
303  *      - TODO: replace data in function with data in IDirectMusicTrackImpl
304  *                      implement loading for missing (empty) clauses
305  *                      fix a problem with tempo track loading (look at code)
306  */
307 HRESULT WINAPI DMUSIC_FillTrackFromFileHandle (IDirectMusicTrack8Impl *segment, HANDLE fd)
308 {
309         rawChunk chunk;
310         DWORD BytesRead, ListCount = 0, ListCount2 = 0, ListCount3 = 0, ListCount4 = 0, \
311                 ListSize, ListSize2, ListSize3, ListSize4, FileCount = 0, FileSize, FileCount2 = 0, FileSize2 /* *2s, *3s and *4s are for various subchunks  */;
312         int i;  
313         
314         /* general track info */
315         DMUS_IO_TRACK_HEADER header;
316         DMUS_IO_TRACK_EXTRAS_HEADER extheader;
317         GUID guid;
318         DMUS_IO_VERSION version;
319         UNFO_List UNFO;
320         /* tempo track stuff */
321         DMUS_IO_TEMPO_ITEM tempo;
322         /* chord track stuff */
323         DWORD chordHeader;
324         ChordData chordData;
325         /* command track stuff */
326         DMUS_IO_COMMAND command;
327         /* sytle list stuff (support only 1 while still in parse development mode)*/
328         DWORD timestamp;
329         Reference reference;
330         /* band track stuff */
331         BandTrack bandTrack;
332         /* wave track stuff (only singular) */
333         WaveTrack waveTrack;
334         /* segment trigger track stuff */
335         SegTriggerTrack segTriggerTrack;
336         /* time signature track stuff */
337         TimeSigTrack timeSigTrack;
338         /* script track list stuff */
339         ScriptEvent event;
340         
341         TRACE("reading 'RIFF' chunk...\n");
342         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
343         if (chunk.id == FOURCC_RIFF) {
344                 TRACE ("'RIFF': RIFF file\n");
345                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
346                 FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
347                 TRACE("reading chunks ...\n");
348                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);  /* read ID of following form */
349                 if (chunk.id == DMUS_FOURCC_TRACK_FORM) {
350                         TRACE("'DMTK': track form\n");
351                         do {
352                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
353                                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
354                                 FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
355                                 switch (chunk.id)
356                                 {
357                                         case DMUS_FOURCC_TRACK_CHUNK: {
358                                                 TRACE("'trkh': track header\n");
359                                                 ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
360                                                 TRACE_(dmfiledat)("=> track guidClassID = %s; dwPosition = %ld; dwGroup = %ld; ckid = %ld; fccType = %ld\n", \
361                                                         debugstr_guid (&header.guidClassID), header.dwPosition, header.dwGroup, header.ckid, header.fccType);
362                                                 break;
363                                         } case DMUS_FOURCC_TRACK_EXTRAS_CHUNK: {
364                                                 TRACE("'trkx': extra track flags\n");
365                                                 ReadFile (fd, &extheader, chunk.size, &BytesRead, NULL);
366                                                 TRACE_(dmfiledat)("=> dwFlags = %ld; dwPriority = %ld\n", extheader.dwFlags, 
367                                                         extheader.dwPriority);
368                                                 break;
369                                         } case DMUS_FOURCC_GUID_CHUNK: {
370                                                 TRACE("'guid': GUID\n");
371                                                 ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
372                                                 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
373                                                 break;
374                                         } case DMUS_FOURCC_VERSION_CHUNK: {
375                                                 TRACE("'vers': version\n");
376                                                 ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
377                                                 TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
378                                                 break;
379                                         } case FOURCC_LIST:{
380                                                 TRACE("'LIST': list (size = %ld)\n", chunk.size);
381                                                 ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
382                                                 ListCount = 0; /* reset */
383                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
384                                                 switch (chunk.id)
385                                                 {
386                                                         case DMUS_FOURCC_UNFO_LIST: {
387                                                                 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
388                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
389                                                                 DMUSIC_FillUNFOFromFileHandle (UNFO, fd); /* forward to DMUSIC_FillUNFOFromFileHandle */
390                                                                 break;                                                          
391                                                         } case DMUS_FOURCC_CHORDTRACK_LIST: {
392                                                                 TRACE("'cord': chord track list\n");
393                                                                 do {
394                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
395                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
396                                                                         ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
397                                                                         switch (chunk.id)
398                                                                         {
399                                                                                 case DMUS_FOURCC_CHORDTRACKHEADER_CHUNK: {
400                                                                                         TRACE("'crdh': chord header\n");
401                                                                                         ReadFile (fd, &chordHeader, chunk.size, &BytesRead, NULL);
402                                                                                         TRACE_(dmfiledat)("=> chord root = %i; scale = %i\n", (chordHeader && 0xFF000000) >> 24, chordHeader && 0x00FFFFFF);
403                                                                                         break;
404                                                                                 } case DMUS_FOURCC_CHORDTRACKBODY_CHUNK: {
405                                                                                         TRACE("'crdb': chord body\n");
406                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_CHORD) */                                                                                  
407                                                                                         ReadFile (fd, &chordData.chord, chunk.size, &BytesRead, NULL); /* read DMUS_IO_CHORD */
408                                                                                         TRACE_(dmfiledat)("=> wszName[16] = %s; mtTime = %li; chord.wMeasure = %d; chord.bBeat = %i; bFlags = %i\n", \
409                                                                                                 debugstr_w (chordData.chord.wszName), chordData.chord.mtTime, chordData.chord.wMeasure, chordData.chord.bBeat, chordData.chord.bFlags);
410                                                                                         ReadFile (fd, &chordData.nrofsubchords, sizeof(DWORD), &BytesRead, NULL); /* read number of subchords */
411                                                                                         TRACE_(dmfiledat)("=> number of subchords = %ld\n", chordData.nrofsubchords);
412                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_SUBCHORD) */
413                                                                                         chordData.subchord = (DMUS_IO_SUBCHORD*) HeapAlloc (GetProcessHeap (), 0, sizeof(DMUS_IO_SUBCHORD) * chordData.nrofsubchords); /* allocate space */
414                                                                                         for (i = 0; i < chordData.nrofsubchords; i++)
415                                                                                         {
416                                                                                                 TRACE_(dmfiledat)("=> subchord[%i]:  dwChordPattern = %ld; dwScalePattern = %ld; dwInversionPoints = %ld; dwLevels = %ld; bChordRoot = %i; bScaleRoot = %i\n", \
417                                                                                                         i, chordData.subchord[i].dwChordPattern, chordData.subchord[i].dwScalePattern, chordData.subchord[i].dwInversionPoints, chordData.subchord[i].dwLevels, \
418                                                                                                         chordData.subchord[i].bChordRoot, chordData.subchord[i].bScaleRoot);
419                                                                                         }
420                                                                                         ReadFile (fd, chordData.subchord, chunk.size*chordData.nrofsubchords, &BytesRead, NULL);
421                                                                                         break;
422                                                                                 } default: {
423                                                                                         WARN("Invalid chunk (only 'crdh' and 'crdb' chunks allowed)\n");
424                                                                                         break;
425                                                                                 }
426                                                                         }
427                                                                         TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
428                                                                 } while (ListCount < ListSize);
429                                                                 break;
430                                                         }  case DMUS_FOURCC_STYLE_TRACK_LIST: {
431                                                                 TRACE("'sttr': style track list\n");
432                                                                 do {
433                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
434                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
435                                                                         ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;                               
436                                                                         if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_STYLE_REF_LIST) {
437                                                                                 ListSize2 = chunk.size - sizeof(FOURCC);
438                                                                                 ListCount2 = 0;
439                                                                                 TRACE("'strf': style reference list (size = %ld)\n", ListSize2);
440                                                                                 do {                                                                            
441                                                                                 
442                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
443                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
444                                                                                         ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
445                                                                                         switch (chunk.id)
446                                                                                         {
447                                                                                                 case DMUS_FOURCC_TIME_STAMP_CHUNK: {
448                                                                                                         TRACE("'stmp': time stamp\n");
449                                                                                                         ReadFile (fd, &timestamp, chunk.size, &BytesRead, NULL);
450                                                                                                         TRACE_(dmfiledat)("=> time stamp = %ld\n", timestamp);
451                                                                                                         break;
452                                                                                                 } case FOURCC_LIST: {
453                                                                                                         TRACE("'LIST': list\n");
454                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
455                                                                                                         if (chunk.id == DMUS_FOURCC_REF_LIST){
456                                                                                                                 TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n");
457                                                                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
458                                                                                                                 DMUSIC_FillReferenceFromFileHandle (reference, fd);
459                                                                                                         } else {
460                                                                                                                 WARN("invalid chunk (only 'DMRF' chunk allwed)\n");
461                                                                                                         }                                                                                       
462                                                                                                         break;
463                                                                                                 } default: {
464                                                                                                         WARN("invalid chunk (only 'stmp' and 'LIST' chunk allowed)\n");
465                                                                                                         break;
466                                                                                                 }
467                                                                                         }
468                                                                                         TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);
469                                                                                 } while (ListCount2 < ListSize2);
470                                                                         } else {
471                                                                                 WARN("invalid chunk (only 'strf' allowed)\n");
472                                                                         }                                                                                                                                                       
473                                                                         TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
474                                                                 } while (ListCount < ListSize);
475                                                                 break;  
476                                                         } case DMUS_FOURCC_PERS_TRACK_LIST: {
477                                                                 FIXME("'pftr': chordmap track list: not supported yet\n");
478                                                                 break;
479                                                         } case DMUS_FOURCC_LYRICSTRACK_LIST: {
480                                                                 FIXME("'lyrt': lyrics track list: not supported yet\n");
481                                                                 break;
482                                                         }  case DMUS_FOURCC_MARKERTRACK_LIST: {
483                                                                 FIXME("'MARK': marker track list: not supported yet\n");
484                                                                 break;
485                                                         }  case DMUS_FOURCC_MELODYFORM_TRACK_LIST: {
486                                                                 FIXME("'mfrm': melody formulation track list: not supported yet\n");
487                                                                 break;
488                                                         }  case DMUS_FOURCC_PARAMCONTROLTRACK_TRACK_LIST: {
489                                                                 FIXME("'prmt': parameter control track list: not supported yet\n");
490                                                                 break;                                          
491                                                         }  case DMUS_FOURCC_SCRIPTTRACK_LIST: {
492                                                                 TRACE("'scrt': script track list\n");
493                                                                 do {
494                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
495                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
496                                                                         ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;                               
497                                                                         if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_SCRIPTTRACKEVENTS_LIST) {
498                                                                                 TRACE("'scrl': script events list\n");
499                                                                                 ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
500                                                                                 ListCount2 = 0;
501                                                                                 do {
502                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
503                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
504                                                                                         ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
505                                                                                         if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_SCRIPTTRACKEVENT_LIST) {
506                                                                                                 TRACE("'scre': script event list\n");
507                                                                                                 ListSize3 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
508                                                                                                 ListCount3 = 0;
509                                                                                                 do {
510                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
511                                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
512                                                                                                         ListCount3 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
513                                                                                                         switch (chunk.id)
514                                                                                                         {
515                                                                                                                 case DMUS_FOURCC_SCRIPTTRACKEVENTHEADER_CHUNK: {
516                                                                                                                         TRACE("'scrh': event header\n");
517                                                                                                                         ReadFile (fd, &event.header, chunk.size, &BytesRead, NULL);
518                                                                                                                         TRACE_(dmfiledat)("=> dwFlags = %ld; lTimeLogical = %li; lTimePhysical = %li\n", \
519                                                                                                                                 event.header.dwFlags, event.header.lTimeLogical, event.header.lTimePhysical);
520                                                                                                                         break;
521                                                                                                                 } case FOURCC_LIST: {
522                                                                                                                         TRACE("'LIST': list\n");
523                                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
524                                                                                                                         if (chunk.id == DMUS_FOURCC_REF_LIST){
525                                                                                                                                 TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n");
526                                                                                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
527                                                                                                                                 DMUSIC_FillReferenceFromFileHandle (event.reference, fd);
528                                                                                                                         } else {
529                                                                                                                                 WARN("invalid chunk (only 'DMRF' chunk allwed)\n");
530                                                                                                                         }                                                                                                                               
531                                                                                                                         break;
532                                                                                                                 } case DMUS_FOURCC_SCRIPTTRACKEVENTNAME_CHUNK: {
533                                                                                                                         TRACE("'scrn': routine name\n");
534                                                                                                                         event.name = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size);
535                                                                                                                         ReadFile (fd, event.name, chunk.size, &BytesRead, NULL);
536                                                                                                                         TRACE_(dmfiledat)("=> routine name = %s\n", debugstr_w (event.name));
537                                                                                                                         break;
538                                                                                                                 } default: {
539                                                                                                                         WARN("invalid chunk (only 'scrh', 'scrn' and 'LIST' chunk allowed)\n");
540                                                                                                                         break;
541                                                                                                                 }
542                                                                                                         }
543                                                                                                         TRACE("ListCount3 (%ld) < ListSize3 (%ld)\n", ListCount3, ListSize3);
544                                                                                                 } while (ListCount3 < ListSize3);       
545                                                                                         } else {
546                                                                                                 WARN("invalid chunk (only 'scre' chunk allowed)\n");
547                                                                                         }
548                                                                                         TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);
549                                                                                 } while (ListCount2 < ListSize2);       
550                                                                         } else {
551                                                                                 WARN("invalid chunk (only 'scrl' chunk allowed)\n");
552                                                                         }
553                                                                         TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
554                                                                 } while (ListCount < ListSize);                                                                         
555                                                                 break;
556                                                         }  case DMUS_FOURCC_SEGTRACK_LIST: {
557                                                                 TRACE("'segt': segment trigger track list\n");
558                                                                 do {
559                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
560                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
561                                                                         ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;                               
562                                                                         switch (chunk.id)
563                                                                         {
564                                                                                 case DMUS_FOURCC_SEGTRACK_CHUNK: {
565                                                                                         TRACE("'sgth': segment track header\n");
566                                                                                         ReadFile (fd, &segTriggerTrack.header, chunk.size, &BytesRead, NULL);
567                                                                                         TRACE_(dmfiledat)("=> dwFlags = %ld\n", segTriggerTrack.header.dwFlags);                                                                                        
568                                                                                         break;
569                                                                                 } case FOURCC_LIST: {
570                                                                                         TRACE("'LIST': list\n");
571                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
572                                                                                         if (chunk.id == DMUS_FOURCC_SEGMENTS_LIST) {
573                                                                                                 TRACE("'lsgl': segment lists list\n");
574                                                                                                 ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
575                                                                                                 ListCount2 = 0;
576                                                                                                 do {                            
577                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
578                                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
579                                                                                                         ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
580                                                                                                         if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_SEGMENT_LIST) {
581                                                                                                                 ListSize3 = chunk.size - sizeof(FOURCC);
582                                                                                                                 ListCount3 = 0;
583                                                                                                                 do {
584                                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
585                                                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
586                                                                                                                         ListCount3 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
587                                                                                                                         switch (chunk.id)
588                                                                                                                         {
589                                                                                                                                 case DMUS_FOURCC_SEGMENTITEM_CHUNK: {
590                                                                                                                                         TRACE("'sgih': segment item header\n");
591                                                                                                                                         ReadFile (fd, &segTriggerTrack.itemHeader, chunk.size, &BytesRead, NULL);
592                                                                                                                                         TRACE_(dmfiledat)("=> lTimeLogical = %li; lTimePhysical = %li; dwPlayFlags = %ld; dwFlags = %ld\n", \
593                                                                                                                                                 segTriggerTrack.itemHeader.lTimeLogical, segTriggerTrack.itemHeader.lTimePhysical, \
594                                                                                                                                                 segTriggerTrack.itemHeader.dwPlayFlags, segTriggerTrack.itemHeader.dwFlags);
595                                                                                                                                         break;
596                                                                                                                                 } case DMUS_FOURCC_SEGMENTITEMNAME_CHUNK: {
597                                                                                                                                         TRACE("'snam': motif name\n");
598                                                                                                                                         segTriggerTrack.motifName = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size);
599                                                                                                                                         ReadFile (fd, segTriggerTrack.motifName, chunk.size, &BytesRead, NULL);
600                                                                                                                                         TRACE_(dmfiledat)("=> motif name = %s\n", debugstr_w (segTriggerTrack.motifName));
601                                                                                                                                         break;
602                                                                                                                                 } case FOURCC_LIST: {
603                                                                                                                                         TRACE("'LIST': list\n");
604                                                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
605                                                                                                                                         if (chunk.id == DMUS_FOURCC_REF_LIST) {
606                                                                                                                                                 TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n");
607                                                                                                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
608                                                                                                                                                 DMUSIC_FillReferenceFromFileHandle (segTriggerTrack.reference, fd);                                                                                                                                                     
609                                                                                                                                         } else {
610                                                                                                                                                 WARN("invalid chunk (only 'DMRF' chunk allowed)\n");
611                                                                                                                                         }
612                                                                                                                                         break;
613                                                                                                                                 } default: {
614                                                                                                                                         WARN("invalid chunk (only 'sgih', 'snam' and 'LIST' chunks allowed)\n");
615                                                                                                                                         break;
616                                                                                                                                 }
617                                                                                                                         }
618                                                                                                                         TRACE("ListCount3 (%ld) < ListSize3 (%ld)\n", ListCount3, ListSize3);
619                                                                                                                 } while (ListCount3 < ListSize3);
620                                                                                                         } else {
621                                                                                                                 WARN("invalid chunk (only 'lseg' chunk allowed)\n");
622                                                                                                         }
623                                                                                                         TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);
624                                                                                                 } while (ListCount2 < ListSize2);                                       
625                                                                                         } else {
626                                                                                                 WARN("invalid chunk (only 'lsgl' chunk allowed\n");
627                                                                                         }                                                                                               
628                                                                                         break;
629                                                                                 } default: {
630                                                                                         WARN("invalid chunk (only 'sgth' and 'LIST' chunks allowed)\n");
631                                                                                         break;
632                                                                                 }
633                                                                         }
634                                                                         TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
635                                                                 } while (ListCount < ListSize);                                                                                                                 
636                                                                 break;
637                                                         }  case DMUS_FOURCC_TIMESIGTRACK_LIST: {
638                                                                 TRACE("'TIMS': time signature track list\n");
639                                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
640                                                                 if (chunk.id == DMUS_FOURCC_TIMESIGNATURE_TRACK) {
641                                                                         TRACE("'tims': time signatures\n");
642                                                                         timeSigTrack.nrofitems = chunk.size - sizeof(DWORD);
643                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
644                                                                         if (chunk.size != sizeof(DMUS_IO_TIMESIGNATURE_ITEM))
645                                                                                 WARN("there seem to be a problem: file claims that size of DMUSIC_IO_TEMPO_ITEM is %ld, while real sizeof returns %i\n", chunk.size, sizeof(DMUS_IO_TIMESIGNATURE_ITEM));
646                                                                         timeSigTrack.nrofitems /= chunk.size;
647                                                                         TRACE_(dmfiledat)("=> number of items = %ld\n", timeSigTrack.nrofitems);
648                                                                         timeSigTrack.items = (DMUS_IO_TIMESIGNATURE_ITEM*) HeapAlloc (GetProcessHeap (), 0, chunk.size * timeSigTrack.nrofitems);
649                                                                         ReadFile(fd, timeSigTrack.items, chunk.size * timeSigTrack.nrofitems, &BytesRead, NULL);
650                                                                         for (i = 0; i < timeSigTrack.nrofitems; i++)
651                                                                         {
652                                                                                 TRACE_(dmfiledat)("=> time signature[%i]: lTime = %li; bBeatsPerMeasure = %i; bBeat = %i; wGridsPerBeat = %d\n", \
653                                                                                         i, timeSigTrack.items[i].lTime, timeSigTrack.items[i].bBeatsPerMeasure, timeSigTrack.items[i].bBeat, timeSigTrack.items[i].wGridsPerBeat);
654                                                                         }
655                                                                 } else {
656                                                                         WARN("invalid chunk (only 'tims' chunk allowed)\n");
657                                                                 }                                                                       
658                                                                 break;                                                          
659                                                         }  case DMUS_FOURCC_WAVETRACK_LIST: {
660                                                                 TRACE("'wavt': wave track list\n");
661                                                                 do {
662                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
663                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
664                                                                         ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;                               
665                                                                         switch (chunk.id)
666                                                                         {
667                                                                                 case DMUS_FOURCC_WAVETRACK_CHUNK: {
668                                                                                         TRACE("'wath': wave track header\n");
669                                                                                         ReadFile (fd, &waveTrack.header, chunk.size, &BytesRead, NULL);
670                                                                                         TRACE_(dmfiledat)("=> lVolume = %li; dwFlags = %ld\n", waveTrack.header.lVolume, waveTrack.header.dwFlags);
671                                                                                         break;
672                                                                                 } case FOURCC_LIST: {
673                                                                                         TRACE("'LIST': list\n");
674                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
675                                                                                         if (chunk.id == DMUS_FOURCC_WAVEPART_LIST) {
676                                                                                                 TRACE("'wavp': wave parts list\n");
677                                                                                                 ListSize2 = chunk.size - sizeof(FOURCC);
678                                                                                                 ListCount2 = 0;
679                                                                                                 do {                            
680                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
681                                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
682                                                                                                         ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
683                                                                                                         switch (chunk.id)
684                                                                                                         {
685                                                                                                                 case DMUS_FOURCC_WAVEPART_CHUNK: {
686                                                                                                                         TRACE("'waph': wave part header\n");
687                                                                                                                         ReadFile (fd, &waveTrack.partHeader, chunk.size, &BytesRead, NULL);
688                                                                                                                         TRACE_(dmfiledat)("=> lVolume = %li; dwVariations = %ld; dwPChannel = %ld; dwLockToPart = %ld; dwFlags = %ld; dwIndex = %ld\n", \
689                                                                                                                                 waveTrack.partHeader.lVolume, waveTrack.partHeader.dwVariations, waveTrack.partHeader.dwPChannel, \
690                                                                                                                                 waveTrack.partHeader.dwLockToPart, waveTrack.partHeader.dwFlags, waveTrack.partHeader.dwIndex);
691                                                                                                                         break;
692                                                                                                                 } case FOURCC_LIST: {
693                                                                                                                         TRACE("'LIST': list\n");
694                                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
695                                                                                                                         if (chunk.id == DMUS_FOURCC_WAVEITEM_LIST) {
696                                                                                                                                 TRACE("'wavi': wave items list\n");
697                                                                                                                                 ListSize3 = chunk.size - sizeof(FOURCC);
698                                                                                                                                 ListCount3 = 0;
699                                                                                                                                 do {                            
700                                                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
701                                                                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
702                                                                                                                                         ListCount3 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
703                                                                                                                                         if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_WAVE_LIST) {
704                                                                                                                                                 TRACE("'wave': wave item list\n");
705                                                                                                                                                 ListSize4 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
706                                                                                                                                                 ListCount4 = 0; /* reset */
707                                                                                                                                                 do {
708                                                                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
709                                                                                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
710                                                                                                                                                         ListCount4 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
711                                                                                                                                                         switch (chunk.id)
712                                                                                                                                                         {
713                                                                                                                                                                 case DMUS_FOURCC_WAVEITEM_CHUNK: {
714                                                                                                                                                                         TRACE("'waih': wave item header\n");
715                                                                                                                                                                         ReadFile (fd, &waveTrack.itemHeader, chunk.size, &BytesRead, NULL);
716                                                                                                                                                                         TRACE_(dmfiledat)("=> lVolume = %li; lPitch = %li; dwVariations = %ld; rtTime = FIXME; rtStartOffset = FIXME; rtReserved = FIXME; rtDuration = FIXME; mtLogicalTime = %li; dwLoopStart = %ld; dwLoopEnd = %ld; dwFlags = %ld\n", \
717                                                                                                                                                                                 waveTrack.itemHeader.lVolume, waveTrack.itemHeader.lPitch, waveTrack.itemHeader.dwVariations, /*waveTrack.itemHeader.rtTime, \
718                                                                                                                                                                                 waveTrack.itemHeader.rtStartOffset, waveTrack.itemHeader.rtReserved, waveTrack.itemHeader.rtDuration, */waveTrack.itemHeader.mtLogicalTime, \
719                                                                                                                                                                                 waveTrack.itemHeader.dwLoopStart, waveTrack.itemHeader.dwLoopEnd, waveTrack.itemHeader.dwFlags);
720                                                                                                                                                                         break;
721                                                                                                                                                                 } case mmioFOURCC('w','v','c','u'): {
722                                                                                                                                                                         FIXME("'wvcu': undocumented and unknown chunk type (skipping)\n");
723                                                                                                                                                                         SetFilePointer (fd, chunk.size, NULL, FILE_CURRENT); /* skip */
724                                                                                                                                                                         break;
725                                                                                                                                                                 } case FOURCC_LIST: {
726                                                                                                                                                                         TRACE("'LIST': list\n");
727                                                                                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
728                                                                                                                                                                         if (chunk.id == DMUS_FOURCC_REF_LIST) {
729                                                                                                                                                                                 TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n");
730                                                                                                                                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
731                                                                                                                                                                                 DMUSIC_FillReferenceFromFileHandle (waveTrack.reference, fd);                                                                                                                                                                           
732                                                                                                                                                                         } else {
733                                                                                                                                                                                 WARN ("invalid chunk (only 'DMRF' chunk allowed\n");
734                                                                                                                                                                         }
735                                                                                                                                                                         break;
736                                                                                                                                                                 } default: {
737                                                                                                                                                                         WARN("invalid chunk (only 'waih' and 'LIST' (and undocumented 'wvcu') chunks allowed)\n");
738                                                                                                                                                                 }
739                                                                                                                                                         }
740                                                                                                                                                         TRACE("ListCount4 (%ld) < ListSize4 (%ld)\n", ListCount4, ListSize4);
741                                                                                                                                                 } while (ListCount4 < ListSize4);
742                                                                                                                                         } else {
743                                                                                                                                                 WARN("invalid chunk (only 'wave' chunk allowed)\n");
744                                                                                                                                         }
745                                                                                                                                         TRACE("ListCount3 (%ld) < ListSize3 (%ld)\n", ListCount3, ListSize3);
746                                                                                                                                 } while (ListCount3 < ListSize3);       
747                                                                                                                         } else {
748                                                                                                                                 WARN("invalid chunk (only 'wavi' chunk allowed)\n");
749                                                                                                                         }
750                                                                                                                         break;
751                                                                                                                 } default: {
752                                                                                                                         WARN("invalid chunk (only 'waph' and 'LIST' chunks allowed)\n");
753                                                                                                                         break;
754                                                                                                                 }                                                                                                                       
755                                                                                                         }
756                                                                                                         TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);
757                                                                                                 } while (ListCount2 < ListSize2);                                                                                               
758                                                                                         } else {
759                                                                                                 WARN("invalid chunk (only 'wavp' chunk allwed)\n");
760                                                                                         }
761                                                                                         break;
762                                                                                 } default: {
763                                                                                         WARN("invalid chunk (only 'wath' and 'LIST' chunks allowed)\n");
764                                                                                         break;
765                                                                                 }                                                                               
766                                                                         }
767                                                                         TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
768                                                                 } while (ListCount < ListSize);                                                         
769                                                                 break;                                                          
770                                                         } default: {
771                                                                 WARN ("invalid chunk (only 'UNFO', 'cord', 'sttr', 'pftr', 'lyrt', 'MARK' and 'mfrm' chunks allowed)\n");
772                                                                 break;
773                                                         }                                               
774                                                 }
775                                                 break;
776                                         } case FOURCC_RIFF: {
777                                                 TRACE("'RIFF': embedded RIFF chunk (probably band track form)\n");
778                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
779                                                 if (chunk.id == DMUS_FOURCC_BANDTRACK_FORM) {
780                                                         TRACE("'DMBT': band track form\n");
781                                                         FileSize2 = chunk.size - sizeof(FOURCC);
782                                                         do {
783                                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
784                                                                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
785                                                                 FileCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
786                                                                 switch (chunk.id)
787                                                                 {
788                                                                         case DMUS_FOURCC_BANDTRACK_CHUNK: {
789                                                                                 TRACE("'dbth': band track header\n");
790                                                                                 ReadFile (fd, &bandTrack.header, chunk.size, &BytesRead, NULL);
791                                                                                 TRACE_(dmfiledat)("=> bAutoDownload = %d\n", bandTrack.header.bAutoDownload);
792                                                                                 break;
793                                                                         } case DMUS_FOURCC_GUID_CHUNK: {
794                                                                                 TRACE("'guid': GUID\n");
795                                                                                 ReadFile (fd, &bandTrack.guid, chunk.size, &BytesRead, NULL);
796                                                                                 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid (&bandTrack.guid));
797                                                                                 break;
798                                                                         } case DMUS_FOURCC_VERSION_CHUNK: {
799                                                                                 TRACE("'vers': version\n");
800                                                                                 ReadFile (fd, &bandTrack.version, chunk.size, &BytesRead, NULL);
801                                                                                 TRACE_(dmfiledat)("=> version = %ld%ld\n", bandTrack.version.dwVersionMS, bandTrack.version.dwVersionLS);                               
802                                                                                 break;
803                                                                         } case FOURCC_LIST: {
804                                                                                 TRACE("'LIST': list (content size = %ld)\n", chunk.size);
805                                                                                 ListSize = chunk.size - sizeof(FOURCC);
806                                                                                 ListCount = 0;
807                                                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
808                                                                                 switch (chunk.id)
809                                                                                 {
810                                                                                         case DMUS_FOURCC_UNFO_LIST:{
811                                                                                                 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle)\n");
812                                                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
813                                                                                                 DMUSIC_FillUNFOFromFileHandle (UNFO, fd);                                                               
814                                                                                                 break;                                                          
815                                                                                         } case DMUS_FOURCC_BANDS_LIST: {
816                                                                                                 TRACE("'lbdl': bands list (content size = %ld)\n", ListSize);
817                                                                                                 do {
818                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
819                                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
820                                                                                                         ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
821                                                                                                         if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_BAND_LIST) {
822                                                                                                                 ListSize2 = chunk.size - sizeof(FOURCC);
823                                                                                                                 ListCount2 = 0;
824                                                                                                                 TRACE("'lbnd': band list (content size = %ld)\n", ListSize2);
825                                                                                                                 do {
826                                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
827                                                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
828                                                                                                                         ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
829                                                                                                                         switch (chunk.id)
830                                                                                                                         {
831                                                                                                                                 case DMUS_FOURCC_BANDITEM_CHUNK: {
832                                                                                                                                         TRACE("'bdih': old band header\n");
833                                                                                                                                         ReadFile (fd, &bandTrack.header1, chunk.size, &BytesRead, NULL);
834                                                                                                                                         TRACE_(dmfiledat)("=> lBandTime = %li\n", bandTrack.header1.lBandTime);
835                                                                                                                                         break;
836                                                                                                                                 } case DMUS_FOURCC_BANDITEM_CHUNK2: {
837                                                                                                                                         TRACE("'bd2h': new band header\n");
838                                                                                                                                         ReadFile (fd, &bandTrack.header2, chunk.size, &BytesRead, NULL);
839                                                                                                                                         TRACE_(dmfiledat)("=> lBandTimeLogical = %li; lBandTimePhysical = %li\n", \
840                                                                                                                                                 bandTrack.header2.lBandTimeLogical, bandTrack.header2.lBandTimePhysical);
841                                                                                                                                         break;
842                                                                                                                                 } case FOURCC_RIFF: {
843                                                                                                                                         TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded band form)\n", chunk.size);
844                                                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
845                                                                                                                                         if (chunk.id == DMUS_FOURCC_BAND_FORM) {
846                                                                                                                                                 TRACE("'DMBD': embedded band form (forward to DMUSIC_FillBandFromFileHandle)\n");
847                                                                                                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */
848                                                                                                                                                 DMUSIC_FillBandFromFileHandle (NULL, fd);
849                                                                                                                                         } else WARN("invalid chunk (only 'DMBD' chunk allowed)\n");
850                                                                                                                                         break;
851                                                                                                                                 } default: {
852                                                                                                                                         WARN("invalid chunk (only 'bdih', 'bd2h' and 'RIFF' chunks allowed)\n");
853                                                                                                                                         break;
854                                                                                                                                 }
855                                                                                                                         }
856                                                                                                                         TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);                                                                   
857                                                                                                                 } while (ListCount2 < ListSize2);
858                                                                                                         } else WARN("unknown chunk - expect error\n");
859                                                                                                         
860                                                                                                 } while (ListCount < ListSize);
861                                                                                                 break;
862                                                                                         } default: {
863                                                                                                 WARN("invalid chunk (only 'UNFO' and 'lbdl' chunks allowed)\n");
864                                                                                         }
865                                                                                 }
866                                                                                 break;
867                                                                         } default: {
868                                                                                 WARN("invalid chunk (only 'dbth', 'guid', 'vers' and 'LIST' chunks allowed)\n");
869                                                                                 break;
870                                                                         }                                                               
871                                                                 }
872                                                                 TRACE("FileCount2 (%ld) < FileSize2 (%ld)\n", FileCount2, FileSize2);                                                                   
873                                                         } while (FileCount2 < FileSize2);
874                                                 } else {
875                                                         WARN("invalid chunk (only 'DMBT' chunk allowed\n");
876                                                 }
877                                                 break;
878                                         } case DMUS_FOURCC_COMMANDTRACK_CHUNK: {
879                                                 TRACE("'cmnd': command track\n");
880                                                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof(DMUS_IO_COMMAND) */
881                                                 ReadFile (fd, &command, chunk.size, &BytesRead, NULL); /* read DMUS_IO_COMMAND */
882                                                 TRACE_(dmfiledat)("wMeasure = %d; bBeat = %i; bCommand = %i; bGrooveLevel = %i; bGrooveRange = %i; bRepeatMode = %i\n", \
883                                                         command.wMeasure, command.bBeat, command.bCommand, command.bGrooveLevel, command.bGrooveRange, command.bRepeatMode);
884                                                 break;
885                                         }  case DMUS_FOURCC_MUTE_CHUNK: {
886                                                 FIXME("'mute': mute track chunk: not supported yet\n");
887                                                 break;
888                                         }  case DMUS_FOURCC_PATTERN_FORM: {
889                                                 FIXME("'DMPT': pattern track form: not supported yet\n");
890                                                 break;
891                                         }  case DMUS_FOURCC_SEQ_TRACK: {
892                                                 FIXME("'seqt': sequence track chunk: not supported yet\n");
893                                                 break;
894                                         }  case DMUS_FOURCC_SIGNPOST_TRACK_CHUNK: {
895                                                 FIXME("'sgnp': signpost track chunk: not supported yet\n");
896                                                 break;
897                                         }  case DMUS_FOURCC_SYSEX_TRACK: {
898                                                 FIXME("'syex': sysex track chunk: not supported yet\n");
899                                                 break;
900                                         }  case DMUS_FOURCC_TEMPO_TRACK: {
901                                                 TRACE("'tetr': tempo track chunk\n");
902                                                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
903                                                 if (chunk.size != sizeof(DMUS_IO_TEMPO_ITEM))
904                                                         WARN("there seem to be a problem: file claims that size of DMUSIC_IO_TEMPO_ITEM is %ld, while real sizeof returns %i\n", \
905                                                                 chunk.size, sizeof(DMUS_IO_TEMPO_ITEM));
906                                                 ReadFile (fd, &tempo, chunk.size, &BytesRead, NULL);
907                                                 TRACE_(dmfiledat)("=> lTime = %ld; dblTempo = %f\n", tempo.lTime, tempo.dblTempo);
908                                                 break;
909                                         } default: {
910                                                 WARN("invalid chunk (too many too list)\n");
911                                                 break;
912                                         }
913                                 }
914                                 TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);
915                         } while (FileCount < FileSize);
916                 } else {
917                         WARN("invalid chunk (only 'DMTK' chunk allowed)\n");
918                 }
919         } else {
920                 WARN("'RIFF' not found: not a RIFF file\n");
921         }
922         
923         return S_OK;
924 }
925
926 /******************************************************************************
927  * DMUSIC_FillSegmentFromFileHandle: 
928  *      - fills a IDirectMusicSegment8Impl struct with data from file handle. 
929  *      - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it 
930  *                   from another DMUSIC_Fill* function, make sure pointer is at
931  *               correct place!
932  *      - TODO: replace data in function with data in IDirectMusicSegmentImpl
933  *                      implement loading for missing (empty) clauses
934  */
935 HRESULT WINAPI DMUSIC_FillSegmentFromFileHandle (IDirectMusicSegment8Impl *segment, HANDLE fd)
936 {
937         rawChunk chunk;
938         DWORD BytesRead, ListCount = 0, ListSize, FileCount = 0, FileSize;
939         /* FIXME: Replace stuff located below with the stuff in segment */
940         UNFO_List UNFO;
941         DMUS_IO_SEGMENT_HEADER header;
942         DMUS_IO_VERSION version;
943         GUID guid;
944         
945         TRACE("reading 'RIFF' chunk...\n");
946         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
947         if (chunk.id == FOURCC_RIFF) {
948                 TRACE("'RIFF': RIFF file\n");
949                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
950                 FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
951                 TRACE("reading chunks ...\n");
952                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */             
953                 if (chunk.id == DMUS_FOURCC_SEGMENT_FORM) {
954                         TRACE("DMSG: segment form\n");
955                         do {
956                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
957                                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
958                                 FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
959                                 switch (chunk.id)
960                                 {
961                                         case DMUS_FOURCC_SEGMENT_CHUNK: {
962                                                 TRACE("segh: segment header\n");
963                                                 ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
964                                                 TRACE_(dmfiledat)("=> dwRepeats = %ld; mtLength = %li; mtPlayStart = %li; mtLoopStart = %li; mtLoopEnd = %li; dwResolution = %ld; rtLength = FIXME; dwFlags = %ld; dwReserved = %ld\n", \
965                                                         header.dwRepeats, header.mtLength, header.mtPlayStart, header.mtLoopStart, header.mtLoopEnd, header.dwResolution/*, header.rtLength*/, header.dwFlags, header.dwReserved);
966                                                 break;
967                                         } case DMUS_FOURCC_GUID_CHUNK: {
968                                                 TRACE("'guid': GUID\n");
969                                                 ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
970                                                 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
971                                                 break;
972                                         } case DMUS_FOURCC_VERSION_CHUNK: {
973                                                 TRACE("'vers': version\n");
974                                                 ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
975                                                 TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
976                                                 break;
977                                         } case FOURCC_LIST:{
978                                                 TRACE("'LIST': list (size) = %ld\n", chunk.size);
979                                                 ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
980                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
981                                                 switch (chunk.id)
982                                                 {
983                                                         case DMUS_FOURCC_UNFO_LIST: {
984                                                                 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
985                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
986                                                                 DMUSIC_FillUNFOFromFileHandle (UNFO, fd);                                                               
987                                                                 break;                                                          
988                                                         } case DMUS_FOURCC_TRACK_LIST: {
989                                                                 TRACE("'trkl': track list chunk (forward)\n");
990                                                                 do {
991                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read RIFF */
992                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read track size */
993                                                                         TRACE("track size = %ld\n", chunk.size);
994                                                                         ListCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
995                                                                         SetFilePointer (fd, -(sizeof(DWORD) + sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'RIFF' chunk */
996                                                                         DMUSIC_FillTrackFromFileHandle (NULL, fd); /* read encapsulated track as if it was in a track file */
997                                                                         TRACE("(Track) List Count = %ld < (Track) List Size = %ld\n", ListCount, ListSize);
998                                                                 } while (ListCount < ListSize);
999                                                                 break;
1000                                                         }
1001                                                 }
1002                                                 break;
1003                                         } case FOURCC_RIFF: {
1004                                                 TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded container form)\n", chunk.size);
1005                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1006                                                 if (chunk.id == DMUS_FOURCC_CONTAINER_FORM) {
1007                                                         TRACE("'DMCN': embedded container form (forward to DMUSIC_FillContainerFromFileHandle(...))\n");
1008                                                         SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */
1009                                                         DMUSIC_FillContainerFromFileHandle (NULL, fd);
1010                                                 } else WARN("invalid chunk (only 'DMCN' chunk allowed)\n");
1011                                                 break;  
1012                                         } case DMUS_FOURCC_TOOLGRAPH_FORM: {
1013                                                 FIXME("'DMTG': toolgraph chunk: not supported yet\n");
1014                                                 break;
1015                                         } case DMUS_FOURCC_AUDIOPATH_FORM: {
1016                                                 FIXME("'DMAP': audiopath chunk: not supported yet\n");
1017                                                 break;
1018                                         } default: {
1019                                                 WARN("invalid chunk (only 'segh', 'guid', 'vers', 'LIST', 'RIFF', 'DMTG' and 'DMAP' chunks allowed)\n");
1020                                                 break;
1021                                         }
1022                                 }
1023                                 TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);
1024                         } while (FileCount < FileSize);
1025                 } else {
1026                         WARN("invalid chunk (only 'DMSG' chunk allowed)\n");
1027                 }
1028         } else {
1029                 WARN("'RIFF' not found: not a RIFF file\n");
1030         }
1031         
1032         return S_OK;
1033 }
1034
1035  /******************************************************************************
1036  * DMUSIC_FillScriptFromFileHandle: 
1037  *      - fills a IDirectMusicScriptImpl struct with data from file handle. 
1038  *      - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it 
1039  *                   from another DMUSIC_Fill* function, make sure pointer is at
1040  *               correct place!
1041  *      - TODO: replace data in function with data in IDirectMusicScriptImpl
1042  */
1043
1044 HRESULT WINAPI DMUSIC_FillScriptFromFileHandle (IDirectMusicScriptImpl *script, HANDLE fd)
1045 {
1046         rawChunk chunk;
1047         DWORD BytesRead/*, ListCount = 0*/, ListSize, FileCount = 0, FileSize;
1048         /* FIXME: Replace stuff located below with the stuff in script */
1049         UNFO_List UNFO;
1050         DMUS_IO_SCRIPT_HEADER header;
1051         DMUS_IO_VERSION version, scriptversion;
1052         GUID guid;
1053         WCHAR* scriptlang;
1054         WCHAR* scriptsrc;
1055         Reference scriptsrcref;
1056         
1057         TRACE("reading 'RIFF' chunk...\n");
1058         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1059         if (chunk.id == FOURCC_RIFF) {
1060                 TRACE("'RIFF': RIFF file\n");
1061                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
1062                 FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
1063                 TRACE("reading chunks ...\n");
1064                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */             
1065                 if (chunk.id == DMUS_FOURCC_SCRIPT_FORM) {
1066                         TRACE("'DMSC': script form\n");
1067                         do {
1068                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1069                                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1070                                 FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
1071                                 switch (chunk.id)
1072                                 {
1073                                         case DMUS_FOURCC_SCRIPT_CHUNK: {
1074                                                 TRACE("'schd': script header\n");
1075                                                 ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
1076                                                 TRACE_(dmfiledat)("=> dwFlags = %ld\n", header.dwFlags);
1077                                                 break;
1078                                         } case DMUS_FOURCC_GUID_CHUNK: {
1079                                                 TRACE("'guid': GUID\n");
1080                                                 ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
1081                                                 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
1082                                                 break;
1083                                         } case DMUS_FOURCC_VERSION_CHUNK: {
1084                                                 TRACE("'vers': version\n");
1085                                                 ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
1086                                                 TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
1087                                                 break;
1088                                         } case FOURCC_LIST:{
1089                                                 TRACE("'LIST': list (size) = %ld\n", chunk.size);
1090                                                 ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
1091                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1092                                                 switch (chunk.id)
1093                                                 {
1094                                                         case DMUS_FOURCC_UNFO_LIST: {
1095                                                                 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
1096                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
1097                                                                 DMUSIC_FillUNFOFromFileHandle (UNFO, fd);                                                               
1098                                                                 break;
1099                                                         } case DMUS_FOURCC_REF_LIST: {
1100                                                                 TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n");
1101                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
1102                                                                 DMUSIC_FillReferenceFromFileHandle (scriptsrcref, fd);
1103                                                         } default: {
1104                                                                 WARN("invalid chunk (only 'UNFO' and 'DMRF' chunks allowed)\n");
1105                                                         }                                                               
1106                                                 }
1107                                                 break;
1108                                         } case DMUS_FOURCC_SCRIPTVERSION_CHUNK: {
1109                                                 TRACE("'scve': DirectMusic version\n");
1110                                                 ReadFile (fd, &scriptversion, chunk.size, &BytesRead, NULL);
1111                                                 TRACE_(dmfiledat)("=> script version = %ld%ld\n", scriptversion.dwVersionMS, scriptversion.dwVersionLS);
1112                                                 break;
1113                                         } case FOURCC_RIFF: {
1114                                                 TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded container form)\n", chunk.size);
1115                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1116                                                 if (chunk.id == DMUS_FOURCC_CONTAINER_FORM) {
1117                                                         TRACE("'DMCN': embedded container form (forward to DMUSIC_FillContainerFromFileHandle(...))\n");
1118                                                         SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */
1119                                                         DMUSIC_FillContainerFromFileHandle (NULL, fd);
1120                                                 } else WARN("invalid chunk (only 'DMCN' chunk allowed)\n");
1121                                                 break;
1122                                         } case DMUS_FOURCC_SCRIPTLANGUAGE_CHUNK: {
1123                                                 TRACE("'scla': scripting language\n");
1124                                                 scriptlang = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
1125                                                 ReadFile (fd, scriptlang, chunk.size, &BytesRead, NULL);
1126                                                 TRACE_(dmfiledat)("script language = %s\n", debugstr_w(scriptlang));                                            
1127                                                 break;
1128                                         } case DMUS_FOURCC_SCRIPTSOURCE_CHUNK: {
1129                                                 TRACE("'scsr': script source\n");
1130                                                 scriptsrc = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
1131                                                 ReadFile (fd, scriptsrc, chunk.size, &BytesRead, NULL);
1132                                                 TRACE_(dmfiledat)("script source = %s\n", debugstr_w(scriptsrc));                                                       
1133                                                 break;
1134                                         } default: {
1135                                                 WARN("invalid chunk (only 'schd', 'guid', 'vers', 'LIST', 'scve', 'RIFF' and 'scla' chunks allowed)\n");
1136                                                 break;
1137                                         }
1138                                 }
1139                                 TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);
1140                         } while (FileCount < FileSize);
1141                 } else {
1142                         WARN("invalid chunk (only 'DMSC' chunk allowed)\n");
1143                 }
1144         } else {
1145                 WARN("'RIFF' not found: not a RIFF file\n");
1146         }
1147         
1148         return S_OK;
1149 }
1150
1151 /******************************************************************************
1152  * DMUSIC_FillContainerFromFileHandle: 
1153  *      - fills a IDirectMusicContainerImpl struct with data from file handle. 
1154  *      - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it 
1155  *                   from another DMUSIC_Fill* function, make sure pointer is at
1156  *               correct place!
1157  *      - TODO: replace data in function with data in IDirectMusicContainerImpl
1158  */
1159 HRESULT WINAPI DMUSIC_FillContainerFromFileHandle (IDirectMusicContainerImpl *container, HANDLE fd)
1160 {
1161         rawChunk chunk;
1162         DWORD BytesRead, ListCount = 0, ListSize, ListCount2 = 0, ListSize2, FileCount = 0, FileSize;
1163         /* FIXME: Replace stuff located below with the stuff in container */
1164         UNFO_List UNFO;
1165         DMUS_IO_CONTAINER_HEADER header;
1166         DMUS_IO_VERSION version;
1167         GUID guid;
1168         WCHAR* alias;
1169         DMUS_IO_CONTAINED_OBJECT_HEADER objheader;
1170         Reference dataref;
1171         
1172         TRACE("reading 'RIFF' chunk...\n");
1173         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1174         if (chunk.id == FOURCC_RIFF) {
1175                 TRACE("'RIFF': RIFF file\n");
1176                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
1177                 FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
1178                 TRACE("reading chunks ...\n");
1179                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */             
1180                 if (chunk.id == DMUS_FOURCC_CONTAINER_FORM) {
1181                         TRACE("'DMCN': container form\n");
1182                         do {
1183                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1184                                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1185                                 FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
1186                                 switch (chunk.id)
1187                                 {
1188                                         case DMUS_FOURCC_CONTAINER_CHUNK: {
1189                                                 TRACE("'conh': container header\n");
1190                                                 ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
1191                                                 TRACE_(dmfiledat)("=> dwFlags = %ld\n", header.dwFlags);
1192                                                 break;
1193                                         } case DMUS_FOURCC_GUID_CHUNK: {
1194                                                 TRACE("'guid': GUID\n");
1195                                                 ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
1196                                                 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
1197                                                 break;
1198                                         } case DMUS_FOURCC_VERSION_CHUNK: {
1199                                                 TRACE("'vers': version\n");
1200                                                 ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
1201                                                 TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
1202                                                 break;
1203                                         } case FOURCC_LIST:{
1204                                                 TRACE("'LIST': list (size) = %ld\n", chunk.size);
1205                                                 ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
1206                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1207                                                 switch (chunk.id)
1208                                                 {
1209                                                         case DMUS_FOURCC_UNFO_LIST: {
1210                                                                 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
1211                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
1212                                                                 DMUSIC_FillUNFOFromFileHandle (UNFO, fd);                                                               
1213                                                                 break;
1214                                                         } case DMUS_FOURCC_CONTAINED_OBJECTS_LIST: {
1215                                                                 TRACE("'cosl': objects list (content size = %ld)\n", ListSize);
1216                                                                 do {
1217                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1218                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1219                                                                         ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;       
1220                                                                         if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_CONTAINED_OBJECT_LIST) {
1221                                                                                 ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
1222                                                                                 ListCount2 = 0; /* reset */
1223                                                                                 TRACE("'cobl': object (content size = %ld)\n", ListSize2);
1224                                                                                 do {
1225                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1226                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1227                                                                                         ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
1228                                                                                         switch (chunk.id)
1229                                                                                         {
1230                                                                                                 case DMUS_FOURCC_CONTAINED_ALIAS_CHUNK: {
1231                                                                                                         TRACE("'coba': alias (size = %ld)\n", chunk.size);
1232                                                                                                         alias = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, chunk.size); /* allocate space */
1233                                                                                                         ReadFile (fd, alias, chunk.size, &BytesRead, NULL);
1234                                                                                                         TRACE_(dmfiledat)("=> alias = %s\n", debugstr_w(alias));
1235                                                                                                         break;
1236                                                                                                 } case DMUS_FOURCC_CONTAINED_OBJECT_CHUNK: {
1237                                                                                                         TRACE("'cobh': object header (size = %ld)\n", chunk.size);
1238                                                                                                         ReadFile (fd, &objheader, chunk.size, &BytesRead, NULL);
1239                                                                                                         TRACE_(dmfiledat)("=> guidClassID = %s; dwFlags = %ld; ckid = %ld; fccType = %ld\n", \
1240                                                                                                                 debugstr_guid(&objheader.guidClassID), objheader.dwFlags, objheader.ckid, objheader.fccType);
1241                                                                                                         break;
1242                                                                                                 } case FOURCC_LIST: {
1243                                                                                                         TRACE("'LIST': list chunk (size = %ld)\n", chunk.size);
1244                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1245                                                                                                         if (chunk.id == DMUS_FOURCC_REF_LIST) {
1246                                                                                                                 TRACE("'DMRF': reference list (instead of 'data' chunk: size = %ld)\n", chunk.size - 4); /* set pointer at beginning of list */
1247                                                                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT);
1248                                                                                                                 DMUSIC_FillReferenceFromFileHandle (dataref, fd); /* forward to DMUSIC_FillReferenceFromFileHandle */
1249                                                                                                         } else WARN("invalid chunk (only 'DMRF' chunk allowed\n");                                              
1250                                                                                                         break;                                                                                          
1251                                                                                                 } case FOURCC_RIFF: {
1252                                                                                                         TRACE("'RIFF': encapsulated data (can be 'DMSG' or 'DMSG')\n");
1253                                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1254                                                                                                         SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */
1255                                                                                                         switch (chunk.id)
1256                                                                                                         {
1257                                                                                                                 case DMUS_FOURCC_SEGMENT_FORM: {
1258                                                                                                                         TRACE("'DMSG': embedded segment form (forward to DMUSIC_FillSegmentFromFileHandle(...))\n");
1259                                                                                                                         DMUSIC_FillSegmentFromFileHandle (NULL, fd);
1260                                                                                                                         break;
1261                                                                                                                 } case DMUS_FOURCC_STYLE_FORM: {
1262                                                                                                                         TRACE("'DMST': embedded style form (forward to DMUSIC_FillStyleFromFileHandle(...))\n");                                                                                                                        
1263                                                                                                                         DMUSIC_FillStyleFromFileHandle (NULL, fd);
1264                                                                                                                         break;
1265                                                                                                                 } case mmioFOURCC('W','A','V','E'): {
1266                                                                                                                         FIXME("'WAVE': not yet supported (skipping)\n");                                                                                                                        
1267                                                                                                                         SetFilePointer (fd, sizeof(FOURCC) + sizeof(DWORD) + chunk.size, NULL, FILE_CURRENT); /* skip */
1268                                                                                                                         break;
1269                                                                                                                 } default: {
1270                                                                                                                         WARN("invalid chunk (only 'DMSG' and 'DMST' chunks allowed)\n");
1271                                                                                                                         break;
1272                                                                                                                 }
1273                                                                                                         }
1274                                                                                                         break;
1275                                                                                                 } default: {
1276                                                                                                         WARN("invalid chunk (only 'coba', 'cobh', 'data' and 'LIST' chunks allowed\n");
1277                                                                                                         break;
1278                                                                                                 }
1279                                                                                         }
1280                                                                                         TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);                                                   
1281                                                                                 } while (ListCount2 < ListSize2);
1282                                                                         } else WARN("invalid chunk (only 'cobl' chunk allowed)\n");
1283                                                                         TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);                                                       
1284                                                                 } while (ListCount < ListSize);
1285                                                                 break;                                                          
1286                                                         } default: {
1287                                                                 WARN("invalid chunk (only 'UNFO' and 'cosl' chunks allowed)\n");
1288                                                         }                                                               
1289                                                 }
1290                                                 break;
1291                                         } default: {
1292                                                 WARN("invalid chunk (only 'schd', 'guid', 'vers', 'LIST', 'scve', 'RIFF' and 'scla' chunks allowed)\n");
1293                                                 break;
1294                                         }
1295                                 }
1296                                 TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);
1297                         } while (FileCount < FileSize);
1298                 } else {
1299                         WARN("invalid chunk (only 'DMSC' chunk allowed)\n");
1300                 }
1301         } else {
1302                 WARN("'RIFF' not found: not a RIFF file\n");
1303         }
1304         
1305         return S_OK;
1306 }
1307
1308 /******************************************************************************
1309  * DMUSIC_FillStyleFromFileHandle: 
1310  *      - fills a IDirectMusicStyle8Impl struct with data from file handle. 
1311  *      - IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it 
1312  *                   from another DMUSIC_Fill* function, make sure pointer is at
1313  *               correct place!
1314  *      - TODO: replace data in function with data in IDirectMusicStyleImpl
1315  */
1316 HRESULT WINAPI DMUSIC_FillStyleFromFileHandle (IDirectMusicStyle8Impl *style, HANDLE fd)
1317 {
1318         rawChunk chunk;
1319         DWORD BytesRead, ListCount = 0, ListSize, ListCount2 = 0, ListSize2, FileCount = 0, FileSize;
1320         int i;
1321         /* FIXME: Replace stuff located below with the stuff in container */
1322         UNFO_List UNFO;
1323         DMUS_IO_STYLE header;
1324         DMUS_IO_VERSION version;
1325         GUID guid;
1326         Part part;
1327         Pattern pattern;
1328         
1329         TRACE("reading 'RIFF' chunk...\n");
1330         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1331         if (chunk.id == FOURCC_RIFF) {
1332                 TRACE("'RIFF': RIFF file\n");
1333                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
1334                 FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
1335                 TRACE("reading chunks ...\n");
1336                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */             
1337                 if (chunk.id == DMUS_FOURCC_STYLE_FORM) {
1338                         TRACE("'DMST': style form\n");
1339                         do {
1340                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1341                                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1342                                 FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
1343
1344                                 switch (chunk.id)
1345                                 {
1346                                         case DMUS_FOURCC_STYLE_CHUNK: {
1347                                                 TRACE("'styh': style header\n");
1348                                                 ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
1349                                                 TRACE_(dmfiledat)("=> timeSig.bBeatsPerMeasure = %i; timeSig.bBeat = %i; timeSig.wGridsPerBeat = %d; dblTempo = %f\n", \
1350                                                         header.timeSig.bBeatsPerMeasure, header.timeSig.bBeat, header.timeSig.wGridsPerBeat, header.dblTempo);
1351                                                 break;
1352                                         } case DMUS_FOURCC_GUID_CHUNK: {
1353                                                 TRACE("'guid': GUID\n");
1354                                                 ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
1355                                                 TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
1356                                                 break;
1357                                         } case DMUS_FOURCC_VERSION_CHUNK: {
1358                                                 TRACE("'vers': version\n");
1359                                                 ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
1360                                                 TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
1361                                                 break;
1362                                         } case FOURCC_RIFF: {
1363                                                 TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded band form)\n", chunk.size);
1364                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1365                                                 if (chunk.id == DMUS_FOURCC_BAND_FORM) {
1366                                                         TRACE("'DMBD': embedded band form (forward to DMUSIC_FillBandFromFileHandle)\n");
1367                                                         SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */
1368                                                         DMUSIC_FillBandFromFileHandle (NULL, fd);
1369                                                 } else WARN("invalid chunk (only 'DMBD' chunk allowed)\n");
1370                                                 break;                                          
1371                                         } case FOURCC_LIST:{
1372                                                 TRACE("'LIST': list (size) = %ld\n", chunk.size);
1373                                                 ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
1374                                                 ListCount = 0;
1375                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1376                                                 switch (chunk.id)
1377                                                 {
1378                                                         case DMUS_FOURCC_UNFO_LIST: {
1379                                                                 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
1380                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
1381                                                                 DMUSIC_FillUNFOFromFileHandle (UNFO, fd);                                                               
1382                                                                 break;
1383                                                         } case DMUS_FOURCC_PART_LIST: {
1384                                                                 TRACE("'part': parts list (content size = %ld)\n", ListSize);
1385                                                                 do {
1386                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1387                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1388                                                                         ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
1389                                                                         switch (chunk.id)
1390                                                                         {
1391                                                                                 case DMUS_FOURCC_PART_CHUNK: {
1392                                                                                         TRACE("'prth': part header\n");
1393                                                                                         ReadFile (fd, &part.header, chunk.size, &BytesRead, NULL);
1394                                                                                         TRACE_(dmfiledat)("=> timeSig.bBeatsPerMeasure = %i; timeSig.bBeat = %i; timeSig.wGridsPerBeat = %d; dwVariationChoices = %p; guidPartID = %s; wNbrMeasures = %d; bPlayModeFlags = %i; bInvertUpper = %i; bInvertLower = %i; bPad = %p; dwFlags = %ld\n", \
1395                                                                                                 part.header.timeSig.bBeatsPerMeasure, part.header.timeSig.bBeat, part.header.timeSig.wGridsPerBeat, part.header.dwVariationChoices, \
1396                                                                                                 debugstr_guid (&part.header.guidPartID), part.header.wNbrMeasures, part.header.bPlayModeFlags, part.header.bInvertUpper, part.header.bInvertLower, \
1397                                                                                                 part.header.bPad, part.header.dwFlags);
1398                                                                                         break;
1399                                                                                 } case DMUS_FOURCC_NOTE_CHUNK: {
1400                                                                                         TRACE("'note': notes (size = %ld)\n", chunk.size);
1401                                                                                         part.nrofnotes = chunk.size - sizeof(DWORD); /* pure contents of 'note' (without first DWORD) */
1402                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLENOTE) */
1403                                                                                         part.nrofnotes /= chunk.size; /*  nrofnotes = pure contents / sizeof (DMUS_IO_STYLENOTE) */
1404                                                                                         part.notes = (DMUS_IO_STYLENOTE*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofnotes);
1405                                                                                         ReadFile (fd, part.notes, chunk.size * part.nrofnotes, &BytesRead, NULL);
1406                                                                                         TRACE_(dmfiledat)("=> number of notes = %ld\n", part.nrofnotes);
1407                                                                                         for (i = 0; i < part.nrofnotes; i++)
1408                                                                                         {
1409                                                                                                 TRACE_(dmfiledat)("=> note[%i]: mtGridStart = %li; dwVariation = %ld; mtDuration = %li; nTimeOffset = %i; wMusicValue = %d; bVelocity = %i; bTimeRange = %i; bDurRange = %i; bVelRange = %i; bInversionID = %i; bPlayModeFlags = %i; bNoteFlags= %i;\n", \
1410                                                                                                         i, part.notes[i].mtGridStart, part.notes[i].dwVariation, part.notes[i].mtDuration, part.notes[i].nTimeOffset, part.notes[i].wMusicValue, part.notes[i].bVelocity, part.notes[i].bTimeRange, \
1411                                                                                                         part.notes[i].bDurRange, part.notes[i].bVelRange, part.notes[i].bInversionID, part.notes[i].bPlayModeFlags, part.notes[i].bNoteFlags);                                                                                          
1412                                                                                         }
1413                                                                                         break;
1414                                                                                 } case DMUS_FOURCC_CURVE_CHUNK: {
1415                                                                                         TRACE("'crve': curves (size = %ld)\n", chunk.size);
1416                                                                                         part.nrofcurves = chunk.size - sizeof(DWORD); /* pure contents of 'crve' (without first DWORD) */
1417                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLECURVE) */
1418                                                                                         part.nrofcurves /= chunk.size; /*  nrofnotes = pure contents / sizeof (DMUS_IO_STYLECURVE) */
1419                                                                                         part.curves = (DMUS_IO_STYLECURVE*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofcurves);
1420                                                                                         ReadFile (fd, part.curves, chunk.size * part.nrofcurves, &BytesRead, NULL);
1421                                                                                         TRACE_(dmfiledat)("=> number of curves = %ld\n", part.nrofcurves);
1422                                                                                         for (i = 0; i < part.nrofcurves; i++)
1423                                                                                         {
1424                                                                                                 TRACE_(dmfiledat)("=> curve[%i]: mtGridStart = %li; dwVariation = %ld; mtDuration = %li; mtResetDuration = %li; nTimeOffset = %i; nStartValue = %i; nEndValue = %i; nResetValue = %i; bEventType = %i; bCurveShape = %i; bCCData = %i; bFlags = %i; wParamType = %d;wMergeIndex = %d\n", \
1425                                                                                                         i, part.curves[i].mtGridStart, part.curves[i].dwVariation, part.curves[i].mtDuration, part.curves[i].mtResetDuration, part.curves[i].nTimeOffset, part.curves[i].nStartValue, part.curves[i].nEndValue,  \
1426                                                                                                         part.curves[i].nResetValue, part.curves[i].bEventType, part.curves[i].bCurveShape, part.curves[i].bCCData, part.curves[i].bFlags, part.curves[i].wParamType, part.curves[i].wMergeIndex);
1427                                                                                         }
1428                                                                                         break;
1429                                                                                 } case DMUS_FOURCC_MARKER_CHUNK: {
1430                                                                                         TRACE("'mrkr': markers (size = %ld)\n", chunk.size);
1431                                                                                         part.nrofmarkers = chunk.size - sizeof(DWORD); /* pure contents of 'mrkr' (without first DWORD) */
1432                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLEMARKER) */
1433                                                                                         part.nrofmarkers /= chunk.size; /*  nrofnotes = pure contents / sizeof (DMUS_IO_STYLEMARKER) */
1434                                                                                         part.markers = (DMUS_IO_STYLEMARKER*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofmarkers);
1435                                                                                         ReadFile (fd, part.markers, chunk.size * part.nrofmarkers, &BytesRead, NULL);
1436                                                                                         TRACE_(dmfiledat)("=> number of markers = %ld\n", part.nrofmarkers);
1437                                                                                 for (i = 0; i < part.nrofmarkers; i++)
1438                                                                                         {
1439                                                                                                 TRACE_(dmfiledat)("=> marker[%i]: mtGridStart = %li; dwVariation = %ld; wMarkerFlags = %d\n", \
1440                                                                                                         i, part.markers[i].mtGridStart, part.markers[i].dwVariation, part.markers[i].wMarkerFlags);
1441                                                                                         }
1442                                                                                         break;
1443                                                                                 } case DMUS_FOURCC_RESOLUTION_CHUNK: {
1444                                                                                         TRACE("'rsln': resolutions (size = %ld)\n", chunk.size);
1445                                                                                         part.nrofresolutions = chunk.size - sizeof(DWORD); /* pure contents of 'rsln' (without first DWORD) */
1446                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLERESOLUTION) */
1447                                                                                         part.nrofresolutions /= chunk.size; /*  nrofnotes = pure contents / sizeof (DMUS_IO_STYLERESOLUTION) */
1448                                                                                         part.resolutions = (DMUS_IO_STYLERESOLUTION*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofresolutions);
1449                                                                                         ReadFile (fd, part.resolutions, chunk.size * part.nrofresolutions, &BytesRead, NULL);
1450                                                                                         TRACE_(dmfiledat)("=> number of resolutions = %ld\n", part.nrofresolutions);
1451                                                                                 for (i = 0; i < part.nrofresolutions; i++)
1452                                                                                         {
1453                                                                                                 TRACE_(dmfiledat)("=> resolution[%i]: dwVariation = %ld; wMusicValue = %d; bInversionID = %i; bPlayModeFlags = %i", \
1454                                                                                                         i, part.resolutions[i].dwVariation, part.resolutions[i].wMusicValue, part.resolutions[i].bInversionID, part.resolutions[i].bPlayModeFlags);
1455                                                                                         }
1456                                                                                         break;
1457                                                                                 } case DMUS_FOURCC_ANTICIPATION_CHUNK: {
1458                                                                                         TRACE("'anpn': anticipations (size = %ld)\n", chunk.size);
1459                                                                                         part.nrofanticipations = chunk.size - sizeof(DWORD); /* pure contents of 'anpn' (without first DWORD) */
1460                                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_STYLE_ANTICIPATION) */
1461                                                                                         part.nrofanticipations /= chunk.size; /*  nrofnotes = pure contents / sizeof (DMUS_IO_STYLE_ANTICIPATION) */
1462                                                                                         part.anticipations = (DMUS_IO_STYLE_ANTICIPATION*) HeapAlloc (GetProcessHeap (), 0, chunk.size * part.nrofanticipations);
1463                                                                                         ReadFile (fd, part.anticipations, chunk.size * part.nrofanticipations, &BytesRead, NULL);
1464                                                                                         TRACE_(dmfiledat)("=> number of anticipations = %ld\n", part.nrofanticipations);
1465                                                                                         for (i = 0; i < part.nrofanticipations; i++)
1466                                                                                         {
1467                                                                                                 TRACE_(dmfiledat)("=> anticipation[%i]: mtGridStart = %li; dwVariation = %ld; nTimeOffset = %i; bTimeRange = %i\n", \
1468                                                                                                         i, part.anticipations[i].mtGridStart, part.anticipations[i].dwVariation, part.anticipations[i].nTimeOffset, part.anticipations[i].bTimeRange);
1469                                                                                         }
1470                                                                                         break;
1471                                                                                 } case FOURCC_LIST: {
1472                                                                                         TRACE("'LIST': list chunk (size = %ld)\n", chunk.size);
1473                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1474                                                                                         if (chunk.id == DMUS_FOURCC_UNFO_LIST) {
1475                                                                                                 TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
1476                                                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT);  /* set pointer at beginning of list */
1477                                                                                                 DMUSIC_FillUNFOFromFileHandle (part.UNFO, fd);                                                          
1478                                                                                         } else WARN("invalid chunk (only 'UNFO' chunk allowed\n");                                              
1479                                                                                         break;                                                                                                                                                                                          
1480                                                                                 } default: {
1481                                                                                         WARN("invalid chunk (only 'prth','note', 'crve', 'mrkr', 'rsln', 'anpn' and 'LIST' chunks allowed\n");
1482                                                                                         break;
1483                                                                                 }
1484                                                                         }
1485                                                                         TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);                                                       
1486                                                                 } while (ListCount < ListSize);
1487                                                                 break;  
1488                                                         } case DMUS_FOURCC_PATTERN_LIST: {
1489                                                                 TRACE("'pttn': patterns list (content size = %ld)\n", ListSize);
1490                                                                 do {
1491                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1492                                                                         ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1493                                                                         ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
1494                                                                         switch (chunk.id)
1495                                                                         {
1496                                                                                 case DMUS_FOURCC_PATTERN_CHUNK: {
1497                                                                                         TRACE("'ptnh': pattern header\n");
1498                                                                                         ReadFile (fd, &pattern.header, chunk.size, &BytesRead, NULL);
1499                                                                                         TRACE_(dmfiledat)("=> timeSig.bBeatsPerMeasure = %i; timeSig.bBeat = %i; timeSig.wGridsPerBeat = %d; bGrooveBottom = %i; bGrooveTop = %i; wEmbellishment = %d; wNbrMeasures = %d; bDestGrooveBottom = %i; bDestGrooveTop = %i; dwFlags = %ld\n", \
1500                                                                                                 pattern.header.timeSig.bBeatsPerMeasure, pattern.header.timeSig.bBeat, pattern.header.timeSig.wGridsPerBeat, pattern.header.bGrooveBottom, pattern.header.bGrooveTop, pattern.header.wEmbellishment, \
1501                                                                                                 pattern.header.wNbrMeasures, pattern.header.bDestGrooveBottom, pattern.header.bDestGrooveTop, pattern.header.dwFlags); 
1502                                                                                         break;
1503                                                                                 } case DMUS_FOURCC_RHYTHM_CHUNK: {
1504                                                                                         TRACE("'rhtm': rhytms\n");                                                                                      
1505                                                                                         pattern.nrofrhytms = chunk.size / sizeof(DWORD);
1506                                                                                         TRACE_(dmfiledat)("=> number of rhytms = %ld\n", pattern.nrofrhytms);
1507                                                                                         pattern.rhytms = (DWORD*) HeapAlloc (GetProcessHeap (), 0, sizeof(DWORD) * pattern.nrofrhytms);
1508                                                                                         ReadFile (fd, pattern.rhytms, sizeof(DWORD) * pattern.nrofrhytms, &BytesRead, NULL);
1509                                                                                         for (i = 0; i < pattern.nrofrhytms; i++)
1510                                                                                         {
1511                                                                                                 TRACE_(dmfiledat)("=> rhytm[%i] = %ld\n", i, pattern.rhytms[i]);
1512                                                                                         }
1513                                                                                         break;
1514                                                                                 } case DMUS_FOURCC_MOTIFSETTINGS_CHUNK: {
1515                                                                                         TRACE("'mtfs': motif settings\n");                                                                                      
1516                                                                                         ReadFile (fd, &pattern.motsettings, chunk.size, &BytesRead, NULL);
1517                                                                                         TRACE_(dmfiledat)("=> dwRepeats = %ld; mtPlayStart = %li; mtLoopStart = %li; mtLoopEnd = %li; dwResolution = %ld\n", \
1518                                                                                                 pattern.motsettings.dwRepeats, pattern.motsettings.mtPlayStart, pattern.motsettings.mtLoopStart, pattern.motsettings.mtLoopEnd, pattern.motsettings.dwResolution);
1519                                                                                         break;                                                                                  
1520                                                                                 } case FOURCC_LIST: {
1521                                                                                         TRACE("'LIST': list chunk (size = %ld)\n", chunk.size);
1522                                                                                         ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
1523                                                                                         ListCount2 = 0;
1524                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1525                                                                                         switch (chunk.id)
1526                                                                                         {
1527                                                                                                 case DMUS_FOURCC_UNFO_LIST: {
1528                                                                                                         TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
1529                                                                                                         SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
1530                                                                                                         DMUSIC_FillUNFOFromFileHandle (UNFO, fd);
1531                                                                                                         break;
1532                                                                                                 } case DMUS_FOURCC_PARTREF_LIST: {
1533                                                                                                         TRACE("'pref': part references list (content size = %ld)\n", ListSize2);
1534                                                                                                         do {
1535                                                                                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1536                                                                                                                 ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
1537                                                                                                                 ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
1538                                                                                                                 switch (chunk.id)
1539                                                                                                                 { 
1540                                                                                                                         case DMUS_FOURCC_PARTREF_CHUNK: {
1541                                                                                                                                 TRACE("'prfc': part reference\n");
1542                                                                                                                                 ReadFile (fd, &pattern.partref, chunk.size, &BytesRead, NULL);
1543                                                                                                                                 TRACE_(dmfiledat)("=> guidPartID = %s; wLogicalPartID = %d; bVariationLockID = %i; bSubChordLevel = %i; bPriority = %i; bRandomVariation = %i; wPad = %d; dwPChannel = %ld\n", \
1544                                                                                                                                         debugstr_guid (&pattern.partref.guidPartID), pattern.partref.wLogicalPartID, pattern.partref.bVariationLockID, pattern.partref.bSubChordLevel, \
1545                                                                                                                                         pattern.partref.bPriority, pattern.partref.bRandomVariation, pattern.partref.wPad, pattern.partref.dwPChannel);
1546                                                                                                                         break;
1547                                                                                                                         } case FOURCC_LIST: {
1548                                                                                                                                 TRACE("'LIST': list chunk (MSDN doesn't mention it)\n");
1549                                                                                                                                 ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1550                                                                                                                                 if (chunk.id == DMUS_FOURCC_UNFO_LIST) {
1551                                                                                                                                         TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
1552                                                                                                                                         SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
1553                                                                                                                                         DMUSIC_FillUNFOFromFileHandle (UNFO, fd);
1554                                                                                                                                 } else {
1555                                                                                                                                         WARN("invalid chunk (only 'UNFO' chunk allowed)\n");
1556                                                                                                                         }
1557                                                                                                                                 break;
1558                                                                                                                         } default: {
1559                                                                                                                                 WARN("invalid chunk (only 'prfc' and 'UNFO'chunk allowed)\n");
1560                                                                                                                         }
1561                                                                                                                 }
1562                                                                                                                 TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);                                                   
1563                                                                                                         } while (ListCount2 < ListSize2);
1564                                                                                                         break;
1565                                                                                                 } default: {
1566                                                                                                         WARN("invalid chunk (only 'UNFO' and 'pref' chunks allowed\n");
1567                                                                                                 break;
1568                                                                                                 }
1569                                                                                         }
1570                                                                                         break;                                                                                                  
1571                                                                                 } case FOURCC_RIFF: {
1572                                                                                         TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded band form)\n", chunk.size);
1573                                                                                         ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
1574                                                                                         if (chunk.id == DMUS_FOURCC_BAND_FORM) {
1575                                                                                                 TRACE("'DMBD': embedded band form (forward to DMUSIC_FillBandFromFileHandle(...))\n");
1576                                                                                                 SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */
1577                                                                                                 DMUSIC_FillBandFromFileHandle (NULL, fd);
1578                                                                                         } else WARN("invalid chunk (only 'DMBD' chunk allowed)\n");
1579                                                                                         break;                                                                                  
1580                                                                                 } default: {
1581                                                                                         WARN("invalid chunk (only 'prnh','rhtm', 'mtfs', 'LIST' and 'RIFF' chunks allowed\n");                                                                                  
1582                                                                                         break;
1583                                                                                 }
1584                                                                         }
1585                                                                         TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);                                                       
1586                                                                 } while (ListCount < ListSize);
1587                                                                 break;
1588                                                         } default: {
1589                                                         WARN("invalid chunk (only 'UNFO', 'part', 'pttn' and 'RIFF' chunks allowed)\n");
1590                                                         }
1591                                         }
1592                                         break;
1593                                         } default: {
1594                                                 WARN("invalid chunk (only 'styh', 'guid', 'vers', 'LIST', and 'RIFF' chunks allowed)\n");
1595                                                 break;
1596                                         }
1597                         }
1598                                 TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);
1599                         } while (FileCount < FileSize);
1600                 } else {
1601                         WARN("invalid chunk (only 'DMST' chunk allowed)\n");
1602                 }
1603         } else {
1604                 WARN("'RIFF' not found: not a RIFF file\n");
1605         }
1606
1607         return S_OK;
1608 }
1609
1610 #endif