21 #if 0 // Remove once new EnhMetaFile support is implemented.
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 */
36 DWORD size
= 0, length
= 0;
38 mDC
= NtGdiCreateMetafileDC( hDC
); // Basically changes the handle from 1xxxx to 46xxxx.
39 // If hDC == NULL, works just like createdc in win32k.
41 if ( !GdiGetHandleUserData((HGDIOBJ
) mDC
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
))
43 SetLastError (ERROR_INVALID_PARAMETER
);
44 return NULL
; // need to delete the handle?
47 pLDC
= LocalAlloc(LMEM_ZEROINIT
, sizeof(LDC
));
49 Dc_Attr
->pvLDC
= pLDC
;
51 pLDC
->iType
= LDC_EMFDC
56 /* App name\0Title\0\0 */
57 length
= lstrlenW(description
);
58 length
+= lstrlenW(description
+ length
+ 1);
63 size
= sizeof(ENHMETAFILE
) + (length
+ 3) / 4 * 4;
65 //Allocate ENHMETAFILE structure
66 EmfDC
= LocalAlloc(LMEM_ZEROINIT
, sizeof(ENHMETAFILE
));
67 pLDC
->pvEmfDC
= EmfDC
;
69 EmfDC
->handles_size
= HANDLE_LIST_INC
;
70 EmfDC
->cur_handles
= 1;
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
);
84 EmfDC
->emf
= LocalAlloc(LMEM_ZEROINIT
, size
);
86 EmfDC
->emf
->iType
= EMR_HEADER
;
87 EmfDC
->emf
->nSize
= size
;
89 EmfDC
->emf
->rclBounds
.left
= EmfDC
->emf
->rclBounds
.top
= 0;
90 EmfDC
->emf
->rclBounds
.right
= EmfDC
->emf
->rclBounds
.bottom
= -1;
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
;
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;
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;
112 EmfDC
->emf
->sReserved
= 0; /* According to docs, this is reserved and must be 0 */
113 EmfDC
->emf
->nDescription
= length
/ 2;
115 EmfDC
->emf
->offDescription
= length
? sizeof(ENHMETAHEADER
) : 0;
117 EmfDC
->emf
->nPalEntries
= 0; /* I guess this should start at 0 */
120 EmfDC
->emf
->szlDevice
.cx
= EmfDC
->horzres
;
121 EmfDC
->emf
->szlDevice
.cy
= EmfDC
->vertres
;
123 /* Size in millimeters */
124 EmfDC
->emf
->szlMillimeters
.cx
= EmfDC
->horzsize
;
125 EmfDC
->emf
->szlMillimeters
.cy
= EmfDC
->vertsize
;
127 /* Size in micrometers */
128 EmfDC
->emf
->szlMicrometers
.cx
= EmfDC
->horzsize
* 1000;
129 EmfDC
->emf
->szlMicrometers
.cy
= EmfDC
->vertsize
* 1000;
131 RtlCopyMemory((char *)EmfDC
->emf
+ sizeof(ENHMETAHEADER
), description
, length
);
133 if (filename
) /* disk based metafile */
135 if ((hFile
= CreateFileW(filename
, GENERIC_WRITE
| GENERIC_READ
, 0,
136 NULL
, CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
)
138 EMFDRV_DeleteDC( EmfDC
);
141 if (!WriteFile( hFile
, (LPSTR
)EmfDC
->emf
, size
, NULL
, NULL
))
143 EMFDRV_DeleteDC( EmfDC
);
147 EmfDC
.iType
= METAFILE_DISK
;
150 EmfDC
.iType
= METAFILE_MEMORY
;
163 HENHMETAFILE hemfSrc
,
170 Status
= HEAP_strdupA2W ( &lpszFileW
, lpszFile
);
171 if (!NT_SUCCESS (Status
))
172 SetLastError (RtlNtStatusToDosError(Status
));
177 HEAP_free ( lpszFileW
);
192 LPCSTR lpDescription
)
195 LPWSTR lpFileNameW
, lpDescriptionW
;
199 if (lpFileName
!= NULL
)
201 Status
= HEAP_strdupA2W ( &lpFileNameW
, lpFileName
);
202 if (!NT_SUCCESS (Status
))
203 SetLastError (RtlNtStatusToDosError(Status
));
208 lpDescriptionW
= NULL
;
209 if (lpDescription
!= NULL
)
211 Status
= HEAP_strdupA2W ( &lpDescriptionW
, lpDescription
);
212 if (!NT_SUCCESS (Status
))
213 SetLastError (RtlNtStatusToDosError(Status
));
220 if (lpDescriptionW
!= NULL
)
221 HEAP_free ( lpDescriptionW
);
223 if (lpFileNameW
!= NULL
)
224 HEAP_free ( lpFileNameW
);
230 /* Previous implementation in win32k */
233 NtGdiCreateEnhMetaFile(HDC hDCRef
,
243 DWORD dwDesiredAccess
;
249 * Shall we create hdc NtGdiHdcCompatible hdc ??
251 UNICODE_STRING DriverName
;
252 RtlInitUnicodeString(&DriverName
, L
"DISPLAY");
253 //IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
254 tempHDC
= NtGdiOpenDCW( &DriverName
,
257 0, // DCW 0 and ICW 1.
263 GDIOBJ_SetOwnership(GdiHandleTable
, tempHDC
, PsGetCurrentProcess());
264 DC_SetOwnership(tempHDC
, PsGetCurrentProcess());
266 Dc
= DC_LockDc(tempHDC
);
271 NtGdiDeleteObjectApp(tempHDC
);
273 SetLastWin32Error(ERROR_INVALID_HANDLE
);
279 length
= wcslen(Description
);
280 length
+= wcslen(Description
+ length
+ 1);
285 MemSize
= sizeof(ENHMETAHEADER
) + (length
+ 3) / 4 * 4;
287 if (!(Dc
->emh
= EngAllocMem(FL_ZERO_MEMORY
, MemSize
, 0)))
292 NtGdiDeleteObjectApp(tempHDC
);
294 SetLastWin32Error(ERROR_INVALID_HANDLE
);
298 Dc
->emh
->iType
= EMR_HEADER
;
299 Dc
->emh
->nSize
= MemSize
;
301 Dc
->emh
->rclBounds
.left
= Dc
->emh
->rclBounds
.top
= 0;
302 Dc
->emh
->rclBounds
.right
= Dc
->emh
->rclBounds
.bottom
= -1;
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
;
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;
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;
324 Dc
->emh
->sReserved
= 0; /* According to docs, this is reserved and must be 0 */
325 Dc
->emh
->nDescription
= length
/ 2;
327 Dc
->emh
->offDescription
= length
? sizeof(ENHMETAHEADER
) : 0;
329 Dc
->emh
->nPalEntries
= 0; /* I guess this should start at 0 */
332 Dc
->emh
->szlDevice
.cx
= NtGdiGetDeviceCaps(tempHDC
, HORZRES
);
333 Dc
->emh
->szlDevice
.cy
= NtGdiGetDeviceCaps(tempHDC
, VERTRES
);
335 /* Size in millimeters */
336 Dc
->emh
->szlMillimeters
.cx
= NtGdiGetDeviceCaps(tempHDC
, HORZSIZE
);
337 Dc
->emh
->szlMillimeters
.cy
= NtGdiGetDeviceCaps(tempHDC
, VERTSIZE
);
339 /* Size in micrometers */
340 Dc
->emh
->szlMicrometers
.cx
= Dc
->emh
->szlMillimeters
.cx
* 1000;
341 Dc
->emh
->szlMicrometers
.cy
= Dc
->emh
->szlMillimeters
.cy
* 1000;
345 memcpy((char *)Dc
->emh
+ sizeof(ENHMETAHEADER
), Description
, length
);
351 OBJECT_ATTRIBUTES ObjectAttributes
;
352 IO_STATUS_BLOCK IoStatusBlock
;
353 IO_STATUS_BLOCK Iosb
;
354 UNICODE_STRING NtPathU
;
356 ULONG FileAttributes
= (FILE_ATTRIBUTE_VALID_FLAGS
& ~FILE_ATTRIBUTE_DIRECTORY
);
358 DPRINT1("Trying Create EnhMetaFile\n");
360 /* disk based metafile */
361 dwDesiredAccess
= GENERIC_WRITE
| GENERIC_READ
| SYNCHRONIZE
| FILE_READ_ATTRIBUTES
;
363 if (!RtlDosPathNameToNtPathName_U (File
, &NtPathU
, NULL
, NULL
))
368 NtGdiDeleteObjectApp(tempHDC
);
370 DPRINT1("Can not Create EnhMetaFile\n");
371 SetLastWin32Error(ERROR_PATH_NOT_FOUND
);
375 InitializeObjectAttributes(&ObjectAttributes
, &NtPathU
, 0, NULL
, NULL
);
377 Status
= NtCreateFile (&Dc
->hFile
, dwDesiredAccess
, &ObjectAttributes
, &IoStatusBlock
,
378 NULL
, FileAttributes
, 0, FILE_OVERWRITE_IF
, FILE_NON_DIRECTORY_FILE
,
381 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathU
.Buffer
);
383 if (!NT_SUCCESS(Status
))
389 NtGdiDeleteObjectApp(tempHDC
);
391 DPRINT1("Create EnhMetaFile fail\n");
392 SetLastWin32Error(ERROR_INVALID_HANDLE
);
396 SetLastWin32Error(IoStatusBlock
.Information
== FILE_OVERWRITTEN
? ERROR_ALREADY_EXISTS
: 0);
398 Status
= NtWriteFile(Dc
->hFile
, NULL
, NULL
, NULL
, &Iosb
, (PVOID
)&Dc
->emh
, Dc
->emh
->nSize
, NULL
, NULL
);
399 if (Status
== STATUS_PENDING
)
401 Status
= NtWaitForSingleObject(Dc
->hFile
,FALSE
,NULL
);
402 if (NT_SUCCESS(Status
))
404 Status
= Iosb
.Status
;
408 if (NT_SUCCESS(Status
))
416 DPRINT1("Write to EnhMetaFile fail\n");
417 SetLastWin32Error(ERROR_CAN_NOT_COMPLETE
);
422 NtGdiDeleteObjectApp(tempHDC
);
446 LPWSTR lpszMetaFileW
;
449 Status
= HEAP_strdupA2W ( &lpszMetaFileW
, lpszMetaFile
);
450 if (!NT_SUCCESS (Status
))
451 SetLastError (RtlNtStatusToDosError(Status
));
456 HEAP_free ( lpszMetaFileW
);
468 GetEnhMetaFileDescriptionA(
471 LPSTR lpszDescription
)
474 LPWSTR lpszDescriptionW
;
476 if ( lpszDescription
&& cchBuffer
)
478 lpszDescriptionW
= (LPWSTR
)HEAP_alloc ( cchBuffer
*sizeof(WCHAR
) );
479 if ( !lpszDescriptionW
)
481 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY
));
486 lpszDescriptionW
= NULL
;
488 if ( lpszDescription
&& cchBuffer
)
490 Status
= RtlUnicodeToMultiByteN ( lpszDescription
,
495 HEAP_free ( lpszDescriptionW
);
496 if ( !NT_SUCCESS(Status
) )
498 SetLastError (RtlNtStatusToDosError(Status
));
508 /* Unimplemented functions */
513 HENHMETAFILE hemfSrc
,
524 LPCWSTR lpszMetaFile
)
533 GetEnhMetaFileDescriptionW(
536 LPWSTR lpszDescription
)
549 LPCWSTR lpDescription
)