1 #include <precomp.h> 2 3 #define NDEBUG 4 #include <debug.h> 5 6 7 8 /* 9 * @unimplemented 10 */ 11 HENHMETAFILE 12 WINAPI 13 CloseEnhMetaFile( 14 HDC hdc) 15 { 16 UNIMPLEMENTED; 17 return 0; 18 } 19 20 21 #if 0 // Remove once new EnhMetaFile support is implemented. 22 HDC 23 WINAPI 24 CreateEnhMetaFileW( 25 HDC hDC, /* [in] optional reference DC */ 26 LPCWSTR filename, /* [in] optional filename for disk metafiles */ 27 const RECT* rect, /* [in] optional bounding rectangle */ 28 LPCWSTR description /* [in] optional description */ 29 ) 30 { 31 HDC mDC; 32 PDC_ATTR Dc_Attr; 33 PLDC pLDC; 34 HANDLE hFile; 35 PENHMETAFILE EmfDC; 36 DWORD size = 0, length = 0; 37 38 mDC = NtGdiCreateMetafileDC( hDC ); // Basically changes the handle from 1xxxx to 46xxxx. 39 // If hDC == NULL, works just like createdc in win32k. 40 41 if ( !GdiGetHandleUserData((HGDIOBJ) mDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) 42 { 43 SetLastError (ERROR_INVALID_PARAMETER); 44 return NULL; // need to delete the handle? 45 } 46 47 pLDC = LocalAlloc(LMEM_ZEROINIT, sizeof(LDC)); 48 49 Dc_Attr->pvLDC = pLDC; 50 pLDC->hDC = mDC; 51 pLDC->iType = LDC_EMFDC 52 53 54 if (description) 55 { 56 /* App name\0Title\0\0 */ 57 length = lstrlenW(description); 58 length += lstrlenW(description + length + 1); 59 length += 3; 60 length *= 2; 61 } 62 63 size = sizeof(ENHMETAFILE) + (length + 3) / 4 * 4; 64 65 //Allocate ENHMETAFILE structure 66 EmfDC = LocalAlloc(LMEM_ZEROINIT, sizeof(ENHMETAFILE)); 67 pLDC->pvEmfDC = EmfDC; 68 69 EmfDC->handles_size = HANDLE_LIST_INC; 70 EmfDC->cur_handles = 1; 71 72 EmfDC->horzres = GetDeviceCaps(mDC, HORZRES); 73 EmfDC->vertres = GetDeviceCaps(mDC, VERTRES); 74 EmfDC->logpixelsx = GetDeviceCaps(mDC, LOGPIXELSX); 75 EmfDC->logpixelsy = GetDeviceCaps(mDC, LOGPIXELSY); 76 EmfDC->horzsize = GetDeviceCaps(mDC, HORZSIZE); 77 EmfDC->vertsize = GetDeviceCaps(mDC, VERTSIZE); 78 EmfDC->bitspixel = GetDeviceCaps(mDC, BITSPIXEL); 79 EmfDC->textcaps = GetDeviceCaps(mDC, TEXTCAPS); 80 EmfDC->rastercaps = GetDeviceCaps(mDC, RASTERCAPS); 81 EmfDC->technology = GetDeviceCaps(mDC, TECHNOLOGY); 82 EmfDC->planes = GetDeviceCaps(mDC, PLANES); 83 84 EmfDC->emf = LocalAlloc(LMEM_ZEROINIT, size); 85 86 EmfDC->emf->iType = EMR_HEADER; 87 EmfDC->emf->nSize = size; 88 89 EmfDC->emf->rclBounds.left = EmfDC->emf->rclBounds.top = 0; 90 EmfDC->emf->rclBounds.right = EmfDC->emf->rclBounds.bottom = -1; 91 92 if(rect) 93 { 94 EmfDC->emf->rclFrame.left = rect->left; 95 EmfDC->emf->rclFrame.top = rect->top; 96 EmfDC->emf->rclFrame.right = rect->right; 97 EmfDC->emf->rclFrame.bottom = rect->bottom; 98 } 99 else 100 { 101 /* Set this to {0,0 - -1,-1} and update it at the end */ 102 EmfDC->emf->rclFrame.left = EmfDC->emf->rclFrame.top = 0; 103 EmfDC->emf->rclFrame.right = EmfDC->emf->rclFrame.bottom = -1; 104 } 105 106 EmfDC->emf->dSignature = ENHMETA_SIGNATURE; 107 EmfDC->emf->nVersion = 0x10000; 108 EmfDC->emf->nBytes = pLDC->pvEmfDC->nSize; 109 EmfDC->emf->nRecords = 1; 110 EmfDC->emf->nHandles = 1; 111 112 EmfDC->emf->sReserved = 0; /* According to docs, this is reserved and must be 0 */ 113 EmfDC->emf->nDescription = length / 2; 114 115 EmfDC->emf->offDescription = length ? sizeof(ENHMETAHEADER) : 0; 116 117 EmfDC->emf->nPalEntries = 0; /* I guess this should start at 0 */ 118 119 /* Size in pixels */ 120 EmfDC->emf->szlDevice.cx = EmfDC->horzres; 121 EmfDC->emf->szlDevice.cy = EmfDC->vertres; 122 123 /* Size in millimeters */ 124 EmfDC->emf->szlMillimeters.cx = EmfDC->horzsize; 125 EmfDC->emf->szlMillimeters.cy = EmfDC->vertsize; 126 127 /* Size in micrometers */ 128 EmfDC->emf->szlMicrometers.cx = EmfDC->horzsize * 1000; 129 EmfDC->emf->szlMicrometers.cy = EmfDC->vertsize * 1000; 130 131 RtlCopyMemory((char *)EmfDC->emf + sizeof(ENHMETAHEADER), description, length); 132 133 if (filename) /* disk based metafile */ 134 { 135 if ((hFile = CreateFileW(filename, GENERIC_WRITE | GENERIC_READ, 0, 136 NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) 137 { 138 EMFDRV_DeleteDC( EmfDC ); 139 return NULL; 140 } 141 if (!WriteFile( hFile, (LPSTR)EmfDC->emf, size, NULL, NULL )) 142 { 143 EMFDRV_DeleteDC( EmfDC ); 144 return NULL; 145 } 146 EmfDC.hFile = hFile; 147 EmfDC.iType = METAFILE_DISK; 148 } 149 else 150 EmfDC.iType = METAFILE_MEMORY; 151 152 return mDC; 153 } 154 #endif 155 156 157 /* 158 * @unimplemented 159 */ 160 HENHMETAFILE 161 WINAPI 162 CopyEnhMetaFileA( 163 HENHMETAFILE hemfSrc, 164 LPCSTR lpszFile) 165 { 166 NTSTATUS Status; 167 LPWSTR lpszFileW; 168 HENHMETAFILE rc = 0; 169 170 Status = HEAP_strdupA2W ( &lpszFileW, lpszFile ); 171 if (!NT_SUCCESS (Status)) 172 SetLastError (RtlNtStatusToDosError(Status)); 173 else 174 { 175 rc = NULL; 176 177 HEAP_free ( lpszFileW ); 178 } 179 return rc; 180 } 181 182 183 /* 184 * @unimplemented 185 */ 186 HDC 187 WINAPI 188 CreateEnhMetaFileA( 189 HDC hdcRef, 190 LPCSTR lpFileName, 191 CONST RECT *lpRect, 192 LPCSTR lpDescription) 193 { 194 NTSTATUS Status; 195 LPWSTR lpFileNameW, lpDescriptionW; 196 HDC rc = 0; 197 198 lpFileNameW = NULL; 199 if (lpFileName != NULL) 200 { 201 Status = HEAP_strdupA2W ( &lpFileNameW, lpFileName ); 202 if (!NT_SUCCESS (Status)) 203 SetLastError (RtlNtStatusToDosError(Status)); 204 205 return rc; 206 } 207 208 lpDescriptionW = NULL; 209 if (lpDescription != NULL) 210 { 211 Status = HEAP_strdupA2W ( &lpDescriptionW, lpDescription ); 212 if (!NT_SUCCESS (Status)) 213 SetLastError (RtlNtStatusToDosError(Status)); 214 215 return rc; 216 } 217 218 rc = NULL; 219 220 if (lpDescriptionW != NULL) 221 HEAP_free ( lpDescriptionW ); 222 223 if (lpFileNameW != NULL) 224 HEAP_free ( lpFileNameW ); 225 226 return rc; 227 } 228 229 #if 0 230 /* Previous implementation in win32k */ 231 HDC 232 WINAPI 233 NtGdiCreateEnhMetaFile(HDC hDCRef, 234 LPCWSTR File, 235 CONST LPRECT Rect, 236 LPCWSTR Description) 237 { 238 PDC Dc; 239 HDC ret = NULL; 240 DWORD length = 0; 241 HDC tempHDC; 242 DWORD MemSize; 243 DWORD dwDesiredAccess; 244 245 tempHDC = hDCRef; 246 if (hDCRef == NULL) 247 { 248 /* FIXME ?? 249 * Shall we create hdc NtGdiHdcCompatible hdc ?? 250 */ 251 UNICODE_STRING DriverName; 252 RtlInitUnicodeString(&DriverName, L"DISPLAY"); 253 //IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE); 254 tempHDC = NtGdiOpenDCW( &DriverName, 255 NULL, 256 NULL, 257 0, // DCW 0 and ICW 1. 258 NULL, 259 (PVOID) NULL, 260 (PVOID) NULL ); 261 } 262 263 GDIOBJ_SetOwnership(GdiHandleTable, tempHDC, PsGetCurrentProcess()); 264 DC_SetOwnership(tempHDC, PsGetCurrentProcess()); 265 266 Dc = DC_LockDc(tempHDC); 267 if (Dc == NULL) 268 { 269 if (hDCRef == NULL) 270 { 271 NtGdiDeleteObjectApp(tempHDC); 272 } 273 SetLastWin32Error(ERROR_INVALID_HANDLE); 274 return NULL; 275 } 276 277 if(Description) 278 { 279 length = wcslen(Description); 280 length += wcslen(Description + length + 1); 281 length += 3; 282 length *= 2; 283 } 284 285 MemSize = sizeof(ENHMETAHEADER) + (length + 3) / 4 * 4; 286 287 if (!(Dc->emh = EngAllocMem(FL_ZERO_MEMORY, MemSize, 0))) 288 { 289 DC_UnlockDc(Dc); 290 if (hDCRef == NULL) 291 { 292 NtGdiDeleteObjectApp(tempHDC); 293 } 294 SetLastWin32Error(ERROR_INVALID_HANDLE); 295 return NULL; 296 } 297 298 Dc->emh->iType = EMR_HEADER; 299 Dc->emh->nSize = MemSize; 300 301 Dc->emh->rclBounds.left = Dc->emh->rclBounds.top = 0; 302 Dc->emh->rclBounds.right = Dc->emh->rclBounds.bottom = -1; 303 304 if(Rect) 305 { 306 Dc->emh->rclFrame.left = Rect->left; 307 Dc->emh->rclFrame.top = Rect->top; 308 Dc->emh->rclFrame.right = Rect->right; 309 Dc->emh->rclFrame.bottom = Rect->bottom; 310 } 311 else 312 { 313 /* Set this to {0,0 - -1,-1} and update it at the end */ 314 Dc->emh->rclFrame.left = Dc->emh->rclFrame.top = 0; 315 Dc->emh->rclFrame.right = Dc->emh->rclFrame.bottom = -1; 316 } 317 318 Dc->emh->dSignature = ENHMETA_SIGNATURE; 319 Dc->emh->nVersion = 0x10000; 320 Dc->emh->nBytes = Dc->emh->nSize; 321 Dc->emh->nRecords = 1; 322 Dc->emh->nHandles = 1; 323 324 Dc->emh->sReserved = 0; /* According to docs, this is reserved and must be 0 */ 325 Dc->emh->nDescription = length / 2; 326 327 Dc->emh->offDescription = length ? sizeof(ENHMETAHEADER) : 0; 328 329 Dc->emh->nPalEntries = 0; /* I guess this should start at 0 */ 330 331 /* Size in pixels */ 332 Dc->emh->szlDevice.cx = NtGdiGetDeviceCaps(tempHDC, HORZRES); 333 Dc->emh->szlDevice.cy = NtGdiGetDeviceCaps(tempHDC, VERTRES); 334 335 /* Size in millimeters */ 336 Dc->emh->szlMillimeters.cx = NtGdiGetDeviceCaps(tempHDC, HORZSIZE); 337 Dc->emh->szlMillimeters.cy = NtGdiGetDeviceCaps(tempHDC, VERTSIZE); 338 339 /* Size in micrometers */ 340 Dc->emh->szlMicrometers.cx = Dc->emh->szlMillimeters.cx * 1000; 341 Dc->emh->szlMicrometers.cy = Dc->emh->szlMillimeters.cy * 1000; 342 343 if(Description) 344 { 345 memcpy((char *)Dc->emh + sizeof(ENHMETAHEADER), Description, length); 346 } 347 348 ret = tempHDC; 349 if (File) 350 { 351 OBJECT_ATTRIBUTES ObjectAttributes; 352 IO_STATUS_BLOCK IoStatusBlock; 353 IO_STATUS_BLOCK Iosb; 354 UNICODE_STRING NtPathU; 355 NTSTATUS Status; 356 ULONG FileAttributes = (FILE_ATTRIBUTE_VALID_FLAGS & ~FILE_ATTRIBUTE_DIRECTORY); 357 358 DPRINT1("Trying Create EnhMetaFile\n"); 359 360 /* disk based metafile */ 361 dwDesiredAccess = GENERIC_WRITE | GENERIC_READ | SYNCHRONIZE | FILE_READ_ATTRIBUTES; 362 363 if (!RtlDosPathNameToNtPathName_U (File, &NtPathU, NULL, NULL)) 364 { 365 DC_UnlockDc(Dc); 366 if (hDCRef == NULL) 367 { 368 NtGdiDeleteObjectApp(tempHDC); 369 } 370 DPRINT1("Can not Create EnhMetaFile\n"); 371 SetLastWin32Error(ERROR_PATH_NOT_FOUND); 372 return NULL; 373 } 374 375 InitializeObjectAttributes(&ObjectAttributes, &NtPathU, 0, NULL, NULL); 376 377 Status = NtCreateFile (&Dc->hFile, dwDesiredAccess, &ObjectAttributes, &IoStatusBlock, 378 NULL, FileAttributes, 0, FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE, 379 NULL, 0); 380 381 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathU.Buffer); 382 383 if (!NT_SUCCESS(Status)) 384 { 385 Dc->hFile = NULL; 386 DC_UnlockDc(Dc); 387 if (hDCRef == NULL) 388 { 389 NtGdiDeleteObjectApp(tempHDC); 390 } 391 DPRINT1("Create EnhMetaFile fail\n"); 392 SetLastWin32Error(ERROR_INVALID_HANDLE); 393 return NULL; 394 } 395 396 SetLastWin32Error(IoStatusBlock.Information == FILE_OVERWRITTEN ? ERROR_ALREADY_EXISTS : 0); 397 398 Status = NtWriteFile(Dc->hFile, NULL, NULL, NULL, &Iosb, (PVOID)&Dc->emh, Dc->emh->nSize, NULL, NULL); 399 if (Status == STATUS_PENDING) 400 { 401 Status = NtWaitForSingleObject(Dc->hFile,FALSE,NULL); 402 if (NT_SUCCESS(Status)) 403 { 404 Status = Iosb.Status; 405 } 406 } 407 408 if (NT_SUCCESS(Status)) 409 { 410 ret = tempHDC; 411 DC_UnlockDc(Dc); 412 } 413 else 414 { 415 Dc->hFile = NULL; 416 DPRINT1("Write to EnhMetaFile fail\n"); 417 SetLastWin32Error(ERROR_CAN_NOT_COMPLETE); 418 ret = NULL; 419 DC_UnlockDc(Dc); 420 if (hDCRef == NULL) 421 { 422 NtGdiDeleteObjectApp(tempHDC); 423 } 424 } 425 } 426 else 427 { 428 DC_UnlockDc(Dc); 429 } 430 431 return ret; 432 } 433 #endif 434 435 436 437 /* 438 * @unimplemented 439 */ 440 HENHMETAFILE 441 WINAPI 442 GetEnhMetaFileA( 443 LPCSTR lpszMetaFile) 444 { 445 NTSTATUS Status; 446 LPWSTR lpszMetaFileW; 447 HENHMETAFILE rc = 0; 448 449 Status = HEAP_strdupA2W ( &lpszMetaFileW, lpszMetaFile ); 450 if (!NT_SUCCESS (Status)) 451 SetLastError (RtlNtStatusToDosError(Status)); 452 else 453 { 454 rc = NULL; 455 456 HEAP_free ( lpszMetaFileW ); 457 } 458 459 return rc; 460 } 461 462 463 /* 464 * @unimplemented 465 */ 466 UINT 467 WINAPI 468 GetEnhMetaFileDescriptionA( 469 HENHMETAFILE hemf, 470 UINT cchBuffer, 471 LPSTR lpszDescription) 472 { 473 NTSTATUS Status; 474 LPWSTR lpszDescriptionW; 475 476 if ( lpszDescription && cchBuffer ) 477 { 478 lpszDescriptionW = (LPWSTR)HEAP_alloc ( cchBuffer*sizeof(WCHAR) ); 479 if ( !lpszDescriptionW ) 480 { 481 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY)); 482 return 0; 483 } 484 } 485 else 486 lpszDescriptionW = NULL; 487 488 if ( lpszDescription && cchBuffer ) 489 { 490 Status = RtlUnicodeToMultiByteN ( lpszDescription, 491 cchBuffer, 492 NULL, 493 lpszDescriptionW, 494 cchBuffer ); 495 HEAP_free ( lpszDescriptionW ); 496 if ( !NT_SUCCESS(Status) ) 497 { 498 SetLastError (RtlNtStatusToDosError(Status)); 499 return 0; 500 } 501 } 502 503 return 0; 504 } 505 506 507 508 /* Unimplemented functions */ 509 510 HENHMETAFILE 511 WINAPI 512 CopyEnhMetaFileW( 513 HENHMETAFILE hemfSrc, 514 LPCWSTR lpszFile) 515 { 516 UNIMPLEMENTED; 517 return 0; 518 } 519 520 521 HENHMETAFILE 522 WINAPI 523 GetEnhMetaFileW( 524 LPCWSTR lpszMetaFile) 525 { 526 UNIMPLEMENTED; 527 return 0; 528 } 529 530 531 UINT 532 WINAPI 533 GetEnhMetaFileDescriptionW( 534 HENHMETAFILE hemf, 535 UINT cchBuffer, 536 LPWSTR lpszDescription) 537 { 538 UNIMPLEMENTED; 539 return 0; 540 } 541 542 543 HDC 544 WINAPI 545 CreateEnhMetaFileW( 546 HDC hdcRef, 547 LPCWSTR lpFileName, 548 LPCRECT lpRect, 549 LPCWSTR lpDescription) 550 { 551 UNIMPLEMENTED; 552 return 0; 553 } 554