diff --git a/dlls/msvideo/drawdib.c b/dlls/msvideo/drawdib.c
index 7bfff98ceec1269c002d2daaacfbcec714f99f22..2cc61cad50e4614a5d9f3b229e750769ac557e02 100644
--- a/dlls/msvideo/drawdib.c
+++ b/dlls/msvideo/drawdib.c
@@ -21,33 +21,32 @@
  */
 
 #include <string.h>
-#include "windef.h"
-#include "winbase.h"
+#include "msvideo_private.h"
+
 #include "wingdi.h"
 #include "winuser.h"
-#include "wine/winbase16.h"
+
 #include "wine/debug.h"
-#include "vfw.h"
-#include "msvideo_private.h"
-#include "windef.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
 
-typedef struct {
-	HDC hdc;
-	INT dxDst;
-	INT dyDst;
-	LPBITMAPINFOHEADER lpbi;
-	INT dxSrc;
-	INT dySrc;
-	HPALETTE hpal;				/* Palette to use for the DIB */
-	BOOL begun;					/* DrawDibBegin has been called */
-	LPBITMAPINFOHEADER lpbiOut;	/* Output format */
-	HIC hic;					/* HIC for decompression */
-	HDC hMemDC;					/* DC for buffering */
-	HBITMAP hOldDib;			/* Original Dib */
-	HBITMAP hDib;				/* DibSection */
-	LPVOID lpvbits;				/* Buffer for holding decompressed dib */
+typedef struct tagWINE_HDD {
+    HDC                 hdc;
+    INT                 dxDst;
+    INT                 dyDst;
+    LPBITMAPINFOHEADER  lpbi;
+    INT                 dxSrc;
+    INT                 dySrc;
+    HPALETTE            hpal;		/* Palette to use for the DIB */
+    BOOL                begun;		/* DrawDibBegin has been called */
+    LPBITMAPINFOHEADER  lpbiOut;	/* Output format */
+    HIC                 hic;		/* HIC for decompression */
+    HDC                 hMemDC;		/* DC for buffering */
+    HBITMAP             hOldDib;	/* Original Dib */
+    HBITMAP             hDib;		/* DibSection */
+    LPVOID              lpvbits;	/* Buffer for holding decompressed dib */
+    HDRAWDIB            hSelf;
+    struct tagWINE_HDD* next;
 } WINE_HDD;
 
 int num_colours(LPBITMAPINFOHEADER lpbi)
@@ -59,268 +58,313 @@ int num_colours(LPBITMAPINFOHEADER lpbi)
 	return 0;
 }
 
-/***********************************************************************
- *		DrawDibOpen		[MSVFW32.@]
- */
-HDRAWDIB VFWAPI DrawDibOpen(void) {
-	HDRAWDIB hdd;
+static WINE_HDD*        HDD_FirstHdd /* = NULL */;
+
+static WINE_HDD*       MSVIDEO_GetHddPtr(HDRAWDIB hd)
+{
+    WINE_HDD*   hdd;
 
-	TRACE("(void)\n");
-	hdd = HDRAWDIB_32(GlobalAlloc16(GHND,sizeof(WINE_HDD)));
-	TRACE("=> %p\n",hdd);
-	return hdd;
+    for (hdd = HDD_FirstHdd; hdd != NULL && hdd->hSelf != hdd; hdd = hdd->next);
+    return hdd;
 }
 
+static DWORD HDD_HandleRef = 1;
+
 /***********************************************************************
- *		DrawDibClose		[MSVFW32.@]
+ *		DrawDibOpen		[MSVFW32.@]
  */
-BOOL VFWAPI DrawDibClose(HDRAWDIB hdd) {
-	WINE_HDD *whdd = GlobalLock16(HDRAWDIB_16(hdd));
+HDRAWDIB VFWAPI DrawDibOpen(void) 
+{
+    WINE_HDD*   whdd;
 
-	TRACE("(%p)\n",hdd);
+    TRACE("(void)\n");
+	
+    whdd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_HDD));
+    TRACE("=> %p\n", whdd);
 
-	if (!whdd)
-		return FALSE;
+    while (MSVIDEO_GetHddPtr((HDRAWDIB)HDD_HandleRef) != NULL) HDD_HandleRef++;
+    whdd->hSelf = (HDRAWDIB)HDD_HandleRef++;
 
-	if (whdd->begun)
-		DrawDibEnd(hdd);
+    whdd->next = HDD_FirstHdd;
+    HDD_FirstHdd = whdd;
 
-	GlobalUnlock16(HDRAWDIB_16(hdd));
-	GlobalFree16(HDRAWDIB_16(hdd));
-	return TRUE;
+    return whdd->hSelf;
 }
 
 /***********************************************************************
- *		DrawDibEnd		[MSVFW32.@]
+ *		DrawDibClose		[MSVFW32.@]
  */
-BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) {
-	BOOL ret = TRUE;
-	WINE_HDD *whdd = GlobalLock16(HDRAWDIB_16(hdd));
-
-	TRACE("(%p)\n",hdd);
-
-	whdd->hpal = 0; /* Do not free this */
-	whdd->hdc = 0;
-	if (whdd->lpbi) {
-		HeapFree(GetProcessHeap(),0,whdd->lpbi);
-		whdd->lpbi = NULL;
-	}
-	if (whdd->lpbiOut) {
-		HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
-		whdd->lpbiOut = NULL;
-	}
-
-	whdd->begun = FALSE;
+BOOL VFWAPI DrawDibClose(HDRAWDIB hdd) 
+{
+    WINE_HDD* whdd = MSVIDEO_GetHddPtr(hdd);
 
-	/*if (whdd->lpvbits)
-	  HeapFree(GetProcessHeap(),0,whdd->lpvbuf);*/
+    TRACE("(%p)\n", hdd);
 
-	if (whdd->hMemDC) {
-		SelectObject(whdd->hMemDC,whdd->hOldDib);
-		DeleteDC(whdd->hMemDC);
-	}
+    if (!whdd) return FALSE;
 
-	if (whdd->hDib)
-		DeleteObject(whdd->hDib);
+    if (whdd->begun) DrawDibEnd(hdd);
 
-	if (whdd->hic) {
-		ICDecompressEnd(whdd->hic);
-		ICClose(whdd->hic);
-	}
+    HeapFree(GetProcessHeap(), 0, whdd);
 
-	whdd->lpvbits = NULL;
+    return TRUE;
+}
 
-	GlobalUnlock16(HDRAWDIB_16(hdd));
-	return ret;
+/***********************************************************************
+ *		DrawDibEnd		[MSVFW32.@]
+ */
+BOOL VFWAPI DrawDibEnd(HDRAWDIB hdd) 
+{
+    BOOL ret = TRUE;
+    WINE_HDD *whdd = MSVIDEO_GetHddPtr(hdd);
+
+    TRACE("(%p)\n", hdd);
+
+    whdd->hpal = 0; /* Do not free this */
+    whdd->hdc = 0;
+    if (whdd->lpbi) 
+    {
+        HeapFree(GetProcessHeap(), 0, whdd->lpbi);
+        whdd->lpbi = NULL;
+    }
+    if (whdd->lpbiOut) 
+    {
+        HeapFree(GetProcessHeap(), 0, whdd->lpbiOut);
+        whdd->lpbiOut = NULL;
+    }
+
+    whdd->begun = FALSE;
+
+    /*if (whdd->lpvbits)
+      HeapFree(GetProcessHeap(), 0, whdd->lpvbuf);*/
+
+    if (whdd->hMemDC) 
+    {
+        SelectObject(whdd->hMemDC, whdd->hOldDib);
+        DeleteDC(whdd->hMemDC);
+        whdd->hMemDC = 0;
+    }
+
+    if (whdd->hDib) DeleteObject(whdd->hDib);
+    whdd->hDib = 0;
+
+    if (whdd->hic) 
+    {
+        ICDecompressEnd(whdd->hic);
+        ICClose(whdd->hic);
+        whdd->hic = 0;
+    }
+
+    whdd->lpvbits = NULL;
+
+    return ret;
 }
 
 /***********************************************************************
  *              DrawDibBegin            [MSVFW32.@]
  */
 BOOL VFWAPI DrawDibBegin(HDRAWDIB hdd,
-						 HDC      hdc,
-						 INT      dxDst,
-						 INT      dyDst,
-						 LPBITMAPINFOHEADER lpbi,
-						 INT      dxSrc,
-						 INT      dySrc,
-						 UINT     wFlags) {
-	BOOL ret = TRUE;
-	WINE_HDD *whdd;
-
-	TRACE("(%p,%p,%d,%d,%p,%d,%d,0x%08lx)\n",
-		hdd,hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,(DWORD)wFlags
-	);
-	TRACE("lpbi: %ld,%ld/%ld,%d,%d,%ld,%ld,%ld,%ld,%ld,%ld\n",
-		  lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes,
-		  lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage,
-		  lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed,
-		  lpbi->biClrImportant);
-
-	if (wFlags & ~(DDF_BUFFER))
-		FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));
-
-	whdd = (WINE_HDD*)GlobalLock16(HDRAWDIB_16(hdd));
-	if (!whdd) return FALSE;
-
-	if (whdd->begun)
-		DrawDibEnd(hdd);
-
-	if (lpbi->biCompression) {
-		DWORD size = 0;
-
-		whdd->hic = ICOpen(ICTYPE_VIDEO,lpbi->biCompression,ICMODE_DECOMPRESS);
-		if (!whdd->hic) {
-			WARN("Could not open IC. biCompression == 0x%08lx\n",lpbi->biCompression);
-			ret = FALSE;
-		}
-
-		if (ret) {
-			size = ICDecompressGetFormat(whdd->hic,lpbi,NULL);
-			if (size == ICERR_UNSUPPORTED) {
-				WARN("Codec doesn't support GetFormat, giving up.\n");
-				ret = FALSE;
-			}
-		}
-
-		if (ret) {
-			whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,size);
-
-			if (ICDecompressGetFormat(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
-				ret = FALSE;
-		}
-
-		if (ret) {
-			/* FIXME: Use Ex functions if available? */
-			if (ICDecompressBegin(whdd->hic,lpbi,whdd->lpbiOut) != ICERR_OK)
-				ret = FALSE;
-
-			TRACE("biSizeImage == %ld\n",whdd->lpbiOut->biSizeImage);
-			TRACE("biCompression == %ld\n",whdd->lpbiOut->biCompression);
-			TRACE("biBitCount == %d\n",whdd->lpbiOut->biBitCount);
-		}
-	} else {
-		DWORD dwSize;
-		/* No compression */
-		TRACE("Not compressed!\n");
-		dwSize = lpbi->biSize + num_colours(lpbi)*sizeof(RGBQUAD);
-		whdd->lpbiOut = HeapAlloc(GetProcessHeap(),0,dwSize);
-		memcpy(whdd->lpbiOut,lpbi,dwSize);
-	}
-
-	if (ret) {
-		/*whdd->lpvbuf = HeapAlloc(GetProcessHeap(),0,whdd->lpbiOut->biSizeImage);*/
-
-		whdd->hMemDC = CreateCompatibleDC(hdc);
-		TRACE("Creating: %ld,%p\n",whdd->lpbiOut->biSize,whdd->lpvbits);
-		whdd->hDib = CreateDIBSection(whdd->hMemDC,(BITMAPINFO *)whdd->lpbiOut,DIB_RGB_COLORS,&(whdd->lpvbits),0,0);
-		if (!whdd->hDib) {
-			TRACE("Error: %ld\n",GetLastError());
-		}
-		TRACE("Created: %p,%p\n",whdd->hDib,whdd->lpvbits);
-		whdd->hOldDib = SelectObject(whdd->hMemDC,whdd->hDib);
-	}
-
-	if (ret) {
-		whdd->hdc = hdc;
-		whdd->dxDst = dxDst;
-		whdd->dyDst = dyDst;
-		whdd->lpbi = HeapAlloc(GetProcessHeap(),0,lpbi->biSize);
-		memcpy(whdd->lpbi,lpbi,lpbi->biSize);
-		whdd->dxSrc = dxSrc;
-		whdd->dySrc = dySrc;
-		whdd->begun = TRUE;
-		whdd->hpal = 0;
-	} else {
-		if (whdd->hic)
-			ICClose(whdd->hic);
-		if (whdd->lpbiOut) {
-			HeapFree(GetProcessHeap(),0,whdd->lpbiOut);
-			whdd->lpbiOut = NULL;
-		}
-	}
-
-	GlobalUnlock16(HDRAWDIB_16(hdd));
-
-	return ret;
+                         HDC      hdc,
+                         INT      dxDst,
+                         INT      dyDst,
+                         LPBITMAPINFOHEADER lpbi,
+                         INT      dxSrc,
+                         INT      dySrc,
+                         UINT     wFlags) 
+{
+    BOOL ret = TRUE;
+    WINE_HDD *whdd;
+
+    TRACE("(%p,%p,%d,%d,%p,%d,%d,0x%08lx)\n",
+          hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, (DWORD)wFlags);
+
+    TRACE("lpbi: %ld,%ld/%ld,%d,%d,%ld,%ld,%ld,%ld,%ld,%ld\n",
+          lpbi->biSize, lpbi->biWidth, lpbi->biHeight, lpbi->biPlanes,
+          lpbi->biBitCount, lpbi->biCompression, lpbi->biSizeImage,
+          lpbi->biXPelsPerMeter, lpbi->biYPelsPerMeter, lpbi->biClrUsed,
+          lpbi->biClrImportant);
+
+    if (wFlags & ~(DDF_BUFFER))
+        FIXME("wFlags == 0x%08x not handled\n", wFlags & ~(DDF_BUFFER));
+
+    whdd = MSVIDEO_GetHddPtr(hdd);
+    if (!whdd) return FALSE;
+
+    if (whdd->begun) DrawDibEnd(hdd);
+
+    if (lpbi->biCompression) 
+    {
+        DWORD size = 0;
+
+        whdd->hic = ICOpen(ICTYPE_VIDEO, lpbi->biCompression, ICMODE_DECOMPRESS);
+        if (!whdd->hic) 
+        {
+            WARN("Could not open IC. biCompression == 0x%08lx\n", lpbi->biCompression);
+            ret = FALSE;
+        }
+
+        if (ret) 
+        {
+            size = ICDecompressGetFormat(whdd->hic, lpbi, NULL);
+            if (size == ICERR_UNSUPPORTED) 
+            {
+                WARN("Codec doesn't support GetFormat, giving up.\n");
+                ret = FALSE;
+            }
+        }
+
+        if (ret) 
+        {
+            whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, size);
+
+            if (ICDecompressGetFormat(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK)
+                ret = FALSE;
+        }
+
+        if (ret) 
+        {
+            /* FIXME: Use Ex functions if available? */
+            if (ICDecompressBegin(whdd->hic, lpbi, whdd->lpbiOut) != ICERR_OK)
+                ret = FALSE;
+            
+            TRACE("biSizeImage == %ld\n", whdd->lpbiOut->biSizeImage);
+            TRACE("biCompression == %ld\n", whdd->lpbiOut->biCompression);
+            TRACE("biBitCount == %d\n", whdd->lpbiOut->biBitCount);
+        }
+    }
+    else 
+    {
+        DWORD dwSize;
+        /* No compression */
+        TRACE("Not compressed!\n");
+        dwSize = lpbi->biSize + num_colours(lpbi)*sizeof(RGBQUAD);
+        whdd->lpbiOut = HeapAlloc(GetProcessHeap(), 0, dwSize);
+        memcpy(whdd->lpbiOut, lpbi, dwSize);
+    }
+
+    if (ret) 
+    {
+        /*whdd->lpvbuf = HeapAlloc(GetProcessHeap(), 0, whdd->lpbiOut->biSizeImage);*/
+
+        whdd->hMemDC = CreateCompatibleDC(hdc);
+        TRACE("Creating: %ld, %p\n", whdd->lpbiOut->biSize, whdd->lpvbits);
+        whdd->hDib = CreateDIBSection(whdd->hMemDC, (BITMAPINFO *)whdd->lpbiOut, DIB_RGB_COLORS, &(whdd->lpvbits), 0, 0);
+        if (!whdd->hDib) 
+        {
+            TRACE("Error: %ld\n", GetLastError());
+        }
+        TRACE("Created: %p,%p\n", whdd->hDib, whdd->lpvbits);
+        whdd->hOldDib = SelectObject(whdd->hMemDC, whdd->hDib);
+    }
+
+    if (ret) 
+    {
+        whdd->hdc = hdc;
+        whdd->dxDst = dxDst;
+        whdd->dyDst = dyDst;
+        whdd->lpbi = HeapAlloc(GetProcessHeap(), 0, lpbi->biSize);
+        memcpy(whdd->lpbi, lpbi, lpbi->biSize);
+        whdd->dxSrc = dxSrc;
+        whdd->dySrc = dySrc;
+        whdd->begun = TRUE;
+        whdd->hpal = 0;
+    } 
+    else 
+    {
+        if (whdd->hic)
+            ICClose(whdd->hic);
+        if (whdd->lpbiOut) 
+        {
+            HeapFree(GetProcessHeap(), 0, whdd->lpbiOut);
+            whdd->lpbiOut = NULL;
+        }
+    }
+
+    return ret;
 }
 
 /**********************************************************************
  *		DrawDibDraw		[MSVFW32.@]
  */
 BOOL VFWAPI DrawDibDraw(HDRAWDIB hdd, HDC hdc,
-	INT xDst, INT yDst, INT dxDst, INT dyDst,
-	LPBITMAPINFOHEADER lpbi,
-	LPVOID lpBits,
-	INT xSrc, INT ySrc, INT dxSrc, INT dySrc,
-	UINT wFlags
-) {
-	WINE_HDD *whdd;
-	BOOL ret = TRUE;
-
-	TRACE("(%p,%p,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08lx)\n",
-		  hdd,hdc,xDst,yDst,dxDst,dyDst,lpbi,lpBits,xSrc,ySrc,dxSrc,dySrc,(DWORD)wFlags
-	);
-
-	if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME |
-				   DDF_UPDATE | DDF_DONTDRAW))
-		FIXME("wFlags == 0x%08lx not handled\n",(DWORD)wFlags);
-
-	if (!lpBits) {
-		/* Undocumented? */
-		lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(num_colours(lpbi)*sizeof(RGBQUAD));
-	}
-
-	whdd = GlobalLock16(HDRAWDIB_16(hdd));
-
-#define CHANGED(x) (whdd->x != x)
-
-	if ((!whdd->begun) || (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) || (!(wFlags & DDF_SAME_DRAW) &&
-		 (CHANGED(lpbi) || CHANGED(dxSrc) || CHANGED(dySrc) || CHANGED(dxDst) || CHANGED(dyDst)))) {
-		TRACE("Something changed!\n");
-		ret = DrawDibBegin(hdd,hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,0);
-	}
+                        INT xDst, INT yDst, INT dxDst, INT dyDst,
+                        LPBITMAPINFOHEADER lpbi,
+                        LPVOID lpBits,
+                        INT xSrc, INT ySrc, INT dxSrc, INT dySrc,
+                        UINT wFlags)
+{
+    WINE_HDD *whdd;
+    BOOL ret = TRUE;
 
-#undef CHANGED
+    TRACE("(%p,%p,%d,%d,%d,%d,%p,%p,%d,%d,%d,%d,0x%08lx)\n",
+          hdd, hdc, xDst, yDst, dxDst, dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, (DWORD)wFlags);
 
-        if ((dxDst == -1) && (dyDst == -1)) {
-		dxDst = dxSrc;
-		dyDst = dySrc;
-	}
+    whdd = MSVIDEO_GetHddPtr(hdd);
+    if (whdd) return FALSE;
 
-	if (!(wFlags & DDF_UPDATE)) {
-	    /* biSizeImage may be set to 0 for BI_RGB (uncompressed) bitmaps */
-	    if ((lpbi->biCompression == BI_RGB) && (lpbi->biSizeImage == 0))
-		    lpbi->biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight;
+    if (wFlags & ~(DDF_SAME_HDC | DDF_SAME_DRAW | DDF_NOTKEYFRAME | DDF_UPDATE | DDF_DONTDRAW))
+        FIXME("wFlags == 0x%08lx not handled\n", (DWORD)wFlags);
 
-		if (lpbi->biCompression) {
-		    DWORD flags = 0;
+    if (!lpBits) 
+    {
+        /* Undocumented? */
+        lpBits = (LPSTR)lpbi + (WORD)(lpbi->biSize) + (WORD)(num_colours(lpbi)*sizeof(RGBQUAD));
+    }
 
-			TRACE("Compression == 0x%08lx\n",lpbi->biCompression);
 
-			if (wFlags & DDF_NOTKEYFRAME)
-			    flags |= ICDECOMPRESS_NOTKEYFRAME;
+#define CHANGED(x) (whdd->x != x)
 
-			ICDecompress(whdd->hic,flags,lpbi,lpBits,whdd->lpbiOut,whdd->lpvbits);
-		} else {
-		    memcpy(whdd->lpvbits,lpBits,lpbi->biSizeImage);
-		}
-	}
-	if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
-	    SelectPalette(hdc,whdd->hpal,FALSE);
+    if ((!whdd->begun) || 
+        (!(wFlags & DDF_SAME_HDC) && CHANGED(hdc)) || 
+        (!(wFlags & DDF_SAME_DRAW) && (CHANGED(lpbi) || CHANGED(dxSrc) || CHANGED(dySrc) || CHANGED(dxDst) || CHANGED(dyDst)))) 
+    {
+        TRACE("Something changed!\n");
+        ret = DrawDibBegin(hdd, hdc, dxDst, dyDst, lpbi, dxSrc, dySrc, 0);
+    }
 
-	if (!(StretchBlt(whdd->hdc,xDst,yDst,dxDst,dyDst,whdd->hMemDC,xSrc,ySrc,dxSrc,dySrc,SRCCOPY)))
-	    ret = FALSE;
+#undef CHANGED
 
-	GlobalUnlock16(HDRAWDIB_16(hdd));
-	return ret;
+    if ((dxDst == -1) && (dyDst == -1)) 
+    {
+        dxDst = dxSrc;
+        dyDst = dySrc;
+    }
+
+    if (!(wFlags & DDF_UPDATE)) 
+    {
+        /* biSizeImage may be set to 0 for BI_RGB (uncompressed) bitmaps */
+        if ((lpbi->biCompression == BI_RGB) && (lpbi->biSizeImage == 0))
+            lpbi->biSizeImage = ((lpbi->biWidth * lpbi->biBitCount + 31) / 32) * 4 * lpbi->biHeight;
+
+        if (lpbi->biCompression) 
+        {
+            DWORD flags = 0;
+
+            TRACE("Compression == 0x%08lx\n", lpbi->biCompression);
+
+            if (wFlags & DDF_NOTKEYFRAME)
+                flags |= ICDECOMPRESS_NOTKEYFRAME;
+
+            ICDecompress(whdd->hic, flags, lpbi, lpBits, whdd->lpbiOut, whdd->lpvbits);
+        }
+        else
+        {
+            memcpy(whdd->lpvbits, lpBits, lpbi->biSizeImage);
+        }
+    }
+    if (!(wFlags & DDF_DONTDRAW) && whdd->hpal)
+        SelectPalette(hdc, whdd->hpal, FALSE);
+
+    if (!(StretchBlt(whdd->hdc, xDst, yDst, dxDst, dyDst, whdd->hMemDC, xSrc, ySrc, dxSrc, dySrc, SRCCOPY)))
+        ret = FALSE;
+    
+    return ret;
 }
 
 /*************************************************************************
  *		DrawDibStart		[MSVFW32.@]
  */
 BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
-	FIXME("(%p,%ld), stub\n",hdd,rate);
+	FIXME("(%p, %ld), stub\n", hdd, rate);
 	return TRUE;
 }
 
@@ -328,70 +372,75 @@ BOOL VFWAPI DrawDibStart(HDRAWDIB hdd, DWORD rate) {
  *		DrawDibStop		[MSVFW32.@]
  */
 BOOL VFWAPI DrawDibStop(HDRAWDIB hdd) {
-	FIXME("(%p), stub\n",hdd);
+	FIXME("(%p), stub\n", hdd);
 	return TRUE;
 }
 
 /***********************************************************************
  *              DrawDibSetPalette       [MSVFW32.@]
  */
-BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal) {
-	WINE_HDD *whdd;
+BOOL VFWAPI DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal) 
+{
+    WINE_HDD *whdd;
 
-	TRACE("(%p,%p)\n",hdd,hpal);
+    TRACE("(%p, %p)\n", hdd, hpal);
 
-	whdd = GlobalLock16(HDRAWDIB_16(hdd));
-	whdd->hpal = hpal;
+    whdd = MSVIDEO_GetHddPtr(hdd);
+    if (!whdd) return FALSE;
 
-	if (whdd->begun) {
-		SelectPalette(whdd->hdc,hpal,0);
-		RealizePalette(whdd->hdc);
-	}
-	GlobalUnlock16(HDRAWDIB_16(hdd));
-	return TRUE;
+    whdd->hpal = hpal;
+
+    if (whdd->begun) 
+    {
+        SelectPalette(whdd->hdc, hpal, 0);
+        RealizePalette(whdd->hdc);
+    }
+
+    return TRUE;
 }
 
 /***********************************************************************
  *              DrawDibGetPalette       [MSVFW32.@]
  */
-HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) {
-	WINE_HDD *whdd;
-	HPALETTE ret;
+HPALETTE VFWAPI DrawDibGetPalette(HDRAWDIB hdd) 
+{
+    WINE_HDD *whdd;
+
+    TRACE("(%p)\n", hdd);
 
-	TRACE("(%p)\n",hdd);
+    whdd = MSVIDEO_GetHddPtr(hdd);
+    if (!whdd) return FALSE;
 
-	whdd = GlobalLock16(HDRAWDIB_16(hdd));
-	ret = whdd->hpal;
-	GlobalUnlock16(HDRAWDIB_16(hdd));
-	return ret;
+    return whdd->hpal;
 }
 
 /***********************************************************************
  *              DrawDibRealize          [MSVFW32.@]
  */
-UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) {
-	WINE_HDD *whdd;
-	HPALETTE oldPal;
-	UINT ret = 0;
+UINT VFWAPI DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground) 
+{
+    WINE_HDD *whdd;
+    HPALETTE oldPal;
+    UINT ret = 0;
 
-	FIXME("(%p,%p,%d), stub\n",hdd,hdc,fBackground);
+    FIXME("(%p, %p, %d), stub\n", hdd, hdc, fBackground);
 
-	whdd = GlobalLock16(HDRAWDIB_16(hdd));
+    whdd = MSVIDEO_GetHddPtr(hdd);
+    if (!whdd) return FALSE;
 
-	if (!whdd || !(whdd->begun)) {
-		ret = 0;
-		goto out;
-	}
+    if (!whdd || !(whdd->begun)) 
+    {
+        ret = 0;
+        goto out;
+    }
 
-	if (!whdd->hpal)
-		whdd->hpal = CreateHalftonePalette(hdc);
+    if (!whdd->hpal)
+        whdd->hpal = CreateHalftonePalette(hdc);
 
-	oldPal = SelectPalette(hdc,whdd->hpal,fBackground);
-	ret = RealizePalette(hdc);
+    oldPal = SelectPalette(hdc, whdd->hpal, fBackground);
+    ret = RealizePalette(hdc);
 
  out:
-	GlobalUnlock16(HDRAWDIB_16(hdd));
-
-	TRACE("=> %u\n",ret);
-	return ret;
+    TRACE("=> %u\n", ret);
+    return ret;
 }
diff --git a/dlls/msvideo/msvideo16.c b/dlls/msvideo/msvideo16.c
index c12c60b03e2c75e0d116dd71032b725fbd2794bd..ede5e28239d02a00cc2e1d0748308554654ed9b6 100644
--- a/dlls/msvideo/msvideo16.c
+++ b/dlls/msvideo/msvideo16.c
@@ -22,12 +22,9 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "winbase.h"
-#include "windef.h"
+#include "msvideo_private.h"
 #include "winver.h"
-#include "vfw.h"
 #include "vfw16.h"
-#include "msvideo_private.h"
 #include "stackframe.h"
 #include "wine/debug.h"
 
@@ -106,7 +103,7 @@ BOOL16 VFWAPI DrawDibSetPalette16(HDRAWDIB16 hdd, HPALETTE16 hpal)
 UINT16 VFWAPI DrawDibRealize16(HDRAWDIB16 hdd, HDC16 hdc,
 			       BOOL16 fBackground)
 {
-    return (UINT16) DrawDibRealize(HDRAWDIB_32(hdd), HDC_32(hdc), fBackground);
+    return (UINT16)DrawDibRealize(HDRAWDIB_32(hdd), HDC_32(hdc), fBackground);
 }
 
 /*************************************************************************
@@ -685,7 +682,7 @@ static  LRESULT CALLBACK  IC_Callback3216(HIC hic, HDRVR hdrv, UINT msg, DWORD l
     WINE_HIC*   whic;
     LRESULT     ret = 0;
 
-    whic = GlobalLock16(HIC_16(hic));
+    whic = MSVIDEO_GetHicPtr(hic);
     if (whic)
     {
         switch (msg)
@@ -703,9 +700,8 @@ static  LRESULT CALLBACK  IC_Callback3216(HIC hic, HDRVR hdrv, UINT msg, DWORD l
             UnMapLS(lp2);
             break;
         }
-        GlobalUnlock16(HIC_16(hic));
     }
-    else ret = MMSYSERR_ERROR;
+    else ret = ICERR_BADHANDLE;
     return ret;
 }
 
@@ -717,7 +713,7 @@ HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FAR
     HIC         hic32;
 
     hic32 = MSVIDEO_OpenFunction(fccType, fccHandler, wMode, 
-                                 (DRIVERPROC)IC_Callback3216, (DRIVERPROC16)lpfnHandler);
+                                 (DRIVERPROC)IC_Callback3216, (DWORD)lpfnHandler);
     return HIC_16(hic32);
 }
 
@@ -726,10 +722,10 @@ HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FAR
  */
 LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) 
 {
-    LRESULT     ret = MMSYSERR_ERROR;
+    LRESULT     ret = ICERR_BADHANDLE;
     WINE_HIC*   whic;
 
-    whic = GlobalLock16(hic);
+    whic = MSVIDEO_GetHicPtr(HIC_32(hic));
     if (whic)
     {
         /* we've got a 16 bit driver proc... call it directly */
@@ -747,7 +743,6 @@ LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lPara
             if (data16)
                 MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2);
         }
-        GlobalUnlock16(hic);
     }
     return ret;
 }
@@ -841,7 +836,7 @@ DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len,
 static  LRESULT CALLBACK IC_CallTo16(HDRVR hdrv, HIC hic, UINT msg, LPARAM lp1, LPARAM lp2)
 {
 #if 0
-    WINE_HIC*   whic = GlobalLock16(HIC_16(hic));
+    WINE_HIC*   whic = IC_GetPtr(hic);
     LRESULT     ret = 0;
     
     
diff --git a/dlls/msvideo/msvideo_main.c b/dlls/msvideo/msvideo_main.c
index 9fbc380aef2c513bf124af06622cfff471f018ea..64a94ab49dee9d13bc25d048093b82384b5bfbb2 100644
--- a/dlls/msvideo/msvideo_main.c
+++ b/dlls/msvideo/msvideo_main.c
@@ -19,24 +19,40 @@
  * FIXME: This all assumes 32 bit codecs
  *		Win95 appears to prefer 32 bit codecs, even from 16 bit code.
  *		There is the ICOpenFunction16 to worry about still, though.
+ *      
+ * TODO
+ *      - no thread safety
+ *      - the four CC comparisons are wrong on big endian machines
  */
 
 #include <stdio.h>
 #include <string.h>
 
-#include "winbase.h"
-#include "windef.h"
+#include "msvideo_private.h"
 #include "wingdi.h"
 #include "winuser.h"
-#include "vfw.h"
-#include "wine/winbase16.h"
+
 #include "wine/debug.h"
-#include "msvideo_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
 
 LRESULT (CALLBACK *pFnCallTo16)(HDRVR, HIC, UINT, LPARAM, LPARAM) = NULL;
 
+static WINE_HIC*        MSVIDEO_FirstHic /* = NULL */;
+
+/******************************************************************
+ *		MSVIDEO_GetHicPtr
+ *
+ *
+ */
+WINE_HIC*   MSVIDEO_GetHicPtr(HIC hic)
+{
+    WINE_HIC*   whic;
+
+    for (whic = MSVIDEO_FirstHic; whic && whic->hic != hic; whic = whic->next);
+    return whic;
+}
+
 /***********************************************************************
  *		VideoForWindowsVersion		[MSVFW32.2]
  *		VideoForWindowsVersion		[MSVIDEO.2]
@@ -60,141 +76,166 @@ BOOL VFWAPI ICInfo(
 	DWORD fccHandler,	/* [in] <n>th compressor */
 	ICINFO *lpicinfo)	/* [out] information about compressor */
 {
-	char	type[5],buf[2000];
-
-	memcpy(type,&fccType,4);type[4]=0;
-	TRACE("(%s,%ld,%p).\n",type,fccHandler,lpicinfo);
-	/* does OpenDriver/CloseDriver */
-	lpicinfo->dwSize = sizeof(ICINFO);
-	lpicinfo->fccType = fccType;
-	lpicinfo->dwFlags = 0;
-	if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,2000,"system.ini")) {
-		char *s = buf;
-		while (*s) {
-			if (!strncasecmp(type,s,4)) {
-				if(!fccHandler--) {
-					lpicinfo->fccHandler = mmioStringToFOURCCA(s+5,0);
-					return TRUE;
-				}
-			}
-			s=s+strlen(s)+1; /* either next char or \0 */
-		}
-	}
-	return FALSE;
+    char	buf[2000];
+
+    TRACE("(%.4s,%.4s,%p)\n", (char*)&fccType, (char*)&fccHandler, lpicinfo);
+
+    if (GetPrivateProfileStringA("drivers32", NULL, NULL, buf, sizeof(buf), "system.ini")) 
+    {
+        char *s = buf;
+        while (*s) 
+        {
+            if (!strncasecmp((char*)&fccType, s, 4) && s[4] == '.' && s[9] == '=')
+            {
+                if (!fccHandler--) 
+                {
+                    HIC hic;
+
+                    lpicinfo->fccHandler = mmioStringToFOURCCA(s + 5, 0);
+                    hic = ICOpen(fccType, lpicinfo->fccHandler, ICMODE_QUERY);
+                    if (hic)
+                    {
+                        ICGetInfo(hic, lpicinfo, lpicinfo->dwSize);
+                        ICClose(hic);
+                        return TRUE;
+                    }
+                    return FALSE;
+                }
+            }
+            s += strlen(s) + 1; /* either next char or \0 */
+        }
+    }
+    return FALSE;
 }
 
+static DWORD IC_HandleRef = 1;
+
 /***********************************************************************
  *		ICOpen				[MSVFW32.@]
  * Opens an installable compressor. Return special handle.
  */
-HIC VFWAPI ICOpen(DWORD fccType,DWORD fccHandler,UINT wMode) {
-	char		type[5],handler[5],codecname[20];
-	ICOPEN		icopen;
-	HDRVR		hdrv;
-	HIC		hic;
-	WINE_HIC	*whic;
-        BOOL            bIs16;
-
-	memcpy(type,&fccType,4);type[4]=0;
-	memcpy(handler,&fccHandler,4);handler[4]=0;
-	TRACE("(%s,%s,0x%08lx)\n",type,handler,(DWORD)wMode);
-
-	sprintf(codecname,"%s.%s",type,handler);
-
-	/* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
-	 * same layout as ICOPEN
-	 */
-	icopen.dwSize		= sizeof(ICOPEN);
-	icopen.fccType		= fccType;
-	icopen.fccHandler	= fccHandler;
-        icopen.dwVersion        = 0x00001000; /* FIXME */
-	icopen.dwFlags		= wMode;
-        icopen.dwError          = 0;
-        icopen.pV1Reserved      = NULL;
-        icopen.pV2Reserved      = NULL;
-        icopen.dnDevNode        = 0; /* FIXME */
+HIC VFWAPI ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode) 
+{
+    char		codecname[20];
+    ICOPEN		icopen;
+    HDRVR		hdrv;
+    WINE_HIC*           whic;
+    BOOL                bIs16;
+
+    TRACE("(%.4s,%.4s,0x%08lx)\n", (char*)&fccType, (char*)&fccHandler, (DWORD)wMode);
+
+    sprintf(codecname, "%.4s.%.4s", (char*)&fccType, (char*)&fccHandler);
+
+    /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
+     * same layout as ICOPEN
+     */
+    icopen.dwSize		= sizeof(ICOPEN);
+    icopen.fccType		= fccType;
+    icopen.fccHandler	        = fccHandler;
+    icopen.dwVersion            = 0x00001000; /* FIXME */
+    icopen.dwFlags		= wMode;
+    icopen.dwError              = 0;
+    icopen.pV1Reserved          = NULL;
+    icopen.pV2Reserved          = NULL;
+    icopen.dnDevNode            = 0; /* FIXME */
         
-	hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
-	if (!hdrv) {
-	    if (!strcasecmp(type,"vids")) {
-		sprintf(codecname,"vidc.%s",handler);
-		fccType = mmioFOURCC('v','i','d','c');
-	    }
-	    hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
-	    if (!hdrv)
-		    return 0;
-	}
-        bIs16 = GetDriverFlags(hdrv) & WINE_GDF_16BIT;
-
-        if (bIs16 && !pFnCallTo16)
+    hdrv = OpenDriverA(codecname, "drivers32", (LPARAM)&icopen);
+    if (!hdrv) 
+    {
+        if (fccType == streamtypeVIDEO) 
         {
-            FIXME("Got a 16 bit driver, but no 16 bit support in msvfw\n");
-            return 0;
+            sprintf(codecname, "vidc.%.4s", (char*)&fccHandler);
+            fccType = ICTYPE_VIDEO;
+            hdrv = OpenDriverA(codecname, "drivers32", (LPARAM)&icopen);
         }
-	/* The handle should be a valid 16-bit handle as well */
-	hic = HIC_32(GlobalAlloc16(GHND,sizeof(WINE_HIC)));
-	whic = (WINE_HIC*)GlobalLock16(HIC_16(hic));
-	whic->hdrv	   = hdrv;
-        /* FIXME: is the signature the real one ? */
-	whic->driverproc   = bIs16 ? (DRIVERPROC)pFnCallTo16 : NULL;
-        whic->driverproc16 = NULL;
-
-	GlobalUnlock16(HIC_16(hic));
-	TRACE("=> %p\n",hic);
-	return HIC_32(hic);
+        if (!hdrv)
+            return 0;
+    }
+    bIs16 = GetDriverFlags(hdrv) & WINE_GDF_16BIT;
+
+    if (bIs16 && !pFnCallTo16)
+    {
+        FIXME("Got a 16 bit driver, but no 16 bit support in msvfw\n");
+        return 0;
+    }
+    whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC));
+    if (!whic)
+    {
+        CloseDriver(hdrv, 0, 0);
+        return FALSE;
+    }
+    whic->hdrv          = hdrv;
+    /* FIXME: is the signature the real one ? */
+    whic->driverproc    = bIs16 ? (DRIVERPROC)pFnCallTo16 : NULL;
+    whic->driverproc16  = 0;
+    whic->type          = fccType;
+    whic->handler       = fccHandler;
+    while (MSVIDEO_GetHicPtr(HIC_32(IC_HandleRef)) != NULL) IC_HandleRef++;
+    whic->hic           = HIC_32(IC_HandleRef++);
+    whic->next          = MSVIDEO_FirstHic;
+    MSVIDEO_FirstHic = whic;
+
+    TRACE("=> %p\n", whic->hic);
+    return whic->hic;
 }
 
 /***********************************************************************
  *		MSVIDEO_OpenFunction
  */
 HIC MSVIDEO_OpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, 
-                         DRIVERPROC lpfnHandler, DRIVERPROC16 lpfnHandler16) 
+                         DRIVERPROC lpfnHandler, DWORD lpfnHandler16) 
 {
-	char	type[5],handler[5],codecname[20];
-	HIC	hic;
-        ICOPEN icopen;
-	WINE_HIC	*whic;
-
-	memcpy(type,&fccType,4);type[4]=0;
-	memcpy(handler,&fccHandler,4);handler[4]=0;
-	TRACE("(%s,%s,%d,%p,%p)\n",type,handler,wMode,lpfnHandler,lpfnHandler16);
-
-        icopen.fccType    = fccType;
-        icopen.fccHandler = fccHandler;
-        icopen.dwSize     = sizeof(ICOPEN);
-        icopen.dwFlags    = wMode;
-
-        sprintf(codecname,"%s.%s",type,handler);
-
-	hic = HIC_32(GlobalAlloc16(GHND,sizeof(WINE_HIC)));
-	if (!hic)
-		return 0;
-	whic = GlobalLock16(HIC_16(hic));
-	whic->driverproc   = lpfnHandler;
-	whic->driverproc16 = lpfnHandler16;
-
-	/* Now try opening/loading the driver. Taken from DRIVER_AddToList */
-	/* What if the function is used more than once? */
-
-	if (MSVIDEO_SendMessage(hic,DRV_LOAD,0L,0L) != DRV_SUCCESS) {
-		WARN("DRV_LOAD failed for hic %p\n", hic);
-		GlobalFree16(HIC_16(hic));
-		return 0;
-	}
-	/* return value is not checked */
-	MSVIDEO_SendMessage(hic,DRV_ENABLE,0L,0L);
+    ICOPEN      icopen;
+    WINE_HIC*   whic;
+
+    TRACE("(%.4s,%.4s,%d,%p,%08lx)\n", 
+          (char*)&fccType, (char*)&fccHandler, wMode, lpfnHandler, lpfnHandler16);
+
+    icopen.dwSize		= sizeof(ICOPEN);
+    icopen.fccType		= fccType;
+    icopen.fccHandler	        = fccHandler;
+    icopen.dwVersion            = 0x00001000; /* FIXME */
+    icopen.dwFlags		= wMode;
+    icopen.dwError              = 0;
+    icopen.pV1Reserved          = NULL;
+    icopen.pV2Reserved          = NULL;
+    icopen.dnDevNode            = 0; /* FIXME */
+
+    whic = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_HIC));
+    if (!whic) return 0;
+
+    whic->driverproc   = lpfnHandler;
+    whic->driverproc16 = lpfnHandler16;
+    while (MSVIDEO_GetHicPtr(HIC_32(IC_HandleRef)) != NULL) IC_HandleRef++;
+    whic->hic          = HIC_32(IC_HandleRef++);
+    whic->next         = MSVIDEO_FirstHic;
+    MSVIDEO_FirstHic = whic;
+
+    /* Now try opening/loading the driver. Taken from DRIVER_AddToList */
+    /* What if the function is used more than once? */
+
+    if (MSVIDEO_SendMessage(whic->hic, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) 
+    {
+        WARN("DRV_LOAD failed for hic %p\n", whic->hic);
+        MSVIDEO_FirstHic = whic->next;
+        HeapFree(GetProcessHeap(), 0, whic);
+        return 0;
+    }
+    /* return value is not checked */
+    MSVIDEO_SendMessage(whic->hic, DRV_ENABLE, 0L, 0L);
 
-        whic->hdrv = (HDRVR)MSVIDEO_SendMessage(hic,DRV_OPEN,0,(DWORD)&icopen);
+    whic->hdrv = (HDRVR)MSVIDEO_SendMessage(whic->hic, DRV_OPEN, 0, (DWORD)&icopen);
 
-	if (whic->hdrv == 0) {
-		WARN("DRV_OPEN failed for hic %p\n",hic);
-		GlobalFree16(HIC_16(hic));
-		return 0;
-	}
+    if (whic->hdrv == 0) 
+    {
+        WARN("DRV_OPEN failed for hic %p\n", whic->hic);
+        MSVIDEO_FirstHic = whic->next;
+        HeapFree(GetProcessHeap(), 0, whic);
+        return 0;
+    }
 
-	GlobalUnlock16(HIC_16(hic));
-	TRACE("=> %p\n",hic);
-	return hic;
+    TRACE("=> %p\n", whic->hic);
+    return whic->hic;
 }
 
 /***********************************************************************
@@ -202,7 +243,7 @@ HIC MSVIDEO_OpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode,
  */
 HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler) 
 {
-    return MSVIDEO_OpenFunction(fccType, fccHandler, wMode, (DRIVERPROC)lpfnHandler, NULL);
+    return MSVIDEO_OpenFunction(fccType, fccHandler, wMode, (DRIVERPROC)lpfnHandler, 0);
 }
 
 /***********************************************************************
@@ -220,83 +261,85 @@ LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo,DWORD cb) {
 /***********************************************************************
  *		ICLocate			[MSVFW32.@]
  */
-HIC VFWAPI ICLocate(
-	DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
-	LPBITMAPINFOHEADER lpbiOut, WORD wMode)
+HIC VFWAPI ICLocate(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
+                    LPBITMAPINFOHEADER lpbiOut, WORD wMode)
 {
-	char	type[5],handler[5];
-	HIC	hic;
-	DWORD	querymsg;
-	LPSTR pszBuffer;
-
-	type[4]=0;memcpy(type,&fccType,4);
-	handler[4]=0;memcpy(handler,&fccHandler,4);
-
-	TRACE("(%s,%s,%p,%p,0x%04x)\n", type, handler, lpbiIn, lpbiOut, wMode);
-
-	switch (wMode) {
-	case ICMODE_FASTCOMPRESS:
-	case ICMODE_COMPRESS:
-		querymsg = ICM_COMPRESS_QUERY;
-		break;
-	case ICMODE_FASTDECOMPRESS:
-	case ICMODE_DECOMPRESS:
-		querymsg = ICM_DECOMPRESS_QUERY;
-		break;
-	case ICMODE_DRAW:
-		querymsg = ICM_DRAW_QUERY;
-		break;
-	default:
-		WARN("Unknown mode (%d)\n",wMode);
-		return 0;
-	}
-
-	/* Easy case: handler/type match, we just fire a query and return */
-	hic = ICOpen(fccType,fccHandler,wMode);
-	if (hic) {
-		if (!ICSendMessage(hic,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
-			return hic;
-		ICClose(hic);
-	}
+    HIC         hic;
+    DWORD	querymsg;
+    LPSTR       pszBuffer;
+
+    TRACE("(%.4s,%.4s,%p,%p,0x%04x)\n", 
+          (char*)&fccType, (char*)&fccHandler, lpbiIn, lpbiOut, wMode);
+
+    switch (wMode) 
+    {
+    case ICMODE_FASTCOMPRESS:
+    case ICMODE_COMPRESS:
+        querymsg = ICM_COMPRESS_QUERY;
+        break;
+    case ICMODE_FASTDECOMPRESS:
+    case ICMODE_DECOMPRESS:
+        querymsg = ICM_DECOMPRESS_QUERY;
+        break;
+    case ICMODE_DRAW:
+        querymsg = ICM_DRAW_QUERY;
+        break;
+    default:
+        WARN("Unknown mode (%d)\n", wMode);
+        return 0;
+    }
 
-	type[4]='.';memcpy(type,&fccType,4);
-	handler[4]='.';memcpy(handler,&fccHandler,4);
-
-	/* Now try each driver in turn. 32 bit codecs only. */
-	/* FIXME: Move this to an init routine? */
-
-	pszBuffer = (LPSTR)HeapAlloc(GetProcessHeap(),0,1024);
-	if (GetPrivateProfileSectionA("drivers32",pszBuffer,1024,"system.ini")) {
-		char* s = pszBuffer;
-		while (*s) {
-			if (!strncasecmp(type,s,5)) {
-				char *s2 = s;
-				while (*s2 != '\0' && *s2 != '.') s2++;
-				if (*s2++) {
-					HIC h;
-
-					h = ICOpen(fccType,*(DWORD*)s2,wMode);
-					if (h) {
-						if (!ICSendMessage(h,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
-							return h;
-						ICClose(h);
-					}
-				}
-			}
-			s += strlen(s) + 1;
-		}
-	}
-	HeapFree(GetProcessHeap(),0,pszBuffer);
+    /* Easy case: handler/type match, we just fire a query and return */
+    hic = ICOpen(fccType, fccHandler, wMode);
+    if (hic) 
+    {
+        if (!ICSendMessage(hic, querymsg, (DWORD)lpbiIn, (DWORD)lpbiOut))
+        {
+            TRACE("=> %p\n", hic);
+            return hic;
+        }
+        ICClose(hic);
+    }
 
-	if (fccType==streamtypeVIDEO) {
-		hic = ICLocate(ICTYPE_VIDEO,fccHandler,lpbiIn,lpbiOut,wMode);
-		if (hic)
-			return hic;
-	}
+    /* Now try each driver in turn. 32 bit codecs only. */
+    /* FIXME: Move this to an init routine? */
+    
+    pszBuffer = (LPSTR)HeapAlloc(GetProcessHeap(), 0, 1024);
+    if (GetPrivateProfileSectionA("drivers32", pszBuffer, 1024, "system.ini")) 
+    {
+        char* s = pszBuffer;
+        while (*s) 
+        {
+            if (!strncasecmp((char*)&fccType, s, 4) && s[4] == '.' && s[9] == '=')
+            {
+                char *s2 = s;
+                while (*s2 != '\0' && *s2 != '.') s2++;
+                if (*s2++) 
+                {
+                    hic = ICOpen(fccType, *(DWORD*)s2, wMode);
+                    if (hic) 
+                    {
+                        if (!ICSendMessage(hic, querymsg, (DWORD)lpbiIn, (DWORD)lpbiOut))
+                        {
+                            HeapFree(GetProcessHeap(), 0, pszBuffer);
+                            TRACE("=> %p\n", hic);
+                            return hic;
+                        }
+                        ICClose(hic);
+                    }
+                }
+            }
+            s += strlen(s) + 1;
+        }
+    }
+    HeapFree(GetProcessHeap(), 0, pszBuffer);
 
-	type[4] = handler[4] = '\0';
-	WARN("(%.4s,%.4s,%p,%p,0x%04x) not found!\n",type,handler,lpbiIn,lpbiOut,wMode);
-	return 0;
+    if (fccType == streamtypeVIDEO) 
+        return ICLocate(ICTYPE_VIDEO, fccHandler, lpbiIn, lpbiOut, wMode);
+    
+    WARN("(%.4s,%.4s,%p,%p,0x%04x) not found!\n",
+         (char*)&fccType, (char*)&fccHandler, lpbiIn, lpbiOut, wMode);
+    return 0;
 }
 
 /***********************************************************************
@@ -422,7 +465,7 @@ DWORD VFWAPIV  ICDecompress(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat,
 LRESULT MSVIDEO_SendMessage(HIC hic,UINT msg,DWORD lParam1,DWORD lParam2)
 {
     LRESULT     ret;
-    WINE_HIC*   whic = GlobalLock16(HIC_16(hic));
+    WINE_HIC*   whic = MSVIDEO_GetHicPtr(hic);
     
 #define XX(x) case x: TRACE("(%p,"#x",0x%08lx,0x%08lx)\n",hic,lParam1,lParam2);break;
     
@@ -498,9 +541,7 @@ LRESULT MSVIDEO_SendMessage(HIC hic,UINT msg,DWORD lParam1,DWORD lParam2)
         ret = SendDriverMessage(whic->hdrv, msg, lParam1, lParam2);
     }
 
-    GlobalUnlock16(HIC_16(hic));
-    
-    TRACE("	-> 0x%08lx\n",ret);
+    TRACE("	-> 0x%08lx\n", ret);
     return ret;
 }
 
@@ -577,20 +618,38 @@ DWORD VFWAPIV ICDraw(HIC hic, DWORD dwFlags, LPVOID lpFormat, LPVOID lpData, DWO
 /***********************************************************************
  *		ICClose			[MSVFW32.@]
  */
-LRESULT WINAPI ICClose(HIC hic) {
-	WINE_HIC *whic = GlobalLock16(HIC_16(hic));
-	TRACE("(%p)\n",hic);
-	if (whic->driverproc) {
-		ICSendMessage(hic,DRV_CLOSE,0,0);
-		ICSendMessage(hic,DRV_DISABLE,0,0);
-		ICSendMessage(hic,DRV_FREE,0,0);
-	} else {
-		CloseDriver(whic->hdrv,0,0);
-	}
+LRESULT WINAPI ICClose(HIC hic)
+{
+    WINE_HIC* whic = MSVIDEO_GetHicPtr(hic);
+    WINE_HIC** p;
 
-	GlobalUnlock16(HIC_16(hic));
-	GlobalFree16(HIC_16(hic));
-	return 0;
+    TRACE("(%p)\n",hic);
+
+    if (!whic) return ICERR_BADHANDLE;
+
+    if (whic->driverproc) 
+    {
+        MSVIDEO_SendMessage(hic, DRV_CLOSE, 0, 0);
+        MSVIDEO_SendMessage(hic, DRV_DISABLE, 0, 0);
+        MSVIDEO_SendMessage(hic, DRV_FREE, 0, 0);
+    }
+    else
+    {
+        CloseDriver(whic->hdrv, 0, 0);
+    }
+
+    /* remove whic from list */
+    for (p = &MSVIDEO_FirstHic; *p != NULL; p = &((*p)->next))
+    {
+        if ((*p) == whic)
+        {
+            *p = whic->next;
+            break;
+        }
+    }
+
+    HeapFree(GetProcessHeap(), 0, whic);
+    return 0;
 }
 
 
diff --git a/dlls/msvideo/msvideo_private.h b/dlls/msvideo/msvideo_private.h
index f5c0d8bd9abc80e2c2fd2e4b19e76c3e73466c0a..ac5fa38efbcc16e3aaeeae901c68c2cfe945d1a7 100644
--- a/dlls/msvideo/msvideo_private.h
+++ b/dlls/msvideo/msvideo_private.h
@@ -19,24 +19,31 @@
 #ifndef __WINE_MSVIDEO_PRIVATE_H
 #define __WINE_MSVIDEO_PRIVATE_H
 
+#include "winbase.h"
+#include "windef.h"
+#include "vfw.h"
+
 /* HIC struct (same layout as Win95 one) */
 typedef struct tagWINE_HIC {
-	DWORD		magic;		/* 00: 'Smag' */
-	HANDLE		curthread;	/* 04: */
-	DWORD		type;		/* 08: */
-	DWORD		handler;	/* 0C: */
-	HDRVR		hdrv;		/* 10: */
-	DWORD		private;	/* 14:(handled by SendDriverMessage)*/
-	DRIVERPROC	driverproc;	/* 18:(handled by SendDriverMessage)*/
-	DWORD		x1;		/* 1c: name? */
-	WORD		x2;		/* 20: */
-	DWORD		x3;		/* 22: */
+    DWORD		magic;		/* 00: 'Smag' */
+    HANDLE		curthread;	/* 04: */
+    DWORD		type;		/* 08: */
+    DWORD		handler;	/* 0C: */
+    HDRVR		hdrv;		/* 10: */
+    DWORD		private;	/* 14:(handled by SendDriverMessage)*/
+    DRIVERPROC  	driverproc;	/* 18:(handled by SendDriverMessage)*/
+    DWORD		x1;		/* 1c: name? */
+    WORD		x2;		/* 20: */
+    DWORD		x3;		/* 22: */
 					/* 26: */
-        DRIVERPROC16    driverproc16;   /* Wine specific flags */
+    DWORD               driverproc16;   /* Wine specific flags */
+    HIC                 hic;
+    struct tagWINE_HIC* next;
 } WINE_HIC;
 
-HIC     MSVIDEO_OpenFunction(DWORD, DWORD, UINT, DRIVERPROC, DRIVERPROC16);
-LRESULT MSVIDEO_SendMessage(HIC, UINT, DWORD, DWORD);
+HIC             MSVIDEO_OpenFunction(DWORD, DWORD, UINT, DRIVERPROC, DWORD);
+LRESULT         MSVIDEO_SendMessage(HIC, UINT, DWORD, DWORD);
+WINE_HIC*       MSVIDEO_GetHicPtr(HIC);
 
 extern LRESULT  (CALLBACK *pFnCallTo16)(HDRVR, HIC, UINT, LPARAM, LPARAM);