mirror of
https://github.com/reactos/reactos.git
synced 2024-08-22 11:22:59 +00:00
252 lines
6.2 KiB
C
252 lines
6.2 KiB
C
/*
|
|
* COPYRIGHT: GPL, see COPYING in the top level directory
|
|
* PROJECT: ReactOS win32 kernel mode subsystem server
|
|
* PURPOSE: File access support routines
|
|
* FILE: win32ss/user/ntuser/misc/file.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;
|
|
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);
|
|
hSection = NULL;
|
|
}
|
|
|
|
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 = NULL;
|
|
|
|
liSectionOffset.QuadPart = ulViewSize = ulSectionOffset;
|
|
Status = ZwMapViewOfSection(hSection,
|
|
NtCurrentProcess(),
|
|
&pvBase,
|
|
0,
|
|
0,
|
|
&liSectionOffset,
|
|
&ulViewSize,
|
|
ViewShare,
|
|
0,
|
|
dwPageProtect);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
SetLastNtError(Status);
|
|
pvBase = NULL;
|
|
}
|
|
|
|
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;
|
|
}
|