Winspool DocumentProperties and DeviceCapabilities should now work on
native 16 bit drivers.

diff --git a/graphics/driver.c b/graphics/driver.c
index 67306da..f2a0732 100644
--- a/graphics/driver.c
+++ b/graphics/driver.c
@@ -179,7 +179,7 @@
     if(!DRIVER_GetDriverName( lpszDevice, buf, sizeof(buf) )) return -1;
     funcs = DRIVER_FindDriver( buf );
     if(!funcs || !funcs->pExtDeviceMode) return -1;
-    return funcs->pExtDeviceMode(hwnd, lpdmOutput, lpszDevice, lpszPort,
+    return funcs->pExtDeviceMode(buf, hwnd, lpdmOutput, lpszDevice, lpszPort,
 				 lpdmInput, lpszProfile, fwMode);
 }
 
@@ -217,8 +217,9 @@
     if(!DRIVER_GetDriverName( lpszDevice, buf, sizeof(buf) )) return -1;
     funcs = DRIVER_FindDriver( buf );
     if(!funcs || !funcs->pDeviceCapabilities) return -1;
-    return funcs->pDeviceCapabilities( lpszDevice, lpszPort, fwCapability,
-				       lpszOutput, lpdm);
+    return funcs->pDeviceCapabilities( buf, lpszDevice, lpszPort,
+				       fwCapability, lpszOutput, lpdm);
+
 }
 
 
diff --git a/graphics/psdrv/driver.c b/graphics/psdrv/driver.c
index 3134df2..c764e6c 100644
--- a/graphics/psdrv/driver.c
+++ b/graphics/psdrv/driver.c
@@ -281,8 +281,8 @@
  *
  *       PSDRV_ExtDeviceMode
  */
-INT PSDRV_ExtDeviceMode(HWND hwnd, LPDEVMODEA lpdmOutput, LPSTR lpszDevice,
-			LPSTR lpszPort, LPDEVMODEA lpdmInput,
+INT PSDRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
+			LPSTR lpszDevice, LPSTR lpszPort, LPDEVMODEA lpdmInput,
 			LPSTR lpszProfile, DWORD dwMode)
 {
     return PSDRV_ExtDeviceMode16(hwnd, 0, lpdmOutput, lpszDevice, lpszPort,
@@ -485,12 +485,12 @@
  *
  *     PSDRV_DeviceCapabilities
  */
-DWORD PSDRV_DeviceCapabilities(LPCSTR lpszDevice, LPCSTR lpszPort,
-			       WORD fwCapability, LPSTR lpszOutput,
-			       LPDEVMODEA lpdm)
+DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice,
+			       LPCSTR lpszPort, WORD fwCapability,
+			       LPSTR lpszOutput, LPDEVMODEA lpdm)
 {
-  return PSDRV_DeviceCapabilities16(lpszDevice, lpszPort, fwCapability,
-				    lpszOutput, lpdm);
+    return PSDRV_DeviceCapabilities16(lpszDevice, lpszPort, fwCapability,
+				      lpszOutput, lpdm);
 }
 
 /***************************************************************
diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c
index f8f55fb..f1deb50 100644
--- a/graphics/win16drv/init.c
+++ b/graphics/win16drv/init.c
@@ -55,14 +55,14 @@
     NULL,                            /* pCreateDIBSection16 */
     NULL,                            /* pDeleteDC */
     NULL,                            /* pDeleteObject */
-    NULL,                            /* pDeviceCapabilities */
+    WIN16DRV_DeviceCapabilities,     /* pDeviceCapabilities */
     WIN16DRV_Ellipse,                /* pEllipse */
     NULL,                            /* pEndDoc */
     NULL,                            /* pEndPage */
     WIN16DRV_EnumDeviceFonts,        /* pEnumDeviceFonts */
     WIN16DRV_Escape,                 /* pEscape */
     NULL,                            /* pExcludeClipRect */
-    NULL,                            /* pExtDeviceMode */
+    WIN16DRV_ExtDeviceMode,          /* pExtDeviceMode */
     NULL,                            /* pExtFloodFill */
     WIN16DRV_ExtTextOut,             /* pExtTextOut */
     NULL,                            /* pFillRgn */
@@ -210,6 +210,7 @@
     printerDevCaps = (DeviceCaps *) xmalloc(sizeof(DeviceCaps));
     memset(printerDevCaps, 0, sizeof(DeviceCaps));
 
+    if(!output) output = "LPT1:";
     /* Get GDIINFO which is the same as a DeviceCaps structure */
     wRet = PRTDRV_Enable(printerDevCaps, GETGDIINFO, device, driver, output,NULL); 
 
diff --git a/graphics/win16drv/prtdrv.c b/graphics/win16drv/prtdrv.c
index 84a0726..2db2dd0 100644
--- a/graphics/win16drv/prtdrv.c
+++ b/graphics/win16drv/prtdrv.c
@@ -82,7 +82,7 @@
 	{
 	    TRACE("Comparing %s,%s\n",ptmpLPD->szDriver,pszDriver);
 	    /* Found driver store info, exit loop */
-	    if (lstrcmpiA(ptmpLPD->szDriver, pszDriver) == 0)
+	    if (strcasecmp(ptmpLPD->szDriver, pszDriver) == 0)
 	      pLPD = ptmpLPD;
 	}
     }
@@ -790,3 +790,196 @@
     }
     return wRet;
 }
+
+/**************************************************************
+ *
+ *       WIN16DRV_ExtDeviceMode
+ */
+INT WIN16DRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd, LPDEVMODEA lpdmOutput,
+			   LPSTR lpszDevice, LPSTR lpszPort,
+			   LPDEVMODEA lpdmInput, LPSTR lpszProfile,
+			   DWORD dwMode)
+{
+    LOADED_PRINTER_DRIVER *pLPD = LoadPrinterDriver(lpszDriver);
+    LPVOID lpSegOut = NULL, lpSegIn = NULL;
+    LPSTR lpSegDevice, lpSegPort, lpSegProfile;
+    INT16 wRet;
+    WORD wOutSize = 0;
+
+    if(!pLPD) return -1;
+
+    if(pLPD->fn[FUNC_EXTDEVICEMODE] == NULL) {
+        WARN("No EXTDEVICEMODE\n");
+	return -1;
+    }
+    lpSegDevice = SEGPTR_STRDUP(lpszDevice);
+    lpSegPort = SEGPTR_STRDUP(lpszPort);
+    lpSegProfile = SEGPTR_STRDUP(lpszProfile);
+    if(lpdmOutput) {
+      /* We don't know how big this will be so we call the driver's
+	 ExtDeviceMode to find out */
+
+	wOutSize = Callbacks->CallDrvExtDeviceModeProc(
+	    pLPD->fn[FUNC_EXTDEVICEMODE], hwnd, pLPD->hInst, 0,
+	    SEGPTR_GET(lpSegDevice), SEGPTR_GET(lpSegPort), 0,
+	    SEGPTR_GET(lpSegProfile), 0 );
+	lpSegOut = SEGPTR_ALLOC(wOutSize);
+	memcpy(lpSegOut, lpdmOutput, wOutSize); /* probably unnecessary */
+    }
+    if(lpdmInput) {
+      /* This time we get the information from the fields */
+        lpSegIn = SEGPTR_ALLOC(lpdmInput->dmSize + lpdmInput->dmDriverExtra);
+	memcpy(lpSegIn, lpdmInput, lpdmInput->dmSize +
+	       lpdmInput->dmDriverExtra);
+    }
+    wRet = Callbacks->CallDrvExtDeviceModeProc( pLPD->fn[FUNC_EXTDEVICEMODE],
+						hwnd, pLPD->hInst,
+						SEGPTR_GET(lpSegOut),
+						SEGPTR_GET(lpSegDevice),
+						SEGPTR_GET(lpSegPort),
+						SEGPTR_GET(lpSegIn),
+						SEGPTR_GET(lpSegProfile),
+						dwMode );
+    if(lpSegOut) {
+        memcpy(lpdmOutput, lpSegOut, wOutSize);
+	SEGPTR_FREE(lpSegOut);
+    }
+    if(lpSegIn) {
+        memcpy(lpdmInput, lpSegIn, lpdmInput->dmSize +
+	       lpdmInput->dmDriverExtra);
+	SEGPTR_FREE(lpSegIn);
+    }
+    SEGPTR_FREE(lpSegDevice);
+    SEGPTR_FREE(lpSegPort);
+    SEGPTR_FREE(lpSegProfile);
+    return wRet;
+}
+
+/**************************************************************
+ *
+ *       WIN16DRV_DeviceCapabilities
+ *
+ * This is a bit of a pain since we don't know the size of lpszOutput we have
+ * call the driver twice.
+ */
+DWORD WIN16DRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice,
+				  LPCSTR lpszPort, WORD fwCapability,
+				  LPSTR lpszOutput, LPDEVMODEA lpDevMode)
+{
+    LOADED_PRINTER_DRIVER *pLPD = LoadPrinterDriver(lpszDriver);
+    LPVOID lpSegdm = NULL, lpSegOut = NULL;
+    LPSTR lpSegDevice, lpSegPort;
+    DWORD dwRet;
+    INT OutputSize;
+
+    TRACE("%s,%s,%s,%d,%p,%p\n", lpszDriver, lpszDevice, lpszPort,
+	  fwCapability, lpszOutput, lpDevMode);
+
+    if(!pLPD) return -1;
+
+    if(pLPD->fn[FUNC_DEVICECAPABILITIES] == NULL) {
+        WARN("No DEVICECAPABILITES\n");
+	return -1;
+    }
+    lpSegDevice = SEGPTR_STRDUP(lpszDevice);
+    lpSegPort = SEGPTR_STRDUP(lpszPort);
+
+    if(lpDevMode) {
+        lpSegdm = SEGPTR_ALLOC(lpDevMode->dmSize + lpDevMode->dmDriverExtra);
+	memcpy(lpSegdm, lpDevMode, lpDevMode->dmSize +
+	       lpDevMode->dmDriverExtra);
+    }
+
+    dwRet = Callbacks->CallDrvDeviceCapabilitiesProc(
+	    pLPD->fn[FUNC_DEVICECAPABILITIES],
+	    SEGPTR_GET(lpSegDevice), SEGPTR_GET(lpSegPort),
+	    fwCapability, 0, SEGPTR_GET(lpSegdm) );
+
+    if(dwRet == -1) return -1;
+
+    switch(fwCapability) {
+    case DC_BINADJUST:
+    case DC_COLLATE:
+    case DC_COLORDEVICE:
+    case DC_COPIES:
+    case DC_DRIVER:
+    case DC_DUPLEX:
+    case DC_EMF_COMPLIANT:
+    case DC_EXTRA:
+    case DC_FIELDS:
+    case DC_MANUFACTURER:
+    case DC_MAXEXTENT:
+    case DC_MINEXTENT:
+    case DC_MODEL:
+    case DC_ORIENTATION:
+    case DC_PRINTERMEM:
+    case DC_PRINTRATEUNIT:
+    case DC_SIZE:
+        OutputSize = 0;
+	break;
+
+    case DC_BINNAMES:
+	OutputSize = 24 * dwRet;
+	break;
+
+    case DC_BINS:
+    case DC_PAPERS:
+	OutputSize = sizeof(WORD) * dwRet;
+	break;
+
+    case DC_DATATYPE_PRODUCED:
+	OutputSize = dwRet;
+	FIXME("%ld DataTypes supported. Don't know how long to make buffer!\n",
+	      dwRet);
+   	break;
+
+    case DC_ENUMRESOLUTIONS:
+	OutputSize = 2 * sizeof(LONG) * dwRet;
+	break;
+
+    case DC_FILEDEPENDENCIES:
+    case DC_MEDIAREADY:
+    case DC_PAPERNAMES:
+	OutputSize = 64 * dwRet;
+	break;
+
+    case DC_NUP:
+	OutputSize = sizeof(DWORD) * dwRet;
+	break;
+
+    case DC_PAPERSIZE:
+	OutputSize = sizeof(POINT16) * dwRet;
+	break;
+
+    case DC_PERSONALITY:
+	OutputSize = 32 * dwRet;
+	break;
+
+    default:
+        FIXME("Unsupported capability %d\n", fwCapability);
+	OutputSize = 0;
+	break;
+    }
+
+    if(OutputSize && lpszOutput) {
+        lpSegOut = SEGPTR_ALLOC(OutputSize);
+	dwRet = Callbacks->CallDrvDeviceCapabilitiesProc(
+					pLPD->fn[FUNC_DEVICECAPABILITIES],
+					SEGPTR_GET(lpSegDevice),
+					SEGPTR_GET(lpSegPort),
+					fwCapability,
+					SEGPTR_GET(lpSegOut),
+					SEGPTR_GET(lpSegdm) );
+	memcpy(lpszOutput, lpSegOut, OutputSize);
+	SEGPTR_FREE(lpSegOut);
+    }
+
+    if(lpSegdm) {
+        memcpy(lpDevMode, lpSegdm, lpDevMode->dmSize +
+	       lpDevMode->dmDriverExtra);
+	SEGPTR_FREE(lpSegdm);
+    }
+    SEGPTR_FREE(lpSegDevice);
+    SEGPTR_FREE(lpSegPort);
+    return dwRet;
+}
diff --git a/if1632/thunk.c b/if1632/thunk.c
index 9498e73..9d12963 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -69,6 +69,10 @@
                                                         WORD,WORD,LONG,WORD,WORD,
                                                         WORD,WORD,LONG,LONG,LONG,
                                                         LONG);
+extern WORD CALLBACK THUNK_CallTo16_word_wwlllllw(FARPROC16,WORD,WORD,LONG,
+						  LONG,LONG,LONG,LONG,WORD);
+extern LONG CALLBACK THUNK_CallTo16_long_llwll(FARPROC16,LONG,LONG,WORD,LONG,
+					       LONG);
 /* ### stop build ### */
 
 
@@ -127,8 +131,11 @@
     (void *)THUNK_CallTo16_long_lwlll,           /* CallDrvRealizeProc */
     (void *)THUNK_CallTo16_word_lwwwwlwwwwllll,  /* CallDrvStretchBltProc */
     (void *)THUNK_CallTo16_long_lwwllwlllllw,    /* CallDrvExtTextOutProc */
-    (void *)THUNK_CallTo16_word_llwwlll,         /* CallDrvGetCharWidth */ 
-    (void *)THUNK_CallTo16_word_ww               /* CallDrvAbortProc */
+    (void *)THUNK_CallTo16_word_llwwlll,         /* CallDrvGetCharWidth */
+    (void *)THUNK_CallTo16_word_ww,              /* CallDrvAbortProc */
+    (void *)THUNK_CallTo16_word_wwlllllw,        /* CallDrvExtDeviceModeProc */
+    (void *)THUNK_CallTo16_long_llwll            /* CallDrvDeviceCapabilitesProc */
+    
 };
 
 const CALLBACKS_TABLE *Callbacks = &CALLBACK_EmulatorTable;
diff --git a/include/callback.h b/include/callback.h
index 3f9b42c..082aa96 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -61,6 +61,11 @@
     WORD (CALLBACK *CallDrvGetCharWidthProc)( FARPROC16, SEGPTR, SEGPTR, WORD,
 					      WORD, SEGPTR, SEGPTR, SEGPTR );
     BOOL16 (CALLBACK *CallDrvAbortProc)( FARPROC16, HDC16, INT16 );
+    WORD (CALLBACK *CallDrvExtDeviceModeProc)( FARPROC16, WORD, WORD, SEGPTR,
+					       SEGPTR, SEGPTR, SEGPTR, SEGPTR,
+					       WORD );
+    DWORD (CALLBACK *CallDrvDeviceCapabilitiesProc)( FARPROC16, SEGPTR, SEGPTR,
+						     WORD, SEGPTR, SEGPTR );
 } CALLBACKS_TABLE;
 
 extern const CALLBACKS_TABLE *Callbacks;
diff --git a/include/gdi.h b/include/gdi.h
index 7cb509d..1c95104 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -179,15 +179,15 @@
 				     DWORD);
     BOOL     (*pDeleteDC)(DC*);
     BOOL     (*pDeleteObject)(HGDIOBJ);
-    DWORD    (*pDeviceCapabilities)(LPCSTR,LPCSTR,WORD,LPSTR,LPDEVMODEA);
+    DWORD    (*pDeviceCapabilities)(LPSTR,LPCSTR,LPCSTR,WORD,LPSTR,LPDEVMODEA);
     BOOL     (*pEllipse)(DC*,INT,INT,INT,INT);
     INT      (*pEndDoc)(DC*);
     INT      (*pEndPage)(DC*);
     BOOL     (*pEnumDeviceFonts)(DC*,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM);
     INT      (*pEscape)(DC*,INT,INT,SEGPTR,SEGPTR);
     INT      (*pExcludeClipRect)(DC*,INT,INT,INT,INT);
-    INT      (*pExtDeviceMode)(HWND,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,LPSTR,
-			       DWORD); 
+    INT      (*pExtDeviceMode)(LPSTR,HWND,LPDEVMODEA,LPSTR,LPSTR,LPDEVMODEA,
+			       LPSTR,DWORD); 
     BOOL     (*pExtFloodFill)(DC*,INT,INT,COLORREF,UINT);
     BOOL     (*pExtTextOut)(DC*,INT,INT,UINT,const RECT*,LPCSTR,UINT,
 			    const INT*);
diff --git a/include/psdrv.h b/include/psdrv.h
index 67e5ea7..9c63728 100644
--- a/include/psdrv.h
+++ b/include/psdrv.h
@@ -360,11 +360,13 @@
 				const void *bits, const BITMAPINFO *info,
 				UINT wUsage, DWORD dwRop );
 
-extern INT PSDRV_ExtDeviceMode(HWND hwnd, LPDEVMODEA lpdmOutput,
+extern INT PSDRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd,
+			       LPDEVMODEA lpdmOutput,
 			       LPSTR lpszDevice, LPSTR lpszPort,
 			       LPDEVMODEA lpdmInput, LPSTR lpszProfile,
 			       DWORD dwMode);
-extern DWORD PSDRV_DeviceCapabilities(LPCSTR lpszDevice, LPCSTR lpszPort,
+extern DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice,
+				      LPCSTR lpszPort,
 				      WORD fwCapability, LPSTR lpszOutput,
 				      LPDEVMODEA lpdm);
 
diff --git a/include/win16drv.h b/include/win16drv.h
index 26c9899..645c943 100644
--- a/include/win16drv.h
+++ b/include/win16drv.h
@@ -224,6 +224,14 @@
 extern BOOL WIN16DRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf, 
 				        DEVICEFONTENUMPROC proc, LPARAM lp );
 
+extern INT WIN16DRV_ExtDeviceMode(LPSTR lpszDriver, HWND hwnd,
+				  LPDEVMODEA lpdmOutput,
+				  LPSTR lpszDevice,
+				  LPSTR lpszPort, LPDEVMODEA lpdmInput,
+				  LPSTR lpszProfile, DWORD dwMode);
+extern DWORD WIN16DRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice,
+					 LPCSTR lpszPort, WORD fwCapability,
+					 LPSTR lpszOutput, LPDEVMODEA lpdm);
 
 /*
  * Wine 16bit driver global variables