Reintegrate header-work branch. Important changes include continued work on headers...
[reactos.git] / reactos / subsystems / win32 / win32k / objects / print.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /* $Id$ */
20
21 #include <win32k.h>
22
23 #define NDEBUG
24 #include <debug.h>
25
26 INT
27 APIENTRY
28 NtGdiAbortDoc(HDC hDC)
29 {
30 UNIMPLEMENTED;
31 return 0;
32 }
33
34 INT
35 APIENTRY
36 NtGdiEndDoc(HDC hDC)
37 {
38 UNIMPLEMENTED;
39 return 0;
40 }
41
42 INT
43 APIENTRY
44 NtGdiEndPage(HDC hDC)
45 {
46 UNIMPLEMENTED;
47 return 0;
48 }
49
50 INT
51 FASTCALL
52 IntGdiEscape(PDC dc,
53 INT Escape,
54 INT InSize,
55 LPCSTR InData,
56 LPVOID OutData)
57 {
58 if (Escape == QUERYESCSUPPORT)
59 return FALSE;
60
61 UNIMPLEMENTED;
62 return SP_ERROR;
63 }
64
65 INT
66 APIENTRY
67 NtGdiEscape(HDC hDC,
68 INT Escape,
69 INT InSize,
70 LPCSTR InData,
71 LPVOID OutData)
72 {
73 PDC dc;
74 INT ret;
75
76 dc = DC_LockDc(hDC);
77 if (dc == NULL)
78 {
79 SetLastWin32Error(ERROR_INVALID_HANDLE);
80 return SP_ERROR;
81 }
82
83 /* TODO FIXME - don't pass umode buffer to an Int function */
84 ret = IntGdiEscape(dc, Escape, InSize, InData, OutData);
85
86 DC_UnlockDc( dc );
87 return ret;
88 }
89
90 INT
91 APIENTRY
92 IntEngExtEscape(
93 SURFOBJ *Surface,
94 INT Escape,
95 INT InSize,
96 LPVOID InData,
97 INT OutSize,
98 LPVOID OutData)
99 {
100 if (Escape == QUERYESCSUPPORT)
101 return FALSE;
102
103 DPRINT1("IntEngExtEscape is unimplemented. - Keep going and have a nice day\n");
104 return -1;
105 }
106
107 INT
108 APIENTRY
109 IntGdiExtEscape(
110 PDC dc,
111 INT Escape,
112 INT InSize,
113 LPCSTR InData,
114 INT OutSize,
115 LPSTR OutData)
116 {
117 SURFACE *psurf = dc->dclevel.pSurface;
118 INT Result;
119
120 /* FIXME - Handle psurf == NULL !!!!!! */
121
122 if ( NULL == dc->ppdev->DriverFunctions.Escape )
123 {
124 Result = IntEngExtEscape(
125 &psurf->SurfObj,
126 Escape,
127 InSize,
128 (PVOID)((ULONG_PTR)InData),
129 OutSize,
130 (PVOID)OutData);
131 }
132 else
133 {
134 Result = dc->ppdev->DriverFunctions.Escape(
135 &psurf->SurfObj,
136 Escape,
137 InSize,
138 (PVOID)InData,
139 OutSize,
140 (PVOID)OutData );
141 }
142
143 return Result;
144 }
145
146 INT
147 APIENTRY
148 NtGdiExtEscape(
149 HDC hDC,
150 IN OPTIONAL PWCHAR pDriver,
151 IN INT nDriver,
152 INT Escape,
153 INT InSize,
154 OPTIONAL LPSTR UnsafeInData,
155 INT OutSize,
156 OPTIONAL LPSTR UnsafeOutData)
157 {
158 PDC pDC;
159 LPVOID SafeInData = NULL;
160 LPVOID SafeOutData = NULL;
161 NTSTATUS Status = STATUS_SUCCESS;
162 INT Result;
163
164 if (hDC == 0)
165 {
166 hDC = UserGetWindowDC(NULL);
167 }
168
169 pDC = DC_LockDc(hDC);
170 if ( pDC == NULL )
171 {
172 SetLastWin32Error(ERROR_INVALID_HANDLE);
173 return -1;
174 }
175 if ( pDC->dctype == DC_TYPE_INFO)
176 {
177 DC_UnlockDc(pDC);
178 return 0;
179 }
180
181 if ( InSize && UnsafeInData )
182 {
183 _SEH2_TRY
184 {
185 ProbeForRead(UnsafeInData,
186 InSize,
187 1);
188 }
189 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
190 {
191 Status = _SEH2_GetExceptionCode();
192 }
193 _SEH2_END;
194
195 if (!NT_SUCCESS(Status))
196 {
197 DC_UnlockDc(pDC);
198 SetLastNtError(Status);
199 return -1;
200 }
201
202 SafeInData = ExAllocatePoolWithTag ( PagedPool, InSize, TAG_PRINT );
203 if ( !SafeInData )
204 {
205 DC_UnlockDc(pDC);
206 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
207 return -1;
208 }
209
210 _SEH2_TRY
211 {
212 /* pointers were already probed! */
213 RtlCopyMemory(SafeInData,
214 UnsafeInData,
215 InSize);
216 }
217 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
218 {
219 Status = _SEH2_GetExceptionCode();
220 }
221 _SEH2_END;
222
223 if ( !NT_SUCCESS(Status) )
224 {
225 ExFreePoolWithTag ( SafeInData, TAG_PRINT );
226 DC_UnlockDc(pDC);
227 SetLastNtError(Status);
228 return -1;
229 }
230 }
231
232 if ( OutSize && UnsafeOutData )
233 {
234 _SEH2_TRY
235 {
236 ProbeForWrite(UnsafeOutData,
237 OutSize,
238 1);
239 }
240 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
241 {
242 Status = _SEH2_GetExceptionCode();
243 }
244 _SEH2_END;
245
246 if (!NT_SUCCESS(Status))
247 {
248 SetLastNtError(Status);
249 goto freeout;
250 }
251
252 SafeOutData = ExAllocatePoolWithTag ( PagedPool, OutSize, TAG_PRINT );
253 if ( !SafeOutData )
254 {
255 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
256 freeout:
257 if ( SafeInData )
258 ExFreePoolWithTag ( SafeInData, TAG_PRINT );
259 DC_UnlockDc(pDC);
260 return -1;
261 }
262 }
263
264 Result = IntGdiExtEscape ( pDC, Escape, InSize, SafeInData, OutSize, SafeOutData );
265
266 DC_UnlockDc(pDC);
267
268 if ( SafeInData )
269 ExFreePoolWithTag ( SafeInData ,TAG_PRINT );
270
271 if ( SafeOutData )
272 {
273 _SEH2_TRY
274 {
275 /* pointers were already probed! */
276 RtlCopyMemory(UnsafeOutData,
277 SafeOutData,
278 OutSize);
279 }
280 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
281 {
282 Status = _SEH2_GetExceptionCode();
283 }
284 _SEH2_END;
285
286 ExFreePoolWithTag ( SafeOutData, TAG_PRINT );
287 if ( !NT_SUCCESS(Status) )
288 {
289 SetLastNtError(Status);
290 return -1;
291 }
292 }
293
294 return Result;
295 }
296
297 INT
298 APIENTRY
299 NtGdiStartDoc(
300 IN HDC hdc,
301 IN DOCINFOW *pdi,
302 OUT BOOL *pbBanding,
303 IN INT iJob)
304 {
305 UNIMPLEMENTED;
306 return 0;
307 }
308
309 INT
310 APIENTRY
311 NtGdiStartPage(HDC hDC)
312 {
313 UNIMPLEMENTED;
314 return 0;
315 }
316 /* EOF */