--- /dev/null
+/*
+ * COPYRIGHT: GPL, see COPYING in the top level directory
+ * PROJECT: ReactOS win32 kernel mode subsystem server
+ * PURPOSE: File access support routines
+ * FILE: subsystem/win32/win32k/misc/registry.c
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
+ */
+
+#include <win32k.h>
+
+#define NDEBUG
+#include <debug.h>
+
+BOOL
+NTAPI
+W32kDosPathNameToNtPathName(
+ IN PCWSTR pwszDosPathName,
+ OUT PUNICODE_STRING pustrNtPathName)
+{
+ NTSTATUS Status;
+
+ /* Prepend "\??\" */
+ pustrNtPathName->Length = 0;
+ Status = RtlAppendUnicodeToString(pustrNtPathName, L"\\??\\");
+ if (!NT_SUCCESS(Status))
+ {
+ return FALSE;
+ }
+
+ /* Append the dos name */
+ Status = RtlAppendUnicodeToString(pustrNtPathName, pwszDosPathName);
+ if (!NT_SUCCESS(Status))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+HANDLE
+NTAPI
+W32kOpenFile(PCWSTR pwszFileName, DWORD dwDesiredAccess)
+{
+ UNICODE_STRING ustrFile;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE hFile = INVALID_HANDLE_VALUE;
+ NTSTATUS Status;
+
+ DPRINT("W32kOpenFile(%S)\n", pwszFileName);
+
+ RtlInitUnicodeString(&ustrFile, pwszFileName);
+
+ InitializeObjectAttributes(&ObjectAttributes, &ustrFile, 0, NULL, NULL);
+
+ Status = ZwCreateFile(&hFile,
+ dwDesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ FILE_OPEN,
+ FILE_NON_DIRECTORY_FILE,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ hFile = NULL;
+ }
+
+ DPRINT("Leaving W32kOpenFile, Status=0x%lx, hFile=0x%p\n", Status, hFile);
+ return hFile;
+}
+
+HANDLE
+NTAPI
+W32kCreateFileSection(HANDLE hFile,
+ ULONG flAllocation,
+ DWORD flPageProtection,
+ ULONGLONG ullMaxSize)
+{
+ NTSTATUS Status;
+ HANDLE hSection = NULL;
+ ACCESS_MASK amDesiredAccess;
+
+ /* Set access mask */
+ amDesiredAccess = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ;
+
+ /* Check if write access is requested */
+ if (flPageProtection == PAGE_READWRITE)
+ {
+ /* Add it to access mask */
+ amDesiredAccess |= SECTION_MAP_WRITE;
+ }
+
+ /* Now create the actual section */
+ Status = ZwCreateSection(&hSection,
+ amDesiredAccess,
+ NULL,
+ NULL,
+ flPageProtection,
+ flAllocation,
+ hFile);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ }
+
+ DPRINT("Leaving W32kCreateFileSection, Status=0x%lx, hSection=0x%p\n", Status, hSection);
+
+ /* Return section handle */
+ return hSection;
+}
+
+PVOID
+NTAPI
+W32kMapViewOfSection(
+ HANDLE hSection,
+ DWORD dwPageProtect,
+ ULONG_PTR ulSectionOffset)
+{
+ NTSTATUS Status;
+ LARGE_INTEGER liSectionOffset;
+ ULONG_PTR ulViewSize;
+ PVOID pvBase = 0;
+
+ liSectionOffset.QuadPart = ulViewSize = ulSectionOffset;
+ Status = ZwMapViewOfSection(hSection,
+ NtCurrentProcess(),
+ &pvBase,
+ 0,
+ 0,
+ &liSectionOffset,
+ &ulViewSize,
+ ViewShare,
+ 0,
+ dwPageProtect);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ }
+
+ DPRINT("Leaving W32kMapViewOfSection, Status=0x%lx, pvBase=0x%p\n", Status, pvBase);
+
+ return pvBase;
+}
+
+HBITMAP
+NTAPI
+UserLoadImage(PCWSTR pwszName)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ HANDLE hFile, hSection;
+ BITMAPFILEHEADER *pbmfh;
+ LPBITMAPINFO pbmi;
+ PVOID pvBits;
+ HBITMAP hbmp = 0;
+
+ DPRINT("Enter UserLoadImage(%ls)\n", pwszName);
+
+ /* Open the file */
+ hFile = W32kOpenFile(pwszName, FILE_READ_DATA);
+ if (!hFile)
+ {
+ return NULL;
+ }
+
+ /* Create a section */
+ hSection = W32kCreateFileSection(hFile, SEC_COMMIT, PAGE_READONLY, 0);
+ ZwClose(hFile);
+ if (!hSection)
+ {
+ return NULL;
+ }
+
+ /* Map the section */
+ pbmfh = W32kMapViewOfSection(hSection, PAGE_READONLY, 0);
+ ZwClose(hSection);
+ if (!pbmfh)
+ {
+ return NULL;
+ }
+
+ /* Get a pointer to the BITMAPINFO */
+ pbmi = (LPBITMAPINFO)(pbmfh + 1);
+
+ _SEH2_TRY
+ {
+ ProbeForRead(&pbmfh->bfSize, sizeof(DWORD), 1);
+ ProbeForRead(pbmfh, pbmfh->bfSize, 1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Bad File?\n");
+ goto leave;
+ }
+
+ if (pbmfh->bfType == 0x4D42 /* 'BM' */)
+ {
+ /* Could be BITMAPCOREINFO */
+ BITMAPINFO* pConvertedInfo;
+ HDC hdc;
+
+ pvBits = (PVOID)((PCHAR)pbmfh + pbmfh->bfOffBits);
+
+ pConvertedInfo = DIB_ConvertBitmapInfo(pbmi, DIB_RGB_COLORS);
+ if(!pConvertedInfo)
+ {
+ DPRINT1("Unable to convert the bitmap Info\n");
+ goto leave;
+ }
+
+ hdc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
+
+ hbmp = GreCreateDIBitmapInternal(hdc,
+ pConvertedInfo->bmiHeader.biWidth,
+ pConvertedInfo->bmiHeader.biHeight,
+ CBM_INIT,
+ pvBits,
+ pConvertedInfo,
+ DIB_RGB_COLORS,
+ 0,
+ pbmfh->bfSize - pbmfh->bfOffBits,
+ 0);
+
+ NtGdiDeleteObjectApp(hdc);
+ DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi, -1);
+ }
+ else
+ {
+ DPRINT1("Unknown file type!\n");
+ }
+
+leave:
+ /* Unmap our section, we don't need it anymore */
+ ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh);
+
+ DPRINT("Leaving UserLoadImage, hbmp = %p\n", hbmp);
+ return hbmp;
+}