[KERNEL32][CONSRV]
[reactos.git] / win32ss / gdi / ntgdi / print.c
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 */