xref: /reactos/win32ss/gdi/ntgdi/print.c (revision 3e1a5415)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:         ReactOS win32 kernel mode subsystem
3c2c66affSColin Finck  * LICENSE:         GPL - See COPYING in the top level directory
4c2c66affSColin Finck  * FILE:            win32ss/gdi/ntgdi/print.c
5c2c66affSColin Finck  * PURPOSE:         Print functions
6c2c66affSColin Finck  * PROGRAMMER:
7c2c66affSColin Finck  */
8c2c66affSColin Finck 
9c2c66affSColin Finck #include <win32k.h>
10c2c66affSColin Finck 
11c2c66affSColin Finck #define NDEBUG
12c2c66affSColin Finck #include <debug.h>
13c2c66affSColin Finck 
14c2c66affSColin Finck INT
15c2c66affSColin Finck APIENTRY
NtGdiAbortDoc(HDC hDC)16c2c66affSColin Finck NtGdiAbortDoc(HDC  hDC)
17c2c66affSColin Finck {
18c2c66affSColin Finck   UNIMPLEMENTED;
19c2c66affSColin Finck   return 0;
20c2c66affSColin Finck }
21c2c66affSColin Finck 
22c2c66affSColin Finck INT
23c2c66affSColin Finck APIENTRY
NtGdiEndDoc(HDC hDC)24c2c66affSColin Finck NtGdiEndDoc(HDC  hDC)
25c2c66affSColin Finck {
26c2c66affSColin Finck   UNIMPLEMENTED;
27c2c66affSColin Finck   return 0;
28c2c66affSColin Finck }
29c2c66affSColin Finck 
30c2c66affSColin Finck INT
31c2c66affSColin Finck APIENTRY
NtGdiEndPage(HDC hDC)32c2c66affSColin Finck NtGdiEndPage(HDC  hDC)
33c2c66affSColin Finck {
34c2c66affSColin Finck   UNIMPLEMENTED;
35c2c66affSColin Finck   return 0;
36c2c66affSColin Finck }
37c2c66affSColin Finck 
38c2c66affSColin Finck INT
39c2c66affSColin Finck FASTCALL
IntGdiEscape(PDC dc,INT Escape,INT InSize,LPCSTR InData,LPVOID OutData)40c2c66affSColin Finck IntGdiEscape(PDC    dc,
41c2c66affSColin Finck              INT    Escape,
42c2c66affSColin Finck              INT    InSize,
43c2c66affSColin Finck              LPCSTR InData,
44c2c66affSColin Finck              LPVOID OutData)
45c2c66affSColin Finck {
46c2c66affSColin Finck   if (Escape == QUERYESCSUPPORT)
47c2c66affSColin Finck     return FALSE;
48c2c66affSColin Finck 
49c2c66affSColin Finck   UNIMPLEMENTED;
50c2c66affSColin Finck   return SP_ERROR;
51c2c66affSColin Finck }
52c2c66affSColin Finck 
53c2c66affSColin Finck INT
54c2c66affSColin Finck APIENTRY
NtGdiEscape(HDC hDC,INT Escape,INT InSize,LPCSTR InData,LPVOID OutData)55c2c66affSColin Finck NtGdiEscape(HDC  hDC,
56c2c66affSColin Finck             INT  Escape,
57c2c66affSColin Finck             INT  InSize,
58c2c66affSColin Finck             LPCSTR  InData,
59c2c66affSColin Finck             LPVOID  OutData)
60c2c66affSColin Finck {
61c2c66affSColin Finck   PDC dc;
62c2c66affSColin Finck   INT ret;
63c2c66affSColin Finck 
64c2c66affSColin Finck   dc = DC_LockDc(hDC);
65c2c66affSColin Finck   if (dc == NULL)
66c2c66affSColin Finck   {
67c2c66affSColin Finck     EngSetLastError(ERROR_INVALID_HANDLE);
68c2c66affSColin Finck     return SP_ERROR;
69c2c66affSColin Finck   }
70c2c66affSColin Finck 
71c2c66affSColin Finck   /* TODO: FIXME: Don't pass umode buffer to an Int function */
72c2c66affSColin Finck   ret = IntGdiEscape(dc, Escape, InSize, InData, OutData);
73c2c66affSColin Finck 
74c2c66affSColin Finck   DC_UnlockDc( dc );
75c2c66affSColin Finck   return ret;
76c2c66affSColin Finck }
77c2c66affSColin Finck 
78c2c66affSColin Finck INT
79c2c66affSColin Finck APIENTRY
NtGdiExtEscape(HDC hDC,IN OPTIONAL PWCHAR pDriver,IN INT nDriver,INT Escape,INT InSize,OPTIONAL LPSTR UnsafeInData,INT OutSize,OPTIONAL LPSTR UnsafeOutData)80c2c66affSColin Finck NtGdiExtEscape(
81c2c66affSColin Finck    HDC    hDC,
82c2c66affSColin Finck    IN OPTIONAL PWCHAR pDriver,
83c2c66affSColin Finck    IN INT nDriver,
84c2c66affSColin Finck    INT    Escape,
85c2c66affSColin Finck    INT    InSize,
86c2c66affSColin Finck    OPTIONAL LPSTR UnsafeInData,
87c2c66affSColin Finck    INT    OutSize,
88c2c66affSColin Finck    OPTIONAL LPSTR  UnsafeOutData)
89c2c66affSColin Finck {
90c2c66affSColin Finck    LPVOID   SafeInData = NULL;
91c2c66affSColin Finck    LPVOID   SafeOutData = NULL;
92c2c66affSColin Finck    NTSTATUS Status = STATUS_SUCCESS;
93c2c66affSColin Finck    INT      Result;
94*3e1a5415SJérôme Gardou    PPDEVOBJ ppdev;
95*3e1a5415SJérôme Gardou    PSURFACE psurf;
96c2c66affSColin Finck 
97*3e1a5415SJérôme Gardou    if (hDC == NULL)
98c2c66affSColin Finck    {
99*3e1a5415SJérôme Gardou       if (pDriver)
100*3e1a5415SJérôme Gardou       {
101*3e1a5415SJérôme Gardou          /* FIXME : Get the pdev from its name */
102*3e1a5415SJérôme Gardou          UNIMPLEMENTED;
103*3e1a5415SJérôme Gardou          return -1;
104c2c66affSColin Finck       }
105c2c66affSColin Finck 
106*3e1a5415SJérôme Gardou       ppdev = EngpGetPDEV(NULL);
107*3e1a5415SJérôme Gardou       if (!ppdev)
108*3e1a5415SJérôme Gardou       {
109*3e1a5415SJérôme Gardou          EngSetLastError(ERROR_BAD_DEVICE);
110*3e1a5415SJérôme Gardou          return -1;
111*3e1a5415SJérôme Gardou       }
112*3e1a5415SJérôme Gardou 
113*3e1a5415SJérôme Gardou       /* We're using the primary surface of the pdev. Lock it */
114*3e1a5415SJérôme Gardou       EngAcquireSemaphore(ppdev->hsemDevLock);
115*3e1a5415SJérôme Gardou 
116*3e1a5415SJérôme Gardou       psurf = ppdev->pSurface;
117*3e1a5415SJérôme Gardou       if (!psurf)
118*3e1a5415SJérôme Gardou       {
119*3e1a5415SJérôme Gardou          EngReleaseSemaphore(ppdev->hsemDevLock);
120*3e1a5415SJérôme Gardou          PDEVOBJ_vRelease(ppdev);
121*3e1a5415SJérôme Gardou          return 0;
122*3e1a5415SJérôme Gardou       }
123*3e1a5415SJérôme Gardou       SURFACE_ShareLockByPointer(psurf);
124*3e1a5415SJérôme Gardou    }
125*3e1a5415SJérôme Gardou    else
126*3e1a5415SJérôme Gardou    {
127*3e1a5415SJérôme Gardou       PDC pDC = DC_LockDc(hDC);
128c2c66affSColin Finck       if ( pDC == NULL )
129c2c66affSColin Finck       {
130c2c66affSColin Finck          EngSetLastError(ERROR_INVALID_HANDLE);
131c2c66affSColin Finck          return -1;
132c2c66affSColin Finck       }
133c2c66affSColin Finck 
134*3e1a5415SJérôme Gardou       /* Get the PDEV from the DC */
135*3e1a5415SJérôme Gardou       ppdev = pDC->ppdev;
136*3e1a5415SJérôme Gardou       PDEVOBJ_vReference(ppdev);
137*3e1a5415SJérôme Gardou 
138*3e1a5415SJérôme Gardou       /* Check if we have a surface */
139*3e1a5415SJérôme Gardou       psurf = pDC->dclevel.pSurface;
140*3e1a5415SJérôme Gardou       if (!psurf)
141*3e1a5415SJérôme Gardou       {
142*3e1a5415SJérôme Gardou          DC_UnlockDc(pDC);
143*3e1a5415SJérôme Gardou          PDEVOBJ_vRelease(ppdev);
144*3e1a5415SJérôme Gardou          return 0;
145*3e1a5415SJérôme Gardou       }
146*3e1a5415SJérôme Gardou       SURFACE_ShareLockByPointer(psurf);
147*3e1a5415SJérôme Gardou 
148*3e1a5415SJérôme Gardou       /* We're done with the DC */
149*3e1a5415SJérôme Gardou       DC_UnlockDc(pDC);
150*3e1a5415SJérôme Gardou    }
151*3e1a5415SJérôme Gardou 
152*3e1a5415SJérôme Gardou    /* See if we actually have a driver function to call */
153*3e1a5415SJérôme Gardou    if (ppdev->DriverFunctions.Escape == NULL)
154*3e1a5415SJérôme Gardou    {
155*3e1a5415SJérôme Gardou       Result = 0;
156*3e1a5415SJérôme Gardou       goto Exit;
157*3e1a5415SJérôme Gardou    }
158*3e1a5415SJérôme Gardou 
159c2c66affSColin Finck    if ( InSize && UnsafeInData )
160c2c66affSColin Finck    {
161c2c66affSColin Finck       _SEH2_TRY
162c2c66affSColin Finck       {
163c2c66affSColin Finck         ProbeForRead(UnsafeInData,
164c2c66affSColin Finck                      InSize,
165c2c66affSColin Finck                      1);
166c2c66affSColin Finck       }
167c2c66affSColin Finck       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
168c2c66affSColin Finck       {
169c2c66affSColin Finck         Status = _SEH2_GetExceptionCode();
170c2c66affSColin Finck       }
171c2c66affSColin Finck       _SEH2_END;
172c2c66affSColin Finck 
173c2c66affSColin Finck       if (!NT_SUCCESS(Status))
174c2c66affSColin Finck       {
175*3e1a5415SJérôme Gardou          Result = -1;
176*3e1a5415SJérôme Gardou          goto Exit;
177c2c66affSColin Finck       }
178c2c66affSColin Finck 
179c2c66affSColin Finck       SafeInData = ExAllocatePoolWithTag ( PagedPool, InSize, GDITAG_TEMP );
180c2c66affSColin Finck       if ( !SafeInData )
181c2c66affSColin Finck       {
182c2c66affSColin Finck          EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
183*3e1a5415SJérôme Gardou          Result = -1;
184*3e1a5415SJérôme Gardou          goto Exit;
185c2c66affSColin Finck       }
186c2c66affSColin Finck 
187c2c66affSColin Finck       _SEH2_TRY
188c2c66affSColin Finck       {
189c2c66affSColin Finck         /* Pointers were already probed! */
190c2c66affSColin Finck         RtlCopyMemory(SafeInData,
191c2c66affSColin Finck                       UnsafeInData,
192c2c66affSColin Finck                       InSize);
193c2c66affSColin Finck       }
194c2c66affSColin Finck       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
195c2c66affSColin Finck       {
196c2c66affSColin Finck         Status = _SEH2_GetExceptionCode();
197c2c66affSColin Finck       }
198c2c66affSColin Finck       _SEH2_END;
199c2c66affSColin Finck 
200c2c66affSColin Finck       if ( !NT_SUCCESS(Status) )
201c2c66affSColin Finck       {
202c2c66affSColin Finck          SetLastNtError(Status);
203*3e1a5415SJérôme Gardou          Result = -1;
204*3e1a5415SJérôme Gardou          goto Exit;
205c2c66affSColin Finck       }
206c2c66affSColin Finck    }
207c2c66affSColin Finck 
208c2c66affSColin Finck    if ( OutSize && UnsafeOutData )
209c2c66affSColin Finck    {
210c2c66affSColin Finck       _SEH2_TRY
211c2c66affSColin Finck       {
212c2c66affSColin Finck         ProbeForWrite(UnsafeOutData,
213c2c66affSColin Finck                       OutSize,
214c2c66affSColin Finck                       1);
215c2c66affSColin Finck       }
216c2c66affSColin Finck       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
217c2c66affSColin Finck       {
218c2c66affSColin Finck         Status = _SEH2_GetExceptionCode();
219c2c66affSColin Finck       }
220c2c66affSColin Finck       _SEH2_END;
221c2c66affSColin Finck 
222c2c66affSColin Finck       if (!NT_SUCCESS(Status))
223c2c66affSColin Finck       {
224c2c66affSColin Finck          SetLastNtError(Status);
225*3e1a5415SJérôme Gardou          Result = -1;
226*3e1a5415SJérôme Gardou          goto Exit;
227c2c66affSColin Finck       }
228c2c66affSColin Finck 
229c2c66affSColin Finck       SafeOutData = ExAllocatePoolWithTag ( PagedPool, OutSize, GDITAG_TEMP );
230c2c66affSColin Finck       if ( !SafeOutData )
231c2c66affSColin Finck       {
232c2c66affSColin Finck          EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
233*3e1a5415SJérôme Gardou          Result = -1;
234*3e1a5415SJérôme Gardou          goto Exit;
235c2c66affSColin Finck       }
236c2c66affSColin Finck    }
237c2c66affSColin Finck 
238*3e1a5415SJérôme Gardou    /* Finally call the driver */
239*3e1a5415SJérôme Gardou    Result = ppdev->DriverFunctions.Escape(
240*3e1a5415SJérôme Gardou          &psurf->SurfObj,
241*3e1a5415SJérôme Gardou          Escape,
242*3e1a5415SJérôme Gardou          InSize,
243*3e1a5415SJérôme Gardou          SafeInData,
244*3e1a5415SJérôme Gardou          OutSize,
245*3e1a5415SJérôme Gardou          SafeOutData );
246c2c66affSColin Finck 
247*3e1a5415SJérôme Gardou Exit:
248*3e1a5415SJérôme Gardou    if (hDC == NULL)
249*3e1a5415SJérôme Gardou    {
250*3e1a5415SJérôme Gardou       EngReleaseSemaphore(ppdev->hsemDevLock);
251*3e1a5415SJérôme Gardou    }
252*3e1a5415SJérôme Gardou    SURFACE_ShareUnlockSurface(psurf);
253*3e1a5415SJérôme Gardou    PDEVOBJ_vRelease(ppdev);
254c2c66affSColin Finck 
255c2c66affSColin Finck    if ( SafeInData )
256*3e1a5415SJérôme Gardou    {
257c2c66affSColin Finck       ExFreePoolWithTag ( SafeInData ,GDITAG_TEMP );
258*3e1a5415SJérôme Gardou    }
259c2c66affSColin Finck 
260c2c66affSColin Finck    if ( SafeOutData )
261c2c66affSColin Finck    {
262*3e1a5415SJérôme Gardou       if (Result > 0)
263*3e1a5415SJérôme Gardou       {
264c2c66affSColin Finck          _SEH2_TRY
265c2c66affSColin Finck          {
266c2c66affSColin Finck             /* Pointers were already probed! */
267*3e1a5415SJérôme Gardou             RtlCopyMemory(UnsafeOutData, SafeOutData, OutSize);
268c2c66affSColin Finck          }
269c2c66affSColin Finck          _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
270c2c66affSColin Finck          {
271c2c66affSColin Finck             Status = _SEH2_GetExceptionCode();
272c2c66affSColin Finck          }
273c2c66affSColin Finck          _SEH2_END;
274c2c66affSColin Finck 
275c2c66affSColin Finck          if ( !NT_SUCCESS(Status) )
276c2c66affSColin Finck          {
277c2c66affSColin Finck             SetLastNtError(Status);
278*3e1a5415SJérôme Gardou             Result = -1;
279c2c66affSColin Finck          }
280c2c66affSColin Finck       }
281c2c66affSColin Finck 
282*3e1a5415SJérôme Gardou       ExFreePoolWithTag ( SafeOutData, GDITAG_TEMP );
283*3e1a5415SJérôme Gardou    }
284*3e1a5415SJérôme Gardou 
285c2c66affSColin Finck    return Result;
286c2c66affSColin Finck }
287c2c66affSColin Finck 
288c2c66affSColin Finck INT
289c2c66affSColin Finck APIENTRY
NtGdiStartDoc(IN HDC hdc,IN DOCINFOW * pdi,OUT BOOL * pbBanding,IN INT iJob)290c2c66affSColin Finck NtGdiStartDoc(
291c2c66affSColin Finck     IN HDC hdc,
292c2c66affSColin Finck     IN DOCINFOW *pdi,
293c2c66affSColin Finck     OUT BOOL *pbBanding,
294c2c66affSColin Finck     IN INT iJob)
295c2c66affSColin Finck {
296c2c66affSColin Finck   UNIMPLEMENTED;
297c2c66affSColin Finck   return 0;
298c2c66affSColin Finck }
299c2c66affSColin Finck 
300c2c66affSColin Finck INT
301c2c66affSColin Finck APIENTRY
NtGdiStartPage(HDC hDC)302c2c66affSColin Finck NtGdiStartPage(HDC  hDC)
303c2c66affSColin Finck {
304c2c66affSColin Finck   UNIMPLEMENTED;
305c2c66affSColin Finck   return 0;
306c2c66affSColin Finck }
307c2c66affSColin Finck /* EOF */
308