Updated msvideo. New program 'icinfo [-about] [-configure]' to
query installed (win32) compressors. Started on AVIFILE support.

diff --git a/configure b/configure
index 13fc1dd..f91e9db 100755
--- a/configure
+++ b/configure
@@ -4156,6 +4156,7 @@
 programs/Makefile
 programs/clock/Makefile
 programs/control/Makefile
+programs/avitools/Makefile
 programs/notepad/Makefile
 programs/progman/Makefile
 programs/regtest/Makefile
@@ -4310,6 +4311,7 @@
 programs/Makefile
 programs/clock/Makefile
 programs/control/Makefile
+programs/avitools/Makefile
 programs/notepad/Makefile
 programs/progman/Makefile
 programs/regtest/Makefile
diff --git a/configure.in b/configure.in
index cd4ad40..f86104e 100644
--- a/configure.in
+++ b/configure.in
@@ -600,6 +600,7 @@
 programs/Makefile
 programs/clock/Makefile
 programs/control/Makefile
+programs/avitools/Makefile
 programs/notepad/Makefile
 programs/progman/Makefile
 programs/regtest/Makefile
diff --git a/include/debug.h b/include/debug.h
index 8d0ea7a..ae9450b 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -89,70 +89,71 @@
 #define dbch_mpr 81
 #define dbch_msacm 82
 #define dbch_msg 83
-#define dbch_nativefont 84
-#define dbch_nonclient 85
-#define dbch_ntdll 86
-#define dbch_ole 87
-#define dbch_pager 88
-#define dbch_palette 89
-#define dbch_pidl 90
-#define dbch_print 91
-#define dbch_process 92
-#define dbch_profile 93
-#define dbch_progress 94
-#define dbch_prop 95
-#define dbch_propsheet 96
-#define dbch_psapi 97
-#define dbch_psdrv 98
-#define dbch_ras 99
-#define dbch_rebar 100
-#define dbch_reg 101
-#define dbch_region 102
-#define dbch_relay 103
-#define dbch_resource 104
-#define dbch_scroll 105
-#define dbch_security 106
-#define dbch_segment 107
-#define dbch_selector 108
-#define dbch_sem 109
-#define dbch_sendmsg 110
-#define dbch_server 111
-#define dbch_shell 112
-#define dbch_shm 113
-#define dbch_snoop 114
-#define dbch_sound 115
-#define dbch_static 116
-#define dbch_statusbar 117
-#define dbch_stress 118
-#define dbch_string 119
-#define dbch_syscolor 120
-#define dbch_system 121
-#define dbch_tab 122
-#define dbch_task 123
-#define dbch_text 124
-#define dbch_thread 125
-#define dbch_thunk 126
-#define dbch_timer 127
-#define dbch_toolbar 128
-#define dbch_toolhelp 129
-#define dbch_tooltips 130
-#define dbch_trackbar 131
-#define dbch_treeview 132
-#define dbch_tweak 133
-#define dbch_uitools 134
-#define dbch_updown 135
-#define dbch_ver 136
-#define dbch_virtual 137
-#define dbch_vxd 138
-#define dbch_wave 139
-#define dbch_win 140
-#define dbch_win16drv 141
-#define dbch_win32 142
-#define dbch_wing 143
-#define dbch_winsock 144
-#define dbch_wnet 145
-#define dbch_x11 146
-#define dbch_x11drv 147
+#define dbch_msvideo 84
+#define dbch_nativefont 85
+#define dbch_nonclient 86
+#define dbch_ntdll 87
+#define dbch_ole 88
+#define dbch_pager 89
+#define dbch_palette 90
+#define dbch_pidl 91
+#define dbch_print 92
+#define dbch_process 93
+#define dbch_profile 94
+#define dbch_progress 95
+#define dbch_prop 96
+#define dbch_propsheet 97
+#define dbch_psapi 98
+#define dbch_psdrv 99
+#define dbch_ras 100
+#define dbch_rebar 101
+#define dbch_reg 102
+#define dbch_region 103
+#define dbch_relay 104
+#define dbch_resource 105
+#define dbch_scroll 106
+#define dbch_security 107
+#define dbch_segment 108
+#define dbch_selector 109
+#define dbch_sem 110
+#define dbch_sendmsg 111
+#define dbch_server 112
+#define dbch_shell 113
+#define dbch_shm 114
+#define dbch_snoop 115
+#define dbch_sound 116
+#define dbch_static 117
+#define dbch_statusbar 118
+#define dbch_stress 119
+#define dbch_string 120
+#define dbch_syscolor 121
+#define dbch_system 122
+#define dbch_tab 123
+#define dbch_task 124
+#define dbch_text 125
+#define dbch_thread 126
+#define dbch_thunk 127
+#define dbch_timer 128
+#define dbch_toolbar 129
+#define dbch_toolhelp 130
+#define dbch_tooltips 131
+#define dbch_trackbar 132
+#define dbch_treeview 133
+#define dbch_tweak 134
+#define dbch_uitools 135
+#define dbch_updown 136
+#define dbch_ver 137
+#define dbch_virtual 138
+#define dbch_vxd 139
+#define dbch_wave 140
+#define dbch_win 141
+#define dbch_win16drv 142
+#define dbch_win32 143
+#define dbch_wing 144
+#define dbch_winsock 145
+#define dbch_wnet 146
+#define dbch_x11 147
+#define dbch_x11drv 148
 /* Definitions for classes identifiers */
 #define dbcl_fixme 0
 #define dbcl_err 1
diff --git a/include/debugdefs.h b/include/debugdefs.h
index cd1a472..77f7c28 100644
--- a/include/debugdefs.h
+++ b/include/debugdefs.h
@@ -4,7 +4,7 @@
 #include "debugtools.h"
 #endif
 
-#define DEBUG_CHANNEL_COUNT 148
+#define DEBUG_CHANNEL_COUNT 149
 #ifdef DEBUG_RUNTIME
 short debug_msg_enabled[][DEBUG_CLASS_COUNT] = {
 {1, 1, 0, 0},
@@ -155,6 +155,7 @@
 {1, 1, 0, 0},
 {1, 1, 0, 0},
 {1, 1, 0, 0},
+{1, 1, 0, 0},
 };
 const char* debug_ch_name[] = {
 "accel",
@@ -241,6 +242,7 @@
 "mpr",
 "msacm",
 "msg",
+"msvideo",
 "nativefont",
 "nonclient",
 "ntdll",
diff --git a/include/oleauto.h b/include/oleauto.h
index 3055218..ec344ff 100644
--- a/include/oleauto.h
+++ b/include/oleauto.h
@@ -158,8 +158,6 @@
 #define VARIANT_TRUE	 ((VARIANT_BOOL)0xFFFF)
 #define VARIANT_FALSE	 ((VARIANT_BOOL)0x0000)
 
-typedef LONG SCODE;
-
 enum VARENUM {
 	VT_EMPTY = 0,
 	VT_NULL = 1,
diff --git a/include/vfw.h b/include/vfw.h
index 6aeeb1b..ae0a174 100644
--- a/include/vfw.h
+++ b/include/vfw.h
@@ -3,12 +3,19 @@
 
 #include <wintypes.h>
 #include <driver.h>
+#include <objbase.h>
 
 #define VFWAPI	WINAPI
 #define VFWAPIV	WINAPIV
 
 DWORD VFWAPI VideoForWindowsVersion(void);
 
+#ifndef mmioFOURCC
+#define mmioFOURCC( ch0, ch1, ch2, ch3 )				\
+	( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) |		\
+	( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
+#endif
+
 #ifndef aviTWOCC
 #define aviTWOCC(ch0, ch1) ((WORD)(BYTE)(ch0) | ((WORD)(BYTE)(ch1) << 8))
 #endif
@@ -16,7 +23,6 @@
 #define ICTYPE_VIDEO	mmioFOURCC('v', 'i', 'd', 'c')
 #define ICTYPE_AUDIO	mmioFOURCC('a', 'u', 'd', 'c')
 
-
 /* Installable Compressor M? */
 
 /* HIC32 struct (same layout as Win95 one) */
@@ -146,7 +152,87 @@
 				/* 24: */
 } ICOPEN,*LPICOPEN;
 
-/* Values for dwFlags of ICOpen() */
+#define ICCOMPRESS_KEYFRAME     0x00000001L
+
+typedef struct {
+    DWORD		dwFlags;
+    LPBITMAPINFOHEADER	lpbiOutput;
+    LPVOID		lpOutput;
+    LPBITMAPINFOHEADER	lpbiInput;
+    LPVOID		lpInput;
+    LPDWORD		lpckid;
+    LPDWORD		lpdwFlags;
+    LONG		lFrameNum;
+    DWORD		dwFrameSize;
+    DWORD		dwQuality;
+    LPBITMAPINFOHEADER	lpbiPrev;
+    LPVOID		lpPrev;
+} ICCOMPRESS;
+
+DWORD VFWAPIV ICCompress32(
+	HIC32 hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiOutput,LPVOID lpData,
+	LPBITMAPINFOHEADER lpbiInput,LPVOID lpBits,LPDWORD lpckid,
+	LPDWORD lpdwFlags,LONG lFrameNum,DWORD dwFrameSize,DWORD dwQuality,
+	LPBITMAPINFOHEADER lpbiPrev,LPVOID lpPrev
+);
+
+#define ICCompressGetFormat32(hic, lpbiInput, lpbiOutput) 		\
+	ICSendMessage32(						\
+	    hic,ICM_COMPRESS_GET_FORMAT,(DWORD)(LPVOID)(lpbiInput),	\
+	    (DWORD)(LPVOID)(lpbiOutput)					\
+	)
+#define ICCompressGetFormat WINELIB_NAME(ICCompressGetFormat)
+
+#define ICCompressGetFormatSize32(hic,lpbi) ICCompressGetFormat32(hic,lpbi,NULL)
+#define ICCompressGetFormatSize WINELIB_NAME(ICCompressGetFormatSize)
+
+#define ICCompressBegin32(hic, lpbiInput, lpbiOutput) 			\
+    ICSendMessage32(							\
+    	hic, ICM_COMPRESS_BEGIN, (DWORD)(LPVOID)(lpbiInput),		\
+	(DWORD)(LPVOID)(lpbiOutput)					\
+    )
+#define ICCompressBegin WINELIB_NAME(ICCompressBegin)
+
+#define ICCompressGetSize32(hic, lpbiInput, lpbiOutput) 		\
+    ICSendMessage32(							\
+    	hic, ICM_COMPRESS_GET_SIZE, (DWORD)(LPVOID)(lpbiInput), 	\
+	(DWORD)(LPVOID)(lpbiOutput)					\
+    )
+#define ICCompressGetSize WINELIB_NAME(ICCompressGetSize)
+
+#define ICCompressQuery32(hic, lpbiInput, lpbiOutput)		\
+    ICSendMessage32(						\
+    	hic, ICM_COMPRESS_QUERY, (DWORD)(LPVOID)(lpbiInput),	\
+	(DWORD)(LPVOID)(lpbiOutput)				\
+    )
+#define ICCompressQuery WINELIB_NAME(ICCompressQuery)
+
+
+#define ICCompressEnd32(hic) ICSendMessage32(hic, ICM_COMPRESS_END, 0, 0)
+#define ICCompressEnd WINELIB_NAME(ICCompressEnd)
+
+/* ICCOMPRESSFRAMES.dwFlags */
+#define ICCOMPRESSFRAMES_PADDING        0x00000001
+typedef struct {
+    DWORD               dwFlags;
+    LPBITMAPINFOHEADER  lpbiOutput;
+    LPARAM              lOutput;
+    LPBITMAPINFOHEADER  lpbiInput;
+    LPARAM              lInput;
+    LONG                lStartFrame;
+    LONG                lFrameCount;
+    LONG                lQuality;
+    LONG                lDataRate;
+    LONG                lKeyRate;
+    DWORD               dwRate;
+    DWORD               dwScale;
+    DWORD               dwOverheadPerFrame;
+    DWORD               dwReserved2;
+    LONG (CALLBACK *GetData)(LPARAM lInput,LONG lFrame,LPVOID lpBits,LONG len);
+    LONG (CALLBACK *PutData)(LPARAM lOutput,LONG lFrame,LPVOID lpBits,LONG len);
+} ICCOMPRESSFRAMES;
+
+/* Values for wMode of ICOpen() */
 #define	ICMODE_COMPRESS		1
 #define	ICMODE_DECOMPRESS	2
 #define	ICMODE_FASTDECOMPRESS	3
@@ -174,9 +260,9 @@
 	WCHAR	szDriver[128];		/* 138:driver that contains compressor*/
 					/* 238: */
 } ICINFO32;
+DECL_WINELIB_TYPE(ICINFO);
 
-
-/* Flags for the <dwFlags> field of the <ICINFO> structure. */
+/* ICINFO.dwFlags */
 #define	VIDCF_QUALITY		0x0001  /* supports quality */
 #define	VIDCF_CRUNCH		0x0002  /* supports crunching to a frame size */
 #define	VIDCF_TEMPORAL		0x0004  /* supports inter-frame compress */
@@ -193,19 +279,22 @@
 /* ICM_ABOUT */
 #define ICMF_ABOUT_QUERY         0x00000001
 
-#define ICQueryAbout(hic) \
-	(ICSendMessage(hic,ICM_ABOUT,(DWORD)-1,ICMF_ABOUT_QUERY)==ICERR_OK)
+#define ICQueryAbout32(hic) \
+	(ICSendMessage32(hic,ICM_ABOUT,(DWORD)-1,ICMF_ABOUT_QUERY)==ICERR_OK)
+#define ICQueryAbout WINELIB_NAME(ICQueryAbout)
 
-#define ICAbout(hic, hwnd) \
-	ICSendMessage(hic,ICM_ABOUT,(DWORD)(UINT)(hwnd),0)
+#define ICAbout32(hic, hwnd) ICSendMessage32(hic,ICM_ABOUT,(DWORD)(UINT)(hwnd),0)
+#define ICAbout WINELIB_NAME(ICAbout)
 
 /* ICM_CONFIGURE */
 #define ICMF_CONFIGURE_QUERY	0x00000001
-#define ICQueryConfigure(hic) \
-	(ICSendMessage(hic,ICM_CONFIGURE,(DWORD)-1,ICMF_CONFIGURE_QUERY)==ICERR_OK)
+#define ICQueryConfigure32(hic) \
+	(ICSendMessage32(hic,ICM_CONFIGURE,(DWORD)-1,ICMF_CONFIGURE_QUERY)==ICERR_OK)
+#define ICQueryConfigure WINELIB_NAME(ICQueryConfigure)
 
-#define ICConfigure(hic,hwnd) \
-	ICSendMessage(hic,ICM_CONFIGURE,(DWORD)(UINT)(hwnd),0)
+#define ICConfigure32(hic,hwnd) \
+	ICSendMessage32(hic,ICM_CONFIGURE,(DWORD)(UINT)(hwnd),0)
+#define ICConfigure WINELIB_NAME(ICConfigure)
 
 /* Decompression stuff */
 #define ICDECOMPRESS_HURRYUP		0x80000000	/* don't draw just buffer (hurry up!) */
@@ -242,15 +331,67 @@
     INT32		dySrc;
 } ICDECOMPRESSEX;
 
+DWORD VFWAPIV ICDecompress32(HIC32 hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat,LPVOID lpData,LPBITMAPINFOHEADER lpbi,LPVOID lpBits);
+#define ICDecompress WINELIB_NAME(ICDecompress)
+
+
+#define ICDecompressBegin32(hic, lpbiInput, lpbiOutput) 	\
+    ICSendMessage32(						\
+    	hic, ICM_DECOMPRESS_BEGIN, (DWORD)(LPVOID)(lpbiInput),	\
+	(DWORD)(LPVOID)(lpbiOutput)				\
+    )
+#define ICDecompressBegin WINELIB_NAME(ICDecompressBegin)
+
+#define ICDecompressQuery32(hic, lpbiInput, lpbiOutput) 	\
+    ICSendMessage32(						\
+    	hic,ICM_DECOMPRESS_QUERY, (DWORD)(LPVOID)(lpbiInput),	\
+	(DWORD) (LPVOID)(lpbiOutput)				\
+    )
+#define ICDecompressQuery WINELIB_NAME(ICDecompressQuery)
+
+#define ICDecompressGetFormat32(hic, lpbiInput, lpbiOutput)		\
+    ((LONG)ICSendMessage32(						\
+    	hic,ICM_DECOMPRESS_GET_FORMAT, (DWORD)(LPVOID)(lpbiInput),	\
+	(DWORD)(LPVOID)(lpbiOutput)					\
+    ))
+#define ICDecompressGetFormat WINELIB_NAME(ICDecompressGetFormat)
+
+#define ICDecompressGetFormatSize32(hic, lpbi) 				\
+	ICDecompressGetFormat32(hic, lpbi, NULL)
+#define ICDecompressGetFormatSize WINELIB_NAME(ICDecompressGetFormatSize)
+
+#define ICDecompressGetPalette32(hic, lpbiInput, lpbiOutput)		\
+    ICSendMessage32(							\
+    	hic, ICM_DECOMPRESS_GET_PALETTE, (DWORD)(LPVOID)(lpbiInput), 	\
+	(DWORD)(LPVOID)(lpbiOutput)					\
+    )
+#define ICDecompressGetPalette WINELIB_NAME(ICDecompressGetPalette)
+
+#define ICDecompressSetPalette32(hic,lpbiPalette)	\
+        ICSendMessage32(				\
+		hic,ICM_DECOMPRESS_SET_PALETTE,		\
+		(DWORD)(LPVOID)(lpbiPalette),0		\
+	)
+#define ICDecompressSetPalette WINELIB_NAME(ICDecompressSetPalette)
+
+#define ICDecompressEnd32(hic) ICSendMessage32(hic, ICM_DECOMPRESS_END, 0, 0)
+#define ICDecompressEnd WINELIB_NAME(ICDecompressEnd)
+
+
 #define ICDRAW_QUERY        0x00000001L   /* test for support */
 #define ICDRAW_FULLSCREEN   0x00000002L   /* draw to full screen */
 #define ICDRAW_HDC          0x00000004L   /* draw to a HDC/HWND */
 
-
 BOOL32	VFWAPI	ICInfo32(DWORD fccType, DWORD fccHandler, ICINFO32 * lpicinfo);
+#define ICInfo WINELIB_NAME(ICInfo)
 LRESULT	VFWAPI	ICGetInfo32(HIC32 hic,ICINFO32 *picinfo, DWORD cb);
+#define ICGetInfo WINELIB_NAME(ICGetInfo)
 HIC32	VFWAPI	ICOpen32(DWORD fccType, DWORD fccHandler, UINT32 wMode);
+#define ICOpen WINELIB_NAME(ICOpen)
+LRESULT VFWAPI ICClose32(HIC32 hic);
+#define ICClose WINELIB_NAME(ICClose)
 LRESULT	VFWAPI	ICSendMessage32(HIC32 hic, UINT32 msg, DWORD dw1, DWORD dw2);
+#define ICSendMessage WINELIB_NAME(ICSendMessage)
 DWORD	VFWAPIV	ICDrawBegin32(
         HIC32			hic,
         DWORD			dwFlags,/* flags */
@@ -267,6 +408,271 @@
         INT32			dxSrc,
         INT32			dySrc,
         DWORD			dwRate,	/* frames/second = (dwRate/dwScale) */
-        DWORD			dwScale);
+        DWORD			dwScale
+);
+#define ICDrawBegin WINELIB_NAME(ICDrawBegin)
+
+/********************* AVIFILE function declarations *************************/
+
+/* AVIFileHdr.dwFlags */
+#define AVIF_HASINDEX		0x00000010	/* Index at end of file? */
+#define AVIF_MUSTUSEINDEX	0x00000020
+#define AVIF_ISINTERLEAVED	0x00000100
+#define AVIF_TRUSTCKTYPE	0x00000800	/* Use CKType to find key frames*/
+#define AVIF_WASCAPTUREFILE	0x00010000
+#define AVIF_COPYRIGHTED	0x00020000
+
+#define AVI_HEADERSIZE	2048
+
+/* AVIStreamHeader.dwFlags */
+#define AVISF_DISABLED                  0x00000001
+#define AVISF_VIDEO_PALCHANGES          0x00010000
+
+typedef struct {
+    FOURCC	fccType;
+    FOURCC	fccHandler;
+    DWORD	dwFlags;        /* AVISF_* */
+    WORD	wPriority;
+    WORD	wLanguage;
+    DWORD	dwInitialFrames;
+    DWORD	dwScale;        
+    DWORD	dwRate; /* dwRate / dwScale == samples/second */
+    DWORD	dwStart;
+    DWORD	dwLength; /* In units above... */
+    DWORD	dwSuggestedBufferSize;
+    DWORD	dwQuality;
+    DWORD	dwSampleSize;
+    RECT32	rcFrame;
+} AVIStreamHeader;
+
+/* AVIINDEXENTRY.dwFlags */
+#define AVIIF_LIST	0x00000001	/* chunk is a 'LIST' */
+#define AVIIF_KEYFRAME	0x00000010	/* this frame is a key frame. */
+
+#define AVIIF_NOTIME	0x00000100	/* this frame doesn't take any time */
+#define AVIIF_COMPUSE	0x0FFF0000
+
+typedef struct _AVIINDEXENTRY {
+    DWORD	ckid;
+    DWORD	dwFlags;
+    DWORD	dwChunkOffset;
+    DWORD	dwChunkLength;
+} AVIINDEXENTRY;
+
+typedef struct _AVIPALCHANGE {
+    BYTE		bFirstEntry;
+    BYTE		bNumEntries;
+    WORD		wFlags;		/* pad */
+    PALETTEENTRY	peNew[1];
+} AVIPALCHANGE;
+
+#define AVIIF_KEYFRAME	0x00000010	/* this frame is a key frame. */
+
+#define	AVIGETFRAMEF_BESTDISPLAYFMT	1
+
+typedef struct _AVISTREAMINFO32A {
+    DWORD	fccType;
+    DWORD	fccHandler;
+    DWORD	dwFlags;        /* AVIIF_* */
+    DWORD	dwCaps;
+    WORD	wPriority;
+    WORD	wLanguage;
+    DWORD	dwScale;
+    DWORD	dwRate;		/* dwRate / dwScale == samples/second */
+    DWORD	dwStart;
+    DWORD	dwLength;	/* In units above... */
+    DWORD	dwInitialFrames;
+    DWORD	dwSuggestedBufferSize;
+    DWORD	dwQuality;
+    DWORD	dwSampleSize;
+    RECT32	rcFrame;
+    DWORD	dwEditCount;
+    DWORD	dwFormatChangeCount;
+    CHAR	szName[64];
+} AVISTREAMINFO32A, * LPAVISTREAMINFO32A, *PAVISTREAMINFO32A;
+
+typedef struct _AVISTREAMINFO32W {
+    DWORD	fccType;
+    DWORD	fccHandler;
+    DWORD	dwFlags;
+    DWORD	dwCaps;
+    WORD	wPriority;
+    WORD	wLanguage;
+    DWORD	dwScale;
+    DWORD	dwRate;		/* dwRate / dwScale == samples/second */
+    DWORD	dwStart;
+    DWORD	dwLength;	/* In units above... */
+    DWORD	dwInitialFrames;
+    DWORD	dwSuggestedBufferSize;
+    DWORD	dwQuality;
+    DWORD	dwSampleSize;
+    RECT32	rcFrame;
+    DWORD	dwEditCount;
+    DWORD	dwFormatChangeCount;
+    WCHAR	szName[64];
+} AVISTREAMINFO32W, * LPAVISTREAMINFO32W, *PAVISTREAMINFO32W;
+DECL_WINELIB_TYPE_AW(AVISTREAMINFO);
+DECL_WINELIB_TYPE_AW(LPAVISTREAMINFO);
+DECL_WINELIB_TYPE_AW(PAVISTREAMINFO);
+
+#define AVISTREAMINFO_DISABLED		0x00000001
+#define AVISTREAMINFO_FORMATCHANGES	0x00010000
+
+/* AVIFILEINFO.dwFlags */
+#define AVIFILEINFO_HASINDEX		0x00000010
+#define AVIFILEINFO_MUSTUSEINDEX	0x00000020
+#define AVIFILEINFO_ISINTERLEAVED	0x00000100
+#define AVIFILEINFO_WASCAPTUREFILE	0x00010000
+#define AVIFILEINFO_COPYRIGHTED		0x00020000
+
+/* AVIFILEINFO.dwCaps */
+#define AVIFILECAPS_CANREAD		0x00000001
+#define AVIFILECAPS_CANWRITE		0x00000002
+#define AVIFILECAPS_ALLKEYFRAMES	0x00000010
+#define AVIFILECAPS_NOCOMPRESSION	0x00000020
+
+typedef struct _AVIFILEINFO32W {
+    DWORD               dwMaxBytesPerSec;
+    DWORD               dwFlags;
+    DWORD               dwCaps;
+    DWORD               dwStreams;
+    DWORD               dwSuggestedBufferSize;
+    DWORD               dwWidth;
+    DWORD               dwHeight;
+    DWORD               dwScale;        
+    DWORD               dwRate;
+    DWORD               dwLength;
+    DWORD               dwEditCount;
+    WCHAR               szFileType[64];
+} AVIFILEINFO32W, * LPAVIFILEINFO32W, *PAVIFILEINFO32W;
+typedef struct _AVIFILEINFO32A {
+    DWORD               dwMaxBytesPerSec;
+    DWORD               dwFlags;
+    DWORD               dwCaps;
+    DWORD               dwStreams;
+    DWORD               dwSuggestedBufferSize;
+    DWORD               dwWidth;
+    DWORD               dwHeight;
+    DWORD               dwScale;        
+    DWORD               dwRate;
+    DWORD               dwLength;
+    DWORD               dwEditCount;
+    CHAR               szFileType[64];
+} AVIFILEINFO32A, * LPAVIFILEINFO32A, *PAVIFILEINFO32A;
+DECL_WINELIB_TYPE_AW(AVIFILEINFO);
+DECL_WINELIB_TYPE_AW(PAVIFILEINFO);
+DECL_WINELIB_TYPE_AW(LPAVIFILEINFO);
+
+/* AVICOMPRESSOPTIONS.dwFlags. determines presence of fields in below struct */
+#define AVICOMPRESSF_INTERLEAVE	0x00000001
+#define AVICOMPRESSF_DATARATE	0x00000002
+#define AVICOMPRESSF_KEYFRAMES	0x00000004
+#define AVICOMPRESSF_VALID	0x00000008
+
+typedef struct {
+    DWORD	fccType;		/* stream type, for consistency */
+    DWORD	fccHandler;		/* compressor */
+    DWORD	dwKeyFrameEvery;	/* keyframe rate */
+    DWORD	dwQuality;		/* compress quality 0-10,000 */
+    DWORD	dwBytesPerSecond;	/* bytes per second */
+    DWORD	dwFlags;		/* flags... see below */
+    LPVOID	lpFormat;		/* save format */
+    DWORD	cbFormat;
+    LPVOID	lpParms;		/* compressor options */
+    DWORD	cbParms;
+    DWORD	dwInterleaveEvery;	/* for non-video streams only */
+} AVICOMPRESSOPTIONS, *LPAVICOMPRESSOPTIONS,*PAVICOMPRESSOPTIONS;
+
+
+
+#define DEFINE_AVIGUID(name, l, w1, w2) \
+    DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46)
+
+DEFINE_AVIGUID(IID_IAVIFile,            0x00020020, 0, 0);
+DEFINE_AVIGUID(IID_IAVIStream,          0x00020021, 0, 0);
+DEFINE_AVIGUID(IID_IAVIStreaming,       0x00020022, 0, 0);
+DEFINE_AVIGUID(IID_IGetFrame,           0x00020023, 0, 0);
+DEFINE_AVIGUID(IID_IAVIEditStream,      0x00020024, 0, 0);
+
+DEFINE_AVIGUID(CLSID_AVIFile,           0x00020000, 0, 0);
+
+
+/* IAVIStream32 interface. */
+#define ICOM_INTERFACE IAVIStream32
+typedef struct IAVIStream32 IAVIStream32,*PAVISTREAM32;
+ICOM_BEGIN(IAVIStream32, IUnknown)
+    ICOM_METHOD2(HRESULT,Create,LPARAM,,LPARAM,);
+    ICOM_METHOD2(HRESULT,Info,AVISTREAMINFO32W*,,LONG,);
+    ICOM_METHOD2(LONG,FindSample,LONG,,LONG,);
+    ICOM_METHOD3(HRESULT,ReadFormat,LONG,,LPVOID,,LONG*,);
+    ICOM_METHOD3(HRESULT,SetFormat,LONG,,LPVOID,,LONG,);
+    ICOM_METHOD6(HRESULT,Read,LONG,,LONG,,LPVOID,,LONG,,LONG*,,LONG*,);
+    ICOM_METHOD7(HRESULT,Write,LONG,,LONG,,LPVOID,,LONG,,DWORD,,LONG*,,LONG*,);
+    ICOM_METHOD2(HRESULT,Delete,LONG,,LONG,);
+    ICOM_METHOD3(HRESULT,ReadData,DWORD,,LPVOID,,LONG*,);
+    ICOM_METHOD3(HRESULT,WriteData,DWORD,,LPVOID,,LONG,);
+    ICOM_METHOD2(HRESULT,SetInfo,AVISTREAMINFO32W*,,LONG,);
+ICOM_END(IAVIStream32)
+#undef ICOM_INTERFACE
+
+/* IAVIFile32 interface. In Win32 this interface uses UNICODE only */
+#define ICOM_INTERFACE IAVIFile32
+typedef struct IAVIFile32 IAVIFile32,*PAVIFILE32;
+ICOM_BEGIN(IAVIFile32,IUnknown)
+	ICOM_METHOD2(HRESULT,Info,AVIFILEINFO32W*,,LONG,);
+	ICOM_METHOD3(HRESULT,GetStream,PAVISTREAM32*,,DWORD,,LONG,);
+	ICOM_METHOD2(HRESULT,CreateStream,PAVISTREAM32*,,AVISTREAMINFO32W*,);
+	ICOM_METHOD3(HRESULT,WriteData,DWORD,,LPVOID,,LONG,);
+	ICOM_METHOD3(HRESULT,ReadData,DWORD,,LPVOID,,LONG*,);
+	ICOM_METHOD (HRESULT,EndRecord);
+	ICOM_METHOD2(HRESULT,DeleteStream,DWORD,,LONG,);
+ICOM_END(IAVIFile32)
+#undef ICOM_INTERFACE
+
+#define AVIERR_OK		0
+#define MAKE_AVIERR(error)	MAKE_SCODE(SEVERITY_ERROR,FACILITY_ITF,0x4000+error)
+
+#define AVIERR_UNSUPPORTED	MAKE_AVIERR(101)
+#define AVIERR_BADFORMAT	MAKE_AVIERR(102)
+#define AVIERR_MEMORY		MAKE_AVIERR(103)
+#define AVIERR_INTERNAL		MAKE_AVIERR(104)
+#define AVIERR_BADFLAGS		MAKE_AVIERR(105)
+#define AVIERR_BADPARAM		MAKE_AVIERR(106)
+#define AVIERR_BADSIZE		MAKE_AVIERR(107)
+#define AVIERR_BADHANDLE	MAKE_AVIERR(108)
+#define AVIERR_FILEREAD		MAKE_AVIERR(109)
+#define AVIERR_FILEWRITE	MAKE_AVIERR(110)
+#define AVIERR_FILEOPEN		MAKE_AVIERR(111)
+#define AVIERR_COMPRESSOR	MAKE_AVIERR(112)
+#define AVIERR_NOCOMPRESSOR	MAKE_AVIERR(113)
+#define AVIERR_READONLY		MAKE_AVIERR(114)
+#define AVIERR_NODATA		MAKE_AVIERR(115)
+#define AVIERR_BUFFERTOOSMALL	MAKE_AVIERR(116)
+#define AVIERR_CANTCOMPRESS	MAKE_AVIERR(117)
+#define AVIERR_USERABORT	MAKE_AVIERR(198)
+#define AVIERR_ERROR		MAKE_AVIERR(199)
+
+void WINAPI AVIFileInit32(void);
+#define AVIFileInit WINELIB_NAME(AVIFileInit)
+
+HRESULT WINAPI AVIFileOpen32A(PAVIFILE32 * ppfile,LPCSTR szFile,UINT32 uMode,LPCLSID lpHandler);
+#define AVIFileOpen WINELIB_NAME_AW(AVIFileOpen)
+
+HRESULT WINAPI AVIFileCreateStream32A(PAVIFILE32 pfile,PAVISTREAM32 *ppavi,AVISTREAMINFO32A * psi);
+HRESULT WINAPI AVIFileCreateStream32W(PAVIFILE32 pfile,PAVISTREAM32 *ppavi,AVISTREAMINFO32W * psi);
+#define AVIFileCreateStream WINELIB_NAME_AW(AVIFileCreateStream)
+HRESULT WINAPI AVIMakeCompressedStream32(PAVISTREAM32*ppsCompressed,PAVISTREAM32 ppsSource,AVICOMPRESSOPTIONS *lpOptions,CLSID*pclsidHandler); 
+#define AVIMakeCompressedStream WINELIB_NAME_AW(AVIMakeCompressedStream)
+HRESULT WINAPI AVIStreamSetFormat32(PAVISTREAM32 iface,LONG pos,LPVOID format,LONG formatsize);
+#define AVIStreamSetFormat WINELIB_NAME(AVIStreamSetFormat)
+HRESULT WINAPI AVIStreamWrite32(PAVISTREAM32 iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten);
+#define AVIStreamWrite WINELIB_NAME(AVIStreamWrite)
+ULONG WINAPI AVIStreamRelease32(PAVISTREAM32 iface);
+#define AVIStreamRelease WINELIB_NAME(AVIStreamRelease)
+ULONG WINAPI AVIFileRelease32(PAVIFILE32 iface);
+#define AVIFileRelease WINELIB_NAME(AVIFileRelease)
+void WINAPI AVIFileExit32(void);
+#define AVIFileExit WINELIB_NAME(AVIFileExit)
+
 
 #endif
diff --git a/include/winerror.h b/include/winerror.h
index ea61294..f3367b3 100644
--- a/include/winerror.h
+++ b/include/winerror.h
@@ -4,6 +4,7 @@
 
 extern int WIN32_LastError;
 
+#define FACILITY_ITF		4
 #define FACILITY_WIN32		7
 
 #define SEVERITY_ERROR		1
diff --git a/include/wintypes.h b/include/wintypes.h
index e456dad..fc981dd 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -89,6 +89,7 @@
 typedef unsigned short  BOOL16;
 typedef int             BOOL32;
 typedef double          DATE;
+typedef long		SCODE;
 typedef long            LONG_PTR;
 typedef unsigned long   ULONG_PTR;
 #ifdef __i386__
@@ -301,6 +302,7 @@
 DECL_WINELIB_TYPE(HFONT)
 DECL_WINELIB_TYPE(HGDIOBJ)
 DECL_WINELIB_TYPE(HGLOBAL)
+DECL_WINELIB_TYPE(HIC)
 DECL_WINELIB_TYPE(HICON)
 DECL_WINELIB_TYPE(HINSTANCE)
 DECL_WINELIB_TYPE(HLOCAL)
diff --git a/multimedia/msvideo.c b/multimedia/msvideo.c
index 177803d..38aea13 100644
--- a/multimedia/msvideo.c
+++ b/multimedia/msvideo.c
@@ -2,6 +2,7 @@
  * Copyright 1998 Marcus Meissner
  */
 #include <stdio.h>
+#include <strings.h>
 
 #include "windows.h"
 #include "driver.h"
@@ -36,7 +37,7 @@
 	char	type[5],buf[2000];
 
 	memcpy(type,&fccType,4);type[4]=0;
-	TRACE(mmsys,"(%s,%ld,%p).\n",type,fccHandler,lpicinfo);
+	TRACE(msvideo,"(%s,%ld,%p).\n",type,fccHandler,lpicinfo);
 	/* does OpenDriver/CloseDriver */
 	lpicinfo->dwSize = sizeof(ICINFO32);
 	lpicinfo->fccType = fccType;
@@ -69,8 +70,13 @@
 
 	memcpy(type,&fccType,4);type[4]=0;
 	memcpy(handler,&fccHandler,4);handler[4]=0;
-	TRACE(mmsys,"(%s,%s,0x%08lx)\n",type,handler,(DWORD)wMode);
-	sprintf(codecname,"%s.%s",type,handler);
+	TRACE(msvideo,"(%s,%s,0x%08lx)\n",type,handler,(DWORD)wMode);
+	/* FIXME: When do we use 'vids' , when 'vidc'? Unclear */
+	if (!strcasecmp(type,"vids")) {
+	    sprintf(codecname,"vidc.%s",handler);
+	    fccType = mmioFOURCC('v','i','d','c');
+	} else
+	    sprintf(codecname,"%s.%s",type,handler);
 	hdrv=OpenDriver32A(codecname,"drivers32",0);
 	if (!hdrv)
 		return 0;
@@ -83,7 +89,8 @@
 	icopen.fccType		= fccType;
 	icopen.fccHandler	= fccHandler;
 	icopen.dwSize		= sizeof(ICOPEN);
-	/* FIXME: fill out rest too... */
+	icopen.dwFlags		= wMode;
+	/* FIXME: do we need to fill out the rest too? */
 	whic->private	= whic->driverproc(0,hdrv,DRV_OPEN,0,&icopen);
 	return (HIC32)whic;
 }
@@ -91,20 +98,60 @@
 LRESULT WINAPI
 ICGetInfo32(HIC32 hic,ICINFO32 *picinfo,DWORD cb) {
 	LRESULT		ret;
-	WINE_HIC	*whic = (WINE_HIC*)hic;
 
-	TRACE(mmsys,"(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
-	ret = ICSendMessage32(whic,ICM_GETINFO,(DWORD)picinfo,cb);
-	TRACE(mmsys,"	-> 0x%08lx\n",ret);
+	TRACE(msvideo,"(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
+	ret = ICSendMessage32(hic,ICM_GETINFO,(DWORD)picinfo,cb);
+	TRACE(msvideo,"	-> 0x%08lx\n",ret);
 	return ret;
 }
 
+DWORD VFWAPIV
+ICCompress32(
+	HIC32 hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiOutput,LPVOID lpData,
+	LPBITMAPINFOHEADER lpbiInput,LPVOID lpBits,LPDWORD lpckid,
+	LPDWORD lpdwFlags,LONG lFrameNum,DWORD dwFrameSize,DWORD dwQuality,
+	LPBITMAPINFOHEADER lpbiPrev,LPVOID lpPrev
+) {
+	ICCOMPRESS	iccmp;
+
+	iccmp.dwFlags		= dwFlags;
+
+	iccmp.lpbiOutput	= lpbiOutput;
+	iccmp.lpOutput		= lpData;
+	iccmp.lpbiInput		= lpbiInput;
+	iccmp.lpInput		= lpBits;
+
+	iccmp.lpckid		= lpckid;
+	iccmp.lpdwFlags		= lpdwFlags;
+	iccmp.lFrameNum		= lFrameNum;
+	iccmp.dwFrameSize	= dwFrameSize;
+	iccmp.dwQuality		= dwQuality;
+	iccmp.lpbiPrev		= lpbiPrev;
+	iccmp.lpPrev		= lpPrev;
+	return ICSendMessage32(hic,ICM_COMPRESS,(LPARAM)&iccmp,sizeof(iccmp));
+}
+
+DWORD VFWAPIV 
+ICDecompress32(HIC32 hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat,LPVOID lpData,LPBITMAPINFOHEADER  lpbi,LPVOID lpBits) {
+	ICDECOMPRESS	icd;
+
+	icd.dwFlags	= dwFlags;
+	icd.lpbiInput	= lpbiFormat;
+	icd.lpInput	= lpData;
+
+	icd.lpbiOutput	= lpbi;
+	icd.lpOutput	= lpBits;
+	/* 
+	icd.ckid	= ??? ckid from AVI file? how do we get it? ;
+	 */
+	return ICSendMessage32(hic,ICM_DECOMPRESS,(LPARAM)&icd,sizeof(icd));
+}
 
 HIC32 WINAPI
 ICLocate(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
 	 LPBITMAPINFOHEADER lpbiOut, WORD wFlags
 ) {
-	FIXME(mmsys,"stub!\n");
+	FIXME(msvideo,"stub!\n");
 	return 0;
 }
 
@@ -113,19 +160,57 @@
 	LRESULT		ret;
 	WINE_HIC	*whic = (WINE_HIC*)hic;
 
+#define XX(x) case x: TRACE(msvideo,"(0x%08lx,"#x",0x%08lx,0x%08lx)\n",(DWORD)hic,lParam1,lParam2);break;
+
 	switch (msg) {
-	case ICM_GETINFO:
-		FIXME(mmsys,"(0x%08lx,ICM_GETINFO,0x%08lx,0x%08lx)\n",(DWORD)hic,lParam1,lParam2);
-		break;
+	XX(ICM_ABOUT)
+	XX(ICM_GETINFO)
+	XX(ICM_COMPRESS_FRAMES_INFO)
+	XX(ICM_COMPRESS_GET_FORMAT)
+	XX(ICM_COMPRESS_GET_SIZE)
+	XX(ICM_COMPRESS_QUERY)
+	XX(ICM_COMPRESS_BEGIN)
+	XX(ICM_COMPRESS)
+	XX(ICM_COMPRESS_END)
+	XX(ICM_DECOMPRESS_GET_FORMAT)
+	XX(ICM_DECOMPRESS_QUERY)
+	XX(ICM_DECOMPRESS_BEGIN)
+	XX(ICM_DECOMPRESS)
+	XX(ICM_DECOMPRESS_END)
+	XX(ICM_DECOMPRESS_SET_PALETTE)
+	XX(ICM_DECOMPRESS_GET_PALETTE)
+	XX(ICM_DRAW_QUERY)
+	XX(ICM_DRAW_BEGIN)
+	XX(ICM_DRAW_GET_PALETTE)
+	XX(ICM_DRAW_START)
+	XX(ICM_DRAW_STOP)
+	XX(ICM_DRAW_END)
+	XX(ICM_DRAW_GETTIME)
+	XX(ICM_DRAW)
+	XX(ICM_DRAW_WINDOW)
+	XX(ICM_DRAW_SETTIME)
+	XX(ICM_DRAW_REALIZE)
+	XX(ICM_DRAW_FLUSH)
+	XX(ICM_DRAW_RENDERBUFFER)
+	XX(ICM_DRAW_START_PLAY)
+	XX(ICM_DRAW_STOP_PLAY)
+	XX(ICM_DRAW_SUGGESTFORMAT)
+	XX(ICM_DRAW_CHANGEPALETTE)
+	XX(ICM_GETBUFFERSWANTED)
+	XX(ICM_GETDEFAULTKEYFRAMERATE)
+	XX(ICM_DECOMPRESSEX_BEGIN)
+	XX(ICM_DECOMPRESSEX_QUERY)
+	XX(ICM_DECOMPRESSEX)
+	XX(ICM_DECOMPRESSEX_END)
+	XX(ICM_SET_STATUS_PROC)
 	default:
-		FIXME(mmsys,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx)\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2);
+		FIXME(msvideo,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx)\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2);
 	}
 	ret = whic->driverproc(whic->private,whic->hdrv,msg,lParam1,lParam2);
-	FIXME(mmsys,"	-> 0x%08lx\n",ret);
+	TRACE(msvideo,"	-> 0x%08lx\n",ret);
 	return ret;
 }
 
-
 DWORD	VFWAPIV	ICDrawBegin32(
         HIC32			hic,
         DWORD			dwFlags,/* flags */
@@ -146,23 +231,28 @@
 		return 0;
 }
 
+LRESULT WINAPI ICClose32(HIC32 hic) {
+	FIXME(msvideo,"(%d),stub!\n",hic);
+	return 0;
+}
+
 HANDLE32 /* HDRAWDIB */ WINAPI
 DrawDibOpen32( void ) {
-	FIXME(mmsys,"stub!\n");
+	FIXME(msvideo,"stub!\n");
 	return 0;
 }
 HWND32 VFWAPIV MCIWndCreate32 (HWND32 hwndParent, HINSTANCE32 hInstance,
                       DWORD dwStyle,LPVOID szFile)
-{	FIXME(mmsys,"%x %x %lx %p\n",hwndParent, hInstance, dwStyle, szFile);
+{	FIXME(msvideo,"%x %x %lx %p\n",hwndParent, hInstance, dwStyle, szFile);
 	return 0;
 }
 HWND32 VFWAPIV MCIWndCreate32A(HWND32 hwndParent, HINSTANCE32 hInstance,
                       DWORD dwStyle,LPCSTR szFile)
-{	FIXME(mmsys,"%x %x %lx %s\n",hwndParent, hInstance, dwStyle, szFile);
+{	FIXME(msvideo,"%x %x %lx %s\n",hwndParent, hInstance, dwStyle, szFile);
 	return 0;
 }
 HWND32 VFWAPIV MCIWndCreate32W(HWND32 hwndParent, HINSTANCE32 hInstance,
                       DWORD dwStyle,LPCWSTR szFile)
-{	FIXME(mmsys,"%x %x %lx %s\n",hwndParent, hInstance, dwStyle, debugstr_w(szFile));
+{	FIXME(msvideo,"%x %x %lx %s\n",hwndParent, hInstance, dwStyle, debugstr_w(szFile));
 	return 0;
 }
diff --git a/ole/guid.c b/ole/guid.c
index 5de3c10..1477676 100644
--- a/ole/guid.c
+++ b/ole/guid.c
@@ -15,5 +15,6 @@
 #include "dinput.h"
 #include "dsound.h"
 #include "dplay.h"
+#include "vfw.h"
 
 #endif
diff --git a/programs/Makefile.in b/programs/Makefile.in
index 3d498e7..4e15ece 100644
--- a/programs/Makefile.in
+++ b/programs/Makefile.in
@@ -1,4 +1,5 @@
 SUBDIRS = \
+	avitools \
 	clock \
 	control \
 	notepad \
diff --git a/programs/avitools/.cvsignore b/programs/avitools/.cvsignore
new file mode 100644
index 0000000..365d3f2
--- /dev/null
+++ b/programs/avitools/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+icinfo
diff --git a/programs/avitools/Makefile.in b/programs/avitools/Makefile.in
new file mode 100644
index 0000000..f031d95
--- /dev/null
+++ b/programs/avitools/Makefile.in
@@ -0,0 +1,56 @@
+DEFS      = -DWINELIB
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = none
+PROGRAMS  = icinfo
+ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XLIB) $(LIBS)
+RCFLAGS   = -w32 -h
+WRCEXTRA  = -A -p $*
+
+LANGUAGES   =
+LICENSELANG =
+
+MOSTSRCS = \
+	icinfo.c
+
+# Some strings need addresses >= 0x10000
+STRINGSRCS = \
+	$(LICENSELANG:%=License_%.c)
+
+RC_SRCS = $(LANGUAGES:%=%.rc)
+
+C_SRCS = $(MOSTSRCS) $(STRINGSRCS)
+
+MOSTOBJS = $(MOSTSRCS:.c=.o)
+STRINGOBJS = $(STRINGSRCS:.c=.o) $(RC_SRCS:.rc=.o)
+
+all: check_wrc $(PROGRAMS)
+
+depend::
+
+@MAKE_RULES@
+
+# Override resource compiler rules
+.rc.s:
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -o $*.s
+
+.rc.h:
+	$(CPP) $(DEFS) $(OPTIONS) $(DIVINCL) -DRC_INVOKED -P -x c $< | $(WRC) $(WRCFLAGS) $(WRCEXTRA) -nH $*.h
+
+
+icinfo: $(MOSTOBJS) $(STRINGOBJS)
+	$(CC) -o icinfo $(MOSTOBJS) $(LDOPTIONS) $(ALL_LIBS) $(STRINGOBJS)
+
+install: dummy
+	$(INSTALL_PROGRAM) clock $(bindir)/clock
+
+uninstall: dummy
+	$(RM) $(bindir)/clock
+
+$(RC_SRCS:.rc=.s): $(WRC)
+
+dummy:
+
+### Dependencies:
diff --git a/programs/avitools/icinfo.c b/programs/avitools/icinfo.c
new file mode 100644
index 0000000..e3c1291
--- /dev/null
+++ b/programs/avitools/icinfo.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <strings.h>
+#include "wintypes.h"
+#include "windows.h"
+#include "mmsystem.h"
+#include "vfw.h"
+
+
+int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show)
+{
+    int n=0,doabout=0,doconfigure=0;
+    char	buf[128],type[5],handler[5];
+    HMODULE	msvfw32 = LoadLibrary("msvfw32.dll");
+
+BOOL32  (VFWAPI  *fnICInfo)(DWORD fccType, DWORD fccHandler, ICINFO * lpicinfo);
+LRESULT (VFWAPI *fnICClose)(HIC hic);
+HIC	(VFWAPI	*fnICOpen)(DWORD fccType, DWORD fccHandler, UINT wMode);
+LRESULT	(VFWAPI	*fnICGetInfo)(HIC hic,ICINFO *picinfo, DWORD cb);
+LRESULT	(VFWAPI	*fnICSendMessage)(HIC hic, UINT msg, DWORD dw1, DWORD dw2);
+
+#define XX(x) fn##x = (void*)GetProcAddress(msvfw32,#x);
+	XX(ICInfo);
+	XX(ICOpen);
+	XX(ICClose);
+	XX(ICGetInfo);
+	XX(ICSendMessage);
+#undef XX
+
+    if (strstr(cmdline,"-about"))
+    	doabout = 1;
+    if (strstr(cmdline,"-configure"))
+    	doconfigure = 1;
+
+    printf("Currently installed Video Compressors:\n");
+    while (1) {
+    	ICINFO	ii;
+	HIC	hic;
+
+	ii.dwSize = sizeof(ii);
+    	if (!fnICInfo(ICTYPE_VIDEO,n++,&ii))
+	    break;
+	if (!(hic=fnICOpen(ii.fccType,ii.fccHandler,ICMODE_QUERY)))
+	    continue;
+	if (!fnICGetInfo(hic,&ii,sizeof(ii))) {
+	    fnICClose(hic);
+	    continue;
+	}
+#define w2s(w,s) WideCharToMultiByte(0,0,w,-1,s,128,0,NULL)
+
+	w2s(ii.szName,buf);
+	memcpy(type,&(ii.fccType),4);type[4]='\0';
+	memcpy(handler,&(ii.fccHandler),4);handler[4]='\0';
+	printf("%s.%s: %s\n",type,handler,buf);
+	printf("\tdwFlags: 0x%08lx (",ii.dwFlags);
+#define XX(x) if (ii.dwFlags & x) printf(#x" ");
+	XX(VIDCF_QUALITY);
+	XX(VIDCF_CRUNCH);
+	XX(VIDCF_TEMPORAL);
+	XX(VIDCF_COMPRESSFRAMES);
+	XX(VIDCF_DRAW);
+	XX(VIDCF_FASTTEMPORALC);
+	XX(VIDCF_FASTTEMPORALD);
+	XX(VIDCF_QUALITYTIME);
+#undef XX
+	printf(")\n");
+	printf("\tdwVersion: 0x%08lx\n",ii.dwVersion);
+	printf("\tdwVersionICM: 0x%08lx\n",ii.dwVersionICM);
+	w2s(ii.szDescription,buf);
+	printf("\tszDescription: %s\n",buf);
+	if (doabout) ICAbout(hic,0);
+	if (doconfigure && ICQueryConfigure32(hic))
+		ICConfigure(hic,0);
+	fnICClose(hic);
+    }
+    return 0;    
+}
+
diff --git a/relay32/msvfw32.spec b/relay32/msvfw32.spec
index b289038..9fc550a 100644
--- a/relay32/msvfw32.spec
+++ b/relay32/msvfw32.spec
@@ -1,6 +1,9 @@
 name	msvfw32
 type	win32
 
+# Yes, ICCompress,ICDecompress,MCIWnd* and ICDraw* are cdecl (VFWAPIV).
+# The rest is stdcall (VFWAPI) however. -Marcus Meissner, 990124
+
   2 stdcall VideoForWindowsVersion() VideoForWindowsVersion
   3 stub    DrawDibBegin
   4 stub    DrawDibChangePalette
@@ -21,13 +24,13 @@
  19 stub    GetOpenFileNamePreviewW
  20 stub    GetSaveFileNamePreviewA
  21 stub    GetSaveFileNamePreviewW
- 22 stub    ICClose
- 23 stub    ICCompress
+ 22 stdcall ICClose(long) ICClose32
+ 23 cdecl   ICCompress(long long ptr ptr ptr ptr ptr ptr long long long ptr ptr) ICCompress32
  24 stub    ICCompressorChoose
  25 stub    ICCompressorFree
- 26 stub    ICDecompress
- 27 stub    ICDraw
- 28 stdcall ICDrawBegin(long long long long long long long long long ptr long long long long long long) ICDrawBegin32
+ 26 cdecl   ICDecompress(long long ptr ptr ptr ptr) ICDecompress32
+ 27 stub    ICDraw 	# CDECL too
+ 28 cdecl   ICDrawBegin(long long long long long long long long long ptr long long long long long long) ICDrawBegin32
  29 stub    ICGetDisplayFormat
  30 stdcall ICGetInfo(long ptr long) ICGetInfo32
  31 stub    ICImageCompress
@@ -43,9 +46,9 @@
  41 stub    ICSeqCompressFrame
  42 stub    ICSeqCompressFrameEnd
  43 stub    ICSeqCompressFrameStart
- 44 stdcall MCIWndCreate (long long long ptr) MCIWndCreate32
- 45 stdcall MCIWndCreateA (long long long str) MCIWndCreate32A
- 46 stdcall MCIWndCreateW (long long long wstr) MCIWndCreate32W
+ 44 cdecl   MCIWndCreate (long long long ptr) MCIWndCreate32
+ 45 cdecl   MCIWndCreateA (long long long str) MCIWndCreate32A
+ 46 cdecl   MCIWndCreateW (long long long wstr) MCIWndCreate32W
  47 stub    MCIWndRegisterClass
  48 stub    StretchDIB
  49 stub    ls_ThunkData32