It appears that StartDoc sends the STARTDOC escape with the DOCINFO
structure pointed to with the output data parameter.

diff --git a/graphics/escape.c b/graphics/escape.c
index 2c45d0e..54ca020 100644
--- a/graphics/escape.c
+++ b/graphics/escape.c
@@ -114,7 +114,10 @@
         break;
     }
 
-      /* Escape(hdc,STARTDOC,LPSTR,NULL); */
+      /* Escape(hdc,STARTDOC,LPSTR,LPDOCINFOA);
+       * lpvOutData is actually a pointer to the DocInfo structure and used as
+       * a second input parameter
+       */
 
     case STARTDOC: /* string may not be \0 terminated */
         if(lpszInData) {
@@ -123,6 +126,18 @@
 	    segin = SEGPTR_GET(cp);
 	} else
 	    segin = 0;
+
+	if(lpvOutData) {
+	    DOCINFO16 *lpsegdoc = SEGPTR_NEW(DOCINFO16);
+	    DOCINFOA *lpdoc = lpvOutData;
+	    memset(lpsegdoc, 0, sizeof(*lpsegdoc));
+	    lpsegdoc->cbSize = sizeof(*lpsegdoc);
+	    lpsegdoc->lpszDocName = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszDocName));
+	    lpsegdoc->lpszOutput = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszOutput));
+	    lpsegdoc->lpszDatatype = SEGPTR_GET(SEGPTR_STRDUP(lpdoc->lpszDatatype));
+	    lpsegdoc->fwType = lpdoc->fwType;
+	    segout = SEGPTR_GET(lpsegdoc);
+	}
 	break;
 
     case SETABORTPROC:
@@ -193,7 +208,16 @@
         SEGPTR_FREE(x);
         break;
     }
-    case STARTDOC:
+    case STARTDOC: {
+        DOCINFO16 *doc = PTR_SEG_TO_LIN(segout);
+	SEGPTR_FREE(PTR_SEG_TO_LIN(doc->lpszDocName));
+	SEGPTR_FREE(PTR_SEG_TO_LIN(doc->lpszOutput));
+	SEGPTR_FREE(PTR_SEG_TO_LIN(doc->lpszDatatype));
+	SEGPTR_FREE(doc);
+	SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
+	break;
+    }
+
     case CLIP_TO_PATH:
     case END_PATH:
         SEGPTR_FREE(PTR_SEG_TO_LIN(segin));
diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c
index 7f206af..267aa89 100644
--- a/graphics/win16drv/init.c
+++ b/graphics/win16drv/init.c
@@ -339,19 +339,27 @@
             }
           break;
           case STARTDOC:
-	    nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
-				  lpInData, lpOutData);
-            if (nRet != -1)
-            {
-              HDC *tmpHdc = SEGPTR_NEW(HDC);
+	    {
+	      /* lpInData is not necessarily \0 terminated so make it so */
+	      char *cp = SEGPTR_ALLOC(cbInput + 1);
+	      memcpy(cp, PTR_SEG_TO_LIN(lpInData), cbInput);
+	      cp[cbInput] = '\0';
+	    
+	      nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
+				    SEGPTR_GET(cp), lpOutData);
+	      SEGPTR_FREE(cp);
+	      if (nRet != -1)
+		{
+		  HDC *tmpHdc = SEGPTR_NEW(HDC);
 
 #define SETPRINTERDC SETABORTPROC
 
-              *tmpHdc = dc->hSelf;
-              PRTDRV_Control(physDev->segptrPDEVICE, SETPRINTERDC,
-                             SEGPTR_GET(tmpHdc), (SEGPTR)NULL);
-              SEGPTR_FREE(tmpHdc);
-            }
+		  *tmpHdc = dc->hSelf;
+		  PRTDRV_Control(physDev->segptrPDEVICE, SETPRINTERDC,
+				 SEGPTR_GET(tmpHdc), (SEGPTR)NULL);
+		  SEGPTR_FREE(tmpHdc);
+		}
+	    }
             break;
 	  default:
 	    nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
diff --git a/include/wine/wingdi16.h b/include/wine/wingdi16.h
index 88d37b4..ffec4cf 100644
--- a/include/wine/wingdi16.h
+++ b/include/wine/wingdi16.h
@@ -261,6 +261,8 @@
     INT16    cbSize;
     SEGPTR   lpszDocName;
     SEGPTR   lpszOutput;
+    SEGPTR   lpszDatatype;
+    DWORD    fwType;
 } DOCINFO16, *LPDOCINFO16;
 
 typedef BOOL16 (CALLBACK* ABORTPROC16)(HDC16, INT16);
diff --git a/misc/printdrv.c b/misc/printdrv.c
index db93fbb..9f853fb 100644
--- a/misc/printdrv.c
+++ b/misc/printdrv.c
@@ -45,8 +45,16 @@
     docA.cbSize = lpdoc->cbSize;
     docA.lpszDocName = PTR_SEG_TO_LIN(lpdoc->lpszDocName);
     docA.lpszOutput = PTR_SEG_TO_LIN(lpdoc->lpszOutput);
-    docA.lpszDatatype = NULL;
-    docA.fwType = 0;
+
+    if(lpdoc->cbSize >= 14)
+        docA.lpszDatatype = PTR_SEG_TO_LIN(lpdoc->lpszDatatype);
+    else
+        docA.lpszDatatype = NULL;
+
+    if(lpdoc->cbSize >= 18)
+        docA.fwType = lpdoc->fwType;
+    else
+        docA.fwType = 0;
 
     return StartDocA(hdc, &docA);
 }
@@ -54,6 +62,10 @@
 /******************************************************************
  *                  StartDocA  [GDI32.347]
  *
+ * StartDoc calls the STARTDOC Escape with the input data pointing to DocName
+ * and the output data (which is used as a second input parameter).pointing at
+ * the whole docinfo structure.  This seems to be an undocumented feature of
+ * the STARTDOC Escape. 
  */
 INT WINAPI StartDocA(HDC hdc, const DOCINFOA* doc)
 {
@@ -68,7 +80,7 @@
         return dc->funcs->pStartDoc( dc, doc );
     else
         return Escape(hdc, STARTDOC, strlen(doc->lpszDocName),
-		      doc->lpszDocName, 0);
+		      doc->lpszDocName, (LPVOID)doc);
 }
 
 /*************************************************************************