2 * PROJECT: ReactOS Win32k Subsystem
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: win32k/objects/metafile.c
5 * PURPOSE: Metafile Implementation
9 /* INCLUDES ******************************************************************/
16 /* System Service Calls ******************************************************/
23 NtGdiConvertMetafileRect(IN HDC hDC
,
35 NtGdiCreateMetafileDC(IN HDC hdc
)
48 DWORD dwDesiredAccess
;
54 * Shall we create hdc NtGdiHdcCompatible hdc ??
56 UNICODE_STRING DriverName
;
57 RtlInitUnicodeString(&DriverName
, L
"DISPLAY");
58 //IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
59 tempHDC
= NtGdiOpenDCW( &DriverName
,
62 0, // DCW 0 and ICW 1.
68 GDIOBJ_SetOwnership(GdiHandleTable
, tempHDC
, PsGetCurrentProcess());
69 DC_SetOwnership(tempHDC
, PsGetCurrentProcess());
71 Dc
= DC_LockDc(tempHDC
);
76 NtGdiDeleteObjectApp(tempHDC
);
78 SetLastWin32Error(ERROR_INVALID_HANDLE
);
84 length
= wcslen(Description
);
85 length
+= wcslen(Description
+ length
+ 1);
90 MemSize
= sizeof(ENHMETAHEADER
) + (length
+ 3) / 4 * 4;
92 if (!(Dc
->emh
= EngAllocMem(FL_ZERO_MEMORY
, MemSize
, 0)))
97 NtGdiDeleteObjectApp(tempHDC
);
99 SetLastWin32Error(ERROR_INVALID_HANDLE
);
103 Dc
->emh
->iType
= EMR_HEADER
;
104 Dc
->emh
->nSize
= MemSize
;
106 Dc
->emh
->rclBounds
.left
= Dc
->emh
->rclBounds
.top
= 0;
107 Dc
->emh
->rclBounds
.right
= Dc
->emh
->rclBounds
.bottom
= -1;
111 Dc
->emh
->rclFrame
.left
= Rect
->left
;
112 Dc
->emh
->rclFrame
.top
= Rect
->top
;
113 Dc
->emh
->rclFrame
.right
= Rect
->right
;
114 Dc
->emh
->rclFrame
.bottom
= Rect
->bottom
;
118 /* Set this to {0,0 - -1,-1} and update it at the end */
119 Dc
->emh
->rclFrame
.left
= Dc
->emh
->rclFrame
.top
= 0;
120 Dc
->emh
->rclFrame
.right
= Dc
->emh
->rclFrame
.bottom
= -1;
123 Dc
->emh
->dSignature
= ENHMETA_SIGNATURE
;
124 Dc
->emh
->nVersion
= 0x10000;
125 Dc
->emh
->nBytes
= Dc
->emh
->nSize
;
126 Dc
->emh
->nRecords
= 1;
127 Dc
->emh
->nHandles
= 1;
129 Dc
->emh
->sReserved
= 0; /* According to docs, this is reserved and must be 0 */
130 Dc
->emh
->nDescription
= length
/ 2;
132 Dc
->emh
->offDescription
= length
? sizeof(ENHMETAHEADER
) : 0;
134 Dc
->emh
->nPalEntries
= 0; /* I guess this should start at 0 */
137 Dc
->emh
->szlDevice
.cx
= NtGdiGetDeviceCaps(tempHDC
, HORZRES
);
138 Dc
->emh
->szlDevice
.cy
= NtGdiGetDeviceCaps(tempHDC
, VERTRES
);
140 /* Size in millimeters */
141 Dc
->emh
->szlMillimeters
.cx
= NtGdiGetDeviceCaps(tempHDC
, HORZSIZE
);
142 Dc
->emh
->szlMillimeters
.cy
= NtGdiGetDeviceCaps(tempHDC
, VERTSIZE
);
144 /* Size in micrometers */
145 Dc
->emh
->szlMicrometers
.cx
= Dc
->emh
->szlMillimeters
.cx
* 1000;
146 Dc
->emh
->szlMicrometers
.cy
= Dc
->emh
->szlMillimeters
.cy
* 1000;
150 memcpy((char *)Dc
->emh
+ sizeof(ENHMETAHEADER
), Description
, length
);
156 OBJECT_ATTRIBUTES ObjectAttributes
;
157 IO_STATUS_BLOCK IoStatusBlock
;
158 IO_STATUS_BLOCK Iosb
;
159 UNICODE_STRING NtPathU
;
161 ULONG FileAttributes
= (FILE_ATTRIBUTE_VALID_FLAGS
& ~FILE_ATTRIBUTE_DIRECTORY
);
163 DPRINT1("Trying Create EnhMetaFile\n");
165 /* disk based metafile */
166 dwDesiredAccess
= GENERIC_WRITE
| GENERIC_READ
| SYNCHRONIZE
| FILE_READ_ATTRIBUTES
;
168 if (!RtlDosPathNameToNtPathName_U (File
, &NtPathU
, NULL
, NULL
))
173 NtGdiDeleteObjectApp(tempHDC
);
175 DPRINT1("Can not Create EnhMetaFile\n");
176 SetLastWin32Error(ERROR_PATH_NOT_FOUND
);
180 InitializeObjectAttributes(&ObjectAttributes
, &NtPathU
, 0, NULL
, NULL
);
182 Status
= NtCreateFile (&Dc
->hFile
, dwDesiredAccess
, &ObjectAttributes
, &IoStatusBlock
,
183 NULL
, FileAttributes
, 0, FILE_OVERWRITE_IF
, FILE_NON_DIRECTORY_FILE
,
186 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathU
.Buffer
);
188 if (!NT_SUCCESS(Status
))
194 NtGdiDeleteObjectApp(tempHDC
);
196 DPRINT1("Create EnhMetaFile fail\n");
197 SetLastWin32Error(ERROR_INVALID_HANDLE
);
201 SetLastWin32Error(IoStatusBlock
.Information
== FILE_OVERWRITTEN
? ERROR_ALREADY_EXISTS
: 0);
203 Status
= NtWriteFile(Dc
->hFile
, NULL
, NULL
, NULL
, &Iosb
, (PVOID
)&Dc
->emh
, Dc
->emh
->nSize
, NULL
, NULL
);
204 if (Status
== STATUS_PENDING
)
206 Status
= NtWaitForSingleObject(Dc
->hFile
,FALSE
,NULL
);
207 if (NT_SUCCESS(Status
))
209 Status
= Iosb
.Status
;
213 if (NT_SUCCESS(Status
))
221 DPRINT1("Write to EnhMetaFile fail\n");
222 SetLastWin32Error(ERROR_CAN_NOT_COMPLETE
);
227 NtGdiDeleteObjectApp(tempHDC
);
245 NtGdiCreateServerMetaFile(IN DWORD iType
,
261 NtGdiGetServerMetaFileBits(IN HANDLE hmo
,
263 OUT OPTIONAL PBYTE pjData
,