[ros-diffs] [jimtabor] 41135: - Implementation of gdi printing support. Work in progress. Added StartDocW plus others and fixed some defines. Found the initialization bug again, yes it was never fixed, but worked around. The debug spam has a purpose, just read it.

jimtabor at svn.reactos.org jimtabor at svn.reactos.org
Wed May 27 06:49:31 CEST 2009


Author: jimtabor
Date: Wed May 27 08:49:29 2009
New Revision: 41135

URL: http://svn.reactos.org/svn/reactos?rev=41135&view=rev
Log:
- Implementation of gdi printing support. Work in progress. Added StartDocW plus others and fixed some defines. Found the initialization bug again, yes it was never fixed, but worked around. The debug spam has a purpose, just read it.

Modified:
    trunk/reactos/dll/win32/gdi32/include/gdi32p.h
    trunk/reactos/dll/win32/gdi32/misc/misc.c
    trunk/reactos/dll/win32/gdi32/objects/dc.c
    trunk/reactos/dll/win32/gdi32/objects/printdrv.c
    trunk/reactos/include/reactos/win32k/ntgdihdl.h

Modified: trunk/reactos/dll/win32/gdi32/include/gdi32p.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/include/gdi32p.h?rev=41135&r1=41134&r2=41135&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdi32/include/gdi32p.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/include/gdi32p.h [iso-8859-1] Wed May 27 08:49:29 2009
@@ -104,7 +104,8 @@
   DWORD           dwDriverCount;   // After init should be 2
   DWORD           WOW64_UMPDev;
   DWORD           WOW64_hMod;
-  WCHAR           String[188];
+  DWORD           Unknown;
+  PVOID           apfn[INDEX_LAST]; // Print Driver pfn
 } UMPDEV, *PUMPDEV;
 
 #define LOCALFONT_COUNT 10
@@ -128,7 +129,7 @@
 typedef BOOL WINAPI (*OPENPRINTERW) (LPWSTR,PHANDLE,LPPRINTER_DEFAULTSW);
 typedef BOOL WINAPI (*READPRINTER) (HANDLE,PVOID,DWORD,PDWORD);
 typedef BOOL WINAPI (*RESETPRINTERW) (HANDLE,LPPRINTER_DEFAULTSW);
-typedef BOOL WINAPI (*STARTDOCDLGW) (HANDLE,DOCINFOW *);
+typedef LPWSTR WINAPI (*STARTDOCDLGW) (HANDLE,DOCINFOW *);
 typedef DWORD WINAPI (*STARTDOCPRINTERW) (HANDLE,DWORD,PBYTE);
 typedef BOOL WINAPI (*STARTPAGEPRINTER) (HANDLE);
 // ddk/winsplp.h
@@ -145,6 +146,8 @@
 typedef DWORD WINAPI (*QUERYSPOOLMODE) (HANDLE,DWORD,DWORD);
 typedef DWORD WINAPI (*QUERYREMOTEFONTS) (DWORD,DWORD,DWORD);
 
+extern CLOSEPRINTER fpClosePrinter;
+
 /* FUNCTIONS *****************************************************************/
 
 PVOID
@@ -195,6 +198,7 @@
 );
 
 PLDC
+FASTCALL
 GdiGetLDC(HDC hDC);
 
 HGDIOBJ
@@ -277,6 +281,7 @@
 VOID GdiSAPCallback(PLDC pldc);
 
 int FASTCALL DocumentEventEx(PVOID,HANDLE,HDC,int,ULONG,PVOID,ULONG,PVOID);
+BOOL FASTCALL EndPagePrinterEx(PVOID,HANDLE);
 BOOL FASTCALL LoadTheSpoolerDrv(VOID);
 
 /* EOF */

Modified: trunk/reactos/dll/win32/gdi32/misc/misc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/misc/misc.c?rev=41135&r1=41134&r2=41135&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdi32/misc/misc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/misc/misc.c [iso-8859-1] Wed May 27 08:49:29 2009
@@ -28,6 +28,9 @@
 
 #include "precomp.h"
 
+#define NDEBUG
+#include <debug.h>
+
 PGDI_TABLE_ENTRY GdiHandleTable = NULL;
 PGDI_SHARED_HANDLE_TABLE GdiSharedHandleTable = NULL;
 HANDLE CurrentProcessId = NULL;
@@ -121,47 +124,93 @@
 
 BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, DWORD ObjectType, PVOID *UserData)
 {
-  PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj);
-  if((Entry->Type & GDI_ENTRY_BASETYPE_MASK) == ObjectType &&
-    ( (Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK ) == 
+  if ( GdiHandleTable )
+  {
+     PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj);
+     if((Entry->Type & GDI_ENTRY_BASETYPE_MASK) == ObjectType &&
+       ( (Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK ) == 
                                                                    GDI_HANDLE_GET_TYPE(hGdiObj))
-  {
-    HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
-    if(pid == NULL || pid == CurrentProcessId)
-    {
-    //
-    // Need to test if we have Read & Write access to the VM address space.
-    //
-      BOOL Result = TRUE;
-      if(Entry->UserData)
-      {
-         volatile CHAR *Current = (volatile CHAR*)Entry->UserData;
-         _SEH2_TRY
+     {
+       HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
+       if(pid == NULL || pid == CurrentProcessId)
+       {
+       //
+       // Need to test if we have Read & Write access to the VM address space.
+       //
+         BOOL Result = TRUE;
+         if(Entry->UserData)
          {
-           *Current = *Current;
+            volatile CHAR *Current = (volatile CHAR*)Entry->UserData;
+            _SEH2_TRY
+            {
+              *Current = *Current;
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+              Result = FALSE;
+            }
+            _SEH2_END
          }
-         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-         {
+         else
+            Result = FALSE; // Can not be zero.
+         if (Result) *UserData = Entry->UserData;
+         return Result;
+       }
+     }
+     SetLastError(ERROR_INVALID_PARAMETER);
+     return FALSE;
+  }
+  else
+  {
+    DPRINT1("!GGHUD: Warning System Initialization Error!!!! GdiHandleTable == 0x%x !!!\n",GdiHandleTable);
+    *UserData = NULL;
+  }
+  return FALSE;
+}
+
+PLDC
+FASTCALL
+GdiGetLDC(HDC hDC)
+{
+  if ( GdiHandleTable )
+  {
+     PDC_ATTR Dc_Attr;
+     PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX((HGDIOBJ) hDC);
+     HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1);
+     // Don't check the mask, just the object type.
+     if ( Entry->ObjectType == GDIObjType_DC_TYPE &&
+          (pid == NULL || pid == CurrentProcessId) )
+     {
+        BOOL Result = TRUE;
+        if (Entry->UserData)
+        {
+           volatile CHAR *Current = (volatile CHAR*)Entry->UserData;
+           _SEH2_TRY
+           {
+             *Current = *Current;
+           }
+           _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+           {
+             Result = FALSE;
+           }
+           _SEH2_END
+        }
+        else
            Result = FALSE;
-         }
-         _SEH2_END
-      }
-       else
-         Result = FALSE; // Can not be zero.
-      if (Result) *UserData = Entry->UserData;
-      return Result;
-    }
-  }
-  SetLastError(ERROR_INVALID_PARAMETER);
-  return FALSE;
-}
-
-PLDC GdiGetLDC(HDC hDC)
-{
-    PDC_ATTR Dc_Attr;
-    if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
-      return NULL;
-    return Dc_Attr->pvLDC;
+
+        if (Result)
+        {
+           Dc_Attr = (PDC_ATTR)Entry->UserData;
+           return Dc_Attr->pvLDC;
+        }
+     }
+     return NULL;
+  }
+  else
+  {
+     DPRINT1("!LDC: Warning System Initialization Error!!!! GdiHandleTable == 0x%x !!!\n",GdiHandleTable);
+  }
+  return NULL;
 }
 
 VOID GdiSAPCallback(PLDC pldc)

Modified: trunk/reactos/dll/win32/gdi32/objects/dc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/objects/dc.c?rev=41135&r1=41134&r2=41135&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdi32/objects/dc.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/objects/dc.c [iso-8859-1] Wed May 27 08:49:29 2009
@@ -275,25 +275,37 @@
 DeleteDC(HDC hDC)
 {
   BOOL Ret = TRUE;
-#if 0
-  PDC_ATTR Dc_Attr;
-  PLDC pLDC;
-
-  if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
-
-  if ( Dc_Attr )
-    {
-      pLDC = Dc_Attr->pvLDC;
-
-      if ( pLDC )
-        {
-          DPRINT1("Delete the Local DC structure\n");
-          LocalFree( pLDC );
-        }
-    }
-#endif
+  PLDC pLDC = NULL;
+  HANDLE hPrinter = NULL;
+  ULONG hType = GDI_HANDLE_GET_TYPE(hDC);
+
+  pLDC = GdiGetLDC(hDC);
+
+  if (hType != GDILoObjType_LO_DC_TYPE)
+  {
+
+     if ( !pLDC || hType == GDILoObjType_LO_METADC16_TYPE)
+     {
+        SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+     }
+     if (pLDC->Flags & LDC_INIT_DOCUMENT) AbortDoc(hDC);
+     if (pLDC->hPrinter)
+     {
+        DocumentEventEx(NULL, pLDC->hPrinter, hDC, DOCUMENTEVENT_DELETEDC, 0, NULL, 0, NULL);
+        hPrinter = pLDC->hPrinter;
+        pLDC->hPrinter = NULL;
+     }
+  }
+
   Ret = NtGdiDeleteObjectApp(hDC);
 
+  if (Ret && pLDC )
+  {
+     DPRINT1("Delete the Local DC structure\n");
+     LocalFree( pLDC );
+  }
+  if (hPrinter) fpClosePrinter(hPrinter);
   return Ret;
 }
 

Modified: trunk/reactos/dll/win32/gdi32/objects/printdrv.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/objects/printdrv.c?rev=41135&r1=41134&r2=41135&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdi32/objects/printdrv.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/objects/printdrv.c [iso-8859-1] Wed May 27 08:49:29 2009
@@ -40,7 +40,7 @@
 HANDLE ghSpooler = NULL;
 
 static ABORTPRINTER fpAbortPrinter;
-static CLOSEPRINTER fpClosePrinter;
+CLOSEPRINTER fpClosePrinter;
 static CLOSESPOOLFILEHANDLE fpCloseSpoolFileHandle;
 static COMMITSPOOLDATA fpCommitSpoolData;
 //static fpConnectToLd64In32Server;
@@ -92,10 +92,60 @@
       return SP_ERROR;
    }
 
+   if (pldc->Flags & LDC_ATENDPAGE) return 1;
+
+   if (pldc->Flags & LDC_META_PRINT)
+   {
+      if ( Form )
+      {
+         // Do MF EndPageForm
+      }
+      else
+      {
+         // Do MF EndPage
+      }
+      return Ret;      
+   }
+
+   if (pldc->Flags & LDC_KILL_DOCUMENT || pldc->Flags & LDC_INIT_PAGE)
+   {
+      SetLastError(ERROR_INVALID_PARAMETER);
+      return SP_ERROR;
+   }
+
+   if (pldc->Flags & LDC_SAPCALLBACK) GdiSAPCallback(pldc);
+
+   pldc->Flags &= ~LDC_INIT_PAGE;
+
+   DocumentEventEx(NULL, pldc->hPrinter, hdc, DOCUMENTEVENT_ENDPAGE, 0, NULL, 0, NULL);   
+
+   ((PW32CLIENTINFO)NtCurrentTeb()->Win32ClientInfo)->cSpins = 0;
+
+   if ( NtGdiEndPage(hdc) )
+   {
+      BOOL Good;
+//      if (pldc->pUMPDev)
+         Good = EndPagePrinterEx(NULL,pldc->hPrinter);
+
+      if (Good) pldc->Flags |= LDC_STARTPAGE;
+      Ret = 1;
+   }
+   else
+      SetLastError(ERROR_INVALID_PARAMETER);
    return Ret;
 }
 
 /* FUNCTIONS *****************************************************************/
+
+BOOL
+FASTCALL
+AbortPrinterEx(
+        PVOID   pvUMPDev,
+        HANDLE  hPrinter
+               )
+{
+    return fpAbortPrinter(hPrinter);
+}
 
 int
 FASTCALL
@@ -128,11 +178,11 @@
 EndPagePrinterEx(
         PVOID   pvUMPDev,
         HANDLE  hPrinter
-               )
+                )
 {
     return fpEndPagePrinter(hPrinter);
 }
-
+ 
 BOOL
 FASTCALL
 LoadTheSpoolerDrv(VOID)
@@ -169,7 +219,7 @@
         fpSeekPrinter = GetProcAddress(hModWinSpoolDrv, "SeekPrinter");
         fpSplDriverUnloadComplete = GetProcAddress(hModWinSpoolDrv, "SplDriverUnloadComplete");
         fpSplReadPrinter = GetProcAddress(hModWinSpoolDrv, (LPCSTR)205);
-        fpStartDocDlgW = GetProcAddress(hModWinSpoolDrv, "StartDocDlgW");
+        fpStartDocDlgW = (PVOID)GetProcAddress(hModWinSpoolDrv, "StartDocDlgW");
         fpStartDocPrinterW = (PVOID)GetProcAddress(hModWinSpoolDrv, "StartDocPrinterW");
         fpStartPagePrinter = GetProcAddress(hModWinSpoolDrv, "StartPagePrinter");
 
@@ -213,6 +263,31 @@
   return (ghSpooler != NULL);
 }
 
+/*
+  Note from msdn:
+
+   The sequence for a print job is as follows:
+
+   1. To begin a print job, call StartDocPrinter.
+   2. To begin each page, call StartPagePrinter.
+   3. To write data to a page, call WritePrinter.
+   4. To end each page, call EndPagePrinter.
+   5. Repeat 2, 3, and 4 for as many pages as necessary.
+   6. To end the print job, call EndDocPrinter.
+                  
+ */
+DWORD
+FASTCALL
+StartDocPrinterWEx(
+        PVOID   pvUMPDev,
+        HANDLE  hPrinter,
+        DWORD   Level,
+        LPBYTE  pDocInfo
+                  )
+{
+    return fpStartDocPrinterW(hPrinter,Level,pDocInfo);
+}
+
 BOOL
 FASTCALL
 StartPagePrinterEx(
@@ -312,7 +387,7 @@
    if (pldc->Flags & LDC_INIT_DOCUMENT)
    {
       BOOL Good;
-      if (pldc->Flags & LDC_ENDPAGE_MFDC) EndPage(hdc);
+      if (pldc->Flags & LDC_INIT_PAGE) EndPage(hdc);
 
       DocumentEventEx(NULL, pldc->hPrinter, hdc, DOCUMENTEVENT_ENDDOC, 0, NULL, 0, NULL);
    
@@ -320,7 +395,7 @@
 
       Good = NtGdiEndDoc(hdc);
 
-      if (Good)
+//      if (pldc->pUMPDev)
          Good = EndDocPrinterEx(NULL,pldc->hPrinter);
 
       if (Good)
@@ -348,9 +423,7 @@
  */
 int
 WINAPI
-EndPage(
-	HDC	hdc
-	)
+EndPage(HDC hdc	)
 {
    return IntEndPage(hdc,FALSE);
 }
@@ -404,22 +477,116 @@
 	)
 {
    PLDC pldc;
+   DOCINFOW diW;
+   DOC_INFO_1W di1W;
+   LPWSTR lpwstrRet = NULL;
+   BOOL Banding;
+   int PrnJobNo, Ret = SP_ERROR;  
    ULONG hType = GDI_HANDLE_GET_TYPE(hdc);
 
    if (hType == GDILoObjType_LO_DC_TYPE || hType == GDILoObjType_LO_METADC16_TYPE)
-   {
-      SetLastError(ERROR_INVALID_HANDLE);
-      return SP_ERROR;
-   }
+      return SP_ERROR;
 
    pldc = GdiGetLDC(hdc);
-   if ( !pldc )
-   {
-      SetLastError(ERROR_INVALID_HANDLE);
-      return SP_ERROR;
-   }
-
-   return NtGdiStartDoc ( hdc, (DOCINFOW *)lpdi, NULL, 0);
+   if ( !pldc || pldc->Flags & LDC_ATENDPAGE)
+   {
+      SetLastError(ERROR_INVALID_HANDLE);
+      return SP_ERROR;
+   }
+
+   if (!pldc->hPrinter) return SP_ERROR;
+
+   pldc->Flags &= ~LDC_KILL_DOCUMENT;
+
+   if (lpdi)
+      RtlCopyMemory(&diW, lpdi, sizeof(DOCINFOW));
+   else
+   {
+      diW.cbSize = sizeof(DOCINFOW);
+      diW.lpszDocName  = NULL;
+      diW.lpszOutput   = NULL;
+      diW.lpszDatatype = NULL;
+      diW.fwType = 0;
+   }
+
+   if (!diW.lpszOutput)
+      if (pldc->pwszPort) diW.lpszOutput = pldc->pwszPort;
+
+   lpwstrRet = fpStartDocDlgW(pldc->hPrinter, &diW);
+   if (lpwstrRet == (LPWSTR)SP_APPABORT)
+   {
+      pldc->Flags |= LDC_KILL_DOCUMENT;
+      return SP_ERROR;
+   }
+   if (lpwstrRet == (LPWSTR)SP_ERROR) return SP_ERROR;
+
+   if (lpwstrRet != 0) diW.lpszOutput = lpwstrRet;
+
+   Ret = DocumentEventEx( NULL,
+                          pldc->hPrinter,
+                          hdc,
+                          DOCUMENTEVENT_STARTDOC,
+                          sizeof(ULONG),
+                          &diW,
+                          0,
+                          NULL);
+
+   if (Ret == SP_APPABORT)
+   {
+      pldc->Flags |= LDC_KILL_DOCUMENT;
+      Ret = SP_ERROR;
+   }
+   if (Ret == SP_ERROR)
+   {
+      if (lpwstrRet) LocalFree(lpwstrRet);
+      return Ret;
+   }
+
+   di1W.pDocName    = (LPWSTR)diW.lpszDocName;
+   di1W.pOutputFile = (LPWSTR)diW.lpszOutput;
+   di1W.pDatatype   = (LPWSTR)diW.lpszDatatype;
+
+   Ret = SP_ERROR;
+
+   PrnJobNo = StartDocPrinterWEx(NULL, pldc->hPrinter, 1, (LPBYTE)&di1W);
+   if (PrnJobNo <= 0)
+   {
+      Ret = NtGdiStartDoc( hdc, &diW, &Banding, PrnJobNo);
+      if (Ret)
+      {
+         if (pldc->pAbortProc)
+         {
+            GdiSAPCallback(pldc);
+            pldc->Flags |= LDC_SAPCALLBACK;
+            pldc->CallBackTick = GetTickCount();
+         }
+         pldc->Flags |= LDC_INIT_DOCUMENT;
+         if (!Banding) pldc->Flags |= LDC_STARTPAGE;
+      }
+   }
+   if (Ret == SP_ERROR)
+   {
+       //if ( pldc->pUMPDev  )
+         AbortPrinterEx(NULL, pldc->hPrinter);
+       DPRINT1("StartDoc Died!!!\n");
+   }
+   else
+   {
+      if ( DocumentEventEx( NULL,
+                            pldc->hPrinter,
+                            hdc,
+                            DOCUMENTEVENT_STARTDOCPOST,
+                            sizeof(ULONG),
+                            &Ret,
+                            0,
+                            NULL) == SP_ERROR)
+      {
+          AbortDoc(hdc);
+          Ret = SP_ERROR;
+      }
+   }
+   if (lpwstrRet) LocalFree(lpwstrRet);
+   return Ret;
 }
 
 /*
@@ -502,9 +669,9 @@
 	return SP_ERROR;
    }
 
-   pldc->Flags &= ~(LDC_STARTPAGE);
-
-   if (pldc->Flags & LDC_ENDPAGE_MFDC) return 1;
+   pldc->Flags &= ~(LDC_ATENDPAGE|LDC_STARTPAGE);
+
+   if (pldc->Flags & LDC_INIT_PAGE) return 1;
 
    if (DocumentEventEx(NULL, pldc->hPrinter, hdc, DOCUMENTEVENT_STARTPAGE, 0, NULL, 0, NULL) != SP_ERROR)
    {

Modified: trunk/reactos/include/reactos/win32k/ntgdihdl.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntgdihdl.h?rev=41135&r1=41134&r2=41135&view=diff
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntgdihdl.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/win32k/ntgdihdl.h [iso-8859-1] Wed May 27 08:49:29 2009
@@ -186,7 +186,6 @@
 #define LDC_INFODC        0x01000000 /* If CreateIC was passed. */
 #define LDC_DEVCAPS       0x02000000
 #define LDC_ATENDPAGE     0x10000000
-#define LDC_ENDPAGE_MFDC  0x80000000
 
 /* DC_ATTR Xform Flags */
 #define METAFILE_TO_WORLD_IDENTITY          0x00000001



More information about the Ros-diffs mailing list