Purpose: Framework Core Low-Level Wrappers to the Operating-System API
- this unit is a part of the Open Source Synopse mORMot framework 2, licensed under a MPL/GPL/LGPL three license - see LICENSE.md
Unit Name | Description | |
---|---|---|
mormot.core.base | Framework Core Shared Types and RTL-like Functions |
Objects | Description | |
---|---|---|
EOSException | Exception types raised by this mormot.core.os unit | |
TAutoLock | Raw class used by TAutoLocker.ProtectMethod and TSynLocker.ProtectMethod | |
TDiskPartition | Stores information about a disk partition | |
TExecutable | Stores some global information about the current executable and computer | |
TExecutableCommandLine | Implements command-line arguments parsing e.g. for TExecutable.Command | |
TExecutableResource | Low-level access to a resource bound to the executable | |
TFileStreamEx | A TFileStream replacement which supports FileName longer than MAX_PATH, and a proper Create(aHandle) constructor in FPC | |
TFileStreamFromHandle | FPC TFileStream miss a Create(aHandle) constructor like Delphi | |
TFileStreamNoWriteError | File stream which ignores I/O write errors | |
TFileVersion | Used to retrieve version information from any EXE | |
TLecuyerThreadSafe | A thread-safe Pierre L'Ecuyer software random generator | |
TLightLock | A lightweight exclusive non-reentrant lock, stored in a PtrUInt value | |
TLockedList | Thread-safe dual-linked list of TLockedListOne descendants with recycling | |
TLockedListOne | Abstract parent of one data entry in TLockedList, storing two PLockedListOne | |
TMemoryInfo | Hold low-level information about current memory usage | |
TMemoryMap | Cross-platform memory mapping of a file content | |
TObjectOSLightLock | A thread-safe class with a virtual constructor and properties persistence | |
TObjectRWLightLock | A thread-safe class with a virtual constructor and properties persistence | |
TObjectRWLock | A thread-safe class with a virtual constructor and properties persistence | |
TOperatingSystemVersion | The running Operating System, encoded as a 32-bit integer | |
TOSLightLock | The fastest non-reentrant lock supplied by the Operating System | |
TOSLock | The standard reentrant lock supplied by the Operating System | |
TOSVersionInfoEx | Low-level API structure, not defined in old Delphi versions | |
TProcessInfo | Low-level structure used to compute process memory and CPU usage | |
TRawSmbiosInfo | The raw SMBIOS information as filled by GetRawSmbios | |
TRWLightLock | A lightweight multiple Reads / exclusive Write non-upgradable lock | |
TRWLock | A lightweight multiple Reads / exclusive Write reentrant lock | |
TService | Abstract class to let an executable implement a Windows Service | |
TServiceController | TServiceControler class is intended to create a new Windows Service instance or to maintain (that is start, stop, pause, resume...) an existing Service | |
TServiceSingle | Inherit from this class if your application has a single Windows Service | |
TSynEvent | Our lightweight cross-platform TEvent-like component | |
TSynLibrary | Encapsulate cross-platform loading of library files | |
TSynLocked | A thread-safe class with a virtual constructor and properties persistence | |
TSynLocker | Allow to add cross-platform locking methods to any class instance | |
TSynLogExceptionContext | Calling context when intercepting exceptions | |
TSynMemoryStreamMapped | A TStream created from a file content, using fast memory mapping | |
TSynWindowsPrivileges | Manage available privileges on Windows platform | |
TSystemUseData | Store CPU and RAM usage for a given process | |
TWinCryptoApi | Direct access to the Windows CryptoApi | |
TWinProcessInfo | Information returned by GetProcessInfo() overloaded functions | |
TWinRegistry | Direct access to the Windows Registry |
EOSException = class(ExceptionWithProps)
Exception types raised by this mormot.core.os unit
TOperatingSystemVersion = packed record
The running Operating System, encoded as a 32-bit integer
TOSVersionInfoEx = record
Low-level API structure, not defined in old Delphi versions
TFileVersion = class(TSynPersistent)
Used to retrieve version information from any EXE
- under Linux, all version numbers are set to 0 by default, unless you define the FPCUSEVERSIONINFO conditional and information is extracted from executable
resources
- for the main executable
, do not create once instance of this class, but call GetExecutableVersion
/ SetExecutableVersion
and access the Executable
global variable
Build: integer;
Executable
release
build
number
BuildYear: word;
Build
year of this exe file
Comments: RawUtf8;
Associated Comments
string version resource
CompanyName: RawUtf8;
Associated CompanyName
string version resource
FileDescription: RawUtf8;
Associated FileDescription
string version resource
FileVersion: RawUtf8;
Associated FileVersion
string version resource
InternalName: RawUtf8;
Associated InternalName
string version resource
LanguageInfo: RawUtf8;
Associated Language Translation string version resource
LegalCopyright: RawUtf8;
Associated LegalCopyright
string version resource
Main: string;
Version info of the exe file as '3.1'
- return "string" type, i.e. UnicodeString for Delphi 2009+
Major: integer;
Executable
major
version number
Minor: integer;
Executable
minor
version number
OriginalFilename: RawUtf8;
Associated OriginalFileName
string version resource
ProductName: RawUtf8;
Associated ProductName
string version resource
ProductVersion: RawUtf8;
Associated ProductVersion
string version resource
Release: integer;
Executable
release
version number
constructor Create(const aFileName: TFileName; aMajor: integer = 0; aMinor: integer = 0; aRelease: integer = 0; aBuild: integer = 0); reintroduce;
Initialize the version information, with optional custom values
- will set the version numbers, and get BuildDateTime
/BuildYear
- call RetrieveInformationFromFileName
to parse its internal resources
- for the main
executable
, do not use this constructor, but call GetExecutableVersion
/ SetExecutableVersion
and access the Executable
global variable
function BuildDateTimeString: string;
Build
date and time of this exe file, as plain text
function DetailedOrVoid: string;
Version info of the exe file as '3.1.0.123' or ''
- this method returns '' if Detailed
is '0.0.0.0'
class function GetVersionInfo(const aFileName: TFileName): RawUtf8;
Returns the version information of a specified exe file as text
- includes FileName (without path), Detailed
and BuildDateTime
properties
- e.g. 'myprogram.exe 3.1.0.123 2016-06-14 19:07:55'
function RetrieveInformationFromFileName: boolean;
Open and extract file information from the executable
FileName
- note that resource extraction is not available on POSIX, unless the FPCUSEVERSIONINFO conditional has been specified in the project options
function UserAgent: RawUtf8;
Returns a ready-to-use User-Agent header with exe name, version and OS
- e.g. 'myprogram/3.1.0.123W32
' for myprogram running on Win32
- here OS_INITIAL
[] character is used to identify the OS, with '32' appended on Win32 only (e.g. 'myprogram/3.1.0.2W', is for Win64)
- use UserAgentParse
() to decode this text
into meaningful information
function Version32: integer;
Retrieve the version as a 32-bit integer with Major.Minor.Release
- following Major
shl 16+Minor
shl 8+Release
bit pattern
function VersionInfo: RawUtf8;
Returns the version information of this exe file as text
- includes FileName (without path), Detailed
and BuildDateTime
properties
- e.g. 'myprogram.exe 3.1.0.123 (2016-06-14 19:07:55)'
property BuildDateTime: TDateTime read fBuildDateTime write fBuildDateTime;
Build
date and time of this exe file
property Detailed: string read fDetailed write fDetailed;
Version info of the exe file as '3.1.0.123'
- return "string" type, i.e. UnicodeString for Delphi 2009+
- under Linux, always return '0.0.0.0' if no custom version number has been defined
- consider using DetailedOrVoid
method if '0.0.0.0' is not expected
TExecutableCommandLine = class(TObject)
Implements command-line arguments parsing e.g. for TExecutable.Command
- call Arg() Options() and Get/Param() to define and retrieve the flags from their names and supply some description text
, then call DetectUnknown and/or FullDescription to interact with the user
- by default, will use -/-- switches on POSIX, and / on Windows
function Arg(const name: RawUtf8; const description: RawUtf8 = ''): boolean; overload;
Mark and describe an "arg
" value in Args
[]
- e.g. returns true if the name appears in Args
[]
function Arg(const name: array of RawUtf8; const description: RawUtf8 = ''): boolean; overload;
Mark and describe or or several "arg
" value(s) in Args
[]
- e.g. returns true if any of the name(s) appears in Args
[]
function Arg(index: integer; const description: RawUtf8 = ''; optional: boolean = true): boolean; overload;
Mark and describe an "arg
" value by 0-based index in Args
[]
- if true, you can access the value from Args
[index]
function ArgFile(index: integer; const description: RawUtf8 = ''; optional: boolean = true; isFolder: boolean = false): TFileName;
Mark and describe an existing TFileName "arg
" value by 0-based index in Args
[]
- if set, will fail in DetectUnknown
if the file (or the folder) does not exist, or returns Args
[index] file/folder name as string
function ArgString(index: integer; const description: RawUtf8 = ''; optional: boolean = true): string;
Mark and describe a string/TFileName "arg
" value by 0-based index in Args
[]
- if existing, returns Args
[index] as string - otherwise returns ''
function ArgU(index: integer; const description: RawUtf8 = ''; optional: boolean = true): RawUtf8;
Mark and describe an "arg
" value by 0-based index in Args
[]
- if existing, returns the value from Args
[index] - otherwise returns ''
function CheckFileName(const name: TFileName; isFolder: boolean = false): TFileName;
Will fail in DetectUnknown
if the file or folder name does not exist
- also calls and return ExpandFileName() on the supplied file or folder name
function ConsoleHelpFailed(const exedescription: RawUtf8 = ''): boolean;
Define 'h help' and call ConsoleWriteUnknown
()
- caller should exit the process if this method returned true
function ConsoleWriteUnknown(const exedescription: RawUtf8 = ''): boolean;
Call DetectUnknown
and output any error message to the console
- return false if the parameters are valid
- otherwise, return true and caller should exit the process
function DetectUnknown: RawUtf8;
Check if the supplied parameters were all registered from previous Arg
() Options
() and Get/Param
() calls
- return '' if no unexpected flag has
been supplied
- return an error message like 'Unexpected --name option
' otherwise
function FullDescription(const customexedescription: RawUtf8 = ''; const exename: RawUtf8 = ''; const onlyusage: RawUtf8 = ''): RawUtf8;
Generate the text
from all Arg
() Options
() and Get/Param
() descriptions and the supplied high-level description of the program
- the parameter <name> would be extracted from any #word in the description text
,
- for instance:
with Executable.Command do // you may better use a local variable begin ExeDescription := 'An executable to test mORMot Execute.Command'; verbose := Option('&verbose', 'generate verbose output'); Get(['t', 'threads'], threads, '#number of threads to run', 5); ConsoleWrite(FullDescription); end;
will fill "verbose" and "threads" local variables, and output on Linux:
An executable to test mORMot Execute.Command
Usage: mormot2tests [options] [params]
Options: -v, --verbose generate verbose output
Params: -t, --threads <number> (default 5) number of threads to run
function Get(const name: array of RawUtf8; out value: integer; const description: RawUtf8 = ''; default: integer = maxInt): boolean; overload;
Search for "-parametername" and return its integer "parametervalue"
function Get(const name: RawUtf8; out value: integer; const description: RawUtf8 = ''; default: integer = maxInt): boolean; overload;
Search for "-parametername" and return its integer "parametervalue"
- if name contains a & character, will also register the following char
function Get(const name: array of RawUtf8; min, max: integer; out value: integer; const description: RawUtf8 = ''; default: integer = -1): boolean; overload;
Search for "-parametername" and return its integer "parametervalue"
function Get(const name: RawUtf8; min, max: integer; out value: integer; const description: RawUtf8 = ''; default: integer = maxInt): boolean; overload;
Search for "-parametername" and return its integer "parametervalue"
- if name contains a & character, will also register the following char
function Get(const name: RawUtf8; out value: TStringDynArray; const description: RawUtf8 = ''): boolean; overload;
Search for "-parametername" and return all string "parametervalue" occurrences
- if name contains a & character, will also register the following char
function Get(const name: array of RawUtf8; out value: TRawUtf8DynArray; const description: RawUtf8 = ''): boolean; overload;
Search for "-parametername" and return all RawUtf8
"parametervalue" occurrences
function Get(const name: array of RawUtf8; out value: RawUtf8; const description: RawUtf8 = ''; const default: RawUtf8 = ''): boolean; overload;
Search for "-parametername" and return its RawUtf8
"parametervalue"
- returns true if any '-name' or '--name' or '/name' do appear with a value
function Get(const name: RawUtf8; out value: RawUtf8; const description: RawUtf8 = ''; const default: RawUtf8 = ''): boolean; overload;
Search for "-parametername" and return its RawUtf8
"parametervalue"
- returns true if '-name' or '--name' or '/name' do appear with a value
- if name contains a & character, will also register the following char, e.g. Get('&concise') is the same as Get(['c', 'concise'])
function Get(const name: array of RawUtf8; out value: string; const description: RawUtf8 = ''; const default: string = ''): boolean; overload;
Search for "-parametername" and return its plain string "parametervalue"
function Get(const name: array of RawUtf8; out value: TStringDynArray; const description: RawUtf8 = ''): boolean; overload;
Search for "-parametername" and return all string "parametervalue" occurrences
function Get(const name: RawUtf8; out value: string; const description: RawUtf8 = ''; const default: string = ''): boolean; overload;
Search for "-parametername" and return its plain string "parametervalue"
- if name contains a & character, will also register the following char
function Has(const name: RawUtf8): boolean; overload;
Search for "-parametername" parameter in Names
[]
- if name contains a & character, will also search the following char
function Has(const name: array of RawUtf8): boolean; overload;
Search for "-parametername" parameter in Names
[]
function Option(const name: array of RawUtf8; const description: RawUtf8 = ''): boolean; overload;
Search for one or severl -xxxx switches in Options
[]
- returns true if any '-name' or '--name' or '/name' do appear
function Option(const name: RawUtf8; const description: RawUtf8 = ''): boolean; overload;
Search for a -xxxx switch in Options
[]
- returns true if '-name' or '--name' or '/name' do appear
- if name contains a & character, will also register the following char, e.g. Option
('&concise') is the same as Option
(['c', 'concise'])
function Param(const name: array of RawUtf8; default: integer; const description: RawUtf8 = ''): integer; overload;
Search for "-parametername" and return its integer "parametervalue" or default
function Param(const name: RawUtf8; const description: RawUtf8 = ''; const default: RawUtf8 = ''): RawUtf8; overload;
Search for "-parametername" and return '' or its RawUtf8
"parametervalue"
- if name contains a & character, will also register the following char
function Param(const name: array of RawUtf8; const description: RawUtf8 = ''; const default: RawUtf8 = ''): RawUtf8; overload;
Search for "-parametername" and return '' or its RawUtf8
"parametervalue"
function Param(const name: RawUtf8; default: integer; const description: RawUtf8 = ''): integer; overload;
Search for "-parametername" and return its integer "parametervalue" or default
- if name contains a & character, will also register the following char
function ParamS(const name: RawUtf8; const description: RawUtf8 = ''; const default: string = ''): string; overload;
Search for "-parametername" and return '' or its string "parametervalue"
- if name contains a & character, will also register the following char
function ParamS(const name: array of RawUtf8; const description: RawUtf8 = ''; const default: string = ''): string; overload;
Search for "-parametername" and return '' or its string "parametervalue"
function Parse(const DescriptionLineFeed: RawUtf8 = CRLF; const ShortSwitch: RawUtf8 = '/' ; const LongSwitch: RawUtf8 = '/' ): boolean;
Fill the stored arguments and options
from executable
parameters
- called e.g. at unit inialization to set Executable.CommandLine variable
- you can execute it again e.g. to customize the switches characters
function SwitchAsText(const v: RawUtf8): RawUtf8;
Internal method returning a switch text
from its identifier
procedure Clear;
Remove all recognized arguments and switches
property Args: TRawUtf8DynArray read fNames[clkArg];
The ParamStr(1..ParamCount) arguments as RawUtf8
, excluding Options
[] switches and Params
[]/Values
[] parameters
property CaseSensitiveNames: boolean read fCaseSensitiveNames write fCaseSensitiveNames;
If search within Args
[] Options
[] or Names
[] should be case-sensitive
property ExeDescription: RawUtf8 read fExeDescription write fExeDescription;
Set a text
which describes the executable
- as used by default by FullDescription
() and ConsoleWriteUnknown
()
property LineFeed: RawUtf8 read fLineFeed write fLineFeed;
DescriptionLineFeed value from TExecutableCommandLine.Parse
()
property Names: TRawUtf8DynArray read fNames[clkParam];
The names
of "-parametername parametervalue" as stored in ParamStr()
- mapping the Values
[] associated array
property Options: TRawUtf8DynArray read fNames[clkOption];
The "-optionname" boolean switches as stored in ParamStr()
property RawParams: TRawUtf8DynArray read fRawParams write fRawParams;
Map ParamStr(1 .. ParamCount) values
, encoded as RawUtf8
- may be used e.g. for regression tests instead of ParamStr():
c.RawParams := CsvToRawUtf8DynArray('-o file.txt --y -v -t 1', ' ');
property Values: TRawUtf8DynArray read fValues;
The values
of "-parametername parametervalue" as stored in ParamStr()
- mapping the Names
[] associated array
TExecutable = record
Stores some global information about the current executable
and computer
- as set at unit initialization into the Executable
global variable
Command: TExecutableCommandLine;
The Command
Line arguments, parsed during unit initialization
Hash: THash128Rec;
Some hash
representation of this information
- the very same executable
on the very same computer run by the very same user
will always have the same Hash
value
- is computed from the crc32c
of this TExecutable
fields: c0 from Version32, CpuFeatures
and Host
, c1 from User
, c2 from ProgramFullSpec
and c3 from InstanceFileName
- may be used as an entropy seed, or to identify a process execution
Host: RawUtf8;
The current computer host
name
InstanceFileName: TFileName;
The full path of the running executable
or library
- for an executable
, same as paramstr(0)
- for a library, will contain the whole .dll file name
ProgramFileName: TFileName;
The main executable
file name (including full path)
- same as paramstr(0)
ProgramFilePath: TFileName;
The main executable
full path (excluding .exe file name)
- same as ExtractFilePath(paramstr(0))
ProgramFullSpec: RawUtf8;
The main executable
details, as used e.g. by TSynLog
- e.g. 'C:\Dev\lib\SQLite3\exe\TestSQL3.exe 1.2.3.123 (2011-03-29 11:09:06)'
- you should have called GetExecutableVersion
or SetExecutableVersion
to populate this field
ProgramName: RawUtf8;
The main executable
name, without any path nor extension
- e.g. 'Test' for 'c:\pathto\Test.exe'
User: RawUtf8;
The current computer user
name
Version: TFileVersion;
The current executable
version
- you should have called GetExecutableVersion
or SetExecutableVersion
to populate this field
TRawSmbiosInfo = record
The raw SMBIOS
information as filled by GetRawSmbios
- first 4 bytes are $010003ff on POSIX if read from /var/tmp/.synopse.smb
Data: RawByteString;
Low-level binary of the SMBIOS
Structure Table
DmiRevision: byte;
Typically 0 for SMBIOS
2.1, 1 for SMBIOS
3.0
Length: DWORD;
The length
of encoded binary in data
Reserved: byte;
Some flag only set by GetSystemFirmwareTable() Windows API
SmbMajorVersion: byte;
Typically 2-3
SmbMinorVersion: byte;
Typically 0-1
TWinRegistry = object(TObject)
Direct access to the Windows Registry
- could be used as alternative to TRegistry, which doesn't behave the same on all Delphi versions, and is enhanced on FPC (e.g. which supports REG_MULTI_SZ)
- is also Unicode ready for text
, using UTF-8 conversion on all compilers
key: HKEY;
The opened HKEY handle
function ReadBuffer(const entry: SynUnicode; data: pointer; datalen: DWORD): boolean;
Read a Windows Registry content as binary buffer after ReadOpen
()
- just a wrapper around RegQueryValueExW() API call
function ReadData(const entry: SynUnicode): RawByteString;
Read a Windows Registry content after ReadOpen
()
- works with any kind of key
, but was designed for REG_BINARY
function ReadDword(const entry: SynUnicode): cardinal;
Read a Windows Registry 32-bit REG_DWORD value after ReadOpen
()
function ReadEnumEntries: TRawUtf8DynArray;
Enumeration of all sub-entries names of a Windows Registry key
function ReadMax(const entry: SynUnicode; data: pointer; maxdatalen: DWORD): DWORD;
Read a Windows Registry content as length-specified buffer after ReadOpen
()
- returns the number of bytes written to Data
function ReadOpen(root: TWinRegistryRoot; const keyname: RawUtf8; closefirst: boolean = false): boolean;
Start low-level read access to a Windows Registry node
- on success (returned true), Close
method should be eventually called
function ReadQword(const entry: SynUnicode): QWord;
Read a Windows Registry 64-bit REG_QWORD value after ReadOpen
()
function ReadSize(const entry: SynUnicode): integer;
Retrieve a Windows Registry content size as binary bytes after ReadOpen
()
- returns -1 if the entry is not found
function ReadString(const entry: SynUnicode; andtrim: boolean = true): RawUtf8;
Read a UTF-8 string from the Windows Registry after ReadOpen
()
- in respect to Delphi's TRegistry, will properly handle REG_MULTI_SZ (return the first value of the multi-list) - use ReadData
to retrieve all REG_MULTI_SZ values as one blob
- we don't use string here since it would induce a dependency to mormot.core.unicode
procedure Close;
Finalize low-level read access to the Windows Registry after ReadOpen
()
TSynWindowsPrivileges = object(TObject)
Manage available privileges on Windows platform
- not all available privileges are active for all process
- for usage of more advanced WinAPI, explicit enabling of privilege is sometimes needed
function Disable(aPrivilege: TWinSystemPrivilege): boolean;
Disable
privilege
- if aPrivilege is already disabled return true, if operation is not possible (required privilege doesn't exist or API error) return false
function Enable(aPrivilege: TWinSystemPrivileges): boolean; overload;
Enable
one or several privilege(s) from a set
- if aPrivilege is already enabled
return true, if operation is not possible (required privilege doesn't exist or API error) return false
function Enable(aPrivilege: TWinSystemPrivilege): boolean; overload;
Enable
privilege
- if aPrivilege is already enabled
return true, if operation is not possible (required privilege doesn't exist or API error) return false
procedure Done(aRestoreInitiallyEnabled: boolean = true);
Finalize the object and relese Token
handle
- aRestoreInitiallyEnabled parameter can be used to restore initially state of enabled
privileges
procedure Init(aTokenPrivilege: TWinTokenType = wttProcess; aLoadPrivileges: boolean = true);
Initialize the object dedicated to management of available
privileges
- aTokenPrivilege can be used for current process or current thread
property Available: TWinSystemPrivileges read fAvailable;
Set of available
privileges for current process/thread
property Enabled: TWinSystemPrivileges read fEnabled;
Set of enabled
privileges for current process/thread
property Token: THandle read fToken;
Low-level access to the privileges token
handle
TWinProcessInfo = record
Information returned by GetProcessInfo
() overloaded functions
AffinityMask: cardinal;
GetProcessAffinityMask-like value
AvailableInfo: TWinProcessAvailableInfos;
Which information was returned within this structure
BasePriority: integer;
Process priority
BeingDebugged: byte;
Indicates whether the specified process is currently being debugged
CommandLine: SynUnicode;
Command-line string passed to the process
ExitStatus: integer;
GetExitCodeProcess-like value
ImagePath: SynUnicode;
Path of the image file for the process
ParentPID: cardinal;
The Parent Process ID
PEBBaseAddress: pointer;
Points to the low-level internal PEB structure
- you can not directly access this memory, unless ReadProcessMemory() with proper wspDebug priviledge API is called
PID: cardinal;
The Process ID
SessionID: cardinal;
Terminal Services session identifier associated with this process
TWinCryptoApi = object(TObject)
Direct access to the Windows CryptoApi
AcquireContextA: function(var phProv: HCRYPTPROV; pszContainer: PAnsiChar; pszProvider: PAnsiChar; dwProvType: DWORD; dwFlags: DWORD): BOOL; stdcall;
Acquire a handle to a particular key container within a particular cryptographic service provider (CSP)
ConvertSecurityDescriptorToStringSecurityDescriptorA: function( SecurityDescriptor: PSECURITY_DESCRIPTOR; RequestedStringSDRevision: DWORD; SecurityInformation: DWORD; var StringSecurityDescriptor: PAnsiChar; StringSecurityDescriptorLen: LPDWORD): BOOL; stdcall;
Converts a security descriptor to a string format
Decrypt: function(hKey: HCRYPTKEY; hHash: HCRYPTHASH; Final: BOOL; dwFlags: DWORD; pbData: pointer; var pdwDataLen: DWORD): BOOL; stdcall;
Decrypts data previously encrypted by using the CryptEncrypt function
DestroyKey: function(hKey: HCRYPTKEY): BOOL; stdcall;
Releases the handle referenced by the hKey parameter
Encrypt: function(hKey: HCRYPTKEY; hHash: HCRYPTHASH; Final: BOOL; dwFlags: DWORD; pbData: pointer; var pdwDataLen: DWORD; dwBufLen: DWORD): BOOL; stdcall;
Encrypt
the data designated by the key held by the CSP module referenced by the hKey parameter
GenRandom: function(hProv: HCRYPTPROV; dwLen: DWORD; pbBuffer: pointer): BOOL; stdcall;
Fills a buffer with cryptographically random bytes
- since Windows Vista with Service Pack 1 (SP1), an AES
counter-mode based PRNG specified in NIST Special Publication 800-90 is used
ImportKey: function(hProv: HCRYPTPROV; pbData: pointer; dwDataLen: DWORD; hPubKey: HCRYPTKEY; dwFlags: DWORD; var phKey: HCRYPTKEY): BOOL; stdcall;
Transfers a cryptographic key from a key BLOB into a cryptographic service provider (CSP)
ReleaseContext: function(hProv: HCRYPTPROV; dwFlags: PtrUInt): BOOL; stdcall;
Releases the handle of a cryptographic service provider (CSP) and a key container
SetKeyParam: function(hKey: HCRYPTKEY; dwParam: DWORD; pbData: pointer; dwFlags: DWORD): BOOL; stdcall;
Customizes various aspects of a session key's operations
function Available: boolean;
Try to load the CryptoApi
on this system
function SecurityDescriptorToText(sd: pointer; out text: RawUtf8): boolean;
Wrapper around ConvertSecurityDescriptorToStringSecurityDescriptorA
()
- see also SecurityDescriptorToText
() function in mormot.core.os.security
TSynLogExceptionContext = object(TObject)
Calling context when intercepting exceptions
- used e.g. for TSynLogExceptionToStr
or RawExceptionIntercept
() handlers
EAddr: PtrUInt;
The address where the exception occurred
EClass: ExceptClass;
The raised exception class
ECode: DWord;
The OS-level exception code
- could be $0EEDFAE0 of $0EEDFADE for Delphi-generated exceptions
EInstance: Exception;
The Delphi Exception instance
- may be nil for external/OS exceptions
ELevel: TSynLogLevel;
The logging level corresponding to this exception
- may be either sllException or sllExceptionOS
EStack: PPtrUIntArray;
The optional stack trace
EStackCount: integer;
= FPC's RaiseProc() FrameCount if EStack
is Frame: PCodePointer
ETimestamp: TUnixTime;
Timestamp of this exception, as number of seconds since UNIX Epoch
- UnixTimeUtc
is faster than NowUtc
or GetSystemTime
- use UnixTimeToDateTime
() to convert it into a regular TDateTime
function AdditionalInfo(out ExceptionNames: TPUtf8CharDynArray): cardinal;
Retrieve some extended information about a given Exception
- on Windows, recognize most DotNet CLR Exception Names
TFileStreamFromHandle = class(THandleStream)
FPC TFileStream miss a Create(aHandle) constructor like Delphi
destructor Destroy; override;
Explictely close the handle if needed
property DontReleaseHandle: boolean read fDontReleaseHandle write fDontReleaseHandle;
Destroy
calls FileClose
(Handle) unless this property is true
TFileStreamEx = class(TFileStreamFromHandle)
A TFileStream replacement which supports FileName longer than MAX_PATH, and a proper Create(aHandle) constructor in FPC
constructor Create(const aFileName: TFileName; Mode: cardinal);
Faster (1 API call instead of 3) open or create
the file from its name, depending on the supplied Mode
- Mode is typically fmCreate / fmOpenReadShared
constructor CreateFromHandle(const aFileName: TFileName; aHandle: THandle);
Can use this class from a low-level file OS handle
constructor CreateWrite(const aFileName: TFileName);
Open for writing or create
a non-existing file from its name
- use fmCreate if aFileName does not exists, or fmOpenWrite otherwise
property FileName : TFileName read fFilename;
The file name assigned to this class constructor
TFileStreamNoWriteError = class(TFileStreamEx)
File stream which ignores I/O write errors
- in case disk space is exhausted, TFileStreamNoWriteError.WriteBuffer won't throw any exception, so application will continue to work
- used e.g. by TSynLog
to let the application continue with no exception, even in case of a disk/partition full of logs
constructor CreateAndRenameIfLocked( var aFileName: TFileName; aAliases: integer = 3);
Open for writing, potentially with alternate unlocked file names
- use fmCreate if aFileName does not exists, or fmOpenWrite otherwise
- on error, will try up to aAliases alternate '<filename>-locked<#>.<ext>'
function Write(const Buffer; Count: Longint): Longint; override;
This overriden function returns Count, as if it was always successful
TMemoryMap = object(TObject)
Cross-platform memory mapping of a file content
function Map(const aFileName: TFileName): boolean; overload;
Map
the file specified by its name
- file will be closed when UnMap
will be called
function Map(aFile: THandle; aCustomSize: PtrUInt = 0; aCustomOffset: Int64 = 0; aFileOwned: boolean = false; aFileSize: Int64 = -1): boolean; overload;
Map
the corresponding file handle
- if aCustomSize and aCustomOffset are specified, the corresponding map
view if created (by default, will map
whole file)
procedure Map(aBuffer: pointer; aBufferSize: PtrUInt); overload;
Set a fixed buffer
for the content
- emulates memory-mapping over an existing buffer
procedure UnMap;
Unmap
the file
property Buffer: PAnsiChar read fBuf;
Retrieve the memory buffer
mapped to the file content
property FileHandle: THandle read fFile;
Access to the low-level associated File handle (if any)
property FileSize: Int64 read fFileSize;
Retrieve the mapped file size
property Size: PtrUInt read fBufSize;
TSynMemoryStreamMapped = class(TSynMemoryStream)
A TStream created from a file content, using fast memory mapping
constructor Create(aFile: THandle; aCustomSize: PtrUInt = 0; aCustomOffset: Int64 = 0); overload;
Create
a TStream from a file content using fast memory mapping
- if aCustomSize and aCustomOffset are specified, the corresponding map view if created (by default, will map whole file)
constructor Create(const aFileName: TFileName; aCustomSize: PtrUInt = 0; aCustomOffset: Int64 = 0); overload;
Create
a TStream from a file content using fast memory mapping
- if aCustomSize and aCustomOffset are specified, the corresponding map view if created (by default, will map whole file)
destructor Destroy; override;
Release any internal mapped file instance
property FileName: TFileName read fFileName;
The file name, if created from such Create
(aFileName) constructor
TExecutableResource = object(TObject)
Low-level access to a resource bound to the executable
- so that Windows is not required in your unit uses clause
Buffer: pointer;
The resource memory pointer, after successful Open()
Size: PtrInt;
The resource memory size
in bytes, after successful Open()
function Open(const ResourceName: string; ResType: PChar; Instance: TLibHandle = 0): boolean;
Locate and lock a resource
- use the current executable
if Instance is left to its 0 default value
- returns TRUE if the resource has been found, and Buffer
/Size
are set
procedure Close;
Unlock and finalize a resource
TSystemUseData = packed record
Store
CPU and RAM usage for a given process
- as used by TSystemUse
class
Kernel: single;
Percent of current Kernel
-space CPU usage for this process
Timestamp: TDateTime;
When the data has been sampled
User: single;
Percent of current User
-space CPU usage for this process
VirtualKB: cardinal;
How many KB of virtual memory are used by this process
WorkKB: cardinal;
How many KB of working memory are used by this process
TProcessInfo = object(TObject)
Low-level structure used to compute process memory and CPU usage
function Init: boolean;
Initialize the system/process resource tracking
function PerProcess(PID: cardinal; Now: PDateTime; out Data: TSystemUseData; var PrevKernel, PrevUser: Int64): boolean;
Retrieve CPU and RAM usage for a given process
function PerSystem(out Idle, Kernel, User: single): boolean;
Percent of current Idle/Kernel/User CPU usage for all processes
function Start: boolean;
To be called before PerSystem
() or PerProcess
() iteration
TMemoryInfo = record
Hold low-level information about current memory usage
- as filled by GetMemoryInfo
()
TDiskPartition = packed record
Stores information about a disk partition
mounted: TFileName;
Where this partition has been mounted
- e.g. 'C:' or '/home'
- you can use GetDiskInfo
(mounted
) to retrieve current space information
name: RawUtf8;
The name
of this partition
- is the Volume name
under Windows, or the Device name
under POSIX
size: QWord;
Total size
(in bytes) of this partition
TSynLibrary = class(TObject)
Encapsulate cross-platform loading of library files
- this generic class can be used for any external library (.dll/.so)
destructor Destroy; override;
Release associated memory and linked library
function Exists: boolean;
Return TRUE if the library and all procedures were found
function Resolve(const Prefix, ProcName: RawUtf8; Entry: PPointer; RaiseExceptionOnFailure: ExceptionClass = nil): boolean;
Cross-platform resolution of a function entry in this library
- if RaiseExceptionOnFailure is set, missing entry will call FreeLib
then raise it
- ProcName can be a space-separated list of procedure names, to try alternate API names (e.g. for OpenSSL 1.1.1/3.x compatibility)
- if ProcName starts with '?' then RaiseExceptionOnFailure = nil is set
function ResolveAll(ProcName: PPAnsiChar; Entry: PPointer): boolean;
Cross-platform resolution of all function entries in this library
- will search and fill Entry^ for all ProcName^ until ProcName^=nil
- return true on success, false and call FreeLib
if any entry is missing
function TryLoadLibrary(const aLibrary: array of TFileName; aRaiseExceptionOnFailure: ExceptionClass): boolean; virtual;
Same as SafeLoadLibrary() but setting fLibraryPath and cwd on Windows
procedure FreeLib;
Cross-platform call to FreeLibrary() + set fHandle := 0
- as called by Destroy
, but you can use it directly to reload the library
property Handle: TLibHandle read fHandle write fHandle;
The associated library handle
property LibraryPath: TFileName read fLibraryPath;
The loaded library path
- on POSIX, contains the full path (via dladdr) once Resolve
() is called
property TryFromExecutableFolder: boolean read fTryFromExecutableFolder write fTryFromExecutableFolder;
If set, and no path is specified, will try from Executable.ProgramFilePath
TLightLock = object(TObject)
A lightweight exclusive non-reentrant lock, stored in a PtrUInt
value
- calls SwitchToThread
after some spinning, but don't use any R/W OS API
- warning: methods are non reentrant, i.e. calling Lock twice in a raw would deadlock: use TRWLock
or TSynLocker
/TOSLock
for reentrant methods
- several lightlocks, each protecting a few variables (e.g. a list), may be more efficient than a more global TOSLock
/TRWLock
- our light locks are expected to be kept a very small amount of time (some CPU cycles): use TOSLightLock
if the lock may block too long
- TryLock/UnLock can be used to thread-safely acquire a shared resource
- only consume 4 bytes on CPU32, 8 bytes on CPU64
function IsLocked: boolean;
Check if the non-reentrant lock
has been acquired
function TryLock: boolean;
Try to enter an exclusive non-reentrant lock
- if returned true, caller should eventually call UnLock
()
- could also be used to thread-safely acquire a shared resource
procedure Done;
Could be called to finalize the instance as a TOSLock
- does nothing - just for compatibility with TOSLock
procedure Init;
To be called if the instance has not been filled with 0
- e.g. not needed if TLightLock
is defined as a class field
procedure Lock;
Enter an exclusive non-reentrant lock
procedure UnLock;
Leave an exclusive non-reentrant lock
TRWLightLock = object(TObject)
A lightweight multiple Reads / exclusive Write non-upgradable lock
- calls SwitchToThread
after some spinning, but don't use any R/W OS API
- warning: ReadLocks are reentrant and allow concurrent acccess, but calling WriteLock within a ReadLock, or within another WriteLock, would deadlock
- consider TRWLock
if you need an upgradable lock - but for mostly reads, TRWLightLock.ReadLock
/ReadUnLock/WriteLock pattern is faster than upgrading
- our light locks are expected to be kept a very small amount of time (some CPU cycles): use TSynLocker
or TOSLock
if the lock may block too long
- several lightlocks, each protecting a few variables (e.g. a list), may be more efficient than a more global TOSLock
/TRWLock
- only consume 4 bytes on CPU32, 8 bytes on CPU64
function TryReadLock: boolean;
Try to enter a non-upgradable multiple reads lock
- if returned true, caller should eventually call ReadUnLock
- read locks maintain a thread-safe counter, so are reentrant and non blocking
- warning: nested WriteLock
call after a ReadLock
would deadlock
function TryWriteLock: boolean;
Try to enter a non-reentrant non-upgradable exclusive write lock
- if returned true, caller should eventually call WriteUnLock
- warning: nested TryWriteLock
call after a ReadLock
or another WriteLock
would deadlock
procedure Init;
To be called if the instance has not been filled with 0
- e.g. not needed if TRWLightLock
is defined as a class field
procedure ReadLock;
Enter a non-upgradable multiple reads lock
- read locks maintain a thread-safe counter, so are reentrant and non blocking
- warning: nested WriteLock
call after a ReadLock
would deadlock
procedure ReadUnLock;
Leave a non-upgradable multiple reads lock
procedure WriteLock;
Enter a non-reentrant non-upgradable exclusive write lock
- warning: nested WriteLock
call after a ReadLock
or another WriteLock
would deadlock
procedure WriteUnLock;
Leave a non-reentrant non-upgradable exclusive write lock
TRWLock = object(TObject)
A lightweight multiple Reads / exclusive Write reentrant lock
- calls SwitchToThread
after some spinning, but don't use any R/W OS API
- our light locks are expected to be kept a very small amount of time (some CPU cycles): use TSynLocker
or TOSLock
if the lock may block too long
- warning: all methods are reentrant, but WriteLock/ReadWriteLock would deadlock if called after a ReadOnlyLock
procedure AssertDone;
Could be called at shutdown to ensure that the R/W lock
is in neutral state
procedure Init;
Initialize the R/W lock
- not needed if TRWLock
is part of a class - i.e. if was filled with 0
procedure Lock(context: TRWLockContext = cWrite );
Circumvent weird Delphi bug a high-level wrapper over ReadOnlyLock
/ReadWriteLock
/WriteLock
methods
procedure ReadOnlyLock;
Wait for the lock
to be available for reading, but not upgradable to write
- several readers could acquire the lock
simultaneously
- ReadOnlyLock
is reentrant since there is a thread-safe internal counter
- warning: calling ReadWriteLock
/WriteLock
after ReadOnlyLock
would deadlock
- typical usage is the following:
rwlock.ReadOnlyLock; // won't block concurrent ReadOnlyLock try result := Exists(value); finally rwlock.ReadOnlyUnLock; end;
procedure ReadOnlyUnLock;
Release a previous ReadOnlyLock
call
procedure ReadWriteLock;
Wait for the lock
to be accessible for reading - later upgradable to write
- will mark the lock
with the current thread so that a nested WriteLock
would be possible, but won't block concurrent ReadOnlyLock
- several readers could acquire ReadOnlyLock
simultaneously, but only a single thread could acquire a ReadWriteLock
- reentrant method, and nested WriteLock
is allowed
- typical usage is the following:
rwlock.ReadWriteLock; // won't block concurrent ReadOnlyLock try // but block other ReadWriteLock/WriteLock result := Exists(value); if not result then begin rwlock.WriteLock; // block any ReadOnlyLock/ReadWriteLock/WriteLock try Add(value); finally rwlock.WriteUnLock; end; end; finally rwlock.ReadWriteUnLock; end;
procedure ReadWriteUnLock;
Release a previous ReadWriteLock
call
procedure UnLock(context: TRWLockContext = cWrite );
A high-level wrapper over ReadOnlyUnLock
/ReadWriteUnLock
/WriteUnLock
methods
procedure WriteLock;
Wait for the lock
to be accessible for writing
- the write lock
is exclusive
- calling WriteLock
within a ReadWriteLock
is allowed and won't block
- but calling WriteLock
within a ReadOnlyLock
would deaadlock
- this method is reentrant from a single thread
- typical usage is the following:
rwlock.WriteLock; // block any ReadOnlyLock/ReadWriteLock/WriteLock try Add(value); finally rwlock.WriteUnLock; end;
procedure WriteUnlock;
Release a previous WriteLock
call
TOSLock = object(TObject)
The standard reentrant lock supplied by the Operating System
- maps TRTLCriticalSection
, i.e. calls Win32 API or pthreads library
- don't forget to call Init and Done to properly initialize the structure
- if you do require a non-reentrant/recursive lock, consider TOSLightLock
- same signature as TLightLock
/TOSLightLock
, usable as compile time alternatives
function TryLock: boolean;
Try to enter an OS lock
- if returned true, caller should eventually call UnLock
()
procedure Done;
To be called to finalize the instance
procedure Init;
To be called to setup the instance
- mandatory in all cases, even if TOSLock
is part of a class
procedure Lock;
Enter an OS lock
- notice: this method IS reentrant/recursive
procedure UnLock;
Leave an OS lock
TOSLightLock = object(TObject)
The fastest non-reentrant lock supplied by the Operating System
- calls Slim Reader/Writer (SRW) Win32 API in exclusive mode or directly the pthread_mutex_*() library calls in non-recursive/fast mode on Linux
- on XP, where SRW are not available, fallback to a TLightLock
- on non-Linux POSIX, fallback to regular cthreads/TRTLCriticalSection
- don't forget to call Init and Done to properly initialize the structure
- to protect a very small code section of a few CPU cycles with no Init/Done needed, and a lower footprint, you may consider our TLightLock
- same signature as TOSLock
/TLightLock
, usable as compile time alternatives
- warning: non-reentrant, i.e. nested Lock calls would block, as TLightLock
- no TryLock is defined on Windows, because TryAcquireSRWLockExclusive
() raised some unexpected EExternalException C000026 NT_STATUS_RESOURCE_NOT_OWNED ("Attempt to release mutex not owned by caller") during testing
procedure Done;
To be called to finalize the instance
procedure Init;
To be called to setup the instance
- mandatory in all cases, even if TOSLock
is part of a class
procedure Lock;
Enter an OS lock
- warning: this method is NOT reentrant/recursive, so any nested call would deadlock
procedure UnLock;
Leave an OS lock
TLockedListOne = record
Abstract parent of one data entry in TLockedList
, storing two PLockedListOne
- TLockedList
should store
unmanaged records starting with those fields
- sequence field contains an incremental random-seeded 30-bit integer > 65535, to avoid ABA problems when instances are recycled
TLockedList = object(TObject)
Thread-safe dual-linked list of TLockedListOne
descendants with recycling
Count: integer;
How many TLockedListOne
instances are currently stored in this list
- excluding the instances in the recycle bin
Safe: TLightLock;
Thread-safe
access to the list
function EmptyBin: integer;
Release all to-be-recycled items available in the internal bin
- returns how many items have been released from the internal collector
function Free(one: pointer): boolean;
Release one PLockedListOne
used data instance in threadsafe O(1) process
function New: pointer;
Allocate a new
PLockedListOne
data instance in threadsafe O(1) process
procedure Clear;
Release all TLockedListOne
instances currently stored in this list
- without moving any of those instances into the internal recycle bin
procedure Done;
Release all stored memory
procedure Init(onesize: PtrUInt; const onefree: TOnLockedListOne = nil);
Initialize the storage for an inherited TLockedListOne
size
property Head: pointer read fHead;
Raw access to the stored items as PLockedListOne
dual-linked list
property Size: integer read fSize;
The size
of one stored instance, including its TLockedListOne
header
TSynLocker = object(TObject)
Allow to add cross-platform locking methods to any class instance
- typical use is to define a Safe: TSynLocker
property, call Safe.Init and Safe.Done in constructor/destructor methods, and use Safe.Lock/UnLock methods in a try ... finally section
- in respect to the TCriticalSection class, fix a potential CPU cache line conflict which may degrade the multi-threading performance, as reported by @http
://www.delphitools.info/2011/11/30/fixing-tcriticalsection
- internal padding is used to safely store
up to 7 values protected from concurrent access with a mutex, so that SizeOf(TSynLocker
)>128
- for object-level locking, see TSynLocked
which owns one such instance, or call low-level fSafe := NewSynLocker
in your constructor, then fSafe^.DoneAndFreemem in your destructor
- RWUse property could replace the TRTLCriticalSection
by a lighter TRWLock
- see also TRWLock
and TObjectRWLock
if the multiple read / exclusive write lock is better (only if the locked process does not take too much time)
Padding: array[0..6] of TSynVarData;
Internal padding
data, also used to store
up to 7 variant values
- this memory buffer will ensure no CPU cache line mixup occurs
- you should not use this field directly, but rather the Locked
[], LockedInt64
[], LockedUtf8
[] or LockedPointer
[] methods
- if you want to access those array values, ensure you protect them using a Safe.Lock; try ... Padding
[n] ... finally Safe.Unlock structure, and maintain the PaddingUsedCount
property accurately
function LockedExchange(Index: integer; const Value: variant): variant;
Safe locked
in-place exchange of a Variant value
- you may store
up to 7 variables, using an 0..6 index, shared with Locked
and LockedUtf8
array properties
- returns the previous stored value, or null
if the Index is out of range
function LockedInt64Increment(Index: integer; const Increment: Int64): Int64;
Safe locked
in-place increment to an Int64 value
- you may store
up to 7 variables, using an 0..6 index, shared with Locked
and LockedUtf8
array properties
- Int64s will be stored internally as a varInt64 variant
- returns the newly stored value
- if the internal value is not defined yet, would use 0 as default value
function LockedPointerExchange(Index: integer; Value: pointer): pointer;
Safe locked
in-place exchange of a pointer/TObject value
- you may store
up to 7 variables, using an 0..6 index, shared with Locked
and LockedUtf8
array properties
- pointers will be stored internally as a varUnknown variant
- returns the previous stored value, nil if the Index is out of range, or does not store
a pointer
function ProtectMethod: IUnknown;
Will enter the mutex until the IUnknown reference is released
- could be used as such under Delphi:
begin ... // unsafe code Safe.ProtectMethod; ... // thread-safe code end; // local hidden IUnknown will release the lock for the method
- warning: under FPC, you should assign its result to a local variable - see bug http
://bugs.freepascal.org/view.php?id=26602
var LockFPC: IUnknown; begin ... // unsafe code LockFPC := Safe.ProtectMethod; ... // thread-safe code end; // LockFPC will release the lock for the method
or
begin ... // unsafe code with Safe.ProtectMethod do begin ... // thread-safe code end; // local hidden IUnknown will release the lock for the method end;
function TryLock: boolean;
Will try to acquire the mutex
- do nothing and return false if RWUse
is not the default uSharedLock
- use as such to avoid race condition (from a Safe: TSynLocker
property):
if Safe.TryLock then try ... finally Safe.Unlock; end;
function TryLockMS(retryms: integer; terminated: PBoolean = nil): boolean;
Will try to acquire the mutex for a given time
- just wait and return false if RWUse
is not the default uSharedLock
- use as such to avoid race condition (from a Safe: TSynLocker
property):
if Safe.TryLockMS(100) then try ... finally Safe.Unlock; end;
procedure Done;
Finalize the mutex
- calling this method is mandatory (e.g. in the class destructor owning the TSynLocker
instance), otherwise you may encounter unexpected behavior, like access violations or memory leaks
procedure DoneAndFreeMem;
Finalize the mutex, and call FreeMem() on the pointer of this instance
- should have been initiazed with a NewSynLocker
call
procedure Init;
Initialize the mutex
- calling this method is mandatory (e.g. in the class constructor owning the TSynLocker
instance), otherwise you may encounter unexpected behavior, like access violations or memory leaks
procedure Lock;
Lock
the instance for exclusive access, as RWLock(cWrite)
- is re-entrant from the same thread i.e. you can nest Lock
/UnLock
calls
- warning: with RWUse
=uRWLock, would deadlock after a nested ReadLock
, but not after ReadWriteLock
- use as such to avoid race condition (from a Safe: TSynLocker
property):
Safe.Lock; try ... finally Safe.Unlock; end;
procedure ReadLock;
Low-level acquisition of the lock
, as RWLock(cReadOnly)
- if RWUse
=uSharedLock, calls EnterCriticalSection
(no parallel readings)
- warning: with RWUse
=uRWLock, a nested Lock
call would deadlock, but not nested ReadLock
calls
procedure ReadUnLock;
Low-level release of the lock
, as RWUnLock(cReadOnly)
procedure ReadWriteLock;
Low-level acquisition of the lock
, as RWLock(cReadWrite)
- if RWUse
=uSharedLock, calls EnterCriticalSection
(no parallel readings)
- with RWUse
=uRWLock, a nested Lock
call would not deadlock
procedure ReadWriteUnLock;
Low-level release of the lock
, as RWUnLock(cReadWrite)
procedure UnLock; overload;
Release the instance for exclusive access, as RWUnLock(cWrite)
- each Lock
/TryLock
should have its exact UnLock
opposite, so a try..finally block is mandatory for safe code
property IsInitialized: boolean read fInitialized;
Returns true if the Init
method has been called for this mutex
- is only relevant if the whole object has been previously filled with 0, i.e. as part of a class or as global variable, but won't be accurate when allocated on stack
property IsLocked: boolean read GetIsLocked;
Returns true if the mutex is currently locked
by another thread
- with RWUse
=uRWLock, any lock
(even ReadOnlyLock) would return true
property Locked[Index: integer]: Variant read GetVariant write SetVariant;
Safe locked
access to a Variant value
- you may store
up to 7 variables, using an 0..6 index, shared with LockedBool
, LockedInt64
, LockedPointer
and LockedUtf8
array properties
- returns null
if the Index is out of range
- allow concurrent thread reading if RWUse
was set to uRWLock
property LockedBool[Index: integer]: boolean read GetBool write SetBool;
Safe locked
access to a boolean value
- you may store
up to 7 variables, using an 0..6 index, shared with Locked
, LockedInt64
, LockedPointer
and LockedUtf8
array properties
- value will be stored internally as a varboolean variant
- returns nil if the Index is out of range, or does not store
a boolean
- allow concurrent thread reading if RWUse
was set to uRWLock
property LockedInt64[Index: integer]: Int64 read GetInt64 write SetInt64;
Safe locked
access to a Int64 value
- you may store
up to 7 variables, using an 0..6 index, shared with Locked
and LockedUtf8
array properties
- Int64s will be stored internally as a varInt64 variant
- returns nil if the Index is out of range, or does not store
a Int64
- allow concurrent thread reading if RWUse
was set to uRWLock
property LockedPointer[Index: integer]: pointer read GetPointer write SetPointer;
Safe locked
access to a pointer/TObject value
- you may store
up to 7 variables, using an 0..6 index, shared with Locked
, LockedBool
, LockedInt64
and LockedUtf8
array properties
- pointers will be stored internally as a varUnknown variant
- returns nil if the Index is out of range, or does not store
a pointer
- allow concurrent thread reading if RWUse
was set to uRWLock
property LockedUtf8[Index: integer]: RawUtf8 read GetUtf8 write SetUtf8;
Safe locked
access to an UTF-8 string value
- you may store
up to 7 variables, using an 0..6 index, shared with Locked
and LockedPointer
array properties
- UTF-8 string will be stored internally as a varString variant
- returns '' if the Index is out of range, or does not store
a string
- allow concurrent thread reading if RWUse
was set to uRWLock
property PaddingUsedCount: byte read fPaddingUsedCount write fPaddingUsedCount;
Number of values stored in the internal Padding
[] array
- equals 0 if no value is actually stored, or a 1..7 number otherwise
- you should not have to use this field, but for optimized low-level direct access to Padding
[] values, within a Lock
/UnLock
safe block
property RWUse: TSynLockerUse read fRWUse write fRWUse;
How RWLock/RWUnLock would be processed
property UnlockedInt64[Index: integer]: Int64 read GetUnlockedInt64 write SetUnlockedInt64;
Unsafe access to a Int64 value
- you may store
up to 7 variables, using an 0..6 index, shared with Locked
and LockedUtf8
array properties
- Int64s will be stored internally as a varInt64 variant
- returns nil if the Index is out of range, or does not store
a Int64
- you should rather call LockedInt64
[] property, or use this property with a Lock
; try ... finally UnLock
block
TAutoLock = class(TInterfacedObject)
Raw class used by TAutoLocker.ProtectMethod
and TSynLocker.ProtectMethod
- defined here for use by TAutoLocker
in mormot.core.data.pas
TSynEvent = class(TSynPersistent)
Our lightweight cross-platform TEvent
-like component
- on Windows, calls directly the CreateEvent/ResetEvent/SetEvent API
- on Linux, will use eventfd() in blocking and non-semaphore mode
- on other POSIX, will use PRTLEvent which is lighter than TEvent
BasicEvent
- only limitation is that we don't know if WaitFor is signaled or timeout, but this is not a real problem in practice since most code don't need this information or has already its own flag in its implementation logic
constructor Create; override;
For eventfd() initialize an instance of cross-platform event
destructor Destroy; override;
Finalize this instance of cross-platform event
function IsEventFD: boolean;
Could be used to tune your algorithm if the eventfd() API is used
function SleepStep(var start: Int64; terminated: PBoolean): Int64;
Calls SleepHiRes
() in steps while checking terminated flag and this event
procedure ResetEvent;
Ignore any pending events, so that WaitFor
will be set on next SetEvent
procedure SetEvent;
Trigger any pending event, releasing the WaitFor
/WaitForEver
methods
procedure WaitFor(TimeoutMS: integer);
Wait until SetEvent
is called from another thread, with a maximum time
- does not return if it was signaled or timeout
- WARNING: you should wait from a single thread at once
procedure WaitForEver;
Wait until SetEvent
is called from another thread, with no maximum time
TSynLocked = class(TSynPersistent)
A thread-safe class with a virtual constructor and properties persistence
- publishes a TSynLocker
instance, and its managed critical section
- consider a TLightLock
field as lighter options, or a R/W lock with TObjectRWLock
and TObjectRWLightLock
classes, or even a TObjectOSLightLock
- TSynLockedWithRttiMethods
would add paranoid JSON persistence lock
constructor Create; override;
TSynLocker
would increase inherited fields offset initialize the instance, and its associated lock
destructor Destroy; override;
Finalize the instance, and its associated lock
procedure Lock;
Could be used as a short-cut to Safe
^.Lock
procedure Unlock;
Could be used as a short-cut to Safe
^.UnLock
property Safe: PSynLocker read fSafe;
Access to the associated instance critical section
TObjectOSLightLock = class(TSynPersistent)
A thread-safe class with a virtual constructor and properties persistence
- publishes the fastest available non-reentrant Operating System lock
constructor Create; override;
Initialize the instance, and its associated OS lock
destructor Destroy; override;
Finalize the instance, and its associated OS lock
procedure Lock;
Could be used as a short-cut to Safe
^.Lock
procedure Unlock;
Could be used as a short-cut to Safe
^.UnLock
property Safe: TOSLightLock read fSafe;
Access to the associated non-reentrant Operating System lock
instance
TObjectRWLightLock = class(TSynPersistent)
A thread-safe class with a virtual constructor and properties persistence
- publishes a non-upgradable multiple Read / exclusive Write TRWLightLock
property Safe: TRWLightLock read fSafe;
Access to the associated non-upgradable TRWLightLock
instance
- call Safe
methods to protect multi-thread access on this storage
TObjectRWLock = class(TSynPersistent)
A thread-safe class with a virtual constructor and properties persistence
- publishes an upgradable multiple Read / exclusive Write TRWLock
property Safe: TRWLock read fSafe;
Access to the associated upgradable TRWLock
instance
- call Safe
methods to protect multi-thread access on this storage
TLecuyerThreadSafe = object(TObject)
A thread-safe Pierre L'Ecuyer software random generator
- just wrap TLecuyer
with a TLighLock
- should not be used, unless may be slightly faster than a threadvar
function Next: cardinal; overload;
Compute the next
32-bit generated value
function NextDouble: double;
Compute a 64-bit floating point value
procedure Fill(dest: pointer; count: integer);
XOR some memory buffer with random bytes
procedure FillShort31(var dest: TShort31);
Fill
some string[31] with 7-bit ASCII random text
TServiceController = class(TObject)
TServiceControler class is intended to create a new Windows Service instance or to maintain (that is start, stop, pause, resume...) an existing Service
- to provide the service itself, use the TService
class
constructor CreateNewService( const TargetComputer, DatabaseName, Name, DisplayName: RawUtf8; const Path: TFileName; const OrderGroup: RawUtf8 = ''; const Dependencies: RawUtf8 = ''; const Username: RawUtf8 = ''; const Password: RawUtf8 = ''; DesiredAccess: cardinal = SERVICE_ALL_ACCESS; ServiceType: cardinal = SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS; StartType: cardinal = SERVICE_DEMAND_START; ErrorControl: cardinal = SERVICE_ERROR_NORMAL);
Create a new Windows Service and control it and/or its configuration
- TargetComputer - set it to empty string if local computer is the target.
- DatabaseName - set it to empty string if the default database is supposed ('ServicesActive').
- Name - name of a service.
- DisplayName - display name of a service.
- Path - a path to binary (executable
) of the service created.
- OrderGroup - an order group name (unnecessary)
- Dependencies - string containing a list with names of services, which must start
before this service (every name should be separated with ';' or an empty string can be passed if there is no dependency).
- Username - login name. For service type SERVICE_WIN32_OWN_PROCESS
, the account name in the form of "DomainName\Username"; If the account belongs to the built-in domain, ".\Username" can be specified; Services of type SERVICE_WIN32_SHARE_PROCESS
are not allowed to specify an account other than LocalSystem. If '' is specified, the service will be logged on as the 'LocalSystem' account, in which case, the Password parameter must be empty too.
- Password - a password for login name. If the service type is SERVICE_KERNEL_DRIVER or SERVICE_FILE_SYSTEM_DRIVER, this parameter is ignored.
- DesiredAccess - a combination of following flags: SERVICE_ALL_ACCESS
(default value), SERVICE_CHANGE_CONFIG
, SERVICE_ENUMERATE_DEPENDENTS
, SERVICE_INTERROGATE
, SERVICE_PAUSE_CONTINUE
, SERVICE_QUERY_CONFIG
, SERVICE_QUERY_STATUS
, SERVICE_START
, SERVICE_STOP
, SERVICE_USER_DEFINED_CONTROL
- ServiceType - a set of following flags: SERVICE_WIN32_OWN_PROCESS
(default value, which specifies a Win32 service that runs in its own process), SERVICE_WIN32_SHARE_PROCESS
, SERVICE_KERNEL_DRIVER, SERVICE_FILE_SYSTEM_DRIVER, SERVICE_INTERACTIVE_PROCESS
(default value, which enables a Win32 service process to interact with the desktop)
- StartType - one of following values: SERVICE_BOOT_START
, SERVICE_SYSTEM_START
, SERVICE_AUTO_START
(which specifies a device driver or service started by the service control manager automatically during system startup), SERVICE_DEMAND_START
(default value, which specifies a service started by a service control manager when a process calls the StartService function, that is the TServiceController.Start
method), SERVICE_DISABLED
- ErrorControl - one of following: SERVICE_ERROR_IGNORE
, SERVICE_ERROR_NORMAL
(default value, by which the startup program logs the error and displays a message but continues the startup operation), SERVICE_ERROR_SEVERE
, SERVICE_ERROR_CRITICAL
constructor CreateOpenService( const TargetComputer, DataBaseName, Name: RawUtf8; DesiredAccess: cardinal = SERVICE_ALL_ACCESS);
Open an existing service, in order to control it or its configuration from your application
- TargetComputer - set it to empty string if local computer is the target.
- DatabaseName - set it to empty string if the default database is supposed ('ServicesActive').
- Name - name of a service.
- DesiredAccess - a combination of following flags: SERVICE_ALL_ACCESS
, SERVICE_CHANGE_CONFIG
, SERVICE_ENUMERATE_DEPENDENTS
, SERVICE_INTERROGATE
, SERVICE_PAUSE_CONTINUE
, SERVICE_QUERY_CONFIG
, SERVICE_QUERY_STATUS
, SERVICE_START
, SERVICE_STOP
, SERVICE_USER_DEFINED_CONTROL
destructor Destroy; override;
Release memory and handles
class function CurrentState(const Name: RawUtf8): TServiceState;
Wrapper around CreateOpenService
(SERVICE_QUERY_STATUS
) and GetState
function Delete: boolean;
Removes service from the system, i.e. close the Service
class function Install(const Name, DisplayName, Description: RawUtf8; AutoStart: boolean; ExeName: TFileName = ''; const Dependencies: RawUtf8 = ''; const UserName: RawUtf8 = ''; const Password: RawUtf8 = ''): TServiceState;
Wrapper around CreateNewService
() to install
the current executable
as service
function Pause: boolean;
Requests the service to pause
function Refresh: boolean;
Requests the service to update immediately its current status
information to the service control manager
function Resume: boolean;
Requests the paused service to resume
function SetDescription(const Description: RawUtf8): boolean;
Try to define the description text
of this service
function Shutdown: boolean;
Request the service to shutdown
- this function always return false
function Start(const Args: array of PWideChar): boolean;
Starts the execution of a service with some specified arguments
- this version expect
PWideChar pointers, i.e. UTF-16 strings
function Stop: boolean;
Requests the service to stop
class procedure CheckParameters(const ExeFileName: TFileName; const ServiceName, DisplayName, Description: RawUtf8; const Dependencies: RawUtf8 = '');
This class method will check the command line parameters, and will let control the service according to it
- MyServiceSetup.exe /install
will install
the service
- MyServiceSetup.exe /start
will start
the service
- MyServiceSetup.exe /stop
will stop
the service
- MyServiceSetup.exe /uninstall will uninstall the service
- so that you can write in the main block of your .dpr:
CheckParameters('MyService.exe',HTTPSERVICENAME,HTTPSERVICEDISPLAYNAME);
- if ExeFileName='', it will install
the current executable
- optional Description and Dependencies text
may be specified
property Handle: THandle read fHandle;
Handle
of service opened or created
- its value is 0 if something failed in any Create*() method
property SCHandle: THandle read fSCHandle;
Handle
of SC manager
property State: TServiceState read GetState;
Retrieve the Current state
of the service
property Status: TServiceStatus read GetStatus;
Retrieve the Current status
of the service
TService = class(TSynPersistent)
Abstract class to let an executable
implement a Windows Service
- do not use this class directly, but TServiceSingle
constructor Create(const aServiceName, aDisplayName: RawUtf8); reintroduce; virtual;
Creates the service
- the service is added to the internal registered services
- main application must instantiate the TServiceSingle
class, then call the global ServiceSingleRun
procedure to actually start
the services
- caller must free the TService
instance when it's no longer used
function Install(const Params: TFileName = ''): boolean;
Installs the service in the database
- return true on success
- create
a local TServiceController
with the current executable
file, with the supplied command line parameters
- you can optionally append
some parameters, which will be appended to the
function ReportStatus(dwState, dwExitCode, dwWait: cardinal): BOOL;
Reports new status
to the system
procedure DoCtrlHandle(Code: cardinal); virtual;
This method is the main service entrance, from the OS point of view
- it will call OnControl
/OnStop
/OnPause
/OnResume
/OnShutdown
events
- and report the service status
to the system (via ReportStatus
method)
class procedure DoLog(Level: TSynLogLevel; const Fmt: RawUtf8; const Args: array of const; Instance: TObject);
Internal method redirecting to WindowsServiceLog
global variable
procedure Execute; virtual;
This is the main method, in which the Service should implement its run
procedure Remove;
Removes the service from database
- uses a local TServiceController
with the current Service Name
procedure Start;
Starts the service
- uses a local TServiceController
with the current Service Name
procedure Stop;
Stops the service
- uses a local TServiceController
with the current Service Name
property ArgCount: integer read GetArgCount;
Number of arguments passed to the service by the service controler
property Args[Idx: integer]: RawUtf8 read GetArgs;
List of arguments passed to the service by the service controler
- Idx is in range 0..ArgCount
- 1
property ControlHandler: TServiceControlHandler read GetControlHandler write SetControlHandler;
Callback handler for Windows Service Controller
- if handler is not set, then auto generated handler calls DoCtrlHandle
(note that this auto-generated stubb is... not working yet - so you should either set your own procedure to this property, or use TServiceSingle
)
- a typical control handler may be defined as such:
var MyGlobalService: TService;
procedure MyServiceControlHandler(Opcode: LongWord); stdcall; begin if MyGlobalService<>nil then MyGlobalService.DoCtrlHandle(Opcode); end;
... MyGlobalService := TService.Create(... MyGlobalService.ControlHandler := MyServiceControlHandler;
property Data: cardinal read FData write FData;
Any data
You wish to associate with the service object
property DisplayName: RawUtf8 read fDisplayName write fDisplayName;
Display name of the service
property Installed: boolean read GetInstalled;
Whether service is installed
in DataBase
- uses a local TServiceController
to check if the current Service Name exists
property OnControl: TServiceControlEvent read fOnControl write fOnControl;
Custom event triggered when a Control Code is received from Windows
property OnExecute: TServiceEvent read fOnExecute write fOnExecute;
Custom Execute event
- launched in the main service thread (i.e. in the Execute method)
property OnInterrogate: TServiceEvent read fOnInterrogate write fOnInterrogate;
Custom event triggered when the service receive an Interrogate command
- could call ReportStatus
() e.g. to notify a problem
property OnPause: TServiceEvent read fOnPause write fOnPause;
Custom event triggered when the service is paused
property OnResume: TServiceEvent read fOnResume write fOnResume;
Custom event triggered when the service is resumed
property OnShutdown: TServiceEvent read fOnShutdown write fOnShutdown;
Custom event triggered when the service is shut down
property OnStart: TServiceEvent read fOnStart write fOnStart;
Start
event is executed before the main service thread (i.e. in the Execute method)
property OnStop: TServiceEvent read fOnStop write fOnStop;
Custom event triggered when the service is stopped
property ServiceName: RawUtf8 read fServiceName;
Name of the service. Must be unique
property ServiceType: cardinal read fServiceType write fServiceType;
Type of service
property StartType: cardinal read fStartType write fStartType;
Type of start
of service
property Status: TServiceStatus read fStatusRec write SetStatus;
Current service status
- To report new status
to the system, assign another value to this record, or use ReportStatus
method (preferred)
TServiceSingle = class(TService)
Inherit from this class if your application has a single Windows Service
- note that only this single-service implementation is available by now
- the regular way of executing services is to instantiate a TServiceSingle
instance (which will fill the ServiceSingle
variable) and its methods, then eventually call ServiceSingleRun
constructor Create(const aServiceName, aDisplayName: RawUtf8); override;
Will set a global function as service controller
destructor Destroy; override;
Will release the global service controller
PLockedListOne = ^TLockedListOne;
Points to one data entry in TLockedList
PSynLocker = ^TSynLocker;
A pointer to a TSynLocker
mutex instance
- see also NewSynLocker
and TSynLocker.DoneAndFreemem
functions
TAppendShortUuid = procedure(const u: TGuid; var s: ShortString);
Function prototype for AppendShortUuid
()
TArmCpuImplementer = ( aciUnknown, aciARM, aciBroadcom, aciCavium, aciDEC, aciFUJITSU, aciHiSilicon, aciInfineon, aciMotorola, aciNVIDIA, aciAPM, aciQualcomm, aciSamsung, aciMarvell, aciApple, aciFaraday, aciIntel, aciMicrosoft, aciPhytium, aciAmpere );
The recognized ARM/AARCH64 CPU hardware implementers
- https://github.com/karelzak/util-linux/blob/master/sys-utils/lscpu-arm.c
TArmCpuImplementers = set of TArmCpuImplementer;
A set of recognized ARM/AARCH64 CPU hardware implementers
TArmCpuType = ( actUnknown, actARM810, actARM920, actARM922, actARM926, actARM940, actARM946, actARM966, actARM1020, actARM1022, actARM1026, actARM11MPCore, actARM1136, actARM1156, actARM1176, actCortexA5, actCortexA7, actCortexA8, actCortexA9, actCortexA12, actCortexA15, actCortexA17, actCortexR4, actCortexR5, actCortexR7, actCortexR8, actCortexM0, actCortexM1, actCortexM3, actCortexM4, actCortexM7, actCortexM0P, actCortexA32, actCortexA53, actCortexA35, actCortexA55, actCortexA65, actCortexA57, actCortexA72, actCortexA73, actCortexA75, actCortexA76, actNeoverseN1, actCortexA77, actCortexA76AE, actCortexR52, actCortexM23, actCortexM33, actNeoverseV1, actCortexA78, actCortexA78AE, actCortexX1, actCortex510, actCortex710, actCortexX2, actNeoverseN2, actNeoverseE1, actCortexA78C, actCortexX1C, actCortexA715, actCortexX3, actNeoverseV2, actCortexA520, actCortexA720, actCortexX4, actNeoverseV3, actCortextX925, actCortextA725, actNeoverseN3 );
The recognized ARM/AARCH64 CPU types
- https://github.com/karelzak/util-linux/blob/master/sys-utils/lscpu-arm.c
- is defined on all platforms for cross-system use
TArmCpuTypes = set of TArmCpuType;
A set of recognized ARM/AARCH64 CPU types
TConsoleColor = ( ccBlack, ccBlue, ccGreen, ccCyan, ccRed, ccMagenta, ccBrown, ccLightGray, ccDarkGray, ccLightBlue, ccLightGreen, ccLightCyan, ccLightRed, ccLightMagenta, ccYellow, ccWhite );
Available console colors
TCpuSet = PtrUInt ;
Store
a bitmask of logical CPU cores, as used by SetThreadMaskAffinity
- has 32/64-bit pointer-size on Windows, or 1024 bits on POSIX
TDiskPartitions = array of TDiskPartition;
Stores information about several disk partitions
TExecutableCommandLineKind = ( clkUndefined, clkArg, clkOption, clkParam );
The command line switches supported by TExecutableCommandLine
- clkArg is for "exename arg1 arg2 arg3" main indexed arguments
- clkOption is for "exename -o --opt1" boolean flags
- clkParam is for "exename -n value --name value --name2=value2" pairs
TFileAge = integer;
System-specific type returned by FileAge(): local 32-bit bitmask on Windows
TGetComputerUuid = set of ( gcuSmbios, gcuSmbiosData, gcuSmbiosText, gcuCpuFeatures, gcuCpuInfoText, gcuBiosInfoText, gcuMacAddress);
Define how GetComputerUuid
() computes its 128-bit UUID identifier
- set of potential sources, which may be excluded from computation
TIsDirectoryWritable = set of ( idwExcludeWinUac, idwExcludeWinSys, idwTryWinExeFile, idwWriteSomeContent);
Defines how IsDirectoryWritable
() verifies a folder
- on Win32 Vista+, idwExcludeWinUac will check IsUacVirtualFolder
()
- on Windows, idwExcludeWinSys will check IsSystemFolder
()
- on Windows, idwTryWinExeFile will try to generate a 'xxxxx.exe' file
- idwWriteSomeContent will also try to write some bytes into the file
TLibHandle = THandle;
Defined as in FPC RTL, to avoid dependency to Windows.pas unit
- note that on POSIX, a THandle is a 32-bit integer, but library or resource handles are likely to map pointers, i.e. up to a 64-bit integer
TLineFeed = ( lfSystem, lfCR, lfCRLF );
Allow to customize the possible line feeds
TOnLockedListOne = procedure(one: PLockedListOne) of object;
Optional callback event to finalize one TLockedListOne
instance
TOnRawLogException = procedure(const Ctxt: TSynLogExceptionContext);
The global function signature expected by RawExceptionIntercept
()
- assigned e.g. to SynLogException() in mormot.core.log.pas
TOnRedirect = function(const text: RawByteString; pid: cardinal): boolean of object;
Callback used by RunRedirect
() to notify of console output at runtime
- newly console output text
is given as raw bytes sent by the application, with no conversion: on POSIX, it is likely to be UTF-8 but on Windows it depends on the actual program so is likely to be CP_OEM
but others could use the system code page or even UTF-16 binary with BOM (!) - so you may consider using AnsiToUtf8
() with the proper code page
- should return true to stop the execution, or false to continue
- is called once when the process is started, with text
='', ignoring its return
- on idle state (each 200ms), is called with text
='' to allow execution abort
- the raw process ID (dword on Windows, cint on POSIX) is also supplied
TOperatingSystem = ( osUnknown, osWindows, osLinux, osOSX, osBSD, osPOSIX, osArch, osAurox, osDebian, osFedora, osGentoo, osKnoppix, osMint, osMandrake, osMandriva, osNovell, osUbuntu, osSlackware, osSolaris, osSuse, osSynology, osTrustix, osClear, osUnited, osRedHat, osLFS, osOracle, osMageia, osCentOS, osCloud, osXen, osAmazon, osCoreOS, osAlpine, osAndroid );
The known operating systems
- it will also recognize most Linux distributions
TOSLightMutex = pointer;
Handle for Slim Reader/Writer (SRW) locks in exclusive mode
TParseCommand = ( pcHasRedirection, pcHasSubCommand, pcHasParenthesis, pcHasJobControl, pcHasWildcard, pcHasShellVariable, pcUnbalancedSingleQuote, pcUnbalancedDoubleQuote, pcTooManyArguments, pcInvalidCommand, pcHasEndingBackSlash );
Command line patterns recognized by ParseCommandArgs
()
TParseCommandsArgs = array[0..31] of PAnsiChar;
Used to store
references of arguments recognized by ParseCommandArgs
()
TRTLCriticalSection = Windows.TRTLCriticalSection;
Redefined as our own mormot.core.os type to avoid dependency to Windows
TRunAbortMethods = set of (ramCtrlC, ramQuit);
How RunRedirect
() or RunCommand
() should try to gracefully terminate
- ramCtrlC calls CancelProcess
(), i.e. send CTRL_C_EVENT
- ramQuit calls QuitProcess
(), i.e. send WM_QUIT on all the process threads
- note that TerminateProcess is always called after RunAbortTimeoutSecs
timeout, or if this set of methods is void
TRunOptions = set of ( roEnvAddExisting, roWinJobCloseChildren, roWinNoProcessDetach);
Define how RunCommand
() and RunRedirect
() run their sub-process
- roEnvAddExisting is used when the env pairs should be added to the existing system environment variable
- roWinJobCloseChildren will setup a Windows Job to close any child process(es) when the created process quits
- roWinNoProcessDetach will avoid creating a Windows sub-process and group
TRWLockContext = ( cReadOnly, cReadWrite, cWrite );
How TRWLock.Lock
and TRWLock.UnLock
high-level wrapper methods are called
TServiceControlEvent = procedure(Sender: TService; Code: cardinal) of object;
Event triggered for Control handler
TServiceControlHandler = procedure(CtrlCode: cardinal); stdcall;
Callback procedure for Windows Service Controller
TServiceEvent = procedure(Sender: TService) of object;
Event triggered to implement the Service functionality
TServiceState = ( ssNotInstalled, ssStopped, ssStarting, ssStopping, ssRunning, ssResuming, ssPausing, ssPaused, ssFailed, ssErrorRetrievingState );
All possible states of a Windows service
- on POSIX, will identify only if the daemon is ssRunning or ssStopped
TShortToUuid = function(const text: ShortString; out uuid: TGuid): boolean;
Function prototype for ShortToUuid
()
TSmbiosBasicInfo = ( sbiUndefined, sbiBiosVendor, sbiBiosVersion, sbiBiosFirmware, sbiBiosRelease, sbiBiosDate, sbiManufacturer, sbiProductName, sbiVersion, sbiSerial, sbiUuid, sbiSku, sbiFamily, sbiBoardManufacturer, sbiBoardProductName, sbiBoardVersion, sbiBoardSerial, sbiBoardAssetTag, sbiBoardLocation, sbiCpuManufacturer, sbiCpuVersion, sbiCpuSerial, sbiCpuAssetTag, sbiCpuPartNumber, sbiBatteryLocation, sbiBatteryManufacturer, sbiBatteryName, sbiBatteryVersion, sbiBatteryChemistry, sbiOem );
The basic SMBIOS
fields supported by GetSmbios
/DecodeSmbios
functions
- only include the first occurrence for board/cpu/battery types
- see TSmbiosInfo
in mormot.core.perf.pas for more complete decoding
TSmbiosBasicInfos = array[TSmbiosBasicInfo] of RawUtf8;
The text
fields stored by GetSmbios
/DecodeSmbios
functions
TSynLockerUse = ( uSharedLock, uRWLock, uNoLock );
How TSynLocker
handles its thread processing
- by default, uSharedLock will use the main TRTLCriticalSection
- you may set uRWLock and call overloaded RWLock/RWUnLock() to use our lighter TRWLock
- but be aware that cReadOnly followed by cReadWrite/cWrite would deadlock - regular Lock/UnLock will use cWrite exclusive lock
- uNoLock will disable the whole locking mechanism
TSystemCertificateStore = ( scsCA, scsMY, scsRoot, scsSpc );
Identify the (Windows) system certificate stores for GetSystemStoreAsPem
()
- ignored on POSIX systems, in which the main cacert.pem file is used
- scsCA contains known Certification Authority certificates, i.e. from entities entrusted to issue certificates that assert that the recipient individual, computer, or organization requesting the certificate fulfills the conditions of an established policy
- scsMY holds certificates with associated private keys (Windows only)
- scsRoot contains known Root certificates, i.e. self-signed CA certificates which are the root of the whole certificates trust tree
- scsSpc contains Software Publisher Certificates (Windows only)
TSystemPath = ( spCommonData, spUserData, spCommonDocuments, spUserDocuments, spTemp, spLog );
Identify an operating system folder for GetSystemPath
()
- on Windows, spCommonData maps e.g. 'C:\ProgramData', spUserData points to 'C:\Users\<user>\AppData\Local', spCommonDocuments to 'C:\Users\Public\Documents', spUserDocuments to 'C:\Users\<user>\Documents', spTemp will call GetTempPath() or read the $TEMP environment variable, pointing typically to 'C:\Users\<user>\AppData\Local\Temp\', and spLog either to '<exepath>\log' or 'C:\Users\<user>\AppData\Local\<exename>-log' (the first writable)
- on POSIX, spTemp will use $TMPDIR/$TMP environment variables, spCommonData, spCommonDocuments and spUserDocuments point to $HOME, spUserData maps $XDG_CACHE_HOME or '$HOME/.cache' or '$TMP/<user>', and spLog maps '/var/log/<exename>' or '<exepath>/log' or '$TMP/<exename>-log'
- on all systems, returned spTemp, spLog and spUserData folders are always writable by the current user
TSystemTime = Windows.TSystemTime;
Redefined as our own mormot.core.os type to avoid dependency to Windows
- warning: do not use this type directly, but rather TSynSystemTime
as defined in mormot.core.datetime which is really cross-platform, and has consistent field order (FPC POSIX/Windows fields do not match!)
TSystemUseDataDynArray = array of TSystemUseData;
Store
CPU and RAM usage history for a given process
- as returned by TSystemUse.History
TThreadID = DWORD;
Windows handle for a Thread - for cross-platform/cross-compiler clarity
- note that on POSIX TThreadID
is a pointer and not a 32-bit file handle
TUriMethod = ( mNone, mGET, mPOST, mPUT, mDELETE, mHEAD, mBEGIN, mEND, mABORT, mLOCK, mUNLOCK, mSTATE, mPATCH, mOPTIONS );
The available HTTP
methods transmitted between client and server
- remote ORM supports non-standard mLOCK/mUNLOCK/mABORT/mSTATE verbs
- not all IANA verbs are available, because our TRestRouter
will only support mGET .. mOPTIONS verbs anyway
- for basic CRUD operations, we consider Create=mPOST, Read=mGET, Update=mPUT and Delete=mDELETE - even if it is not fully RESTful
TUriMethods = set of TUriMethod;
Set of available HTTP
methods transmitted between client and server
TW32Temp = array[0..W32_MAX] of WideChar;
4KB stack buffer for no heap allocation during UTF-16 encoding or switch to extended-length path
TWindowsVersion = ( wUnknown, w2000, wXP, wXP_64, wServer2003, wServer2003_R2, wVista, wVista_64, wServer2008, wServer2008_64, wSeven, wSeven_64, wServer2008_R2, wServer2008_R2_64, wEight, wEight_64, wServer2012, wServer2012_64, wEightOne, wEightOne_64, wServer2012R2, wServer2012R2_64, wTen, wTen_64, wServer2016, wServer2016_64, wEleven, wEleven_64, wServer2019_64, wServer2022_64, wServer2025_64 );
The recognized Windows versions
- defined even outside OSWINDOWS to access e.g. from monitoring tools
TWinProcessAvailableInfos = set of ( wpaiPID, wpaiBasic, wpaiPEB, wpaiCommandLine, wpaiImagePath);
Which information was returned by GetProcessInfo
() overloaded functions
- wpaiPID is set when PID
was retrieved
- wpaiBasic with ParentPID/BasePriority/ExitStatus/PEBBaseAddress/AffinityMask
- wpaiPEB with SessionID/BeingDebugged
- wpaiCommandLine and wpaiImagePath when CommandLine and ImagePath are set
TWinRegistryRoot = ( wrClasses, wrCurrentUser, wrLocalMachine, wrUsers );
The known Windows Registry Root key used by TWinRegistry.ReadOpen
TWinSystemPrivilege = ( wspCreateToken, wspAssignPrimaryToken, wspLockMemory, wspIncreaseQuota, wspUnsolicitedInput, wspMachineAccount, wspTCP, wspSecurity, wspTakeOwnership, wspLoadDriver, wspSystemProfile, wspSystemTime, wspProfSingleProcess, wspIncBasePriority, wspCreatePageFile, wspCreatePermanent, wspBackup, wspRestore, wspShutdown, wspDebug, wspAudit, wspSystemEnvironment, wspChangeNotify, wspRemoteShutdown, wspUndock, wspSyncAgent, wspEnableDelegation, wspManageVolume, wspImpersonate, wspCreateGlobal, wspTrustedCredmanAccess, wspRelabel, wspIncWorkingSet, wspTimeZone, wspCreateSymbolicLink );
TSynWindowsPrivileges
enumeration synchronized with WinAPI
- see https://docs.microsoft.com/en-us/windows/desktop/secauthz/privilege-constants
TWinSystemPrivileges = set of TWinSystemPrivilege;
TSynWindowsPrivileges
set synchronized with WinAPI
TWinTokenType = ( wttProcess, wttThread );
Define which WinAPI token is to be retrieved
- define the execution context, i.e. if the token is used for the current process or the current thread
- used e.g. by TSynWindowsPrivileges
or mormot.core.os.security
BINARY_CONTENT_TYPE = 'application/octet-stream';
MIME content type used for raw binary data
BINARY_CONTENT_TYPE_HEADER = HEADER_CONTENT_TYPE + BINARY_CONTENT_TYPE;
HTTP
header for MIME content type used for raw binary data
BINARY_CONTENT_TYPE_UPPER = 'APPLICATION/OCTET-STREAM';
MIME content type used for raw binary data, in upper case
BOOL_STR: array[boolean] of string[7] = ( 'false', 'true');
JSON compatible representation of a boolean value, i.e. 'false' and 'true'
- can be used e.g. in logs, or anything accepting a ShortString
COMPILER_VERSION: RawUtf8 = 'Delphi' + ' 6' + ' 7' + ' 8' + ' 2005' + ' 2007' + ' 2006' + ' 2009' + ' 2010' + ' XE' + ' XE2' + ' XE3' + ' XE4' + ' XE5' + ' AppMethod 1' + ' XE6' + ' XE7' + ' XE8' + ' 10 Seattle' + ' 10.1 Berlin' + ' 10.2 Tokyo' + ' 10.3 Rio' + ' 10.4 Sydney' + ' 11' + '.3' + ' Alexandria' + ' 12' + '.3' + ' Athens' + ' 13 Next' + ' 32 bit' ;
Contains the Delphi/FPC Compiler Version as text
- e.g. 'Delphi 10.3 Rio', 'Delphi 2010' or 'Free Pascal 3.3.1'
COMP_TEXT = 'Delphi';
The compiler family used
CONTENT_TYPE_TEXTUAL: array[0..7] of PAnsiChar = ( JSON_CONTENT_TYPE_UPPER, 'TEXT/', 'APPLICATION/XML', 'APPLICATION/JSON', 'APPLICATION/JAVASCRIPT', 'APPLICATION/X-JAVASCRIPT', 'IMAGE/SVG+XML', nil);
A IdemPPChar
() compatible array of textual MIME content types
- as used e.g. by IsHtmlContentTypeTextual
()
CPU_ARCH_TEXT = 'x86' ;
The CPU architecture used for compilation
CRLF = #13#10;
Operating-system dependent Line Feed characters (#13#10 or #10)
ENGLISH_LANGID = $0409;
= HANDLE(-1)
ERROR_ACCESS_DENIED = Windows.ERROR_ACCESS_DENIED;
= ERROR_SUCCESS
ERROR_WINHTTP_TIMEOUT = 12002;
See http
://msdn.microsoft.com/en-us/library/windows/desktop/aa383770
FILES_ALL = '*.*';
Operating-system dependent wildchar to match all files in a folder
fmCreateOrRewrite: array[boolean] of cardinal = ( fmCreateShared, fmOpenWriteShared);
A convenient array constant to open a file for writing without exclusion
fmCreateShared = fmCreate or fmShareReadWrite;
A convenient constant to create a file without exclusion
fmOpenReadShared = fmOpenRead or fmShareReadWrite;
A convenient constant to open a file for reading without exclusion
fmOpenWriteShared = fmOpenReadWrite or fmShareReadWrite;
A convenient constant to open a file for writing without exclusion
fmShareRead = fmShareDenyWrite;
Human-friendly alias to open a file for exclusive writing
fmShareReadWrite = fmShareDenyNone;
Human-friendly alias to open a file with no read/write exclusion
fmShareWrite = fmShareDenyRead;
Human-friendly alias to open a file for exclusive reading
HEADER_BEARER_UPPER = 'AUTHORIZATION: BEARER ';
HTTP
header name for the authorization token, in upper case
- could be used e.g. with IdemPChar
() to retrieve a JWT value
- will detect header computed e.g. by motmot.net.http's AuthorizationBearer
()
HEADER_CONTENT_TYPE = 'Content-Type: ';
HTTP
header name for the content type, as defined in the corresponding RFC
HEADER_CONTENT_TYPE_UPPER = 'CONTENT-TYPE: ';
HTTP
header name for the content type, in upper case
- as defined in the corresponding RFC
- could be used e.g. with IdemPChar
() to retrieve the Content-Type value
HEADER_REMOTEIP_UPPER = 'REMOTEIP: ';
HTTP
header name for the client IP, in upper case
- as defined in our HTTP
server classes
- could be used e.g. with IdemPChar
() to retrieve the remote IP address
HTML_CONTENT_TYPE = 'text/html; charset=UTF-8';
MIME content type used for UTF-8 encoded HTML
HTML_CONTENT_TYPE_HEADER = HEADER_CONTENT_TYPE + HTML_CONTENT_TYPE;
HTTP
header for MIME content type used for UTF-8 encoded HTML
HTTP_ACCEPTED = 202;
HTTP
Status Code for "Accepted"
HTTP_ASYNCRESPONSE = 777;
A fake response code, used by THttpServerRequest.SetAsyncResponse
- for internal THttpAsyncServer
asynchronous process
HTTP_BADGATEWAY = 502;
HTTP
Status Code for "Bad Gateway"
HTTP_BADREQUEST = 400;
HTTP
Status Code for "Bad Request"
HTTP_BANIP_RESPONSE: string[201] = 'HTTP/1.0 418 I''m a teapot'#13#10 + 'Content-Length: 125'#13#10 + 'Content-Type: text/plain'#13#10#13#10 + 'Server refuses to brew coffee because it is currently a teapot.'#13#10 + 'Do not mess with it and retry from this IP in a few seconds.';
HTTP
body following RFC 2324 standard e.g. for banned IP
HTTP_CLIENTERROR = 666;
A fake response code, generated for client side panic failure/exception
- for it is the number of a man
HTTP_CONFLICT = 409;
HTTP
Status Code for "Conflict"
HTTP_CONTINUE = 100;
HTTP
Status Code for "Continue"
HTTP_CREATED = 201;
HTTP
Status Code for "Created"
HTTP_FORBIDDEN = 403;
HTTP
Status Code for "Forbidden"
HTTP_FOUND = 302;
HTTP
Status Code for "Found"
HTTP_GATEWAYTIMEOUT = 504;
HTTP
Status Code for "Gateway Timeout"
HTTP_GET_OK = [HTTP_SUCCESS, HTTP_NOCONTENT, HTTP_PARTIALCONTENT];
The successful HTTP
response codes after a GET request
HTTP_HTTPVERSIONNONSUPPORTED = 505;
HTTP
Status Code for "HTTP
Version Not Supported"
HTTP_MOVEDPERMANENTLY = 301;
HTTP
Status Code for "Moved Permanently"
HTTP_MULTIPLECHOICES = 300;
HTTP
Status Code for "Multiple Choices"
HTTP_NOCONTENT = 204;
HTTP
Status Code for "No Content"
HTTP_NONAUTHORIZEDINFO = 203;
HTTP
Status Code for "Non-Authoritative Information"
HTTP_NONE = 0;
Void HTTP
Status Code (not a standard value, for internal use only)
HTTP_NOTACCEPTABLE = 406;
HTTP
Status Code for "Not Acceptable"
HTTP_NOTALLOWED = 405;
HTTP
Status Code for "Method Not Allowed"
HTTP_NOTFOUND = 404;
HTTP
Status Code for "Not Found"
HTTP_NOTIMPLEMENTED = 501;
HTTP
Status Code for "Not Implemented"
HTTP_NOTMODIFIED = 304;
HTTP
Status Code for "Not Modified"
HTTP_PARTIALCONTENT = 206;
HTTP
Status Code for "Partial Content"
HTTP_PAYLOADTOOLARGE = 413;
HTTP
Status Code for "Payload Too Large"
HTTP_PERMANENTREDIRECT = 308;
HTTP
Status Code for "Permanent Redirect"
HTTP_PROXYAUTHREQUIRED = 407;
HTTP
Status Code for "Proxy Authentication Required"
HTTP_RANGENOTSATISFIABLE = 416;
HTTP
Status Code for "Range Not Satisfiable"
HTTP_RESETCONTENT = 205;
HTTP
Status Code for "Reset Content"
HTTP_SEEOTHER = 303;
HTTP
Status Code for "See Other"
HTTP_SERVERERROR = 500;
HTTP
Status Code for "Internal Server Error"
HTTP_SUCCESS = 200;
HTTP
Status Code for "Success"
HTTP_SWITCHINGPROTOCOLS = 101;
HTTP
Status Code for "Switching Protocols"
HTTP_TEAPOT = 418;
HTTP
Status Code for "I'm a teapot"
HTTP_TEMPORARYREDIRECT = 307;
HTTP
Status Code for "Temporary Redirect"
HTTP_TIMEOUT = 408;
HTTP
Status Code for "Request Time-out"
HTTP_UNAUTHORIZED = 401;
HTTP
Status Code for "Unauthorized"
HTTP_UNAVAILABLE = 503;
HTTP
Status Code for "Service Unavailable"
HTTP_USEPROXY = 305;
HTTP
Status Code for "Use Proxy"
INFINITE = cardinal(-1);
Redefined here to avoid dependency to the Windows or SyncObjs units
InvertedPathDelim = '/';
Operating-system dependent "inverted" delimiter for NormalizeFileName
()
JPEG_CONTENT_TYPE = 'image/jpeg';
MIME content type used for a JPEG picture
JSON_CONTENT_TYPE = 'application/json';
MIME content type used for JSON communication (as used by the Microsoft WCF framework and the YUI framework)
- no 'charset=UTF-8' encoding is necessary, as by specified by RFC 7159
JSON_CONTENT_TYPE_HEADER = HEADER_CONTENT_TYPE + JSON_CONTENT_TYPE;
HTTP
header for MIME content type used for plain JSON
- i.e. 'Content-Type: application/json'
JSON_CONTENT_TYPE_HEADER_UPPER = HEADER_CONTENT_TYPE_UPPER + JSON_CONTENT_TYPE_UPPER;
HTTP
header for MIME content type used for plain JSON, in upper case
- could be used e.g. with IdemPChar
() to retrieve the Content-Type value
JSON_CONTENT_TYPE_UPPER = 'APPLICATION/JSON';
MIME content type used for plain JSON, in upper case
- could be used e.g. with IdemPChar
() to retrieve the Content-Type value
JSON_NAN: array[TFloatNan] of string[11] = ( '0', '"NaN"', '"Infinity"', '"-Infinity"');
The JavaScript-like values of non-number IEEE constants
- as recognized by FloatToShortNan
, and used by TTextWriter.Add
() when serializing such single/double/extended floating-point values
LINE_FEED: array[TLineFeed] of string[3] = (CRLF, #10, #13#10);
Convert a TLineFeed
value into its UTF-8 text
representation
MACOS_NAME: array[8 .. 25] of RawUtf8 = ( '10.4 Tiger', '10.5 Leopard', '10.6 Snow Leopard', '10.7 Lion', '10.8 Mountain Lion', '10.9 Mavericks', '10.10 Yosemite', '10.11 El Capitan', '10.12 Sierra', '10.13 High Sierra', '10.14 Mojave', '10.15 Catalina', '11 Big Sur', '12 Monterey', '13 Ventura', '14 Sonoma', '15 Sequoia', '16 Next');
The recognized MacOS versions, as plain text
- indexed from OSVersion32.utsrelease[2] kernel revision
MilliSecsPerMin = MilliSecsPerSec * SecsPerMin;
1 shl 10 = 1024 = rough approximation of 1000
NORESPONSE_CONTENT_TYPE = '!NORESPONSE';
Used to notify e.g. the THttpServerRequest
not to wait for any response from the client
- is not to be used in normal HTTP
process, but may be used e.g. by TWebSocketProtocolRest.ProcessFrame() to avoid to wait for an incoming response from the other endpoint
OS_INITIAL: array[TOperatingSystem] of AnsiChar = ( '?', 'W', 'L', 'X', 'B', 'P', 'A', 'a', 'D', 'F', 'G', 'K', 'M', 'm', 'n', 'N', 'U', 'S', 's', 'u', 'Y', 'T', 'C', 't', 'R', 'l', 'O', 'G', 'c', 'd', 'x', 'Z', 'r', 'p', 'J' );
Translate one operating system (and distribution) into a single character
- may be used internally e.g. for a HTTP
User-Agent header, as with TFileVersion.UserAgent
and UserAgentParse
()
OS_LINUX = [ osLinux, osArch .. osAndroid];
Unknown Windows Linux OSX BSD POSIX Arch Aurox Debian Fedora Gentoo Knoppix Mint Mandrake Mandriva Novell Ubuntu Slackware Solaris Suse Synology Trustix Clear United RedHat LFS Oracle Mageia CentOS Cloud Xen Amazon CoreOS Alpine Android (J=JVM) the operating systems items which actually have a Linux kernel
OS_NAME: array[TOperatingSystem] of RawUtf8 = ( 'Unknown', 'Windows', 'Linux', 'OSX', 'BSD', 'POSIX', 'Arch', 'Aurox', 'Debian', 'Fedora', 'Gentoo', 'Knoppix', 'Mint', 'Mandrake', 'Mandriva', 'Novell', 'Ubuntu', 'Slackware', 'Solaris', 'Suse', 'Synology', 'Trustix', 'Clear', 'United', 'RedHat', 'LFS', 'Oracle', 'Mageia', 'CentOS', 'Cloud', 'Xen', 'Amazon', 'CoreOS', 'Alpine', 'Android');
Translate one operating system (and distribution) into a its common name
OS_TEXT = 'Win';
The target Operating System used for compilation, as short text
PARSCOMMAND_POSIX = false ;
Let ParseCommandArgs
/ExtractExecutableName
/ExtractCommandArgs
follow the current running OS command-line expectations by default
PARSECOMMAND_BASH = [pcHasRedirection .. pcHasShellVariable];
Identifies some bash-specific processing
PARSECOMMAND_ERROR = [pcUnbalancedSingleQuote .. pcHasEndingBackSlash];
Identifies obvious invalid content
PathCaseInsensitive = true;
Operating-system dependent boolean if paths are case-insensitive
SecsPerDay = SecsPerMin * MinsPerDay;
Missing in oldest Delphi
SecsPerHour = SecsPerMin * MinsPerHour;
Some time conversion constants with Milli/Micro/NanoSec resolution
SecsPerYear = 12 * SecsPerMonth;
Rough approximation of SecsPerDay
* 365.2425 / 12
SERVICESTATE_COLOR: array[TServiceState] of TConsoleColor = ( ccBlue, ccLightRed, ccGreen, ccRed, ccLightGreen, ccGreen, ccBrown, ccWhite, ccMagenta, ccYellow);
Could be used with ConsoleWrite
() to notify a Windows service state
STATICFILE_CONTENT_TYPE = '!STATICFILE';
Internal HTTP
content-type for efficient static file sending
- detected e.g. by http.sys' THttpApiServer.Request or via the NGINX X-Accel-Redirect header's THttpServer.Process (see THttpServer.NginxSendFileFrom) for direct sending with no local bufferring
- the OutCustomHeader should contain the proper 'Content-type: ....' corresponding to the file (e.g. by calling GetMimeContentType
() function)
STATICFILE_CONTENT_TYPE_HEADER = HEADER_CONTENT_TYPE + STATICFILE_CONTENT_TYPE;
Internal HTTP
content-type Header for efficient static file sending
STATICFILE_CONTENT_TYPE_HEADER_UPPPER = HEADER_CONTENT_TYPE_UPPER + STATICFILE_CONTENT_TYPE;
Uppercase
version of HTTP
header for static file content serving
TEXT_CONTENT_TYPE = 'text/plain; charset=UTF-8';
MIME content type used for plain UTF-8 text
TEXT_CONTENT_TYPE_HEADER = HEADER_CONTENT_TYPE + TEXT_CONTENT_TYPE;
HTTP
header for MIME content type used for plain UTF-8 text
UnixDelta = 25569;
Number of days offset between the Unix Epoch (1970) and TDateTime origin
UnixFileTimeDelta = 116444736000000000;
Number of Windows TFileTime
ticks (100ns) from year 1601 to 1970
W32_MAX = 2047;
Windows file APIs have hardcoded MAX_PATH = 260 :(
- but more than 260 chars are possible with the \\?\..... prefix or by disabling the limitation in registry since Windows 10, version 1607 https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
- extended-length path allows up to 32,767 widechars
- but 2047 chars seems big enough in practice e.g. with NTFS - POSIX uses 4096
WINDOWS_32 = [ w2000, wXP, wServer2003, wServer2003_R2, wVista, wServer2008, wSeven, wServer2008_R2, wEight, wServer2012, wEightOne, wServer2012R2, wTen, wServer2016, wEleven];
The recognized Windows versions which are 32-bit
WINDOWS_NAME: array[TWindowsVersion] of RawUtf8 = ( '', '2000', 'XP', 'XP 64bit', 'Server 2003', 'Server 2003 R2', 'Vista', 'Vista 64bit', 'Server 2008', 'Server 2008 64bit', '7', '7 64bit', 'Server 2008 R2', 'Server 2008 R2 64bit', '8', '8 64bit', 'Server 2012', 'Server 2012 64bit', '8.1', '8.1 64bit', 'Server 2012 R2', 'Server 2012 R2 64bit', '10', '10 64bit', 'Server 2016', 'Server 2016 64bit', '11', '11 64bit', 'Server 2019 64bit', 'Server 2022 64bit', 'Server 2025 64bit');
The recognized Windows versions, as plain text
- defined even outside OSWINDOWS to allow process e.g. from monitoring tools
XML_CONTENT_TYPE = 'text/xml';
MIME content type used for UTF-8 encoded XML
XML_CONTENT_TYPE_HEADER = HEADER_CONTENT_TYPE + XML_CONTENT_TYPE;
HTTP
header for MIME content type used for UTF-8 encoded XML
_AW = 'A';
A global constant to be appended for Windows Ansi or Wide API names
- match the Ansi API oldest Delphi, where String=AnsiString
- but won't always match the Ansi API on FPC, because Lazarus forces CP_UTF8
, so you should NOT use this suffix, but the '*W' API everywhere, with proper conversion into RawUtf8
or TFileName/string
Functions or procedures | Description | |
---|---|---|
AllocConsole | Similar to Windows AllocConsole API call, to be truly cross-platform | |
AppendToFile | Create or append a string content to a File | |
ArmCpuImplementer | Recognize a given ARM/AARCH64 CPU implementer from its 8-bit hardware ID | |
ArmCpuImplementerName | Recognize a given ARM/AARCH64 CPU implementer name from its 8-bit hardware ID | |
ArmCpuType | Recognize a given ARM/AARCH64 CPU from its 12-bit hardware ID | |
ArmCpuTypeName | Recognize a given ARM/AARCH64 CPU type name from its 12-bit hardware ID | |
AssignJobToProcess | Associate a process to a Windows Job created by CreateJobToClose() | |
BufferFromFile | Fill a memory buffer from a file content | |
CancelProcess | Try to gently stop a given Windows console app from its ProcessID | |
ChangeRoot | Changes the root directory of the calling process | |
CloseHandle | Finalize a Windows resource (e.g. IOCP instance) | |
CoInit | This global procedure should be called from each thread needing to use OLE | |
ComputeGetSmbios | Some global definitions for proper caching and inlining of GetSmbios() | |
ConsoleKeyPressed | Low-level access to the keyboard state of a given key | |
ConsoleReadBody | Read all available content from stdin | |
ConsoleWaitForEnterKey | Will wait for the ENTER key to be pressed, with all needed waiting process | |
ConsoleWrite | Write some text to the console using a given color | |
ConsoleWriteLn | Append a line feed to the console | |
ConsoleWriteRaw | Write some text to the console using the current color | |
CopyFile | Copy one file to another, similar to the Windows API | |
CoUninit | This global procedure should be called at thread termination | |
CreateJobToClose | Define a Windows Job to close associated processes together | |
CryptDataForCurrentUserDPAPI | Protect some data for the current user, using Windows DPAPI | |
CurrentCpuSet | Retrieve the current CPU cores masks available of the system | |
CurrentStateToServiceState | Convert the Control Code retrieved from Windows into a service state enumeration item | |
CurrentThreadNameShort | Low-level access to the thread name, as set by SetThreadName() | |
DateTimeToFileTime | Convert a TDateTime to a Win32 64-bit FILETIME value | |
DateTimeToWindowsFileTime | Low-level conversion of a TDateTime into a Windows File 32-bit TimeStamp | |
DecodeSmbios | Decode basic SMBIOS information as text from a TRawSmbiosInfo binary blob | |
DelayedProc | Convenient late-binding of any external library function | |
DeleteCriticalSection | Finalize a Critical Section (for Lock/UnLock) | |
DeleteCriticalSectionIfNeeded | On need finalization of a mutex | |
DeleteFile | Redefined here to avoid warning to include "Windows" in uses clause and support FileName longer than MAX_PATH | |
DirectoryDelete | Delete the content of a specified directory | |
DirectoryDeleteOlderFiles | Delete the files older than a given age in a specified directory | |
DirectoryExists | Redefined here to support FileName longer than MAX_PATH | |
DirectorySize | Compute the size of a directory's files, optionally with nested folders | |
DisplayError | Prompt the user for an error message to notify an unexpected issue | |
DisplayFatalError | Prompt the user for an error message to notify an unexpected issue | |
DropPriviledges | Change the current UID/GID to another user, by name | |
EnsureDirectoryExists | Creates a directory if not already existing | |
EnterCriticalSection | Enter a Critical Section (Lock) | |
EnumAllProcesses | Return the PIDs of all running processes | |
EnumProcessName | Return the process name of a given process ID | |
ExpandEnvVars | Expand any embedded environment variables, i.e %windir% | |
ExtractCommandArgs | High-level extraction of all parts of a RunCommand() execution command | |
ExtractExecutableName | High-level extraction of the executable of a RunCommand() execution command | |
ExtractExt | Extract an extension from a file name like ExtractFileExt function | |
ExtractExtP | Extract an extension from a file name like ExtractFileExt function | |
ExtractExtU | Extract an extension from a file name like ExtractFileExt function | |
ExtractName | Extract a name from a file name like ExtractFileName function | |
ExtractNameU | Extract a name from a file name like ExtractFileName function | |
ExtractPath | Extract a path from a file name like ExtractFilePath function | |
ExtractPathU | Extract a path from a RawUtf8 file name like ExtractFilePath function | |
FileAgeToDateTime | Get a file date and time, from its name | |
FileAgeToUnixTimeUtc | Get a file date and time, from its name, as seconds since Unix Epoch | |
FileAgeToWindowsTime | Get the date and time of one file into a Windows File 32-bit TimeStamp | |
FileClose | Redefined here to avoid warning to include "Windows" in uses clause | |
FileCreate | Redefined here to avoid warning to include "Windows" in uses clause | |
FileDateToDateTime | Faster cross-platform alternative to sysutils homonymous function | |
FileExists | Redefined here to support FileName longer than MAX_PATH | |
FileFromBuffer | Create a File from a memory buffer content | |
FileFromString | Create a File from a string content | |
FileInfoByHandle | Get low-level file information, in a cross-platform way | |
FileInfoByName | Get low-level file information, in a cross-platform way | |
FileInfoByName | Get a file size and its UTC Unix timestamp in milliseconds resolution | |
FileIsExecutable | Check if a given file is likely to be an executable | |
FileIsReadable | Try to open the file from its name, as fmOpenReadShared | |
FileIsSymLink | Check if a given file is a symbolic link | |
FileIsWritable | Check if a file exists and can be written | |
FileOpen | Redefined here to call CreateFileW() on non-Unicode RTL and support aFileName longer than MAX_PATH | |
FileOpenSequentialRead | Overloaded function optimized for one pass reading of a (huge) file | |
FileReadAll | A wrapper around FileRead() to ensure a whole memory buffer is retrieved | |
FileSeek64 | FileSeek() overloaded function, working with huge files | |
FileSetDateFrom | Copy the date of one file to another | |
FileSetDateFrom | Copy the date of one file to another | |
FileSetDateFromUnixUtc | Set the file date/time from a supplied UTC TUnixTime value | |
FileSetDateFromWindowsTime | Copy the date of one file from a Windows File 32-bit TimeStamp | |
FileSetHidden | Reduce the visibility of a given file, and set its read/write attributes | |
FileSetSticky | Set the "sticky bit" on a file or directory | |
FileSetTime | Redirection to Windows SetFileTime() of a file name from Int64(TFileTime) | |
FileSize | Get a file size, from its name | |
FileSize | Get a file size, from its handle | |
FileStreamSequentialRead | Returns a TFileStreamFromHandle optimized for one pass file reading | |
FileSymLink | Create a symbolic link named SymLink pointing to the Target file | |
FileTimeToDateTime | Convert a Win32 64-bit FILETIME value into a TDateTime | |
FileTimeToUnixMSTime | Convert a Win32 64-bit FILETIME value into an Unix milliseconds time | |
FileTimeToUnixTime | Convert a Win32 64-bit FILETIME value into an Unix seconds time | |
FileWriteAll | A wrapper around FileWrite() to ensure a whole memory buffer is retrieved | |
FillSystemRandom | Low-level function returning some random binary from the Operating System | |
FlushFileBuffers | Compatibility function, wrapping Win32 API file flush to disk | |
FreeEnvironmentStringsW | Redefined in mormot.core.os to avoid dependency to the Windows unit | |
GetComputerUuid | Retrieve a genuine 128-bit UUID identifier for this computer | |
GetComputerUuid | Retrieve a genuine 128-bit UUID identifier for this computer | |
GetCurrentProcess | Retrieves the current process ID | |
GetCurrentProcessId | Retrieves the current process ID | |
GetCurrentThreadId | Retrieves the current thread ID | |
GetCurrentThreadInfo | Returns the thread id and the thread name as a ShortString | |
GetCurrentThreadName | Retrieve the thread name, as set by SetThreadName() | |
GetDelphiCompilerVersion | Deprecated function: use COMPILER_VERSION constant instead | |
GetDesktopWindow | Compatibility function, wrapping Win32 API function | |
GetDiskAvailable | Retrieve how many bytes are currently available on a given folder | |
GetDiskInfo | Retrieve low-level information about a given disk partition | |
GetDiskPartitions | Retrieve low-level information about all mounted disk partitions of the system | |
GetEnvironmentStringsW | Redefined in mormot.core.os to avoid dependency to the Windows unit | |
GetErrorText | Returns a given error code as plain text | |
GetExecutableName | Try to retrieve the file name of the executable/library holding a function | |
GetExecutableVersion | Initialize Executable global variable, from the program version resources | |
GetFileNameFromUrl | Ask the Operating System to convert a file URL to a local file path | |
GetFileNameWithoutExt | Compute the file name, including its path if supplied, but without its extension | |
GetFileNameWithoutExtOrPath | Extract the file name without any path nor extension, as UTF-8 | |
GetLastDelimU | Defined here for proper ExtractExtP() inlining | |
GetLastError | Compatibility function, wrapping Win32 API last error code | |
GetLocalTime | Returns the current Local time as TSystemTime from the OS | |
GetMemoryInfo | Retrieve low-level information about current memory usage | |
GetMemoryInfoText | Retrieve some human-readable text from GetMemoryInfo | |
GetModuleHandle | Retrieves the current executable module handle, i.e. its memory load address | |
GetOneSystemStoreAsPem | Retrieve all certificates of a given system store as PEM text | |
GetParentProcess | Return the process ID of the parent of a given PID | |
GetProcessInfo | Retrieve low-level process information, from the Windows API | |
GetProcessInfo | Retrieve low-level process(es) information, from the Windows API | |
GetRawSmbios | Retrieve the SMBIOS raw information as a single RawSmbios gloabl binary blob | |
GetServicePid | Return the ProcessID of a given service, by name | |
GetSmbios | Retrieve SMBIOS information as text | |
GetSystemInfoText | Retrieve some human-readable text about the current system in several lines | |
GetSystemPath | Returns an operating system folder | |
GetSystemStoreAsPem | Retrieve the OS certificates store as PEM text | |
GetSystemTime | Returns the current UTC time as TSystemTime from the OS | |
GetUptimeSec | Returns how many seconds the system was up, accouting for time when the computer is asleep | |
GlobalLock | Enter a process-wide giant lock for thread-safe shared process | |
GlobalUnLock | Release the giant lock for thread-safe shared process | |
HandleCtrlC | Install a Windows event handler for Ctrl+C pressed on the Console | |
HasConsole | Always true on POSIX, may be false for a plain Windows GUI application | |
InitializeCriticalSection | Initialize a Critical Section (for Lock/UnLock) | |
InitializeCriticalSectionIfNeededAndEnter | On need initialization of a mutex, then enter the lock | |
IocpCreate | Initialize Windows IOCP instance | |
IocpGetQueuedStatus | Retrieve Windows IOCP instance status | |
IocpPostQueuedStatus | Trigger a Windows IOCP instance | |
IsDebuggerPresent | Check if this process is currently running into the debugger | |
IsDirectoryWritable | Check if the directory is writable for the current user | |
IsInitializedCriticalSection | Returns TRUE if the supplied mutex has been initialized | |
IsInvalidHttpHeader | Check the supplied HTTP header to not contain more than one EOL | |
IsSharedViolation | Check if the last error reporting by the system is a file access violation | |
IsSystemFolder | Rough detection of 'c:\windows' and 'c:\program files' folders | |
IsUacVirtualFolder | Check if a folder may be affected by UAC folder virtualization | |
IsUacVirtualizationEnabled | Check if UAC folder/registry virtualization is enabled for this process | |
KillProcess | Forcibly terminate a Windows process from its ProcessID | |
LeaveCriticalSection | Leave a Critical Section (UnLock) | |
LibraryClose | Raw cross-platform library unloading function | |
LibraryError | Raw cross-platform library resolution error, e.g. after LibraryOpen | |
LibraryOpen | Raw cross-platform library loading function | |
LibraryResolve | Raw cross-platform library resolution function, as defined in FPC RTL | |
MatchOS | Check if the current OS (i.e. OS_KIND value) match a description | |
NewSynLocker | Initialize a TSynLocker instance from heap | |
NormalizeDirectoryExists | Just a wrapper around EnsureDirectoryExists(NormalizeFileName(Directory)) | |
NormalizeFileName | Ensure all \ / path delimiters are normalized into the current OS expectation | |
NormalizeFileNameU | Ensure all \ / path delimiters are normalized into the current OS expectation | |
NowUtc | Returns the current UTC time | |
ObjArrayAdd | Wrapper to implement a thread-safe T*ObjArray dynamic array storage | |
ParseCommandArgs | Low-level parsing of a RunCommand() execution command | |
PatchCode | Self-modifying code - change some memory buffer in the code segment | |
PatchCodePtrUInt | Self-modifying code - change one PtrUInt in the code segment | |
PostMessage | Post a message to the Windows message queue | |
PtrArrayDelete | Wrapper to implement a thread-safe pointer dynamic array storage | |
QueryPerformanceMicroSeconds | Returns a high-resolution system-wide monotonic timestamp as microseconds | |
QuitProcess | Try to gently quit a Windows process from its ProcessID | |
QuoteFileName | Add some " before and after if FileName has some space within | |
RaiseLastError | Raise an EOSException from the last system error using WinErrorText() | |
RaiseLastModuleError | Raise an Exception from the last module error using WinErrorText() | |
RawExceptionIntercept | Setup Exception interception for the whole process | |
RawKillThread | Try to kill/cancel a thread | |
RawSetThreadName | Low-level naming of a thread | |
RawTokenGetInfo | Low-level retrieveal of raw binary information for a given token | |
RawTokenOpen | Calls OpenProcessToken() or OpenThreadToken() to get the current token | |
ReadRegString | Quickly retrieve a Text value from Registry | |
ReadSystemMemory | Fill a buffer with a copy of some low-level system memory | |
RedirectCode | Low-level i386/x86_64 asm routine patch and redirection | |
RegisterGlobalShutdownRelease | Framework will register here some instances to be released eventually | |
RenameFile | Redefined here to avoid warning to include "Windows" in uses clause and support FileName longer than MAX_PATH | |
ReserveExecutableMemory | Cross-platform reserve some executable memory | |
ReserveExecutableMemoryPageAccess | To be called after ReserveExecutableMemory() when you want to actually write the memory blocks | |
ResetCpuSet | Fill a bitmask of CPU cores with zeros | |
RetrieveLoadAvg | Return the system-wide time usage information | |
RetrieveProcessInfo | Return the time and memory usage information about a given process | |
RetrieveSystemTimes | Return the system-wide time usage information | |
RtlCaptureStackBackTrace | Retrieves the current stack trace | |
RunCommand | Like fpSystem, but cross-platform | |
RunCommandWin | Windows-specific RunCommand() function returning raw TProcessInformation | |
RunProcess | Like SysUtils.ExecuteProcess, but allowing not to wait for the process to finish | |
RunRedirect | Execute a command, returning its output console as UTF-8 text | |
SafeFileName | Check for unsafe '..' '/xxx' 'c:xxx' '~/xxx' or '\\' patterns in a filename | |
SafeFileNameU | Check for unsafe '..' '/xxx' 'c:xxx' '~/xxx' or '\\' patterns in a RawUtf8 filename | |
SafePathName | Check for unsafe '..' '/xxx' 'c:xxx' '~/xxx' or '\\' patterns in a path | |
SafePathNameU | Check for unsafe '..' '/xxx' 'c:xxx' '~/xxx' or '\\' patterns in a RawUtf8 path | |
SearchRecToDateTime | Get a file date and time, from a FindFirst/FindNext search | |
SearchRecToDateTimeUtc | Get a file UTC date and time, from a FindFirst/FindNext search | |
SearchRecToUnixTimeUtc | Get a file UTC date and time, from a FindFirst/FindNext search, as Unix time | |
SearchRecToWindowsTime | Get a file date and time, from a FindFirst/FindNext search, as Windows time | |
SearchRecValidFile | Check if a FindFirst/FindNext found instance is actually a file | |
SearchRecValidFolder | Check if a FindFirst/FindNext found instance is actually a folder | |
SeemsRealPointer | Check if the supplied pointer is actually pointing to some memory page | |
ServiceSingleRun | Launch the registered Service execution | |
SetCpuSet | Set a particular bit in a mask of CPU cores | |
SetCurrentThreadName | Name the current thread so that it would be easily identified in the IDE debugger | |
SetCurrentThreadName | Name the current thread so that it would be easily identified in the IDE debugger | |
SetEndOfFile | Compatibility function, wrapping Win32 API file truncate at current position | |
SetExecutableVersion | Initialize Executable global variable, supplying the version as text | |
SetExecutableVersion | Initialize Executable global variable with custom version numbers | |
SetLastError | Compatibility function, wrapping Win32 API last error code | |
SetSystemPath | Force an operating system folder | |
SetSystemTime | Set the current system time as UTC timestamp | |
SetSystemTimeZone | Allow to change the current system time zone on Windows | |
SetThreadCpuAffinity | Try to assign a given thread to a specific logical CPU core | |
SetThreadMaskAffinity | Try to assign a given thread to a specific set of logical CPU core(s) | |
SetThreadSocketAffinity | Try to assign a given thread to a specific hardware CPU socket | |
SleepDelay | Compute optimal sleep time as 0/1/5/50 then 120-250 ms steps | |
SleepHiRes | Similar to Windows sleep() API call, to be truly cross-platform | |
SleepHiRes | Similar to Windows sleep() API call, but truly cross-platform and checking the Terminated flag during its wait for quick abort response | |
SleepStep | Call SleepHiRes() taking count of the activity, in 0/1/5/50/120-250 ms steps | |
SleepStepTime | Compute optimal sleep time as SleepStep, in 0/1/5/50/120-250 ms steps | |
SortDynArrayFileName | Compare two "array of TFileName" elements, grouped by file extension | |
SpinExc | Try LockedExc() in a loop, calling SwitchToThread after some spinning | |
StatusCodeIsSuccess | Returns true for successful HTTP status codes, i.e. in 200..399 range | |
StatusCodeToReason | Retrieve the HTTP reason text from its integer code | |
StatusCodeToShort | Convert any HTTP_* constant to an integer status code and its English text | |
StatusCodeToText | Retrieve the HTTP reason text from its integer code as PRawUtf8 | |
StreamCopyUntilEnd | Copy all Source content into Dest from current position | |
StringFromFile | Read a File content into a string | |
StringFromFiles | Read all Files content from a list of file names | |
StringFromFirstFile | Read a File content from a list of potential files | |
StringFromFolders | Read all Files content from a list of folders names | |
SwitchToThread | Similar to Windows SwitchToThread API call, to be truly cross-platform | |
TemporaryFileName | Compute an unique temporary file name | |
TextBackground | Change the console text background color | |
TextColor | Change the console text writing color | |
ToMethod | Convert a string HTTP verb into its TUriMethod enumerate | |
ToText | Convert an Operating System type into its text representation | |
ToText | Convert a TUriMethod enumerate to its #0 terminated uppercase text | |
ToText | Return the ready to be displayed text of a TServiceState value | |
ToTextOS | Convert a 32-bit Operating System type into its full text representation | |
ToTextShort | Convert an Operating System type into its one-word text representation | |
TryEnterCriticalSection | Try to enter a Critical Section (Lock) | |
UnAmp | Detect any & character, and extract it as part of the result array | |
Unicode_AnsiToWide | Compatibility function, wrapping MultiByteToWideChar() Win32 API call | |
Unicode_CodePage | Returns the curent system code page for AnsiString types | |
Unicode_CompareString | Compatibility function, wrapping CompareStringW() Win32 API text comparison | |
Unicode_FromUtf8 | Local RTL wrapper function to avoid linking mormot.core.unicode.pas | |
Unicode_InPlaceLower | Compatibility function, wrapping Win32 API CharLowerBuffW() | |
Unicode_InPlaceUpper | Compatibility function, wrapping Win32 API CharUpperBuffW() | |
Unicode_WideToAnsi | Compatibility function, wrapping WideCharToMultiByte() Win32 API call | |
Unicode_WideToShort | Conversion of some UTF-16 buffer into a temporary Ansi ShortString | |
UnixMSTimeToFileTime | Convert an Unix milliseconds time to a Win32 64-bit FILETIME value | |
UnixMSTimeUtc | Returns the current UTC date/time as a millisecond-based c-encoded time | |
UnixMSTimeUtcFast | Returns the current UTC date/time as a millisecond-based c-encoded time | |
UnixTimeToFileTime | Convert an Unix seconds time to a Win32 64-bit FILETIME value | |
UnixTimeToLocalTime | A wrapper calling SystemTimeToTzSpecificLocalTime Windows API | |
UnixTimeUtc | Returns the current UTC date/time as a second-based c-encoded time | |
UserAgentParse | Quickly parse the TFileVersion.UserAgent content | |
Utf8ToConsole | Direct conversion of a UTF-8 encoded string into a console OEM-encoded string | |
Utf8ToWin32PWideChar | Local RTL wrapper function to avoid linking mormot.core.unicode.pas | |
ValidHandle | Cross-platform check if the supplied THandle is not invalid | |
W32 | Efficiently return a PWideChar from a TFileName on all compilers | |
WaitForSingleObject | Redefined in mormot.core.os to avoid dependency to the Windows unit | |
Win32PWideCharToUtf8 | Local RTL wrapper function to avoid linking mormot.core.unicode.pas | |
Win32PWideCharToUtf8 | Local RTL wrapper function to avoid linking mormot.core.unicode.pas | |
WinCheck | Call RaiseLastError(Code) if Code <> NO_ERROR = ERROR_SUCCESS | |
WindowsFileTime64ToUnixMSTime | Convert a Windows API File 64-bit TimeStamp into a regular TUnixMSTime | |
WindowsFileTimeToDateTime | Convert a Windows API File 32-bit TimeStamp into a regular TDateTime | |
WinErrorConstant | Return the best known ERROR_* system error message constant texts | |
WinErrorText | Return the error message of a given Module | |
WinGetEnumName | Minimal GetEnumName() for Delphi + FPC on base enum type with no Min/Max | |
WinLastError | Return a RaiseLastError-like error message using WinErrorText() | |
XorOSEntropy | Call several Operating System APIs to gather 512-bit of entropy information | |
_oskb | Internal function to avoid linking mormot.core.buffers.pas |
procedure AllocConsole;
Similar to Windows AllocConsole
API call, to be truly cross-platform
- do nothing on Linux/POSIX, but set StdOut
propertly from StdOutputHandle
- on Windows, will call the corresponding API, and set StdOut
global variable
function AppendToFile(const Content: RawUtf8; const FileName: TFileName; BackupOverMaxSize: Int64 = 0): boolean;
Create or append
a string content to a File
- can optionally rotate the file to a FileName+'.bak' over a specific size
function ArmCpuImplementer(id: byte): TArmCpuImplementer;
Recognize a given ARM/AARCH64 CPU implementer from its 8-bit hardware ID
function ArmCpuImplementerName(aci: TArmCpuImplementer; id: word): RawUtf8;
Recognize a given ARM/AARCH64 CPU implementer name from its 8-bit hardware ID
function ArmCpuType(id: word): TArmCpuType;
Recognize a given ARM/AARCH64 CPU from its 12-bit hardware ID
function ArmCpuTypeName(act: TArmCpuType; id: word): RawUtf8;
Recognize a given ARM/AARCH64 CPU type name from its 12-bit hardware ID
function AssignJobToProcess(job, process: THandle; const ctxt: ShortString): boolean;
Associate a process to a Windows Job created by CreateJobToClose
()
function BufferFromFile(const FileName: TFileName; Buf: pointer; Len: PtrInt): boolean;
Fill a memory buffer from a file content
function CancelProcess(pid: cardinal; waitseconds: integer): boolean;
Try to gently stop a given Windows console app from its ProcessID
- will send a Ctrl-C event (acquiring the process console)
function ChangeRoot(const FolderName: RawUtf8): boolean;
Changes the root directory of the calling process
- only implemented on POSIX by now
function CloseHandle(hObject: THandle): BOOL; stdcall;
Finalize a Windows resource (e.g. IOCP instance)
- redefined in mormot.core.os to avoid dependency to the Windows unit
procedure CoInit;
This global procedure should be called from each thread needing to use OLE
- it is called e.g. by TOleDBConnection.Create when an OleDb connection is instantiated for a new thread
- every call of CoInit
shall be followed by a call to CoUninit
- implementation will maintain some global counting, to call the CoInitialize API only once per thread
- only made public for user convenience, e.g. when using custom COM objects
procedure ComputeGetSmbios;
Some global definitions for proper caching and inlining of GetSmbios
()
function ConsoleKeyPressed(ExpectedKey: Word): boolean;
Low-level access to the keyboard state of a given key
function ConsoleReadBody: RawByteString;
Read all available content from stdin
- could be used to retrieve some file piped to the command line
- the content is not converted, so will follow the encoding used for storage
procedure ConsoleWaitForEnterKey;
Will wait for the ENTER key to be pressed, with all needed waiting process
- on the main thread, will call Synchronize() for proper work e.g. with interface-based service implemented as optExecInMainThread
- on Windows, from a non-main Thread, respond to PostThreadMessage(WM_QUIT)
- on Windows, also properly respond to Ctrl-C or closing console events
- on POSIX, will call SynDaemonIntercept first, so that Ctrl-C or SIG_QUIT will also be intercepted and let this procedure return
procedure ConsoleWrite(const Text: RawUtf8; Color: TConsoleColor = ccLightGray; NoLineFeed: boolean = false; NoColor: boolean = false); overload;
Write some text
to the console using a given color
- this method is protected by its own CriticalSection for output consistency
procedure ConsoleWriteLn;
Append
a line feed to the console
- similar to writeln but redirect to ConsoleWrite
() with proper thread safety
procedure ConsoleWriteRaw(const Text: RawUtf8; NoLineFeed: boolean = false); overload;
Write some text
to the console using the current color
- similar to writeln() but redirect to ConsoleWrite
(NoColor=true)
function CopyFile(const Source, Target: TFileName; FailIfExists: boolean): boolean;
Copy one file to another, similar to the Windows API
procedure CoUninit;
This global procedure should be called at thread termination
- it is called e.g. by TOleDBConnection.Destroy, when thread associated to an OleDb connection is terminated
- every call of CoInit
shall be followed by a call to CoUninit
- only made public for user convenience, e.g. when using custom COM objects
function CreateJobToClose(parentpid: cardinal): THandle;
Define a Windows Job to close associated processes together
- warning: main process should include the CREATE_BREAKAWAY_FROM_JOB flag
- you should later call CloseHandle
() on the returned handle, if not 0
function CryptDataForCurrentUserDPAPI(const Data, AppSecret: RawByteString; Encrypt: boolean): RawByteString;
Protect some data for the current user, using Windows DPAPI
- the application can specify a secret salt text
, which should reflect the current execution context, to ensure nobody could decrypt
the data without knowing this application-specific AppSecret value
- will use CryptProtectData DPAPI function call under Windows
- see https://msdn.microsoft.com/en-us/library/ms995355
- this function is Windows-only, could be slow, and you don't know which algorithm is really used on your system, so using our mormot.crypt.core.pas CryptDataForCurrentUser
() is probably a safer (and cross-platform) alternative
- also note that DPAPI has been closely reverse
engineered - see e.g. https://www.passcape.com/index.php?section=docsys&cmd=details&id=28
function CurrentCpuSet(out CpuSet: TCpuSet): integer;
Retrieve the current CPU cores masks available of the system
- the current process may have been tuned to use only a sub-set of the cores e.g. via "taskset -c" on Linux
- return the number of accessible CPU cores - i.e. GetBitsCount
(CpuSet) or 0 if the function failed
function CurrentStateToServiceState(CurrentState: cardinal): TServiceState;
Convert the Control Code retrieved from Windows into a service state enumeration item
function CurrentThreadNameShort: PShortString;
Low-level access to the thread name, as set by SetThreadName
()
- since threadvar can't contain managed strings, it is defined as TShort31
, so is limited to 31 chars, which is enough since POSIX truncates to 16 chars and SetThreadName
does trim
meaningless patterns
procedure DateTimeToFileTime(dt: TDateTime; out FT: TFileTime);
Convert a TDateTime to a Win32 64-bit FILETIME value
function DateTimeToWindowsFileTime(DateTime: TDateTime): integer;
Low-level conversion of a TDateTime into a Windows File 32-bit TimeStamp
- returns 0 if the conversion failed
function DecodeSmbios(var raw: TRawSmbiosInfo; out info: TSmbiosBasicInfos): PtrInt;
Decode basic SMBIOS
information as text
from a TRawSmbiosInfo
binary blob
- see DecodeSmbiosInfo
() in mormot.core.perf.pas for a more complete decoder
- returns the total size of DMI/SMBIOS
information in raw.data (may be lower)
- will also adjust raw.Length and truncate raw.Data to the actual useful size
function DelayedProc(var api; var lib: THandle; libname: PChar; procname: PAnsiChar): boolean;
Convenient late-binding of any external library function
- just wrapper around LoadLibray + GetProcAddress once over a pointer
procedure DeleteCriticalSection(var cs : TRTLCriticalSection); stdcall;
Finalize a Critical Section (for Lock/UnLock)
- redefined in mormot.core.os to avoid dependency to the Windows unit
- under Delphi/Windows, directly call the homonymous Win32 API
procedure DeleteCriticalSectionIfNeeded(var cs: TRTLCriticalSection);
On need finalization of a mutex
- if the supplied mutex has been initialized, delete it
- if the supplied mutex is void (i.e. all filled with 0), do nothing
function DeleteFile(const aFileName: TFileName): boolean;
Redefined here to avoid warning to include "Windows" in uses clause and support FileName longer than MAX_PATH
- why did Delphi define this slow RTL function as inlined in SysUtils.pas?
function DirectoryDelete(const Directory: TFileName; const Mask: TFileName = FILES_ALL; DeleteOnlyFilesNotDirectory: boolean = false; DeletedCount: PInteger = nil): boolean;
Delete the content of a specified directory
- only one level of file is deleted within the folder: no recursive deletion is processed by this function (for safety)
- if DeleteOnlyFilesNotDirectory is TRUE, it won't remove the folder itself, but just the files found in it
- warning: DeletedCount^ should be a 32-bit "integer" variable, not a PtrInt
function DirectoryDeleteOlderFiles(const Directory: TFileName; TimePeriod: TDateTime; const Mask: TFileName = FILES_ALL; Recursive: boolean = false; TotalSize: PInt64 = nil): boolean;
Delete the files older than a given age in a specified directory
- for instance, to delete all files older than one day:
DirectoryDeleteOlderFiles(FolderName, 1);
- only one level of file is deleted within the folder: no recursive deletion is processed by this function, unless Recursive is TRUE
- if Recursive=true, caller should set TotalSize^=0 to have an accurate value
- return false if any deprecated DeleteFile
() did fail during the process
function DirectoryExists(const FileName: TFileName; FollowLink: boolean = true): boolean;
Redefined here to support FileName longer than MAX_PATH
function DirectorySize(const FileName: TFileName; Recursive: boolean = false; const Mask: TFileName = FILES_ALL): Int64;
Compute the size of a directory's files, optionally with nested folders
- basic implementation using FindFirst/FindNext so won't be the fastest available, nor fully accurate when files are actually (hard) links
procedure DisplayError(const fmt: string; const args: array of const);
Prompt the user for an error message to notify an unexpected issue
- redirect to DisplayFatalError
() without any title
- expects the regular Format() layout with %s %d - not the FormatUtf8
() %
procedure DisplayFatalError(const title, msg: RawUtf8);
Prompt the user for an error message to notify an unexpected issue
- in practice, text
encoding is better to be plain 7-bit ASCII
- on Windows, will allocate a console if needed and write to STD_ERROR_HANDLE
- on POSIX, will send the output to StdErrorHandle (=2)
function DropPriviledges(const UserName: RawUtf8 = 'nobody'): boolean;
Change the current UID/GID to another user, by name
- only implemented on POSIX by now
function EnsureDirectoryExists(const Directory: TFileName; RaiseExceptionOnCreationFailure: ExceptionClass = nil): TFileName; overload;
Creates a directory if not already existing
- returns the full expanded directory name, including trailing path delimiter
- returns '' on error, unless RaiseExceptionOnCreationFailure is set
procedure EnterCriticalSection(var cs: TRTLCriticalSection); stdcall;
Enter a Critical Section (Lock)
- redefined in mormot.core.os to avoid dependency to the Windows unit
- under Delphi/Windows, directly call the homonymous Win32 API
function EnumAllProcesses: TCardinalDynArray;
Return the PIDs of all running processes
- under Windows, is a wrapper around EnumProcesses() PsAPI call
- on Linux, will enumerate /proc/* pseudo-files
function EnumProcessName(PID: cardinal): RawUtf8;
Return the process name of a given process ID
- under Windows, is a wrapper around QueryFullProcessImageNameW/GetModuleFileNameEx PsAPI call
- on Linux, will query /proc/[pid
]/exe or /proc/[pid
]/cmdline pseudo-file
function ExpandEnvVars(const aStr: string): string;
Expand any embedded environment variables, i.e %windir%
function ExtractCommandArgs(const cmd: RawUtf8; out param: TRawUtf8DynArray; posix: boolean = PARSCOMMAND_POSIX): TParseCommands;
High-level extraction of all parts of a RunCommand
() execution command
- output param[0] is the executable
name, and other param[] are the actual command line arguments, just like the ParamStr() RTL function
- param is left nil on error, with result * PARSECOMMAND_ERROR
<> []
function ExtractExecutableName(const cmd: RawUtf8; posix: boolean = PARSCOMMAND_POSIX): RawUtf8;
High-level extraction of the executable
of a RunCommand
() execution command
- returns the first parameter returned by ParseCommandArgs
()
function ExtractExt(const FileName: TFileName; WithoutDot: boolean = false): TFileName;
Extract an extension from a file name like ExtractFileExt function
- but cross-platform, i.e. detect both '\' and '/' on all platforms
function ExtractExtP(const FileName: RawUtf8; WithoutDot: boolean = false): PUtf8Char;
Extract an extension from a file name like ExtractFileExt function
- but cross-platform, i.e. detect both '\' and '/' on all platforms
function ExtractExtU(const FileName: RawUtf8; WithoutDot: boolean = false): RawUtf8;
Extract an extension from a file name like ExtractFileExt function
- but cross-platform, i.e. detect both '\' and '/' on all platforms
function ExtractName(const FileName: TFileName): TFileName;
Extract a name from a file name like ExtractFileName function
- but cross-platform, i.e. detect both '\' and '/' on all platforms
function ExtractNameU(const FileName: RawUtf8): RawUtf8;
Extract a name from a file name like ExtractFileName function
- but cross-platform, i.e. detect both '\' and '/' on all platforms
function ExtractPath(const FileName: TFileName): TFileName;
Extract a path from a file name like ExtractFilePath function
- but cross-platform, i.e. detect both '\' and '/' on all platforms
function ExtractPathU(const FileName: RawUtf8): RawUtf8;
Extract a path from a RawUtf8
file name like ExtractFilePath function
- but cross-platform, i.e. detect both '\' and '/' on all platforms
function FileAgeToDateTime(const FileName: TFileName): TDateTime;
Get a file date and time, from its name
- returns 0 if file doesn't exist
- returns the local file age, encoded as TDateTime
- under Windows, will use GetFileAttributesEx fast API
function FileAgeToUnixTimeUtc(const FileName: TFileName; AllowDir: boolean = false): TUnixTime;
Get a file date and time, from its name, as seconds since Unix Epoch
- returns 0 if file (or folder if AllowDir is true) doesn't exist
- returns the system API file age (not converted local), encoded as TUnixTime
- under Windows, will use GetFileAttributesEx and FileTimeToUnixTime
- under POSIX, will call directly the stat syscall
- faster than FileAgeToDateTime
() since don't convert to local time
function FileAgeToWindowsTime(F: THandle): integer;
Get the date and time of one file into a Windows File 32-bit TimeStamp
- this cross-system function is used e.g. by mormot.core.zip which expects Windows TimeStamps in its headers
procedure FileClose(F: THandle); stdcall;
Redefined here to avoid warning to include "Windows" in uses clause
- why did Delphi define this slow RTL function as inlined in SysUtils.pas?
function FileCreate(const aFileName: TFileName; aMode: integer = 0; aRights: integer = 0): THandle;
Redefined here to avoid warning to include "Windows" in uses clause
- why did Delphi define this slow RTL function as inlined in SysUtils.pas?
- also supports aFileName longer than MAX_PATH
- on Windows, aRights parameter is just ignored, and on POSIX aRights = 0 will set the default octal 644 file access attributes (-rw-r-r--)
- warning: this function replaces ALL SysUtils.FileCreate() overloads, putting aMode as the SECOND parameter, just like with FileOpen
()
function FileDateToDateTime(const FileDate: TFileAge): TDateTime;
Faster cross-platform alternative to sysutils homonymous function
- on Windows, just redirect to WindowsFileTimeToDateTime
() since FileDate is already expected to be in local time from FileAge()
- on POSIX, FileDate is a 64-bit UTC value as returned from OS stat API, and will be converted into a local TDateTime
- note: FPC FileAge(TDateTime) is wrong and truncates 1-2 seconds on Windows
function FileExists(const FileName: TFileName; FollowLink: boolean = true; CheckAsDir: boolean = false): boolean;
Redefined here to support FileName longer than MAX_PATH
- as our FileOpen
/FileCreate
redefinitions
- CheckAsDir = true is used by DirectoryExists
()
function FileFromBuffer(Buf: pointer; Len: PtrInt; const FileName: TFileName; FlushOnDisk: boolean = false): boolean;
Create a File from a memory buffer content
function FileFromString(const Content: RawByteString; const FileName: TFileName; FlushOnDisk: boolean = false): boolean;
Create a File from a string content
- uses RawByteString
for byte storage, whatever the codepage is
- can optionaly force flush all write buffers to disk
function FileInfoByHandle(aFileHandle: THandle; FileId, FileSize: PInt64; LastWriteAccess, FileCreateDateTime: PUnixMSTime): boolean;
Get low-level file information, in a cross-platform way
- returns true on success
- you can specify nil for any returned value if you don't need
- here file write/creation time are given as TUnixMSTime
values, for better cross-platform process - note that FileCreateDateTime may not be supported by most Linux file systems, so the oldest timestamp available is returned as failover on such systems (probably the latest file metadata writing)
function FileInfoByName(const FileName: TFileName; out FileSize: Int64; out FileTimestampUtc: TUnixMSTime): boolean; overload;
Get a file size and its UTC Unix timestamp in milliseconds resolution
- return false if FileName was not found
- return true and set FileSize
and FileTimestampUtc if found - note that no local time conversion is done, so timestamp won't match FileAge()
- if FileName is a folder/directory, then returned FileSize
equals -1
- use a single Operating System call, so is faster than FileSize
+ FileAge
function FileInfoByName(const FileName: TFileName; FileId, FileSize: PInt64; LastWriteAccess, FileCreateDateTime: PUnixMSTime): boolean; overload;
Get low-level file information, in a cross-platform way
- is a wrapper around FileInfoByHandle
() function
- returns true on success
function FileIsExecutable(const FileName: TFileName): boolean;
Check if a given file is likely to be an executable
- will check the DOS/WinPE executable
header in its first bytes on Windows
- will call fpStat() on POSIX to check the File and Executable
bits
function FileIsReadable(const aFileName: TFileName): boolean;
Try to open the file from its name, as fmOpenReadShared
- on Windows, calls CreateFileW(aFileName,GENERIC_READ) then CloseHandle
- on POSIX, calls fpOpen(pointer(aFileName),O_RDONLY) with no fpFlock() call
function FileIsSymLink(const FileName: TFileName): boolean;
Check if a given file is a symbolic link
function FileIsWritable(const FileName: TFileName): boolean;
Check if a file exists and can be written
- on POSIX, call fpaccess() and check for the W_OK attribute
- on Windows, check faReadOnly and supports aFileName longer than MAX_PATH
function FileOpen(const aFileName: TFileName; aMode: integer): THandle;
Redefined here to call CreateFileW() on non-Unicode RTL and support aFileName longer than MAX_PATH
function FileOpenSequentialRead(const FileName: TFileName): integer;
Overloaded function optimized for one pass reading of a (huge) file
- will use e.g. the FILE_FLAG_SEQUENTIAL_SCAN flag under Windows, as stated by http
://blogs.msdn.com/b/oldnewthing/archive/2012/01/20/10258690.aspx
- on POSIX, calls fpOpen(pointer(FileName),O_RDONLY) with no fpFlock() call
- is used e.g. by StringFromFile
() or HashFile
() functions
- note: you could better use FileReadAll
() to retrieve a whole data buffer
function FileReadAll(F: THandle; Buffer: pointer; Size: PtrInt): boolean;
A wrapper around FileRead() to ensure a whole memory buffer is retrieved
- expects Size to be up to 2GB (seems like a big enough memory buffer)
- on Windows, will read by 16MB chunks to avoid ERROR_NO_SYSTEM_RESOURCES
- will call FileRead() and retry up to Size bytes are filled in the buffer
- return true if all memory buffer has been read, or false on error
function FileSeek64(Handle: THandle; const Offset: Int64; Origin: cardinal = soFromBeginning): Int64;
FileSeek() overloaded function, working with huge files
- Delphi FileSeek() is buggy -> use this function to safely access files bigger than 2 GB (thanks to sanyin for the report)
function FileSetDateFrom(const Dest, Source: TFileName): boolean; overload;
Copy the date of one file to another
- FileSetDate(THandle, Age) is not implemented on POSIX: filename is needed
function FileSetDateFrom(const Dest: TFileName; SourceHandle: THandle): boolean; overload;
Copy the date of one file to another
- FileSetDate(THandle, Age) is not implemented on POSIX: filename is needed
function FileSetDateFromUnixUtc(const Dest: TFileName; Time: TUnixTime): boolean;
Set the file date/time from a supplied UTC TUnixTime
value
- avoid any temporary conversion to local time
- Time may come from FileAgeToUnixTimeUtc
()
function FileSetDateFromWindowsTime(const Dest: TFileName; WinTime: integer): boolean;
Copy the date of one file from a Windows File 32-bit TimeStamp
- this cross-system function is used e.g. by mormot.core.zip which expects Windows TimeStamps in its headers
- FileSetDate(THandle, Age) is not implemented on POSIX: filename is needed
procedure FileSetHidden(const FileName: TFileName; ReadOnly: boolean);
Reduce the visibility of a given file, and set its read/write attributes
- on POSIX, change attributes for the the owner, and reset group/world flags so that it is accessible by the current user only; under POSIX, there is no "hidden" file attribute, but you should define a FileName starting by '.'
- on Windows, will set the "hidden" file attribue
procedure FileSetSticky(const FileName: TFileName);
Set the "sticky bit" on a file or directory
- on POSIX, a "sticky" folder will ensure that its nested files will be deleted by their owner; and a "sticky" file will ensure e.g. that no /var/tmp file is deleted by systemd during its clean up phases
- on Windows, will set the Hidden and System file attributes
function FileSetTime(const FileName: TFileName; const Created, Accessed, Written: Int64): boolean;
Redirection to Windows SetFileTime() of a file name from Int64(TFileTime
)
- if any Int64 is 0, the proper value will be guess from the non-0 values
function FileSize(F: THandle): Int64; overload;
Get a file size, from its handle
- returns 0 if file doesn't exist
- under Windows, will use the GetFileSizeEx fast API
- on POSIX, will use efficient FpFStat() single call and no file seek
function FileSize(const FileName: TFileName): Int64; overload;
Get a file size, from its name
- returns 0 if file doesn't exist, or is a directory
- under Windows, will use GetFileAttributesEx fast API
- on POSIX, will use efficient fpStat() single call but not FileOpen
/FileClose
function FileStreamSequentialRead(const FileName: TFileName): THandleStream;
Returns a TFileStreamFromHandle
optimized for one pass file reading
- will use FileOpenSequentialRead
(), i.e. FILE_FLAG_SEQUENTIAL_SCAN on Windows
- on POSIX, calls fpOpen(pointer(FileName),O_RDONLY) with no fpFlock() call
- is used e.g. by TRestOrmServerFullMemory
and TAlgoCompress
function FileSymLink(const SymLink, Target: TFileName): boolean;
Create a symbolic link named SymLink pointing to the Target file
- won't work with directories, a non existing target file, or on Windows XP
- need specific (admin) priviledges on Windows, or developper mode enabled
function FileTimeToDateTime(const FT: TFileTime): TDateTime;
Convert a Win32 64-bit FILETIME value into a TDateTime
function FileTimeToUnixMSTime(const FT: TFileTime): TUnixMSTime;
Convert a Win32 64-bit FILETIME value into an Unix milliseconds time
function FileTimeToUnixTime(const FT: TFileTime): TUnixTime;
Convert a Win32 64-bit FILETIME value into an Unix seconds time
function FileWriteAll(F: THandle; Buffer: pointer; Size: PtrInt): boolean;
A wrapper around FileWrite() to ensure a whole memory buffer is retrieved
- will call FileWrite() and retry up to Size bytes are written from the buffer
- return true if all memory buffer has been written, or false on error
function FillSystemRandom(Buffer: PByteArray; Len: integer; AllowBlocking: boolean): boolean;
Low-level function returning some random binary from the Operating System
- will call /dev/urandom or /dev/random under POSIX, and CryptGenRandom API on Windows then return TRUE, or fallback to mormot.core.base gsl_rng_taus2 generator and return FALSE if the system API failed
- on POSIX, only up to 32 bytes (256 bits) bits are retrieved from /dev/urandom or /dev/random as stated by "man urandom" Usage - then RandomBytes
() padded
- so you may consider that the output Buffer is always filled with random
- you should not have to call this procedure, but faster and safer TAesPrng
from mormot.crypt.core - also consider the TSystemPrng
class
procedure FlushFileBuffers(F: THandle); stdcall;
Compatibility function, wrapping Win32 API file flush to disk
function FreeEnvironmentStringsW(EnvBlock: PWideChar): BOOL; stdcall;
Redefined in mormot.core.os to avoid dependency to the Windows unit
procedure GetComputerUuid(out uuid: TGuid; disable: TGetComputerUuid = []); overload;
Retrieve a genuine 128-bit UUID identifier for this computer
- first try GetSmbios
(sbiUuid), i.e. the SMBIOS
System UUID
- otherwise, will compute a genuine hash
from known hardware information (CPU, Bios, MAC) and store
it in a local file for the next access (if disable is void), e.g. into '/var/tmp/.synopse.uid' on POSIX
- on Mac, include the mormot.core.os.mac unit to properly read this UUID
- note: some BIOS have no UUID, so we fallback to our hardware hash
on those
- you can specify some HW sources to be ignored during the calculation
function GetComputerUuid(disable: TGetComputerUuid = []): RawUtf8; overload;
Retrieve a genuine 128-bit UUID identifier for this computer
- returns GetSmbios
(sbiUuid) if available
- if no GetSmbios
(sbiUuid) is available, will compute a genuine hash
from HW and store
it on a local file for the next access (if disable is void)
- you can specify some HW sources to be ignored during the calculation
function GetCurrentProcess: THandle; stdcall;
Retrieves the current process ID
- redefined in mormot.core.os to avoid dependency to the Windows unit
function GetCurrentProcessId: DWORD; stdcall;
Retrieves the current process ID
- redefined in mormot.core.os to avoid dependency to the Windows unit
function GetCurrentThreadId: DWORD; stdcall;
Retrieves the current thread ID
- redefined in mormot.core.os to avoid dependency to the Windows unit
function GetCurrentThreadInfo: ShortString;
Returns the thread id and the thread name as a ShortString
- returns e.g. 'Thread 0001abcd [shortthreadname]'
- for convenient use when logging or raising an exception
function GetCurrentThreadName: RawUtf8;
Retrieve the thread name, as set by SetThreadName
()
- if possible, direct CurrentThreadNameShort
function is slightly faster
- will return the CurrentThreadNameShort
^ threadvar 31 chars value
function GetDelphiCompilerVersion: RawUtf8; deprecated;
Deprecated function: use COMPILER_VERSION
constant instead
function GetDesktopWindow: PtrInt; stdcall;
Compatibility function, wrapping Win32 API function
- returns the current main Window handle on Windows, or 0 on POSIX/Linux
function GetDiskAvailable(aDriveFolderOrFile: TFileName): QWord;
Retrieve how many bytes are currently available on a given folder
- returns 0 if the function fails
function GetDiskInfo(var aDriveFolderOrFile: TFileName; out aAvailableBytes, aFreeBytes, aTotalBytes: QWord ; aVolumeName: PSynUnicode = nil): boolean;
Retrieve low-level information about a given disk partition
- as used by TSynMonitorDisk
and GetDiskPartitionsText
()
- aDriveFolderOrFile is a directory on disk (no need to specify a raw drive name like 'c:\' on Windows)
- warning: aDriveFolderOrFile may be modified at input
- only under Windows the Quotas are applied separately to aAvailableBytes in respect to global aFreeBytes
function GetDiskPartitions: TDiskPartitions;
Retrieve low-level information about all mounted disk partitions of the system
- returned partitions array is sorted by "mounted" ascending order
function GetEnvironmentStringsW: PWideChar; stdcall;
Redefined in mormot.core.os to avoid dependency to the Windows unit
function GetErrorText(error: integer): RawUtf8;
Returns a given error code as plain text
- redirects to WinErrorText
(error, nil) on Windows, or StrError() on POSIX
function GetExecutableName(aAddress: pointer): TFileName;
Try to retrieve the file name of the executable
/library holding a function
- calls dladdr() on POSIX, or GetModuleFileName() on Windows
procedure GetExecutableVersion;
Initialize Executable
global variable, from the program version resources
- is not retrieved at startup, unless this function is especially called
- on POSIX, requires FPCUSEVERSIONINFO conditional to be set for the project
- use SetExecutableVersion
() if you want to force a custom version
- is in fact just a wrapper around SetExecutableVersion
(0, 0, 0, 0)
function GetFileNameFromUrl(const Uri: RawUtf8): TFileName;
Ask the Operating System to convert a file URL to a local file path
- only Windows has a such a PathCreateFromUrlW() API
- POSIX define this in mormot.net.http.pas, where TUri
is available
- used e.g. by TNetClientProtocolFile to implement the 'file://' protocol
function GetFileNameWithoutExt(const FileName: TFileName; Extension: PFileName = nil): TFileName;
Compute the file name, including its path if supplied, but without its extension
- e.g. GetFileNameWithoutExt
('/var/toto.ext') = '/var/toto'
- may optionally return the extracted extension, as '.ext'
- will be cross-platform, i.e. detect both '\' and '/' on all platforms
function GetFileNameWithoutExtOrPath(const FileName: TFileName): RawUtf8;
Extract the file name without any path nor extension, as UTF-8
- e.g. GetFileNameWithoutExt
('/var/toto.ext') = 'toto'
- used e.g. to compute Executable.ProgramName
function GetLastDelimU(const FileName: RawUtf8; OtherDelim: AnsiChar): PtrInt;
Defined here for proper ExtractExtP
() inlining
function GetLastError: integer; stdcall;
Compatibility function, wrapping Win32 API last error code
procedure GetLocalTime(out result: TSystemTime); stdcall;
Returns the current Local time as TSystemTime
from the OS
- under Delphi/Windows, directly call the homonymous Win32 API
- redefined in mormot.core.os to avoid dependency to the Windows unit
- under Linux/POSIX, calls clock_gettime(CLOCK_REALTIME_COARSE) if available or fpgettimeofday() on Darwin/MacOS, with FPC RTL TZSeconds adjustment (so will be fixed for the whole process lifetime and won't change at daylight)
- warning: do not call this function directly, but rather mormot.core.datetime TSynSystemTime.FromNowLocal
cross-platform method instead
function GetMemoryInfo(out info: TMemoryInfo; withalloc: boolean): boolean;
Retrieve low-level information about current memory usage
- as used by TSynMonitorMemory
- under BSD, only memtotal/memfree/percent are properly returned
- allocreserved and allocused are set only if withalloc is TRUE
function GetMemoryInfoText: RawUtf8;
Retrieve some human-readable text
from GetMemoryInfo
- numbers are rounded up to a single GB number with no decimals
- returns e.g. 'used 6GB/16GB (35% free)' text
function GetModuleHandle(lpModuleName: PChar): HMODULE;
Retrieves the current executable
module handle, i.e. its memory load address
- redefined in mormot.core.os to avoid dependency to the Windows unit
function GetOneSystemStoreAsPem(CertStore: TSystemCertificateStore; FlushCache: boolean = false; now: cardinal = 0): RawUtf8;
Retrieve all certificates of a given system store
as PEM text
- on Windows, will use the System Crypt API
- on POSIX, scsRoot loads the main CA file of the known system file, and scsCA the additional certificate files which may not be part of the main file
- GetSystemStoreAsPemLocalFile
file and 'SSL_CA_CERT_FILE' environment variables are ignored: call GetSystemStoreAsPem
() instead for the global store
- an internal cache is refreshed every 4 minutes unless FlushCache is set
function GetParentProcess(PID: cardinal = 0): cardinal;
Return the process ID of the parent of a given PID
- by default (PID
= 0), will search for the parent of the current process
- returns 0 if the PID
was not found
procedure GetProcessInfo(const aPidList: TCardinalDynArray; out aInfo: TWinProcessInfoDynArray); overload;
Retrieve low-level process(es) information, from the Windows API
- will set the needed wspDebug / SE_DEBUG_NAME priviledge during the call
procedure GetProcessInfo(aPid: cardinal; out aInfo: TWinProcessInfo); overload;
Retrieve low-level process information, from the Windows API
- will set the needed wspDebug / SE_DEBUG_NAME priviledge during the call
function GetRawSmbios: boolean;
Retrieve the SMBIOS
raw information as a single RawSmbios
gloabl binary blob
- will try the Windows API if available, or search and parse the main system memory with UEFI redirection if needed - via /systab system file on Linux, or kenv() on FreeBSD (only fully tested to work on Windows XP+ and Linux)
- follow DSP0134 3.6.0 System Management BIOS (SMBIOS
) Reference Specification with both SMBIOS
2.1 (32-bit) or SMBIOS
3.0 (64-bit) entry points
- the current user should have enough rights to read the main system memory, which means it should be root on most POSIX Operating Systems - so we persist this raw binary in /var/tmp/.synopse.smb to retrieve it from non-root user
function GetServicePid(const aServiceName: RawUtf8; aServiceState: PServiceState = nil): cardinal;
Return the ProcessID of a given service, by name
function GetSmbios(info: TSmbiosBasicInfo): RawUtf8;
Retrieve SMBIOS
information as text
- only the main values are decoded - see GetSmbiosInfo
in mormot.core.perf for a more complete DMI/SMBIOS
decoder
- on POSIX, requires root to access full SMBIOS
information - will fallback reading /sys/class/dmi/id/* on Linux or kenv() on FreeBSD for most entries if we found no previous root-retrieved cache in local /var/tmp/.synopse.smb
- see _SmbiosDecodeUuid
global flag for UUID decoding
function GetSystemInfoText: RawUtf8;
Retrieve some human-readable text
about the current system in several lines
- includes UTC timestamp, memory and disk availability, and exe/OS/CPU info
function GetSystemPath(kind: TSystemPath): TFileName;
Returns an operating system folder
- will return the full path of a given kind of private or shared folder, depending on the underlying operating system
- will use SHGetFolderPath and the corresponding CSIDL constant under Windows
- under POSIX, will return the proper environment variable
- spLog is a writable sub-folder specific to mORMot, always created if needed
- returned folder name contains the trailing path delimiter (\ or /)
function GetSystemStoreAsPem( CertStores: TSystemCertificateStores = [scsCA, scsRoot]; FlushCache: boolean = false; OnlySystemStore: boolean = false): RawUtf8;
Retrieve the OS certificates store
as PEM text
- first search for [Executable.ProgramFilePath+]GetSystemStoreAsPemLocalFile
, then for a file pointed by a 'SSL_CA_CERT_FILE' environment variable - unless OnlySystemStore is forced to true
- if no such file exists, or if OnlySystemStore is true, will concatenate the supplied CertStores values via individual GetOneSystemStoreAsPem
() calls
- return CA + ROOT certificates by default, ready to validate a certificate
- Darwin specific API is not supported yet, and is handled as a BSD system
- an internal cache is refreshed every 4 minutes unless FlushCache is set
procedure GetSystemTime(out result: TSystemTime); stdcall;
Returns the current UTC time as TSystemTime
from the OS
- under Delphi/Windows, directly call the homonymous Win32 API
- redefined in mormot.core.os to avoid dependency to the Windows unit
- under Linux/POSIX, calls clock_gettime(CLOCK_REALTIME_COARSE) if available or fpgettimeofday() on Darwin/MacOS
- warning: do not call this function directly, but rather mormot.core.datetime TSynSystemTime.FromNowUtc
cross-platform method instead
function GetUptimeSec: cardinal;
Returns how many seconds the system was up, accouting for time when the computer is asleep
- on Windows, computes GetTickCount64
div 1000
- on Linux/BSD, will use CLOCK_BOOTTIME/CLOCK_UPTIME clock
- on MacOS, will use mach_continuous_time() API
procedure GlobalLock;
Enter a process-wide giant lock for thread-safe shared process
- shall be protected as such:
GlobalLock; try .... do something thread-safe but as short as possible finally GlobalUnLock; end;
- you should better not use such a giant-lock, but an instance-dedicated critical section/TSynLocker
or TRWLock
- these functions are just here to be convenient, for non time-critical process (e.g. singleton initialization of external libraries, or before RegisterGlobalShutdownRelease
() which will use it anyway)
procedure GlobalUnLock;
Release the giant lock for thread-safe shared process
function HandleCtrlC(const OnClose: TThreadMethod): boolean;
Install a Windows event handler for Ctrl+C pressed on the Console
function HasConsole: boolean;
Always true on POSIX, may be false for a plain Windows GUI application
procedure InitializeCriticalSection(var cs : TRTLCriticalSection); stdcall;
Initialize a Critical Section (for Lock/UnLock)
- redefined in mormot.core.os to avoid dependency to the Windows unit
- under Delphi/Windows, directly call the homonymous Win32 API
procedure InitializeCriticalSectionIfNeededAndEnter(var cs: TRTLCriticalSection);
On need initialization of a mutex, then enter the lock
- if the supplied mutex has been initialized, do nothing
- if the supplied mutex is void (i.e. all filled with 0), initialize it
function IocpCreate(FileHandle, ExistingCompletionPort: THandle; CompletionKey: pointer; NumberOfConcurrentThreads: DWORD): THandle; stdcall;
Initialize Windows IOCP instance
- renamed in mormot.core.os to avoid dependency to the Windows unit
function IocpGetQueuedStatus(CompletionPort: THandle; var lpNumberOfBytesTransferred: DWORD; var lpCompletionKey: pointer; var lpOverlapped: pointer; dwMilliseconds: DWORD): BOOL; stdcall;
Retrieve Windows IOCP instance status
- renamed in mormot.core.os to avoid dependency to the Windows unit
function IocpPostQueuedStatus(CompletionPort: THandle; NumberOfBytesTransferred: DWORD; dwCompletionKey: pointer; lpOverlapped: POverlapped): BOOL; stdcall;
Trigger a Windows IOCP instance
- renamed in mormot.core.os to avoid dependency to the Windows unit
function IsDebuggerPresent: BOOL; stdcall;
Check if this process is currently running into the debugger
- redirect to the homonymous WinAPI function on Windows, or check if the /proc/self/status "TracerPid:" value is non zero on Linux, or search if "lazarus" is part of the parent process name for BSD
function IsDirectoryWritable(const Directory: TFileName; Flags: TIsDirectoryWritable = []): boolean;
Check if the directory is writable for the current user
- try to write and delete a void file with a random name in this folder
function IsInitializedCriticalSection(var cs: TRTLCriticalSection): boolean;
Returns TRUE if the supplied mutex has been initialized
- will check if the supplied mutex is void (i.e. all filled with 0 bytes)
function IsInvalidHttpHeader(head: PUtf8Char; headlen: PtrInt): boolean;
Check the supplied HTTP
header to not contain more than one EOL
- to avoid unexpected HTTP
body injection, e.g. from unsafe business code
function IsSharedViolation(ErrorCode: integer = 0): boolean;
Check if the last error reporting by the system is a file access violation
- call GetLastError
is no ErrorCode is supplied
function IsSystemFolder(const Folder: TFileName): boolean;
Rough detection of 'c:\windows' and 'c:\program files' folders
function IsUacVirtualFolder(const Folder: TFileName): boolean;
Check if a folder may be affected by UAC folder virtualization
- on Win32 Vista+, detects 'c:\windows' and 'c:\program files' UAC folders
- returns always false on Win64
function IsUacVirtualizationEnabled: boolean;
Check if UAC folder/registry virtualization is enabled for this process
- returns always false on Win64 - by design
- calls GetTokenInformation(TokenVirtualizationEnabled) on Win32
- if you include {$R src\mormot.win.default.manifest.res} in your project, UAC virtualization is disabled and this function returns false
function KillProcess(pid: cardinal; waitseconds: integer = 30): boolean;
Forcibly terminate a Windows process from its ProcessID
- call TerminateProcess() and wait for its ending
procedure LeaveCriticalSection(var cs: TRTLCriticalSection); stdcall;
Leave a Critical Section (UnLock)
- redefined in mormot.core.os to avoid dependency to the Windows unit
- under Delphi/Windows, directly call the homonymous Win32 API
procedure LibraryClose(Lib: TLibHandle);
Raw cross-platform library unloading function
- alternative to FreeLibrary() Windows API and FPC RTL
function LibraryError: string;
Raw cross-platform library resolution error, e.g. after LibraryOpen
function LibraryOpen(const LibraryName: TFileName): TLibHandle;
Raw cross-platform library loading function
- alternative to LoadLibrary() and SafeLoadLibrary() Windows API and RTL
- on Windows, set the SEM_NOOPENFILEERRORBOX and SEM_FAILCRITICALERRORS flags to avoid unexpected message boxes (which should not happen e.g. on a service)
- on Win32, reset the FPU flags after load as required with some libraries
- consider inheriting TSynLibrary
if you want to map a set of API functions
function LibraryResolve(Lib: TLibHandle; ProcName: PAnsiChar): pointer; stdcall;
Raw cross-platform library resolution function, as defined in FPC RTL
- alternative to GetProcAddr() Windows API and FPC RTL
function MatchOS(os: TOperatingSystem): boolean;
Check if the current OS (i.e. OS_KIND
value) match a description
- will handle osPosix and osLinux as generic detection of those systems
- osUnknown will always return true
function NewSynLocker: PSynLocker;
Initialize a TSynLocker
instance from heap
- call DoneandFreeMem to release the associated memory and OS mutex
- as used e.g. by TSynLocked
/TSynLockedWithRttiMethods
to reduce class instance size
function NormalizeDirectoryExists(const Directory: TFileName; RaiseExceptionOnCreationFailure: ExceptionClass = nil): TFileName; overload;
Just a wrapper around EnsureDirectoryExists
(NormalizeFileName
(Directory))
function NormalizeFileName(const FileName: TFileName): TFileName;
Ensure all \ / path delimiters are normalized into the current OS expectation
- i.e. normalize file name to use '\' on Windows, or '/' on POSIX
- see MakePath
() from mormot.core.text.pas to concatenate path items
procedure NormalizeFileNameU(var FileName: RawUtf8);
Ensure all \ / path delimiters are normalized into the current OS expectation
- this function works in-place on an UTF-8 string instance
function NowUtc: TDateTime;
Returns the current UTC time
- wrap UnixMSTimeUtcFast
, so use e.g. clock_gettime(CLOCK_REALTIME_COARSE) under Linux, or GetSystemTimeAsFileTime under Windows
function ObjArrayAdd(var aObjArray; aItem: TObject; var aSafe: TLightLock; aCount: PInteger = nil): PtrInt; overload;
Wrapper to implement a thread-safe T*ObjArray dynamic array storage
- warning: aCount^ should be a 32-bit "integer" variable, not a PtrInt
function ParseCommandArgs(const cmd: RawUtf8; argv: PParseCommandsArgs = nil; argc: PInteger = nil; temp: PRawUtf8 = nil; posix: boolean = PARSCOMMAND_POSIX): TParseCommands;
Low-level parsing of a RunCommand
() execution command
- parse and fill argv^[0 .. argc^ - 1] with corresponding arguments, after un-escaping and un-quoting if applicable, using temp^ to store
the content, and argv^[argc^] = nil, as expected by low-level OS exec() syscall parameters
- if argv=nil, do only the parsing, not the argument extraction - could be used for fast validation of the command line syntax
- you can force arguments OS flavor using the posix parameter - note that Windows parsing is not consistent by itself (e.g. double quoting or escaping depends on the actual executable
called) so returned flags should be considered as indicative only with posix=false
- you can check for errors with result * PARSECOMMAND_ERROR
<> []
- warning: argc^ should be a 32-bit "integer" variable, not a PtrInt
procedure PatchCode(Old, New: pointer; Size: PtrInt; Backup: pointer = nil; LeaveUnprotected: boolean = false);
Self-modifying code - change some memory buffer in the code segment
- if Backup is not nil, it should point to a Size array of bytes, ready to contain the overridden code buffer, for further hook disabling
- some systems do forbid such live patching: consider setting NOPATCHVMT and NOPATCHRTL conditionals for such projects
procedure PatchCodePtrUInt(Code: PPtrUInt; Value: PtrUInt; LeaveUnprotected: boolean = false);
Self-modifying code - change one PtrUInt
in the code segment
function PostMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL;
Post a message to the Windows message queue
- redefined in mormot.core.os to avoid dependency to the Windows unit
function PtrArrayDelete(var aPtrArray; aItem: pointer; var aSafe: TLightLock; aCount: PInteger = nil): PtrInt; overload;
Wrapper to implement a thread-safe pointer dynamic array storage
- warning: aCount^ should be a 32-bit "integer" variable, not a PtrInt
procedure QueryPerformanceMicroSeconds(out Value: Int64);
Returns a high-resolution system-wide monotonic timestamp as microseconds
- under Linux/POSIX, has true microseconds resolution, calling e.g. CLOCK_MONOTONIC on Linux/BSD
- under Windows, calls QueryPerformanceCounter / QueryPerformanceFrequency
function QuitProcess(pid: cardinal; waitseconds: integer): boolean;
Try to gently quit a Windows process from its ProcessID
- will send a WM_QUIT message to all its threads
function QuoteFileName(const FileName: TFileName): TFileName;
Add some " before and after if FileName has some space within
- could be used when generating command line parameters
procedure RaiseLastError(const Context: shortstring; RaisedException: ExceptClass = nil; Code: integer = 0);
Raise an EOSException
from the last system error using WinErrorText
()
- if Code is kept to its default 0, GetLastError
is called
procedure RaiseLastModuleError(ModuleName: PChar; ModuleException: ExceptClass);
Raise an Exception from the last module error using WinErrorText
()
procedure RawExceptionIntercept(const Handler: TOnRawLogException);
Setup Exception interception for the whole process
- call RawExceptionIntercept
(nil) to disable custom exception handling
function RawKillThread(Thread: TThread): boolean;
Try to kill/cancel a thread
- on Windows, calls the TerminateThread() API
- under Linux/FPC, calls pthread_cancel() API which is asynchronous
procedure RawSetThreadName(ThreadID: TThreadID; const Name: RawUtf8);
Low-level naming of a thread
- on Windows, will raise a standard "fake" exception to notify the thread name
- under Linux/FPC, calls pthread_setname_np() API which truncates to 16 chars
function RawTokenGetInfo(tok: THandle; tic: TTokenInformationClass; var buf: TSynTempBuffer): cardinal;
Low-level retrieveal of raw binary information for a given token
- returns the number of bytes retrieved into buf.buf
- caller should then run buf.Done to release the buf result memory
function RawTokenOpen(wtt: TWinTokenType; access: cardinal): THandle;
Calls OpenProcessToken() or OpenThreadToken() to get the current token
- caller should then run CloseHandle
() once done with the Token handle
function ReadRegString(Key: THandle; const Path, Value: string): string;
Quickly retrieve a Text
value from Registry
- could be used if TWinRegistry
is not needed, e.g. for a single value
function ReadSystemMemory(address, size: PtrUInt): RawByteString;
Fill a buffer with a copy of some low-level system memory
- used e.g. by GetRawSmbios
on XP or Linux/POSIX
- will allow to read up to 4MB of memory
- use low-level ntdll.dll API on Windows, or reading /dev/mem on POSIX - so expect
sudo/root rights on most systems
procedure RedirectCode(Func, RedirectFunc: pointer);
Low-level i386/x86_64 asm routine patch and redirection
function RegisterGlobalShutdownRelease(Instance: TObject; SearchExisting: boolean = false): pointer;
Framework will register here some instances to be released eventually
- better in this root unit than in each finalization section
- its use is protected by the GlobalLock
function RenameFile(const OldName, NewName: TFileName): boolean;
Redefined here to avoid warning to include "Windows" in uses clause and support FileName longer than MAX_PATH
- why did Delphi define this slow RTL function as inlined in SysUtils.pas?
function ReserveExecutableMemory(size: cardinal): pointer;
Cross-platform reserve some executable
memory
- using PAGE_EXECUTE_READWRITE flags on Windows, and PROT_READ or PROT_WRITE or PROT_EXEC on POSIX
- this function maintain an internal list of 64KB memory pages for efficiency
- memory blocks can not be released (don't try to use fremeem on them) and will be returned to the system at process finalization
procedure ReserveExecutableMemoryPageAccess(Reserved: pointer; Exec: boolean);
To be called after ReserveExecutableMemory
() when you want to actually write the memory blocks
- affect the mapping flags of the first memory page (4KB) of the Reserved buffer, so its size should be < 4KB
- do nothing on Windows and Linux, but may be needed on OpenBSD
procedure ResetCpuSet(out CpuSet: TCpuSet);
Fill a bitmask of CPU cores with zeros
function RetrieveLoadAvg: RawUtf8;
Return the system-wide time usage information
- on LINUX, retrieve /proc/loadavg or on OSX/BSD call libc getloadavg()
- return '' on Windows - call RetrieveSystemTimes
() instead
function RetrieveProcessInfo(PID: cardinal; out KernelTime, UserTime: Int64; out WorkKB, VirtualKB: cardinal): boolean;
Return the time and memory usage information about a given process
- under Windows, is a wrapper around GetProcessTimes/GetProcessMemoryInfo
function RetrieveSystemTimes(out IdleTime, KernelTime, UserTime: Int64): boolean;
Return the system-wide time usage information
- under Windows, is a wrapper around GetSystemTimes() kernel API call
- return false on POSIX system - call RetrieveLoadAvg
() instead
function RtlCaptureStackBackTrace(FramesToSkip, FramesToCapture: cardinal; BackTrace, BackTraceHash: pointer): byte; stdcall;
Retrieves the current stack trace
- only available since Windows XP
- FramesToSkip + FramesToCapture should be <= 62
function RunCommand(const cmd: TFileName; waitfor: boolean; const env: TFileName = ''; options: TRunOptions = []; waitfordelayms: cardinal = INFINITE; processhandle: PHandle = nil; redirected: PRawByteString = nil; const onoutput: TOnRedirect = nil; const wrkdir: TFileName = '' ): integer;
Like fpSystem, but cross-platform
- under POSIX, calls bash only if needed, after ParseCommandArgs
() analysis
- under Windows (especially Windows 10), creating a process can be dead slow https://randomascii.wordpress.com/2019/04/21/on2-in-createprocess
- waitfordelayms/processhandle/redirected/onoutput exist on Windows only - and redirected is the raw byte output, which may be OEM, WinAnsi or UTF-16 depending on the program itself
- parsed is implemented on POSIX only
- optional env should be encoded as 'n1=v1'#0'n2=v2'#0#0 pairs
function RunCommandWin(const cmd: TFileName; waitfor: boolean; var processinfo: TProcessInformation; const env: TFileName = ''; options: TRunOptions = []; waitfordelayms: cardinal = INFINITE; redirected: PRawByteString = nil; const onoutput: TOnRedirect = nil; const wrkdir: TFileName = ''): integer;
Windows-specific RunCommand
() function returning raw TProcessInformation
function RunProcess(const path, arg1: TFileName; waitfor: boolean; const arg2: TFileName = ''; const arg3: TFileName = ''; const arg4: TFileName = ''; const arg5: TFileName = ''; const env: TFileName = ''; options: TRunOptions = []): integer;
Like SysUtils.ExecuteProcess, but allowing not to wait for the process to finish
- optional env value follows 'n1=v1'#0'n2=v2'#0'n3=v3'#0#0 Windows layout
function RunRedirect(const cmd: TFileName; exitcode: PInteger = nil; const onoutput: TOnRedirect = nil; waitfordelayms: cardinal = INFINITE; setresult: boolean = true; const env: TFileName = ''; const wrkdir: TFileName = ''; options: TRunOptions = []): RawByteString;
Execute a command, returning its output console as UTF-8 text
- calling CreateProcessW on Windows (i.e. our RunCommand
), and FPC RTL popen/pclose on POSIX
- return '' on cmd execution error, or the whole output console content with no conversion: on POSIX, it is likely to be UTF-8 but on Windows it depends on the actual program so is likely to be CP_OEM
but others could use the system code page or even UTF-16 binary with BOM (!) - so you may consider using AnsiToUtf8
() with the proper code page
- will optionally call onoutput() to notify the new output state
- aborts if onoutput() callback returns true, or waitfordelayms expires
- optional env is Windows only, (FPC popen does not support it), and should be encoded as name=value#0 pairs
- you can specify a wrkdir if the path specified by cmd is not good enough
- warning: exitcode^ should be a 32-bit "integer" variable, not a PtrInt
function SafeFileName(const FileName: TFileName): boolean;
Check for unsafe '..' '/xxx' 'c:xxx' '~/xxx' or '\\' patterns in a filename
function SafeFileNameU(const FileName: RawUtf8): boolean;
Check for unsafe '..' '/xxx' 'c:xxx' '~/xxx' or '\\' patterns in a RawUtf8
filename
function SafePathName(const Path: TFileName): boolean;
Check for unsafe '..' '/xxx' 'c:xxx' '~/xxx' or '\\' patterns in a path
function SafePathNameU(const Path: RawUtf8): boolean;
Check for unsafe '..' '/xxx' 'c:xxx' '~/xxx' or '\\' patterns in a RawUtf8
path
function SearchRecToDateTime(const F: TSearchRec): TDateTime;
Get a file date and time, from a FindFirst/FindNext search
- the returned timestamp is in local time, not UTC
- this method would use the F.Timestamp field available since Delphi XE2
function SearchRecToDateTimeUtc(const F: TSearchRec): TDateTime;
Get a file UTC date and time, from a FindFirst/FindNext search
- SearchRecToDateTime
(), SearchRecToWindowsTime
() and F.TimeStamp, which have local time and require a conversion, may appear less useful on server side
- is implemented as a wrapper around SearchRecToUnixTimeUtc
()
function SearchRecToUnixTimeUtc(const F: TSearchRec): TUnixTime;
Get a file UTC date and time, from a FindFirst/FindNext search, as Unix time
- SearchRecToDateTime
(), SearchRecToWindowsTime
() and F.TimeStamp, which have local time and require a conversion, may appear less useful on server side
function SearchRecToWindowsTime(const F: TSearchRec): integer;
Get a file date and time, from a FindFirst/FindNext search, as Windows time
- this cross-system function is used e.g. by mormot.core.zip which expects Windows TimeStamps in its headers
function SearchRecValidFile(const F: TSearchRec): boolean;
Check if a FindFirst/FindNext found instance is actually a file
function SearchRecValidFolder(const F: TSearchRec): boolean;
Check if a FindFirst/FindNext found instance is actually a folder
function SeemsRealPointer(p: pointer): boolean;
Check if the supplied pointer is actually pointing to some memory page
- will call slow but safe VirtualQuery API on Windows, or try a fpaccess() syscall on POSIX systems (validated on Linux only)
function ServiceSingleRun: boolean;
Launch the registered Service execution
- ServiceSingle
provided by this application (most probably from TServiceSingle.Create
) is sent to the operating system
- returns TRUE on success
- returns FALSE on error (to get extended information, call GetLastError
)
function SetCpuSet(var CpuSet: TCpuSet; CpuIndex: cardinal): boolean;
Set a particular bit in a mask of CPU cores
procedure SetCurrentThreadName(const Format: RawUtf8; const Args: array of const); overload;
Name the current thread so that it would be easily identified in the IDE debugger
- could then be retrieved by CurrentThreadNameShort
/GetCurrentThreadName
- just a wrapper around SetThreadName
(GetCurrentThreadId
, ...)
procedure SetCurrentThreadName(const Name: RawUtf8); overload;
Name the current thread so that it would be easily identified in the IDE debugger
- could also be retrieved by CurrentThreadNameShort
/GetCurrentThreadName
- just a wrapper around SetThreadName
(GetCurrentThreadId
, ...)
procedure SetEndOfFile(F: THandle); stdcall;
Compatibility function, wrapping Win32 API file truncate at current position
procedure SetExecutableVersion(aMajor, aMinor, aRelease, aBuild: integer); overload;
Initialize Executable
global variable with custom version numbers
- GetExecutableVersion
will retrieve version information from the executable
itself (if it was included at build time and FPCUSEVERSIONINFO conditional was specified for the project)
- but you can use this function to set any custom version number
procedure SetExecutableVersion(const aVersionText: RawUtf8); overload;
Initialize Executable
global variable, supplying the version as text
- e.g. SetExecutableVersion
('7.1.2.512');
procedure SetLastError(error: integer); stdcall;
Compatibility function, wrapping Win32 API last error code
function SetSystemPath(kind: TSystemPath; const path: TFileName): boolean;
Force an operating system folder
- if the default location is not good enough for your project
- will just check that the directory exists, not that it is writable
function SetSystemTime(const utctime: TSystemTime): boolean;
Set the current system time as UTC timestamp
- we define two functions with diverse signature to circumvent the FPC RTL TSystemTime
field order inconsistency
- warning: do not call this function directly, but rather mormot.core.datetime TSynSystemTime.ChangeOperatingSystemTime
cross-platform method instead
procedure SetSystemTimeZone(const info: TDynamicTimeZoneInformation);
Allow to change the current system time zone on Windows
- don't use this low-level function but the high-level mormot.core.search TSynTimeZone.ChangeOperatingSystemTimeZone
method
- will set the needed wspSystemTime / SE_SYSTEMTIME_NAME priviledge
- will select the proper API before and after Vista, if needed
- raise EOSException
on failure
function SetThreadCpuAffinity(Thread: TThread; CpuIndex: cardinal): boolean;
Try to assign a given thread to a specific logical CPU core
- CpuIndex should be in 0 .. SystemInfo.dwNumberOfProcessors - 1 range
function SetThreadMaskAffinity(Thread: TThread; const Mask: TCpuSet): boolean;
Try to assign a given thread to a specific set of logical CPU core(s)
- on Windows, calls the SetThreadAffinityMask() API
- under Linux/FPC, calls pthread_setaffinity_np() API
function SetThreadSocketAffinity(Thread: TThread; SocketIndex: cardinal): boolean;
Try to assign a given thread to a specific hardware CPU socket
- SocketIndex should be in 0 .. CpuSockets
- 1 range, and will use the CpuSocketsMask
[] information retrieved during process startup
function SleepDelay(elapsed: PtrInt): PtrInt;
Compute optimal sleep time as 0/1/5/50 then 120-250 ms steps
- is agressively designed burning some CPU in favor of responsiveness
function SleepHiRes(ms: cardinal; var terminated: boolean; terminatedvalue: boolean = true): boolean; overload;
Similar to Windows sleep() API call, but truly cross-platform and checking the Terminated flag during its wait for quick abort response
- returns true if terminated^ was set to true (terminatedvalue)
procedure SleepHiRes(ms: cardinal); overload;
Similar to Windows sleep() API call, to be truly cross-platform
- using millisecond resolution
- SleepHiRes
(0) calls ThreadSwitch on Windows, but POSIX version will wait 10 microsecond unless SleepHiRes0Yield is forced to true (bad idea)
- in respect to RTL's Sleep() function, it will return on ESysEINTR if was interrupted by any OS signal
- warning: wait typically for the next system timer interrupt on Windows, which is every 16ms by default; as a consequence, never rely on the ms supplied value to guess the elapsed time, but call GetTickCount64
function SleepStep(var start: Int64; terminated: PBoolean = nil): Int64;
Call SleepHiRes
() taking count of the activity, in 0/1/5/50/120-250 ms steps
- range is agressively designed burning some CPU in favor of responsiveness
- should reset start := 0 when some activity occurred, or start := -1 on Windows to avoid any SleepHiRes
(0) = SwitchToThread
call
- would optionally return if terminated^ is set, or event is signaled
- returns the current GetTickCount64
value
function SleepStepTime(var start, tix: Int64; endtix: PInt64 = nil): PtrInt;
Compute optimal sleep time as SleepStep
, in 0/1/5/50/120-250 ms steps
- is agressively designed burning some CPU in favor of responsiveness
- start=0 would fill its value with tix; start<0 would fill its value with tix-50 so that SleepDelay
() would never call SleepHiRes
(0)
function SortDynArrayFileName(const A, B): integer;
Compare two "array of TFileName" elements, grouped by file extension
- i.e. with no case sensitivity on Windows
- the expected string type is the RTL string, i.e. TFileName
- calls internally GetFileNameWithoutExt
() and AnsiCompareFileName()
procedure SpinExc(var Target: PtrUInt; NewValue, Comperand: PtrUInt);
Try LockedExc
() in a loop, calling SwitchToThread
after some spinning
function StatusCodeIsSuccess(Code: integer): boolean;
Returns true for successful HTTP
status codes, i.e. in 200..399 range
- will map mainly SUCCESS (200), CREATED (201), NOCONTENT (204), PARTIALCONTENT (206), NOTMODIFIED (304) or TEMPORARYREDIRECT (307) codes
- any HTTP
status not part of this range will be identified as erronous request e.g. in the web server statistics
procedure StatusCodeToReason(Code: cardinal; var Reason: RawUtf8);
Retrieve the HTTP
reason text
from its integer code
- as defined in http
://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
function StatusCodeToShort(Code: cardinal): TShort47;
Convert any HTTP_* constant to an integer status code and its English text
- returns e.g. '200 OK' or '404 Not Found', calling StatusCodeToText
()
function StatusCodeToText(Code: cardinal): PRawUtf8;
Retrieve the HTTP
reason text
from its integer code as PRawUtf8
- e.g. StatusCodeToText
(200)^='OK'
- as defined in http
://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
- returns the generic 'Invalid Request' for any unknown Code
function StreamCopyUntilEnd(Source, Dest: TStream): Int64;
Copy all Source content into Dest from current position
- on Delphi, Dest.CopyFrom(Source, 0) uses GetSize and ReadBuffer which is not compatible e.g. with TAesPkcs7Reader
padding - and has a small buffer
- returns the number of bytes copied from Source to Dest
function StringFromFile(const FileName: TFileName; HasNoSize: boolean = false): RawByteString;
Read a File content into a string
- content can be binary or text
- returns '' if file was not found or any read error occurred
- wil use GetFileSize() API by default, unless HasNoSize is defined, and read will be done using a buffer (required e.g. for POSIX char files)
- uses RawByteString
for byte storage, whatever the codepage is
function StringFromFiles(const FileName: array of TFileName): TRawByteStringDynArray;
Read all Files content from a list of file names
- returns '' if no FileName[] file was found, or the read content
function StringFromFirstFile(const FileName: array of TFileName): RawByteString;
Read a File content from a list of potential files
- returns '' if no file was found, or the first matching FileName[] content
function StringFromFolders(const Folders: array of TFileName; const Mask: TFileName = FILES_ALL; FileNames: PFileNameDynArray = nil): TRawByteStringDynArray;
Read all Files content from a list of folders names
- returns the content of every file contained in the supplied Folders[]
- with optionally the FileNames
[] corresponding to each result[] content
procedure SwitchToThread; stdcall;
Similar to Windows SwitchToThread
API call, to be truly cross-platform
- call fpnanosleep(10) on POSIX systems, or the homonymous API on Windows
function TemporaryFileName: TFileName;
Compute an unique temporary file name
- following 'exename_123.tmp' pattern, in the system temporary folder
procedure TextBackground(Color: TConsoleColor);
Change the console text
background color
procedure TextColor(Color: TConsoleColor);
Change the console text
writing color
function ToMethod(const method: RawUtf8): TUriMethod;
Convert a string HTTP
verb into its TUriMethod
enumerate
- conversion is case-insensitive
function ToText(st: TServiceState): PShortString; overload;
Return the ready to be displayed text
of a TServiceState
value
function ToText(m: TUriMethod): PUtf8Char; overload;
Convert a TUriMethod
enumerate to its #0 terminated uppercase
text
function ToText(const osv: TOperatingSystemVersion): RawUtf8; overload;
Convert an Operating System type into its text
representation
- returns e.g. 'Windows Vista' or 'Ubuntu' or 'macOS 13 Ventura'
function ToTextOS(osint32: integer): RawUtf8;
Convert a 32-bit Operating System type into its full text
representation
- including the kernel revision (not the distribution version) on POSIX systems
- returns e.g. 'Windows Vista', 'Windows 11 64-bit 22000' or 'Ubuntu Linux 5.4.0'
function ToTextShort(const osv: TOperatingSystemVersion): RawUtf8;
Convert an Operating System type into its one-word text
representation
- returns e.g. 'Vista' or 'Ubuntu' or 'OSX'
function TryEnterCriticalSection(var cs: TRTLCriticalSection): integer; stdcall;
Try to enter a Critical Section (Lock)
- returns 1 if the lock was acquired, or 0 if the mutex is already locked
- redefined in mormot.core.os to avoid dependency to the Windows unit
- under Delphi/Windows, directly call the homonymous Win32 API
function UnAmp(const name: RawUtf8): TRawUtf8DynArray;
Detect any & character, and extract it as part of the result array
- e.g. UnAmp
('alter&nate') returns ['n', 'alternate']
function Unicode_AnsiToWide( A: PAnsiChar; W: PWideChar; LA, LW, CodePage: PtrInt): integer;
Compatibility function, wrapping MultiByteToWideChar() Win32 API call
- returns the number of WideChar written into W^ destination buffer
- on POSIX, use the ICU library, or fallback to FPC RTL widestringmanager with a temporary variable - you would need to include cwstring unit
- raw function called by TSynAnsiConvert.AnsiBufferToUnicode
from mormot.core.unicode unit
function Unicode_CodePage: integer;
Returns the curent system code page for AnsiString types
- as used to initialize CurrentAnsiConvert
in mormot.core.unicode unit
- calls GetACP() Win32 API value on Delphi, or DefaultSystemCodePage on FPC - i.e. GetSystemCodePage() on POSIX (likely to be UTF-8) or the value used by the LCL for its "string" types (also typically UTF-8 even on Windows)
function Unicode_CompareString( PW1, PW2: PWideChar; L1, L2: PtrInt; IgnoreCase: boolean): integer;
Compatibility function, wrapping CompareStringW() Win32 API text
comparison
- returns 1 if PW1>PW2, 2 if PW1=PW2, 3 if PW1<PW2 - so substract 2 to have
-1,0,1 as regular StrCompW
/StrICompW comparison function result
- will compute StrLen
(PW1/PW2) if L1 or L2 < 0
- on POSIX, use the ICU library, or fallback to FPC RTL widestringmanager with a temporary variable - you would need to include cwstring unit
- in practice, is seldom called, unless our proprietary WIN32CASE collation is used in mormot.db.raw.sqlite3, or via Utf8CompareOS
() or Utf8CompareIOS
() functions from mormot.core.unicode
- consider Utf8ILCompReference
() from mormot.core.unicode.pas for an operating-system-independent Unicode 10.0 comparison function
function Unicode_FromUtf8(Text: PUtf8Char; TextLen: PtrInt; var Dest: TSynTempBuffer): PWideChar;
Local RTL wrapper function to avoid linking mormot.core.unicode.pas
- returns dest.buf as result, and dest.len as length in WideChar (not bytes)
- caller should always call Dest.Done to release any (unlikely) allocated memory
function Unicode_InPlaceLower(W: PWideChar; WLen: integer): integer; stdcall;
Compatibility function, wrapping Win32 API CharLowerBuffW()
- on POSIX, use the ICU library, or fallback to 'A'..'Z' conversion only
- raw function called by LowerCaseUnicode
() from mormot.core.unicode unit
function Unicode_InPlaceUpper(W: PWideChar; WLen: integer): integer; stdcall;
Compatibility function, wrapping Win32 API CharUpperBuffW()
- on POSIX, use the ICU library, or fallback to 'a'..'z' conversion only
- raw function called by UpperCaseUnicode
() from mormot.core.unicode unit
function Unicode_WideToAnsi( W: PWideChar; A: PAnsiChar; LW, LA, CodePage: PtrInt): integer;
Compatibility function, wrapping WideCharToMultiByte() Win32 API call
- returns the number of AnsiChar written into A^ destination buffer
- on POSIX, use the ICU library, or fallback to FPC RTL widestringmanager with a temporary variable - you would need to include cwstring unit
- raw function called by TSynAnsiConvert.UnicodeBufferToAnsi
from mormot.core.unicode unit
procedure Unicode_WideToShort(W: PWideChar; LW, CodePage: PtrInt; var res: ShortString);
Conversion of some UTF-16 buffer into a temporary Ansi ShortString
- used when mormot.core.unicode is an overkill, e.g. TCrtSocket.SockSend
()
- calls IsAnsiCompatibleW
() first to quickly handle any ASCII-7 output
procedure UnixMSTimeToFileTime(I64: TUnixMSTime; out FT: TFileTime);
Convert an Unix milliseconds time to a Win32 64-bit FILETIME value
function UnixMSTimeUtc: TUnixMSTime;
Returns the current UTC date/time as a millisecond-based c-encoded time
- i.e. current number of milliseconds elapsed since Unix epoch 1/1/1970
- will use e.g. fast clock_gettime(CLOCK_REALTIME_COARSE) under Linux, or GetSystemTimePreciseAsFileTime under Windows 8 and later
- on Windows, is slightly more accurate, but slower than UnixMSTimeUtcFast
function UnixMSTimeUtcFast: TUnixMSTime;
Returns the current UTC date/time as a millisecond-based c-encoded time
- under Linux/POSIX, is the very same than UnixMSTimeUtc
(inlined call)
- under Windows 8+, will call GetSystemTimeAsFileTime instead of GetSystemTimePreciseAsFileTime, which has higher precision, but is slower
- prefer it under Windows, if a dozen of ms resolution is enough for your task
procedure UnixTimeToFileTime(I64: TUnixTime; out FT: TFileTime);
Convert an Unix seconds time to a Win32 64-bit FILETIME value
procedure UnixTimeToLocalTime(I64: TUnixTime; out Local: TSystemTime);
A wrapper calling SystemTimeToTzSpecificLocalTime Windows API
- note: FileTimeToLocalFileTime is not to be involved here
- only used by mormot.lib.static for proper SQlite3 linking on Windows
function UnixTimeUtc: TUnixTime;
Returns the current UTC date/time as a second-based c-encoded time
- i.e. current number of seconds elapsed since Unix epoch 1/1/1970
- use e.g. fast clock_gettime(CLOCK_REALTIME_COARSE) under Linux, or GetSystemTimeAsFileTime under Windows
- returns a 64-bit unsigned value, so is "Year2038bug" free
function UserAgentParse(const UserAgent: RawUtf8; out ProgramName, ProgramVersion: RawUtf8; out OS: TOperatingSystem): boolean;
Quickly parse the TFileVersion.UserAgent
content
- identify e.g. 'myprogram/3.1.0.2W' or 'myprogram/3.1.0.2W32
' text
function Utf8ToConsole(const S: RawUtf8): RawByteString;
Direct conversion of a UTF-8 encoded string into a console OEM-encoded string
- under Windows, will use the CP_OEM
encoding
- under Linux, will expect
the console to be defined with UTF-8 encoding
- we don't propose any ConsoleToUtf8() function because Windows depends on the running program itself: most should generates CP_OEM
(e.g. 850) as expected, but some could use the system code page or even UTF-16 binary with BOM (!) - so you may consider using AnsiToUtf8
() with the proper code page
function Utf8ToWin32PWideChar(const u: RawUtf8; var d: TSynTempBuffer): PWideChar;
Local RTL wrapper function to avoid linking mormot.core.unicode.pas
- just a wrapper around Unicode_FromUtf8
() over a temporary buffer
- caller should always call d.Done to release any (unlikely) allocated memory
function ValidHandle(Handle: THandle): boolean;
Cross-platform check if the supplied THandle is not invalid
function W32(const FileName: TFileName; var Temp: TW32Temp): PWideChar;
Efficiently return a PWideChar from a TFileName on all compilers
- without any memory allocation, and with proper Unicode support
- is also able to handle FileName with length > MAX_PATH, up to 2048 chars
- all the low-level file functions of this unit (e.g. FileCreate
or FileOpen
) will use this function to support file names longer than MAX_PATH
function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; stdcall;
Redefined in mormot.core.os to avoid dependency to the Windows unit
procedure Win32PWideCharToUtf8(P: PWideChar; out res: RawUtf8); overload;
Local RTL wrapper function to avoid linking mormot.core.unicode.pas
procedure Win32PWideCharToUtf8(P: PWideChar; Len: PtrInt; out res: RawUtf8); overload;
Local RTL wrapper function to avoid linking mormot.core.unicode.pas
procedure WinCheck(const Context: shortstring; Code: integer; RaisedException: ExceptClass = nil);
Call RaiseLastError
(Code) if Code <> NO_ERROR
= ERROR_SUCCESS
function WindowsFileTime64ToUnixMSTime(WinTime: QWord): TUnixMSTime;
Convert a Windows API File 64-bit TimeStamp into a regular TUnixMSTime
- i.e. a FILETIME value as returned by GetFileTime() Win32 API
- some binary formats (e.g. ISO 9660 or LDAP) have such FILETIME fields
function WindowsFileTimeToDateTime(WinTime: integer): TDateTime;
Convert a Windows API File 32-bit TimeStamp into a regular TDateTime
- returns 0 if the conversion failed
- used e.g. by FileSetDateFromWindowsTime
() on POSIX
function WinErrorConstant(Code: cardinal): PShortString;
Return the best known ERROR_* system error message constant texts
- without the 'ERROR_' prefix
- as used by WinErrorText
() and some low-level Windows API wrappers
function WinErrorText(Code: cardinal; ModuleName: PChar): RawUtf8;
Return the error message of a given Module
- first try WinErrorConstant
() for system error constants (if ModuleName=nil), then call FormatMessage() and override the RTL function to force the ENGLISH_LANGID
flag first
- if ModuleName does support this Code, will try it as system error
- replace SysErrorMessagePerModule() and SysErrorMessage() from mORMot 1
function WinGetEnumName(Info: PAnsiChar; Value: integer): PShortString;
Minimal GetEnumName
() for Delphi + FPC on base enum type with no Min/Max
function WinLastError(const Context: shortstring; Code: integer = 0): string;
Return a RaiseLastError
-like error message using WinErrorText
()
- if Code is kept to its default 0, GetLastError
is called
procedure XorOSEntropy(var e: THash512Rec);
Call several Operating System APIs to gather 512-bit of entropy information
function _oskb(Size: QWord): shortstring;
Internal function to avoid linking mormot.core.buffers.pas
- will output the value as one number with one decimal and KB/MB/GB/TB suffix
AcquireSRWLockExclusive: procedure(var P: TOSLightMutex); stdcall;
Slim Reader/Writer (SRW) API exclusive mode - fallback to TLightLock
on XP
AppendShortUuid: TAppendShortUuid;
Append
a TGuid into lower-cased '3f2504e0-4f89-11d3-9a0c-0305e82c3301' text
- this unit defaults to the RTL, but mormot.core.text.pas will override it
BiosInfoText: RawUtf8;
Some textual information about the current computer hardware, from BIOS
- contains e.g. 'LENOVO 20HES23B0U ThinkPad T470'
BOOL_UTF8: array[boolean] of RawUtf8;
JSON compatible representation of a boolean value, i.e. 'false' and 'true'
- can be used when a RawUtf8
string is expected
- this global will be initialized with 'false' and 'true' constants, to avoid a memory allocation each time it is assigned to a variable
CpuCache: array[1..4] of record Count, Size, LineSize: cardinal; end;
Level 1 to 4 CPU caches as returned by GetLogicalProcessorInformation
- yes, Intel introduced a Level 4 cache (eDRAM) with some Haswell/Iris CPUs
- this information is not retrieved on all Linux / POSIX systems yet
- only Unified or Data caches are include (not Instruction or Trace)
- note: some CPU - like the Apple M1 - have 128 bytes of LineSize
CpuCacheSize: cardinal;
The on-chip cache size, in bytes, as returned by the OS
- retrieved from /proc/cpuinfo "cache size" entry (L3 cache) on Linux or CpuCache
[3/4].Size (from GetLogicalProcessorInformation) on Windows
CpuCacheText: RawUtf8;
The available cache information as returned by the OS
- e.g. 'L1=2*32KB L2=256KB L3=3MB' on Windows or '3072 KB' on Linux
CpuInfoText: RawUtf8;
Some textual information about the current CPU and its known cache
- contains e.g. '4 x Intel(R) Core(TM) i5-7300U CPU @ 2.60GHz [3MB]'
CpuSockets: integer;
How many hardware CPU sockets are defined on this system
- i.e. the number of physical CPU slots, not the number of logical CPU cores as returned by SystemInfo.dwNumberOfProcessors
- as used e.g. by SetThreadAffinity()
CpuSocketsMask: array of TCpuSet;
Low-level bitmasks of logical CPU cores hosted on each hardware CPU socket
- filled at process startup as CpuSocketsMask
[0 .. CpuSockets
- 1] range
CreateDummyCertificate: function(const Stuff, CertName: RawUtf8; Marker: cardinal): RawByteString;
Low-level function used by StuffExeCertificate() in mormot.misc.pecoff.pas
- properly implemented by mormot.crypt.openssl.pas, but mormot.misc.pecoff has its own stand-alone version using a pre-generated fixed certificate
- warning: the Marker should have no 0 byte within
Executable: TExecutable;
Global information about the current executable
and computer
- this structure is initialized in this unit's initialization block below but you need to call GetExecutableVersion
to initialize its Version fields from the executable
version resource (if any)
- you can call SetExecutableVersion
() with a custom version, if needed
ExeVersion: TExecutable absolute Executable;
Deprecated global: use Executable
variable instead
GetExecutableLocation: function(aAddress: pointer): ShortString;
Return a function/method location according to the supplied code address
- returns the address as hexadecimal by default, e.g. '4cb765'
- if mormot.core.log.pas is defined in the project, will redirect to TDebugFile.FindLocationShort
() method using .map/.dbg/.mab information, and return filename, symbol name and line number (if any) as plain text
, e.g. '4cb765 ../src/core/mormot.core.base.pas statuscodeissuccess
(11183)' on FPC
GetSystemMacAddress: function: TRawUtf8DynArray;
Retrieve the MAC addresses of all hardware network adapters
- mormot.net.sock.pas will inject here its own cross-platform version
- this unit will include a simple parser of /sys/class/net/* for Linux only
- as used e.g. by GetComputerUuid
() fallback if SMBIOS
is not available
GetSystemStoreAsPemLocalFile: TFileName;
The local PEM file name to be searched by GetSystemStoreAsPem
() to override the OS certificates store
- a relative file name (i.e. with no included path, e.g. 'cacert.pem') will be searched in the Executable.ProgramFilePath folder
- an absolute file name (e.g. 'C:\path\to\file.pem' or '/posix/path') could also be specified
- set by default to '' to disable this override (for security purposes)
GetTickCount64: function: Int64; stdcall;
Returns a system-wide current monotonic timestamp as milliseconds
- will use the corresponding native API function under Vista+, or will be redirected to a custom wrapper function for older Windows versions (XP) to avoid the 32-bit overflow/wrapping issue of GetTickCount
- warning: FPC's SysUtils.GetTickCount64 or TThread.GetTickCount64 don't handle properly 49 days wrapping under XP -> always use this safe version
- warning: FPC's SysUtils.GetTickCount64 may call fpgettimeofday() e.g. on Darwin, which is not monotonic -> always use this more coherent version
- on POSIX, will call (via vDSO) the very fast CLOCK_MONOTONIC_COARSE if available, or the low-level mach_absolute_time() monotonic Darwin API
- do not expect
exact millisecond resolution - steps may rather be e.g. within the 15-16 ms range on Windows, and 4-5 ms range on Linux
InitializeSRWLock: procedure(var P: TOSLightMutex); stdcall;
Slim Reader/Writer (SRW) API exclusive mode - fallback to TLightLock
on XP
IsWow64: boolean;
Is set to TRUE if the current process is a 32-bit image running under WOW64
- WOW64 is the x86 emulator that allows 32-bit Windows-based applications to run seamlessly on 64-bit Windows
- equals always FALSE if the current executable
is a 64-bit image
JSON_CONTENT_TYPE_HEADER_VAR: RawUtf8;
HTTP
header for MIME content type used for plain JSON
- this global will be initialized with JSON_CONTENT_TYPE_HEADER
constant, to avoid a memory allocation each time it is assigned to a variable
JSON_CONTENT_TYPE_VAR: RawUtf8;
MIME content type used for JSON communication
- i.e. 'application/json' as stated by datatracker.ietf.org/doc/html/rfc7159
- this global will be initialized with JSON_CONTENT_TYPE
constant, to avoid a memory allocation each time it is assigned to a variable
NULL_STR_VAR: RawUtf8;
Can be used to avoid a memory allocation for res := 'null
'
- this global will be initialized with 'null
' constant, to avoid a memory allocation each time it is assigned to a variable
OSVersion: TWindowsVersion;
The current Windows edition, as retrieved for the current process
OSVersion32: TOperatingSystemVersion;
The running Operating System
OSVersionInfo: TOSVersionInfoEx;
Low-level Operating System information, as retrieved for the current process
OSVersionInfoEx: RawUtf8;
Some addition system information as text
, e.g. 'Wine 1.1.5'
- also always appended to OSVersionText
high-level description
- use if PosEx
('Wine', OSVersionInfoEx
) > 0 then to check for Wine presence
OSVersionInt32: integer absolute OSVersion32;
The running Operating System, encoded as a 32-bit integer
OSVersionShort: RawUtf8;
The current Operating System version, as retrieved for the current process and computed by ToTextOS
(OSVersionInt32
)
- contains e.g. 'Windows Vista' or 'Ubuntu Linux 5.4.0' or 'macOS 13 Ventura 22.3.0'
OSVersionText: RawUtf8;
The current Operating System version, as retrieved for the current process
- contains e.g. 'Windows Seven 64 SP1 (6.1.7601)' or 'Windows XP SP3 (5.1.2600)' or 'Windows 10 64bit 22H2 (10.0.19045.4046)' or 'macOS 13 Ventura (Darwin 22.3.0)' or 'Ubuntu 16.04.5 LTS - Linux 3.13.0 110 generic#157 Ubuntu SMP Mon Feb 20 11:55:25 UTC 2017'
OS_KIND: TOperatingSystem = osWindows ;
The target Operating System used for compilation, as TOperatingSystem
- a specific Linux distribution may be detected instead of plain osLinux
RawSmbios: TRawSmbiosInfo;
Global variable filled by GetRawSmbios
from SMBIOS
binary information
ReleaseSRWLockExclusive: procedure(var P: TOSLightMutex); stdcall;
Slim Reader/Writer (SRW) API exclusive mode - fallback to TLightLock
on XP
RunAbortMethods: TRunAbortMethods = [ramCtrlC, ramQuit];
RunRedirect
/RunCommand
methods to gracefully terminate before TerminateProcess
RunAbortTimeoutSecs: integer = 5;
How many seconds we should wait for gracefull termination of a process in RunRedirect
() - or RunCommand
() on Windows
- set 0 to disable gracefull exit, and force hard SIGKILL/TerminateProcess
RunFromSynTests: boolean;
Global flag to modify the code behavior at runtime when run from TSynTests
- e.g. TSynDaemon.AfterCreate won't overwrite TSynTests.RunAsConsole
logs
ServiceSingle: TServiceSingle = nil;
The main TServiceSingle
instance running in the current executable
- the regular way of executing services is to instantiate a TServiceSingle
instance (which will fill this ServiceSingle
variable) and its methods, then eventually call ServiceSingleRun
SetThreadName: procedure(ThreadID: TThreadID; const Format: RawUtf8; const Args: array of const);
Name a thread so that it would be easily identified in the IDE debugger
- default implementation does nothing, unless mormot.core.log is included
- you can force this function to do nothing by setting the NOSETTHREADNAME conditional, if you have issues with this feature when debugging your app
- most meaningless patterns (like 'TSql') are trimmed to reduce the resulting length - which is convenient e.g. with POSIX truncation to 16 chars
- you can retrieve the name later on using CurrentThreadNameShort
- this method will register TSynLog.LogThreadName
(), so threads calling it should also call TSynLogFamily.OnThreadEnded
/TSynLog.NotifyThreadEnded
SharedRandom: TLecuyerThreadSafe;
A global thread-safe Pierre L'Ecuyer software random generator
- should not be used, unless may be slightly faster than a threadvar
ShortToUuid: TShortToUuid;
Decode a '3F2504E0-4F89-11D3-9A0C-0305E82C3301' text
into a TGuid
- this unit defaults to the RTL, but mormot.core.text.pas will override it
StdOut: THandle;
Low-level handle used for console writing
- may be overriden when console is redirected
- on Windows, is initialized when AllocConsole
or TextColor
() are called
SystemInfo: TSystemInfo;
The current System information, as retrieved for the current process
- under a WOW64 process, it will use the GetNativeSystemInfo() new API to retrieve the real top-most system information
- note that the lpMinimumApplicationAddress field is replaced by a more optimistic/realistic value ($100000 instead of default $10000)
- under BSD/Linux, only contain dwPageSize and dwNumberOfProcessors fields
SystemMemorySize: PtrUInt;
The number of physical memory bytes available to the process
- equals TMemoryInfo.memtotal
as retrieved from GetMemoryInfo
() at startup
TimeZoneLocalBias: integer;
The number of minutes bias in respect to UTC/GMT date/time
- as retrieved via -GetLocalTimeOffset() at startup, so may not be accurate after a time shift during the process execution - but any long-running process (like a service) should use UTC timestamps only
WindowsDisplayVersion: RawUtf8;
On Windows, the ready-to-be-displayed text
version of the system
- e.g. '22H2'
WindowsProductName: RawUtf8;
On Windows, the ready-to-be-displayed text
version of the system
- e.g. 'Windows 10 Entreprise N'
WindowsServiceLog: TSynLogProc;
Can be assigned from TSynLog.DoLog
class method for TServiceController
/TService
logging
- default is nil, i.e. disabling logging, since it may interfere with the logging process of the Windows Service itself
WindowsUbr: integer;
On Windows, the Update Build Revision as shown with the "ver/winver" command
- to track the current update state of the system
_SmbiosDecodeUuid: (sduDirect, sduInvert, sduVersion) ;
Customize how DecodeSmbiosUuid
() handle endianess of its first bytes
- sduDirect will directly use GUIDToString
() layout (seems expected on Windows to match "wmic csproduct get uuid" value)
- sduInvert will force first values inversion (mandatory on MacOS)
- sduVersion will invert for SMBios
version < 2.6 (set outside Windows)