2 * COPYRIGHT: GPL, see COPYING in the top level directory
3 * PROJECT: ReactOS win32 kernel mode subsystem server
4 * PURPOSE: File access support routines
5 * FILE: subsystem/win32/win32k/misc/registry.c
6 * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
16 W32kDosPathNameToNtPathName(
17 IN PCWSTR pwszDosPathName
,
18 OUT PUNICODE_STRING pustrNtPathName
)
23 pustrNtPathName
->Length
= 0;
24 Status
= RtlAppendUnicodeToString(pustrNtPathName
, L
"\\??\\");
25 if (!NT_SUCCESS(Status
))
30 /* Append the dos name */
31 Status
= RtlAppendUnicodeToString(pustrNtPathName
, pwszDosPathName
);
32 if (!NT_SUCCESS(Status
))
43 W32kOpenFile(PCWSTR pwszFileName
, DWORD dwDesiredAccess
)
45 UNICODE_STRING ustrFile
;
46 OBJECT_ATTRIBUTES ObjectAttributes
;
47 IO_STATUS_BLOCK IoStatusBlock
;
48 HANDLE hFile
= INVALID_HANDLE_VALUE
;
51 DPRINT("W32kOpenFile(%S)\n", pwszFileName
);
53 RtlInitUnicodeString(&ustrFile
, pwszFileName
);
55 InitializeObjectAttributes(&ObjectAttributes
, &ustrFile
, 0, NULL
, NULL
);
57 Status
= ZwCreateFile(&hFile
,
62 FILE_ATTRIBUTE_NORMAL
,
65 FILE_NON_DIRECTORY_FILE
,
68 if (!NT_SUCCESS(Status
))
70 SetLastNtError(Status
);
74 DPRINT("Leaving W32kOpenFile, Status=0x%x, hFile=0x%x\n", Status
, hFile
);
80 W32kCreateFileSection(HANDLE hFile
,
82 DWORD flPageProtection
,
86 HANDLE hSection
= NULL
;
87 ACCESS_MASK amDesiredAccess
;
90 amDesiredAccess
= STANDARD_RIGHTS_REQUIRED
| SECTION_QUERY
| SECTION_MAP_READ
;
92 /* Check if write access is requested */
93 if (flPageProtection
== PAGE_READWRITE
)
95 /* Add it to access mask */
96 amDesiredAccess
|= SECTION_MAP_WRITE
;
99 /* Now create the actual section */
100 Status
= ZwCreateSection(&hSection
,
107 if (!NT_SUCCESS(Status
))
109 SetLastNtError(Status
);
112 DPRINT("Leaving W32kCreateFileSection, Status=0x%x, hSection=0x%x\n", Status
, hSection
);
114 /* Return section handle */
120 W32kMapViewOfSection(
123 ULONG_PTR ulSectionOffset
)
126 LARGE_INTEGER liSectionOffset
;
127 ULONG_PTR ulViewSize
;
131 liSectionOffset
.QuadPart
= ulSectionOffset
;
132 Status
= ZwMapViewOfSection(hSection
,
142 if (!NT_SUCCESS(Status
))
144 SetLastNtError(Status
);
147 DPRINT("Leaving W32kMapViewOfSection, Status=0x%x, pvBase=0x%x\n", Status
, pvBase
);
152 typedef struct tagBITMAPV5INFO
154 BITMAPV5HEADER bmiHeader
;
155 RGBQUAD bmiColors
[256];
156 } BITMAPV5INFO
, *PBITMAPV5INFO
;
158 // FIXME: this should go to dibobj.c
160 ProbeAndConvertBitmapInfo(
161 OUT BITMAPV5HEADER
*pbmhDst
,
162 OUT RGBQUAD
*pbmiColorsDst
,
164 IN PBITMAPINFO pbmiUnsafe
)
170 /* Get the size and probe */
171 ProbeForRead(&pbmiUnsafe
->bmiHeader
.biSize
, sizeof(DWORD
), 1);
172 dwSize
= pbmiUnsafe
->bmiHeader
.biSize
;
173 ProbeForRead(pbmiUnsafe
, dwSize
, 1);
176 // FIXME: are intermediate sizes allowed? As what are they interpreted?
177 // make sure we don't use a too big dwSize later
178 if (dwSize
!= sizeof(BITMAPCOREHEADER
) &&
179 dwSize
!= sizeof(BITMAPINFOHEADER
) &&
180 dwSize
!= sizeof(BITMAPV4HEADER
) &&
181 dwSize
!= sizeof(BITMAPV5HEADER
))
183 return STATUS_INVALID_PARAMETER
;
186 pbmiColors
= (RGBQUAD
*)((PCHAR
)pbmiUnsafe
+ dwSize
);
188 pbmhDst
->bV5Size
= sizeof(BITMAPV5HEADER
);
190 if (dwSize
== sizeof(BITMAPCOREHEADER
))
192 PBITMAPCOREHEADER pbch
= (PBITMAPCOREHEADER
)pbmiUnsafe
;
194 /* Manually copy the fields that are present */
195 pbmhDst
->bV5Width
= pbch
->bcWidth
;
196 pbmhDst
->bV5Height
= pbch
->bcHeight
;
197 pbmhDst
->bV5Planes
= pbch
->bcPlanes
;
198 pbmhDst
->bV5BitCount
= pbch
->bcBitCount
;
200 /* Set some default values */
201 pbmhDst
->bV5Compression
= BI_RGB
;
202 pbmhDst
->bV5SizeImage
= 0;
203 pbmhDst
->bV5XPelsPerMeter
= 72;
204 pbmhDst
->bV5YPelsPerMeter
= 72;
205 pbmhDst
->bV5ClrUsed
= 0;
206 pbmhDst
->bV5ClrImportant
= 0;
210 /* Copy valid fields */
211 memcpy(pbmhDst
, pbmiUnsafe
, dwSize
);
213 /* Zero out the rest of the V5 header */
214 memset((char*)pbmhDst
+ dwSize
, 0, sizeof(BITMAPV5HEADER
) - dwSize
);
218 if (dwSize
< sizeof(BITMAPV4HEADER
))
220 if (pbmhDst
->bV5Compression
== BI_BITFIELDS
)
222 DWORD
*pMasks
= (DWORD
*)pbmiColors
;
223 pbmhDst
->bV5RedMask
= pMasks
[0];
224 pbmhDst
->bV5GreenMask
= pMasks
[1];
225 pbmhDst
->bV5BlueMask
= pMasks
[2];
226 pbmhDst
->bV5AlphaMask
= 0;
227 pbmhDst
->bV5ClrUsed
= 0;
230 // pbmhDst->bV5CSType;
231 // pbmhDst->bV5Endpoints;
232 // pbmhDst->bV5GammaRed;
233 // pbmhDst->bV5GammaGreen;
234 // pbmhDst->bV5GammaBlue;
237 if (dwSize
< sizeof(BITMAPV5HEADER
))
239 // pbmhDst->bV5Intent;
240 // pbmhDst->bV5ProfileData;
241 // pbmhDst->bV5ProfileSize;
242 // pbmhDst->bV5Reserved;
245 ulWidthBytes
= ((pbmhDst
->bV5Width
* pbmhDst
->bV5Planes
*
246 pbmhDst
->bV5BitCount
+ 31) & ~31) / 8;
248 if (pbmhDst
->bV5SizeImage
== 0)
249 pbmhDst
->bV5SizeImage
= abs(ulWidthBytes
* pbmhDst
->bV5Height
);
251 if (pbmhDst
->bV5ClrUsed
== 0)
252 pbmhDst
->bV5ClrUsed
= pbmhDst
->bV5BitCount
== 1 ? 2 :
253 (pbmhDst
->bV5BitCount
== 4 ? 16 :
254 (pbmhDst
->bV5BitCount
== 8 ? 256 : 0));
256 if (pbmhDst
->bV5Planes
!= 1)
258 return STATUS_INVALID_PARAMETER
;
261 if (pbmhDst
->bV5BitCount
!= 0 && pbmhDst
->bV5BitCount
!= 1 &&
262 pbmhDst
->bV5BitCount
!= 4 && pbmhDst
->bV5BitCount
!= 8 &&
263 pbmhDst
->bV5BitCount
!= 16 && pbmhDst
->bV5BitCount
!= 24 &&
264 pbmhDst
->bV5BitCount
!= 32)
266 DPRINT("Invalid bit count: %d\n", pbmhDst
->bV5BitCount
);
267 return STATUS_INVALID_PARAMETER
;
270 if ((pbmhDst
->bV5BitCount
== 0 &&
271 pbmhDst
->bV5Compression
!= BI_JPEG
&& pbmhDst
->bV5Compression
!= BI_PNG
))
273 DPRINT("Bit count 0 is invalid for compression %d.\n", pbmhDst
->bV5Compression
);
274 return STATUS_INVALID_PARAMETER
;
277 if (pbmhDst
->bV5Compression
== BI_BITFIELDS
&&
278 pbmhDst
->bV5BitCount
!= 16 && pbmhDst
->bV5BitCount
!= 32)
280 DPRINT("Bit count %d is invalid for compression BI_BITFIELDS.\n", pbmhDst
->bV5BitCount
);
281 return STATUS_INVALID_PARAMETER
;
285 cColors
= min(cColors
, pbmhDst
->bV5ClrUsed
);
286 memcpy(pbmiColorsDst
, pbmiColors
, cColors
* sizeof(RGBQUAD
));
288 return STATUS_SUCCESS
;
294 UserLoadImage(PCWSTR pwszName
)
297 HANDLE hFile
, hSection
;
298 BITMAPFILEHEADER
*pbmfh
;
303 BITMAPV5INFO bmiLocal
;
306 hFile
= W32kOpenFile(pwszName
, FILE_READ_DATA
);
307 if (hFile
== INVALID_HANDLE_VALUE
)
310 /* Create a section */
311 hSection
= W32kCreateFileSection(hFile
, SEC_COMMIT
, PAGE_READONLY
, 0);
316 /* Map the section */
317 pbmfh
= W32kMapViewOfSection(hSection
, PAGE_READONLY
, 0);
322 /* Get a pointer to the BITMAPINFO */
323 pbmi
= (LPBITMAPINFO
)(pbmfh
+ 1);
325 /* Create a normalized local BITMAPINFO */
328 Status
= ProbeAndConvertBitmapInfo(&bmiLocal
.bmiHeader
,
333 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
335 Status
= _SEH2_GetExceptionCode();
339 if (NT_SUCCESS(Status
))
341 cjInfoSize
= bmiLocal
.bmiHeader
.bV5Size
+
342 bmiLocal
.bmiHeader
.bV5ClrUsed
* sizeof(RGBQUAD
);
343 pvBits
= (PVOID
)((PCHAR
)pbmi
+ cjInfoSize
);
345 // FIXME: use Gre... so that the BITMAPINFO doesn't get probed
346 hbmp
= NtGdiCreateDIBitmapInternal(NULL
,
347 bmiLocal
.bmiHeader
.bV5Width
,
348 bmiLocal
.bmiHeader
.bV5Height
,
353 bmiLocal
.bmiHeader
.bV5Size
,
354 bmiLocal
.bmiHeader
.bV5SizeImage
,
359 /* Unmap our section, we don't need it anymore */
360 ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh
);
362 DPRINT("Leaving UserLoadImage, hbmp = %p\n", hbmp
);