dmusic: framework for file loading

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



	As I've mentioned, we'll need a function for loading chunks from dmusic
files. I tried to write one, and here's result; it's not very nice, but
it works (sort of). 
	At the time being, it only "loads" and displays data
(--debugmsg=+dmfile for debug and --debugmsg=+dmfiledat for the display
of data). I couldn't make it load data into IDirectMusic*Impl
interfaces, because whatever I did, exception occured (maybe someone
more familiar with this could do this (Raphael?)). Also, if someone has
more robust and simpler function, please tell me.
	DMUSIC_FillSegmentFromFileHandle loads sample.sgt from DX SDK
completely... however, i didn't try the other.
	
	Also "fixed" a problem I've encountered while running 3DAudio.exe (from
SDK). One of the latest patches added this clause: 

if (!ppDirectSound)
	IDirectSound_Release(*ppDirectSound);

I don't know why, but it causes exception (i've commented it).


ChangeLog:
   - wine/dlls/dmusic/dmusic_private.h: added some new structs
   - wine/dlls/dmusic/dmusic_loader.c: load file
   - wine/dlls/dmusic/dmusic_preformance.c: minor fix
   - wine/dlls/dmusic/helper.c: new file with file loading functions



-- 
Rok Mandeljc <rok.mandeljc@gimb.org>

"All that is gold does not glitter,
Not all those who wander are lost;
The old that is strong does not wither,
Deep roots are not reached by the frost. 
From the ashes a fire shall be woken,
A light from the shadows shall spring;
Renewed shall be blade that was broken,
The crownless again shall be king."
	        -- J.R.R. Tolkien
diff -Nru Original/wine/dlls/dmusic/dmusic_loader.c wine/dlls/dmusic/dmusic_loader.c
--- Original/wine/dlls/dmusic/dmusic_loader.c	2003-06-20 13:57:28.000000000 +0200
+++ wine/dlls/dmusic/dmusic_loader.c	2003-06-22 14:54:33.000000000 +0200
@@ -315,15 +315,45 @@
 	ICOM_THIS(IDirectMusicLoader8Impl,iface);
 
 	FIXME("(%p, %s, %s, %s, %p): stub\n", This, debugstr_guid(rguidClassID), debugstr_guid(iidInterfaceID), debugstr_w(pwzFilePath), ppObject);
+	
+	HANDLE *fd;
 
-	if (IsEqualGUID(iidInterfaceID, &CLSID_DirectSoundWave)) {
-	  FIXME("wanted 'wav'\n");
-	} else if (IsEqualGUID(iidInterfaceID, &CLSID_DirectMusicScript)) {
-	  FIXME("wanted 'spt'\n");
-	} else if (IsEqualGUID(iidInterfaceID, &CLSID_DirectMusicContainer)) {
-	  FIXME("wanted 'con'\n");
+	fd = CreateFileW (pwzFilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+	if (!fd) {
+		WARN ("could not load file\n");
+		return DMUS_E_LOADER_FAILEDOPEN;
+	}
+	
+	if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicAudioPathConfig)) {
+		FIXME("wanted 'aud'\n");
+	} else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicBand)) {
+		FIXME("wanted 'bnd'\n");
+		DMUSIC_FillBandFromFileHandle (NULL, fd);
+	} else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicContainer)) {
+		FIXME("wanted 'con'\n");
+	} else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicCollection)) {
+		FIXME("wanted 'dls'\n");
+	} else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicChordMap)) {
+		FIXME("wanted 'cdm'\n");
+	} else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicSegment)) {
+		FIXME("wanted 'sgt'\n");
+		DMUSIC_FillSegmentFromFileHandle (NULL, fd);
+	} else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicScript)) {
+		FIXME("wanted 'spt'\n");
+	} else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicSong)) {
+		FIXME("wanted 'sng'\n");
+	} else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicStyle)) {
+		FIXME("wanted 'sty'\n");
+	} else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicSegment)) {
+		FIXME("wanted 'tpl'\n");
+	} else if (IsEqualGUID(rguidClassID, &CLSID_DirectMusicGraph)) {
+		FIXME("wanted 'tgr'\n");
+	} else if (IsEqualGUID(rguidClassID, &CLSID_DirectSoundWave)) {
+		FIXME("wanted 'wav'\n");
 	}
 
+	CloseHandle (fd);
+	
 	if (IsEqualGUID(iidInterfaceID, &IID_IDirectMusicSegment) || 
 	    IsEqualGUID(iidInterfaceID, &IID_IDirectMusicSegment8)) {
 	  IDirectMusicSegment8Impl* segment;
@@ -331,6 +361,7 @@
 	  segment->lpVtbl = &DirectMusicSegment8_Vtbl;
 	  segment->ref = 1;
 	  *ppObject = segment;
+	  return S_OK;
 	} else if (IsEqualGUID(iidInterfaceID, &IID_IDirectMusicContainer)) {
 	  IDirectMusicContainerImpl* container;
 	  container = HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectMusicContainerImpl));
diff -Nru Original/wine/dlls/dmusic/dmusic_performance.c wine/dlls/dmusic/dmusic_performance.c
--- Original/wine/dlls/dmusic/dmusic_performance.c	2003-06-20 13:57:28.000000000 +0200
+++ wine/dlls/dmusic/dmusic_performance.c	2003-06-22 14:37:05.000000000 +0200
@@ -1015,7 +1015,7 @@
         ICOM_THIS(IDirectMusicPerformance8Impl,iface);
 	FIXME("(%p, %p, %p, %p, %lx, %lu, %lx, %p): to check\n", This, ppDirectMusic, ppDirectSound, hWnd, dwDefaultPathType, dwPChannelCount, dwFlags, pParams);
 
-        if (This->dmusic || This->dsound)
+	if (This->dmusic || This->dsound)
 	  return DMUS_E_ALREADY_INITED;
 
 	if (NULL != ppDirectSound && NULL != *ppDirectSound) {
@@ -1029,8 +1029,8 @@
 	IDirectMusicPerformance8Impl_Init(iface, ppDirectMusic, This->dsound, hWnd);
 
 	/* Init increases the ref count of the dsound object. Decremente it if the app don't want a pointer to the object. */
-        if (!ppDirectSound)
-	  IDirectSound_Release(*ppDirectSound);
+	/*if (!ppDirectSound)
+	  IDirectSound_Release(*ppDirectSound);*/
 	
 	/* as seen in msdn we need params init before audio path creation */
 	if (NULL != pParams) {
diff -Nru Original/wine/dlls/dmusic/dmusic_private.h wine/dlls/dmusic/dmusic_private.h
--- Original/wine/dlls/dmusic/dmusic_private.h	2003-06-20 13:57:28.000000000 +0200
+++ wine/dlls/dmusic/dmusic_private.h	2003-06-22 14:37:05.000000000 +0200
@@ -152,6 +152,56 @@
 	DMUSIC_PRIVATE_MCHANNEL channel[16]; /* 16 channels in a group */
 } DMUSIC_PRIVATE_CHANNEL_GROUP, *LPDMUSIC_PRIVATE_CHANNEL_GROUP;
 
+/* used for loading chunks of data from files */
+typedef struct _rawChunk
+{
+	FOURCC id; /* FOURCC */
+	DWORD size; /* size of chunk_riff */
+	// BYTE* data; /* chunk_riff data */
+} rawChunk;
+
+/* struct in which UNFO data is stored */
+typedef struct _UNFO_List
+{
+	WCHAR* name;
+	WCHAR* artist;
+	WCHAR* copyright;
+	WCHAR* version;
+	WCHAR* subject;
+	WCHAR* comment;
+} UNFO_List;
+
+typedef struct _ChordData
+{
+	DMUS_IO_CHORD chord;
+	DWORD nrofsubchords;
+	DMUS_IO_SUBCHORD *subchord;	
+} ChordData;
+
+typedef struct _Reference
+{
+	DMUS_IO_REFERENCE header;
+	GUID guid;
+	FILETIME date;
+	WCHAR* name;
+	WCHAR* file;
+	WCHAR* category;
+	DMUS_IO_VERSION version;
+} Reference;
+
+typedef struct _BandTrack
+{
+	DMUS_IO_BAND_TRACK_HEADER header;
+	GUID guid;
+	DMUS_IO_VERSION version;
+	UNFO_List UNFO;
+	
+	DMUS_IO_BAND_ITEM_HEADER header1;
+	DMUS_IO_BAND_ITEM_HEADER2 header2;
+	
+	/* IDirectMusicBandImpl **band; */
+	
+} BandTrack;
 
 /*****************************************************************************
  * IDirectMusicImpl implementation structure
@@ -783,7 +833,7 @@
   ICOM_VFIELD(IDirectMusicSegment);
   DWORD          ref;
 
-  /* IDirectMusicSegmentImpl fields */
+  /* IDirectMusicSegmentImpl fields */  
 };
 
 /* IUnknown: */
@@ -1323,5 +1373,11 @@
  * Helper Functions
  */
 void register_waveport (LPGUID lpGUID, LPCSTR lpszDesc, LPCSTR lpszDrvName, LPVOID lpContext);
+/* Loader Helper Functions */
+HRESULT WINAPI DMUSIC_FillSegmentFromFileHandle (IDirectMusicSegmentImpl *segment, HANDLE fd);
+HRESULT WINAPI DMUSIC_FillTrackFromFileHandle (IDirectMusicTrackImpl *segment, HANDLE fd);
+HRESULT WINAPI DMUSIC_FillReferenceFromFileHandle (Reference reference, HANDLE fd);
+HRESULT WINAPI DMUSIC_FillUNFOFromFileHandle (UNFO_List UNFO, HANDLE fd);
+HRESULT WINAPI DMUSIC_FillBandFromFileHandle (IDirectMusicBandImpl *band, HANDLE fd);
 
 #endif	/* __WINE_DMUSIC_PRIVATE_H */
diff -Nru Original/wine/dlls/dmusic/helper.c wine/dlls/dmusic/helper.c
--- Original/wine/dlls/dmusic/helper.c	1970-01-01 01:00:00.000000000 +0100
+++ wine/dlls/dmusic/helper.c	2003-06-22 14:37:08.000000000 +0200
@@ -0,0 +1,735 @@
+/* Helper functions for dmusic file handling
+ *
+ * Copyright (C) 2003 Rok Mandeljc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#include "dmusic_private.h"
+
+/* used while still in testing */
+WINE_DEFAULT_DEBUG_CHANNEL(dmfile);
+WINE_DECLARE_DEBUG_CHANNEL(dmfiledat);
+
+/******************************************************************************
+ * DMUSIC_FillUNFOFromFileHandle: 
+ *	- fills a UNFO_List struct (dmusic_private.h) with data from file handle. 
+ *	- IMPORTANT: it expects a LIST chunk at beginning, so if you are calling it 
+ *	             from another DMUSIC_Fill* function, make sure pointer is at
+ *               correct place!
+ */
+HRESULT WINAPI DMUSIC_FillUNFOFromFileHandle (UNFO_List UNFO, HANDLE fd)
+{
+	rawChunk chunk;
+	DWORD BytesRead, ListCount = 0, ListSize;
+
+	TRACE("reading 'LIST' chunk...\n");
+	ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read 'LIST' */
+	ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'LIST' chunk */
+	if (chunk.id == FOURCC_LIST && 	ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_UNFO_LIST) {
+		TRACE("'UNFO': UNFO list\n");
+		ListSize = chunk.size - sizeof(FOURCC); /* list contents size is same as size of LIST chunk - size of following field ID*/
+		do {
+			ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following field */
+			ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of following field */
+			ListCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
+			switch (chunk.id)
+			{
+				case DMUS_FOURCC_UNAM_CHUNK: {
+					TRACE("'UNAM': name\n");
+					UNFO.name = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size); /* allocate space */
+					ReadFile (fd, UNFO.name, chunk.size, &BytesRead, NULL);
+					TRACE_(dmfiledat)("=> name = %s\n", debugstr_w(UNFO.name));
+					break;
+				} case DMUS_FOURCC_UART_CHUNK: {
+					TRACE("'UART': artist\n");
+					UNFO.artist = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size); /* allocate space */
+					ReadFile (fd, UNFO.artist, chunk.size, &BytesRead, NULL);
+					TRACE_(dmfiledat)("artist = %s\n", debugstr_w(UNFO.artist));
+					break;
+				} case DMUS_FOURCC_UCOP_CHUNK: {
+					TRACE("'UCOP': copyright\n");
+					UNFO.copyright = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size); /* allocate space */
+					ReadFile (fd, UNFO.copyright, chunk.size, &BytesRead, NULL);
+					TRACE_(dmfiledat)("=> copyright = %s\n", debugstr_w(UNFO.copyright));
+					break;
+				} case DMUS_FOURCC_USBJ_CHUNK:{
+					TRACE("'USBJ': subject\n");
+					UNFO.subject = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size); /* allocate space */
+					ReadFile (fd, UNFO.subject, chunk.size, &BytesRead, NULL);
+					TRACE_(dmfiledat)("=> subject = %s\n", debugstr_w(UNFO.subject));
+					break;
+				} case DMUS_FOURCC_UCMT_CHUNK: {
+					TRACE("'UCMT': comment\n");
+					UNFO.comment = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size); /* allocate space */
+					ReadFile (fd, UNFO.comment, chunk.size, &BytesRead, NULL);
+					TRACE_(dmfiledat)("=> comment = %s\n", debugstr_w(UNFO.comment));
+					break;
+				} default: {
+					WARN("invalid chunk (only 'UNAM', 'UART', 'UCOP', 'USBJ', 'UCMT' allowed)\n");
+					break;
+				}
+			}
+			TRACE("ListCount (%ld) < ListSize(%ld)\n", ListCount, ListSize);
+		} while (ListCount < ListSize);
+	} else {
+		WARN("'UNFO' not found: not an UNFO list\n");
+	}		
+	return S_OK;	
+}
+
+/******************************************************************************
+ * DMUSIC_FillReferenceFromFileHandle: 
+ *	- fills a Reference struct (dmusic_private.h) with data from file handle. 
+ *	- IMPORTANT: it expects a LIST chunk at beginning, so if you are calling it 
+ *	             from another DMUSIC_Fill* function, make sure pointer is at
+ *               correct place!
+ */
+HRESULT WINAPI DMUSIC_FillReferenceFromFileHandle (Reference reference, HANDLE fd)
+{
+	rawChunk chunk;
+	DWORD BytesRead, ListCount = 0, ListSize;
+
+	TRACE("reading 'LIST' chunk...\n");
+	ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read 'LIST' */
+	ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'LIST' chunk */
+	if (chunk.id == FOURCC_LIST && 	ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_REF_LIST) {
+		TRACE("'DMRF': reference list\n");
+		ListSize = chunk.size - sizeof(FOURCC); /* list contents size is same as size of LIST chunk - size of following field ID*/
+		do {
+			ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following field */
+			ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of following field */				
+			ListCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
+			switch (chunk.id)
+			{
+				case DMUS_FOURCC_REF_CHUNK: {
+					TRACE("'refh': reference header\n");
+					ReadFile (fd, &reference.header, chunk.size, &BytesRead, NULL);
+					TRACE_(dmfiledat)("=> guidClassID = %s; dwValidData = %ld\n", debugstr_guid (&reference.header.guidClassID), reference.header.dwValidData);
+					break;
+				} case DMUS_FOURCC_GUID_CHUNK: {
+					TRACE("'guid': GUID\n");
+					ReadFile (fd, &reference.guid, chunk.size, &BytesRead, NULL);
+					TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid (&reference.guid));
+					break;
+				} case DMUS_FOURCC_DATE_CHUNK: {
+					TRACE("'date': file date\n");
+					ReadFile (fd, &reference.date, chunk.size, &BytesRead, NULL);
+					TRACE_(dmfiledat)("=> file date = %ld%ld\n", reference.date.dwHighDateTime, reference.date.dwLowDateTime);
+					break;
+				} case DMUS_FOURCC_NAME_CHUNK: {
+					TRACE("'name': name\n");
+					reference.name = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size);
+					ReadFile (fd, reference.name, chunk.size, &BytesRead, NULL);
+					TRACE_(dmfiledat)("=> name = %s\n", debugstr_w (reference.name));
+					break;
+				} case DMUS_FOURCC_FILE_CHUNK: {
+					TRACE("'file': file name\n");
+					reference.file = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size);
+					ReadFile (fd, reference.file, chunk.size, &BytesRead, NULL);
+					TRACE_(dmfiledat)("=> file name = %s\n", debugstr_w (reference.file));
+					break;
+				} case DMUS_FOURCC_CATEGORY_CHUNK: {
+					TRACE("'catg': category\n");
+					reference.category = (WCHAR*) HeapAlloc (GetProcessHeap (), 0, sizeof(WCHAR) * chunk.size);
+					ReadFile (fd, reference.category, chunk.size, &BytesRead, NULL);
+					TRACE_(dmfiledat)("=> category = %s\n", debugstr_w (reference.category));
+					break;
+				} case DMUS_FOURCC_VERSION_CHUNK: {
+					TRACE("'vers': version\n");
+					ReadFile (fd, &reference.version, sizeof(DMUS_IO_VERSION), &BytesRead, NULL);
+					TRACE_(dmfiledat)("=> version = %ld%ld\n", reference.version.dwVersionMS, reference.version.dwVersionLS);				
+					break;
+				} default: {
+					WARN("invalid chunk (only 'refh, 'guid', 'date', 'name', 'file', 'catg', 'vers' allowed\n");
+					break;
+				}	
+			}
+			TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
+		} while (ListCount < ListSize);	
+	}
+	
+	return S_OK;
+}
+
+/******************************************************************************
+ * DMUSIC_FillBandFromFileHandle: 
+ *	- fills a IDirectMusicBandImpl struct with data from file handle. 
+ *	- IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it 
+ *	             from another DMUSIC_Fill* function, make sure pointer is at
+ *               correct place!
+ *	- TODO: replace data in function with data in IDirectMusicBandImpl
+ */
+HRESULT WINAPI DMUSIC_FillBandFromFileHandle (IDirectMusicBandImpl *band, HANDLE fd)
+{
+	rawChunk chunk;
+	DWORD BytesRead, ListCount = 0, ListSize, ListCount2 = 0, ListSize2, FileCount = 0, FileSize;
+	/* FIXME: Replace stuff located below with the stuff in band */
+	UNFO_List UNFO;
+	DMUS_IO_VERSION version;
+	GUID guid;
+	/* only in singular form for time being */
+	DMUS_IO_INSTRUMENT header;
+	Reference reference;
+	
+	TRACE("reading 'RIFF' chunk...\n");
+	ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read 'RIFF' */
+	if (chunk.id == FOURCC_RIFF) {
+		TRACE("'RIFF': RIFF file\n");
+		ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
+		FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
+		TRACE("reading chunks ...\n");
+		ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */
+		if (chunk.id == DMUS_FOURCC_BAND_FORM) {
+			TRACE("'DMBD': band form\n");
+			do {
+				ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+				ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
+				FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
+				switch (chunk.id)
+				{
+					case DMUS_FOURCC_GUID_CHUNK: {
+						TRACE("'guid': GUID\n");
+						ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
+						TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
+						break;
+					} case DMUS_FOURCC_VERSION_CHUNK: {
+						TRACE("'vers': version\n");
+						ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
+						TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
+						break;			
+					} case FOURCC_LIST:{
+						TRACE("'LIST': list chunk (size = %ld)\n", chunk.size);
+						ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
+						ListCount = 0; /* reset */
+						ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read list ID  */
+						switch (chunk.id)
+						{
+							case DMUS_FOURCC_UNFO_LIST: {
+								TRACE("'UNFO': UNFO list (content size = %ld)\n", ListSize);
+								SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* set pointer at beginning of list */
+								DMUSIC_FillUNFOFromFileHandle (UNFO, fd); /* forward to DMUSIC_FillUNFOFromFileHandle */
+								break;								
+							} case DMUS_FOURCC_INSTRUMENTS_LIST: {
+								TRACE("'lbil': instrumets list (content size = %ld)\n", ListSize);
+								do {
+									ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+									ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
+									ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;	
+									if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_INSTRUMENT_LIST) {
+										ListSize2 = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
+										ListCount2 = 0; /* reset */
+										TRACE("'lbin': instrument (size = %ld)\n", ListSize2);
+										do {
+											ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+											ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
+											ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
+											switch (chunk.id)
+											{
+												case DMUS_FOURCC_INSTRUMENT_CHUNK: {
+													TRACE("'bins': instrument header\n");
+													ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
+													TRACE_(dmfiledat)("=> dwPatch = %ld; dwAssignPatch = %ld; dwPChannel = %ld; dwFlags = %ld; bPan = %i; bVolume = %i; nTranspose = %i; dwChannelPriority = %ld; nPitchBendRange = %i", \
+														header.dwPatch, header.dwAssignPatch, header.dwPChannel, header.dwFlags, header.bPan, header.bVolume, header.nTranspose, header.dwChannelPriority, header.nPitchBendRange);
+													break;
+												} case FOURCC_LIST: {
+													TRACE("'LIST': list chunk (size = %ld)\n", chunk.size);
+													ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+													if (chunk.id == DMUS_FOURCC_REF_LIST) {
+														TRACE("'DMRF': reference list (size = %ld)\n", chunk.size - 4); /* set pointer at beginning of list */
+														SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT);
+														DMUSIC_FillReferenceFromFileHandle (reference, fd); /* forward to DMUSIC_FillReferenceFromFileHandle */
+													} else WARN("invalid chunk (only 'DMRF' chunk allowed\n");						
+													break;												
+												} default: {
+													WARN("invalid chunk (only 'bins' and 'LIST' chunks allowed\n");
+													break;
+												}
+											}
+											TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);							
+										} while (ListCount2 < ListSize2);
+										
+									} else WARN("invalid chunk (only 'lbin' chunk allowed)\n");
+									TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);							
+								} while (ListCount < ListSize);
+								break;
+							} default: {
+								WARN("invalid chunk (only 'UNFO' and 'lbil' chunks allowed\n");
+								break;
+							}
+						}
+						break;
+					} default: {
+						WARN("invalid chunk (only 'guid', 'vers' and 'LIST' chunks allowed)\n");
+						break;
+					}
+				}
+				TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);				
+			} while (FileCount < FileSize);
+		}
+	} else {
+		WARN("'RIFF' not found: not a RIFF file\n");
+	}
+	
+	return S_OK;
+}
+
+/******************************************************************************
+ * DMUSIC_FillTrackFromFileHandle: 
+ *	- fills a IDirectMusicTrackImpl struct with data from file handle. 
+ *	- IMPORTANT: it expects a RIFF chunk at beginning, so if you are calling it 
+ *	             from another DMUSIC_Fill* function, make sure pointer is at
+ *               correct place!
+ *	- TODO: replace data in function with data in IDirectMusicTrackImpl
+ *			implement loading for missing (empty) clauses
+ *			fix a problem with tempo track loading (look at code)
+ */
+HRESULT WINAPI DMUSIC_FillTrackFromFileHandle (IDirectMusicTrackImpl *segment, HANDLE fd)
+{
+	rawChunk chunk;
+	DWORD BytesRead, ListCount = 0, ListCount2 = 0, ListSize, ListSize2, FileCount = 0, FileSize, FileCount2 = 0, FileSize2 /* *2s are for various subchunks  */;
+	
+	/* general track info */
+	DMUS_IO_TRACK_HEADER header;
+	DMUS_IO_TRACK_EXTRAS_HEADER extheader;
+	GUID guid;
+	DMUS_IO_VERSION version;
+	UNFO_List UNFO;
+	/* tempo track stuff */
+	DMUS_IO_TEMPO_ITEM tempo;
+	/* chord track stuff */
+	DWORD chordHeader;
+	ChordData chordData;
+	/* command track stuff */
+	DMUS_IO_COMMAND command;
+	/* sytle list stuff (support only 1 while still in parse development mode)*/
+	DWORD timestamp;
+	Reference reference;
+	/* band track stuff */
+	BandTrack bandTrack;
+		
+	TRACE("reading 'RIFF' chunk...\n");
+	ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+	if (chunk.id == FOURCC_RIFF) {
+		TRACE ("'RIFF': RIFF file\n");
+		ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
+		FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
+		TRACE("reading chunks ...\n");
+		ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);  /* read ID of following form */
+		if (chunk.id == DMUS_FOURCC_TRACK_FORM) {
+			TRACE("'DMTK': track form\n");
+			do {
+				ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+				ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
+				FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
+				switch (chunk.id)
+				{
+					case DMUS_FOURCC_TRACK_CHUNK: {
+						TRACE("'trkh': track header\n");
+						ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
+						TRACE_(dmfiledat)("=> track guidClassID = %s; dwPosition = %ld; dwGroup = %ld; ckid = %ld; fccType = %ld\n", \
+							debugstr_guid (&header.guidClassID), header.dwPosition, header.dwGroup, header.ckid, header.fccType);
+						break;
+					} case DMUS_FOURCC_TRACK_EXTRAS_CHUNK: {
+						TRACE("'trkx': extra track flags\n");
+						ReadFile (fd, &extheader, chunk.size, &BytesRead, NULL);
+						TRACE_(dmfiledat)("=> dwFlags = %ld; dwPriority = %ld\n", extheader.dwFlags, 
+							extheader.dwPriority);
+						break;
+					} case DMUS_FOURCC_GUID_CHUNK: {
+						TRACE("'guid': GUID\n");
+						ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
+						TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
+						break;
+					} case DMUS_FOURCC_VERSION_CHUNK: {
+						TRACE("'vers': version\n");
+						ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
+						TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
+						break;
+					} case FOURCC_LIST:{
+						TRACE("'LIST': list (size = %ld)\n", chunk.size);
+						ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
+						ListCount = 0; /* reset */
+						ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+						switch (chunk.id)
+						{
+							case DMUS_FOURCC_UNFO_LIST: {
+								TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
+								SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
+								DMUSIC_FillUNFOFromFileHandle (UNFO, fd); /* forward to DMUSIC_FillUNFOFromFileHandle */
+								break;								
+							} case DMUS_FOURCC_CHORDTRACK_LIST: {
+								TRACE("'cord': chord track list\n");
+								do {
+									ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+									ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
+									ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
+									switch (chunk.id)
+									{
+										case DMUS_FOURCC_CHORDTRACKHEADER_CHUNK: {
+											TRACE("'crdh': chord header\n");
+											ReadFile (fd, &chordHeader, chunk.size, &BytesRead, NULL);
+											TRACE_(dmfiledat)("=> chord root = %i; scale = %i\n", (chordHeader && 0xFF000000) >> 24, chordHeader && 0x00FFFFFF);
+											break;
+										} case DMUS_FOURCC_CHORDTRACKBODY_CHUNK: {
+											TRACE("'crdb': chord body\n");
+											ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_CHORD) */											
+											ReadFile (fd, &chordData.chord, chunk.size, &BytesRead, NULL); /* read DMUS_IO_CHORD */
+											TRACE_(dmfiledat)("=> wszName[16] = %s; mtTime = %li; chord.wMeasure = %d; chord.bBeat = %i; bFlags = %i\n", \
+												debugstr_w (chordData.chord.wszName), chordData.chord.mtTime, chordData.chord.wMeasure, chordData.chord.bBeat, chordData.chord.bFlags);
+											ReadFile (fd, &chordData.nrofsubchords, sizeof(DWORD), &BytesRead, NULL); /* read number of subchords */
+											TRACE_(dmfiledat)("=> number of subchords = %ld\n", chordData.nrofsubchords);
+											ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof (DMUS_IO_SUBCHORD) */
+											chordData.subchord = (DMUS_IO_SUBCHORD*) HeapAlloc (GetProcessHeap (), 0, sizeof(DMUS_IO_SUBCHORD) * chordData.nrofsubchords); /* allocate space */
+											int i;
+											for (i = 0; i < chordData.nrofsubchords; i++)
+											{
+												TRACE_(dmfiledat)("=> subchord[%i]:  dwChordPattern = %ld; dwScalePattern = %ld; dwInversionPoints = %ld; dwLevels = %ld; bChordRoot = %i; bScaleRoot = %i\n", \
+													i, chordData.subchord[i].dwChordPattern, chordData.subchord[i].dwScalePattern, chordData.subchord[i].dwInversionPoints, chordData.subchord[i].dwLevels, \
+													chordData.subchord[i].bChordRoot, chordData.subchord[i].bScaleRoot);
+											}
+											ReadFile (fd, chordData.subchord, chunk.size*chordData.nrofsubchords, &BytesRead, NULL);
+											break;
+										} default: {
+											WARN("Invalid chunk (only 'crdh' and 'crdb' chunks allowed)\n");
+											break;
+										}
+									}
+									TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
+								} while (ListCount < ListSize);
+								break;
+							}  case DMUS_FOURCC_STYLE_TRACK_LIST: {
+								TRACE("'sttr': style track list\n");
+								do {
+									ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+									ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
+									ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;				
+									if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_STYLE_REF_LIST) {
+										ListSize2 = chunk.size - sizeof(FOURCC);
+										TRACE("'strf': style reference list (size = %ld)\n", ListSize2);
+										do {										
+										
+											ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+											ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
+											ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
+											switch (chunk.id)
+											{
+												case DMUS_FOURCC_TIME_STAMP_CHUNK: {
+													TRACE("'stmp': time stamp\n");
+													ReadFile (fd, &timestamp, chunk.size, &BytesRead, NULL);
+													TRACE_(dmfiledat)("=> time stamp = %ld\n", timestamp);
+													break;
+												} case FOURCC_LIST: {
+													TRACE("'LIST': list\n");
+													ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+													if (chunk.id == DMUS_FOURCC_REF_LIST){
+														TRACE("'DMRF': reference list (forward to DMUSIC_FillReferenceFromFileHandle(...)\n");
+														SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
+														DMUSIC_FillReferenceFromFileHandle (reference, fd);
+													} else {
+														WARN("invalid chunk (only 'DMRF' chunk allwed)\n");
+													}											
+													break;
+												} default: {
+													WARN("invalid chunk (only 'stmp' and 'LIST' chunk allowed)\n");
+													break;
+												}
+											}
+											TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);
+										} while (ListCount2 < ListSize2);
+									} else {
+										WARN("invalid chunk (only 'strf' allowed)\n");
+									}																			
+									TRACE("ListCount (%ld) < ListSize (%ld)\n", ListCount, ListSize);
+								} while (ListCount < ListSize);
+								break;	
+							} 
+						}
+						break;
+					} case FOURCC_RIFF: {
+						TRACE("'RIFF': embedded RIFF chunk (probably band track form)\n");
+						ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+						if (chunk.id == DMUS_FOURCC_BANDTRACK_FORM) {
+							TRACE("'DMBT': band track form\n");
+							FileSize2 = chunk.size - sizeof(FOURCC);
+							do {
+								ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+								ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
+								FileCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
+								switch (chunk.id)
+								{
+									case DMUS_FOURCC_BANDTRACK_CHUNK: {
+										TRACE("'dbth': band track header\n");
+										ReadFile (fd, &bandTrack.header, chunk.size, &BytesRead, NULL);
+										TRACE_(dmfiledat)("=> bAutoDownload = %d\n", bandTrack.header.bAutoDownload);
+										break;
+									} case DMUS_FOURCC_GUID_CHUNK: {
+										TRACE("'guid': GUID\n");
+										ReadFile (fd, &bandTrack.guid, chunk.size, &BytesRead, NULL);
+										TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid (&bandTrack.guid));
+										break;
+									} case DMUS_FOURCC_VERSION_CHUNK: {
+										TRACE("'vers': version\n");
+										ReadFile (fd, &bandTrack.version, chunk.size, &BytesRead, NULL);
+										TRACE_(dmfiledat)("=> version = %ld%ld\n", bandTrack.version.dwVersionMS, bandTrack.version.dwVersionLS);				
+										break;
+									} case FOURCC_LIST: {
+										TRACE("'LIST': list (content size = %ld)\n", chunk.size);
+										ListSize = chunk.size - sizeof(FOURCC);
+										ListCount = 0;
+										ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+										switch (chunk.id)
+										{
+											case DMUS_FOURCC_UNFO_LIST:{
+												TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle)\n");
+												SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'LIST' chunk */
+												DMUSIC_FillUNFOFromFileHandle (UNFO, fd);								
+												break;								
+											} case DMUS_FOURCC_BANDS_LIST: {
+												TRACE("'lbdl': bands list (content size = %ld)\n", ListSize);
+												do {
+													ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+													ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
+													ListCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
+													if (chunk.id == FOURCC_LIST && ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL) && chunk.id == DMUS_FOURCC_BAND_LIST) {
+														ListSize2 = chunk.size - sizeof(FOURCC);
+														ListCount2 = 0;
+														TRACE("'lbnd': band list (content size = %ld)\n", ListSize2);
+														do {
+															ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+															ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
+															ListCount2 += sizeof(FOURCC) + sizeof(DWORD) + chunk.size;
+															switch (chunk.id)
+															{
+																case DMUS_FOURCC_BANDITEM_CHUNK: {
+																	TRACE("'bdih': old band header\n");
+																	ReadFile (fd, &bandTrack.header1, chunk.size, &BytesRead, NULL);
+																	TRACE_(dmfiledat)("=> lBandTime = %li\n", bandTrack.header1.lBandTime);
+																	break;
+																} case DMUS_FOURCC_BANDITEM_CHUNK2: {
+																	TRACE("'bd2h': new band header\n");
+																	ReadFile (fd, &bandTrack.header2, chunk.size, &BytesRead, NULL);
+																	TRACE_(dmfiledat)("=> lBandTimeLogical = %li; lBandTimePhysical = %li\n", \
+																		bandTrack.header2.lBandTimeLogical, bandTrack.header2.lBandTimePhysical);
+																	break;
+																} case FOURCC_RIFF: {
+																	TRACE("'RIFF': embedded RIFF (size = %ld; could be embedded band form)\n", chunk.size);
+																	ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+																	if (chunk.id == DMUS_FOURCC_BAND_FORM) {
+																		TRACE("'DMBD': embedded band form (forward to DMUSIC_FillBandFromFileHandle)\n");
+																		SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before 'RIFF' chunk */
+																		DMUSIC_FillBandFromFileHandle (NULL, fd);
+																	} else WARN("invalid chunk (only 'RIFF' chunk allowed)\n");
+																	break;
+																} default: {
+																	WARN("invalid chunk (only 'bdih', 'bd2h' and 'RIFF' chunks allowed)\n");
+																	break;
+																}
+															}
+															TRACE("ListCount2 (%ld) < ListSize2 (%ld)\n", ListCount2, ListSize2);									
+														} while (ListCount2 < ListSize2);
+													} else WARN("unknown chunk - expect error\n");
+													
+												} while (ListCount < ListSize);
+												break;
+											} default: {
+												WARN("invalid chunk (only 'UNFO' and 'lbdl' chunks allowed)\n");
+											}
+										}
+										break;
+									} default: {
+										WARN("invalid chunk (only 'dbth', 'guid', 'vers' and 'LIST' chunks allowed)\n");
+										break;
+									}								
+								}
+								TRACE("FileCount2 (%ld) < FileSize2 (%ld)\n", FileCount2, FileSize2);									
+							} while (FileCount2 < FileSize2);
+						} else {
+							WARN("invalid chunk (only 'DMBT' chunk allowed\n");
+						}
+						break;
+					} case DMUS_FOURCC_PERS_TRACK_LIST: {
+						FIXME("'pftr': chordmap track list: not supported yet\n");
+						break;
+					} case DMUS_FOURCC_COMMANDTRACK_CHUNK: {
+						TRACE("'cmnd': command track\n");
+						ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read sizeof(DMUS_IO_COMMAND) */
+						ReadFile (fd, &command, chunk.size, &BytesRead, NULL); /* read DMUS_IO_COMMAND */
+						TRACE_(dmfiledat)("wMeasure = %d; bBeat = %i; bCommand = %i; bGrooveLevel = %i; bGrooveRange = %i; bRepeatMode = %i\n", \
+							command.wMeasure, command.bBeat, command.bCommand, command.bGrooveLevel, command.bGrooveRange, command.bRepeatMode);
+						break;
+					} case DMUS_FOURCC_LYRICSTRACK_LIST: {
+						FIXME("'lyrt': lyrics track list: not supported yet\n");
+						break;
+					}  case DMUS_FOURCC_MARKERTRACK_LIST: {
+						FIXME("'MARK': marker track list: not supported yet\n");
+						break;
+					}  case DMUS_FOURCC_MELODYFORM_TRACK_LIST: {
+						FIXME("'mfrm': melody formulation track list: not supported yet\n");
+						break;
+					}  case DMUS_FOURCC_MUTE_CHUNK: {
+						FIXME("'mute': mute track chunk: not supported yet\n");
+						break;
+					}  case DMUS_FOURCC_PARAMCONTROLTRACK_TRACK_LIST: {
+						FIXME("'prmt': parameter control track list: not supported yet\n");
+						break;
+					}  case DMUS_FOURCC_PATTERN_FORM: {
+						FIXME("'DMPT': pattern track form: not supported yet\n");
+						break;
+					}  case DMUS_FOURCC_SCRIPTTRACK_LIST: {
+						FIXME("'scrt': script track list: not supported yet\n");
+						break;
+					}  case DMUS_FOURCC_SEGTRACK_LIST: {
+						FIXME("'segt': segment trigger track list: not supported yet\n");
+						break;
+					}  case DMUS_FOURCC_SEQ_TRACK: {
+						FIXME("'seqt': sequence track chunk: not supported yet\n");
+						break;
+					}  case DMUS_FOURCC_SIGNPOST_TRACK_CHUNK: {
+						FIXME("'sgnp': signpost track chunk: not supported yet\n");
+						break;
+					}  case DMUS_FOURCC_SYSEX_TRACK: {
+						FIXME("'syex': sysex track chunk: not supported yet\n");
+						break;
+					}  case DMUS_FOURCC_TEMPO_TRACK: {
+						TRACE("'tetr': tempo track chunk\n");
+						ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
+						if (chunk.size != sizeof(DMUS_IO_TEMPO_ITEM))
+							WARN("there seem so te ba problem: file claims that size of DMUSIC_IO_TEMPO_ITEM is %ld, while real sizeof returns %i", \
+								chunk.size, sizeof(DMUS_IO_TEMPO_ITEM));
+						ReadFile (fd, &tempo, chunk.size, &BytesRead, NULL);
+						TRACE_(dmfiledat)("lTime = %ld; dblTempo = %lf\n", tempo.lTime, tempo.dblTempo);
+						break;
+					}  case DMUS_FOURCC_TIMESIGNATURE_TRACK: {
+						FIXME("'tims': time signature track list: not supported yet\n");
+						break;
+					}  case DMUS_FOURCC_WAVETRACK_LIST: {
+						FIXME("'wavt': wave track list not supported yet\n");
+						break;
+					} default: {
+						WARN("invalid chunk (too many too list)\n");
+						break;
+					}
+				}
+				TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);
+			} while (FileCount < FileSize);
+		} else {
+			WARN("invalid chunk (only 'DMTK' chunk allowed)\n");
+		}
+	} else {
+		WARN("'RIFF' not found: not a RIFF file\n");
+	}
+	
+	return S_OK;
+}
+
+HRESULT WINAPI DMUSIC_FillSegmentFromFileHandle (IDirectMusicSegmentImpl *segment, HANDLE fd)
+{
+	rawChunk chunk;
+	DWORD BytesRead, ListCount = 0, ListSize, FileCount = 0, FileSize;
+	/* FIXME: Replace stuff located below with the stuff in segment */
+	UNFO_List UNFO;
+	DMUS_IO_SEGMENT_HEADER header;
+	DMUS_IO_VERSION version;
+	GUID guid;
+	
+	TRACE("reading 'RIFF' chunk...\n");
+	ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+	if (chunk.id == FOURCC_RIFF) {
+		TRACE("'RIFF': RIFF file\n");
+		ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read size of 'RIFF' chunk */
+		FileSize = chunk.size - sizeof(FOURCC); /* file content size = size of 'RIFF' chunk - FOURCC ID of following form */
+		TRACE("reading chunks ...\n");
+		ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read ID of following form */		
+		if (chunk.id == DMUS_FOURCC_SEGMENT_FORM) {
+			TRACE("DMSG: segment form\n");
+			do {
+				ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+				ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL);
+				FileCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
+				switch (chunk.id)
+				{
+					case DMUS_FOURCC_SEGMENT_CHUNK: {
+						TRACE("segh: segment header\n");
+						ReadFile (fd, &header, chunk.size, &BytesRead, NULL);
+						TRACE_(dmfiledat)("dwRepeats = %ld; mtLength = %li; mtPlayStart = %li; mtLoopStart = %li; mtLoopEnd = %li; dwResolution = %ld; rtLenght = FIXME; dwFlags = %ld; dwReserved = %ld\n", \
+							header.dwRepeats, header.mtLength, header.mtPlayStart, header.mtLoopStart, header.mtLoopEnd, header.dwResolution/*, header.rtLenght*/, header.dwFlags, header.dwReserved);
+						break;
+					} case DMUS_FOURCC_GUID_CHUNK: {
+						TRACE("'guid': GUID\n");
+						ReadFile (fd, &guid, chunk.size, &BytesRead, NULL);
+						TRACE_(dmfiledat)("=> GUID = %s\n", debugstr_guid(&guid));
+						break;
+					} case DMUS_FOURCC_VERSION_CHUNK: {
+						TRACE("'vers': version\n");
+						ReadFile (fd, &version, chunk.size, &BytesRead, NULL);
+						TRACE_(dmfiledat)("=> version = %ld%ld\n", version.dwVersionMS, version.dwVersionLS);
+						break;
+					} case FOURCC_LIST:{
+						TRACE("'LIST': list (size) = %ld\n", chunk.size);
+						ListSize = chunk.size - sizeof(FOURCC); /* list content size = size of 'LIST' chunk - FOURCC ID of the list */
+						ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL);
+						switch (chunk.id)
+						{
+							case DMUS_FOURCC_UNFO_LIST: {
+								TRACE("'UNFO': UNFO list (forward to DMUSIC_FillUNFOFromFileHandle(...))\n");
+								SetFilePointer (fd, -(sizeof(DWORD) + 2*sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'LIST' chunk */
+								DMUSIC_FillUNFOFromFileHandle (UNFO, fd);								
+								break;								
+							} case DMUS_FOURCC_TRACK_LIST: {
+								TRACE("'trkl': track list chunk (forward)\n");
+								do {
+									ReadFile (fd, &chunk.id, sizeof(FOURCC), &BytesRead, NULL); /* read RIFF */
+									ReadFile (fd, &chunk.size, sizeof(DWORD), &BytesRead, NULL); /* read track size */
+									TRACE("track size = %ld\n", chunk.size);
+									ListCount += chunk.size + sizeof(DWORD) + sizeof(FOURCC);
+									SetFilePointer (fd, -(sizeof(DWORD) + sizeof(FOURCC)), NULL, FILE_CURRENT); /* place pointer before the 'RIFF' chunk */
+									DMUSIC_FillTrackFromFileHandle (NULL, fd); /* read encapsulated track as if it was in a track file */
+									TRACE("(Track) List Count = %ld < (Track) List Size = %ld\n", ListCount, ListSize);
+								} while (ListCount < ListSize);
+								break;
+							}
+						}
+						break;
+					} case DMUS_FOURCC_CONTAINER_FORM: {
+						FIXME("'DMCN': container form chunk: not supported yet\n");
+						break;
+					} case DMUS_FOURCC_TOOLGRAPH_FORM: {
+						FIXME("'DMTG': toolgraph chunk: not supported yet\n");
+						break;
+					} case DMUS_FOURCC_AUDIOPATH_FORM: {
+						FIXME("'DMAP': audiopath chunk: not supported yet\n");
+						break;
+					} default: {
+						FIXME("invalid chunk (only 'segh', 'guid', 'vers', 'LIST', 'DMCN', 'DMTG' and 'DMAP' chunks allowed)\n");
+						break;
+					}
+				}
+				TRACE("FileCount (%ld) < FileSize (%ld)\n", FileCount, FileSize);
+			} while (FileCount < FileSize);
+		}
+	} else {
+		WARN("'RIFF' not found: not a RIFF file\n");
+	}
+	
+	return S_OK;
+}
diff -Nru Original/wine/dlls/dmusic/Makefile.in wine/dlls/dmusic/Makefile.in
--- Original/wine/dlls/dmusic/Makefile.in	2003-05-03 07:32:58.000000000 +0200
+++ wine/dlls/dmusic/Makefile.in	2003-06-22 14:37:04.000000000 +0200
@@ -20,7 +20,8 @@
 	dmusic_port.c \
 	dmusic_segment.c \
 	dmusic_style.c \
-	dmusic_synth.c
+	dmusic_synth.c \
+	helper.c
 
 RC_SRCS = version.rc
 

Attachment: signature.asc
Description: To je digitalno podpisan del=?iso-8859-2?Q?sporo=E8ila?=


[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux