Implemented an IMA driver.

diff --git a/configure b/configure
index 34400a7..184aa12 100755
--- a/configure
+++ b/configure
@@ -10360,7 +10360,7 @@
 
 MAKE_PROG_RULES=programs/Makeprog.rules
 
-ac_config_files="$ac_config_files Make.rules dlls/Makedll.rules programs/Makeprog.rules Makefile console/Makefile controls/Makefile debugger/Makefile dlls/Makefile dlls/advapi32/Makefile dlls/avicap32/Makefile dlls/avifil32/Makefile dlls/comctl32/Makefile dlls/commdlg/Makefile dlls/crtdll/Makefile dlls/crypt32/Makefile dlls/dciman32/Makefile dlls/ddraw/Makefile dlls/devenum/Makefile dlls/dinput/Makefile dlls/dplay/Makefile dlls/dplayx/Makefile dlls/dsound/Makefile dlls/gdi/Makefile dlls/glu32/Makefile dlls/icmp/Makefile dlls/imagehlp/Makefile dlls/imm32/Makefile dlls/kernel/Makefile dlls/lzexpand/Makefile dlls/mapi32/Makefile dlls/mpr/Makefile dlls/msacm/Makefile dlls/msacm/msg711/Makefile dlls/msdmo/Makefile dlls/msimg32/Makefile dlls/msnet32/Makefile dlls/msrle32/Makefile dlls/msvcrt/Makefile dlls/msvcrt20/Makefile dlls/msvideo/Makefile dlls/netapi32/Makefile dlls/ntdll/Makefile dlls/odbc32/Makefile dlls/ole32/Makefile dlls/oleaut32/Makefile dlls/olecli/Makefile dlls/oledlg/Makefile dlls/olepro32/Makefile dlls/olesvr/Makefile dlls/opengl32/Makefile dlls/psapi/Makefile dlls/qcap/Makefile dlls/quartz/Makefile dlls/rasapi32/Makefile dlls/richedit/Makefile dlls/rpcrt4/Makefile dlls/serialui/Makefile dlls/setupapi/Makefile dlls/shdocvw/Makefile dlls/shell32/Makefile dlls/shfolder/Makefile dlls/shlwapi/Makefile dlls/sti/Makefile dlls/tapi32/Makefile dlls/ttydrv/Makefile dlls/twain/Makefile dlls/url/Makefile dlls/urlmon/Makefile dlls/user/Makefile dlls/version/Makefile dlls/win32s/Makefile dlls/winaspi/Makefile dlls/winedos/Makefile dlls/wineps/Makefile dlls/wininet/Makefile dlls/winmm/Makefile dlls/winmm/joystick/Makefile dlls/winmm/mcianim/Makefile dlls/winmm/mciavi/Makefile dlls/winmm/mcicda/Makefile dlls/winmm/mciseq/Makefile dlls/winmm/mciwave/Makefile dlls/winmm/midimap/Makefile dlls/winmm/wavemap/Makefile dlls/winmm/winearts/Makefile dlls/winmm/wineoss/Makefile dlls/winnls/Makefile dlls/winsock/Makefile dlls/winspool/Makefile dlls/wintrust/Makefile dlls/wow32/Makefile dlls/wsock32/Makefile dlls/x11drv/Makefile documentation/Makefile files/Makefile graphics/Makefile graphics/enhmetafiledrv/Makefile graphics/metafiledrv/Makefile graphics/win16drv/Makefile graphics/x11drv/Makefile if1632/Makefile include/Makefile library/Makefile libtest/Makefile loader/Makefile loader/ne/Makefile memory/Makefile misc/Makefile miscemu/Makefile msdos/Makefile objects/Makefile ole/Makefile programs/Makefile programs/avitools/Makefile programs/clock/Makefile programs/cmdlgtst/Makefile programs/control/Makefile programs/notepad/Makefile programs/osversioncheck/Makefile programs/progman/Makefile programs/regapi/Makefile programs/regtest/Makefile programs/uninstaller/Makefile programs/view/Makefile programs/wcmd/Makefile programs/wineconsole/Makefile programs/winemine/Makefile programs/winetest/Makefile programs/winhelp/Makefile programs/winver/Makefile relay32/Makefile scheduler/Makefile server/Makefile tools/Makefile tools/winapi/Makefile tools/winebuild/Makefile tools/winedump/Makefile tools/wmc/Makefile tools/wrc/Makefile tsx11/Makefile unicode/Makefile win32/Makefile windows/Makefile windows/x11drv/Makefile"
+ac_config_files="$ac_config_files Make.rules dlls/Makedll.rules programs/Makeprog.rules Makefile console/Makefile controls/Makefile debugger/Makefile dlls/Makefile dlls/advapi32/Makefile dlls/avicap32/Makefile dlls/avifil32/Makefile dlls/comctl32/Makefile dlls/commdlg/Makefile dlls/crtdll/Makefile dlls/crypt32/Makefile dlls/dciman32/Makefile dlls/ddraw/Makefile dlls/devenum/Makefile dlls/dinput/Makefile dlls/dplay/Makefile dlls/dplayx/Makefile dlls/dsound/Makefile dlls/gdi/Makefile dlls/glu32/Makefile dlls/icmp/Makefile dlls/imagehlp/Makefile dlls/imm32/Makefile dlls/kernel/Makefile dlls/lzexpand/Makefile dlls/mapi32/Makefile dlls/mpr/Makefile dlls/msacm/Makefile dlls/msacm/imaadp32/Makefile dlls/msacm/msg711/Makefile dlls/msdmo/Makefile dlls/msimg32/Makefile dlls/msnet32/Makefile dlls/msrle32/Makefile dlls/msvcrt/Makefile dlls/msvcrt20/Makefile dlls/msvideo/Makefile dlls/netapi32/Makefile dlls/ntdll/Makefile dlls/odbc32/Makefile dlls/ole32/Makefile dlls/oleaut32/Makefile dlls/olecli/Makefile dlls/oledlg/Makefile dlls/olepro32/Makefile dlls/olesvr/Makefile dlls/opengl32/Makefile dlls/psapi/Makefile dlls/qcap/Makefile dlls/quartz/Makefile dlls/rasapi32/Makefile dlls/richedit/Makefile dlls/rpcrt4/Makefile dlls/serialui/Makefile dlls/setupapi/Makefile dlls/shdocvw/Makefile dlls/shell32/Makefile dlls/shfolder/Makefile dlls/shlwapi/Makefile dlls/sti/Makefile dlls/tapi32/Makefile dlls/ttydrv/Makefile dlls/twain/Makefile dlls/url/Makefile dlls/urlmon/Makefile dlls/user/Makefile dlls/version/Makefile dlls/win32s/Makefile dlls/winaspi/Makefile dlls/winedos/Makefile dlls/wineps/Makefile dlls/wininet/Makefile dlls/winmm/Makefile dlls/winmm/joystick/Makefile dlls/winmm/mcianim/Makefile dlls/winmm/mciavi/Makefile dlls/winmm/mcicda/Makefile dlls/winmm/mciseq/Makefile dlls/winmm/mciwave/Makefile dlls/winmm/midimap/Makefile dlls/winmm/wavemap/Makefile dlls/winmm/winearts/Makefile dlls/winmm/wineoss/Makefile dlls/winnls/Makefile dlls/winsock/Makefile dlls/winspool/Makefile dlls/wintrust/Makefile dlls/wow32/Makefile dlls/wsock32/Makefile dlls/x11drv/Makefile documentation/Makefile files/Makefile graphics/Makefile graphics/enhmetafiledrv/Makefile graphics/metafiledrv/Makefile graphics/win16drv/Makefile graphics/x11drv/Makefile if1632/Makefile include/Makefile library/Makefile libtest/Makefile loader/Makefile loader/ne/Makefile memory/Makefile misc/Makefile miscemu/Makefile msdos/Makefile objects/Makefile ole/Makefile programs/Makefile programs/avitools/Makefile programs/clock/Makefile programs/cmdlgtst/Makefile programs/control/Makefile programs/notepad/Makefile programs/osversioncheck/Makefile programs/progman/Makefile programs/regapi/Makefile programs/regtest/Makefile programs/uninstaller/Makefile programs/view/Makefile programs/wcmd/Makefile programs/wineconsole/Makefile programs/winemine/Makefile programs/winetest/Makefile programs/winhelp/Makefile programs/winver/Makefile relay32/Makefile scheduler/Makefile server/Makefile tools/Makefile tools/winapi/Makefile tools/winebuild/Makefile tools/winedump/Makefile tools/wmc/Makefile tools/wrc/Makefile tsx11/Makefile unicode/Makefile win32/Makefile windows/Makefile windows/x11drv/Makefile"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -10712,6 +10712,7 @@
   "dlls/mapi32/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/mapi32/Makefile" ;;
   "dlls/mpr/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/mpr/Makefile" ;;
   "dlls/msacm/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/msacm/Makefile" ;;
+  "dlls/msacm/imaadp32/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/msacm/imaadp32/Makefile" ;;
   "dlls/msacm/msg711/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/msacm/msg711/Makefile" ;;
   "dlls/msdmo/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/msdmo/Makefile" ;;
   "dlls/msimg32/Makefile" ) CONFIG_FILES="$CONFIG_FILES dlls/msimg32/Makefile" ;;
@@ -10844,7 +10845,7 @@
   "programs/winetest/tests" ) CONFIG_COMMANDS="$CONFIG_COMMANDS programs/winetest/tests" ;;
   "include/wine/version.h" ) CONFIG_COMMANDS="$CONFIG_COMMANDS include/wine/version.h" ;;
   "include/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS include/config.h" ;;
-  *) { { echo "$as_me:10847: error: invalid argument: $ac_config_target" >&5
+  *) { { echo "$as_me:10848: error: invalid argument: $ac_config_target" >&5
 echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
    { (exit 1); exit 1; }; };;
   esac
@@ -11116,7 +11117,7 @@
   esac
 
   if test x"$ac_file" != x-; then
-    { echo "$as_me:11119: creating $ac_file" >&5
+    { echo "$as_me:11120: creating $ac_file" >&5
 echo "$as_me: creating $ac_file" >&6;}
     rm -f "$ac_file"
   fi
@@ -11134,7 +11135,7 @@
       -) echo $tmp/stdin ;;
       [\\/$]*)
          # Absolute (can't be DOS-style, as IFS=:)
-         test -f "$f" || { { echo "$as_me:11137: error: cannot find input file: $f" >&5
+         test -f "$f" || { { echo "$as_me:11138: error: cannot find input file: $f" >&5
 echo "$as_me: error: cannot find input file: $f" >&2;}
    { (exit 1); exit 1; }; }
          echo $f;;
@@ -11147,7 +11148,7 @@
            echo $srcdir/$f
          else
            # /dev/null tree
-           { { echo "$as_me:11150: error: cannot find input file: $f" >&5
+           { { echo "$as_me:11151: error: cannot find input file: $f" >&5
 echo "$as_me: error: cannot find input file: $f" >&2;}
    { (exit 1); exit 1; }; }
          fi;;
@@ -11208,7 +11209,7 @@
   * )   ac_file_in=$ac_file.in ;;
   esac
 
-  test x"$ac_file" != x- && { echo "$as_me:11211: creating $ac_file" >&5
+  test x"$ac_file" != x- && { echo "$as_me:11212: creating $ac_file" >&5
 echo "$as_me: creating $ac_file" >&6;}
 
   # First look for the input files in the build tree, otherwise in the
@@ -11219,7 +11220,7 @@
       -) echo $tmp/stdin ;;
       [\\/$]*)
          # Absolute (can't be DOS-style, as IFS=:)
-         test -f "$f" || { { echo "$as_me:11222: error: cannot find input file: $f" >&5
+         test -f "$f" || { { echo "$as_me:11223: error: cannot find input file: $f" >&5
 echo "$as_me: error: cannot find input file: $f" >&2;}
    { (exit 1); exit 1; }; }
          echo $f;;
@@ -11232,7 +11233,7 @@
            echo $srcdir/$f
          else
            # /dev/null tree
-           { { echo "$as_me:11235: error: cannot find input file: $f" >&5
+           { { echo "$as_me:11236: error: cannot find input file: $f" >&5
 echo "$as_me: error: cannot find input file: $f" >&2;}
    { (exit 1); exit 1; }; }
          fi;;
@@ -11349,7 +11350,7 @@
   rm -f $tmp/in
   if test x"$ac_file" != x-; then
     if cmp -s $ac_file $tmp/config.h 2>/dev/null; then
-      { echo "$as_me:11352: $ac_file is unchanged" >&5
+      { echo "$as_me:11353: $ac_file is unchanged" >&5
 echo "$as_me: $ac_file is unchanged" >&6;}
     else
       ac_dir=`$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
@@ -11400,50 +11401,50 @@
   ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
 
   case $ac_dest in
-    dlls/ddraw/d3ddevice ) test -d "dlls/ddraw/d3ddevice" || ({ echo "$as_me:11403: creating dlls/ddraw/d3ddevice" >&5
+    dlls/ddraw/d3ddevice ) test -d "dlls/ddraw/d3ddevice" || ({ echo "$as_me:11404: creating dlls/ddraw/d3ddevice" >&5
 echo "$as_me: creating dlls/ddraw/d3ddevice" >&6;} && mkdir "dlls/ddraw/d3ddevice") ;;
-    dlls/ddraw/dclipper ) test -d "dlls/ddraw/dclipper" || ({ echo "$as_me:11405: creating dlls/ddraw/dclipper" >&5
+    dlls/ddraw/dclipper ) test -d "dlls/ddraw/dclipper" || ({ echo "$as_me:11406: creating dlls/ddraw/dclipper" >&5
 echo "$as_me: creating dlls/ddraw/dclipper" >&6;} && mkdir "dlls/ddraw/dclipper") ;;
-    dlls/ddraw/ddraw ) test -d "dlls/ddraw/ddraw" || ({ echo "$as_me:11407: creating dlls/ddraw/ddraw" >&5
+    dlls/ddraw/ddraw ) test -d "dlls/ddraw/ddraw" || ({ echo "$as_me:11408: creating dlls/ddraw/ddraw" >&5
 echo "$as_me: creating dlls/ddraw/ddraw" >&6;} && mkdir "dlls/ddraw/ddraw") ;;
-    dlls/ddraw/direct3d ) test -d "dlls/ddraw/direct3d" || ({ echo "$as_me:11409: creating dlls/ddraw/direct3d" >&5
+    dlls/ddraw/direct3d ) test -d "dlls/ddraw/direct3d" || ({ echo "$as_me:11410: creating dlls/ddraw/direct3d" >&5
 echo "$as_me: creating dlls/ddraw/direct3d" >&6;} && mkdir "dlls/ddraw/direct3d") ;;
-    dlls/ddraw/dpalette ) test -d "dlls/ddraw/dpalette" || ({ echo "$as_me:11411: creating dlls/ddraw/dpalette" >&5
+    dlls/ddraw/dpalette ) test -d "dlls/ddraw/dpalette" || ({ echo "$as_me:11412: creating dlls/ddraw/dpalette" >&5
 echo "$as_me: creating dlls/ddraw/dpalette" >&6;} && mkdir "dlls/ddraw/dpalette") ;;
-    dlls/ddraw/dsurface ) test -d "dlls/ddraw/dsurface" || ({ echo "$as_me:11413: creating dlls/ddraw/dsurface" >&5
+    dlls/ddraw/dsurface ) test -d "dlls/ddraw/dsurface" || ({ echo "$as_me:11414: creating dlls/ddraw/dsurface" >&5
 echo "$as_me: creating dlls/ddraw/dsurface" >&6;} && mkdir "dlls/ddraw/dsurface") ;;
-    dlls/dinput/joystick ) test -d "dlls/dinput/joystick" || ({ echo "$as_me:11415: creating dlls/dinput/joystick" >&5
+    dlls/dinput/joystick ) test -d "dlls/dinput/joystick" || ({ echo "$as_me:11416: creating dlls/dinput/joystick" >&5
 echo "$as_me: creating dlls/dinput/joystick" >&6;} && mkdir "dlls/dinput/joystick") ;;
-    dlls/dinput/keyboard ) test -d "dlls/dinput/keyboard" || ({ echo "$as_me:11417: creating dlls/dinput/keyboard" >&5
+    dlls/dinput/keyboard ) test -d "dlls/dinput/keyboard" || ({ echo "$as_me:11418: creating dlls/dinput/keyboard" >&5
 echo "$as_me: creating dlls/dinput/keyboard" >&6;} && mkdir "dlls/dinput/keyboard") ;;
-    dlls/dinput/mouse ) test -d "dlls/dinput/mouse" || ({ echo "$as_me:11419: creating dlls/dinput/mouse" >&5
+    dlls/dinput/mouse ) test -d "dlls/dinput/mouse" || ({ echo "$as_me:11420: creating dlls/dinput/mouse" >&5
 echo "$as_me: creating dlls/dinput/mouse" >&6;} && mkdir "dlls/dinput/mouse") ;;
-    dlls/kernel/messages ) test -d "dlls/kernel/messages" || ({ echo "$as_me:11421: creating dlls/kernel/messages" >&5
+    dlls/kernel/messages ) test -d "dlls/kernel/messages" || ({ echo "$as_me:11422: creating dlls/kernel/messages" >&5
 echo "$as_me: creating dlls/kernel/messages" >&6;} && mkdir "dlls/kernel/messages") ;;
-    dlls/kernel/tests ) test -d "dlls/kernel/tests" || ({ echo "$as_me:11423: creating dlls/kernel/tests" >&5
+    dlls/kernel/tests ) test -d "dlls/kernel/tests" || ({ echo "$as_me:11424: creating dlls/kernel/tests" >&5
 echo "$as_me: creating dlls/kernel/tests" >&6;} && mkdir "dlls/kernel/tests") ;;
-    dlls/user/dde ) test -d "dlls/user/dde" || ({ echo "$as_me:11425: creating dlls/user/dde" >&5
+    dlls/user/dde ) test -d "dlls/user/dde" || ({ echo "$as_me:11426: creating dlls/user/dde" >&5
 echo "$as_me: creating dlls/user/dde" >&6;} && mkdir "dlls/user/dde") ;;
-    dlls/user/resources ) test -d "dlls/user/resources" || ({ echo "$as_me:11427: creating dlls/user/resources" >&5
+    dlls/user/resources ) test -d "dlls/user/resources" || ({ echo "$as_me:11428: creating dlls/user/resources" >&5
 echo "$as_me: creating dlls/user/resources" >&6;} && mkdir "dlls/user/resources") ;;
-    dlls/user/tests ) test -d "dlls/user/tests" || ({ echo "$as_me:11429: creating dlls/user/tests" >&5
+    dlls/user/tests ) test -d "dlls/user/tests" || ({ echo "$as_me:11430: creating dlls/user/tests" >&5
 echo "$as_me: creating dlls/user/tests" >&6;} && mkdir "dlls/user/tests") ;;
-    dlls/wineps/data ) test -d "dlls/wineps/data" || ({ echo "$as_me:11431: creating dlls/wineps/data" >&5
+    dlls/wineps/data ) test -d "dlls/wineps/data" || ({ echo "$as_me:11432: creating dlls/wineps/data" >&5
 echo "$as_me: creating dlls/wineps/data" >&6;} && mkdir "dlls/wineps/data") ;;
-    include/wine ) test -d "include/wine" || ({ echo "$as_me:11433: creating include/wine" >&5
+    include/wine ) test -d "include/wine" || ({ echo "$as_me:11434: creating include/wine" >&5
 echo "$as_me: creating include/wine" >&6;} && mkdir "include/wine") ;;
-    programs/regapi/tests ) test -d "programs/regapi/tests" || ({ echo "$as_me:11435: creating programs/regapi/tests" >&5
+    programs/regapi/tests ) test -d "programs/regapi/tests" || ({ echo "$as_me:11436: creating programs/regapi/tests" >&5
 echo "$as_me: creating programs/regapi/tests" >&6;} && mkdir "programs/regapi/tests") ;;
-    programs/winetest/tests ) test -d "programs/winetest/tests" || ({ echo "$as_me:11437: creating programs/winetest/tests" >&5
+    programs/winetest/tests ) test -d "programs/winetest/tests" || ({ echo "$as_me:11438: creating programs/winetest/tests" >&5
 echo "$as_me: creating programs/winetest/tests" >&6;} && mkdir "programs/winetest/tests") ;;
-    include/wine/version.h ) { echo "$as_me:11439: creating include/wine/version.h" >&5
+    include/wine/version.h ) { echo "$as_me:11440: creating include/wine/version.h" >&5
 echo "$as_me: creating include/wine/version.h" >&6;}
 cat >$tmp/version.h <<CEOF
 /* Generated automatically by configure; DO NOT EDIT! */
 #define WINE_RELEASE_INFO "Wine version $wine_version"
 CEOF
 if cmp -s $tmp/version.h include/wine/version.h 2>/dev/null; then
-  { echo "$as_me:11446: include/wine/version.h is unchanged" >&5
+  { echo "$as_me:11447: include/wine/version.h is unchanged" >&5
 echo "$as_me: include/wine/version.h is unchanged" >&6;}
   rm -f $tmp/version.h
 else
diff --git a/configure.ac b/configure.ac
index 9e54a47..683fa01 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1322,6 +1322,7 @@
 dlls/mapi32/Makefile
 dlls/mpr/Makefile
 dlls/msacm/Makefile
+dlls/msacm/imaadp32/Makefile
 dlls/msacm/msg711/Makefile
 dlls/msdmo/Makefile
 dlls/msimg32/Makefile
diff --git a/dlls/Makefile.in b/dlls/Makefile.in
index 0f667db..6a48e32 100644
--- a/dlls/Makefile.in
+++ b/dlls/Makefile.in
@@ -38,6 +38,7 @@
 	mapi32 \
 	mpr \
 	msacm \
+	msacm/imaadp32 \
 	msacm/msg711 \
 	msdmo \
 	msimg32 \
@@ -127,6 +128,7 @@
 	gdi.dll$(DLLEXT) \
 	gdi32.dll$(DLLEXT) \
 	icmp.dll$(DLLEXT) \
+	imaadp32.acm$(DLLEXT) \
 	imagehlp.dll$(DLLEXT) \
 	imm.dll$(DLLEXT) \
 	imm32.dll$(DLLEXT) \
@@ -285,6 +287,9 @@
 icmp.dll$(DLLEXT): icmp/icmp.dll$(DLLEXT)
 	$(RM) $@ && $(LN_S) icmp/icmp.dll$(DLLEXT) $@
 
+imaadp32.acm$(DLLEXT): msacm/imaadp32/imaadp32.acm$(DLLEXT)
+	$(RM) $@ && $(LN_S) msacm/imaadp32/imaadp32.acm$(DLLEXT) $@
+
 imagehlp.dll$(DLLEXT): imagehlp/imagehlp.dll$(DLLEXT)
 	$(RM) $@ && $(LN_S) imagehlp/imagehlp.dll$(DLLEXT) $@
 
@@ -578,6 +583,10 @@
 mpr/mpr.dll$(DLLEXT): dummy kernel32.dll$(DLLEXT) ntdll.dll$(DLLEXT)
 	@cd mpr && $(MAKE) mpr.dll$(DLLEXT)
 
+msacm/imaadp32/imaadp32.acm$(DLLEXT): dummy winmm.dll$(DLLEXT) user32.dll$(DLLEXT) \
+  kernel32.dll$(DLLEXT) ntdll.dll$(DLLEXT)
+	@cd msacm/imaadp32 && $(MAKE) imaadp32.acm$(DLLEXT)
+
 msacm/msacm32.dll$(DLLEXT): dummy winmm.dll$(DLLEXT) user32.dll$(DLLEXT) \
   advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT) ntdll.dll$(DLLEXT)
 	@cd msacm && $(MAKE) msacm32.dll$(DLLEXT)
@@ -791,7 +800,7 @@
 	@cd winnls && $(MAKE) winnls32.dll$(DLLEXT)
 
 winsock/ws2_32.dll$(DLLEXT): dummy user32.dll$(DLLEXT) kernel32.dll$(DLLEXT) \
-  ntdll.dll$(DLLEXT) libuser32.dll.$(LIBEXT) libkernel32.dll.$(LIBEXT) libntdll.dll.$(LIBEXT)
+  ntdll.dll$(DLLEXT)
 	@cd winsock && $(MAKE) ws2_32.dll$(DLLEXT)
 
 winspool/winspool.drv$(DLLEXT): dummy advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT) \
diff --git a/dlls/msacm/imaadp32/.cvsignore b/dlls/msacm/imaadp32/.cvsignore
new file mode 100644
index 0000000..7901fe2
--- /dev/null
+++ b/dlls/msacm/imaadp32/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+imaadp32.acm.spec.c
diff --git a/dlls/msacm/imaadp32/Makefile.in b/dlls/msacm/imaadp32/Makefile.in
new file mode 100644
index 0000000..0e60c8c
--- /dev/null
+++ b/dlls/msacm/imaadp32/Makefile.in
@@ -0,0 +1,14 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../../..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = imaadp32.acm
+
+LDDLLFLAGS = @LDDLLFLAGS@
+SYMBOLFILE = $(MODULE).tmp.o
+
+C_SRCS = imaadp32.c
+
+@MAKE_DLL_RULES@
+
+### Dependencies:
diff --git a/dlls/msacm/imaadp32/imaadp32.acm.spec b/dlls/msacm/imaadp32/imaadp32.acm.spec
new file mode 100644
index 0000000..71a0b99
--- /dev/null
+++ b/dlls/msacm/imaadp32/imaadp32.acm.spec
@@ -0,0 +1,13 @@
+name imaadp32
+file imaadp32.acm
+type win32
+init IMAADP32_DllMain
+
+import winmm.dll
+import user32.dll
+import kernel32.dll
+import ntdll.dll
+
+debug_channels (imaadp32)
+
+@ stdcall DriverProc(long long long long long) IMAADP32_DriverProc
diff --git a/dlls/msacm/imaadp32/imaadp32.c b/dlls/msacm/imaadp32/imaadp32.c
new file mode 100644
index 0000000..6cccbc5
--- /dev/null
+++ b/dlls/msacm/imaadp32/imaadp32.c
@@ -0,0 +1,814 @@
+/*
+ * imaadp32.drv - IMA4 codec driver
+ *
+ * Copyright 2001 Hidenori Takeshima
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *
+ * FIXME - no encoding.
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winnls.h"
+#include "winuser.h"
+#include "mmsystem.h"
+#include "msacm.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(imaadp32);
+
+
+/***********************************************************************/
+
+#define ACMDM_DRIVER_NOTIFY             (ACMDM_BASE + 1)
+#define ACMDM_DRIVER_DETAILS            (ACMDM_BASE + 10)
+
+#define ACMDM_HARDWARE_WAVE_CAPS_INPUT  (ACMDM_BASE + 20)
+#define ACMDM_HARDWARE_WAVE_CAPS_OUTPUT (ACMDM_BASE + 21)
+
+#define ACMDM_FORMATTAG_DETAILS         (ACMDM_BASE + 25)
+#define ACMDM_FORMAT_DETAILS            (ACMDM_BASE + 26)
+#define ACMDM_FORMAT_SUGGEST            (ACMDM_BASE + 27)
+
+#define ACMDM_FILTERTAG_DETAILS         (ACMDM_BASE + 50)
+#define ACMDM_FILTER_DETAILS            (ACMDM_BASE + 51)
+
+#define ACMDM_STREAM_OPEN               (ACMDM_BASE + 76)
+#define ACMDM_STREAM_CLOSE              (ACMDM_BASE + 77)
+#define ACMDM_STREAM_SIZE               (ACMDM_BASE + 78)
+#define ACMDM_STREAM_CONVERT            (ACMDM_BASE + 79)
+#define ACMDM_STREAM_RESET              (ACMDM_BASE + 80)
+#define ACMDM_STREAM_PREPARE            (ACMDM_BASE + 81)
+#define ACMDM_STREAM_UNPREPARE          (ACMDM_BASE + 82)
+#define ACMDM_STREAM_UPDATE             (ACMDM_BASE + 83)
+
+typedef struct _ACMDRVSTREAMINSTANCE
+{
+  DWORD           cbStruct;
+  PWAVEFORMATEX   pwfxSrc;
+  PWAVEFORMATEX   pwfxDst;
+  PWAVEFILTER     pwfltr;
+  DWORD           dwCallback;
+  DWORD           dwInstance;
+  DWORD           fdwOpen;
+  DWORD           fdwDriver;
+  DWORD           dwDriver;
+  HACMSTREAM    has;
+} ACMDRVSTREAMINSTANCE, *PACMDRVSTREAMINSTANCE;
+
+typedef struct _ACMDRVSTREAMHEADER *PACMDRVSTREAMHEADER;
+typedef struct _ACMDRVSTREAMHEADER {
+  DWORD  cbStruct;
+  DWORD  fdwStatus;
+  DWORD  dwUser;
+  LPBYTE pbSrc;
+  DWORD  cbSrcLength;
+  DWORD  cbSrcLengthUsed;
+  DWORD  dwSrcUser;
+  LPBYTE pbDst;
+  DWORD  cbDstLength;
+  DWORD  cbDstLengthUsed;
+  DWORD  dwDstUser;
+
+  DWORD fdwConvert;
+  PACMDRVSTREAMHEADER *padshNext;
+  DWORD fdwDriver;
+  DWORD dwDriver;
+
+  /* Internal fields for ACM */
+  DWORD  fdwPrepared;
+  DWORD  dwPrepared;
+  LPBYTE pbPreparedSrc;
+  DWORD  cbPreparedSrcLength;
+  LPBYTE pbPreparedDst;
+  DWORD  cbPreparedDstLength;
+} ACMDRVSTREAMHEADER;
+
+typedef struct _ACMDRVSTREAMSIZE
+{
+  DWORD cbStruct;
+  DWORD fdwSize;
+  DWORD cbSrcLength;
+  DWORD cbDstLength;
+} ACMDRVSTREAMSIZE, *PACMDRVSTREAMSIZE;
+
+typedef struct _ACMDRVFORMATSUGGEST
+{
+  DWORD           cbStruct;
+  DWORD           fdwSuggest;
+  PWAVEFORMATEX   pwfxSrc;
+  DWORD           cbwfxSrc;
+  PWAVEFORMATEX   pwfxDst;
+  DWORD           cbwfxDst;
+} ACMDRVFORMATSUGGEST, *PACMDRVFORMATSUGGEST;
+
+
+
+
+/***********************************************************************/
+
+enum CodecType
+{
+	CodecType_Invalid,
+	CodecType_EncIMAADPCM,
+	CodecType_DecIMAADPCM,
+};
+
+typedef struct CodecImpl
+{
+	int	dummy;
+} CodecImpl;
+
+/***********************************************************************/
+
+
+static const int ima_step[88+1] =
+{
+	/* from Y.Ajima's WAVFMT.TXT */
+	    7,     8,     9,    10,    11,    12,    13,    14,
+	   16,    17,    19,    21,    23,    25,    28,    31,
+	   34,    37,    41,    45,    50,    55,    60,    66,
+	   73,    80,    88,    97,   107,   118,   130,   143,
+	  157,   173,   190,   209,   230,   253,   279,   307,
+	  337,   371,   408,   449,   494,   544,   598,   658,
+	  724,   796,   876,   963,  1060,  1166,  1282,  1411,
+	 1552,  1707,  1878,  2066,  2272,  2499,  2749,  3024,
+	 3327,  3660,  4026,  4428,  4871,  5358,  5894,  6484,
+	 7132,  7845,  8630,  9493, 10442, 11487, 12635, 13899,
+	15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+};
+
+static const int ima_indexupdate[8*2] =
+{
+	/* from Y.Ajima's WAVFMT.TXT */
+	-1,-1,-1,-1, 2, 4, 6, 8,
+	-1,-1,-1,-1, 2, 4, 6, 8,
+};
+
+static int stepindex_to_diff( int stepindex, int input )
+{
+	/* from Y.Ajima's WAVFMT.TXT */
+	int absdiff;
+
+	absdiff = (ima_step[stepindex]*((input&0x7)*2+1)) >> 3;
+	return (input&0x8) ? (-absdiff) : absdiff;
+}
+
+static int update_stepindex( int oldindex, int input )
+{
+	int	index;
+
+	index = oldindex + ima_indexupdate[input];
+	return (index < 0) ? 0 : (index > 88) ? 88 : index;
+}
+
+static void decode_ima_block( int channels, int samplesperblock, SHORT* pDst, BYTE* pSrc )
+{
+	int	samp[2];
+	int	stepindex[2];
+	int	inputs[8];
+	int	n,k,diff;
+
+	for ( n = 0; n < channels; n++ )
+	{
+		samp[n] = *(SHORT*)pSrc; pSrc += sizeof(SHORT);
+		stepindex[n] = *pSrc; pSrc += sizeof(SHORT);
+		*pDst++ = samp[n];
+	}
+	samplesperblock --;
+
+	while ( samplesperblock >= 8 )
+	{
+		for ( n = 0; n < channels; n++ )
+		{
+			for ( k = 0; k < 4; k++ )
+			{
+				inputs[k*2+0] = (*pSrc) & 0xf;
+				inputs[k*2+1] = (*pSrc) >> 4;
+				pSrc ++;
+			}
+			for ( k = 0; k < 8; k++ )
+			{
+				diff = stepindex_to_diff( stepindex[n], inputs[k] );
+				stepindex[n] = update_stepindex( stepindex[n], inputs[k] );
+				diff += samp[n];
+				if ( diff < -32768 ) diff = -32768;
+				if ( diff >  32767 ) diff =  32767;
+				samp[n] = diff;
+				pDst[k*channels+n] = samp[n];
+			}
+		}
+
+		pDst += channels*8;
+		samplesperblock -= 8;
+	}
+}
+
+static LONG IMAADPCM32_Decode( int channels, int blockalign, int samplesperblock, BYTE* pbDst, DWORD cbDstLength, DWORD* pcbDstLengthUsed, BYTE* pbSrc, DWORD cbSrcLength, DWORD* pcbSrcLengthUsed )
+{
+	DWORD	cbDstLengthUsed = 0;
+	DWORD	cbSrcLengthUsed = 0;
+	int	dstblocksize;
+
+	dstblocksize = samplesperblock*channels*sizeof(SHORT);
+	while ( cbDstLength >= dstblocksize && cbSrcLength >= blockalign )
+	{
+		decode_ima_block( channels, samplesperblock, (SHORT*)pbDst, pbSrc );
+		pbDst += dstblocksize;
+		cbDstLength -= dstblocksize;
+		cbDstLengthUsed += dstblocksize;
+		pbSrc += blockalign;
+		cbSrcLength -= blockalign;
+		cbSrcLengthUsed += blockalign;
+	}
+
+	*pcbSrcLengthUsed = cbSrcLengthUsed;
+	*pcbDstLengthUsed = cbDstLengthUsed;
+
+	return MMSYSERR_NOERROR;
+}
+
+
+/***********************************************************************/
+
+static LONG Codec_DrvQueryConfigure( CodecImpl* This )
+{
+	return MMSYSERR_NOTSUPPORTED;
+}
+
+static LONG Codec_DrvConfigure( CodecImpl* This, HWND hwnd, DRVCONFIGINFO* pinfo )
+{
+	return MMSYSERR_NOTSUPPORTED;
+}
+
+static LONG Codec_DriverDetails( ACMDRIVERDETAILSW* pDrvDetails )
+{
+	if ( pDrvDetails->cbStruct < sizeof(ACMDRIVERDETAILSW) )
+		return MMSYSERR_INVALPARAM;
+
+	ZeroMemory( pDrvDetails, sizeof(ACMDRIVERDETAILSW) );
+	pDrvDetails->cbStruct = sizeof(ACMDRIVERDETAILSW);
+
+	pDrvDetails->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
+	pDrvDetails->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
+	pDrvDetails->wMid = 0xff;	/* FIXME? */
+	pDrvDetails->wPid = 0x00;	/* FIXME? */
+	pDrvDetails->vdwACM = 0x01000000;	/* FIXME? */
+	pDrvDetails->vdwDriver = 0x01000000;	/* FIXME? */
+	pDrvDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
+	pDrvDetails->cFormatTags = 2;
+	pDrvDetails->cFilterTags = 0;
+	pDrvDetails->hicon = (HICON)NULL;
+	MultiByteToWideChar( CP_ACP, 0, "WineIMA", -1,
+		pDrvDetails->szShortName,
+		sizeof(pDrvDetails->szShortName)/sizeof(WCHAR) );
+	MultiByteToWideChar( CP_ACP, 0, "Wine IMA codec", -1,
+		pDrvDetails->szLongName,
+		sizeof(pDrvDetails->szLongName)/sizeof(WCHAR) );
+    MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
+		pDrvDetails->szCopyright,
+		sizeof(pDrvDetails->szCopyright)/sizeof(WCHAR) );
+	MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
+		pDrvDetails->szLicensing,
+		sizeof(pDrvDetails->szLicensing)/sizeof(WCHAR) );
+	pDrvDetails->szFeatures[0] = 0;
+
+	return MMSYSERR_NOERROR;
+}
+
+static LONG Codec_QueryAbout( void )
+{
+	return MMSYSERR_NOTSUPPORTED;
+}
+
+static LONG Codec_About( HWND hwnd )
+{
+	return MMSYSERR_NOTSUPPORTED;
+}
+
+/***********************************************************************/
+
+static LONG Codec_FormatTagDetails( CodecImpl* This, ACMFORMATTAGDETAILSW* pFmtTagDetails, DWORD dwFlags )
+{
+	FIXME( "enumerate tags\n" );
+
+	switch ( dwFlags )
+	{
+	case ACM_FORMATTAGDETAILSF_INDEX:
+		switch ( pFmtTagDetails->dwFormatTagIndex )
+		{
+		case 0:
+			pFmtTagDetails->dwFormatTag = 0x11;	/* IMA ADPCM */
+			break;
+		case 1:
+			pFmtTagDetails->dwFormatTag = 1;	/* PCM */
+			break;
+		default:
+			return ACMERR_NOTPOSSIBLE;
+		}
+		break;
+	case ACM_FORMATTAGDETAILSF_FORMATTAG:
+		switch ( pFmtTagDetails->dwFormatTag )
+		{
+		case 0x11:	/* IMA ADPCM */
+			pFmtTagDetails->dwFormatTagIndex = 0;
+			break;
+		case 1:	/* PCM */
+			pFmtTagDetails->dwFormatTagIndex = 1;
+			break;
+		default:
+			return ACMERR_NOTPOSSIBLE;
+		}
+		break;
+	case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
+		if ( pFmtTagDetails->dwFormatTag != 0 &&
+			 pFmtTagDetails->dwFormatTag != 1 &&
+			 pFmtTagDetails->dwFormatTag != 0x11 )
+			return ACMERR_NOTPOSSIBLE;
+		pFmtTagDetails->dwFormatTagIndex = 0;
+		break;
+	default:
+		return MMSYSERR_NOTSUPPORTED;
+	}
+
+	pFmtTagDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
+	pFmtTagDetails->cbFormatSize = sizeof(WAVEFORMATEX);
+	pFmtTagDetails->cStandardFormats = 2;	/* FIXME */
+	pFmtTagDetails->szFormatTag[0] = 0;	/* FIXME */
+
+	return MMSYSERR_NOERROR;
+}
+
+static LONG Codec_FormatDetails( CodecImpl* This, ACMFORMATDETAILSW* pFmtDetails, DWORD dwFlags )
+{
+	FIXME( "enumerate standard formats\n" );
+
+	if ( pFmtDetails->cbStruct < sizeof(ACMFORMATDETAILSW) )
+		return MMSYSERR_INVALPARAM;
+	pFmtDetails->cbStruct = sizeof(ACMFORMATDETAILSW);
+
+	switch ( dwFlags )
+	{
+	case ACM_FORMATDETAILSF_INDEX:
+		switch ( pFmtDetails->dwFormatIndex )
+		{
+		case 0:
+			pFmtDetails->dwFormatTag = 0x11;	/* IMA ADPCM */
+			break;
+		case 1:
+			pFmtDetails->dwFormatTag = 1;	/* PCM */
+			break;
+		default:
+			return MMSYSERR_INVALPARAM;
+		}
+		break;
+	case ACM_FORMATDETAILSF_FORMAT:
+		switch ( pFmtDetails->dwFormatTag )
+		{
+		case 0x11:	/* IMA ADPCM */
+			pFmtDetails->dwFormatIndex = 0;
+			break;
+		case 1:	/* PCM */
+			pFmtDetails->dwFormatIndex = 1;
+			break;
+		default:
+			return ACMERR_NOTPOSSIBLE;
+		}
+		break;
+	default:
+		return MMSYSERR_NOTSUPPORTED;
+	}
+
+	pFmtDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
+	pFmtDetails->pwfx->wFormatTag = pFmtDetails->dwFormatTag;
+	pFmtDetails->pwfx->nChannels = 1;
+	pFmtDetails->pwfx->nSamplesPerSec = 11025;
+	pFmtDetails->pwfx->wBitsPerSample = 4;
+	if ( pFmtDetails->dwFormatTag == 1 )
+	{
+		pFmtDetails->cbwfx = sizeof(PCMWAVEFORMAT);
+	}
+	else
+	{
+		pFmtDetails->pwfx->cbSize = sizeof(WORD);
+		pFmtDetails->cbwfx = sizeof(WAVEFORMATEX) + sizeof(WORD);
+	}
+	pFmtDetails->szFormat[0] = 0;	/* FIXME */
+
+    return MMSYSERR_NOERROR;
+}
+
+
+static LONG Codec_FormatSuggest( CodecImpl* This, ACMDRVFORMATSUGGEST* pFmtSuggest )
+{
+	DWORD	fdwSuggest;
+
+	FIXME( "get suggested format\n" );
+
+	if ( pFmtSuggest->cbStruct != sizeof(ACMDRVFORMATSUGGEST) )
+		return MMSYSERR_INVALPARAM;
+
+	if ( pFmtSuggest->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
+		 pFmtSuggest->cbwfxDst < sizeof(PCMWAVEFORMAT) )
+		return MMSYSERR_INVALPARAM;
+
+	fdwSuggest = pFmtSuggest->fdwSuggest;
+
+	if ( fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS )
+	{
+		if ( pFmtSuggest->pwfxSrc->nChannels != pFmtSuggest->pwfxDst->nChannels )
+			return ACMERR_NOTPOSSIBLE;
+		fdwSuggest &= ~ACM_FORMATSUGGESTF_NCHANNELS;
+	}
+
+	if ( fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC )
+	{
+		if ( pFmtSuggest->pwfxSrc->nSamplesPerSec != pFmtSuggest->pwfxDst->nSamplesPerSec )
+			return ACMERR_NOTPOSSIBLE;
+		fdwSuggest &= ~ACM_FORMATSUGGESTF_NSAMPLESPERSEC;
+	}
+
+	if ( pFmtSuggest->pwfxSrc->wFormatTag == 1 )
+	{
+		/* Compressor */
+		if ( pFmtSuggest->cbwfxDst < (sizeof(WAVEFORMATEX)+sizeof(WORD)) )
+			return MMSYSERR_INVALPARAM;
+		if ( pFmtSuggest->pwfxSrc->wBitsPerSample != 16 )
+			return ACMERR_NOTPOSSIBLE;
+
+		if ( fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG )
+		{
+			if ( pFmtSuggest->pwfxDst->wFormatTag != 0x11 )
+				return ACMERR_NOTPOSSIBLE;
+			fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
+		}
+
+		if ( fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE )
+		{
+			if ( pFmtSuggest->pwfxDst->wBitsPerSample != 4 )
+				return ACMERR_NOTPOSSIBLE;
+			fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
+		}
+
+		if ( fdwSuggest != 0 )
+			return MMSYSERR_INVALFLAG;
+
+		if ( !(fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG) )
+			pFmtSuggest->pwfxDst->wFormatTag = 0x11;
+		pFmtSuggest->pwfxDst->nChannels = pFmtSuggest->pwfxSrc->nChannels;
+		pFmtSuggest->pwfxDst->nSamplesPerSec = pFmtSuggest->pwfxSrc->nSamplesPerSec;
+		pFmtSuggest->pwfxDst->nAvgBytesPerSec = 0; /* FIXME */
+		pFmtSuggest->pwfxDst->nBlockAlign = 0; /* FIXME */
+		pFmtSuggest->pwfxDst->wBitsPerSample = 4;
+		pFmtSuggest->pwfxDst->cbSize = 2;
+
+		FIXME( "no compressor" );
+		return ACMERR_NOTPOSSIBLE;
+	}
+	else
+	{
+		/* Decompressor */
+		if ( pFmtSuggest->cbwfxSrc < (sizeof(WAVEFORMATEX)+sizeof(WORD)) )
+			return MMSYSERR_INVALPARAM;
+		if ( pFmtSuggest->pwfxSrc->wFormatTag != 0x11 )
+			return ACMERR_NOTPOSSIBLE;
+		if ( pFmtSuggest->pwfxSrc->wBitsPerSample != 4 )
+			return ACMERR_NOTPOSSIBLE;
+
+		if ( fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG )
+		{
+			if ( pFmtSuggest->pwfxDst->wFormatTag != 1 )
+				return ACMERR_NOTPOSSIBLE;
+			fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
+		}
+
+		if ( fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE )
+		{
+			if ( pFmtSuggest->pwfxDst->wBitsPerSample != 16 )
+				return ACMERR_NOTPOSSIBLE;
+			fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
+		}
+
+		if ( fdwSuggest != 0 )
+			return MMSYSERR_INVALFLAG;
+
+		pFmtSuggest->pwfxDst->wFormatTag = 1;
+		pFmtSuggest->pwfxDst->nChannels = pFmtSuggest->pwfxSrc->nChannels;
+		pFmtSuggest->pwfxDst->nSamplesPerSec = pFmtSuggest->pwfxSrc->nSamplesPerSec;
+		pFmtSuggest->pwfxDst->nAvgBytesPerSec = pFmtSuggest->pwfxSrc->nSamplesPerSec * pFmtSuggest->pwfxSrc->nChannels * 2;
+		pFmtSuggest->pwfxDst->nBlockAlign = pFmtSuggest->pwfxSrc->nChannels * 2;
+		pFmtSuggest->pwfxDst->wBitsPerSample = 16;
+	}
+
+	return MMSYSERR_NOERROR;
+}
+
+static LONG Codec_FilterTagDetails( CodecImpl* This, ACMFILTERTAGDETAILSW* pFilterTagDetails, DWORD dwFlags )
+{
+	/* This is a codec driver. */
+	return MMSYSERR_NOTSUPPORTED;
+}
+
+static LONG Codec_FilterDetails( CodecImpl* This, ACMFILTERDETAILSW* pFilterDetails, DWORD dwFlags )
+{
+	/* This is a codec driver. */
+	return MMSYSERR_NOTSUPPORTED;
+}
+
+static LONG Codec_StreamOpen( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst )
+{
+	enum CodecType	codectype = CodecType_Invalid;
+
+	if ( pStreamInst->cbStruct != sizeof(ACMDRVSTREAMINSTANCE) )
+	{
+		TRACE("invalid size of struct\n");
+		return MMSYSERR_INVALPARAM;
+	}
+
+	if ( pStreamInst->fdwOpen & (~(ACM_STREAMOPENF_ASYNC|ACM_STREAMOPENF_NONREALTIME|ACM_STREAMOPENF_QUERY|CALLBACK_EVENT|CALLBACK_FUNCTION|CALLBACK_WINDOW)) )
+	{
+		TRACE("unknown flags\n");
+		return MMSYSERR_INVALFLAG;
+	}
+
+	/* No support for async operations. */
+	if ( pStreamInst->fdwOpen & ACM_STREAMOPENF_ASYNC )
+		return MMSYSERR_INVALFLAG;
+
+	/* This is a codec driver. */
+	if ( pStreamInst->pwfxSrc->nChannels != pStreamInst->pwfxDst->nChannels || pStreamInst->pwfxSrc->nSamplesPerSec != pStreamInst->pwfxDst->nSamplesPerSec )
+		return ACMERR_NOTPOSSIBLE;
+	if ( pStreamInst->pwfltr != NULL )
+		return ACMERR_NOTPOSSIBLE;
+
+	if ( pStreamInst->pwfxSrc->wFormatTag == 1 )
+	{
+		if ( pStreamInst->pwfxSrc->wBitsPerSample != 16 )
+			return ACMERR_NOTPOSSIBLE;
+		if ( pStreamInst->pwfxDst->wBitsPerSample != 4 )
+			return ACMERR_NOTPOSSIBLE;
+
+		/* Queried as a compressor */
+		FIXME( "Compressor is not implemented now\n" );
+		return ACMERR_NOTPOSSIBLE;
+	}
+	else
+	if ( pStreamInst->pwfxDst->wFormatTag == 1 )
+	{
+		if ( pStreamInst->pwfxDst->wBitsPerSample != 16 )
+			return ACMERR_NOTPOSSIBLE;
+		if ( pStreamInst->pwfxSrc->wBitsPerSample != 4 )
+			return ACMERR_NOTPOSSIBLE;
+
+		switch ( pStreamInst->pwfxSrc->wFormatTag )
+		{
+		case 0x11: /* IMA ADPCM */
+			TRACE( "IMG ADPCM deompressor\n" );
+			codectype = CodecType_DecIMAADPCM;
+			break;
+		default:
+			return ACMERR_NOTPOSSIBLE;
+		}
+	}
+	else
+	{
+		return ACMERR_NOTPOSSIBLE;
+	}
+
+	if ( pStreamInst->fdwOpen & ACM_STREAMOPENF_QUERY )
+		return MMSYSERR_NOERROR;
+
+	pStreamInst->dwDriver = (DWORD)codectype;
+
+	return MMSYSERR_NOERROR;
+}
+
+static LONG Codec_StreamClose( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst )
+{
+	return MMSYSERR_NOERROR;
+}
+
+static LONG Codec_StreamSize( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMSIZE* pStreamSize )
+{
+	enum CodecType	codectype;
+	LONG	res;
+
+	if ( pStreamSize->cbStruct != sizeof(ACMDRVSTREAMSIZE) )
+		return MMSYSERR_INVALPARAM;
+
+	codectype = (enum CodecType)pStreamInst->dwDriver;
+
+	res = MMSYSERR_NOERROR;
+	FIXME("()\n");
+	switch ( codectype )
+	{
+	case CodecType_EncIMAADPCM:
+		if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_SOURCE )
+			pStreamSize->cbDstLength = 64 + (pStreamSize->cbSrcLength >> 2);
+		else
+		if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_DESTINATION )
+			pStreamSize->cbSrcLength = pStreamSize->cbDstLength << 2;
+		else
+			res = MMSYSERR_INVALFLAG;
+		break;
+	case CodecType_DecIMAADPCM:
+		if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_SOURCE )
+			pStreamSize->cbDstLength = pStreamSize->cbSrcLength << 2;
+		else
+		if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_DESTINATION )
+			pStreamSize->cbSrcLength = 64 + (pStreamSize->cbDstLength >> 2);
+		else
+			res = MMSYSERR_INVALFLAG;
+		break;
+	default:
+		ERR( "CodecType_Invalid\n" );
+		res = MMSYSERR_NOTSUPPORTED;
+		break;
+	}
+
+	return res;
+}
+
+static LONG Codec_StreamConvert( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMHEADER* pStreamHdr )
+{
+	enum CodecType	codectype;
+	LONG	res;
+
+	codectype = (enum CodecType)pStreamInst->dwDriver;
+
+	res = MMSYSERR_NOTSUPPORTED;
+	switch ( codectype )
+	{
+	case CodecType_EncIMAADPCM:
+		FIXME( "CodecType_EncIMAADPCM\n" );
+		break;
+	case CodecType_DecIMAADPCM:
+		TRACE( "CodecType_DecIMAADPCM\n" );
+		res = IMAADPCM32_Decode( pStreamInst->pwfxSrc->nChannels, pStreamInst->pwfxSrc->nBlockAlign, *(WORD*)(((BYTE*)pStreamInst->pwfxSrc) + sizeof(WAVEFORMATEX)), pStreamHdr->pbDst, pStreamHdr->cbDstLength, &pStreamHdr->cbDstLengthUsed, pStreamHdr->pbSrc, pStreamHdr->cbSrcLength, &pStreamHdr->cbSrcLengthUsed );
+		break;
+	default:
+		ERR( "CodecType_Invalid\n" );
+		break;
+	}
+
+	return res;
+}
+
+static LONG Codec_StreamReset( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, DWORD dwFlags )
+{
+	return MMSYSERR_NOTSUPPORTED;
+}
+
+static LONG Codec_StreamPrepare( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMHEADER* pStreamHdr )
+{
+	return MMSYSERR_NOTSUPPORTED;
+}
+
+static LONG Codec_StreamUnprepare( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMHEADER* pStreamHdr )
+{
+	return MMSYSERR_NOTSUPPORTED;
+}
+
+
+
+/***********************************************************************/
+
+static CodecImpl* Codec_AllocDriver( void )
+{
+	CodecImpl*	This;
+
+	This = HeapAlloc( GetProcessHeap(), 0, sizeof(CodecImpl) );
+	if ( This == NULL )
+		return NULL;
+	ZeroMemory( This, sizeof(CodecImpl) );
+
+	/* initialize members. */
+
+	return This;
+}
+
+static void Codec_Close( CodecImpl* This )
+{
+
+	HeapFree( GetProcessHeap(), 0, This );
+}
+
+
+
+/***********************************************************************/
+
+LONG WINAPI IMAADP32_DriverProc(
+	DWORD dwDriverId, HDRVR hdrvr, UINT msg, LONG lParam1, LONG lParam2 )
+{
+	TRACE( "DriverProc(%08lx,%08x,%08x,%08lx,%08lx)\n",
+			 dwDriverId, hdrvr, msg, lParam1, lParam2 );
+
+	switch ( msg )
+	{
+	case DRV_LOAD:
+		TRACE("DRV_LOAD\n");
+		return TRUE;
+	case DRV_FREE:
+		TRACE("DRV_FREE\n");
+		return TRUE;
+	case DRV_OPEN:
+		TRACE("DRV_OPEN\n");
+		return (LONG)Codec_AllocDriver();
+	case DRV_CLOSE:
+		TRACE("DRV_CLOSE\n");
+		Codec_Close( (CodecImpl*)dwDriverId );
+		return TRUE;
+	case DRV_ENABLE:
+		TRACE("DRV_ENABLE\n");
+		return TRUE;
+	case DRV_DISABLE:
+		TRACE("DRV_DISABLE\n");
+		return TRUE;
+	case DRV_QUERYCONFIGURE:
+		TRACE("DRV_QUERYCONFIGURE\n");
+		return Codec_DrvQueryConfigure( (CodecImpl*)dwDriverId );
+	case DRV_CONFIGURE:
+		TRACE("DRV_CONFIGURE\n");
+		return Codec_DrvConfigure( (CodecImpl*)dwDriverId,
+					(HWND)lParam1, (DRVCONFIGINFO*)lParam2 );
+	case DRV_INSTALL:
+		TRACE("DRV_INSTALL\n");
+		return DRVCNF_OK;
+	case DRV_REMOVE:
+		TRACE("DRV_REMOVE\n");
+		return 0;
+	case DRV_POWER:
+		TRACE("DRV_POWER\n");
+		return TRUE;
+
+	case ACMDM_DRIVER_NOTIFY:
+		return MMSYSERR_NOERROR;
+	case ACMDM_DRIVER_DETAILS:
+		return Codec_DriverDetails((ACMDRIVERDETAILSW*)lParam1);
+	case ACMDM_DRIVER_ABOUT:
+		TRACE("ACMDM_DRIVER_ABOUT\n");
+		return (lParam1 == -1) ? Codec_QueryAbout() : Codec_About( (HWND)lParam1 );
+
+	case ACMDM_HARDWARE_WAVE_CAPS_INPUT:
+		return MMSYSERR_NOTSUPPORTED;
+	case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT:
+		return MMSYSERR_NOTSUPPORTED;
+
+	case ACMDM_FORMATTAG_DETAILS:
+		return Codec_FormatTagDetails( (CodecImpl*)dwDriverId, (ACMFORMATTAGDETAILSW*)lParam1, (DWORD)lParam2 );
+	case ACMDM_FORMAT_DETAILS:
+		return Codec_FormatDetails( (CodecImpl*)dwDriverId, (ACMFORMATDETAILSW*)lParam1, (DWORD)lParam2 );
+	case ACMDM_FORMAT_SUGGEST:
+		return Codec_FormatSuggest( (CodecImpl*)dwDriverId, (ACMDRVFORMATSUGGEST*)lParam1 );
+
+	case ACMDM_FILTERTAG_DETAILS:
+		return Codec_FilterTagDetails( (CodecImpl*)dwDriverId, (ACMFILTERTAGDETAILSW*)lParam1, (DWORD)lParam2 );
+	case ACMDM_FILTER_DETAILS:
+		return Codec_FilterDetails( (CodecImpl*)dwDriverId, (ACMFILTERDETAILSW*)lParam1, (DWORD)lParam2 );
+
+	case ACMDM_STREAM_OPEN:
+		return Codec_StreamOpen( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1 );
+	case ACMDM_STREAM_CLOSE:
+		return Codec_StreamClose( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1 );
+	case ACMDM_STREAM_SIZE:
+		return Codec_StreamSize( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMSIZE*)lParam2 );
+	case ACMDM_STREAM_CONVERT:
+		return Codec_StreamConvert( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMHEADER*)lParam2 );
+	case ACMDM_STREAM_RESET:
+		return Codec_StreamReset( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (DWORD)lParam2 );
+	case ACMDM_STREAM_PREPARE:
+		return Codec_StreamPrepare( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMHEADER*)lParam2 );
+	case ACMDM_STREAM_UNPREPARE:
+		return Codec_StreamUnprepare( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMHEADER*)lParam2 );
+
+	}
+
+	return DefDriverProc( dwDriverId, hdrvr, msg, lParam1, lParam2 );
+}
+
+/***********************************************************************/
+
+BOOL WINAPI IMAADP32_DllMain( HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved )
+{
+	TRACE( "(%08x,%08lx,%p)\n",hInst,dwReason,lpvReserved );
+
+	return TRUE;
+}
diff --git a/documentation/samples/system.ini b/documentation/samples/system.ini
index c10a7d4..6c0c33c 100644
--- a/documentation/samples/system.ini
+++ b/documentation/samples/system.ini
@@ -10,4 +10,5 @@
 [drivers32]
 VIDC.MRLE=msrle32.dll
 msacm.msg711=msg711.drv
+msacm.imaadp32=imaadp32.acm