2022-08-10 09:50:49 +00:00
/***
Copyright ( C ) 2022 J Reece Wilson ( a / k / a " Reece " ) . All rights reserved .
2022-12-17 20:14:19 +00:00
File : AuProcessSectionView . NT . cpp
2022-08-10 09:50:49 +00:00
Date : 2022 - 08 - 09
Author : Reece
* * */
# include <Source/RuntimeInternal.hpp>
2022-12-17 20:14:19 +00:00
# include "AuProcessSectionView.NT.hpp"
2022-08-10 09:50:49 +00:00
# include "Process.hpp"
# include <Source/IO/FS/FileStream.NT.hpp>
2022-12-17 20:14:19 +00:00
# include "AuProcessSectionFileMapView.NT.hpp"
2022-12-14 07:12:43 +00:00
# include <Source/IO/IPC/AuIPCHandle.hpp>
2022-08-10 09:50:49 +00:00
# include <Windows.h>
namespace Aurora : : Process
{
2022-12-17 20:14:19 +00:00
AuUInt ProcessSectionView : : GetStart ( )
{
return AuNumericLimits < AuUInt > : : min ( ) ;
}
AuUInt ProcessSectionView : : GetEnd ( )
{
return AuNumericLimits < AuUInt > : : max ( ) ;
}
2022-09-30 22:47:18 +00:00
AuSPtr < IProcessSectionMapView > ProcessSectionView : : Allocate ( AuUInt uLength )
2022-08-10 09:50:49 +00:00
{
2022-09-30 22:47:18 +00:00
PageTable table { } ;
table . NX = true ;
table . readable = true ;
table . writable = true ;
return this - > AllocateEx2 ( uLength , 0 , table ) ;
2022-08-10 09:50:49 +00:00
}
AuSPtr < IProcessSectionMapView > ProcessSectionView : : MapFileByPath ( const AuString & str ,
2022-09-30 22:47:18 +00:00
AuUInt64 uOffset ,
AuUInt uLength ,
2022-08-10 09:50:49 +00:00
AuFS : : EFileOpenMode mode ,
AuFS : : EFileAdvisoryLockLevel sectionLock )
{
2023-07-29 08:02:55 +00:00
auto pHandle = AuIO : : IOHandleShared ( ) ;
if ( ! pHandle )
{
SysPushErrorMemory ( ) ;
return nullptr ;
}
AuIO : : IIOHandle : : HandleCreate createhandle ( str ) ;
createhandle . eAdvisoryLevel = AuFS : : EFileAdvisoryLockLevel : : eNoSafety ;
createhandle . eMode = mode ;
createhandle . bFailIfNonEmptyFile = false ;
createhandle . bDirectIOMode = false ;
createhandle . bAsyncHandle = false ;
if ( ! pHandle - > InitFromPath ( createhandle ) )
{
return nullptr ;
}
return this - > MapFileByObject ( pHandle , uOffset , uLength , mode , sectionLock ) ;
2022-08-10 09:50:49 +00:00
}
2023-07-29 08:02:55 +00:00
AuSPtr < IProcessSectionMapView > ProcessSectionView : : MapFileByObject ( const AuSPtr < IO : : IIOHandle > & pIOHandle ,
2022-09-30 22:47:18 +00:00
AuUInt64 uOffset ,
AuUInt uLength ,
2022-08-10 09:50:49 +00:00
AuFS : : EFileOpenMode mode ,
AuFS : : EFileAdvisoryLockLevel processLockLevel )
{
HANDLE hFileMap ;
ULONG desiredAccess { } , pageAttributes { } ;
2023-07-29 08:02:55 +00:00
if ( ! pIOHandle )
2022-08-10 09:50:49 +00:00
{
2022-09-30 22:47:18 +00:00
SysPushErrorArg ( ) ;
2022-08-10 09:50:49 +00:00
return { } ;
}
2022-09-30 22:47:18 +00:00
if ( ! uLength )
2022-08-14 23:41:43 +00:00
{
2022-09-30 22:47:18 +00:00
SysPushErrorArg ( " invalid uLength " ) ;
2022-08-14 23:41:43 +00:00
return { } ;
}
2022-08-10 09:50:49 +00:00
if ( processLockLevel ! = AuFS : : EFileAdvisoryLockLevel : : eNoSafety )
{
DWORD dwFlags { } ;
OVERLAPPED overlapped { } ;
if ( processLockLevel = = AuFS : : EFileAdvisoryLockLevel : : eBlockReadWrite )
{
dwFlags | = LOCKFILE_EXCLUSIVE_LOCK ;
}
dwFlags | = LOCKFILE_FAIL_IMMEDIATELY ;
2022-09-30 22:47:18 +00:00
overlapped . Offset = AuBitsToLower ( uOffset ) ;
overlapped . OffsetHigh = AuBitsToHigher ( uOffset ) ;
2022-08-10 09:50:49 +00:00
2023-07-29 08:02:55 +00:00
if ( ! : : LockFileEx ( ( HANDLE ) pIOHandle - > GetOSHandle ( ) ,
2022-08-10 09:50:49 +00:00
dwFlags ,
0 ,
2022-09-30 22:47:18 +00:00
AuBitsToLower ( uLength ) ,
AuBitsToHigher ( uLength ) ,
2022-08-10 09:50:49 +00:00
& overlapped ) )
{
SysPushErrorIO ( " No Lock " ) ;
return { } ;
}
}
switch ( mode )
{
case AuFS : : EFileOpenMode : : eRead :
{
desiredAccess = SECTION_MAP_READ ;
pageAttributes = PAGE_READONLY ;
break ;
}
case AuFS : : EFileOpenMode : : eWrite :
case AuFS : : EFileOpenMode : : eReadWrite :
{
desiredAccess = SECTION_MAP_READ | SECTION_MAP_WRITE ;
pageAttributes = PAGE_READWRITE ;
break ;
}
default :
SysPushErrorGeneric ( ) ;
return { } ;
} ;
2023-07-29 08:02:55 +00:00
hFileMap = : : CreateFileMappingA ( ( HANDLE ) pIOHandle - > GetOSHandle ( ) ,
2022-08-10 09:50:49 +00:00
nullptr ,
pageAttributes ,
# if defined(AURORA_IS_64BIT)
2022-09-30 22:47:18 +00:00
AuBitsToHigher ( uLength ) ,
AuBitsToLower ( uLength ) ,
2022-08-10 09:50:49 +00:00
# else
0 ,
2022-09-30 22:47:18 +00:00
uLength ,
2022-08-10 09:50:49 +00:00
# endif
nullptr ) ;
if ( ( hFileMap = = INVALID_HANDLE_VALUE ) | |
( ! hFileMap ) )
{
SysPushErrorIO ( " Couldn't create file map. Is the requeted access mode too high for the given object? " ) ;
return { } ;
}
auto map = : : MapViewOfFile ( hFileMap ,
desiredAccess ,
2022-09-30 22:47:18 +00:00
AuBitsToHigher ( uOffset ) ,
AuBitsToLower ( uOffset ) ,
uLength ) ;
2022-08-10 09:50:49 +00:00
if ( ! map )
{
SysPushErrorIO ( " Couldn't create map of section " ) ;
AuWin32CloseHandle ( hFileMap ) ;
return { } ;
}
2022-09-30 22:47:18 +00:00
auto pNewObject = AuMakeShared < ProcessSectionFileMapView > ( AuUInt ( map ) , hFileMap ) ;
if ( ! pNewObject )
2022-08-10 09:50:49 +00:00
{
SysPushErrorMem ( ) ;
AuWin32CloseHandle ( hFileMap ) ;
: : UnmapViewOfFile ( map ) ;
return { } ;
}
2022-09-30 22:47:18 +00:00
pNewObject - > pProcessGlobalHint = this ;
2023-04-17 14:55:51 +00:00
pNewObject - > uLength = uLength ;
2022-09-30 22:47:18 +00:00
return pNewObject ;
2022-08-10 09:50:49 +00:00
}
AuSPtr < IProcessSectionMapView > ProcessSectionView : : MapIPCMemory ( const AuString & handleString ,
2022-09-30 22:47:18 +00:00
AuUInt64 uOffset ,
AuUInt uLength ,
2022-08-10 09:50:49 +00:00
AuFS : : EFileOpenMode mode )
{
AuIPC : : IPCHandle handle ;
HANDLE hFileMap ;
ULONG desiredAccess { } , pageAttributes { } ;
2022-09-30 22:47:18 +00:00
if ( ! uLength )
2022-08-14 23:41:43 +00:00
{
2022-09-30 22:47:18 +00:00
SysPushErrorArg ( " invalid uLength " ) ;
2022-08-14 23:41:43 +00:00
return { } ;
}
2022-08-10 09:50:49 +00:00
if ( ! handle . FromString ( handleString ) )
{
SysPushErrorParseError ( " {} " , handleString ) ;
return { } ;
}
auto token = handle . GetToken ( AuIPC : : EIPCHandleType : : eIPCMemory , 0 ) ;
if ( ! token )
{
SysPushErrorParseError ( ) ;
return { } ;
}
2022-08-11 11:28:20 +00:00
auto actualLength = token - > token . word ;
auto path = token - > token . ToNTPath ( ) ;
2022-09-30 22:47:18 +00:00
if ( actualLength < uOffset + uLength )
2022-08-11 11:28:20 +00:00
{
SysPushErrorIO ( " Out of range " ) ;
return { } ;
}
2022-08-10 09:50:49 +00:00
switch ( mode )
{
case AuFS : : EFileOpenMode : : eRead :
{
desiredAccess = SECTION_MAP_READ ;
pageAttributes = PAGE_READONLY ;
break ;
}
case AuFS : : EFileOpenMode : : eWrite :
case AuFS : : EFileOpenMode : : eReadWrite :
{
desiredAccess = SECTION_MAP_READ | SECTION_MAP_WRITE ;
pageAttributes = PAGE_READWRITE ;
break ;
}
default :
SysPushErrorGeneric ( ) ;
return { } ;
} ;
2022-08-13 20:35:19 +00:00
hFileMap = : : OpenFileMappingA ( desiredAccess ,
FALSE ,
path . c_str ( ) ) ;
2022-08-10 09:50:49 +00:00
if ( ( hFileMap = = INVALID_HANDLE_VALUE ) | |
( ! hFileMap ) )
{
SysPushErrorIO ( " Couldn't create IPC map (handle: {}) " , handleString ) ;
return { } ;
}
auto map = : : MapViewOfFile ( hFileMap ,
desiredAccess ,
2022-09-30 22:47:18 +00:00
AuBitsToHigher ( uOffset ) ,
AuBitsToLower ( uOffset ) ,
uLength ) ;
2022-08-10 09:50:49 +00:00
if ( ! map )
{
SysPushErrorIO ( " Couldn't create map of IPC section (handle: {}) " , handleString ) ;
AuWin32CloseHandle ( hFileMap ) ;
return { } ;
}
2022-09-30 22:47:18 +00:00
auto pNewObject = AuMakeShared < ProcessSectionFileMapView > ( AuUInt ( map ) , hFileMap ) ;
if ( ! pNewObject )
2022-08-10 09:50:49 +00:00
{
SysPushErrorMem ( ) ;
AuWin32CloseHandle ( hFileMap ) ;
: : UnmapViewOfFile ( map ) ;
return { } ;
}
2022-09-30 22:47:18 +00:00
pNewObject - > pProcessGlobalHint = this ;
2023-04-17 14:55:51 +00:00
pNewObject - > uLength = uLength ;
2022-09-30 22:47:18 +00:00
return pNewObject ;
}
AuSPtr < IProcessSectionMapView > ProcessSectionView : : AllocateEx ( AuUInt uLength ,
AuUInt uOffset )
{
SysAssert ( this - > bPanicOnEx , " Windows 7/8 called a Windows 10 RS4 memory management routine. "
" Applications requiring explicit and pre-reserved memory maps cannot run on unmodified unsupported versions of Windows. "
" We lied about reserving a region of bytes with a ProcessSectionView. Unable to gurantee uOffset. " ) ;
return this - > Allocate ( uLength ) ;
}
AuSPtr < IProcessSectionMapView > ProcessSectionView : : AllocateEx2 ( AuUInt uLength ,
AuUInt uOffset ,
PageTable permissions )
{
SysAssert ( this - > bPanicOnEx , " Windows 7/8 called a Windows 10 RS4 memory management routine. "
" Applications requiring explicit and pre-reserved memory maps cannot run on unmodified unsupported versions of Windows. "
" We lied about reserving a region of bytes with a ProcessSectionView. Unable to gurantee uOffset. " ) ;
HANDLE hFileMap ;
if ( ! uLength )
{
SysPushErrorArg ( " invalid uLength " ) ;
return { } ;
}
DWORD uPageFlags { } ;
if ( permissions . writable & & permissions . NX )
{
uPageFlags = PAGE_READWRITE ;
}
else if ( permissions . readable & & permissions . NX )
{
uPageFlags = PAGE_READONLY ;
}
else if ( permissions . writable )
{
uPageFlags = PAGE_EXECUTE_READWRITE ;
}
else if ( permissions . readable )
{
uPageFlags = PAGE_EXECUTE_READ ;
}
hFileMap = : : CreateFileMappingA ( INVALID_HANDLE_VALUE ,
nullptr ,
uPageFlags ,
# if defined(AURORA_IS_64BIT)
AuBitsToHigher ( uLength ) ,
AuBitsToLower ( uLength ) ,
# else
0 ,
uLength ,
# endif
nullptr ) ;
if ( ( hFileMap = = INVALID_HANDLE_VALUE ) | |
( ! hFileMap ) )
{
SysPushErrorIO ( " Couldn't create file map " ) ;
return { } ;
}
DWORD sectionPermission { } ;
if ( permissions . readable )
{
sectionPermission = SECTION_MAP_READ ;
}
if ( permissions . writable )
{
sectionPermission | = SECTION_MAP_WRITE ;
}
if ( ! permissions . NX )
{
sectionPermission | = SECTION_MAP_EXECUTE ;
}
auto map = : : MapViewOfFile ( hFileMap ,
sectionPermission ,
0 ,
0 ,
uLength ) ;
if ( ! map )
{
SysPushErrorIO ( " Couldn't create allocation of section " ) ;
AuWin32CloseHandle ( hFileMap ) ;
return { } ;
}
auto pNewObject = AuMakeShared < ProcessSectionFileMapView > ( AuUInt ( map ) , hFileMap ) ;
if ( ! pNewObject )
{
SysPushErrorMem ( ) ;
AuWin32CloseHandle ( hFileMap ) ;
return { } ;
}
pNewObject - > pProcessGlobalHint = this ;
2023-04-17 14:55:51 +00:00
pNewObject - > uLength = uLength ;
2022-09-30 22:47:18 +00:00
return pNewObject ;
}
AuSPtr < IProcessSectionMapView > ProcessSectionView : : MapFileByPathEx ( AuUInt viewOffset ,
const AuString & str ,
AuUInt64 uOffset ,
AuUInt uLength ,
Aurora : : IO : : FS : : EFileOpenMode mode ,
Aurora : : IO : : FS : : EFileAdvisoryLockLevel processLockLevel )
{
SysAssert ( this - > bPanicOnEx , " Windows 7/8 called a Windows 10 RS4 memory management routine. "
" Applications requiring explicit and pre-reserved memory maps cannot run on unmodified unsupported versions of Windows. "
" We lied about reserving a region of bytes with a ProcessSectionView. Unable to gurantee uOffset. " ) ;
return this - > MapFileByPath ( str , uOffset , uLength , mode , processLockLevel ) ;
}
AuSPtr < IProcessSectionMapView > ProcessSectionView : : MapFileByObjectEx ( AuUInt viewOffset ,
2023-07-29 08:02:55 +00:00
const AuSPtr < IO : : IIOHandle > & pIOHandle ,
2022-09-30 22:47:18 +00:00
AuUInt64 uOffset ,
AuUInt uLength ,
Aurora : : IO : : FS : : EFileOpenMode mode ,
Aurora : : IO : : FS : : EFileAdvisoryLockLevel processLockLevel )
{
SysAssert ( this - > bPanicOnEx , " Windows 7/8 called a Windows 10 RS4 memory management routine. "
" Applications requiring explicit and pre-reserved memory maps cannot run on unmodified unsupported versions of Windows. "
" We lied about reserving a region of bytes with a ProcessSectionView. Unable to gurantee uOffset. " ) ;
2023-07-29 08:02:55 +00:00
return this - > MapFileByObject ( pIOHandle , uOffset , uLength , mode , processLockLevel ) ;
2022-09-30 22:47:18 +00:00
}
AuSPtr < IProcessSectionMapView > ProcessSectionView : : MapIPCMemoryEx ( AuUInt viewOffset ,
const AuString & handle ,
AuUInt64 uOffset ,
AuUInt uLength ,
Aurora : : IO : : FS : : EFileOpenMode mode )
{
SysAssert ( this - > bPanicOnEx , " Windows 7/8 called a Windows 10 RS4 memory management routine. "
" Applications requiring explicit and pre-reserved memory maps cannot run on unmodified unsupported versions of Windows. "
" We lied about reserving a region of bytes with a ProcessSectionView. Unable to gurantee uOffset. " ) ;
return this - > MapIPCMemory ( handle , uOffset , uLength , mode ) ;
}
AuList < AuPair < AuUInt , AuUInt > > ProcessSectionView : : GetAllocations ( )
{
AU_LOCK_GUARD ( this - > spinlock ) ;
return this - > allocations ;
2022-08-10 09:50:49 +00:00
}
2023-06-08 08:52:53 +00:00
void ProcessSectionView : : DoVanillaDriverlessExtesionWin7Test ( )
{
# if defined(AURORA_PLATFORM_WIN32)
# define WIN_7_WARN "WARNING: ADDRESS SPACE CANNOT BE RESERVED ON OLDER NT KERNELS. \r\n" \
" AuProcess::ReserveAddressSpace(AuUInt uOffset) is about to lie about reserving the address space, yield the entire address space, and leave a note to terminate the application if an explicit fixed-offset request is made. "
SysPushErrorUnimplemented ( " Win7_ReserveAddressSpace_RS4_REQ " ) ;
AuUInt uEnvSize { } ;
: : getenv_s ( & uEnvSize , nullptr , 0 , " AURORA_FORCE_RANDOM_ADDRESS_WITHOUT_VIRTALLOC2 " ) ;
if ( uEnvSize )
{
// bah
// enjoy return not respecting what was provided as the expected offset.
// this is not a workaround for missing functionality in the operating systems userland and kernel abstraction.
// this will just prevent us from panicing preemptively.
this - > bPanicOnEx = true ;
}
else
{
AuLogWarn ( WIN_7_WARN ) ;
this - > bPanicOnEx = false ;
}
# else
AuLogWarn ( " I don't know this platform - AuProcess " ) ;
this - > bPanicOnEx = true ;
# endif
}
2022-08-10 09:50:49 +00:00
AUKN_SYM AuSPtr < IProcessSectionView > GetGlobalProcessSpace ( )
{
static ProcessSectionView gSingleton ;
2023-06-08 08:52:53 +00:00
gSingleton . DoVanillaDriverlessExtesionWin7Test ( ) ;
2022-08-10 09:50:49 +00:00
return AuUnsafeRaiiToShared ( & gSingleton ) ;
}
}