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