fast bugfix, NtGdiExtEscape should accpect a NULL hdc.
[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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$ */
20
21 #include <w32k.h>
22
23 #define NDEBUG
24 #include <debug.h>
25
26 INT
27 STDCALL
28 NtGdiAbortDoc(HDC hDC)
29 {
30 UNIMPLEMENTED;
31 return 0;
32 }
33
34 INT
35 STDCALL
36 NtGdiEndDoc(HDC hDC)
37 {
38 UNIMPLEMENTED;
39 return 0;
40 }
41
42 INT
43 STDCALL
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 STDCALL
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 STDCALL
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 STDCALL
109 IntGdiExtEscape(
110 PDC dc,
111 INT Escape,
112 INT InSize,
113 LPCSTR InData,
114 INT OutSize,
115 LPSTR OutData)
116 {
117 BITMAPOBJ *BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
118 INT Result;
119
120 /* FIXME - Handle BitmapObj == NULL !!!!!! */
121
122 if ( NULL == dc->DriverFunctions.Escape )
123 {
124 Result = IntEngExtEscape(
125 &BitmapObj->SurfObj,
126 Escape,
127 InSize,
128 (PVOID)((ULONG_PTR)InData),
129 OutSize,
130 (PVOID)OutData);
131 }
132 else
133 {
134 Result = dc->DriverFunctions.Escape(
135 &BitmapObj->SurfObj,
136 Escape,
137 InSize,
138 (PVOID)InData,
139 OutSize,
140 (PVOID)OutData );
141 }
142 BITMAPOBJ_UnlockBitmap(BitmapObj);
143
144 return Result;
145 }
146
147 INT
148 STDCALL
149 NtGdiExtEscape(
150 HDC hDC,
151 IN OPTIONAL PWCHAR pDriver,
152 IN INT nDriver,
153 INT Escape,
154 INT InSize,
155 OPTIONAL LPSTR UnsafeInData,
156 INT OutSize,
157 OPTIONAL LPSTR UnsafeOutData)
158 {
159 PDC pDC;
160 LPVOID SafeInData = NULL;
161 LPVOID SafeOutData = NULL;
162 NTSTATUS Status = STATUS_SUCCESS;
163 INT Result;
164
165 if (hDC == 0)
166 {
167 hDC = (HDC)UserGetWindowDC(NULL);
168 }
169
170 pDC = DC_LockDc(hDC);
171 if ( pDC == NULL )
172 {
173 SetLastWin32Error(ERROR_INVALID_HANDLE);
174 return -1;
175 }
176 if ( pDC->IsIC )
177 {
178 DC_UnlockDc(pDC);
179 return 0;
180 }
181
182 if ( InSize && UnsafeInData )
183 {
184 _SEH_TRY
185 {
186 ProbeForRead(UnsafeInData,
187 InSize,
188 1);
189 }
190 _SEH_HANDLE
191 {
192 Status = _SEH_GetExceptionCode();
193 }
194 _SEH_END;
195
196 if (!NT_SUCCESS(Status))
197 {
198 DC_UnlockDc(pDC);
199 SetLastNtError(Status);
200 return -1;
201 }
202
203 SafeInData = ExAllocatePoolWithTag ( PagedPool, InSize, TAG_PRINT );
204 if ( !SafeInData )
205 {
206 DC_UnlockDc(pDC);
207 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
208 return -1;
209 }
210
211 _SEH_TRY
212 {
213 /* pointers were already probed! */
214 RtlCopyMemory(SafeInData,
215 UnsafeInData,
216 InSize);
217 }
218 _SEH_HANDLE
219 {
220 Status = _SEH_GetExceptionCode();
221 }
222 _SEH_END;
223
224 if ( !NT_SUCCESS(Status) )
225 {
226 ExFreePool ( SafeInData );
227 DC_UnlockDc(pDC);
228 SetLastNtError(Status);
229 return -1;
230 }
231 }
232
233 if ( OutSize && UnsafeOutData )
234 {
235 _SEH_TRY
236 {
237 ProbeForWrite(UnsafeOutData,
238 OutSize,
239 1);
240 }
241 _SEH_HANDLE
242 {
243 Status = _SEH_GetExceptionCode();
244 }
245 _SEH_END;
246
247 if (!NT_SUCCESS(Status))
248 {
249 SetLastNtError(Status);
250 goto freeout;
251 }
252
253 SafeOutData = ExAllocatePoolWithTag ( PagedPool, OutSize, TAG_PRINT );
254 if ( !SafeOutData )
255 {
256 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
257 freeout:
258 if ( SafeInData )
259 ExFreePool ( SafeInData );
260 DC_UnlockDc(pDC);
261 return -1;
262 }
263 }
264
265 Result = IntGdiExtEscape ( pDC, Escape, InSize, SafeInData, OutSize, SafeOutData );
266
267 DC_UnlockDc(pDC);
268
269 if ( SafeInData )
270 ExFreePool ( SafeInData );
271
272 if ( SafeOutData )
273 {
274 _SEH_TRY
275 {
276 /* pointers were already probed! */
277 RtlCopyMemory(UnsafeOutData,
278 SafeOutData,
279 OutSize);
280 }
281 _SEH_HANDLE
282 {
283 Status = _SEH_GetExceptionCode();
284 }
285 _SEH_END;
286
287 ExFreePool ( SafeOutData );
288 if ( !NT_SUCCESS(Status) )
289 {
290 SetLastNtError(Status);
291 return -1;
292 }
293 }
294
295 return Result;
296 }
297
298 INT
299 APIENTRY
300 NtGdiStartDoc(
301 IN HDC hdc,
302 IN DOCINFOW *pdi,
303 OUT BOOL *pbBanding,
304 IN INT iJob)
305 {
306 UNIMPLEMENTED;
307 return 0;
308 }
309
310 INT
311 STDCALL
312 NtGdiStartPage(HDC hDC)
313 {
314 UNIMPLEMENTED;
315 return 0;
316 }
317 /* EOF */