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 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 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 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 302 NtGdiStartPage(HDC hDC) 303 { 304 UNIMPLEMENTED; 305 return 0; 306 } 307 /* EOF */ 308