xref: /reactos/win32ss/gdi/ntgdi/print.c (revision f6f20487)
1 /*
2  * PROJECT:         ReactOS win32 kernel mode subsystem
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            subsystems/win32/win32k/objects/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
16 NtGdiAbortDoc(HDC  hDC)
17 {
18   UNIMPLEMENTED;
19   return 0;
20 }
21 
22 INT
23 APIENTRY
24 NtGdiEndDoc(HDC  hDC)
25 {
26   UNIMPLEMENTED;
27   return 0;
28 }
29 
30 INT
31 APIENTRY
32 NtGdiEndPage(HDC  hDC)
33 {
34   UNIMPLEMENTED;
35   return 0;
36 }
37 
38 INT
39 FASTCALL
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
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
80 IntGdiExtEscape(
81    PDC    dc,
82    INT    Escape,
83    INT    InSize,
84    LPCSTR InData,
85    INT    OutSize,
86    LPSTR  OutData)
87 {
88    SURFACE *psurf = dc->dclevel.pSurface;
89    INT Result;
90 
91    if (!dc->ppdev->DriverFunctions.Escape || !psurf)
92    {
93       Result = 0;
94    }
95    else
96    {
97       Result = dc->ppdev->DriverFunctions.Escape(
98          &psurf->SurfObj,
99          Escape,
100          InSize,
101          (PVOID)InData,
102          OutSize,
103          (PVOID)OutData );
104    }
105 
106    return Result;
107 }
108 
109 INT
110 APIENTRY
111 NtGdiExtEscape(
112    HDC    hDC,
113    IN OPTIONAL PWCHAR pDriver,
114    IN INT nDriver,
115    INT    Escape,
116    INT    InSize,
117    OPTIONAL LPSTR UnsafeInData,
118    INT    OutSize,
119    OPTIONAL LPSTR  UnsafeOutData)
120 {
121    PDC      pDC;
122    LPVOID   SafeInData = NULL;
123    LPVOID   SafeOutData = NULL;
124    NTSTATUS Status = STATUS_SUCCESS;
125    INT      Result;
126 
127    if (hDC == 0)
128    {
129        hDC = UserGetWindowDC(NULL);
130    }
131 
132    pDC = DC_LockDc(hDC);
133    if ( pDC == NULL )
134    {
135       EngSetLastError(ERROR_INVALID_HANDLE);
136       return -1;
137    }
138    if ( pDC->dctype == DC_TYPE_INFO)
139    {
140       DC_UnlockDc(pDC);
141       return 0;
142    }
143 
144    if ( InSize && UnsafeInData )
145    {
146       _SEH2_TRY
147       {
148         ProbeForRead(UnsafeInData,
149                      InSize,
150                      1);
151       }
152       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
153       {
154         Status = _SEH2_GetExceptionCode();
155       }
156       _SEH2_END;
157 
158       if (!NT_SUCCESS(Status))
159       {
160         DC_UnlockDc(pDC);
161         SetLastNtError(Status);
162         return -1;
163       }
164 
165       SafeInData = ExAllocatePoolWithTag ( PagedPool, InSize, GDITAG_TEMP );
166       if ( !SafeInData )
167       {
168          DC_UnlockDc(pDC);
169          EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
170          return -1;
171       }
172 
173       _SEH2_TRY
174       {
175         /* Pointers were already probed! */
176         RtlCopyMemory(SafeInData,
177                       UnsafeInData,
178                       InSize);
179       }
180       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
181       {
182         Status = _SEH2_GetExceptionCode();
183       }
184       _SEH2_END;
185 
186       if ( !NT_SUCCESS(Status) )
187       {
188          ExFreePoolWithTag ( SafeInData, GDITAG_TEMP );
189          DC_UnlockDc(pDC);
190          SetLastNtError(Status);
191          return -1;
192       }
193    }
194 
195    if ( OutSize && UnsafeOutData )
196    {
197       _SEH2_TRY
198       {
199         ProbeForWrite(UnsafeOutData,
200                       OutSize,
201                       1);
202       }
203       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
204       {
205         Status = _SEH2_GetExceptionCode();
206       }
207       _SEH2_END;
208 
209       if (!NT_SUCCESS(Status))
210       {
211         SetLastNtError(Status);
212         goto freeout;
213       }
214 
215       SafeOutData = ExAllocatePoolWithTag ( PagedPool, OutSize, GDITAG_TEMP );
216       if ( !SafeOutData )
217       {
218          EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
219 freeout:
220          if ( SafeInData )
221             ExFreePoolWithTag ( SafeInData, GDITAG_TEMP );
222          DC_UnlockDc(pDC);
223          return -1;
224       }
225    }
226 
227    Result = IntGdiExtEscape ( pDC, Escape, InSize, SafeInData, OutSize, SafeOutData );
228 
229    DC_UnlockDc(pDC);
230 
231    if ( SafeInData )
232       ExFreePoolWithTag ( SafeInData ,GDITAG_TEMP );
233 
234    if ( SafeOutData )
235    {
236       _SEH2_TRY
237       {
238         /* Pointers were already probed! */
239         RtlCopyMemory(UnsafeOutData,
240                       SafeOutData,
241                       OutSize);
242       }
243       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
244       {
245         Status = _SEH2_GetExceptionCode();
246       }
247       _SEH2_END;
248 
249       ExFreePoolWithTag ( SafeOutData, GDITAG_TEMP );
250       if ( !NT_SUCCESS(Status) )
251       {
252          SetLastNtError(Status);
253          return -1;
254       }
255    }
256 
257    return Result;
258 }
259 
260 INT
261 APIENTRY
262 NtGdiStartDoc(
263     IN HDC hdc,
264     IN DOCINFOW *pdi,
265     OUT BOOL *pbBanding,
266     IN INT iJob)
267 {
268   UNIMPLEMENTED;
269   return 0;
270 }
271 
272 INT
273 APIENTRY
274 NtGdiStartPage(HDC  hDC)
275 {
276   UNIMPLEMENTED;
277   return 0;
278 }
279 /* EOF */
280