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