You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
509 lines
11 KiB
509 lines
11 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: usermode.cxx
|
|
*
|
|
* Copyright (c) 1998-1999 Microsoft Corporation
|
|
*
|
|
* This file contains all the system abstraction routines required to allow
|
|
* GDI to run as a stand-alone graphics library in user-mode.
|
|
*
|
|
* Created: 29-Apr-1998
|
|
* Author: J. Andrew Goossen [andrewgo]
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
extern "C" {
|
|
BOOL gbRemoteSession=0;
|
|
}
|
|
|
|
// Temporary HDEV for first bringing up user-mode GDI+, which represents
|
|
// the screen 'device'. This sure as heck had better be temporary!
|
|
|
|
HDEV ghdevDisplay;
|
|
|
|
// Copy of a drvsup.cxx structure that should really be moved to engine.h:
|
|
|
|
typedef struct _DRV_NAMES {
|
|
ULONG cNames;
|
|
struct {
|
|
HANDLE hDriver;
|
|
LPWSTR lpDisplayName;
|
|
} D[1];
|
|
} DRV_NAMES, *PDRV_NAMES;
|
|
|
|
HDEV hCreateHDEV(PGRAPHICS_DEVICE,PDRV_NAMES,PDEVMODEW,PVOID,BOOL,FLONG,HDEV*);
|
|
|
|
// Some random goop needed for linking user-mode GDI+:
|
|
|
|
extern "C" {
|
|
PEPROCESS gpepCSRSS;
|
|
ULONG gSessionId;
|
|
};
|
|
|
|
/*****************************Private*Routine******************************\
|
|
* BOOL GpInitialize
|
|
*
|
|
* History:
|
|
* 3-May-1998 -by- J. Andrew Goossen [andrewgo]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
extern "C"
|
|
BOOL
|
|
GpInitialize(
|
|
HWND hwnd)
|
|
{
|
|
DRV_NAMES drvName;
|
|
HDEV hdevDisabled;
|
|
BOOL bRet = FALSE;
|
|
|
|
drvName.cNames = 1;
|
|
drvName.D[0].hDriver = NULL;
|
|
drvName.D[0].lpDisplayName = (LPWSTR)GpsEnableDriver;
|
|
|
|
if (ghdevDisplay == NULL)
|
|
{
|
|
KdPrint(("hCreateDEV.................\n"));
|
|
|
|
ghdevDisplay = hCreateHDEV(NULL,
|
|
&drvName,
|
|
((PDEVMODEW)(hwnd)),
|
|
NULL,
|
|
TRUE, // ignored in this case
|
|
GCH_GDIPLUS_DISPLAY,
|
|
&hdevDisabled);
|
|
|
|
bRet = (ghdevDisplay != NULL);
|
|
}
|
|
else
|
|
{
|
|
WARNING("Can't yet create multiple windows");
|
|
}
|
|
|
|
return(bRet);
|
|
}
|
|
|
|
/*****************************Private*Routine******************************\
|
|
* HDC UserGetDesktopDC
|
|
*
|
|
* History:
|
|
* 3-May-1998 -by- J. Andrew Goossen [andrewgo]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
HDC
|
|
UserGetDesktopDC(
|
|
ULONG iType,
|
|
BOOL bAltType,
|
|
BOOL bValidate)
|
|
{
|
|
HDC hdc = NULL;
|
|
|
|
if ((iType == DCTYPE_DIRECT) && (bValidate))
|
|
{
|
|
if (ghdevDisplay != NULL)
|
|
{
|
|
hdc = GreCreateDisplayDC(ghdevDisplay, DCTYPE_DIRECT, bAltType);
|
|
}
|
|
else
|
|
{
|
|
WARNING("ghdevDisplay not initialized");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WARNING("UserGetDesktopDC functionality not yet handled");
|
|
}
|
|
|
|
return(hdc);
|
|
}
|
|
|
|
/*****************************Private*Routine******************************\
|
|
* HDEV UserGetHDEV
|
|
*
|
|
\**************************************************************************/
|
|
|
|
HDEV
|
|
UserGetHDEV()
|
|
{
|
|
return(ghdevDisplay);
|
|
}
|
|
|
|
/*****************************Private*Routine******************************\
|
|
* BOOL UserVisrgnFromHwnd
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL
|
|
UserVisrgnFromHwnd(
|
|
HRGN* phrgn,
|
|
HWND hwnd)
|
|
{
|
|
*phrgn = NULL;
|
|
return(FALSE);
|
|
}
|
|
|
|
/*****************************Private*Routine******************************\
|
|
* DWORD GetAppCompatFlags
|
|
*
|
|
\**************************************************************************/
|
|
|
|
extern "C"
|
|
DWORD
|
|
GetAppCompatFlags(
|
|
PVOID pv)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
/*****************************Private*Routine******************************\
|
|
* VOID* pAllocMem
|
|
*
|
|
* Hack for screen.c header mess.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
extern "C"
|
|
VOID*
|
|
pAllocMem(
|
|
ULONG size,
|
|
ULONG tag)
|
|
{
|
|
return(PALLOCMEM(size, tag));
|
|
}
|
|
|
|
/*****************************Private*Routine******************************\
|
|
* VOID vFreeMem
|
|
*
|
|
* Hack for screen.c header mess.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
extern "C"
|
|
VOID
|
|
vFreeMem(
|
|
VOID* p)
|
|
{
|
|
VFREEMEM(p);
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
MapViewInProcessSpace(
|
|
PVOID pv,
|
|
PVOID *ppv,
|
|
ULONG *psize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Map view of a file into current process' address space
|
|
|
|
Arguments:
|
|
|
|
pv - Points to a MEMORY_MAPPED_FILE structure
|
|
ppv - Return the base address of the mapped view
|
|
psize - Return the size of the mapped view
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS if successful, error code otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
MEMORY_MAPPED_FILE *mappedFile = (MEMORY_MAPPED_FILE *) pv;
|
|
|
|
if (!mappedFile ||
|
|
!mappedFile->fileMap ||
|
|
!(*ppv = MapViewOfFile(mappedFile->fileMap,
|
|
mappedFile->readOnly ? FILE_MAP_READ : FILE_MAP_WRITE,
|
|
0,
|
|
0,
|
|
mappedFile->fileSize)))
|
|
{
|
|
WARNING("MapViewInProcessSpace failed\n");
|
|
*ppv = NULL;
|
|
*psize = 0;
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
*psize = mappedFile->fileSize;
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
UnmapViewInProcessSpace(
|
|
PVOID pv
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unmap view of a file from the current process' address space
|
|
|
|
Arguments:
|
|
|
|
pv - Base address of the view to be unmapped
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS if successful, error code otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
return UnmapViewOfFile(pv) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CreateMemoryMappedSection(
|
|
PWSTR filename,
|
|
FILEVIEW *fileview,
|
|
INT size
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Create a memory-mapped file structure
|
|
|
|
Arguments:
|
|
|
|
filename - Specifies the name of the file to be mapped
|
|
fileview - Return information about the memory-mapped file
|
|
size - Size to be mapped
|
|
0 : map entire content of an existing file for reading
|
|
else : create a file of the specified size for reading & writing
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE otherwise
|
|
|
|
--*/
|
|
|
|
#define SYSTEM32_STR L"SYSTEM32"
|
|
#define SYSTEM32_LEN 8
|
|
#define SYSTEMROOT_STR L"SYSTEMROOT"
|
|
#define SYSTEMROOT_LEN 10
|
|
|
|
{
|
|
FILEVIEW fv;
|
|
HANDLE fileHandle;
|
|
MEMORY_MAPPED_FILE *mappedFile;
|
|
BY_HANDLE_FILE_INFORMATION fileinfo;
|
|
WCHAR fullpath[MAX_PATH];
|
|
PWSTR p;
|
|
|
|
ZeroMemory(&fv, sizeof(FILEVIEW));
|
|
ZeroMemory(fileview, sizeof(FILEVIEW));
|
|
|
|
//
|
|
// Expand the input filename to fully qualified path
|
|
//
|
|
|
|
p = filename;
|
|
|
|
while (*p && _wcsnicmp(p, SYSTEMROOT_STR, SYSTEMROOT_LEN))
|
|
p++;
|
|
|
|
if (*p)
|
|
{
|
|
if (GetWindowsDirectoryW(fullpath, MAX_PATH))
|
|
{
|
|
wcscat(fullpath, p + SYSTEMROOT_LEN);
|
|
filename = fullpath;
|
|
}
|
|
else
|
|
{
|
|
WARNING("GetWindowsDirectory failed\n");
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
p = filename;
|
|
|
|
while (*p && _wcsnicmp(p, SYSTEM32_STR, SYSTEM32_LEN))
|
|
p++;
|
|
|
|
if (*p)
|
|
{
|
|
if (GetSystemDirectoryW(fullpath, MAX_PATH))
|
|
{
|
|
wcscat(fullpath, p + SYSTEM32_LEN);
|
|
filename = fullpath;
|
|
}
|
|
else
|
|
{
|
|
WARNING("GetSystemDirectory failed\n");
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Allocate memory for a MEMORY_MAPPED_FILE structure
|
|
// (assume content is zero-initialized)
|
|
//
|
|
|
|
mappedFile = (MEMORY_MAPPED_FILE *) PALLOCMEM(sizeof(MEMORY_MAPPED_FILE), 'fmmG');
|
|
|
|
if (mappedFile == NULL)
|
|
return NULL;
|
|
|
|
//
|
|
// Open the file for reading or writing
|
|
//
|
|
|
|
if (size != 0)
|
|
{
|
|
mappedFile->readOnly = FALSE;
|
|
|
|
fileHandle = CreateFileW(filename,
|
|
GENERIC_READ|GENERIC_WRITE,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
NULL,
|
|
OPEN_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
mappedFile->readOnly = TRUE;
|
|
|
|
fileHandle = CreateFileW(filename,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL);
|
|
}
|
|
|
|
if (fileHandle == INVALID_HANDLE_VALUE)
|
|
goto errorExit;
|
|
|
|
//
|
|
// Get timestamp information about the file
|
|
//
|
|
|
|
if (!GetFileInformationByHandle(fileHandle, &fileinfo))
|
|
goto errorExit;
|
|
|
|
fv.LastWriteTime.LowPart = fileinfo.ftLastWriteTime.dwLowDateTime;
|
|
fv.LastWriteTime.HighPart = fileinfo.ftLastWriteTime.dwHighDateTime;
|
|
|
|
//
|
|
// If file was opened for writing, set it to requested size
|
|
//
|
|
|
|
if (size != 0)
|
|
{
|
|
if (size > 0)
|
|
fileinfo.nFileSizeLow = (DWORD) size;
|
|
|
|
fileinfo.nFileSizeHigh = 0;
|
|
|
|
if (!SetFilePointer(fileHandle, fileinfo.nFileSizeLow, 0, FILE_BEGIN))
|
|
goto errorExit;
|
|
}
|
|
|
|
if (fileinfo.nFileSizeHigh != 0)
|
|
goto errorExit;
|
|
|
|
mappedFile->fileSize = fv.cjView = fileinfo.nFileSizeLow;
|
|
|
|
//
|
|
// Create a file mapping handle
|
|
//
|
|
|
|
mappedFile->fileMap = CreateFileMapping(
|
|
fileHandle,
|
|
NULL,
|
|
mappedFile->readOnly ? PAGE_READONLY : PAGE_READWRITE,
|
|
0,
|
|
fileinfo.nFileSizeLow,
|
|
NULL);
|
|
|
|
if (mappedFile->fileMap != NULL)
|
|
{
|
|
CloseHandle(fileHandle);
|
|
fv.pSection = mappedFile;
|
|
|
|
CopyMemory(fileview, &fv, sizeof(FILEVIEW));
|
|
return TRUE;
|
|
}
|
|
|
|
errorExit:
|
|
|
|
WARNING("CreateMemoryMappedSection failed\n");
|
|
|
|
if (fileHandle != INVALID_HANDLE_VALUE)
|
|
CloseHandle(fileHandle);
|
|
|
|
DeleteMemoryMappedSection(mappedFile);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
VOID
|
|
DeleteMemoryMappedSection(
|
|
PVOID pv
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dispose of a memory-mapped file structure
|
|
|
|
Arguments:
|
|
|
|
pv - Points to a MEMORY_MAPPED_FILE structure
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
|
|
{
|
|
MEMORY_MAPPED_FILE *mappedFile = (MEMORY_MAPPED_FILE *) pv;
|
|
|
|
if (mappedFile != NULL)
|
|
{
|
|
if (mappedFile->fileMap != NULL)
|
|
CloseHandle(mappedFile->fileMap);
|
|
|
|
VFREEMEM(mappedFile);
|
|
}
|
|
}
|
|
|
|
|
|
NTSYSAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
ZwOpenKey(
|
|
PHANDLE KeyHandle,
|
|
ACCESS_MASK DesiredAccess,
|
|
POBJECT_ATTRIBUTES ObjectAttributes
|
|
)
|
|
|
|
{
|
|
if (DesiredAccess == GENERIC_READ || DesiredAccess == 0)
|
|
DesiredAccess = KEY_READ;
|
|
|
|
return NtOpenKey(KeyHandle, DesiredAccess, ObjectAttributes);
|
|
}
|
|
|
|
|
|
|
|
|