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