📄 jusectionobjs.pas
字号:
unit JuSectionObjs;
interface
uses
Windows, SysUtils, Classes;
{
type
PFileCreationStruct = ^TFileCreationStruct;
TFileCreationStruct = record
DesiredAccess: Cardinal;
ShareMode: Cardinal;
SecurityAttributes: TSecurityAttributes;
CreationDisposition: Cardinal;
FlagsAndAttributes: Cardinal;
TemplateFileHandle: THandle;
end;
PMapCreationStruct = ^TMapCreationStruct;
TMapCreationStruct = record
SourceHandle: THandle;
SecurityAttributes: TSecurityAttributes;
Protect: Cardinal;
Size: Int64;
MapName: array [0..MAX_PATH - 1] of Char;
end;
PMapViewStruct = ^TMapViewStruct;
TMapViewStruct = record
SectionHandle: THandle;
ViewDesiredAccess: Cardinal;
ViewOffset: Int64;
MapDataLen: Cardinal;
end;
PSectionCreationStruct = ^TSectionCreationStruct;
TSectionCreationStruct = record
FileCreation: TFileCreationStruct;
MapCreation: TMapCreationStruct;
MapView: TMapViewStruct;
end;
}
{ Windows section kernel object. }
{ These classes can only be used in Windows; Not in Linux! }
type
ESectionException = class(Exception) end;
{ TJuSectionObject }
{ Abstract base class of Windows section kernel object, that is, file mapping object. }
{ This class can NOT be used to instantiate an object. }
{ Instead, users should use TJuMemMapping or TJuFileMapping }
{ to create page-backed mapping object or file-backed mapping object, respectively. }
TJuSectionObject = class(TObject)
private
FHandle: THandle;
FName: string;
FData: Pointer;
FMapped: Boolean;
FIsCreator: Boolean;
FViewDesiredAccess: Cardinal;
FSecurityAttributes: PSecurityAttributes;
FProtect: Cardinal;
FSize: Int64;
FViewOffset: Int64;
FViewSize: Cardinal;
FViewBaseSpecified: Boolean;
FPageSize: Cardinal;
FAllocationGranularity: Cardinal;
protected
{ Handle of this section object }
property Handle: THandle read FHandle;
{ Name of this section object }
property Name: string read FName;
{ Pointer to mapped data }
property Data: Pointer read FData;
{ Whether data has been mapped onto section object }
property Mapped: Boolean read FMapped;
{ Whether this process is the creator of the section object }
property IsCreator: Boolean read FIsCreator;
{ Desired access to this section object }
property ViewDesiredAccess: Cardinal read FViewDesiredAccess;
{ security attributes of this section object }
property SecurityAttributes: PSecurityAttributes read FSecurityAttributes;
{ Page protection attributes of pages mapped onto this section object }
property Protect: Cardinal read FProtect;
{ Size of the mapping source, i.e. system paging file or disk file }
property Size: Int64 read FSize;
{ Start position of the view to the section object }
property ViewOffset: Int64 read FViewOffset;
{ View size, i.e. number of bytes mapped of the section object }
property ViewSize: Cardinal read FViewSize;
{ Base address of the map view is specified by users. }
property ViewBaseSpecified: Boolean read FViewBaseSpecified;
{ Page size of CPU. In Intel x86, 4KB per page. }
property PageSize: Cardinal read FPageSize;
{ Allocation granularity of CPU. In Intel x86, 64KB per allocation unit. }
property AllocationGranularity: Cardinal read FAllocationGranularity;
protected
{ Abstract creator of section object. }
function DoCreateSection(const MapName: string; Size: Int64;
SecurityAttributes: PSecurityAttributes = nil;
Protect: Cardinal = PAGE_READWRITE): THandle; virtual; abstract;
public
constructor Create();
// constructor Create(CreateMapped: Boolean = True; CreationStruct: PSectionCreationStruct = nil);
destructor Destroy(); override;
{ Open an existing named section object. }
class function OpenSection(const MapName: string;
DesiredAccess: Cardinal = PAGE_READONLY;
InheritHandle: Boolean = False): THandle;
{ whether a section object named as MapName has been created. }
class function HasCreated(const MapName: string): Boolean;
{ Create a section object named as MapName. }
{ This function needs to call the abstract function DoCreateSection. }
function CreateSection(const MapName: string; Size: Int64;
SecurityAttributes: PSecurityAttributes = nil;
Protect: Cardinal = PAGE_READWRITE): THandle; virtual;
{ Map view of the section object. }
{ This function needs to call the abstract function DoMap. }
function Map(ViewOffset: Int64 = 0; ViewSize: Cardinal = 0;
ViewDesiredAccess: Cardinal = FILE_MAP_ALL_ACCESS; ViewBase: Pointer = nil): Pointer; virtual;
{ Unmap view of the section object. }
procedure Unmap(); virtual;
{ Get pointer to data stored in the section object. }
{ Users can use this pointer to modify data. }
{ However, procedure write is better than this to modify data. }
function Read(): Pointer; virtual; abstract;
{ Write data into the section object }
procedure Write(const Buffer: Pointer; BufferSize: Cardinal; StartPos: Cardinal = 0); virtual; abstract;
end;
{ TJuMemMapping }
{ Page-backed section object }
TJuMemMapping = class(TJuSectionObject)
private
FDataSize: Cardinal;
procedure SetMapped(const Value: Boolean);
protected
function DoCreateSection(const MapName: string; Size: Int64;
SecurityAttributes: PSecurityAttributes = nil;
Protect: Cardinal = PAGE_READWRITE): THandle; override;
public
constructor Create(CreateMapped: Boolean = False; const MapName: string = ''; Size: Int64 = 0;
SecurityAttributes: PSecurityAttributes = nil; Protect: Cardinal = PAGE_READWRITE;
ViewDesiredAccess: Cardinal = FILE_MAP_ALL_ACCESS;
ViewOffset: Int64 = 0; ViewSize: Cardinal = 0; ViewBase: Pointer = nil);
function Map(ViewOffset: Int64 = 0; ViewSize: Cardinal = 0;
ViewDesiredAccess: Cardinal = FILE_MAP_ALL_ACCESS; ViewBase: Pointer = nil): Pointer; override;
procedure Unmap(); override;
function Read(): Pointer; override;
procedure Write(const Buffer: Pointer; BufferSize: Cardinal; StartPos: Cardinal = 0); override;
public
// Inherited
property Handle;
property Name;
property Data;
property Mapped write SetMapped;
property IsCreator;
property ViewDesiredAccess;
property SecurityAttributes;
property Protect;
property Size;
property ViewOffset;
property ViewSize;
property ViewBaseSpecified;
property PageSize;
property AllocationGranularity;
// New
property DataSize: Cardinal read FDataSize;
end;
{ TJuFileMapping }
{ File-backed section object }
TJuFileMapping = class(TJuSectionObject)
private
FFileHandle: THandle;
FFileShareMode: Cardinal;
FFileDesiredAccess: Cardinal;
FFileFlagsAndAttributes: Cardinal;
FFileCreationDisposition: Cardinal;
FFileSecurityAttributes: PSecurityAttributes;
FFileName: string;
FFileTemplateHandle: THandle;
procedure SetMapped(const Value: Boolean);
protected
function DoCreateSection(const MapName: string; Size: Int64;
SecurityAttributes: PSecurityAttributes = nil;
Protect: Cardinal = PAGE_READWRITE): THandle; override;
public
constructor Create(const FileName: string; CreateMapped: Boolean = False;
MapName: string = ''; Size: Int64 = 0;
FileDesiredAccess: Cardinal = GENERIC_READ or GENERIC_WRITE;
FileShareMode: Cardinal = FILE_SHARE_READ;
FileSecurityAttributes: PSecurityAttributes = nil;
FileCreationDisposition: Cardinal = CREATE_ALWAYS;
FileFlagsAndAttributes: Cardinal = FILE_ATTRIBUTE_NORMAL or FILE_FLAG_WRITE_THROUGH;
FileTemplateHandle: THandle = 0;
SecurityAttributes: PSecurityAttributes = nil; Protect: Cardinal = PAGE_READWRITE;
ViewDesiredAccess: Cardinal = FILE_MAP_ALL_ACCESS;
ViewOffset: Int64 = 0; ViewSize: Cardinal = 0; ViewBase: Pointer = nil);
destructor Destroy(); override;
function CreateFile(const FileName: string;
FileDesiredAccess: Cardinal = GENERIC_READ or GENERIC_WRITE;
FileShareMode: Cardinal = 0;
FileSecurityAttributes: PSecurityAttributes = nil;
FileCreationDisposition: Cardinal = OPEN_EXISTING;
FileFlagsAndAttributes: Cardinal = FILE_ATTRIBUTE_NORMAL;
FileTemplateHandle: THandle = 0): THandle;
function Map(ViewOffset: Int64 = 0; ViewSize: Cardinal = 0;
ViewDesiredAccess: Cardinal = FILE_MAP_ALL_ACCESS; ViewBase: Pointer = nil): Pointer; override;
function Read(): Pointer; override;
procedure Write(const Buffer: Pointer; BufferSize: Cardinal; StartPos: Cardinal = 0); override;
procedure Flush(); virtual;
public
// Inherited
property Handle;
property Name;
property Data;
property Mapped write SetMapped;
property IsCreator;
property ViewDesiredAccess;
property SecurityAttributes;
property Protect;
property Size;
property ViewOffset;
property ViewSize;
property ViewBaseSpecified;
property PageSize;
property AllocationGranularity;
// New
property FileHandle: THandle read FFileHandle;
property FileName: string read FFileName;
property FileDesiredAccess: Cardinal read FFileDesiredAccess;
property FileShareMode: Cardinal read FFileShareMode;
property FileSecurityAttributes: PSecurityAttributes read FFileSecurityAttributes;
property FileCreationDisposition: Cardinal read FFileCreationDisposition;
property FileFlagsAndAttributes: Cardinal read FFileFlagsAndAttributes;
property FileTemplateHandle: THandle read FFileTemplateHandle;
end;
implementation
uses
JuUtils, Math;
{ TJuSectionObject }
const
SSectionCreationErr = 'Failed to create section object';
SMapViewErr = 'Failed to map view of section object';
SSectionUnnamedErr = 'Section object unnamed';
SFileCreationErr = 'Failed to create or open file %s to create file mapping object';
constructor TJuSectionObject.Create();
begin
FAllocationGranularity := GetAllocationGranularity();
FPageSize := GetPageSize();
end;
function TJuSectionObject.CreateSection(const MapName: string; Size: Int64;
SecurityAttributes: PSecurityAttributes; Protect: Cardinal): THandle;
begin
Result := FHandle;
if FHandle <> 0 then exit;
FName := MapName;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -