{******************************************************************************}
{ }
{ Project JEDI Code Library (JCL) }
{ }
{ The contents of this file are subject to the Mozilla Public License Version }
{ 1.1 (the "License"); you may not use this file except in compliance with the }
{ License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ }
{ }
{ Software distributed under the License is distributed on an "AS IS" basis, }
{ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for }
{ the specific language governing rights and limitations under the License. }
{ }
{ The Original Code is JclWin32.pas. }
{ }
{ The Initial Developer of the Original Code is documented in the accompanying }
{ help file JCL.chm. Portions created by these individuals are Copyright (C) }
{ of these individuals. }
{ }
{******************************************************************************}
{ }
{ This unit defines various Win32 API declarations which are either missing or }
{ incorrect in one or more of the supported Delphi versions. This unit is not }
{ intended for regular code, only API declarations. }
{ }
{ Unit owner: Peter Friese }
{ Last modified: November 18, 2001 }
{ }
{******************************************************************************}
unit JclWin32;
{$I jcl.inc}
{$WEAKPACKAGEUNIT ON}
interface
uses
Windows, ActiveX, ImageHlp,
{$IFDEF COMPILER5_UP}
AccCtrl, AclApi,
{$ENDIF COMPILER5_UP}
ShlObj;
//------------------------------------------------------------------------------
// Locales related
//------------------------------------------------------------------------------
function LANGIDFROMLCID(const lcid: LCID): Word;
function MAKELANGID(const usPrimaryLanguage, usSubLanguage: Byte): Word;
function PRIMARYLANGID(const lgid: Word): Word;
function SUBLANGID(const lgid: Word): Word;
function MAKELCID(const wLanguageID, wSortID: Word): LCID;
function SORTIDFROMLCID(const lcid: LCID): Word;
const
KLF_SETFORPROCESS = $00000100;
DATE_YEARMONTH = $00000008;
//------------------------------------------------------------------------------
// Various Base Services declarations
//------------------------------------------------------------------------------
function InterlockedExchangePointer(var Target: Pointer; Value: Pointer): Pointer;
stdcall; external 'kernel32.dll' name 'InterlockedExchangePointer';
function SignalObjectAndWait(hObjectToSignal: THandle; hObjectToWaitOn: THandle;
dwMilliseconds: DWORD; bAlertable: BOOL): DWORD; stdcall; external kernel32
name 'SignalObjectAndWait';
const
// ProductType
VER_NT_WORKSTATION = $0000001;
VER_NT_DOMAIN_CONTROLLER = $0000002;
VER_NT_SERVER = $0000003;
// SuiteMask
VER_SUITE_SMALLBUSINESS = $00000001;
VER_SUITE_ENTERPRISE = $00000002;
VER_SUITE_BACKOFFICE = $00000004;
VER_SUITE_COMMUNICATIONS = $00000008;
VER_SUITE_TERMINAL = $00000010;
VER_SUITE_SMALLBUSINESS_RESTRICTED = $00000020;
VER_SUITE_EMBEDDEDNT = $00000040;
VER_SUITE_DATACENTER = $00000080;
VER_SUITE_SINGLEUSERTS = $00000100;
VER_SUITE_PERSONAL = $00000200;
VER_SUITE_SERVERAPPLIANCE = $00000400;
type
POSVersionInfoEx = ^TOSVersionInfoEx;
TOSVersionInfoEx = record
dwOSVersionInfoSize: DWORD;
dwMajorVersion: DWORD;
dwMinorVersion: DWORD;
dwBuildNumber: DWORD;
dwPlatformId: DWORD;
szCSDVersion: array [0..127] of Char; // Maintenance string for PSS usage
wServicePackMajor: Word;
wServicePackMinor: Word;
wSuiteMask: Word;
wProductType: Byte;
wReserved: Byte;
end;
function GetVersionEx(lpVersionInformation: POSVersionInfoEx): BOOL; stdcall;
function CreateMutex(lpMutexAttributes: PSecurityAttributes; bInitialOwner: DWORD;
lpName: PChar): THandle; stdcall; external kernel32 name 'CreateMutexA';
//------------------------------------------------------------------------------
// Shell related declarations (missing/incorrect in different delphi versions)
//------------------------------------------------------------------------------
{$IFNDEF COMPILER4_UP}
{$IFDEF SUPPORTS_INTERFACE}
type
IContextMenu2 = interface (IContextMenu)
[SID_IContextMenu2]
function HandleMenuMsg(uMsg: UINT; WParam: WPARAM; LParam: LPARAM): HRESULT; stdcall;
end;
function SHGetSpecialFolderPath(hwndOwner: HWND; lpszPath: PChar;
nFolder: Integer; fCreate: BOOL): BOOL; stdcall; external
'shell32.dll' name 'SHGetSpecialFolderPathA'
const
SID_IQueryInfo = '{00021500-0000-0000-C000-000000000046}';
type
IQueryInfo = interface (IUnknown)
[SID_IQueryInfo]
function GetInfoTip(dwFlags: DWORD; var ppwszTip: PWideChar): HRESULT; stdcall;
function GetInfoFlags(out pdwFlags: DWORD): HRESULT; stdcall;
end;
{$ENDIF SUPPORTS_INTERFACE}
{$ENDIF COMPILER4_UP}
//==============================================================================
// Miscellanuous (missing in delphi 3)
//==============================================================================
{$IFNDEF COMPILER4_UP}
const
TIME_ZONE_ID_INVALID = DWORD($FFFFFFFF);
TIME_ZONE_ID_UNKNOWN = 0;
TIME_ZONE_ID_STANDARD = 1;
TIME_ZONE_ID_DAYLIGHT = 2;
{$ENDIF COMPILER4_UP}
//==============================================================================
// COM related declarations
//==============================================================================
type
TCoCreateInstanceExProc = function (const clsid: TGUID;
unkOuter: IUnknown; dwClsCtx: Longint; ServerInfo: Pointer{PCoServerInfo};
dwCount: Longint; rgmqResults: Pointer{PMultiQIArray}): HResult stdcall;
//==============================================================================
// Security related declarations from winnt.h
//==============================================================================
/////////////////////////////////////////////////////////////////////////////
// //
// Universal well-known SIDs //
// //
// Null SID S-1-0-0 //
// World S-1-1-0 //
// Local S-1-2-0 //
// Creator Owner ID S-1-3-0 //
// Creator Group ID S-1-3-1 //
// Creator Owner Server ID S-1-3-2 //
// Creator Group Server ID S-1-3-3 //
// //
// (Non-unique IDs) S-1-4 //
// //
/////////////////////////////////////////////////////////////////////////////
const
SECURITY_NULL_SID_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 0));
SECURITY_WORLD_SID_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 1));
SECURITY_LOCAL_SID_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 2));
SECURITY_CREATOR_SID_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 3));
SECURITY_NON_UNIQUE_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 4));
SECURITY_NULL_RID = ($00000000);
SECURITY_WORLD_RID = ($00000000);
SECURITY_LOCAL_RID = ($00000000);
SECURITY_CREATOR_OWNER_RID = ($00000000);
SECURITY_CREATOR_GROUP_RID = ($00000001);
SECURITY_CREATOR_OWNER_SERVER_RID = ($00000002);
SECURITY_CREATOR_GROUP_SERVER_RID = ($00000003);
/////////////////////////////////////////////////////////////////////////////
// //
// NT well-known SIDs //
// //
// NT Authority S-1-5 //
// Dialup S-1-5-1 //
// //
// Network S-1-5-2 //
// Batch S-1-5-3 //
// Interactive S-1-5-4 //
// Service S-1-5-6 //
// AnonymousLogon S-1-5-7 (aka null logon session) //
// Proxy S-1-5-8 //
// ServerLogon S-1-5-9 (aka domain controller account) //
// Self S-1-5-10 (self RID) //
// Authenticated User S-1-5-11 (Authenticated user somewhere) //
// Restricted Code S-1-5-12 (Running restricted code) //
// Terminal Server S-1-5-13 (Running on Terminal Server) //
// //
// (Logon IDs) S-1-5-5-X-Y //
// //
// (NT non-unique IDs) S-1-5-0x15-... //
// //
// (Built-in domain) s-1-5-0x20 //
// //
/////////////////////////////////////////////////////////////////////////////
const
SECURITY_NT_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
SECURITY_DIALUP_RID = ($00000001);
SECURITY_NETWORK_RID = ($00000002);
SECURITY_BATCH_RID = ($00000003);
SECURITY_INTERACTIVE_RID = ($00000004);
SECURITY_SERVICE_RID = ($00000006);
SECURITY_ANONYMOUS_LOGON_RID = ($00000007);
SECURITY_PROXY_RID = ($00000008);
SECURITY_ENTERPRISE_CONTROLLERS_RID = ($00000009);
SECURITY_SERVER_LOGON_RID = SECURITY_ENTERPRISE_CONTROLLERS_RID;
SECURITY_PRINCIPAL_SELF_RID = ($0000000A);
SECURITY_AUTHENTICATED_USER_RID = ($0000000B);
SECURITY_RESTRICTED_CODE_RID = ($0000000C);
SECURITY_TERMINAL_SERVER_RID = ($0000000D);
SECURITY_LOGON_IDS_RID = ($00000005);
SECURITY_LOGON_IDS_RID_COUNT = (3);
SECURITY_LOCAL_SYSTEM_RID = ($00000012);
SECURITY_NT_NON_UNIQUE = ($00000015);
SECURITY_BUILTIN_DOMAIN_RID = ($00000020);
/////////////////////////////////////////////////////////////////////////////
// //
// well-known domain relative sub-authority values (RIDs)... //
// //
/////////////////////////////////////////////////////////////////////////////
// Well-known users ...
DOMAIN_USER_RID_ADMIN = ($000001F4);
DOMAIN_USER_RID_GUEST = ($000001F5);
DOMAIN_USER_RID_KRBTGT = ($000001F6);
// well-known groups ...
DOMAIN_GROUP_RID_ADMINS = ($00000200);
DOMAIN_GROUP_RID_USERS = ($00000201);
DOMAIN_GROUP_RID_GUESTS = ($00000202);
DOMAIN_GROUP_RID_COMPUTERS = ($00000203);
DOMAIN_GROUP_RID_CONTROLLERS = ($00000204);
DOMAIN_GROUP_RID_CERT_ADMINS = ($00000205);
DOMAIN_GROUP_RID_SCHEMA_ADMINS = ($00000206);
DOMAIN_GROUP_RID_ENTERPRISE_ADMINS = ($00000207);
DOMAIN_GROUP_RID_POLICY_ADMINS = ($00000208);
// well-known aliases ...
DOMAIN_ALIAS_RID_ADMINS = ($00000220);
DOMAIN_ALIAS_RID_USERS = ($00000221);
DOMAIN_ALIAS_RID_GUESTS = ($00000222);
DOMAIN_ALIAS_RID_POWER_USERS = ($00000223);
DOMAIN_ALIAS_RID_ACCOUNT_OPS = ($00000224);
DOMAIN_ALIAS_RID_SYSTEM_OPS = ($00000225);
DOMAIN_ALIAS_RID_PRINT_OPS = ($00000226);
DOMAIN_ALIAS_RID_BACKUP_OPS = ($00000227);
DOMAIN_ALIAS_RID_REPLICATOR = ($00000228);
DOMAIN_ALIAS_RID_RAS_SERVERS = ($00000229);
DOMAIN_ALIAS_RID_PREW2KCOMPACCESS = ($0000022A);
SE_CREATE_TOKEN_NAME = 'SeCreateTokenPrivilege';
SE_ASSIGNPRIMARYTOKEN_NAME = 'SeAssignPrimaryTokenPrivilege';
SE_LOCK_MEMORY_NAME = 'SeLockMemoryPrivilege';
SE_INCREASE_QUOTA_NAME = 'SeIncreaseQuotaPrivilege';
SE_UNSOLICITED_INPUT_NAME = 'SeUnsolicitedInputPrivilege';
SE_MACHINE_ACCOUNT_NAME = 'SeMachineAccountPrivilege';
SE_TCB_NAME = 'SeTcbPrivilege';
SE_SECURITY_NAME = 'SeSecurityPrivilege';
SE_TAKE_OWNERSHIP_NAME = 'SeTakeOwnershipPrivilege';
SE_LOAD_DRIVER_NAME = 'SeLoadDriverPrivilege';
SE_SYSTEM_PROFILE_NAME = 'SeSystemProfilePrivilege';
SE_SYSTEMTIME_NAME = 'SeSystemtimePrivilege';
SE_PROF_SINGLE_PROCESS_NAME = 'SeProfileSingleProcessPrivilege';
SE_INC_BASE_PRIORITY_NAME = 'SeIncreaseBasePriorityPrivilege';
SE_CREATE_PAGEFILE_NAME = 'SeCreatePagefilePrivilege';
SE_CREATE_PERMANENT_NAME = 'SeCreatePermanentPrivilege';
SE_BACKUP_NAME = 'SeBackupPrivilege';
SE_RESTORE_NAME = 'SeRestorePrivilege';
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
SE_DEBUG_NAME = 'SeDebugPrivilege';
SE_AUDIT_NAME = 'SeAuditPrivilege';
SE_SYSTEM_ENVIRONMENT_NAME = 'SeSystemEnvironmentPrivilege';
SE_CHANGE_NOTIFY_NAME = 'SeChangeNotifyPrivilege';
SE_REMOTE_SHUTDOWN_NAME = 'SeRemoteShutdownPrivilege';
SE_UNDOCK_NAME = 'SeUndockPrivilege';
SE_SYNC_AGENT_NAME = 'SeSyncAgentPrivilege';
SE_ENABLE_DELEGATION_NAME = 'SeEnableDelegationPrivilege';
{$IFNDEF COMPILER5_UP}
type
SE_OBJECT_TYPE = (
SE_UNKNOWN_OBJECT_TYPE,
SE_FILE_OBJECT,
SE_SERVICE,
SE_PRINTER,
SE_REGISTRY_KEY,
SE_LMSHARE,
SE_KERNEL_OBJECT,
SE_WINDOW_OBJECT,
SE_DS_OBJECT,
SE_DS_OBJECT_ALL,
SE_PROVIDER_DEFINED_OBJECT,
SE_WMIGUID_OBJECT
);
{$ENDIF COMPILER5_UP}
{$IFNDEF COMPILER4_UP}
const
SECURITY_DESCRIPTOR_REVISION = 1;
SECURITY_DESCRIPTOR_REVISION1 = 1;
SECURITY_DESCRIPTOR_MIN_LENGTH = 20;
{$ENDIF COMPILER4_UP}
// TODO SetNamedSecurityInfo is incorrectly declared, at least for Windows 2000
// it is. D5 unit tries to import from aclapi.dll but it is located in advapi3.dll
// Have to check whether this is also true for Windows NT 4.
type
PPSID = ^PSID;
function SetNamedSecurityInfoW(pObjectName: PWideChar; ObjectType: SE_OBJECT_TYPE;
SecurityInfo: SECURITY_INFORMATION; ppsidOwner, ppsidGroup: PPSID; ppDacl,
ppSacl: PACL): DWORD; stdcall; external 'advapi32.dll' name 'SetNamedSecurityInfoW';
function AdjustTokenPrivileges(TokenHandle: THandle; DisableAllPrivileges: BOOL;
const NewState: TTokenPrivileges; BufferLength: DWORD;
PreviousState: PTokenPrivileges; ReturnLength: PDWORD): BOOL; stdcall;
external 'advapi32.dll' name 'AdjustTokenPrivileges'
//==============================================================================
// NTFS related I/O control codes, types and constants from winnt.h, winioctl.h
//==============================================================================
type
PFileAllocatedRangeBuffer = ^TFileAllocatedRangeBuffer;
_FILE_ALLOCATED_RANGE_BUFFER = record
FileOffset: TLargeInteger;
Length: TLargeInteger;
end;
TFileAllocatedRangeBuffer = _FILE_ALLOCATED_RANGE_BUFFER;
PFileZeroDataInformation = ^TFileZeroDataInformation;
_FILE_ZERO_DATA_INFORMATION = record
FileOffset: TLargeInteger;
BeyondFinalZero: TLargeInteger;
end;
TFileZeroDataInformation = _FILE_ZERO_DATA_INFORMATION;
const
COMPRESSION_FORMAT_NONE = $0000;
COMPRESSION_FORMAT_DEFAULT = $0001;
COMPRESSION_FORMAT_LZNT1 = $0002;
FILE_SUPPORTS_SPARSE_FILES = $00000040;
FILE_SUPPORTS_REPARSE_POINTS = $00000080;
IO_REPARSE_TAG_MOUNT_POINT = DWORD($A0000003);
IO_REPARSE_TAG_HSM = DWORD($C0000004);
IO_REPARSE_TAG_SIS = DWORD($80000007);
FILE_ATTRIBUTE_DEVICE = $00000040;
FILE_ATTRIBUTE_SPARSE_FILE = $00000200;
FILE_ATTRIBUTE_REPARSE_POINT = $00000400;
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = $00002000;
FILE_ATTRIBUTE_ENCRYPTED = $00004000;
FILE_DEVICE_FILE_SYSTEM = $00000009;
METHOD_BUFFERED = 0;
METHOD_IN_DIRECT = 1;
METHOD_OUT_DIRECT = 2;
METHOD_NEITHER = 3;
FILE_ANY_ACCESS = 0;
FILE_SPECIAL_ACCESS = FILE_ANY_ACCESS;
FILE_READ_ACCESS = $0001;
FILE_WRITE_ACCESS = $0002;
FILE_WRITE_DATA = $0002;
FILE_READ_DATA = $0001;
FSCTL_GET_COMPRESSION = (FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_ANY_ACCESS shl 14) or
(15 shl 2) or METHOD_BUFFERED;
FSCTL_SET_COMPRESSION = (FILE_DEVICE_FILE_SYSTEM shl 16) or
((FILE_READ_DATA or FILE_WRITE_DATA) shl 14) or
(16 shl 2) or METHOD_BUFFERED;
FSCTL_LOCK_VOLUME = (FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_ANY_ACCESS shl 14) or
(6 shl 2) or METHOD_BUFFERED;
FSCTL_UNLOCK_VOLUME = (FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_ANY_ACCESS shl 14) or
(7 shl 2) or METHOD_BUFFERED;
FSCTL_SET_SPARSE = (FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_SPECIAL_ACCESS shl 14) or
(49 shl 2) or METHOD_BUFFERED;
FSCTL_SET_ZERO_DATA = (FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_WRITE_DATA shl 14) or
(50 shl 2) or METHOD_BUFFERED;
FSCTL_QUERY_ALLOCATED_RANGES =
(FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_READ_DATA shl 14) or
(51 shl 2) or METHOD_NEITHER;
FSCTL_SET_REPARSE_POINT = (FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_SPECIAL_ACCESS shl 14) or
(41 shl 2) or METHOD_BUFFERED;
FSCTL_GET_REPARSE_POINT = (FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_ANY_ACCESS shl 14) or
(42 shl 2) or METHOD_BUFFERED;
FSCTL_DELETE_REPARSE_POINT =
(FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_SPECIAL_ACCESS shl 14) or
(43 shl 2) or METHOD_BUFFERED;
FSCTL_REQUEST_OPLOCK_LEVEL_1 =
(FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_ANY_ACCESS shl 14) or
(0 shl 2) or METHOD_BUFFERED;
FSCTL_REQUEST_OPLOCK_LEVEL_2 =
(FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_ANY_ACCESS shl 14) or
(1 shl 2) or METHOD_BUFFERED;
FSCTL_REQUEST_BATCH_OPLOCK =
(FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_ANY_ACCESS shl 14) or
(2 shl 2) or METHOD_BUFFERED;
FSCTL_REQUEST_FILTER_OPLOCK =
(FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_ANY_ACCESS shl 14) or
(23 shl 2) or METHOD_BUFFERED;
FSCTL_OPLOCK_BREAK_ACKNOWLEDGE =
(FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_ANY_ACCESS shl 14) or
(3 shl 2) or METHOD_BUFFERED;
FSCTL_OPBATCH_ACK_CLOSE_PENDING =
(FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_ANY_ACCESS shl 14) or
(4 shl 2) or METHOD_BUFFERED;
FSCTL_OPLOCK_BREAK_NOTIFY =
(FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_ANY_ACCESS shl 14) or
(5 shl 2) or METHOD_BUFFERED;
FSCTL_OPLOCK_BREAK_ACK_NO_2 =
(FILE_DEVICE_FILE_SYSTEM shl 16) or
(FILE_ANY_ACCESS shl 14) or
(20 shl 2) or METHOD_BUFFERED;
function GetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint: LPCSTR; lpszVolumeName: LPSTR; cchBufferLength: DWORD): BOOL;
function SetVolumeMountPoint(lpszVolumeMountPoint: LPCSTR; lpszVolumeName: LPCSTR): BOOL;
function DeleteVolumeMountPoint(lpszVolumeMountPoint: LPCSTR): BOOL;
//------------------------------------------------------------------------------
// NTFS Reparse Points
//------------------------------------------------------------------------------
//
// The reparse structure is used by layered drivers to store data in a
// reparse point. The constraints on reparse tags are defined below.
// This version of the reparse data buffer is only for Microsoft tags.
//
type
PReparseDataBuffer = ^TReparseDataBuffer;
_REPARSE_DATA_BUFFER = record
ReparseTag: DWORD;
ReparseDataLength: Word;
Reserved: Word;
case Integer of
0: ( // SymbolicLinkReparseBuffer and MountPointReparseBuffer
SubstituteNameOffset: Word;
SubstituteNameLength: Word;
PrintNameOffset: Word;
PrintNameLength: Word;
PathBuffer: array [0..0] of WCHAR);
1: ( // GenericReparseBuffer
DataBuffer: array [0..0] of Byte);
end;
TReparseDataBuffer = _REPARSE_DATA_BUFFER;
const
REPARSE_DATA_BUFFER_HEADER_SIZE = 8;
REPARSE_GUID_DATA_BUFFER_HEADER_SIZE = 24;
type
PReparsePointInformation = ^TReparsePointInformation;
_REPARSE_POINT_INFORMATION = record
ReparseDataLength: Word;
UnparsedNameLength: Word;
end;
TReparsePointInformation = _REPARSE_POINT_INFORMATION;
const
MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024;
IO_REPARSE_TAG_RESERVED_ZERO = (0);
IO_REPARSE_TAG_RESERVED_ONE = (1);
IO_REPARSE_TAG_RESERVED_RANGE = IO_RE