From a5af90b2ff55e5e47591a1da85fbe0b9d8f1ba50 Mon Sep 17 00:00:00 2001 From: tony Date: Mon, 6 Jan 2025 11:51:50 +0000 Subject: [PATCH 1/7] Added Lazarus Build Files --- Lib/Core/Makefile.fpc | 169 +++--- Lib/Protocols/Makefile.fpc | 616 +++++++++----------- Lib/System/Makefile.fpc | 88 +-- fpmake.pp | 394 ------------- getindy.sh | 61 -- lazarus-fpc/indycore.lpk | 284 +++++++++ lazarus-fpc/indycore.pas | 27 + lazarus-fpc/indylaz.lpk | 116 ++++ lazarus-fpc/indylaz.pas | 29 + lazarus-fpc/indyprotocols.lpk | 1036 +++++++++++++++++++++++++++++++++ lazarus-fpc/indyprotocols.pas | 74 +++ lazarus-fpc/indysystem.lpk | 150 +++++ lazarus-fpc/indysystem.pas | 27 + 13 files changed, 2114 insertions(+), 957 deletions(-) delete mode 100644 fpmake.pp delete mode 100644 getindy.sh create mode 100644 lazarus-fpc/indycore.lpk create mode 100644 lazarus-fpc/indycore.pas create mode 100644 lazarus-fpc/indylaz.lpk create mode 100644 lazarus-fpc/indylaz.pas create mode 100644 lazarus-fpc/indyprotocols.lpk create mode 100644 lazarus-fpc/indyprotocols.pas create mode 100644 lazarus-fpc/indysystem.lpk create mode 100644 lazarus-fpc/indysystem.pas diff --git a/Lib/Core/Makefile.fpc b/Lib/Core/Makefile.fpc index b465c99b7..a4afa4c20 100644 --- a/Lib/Core/Makefile.fpc +++ b/Lib/Core/Makefile.fpc @@ -1,89 +1,80 @@ -# Makefile.fpc for indycorefpc 10.6.3.0 - -[package] -name=indycorefpc -version=10.6.3.0 -main=indy - - -[compiler] -includedir=../Inc -unittargetdir=lib/$(CPU_TARGET)-$(OS_TARGET) -unitdir=../System/lib/$(CPU_TARGET)-$(OS_TARGET) -options=-gl - -[target] -units=indycorefpc -rsts=IdResourceStringsCore.rst - -implicitunits=IdAssignedNumbers \ - IdBuffer \ - IdCmdTCPClient \ - IdCmdTCPServer \ - IdCommandHandlers \ - IdContext \ - IdCustomTCPServer \ - IdCustomTransparentProxy \ - IdExceptionCore \ - IdGlobalCore \ - IdIOHandler \ - IdIOHandlerSocket \ - IdIOHandlerStack \ - IdIOHandlerStream \ - IdIPAddress \ - IdIPMCastBase \ - IdIPMCastClient \ - IdIPMCastServer \ - IdIcmpClient \ - IdIntercept \ - IdInterceptSimLog \ - IdInterceptThrottler \ - IdLogBase \ - IdLogDebug \ - IdLogEvent \ - IdLogFile \ - IdLogStream \ - IdRawBase \ - IdRawClient \ - IdRawFunctions \ - IdRawHeaders \ - IdReply \ - IdReplyRFC \ - IdResourceStringsCore \ - IdScheduler \ - IdSchedulerOfThread \ - IdSchedulerOfThreadDefault \ - IdSchedulerOfThreadPool \ - IdServerIOHandler \ - IdServerIOHandlerSocket \ - IdServerIOHandlerStack \ - IdSimpleServer \ - IdSocketHandle \ - IdSocks \ - IdSync \ - IdTCPClient \ - IdTCPConnection \ - IdTCPServer \ - IdTCPStream \ - IdTask \ - IdThread \ - IdThreadComponent \ - IdThreadSafe \ - IdTraceRoute \ - IdUDPBase \ - IdUDPClient \ - IdUDPServer \ - IdYarn - - -[requires] -packages=indysystemfpc -packagedir=../System/lib/$(CPU_TARGET)-$(OS_TARGET) - -[install] -fpcpackage=y -fpcsubdir=packages/extra -buildunit=indycorefpc - -[shared] -build=n +[package] +name=indycore +version=$(INDY_VERSION) +main=indy + +[requires] +packages=indysystem + +[compiler] +options= -MDelphi $(OPT) -Scghi -CX -Ur -Xs -vew +unittargetdir= ../../units/$(CPU_TARGET)-$(OS_TARGET) +includedir=. +unitdir=. + +[target] +units=indycorefpc +implicitunits=IdAssignedNumbers \ + IdBuffer \ + IdCmdTCPClient \ + IdCmdTCPServer \ + IdCommandHandlers \ + IdContext \ + IdCustomTCPServer \ + IdCustomTransparentProxy \ + IdExceptionCore \ + IdGlobalCore \ + IdIcmpClient \ + IdIntercept \ + IdInterceptSimLog \ + IdInterceptThrottler \ + IdIOHandler \ + IdIOHandlerSocket \ + IdIOHandlerStack \ + IdIOHandlerStream \ + IdIPAddress \ + IdIPMCastBase \ + IdIPMCastClient \ + IdIPMCastServer \ + IdLogBase \ + IdLogDebug \ + IdLogEvent \ + IdLogFile \ + IdLogStream \ + IdRawBase \ + IdRawClient \ + IdRawFunctions \ + IdRawHeaders \ + IdReply \ + IdReplyRFC \ + IdResourceStringsCore \ + IdSchedulerOfThreadDefault \ + IdSchedulerOfThread \ + IdSchedulerOfThreadPool \ + IdScheduler \ + IdServerIOHandler \ + IdServerIOHandlerSocket \ + IdServerIOHandlerStack \ + IdSimpleServer \ + IdSocketHandle \ + IdSocks \ + IdSync \ + IdTask \ + IdTCPClient \ + IdTCPConnection \ + IdTCPServer \ + IdTCPStream \ + IdThreadComponent \ + IdThread \ + IdThreadSafe \ + IdTraceRoute \ + IdUDPBase \ + IdUDPClient \ + IdUDPServer \ + IdYarn + + +[install] +fpcpackage=y +fpcsubdir=packages/extra +buildunit=indycorefpc diff --git a/Lib/Protocols/Makefile.fpc b/Lib/Protocols/Makefile.fpc index 5582c92c1..f38bf0c66 100644 --- a/Lib/Protocols/Makefile.fpc +++ b/Lib/Protocols/Makefile.fpc @@ -1,346 +1,270 @@ -# Makefile.fpc for indycorefpc 10.6.3.0 - -[package] -name=indyprotocolsfpc -version=10.6.3.0 -main=indy - -[compiler] -includedir=../Inc -unittargetdir=lib/$(CPU_TARGET)-$(OS_TARGET) -unitdir=../System/lib/$(CPU_TARGET)-$(OS_TARGET) \ - ../Core/lib/$(CPU_TARGET)-$(OS_TARGET) -options=-gl - -[target] -units=indyprotocolsfpc -rsts=IdResourceStringsProtocols -rsts_amiga= -rsts_atari= -rsts_beos= -rsts_darwin=IdZLibConst -rsts_emx= -rsts_freebsd=IdZLibConst -rsts_go32v1= -rsts_go32v2= -rsts_linux=IdZLibConst -rsts_macos= -rsts_morphos= -rsts_netbsd=IdZLibConst -rsts_netware= -rsts_netwlibc= -rsts_openbsd=IdZLibConst -rsts_os2= -rsts_palmos= -rsts_qnx=IdZLibConst -rsts_solaris=IdZLibConst -rsts_watcom= -rsts_win32=IdZLibConst -rsts_win64= -rsts_wince= -rsts_gba= -implicitunits=IdASN1Util \ - IdAllAuthentications \ - IdAllFTPListParsers \ - IdAllHeaderCoders \ - IdAttachment \ - IdAttachmentFile \ - IdAttachmentMemory \ - IdAuthentication \ - IdAuthenticationDigest \ - IdAuthenticationManager \ - IdBlockCipherIntercept \ - IdChargenServer \ - IdChargenUDPServer \ - IdCharsets \ - IdCoder \ - IdCoder00E \ - IdCoder3to4 \ - IdCoderBinHex4 \ - IdCoderHeader \ - IdCoderMIME \ - IdCoderQuotedPrintable \ - IdCoderUUE \ - IdCoderXXE \ - IdConnectThroughHttpProxy \ - IdContainers \ - IdCookie \ - IdCookieManager \ - IdCustomHTTPServer \ - IdDICT \ - IdDICTCommon \ - IdDICTServer \ - IdDNSCommon \ - IdDNSResolver \ - IdDNSServer \ - IdDateTimeStamp \ - IdDayTime \ - IdDayTimeServer \ - IdDayTimeUDP \ - IdDayTimeUDPServer \ - IdDiscardServer \ - IdDiscardUDPServer \ - IdEMailAddress \ - IdEcho \ - IdEchoServer \ - IdEchoUDP \ - IdEchoUDPServer \ - IdExplicitTLSClientServerBase \ - IdFIPS \ - IdFSP \ - IdFTP \ - IdFTPBaseFileSystem \ - IdFTPCommon \ - IdFTPList \ - IdFTPListOutput \ - IdFTPListParseAS400 \ - IdFTPListParseBase \ - IdFTPListParseBullGCOS7 \ - IdFTPListParseBullGCOS8 \ - IdFTPListParseChameleonNewt \ - IdFTPListParseCiscoIOS \ - IdFTPListParseDistinctTCPIP \ - IdFTPListParseEPLF \ - IdFTPListParseHellSoft \ - IdFTPListParseIEFTPGateway \ - IdFTPListParseKA9Q \ - IdFTPListParseMPEiX \ - IdFTPListParseMVS \ - IdFTPListParseMicrowareOS9 \ - IdFTPListParseMusic \ - IdFTPListParseNCSAForDOS \ - IdFTPListParseNCSAForMACOS \ - IdFTPListParseNovellNetware \ - IdFTPListParseNovellNetwarePSU \ - IdFTPListParseOS2 \ - IdFTPListParsePCNFSD \ - IdFTPListParsePCTCP \ - IdFTPListParseStercomOS390Exp \ - IdFTPListParseStercomUnixEnt \ - IdFTPListParseStratusVOS \ - IdFTPListParseSuperTCP \ - IdFTPListParseTOPS20 \ - IdFTPListParseTSXPlus \ - IdFTPListParseTandemGuardian \ - IdFTPListParseUnisysClearPath \ - IdFTPListParseUnix \ - IdFTPListParseVM \ - IdFTPListParseVMS \ - IdFTPListParseVSE \ - IdFTPListParseVxWorks \ - IdFTPListParseWfFTP \ - IdFTPListParseWinQVTNET \ - IdFTPListParseWindowsNT \ - IdFTPListParseXecomMicroRTOS \ - IdFTPListTypes \ - IdFTPServer \ - IdFTPServerContextBase \ - IdFinger \ - IdFingerServer \ - IdGlobalProtocols \ - IdGopher \ - IdGopherConsts \ - IdGopherServer \ - IdHMAC \ - IdHMACMD5 \ - IdHMACSHA1 \ - IdHTTP \ - IdHTTPHeaderInfo \ - IdHTTPProxyServer \ - IdHTTPServer \ - IdHash \ - IdHashAdler32 \ - IdHashCRC \ - IdHashElf \ - IdHashMessageDigest \ - IdHashSHA \ - IdHeaderCoder2022JP \ - IdHeaderCoderBase \ - IdHeaderCoderIndy \ - IdHeaderCoderPlain \ - IdHeaderCoderUTF \ - IdHeaderList \ - IdIMAP4 \ - IdIMAP4Server \ - IdIPAddrMon \ - IdIPWatch \ - IdIRC \ - IdIdent \ - IdIdentServer \ - IdIrcServer \ - IdLPR \ - IdMailBox \ - IdMappedFTP \ - IdMappedPOP3 \ - IdMappedPortTCP \ - IdMappedPortUDP \ - IdMappedTelnet \ - IdMessage \ - IdMessageBuilder \ - IdMessageClient \ - IdMessageCoder \ - IdMessageCoderBinHex4 \ - IdMessageCoderMIME \ - IdMessageCoderQuotedPrintable \ - IdMessageCoderUUE \ - IdMessageCoderXXE \ - IdMessageCoderYenc \ - IdMessageCollection \ - IdMessageParts \ - IdMultipartFormData \ - IdNNTP \ - IdNNTPServer \ - IdNetworkCalculator \ - IdOSFileName \ - IdOTPCalculator \ - IdPOP3 \ - IdPOP3Server \ - IdQOTDUDP \ - IdQOTDUDPServer \ - IdQotd \ - IdQotdServer \ - IdRSH \ - IdRSHServer \ - IdRemoteCMDClient \ - IdRemoteCMDServer \ - IdReplyFTP \ - IdReplyIMAP4 \ - IdReplyPOP3 \ - IdReplySMTP \ - IdResourceStringsProtocols \ - IdRexec \ - IdRexecServer \ - IdSASL \ - IdSASLAnonymous \ - IdSASLCollection \ - IdSASLDigest \ - IdSASLExternal \ - IdSASLLogin \ - IdSASLOTP \ - IdSASLPlain \ - IdSASLSKey \ - IdSASLUserPass \ - IdSASL_CRAMBase \ - IdSASL_CRAM_MD5 \ - IdSASL_CRAM_SHA1 \ - IdSMTP \ - IdSMTPBase \ - IdSMTPRelay \ - IdSMTPServer \ - IdSNMP \ - IdSNPP \ - IdSNTP \ - IdSSL \ - IdServerInterceptLogBase \ - IdServerInterceptLogEvent \ - IdServerInterceptLogFile \ - IdStrings \ - IdSysLog \ - IdSysLogMessage \ - IdSysLogServer \ - IdSystat \ - IdSystatServer \ - IdSystatUDP \ - IdSystatUDPServer \ - IdTelnet \ - IdTelnetServer \ - IdText \ - IdTime \ - IdTimeServer \ - IdTimeUDP \ - IdTimeUDPServer \ - IdTrivialFTP \ - IdTrivialFTPBase \ - IdTrivialFTPServer \ - IdURI \ - IdUnixTime \ - IdUnixTimeServer \ - IdUnixTimeUDP \ - IdUnixTimeUDPServer \ - IdUriUtils \ - IdUserAccounts \ - IdUserPassProvider \ - IdVCard \ - IdWebDAV \ - IdWhoIsServer \ - IdWhois \ - IdZLibCompressorBase - -implicitunits_amiga= -units_amiga= -implicitunits_atari= -units_atari= -implicitunits_beos= -units_beos= -implicitunits_darwin=IdSSLOpenSSLHeaders IdZLibHeaders \ - IdZLib IdZLibConst IdNTLM -units_darwin=IdCompressorZLib IdSSLOpenSSL IdCompressionIntercept IdAuthenticationNTLM -implicitunits_emx= -units_emx= -implicitunits_freebsd=IdSSLOpenSSLHeaders IdZLibHeaders \ - IdZLib IdZLibConst IdNTLM -units_freebsd=IdCompressorZLib IdSSLOpenSSL \ - IdCompressionIntercept IdAuthenticationNTLM -implicitunits_go_32v1= -units_go32v1= -implicitunits_go32v2= -units_go32v2= -implicitunits_linux=IdSSLOpenSSLHeaders IdZLibHeaders \ - IdZLib IdZLibConst IdNTLM -units_linux=IdCompressorZLib IdSSLOpenSSL \ -IdCompressionIntercept IdAuthenticationNTLM -implicitunits_macos= -units_macos= -implicitunits_morphos= -units_morphos= -implicitunits_netbsd=IdSSLOpenSSLHeaders IdZLibHeaders \ - IdZLib IdZLibConst IdNTLM -units_netbsd=IdCompressorZLib IdSSLOpenSSL \ - IdCompressionIntercept IdAuthenticationNTLM -implicitunits_netware= -units_netware= -implicitunits_netwlibc= -units_netwlibc= -implicitunits_openbsd=IdSSLOpenSSLHeaders IdZLibHeaders \ - IdZLib IdZLibConst IdNTLM -units_openbsd=IdCompressorZLib IdSSLOpenSSL \ -IdCompressionIntercept IdAuthenticationNTLM -implicitunits_os2= -units_os2= -implicitunits_palmos= -units_palmos= -implicitunits_qnx=IdSSLOpenSSLHeaders IdZLibHeaders \ - IdZLib IdZLibConst IdNTLM -units_qnx=IdCompressorZLib IdSSLOpenSSL IdCompressionIntercept IdAuthenticationNTLM -implicitunits_solaris=IdSSLOpenSSLHeaders IdZLibHeaders \ - IdZLib IdZLibConst IdNTLM -units_solaris=IdCompressorZLib IdSSLOpenSSL \ - IdCompressionIntercept IdAuthenticationNTLM -implicitunits_watcom= -units_watcom= -implicitunits_win32=IdSSLOpenSSLHeaders IdZLibHeaders \ - IdZLib IdZLibConst IdNTLM IdSSPI -units_win32=IdCompressorZLib IdSSLOpenSSL \ - IdCompressionIntercept IdAuthenticationNTLM \ - IdAuthenticationSSPI -implicitunits_win64=IdSSLOpenSSLHeaders IdZLibHeaders \ - IdZLib IdZLibConst IdNTLM IdSSPI -units_win64=IdCompressorZLib IdSSLOpenSSL \ - IdCompressionIntercept IdAuthenticationNTLM \ - IdAuthenticationSSPI -implicitunits_wince= -units_wince= -implicitunits_wdosx= -units_wdosx= -implicitunits_gba= -units_gba= -[requires] -packages=indycorefpc -packagedir=../System/lib/$(CPU_TARGET)-$(OS_TARGET)/:../Core/lib/$(CPU_TARGET)-$(OS_TARGET)/ - -[install] -fpcpackage=y -fpcsubdir=packages/extra - -[shared] -build=n +[package] +name=indyprotocols +version=$(INDY_VERSION) +main=indy + +[requires] +packages=indycore + +[compiler] +options= -MDelphi $(OPT) -Scghi -CX -Ur -Xs -vew +unittargetdir= ../../units/$(CPU_TARGET)-$(OS_TARGET) +includedir=../../includes +unitdir=. + +[target] +units=indyprotocolsfpc +implicitunits=IdAllAuthentications \ + IdAllFTPListParsers \ + IdAllHeaderCoders \ + IdASN1Util \ + IdAttachmentFile \ + IdAttachmentMemory \ + IdAttachment \ + IdAuthenticationDigest \ + IdAuthenticationManager \ + IdAuthenticationNTLM \ + IdAuthentication \ + IdAuthenticationSSPI \ + IdBlockCipherIntercept \ + IdChargenServer \ + IdChargenUDPServer \ + IdCharsets \ + IdCoder00E \ + IdCoder3to4 \ + IdCoderBinHex4 \ + IdCoderHeader \ + IdCoderMIME \ + IdCoder \ + IdCoderQuotedPrintable \ + IdCoderUUE \ + IdCoderXXE \ + IdCompressionIntercept \ + IdCompressorZLib \ + IdConnectThroughHttpProxy \ + IdContainers \ + IdCookieManager \ + IdCookie \ + IdCustomHTTPServer \ + IdDateTimeStamp \ + IdDayTime \ + IdDayTimeServer \ + IdDayTimeUDP \ + IdDayTimeUDPServer \ + IdDICTCommon \ + IdDICT \ + IdDICTServer \ + IdDiscardServer \ + IdDiscardUDPServer \ + IdDNSCommon \ + IdDNSResolver \ + IdDNSServer \ + IdEcho \ + IdEchoServer \ + IdEchoUDP \ + IdEchoUDPServer \ + IdEMailAddress \ + IdExplicitTLSClientServerBase \ + IdFinger \ + IdFingerServer \ + IdFIPS \ + IdFSP \ + IdFTPBaseFileSystem \ + IdFTPCommon \ + IdFTPListOutput \ + IdFTPListParseAS400 \ + IdFTPListParseBase \ + IdFTPListParseBullGCOS7 \ + IdFTPListParseBullGCOS8 \ + IdFTPListParseChameleonNewt \ + IdFTPListParseCiscoIOS \ + IdFTPListParseDistinctTCPIP \ + IdFTPListParseEPLF \ + IdFTPListParseHellSoft \ + IdFTPListParseIEFTPGateway \ + IdFTPListParseKA9Q \ + IdFTPListParseMicrowareOS9 \ + IdFTPListParseMPEiX \ + IdFTPListParseMusic \ + IdFTPListParseMVS \ + IdFTPListParseNCSAForDOS \ + IdFTPListParseNCSAForMACOS \ + IdFTPListParseNovellNetware \ + IdFTPListParseNovellNetwarePSU \ + IdFTPListParseOS2 \ + IdFTPListParsePCNFSD \ + IdFTPListParsePCTCP \ + IdFTPListParseStercomOS390Exp \ + IdFTPListParseStercomUnixEnt \ + IdFTPListParseStratusVOS \ + IdFTPListParseSuperTCP \ + IdFTPListParseTandemGuardian \ + IdFTPListParseTOPS20 \ + IdFTPListParseTSXPlus \ + IdFTPListParseUnisysClearPath \ + IdFTPListParseUnix \ + IdFTPListParseVM \ + IdFTPListParseVMS \ + IdFTPListParseVSE \ + IdFTPListParseVxWorks \ + IdFTPListParseWfFTP \ + IdFTPListParseWindowsNT \ + IdFTPListParseWinQVTNET \ + IdFTPListParseXecomMicroRTOS \ + IdFTPList \ + IdFTPListTypes \ + IdFTP \ + IdFTPServerContextBase \ + IdFTPServer \ + IdGlobalProtocols \ + IdGopherConsts \ + IdGopher \ + IdGopherServer \ + IdHashAdler32 \ + IdHashCRC \ + IdHashElf \ + IdHashMessageDigest \ + IdHash \ + IdHashSHA \ + IdHeaderCoder2022JP \ + IdHeaderCoderBase \ + IdHeaderCoderIndy \ + IdHeaderCoderPlain \ + IdHeaderList \ + IdHL7 \ + IdHMACMD5 \ + IdHMAC \ + IdHMACSHA1 \ + IdHTTPHeaderInfo \ + IdHTTP \ + IdHTTPProxyServer \ + IdHTTPServer \ + IdIdent \ + IdIdentServer \ + IdIMAP4 \ + IdIMAP4Server \ + IdIPAddrMon \ + IdIPWatch \ + IdIRC \ + IdIrcServer \ + IdLPR \ + IdMailBox \ + IdMappedFTP \ + IdMappedPOP3 \ + IdMappedPortTCP \ + IdMappedPortUDP \ + IdMappedTelnet \ + IdMessageBuilder \ + IdMessageClient \ + IdMessageCoderBinHex4 \ + IdMessageCoderMIME \ + IdMessageCoder \ + IdMessageCoderQuotedPrintable \ + IdMessageCoderUUE \ + IdMessageCoderXXE \ + IdMessageCoderYenc \ + IdMessageCollection \ + IdMessageHelper \ + IdMessageParts \ + IdMessage \ + IdMultipartFormData \ + IdNetworkCalculator \ + IdNNTP \ + IdNNTPServer \ + IdNTLM \ + IdNTLMv2 \ + IdOSFileName \ + IdOTPCalculator \ + IdPOP3 \ + IdPOP3Server \ + IdQotd \ + IdQotdServer \ + IdQOTDUDP \ + IdQOTDUDPServer \ + IdRemoteCMDClient \ + IdRemoteCMDServer \ + IdReplyFTP \ + IdReplyIMAP4 \ + IdReplyPOP3 \ + IdReplySMTP \ + IdResourceStringsProtocols \ + IdResourceStringsSSPI \ + IdResourceStringsUriUtils \ + IdRexec \ + IdRexecServer \ + IdRSH \ + IdRSHServer \ + IdSASLAnonymous \ + IdSASLCollection \ + IdSASL_CRAMBase \ + IdSASL_CRAM_MD5 \ + IdSASL_CRAM_SHA1 \ + IdSASLDigest \ + IdSASLExternal \ + IdSASLLogin \ + IdSASLOTP \ + IdSASL \ + IdSASLPlain \ + IdSASLSKey \ + IdSASLUserPass \ + IdServerInterceptLogBase \ + IdServerInterceptLogEvent \ + IdServerInterceptLogFile \ + IdSMTPBase \ + IdSMTP \ + IdSMTPRelay \ + IdSMTPServer \ + IdSNMP \ + IdSNPP \ + IdSNTP \ + IdSocksServer \ + IdSSL \ + IdSSPI \ + IdStrings \ + IdSysLogMessage \ + IdSysLog \ + IdSysLogServer \ + IdSystat \ + IdSystatServer \ + IdSystatUDP \ + IdSystatUDPServer \ + IdTelnet \ + IdTelnetServer \ + IdText \ + IdTime \ + IdTimeServer \ + IdTimeUDP \ + IdTimeUDPServer \ + IdTrivialFTPBase \ + IdTrivialFTP \ + IdTrivialFTPServer \ + IdUnixTime \ + IdUnixTimeServer \ + IdUnixTimeUDP \ + IdUnixTimeUDPServer \ + IdURI \ + IdUriUtils \ + IdUserAccounts \ + IdUserPassProvider \ + IdVCard \ + IdWebDAV \ + IdWhois \ + IdWhoIsServer \ + IdZLibCompressorBase \ + IdZLibConst \ + IdZLibHeaders \ + IdZLib + + +[install] +fpcpackage=y +fpcsubdir=packages/extra +buildunit=indyprotocolsfpc + +[clean] +files=../../units/$(CPU_TARGET)-$(OS_TARGET)/IdResourceStringsCore.rsj \ + ../../units/$(CPU_TARGET)-$(OS_TARGET)/IdResourceStringsProtocols.rsj \ + ../../units/$(CPU_TARGET)-$(OS_TARGET)/IdResourceStrings.rsj \ + ../../units/$(CPU_TARGET)-$(OS_TARGET)/IdResourceStringsSSPI.rsj \ + ../../units/$(CPU_TARGET)-$(OS_TARGET)/IdResourceStringsUnix.rsj \ + ../../units/$(CPU_TARGET)-$(OS_TARGET)/IdResourceStringsUriUtils.rsj diff --git a/Lib/System/Makefile.fpc b/Lib/System/Makefile.fpc index eb2dec373..fcbf3151d 100644 --- a/Lib/System/Makefile.fpc +++ b/Lib/System/Makefile.fpc @@ -1,67 +1,21 @@ -# Makefile.fpc for indysystemfpc 10.6.3.0 - -[package] -name=indysystemfpc -version=10.6.3.0 -main=indy - -[require] -packages=fcl-base - -[compiler] -includedir=../Inc -unittargetdir=lib/$(CPU_TARGET)-$(OS_TARGET) -unitdir=lib/$(CPU_TARGET)-$(OS_TARGET) -options=-gl - -#Note that we use implicitunits_TARGETOS for all -#so we can easily modify things when new targets -#are added. We have to think years down the line. -[target] -units=indysystemfpc -rsts=IdResourceStrings -implicitunits=IdAntiFreezeBase \ - IdBaseComponent \ - IdCTypes \ - IdComponent \ - IdException \ - IdGlobal \ - IdResourceStrings \ - IdStack \ - IdStackConsts \ - IdStream \ - IdStreamVCL \ - IdStruct - -implicitunits_amiga= -implicitunits_atari= -implicitunits_beos= -implicitunits_darwin=IdStackUnix IdStackBSDBase -implicitunits_emx= -implicitunits_freebsd=IdStackUnix IdStackBSDBase -implicitunits_go32v1= -implicitunits_go32v2= -implicitunits_linux=IdStackUnix IdStackBSDBase -implicitunits_macos= -implicitunits_morphos= -implicitunits_netbsd=IdStackUnix IdStackBSDBase -implicitunits_netware= -implicitunits_netwlibc= -implicitunits_openbsd=IdStackUnix IdStackBSDBase -implicitunits_os2= -implicitunits_palmos= -implicitunits_qnx=IdStackUnix IdStackBSDBase -implicitunits_solaris=IdStackUnix IdStackBSDBase -implicitunits_watcom= -implicitunits_win32=IdStackBSDBase IdStackWindows IdWinsock2 IdWship6 -implicitunits_win64=IdStackBSDBase IdStackWindows IdWinsock2 IdWship6 -implicitunits_wince=IdStackBSDBase IdStackWindows IdWinsock2 IdWship6 -implicitunits_wdosx= - -[install] -fpcpackage=y -fpcsubdir=packages/extra -buildunit=indysystemfpc - -[shared] -build=n +[package] +name=indysystem +version=$(INDY_VERSION) +main=indy + +[requires] +packages=fcl-base + +[compiler] +options= -MDelphi $(OPT) -Scghi -CX -Ur -Xs -vew +unittargetdir= ../../units/$(CPU_TARGET)-$(OS_TARGET) +includedir=. +unitdir=. + +[target] +units=indysystemfpc + +[install] +fpcpackage=y +fpcsubdir=packages/extra +buildunit=indysystemfpc diff --git a/fpmake.pp b/fpmake.pp deleted file mode 100644 index 56be6643b..000000000 --- a/fpmake.pp +++ /dev/null @@ -1,394 +0,0 @@ -{$mode objfpc}{$H+} -program fpmake; - - { Generated automatically by fppkg on 17-10-10 } - -uses fpmkunit; - -function AddIndyUnit(P : TPackage; const AFileName : String) : TTarget; inline; -begin - - Result:=P.Targets.AddUnit(AFileName); - Result.Dependencies.AddInclude('IdCompilerDefines.inc'); -end; - -const - {$I IdVers.inc} - -Var - P : TPackage; - T : TTarget; - D : TDependency; - -begin - With Installer do - begin - { - indy - } - P:=AddPackage(gsIdProductName); - P.Version:=gsIdVersion; - P.Dependencies.Add('fcl-base'); - D:=P.Dependencies.Add('iconvenc'); - D.OSes:=AllUnixOSes; - {$IFDEF KYLIXCOMPAT} - D:=P.Dependencies.Add('libc'); - D.OSes:=[linux]; - D.CPUs:=[i386]; - D:=P.Dependencies.Add('fcl-net'); - D.OSes:=[linux]; - D.CPUs:=T.CPUs - [i386]; - D:=P.Dependencies.Add('fcl-net'); - D.OSes:=AllUnixOSes - [linux]; - {$ELSE} - D:=P.Dependencies.Add('fcl-net'); - D.OSes:=AllUnixOSes; - {$ENDIF} - T:=P.Targets.AddUnit('indysystemfpc.pas'); - T:=P.Targets.AddUnit('indycorefpc.pas'); - T:=P.Targets.AddUnit('indyprotocolsfpc.pas'); - T:=AddIndyUnit(P,'IdASN1Util.pas'); - T:=AddIndyUnit(P,'IdAllAuthentications.pas'); - T:=AddIndyUnit(P,'IdAllFTPListParsers.pas'); - T:=AddIndyUnit(P,'IdAllHeaderCoders.pas'); - T:=AddIndyUnit(P,'IdAntiFreezeBase.pas'); - T:=AddIndyUnit(P,'IdAssignedNumbers.pas'); - T:=AddIndyUnit(P,'IdAttachment.pas'); - T:=AddIndyUnit(P,'IdAttachmentFile.pas'); - T:=AddIndyUnit(P,'IdAttachmentMemory.pas'); - T:=AddIndyUnit(P,'IdAuthentication.pas'); - T:=AddIndyUnit(P,'IdAuthenticationDigest.pas'); - T:=AddIndyUnit(P,'IdAuthenticationManager.pas'); - T:=AddIndyUnit(P,'IdBaseComponent.pas'); - T:=AddIndyUnit(P,'IdBlockCipherIntercept.pas'); - T:=AddIndyUnit(P,'IdBuffer.pas'); - T:=AddIndyUnit(P,'IdCTypes.pas'); - T:=AddIndyUnit(P,'IdChargenServer.pas'); - T:=AddIndyUnit(P,'IdChargenUDPServer.pas'); - T:=AddIndyUnit(P,'IdCharsets.pas'); - T:=AddIndyUnit(P,'IdCmdTCPClient.pas'); - T:=AddIndyUnit(P,'IdCmdTCPServer.pas'); - T:=AddIndyUnit(P,'IdCoder.pas'); - T:=AddIndyUnit(P,'IdCoder00E.pas'); - T:=AddIndyUnit(P,'IdCoder3to4.pas'); - T:=AddIndyUnit(P,'IdCoderBinHex4.pas'); - T:=AddIndyUnit(P,'IdCoderHeader.pas'); - T:=AddIndyUnit(P,'IdCoderMIME.pas'); - T:=AddIndyUnit(P,'IdCoderQuotedPrintable.pas'); - T:=AddIndyUnit(P,'IdCoderUUE.pas'); - T:=AddIndyUnit(P,'IdCoderXXE.pas'); - T:=AddIndyUnit(P,'IdCommandHandlers.pas'); - T:=AddIndyUnit(P,'IdComponent.pas'); - T:=AddIndyUnit(P,'IdConnectThroughHttpProxy.pas'); - T:=AddIndyUnit(P,'IdContainers.pas'); - T:=AddIndyUnit(P,'IdContext.pas'); - T:=AddIndyUnit(P,'IdCookie.pas'); - T:=AddIndyUnit(P,'IdCookieManager.pas'); - T:=AddIndyUnit(P,'IdCustomHTTPServer.pas'); - T:=AddIndyUnit(P,'IdCustomTCPServer.pas'); - T:=AddIndyUnit(P,'IdCustomTransparentProxy.pas'); - T:=AddIndyUnit(P,'IdDICT.pas'); - T:=AddIndyUnit(P,'IdDICTCommon.pas'); - T:=AddIndyUnit(P,'IdDICTServer.pas'); - T:=AddIndyUnit(P,'IdDNSCommon.pas'); - T:=AddIndyUnit(P,'IdDNSResolver.pas'); - T:=AddIndyUnit(P,'IdDNSServer.pas'); - T:=AddIndyUnit(P,'IdDateTimeStamp.pas'); - T:=AddIndyUnit(P,'IdDayTime.pas'); - T:=AddIndyUnit(P,'IdDayTimeServer.pas'); - T:=AddIndyUnit(P,'IdDayTimeUDP.pas'); - T:=AddIndyUnit(P,'IdDayTimeUDPServer.pas'); - T:=AddIndyUnit(P,'IdDiscardServer.pas'); - T:=AddIndyUnit(P,'IdDiscardUDPServer.pas'); - T:=AddIndyUnit(P,'IdEMailAddress.pas'); - T:=AddIndyUnit(P,'IdEcho.pas'); - T:=AddIndyUnit(P,'IdEchoServer.pas'); - T:=AddIndyUnit(P,'IdEchoUDP.pas'); - T:=AddIndyUnit(P,'IdEchoUDPServer.pas'); - T:=AddIndyUnit(P,'IdException.pas'); - T:=AddIndyUnit(P,'IdExceptionCore.pas'); - T:=AddIndyUnit(P,'IdExplicitTLSClientServerBase.pas'); - T:=AddIndyUnit(P,'IdFIPS.pas'); - T:=AddIndyUnit(P,'IdFSP.pas'); - T:=AddIndyUnit(P,'IdFTP.pas'); - T:=AddIndyUnit(P,'IdFTPBaseFileSystem.pas'); - T:=AddIndyUnit(P,'IdFTPCommon.pas'); - T:=AddIndyUnit(P,'IdFTPList.pas'); - T:=AddIndyUnit(P,'IdFTPListOutput.pas'); - T:=AddIndyUnit(P,'IdFTPListParseAS400.pas'); - T:=AddIndyUnit(P,'IdFTPListParseBase.pas'); - T:=AddIndyUnit(P,'IdFTPListParseBullGCOS7.pas'); - T:=AddIndyUnit(P,'IdFTPListParseBullGCOS8.pas'); - T:=AddIndyUnit(P,'IdFTPListParseChameleonNewt.pas'); - T:=AddIndyUnit(P,'IdFTPListParseCiscoIOS.pas'); - T:=AddIndyUnit(P,'IdFTPListParseDistinctTCPIP.pas'); - T:=AddIndyUnit(P,'IdFTPListParseEPLF.pas'); - T:=AddIndyUnit(P,'IdFTPListParseHellSoft.pas'); - T:=AddIndyUnit(P,'IdFTPListParseIEFTPGateway.pas'); - T:=AddIndyUnit(P,'IdFTPListParseKA9Q.pas'); - T:=AddIndyUnit(P,'IdFTPListParseMPEiX.pas'); - T:=AddIndyUnit(P,'IdFTPListParseMVS.pas'); - T:=AddIndyUnit(P,'IdFTPListParseMicrowareOS9.pas'); - T:=AddIndyUnit(P,'IdFTPListParseMusic.pas'); - T:=AddIndyUnit(P,'IdFTPListParseNCSAForDOS.pas'); - T:=AddIndyUnit(P,'IdFTPListParseNCSAForMACOS.pas'); - T:=AddIndyUnit(P,'IdFTPListParseNovellNetware.pas'); - T:=AddIndyUnit(P,'IdFTPListParseNovellNetwarePSU.pas'); - T:=AddIndyUnit(P,'IdFTPListParseOS2.pas'); - T:=AddIndyUnit(P,'IdFTPListParsePCNFSD.pas'); - T:=AddIndyUnit(P,'IdFTPListParsePCTCP.pas'); - T:=AddIndyUnit(P,'IdFTPListParseStercomOS390Exp.pas'); - T:=AddIndyUnit(P,'IdFTPListParseStercomUnixEnt.pas'); - T:=AddIndyUnit(P,'IdFTPListParseStratusVOS.pas'); - T:=AddIndyUnit(P,'IdFTPListParseSuperTCP.pas'); - T:=AddIndyUnit(P,'IdFTPListParseTOPS20.pas'); - T:=AddIndyUnit(P,'IdFTPListParseTSXPlus.pas'); - T:=AddIndyUnit(P,'IdFTPListParseTandemGuardian.pas'); - T:=AddIndyUnit(P,'IdFTPListParseUnisysClearPath.pas'); - T:=AddIndyUnit(P,'IdFTPListParseUnix.pas'); - T:=AddIndyUnit(P,'IdFTPListParseVM.pas'); - T:=AddIndyUnit(P,'IdFTPListParseVMS.pas'); - T:=AddIndyUnit(P,'IdFTPListParseVSE.pas'); - T:=AddIndyUnit(P,'IdFTPListParseVxWorks.pas'); - T:=AddIndyUnit(P,'IdFTPListParseWfFTP.pas'); - T:=AddIndyUnit(P,'IdFTPListParseWinQVTNET.pas'); - T:=AddIndyUnit(P,'IdFTPListParseWindowsNT.pas'); - T:=AddIndyUnit(P,'IdFTPListParseXecomMicroRTOS.pas'); - T:=AddIndyUnit(P,'IdFTPListTypes.pas'); - T:=AddIndyUnit(P,'IdFTPServer.pas'); - T:=AddIndyUnit(P,'IdFTPServerContextBase.pas'); - T:=AddIndyUnit(P,'IdFinger.pas'); - T:=AddIndyUnit(P,'IdFingerServer.pas'); - T:=AddIndyUnit(P,'IdGlobal.pas'); - T.Dependencies.AddInclude('IdVers.inc'); - T:=AddIndyUnit(P,'IdGlobalCore.pas'); - T:=AddIndyUnit(P,'IdGlobalProtocols.pas'); - T:=AddIndyUnit(P,'IdGopher.pas'); - T:=AddIndyUnit(P,'IdGopherConsts.pas'); - T:=AddIndyUnit(P,'IdGopherServer.pas'); - T:=AddIndyUnit(P,'IdHMAC.pas'); - T:=AddIndyUnit(P,'IdHMACMD5.pas'); - T:=AddIndyUnit(P,'IdHMACSHA1.pas'); - T:=AddIndyUnit(P,'IdHTTP.pas'); - T:=AddIndyUnit(P,'IdHTTPHeaderInfo.pas'); - T:=AddIndyUnit(P,'IdHTTPProxyServer.pas'); - T:=AddIndyUnit(P,'IdHTTPServer.pas'); - T:=AddIndyUnit(P,'IdHash.pas'); - T:=AddIndyUnit(P,'IdHashAdler32.pas'); - T:=AddIndyUnit(P,'IdHashCRC.pas'); - T:=AddIndyUnit(P,'IdHashElf.pas'); - T:=AddIndyUnit(P,'IdHashMessageDigest.pas'); - T:=AddIndyUnit(P,'IdHashSHA.pas'); - T:=AddIndyUnit(P,'IdHeaderCoder2022JP.pas'); - T:=AddIndyUnit(P,'IdHeaderCoderBase.pas'); - T:=AddIndyUnit(P,'IdHeaderCoderIndy.pas'); - T:=AddIndyUnit(P,'IdHeaderCoderPlain.pas'); - T:=AddIndyUnit(P,'IdHeaderCoderUTF.pas'); - T:=AddIndyUnit(P,'IdHeaderList.pas'); - T:=AddIndyUnit(P,'IdIMAP4.pas'); - T:=AddIndyUnit(P,'IdIMAP4Server.pas'); - T:=AddIndyUnit(P,'IdIOHandler.pas'); - T:=AddIndyUnit(P,'IdIOHandlerSocket.pas'); - T:=AddIndyUnit(P,'IdIOHandlerStack.pas'); - T:=AddIndyUnit(P,'IdIOHandlerStream.pas'); - T:=AddIndyUnit(P,'IdIPAddrMon.pas'); - T:=AddIndyUnit(P,'IdIPAddress.pas'); - T:=AddIndyUnit(P,'IdIPMCastBase.pas'); - T:=AddIndyUnit(P,'IdIPMCastClient.pas'); - T:=AddIndyUnit(P,'IdIPMCastServer.pas'); - T:=AddIndyUnit(P,'IdIPWatch.pas'); - T:=AddIndyUnit(P,'IdIRC.pas'); - T:=AddIndyUnit(P,'IdIcmpClient.pas'); - T:=AddIndyUnit(P,'IdIdent.pas'); - T:=AddIndyUnit(P,'IdIdentServer.pas'); - T:=AddIndyUnit(P,'IdIntercept.pas'); - T:=AddIndyUnit(P,'IdInterceptSimLog.pas'); - T:=AddIndyUnit(P,'IdInterceptThrottler.pas'); - T:=AddIndyUnit(P,'IdIrcServer.pas'); - T:=AddIndyUnit(P,'IdLPR.pas'); - T:=AddIndyUnit(P,'IdLogBase.pas'); - T:=AddIndyUnit(P,'IdLogDebug.pas'); - T:=AddIndyUnit(P,'IdLogEvent.pas'); - T:=AddIndyUnit(P,'IdLogFile.pas'); - T:=AddIndyUnit(P,'IdLogStream.pas'); - T:=AddIndyUnit(P,'IdMailBox.pas'); - T:=AddIndyUnit(P,'IdMappedFTP.pas'); - T:=AddIndyUnit(P,'IdMappedPOP3.pas'); - T:=AddIndyUnit(P,'IdMappedPortTCP.pas'); - T:=AddIndyUnit(P,'IdMappedPortUDP.pas'); - T:=AddIndyUnit(P,'IdMappedTelnet.pas'); - T:=AddIndyUnit(P,'IdMessage.pas'); - T:=AddIndyUnit(P,'IdMessageBuilder.pas'); - T:=AddIndyUnit(P,'IdMessageClient.pas'); - T:=AddIndyUnit(P,'IdMessageCoder.pas'); - T:=AddIndyUnit(P,'IdMessageCoderBinHex4.pas'); - T:=AddIndyUnit(P,'IdMessageCoderMIME.pas'); - T:=AddIndyUnit(P,'IdMessageCoderQuotedPrintable.pas'); - T:=AddIndyUnit(P,'IdMessageCoderUUE.pas'); - T:=AddIndyUnit(P,'IdMessageCoderXXE.pas'); - T:=AddIndyUnit(P,'IdMessageCoderYenc.pas'); - T:=AddIndyUnit(P,'IdMessageCollection.pas'); - T:=AddIndyUnit(P,'IdMessageParts.pas'); - T:=AddIndyUnit(P,'IdMultipartFormData.pas'); - T:=AddIndyUnit(P,'IdNNTP.pas'); - T:=AddIndyUnit(P,'IdNNTPServer.pas'); - T:=AddIndyUnit(P,'IdNetworkCalculator.pas'); - T:=AddIndyUnit(P,'IdOSFileName.pas'); - T:=AddIndyUnit(P,'IdOTPCalculator.pas'); - T:=AddIndyUnit(P,'IdPOP3.pas'); - T:=AddIndyUnit(P,'IdPOP3Server.pas'); - T:=AddIndyUnit(P,'IdQOTDUDP.pas'); - T:=AddIndyUnit(P,'IdQOTDUDPServer.pas'); - T:=AddIndyUnit(P,'IdQotd.pas'); - T:=AddIndyUnit(P,'IdQotdServer.pas'); - T:=AddIndyUnit(P,'IdRSH.pas'); - T:=AddIndyUnit(P,'IdRSHServer.pas'); - T:=AddIndyUnit(P,'IdRawBase.pas'); - T:=AddIndyUnit(P,'IdRawClient.pas'); - T:=AddIndyUnit(P,'IdRawFunctions.pas'); - T:=AddIndyUnit(P,'IdRawHeaders.pas'); - T:=AddIndyUnit(P,'IdRemoteCMDClient.pas'); - T:=AddIndyUnit(P,'IdRemoteCMDServer.pas'); - T:=AddIndyUnit(P,'IdReply.pas'); - T:=AddIndyUnit(P,'IdReplyFTP.pas'); - T:=AddIndyUnit(P,'IdReplyIMAP4.pas'); - T:=AddIndyUnit(P,'IdReplyPOP3.pas'); - T:=AddIndyUnit(P,'IdReplyRFC.pas'); - T:=AddIndyUnit(P,'IdReplySMTP.pas'); - T:=AddIndyUnit(P,'IdResourceStrings.pas'); - T.ResourceStrings:=True; - T:=AddIndyUnit(P,'IdResourceStringsCore.pas'); - T.ResourceStrings:=True; - T:=AddIndyUnit(P,'IdResourceStringsProtocols.pas'); - T.ResourceStrings:=True; - T:=AddIndyUnit(P,'IdRexec.pas'); - T:=AddIndyUnit(P,'IdRexecServer.pas'); - T:=AddIndyUnit(P,'IdSASL.pas'); - T:=AddIndyUnit(P,'IdSASLAnonymous.pas'); - T:=AddIndyUnit(P,'IdSASLCollection.pas'); - T:=AddIndyUnit(P,'IdSASLDigest.pas'); - T:=AddIndyUnit(P,'IdSASLExternal.pas'); - T:=AddIndyUnit(P,'IdSASLLogin.pas'); - T:=AddIndyUnit(P,'IdSASLOTP.pas'); - T:=AddIndyUnit(P,'IdSASLPlain.pas'); - T:=AddIndyUnit(P,'IdSASLSKey.pas'); - T:=AddIndyUnit(P,'IdSASLUserPass.pas'); - T:=AddIndyUnit(P,'IdSASL_CRAMBase.pas'); - T:=AddIndyUnit(P,'IdSASL_CRAM_MD5.pas'); - T:=AddIndyUnit(P,'IdSASL_CRAM_SHA1.pas'); - T:=AddIndyUnit(P,'IdSMTP.pas'); - T:=AddIndyUnit(P,'IdSMTPBase.pas'); - T:=AddIndyUnit(P,'IdSMTPRelay.pas'); - T:=AddIndyUnit(P,'IdSMTPServer.pas'); - T:=AddIndyUnit(P,'IdSNMP.pas'); - T:=AddIndyUnit(P,'IdSNPP.pas'); - T:=AddIndyUnit(P,'IdSNTP.pas'); - T:=AddIndyUnit(P,'IdSSL.pas'); - T:=AddIndyUnit(P,'IdScheduler.pas'); - T:=AddIndyUnit(P,'IdSchedulerOfThread.pas'); - T:=AddIndyUnit(P,'IdSchedulerOfThreadDefault.pas'); - T:=AddIndyUnit(P,'IdSchedulerOfThreadPool.pas'); - T:=AddIndyUnit(P,'IdServerIOHandler.pas'); - T:=AddIndyUnit(P,'IdServerIOHandlerSocket.pas'); - T:=AddIndyUnit(P,'IdServerIOHandlerStack.pas'); - T:=AddIndyUnit(P,'IdServerInterceptLogBase.pas'); - T:=AddIndyUnit(P,'IdServerInterceptLogEvent.pas'); - T:=AddIndyUnit(P,'IdServerInterceptLogFile.pas'); - T:=AddIndyUnit(P,'IdSimpleServer.pas'); - T:=AddIndyUnit(P,'IdSocketHandle.pas'); - T:=AddIndyUnit(P,'IdSocks.pas'); - T:=AddIndyUnit(P,'IdStack.pas'); - T:=AddIndyUnit(P,'IdStackConsts.pas'); - T:=AddIndyUnit(P,'IdStream.pas'); - T:=AddIndyUnit(P,'IdStreamVCL.pas'); - T:=AddIndyUnit(P,'IdStrings.pas'); - T:=AddIndyUnit(P,'IdStruct.pas'); - T:=AddIndyUnit(P,'IdSync.pas'); - T:=AddIndyUnit(P,'IdSysLog.pas'); - T:=AddIndyUnit(P,'IdSysLogMessage.pas'); - T:=AddIndyUnit(P,'IdSysLogServer.pas'); - T:=AddIndyUnit(P,'IdSystat.pas'); - T:=AddIndyUnit(P,'IdSystatServer.pas'); - T:=AddIndyUnit(P,'IdSystatUDP.pas'); - T:=AddIndyUnit(P,'IdSystatUDPServer.pas'); - T:=AddIndyUnit(P,'IdTCPClient.pas'); - T:=AddIndyUnit(P,'IdTCPConnection.pas'); - T:=AddIndyUnit(P,'IdTCPServer.pas'); - T:=AddIndyUnit(P,'IdTCPStream.pas'); - T:=AddIndyUnit(P,'IdTask.pas'); - T:=AddIndyUnit(P,'IdTelnet.pas'); - T:=AddIndyUnit(P,'IdTelnetServer.pas'); - T:=AddIndyUnit(P,'IdText.pas'); - T:=AddIndyUnit(P,'IdThread.pas'); - T:=AddIndyUnit(P,'IdThreadComponent.pas'); - T:=AddIndyUnit(P,'IdThreadSafe.pas'); - T:=AddIndyUnit(P,'IdTime.pas'); - T:=AddIndyUnit(P,'IdTimeServer.pas'); - T:=AddIndyUnit(P,'IdTimeUDP.pas'); - T:=AddIndyUnit(P,'IdTimeUDPServer.pas'); - T:=AddIndyUnit(P,'IdTraceRoute.pas'); - T:=AddIndyUnit(P,'IdTrivialFTP.pas'); - T:=AddIndyUnit(P,'IdTrivialFTPBase.pas'); - T:=AddIndyUnit(P,'IdTrivialFTPServer.pas'); - T:=AddIndyUnit(P,'IdUDPBase.pas'); - T:=AddIndyUnit(P,'IdUDPClient.pas'); - T:=AddIndyUnit(P,'IdUDPServer.pas'); - T:=AddIndyUnit(P,'IdURI.pas'); - T:=AddIndyUnit(P,'IdUnixTime.pas'); - T:=AddIndyUnit(P,'IdUnixTimeServer.pas'); - T:=AddIndyUnit(P,'IdUnixTimeUDP.pas'); - T:=AddIndyUnit(P,'IdUnixTimeUDPServer.pas'); - T:=AddIndyUnit(P,'IdUriUtils.pas'); - T:=AddIndyUnit(P,'IdUserAccounts.pas'); - T:=AddIndyUnit(P,'IdUserPassProvider.pas'); - T:=AddIndyUnit(P,'IdVCard.pas'); - T:=AddIndyUnit(P,'IdWebDAV.pas'); - T:=AddIndyUnit(P,'IdWhoIsServer.pas'); - T:=AddIndyUnit(P,'IdWhois.pas'); - T:=AddIndyUnit(P,'IdYarn.pas'); - T:=AddIndyUnit(P,'IdZLibCompressorBase.pas'); - - T:=AddIndyUnit(P,'IdStackBSDBase.pas'); - T.OSes:=AllUnixOSes + AllWindowsOSes; - T:=AddIndyUnit(P,'IdZLibHeaders.pas'); - T.OSes:=AllUnixOSes + [win32,win64]; - T:=AddIndyUnit(P,'IdZLib.pas'); - T.OSes:=AllUnixOSes + [win32,win64]; - T:=AddIndyUnit(P,'IdZLibConst.pas'); - T.OSes:=AllUnixOSes + [win32,win64]; - T.ResourceStrings:=True; - T:=AddIndyUnit(P,'IdNTLM.pas'); - T.OSes:=AllUnixOSes + [win32,win64]; - T:=AddIndyUnit(P,'IdCompressorZLib.pas'); - T.OSes:=AllUnixOSes + [win32,win64]; - T:=AddIndyUnit(P,'IdCompressionIntercept.pas'); - T.OSes:=AllUnixOSes + [win32,win64]; - T:=AddIndyUnit(P,'IdAuthenticationNTLM.pas'); - T.OSes:=AllUnixOSes + [win32,win64]; - {$IFDEF KYLIXCOMPAT} - T:=AddIndyUnit(P,'IdStackLibc.pas'); - T.OSes:=[linux]; - T.CPUs:=[i386]; - T:=AddIndyUnit(P,'IdStackUnix.pas'); - T.OSes:=[linux]; - T.CPUs:=T.CPUs - [i386]; - T:=AddIndyUnit(P,'IdStackUnix.pas'); - T.OSes:=AllUnixOSes - [linux]; - {$ELSE} - T:=AddIndyUnit(P,'IdStackUnix.pas'); - T.OSes:=AllUnixOSes; - {$ENDIF} - T:=AddIndyUnit(P,'IdStackWindows.pas'); - T.OSes:=AllWindowsOSes; - T:=AddIndyUnit(P,'IdWinsock2.pas'); - T.OSes:=AllWindowsOSes; - T:=AddIndyUnit(P,'IdWship6.pas'); - T.OSes:=AllWindowsOSes; - T:=AddIndyUnit(P,'IdSSPI.pas'); - T.OSes:=[win32,win64]; - T:=AddIndyUnit(P,'IdAuthenticationSSPI.pas'); - T.OSes:=[win32,win64]; - Run; - end; -end. - diff --git a/getindy.sh b/getindy.sh deleted file mode 100644 index 19c741974..000000000 --- a/getindy.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/sh -OS=`uname -s` -if [ "$OS" = 'Darwin' ] -then - S_PREFIX='/Volumes/E$/source/indy10/trunk' - FPCSRC=/Developer/FreePascalCompiler/$(fpc -iV)/Source -else - S_PREFIX='/mnt/hgfs/IndyTiburon' - FPCSRC=/usr/share/fpcsrc/$(fpc -iV) - if [ ! -d $FPCSRC ] - then - FPCSRC=/usr/share/fpcsrc - fi -fi -DOS2_UNIX='tr -d ''\r' -INDYVERSION=`cat $S_PREFIX/lib/System/IdVers.inc | grep ' *gsIdVersion *=.*;' | sed -e 's/[^0-9.]//g'` -INDYDIR=indy-$INDYVERSION -FPCINDYDIR=$INDYDIR/fpc -LAZINDYDIR=$INDYDIR/lazarus - -echo parameter 1 = $1 -if [ "$1" != "buildonly" ] -then - rm -rf $INDYDIR - mkdir -p $INDYDIR/fpc - - cp -p $S_PREFIX/lib/fpcnotes/* $INDYDIR - cp -p $S_PREFIX/lib/makeindyrpm.sh $INDYDIR - cp -p $S_PREFIX/lib/indy-fpc.spec.template $INDYDIR - FILENAMES=$(cat $S_PREFIX/lib/RTFileList.txt | $DOS2_UNIX | tr '\\' '/') - for i in $FILENAMES - do - cp -p $S_PREFIX//lib/$i $FPCINDYDIR - done - cp -p $S_PREFIX/lib/System/IdCompilerDefines.inc $FPCINDYDIR - cp -p $S_PREFIX/lib/System/IdVers.inc $FPCINDYDIR - cp -p $S_PREFIX/lib/System/indysystemfpc.pas $FPCINDYDIR - cp -p $S_PREFIX/lib/Core/indycorefpc.pas $FPCINDYDIR - cp -p $S_PREFIX/lib/Protocols/indyprotocolsfpc.pas $FPCINDYDIR - cp -p $S_PREFIX/lib/indymaster-Makefile.fpc $FPCINDYDIR/Makefile.fpc - mkdir -p $FPCINDYDIR/examples - cp -rp $S_PREFIX/lib/Examples/* $FPCINDYDIR/examples - find $FPCINDYDIR/examples -type d -name ".svn" -exec rm -rf '{}' \; - mkdir -p $FPCINDYDIR/debian - cp -rp $S_PREFIX/lib/debian/* $FPCINDYDIR/debian - find $FPCINDYDIR/debian -type d -name ".svn" -exec rm -rf '{}' \; -fi -make - -FPCDIR=$FPCSRC;export FPCDIR -cd $FPCINDYDIR -echo $(pwd) -fpcmake -rTall -make -cd examples -fpcmake -rTall -cd .. - - - - diff --git a/lazarus-fpc/indycore.lpk b/lazarus-fpc/indycore.lpk new file mode 100644 index 000000000..ea8c87dcd --- /dev/null +++ b/lazarus-fpc/indycore.lpk @@ -0,0 +1,284 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lazarus-fpc/indycore.pas b/lazarus-fpc/indycore.pas new file mode 100644 index 000000000..dc5bf1ca2 --- /dev/null +++ b/lazarus-fpc/indycore.pas @@ -0,0 +1,27 @@ +{ This file was automatically created by Lazarus. Do not edit! + This source is only used to compile and install the package. + } + +unit indycore; + +{$warn 5023 off : no warning about unused units} +interface + +uses + IdAssignedNumbers, IdBuffer, IdCmdTCPClient, IdCmdTCPServer, + IdCommandHandlers, IdContext, IdCustomTCPServer, IdCustomTransparentProxy, + IdExceptionCore, IdGlobalCore, IdIcmpClient, IdIntercept, IdInterceptSimLog, + IdInterceptThrottler, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, + IdIOHandlerStream, IdIPAddress, IdIPMCastBase, IdIPMCastClient, + IdIPMCastServer, IdLogBase, IdLogDebug, IdLogEvent, IdLogFile, IdLogStream, + IdRawBase, IdRawClient, IdRawFunctions, IdRawHeaders, IdReply, IdReplyRFC, + IdResourceStringsCore, IdScheduler, IdSchedulerOfThread, + IdSchedulerOfThreadDefault, IdSchedulerOfThreadPool, IdServerIOHandler, + IdServerIOHandlerSocket, IdServerIOHandlerStack, IdSimpleServer, + IdSocketHandle, IdSocks, IdSync, IdTask, IdTCPClient, IdTCPConnection, + IdTCPServer, IdTCPStream, IdThread, IdThreadComponent, IdThreadSafe, + IdTraceRoute, IdUDPBase, IdUDPClient, IdUDPServer, IdYarn; + +implementation + +end. diff --git a/lazarus-fpc/indylaz.lpk b/lazarus-fpc/indylaz.lpk new file mode 100644 index 000000000..b39c44e5a --- /dev/null +++ b/lazarus-fpc/indylaz.lpk @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lazarus-fpc/indylaz.pas b/lazarus-fpc/indylaz.pas new file mode 100644 index 000000000..ae9863ffa --- /dev/null +++ b/lazarus-fpc/indylaz.pas @@ -0,0 +1,29 @@ +{ This file was automatically created by Lazarus. Do not edit! + This source is only used to compile and install the package. + } + +unit indylaz; + +{$warn 5023 off : no warning about unused units} +interface + +uses + IdDsnBaseCmpEdt, IdDsnCoreResourceStrings, IdDsnPropEdBinding, + IdDsnPropEdBindingVCL, IdCoreDsnRegister, IdAboutVCL, IdDsnRegister, + IdDsnResourceStrings, IdDsnSASLListEditor, IdDsnSASLListEditorForm, + IdDsnSASLListEditorFormVCL, IdAbout, IdRegisterCore, IdRegister, + LazarusPackageIntf; + +implementation + +procedure Register; +begin + RegisterUnit('IdCoreDsnRegister' , @IdCoreDsnRegister.Register); + RegisterUnit('IdDsnRegister' , @IdDsnRegister.Register); + RegisterUnit('IdRegisterCore' , @IdRegisterCore.Register); + RegisterUnit('IdRegister' , @IdRegister.Register); +end; + +initialization + RegisterPackage('indylaz' , @Register); +end. diff --git a/lazarus-fpc/indyprotocols.lpk b/lazarus-fpc/indyprotocols.lpk new file mode 100644 index 000000000..27fa9f1ce --- /dev/null +++ b/lazarus-fpc/indyprotocols.lpk @@ -0,0 +1,1036 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lazarus-fpc/indyprotocols.pas b/lazarus-fpc/indyprotocols.pas new file mode 100644 index 000000000..665e36003 --- /dev/null +++ b/lazarus-fpc/indyprotocols.pas @@ -0,0 +1,74 @@ +{ This file was automatically created by Lazarus. Do not edit! + This source is only used to compile and install the package. + } + +unit indyprotocols; + +{$warn 5023 off : no warning about unused units} +interface + +uses + IdAllAuthentications, IdAllFTPListParsers, IdAllHeaderCoders, IdASN1Coder, + IdASN1Util, IdAttachment, IdAttachmentFile, IdAttachmentMemory, + IdAuthentication, IdAuthenticationDigest, IdAuthenticationManager, + IdAuthenticationSSPI, IdBlockCipherIntercept, IdChargenServer, + IdChargenUDPServer, IdCharsets, IdCoder00E, IdCoderBinHex4, IdCoderHeader, + IdCoderQuotedPrintable, IdCoderUUE, IdCoderXXE, IdCompressionIntercept, + IdCompressorZLib, IdConnectThroughHttpProxy, IdContainers, IdCookie, + IdCookieManager, IdCustomHTTPServer, IdDateTimeStamp, IdDayTime, + IdDayTimeServer, IdDayTimeUDP, IdDayTimeUDPServer, IdDICT, IdDICTCommon, + IdDICTServer, IdDiscardServer, IdDiscardUDPServer, IdDNSCommon, + IdDNSResolver, IdDNSServer, IdEcho, IdEchoServer, IdEchoUDP, + IdEchoUDPServer, IdEMailAddress, IdExplicitTLSClientServerBase, IdFinger, + IdFingerServer, IdFSP, IdFTP, IdFTPBaseFileSystem, IdFTPCommon, IdFTPList, + IdFTPListOutput, IdFTPListParseAS400, IdFTPListParseBase, + IdFTPListParseBullGCOS7, IdFTPListParseBullGCOS8, + IdFTPListParseChameleonNewt, IdFTPListParseCiscoIOS, + IdFTPListParseDistinctTCPIP, IdFTPListParseEPLF, IdFTPListParseHellSoft, + IdFTPListParseIEFTPGateway, IdFTPListParseKA9Q, IdFTPListParseMicrowareOS9, + IdFTPListParseMPEiX, IdFTPListParseMusic, IdFTPListParseMVS, + IdFTPListParseNCSAForDOS, IdFTPListParseNCSAForMACOS, + IdFTPListParseNovellNetware, IdFTPListParseNovellNetwarePSU, + IdFTPListParseOS2, IdFTPListParsePCNFSD, IdFTPListParsePCTCP, + IdFTPListParseStercomOS390Exp, IdFTPListParseStercomUnixEnt, + IdFTPListParseStratusVOS, IdFTPListParseSuperTCP, + IdFTPListParseTandemGuardian, IdFTPListParseTOPS20, IdFTPListParseTSXPlus, + IdFTPListParseUnisysClearPath, IdFTPListParseUnix, IdFTPListParseVM, + IdFTPListParseVMS, IdFTPListParseVSE, IdFTPListParseVxWorks, + IdFTPListParseWfFTP, IdFTPListParseWindowsNT, IdFTPListParseWinQVTNET, + IdFTPListParseXecomMicroRTOS, IdFTPListTypes, IdFTPServer, + IdFTPServerContextBase, IdGlobalProtocols, IdGopher, IdGopherConsts, + IdGopherServer, IdHashAdler32, IdHashCRC, IdHashElf, IdHashSHA1, + IdHeaderCoder2022JP, IdHeaderCoderBase, IdHeaderCoderBig5, + IdHeaderCoderIndy, IdHeaderCoderPlain, IdHeaderList, IdHL7, IdHMAC, + IdHMACMD5, IdHMACSHA1, IdHostnameServer, IdHTTP, IdHTTPHeaderInfo, + IdHTTPProxyServer, IdHTTPServer, IdIdent, IdIdentServer, IdIMAP4, + IdIMAP4Server, IdIPAddrMon, IdIPWatch, IdIRC, IdIrcServer, IdLDAPV3, + IdLDAPV3Coder, IdLPR, IdMailBox, IdMappedFTP, IdMappedPOP3, IdMappedPortTCP, + IdMappedPortUDP, IdMappedTelnet, IdMessage, IdMessageBuilder, + IdMessageClient, IdMessageCoder, IdMessageCoderBinHex4, IdMessageCoderMIME, + IdMessageCoderQuotedPrintable, IdMessageCoderUUE, IdMessageCoderXXE, + IdMessageCoderYenc, IdMessageCollection, IdMessageHelper, IdMessageParts, + IdMIMETypes, IdMultipartFormData, IdNetworkCalculator, IdNNTP, IdNNTPServer, + IdOSFileName, IdOTPCalculator, IdPOP3, IdPOP3Server, IdQotd, IdQotdServer, + IdQOTDUDP, IdQOTDUDPServer, IdRemoteCMDClient, IdRemoteCMDServer, + IdReplyFTP, IdReplyIMAP4, IdReplyPOP3, IdReplySMTP, + IdResourceStringsProtocols, IdResourceStringsSSPI, + IdResourceStringsUriUtils, IdRexec, IdRexecServer, IdRSH, IdRSHServer, + IdSASL, IdSASLAnonymous, IdSASLCollection, IdSASL_CRAMBase, IdSASL_CRAM_MD5, + IdSASL_CRAM_SHA1, IdSASLDigest, IdSASLExternal, IdSASLLogin, IdSASLOTP, + IdSASLPlain, IdSASLSKey, IdSASLUserPass, IdServerInterceptLogBase, + IdServerInterceptLogEvent, IdServerInterceptLogFile, IdSMTP, IdSMTPBase, + IdSMTPRelay, IdSMTPServer, IdSNMP, IdSNPP, IdSNTP, IdSocksServer, IdSSH, + IdSSPI, IdStrings, IdSysLog, IdSysLogMessage, IdSysLogServer, IdSystat, + IdSystatServer, IdSystatUDP, IdSystatUDPServer, IdTelnet, IdTelnetServer, + IdText, IdTime, IdTimeServer, IdTimeUDP, IdTimeUDPServer, IdTrivialFTP, + IdTrivialFTPBase, IdTrivialFTPServer, IdUnixTime, IdUnixTimeServer, + IdUnixTimeUDP, IdUnixTimeUDPServer, IdURI, IdUriUtils, IdUserAccounts, + IdUserPassProvider, IdVCard, IdWebDAV, IdWhois, IdWhoIsServer, IdZLib, + IdZLibCompressorBase, IdZLibConst, IdZLibHeaders, IdSSL, IdHash, IdFIPS, + IdCoder, IdCoderMIME, IdCoder3to4, IdNTLM, IdAuthenticationNTLM; + +implementation + +end. diff --git a/lazarus-fpc/indysystem.lpk b/lazarus-fpc/indysystem.lpk new file mode 100644 index 000000000..07e5d40e5 --- /dev/null +++ b/lazarus-fpc/indysystem.lpk @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lazarus-fpc/indysystem.pas b/lazarus-fpc/indysystem.pas new file mode 100644 index 000000000..07f35d880 --- /dev/null +++ b/lazarus-fpc/indysystem.pas @@ -0,0 +1,27 @@ +{ This file was automatically created by Lazarus. Do not edit! + This source is only used to compile and install the package. + } + +unit indysystem; + +{$warn 5023 off : no warning about unused units} +interface + +uses + IdBaseComponent, IdComponent, IdCTypes, IdException, IdGlobal, IdIDN, + IdResourceStrings, IdResourceStringsDotNet11, IdResourceStringsIconv, + IdResourceStringsKylixCompat, IdResourceStringsTextEncoding, + IdResourceStringsUnix, IdResourceStringsVCLPosix, IdStack, IdStackBSDBase, + IdStackConsts, IdStream, IdStreamVCL, IdStruct, IdTransactedFileStream, + IdVCLPosixSupplemental, IdWinsock2, IdWship6, IdAntiFreezeBase, + LazarusPackageIntf; + +implementation + +procedure Register; +begin +end; + +initialization + RegisterPackage('indysystem' , @Register); +end. From 3fb4e95ee5bdbc4753e204d2abc6b3fa0fd703d0 Mon Sep 17 00:00:00 2001 From: tony Date: Mon, 6 Jan 2025 11:55:26 +0000 Subject: [PATCH 2/7] README for lazarus added --- README.Lazarus-fpc | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 README.Lazarus-fpc diff --git a/README.Lazarus-fpc b/README.Lazarus-fpc new file mode 100644 index 000000000..0140c0196 --- /dev/null +++ b/README.Lazarus-fpc @@ -0,0 +1,62 @@ +LAZARUS INSTALLATION GUIDE + +You should already have extracted this source tree to a permanent location on +your system. If not then now is a good time to do so. + +1. Start the Lazarus IDE +2. Select the Package-> Open Package File menu item +3. Open the Indylaz.lpk package in the top directory of this source tree. +4. When the package manager opens, select Use->Install + +Lazarus should now recompile and when the IDE re-opens, you should now see the +Indy components at the end of your component palette. + +Online user guides are available describing the Indy components and how to use +them. The runtime package indyprotocols should automatically be added to any +project using an Indy component. There is no need to add any other package. + +You can also use Indy from a console mode application. In this case, you will +have to explicitly add the indyprotocols runtime package as a project +requirement. In console mode applications, you are also responsible for adding +the appropriate Indy unit names to each of your project's units that use Indy +components, and to explicitly create each component you use. + +FPC INSTALLATION GUIDE + +You can also use Indy components in any FPC compiled program, even when you are +not using the Lazarus IDE. There are two possible strategies for the use of +Indy with FPC: + +1. Direct Use of Indy source code + +In this case, you need to add the following directories from the Indy source +tree to your project's units search path (-Fu command line option) and include +files path (-Fi) + +Lib/Protocols +Lib/Core +Lib/System + + +2 Pre-compiled Indy units + +You can also pre-compile the Indy components and link the compiled units into +your program. To compile the Indy components from the command line enter: + +fpcmake -r +make + +The compiled units will be placed in the Indy source tree directory + +units/- + +e.g. units/x86_64-linux for 64-bit Linux + +In this case, you need to add the following directories from the Indy source +tree to your projects units search path (-Fu command line option) + +units/- + + + + From 85c068046e2951833192aa0d2beb3593b95ed1e6 Mon Sep 17 00:00:00 2001 From: tony Date: Mon, 6 Jan 2025 12:16:37 +0000 Subject: [PATCH 3/7] Source Code updates to enable compile with FPC --- Lib/Core/IdCompilerDefines.inc | 5 ++++- Lib/Protocols/IdAuthenticationSSPI.pas | 7 ++++--- Lib/Protocols/IdCompilerDefines.inc | 5 ++++- Lib/Protocols/IdSSH.pas | 5 +++-- Lib/Protocols/IdSSPI.pas | 6 ++++++ Lib/System/IdCompilerDefines.inc | 5 ++++- Lib/System/IdTransactedFileStream.pas | 2 ++ Lib/System/IdWinsock2.pas | 8 ++++++-- Lib/System/IdWship6.pas | 5 ++++- 9 files changed, 37 insertions(+), 11 deletions(-) diff --git a/Lib/Core/IdCompilerDefines.inc b/Lib/Core/IdCompilerDefines.inc index 8ce7d254c..157bc07ec 100644 --- a/Lib/Core/IdCompilerDefines.inc +++ b/Lib/Core/IdCompilerDefines.inc @@ -37,8 +37,11 @@ // $DEFINE the following if the global objects in the IdStack and IdThread // units should be freed on finalization -{.$DEFINE FREE_ON_FINAL} +{$IFDEF FPC} +{$DEFINE FREE_ON_FINAL} +{$ELSE} {$UNDEF FREE_ON_FINAL} +{$ENDIF} // Make sure the following is $DEFINE'd only for suitable environments // as specified further below. This works in conjunction with the diff --git a/Lib/Protocols/IdAuthenticationSSPI.pas b/Lib/Protocols/IdAuthenticationSSPI.pas index dd9e2b6f5..af4f8ff07 100644 --- a/Lib/Protocols/IdAuthenticationSSPI.pas +++ b/Lib/Protocols/IdAuthenticationSSPI.pas @@ -41,7 +41,7 @@ interface {$i IdCompilerDefines.inc} - +{$IFDEF USE_SSPI} uses IdGlobal, IdAuthentication, @@ -430,8 +430,9 @@ TIdSSPINTLMAuthentication = class(TIdAuthentication) {$HPPEMIT '#pragma link "IdAuthenticationSSPI"'} {$ENDIF} +{$ENDIF} implementation - +{$IFDEF USE_SSPI} uses IdGlobalProtocols, IdCoderMIME, @@ -1317,6 +1318,6 @@ finalization UnregisterAuthenticationMethod('Negotiate'); {do not localize} end; FreeAndNil(gSSPIInterface); - +{$ENDIF} end. diff --git a/Lib/Protocols/IdCompilerDefines.inc b/Lib/Protocols/IdCompilerDefines.inc index 8ce7d254c..157bc07ec 100644 --- a/Lib/Protocols/IdCompilerDefines.inc +++ b/Lib/Protocols/IdCompilerDefines.inc @@ -37,8 +37,11 @@ // $DEFINE the following if the global objects in the IdStack and IdThread // units should be freed on finalization -{.$DEFINE FREE_ON_FINAL} +{$IFDEF FPC} +{$DEFINE FREE_ON_FINAL} +{$ELSE} {$UNDEF FREE_ON_FINAL} +{$ENDIF} // Make sure the following is $DEFINE'd only for suitable environments // as specified further below. This works in conjunction with the diff --git a/Lib/Protocols/IdSSH.pas b/Lib/Protocols/IdSSH.pas index 158b3d833..7041275a8 100644 --- a/Lib/Protocols/IdSSH.pas +++ b/Lib/Protocols/IdSSH.pas @@ -34,6 +34,7 @@ interface uses Classes, IdContainers, + IdYarn, IdGlobalCore, IdIOHandler, IdIOHandlerSocket, @@ -61,7 +62,7 @@ TIdServerIOHandlerSSHBase = class(TIdServerIOHandler) protected public //this is for the FTP Server to make a client IOHandler for it's data connection's IOHandler - function MakeClientIOHandler(ATheThread:TIdThreadHandle ): TIdIOHandler; overload; override; + function MakeClientIOHandler(ATheThread:TIdYarn ): TIdIOHandler; overload; override; function MakeClientIOHandler : TIdSSHIOHandlerSocketBase; reintroduce; overload; virtual; abstract; function MakeFTPSvrPort : TIdSSHIOHandlerSocketBase; virtual; abstract; function MakeFTPSvrPasv : TIdSSHIOHandlerSocketBase; virtual; abstract; @@ -143,7 +144,7 @@ procedure TIdSSHIOHandlerSocketBase.SetPassThrough(const AValue: Boolean); { TIdServerIOHandlerSSHBase } -function TIdServerIOHandlerSSHBase.MakeClientIOHandler(ATheThread:TIdThreadHandle ): TIdIOHandler; +function TIdServerIOHandlerSSHBase.MakeClientIOHandler(ATheThread:TIdYarn ): TIdIOHandler; begin Result := MakeClientIOHandler; end; diff --git a/Lib/Protocols/IdSSPI.pas b/Lib/Protocols/IdSSPI.pas index 7160051fb..9aefcf4d9 100644 --- a/Lib/Protocols/IdSSPI.pas +++ b/Lib/Protocols/IdSSPI.pas @@ -39,6 +39,8 @@ interface {$i IdCompilerDefines.inc} +{$IFDEF USE_SSPI} + uses IdGlobal, @@ -2867,7 +2869,9 @@ SEC_WINNT_AUTH_IDENTITY_EXA = record *) +{$ENDIF} implementation +{$IFDEF USE_SSPI} procedure SecInvalidateHandle(var x: SecHandle); begin @@ -2893,4 +2897,6 @@ function SEC_SUCCESS(Status: SECURITY_STATUS): Boolean; Result := Status >= 0; end; +{$ENDIF} + end. diff --git a/Lib/System/IdCompilerDefines.inc b/Lib/System/IdCompilerDefines.inc index 8ce7d254c..157bc07ec 100644 --- a/Lib/System/IdCompilerDefines.inc +++ b/Lib/System/IdCompilerDefines.inc @@ -37,8 +37,11 @@ // $DEFINE the following if the global objects in the IdStack and IdThread // units should be freed on finalization -{.$DEFINE FREE_ON_FINAL} +{$IFDEF FPC} +{$DEFINE FREE_ON_FINAL} +{$ELSE} {$UNDEF FREE_ON_FINAL} +{$ENDIF} // Make sure the following is $DEFINE'd only for suitable environments // as specified further below. This works in conjunction with the diff --git a/Lib/System/IdTransactedFileStream.pas b/Lib/System/IdTransactedFileStream.pas index 2651f1715..456f6233d 100644 --- a/Lib/System/IdTransactedFileStream.pas +++ b/Lib/System/IdTransactedFileStream.pas @@ -345,7 +345,9 @@ destructor TIdTransactedFileStream.Destroy ; inherited Destroy; {$ELSE} //we have to deference our copy of the THandle so we don't free it twice. + {$IFNDEF FPC} {not accessible for FPC} FHandle := INVALID_HANDLE_VALUE; + {$ENDIF} FreeAndNil( FFileStream ); inherited Destroy; {$ENDIF} diff --git a/Lib/System/IdWinsock2.pas b/Lib/System/IdWinsock2.pas index 4f7df261f..23c72e596 100644 --- a/Lib/System/IdWinsock2.pas +++ b/Lib/System/IdWinsock2.pas @@ -158,6 +158,8 @@ interface } +{$IFDEF WINDOWS} + {$I IdRangeCheckingOff.inc} {$IFDEF FPC} @@ -5969,11 +5971,11 @@ RSS_SCALABILITY_INFO = record {$EXTERNALSYM IN6ADDR_TEREDOPREFIX_LENGTH} IN6ADDR_TEREDOPREFIX_LENGTH = 32; - +{$ENDIF} //============================================================= implementation //============================================================= - +{$IFDEF WINDOWS} uses IdResourceStrings {$IFDEF HAS_AnsiStrings_StrLen}, AnsiStrings{$ENDIF} @@ -9019,5 +9021,7 @@ initialization InitializeStubs; +{$ENDIF} + end. diff --git a/Lib/System/IdWship6.pas b/Lib/System/IdWship6.pas index 4699f35b5..d6f93b48d 100644 --- a/Lib/System/IdWship6.pas +++ b/Lib/System/IdWship6.pas @@ -34,6 +34,7 @@ interface {$I IdCompilerDefines.inc} +{$IFDEF WINDOWS} {$IFDEF FPC} {$IFDEF WIN32} {$ALIGN OFF} @@ -438,7 +439,9 @@ function gaiErrorToWsaError(const gaiError: Integer): Integer; procedure InitLibrary; procedure CloseLibrary; +{$ENDIF} implementation +{$IFDEF WINDOWS} uses SysUtils; @@ -1541,5 +1544,5 @@ procedure InitLibrary; initialization finalization CloseLibrary; - +{$ENDIF} end. From fe33518935c1cf604e4c667d3377170666c4e824 Mon Sep 17 00:00:00 2001 From: tony Date: Mon, 6 Jan 2025 13:17:41 +0000 Subject: [PATCH 4/7] Readme update --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e2fdf5588..bba2d52ef 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Indy - Internet Direct +This fork is the basis of a pull request and should be ignored by most users. + Indy is a well-known internet component suite for **Delphi**, **C++Builder**, and **Free Pascal** providing both low-level support (TCP, UDP, raw sockets) and over a 120 higher level protocols (SMTP, POP3, NNT, HTTP, FTP) for building both client and server applications. From 697d77b147c9af9f956b3c1806b43b5ffbd6ec65 Mon Sep 17 00:00:00 2001 From: tony Date: Wed, 8 Jan 2025 10:01:37 +0000 Subject: [PATCH 5/7] Removed VCL and DotNet specific units from lazarus system package --- lazarus-fpc/indysystem.lpk | 18 +----------------- lazarus-fpc/indysystem.pas | 12 +++++------- 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/lazarus-fpc/indysystem.lpk b/lazarus-fpc/indysystem.lpk index 07e5d40e5..0b562faa4 100644 --- a/lazarus-fpc/indysystem.lpk +++ b/lazarus-fpc/indysystem.lpk @@ -31,7 +31,7 @@ Redistributions in binary form must reproduce the above copyright notice, this l No personal names or organizations names associated with the Indy project may be used to endorse or promote products derived from this software without specific prior written permission of the specific individual or organization. THIS SOFTWARE IS PROVIDED BY Chad Z. Hower (Kudzu) and the Indy Pit Crew &amp;quot;AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."/> - + @@ -65,10 +65,6 @@ THIS SOFTWARE IS PROVIDED BY Chad Z. Hower (Kudzu) and the Indy Pit Crew &am - - - - @@ -85,10 +81,6 @@ THIS SOFTWARE IS PROVIDED BY Chad Z. Hower (Kudzu) and the Indy Pit Crew &am - - - - @@ -105,10 +97,6 @@ THIS SOFTWARE IS PROVIDED BY Chad Z. Hower (Kudzu) and the Indy Pit Crew &am - - - - @@ -117,10 +105,6 @@ THIS SOFTWARE IS PROVIDED BY Chad Z. Hower (Kudzu) and the Indy Pit Crew &am - - - - diff --git a/lazarus-fpc/indysystem.pas b/lazarus-fpc/indysystem.pas index 07f35d880..2cd1582b2 100644 --- a/lazarus-fpc/indysystem.pas +++ b/lazarus-fpc/indysystem.pas @@ -9,12 +9,10 @@ interface uses IdBaseComponent, IdComponent, IdCTypes, IdException, IdGlobal, IdIDN, - IdResourceStrings, IdResourceStringsDotNet11, IdResourceStringsIconv, - IdResourceStringsKylixCompat, IdResourceStringsTextEncoding, - IdResourceStringsUnix, IdResourceStringsVCLPosix, IdStack, IdStackBSDBase, - IdStackConsts, IdStream, IdStreamVCL, IdStruct, IdTransactedFileStream, - IdVCLPosixSupplemental, IdWinsock2, IdWship6, IdAntiFreezeBase, - LazarusPackageIntf; + IdResourceStrings, IdResourceStringsIconv, IdResourceStringsKylixCompat, + IdResourceStringsTextEncoding, IdResourceStringsUnix, IdStack, + IdStackBSDBase, IdStackConsts, IdStream, IdStruct, IdTransactedFileStream, + IdWinsock2, IdWship6, IdAntiFreezeBase, LazarusPackageIntf; implementation @@ -23,5 +21,5 @@ procedure Register; end; initialization - RegisterPackage('indysystem' , @Register); + RegisterPackage('indysystem', @Register); end. From 85974c129d7c90cbbc08a075d0823e990c747baa Mon Sep 17 00:00:00 2001 From: tony Date: Wed, 8 Jan 2025 14:05:54 +0000 Subject: [PATCH 6/7] Removed StreamVCL from fpc build unit --- Lib/System/indysystemfpc.pas | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/System/indysystemfpc.pas b/Lib/System/indysystemfpc.pas index d85b30fe0..d86aeb1f1 100644 --- a/Lib/System/indysystemfpc.pas +++ b/Lib/System/indysystemfpc.pas @@ -12,7 +12,6 @@ interface IdStack, IdStackConsts, IdStream, - IdStreamVCL, IdStruct; implementation From 8ff6cb88503d84b3944379130bd3b2398bdce9b6 Mon Sep 17 00:00:00 2001 From: tony Date: Wed, 8 Jan 2025 14:11:22 +0000 Subject: [PATCH 7/7] Updated gitattributes --- .gitattributes | 8 + Lib/Core/IdCompilerDefines.inc | 4188 ++--- Lib/Core/IdCore90ASM90.inc | 24 +- Lib/Core/IdDsnBaseCmpEdt.pas | 188 +- Lib/Core/IddclCore90ASM90.inc | 24 +- Lib/FCL/IdCompilerDefines.inc | 4182 ++--- Lib/FCL/IdVers.inc | 36 +- Lib/Indy100Net.dpk | 670 +- Lib/Indy110Net.dpk | 670 +- Lib/Indy90Net.dpk | 670 +- Lib/Protocols/IdAuthenticationSSPI.pas | 2646 +-- Lib/Protocols/IdCompilerDefines.inc | 4188 ++--- Lib/Protocols/IdCompressionIntercept.pas | 682 +- Lib/Protocols/IdCompressorZLib.pas | 692 +- Lib/Protocols/IdDsnRegister.pas | 396 +- Lib/Protocols/IdHTTP.pas | 6556 ++++---- Lib/Protocols/IdIMAP4.pas | 14524 ++++++++--------- Lib/Protocols/IdMessageHelper.pas | 470 +- Lib/Protocols/IdProtocols90ASM90.inc | 24 +- Lib/Protocols/IdSSH.pas | 358 +- Lib/Protocols/IdSSL.pas | 620 +- Lib/Protocols/IdSSPI.pas | 5804 +++---- Lib/Protocols/IdSecurity90ASM90.inc | 24 +- Lib/Protocols/IdZLib.pas | 2314 +-- Lib/Protocols/IdZLibHeaders.pas | 3252 ++-- Lib/Protocols/IddclProtocols90ASM90.inc | 24 +- Lib/Protocols/IndyProtocols100.dpk | 540 +- Lib/Protocols/IndyProtocols100Net.dpk | 520 +- Lib/Protocols/IndyProtocols110.dpk | 540 +- Lib/Protocols/IndyProtocols110Net.dpk | 522 +- Lib/Protocols/IndyProtocols120.dpk | 540 +- Lib/Protocols/IndyProtocols120Net.dpk | 522 +- Lib/Protocols/IndyProtocols130.dpk | 540 +- Lib/Protocols/IndyProtocols130Net.dpk | 522 +- Lib/Protocols/IndyProtocols140.dpk | 542 +- Lib/Protocols/IndyProtocols150.dpk | 542 +- Lib/Protocols/IndyProtocols160.dpk | 582 +- Lib/Protocols/IndyProtocols160.dproj | 846 +- Lib/Protocols/IndyProtocols170.dpk | 586 +- Lib/Protocols/IndyProtocols170.dproj | 770 +- Lib/Protocols/IndyProtocols180.dpk | 604 +- Lib/Protocols/IndyProtocols180.dproj | 844 +- Lib/Protocols/IndyProtocols190.dpk | 604 +- Lib/Protocols/IndyProtocols190.dproj | 940 +- Lib/Protocols/IndyProtocols200.dpk | 604 +- Lib/Protocols/IndyProtocols200.dproj | 916 +- Lib/Protocols/IndyProtocols210.dpk | 604 +- Lib/Protocols/IndyProtocols210.dproj | 856 +- Lib/Protocols/IndyProtocols220.dpk | 604 +- Lib/Protocols/IndyProtocols220.dproj | 938 +- Lib/Protocols/IndyProtocols230.dpk | 604 +- Lib/Protocols/IndyProtocols230.dproj | 938 +- Lib/Protocols/IndyProtocols240.dpk | 604 +- Lib/Protocols/IndyProtocols240.dproj | 1504 +- Lib/Protocols/IndyProtocols250.dpk | 604 +- Lib/Protocols/IndyProtocols250.dproj | 1506 +- Lib/Protocols/IndyProtocols40.dpk | 538 +- Lib/Protocols/IndyProtocols50.dpk | 538 +- Lib/Protocols/IndyProtocols60.dpk | 540 +- Lib/Protocols/IndyProtocols70.dpk | 540 +- Lib/Protocols/IndyProtocols80.dpk | 540 +- Lib/Protocols/IndyProtocols80Net.dpk | 520 +- Lib/Protocols/IndyProtocols90.dpk | 542 +- Lib/Protocols/IndyProtocols90Net.dpk | 520 +- Lib/Protocols/IndyProtocolsK3.dpk | 540 +- Lib/Security/IdSecurity90ASM90.inc | 24 +- Lib/Security/IddclSecurity90ASM90.inc | 24 +- Lib/SuperCore/IdCompilerDefines.inc | 4182 ++--- Lib/System/IdCompilerDefines.inc | 4188 ++--- Lib/System/IdStack.pas | 2492 +-- Lib/System/IdStackDotNet.pas | 2836 ++-- Lib/System/IdStackLibc.pas | 2968 ++-- Lib/System/IdStackLinux.pas | 2918 ++-- Lib/System/IdStackUnix.pas | 2760 ++-- Lib/System/IdStackVCLPosix.pas | 3188 ++-- Lib/System/IdStackWindows.pas | 5194 +++--- Lib/System/IdSystem90ASM90.inc | 24 +- Lib/System/IdTransactedFileStream.pas | 724 +- Lib/System/IdVers.inc | 36 +- Lib/System/IdWinsock2.pas | 18054 ++++++++++----------- Lib/System/IdWship6.pas | 3096 ++-- 81 files changed, 66078 insertions(+), 66070 deletions(-) diff --git a/.gitattributes b/.gitattributes index e51621f29..04cc8e960 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2712,3 +2712,11 @@ icons/tIdAntiFreeze.bmp -text svneol=unset#unset icons/tIdDecoderUUE.bmp -text svneol=unset#unset icons/tIdEncoderUUE.bmp -text svneol=unset#unset icons/tIdIdent.bmp -text svneol=unset#unset +*.pas text +*.inc text +*.lpr text +*.lpi text +*.lps text +*.dpk text +*.dproj text + diff --git a/Lib/Core/IdCompilerDefines.inc b/Lib/Core/IdCompilerDefines.inc index 157bc07ec..ccfd332fe 100644 --- a/Lib/Core/IdCompilerDefines.inc +++ b/Lib/Core/IdCompilerDefines.inc @@ -1,2094 +1,2094 @@ -{$IFDEF CONDITIONALEXPRESSIONS} - // Must be at the top... - {$IF CompilerVersion >= 24.0} - {$LEGACYIFEND ON} - {$IFEND} -{$ENDIF} - -// General - -// Make this $DEFINE to use the 16 color icons required by Borland -// or DEFINE to use the 256 color Indy versions -{.$DEFINE Borland} - -// S.G. 4/9/2002: IPv4/IPv6 general switch (for defaults only) -{$DEFINE IdIPv4} // use IPv4 by default -{.$IFDEF IdIPv6} // use IPv6 by default - -{$DEFINE INDY100} -{$DEFINE 10_7_0} //so developers can IFDEF for this product version -{$DEFINE 10_7_0_0} //so developers can IFDEF for this specific version - -// When generating C++Builder output files, certain workarounds to compiler -// problems need to be enabled! When invoking DCC on the command-line, use -// the -DBCB parameter. When invoking MSBUILD, include the DCC_Define="BCB" -// attribute in the /p parameter. -{$IFDEF BCB} - {$DEFINE CBUILDER} -{$ELSE} - {$DEFINE DELPHI} -{$ENDIF} - -{$UNDEF USE_OPENSSL} -{$UNDEF STATICLOAD_OPENSSL} - -{$UNDEF USE_ZLIB_UNIT} -{$UNDEF USE_SSPI} - -// $DEFINE the following if the global objects in the IdStack and IdThread -// units should be freed on finalization -{$IFDEF FPC} -{$DEFINE FREE_ON_FINAL} -{$ELSE} -{$UNDEF FREE_ON_FINAL} -{$ENDIF} - -// Make sure the following is $DEFINE'd only for suitable environments -// as specified further below. This works in conjunction with the -// FREE_ON_FINAL define above. -{$UNDEF REGISTER_EXPECTED_MEMORY_LEAK} -{$UNDEF HAS_System_RegisterExpectedMemoryLeak} - -// FastMM is natively available in BDS 2006 and higher. $DEFINE the -// following if FastMM has been installed manually in earlier versions -{.$DEFINE USE_FASTMM4} -{$UNDEF USE_FASTMM4} - -// $DEFINE the following if MadExcept has been installed manually in -// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced -// in BDS 2006) -{.$DEFINE USE_MADEXCEPT} -{$UNDEF USE_MADEXCEPT} - -// $DEFINE the following if LeakCheck has been installed manually in -// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced -// in BDS 2006) -{.$DEFINE USE_LEAKCHECK} -{$UNDEF USE_LEAKCHECK} - -// Make sure the following are $DEFINE'd only for Delphi/C++Builder 2009 onwards -// as specified further below. The VCL is fully Unicode, where the 'String' -// type maps to System.UnicodeString, not System.AnsiString anymore -{$UNDEF STRING_IS_UNICODE} -{$UNDEF STRING_IS_ANSI} -{$UNDEF STRING_UNICODE_MISMATCH} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. Delphi/C++Builder Mobile/NextGen compilers -// do not support Ansi data types anymore, and is moving away from raw -// pointers as well. -// -// UPDATE: in Delphi/C++Builder 10.4, all Ansi types are supported again on -// all platforms, including the mobile compilers. -{$DEFINE HAS_AnsiString} -{$DEFINE HAS_AnsiChar} -{$DEFINE HAS_PAnsiChar} -{$UNDEF HAS_PPAnsiChar} -{$UNDEF NO_ANSI_TYPES} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. Delphi/C++Builder Mobile/NextGen compilers -// use ARC for TObject life time management. -// -// UPDATE: ARC for TObject lifetime management has been removed in -// Delphi/C++Builder 10.4 mobile compilers. All platforms now use a single -// unified memory management model! -{$UNDEF USE_MARSHALLED_PTRS} -{$UNDEF HAS_MarshaledAString} -{$UNDEF USE_OBJECT_ARC} - -// Make sure the following is $DEFINE'd only for suitable environments -// as specified further below. -{$UNDEF STRING_IS_IMMUTABLE} -{$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. -{$UNDEF HAS_TEncoding} -{$UNDEF HAS_TEncoding_GetEncoding_ByEncodingName} -{$UNDEF HAS_Exception_RaiseOuterException} -{$UNDEF HAS_System_ReturnAddress} -{$UNDEF HAS_TCharacter} -{$UNDEF HAS_TInterlocked} -{$UNDEF HAS_TNetEncoding} - -// Make sure that this is defined only for environments where we are using -// the iconv library to charactor conversions. -{.$UNDEF USE_ICONV} -{.$UNDEF USE_LCONVENC} - -//Define for Delphi cross-compiler targetting Posix -{$UNDEF USE_VCL_POSIX} -{$UNDEF HAS_ComponentPlatformsAttribute} -{$UNDEF HAS_ComponentPlatformsAttribute_Win32} -{$UNDEF HAS_ComponentPlatformsAttribute_Win64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSX32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator32} -{$UNDEF HAS_ComponentPlatformsAttribute_Android} -{$UNDEF HAS_ComponentPlatformsAttribute_Android32Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device32} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux64} -{$UNDEF HAS_ComponentPlatformsAttribute_WinNX32} -{$UNDEF HAS_ComponentPlatformsAttribute_WinIoT32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device64} -{$UNDEF HAS_ComponentPlatformsAttribute_WinARM} -{$UNDEF HAS_ComponentPlatformsAttribute_WinARM32} -{$UNDEF HAS_ComponentPlatformsAttribute_OSX64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux32Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux64Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Android64} -{$UNDEF HAS_ComponentPlatformsAttribute_Android64Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator64} -{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm32} -{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSXArm64} -{$UNDEF HAS_ComponentPlatformsAttribute_AllPlatforms} -{$UNDEF HAS_DIRECTIVE_WARN_DEFAULT} - -// Define for Delphi to auto-generate platform-appropriate '#pragma link' statements in HPP files -{$UNDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT} - -// detect compiler versions - -{$IFNDEF FPC} - - // TODO: to detect features in Delphi/C++Builder v6 and later, use CompilerVersion - // and RTLVersion constants instead of VERXXX defines. We still support v5, which - // does not have such constants. - - // Delphi 4 - {$IFDEF VER120} - {$DEFINE DCC} - {$DEFINE VCL_40} - {$DEFINE DELPHI_4} - {$ENDIF} - - // C++Builder 4 - {$IFDEF VER125} - {$DEFINE DCC} - {$DEFINE VCL_40} - {$DEFINE CBUILDER_4} - {$ENDIF} - - // Delphi & C++Builder 5 - {$IFDEF VER130} - {$DEFINE DCC} - {$DEFINE VCL_50} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_5} - {$ELSE} - {$DEFINE DELPHI_5} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 6 - {$IFDEF VER140} - {$DEFINE DCC} - {$DEFINE VCL_60} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_6} - {$ELSE} - {$DEFINE DELPHI_6} - {$ENDIF} - {$ENDIF} - - //Delphi 7 - {$IFDEF VER150} - {$DEFINE DCC} - {$DEFINE VCL_70} - {$DEFINE DELPHI_7} // there was no C++ Builder 7 - {$ENDIF} - - //Delphi 8 - {$IFDEF VER160} - {$DEFINE DCC} - {$DEFINE VCL_80} - {$DEFINE DELPHI_8} // there was no C++ Builder 8 - {$ENDIF} - - //Delphi 2005 - {$IFDEF VER170} - {$DEFINE DCC} - {$DEFINE VCL_2005} - {$DEFINE DELPHI_2005} // there was no C++Builder 2005 - {$ENDIF} - - // NOTE: CodeGear decided to make Highlander be a non-breaking release - // (no interface changes, thus fully backwards compatible without any - // end user code changes), so VER180 applies to both BDS 2006 and - // Highlander prior to the release of RAD Studio 2007. Use VER185 to - // identify Highlanger specifically. - - //Delphi & C++Builder 2006 - //Delphi & C++Builder 2007 (Highlander) - {$IFDEF VER180} - {$DEFINE DCC} - {$DEFINE VCL_2006} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2006} - {$ELSE} - {$DEFINE DELPHI_2006} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2007 (Highlander) - {$IFDEF VER185} - {$DEFINE DCC} - {$UNDEF VCL_2006} - {$DEFINE VCL_2007} - {$IFDEF CBUILDER} - {$UNDEF CBUILDER_2006} - {$DEFINE CBUILDER_2007} - {$ELSE} - {$UNDEF DELPHI_2006} - {$DEFINE DELPHI_2007} - {$ENDIF} - {$ENDIF} - - // BDS 2007 NET personality uses VER190 instead of 185. - //Delphi .NET 2007 - {$IFDEF VER190} - {$DEFINE DCC} - {$IFDEF CIL} - //Delphi 2007 - {$DEFINE VCL_2007} - {$DEFINE DELPHI_2007} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2009 (Tiburon) - {$IFDEF VER200} - {$DEFINE DCC} - {$DEFINE VCL_2009} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2009} - {$ELSE} - {$DEFINE DELPHI_2009} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2010 (Weaver) - {$IFDEF VER210} - {$DEFINE DCC} - {$DEFINE VCL_2010} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2010} - {$ELSE} - {$DEFINE DELPHI_2010} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder XE (Fulcrum) - {$IFDEF VER220} - //REMOVE DCC DEFINE after the next Fulcrum beta. - //It will be defined there. - {$IFNDEF DCC} - {$DEFINE DCC} - {$ENDIF} - {$DEFINE VCL_XE} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE} - {$ELSE} - {$DEFINE DELPHI_XE} - {$ENDIF} - {$ENDIF} - - // DCC is now defined by the Delphi compiler starting in XE2 - - //Delphi & CBuilder XE2 (Pulsar) - {$IFDEF VER230} - {$DEFINE VCL_XE2} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE2} - {$ELSE} - {$DEFINE DELPHI_XE2} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE3 (Waterdragon) - //Delphi & CBuilder XE3.5 (Quintessence - early betas only) - {$IFDEF VER240} - {$DEFINE VCL_XE3} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE3} - {$ELSE} - {$DEFINE DELPHI_XE3} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE4 (Quintessence) - {$IFDEF VER250} - {$UNDEF VCL_XE3} - {$DEFINE VCL_XE4} - {$IFDEF CBUILDER} - {$UNDEF CBUILDER_XE3} - {$DEFINE CBUILDER_XE4} - {$ELSE} - {$UNDEF DELPHI_XE3} - {$DEFINE DELPHI_XE4} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE5 (Zephyr) - {$IFDEF VER260} - {$DEFINE VCL_XE5} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE5} - {$ELSE} - {$DEFINE DELPHI_XE5} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder AppMethod - //AppMethod is just XE5 for mobile only, VCL is removed - {$IFDEF VER265} - {$DEFINE VCL_XE5} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE5} - {$ELSE} - {$DEFINE DELPHI_XE5} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE6 (Proteus) - {$IFDEF VER270} - {$DEFINE VCL_XE6} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE6} - {$ELSE} - {$DEFINE DELPHI_XE6} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE7 (Carpathia) - {$IFDEF VER280} - {$DEFINE VCL_XE7} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE7} - {$ELSE} - {$DEFINE DELPHI_XE7} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE8 (Elbrus) - {$IFDEF VER290} - {$DEFINE VCL_XE8} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE8} - {$ELSE} - {$DEFINE DELPHI_XE8} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.0 Seattle (Aitana) - {$IFDEF VER300} - {$DEFINE VCL_10_0} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_VCL_10_0} - {$ELSE} - {$DEFINE DELPHI_VCL_10_0} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.1 Berlin (BigBen) - {$IFDEF VER310} - {$DEFINE VCL_10_1} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_1} - {$ELSE} - {$DEFINE DELPHI_10_1} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.2 Tokyo (Godzilla) - {$IFDEF VER320} - {$DEFINE VCL_10_2} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_2} - {$ELSE} - {$DEFINE DELPHI_10_2} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.3 Rio (Carnival) - {$IFDEF VER330} - {$DEFINE VCL_10_3} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_3} - {$ELSE} - {$DEFINE DELPHI_10_3} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.4 Sydney (Denali) - {$IFDEF VER340} - {$DEFINE VCL_10_4} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_4} - {$ELSE} - {$DEFINE DELPHI_10_4} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 11.0 Alexandria (Olympus) - {$IFDEF VER350} - {$DEFINE VCL_11} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_11} - {$ELSE} - {$DEFINE DELPHI_11} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 12.0 Athens (Yukon) - {$IFDEF VER360} - {$DEFINE VCL_12} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_12} - {$ELSE} - {$DEFINE DELPHI_12} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 13.0+ (?) - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF CompilerVersion >= 37} - {$MESSAGE WARN 'Unknown compiler version detected! Assuming >= 13.x '} - {$DEFINE VCL_UNKNOWN_VERSION} - {$DEFINE VCL_13} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_13} - {$ELSE} - {$DEFINE DELPHI_13} - {$ENDIF} - {$IFEND} - {$ENDIF} - - // Kylix - // - //Important: Don't use CompilerVersion here as IF's are evaluated before - //IFDEF's and Kylix 1 does not have CompilerVersion defined at all. - {$IFDEF LINUX} - {$DEFINE UNIX} - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF (RTLVersion >= 14.0) and (RTLVersion <= 14.5) } - {$DEFINE KYLIX} - {$IF RTLVersion = 14.5} - {$DEFINE KYLIX_3} - {$ELSEIF RTLVersion >= 14.2} - {$DEFINE KYLIX_2} - {$ELSE} - {$DEFINE KYLIX_1} - {$IFEND} - {$IFEND} - {$ENDIF} - {$ENDIF} - -{$ENDIF} - -// Delphi.NET -// Covers D8+ -{$IFDEF CIL} - // Platform specific conditional. Used for platform specific code. - {$DEFINE DOTNET} - {$DEFINE STRING_IS_UNICODE} - {$DEFINE STRING_IS_IMMUTABLE} - {.$DEFINE HAS_Int8} - {.$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_UInt64} -{$ENDIF} - -{$IFDEF KYLIX} - {$DEFINE VCL_60} - {$DEFINE INT_THREAD_PRIORITY} - {$DEFINE CPUI386} - {$UNDEF USE_BASEUNIX} - - {$IFDEF KYLIX_3} - {$DEFINE KYLIX_3_OR_ABOVE} - {$ENDIF} - - {$IFDEF KYLIX_3_OR_ABOVE} - {$DEFINE KYLIX_2_OR_ABOVE} - {$ELSE} - {$IFDEF KYLIX_2} - {$DEFINE KYLIX_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF KYLIX_2_OR_ABOVE} - {$DEFINE KYLIX_1_OR_ABOVE} - {$ELSE} - {$IFDEF KYLIX_1} - {$DEFINE KYLIX_1_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFNDEF KYLIX_3_OR_ABOVE} - {$DEFINE KYLIXCOMPAT} - {$ENDIF} - - {$IFDEF KYLIX_2_OR_ABOVE} - {$DEFINE USE_ZLIB_UNIT} - {$ENDIF} -{$ENDIF} - -// FPC (2+) - -{$IFDEF FPC} - // TODO: In FreePascal 4.2.0+, a Delphi-like UnicodeString type is supported. - // However, String/(P)Char do not map to UnicodeString/(P)WideChar unless - // either {$MODE DelphiUnicode} or {$MODESWITCH UnicodeStrings} is used. - // We should consider enabling one of them so Indy uses the same Unicode logic - // in Delphi 2009+ and FreePascal 4.2.0+ and reduces IFDEFs (in particular, - // STRING_UNICODE_MISMATCH, see further below). However, FreePascal's RTL - // is largely not UnicodeString-enabled yet. Maybe we should enable - // {$MODE DelphiUnicode} anyway, and then deal with any RTL function issues - // on an as-needed basis... - {$MODE Delphi} - //note that we may need further defines for widget types depending on - //what we do and what platforms we support in FPC. - //I'll let Marco think about that one. - {$IFDEF UNIX} - {$DEFINE USE_BASEUNIX} - {$IFDEF LINUX} - //In Linux for I386, you can choose between a Kylix-libc API or - //the standard RTL Unix API. Just pass -dKYLIXCOMPAT to the FPC compiler. - //I will see what I can do about the Makefile. - {$IFDEF KYLIXCOMPAT} - {$IFDEF CPUI386} - {$UNDEF USE_BASEUNIX} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$IFDEF USE_BASEUNIX} - {$UNDEF KYLIXCOMPAT} - {$ENDIF} - {$ENDIF} - - // FPC_FULLVERSION was added in FPC 2.2.4 - // Have to use Defined() or else Delphi compiler chokes, since it - // evaluates $IF statements before $IFDEF statements... - - {$MACRO ON} // must be on in order to use versioning macros - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30101)} - {$DEFINE FPC_3_1_1_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30000)} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20701)} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20604)} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20602)} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20600)} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20404)} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20402)} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20400)} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20204)} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20202)} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20105)} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$IFEND} - - // just in case - {$IFDEF FPC_3_1_1} - {$DEFINE FPC_3_1_1_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_3_0_0} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_7_1} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_4} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_2} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_0} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_4} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_2} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_0} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_2_4} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_2_2} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_1_5} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ENDIF} - - {$IFDEF FPC_3_1_1_OR_ABOVE} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_3_0_0} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_3_0_0_OR_ABOVE} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_7_1} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_7_1_OR_ABOVE} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_4} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_4_OR_ABOVE} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_2} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_0} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_0_OR_ABOVE} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_4} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_4_OR_ABOVE} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_2} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_2_OR_ABOVE} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_0} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_0_OR_ABOVE} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_2_4} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_4_OR_ABOVE} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_2_2} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_2_OR_ABOVE} - {$DEFINE FPC_2_2_0_OR_ABOVE} - {$ELSE} - {$IFDEF VER2_2} - {$DEFINE FPC_2_2_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_0_OR_ABOVE} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_1_5} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {.$IFDEF FPC_2_7_1_OR_ABOVE} - // support for RawByteString and UnicodeString - {.$MODE DelphiUnicode} - {.$MODESWITCH UnicodeStrings} - {.$CODEPAGE UTF8} // needed for Unicode string literals to work properly - {.$DEFINE VCL_2009} - {.$DEFINE DELPHI_2009} - {.$ELSE} - {$DEFINE VCL_70} - {$DEFINE DELPHI_7} - {.$ENDIF} -{$ENDIF} - -// end FPC - -{$IFDEF VCL_13} - {$DEFINE VCL_13_OR_ABOVE} -{$ENDIF} - -{$IFDEF VCL_13_OR_ABOVE} - {$DEFINE VCL_12_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_12} - {$DEFINE VCL_12_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_12_OR_ABOVE} - {$DEFINE VCL_11_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_11} - {$DEFINE VCL_11_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_11_OR_ABOVE} - {$DEFINE VCL_10_4_OR_ABOVE} - {$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_4} - {$DEFINE VCL_10_4_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_4_OR_ABOVE} - {$DEFINE VCL_10_3_OR_ABOVE} - {$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_3} - {$DEFINE VCL_10_3_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_OR_ABOVE} - {$DEFINE VCL_10_2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_2} - {$DEFINE VCL_10_2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_2_OR_ABOVE} - {$DEFINE VCL_10_1_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_1} - {$DEFINE VCL_10_1_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_1_OR_ABOVE} - {$DEFINE VCL_10_0_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_0} - {$DEFINE VCL_10_0_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_0_OR_ABOVE} - {$DEFINE VCL_XE8_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE8} - {$DEFINE VCL_XE8_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE VCL_XE7_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE7} - {$DEFINE VCL_XE7_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE7_OR_ABOVE} - {$DEFINE VCL_XE6_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE6} - {$DEFINE VCL_XE6_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE6_OR_ABOVE} - {$DEFINE VCL_XE5_OR_ABOVE} - {$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE5} - {$DEFINE VCL_XE5_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE5_OR_ABOVE} - {$DEFINE VCL_XE4_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE4} - {$DEFINE VCL_XE4_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE4_OR_ABOVE} - {$DEFINE VCL_XE3_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE3} - {$DEFINE VCL_XE3_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE3_OR_ABOVE} - {$DEFINE VCL_XE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE2} - {$DEFINE VCL_XE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE2_OR_ABOVE} - {$DEFINE VCL_XE_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE} - {$DEFINE VCL_XE_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE_OR_ABOVE} - {$DEFINE VCL_2010_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2010} - {$DEFINE VCL_2010_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2010_OR_ABOVE} - {$DEFINE VCL_2009_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2009} - {$DEFINE VCL_2009_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2009_OR_ABOVE} - {$DEFINE VCL_2007_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2007} - {$DEFINE VCL_2007_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2007_OR_ABOVE} - {$DEFINE VCL_2006_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2006} - {$DEFINE VCL_2006_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2006_OR_ABOVE} - {$DEFINE VCL_2005_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2005} - {$DEFINE VCL_2005_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2005_OR_ABOVE} - {$DEFINE VCL_8_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_80} - {$DEFINE VCL_8_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_8_OR_ABOVE} - {$DEFINE VCL_7_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_70} - {$DEFINE VCL_7_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_7_OR_ABOVE} - {$DEFINE VCL_6_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_60} - {$DEFINE VCL_6_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_6_OR_ABOVE} - {$DEFINE VCL_5_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_50} - {$DEFINE VCL_5_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_5_OR_ABOVE} - {$DEFINE VCL_4_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_40} - {$DEFINE VCL_4_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -// Normalize Delphi compiler defines to match FPC for consistency: -// -// CPU32 - any 32-bit CPU -// CPU64 - any 64-bit CPU -// WINDOWS - any Windows platform (32-bit, 64-bit, CE) -// WIN32 - Windows 32-bit -// WIN64 - Windows 64-bit -// WINCE - Windows CE -// -// Consult the "Free Pascal Programmer's Guide", Appendix G for the complete -// list of defines that are used. Do not work on this unless you understand -// what the FreePascal developers are doing. Not only do you have to -// descriminate with operating systems, but also with chip architectures -// are well. -// -// DCC Pulsar+ define the following values: -// ASSEMBLER -// DCC -// CONDITIONALEXPRESSIONS -// NATIVECODE -// UNICODE -// MACOS -// MACOS32 -// MACOS64 -// MSWINDOWS -// WIN32 -// WIN64 -// LINUX -// POSIX -// POSIX32 -// CPU386 -// CPUX86 -// CPUX64 -// -// Kylix defines the following values: -// LINUX -// (others??) -// - -{$IFNDEF FPC} - // TODO: We need to use ENDIAN_BIG for big endian chip architectures, - // such as 680x0, PowerPC, Sparc, and MIPS, once DCC supports them, - // provided it does not already define its own ENDIAN values by then... - {$DEFINE ENDIAN_LITTLE} - {$IFNDEF VCL_6_OR_ABOVE} - {$DEFINE MSWINDOWS} - {$ENDIF} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} - // TODO: map Pulsar's non-Windows platform defines... - {$IFDEF VCL_XE2_OR_ABOVE} - {$IFDEF VCL_XE8_OR_ABOVE} - {$IFDEF CPU32BITS} - //any 32-bit CPU - {$DEFINE CPU32} - {$ENDIF} - {$IFDEF CPU64BITS} - {$DEFINE CPU64} - {$ENDIF} - {$ELSE} - {$IFDEF CPU386} - //any 32-bit CPU - {$DEFINE CPU32} - //Intel 386 compatible chip architecture - {$DEFINE CPUI386} - {$ENDIF} - {$IFDEF CPUX86} - {$DEFINE CPU32} - {$ENDIF} - {$IFDEF CPUX64} - //any 64-bit CPU - {$DEFINE CPU64} - //AMD64 compatible chip architecture - {$DEFINE CPUX86_64} //historical name for AMD64 - {$DEFINE CPUAMD64} - {$ENDIF} - {$ENDIF} - {$ELSE} - {$IFNDEF DOTNET} - {$IFNDEF KYLIX} - {$DEFINE I386} - {$ENDIF} - {$ENDIF} - {$DEFINE CPU32} - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - //differences in DotNET Framework versions. - {$IFDEF VCL_2007_OR_ABOVE} - {$DEFINE DOTNET_2} - {$DEFINE DOTNET_2_OR_ABOVE} - {$ELSE} - {$DEFINE DOTNET_1_1} - {$ENDIF} - {$DEFINE DOTNET_1_1_OR_ABOVE} - // Extra include used in D7 for testing. Remove later when all comps are - // ported. Used to selectively exclude non ported parts. Allowed in places - // IFDEFs are otherwise not permitted. - {$DEFINE DOTNET_EXCLUDE} -{$ENDIF} - -// Check for available features - -{$IFDEF CBUILDER} - // When generating a C++ HPP file, if a class has no explicit constructor - // defined and contains compiler-managed members (xxxString, TDateTime, - // Variant, DelphiInterface, etc), the HPP will contain a forwarding - // inline constructor that implicitly initializes those managed members, - // which will overwrite any non-default initializations performed inside - // of InitComponent() overrides! In this situation, the workaround is to - // define an explicit constructor that calls the base class constructor - // manually, allowing those managed members to be initialized by the - // compiler before InitComponent() overrides then re-assign them. - {$DEFINE WORKAROUND_INLINE_CONSTRUCTORS} -{$ENDIF} - -{$IFDEF VCL_5_OR_ABOVE} - {$IFNDEF FPC} - {$IFNDEF KYLIX} - {$DEFINE HAS_RemoveFreeNotification} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_GetObjectProp} - {$DEFINE HAS_TObjectList} - {$DEFINE HAS_StrToInt64Def} -{$ENDIF} - -{$IFDEF VCL_6_OR_ABOVE} - {$DEFINE HAS_PCardinal} - {$DEFINE HAS_PByte} - {$DEFINE HAS_PWord} - {$DEFINE HAS_PPointer} - {$DEFINE HAS_TList_Assign} - {$DEFINE HAS_sLineBreak} - {$DEFINE HAS_RaiseLastOSError} - {$DEFINE HAS_SysUtils_IncludeExcludeTrailingPathDelimiter} - {$DEFINE HAS_SysUtils_DirectoryExists} - {$DEFINE HAS_UNIT_DateUtils} - {$DEFINE HAS_UNIT_StrUtils} - {$DEFINE HAS_UNIT_Types} - {$DEFINE HAS_TryStrToInt} - {$DEFINE HAS_TryStrToInt64} - {$DEFINE HAS_TryEncodeDate} - {$DEFINE HAS_TryEncodeTime} - {$DEFINE HAS_ENUM_ELEMENT_VALUES} - {$IFNDEF FPC} - {$DEFINE HAS_IInterface} - {$DEFINE HAS_TSelectionEditor} - {$DEFINE HAS_TStringList_CaseSensitive} - {$DEFINE HAS_AcquireExceptionObject} - {$IFNDEF KYLIX} - {$DEFINE HAS_DEPRECATED} - {$DEFINE HAS_SYMBOL_PLATFORM} - {$DEFINE HAS_UNIT_PLATFORM} - {$IFNDEF VCL_8_OR_ABOVE} - // Delphi 6 and 7 have an annoying bug that if a class method is declared as - // deprecated, the compiler will emit a "symbol is deprecated" warning - // on the method's implementation! So we will have to wrap implementations - // of deprecated methods with {$WARN SYMBOL_DEPRECATED OFF} directives - // to disable that warning. - {$DEFINE DEPRECATED_IMPL_BUG} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$IFNDEF DOTNET} - //Widget defines are omitted in .NET - {$DEFINE VCL_60_PLUS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_7_OR_ABOVE} - {$IFNDEF FPC} - {$DEFINE HAS_UInt64} // Note: it was just an alias for Int64 until D2006! - {$DEFINE HAS_NAMED_THREADS} - {$DEFINE HAS_TStrings_NameValueSeparator} - {$DEFINE HAS_TStrings_ValueFromIndex} - // Note: there is a ZLib unit available, but it doesn't have everything - // that is available in the System.ZLib unit in Delphi XE2+, so we are - // not going to use this ZLib unit yet... - {.$DEFINE HAS_UNIT_ZLib} - {$ENDIF} - {$DEFINE HAS_TFormatSettings} - {$DEFINE HAS_PosEx} - {$IFNDEF VCL_70} - // not implemented in D7 - {$DEFINE HAS_STATIC_TThread_Queue} - {$ENDIF} - {$IFNDEF CIL} - {$IFNDEF VCL_80} - // not implemented in D8 or .NET - {$DEFINE HAS_STATIC_TThread_Synchronize} - {$ENDIF} - {$ENDIF} -{$ELSE} - {$IFDEF CBUILDER_6} - {$DEFINE HAS_NAMED_THREADS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2005_OR_ABOVE} - {$IFDEF DCC} - // class helpers were first introduced in D2005, but were buggy and not - // officially supported until D2006... - {.$DEFINE HAS_CLASS_HELPER} - {$ENDIF} -{$ELSE} - {$IFDEF DCC} - // InterlockedCompareExchange() was declared in the Windows unit using Pointer - // parameters until Delphi 2005, when it was switched to Longint parameters - // instead to match the actual Win32 API declaration. - {$DEFINE HAS_InterlockedCompareExchange_Pointers} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2006_OR_ABOVE} - {$DEFINE USE_INLINE} - {$DEFINE HAS_2PARAM_FileAge} - {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? - {$DEFINE HAS_CLASS_HELPER} - {$IFDEF WINDOWS} - // System.RegisterExpectedMemoryLeak() is only available on Windows at this time - {$DEFINE HAS_System_RegisterExpectedMemoryLeak} - {$ENDIF} - // In C++Builder 2006 and 2007, UInt64 is emitted as signed __int64 in HPP - // files instead of as unsigned __int64. This causes conflicts in overloaded - // routines that have (U)Int64 parameters. This was fixed in C++Builder 2009... - {$IFDEF CBUILDER} - {$DEFINE BROKEN_UINT64_HPPEMIT} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2007_OR_ABOVE} - {$IFNDEF CBUILDER_2007} - // class properties are broken in C++Builder 2007, causing AVs at compile-time - {$DEFINE HAS_CLASSPROPERTIES} - {$ENDIF} - // Native(U)Int exist but are buggy, so do not use them yet - {.$DEFINE HAS_NativeInt} - {.$DEFINE HAS_NativeUInt} - {$DEFINE HAS_DWORD_PTR} - {$DEFINE HAS_ULONG_PTR} - {$DEFINE HAS_ULONGLONG} - {$DEFINE HAS_PGUID} - {$DEFINE HAS_PPAnsiChar} - {$DEFINE HAS_CurrentYear} - {$IFNDEF DOTNET} - {$DEFINE HAS_TIMEUNITS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2009_OR_ABOVE} - {$IFNDEF DOTNET} - {$DEFINE STRING_IS_UNICODE} - {$DEFINE HAS_UnicodeString} - {$DEFINE HAS_TEncoding} - {$DEFINE HAS_TCharacter} - {$DEFINE HAS_InterlockedCompareExchangePointer} - {$DEFINE HAS_WIDE_TCharArray} - {$DEFINE HAS_PUInt64} - {$IFDEF VCL_2009} - // TODO: need to differentiate between RTM and Update 1 - // FmtStr() is broken in RTM but was fixed in Update 1 - {$DEFINE BROKEN_FmtStr} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_CLASSVARS} - {$DEFINE HAS_DEPRECATED_MSG} - {$DEFINE HAS_TBytes} - // Native(U)Int are still buggy, so do not use them yet - {.$DEFINE HAS_NativeInt} - {.$DEFINE HAS_NativeUInt} - {$DEFINE HAS_Int8} - {$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_UIntToStr} - // UInt64 is now emitted as unsigned __int64 in HPP files - {$IFDEF CBUILDER} - {$UNDEF BROKEN_UINT64_HPPEMIT} - {$ENDIF} - {$IFDEF DCC} - {$IFDEF WINDOWS} - // Exception.RaiseOuterException() is only available on Windows at this time - {$DEFINE HAS_Exception_RaiseOuterException} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_SetCodePage} - {$DEFINE HAS_PRawByteString} - {$DEFINE HAS_TThreadProcedure} -{$ENDIF} - -{$IFDEF VCL_2010_OR_ABOVE} - {$DEFINE HAS_CLASSCONSTRUCTOR} - {$DEFINE HAS_CLASSDESTRUCTOR} - {$DEFINE HAS_DELAYLOAD} - {$DEFINE HAS_TThread_NameThreadForDebugging} - {$DEFINE DEPRECATED_TThread_SuspendResume} - // Native(U)Int are finally ok to use now - {$DEFINE HAS_NativeInt} - {$DEFINE HAS_NativeUInt} - {$DEFINE HAS_USHORT} - {$DEFINE HAS_IOUtils_TPath} -{$ENDIF} - -{$IFDEF VCL_XE_OR_ABOVE} - {$DEFINE HAS_TFormatSettings_Object} - {$DEFINE HAS_LocaleCharsFromUnicode} - {$DEFINE HAS_UnicodeFromLocaleChars} - {$DEFINE HAS_PLongBool} - {$DEFINE HAS_PVOID} - {$DEFINE HAS_ULONG64} - {$DEFINE HAS_TEncoding_GetEncoding_ByEncodingName} - {$DEFINE HAS_DateUtils_TTimeZone} - {$IFDEF DCC} - // Exception.RaiseOuterException() is now available on all platforms - {$DEFINE HAS_Exception_RaiseOuterException} - {$ENDIF} - {$IFNDEF DOTNET} - {$DEFINE HAS_TInterlocked} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE2_OR_ABOVE} - {$DEFINE HAS_SIZE_T} - {$DEFINE HAS_PSIZE_T} - {$DEFINE HAS_SSIZE_T} - {$DEFINE HAS_PSSIZE_T} - {$DEFINE HAS_LONG} - {$DEFINE HAS_ComponentPlatformsAttribute} - {$DEFINE HAS_ComponentPlatformsAttribute_Win32} - {$DEFINE HAS_ComponentPlatformsAttribute_Win64} - {$DEFINE HAS_ComponentPlatformsAttribute_OSX32} - {$DEFINE HAS_System_ReturnAddress} - {$DEFINE HAS_DIRECTIVE_WARN_DEFAULT} - {$DEFINE HAS_UNIT_System_ZLib} -{$ENDIF} - -{$IFDEF VCL_XE3_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_ZEROBASEDSTRINGS} - {$DEFINE HAS_SysUtils_TStringHelper} - {$IFDEF NEXTGEN} - {$DEFINE DCC_NEXTGEN} - {$DEFINE HAS_MarshaledAString} - {$DEFINE USE_MARSHALLED_PTRS} - {$IFDEF AUTOREFCOUNT} - {$DEFINE USE_OBJECT_ARC} - {$ENDIF} - {$ENDIF} - // technically, these are present in XE3, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} - {.$DEFINE HAS_ComponentPlatformsAttribute_Android} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32} - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} - {.$DEFINE HAS_ComponentPlatformsAttribute_WinNX32} -{$ENDIF} - -{$IFDEF VCL_XE4_OR_ABOVE} - {$DEFINE HAS_AnsiStrings_StrPLCopy} - {$DEFINE HAS_AnsiStrings_StrLen} - {$DEFINE HAS_Character_TCharHelper} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} -{$ENDIF} - -{$IFDEF VCL_XE5_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_Android} -{$ENDIF} - -{$IFDEF VCL_XE5_UPDATE2_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_LINKUNIT} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_NAMESPACE} -{$ENDIF} - -{$IFDEF VCL_XE7_OR_ABOVE} - {$DEFINE HAS_TNetEncoding} -{$ENDIF} - -{$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device32} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device64} - // technically, these are present in XE8, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64} - {.$DEFINE HAS_ComponentPlatformsAttribute_WinIoT32} -{$ENDIF} - -{$IFDEF VCL_10_0_OR_ABOVE} - {$IFDEF ANDROID} - {$DEFINE HAS_TAndroidHelper} - {$ENDIF} - // technically, these are present in 10.0 Seattle, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_WinARM} -{$ENDIF} - -{$IFDEF VCL_10_1_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_LEGACYHPP} - {$DEFINE HAS_TStrings_AddPair} - // technically, these are present in 10.1 Berlin, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_OSX64} - {.$DEFINE HAS_ComponentPlatformsAttribute_OSXNX64} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32Arm} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64Arm} - {.$DEFINE HAS_ComponentPlatformsAttribute_Android64} -{$ENDIF} - -{$IFDEF VCL_10_2_OR_ABOVE} - {.$WARN IMPLICIT_INTEGER_CAST_LOSS OFF} - {.$WARN IMPLICIT_CONVERSION_LOSS OFF} - {.$WARN COMBINING_SIGNED_UNSIGNED64 OFF} - {$DEFINE HAS_STATIC_TThread_ForceQueue} - // In Delphi 10.2 Tokyo, TThread.ForceQueue() is broken on Android, the - // passed in procedure is called immediately instead of being delayed! - {$IFDEF ANDROID} - {$DEFINE BROKEN_TThread_ForceQueue} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator32} - {$DEFINE HAS_ComponentPlatformsAttribute_Android32Arm} - {$DEFINE HAS_ComponentPlatformsAttribute_WinARM32} - {$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} // removed in 10.3 Rio - // technically, these are present in 10.3 Rio, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator64} - {$IFDEF DCC} - {$IFDEF LINUX} - // RLebeau 9/25/2019: there is a bug in the IDE when debugging Linux projects - // where the EThreadNameException exception raised by TThread.NameThreadForDebugging() - // is not handled correctly. - {$UNDEF HAS_NAMED_THREADS} - {$ENDIF} - {$ENDIF} - {$IFDEF ANDROID} - {$UNDEF BROKEN_TThread_ForceQueue} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_UPDATE2_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_AllPlatforms} - {$DEFINE HAS_ComponentPlatformsAttribute_OSX64} -{$ENDIF} - -{$IFDEF VCL_10_4_OR_ABOVE} - // 0-based string indexing via '[]' is turned off by default in Delphi 10.4. - // TStringHelper is always 0-indexed, flat RTL functions are always 1-indexed, - // and now '[]' is 1-indexed again on all platforms - {$ZEROBASEDSTRINGS OFF} - // is the default. - {.$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} -{$ENDIF} - -{$IFDEF VCL_11_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm32} - {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm64} - {$DEFINE HAS_ComponentPlatformsAttribute_OSXArm64} -{$ENDIF} - -// Delphi XE+ cross-compiling -{$IFNDEF FPC} - {$IFDEF POSIX} - {$IF RTLVersion >= 22.0} - {$DEFINE UNIX} - {$UNDEF USE_BASEUNIX} - {$DEFINE VCL_CROSS_COMPILE} - {$DEFINE USE_VCL_POSIX} - {$IFEND} - {$ENDIF} - {$IFDEF LINUX} - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF RTLVersion >= 22.0} - {$DEFINE VCL_CROSS_COMPILE} - {$DEFINE USE_VCL_POSIX} - {$IFEND} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_CROSS_COMPILE} - {$UNDEF KYLIXCOMPAT} -{$ELSE} - {$IFDEF KYLIXCOMPAT} - {$linklib c} - {$ENDIF} -{$ENDIF} - -{$IFDEF FPC} - {$DEFINE USE_INLINE} - {$DEFINE USE_CLASSINLINE} - {$DEFINE USE_TBitBtn} //use Bit Buttons instead of Buttons - {$DEFINE FPC_REINTRODUCE_BUG} - {$DEFINE FPC_CIRCULAR_BUG} - {$DEFINE NO_REDECLARE} - {$DEFINE BYTE_COMPARE_SETS} - {$DEFINE HAS_QWord} // TODO: when was QWord introduced? - {$DEFINE HAS_PQWord} // TODO: when was PQWord introduced? - {$IFDEF FPC_2_1_5_OR_ABOVE} - {$DEFINE HAS_UInt64} - {.$DEFINE HAS_PUInt64} // TODO: is this defined? - {$ENDIF} - {$IFDEF FPC_2_2_0_OR_ABOVE} - {$DEFINE HAS_InterlockedCompareExchange_Pointers} - {$ENDIF} - {$IFDEF FPC_2_2_2_OR_ABOVE} - {$DEFINE HAS_SharedSuffix} - {$ENDIF} - {$IFDEF FPC_2_2_4_OR_ABOVE} - // these types are only available on Unix systems (FreeBSD, Linux, etc) - {$IFDEF UNIX} - {$DEFINE HAS_UNIT_UnixType} - {$DEFINE HAS_SIZE_T} - {$DEFINE HAS_PSIZE_T} - {$DEFINE HAS_SSIZE_T} - {$DEFINE HAS_PSSIZE_T} - {$DEFINE HAS_TIME_T} - {$DEFINE HAS_PTIME_T} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_PtrInt} - {$DEFINE HAS_PtrUInt} - {$DEFINE HAS_PGUID} - {$DEFINE HAS_LPGUID} - {$DEFINE HAS_PPAnsiChar} - {$DEFINE HAS_ENUM_ELEMENT_VALUES} - {$DEFINE HAS_AcquireExceptionObject} // TODO: when was AcquireExceptionObject introduced? - {$IFDEF WINDOWS} - {$DEFINE HAS_ULONG_PTR} - {.$DEFINE HAS_ULONGLONG} // TODO: is this defined? - {$ENDIF} - {$DEFINE HAS_UNIT_ctypes} - {$DEFINE HAS_sLineBreak} - {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? - {$IFDEF FPC_HAS_UNICODESTRING} - {$DEFINE HAS_UnicodeString} - {$ELSE} - {$IFDEF FPC_2_4_0_OR_ABOVE} - {$DEFINE HAS_UnicodeString} - {$ENDIF} - {$ENDIF} - {$IFDEF FPC_2_4_4_OR_ABOVE} - {$DEFINE DEPRECATED_TThread_SuspendResume} - {$DEFINE HAS_DEPRECATED} // TODO: when was deprecated introduced? Possibly 1.9.x - {$DEFINE HAS_DEPRECATED_MSG} // TODO: when was message support added? Possibly 2.4.x - {$DEFINE HAS_STATIC_TThread_Synchronize} - {$IFNDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE USE_SEMICOLON_BEFORE_DEPRECATED} // TODO: which earlier versions require a semicolon? - {$ENDIF} - {$ENDIF} - {$IFDEF FPC_2_6_0_OR_ABOVE} - {$DEFINE HAS_NativeInt} - {$DEFINE HAS_NativeUInt} - {$DEFINE HAS_CLASS_HELPER} - {$ENDIF} - {$IFDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE HAS_Int8} - {$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_GetLocalTimeOffset} - {$DEFINE HAS_UniversalTimeToLocal} - {$DEFINE HAS_LocalTimeToUniversal} - {$ENDIF} - {$IFDEF FPC_2_6_4_OR_ABOVE} - {$DEFINE HAS_PInt8} - {$DEFINE HAS_PUInt8} - {$DEFINE HAS_PInt16} - {$DEFINE HAS_PUInt16} - {$DEFINE HAS_PInt32} - {$DEFINE HAS_PUInt32} - {$ENDIF} - {$IFDEF FPC_3_0_0_OR_ABOVE} - {$DEFINE HAS_STATIC_TThread_Queue} - {$DEFINE HAS_SetCodePage} - {$ENDIF} - {$IFDEF FPC_UNICODESTRINGS} - {$DEFINE STRING_IS_UNICODE} - {$ENDIF} - {$IFDEF FPC_3_1_1_OR_ABOVE} - {$DEFINE HAS_STATIC_TThread_ForceQueue} // requires rev 37359+ - {$DEFINE HAS_PRawByteString} - {$DEFINE HAS_UIntToStr} // requires rev 40529+ - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - {$DEFINE WIDGET_WINFORMS} -{$ELSE} - {$DEFINE WIDGET_VCL_LIKE} // LCL included. - {$DEFINE WIDGET_VCL_LIKE_OR_KYLIX} - {$IFDEF FPC} - {$DEFINE WIDGET_LCL} - {$ELSE} - {$IFDEF KYLIX} - {$DEFINE WIDGET_KYLIX} - {$ELSE} - {$DEFINE WIDGET_VCL} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -// .NET and Delphi 2009+ support UNICODE strings natively! -// -// FreePascal 2.4.0+ supports UnicodeString, but does not map its -// native String type to UnicodeString except when {$MODE DelphiUnicode} -// or {$MODESWITCH UnicodeStrings} is enabled. However, UNICODE is not -// defined in that mode yet until its RTL has been updated to support -// UnicodeString. STRING_UNICODE_MISMATCH is defined when the native -// String/Char types do not map to the same types that APIs are expecting -// based on whether UNICODE is defined or not. -// -// NOTE: Do not define UNICODE here. The compiler defines -// the symbol automatically. -{$IFDEF STRING_IS_UNICODE} - {$IFNDEF UNICODE} - {$DEFINE STRING_UNICODE_MISMATCH} - {$ENDIF} -{$ELSE} - {$DEFINE STRING_IS_ANSI} - {$IFDEF UNICODE} - {$DEFINE STRING_UNICODE_MISMATCH} - {$ENDIF} -{$ENDIF} - -{$IFDEF DCC_NEXTGEN} - {$DEFINE NO_ANSI_TYPES} - {.$DEFINE STRING_IS_IMMUTABLE} // Strings are NOT immutable in NEXTGEN yet - {$IFDEF USE_OBJECT_ARC} - // TODO: move these to an appropriate section. Not doing this yet because - // it is a major interface change to switch to Generics and we should - // maintain backwards compatibility with earlier compilers for the time - // being. Defining them only here for now because the non-Generic versions - // of these classes have become deprecated by ARC and so we need to start - // taking advantage of the Generics versions... - {$DEFINE HAS_UNIT_Generics_Collections} - {$DEFINE HAS_UNIT_Generics_Defaults} - {$DEFINE HAS_GENERICS_TDictionary} - {$DEFINE HAS_GENERICS_TList} - {$DEFINE HAS_GENERICS_TObjectList} - {$DEFINE HAS_GENERICS_TThreadList} - // TArray.Copy() was introduced in XE7 but was buggy. It was fixed in XE8: - // - // RSP-9763 TArray.Copy copies from destination to source for unmanaged types - // https://quality.embarcadero.com/browse/RSP-9763 - // - {$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE HAS_GENERICS_TArray_Copy} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -// TODO: Ansi data types were disabled on mobile platforms in XE3, but -// UTF8String and RawByteString were re-enabled in 10.1 Berlin! What else, -// if anything, was re-enabled to facilitate that? -// -// UPDATE: In 10.4 Sydney, AnsiChar and AnsiString were re-enabled on -// mobile platforms! NEXTGEN is no longer defined in the mobile compilers. -{$IFDEF NO_ANSI_TYPES} - {$UNDEF HAS_AnsiString} - {$UNDEF HAS_AnsiChar} - {$UNDEF HAS_PAnsiChar} - {$UNDEF HAS_PPAnsiChar} - {$UNDEF HAS_AnsiStrings_StrPLCopy} - {$UNDEF HAS_AnsiStrings_StrLen} -{$ENDIF} - -{$IFDEF WIN32} - {$DEFINE WIN32_OR_WIN64} -{$ENDIF} -{$IFDEF WIN64} - {$DEFINE WIN32_OR_WIN64} -{$ENDIF} - -{$IFDEF WIN32_OR_WIN64} - {$DEFINE USE_ZLIB_UNIT} - {$IFNDEF DCC_NEXTGEN} - {$DEFINE USE_OPENSSL} // !!! MOVED HERE BY EMBT - {$DEFINE USE_SSPI} - {$IFDEF STRING_IS_UNICODE} - {$DEFINE SSPI_UNICODE} - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF WINCE} - {$DEFINE USE_OPENSSL} - // RLebeau: not sure if the above Win32/64 defines also apply to WinCE, - // so keeping them separate for now... -{$ENDIF} - -// High-performance counters are not reliable on multi-core systems, and have -// been known to cause problems with TIdIOHandler.ReadLn() timeouts in Windows -// XP SP3, both 32-bit and 64-bit. Refer to these discussions for more info: -// -// http://www.virtualdub.org/blog/pivot/entry.php?id=106 -// http://blogs.msdn.com/oldnewthing/archive/2008/09/08/8931563.aspx -// -// Do not enable thus unless you know it will work correctly on your systems! -{$IFDEF WINDOWS} - {.$DEFINE USE_HI_PERF_COUNTER_FOR_TICKS} -{$ENDIF} - -{$IFDEF UNIX} - {$DEFINE USE_OPENSSL} - {$DEFINE USE_ZLIB_UNIT} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF MACOS} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF DARWIN} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF LINUX} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF IOS} - {$DEFINE HAS_getifaddrs} - {$DEFINE USE_OPENSSL} - - // Support for 64-bit ARM iOS Simulator was added in Delphi 11.2 - // TODO: how to detect iOS Simulator in FPC? Does it support 64-bit ARM? - {$IFDEF CPUARM} - {$IFNDEF IOSSIMULATOR} - // RLebeau: For iOS devices, OpenSSL cannot be used as an external library, - // it must be statically linked into the app. For the iOS simulator, this - // is not true. Users who want to use OpenSSL in iOS device apps will need - // to add the static OpenSSL library to the project and then include the - // IdSSLOpenSSLHeaders_static unit in their uses clause. It hooks up the - // statically linked functions for the IdSSLOpenSSLHeaders unit to use... - {$DEFINE STATICLOAD_OPENSSL} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{$IFDEF FREEBSD} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF ANDROID} - {$UNDEF HAS_getifaddrs} -{$ENDIF} - -{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} - {$DEFINE REQUIRES_PROPER_ALIGNMENT} -{$ENDIF} - -// -//iconv defines section. -{$DEFINE USE_ICONV_UNIT} -{$DEFINE USE_ICONV_ENC} -{$IFDEF UNIX} - {$DEFINE USE_ICONV} - {$IFDEF USE_BASEUNIX} - {$IFDEF FPC} - {$UNDEF USE_ICONV_UNIT} - {$ELSE} - {$UNDEF USE_ICONV_ENC} - {$ENDIF} - {$ENDIF} - {$IFDEF KYLIXCOMPAT} - //important!! Iconv functions are defined in the libc.pas Kylix compatible unit. - {$UNDEF USE_ICONV_ENC} - {$UNDEF USE_ICONV_UNIT} - {$ENDIF} -{$ENDIF} -{$IFDEF NETWARELIBC} - {$DEFINE USE_ICONV} - //important!!! iconv functions are defined in the libc.pas Novell Netware header. - //Do not define USE_ICONV_UNIT - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} -{$ENDIF} - -{$UNDEF USE_SAFELOADLIBRARY} -{$IFDEF WINDOWS} - {$UNDEF USE_ICONV_ENC} - {$DEFINE USE_SAFELOADLIBRARY} -{$ENDIF} -// Use here for all *nix systems that you do not want to use iconv library -{$IFDEF FPC} - {$IFDEF ANDROID} - {$UNDEF USE_ICONV} - {$DEFINE USE_LCONVENC} - {$ENDIF} -{$ENDIF} - -{$UNDEF USE_INVALIDATE_MOD_CACHE} -{$UNDEF USE_SAFELOADLIBRARY} -//This must come after the iconv defines because this compiler targets a Unix-like -//operating system. One key difference is that it does have a TEncoding class. -//If this comes before the ICONV defines, it creates problems. -//This also must go before the THandle size calculations. -{$IFDEF VCL_CROSS_COMPILE} - {$IFDEF POSIX} - {$IFNDEF LINUX} - {$DEFINE BSD} - {$ENDIF} - {$DEFINE USE_SAFELOADLIBRARY} - {$DEFINE USE_INVALIDATE_MOD_CACHE} - {$ENDIF} - //important!!! iconv functions are defined in the libc.pas Novell Netware header. - //Do not define USE_ICONVUNIT - {$UNDEF USE_ICONV} - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} - {$DEFINE INT_THREAD_PRIORITY} -{$ENDIF} - -{$IFNDEF USE_ICONV} - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} -{$ENDIF} - -//IMPORTANT!!!! -// -//Do not remove this!!! This is to work around a conflict. In DCC, MACOS -//will mean OS X. In FreePascal, the DEFINE MACOS means MacIntosh System OS Classic. -{$IFDEF DCC} - // DCC defines MACOS for both iOS and OS X platforms, need to differentiate - {$IFDEF MACOS} - {$IFNDEF IOS} - {$DEFINE OSX} - {$DEFINE DARWIN} - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF FPC} - // FPC defines DARWIN for both OSX and iOS, need to differentiate - {$IFDEF DARWIN} - {$IFNDEF IOS} - {$DEFINE OSX} - {$ENDIF} - {$ENDIF} - {$IFDEF MACOS} - {$DEFINE MACOS_CLASSIC} - {$ENDIF} -{$ENDIF} - -{ -BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit -word to an 8 bit byte and an 8 bit byte field named sa_len was added. -} -//Place this only after DARWIN has been defined for Delphi MACOS -{$IFDEF FREEBSD} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF DARWIN} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF MORPHOS} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} - -// Do NOT remove these IFDEF's. They are here because InterlockedExchange -// only handles 32bit values. Some Operating Systems may have 64bit -// THandles. This is not always tied to the platform architecture. - -{$IFDEF AMIGA} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF ATARI} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF BEOS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF BSD} - //I think BSD might handle FreeBSD, NetBSD, OpenBSD, and Darwin - {$IFDEF IOS} - {$IFDEF CPUARM64} - {$DEFINE CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$IFDEF CPUARM32} - {$DEFINE CPU32} - {$ENDIF} - {$DEFINE THANDLE_32} - {$ENDIF} - {$ENDIF} - {$IFDEF OSX} - {$IFDEF FPC} - {$DEFINE THANDLE_32} - {$ELSE} - {$DEFINE THANDLE_CPUBITS} // !!! ADDED OSX BY EMBT - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF EMBEDDED} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF EMX} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF GBA} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF GO32} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF LINUX} - {$IFDEF LINUX64} - {$DEFINE CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$IFDEF LINUX32} - {$DEFINE CPU32} - {$ENDIF} - {$DEFINE THANDLE_32} - {$ENDIF} -{$ENDIF} -{$IFDEF MACOS_CLASSIC} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF MORPHOS} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF NATIVENT} //Native NT for kernel level drivers - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF NDS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF NETWARE} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF NETWARELIBC} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF OS2} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF PALMOS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF SOLARIS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF SYMBIAN} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WII} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WATCOM} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WINDOWS} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} - -// end platform specific stuff for THandle size - -{$IFDEF THANDLE_CPUBITS} - {$IFDEF CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$DEFINE THANDLE_32} - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - {$DEFINE DOTNET_OR_ICONV} -{$ENDIF} -{$IFDEF USE_ICONV} - {$DEFINE DOTNET_OR_ICONV} -{$ENDIF} - -{$UNDEF STREAM_SIZE_64} -{$IFDEF FPC} - {$DEFINE STREAM_SIZE_64} -{$ELSE} - {$IFDEF VCL_6_OR_ABOVE} - {$DEFINE STREAM_SIZE_64} - {$ENDIF} -{$ENDIF} - -{$IFNDEF FREE_ON_FINAL} - {$IFNDEF DOTNET} - {$IFDEF HAS_System_RegisterExpectedMemoryLeak} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_FASTMM4} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_MADEXCEPT} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_LEAKCHECK} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{ -We must determine what the SocketType parameter is for the Socket function. -In DotNET, it's SocketType. In Kylix and the libc.pas Kylix-compatibility -library, it's a __socket_type. In BaseUnix, it's a C-type Integer. In Windows, -it's a LongInt. - -} -{$UNDEF SOCKETTYPE_IS_SOCKETTYPE} -{$UNDEF SOCKETTYPE_IS_CINT} -{$UNDEF SOCKETTYPE_IS___SOCKETTYPE} -{$UNDEF SOCKETTYPE_IS_LONGINT} -{$UNDEF SOCKETTYPE_IS_NUMERIC} -{$UNDEF SOCKET_LEN_IS_socklen_t} -{$IFDEF DOTNET} - {$DEFINE SOCKETTYPE_IS_SOCKETTYPE} -{$ENDIF} -{$IFDEF USE_BASEUNIX} - {$DEFINE SOCKETTYPE_IS_CINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF KYLIXCOMPAT} - {$DEFINE SOCKETTYPE_IS___SOCKETTYPE} -{$ENDIF} -{$IFDEF USE_VCL_POSIX} - {$DEFINE SOCKETTYPE_IS_NUMERIC} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKET_LEN_IS_socklen_t} -{$ENDIF} -{$IFDEF WINDOWS} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF OS2} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF NETWARE} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} - -{Take advantage of some TCP features specific to some stacks. -They work somewhat similarly but there's a key difference. -In Linux, TCP_CORK is turned on to send fixed packet sizes and -when turned-off (uncorked), any remaining data is sent. With -TCP_NOPUSH, this might not happen and remaining data is only sent -before disconnect. TCP_KEEPIDLE and TCP_KEEPINTVL so the IFDEF LINUX and IFDEF -SOLARIS instead of IFDEF UNIX is not an error, it's deliberate.} -{$UNDEF HAS_TCP_NOPUSH} -{$UNDEF HAS_TCP_CORK} -{$UNDEF HAS_TCP_KEEPIDLE} -{$UNDEF HAS_TCP_KEEPINTVL} -{$UNDEF HAS_SOCKET_NOSIGPIPE} -{$IFDEF BSD} - {$DEFINE HAS_TCP_NOPUSH} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE HAS_TCP_NOPUSH} -{$ENDIF} -{$IFDEF LINUX} - {$DEFINE HAS_TCP_CORK} - {$DEFINE HAS_TCP_KEEPIDLE} - {$DEFINE HAS_TCP_KEEPINTVL} -{$ENDIF} -{$IFDEF SOLARIS} - {$DEFINE HAS_TCP_CORK} -{$ENDIF} -{$IFDEF NETBSD} - {$DEFINE HAS_TCP_CORK} - {$DEFINE HAS_TCP_KEEPIDLE} - {$DEFINE HAS_TCP_KEEPINTVL} -{$ENDIF} -{$IFDEF USE_VCL_POSIX} - // TODO: which platforms actually have SO_NOSIGPIPE available? - {$DEFINE HAS_SOCKET_NOSIGPIPE} - {$IFDEF ANDROID} - {$UNDEF HAS_SOCKET_NOSIGPIPE} - {$ENDIF} - {$IFDEF LINUX} - {$UNDEF HAS_SOCKET_NOSIGPIPE} - {$ENDIF} -{$ENDIF} -{end Unix OS specific stuff} -{$IFDEF DEBUG} - {$UNDEF USE_INLINE} -{$ENDIF} - -// RLebeau 5/24/2015: In C++Builder 2006 and 2007, UInt64 is emitted as -// signed __int64 in HPP files instead of as unsigned __int64. This causes -// conflicts in overloaded routines that have (U)Int64 parameters. This -// was fixed in C++Builder 2009. For compilers that do not have a native -// UInt64 type, or for C++Builder 2006/2007, let's define a record type -// that can hold UInt64 values... -{$IFDEF HAS_UInt64} - {$IFDEF BROKEN_UINT64_HPPEMIT} - {$DEFINE TIdUInt64_HAS_QuadPart} - {$ENDIF} -{$ELSE} - {$IFNDEF HAS_QWord} - {$DEFINE TIdUInt64_HAS_QuadPart} - {$ENDIF} -{$ENDIF} - -// RLebeau 9/5/2013: it would take a lot of work to re-write Indy to support -// both 0-based and 1-based string indexing, so we'll just turn off 0-based -// indexing for now... -{$IFDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} - {$ZEROBASEDSTRINGS OFF} -{$ENDIF} +{$IFDEF CONDITIONALEXPRESSIONS} + // Must be at the top... + {$IF CompilerVersion >= 24.0} + {$LEGACYIFEND ON} + {$IFEND} +{$ENDIF} + +// General + +// Make this $DEFINE to use the 16 color icons required by Borland +// or DEFINE to use the 256 color Indy versions +{.$DEFINE Borland} + +// S.G. 4/9/2002: IPv4/IPv6 general switch (for defaults only) +{$DEFINE IdIPv4} // use IPv4 by default +{.$IFDEF IdIPv6} // use IPv6 by default + +{$DEFINE INDY100} +{$DEFINE 10_7_0} //so developers can IFDEF for this product version +{$DEFINE 10_7_0_0} //so developers can IFDEF for this specific version + +// When generating C++Builder output files, certain workarounds to compiler +// problems need to be enabled! When invoking DCC on the command-line, use +// the -DBCB parameter. When invoking MSBUILD, include the DCC_Define="BCB" +// attribute in the /p parameter. +{$IFDEF BCB} + {$DEFINE CBUILDER} +{$ELSE} + {$DEFINE DELPHI} +{$ENDIF} + +{$UNDEF USE_OPENSSL} +{$UNDEF STATICLOAD_OPENSSL} + +{$UNDEF USE_ZLIB_UNIT} +{$UNDEF USE_SSPI} + +// $DEFINE the following if the global objects in the IdStack and IdThread +// units should be freed on finalization +{$IFDEF FPC} +{$DEFINE FREE_ON_FINAL} +{$ELSE} +{$UNDEF FREE_ON_FINAL} +{$ENDIF} + +// Make sure the following is $DEFINE'd only for suitable environments +// as specified further below. This works in conjunction with the +// FREE_ON_FINAL define above. +{$UNDEF REGISTER_EXPECTED_MEMORY_LEAK} +{$UNDEF HAS_System_RegisterExpectedMemoryLeak} + +// FastMM is natively available in BDS 2006 and higher. $DEFINE the +// following if FastMM has been installed manually in earlier versions +{.$DEFINE USE_FASTMM4} +{$UNDEF USE_FASTMM4} + +// $DEFINE the following if MadExcept has been installed manually in +// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced +// in BDS 2006) +{.$DEFINE USE_MADEXCEPT} +{$UNDEF USE_MADEXCEPT} + +// $DEFINE the following if LeakCheck has been installed manually in +// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced +// in BDS 2006) +{.$DEFINE USE_LEAKCHECK} +{$UNDEF USE_LEAKCHECK} + +// Make sure the following are $DEFINE'd only for Delphi/C++Builder 2009 onwards +// as specified further below. The VCL is fully Unicode, where the 'String' +// type maps to System.UnicodeString, not System.AnsiString anymore +{$UNDEF STRING_IS_UNICODE} +{$UNDEF STRING_IS_ANSI} +{$UNDEF STRING_UNICODE_MISMATCH} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. Delphi/C++Builder Mobile/NextGen compilers +// do not support Ansi data types anymore, and is moving away from raw +// pointers as well. +// +// UPDATE: in Delphi/C++Builder 10.4, all Ansi types are supported again on +// all platforms, including the mobile compilers. +{$DEFINE HAS_AnsiString} +{$DEFINE HAS_AnsiChar} +{$DEFINE HAS_PAnsiChar} +{$UNDEF HAS_PPAnsiChar} +{$UNDEF NO_ANSI_TYPES} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. Delphi/C++Builder Mobile/NextGen compilers +// use ARC for TObject life time management. +// +// UPDATE: ARC for TObject lifetime management has been removed in +// Delphi/C++Builder 10.4 mobile compilers. All platforms now use a single +// unified memory management model! +{$UNDEF USE_MARSHALLED_PTRS} +{$UNDEF HAS_MarshaledAString} +{$UNDEF USE_OBJECT_ARC} + +// Make sure the following is $DEFINE'd only for suitable environments +// as specified further below. +{$UNDEF STRING_IS_IMMUTABLE} +{$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. +{$UNDEF HAS_TEncoding} +{$UNDEF HAS_TEncoding_GetEncoding_ByEncodingName} +{$UNDEF HAS_Exception_RaiseOuterException} +{$UNDEF HAS_System_ReturnAddress} +{$UNDEF HAS_TCharacter} +{$UNDEF HAS_TInterlocked} +{$UNDEF HAS_TNetEncoding} + +// Make sure that this is defined only for environments where we are using +// the iconv library to charactor conversions. +{.$UNDEF USE_ICONV} +{.$UNDEF USE_LCONVENC} + +//Define for Delphi cross-compiler targetting Posix +{$UNDEF USE_VCL_POSIX} +{$UNDEF HAS_ComponentPlatformsAttribute} +{$UNDEF HAS_ComponentPlatformsAttribute_Win32} +{$UNDEF HAS_ComponentPlatformsAttribute_Win64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSX32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator32} +{$UNDEF HAS_ComponentPlatformsAttribute_Android} +{$UNDEF HAS_ComponentPlatformsAttribute_Android32Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device32} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux64} +{$UNDEF HAS_ComponentPlatformsAttribute_WinNX32} +{$UNDEF HAS_ComponentPlatformsAttribute_WinIoT32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device64} +{$UNDEF HAS_ComponentPlatformsAttribute_WinARM} +{$UNDEF HAS_ComponentPlatformsAttribute_WinARM32} +{$UNDEF HAS_ComponentPlatformsAttribute_OSX64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux32Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux64Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Android64} +{$UNDEF HAS_ComponentPlatformsAttribute_Android64Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator64} +{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm32} +{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSXArm64} +{$UNDEF HAS_ComponentPlatformsAttribute_AllPlatforms} +{$UNDEF HAS_DIRECTIVE_WARN_DEFAULT} + +// Define for Delphi to auto-generate platform-appropriate '#pragma link' statements in HPP files +{$UNDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT} + +// detect compiler versions + +{$IFNDEF FPC} + + // TODO: to detect features in Delphi/C++Builder v6 and later, use CompilerVersion + // and RTLVersion constants instead of VERXXX defines. We still support v5, which + // does not have such constants. + + // Delphi 4 + {$IFDEF VER120} + {$DEFINE DCC} + {$DEFINE VCL_40} + {$DEFINE DELPHI_4} + {$ENDIF} + + // C++Builder 4 + {$IFDEF VER125} + {$DEFINE DCC} + {$DEFINE VCL_40} + {$DEFINE CBUILDER_4} + {$ENDIF} + + // Delphi & C++Builder 5 + {$IFDEF VER130} + {$DEFINE DCC} + {$DEFINE VCL_50} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_5} + {$ELSE} + {$DEFINE DELPHI_5} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 6 + {$IFDEF VER140} + {$DEFINE DCC} + {$DEFINE VCL_60} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_6} + {$ELSE} + {$DEFINE DELPHI_6} + {$ENDIF} + {$ENDIF} + + //Delphi 7 + {$IFDEF VER150} + {$DEFINE DCC} + {$DEFINE VCL_70} + {$DEFINE DELPHI_7} // there was no C++ Builder 7 + {$ENDIF} + + //Delphi 8 + {$IFDEF VER160} + {$DEFINE DCC} + {$DEFINE VCL_80} + {$DEFINE DELPHI_8} // there was no C++ Builder 8 + {$ENDIF} + + //Delphi 2005 + {$IFDEF VER170} + {$DEFINE DCC} + {$DEFINE VCL_2005} + {$DEFINE DELPHI_2005} // there was no C++Builder 2005 + {$ENDIF} + + // NOTE: CodeGear decided to make Highlander be a non-breaking release + // (no interface changes, thus fully backwards compatible without any + // end user code changes), so VER180 applies to both BDS 2006 and + // Highlander prior to the release of RAD Studio 2007. Use VER185 to + // identify Highlanger specifically. + + //Delphi & C++Builder 2006 + //Delphi & C++Builder 2007 (Highlander) + {$IFDEF VER180} + {$DEFINE DCC} + {$DEFINE VCL_2006} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2006} + {$ELSE} + {$DEFINE DELPHI_2006} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2007 (Highlander) + {$IFDEF VER185} + {$DEFINE DCC} + {$UNDEF VCL_2006} + {$DEFINE VCL_2007} + {$IFDEF CBUILDER} + {$UNDEF CBUILDER_2006} + {$DEFINE CBUILDER_2007} + {$ELSE} + {$UNDEF DELPHI_2006} + {$DEFINE DELPHI_2007} + {$ENDIF} + {$ENDIF} + + // BDS 2007 NET personality uses VER190 instead of 185. + //Delphi .NET 2007 + {$IFDEF VER190} + {$DEFINE DCC} + {$IFDEF CIL} + //Delphi 2007 + {$DEFINE VCL_2007} + {$DEFINE DELPHI_2007} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2009 (Tiburon) + {$IFDEF VER200} + {$DEFINE DCC} + {$DEFINE VCL_2009} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2009} + {$ELSE} + {$DEFINE DELPHI_2009} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2010 (Weaver) + {$IFDEF VER210} + {$DEFINE DCC} + {$DEFINE VCL_2010} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2010} + {$ELSE} + {$DEFINE DELPHI_2010} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder XE (Fulcrum) + {$IFDEF VER220} + //REMOVE DCC DEFINE after the next Fulcrum beta. + //It will be defined there. + {$IFNDEF DCC} + {$DEFINE DCC} + {$ENDIF} + {$DEFINE VCL_XE} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE} + {$ELSE} + {$DEFINE DELPHI_XE} + {$ENDIF} + {$ENDIF} + + // DCC is now defined by the Delphi compiler starting in XE2 + + //Delphi & CBuilder XE2 (Pulsar) + {$IFDEF VER230} + {$DEFINE VCL_XE2} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE2} + {$ELSE} + {$DEFINE DELPHI_XE2} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE3 (Waterdragon) + //Delphi & CBuilder XE3.5 (Quintessence - early betas only) + {$IFDEF VER240} + {$DEFINE VCL_XE3} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE3} + {$ELSE} + {$DEFINE DELPHI_XE3} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE4 (Quintessence) + {$IFDEF VER250} + {$UNDEF VCL_XE3} + {$DEFINE VCL_XE4} + {$IFDEF CBUILDER} + {$UNDEF CBUILDER_XE3} + {$DEFINE CBUILDER_XE4} + {$ELSE} + {$UNDEF DELPHI_XE3} + {$DEFINE DELPHI_XE4} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE5 (Zephyr) + {$IFDEF VER260} + {$DEFINE VCL_XE5} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE5} + {$ELSE} + {$DEFINE DELPHI_XE5} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder AppMethod + //AppMethod is just XE5 for mobile only, VCL is removed + {$IFDEF VER265} + {$DEFINE VCL_XE5} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE5} + {$ELSE} + {$DEFINE DELPHI_XE5} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE6 (Proteus) + {$IFDEF VER270} + {$DEFINE VCL_XE6} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE6} + {$ELSE} + {$DEFINE DELPHI_XE6} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE7 (Carpathia) + {$IFDEF VER280} + {$DEFINE VCL_XE7} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE7} + {$ELSE} + {$DEFINE DELPHI_XE7} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE8 (Elbrus) + {$IFDEF VER290} + {$DEFINE VCL_XE8} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE8} + {$ELSE} + {$DEFINE DELPHI_XE8} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.0 Seattle (Aitana) + {$IFDEF VER300} + {$DEFINE VCL_10_0} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_VCL_10_0} + {$ELSE} + {$DEFINE DELPHI_VCL_10_0} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.1 Berlin (BigBen) + {$IFDEF VER310} + {$DEFINE VCL_10_1} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_1} + {$ELSE} + {$DEFINE DELPHI_10_1} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.2 Tokyo (Godzilla) + {$IFDEF VER320} + {$DEFINE VCL_10_2} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_2} + {$ELSE} + {$DEFINE DELPHI_10_2} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.3 Rio (Carnival) + {$IFDEF VER330} + {$DEFINE VCL_10_3} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_3} + {$ELSE} + {$DEFINE DELPHI_10_3} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.4 Sydney (Denali) + {$IFDEF VER340} + {$DEFINE VCL_10_4} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_4} + {$ELSE} + {$DEFINE DELPHI_10_4} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 11.0 Alexandria (Olympus) + {$IFDEF VER350} + {$DEFINE VCL_11} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_11} + {$ELSE} + {$DEFINE DELPHI_11} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 12.0 Athens (Yukon) + {$IFDEF VER360} + {$DEFINE VCL_12} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_12} + {$ELSE} + {$DEFINE DELPHI_12} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 13.0+ (?) + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF CompilerVersion >= 37} + {$MESSAGE WARN 'Unknown compiler version detected! Assuming >= 13.x '} + {$DEFINE VCL_UNKNOWN_VERSION} + {$DEFINE VCL_13} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_13} + {$ELSE} + {$DEFINE DELPHI_13} + {$ENDIF} + {$IFEND} + {$ENDIF} + + // Kylix + // + //Important: Don't use CompilerVersion here as IF's are evaluated before + //IFDEF's and Kylix 1 does not have CompilerVersion defined at all. + {$IFDEF LINUX} + {$DEFINE UNIX} + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF (RTLVersion >= 14.0) and (RTLVersion <= 14.5) } + {$DEFINE KYLIX} + {$IF RTLVersion = 14.5} + {$DEFINE KYLIX_3} + {$ELSEIF RTLVersion >= 14.2} + {$DEFINE KYLIX_2} + {$ELSE} + {$DEFINE KYLIX_1} + {$IFEND} + {$IFEND} + {$ENDIF} + {$ENDIF} + +{$ENDIF} + +// Delphi.NET +// Covers D8+ +{$IFDEF CIL} + // Platform specific conditional. Used for platform specific code. + {$DEFINE DOTNET} + {$DEFINE STRING_IS_UNICODE} + {$DEFINE STRING_IS_IMMUTABLE} + {.$DEFINE HAS_Int8} + {.$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_UInt64} +{$ENDIF} + +{$IFDEF KYLIX} + {$DEFINE VCL_60} + {$DEFINE INT_THREAD_PRIORITY} + {$DEFINE CPUI386} + {$UNDEF USE_BASEUNIX} + + {$IFDEF KYLIX_3} + {$DEFINE KYLIX_3_OR_ABOVE} + {$ENDIF} + + {$IFDEF KYLIX_3_OR_ABOVE} + {$DEFINE KYLIX_2_OR_ABOVE} + {$ELSE} + {$IFDEF KYLIX_2} + {$DEFINE KYLIX_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF KYLIX_2_OR_ABOVE} + {$DEFINE KYLIX_1_OR_ABOVE} + {$ELSE} + {$IFDEF KYLIX_1} + {$DEFINE KYLIX_1_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFNDEF KYLIX_3_OR_ABOVE} + {$DEFINE KYLIXCOMPAT} + {$ENDIF} + + {$IFDEF KYLIX_2_OR_ABOVE} + {$DEFINE USE_ZLIB_UNIT} + {$ENDIF} +{$ENDIF} + +// FPC (2+) + +{$IFDEF FPC} + // TODO: In FreePascal 4.2.0+, a Delphi-like UnicodeString type is supported. + // However, String/(P)Char do not map to UnicodeString/(P)WideChar unless + // either {$MODE DelphiUnicode} or {$MODESWITCH UnicodeStrings} is used. + // We should consider enabling one of them so Indy uses the same Unicode logic + // in Delphi 2009+ and FreePascal 4.2.0+ and reduces IFDEFs (in particular, + // STRING_UNICODE_MISMATCH, see further below). However, FreePascal's RTL + // is largely not UnicodeString-enabled yet. Maybe we should enable + // {$MODE DelphiUnicode} anyway, and then deal with any RTL function issues + // on an as-needed basis... + {$MODE Delphi} + //note that we may need further defines for widget types depending on + //what we do and what platforms we support in FPC. + //I'll let Marco think about that one. + {$IFDEF UNIX} + {$DEFINE USE_BASEUNIX} + {$IFDEF LINUX} + //In Linux for I386, you can choose between a Kylix-libc API or + //the standard RTL Unix API. Just pass -dKYLIXCOMPAT to the FPC compiler. + //I will see what I can do about the Makefile. + {$IFDEF KYLIXCOMPAT} + {$IFDEF CPUI386} + {$UNDEF USE_BASEUNIX} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$IFDEF USE_BASEUNIX} + {$UNDEF KYLIXCOMPAT} + {$ENDIF} + {$ENDIF} + + // FPC_FULLVERSION was added in FPC 2.2.4 + // Have to use Defined() or else Delphi compiler chokes, since it + // evaluates $IF statements before $IFDEF statements... + + {$MACRO ON} // must be on in order to use versioning macros + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30101)} + {$DEFINE FPC_3_1_1_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30000)} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20701)} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20604)} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20602)} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20600)} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20404)} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20402)} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20400)} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20204)} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20202)} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20105)} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$IFEND} + + // just in case + {$IFDEF FPC_3_1_1} + {$DEFINE FPC_3_1_1_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_3_0_0} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_7_1} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_4} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_2} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_0} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_4} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_2} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_0} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_2_4} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_2_2} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_1_5} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ENDIF} + + {$IFDEF FPC_3_1_1_OR_ABOVE} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_3_0_0} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_3_0_0_OR_ABOVE} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_7_1} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_7_1_OR_ABOVE} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_4} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_4_OR_ABOVE} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_2} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_0} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_0_OR_ABOVE} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_4} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_4_OR_ABOVE} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_2} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_2_OR_ABOVE} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_0} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_0_OR_ABOVE} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_2_4} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_4_OR_ABOVE} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_2_2} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_2_OR_ABOVE} + {$DEFINE FPC_2_2_0_OR_ABOVE} + {$ELSE} + {$IFDEF VER2_2} + {$DEFINE FPC_2_2_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_0_OR_ABOVE} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_1_5} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {.$IFDEF FPC_2_7_1_OR_ABOVE} + // support for RawByteString and UnicodeString + {.$MODE DelphiUnicode} + {.$MODESWITCH UnicodeStrings} + {.$CODEPAGE UTF8} // needed for Unicode string literals to work properly + {.$DEFINE VCL_2009} + {.$DEFINE DELPHI_2009} + {.$ELSE} + {$DEFINE VCL_70} + {$DEFINE DELPHI_7} + {.$ENDIF} +{$ENDIF} + +// end FPC + +{$IFDEF VCL_13} + {$DEFINE VCL_13_OR_ABOVE} +{$ENDIF} + +{$IFDEF VCL_13_OR_ABOVE} + {$DEFINE VCL_12_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_12} + {$DEFINE VCL_12_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_12_OR_ABOVE} + {$DEFINE VCL_11_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_11} + {$DEFINE VCL_11_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_11_OR_ABOVE} + {$DEFINE VCL_10_4_OR_ABOVE} + {$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_4} + {$DEFINE VCL_10_4_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_4_OR_ABOVE} + {$DEFINE VCL_10_3_OR_ABOVE} + {$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_3} + {$DEFINE VCL_10_3_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_OR_ABOVE} + {$DEFINE VCL_10_2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_2} + {$DEFINE VCL_10_2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_2_OR_ABOVE} + {$DEFINE VCL_10_1_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_1} + {$DEFINE VCL_10_1_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_1_OR_ABOVE} + {$DEFINE VCL_10_0_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_0} + {$DEFINE VCL_10_0_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_0_OR_ABOVE} + {$DEFINE VCL_XE8_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE8} + {$DEFINE VCL_XE8_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE VCL_XE7_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE7} + {$DEFINE VCL_XE7_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE7_OR_ABOVE} + {$DEFINE VCL_XE6_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE6} + {$DEFINE VCL_XE6_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE6_OR_ABOVE} + {$DEFINE VCL_XE5_OR_ABOVE} + {$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE5} + {$DEFINE VCL_XE5_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE5_OR_ABOVE} + {$DEFINE VCL_XE4_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE4} + {$DEFINE VCL_XE4_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE4_OR_ABOVE} + {$DEFINE VCL_XE3_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE3} + {$DEFINE VCL_XE3_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE3_OR_ABOVE} + {$DEFINE VCL_XE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE2} + {$DEFINE VCL_XE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE2_OR_ABOVE} + {$DEFINE VCL_XE_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE} + {$DEFINE VCL_XE_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE_OR_ABOVE} + {$DEFINE VCL_2010_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2010} + {$DEFINE VCL_2010_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2010_OR_ABOVE} + {$DEFINE VCL_2009_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2009} + {$DEFINE VCL_2009_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2009_OR_ABOVE} + {$DEFINE VCL_2007_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2007} + {$DEFINE VCL_2007_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2007_OR_ABOVE} + {$DEFINE VCL_2006_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2006} + {$DEFINE VCL_2006_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2006_OR_ABOVE} + {$DEFINE VCL_2005_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2005} + {$DEFINE VCL_2005_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2005_OR_ABOVE} + {$DEFINE VCL_8_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_80} + {$DEFINE VCL_8_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_8_OR_ABOVE} + {$DEFINE VCL_7_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_70} + {$DEFINE VCL_7_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_7_OR_ABOVE} + {$DEFINE VCL_6_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_60} + {$DEFINE VCL_6_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_6_OR_ABOVE} + {$DEFINE VCL_5_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_50} + {$DEFINE VCL_5_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_5_OR_ABOVE} + {$DEFINE VCL_4_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_40} + {$DEFINE VCL_4_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +// Normalize Delphi compiler defines to match FPC for consistency: +// +// CPU32 - any 32-bit CPU +// CPU64 - any 64-bit CPU +// WINDOWS - any Windows platform (32-bit, 64-bit, CE) +// WIN32 - Windows 32-bit +// WIN64 - Windows 64-bit +// WINCE - Windows CE +// +// Consult the "Free Pascal Programmer's Guide", Appendix G for the complete +// list of defines that are used. Do not work on this unless you understand +// what the FreePascal developers are doing. Not only do you have to +// descriminate with operating systems, but also with chip architectures +// are well. +// +// DCC Pulsar+ define the following values: +// ASSEMBLER +// DCC +// CONDITIONALEXPRESSIONS +// NATIVECODE +// UNICODE +// MACOS +// MACOS32 +// MACOS64 +// MSWINDOWS +// WIN32 +// WIN64 +// LINUX +// POSIX +// POSIX32 +// CPU386 +// CPUX86 +// CPUX64 +// +// Kylix defines the following values: +// LINUX +// (others??) +// + +{$IFNDEF FPC} + // TODO: We need to use ENDIAN_BIG for big endian chip architectures, + // such as 680x0, PowerPC, Sparc, and MIPS, once DCC supports them, + // provided it does not already define its own ENDIAN values by then... + {$DEFINE ENDIAN_LITTLE} + {$IFNDEF VCL_6_OR_ABOVE} + {$DEFINE MSWINDOWS} + {$ENDIF} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} + // TODO: map Pulsar's non-Windows platform defines... + {$IFDEF VCL_XE2_OR_ABOVE} + {$IFDEF VCL_XE8_OR_ABOVE} + {$IFDEF CPU32BITS} + //any 32-bit CPU + {$DEFINE CPU32} + {$ENDIF} + {$IFDEF CPU64BITS} + {$DEFINE CPU64} + {$ENDIF} + {$ELSE} + {$IFDEF CPU386} + //any 32-bit CPU + {$DEFINE CPU32} + //Intel 386 compatible chip architecture + {$DEFINE CPUI386} + {$ENDIF} + {$IFDEF CPUX86} + {$DEFINE CPU32} + {$ENDIF} + {$IFDEF CPUX64} + //any 64-bit CPU + {$DEFINE CPU64} + //AMD64 compatible chip architecture + {$DEFINE CPUX86_64} //historical name for AMD64 + {$DEFINE CPUAMD64} + {$ENDIF} + {$ENDIF} + {$ELSE} + {$IFNDEF DOTNET} + {$IFNDEF KYLIX} + {$DEFINE I386} + {$ENDIF} + {$ENDIF} + {$DEFINE CPU32} + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + //differences in DotNET Framework versions. + {$IFDEF VCL_2007_OR_ABOVE} + {$DEFINE DOTNET_2} + {$DEFINE DOTNET_2_OR_ABOVE} + {$ELSE} + {$DEFINE DOTNET_1_1} + {$ENDIF} + {$DEFINE DOTNET_1_1_OR_ABOVE} + // Extra include used in D7 for testing. Remove later when all comps are + // ported. Used to selectively exclude non ported parts. Allowed in places + // IFDEFs are otherwise not permitted. + {$DEFINE DOTNET_EXCLUDE} +{$ENDIF} + +// Check for available features + +{$IFDEF CBUILDER} + // When generating a C++ HPP file, if a class has no explicit constructor + // defined and contains compiler-managed members (xxxString, TDateTime, + // Variant, DelphiInterface, etc), the HPP will contain a forwarding + // inline constructor that implicitly initializes those managed members, + // which will overwrite any non-default initializations performed inside + // of InitComponent() overrides! In this situation, the workaround is to + // define an explicit constructor that calls the base class constructor + // manually, allowing those managed members to be initialized by the + // compiler before InitComponent() overrides then re-assign them. + {$DEFINE WORKAROUND_INLINE_CONSTRUCTORS} +{$ENDIF} + +{$IFDEF VCL_5_OR_ABOVE} + {$IFNDEF FPC} + {$IFNDEF KYLIX} + {$DEFINE HAS_RemoveFreeNotification} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_GetObjectProp} + {$DEFINE HAS_TObjectList} + {$DEFINE HAS_StrToInt64Def} +{$ENDIF} + +{$IFDEF VCL_6_OR_ABOVE} + {$DEFINE HAS_PCardinal} + {$DEFINE HAS_PByte} + {$DEFINE HAS_PWord} + {$DEFINE HAS_PPointer} + {$DEFINE HAS_TList_Assign} + {$DEFINE HAS_sLineBreak} + {$DEFINE HAS_RaiseLastOSError} + {$DEFINE HAS_SysUtils_IncludeExcludeTrailingPathDelimiter} + {$DEFINE HAS_SysUtils_DirectoryExists} + {$DEFINE HAS_UNIT_DateUtils} + {$DEFINE HAS_UNIT_StrUtils} + {$DEFINE HAS_UNIT_Types} + {$DEFINE HAS_TryStrToInt} + {$DEFINE HAS_TryStrToInt64} + {$DEFINE HAS_TryEncodeDate} + {$DEFINE HAS_TryEncodeTime} + {$DEFINE HAS_ENUM_ELEMENT_VALUES} + {$IFNDEF FPC} + {$DEFINE HAS_IInterface} + {$DEFINE HAS_TSelectionEditor} + {$DEFINE HAS_TStringList_CaseSensitive} + {$DEFINE HAS_AcquireExceptionObject} + {$IFNDEF KYLIX} + {$DEFINE HAS_DEPRECATED} + {$DEFINE HAS_SYMBOL_PLATFORM} + {$DEFINE HAS_UNIT_PLATFORM} + {$IFNDEF VCL_8_OR_ABOVE} + // Delphi 6 and 7 have an annoying bug that if a class method is declared as + // deprecated, the compiler will emit a "symbol is deprecated" warning + // on the method's implementation! So we will have to wrap implementations + // of deprecated methods with {$WARN SYMBOL_DEPRECATED OFF} directives + // to disable that warning. + {$DEFINE DEPRECATED_IMPL_BUG} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$IFNDEF DOTNET} + //Widget defines are omitted in .NET + {$DEFINE VCL_60_PLUS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_7_OR_ABOVE} + {$IFNDEF FPC} + {$DEFINE HAS_UInt64} // Note: it was just an alias for Int64 until D2006! + {$DEFINE HAS_NAMED_THREADS} + {$DEFINE HAS_TStrings_NameValueSeparator} + {$DEFINE HAS_TStrings_ValueFromIndex} + // Note: there is a ZLib unit available, but it doesn't have everything + // that is available in the System.ZLib unit in Delphi XE2+, so we are + // not going to use this ZLib unit yet... + {.$DEFINE HAS_UNIT_ZLib} + {$ENDIF} + {$DEFINE HAS_TFormatSettings} + {$DEFINE HAS_PosEx} + {$IFNDEF VCL_70} + // not implemented in D7 + {$DEFINE HAS_STATIC_TThread_Queue} + {$ENDIF} + {$IFNDEF CIL} + {$IFNDEF VCL_80} + // not implemented in D8 or .NET + {$DEFINE HAS_STATIC_TThread_Synchronize} + {$ENDIF} + {$ENDIF} +{$ELSE} + {$IFDEF CBUILDER_6} + {$DEFINE HAS_NAMED_THREADS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2005_OR_ABOVE} + {$IFDEF DCC} + // class helpers were first introduced in D2005, but were buggy and not + // officially supported until D2006... + {.$DEFINE HAS_CLASS_HELPER} + {$ENDIF} +{$ELSE} + {$IFDEF DCC} + // InterlockedCompareExchange() was declared in the Windows unit using Pointer + // parameters until Delphi 2005, when it was switched to Longint parameters + // instead to match the actual Win32 API declaration. + {$DEFINE HAS_InterlockedCompareExchange_Pointers} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2006_OR_ABOVE} + {$DEFINE USE_INLINE} + {$DEFINE HAS_2PARAM_FileAge} + {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? + {$DEFINE HAS_CLASS_HELPER} + {$IFDEF WINDOWS} + // System.RegisterExpectedMemoryLeak() is only available on Windows at this time + {$DEFINE HAS_System_RegisterExpectedMemoryLeak} + {$ENDIF} + // In C++Builder 2006 and 2007, UInt64 is emitted as signed __int64 in HPP + // files instead of as unsigned __int64. This causes conflicts in overloaded + // routines that have (U)Int64 parameters. This was fixed in C++Builder 2009... + {$IFDEF CBUILDER} + {$DEFINE BROKEN_UINT64_HPPEMIT} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2007_OR_ABOVE} + {$IFNDEF CBUILDER_2007} + // class properties are broken in C++Builder 2007, causing AVs at compile-time + {$DEFINE HAS_CLASSPROPERTIES} + {$ENDIF} + // Native(U)Int exist but are buggy, so do not use them yet + {.$DEFINE HAS_NativeInt} + {.$DEFINE HAS_NativeUInt} + {$DEFINE HAS_DWORD_PTR} + {$DEFINE HAS_ULONG_PTR} + {$DEFINE HAS_ULONGLONG} + {$DEFINE HAS_PGUID} + {$DEFINE HAS_PPAnsiChar} + {$DEFINE HAS_CurrentYear} + {$IFNDEF DOTNET} + {$DEFINE HAS_TIMEUNITS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2009_OR_ABOVE} + {$IFNDEF DOTNET} + {$DEFINE STRING_IS_UNICODE} + {$DEFINE HAS_UnicodeString} + {$DEFINE HAS_TEncoding} + {$DEFINE HAS_TCharacter} + {$DEFINE HAS_InterlockedCompareExchangePointer} + {$DEFINE HAS_WIDE_TCharArray} + {$DEFINE HAS_PUInt64} + {$IFDEF VCL_2009} + // TODO: need to differentiate between RTM and Update 1 + // FmtStr() is broken in RTM but was fixed in Update 1 + {$DEFINE BROKEN_FmtStr} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_CLASSVARS} + {$DEFINE HAS_DEPRECATED_MSG} + {$DEFINE HAS_TBytes} + // Native(U)Int are still buggy, so do not use them yet + {.$DEFINE HAS_NativeInt} + {.$DEFINE HAS_NativeUInt} + {$DEFINE HAS_Int8} + {$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_UIntToStr} + // UInt64 is now emitted as unsigned __int64 in HPP files + {$IFDEF CBUILDER} + {$UNDEF BROKEN_UINT64_HPPEMIT} + {$ENDIF} + {$IFDEF DCC} + {$IFDEF WINDOWS} + // Exception.RaiseOuterException() is only available on Windows at this time + {$DEFINE HAS_Exception_RaiseOuterException} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_SetCodePage} + {$DEFINE HAS_PRawByteString} + {$DEFINE HAS_TThreadProcedure} +{$ENDIF} + +{$IFDEF VCL_2010_OR_ABOVE} + {$DEFINE HAS_CLASSCONSTRUCTOR} + {$DEFINE HAS_CLASSDESTRUCTOR} + {$DEFINE HAS_DELAYLOAD} + {$DEFINE HAS_TThread_NameThreadForDebugging} + {$DEFINE DEPRECATED_TThread_SuspendResume} + // Native(U)Int are finally ok to use now + {$DEFINE HAS_NativeInt} + {$DEFINE HAS_NativeUInt} + {$DEFINE HAS_USHORT} + {$DEFINE HAS_IOUtils_TPath} +{$ENDIF} + +{$IFDEF VCL_XE_OR_ABOVE} + {$DEFINE HAS_TFormatSettings_Object} + {$DEFINE HAS_LocaleCharsFromUnicode} + {$DEFINE HAS_UnicodeFromLocaleChars} + {$DEFINE HAS_PLongBool} + {$DEFINE HAS_PVOID} + {$DEFINE HAS_ULONG64} + {$DEFINE HAS_TEncoding_GetEncoding_ByEncodingName} + {$DEFINE HAS_DateUtils_TTimeZone} + {$IFDEF DCC} + // Exception.RaiseOuterException() is now available on all platforms + {$DEFINE HAS_Exception_RaiseOuterException} + {$ENDIF} + {$IFNDEF DOTNET} + {$DEFINE HAS_TInterlocked} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE2_OR_ABOVE} + {$DEFINE HAS_SIZE_T} + {$DEFINE HAS_PSIZE_T} + {$DEFINE HAS_SSIZE_T} + {$DEFINE HAS_PSSIZE_T} + {$DEFINE HAS_LONG} + {$DEFINE HAS_ComponentPlatformsAttribute} + {$DEFINE HAS_ComponentPlatformsAttribute_Win32} + {$DEFINE HAS_ComponentPlatformsAttribute_Win64} + {$DEFINE HAS_ComponentPlatformsAttribute_OSX32} + {$DEFINE HAS_System_ReturnAddress} + {$DEFINE HAS_DIRECTIVE_WARN_DEFAULT} + {$DEFINE HAS_UNIT_System_ZLib} +{$ENDIF} + +{$IFDEF VCL_XE3_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_ZEROBASEDSTRINGS} + {$DEFINE HAS_SysUtils_TStringHelper} + {$IFDEF NEXTGEN} + {$DEFINE DCC_NEXTGEN} + {$DEFINE HAS_MarshaledAString} + {$DEFINE USE_MARSHALLED_PTRS} + {$IFDEF AUTOREFCOUNT} + {$DEFINE USE_OBJECT_ARC} + {$ENDIF} + {$ENDIF} + // technically, these are present in XE3, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} + {.$DEFINE HAS_ComponentPlatformsAttribute_Android} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32} + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} + {.$DEFINE HAS_ComponentPlatformsAttribute_WinNX32} +{$ENDIF} + +{$IFDEF VCL_XE4_OR_ABOVE} + {$DEFINE HAS_AnsiStrings_StrPLCopy} + {$DEFINE HAS_AnsiStrings_StrLen} + {$DEFINE HAS_Character_TCharHelper} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} +{$ENDIF} + +{$IFDEF VCL_XE5_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_Android} +{$ENDIF} + +{$IFDEF VCL_XE5_UPDATE2_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_LINKUNIT} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_NAMESPACE} +{$ENDIF} + +{$IFDEF VCL_XE7_OR_ABOVE} + {$DEFINE HAS_TNetEncoding} +{$ENDIF} + +{$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device32} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device64} + // technically, these are present in XE8, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64} + {.$DEFINE HAS_ComponentPlatformsAttribute_WinIoT32} +{$ENDIF} + +{$IFDEF VCL_10_0_OR_ABOVE} + {$IFDEF ANDROID} + {$DEFINE HAS_TAndroidHelper} + {$ENDIF} + // technically, these are present in 10.0 Seattle, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_WinARM} +{$ENDIF} + +{$IFDEF VCL_10_1_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_LEGACYHPP} + {$DEFINE HAS_TStrings_AddPair} + // technically, these are present in 10.1 Berlin, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_OSX64} + {.$DEFINE HAS_ComponentPlatformsAttribute_OSXNX64} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32Arm} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64Arm} + {.$DEFINE HAS_ComponentPlatformsAttribute_Android64} +{$ENDIF} + +{$IFDEF VCL_10_2_OR_ABOVE} + {.$WARN IMPLICIT_INTEGER_CAST_LOSS OFF} + {.$WARN IMPLICIT_CONVERSION_LOSS OFF} + {.$WARN COMBINING_SIGNED_UNSIGNED64 OFF} + {$DEFINE HAS_STATIC_TThread_ForceQueue} + // In Delphi 10.2 Tokyo, TThread.ForceQueue() is broken on Android, the + // passed in procedure is called immediately instead of being delayed! + {$IFDEF ANDROID} + {$DEFINE BROKEN_TThread_ForceQueue} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator32} + {$DEFINE HAS_ComponentPlatformsAttribute_Android32Arm} + {$DEFINE HAS_ComponentPlatformsAttribute_WinARM32} + {$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} // removed in 10.3 Rio + // technically, these are present in 10.3 Rio, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator64} + {$IFDEF DCC} + {$IFDEF LINUX} + // RLebeau 9/25/2019: there is a bug in the IDE when debugging Linux projects + // where the EThreadNameException exception raised by TThread.NameThreadForDebugging() + // is not handled correctly. + {$UNDEF HAS_NAMED_THREADS} + {$ENDIF} + {$ENDIF} + {$IFDEF ANDROID} + {$UNDEF BROKEN_TThread_ForceQueue} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_UPDATE2_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_AllPlatforms} + {$DEFINE HAS_ComponentPlatformsAttribute_OSX64} +{$ENDIF} + +{$IFDEF VCL_10_4_OR_ABOVE} + // 0-based string indexing via '[]' is turned off by default in Delphi 10.4. + // TStringHelper is always 0-indexed, flat RTL functions are always 1-indexed, + // and now '[]' is 1-indexed again on all platforms - {$ZEROBASEDSTRINGS OFF} + // is the default. + {.$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} +{$ENDIF} + +{$IFDEF VCL_11_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm32} + {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm64} + {$DEFINE HAS_ComponentPlatformsAttribute_OSXArm64} +{$ENDIF} + +// Delphi XE+ cross-compiling +{$IFNDEF FPC} + {$IFDEF POSIX} + {$IF RTLVersion >= 22.0} + {$DEFINE UNIX} + {$UNDEF USE_BASEUNIX} + {$DEFINE VCL_CROSS_COMPILE} + {$DEFINE USE_VCL_POSIX} + {$IFEND} + {$ENDIF} + {$IFDEF LINUX} + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF RTLVersion >= 22.0} + {$DEFINE VCL_CROSS_COMPILE} + {$DEFINE USE_VCL_POSIX} + {$IFEND} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_CROSS_COMPILE} + {$UNDEF KYLIXCOMPAT} +{$ELSE} + {$IFDEF KYLIXCOMPAT} + {$linklib c} + {$ENDIF} +{$ENDIF} + +{$IFDEF FPC} + {$DEFINE USE_INLINE} + {$DEFINE USE_CLASSINLINE} + {$DEFINE USE_TBitBtn} //use Bit Buttons instead of Buttons + {$DEFINE FPC_REINTRODUCE_BUG} + {$DEFINE FPC_CIRCULAR_BUG} + {$DEFINE NO_REDECLARE} + {$DEFINE BYTE_COMPARE_SETS} + {$DEFINE HAS_QWord} // TODO: when was QWord introduced? + {$DEFINE HAS_PQWord} // TODO: when was PQWord introduced? + {$IFDEF FPC_2_1_5_OR_ABOVE} + {$DEFINE HAS_UInt64} + {.$DEFINE HAS_PUInt64} // TODO: is this defined? + {$ENDIF} + {$IFDEF FPC_2_2_0_OR_ABOVE} + {$DEFINE HAS_InterlockedCompareExchange_Pointers} + {$ENDIF} + {$IFDEF FPC_2_2_2_OR_ABOVE} + {$DEFINE HAS_SharedSuffix} + {$ENDIF} + {$IFDEF FPC_2_2_4_OR_ABOVE} + // these types are only available on Unix systems (FreeBSD, Linux, etc) + {$IFDEF UNIX} + {$DEFINE HAS_UNIT_UnixType} + {$DEFINE HAS_SIZE_T} + {$DEFINE HAS_PSIZE_T} + {$DEFINE HAS_SSIZE_T} + {$DEFINE HAS_PSSIZE_T} + {$DEFINE HAS_TIME_T} + {$DEFINE HAS_PTIME_T} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_PtrInt} + {$DEFINE HAS_PtrUInt} + {$DEFINE HAS_PGUID} + {$DEFINE HAS_LPGUID} + {$DEFINE HAS_PPAnsiChar} + {$DEFINE HAS_ENUM_ELEMENT_VALUES} + {$DEFINE HAS_AcquireExceptionObject} // TODO: when was AcquireExceptionObject introduced? + {$IFDEF WINDOWS} + {$DEFINE HAS_ULONG_PTR} + {.$DEFINE HAS_ULONGLONG} // TODO: is this defined? + {$ENDIF} + {$DEFINE HAS_UNIT_ctypes} + {$DEFINE HAS_sLineBreak} + {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? + {$IFDEF FPC_HAS_UNICODESTRING} + {$DEFINE HAS_UnicodeString} + {$ELSE} + {$IFDEF FPC_2_4_0_OR_ABOVE} + {$DEFINE HAS_UnicodeString} + {$ENDIF} + {$ENDIF} + {$IFDEF FPC_2_4_4_OR_ABOVE} + {$DEFINE DEPRECATED_TThread_SuspendResume} + {$DEFINE HAS_DEPRECATED} // TODO: when was deprecated introduced? Possibly 1.9.x + {$DEFINE HAS_DEPRECATED_MSG} // TODO: when was message support added? Possibly 2.4.x + {$DEFINE HAS_STATIC_TThread_Synchronize} + {$IFNDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE USE_SEMICOLON_BEFORE_DEPRECATED} // TODO: which earlier versions require a semicolon? + {$ENDIF} + {$ENDIF} + {$IFDEF FPC_2_6_0_OR_ABOVE} + {$DEFINE HAS_NativeInt} + {$DEFINE HAS_NativeUInt} + {$DEFINE HAS_CLASS_HELPER} + {$ENDIF} + {$IFDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE HAS_Int8} + {$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_GetLocalTimeOffset} + {$DEFINE HAS_UniversalTimeToLocal} + {$DEFINE HAS_LocalTimeToUniversal} + {$ENDIF} + {$IFDEF FPC_2_6_4_OR_ABOVE} + {$DEFINE HAS_PInt8} + {$DEFINE HAS_PUInt8} + {$DEFINE HAS_PInt16} + {$DEFINE HAS_PUInt16} + {$DEFINE HAS_PInt32} + {$DEFINE HAS_PUInt32} + {$ENDIF} + {$IFDEF FPC_3_0_0_OR_ABOVE} + {$DEFINE HAS_STATIC_TThread_Queue} + {$DEFINE HAS_SetCodePage} + {$ENDIF} + {$IFDEF FPC_UNICODESTRINGS} + {$DEFINE STRING_IS_UNICODE} + {$ENDIF} + {$IFDEF FPC_3_1_1_OR_ABOVE} + {$DEFINE HAS_STATIC_TThread_ForceQueue} // requires rev 37359+ + {$DEFINE HAS_PRawByteString} + {$DEFINE HAS_UIntToStr} // requires rev 40529+ + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + {$DEFINE WIDGET_WINFORMS} +{$ELSE} + {$DEFINE WIDGET_VCL_LIKE} // LCL included. + {$DEFINE WIDGET_VCL_LIKE_OR_KYLIX} + {$IFDEF FPC} + {$DEFINE WIDGET_LCL} + {$ELSE} + {$IFDEF KYLIX} + {$DEFINE WIDGET_KYLIX} + {$ELSE} + {$DEFINE WIDGET_VCL} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +// .NET and Delphi 2009+ support UNICODE strings natively! +// +// FreePascal 2.4.0+ supports UnicodeString, but does not map its +// native String type to UnicodeString except when {$MODE DelphiUnicode} +// or {$MODESWITCH UnicodeStrings} is enabled. However, UNICODE is not +// defined in that mode yet until its RTL has been updated to support +// UnicodeString. STRING_UNICODE_MISMATCH is defined when the native +// String/Char types do not map to the same types that APIs are expecting +// based on whether UNICODE is defined or not. +// +// NOTE: Do not define UNICODE here. The compiler defines +// the symbol automatically. +{$IFDEF STRING_IS_UNICODE} + {$IFNDEF UNICODE} + {$DEFINE STRING_UNICODE_MISMATCH} + {$ENDIF} +{$ELSE} + {$DEFINE STRING_IS_ANSI} + {$IFDEF UNICODE} + {$DEFINE STRING_UNICODE_MISMATCH} + {$ENDIF} +{$ENDIF} + +{$IFDEF DCC_NEXTGEN} + {$DEFINE NO_ANSI_TYPES} + {.$DEFINE STRING_IS_IMMUTABLE} // Strings are NOT immutable in NEXTGEN yet + {$IFDEF USE_OBJECT_ARC} + // TODO: move these to an appropriate section. Not doing this yet because + // it is a major interface change to switch to Generics and we should + // maintain backwards compatibility with earlier compilers for the time + // being. Defining them only here for now because the non-Generic versions + // of these classes have become deprecated by ARC and so we need to start + // taking advantage of the Generics versions... + {$DEFINE HAS_UNIT_Generics_Collections} + {$DEFINE HAS_UNIT_Generics_Defaults} + {$DEFINE HAS_GENERICS_TDictionary} + {$DEFINE HAS_GENERICS_TList} + {$DEFINE HAS_GENERICS_TObjectList} + {$DEFINE HAS_GENERICS_TThreadList} + // TArray.Copy() was introduced in XE7 but was buggy. It was fixed in XE8: + // + // RSP-9763 TArray.Copy copies from destination to source for unmanaged types + // https://quality.embarcadero.com/browse/RSP-9763 + // + {$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE HAS_GENERICS_TArray_Copy} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +// TODO: Ansi data types were disabled on mobile platforms in XE3, but +// UTF8String and RawByteString were re-enabled in 10.1 Berlin! What else, +// if anything, was re-enabled to facilitate that? +// +// UPDATE: In 10.4 Sydney, AnsiChar and AnsiString were re-enabled on +// mobile platforms! NEXTGEN is no longer defined in the mobile compilers. +{$IFDEF NO_ANSI_TYPES} + {$UNDEF HAS_AnsiString} + {$UNDEF HAS_AnsiChar} + {$UNDEF HAS_PAnsiChar} + {$UNDEF HAS_PPAnsiChar} + {$UNDEF HAS_AnsiStrings_StrPLCopy} + {$UNDEF HAS_AnsiStrings_StrLen} +{$ENDIF} + +{$IFDEF WIN32} + {$DEFINE WIN32_OR_WIN64} +{$ENDIF} +{$IFDEF WIN64} + {$DEFINE WIN32_OR_WIN64} +{$ENDIF} + +{$IFDEF WIN32_OR_WIN64} + {$DEFINE USE_ZLIB_UNIT} + {$IFNDEF DCC_NEXTGEN} + {$DEFINE USE_OPENSSL} // !!! MOVED HERE BY EMBT + {$DEFINE USE_SSPI} + {$IFDEF STRING_IS_UNICODE} + {$DEFINE SSPI_UNICODE} + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF WINCE} + {$DEFINE USE_OPENSSL} + // RLebeau: not sure if the above Win32/64 defines also apply to WinCE, + // so keeping them separate for now... +{$ENDIF} + +// High-performance counters are not reliable on multi-core systems, and have +// been known to cause problems with TIdIOHandler.ReadLn() timeouts in Windows +// XP SP3, both 32-bit and 64-bit. Refer to these discussions for more info: +// +// http://www.virtualdub.org/blog/pivot/entry.php?id=106 +// http://blogs.msdn.com/oldnewthing/archive/2008/09/08/8931563.aspx +// +// Do not enable thus unless you know it will work correctly on your systems! +{$IFDEF WINDOWS} + {.$DEFINE USE_HI_PERF_COUNTER_FOR_TICKS} +{$ENDIF} + +{$IFDEF UNIX} + {$DEFINE USE_OPENSSL} + {$DEFINE USE_ZLIB_UNIT} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF MACOS} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF DARWIN} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF LINUX} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF IOS} + {$DEFINE HAS_getifaddrs} + {$DEFINE USE_OPENSSL} + + // Support for 64-bit ARM iOS Simulator was added in Delphi 11.2 + // TODO: how to detect iOS Simulator in FPC? Does it support 64-bit ARM? + {$IFDEF CPUARM} + {$IFNDEF IOSSIMULATOR} + // RLebeau: For iOS devices, OpenSSL cannot be used as an external library, + // it must be statically linked into the app. For the iOS simulator, this + // is not true. Users who want to use OpenSSL in iOS device apps will need + // to add the static OpenSSL library to the project and then include the + // IdSSLOpenSSLHeaders_static unit in their uses clause. It hooks up the + // statically linked functions for the IdSSLOpenSSLHeaders unit to use... + {$DEFINE STATICLOAD_OPENSSL} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF FREEBSD} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF ANDROID} + {$UNDEF HAS_getifaddrs} +{$ENDIF} + +{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} + {$DEFINE REQUIRES_PROPER_ALIGNMENT} +{$ENDIF} + +// +//iconv defines section. +{$DEFINE USE_ICONV_UNIT} +{$DEFINE USE_ICONV_ENC} +{$IFDEF UNIX} + {$DEFINE USE_ICONV} + {$IFDEF USE_BASEUNIX} + {$IFDEF FPC} + {$UNDEF USE_ICONV_UNIT} + {$ELSE} + {$UNDEF USE_ICONV_ENC} + {$ENDIF} + {$ENDIF} + {$IFDEF KYLIXCOMPAT} + //important!! Iconv functions are defined in the libc.pas Kylix compatible unit. + {$UNDEF USE_ICONV_ENC} + {$UNDEF USE_ICONV_UNIT} + {$ENDIF} +{$ENDIF} +{$IFDEF NETWARELIBC} + {$DEFINE USE_ICONV} + //important!!! iconv functions are defined in the libc.pas Novell Netware header. + //Do not define USE_ICONV_UNIT + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} +{$ENDIF} + +{$UNDEF USE_SAFELOADLIBRARY} +{$IFDEF WINDOWS} + {$UNDEF USE_ICONV_ENC} + {$DEFINE USE_SAFELOADLIBRARY} +{$ENDIF} +// Use here for all *nix systems that you do not want to use iconv library +{$IFDEF FPC} + {$IFDEF ANDROID} + {$UNDEF USE_ICONV} + {$DEFINE USE_LCONVENC} + {$ENDIF} +{$ENDIF} + +{$UNDEF USE_INVALIDATE_MOD_CACHE} +{$UNDEF USE_SAFELOADLIBRARY} +//This must come after the iconv defines because this compiler targets a Unix-like +//operating system. One key difference is that it does have a TEncoding class. +//If this comes before the ICONV defines, it creates problems. +//This also must go before the THandle size calculations. +{$IFDEF VCL_CROSS_COMPILE} + {$IFDEF POSIX} + {$IFNDEF LINUX} + {$DEFINE BSD} + {$ENDIF} + {$DEFINE USE_SAFELOADLIBRARY} + {$DEFINE USE_INVALIDATE_MOD_CACHE} + {$ENDIF} + //important!!! iconv functions are defined in the libc.pas Novell Netware header. + //Do not define USE_ICONVUNIT + {$UNDEF USE_ICONV} + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} + {$DEFINE INT_THREAD_PRIORITY} +{$ENDIF} + +{$IFNDEF USE_ICONV} + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} +{$ENDIF} + +//IMPORTANT!!!! +// +//Do not remove this!!! This is to work around a conflict. In DCC, MACOS +//will mean OS X. In FreePascal, the DEFINE MACOS means MacIntosh System OS Classic. +{$IFDEF DCC} + // DCC defines MACOS for both iOS and OS X platforms, need to differentiate + {$IFDEF MACOS} + {$IFNDEF IOS} + {$DEFINE OSX} + {$DEFINE DARWIN} + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF FPC} + // FPC defines DARWIN for both OSX and iOS, need to differentiate + {$IFDEF DARWIN} + {$IFNDEF IOS} + {$DEFINE OSX} + {$ENDIF} + {$ENDIF} + {$IFDEF MACOS} + {$DEFINE MACOS_CLASSIC} + {$ENDIF} +{$ENDIF} + +{ +BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit +word to an 8 bit byte and an 8 bit byte field named sa_len was added. +} +//Place this only after DARWIN has been defined for Delphi MACOS +{$IFDEF FREEBSD} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF DARWIN} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF MORPHOS} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} + +// Do NOT remove these IFDEF's. They are here because InterlockedExchange +// only handles 32bit values. Some Operating Systems may have 64bit +// THandles. This is not always tied to the platform architecture. + +{$IFDEF AMIGA} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF ATARI} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF BEOS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF BSD} + //I think BSD might handle FreeBSD, NetBSD, OpenBSD, and Darwin + {$IFDEF IOS} + {$IFDEF CPUARM64} + {$DEFINE CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$IFDEF CPUARM32} + {$DEFINE CPU32} + {$ENDIF} + {$DEFINE THANDLE_32} + {$ENDIF} + {$ENDIF} + {$IFDEF OSX} + {$IFDEF FPC} + {$DEFINE THANDLE_32} + {$ELSE} + {$DEFINE THANDLE_CPUBITS} // !!! ADDED OSX BY EMBT + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF EMBEDDED} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF EMX} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF GBA} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF GO32} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF LINUX} + {$IFDEF LINUX64} + {$DEFINE CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$IFDEF LINUX32} + {$DEFINE CPU32} + {$ENDIF} + {$DEFINE THANDLE_32} + {$ENDIF} +{$ENDIF} +{$IFDEF MACOS_CLASSIC} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF MORPHOS} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF NATIVENT} //Native NT for kernel level drivers + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF NDS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF NETWARE} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF NETWARELIBC} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF OS2} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF PALMOS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF SOLARIS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF SYMBIAN} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WII} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WATCOM} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WINDOWS} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} + +// end platform specific stuff for THandle size + +{$IFDEF THANDLE_CPUBITS} + {$IFDEF CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$DEFINE THANDLE_32} + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + {$DEFINE DOTNET_OR_ICONV} +{$ENDIF} +{$IFDEF USE_ICONV} + {$DEFINE DOTNET_OR_ICONV} +{$ENDIF} + +{$UNDEF STREAM_SIZE_64} +{$IFDEF FPC} + {$DEFINE STREAM_SIZE_64} +{$ELSE} + {$IFDEF VCL_6_OR_ABOVE} + {$DEFINE STREAM_SIZE_64} + {$ENDIF} +{$ENDIF} + +{$IFNDEF FREE_ON_FINAL} + {$IFNDEF DOTNET} + {$IFDEF HAS_System_RegisterExpectedMemoryLeak} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_FASTMM4} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_MADEXCEPT} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_LEAKCHECK} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{ +We must determine what the SocketType parameter is for the Socket function. +In DotNET, it's SocketType. In Kylix and the libc.pas Kylix-compatibility +library, it's a __socket_type. In BaseUnix, it's a C-type Integer. In Windows, +it's a LongInt. + +} +{$UNDEF SOCKETTYPE_IS_SOCKETTYPE} +{$UNDEF SOCKETTYPE_IS_CINT} +{$UNDEF SOCKETTYPE_IS___SOCKETTYPE} +{$UNDEF SOCKETTYPE_IS_LONGINT} +{$UNDEF SOCKETTYPE_IS_NUMERIC} +{$UNDEF SOCKET_LEN_IS_socklen_t} +{$IFDEF DOTNET} + {$DEFINE SOCKETTYPE_IS_SOCKETTYPE} +{$ENDIF} +{$IFDEF USE_BASEUNIX} + {$DEFINE SOCKETTYPE_IS_CINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF KYLIXCOMPAT} + {$DEFINE SOCKETTYPE_IS___SOCKETTYPE} +{$ENDIF} +{$IFDEF USE_VCL_POSIX} + {$DEFINE SOCKETTYPE_IS_NUMERIC} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKET_LEN_IS_socklen_t} +{$ENDIF} +{$IFDEF WINDOWS} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF OS2} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF NETWARE} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} + +{Take advantage of some TCP features specific to some stacks. +They work somewhat similarly but there's a key difference. +In Linux, TCP_CORK is turned on to send fixed packet sizes and +when turned-off (uncorked), any remaining data is sent. With +TCP_NOPUSH, this might not happen and remaining data is only sent +before disconnect. TCP_KEEPIDLE and TCP_KEEPINTVL so the IFDEF LINUX and IFDEF +SOLARIS instead of IFDEF UNIX is not an error, it's deliberate.} +{$UNDEF HAS_TCP_NOPUSH} +{$UNDEF HAS_TCP_CORK} +{$UNDEF HAS_TCP_KEEPIDLE} +{$UNDEF HAS_TCP_KEEPINTVL} +{$UNDEF HAS_SOCKET_NOSIGPIPE} +{$IFDEF BSD} + {$DEFINE HAS_TCP_NOPUSH} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE HAS_TCP_NOPUSH} +{$ENDIF} +{$IFDEF LINUX} + {$DEFINE HAS_TCP_CORK} + {$DEFINE HAS_TCP_KEEPIDLE} + {$DEFINE HAS_TCP_KEEPINTVL} +{$ENDIF} +{$IFDEF SOLARIS} + {$DEFINE HAS_TCP_CORK} +{$ENDIF} +{$IFDEF NETBSD} + {$DEFINE HAS_TCP_CORK} + {$DEFINE HAS_TCP_KEEPIDLE} + {$DEFINE HAS_TCP_KEEPINTVL} +{$ENDIF} +{$IFDEF USE_VCL_POSIX} + // TODO: which platforms actually have SO_NOSIGPIPE available? + {$DEFINE HAS_SOCKET_NOSIGPIPE} + {$IFDEF ANDROID} + {$UNDEF HAS_SOCKET_NOSIGPIPE} + {$ENDIF} + {$IFDEF LINUX} + {$UNDEF HAS_SOCKET_NOSIGPIPE} + {$ENDIF} +{$ENDIF} +{end Unix OS specific stuff} +{$IFDEF DEBUG} + {$UNDEF USE_INLINE} +{$ENDIF} + +// RLebeau 5/24/2015: In C++Builder 2006 and 2007, UInt64 is emitted as +// signed __int64 in HPP files instead of as unsigned __int64. This causes +// conflicts in overloaded routines that have (U)Int64 parameters. This +// was fixed in C++Builder 2009. For compilers that do not have a native +// UInt64 type, or for C++Builder 2006/2007, let's define a record type +// that can hold UInt64 values... +{$IFDEF HAS_UInt64} + {$IFDEF BROKEN_UINT64_HPPEMIT} + {$DEFINE TIdUInt64_HAS_QuadPart} + {$ENDIF} +{$ELSE} + {$IFNDEF HAS_QWord} + {$DEFINE TIdUInt64_HAS_QuadPart} + {$ENDIF} +{$ENDIF} + +// RLebeau 9/5/2013: it would take a lot of work to re-write Indy to support +// both 0-based and 1-based string indexing, so we'll just turn off 0-based +// indexing for now... +{$IFDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} + {$ZEROBASEDSTRINGS OFF} +{$ENDIF} diff --git a/Lib/Core/IdCore90ASM90.inc b/Lib/Core/IdCore90ASM90.inc index 09798c336..95a4e0f5c 100644 --- a/Lib/Core/IdCore90ASM90.inc +++ b/Lib/Core/IdCore90ASM90.inc @@ -1,12 +1,12 @@ -[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Core Run-Time Package for Borland Developer Studio')] -[assembly: AssemblyConfiguration('')] -[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] -[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyTrademark('')] -[assembly: AssemblyCulture('')] -[assembly: AssemblyTitle('Indy .NET Core Run-Time Package')] -[assembly: AssemblyVersion('10.7.0.*')] -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile('')] -[assembly: AssemblyKeyName('')] +[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Core Run-Time Package for Borland Developer Studio')] +[assembly: AssemblyConfiguration('')] +[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] +[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyTrademark('')] +[assembly: AssemblyCulture('')] +[assembly: AssemblyTitle('Indy .NET Core Run-Time Package')] +[assembly: AssemblyVersion('10.7.0.*')] +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile('')] +[assembly: AssemblyKeyName('')] diff --git a/Lib/Core/IdDsnBaseCmpEdt.pas b/Lib/Core/IdDsnBaseCmpEdt.pas index cbafa5710..50e1f711a 100644 --- a/Lib/Core/IdDsnBaseCmpEdt.pas +++ b/Lib/Core/IdDsnBaseCmpEdt.pas @@ -1,94 +1,94 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.2 9/5/2004 2:08:16 PM JPMugaas - Should work in D9 NET. - - Rev 1.1 2/3/2004 11:42:50 AM JPMugaas - Fixed for new design. - - Rev 1.0 11/13/2002 08:43:16 AM JPMugaas -} - -unit IdDsnBaseCmpEdt; - -{$I IdCompilerDefines.inc} - -interface - -uses - {$IFDEF DOTNET} - Borland.Vcl.Design.DesignIntF, - Borland.Vcl.Design.DesignEditors - {$ELSE} - {$IFDEF FPC} - ComponentEditors - {$ELSE} - {$IFDEF VCL_6_OR_ABOVE} - DesignIntf, - DesignEditors - {$ELSE} - Dsgnintf - {$ENDIF} - {$ENDIF} - {$ENDIF} - ; - -type - {$IFDEF FPC} - TIdBaseComponentEditor = class(TDefaultComponentEditor) - {$ELSE} - TIdBaseComponentEditor = class(TDefaultEditor) - {$ENDIF} - public - procedure ExecuteVerb(Index: Integer); override; - function GetVerb(Index: Integer): string; override; - function GetVerbCount: Integer; override; - end; - -implementation - -uses - IdAbout, - IdGlobal, - IdDsnCoreResourceStrings, - SysUtils; - -{ TIdBaseComponentEditor } - -procedure TIdBaseComponentEditor.ExecuteVerb(Index: Integer); -begin - case Index of - 0 : ShowAboutBox(RSAAboutBoxCompName, gsIdVersion); - end; -end; - -function TIdBaseComponentEditor.GetVerb(Index: Integer): string; -begin - case Index of - 0: Result := IndyFormat(RSAAboutMenuItemName, [gsIdVersion]); - end; -end; - -function TIdBaseComponentEditor.GetVerbCount: Integer; -begin - Result := 1; -end; - -end. - +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.2 9/5/2004 2:08:16 PM JPMugaas + Should work in D9 NET. + + Rev 1.1 2/3/2004 11:42:50 AM JPMugaas + Fixed for new design. + + Rev 1.0 11/13/2002 08:43:16 AM JPMugaas +} + +unit IdDsnBaseCmpEdt; + +{$I IdCompilerDefines.inc} + +interface + +uses + {$IFDEF DOTNET} + Borland.Vcl.Design.DesignIntF, + Borland.Vcl.Design.DesignEditors + {$ELSE} + {$IFDEF FPC} + ComponentEditors + {$ELSE} + {$IFDEF VCL_6_OR_ABOVE} + DesignIntf, + DesignEditors + {$ELSE} + Dsgnintf + {$ENDIF} + {$ENDIF} + {$ENDIF} + ; + +type + {$IFDEF FPC} + TIdBaseComponentEditor = class(TDefaultComponentEditor) + {$ELSE} + TIdBaseComponentEditor = class(TDefaultEditor) + {$ENDIF} + public + procedure ExecuteVerb(Index: Integer); override; + function GetVerb(Index: Integer): string; override; + function GetVerbCount: Integer; override; + end; + +implementation + +uses + IdAbout, + IdGlobal, + IdDsnCoreResourceStrings, + SysUtils; + +{ TIdBaseComponentEditor } + +procedure TIdBaseComponentEditor.ExecuteVerb(Index: Integer); +begin + case Index of + 0 : ShowAboutBox(RSAAboutBoxCompName, gsIdVersion); + end; +end; + +function TIdBaseComponentEditor.GetVerb(Index: Integer): string; +begin + case Index of + 0: Result := IndyFormat(RSAAboutMenuItemName, [gsIdVersion]); + end; +end; + +function TIdBaseComponentEditor.GetVerbCount: Integer; +begin + Result := 1; +end; + +end. + diff --git a/Lib/Core/IddclCore90ASM90.inc b/Lib/Core/IddclCore90ASM90.inc index 55000c65c..840a6bc7e 100644 --- a/Lib/Core/IddclCore90ASM90.inc +++ b/Lib/Core/IddclCore90ASM90.inc @@ -1,12 +1,12 @@ -[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Core Design-Time Package for Borland Developer Studio')] -[assembly: AssemblyConfiguration('')] -[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] -[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyTrademark('')] -[assembly: AssemblyCulture('')] -[assembly: AssemblyTitle('Indy .NET Core Design-Time Package')] -[assembly: AssemblyVersion('10.7.0.*')] -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile('')] -[assembly: AssemblyKeyName('')] +[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Core Design-Time Package for Borland Developer Studio')] +[assembly: AssemblyConfiguration('')] +[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] +[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyTrademark('')] +[assembly: AssemblyCulture('')] +[assembly: AssemblyTitle('Indy .NET Core Design-Time Package')] +[assembly: AssemblyVersion('10.7.0.*')] +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile('')] +[assembly: AssemblyKeyName('')] diff --git a/Lib/FCL/IdCompilerDefines.inc b/Lib/FCL/IdCompilerDefines.inc index 8ce7d254c..24f902e86 100644 --- a/Lib/FCL/IdCompilerDefines.inc +++ b/Lib/FCL/IdCompilerDefines.inc @@ -1,2091 +1,2091 @@ -{$IFDEF CONDITIONALEXPRESSIONS} - // Must be at the top... - {$IF CompilerVersion >= 24.0} - {$LEGACYIFEND ON} - {$IFEND} -{$ENDIF} - -// General - -// Make this $DEFINE to use the 16 color icons required by Borland -// or DEFINE to use the 256 color Indy versions -{.$DEFINE Borland} - -// S.G. 4/9/2002: IPv4/IPv6 general switch (for defaults only) -{$DEFINE IdIPv4} // use IPv4 by default -{.$IFDEF IdIPv6} // use IPv6 by default - -{$DEFINE INDY100} -{$DEFINE 10_7_0} //so developers can IFDEF for this product version -{$DEFINE 10_7_0_0} //so developers can IFDEF for this specific version - -// When generating C++Builder output files, certain workarounds to compiler -// problems need to be enabled! When invoking DCC on the command-line, use -// the -DBCB parameter. When invoking MSBUILD, include the DCC_Define="BCB" -// attribute in the /p parameter. -{$IFDEF BCB} - {$DEFINE CBUILDER} -{$ELSE} - {$DEFINE DELPHI} -{$ENDIF} - -{$UNDEF USE_OPENSSL} -{$UNDEF STATICLOAD_OPENSSL} - -{$UNDEF USE_ZLIB_UNIT} -{$UNDEF USE_SSPI} - -// $DEFINE the following if the global objects in the IdStack and IdThread -// units should be freed on finalization -{.$DEFINE FREE_ON_FINAL} -{$UNDEF FREE_ON_FINAL} - -// Make sure the following is $DEFINE'd only for suitable environments -// as specified further below. This works in conjunction with the -// FREE_ON_FINAL define above. -{$UNDEF REGISTER_EXPECTED_MEMORY_LEAK} -{$UNDEF HAS_System_RegisterExpectedMemoryLeak} - -// FastMM is natively available in BDS 2006 and higher. $DEFINE the -// following if FastMM has been installed manually in earlier versions -{.$DEFINE USE_FASTMM4} -{$UNDEF USE_FASTMM4} - -// $DEFINE the following if MadExcept has been installed manually in -// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced -// in BDS 2006) -{.$DEFINE USE_MADEXCEPT} -{$UNDEF USE_MADEXCEPT} - -// $DEFINE the following if LeakCheck has been installed manually in -// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced -// in BDS 2006) -{.$DEFINE USE_LEAKCHECK} -{$UNDEF USE_LEAKCHECK} - -// Make sure the following are $DEFINE'd only for Delphi/C++Builder 2009 onwards -// as specified further below. The VCL is fully Unicode, where the 'String' -// type maps to System.UnicodeString, not System.AnsiString anymore -{$UNDEF STRING_IS_UNICODE} -{$UNDEF STRING_IS_ANSI} -{$UNDEF STRING_UNICODE_MISMATCH} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. Delphi/C++Builder Mobile/NextGen compilers -// do not support Ansi data types anymore, and is moving away from raw -// pointers as well. -// -// UPDATE: in Delphi/C++Builder 10.4, all Ansi types are supported again on -// all platforms, including the mobile compilers. -{$DEFINE HAS_AnsiString} -{$DEFINE HAS_AnsiChar} -{$DEFINE HAS_PAnsiChar} -{$UNDEF HAS_PPAnsiChar} -{$UNDEF NO_ANSI_TYPES} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. Delphi/C++Builder Mobile/NextGen compilers -// use ARC for TObject life time management. -// -// UPDATE: ARC for TObject lifetime management has been removed in -// Delphi/C++Builder 10.4 mobile compilers. All platforms now use a single -// unified memory management model! -{$UNDEF USE_MARSHALLED_PTRS} -{$UNDEF HAS_MarshaledAString} -{$UNDEF USE_OBJECT_ARC} - -// Make sure the following is $DEFINE'd only for suitable environments -// as specified further below. -{$UNDEF STRING_IS_IMMUTABLE} -{$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. -{$UNDEF HAS_TEncoding} -{$UNDEF HAS_TEncoding_GetEncoding_ByEncodingName} -{$UNDEF HAS_Exception_RaiseOuterException} -{$UNDEF HAS_System_ReturnAddress} -{$UNDEF HAS_TCharacter} -{$UNDEF HAS_TInterlocked} -{$UNDEF HAS_TNetEncoding} - -// Make sure that this is defined only for environments where we are using -// the iconv library to charactor conversions. -{.$UNDEF USE_ICONV} -{.$UNDEF USE_LCONVENC} - -//Define for Delphi cross-compiler targetting Posix -{$UNDEF USE_VCL_POSIX} -{$UNDEF HAS_ComponentPlatformsAttribute} -{$UNDEF HAS_ComponentPlatformsAttribute_Win32} -{$UNDEF HAS_ComponentPlatformsAttribute_Win64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSX32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator32} -{$UNDEF HAS_ComponentPlatformsAttribute_Android} -{$UNDEF HAS_ComponentPlatformsAttribute_Android32Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device32} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux64} -{$UNDEF HAS_ComponentPlatformsAttribute_WinNX32} -{$UNDEF HAS_ComponentPlatformsAttribute_WinIoT32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device64} -{$UNDEF HAS_ComponentPlatformsAttribute_WinARM} -{$UNDEF HAS_ComponentPlatformsAttribute_WinARM32} -{$UNDEF HAS_ComponentPlatformsAttribute_OSX64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux32Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux64Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Android64} -{$UNDEF HAS_ComponentPlatformsAttribute_Android64Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator64} -{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm32} -{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSXArm64} -{$UNDEF HAS_ComponentPlatformsAttribute_AllPlatforms} -{$UNDEF HAS_DIRECTIVE_WARN_DEFAULT} - -// Define for Delphi to auto-generate platform-appropriate '#pragma link' statements in HPP files -{$UNDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT} - -// detect compiler versions - -{$IFNDEF FPC} - - // TODO: to detect features in Delphi/C++Builder v6 and later, use CompilerVersion - // and RTLVersion constants instead of VERXXX defines. We still support v5, which - // does not have such constants. - - // Delphi 4 - {$IFDEF VER120} - {$DEFINE DCC} - {$DEFINE VCL_40} - {$DEFINE DELPHI_4} - {$ENDIF} - - // C++Builder 4 - {$IFDEF VER125} - {$DEFINE DCC} - {$DEFINE VCL_40} - {$DEFINE CBUILDER_4} - {$ENDIF} - - // Delphi & C++Builder 5 - {$IFDEF VER130} - {$DEFINE DCC} - {$DEFINE VCL_50} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_5} - {$ELSE} - {$DEFINE DELPHI_5} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 6 - {$IFDEF VER140} - {$DEFINE DCC} - {$DEFINE VCL_60} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_6} - {$ELSE} - {$DEFINE DELPHI_6} - {$ENDIF} - {$ENDIF} - - //Delphi 7 - {$IFDEF VER150} - {$DEFINE DCC} - {$DEFINE VCL_70} - {$DEFINE DELPHI_7} // there was no C++ Builder 7 - {$ENDIF} - - //Delphi 8 - {$IFDEF VER160} - {$DEFINE DCC} - {$DEFINE VCL_80} - {$DEFINE DELPHI_8} // there was no C++ Builder 8 - {$ENDIF} - - //Delphi 2005 - {$IFDEF VER170} - {$DEFINE DCC} - {$DEFINE VCL_2005} - {$DEFINE DELPHI_2005} // there was no C++Builder 2005 - {$ENDIF} - - // NOTE: CodeGear decided to make Highlander be a non-breaking release - // (no interface changes, thus fully backwards compatible without any - // end user code changes), so VER180 applies to both BDS 2006 and - // Highlander prior to the release of RAD Studio 2007. Use VER185 to - // identify Highlanger specifically. - - //Delphi & C++Builder 2006 - //Delphi & C++Builder 2007 (Highlander) - {$IFDEF VER180} - {$DEFINE DCC} - {$DEFINE VCL_2006} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2006} - {$ELSE} - {$DEFINE DELPHI_2006} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2007 (Highlander) - {$IFDEF VER185} - {$DEFINE DCC} - {$UNDEF VCL_2006} - {$DEFINE VCL_2007} - {$IFDEF CBUILDER} - {$UNDEF CBUILDER_2006} - {$DEFINE CBUILDER_2007} - {$ELSE} - {$UNDEF DELPHI_2006} - {$DEFINE DELPHI_2007} - {$ENDIF} - {$ENDIF} - - // BDS 2007 NET personality uses VER190 instead of 185. - //Delphi .NET 2007 - {$IFDEF VER190} - {$DEFINE DCC} - {$IFDEF CIL} - //Delphi 2007 - {$DEFINE VCL_2007} - {$DEFINE DELPHI_2007} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2009 (Tiburon) - {$IFDEF VER200} - {$DEFINE DCC} - {$DEFINE VCL_2009} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2009} - {$ELSE} - {$DEFINE DELPHI_2009} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2010 (Weaver) - {$IFDEF VER210} - {$DEFINE DCC} - {$DEFINE VCL_2010} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2010} - {$ELSE} - {$DEFINE DELPHI_2010} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder XE (Fulcrum) - {$IFDEF VER220} - //REMOVE DCC DEFINE after the next Fulcrum beta. - //It will be defined there. - {$IFNDEF DCC} - {$DEFINE DCC} - {$ENDIF} - {$DEFINE VCL_XE} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE} - {$ELSE} - {$DEFINE DELPHI_XE} - {$ENDIF} - {$ENDIF} - - // DCC is now defined by the Delphi compiler starting in XE2 - - //Delphi & CBuilder XE2 (Pulsar) - {$IFDEF VER230} - {$DEFINE VCL_XE2} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE2} - {$ELSE} - {$DEFINE DELPHI_XE2} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE3 (Waterdragon) - //Delphi & CBuilder XE3.5 (Quintessence - early betas only) - {$IFDEF VER240} - {$DEFINE VCL_XE3} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE3} - {$ELSE} - {$DEFINE DELPHI_XE3} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE4 (Quintessence) - {$IFDEF VER250} - {$UNDEF VCL_XE3} - {$DEFINE VCL_XE4} - {$IFDEF CBUILDER} - {$UNDEF CBUILDER_XE3} - {$DEFINE CBUILDER_XE4} - {$ELSE} - {$UNDEF DELPHI_XE3} - {$DEFINE DELPHI_XE4} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE5 (Zephyr) - {$IFDEF VER260} - {$DEFINE VCL_XE5} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE5} - {$ELSE} - {$DEFINE DELPHI_XE5} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder AppMethod - //AppMethod is just XE5 for mobile only, VCL is removed - {$IFDEF VER265} - {$DEFINE VCL_XE5} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE5} - {$ELSE} - {$DEFINE DELPHI_XE5} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE6 (Proteus) - {$IFDEF VER270} - {$DEFINE VCL_XE6} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE6} - {$ELSE} - {$DEFINE DELPHI_XE6} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE7 (Carpathia) - {$IFDEF VER280} - {$DEFINE VCL_XE7} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE7} - {$ELSE} - {$DEFINE DELPHI_XE7} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE8 (Elbrus) - {$IFDEF VER290} - {$DEFINE VCL_XE8} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE8} - {$ELSE} - {$DEFINE DELPHI_XE8} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.0 Seattle (Aitana) - {$IFDEF VER300} - {$DEFINE VCL_10_0} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_VCL_10_0} - {$ELSE} - {$DEFINE DELPHI_VCL_10_0} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.1 Berlin (BigBen) - {$IFDEF VER310} - {$DEFINE VCL_10_1} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_1} - {$ELSE} - {$DEFINE DELPHI_10_1} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.2 Tokyo (Godzilla) - {$IFDEF VER320} - {$DEFINE VCL_10_2} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_2} - {$ELSE} - {$DEFINE DELPHI_10_2} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.3 Rio (Carnival) - {$IFDEF VER330} - {$DEFINE VCL_10_3} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_3} - {$ELSE} - {$DEFINE DELPHI_10_3} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.4 Sydney (Denali) - {$IFDEF VER340} - {$DEFINE VCL_10_4} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_4} - {$ELSE} - {$DEFINE DELPHI_10_4} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 11.0 Alexandria (Olympus) - {$IFDEF VER350} - {$DEFINE VCL_11} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_11} - {$ELSE} - {$DEFINE DELPHI_11} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 12.0 Athens (Yukon) - {$IFDEF VER360} - {$DEFINE VCL_12} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_12} - {$ELSE} - {$DEFINE DELPHI_12} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 13.0+ (?) - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF CompilerVersion >= 37} - {$MESSAGE WARN 'Unknown compiler version detected! Assuming >= 13.x '} - {$DEFINE VCL_UNKNOWN_VERSION} - {$DEFINE VCL_13} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_13} - {$ELSE} - {$DEFINE DELPHI_13} - {$ENDIF} - {$IFEND} - {$ENDIF} - - // Kylix - // - //Important: Don't use CompilerVersion here as IF's are evaluated before - //IFDEF's and Kylix 1 does not have CompilerVersion defined at all. - {$IFDEF LINUX} - {$DEFINE UNIX} - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF (RTLVersion >= 14.0) and (RTLVersion <= 14.5) } - {$DEFINE KYLIX} - {$IF RTLVersion = 14.5} - {$DEFINE KYLIX_3} - {$ELSEIF RTLVersion >= 14.2} - {$DEFINE KYLIX_2} - {$ELSE} - {$DEFINE KYLIX_1} - {$IFEND} - {$IFEND} - {$ENDIF} - {$ENDIF} - -{$ENDIF} - -// Delphi.NET -// Covers D8+ -{$IFDEF CIL} - // Platform specific conditional. Used for platform specific code. - {$DEFINE DOTNET} - {$DEFINE STRING_IS_UNICODE} - {$DEFINE STRING_IS_IMMUTABLE} - {.$DEFINE HAS_Int8} - {.$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_UInt64} -{$ENDIF} - -{$IFDEF KYLIX} - {$DEFINE VCL_60} - {$DEFINE INT_THREAD_PRIORITY} - {$DEFINE CPUI386} - {$UNDEF USE_BASEUNIX} - - {$IFDEF KYLIX_3} - {$DEFINE KYLIX_3_OR_ABOVE} - {$ENDIF} - - {$IFDEF KYLIX_3_OR_ABOVE} - {$DEFINE KYLIX_2_OR_ABOVE} - {$ELSE} - {$IFDEF KYLIX_2} - {$DEFINE KYLIX_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF KYLIX_2_OR_ABOVE} - {$DEFINE KYLIX_1_OR_ABOVE} - {$ELSE} - {$IFDEF KYLIX_1} - {$DEFINE KYLIX_1_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFNDEF KYLIX_3_OR_ABOVE} - {$DEFINE KYLIXCOMPAT} - {$ENDIF} - - {$IFDEF KYLIX_2_OR_ABOVE} - {$DEFINE USE_ZLIB_UNIT} - {$ENDIF} -{$ENDIF} - -// FPC (2+) - -{$IFDEF FPC} - // TODO: In FreePascal 4.2.0+, a Delphi-like UnicodeString type is supported. - // However, String/(P)Char do not map to UnicodeString/(P)WideChar unless - // either {$MODE DelphiUnicode} or {$MODESWITCH UnicodeStrings} is used. - // We should consider enabling one of them so Indy uses the same Unicode logic - // in Delphi 2009+ and FreePascal 4.2.0+ and reduces IFDEFs (in particular, - // STRING_UNICODE_MISMATCH, see further below). However, FreePascal's RTL - // is largely not UnicodeString-enabled yet. Maybe we should enable - // {$MODE DelphiUnicode} anyway, and then deal with any RTL function issues - // on an as-needed basis... - {$MODE Delphi} - //note that we may need further defines for widget types depending on - //what we do and what platforms we support in FPC. - //I'll let Marco think about that one. - {$IFDEF UNIX} - {$DEFINE USE_BASEUNIX} - {$IFDEF LINUX} - //In Linux for I386, you can choose between a Kylix-libc API or - //the standard RTL Unix API. Just pass -dKYLIXCOMPAT to the FPC compiler. - //I will see what I can do about the Makefile. - {$IFDEF KYLIXCOMPAT} - {$IFDEF CPUI386} - {$UNDEF USE_BASEUNIX} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$IFDEF USE_BASEUNIX} - {$UNDEF KYLIXCOMPAT} - {$ENDIF} - {$ENDIF} - - // FPC_FULLVERSION was added in FPC 2.2.4 - // Have to use Defined() or else Delphi compiler chokes, since it - // evaluates $IF statements before $IFDEF statements... - - {$MACRO ON} // must be on in order to use versioning macros - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30101)} - {$DEFINE FPC_3_1_1_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30000)} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20701)} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20604)} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20602)} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20600)} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20404)} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20402)} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20400)} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20204)} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20202)} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20105)} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$IFEND} - - // just in case - {$IFDEF FPC_3_1_1} - {$DEFINE FPC_3_1_1_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_3_0_0} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_7_1} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_4} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_2} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_0} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_4} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_2} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_0} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_2_4} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_2_2} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_1_5} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ENDIF} - - {$IFDEF FPC_3_1_1_OR_ABOVE} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_3_0_0} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_3_0_0_OR_ABOVE} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_7_1} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_7_1_OR_ABOVE} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_4} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_4_OR_ABOVE} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_2} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_0} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_0_OR_ABOVE} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_4} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_4_OR_ABOVE} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_2} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_2_OR_ABOVE} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_0} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_0_OR_ABOVE} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_2_4} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_4_OR_ABOVE} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_2_2} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_2_OR_ABOVE} - {$DEFINE FPC_2_2_0_OR_ABOVE} - {$ELSE} - {$IFDEF VER2_2} - {$DEFINE FPC_2_2_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_0_OR_ABOVE} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_1_5} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {.$IFDEF FPC_2_7_1_OR_ABOVE} - // support for RawByteString and UnicodeString - {.$MODE DelphiUnicode} - {.$MODESWITCH UnicodeStrings} - {.$CODEPAGE UTF8} // needed for Unicode string literals to work properly - {.$DEFINE VCL_2009} - {.$DEFINE DELPHI_2009} - {.$ELSE} - {$DEFINE VCL_70} - {$DEFINE DELPHI_7} - {.$ENDIF} -{$ENDIF} - -// end FPC - -{$IFDEF VCL_13} - {$DEFINE VCL_13_OR_ABOVE} -{$ENDIF} - -{$IFDEF VCL_13_OR_ABOVE} - {$DEFINE VCL_12_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_12} - {$DEFINE VCL_12_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_12_OR_ABOVE} - {$DEFINE VCL_11_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_11} - {$DEFINE VCL_11_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_11_OR_ABOVE} - {$DEFINE VCL_10_4_OR_ABOVE} - {$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_4} - {$DEFINE VCL_10_4_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_4_OR_ABOVE} - {$DEFINE VCL_10_3_OR_ABOVE} - {$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_3} - {$DEFINE VCL_10_3_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_OR_ABOVE} - {$DEFINE VCL_10_2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_2} - {$DEFINE VCL_10_2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_2_OR_ABOVE} - {$DEFINE VCL_10_1_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_1} - {$DEFINE VCL_10_1_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_1_OR_ABOVE} - {$DEFINE VCL_10_0_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_0} - {$DEFINE VCL_10_0_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_0_OR_ABOVE} - {$DEFINE VCL_XE8_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE8} - {$DEFINE VCL_XE8_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE VCL_XE7_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE7} - {$DEFINE VCL_XE7_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE7_OR_ABOVE} - {$DEFINE VCL_XE6_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE6} - {$DEFINE VCL_XE6_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE6_OR_ABOVE} - {$DEFINE VCL_XE5_OR_ABOVE} - {$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE5} - {$DEFINE VCL_XE5_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE5_OR_ABOVE} - {$DEFINE VCL_XE4_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE4} - {$DEFINE VCL_XE4_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE4_OR_ABOVE} - {$DEFINE VCL_XE3_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE3} - {$DEFINE VCL_XE3_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE3_OR_ABOVE} - {$DEFINE VCL_XE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE2} - {$DEFINE VCL_XE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE2_OR_ABOVE} - {$DEFINE VCL_XE_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE} - {$DEFINE VCL_XE_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE_OR_ABOVE} - {$DEFINE VCL_2010_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2010} - {$DEFINE VCL_2010_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2010_OR_ABOVE} - {$DEFINE VCL_2009_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2009} - {$DEFINE VCL_2009_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2009_OR_ABOVE} - {$DEFINE VCL_2007_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2007} - {$DEFINE VCL_2007_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2007_OR_ABOVE} - {$DEFINE VCL_2006_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2006} - {$DEFINE VCL_2006_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2006_OR_ABOVE} - {$DEFINE VCL_2005_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2005} - {$DEFINE VCL_2005_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2005_OR_ABOVE} - {$DEFINE VCL_8_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_80} - {$DEFINE VCL_8_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_8_OR_ABOVE} - {$DEFINE VCL_7_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_70} - {$DEFINE VCL_7_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_7_OR_ABOVE} - {$DEFINE VCL_6_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_60} - {$DEFINE VCL_6_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_6_OR_ABOVE} - {$DEFINE VCL_5_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_50} - {$DEFINE VCL_5_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_5_OR_ABOVE} - {$DEFINE VCL_4_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_40} - {$DEFINE VCL_4_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -// Normalize Delphi compiler defines to match FPC for consistency: -// -// CPU32 - any 32-bit CPU -// CPU64 - any 64-bit CPU -// WINDOWS - any Windows platform (32-bit, 64-bit, CE) -// WIN32 - Windows 32-bit -// WIN64 - Windows 64-bit -// WINCE - Windows CE -// -// Consult the "Free Pascal Programmer's Guide", Appendix G for the complete -// list of defines that are used. Do not work on this unless you understand -// what the FreePascal developers are doing. Not only do you have to -// descriminate with operating systems, but also with chip architectures -// are well. -// -// DCC Pulsar+ define the following values: -// ASSEMBLER -// DCC -// CONDITIONALEXPRESSIONS -// NATIVECODE -// UNICODE -// MACOS -// MACOS32 -// MACOS64 -// MSWINDOWS -// WIN32 -// WIN64 -// LINUX -// POSIX -// POSIX32 -// CPU386 -// CPUX86 -// CPUX64 -// -// Kylix defines the following values: -// LINUX -// (others??) -// - -{$IFNDEF FPC} - // TODO: We need to use ENDIAN_BIG for big endian chip architectures, - // such as 680x0, PowerPC, Sparc, and MIPS, once DCC supports them, - // provided it does not already define its own ENDIAN values by then... - {$DEFINE ENDIAN_LITTLE} - {$IFNDEF VCL_6_OR_ABOVE} - {$DEFINE MSWINDOWS} - {$ENDIF} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} - // TODO: map Pulsar's non-Windows platform defines... - {$IFDEF VCL_XE2_OR_ABOVE} - {$IFDEF VCL_XE8_OR_ABOVE} - {$IFDEF CPU32BITS} - //any 32-bit CPU - {$DEFINE CPU32} - {$ENDIF} - {$IFDEF CPU64BITS} - {$DEFINE CPU64} - {$ENDIF} - {$ELSE} - {$IFDEF CPU386} - //any 32-bit CPU - {$DEFINE CPU32} - //Intel 386 compatible chip architecture - {$DEFINE CPUI386} - {$ENDIF} - {$IFDEF CPUX86} - {$DEFINE CPU32} - {$ENDIF} - {$IFDEF CPUX64} - //any 64-bit CPU - {$DEFINE CPU64} - //AMD64 compatible chip architecture - {$DEFINE CPUX86_64} //historical name for AMD64 - {$DEFINE CPUAMD64} - {$ENDIF} - {$ENDIF} - {$ELSE} - {$IFNDEF DOTNET} - {$IFNDEF KYLIX} - {$DEFINE I386} - {$ENDIF} - {$ENDIF} - {$DEFINE CPU32} - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - //differences in DotNET Framework versions. - {$IFDEF VCL_2007_OR_ABOVE} - {$DEFINE DOTNET_2} - {$DEFINE DOTNET_2_OR_ABOVE} - {$ELSE} - {$DEFINE DOTNET_1_1} - {$ENDIF} - {$DEFINE DOTNET_1_1_OR_ABOVE} - // Extra include used in D7 for testing. Remove later when all comps are - // ported. Used to selectively exclude non ported parts. Allowed in places - // IFDEFs are otherwise not permitted. - {$DEFINE DOTNET_EXCLUDE} -{$ENDIF} - -// Check for available features - -{$IFDEF CBUILDER} - // When generating a C++ HPP file, if a class has no explicit constructor - // defined and contains compiler-managed members (xxxString, TDateTime, - // Variant, DelphiInterface, etc), the HPP will contain a forwarding - // inline constructor that implicitly initializes those managed members, - // which will overwrite any non-default initializations performed inside - // of InitComponent() overrides! In this situation, the workaround is to - // define an explicit constructor that calls the base class constructor - // manually, allowing those managed members to be initialized by the - // compiler before InitComponent() overrides then re-assign them. - {$DEFINE WORKAROUND_INLINE_CONSTRUCTORS} -{$ENDIF} - -{$IFDEF VCL_5_OR_ABOVE} - {$IFNDEF FPC} - {$IFNDEF KYLIX} - {$DEFINE HAS_RemoveFreeNotification} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_GetObjectProp} - {$DEFINE HAS_TObjectList} - {$DEFINE HAS_StrToInt64Def} -{$ENDIF} - -{$IFDEF VCL_6_OR_ABOVE} - {$DEFINE HAS_PCardinal} - {$DEFINE HAS_PByte} - {$DEFINE HAS_PWord} - {$DEFINE HAS_PPointer} - {$DEFINE HAS_TList_Assign} - {$DEFINE HAS_sLineBreak} - {$DEFINE HAS_RaiseLastOSError} - {$DEFINE HAS_SysUtils_IncludeExcludeTrailingPathDelimiter} - {$DEFINE HAS_SysUtils_DirectoryExists} - {$DEFINE HAS_UNIT_DateUtils} - {$DEFINE HAS_UNIT_StrUtils} - {$DEFINE HAS_UNIT_Types} - {$DEFINE HAS_TryStrToInt} - {$DEFINE HAS_TryStrToInt64} - {$DEFINE HAS_TryEncodeDate} - {$DEFINE HAS_TryEncodeTime} - {$DEFINE HAS_ENUM_ELEMENT_VALUES} - {$IFNDEF FPC} - {$DEFINE HAS_IInterface} - {$DEFINE HAS_TSelectionEditor} - {$DEFINE HAS_TStringList_CaseSensitive} - {$DEFINE HAS_AcquireExceptionObject} - {$IFNDEF KYLIX} - {$DEFINE HAS_DEPRECATED} - {$DEFINE HAS_SYMBOL_PLATFORM} - {$DEFINE HAS_UNIT_PLATFORM} - {$IFNDEF VCL_8_OR_ABOVE} - // Delphi 6 and 7 have an annoying bug that if a class method is declared as - // deprecated, the compiler will emit a "symbol is deprecated" warning - // on the method's implementation! So we will have to wrap implementations - // of deprecated methods with {$WARN SYMBOL_DEPRECATED OFF} directives - // to disable that warning. - {$DEFINE DEPRECATED_IMPL_BUG} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$IFNDEF DOTNET} - //Widget defines are omitted in .NET - {$DEFINE VCL_60_PLUS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_7_OR_ABOVE} - {$IFNDEF FPC} - {$DEFINE HAS_UInt64} // Note: it was just an alias for Int64 until D2006! - {$DEFINE HAS_NAMED_THREADS} - {$DEFINE HAS_TStrings_NameValueSeparator} - {$DEFINE HAS_TStrings_ValueFromIndex} - // Note: there is a ZLib unit available, but it doesn't have everything - // that is available in the System.ZLib unit in Delphi XE2+, so we are - // not going to use this ZLib unit yet... - {.$DEFINE HAS_UNIT_ZLib} - {$ENDIF} - {$DEFINE HAS_TFormatSettings} - {$DEFINE HAS_PosEx} - {$IFNDEF VCL_70} - // not implemented in D7 - {$DEFINE HAS_STATIC_TThread_Queue} - {$ENDIF} - {$IFNDEF CIL} - {$IFNDEF VCL_80} - // not implemented in D8 or .NET - {$DEFINE HAS_STATIC_TThread_Synchronize} - {$ENDIF} - {$ENDIF} -{$ELSE} - {$IFDEF CBUILDER_6} - {$DEFINE HAS_NAMED_THREADS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2005_OR_ABOVE} - {$IFDEF DCC} - // class helpers were first introduced in D2005, but were buggy and not - // officially supported until D2006... - {.$DEFINE HAS_CLASS_HELPER} - {$ENDIF} -{$ELSE} - {$IFDEF DCC} - // InterlockedCompareExchange() was declared in the Windows unit using Pointer - // parameters until Delphi 2005, when it was switched to Longint parameters - // instead to match the actual Win32 API declaration. - {$DEFINE HAS_InterlockedCompareExchange_Pointers} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2006_OR_ABOVE} - {$DEFINE USE_INLINE} - {$DEFINE HAS_2PARAM_FileAge} - {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? - {$DEFINE HAS_CLASS_HELPER} - {$IFDEF WINDOWS} - // System.RegisterExpectedMemoryLeak() is only available on Windows at this time - {$DEFINE HAS_System_RegisterExpectedMemoryLeak} - {$ENDIF} - // In C++Builder 2006 and 2007, UInt64 is emitted as signed __int64 in HPP - // files instead of as unsigned __int64. This causes conflicts in overloaded - // routines that have (U)Int64 parameters. This was fixed in C++Builder 2009... - {$IFDEF CBUILDER} - {$DEFINE BROKEN_UINT64_HPPEMIT} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2007_OR_ABOVE} - {$IFNDEF CBUILDER_2007} - // class properties are broken in C++Builder 2007, causing AVs at compile-time - {$DEFINE HAS_CLASSPROPERTIES} - {$ENDIF} - // Native(U)Int exist but are buggy, so do not use them yet - {.$DEFINE HAS_NativeInt} - {.$DEFINE HAS_NativeUInt} - {$DEFINE HAS_DWORD_PTR} - {$DEFINE HAS_ULONG_PTR} - {$DEFINE HAS_ULONGLONG} - {$DEFINE HAS_PGUID} - {$DEFINE HAS_PPAnsiChar} - {$DEFINE HAS_CurrentYear} - {$IFNDEF DOTNET} - {$DEFINE HAS_TIMEUNITS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2009_OR_ABOVE} - {$IFNDEF DOTNET} - {$DEFINE STRING_IS_UNICODE} - {$DEFINE HAS_UnicodeString} - {$DEFINE HAS_TEncoding} - {$DEFINE HAS_TCharacter} - {$DEFINE HAS_InterlockedCompareExchangePointer} - {$DEFINE HAS_WIDE_TCharArray} - {$DEFINE HAS_PUInt64} - {$IFDEF VCL_2009} - // TODO: need to differentiate between RTM and Update 1 - // FmtStr() is broken in RTM but was fixed in Update 1 - {$DEFINE BROKEN_FmtStr} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_CLASSVARS} - {$DEFINE HAS_DEPRECATED_MSG} - {$DEFINE HAS_TBytes} - // Native(U)Int are still buggy, so do not use them yet - {.$DEFINE HAS_NativeInt} - {.$DEFINE HAS_NativeUInt} - {$DEFINE HAS_Int8} - {$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_UIntToStr} - // UInt64 is now emitted as unsigned __int64 in HPP files - {$IFDEF CBUILDER} - {$UNDEF BROKEN_UINT64_HPPEMIT} - {$ENDIF} - {$IFDEF DCC} - {$IFDEF WINDOWS} - // Exception.RaiseOuterException() is only available on Windows at this time - {$DEFINE HAS_Exception_RaiseOuterException} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_SetCodePage} - {$DEFINE HAS_PRawByteString} - {$DEFINE HAS_TThreadProcedure} -{$ENDIF} - -{$IFDEF VCL_2010_OR_ABOVE} - {$DEFINE HAS_CLASSCONSTRUCTOR} - {$DEFINE HAS_CLASSDESTRUCTOR} - {$DEFINE HAS_DELAYLOAD} - {$DEFINE HAS_TThread_NameThreadForDebugging} - {$DEFINE DEPRECATED_TThread_SuspendResume} - // Native(U)Int are finally ok to use now - {$DEFINE HAS_NativeInt} - {$DEFINE HAS_NativeUInt} - {$DEFINE HAS_USHORT} - {$DEFINE HAS_IOUtils_TPath} -{$ENDIF} - -{$IFDEF VCL_XE_OR_ABOVE} - {$DEFINE HAS_TFormatSettings_Object} - {$DEFINE HAS_LocaleCharsFromUnicode} - {$DEFINE HAS_UnicodeFromLocaleChars} - {$DEFINE HAS_PLongBool} - {$DEFINE HAS_PVOID} - {$DEFINE HAS_ULONG64} - {$DEFINE HAS_TEncoding_GetEncoding_ByEncodingName} - {$DEFINE HAS_DateUtils_TTimeZone} - {$IFDEF DCC} - // Exception.RaiseOuterException() is now available on all platforms - {$DEFINE HAS_Exception_RaiseOuterException} - {$ENDIF} - {$IFNDEF DOTNET} - {$DEFINE HAS_TInterlocked} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE2_OR_ABOVE} - {$DEFINE HAS_SIZE_T} - {$DEFINE HAS_PSIZE_T} - {$DEFINE HAS_SSIZE_T} - {$DEFINE HAS_PSSIZE_T} - {$DEFINE HAS_LONG} - {$DEFINE HAS_ComponentPlatformsAttribute} - {$DEFINE HAS_ComponentPlatformsAttribute_Win32} - {$DEFINE HAS_ComponentPlatformsAttribute_Win64} - {$DEFINE HAS_ComponentPlatformsAttribute_OSX32} - {$DEFINE HAS_System_ReturnAddress} - {$DEFINE HAS_DIRECTIVE_WARN_DEFAULT} - {$DEFINE HAS_UNIT_System_ZLib} -{$ENDIF} - -{$IFDEF VCL_XE3_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_ZEROBASEDSTRINGS} - {$DEFINE HAS_SysUtils_TStringHelper} - {$IFDEF NEXTGEN} - {$DEFINE DCC_NEXTGEN} - {$DEFINE HAS_MarshaledAString} - {$DEFINE USE_MARSHALLED_PTRS} - {$IFDEF AUTOREFCOUNT} - {$DEFINE USE_OBJECT_ARC} - {$ENDIF} - {$ENDIF} - // technically, these are present in XE3, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} - {.$DEFINE HAS_ComponentPlatformsAttribute_Android} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32} - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} - {.$DEFINE HAS_ComponentPlatformsAttribute_WinNX32} -{$ENDIF} - -{$IFDEF VCL_XE4_OR_ABOVE} - {$DEFINE HAS_AnsiStrings_StrPLCopy} - {$DEFINE HAS_AnsiStrings_StrLen} - {$DEFINE HAS_Character_TCharHelper} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} -{$ENDIF} - -{$IFDEF VCL_XE5_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_Android} -{$ENDIF} - -{$IFDEF VCL_XE5_UPDATE2_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_LINKUNIT} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_NAMESPACE} -{$ENDIF} - -{$IFDEF VCL_XE7_OR_ABOVE} - {$DEFINE HAS_TNetEncoding} -{$ENDIF} - -{$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device32} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device64} - // technically, these are present in XE8, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64} - {.$DEFINE HAS_ComponentPlatformsAttribute_WinIoT32} -{$ENDIF} - -{$IFDEF VCL_10_0_OR_ABOVE} - {$IFDEF ANDROID} - {$DEFINE HAS_TAndroidHelper} - {$ENDIF} - // technically, these are present in 10.0 Seattle, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_WinARM} -{$ENDIF} - -{$IFDEF VCL_10_1_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_LEGACYHPP} - {$DEFINE HAS_TStrings_AddPair} - // technically, these are present in 10.1 Berlin, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_OSX64} - {.$DEFINE HAS_ComponentPlatformsAttribute_OSXNX64} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32Arm} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64Arm} - {.$DEFINE HAS_ComponentPlatformsAttribute_Android64} -{$ENDIF} - -{$IFDEF VCL_10_2_OR_ABOVE} - {.$WARN IMPLICIT_INTEGER_CAST_LOSS OFF} - {.$WARN IMPLICIT_CONVERSION_LOSS OFF} - {.$WARN COMBINING_SIGNED_UNSIGNED64 OFF} - {$DEFINE HAS_STATIC_TThread_ForceQueue} - // In Delphi 10.2 Tokyo, TThread.ForceQueue() is broken on Android, the - // passed in procedure is called immediately instead of being delayed! - {$IFDEF ANDROID} - {$DEFINE BROKEN_TThread_ForceQueue} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator32} - {$DEFINE HAS_ComponentPlatformsAttribute_Android32Arm} - {$DEFINE HAS_ComponentPlatformsAttribute_WinARM32} - {$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} // removed in 10.3 Rio - // technically, these are present in 10.3 Rio, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator64} - {$IFDEF DCC} - {$IFDEF LINUX} - // RLebeau 9/25/2019: there is a bug in the IDE when debugging Linux projects - // where the EThreadNameException exception raised by TThread.NameThreadForDebugging() - // is not handled correctly. - {$UNDEF HAS_NAMED_THREADS} - {$ENDIF} - {$ENDIF} - {$IFDEF ANDROID} - {$UNDEF BROKEN_TThread_ForceQueue} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_UPDATE2_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_AllPlatforms} - {$DEFINE HAS_ComponentPlatformsAttribute_OSX64} -{$ENDIF} - -{$IFDEF VCL_10_4_OR_ABOVE} - // 0-based string indexing via '[]' is turned off by default in Delphi 10.4. - // TStringHelper is always 0-indexed, flat RTL functions are always 1-indexed, - // and now '[]' is 1-indexed again on all platforms - {$ZEROBASEDSTRINGS OFF} - // is the default. - {.$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} -{$ENDIF} - -{$IFDEF VCL_11_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm32} - {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm64} - {$DEFINE HAS_ComponentPlatformsAttribute_OSXArm64} -{$ENDIF} - -// Delphi XE+ cross-compiling -{$IFNDEF FPC} - {$IFDEF POSIX} - {$IF RTLVersion >= 22.0} - {$DEFINE UNIX} - {$UNDEF USE_BASEUNIX} - {$DEFINE VCL_CROSS_COMPILE} - {$DEFINE USE_VCL_POSIX} - {$IFEND} - {$ENDIF} - {$IFDEF LINUX} - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF RTLVersion >= 22.0} - {$DEFINE VCL_CROSS_COMPILE} - {$DEFINE USE_VCL_POSIX} - {$IFEND} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_CROSS_COMPILE} - {$UNDEF KYLIXCOMPAT} -{$ELSE} - {$IFDEF KYLIXCOMPAT} - {$linklib c} - {$ENDIF} -{$ENDIF} - -{$IFDEF FPC} - {$DEFINE USE_INLINE} - {$DEFINE USE_CLASSINLINE} - {$DEFINE USE_TBitBtn} //use Bit Buttons instead of Buttons - {$DEFINE FPC_REINTRODUCE_BUG} - {$DEFINE FPC_CIRCULAR_BUG} - {$DEFINE NO_REDECLARE} - {$DEFINE BYTE_COMPARE_SETS} - {$DEFINE HAS_QWord} // TODO: when was QWord introduced? - {$DEFINE HAS_PQWord} // TODO: when was PQWord introduced? - {$IFDEF FPC_2_1_5_OR_ABOVE} - {$DEFINE HAS_UInt64} - {.$DEFINE HAS_PUInt64} // TODO: is this defined? - {$ENDIF} - {$IFDEF FPC_2_2_0_OR_ABOVE} - {$DEFINE HAS_InterlockedCompareExchange_Pointers} - {$ENDIF} - {$IFDEF FPC_2_2_2_OR_ABOVE} - {$DEFINE HAS_SharedSuffix} - {$ENDIF} - {$IFDEF FPC_2_2_4_OR_ABOVE} - // these types are only available on Unix systems (FreeBSD, Linux, etc) - {$IFDEF UNIX} - {$DEFINE HAS_UNIT_UnixType} - {$DEFINE HAS_SIZE_T} - {$DEFINE HAS_PSIZE_T} - {$DEFINE HAS_SSIZE_T} - {$DEFINE HAS_PSSIZE_T} - {$DEFINE HAS_TIME_T} - {$DEFINE HAS_PTIME_T} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_PtrInt} - {$DEFINE HAS_PtrUInt} - {$DEFINE HAS_PGUID} - {$DEFINE HAS_LPGUID} - {$DEFINE HAS_PPAnsiChar} - {$DEFINE HAS_ENUM_ELEMENT_VALUES} - {$DEFINE HAS_AcquireExceptionObject} // TODO: when was AcquireExceptionObject introduced? - {$IFDEF WINDOWS} - {$DEFINE HAS_ULONG_PTR} - {.$DEFINE HAS_ULONGLONG} // TODO: is this defined? - {$ENDIF} - {$DEFINE HAS_UNIT_ctypes} - {$DEFINE HAS_sLineBreak} - {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? - {$IFDEF FPC_HAS_UNICODESTRING} - {$DEFINE HAS_UnicodeString} - {$ELSE} - {$IFDEF FPC_2_4_0_OR_ABOVE} - {$DEFINE HAS_UnicodeString} - {$ENDIF} - {$ENDIF} - {$IFDEF FPC_2_4_4_OR_ABOVE} - {$DEFINE DEPRECATED_TThread_SuspendResume} - {$DEFINE HAS_DEPRECATED} // TODO: when was deprecated introduced? Possibly 1.9.x - {$DEFINE HAS_DEPRECATED_MSG} // TODO: when was message support added? Possibly 2.4.x - {$DEFINE HAS_STATIC_TThread_Synchronize} - {$IFNDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE USE_SEMICOLON_BEFORE_DEPRECATED} // TODO: which earlier versions require a semicolon? - {$ENDIF} - {$ENDIF} - {$IFDEF FPC_2_6_0_OR_ABOVE} - {$DEFINE HAS_NativeInt} - {$DEFINE HAS_NativeUInt} - {$DEFINE HAS_CLASS_HELPER} - {$ENDIF} - {$IFDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE HAS_Int8} - {$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_GetLocalTimeOffset} - {$DEFINE HAS_UniversalTimeToLocal} - {$DEFINE HAS_LocalTimeToUniversal} - {$ENDIF} - {$IFDEF FPC_2_6_4_OR_ABOVE} - {$DEFINE HAS_PInt8} - {$DEFINE HAS_PUInt8} - {$DEFINE HAS_PInt16} - {$DEFINE HAS_PUInt16} - {$DEFINE HAS_PInt32} - {$DEFINE HAS_PUInt32} - {$ENDIF} - {$IFDEF FPC_3_0_0_OR_ABOVE} - {$DEFINE HAS_STATIC_TThread_Queue} - {$DEFINE HAS_SetCodePage} - {$ENDIF} - {$IFDEF FPC_UNICODESTRINGS} - {$DEFINE STRING_IS_UNICODE} - {$ENDIF} - {$IFDEF FPC_3_1_1_OR_ABOVE} - {$DEFINE HAS_STATIC_TThread_ForceQueue} // requires rev 37359+ - {$DEFINE HAS_PRawByteString} - {$DEFINE HAS_UIntToStr} // requires rev 40529+ - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - {$DEFINE WIDGET_WINFORMS} -{$ELSE} - {$DEFINE WIDGET_VCL_LIKE} // LCL included. - {$DEFINE WIDGET_VCL_LIKE_OR_KYLIX} - {$IFDEF FPC} - {$DEFINE WIDGET_LCL} - {$ELSE} - {$IFDEF KYLIX} - {$DEFINE WIDGET_KYLIX} - {$ELSE} - {$DEFINE WIDGET_VCL} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -// .NET and Delphi 2009+ support UNICODE strings natively! -// -// FreePascal 2.4.0+ supports UnicodeString, but does not map its -// native String type to UnicodeString except when {$MODE DelphiUnicode} -// or {$MODESWITCH UnicodeStrings} is enabled. However, UNICODE is not -// defined in that mode yet until its RTL has been updated to support -// UnicodeString. STRING_UNICODE_MISMATCH is defined when the native -// String/Char types do not map to the same types that APIs are expecting -// based on whether UNICODE is defined or not. -// -// NOTE: Do not define UNICODE here. The compiler defines -// the symbol automatically. -{$IFDEF STRING_IS_UNICODE} - {$IFNDEF UNICODE} - {$DEFINE STRING_UNICODE_MISMATCH} - {$ENDIF} -{$ELSE} - {$DEFINE STRING_IS_ANSI} - {$IFDEF UNICODE} - {$DEFINE STRING_UNICODE_MISMATCH} - {$ENDIF} -{$ENDIF} - -{$IFDEF DCC_NEXTGEN} - {$DEFINE NO_ANSI_TYPES} - {.$DEFINE STRING_IS_IMMUTABLE} // Strings are NOT immutable in NEXTGEN yet - {$IFDEF USE_OBJECT_ARC} - // TODO: move these to an appropriate section. Not doing this yet because - // it is a major interface change to switch to Generics and we should - // maintain backwards compatibility with earlier compilers for the time - // being. Defining them only here for now because the non-Generic versions - // of these classes have become deprecated by ARC and so we need to start - // taking advantage of the Generics versions... - {$DEFINE HAS_UNIT_Generics_Collections} - {$DEFINE HAS_UNIT_Generics_Defaults} - {$DEFINE HAS_GENERICS_TDictionary} - {$DEFINE HAS_GENERICS_TList} - {$DEFINE HAS_GENERICS_TObjectList} - {$DEFINE HAS_GENERICS_TThreadList} - // TArray.Copy() was introduced in XE7 but was buggy. It was fixed in XE8: - // - // RSP-9763 TArray.Copy copies from destination to source for unmanaged types - // https://quality.embarcadero.com/browse/RSP-9763 - // - {$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE HAS_GENERICS_TArray_Copy} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -// TODO: Ansi data types were disabled on mobile platforms in XE3, but -// UTF8String and RawByteString were re-enabled in 10.1 Berlin! What else, -// if anything, was re-enabled to facilitate that? -// -// UPDATE: In 10.4 Sydney, AnsiChar and AnsiString were re-enabled on -// mobile platforms! NEXTGEN is no longer defined in the mobile compilers. -{$IFDEF NO_ANSI_TYPES} - {$UNDEF HAS_AnsiString} - {$UNDEF HAS_AnsiChar} - {$UNDEF HAS_PAnsiChar} - {$UNDEF HAS_PPAnsiChar} - {$UNDEF HAS_AnsiStrings_StrPLCopy} - {$UNDEF HAS_AnsiStrings_StrLen} -{$ENDIF} - -{$IFDEF WIN32} - {$DEFINE WIN32_OR_WIN64} -{$ENDIF} -{$IFDEF WIN64} - {$DEFINE WIN32_OR_WIN64} -{$ENDIF} - -{$IFDEF WIN32_OR_WIN64} - {$DEFINE USE_ZLIB_UNIT} - {$IFNDEF DCC_NEXTGEN} - {$DEFINE USE_OPENSSL} // !!! MOVED HERE BY EMBT - {$DEFINE USE_SSPI} - {$IFDEF STRING_IS_UNICODE} - {$DEFINE SSPI_UNICODE} - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF WINCE} - {$DEFINE USE_OPENSSL} - // RLebeau: not sure if the above Win32/64 defines also apply to WinCE, - // so keeping them separate for now... -{$ENDIF} - -// High-performance counters are not reliable on multi-core systems, and have -// been known to cause problems with TIdIOHandler.ReadLn() timeouts in Windows -// XP SP3, both 32-bit and 64-bit. Refer to these discussions for more info: -// -// http://www.virtualdub.org/blog/pivot/entry.php?id=106 -// http://blogs.msdn.com/oldnewthing/archive/2008/09/08/8931563.aspx -// -// Do not enable thus unless you know it will work correctly on your systems! -{$IFDEF WINDOWS} - {.$DEFINE USE_HI_PERF_COUNTER_FOR_TICKS} -{$ENDIF} - -{$IFDEF UNIX} - {$DEFINE USE_OPENSSL} - {$DEFINE USE_ZLIB_UNIT} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF MACOS} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF DARWIN} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF LINUX} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF IOS} - {$DEFINE HAS_getifaddrs} - {$DEFINE USE_OPENSSL} - - // Support for 64-bit ARM iOS Simulator was added in Delphi 11.2 - // TODO: how to detect iOS Simulator in FPC? Does it support 64-bit ARM? - {$IFDEF CPUARM} - {$IFNDEF IOSSIMULATOR} - // RLebeau: For iOS devices, OpenSSL cannot be used as an external library, - // it must be statically linked into the app. For the iOS simulator, this - // is not true. Users who want to use OpenSSL in iOS device apps will need - // to add the static OpenSSL library to the project and then include the - // IdSSLOpenSSLHeaders_static unit in their uses clause. It hooks up the - // statically linked functions for the IdSSLOpenSSLHeaders unit to use... - {$DEFINE STATICLOAD_OPENSSL} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{$IFDEF FREEBSD} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF ANDROID} - {$UNDEF HAS_getifaddrs} -{$ENDIF} - -{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} - {$DEFINE REQUIRES_PROPER_ALIGNMENT} -{$ENDIF} - -// -//iconv defines section. -{$DEFINE USE_ICONV_UNIT} -{$DEFINE USE_ICONV_ENC} -{$IFDEF UNIX} - {$DEFINE USE_ICONV} - {$IFDEF USE_BASEUNIX} - {$IFDEF FPC} - {$UNDEF USE_ICONV_UNIT} - {$ELSE} - {$UNDEF USE_ICONV_ENC} - {$ENDIF} - {$ENDIF} - {$IFDEF KYLIXCOMPAT} - //important!! Iconv functions are defined in the libc.pas Kylix compatible unit. - {$UNDEF USE_ICONV_ENC} - {$UNDEF USE_ICONV_UNIT} - {$ENDIF} -{$ENDIF} -{$IFDEF NETWARELIBC} - {$DEFINE USE_ICONV} - //important!!! iconv functions are defined in the libc.pas Novell Netware header. - //Do not define USE_ICONV_UNIT - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} -{$ENDIF} - -{$UNDEF USE_SAFELOADLIBRARY} -{$IFDEF WINDOWS} - {$UNDEF USE_ICONV_ENC} - {$DEFINE USE_SAFELOADLIBRARY} -{$ENDIF} -// Use here for all *nix systems that you do not want to use iconv library -{$IFDEF FPC} - {$IFDEF ANDROID} - {$UNDEF USE_ICONV} - {$DEFINE USE_LCONVENC} - {$ENDIF} -{$ENDIF} - -{$UNDEF USE_INVALIDATE_MOD_CACHE} -{$UNDEF USE_SAFELOADLIBRARY} -//This must come after the iconv defines because this compiler targets a Unix-like -//operating system. One key difference is that it does have a TEncoding class. -//If this comes before the ICONV defines, it creates problems. -//This also must go before the THandle size calculations. -{$IFDEF VCL_CROSS_COMPILE} - {$IFDEF POSIX} - {$IFNDEF LINUX} - {$DEFINE BSD} - {$ENDIF} - {$DEFINE USE_SAFELOADLIBRARY} - {$DEFINE USE_INVALIDATE_MOD_CACHE} - {$ENDIF} - //important!!! iconv functions are defined in the libc.pas Novell Netware header. - //Do not define USE_ICONVUNIT - {$UNDEF USE_ICONV} - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} - {$DEFINE INT_THREAD_PRIORITY} -{$ENDIF} - -{$IFNDEF USE_ICONV} - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} -{$ENDIF} - -//IMPORTANT!!!! -// -//Do not remove this!!! This is to work around a conflict. In DCC, MACOS -//will mean OS X. In FreePascal, the DEFINE MACOS means MacIntosh System OS Classic. -{$IFDEF DCC} - // DCC defines MACOS for both iOS and OS X platforms, need to differentiate - {$IFDEF MACOS} - {$IFNDEF IOS} - {$DEFINE OSX} - {$DEFINE DARWIN} - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF FPC} - // FPC defines DARWIN for both OSX and iOS, need to differentiate - {$IFDEF DARWIN} - {$IFNDEF IOS} - {$DEFINE OSX} - {$ENDIF} - {$ENDIF} - {$IFDEF MACOS} - {$DEFINE MACOS_CLASSIC} - {$ENDIF} -{$ENDIF} - -{ -BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit -word to an 8 bit byte and an 8 bit byte field named sa_len was added. -} -//Place this only after DARWIN has been defined for Delphi MACOS -{$IFDEF FREEBSD} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF DARWIN} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF MORPHOS} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} - -// Do NOT remove these IFDEF's. They are here because InterlockedExchange -// only handles 32bit values. Some Operating Systems may have 64bit -// THandles. This is not always tied to the platform architecture. - -{$IFDEF AMIGA} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF ATARI} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF BEOS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF BSD} - //I think BSD might handle FreeBSD, NetBSD, OpenBSD, and Darwin - {$IFDEF IOS} - {$IFDEF CPUARM64} - {$DEFINE CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$IFDEF CPUARM32} - {$DEFINE CPU32} - {$ENDIF} - {$DEFINE THANDLE_32} - {$ENDIF} - {$ENDIF} - {$IFDEF OSX} - {$IFDEF FPC} - {$DEFINE THANDLE_32} - {$ELSE} - {$DEFINE THANDLE_CPUBITS} // !!! ADDED OSX BY EMBT - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF EMBEDDED} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF EMX} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF GBA} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF GO32} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF LINUX} - {$IFDEF LINUX64} - {$DEFINE CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$IFDEF LINUX32} - {$DEFINE CPU32} - {$ENDIF} - {$DEFINE THANDLE_32} - {$ENDIF} -{$ENDIF} -{$IFDEF MACOS_CLASSIC} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF MORPHOS} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF NATIVENT} //Native NT for kernel level drivers - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF NDS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF NETWARE} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF NETWARELIBC} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF OS2} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF PALMOS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF SOLARIS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF SYMBIAN} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WII} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WATCOM} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WINDOWS} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} - -// end platform specific stuff for THandle size - -{$IFDEF THANDLE_CPUBITS} - {$IFDEF CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$DEFINE THANDLE_32} - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - {$DEFINE DOTNET_OR_ICONV} -{$ENDIF} -{$IFDEF USE_ICONV} - {$DEFINE DOTNET_OR_ICONV} -{$ENDIF} - -{$UNDEF STREAM_SIZE_64} -{$IFDEF FPC} - {$DEFINE STREAM_SIZE_64} -{$ELSE} - {$IFDEF VCL_6_OR_ABOVE} - {$DEFINE STREAM_SIZE_64} - {$ENDIF} -{$ENDIF} - -{$IFNDEF FREE_ON_FINAL} - {$IFNDEF DOTNET} - {$IFDEF HAS_System_RegisterExpectedMemoryLeak} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_FASTMM4} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_MADEXCEPT} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_LEAKCHECK} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{ -We must determine what the SocketType parameter is for the Socket function. -In DotNET, it's SocketType. In Kylix and the libc.pas Kylix-compatibility -library, it's a __socket_type. In BaseUnix, it's a C-type Integer. In Windows, -it's a LongInt. - -} -{$UNDEF SOCKETTYPE_IS_SOCKETTYPE} -{$UNDEF SOCKETTYPE_IS_CINT} -{$UNDEF SOCKETTYPE_IS___SOCKETTYPE} -{$UNDEF SOCKETTYPE_IS_LONGINT} -{$UNDEF SOCKETTYPE_IS_NUMERIC} -{$UNDEF SOCKET_LEN_IS_socklen_t} -{$IFDEF DOTNET} - {$DEFINE SOCKETTYPE_IS_SOCKETTYPE} -{$ENDIF} -{$IFDEF USE_BASEUNIX} - {$DEFINE SOCKETTYPE_IS_CINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF KYLIXCOMPAT} - {$DEFINE SOCKETTYPE_IS___SOCKETTYPE} -{$ENDIF} -{$IFDEF USE_VCL_POSIX} - {$DEFINE SOCKETTYPE_IS_NUMERIC} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKET_LEN_IS_socklen_t} -{$ENDIF} -{$IFDEF WINDOWS} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF OS2} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF NETWARE} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} - -{Take advantage of some TCP features specific to some stacks. -They work somewhat similarly but there's a key difference. -In Linux, TCP_CORK is turned on to send fixed packet sizes and -when turned-off (uncorked), any remaining data is sent. With -TCP_NOPUSH, this might not happen and remaining data is only sent -before disconnect. TCP_KEEPIDLE and TCP_KEEPINTVL so the IFDEF LINUX and IFDEF -SOLARIS instead of IFDEF UNIX is not an error, it's deliberate.} -{$UNDEF HAS_TCP_NOPUSH} -{$UNDEF HAS_TCP_CORK} -{$UNDEF HAS_TCP_KEEPIDLE} -{$UNDEF HAS_TCP_KEEPINTVL} -{$UNDEF HAS_SOCKET_NOSIGPIPE} -{$IFDEF BSD} - {$DEFINE HAS_TCP_NOPUSH} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE HAS_TCP_NOPUSH} -{$ENDIF} -{$IFDEF LINUX} - {$DEFINE HAS_TCP_CORK} - {$DEFINE HAS_TCP_KEEPIDLE} - {$DEFINE HAS_TCP_KEEPINTVL} -{$ENDIF} -{$IFDEF SOLARIS} - {$DEFINE HAS_TCP_CORK} -{$ENDIF} -{$IFDEF NETBSD} - {$DEFINE HAS_TCP_CORK} - {$DEFINE HAS_TCP_KEEPIDLE} - {$DEFINE HAS_TCP_KEEPINTVL} -{$ENDIF} -{$IFDEF USE_VCL_POSIX} - // TODO: which platforms actually have SO_NOSIGPIPE available? - {$DEFINE HAS_SOCKET_NOSIGPIPE} - {$IFDEF ANDROID} - {$UNDEF HAS_SOCKET_NOSIGPIPE} - {$ENDIF} - {$IFDEF LINUX} - {$UNDEF HAS_SOCKET_NOSIGPIPE} - {$ENDIF} -{$ENDIF} -{end Unix OS specific stuff} -{$IFDEF DEBUG} - {$UNDEF USE_INLINE} -{$ENDIF} - -// RLebeau 5/24/2015: In C++Builder 2006 and 2007, UInt64 is emitted as -// signed __int64 in HPP files instead of as unsigned __int64. This causes -// conflicts in overloaded routines that have (U)Int64 parameters. This -// was fixed in C++Builder 2009. For compilers that do not have a native -// UInt64 type, or for C++Builder 2006/2007, let's define a record type -// that can hold UInt64 values... -{$IFDEF HAS_UInt64} - {$IFDEF BROKEN_UINT64_HPPEMIT} - {$DEFINE TIdUInt64_HAS_QuadPart} - {$ENDIF} -{$ELSE} - {$IFNDEF HAS_QWord} - {$DEFINE TIdUInt64_HAS_QuadPart} - {$ENDIF} -{$ENDIF} - -// RLebeau 9/5/2013: it would take a lot of work to re-write Indy to support -// both 0-based and 1-based string indexing, so we'll just turn off 0-based -// indexing for now... -{$IFDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} - {$ZEROBASEDSTRINGS OFF} -{$ENDIF} +{$IFDEF CONDITIONALEXPRESSIONS} + // Must be at the top... + {$IF CompilerVersion >= 24.0} + {$LEGACYIFEND ON} + {$IFEND} +{$ENDIF} + +// General + +// Make this $DEFINE to use the 16 color icons required by Borland +// or DEFINE to use the 256 color Indy versions +{.$DEFINE Borland} + +// S.G. 4/9/2002: IPv4/IPv6 general switch (for defaults only) +{$DEFINE IdIPv4} // use IPv4 by default +{.$IFDEF IdIPv6} // use IPv6 by default + +{$DEFINE INDY100} +{$DEFINE 10_7_0} //so developers can IFDEF for this product version +{$DEFINE 10_7_0_0} //so developers can IFDEF for this specific version + +// When generating C++Builder output files, certain workarounds to compiler +// problems need to be enabled! When invoking DCC on the command-line, use +// the -DBCB parameter. When invoking MSBUILD, include the DCC_Define="BCB" +// attribute in the /p parameter. +{$IFDEF BCB} + {$DEFINE CBUILDER} +{$ELSE} + {$DEFINE DELPHI} +{$ENDIF} + +{$UNDEF USE_OPENSSL} +{$UNDEF STATICLOAD_OPENSSL} + +{$UNDEF USE_ZLIB_UNIT} +{$UNDEF USE_SSPI} + +// $DEFINE the following if the global objects in the IdStack and IdThread +// units should be freed on finalization +{.$DEFINE FREE_ON_FINAL} +{$UNDEF FREE_ON_FINAL} + +// Make sure the following is $DEFINE'd only for suitable environments +// as specified further below. This works in conjunction with the +// FREE_ON_FINAL define above. +{$UNDEF REGISTER_EXPECTED_MEMORY_LEAK} +{$UNDEF HAS_System_RegisterExpectedMemoryLeak} + +// FastMM is natively available in BDS 2006 and higher. $DEFINE the +// following if FastMM has been installed manually in earlier versions +{.$DEFINE USE_FASTMM4} +{$UNDEF USE_FASTMM4} + +// $DEFINE the following if MadExcept has been installed manually in +// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced +// in BDS 2006) +{.$DEFINE USE_MADEXCEPT} +{$UNDEF USE_MADEXCEPT} + +// $DEFINE the following if LeakCheck has been installed manually in +// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced +// in BDS 2006) +{.$DEFINE USE_LEAKCHECK} +{$UNDEF USE_LEAKCHECK} + +// Make sure the following are $DEFINE'd only for Delphi/C++Builder 2009 onwards +// as specified further below. The VCL is fully Unicode, where the 'String' +// type maps to System.UnicodeString, not System.AnsiString anymore +{$UNDEF STRING_IS_UNICODE} +{$UNDEF STRING_IS_ANSI} +{$UNDEF STRING_UNICODE_MISMATCH} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. Delphi/C++Builder Mobile/NextGen compilers +// do not support Ansi data types anymore, and is moving away from raw +// pointers as well. +// +// UPDATE: in Delphi/C++Builder 10.4, all Ansi types are supported again on +// all platforms, including the mobile compilers. +{$DEFINE HAS_AnsiString} +{$DEFINE HAS_AnsiChar} +{$DEFINE HAS_PAnsiChar} +{$UNDEF HAS_PPAnsiChar} +{$UNDEF NO_ANSI_TYPES} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. Delphi/C++Builder Mobile/NextGen compilers +// use ARC for TObject life time management. +// +// UPDATE: ARC for TObject lifetime management has been removed in +// Delphi/C++Builder 10.4 mobile compilers. All platforms now use a single +// unified memory management model! +{$UNDEF USE_MARSHALLED_PTRS} +{$UNDEF HAS_MarshaledAString} +{$UNDEF USE_OBJECT_ARC} + +// Make sure the following is $DEFINE'd only for suitable environments +// as specified further below. +{$UNDEF STRING_IS_IMMUTABLE} +{$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. +{$UNDEF HAS_TEncoding} +{$UNDEF HAS_TEncoding_GetEncoding_ByEncodingName} +{$UNDEF HAS_Exception_RaiseOuterException} +{$UNDEF HAS_System_ReturnAddress} +{$UNDEF HAS_TCharacter} +{$UNDEF HAS_TInterlocked} +{$UNDEF HAS_TNetEncoding} + +// Make sure that this is defined only for environments where we are using +// the iconv library to charactor conversions. +{.$UNDEF USE_ICONV} +{.$UNDEF USE_LCONVENC} + +//Define for Delphi cross-compiler targetting Posix +{$UNDEF USE_VCL_POSIX} +{$UNDEF HAS_ComponentPlatformsAttribute} +{$UNDEF HAS_ComponentPlatformsAttribute_Win32} +{$UNDEF HAS_ComponentPlatformsAttribute_Win64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSX32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator32} +{$UNDEF HAS_ComponentPlatformsAttribute_Android} +{$UNDEF HAS_ComponentPlatformsAttribute_Android32Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device32} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux64} +{$UNDEF HAS_ComponentPlatformsAttribute_WinNX32} +{$UNDEF HAS_ComponentPlatformsAttribute_WinIoT32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device64} +{$UNDEF HAS_ComponentPlatformsAttribute_WinARM} +{$UNDEF HAS_ComponentPlatformsAttribute_WinARM32} +{$UNDEF HAS_ComponentPlatformsAttribute_OSX64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux32Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux64Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Android64} +{$UNDEF HAS_ComponentPlatformsAttribute_Android64Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator64} +{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm32} +{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSXArm64} +{$UNDEF HAS_ComponentPlatformsAttribute_AllPlatforms} +{$UNDEF HAS_DIRECTIVE_WARN_DEFAULT} + +// Define for Delphi to auto-generate platform-appropriate '#pragma link' statements in HPP files +{$UNDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT} + +// detect compiler versions + +{$IFNDEF FPC} + + // TODO: to detect features in Delphi/C++Builder v6 and later, use CompilerVersion + // and RTLVersion constants instead of VERXXX defines. We still support v5, which + // does not have such constants. + + // Delphi 4 + {$IFDEF VER120} + {$DEFINE DCC} + {$DEFINE VCL_40} + {$DEFINE DELPHI_4} + {$ENDIF} + + // C++Builder 4 + {$IFDEF VER125} + {$DEFINE DCC} + {$DEFINE VCL_40} + {$DEFINE CBUILDER_4} + {$ENDIF} + + // Delphi & C++Builder 5 + {$IFDEF VER130} + {$DEFINE DCC} + {$DEFINE VCL_50} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_5} + {$ELSE} + {$DEFINE DELPHI_5} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 6 + {$IFDEF VER140} + {$DEFINE DCC} + {$DEFINE VCL_60} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_6} + {$ELSE} + {$DEFINE DELPHI_6} + {$ENDIF} + {$ENDIF} + + //Delphi 7 + {$IFDEF VER150} + {$DEFINE DCC} + {$DEFINE VCL_70} + {$DEFINE DELPHI_7} // there was no C++ Builder 7 + {$ENDIF} + + //Delphi 8 + {$IFDEF VER160} + {$DEFINE DCC} + {$DEFINE VCL_80} + {$DEFINE DELPHI_8} // there was no C++ Builder 8 + {$ENDIF} + + //Delphi 2005 + {$IFDEF VER170} + {$DEFINE DCC} + {$DEFINE VCL_2005} + {$DEFINE DELPHI_2005} // there was no C++Builder 2005 + {$ENDIF} + + // NOTE: CodeGear decided to make Highlander be a non-breaking release + // (no interface changes, thus fully backwards compatible without any + // end user code changes), so VER180 applies to both BDS 2006 and + // Highlander prior to the release of RAD Studio 2007. Use VER185 to + // identify Highlanger specifically. + + //Delphi & C++Builder 2006 + //Delphi & C++Builder 2007 (Highlander) + {$IFDEF VER180} + {$DEFINE DCC} + {$DEFINE VCL_2006} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2006} + {$ELSE} + {$DEFINE DELPHI_2006} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2007 (Highlander) + {$IFDEF VER185} + {$DEFINE DCC} + {$UNDEF VCL_2006} + {$DEFINE VCL_2007} + {$IFDEF CBUILDER} + {$UNDEF CBUILDER_2006} + {$DEFINE CBUILDER_2007} + {$ELSE} + {$UNDEF DELPHI_2006} + {$DEFINE DELPHI_2007} + {$ENDIF} + {$ENDIF} + + // BDS 2007 NET personality uses VER190 instead of 185. + //Delphi .NET 2007 + {$IFDEF VER190} + {$DEFINE DCC} + {$IFDEF CIL} + //Delphi 2007 + {$DEFINE VCL_2007} + {$DEFINE DELPHI_2007} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2009 (Tiburon) + {$IFDEF VER200} + {$DEFINE DCC} + {$DEFINE VCL_2009} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2009} + {$ELSE} + {$DEFINE DELPHI_2009} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2010 (Weaver) + {$IFDEF VER210} + {$DEFINE DCC} + {$DEFINE VCL_2010} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2010} + {$ELSE} + {$DEFINE DELPHI_2010} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder XE (Fulcrum) + {$IFDEF VER220} + //REMOVE DCC DEFINE after the next Fulcrum beta. + //It will be defined there. + {$IFNDEF DCC} + {$DEFINE DCC} + {$ENDIF} + {$DEFINE VCL_XE} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE} + {$ELSE} + {$DEFINE DELPHI_XE} + {$ENDIF} + {$ENDIF} + + // DCC is now defined by the Delphi compiler starting in XE2 + + //Delphi & CBuilder XE2 (Pulsar) + {$IFDEF VER230} + {$DEFINE VCL_XE2} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE2} + {$ELSE} + {$DEFINE DELPHI_XE2} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE3 (Waterdragon) + //Delphi & CBuilder XE3.5 (Quintessence - early betas only) + {$IFDEF VER240} + {$DEFINE VCL_XE3} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE3} + {$ELSE} + {$DEFINE DELPHI_XE3} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE4 (Quintessence) + {$IFDEF VER250} + {$UNDEF VCL_XE3} + {$DEFINE VCL_XE4} + {$IFDEF CBUILDER} + {$UNDEF CBUILDER_XE3} + {$DEFINE CBUILDER_XE4} + {$ELSE} + {$UNDEF DELPHI_XE3} + {$DEFINE DELPHI_XE4} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE5 (Zephyr) + {$IFDEF VER260} + {$DEFINE VCL_XE5} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE5} + {$ELSE} + {$DEFINE DELPHI_XE5} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder AppMethod + //AppMethod is just XE5 for mobile only, VCL is removed + {$IFDEF VER265} + {$DEFINE VCL_XE5} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE5} + {$ELSE} + {$DEFINE DELPHI_XE5} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE6 (Proteus) + {$IFDEF VER270} + {$DEFINE VCL_XE6} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE6} + {$ELSE} + {$DEFINE DELPHI_XE6} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE7 (Carpathia) + {$IFDEF VER280} + {$DEFINE VCL_XE7} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE7} + {$ELSE} + {$DEFINE DELPHI_XE7} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE8 (Elbrus) + {$IFDEF VER290} + {$DEFINE VCL_XE8} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE8} + {$ELSE} + {$DEFINE DELPHI_XE8} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.0 Seattle (Aitana) + {$IFDEF VER300} + {$DEFINE VCL_10_0} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_VCL_10_0} + {$ELSE} + {$DEFINE DELPHI_VCL_10_0} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.1 Berlin (BigBen) + {$IFDEF VER310} + {$DEFINE VCL_10_1} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_1} + {$ELSE} + {$DEFINE DELPHI_10_1} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.2 Tokyo (Godzilla) + {$IFDEF VER320} + {$DEFINE VCL_10_2} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_2} + {$ELSE} + {$DEFINE DELPHI_10_2} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.3 Rio (Carnival) + {$IFDEF VER330} + {$DEFINE VCL_10_3} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_3} + {$ELSE} + {$DEFINE DELPHI_10_3} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.4 Sydney (Denali) + {$IFDEF VER340} + {$DEFINE VCL_10_4} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_4} + {$ELSE} + {$DEFINE DELPHI_10_4} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 11.0 Alexandria (Olympus) + {$IFDEF VER350} + {$DEFINE VCL_11} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_11} + {$ELSE} + {$DEFINE DELPHI_11} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 12.0 Athens (Yukon) + {$IFDEF VER360} + {$DEFINE VCL_12} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_12} + {$ELSE} + {$DEFINE DELPHI_12} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 13.0+ (?) + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF CompilerVersion >= 37} + {$MESSAGE WARN 'Unknown compiler version detected! Assuming >= 13.x '} + {$DEFINE VCL_UNKNOWN_VERSION} + {$DEFINE VCL_13} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_13} + {$ELSE} + {$DEFINE DELPHI_13} + {$ENDIF} + {$IFEND} + {$ENDIF} + + // Kylix + // + //Important: Don't use CompilerVersion here as IF's are evaluated before + //IFDEF's and Kylix 1 does not have CompilerVersion defined at all. + {$IFDEF LINUX} + {$DEFINE UNIX} + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF (RTLVersion >= 14.0) and (RTLVersion <= 14.5) } + {$DEFINE KYLIX} + {$IF RTLVersion = 14.5} + {$DEFINE KYLIX_3} + {$ELSEIF RTLVersion >= 14.2} + {$DEFINE KYLIX_2} + {$ELSE} + {$DEFINE KYLIX_1} + {$IFEND} + {$IFEND} + {$ENDIF} + {$ENDIF} + +{$ENDIF} + +// Delphi.NET +// Covers D8+ +{$IFDEF CIL} + // Platform specific conditional. Used for platform specific code. + {$DEFINE DOTNET} + {$DEFINE STRING_IS_UNICODE} + {$DEFINE STRING_IS_IMMUTABLE} + {.$DEFINE HAS_Int8} + {.$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_UInt64} +{$ENDIF} + +{$IFDEF KYLIX} + {$DEFINE VCL_60} + {$DEFINE INT_THREAD_PRIORITY} + {$DEFINE CPUI386} + {$UNDEF USE_BASEUNIX} + + {$IFDEF KYLIX_3} + {$DEFINE KYLIX_3_OR_ABOVE} + {$ENDIF} + + {$IFDEF KYLIX_3_OR_ABOVE} + {$DEFINE KYLIX_2_OR_ABOVE} + {$ELSE} + {$IFDEF KYLIX_2} + {$DEFINE KYLIX_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF KYLIX_2_OR_ABOVE} + {$DEFINE KYLIX_1_OR_ABOVE} + {$ELSE} + {$IFDEF KYLIX_1} + {$DEFINE KYLIX_1_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFNDEF KYLIX_3_OR_ABOVE} + {$DEFINE KYLIXCOMPAT} + {$ENDIF} + + {$IFDEF KYLIX_2_OR_ABOVE} + {$DEFINE USE_ZLIB_UNIT} + {$ENDIF} +{$ENDIF} + +// FPC (2+) + +{$IFDEF FPC} + // TODO: In FreePascal 4.2.0+, a Delphi-like UnicodeString type is supported. + // However, String/(P)Char do not map to UnicodeString/(P)WideChar unless + // either {$MODE DelphiUnicode} or {$MODESWITCH UnicodeStrings} is used. + // We should consider enabling one of them so Indy uses the same Unicode logic + // in Delphi 2009+ and FreePascal 4.2.0+ and reduces IFDEFs (in particular, + // STRING_UNICODE_MISMATCH, see further below). However, FreePascal's RTL + // is largely not UnicodeString-enabled yet. Maybe we should enable + // {$MODE DelphiUnicode} anyway, and then deal with any RTL function issues + // on an as-needed basis... + {$MODE Delphi} + //note that we may need further defines for widget types depending on + //what we do and what platforms we support in FPC. + //I'll let Marco think about that one. + {$IFDEF UNIX} + {$DEFINE USE_BASEUNIX} + {$IFDEF LINUX} + //In Linux for I386, you can choose between a Kylix-libc API or + //the standard RTL Unix API. Just pass -dKYLIXCOMPAT to the FPC compiler. + //I will see what I can do about the Makefile. + {$IFDEF KYLIXCOMPAT} + {$IFDEF CPUI386} + {$UNDEF USE_BASEUNIX} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$IFDEF USE_BASEUNIX} + {$UNDEF KYLIXCOMPAT} + {$ENDIF} + {$ENDIF} + + // FPC_FULLVERSION was added in FPC 2.2.4 + // Have to use Defined() or else Delphi compiler chokes, since it + // evaluates $IF statements before $IFDEF statements... + + {$MACRO ON} // must be on in order to use versioning macros + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30101)} + {$DEFINE FPC_3_1_1_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30000)} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20701)} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20604)} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20602)} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20600)} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20404)} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20402)} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20400)} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20204)} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20202)} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20105)} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$IFEND} + + // just in case + {$IFDEF FPC_3_1_1} + {$DEFINE FPC_3_1_1_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_3_0_0} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_7_1} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_4} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_2} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_0} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_4} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_2} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_0} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_2_4} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_2_2} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_1_5} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ENDIF} + + {$IFDEF FPC_3_1_1_OR_ABOVE} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_3_0_0} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_3_0_0_OR_ABOVE} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_7_1} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_7_1_OR_ABOVE} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_4} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_4_OR_ABOVE} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_2} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_0} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_0_OR_ABOVE} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_4} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_4_OR_ABOVE} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_2} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_2_OR_ABOVE} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_0} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_0_OR_ABOVE} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_2_4} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_4_OR_ABOVE} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_2_2} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_2_OR_ABOVE} + {$DEFINE FPC_2_2_0_OR_ABOVE} + {$ELSE} + {$IFDEF VER2_2} + {$DEFINE FPC_2_2_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_0_OR_ABOVE} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_1_5} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {.$IFDEF FPC_2_7_1_OR_ABOVE} + // support for RawByteString and UnicodeString + {.$MODE DelphiUnicode} + {.$MODESWITCH UnicodeStrings} + {.$CODEPAGE UTF8} // needed for Unicode string literals to work properly + {.$DEFINE VCL_2009} + {.$DEFINE DELPHI_2009} + {.$ELSE} + {$DEFINE VCL_70} + {$DEFINE DELPHI_7} + {.$ENDIF} +{$ENDIF} + +// end FPC + +{$IFDEF VCL_13} + {$DEFINE VCL_13_OR_ABOVE} +{$ENDIF} + +{$IFDEF VCL_13_OR_ABOVE} + {$DEFINE VCL_12_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_12} + {$DEFINE VCL_12_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_12_OR_ABOVE} + {$DEFINE VCL_11_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_11} + {$DEFINE VCL_11_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_11_OR_ABOVE} + {$DEFINE VCL_10_4_OR_ABOVE} + {$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_4} + {$DEFINE VCL_10_4_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_4_OR_ABOVE} + {$DEFINE VCL_10_3_OR_ABOVE} + {$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_3} + {$DEFINE VCL_10_3_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_OR_ABOVE} + {$DEFINE VCL_10_2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_2} + {$DEFINE VCL_10_2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_2_OR_ABOVE} + {$DEFINE VCL_10_1_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_1} + {$DEFINE VCL_10_1_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_1_OR_ABOVE} + {$DEFINE VCL_10_0_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_0} + {$DEFINE VCL_10_0_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_0_OR_ABOVE} + {$DEFINE VCL_XE8_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE8} + {$DEFINE VCL_XE8_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE VCL_XE7_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE7} + {$DEFINE VCL_XE7_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE7_OR_ABOVE} + {$DEFINE VCL_XE6_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE6} + {$DEFINE VCL_XE6_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE6_OR_ABOVE} + {$DEFINE VCL_XE5_OR_ABOVE} + {$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE5} + {$DEFINE VCL_XE5_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE5_OR_ABOVE} + {$DEFINE VCL_XE4_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE4} + {$DEFINE VCL_XE4_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE4_OR_ABOVE} + {$DEFINE VCL_XE3_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE3} + {$DEFINE VCL_XE3_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE3_OR_ABOVE} + {$DEFINE VCL_XE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE2} + {$DEFINE VCL_XE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE2_OR_ABOVE} + {$DEFINE VCL_XE_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE} + {$DEFINE VCL_XE_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE_OR_ABOVE} + {$DEFINE VCL_2010_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2010} + {$DEFINE VCL_2010_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2010_OR_ABOVE} + {$DEFINE VCL_2009_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2009} + {$DEFINE VCL_2009_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2009_OR_ABOVE} + {$DEFINE VCL_2007_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2007} + {$DEFINE VCL_2007_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2007_OR_ABOVE} + {$DEFINE VCL_2006_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2006} + {$DEFINE VCL_2006_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2006_OR_ABOVE} + {$DEFINE VCL_2005_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2005} + {$DEFINE VCL_2005_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2005_OR_ABOVE} + {$DEFINE VCL_8_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_80} + {$DEFINE VCL_8_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_8_OR_ABOVE} + {$DEFINE VCL_7_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_70} + {$DEFINE VCL_7_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_7_OR_ABOVE} + {$DEFINE VCL_6_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_60} + {$DEFINE VCL_6_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_6_OR_ABOVE} + {$DEFINE VCL_5_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_50} + {$DEFINE VCL_5_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_5_OR_ABOVE} + {$DEFINE VCL_4_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_40} + {$DEFINE VCL_4_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +// Normalize Delphi compiler defines to match FPC for consistency: +// +// CPU32 - any 32-bit CPU +// CPU64 - any 64-bit CPU +// WINDOWS - any Windows platform (32-bit, 64-bit, CE) +// WIN32 - Windows 32-bit +// WIN64 - Windows 64-bit +// WINCE - Windows CE +// +// Consult the "Free Pascal Programmer's Guide", Appendix G for the complete +// list of defines that are used. Do not work on this unless you understand +// what the FreePascal developers are doing. Not only do you have to +// descriminate with operating systems, but also with chip architectures +// are well. +// +// DCC Pulsar+ define the following values: +// ASSEMBLER +// DCC +// CONDITIONALEXPRESSIONS +// NATIVECODE +// UNICODE +// MACOS +// MACOS32 +// MACOS64 +// MSWINDOWS +// WIN32 +// WIN64 +// LINUX +// POSIX +// POSIX32 +// CPU386 +// CPUX86 +// CPUX64 +// +// Kylix defines the following values: +// LINUX +// (others??) +// + +{$IFNDEF FPC} + // TODO: We need to use ENDIAN_BIG for big endian chip architectures, + // such as 680x0, PowerPC, Sparc, and MIPS, once DCC supports them, + // provided it does not already define its own ENDIAN values by then... + {$DEFINE ENDIAN_LITTLE} + {$IFNDEF VCL_6_OR_ABOVE} + {$DEFINE MSWINDOWS} + {$ENDIF} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} + // TODO: map Pulsar's non-Windows platform defines... + {$IFDEF VCL_XE2_OR_ABOVE} + {$IFDEF VCL_XE8_OR_ABOVE} + {$IFDEF CPU32BITS} + //any 32-bit CPU + {$DEFINE CPU32} + {$ENDIF} + {$IFDEF CPU64BITS} + {$DEFINE CPU64} + {$ENDIF} + {$ELSE} + {$IFDEF CPU386} + //any 32-bit CPU + {$DEFINE CPU32} + //Intel 386 compatible chip architecture + {$DEFINE CPUI386} + {$ENDIF} + {$IFDEF CPUX86} + {$DEFINE CPU32} + {$ENDIF} + {$IFDEF CPUX64} + //any 64-bit CPU + {$DEFINE CPU64} + //AMD64 compatible chip architecture + {$DEFINE CPUX86_64} //historical name for AMD64 + {$DEFINE CPUAMD64} + {$ENDIF} + {$ENDIF} + {$ELSE} + {$IFNDEF DOTNET} + {$IFNDEF KYLIX} + {$DEFINE I386} + {$ENDIF} + {$ENDIF} + {$DEFINE CPU32} + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + //differences in DotNET Framework versions. + {$IFDEF VCL_2007_OR_ABOVE} + {$DEFINE DOTNET_2} + {$DEFINE DOTNET_2_OR_ABOVE} + {$ELSE} + {$DEFINE DOTNET_1_1} + {$ENDIF} + {$DEFINE DOTNET_1_1_OR_ABOVE} + // Extra include used in D7 for testing. Remove later when all comps are + // ported. Used to selectively exclude non ported parts. Allowed in places + // IFDEFs are otherwise not permitted. + {$DEFINE DOTNET_EXCLUDE} +{$ENDIF} + +// Check for available features + +{$IFDEF CBUILDER} + // When generating a C++ HPP file, if a class has no explicit constructor + // defined and contains compiler-managed members (xxxString, TDateTime, + // Variant, DelphiInterface, etc), the HPP will contain a forwarding + // inline constructor that implicitly initializes those managed members, + // which will overwrite any non-default initializations performed inside + // of InitComponent() overrides! In this situation, the workaround is to + // define an explicit constructor that calls the base class constructor + // manually, allowing those managed members to be initialized by the + // compiler before InitComponent() overrides then re-assign them. + {$DEFINE WORKAROUND_INLINE_CONSTRUCTORS} +{$ENDIF} + +{$IFDEF VCL_5_OR_ABOVE} + {$IFNDEF FPC} + {$IFNDEF KYLIX} + {$DEFINE HAS_RemoveFreeNotification} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_GetObjectProp} + {$DEFINE HAS_TObjectList} + {$DEFINE HAS_StrToInt64Def} +{$ENDIF} + +{$IFDEF VCL_6_OR_ABOVE} + {$DEFINE HAS_PCardinal} + {$DEFINE HAS_PByte} + {$DEFINE HAS_PWord} + {$DEFINE HAS_PPointer} + {$DEFINE HAS_TList_Assign} + {$DEFINE HAS_sLineBreak} + {$DEFINE HAS_RaiseLastOSError} + {$DEFINE HAS_SysUtils_IncludeExcludeTrailingPathDelimiter} + {$DEFINE HAS_SysUtils_DirectoryExists} + {$DEFINE HAS_UNIT_DateUtils} + {$DEFINE HAS_UNIT_StrUtils} + {$DEFINE HAS_UNIT_Types} + {$DEFINE HAS_TryStrToInt} + {$DEFINE HAS_TryStrToInt64} + {$DEFINE HAS_TryEncodeDate} + {$DEFINE HAS_TryEncodeTime} + {$DEFINE HAS_ENUM_ELEMENT_VALUES} + {$IFNDEF FPC} + {$DEFINE HAS_IInterface} + {$DEFINE HAS_TSelectionEditor} + {$DEFINE HAS_TStringList_CaseSensitive} + {$DEFINE HAS_AcquireExceptionObject} + {$IFNDEF KYLIX} + {$DEFINE HAS_DEPRECATED} + {$DEFINE HAS_SYMBOL_PLATFORM} + {$DEFINE HAS_UNIT_PLATFORM} + {$IFNDEF VCL_8_OR_ABOVE} + // Delphi 6 and 7 have an annoying bug that if a class method is declared as + // deprecated, the compiler will emit a "symbol is deprecated" warning + // on the method's implementation! So we will have to wrap implementations + // of deprecated methods with {$WARN SYMBOL_DEPRECATED OFF} directives + // to disable that warning. + {$DEFINE DEPRECATED_IMPL_BUG} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$IFNDEF DOTNET} + //Widget defines are omitted in .NET + {$DEFINE VCL_60_PLUS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_7_OR_ABOVE} + {$IFNDEF FPC} + {$DEFINE HAS_UInt64} // Note: it was just an alias for Int64 until D2006! + {$DEFINE HAS_NAMED_THREADS} + {$DEFINE HAS_TStrings_NameValueSeparator} + {$DEFINE HAS_TStrings_ValueFromIndex} + // Note: there is a ZLib unit available, but it doesn't have everything + // that is available in the System.ZLib unit in Delphi XE2+, so we are + // not going to use this ZLib unit yet... + {.$DEFINE HAS_UNIT_ZLib} + {$ENDIF} + {$DEFINE HAS_TFormatSettings} + {$DEFINE HAS_PosEx} + {$IFNDEF VCL_70} + // not implemented in D7 + {$DEFINE HAS_STATIC_TThread_Queue} + {$ENDIF} + {$IFNDEF CIL} + {$IFNDEF VCL_80} + // not implemented in D8 or .NET + {$DEFINE HAS_STATIC_TThread_Synchronize} + {$ENDIF} + {$ENDIF} +{$ELSE} + {$IFDEF CBUILDER_6} + {$DEFINE HAS_NAMED_THREADS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2005_OR_ABOVE} + {$IFDEF DCC} + // class helpers were first introduced in D2005, but were buggy and not + // officially supported until D2006... + {.$DEFINE HAS_CLASS_HELPER} + {$ENDIF} +{$ELSE} + {$IFDEF DCC} + // InterlockedCompareExchange() was declared in the Windows unit using Pointer + // parameters until Delphi 2005, when it was switched to Longint parameters + // instead to match the actual Win32 API declaration. + {$DEFINE HAS_InterlockedCompareExchange_Pointers} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2006_OR_ABOVE} + {$DEFINE USE_INLINE} + {$DEFINE HAS_2PARAM_FileAge} + {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? + {$DEFINE HAS_CLASS_HELPER} + {$IFDEF WINDOWS} + // System.RegisterExpectedMemoryLeak() is only available on Windows at this time + {$DEFINE HAS_System_RegisterExpectedMemoryLeak} + {$ENDIF} + // In C++Builder 2006 and 2007, UInt64 is emitted as signed __int64 in HPP + // files instead of as unsigned __int64. This causes conflicts in overloaded + // routines that have (U)Int64 parameters. This was fixed in C++Builder 2009... + {$IFDEF CBUILDER} + {$DEFINE BROKEN_UINT64_HPPEMIT} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2007_OR_ABOVE} + {$IFNDEF CBUILDER_2007} + // class properties are broken in C++Builder 2007, causing AVs at compile-time + {$DEFINE HAS_CLASSPROPERTIES} + {$ENDIF} + // Native(U)Int exist but are buggy, so do not use them yet + {.$DEFINE HAS_NativeInt} + {.$DEFINE HAS_NativeUInt} + {$DEFINE HAS_DWORD_PTR} + {$DEFINE HAS_ULONG_PTR} + {$DEFINE HAS_ULONGLONG} + {$DEFINE HAS_PGUID} + {$DEFINE HAS_PPAnsiChar} + {$DEFINE HAS_CurrentYear} + {$IFNDEF DOTNET} + {$DEFINE HAS_TIMEUNITS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2009_OR_ABOVE} + {$IFNDEF DOTNET} + {$DEFINE STRING_IS_UNICODE} + {$DEFINE HAS_UnicodeString} + {$DEFINE HAS_TEncoding} + {$DEFINE HAS_TCharacter} + {$DEFINE HAS_InterlockedCompareExchangePointer} + {$DEFINE HAS_WIDE_TCharArray} + {$DEFINE HAS_PUInt64} + {$IFDEF VCL_2009} + // TODO: need to differentiate between RTM and Update 1 + // FmtStr() is broken in RTM but was fixed in Update 1 + {$DEFINE BROKEN_FmtStr} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_CLASSVARS} + {$DEFINE HAS_DEPRECATED_MSG} + {$DEFINE HAS_TBytes} + // Native(U)Int are still buggy, so do not use them yet + {.$DEFINE HAS_NativeInt} + {.$DEFINE HAS_NativeUInt} + {$DEFINE HAS_Int8} + {$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_UIntToStr} + // UInt64 is now emitted as unsigned __int64 in HPP files + {$IFDEF CBUILDER} + {$UNDEF BROKEN_UINT64_HPPEMIT} + {$ENDIF} + {$IFDEF DCC} + {$IFDEF WINDOWS} + // Exception.RaiseOuterException() is only available on Windows at this time + {$DEFINE HAS_Exception_RaiseOuterException} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_SetCodePage} + {$DEFINE HAS_PRawByteString} + {$DEFINE HAS_TThreadProcedure} +{$ENDIF} + +{$IFDEF VCL_2010_OR_ABOVE} + {$DEFINE HAS_CLASSCONSTRUCTOR} + {$DEFINE HAS_CLASSDESTRUCTOR} + {$DEFINE HAS_DELAYLOAD} + {$DEFINE HAS_TThread_NameThreadForDebugging} + {$DEFINE DEPRECATED_TThread_SuspendResume} + // Native(U)Int are finally ok to use now + {$DEFINE HAS_NativeInt} + {$DEFINE HAS_NativeUInt} + {$DEFINE HAS_USHORT} + {$DEFINE HAS_IOUtils_TPath} +{$ENDIF} + +{$IFDEF VCL_XE_OR_ABOVE} + {$DEFINE HAS_TFormatSettings_Object} + {$DEFINE HAS_LocaleCharsFromUnicode} + {$DEFINE HAS_UnicodeFromLocaleChars} + {$DEFINE HAS_PLongBool} + {$DEFINE HAS_PVOID} + {$DEFINE HAS_ULONG64} + {$DEFINE HAS_TEncoding_GetEncoding_ByEncodingName} + {$DEFINE HAS_DateUtils_TTimeZone} + {$IFDEF DCC} + // Exception.RaiseOuterException() is now available on all platforms + {$DEFINE HAS_Exception_RaiseOuterException} + {$ENDIF} + {$IFNDEF DOTNET} + {$DEFINE HAS_TInterlocked} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE2_OR_ABOVE} + {$DEFINE HAS_SIZE_T} + {$DEFINE HAS_PSIZE_T} + {$DEFINE HAS_SSIZE_T} + {$DEFINE HAS_PSSIZE_T} + {$DEFINE HAS_LONG} + {$DEFINE HAS_ComponentPlatformsAttribute} + {$DEFINE HAS_ComponentPlatformsAttribute_Win32} + {$DEFINE HAS_ComponentPlatformsAttribute_Win64} + {$DEFINE HAS_ComponentPlatformsAttribute_OSX32} + {$DEFINE HAS_System_ReturnAddress} + {$DEFINE HAS_DIRECTIVE_WARN_DEFAULT} + {$DEFINE HAS_UNIT_System_ZLib} +{$ENDIF} + +{$IFDEF VCL_XE3_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_ZEROBASEDSTRINGS} + {$DEFINE HAS_SysUtils_TStringHelper} + {$IFDEF NEXTGEN} + {$DEFINE DCC_NEXTGEN} + {$DEFINE HAS_MarshaledAString} + {$DEFINE USE_MARSHALLED_PTRS} + {$IFDEF AUTOREFCOUNT} + {$DEFINE USE_OBJECT_ARC} + {$ENDIF} + {$ENDIF} + // technically, these are present in XE3, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} + {.$DEFINE HAS_ComponentPlatformsAttribute_Android} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32} + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} + {.$DEFINE HAS_ComponentPlatformsAttribute_WinNX32} +{$ENDIF} + +{$IFDEF VCL_XE4_OR_ABOVE} + {$DEFINE HAS_AnsiStrings_StrPLCopy} + {$DEFINE HAS_AnsiStrings_StrLen} + {$DEFINE HAS_Character_TCharHelper} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} +{$ENDIF} + +{$IFDEF VCL_XE5_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_Android} +{$ENDIF} + +{$IFDEF VCL_XE5_UPDATE2_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_LINKUNIT} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_NAMESPACE} +{$ENDIF} + +{$IFDEF VCL_XE7_OR_ABOVE} + {$DEFINE HAS_TNetEncoding} +{$ENDIF} + +{$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device32} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device64} + // technically, these are present in XE8, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64} + {.$DEFINE HAS_ComponentPlatformsAttribute_WinIoT32} +{$ENDIF} + +{$IFDEF VCL_10_0_OR_ABOVE} + {$IFDEF ANDROID} + {$DEFINE HAS_TAndroidHelper} + {$ENDIF} + // technically, these are present in 10.0 Seattle, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_WinARM} +{$ENDIF} + +{$IFDEF VCL_10_1_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_LEGACYHPP} + {$DEFINE HAS_TStrings_AddPair} + // technically, these are present in 10.1 Berlin, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_OSX64} + {.$DEFINE HAS_ComponentPlatformsAttribute_OSXNX64} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32Arm} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64Arm} + {.$DEFINE HAS_ComponentPlatformsAttribute_Android64} +{$ENDIF} + +{$IFDEF VCL_10_2_OR_ABOVE} + {.$WARN IMPLICIT_INTEGER_CAST_LOSS OFF} + {.$WARN IMPLICIT_CONVERSION_LOSS OFF} + {.$WARN COMBINING_SIGNED_UNSIGNED64 OFF} + {$DEFINE HAS_STATIC_TThread_ForceQueue} + // In Delphi 10.2 Tokyo, TThread.ForceQueue() is broken on Android, the + // passed in procedure is called immediately instead of being delayed! + {$IFDEF ANDROID} + {$DEFINE BROKEN_TThread_ForceQueue} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator32} + {$DEFINE HAS_ComponentPlatformsAttribute_Android32Arm} + {$DEFINE HAS_ComponentPlatformsAttribute_WinARM32} + {$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} // removed in 10.3 Rio + // technically, these are present in 10.3 Rio, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator64} + {$IFDEF DCC} + {$IFDEF LINUX} + // RLebeau 9/25/2019: there is a bug in the IDE when debugging Linux projects + // where the EThreadNameException exception raised by TThread.NameThreadForDebugging() + // is not handled correctly. + {$UNDEF HAS_NAMED_THREADS} + {$ENDIF} + {$ENDIF} + {$IFDEF ANDROID} + {$UNDEF BROKEN_TThread_ForceQueue} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_UPDATE2_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_AllPlatforms} + {$DEFINE HAS_ComponentPlatformsAttribute_OSX64} +{$ENDIF} + +{$IFDEF VCL_10_4_OR_ABOVE} + // 0-based string indexing via '[]' is turned off by default in Delphi 10.4. + // TStringHelper is always 0-indexed, flat RTL functions are always 1-indexed, + // and now '[]' is 1-indexed again on all platforms - {$ZEROBASEDSTRINGS OFF} + // is the default. + {.$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} +{$ENDIF} + +{$IFDEF VCL_11_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm32} + {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm64} + {$DEFINE HAS_ComponentPlatformsAttribute_OSXArm64} +{$ENDIF} + +// Delphi XE+ cross-compiling +{$IFNDEF FPC} + {$IFDEF POSIX} + {$IF RTLVersion >= 22.0} + {$DEFINE UNIX} + {$UNDEF USE_BASEUNIX} + {$DEFINE VCL_CROSS_COMPILE} + {$DEFINE USE_VCL_POSIX} + {$IFEND} + {$ENDIF} + {$IFDEF LINUX} + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF RTLVersion >= 22.0} + {$DEFINE VCL_CROSS_COMPILE} + {$DEFINE USE_VCL_POSIX} + {$IFEND} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_CROSS_COMPILE} + {$UNDEF KYLIXCOMPAT} +{$ELSE} + {$IFDEF KYLIXCOMPAT} + {$linklib c} + {$ENDIF} +{$ENDIF} + +{$IFDEF FPC} + {$DEFINE USE_INLINE} + {$DEFINE USE_CLASSINLINE} + {$DEFINE USE_TBitBtn} //use Bit Buttons instead of Buttons + {$DEFINE FPC_REINTRODUCE_BUG} + {$DEFINE FPC_CIRCULAR_BUG} + {$DEFINE NO_REDECLARE} + {$DEFINE BYTE_COMPARE_SETS} + {$DEFINE HAS_QWord} // TODO: when was QWord introduced? + {$DEFINE HAS_PQWord} // TODO: when was PQWord introduced? + {$IFDEF FPC_2_1_5_OR_ABOVE} + {$DEFINE HAS_UInt64} + {.$DEFINE HAS_PUInt64} // TODO: is this defined? + {$ENDIF} + {$IFDEF FPC_2_2_0_OR_ABOVE} + {$DEFINE HAS_InterlockedCompareExchange_Pointers} + {$ENDIF} + {$IFDEF FPC_2_2_2_OR_ABOVE} + {$DEFINE HAS_SharedSuffix} + {$ENDIF} + {$IFDEF FPC_2_2_4_OR_ABOVE} + // these types are only available on Unix systems (FreeBSD, Linux, etc) + {$IFDEF UNIX} + {$DEFINE HAS_UNIT_UnixType} + {$DEFINE HAS_SIZE_T} + {$DEFINE HAS_PSIZE_T} + {$DEFINE HAS_SSIZE_T} + {$DEFINE HAS_PSSIZE_T} + {$DEFINE HAS_TIME_T} + {$DEFINE HAS_PTIME_T} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_PtrInt} + {$DEFINE HAS_PtrUInt} + {$DEFINE HAS_PGUID} + {$DEFINE HAS_LPGUID} + {$DEFINE HAS_PPAnsiChar} + {$DEFINE HAS_ENUM_ELEMENT_VALUES} + {$DEFINE HAS_AcquireExceptionObject} // TODO: when was AcquireExceptionObject introduced? + {$IFDEF WINDOWS} + {$DEFINE HAS_ULONG_PTR} + {.$DEFINE HAS_ULONGLONG} // TODO: is this defined? + {$ENDIF} + {$DEFINE HAS_UNIT_ctypes} + {$DEFINE HAS_sLineBreak} + {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? + {$IFDEF FPC_HAS_UNICODESTRING} + {$DEFINE HAS_UnicodeString} + {$ELSE} + {$IFDEF FPC_2_4_0_OR_ABOVE} + {$DEFINE HAS_UnicodeString} + {$ENDIF} + {$ENDIF} + {$IFDEF FPC_2_4_4_OR_ABOVE} + {$DEFINE DEPRECATED_TThread_SuspendResume} + {$DEFINE HAS_DEPRECATED} // TODO: when was deprecated introduced? Possibly 1.9.x + {$DEFINE HAS_DEPRECATED_MSG} // TODO: when was message support added? Possibly 2.4.x + {$DEFINE HAS_STATIC_TThread_Synchronize} + {$IFNDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE USE_SEMICOLON_BEFORE_DEPRECATED} // TODO: which earlier versions require a semicolon? + {$ENDIF} + {$ENDIF} + {$IFDEF FPC_2_6_0_OR_ABOVE} + {$DEFINE HAS_NativeInt} + {$DEFINE HAS_NativeUInt} + {$DEFINE HAS_CLASS_HELPER} + {$ENDIF} + {$IFDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE HAS_Int8} + {$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_GetLocalTimeOffset} + {$DEFINE HAS_UniversalTimeToLocal} + {$DEFINE HAS_LocalTimeToUniversal} + {$ENDIF} + {$IFDEF FPC_2_6_4_OR_ABOVE} + {$DEFINE HAS_PInt8} + {$DEFINE HAS_PUInt8} + {$DEFINE HAS_PInt16} + {$DEFINE HAS_PUInt16} + {$DEFINE HAS_PInt32} + {$DEFINE HAS_PUInt32} + {$ENDIF} + {$IFDEF FPC_3_0_0_OR_ABOVE} + {$DEFINE HAS_STATIC_TThread_Queue} + {$DEFINE HAS_SetCodePage} + {$ENDIF} + {$IFDEF FPC_UNICODESTRINGS} + {$DEFINE STRING_IS_UNICODE} + {$ENDIF} + {$IFDEF FPC_3_1_1_OR_ABOVE} + {$DEFINE HAS_STATIC_TThread_ForceQueue} // requires rev 37359+ + {$DEFINE HAS_PRawByteString} + {$DEFINE HAS_UIntToStr} // requires rev 40529+ + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + {$DEFINE WIDGET_WINFORMS} +{$ELSE} + {$DEFINE WIDGET_VCL_LIKE} // LCL included. + {$DEFINE WIDGET_VCL_LIKE_OR_KYLIX} + {$IFDEF FPC} + {$DEFINE WIDGET_LCL} + {$ELSE} + {$IFDEF KYLIX} + {$DEFINE WIDGET_KYLIX} + {$ELSE} + {$DEFINE WIDGET_VCL} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +// .NET and Delphi 2009+ support UNICODE strings natively! +// +// FreePascal 2.4.0+ supports UnicodeString, but does not map its +// native String type to UnicodeString except when {$MODE DelphiUnicode} +// or {$MODESWITCH UnicodeStrings} is enabled. However, UNICODE is not +// defined in that mode yet until its RTL has been updated to support +// UnicodeString. STRING_UNICODE_MISMATCH is defined when the native +// String/Char types do not map to the same types that APIs are expecting +// based on whether UNICODE is defined or not. +// +// NOTE: Do not define UNICODE here. The compiler defines +// the symbol automatically. +{$IFDEF STRING_IS_UNICODE} + {$IFNDEF UNICODE} + {$DEFINE STRING_UNICODE_MISMATCH} + {$ENDIF} +{$ELSE} + {$DEFINE STRING_IS_ANSI} + {$IFDEF UNICODE} + {$DEFINE STRING_UNICODE_MISMATCH} + {$ENDIF} +{$ENDIF} + +{$IFDEF DCC_NEXTGEN} + {$DEFINE NO_ANSI_TYPES} + {.$DEFINE STRING_IS_IMMUTABLE} // Strings are NOT immutable in NEXTGEN yet + {$IFDEF USE_OBJECT_ARC} + // TODO: move these to an appropriate section. Not doing this yet because + // it is a major interface change to switch to Generics and we should + // maintain backwards compatibility with earlier compilers for the time + // being. Defining them only here for now because the non-Generic versions + // of these classes have become deprecated by ARC and so we need to start + // taking advantage of the Generics versions... + {$DEFINE HAS_UNIT_Generics_Collections} + {$DEFINE HAS_UNIT_Generics_Defaults} + {$DEFINE HAS_GENERICS_TDictionary} + {$DEFINE HAS_GENERICS_TList} + {$DEFINE HAS_GENERICS_TObjectList} + {$DEFINE HAS_GENERICS_TThreadList} + // TArray.Copy() was introduced in XE7 but was buggy. It was fixed in XE8: + // + // RSP-9763 TArray.Copy copies from destination to source for unmanaged types + // https://quality.embarcadero.com/browse/RSP-9763 + // + {$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE HAS_GENERICS_TArray_Copy} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +// TODO: Ansi data types were disabled on mobile platforms in XE3, but +// UTF8String and RawByteString were re-enabled in 10.1 Berlin! What else, +// if anything, was re-enabled to facilitate that? +// +// UPDATE: In 10.4 Sydney, AnsiChar and AnsiString were re-enabled on +// mobile platforms! NEXTGEN is no longer defined in the mobile compilers. +{$IFDEF NO_ANSI_TYPES} + {$UNDEF HAS_AnsiString} + {$UNDEF HAS_AnsiChar} + {$UNDEF HAS_PAnsiChar} + {$UNDEF HAS_PPAnsiChar} + {$UNDEF HAS_AnsiStrings_StrPLCopy} + {$UNDEF HAS_AnsiStrings_StrLen} +{$ENDIF} + +{$IFDEF WIN32} + {$DEFINE WIN32_OR_WIN64} +{$ENDIF} +{$IFDEF WIN64} + {$DEFINE WIN32_OR_WIN64} +{$ENDIF} + +{$IFDEF WIN32_OR_WIN64} + {$DEFINE USE_ZLIB_UNIT} + {$IFNDEF DCC_NEXTGEN} + {$DEFINE USE_OPENSSL} // !!! MOVED HERE BY EMBT + {$DEFINE USE_SSPI} + {$IFDEF STRING_IS_UNICODE} + {$DEFINE SSPI_UNICODE} + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF WINCE} + {$DEFINE USE_OPENSSL} + // RLebeau: not sure if the above Win32/64 defines also apply to WinCE, + // so keeping them separate for now... +{$ENDIF} + +// High-performance counters are not reliable on multi-core systems, and have +// been known to cause problems with TIdIOHandler.ReadLn() timeouts in Windows +// XP SP3, both 32-bit and 64-bit. Refer to these discussions for more info: +// +// http://www.virtualdub.org/blog/pivot/entry.php?id=106 +// http://blogs.msdn.com/oldnewthing/archive/2008/09/08/8931563.aspx +// +// Do not enable thus unless you know it will work correctly on your systems! +{$IFDEF WINDOWS} + {.$DEFINE USE_HI_PERF_COUNTER_FOR_TICKS} +{$ENDIF} + +{$IFDEF UNIX} + {$DEFINE USE_OPENSSL} + {$DEFINE USE_ZLIB_UNIT} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF MACOS} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF DARWIN} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF LINUX} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF IOS} + {$DEFINE HAS_getifaddrs} + {$DEFINE USE_OPENSSL} + + // Support for 64-bit ARM iOS Simulator was added in Delphi 11.2 + // TODO: how to detect iOS Simulator in FPC? Does it support 64-bit ARM? + {$IFDEF CPUARM} + {$IFNDEF IOSSIMULATOR} + // RLebeau: For iOS devices, OpenSSL cannot be used as an external library, + // it must be statically linked into the app. For the iOS simulator, this + // is not true. Users who want to use OpenSSL in iOS device apps will need + // to add the static OpenSSL library to the project and then include the + // IdSSLOpenSSLHeaders_static unit in their uses clause. It hooks up the + // statically linked functions for the IdSSLOpenSSLHeaders unit to use... + {$DEFINE STATICLOAD_OPENSSL} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF FREEBSD} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF ANDROID} + {$UNDEF HAS_getifaddrs} +{$ENDIF} + +{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} + {$DEFINE REQUIRES_PROPER_ALIGNMENT} +{$ENDIF} + +// +//iconv defines section. +{$DEFINE USE_ICONV_UNIT} +{$DEFINE USE_ICONV_ENC} +{$IFDEF UNIX} + {$DEFINE USE_ICONV} + {$IFDEF USE_BASEUNIX} + {$IFDEF FPC} + {$UNDEF USE_ICONV_UNIT} + {$ELSE} + {$UNDEF USE_ICONV_ENC} + {$ENDIF} + {$ENDIF} + {$IFDEF KYLIXCOMPAT} + //important!! Iconv functions are defined in the libc.pas Kylix compatible unit. + {$UNDEF USE_ICONV_ENC} + {$UNDEF USE_ICONV_UNIT} + {$ENDIF} +{$ENDIF} +{$IFDEF NETWARELIBC} + {$DEFINE USE_ICONV} + //important!!! iconv functions are defined in the libc.pas Novell Netware header. + //Do not define USE_ICONV_UNIT + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} +{$ENDIF} + +{$UNDEF USE_SAFELOADLIBRARY} +{$IFDEF WINDOWS} + {$UNDEF USE_ICONV_ENC} + {$DEFINE USE_SAFELOADLIBRARY} +{$ENDIF} +// Use here for all *nix systems that you do not want to use iconv library +{$IFDEF FPC} + {$IFDEF ANDROID} + {$UNDEF USE_ICONV} + {$DEFINE USE_LCONVENC} + {$ENDIF} +{$ENDIF} + +{$UNDEF USE_INVALIDATE_MOD_CACHE} +{$UNDEF USE_SAFELOADLIBRARY} +//This must come after the iconv defines because this compiler targets a Unix-like +//operating system. One key difference is that it does have a TEncoding class. +//If this comes before the ICONV defines, it creates problems. +//This also must go before the THandle size calculations. +{$IFDEF VCL_CROSS_COMPILE} + {$IFDEF POSIX} + {$IFNDEF LINUX} + {$DEFINE BSD} + {$ENDIF} + {$DEFINE USE_SAFELOADLIBRARY} + {$DEFINE USE_INVALIDATE_MOD_CACHE} + {$ENDIF} + //important!!! iconv functions are defined in the libc.pas Novell Netware header. + //Do not define USE_ICONVUNIT + {$UNDEF USE_ICONV} + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} + {$DEFINE INT_THREAD_PRIORITY} +{$ENDIF} + +{$IFNDEF USE_ICONV} + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} +{$ENDIF} + +//IMPORTANT!!!! +// +//Do not remove this!!! This is to work around a conflict. In DCC, MACOS +//will mean OS X. In FreePascal, the DEFINE MACOS means MacIntosh System OS Classic. +{$IFDEF DCC} + // DCC defines MACOS for both iOS and OS X platforms, need to differentiate + {$IFDEF MACOS} + {$IFNDEF IOS} + {$DEFINE OSX} + {$DEFINE DARWIN} + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF FPC} + // FPC defines DARWIN for both OSX and iOS, need to differentiate + {$IFDEF DARWIN} + {$IFNDEF IOS} + {$DEFINE OSX} + {$ENDIF} + {$ENDIF} + {$IFDEF MACOS} + {$DEFINE MACOS_CLASSIC} + {$ENDIF} +{$ENDIF} + +{ +BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit +word to an 8 bit byte and an 8 bit byte field named sa_len was added. +} +//Place this only after DARWIN has been defined for Delphi MACOS +{$IFDEF FREEBSD} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF DARWIN} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF MORPHOS} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} + +// Do NOT remove these IFDEF's. They are here because InterlockedExchange +// only handles 32bit values. Some Operating Systems may have 64bit +// THandles. This is not always tied to the platform architecture. + +{$IFDEF AMIGA} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF ATARI} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF BEOS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF BSD} + //I think BSD might handle FreeBSD, NetBSD, OpenBSD, and Darwin + {$IFDEF IOS} + {$IFDEF CPUARM64} + {$DEFINE CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$IFDEF CPUARM32} + {$DEFINE CPU32} + {$ENDIF} + {$DEFINE THANDLE_32} + {$ENDIF} + {$ENDIF} + {$IFDEF OSX} + {$IFDEF FPC} + {$DEFINE THANDLE_32} + {$ELSE} + {$DEFINE THANDLE_CPUBITS} // !!! ADDED OSX BY EMBT + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF EMBEDDED} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF EMX} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF GBA} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF GO32} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF LINUX} + {$IFDEF LINUX64} + {$DEFINE CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$IFDEF LINUX32} + {$DEFINE CPU32} + {$ENDIF} + {$DEFINE THANDLE_32} + {$ENDIF} +{$ENDIF} +{$IFDEF MACOS_CLASSIC} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF MORPHOS} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF NATIVENT} //Native NT for kernel level drivers + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF NDS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF NETWARE} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF NETWARELIBC} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF OS2} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF PALMOS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF SOLARIS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF SYMBIAN} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WII} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WATCOM} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WINDOWS} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} + +// end platform specific stuff for THandle size + +{$IFDEF THANDLE_CPUBITS} + {$IFDEF CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$DEFINE THANDLE_32} + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + {$DEFINE DOTNET_OR_ICONV} +{$ENDIF} +{$IFDEF USE_ICONV} + {$DEFINE DOTNET_OR_ICONV} +{$ENDIF} + +{$UNDEF STREAM_SIZE_64} +{$IFDEF FPC} + {$DEFINE STREAM_SIZE_64} +{$ELSE} + {$IFDEF VCL_6_OR_ABOVE} + {$DEFINE STREAM_SIZE_64} + {$ENDIF} +{$ENDIF} + +{$IFNDEF FREE_ON_FINAL} + {$IFNDEF DOTNET} + {$IFDEF HAS_System_RegisterExpectedMemoryLeak} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_FASTMM4} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_MADEXCEPT} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_LEAKCHECK} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{ +We must determine what the SocketType parameter is for the Socket function. +In DotNET, it's SocketType. In Kylix and the libc.pas Kylix-compatibility +library, it's a __socket_type. In BaseUnix, it's a C-type Integer. In Windows, +it's a LongInt. + +} +{$UNDEF SOCKETTYPE_IS_SOCKETTYPE} +{$UNDEF SOCKETTYPE_IS_CINT} +{$UNDEF SOCKETTYPE_IS___SOCKETTYPE} +{$UNDEF SOCKETTYPE_IS_LONGINT} +{$UNDEF SOCKETTYPE_IS_NUMERIC} +{$UNDEF SOCKET_LEN_IS_socklen_t} +{$IFDEF DOTNET} + {$DEFINE SOCKETTYPE_IS_SOCKETTYPE} +{$ENDIF} +{$IFDEF USE_BASEUNIX} + {$DEFINE SOCKETTYPE_IS_CINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF KYLIXCOMPAT} + {$DEFINE SOCKETTYPE_IS___SOCKETTYPE} +{$ENDIF} +{$IFDEF USE_VCL_POSIX} + {$DEFINE SOCKETTYPE_IS_NUMERIC} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKET_LEN_IS_socklen_t} +{$ENDIF} +{$IFDEF WINDOWS} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF OS2} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF NETWARE} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} + +{Take advantage of some TCP features specific to some stacks. +They work somewhat similarly but there's a key difference. +In Linux, TCP_CORK is turned on to send fixed packet sizes and +when turned-off (uncorked), any remaining data is sent. With +TCP_NOPUSH, this might not happen and remaining data is only sent +before disconnect. TCP_KEEPIDLE and TCP_KEEPINTVL so the IFDEF LINUX and IFDEF +SOLARIS instead of IFDEF UNIX is not an error, it's deliberate.} +{$UNDEF HAS_TCP_NOPUSH} +{$UNDEF HAS_TCP_CORK} +{$UNDEF HAS_TCP_KEEPIDLE} +{$UNDEF HAS_TCP_KEEPINTVL} +{$UNDEF HAS_SOCKET_NOSIGPIPE} +{$IFDEF BSD} + {$DEFINE HAS_TCP_NOPUSH} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE HAS_TCP_NOPUSH} +{$ENDIF} +{$IFDEF LINUX} + {$DEFINE HAS_TCP_CORK} + {$DEFINE HAS_TCP_KEEPIDLE} + {$DEFINE HAS_TCP_KEEPINTVL} +{$ENDIF} +{$IFDEF SOLARIS} + {$DEFINE HAS_TCP_CORK} +{$ENDIF} +{$IFDEF NETBSD} + {$DEFINE HAS_TCP_CORK} + {$DEFINE HAS_TCP_KEEPIDLE} + {$DEFINE HAS_TCP_KEEPINTVL} +{$ENDIF} +{$IFDEF USE_VCL_POSIX} + // TODO: which platforms actually have SO_NOSIGPIPE available? + {$DEFINE HAS_SOCKET_NOSIGPIPE} + {$IFDEF ANDROID} + {$UNDEF HAS_SOCKET_NOSIGPIPE} + {$ENDIF} + {$IFDEF LINUX} + {$UNDEF HAS_SOCKET_NOSIGPIPE} + {$ENDIF} +{$ENDIF} +{end Unix OS specific stuff} +{$IFDEF DEBUG} + {$UNDEF USE_INLINE} +{$ENDIF} + +// RLebeau 5/24/2015: In C++Builder 2006 and 2007, UInt64 is emitted as +// signed __int64 in HPP files instead of as unsigned __int64. This causes +// conflicts in overloaded routines that have (U)Int64 parameters. This +// was fixed in C++Builder 2009. For compilers that do not have a native +// UInt64 type, or for C++Builder 2006/2007, let's define a record type +// that can hold UInt64 values... +{$IFDEF HAS_UInt64} + {$IFDEF BROKEN_UINT64_HPPEMIT} + {$DEFINE TIdUInt64_HAS_QuadPart} + {$ENDIF} +{$ELSE} + {$IFNDEF HAS_QWord} + {$DEFINE TIdUInt64_HAS_QuadPart} + {$ENDIF} +{$ENDIF} + +// RLebeau 9/5/2013: it would take a lot of work to re-write Indy to support +// both 0-based and 1-based string indexing, so we'll just turn off 0-based +// indexing for now... +{$IFDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} + {$ZEROBASEDSTRINGS OFF} +{$ENDIF} diff --git a/Lib/FCL/IdVers.inc b/Lib/FCL/IdVers.inc index b2c553572..316666f1b 100644 --- a/Lib/FCL/IdVers.inc +++ b/Lib/FCL/IdVers.inc @@ -1,18 +1,18 @@ - gsIdVersionMajor = 10; - {$NODEFINE gsIdVersionMajor} - gsIdVersionMinor = 7; - {$NODEFINE gsIdVersionMinor} - gsIdVersionRelease = 0; - {$NODEFINE gsIdVersionRelease} - gsIdVersionBuild = 0; - {$NODEFINE gsIdVersionBuild} - - (*$HPPEMIT '#define gsIdVersionMajor 10'*) - (*$HPPEMIT '#define gsIdVersionMinor 7'*) - (*$HPPEMIT '#define gsIdVersionRelease 0'*) - (*$HPPEMIT '#define gsIdVersionBuild 0'*) - (*$HPPEMIT ''*) - - gsIdVersion = '10.7.0.0'; {do not localize} - gsIdProductName = 'Indy'; {do not localize} - gsIdProductVersion = '10.7.0'; {do not localize} + gsIdVersionMajor = 10; + {$NODEFINE gsIdVersionMajor} + gsIdVersionMinor = 7; + {$NODEFINE gsIdVersionMinor} + gsIdVersionRelease = 0; + {$NODEFINE gsIdVersionRelease} + gsIdVersionBuild = 0; + {$NODEFINE gsIdVersionBuild} + + (*$HPPEMIT '#define gsIdVersionMajor 10'*) + (*$HPPEMIT '#define gsIdVersionMinor 7'*) + (*$HPPEMIT '#define gsIdVersionRelease 0'*) + (*$HPPEMIT '#define gsIdVersionBuild 0'*) + (*$HPPEMIT ''*) + + gsIdVersion = '10.7.0.0'; {do not localize} + gsIdProductName = 'Indy'; {do not localize} + gsIdProductVersion = '10.7.0'; {do not localize} diff --git a/Lib/Indy100Net.dpk b/Lib/Indy100Net.dpk index f802a4f22..6a452c3db 100644 --- a/Lib/Indy100Net.dpk +++ b/Lib/Indy100Net.dpk @@ -1,335 +1,335 @@ -package Indy100Net; - -{$ALIGN 0} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Master'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - Borland.Delphi, - Borland.Vcl, - Borland.VclRtl; - -contains - IdASN1Util in 'Protocols\IdASN1Util.pas', - IdAllAuthentications in 'Protocols\IdAllAuthentications.pas', - IdAllFTPListParsers in 'Protocols\IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'Protocols\IdAllHeaderCoders.pas', - IdAntiFreezeBase in 'System\IdAntiFreezeBase.pas', - IdAssignedNumbers in 'Core\IdAssignedNumbers.pas', - IdAttachment in 'Protocols\IdAttachment.pas', - IdAttachmentFile in 'Protocols\IdAttachmentFile.pas', - IdAttachmentMemory in 'Protocols\IdAttachmentMemory.pas', - IdAuthentication in 'Protocols\IdAuthentication.pas', - IdAuthenticationDigest in 'Protocols\IdAuthenticationDigest.pas', - IdAuthenticationManager in 'Protocols\IdAuthenticationManager.pas', - IdBaseComponent in 'System\IdBaseComponent.pas', - IdBlockCipherIntercept in 'Protocols\IdBlockCipherIntercept.pas', - IdBuffer in 'Core\IdBuffer.pas', - IdCarrierStream in 'Security\IdCarrierStream.pas', - IdChargenServer in 'Protocols\IdChargenServer.pas', - IdChargenUDPServer in 'Protocols\IdChargenUDPServer.pas', - IdCharsets in 'Protocols\IdCharsets.pas', - IdCmdTCPClient in 'Core\IdCmdTCPClient.pas', - IdCmdTCPServer in 'Core\IdCmdTCPServer.pas', - IdCoder in 'Protocols\IdCoder.pas', - IdCoder00E in 'Protocols\IdCoder00E.pas', - IdCoder3to4 in 'Protocols\IdCoder3to4.pas', - IdCoderBinHex4 in 'Protocols\IdCoderBinHex4.pas', - IdCoderHeader in 'Protocols\IdCoderHeader.pas', - IdCoderMIME in 'Protocols\IdCoderMIME.pas', - IdCoderQuotedPrintable in 'Protocols\IdCoderQuotedPrintable.pas', - IdCoderUUE in 'Protocols\IdCoderUUE.pas', - IdCoderXXE in 'Protocols\IdCoderXXE.pas', - IdCommandHandlers in 'Core\IdCommandHandlers.pas', - IdComponent in 'System\IdComponent.pas', - IdConnectThroughHttpProxy in 'Protocols\IdConnectThroughHttpProxy.pas', - IdContainers in 'Protocols\IdContainers.pas', - IdContext in 'Core\IdContext.pas', - IdCookie in 'Protocols\IdCookie.pas', - IdCookieManager in 'Protocols\IdCookieManager.pas', - IdCustomHTTPServer in 'Protocols\IdCustomHTTPServer.pas', - IdCustomTCPServer in 'Core\IdCustomTCPServer.pas', - IdCustomTransparentProxy in 'Core\IdCustomTransparentProxy.pas', - IdDICT in 'Protocols\IdDICT.pas', - IdDICTCommon in 'Protocols\IdDICTCommon.pas', - IdDICTServer in 'Protocols\IdDICTServer.pas', - IdDNSCommon in 'Protocols\IdDNSCommon.pas', - IdDNSResolver in 'Protocols\IdDNSResolver.pas', - IdDNSServer in 'Protocols\IdDNSServer.pas', - IdDateTimeStamp in 'Protocols\IdDateTimeStamp.pas', - IdDayTime in 'Protocols\IdDayTime.pas', - IdDayTimeServer in 'Protocols\IdDayTimeServer.pas', - IdDayTimeUDP in 'Protocols\IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'Protocols\IdDayTimeUDPServer.pas', - IdDiscardServer in 'Protocols\IdDiscardServer.pas', - IdDiscardUDPServer in 'Protocols\IdDiscardUDPServer.pas', - IdEMailAddress in 'Protocols\IdEMailAddress.pas', - IdEcho in 'Protocols\IdEcho.pas', - IdEchoServer in 'Protocols\IdEchoServer.pas', - IdEchoUDP in 'Protocols\IdEchoUDP.pas', - IdEchoUDPServer in 'Protocols\IdEchoUDPServer.pas', - IdException in 'System\IdException.pas', - IdExceptionCore in 'Core\IdExceptionCore.pas', - IdExplicitTLSClientServerBase in 'Protocols\IdExplicitTLSClientServerBase.pas', - IdFIPS in 'Protocols\IdFIPS.pas', - IdFSP in 'Protocols\IdFSP.pas', - IdFTP in 'Protocols\IdFTP.pas', - IdFTPBaseFileSystem in 'Protocols\IdFTPBaseFileSystem.pas', - IdFTPCommon in 'Protocols\IdFTPCommon.pas', - IdFTPList in 'Protocols\IdFTPList.pas', - IdFTPListOutput in 'Protocols\IdFTPListOutput.pas', - IdFTPListParseAS400 in 'Protocols\IdFTPListParseAS400.pas', - IdFTPListParseBase in 'Protocols\IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'Protocols\IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'Protocols\IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'Protocols\IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'Protocols\IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'Protocols\IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'Protocols\IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'Protocols\IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'Protocols\IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'Protocols\IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'Protocols\IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'Protocols\IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'Protocols\IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'Protocols\IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'Protocols\IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'Protocols\IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'Protocols\IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'Protocols\IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'Protocols\IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'Protocols\IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'Protocols\IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'Protocols\IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'Protocols\IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'Protocols\IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'Protocols\IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'Protocols\IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'Protocols\IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'Protocols\IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'Protocols\IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'Protocols\IdFTPListParseUnix.pas', - IdFTPListParseVM in 'Protocols\IdFTPListParseVM.pas', - IdFTPListParseVMS in 'Protocols\IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'Protocols\IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'Protocols\IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'Protocols\IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'Protocols\IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'Protocols\IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'Protocols\IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'Protocols\IdFTPListTypes.pas', - IdFTPServer in 'Protocols\IdFTPServer.pas', - IdFTPServerContextBase in 'Protocols\IdFTPServerContextBase.pas', - IdFinger in 'Protocols\IdFinger.pas', - IdFingerServer in 'Protocols\IdFingerServer.pas', - IdGlobal in 'System\IdGlobal.pas', - IdGlobalCore in 'Core\IdGlobalCore.pas', - IdGlobalProtocols in 'Protocols\IdGlobalProtocols.pas', - IdGopher in 'Protocols\IdGopher.pas', - IdGopherConsts in 'Protocols\IdGopherConsts.pas', - IdGopherServer in 'Protocols\IdGopherServer.pas', - IdHL7 in 'Protocols\IdHL7.pas', - IdHMAC in 'Protocols\IdHMAC.pas', - IdHMACMD5 in 'Protocols\IdHMACMD5.pas', - IdHMACSHA1 in 'Protocols\IdHMACSHA1.pas', - IdHTTP in 'Protocols\IdHTTP.pas', - IdHTTPHeaderInfo in 'Protocols\IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'Protocols\IdHTTPHelper.pas', - IdHTTPProxyServer in 'Protocols\IdHTTPProxyServer.pas', - IdHTTPServer in 'Protocols\IdHTTPServer.pas', - IdHash in 'Protocols\IdHash.pas', - IdHashCRC in 'Protocols\IdHashCRC.pas', - IdHashElf in 'Protocols\IdHashElf.pas', - IdHashMessageDigest in 'Protocols\IdHashMessageDigest.pas', - IdHashSHA in 'Protocols\IdHashSHA.pas', - IdHeaderCoder2022JP in 'Protocols\IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'Protocols\IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'Protocols\IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'Protocols\IdHeaderCoderPlain.pas', - IdHeaderList in 'Protocols\IdHeaderList.pas', - IdIMAP4 in 'Protocols\IdIMAP4.pas', - IdIMAP4Server in 'Protocols\IdIMAP4Server.pas', - IdIOHandler in 'Core\IdIOHandler.pas', - IdIOHandlerSocket in 'Core\IdIOHandlerSocket.pas', - IdIOHandlerStack in 'Core\IdIOHandlerStack.pas', - IdIOHandlerStream in 'Core\IdIOHandlerStream.pas', - IdIOHandlerTls in 'Security\IdIOHandlerTls.pas', - IdIPAddrMon in 'Protocols\IdIPAddrMon.pas', - IdIPAddress in 'Core\IdIPAddress.pas', - IdIPMCastBase in 'Core\IdIPMCastBase.pas', - IdIPMCastClient in 'Core\IdIPMCastClient.pas', - IdIPMCastServer in 'Core\IdIPMCastServer.pas', - IdIPWatch in 'Protocols\IdIPWatch.pas', - IdIRC in 'Protocols\IdIRC.pas', - IdIcmpClient in 'Core\IdIcmpClient.pas', - IdIdent in 'Protocols\IdIdent.pas', - IdIdentServer in 'Protocols\IdIdentServer.pas', - IdIntercept in 'Core\IdIntercept.pas', - IdInterceptSimLog in 'Core\IdInterceptSimLog.pas', - IdInterceptThrottler in 'Core\IdInterceptThrottler.pas', - IdIrcServer in 'Protocols\IdIrcServer.pas', - IdLPR in 'Protocols\IdLPR.pas', - IdLogBase in 'Core\IdLogBase.pas', - IdLogDebug in 'Core\IdLogDebug.pas', - IdLogEvent in 'Core\IdLogEvent.pas', - IdLogFile in 'Core\IdLogFile.pas', - IdLogStream in 'Core\IdLogStream.pas', - IdMailBox in 'Protocols\IdMailBox.pas', - IdMappedFTP in 'Protocols\IdMappedFTP.pas', - IdMappedPOP3 in 'Protocols\IdMappedPOP3.pas', - IdMappedPortTCP in 'Protocols\IdMappedPortTCP.pas', - IdMappedPortUDP in 'Protocols\IdMappedPortUDP.pas', - IdMappedTelnet in 'Protocols\IdMappedTelnet.pas', - IdMessage in 'Protocols\IdMessage.pas', - IdMessageBuilder in 'Protocols\IdMessageBuilder.pas', - IdMessageClient in 'Protocols\IdMessageClient.pas', - IdMessageCoder in 'Protocols\IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'Protocols\IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'Protocols\IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'Protocols\IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'Protocols\IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'Protocols\IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'Protocols\IdMessageCoderYenc.pas', - IdMessageCollection in 'Protocols\IdMessageCollection.pas', - IdMessageHelper in 'Protocols\IdMessageHelper.pas', - IdMessageParts in 'Protocols\IdMessageParts.pas', - IdMultipartFormData in 'Protocols\IdMultipartFormData.pas', - IdNNTP in 'Protocols\IdNNTP.pas', - IdNNTPServer in 'Protocols\IdNNTPServer.pas', - IdNetworkCalculator in 'Protocols\IdNetworkCalculator.pas', - IdOSFileName in 'Protocols\IdOSFileName.pas', - IdOTPCalculator in 'Protocols\IdOTPCalculator.pas', - IdPOP3 in 'Protocols\IdPOP3.pas', - IdPOP3Server in 'Protocols\IdPOP3Server.pas', - IdQOTDUDP in 'Protocols\IdQOTDUDP.pas', - IdQOTDUDPServer in 'Protocols\IdQOTDUDPServer.pas', - IdQotd in 'Protocols\IdQotd.pas', - IdQotdServer in 'Protocols\IdQotdServer.pas', - IdRSH in 'Protocols\IdRSH.pas', - IdRSHServer in 'Protocols\IdRSHServer.pas', - IdRawBase in 'Core\IdRawBase.pas', - IdRawClient in 'Core\IdRawClient.pas', - IdRawFunctions in 'Core\IdRawFunctions.pas', - IdRawHeaders in 'Core\IdRawHeaders.pas', - IdRemoteCMDClient in 'Protocols\IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'Protocols\IdRemoteCMDServer.pas', - IdReply in 'Core\IdReply.pas', - IdReplyFTP in 'Protocols\IdReplyFTP.pas', - IdReplyIMAP4 in 'Protocols\IdReplyIMAP4.pas', - IdReplyPOP3 in 'Protocols\IdReplyPOP3.pas', - IdReplyRFC in 'Core\IdReplyRFC.pas', - IdReplySMTP in 'Protocols\IdReplySMTP.pas', - IdResourceStrings in 'System\IdResourceStrings.pas', - IdResourceStringsCore in 'Core\IdResourceStringsCore.pas', - IdResourceStringsProtocols in 'Protocols\IdResourceStringsProtocols.pas', - IdRexec in 'Protocols\IdRexec.pas', - IdRexecServer in 'Protocols\IdRexecServer.pas', - IdSASL in 'Protocols\IdSASL.pas', - IdSASLAnonymous in 'Protocols\IdSASLAnonymous.pas', - IdSASLCollection in 'Protocols\IdSASLCollection.pas', - IdSASLDigest in 'Protocols\IdSASLDigest.pas', - IdSASLExternal in 'Protocols\IdSASLExternal.pas', - IdSASLLogin in 'Protocols\IdSASLLogin.pas', - IdSASLOAuth in 'Protocols\IdSASLOAuth.pas', - IdSASLOTP in 'Protocols\IdSASLOTP.pas', - IdSASLPlain in 'Protocols\IdSASLPlain.pas', - IdSASLSKey in 'Protocols\IdSASLSKey.pas', - IdSASLUserPass in 'Protocols\IdSASLUserPass.pas', - IdSASL_CRAMBase in 'Protocols\IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'Protocols\IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'Protocols\IdSASL_CRAM_SHA1.pas', - IdSMTP in 'Protocols\IdSMTP.pas', - IdSMTPBase in 'Protocols\IdSMTPBase.pas', - IdSMTPRelay in 'Protocols\IdSMTPRelay.pas', - IdSMTPServer in 'Protocols\IdSMTPServer.pas', - IdSNPP in 'Protocols\IdSNPP.pas', - IdSNTP in 'Protocols\IdSNTP.pas', - IdSSL in 'Protocols\IdSSL.pas', - IdSSLDotNET in 'Protocols\IdSSLDotNET.pas', - IdScheduler in 'Core\IdScheduler.pas', - IdSchedulerOfThread in 'Core\IdSchedulerOfThread.pas', - IdSchedulerOfThreadDefault in 'Core\IdSchedulerOfThreadDefault.pas', - IdSchedulerOfThreadPool in 'Core\IdSchedulerOfThreadPool.pas', - IdServerIOHandler in 'Core\IdServerIOHandler.pas', - IdServerIOHandlerSocket in 'Core\IdServerIOHandlerSocket.pas', - IdServerIOHandlerStack in 'Core\IdServerIOHandlerStack.pas', - IdServerIOHandlerTls in 'Security\IdServerIOHandlerTls.pas', - IdServerInterceptLogBase in 'Protocols\IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'Protocols\IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'Protocols\IdServerInterceptLogFile.pas', - IdSimpleServer in 'Core\IdSimpleServer.pas', - IdSocketHandle in 'Core\IdSocketHandle.pas', - IdSocketStream in 'Security\IdSocketStream.pas', - IdSocks in 'Core\IdSocks.pas', - IdSocksServer in 'Protocols\IdSocksServer.pas', - IdStack in 'System\IdStack.pas', - IdStackConsts in 'System\IdStackConsts.pas', - IdStackDotNet in 'System\IdStackDotNet.pas', - IdStream in 'System\IdStream.pas', - IdStreamNET in 'System\IdStreamNET.pas', - IdStrings in 'Protocols\IdStrings.pas', - IdStruct in 'System\IdStruct.pas', - IdSync in 'Core\IdSync.pas', - IdSysLog in 'Protocols\IdSysLog.pas', - IdSysLogMessage in 'Protocols\IdSysLogMessage.pas', - IdSysLogServer in 'Protocols\IdSysLogServer.pas', - IdSystat in 'Protocols\IdSystat.pas', - IdSystatServer in 'Protocols\IdSystatServer.pas', - IdSystatUDP in 'Protocols\IdSystatUDP.pas', - IdSystatUDPServer in 'Protocols\IdSystatUDPServer.pas', - IdTCPClient in 'Core\IdTCPClient.pas', - IdTCPConnection in 'Core\IdTCPConnection.pas', - IdTCPServer in 'Core\IdTCPServer.pas', - IdTCPStream in 'Core\IdTCPStream.pas', - IdTask in 'Core\IdTask.pas', - IdTelnet in 'Protocols\IdTelnet.pas', - IdTelnetServer in 'Protocols\IdTelnetServer.pas', - IdText in 'Protocols\IdText.pas', - IdThread in 'Core\IdThread.pas', - IdThreadComponent in 'Core\IdThreadComponent.pas', - IdThreadSafe in 'Core\IdThreadSafe.pas', - IdTime in 'Protocols\IdTime.pas', - IdTimeServer in 'Protocols\IdTimeServer.pas', - IdTimeUDP in 'Protocols\IdTimeUDP.pas', - IdTimeUDPServer in 'Protocols\IdTimeUDPServer.pas', - IdTlsClientOptions in 'Security\IdTlsClientOptions.pas', - IdTlsServerOptions in 'Security\IdTlsServerOptions.pas', - IdTraceRoute in 'Core\IdTraceRoute.pas', - IdTrivialFTP in 'Protocols\IdTrivialFTP.pas', - IdTrivialFTPBase in 'Protocols\IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'Protocols\IdTrivialFTPServer.pas', - IdUDPBase in 'Core\IdUDPBase.pas', - IdUDPClient in 'Core\IdUDPClient.pas', - IdUDPServer in 'Core\IdUDPServer.pas', - IdURI in 'Protocols\IdURI.pas', - IdUnixTime in 'Protocols\IdUnixTime.pas', - IdUnixTimeServer in 'Protocols\IdUnixTimeServer.pas', - IdUnixTimeUDP in 'Protocols\IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'Protocols\IdUnixTimeUDPServer.pas', - IdUriUtils in 'Protocols\IdUriUtils.pas', - IdUserAccounts in 'Protocols\IdUserAccounts.pas', - IdUserPassProvider in 'Protocols\IdUserPassProvider.pas', - IdVCard in 'Protocols\IdVCard.pas', - IdWebDAV in 'Protocols\IdWebDAV.pas', - IdWhoIsServer in 'Protocols\IdWhoIsServer.pas', - IdWhois in 'Protocols\IdWhois.pas', - IdYarn in 'Core\IdYarn.pas', - IdZLibCompressorBase in 'Protocols\IdZLibCompressorBase.pas'; - -end. +package Indy100Net; + +{$ALIGN 0} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Master'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + Borland.Delphi, + Borland.Vcl, + Borland.VclRtl; + +contains + IdASN1Util in 'Protocols\IdASN1Util.pas', + IdAllAuthentications in 'Protocols\IdAllAuthentications.pas', + IdAllFTPListParsers in 'Protocols\IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'Protocols\IdAllHeaderCoders.pas', + IdAntiFreezeBase in 'System\IdAntiFreezeBase.pas', + IdAssignedNumbers in 'Core\IdAssignedNumbers.pas', + IdAttachment in 'Protocols\IdAttachment.pas', + IdAttachmentFile in 'Protocols\IdAttachmentFile.pas', + IdAttachmentMemory in 'Protocols\IdAttachmentMemory.pas', + IdAuthentication in 'Protocols\IdAuthentication.pas', + IdAuthenticationDigest in 'Protocols\IdAuthenticationDigest.pas', + IdAuthenticationManager in 'Protocols\IdAuthenticationManager.pas', + IdBaseComponent in 'System\IdBaseComponent.pas', + IdBlockCipherIntercept in 'Protocols\IdBlockCipherIntercept.pas', + IdBuffer in 'Core\IdBuffer.pas', + IdCarrierStream in 'Security\IdCarrierStream.pas', + IdChargenServer in 'Protocols\IdChargenServer.pas', + IdChargenUDPServer in 'Protocols\IdChargenUDPServer.pas', + IdCharsets in 'Protocols\IdCharsets.pas', + IdCmdTCPClient in 'Core\IdCmdTCPClient.pas', + IdCmdTCPServer in 'Core\IdCmdTCPServer.pas', + IdCoder in 'Protocols\IdCoder.pas', + IdCoder00E in 'Protocols\IdCoder00E.pas', + IdCoder3to4 in 'Protocols\IdCoder3to4.pas', + IdCoderBinHex4 in 'Protocols\IdCoderBinHex4.pas', + IdCoderHeader in 'Protocols\IdCoderHeader.pas', + IdCoderMIME in 'Protocols\IdCoderMIME.pas', + IdCoderQuotedPrintable in 'Protocols\IdCoderQuotedPrintable.pas', + IdCoderUUE in 'Protocols\IdCoderUUE.pas', + IdCoderXXE in 'Protocols\IdCoderXXE.pas', + IdCommandHandlers in 'Core\IdCommandHandlers.pas', + IdComponent in 'System\IdComponent.pas', + IdConnectThroughHttpProxy in 'Protocols\IdConnectThroughHttpProxy.pas', + IdContainers in 'Protocols\IdContainers.pas', + IdContext in 'Core\IdContext.pas', + IdCookie in 'Protocols\IdCookie.pas', + IdCookieManager in 'Protocols\IdCookieManager.pas', + IdCustomHTTPServer in 'Protocols\IdCustomHTTPServer.pas', + IdCustomTCPServer in 'Core\IdCustomTCPServer.pas', + IdCustomTransparentProxy in 'Core\IdCustomTransparentProxy.pas', + IdDICT in 'Protocols\IdDICT.pas', + IdDICTCommon in 'Protocols\IdDICTCommon.pas', + IdDICTServer in 'Protocols\IdDICTServer.pas', + IdDNSCommon in 'Protocols\IdDNSCommon.pas', + IdDNSResolver in 'Protocols\IdDNSResolver.pas', + IdDNSServer in 'Protocols\IdDNSServer.pas', + IdDateTimeStamp in 'Protocols\IdDateTimeStamp.pas', + IdDayTime in 'Protocols\IdDayTime.pas', + IdDayTimeServer in 'Protocols\IdDayTimeServer.pas', + IdDayTimeUDP in 'Protocols\IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'Protocols\IdDayTimeUDPServer.pas', + IdDiscardServer in 'Protocols\IdDiscardServer.pas', + IdDiscardUDPServer in 'Protocols\IdDiscardUDPServer.pas', + IdEMailAddress in 'Protocols\IdEMailAddress.pas', + IdEcho in 'Protocols\IdEcho.pas', + IdEchoServer in 'Protocols\IdEchoServer.pas', + IdEchoUDP in 'Protocols\IdEchoUDP.pas', + IdEchoUDPServer in 'Protocols\IdEchoUDPServer.pas', + IdException in 'System\IdException.pas', + IdExceptionCore in 'Core\IdExceptionCore.pas', + IdExplicitTLSClientServerBase in 'Protocols\IdExplicitTLSClientServerBase.pas', + IdFIPS in 'Protocols\IdFIPS.pas', + IdFSP in 'Protocols\IdFSP.pas', + IdFTP in 'Protocols\IdFTP.pas', + IdFTPBaseFileSystem in 'Protocols\IdFTPBaseFileSystem.pas', + IdFTPCommon in 'Protocols\IdFTPCommon.pas', + IdFTPList in 'Protocols\IdFTPList.pas', + IdFTPListOutput in 'Protocols\IdFTPListOutput.pas', + IdFTPListParseAS400 in 'Protocols\IdFTPListParseAS400.pas', + IdFTPListParseBase in 'Protocols\IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'Protocols\IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'Protocols\IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'Protocols\IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'Protocols\IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'Protocols\IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'Protocols\IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'Protocols\IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'Protocols\IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'Protocols\IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'Protocols\IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'Protocols\IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'Protocols\IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'Protocols\IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'Protocols\IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'Protocols\IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'Protocols\IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'Protocols\IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'Protocols\IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'Protocols\IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'Protocols\IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'Protocols\IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'Protocols\IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'Protocols\IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'Protocols\IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'Protocols\IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'Protocols\IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'Protocols\IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'Protocols\IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'Protocols\IdFTPListParseUnix.pas', + IdFTPListParseVM in 'Protocols\IdFTPListParseVM.pas', + IdFTPListParseVMS in 'Protocols\IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'Protocols\IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'Protocols\IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'Protocols\IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'Protocols\IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'Protocols\IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'Protocols\IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'Protocols\IdFTPListTypes.pas', + IdFTPServer in 'Protocols\IdFTPServer.pas', + IdFTPServerContextBase in 'Protocols\IdFTPServerContextBase.pas', + IdFinger in 'Protocols\IdFinger.pas', + IdFingerServer in 'Protocols\IdFingerServer.pas', + IdGlobal in 'System\IdGlobal.pas', + IdGlobalCore in 'Core\IdGlobalCore.pas', + IdGlobalProtocols in 'Protocols\IdGlobalProtocols.pas', + IdGopher in 'Protocols\IdGopher.pas', + IdGopherConsts in 'Protocols\IdGopherConsts.pas', + IdGopherServer in 'Protocols\IdGopherServer.pas', + IdHL7 in 'Protocols\IdHL7.pas', + IdHMAC in 'Protocols\IdHMAC.pas', + IdHMACMD5 in 'Protocols\IdHMACMD5.pas', + IdHMACSHA1 in 'Protocols\IdHMACSHA1.pas', + IdHTTP in 'Protocols\IdHTTP.pas', + IdHTTPHeaderInfo in 'Protocols\IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'Protocols\IdHTTPHelper.pas', + IdHTTPProxyServer in 'Protocols\IdHTTPProxyServer.pas', + IdHTTPServer in 'Protocols\IdHTTPServer.pas', + IdHash in 'Protocols\IdHash.pas', + IdHashCRC in 'Protocols\IdHashCRC.pas', + IdHashElf in 'Protocols\IdHashElf.pas', + IdHashMessageDigest in 'Protocols\IdHashMessageDigest.pas', + IdHashSHA in 'Protocols\IdHashSHA.pas', + IdHeaderCoder2022JP in 'Protocols\IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'Protocols\IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'Protocols\IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'Protocols\IdHeaderCoderPlain.pas', + IdHeaderList in 'Protocols\IdHeaderList.pas', + IdIMAP4 in 'Protocols\IdIMAP4.pas', + IdIMAP4Server in 'Protocols\IdIMAP4Server.pas', + IdIOHandler in 'Core\IdIOHandler.pas', + IdIOHandlerSocket in 'Core\IdIOHandlerSocket.pas', + IdIOHandlerStack in 'Core\IdIOHandlerStack.pas', + IdIOHandlerStream in 'Core\IdIOHandlerStream.pas', + IdIOHandlerTls in 'Security\IdIOHandlerTls.pas', + IdIPAddrMon in 'Protocols\IdIPAddrMon.pas', + IdIPAddress in 'Core\IdIPAddress.pas', + IdIPMCastBase in 'Core\IdIPMCastBase.pas', + IdIPMCastClient in 'Core\IdIPMCastClient.pas', + IdIPMCastServer in 'Core\IdIPMCastServer.pas', + IdIPWatch in 'Protocols\IdIPWatch.pas', + IdIRC in 'Protocols\IdIRC.pas', + IdIcmpClient in 'Core\IdIcmpClient.pas', + IdIdent in 'Protocols\IdIdent.pas', + IdIdentServer in 'Protocols\IdIdentServer.pas', + IdIntercept in 'Core\IdIntercept.pas', + IdInterceptSimLog in 'Core\IdInterceptSimLog.pas', + IdInterceptThrottler in 'Core\IdInterceptThrottler.pas', + IdIrcServer in 'Protocols\IdIrcServer.pas', + IdLPR in 'Protocols\IdLPR.pas', + IdLogBase in 'Core\IdLogBase.pas', + IdLogDebug in 'Core\IdLogDebug.pas', + IdLogEvent in 'Core\IdLogEvent.pas', + IdLogFile in 'Core\IdLogFile.pas', + IdLogStream in 'Core\IdLogStream.pas', + IdMailBox in 'Protocols\IdMailBox.pas', + IdMappedFTP in 'Protocols\IdMappedFTP.pas', + IdMappedPOP3 in 'Protocols\IdMappedPOP3.pas', + IdMappedPortTCP in 'Protocols\IdMappedPortTCP.pas', + IdMappedPortUDP in 'Protocols\IdMappedPortUDP.pas', + IdMappedTelnet in 'Protocols\IdMappedTelnet.pas', + IdMessage in 'Protocols\IdMessage.pas', + IdMessageBuilder in 'Protocols\IdMessageBuilder.pas', + IdMessageClient in 'Protocols\IdMessageClient.pas', + IdMessageCoder in 'Protocols\IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'Protocols\IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'Protocols\IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'Protocols\IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'Protocols\IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'Protocols\IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'Protocols\IdMessageCoderYenc.pas', + IdMessageCollection in 'Protocols\IdMessageCollection.pas', + IdMessageHelper in 'Protocols\IdMessageHelper.pas', + IdMessageParts in 'Protocols\IdMessageParts.pas', + IdMultipartFormData in 'Protocols\IdMultipartFormData.pas', + IdNNTP in 'Protocols\IdNNTP.pas', + IdNNTPServer in 'Protocols\IdNNTPServer.pas', + IdNetworkCalculator in 'Protocols\IdNetworkCalculator.pas', + IdOSFileName in 'Protocols\IdOSFileName.pas', + IdOTPCalculator in 'Protocols\IdOTPCalculator.pas', + IdPOP3 in 'Protocols\IdPOP3.pas', + IdPOP3Server in 'Protocols\IdPOP3Server.pas', + IdQOTDUDP in 'Protocols\IdQOTDUDP.pas', + IdQOTDUDPServer in 'Protocols\IdQOTDUDPServer.pas', + IdQotd in 'Protocols\IdQotd.pas', + IdQotdServer in 'Protocols\IdQotdServer.pas', + IdRSH in 'Protocols\IdRSH.pas', + IdRSHServer in 'Protocols\IdRSHServer.pas', + IdRawBase in 'Core\IdRawBase.pas', + IdRawClient in 'Core\IdRawClient.pas', + IdRawFunctions in 'Core\IdRawFunctions.pas', + IdRawHeaders in 'Core\IdRawHeaders.pas', + IdRemoteCMDClient in 'Protocols\IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'Protocols\IdRemoteCMDServer.pas', + IdReply in 'Core\IdReply.pas', + IdReplyFTP in 'Protocols\IdReplyFTP.pas', + IdReplyIMAP4 in 'Protocols\IdReplyIMAP4.pas', + IdReplyPOP3 in 'Protocols\IdReplyPOP3.pas', + IdReplyRFC in 'Core\IdReplyRFC.pas', + IdReplySMTP in 'Protocols\IdReplySMTP.pas', + IdResourceStrings in 'System\IdResourceStrings.pas', + IdResourceStringsCore in 'Core\IdResourceStringsCore.pas', + IdResourceStringsProtocols in 'Protocols\IdResourceStringsProtocols.pas', + IdRexec in 'Protocols\IdRexec.pas', + IdRexecServer in 'Protocols\IdRexecServer.pas', + IdSASL in 'Protocols\IdSASL.pas', + IdSASLAnonymous in 'Protocols\IdSASLAnonymous.pas', + IdSASLCollection in 'Protocols\IdSASLCollection.pas', + IdSASLDigest in 'Protocols\IdSASLDigest.pas', + IdSASLExternal in 'Protocols\IdSASLExternal.pas', + IdSASLLogin in 'Protocols\IdSASLLogin.pas', + IdSASLOAuth in 'Protocols\IdSASLOAuth.pas', + IdSASLOTP in 'Protocols\IdSASLOTP.pas', + IdSASLPlain in 'Protocols\IdSASLPlain.pas', + IdSASLSKey in 'Protocols\IdSASLSKey.pas', + IdSASLUserPass in 'Protocols\IdSASLUserPass.pas', + IdSASL_CRAMBase in 'Protocols\IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'Protocols\IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'Protocols\IdSASL_CRAM_SHA1.pas', + IdSMTP in 'Protocols\IdSMTP.pas', + IdSMTPBase in 'Protocols\IdSMTPBase.pas', + IdSMTPRelay in 'Protocols\IdSMTPRelay.pas', + IdSMTPServer in 'Protocols\IdSMTPServer.pas', + IdSNPP in 'Protocols\IdSNPP.pas', + IdSNTP in 'Protocols\IdSNTP.pas', + IdSSL in 'Protocols\IdSSL.pas', + IdSSLDotNET in 'Protocols\IdSSLDotNET.pas', + IdScheduler in 'Core\IdScheduler.pas', + IdSchedulerOfThread in 'Core\IdSchedulerOfThread.pas', + IdSchedulerOfThreadDefault in 'Core\IdSchedulerOfThreadDefault.pas', + IdSchedulerOfThreadPool in 'Core\IdSchedulerOfThreadPool.pas', + IdServerIOHandler in 'Core\IdServerIOHandler.pas', + IdServerIOHandlerSocket in 'Core\IdServerIOHandlerSocket.pas', + IdServerIOHandlerStack in 'Core\IdServerIOHandlerStack.pas', + IdServerIOHandlerTls in 'Security\IdServerIOHandlerTls.pas', + IdServerInterceptLogBase in 'Protocols\IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'Protocols\IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'Protocols\IdServerInterceptLogFile.pas', + IdSimpleServer in 'Core\IdSimpleServer.pas', + IdSocketHandle in 'Core\IdSocketHandle.pas', + IdSocketStream in 'Security\IdSocketStream.pas', + IdSocks in 'Core\IdSocks.pas', + IdSocksServer in 'Protocols\IdSocksServer.pas', + IdStack in 'System\IdStack.pas', + IdStackConsts in 'System\IdStackConsts.pas', + IdStackDotNet in 'System\IdStackDotNet.pas', + IdStream in 'System\IdStream.pas', + IdStreamNET in 'System\IdStreamNET.pas', + IdStrings in 'Protocols\IdStrings.pas', + IdStruct in 'System\IdStruct.pas', + IdSync in 'Core\IdSync.pas', + IdSysLog in 'Protocols\IdSysLog.pas', + IdSysLogMessage in 'Protocols\IdSysLogMessage.pas', + IdSysLogServer in 'Protocols\IdSysLogServer.pas', + IdSystat in 'Protocols\IdSystat.pas', + IdSystatServer in 'Protocols\IdSystatServer.pas', + IdSystatUDP in 'Protocols\IdSystatUDP.pas', + IdSystatUDPServer in 'Protocols\IdSystatUDPServer.pas', + IdTCPClient in 'Core\IdTCPClient.pas', + IdTCPConnection in 'Core\IdTCPConnection.pas', + IdTCPServer in 'Core\IdTCPServer.pas', + IdTCPStream in 'Core\IdTCPStream.pas', + IdTask in 'Core\IdTask.pas', + IdTelnet in 'Protocols\IdTelnet.pas', + IdTelnetServer in 'Protocols\IdTelnetServer.pas', + IdText in 'Protocols\IdText.pas', + IdThread in 'Core\IdThread.pas', + IdThreadComponent in 'Core\IdThreadComponent.pas', + IdThreadSafe in 'Core\IdThreadSafe.pas', + IdTime in 'Protocols\IdTime.pas', + IdTimeServer in 'Protocols\IdTimeServer.pas', + IdTimeUDP in 'Protocols\IdTimeUDP.pas', + IdTimeUDPServer in 'Protocols\IdTimeUDPServer.pas', + IdTlsClientOptions in 'Security\IdTlsClientOptions.pas', + IdTlsServerOptions in 'Security\IdTlsServerOptions.pas', + IdTraceRoute in 'Core\IdTraceRoute.pas', + IdTrivialFTP in 'Protocols\IdTrivialFTP.pas', + IdTrivialFTPBase in 'Protocols\IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'Protocols\IdTrivialFTPServer.pas', + IdUDPBase in 'Core\IdUDPBase.pas', + IdUDPClient in 'Core\IdUDPClient.pas', + IdUDPServer in 'Core\IdUDPServer.pas', + IdURI in 'Protocols\IdURI.pas', + IdUnixTime in 'Protocols\IdUnixTime.pas', + IdUnixTimeServer in 'Protocols\IdUnixTimeServer.pas', + IdUnixTimeUDP in 'Protocols\IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'Protocols\IdUnixTimeUDPServer.pas', + IdUriUtils in 'Protocols\IdUriUtils.pas', + IdUserAccounts in 'Protocols\IdUserAccounts.pas', + IdUserPassProvider in 'Protocols\IdUserPassProvider.pas', + IdVCard in 'Protocols\IdVCard.pas', + IdWebDAV in 'Protocols\IdWebDAV.pas', + IdWhoIsServer in 'Protocols\IdWhoIsServer.pas', + IdWhois in 'Protocols\IdWhois.pas', + IdYarn in 'Core\IdYarn.pas', + IdZLibCompressorBase in 'Protocols\IdZLibCompressorBase.pas'; + +end. diff --git a/Lib/Indy110Net.dpk b/Lib/Indy110Net.dpk index b1139dcdb..3acb1b22d 100644 --- a/Lib/Indy110Net.dpk +++ b/Lib/Indy110Net.dpk @@ -1,335 +1,335 @@ -package Indy110Net; - -{$ALIGN 0} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Master'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - Borland.Delphi, - Borland.Vcl, - Borland.VclRtl; - -contains - IdASN1Util in 'Protocols\IdASN1Util.pas', - IdAllAuthentications in 'Protocols\IdAllAuthentications.pas', - IdAllFTPListParsers in 'Protocols\IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'Protocols\IdAllHeaderCoders.pas', - IdAntiFreezeBase in 'System\IdAntiFreezeBase.pas', - IdAssignedNumbers in 'Core\IdAssignedNumbers.pas', - IdAttachment in 'Protocols\IdAttachment.pas', - IdAttachmentFile in 'Protocols\IdAttachmentFile.pas', - IdAttachmentMemory in 'Protocols\IdAttachmentMemory.pas', - IdAuthentication in 'Protocols\IdAuthentication.pas', - IdAuthenticationDigest in 'Protocols\IdAuthenticationDigest.pas', - IdAuthenticationManager in 'Protocols\IdAuthenticationManager.pas', - IdBaseComponent in 'System\IdBaseComponent.pas', - IdBlockCipherIntercept in 'Protocols\IdBlockCipherIntercept.pas', - IdBuffer in 'Core\IdBuffer.pas', - IdCarrierStream in 'Security\IdCarrierStream.pas', - IdChargenServer in 'Protocols\IdChargenServer.pas', - IdChargenUDPServer in 'Protocols\IdChargenUDPServer.pas', - IdCharsets in 'Protocols\IdCharsets.pas', - IdCmdTCPClient in 'Core\IdCmdTCPClient.pas', - IdCmdTCPServer in 'Core\IdCmdTCPServer.pas', - IdCoder in 'Protocols\IdCoder.pas', - IdCoder00E in 'Protocols\IdCoder00E.pas', - IdCoder3to4 in 'Protocols\IdCoder3to4.pas', - IdCoderBinHex4 in 'Protocols\IdCoderBinHex4.pas', - IdCoderHeader in 'Protocols\IdCoderHeader.pas', - IdCoderMIME in 'Protocols\IdCoderMIME.pas', - IdCoderQuotedPrintable in 'Protocols\IdCoderQuotedPrintable.pas', - IdCoderUUE in 'Protocols\IdCoderUUE.pas', - IdCoderXXE in 'Protocols\IdCoderXXE.pas', - IdCommandHandlers in 'Core\IdCommandHandlers.pas', - IdComponent in 'System\IdComponent.pas', - IdConnectThroughHttpProxy in 'Protocols\IdConnectThroughHttpProxy.pas', - IdContainers in 'Protocols\IdContainers.pas', - IdContext in 'Core\IdContext.pas', - IdCookie in 'Protocols\IdCookie.pas', - IdCookieManager in 'Protocols\IdCookieManager.pas', - IdCustomHTTPServer in 'Protocols\IdCustomHTTPServer.pas', - IdCustomTCPServer in 'Core\IdCustomTCPServer.pas', - IdCustomTransparentProxy in 'Core\IdCustomTransparentProxy.pas', - IdDICT in 'Protocols\IdDICT.pas', - IdDICTCommon in 'Protocols\IdDICTCommon.pas', - IdDICTServer in 'Protocols\IdDICTServer.pas', - IdDNSCommon in 'Protocols\IdDNSCommon.pas', - IdDNSResolver in 'Protocols\IdDNSResolver.pas', - IdDNSServer in 'Protocols\IdDNSServer.pas', - IdDateTimeStamp in 'Protocols\IdDateTimeStamp.pas', - IdDayTime in 'Protocols\IdDayTime.pas', - IdDayTimeServer in 'Protocols\IdDayTimeServer.pas', - IdDayTimeUDP in 'Protocols\IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'Protocols\IdDayTimeUDPServer.pas', - IdDiscardServer in 'Protocols\IdDiscardServer.pas', - IdDiscardUDPServer in 'Protocols\IdDiscardUDPServer.pas', - IdEMailAddress in 'Protocols\IdEMailAddress.pas', - IdEcho in 'Protocols\IdEcho.pas', - IdEchoServer in 'Protocols\IdEchoServer.pas', - IdEchoUDP in 'Protocols\IdEchoUDP.pas', - IdEchoUDPServer in 'Protocols\IdEchoUDPServer.pas', - IdException in 'System\IdException.pas', - IdExceptionCore in 'Core\IdExceptionCore.pas', - IdExplicitTLSClientServerBase in 'Protocols\IdExplicitTLSClientServerBase.pas', - IdFIPS in 'Protocols\IdFIPS.pas', - IdFSP in 'Protocols\IdFSP.pas', - IdFTP in 'Protocols\IdFTP.pas', - IdFTPBaseFileSystem in 'Protocols\IdFTPBaseFileSystem.pas', - IdFTPCommon in 'Protocols\IdFTPCommon.pas', - IdFTPList in 'Protocols\IdFTPList.pas', - IdFTPListOutput in 'Protocols\IdFTPListOutput.pas', - IdFTPListParseAS400 in 'Protocols\IdFTPListParseAS400.pas', - IdFTPListParseBase in 'Protocols\IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'Protocols\IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'Protocols\IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'Protocols\IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'Protocols\IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'Protocols\IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'Protocols\IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'Protocols\IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'Protocols\IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'Protocols\IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'Protocols\IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'Protocols\IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'Protocols\IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'Protocols\IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'Protocols\IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'Protocols\IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'Protocols\IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'Protocols\IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'Protocols\IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'Protocols\IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'Protocols\IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'Protocols\IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'Protocols\IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'Protocols\IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'Protocols\IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'Protocols\IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'Protocols\IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'Protocols\IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'Protocols\IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'Protocols\IdFTPListParseUnix.pas', - IdFTPListParseVM in 'Protocols\IdFTPListParseVM.pas', - IdFTPListParseVMS in 'Protocols\IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'Protocols\IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'Protocols\IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'Protocols\IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'Protocols\IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'Protocols\IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'Protocols\IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'Protocols\IdFTPListTypes.pas', - IdFTPServer in 'Protocols\IdFTPServer.pas', - IdFTPServerContextBase in 'Protocols\IdFTPServerContextBase.pas', - IdFinger in 'Protocols\IdFinger.pas', - IdFingerServer in 'Protocols\IdFingerServer.pas', - IdGlobal in 'System\IdGlobal.pas', - IdGlobalCore in 'Core\IdGlobalCore.pas', - IdGlobalProtocols in 'Protocols\IdGlobalProtocols.pas', - IdGopher in 'Protocols\IdGopher.pas', - IdGopherConsts in 'Protocols\IdGopherConsts.pas', - IdGopherServer in 'Protocols\IdGopherServer.pas', - IdHL7 in 'Protocols\IdHL7.pas', - IdHMAC in 'Protocols\IdHMAC.pas', - IdHMACMD5 in 'Protocols\IdHMACMD5.pas', - IdHMACSHA1 in 'Protocols\IdHMACSHA1.pas', - IdHTTP in 'Protocols\IdHTTP.pas', - IdHTTPHeaderInfo in 'Protocols\IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'Protocols\IdHTTPHelper.pas', - IdHTTPProxyServer in 'Protocols\IdHTTPProxyServer.pas', - IdHTTPServer in 'Protocols\IdHTTPServer.pas', - IdHash in 'Protocols\IdHash.pas', - IdHashCRC in 'Protocols\IdHashCRC.pas', - IdHashElf in 'Protocols\IdHashElf.pas', - IdHashMessageDigest in 'Protocols\IdHashMessageDigest.pas', - IdHashSHA in 'Protocols\IdHashSHA.pas', - IdHeaderCoder2022JP in 'Protocols\IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'Protocols\IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'Protocols\IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'Protocols\IdHeaderCoderPlain.pas', - IdHeaderList in 'Protocols\IdHeaderList.pas', - IdIMAP4 in 'Protocols\IdIMAP4.pas', - IdIMAP4Server in 'Protocols\IdIMAP4Server.pas', - IdIOHandler in 'Core\IdIOHandler.pas', - IdIOHandlerSocket in 'Core\IdIOHandlerSocket.pas', - IdIOHandlerStack in 'Core\IdIOHandlerStack.pas', - IdIOHandlerStream in 'Core\IdIOHandlerStream.pas', - IdIOHandlerTls in 'Security\IdIOHandlerTls.pas', - IdIPAddrMon in 'Protocols\IdIPAddrMon.pas', - IdIPAddress in 'Core\IdIPAddress.pas', - IdIPMCastBase in 'Core\IdIPMCastBase.pas', - IdIPMCastClient in 'Core\IdIPMCastClient.pas', - IdIPMCastServer in 'Core\IdIPMCastServer.pas', - IdIPWatch in 'Protocols\IdIPWatch.pas', - IdIRC in 'Protocols\IdIRC.pas', - IdIcmpClient in 'Core\IdIcmpClient.pas', - IdIdent in 'Protocols\IdIdent.pas', - IdIdentServer in 'Protocols\IdIdentServer.pas', - IdIntercept in 'Core\IdIntercept.pas', - IdInterceptSimLog in 'Core\IdInterceptSimLog.pas', - IdInterceptThrottler in 'Core\IdInterceptThrottler.pas', - IdIrcServer in 'Protocols\IdIrcServer.pas', - IdLPR in 'Protocols\IdLPR.pas', - IdLogBase in 'Core\IdLogBase.pas', - IdLogDebug in 'Core\IdLogDebug.pas', - IdLogEvent in 'Core\IdLogEvent.pas', - IdLogFile in 'Core\IdLogFile.pas', - IdLogStream in 'Core\IdLogStream.pas', - IdMailBox in 'Protocols\IdMailBox.pas', - IdMappedFTP in 'Protocols\IdMappedFTP.pas', - IdMappedPOP3 in 'Protocols\IdMappedPOP3.pas', - IdMappedPortTCP in 'Protocols\IdMappedPortTCP.pas', - IdMappedPortUDP in 'Protocols\IdMappedPortUDP.pas', - IdMappedTelnet in 'Protocols\IdMappedTelnet.pas', - IdMessage in 'Protocols\IdMessage.pas', - IdMessageBuilder in 'Protocols\IdMessageBuilder.pas', - IdMessageClient in 'Protocols\IdMessageClient.pas', - IdMessageCoder in 'Protocols\IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'Protocols\IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'Protocols\IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'Protocols\IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'Protocols\IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'Protocols\IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'Protocols\IdMessageCoderYenc.pas', - IdMessageCollection in 'Protocols\IdMessageCollection.pas', - IdMessageHelper in 'Protocols\IdMessageHelper.pas', - IdMessageParts in 'Protocols\IdMessageParts.pas', - IdMultipartFormData in 'Protocols\IdMultipartFormData.pas', - IdNNTP in 'Protocols\IdNNTP.pas', - IdNNTPServer in 'Protocols\IdNNTPServer.pas', - IdNetworkCalculator in 'Protocols\IdNetworkCalculator.pas', - IdOSFileName in 'Protocols\IdOSFileName.pas', - IdOTPCalculator in 'Protocols\IdOTPCalculator.pas', - IdPOP3 in 'Protocols\IdPOP3.pas', - IdPOP3Server in 'Protocols\IdPOP3Server.pas', - IdQOTDUDP in 'Protocols\IdQOTDUDP.pas', - IdQOTDUDPServer in 'Protocols\IdQOTDUDPServer.pas', - IdQotd in 'Protocols\IdQotd.pas', - IdQotdServer in 'Protocols\IdQotdServer.pas', - IdRSH in 'Protocols\IdRSH.pas', - IdRSHServer in 'Protocols\IdRSHServer.pas', - IdRawBase in 'Core\IdRawBase.pas', - IdRawClient in 'Core\IdRawClient.pas', - IdRawFunctions in 'Core\IdRawFunctions.pas', - IdRawHeaders in 'Core\IdRawHeaders.pas', - IdRemoteCMDClient in 'Protocols\IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'Protocols\IdRemoteCMDServer.pas', - IdReply in 'Core\IdReply.pas', - IdReplyFTP in 'Protocols\IdReplyFTP.pas', - IdReplyIMAP4 in 'Protocols\IdReplyIMAP4.pas', - IdReplyPOP3 in 'Protocols\IdReplyPOP3.pas', - IdReplyRFC in 'Core\IdReplyRFC.pas', - IdReplySMTP in 'Protocols\IdReplySMTP.pas', - IdResourceStrings in 'System\IdResourceStrings.pas', - IdResourceStringsCore in 'Core\IdResourceStringsCore.pas', - IdResourceStringsProtocols in 'Protocols\IdResourceStringsProtocols.pas', - IdRexec in 'Protocols\IdRexec.pas', - IdRexecServer in 'Protocols\IdRexecServer.pas', - IdSASL in 'Protocols\IdSASL.pas', - IdSASLAnonymous in 'Protocols\IdSASLAnonymous.pas', - IdSASLCollection in 'Protocols\IdSASLCollection.pas', - IdSASLDigest in 'Protocols\IdSASLDigest.pas', - IdSASLExternal in 'Protocols\IdSASLExternal.pas', - IdSASLLogin in 'Protocols\IdSASLLogin.pas', - IdSASLOAuth in 'Protocols\IdSASLOAuth.pas', - IdSASLOTP in 'Protocols\IdSASLOTP.pas', - IdSASLPlain in 'Protocols\IdSASLPlain.pas', - IdSASLSKey in 'Protocols\IdSASLSKey.pas', - IdSASLUserPass in 'Protocols\IdSASLUserPass.pas', - IdSASL_CRAMBase in 'Protocols\IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'Protocols\IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'Protocols\IdSASL_CRAM_SHA1.pas', - IdSMTP in 'Protocols\IdSMTP.pas', - IdSMTPBase in 'Protocols\IdSMTPBase.pas', - IdSMTPRelay in 'Protocols\IdSMTPRelay.pas', - IdSMTPServer in 'Protocols\IdSMTPServer.pas', - IdSNPP in 'Protocols\IdSNPP.pas', - IdSNTP in 'Protocols\IdSNTP.pas', - IdSSL in 'Protocols\IdSSL.pas', - IdSSLDotNET in 'Protocols\IdSSLDotNET.pas', - IdScheduler in 'Core\IdScheduler.pas', - IdSchedulerOfThread in 'Core\IdSchedulerOfThread.pas', - IdSchedulerOfThreadDefault in 'Core\IdSchedulerOfThreadDefault.pas', - IdSchedulerOfThreadPool in 'Core\IdSchedulerOfThreadPool.pas', - IdServerIOHandler in 'Core\IdServerIOHandler.pas', - IdServerIOHandlerSocket in 'Core\IdServerIOHandlerSocket.pas', - IdServerIOHandlerStack in 'Core\IdServerIOHandlerStack.pas', - IdServerIOHandlerTls in 'Security\IdServerIOHandlerTls.pas', - IdServerInterceptLogBase in 'Protocols\IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'Protocols\IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'Protocols\IdServerInterceptLogFile.pas', - IdSimpleServer in 'Core\IdSimpleServer.pas', - IdSocketHandle in 'Core\IdSocketHandle.pas', - IdSocketStream in 'Security\IdSocketStream.pas', - IdSocks in 'Core\IdSocks.pas', - IdSocksServer in 'Protocols\IdSocksServer.pas', - IdStack in 'System\IdStack.pas', - IdStackConsts in 'System\IdStackConsts.pas', - IdStackDotNet in 'System\IdStackDotNet.pas', - IdStream in 'System\IdStream.pas', - IdStreamNET in 'System\IdStreamNET.pas', - IdStrings in 'Protocols\IdStrings.pas', - IdStruct in 'System\IdStruct.pas', - IdSync in 'Core\IdSync.pas', - IdSysLog in 'Protocols\IdSysLog.pas', - IdSysLogMessage in 'Protocols\IdSysLogMessage.pas', - IdSysLogServer in 'Protocols\IdSysLogServer.pas', - IdSystat in 'Protocols\IdSystat.pas', - IdSystatServer in 'Protocols\IdSystatServer.pas', - IdSystatUDP in 'Protocols\IdSystatUDP.pas', - IdSystatUDPServer in 'Protocols\IdSystatUDPServer.pas', - IdTCPClient in 'Core\IdTCPClient.pas', - IdTCPConnection in 'Core\IdTCPConnection.pas', - IdTCPServer in 'Core\IdTCPServer.pas', - IdTCPStream in 'Core\IdTCPStream.pas', - IdTask in 'Core\IdTask.pas', - IdTelnet in 'Protocols\IdTelnet.pas', - IdTelnetServer in 'Protocols\IdTelnetServer.pas', - IdText in 'Protocols\IdText.pas', - IdThread in 'Core\IdThread.pas', - IdThreadComponent in 'Core\IdThreadComponent.pas', - IdThreadSafe in 'Core\IdThreadSafe.pas', - IdTime in 'Protocols\IdTime.pas', - IdTimeServer in 'Protocols\IdTimeServer.pas', - IdTimeUDP in 'Protocols\IdTimeUDP.pas', - IdTimeUDPServer in 'Protocols\IdTimeUDPServer.pas', - IdTlsClientOptions in 'Security\IdTlsClientOptions.pas', - IdTlsServerOptions in 'Security\IdTlsServerOptions.pas', - IdTraceRoute in 'Core\IdTraceRoute.pas', - IdTrivialFTP in 'Protocols\IdTrivialFTP.pas', - IdTrivialFTPBase in 'Protocols\IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'Protocols\IdTrivialFTPServer.pas', - IdUDPBase in 'Core\IdUDPBase.pas', - IdUDPClient in 'Core\IdUDPClient.pas', - IdUDPServer in 'Core\IdUDPServer.pas', - IdURI in 'Protocols\IdURI.pas', - IdUnixTime in 'Protocols\IdUnixTime.pas', - IdUnixTimeServer in 'Protocols\IdUnixTimeServer.pas', - IdUnixTimeUDP in 'Protocols\IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'Protocols\IdUnixTimeUDPServer.pas', - IdUriUtils in 'Protocols\IdUriUtils.pas', - IdUserAccounts in 'Protocols\IdUserAccounts.pas', - IdUserPassProvider in 'Protocols\IdUserPassProvider.pas', - IdVCard in 'Protocols\IdVCard.pas', - IdWebDAV in 'Protocols\IdWebDAV.pas', - IdWhoIsServer in 'Protocols\IdWhoIsServer.pas', - IdWhois in 'Protocols\IdWhois.pas', - IdYarn in 'Core\IdYarn.pas', - IdZLibCompressorBase in 'Protocols\IdZLibCompressorBase.pas'; - -end. +package Indy110Net; + +{$ALIGN 0} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Master'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + Borland.Delphi, + Borland.Vcl, + Borland.VclRtl; + +contains + IdASN1Util in 'Protocols\IdASN1Util.pas', + IdAllAuthentications in 'Protocols\IdAllAuthentications.pas', + IdAllFTPListParsers in 'Protocols\IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'Protocols\IdAllHeaderCoders.pas', + IdAntiFreezeBase in 'System\IdAntiFreezeBase.pas', + IdAssignedNumbers in 'Core\IdAssignedNumbers.pas', + IdAttachment in 'Protocols\IdAttachment.pas', + IdAttachmentFile in 'Protocols\IdAttachmentFile.pas', + IdAttachmentMemory in 'Protocols\IdAttachmentMemory.pas', + IdAuthentication in 'Protocols\IdAuthentication.pas', + IdAuthenticationDigest in 'Protocols\IdAuthenticationDigest.pas', + IdAuthenticationManager in 'Protocols\IdAuthenticationManager.pas', + IdBaseComponent in 'System\IdBaseComponent.pas', + IdBlockCipherIntercept in 'Protocols\IdBlockCipherIntercept.pas', + IdBuffer in 'Core\IdBuffer.pas', + IdCarrierStream in 'Security\IdCarrierStream.pas', + IdChargenServer in 'Protocols\IdChargenServer.pas', + IdChargenUDPServer in 'Protocols\IdChargenUDPServer.pas', + IdCharsets in 'Protocols\IdCharsets.pas', + IdCmdTCPClient in 'Core\IdCmdTCPClient.pas', + IdCmdTCPServer in 'Core\IdCmdTCPServer.pas', + IdCoder in 'Protocols\IdCoder.pas', + IdCoder00E in 'Protocols\IdCoder00E.pas', + IdCoder3to4 in 'Protocols\IdCoder3to4.pas', + IdCoderBinHex4 in 'Protocols\IdCoderBinHex4.pas', + IdCoderHeader in 'Protocols\IdCoderHeader.pas', + IdCoderMIME in 'Protocols\IdCoderMIME.pas', + IdCoderQuotedPrintable in 'Protocols\IdCoderQuotedPrintable.pas', + IdCoderUUE in 'Protocols\IdCoderUUE.pas', + IdCoderXXE in 'Protocols\IdCoderXXE.pas', + IdCommandHandlers in 'Core\IdCommandHandlers.pas', + IdComponent in 'System\IdComponent.pas', + IdConnectThroughHttpProxy in 'Protocols\IdConnectThroughHttpProxy.pas', + IdContainers in 'Protocols\IdContainers.pas', + IdContext in 'Core\IdContext.pas', + IdCookie in 'Protocols\IdCookie.pas', + IdCookieManager in 'Protocols\IdCookieManager.pas', + IdCustomHTTPServer in 'Protocols\IdCustomHTTPServer.pas', + IdCustomTCPServer in 'Core\IdCustomTCPServer.pas', + IdCustomTransparentProxy in 'Core\IdCustomTransparentProxy.pas', + IdDICT in 'Protocols\IdDICT.pas', + IdDICTCommon in 'Protocols\IdDICTCommon.pas', + IdDICTServer in 'Protocols\IdDICTServer.pas', + IdDNSCommon in 'Protocols\IdDNSCommon.pas', + IdDNSResolver in 'Protocols\IdDNSResolver.pas', + IdDNSServer in 'Protocols\IdDNSServer.pas', + IdDateTimeStamp in 'Protocols\IdDateTimeStamp.pas', + IdDayTime in 'Protocols\IdDayTime.pas', + IdDayTimeServer in 'Protocols\IdDayTimeServer.pas', + IdDayTimeUDP in 'Protocols\IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'Protocols\IdDayTimeUDPServer.pas', + IdDiscardServer in 'Protocols\IdDiscardServer.pas', + IdDiscardUDPServer in 'Protocols\IdDiscardUDPServer.pas', + IdEMailAddress in 'Protocols\IdEMailAddress.pas', + IdEcho in 'Protocols\IdEcho.pas', + IdEchoServer in 'Protocols\IdEchoServer.pas', + IdEchoUDP in 'Protocols\IdEchoUDP.pas', + IdEchoUDPServer in 'Protocols\IdEchoUDPServer.pas', + IdException in 'System\IdException.pas', + IdExceptionCore in 'Core\IdExceptionCore.pas', + IdExplicitTLSClientServerBase in 'Protocols\IdExplicitTLSClientServerBase.pas', + IdFIPS in 'Protocols\IdFIPS.pas', + IdFSP in 'Protocols\IdFSP.pas', + IdFTP in 'Protocols\IdFTP.pas', + IdFTPBaseFileSystem in 'Protocols\IdFTPBaseFileSystem.pas', + IdFTPCommon in 'Protocols\IdFTPCommon.pas', + IdFTPList in 'Protocols\IdFTPList.pas', + IdFTPListOutput in 'Protocols\IdFTPListOutput.pas', + IdFTPListParseAS400 in 'Protocols\IdFTPListParseAS400.pas', + IdFTPListParseBase in 'Protocols\IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'Protocols\IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'Protocols\IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'Protocols\IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'Protocols\IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'Protocols\IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'Protocols\IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'Protocols\IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'Protocols\IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'Protocols\IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'Protocols\IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'Protocols\IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'Protocols\IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'Protocols\IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'Protocols\IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'Protocols\IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'Protocols\IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'Protocols\IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'Protocols\IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'Protocols\IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'Protocols\IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'Protocols\IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'Protocols\IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'Protocols\IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'Protocols\IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'Protocols\IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'Protocols\IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'Protocols\IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'Protocols\IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'Protocols\IdFTPListParseUnix.pas', + IdFTPListParseVM in 'Protocols\IdFTPListParseVM.pas', + IdFTPListParseVMS in 'Protocols\IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'Protocols\IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'Protocols\IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'Protocols\IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'Protocols\IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'Protocols\IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'Protocols\IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'Protocols\IdFTPListTypes.pas', + IdFTPServer in 'Protocols\IdFTPServer.pas', + IdFTPServerContextBase in 'Protocols\IdFTPServerContextBase.pas', + IdFinger in 'Protocols\IdFinger.pas', + IdFingerServer in 'Protocols\IdFingerServer.pas', + IdGlobal in 'System\IdGlobal.pas', + IdGlobalCore in 'Core\IdGlobalCore.pas', + IdGlobalProtocols in 'Protocols\IdGlobalProtocols.pas', + IdGopher in 'Protocols\IdGopher.pas', + IdGopherConsts in 'Protocols\IdGopherConsts.pas', + IdGopherServer in 'Protocols\IdGopherServer.pas', + IdHL7 in 'Protocols\IdHL7.pas', + IdHMAC in 'Protocols\IdHMAC.pas', + IdHMACMD5 in 'Protocols\IdHMACMD5.pas', + IdHMACSHA1 in 'Protocols\IdHMACSHA1.pas', + IdHTTP in 'Protocols\IdHTTP.pas', + IdHTTPHeaderInfo in 'Protocols\IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'Protocols\IdHTTPHelper.pas', + IdHTTPProxyServer in 'Protocols\IdHTTPProxyServer.pas', + IdHTTPServer in 'Protocols\IdHTTPServer.pas', + IdHash in 'Protocols\IdHash.pas', + IdHashCRC in 'Protocols\IdHashCRC.pas', + IdHashElf in 'Protocols\IdHashElf.pas', + IdHashMessageDigest in 'Protocols\IdHashMessageDigest.pas', + IdHashSHA in 'Protocols\IdHashSHA.pas', + IdHeaderCoder2022JP in 'Protocols\IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'Protocols\IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'Protocols\IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'Protocols\IdHeaderCoderPlain.pas', + IdHeaderList in 'Protocols\IdHeaderList.pas', + IdIMAP4 in 'Protocols\IdIMAP4.pas', + IdIMAP4Server in 'Protocols\IdIMAP4Server.pas', + IdIOHandler in 'Core\IdIOHandler.pas', + IdIOHandlerSocket in 'Core\IdIOHandlerSocket.pas', + IdIOHandlerStack in 'Core\IdIOHandlerStack.pas', + IdIOHandlerStream in 'Core\IdIOHandlerStream.pas', + IdIOHandlerTls in 'Security\IdIOHandlerTls.pas', + IdIPAddrMon in 'Protocols\IdIPAddrMon.pas', + IdIPAddress in 'Core\IdIPAddress.pas', + IdIPMCastBase in 'Core\IdIPMCastBase.pas', + IdIPMCastClient in 'Core\IdIPMCastClient.pas', + IdIPMCastServer in 'Core\IdIPMCastServer.pas', + IdIPWatch in 'Protocols\IdIPWatch.pas', + IdIRC in 'Protocols\IdIRC.pas', + IdIcmpClient in 'Core\IdIcmpClient.pas', + IdIdent in 'Protocols\IdIdent.pas', + IdIdentServer in 'Protocols\IdIdentServer.pas', + IdIntercept in 'Core\IdIntercept.pas', + IdInterceptSimLog in 'Core\IdInterceptSimLog.pas', + IdInterceptThrottler in 'Core\IdInterceptThrottler.pas', + IdIrcServer in 'Protocols\IdIrcServer.pas', + IdLPR in 'Protocols\IdLPR.pas', + IdLogBase in 'Core\IdLogBase.pas', + IdLogDebug in 'Core\IdLogDebug.pas', + IdLogEvent in 'Core\IdLogEvent.pas', + IdLogFile in 'Core\IdLogFile.pas', + IdLogStream in 'Core\IdLogStream.pas', + IdMailBox in 'Protocols\IdMailBox.pas', + IdMappedFTP in 'Protocols\IdMappedFTP.pas', + IdMappedPOP3 in 'Protocols\IdMappedPOP3.pas', + IdMappedPortTCP in 'Protocols\IdMappedPortTCP.pas', + IdMappedPortUDP in 'Protocols\IdMappedPortUDP.pas', + IdMappedTelnet in 'Protocols\IdMappedTelnet.pas', + IdMessage in 'Protocols\IdMessage.pas', + IdMessageBuilder in 'Protocols\IdMessageBuilder.pas', + IdMessageClient in 'Protocols\IdMessageClient.pas', + IdMessageCoder in 'Protocols\IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'Protocols\IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'Protocols\IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'Protocols\IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'Protocols\IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'Protocols\IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'Protocols\IdMessageCoderYenc.pas', + IdMessageCollection in 'Protocols\IdMessageCollection.pas', + IdMessageHelper in 'Protocols\IdMessageHelper.pas', + IdMessageParts in 'Protocols\IdMessageParts.pas', + IdMultipartFormData in 'Protocols\IdMultipartFormData.pas', + IdNNTP in 'Protocols\IdNNTP.pas', + IdNNTPServer in 'Protocols\IdNNTPServer.pas', + IdNetworkCalculator in 'Protocols\IdNetworkCalculator.pas', + IdOSFileName in 'Protocols\IdOSFileName.pas', + IdOTPCalculator in 'Protocols\IdOTPCalculator.pas', + IdPOP3 in 'Protocols\IdPOP3.pas', + IdPOP3Server in 'Protocols\IdPOP3Server.pas', + IdQOTDUDP in 'Protocols\IdQOTDUDP.pas', + IdQOTDUDPServer in 'Protocols\IdQOTDUDPServer.pas', + IdQotd in 'Protocols\IdQotd.pas', + IdQotdServer in 'Protocols\IdQotdServer.pas', + IdRSH in 'Protocols\IdRSH.pas', + IdRSHServer in 'Protocols\IdRSHServer.pas', + IdRawBase in 'Core\IdRawBase.pas', + IdRawClient in 'Core\IdRawClient.pas', + IdRawFunctions in 'Core\IdRawFunctions.pas', + IdRawHeaders in 'Core\IdRawHeaders.pas', + IdRemoteCMDClient in 'Protocols\IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'Protocols\IdRemoteCMDServer.pas', + IdReply in 'Core\IdReply.pas', + IdReplyFTP in 'Protocols\IdReplyFTP.pas', + IdReplyIMAP4 in 'Protocols\IdReplyIMAP4.pas', + IdReplyPOP3 in 'Protocols\IdReplyPOP3.pas', + IdReplyRFC in 'Core\IdReplyRFC.pas', + IdReplySMTP in 'Protocols\IdReplySMTP.pas', + IdResourceStrings in 'System\IdResourceStrings.pas', + IdResourceStringsCore in 'Core\IdResourceStringsCore.pas', + IdResourceStringsProtocols in 'Protocols\IdResourceStringsProtocols.pas', + IdRexec in 'Protocols\IdRexec.pas', + IdRexecServer in 'Protocols\IdRexecServer.pas', + IdSASL in 'Protocols\IdSASL.pas', + IdSASLAnonymous in 'Protocols\IdSASLAnonymous.pas', + IdSASLCollection in 'Protocols\IdSASLCollection.pas', + IdSASLDigest in 'Protocols\IdSASLDigest.pas', + IdSASLExternal in 'Protocols\IdSASLExternal.pas', + IdSASLLogin in 'Protocols\IdSASLLogin.pas', + IdSASLOAuth in 'Protocols\IdSASLOAuth.pas', + IdSASLOTP in 'Protocols\IdSASLOTP.pas', + IdSASLPlain in 'Protocols\IdSASLPlain.pas', + IdSASLSKey in 'Protocols\IdSASLSKey.pas', + IdSASLUserPass in 'Protocols\IdSASLUserPass.pas', + IdSASL_CRAMBase in 'Protocols\IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'Protocols\IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'Protocols\IdSASL_CRAM_SHA1.pas', + IdSMTP in 'Protocols\IdSMTP.pas', + IdSMTPBase in 'Protocols\IdSMTPBase.pas', + IdSMTPRelay in 'Protocols\IdSMTPRelay.pas', + IdSMTPServer in 'Protocols\IdSMTPServer.pas', + IdSNPP in 'Protocols\IdSNPP.pas', + IdSNTP in 'Protocols\IdSNTP.pas', + IdSSL in 'Protocols\IdSSL.pas', + IdSSLDotNET in 'Protocols\IdSSLDotNET.pas', + IdScheduler in 'Core\IdScheduler.pas', + IdSchedulerOfThread in 'Core\IdSchedulerOfThread.pas', + IdSchedulerOfThreadDefault in 'Core\IdSchedulerOfThreadDefault.pas', + IdSchedulerOfThreadPool in 'Core\IdSchedulerOfThreadPool.pas', + IdServerIOHandler in 'Core\IdServerIOHandler.pas', + IdServerIOHandlerSocket in 'Core\IdServerIOHandlerSocket.pas', + IdServerIOHandlerStack in 'Core\IdServerIOHandlerStack.pas', + IdServerIOHandlerTls in 'Security\IdServerIOHandlerTls.pas', + IdServerInterceptLogBase in 'Protocols\IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'Protocols\IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'Protocols\IdServerInterceptLogFile.pas', + IdSimpleServer in 'Core\IdSimpleServer.pas', + IdSocketHandle in 'Core\IdSocketHandle.pas', + IdSocketStream in 'Security\IdSocketStream.pas', + IdSocks in 'Core\IdSocks.pas', + IdSocksServer in 'Protocols\IdSocksServer.pas', + IdStack in 'System\IdStack.pas', + IdStackConsts in 'System\IdStackConsts.pas', + IdStackDotNet in 'System\IdStackDotNet.pas', + IdStream in 'System\IdStream.pas', + IdStreamNET in 'System\IdStreamNET.pas', + IdStrings in 'Protocols\IdStrings.pas', + IdStruct in 'System\IdStruct.pas', + IdSync in 'Core\IdSync.pas', + IdSysLog in 'Protocols\IdSysLog.pas', + IdSysLogMessage in 'Protocols\IdSysLogMessage.pas', + IdSysLogServer in 'Protocols\IdSysLogServer.pas', + IdSystat in 'Protocols\IdSystat.pas', + IdSystatServer in 'Protocols\IdSystatServer.pas', + IdSystatUDP in 'Protocols\IdSystatUDP.pas', + IdSystatUDPServer in 'Protocols\IdSystatUDPServer.pas', + IdTCPClient in 'Core\IdTCPClient.pas', + IdTCPConnection in 'Core\IdTCPConnection.pas', + IdTCPServer in 'Core\IdTCPServer.pas', + IdTCPStream in 'Core\IdTCPStream.pas', + IdTask in 'Core\IdTask.pas', + IdTelnet in 'Protocols\IdTelnet.pas', + IdTelnetServer in 'Protocols\IdTelnetServer.pas', + IdText in 'Protocols\IdText.pas', + IdThread in 'Core\IdThread.pas', + IdThreadComponent in 'Core\IdThreadComponent.pas', + IdThreadSafe in 'Core\IdThreadSafe.pas', + IdTime in 'Protocols\IdTime.pas', + IdTimeServer in 'Protocols\IdTimeServer.pas', + IdTimeUDP in 'Protocols\IdTimeUDP.pas', + IdTimeUDPServer in 'Protocols\IdTimeUDPServer.pas', + IdTlsClientOptions in 'Security\IdTlsClientOptions.pas', + IdTlsServerOptions in 'Security\IdTlsServerOptions.pas', + IdTraceRoute in 'Core\IdTraceRoute.pas', + IdTrivialFTP in 'Protocols\IdTrivialFTP.pas', + IdTrivialFTPBase in 'Protocols\IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'Protocols\IdTrivialFTPServer.pas', + IdUDPBase in 'Core\IdUDPBase.pas', + IdUDPClient in 'Core\IdUDPClient.pas', + IdUDPServer in 'Core\IdUDPServer.pas', + IdURI in 'Protocols\IdURI.pas', + IdUnixTime in 'Protocols\IdUnixTime.pas', + IdUnixTimeServer in 'Protocols\IdUnixTimeServer.pas', + IdUnixTimeUDP in 'Protocols\IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'Protocols\IdUnixTimeUDPServer.pas', + IdUriUtils in 'Protocols\IdUriUtils.pas', + IdUserAccounts in 'Protocols\IdUserAccounts.pas', + IdUserPassProvider in 'Protocols\IdUserPassProvider.pas', + IdVCard in 'Protocols\IdVCard.pas', + IdWebDAV in 'Protocols\IdWebDAV.pas', + IdWhoIsServer in 'Protocols\IdWhoIsServer.pas', + IdWhois in 'Protocols\IdWhois.pas', + IdYarn in 'Core\IdYarn.pas', + IdZLibCompressorBase in 'Protocols\IdZLibCompressorBase.pas'; + +end. diff --git a/Lib/Indy90Net.dpk b/Lib/Indy90Net.dpk index f590d09ef..6c06368e2 100644 --- a/Lib/Indy90Net.dpk +++ b/Lib/Indy90Net.dpk @@ -1,335 +1,335 @@ -package Indy90Net; - -{$ALIGN 0} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Master'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - Borland.Delphi, - Borland.Vcl, - Borland.VclRtl; - -contains - IdASN1Util in 'Protocols\IdASN1Util.pas', - IdAllAuthentications in 'Protocols\IdAllAuthentications.pas', - IdAllFTPListParsers in 'Protocols\IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'Protocols\IdAllHeaderCoders.pas', - IdAntiFreezeBase in 'System\IdAntiFreezeBase.pas', - IdAssignedNumbers in 'Core\IdAssignedNumbers.pas', - IdAttachment in 'Protocols\IdAttachment.pas', - IdAttachmentFile in 'Protocols\IdAttachmentFile.pas', - IdAttachmentMemory in 'Protocols\IdAttachmentMemory.pas', - IdAuthentication in 'Protocols\IdAuthentication.pas', - IdAuthenticationDigest in 'Protocols\IdAuthenticationDigest.pas', - IdAuthenticationManager in 'Protocols\IdAuthenticationManager.pas', - IdBaseComponent in 'System\IdBaseComponent.pas', - IdBlockCipherIntercept in 'Protocols\IdBlockCipherIntercept.pas', - IdBuffer in 'Core\IdBuffer.pas', - IdCarrierStream in 'Security\IdCarrierStream.pas', - IdChargenServer in 'Protocols\IdChargenServer.pas', - IdChargenUDPServer in 'Protocols\IdChargenUDPServer.pas', - IdCharsets in 'Protocols\IdCharsets.pas', - IdCmdTCPClient in 'Core\IdCmdTCPClient.pas', - IdCmdTCPServer in 'Core\IdCmdTCPServer.pas', - IdCoder in 'Protocols\IdCoder.pas', - IdCoder00E in 'Protocols\IdCoder00E.pas', - IdCoder3to4 in 'Protocols\IdCoder3to4.pas', - IdCoderBinHex4 in 'Protocols\IdCoderBinHex4.pas', - IdCoderHeader in 'Protocols\IdCoderHeader.pas', - IdCoderMIME in 'Protocols\IdCoderMIME.pas', - IdCoderQuotedPrintable in 'Protocols\IdCoderQuotedPrintable.pas', - IdCoderUUE in 'Protocols\IdCoderUUE.pas', - IdCoderXXE in 'Protocols\IdCoderXXE.pas', - IdCommandHandlers in 'Core\IdCommandHandlers.pas', - IdComponent in 'System\IdComponent.pas', - IdConnectThroughHttpProxy in 'Protocols\IdConnectThroughHttpProxy.pas', - IdContainers in 'Protocols\IdContainers.pas', - IdContext in 'Core\IdContext.pas', - IdCookie in 'Protocols\IdCookie.pas', - IdCookieManager in 'Protocols\IdCookieManager.pas', - IdCustomHTTPServer in 'Protocols\IdCustomHTTPServer.pas', - IdCustomTCPServer in 'Core\IdCustomTCPServer.pas', - IdCustomTransparentProxy in 'Core\IdCustomTransparentProxy.pas', - IdDICT in 'Protocols\IdDICT.pas', - IdDICTCommon in 'Protocols\IdDICTCommon.pas', - IdDICTServer in 'Protocols\IdDICTServer.pas', - IdDNSCommon in 'Protocols\IdDNSCommon.pas', - IdDNSResolver in 'Protocols\IdDNSResolver.pas', - IdDNSServer in 'Protocols\IdDNSServer.pas', - IdDateTimeStamp in 'Protocols\IdDateTimeStamp.pas', - IdDayTime in 'Protocols\IdDayTime.pas', - IdDayTimeServer in 'Protocols\IdDayTimeServer.pas', - IdDayTimeUDP in 'Protocols\IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'Protocols\IdDayTimeUDPServer.pas', - IdDiscardServer in 'Protocols\IdDiscardServer.pas', - IdDiscardUDPServer in 'Protocols\IdDiscardUDPServer.pas', - IdEMailAddress in 'Protocols\IdEMailAddress.pas', - IdEcho in 'Protocols\IdEcho.pas', - IdEchoServer in 'Protocols\IdEchoServer.pas', - IdEchoUDP in 'Protocols\IdEchoUDP.pas', - IdEchoUDPServer in 'Protocols\IdEchoUDPServer.pas', - IdException in 'System\IdException.pas', - IdExceptionCore in 'Core\IdExceptionCore.pas', - IdExplicitTLSClientServerBase in 'Protocols\IdExplicitTLSClientServerBase.pas', - IdFIPS in 'Protocols\IdFIPS.pas', - IdFSP in 'Protocols\IdFSP.pas', - IdFTP in 'Protocols\IdFTP.pas', - IdFTPBaseFileSystem in 'Protocols\IdFTPBaseFileSystem.pas', - IdFTPCommon in 'Protocols\IdFTPCommon.pas', - IdFTPList in 'Protocols\IdFTPList.pas', - IdFTPListOutput in 'Protocols\IdFTPListOutput.pas', - IdFTPListParseAS400 in 'Protocols\IdFTPListParseAS400.pas', - IdFTPListParseBase in 'Protocols\IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'Protocols\IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'Protocols\IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'Protocols\IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'Protocols\IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'Protocols\IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'Protocols\IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'Protocols\IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'Protocols\IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'Protocols\IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'Protocols\IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'Protocols\IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'Protocols\IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'Protocols\IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'Protocols\IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'Protocols\IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'Protocols\IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'Protocols\IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'Protocols\IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'Protocols\IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'Protocols\IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'Protocols\IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'Protocols\IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'Protocols\IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'Protocols\IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'Protocols\IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'Protocols\IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'Protocols\IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'Protocols\IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'Protocols\IdFTPListParseUnix.pas', - IdFTPListParseVM in 'Protocols\IdFTPListParseVM.pas', - IdFTPListParseVMS in 'Protocols\IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'Protocols\IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'Protocols\IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'Protocols\IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'Protocols\IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'Protocols\IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'Protocols\IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'Protocols\IdFTPListTypes.pas', - IdFTPServer in 'Protocols\IdFTPServer.pas', - IdFTPServerContextBase in 'Protocols\IdFTPServerContextBase.pas', - IdFinger in 'Protocols\IdFinger.pas', - IdFingerServer in 'Protocols\IdFingerServer.pas', - IdGlobal in 'System\IdGlobal.pas', - IdGlobalCore in 'Core\IdGlobalCore.pas', - IdGlobalProtocols in 'Protocols\IdGlobalProtocols.pas', - IdGopher in 'Protocols\IdGopher.pas', - IdGopherConsts in 'Protocols\IdGopherConsts.pas', - IdGopherServer in 'Protocols\IdGopherServer.pas', - IdHL7 in 'Protocols\IdHL7.pas', - IdHMAC in 'Protocols\IdHMAC.pas', - IdHMACMD5 in 'Protocols\IdHMACMD5.pas', - IdHMACSHA1 in 'Protocols\IdHMACSHA1.pas', - IdHTTP in 'Protocols\IdHTTP.pas', - IdHTTPHeaderInfo in 'Protocols\IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'Protocols\IdHTTPHelper.pas', - IdHTTPProxyServer in 'Protocols\IdHTTPProxyServer.pas', - IdHTTPServer in 'Protocols\IdHTTPServer.pas', - IdHash in 'Protocols\IdHash.pas', - IdHashCRC in 'Protocols\IdHashCRC.pas', - IdHashElf in 'Protocols\IdHashElf.pas', - IdHashMessageDigest in 'Protocols\IdHashMessageDigest.pas', - IdHashSHA in 'Protocols\IdHashSHA.pas', - IdHeaderCoder2022JP in 'Protocols\IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'Protocols\IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'Protocols\IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'Protocols\IdHeaderCoderPlain.pas', - IdHeaderList in 'Protocols\IdHeaderList.pas', - IdIMAP4 in 'Protocols\IdIMAP4.pas', - IdIMAP4Server in 'Protocols\IdIMAP4Server.pas', - IdIOHandler in 'Core\IdIOHandler.pas', - IdIOHandlerSocket in 'Core\IdIOHandlerSocket.pas', - IdIOHandlerStack in 'Core\IdIOHandlerStack.pas', - IdIOHandlerStream in 'Core\IdIOHandlerStream.pas', - IdIOHandlerTls in 'Security\IdIOHandlerTls.pas', - IdIPAddrMon in 'Protocols\IdIPAddrMon.pas', - IdIPAddress in 'Core\IdIPAddress.pas', - IdIPMCastBase in 'Core\IdIPMCastBase.pas', - IdIPMCastClient in 'Core\IdIPMCastClient.pas', - IdIPMCastServer in 'Core\IdIPMCastServer.pas', - IdIPWatch in 'Protocols\IdIPWatch.pas', - IdIRC in 'Protocols\IdIRC.pas', - IdIcmpClient in 'Core\IdIcmpClient.pas', - IdIdent in 'Protocols\IdIdent.pas', - IdIdentServer in 'Protocols\IdIdentServer.pas', - IdIntercept in 'Core\IdIntercept.pas', - IdInterceptSimLog in 'Core\IdInterceptSimLog.pas', - IdInterceptThrottler in 'Core\IdInterceptThrottler.pas', - IdIrcServer in 'Protocols\IdIrcServer.pas', - IdLPR in 'Protocols\IdLPR.pas', - IdLogBase in 'Core\IdLogBase.pas', - IdLogDebug in 'Core\IdLogDebug.pas', - IdLogEvent in 'Core\IdLogEvent.pas', - IdLogFile in 'Core\IdLogFile.pas', - IdLogStream in 'Core\IdLogStream.pas', - IdMailBox in 'Protocols\IdMailBox.pas', - IdMappedFTP in 'Protocols\IdMappedFTP.pas', - IdMappedPOP3 in 'Protocols\IdMappedPOP3.pas', - IdMappedPortTCP in 'Protocols\IdMappedPortTCP.pas', - IdMappedPortUDP in 'Protocols\IdMappedPortUDP.pas', - IdMappedTelnet in 'Protocols\IdMappedTelnet.pas', - IdMessage in 'Protocols\IdMessage.pas', - IdMessageBuilder in 'Protocols\IdMessageBuilder.pas', - IdMessageClient in 'Protocols\IdMessageClient.pas', - IdMessageCoder in 'Protocols\IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'Protocols\IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'Protocols\IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'Protocols\IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'Protocols\IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'Protocols\IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'Protocols\IdMessageCoderYenc.pas', - IdMessageCollection in 'Protocols\IdMessageCollection.pas', - IdMessageHelper in 'Protocols\IdMessageHelper.pas', - IdMessageParts in 'Protocols\IdMessageParts.pas', - IdMultipartFormData in 'Protocols\IdMultipartFormData.pas', - IdNNTP in 'Protocols\IdNNTP.pas', - IdNNTPServer in 'Protocols\IdNNTPServer.pas', - IdNetworkCalculator in 'Protocols\IdNetworkCalculator.pas', - IdOSFileName in 'Protocols\IdOSFileName.pas', - IdOTPCalculator in 'Protocols\IdOTPCalculator.pas', - IdPOP3 in 'Protocols\IdPOP3.pas', - IdPOP3Server in 'Protocols\IdPOP3Server.pas', - IdQOTDUDP in 'Protocols\IdQOTDUDP.pas', - IdQOTDUDPServer in 'Protocols\IdQOTDUDPServer.pas', - IdQotd in 'Protocols\IdQotd.pas', - IdQotdServer in 'Protocols\IdQotdServer.pas', - IdRSH in 'Protocols\IdRSH.pas', - IdRSHServer in 'Protocols\IdRSHServer.pas', - IdRawBase in 'Core\IdRawBase.pas', - IdRawClient in 'Core\IdRawClient.pas', - IdRawFunctions in 'Core\IdRawFunctions.pas', - IdRawHeaders in 'Core\IdRawHeaders.pas', - IdRemoteCMDClient in 'Protocols\IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'Protocols\IdRemoteCMDServer.pas', - IdReply in 'Core\IdReply.pas', - IdReplyFTP in 'Protocols\IdReplyFTP.pas', - IdReplyIMAP4 in 'Protocols\IdReplyIMAP4.pas', - IdReplyPOP3 in 'Protocols\IdReplyPOP3.pas', - IdReplyRFC in 'Core\IdReplyRFC.pas', - IdReplySMTP in 'Protocols\IdReplySMTP.pas', - IdResourceStrings in 'System\IdResourceStrings.pas', - IdResourceStringsCore in 'Core\IdResourceStringsCore.pas', - IdResourceStringsProtocols in 'Protocols\IdResourceStringsProtocols.pas', - IdRexec in 'Protocols\IdRexec.pas', - IdRexecServer in 'Protocols\IdRexecServer.pas', - IdSASL in 'Protocols\IdSASL.pas', - IdSASLAnonymous in 'Protocols\IdSASLAnonymous.pas', - IdSASLCollection in 'Protocols\IdSASLCollection.pas', - IdSASLDigest in 'Protocols\IdSASLDigest.pas', - IdSASLExternal in 'Protocols\IdSASLExternal.pas', - IdSASLLogin in 'Protocols\IdSASLLogin.pas', - IdSASLOAuth in 'Protocols\IdSASLOAuth.pas', - IdSASLOTP in 'Protocols\IdSASLOTP.pas', - IdSASLPlain in 'Protocols\IdSASLPlain.pas', - IdSASLSKey in 'Protocols\IdSASLSKey.pas', - IdSASLUserPass in 'Protocols\IdSASLUserPass.pas', - IdSASL_CRAMBase in 'Protocols\IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'Protocols\IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'Protocols\IdSASL_CRAM_SHA1.pas', - IdSMTP in 'Protocols\IdSMTP.pas', - IdSMTPBase in 'Protocols\IdSMTPBase.pas', - IdSMTPRelay in 'Protocols\IdSMTPRelay.pas', - IdSMTPServer in 'Protocols\IdSMTPServer.pas', - IdSNPP in 'Protocols\IdSNPP.pas', - IdSNTP in 'Protocols\IdSNTP.pas', - IdSSL in 'Protocols\IdSSL.pas', - IdSSLDotNET in 'Protocols\IdSSLDotNET.pas', - IdScheduler in 'Core\IdScheduler.pas', - IdSchedulerOfThread in 'Core\IdSchedulerOfThread.pas', - IdSchedulerOfThreadDefault in 'Core\IdSchedulerOfThreadDefault.pas', - IdSchedulerOfThreadPool in 'Core\IdSchedulerOfThreadPool.pas', - IdServerIOHandler in 'Core\IdServerIOHandler.pas', - IdServerIOHandlerSocket in 'Core\IdServerIOHandlerSocket.pas', - IdServerIOHandlerStack in 'Core\IdServerIOHandlerStack.pas', - IdServerIOHandlerTls in 'Security\IdServerIOHandlerTls.pas', - IdServerInterceptLogBase in 'Protocols\IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'Protocols\IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'Protocols\IdServerInterceptLogFile.pas', - IdSimpleServer in 'Core\IdSimpleServer.pas', - IdSocketHandle in 'Core\IdSocketHandle.pas', - IdSocketStream in 'Security\IdSocketStream.pas', - IdSocks in 'Core\IdSocks.pas', - IdSocksServer in 'Protocols\IdSocksServer.pas', - IdStack in 'System\IdStack.pas', - IdStackConsts in 'System\IdStackConsts.pas', - IdStackDotNet in 'System\IdStackDotNet.pas', - IdStream in 'System\IdStream.pas', - IdStreamNET in 'System\IdStreamNET.pas', - IdStrings in 'Protocols\IdStrings.pas', - IdStruct in 'System\IdStruct.pas', - IdSync in 'Core\IdSync.pas', - IdSysLog in 'Protocols\IdSysLog.pas', - IdSysLogMessage in 'Protocols\IdSysLogMessage.pas', - IdSysLogServer in 'Protocols\IdSysLogServer.pas', - IdSystat in 'Protocols\IdSystat.pas', - IdSystatServer in 'Protocols\IdSystatServer.pas', - IdSystatUDP in 'Protocols\IdSystatUDP.pas', - IdSystatUDPServer in 'Protocols\IdSystatUDPServer.pas', - IdTCPClient in 'Core\IdTCPClient.pas', - IdTCPConnection in 'Core\IdTCPConnection.pas', - IdTCPServer in 'Core\IdTCPServer.pas', - IdTCPStream in 'Core\IdTCPStream.pas', - IdTask in 'Core\IdTask.pas', - IdTelnet in 'Protocols\IdTelnet.pas', - IdTelnetServer in 'Protocols\IdTelnetServer.pas', - IdText in 'Protocols\IdText.pas', - IdThread in 'Core\IdThread.pas', - IdThreadComponent in 'Core\IdThreadComponent.pas', - IdThreadSafe in 'Core\IdThreadSafe.pas', - IdTime in 'Protocols\IdTime.pas', - IdTimeServer in 'Protocols\IdTimeServer.pas', - IdTimeUDP in 'Protocols\IdTimeUDP.pas', - IdTimeUDPServer in 'Protocols\IdTimeUDPServer.pas', - IdTlsClientOptions in 'Security\IdTlsClientOptions.pas', - IdTlsServerOptions in 'Security\IdTlsServerOptions.pas', - IdTraceRoute in 'Core\IdTraceRoute.pas', - IdTrivialFTP in 'Protocols\IdTrivialFTP.pas', - IdTrivialFTPBase in 'Protocols\IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'Protocols\IdTrivialFTPServer.pas', - IdUDPBase in 'Core\IdUDPBase.pas', - IdUDPClient in 'Core\IdUDPClient.pas', - IdUDPServer in 'Core\IdUDPServer.pas', - IdURI in 'Protocols\IdURI.pas', - IdUnixTime in 'Protocols\IdUnixTime.pas', - IdUnixTimeServer in 'Protocols\IdUnixTimeServer.pas', - IdUnixTimeUDP in 'Protocols\IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'Protocols\IdUnixTimeUDPServer.pas', - IdUriUtils in 'Protocols\IdUriUtils.pas', - IdUserAccounts in 'Protocols\IdUserAccounts.pas', - IdUserPassProvider in 'Protocols\IdUserPassProvider.pas', - IdVCard in 'Protocols\IdVCard.pas', - IdWebDAV in 'Protocols\IdWebDAV.pas', - IdWhoIsServer in 'Protocols\IdWhoIsServer.pas', - IdWhois in 'Protocols\IdWhois.pas', - IdYarn in 'Core\IdYarn.pas', - IdZLibCompressorBase in 'Protocols\IdZLibCompressorBase.pas'; - -end. +package Indy90Net; + +{$ALIGN 0} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Master'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + Borland.Delphi, + Borland.Vcl, + Borland.VclRtl; + +contains + IdASN1Util in 'Protocols\IdASN1Util.pas', + IdAllAuthentications in 'Protocols\IdAllAuthentications.pas', + IdAllFTPListParsers in 'Protocols\IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'Protocols\IdAllHeaderCoders.pas', + IdAntiFreezeBase in 'System\IdAntiFreezeBase.pas', + IdAssignedNumbers in 'Core\IdAssignedNumbers.pas', + IdAttachment in 'Protocols\IdAttachment.pas', + IdAttachmentFile in 'Protocols\IdAttachmentFile.pas', + IdAttachmentMemory in 'Protocols\IdAttachmentMemory.pas', + IdAuthentication in 'Protocols\IdAuthentication.pas', + IdAuthenticationDigest in 'Protocols\IdAuthenticationDigest.pas', + IdAuthenticationManager in 'Protocols\IdAuthenticationManager.pas', + IdBaseComponent in 'System\IdBaseComponent.pas', + IdBlockCipherIntercept in 'Protocols\IdBlockCipherIntercept.pas', + IdBuffer in 'Core\IdBuffer.pas', + IdCarrierStream in 'Security\IdCarrierStream.pas', + IdChargenServer in 'Protocols\IdChargenServer.pas', + IdChargenUDPServer in 'Protocols\IdChargenUDPServer.pas', + IdCharsets in 'Protocols\IdCharsets.pas', + IdCmdTCPClient in 'Core\IdCmdTCPClient.pas', + IdCmdTCPServer in 'Core\IdCmdTCPServer.pas', + IdCoder in 'Protocols\IdCoder.pas', + IdCoder00E in 'Protocols\IdCoder00E.pas', + IdCoder3to4 in 'Protocols\IdCoder3to4.pas', + IdCoderBinHex4 in 'Protocols\IdCoderBinHex4.pas', + IdCoderHeader in 'Protocols\IdCoderHeader.pas', + IdCoderMIME in 'Protocols\IdCoderMIME.pas', + IdCoderQuotedPrintable in 'Protocols\IdCoderQuotedPrintable.pas', + IdCoderUUE in 'Protocols\IdCoderUUE.pas', + IdCoderXXE in 'Protocols\IdCoderXXE.pas', + IdCommandHandlers in 'Core\IdCommandHandlers.pas', + IdComponent in 'System\IdComponent.pas', + IdConnectThroughHttpProxy in 'Protocols\IdConnectThroughHttpProxy.pas', + IdContainers in 'Protocols\IdContainers.pas', + IdContext in 'Core\IdContext.pas', + IdCookie in 'Protocols\IdCookie.pas', + IdCookieManager in 'Protocols\IdCookieManager.pas', + IdCustomHTTPServer in 'Protocols\IdCustomHTTPServer.pas', + IdCustomTCPServer in 'Core\IdCustomTCPServer.pas', + IdCustomTransparentProxy in 'Core\IdCustomTransparentProxy.pas', + IdDICT in 'Protocols\IdDICT.pas', + IdDICTCommon in 'Protocols\IdDICTCommon.pas', + IdDICTServer in 'Protocols\IdDICTServer.pas', + IdDNSCommon in 'Protocols\IdDNSCommon.pas', + IdDNSResolver in 'Protocols\IdDNSResolver.pas', + IdDNSServer in 'Protocols\IdDNSServer.pas', + IdDateTimeStamp in 'Protocols\IdDateTimeStamp.pas', + IdDayTime in 'Protocols\IdDayTime.pas', + IdDayTimeServer in 'Protocols\IdDayTimeServer.pas', + IdDayTimeUDP in 'Protocols\IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'Protocols\IdDayTimeUDPServer.pas', + IdDiscardServer in 'Protocols\IdDiscardServer.pas', + IdDiscardUDPServer in 'Protocols\IdDiscardUDPServer.pas', + IdEMailAddress in 'Protocols\IdEMailAddress.pas', + IdEcho in 'Protocols\IdEcho.pas', + IdEchoServer in 'Protocols\IdEchoServer.pas', + IdEchoUDP in 'Protocols\IdEchoUDP.pas', + IdEchoUDPServer in 'Protocols\IdEchoUDPServer.pas', + IdException in 'System\IdException.pas', + IdExceptionCore in 'Core\IdExceptionCore.pas', + IdExplicitTLSClientServerBase in 'Protocols\IdExplicitTLSClientServerBase.pas', + IdFIPS in 'Protocols\IdFIPS.pas', + IdFSP in 'Protocols\IdFSP.pas', + IdFTP in 'Protocols\IdFTP.pas', + IdFTPBaseFileSystem in 'Protocols\IdFTPBaseFileSystem.pas', + IdFTPCommon in 'Protocols\IdFTPCommon.pas', + IdFTPList in 'Protocols\IdFTPList.pas', + IdFTPListOutput in 'Protocols\IdFTPListOutput.pas', + IdFTPListParseAS400 in 'Protocols\IdFTPListParseAS400.pas', + IdFTPListParseBase in 'Protocols\IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'Protocols\IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'Protocols\IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'Protocols\IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'Protocols\IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'Protocols\IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'Protocols\IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'Protocols\IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'Protocols\IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'Protocols\IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'Protocols\IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'Protocols\IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'Protocols\IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'Protocols\IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'Protocols\IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'Protocols\IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'Protocols\IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'Protocols\IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'Protocols\IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'Protocols\IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'Protocols\IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'Protocols\IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'Protocols\IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'Protocols\IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'Protocols\IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'Protocols\IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'Protocols\IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'Protocols\IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'Protocols\IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'Protocols\IdFTPListParseUnix.pas', + IdFTPListParseVM in 'Protocols\IdFTPListParseVM.pas', + IdFTPListParseVMS in 'Protocols\IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'Protocols\IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'Protocols\IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'Protocols\IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'Protocols\IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'Protocols\IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'Protocols\IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'Protocols\IdFTPListTypes.pas', + IdFTPServer in 'Protocols\IdFTPServer.pas', + IdFTPServerContextBase in 'Protocols\IdFTPServerContextBase.pas', + IdFinger in 'Protocols\IdFinger.pas', + IdFingerServer in 'Protocols\IdFingerServer.pas', + IdGlobal in 'System\IdGlobal.pas', + IdGlobalCore in 'Core\IdGlobalCore.pas', + IdGlobalProtocols in 'Protocols\IdGlobalProtocols.pas', + IdGopher in 'Protocols\IdGopher.pas', + IdGopherConsts in 'Protocols\IdGopherConsts.pas', + IdGopherServer in 'Protocols\IdGopherServer.pas', + IdHL7 in 'Protocols\IdHL7.pas', + IdHMAC in 'Protocols\IdHMAC.pas', + IdHMACMD5 in 'Protocols\IdHMACMD5.pas', + IdHMACSHA1 in 'Protocols\IdHMACSHA1.pas', + IdHTTP in 'Protocols\IdHTTP.pas', + IdHTTPHeaderInfo in 'Protocols\IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'Protocols\IdHTTPHelper.pas', + IdHTTPProxyServer in 'Protocols\IdHTTPProxyServer.pas', + IdHTTPServer in 'Protocols\IdHTTPServer.pas', + IdHash in 'Protocols\IdHash.pas', + IdHashCRC in 'Protocols\IdHashCRC.pas', + IdHashElf in 'Protocols\IdHashElf.pas', + IdHashMessageDigest in 'Protocols\IdHashMessageDigest.pas', + IdHashSHA in 'Protocols\IdHashSHA.pas', + IdHeaderCoder2022JP in 'Protocols\IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'Protocols\IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'Protocols\IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'Protocols\IdHeaderCoderPlain.pas', + IdHeaderList in 'Protocols\IdHeaderList.pas', + IdIMAP4 in 'Protocols\IdIMAP4.pas', + IdIMAP4Server in 'Protocols\IdIMAP4Server.pas', + IdIOHandler in 'Core\IdIOHandler.pas', + IdIOHandlerSocket in 'Core\IdIOHandlerSocket.pas', + IdIOHandlerStack in 'Core\IdIOHandlerStack.pas', + IdIOHandlerStream in 'Core\IdIOHandlerStream.pas', + IdIOHandlerTls in 'Security\IdIOHandlerTls.pas', + IdIPAddrMon in 'Protocols\IdIPAddrMon.pas', + IdIPAddress in 'Core\IdIPAddress.pas', + IdIPMCastBase in 'Core\IdIPMCastBase.pas', + IdIPMCastClient in 'Core\IdIPMCastClient.pas', + IdIPMCastServer in 'Core\IdIPMCastServer.pas', + IdIPWatch in 'Protocols\IdIPWatch.pas', + IdIRC in 'Protocols\IdIRC.pas', + IdIcmpClient in 'Core\IdIcmpClient.pas', + IdIdent in 'Protocols\IdIdent.pas', + IdIdentServer in 'Protocols\IdIdentServer.pas', + IdIntercept in 'Core\IdIntercept.pas', + IdInterceptSimLog in 'Core\IdInterceptSimLog.pas', + IdInterceptThrottler in 'Core\IdInterceptThrottler.pas', + IdIrcServer in 'Protocols\IdIrcServer.pas', + IdLPR in 'Protocols\IdLPR.pas', + IdLogBase in 'Core\IdLogBase.pas', + IdLogDebug in 'Core\IdLogDebug.pas', + IdLogEvent in 'Core\IdLogEvent.pas', + IdLogFile in 'Core\IdLogFile.pas', + IdLogStream in 'Core\IdLogStream.pas', + IdMailBox in 'Protocols\IdMailBox.pas', + IdMappedFTP in 'Protocols\IdMappedFTP.pas', + IdMappedPOP3 in 'Protocols\IdMappedPOP3.pas', + IdMappedPortTCP in 'Protocols\IdMappedPortTCP.pas', + IdMappedPortUDP in 'Protocols\IdMappedPortUDP.pas', + IdMappedTelnet in 'Protocols\IdMappedTelnet.pas', + IdMessage in 'Protocols\IdMessage.pas', + IdMessageBuilder in 'Protocols\IdMessageBuilder.pas', + IdMessageClient in 'Protocols\IdMessageClient.pas', + IdMessageCoder in 'Protocols\IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'Protocols\IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'Protocols\IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'Protocols\IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'Protocols\IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'Protocols\IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'Protocols\IdMessageCoderYenc.pas', + IdMessageCollection in 'Protocols\IdMessageCollection.pas', + IdMessageHelper in 'Protocols\IdMessageHelper.pas', + IdMessageParts in 'Protocols\IdMessageParts.pas', + IdMultipartFormData in 'Protocols\IdMultipartFormData.pas', + IdNNTP in 'Protocols\IdNNTP.pas', + IdNNTPServer in 'Protocols\IdNNTPServer.pas', + IdNetworkCalculator in 'Protocols\IdNetworkCalculator.pas', + IdOSFileName in 'Protocols\IdOSFileName.pas', + IdOTPCalculator in 'Protocols\IdOTPCalculator.pas', + IdPOP3 in 'Protocols\IdPOP3.pas', + IdPOP3Server in 'Protocols\IdPOP3Server.pas', + IdQOTDUDP in 'Protocols\IdQOTDUDP.pas', + IdQOTDUDPServer in 'Protocols\IdQOTDUDPServer.pas', + IdQotd in 'Protocols\IdQotd.pas', + IdQotdServer in 'Protocols\IdQotdServer.pas', + IdRSH in 'Protocols\IdRSH.pas', + IdRSHServer in 'Protocols\IdRSHServer.pas', + IdRawBase in 'Core\IdRawBase.pas', + IdRawClient in 'Core\IdRawClient.pas', + IdRawFunctions in 'Core\IdRawFunctions.pas', + IdRawHeaders in 'Core\IdRawHeaders.pas', + IdRemoteCMDClient in 'Protocols\IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'Protocols\IdRemoteCMDServer.pas', + IdReply in 'Core\IdReply.pas', + IdReplyFTP in 'Protocols\IdReplyFTP.pas', + IdReplyIMAP4 in 'Protocols\IdReplyIMAP4.pas', + IdReplyPOP3 in 'Protocols\IdReplyPOP3.pas', + IdReplyRFC in 'Core\IdReplyRFC.pas', + IdReplySMTP in 'Protocols\IdReplySMTP.pas', + IdResourceStrings in 'System\IdResourceStrings.pas', + IdResourceStringsCore in 'Core\IdResourceStringsCore.pas', + IdResourceStringsProtocols in 'Protocols\IdResourceStringsProtocols.pas', + IdRexec in 'Protocols\IdRexec.pas', + IdRexecServer in 'Protocols\IdRexecServer.pas', + IdSASL in 'Protocols\IdSASL.pas', + IdSASLAnonymous in 'Protocols\IdSASLAnonymous.pas', + IdSASLCollection in 'Protocols\IdSASLCollection.pas', + IdSASLDigest in 'Protocols\IdSASLDigest.pas', + IdSASLExternal in 'Protocols\IdSASLExternal.pas', + IdSASLLogin in 'Protocols\IdSASLLogin.pas', + IdSASLOAuth in 'Protocols\IdSASLOAuth.pas', + IdSASLOTP in 'Protocols\IdSASLOTP.pas', + IdSASLPlain in 'Protocols\IdSASLPlain.pas', + IdSASLSKey in 'Protocols\IdSASLSKey.pas', + IdSASLUserPass in 'Protocols\IdSASLUserPass.pas', + IdSASL_CRAMBase in 'Protocols\IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'Protocols\IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'Protocols\IdSASL_CRAM_SHA1.pas', + IdSMTP in 'Protocols\IdSMTP.pas', + IdSMTPBase in 'Protocols\IdSMTPBase.pas', + IdSMTPRelay in 'Protocols\IdSMTPRelay.pas', + IdSMTPServer in 'Protocols\IdSMTPServer.pas', + IdSNPP in 'Protocols\IdSNPP.pas', + IdSNTP in 'Protocols\IdSNTP.pas', + IdSSL in 'Protocols\IdSSL.pas', + IdSSLDotNET in 'Protocols\IdSSLDotNET.pas', + IdScheduler in 'Core\IdScheduler.pas', + IdSchedulerOfThread in 'Core\IdSchedulerOfThread.pas', + IdSchedulerOfThreadDefault in 'Core\IdSchedulerOfThreadDefault.pas', + IdSchedulerOfThreadPool in 'Core\IdSchedulerOfThreadPool.pas', + IdServerIOHandler in 'Core\IdServerIOHandler.pas', + IdServerIOHandlerSocket in 'Core\IdServerIOHandlerSocket.pas', + IdServerIOHandlerStack in 'Core\IdServerIOHandlerStack.pas', + IdServerIOHandlerTls in 'Security\IdServerIOHandlerTls.pas', + IdServerInterceptLogBase in 'Protocols\IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'Protocols\IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'Protocols\IdServerInterceptLogFile.pas', + IdSimpleServer in 'Core\IdSimpleServer.pas', + IdSocketHandle in 'Core\IdSocketHandle.pas', + IdSocketStream in 'Security\IdSocketStream.pas', + IdSocks in 'Core\IdSocks.pas', + IdSocksServer in 'Protocols\IdSocksServer.pas', + IdStack in 'System\IdStack.pas', + IdStackConsts in 'System\IdStackConsts.pas', + IdStackDotNet in 'System\IdStackDotNet.pas', + IdStream in 'System\IdStream.pas', + IdStreamNET in 'System\IdStreamNET.pas', + IdStrings in 'Protocols\IdStrings.pas', + IdStruct in 'System\IdStruct.pas', + IdSync in 'Core\IdSync.pas', + IdSysLog in 'Protocols\IdSysLog.pas', + IdSysLogMessage in 'Protocols\IdSysLogMessage.pas', + IdSysLogServer in 'Protocols\IdSysLogServer.pas', + IdSystat in 'Protocols\IdSystat.pas', + IdSystatServer in 'Protocols\IdSystatServer.pas', + IdSystatUDP in 'Protocols\IdSystatUDP.pas', + IdSystatUDPServer in 'Protocols\IdSystatUDPServer.pas', + IdTCPClient in 'Core\IdTCPClient.pas', + IdTCPConnection in 'Core\IdTCPConnection.pas', + IdTCPServer in 'Core\IdTCPServer.pas', + IdTCPStream in 'Core\IdTCPStream.pas', + IdTask in 'Core\IdTask.pas', + IdTelnet in 'Protocols\IdTelnet.pas', + IdTelnetServer in 'Protocols\IdTelnetServer.pas', + IdText in 'Protocols\IdText.pas', + IdThread in 'Core\IdThread.pas', + IdThreadComponent in 'Core\IdThreadComponent.pas', + IdThreadSafe in 'Core\IdThreadSafe.pas', + IdTime in 'Protocols\IdTime.pas', + IdTimeServer in 'Protocols\IdTimeServer.pas', + IdTimeUDP in 'Protocols\IdTimeUDP.pas', + IdTimeUDPServer in 'Protocols\IdTimeUDPServer.pas', + IdTlsClientOptions in 'Security\IdTlsClientOptions.pas', + IdTlsServerOptions in 'Security\IdTlsServerOptions.pas', + IdTraceRoute in 'Core\IdTraceRoute.pas', + IdTrivialFTP in 'Protocols\IdTrivialFTP.pas', + IdTrivialFTPBase in 'Protocols\IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'Protocols\IdTrivialFTPServer.pas', + IdUDPBase in 'Core\IdUDPBase.pas', + IdUDPClient in 'Core\IdUDPClient.pas', + IdUDPServer in 'Core\IdUDPServer.pas', + IdURI in 'Protocols\IdURI.pas', + IdUnixTime in 'Protocols\IdUnixTime.pas', + IdUnixTimeServer in 'Protocols\IdUnixTimeServer.pas', + IdUnixTimeUDP in 'Protocols\IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'Protocols\IdUnixTimeUDPServer.pas', + IdUriUtils in 'Protocols\IdUriUtils.pas', + IdUserAccounts in 'Protocols\IdUserAccounts.pas', + IdUserPassProvider in 'Protocols\IdUserPassProvider.pas', + IdVCard in 'Protocols\IdVCard.pas', + IdWebDAV in 'Protocols\IdWebDAV.pas', + IdWhoIsServer in 'Protocols\IdWhoIsServer.pas', + IdWhois in 'Protocols\IdWhois.pas', + IdYarn in 'Core\IdYarn.pas', + IdZLibCompressorBase in 'Protocols\IdZLibCompressorBase.pas'; + +end. diff --git a/Lib/Protocols/IdAuthenticationSSPI.pas b/Lib/Protocols/IdAuthenticationSSPI.pas index af4f8ff07..4293b3840 100644 --- a/Lib/Protocols/IdAuthenticationSSPI.pas +++ b/Lib/Protocols/IdAuthenticationSSPI.pas @@ -1,1323 +1,1323 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.3 6/11/2004 9:33:58 AM DSiders - Added "Do not Localize" comments. - - Rev 1.2 13.1.2004 ã. 17:26:06 DBondzhev - Added Domain property - - Rev 1.1 4/12/2003 10:24:04 PM GGrieve - Fix to Compile - - Rev 1.0 11/14/2002 02:13:50 PM JPMugaas -} - -unit IdAuthenticationSSPI; - -{ - Implementation of the NTLM authentication with SSPI - Author: Alex Brainman - Copyright: (c) Chad Z. Hower and The Winshoes Working Group. -} - -{$DEFINE SET_ENCRYPT_IN_FT_WITH_GETPROCADDRESS_FUDGE} - -interface - -{$i IdCompilerDefines.inc} -{$IFDEF USE_SSPI} -uses - IdGlobal, - IdAuthentication, - IdCoder, - Windows, - SysUtils, - IdSSPI; - -const - SEC_E_OK = 0; - {$EXTERNALSYM SEC_E_OK} - SEC_E_INSUFFICIENT_MEMORY = HRESULT($80090300); - {$EXTERNALSYM SEC_E_INSUFFICIENT_MEMORY} - SEC_E_INVALID_HANDLE = HRESULT($80090301); - {$EXTERNALSYM SEC_E_INVALID_HANDLE} - SEC_E_UNSUPPORTED_FUNCTION = HRESULT($80090302); - {$EXTERNALSYM SEC_E_UNSUPPORTED_FUNCTION} - SEC_E_TARGET_UNKNOWN = HRESULT($80090303); - {$EXTERNALSYM SEC_E_TARGET_UNKNOWN} - SEC_E_INTERNAL_ERROR = HRESULT($80090304); - {$EXTERNALSYM SEC_E_INTERNAL_ERROR} - SEC_E_SECPKG_NOT_FOUND = HRESULT($80090305); - {$EXTERNALSYM SEC_E_SECPKG_NOT_FOUND} - SEC_E_NOT_OWNER = HRESULT($80090306); - {$EXTERNALSYM SEC_E_NOT_OWNER} - SEC_E_CANNOT_INSTALL = HRESULT($80090307); - {$EXTERNALSYM SEC_E_CANNOT_INSTALL} - SEC_E_INVALID_TOKEN = HRESULT($80090308); - {$EXTERNALSYM SEC_E_INVALID_TOKEN} - SEC_E_CANNOT_PACK = HRESULT($80090309); - {$EXTERNALSYM SEC_E_CANNOT_PACK} - SEC_E_QOP_NOT_SUPPORTED = HRESULT($8009030A); - {$EXTERNALSYM SEC_E_QOP_NOT_SUPPORTED} - SEC_E_NO_IMPERSONATION = HRESULT($8009030B); - {$EXTERNALSYM SEC_E_NO_IMPERSONATION} - SEC_E_LOGON_DENIED = HRESULT($8009030C); - {$EXTERNALSYM SEC_E_LOGON_DENIED} - SEC_E_UNKNOWN_CREDENTIALS = HRESULT($8009030D); - {$EXTERNALSYM SEC_E_UNKNOWN_CREDENTIALS} - SEC_E_NO_CREDENTIALS = HRESULT($8009030E); - {$EXTERNALSYM SEC_E_NO_CREDENTIALS} - SEC_E_MESSAGE_ALTERED = HRESULT($8009030F); - {$EXTERNALSYM SEC_E_MESSAGE_ALTERED} - SEC_E_OUT_OF_SEQUENCE = HRESULT($80090310); - {$EXTERNALSYM SEC_E_OUT_OF_SEQUENCE} - SEC_E_NO_AUTHENTICATING_AUTHORITY = HRESULT($80090311); - {$EXTERNALSYM SEC_E_NO_AUTHENTICATING_AUTHORITY} - SEC_I_CONTINUE_NEEDED = HRESULT($00090312); - {$EXTERNALSYM SEC_I_CONTINUE_NEEDED} - SEC_I_COMPLETE_NEEDED = HRESULT($00090313); - {$EXTERNALSYM SEC_I_COMPLETE_NEEDED} - SEC_I_COMPLETE_AND_CONTINUE = HRESULT($00090314); - {$EXTERNALSYM SEC_I_COMPLETE_AND_CONTINUE} - SEC_I_LOCAL_LOGON = HRESULT($00090315); - {$EXTERNALSYM SEC_I_LOCAL_LOGON} - SEC_E_BAD_PKGID = HRESULT($80090316); - {$EXTERNALSYM SEC_E_BAD_PKGID} - SEC_E_CONTEXT_EXPIRED = HRESULT($80090317); - {$EXTERNALSYM SEC_E_CONTEXT_EXPIRED} - SEC_E_INCOMPLETE_MESSAGE = HRESULT($80090318); - {$EXTERNALSYM SEC_E_INCOMPLETE_MESSAGE} - SEC_E_INCOMPLETE_CREDENTIALS = HRESULT($80090320); - {$EXTERNALSYM SEC_E_INCOMPLETE_CREDENTIALS} - SEC_E_BUFFER_TOO_SMALL = HRESULT($80090321); - {$EXTERNALSYM SEC_E_BUFFER_TOO_SMALL} - SEC_I_INCOMPLETE_CREDENTIALS = HRESULT($00090320); - {$EXTERNALSYM SEC_I_INCOMPLETE_CREDENTIALS} - SEC_I_RENEGOTIATE = HRESULT($00090321); - {$EXTERNALSYM SEC_I_RENEGOTIATE} - SEC_E_WRONG_PRINCIPAL = HRESULT($80090322); - {$EXTERNALSYM SEC_E_WRONG_PRINCIPAL} - SEC_I_NO_LSA_CONTEXT = HRESULT($00090323); - {$EXTERNALSYM SEC_I_NO_LSA_CONTEXT} - SEC_E_TIME_SKEW = HRESULT($80090324); - {$EXTERNALSYM SEC_E_TIME_SKEW} - SEC_E_UNTRUSTED_ROOT = HRESULT($80090325); - {$EXTERNALSYM SEC_E_UNTRUSTED_ROOT} - SEC_E_ILLEGAL_MESSAGE = HRESULT($80090326); - {$EXTERNALSYM SEC_E_ILLEGAL_MESSAGE} - SEC_E_CERT_UNKNOWN = HRESULT($80090327); - {$EXTERNALSYM SEC_E_CERT_UNKNOWN} - SEC_E_CERT_EXPIRED = HRESULT($80090328); - {$EXTERNALSYM SEC_E_CERT_EXPIRED} - SEC_E_ENCRYPT_FAILURE = HRESULT($80090329); - {$EXTERNALSYM SEC_E_ENCRYPT_FAILURE} - SEC_E_DECRYPT_FAILURE = HRESULT($80090330); - {$EXTERNALSYM SEC_E_DECRYPT_FAILURE} - SEC_E_ALGORITHM_MISMATCH = HRESULT($80090331); - {$EXTERNALSYM SEC_E_ALGORITHM_MISMATCH} - SEC_E_SECURITY_QOS_FAILED = HRESULT($80090332); - {$EXTERNALSYM SEC_E_SECURITY_QOS_FAILED} - - SEC_E_UNFINISHED_CONTEXT_DELETED = HRESULT($80090333); - {$EXTERNALSYM SEC_E_UNFINISHED_CONTEXT_DELETED} - SEC_E_NO_TGT_REPLY = HRESULT($80090334); - {$EXTERNALSYM SEC_E_NO_TGT_REPLY} - SEC_E_NO_IP_ADDRESSES = HRESULT($80090335); - {$EXTERNALSYM SEC_E_NO_IP_ADDRESSES} - SEC_E_WRONG_CREDENTIAL_HANDLE = HRESULT($80090336); - {$EXTERNALSYM SEC_E_WRONG_CREDENTIAL_HANDLE} - SEC_E_CRYPTO_SYSTEM_INVALID = HRESULT($80090337); - {$EXTERNALSYM SEC_E_CRYPTO_SYSTEM_INVALID} - SEC_E_MAX_REFERRALS_EXCEEDED = HRESULT($80090338); - {$EXTERNALSYM SEC_E_MAX_REFERRALS_EXCEEDED} - SEC_E_MUST_BE_KDC = HRESULT($80090339); - {$EXTERNALSYM SEC_E_MUST_BE_KDC} - SEC_E_STRONG_CRYPTO_NOT_SUPPORTED = HRESULT($8009033A); - {$EXTERNALSYM SEC_E_STRONG_CRYPTO_NOT_SUPPORTED} - SEC_E_TOO_MANY_PRINCIPALS = HRESULT($8009033B); - {$EXTERNALSYM SEC_E_TOO_MANY_PRINCIPALS} - SEC_E_NO_PA_DATA = HRESULT($8009033C); - {$EXTERNALSYM SEC_E_NO_PA_DATA} - SEC_E_PKINIT_NAME_MISMATCH = HRESULT($8009033D); - {$EXTERNALSYM SEC_E_PKINIT_NAME_MISMATCH} - SEC_E_SMARTCARD_LOGON_REQUIRED = HRESULT($8009033E); - {$EXTERNALSYM SEC_E_SMARTCARD_LOGON_REQUIRED} - SEC_E_SHUTDOWN_IN_PROGRESS = HRESULT($8009033F); - {$EXTERNALSYM SEC_E_SHUTDOWN_IN_PROGRESS} - SEC_E_KDC_INVALID_REQUEST = HRESULT($80090340); - {$EXTERNALSYM SEC_E_KDC_INVALID_REQUEST} - SEC_E_KDC_UNABLE_TO_REFER = HRESULT($80090341); - {$EXTERNALSYM SEC_E_KDC_UNABLE_TO_REFER} - SEC_E_KDC_UNKNOWN_ETYPE = HRESULT($80090342); - {$EXTERNALSYM SEC_E_KDC_UNKNOWN_ETYPE} - SEC_E_UNSUPPORTED_PREAUTH = HRESULT($80090343); - {$EXTERNALSYM SEC_E_UNSUPPORTED_PREAUTH} - SEC_E_DELEGATION_REQUIRED = HRESULT($80090345); - {$EXTERNALSYM SEC_E_DELEGATION_REQUIRED} - SEC_E_BAD_BINDINGS = HRESULT($80090346); - {$EXTERNALSYM SEC_E_BAD_BINDINGS} - SEC_E_MULTIPLE_ACCOUNTS = HRESULT($80090347); - {$EXTERNALSYM SEC_E_MULTIPLE_ACCOUNTS} - SEC_E_NO_KERB_KEY = HRESULT($80090348); - {$EXTERNALSYM SEC_E_NO_KERB_KEY} - SEC_E_CERT_WRONG_USAGE = HRESULT($80090349); - {$EXTERNALSYM SEC_E_CERT_WRONG_USAGE} - SEC_E_DOWNGRADE_DETECTED = HRESULT($80090350); - {$EXTERNALSYM SEC_E_DOWNGRADE_DETECTED} - SEC_E_SMARTCARD_CERT_REVOKED = HRESULT($80090351); - {$EXTERNALSYM SEC_E_SMARTCARD_CERT_REVOKED} - SEC_E_ISSUING_CA_UNTRUSTED = HRESULT($80090352); - {$EXTERNALSYM SEC_E_ISSUING_CA_UNTRUSTED} - SEC_E_REVOCATION_OFFLINE_C = HRESULT($80090353); - {$EXTERNALSYM SEC_E_REVOCATION_OFFLINE_C} - SEC_E_PKINIT_CLIENT_FAILURE = HRESULT($80090354); - {$EXTERNALSYM SEC_E_PKINIT_CLIENT_FAILURE} - SEC_E_SMARTCARD_CERT_EXPIRED = HRESULT($80090355); - {$EXTERNALSYM SEC_E_SMARTCARD_CERT_EXPIRED} - SEC_E_NO_S4U_PROT_SUPPORT = HRESULT($80090356); - {$EXTERNALSYM SEC_E_NO_S4U_PROT_SUPPORT} - SEC_E_CROSSREALM_DELEGATION_FAILURE = HRESULT($80090357); - {$EXTERNALSYM SEC_E_CROSSREALM_DELEGATION_FAILURE} - SEC_E_REVOCATION_OFFLINE_KDC = HRESULT($80090358); - {$EXTERNALSYM SEC_E_REVOCATION_OFFLINE_KDC} - SEC_E_ISSUING_CA_UNTRUSTED_KDC = HRESULT($80090359); - {$EXTERNALSYM SEC_E_ISSUING_CA_UNTRUSTED_KDC} - SEC_E_KDC_CERT_EXPIRED = HRESULT($8009035A); - {$EXTERNALSYM SEC_E_KDC_CERT_EXPIRED} - SEC_E_KDC_CERT_REVOKED = HRESULT($8009035B); - {$EXTERNALSYM SEC_E_KDC_CERT_REVOKED} - SEC_I_SIGNATURE_NEEDED = HRESULT($0009035C); - {$EXTERNALSYM SEC_I_SIGNATURE_NEEDED} - SEC_E_INVALID_PARAMETER = HRESULT($8009035D); - {$EXTERNALSYM SEC_E_INVALID_PARAMETER} - SEC_E_DELEGATION_POLICY = HRESULT($8009035E); - {$EXTERNALSYM SEC_E_DELEGATION_POLICY} - SEC_E_POLICY_NLTM_ONLY = HRESULT($8009035F); - {$EXTERNALSYM SEC_E_POLICY_NLTM_ONLY} - SEC_I_NO_RENEGOTIATION = HRESULT($00090360); - {$EXTERNALSYM SEC_I_NO_RENEGOTIATION} - SEC_E_NO_CONTEXT = HRESULT($80090361); - {$EXTERNALSYM SEC_E_NO_CONTEXT} - SEC_E_PKU2U_CERT_FAILURE = HRESULT($80090362); - {$EXTERNALSYM SEC_E_PKU2U_CERT_FAILURE} - SEC_E_MUTUAL_AUTH_FAILED = HRESULT($80090363); - {$EXTERNALSYM SEC_E_MUTUAL_AUTH_FAILED} - -type - ESSPIException = class(Exception) - public - // Params must be in this order to avoid conflict with CreateHelp - // constructor in CBuilder as CB does not differentiate constructors - // by name as Delphi does - constructor CreateError(const AErrorNo: Integer; const AFailedFuncName: string); - // - class function GetErrorMessageByNo(AErrorNo: UInt32): string; - end; - - ESSPIInterfaceInitFailed = class(ESSPIException); - - { TSSPIInterface } - - TSSPIInterface = class(TObject) - private - fLoadPending, fIsAvailable: Boolean; - fPFunctionTable: PSecurityFunctionTable; - fDLLHandle: TIdLibHandle; - procedure ReleaseFunctionTable; - procedure CheckAvailable; - function GetFunctionTable: SecurityFunctionTable; - public - class procedure RaiseIfError(aStatus: SECURITY_STATUS; const aFunctionName: string); - function IsAvailable: Boolean; - property FunctionTable: SecurityFunctionTable read GetFunctionTable; - public - constructor Create; - destructor Destroy; override; - end; - - { TSSPIPackages } - - TSSPIPackage = class(TObject) - private - fPSecPkginfo: PSecPkgInfo; - function GetPSecPkgInfo: PSecPkgInfo; - function GetMaxToken: ULONG; - function GetName: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}; - public - property MaxToken: ULONG read GetMaxToken; - property Name: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF} read GetName; - public - constructor Create(aPSecPkginfo: PSecPkgInfo); - end; - - TCustomSSPIPackage = class(TSSPIPackage) - private - fInfo: PSecPkgInfo; - public - constructor Create(const aPkgName: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}); - destructor Destroy; override; - end; - - TSSPINTLMPackage = class(TCustomSSPIPackage) - public - constructor Create; - end; - - { TSSPICredentials } - - TSSPICredentialsUse = (scuInBound, scuOutBound, scuBoth); - - TSSPICredentials = class(TObject) - private - fPackage: TSSPIPackage; - fHandle: CredHandle; - fUse: TSSPICredentialsUse; - fAcquired: Boolean; - fExpiry: TimeStamp; - function GetHandle: PCredHandle; - procedure SetUse(aValue: TSSPICredentialsUse); - protected - procedure CheckAcquired; - procedure CheckNotAcquired; - procedure DoAcquire(pszPrincipal: {$IFDEF SSPI_UNICODE}PSEC_WCHAR{$ELSE}PSEC_CHAR{$ENDIF}; pvLogonId, pAuthData: PVOID); - procedure DoRelease; virtual; - public - procedure Release; - property Package: TSSPIPackage read fPackage; - property Handle: PCredHandle read GetHandle; - property Use: TSSPICredentialsUse read fUse write SetUse; - property Acquired: Boolean read fAcquired; - public - constructor Create(aPackage: TSSPIPackage); - destructor Destroy; override; - end; - - { TSSPIWinNTCredentials } - - TSSPIWinNTCredentials = class(TSSPICredentials) - protected - public - procedure Acquire(aUse: TSSPICredentialsUse); overload; - procedure Acquire(aUse: TSSPICredentialsUse; - const aDomain, aUserName, aPassword: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}); overload; - end; - - { TSSPIContext } - - TSSPIContext = class(TObject) - private - fCredentials: TSSPICredentials; - fHandle: CtxtHandle; - fHasHandle: Boolean; - fExpiry: TimeStamp; - function GetHandle: PCtxtHandle; - function GetExpiry: TimeStamp; - procedure UpdateHasContextAndCheckForError( - const aFuncResult: SECURITY_STATUS; const aFuncName: string; - const aErrorsToIgnore: array of SECURITY_STATUS); - protected - procedure CheckHasHandle; - procedure CheckCredentials; - function DoInitialize(const aTokenSourceName: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}; - var aIn, aOut: SecBufferDesc; - const errorsToIgnore: array of SECURITY_STATUS): SECURITY_STATUS; - procedure DoRelease; virtual; - function GetRequestedFlags: ULONG; virtual; abstract; - procedure SetEstablishedFlags(aFlags: ULONG); virtual; abstract; - function GetAuthenticated: Boolean; virtual; abstract; - property HasHandle: Boolean read fHasHandle; - public - procedure Release; - property Credentials: TSSPICredentials read fCredentials; - property Handle: PCtxtHandle read GetHandle; - property Authenticated: Boolean read GetAuthenticated; - property Expiry: TimeStamp read GetExpiry; - public - constructor Create(aCredentials: TSSPICredentials); - destructor Destroy; override; - end; - - { TSSPIConnectionContext } - - TCustomSSPIConnectionContext = class(TSSPIContext) - private - fStatus: SECURITY_STATUS; - fOutBuffDesc, fInBuffDesc: SecBufferDesc; - fInBuff: SecBuffer; - protected - procedure DoRelease; override; - function GetAuthenticated: Boolean; override; - function DoUpdateAndGenerateReply(var aIn, aOut: SecBufferDesc; - const aErrorsToIgnore: array of SECURITY_STATUS - ): SECURITY_STATUS; virtual; abstract; - public - constructor Create(ACredentials: TSSPICredentials); - function UpdateAndGenerateReply( - const aFromPeerToken: TIdBytes; var aToPeerToken: TIdBytes): Boolean; - end; - - TSSPIClientConnectionContext = class(TCustomSSPIConnectionContext) - private - fTargetName: string; - fReqReguested, fReqEstablished: ULONG; - protected - function GetRequestedFlags: ULONG; override; - procedure SetEstablishedFlags(aFlags: ULONG); override; - function DoUpdateAndGenerateReply(var aIn, aOut: SecBufferDesc; - const aErrorsToIgnore: array of SECURITY_STATUS - ): SECURITY_STATUS; override; - public - function GenerateInitialChallenge(const aTargetName: string; - var aToPeerToken: TIdBytes): Boolean; - public - constructor Create(aCredentials: TSSPICredentials); - end; - - TIndySSPINTLMClient = class(TObject) - protected - fNTLMPackage: TSSPINTLMPackage; - fCredentials: TSSPIWinNTCredentials; - fContext: TSSPIClientConnectionContext; - public - procedure SetCredentials(const aDomain, aUserName, aPassword: string); - procedure SetCredentialsAsCurrentUser; - function InitAndBuildType1Message: TIdBytes; - function UpdateAndBuildType3Message(const aServerType2Message: TIdBytes): TIdBytes; - public - constructor Create; - destructor Destroy; override; - end; - - TIdSSPINTLMAuthentication = class(TIdAuthentication) - protected - FNTLMInfo: string; - FSSPIClient: TIndySSPINTLMClient; - procedure SetDomain(const Value: String); - function GetDomain: String; - procedure SetUserName(const Value: String); override; - function GetSteps: Integer; override; - function DoNext: TIdAuthWhatsNext; override; - public - constructor Create; override; - destructor Destroy; override; - function Authentication: string; override; - function KeepAlive: Boolean; override; - property Domain: String read GetDomain write SetDomain; - end; - - // RLebeau 4/17/10: this forces C++Builder to link to this unit so - // RegisterAuthenticationMethod can be called correctly at program startup... - - {$IFDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT} - {$HPPEMIT LINKUNIT} - {$ELSE} - {$HPPEMIT '#pragma link "IdAuthenticationSSPI"'} - {$ENDIF} - -{$ENDIF} -implementation -{$IFDEF USE_SSPI} -uses - IdGlobalProtocols, - IdCoderMIME, - IdResourceStringsSSPI, - IdHeaderList; - -var - gSSPIInterface: TSSPIInterface = nil; - gAuthRegistered: Boolean = False; - -{ ESSPIException } - -class function ESSPIException.GetErrorMessageByNo(aErrorNo: UInt32): string; -begin - case HRESULT(aErrorNo) of - SEC_E_OK: - Result := RSHTTPSSPISuccess; - SEC_E_INSUFFICIENT_MEMORY: - Result := RSHTTPSSPINotEnoughMem; - SEC_E_INVALID_HANDLE: - Result := RSHTTPSSPIInvalidHandle; - SEC_E_UNSUPPORTED_FUNCTION: - Result := RSHTTPSSPIFuncNotSupported; - SEC_E_TARGET_UNKNOWN: - Result := RSHTTPSSPIUnknownTarget; - SEC_E_INTERNAL_ERROR: - Result := RSHTTPSSPIInternalError; - SEC_E_SECPKG_NOT_FOUND: - Result := RSHTTPSSPISecPackageNotFound; - SEC_E_NOT_OWNER: - Result := RSHTTPSSPINotOwner; - SEC_E_CANNOT_INSTALL: - Result := RSHTTPSSPIPackageCannotBeInstalled; - SEC_E_INVALID_TOKEN: - Result := RSHTTPSSPIInvalidToken; - SEC_E_CANNOT_PACK: - Result := RSHTTPSSPICannotPack; - SEC_E_QOP_NOT_SUPPORTED: - Result := RSHTTPSSPIQOPNotSupported; - SEC_E_NO_IMPERSONATION: - Result := RSHTTPSSPINoImpersonation; - SEC_E_LOGON_DENIED: - Result := RSHTTPSSPILoginDenied; - SEC_E_UNKNOWN_CREDENTIALS: - Result := RSHTTPSSPIUnknownCredentials; - SEC_E_NO_CREDENTIALS: - Result := RSHTTPSSPINoCredentials; - SEC_E_MESSAGE_ALTERED: - Result := RSHTTPSSPIMessageAltered; - SEC_E_OUT_OF_SEQUENCE: - Result := RSHTTPSSPIOutOfSequence; - SEC_E_NO_AUTHENTICATING_AUTHORITY: - Result := RSHTTPSSPINoAuthAuthority; - SEC_I_CONTINUE_NEEDED: - Result := RSHTTPSSPIContinueNeeded; - SEC_I_COMPLETE_NEEDED: - Result := RSHTTPSSPICompleteNeeded; - SEC_I_COMPLETE_AND_CONTINUE: - Result :=RSHTTPSSPICompleteContinueNeeded; - SEC_I_LOCAL_LOGON: - Result := RSHTTPSSPILocalLogin; - SEC_E_BAD_PKGID: - Result := RSHTTPSSPIBadPackageID; - SEC_E_CONTEXT_EXPIRED: - Result := RSHTTPSSPIContextExpired; - SEC_E_INCOMPLETE_MESSAGE: - Result := RSHTTPSSPIIncompleteMessage; - SEC_E_INCOMPLETE_CREDENTIALS: - Result := RSHTTPSSPIIncompleteCredentialNotInit; - SEC_E_BUFFER_TOO_SMALL: - Result := RSHTTPSSPIBufferTooSmall; - SEC_I_INCOMPLETE_CREDENTIALS: - Result := RSHTTPSSPIIncompleteCredentialsInit; - SEC_I_RENEGOTIATE: - Result := RSHTTPSSPIRengotiate; - SEC_E_WRONG_PRINCIPAL: - Result := RSHTTPSSPIWrongPrincipal; - SEC_I_NO_LSA_CONTEXT: - Result := RSHTTPSSPINoLSACode; - SEC_E_TIME_SKEW: - Result := RSHTTPSSPITimeScew; - SEC_E_UNTRUSTED_ROOT: - Result := RSHTTPSSPIUntrustedRoot; - SEC_E_ILLEGAL_MESSAGE: - Result := RSHTTPSSPIIllegalMessage; - SEC_E_CERT_UNKNOWN: - Result := RSHTTPSSPICertUnknown; - SEC_E_CERT_EXPIRED: - Result := RSHTTPSSPICertExpired; - SEC_E_ENCRYPT_FAILURE: - Result := RSHTTPSSPIEncryptionFailure; - SEC_E_DECRYPT_FAILURE: - Result := RSHTTPSSPIDecryptionFailure; - SEC_E_ALGORITHM_MISMATCH: - Result := RSHTTPSSPIAlgorithmMismatch; - SEC_E_SECURITY_QOS_FAILED: - Result := RSHTTPSSPISecurityQOSFailure; - SEC_E_UNFINISHED_CONTEXT_DELETED : - Result := RSHTTPSSPISecCtxWasDelBeforeUpdated; - SEC_E_NO_TGT_REPLY : - Result := RSHTTPSSPIClientNoTGTReply; - SEC_E_NO_IP_ADDRESSES : - Result := RSHTTPSSPILocalNoIPAddr; - SEC_E_WRONG_CREDENTIAL_HANDLE : - Result := RSHTTPSSPIWrongCredHandle; - SEC_E_CRYPTO_SYSTEM_INVALID : - Result := RSHTTPSSPICryptoSysInvalid; - SEC_E_MAX_REFERRALS_EXCEEDED : - Result := RSHTTPSSPIMaxTicketRef; - SEC_E_MUST_BE_KDC : - Result := RSHTTPSSPIMustBeKDC; - SEC_E_STRONG_CRYPTO_NOT_SUPPORTED : - Result := RSHTTPSSPIStrongCryptoNotSupported; - SEC_E_TOO_MANY_PRINCIPALS : - Result := RSHTTPSSPIKDCReplyTooManyPrincipals; - SEC_E_NO_PA_DATA : - Result := RSHTTPSSPINoPAData; - SEC_E_PKINIT_NAME_MISMATCH : - Result := RSHTTPSSPIPKInitNameMismatch; - SEC_E_SMARTCARD_LOGON_REQUIRED : - Result := RSHTTPSSPISmartcardLogonReq; - SEC_E_SHUTDOWN_IN_PROGRESS : - Result := RSHTTPSSPISysShutdownInProg; - SEC_E_KDC_INVALID_REQUEST : - Result := RSHTTPSSPIKDCInvalidRequest; - SEC_E_KDC_UNABLE_TO_REFER : - Result := RSHTTPSSPIKDCUnableToRefer; - SEC_E_KDC_UNKNOWN_ETYPE : - Result := RSHTTPSSPIKDCETypeUnknown; - SEC_E_UNSUPPORTED_PREAUTH : - Result := RSHTTPSSPIUnsupPreauth; - SEC_E_DELEGATION_REQUIRED : - Result := RSHTTPSSPIDeligationReq; - SEC_E_BAD_BINDINGS : - Result := RSHTTPSSPIBadBindings; - SEC_E_MULTIPLE_ACCOUNTS : - Result := RSHTTPSSPIMultipleAccounts; - SEC_E_NO_KERB_KEY : - Result := RSHTTPSSPINoKerbKey; - SEC_E_CERT_WRONG_USAGE : - Result := RSHTTPSSPICertWrongUsage; - SEC_E_DOWNGRADE_DETECTED : - Result := RSHTTPSSPIDowngradeDetected; - SEC_E_SMARTCARD_CERT_REVOKED : - Result := RSHTTPSSPISmartcardCertRevoked; - SEC_E_ISSUING_CA_UNTRUSTED : - Result := RSHTTPSSPIIssuingCAUntrusted; - SEC_E_REVOCATION_OFFLINE_C : - Result := RSHTTPSSPIRevocationOffline; - SEC_E_PKINIT_CLIENT_FAILURE : - Result := RSHTTPSSPIPKInitClientFailure; - SEC_E_SMARTCARD_CERT_EXPIRED : - Result := RSHTTPSSPISmartcardExpired; - SEC_E_NO_S4U_PROT_SUPPORT : - Result := RSHTTPSSPINoS4UProtSupport; - SEC_E_CROSSREALM_DELEGATION_FAILURE : - Result := RSHTTPSSPICrossRealmDeligationFailure; - SEC_E_REVOCATION_OFFLINE_KDC : - Result := RSHTTPSSPIRevocationOfflineKDC; - SEC_E_ISSUING_CA_UNTRUSTED_KDC : - Result := RSHTTPSSPICAUntrustedKDC; - SEC_E_KDC_CERT_EXPIRED : - Result := RSHTTPSSPIKDCCertExpired; - SEC_E_KDC_CERT_REVOKED : - Result := RSHTTPSSPIKDCCertRevoked; - SEC_I_SIGNATURE_NEEDED : - Result := RSHTTPSSPISignatureNeeded; - SEC_E_INVALID_PARAMETER : - Result := RSHTTPSSPIInvalidParameter; - SEC_E_DELEGATION_POLICY : - Result := RSHTTPSSPIDeligationPolicy; - SEC_E_POLICY_NLTM_ONLY : - Result := RSHTTPSSPIPolicyNTLMOnly; - SEC_I_NO_RENEGOTIATION : - Result := RSHTTPSSPINoRenegotiation; - SEC_E_NO_CONTEXT : - Result := RSHTTPSSPINoContext; - SEC_E_PKU2U_CERT_FAILURE : - Result := RSHTTPSSPIPKU2UCertFailure; - SEC_E_MUTUAL_AUTH_FAILED : - Result := RSHTTPSSPIMutualAuthFailed; - else - Result := RSHTTPSSPIUnknwonError; - end; -end; - -constructor ESSPIException.CreateError(const AErrorNo: Integer; const AFailedFuncName: string); -begin - if AErrorNo = SEC_E_OK then begin - inherited Create(AFailedFuncName); - end else begin - inherited CreateFmt(RSHTTPSSPIErrorMsg, - [AFailedFuncName, AErrorNo, AErrorNo, GetErrorMessageByNo(AErrorNo)]); - end; -end; - -{ TSSPIInterface } - -procedure TSSPIInterface.ReleaseFunctionTable; -begin - if fPFunctionTable <> nil then begin - fPFunctionTable := nil; - end; -end; - -procedure TSSPIInterface.CheckAvailable; -begin - if not IsAvailable then begin - raise ESSPIInterfaceInitFailed.Create(RSHTTPSSPIInterfaceInitFailed); - end; -end; - -function TSSPIInterface.GetFunctionTable: SecurityFunctionTable; -begin - CheckAvailable; - Result := fPFunctionTable^; -end; - -class procedure TSSPIInterface.RaiseIfError(aStatus: SECURITY_STATUS; - const aFunctionName: string); -begin - if not SEC_SUCCESS(aStatus) then begin - raise ESSPIException.CreateError(aStatus, aFunctionName); - end; -end; - -function TSSPIInterface.IsAvailable: Boolean; - - procedure LoadDLL; - const - SECURITY_DLL_NT = 'security.dll'; {Do not translate} - SECURITY_DLL_95 = 'secur32.dll'; {Do not translate} - ENCRYPT_MESSAGE = 'EncryptMessage'; {Do not translate} - DECRYPT_MESSAGE = 'DecryptMessage'; {Do not translate} - var - dllName: string; - entrypoint: INIT_SECURITY_INTERFACE; - begin - fIsAvailable := False; - if IndyWindowsPlatform = VER_PLATFORM_WIN32_WINDOWS then - { Windows95 SSPI dll } - dllName := SECURITY_DLL_95 - else - { WindowsNT & Windows2000 SSPI dll } - dllName := SECURITY_DLL_NT; - { load SSPI dll } - //In Windows, you should use SafeLoadLibrary instead of the LoadLibrary API - //call because LoadLibrary messes with the FPU control word. - fDLLHandle := SafeLoadLibrary(dllName); - if fDLLHandle <> IdNilHandle then begin - { get InitSecurityInterface entry point - and call it to fetch SPPI function table} - entrypoint := LoadLibFunction(fDLLHandle, SECURITY_ENTRYPOINT); - fPFunctionTable := entrypoint(); - { let's see what SSPI functions are available - and if we can continue on with the set } - fIsAvailable := - Assigned({$IFDEF SSPI_UNICODE}fPFunctionTable^.QuerySecurityPackageInfoW{$ELSE}fPFunctionTable^.QuerySecurityPackageInfoA{$ENDIF}) and - Assigned(fPFunctionTable^.FreeContextBuffer) and - Assigned(fPFunctionTable^.DeleteSecurityContext) and - Assigned(fPFunctionTable^.FreeCredentialsHandle) and - Assigned({$IFDEF SSPI_UNICODE}fPFunctionTable^.AcquireCredentialsHandleW{$ELSE}fPFunctionTable^.AcquireCredentialsHandleA{$ENDIF}) and - Assigned({$IFDEF SSPI_UNICODE}fPFunctionTable^.InitializeSecurityContextW{$ELSE}fPFunctionTable^.InitializeSecurityContextA{$ENDIF}) and - Assigned(fPFunctionTable^.AcceptSecurityContext) and - Assigned(fPFunctionTable^.ImpersonateSecurityContext) and - Assigned(fPFunctionTable^.RevertSecurityContext) and - Assigned({$IFDEF SSPI_UNICODE}fPFunctionTable^.QueryContextAttributesW{$ELSE}fPFunctionTable^.QueryContextAttributesA{$ENDIF}) and - Assigned(fPFunctionTable^.MakeSignature) and - Assigned(fPFunctionTable^.VerifySignature); - {$IFDEF SET_ENCRYPT_IN_FT_WITH_GETPROCADDRESS_FUDGE} - { fudge for Encrypt/DecryptMessage } - if not Assigned(fPFunctionTable^.EncryptMessage) then begin - fPFunctionTable^.EncryptMessage := LoadLibFunction(fDLLHandle, ENCRYPT_MESSAGE); - end; - if not Assigned(fPFunctionTable^.DecryptMessage) then begin - fPFunctionTable^.DecryptMessage := LoadLibFunction(fDLLHandle, DECRYPT_MESSAGE); - end; - {$ENDIF} - end; - end; - -begin - if not fIsAvailable then begin - if fLoadPending then begin - ReleaseFunctionTable; - LoadDLL; - fLoadPending := False; - end; - end; - Result := fIsAvailable; -end; - -constructor TSSPIInterface.Create; -begin - inherited Create; - fLoadPending := True; - fIsAvailable := False; - fPFunctionTable := nil; -end; - -destructor TSSPIInterface.Destroy; -begin - ReleaseFunctionTable; - if fDLLHandle <> IdNilHandle then begin - FreeLibrary(fDLLHandle); - fDLLHandle := IdNilHandle; - end; - inherited Destroy; -end; - -{ TSSPIPackage } - -constructor TSSPIPackage.Create(aPSecPkginfo: PSecPkgInfo); -begin - inherited Create; - fPSecPkginfo := aPSecPkginfo; -end; - -function TSSPIPackage.GetPSecPkgInfo: PSecPkgInfo; -begin - if not Assigned(fPSecPkginfo) then begin - raise ESSPIException.Create(RSHTTPSSPINoPkgInfoSpecified); - end; - Result := fPSecPkginfo; -end; - -function TSSPIPackage.GetMaxToken: ULONG; -begin - Result := GetPSecPkgInfo^.cbMaxToken; -end; - -function TSSPIPackage.GetName: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}; -begin - Result := GetPSecPkgInfo^.Name; -end; - -{ TCustomSSPIPackage } - -constructor TCustomSSPIPackage.Create(const aPkgName: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}); -begin - gSSPIInterface.RaiseIfError( - {$IFDEF SSPI_UNICODE} - gSSPIInterface.FunctionTable.QuerySecurityPackageInfoW(PWideChar(aPkgName), @fInfo), - 'QuerySecurityPackageInfoW' {Do not translate} - {$ELSE} - gSSPIInterface.FunctionTable.QuerySecurityPackageInfoA(PAnsiChar(aPkgName), @fInfo), - 'QuerySecurityPackageInfoA' {Do not translate} - {$ENDIF} - ); - inherited Create(fInfo); -end; - -destructor TCustomSSPIPackage.Destroy; -begin - if fInfo <> nil then begin - gSSPIInterface.RaiseIfError( - gSSPIInterface.FunctionTable.FreeContextBuffer(fInfo), 'FreeContextBuffer'); {Do not localize} - end; - inherited Destroy; -end; - -{ TSSPINTLMPackage } - -constructor TSSPINTLMPackage.Create; -begin - inherited Create(NTLMSP_NAME); -end; - -{ TSSPICredentials } - -constructor TSSPICredentials.Create(aPackage: TSSPIPackage); -begin - inherited Create; - fPackage := aPackage; - fUse := scuOutBound; - fAcquired := False; -end; - -procedure TSSPICredentials.CheckAcquired; -begin - if not fAcquired then begin - raise ESSPIException.Create(RSHTTPSSPINoCredentialHandle); - end; -end; - -procedure TSSPICredentials.CheckNotAcquired; -begin - if fAcquired then begin - raise ESSPIException.Create(RSHTTPSSPICanNotChangeCredentials); - end; -end; - -procedure TSSPICredentials.DoAcquire - (pszPrincipal: {$IFDEF SSPI_UNICODE}PSEC_WCHAR{$ELSE}PSEC_CHAR{$ENDIF}; pvLogonId, pAuthData: PVOID); -var - cu: ULONG; -begin - Release; - case Use of - scuInBound: - cu := SECPKG_CRED_INBOUND; - scuOutBound: - cu := SECPKG_CRED_OUTBOUND; - scuBoth: - cu := SECPKG_CRED_BOTH; - else - raise ESSPIException.Create(RSHTTPSSPIUnknwonCredentialUse); - end; - gSSPIInterface.RaiseIfError( - gSSPIInterface.FunctionTable.{$IFDEF SSPI_UNICODE}AcquireCredentialsHandleW{$ELSE}AcquireCredentialsHandleA{$ENDIF}( - pszPrincipal, {$IFDEF SSPI_UNICODE}PSEC_WCHAR{$ELSE}PSEC_CHAR{$ENDIF}(Package.Name), cu, pvLogonId, pAuthData, nil, nil, - @fHandle, @fExpiry), - {$IFDEF SSPI_UNICODE} - 'AcquireCredentialsHandleW' {Do not translater} - {$ELSE} - 'AcquireCredentialsHandleA' {Do not translater} - {$ENDIF} - ); - fAcquired := True; -end; - -procedure TSSPICredentials.DoRelease; -begin - gSSPIInterface.RaiseIfError( - gSSPIInterface.FunctionTable.FreeCredentialsHandle(@fHandle), - 'FreeCredentialsHandle'); {Do not translate} - SecInvalidateHandle(fHandle); -end; - -procedure TSSPICredentials.Release; -begin - if fAcquired then begin - DoRelease; - fAcquired := False; - end; -end; - -function TSSPICredentials.GetHandle: PCredHandle; -begin - CheckAcquired; - Result := @fHandle; -end; - -procedure TSSPICredentials.SetUse(aValue: TSSPICredentialsUse); -begin - if fUse <> aValue then begin - CheckNotAcquired; - fUse := aValue; - end; -end; - -destructor TSSPICredentials.Destroy; -begin - Release; - inherited Destroy; -end; - -{ TSSPIWinNTCredentials } - -procedure TSSPIWinNTCredentials.Acquire(aUse: TSSPICredentialsUse); -begin - Acquire(aUse, '', '', ''); {Do not translate} -end; - -procedure TSSPIWinNTCredentials.Acquire(aUse: TSSPICredentialsUse; - const aDomain, aUserName, aPassword: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}); -var - ai: SEC_WINNT_AUTH_IDENTITY; - pai: PVOID; -begin - Use := aUse; - if (Length(aDomain) > 0) and (Length(aUserName) > 0) then begin - {$IFDEF SSPI_UNICODE} - ai.User := PUSHORT(PWideChar(aUserName)); - ai.UserLength := Length(aUserName); - ai.Domain := PUSHORT(PWideChar(aDomain)); - ai.DomainLength := Length(aDomain); - ai.Password := PUSHORT(PWideChar(aPassword)); - ai.PasswordLength := Length(aPassword); - ai.Flags := SEC_WINNT_AUTH_IDENTITY_UNICODE; - {$ELSE} - ai.User := PUCHAR(PAnsiChar(aUserName)); - ai.UserLength := Length(aUserName); - ai.Domain := PUCHAR(PAnsiChar(aDomain)); - ai.DomainLength := Length(aDomain); - ai.Password := PUCHAR(PAnsiChar(aPassword)); - ai.PasswordLength := Length(aPassword); - ai.Flags := SEC_WINNT_AUTH_IDENTITY_ANSI; - {$ENDIF} - pai := @ai; - end else - begin - pai := nil; - end; - DoAcquire(nil, nil, pai); -end; - -{ TSSPIContext } - -constructor TSSPIContext.Create(aCredentials: TSSPICredentials); -begin - inherited Create; - fCredentials := aCredentials; - fHasHandle := False; -end; - -destructor TSSPIContext.Destroy; -begin - Release; - inherited Destroy; -end; - -procedure TSSPIContext.UpdateHasContextAndCheckForError( - const aFuncResult: SECURITY_STATUS; const aFuncName: string; - const aErrorsToIgnore: array of SECURITY_STATUS); -var - doRaise: Boolean; - i: Integer; -begin - doRaise := not SEC_SUCCESS(aFuncResult); - if doRaise then begin - for i := Low(aErrorsToIgnore) to High(aErrorsToIgnore) do begin - if aFuncResult = aErrorsToIgnore[i] then begin - doRaise := False; - Break; - end; - end; - end; - if doRaise then begin - raise ESSPIException.CreateError(aFuncResult, aFuncName); - end; - fHasHandle := True; -end; - -function TSSPIContext.DoInitialize(const aTokenSourceName: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}; - var aIn, aOut: SecBufferDesc; - const errorsToIgnore: array of SECURITY_STATUS): SECURITY_STATUS; -var - tmp: PCtxtHandle; - tmp2: PSecBufferDesc; - r: ULONG; -begin - if fHasHandle then begin - tmp := @fHandle; - tmp2 := @aIn; - end else begin - tmp := nil; - tmp2 := nil; - end; - Result := - gSSPIInterface.FunctionTable.{$IFDEF SSPI_UNICODE}InitializeSecurityContextW{$ELSE}InitializeSecurityContextA{$ENDIF}( - Credentials.Handle, tmp, - {$IFDEF SSPI_UNICODE}PWideChar{$ELSE}PAnsiChar{$ENDIF}(aTokenSourceName), - GetRequestedFlags, 0, SECURITY_NATIVE_DREP, tmp2, 0, - @fHandle, @aOut, @r, @fExpiry - ); - UpdateHasContextAndCheckForError(Result, - {$IFDEF SSPI_UNICODE}'InitializeSecurityContextW'{$ELSE}'InitializeSecurityContextA'{$ENDIF}, {Do not translate} - errorsToIgnore); - SetEstablishedFlags(r); -end; - -procedure TSSPIContext.DoRelease; -begin - gSSPIInterface.RaiseIfError( - gSSPIInterface.FunctionTable.DeleteSecurityContext(@fHandle), 'DeleteSecurityContext'); {Do not translate} -end; - -procedure TSSPIContext.Release; -begin - if HasHandle then begin - DoRelease; - fHasHandle := False; - end; -end; - -procedure TSSPIContext.CheckHasHandle; -begin - if not HasHandle then begin - raise ESSPIException.Create(RSHTTPSSPINoCredentialHandle); - end; -end; - -procedure TSSPIContext.CheckCredentials; -begin - if (not Assigned(Credentials)) or (not Credentials.Acquired) then begin - raise ESSPIException.Create(RSHTTPSSPIDoAuquireCredentialHandle); - end; -end; - -function TSSPIContext.GetExpiry: TimeStamp; -begin - CheckHasHandle; - Result := fExpiry; -end; - -function TSSPIContext.GetHandle: PCtxtHandle; -begin - CheckHasHandle; - Result := @fHandle; -end; - -{ TCustomSSPIConnectionContext } - -procedure TCustomSSPIConnectionContext.DoRelease; -begin - inherited DoRelease; - fStatus := SEC_E_INVALID_HANDLE; // just to put something other then SEC_E_OK -end; - -function TCustomSSPIConnectionContext.GetAuthenticated: Boolean; -begin - CheckHasHandle; - Result := fStatus = SEC_E_OK; -end; - -function TCustomSSPIConnectionContext.UpdateAndGenerateReply - (const aFromPeerToken: TIdBytes; var aToPeerToken: TIdBytes): Boolean; -var - fOutBuff: SecBuffer; -begin - // keep the compiler happy (when was this fixed exactly?) - {$IFDEF DCC}{$IFNDEF VCL_8_OR_ABOVE} - Result := False; - {$ENDIF}{$ENDIF} - - { check credentials } - CheckCredentials; - { prepare input buffer } - - fInBuff.cbBuffer := Length(aFromPeerToken); - - //Assert(Length(aFromPeerToken)>0); - if fInBuff.cbBuffer > 0 then begin - fInBuff.pvBuffer := @aFromPeerToken[0]; - end; - - { prepare output buffer } - fOutBuff.BufferType := SECBUFFER_TOKEN; - fOutBuff.cbBuffer := Credentials.Package.MaxToken; - fOutBuff.pvBuffer := AllocMem(fOutBuff.cbBuffer); - - fOutBuffDesc.ulVersion := SECBUFFER_VERSION; - fOutBuffDesc.cBuffers := 1; - fOutBuffDesc.pBuffers := @fOutBuff; - - try - { do processing } - fStatus := DoUpdateAndGenerateReply(fInBuffDesc, fOutBuffDesc, []); - { complete token if applicable } - case fStatus of - SEC_I_COMPLETE_NEEDED, - SEC_I_COMPLETE_AND_CONTINUE: - begin - if not Assigned(gSSPIInterface.FunctionTable.CompleteAuthToken) then begin - raise ESSPIException.Create(RSHTTPSSPICompleteTokenNotSupported); - end; - fStatus := gSSPIInterface.FunctionTable.CompleteAuthToken(Handle, @fOutBuffDesc); - gSSPIInterface.RaiseIfError(fStatus, 'CompleteAuthToken'); {Do not translate} - end; - end; - Result := - (fStatus = SEC_I_CONTINUE_NEEDED) or - (fStatus = SEC_I_COMPLETE_AND_CONTINUE) or - (fOutBuff.cbBuffer > 0); - if Result then begin - aToPeerToken := RawToBytes(fOutBuff.pvBuffer^, fOutBuff.cbBuffer); - end; - finally - FreeMem(fOutBuff.pvBuffer); - end; -end; - -constructor TCustomSSPIConnectionContext.Create(aCredentials: TSSPICredentials); -begin - inherited Create(aCredentials); - - fInBuff.BufferType := SECBUFFER_TOKEN; - - fInBuffDesc.ulVersion := SECBUFFER_VERSION; - fInBuffDesc.cBuffers := 1; - fInBuffDesc.pBuffers := @fInBuff; - - fOutBuffDesc.ulVersion := SECBUFFER_VERSION; - fOutBuffDesc.cBuffers := 1; -end; - -{ TSSPIClientConnectionContext } - -constructor TSSPIClientConnectionContext.Create(aCredentials: TSSPICredentials); -begin - inherited Create(aCredentials); - fTargetName := ''; {Do not translate} -end; - -function TSSPIClientConnectionContext.GetRequestedFlags: ULONG; -begin - Result := fReqReguested; -end; - -procedure TSSPIClientConnectionContext.SetEstablishedFlags(aFlags: ULONG); -begin - fReqEstablished := aFlags; -end; - -function TSSPIClientConnectionContext.DoUpdateAndGenerateReply - (var aIn, aOut: SecBufferDesc; - const aErrorsToIgnore: array of SECURITY_STATUS): SECURITY_STATUS; -begin - Result := DoInitialize(fTargetName, aIn, aOut, []); -end; - -function TSSPIClientConnectionContext.GenerateInitialChallenge - (const aTargetName: string; var aToPeerToken: TIdBytes): Boolean; -begin - Release; - fTargetName := aTargetName; - Result := UpdateAndGenerateReply(nil, aToPeerToken); {Do not translate} -end; - -{ TIndySSPINTLMClient } - -constructor TIndySSPINTLMClient.Create; -begin - inherited Create; - fNTLMPackage := TSSPINTLMPackage.Create; - fCredentials := TSSPIWinNTCredentials.Create(fNTLMPackage); - fContext := TSSPIClientConnectionContext.Create(fCredentials); -end; - -destructor TIndySSPINTLMClient.Destroy; -begin - FreeAndNil(fContext); - FreeAndNil(fCredentials); - FreeAndNil(fNTLMPackage); - inherited Destroy; -end; - -procedure TIndySSPINTLMClient.SetCredentials(const aDomain, aUserName, aPassword: string); -begin - fCredentials.Acquire(scuOutBound, aDomain, aUserName, aPassword); -end; - -procedure TIndySSPINTLMClient.SetCredentialsAsCurrentUser; -begin - fCredentials.Acquire(scuOutBound); -end; - -function TIndySSPINTLMClient.InitAndBuildType1Message: TIdBytes; -begin - fContext.GenerateInitialChallenge('', Result); -end; - -function TIndySSPINTLMClient.UpdateAndBuildType3Message(const aServerType2Message: TIdBytes): TIdBytes; -begin - fContext.UpdateAndGenerateReply(aServerType2Message, Result); -end; - -{ TIdSSPINTLMAuthentication } - -constructor TIdSSPINTLMAuthentication.Create; -begin - inherited Create; - FSSPIClient := TIndySSPINTLMClient.Create; - Domain := IndyComputerName; -end; - -function TIdSSPINTLMAuthentication.DoNext: TIdAuthWhatsNext; -begin - Result := wnDoRequest; - case FCurrentStep of - //Authentication() does the 2>3 progression - 0, 1, 3: - begin - Inc(FCurrentStep); - Result := wnDoRequest; - end; - 4: - begin - FCurrentStep := 0; - if Username = '' then begin - Result := wnAskTheProgram; - end else begin - Result := wnFail; - Username := ''; - Password := ''; - Domain := IndyComputerName; - end; - end; - end; -end; - -function TIdSSPINTLMAuthentication.Authentication: string; -var - buf: TIdBytes; -begin - Result := ''; - buf := nil; - case FCurrentStep of - 1: - begin - if Length(Username) = 0 then begin - FSSPIClient.SetCredentialsAsCurrentUser; - end else begin - FSSPIClient.SetCredentials(Domain, Username, Password); - end; - Result := 'NTLM ' + TIdEncoderMIME.EncodeBytes(FSSPIClient.InitAndBuildType1Message); {Do not translate} - FNTLMInfo := ''; {Do not translate} - end; - 2: - begin - if Length(FNTLMInfo) = 0 then begin - FNTLMInfo := ReadAuthInfo('NTLM'); {Do not translate} - Fetch(FNTLMInfo); - end; - - if Length(FNTLMInfo) = 0 then begin - Reset; - Abort; - end; - - buf := TIdDecoderMIME.DecodeBytes(FNTLMInfo); - Result := 'NTLM ' + TIdEncoderMIME.EncodeBytes(FSSPIClient.UpdateAndBuildType3Message(buf)); {Do not translate} - - FCurrentStep := 3; - end; - 3: begin - FCurrentStep := 4; - end; - end; -end; - -function TIdSSPINTLMAuthentication.KeepAlive: Boolean; -begin - Result := FCurrentStep >= 1; -end; - -function TIdSSPINTLMAuthentication.GetSteps: Integer; -begin - Result := 3; -end; - -procedure TIdSSPINTLMAuthentication.SetDomain(const Value: String); -begin - Params.Values['Domain'] := Value; {do not localize} -end; - -function TIdSSPINTLMAuthentication.GetDomain: String; -begin - Result := Params.Values['Domain']; {do not localize} -end; - -procedure TIdSSPINTLMAuthentication.SetUserName(const Value: String); -var - S: String; - Idx: Integer; -begin - S := Value; - Idx := IndyPos('\', S); - if Idx > 0 then begin - Domain := Copy(S, 1, Idx - 1); - Delete(S, 1, Idx); - end; - inherited SetUserName(S); -end; - -destructor TIdSSPINTLMAuthentication.Destroy; -begin - FreeAndNil(FSSPIClient); - inherited; -end; - -initialization - gSSPIInterface := TSSPIInterface.Create; - if gSSPIInterface.IsAvailable then begin - RegisterAuthenticationMethod('NTLM', TIdSSPINTLMAuthentication); {do not localize} - RegisterAuthenticationMethod('Negotiate', TIdSSPINTLMAuthentication); {do not localize} - gAuthRegistered := True; - end; -finalization - if gAuthRegistered then begin - UnregisterAuthenticationMethod('NTLM'); {do not localize} - UnregisterAuthenticationMethod('Negotiate'); {do not localize} - end; - FreeAndNil(gSSPIInterface); -{$ENDIF} -end. - +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.3 6/11/2004 9:33:58 AM DSiders + Added "Do not Localize" comments. + + Rev 1.2 13.1.2004 ã. 17:26:06 DBondzhev + Added Domain property + + Rev 1.1 4/12/2003 10:24:04 PM GGrieve + Fix to Compile + + Rev 1.0 11/14/2002 02:13:50 PM JPMugaas +} + +unit IdAuthenticationSSPI; + +{ + Implementation of the NTLM authentication with SSPI + Author: Alex Brainman + Copyright: (c) Chad Z. Hower and The Winshoes Working Group. +} + +{$DEFINE SET_ENCRYPT_IN_FT_WITH_GETPROCADDRESS_FUDGE} + +interface + +{$i IdCompilerDefines.inc} +{$IFDEF USE_SSPI} +uses + IdGlobal, + IdAuthentication, + IdCoder, + Windows, + SysUtils, + IdSSPI; + +const + SEC_E_OK = 0; + {$EXTERNALSYM SEC_E_OK} + SEC_E_INSUFFICIENT_MEMORY = HRESULT($80090300); + {$EXTERNALSYM SEC_E_INSUFFICIENT_MEMORY} + SEC_E_INVALID_HANDLE = HRESULT($80090301); + {$EXTERNALSYM SEC_E_INVALID_HANDLE} + SEC_E_UNSUPPORTED_FUNCTION = HRESULT($80090302); + {$EXTERNALSYM SEC_E_UNSUPPORTED_FUNCTION} + SEC_E_TARGET_UNKNOWN = HRESULT($80090303); + {$EXTERNALSYM SEC_E_TARGET_UNKNOWN} + SEC_E_INTERNAL_ERROR = HRESULT($80090304); + {$EXTERNALSYM SEC_E_INTERNAL_ERROR} + SEC_E_SECPKG_NOT_FOUND = HRESULT($80090305); + {$EXTERNALSYM SEC_E_SECPKG_NOT_FOUND} + SEC_E_NOT_OWNER = HRESULT($80090306); + {$EXTERNALSYM SEC_E_NOT_OWNER} + SEC_E_CANNOT_INSTALL = HRESULT($80090307); + {$EXTERNALSYM SEC_E_CANNOT_INSTALL} + SEC_E_INVALID_TOKEN = HRESULT($80090308); + {$EXTERNALSYM SEC_E_INVALID_TOKEN} + SEC_E_CANNOT_PACK = HRESULT($80090309); + {$EXTERNALSYM SEC_E_CANNOT_PACK} + SEC_E_QOP_NOT_SUPPORTED = HRESULT($8009030A); + {$EXTERNALSYM SEC_E_QOP_NOT_SUPPORTED} + SEC_E_NO_IMPERSONATION = HRESULT($8009030B); + {$EXTERNALSYM SEC_E_NO_IMPERSONATION} + SEC_E_LOGON_DENIED = HRESULT($8009030C); + {$EXTERNALSYM SEC_E_LOGON_DENIED} + SEC_E_UNKNOWN_CREDENTIALS = HRESULT($8009030D); + {$EXTERNALSYM SEC_E_UNKNOWN_CREDENTIALS} + SEC_E_NO_CREDENTIALS = HRESULT($8009030E); + {$EXTERNALSYM SEC_E_NO_CREDENTIALS} + SEC_E_MESSAGE_ALTERED = HRESULT($8009030F); + {$EXTERNALSYM SEC_E_MESSAGE_ALTERED} + SEC_E_OUT_OF_SEQUENCE = HRESULT($80090310); + {$EXTERNALSYM SEC_E_OUT_OF_SEQUENCE} + SEC_E_NO_AUTHENTICATING_AUTHORITY = HRESULT($80090311); + {$EXTERNALSYM SEC_E_NO_AUTHENTICATING_AUTHORITY} + SEC_I_CONTINUE_NEEDED = HRESULT($00090312); + {$EXTERNALSYM SEC_I_CONTINUE_NEEDED} + SEC_I_COMPLETE_NEEDED = HRESULT($00090313); + {$EXTERNALSYM SEC_I_COMPLETE_NEEDED} + SEC_I_COMPLETE_AND_CONTINUE = HRESULT($00090314); + {$EXTERNALSYM SEC_I_COMPLETE_AND_CONTINUE} + SEC_I_LOCAL_LOGON = HRESULT($00090315); + {$EXTERNALSYM SEC_I_LOCAL_LOGON} + SEC_E_BAD_PKGID = HRESULT($80090316); + {$EXTERNALSYM SEC_E_BAD_PKGID} + SEC_E_CONTEXT_EXPIRED = HRESULT($80090317); + {$EXTERNALSYM SEC_E_CONTEXT_EXPIRED} + SEC_E_INCOMPLETE_MESSAGE = HRESULT($80090318); + {$EXTERNALSYM SEC_E_INCOMPLETE_MESSAGE} + SEC_E_INCOMPLETE_CREDENTIALS = HRESULT($80090320); + {$EXTERNALSYM SEC_E_INCOMPLETE_CREDENTIALS} + SEC_E_BUFFER_TOO_SMALL = HRESULT($80090321); + {$EXTERNALSYM SEC_E_BUFFER_TOO_SMALL} + SEC_I_INCOMPLETE_CREDENTIALS = HRESULT($00090320); + {$EXTERNALSYM SEC_I_INCOMPLETE_CREDENTIALS} + SEC_I_RENEGOTIATE = HRESULT($00090321); + {$EXTERNALSYM SEC_I_RENEGOTIATE} + SEC_E_WRONG_PRINCIPAL = HRESULT($80090322); + {$EXTERNALSYM SEC_E_WRONG_PRINCIPAL} + SEC_I_NO_LSA_CONTEXT = HRESULT($00090323); + {$EXTERNALSYM SEC_I_NO_LSA_CONTEXT} + SEC_E_TIME_SKEW = HRESULT($80090324); + {$EXTERNALSYM SEC_E_TIME_SKEW} + SEC_E_UNTRUSTED_ROOT = HRESULT($80090325); + {$EXTERNALSYM SEC_E_UNTRUSTED_ROOT} + SEC_E_ILLEGAL_MESSAGE = HRESULT($80090326); + {$EXTERNALSYM SEC_E_ILLEGAL_MESSAGE} + SEC_E_CERT_UNKNOWN = HRESULT($80090327); + {$EXTERNALSYM SEC_E_CERT_UNKNOWN} + SEC_E_CERT_EXPIRED = HRESULT($80090328); + {$EXTERNALSYM SEC_E_CERT_EXPIRED} + SEC_E_ENCRYPT_FAILURE = HRESULT($80090329); + {$EXTERNALSYM SEC_E_ENCRYPT_FAILURE} + SEC_E_DECRYPT_FAILURE = HRESULT($80090330); + {$EXTERNALSYM SEC_E_DECRYPT_FAILURE} + SEC_E_ALGORITHM_MISMATCH = HRESULT($80090331); + {$EXTERNALSYM SEC_E_ALGORITHM_MISMATCH} + SEC_E_SECURITY_QOS_FAILED = HRESULT($80090332); + {$EXTERNALSYM SEC_E_SECURITY_QOS_FAILED} + + SEC_E_UNFINISHED_CONTEXT_DELETED = HRESULT($80090333); + {$EXTERNALSYM SEC_E_UNFINISHED_CONTEXT_DELETED} + SEC_E_NO_TGT_REPLY = HRESULT($80090334); + {$EXTERNALSYM SEC_E_NO_TGT_REPLY} + SEC_E_NO_IP_ADDRESSES = HRESULT($80090335); + {$EXTERNALSYM SEC_E_NO_IP_ADDRESSES} + SEC_E_WRONG_CREDENTIAL_HANDLE = HRESULT($80090336); + {$EXTERNALSYM SEC_E_WRONG_CREDENTIAL_HANDLE} + SEC_E_CRYPTO_SYSTEM_INVALID = HRESULT($80090337); + {$EXTERNALSYM SEC_E_CRYPTO_SYSTEM_INVALID} + SEC_E_MAX_REFERRALS_EXCEEDED = HRESULT($80090338); + {$EXTERNALSYM SEC_E_MAX_REFERRALS_EXCEEDED} + SEC_E_MUST_BE_KDC = HRESULT($80090339); + {$EXTERNALSYM SEC_E_MUST_BE_KDC} + SEC_E_STRONG_CRYPTO_NOT_SUPPORTED = HRESULT($8009033A); + {$EXTERNALSYM SEC_E_STRONG_CRYPTO_NOT_SUPPORTED} + SEC_E_TOO_MANY_PRINCIPALS = HRESULT($8009033B); + {$EXTERNALSYM SEC_E_TOO_MANY_PRINCIPALS} + SEC_E_NO_PA_DATA = HRESULT($8009033C); + {$EXTERNALSYM SEC_E_NO_PA_DATA} + SEC_E_PKINIT_NAME_MISMATCH = HRESULT($8009033D); + {$EXTERNALSYM SEC_E_PKINIT_NAME_MISMATCH} + SEC_E_SMARTCARD_LOGON_REQUIRED = HRESULT($8009033E); + {$EXTERNALSYM SEC_E_SMARTCARD_LOGON_REQUIRED} + SEC_E_SHUTDOWN_IN_PROGRESS = HRESULT($8009033F); + {$EXTERNALSYM SEC_E_SHUTDOWN_IN_PROGRESS} + SEC_E_KDC_INVALID_REQUEST = HRESULT($80090340); + {$EXTERNALSYM SEC_E_KDC_INVALID_REQUEST} + SEC_E_KDC_UNABLE_TO_REFER = HRESULT($80090341); + {$EXTERNALSYM SEC_E_KDC_UNABLE_TO_REFER} + SEC_E_KDC_UNKNOWN_ETYPE = HRESULT($80090342); + {$EXTERNALSYM SEC_E_KDC_UNKNOWN_ETYPE} + SEC_E_UNSUPPORTED_PREAUTH = HRESULT($80090343); + {$EXTERNALSYM SEC_E_UNSUPPORTED_PREAUTH} + SEC_E_DELEGATION_REQUIRED = HRESULT($80090345); + {$EXTERNALSYM SEC_E_DELEGATION_REQUIRED} + SEC_E_BAD_BINDINGS = HRESULT($80090346); + {$EXTERNALSYM SEC_E_BAD_BINDINGS} + SEC_E_MULTIPLE_ACCOUNTS = HRESULT($80090347); + {$EXTERNALSYM SEC_E_MULTIPLE_ACCOUNTS} + SEC_E_NO_KERB_KEY = HRESULT($80090348); + {$EXTERNALSYM SEC_E_NO_KERB_KEY} + SEC_E_CERT_WRONG_USAGE = HRESULT($80090349); + {$EXTERNALSYM SEC_E_CERT_WRONG_USAGE} + SEC_E_DOWNGRADE_DETECTED = HRESULT($80090350); + {$EXTERNALSYM SEC_E_DOWNGRADE_DETECTED} + SEC_E_SMARTCARD_CERT_REVOKED = HRESULT($80090351); + {$EXTERNALSYM SEC_E_SMARTCARD_CERT_REVOKED} + SEC_E_ISSUING_CA_UNTRUSTED = HRESULT($80090352); + {$EXTERNALSYM SEC_E_ISSUING_CA_UNTRUSTED} + SEC_E_REVOCATION_OFFLINE_C = HRESULT($80090353); + {$EXTERNALSYM SEC_E_REVOCATION_OFFLINE_C} + SEC_E_PKINIT_CLIENT_FAILURE = HRESULT($80090354); + {$EXTERNALSYM SEC_E_PKINIT_CLIENT_FAILURE} + SEC_E_SMARTCARD_CERT_EXPIRED = HRESULT($80090355); + {$EXTERNALSYM SEC_E_SMARTCARD_CERT_EXPIRED} + SEC_E_NO_S4U_PROT_SUPPORT = HRESULT($80090356); + {$EXTERNALSYM SEC_E_NO_S4U_PROT_SUPPORT} + SEC_E_CROSSREALM_DELEGATION_FAILURE = HRESULT($80090357); + {$EXTERNALSYM SEC_E_CROSSREALM_DELEGATION_FAILURE} + SEC_E_REVOCATION_OFFLINE_KDC = HRESULT($80090358); + {$EXTERNALSYM SEC_E_REVOCATION_OFFLINE_KDC} + SEC_E_ISSUING_CA_UNTRUSTED_KDC = HRESULT($80090359); + {$EXTERNALSYM SEC_E_ISSUING_CA_UNTRUSTED_KDC} + SEC_E_KDC_CERT_EXPIRED = HRESULT($8009035A); + {$EXTERNALSYM SEC_E_KDC_CERT_EXPIRED} + SEC_E_KDC_CERT_REVOKED = HRESULT($8009035B); + {$EXTERNALSYM SEC_E_KDC_CERT_REVOKED} + SEC_I_SIGNATURE_NEEDED = HRESULT($0009035C); + {$EXTERNALSYM SEC_I_SIGNATURE_NEEDED} + SEC_E_INVALID_PARAMETER = HRESULT($8009035D); + {$EXTERNALSYM SEC_E_INVALID_PARAMETER} + SEC_E_DELEGATION_POLICY = HRESULT($8009035E); + {$EXTERNALSYM SEC_E_DELEGATION_POLICY} + SEC_E_POLICY_NLTM_ONLY = HRESULT($8009035F); + {$EXTERNALSYM SEC_E_POLICY_NLTM_ONLY} + SEC_I_NO_RENEGOTIATION = HRESULT($00090360); + {$EXTERNALSYM SEC_I_NO_RENEGOTIATION} + SEC_E_NO_CONTEXT = HRESULT($80090361); + {$EXTERNALSYM SEC_E_NO_CONTEXT} + SEC_E_PKU2U_CERT_FAILURE = HRESULT($80090362); + {$EXTERNALSYM SEC_E_PKU2U_CERT_FAILURE} + SEC_E_MUTUAL_AUTH_FAILED = HRESULT($80090363); + {$EXTERNALSYM SEC_E_MUTUAL_AUTH_FAILED} + +type + ESSPIException = class(Exception) + public + // Params must be in this order to avoid conflict with CreateHelp + // constructor in CBuilder as CB does not differentiate constructors + // by name as Delphi does + constructor CreateError(const AErrorNo: Integer; const AFailedFuncName: string); + // + class function GetErrorMessageByNo(AErrorNo: UInt32): string; + end; + + ESSPIInterfaceInitFailed = class(ESSPIException); + + { TSSPIInterface } + + TSSPIInterface = class(TObject) + private + fLoadPending, fIsAvailable: Boolean; + fPFunctionTable: PSecurityFunctionTable; + fDLLHandle: TIdLibHandle; + procedure ReleaseFunctionTable; + procedure CheckAvailable; + function GetFunctionTable: SecurityFunctionTable; + public + class procedure RaiseIfError(aStatus: SECURITY_STATUS; const aFunctionName: string); + function IsAvailable: Boolean; + property FunctionTable: SecurityFunctionTable read GetFunctionTable; + public + constructor Create; + destructor Destroy; override; + end; + + { TSSPIPackages } + + TSSPIPackage = class(TObject) + private + fPSecPkginfo: PSecPkgInfo; + function GetPSecPkgInfo: PSecPkgInfo; + function GetMaxToken: ULONG; + function GetName: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}; + public + property MaxToken: ULONG read GetMaxToken; + property Name: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF} read GetName; + public + constructor Create(aPSecPkginfo: PSecPkgInfo); + end; + + TCustomSSPIPackage = class(TSSPIPackage) + private + fInfo: PSecPkgInfo; + public + constructor Create(const aPkgName: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}); + destructor Destroy; override; + end; + + TSSPINTLMPackage = class(TCustomSSPIPackage) + public + constructor Create; + end; + + { TSSPICredentials } + + TSSPICredentialsUse = (scuInBound, scuOutBound, scuBoth); + + TSSPICredentials = class(TObject) + private + fPackage: TSSPIPackage; + fHandle: CredHandle; + fUse: TSSPICredentialsUse; + fAcquired: Boolean; + fExpiry: TimeStamp; + function GetHandle: PCredHandle; + procedure SetUse(aValue: TSSPICredentialsUse); + protected + procedure CheckAcquired; + procedure CheckNotAcquired; + procedure DoAcquire(pszPrincipal: {$IFDEF SSPI_UNICODE}PSEC_WCHAR{$ELSE}PSEC_CHAR{$ENDIF}; pvLogonId, pAuthData: PVOID); + procedure DoRelease; virtual; + public + procedure Release; + property Package: TSSPIPackage read fPackage; + property Handle: PCredHandle read GetHandle; + property Use: TSSPICredentialsUse read fUse write SetUse; + property Acquired: Boolean read fAcquired; + public + constructor Create(aPackage: TSSPIPackage); + destructor Destroy; override; + end; + + { TSSPIWinNTCredentials } + + TSSPIWinNTCredentials = class(TSSPICredentials) + protected + public + procedure Acquire(aUse: TSSPICredentialsUse); overload; + procedure Acquire(aUse: TSSPICredentialsUse; + const aDomain, aUserName, aPassword: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}); overload; + end; + + { TSSPIContext } + + TSSPIContext = class(TObject) + private + fCredentials: TSSPICredentials; + fHandle: CtxtHandle; + fHasHandle: Boolean; + fExpiry: TimeStamp; + function GetHandle: PCtxtHandle; + function GetExpiry: TimeStamp; + procedure UpdateHasContextAndCheckForError( + const aFuncResult: SECURITY_STATUS; const aFuncName: string; + const aErrorsToIgnore: array of SECURITY_STATUS); + protected + procedure CheckHasHandle; + procedure CheckCredentials; + function DoInitialize(const aTokenSourceName: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}; + var aIn, aOut: SecBufferDesc; + const errorsToIgnore: array of SECURITY_STATUS): SECURITY_STATUS; + procedure DoRelease; virtual; + function GetRequestedFlags: ULONG; virtual; abstract; + procedure SetEstablishedFlags(aFlags: ULONG); virtual; abstract; + function GetAuthenticated: Boolean; virtual; abstract; + property HasHandle: Boolean read fHasHandle; + public + procedure Release; + property Credentials: TSSPICredentials read fCredentials; + property Handle: PCtxtHandle read GetHandle; + property Authenticated: Boolean read GetAuthenticated; + property Expiry: TimeStamp read GetExpiry; + public + constructor Create(aCredentials: TSSPICredentials); + destructor Destroy; override; + end; + + { TSSPIConnectionContext } + + TCustomSSPIConnectionContext = class(TSSPIContext) + private + fStatus: SECURITY_STATUS; + fOutBuffDesc, fInBuffDesc: SecBufferDesc; + fInBuff: SecBuffer; + protected + procedure DoRelease; override; + function GetAuthenticated: Boolean; override; + function DoUpdateAndGenerateReply(var aIn, aOut: SecBufferDesc; + const aErrorsToIgnore: array of SECURITY_STATUS + ): SECURITY_STATUS; virtual; abstract; + public + constructor Create(ACredentials: TSSPICredentials); + function UpdateAndGenerateReply( + const aFromPeerToken: TIdBytes; var aToPeerToken: TIdBytes): Boolean; + end; + + TSSPIClientConnectionContext = class(TCustomSSPIConnectionContext) + private + fTargetName: string; + fReqReguested, fReqEstablished: ULONG; + protected + function GetRequestedFlags: ULONG; override; + procedure SetEstablishedFlags(aFlags: ULONG); override; + function DoUpdateAndGenerateReply(var aIn, aOut: SecBufferDesc; + const aErrorsToIgnore: array of SECURITY_STATUS + ): SECURITY_STATUS; override; + public + function GenerateInitialChallenge(const aTargetName: string; + var aToPeerToken: TIdBytes): Boolean; + public + constructor Create(aCredentials: TSSPICredentials); + end; + + TIndySSPINTLMClient = class(TObject) + protected + fNTLMPackage: TSSPINTLMPackage; + fCredentials: TSSPIWinNTCredentials; + fContext: TSSPIClientConnectionContext; + public + procedure SetCredentials(const aDomain, aUserName, aPassword: string); + procedure SetCredentialsAsCurrentUser; + function InitAndBuildType1Message: TIdBytes; + function UpdateAndBuildType3Message(const aServerType2Message: TIdBytes): TIdBytes; + public + constructor Create; + destructor Destroy; override; + end; + + TIdSSPINTLMAuthentication = class(TIdAuthentication) + protected + FNTLMInfo: string; + FSSPIClient: TIndySSPINTLMClient; + procedure SetDomain(const Value: String); + function GetDomain: String; + procedure SetUserName(const Value: String); override; + function GetSteps: Integer; override; + function DoNext: TIdAuthWhatsNext; override; + public + constructor Create; override; + destructor Destroy; override; + function Authentication: string; override; + function KeepAlive: Boolean; override; + property Domain: String read GetDomain write SetDomain; + end; + + // RLebeau 4/17/10: this forces C++Builder to link to this unit so + // RegisterAuthenticationMethod can be called correctly at program startup... + + {$IFDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT} + {$HPPEMIT LINKUNIT} + {$ELSE} + {$HPPEMIT '#pragma link "IdAuthenticationSSPI"'} + {$ENDIF} + +{$ENDIF} +implementation +{$IFDEF USE_SSPI} +uses + IdGlobalProtocols, + IdCoderMIME, + IdResourceStringsSSPI, + IdHeaderList; + +var + gSSPIInterface: TSSPIInterface = nil; + gAuthRegistered: Boolean = False; + +{ ESSPIException } + +class function ESSPIException.GetErrorMessageByNo(aErrorNo: UInt32): string; +begin + case HRESULT(aErrorNo) of + SEC_E_OK: + Result := RSHTTPSSPISuccess; + SEC_E_INSUFFICIENT_MEMORY: + Result := RSHTTPSSPINotEnoughMem; + SEC_E_INVALID_HANDLE: + Result := RSHTTPSSPIInvalidHandle; + SEC_E_UNSUPPORTED_FUNCTION: + Result := RSHTTPSSPIFuncNotSupported; + SEC_E_TARGET_UNKNOWN: + Result := RSHTTPSSPIUnknownTarget; + SEC_E_INTERNAL_ERROR: + Result := RSHTTPSSPIInternalError; + SEC_E_SECPKG_NOT_FOUND: + Result := RSHTTPSSPISecPackageNotFound; + SEC_E_NOT_OWNER: + Result := RSHTTPSSPINotOwner; + SEC_E_CANNOT_INSTALL: + Result := RSHTTPSSPIPackageCannotBeInstalled; + SEC_E_INVALID_TOKEN: + Result := RSHTTPSSPIInvalidToken; + SEC_E_CANNOT_PACK: + Result := RSHTTPSSPICannotPack; + SEC_E_QOP_NOT_SUPPORTED: + Result := RSHTTPSSPIQOPNotSupported; + SEC_E_NO_IMPERSONATION: + Result := RSHTTPSSPINoImpersonation; + SEC_E_LOGON_DENIED: + Result := RSHTTPSSPILoginDenied; + SEC_E_UNKNOWN_CREDENTIALS: + Result := RSHTTPSSPIUnknownCredentials; + SEC_E_NO_CREDENTIALS: + Result := RSHTTPSSPINoCredentials; + SEC_E_MESSAGE_ALTERED: + Result := RSHTTPSSPIMessageAltered; + SEC_E_OUT_OF_SEQUENCE: + Result := RSHTTPSSPIOutOfSequence; + SEC_E_NO_AUTHENTICATING_AUTHORITY: + Result := RSHTTPSSPINoAuthAuthority; + SEC_I_CONTINUE_NEEDED: + Result := RSHTTPSSPIContinueNeeded; + SEC_I_COMPLETE_NEEDED: + Result := RSHTTPSSPICompleteNeeded; + SEC_I_COMPLETE_AND_CONTINUE: + Result :=RSHTTPSSPICompleteContinueNeeded; + SEC_I_LOCAL_LOGON: + Result := RSHTTPSSPILocalLogin; + SEC_E_BAD_PKGID: + Result := RSHTTPSSPIBadPackageID; + SEC_E_CONTEXT_EXPIRED: + Result := RSHTTPSSPIContextExpired; + SEC_E_INCOMPLETE_MESSAGE: + Result := RSHTTPSSPIIncompleteMessage; + SEC_E_INCOMPLETE_CREDENTIALS: + Result := RSHTTPSSPIIncompleteCredentialNotInit; + SEC_E_BUFFER_TOO_SMALL: + Result := RSHTTPSSPIBufferTooSmall; + SEC_I_INCOMPLETE_CREDENTIALS: + Result := RSHTTPSSPIIncompleteCredentialsInit; + SEC_I_RENEGOTIATE: + Result := RSHTTPSSPIRengotiate; + SEC_E_WRONG_PRINCIPAL: + Result := RSHTTPSSPIWrongPrincipal; + SEC_I_NO_LSA_CONTEXT: + Result := RSHTTPSSPINoLSACode; + SEC_E_TIME_SKEW: + Result := RSHTTPSSPITimeScew; + SEC_E_UNTRUSTED_ROOT: + Result := RSHTTPSSPIUntrustedRoot; + SEC_E_ILLEGAL_MESSAGE: + Result := RSHTTPSSPIIllegalMessage; + SEC_E_CERT_UNKNOWN: + Result := RSHTTPSSPICertUnknown; + SEC_E_CERT_EXPIRED: + Result := RSHTTPSSPICertExpired; + SEC_E_ENCRYPT_FAILURE: + Result := RSHTTPSSPIEncryptionFailure; + SEC_E_DECRYPT_FAILURE: + Result := RSHTTPSSPIDecryptionFailure; + SEC_E_ALGORITHM_MISMATCH: + Result := RSHTTPSSPIAlgorithmMismatch; + SEC_E_SECURITY_QOS_FAILED: + Result := RSHTTPSSPISecurityQOSFailure; + SEC_E_UNFINISHED_CONTEXT_DELETED : + Result := RSHTTPSSPISecCtxWasDelBeforeUpdated; + SEC_E_NO_TGT_REPLY : + Result := RSHTTPSSPIClientNoTGTReply; + SEC_E_NO_IP_ADDRESSES : + Result := RSHTTPSSPILocalNoIPAddr; + SEC_E_WRONG_CREDENTIAL_HANDLE : + Result := RSHTTPSSPIWrongCredHandle; + SEC_E_CRYPTO_SYSTEM_INVALID : + Result := RSHTTPSSPICryptoSysInvalid; + SEC_E_MAX_REFERRALS_EXCEEDED : + Result := RSHTTPSSPIMaxTicketRef; + SEC_E_MUST_BE_KDC : + Result := RSHTTPSSPIMustBeKDC; + SEC_E_STRONG_CRYPTO_NOT_SUPPORTED : + Result := RSHTTPSSPIStrongCryptoNotSupported; + SEC_E_TOO_MANY_PRINCIPALS : + Result := RSHTTPSSPIKDCReplyTooManyPrincipals; + SEC_E_NO_PA_DATA : + Result := RSHTTPSSPINoPAData; + SEC_E_PKINIT_NAME_MISMATCH : + Result := RSHTTPSSPIPKInitNameMismatch; + SEC_E_SMARTCARD_LOGON_REQUIRED : + Result := RSHTTPSSPISmartcardLogonReq; + SEC_E_SHUTDOWN_IN_PROGRESS : + Result := RSHTTPSSPISysShutdownInProg; + SEC_E_KDC_INVALID_REQUEST : + Result := RSHTTPSSPIKDCInvalidRequest; + SEC_E_KDC_UNABLE_TO_REFER : + Result := RSHTTPSSPIKDCUnableToRefer; + SEC_E_KDC_UNKNOWN_ETYPE : + Result := RSHTTPSSPIKDCETypeUnknown; + SEC_E_UNSUPPORTED_PREAUTH : + Result := RSHTTPSSPIUnsupPreauth; + SEC_E_DELEGATION_REQUIRED : + Result := RSHTTPSSPIDeligationReq; + SEC_E_BAD_BINDINGS : + Result := RSHTTPSSPIBadBindings; + SEC_E_MULTIPLE_ACCOUNTS : + Result := RSHTTPSSPIMultipleAccounts; + SEC_E_NO_KERB_KEY : + Result := RSHTTPSSPINoKerbKey; + SEC_E_CERT_WRONG_USAGE : + Result := RSHTTPSSPICertWrongUsage; + SEC_E_DOWNGRADE_DETECTED : + Result := RSHTTPSSPIDowngradeDetected; + SEC_E_SMARTCARD_CERT_REVOKED : + Result := RSHTTPSSPISmartcardCertRevoked; + SEC_E_ISSUING_CA_UNTRUSTED : + Result := RSHTTPSSPIIssuingCAUntrusted; + SEC_E_REVOCATION_OFFLINE_C : + Result := RSHTTPSSPIRevocationOffline; + SEC_E_PKINIT_CLIENT_FAILURE : + Result := RSHTTPSSPIPKInitClientFailure; + SEC_E_SMARTCARD_CERT_EXPIRED : + Result := RSHTTPSSPISmartcardExpired; + SEC_E_NO_S4U_PROT_SUPPORT : + Result := RSHTTPSSPINoS4UProtSupport; + SEC_E_CROSSREALM_DELEGATION_FAILURE : + Result := RSHTTPSSPICrossRealmDeligationFailure; + SEC_E_REVOCATION_OFFLINE_KDC : + Result := RSHTTPSSPIRevocationOfflineKDC; + SEC_E_ISSUING_CA_UNTRUSTED_KDC : + Result := RSHTTPSSPICAUntrustedKDC; + SEC_E_KDC_CERT_EXPIRED : + Result := RSHTTPSSPIKDCCertExpired; + SEC_E_KDC_CERT_REVOKED : + Result := RSHTTPSSPIKDCCertRevoked; + SEC_I_SIGNATURE_NEEDED : + Result := RSHTTPSSPISignatureNeeded; + SEC_E_INVALID_PARAMETER : + Result := RSHTTPSSPIInvalidParameter; + SEC_E_DELEGATION_POLICY : + Result := RSHTTPSSPIDeligationPolicy; + SEC_E_POLICY_NLTM_ONLY : + Result := RSHTTPSSPIPolicyNTLMOnly; + SEC_I_NO_RENEGOTIATION : + Result := RSHTTPSSPINoRenegotiation; + SEC_E_NO_CONTEXT : + Result := RSHTTPSSPINoContext; + SEC_E_PKU2U_CERT_FAILURE : + Result := RSHTTPSSPIPKU2UCertFailure; + SEC_E_MUTUAL_AUTH_FAILED : + Result := RSHTTPSSPIMutualAuthFailed; + else + Result := RSHTTPSSPIUnknwonError; + end; +end; + +constructor ESSPIException.CreateError(const AErrorNo: Integer; const AFailedFuncName: string); +begin + if AErrorNo = SEC_E_OK then begin + inherited Create(AFailedFuncName); + end else begin + inherited CreateFmt(RSHTTPSSPIErrorMsg, + [AFailedFuncName, AErrorNo, AErrorNo, GetErrorMessageByNo(AErrorNo)]); + end; +end; + +{ TSSPIInterface } + +procedure TSSPIInterface.ReleaseFunctionTable; +begin + if fPFunctionTable <> nil then begin + fPFunctionTable := nil; + end; +end; + +procedure TSSPIInterface.CheckAvailable; +begin + if not IsAvailable then begin + raise ESSPIInterfaceInitFailed.Create(RSHTTPSSPIInterfaceInitFailed); + end; +end; + +function TSSPIInterface.GetFunctionTable: SecurityFunctionTable; +begin + CheckAvailable; + Result := fPFunctionTable^; +end; + +class procedure TSSPIInterface.RaiseIfError(aStatus: SECURITY_STATUS; + const aFunctionName: string); +begin + if not SEC_SUCCESS(aStatus) then begin + raise ESSPIException.CreateError(aStatus, aFunctionName); + end; +end; + +function TSSPIInterface.IsAvailable: Boolean; + + procedure LoadDLL; + const + SECURITY_DLL_NT = 'security.dll'; {Do not translate} + SECURITY_DLL_95 = 'secur32.dll'; {Do not translate} + ENCRYPT_MESSAGE = 'EncryptMessage'; {Do not translate} + DECRYPT_MESSAGE = 'DecryptMessage'; {Do not translate} + var + dllName: string; + entrypoint: INIT_SECURITY_INTERFACE; + begin + fIsAvailable := False; + if IndyWindowsPlatform = VER_PLATFORM_WIN32_WINDOWS then + { Windows95 SSPI dll } + dllName := SECURITY_DLL_95 + else + { WindowsNT & Windows2000 SSPI dll } + dllName := SECURITY_DLL_NT; + { load SSPI dll } + //In Windows, you should use SafeLoadLibrary instead of the LoadLibrary API + //call because LoadLibrary messes with the FPU control word. + fDLLHandle := SafeLoadLibrary(dllName); + if fDLLHandle <> IdNilHandle then begin + { get InitSecurityInterface entry point + and call it to fetch SPPI function table} + entrypoint := LoadLibFunction(fDLLHandle, SECURITY_ENTRYPOINT); + fPFunctionTable := entrypoint(); + { let's see what SSPI functions are available + and if we can continue on with the set } + fIsAvailable := + Assigned({$IFDEF SSPI_UNICODE}fPFunctionTable^.QuerySecurityPackageInfoW{$ELSE}fPFunctionTable^.QuerySecurityPackageInfoA{$ENDIF}) and + Assigned(fPFunctionTable^.FreeContextBuffer) and + Assigned(fPFunctionTable^.DeleteSecurityContext) and + Assigned(fPFunctionTable^.FreeCredentialsHandle) and + Assigned({$IFDEF SSPI_UNICODE}fPFunctionTable^.AcquireCredentialsHandleW{$ELSE}fPFunctionTable^.AcquireCredentialsHandleA{$ENDIF}) and + Assigned({$IFDEF SSPI_UNICODE}fPFunctionTable^.InitializeSecurityContextW{$ELSE}fPFunctionTable^.InitializeSecurityContextA{$ENDIF}) and + Assigned(fPFunctionTable^.AcceptSecurityContext) and + Assigned(fPFunctionTable^.ImpersonateSecurityContext) and + Assigned(fPFunctionTable^.RevertSecurityContext) and + Assigned({$IFDEF SSPI_UNICODE}fPFunctionTable^.QueryContextAttributesW{$ELSE}fPFunctionTable^.QueryContextAttributesA{$ENDIF}) and + Assigned(fPFunctionTable^.MakeSignature) and + Assigned(fPFunctionTable^.VerifySignature); + {$IFDEF SET_ENCRYPT_IN_FT_WITH_GETPROCADDRESS_FUDGE} + { fudge for Encrypt/DecryptMessage } + if not Assigned(fPFunctionTable^.EncryptMessage) then begin + fPFunctionTable^.EncryptMessage := LoadLibFunction(fDLLHandle, ENCRYPT_MESSAGE); + end; + if not Assigned(fPFunctionTable^.DecryptMessage) then begin + fPFunctionTable^.DecryptMessage := LoadLibFunction(fDLLHandle, DECRYPT_MESSAGE); + end; + {$ENDIF} + end; + end; + +begin + if not fIsAvailable then begin + if fLoadPending then begin + ReleaseFunctionTable; + LoadDLL; + fLoadPending := False; + end; + end; + Result := fIsAvailable; +end; + +constructor TSSPIInterface.Create; +begin + inherited Create; + fLoadPending := True; + fIsAvailable := False; + fPFunctionTable := nil; +end; + +destructor TSSPIInterface.Destroy; +begin + ReleaseFunctionTable; + if fDLLHandle <> IdNilHandle then begin + FreeLibrary(fDLLHandle); + fDLLHandle := IdNilHandle; + end; + inherited Destroy; +end; + +{ TSSPIPackage } + +constructor TSSPIPackage.Create(aPSecPkginfo: PSecPkgInfo); +begin + inherited Create; + fPSecPkginfo := aPSecPkginfo; +end; + +function TSSPIPackage.GetPSecPkgInfo: PSecPkgInfo; +begin + if not Assigned(fPSecPkginfo) then begin + raise ESSPIException.Create(RSHTTPSSPINoPkgInfoSpecified); + end; + Result := fPSecPkginfo; +end; + +function TSSPIPackage.GetMaxToken: ULONG; +begin + Result := GetPSecPkgInfo^.cbMaxToken; +end; + +function TSSPIPackage.GetName: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}; +begin + Result := GetPSecPkgInfo^.Name; +end; + +{ TCustomSSPIPackage } + +constructor TCustomSSPIPackage.Create(const aPkgName: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}); +begin + gSSPIInterface.RaiseIfError( + {$IFDEF SSPI_UNICODE} + gSSPIInterface.FunctionTable.QuerySecurityPackageInfoW(PWideChar(aPkgName), @fInfo), + 'QuerySecurityPackageInfoW' {Do not translate} + {$ELSE} + gSSPIInterface.FunctionTable.QuerySecurityPackageInfoA(PAnsiChar(aPkgName), @fInfo), + 'QuerySecurityPackageInfoA' {Do not translate} + {$ENDIF} + ); + inherited Create(fInfo); +end; + +destructor TCustomSSPIPackage.Destroy; +begin + if fInfo <> nil then begin + gSSPIInterface.RaiseIfError( + gSSPIInterface.FunctionTable.FreeContextBuffer(fInfo), 'FreeContextBuffer'); {Do not localize} + end; + inherited Destroy; +end; + +{ TSSPINTLMPackage } + +constructor TSSPINTLMPackage.Create; +begin + inherited Create(NTLMSP_NAME); +end; + +{ TSSPICredentials } + +constructor TSSPICredentials.Create(aPackage: TSSPIPackage); +begin + inherited Create; + fPackage := aPackage; + fUse := scuOutBound; + fAcquired := False; +end; + +procedure TSSPICredentials.CheckAcquired; +begin + if not fAcquired then begin + raise ESSPIException.Create(RSHTTPSSPINoCredentialHandle); + end; +end; + +procedure TSSPICredentials.CheckNotAcquired; +begin + if fAcquired then begin + raise ESSPIException.Create(RSHTTPSSPICanNotChangeCredentials); + end; +end; + +procedure TSSPICredentials.DoAcquire + (pszPrincipal: {$IFDEF SSPI_UNICODE}PSEC_WCHAR{$ELSE}PSEC_CHAR{$ENDIF}; pvLogonId, pAuthData: PVOID); +var + cu: ULONG; +begin + Release; + case Use of + scuInBound: + cu := SECPKG_CRED_INBOUND; + scuOutBound: + cu := SECPKG_CRED_OUTBOUND; + scuBoth: + cu := SECPKG_CRED_BOTH; + else + raise ESSPIException.Create(RSHTTPSSPIUnknwonCredentialUse); + end; + gSSPIInterface.RaiseIfError( + gSSPIInterface.FunctionTable.{$IFDEF SSPI_UNICODE}AcquireCredentialsHandleW{$ELSE}AcquireCredentialsHandleA{$ENDIF}( + pszPrincipal, {$IFDEF SSPI_UNICODE}PSEC_WCHAR{$ELSE}PSEC_CHAR{$ENDIF}(Package.Name), cu, pvLogonId, pAuthData, nil, nil, + @fHandle, @fExpiry), + {$IFDEF SSPI_UNICODE} + 'AcquireCredentialsHandleW' {Do not translater} + {$ELSE} + 'AcquireCredentialsHandleA' {Do not translater} + {$ENDIF} + ); + fAcquired := True; +end; + +procedure TSSPICredentials.DoRelease; +begin + gSSPIInterface.RaiseIfError( + gSSPIInterface.FunctionTable.FreeCredentialsHandle(@fHandle), + 'FreeCredentialsHandle'); {Do not translate} + SecInvalidateHandle(fHandle); +end; + +procedure TSSPICredentials.Release; +begin + if fAcquired then begin + DoRelease; + fAcquired := False; + end; +end; + +function TSSPICredentials.GetHandle: PCredHandle; +begin + CheckAcquired; + Result := @fHandle; +end; + +procedure TSSPICredentials.SetUse(aValue: TSSPICredentialsUse); +begin + if fUse <> aValue then begin + CheckNotAcquired; + fUse := aValue; + end; +end; + +destructor TSSPICredentials.Destroy; +begin + Release; + inherited Destroy; +end; + +{ TSSPIWinNTCredentials } + +procedure TSSPIWinNTCredentials.Acquire(aUse: TSSPICredentialsUse); +begin + Acquire(aUse, '', '', ''); {Do not translate} +end; + +procedure TSSPIWinNTCredentials.Acquire(aUse: TSSPICredentialsUse; + const aDomain, aUserName, aPassword: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}); +var + ai: SEC_WINNT_AUTH_IDENTITY; + pai: PVOID; +begin + Use := aUse; + if (Length(aDomain) > 0) and (Length(aUserName) > 0) then begin + {$IFDEF SSPI_UNICODE} + ai.User := PUSHORT(PWideChar(aUserName)); + ai.UserLength := Length(aUserName); + ai.Domain := PUSHORT(PWideChar(aDomain)); + ai.DomainLength := Length(aDomain); + ai.Password := PUSHORT(PWideChar(aPassword)); + ai.PasswordLength := Length(aPassword); + ai.Flags := SEC_WINNT_AUTH_IDENTITY_UNICODE; + {$ELSE} + ai.User := PUCHAR(PAnsiChar(aUserName)); + ai.UserLength := Length(aUserName); + ai.Domain := PUCHAR(PAnsiChar(aDomain)); + ai.DomainLength := Length(aDomain); + ai.Password := PUCHAR(PAnsiChar(aPassword)); + ai.PasswordLength := Length(aPassword); + ai.Flags := SEC_WINNT_AUTH_IDENTITY_ANSI; + {$ENDIF} + pai := @ai; + end else + begin + pai := nil; + end; + DoAcquire(nil, nil, pai); +end; + +{ TSSPIContext } + +constructor TSSPIContext.Create(aCredentials: TSSPICredentials); +begin + inherited Create; + fCredentials := aCredentials; + fHasHandle := False; +end; + +destructor TSSPIContext.Destroy; +begin + Release; + inherited Destroy; +end; + +procedure TSSPIContext.UpdateHasContextAndCheckForError( + const aFuncResult: SECURITY_STATUS; const aFuncName: string; + const aErrorsToIgnore: array of SECURITY_STATUS); +var + doRaise: Boolean; + i: Integer; +begin + doRaise := not SEC_SUCCESS(aFuncResult); + if doRaise then begin + for i := Low(aErrorsToIgnore) to High(aErrorsToIgnore) do begin + if aFuncResult = aErrorsToIgnore[i] then begin + doRaise := False; + Break; + end; + end; + end; + if doRaise then begin + raise ESSPIException.CreateError(aFuncResult, aFuncName); + end; + fHasHandle := True; +end; + +function TSSPIContext.DoInitialize(const aTokenSourceName: {$IFDEF SSPI_UNICODE}TIdUnicodeString{$ELSE}AnsiString{$ENDIF}; + var aIn, aOut: SecBufferDesc; + const errorsToIgnore: array of SECURITY_STATUS): SECURITY_STATUS; +var + tmp: PCtxtHandle; + tmp2: PSecBufferDesc; + r: ULONG; +begin + if fHasHandle then begin + tmp := @fHandle; + tmp2 := @aIn; + end else begin + tmp := nil; + tmp2 := nil; + end; + Result := + gSSPIInterface.FunctionTable.{$IFDEF SSPI_UNICODE}InitializeSecurityContextW{$ELSE}InitializeSecurityContextA{$ENDIF}( + Credentials.Handle, tmp, + {$IFDEF SSPI_UNICODE}PWideChar{$ELSE}PAnsiChar{$ENDIF}(aTokenSourceName), + GetRequestedFlags, 0, SECURITY_NATIVE_DREP, tmp2, 0, + @fHandle, @aOut, @r, @fExpiry + ); + UpdateHasContextAndCheckForError(Result, + {$IFDEF SSPI_UNICODE}'InitializeSecurityContextW'{$ELSE}'InitializeSecurityContextA'{$ENDIF}, {Do not translate} + errorsToIgnore); + SetEstablishedFlags(r); +end; + +procedure TSSPIContext.DoRelease; +begin + gSSPIInterface.RaiseIfError( + gSSPIInterface.FunctionTable.DeleteSecurityContext(@fHandle), 'DeleteSecurityContext'); {Do not translate} +end; + +procedure TSSPIContext.Release; +begin + if HasHandle then begin + DoRelease; + fHasHandle := False; + end; +end; + +procedure TSSPIContext.CheckHasHandle; +begin + if not HasHandle then begin + raise ESSPIException.Create(RSHTTPSSPINoCredentialHandle); + end; +end; + +procedure TSSPIContext.CheckCredentials; +begin + if (not Assigned(Credentials)) or (not Credentials.Acquired) then begin + raise ESSPIException.Create(RSHTTPSSPIDoAuquireCredentialHandle); + end; +end; + +function TSSPIContext.GetExpiry: TimeStamp; +begin + CheckHasHandle; + Result := fExpiry; +end; + +function TSSPIContext.GetHandle: PCtxtHandle; +begin + CheckHasHandle; + Result := @fHandle; +end; + +{ TCustomSSPIConnectionContext } + +procedure TCustomSSPIConnectionContext.DoRelease; +begin + inherited DoRelease; + fStatus := SEC_E_INVALID_HANDLE; // just to put something other then SEC_E_OK +end; + +function TCustomSSPIConnectionContext.GetAuthenticated: Boolean; +begin + CheckHasHandle; + Result := fStatus = SEC_E_OK; +end; + +function TCustomSSPIConnectionContext.UpdateAndGenerateReply + (const aFromPeerToken: TIdBytes; var aToPeerToken: TIdBytes): Boolean; +var + fOutBuff: SecBuffer; +begin + // keep the compiler happy (when was this fixed exactly?) + {$IFDEF DCC}{$IFNDEF VCL_8_OR_ABOVE} + Result := False; + {$ENDIF}{$ENDIF} + + { check credentials } + CheckCredentials; + { prepare input buffer } + + fInBuff.cbBuffer := Length(aFromPeerToken); + + //Assert(Length(aFromPeerToken)>0); + if fInBuff.cbBuffer > 0 then begin + fInBuff.pvBuffer := @aFromPeerToken[0]; + end; + + { prepare output buffer } + fOutBuff.BufferType := SECBUFFER_TOKEN; + fOutBuff.cbBuffer := Credentials.Package.MaxToken; + fOutBuff.pvBuffer := AllocMem(fOutBuff.cbBuffer); + + fOutBuffDesc.ulVersion := SECBUFFER_VERSION; + fOutBuffDesc.cBuffers := 1; + fOutBuffDesc.pBuffers := @fOutBuff; + + try + { do processing } + fStatus := DoUpdateAndGenerateReply(fInBuffDesc, fOutBuffDesc, []); + { complete token if applicable } + case fStatus of + SEC_I_COMPLETE_NEEDED, + SEC_I_COMPLETE_AND_CONTINUE: + begin + if not Assigned(gSSPIInterface.FunctionTable.CompleteAuthToken) then begin + raise ESSPIException.Create(RSHTTPSSPICompleteTokenNotSupported); + end; + fStatus := gSSPIInterface.FunctionTable.CompleteAuthToken(Handle, @fOutBuffDesc); + gSSPIInterface.RaiseIfError(fStatus, 'CompleteAuthToken'); {Do not translate} + end; + end; + Result := + (fStatus = SEC_I_CONTINUE_NEEDED) or + (fStatus = SEC_I_COMPLETE_AND_CONTINUE) or + (fOutBuff.cbBuffer > 0); + if Result then begin + aToPeerToken := RawToBytes(fOutBuff.pvBuffer^, fOutBuff.cbBuffer); + end; + finally + FreeMem(fOutBuff.pvBuffer); + end; +end; + +constructor TCustomSSPIConnectionContext.Create(aCredentials: TSSPICredentials); +begin + inherited Create(aCredentials); + + fInBuff.BufferType := SECBUFFER_TOKEN; + + fInBuffDesc.ulVersion := SECBUFFER_VERSION; + fInBuffDesc.cBuffers := 1; + fInBuffDesc.pBuffers := @fInBuff; + + fOutBuffDesc.ulVersion := SECBUFFER_VERSION; + fOutBuffDesc.cBuffers := 1; +end; + +{ TSSPIClientConnectionContext } + +constructor TSSPIClientConnectionContext.Create(aCredentials: TSSPICredentials); +begin + inherited Create(aCredentials); + fTargetName := ''; {Do not translate} +end; + +function TSSPIClientConnectionContext.GetRequestedFlags: ULONG; +begin + Result := fReqReguested; +end; + +procedure TSSPIClientConnectionContext.SetEstablishedFlags(aFlags: ULONG); +begin + fReqEstablished := aFlags; +end; + +function TSSPIClientConnectionContext.DoUpdateAndGenerateReply + (var aIn, aOut: SecBufferDesc; + const aErrorsToIgnore: array of SECURITY_STATUS): SECURITY_STATUS; +begin + Result := DoInitialize(fTargetName, aIn, aOut, []); +end; + +function TSSPIClientConnectionContext.GenerateInitialChallenge + (const aTargetName: string; var aToPeerToken: TIdBytes): Boolean; +begin + Release; + fTargetName := aTargetName; + Result := UpdateAndGenerateReply(nil, aToPeerToken); {Do not translate} +end; + +{ TIndySSPINTLMClient } + +constructor TIndySSPINTLMClient.Create; +begin + inherited Create; + fNTLMPackage := TSSPINTLMPackage.Create; + fCredentials := TSSPIWinNTCredentials.Create(fNTLMPackage); + fContext := TSSPIClientConnectionContext.Create(fCredentials); +end; + +destructor TIndySSPINTLMClient.Destroy; +begin + FreeAndNil(fContext); + FreeAndNil(fCredentials); + FreeAndNil(fNTLMPackage); + inherited Destroy; +end; + +procedure TIndySSPINTLMClient.SetCredentials(const aDomain, aUserName, aPassword: string); +begin + fCredentials.Acquire(scuOutBound, aDomain, aUserName, aPassword); +end; + +procedure TIndySSPINTLMClient.SetCredentialsAsCurrentUser; +begin + fCredentials.Acquire(scuOutBound); +end; + +function TIndySSPINTLMClient.InitAndBuildType1Message: TIdBytes; +begin + fContext.GenerateInitialChallenge('', Result); +end; + +function TIndySSPINTLMClient.UpdateAndBuildType3Message(const aServerType2Message: TIdBytes): TIdBytes; +begin + fContext.UpdateAndGenerateReply(aServerType2Message, Result); +end; + +{ TIdSSPINTLMAuthentication } + +constructor TIdSSPINTLMAuthentication.Create; +begin + inherited Create; + FSSPIClient := TIndySSPINTLMClient.Create; + Domain := IndyComputerName; +end; + +function TIdSSPINTLMAuthentication.DoNext: TIdAuthWhatsNext; +begin + Result := wnDoRequest; + case FCurrentStep of + //Authentication() does the 2>3 progression + 0, 1, 3: + begin + Inc(FCurrentStep); + Result := wnDoRequest; + end; + 4: + begin + FCurrentStep := 0; + if Username = '' then begin + Result := wnAskTheProgram; + end else begin + Result := wnFail; + Username := ''; + Password := ''; + Domain := IndyComputerName; + end; + end; + end; +end; + +function TIdSSPINTLMAuthentication.Authentication: string; +var + buf: TIdBytes; +begin + Result := ''; + buf := nil; + case FCurrentStep of + 1: + begin + if Length(Username) = 0 then begin + FSSPIClient.SetCredentialsAsCurrentUser; + end else begin + FSSPIClient.SetCredentials(Domain, Username, Password); + end; + Result := 'NTLM ' + TIdEncoderMIME.EncodeBytes(FSSPIClient.InitAndBuildType1Message); {Do not translate} + FNTLMInfo := ''; {Do not translate} + end; + 2: + begin + if Length(FNTLMInfo) = 0 then begin + FNTLMInfo := ReadAuthInfo('NTLM'); {Do not translate} + Fetch(FNTLMInfo); + end; + + if Length(FNTLMInfo) = 0 then begin + Reset; + Abort; + end; + + buf := TIdDecoderMIME.DecodeBytes(FNTLMInfo); + Result := 'NTLM ' + TIdEncoderMIME.EncodeBytes(FSSPIClient.UpdateAndBuildType3Message(buf)); {Do not translate} + + FCurrentStep := 3; + end; + 3: begin + FCurrentStep := 4; + end; + end; +end; + +function TIdSSPINTLMAuthentication.KeepAlive: Boolean; +begin + Result := FCurrentStep >= 1; +end; + +function TIdSSPINTLMAuthentication.GetSteps: Integer; +begin + Result := 3; +end; + +procedure TIdSSPINTLMAuthentication.SetDomain(const Value: String); +begin + Params.Values['Domain'] := Value; {do not localize} +end; + +function TIdSSPINTLMAuthentication.GetDomain: String; +begin + Result := Params.Values['Domain']; {do not localize} +end; + +procedure TIdSSPINTLMAuthentication.SetUserName(const Value: String); +var + S: String; + Idx: Integer; +begin + S := Value; + Idx := IndyPos('\', S); + if Idx > 0 then begin + Domain := Copy(S, 1, Idx - 1); + Delete(S, 1, Idx); + end; + inherited SetUserName(S); +end; + +destructor TIdSSPINTLMAuthentication.Destroy; +begin + FreeAndNil(FSSPIClient); + inherited; +end; + +initialization + gSSPIInterface := TSSPIInterface.Create; + if gSSPIInterface.IsAvailable then begin + RegisterAuthenticationMethod('NTLM', TIdSSPINTLMAuthentication); {do not localize} + RegisterAuthenticationMethod('Negotiate', TIdSSPINTLMAuthentication); {do not localize} + gAuthRegistered := True; + end; +finalization + if gAuthRegistered then begin + UnregisterAuthenticationMethod('NTLM'); {do not localize} + UnregisterAuthenticationMethod('Negotiate'); {do not localize} + end; + FreeAndNil(gSSPIInterface); +{$ENDIF} +end. + diff --git a/Lib/Protocols/IdCompilerDefines.inc b/Lib/Protocols/IdCompilerDefines.inc index 157bc07ec..ccfd332fe 100644 --- a/Lib/Protocols/IdCompilerDefines.inc +++ b/Lib/Protocols/IdCompilerDefines.inc @@ -1,2094 +1,2094 @@ -{$IFDEF CONDITIONALEXPRESSIONS} - // Must be at the top... - {$IF CompilerVersion >= 24.0} - {$LEGACYIFEND ON} - {$IFEND} -{$ENDIF} - -// General - -// Make this $DEFINE to use the 16 color icons required by Borland -// or DEFINE to use the 256 color Indy versions -{.$DEFINE Borland} - -// S.G. 4/9/2002: IPv4/IPv6 general switch (for defaults only) -{$DEFINE IdIPv4} // use IPv4 by default -{.$IFDEF IdIPv6} // use IPv6 by default - -{$DEFINE INDY100} -{$DEFINE 10_7_0} //so developers can IFDEF for this product version -{$DEFINE 10_7_0_0} //so developers can IFDEF for this specific version - -// When generating C++Builder output files, certain workarounds to compiler -// problems need to be enabled! When invoking DCC on the command-line, use -// the -DBCB parameter. When invoking MSBUILD, include the DCC_Define="BCB" -// attribute in the /p parameter. -{$IFDEF BCB} - {$DEFINE CBUILDER} -{$ELSE} - {$DEFINE DELPHI} -{$ENDIF} - -{$UNDEF USE_OPENSSL} -{$UNDEF STATICLOAD_OPENSSL} - -{$UNDEF USE_ZLIB_UNIT} -{$UNDEF USE_SSPI} - -// $DEFINE the following if the global objects in the IdStack and IdThread -// units should be freed on finalization -{$IFDEF FPC} -{$DEFINE FREE_ON_FINAL} -{$ELSE} -{$UNDEF FREE_ON_FINAL} -{$ENDIF} - -// Make sure the following is $DEFINE'd only for suitable environments -// as specified further below. This works in conjunction with the -// FREE_ON_FINAL define above. -{$UNDEF REGISTER_EXPECTED_MEMORY_LEAK} -{$UNDEF HAS_System_RegisterExpectedMemoryLeak} - -// FastMM is natively available in BDS 2006 and higher. $DEFINE the -// following if FastMM has been installed manually in earlier versions -{.$DEFINE USE_FASTMM4} -{$UNDEF USE_FASTMM4} - -// $DEFINE the following if MadExcept has been installed manually in -// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced -// in BDS 2006) -{.$DEFINE USE_MADEXCEPT} -{$UNDEF USE_MADEXCEPT} - -// $DEFINE the following if LeakCheck has been installed manually in -// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced -// in BDS 2006) -{.$DEFINE USE_LEAKCHECK} -{$UNDEF USE_LEAKCHECK} - -// Make sure the following are $DEFINE'd only for Delphi/C++Builder 2009 onwards -// as specified further below. The VCL is fully Unicode, where the 'String' -// type maps to System.UnicodeString, not System.AnsiString anymore -{$UNDEF STRING_IS_UNICODE} -{$UNDEF STRING_IS_ANSI} -{$UNDEF STRING_UNICODE_MISMATCH} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. Delphi/C++Builder Mobile/NextGen compilers -// do not support Ansi data types anymore, and is moving away from raw -// pointers as well. -// -// UPDATE: in Delphi/C++Builder 10.4, all Ansi types are supported again on -// all platforms, including the mobile compilers. -{$DEFINE HAS_AnsiString} -{$DEFINE HAS_AnsiChar} -{$DEFINE HAS_PAnsiChar} -{$UNDEF HAS_PPAnsiChar} -{$UNDEF NO_ANSI_TYPES} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. Delphi/C++Builder Mobile/NextGen compilers -// use ARC for TObject life time management. -// -// UPDATE: ARC for TObject lifetime management has been removed in -// Delphi/C++Builder 10.4 mobile compilers. All platforms now use a single -// unified memory management model! -{$UNDEF USE_MARSHALLED_PTRS} -{$UNDEF HAS_MarshaledAString} -{$UNDEF USE_OBJECT_ARC} - -// Make sure the following is $DEFINE'd only for suitable environments -// as specified further below. -{$UNDEF STRING_IS_IMMUTABLE} -{$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. -{$UNDEF HAS_TEncoding} -{$UNDEF HAS_TEncoding_GetEncoding_ByEncodingName} -{$UNDEF HAS_Exception_RaiseOuterException} -{$UNDEF HAS_System_ReturnAddress} -{$UNDEF HAS_TCharacter} -{$UNDEF HAS_TInterlocked} -{$UNDEF HAS_TNetEncoding} - -// Make sure that this is defined only for environments where we are using -// the iconv library to charactor conversions. -{.$UNDEF USE_ICONV} -{.$UNDEF USE_LCONVENC} - -//Define for Delphi cross-compiler targetting Posix -{$UNDEF USE_VCL_POSIX} -{$UNDEF HAS_ComponentPlatformsAttribute} -{$UNDEF HAS_ComponentPlatformsAttribute_Win32} -{$UNDEF HAS_ComponentPlatformsAttribute_Win64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSX32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator32} -{$UNDEF HAS_ComponentPlatformsAttribute_Android} -{$UNDEF HAS_ComponentPlatformsAttribute_Android32Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device32} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux64} -{$UNDEF HAS_ComponentPlatformsAttribute_WinNX32} -{$UNDEF HAS_ComponentPlatformsAttribute_WinIoT32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device64} -{$UNDEF HAS_ComponentPlatformsAttribute_WinARM} -{$UNDEF HAS_ComponentPlatformsAttribute_WinARM32} -{$UNDEF HAS_ComponentPlatformsAttribute_OSX64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux32Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux64Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Android64} -{$UNDEF HAS_ComponentPlatformsAttribute_Android64Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator64} -{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm32} -{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSXArm64} -{$UNDEF HAS_ComponentPlatformsAttribute_AllPlatforms} -{$UNDEF HAS_DIRECTIVE_WARN_DEFAULT} - -// Define for Delphi to auto-generate platform-appropriate '#pragma link' statements in HPP files -{$UNDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT} - -// detect compiler versions - -{$IFNDEF FPC} - - // TODO: to detect features in Delphi/C++Builder v6 and later, use CompilerVersion - // and RTLVersion constants instead of VERXXX defines. We still support v5, which - // does not have such constants. - - // Delphi 4 - {$IFDEF VER120} - {$DEFINE DCC} - {$DEFINE VCL_40} - {$DEFINE DELPHI_4} - {$ENDIF} - - // C++Builder 4 - {$IFDEF VER125} - {$DEFINE DCC} - {$DEFINE VCL_40} - {$DEFINE CBUILDER_4} - {$ENDIF} - - // Delphi & C++Builder 5 - {$IFDEF VER130} - {$DEFINE DCC} - {$DEFINE VCL_50} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_5} - {$ELSE} - {$DEFINE DELPHI_5} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 6 - {$IFDEF VER140} - {$DEFINE DCC} - {$DEFINE VCL_60} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_6} - {$ELSE} - {$DEFINE DELPHI_6} - {$ENDIF} - {$ENDIF} - - //Delphi 7 - {$IFDEF VER150} - {$DEFINE DCC} - {$DEFINE VCL_70} - {$DEFINE DELPHI_7} // there was no C++ Builder 7 - {$ENDIF} - - //Delphi 8 - {$IFDEF VER160} - {$DEFINE DCC} - {$DEFINE VCL_80} - {$DEFINE DELPHI_8} // there was no C++ Builder 8 - {$ENDIF} - - //Delphi 2005 - {$IFDEF VER170} - {$DEFINE DCC} - {$DEFINE VCL_2005} - {$DEFINE DELPHI_2005} // there was no C++Builder 2005 - {$ENDIF} - - // NOTE: CodeGear decided to make Highlander be a non-breaking release - // (no interface changes, thus fully backwards compatible without any - // end user code changes), so VER180 applies to both BDS 2006 and - // Highlander prior to the release of RAD Studio 2007. Use VER185 to - // identify Highlanger specifically. - - //Delphi & C++Builder 2006 - //Delphi & C++Builder 2007 (Highlander) - {$IFDEF VER180} - {$DEFINE DCC} - {$DEFINE VCL_2006} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2006} - {$ELSE} - {$DEFINE DELPHI_2006} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2007 (Highlander) - {$IFDEF VER185} - {$DEFINE DCC} - {$UNDEF VCL_2006} - {$DEFINE VCL_2007} - {$IFDEF CBUILDER} - {$UNDEF CBUILDER_2006} - {$DEFINE CBUILDER_2007} - {$ELSE} - {$UNDEF DELPHI_2006} - {$DEFINE DELPHI_2007} - {$ENDIF} - {$ENDIF} - - // BDS 2007 NET personality uses VER190 instead of 185. - //Delphi .NET 2007 - {$IFDEF VER190} - {$DEFINE DCC} - {$IFDEF CIL} - //Delphi 2007 - {$DEFINE VCL_2007} - {$DEFINE DELPHI_2007} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2009 (Tiburon) - {$IFDEF VER200} - {$DEFINE DCC} - {$DEFINE VCL_2009} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2009} - {$ELSE} - {$DEFINE DELPHI_2009} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2010 (Weaver) - {$IFDEF VER210} - {$DEFINE DCC} - {$DEFINE VCL_2010} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2010} - {$ELSE} - {$DEFINE DELPHI_2010} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder XE (Fulcrum) - {$IFDEF VER220} - //REMOVE DCC DEFINE after the next Fulcrum beta. - //It will be defined there. - {$IFNDEF DCC} - {$DEFINE DCC} - {$ENDIF} - {$DEFINE VCL_XE} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE} - {$ELSE} - {$DEFINE DELPHI_XE} - {$ENDIF} - {$ENDIF} - - // DCC is now defined by the Delphi compiler starting in XE2 - - //Delphi & CBuilder XE2 (Pulsar) - {$IFDEF VER230} - {$DEFINE VCL_XE2} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE2} - {$ELSE} - {$DEFINE DELPHI_XE2} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE3 (Waterdragon) - //Delphi & CBuilder XE3.5 (Quintessence - early betas only) - {$IFDEF VER240} - {$DEFINE VCL_XE3} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE3} - {$ELSE} - {$DEFINE DELPHI_XE3} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE4 (Quintessence) - {$IFDEF VER250} - {$UNDEF VCL_XE3} - {$DEFINE VCL_XE4} - {$IFDEF CBUILDER} - {$UNDEF CBUILDER_XE3} - {$DEFINE CBUILDER_XE4} - {$ELSE} - {$UNDEF DELPHI_XE3} - {$DEFINE DELPHI_XE4} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE5 (Zephyr) - {$IFDEF VER260} - {$DEFINE VCL_XE5} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE5} - {$ELSE} - {$DEFINE DELPHI_XE5} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder AppMethod - //AppMethod is just XE5 for mobile only, VCL is removed - {$IFDEF VER265} - {$DEFINE VCL_XE5} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE5} - {$ELSE} - {$DEFINE DELPHI_XE5} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE6 (Proteus) - {$IFDEF VER270} - {$DEFINE VCL_XE6} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE6} - {$ELSE} - {$DEFINE DELPHI_XE6} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE7 (Carpathia) - {$IFDEF VER280} - {$DEFINE VCL_XE7} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE7} - {$ELSE} - {$DEFINE DELPHI_XE7} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE8 (Elbrus) - {$IFDEF VER290} - {$DEFINE VCL_XE8} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE8} - {$ELSE} - {$DEFINE DELPHI_XE8} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.0 Seattle (Aitana) - {$IFDEF VER300} - {$DEFINE VCL_10_0} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_VCL_10_0} - {$ELSE} - {$DEFINE DELPHI_VCL_10_0} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.1 Berlin (BigBen) - {$IFDEF VER310} - {$DEFINE VCL_10_1} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_1} - {$ELSE} - {$DEFINE DELPHI_10_1} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.2 Tokyo (Godzilla) - {$IFDEF VER320} - {$DEFINE VCL_10_2} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_2} - {$ELSE} - {$DEFINE DELPHI_10_2} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.3 Rio (Carnival) - {$IFDEF VER330} - {$DEFINE VCL_10_3} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_3} - {$ELSE} - {$DEFINE DELPHI_10_3} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.4 Sydney (Denali) - {$IFDEF VER340} - {$DEFINE VCL_10_4} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_4} - {$ELSE} - {$DEFINE DELPHI_10_4} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 11.0 Alexandria (Olympus) - {$IFDEF VER350} - {$DEFINE VCL_11} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_11} - {$ELSE} - {$DEFINE DELPHI_11} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 12.0 Athens (Yukon) - {$IFDEF VER360} - {$DEFINE VCL_12} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_12} - {$ELSE} - {$DEFINE DELPHI_12} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 13.0+ (?) - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF CompilerVersion >= 37} - {$MESSAGE WARN 'Unknown compiler version detected! Assuming >= 13.x '} - {$DEFINE VCL_UNKNOWN_VERSION} - {$DEFINE VCL_13} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_13} - {$ELSE} - {$DEFINE DELPHI_13} - {$ENDIF} - {$IFEND} - {$ENDIF} - - // Kylix - // - //Important: Don't use CompilerVersion here as IF's are evaluated before - //IFDEF's and Kylix 1 does not have CompilerVersion defined at all. - {$IFDEF LINUX} - {$DEFINE UNIX} - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF (RTLVersion >= 14.0) and (RTLVersion <= 14.5) } - {$DEFINE KYLIX} - {$IF RTLVersion = 14.5} - {$DEFINE KYLIX_3} - {$ELSEIF RTLVersion >= 14.2} - {$DEFINE KYLIX_2} - {$ELSE} - {$DEFINE KYLIX_1} - {$IFEND} - {$IFEND} - {$ENDIF} - {$ENDIF} - -{$ENDIF} - -// Delphi.NET -// Covers D8+ -{$IFDEF CIL} - // Platform specific conditional. Used for platform specific code. - {$DEFINE DOTNET} - {$DEFINE STRING_IS_UNICODE} - {$DEFINE STRING_IS_IMMUTABLE} - {.$DEFINE HAS_Int8} - {.$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_UInt64} -{$ENDIF} - -{$IFDEF KYLIX} - {$DEFINE VCL_60} - {$DEFINE INT_THREAD_PRIORITY} - {$DEFINE CPUI386} - {$UNDEF USE_BASEUNIX} - - {$IFDEF KYLIX_3} - {$DEFINE KYLIX_3_OR_ABOVE} - {$ENDIF} - - {$IFDEF KYLIX_3_OR_ABOVE} - {$DEFINE KYLIX_2_OR_ABOVE} - {$ELSE} - {$IFDEF KYLIX_2} - {$DEFINE KYLIX_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF KYLIX_2_OR_ABOVE} - {$DEFINE KYLIX_1_OR_ABOVE} - {$ELSE} - {$IFDEF KYLIX_1} - {$DEFINE KYLIX_1_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFNDEF KYLIX_3_OR_ABOVE} - {$DEFINE KYLIXCOMPAT} - {$ENDIF} - - {$IFDEF KYLIX_2_OR_ABOVE} - {$DEFINE USE_ZLIB_UNIT} - {$ENDIF} -{$ENDIF} - -// FPC (2+) - -{$IFDEF FPC} - // TODO: In FreePascal 4.2.0+, a Delphi-like UnicodeString type is supported. - // However, String/(P)Char do not map to UnicodeString/(P)WideChar unless - // either {$MODE DelphiUnicode} or {$MODESWITCH UnicodeStrings} is used. - // We should consider enabling one of them so Indy uses the same Unicode logic - // in Delphi 2009+ and FreePascal 4.2.0+ and reduces IFDEFs (in particular, - // STRING_UNICODE_MISMATCH, see further below). However, FreePascal's RTL - // is largely not UnicodeString-enabled yet. Maybe we should enable - // {$MODE DelphiUnicode} anyway, and then deal with any RTL function issues - // on an as-needed basis... - {$MODE Delphi} - //note that we may need further defines for widget types depending on - //what we do and what platforms we support in FPC. - //I'll let Marco think about that one. - {$IFDEF UNIX} - {$DEFINE USE_BASEUNIX} - {$IFDEF LINUX} - //In Linux for I386, you can choose between a Kylix-libc API or - //the standard RTL Unix API. Just pass -dKYLIXCOMPAT to the FPC compiler. - //I will see what I can do about the Makefile. - {$IFDEF KYLIXCOMPAT} - {$IFDEF CPUI386} - {$UNDEF USE_BASEUNIX} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$IFDEF USE_BASEUNIX} - {$UNDEF KYLIXCOMPAT} - {$ENDIF} - {$ENDIF} - - // FPC_FULLVERSION was added in FPC 2.2.4 - // Have to use Defined() or else Delphi compiler chokes, since it - // evaluates $IF statements before $IFDEF statements... - - {$MACRO ON} // must be on in order to use versioning macros - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30101)} - {$DEFINE FPC_3_1_1_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30000)} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20701)} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20604)} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20602)} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20600)} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20404)} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20402)} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20400)} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20204)} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20202)} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20105)} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$IFEND} - - // just in case - {$IFDEF FPC_3_1_1} - {$DEFINE FPC_3_1_1_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_3_0_0} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_7_1} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_4} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_2} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_0} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_4} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_2} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_0} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_2_4} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_2_2} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_1_5} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ENDIF} - - {$IFDEF FPC_3_1_1_OR_ABOVE} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_3_0_0} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_3_0_0_OR_ABOVE} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_7_1} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_7_1_OR_ABOVE} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_4} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_4_OR_ABOVE} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_2} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_0} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_0_OR_ABOVE} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_4} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_4_OR_ABOVE} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_2} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_2_OR_ABOVE} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_0} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_0_OR_ABOVE} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_2_4} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_4_OR_ABOVE} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_2_2} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_2_OR_ABOVE} - {$DEFINE FPC_2_2_0_OR_ABOVE} - {$ELSE} - {$IFDEF VER2_2} - {$DEFINE FPC_2_2_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_0_OR_ABOVE} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_1_5} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {.$IFDEF FPC_2_7_1_OR_ABOVE} - // support for RawByteString and UnicodeString - {.$MODE DelphiUnicode} - {.$MODESWITCH UnicodeStrings} - {.$CODEPAGE UTF8} // needed for Unicode string literals to work properly - {.$DEFINE VCL_2009} - {.$DEFINE DELPHI_2009} - {.$ELSE} - {$DEFINE VCL_70} - {$DEFINE DELPHI_7} - {.$ENDIF} -{$ENDIF} - -// end FPC - -{$IFDEF VCL_13} - {$DEFINE VCL_13_OR_ABOVE} -{$ENDIF} - -{$IFDEF VCL_13_OR_ABOVE} - {$DEFINE VCL_12_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_12} - {$DEFINE VCL_12_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_12_OR_ABOVE} - {$DEFINE VCL_11_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_11} - {$DEFINE VCL_11_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_11_OR_ABOVE} - {$DEFINE VCL_10_4_OR_ABOVE} - {$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_4} - {$DEFINE VCL_10_4_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_4_OR_ABOVE} - {$DEFINE VCL_10_3_OR_ABOVE} - {$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_3} - {$DEFINE VCL_10_3_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_OR_ABOVE} - {$DEFINE VCL_10_2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_2} - {$DEFINE VCL_10_2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_2_OR_ABOVE} - {$DEFINE VCL_10_1_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_1} - {$DEFINE VCL_10_1_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_1_OR_ABOVE} - {$DEFINE VCL_10_0_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_0} - {$DEFINE VCL_10_0_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_0_OR_ABOVE} - {$DEFINE VCL_XE8_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE8} - {$DEFINE VCL_XE8_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE VCL_XE7_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE7} - {$DEFINE VCL_XE7_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE7_OR_ABOVE} - {$DEFINE VCL_XE6_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE6} - {$DEFINE VCL_XE6_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE6_OR_ABOVE} - {$DEFINE VCL_XE5_OR_ABOVE} - {$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE5} - {$DEFINE VCL_XE5_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE5_OR_ABOVE} - {$DEFINE VCL_XE4_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE4} - {$DEFINE VCL_XE4_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE4_OR_ABOVE} - {$DEFINE VCL_XE3_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE3} - {$DEFINE VCL_XE3_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE3_OR_ABOVE} - {$DEFINE VCL_XE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE2} - {$DEFINE VCL_XE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE2_OR_ABOVE} - {$DEFINE VCL_XE_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE} - {$DEFINE VCL_XE_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE_OR_ABOVE} - {$DEFINE VCL_2010_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2010} - {$DEFINE VCL_2010_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2010_OR_ABOVE} - {$DEFINE VCL_2009_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2009} - {$DEFINE VCL_2009_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2009_OR_ABOVE} - {$DEFINE VCL_2007_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2007} - {$DEFINE VCL_2007_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2007_OR_ABOVE} - {$DEFINE VCL_2006_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2006} - {$DEFINE VCL_2006_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2006_OR_ABOVE} - {$DEFINE VCL_2005_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2005} - {$DEFINE VCL_2005_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2005_OR_ABOVE} - {$DEFINE VCL_8_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_80} - {$DEFINE VCL_8_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_8_OR_ABOVE} - {$DEFINE VCL_7_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_70} - {$DEFINE VCL_7_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_7_OR_ABOVE} - {$DEFINE VCL_6_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_60} - {$DEFINE VCL_6_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_6_OR_ABOVE} - {$DEFINE VCL_5_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_50} - {$DEFINE VCL_5_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_5_OR_ABOVE} - {$DEFINE VCL_4_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_40} - {$DEFINE VCL_4_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -// Normalize Delphi compiler defines to match FPC for consistency: -// -// CPU32 - any 32-bit CPU -// CPU64 - any 64-bit CPU -// WINDOWS - any Windows platform (32-bit, 64-bit, CE) -// WIN32 - Windows 32-bit -// WIN64 - Windows 64-bit -// WINCE - Windows CE -// -// Consult the "Free Pascal Programmer's Guide", Appendix G for the complete -// list of defines that are used. Do not work on this unless you understand -// what the FreePascal developers are doing. Not only do you have to -// descriminate with operating systems, but also with chip architectures -// are well. -// -// DCC Pulsar+ define the following values: -// ASSEMBLER -// DCC -// CONDITIONALEXPRESSIONS -// NATIVECODE -// UNICODE -// MACOS -// MACOS32 -// MACOS64 -// MSWINDOWS -// WIN32 -// WIN64 -// LINUX -// POSIX -// POSIX32 -// CPU386 -// CPUX86 -// CPUX64 -// -// Kylix defines the following values: -// LINUX -// (others??) -// - -{$IFNDEF FPC} - // TODO: We need to use ENDIAN_BIG for big endian chip architectures, - // such as 680x0, PowerPC, Sparc, and MIPS, once DCC supports them, - // provided it does not already define its own ENDIAN values by then... - {$DEFINE ENDIAN_LITTLE} - {$IFNDEF VCL_6_OR_ABOVE} - {$DEFINE MSWINDOWS} - {$ENDIF} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} - // TODO: map Pulsar's non-Windows platform defines... - {$IFDEF VCL_XE2_OR_ABOVE} - {$IFDEF VCL_XE8_OR_ABOVE} - {$IFDEF CPU32BITS} - //any 32-bit CPU - {$DEFINE CPU32} - {$ENDIF} - {$IFDEF CPU64BITS} - {$DEFINE CPU64} - {$ENDIF} - {$ELSE} - {$IFDEF CPU386} - //any 32-bit CPU - {$DEFINE CPU32} - //Intel 386 compatible chip architecture - {$DEFINE CPUI386} - {$ENDIF} - {$IFDEF CPUX86} - {$DEFINE CPU32} - {$ENDIF} - {$IFDEF CPUX64} - //any 64-bit CPU - {$DEFINE CPU64} - //AMD64 compatible chip architecture - {$DEFINE CPUX86_64} //historical name for AMD64 - {$DEFINE CPUAMD64} - {$ENDIF} - {$ENDIF} - {$ELSE} - {$IFNDEF DOTNET} - {$IFNDEF KYLIX} - {$DEFINE I386} - {$ENDIF} - {$ENDIF} - {$DEFINE CPU32} - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - //differences in DotNET Framework versions. - {$IFDEF VCL_2007_OR_ABOVE} - {$DEFINE DOTNET_2} - {$DEFINE DOTNET_2_OR_ABOVE} - {$ELSE} - {$DEFINE DOTNET_1_1} - {$ENDIF} - {$DEFINE DOTNET_1_1_OR_ABOVE} - // Extra include used in D7 for testing. Remove later when all comps are - // ported. Used to selectively exclude non ported parts. Allowed in places - // IFDEFs are otherwise not permitted. - {$DEFINE DOTNET_EXCLUDE} -{$ENDIF} - -// Check for available features - -{$IFDEF CBUILDER} - // When generating a C++ HPP file, if a class has no explicit constructor - // defined and contains compiler-managed members (xxxString, TDateTime, - // Variant, DelphiInterface, etc), the HPP will contain a forwarding - // inline constructor that implicitly initializes those managed members, - // which will overwrite any non-default initializations performed inside - // of InitComponent() overrides! In this situation, the workaround is to - // define an explicit constructor that calls the base class constructor - // manually, allowing those managed members to be initialized by the - // compiler before InitComponent() overrides then re-assign them. - {$DEFINE WORKAROUND_INLINE_CONSTRUCTORS} -{$ENDIF} - -{$IFDEF VCL_5_OR_ABOVE} - {$IFNDEF FPC} - {$IFNDEF KYLIX} - {$DEFINE HAS_RemoveFreeNotification} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_GetObjectProp} - {$DEFINE HAS_TObjectList} - {$DEFINE HAS_StrToInt64Def} -{$ENDIF} - -{$IFDEF VCL_6_OR_ABOVE} - {$DEFINE HAS_PCardinal} - {$DEFINE HAS_PByte} - {$DEFINE HAS_PWord} - {$DEFINE HAS_PPointer} - {$DEFINE HAS_TList_Assign} - {$DEFINE HAS_sLineBreak} - {$DEFINE HAS_RaiseLastOSError} - {$DEFINE HAS_SysUtils_IncludeExcludeTrailingPathDelimiter} - {$DEFINE HAS_SysUtils_DirectoryExists} - {$DEFINE HAS_UNIT_DateUtils} - {$DEFINE HAS_UNIT_StrUtils} - {$DEFINE HAS_UNIT_Types} - {$DEFINE HAS_TryStrToInt} - {$DEFINE HAS_TryStrToInt64} - {$DEFINE HAS_TryEncodeDate} - {$DEFINE HAS_TryEncodeTime} - {$DEFINE HAS_ENUM_ELEMENT_VALUES} - {$IFNDEF FPC} - {$DEFINE HAS_IInterface} - {$DEFINE HAS_TSelectionEditor} - {$DEFINE HAS_TStringList_CaseSensitive} - {$DEFINE HAS_AcquireExceptionObject} - {$IFNDEF KYLIX} - {$DEFINE HAS_DEPRECATED} - {$DEFINE HAS_SYMBOL_PLATFORM} - {$DEFINE HAS_UNIT_PLATFORM} - {$IFNDEF VCL_8_OR_ABOVE} - // Delphi 6 and 7 have an annoying bug that if a class method is declared as - // deprecated, the compiler will emit a "symbol is deprecated" warning - // on the method's implementation! So we will have to wrap implementations - // of deprecated methods with {$WARN SYMBOL_DEPRECATED OFF} directives - // to disable that warning. - {$DEFINE DEPRECATED_IMPL_BUG} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$IFNDEF DOTNET} - //Widget defines are omitted in .NET - {$DEFINE VCL_60_PLUS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_7_OR_ABOVE} - {$IFNDEF FPC} - {$DEFINE HAS_UInt64} // Note: it was just an alias for Int64 until D2006! - {$DEFINE HAS_NAMED_THREADS} - {$DEFINE HAS_TStrings_NameValueSeparator} - {$DEFINE HAS_TStrings_ValueFromIndex} - // Note: there is a ZLib unit available, but it doesn't have everything - // that is available in the System.ZLib unit in Delphi XE2+, so we are - // not going to use this ZLib unit yet... - {.$DEFINE HAS_UNIT_ZLib} - {$ENDIF} - {$DEFINE HAS_TFormatSettings} - {$DEFINE HAS_PosEx} - {$IFNDEF VCL_70} - // not implemented in D7 - {$DEFINE HAS_STATIC_TThread_Queue} - {$ENDIF} - {$IFNDEF CIL} - {$IFNDEF VCL_80} - // not implemented in D8 or .NET - {$DEFINE HAS_STATIC_TThread_Synchronize} - {$ENDIF} - {$ENDIF} -{$ELSE} - {$IFDEF CBUILDER_6} - {$DEFINE HAS_NAMED_THREADS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2005_OR_ABOVE} - {$IFDEF DCC} - // class helpers were first introduced in D2005, but were buggy and not - // officially supported until D2006... - {.$DEFINE HAS_CLASS_HELPER} - {$ENDIF} -{$ELSE} - {$IFDEF DCC} - // InterlockedCompareExchange() was declared in the Windows unit using Pointer - // parameters until Delphi 2005, when it was switched to Longint parameters - // instead to match the actual Win32 API declaration. - {$DEFINE HAS_InterlockedCompareExchange_Pointers} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2006_OR_ABOVE} - {$DEFINE USE_INLINE} - {$DEFINE HAS_2PARAM_FileAge} - {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? - {$DEFINE HAS_CLASS_HELPER} - {$IFDEF WINDOWS} - // System.RegisterExpectedMemoryLeak() is only available on Windows at this time - {$DEFINE HAS_System_RegisterExpectedMemoryLeak} - {$ENDIF} - // In C++Builder 2006 and 2007, UInt64 is emitted as signed __int64 in HPP - // files instead of as unsigned __int64. This causes conflicts in overloaded - // routines that have (U)Int64 parameters. This was fixed in C++Builder 2009... - {$IFDEF CBUILDER} - {$DEFINE BROKEN_UINT64_HPPEMIT} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2007_OR_ABOVE} - {$IFNDEF CBUILDER_2007} - // class properties are broken in C++Builder 2007, causing AVs at compile-time - {$DEFINE HAS_CLASSPROPERTIES} - {$ENDIF} - // Native(U)Int exist but are buggy, so do not use them yet - {.$DEFINE HAS_NativeInt} - {.$DEFINE HAS_NativeUInt} - {$DEFINE HAS_DWORD_PTR} - {$DEFINE HAS_ULONG_PTR} - {$DEFINE HAS_ULONGLONG} - {$DEFINE HAS_PGUID} - {$DEFINE HAS_PPAnsiChar} - {$DEFINE HAS_CurrentYear} - {$IFNDEF DOTNET} - {$DEFINE HAS_TIMEUNITS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2009_OR_ABOVE} - {$IFNDEF DOTNET} - {$DEFINE STRING_IS_UNICODE} - {$DEFINE HAS_UnicodeString} - {$DEFINE HAS_TEncoding} - {$DEFINE HAS_TCharacter} - {$DEFINE HAS_InterlockedCompareExchangePointer} - {$DEFINE HAS_WIDE_TCharArray} - {$DEFINE HAS_PUInt64} - {$IFDEF VCL_2009} - // TODO: need to differentiate between RTM and Update 1 - // FmtStr() is broken in RTM but was fixed in Update 1 - {$DEFINE BROKEN_FmtStr} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_CLASSVARS} - {$DEFINE HAS_DEPRECATED_MSG} - {$DEFINE HAS_TBytes} - // Native(U)Int are still buggy, so do not use them yet - {.$DEFINE HAS_NativeInt} - {.$DEFINE HAS_NativeUInt} - {$DEFINE HAS_Int8} - {$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_UIntToStr} - // UInt64 is now emitted as unsigned __int64 in HPP files - {$IFDEF CBUILDER} - {$UNDEF BROKEN_UINT64_HPPEMIT} - {$ENDIF} - {$IFDEF DCC} - {$IFDEF WINDOWS} - // Exception.RaiseOuterException() is only available on Windows at this time - {$DEFINE HAS_Exception_RaiseOuterException} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_SetCodePage} - {$DEFINE HAS_PRawByteString} - {$DEFINE HAS_TThreadProcedure} -{$ENDIF} - -{$IFDEF VCL_2010_OR_ABOVE} - {$DEFINE HAS_CLASSCONSTRUCTOR} - {$DEFINE HAS_CLASSDESTRUCTOR} - {$DEFINE HAS_DELAYLOAD} - {$DEFINE HAS_TThread_NameThreadForDebugging} - {$DEFINE DEPRECATED_TThread_SuspendResume} - // Native(U)Int are finally ok to use now - {$DEFINE HAS_NativeInt} - {$DEFINE HAS_NativeUInt} - {$DEFINE HAS_USHORT} - {$DEFINE HAS_IOUtils_TPath} -{$ENDIF} - -{$IFDEF VCL_XE_OR_ABOVE} - {$DEFINE HAS_TFormatSettings_Object} - {$DEFINE HAS_LocaleCharsFromUnicode} - {$DEFINE HAS_UnicodeFromLocaleChars} - {$DEFINE HAS_PLongBool} - {$DEFINE HAS_PVOID} - {$DEFINE HAS_ULONG64} - {$DEFINE HAS_TEncoding_GetEncoding_ByEncodingName} - {$DEFINE HAS_DateUtils_TTimeZone} - {$IFDEF DCC} - // Exception.RaiseOuterException() is now available on all platforms - {$DEFINE HAS_Exception_RaiseOuterException} - {$ENDIF} - {$IFNDEF DOTNET} - {$DEFINE HAS_TInterlocked} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE2_OR_ABOVE} - {$DEFINE HAS_SIZE_T} - {$DEFINE HAS_PSIZE_T} - {$DEFINE HAS_SSIZE_T} - {$DEFINE HAS_PSSIZE_T} - {$DEFINE HAS_LONG} - {$DEFINE HAS_ComponentPlatformsAttribute} - {$DEFINE HAS_ComponentPlatformsAttribute_Win32} - {$DEFINE HAS_ComponentPlatformsAttribute_Win64} - {$DEFINE HAS_ComponentPlatformsAttribute_OSX32} - {$DEFINE HAS_System_ReturnAddress} - {$DEFINE HAS_DIRECTIVE_WARN_DEFAULT} - {$DEFINE HAS_UNIT_System_ZLib} -{$ENDIF} - -{$IFDEF VCL_XE3_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_ZEROBASEDSTRINGS} - {$DEFINE HAS_SysUtils_TStringHelper} - {$IFDEF NEXTGEN} - {$DEFINE DCC_NEXTGEN} - {$DEFINE HAS_MarshaledAString} - {$DEFINE USE_MARSHALLED_PTRS} - {$IFDEF AUTOREFCOUNT} - {$DEFINE USE_OBJECT_ARC} - {$ENDIF} - {$ENDIF} - // technically, these are present in XE3, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} - {.$DEFINE HAS_ComponentPlatformsAttribute_Android} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32} - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} - {.$DEFINE HAS_ComponentPlatformsAttribute_WinNX32} -{$ENDIF} - -{$IFDEF VCL_XE4_OR_ABOVE} - {$DEFINE HAS_AnsiStrings_StrPLCopy} - {$DEFINE HAS_AnsiStrings_StrLen} - {$DEFINE HAS_Character_TCharHelper} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} -{$ENDIF} - -{$IFDEF VCL_XE5_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_Android} -{$ENDIF} - -{$IFDEF VCL_XE5_UPDATE2_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_LINKUNIT} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_NAMESPACE} -{$ENDIF} - -{$IFDEF VCL_XE7_OR_ABOVE} - {$DEFINE HAS_TNetEncoding} -{$ENDIF} - -{$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device32} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device64} - // technically, these are present in XE8, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64} - {.$DEFINE HAS_ComponentPlatformsAttribute_WinIoT32} -{$ENDIF} - -{$IFDEF VCL_10_0_OR_ABOVE} - {$IFDEF ANDROID} - {$DEFINE HAS_TAndroidHelper} - {$ENDIF} - // technically, these are present in 10.0 Seattle, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_WinARM} -{$ENDIF} - -{$IFDEF VCL_10_1_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_LEGACYHPP} - {$DEFINE HAS_TStrings_AddPair} - // technically, these are present in 10.1 Berlin, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_OSX64} - {.$DEFINE HAS_ComponentPlatformsAttribute_OSXNX64} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32Arm} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64Arm} - {.$DEFINE HAS_ComponentPlatformsAttribute_Android64} -{$ENDIF} - -{$IFDEF VCL_10_2_OR_ABOVE} - {.$WARN IMPLICIT_INTEGER_CAST_LOSS OFF} - {.$WARN IMPLICIT_CONVERSION_LOSS OFF} - {.$WARN COMBINING_SIGNED_UNSIGNED64 OFF} - {$DEFINE HAS_STATIC_TThread_ForceQueue} - // In Delphi 10.2 Tokyo, TThread.ForceQueue() is broken on Android, the - // passed in procedure is called immediately instead of being delayed! - {$IFDEF ANDROID} - {$DEFINE BROKEN_TThread_ForceQueue} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator32} - {$DEFINE HAS_ComponentPlatformsAttribute_Android32Arm} - {$DEFINE HAS_ComponentPlatformsAttribute_WinARM32} - {$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} // removed in 10.3 Rio - // technically, these are present in 10.3 Rio, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator64} - {$IFDEF DCC} - {$IFDEF LINUX} - // RLebeau 9/25/2019: there is a bug in the IDE when debugging Linux projects - // where the EThreadNameException exception raised by TThread.NameThreadForDebugging() - // is not handled correctly. - {$UNDEF HAS_NAMED_THREADS} - {$ENDIF} - {$ENDIF} - {$IFDEF ANDROID} - {$UNDEF BROKEN_TThread_ForceQueue} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_UPDATE2_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_AllPlatforms} - {$DEFINE HAS_ComponentPlatformsAttribute_OSX64} -{$ENDIF} - -{$IFDEF VCL_10_4_OR_ABOVE} - // 0-based string indexing via '[]' is turned off by default in Delphi 10.4. - // TStringHelper is always 0-indexed, flat RTL functions are always 1-indexed, - // and now '[]' is 1-indexed again on all platforms - {$ZEROBASEDSTRINGS OFF} - // is the default. - {.$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} -{$ENDIF} - -{$IFDEF VCL_11_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm32} - {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm64} - {$DEFINE HAS_ComponentPlatformsAttribute_OSXArm64} -{$ENDIF} - -// Delphi XE+ cross-compiling -{$IFNDEF FPC} - {$IFDEF POSIX} - {$IF RTLVersion >= 22.0} - {$DEFINE UNIX} - {$UNDEF USE_BASEUNIX} - {$DEFINE VCL_CROSS_COMPILE} - {$DEFINE USE_VCL_POSIX} - {$IFEND} - {$ENDIF} - {$IFDEF LINUX} - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF RTLVersion >= 22.0} - {$DEFINE VCL_CROSS_COMPILE} - {$DEFINE USE_VCL_POSIX} - {$IFEND} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_CROSS_COMPILE} - {$UNDEF KYLIXCOMPAT} -{$ELSE} - {$IFDEF KYLIXCOMPAT} - {$linklib c} - {$ENDIF} -{$ENDIF} - -{$IFDEF FPC} - {$DEFINE USE_INLINE} - {$DEFINE USE_CLASSINLINE} - {$DEFINE USE_TBitBtn} //use Bit Buttons instead of Buttons - {$DEFINE FPC_REINTRODUCE_BUG} - {$DEFINE FPC_CIRCULAR_BUG} - {$DEFINE NO_REDECLARE} - {$DEFINE BYTE_COMPARE_SETS} - {$DEFINE HAS_QWord} // TODO: when was QWord introduced? - {$DEFINE HAS_PQWord} // TODO: when was PQWord introduced? - {$IFDEF FPC_2_1_5_OR_ABOVE} - {$DEFINE HAS_UInt64} - {.$DEFINE HAS_PUInt64} // TODO: is this defined? - {$ENDIF} - {$IFDEF FPC_2_2_0_OR_ABOVE} - {$DEFINE HAS_InterlockedCompareExchange_Pointers} - {$ENDIF} - {$IFDEF FPC_2_2_2_OR_ABOVE} - {$DEFINE HAS_SharedSuffix} - {$ENDIF} - {$IFDEF FPC_2_2_4_OR_ABOVE} - // these types are only available on Unix systems (FreeBSD, Linux, etc) - {$IFDEF UNIX} - {$DEFINE HAS_UNIT_UnixType} - {$DEFINE HAS_SIZE_T} - {$DEFINE HAS_PSIZE_T} - {$DEFINE HAS_SSIZE_T} - {$DEFINE HAS_PSSIZE_T} - {$DEFINE HAS_TIME_T} - {$DEFINE HAS_PTIME_T} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_PtrInt} - {$DEFINE HAS_PtrUInt} - {$DEFINE HAS_PGUID} - {$DEFINE HAS_LPGUID} - {$DEFINE HAS_PPAnsiChar} - {$DEFINE HAS_ENUM_ELEMENT_VALUES} - {$DEFINE HAS_AcquireExceptionObject} // TODO: when was AcquireExceptionObject introduced? - {$IFDEF WINDOWS} - {$DEFINE HAS_ULONG_PTR} - {.$DEFINE HAS_ULONGLONG} // TODO: is this defined? - {$ENDIF} - {$DEFINE HAS_UNIT_ctypes} - {$DEFINE HAS_sLineBreak} - {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? - {$IFDEF FPC_HAS_UNICODESTRING} - {$DEFINE HAS_UnicodeString} - {$ELSE} - {$IFDEF FPC_2_4_0_OR_ABOVE} - {$DEFINE HAS_UnicodeString} - {$ENDIF} - {$ENDIF} - {$IFDEF FPC_2_4_4_OR_ABOVE} - {$DEFINE DEPRECATED_TThread_SuspendResume} - {$DEFINE HAS_DEPRECATED} // TODO: when was deprecated introduced? Possibly 1.9.x - {$DEFINE HAS_DEPRECATED_MSG} // TODO: when was message support added? Possibly 2.4.x - {$DEFINE HAS_STATIC_TThread_Synchronize} - {$IFNDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE USE_SEMICOLON_BEFORE_DEPRECATED} // TODO: which earlier versions require a semicolon? - {$ENDIF} - {$ENDIF} - {$IFDEF FPC_2_6_0_OR_ABOVE} - {$DEFINE HAS_NativeInt} - {$DEFINE HAS_NativeUInt} - {$DEFINE HAS_CLASS_HELPER} - {$ENDIF} - {$IFDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE HAS_Int8} - {$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_GetLocalTimeOffset} - {$DEFINE HAS_UniversalTimeToLocal} - {$DEFINE HAS_LocalTimeToUniversal} - {$ENDIF} - {$IFDEF FPC_2_6_4_OR_ABOVE} - {$DEFINE HAS_PInt8} - {$DEFINE HAS_PUInt8} - {$DEFINE HAS_PInt16} - {$DEFINE HAS_PUInt16} - {$DEFINE HAS_PInt32} - {$DEFINE HAS_PUInt32} - {$ENDIF} - {$IFDEF FPC_3_0_0_OR_ABOVE} - {$DEFINE HAS_STATIC_TThread_Queue} - {$DEFINE HAS_SetCodePage} - {$ENDIF} - {$IFDEF FPC_UNICODESTRINGS} - {$DEFINE STRING_IS_UNICODE} - {$ENDIF} - {$IFDEF FPC_3_1_1_OR_ABOVE} - {$DEFINE HAS_STATIC_TThread_ForceQueue} // requires rev 37359+ - {$DEFINE HAS_PRawByteString} - {$DEFINE HAS_UIntToStr} // requires rev 40529+ - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - {$DEFINE WIDGET_WINFORMS} -{$ELSE} - {$DEFINE WIDGET_VCL_LIKE} // LCL included. - {$DEFINE WIDGET_VCL_LIKE_OR_KYLIX} - {$IFDEF FPC} - {$DEFINE WIDGET_LCL} - {$ELSE} - {$IFDEF KYLIX} - {$DEFINE WIDGET_KYLIX} - {$ELSE} - {$DEFINE WIDGET_VCL} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -// .NET and Delphi 2009+ support UNICODE strings natively! -// -// FreePascal 2.4.0+ supports UnicodeString, but does not map its -// native String type to UnicodeString except when {$MODE DelphiUnicode} -// or {$MODESWITCH UnicodeStrings} is enabled. However, UNICODE is not -// defined in that mode yet until its RTL has been updated to support -// UnicodeString. STRING_UNICODE_MISMATCH is defined when the native -// String/Char types do not map to the same types that APIs are expecting -// based on whether UNICODE is defined or not. -// -// NOTE: Do not define UNICODE here. The compiler defines -// the symbol automatically. -{$IFDEF STRING_IS_UNICODE} - {$IFNDEF UNICODE} - {$DEFINE STRING_UNICODE_MISMATCH} - {$ENDIF} -{$ELSE} - {$DEFINE STRING_IS_ANSI} - {$IFDEF UNICODE} - {$DEFINE STRING_UNICODE_MISMATCH} - {$ENDIF} -{$ENDIF} - -{$IFDEF DCC_NEXTGEN} - {$DEFINE NO_ANSI_TYPES} - {.$DEFINE STRING_IS_IMMUTABLE} // Strings are NOT immutable in NEXTGEN yet - {$IFDEF USE_OBJECT_ARC} - // TODO: move these to an appropriate section. Not doing this yet because - // it is a major interface change to switch to Generics and we should - // maintain backwards compatibility with earlier compilers for the time - // being. Defining them only here for now because the non-Generic versions - // of these classes have become deprecated by ARC and so we need to start - // taking advantage of the Generics versions... - {$DEFINE HAS_UNIT_Generics_Collections} - {$DEFINE HAS_UNIT_Generics_Defaults} - {$DEFINE HAS_GENERICS_TDictionary} - {$DEFINE HAS_GENERICS_TList} - {$DEFINE HAS_GENERICS_TObjectList} - {$DEFINE HAS_GENERICS_TThreadList} - // TArray.Copy() was introduced in XE7 but was buggy. It was fixed in XE8: - // - // RSP-9763 TArray.Copy copies from destination to source for unmanaged types - // https://quality.embarcadero.com/browse/RSP-9763 - // - {$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE HAS_GENERICS_TArray_Copy} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -// TODO: Ansi data types were disabled on mobile platforms in XE3, but -// UTF8String and RawByteString were re-enabled in 10.1 Berlin! What else, -// if anything, was re-enabled to facilitate that? -// -// UPDATE: In 10.4 Sydney, AnsiChar and AnsiString were re-enabled on -// mobile platforms! NEXTGEN is no longer defined in the mobile compilers. -{$IFDEF NO_ANSI_TYPES} - {$UNDEF HAS_AnsiString} - {$UNDEF HAS_AnsiChar} - {$UNDEF HAS_PAnsiChar} - {$UNDEF HAS_PPAnsiChar} - {$UNDEF HAS_AnsiStrings_StrPLCopy} - {$UNDEF HAS_AnsiStrings_StrLen} -{$ENDIF} - -{$IFDEF WIN32} - {$DEFINE WIN32_OR_WIN64} -{$ENDIF} -{$IFDEF WIN64} - {$DEFINE WIN32_OR_WIN64} -{$ENDIF} - -{$IFDEF WIN32_OR_WIN64} - {$DEFINE USE_ZLIB_UNIT} - {$IFNDEF DCC_NEXTGEN} - {$DEFINE USE_OPENSSL} // !!! MOVED HERE BY EMBT - {$DEFINE USE_SSPI} - {$IFDEF STRING_IS_UNICODE} - {$DEFINE SSPI_UNICODE} - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF WINCE} - {$DEFINE USE_OPENSSL} - // RLebeau: not sure if the above Win32/64 defines also apply to WinCE, - // so keeping them separate for now... -{$ENDIF} - -// High-performance counters are not reliable on multi-core systems, and have -// been known to cause problems with TIdIOHandler.ReadLn() timeouts in Windows -// XP SP3, both 32-bit and 64-bit. Refer to these discussions for more info: -// -// http://www.virtualdub.org/blog/pivot/entry.php?id=106 -// http://blogs.msdn.com/oldnewthing/archive/2008/09/08/8931563.aspx -// -// Do not enable thus unless you know it will work correctly on your systems! -{$IFDEF WINDOWS} - {.$DEFINE USE_HI_PERF_COUNTER_FOR_TICKS} -{$ENDIF} - -{$IFDEF UNIX} - {$DEFINE USE_OPENSSL} - {$DEFINE USE_ZLIB_UNIT} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF MACOS} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF DARWIN} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF LINUX} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF IOS} - {$DEFINE HAS_getifaddrs} - {$DEFINE USE_OPENSSL} - - // Support for 64-bit ARM iOS Simulator was added in Delphi 11.2 - // TODO: how to detect iOS Simulator in FPC? Does it support 64-bit ARM? - {$IFDEF CPUARM} - {$IFNDEF IOSSIMULATOR} - // RLebeau: For iOS devices, OpenSSL cannot be used as an external library, - // it must be statically linked into the app. For the iOS simulator, this - // is not true. Users who want to use OpenSSL in iOS device apps will need - // to add the static OpenSSL library to the project and then include the - // IdSSLOpenSSLHeaders_static unit in their uses clause. It hooks up the - // statically linked functions for the IdSSLOpenSSLHeaders unit to use... - {$DEFINE STATICLOAD_OPENSSL} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{$IFDEF FREEBSD} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF ANDROID} - {$UNDEF HAS_getifaddrs} -{$ENDIF} - -{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} - {$DEFINE REQUIRES_PROPER_ALIGNMENT} -{$ENDIF} - -// -//iconv defines section. -{$DEFINE USE_ICONV_UNIT} -{$DEFINE USE_ICONV_ENC} -{$IFDEF UNIX} - {$DEFINE USE_ICONV} - {$IFDEF USE_BASEUNIX} - {$IFDEF FPC} - {$UNDEF USE_ICONV_UNIT} - {$ELSE} - {$UNDEF USE_ICONV_ENC} - {$ENDIF} - {$ENDIF} - {$IFDEF KYLIXCOMPAT} - //important!! Iconv functions are defined in the libc.pas Kylix compatible unit. - {$UNDEF USE_ICONV_ENC} - {$UNDEF USE_ICONV_UNIT} - {$ENDIF} -{$ENDIF} -{$IFDEF NETWARELIBC} - {$DEFINE USE_ICONV} - //important!!! iconv functions are defined in the libc.pas Novell Netware header. - //Do not define USE_ICONV_UNIT - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} -{$ENDIF} - -{$UNDEF USE_SAFELOADLIBRARY} -{$IFDEF WINDOWS} - {$UNDEF USE_ICONV_ENC} - {$DEFINE USE_SAFELOADLIBRARY} -{$ENDIF} -// Use here for all *nix systems that you do not want to use iconv library -{$IFDEF FPC} - {$IFDEF ANDROID} - {$UNDEF USE_ICONV} - {$DEFINE USE_LCONVENC} - {$ENDIF} -{$ENDIF} - -{$UNDEF USE_INVALIDATE_MOD_CACHE} -{$UNDEF USE_SAFELOADLIBRARY} -//This must come after the iconv defines because this compiler targets a Unix-like -//operating system. One key difference is that it does have a TEncoding class. -//If this comes before the ICONV defines, it creates problems. -//This also must go before the THandle size calculations. -{$IFDEF VCL_CROSS_COMPILE} - {$IFDEF POSIX} - {$IFNDEF LINUX} - {$DEFINE BSD} - {$ENDIF} - {$DEFINE USE_SAFELOADLIBRARY} - {$DEFINE USE_INVALIDATE_MOD_CACHE} - {$ENDIF} - //important!!! iconv functions are defined in the libc.pas Novell Netware header. - //Do not define USE_ICONVUNIT - {$UNDEF USE_ICONV} - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} - {$DEFINE INT_THREAD_PRIORITY} -{$ENDIF} - -{$IFNDEF USE_ICONV} - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} -{$ENDIF} - -//IMPORTANT!!!! -// -//Do not remove this!!! This is to work around a conflict. In DCC, MACOS -//will mean OS X. In FreePascal, the DEFINE MACOS means MacIntosh System OS Classic. -{$IFDEF DCC} - // DCC defines MACOS for both iOS and OS X platforms, need to differentiate - {$IFDEF MACOS} - {$IFNDEF IOS} - {$DEFINE OSX} - {$DEFINE DARWIN} - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF FPC} - // FPC defines DARWIN for both OSX and iOS, need to differentiate - {$IFDEF DARWIN} - {$IFNDEF IOS} - {$DEFINE OSX} - {$ENDIF} - {$ENDIF} - {$IFDEF MACOS} - {$DEFINE MACOS_CLASSIC} - {$ENDIF} -{$ENDIF} - -{ -BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit -word to an 8 bit byte and an 8 bit byte field named sa_len was added. -} -//Place this only after DARWIN has been defined for Delphi MACOS -{$IFDEF FREEBSD} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF DARWIN} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF MORPHOS} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} - -// Do NOT remove these IFDEF's. They are here because InterlockedExchange -// only handles 32bit values. Some Operating Systems may have 64bit -// THandles. This is not always tied to the platform architecture. - -{$IFDEF AMIGA} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF ATARI} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF BEOS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF BSD} - //I think BSD might handle FreeBSD, NetBSD, OpenBSD, and Darwin - {$IFDEF IOS} - {$IFDEF CPUARM64} - {$DEFINE CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$IFDEF CPUARM32} - {$DEFINE CPU32} - {$ENDIF} - {$DEFINE THANDLE_32} - {$ENDIF} - {$ENDIF} - {$IFDEF OSX} - {$IFDEF FPC} - {$DEFINE THANDLE_32} - {$ELSE} - {$DEFINE THANDLE_CPUBITS} // !!! ADDED OSX BY EMBT - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF EMBEDDED} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF EMX} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF GBA} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF GO32} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF LINUX} - {$IFDEF LINUX64} - {$DEFINE CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$IFDEF LINUX32} - {$DEFINE CPU32} - {$ENDIF} - {$DEFINE THANDLE_32} - {$ENDIF} -{$ENDIF} -{$IFDEF MACOS_CLASSIC} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF MORPHOS} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF NATIVENT} //Native NT for kernel level drivers - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF NDS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF NETWARE} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF NETWARELIBC} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF OS2} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF PALMOS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF SOLARIS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF SYMBIAN} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WII} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WATCOM} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WINDOWS} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} - -// end platform specific stuff for THandle size - -{$IFDEF THANDLE_CPUBITS} - {$IFDEF CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$DEFINE THANDLE_32} - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - {$DEFINE DOTNET_OR_ICONV} -{$ENDIF} -{$IFDEF USE_ICONV} - {$DEFINE DOTNET_OR_ICONV} -{$ENDIF} - -{$UNDEF STREAM_SIZE_64} -{$IFDEF FPC} - {$DEFINE STREAM_SIZE_64} -{$ELSE} - {$IFDEF VCL_6_OR_ABOVE} - {$DEFINE STREAM_SIZE_64} - {$ENDIF} -{$ENDIF} - -{$IFNDEF FREE_ON_FINAL} - {$IFNDEF DOTNET} - {$IFDEF HAS_System_RegisterExpectedMemoryLeak} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_FASTMM4} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_MADEXCEPT} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_LEAKCHECK} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{ -We must determine what the SocketType parameter is for the Socket function. -In DotNET, it's SocketType. In Kylix and the libc.pas Kylix-compatibility -library, it's a __socket_type. In BaseUnix, it's a C-type Integer. In Windows, -it's a LongInt. - -} -{$UNDEF SOCKETTYPE_IS_SOCKETTYPE} -{$UNDEF SOCKETTYPE_IS_CINT} -{$UNDEF SOCKETTYPE_IS___SOCKETTYPE} -{$UNDEF SOCKETTYPE_IS_LONGINT} -{$UNDEF SOCKETTYPE_IS_NUMERIC} -{$UNDEF SOCKET_LEN_IS_socklen_t} -{$IFDEF DOTNET} - {$DEFINE SOCKETTYPE_IS_SOCKETTYPE} -{$ENDIF} -{$IFDEF USE_BASEUNIX} - {$DEFINE SOCKETTYPE_IS_CINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF KYLIXCOMPAT} - {$DEFINE SOCKETTYPE_IS___SOCKETTYPE} -{$ENDIF} -{$IFDEF USE_VCL_POSIX} - {$DEFINE SOCKETTYPE_IS_NUMERIC} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKET_LEN_IS_socklen_t} -{$ENDIF} -{$IFDEF WINDOWS} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF OS2} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF NETWARE} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} - -{Take advantage of some TCP features specific to some stacks. -They work somewhat similarly but there's a key difference. -In Linux, TCP_CORK is turned on to send fixed packet sizes and -when turned-off (uncorked), any remaining data is sent. With -TCP_NOPUSH, this might not happen and remaining data is only sent -before disconnect. TCP_KEEPIDLE and TCP_KEEPINTVL so the IFDEF LINUX and IFDEF -SOLARIS instead of IFDEF UNIX is not an error, it's deliberate.} -{$UNDEF HAS_TCP_NOPUSH} -{$UNDEF HAS_TCP_CORK} -{$UNDEF HAS_TCP_KEEPIDLE} -{$UNDEF HAS_TCP_KEEPINTVL} -{$UNDEF HAS_SOCKET_NOSIGPIPE} -{$IFDEF BSD} - {$DEFINE HAS_TCP_NOPUSH} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE HAS_TCP_NOPUSH} -{$ENDIF} -{$IFDEF LINUX} - {$DEFINE HAS_TCP_CORK} - {$DEFINE HAS_TCP_KEEPIDLE} - {$DEFINE HAS_TCP_KEEPINTVL} -{$ENDIF} -{$IFDEF SOLARIS} - {$DEFINE HAS_TCP_CORK} -{$ENDIF} -{$IFDEF NETBSD} - {$DEFINE HAS_TCP_CORK} - {$DEFINE HAS_TCP_KEEPIDLE} - {$DEFINE HAS_TCP_KEEPINTVL} -{$ENDIF} -{$IFDEF USE_VCL_POSIX} - // TODO: which platforms actually have SO_NOSIGPIPE available? - {$DEFINE HAS_SOCKET_NOSIGPIPE} - {$IFDEF ANDROID} - {$UNDEF HAS_SOCKET_NOSIGPIPE} - {$ENDIF} - {$IFDEF LINUX} - {$UNDEF HAS_SOCKET_NOSIGPIPE} - {$ENDIF} -{$ENDIF} -{end Unix OS specific stuff} -{$IFDEF DEBUG} - {$UNDEF USE_INLINE} -{$ENDIF} - -// RLebeau 5/24/2015: In C++Builder 2006 and 2007, UInt64 is emitted as -// signed __int64 in HPP files instead of as unsigned __int64. This causes -// conflicts in overloaded routines that have (U)Int64 parameters. This -// was fixed in C++Builder 2009. For compilers that do not have a native -// UInt64 type, or for C++Builder 2006/2007, let's define a record type -// that can hold UInt64 values... -{$IFDEF HAS_UInt64} - {$IFDEF BROKEN_UINT64_HPPEMIT} - {$DEFINE TIdUInt64_HAS_QuadPart} - {$ENDIF} -{$ELSE} - {$IFNDEF HAS_QWord} - {$DEFINE TIdUInt64_HAS_QuadPart} - {$ENDIF} -{$ENDIF} - -// RLebeau 9/5/2013: it would take a lot of work to re-write Indy to support -// both 0-based and 1-based string indexing, so we'll just turn off 0-based -// indexing for now... -{$IFDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} - {$ZEROBASEDSTRINGS OFF} -{$ENDIF} +{$IFDEF CONDITIONALEXPRESSIONS} + // Must be at the top... + {$IF CompilerVersion >= 24.0} + {$LEGACYIFEND ON} + {$IFEND} +{$ENDIF} + +// General + +// Make this $DEFINE to use the 16 color icons required by Borland +// or DEFINE to use the 256 color Indy versions +{.$DEFINE Borland} + +// S.G. 4/9/2002: IPv4/IPv6 general switch (for defaults only) +{$DEFINE IdIPv4} // use IPv4 by default +{.$IFDEF IdIPv6} // use IPv6 by default + +{$DEFINE INDY100} +{$DEFINE 10_7_0} //so developers can IFDEF for this product version +{$DEFINE 10_7_0_0} //so developers can IFDEF for this specific version + +// When generating C++Builder output files, certain workarounds to compiler +// problems need to be enabled! When invoking DCC on the command-line, use +// the -DBCB parameter. When invoking MSBUILD, include the DCC_Define="BCB" +// attribute in the /p parameter. +{$IFDEF BCB} + {$DEFINE CBUILDER} +{$ELSE} + {$DEFINE DELPHI} +{$ENDIF} + +{$UNDEF USE_OPENSSL} +{$UNDEF STATICLOAD_OPENSSL} + +{$UNDEF USE_ZLIB_UNIT} +{$UNDEF USE_SSPI} + +// $DEFINE the following if the global objects in the IdStack and IdThread +// units should be freed on finalization +{$IFDEF FPC} +{$DEFINE FREE_ON_FINAL} +{$ELSE} +{$UNDEF FREE_ON_FINAL} +{$ENDIF} + +// Make sure the following is $DEFINE'd only for suitable environments +// as specified further below. This works in conjunction with the +// FREE_ON_FINAL define above. +{$UNDEF REGISTER_EXPECTED_MEMORY_LEAK} +{$UNDEF HAS_System_RegisterExpectedMemoryLeak} + +// FastMM is natively available in BDS 2006 and higher. $DEFINE the +// following if FastMM has been installed manually in earlier versions +{.$DEFINE USE_FASTMM4} +{$UNDEF USE_FASTMM4} + +// $DEFINE the following if MadExcept has been installed manually in +// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced +// in BDS 2006) +{.$DEFINE USE_MADEXCEPT} +{$UNDEF USE_MADEXCEPT} + +// $DEFINE the following if LeakCheck has been installed manually in +// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced +// in BDS 2006) +{.$DEFINE USE_LEAKCHECK} +{$UNDEF USE_LEAKCHECK} + +// Make sure the following are $DEFINE'd only for Delphi/C++Builder 2009 onwards +// as specified further below. The VCL is fully Unicode, where the 'String' +// type maps to System.UnicodeString, not System.AnsiString anymore +{$UNDEF STRING_IS_UNICODE} +{$UNDEF STRING_IS_ANSI} +{$UNDEF STRING_UNICODE_MISMATCH} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. Delphi/C++Builder Mobile/NextGen compilers +// do not support Ansi data types anymore, and is moving away from raw +// pointers as well. +// +// UPDATE: in Delphi/C++Builder 10.4, all Ansi types are supported again on +// all platforms, including the mobile compilers. +{$DEFINE HAS_AnsiString} +{$DEFINE HAS_AnsiChar} +{$DEFINE HAS_PAnsiChar} +{$UNDEF HAS_PPAnsiChar} +{$UNDEF NO_ANSI_TYPES} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. Delphi/C++Builder Mobile/NextGen compilers +// use ARC for TObject life time management. +// +// UPDATE: ARC for TObject lifetime management has been removed in +// Delphi/C++Builder 10.4 mobile compilers. All platforms now use a single +// unified memory management model! +{$UNDEF USE_MARSHALLED_PTRS} +{$UNDEF HAS_MarshaledAString} +{$UNDEF USE_OBJECT_ARC} + +// Make sure the following is $DEFINE'd only for suitable environments +// as specified further below. +{$UNDEF STRING_IS_IMMUTABLE} +{$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. +{$UNDEF HAS_TEncoding} +{$UNDEF HAS_TEncoding_GetEncoding_ByEncodingName} +{$UNDEF HAS_Exception_RaiseOuterException} +{$UNDEF HAS_System_ReturnAddress} +{$UNDEF HAS_TCharacter} +{$UNDEF HAS_TInterlocked} +{$UNDEF HAS_TNetEncoding} + +// Make sure that this is defined only for environments where we are using +// the iconv library to charactor conversions. +{.$UNDEF USE_ICONV} +{.$UNDEF USE_LCONVENC} + +//Define for Delphi cross-compiler targetting Posix +{$UNDEF USE_VCL_POSIX} +{$UNDEF HAS_ComponentPlatformsAttribute} +{$UNDEF HAS_ComponentPlatformsAttribute_Win32} +{$UNDEF HAS_ComponentPlatformsAttribute_Win64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSX32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator32} +{$UNDEF HAS_ComponentPlatformsAttribute_Android} +{$UNDEF HAS_ComponentPlatformsAttribute_Android32Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device32} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux64} +{$UNDEF HAS_ComponentPlatformsAttribute_WinNX32} +{$UNDEF HAS_ComponentPlatformsAttribute_WinIoT32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device64} +{$UNDEF HAS_ComponentPlatformsAttribute_WinARM} +{$UNDEF HAS_ComponentPlatformsAttribute_WinARM32} +{$UNDEF HAS_ComponentPlatformsAttribute_OSX64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux32Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux64Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Android64} +{$UNDEF HAS_ComponentPlatformsAttribute_Android64Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator64} +{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm32} +{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSXArm64} +{$UNDEF HAS_ComponentPlatformsAttribute_AllPlatforms} +{$UNDEF HAS_DIRECTIVE_WARN_DEFAULT} + +// Define for Delphi to auto-generate platform-appropriate '#pragma link' statements in HPP files +{$UNDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT} + +// detect compiler versions + +{$IFNDEF FPC} + + // TODO: to detect features in Delphi/C++Builder v6 and later, use CompilerVersion + // and RTLVersion constants instead of VERXXX defines. We still support v5, which + // does not have such constants. + + // Delphi 4 + {$IFDEF VER120} + {$DEFINE DCC} + {$DEFINE VCL_40} + {$DEFINE DELPHI_4} + {$ENDIF} + + // C++Builder 4 + {$IFDEF VER125} + {$DEFINE DCC} + {$DEFINE VCL_40} + {$DEFINE CBUILDER_4} + {$ENDIF} + + // Delphi & C++Builder 5 + {$IFDEF VER130} + {$DEFINE DCC} + {$DEFINE VCL_50} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_5} + {$ELSE} + {$DEFINE DELPHI_5} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 6 + {$IFDEF VER140} + {$DEFINE DCC} + {$DEFINE VCL_60} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_6} + {$ELSE} + {$DEFINE DELPHI_6} + {$ENDIF} + {$ENDIF} + + //Delphi 7 + {$IFDEF VER150} + {$DEFINE DCC} + {$DEFINE VCL_70} + {$DEFINE DELPHI_7} // there was no C++ Builder 7 + {$ENDIF} + + //Delphi 8 + {$IFDEF VER160} + {$DEFINE DCC} + {$DEFINE VCL_80} + {$DEFINE DELPHI_8} // there was no C++ Builder 8 + {$ENDIF} + + //Delphi 2005 + {$IFDEF VER170} + {$DEFINE DCC} + {$DEFINE VCL_2005} + {$DEFINE DELPHI_2005} // there was no C++Builder 2005 + {$ENDIF} + + // NOTE: CodeGear decided to make Highlander be a non-breaking release + // (no interface changes, thus fully backwards compatible without any + // end user code changes), so VER180 applies to both BDS 2006 and + // Highlander prior to the release of RAD Studio 2007. Use VER185 to + // identify Highlanger specifically. + + //Delphi & C++Builder 2006 + //Delphi & C++Builder 2007 (Highlander) + {$IFDEF VER180} + {$DEFINE DCC} + {$DEFINE VCL_2006} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2006} + {$ELSE} + {$DEFINE DELPHI_2006} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2007 (Highlander) + {$IFDEF VER185} + {$DEFINE DCC} + {$UNDEF VCL_2006} + {$DEFINE VCL_2007} + {$IFDEF CBUILDER} + {$UNDEF CBUILDER_2006} + {$DEFINE CBUILDER_2007} + {$ELSE} + {$UNDEF DELPHI_2006} + {$DEFINE DELPHI_2007} + {$ENDIF} + {$ENDIF} + + // BDS 2007 NET personality uses VER190 instead of 185. + //Delphi .NET 2007 + {$IFDEF VER190} + {$DEFINE DCC} + {$IFDEF CIL} + //Delphi 2007 + {$DEFINE VCL_2007} + {$DEFINE DELPHI_2007} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2009 (Tiburon) + {$IFDEF VER200} + {$DEFINE DCC} + {$DEFINE VCL_2009} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2009} + {$ELSE} + {$DEFINE DELPHI_2009} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2010 (Weaver) + {$IFDEF VER210} + {$DEFINE DCC} + {$DEFINE VCL_2010} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2010} + {$ELSE} + {$DEFINE DELPHI_2010} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder XE (Fulcrum) + {$IFDEF VER220} + //REMOVE DCC DEFINE after the next Fulcrum beta. + //It will be defined there. + {$IFNDEF DCC} + {$DEFINE DCC} + {$ENDIF} + {$DEFINE VCL_XE} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE} + {$ELSE} + {$DEFINE DELPHI_XE} + {$ENDIF} + {$ENDIF} + + // DCC is now defined by the Delphi compiler starting in XE2 + + //Delphi & CBuilder XE2 (Pulsar) + {$IFDEF VER230} + {$DEFINE VCL_XE2} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE2} + {$ELSE} + {$DEFINE DELPHI_XE2} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE3 (Waterdragon) + //Delphi & CBuilder XE3.5 (Quintessence - early betas only) + {$IFDEF VER240} + {$DEFINE VCL_XE3} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE3} + {$ELSE} + {$DEFINE DELPHI_XE3} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE4 (Quintessence) + {$IFDEF VER250} + {$UNDEF VCL_XE3} + {$DEFINE VCL_XE4} + {$IFDEF CBUILDER} + {$UNDEF CBUILDER_XE3} + {$DEFINE CBUILDER_XE4} + {$ELSE} + {$UNDEF DELPHI_XE3} + {$DEFINE DELPHI_XE4} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE5 (Zephyr) + {$IFDEF VER260} + {$DEFINE VCL_XE5} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE5} + {$ELSE} + {$DEFINE DELPHI_XE5} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder AppMethod + //AppMethod is just XE5 for mobile only, VCL is removed + {$IFDEF VER265} + {$DEFINE VCL_XE5} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE5} + {$ELSE} + {$DEFINE DELPHI_XE5} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE6 (Proteus) + {$IFDEF VER270} + {$DEFINE VCL_XE6} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE6} + {$ELSE} + {$DEFINE DELPHI_XE6} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE7 (Carpathia) + {$IFDEF VER280} + {$DEFINE VCL_XE7} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE7} + {$ELSE} + {$DEFINE DELPHI_XE7} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE8 (Elbrus) + {$IFDEF VER290} + {$DEFINE VCL_XE8} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE8} + {$ELSE} + {$DEFINE DELPHI_XE8} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.0 Seattle (Aitana) + {$IFDEF VER300} + {$DEFINE VCL_10_0} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_VCL_10_0} + {$ELSE} + {$DEFINE DELPHI_VCL_10_0} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.1 Berlin (BigBen) + {$IFDEF VER310} + {$DEFINE VCL_10_1} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_1} + {$ELSE} + {$DEFINE DELPHI_10_1} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.2 Tokyo (Godzilla) + {$IFDEF VER320} + {$DEFINE VCL_10_2} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_2} + {$ELSE} + {$DEFINE DELPHI_10_2} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.3 Rio (Carnival) + {$IFDEF VER330} + {$DEFINE VCL_10_3} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_3} + {$ELSE} + {$DEFINE DELPHI_10_3} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.4 Sydney (Denali) + {$IFDEF VER340} + {$DEFINE VCL_10_4} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_4} + {$ELSE} + {$DEFINE DELPHI_10_4} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 11.0 Alexandria (Olympus) + {$IFDEF VER350} + {$DEFINE VCL_11} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_11} + {$ELSE} + {$DEFINE DELPHI_11} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 12.0 Athens (Yukon) + {$IFDEF VER360} + {$DEFINE VCL_12} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_12} + {$ELSE} + {$DEFINE DELPHI_12} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 13.0+ (?) + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF CompilerVersion >= 37} + {$MESSAGE WARN 'Unknown compiler version detected! Assuming >= 13.x '} + {$DEFINE VCL_UNKNOWN_VERSION} + {$DEFINE VCL_13} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_13} + {$ELSE} + {$DEFINE DELPHI_13} + {$ENDIF} + {$IFEND} + {$ENDIF} + + // Kylix + // + //Important: Don't use CompilerVersion here as IF's are evaluated before + //IFDEF's and Kylix 1 does not have CompilerVersion defined at all. + {$IFDEF LINUX} + {$DEFINE UNIX} + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF (RTLVersion >= 14.0) and (RTLVersion <= 14.5) } + {$DEFINE KYLIX} + {$IF RTLVersion = 14.5} + {$DEFINE KYLIX_3} + {$ELSEIF RTLVersion >= 14.2} + {$DEFINE KYLIX_2} + {$ELSE} + {$DEFINE KYLIX_1} + {$IFEND} + {$IFEND} + {$ENDIF} + {$ENDIF} + +{$ENDIF} + +// Delphi.NET +// Covers D8+ +{$IFDEF CIL} + // Platform specific conditional. Used for platform specific code. + {$DEFINE DOTNET} + {$DEFINE STRING_IS_UNICODE} + {$DEFINE STRING_IS_IMMUTABLE} + {.$DEFINE HAS_Int8} + {.$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_UInt64} +{$ENDIF} + +{$IFDEF KYLIX} + {$DEFINE VCL_60} + {$DEFINE INT_THREAD_PRIORITY} + {$DEFINE CPUI386} + {$UNDEF USE_BASEUNIX} + + {$IFDEF KYLIX_3} + {$DEFINE KYLIX_3_OR_ABOVE} + {$ENDIF} + + {$IFDEF KYLIX_3_OR_ABOVE} + {$DEFINE KYLIX_2_OR_ABOVE} + {$ELSE} + {$IFDEF KYLIX_2} + {$DEFINE KYLIX_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF KYLIX_2_OR_ABOVE} + {$DEFINE KYLIX_1_OR_ABOVE} + {$ELSE} + {$IFDEF KYLIX_1} + {$DEFINE KYLIX_1_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFNDEF KYLIX_3_OR_ABOVE} + {$DEFINE KYLIXCOMPAT} + {$ENDIF} + + {$IFDEF KYLIX_2_OR_ABOVE} + {$DEFINE USE_ZLIB_UNIT} + {$ENDIF} +{$ENDIF} + +// FPC (2+) + +{$IFDEF FPC} + // TODO: In FreePascal 4.2.0+, a Delphi-like UnicodeString type is supported. + // However, String/(P)Char do not map to UnicodeString/(P)WideChar unless + // either {$MODE DelphiUnicode} or {$MODESWITCH UnicodeStrings} is used. + // We should consider enabling one of them so Indy uses the same Unicode logic + // in Delphi 2009+ and FreePascal 4.2.0+ and reduces IFDEFs (in particular, + // STRING_UNICODE_MISMATCH, see further below). However, FreePascal's RTL + // is largely not UnicodeString-enabled yet. Maybe we should enable + // {$MODE DelphiUnicode} anyway, and then deal with any RTL function issues + // on an as-needed basis... + {$MODE Delphi} + //note that we may need further defines for widget types depending on + //what we do and what platforms we support in FPC. + //I'll let Marco think about that one. + {$IFDEF UNIX} + {$DEFINE USE_BASEUNIX} + {$IFDEF LINUX} + //In Linux for I386, you can choose between a Kylix-libc API or + //the standard RTL Unix API. Just pass -dKYLIXCOMPAT to the FPC compiler. + //I will see what I can do about the Makefile. + {$IFDEF KYLIXCOMPAT} + {$IFDEF CPUI386} + {$UNDEF USE_BASEUNIX} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$IFDEF USE_BASEUNIX} + {$UNDEF KYLIXCOMPAT} + {$ENDIF} + {$ENDIF} + + // FPC_FULLVERSION was added in FPC 2.2.4 + // Have to use Defined() or else Delphi compiler chokes, since it + // evaluates $IF statements before $IFDEF statements... + + {$MACRO ON} // must be on in order to use versioning macros + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30101)} + {$DEFINE FPC_3_1_1_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30000)} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20701)} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20604)} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20602)} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20600)} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20404)} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20402)} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20400)} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20204)} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20202)} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20105)} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$IFEND} + + // just in case + {$IFDEF FPC_3_1_1} + {$DEFINE FPC_3_1_1_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_3_0_0} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_7_1} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_4} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_2} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_0} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_4} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_2} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_0} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_2_4} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_2_2} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_1_5} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ENDIF} + + {$IFDEF FPC_3_1_1_OR_ABOVE} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_3_0_0} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_3_0_0_OR_ABOVE} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_7_1} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_7_1_OR_ABOVE} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_4} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_4_OR_ABOVE} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_2} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_0} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_0_OR_ABOVE} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_4} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_4_OR_ABOVE} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_2} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_2_OR_ABOVE} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_0} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_0_OR_ABOVE} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_2_4} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_4_OR_ABOVE} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_2_2} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_2_OR_ABOVE} + {$DEFINE FPC_2_2_0_OR_ABOVE} + {$ELSE} + {$IFDEF VER2_2} + {$DEFINE FPC_2_2_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_0_OR_ABOVE} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_1_5} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {.$IFDEF FPC_2_7_1_OR_ABOVE} + // support for RawByteString and UnicodeString + {.$MODE DelphiUnicode} + {.$MODESWITCH UnicodeStrings} + {.$CODEPAGE UTF8} // needed for Unicode string literals to work properly + {.$DEFINE VCL_2009} + {.$DEFINE DELPHI_2009} + {.$ELSE} + {$DEFINE VCL_70} + {$DEFINE DELPHI_7} + {.$ENDIF} +{$ENDIF} + +// end FPC + +{$IFDEF VCL_13} + {$DEFINE VCL_13_OR_ABOVE} +{$ENDIF} + +{$IFDEF VCL_13_OR_ABOVE} + {$DEFINE VCL_12_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_12} + {$DEFINE VCL_12_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_12_OR_ABOVE} + {$DEFINE VCL_11_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_11} + {$DEFINE VCL_11_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_11_OR_ABOVE} + {$DEFINE VCL_10_4_OR_ABOVE} + {$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_4} + {$DEFINE VCL_10_4_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_4_OR_ABOVE} + {$DEFINE VCL_10_3_OR_ABOVE} + {$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_3} + {$DEFINE VCL_10_3_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_OR_ABOVE} + {$DEFINE VCL_10_2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_2} + {$DEFINE VCL_10_2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_2_OR_ABOVE} + {$DEFINE VCL_10_1_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_1} + {$DEFINE VCL_10_1_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_1_OR_ABOVE} + {$DEFINE VCL_10_0_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_0} + {$DEFINE VCL_10_0_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_0_OR_ABOVE} + {$DEFINE VCL_XE8_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE8} + {$DEFINE VCL_XE8_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE VCL_XE7_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE7} + {$DEFINE VCL_XE7_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE7_OR_ABOVE} + {$DEFINE VCL_XE6_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE6} + {$DEFINE VCL_XE6_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE6_OR_ABOVE} + {$DEFINE VCL_XE5_OR_ABOVE} + {$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE5} + {$DEFINE VCL_XE5_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE5_OR_ABOVE} + {$DEFINE VCL_XE4_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE4} + {$DEFINE VCL_XE4_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE4_OR_ABOVE} + {$DEFINE VCL_XE3_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE3} + {$DEFINE VCL_XE3_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE3_OR_ABOVE} + {$DEFINE VCL_XE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE2} + {$DEFINE VCL_XE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE2_OR_ABOVE} + {$DEFINE VCL_XE_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE} + {$DEFINE VCL_XE_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE_OR_ABOVE} + {$DEFINE VCL_2010_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2010} + {$DEFINE VCL_2010_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2010_OR_ABOVE} + {$DEFINE VCL_2009_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2009} + {$DEFINE VCL_2009_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2009_OR_ABOVE} + {$DEFINE VCL_2007_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2007} + {$DEFINE VCL_2007_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2007_OR_ABOVE} + {$DEFINE VCL_2006_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2006} + {$DEFINE VCL_2006_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2006_OR_ABOVE} + {$DEFINE VCL_2005_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2005} + {$DEFINE VCL_2005_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2005_OR_ABOVE} + {$DEFINE VCL_8_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_80} + {$DEFINE VCL_8_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_8_OR_ABOVE} + {$DEFINE VCL_7_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_70} + {$DEFINE VCL_7_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_7_OR_ABOVE} + {$DEFINE VCL_6_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_60} + {$DEFINE VCL_6_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_6_OR_ABOVE} + {$DEFINE VCL_5_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_50} + {$DEFINE VCL_5_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_5_OR_ABOVE} + {$DEFINE VCL_4_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_40} + {$DEFINE VCL_4_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +// Normalize Delphi compiler defines to match FPC for consistency: +// +// CPU32 - any 32-bit CPU +// CPU64 - any 64-bit CPU +// WINDOWS - any Windows platform (32-bit, 64-bit, CE) +// WIN32 - Windows 32-bit +// WIN64 - Windows 64-bit +// WINCE - Windows CE +// +// Consult the "Free Pascal Programmer's Guide", Appendix G for the complete +// list of defines that are used. Do not work on this unless you understand +// what the FreePascal developers are doing. Not only do you have to +// descriminate with operating systems, but also with chip architectures +// are well. +// +// DCC Pulsar+ define the following values: +// ASSEMBLER +// DCC +// CONDITIONALEXPRESSIONS +// NATIVECODE +// UNICODE +// MACOS +// MACOS32 +// MACOS64 +// MSWINDOWS +// WIN32 +// WIN64 +// LINUX +// POSIX +// POSIX32 +// CPU386 +// CPUX86 +// CPUX64 +// +// Kylix defines the following values: +// LINUX +// (others??) +// + +{$IFNDEF FPC} + // TODO: We need to use ENDIAN_BIG for big endian chip architectures, + // such as 680x0, PowerPC, Sparc, and MIPS, once DCC supports them, + // provided it does not already define its own ENDIAN values by then... + {$DEFINE ENDIAN_LITTLE} + {$IFNDEF VCL_6_OR_ABOVE} + {$DEFINE MSWINDOWS} + {$ENDIF} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} + // TODO: map Pulsar's non-Windows platform defines... + {$IFDEF VCL_XE2_OR_ABOVE} + {$IFDEF VCL_XE8_OR_ABOVE} + {$IFDEF CPU32BITS} + //any 32-bit CPU + {$DEFINE CPU32} + {$ENDIF} + {$IFDEF CPU64BITS} + {$DEFINE CPU64} + {$ENDIF} + {$ELSE} + {$IFDEF CPU386} + //any 32-bit CPU + {$DEFINE CPU32} + //Intel 386 compatible chip architecture + {$DEFINE CPUI386} + {$ENDIF} + {$IFDEF CPUX86} + {$DEFINE CPU32} + {$ENDIF} + {$IFDEF CPUX64} + //any 64-bit CPU + {$DEFINE CPU64} + //AMD64 compatible chip architecture + {$DEFINE CPUX86_64} //historical name for AMD64 + {$DEFINE CPUAMD64} + {$ENDIF} + {$ENDIF} + {$ELSE} + {$IFNDEF DOTNET} + {$IFNDEF KYLIX} + {$DEFINE I386} + {$ENDIF} + {$ENDIF} + {$DEFINE CPU32} + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + //differences in DotNET Framework versions. + {$IFDEF VCL_2007_OR_ABOVE} + {$DEFINE DOTNET_2} + {$DEFINE DOTNET_2_OR_ABOVE} + {$ELSE} + {$DEFINE DOTNET_1_1} + {$ENDIF} + {$DEFINE DOTNET_1_1_OR_ABOVE} + // Extra include used in D7 for testing. Remove later when all comps are + // ported. Used to selectively exclude non ported parts. Allowed in places + // IFDEFs are otherwise not permitted. + {$DEFINE DOTNET_EXCLUDE} +{$ENDIF} + +// Check for available features + +{$IFDEF CBUILDER} + // When generating a C++ HPP file, if a class has no explicit constructor + // defined and contains compiler-managed members (xxxString, TDateTime, + // Variant, DelphiInterface, etc), the HPP will contain a forwarding + // inline constructor that implicitly initializes those managed members, + // which will overwrite any non-default initializations performed inside + // of InitComponent() overrides! In this situation, the workaround is to + // define an explicit constructor that calls the base class constructor + // manually, allowing those managed members to be initialized by the + // compiler before InitComponent() overrides then re-assign them. + {$DEFINE WORKAROUND_INLINE_CONSTRUCTORS} +{$ENDIF} + +{$IFDEF VCL_5_OR_ABOVE} + {$IFNDEF FPC} + {$IFNDEF KYLIX} + {$DEFINE HAS_RemoveFreeNotification} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_GetObjectProp} + {$DEFINE HAS_TObjectList} + {$DEFINE HAS_StrToInt64Def} +{$ENDIF} + +{$IFDEF VCL_6_OR_ABOVE} + {$DEFINE HAS_PCardinal} + {$DEFINE HAS_PByte} + {$DEFINE HAS_PWord} + {$DEFINE HAS_PPointer} + {$DEFINE HAS_TList_Assign} + {$DEFINE HAS_sLineBreak} + {$DEFINE HAS_RaiseLastOSError} + {$DEFINE HAS_SysUtils_IncludeExcludeTrailingPathDelimiter} + {$DEFINE HAS_SysUtils_DirectoryExists} + {$DEFINE HAS_UNIT_DateUtils} + {$DEFINE HAS_UNIT_StrUtils} + {$DEFINE HAS_UNIT_Types} + {$DEFINE HAS_TryStrToInt} + {$DEFINE HAS_TryStrToInt64} + {$DEFINE HAS_TryEncodeDate} + {$DEFINE HAS_TryEncodeTime} + {$DEFINE HAS_ENUM_ELEMENT_VALUES} + {$IFNDEF FPC} + {$DEFINE HAS_IInterface} + {$DEFINE HAS_TSelectionEditor} + {$DEFINE HAS_TStringList_CaseSensitive} + {$DEFINE HAS_AcquireExceptionObject} + {$IFNDEF KYLIX} + {$DEFINE HAS_DEPRECATED} + {$DEFINE HAS_SYMBOL_PLATFORM} + {$DEFINE HAS_UNIT_PLATFORM} + {$IFNDEF VCL_8_OR_ABOVE} + // Delphi 6 and 7 have an annoying bug that if a class method is declared as + // deprecated, the compiler will emit a "symbol is deprecated" warning + // on the method's implementation! So we will have to wrap implementations + // of deprecated methods with {$WARN SYMBOL_DEPRECATED OFF} directives + // to disable that warning. + {$DEFINE DEPRECATED_IMPL_BUG} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$IFNDEF DOTNET} + //Widget defines are omitted in .NET + {$DEFINE VCL_60_PLUS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_7_OR_ABOVE} + {$IFNDEF FPC} + {$DEFINE HAS_UInt64} // Note: it was just an alias for Int64 until D2006! + {$DEFINE HAS_NAMED_THREADS} + {$DEFINE HAS_TStrings_NameValueSeparator} + {$DEFINE HAS_TStrings_ValueFromIndex} + // Note: there is a ZLib unit available, but it doesn't have everything + // that is available in the System.ZLib unit in Delphi XE2+, so we are + // not going to use this ZLib unit yet... + {.$DEFINE HAS_UNIT_ZLib} + {$ENDIF} + {$DEFINE HAS_TFormatSettings} + {$DEFINE HAS_PosEx} + {$IFNDEF VCL_70} + // not implemented in D7 + {$DEFINE HAS_STATIC_TThread_Queue} + {$ENDIF} + {$IFNDEF CIL} + {$IFNDEF VCL_80} + // not implemented in D8 or .NET + {$DEFINE HAS_STATIC_TThread_Synchronize} + {$ENDIF} + {$ENDIF} +{$ELSE} + {$IFDEF CBUILDER_6} + {$DEFINE HAS_NAMED_THREADS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2005_OR_ABOVE} + {$IFDEF DCC} + // class helpers were first introduced in D2005, but were buggy and not + // officially supported until D2006... + {.$DEFINE HAS_CLASS_HELPER} + {$ENDIF} +{$ELSE} + {$IFDEF DCC} + // InterlockedCompareExchange() was declared in the Windows unit using Pointer + // parameters until Delphi 2005, when it was switched to Longint parameters + // instead to match the actual Win32 API declaration. + {$DEFINE HAS_InterlockedCompareExchange_Pointers} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2006_OR_ABOVE} + {$DEFINE USE_INLINE} + {$DEFINE HAS_2PARAM_FileAge} + {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? + {$DEFINE HAS_CLASS_HELPER} + {$IFDEF WINDOWS} + // System.RegisterExpectedMemoryLeak() is only available on Windows at this time + {$DEFINE HAS_System_RegisterExpectedMemoryLeak} + {$ENDIF} + // In C++Builder 2006 and 2007, UInt64 is emitted as signed __int64 in HPP + // files instead of as unsigned __int64. This causes conflicts in overloaded + // routines that have (U)Int64 parameters. This was fixed in C++Builder 2009... + {$IFDEF CBUILDER} + {$DEFINE BROKEN_UINT64_HPPEMIT} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2007_OR_ABOVE} + {$IFNDEF CBUILDER_2007} + // class properties are broken in C++Builder 2007, causing AVs at compile-time + {$DEFINE HAS_CLASSPROPERTIES} + {$ENDIF} + // Native(U)Int exist but are buggy, so do not use them yet + {.$DEFINE HAS_NativeInt} + {.$DEFINE HAS_NativeUInt} + {$DEFINE HAS_DWORD_PTR} + {$DEFINE HAS_ULONG_PTR} + {$DEFINE HAS_ULONGLONG} + {$DEFINE HAS_PGUID} + {$DEFINE HAS_PPAnsiChar} + {$DEFINE HAS_CurrentYear} + {$IFNDEF DOTNET} + {$DEFINE HAS_TIMEUNITS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2009_OR_ABOVE} + {$IFNDEF DOTNET} + {$DEFINE STRING_IS_UNICODE} + {$DEFINE HAS_UnicodeString} + {$DEFINE HAS_TEncoding} + {$DEFINE HAS_TCharacter} + {$DEFINE HAS_InterlockedCompareExchangePointer} + {$DEFINE HAS_WIDE_TCharArray} + {$DEFINE HAS_PUInt64} + {$IFDEF VCL_2009} + // TODO: need to differentiate between RTM and Update 1 + // FmtStr() is broken in RTM but was fixed in Update 1 + {$DEFINE BROKEN_FmtStr} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_CLASSVARS} + {$DEFINE HAS_DEPRECATED_MSG} + {$DEFINE HAS_TBytes} + // Native(U)Int are still buggy, so do not use them yet + {.$DEFINE HAS_NativeInt} + {.$DEFINE HAS_NativeUInt} + {$DEFINE HAS_Int8} + {$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_UIntToStr} + // UInt64 is now emitted as unsigned __int64 in HPP files + {$IFDEF CBUILDER} + {$UNDEF BROKEN_UINT64_HPPEMIT} + {$ENDIF} + {$IFDEF DCC} + {$IFDEF WINDOWS} + // Exception.RaiseOuterException() is only available on Windows at this time + {$DEFINE HAS_Exception_RaiseOuterException} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_SetCodePage} + {$DEFINE HAS_PRawByteString} + {$DEFINE HAS_TThreadProcedure} +{$ENDIF} + +{$IFDEF VCL_2010_OR_ABOVE} + {$DEFINE HAS_CLASSCONSTRUCTOR} + {$DEFINE HAS_CLASSDESTRUCTOR} + {$DEFINE HAS_DELAYLOAD} + {$DEFINE HAS_TThread_NameThreadForDebugging} + {$DEFINE DEPRECATED_TThread_SuspendResume} + // Native(U)Int are finally ok to use now + {$DEFINE HAS_NativeInt} + {$DEFINE HAS_NativeUInt} + {$DEFINE HAS_USHORT} + {$DEFINE HAS_IOUtils_TPath} +{$ENDIF} + +{$IFDEF VCL_XE_OR_ABOVE} + {$DEFINE HAS_TFormatSettings_Object} + {$DEFINE HAS_LocaleCharsFromUnicode} + {$DEFINE HAS_UnicodeFromLocaleChars} + {$DEFINE HAS_PLongBool} + {$DEFINE HAS_PVOID} + {$DEFINE HAS_ULONG64} + {$DEFINE HAS_TEncoding_GetEncoding_ByEncodingName} + {$DEFINE HAS_DateUtils_TTimeZone} + {$IFDEF DCC} + // Exception.RaiseOuterException() is now available on all platforms + {$DEFINE HAS_Exception_RaiseOuterException} + {$ENDIF} + {$IFNDEF DOTNET} + {$DEFINE HAS_TInterlocked} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE2_OR_ABOVE} + {$DEFINE HAS_SIZE_T} + {$DEFINE HAS_PSIZE_T} + {$DEFINE HAS_SSIZE_T} + {$DEFINE HAS_PSSIZE_T} + {$DEFINE HAS_LONG} + {$DEFINE HAS_ComponentPlatformsAttribute} + {$DEFINE HAS_ComponentPlatformsAttribute_Win32} + {$DEFINE HAS_ComponentPlatformsAttribute_Win64} + {$DEFINE HAS_ComponentPlatformsAttribute_OSX32} + {$DEFINE HAS_System_ReturnAddress} + {$DEFINE HAS_DIRECTIVE_WARN_DEFAULT} + {$DEFINE HAS_UNIT_System_ZLib} +{$ENDIF} + +{$IFDEF VCL_XE3_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_ZEROBASEDSTRINGS} + {$DEFINE HAS_SysUtils_TStringHelper} + {$IFDEF NEXTGEN} + {$DEFINE DCC_NEXTGEN} + {$DEFINE HAS_MarshaledAString} + {$DEFINE USE_MARSHALLED_PTRS} + {$IFDEF AUTOREFCOUNT} + {$DEFINE USE_OBJECT_ARC} + {$ENDIF} + {$ENDIF} + // technically, these are present in XE3, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} + {.$DEFINE HAS_ComponentPlatformsAttribute_Android} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32} + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} + {.$DEFINE HAS_ComponentPlatformsAttribute_WinNX32} +{$ENDIF} + +{$IFDEF VCL_XE4_OR_ABOVE} + {$DEFINE HAS_AnsiStrings_StrPLCopy} + {$DEFINE HAS_AnsiStrings_StrLen} + {$DEFINE HAS_Character_TCharHelper} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} +{$ENDIF} + +{$IFDEF VCL_XE5_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_Android} +{$ENDIF} + +{$IFDEF VCL_XE5_UPDATE2_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_LINKUNIT} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_NAMESPACE} +{$ENDIF} + +{$IFDEF VCL_XE7_OR_ABOVE} + {$DEFINE HAS_TNetEncoding} +{$ENDIF} + +{$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device32} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device64} + // technically, these are present in XE8, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64} + {.$DEFINE HAS_ComponentPlatformsAttribute_WinIoT32} +{$ENDIF} + +{$IFDEF VCL_10_0_OR_ABOVE} + {$IFDEF ANDROID} + {$DEFINE HAS_TAndroidHelper} + {$ENDIF} + // technically, these are present in 10.0 Seattle, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_WinARM} +{$ENDIF} + +{$IFDEF VCL_10_1_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_LEGACYHPP} + {$DEFINE HAS_TStrings_AddPair} + // technically, these are present in 10.1 Berlin, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_OSX64} + {.$DEFINE HAS_ComponentPlatformsAttribute_OSXNX64} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32Arm} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64Arm} + {.$DEFINE HAS_ComponentPlatformsAttribute_Android64} +{$ENDIF} + +{$IFDEF VCL_10_2_OR_ABOVE} + {.$WARN IMPLICIT_INTEGER_CAST_LOSS OFF} + {.$WARN IMPLICIT_CONVERSION_LOSS OFF} + {.$WARN COMBINING_SIGNED_UNSIGNED64 OFF} + {$DEFINE HAS_STATIC_TThread_ForceQueue} + // In Delphi 10.2 Tokyo, TThread.ForceQueue() is broken on Android, the + // passed in procedure is called immediately instead of being delayed! + {$IFDEF ANDROID} + {$DEFINE BROKEN_TThread_ForceQueue} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator32} + {$DEFINE HAS_ComponentPlatformsAttribute_Android32Arm} + {$DEFINE HAS_ComponentPlatformsAttribute_WinARM32} + {$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} // removed in 10.3 Rio + // technically, these are present in 10.3 Rio, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator64} + {$IFDEF DCC} + {$IFDEF LINUX} + // RLebeau 9/25/2019: there is a bug in the IDE when debugging Linux projects + // where the EThreadNameException exception raised by TThread.NameThreadForDebugging() + // is not handled correctly. + {$UNDEF HAS_NAMED_THREADS} + {$ENDIF} + {$ENDIF} + {$IFDEF ANDROID} + {$UNDEF BROKEN_TThread_ForceQueue} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_UPDATE2_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_AllPlatforms} + {$DEFINE HAS_ComponentPlatformsAttribute_OSX64} +{$ENDIF} + +{$IFDEF VCL_10_4_OR_ABOVE} + // 0-based string indexing via '[]' is turned off by default in Delphi 10.4. + // TStringHelper is always 0-indexed, flat RTL functions are always 1-indexed, + // and now '[]' is 1-indexed again on all platforms - {$ZEROBASEDSTRINGS OFF} + // is the default. + {.$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} +{$ENDIF} + +{$IFDEF VCL_11_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm32} + {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm64} + {$DEFINE HAS_ComponentPlatformsAttribute_OSXArm64} +{$ENDIF} + +// Delphi XE+ cross-compiling +{$IFNDEF FPC} + {$IFDEF POSIX} + {$IF RTLVersion >= 22.0} + {$DEFINE UNIX} + {$UNDEF USE_BASEUNIX} + {$DEFINE VCL_CROSS_COMPILE} + {$DEFINE USE_VCL_POSIX} + {$IFEND} + {$ENDIF} + {$IFDEF LINUX} + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF RTLVersion >= 22.0} + {$DEFINE VCL_CROSS_COMPILE} + {$DEFINE USE_VCL_POSIX} + {$IFEND} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_CROSS_COMPILE} + {$UNDEF KYLIXCOMPAT} +{$ELSE} + {$IFDEF KYLIXCOMPAT} + {$linklib c} + {$ENDIF} +{$ENDIF} + +{$IFDEF FPC} + {$DEFINE USE_INLINE} + {$DEFINE USE_CLASSINLINE} + {$DEFINE USE_TBitBtn} //use Bit Buttons instead of Buttons + {$DEFINE FPC_REINTRODUCE_BUG} + {$DEFINE FPC_CIRCULAR_BUG} + {$DEFINE NO_REDECLARE} + {$DEFINE BYTE_COMPARE_SETS} + {$DEFINE HAS_QWord} // TODO: when was QWord introduced? + {$DEFINE HAS_PQWord} // TODO: when was PQWord introduced? + {$IFDEF FPC_2_1_5_OR_ABOVE} + {$DEFINE HAS_UInt64} + {.$DEFINE HAS_PUInt64} // TODO: is this defined? + {$ENDIF} + {$IFDEF FPC_2_2_0_OR_ABOVE} + {$DEFINE HAS_InterlockedCompareExchange_Pointers} + {$ENDIF} + {$IFDEF FPC_2_2_2_OR_ABOVE} + {$DEFINE HAS_SharedSuffix} + {$ENDIF} + {$IFDEF FPC_2_2_4_OR_ABOVE} + // these types are only available on Unix systems (FreeBSD, Linux, etc) + {$IFDEF UNIX} + {$DEFINE HAS_UNIT_UnixType} + {$DEFINE HAS_SIZE_T} + {$DEFINE HAS_PSIZE_T} + {$DEFINE HAS_SSIZE_T} + {$DEFINE HAS_PSSIZE_T} + {$DEFINE HAS_TIME_T} + {$DEFINE HAS_PTIME_T} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_PtrInt} + {$DEFINE HAS_PtrUInt} + {$DEFINE HAS_PGUID} + {$DEFINE HAS_LPGUID} + {$DEFINE HAS_PPAnsiChar} + {$DEFINE HAS_ENUM_ELEMENT_VALUES} + {$DEFINE HAS_AcquireExceptionObject} // TODO: when was AcquireExceptionObject introduced? + {$IFDEF WINDOWS} + {$DEFINE HAS_ULONG_PTR} + {.$DEFINE HAS_ULONGLONG} // TODO: is this defined? + {$ENDIF} + {$DEFINE HAS_UNIT_ctypes} + {$DEFINE HAS_sLineBreak} + {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? + {$IFDEF FPC_HAS_UNICODESTRING} + {$DEFINE HAS_UnicodeString} + {$ELSE} + {$IFDEF FPC_2_4_0_OR_ABOVE} + {$DEFINE HAS_UnicodeString} + {$ENDIF} + {$ENDIF} + {$IFDEF FPC_2_4_4_OR_ABOVE} + {$DEFINE DEPRECATED_TThread_SuspendResume} + {$DEFINE HAS_DEPRECATED} // TODO: when was deprecated introduced? Possibly 1.9.x + {$DEFINE HAS_DEPRECATED_MSG} // TODO: when was message support added? Possibly 2.4.x + {$DEFINE HAS_STATIC_TThread_Synchronize} + {$IFNDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE USE_SEMICOLON_BEFORE_DEPRECATED} // TODO: which earlier versions require a semicolon? + {$ENDIF} + {$ENDIF} + {$IFDEF FPC_2_6_0_OR_ABOVE} + {$DEFINE HAS_NativeInt} + {$DEFINE HAS_NativeUInt} + {$DEFINE HAS_CLASS_HELPER} + {$ENDIF} + {$IFDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE HAS_Int8} + {$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_GetLocalTimeOffset} + {$DEFINE HAS_UniversalTimeToLocal} + {$DEFINE HAS_LocalTimeToUniversal} + {$ENDIF} + {$IFDEF FPC_2_6_4_OR_ABOVE} + {$DEFINE HAS_PInt8} + {$DEFINE HAS_PUInt8} + {$DEFINE HAS_PInt16} + {$DEFINE HAS_PUInt16} + {$DEFINE HAS_PInt32} + {$DEFINE HAS_PUInt32} + {$ENDIF} + {$IFDEF FPC_3_0_0_OR_ABOVE} + {$DEFINE HAS_STATIC_TThread_Queue} + {$DEFINE HAS_SetCodePage} + {$ENDIF} + {$IFDEF FPC_UNICODESTRINGS} + {$DEFINE STRING_IS_UNICODE} + {$ENDIF} + {$IFDEF FPC_3_1_1_OR_ABOVE} + {$DEFINE HAS_STATIC_TThread_ForceQueue} // requires rev 37359+ + {$DEFINE HAS_PRawByteString} + {$DEFINE HAS_UIntToStr} // requires rev 40529+ + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + {$DEFINE WIDGET_WINFORMS} +{$ELSE} + {$DEFINE WIDGET_VCL_LIKE} // LCL included. + {$DEFINE WIDGET_VCL_LIKE_OR_KYLIX} + {$IFDEF FPC} + {$DEFINE WIDGET_LCL} + {$ELSE} + {$IFDEF KYLIX} + {$DEFINE WIDGET_KYLIX} + {$ELSE} + {$DEFINE WIDGET_VCL} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +// .NET and Delphi 2009+ support UNICODE strings natively! +// +// FreePascal 2.4.0+ supports UnicodeString, but does not map its +// native String type to UnicodeString except when {$MODE DelphiUnicode} +// or {$MODESWITCH UnicodeStrings} is enabled. However, UNICODE is not +// defined in that mode yet until its RTL has been updated to support +// UnicodeString. STRING_UNICODE_MISMATCH is defined when the native +// String/Char types do not map to the same types that APIs are expecting +// based on whether UNICODE is defined or not. +// +// NOTE: Do not define UNICODE here. The compiler defines +// the symbol automatically. +{$IFDEF STRING_IS_UNICODE} + {$IFNDEF UNICODE} + {$DEFINE STRING_UNICODE_MISMATCH} + {$ENDIF} +{$ELSE} + {$DEFINE STRING_IS_ANSI} + {$IFDEF UNICODE} + {$DEFINE STRING_UNICODE_MISMATCH} + {$ENDIF} +{$ENDIF} + +{$IFDEF DCC_NEXTGEN} + {$DEFINE NO_ANSI_TYPES} + {.$DEFINE STRING_IS_IMMUTABLE} // Strings are NOT immutable in NEXTGEN yet + {$IFDEF USE_OBJECT_ARC} + // TODO: move these to an appropriate section. Not doing this yet because + // it is a major interface change to switch to Generics and we should + // maintain backwards compatibility with earlier compilers for the time + // being. Defining them only here for now because the non-Generic versions + // of these classes have become deprecated by ARC and so we need to start + // taking advantage of the Generics versions... + {$DEFINE HAS_UNIT_Generics_Collections} + {$DEFINE HAS_UNIT_Generics_Defaults} + {$DEFINE HAS_GENERICS_TDictionary} + {$DEFINE HAS_GENERICS_TList} + {$DEFINE HAS_GENERICS_TObjectList} + {$DEFINE HAS_GENERICS_TThreadList} + // TArray.Copy() was introduced in XE7 but was buggy. It was fixed in XE8: + // + // RSP-9763 TArray.Copy copies from destination to source for unmanaged types + // https://quality.embarcadero.com/browse/RSP-9763 + // + {$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE HAS_GENERICS_TArray_Copy} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +// TODO: Ansi data types were disabled on mobile platforms in XE3, but +// UTF8String and RawByteString were re-enabled in 10.1 Berlin! What else, +// if anything, was re-enabled to facilitate that? +// +// UPDATE: In 10.4 Sydney, AnsiChar and AnsiString were re-enabled on +// mobile platforms! NEXTGEN is no longer defined in the mobile compilers. +{$IFDEF NO_ANSI_TYPES} + {$UNDEF HAS_AnsiString} + {$UNDEF HAS_AnsiChar} + {$UNDEF HAS_PAnsiChar} + {$UNDEF HAS_PPAnsiChar} + {$UNDEF HAS_AnsiStrings_StrPLCopy} + {$UNDEF HAS_AnsiStrings_StrLen} +{$ENDIF} + +{$IFDEF WIN32} + {$DEFINE WIN32_OR_WIN64} +{$ENDIF} +{$IFDEF WIN64} + {$DEFINE WIN32_OR_WIN64} +{$ENDIF} + +{$IFDEF WIN32_OR_WIN64} + {$DEFINE USE_ZLIB_UNIT} + {$IFNDEF DCC_NEXTGEN} + {$DEFINE USE_OPENSSL} // !!! MOVED HERE BY EMBT + {$DEFINE USE_SSPI} + {$IFDEF STRING_IS_UNICODE} + {$DEFINE SSPI_UNICODE} + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF WINCE} + {$DEFINE USE_OPENSSL} + // RLebeau: not sure if the above Win32/64 defines also apply to WinCE, + // so keeping them separate for now... +{$ENDIF} + +// High-performance counters are not reliable on multi-core systems, and have +// been known to cause problems with TIdIOHandler.ReadLn() timeouts in Windows +// XP SP3, both 32-bit and 64-bit. Refer to these discussions for more info: +// +// http://www.virtualdub.org/blog/pivot/entry.php?id=106 +// http://blogs.msdn.com/oldnewthing/archive/2008/09/08/8931563.aspx +// +// Do not enable thus unless you know it will work correctly on your systems! +{$IFDEF WINDOWS} + {.$DEFINE USE_HI_PERF_COUNTER_FOR_TICKS} +{$ENDIF} + +{$IFDEF UNIX} + {$DEFINE USE_OPENSSL} + {$DEFINE USE_ZLIB_UNIT} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF MACOS} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF DARWIN} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF LINUX} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF IOS} + {$DEFINE HAS_getifaddrs} + {$DEFINE USE_OPENSSL} + + // Support for 64-bit ARM iOS Simulator was added in Delphi 11.2 + // TODO: how to detect iOS Simulator in FPC? Does it support 64-bit ARM? + {$IFDEF CPUARM} + {$IFNDEF IOSSIMULATOR} + // RLebeau: For iOS devices, OpenSSL cannot be used as an external library, + // it must be statically linked into the app. For the iOS simulator, this + // is not true. Users who want to use OpenSSL in iOS device apps will need + // to add the static OpenSSL library to the project and then include the + // IdSSLOpenSSLHeaders_static unit in their uses clause. It hooks up the + // statically linked functions for the IdSSLOpenSSLHeaders unit to use... + {$DEFINE STATICLOAD_OPENSSL} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF FREEBSD} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF ANDROID} + {$UNDEF HAS_getifaddrs} +{$ENDIF} + +{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} + {$DEFINE REQUIRES_PROPER_ALIGNMENT} +{$ENDIF} + +// +//iconv defines section. +{$DEFINE USE_ICONV_UNIT} +{$DEFINE USE_ICONV_ENC} +{$IFDEF UNIX} + {$DEFINE USE_ICONV} + {$IFDEF USE_BASEUNIX} + {$IFDEF FPC} + {$UNDEF USE_ICONV_UNIT} + {$ELSE} + {$UNDEF USE_ICONV_ENC} + {$ENDIF} + {$ENDIF} + {$IFDEF KYLIXCOMPAT} + //important!! Iconv functions are defined in the libc.pas Kylix compatible unit. + {$UNDEF USE_ICONV_ENC} + {$UNDEF USE_ICONV_UNIT} + {$ENDIF} +{$ENDIF} +{$IFDEF NETWARELIBC} + {$DEFINE USE_ICONV} + //important!!! iconv functions are defined in the libc.pas Novell Netware header. + //Do not define USE_ICONV_UNIT + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} +{$ENDIF} + +{$UNDEF USE_SAFELOADLIBRARY} +{$IFDEF WINDOWS} + {$UNDEF USE_ICONV_ENC} + {$DEFINE USE_SAFELOADLIBRARY} +{$ENDIF} +// Use here for all *nix systems that you do not want to use iconv library +{$IFDEF FPC} + {$IFDEF ANDROID} + {$UNDEF USE_ICONV} + {$DEFINE USE_LCONVENC} + {$ENDIF} +{$ENDIF} + +{$UNDEF USE_INVALIDATE_MOD_CACHE} +{$UNDEF USE_SAFELOADLIBRARY} +//This must come after the iconv defines because this compiler targets a Unix-like +//operating system. One key difference is that it does have a TEncoding class. +//If this comes before the ICONV defines, it creates problems. +//This also must go before the THandle size calculations. +{$IFDEF VCL_CROSS_COMPILE} + {$IFDEF POSIX} + {$IFNDEF LINUX} + {$DEFINE BSD} + {$ENDIF} + {$DEFINE USE_SAFELOADLIBRARY} + {$DEFINE USE_INVALIDATE_MOD_CACHE} + {$ENDIF} + //important!!! iconv functions are defined in the libc.pas Novell Netware header. + //Do not define USE_ICONVUNIT + {$UNDEF USE_ICONV} + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} + {$DEFINE INT_THREAD_PRIORITY} +{$ENDIF} + +{$IFNDEF USE_ICONV} + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} +{$ENDIF} + +//IMPORTANT!!!! +// +//Do not remove this!!! This is to work around a conflict. In DCC, MACOS +//will mean OS X. In FreePascal, the DEFINE MACOS means MacIntosh System OS Classic. +{$IFDEF DCC} + // DCC defines MACOS for both iOS and OS X platforms, need to differentiate + {$IFDEF MACOS} + {$IFNDEF IOS} + {$DEFINE OSX} + {$DEFINE DARWIN} + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF FPC} + // FPC defines DARWIN for both OSX and iOS, need to differentiate + {$IFDEF DARWIN} + {$IFNDEF IOS} + {$DEFINE OSX} + {$ENDIF} + {$ENDIF} + {$IFDEF MACOS} + {$DEFINE MACOS_CLASSIC} + {$ENDIF} +{$ENDIF} + +{ +BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit +word to an 8 bit byte and an 8 bit byte field named sa_len was added. +} +//Place this only after DARWIN has been defined for Delphi MACOS +{$IFDEF FREEBSD} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF DARWIN} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF MORPHOS} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} + +// Do NOT remove these IFDEF's. They are here because InterlockedExchange +// only handles 32bit values. Some Operating Systems may have 64bit +// THandles. This is not always tied to the platform architecture. + +{$IFDEF AMIGA} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF ATARI} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF BEOS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF BSD} + //I think BSD might handle FreeBSD, NetBSD, OpenBSD, and Darwin + {$IFDEF IOS} + {$IFDEF CPUARM64} + {$DEFINE CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$IFDEF CPUARM32} + {$DEFINE CPU32} + {$ENDIF} + {$DEFINE THANDLE_32} + {$ENDIF} + {$ENDIF} + {$IFDEF OSX} + {$IFDEF FPC} + {$DEFINE THANDLE_32} + {$ELSE} + {$DEFINE THANDLE_CPUBITS} // !!! ADDED OSX BY EMBT + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF EMBEDDED} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF EMX} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF GBA} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF GO32} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF LINUX} + {$IFDEF LINUX64} + {$DEFINE CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$IFDEF LINUX32} + {$DEFINE CPU32} + {$ENDIF} + {$DEFINE THANDLE_32} + {$ENDIF} +{$ENDIF} +{$IFDEF MACOS_CLASSIC} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF MORPHOS} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF NATIVENT} //Native NT for kernel level drivers + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF NDS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF NETWARE} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF NETWARELIBC} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF OS2} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF PALMOS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF SOLARIS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF SYMBIAN} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WII} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WATCOM} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WINDOWS} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} + +// end platform specific stuff for THandle size + +{$IFDEF THANDLE_CPUBITS} + {$IFDEF CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$DEFINE THANDLE_32} + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + {$DEFINE DOTNET_OR_ICONV} +{$ENDIF} +{$IFDEF USE_ICONV} + {$DEFINE DOTNET_OR_ICONV} +{$ENDIF} + +{$UNDEF STREAM_SIZE_64} +{$IFDEF FPC} + {$DEFINE STREAM_SIZE_64} +{$ELSE} + {$IFDEF VCL_6_OR_ABOVE} + {$DEFINE STREAM_SIZE_64} + {$ENDIF} +{$ENDIF} + +{$IFNDEF FREE_ON_FINAL} + {$IFNDEF DOTNET} + {$IFDEF HAS_System_RegisterExpectedMemoryLeak} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_FASTMM4} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_MADEXCEPT} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_LEAKCHECK} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{ +We must determine what the SocketType parameter is for the Socket function. +In DotNET, it's SocketType. In Kylix and the libc.pas Kylix-compatibility +library, it's a __socket_type. In BaseUnix, it's a C-type Integer. In Windows, +it's a LongInt. + +} +{$UNDEF SOCKETTYPE_IS_SOCKETTYPE} +{$UNDEF SOCKETTYPE_IS_CINT} +{$UNDEF SOCKETTYPE_IS___SOCKETTYPE} +{$UNDEF SOCKETTYPE_IS_LONGINT} +{$UNDEF SOCKETTYPE_IS_NUMERIC} +{$UNDEF SOCKET_LEN_IS_socklen_t} +{$IFDEF DOTNET} + {$DEFINE SOCKETTYPE_IS_SOCKETTYPE} +{$ENDIF} +{$IFDEF USE_BASEUNIX} + {$DEFINE SOCKETTYPE_IS_CINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF KYLIXCOMPAT} + {$DEFINE SOCKETTYPE_IS___SOCKETTYPE} +{$ENDIF} +{$IFDEF USE_VCL_POSIX} + {$DEFINE SOCKETTYPE_IS_NUMERIC} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKET_LEN_IS_socklen_t} +{$ENDIF} +{$IFDEF WINDOWS} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF OS2} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF NETWARE} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} + +{Take advantage of some TCP features specific to some stacks. +They work somewhat similarly but there's a key difference. +In Linux, TCP_CORK is turned on to send fixed packet sizes and +when turned-off (uncorked), any remaining data is sent. With +TCP_NOPUSH, this might not happen and remaining data is only sent +before disconnect. TCP_KEEPIDLE and TCP_KEEPINTVL so the IFDEF LINUX and IFDEF +SOLARIS instead of IFDEF UNIX is not an error, it's deliberate.} +{$UNDEF HAS_TCP_NOPUSH} +{$UNDEF HAS_TCP_CORK} +{$UNDEF HAS_TCP_KEEPIDLE} +{$UNDEF HAS_TCP_KEEPINTVL} +{$UNDEF HAS_SOCKET_NOSIGPIPE} +{$IFDEF BSD} + {$DEFINE HAS_TCP_NOPUSH} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE HAS_TCP_NOPUSH} +{$ENDIF} +{$IFDEF LINUX} + {$DEFINE HAS_TCP_CORK} + {$DEFINE HAS_TCP_KEEPIDLE} + {$DEFINE HAS_TCP_KEEPINTVL} +{$ENDIF} +{$IFDEF SOLARIS} + {$DEFINE HAS_TCP_CORK} +{$ENDIF} +{$IFDEF NETBSD} + {$DEFINE HAS_TCP_CORK} + {$DEFINE HAS_TCP_KEEPIDLE} + {$DEFINE HAS_TCP_KEEPINTVL} +{$ENDIF} +{$IFDEF USE_VCL_POSIX} + // TODO: which platforms actually have SO_NOSIGPIPE available? + {$DEFINE HAS_SOCKET_NOSIGPIPE} + {$IFDEF ANDROID} + {$UNDEF HAS_SOCKET_NOSIGPIPE} + {$ENDIF} + {$IFDEF LINUX} + {$UNDEF HAS_SOCKET_NOSIGPIPE} + {$ENDIF} +{$ENDIF} +{end Unix OS specific stuff} +{$IFDEF DEBUG} + {$UNDEF USE_INLINE} +{$ENDIF} + +// RLebeau 5/24/2015: In C++Builder 2006 and 2007, UInt64 is emitted as +// signed __int64 in HPP files instead of as unsigned __int64. This causes +// conflicts in overloaded routines that have (U)Int64 parameters. This +// was fixed in C++Builder 2009. For compilers that do not have a native +// UInt64 type, or for C++Builder 2006/2007, let's define a record type +// that can hold UInt64 values... +{$IFDEF HAS_UInt64} + {$IFDEF BROKEN_UINT64_HPPEMIT} + {$DEFINE TIdUInt64_HAS_QuadPart} + {$ENDIF} +{$ELSE} + {$IFNDEF HAS_QWord} + {$DEFINE TIdUInt64_HAS_QuadPart} + {$ENDIF} +{$ENDIF} + +// RLebeau 9/5/2013: it would take a lot of work to re-write Indy to support +// both 0-based and 1-based string indexing, so we'll just turn off 0-based +// indexing for now... +{$IFDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} + {$ZEROBASEDSTRINGS OFF} +{$ENDIF} diff --git a/Lib/Protocols/IdCompressionIntercept.pas b/Lib/Protocols/IdCompressionIntercept.pas index e3d3a1728..4b314e349 100644 --- a/Lib/Protocols/IdCompressionIntercept.pas +++ b/Lib/Protocols/IdCompressionIntercept.pas @@ -1,341 +1,341 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. - - - $Log$ - - - Rev 1.10 2/22/2004 12:04:00 AM JPMugaas - Updated for file rename. - - - Rev 1.9 2/12/2004 11:28:04 PM JPMugaas - Modified compression intercept to use the ZLibEx unit. - - - Rev 1.8 2004.02.09 9:56:00 PM czhower - Fixed for lib changes. - - - Rev 1.7 5/12/2003 12:31:00 AM GGrieve - Get compiling again with DotNet Changes - - - Rev 1.6 10/12/2003 1:49:26 PM BGooijen - Changed comment of last checkin - - - Rev 1.5 10/12/2003 1:43:24 PM BGooijen - Changed IdCompilerDefines.inc to Core\IdCompilerDefines.inc - - - Rev 1.3 6/27/2003 2:38:04 PM BGooijen - Fixed bug where last part was not compressed/send - - - Rev 1.2 4/10/2003 4:12:42 PM BGooijen - Added TIdServerCompressionIntercept - - - Rev 1.1 4/3/2003 2:55:48 PM BGooijen - Now calls DeinitCompressors on disconnect - - - Rev 1.0 11/14/2002 02:15:50 PM JPMugaas -} -unit IdCompressionIntercept; - -{ This file implements an Indy intercept component that compresses a data - stream using the open-source zlib compression library. In order for this - file to compile on Windows, the follow .obj files *must* be provided as - delivered with this file: - - deflate.obj - inflate.obj - inftrees.obj - trees.obj - adler32.obj - infblock.obj - infcodes.obj - infutil.obj - inffast.obj - - On Linux, the shared-object file libz.so.1 *must* be available on the - system. Most modern Linux distributions include this file. - - Simply set the CompressionLevel property to a value between 1 and 9 to - enable compressing of the data stream. A setting of 0(zero) disables - compression and the component is dormant. The sender *and* received must - have compression enabled in order to properly decompress the data stream. - They do *not* have to use the same CompressionLevel as long as they are - both set to a value between 1 and 9. - - Original Author: Allen Bauer - - This source file is submitted to the Indy project on behalf of Borland - Sofware Corporation. No warranties, express or implied are given with - this source file. -} -interface - -{$I IdCompilerDefines.inc} - -uses - Classes, - {$IFDEF HAS_UNIT_System_ZLib} - {$IFDEF USE_INLINE} - System.ZLib, // here to facilitate inlining - {$ENDIF} - {$ENDIF} - IdException, - IdGlobal, - IdGlobalProtocols, - IdIntercept, - IdZLibHeaders; - -type - EIdCompressionException = class(EIdException); - EIdCompressorInitFailure = class(EIdCompressionException); - EIdDecompressorInitFailure = class(EIdCompressionException); - EIdCompressionError = class(EIdCompressionException); - EIdDecompressionError = class(EIdCompressionException); - - TIdCompressionLevel = 0..9; - - TIdCompressionIntercept = class(TIdConnectionIntercept) - protected - FCompressionLevel: TIdCompressionLevel; - FCompressRec: TZStreamRec; - FDecompressRec: TZStreamRec; - FRecvBuf: TIdBytes; - FRecvCount, FRecvSize: UInt32; - FSendBuf: TIdBytes; - FSendCount, FSendSize: UInt32; - procedure SetCompressionLevel(Value: TIdCompressionLevel); - procedure InitCompressors; - procedure DeinitCompressors; - public - destructor Destroy; override; - procedure Disconnect; override; - procedure Receive(var VBuffer: TIdBytes); override; - procedure Send(var VBuffer: TIdBytes); override; - published - property CompressionLevel: TIdCompressionLevel read FCompressionLevel write SetCompressionLevel; - end; - - TIdServerCompressionIntercept = class(TIdServerIntercept) - protected - FCompressionLevel: TIdCompressionLevel; - public - procedure Init; override; - function Accept(AConnection: TComponent): TIdConnectionIntercept; override; - published - property CompressionLevel: TIdCompressionLevel read FCompressionLevel write FCompressionLevel; - end; - - -implementation - -uses - IdResourceStringsProtocols, IdExceptionCore; - -{ TIdCompressionIntercept } - -procedure TIdCompressionIntercept.DeinitCompressors; -begin - if Assigned(FCompressRec.zalloc) then begin - deflateEnd(FCompressRec); - FillChar(FCompressRec, SizeOf(FCompressRec), 0); - end; - if Assigned(FDecompressRec.zalloc) then - begin - inflateEnd(FDecompressRec); - FillChar(FDecompressRec, SizeOf(FDecompressRec), 0); - end; -end; - -destructor TIdCompressionIntercept.Destroy; -begin - DeinitCompressors; - SetLength(FRecvBuf, 0); - SetLength(FSendBuf, 0); - inherited Destroy; -end; - -procedure TIdCompressionIntercept.Disconnect; -begin - inherited Disconnect; - DeinitCompressors; -end; - -procedure TIdCompressionIntercept.InitCompressors; -begin - if not Assigned(FCompressRec.zalloc) then - begin - FCompressRec.zalloc := IdZLibHeaders.zlibAllocMem; - FCompressRec.zfree := IdZLibHeaders.zlibFreeMem; - if deflateInit_(FCompressRec, FCompressionLevel, zlib_Version, SizeOf(FCompressRec)) <> Z_OK then - begin - raise EIdCompressorInitFailure.Create(RSZLCompressorInitializeFailure); - end; - end; - if not Assigned(FDecompressRec.zalloc) then - begin - FDecompressRec.zalloc := IdZLibHeaders.zlibAllocMem; - FDecompressRec.zfree := IdZLibHeaders.zlibFreeMem; - if inflateInit_(FDecompressRec, zlib_Version, SizeOf(FDecompressRec)) <> Z_OK then - begin - raise EIdDecompressorInitFailure.Create(RSZLDecompressorInitializeFailure); - end; - end; -end; - -procedure TIdCompressionIntercept.Receive(var VBuffer: TIdBytes); -var - LBuffer: TIdBytes; - LPos : integer; - nChars, C : UInt32; - StreamEnd: Boolean; -begin - // let the next Intercept in the chain decode its data first - inherited Receive(VBuffer); - - SetLength(LBuffer, 2048); - if FCompressionLevel in [1..9] then - begin - InitCompressors; - StreamEnd := False; - LPos := 0; - repeat - nChars := IndyMin(Length(VBuffer) - LPos, Length(LBuffer)); - if nChars = 0 then begin - Break; - end; - CopyTIdBytes(VBuffer, LPos, LBuffer, 0, nChars); - Inc(LPos, nChars); - FDecompressRec.next_in := @LBuffer[0]; - FDecompressRec.avail_in := nChars; - FDecompressRec.total_in := 0; - while FDecompressRec.avail_in > 0 do - begin - if FRecvCount = FRecvSize then begin - if FRecvSize = 0 then begin - FRecvSize := 2048; - end else begin - Inc(FRecvSize, 1024); - end; - SetLength(FRecvBuf, FRecvSize); - end; - FDecompressRec.next_out := @FRecvBuf[FRecvCount]; - C := FRecvSize - FRecvCount; - FDecompressRec.avail_out := C; - FDecompressRec.total_out := 0; - case inflate(FDecompressRec, Z_NO_FLUSH) of - Z_STREAM_END: - StreamEnd := True; - Z_STREAM_ERROR, - Z_DATA_ERROR, - Z_MEM_ERROR: - raise EIdDecompressionError.Create(RSZLDecompressionError); - end; - Inc(FRecvCount, C - FDecompressRec.avail_out); - end; - until StreamEnd; - SetLength(VBuffer, FRecvCount); - CopyTIdBytes(FRecvBuf, 0, VBuffer, 0, FRecvCount); - FRecvCount := 0; - end; -end; - -procedure TIdCompressionIntercept.Send(var VBuffer: TIdBytes); -var - LBuffer: TIdBytes; - LLen, LSize: UInt32; -begin - LBuffer := nil; - if FCompressionLevel in [1..9] then - begin - InitCompressors; - // Make sure the Send buffer is large enough to hold the input data - LSize := Length(VBuffer); - if LSize > FSendSize then - begin - if LSize > 2048 then begin - FSendSize := LSize + (LSize + 1023) mod 1024; - end else begin - FSendSize := 2048; - end; - SetLength(FSendBuf, FSendSize); - end; - - // Get the data from the input and save it off - // TODO: get rid of FSendBuf and use ABuffer directly - FSendCount := LSize; - CopyTIdBytes(VBuffer, 0, FSendBuf, 0, FSendCount); - FCompressRec.next_in := @FSendBuf[0]; - FCompressRec.avail_in := FSendCount; - FCompressRec.avail_out := 0; - - // clear the output stream in preparation for compression - SetLength(VBuffer, 0); - SetLength(LBuffer, 1024); - - // As long as data is being outputted, keep compressing - while FCompressRec.avail_out = 0 do - begin - FCompressRec.next_out := @LBuffer[0]; - FCompressRec.avail_out := Length(LBuffer); - case deflate(FCompressRec, Z_SYNC_FLUSH) of - Z_STREAM_ERROR, - Z_DATA_ERROR, - Z_MEM_ERROR: raise EIdCompressionError.Create(RSZLCompressionError); - end; - // Place the compressed data into the output stream - LLen := Length(VBuffer); - SetLength(VBuffer, LLen + UInt32(Length(LBuffer)) - FCompressRec.avail_out); - CopyTIdBytes(LBuffer, 0, VBuffer, LLen, UInt32(Length(LBuffer)) - FCompressRec.avail_out); - end; - end; - - // let the next Intercept in the chain encode its data next - inherited Send(VBuffer); -end; - -procedure TIdCompressionIntercept.SetCompressionLevel(Value: TIdCompressionLevel); -begin - if Value < 0 then begin - Value := 0; - end else if Value > 9 then begin - Value := 9; - end; - if Value <> FCompressionLevel then begin - DeinitCompressors; - FCompressionLevel := Value; - end; -end; - -{ TIdServerCompressionIntercept } - -procedure TIdServerCompressionIntercept.Init; -begin -end; - -function TIdServerCompressionIntercept.Accept(AConnection: TComponent): TIdConnectionIntercept; -begin - Result := TIdCompressionIntercept.Create(nil); - TIdCompressionIntercept(Result).CompressionLevel := CompressionLevel; -end; - -end. - +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. + + + $Log$ + + + Rev 1.10 2/22/2004 12:04:00 AM JPMugaas + Updated for file rename. + + + Rev 1.9 2/12/2004 11:28:04 PM JPMugaas + Modified compression intercept to use the ZLibEx unit. + + + Rev 1.8 2004.02.09 9:56:00 PM czhower + Fixed for lib changes. + + + Rev 1.7 5/12/2003 12:31:00 AM GGrieve + Get compiling again with DotNet Changes + + + Rev 1.6 10/12/2003 1:49:26 PM BGooijen + Changed comment of last checkin + + + Rev 1.5 10/12/2003 1:43:24 PM BGooijen + Changed IdCompilerDefines.inc to Core\IdCompilerDefines.inc + + + Rev 1.3 6/27/2003 2:38:04 PM BGooijen + Fixed bug where last part was not compressed/send + + + Rev 1.2 4/10/2003 4:12:42 PM BGooijen + Added TIdServerCompressionIntercept + + + Rev 1.1 4/3/2003 2:55:48 PM BGooijen + Now calls DeinitCompressors on disconnect + + + Rev 1.0 11/14/2002 02:15:50 PM JPMugaas +} +unit IdCompressionIntercept; + +{ This file implements an Indy intercept component that compresses a data + stream using the open-source zlib compression library. In order for this + file to compile on Windows, the follow .obj files *must* be provided as + delivered with this file: + + deflate.obj + inflate.obj + inftrees.obj + trees.obj + adler32.obj + infblock.obj + infcodes.obj + infutil.obj + inffast.obj + + On Linux, the shared-object file libz.so.1 *must* be available on the + system. Most modern Linux distributions include this file. + + Simply set the CompressionLevel property to a value between 1 and 9 to + enable compressing of the data stream. A setting of 0(zero) disables + compression and the component is dormant. The sender *and* received must + have compression enabled in order to properly decompress the data stream. + They do *not* have to use the same CompressionLevel as long as they are + both set to a value between 1 and 9. + + Original Author: Allen Bauer + + This source file is submitted to the Indy project on behalf of Borland + Sofware Corporation. No warranties, express or implied are given with + this source file. +} +interface + +{$I IdCompilerDefines.inc} + +uses + Classes, + {$IFDEF HAS_UNIT_System_ZLib} + {$IFDEF USE_INLINE} + System.ZLib, // here to facilitate inlining + {$ENDIF} + {$ENDIF} + IdException, + IdGlobal, + IdGlobalProtocols, + IdIntercept, + IdZLibHeaders; + +type + EIdCompressionException = class(EIdException); + EIdCompressorInitFailure = class(EIdCompressionException); + EIdDecompressorInitFailure = class(EIdCompressionException); + EIdCompressionError = class(EIdCompressionException); + EIdDecompressionError = class(EIdCompressionException); + + TIdCompressionLevel = 0..9; + + TIdCompressionIntercept = class(TIdConnectionIntercept) + protected + FCompressionLevel: TIdCompressionLevel; + FCompressRec: TZStreamRec; + FDecompressRec: TZStreamRec; + FRecvBuf: TIdBytes; + FRecvCount, FRecvSize: UInt32; + FSendBuf: TIdBytes; + FSendCount, FSendSize: UInt32; + procedure SetCompressionLevel(Value: TIdCompressionLevel); + procedure InitCompressors; + procedure DeinitCompressors; + public + destructor Destroy; override; + procedure Disconnect; override; + procedure Receive(var VBuffer: TIdBytes); override; + procedure Send(var VBuffer: TIdBytes); override; + published + property CompressionLevel: TIdCompressionLevel read FCompressionLevel write SetCompressionLevel; + end; + + TIdServerCompressionIntercept = class(TIdServerIntercept) + protected + FCompressionLevel: TIdCompressionLevel; + public + procedure Init; override; + function Accept(AConnection: TComponent): TIdConnectionIntercept; override; + published + property CompressionLevel: TIdCompressionLevel read FCompressionLevel write FCompressionLevel; + end; + + +implementation + +uses + IdResourceStringsProtocols, IdExceptionCore; + +{ TIdCompressionIntercept } + +procedure TIdCompressionIntercept.DeinitCompressors; +begin + if Assigned(FCompressRec.zalloc) then begin + deflateEnd(FCompressRec); + FillChar(FCompressRec, SizeOf(FCompressRec), 0); + end; + if Assigned(FDecompressRec.zalloc) then + begin + inflateEnd(FDecompressRec); + FillChar(FDecompressRec, SizeOf(FDecompressRec), 0); + end; +end; + +destructor TIdCompressionIntercept.Destroy; +begin + DeinitCompressors; + SetLength(FRecvBuf, 0); + SetLength(FSendBuf, 0); + inherited Destroy; +end; + +procedure TIdCompressionIntercept.Disconnect; +begin + inherited Disconnect; + DeinitCompressors; +end; + +procedure TIdCompressionIntercept.InitCompressors; +begin + if not Assigned(FCompressRec.zalloc) then + begin + FCompressRec.zalloc := IdZLibHeaders.zlibAllocMem; + FCompressRec.zfree := IdZLibHeaders.zlibFreeMem; + if deflateInit_(FCompressRec, FCompressionLevel, zlib_Version, SizeOf(FCompressRec)) <> Z_OK then + begin + raise EIdCompressorInitFailure.Create(RSZLCompressorInitializeFailure); + end; + end; + if not Assigned(FDecompressRec.zalloc) then + begin + FDecompressRec.zalloc := IdZLibHeaders.zlibAllocMem; + FDecompressRec.zfree := IdZLibHeaders.zlibFreeMem; + if inflateInit_(FDecompressRec, zlib_Version, SizeOf(FDecompressRec)) <> Z_OK then + begin + raise EIdDecompressorInitFailure.Create(RSZLDecompressorInitializeFailure); + end; + end; +end; + +procedure TIdCompressionIntercept.Receive(var VBuffer: TIdBytes); +var + LBuffer: TIdBytes; + LPos : integer; + nChars, C : UInt32; + StreamEnd: Boolean; +begin + // let the next Intercept in the chain decode its data first + inherited Receive(VBuffer); + + SetLength(LBuffer, 2048); + if FCompressionLevel in [1..9] then + begin + InitCompressors; + StreamEnd := False; + LPos := 0; + repeat + nChars := IndyMin(Length(VBuffer) - LPos, Length(LBuffer)); + if nChars = 0 then begin + Break; + end; + CopyTIdBytes(VBuffer, LPos, LBuffer, 0, nChars); + Inc(LPos, nChars); + FDecompressRec.next_in := @LBuffer[0]; + FDecompressRec.avail_in := nChars; + FDecompressRec.total_in := 0; + while FDecompressRec.avail_in > 0 do + begin + if FRecvCount = FRecvSize then begin + if FRecvSize = 0 then begin + FRecvSize := 2048; + end else begin + Inc(FRecvSize, 1024); + end; + SetLength(FRecvBuf, FRecvSize); + end; + FDecompressRec.next_out := @FRecvBuf[FRecvCount]; + C := FRecvSize - FRecvCount; + FDecompressRec.avail_out := C; + FDecompressRec.total_out := 0; + case inflate(FDecompressRec, Z_NO_FLUSH) of + Z_STREAM_END: + StreamEnd := True; + Z_STREAM_ERROR, + Z_DATA_ERROR, + Z_MEM_ERROR: + raise EIdDecompressionError.Create(RSZLDecompressionError); + end; + Inc(FRecvCount, C - FDecompressRec.avail_out); + end; + until StreamEnd; + SetLength(VBuffer, FRecvCount); + CopyTIdBytes(FRecvBuf, 0, VBuffer, 0, FRecvCount); + FRecvCount := 0; + end; +end; + +procedure TIdCompressionIntercept.Send(var VBuffer: TIdBytes); +var + LBuffer: TIdBytes; + LLen, LSize: UInt32; +begin + LBuffer := nil; + if FCompressionLevel in [1..9] then + begin + InitCompressors; + // Make sure the Send buffer is large enough to hold the input data + LSize := Length(VBuffer); + if LSize > FSendSize then + begin + if LSize > 2048 then begin + FSendSize := LSize + (LSize + 1023) mod 1024; + end else begin + FSendSize := 2048; + end; + SetLength(FSendBuf, FSendSize); + end; + + // Get the data from the input and save it off + // TODO: get rid of FSendBuf and use ABuffer directly + FSendCount := LSize; + CopyTIdBytes(VBuffer, 0, FSendBuf, 0, FSendCount); + FCompressRec.next_in := @FSendBuf[0]; + FCompressRec.avail_in := FSendCount; + FCompressRec.avail_out := 0; + + // clear the output stream in preparation for compression + SetLength(VBuffer, 0); + SetLength(LBuffer, 1024); + + // As long as data is being outputted, keep compressing + while FCompressRec.avail_out = 0 do + begin + FCompressRec.next_out := @LBuffer[0]; + FCompressRec.avail_out := Length(LBuffer); + case deflate(FCompressRec, Z_SYNC_FLUSH) of + Z_STREAM_ERROR, + Z_DATA_ERROR, + Z_MEM_ERROR: raise EIdCompressionError.Create(RSZLCompressionError); + end; + // Place the compressed data into the output stream + LLen := Length(VBuffer); + SetLength(VBuffer, LLen + UInt32(Length(LBuffer)) - FCompressRec.avail_out); + CopyTIdBytes(LBuffer, 0, VBuffer, LLen, UInt32(Length(LBuffer)) - FCompressRec.avail_out); + end; + end; + + // let the next Intercept in the chain encode its data next + inherited Send(VBuffer); +end; + +procedure TIdCompressionIntercept.SetCompressionLevel(Value: TIdCompressionLevel); +begin + if Value < 0 then begin + Value := 0; + end else if Value > 9 then begin + Value := 9; + end; + if Value <> FCompressionLevel then begin + DeinitCompressors; + FCompressionLevel := Value; + end; +end; + +{ TIdServerCompressionIntercept } + +procedure TIdServerCompressionIntercept.Init; +begin +end; + +function TIdServerCompressionIntercept.Accept(AConnection: TComponent): TIdConnectionIntercept; +begin + Result := TIdCompressionIntercept.Create(nil); + TIdCompressionIntercept(Result).CompressionLevel := CompressionLevel; +end; + +end. + diff --git a/Lib/Protocols/IdCompressorZLib.pas b/Lib/Protocols/IdCompressorZLib.pas index 7c77a8483..f3ddd264d 100644 --- a/Lib/Protocols/IdCompressorZLib.pas +++ b/Lib/Protocols/IdCompressorZLib.pas @@ -1,346 +1,346 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.9 3/5/2005 3:33:54 PM JPMugaas - Fix for some compiler warnings having to do with TStream.Read being platform - specific. This was fixed by changing the Compressor API to use TIdStreamVCL - instead of TStream. I also made appropriate adjustments to other units for - this. - - Rev 1.8 10/24/2004 2:40:28 PM JPMugaas - Made a better fix for the problem with SmartFTP. It turns out that we may - not be able to avoid a Z_BUF_ERROR in some cases. - - Rev 1.7 10/24/2004 11:17:08 AM JPMugaas - Reimplemented ZLIB Decompression in FTP better. It now should work properly - at ftp://ftp.smartftp.com. - - Rev 1.6 9/16/2004 3:24:04 AM JPMugaas - TIdFTP now compresses to the IOHandler and decompresses from the IOHandler. - - Noted some that the ZLib code is based was taken from ZLibEx. - - Rev 1.4 9/11/2004 10:58:04 AM JPMugaas - FTP now decompresses output directly to the IOHandler. - - Rev 1.3 6/21/2004 12:10:52 PM JPMugaas - Attempt to expand the ZLib support for Int64 support. - - Rev 1.2 2/21/2004 3:32:58 PM JPMugaas - Foxed for Unit rename. - - Rev 1.1 2/14/2004 9:59:50 PM JPMugaas - Reworked the API. There is now a separate API for the Inflate_ and - InflateInit2_ functions as well as separate functions for DeflateInit_ and - DeflateInit2_. This was required for FTP. The API also includes an optional - output stream for the servers. - - Rev 1.0 2/12/2004 11:27:22 PM JPMugaas - New compressor based on ZLibEx. -} - -unit IdCompressorZLib; - -interface -{$i IdCompilerDefines.inc} - -uses - Classes, - {$IFDEF HAS_UNIT_System_ZLib} - {$IFDEF USE_INLINE} - System.ZLib, // here to facilitate inlining - {$ENDIF} - {$ENDIF} - IdException, - IdIOHandler, - IdZLibCompressorBase, - IdZLibHeaders; - -type - TIdCompressorZLib = class(TIdZLibCompressorBase) - protected - function GetIsReady : Boolean; override; - procedure InternalDecompressStream(var LZstream: TZStreamRec; AIOHandler : TIdIOHandler; - AOutStream: TStream); - public - - procedure DeflateStream(AInStream, AOutStream : TStream; - const ALevel : TIdCompressionLevel=0); override; - procedure InflateStream(AInStream, AOutStream : TStream); override; - - procedure CompressStream(AInStream, AOutStream : TStream; const ALevel : TIdCompressionLevel; const AWindowBits, AMemLevel, - AStrategy: Integer); override; - procedure DecompressStream(AInStream, AOutStream : TStream; const AWindowBits : Integer); override; - procedure CompressFTPToIO(AInStream : TStream; AIOHandler : TIdIOHandler; - const ALevel, AWindowBits, AMemLevel, AStrategy: Integer); override; - procedure DecompressFTPFromIO(AIOHandler : TIdIOHandler; AOutputStream : TStream; - const AWindowBits : Integer); override; - end; - - EIdCompressionException = class(EIdException); - EIdCompressorInitFailure = class(EIdCompressionException); - EIdDecompressorInitFailure = class(EIdCompressionException); - EIdCompressionError = class(EIdCompressionException); - EIdDecompressionError = class(EIdCompressionException); - -implementation - -uses - IdAntiFreezeBase, IdComponent, IdResourceStringsProtocols, IdGlobal, - IdGlobalProtocols, IdZLib, SysUtils; - -const - bufferSize = 32768; - -{ TIdCompressorZLib } - -procedure TIdCompressorZLib.InternalDecompressStream( - var LZstream: TZStreamRec; AIOHandler: TIdIOHandler; AOutStream: TStream); -{Note that much of this is taken from the ZLibEx unit and adapted to use the IOHandler} -var - zresult : Integer; - outBuffer: Array [0..bufferSize-1] of TIdAnsiChar; - inSize : Integer; - outSize : Integer; - LBuf : TIdBytes; - - function RawReadFromIOHandler(ABuffer : TIdBytes; AOIHandler : TIdIOHandler; AMax : Integer) : Integer; - begin - //We don't use the IOHandler.ReadBytes because that will check - // for disconnect and raise an exception that we don't want. - - // RLebeau 3/26/09: we need to raise exceptions here! The socket component - // that is performing the IO needs to know what is happening on the socket... - - { - repeat - AIOHandler.CheckForDataOnSource(1); - Result := IndyMin(AIOHandler.InputBuffer.Size, AMax); - if Result > 0 then begin - AIOHandler.InputBuffer.ExtractToBytes(ABuffer, Result, False); - Break; - end; - until not AIOHandler.Connected; - } - - // TODO: ReadStream() has been re-written to not use ReadBytes() anymore, it - // now reads directly from the InputBuffer into the target TStream via - // IOHandler.ReadFromSource() and IOHandler.InputBuffer.ExtractToStream(), - // so we should do something similar here... - - // copied from TIdIOHandler.ReadStream() and trimmed down... - try - AIOHandler.ReadBytes(ABuffer, AMax, False); - except - on E: Exception do begin - // RLebeau - ReadFromSource() inside of ReadBytes() - // could have filled the InputBuffer with more bytes - // than actually requested, so don't extract too - // many bytes here... - AMax := IndyMin(AMax, AIOHandler.InputBuffer.Size); - AIOHandler.InputBuffer.ExtractToBytes(ABuffer, AMax, False); - if not (E is EIdConnClosedGracefully) then begin - raise; - end; - end; - end; - TIdAntiFreezeBase.DoProcess; - Result := AMax; - end; - -begin - SetLength(LBuf, bufferSize); - repeat - inSize := RawReadFromIOHandler(LBuf, AIOHandler, bufferSize); - if inSize < 1 then begin - Break; - end; - - LZstream.next_in := @LBuf[0]; - LZstream.avail_in := inSize; - - repeat - LZstream.next_out := @outBuffer[0]; - LZstream.avail_out := bufferSize; - zresult := inflate(LZstream, Z_NO_FLUSH); - if zresult <> Z_BUF_ERROR then - begin - DCheck(zresult); - end; - outSize := bufferSize - LZstream.avail_out; - AOutStream.Write(outBuffer, outSize); - until (LZstream.avail_in = 0) and (LZstream.avail_out > 0); - until False; - { From the ZLIB FAQ at http://www.gzip.org/zlib/FAQ.txt - - 5. deflate() or inflate() returns Z_BUF_ERROR - - Before making the call, make sure that avail_in and avail_out are not - zero. When setting the parameter flush equal to Z_FINISH, also make sure - that avail_out is big enough to allow processing all pending input. - Note that a Z_BUF_ERROR is not fatal--another call to deflate() or - inflate() can be made with more input or output space. A Z_BUF_ERROR - may in fact be unavoidable depending on how the functions are used, since - it is not possible to tell whether or not there is more output pending - when strm.avail_out returns with zero. -} - repeat - LZstream.next_out := @outBuffer[0]; - LZstream.avail_out := bufferSize; - - zresult := inflate(LZstream, Z_FINISH); - if zresult <> Z_BUF_ERROR then - begin - zresult := DCheck(zresult); - end; - outSize := bufferSize - LZstream.avail_out; - AOutStream.Write(outBuffer, outSize); - - until ((zresult = Z_STREAM_END) and (LZstream.avail_out > 0)) or (zresult = Z_BUF_ERROR); - - DCheck(inflateEnd(LZstream)); -end; - -procedure TIdCompressorZLib.DecompressFTPFromIO(AIOHandler : TIdIOHandler; AOutputStream : TStream; - const AWindowBits : Integer); -{Note that much of this is taken from the ZLibEx unit and adapted to use the IOHandler} -var - Lzstream: TZStreamRec; - LWinBits : Integer; -begin - AIOHandler.BeginWork(wmRead); - try - FillChar(Lzstream,SizeOf(TZStreamRec),0); - { - This is a workaround for some clients and servers that do not send decompression - headers. The reason is that there's an inconsistancy in Internet Drafts for ZLIB - compression. One says to include the headers while an older one says do not - include the headers. - - If you add 32 to the Window Bits parameter, - } - LWinBits := AWindowBits; - if LWinBits > 0 then - begin - LWinBits := Abs( LWinBits) + 32; - end; - LZstream.zalloc := zlibAllocMem; - LZstream.zfree := zlibFreeMem; - DCheck(inflateInit2_(Lzstream,LWinBits,ZLIB_VERSION,SizeOf(TZStreamRec))); - - InternalDecompressStream(Lzstream,AIOHandler,AOutputStream); - finally - AIOHandler.EndWork(wmRead); - end; -end; - -procedure TIdCompressorZLib.CompressFTPToIO(AInStream : TStream; - AIOHandler : TIdIOHandler; - const ALevel, AWindowBits, AMemLevel, AStrategy: Integer); -{Note that much of this is taken from the ZLibEx unit and adapted to use the IOHandler} -var - LCompressRec : TZStreamRec; - - zresult : Integer; - inBuffer : Array [0..bufferSize-1] of TIdAnsiChar; - outBuffer: Array [0..bufferSize-1] of TIdAnsiChar; - inSize : Integer; - outSize : Integer; -begin - AIOHandler.BeginWork(wmWrite, AInStream.Size); - try - FillChar(LCompressRec, SizeOf(TZStreamRec), 0); - CCheck( deflateInit2_(LCompressRec, ALevel, Z_DEFLATED, AWindowBits, AMemLevel, - AStrategy, ZLIB_VERSION, SizeOf(LCompressRec))); - - inSize := AInStream.Read(inBuffer, bufferSize); - - while inSize > 0 do - begin - LCompressRec.next_in := @inBuffer[0]; - LCompressRec.avail_in := inSize; - - repeat - LCompressRec.next_out := @outBuffer[0]; - LCompressRec.avail_out := bufferSize; - - CCheck(deflate(LCompressRec,Z_NO_FLUSH)); - - // outSize := zstream.next_out - outBuffer; - outSize := bufferSize - LCompressRec.avail_out; - if outsize <> 0 then - begin - AIOHandler.Write(RawToBytes(outBuffer, outSize)); - end; - until (LCompressRec.avail_in = 0) and (LCompressRec.avail_out > 0); - - inSize := AInStream.Read(inBuffer, bufferSize); - end; - - repeat - LCompressRec.next_out := @outBuffer[0]; - LCompressRec.avail_out := bufferSize; - - zresult := CCheck(deflate(LCompressRec,Z_FINISH)); - - // outSize := zstream.next_out - outBuffer; - outSize := bufferSize - LCompressRec.avail_out; - - // outStream.Write(outBuffer,outSize); - if outSize <> 0 then - begin - AIOHandler.Write(RawToBytes(outBuffer, outSize)); - end; - until (zresult = Z_STREAM_END) and (LCompressRec.avail_out > 0); - - CCheck(deflateEnd(LCompressRec)); - - finally - AIOHandler.EndWork(wmWrite); - end; -end; - -procedure TIdCompressorZLib.CompressStream(AInStream,AOutStream : TStream; - const ALevel : TIdCompressionLevel; - const AWindowBits, AMemLevel, AStrategy: Integer); - -begin - IdZLib.IndyCompressStream(AInStream,AOutStream,ALevel,AWindowBits,AMemLevel,AStrategy); -end; - -procedure TIdCompressorZLib.DecompressStream(AInStream, AOutStream : TStream; const AWindowBits : Integer); -begin - IdZLib.IndyDeCompressStream(AInStream,AOutStream, AWindowBits); -end; - -procedure TIdCompressorZLib.DeflateStream(AInStream, AOutStream : TStream; const ALevel : TIdCompressionLevel=0); -begin - IdZLib.IndyCompressStream(AInStream,AOutStream,ALevel); -end; - -function TIdCompressorZLib.GetIsReady: Boolean; -begin - Result := IdZLibHeaders.Load; -end; - -procedure TIdCompressorZLib.InflateStream(AInStream, AOutStream : TStream); -begin - IdZlib.DeCompressStream(AInStream,AOutStream); -end; - -end. +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.9 3/5/2005 3:33:54 PM JPMugaas + Fix for some compiler warnings having to do with TStream.Read being platform + specific. This was fixed by changing the Compressor API to use TIdStreamVCL + instead of TStream. I also made appropriate adjustments to other units for + this. + + Rev 1.8 10/24/2004 2:40:28 PM JPMugaas + Made a better fix for the problem with SmartFTP. It turns out that we may + not be able to avoid a Z_BUF_ERROR in some cases. + + Rev 1.7 10/24/2004 11:17:08 AM JPMugaas + Reimplemented ZLIB Decompression in FTP better. It now should work properly + at ftp://ftp.smartftp.com. + + Rev 1.6 9/16/2004 3:24:04 AM JPMugaas + TIdFTP now compresses to the IOHandler and decompresses from the IOHandler. + + Noted some that the ZLib code is based was taken from ZLibEx. + + Rev 1.4 9/11/2004 10:58:04 AM JPMugaas + FTP now decompresses output directly to the IOHandler. + + Rev 1.3 6/21/2004 12:10:52 PM JPMugaas + Attempt to expand the ZLib support for Int64 support. + + Rev 1.2 2/21/2004 3:32:58 PM JPMugaas + Foxed for Unit rename. + + Rev 1.1 2/14/2004 9:59:50 PM JPMugaas + Reworked the API. There is now a separate API for the Inflate_ and + InflateInit2_ functions as well as separate functions for DeflateInit_ and + DeflateInit2_. This was required for FTP. The API also includes an optional + output stream for the servers. + + Rev 1.0 2/12/2004 11:27:22 PM JPMugaas + New compressor based on ZLibEx. +} + +unit IdCompressorZLib; + +interface +{$i IdCompilerDefines.inc} + +uses + Classes, + {$IFDEF HAS_UNIT_System_ZLib} + {$IFDEF USE_INLINE} + System.ZLib, // here to facilitate inlining + {$ENDIF} + {$ENDIF} + IdException, + IdIOHandler, + IdZLibCompressorBase, + IdZLibHeaders; + +type + TIdCompressorZLib = class(TIdZLibCompressorBase) + protected + function GetIsReady : Boolean; override; + procedure InternalDecompressStream(var LZstream: TZStreamRec; AIOHandler : TIdIOHandler; + AOutStream: TStream); + public + + procedure DeflateStream(AInStream, AOutStream : TStream; + const ALevel : TIdCompressionLevel=0); override; + procedure InflateStream(AInStream, AOutStream : TStream); override; + + procedure CompressStream(AInStream, AOutStream : TStream; const ALevel : TIdCompressionLevel; const AWindowBits, AMemLevel, + AStrategy: Integer); override; + procedure DecompressStream(AInStream, AOutStream : TStream; const AWindowBits : Integer); override; + procedure CompressFTPToIO(AInStream : TStream; AIOHandler : TIdIOHandler; + const ALevel, AWindowBits, AMemLevel, AStrategy: Integer); override; + procedure DecompressFTPFromIO(AIOHandler : TIdIOHandler; AOutputStream : TStream; + const AWindowBits : Integer); override; + end; + + EIdCompressionException = class(EIdException); + EIdCompressorInitFailure = class(EIdCompressionException); + EIdDecompressorInitFailure = class(EIdCompressionException); + EIdCompressionError = class(EIdCompressionException); + EIdDecompressionError = class(EIdCompressionException); + +implementation + +uses + IdAntiFreezeBase, IdComponent, IdResourceStringsProtocols, IdGlobal, + IdGlobalProtocols, IdZLib, SysUtils; + +const + bufferSize = 32768; + +{ TIdCompressorZLib } + +procedure TIdCompressorZLib.InternalDecompressStream( + var LZstream: TZStreamRec; AIOHandler: TIdIOHandler; AOutStream: TStream); +{Note that much of this is taken from the ZLibEx unit and adapted to use the IOHandler} +var + zresult : Integer; + outBuffer: Array [0..bufferSize-1] of TIdAnsiChar; + inSize : Integer; + outSize : Integer; + LBuf : TIdBytes; + + function RawReadFromIOHandler(ABuffer : TIdBytes; AOIHandler : TIdIOHandler; AMax : Integer) : Integer; + begin + //We don't use the IOHandler.ReadBytes because that will check + // for disconnect and raise an exception that we don't want. + + // RLebeau 3/26/09: we need to raise exceptions here! The socket component + // that is performing the IO needs to know what is happening on the socket... + + { + repeat + AIOHandler.CheckForDataOnSource(1); + Result := IndyMin(AIOHandler.InputBuffer.Size, AMax); + if Result > 0 then begin + AIOHandler.InputBuffer.ExtractToBytes(ABuffer, Result, False); + Break; + end; + until not AIOHandler.Connected; + } + + // TODO: ReadStream() has been re-written to not use ReadBytes() anymore, it + // now reads directly from the InputBuffer into the target TStream via + // IOHandler.ReadFromSource() and IOHandler.InputBuffer.ExtractToStream(), + // so we should do something similar here... + + // copied from TIdIOHandler.ReadStream() and trimmed down... + try + AIOHandler.ReadBytes(ABuffer, AMax, False); + except + on E: Exception do begin + // RLebeau - ReadFromSource() inside of ReadBytes() + // could have filled the InputBuffer with more bytes + // than actually requested, so don't extract too + // many bytes here... + AMax := IndyMin(AMax, AIOHandler.InputBuffer.Size); + AIOHandler.InputBuffer.ExtractToBytes(ABuffer, AMax, False); + if not (E is EIdConnClosedGracefully) then begin + raise; + end; + end; + end; + TIdAntiFreezeBase.DoProcess; + Result := AMax; + end; + +begin + SetLength(LBuf, bufferSize); + repeat + inSize := RawReadFromIOHandler(LBuf, AIOHandler, bufferSize); + if inSize < 1 then begin + Break; + end; + + LZstream.next_in := @LBuf[0]; + LZstream.avail_in := inSize; + + repeat + LZstream.next_out := @outBuffer[0]; + LZstream.avail_out := bufferSize; + zresult := inflate(LZstream, Z_NO_FLUSH); + if zresult <> Z_BUF_ERROR then + begin + DCheck(zresult); + end; + outSize := bufferSize - LZstream.avail_out; + AOutStream.Write(outBuffer, outSize); + until (LZstream.avail_in = 0) and (LZstream.avail_out > 0); + until False; + { From the ZLIB FAQ at http://www.gzip.org/zlib/FAQ.txt + + 5. deflate() or inflate() returns Z_BUF_ERROR + + Before making the call, make sure that avail_in and avail_out are not + zero. When setting the parameter flush equal to Z_FINISH, also make sure + that avail_out is big enough to allow processing all pending input. + Note that a Z_BUF_ERROR is not fatal--another call to deflate() or + inflate() can be made with more input or output space. A Z_BUF_ERROR + may in fact be unavoidable depending on how the functions are used, since + it is not possible to tell whether or not there is more output pending + when strm.avail_out returns with zero. +} + repeat + LZstream.next_out := @outBuffer[0]; + LZstream.avail_out := bufferSize; + + zresult := inflate(LZstream, Z_FINISH); + if zresult <> Z_BUF_ERROR then + begin + zresult := DCheck(zresult); + end; + outSize := bufferSize - LZstream.avail_out; + AOutStream.Write(outBuffer, outSize); + + until ((zresult = Z_STREAM_END) and (LZstream.avail_out > 0)) or (zresult = Z_BUF_ERROR); + + DCheck(inflateEnd(LZstream)); +end; + +procedure TIdCompressorZLib.DecompressFTPFromIO(AIOHandler : TIdIOHandler; AOutputStream : TStream; + const AWindowBits : Integer); +{Note that much of this is taken from the ZLibEx unit and adapted to use the IOHandler} +var + Lzstream: TZStreamRec; + LWinBits : Integer; +begin + AIOHandler.BeginWork(wmRead); + try + FillChar(Lzstream,SizeOf(TZStreamRec),0); + { + This is a workaround for some clients and servers that do not send decompression + headers. The reason is that there's an inconsistancy in Internet Drafts for ZLIB + compression. One says to include the headers while an older one says do not + include the headers. + + If you add 32 to the Window Bits parameter, + } + LWinBits := AWindowBits; + if LWinBits > 0 then + begin + LWinBits := Abs( LWinBits) + 32; + end; + LZstream.zalloc := zlibAllocMem; + LZstream.zfree := zlibFreeMem; + DCheck(inflateInit2_(Lzstream,LWinBits,ZLIB_VERSION,SizeOf(TZStreamRec))); + + InternalDecompressStream(Lzstream,AIOHandler,AOutputStream); + finally + AIOHandler.EndWork(wmRead); + end; +end; + +procedure TIdCompressorZLib.CompressFTPToIO(AInStream : TStream; + AIOHandler : TIdIOHandler; + const ALevel, AWindowBits, AMemLevel, AStrategy: Integer); +{Note that much of this is taken from the ZLibEx unit and adapted to use the IOHandler} +var + LCompressRec : TZStreamRec; + + zresult : Integer; + inBuffer : Array [0..bufferSize-1] of TIdAnsiChar; + outBuffer: Array [0..bufferSize-1] of TIdAnsiChar; + inSize : Integer; + outSize : Integer; +begin + AIOHandler.BeginWork(wmWrite, AInStream.Size); + try + FillChar(LCompressRec, SizeOf(TZStreamRec), 0); + CCheck( deflateInit2_(LCompressRec, ALevel, Z_DEFLATED, AWindowBits, AMemLevel, + AStrategy, ZLIB_VERSION, SizeOf(LCompressRec))); + + inSize := AInStream.Read(inBuffer, bufferSize); + + while inSize > 0 do + begin + LCompressRec.next_in := @inBuffer[0]; + LCompressRec.avail_in := inSize; + + repeat + LCompressRec.next_out := @outBuffer[0]; + LCompressRec.avail_out := bufferSize; + + CCheck(deflate(LCompressRec,Z_NO_FLUSH)); + + // outSize := zstream.next_out - outBuffer; + outSize := bufferSize - LCompressRec.avail_out; + if outsize <> 0 then + begin + AIOHandler.Write(RawToBytes(outBuffer, outSize)); + end; + until (LCompressRec.avail_in = 0) and (LCompressRec.avail_out > 0); + + inSize := AInStream.Read(inBuffer, bufferSize); + end; + + repeat + LCompressRec.next_out := @outBuffer[0]; + LCompressRec.avail_out := bufferSize; + + zresult := CCheck(deflate(LCompressRec,Z_FINISH)); + + // outSize := zstream.next_out - outBuffer; + outSize := bufferSize - LCompressRec.avail_out; + + // outStream.Write(outBuffer,outSize); + if outSize <> 0 then + begin + AIOHandler.Write(RawToBytes(outBuffer, outSize)); + end; + until (zresult = Z_STREAM_END) and (LCompressRec.avail_out > 0); + + CCheck(deflateEnd(LCompressRec)); + + finally + AIOHandler.EndWork(wmWrite); + end; +end; + +procedure TIdCompressorZLib.CompressStream(AInStream,AOutStream : TStream; + const ALevel : TIdCompressionLevel; + const AWindowBits, AMemLevel, AStrategy: Integer); + +begin + IdZLib.IndyCompressStream(AInStream,AOutStream,ALevel,AWindowBits,AMemLevel,AStrategy); +end; + +procedure TIdCompressorZLib.DecompressStream(AInStream, AOutStream : TStream; const AWindowBits : Integer); +begin + IdZLib.IndyDeCompressStream(AInStream,AOutStream, AWindowBits); +end; + +procedure TIdCompressorZLib.DeflateStream(AInStream, AOutStream : TStream; const ALevel : TIdCompressionLevel=0); +begin + IdZLib.IndyCompressStream(AInStream,AOutStream,ALevel); +end; + +function TIdCompressorZLib.GetIsReady: Boolean; +begin + Result := IdZLibHeaders.Load; +end; + +procedure TIdCompressorZLib.InflateStream(AInStream, AOutStream : TStream); +begin + IdZlib.DeCompressStream(AInStream,AOutStream); +end; + +end. diff --git a/Lib/Protocols/IdDsnRegister.pas b/Lib/Protocols/IdDsnRegister.pas index b8646c403..ab5c9feea 100644 --- a/Lib/Protocols/IdDsnRegister.pas +++ b/Lib/Protocols/IdDsnRegister.pas @@ -1,198 +1,198 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.7 9/5/2004 3:16:58 PM JPMugaas - Should work in D9 DotNET. - - Rev 1.6 3/8/2004 10:14:54 AM JPMugaas - Property editor for SASL mechanisms now supports TIdDICT. - - Rev 1.5 2/26/2004 8:53:14 AM JPMugaas - Hack to restore the property editor for SASL mechanisms. - - Rev 1.4 1/25/2004 4:28:42 PM JPMugaas - Removed a discontinued Unit. - - Rev 1.3 1/25/2004 3:11:06 PM JPMugaas - SASL Interface reworked to make it easier for developers to use. - SSL and SASL reenabled components. - - Rev 1.2 10/12/2003 1:49:28 PM BGooijen - Changed comment of last checkin - - Rev 1.1 10/12/2003 1:43:28 PM BGooijen - Changed IdCompilerDefines.inc to Core\IdCompilerDefines.inc - - Rev 1.0 11/14/2002 02:18:56 PM JPMugaas -} - -unit IdDsnRegister; - -interface - -{$I IdCompilerDefines.inc} - -uses - Classes, - {$IFDEF DOTNET} - Borland.Vcl.Design.DesignIntF, - Borland.Vcl.Design.DesignEditors - {$ELSE} - {$IFDEF FPC} - PropEdits, - ComponentEditors - {$ELSE} - {$IFDEF VCL_6_OR_ABOVE} - DesignIntf, - DesignEditors - {$ELSE} - Dsgnintf - {$ENDIF} - {$ENDIF} - {$ENDIF} - ; -// Procs - -type - TIdPropEdSASL = class(TClassProperty) - public - procedure Edit; override; - function GetAttributes: TPropertyAttributes; override; - function GetValue: string; override; - procedure SetValue(const Value: string); override; - end; - - {$IFDEF HAS_TSelectionEditor} - TIdFTPServerSelectionEditor = class(TSelectionEditor) - public - procedure RequiresUnits(Proc: TGetStrProc); override; - end; - {$ENDIF} - -procedure Register; - -implementation - -uses - {$IFDEF WIDGET_WINFORMS} - IdDsnSASLListEditorFormNET, - {$R 'IdDsnSASLListEditorFormNET.TfrmSASLListEditor.resources' 'IdDsnSASLListEditorFormNET.resx'} - {$ENDIF} - {$IFDEF WIDGET_VCL_LIKE_OR_KYLIX} - IdDsnSASLListEditorFormVCL, - {$ENDIF} - {$IFDEF HAS_TSelectionEditor} - IdFTPServer, - {$ENDIF} - IdSASL, IdSASLCollection, - SysUtils, TypInfo; - {Since we are removing New Design-Time part, we remove the "New Message Part Editor"} - {IdDsnNewMessagePart, } - -type - {$IFDEF WIDGET_WINFORMS} - //we make a create here because I'm not sure how the Visual Designer for WinForms - //we behave in a package. I know it can act weird if something is renamed - TfrmSASLListEditor = class(IdDsnSASLListEditorFormNET.TfrmSASLListEditor) - public - constructor Create(AOwner : TComponent); - end; - {$ENDIF} - {$IFDEF WIDGET_VCL_LIKE_OR_KYLIX} - TfrmSASLListEditor = class(TfrmSASLListEditorVCL); - {$ENDIF} - -{ TfrmSASLListEditor } - -{$IFDEF WIDGET_WINFORMS} -constructor TfrmSASLListEditor.Create(AOwner : TComponent); -begin - inherited Create; -end; -{$ENDIF} - -{$IFDEF HAS_TSelectionEditor} - -{TIdFTPServerSelectionEditor} - -procedure TIdFTPServerSelectionEditor.RequiresUnits(Proc: TGetStrProc); -begin - inherited RequiresUnits(Proc); - Proc('IdFTPListOutput'); - Proc('IdFTPList'); -end; - -{$ENDIF} - -{ TIdPropEdSASL } - -procedure TIdPropEdSASL.Edit; -var - LF: TfrmSASLListEditor; - LComp: TPersistent; - LList: TIdSASLEntries; -begin - inherited Edit; - - LComp := GetComponent(0); - - //done this way to prevent invalid typecast error. - {$IFDEF HAS_GetObjectProp} - LList := TIdSASLEntries(GetObjectProp(LComp, GetPropInfo, TIdSASLEntries)); - {$ELSE} - LList := TObject(GetOrdProp(LComp, GetPropInfo)) as TIdSASLEntries; - {$ENDIF} - - LF := TfrmSASLListEditor.Create(nil); - try - if LComp is TComponent then begin - LF.SetComponentName(TComponent(LComp).Name); - end; - LF.SetList(LList); - if LF.Execute then begin - LF.GetList(LList); - end; - finally - FreeAndNil(LF); - end; -end; - -function TIdPropEdSASL.GetAttributes: TPropertyAttributes; -begin - Result := inherited GetAttributes + [paDialog]; -end; - -function TIdPropEdSASL.GetValue: string; -begin - Result := GetStrValue; -end; - -procedure TIdPropEdSASL.SetValue(const Value: string); -begin - inherited SetValue(Value); -end; - -procedure Register; -begin - RegisterPropertyEditor(TypeInfo(TIdSASLEntries), nil, '', TIdPropEdSASL); - {$IFDEF HAS_TSelectionEditor} - RegisterSelectionEditor(TIdFTPServer,TIdFTPServerSelectionEditor); - {$ENDIF} -end; - -end. +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.7 9/5/2004 3:16:58 PM JPMugaas + Should work in D9 DotNET. + + Rev 1.6 3/8/2004 10:14:54 AM JPMugaas + Property editor for SASL mechanisms now supports TIdDICT. + + Rev 1.5 2/26/2004 8:53:14 AM JPMugaas + Hack to restore the property editor for SASL mechanisms. + + Rev 1.4 1/25/2004 4:28:42 PM JPMugaas + Removed a discontinued Unit. + + Rev 1.3 1/25/2004 3:11:06 PM JPMugaas + SASL Interface reworked to make it easier for developers to use. + SSL and SASL reenabled components. + + Rev 1.2 10/12/2003 1:49:28 PM BGooijen + Changed comment of last checkin + + Rev 1.1 10/12/2003 1:43:28 PM BGooijen + Changed IdCompilerDefines.inc to Core\IdCompilerDefines.inc + + Rev 1.0 11/14/2002 02:18:56 PM JPMugaas +} + +unit IdDsnRegister; + +interface + +{$I IdCompilerDefines.inc} + +uses + Classes, + {$IFDEF DOTNET} + Borland.Vcl.Design.DesignIntF, + Borland.Vcl.Design.DesignEditors + {$ELSE} + {$IFDEF FPC} + PropEdits, + ComponentEditors + {$ELSE} + {$IFDEF VCL_6_OR_ABOVE} + DesignIntf, + DesignEditors + {$ELSE} + Dsgnintf + {$ENDIF} + {$ENDIF} + {$ENDIF} + ; +// Procs + +type + TIdPropEdSASL = class(TClassProperty) + public + procedure Edit; override; + function GetAttributes: TPropertyAttributes; override; + function GetValue: string; override; + procedure SetValue(const Value: string); override; + end; + + {$IFDEF HAS_TSelectionEditor} + TIdFTPServerSelectionEditor = class(TSelectionEditor) + public + procedure RequiresUnits(Proc: TGetStrProc); override; + end; + {$ENDIF} + +procedure Register; + +implementation + +uses + {$IFDEF WIDGET_WINFORMS} + IdDsnSASLListEditorFormNET, + {$R 'IdDsnSASLListEditorFormNET.TfrmSASLListEditor.resources' 'IdDsnSASLListEditorFormNET.resx'} + {$ENDIF} + {$IFDEF WIDGET_VCL_LIKE_OR_KYLIX} + IdDsnSASLListEditorFormVCL, + {$ENDIF} + {$IFDEF HAS_TSelectionEditor} + IdFTPServer, + {$ENDIF} + IdSASL, IdSASLCollection, + SysUtils, TypInfo; + {Since we are removing New Design-Time part, we remove the "New Message Part Editor"} + {IdDsnNewMessagePart, } + +type + {$IFDEF WIDGET_WINFORMS} + //we make a create here because I'm not sure how the Visual Designer for WinForms + //we behave in a package. I know it can act weird if something is renamed + TfrmSASLListEditor = class(IdDsnSASLListEditorFormNET.TfrmSASLListEditor) + public + constructor Create(AOwner : TComponent); + end; + {$ENDIF} + {$IFDEF WIDGET_VCL_LIKE_OR_KYLIX} + TfrmSASLListEditor = class(TfrmSASLListEditorVCL); + {$ENDIF} + +{ TfrmSASLListEditor } + +{$IFDEF WIDGET_WINFORMS} +constructor TfrmSASLListEditor.Create(AOwner : TComponent); +begin + inherited Create; +end; +{$ENDIF} + +{$IFDEF HAS_TSelectionEditor} + +{TIdFTPServerSelectionEditor} + +procedure TIdFTPServerSelectionEditor.RequiresUnits(Proc: TGetStrProc); +begin + inherited RequiresUnits(Proc); + Proc('IdFTPListOutput'); + Proc('IdFTPList'); +end; + +{$ENDIF} + +{ TIdPropEdSASL } + +procedure TIdPropEdSASL.Edit; +var + LF: TfrmSASLListEditor; + LComp: TPersistent; + LList: TIdSASLEntries; +begin + inherited Edit; + + LComp := GetComponent(0); + + //done this way to prevent invalid typecast error. + {$IFDEF HAS_GetObjectProp} + LList := TIdSASLEntries(GetObjectProp(LComp, GetPropInfo, TIdSASLEntries)); + {$ELSE} + LList := TObject(GetOrdProp(LComp, GetPropInfo)) as TIdSASLEntries; + {$ENDIF} + + LF := TfrmSASLListEditor.Create(nil); + try + if LComp is TComponent then begin + LF.SetComponentName(TComponent(LComp).Name); + end; + LF.SetList(LList); + if LF.Execute then begin + LF.GetList(LList); + end; + finally + FreeAndNil(LF); + end; +end; + +function TIdPropEdSASL.GetAttributes: TPropertyAttributes; +begin + Result := inherited GetAttributes + [paDialog]; +end; + +function TIdPropEdSASL.GetValue: string; +begin + Result := GetStrValue; +end; + +procedure TIdPropEdSASL.SetValue(const Value: string); +begin + inherited SetValue(Value); +end; + +procedure Register; +begin + RegisterPropertyEditor(TypeInfo(TIdSASLEntries), nil, '', TIdPropEdSASL); + {$IFDEF HAS_TSelectionEditor} + RegisterSelectionEditor(TIdFTPServer,TIdFTPServerSelectionEditor); + {$ENDIF} +end; + +end. diff --git a/Lib/Protocols/IdHTTP.pas b/Lib/Protocols/IdHTTP.pas index 16bcbeadd..0a066c877 100644 --- a/Lib/Protocols/IdHTTP.pas +++ b/Lib/Protocols/IdHTTP.pas @@ -1,3278 +1,3278 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.65 3/5/2005 3:33:52 PM JPMugaas - Fix for some compiler warnings having to do with TStream.Read being platform - specific. This was fixed by changing the Compressor API to use TIdStreamVCL - instead of TStream. I also made appropriate adjustments to other units for - this. - - Rev 1.64 2/13/2005 3:09:20 PM DSiders - Modified TIdCustomHTTP.PrepareRequest to free the local URI instance if an - exception occurs in the method. (try...finally) - - Rev 1.63 2/11/05 11:29:34 AM RLebeau - Removed compiler warning - - Rev 1.62 2/9/05 2:12:08 AM RLebeau - Fixes for Compiler errors - - Rev 1.61 2/8/05 6:43:42 PM RLebeau - Added OnHeaderAvailable event - - Rev 1.60 1/11/05 1:25:08 AM RLebeau - More changes to SetHostAndPort() - - Rev 1.59 1/6/05 2:28:52 PM RLebeau - Fix for SetHostAndPort() not using its local variables properly - - Rev 1.58 06/01/2005 22:23:04 CCostelloe - Bug fix (typo, gizp instead of gzip) - - Rev 1.57 05/12/2004 23:10:58 CCostelloe - Recoded fix to suit Delphi < 7 - - Rev 1.56 30/11/2004 23:46:12 CCostelloe - Bug fix for SSL connections giving a "Connection closed gracefully" exception - and requested page not getting returned (IOHandler.Response is empty) - - Rev 1.55 25/11/2004 21:28:06 CCostelloe - Bug fix for POSTing fields that have the same name - - Rev 1.54 10/26/2004 10:13:24 PM JPMugaas - Updated refs. - - Rev 1.53 7/16/04 1:19:20 AM RLebeau - Fix for compiler error - - Rev 1.52 7/15/04 8:19:30 PM RLebeau - Updated TIdHTTPProtocol.ProcessResponse() to treat 302 redirects like 303. - - Updated TIdHTTPProtocol.BuildAndSendRequest() to use a try...except block - - Rev 1.51 6/17/2004 8:30:04 AM DSiders - TIdCustomHTTP modified: - - Fixed error in AuthRetries property reading wrong member var. - - Added AuthProxyRetries and MaxAuthRetries properties to public interface. - - TIdHTTP modified to publish AuthRetries, AuthProxyRetries, and MaxAuthRetries. - - TIdHTTPProtocol.ProcessResponse modified to use public properties - AuthRetries, AuthProxyRetries, and MaxAutrhRetries. - - Rev 1.50 2004.05.20 11:36:46 AM czhower - IdStreamVCL - - Rev 1.49 4/28/04 1:45:26 PM RLebeau - Updated TIdCustomHTTP.SetRequestParams() to strip off the trailing CRLF - before encoding rather than afterwards - - Rev 1.48 2004.04.07 11:18:08 PM czhower - Bug and naming fix. - - Rev 1.47 7/4/2004 6:00:02 PM SGrobety - Reformatted to match project guidelines - - Rev 1.46 7/4/2004 4:58:24 PM SGrobety - Reformatted to match project guidelines - - Rev 1.45 6/4/2004 5:16:40 PM SGrobety - Added AMaxHeaderCount: integer parameter to TIdHTTPProtocol.RetrieveHeaders - and MaxHeaderLines property to TIdCustomHTTP (default to 255) - - Rev 1.44 2004.03.06 10:39:52 PM czhower - Removed duplicate code - - Rev 1.43 2004.03.06 8:56:30 PM czhower - -Change to disconnect - -Addition of DisconnectNotifyPeer - -WriteHeader now write bufers - - Rev 1.42 3/3/2004 5:58:00 AM JPMugaas - Some IFDEF excluses were removed because the functionality is now in DotNET. - - Rev 1.41 2004.02.23 9:33:12 PM czhower - Now can optionally ignore response codes for exceptions. - - Rev 1.40 2/15/2004 6:34:02 AM JPMugaas - Fix for where I broke the HTTP client with a parameter change in the GZip - decompress method. - - Rev 1.39 2004.02.03 5:43:44 PM czhower - Name changes - - Rev 1.38 2004.02.03 2:12:10 PM czhower - $I path change - - Rev 1.37 2004.01.27 11:41:18 PM czhower - Removed const arguments - - Rev 1.35 24/01/2004 19:22:34 CCostelloe - Cleaned up warnings - - Rev 1.34 2004.01.22 5:29:02 PM czhower - TextIsSame - - Rev 1.33 2004.01.21 1:04:50 PM czhower - InitComponenet - - Rev 1.32 1/2/2004 11:41:48 AM BGooijen - Enabled IPv6 support - - Rev 1.31 22/11/2003 12:04:28 AM GGrieve - Add support for HTTP status code 303 - - Rev 1.30 10/25/2003 06:51:58 AM JPMugaas - Updated for new API changes and tried to restore some functionality. - - Rev 1.29 2003.10.24 10:43:08 AM czhower - TIdSTream to dos - - Rev 1.28 24/10/2003 10:58:40 AM SGrobety - Made authentication work even if no OnAnthenticate envent handler present - - Rev 1.27 10/18/2003 1:53:10 PM BGooijen - Added include - - Rev 1.26 10/17/2003 12:08:48 AM DSiders - Added localization comments. - - Rev 1.25 2003.10.14 1:27:52 PM czhower - DotNet - - Rev 1.24 10/7/2003 11:33:54 PM GGrieve - Get works under DotNet - - Rev 1.23 10/7/2003 10:07:04 PM GGrieve - Get HTTP compiling for DotNet - - Rev 1.22 10/4/2003 9:15:58 PM GGrieve - fix to compile - - Rev 1.21 9/26/2003 01:41:48 PM JPMugaas - Fix for problem wihere "identity" was being added more than once to the - accepted encoding contents. - - Rev 1.20 9/14/2003 07:54:20 PM JPMugaas - Published the Compressor property. - - Rev 1.19 7/30/2003 05:34:22 AM JPMugaas - Fix for bug where decompression was not done if the Content Length was - specified. I found that at http://www.news.com. - Added Identity to the content encoding to be consistant with Opera. Identity - is the default Accept-Encoding (RFC 2616). - - Rev 1.18 7/13/2003 10:57:28 PM BGooijen - Fixed GZip and Deflate decoding - - Rev 1.17 7/13/2003 11:29:06 AM JPMugaas - Made sure some GZIP decompression stub code is in IdHTTP. - - Rev 1.15 10.7.2003 ã. 21:03:02 DBondzhev - Fixed NTML proxy authorization - - Rev 1.14 6/19/2003 02:36:56 PM JPMugaas - Removed a connected check and it seems to work better that way. - - Rev 1.13 6/5/2003 04:53:54 AM JPMugaas - Reworkings and minor changes for new Reply exception framework. - - Rev 1.12 4/30/2003 01:47:24 PM JPMugaas - Added TODO concerning a ConnectTimeout. - - Rev 1.11 4/2/2003 3:18:30 PM BGooijen - fixed av when retrieving an url when no iohandler was assigned - - Rev 1.10 3/26/2003 5:13:40 PM BGooijen - TIdSSLIOHandlerSocketBase.URIToCheck is now set - - Rev 1.9 3/13/2003 11:05:26 AM JPMugaas - Now should work with 3rd party vendor SSL IOHandlers. - - Rev 1.8 3/11/2003 10:14:52 PM BGooijen - Undid the stripping of the CR - - Rev 1.7 2/27/2003 2:04:26 PM BGooijen - If any call to iohandler.readln returns a CR at the end, it is removed now. - - Rev 1.6 2/26/2003 11:50:08 AM BGooijen - things were messed up in TIdHTTPProtocol.RetrieveHeaders, because the call to - readln doesn't strip the CR at the end (terminator=LF), therefore the end of - the header was not found. - - Rev 1.5 2/26/2003 11:42:46 AM BGooijen - changed ReadLn (IOerror 6) to IOHandler.ReadLn - - Rev 1.4 2/4/2003 6:30:44 PM BGooijen - Re-enabled SSL-support - - Rev 1.3 1/17/2003 04:14:42 PM JPMugaas - Fixed warnings. - - Rev 1.2 12/7/2002 05:32:16 PM JPMugaas - Now compiles with destination removed. - - Rev 1.1 12/6/2002 05:29:52 PM JPMugaas - Now decend from TIdTCPClientCustom instead of TIdTCPClient. - - Rev 1.0 11/13/2002 07:54:12 AM JPMugaas - -2001-Nov Nick Panteleeff - - Authentication and POST parameter extentsions - -2001-Sept Doychin Bondzhev - - New internal design and new Authentication procedures. - - Bug fixes and new features in few other supporting components - -2001-Jul-7 Doychin Bondzhev - - new property AllowCookie - - There is no more ExtraHeders property in Request/Response. Raw headers is used for that purpose. - -2001-Jul-1 Doychin Bondzhev - - SSL support is up again - Thanks to Gregor - -2001-Jun-17 Doychin Bondzhev - - New unit IdHTTPHeaderInfo.pas that contains the - TIdHeaderInfo(TIdEntytiHeaderInfo, TIdRequestHeaderInfo and TIdResponseHeaderInfo) - - Still in development and not verry well tested - By default when there is no authorization object associated with HTTP compoenet and there is user name and password - HTTP component creates and instance of TIdBasicAuthentication class. This behaivor is for both web server and proxy server - authorizations - -2001-Apr-17 Doychin Bondzhev - - Added OnProxyAuthorization event. This event is called on 407 response from the HTTP Proxy. - - Added 2 new properties in TIdHeaderInfo - property AuthenticationScheme: TIdAuthenticationScheme - this property contains information for authentication scheme - requested by the web server - property ProxyAuthenticationScheme: TIdAuthenticationScheme - this property contains information for authentication scheme - requested by the proxy server - - Now the component authomaticly reconginizes the requested authorization scheme and it supports Basic like before and has been - extend to support Digest authorization - -2001-Mar-31 Doychin Bondzhev - - If there is no CookieManager it does not support cookies. - -2001-Feb-18 Doychin Bondzhev - - Added OnAuthorization event. This event is called on 401 response from the HTTP server. - This can be used to ask the user program to supply user name and password in order to acces - the requested resource - -2001-Feb-02 Doychin Bondzhev - - Added Cookie support and relative paths on redirect - -2000-Jul-25 Hadi Hariri - - Overloaded POst and moved clearing to disconect. - -2000-June-22 Hadi Hariri - - Added Proxy support. - -2000-June-10 Hadi Hariri - - Added Chunk-Encoding support and HTTP version number. Some additional - improvements. - -2000-May-23 J. Peter Mugaas - -added redirect capability and supporting properties. Redirect is optional - and is set with HandleRedirects. Redirection is limited to RedirectMaximum - to prevent stack overflow due to recursion and to prevent redirects between - two places which would cause this to go on to infinity. - -2000-May-22 J. Peter Mugaas - -adjusted code for servers which returned LF instead of EOL - -Headers are now retreived before an exception is raised. This - also facilitates server redirection where the server tells the client to - get a document from another location. - -2000-May-01 Hadi Hariri - -Converted to Mercury - -2000-May-01 Hadi Hariri - -Added PostFromStream and some clean up - -2000-Apr-10 Hadi Hariri - -Re-done quite a few things and fixed GET bugs and finished POST method. - -2000-Jan-13 MTL - -Moved to the New Palette Scheme - -2000-Jan-08 MTL - -Cleaned up a few compiler hints during 7.038 build - -1999-Dec-10 Hadi Hariri - -Started. -} - -unit IdHTTP; - -{ - Implementation of the HTTP protcol as specified in RFC 2616, 2109, 2965. - (See NOTE below for details of what is exactly implemented) - - Author: Hadi Hariri (hadi@urusoft.com) - Copyright: (c) Chad Z. Hower and The Winshoes Working Group. - - Initials: Hadi Hariri - HH -} -{ - TODO: Figure out what to do with ConnectTimeout. - Ideally, that should be in the core and is not the same as a read Timeout. -} - -interface - -{$I IdCompilerDefines.inc} - -uses - Classes, - IdException, IdExceptionCore, IdAssignedNumbers, IdHeaderList, IdHTTPHeaderInfo, IdReplyRFC, - IdSSL, IdZLibCompressorBase, - IdTCPClient, IdURI, IdCookieManager, IdAuthentication, IdAuthenticationManager, - IdMultipartFormData, IdGlobal, IdBaseComponent, IdUriUtils; - -type - // TO DOCUMENTATION TEAM - // ------------------------ - // For internal use. No need of documentation - // hmConnect - Used to connect trought CERN proxy to SSL enabled sites. - TIdHTTPMethod = string; - -const - Id_HTTPMethodHead = 'HEAD'; - Id_HTTPMethodGet = 'GET'; - Id_HTTPMethodPost = 'POST'; - Id_HTTPMethodOptions = 'OPTIONS'; - Id_HTTPMethodTrace = 'TRACE'; - Id_HTTPMethodPut = 'PUT'; - Id_HTTPMethodDelete = 'DELETE'; - Id_HTTPMethodConnect = 'CONNECT'; - Id_HTTPMethodPatch = 'PATCH'; - //(hmHead, hmGet, hmPost, hmOptions, hmTrace, hmPut, hmDelete, hmConnect, hmPatch); - -type - TIdHTTPWhatsNext = (wnGoToURL, wnJustExit, wnDontKnow, wnReadAndGo, wnAuthRequest); - TIdHTTPConnectionType = (ctNormal, ctSSL, ctProxy, ctSSLProxy); - - // Protocol options - TIdHTTPOption = (hoInProcessAuth, hoKeepOrigProtocol, hoForceEncodeParams, - hoNonSSLProxyUseConnectVerb, hoNoParseMetaHTTPEquiv, hoWaitForUnexpectedData, - hoTreat302Like303, hoNoProtocolErrorException, hoNoReadMultipartMIME, - hoNoParseXmlCharset, hoWantProtocolErrorContent, hoNoReadChunked - ); - - TIdHTTPOptions = set of TIdHTTPOption; - - // Must be documented - TIdHTTPProtocolVersion = (pv1_0, pv1_1); - - TIdHTTPOnRedirectEvent = procedure(Sender: TObject; var dest: string; var NumRedirect: Integer; var Handled: boolean; var VMethod: TIdHTTPMethod) of object; - TIdHTTPOnHeadersAvailable = procedure(Sender: TObject; AHeaders: TIdHeaderList; var VContinue: Boolean) of object; - TIdOnSelectAuthorization = procedure(Sender: TObject; var AuthenticationClass: TIdAuthenticationClass; AuthInfo: TIdHeaderList) of object; - TIdOnAuthorization = procedure(Sender: TObject; Authentication: TIdAuthentication; var Handled: Boolean) of object; - // TIdProxyOnAuthorization = procedure(Sender: TObject; Authentication: TIdAuthentication; var Handled: boolean) of object; - TIdOnChunkReceived = procedure(Sender : TObject; var Chunk: TIdBytes) of object; - -const - Id_TIdHTTP_ProtocolVersion = pv1_1; - Id_TIdHTTP_RedirectMax = 15; - Id_TIdHTTP_MaxHeaderLines = 255; - Id_TIdHTTP_HandleRedirects = False; - Id_TIdHTTP_MaxAuthRetries = 3; - Id_TIdHTTP_HTTPOptions = [hoKeepOrigProtocol, hoForceEncodeParams]; - -type - TIdCustomHTTP = class; - - // TO DOCUMENTATION TEAM - // ------------------------ - // The following classes are used internally and no need of documentation - // Only TIdHTTP must be documented - // - TIdHTTPResponse = class(TIdResponseHeaderInfo) - protected - {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FHTTP: TIdCustomHTTP; - FResponseCode: Integer; - FResponseText: string; - FKeepAlive: Boolean; - {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FContentStream: TStream; - FResponseVersion: TIdHTTPProtocolVersion; - FMetaHTTPEquiv : TIdMetaHTTPEquiv; - // - function GetKeepAlive: Boolean; - function GetResponseCode: Integer; - - procedure SetResponseText(const AValue: String); - procedure ProcessMetaHTTPEquiv; - public - constructor Create(AHTTP: TIdCustomHTTP); reintroduce; virtual; - destructor Destroy; override; - procedure Clear; override; - property KeepAlive: Boolean read GetKeepAlive write FKeepAlive; - property MetaHTTPEquiv: TIdMetaHTTPEquiv read FMetaHTTPEquiv; - property ResponseText: string read FResponseText write SetResponseText; - property ResponseCode: Integer read GetResponseCode write FResponseCode; - property ResponseVersion: TIdHTTPProtocolVersion read FResponseVersion write FResponseVersion; - property ContentStream: TStream read FContentStream write FContentStream; - end; - - TIdHTTPRequest = class(TIdRequestHeaderInfo) - protected - {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FHTTP: TIdCustomHTTP; - FURL: string; - FMethod: TIdHTTPMethod; - {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FSourceStream: TStream; - FUseProxy: TIdHTTPConnectionType; - FIPVersion: TIdIPVersion; - FDestination: string; - public - constructor Create(AHTTP: TIdCustomHTTP); reintroduce; virtual; - property URL: string read FURL write FURL; - property Method: TIdHTTPMethod read FMethod write FMethod; - property Source: TStream read FSourceStream write FSourceStream; - property UseProxy: TIdHTTPConnectionType read FUseProxy; - property IPVersion: TIdIPVersion read FIPVersion write FIPVersion; - property Destination: string read FDestination write FDestination; - end; - - TIdHTTPProtocol = class(TObject) - protected - {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FHTTP: TIdCustomHTTP; - FRequest: TIdHTTPRequest; - FResponse: TIdHTTPResponse; - public - constructor Create(AConnection: TIdCustomHTTP); - destructor Destroy; override; - function ProcessResponse(AIgnoreReplies: array of Int16): TIdHTTPWhatsNext; - procedure BuildAndSendRequest(AURI: TIdURI); - procedure RetrieveHeaders(AMaxHeaderCount: integer); - // - property Request: TIdHTTPRequest read FRequest; - property Response: TIdHTTPResponse read FResponse; - end; - - TIdCustomHTTP = class(TIdTCPClientCustom) - protected - {Retries counter for WWW authorization} - FAuthRetries: Integer; - {Retries counter for proxy authorization} - FAuthProxyRetries: Integer; - {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FCookieManager: TIdCookieManager; - {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FCompressor : TIdZLibCompressorBase; - FImplicitCookieManager: Boolean; - {Max retries for authorization} - FMaxAuthRetries: Integer; - FMaxHeaderLines: integer; - FAllowCookies: Boolean; - {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FAuthenticationManager: TIdAuthenticationManager; - FProtocolVersion: TIdHTTPProtocolVersion; - - {this is an internal counter for redirects} - FRedirectCount: Integer; - FRedirectMax: Integer; - FHandleRedirects: Boolean; - FOptions: TIdHTTPOptions; - FURI: TIdURI; - FHTTPProto: TIdHTTPProtocol; - FProxyParameters: TIdProxyConnectionInfo; - // - FOnHeadersAvailable: TIdHTTPOnHeadersAvailable; - FOnRedirect: TIdHTTPOnRedirectEvent; - FOnSelectAuthorization: TIdOnSelectAuthorization; - FOnSelectProxyAuthorization: TIdOnSelectAuthorization; - FOnAuthorization: TIdOnAuthorization; - FOnProxyAuthorization: TIdOnAuthorization; - FOnChunkReceived: TIdOnChunkReceived; - // -{ - procedure SetHost(const Value: string); override; - procedure SetPort(const Value: integer); override; -} - procedure DoRequest(const AMethod: TIdHTTPMethod; AURL: string; - ASource, AResponseContent: TStream; AIgnoreReplies: array of Int16); virtual; - function CreateProtocol: TIdHTTPProtocol; virtual; - procedure InitComponent; override; - function InternalReadLn: String; - procedure SetAuthenticationManager(Value: TIdAuthenticationManager); - procedure SetCookieManager(ACookieManager: TIdCookieManager); - procedure SetAllowCookies(AValue: Boolean); - function GetResponseCode: Integer; - function GetResponseText: string; - function DoOnAuthorization(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse): Boolean; virtual; - function DoOnProxyAuthorization(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse): Boolean; virtual; - function DoOnRedirect(var Location: string; var VMethod: TIdHTTPMethod; RedirectCount: integer): boolean; virtual; - procedure Notification(AComponent: TComponent; Operation: TOperation); override; - procedure ProcessCookies(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); - function SetHostAndPort: TIdHTTPConnectionType; - procedure SetCookies(AURL: TIdURI; ARequest: TIdHTTPRequest); - procedure ReadResult(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); - procedure PrepareRequest(ARequest: TIdHTTPRequest); - procedure ConnectToHost(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); - function GetResponse: TIdHTTPResponse; - function GetRequest: TIdHTTPRequest; - function GetMetaHTTPEquiv: TIdMetaHTTPEquiv; - procedure SetRequest(Value: TIdHTTPRequest); - procedure SetProxyParams(AValue: TIdProxyConnectionInfo); - - function SetRequestParams(ASource: TStrings; AByteEncoding: IIdTextEncoding - {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding{$ENDIF} - ): string; - - procedure CheckAndConnect(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); - procedure DoOnDisconnected; override; - public - destructor Destroy; override; - - procedure Delete(AURL: string; AResponseContent: TStream); overload; - function Delete(AURL: string - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; overload; - - procedure Options(AURL: string; AResponseContent: TStream); overload; - function Options(AURL: string - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; overload; - - procedure Get(AURL: string; AResponseContent: TStream); overload; - procedure Get(AURL: string; AResponseContent: TStream; AIgnoreReplies: array of Int16); overload; - function Get(AURL: string - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; overload; - function Get(AURL: string; AIgnoreReplies: array of Int16 - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; overload; - - procedure Trace(AURL: string; AResponseContent: TStream); overload; - function Trace(AURL: string - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; overload; - procedure Head(AURL: string); - - function Post(AURL: string; const ASourceFile: String - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; overload; - function Post(AURL: string; ASource: TStrings; AByteEncoding: IIdTextEncoding = nil - {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil; ADestEncoding: IIdTextEncoding = nil{$ENDIF}): string; overload; - function Post(AURL: string; ASource: TStream - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; overload; - function Post(AURL: string; ASource: TIdMultiPartFormDataStream - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; overload; - - procedure Post(AURL: string; const ASourceFile: String; AResponseContent: TStream); overload; - procedure Post(AURL: string; ASource: TStrings; AResponseContent: TStream; AByteEncoding: IIdTextEncoding = nil - {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}); overload; - procedure Post(AURL: string; ASource, AResponseContent: TStream); overload; - procedure Post(AURL: string; ASource: TIdMultiPartFormDataStream; AResponseContent: TStream); overload; - - function Put(AURL: string; ASource: TStream - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; overload; - procedure Put(AURL: string; ASource, AResponseContent: TStream); overload; - - procedure Patch(AURL: string; ASource, AResponseContent: TStream); overload; - function Patch(AURL: string; ASource: TStream - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; overload; - - {This is an object that can compress and decompress HTTP Deflate encoding} - property Compressor : TIdZLibCompressorBase read FCompressor write FCompressor; - - {This is the response code number such as 404 for File not Found} - property ResponseCode: Integer read GetResponseCode; - {This is the text of the message such as "404 File Not Found here Sorry"} - property ResponseText: string read GetResponseText; - property Response: TIdHTTPResponse read GetResponse; - property MetaHTTPEquiv: TIdMetaHTTPEquiv read GetMetaHTTPEquiv; - { This is the last processed URL } - property URL: TIdURI read FURI; - // number of retry attempts for Authentication - property AuthRetries: Integer read FAuthRetries; - property AuthProxyRetries: Integer read FAuthProxyRetries; - // maximum number of Authentication retries permitted - property MaxAuthRetries: Integer read FMaxAuthRetries write FMaxAuthRetries default Id_TIdHTTP_MaxAuthRetries; - property AllowCookies: Boolean read FAllowCookies write SetAllowCookies default True; - {Do we handle redirect requests or simply raise an exception and let the - developer deal with it} - property HandleRedirects: Boolean read FHandleRedirects write FHandleRedirects default Id_TIdHTTP_HandleRedirects; - property ProtocolVersion: TIdHTTPProtocolVersion read FProtocolVersion write FProtocolVersion default Id_TIdHTTP_ProtocolVersion; - //how many redirects were made in the last request - property RedirectCount: Integer read FRedirectCount; - {This is the maximum number of redirects we wish to handle, we limit this - to prevent stack overflow due to recursion. Recursion is safe ONLY if - prevented for continuing to infinity} - property RedirectMaximum: Integer read FRedirectMax write FRedirectMax default Id_TIdHTTP_RedirectMax; - // S.G. 6/4/2004: This is to prevent the server from responding with too many header lines - property MaxHeaderLines: integer read FMaxHeaderLines write FMaxHeaderLines default Id_TIdHTTP_MaxHeaderLines; - property ProxyParams: TIdProxyConnectionInfo read FProxyParameters write SetProxyParams; - property Request: TIdHTTPRequest read GetRequest write SetRequest; - property HTTPOptions: TIdHTTPOptions read FOptions write FOptions default Id_TIdHTTP_HTTPOptions; - // - property OnHeadersAvailable: TIdHTTPOnHeadersAvailable read FOnHeadersAvailable write FOnHeadersAvailable; - // Fired when a rediretion is requested. - property OnRedirect: TIdHTTPOnRedirectEvent read FOnRedirect write FOnRedirect; - property OnSelectAuthorization: TIdOnSelectAuthorization read FOnSelectAuthorization write FOnSelectAuthorization; - property OnSelectProxyAuthorization: TIdOnSelectAuthorization read FOnSelectProxyAuthorization write FOnSelectProxyAuthorization; - property OnAuthorization: TIdOnAuthorization read FOnAuthorization write FOnAuthorization; - property OnProxyAuthorization: TIdOnAuthorization read FOnProxyAuthorization write FOnProxyAuthorization; - property OnChunkReceived: TIdOnChunkReceived read FOnChunkReceived write FOnChunkReceived; - // Cookie stuff - property CookieManager: TIdCookieManager read FCookieManager write SetCookieManager; - // - property AuthenticationManager: TIdAuthenticationManager read FAuthenticationManager write SetAuthenticationManager; - end; - - TIdHTTP = class(TIdCustomHTTP) - published - // number of Authentication retries permitted - property MaxAuthRetries; - property AllowCookies; - { Do we handle redirect requests or simply raise an exception and let the - developer deal with it } - property HandleRedirects; - property ProtocolVersion; - { This is the maximum number of redirects we wish to handle, we limit this - to prevent stack overflow due to recursion. Recursion is safe ONLY if - prevented for continuing to infinity } - property RedirectMaximum; - property ProxyParams; - property Request; - property HTTPOptions; - // - property OnHeadersAvailable; - // Fired when a rediretion is requested. - property OnRedirect; - property OnSelectAuthorization; - property OnSelectProxyAuthorization; - property OnAuthorization; - property OnProxyAuthorization; - property OnChunkReceived; - // property Host; - // property Port default IdPORT_HTTP; - // Cookie stuff - property CookieManager; - // property AuthenticationManager: TIdAuthenticationManager read FAuthenticationManager write SetAuthenticationManager; - // ZLib compression library object for use with deflate and gzip encoding - property Compressor; - end; - - EIdUnknownProtocol = class(EIdException); - EIdHTTPProtocolException = class( EIdReplyRFCError ) - protected - FErrorMessage: string; - public - constructor CreateError(const anErrCode: Integer; const asReplyMessage: string; - const asErrorMessage: string); reintroduce; virtual; - property ErrorMessage: string read FErrorMessage; - end; - -implementation - -uses - SysUtils, - IdAllAuthentications, IdComponent, IdCoderMIME, IdTCPConnection, - IdResourceStringsCore, IdResourceStringsProtocols, IdGlobalProtocols, - IdIOHandler, IdIOHandlerSocket; - -const - ProtocolVersionString: array[TIdHTTPProtocolVersion] of string = ('1.0', '1.1'); {do not localize} - -{ EIdHTTPProtocolException } - -constructor EIdHTTPProtocolException.CreateError(const anErrCode: Integer; - const asReplyMessage: string; const asErrorMessage: string); -begin - inherited CreateError(anErrCode, asReplyMessage); - FErrorMessage := asErrorMessage; -end; - -{ TIdHTTP } - -function IsContentTypeHtml(AInfo: TIdEntityHeaderInfo) : Boolean; -begin - Result := IsHeaderMediaTypes(AInfo.ContentType, ['text/html', 'text/html-sandboxed','application/xhtml+xml']); {do not localize} -end; - -function IsContentTypeAppXml(AInfo: TIdEntityHeaderInfo) : Boolean; -begin - Result := IsHeaderMediaTypes(AInfo.ContentType, - ['application/xml', 'application/xml-external-parsed-entity', 'application/xml-dtd'] {do not localize} - ); - if not Result then - begin - Result := not IsHeaderMediaType(AInfo.ContentType, 'text'); {do not localize} - if Result then begin - Result := TextEndsWith(ExtractHeaderMediaSubType(AInfo.ContentType), '+xml') {do not localize} - end; - end; -end; - -destructor TIdCustomHTTP.Destroy; -begin - FreeAndNil(FHTTPProto); - FreeAndNil(FURI); - FreeAndNil(FProxyParameters); - SetCookieManager(nil); - inherited Destroy; -end; - -procedure TIdCustomHTTP.Delete(AURL: string; AResponseContent: TStream); -begin - DoRequest(Id_HTTPMethodDelete, AURL, nil, AResponseContent, []); -end; - -function TIdCustomHTTP.Delete(AURL: string - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; -var - LStream: TMemoryStream; -begin - LStream := TMemoryStream.Create; - try - DoRequest(Id_HTTPMethodDelete, AURL, nil, LStream, []); - LStream.Position := 0; - Result := ReadStringAsCharset(LStream, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); - // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... - finally - FreeAndNil(LStream); - end; -end; - -procedure TIdCustomHTTP.Options(AURL: string; AResponseContent: TStream); -begin - DoRequest(Id_HTTPMethodOptions, AURL, nil, AResponseContent, []); -end; - -function TIdCustomHTTP.Options(AURL: string - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; -var - LStream: TMemoryStream; -begin - LStream := TMemoryStream.Create; - try - DoRequest(Id_HTTPMethodOptions, AURL, nil, LStream, []); - LStream.Position := 0; - Result := ReadStringAsCharset(LStream, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); - // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... - finally - FreeAndNil(LStream); - end; -end; - -procedure TIdCustomHTTP.Get(AURL: string; AResponseContent: TStream); -begin - Get(AURL, AResponseContent, []); -end; - -procedure TIdCustomHTTP.Trace(AURL: string; AResponseContent: TStream); -begin - DoRequest(Id_HTTPMethodTrace, AURL, nil, AResponseContent, []); -end; - -procedure TIdCustomHTTP.Head(AURL: string); -begin - DoRequest(Id_HTTPMethodHead, AURL, nil, nil, []); -end; - -procedure TIdCustomHTTP.Post(AURL: string; ASource, AResponseContent: TStream); -var - OldProtocol: TIdHTTPProtocolVersion; -begin - // PLEASE READ CAREFULLY - - // Currently when issuing a POST, IdHTTP will automatically set the protocol - // to version 1.0 independently of the value it had initially. This is because - // there are some servers that don't respect the RFC to the full extent. In - // particular, they don't respect sending/not sending the Expect: 100-Continue - // header. Until we find an optimum solution that does NOT break the RFC, we - // will restrict POSTS to version 1.0. - OldProtocol := FProtocolVersion; - try - // If hoKeepOrigProtocol is SET, is possible to assume that the developer - // is sure in operations of the server - if not (hoKeepOrigProtocol in FOptions) then begin - if Connected then begin - Disconnect; - end; - FProtocolVersion := pv1_0; - end; - DoRequest(Id_HTTPMethodPost, AURL, ASource, AResponseContent, []); - finally - FProtocolVersion := OldProtocol; - end; -end; - -// RLebeau 12/21/2010: this is based on W3's HTML standards: -// -// HTML 4.01 -// http://www.w3.org/TR/html401/ -// -// HTML 5 -// http://www.w3.org/TR/html5/ - -function WWWFormUrlEncode(const ASrc: string; AByteEncoding: IIdTextEncoding - {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding{$ENDIF} - ): string; -const - // HTML 4.01 Section 17.13.4 ("Form content types") says: - // - // application/x-www-form-urlencoded - // - // Control names and values are escaped. Space characters are replaced by `+', - // and then reserved characters are escaped as described in [RFC1738], section - // 2.2: Non-alphanumeric characters are replaced by `%HH', a percent sign and - // two hexadecimal digits representing the ASCII code of the character. Line - // breaks are represented as "CR LF" pairs (i.e., `%0D%0A'). - // - // On the other hand, HTML 5 Section 4.10.16.4 ("URL-encoded form data") says: - // - // If the character isn't in the range U+0020, U+002A, U+002D, U+002E, - // U+0030 .. U+0039, U+0041 .. U+005A, U+005F, U+0061 .. U+007A then replace - // the character with a string formed as follows: Start with the empty string, - // and then, taking each byte of the character when expressed in the selected - // character encoding in turn, append to the string a U+0025 PERCENT SIGN - // character (%) followed by two characters in the ranges U+0030 DIGIT ZERO (0) - // to U+0039 DIGIT NINE (9) and U+0041 LATIN CAPITAL LETTER A to - // U+005A LATIN CAPITAL LETTER Z representing the hexadecimal value of the - // byte zero-padded if necessary). - // - // If the character is a U+0020 SPACE character, replace it with a single - // U+002B PLUS SIGN character (+). - // - // So, lets err on the side of caution and use the HTML 5.x definition, as it - // encodes some of the characters that HTML 4.01 allows unencoded... - // - SafeChars: TIdUnicodeString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*-._'; {do not localize} -var - I, J, CharLen, ByteLen: Integer; - Buf: TIdBytes; - {$IFDEF STRING_IS_ANSI} - LChars: TIdWideChars; - {$ENDIF} - LChar: WideChar; - Encoded: Boolean; -begin - Result := ''; - - // keep the compiler happy - Buf := nil; - {$IFDEF STRING_IS_ANSI} - LChars := nil; - {$ENDIF} - - if ASrc = '' then begin - Exit; - end; - - EnsureEncoding(AByteEncoding, encUTF8); - {$IFDEF STRING_IS_ANSI} - EnsureEncoding(ASrcEncoding, encOSDefault); - LChars := ASrcEncoding.GetChars( - {$IFNDEF VCL_6_OR_ABOVE} - // RLebeau: for some reason, Delphi 5 causes a "There is no overloaded - // version of 'GetChars' that can be called with these arguments" compiler - // error if the PByte type-cast is used, even though GetChars() actually - // expects a PByte as input. Must be a compiler bug, as it compiles fine - // in Delphi 6. So, converting to TIdBytes until I find a better solution... - RawToBytes(PAnsiChar(ASrc)^, Length(ASrc)) - {$ELSE} - PByte(PAnsiChar(ASrc)), Length(ASrc) - {$ENDIF} - ); - {$ENDIF} - - // 2 Chars to handle UTF-16 surrogates - SetLength(Buf, AByteEncoding.GetMaxByteCount(2)); - - I := 0; - while I < Length({$IFDEF STRING_IS_UNICODE}ASrc{$ELSE}LChars{$ENDIF}) do - begin - LChar := {$IFDEF STRING_IS_UNICODE}ASrc[I+1]{$ELSE}LChars[I]{$ENDIF}; - - // RLebeau 1/7/09: using Ord() for #128-#255 because in D2009 and later, the - // compiler may change characters >= #128 from their Ansi codepage value to - // their true Unicode codepoint value, depending on the codepage used for - // the source code. For instance, #128 may become #$20AC... - - if Ord(LChar) = 32 then - begin - Result := Result + '+'; {do not localize} - Inc(I); - end - else if WideCharIsInSet(SafeChars, LChar) then - begin - Result := Result + Char(LChar); - Inc(I); - end else - begin - // HTML 5 Section 4.10.16.4 says: - // - // For each character ... that cannot be expressed using the selected character - // encoding, replace the character by a string consisting of a U+0026 AMPERSAND - // character (&), a U+0023 NUMBER SIGN character (#), one or more characters in - // the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9) representing the - // Unicode code point of the character in base ten, and finally a U+003B - // SEMICOLON character (;). - // - CharLen := CalcUTF16CharLength( - {$IFDEF STRING_IS_UNICODE}ASrc, I+1{$ELSE}LChars, I{$ENDIF} - ); // calculate length including surrogates - ByteLen := AByteEncoding.GetBytes( - {$IFDEF STRING_IS_UNICODE}ASrc, I+1{$ELSE}LChars, I{$ENDIF}, - CharLen, Buf, 0); // explicit Unicode->Ansi conversion - - Encoded := (ByteLen > 0); - if Encoded and (LChar <> '?') then begin {do not localize} - for J := 0 to ByteLen-1 do begin - if Buf[J] = Ord('?') then begin {do not localize} - Encoded := False; - Break; - end; - end; - end; - - if Encoded then begin - for J := 0 to ByteLen-1 do begin - Result := Result + '%' + IntToHex(Ord(Buf[J]), 2); {do not localize} - end; - end else begin - J := GetUTF16Codepoint( - {$IFDEF STRING_IS_UNICODE}ASrc, I+1{$ELSE}LChars, I{$ENDIF}); - Result := Result + '&#' + IntToStr(J) + ';'; {do not localize} - end; - - Inc(I, CharLen); - end; - end; -end; - -function TIdCustomHTTP.SetRequestParams(ASource: TStrings; AByteEncoding: IIdTextEncoding - {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding{$ENDIF} - ): string; -var - i: Integer; - LPos: integer; - LStr: string; - LTemp: TStringList; - {$IFDEF HAS_TStrings_NameValueSeparator} - LChar: string; - J: Integer; - {$ENDIF} - - function EncodeLineBreaks(AStrings: TStrings): String; - begin - if AStrings.Count > 1 then begin - // break trailing CR&LF - Result := ReplaceAll(Trim(AStrings.Text), - {$IFDEF HAS_TStrings_LineBreak}AStrings.LineBreak{$ELSE}sLineBreak{$ENDIF}, - '&'); {do not localize} - end else begin - Result := Trim(AStrings.Text); - end; - end; - -begin - if Assigned(ASource) then begin - if hoForceEncodeParams in FOptions then begin - // make a copy of ASource so the caller's TStrings object is not modified - LTemp := TStringList.Create; - try - LTemp.Assign(ASource); - for i := 0 to LTemp.Count - 1 do begin - LStr := LTemp[i]; - {$IFDEF HAS_TStrings_NameValueSeparator} - // RLebeau 11/8/16: Calling Pos() with a Char as input creates a temporary - // String. Normally this is fine, but profiling reveils this to be a big - // bottleneck for code that makes a lot of calls to Pos() in a loop, so we - // will scan through the string looking for the character without a conversion... - // - // LPos := IndyPos(LTemp.NameValueSeparator, LStr); - // - LChar := LTemp.NameValueSeparator; - LPos := 0; - for J := 1 to Length(LStr) do begin - //if CharEquals(LStr, LPos, LChar) then begin - if LStr[J] = LChar then begin - LPos := J; - Break; - end; - end; - {$ELSE} - LPos := IndyPos('=', LStr); {do not localize} - {$ENDIF} - if LPos > 0 then begin - LTemp[i] := WWWFormUrlEncode(LTemp.Names[i], AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF}) - + '=' {do not localize} - + WWWFormUrlEncode(IndyValueFromIndex(LTemp, i), AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF}); - end else begin - LTemp[i] := WWWFormUrlEncode(LStr, AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF}); - end; - end; - Result := EncodeLineBreaks(LTemp); - finally - LTemp.Free; - end; - end else begin - Result := EncodeLineBreaks(ASource); - end; - end else begin - Result := ''; - end; -end; - -function TIdCustomHTTP.Post(AURL: string; const ASourceFile: String - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; -var - LSource: TIdReadFileExclusiveStream; -begin - LSource := TIdReadFileExclusiveStream.Create(ASourceFile); - try - Result := Post(AURL, LSource{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); - finally - FreeAndNil(LSource); - end; -end; - -procedure TIdCustomHTTP.Post(AURL: string; const ASourceFile: String; AResponseContent: TStream); -var - LSource: TStream; -begin - LSource := TIdReadFileExclusiveStream.Create(ASourceFile); - try - Post(AURL, LSource, AResponseContent); - finally - FreeAndNil(LSource); - end; -end; - -procedure TIdCustomHTTP.Post(AURL: string; ASource: TStrings; AResponseContent: TStream; - AByteEncoding: IIdTextEncoding = nil - {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF} - ); -var - LParams: TMemoryStream; -begin - // Usual posting request have default ContentType is application/x-www-form-urlencoded - if (Request.ContentType = '') or IsContentTypeHtml(Request) then begin - Request.ContentType := 'application/x-www-form-urlencoded'; {do not localize} - end; - - if ASource <> nil then - begin - LParams := TMemoryStream.Create; - try - WriteStringToStream(LParams, SetRequestParams(ASource, AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF})); - LParams.Position := 0; - Post(AURL, LParams, AResponseContent); - finally - FreeAndNil(LParams); - end; - end else begin - Post(AURL, TStream(nil), AResponseContent); - end; -end; - -function TIdCustomHTTP.Post(AURL: string; ASource: TStrings; AByteEncoding: IIdTextEncoding = nil - {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; -var - LResponse: TMemoryStream; -begin - LResponse := TMemoryStream.Create; - try - Post(AURL, ASource, LResponse, AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF}); - LResponse.Position := 0; - Result := ReadStringAsCharset(LResponse, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); - // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... - finally - FreeAndNil(LResponse); - end; -end; - -function TIdCustomHTTP.Post(AURL: string; ASource: TStream - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; -var - LResponse: TMemoryStream; -begin - LResponse := TMemoryStream.Create; - try - Post(AURL, ASource, LResponse); - LResponse.Position := 0; - Result := ReadStringAsCharset(LResponse, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); - // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... - finally - FreeAndNil(LResponse); - end; -end; - -procedure TIdCustomHTTP.Put(AURL: string; ASource, AResponseContent: TStream); -begin - DoRequest(Id_HTTPMethodPut, AURL, ASource, AResponseContent, []); -end; - -function TIdCustomHTTP.Put(AURL: string; ASource: TStream - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; -var - LResponse: TMemoryStream; -begin - LResponse := TMemoryStream.Create; - try - Put(AURL, ASource, LResponse); - LResponse.Position := 0; - Result := ReadStringAsCharset(LResponse, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); - // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... - finally - FreeAndNil(LResponse); - end; -end; - -function TIdCustomHTTP.Get(AURL: string - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; -begin - Result := Get(AURL, []{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); -end; - -function TIdCustomHTTP.Trace(AURL: string - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; -var - LResponse: TMemoryStream; -begin - LResponse := TMemoryStream.Create; - try - Trace(AURL, LResponse); - LResponse.Position := 0; - Result := ReadStringAsCharset(LResponse, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); - // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... - finally - FreeAndNil(LResponse); - end; -end; - -function TIdCustomHTTP.DoOnRedirect(var Location: string; var VMethod: TIdHTTPMethod; RedirectCount: integer): boolean; -begin - // TODO: convert relative URLs to full URLs here... - Result := HandleRedirects; - if Assigned(FOnRedirect) then begin - FOnRedirect(Self, Location, RedirectCount, Result, VMethod); - end; -end; - -procedure TIdCustomHTTP.SetCookies(AURL: TIdURI; ARequest: TIdHTTPRequest); -var - // under ARC, convert a weak reference to a strong reference before working with it - LCookieManager: TIdCookieManager; -begin - if AllowCookies then begin - LCookieManager := FCookieManager; - if Assigned(LCookieManager) then - begin - // Send secure cookies only if we have Secured connection - LCookieManager.GenerateClientCookies( - AURL, - TextIsSame(AURL.Protocol, 'HTTPS'), {do not localize} - ARequest.RawHeaders); - end; - end; -end; - -// This function sets the Host and Port and returns a boolean depending on -// whether a PROXY is being used or not. - -function TIdCustomHTTP.SetHostAndPort: TIdHTTPConnectionType; -var - LHost: string; - LPort: Integer; -begin - // First check to see if a Proxy has been specified. - if Length(ProxyParams.ProxyServer) > 0 then begin - if (not TextIsSame(FHost, ProxyParams.ProxyServer)) or (FPort <> ProxyParams.ProxyPort) then begin - if Connected then begin - Disconnect; - end; - end; - LHost := ProxyParams.ProxyServer; - LPort := ProxyParams.ProxyPort; - if TextIsSame(URL.Protocol, 'HTTPS') then begin {do not localize} - Result := ctSSLProxy; - end else begin - Result := ctProxy; - end; - end else begin - if Assigned(Socket) then begin - if Assigned(Socket.Binding) then begin - if URL.IPVersion <> Socket.Binding.IPVersion then begin - if Connected then begin - Disconnect; // get rid of current socket handle - end; - end; - end; - end; - LHost := URL.Host; - LPort := IndyStrToInt(URL.Port, IdPORT_HTTP); - if (not TextIsSame(FHost, LHost)) or (LPort <> FPort) then begin - if Connected then begin - Disconnect; - end; - end; - if TextIsSame(URL.Protocol, 'HTTPS') then begin {do not localize} - Result := ctSSL; - end else begin - Result := ctNormal; - end; - end; - Host := LHost; - Port := LPort; -end; - -// TODO: move the XML charset detector below to the IdGlobalProtocols unit so -// it can be used in other components, like TIdMessageClient and TIdIMAP4... - -type - XmlEncoding = (xmlUCS4BE, xmlUCS4BEOdd, xmlUCS4LE, xmlUCS4LEOdd, - xmlUTF16BE, xmlUTF16LE, xmlUTF8, xmlEBCDIC, xmlUnknown - ); - - XmlBomInfo = record - Charset: String; - BOMLen: Integer; - BOM: UInt32; - BOMMask: UInt32; - end; - - XmlNonBomInfo = record - CharLen: Integer; - FirstChar: UInt32; - LastChar: UInt32; - CharMask: UInt32; - end; - -const - XmlBOMs: array[xmlUCS4BE..xmlUTF8] of XmlBomInfo = ( - (Charset: 'UCS-4BE'; BOMLen: 4; BOM: $0000FEFF; BOMMask: $FFFFFFFF), {do not localize} - (Charset: ''; {UCS-4} BOMLen: 4; BOM: $0000FFFE; BOMMask: $FFFFFFFF), - (Charset: 'UCS-4LE'; BOMLen: 4; BOM: $FFFE0000; BOMMask: $FFFFFFFF), {do not localize} - (Charset: ''; {UCS-4} BOMLen: 4; BOM: $FEFF0000; BOMMask: $FFFFFFFF), - (Charset: 'UTF-16BE'; BOMLen: 2; BOM: $FEFF0000; BOMMask: $FFFF0000), {do not localize} - (Charset: 'UTF-16LE'; BOMLen: 2; BOM: $FFFE0000; BOMMask: $FFFF0000), {do not localize} - (Charset: 'UTF-8'; BOMLen: 3; BOM: $EFBBBF00; BOMMask: $FFFFFF00) {do not localize} - ); - - XmlNonBOMs: array[xmlUCS4BE..xmlEBCDIC] of XmlNonBomInfo = ( - (CharLen: 4; FirstChar: $0000003C; LastChar: $0000003E; CharMask: $FFFFFFFF), - (CharLen: 4; FirstChar: $00003C00; LastChar: $00003E00; CharMask: $FFFFFFFF), - (CharLen: 4; FirstChar: $3C000000; LastChar: $3E000000; CharMask: $FFFFFFFF), - (CharLen: 4; FirstChar: $003C0000; LastChar: $003E0000; CharMask: $FFFFFFFF), - (CharLen: 2; FirstChar: $003C003F; LastChar: $003E0000; CharMask: $FFFF0000), - (CharLen: 2; FirstChar: $3C003F00; LastChar: $3E000000; CharMask: $FFFF0000), - (CharLen: 1; FirstChar: $3C3F786D; LastChar: $3E000000; CharMask: $FF000000), - (CharLen: 1; FirstChar: $4C6FA794; LastChar: $6E000000; CharMask: $FF000000) - ); - - XmlUCS4AsciiIndex: array[xmlUCS4BE..xmlUCS4LEOdd] of Integer = (3, 2, 0, 1); - - // RLebeau: only interested in EBCDIC ASCII characters that are allowed in - // an XML declaration, we'll treat everything else as #01 for now... - XmlEBCDICTable: array[Byte] of Char = ( - { -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -A -B -C -D -E -F } - {0-} #01, #01, #01, #01, #01, #09, #01, #01, #01, #01, #01, #01, #01, #13, #01, #01, {do not localize} - {1-} #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, {do not localize} - {2-} #01, #01, #01, #01, #01, #10, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, {do not localize} - {3-} #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, {do not localize} - {4-} ' ', #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, '.', '<', #01, #01, #01, {do not localize} - {5-} #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, {do not localize} - {6-} '-', #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, '_', '>', '?', {do not localize} - {7-} #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #27, '=', '"', {do not localize} - {8-} #01, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', #01, #01, #01, #01, #01, #01, {do not localize} - {9-} #01, 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', #01, #01, #01, #01, #01, #01, {do not localize} - {A-} #01, #01, 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', #01, #01, #01, #01, #01, #01, {do not localize} - {B-} #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, {do not localize} - {C-} #01, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', #01, #01, #01, #01, #01, #01, {do not localize} - {D-} #01, 'J', 'K', 'L', 'N', 'N', 'O', 'P', 'Q', 'R', #01, #01, #01, #01, #01, #01, {do not localize} - {E-} #01, #01, 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', #01, #01, #01, #01, #01, #01, {do not localize} - {F-} '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', #01, #01, #01, #01, #01, #01 {do not localize} - ); - -function DetectXmlCharset(AStream: TStream): String; -var - Buffer: TIdBytes; - InBuf, StreamPos, CurPos: TIdStreamSize; - XmlDec, XmlEnc: String; - {$IFDEF STRING_IS_IMMUTABLE} - LSB: TIdStringBuilder; - {$ENDIF} - I, Len: Integer; - Enc: XmlEncoding; - Signature: UInt32; - - function BufferToUInt32: UInt32; - begin - Result := (UInt32(Buffer[0]) shl 24) or - (UInt32(Buffer[1]) shl 16) or - (UInt32(Buffer[2]) shl 8) or - UInt32(Buffer[3]); - end; - -begin - // XML's default encoding is UTF-8 unless specified otherwise, either - // by a BOM or an explicit "encoding" in the XML's prolog... - - Result := 'UTF-8'; {do not localize} - - if AStream = nil then begin - Exit; - end; - - StreamPos := AStream.Position; - try - AStream.Position := 0; - - SetLength(Buffer, 4); - FillBytes(Buffer, 4, $00); - - InBuf := ReadTIdBytesFromStream(AStream, Buffer, 4); - if InBuf < 3 then begin - Exit; - end; - - Signature := BufferToUInt32; - - // check for known BOMs first... - - for Enc := Low(XmlBOMs) to High(XmlBOMs) do begin - if (Signature and XmlBOMs[Enc].BOMMask) = XmlBOMs[Enc].BOM then begin - Inc(StreamPos, XmlBOMs[Enc].BOMLen); - Result := XmlBOMs[Enc].Charset; - Exit; - end; - end; - - // check for non-BOM'ed encodings now... - - if InBuf <> 4 then begin - Exit; - end; - - XmlDec := ''; - - for Enc := Low(XmlNonBOMs) to High(XmlNonBOMs) do begin - if Signature = XmlNonBOMs[Enc].FirstChar then begin - FillBytes(Buffer, 4, $00); - while (AStream.Size - AStream.Position) >= XmlNonBOMs[Enc].CharLen do - begin - ReadTIdBytesFromStream(AStream, Buffer, XmlNonBOMs[Enc].CharLen); - Signature := BufferToUInt32; - if (Signature and XmlNonBOMs[Enc].CharMask) = XmlNonBOMs[Enc].LastChar then - begin - CurPos := AStream.Position; - AStream.Position := 0; - case Enc of - xmlUCS4BE, xmlUCS4LE, xmlUCS4BEOdd, xmlUCS4LEOdd: begin - // TODO: create UCS-4 IIdTextEncoding implementations... - Len := CurPos div XmlNonBOMs[Enc].CharLen; - {$IFDEF STRING_IS_IMMUTABLE} - LSB := TIdStringBuilder.Create(Len); - {$ELSE} - SetLength(XmlDec, Len); - {$ENDIF} - for I := 1 to Len do begin - ReadTIdBytesFromStream(AStream, Buffer, XmlNonBOMs[Enc].CharLen); - {$IFDEF STRING_IS_IMMUTABLE} - LSB.Append(Char(Buffer[XmlUCS4AsciiIndex[Enc]])); - {$ELSE} - XmlDec[I] := Char(Buffer[XmlUCS4AsciiIndex[Enc]]); - {$ENDIF} - end; - {$IFDEF STRING_IS_IMMUTABLE} - XmlDec := LSB.ToString; - LSB := nil; - {$ENDIF} - end; - xmlUTF16BE: begin - XmlDec := ReadStringFromStream(AStream, CurPos, IndyTextEncoding_UTF16BE); - end; - xmlUTF16LE: begin - XmlDec := ReadStringFromStream(AStream, CurPos, IndyTextEncoding_UTF16LE); - end; - xmlUTF8: begin - XmlDec := ReadStringFromStream(AStream, CurPos, IndyTextEncoding_UTF8); - end; - xmlEBCDIC: begin - // TODO: create an EBCDIC IIdTextEncoding implementation... - {$IFDEF STRING_IS_IMMUTABLE} - Len := ReadTIdBytesFromStream(AStream, Buffer, CurPos); - LSB := TStringBuilder.Create(Len); - for I := 0 to Len-1 do begin - LSB.Append(XmlEBCDICTable[Buffer[I]]); - end; - XmlDec := LSB.ToString; - {$ELSE} - XmlDec := ReadStringFromStream(AStream, CurPos, IndyTextEncoding_8Bit); - for I := 1 to Length(XmlDec) do begin - XmlDec[I] := XmlEBCDICTable[Byte(XmlDec[I])]; - end; - {$ENDIF} - end; - end; - Break; - end; - end; - Break; - end; - end; - - if XmlDec = '' then begin - Exit; - end; - - I := Pos('encoding', XmlDec); {do not localize} - if I = 0 then begin - Exit; - end; - - XmlDec := TrimLeft(Copy(XmlDec, I+8, MaxInt)); - if not CharEquals(XmlDec, 1, '=') then begin {do not localize} - Exit; - end; - - XmlDec := TrimLeft(Copy(XmlDec, 2, MaxInt)); - if XmlDec = '' then begin - Exit; - end; - - if XmlDec[1] = #$27 then begin - XmlDec := Copy(XmlDec, 2, MaxInt); - XmlEnc := Fetch(XmlDec, #$27); - end - else if XmlDec[1] = '"' then begin - XmlDec := Copy(XmlDec, 2, MaxInt); - XmlEnc := Fetch(XmlDec, '"'); - end; - - XmlEnc := Trim(XmlEnc); - if XmlEnc = '' then begin - Exit; - end; - - Result := XmlEnc; - finally - AStream.Position := StreamPos; - end; -end; - -procedure TIdCustomHTTP.ReadResult(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); -var - LS: TStream; - LOrigStream, LTmpStream : TStream; - LParseMeth : Integer; - //0 - no parsing - //1 - html - //2 - xml - LCreateTmpContent : Boolean; - LDecMeth : Integer; - //0 - no compression was used or we can't support that feature - //1 - deflate - //2 - gzip - // under ARC, convert a weak reference to a strong reference before working with it - LCompressor: TIdZLibCompressorBase; - - function CheckForPendingData(ATimeout: Integer): Boolean; - begin - Result := not IOHandler.InputBufferIsEmpty; - if not Result then begin - IOHandler.CheckForDataOnSource(ATimeout); - Result := not IOHandler.InputBufferIsEmpty; - end; - end; - - function ShouldRead: Boolean; - var - CanRead: Boolean; - begin - Result := False; - if IndyPos('chunked', LowerCase(AResponse.TransferEncoding)) > 0 then begin {do not localize} - CanRead := not (hoNoReadChunked in FOptions); - end - else if AResponse.HasContentLength then begin - CanRead := AResponse.ContentLength > 0; // If chunked then this is also 0 - end - else if IsHeaderMediaType(AResponse.ContentType, 'multipart') then begin {do not localize} - CanRead := not (hoNoReadMultipartMIME in FOptions); - end - else begin - CanRead := True; - end; - if CanRead then - begin - // DO NOT READ IF THE REQUEST IS HEAD!!! - // The server is supposed to send a 'Content-Length' header without sending - // the actual data. 1xx, 204, and 304 replies are not supposed to contain - // entity bodies, either... - if TextIsSame(ARequest.Method, Id_HTTPMethodHead) or - ({TextIsSame(ARequest.Method, Id_HTTPMethodPost) and} TextIsSame(ARequest.MethodOverride, Id_HTTPMethodHead)) or - // TODO: check for 'X-HTTP-Method' and 'X-METHOD-OVERRIDE' request headers as well... - ((AResponse.ResponseCode div 100) = 1) or - (AResponse.ResponseCode = 204) or - (AResponse.ResponseCode = 304) then - begin - // Have noticed one case where a non-conforming server did send an - // entity body in response to a HEAD request. If requested, ignore - // anything the server may send by accident - if not (hoWaitForUnexpectedData in FOptions) then begin - Exit; - end; - Result := CheckForPendingData(100); - end - else if (AResponse.ResponseCode div 100) = 3 then - begin - // This is a workaround for buggy HTTP 1.1 servers which - // does not return any body with 302 response code - Result := CheckForPendingData(5000); - end else begin - Result := True; - end; - end; - end; - - function ChunkSize: integer; - var - j: Integer; - s: string; - begin - s := InternalReadLn; - j := IndyPos(';', s); {do not localize} - if j > 0 then begin - s := Copy(s, 1, j - 1); - end; - Result := IndyStrToInt('$' + Trim(s), 0); {do not localize} - end; - - procedure ReadChunked; - var - LSize: Integer; - LTrailHeader: String; - LChunk : TIdBytes; - begin - DoStatus(hsStatusText, [RSHTTPChunkStarted]); - BeginWork(wmRead); - try - LSize := ChunkSize; - while LSize <> 0 do begin - // TODO: fire OnChunkReceived even if LS is nil? This way, the caller - // can choose to pass AContentStream=nil and rely solely on OnChunkReceived - // in cases where a chunked response is expected up front, like in - // server-side pushes... - if Assigned(LS) then begin - if Assigned(FOnChunkReceived) then begin - SetLength(LChunk, LSize); - IOHandler.ReadBytes(LChunk, LSize, False); - if Assigned(FOnChunkReceived) then begin - FOnChunkReceived(Self, LChunk); - end; - WriteTIdBytesToStream(LS, LChunk); - end else begin - IOHandler.ReadStream(LS, LSize); - end; - end else begin - IOHandler.Discard(LSize); - end; - InternalReadLn; // CRLF at end of chunk data - LSize := ChunkSize; - end; - // read trailer headers - LTrailHeader := InternalReadLn; - while LTrailHeader <> '' do begin - AResponse.RawHeaders.Add(LTrailHeader); - LTrailHeader := InternalReadLn; - end; - finally - EndWork(wmRead); - end; - end; - - procedure ReadMIME; - var - LMIMEBoundary: TIdBytes; - LIndex: Integer; - LSize: Integer; - begin - LMIMEBoundary := ToBytes('--' + ExtractHeaderSubItem(AResponse.ContentType, 'boundary', QuoteHTTP) + '--'); - BeginWork(wmRead); - try - try - repeat - LIndex := IOHandler.InputBuffer.IndexOf(LMIMEBoundary); - if LIndex <> -1 then - begin - LSize := LIndex + Length(LMIMEBoundary); - if Assigned(LS) then begin - // TODO: use TIdBuffer.ExtractToStream() instead, bypassing the - // overhead of TIdIOHandler.ReadStream() allocating a local buffer - // and calling IOHandler.ReadBytes() to fill that buffer in even - // multiples of the IOHandler's RecvBufferSize. The data we want - // is already in the Buffer's memory, so just read it directly... - // - // IOHandler.InputBuffer.ExtractToStream(LS, LSize); - IOHandler.ReadStream(LS, LSize); - end else begin - IOHandler.Discard(LSize); - end; - InternalReadLn; // CRLF at end of boundary - Break; - end; - LSize := IOHandler.InputBuffer.Size - (Length(LMIMEBoundary)-1); - if LSize > 0 then begin - if Assigned(LS) then begin - // TODO: use TIdBuffer.ExtractToStream() instead, bypassing the - // overhead of TIdIOHandler.ReadStream() allocating a local buffer - // and calling IOHandler.ReadBytes() to fill that buffer in even - // multiples of the IOHandler's RecvBufferSize. The data we want - // is already in the Buffer's memory, so just read it directly... - // - // IOHandler.InputBuffer.ExtractToStream(LS, LSize); - IOHandler.ReadStream(LS, LSize); - end else begin - IOHandler.Discard(LSize); - end; - end; - IOHandler.CheckForDataOnSource; - IOHandler.CheckForDisconnect(True, True); - until False; - except - on E: EIdConnClosedGracefully do begin - if Assigned(LS) then begin - IOHandler.InputBuffer.ExtractToStream(LS); - end else begin - IOHandler.InputBuffer.Clear; - end; - end; - end; - finally - EndWork(wmRead); - end; - end; - -begin - if not ShouldRead then begin - Exit; - end; - - LParseMeth := 0; - LDecMeth := 0; - - if Assigned(AResponse.ContentStream) then begin - if IsContentTypeHtml(AResponse) then begin - if not (hoNoParseMetaHTTPEquiv in FOptions) then begin - LParseMeth := 1; - end; - end - else if IsContentTypeAppXml(Response) then begin - if not (hoNoParseXmlCharset in FOptions) then begin - LParseMeth := 2; - end; - end; - end; - - // under ARC, AResponse.ContentStream uses weak referencing, so need to - // use local strong references to keep the streams alive... - LOrigStream := AResponse.ContentStream; - LCreateTmpContent := (LParseMeth <> 0) and not (LOrigStream is TCustomMemoryStream); - if LCreateTmpContent then begin - LTmpStream := TMemoryStream.Create; - end else begin - LTmpStream := nil; - end; - - try - if LCreateTmpContent then begin - AResponse.ContentStream := LTmpStream; - end; - - // we need to determine what type of decompression may need to be used - // before we read from the IOHandler. If there is compression, then we - // use a local stream to download the compressed data and decompress it. - // If no compression is used, ContentStream will be used directly - - LCompressor := Compressor; - if Assigned(AResponse.ContentStream) then begin - if Assigned(LCompressor) and LCompressor.IsReady then begin - LDecMeth := PosInStrArray(AResponse.ContentEncoding, ['deflate', 'gzip'], False) + 1; {do not localize} - end; - if LDecMeth > 0 then begin - LS := TMemoryStream.Create; - end else begin - LS := AResponse.ContentStream; - end; - end else - begin - LS := nil; - end; - - try - if IndyPos('chunked', LowerCase(AResponse.TransferEncoding)) > 0 then begin {do not localize} - ReadChunked; - end - else if AResponse.HasContentLength then begin - if AResponse.ContentLength > 0 then begin// If chunked then this is also 0 - try - if Assigned(LS) then begin - IOHandler.ReadStream(LS, AResponse.ContentLength); - end else begin - IOHandler.Discard(AResponse.ContentLength); - end; - except - // should this be caught here? We are being told the size, so a - // premature disconnect should be an error, right? - on E: EIdConnClosedGracefully do begin end; - end; - end; - end - else if IsHeaderMediaType(AResponse.ContentType, 'multipart') then begin {do not localize} - ReadMIME; - end else begin - if Assigned(LS) then begin - IOHandler.ReadStream(LS, -1, True); - end else begin - IOHandler.DiscardAll; - end; - end; - if LDecMeth > 0 then begin - LS.Position := 0; - case LDecMeth of - 1 : LCompressor.DecompressDeflateStream(LS, AResponse.ContentStream); - 2 : LCompressor.DecompressGZipStream(LS, AResponse.ContentStream); - end; - end; - finally - if LDecMeth > 0 then begin - FreeAndNil(LS); - end; - end; - case LParseMeth of - 1: begin - // RLebeau 1/30/2012: parse HTML tags, update Response.CharSet ... - AResponse.ProcessMetaHTTPEquiv; - end; - 2: begin - // the media type is not a 'text/...' based XML type, so ignore the - // charset from the headers, if present, and parse the XML itself... - AResponse.CharSet := DetectXmlCharset(AResponse.ContentStream); - end; - else - // TODO: if a Charset is not specified, return an appropriate value - // that is registered with IANA for the reported ContentType... - end; - finally - if LCreateTmpContent then - begin - try - LOrigStream.CopyFrom(LTmpStream, 0); - finally - {$IFNDEF USE_OBJECT_ARC} - LTmpStream.Free; - {$ENDIF} - AResponse.ContentStream := LOrigStream; - end; - end; - end; -end; - -const - Requires_HTTP_1_1: array[0..4] of String = (Id_HTTPMethodTrace, Id_HTTPMethodPut, Id_HTTPMethodOptions, Id_HTTPMethodDelete, Id_HTTPMethodPatch); - Requires_Content_Length: array[0..1] of String = (Id_HTTPMethodPost, Id_HTTPMethodPut); - -procedure TIdCustomHTTP.PrepareRequest(ARequest: TIdHTTPRequest); -var - LURI: TIdURI; - LHost: string; -begin - LURI := TIdURI.Create(ARequest.URL); - - try - if Length(LURI.Username) > 0 then begin - ARequest.Username := LURI.Username; - ARequest.Password := LURI.Password; - end; - - FURI.Username := ARequest.Username; - FURI.Password := ARequest.Password; - - FURI.Path := ProcessPath(FURI.Path, LURI.Path); - FURI.Document := LURI.Document; - FURI.Params := LURI.Params; - - if Length(LURI.Host) > 0 then begin - FURI.Host := LURI.Host; - end; - - if Length(LURI.Protocol) > 0 then begin - FURI.Protocol := LURI.Protocol; - end - // non elegant solution - to be recoded, only for pointing the bug / GREGOR - else if TextIsSame(FURI.Protocol, 'https') then begin {do not localize} - FURI.Protocol := 'https'; {do not localize} - end - else begin - FURI.Protocol := 'http'; {do not localize} - end; - - if Length(LURI.Port) > 0 then begin - FURI.Port := LURI.Port; - end - else if TextIsSame(LURI.Protocol, 'http') then begin {do not localize} - FURI.Port := IntToStr(IdPORT_HTTP); - end - else if TextIsSame(LURI.Protocol, 'https') then begin {do not localize} - FURI.Port := IntToStr(IdPORT_https); - end - else if Length(FURI.Port) = 0 then begin - raise EIdUnknownProtocol.Create(RSHTTPUnknownProtocol); - end; - - if (TextIsSame(ARequest.Method, Id_HTTPMethodOptions) or TextIsSame(ARequest.MethodOverride, Id_HTTPMethodOptions)) - and TextIsSame(LURI.Document, '*') then {do not localize} - begin - ARequest.URL := LURI.Document; - end else begin - // The URL part is not URL encoded at this place - ARequest.URL := URL.GetPathAndParams; - end; - - ARequest.IPVersion := LURI.IPVersion; - FURI.IPVersion := ARequest.IPVersion; - - // Check for valid HTTP request methods - if (PosInStrArray(ARequest.Method, Requires_HTTP_1_1, False) > -1) or - (PosInStrArray(ARequest.MethodOverride, Requires_HTTP_1_1, False) > -1) then - begin - if ProtocolVersion <> pv1_1 then begin - raise EIdException.Create(RSHTTPMethodRequiresVersion); // TODO: create a new Exception class for this - end; - end; - - if Assigned(ARequest.Source) then begin - ARequest.ContentLength := ARequest.Source.Size; - end - else if PosInStrArray(ARequest.Method, Requires_Content_Length, False) > -1 then begin - ARequest.ContentLength := 0; - end else begin - ARequest.ContentLength := -1; - end; - - // RLebeau: wrap an IPv6 address in brackets, per RFC 2732, and RFC 3986 section 3.2.2... - if (FURI.IPVersion = Id_IPv6) and (MakeCanonicalIPv6Address(FURI.Host) <> '') then begin - LHost := '[' + FURI.Host + ']'; {do not localize} - end else begin - LHost := FURI.Host; - end; - - if (TextIsSame(FURI.Protocol, 'http') and (FURI.Port = IntToStr(IdPORT_HTTP))) or {do not localize} - (TextIsSame(FURI.Protocol, 'https') and (FURI.Port = IntToStr(IdPORT_https))) then {do not localize} - begin - ARequest.Host := LHost; - end else begin - ARequest.Host := LHost + ':' + FURI.Port; {do not localize} - end; - finally - FreeAndNil(LURI); // Free URI Object - end; -end; - -procedure TIdCustomHTTP.CheckAndConnect(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); -begin - if not AResponse.KeepAlive then begin - Disconnect; - end; - - if Assigned(IOHandler) then begin - IOHandler.InputBuffer.Clear; - end; - - CheckForGracefulDisconnect(False); - - if not Connected then try - IPVersion := FURI.IPVersion; - - case ARequest.UseProxy of - ctNormal, ctProxy: - begin - if (IOHandler is TIdSSLIOHandlerSocketBase) then begin - TIdSSLIOHandlerSocketBase(IOHandler).PassThrough := True; - TIdSSLIOHandlerSocketBase(IOHandler).URIToCheck := FURI.URI; - end; - end; - - ctSSL, ctSSLProxy: - begin - // if an IOHandler has not been assigned yet, try to create a default SSL IOHandler object - // - // TODO: if an IOHandler has been assigned, but is not an SSL IOHandler, - // release it and try to create a default SSL IOHandler object? - // - if IOHandler = nil then begin - IOHandler := TIdIOHandler.TryMakeIOHandler(TIdSSLIOHandlerSocketBase, Self); - if IOHandler = nil then begin - raise EIdIOHandlerPropInvalid.Create(RSIOHandlerPropInvalid); - end; - ManagedIOHandler := True; - IOHandler.OnStatus := OnStatus; // TODO: assign DoStatus() instead of the handler directly... - end - else if not (IOHandler is TIdSSLIOHandlerSocketBase) then begin - raise EIdIOHandlerPropInvalid.Create(RSIOHandlerPropInvalid); - end; - TIdSSLIOHandlerSocketBase(IOHandler).URIToCheck := FURI.URI; - TIdSSLIOHandlerSocketBase(IOHandler).PassThrough := (ARequest.UseProxy = ctSSLProxy); - end; - end; - - Connect; - except - on E: EIdSSLProtocolReplyError do begin - Disconnect; - raise; - end; - end; -end; - -procedure TIdCustomHTTP.ConnectToHost(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); -var - LLocalHTTP: TIdHTTPProtocol; - LUseConnectVerb: Boolean; - // under ARC, convert a weak reference to a strong reference before working with it - LCompressor: TIdZLibCompressorBase; - LOldProxy: TIdHTTPConnectionType; - LNewDest: string; -begin - // RLebeau 5/29/2018: before doing anything else, clear the InputBuffer. If a - // previous HTTPS request through an SSL/TLS proxy fails due to a user-defined - // OnVerifyPeer handler returning False, the proxy tunnel is still established, - // but the underlying socket may be closed, and unread data left behind in the - // InputBuffer that will cause Connected() below to return True when it should - // be False instead. This leads to a situation where TIdHTTP can skip sending - // a CONNECT request when it creates a new socket connection to the proxy, but - // send an unencrypted HTTP request to the proxy, which may then get forwarded - // to the HTTPS server over a previously cached SSL/TLS tunnel... - - if Assigned(IOHandler) then begin - IOHandler.InputBuffer.Clear; - end; - - LNewDest := URL.Host + ':' + URL.Port; - - LOldProxy := ARequest.FUseProxy; - ARequest.FUseProxy := SetHostAndPort; - - if ARequest.UseProxy <> LOldProxy then begin - if Connected then begin - Disconnect; - end; - end - else if (ARequest.UseProxy = ctSSLProxy) and (not TextIsSame(ARequest.Destination, LNewDest)) then begin - if Connected then begin - Disconnect; - end; - end; - - ARequest.Destination := LNewDest; - - LUseConnectVerb := False; - - case ARequest.UseProxy of - ctNormal, ctSSL: - begin - if (ProtocolVersion = pv1_0) and (Length(ARequest.Connection) = 0) then - begin - ARequest.Connection := 'keep-alive'; {do not localize} - end; - end; - ctSSLProxy: - begin - // if already connected to an SSL proxy, DO NOT send another - // CONNECT request, as it will be sent directly to the target - // HTTP server and not to the proxy! - LUseConnectVerb := not Connected; - end; - ctProxy: - begin - ARequest.URL := FURI.URI; - if (ProtocolVersion = pv1_0) and (Length(ARequest.Connection) = 0) then - begin - // TODO: per RFC 7230: - // "clients are encouraged not to send the Proxy-Connection header field in any requests." - ARequest.ProxyConnection := 'keep-alive'; {do not localize} - end; - if hoNonSSLProxyUseConnectVerb in FOptions then begin - // if already connected to a proxy, DO NOT send another CONNECT - // request, as it will be sent directly to the target HTTP server - // and not to the proxy! - LUseConnectVerb := not Connected; - end; - end; - end; - - LCompressor := FCompressor; - if Assigned(LCompressor) and LCompressor.IsReady then begin - if IndyPos('deflate', ARequest.AcceptEncoding) = 0 then {do not localize} - begin - if ARequest.AcceptEncoding <> '' then begin {do not localize} - ARequest.AcceptEncoding := ARequest.AcceptEncoding + ', deflate'; {do not localize} - end else begin - ARequest.AcceptEncoding := 'deflate'; {do not localize} - end; - end; - if IndyPos('gzip', ARequest.AcceptEncoding) = 0 then {do not localize} - begin - if ARequest.AcceptEncoding <> '' then begin {do not localize} - ARequest.AcceptEncoding := ARequest.AcceptEncoding + ', gzip'; {do not localize} - end else begin - ARequest.AcceptEncoding := 'gzip'; {do not localize} - end; - end; - end else - begin - // TODO: if ARequest.AcceptEncoding is asking for deflate/gzip compression, - // remove it, unless the caller is prepared to decompress the data manually... - end; - {$IFDEF USE_OBJECT_ARC}LCompressor := nil;{$ENDIF} - - // RLebeau 1/10/2015: if AcceptEncoding is blank, DON'T set it to 'identity'! - // Oddly, some faulty servers do not understand 'identity' when explicitly - // stated. 'identity' is the default behavior when no "Accept-Encoding" header - // is present, so just let the server fallback to that normally... - if ARequest.AcceptEncoding <> '' then begin - if IndyPos('identity', ARequest.AcceptEncoding) = 0 then begin {do not localize} - ARequest.AcceptEncoding := ARequest.AcceptEncoding + ', identity'; {do not localize} - end; - // TODO: if AcceptEncoding is 'identity', set it to a blank string? - { - if TextIsSame(ARequest.AcceptEncoding, 'identity') then begin {do not localize - ARequest.AcceptEncoding := ''; - end; - } - end; - - if LUseConnectVerb then begin - LLocalHTTP := CreateProtocol; - try - LLocalHTTP.Request.UserAgent := ARequest.UserAgent; - LLocalHTTP.Request.Host := ARequest.Host; - LLocalHTTP.Request.Pragma := 'no-cache'; {do not localize} - LLocalHTTP.Request.URL := ARequest.Destination; - LLocalHTTP.Request.Method := Id_HTTPMethodConnect; - // TODO: per RFC 7230: - // "clients are encouraged not to send the Proxy-Connection header field in any requests." - LLocalHTTP.Request.ProxyConnection := 'keep-alive'; {do not localize} - LLocalHTTP.Request.FUseProxy := ARequest.UseProxy; - - // leaving LLocalHTTP.Response.ContentStream set to nil so response data is discarded without wasting memory - try - repeat - CheckAndConnect(LLocalHTTP.Request, LLocalHTTP.Response); - LLocalHTTP.BuildAndSendRequest(nil); - - LLocalHTTP.Response.ResponseText := InternalReadLn; - if Length(LLocalHTTP.Response.ResponseText) = 0 then begin - // Support for HTTP responses without status line and headers - LLocalHTTP.Response.ResponseText := 'HTTP/1.0 200 OK'; {do not localize} - LLocalHTTP.Response.Connection := 'close'; {do not localize} - end else begin - LLocalHTTP.RetrieveHeaders(MaxHeaderLines); - ProcessCookies(LLocalHTTP.Request, LLocalHTTP.Response); - end; - - if (LLocalHTTP.Response.ResponseCode div 100) = 2 then begin - // Connection established - if (ARequest.UseProxy = ctSSLProxy) and (IOHandler is TIdSSLIOHandlerSocketBase) then begin - TIdSSLIOHandlerSocketBase(IOHandler).PassThrough := False; - end; - Break; - end; - - case LLocalHTTP.ProcessResponse([]) of - wnAuthRequest: - begin - LLocalHTTP.Request.URL := ARequest.Destination; - end; - wnReadAndGo: - begin - ReadResult(LLocalHTTP.Request, LLocalHTTP.Response); - FAuthRetries := 0; - FAuthProxyRetries := 0; - end; - wnGoToURL: - begin - FAuthRetries := 0; - FAuthProxyRetries := 0; - end; - wnJustExit: - begin - Break; - end; - wnDontKnow: - begin - raise EIdException.Create(RSHTTPNotAcceptable); // TODO: create a new Exception class for this - end; - end; - until False; - except - raise; - // TODO: Add property that will contain the error messages. - end; - finally - FreeAndNil(LLocalHTTP); - end; - end else begin - CheckAndConnect(ARequest, AResponse); - end; - - FHTTPProto.BuildAndSendRequest(URL); - - // RLebeau 1/31/2008: in order for TIdWebDAV to post data correctly, don't - // restrict which HTTP methods can post (except logically for GET and HEAD), - // especially since TIdCustomHTTP.PrepareRequest() does not differentiate when - // setting up the 'Content-Length' header ... - - // TODO: when sending an HTTP 1.1 request with an 'Expect: 100-continue' header, - // do not send the Source data until the server replies with a 100 response code, - // or until a timeout occurs if the server does not send a 100... - - if ARequest.Source <> nil then begin - IOHandler.Write(ARequest.Source, 0, False); - end; -end; - -procedure TIdCustomHTTP.SetAllowCookies(AValue: Boolean); -begin - FAllowCookies := AValue; -end; - -procedure TIdCustomHTTP.ProcessCookies(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); -var - LCookies: TStringList; - // under ARC, convert a weak reference to a strong reference before working with it - LCookieManager: TIdCookieManager; -begin - if AllowCookies then - begin - LCookieManager := FCookieManager; - - if not Assigned(LCookieManager) then begin - LCookieManager := TIdCookieManager.Create(Self); - SetCookieManager(LCookieManager); - FImplicitCookieManager := True; - end; - - LCookies := TStringList.Create; - try - AResponse.RawHeaders.Extract('Set-Cookie', LCookies); {do not localize} - AResponse.MetaHTTPEquiv.RawHeaders.Extract('Set-Cookie', LCookies); {do not localize} - LCookieManager.AddServerCookies(LCookies, FURI); - finally - FreeAndNil(LCookies); - end; - end; -end; - -// under ARC, all weak references to a freed object get nil'ed automatically -// so this is mostly redundant -procedure TIdCustomHTTP.Notification(AComponent: TComponent; Operation: TOperation); -begin - if Operation = opRemove then begin - if (AComponent = FCookieManager) then begin - FCookieManager := nil; - FImplicitCookieManager := False; - end - {$IFNDEF USE_OBJECT_ARC} - else if (AComponent = FAuthenticationManager) then begin - FAuthenticationManager := nil; - end else if (AComponent = FCompressor) then begin - FCompressor := nil; - end - {$ENDIF} - ; - end; - inherited Notification(AComponent, Operation); -end; - -procedure TIdCustomHTTP.SetCookieManager(ACookieManager: TIdCookieManager); -var - // under ARC, convert a weak reference to a strong reference before working with it - LCookieManager: TIdCookieManager; -begin - LCookieManager := FCookieManager; - - if LCookieManager <> ACookieManager then - begin - // under ARC, all weak references to a freed object get nil'ed automatically - - if Assigned(LCookieManager) then begin - if FImplicitCookieManager then begin - FCookieManager := nil; - FImplicitCookieManager := False; - IdDisposeAndNil(LCookieManager); - end else begin - {$IFNDEF USE_OBJECT_ARC} - LCookieManager.RemoveFreeNotification(Self); - {$ENDIF} - end; - end; - - FCookieManager := ACookieManager; - FImplicitCookieManager := False; - - {$IFNDEF USE_OBJECT_ARC} - if Assigned(ACookieManager) then begin - ACookieManager.FreeNotification(Self); - end; - {$ENDIF} - end; -end; - -function TIdCustomHTTP.DoOnAuthorization(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse): Boolean; -var - i: Integer; - S: string; - LAuthCls: TIdAuthenticationClass; - LAuth: TIdAuthentication; -begin - Inc(FAuthRetries); - - // TODO: trigger OnSelectAuthorization on every request, or at least if - // FAuthRetries is 1, or the server has sent a new 'WWW-Authenticate' - // list that does not include the class currently assigned... - if not Assigned(ARequest.Authentication) then begin - // Find wich Authentication method is supported from us. - LAuthCls := nil; - - for i := 0 to AResponse.WWWAuthenticate.Count - 1 do begin - S := AResponse.WWWAuthenticate[i]; - LAuthCls := FindAuthClass(Fetch(S)); - if Assigned(LAuthCls) then begin - Break; - end; - end; - - // let the user override us, if desired. - if Assigned(FOnSelectAuthorization) then begin - OnSelectAuthorization(Self, LAuthCls, AResponse.WWWAuthenticate); - end; - - if not Assigned(LAuthCls) then begin - Result := False; - Exit; - end; - - ARequest.Authentication := LAuthCls.Create; - end; - - { - this is commented out as it breaks SSPI and NTLM authentication. it is - normal and expected to get multiple 407 responses during negotiation. - - // Clear password and reset autorization if previous failed - if (AResponse.FResponseCode = 401) then begin - ARequest.Password := ''; - ARequest.Authentication.Reset; - end; - } - - // S.G. 20/10/2003: Added part about the password. Not testing user name as some - // S.G. 20/10/2003: web sites do not require user name, only password. - // - // RLebeau 11/18/2014: what about SSPI? It does not require an explicit - // username/password as it can use the identity of the user token associated - // with the calling thread! - - LAuth := ARequest.Authentication; - LAuth.Username := ARequest.Username; - LAuth.Password := ARequest.Password; - // S.G. 20/10/2003: ToDo: We need to have a marker here to prevent the code to test with the same username/password combo - // S.G. 20/10/2003: if they are picked up from properties. - LAuth.Params.Values['Authorization'] := ARequest.Authentication.Authentication; {do not localize} - LAuth.AuthParams := AResponse.WWWAuthenticate; - - Result := False; - - repeat - case LAuth.Next of - wnAskTheProgram: - begin // Ask the user porgram to supply us with authorization information - if not Assigned(FOnAuthorization) then - begin - Result := False; - Break; - end; - - LAuth.UserName := ARequest.Username; - LAuth.Password := ARequest.Password; - - OnAuthorization(Self, LAuth, Result); - if not Result then begin - Break; - end; - - ARequest.BasicAuthentication := True; - ARequest.Username := LAuth.UserName; - ARequest.Password := LAuth.Password; - end; - wnDoRequest: - begin - Result := True; - Break; - end; - wnFail: - begin - Result := False; - Break; - end; - end; - until False; -end; - -function TIdCustomHTTP.DoOnProxyAuthorization(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse): Boolean; -var - i: Integer; - S: string; - LAuthCls: TIdAuthenticationClass; - LAuth: TIdAuthentication; -begin - Inc(FAuthProxyRetries); - - // TODO: trigger OnSelectProxyAuthorization on every request, or at least if - // FAuthProxyRetries is 1, or the server has sent a new 'Proxy-Authenticate' - // list that does not include the class currently assigned... - if not Assigned(ProxyParams.Authentication) then begin - // Find which Authentication method is supported from us. - LAuthCls := nil; - - for i := 0 to AResponse.ProxyAuthenticate.Count-1 do begin - S := AResponse.ProxyAuthenticate[i]; - LAuthCls := FindAuthClass(Fetch(S)); - if Assigned(LAuthCls) then begin - Break; - end; - end; - - // let the user override us, if desired. - if Assigned(FOnSelectProxyAuthorization) then begin - OnSelectProxyAuthorization(Self, LAuthCls, AResponse.ProxyAuthenticate); - end; - - if not Assigned(LAuthCls) then begin - Result := False; - Exit; - end; - - ProxyParams.Authentication := LAuthCls.Create; - end; - - { - this is commented out as it breaks SSPI and NTLM authentication. it is - normal and expected to get multiple 407 responses during negotiation. - - // Clear password and reset authorization if previous failed - if (AResponse.FResponseCode = 407) then begin - ProxyParams.ProxyPassword := ''; - ProxyParams.Authentication.Reset; - end; - } - - // RLebeau 11/18/2014: Added part about the password. Not testing user name - // as some proxies do not require user name, only password. - // - // RLebeau 11/18/2014: what about SSPI? It does not require an explicit - // username/password as it can use the identity of the user token associated - // with the calling thread! - - LAuth := ProxyParams.Authentication; - LAuth.Username := ProxyParams.ProxyUsername; - LAuth.Password := ProxyParams.ProxyPassword; - // TODO: do we need to set this, like DoOnAuthorization does? - //LAuth.Params.Values['Authorization'] := ProxyParams.Authentication; {do not localize} - LAuth.AuthParams := AResponse.ProxyAuthenticate; - - Result := False; - - repeat - case LAuth.Next of - wnAskTheProgram: // Ask the user porgram to supply us with authorization information - begin - if not Assigned(OnProxyAuthorization) then begin - Result := False; - Break; - end; - - LAuth.Username := ProxyParams.ProxyUsername; - LAuth.Password := ProxyParams.ProxyPassword; - - OnProxyAuthorization(Self, LAuth, Result); - if not Result then begin - Break; - end; - - // TODO: do we need to set this, like DoOnAuthorization does? - //ProxyParams.BasicAuthentication := True; - ProxyParams.ProxyUsername := LAuth.Username; - ProxyParams.ProxyPassword := LAuth.Password; - end; - wnDoRequest: - begin - Result := True; - Break; - end; - wnFail: - begin - Result := False; - Break; - end; - end; - until False; -end; - -function TIdCustomHTTP.GetResponseCode: Integer; -begin - Result := Response.ResponseCode; -end; - -function TIdCustomHTTP.GetResponseText: string; -begin - Result := Response.ResponseText; -end; - -function TIdCustomHTTP.GetResponse: TIdHTTPResponse; -begin - Result := FHTTPProto.Response; -end; - -function TIdCustomHTTP.GetRequest: TIdHTTPRequest; -begin - Result := FHTTPProto.Request; -end; - -function TIdCustomHTTP.GetMetaHTTPEquiv: TIdMetaHTTPEquiv; -begin - Result := Response.MetaHTTPEquiv; -end; - -procedure TIdCustomHTTP.DoOnDisconnected; -var - // under ARC, convert weak references to strong references before working with them - LAuthManager: TIdAuthenticationManager; - LAuth: TIdAuthentication; -begin - // TODO: in order to handle the case where authentications are used when - // keep-alives are in effect, move this logic somewhere more appropriate, - // like at the end of DoRequest()... - - inherited DoOnDisconnected; - - LAuth := Request.Authentication; - if Assigned(LAuth) and (LAuth.CurrentStep = LAuth.Steps) then - begin - LAuthManager := AuthenticationManager; - if Assigned(LAuthManager) then begin - LAuthManager.AddAuthentication(LAuth, URL); - end; - {$IFNDEF USE_OBJECT_ARC} - LAuth.Free; - {$ENDIF} - Request.Authentication := nil; - end; - - LAuth := ProxyParams.Authentication; - if Assigned(LAuth) and (LAuth.CurrentStep = LAuth.Steps) then begin - LAuth.Reset; - end; -end; - -procedure TIdCustomHTTP.SetAuthenticationManager(Value: TIdAuthenticationManager); -begin - {$IFDEF USE_OBJECT_ARC} - // under ARC, all weak references to a freed object get nil'ed automatically - FAuthenticationManager := Value; - {$ELSE} - if FAuthenticationManager <> Value then begin - if Assigned(FAuthenticationManager) then begin - FAuthenticationManager.RemoveFreeNotification(self); - end; - FAuthenticationManager := Value; - if Assigned(FAuthenticationManager) then begin - FAuthenticationManager.FreeNotification(Self); - end; - end; - {$ENDIF} -end; - -{ -procedure TIdCustomHTTP.SetHost(const Value: string); -begin - inherited SetHost(Value); - URL.Host := Value; -end; - -procedure TIdCustomHTTP.SetPort(const Value: integer); -begin - inherited SetPort(Value); - URL.Port := IntToStr(Value); -end; -} -procedure TIdCustomHTTP.SetRequest(Value: TIdHTTPRequest); -begin - FHTTPProto.Request.Assign(Value); -end; - -procedure TIdCustomHTTP.SetProxyParams(AValue: TIdProxyConnectionInfo); -begin - FProxyParameters.Assign(AValue); -end; - -procedure TIdCustomHTTP.Post(AURL: string; ASource: TIdMultiPartFormDataStream; - AResponseContent: TStream); -begin - Assert(ASource<>nil); - Request.ContentType := ASource.RequestContentType; - // TODO: Request.CharSet := ASource.RequestCharSet; - Post(AURL, TStream(ASource), AResponseContent); -end; - -function TIdCustomHTTP.Post(AURL: string; ASource: TIdMultiPartFormDataStream - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} -): string; -begin - Assert(ASource<>nil); - Request.ContentType := ASource.RequestContentType; - // TODO: Request.CharSet := ASource.RequestCharSet; - Result := Post(AURL, TStream(ASource){$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); -end; - -{ TIdHTTPResponse } - -constructor TIdHTTPResponse.Create(AHTTP: TIdCustomHTTP); -begin - inherited Create(AHTTP); - FHTTP := AHTTP; - FResponseCode := -1; - FMetaHTTPEquiv := TIdMetaHTTPEquiv.Create(AHTTP); -end; - -destructor TIdHTTPResponse.Destroy; -begin - FreeAndNil(FMetaHTTPEquiv); - inherited Destroy; -end; - -procedure TIdHTTPResponse.Clear; -begin - inherited Clear; - ResponseText := ''; - FMetaHTTPEquiv.Clear; -end; - -procedure TIdHTTPResponse.ProcessMetaHTTPEquiv; -var - StdValues: TStringList; - I: Integer; - Name: String; -begin - FMetaHTTPEquiv.ProcessMetaHTTPEquiv(ContentStream); - if FMetaHTTPEquiv.RawHeaders.Count > 0 then begin - // TODO: optimize this - StdValues := TStringList.Create; - try - FMetaHTTPEquiv.RawHeaders.ConvertToStdValues(StdValues); - for I := 0 to StdValues.Count-1 do begin - Name := StdValues.Names[I]; - if Name <> '' then begin - RawHeaders.Values[Name] := IndyValueFromIndex(StdValues, I); - end; - end; - finally - StdValues.Free; - end; - ProcessHeaders; - end; - if FMetaHTTPEquiv.CharSet <> '' then begin - FCharSet := FMetaHTTPEquiv.CharSet; - end; -end; - -function TIdHTTPResponse.GetKeepAlive: Boolean; -begin - if FHTTP.Connected then begin - FHTTP.IOHandler.CheckForDisconnect(False); - end; - - // has the connection already been closed? - FKeepAlive := FHTTP.Connected; - - if FKeepAlive then - begin - // did the client request the connection to be closed? - FKeepAlive := not TextIsSame(Trim(FHTTP.Request.Connection), 'CLOSE'); {do not localize} - if FKeepAlive and (FHTTP.Request.UseProxy in [ctProxy, ctSSLProxy]) then begin - FKeepAlive := not TextIsSame(Trim(FHTTP.Request.ProxyConnection), 'CLOSE'); {do not localize} - end; - end; - - if FKeepAlive then - begin - // did the server/proxy say the connection will be closed? - case FHTTP.ProtocolVersion of // TODO: use ResponseVersion instead? - pv1_1: - { By default we assume that keep-alive is used and will close - the connection only if there is "close" } - begin - FKeepAlive := not TextIsSame(Trim(Connection), 'CLOSE'); {do not localize} - if FKeepAlive and (FHTTP.Request.UseProxy in [ctProxy, ctSSLProxy]) then begin - FKeepAlive := not TextIsSame(Trim(ProxyConnection), 'CLOSE'); {do not localize} - end; - end; - pv1_0: - { By default we assume that keep-alive is not used and will keep - the connection only if there is "keep-alive" } - begin - FKeepAlive := TextIsSame(Trim(Connection), 'KEEP-ALIVE') {do not localize} - { or ((ResponseVersion = pv1_1) and (Trim(Connection) = '')) } - ; - if FKeepAlive and (FHTTP.Request.UseProxy in [ctProxy, ctSSLProxy]) then begin - FKeepAlive := TextIsSame(Trim(ProxyConnection), 'KEEP-ALIVE') {do not localize} - { or ((ResponseVersion = pv1_1) and (Trim(ProxyConnection) = '')) } - ; - end; - end; - end; - end; - - Result := FKeepAlive; -end; - -function TIdHTTPResponse.GetResponseCode: Integer; -var - S, Tmp: string; -begin - if FResponseCode = -1 then - begin - S := FResponseText; - Fetch(S); - S := Trim(S); - // RLebeau: IIS supports status codes with decimals in them, but it is not supposed to - // transmit them to clients, which is a violation of RFC 2616. But have seen it happen, - // so check for it... - Tmp := Fetch(S, ' ', False); {do not localize} - S := Fetch(Tmp, '.', False); {do not localize} - FResponseCode := IndyStrToInt(S, -1); - end; - Result := FResponseCode; -end; - -procedure TIdHTTPResponse.SetResponseText(const AValue: String); -var - S: String; - i: TIdHTTPProtocolVersion; -begin - FResponseText := AValue; - FResponseCode := -1; // re-parse the next time it is accessed - FResponseVersion := pv1_0; // default until determined otherwise... - S := Copy(FResponseText, 6, 3); - for i := Low(TIdHTTPProtocolVersion) to High(TIdHTTPProtocolVersion) do begin - if TextIsSame(ProtocolVersionString[i], S) then begin - FResponseVersion := i; - Exit; - end; - end; -end; - -{ TIdHTTPRequest } - -constructor TIdHTTPRequest.Create(AHTTP: TIdCustomHTTP); -begin - inherited Create(AHTTP); - FHTTP := AHTTP; - FUseProxy := ctNormal; - FIPVersion := ID_DEFAULT_IP_VERSION; -end; - -{ TIdHTTPProtocol } - -constructor TIdHTTPProtocol.Create(AConnection: TIdCustomHTTP); -begin - inherited Create; - FHTTP := AConnection; - // Create the headers - FRequest := TIdHTTPRequest.Create(FHTTP); - FResponse := TIdHTTPResponse.Create(FHTTP); -end; - -destructor TIdHTTPProtocol.Destroy; -begin - FreeAndNil(FRequest); - FreeAndNil(FResponse); - inherited Destroy; -end; - -procedure TIdHTTPProtocol.BuildAndSendRequest(AURI: TIdURI); -var - i: Integer; - LBufferingStarted: Boolean; -begin - Response.Clear; - - // needed for Digest authentication, but maybe others as well... - if Assigned(Request.Authentication) then begin - // TODO: include entity body for Digest "auth-int" qop... - Request.Authentication.SetRequest(Request.Method, Request.URL); - end; - - // TODO: disable header folding for HTTP 1.0 requests - Request.SetHeaders; - FHTTP.ProxyParams.SetHeaders(Request.RawHeaders); - if Assigned(AURI) then begin - FHTTP.SetCookies(AURI, Request); - end; - - // This is a workaround for some HTTP servers which do not implement - // the HTTP protocol properly - LBufferingStarted := not FHTTP.IOHandler.WriteBufferingActive; - if LBufferingStarted then begin - FHTTP.IOHandler.WriteBufferOpen; - end; - try - FHTTP.IOHandler.WriteLn(Request.Method + ' ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize} - // write the headers - for i := 0 to Request.RawHeaders.Count - 1 do begin - if Length(Request.RawHeaders.Strings[i]) > 0 then begin - FHTTP.IOHandler.WriteLn(Request.RawHeaders.Strings[i]); - end; - end; - FHTTP.IOHandler.WriteLn; - if LBufferingStarted then begin - FHTTP.IOHandler.WriteBufferClose; - end; - except - if LBufferingStarted then begin - FHTTP.IOHandler.WriteBufferCancel; - end; - raise; - end; -end; - -procedure TIdHTTPProtocol.RetrieveHeaders(AMaxHeaderCount: integer); -var - s: string; - LHeaderCount: Integer; -begin - // Set the response headers - // Don't use Capture. - // S.G. 6/4/2004: Added AmaxHeaderCount parameter to prevent the "header bombing" of the server - s := FHTTP.InternalReadLn; - try - LHeaderCount := 0; - while (s <> '') and ( (AMaxHeaderCount > 0) or (LHeaderCount < AMaxHeaderCount) ) do - begin - Response.RawHeaders.Add(S); - s := FHTTP.InternalReadLn; - Inc(LHeaderCount); - end; - except - on E: Exception do begin - FHTTP.Disconnect; - if not (E is EIdConnClosedGracefully) then begin - raise; - end; - end; - end; - Response.ProcessHeaders; -end; - -function TIdHTTPProtocol.ProcessResponse(AIgnoreReplies: array of Int16): TIdHTTPWhatsNext; -var - LResponseCode, LResponseDigit: Integer; - - procedure CheckException; - var - i: Integer; - LTempStream: TMemoryStream; - LOrigStream: TStream; - LRaiseException: Boolean; - LDiscardContent: Boolean; - begin - LRaiseException := True; - LDiscardContent := True; - - if hoNoProtocolErrorException in FHTTP.HTTPOptions then begin - LRaiseException := False; - LDiscardContent := not (hoWantProtocolErrorContent in FHTTP.HTTPOptions); - end - else if High(AIgnoreReplies) > -1 then begin - for i := Low(AIgnoreReplies) to High(AIgnoreReplies) do begin - if LResponseCode = AIgnoreReplies[i] then begin - LRaiseException := False; - LDiscardContent := not (hoWantProtocolErrorContent in FHTTP.HTTPOptions); - Break; - end; - end; - end; - - if LRaiseException then begin - LTempStream := TMemoryStream.Create; - end else begin - LTempStream := nil; - end; - try - if LRaiseException or LDiscardContent then begin - LOrigStream := Response.ContentStream; - Response.ContentStream := LTempStream; - end else begin - LOrigStream := nil; - end; - try - try - FHTTP.ReadResult(Request, Response); - except - on E: Exception do begin - FHTTP.Disconnect; - if not (E is EIdConnClosedGracefully) then begin - raise; - end; - end; - end; - if LRaiseException then begin - LTempStream.Position := 0; - raise EIdHTTPProtocolException.CreateError(LResponseCode, Response.ResponseText, - ReadStringAsCharset(LTempStream, Response.CharSet)); - end; - finally - if LRaiseException or LDiscardContent then begin - Response.ContentStream := LOrigStream; - end; - end; - finally - if LRaiseException then begin - LTempStream.Free; - end; - end; - end; - - procedure DiscardContent; - var - LOrigStream: TStream; - begin - LOrigStream := Response.ContentStream; - Response.ContentStream := nil; - try - try - FHTTP.ReadResult(Request, Response); - except - on E: Exception do begin - FHTTP.Disconnect; - if not (E is EIdConnClosedGracefully) then begin - raise; - end; - end; - end; - finally - Response.ContentStream := LOrigStream; - end; - end; - - function HeadersCanContinue: Boolean; - begin - Result := True; - if Assigned(FHTTP.OnHeadersAvailable) then begin - FHTTP.OnHeadersAvailable(FHTTP, Response.RawHeaders, Result); - end; - end; - -var - LLocation: string; - LMethod: TIdHTTPMethod; - LNeedAuth: Boolean; - //LTemp: Integer; -begin - - // provide the user with the headers and let the user decide - // whether the response processing should continue... - if not HeadersCanContinue then begin - // TODO: provide the user an option whether to force DoRequest() to disconnect the connection or not - Response.KeepAlive := False; - Response.Connection := 'close'; {do not localize} - Result := wnJustExit; - Exit; - end; - - // Cache this as ResponseCode calls GetResponseCode which parses it out - LResponseCode := Response.ResponseCode; - LResponseDigit := LResponseCode div 100; - LNeedAuth := False; - - // Handle Redirects - // RLebeau: All 3xx replies other than 304 are redirects. Reply 201 has a - // Location header but is NOT a redirect! - - // RLebeau 4/21/2011: Amazon S3 includes a Location header in its 200 reply - // to some PUT requests. Not sure if this is a bug or intentional, but we - // should NOT perform a redirect for any replies other than 3xx. Amazon S3 - // does NOT include a Location header in its 301 reply, though! This is - // intentional, per Amazon's documentation, as a way for developers to - // detect when URLs are addressed incorrectly... - - if (LResponseDigit = 3) and (LResponseCode <> 304) then - begin - if Response.Location = '' then begin - CheckException; - Result := wnJustExit; - Exit; - end; - - Inc(FHTTP.FRedirectCount); - - // LLocation := TIdURI.URLDecode(Response.Location); - LLocation := Response.Location; - LMethod := Request.Method; - - // fire the event - if not FHTTP.DoOnRedirect(LLocation, LMethod, FHTTP.FRedirectCount) then begin - CheckException; - Result := wnJustExit; - Exit; - end; - - if (FHTTP.FHandleRedirects) and (FHTTP.FRedirectCount < FHTTP.FRedirectMax) then begin - Result := wnGoToURL; - Request.URL := LLocation; - - // GDG 21/11/2003. If it's a 303, we should do a get this time - - // RLebeau 7/15/2004 - do a GET on 302 as well, as mentioned in RFC 2616 - - // RLebeau 1/11/2008 - turns out both situations are WRONG! RFCs 2068 and - // 2616 specifically state that changing the method to GET in response - // to 302 and 303 is errorneous. Indy 9 did it right by reusing the - // original method and source again and only changing the URL, so lets - // revert back to that same behavior! - - // RLebeau 12/28/2012 - one more time. RFCs 2068 and 2616 actually say that - // changing the method in response to 302 is erroneous, but changing the - // method to GET in response to 303 is intentional and why 303 was introduced - // in the first place. Erroneous clients treat 302 as 303, though. Now - // encountering servers that actually expect this 303 behavior, so we have - // to enable it again! Adding an optional HTTPOption flag so clients can - // enable the erroneous 302 behavior if they really need it. - - if ((LResponseCode = 302) and (hoTreat302Like303 in FHTTP.HTTPOptions)) or - (LResponseCode = 303) then - begin - Request.Source := nil; - Request.Method := Id_HTTPMethodGet; - // TODO: if the previous request was a POST with an 'application/x-www-webform-urlencoded' - // body, move the body data into the URL query string this time... - end else begin - Request.Method := LMethod; - end; - Request.MethodOverride := ''; - end else begin - Result := wnJustExit; - Response.Location := LLocation; - end; - - if FHTTP.Connected then begin - // This is a workaround for buggy HTTP 1.1 servers which - // does not return any body with 302 response code - DiscardContent; // may wait a few seconds for any kind of content - end; - end else begin - //Ciaran, 30th Nov 2004: I commented out the following code. When a https server - //sends a disconnect immediately after sending the requested page in an SSL - //session (which they sometimes do to indicate a "session" is finished), the code - //below causes a "Connection closed gracefully" exception BUT the returned page - //is lost (IOHandler.Request is empty). If the code below is re-enabled by - //someone for whatever reason, they MUST test for this case. - // GREGOR Workaround - // if we get an error we disconnect if we use SSLIOHandler - //if Assigned(FHTTP.IOHandler) then - //begin - // Response.KeepAlive := not (FHTTP.Connected and (FHTTP.IOHandler is TIdSSLIOHandlerSocketBase) and Response.KeepAlive); - //end; - - // RLebeau 2/15/2006: RFC 1945 states the following: - // - // For response messages, whether or not an entity body is included with - // a message is dependent on both the request method and the response - // code. All responses to the HEAD request method must not include a - // body, even though the presence of entity header fields may lead one - // to believe they do. All 1xx (informational), 204 (no content), and - // 304 (not modified) responses must not include a body. All other - // responses must include an entity body or a Content-Length header - // field defined with a value of zero (0). - - if LResponseDigit <> 2 then begin - case LResponseCode of - 101: - begin - Response.KeepAlive := True; - Result := wnJustExit; - Exit; - end; - 401: - begin // HTTP Server authorization required - if (FHTTP.AuthRetries >= FHTTP.MaxAuthRetries) or - (not FHTTP.DoOnAuthorization(Request, Response)) then begin - if Assigned(Request.Authentication) then begin - Request.Authentication.Reset; - end; - CheckException; - Result := wnJustExit; - Exit; - end else begin - LNeedAuth := hoInProcessAuth in FHTTP.HTTPOptions; - end; - end; - 407: - begin // Proxy Server authorization requered - if (FHTTP.AuthProxyRetries >= FHTTP.MaxAuthRetries) or - (not FHTTP.DoOnProxyAuthorization(Request, Response)) then - begin - if Assigned(FHTTP.ProxyParams.Authentication) then begin - FHTTP.ProxyParams.Authentication.Reset; - end; - CheckException; - Result := wnJustExit; - Exit; - end else begin - LNeedAuth := hoInProcessAuth in FHTTP.HTTPOptions; - end; - end; - else begin - CheckException; - Result := wnJustExit; - Exit; - end; - end; - end; - - if LNeedAuth then begin - // discard the content of Error message - DiscardContent; - Result := wnAuthRequest; - end else - begin - // RLebeau 6/30/2006: DO NOT READ IF THE REQUEST IS HEAD!!! - // The server is supposed to send a 'Content-Length' header - // without sending the actual data... - if TextIsSame(Request.Method, Id_HTTPMethodHead) or - TextIsSame(Request.MethodOverride, Id_HTTPMethodHead) or - (LResponseCode = 204) then - begin - // Have noticed one case where a non-conforming server did send an - // entity body in response to a HEAD request. If requested, ignore - // anything the server may send by accident - DiscardContent; - end else begin - FHTTP.ReadResult(Request, Response); - end; - Result := wnJustExit; - end; - end; -end; - -function TIdCustomHTTP.CreateProtocol: TIdHTTPProtocol; -begin - Result := TIdHTTPProtocol.Create(Self); -end; - -procedure TIdCustomHTTP.InitComponent; -begin - inherited; - FURI := TIdURI.Create(''); - - FAuthRetries := 0; - FAuthProxyRetries := 0; - AllowCookies := True; - FImplicitCookieManager := False; - FOptions := Id_TIdHTTP_HTTPOptions; - - FRedirectMax := Id_TIdHTTP_RedirectMax; - FHandleRedirects := Id_TIdHTTP_HandleRedirects; - // - FProtocolVersion := Id_TIdHTTP_ProtocolVersion; - - FHTTPProto := CreateProtocol; - FProxyParameters := TIdProxyConnectionInfo.Create; - FProxyParameters.Clear; - - FMaxAuthRetries := Id_TIdHTTP_MaxAuthRetries; - FMaxHeaderLines := Id_TIdHTTP_MaxHeaderLines; -end; - -function TIdCustomHTTP.InternalReadLn: String; -begin - // TODO: add ReadLnTimeoutAction property to TIdIOHandler... - Result := IOHandler.ReadLn; - if IOHandler.ReadLnTimedout then begin - raise EIdReadTimeout.Create(RSReadTimeout); - end; -end; - -function TIdCustomHTTP.Get(AURL: string; AIgnoreReplies: array of Int16 - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; -var - LStream: TMemoryStream; -begin - LStream := TMemoryStream.Create; - try - Get(AURL, LStream, AIgnoreReplies); - LStream.Position := 0; - Result := ReadStringAsCharset(LStream, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); - // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... - finally - FreeAndNil(LStream); - end; -end; - -procedure TIdCustomHTTP.Get(AURL: string; AResponseContent: TStream; - AIgnoreReplies: array of Int16); -begin - DoRequest(Id_HTTPMethodGet, AURL, nil, AResponseContent, AIgnoreReplies); -end; - -procedure TIdCustomHTTP.DoRequest(const AMethod: TIdHTTPMethod; - AURL: string; ASource, AResponseContent: TStream; - AIgnoreReplies: array of Int16); -var - LResponseLocation: TIdStreamSize; -begin - //reset any counters - FRedirectCount := 0; - FAuthRetries := 0; - FAuthProxyRetries := 0; - - if Assigned(AResponseContent) then begin - LResponseLocation := AResponseContent.Position; - end else begin - LResponseLocation := 0; // Just to avoid the warning message - end; - - Request.URL := AURL; - Request.Method := AMethod; - Request.Source := ASource; - Response.ContentStream := AResponseContent; - - try - repeat - PrepareRequest(Request); - if IOHandler is TIdSSLIOHandlerSocketBase then begin - TIdSSLIOHandlerSocketBase(IOHandler).URIToCheck := FURI.URI; - end; - ConnectToHost(Request, Response); - - // Workaround for servers which respond with 100 Continue on GET and HEAD - // This workaround is just for temporary use until we have final HTTP 1.1 - // realisation. HTTP 1.1 is ongoing because of all the buggy and conflicting servers. - // - // This is also necessary as servers are allowed to send any number of - // 1xx informational responses before sending the final response. - // - // Except in the case of 101 SWITCHING PROTOCOLS, which is a final response. - // The protocol on the line is then switched to the requested protocol, per - // the response's 'Upgrade' header, following the 101 response, so we need to - // stop and exit immediately if 101 is received, and let the caller handle - // the new protocol as needed. - repeat - Response.ResponseText := InternalReadLn; - FHTTPProto.RetrieveHeaders(MaxHeaderLines); - ProcessCookies(Request, Response); - if ((Response.ResponseCode div 100) <> 1) or (Response.ResponseCode = 101) then begin - Break; - end; - Response.Clear; - until False; - - case FHTTPProto.ProcessResponse(AIgnoreReplies) of - wnAuthRequest: - begin - Request.URL := AURL; - end; - wnReadAndGo: - begin - ReadResult(Request, Response); - if Assigned(AResponseContent) then begin - AResponseContent.Position := LResponseLocation; - AResponseContent.Size := LResponseLocation; - end; - FAuthRetries := 0; - FAuthProxyRetries := 0; - end; - wnGoToURL: - begin - if Assigned(AResponseContent) then begin - AResponseContent.Position := LResponseLocation; - AResponseContent.Size := LResponseLocation; - end; - FAuthRetries := 0; - FAuthProxyRetries := 0; - end; - wnJustExit: - begin - Break; - end; - wnDontKnow: - begin - raise EIdException.Create(RSHTTPNotAcceptable); // TODO: create a new Exception class for this - end; - end; - until False; - finally - if not ( - Response.KeepAlive or - ((hoNoReadMultipartMIME in FOptions) and IsHeaderMediaType(Response.ContentType, 'multipart')) or {do not localize} - ((hoNoReadChunked in FOptions) and (IndyPos('chunked', LowerCase(Response.TransferEncoding)) > 0)) {do not localize} - ) then - begin - Disconnect; - end; - end; -end; - -procedure TIdCustomHTTP.Patch(AURL: string; ASource, AResponseContent: TStream); -begin - DoRequest(Id_HTTPMethodPatch, AURL, ASource, AResponseContent, []); -end; - -function TIdCustomHTTP.Patch(AURL: string; ASource: TStream - {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} - ): string; -var - LResponse: TMemoryStream; -begin - LResponse := TMemoryStream.Create; - try - Patch(AURL, ASource, LResponse); - LResponse.Position := 0; - Result := ReadStringAsCharset(LResponse, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); - // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... - finally - FreeAndNil(LResponse); - end; -end; - -end. - +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.65 3/5/2005 3:33:52 PM JPMugaas + Fix for some compiler warnings having to do with TStream.Read being platform + specific. This was fixed by changing the Compressor API to use TIdStreamVCL + instead of TStream. I also made appropriate adjustments to other units for + this. + + Rev 1.64 2/13/2005 3:09:20 PM DSiders + Modified TIdCustomHTTP.PrepareRequest to free the local URI instance if an + exception occurs in the method. (try...finally) + + Rev 1.63 2/11/05 11:29:34 AM RLebeau + Removed compiler warning + + Rev 1.62 2/9/05 2:12:08 AM RLebeau + Fixes for Compiler errors + + Rev 1.61 2/8/05 6:43:42 PM RLebeau + Added OnHeaderAvailable event + + Rev 1.60 1/11/05 1:25:08 AM RLebeau + More changes to SetHostAndPort() + + Rev 1.59 1/6/05 2:28:52 PM RLebeau + Fix for SetHostAndPort() not using its local variables properly + + Rev 1.58 06/01/2005 22:23:04 CCostelloe + Bug fix (typo, gizp instead of gzip) + + Rev 1.57 05/12/2004 23:10:58 CCostelloe + Recoded fix to suit Delphi < 7 + + Rev 1.56 30/11/2004 23:46:12 CCostelloe + Bug fix for SSL connections giving a "Connection closed gracefully" exception + and requested page not getting returned (IOHandler.Response is empty) + + Rev 1.55 25/11/2004 21:28:06 CCostelloe + Bug fix for POSTing fields that have the same name + + Rev 1.54 10/26/2004 10:13:24 PM JPMugaas + Updated refs. + + Rev 1.53 7/16/04 1:19:20 AM RLebeau + Fix for compiler error + + Rev 1.52 7/15/04 8:19:30 PM RLebeau + Updated TIdHTTPProtocol.ProcessResponse() to treat 302 redirects like 303. + + Updated TIdHTTPProtocol.BuildAndSendRequest() to use a try...except block + + Rev 1.51 6/17/2004 8:30:04 AM DSiders + TIdCustomHTTP modified: + - Fixed error in AuthRetries property reading wrong member var. + - Added AuthProxyRetries and MaxAuthRetries properties to public interface. + + TIdHTTP modified to publish AuthRetries, AuthProxyRetries, and MaxAuthRetries. + + TIdHTTPProtocol.ProcessResponse modified to use public properties + AuthRetries, AuthProxyRetries, and MaxAutrhRetries. + + Rev 1.50 2004.05.20 11:36:46 AM czhower + IdStreamVCL + + Rev 1.49 4/28/04 1:45:26 PM RLebeau + Updated TIdCustomHTTP.SetRequestParams() to strip off the trailing CRLF + before encoding rather than afterwards + + Rev 1.48 2004.04.07 11:18:08 PM czhower + Bug and naming fix. + + Rev 1.47 7/4/2004 6:00:02 PM SGrobety + Reformatted to match project guidelines + + Rev 1.46 7/4/2004 4:58:24 PM SGrobety + Reformatted to match project guidelines + + Rev 1.45 6/4/2004 5:16:40 PM SGrobety + Added AMaxHeaderCount: integer parameter to TIdHTTPProtocol.RetrieveHeaders + and MaxHeaderLines property to TIdCustomHTTP (default to 255) + + Rev 1.44 2004.03.06 10:39:52 PM czhower + Removed duplicate code + + Rev 1.43 2004.03.06 8:56:30 PM czhower + -Change to disconnect + -Addition of DisconnectNotifyPeer + -WriteHeader now write bufers + + Rev 1.42 3/3/2004 5:58:00 AM JPMugaas + Some IFDEF excluses were removed because the functionality is now in DotNET. + + Rev 1.41 2004.02.23 9:33:12 PM czhower + Now can optionally ignore response codes for exceptions. + + Rev 1.40 2/15/2004 6:34:02 AM JPMugaas + Fix for where I broke the HTTP client with a parameter change in the GZip + decompress method. + + Rev 1.39 2004.02.03 5:43:44 PM czhower + Name changes + + Rev 1.38 2004.02.03 2:12:10 PM czhower + $I path change + + Rev 1.37 2004.01.27 11:41:18 PM czhower + Removed const arguments + + Rev 1.35 24/01/2004 19:22:34 CCostelloe + Cleaned up warnings + + Rev 1.34 2004.01.22 5:29:02 PM czhower + TextIsSame + + Rev 1.33 2004.01.21 1:04:50 PM czhower + InitComponenet + + Rev 1.32 1/2/2004 11:41:48 AM BGooijen + Enabled IPv6 support + + Rev 1.31 22/11/2003 12:04:28 AM GGrieve + Add support for HTTP status code 303 + + Rev 1.30 10/25/2003 06:51:58 AM JPMugaas + Updated for new API changes and tried to restore some functionality. + + Rev 1.29 2003.10.24 10:43:08 AM czhower + TIdSTream to dos + + Rev 1.28 24/10/2003 10:58:40 AM SGrobety + Made authentication work even if no OnAnthenticate envent handler present + + Rev 1.27 10/18/2003 1:53:10 PM BGooijen + Added include + + Rev 1.26 10/17/2003 12:08:48 AM DSiders + Added localization comments. + + Rev 1.25 2003.10.14 1:27:52 PM czhower + DotNet + + Rev 1.24 10/7/2003 11:33:54 PM GGrieve + Get works under DotNet + + Rev 1.23 10/7/2003 10:07:04 PM GGrieve + Get HTTP compiling for DotNet + + Rev 1.22 10/4/2003 9:15:58 PM GGrieve + fix to compile + + Rev 1.21 9/26/2003 01:41:48 PM JPMugaas + Fix for problem wihere "identity" was being added more than once to the + accepted encoding contents. + + Rev 1.20 9/14/2003 07:54:20 PM JPMugaas + Published the Compressor property. + + Rev 1.19 7/30/2003 05:34:22 AM JPMugaas + Fix for bug where decompression was not done if the Content Length was + specified. I found that at http://www.news.com. + Added Identity to the content encoding to be consistant with Opera. Identity + is the default Accept-Encoding (RFC 2616). + + Rev 1.18 7/13/2003 10:57:28 PM BGooijen + Fixed GZip and Deflate decoding + + Rev 1.17 7/13/2003 11:29:06 AM JPMugaas + Made sure some GZIP decompression stub code is in IdHTTP. + + Rev 1.15 10.7.2003 ã. 21:03:02 DBondzhev + Fixed NTML proxy authorization + + Rev 1.14 6/19/2003 02:36:56 PM JPMugaas + Removed a connected check and it seems to work better that way. + + Rev 1.13 6/5/2003 04:53:54 AM JPMugaas + Reworkings and minor changes for new Reply exception framework. + + Rev 1.12 4/30/2003 01:47:24 PM JPMugaas + Added TODO concerning a ConnectTimeout. + + Rev 1.11 4/2/2003 3:18:30 PM BGooijen + fixed av when retrieving an url when no iohandler was assigned + + Rev 1.10 3/26/2003 5:13:40 PM BGooijen + TIdSSLIOHandlerSocketBase.URIToCheck is now set + + Rev 1.9 3/13/2003 11:05:26 AM JPMugaas + Now should work with 3rd party vendor SSL IOHandlers. + + Rev 1.8 3/11/2003 10:14:52 PM BGooijen + Undid the stripping of the CR + + Rev 1.7 2/27/2003 2:04:26 PM BGooijen + If any call to iohandler.readln returns a CR at the end, it is removed now. + + Rev 1.6 2/26/2003 11:50:08 AM BGooijen + things were messed up in TIdHTTPProtocol.RetrieveHeaders, because the call to + readln doesn't strip the CR at the end (terminator=LF), therefore the end of + the header was not found. + + Rev 1.5 2/26/2003 11:42:46 AM BGooijen + changed ReadLn (IOerror 6) to IOHandler.ReadLn + + Rev 1.4 2/4/2003 6:30:44 PM BGooijen + Re-enabled SSL-support + + Rev 1.3 1/17/2003 04:14:42 PM JPMugaas + Fixed warnings. + + Rev 1.2 12/7/2002 05:32:16 PM JPMugaas + Now compiles with destination removed. + + Rev 1.1 12/6/2002 05:29:52 PM JPMugaas + Now decend from TIdTCPClientCustom instead of TIdTCPClient. + + Rev 1.0 11/13/2002 07:54:12 AM JPMugaas + +2001-Nov Nick Panteleeff + - Authentication and POST parameter extentsions + +2001-Sept Doychin Bondzhev + - New internal design and new Authentication procedures. + - Bug fixes and new features in few other supporting components + +2001-Jul-7 Doychin Bondzhev + - new property AllowCookie + - There is no more ExtraHeders property in Request/Response. Raw headers is used for that purpose. + +2001-Jul-1 Doychin Bondzhev + - SSL support is up again - Thanks to Gregor + +2001-Jun-17 Doychin Bondzhev + - New unit IdHTTPHeaderInfo.pas that contains the + TIdHeaderInfo(TIdEntytiHeaderInfo, TIdRequestHeaderInfo and TIdResponseHeaderInfo) + - Still in development and not verry well tested + By default when there is no authorization object associated with HTTP compoenet and there is user name and password + HTTP component creates and instance of TIdBasicAuthentication class. This behaivor is for both web server and proxy server + authorizations + +2001-Apr-17 Doychin Bondzhev + - Added OnProxyAuthorization event. This event is called on 407 response from the HTTP Proxy. + - Added 2 new properties in TIdHeaderInfo + property AuthenticationScheme: TIdAuthenticationScheme - this property contains information for authentication scheme + requested by the web server + property ProxyAuthenticationScheme: TIdAuthenticationScheme - this property contains information for authentication scheme + requested by the proxy server + - Now the component authomaticly reconginizes the requested authorization scheme and it supports Basic like before and has been + extend to support Digest authorization + +2001-Mar-31 Doychin Bondzhev + - If there is no CookieManager it does not support cookies. + +2001-Feb-18 Doychin Bondzhev + - Added OnAuthorization event. This event is called on 401 response from the HTTP server. + This can be used to ask the user program to supply user name and password in order to acces + the requested resource + +2001-Feb-02 Doychin Bondzhev + - Added Cookie support and relative paths on redirect + +2000-Jul-25 Hadi Hariri + - Overloaded POst and moved clearing to disconect. + +2000-June-22 Hadi Hariri + - Added Proxy support. + +2000-June-10 Hadi Hariri + - Added Chunk-Encoding support and HTTP version number. Some additional + improvements. + +2000-May-23 J. Peter Mugaas + -added redirect capability and supporting properties. Redirect is optional + and is set with HandleRedirects. Redirection is limited to RedirectMaximum + to prevent stack overflow due to recursion and to prevent redirects between + two places which would cause this to go on to infinity. + +2000-May-22 J. Peter Mugaas + -adjusted code for servers which returned LF instead of EOL + -Headers are now retreived before an exception is raised. This + also facilitates server redirection where the server tells the client to + get a document from another location. + +2000-May-01 Hadi Hariri + -Converted to Mercury + +2000-May-01 Hadi Hariri + -Added PostFromStream and some clean up + +2000-Apr-10 Hadi Hariri + -Re-done quite a few things and fixed GET bugs and finished POST method. + +2000-Jan-13 MTL + -Moved to the New Palette Scheme + +2000-Jan-08 MTL + -Cleaned up a few compiler hints during 7.038 build + +1999-Dec-10 Hadi Hariri + -Started. +} + +unit IdHTTP; + +{ + Implementation of the HTTP protcol as specified in RFC 2616, 2109, 2965. + (See NOTE below for details of what is exactly implemented) + + Author: Hadi Hariri (hadi@urusoft.com) + Copyright: (c) Chad Z. Hower and The Winshoes Working Group. + + Initials: Hadi Hariri - HH +} +{ + TODO: Figure out what to do with ConnectTimeout. + Ideally, that should be in the core and is not the same as a read Timeout. +} + +interface + +{$I IdCompilerDefines.inc} + +uses + Classes, + IdException, IdExceptionCore, IdAssignedNumbers, IdHeaderList, IdHTTPHeaderInfo, IdReplyRFC, + IdSSL, IdZLibCompressorBase, + IdTCPClient, IdURI, IdCookieManager, IdAuthentication, IdAuthenticationManager, + IdMultipartFormData, IdGlobal, IdBaseComponent, IdUriUtils; + +type + // TO DOCUMENTATION TEAM + // ------------------------ + // For internal use. No need of documentation + // hmConnect - Used to connect trought CERN proxy to SSL enabled sites. + TIdHTTPMethod = string; + +const + Id_HTTPMethodHead = 'HEAD'; + Id_HTTPMethodGet = 'GET'; + Id_HTTPMethodPost = 'POST'; + Id_HTTPMethodOptions = 'OPTIONS'; + Id_HTTPMethodTrace = 'TRACE'; + Id_HTTPMethodPut = 'PUT'; + Id_HTTPMethodDelete = 'DELETE'; + Id_HTTPMethodConnect = 'CONNECT'; + Id_HTTPMethodPatch = 'PATCH'; + //(hmHead, hmGet, hmPost, hmOptions, hmTrace, hmPut, hmDelete, hmConnect, hmPatch); + +type + TIdHTTPWhatsNext = (wnGoToURL, wnJustExit, wnDontKnow, wnReadAndGo, wnAuthRequest); + TIdHTTPConnectionType = (ctNormal, ctSSL, ctProxy, ctSSLProxy); + + // Protocol options + TIdHTTPOption = (hoInProcessAuth, hoKeepOrigProtocol, hoForceEncodeParams, + hoNonSSLProxyUseConnectVerb, hoNoParseMetaHTTPEquiv, hoWaitForUnexpectedData, + hoTreat302Like303, hoNoProtocolErrorException, hoNoReadMultipartMIME, + hoNoParseXmlCharset, hoWantProtocolErrorContent, hoNoReadChunked + ); + + TIdHTTPOptions = set of TIdHTTPOption; + + // Must be documented + TIdHTTPProtocolVersion = (pv1_0, pv1_1); + + TIdHTTPOnRedirectEvent = procedure(Sender: TObject; var dest: string; var NumRedirect: Integer; var Handled: boolean; var VMethod: TIdHTTPMethod) of object; + TIdHTTPOnHeadersAvailable = procedure(Sender: TObject; AHeaders: TIdHeaderList; var VContinue: Boolean) of object; + TIdOnSelectAuthorization = procedure(Sender: TObject; var AuthenticationClass: TIdAuthenticationClass; AuthInfo: TIdHeaderList) of object; + TIdOnAuthorization = procedure(Sender: TObject; Authentication: TIdAuthentication; var Handled: Boolean) of object; + // TIdProxyOnAuthorization = procedure(Sender: TObject; Authentication: TIdAuthentication; var Handled: boolean) of object; + TIdOnChunkReceived = procedure(Sender : TObject; var Chunk: TIdBytes) of object; + +const + Id_TIdHTTP_ProtocolVersion = pv1_1; + Id_TIdHTTP_RedirectMax = 15; + Id_TIdHTTP_MaxHeaderLines = 255; + Id_TIdHTTP_HandleRedirects = False; + Id_TIdHTTP_MaxAuthRetries = 3; + Id_TIdHTTP_HTTPOptions = [hoKeepOrigProtocol, hoForceEncodeParams]; + +type + TIdCustomHTTP = class; + + // TO DOCUMENTATION TEAM + // ------------------------ + // The following classes are used internally and no need of documentation + // Only TIdHTTP must be documented + // + TIdHTTPResponse = class(TIdResponseHeaderInfo) + protected + {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FHTTP: TIdCustomHTTP; + FResponseCode: Integer; + FResponseText: string; + FKeepAlive: Boolean; + {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FContentStream: TStream; + FResponseVersion: TIdHTTPProtocolVersion; + FMetaHTTPEquiv : TIdMetaHTTPEquiv; + // + function GetKeepAlive: Boolean; + function GetResponseCode: Integer; + + procedure SetResponseText(const AValue: String); + procedure ProcessMetaHTTPEquiv; + public + constructor Create(AHTTP: TIdCustomHTTP); reintroduce; virtual; + destructor Destroy; override; + procedure Clear; override; + property KeepAlive: Boolean read GetKeepAlive write FKeepAlive; + property MetaHTTPEquiv: TIdMetaHTTPEquiv read FMetaHTTPEquiv; + property ResponseText: string read FResponseText write SetResponseText; + property ResponseCode: Integer read GetResponseCode write FResponseCode; + property ResponseVersion: TIdHTTPProtocolVersion read FResponseVersion write FResponseVersion; + property ContentStream: TStream read FContentStream write FContentStream; + end; + + TIdHTTPRequest = class(TIdRequestHeaderInfo) + protected + {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FHTTP: TIdCustomHTTP; + FURL: string; + FMethod: TIdHTTPMethod; + {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FSourceStream: TStream; + FUseProxy: TIdHTTPConnectionType; + FIPVersion: TIdIPVersion; + FDestination: string; + public + constructor Create(AHTTP: TIdCustomHTTP); reintroduce; virtual; + property URL: string read FURL write FURL; + property Method: TIdHTTPMethod read FMethod write FMethod; + property Source: TStream read FSourceStream write FSourceStream; + property UseProxy: TIdHTTPConnectionType read FUseProxy; + property IPVersion: TIdIPVersion read FIPVersion write FIPVersion; + property Destination: string read FDestination write FDestination; + end; + + TIdHTTPProtocol = class(TObject) + protected + {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FHTTP: TIdCustomHTTP; + FRequest: TIdHTTPRequest; + FResponse: TIdHTTPResponse; + public + constructor Create(AConnection: TIdCustomHTTP); + destructor Destroy; override; + function ProcessResponse(AIgnoreReplies: array of Int16): TIdHTTPWhatsNext; + procedure BuildAndSendRequest(AURI: TIdURI); + procedure RetrieveHeaders(AMaxHeaderCount: integer); + // + property Request: TIdHTTPRequest read FRequest; + property Response: TIdHTTPResponse read FResponse; + end; + + TIdCustomHTTP = class(TIdTCPClientCustom) + protected + {Retries counter for WWW authorization} + FAuthRetries: Integer; + {Retries counter for proxy authorization} + FAuthProxyRetries: Integer; + {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FCookieManager: TIdCookieManager; + {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FCompressor : TIdZLibCompressorBase; + FImplicitCookieManager: Boolean; + {Max retries for authorization} + FMaxAuthRetries: Integer; + FMaxHeaderLines: integer; + FAllowCookies: Boolean; + {$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FAuthenticationManager: TIdAuthenticationManager; + FProtocolVersion: TIdHTTPProtocolVersion; + + {this is an internal counter for redirects} + FRedirectCount: Integer; + FRedirectMax: Integer; + FHandleRedirects: Boolean; + FOptions: TIdHTTPOptions; + FURI: TIdURI; + FHTTPProto: TIdHTTPProtocol; + FProxyParameters: TIdProxyConnectionInfo; + // + FOnHeadersAvailable: TIdHTTPOnHeadersAvailable; + FOnRedirect: TIdHTTPOnRedirectEvent; + FOnSelectAuthorization: TIdOnSelectAuthorization; + FOnSelectProxyAuthorization: TIdOnSelectAuthorization; + FOnAuthorization: TIdOnAuthorization; + FOnProxyAuthorization: TIdOnAuthorization; + FOnChunkReceived: TIdOnChunkReceived; + // +{ + procedure SetHost(const Value: string); override; + procedure SetPort(const Value: integer); override; +} + procedure DoRequest(const AMethod: TIdHTTPMethod; AURL: string; + ASource, AResponseContent: TStream; AIgnoreReplies: array of Int16); virtual; + function CreateProtocol: TIdHTTPProtocol; virtual; + procedure InitComponent; override; + function InternalReadLn: String; + procedure SetAuthenticationManager(Value: TIdAuthenticationManager); + procedure SetCookieManager(ACookieManager: TIdCookieManager); + procedure SetAllowCookies(AValue: Boolean); + function GetResponseCode: Integer; + function GetResponseText: string; + function DoOnAuthorization(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse): Boolean; virtual; + function DoOnProxyAuthorization(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse): Boolean; virtual; + function DoOnRedirect(var Location: string; var VMethod: TIdHTTPMethod; RedirectCount: integer): boolean; virtual; + procedure Notification(AComponent: TComponent; Operation: TOperation); override; + procedure ProcessCookies(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); + function SetHostAndPort: TIdHTTPConnectionType; + procedure SetCookies(AURL: TIdURI; ARequest: TIdHTTPRequest); + procedure ReadResult(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); + procedure PrepareRequest(ARequest: TIdHTTPRequest); + procedure ConnectToHost(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); + function GetResponse: TIdHTTPResponse; + function GetRequest: TIdHTTPRequest; + function GetMetaHTTPEquiv: TIdMetaHTTPEquiv; + procedure SetRequest(Value: TIdHTTPRequest); + procedure SetProxyParams(AValue: TIdProxyConnectionInfo); + + function SetRequestParams(ASource: TStrings; AByteEncoding: IIdTextEncoding + {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding{$ENDIF} + ): string; + + procedure CheckAndConnect(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); + procedure DoOnDisconnected; override; + public + destructor Destroy; override; + + procedure Delete(AURL: string; AResponseContent: TStream); overload; + function Delete(AURL: string + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; overload; + + procedure Options(AURL: string; AResponseContent: TStream); overload; + function Options(AURL: string + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; overload; + + procedure Get(AURL: string; AResponseContent: TStream); overload; + procedure Get(AURL: string; AResponseContent: TStream; AIgnoreReplies: array of Int16); overload; + function Get(AURL: string + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; overload; + function Get(AURL: string; AIgnoreReplies: array of Int16 + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; overload; + + procedure Trace(AURL: string; AResponseContent: TStream); overload; + function Trace(AURL: string + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; overload; + procedure Head(AURL: string); + + function Post(AURL: string; const ASourceFile: String + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; overload; + function Post(AURL: string; ASource: TStrings; AByteEncoding: IIdTextEncoding = nil + {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil; ADestEncoding: IIdTextEncoding = nil{$ENDIF}): string; overload; + function Post(AURL: string; ASource: TStream + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; overload; + function Post(AURL: string; ASource: TIdMultiPartFormDataStream + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; overload; + + procedure Post(AURL: string; const ASourceFile: String; AResponseContent: TStream); overload; + procedure Post(AURL: string; ASource: TStrings; AResponseContent: TStream; AByteEncoding: IIdTextEncoding = nil + {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}); overload; + procedure Post(AURL: string; ASource, AResponseContent: TStream); overload; + procedure Post(AURL: string; ASource: TIdMultiPartFormDataStream; AResponseContent: TStream); overload; + + function Put(AURL: string; ASource: TStream + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; overload; + procedure Put(AURL: string; ASource, AResponseContent: TStream); overload; + + procedure Patch(AURL: string; ASource, AResponseContent: TStream); overload; + function Patch(AURL: string; ASource: TStream + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; overload; + + {This is an object that can compress and decompress HTTP Deflate encoding} + property Compressor : TIdZLibCompressorBase read FCompressor write FCompressor; + + {This is the response code number such as 404 for File not Found} + property ResponseCode: Integer read GetResponseCode; + {This is the text of the message such as "404 File Not Found here Sorry"} + property ResponseText: string read GetResponseText; + property Response: TIdHTTPResponse read GetResponse; + property MetaHTTPEquiv: TIdMetaHTTPEquiv read GetMetaHTTPEquiv; + { This is the last processed URL } + property URL: TIdURI read FURI; + // number of retry attempts for Authentication + property AuthRetries: Integer read FAuthRetries; + property AuthProxyRetries: Integer read FAuthProxyRetries; + // maximum number of Authentication retries permitted + property MaxAuthRetries: Integer read FMaxAuthRetries write FMaxAuthRetries default Id_TIdHTTP_MaxAuthRetries; + property AllowCookies: Boolean read FAllowCookies write SetAllowCookies default True; + {Do we handle redirect requests or simply raise an exception and let the + developer deal with it} + property HandleRedirects: Boolean read FHandleRedirects write FHandleRedirects default Id_TIdHTTP_HandleRedirects; + property ProtocolVersion: TIdHTTPProtocolVersion read FProtocolVersion write FProtocolVersion default Id_TIdHTTP_ProtocolVersion; + //how many redirects were made in the last request + property RedirectCount: Integer read FRedirectCount; + {This is the maximum number of redirects we wish to handle, we limit this + to prevent stack overflow due to recursion. Recursion is safe ONLY if + prevented for continuing to infinity} + property RedirectMaximum: Integer read FRedirectMax write FRedirectMax default Id_TIdHTTP_RedirectMax; + // S.G. 6/4/2004: This is to prevent the server from responding with too many header lines + property MaxHeaderLines: integer read FMaxHeaderLines write FMaxHeaderLines default Id_TIdHTTP_MaxHeaderLines; + property ProxyParams: TIdProxyConnectionInfo read FProxyParameters write SetProxyParams; + property Request: TIdHTTPRequest read GetRequest write SetRequest; + property HTTPOptions: TIdHTTPOptions read FOptions write FOptions default Id_TIdHTTP_HTTPOptions; + // + property OnHeadersAvailable: TIdHTTPOnHeadersAvailable read FOnHeadersAvailable write FOnHeadersAvailable; + // Fired when a rediretion is requested. + property OnRedirect: TIdHTTPOnRedirectEvent read FOnRedirect write FOnRedirect; + property OnSelectAuthorization: TIdOnSelectAuthorization read FOnSelectAuthorization write FOnSelectAuthorization; + property OnSelectProxyAuthorization: TIdOnSelectAuthorization read FOnSelectProxyAuthorization write FOnSelectProxyAuthorization; + property OnAuthorization: TIdOnAuthorization read FOnAuthorization write FOnAuthorization; + property OnProxyAuthorization: TIdOnAuthorization read FOnProxyAuthorization write FOnProxyAuthorization; + property OnChunkReceived: TIdOnChunkReceived read FOnChunkReceived write FOnChunkReceived; + // Cookie stuff + property CookieManager: TIdCookieManager read FCookieManager write SetCookieManager; + // + property AuthenticationManager: TIdAuthenticationManager read FAuthenticationManager write SetAuthenticationManager; + end; + + TIdHTTP = class(TIdCustomHTTP) + published + // number of Authentication retries permitted + property MaxAuthRetries; + property AllowCookies; + { Do we handle redirect requests or simply raise an exception and let the + developer deal with it } + property HandleRedirects; + property ProtocolVersion; + { This is the maximum number of redirects we wish to handle, we limit this + to prevent stack overflow due to recursion. Recursion is safe ONLY if + prevented for continuing to infinity } + property RedirectMaximum; + property ProxyParams; + property Request; + property HTTPOptions; + // + property OnHeadersAvailable; + // Fired when a rediretion is requested. + property OnRedirect; + property OnSelectAuthorization; + property OnSelectProxyAuthorization; + property OnAuthorization; + property OnProxyAuthorization; + property OnChunkReceived; + // property Host; + // property Port default IdPORT_HTTP; + // Cookie stuff + property CookieManager; + // property AuthenticationManager: TIdAuthenticationManager read FAuthenticationManager write SetAuthenticationManager; + // ZLib compression library object for use with deflate and gzip encoding + property Compressor; + end; + + EIdUnknownProtocol = class(EIdException); + EIdHTTPProtocolException = class( EIdReplyRFCError ) + protected + FErrorMessage: string; + public + constructor CreateError(const anErrCode: Integer; const asReplyMessage: string; + const asErrorMessage: string); reintroduce; virtual; + property ErrorMessage: string read FErrorMessage; + end; + +implementation + +uses + SysUtils, + IdAllAuthentications, IdComponent, IdCoderMIME, IdTCPConnection, + IdResourceStringsCore, IdResourceStringsProtocols, IdGlobalProtocols, + IdIOHandler, IdIOHandlerSocket; + +const + ProtocolVersionString: array[TIdHTTPProtocolVersion] of string = ('1.0', '1.1'); {do not localize} + +{ EIdHTTPProtocolException } + +constructor EIdHTTPProtocolException.CreateError(const anErrCode: Integer; + const asReplyMessage: string; const asErrorMessage: string); +begin + inherited CreateError(anErrCode, asReplyMessage); + FErrorMessage := asErrorMessage; +end; + +{ TIdHTTP } + +function IsContentTypeHtml(AInfo: TIdEntityHeaderInfo) : Boolean; +begin + Result := IsHeaderMediaTypes(AInfo.ContentType, ['text/html', 'text/html-sandboxed','application/xhtml+xml']); {do not localize} +end; + +function IsContentTypeAppXml(AInfo: TIdEntityHeaderInfo) : Boolean; +begin + Result := IsHeaderMediaTypes(AInfo.ContentType, + ['application/xml', 'application/xml-external-parsed-entity', 'application/xml-dtd'] {do not localize} + ); + if not Result then + begin + Result := not IsHeaderMediaType(AInfo.ContentType, 'text'); {do not localize} + if Result then begin + Result := TextEndsWith(ExtractHeaderMediaSubType(AInfo.ContentType), '+xml') {do not localize} + end; + end; +end; + +destructor TIdCustomHTTP.Destroy; +begin + FreeAndNil(FHTTPProto); + FreeAndNil(FURI); + FreeAndNil(FProxyParameters); + SetCookieManager(nil); + inherited Destroy; +end; + +procedure TIdCustomHTTP.Delete(AURL: string; AResponseContent: TStream); +begin + DoRequest(Id_HTTPMethodDelete, AURL, nil, AResponseContent, []); +end; + +function TIdCustomHTTP.Delete(AURL: string + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; +var + LStream: TMemoryStream; +begin + LStream := TMemoryStream.Create; + try + DoRequest(Id_HTTPMethodDelete, AURL, nil, LStream, []); + LStream.Position := 0; + Result := ReadStringAsCharset(LStream, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); + // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... + finally + FreeAndNil(LStream); + end; +end; + +procedure TIdCustomHTTP.Options(AURL: string; AResponseContent: TStream); +begin + DoRequest(Id_HTTPMethodOptions, AURL, nil, AResponseContent, []); +end; + +function TIdCustomHTTP.Options(AURL: string + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; +var + LStream: TMemoryStream; +begin + LStream := TMemoryStream.Create; + try + DoRequest(Id_HTTPMethodOptions, AURL, nil, LStream, []); + LStream.Position := 0; + Result := ReadStringAsCharset(LStream, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); + // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... + finally + FreeAndNil(LStream); + end; +end; + +procedure TIdCustomHTTP.Get(AURL: string; AResponseContent: TStream); +begin + Get(AURL, AResponseContent, []); +end; + +procedure TIdCustomHTTP.Trace(AURL: string; AResponseContent: TStream); +begin + DoRequest(Id_HTTPMethodTrace, AURL, nil, AResponseContent, []); +end; + +procedure TIdCustomHTTP.Head(AURL: string); +begin + DoRequest(Id_HTTPMethodHead, AURL, nil, nil, []); +end; + +procedure TIdCustomHTTP.Post(AURL: string; ASource, AResponseContent: TStream); +var + OldProtocol: TIdHTTPProtocolVersion; +begin + // PLEASE READ CAREFULLY + + // Currently when issuing a POST, IdHTTP will automatically set the protocol + // to version 1.0 independently of the value it had initially. This is because + // there are some servers that don't respect the RFC to the full extent. In + // particular, they don't respect sending/not sending the Expect: 100-Continue + // header. Until we find an optimum solution that does NOT break the RFC, we + // will restrict POSTS to version 1.0. + OldProtocol := FProtocolVersion; + try + // If hoKeepOrigProtocol is SET, is possible to assume that the developer + // is sure in operations of the server + if not (hoKeepOrigProtocol in FOptions) then begin + if Connected then begin + Disconnect; + end; + FProtocolVersion := pv1_0; + end; + DoRequest(Id_HTTPMethodPost, AURL, ASource, AResponseContent, []); + finally + FProtocolVersion := OldProtocol; + end; +end; + +// RLebeau 12/21/2010: this is based on W3's HTML standards: +// +// HTML 4.01 +// http://www.w3.org/TR/html401/ +// +// HTML 5 +// http://www.w3.org/TR/html5/ + +function WWWFormUrlEncode(const ASrc: string; AByteEncoding: IIdTextEncoding + {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding{$ENDIF} + ): string; +const + // HTML 4.01 Section 17.13.4 ("Form content types") says: + // + // application/x-www-form-urlencoded + // + // Control names and values are escaped. Space characters are replaced by `+', + // and then reserved characters are escaped as described in [RFC1738], section + // 2.2: Non-alphanumeric characters are replaced by `%HH', a percent sign and + // two hexadecimal digits representing the ASCII code of the character. Line + // breaks are represented as "CR LF" pairs (i.e., `%0D%0A'). + // + // On the other hand, HTML 5 Section 4.10.16.4 ("URL-encoded form data") says: + // + // If the character isn't in the range U+0020, U+002A, U+002D, U+002E, + // U+0030 .. U+0039, U+0041 .. U+005A, U+005F, U+0061 .. U+007A then replace + // the character with a string formed as follows: Start with the empty string, + // and then, taking each byte of the character when expressed in the selected + // character encoding in turn, append to the string a U+0025 PERCENT SIGN + // character (%) followed by two characters in the ranges U+0030 DIGIT ZERO (0) + // to U+0039 DIGIT NINE (9) and U+0041 LATIN CAPITAL LETTER A to + // U+005A LATIN CAPITAL LETTER Z representing the hexadecimal value of the + // byte zero-padded if necessary). + // + // If the character is a U+0020 SPACE character, replace it with a single + // U+002B PLUS SIGN character (+). + // + // So, lets err on the side of caution and use the HTML 5.x definition, as it + // encodes some of the characters that HTML 4.01 allows unencoded... + // + SafeChars: TIdUnicodeString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789*-._'; {do not localize} +var + I, J, CharLen, ByteLen: Integer; + Buf: TIdBytes; + {$IFDEF STRING_IS_ANSI} + LChars: TIdWideChars; + {$ENDIF} + LChar: WideChar; + Encoded: Boolean; +begin + Result := ''; + + // keep the compiler happy + Buf := nil; + {$IFDEF STRING_IS_ANSI} + LChars := nil; + {$ENDIF} + + if ASrc = '' then begin + Exit; + end; + + EnsureEncoding(AByteEncoding, encUTF8); + {$IFDEF STRING_IS_ANSI} + EnsureEncoding(ASrcEncoding, encOSDefault); + LChars := ASrcEncoding.GetChars( + {$IFNDEF VCL_6_OR_ABOVE} + // RLebeau: for some reason, Delphi 5 causes a "There is no overloaded + // version of 'GetChars' that can be called with these arguments" compiler + // error if the PByte type-cast is used, even though GetChars() actually + // expects a PByte as input. Must be a compiler bug, as it compiles fine + // in Delphi 6. So, converting to TIdBytes until I find a better solution... + RawToBytes(PAnsiChar(ASrc)^, Length(ASrc)) + {$ELSE} + PByte(PAnsiChar(ASrc)), Length(ASrc) + {$ENDIF} + ); + {$ENDIF} + + // 2 Chars to handle UTF-16 surrogates + SetLength(Buf, AByteEncoding.GetMaxByteCount(2)); + + I := 0; + while I < Length({$IFDEF STRING_IS_UNICODE}ASrc{$ELSE}LChars{$ENDIF}) do + begin + LChar := {$IFDEF STRING_IS_UNICODE}ASrc[I+1]{$ELSE}LChars[I]{$ENDIF}; + + // RLebeau 1/7/09: using Ord() for #128-#255 because in D2009 and later, the + // compiler may change characters >= #128 from their Ansi codepage value to + // their true Unicode codepoint value, depending on the codepage used for + // the source code. For instance, #128 may become #$20AC... + + if Ord(LChar) = 32 then + begin + Result := Result + '+'; {do not localize} + Inc(I); + end + else if WideCharIsInSet(SafeChars, LChar) then + begin + Result := Result + Char(LChar); + Inc(I); + end else + begin + // HTML 5 Section 4.10.16.4 says: + // + // For each character ... that cannot be expressed using the selected character + // encoding, replace the character by a string consisting of a U+0026 AMPERSAND + // character (&), a U+0023 NUMBER SIGN character (#), one or more characters in + // the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9) representing the + // Unicode code point of the character in base ten, and finally a U+003B + // SEMICOLON character (;). + // + CharLen := CalcUTF16CharLength( + {$IFDEF STRING_IS_UNICODE}ASrc, I+1{$ELSE}LChars, I{$ENDIF} + ); // calculate length including surrogates + ByteLen := AByteEncoding.GetBytes( + {$IFDEF STRING_IS_UNICODE}ASrc, I+1{$ELSE}LChars, I{$ENDIF}, + CharLen, Buf, 0); // explicit Unicode->Ansi conversion + + Encoded := (ByteLen > 0); + if Encoded and (LChar <> '?') then begin {do not localize} + for J := 0 to ByteLen-1 do begin + if Buf[J] = Ord('?') then begin {do not localize} + Encoded := False; + Break; + end; + end; + end; + + if Encoded then begin + for J := 0 to ByteLen-1 do begin + Result := Result + '%' + IntToHex(Ord(Buf[J]), 2); {do not localize} + end; + end else begin + J := GetUTF16Codepoint( + {$IFDEF STRING_IS_UNICODE}ASrc, I+1{$ELSE}LChars, I{$ENDIF}); + Result := Result + '&#' + IntToStr(J) + ';'; {do not localize} + end; + + Inc(I, CharLen); + end; + end; +end; + +function TIdCustomHTTP.SetRequestParams(ASource: TStrings; AByteEncoding: IIdTextEncoding + {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding{$ENDIF} + ): string; +var + i: Integer; + LPos: integer; + LStr: string; + LTemp: TStringList; + {$IFDEF HAS_TStrings_NameValueSeparator} + LChar: string; + J: Integer; + {$ENDIF} + + function EncodeLineBreaks(AStrings: TStrings): String; + begin + if AStrings.Count > 1 then begin + // break trailing CR&LF + Result := ReplaceAll(Trim(AStrings.Text), + {$IFDEF HAS_TStrings_LineBreak}AStrings.LineBreak{$ELSE}sLineBreak{$ENDIF}, + '&'); {do not localize} + end else begin + Result := Trim(AStrings.Text); + end; + end; + +begin + if Assigned(ASource) then begin + if hoForceEncodeParams in FOptions then begin + // make a copy of ASource so the caller's TStrings object is not modified + LTemp := TStringList.Create; + try + LTemp.Assign(ASource); + for i := 0 to LTemp.Count - 1 do begin + LStr := LTemp[i]; + {$IFDEF HAS_TStrings_NameValueSeparator} + // RLebeau 11/8/16: Calling Pos() with a Char as input creates a temporary + // String. Normally this is fine, but profiling reveils this to be a big + // bottleneck for code that makes a lot of calls to Pos() in a loop, so we + // will scan through the string looking for the character without a conversion... + // + // LPos := IndyPos(LTemp.NameValueSeparator, LStr); + // + LChar := LTemp.NameValueSeparator; + LPos := 0; + for J := 1 to Length(LStr) do begin + //if CharEquals(LStr, LPos, LChar) then begin + if LStr[J] = LChar then begin + LPos := J; + Break; + end; + end; + {$ELSE} + LPos := IndyPos('=', LStr); {do not localize} + {$ENDIF} + if LPos > 0 then begin + LTemp[i] := WWWFormUrlEncode(LTemp.Names[i], AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF}) + + '=' {do not localize} + + WWWFormUrlEncode(IndyValueFromIndex(LTemp, i), AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF}); + end else begin + LTemp[i] := WWWFormUrlEncode(LStr, AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF}); + end; + end; + Result := EncodeLineBreaks(LTemp); + finally + LTemp.Free; + end; + end else begin + Result := EncodeLineBreaks(ASource); + end; + end else begin + Result := ''; + end; +end; + +function TIdCustomHTTP.Post(AURL: string; const ASourceFile: String + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; +var + LSource: TIdReadFileExclusiveStream; +begin + LSource := TIdReadFileExclusiveStream.Create(ASourceFile); + try + Result := Post(AURL, LSource{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); + finally + FreeAndNil(LSource); + end; +end; + +procedure TIdCustomHTTP.Post(AURL: string; const ASourceFile: String; AResponseContent: TStream); +var + LSource: TStream; +begin + LSource := TIdReadFileExclusiveStream.Create(ASourceFile); + try + Post(AURL, LSource, AResponseContent); + finally + FreeAndNil(LSource); + end; +end; + +procedure TIdCustomHTTP.Post(AURL: string; ASource: TStrings; AResponseContent: TStream; + AByteEncoding: IIdTextEncoding = nil + {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF} + ); +var + LParams: TMemoryStream; +begin + // Usual posting request have default ContentType is application/x-www-form-urlencoded + if (Request.ContentType = '') or IsContentTypeHtml(Request) then begin + Request.ContentType := 'application/x-www-form-urlencoded'; {do not localize} + end; + + if ASource <> nil then + begin + LParams := TMemoryStream.Create; + try + WriteStringToStream(LParams, SetRequestParams(ASource, AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF})); + LParams.Position := 0; + Post(AURL, LParams, AResponseContent); + finally + FreeAndNil(LParams); + end; + end else begin + Post(AURL, TStream(nil), AResponseContent); + end; +end; + +function TIdCustomHTTP.Post(AURL: string; ASource: TStrings; AByteEncoding: IIdTextEncoding = nil + {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; +var + LResponse: TMemoryStream; +begin + LResponse := TMemoryStream.Create; + try + Post(AURL, ASource, LResponse, AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF}); + LResponse.Position := 0; + Result := ReadStringAsCharset(LResponse, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); + // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... + finally + FreeAndNil(LResponse); + end; +end; + +function TIdCustomHTTP.Post(AURL: string; ASource: TStream + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; +var + LResponse: TMemoryStream; +begin + LResponse := TMemoryStream.Create; + try + Post(AURL, ASource, LResponse); + LResponse.Position := 0; + Result := ReadStringAsCharset(LResponse, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); + // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... + finally + FreeAndNil(LResponse); + end; +end; + +procedure TIdCustomHTTP.Put(AURL: string; ASource, AResponseContent: TStream); +begin + DoRequest(Id_HTTPMethodPut, AURL, ASource, AResponseContent, []); +end; + +function TIdCustomHTTP.Put(AURL: string; ASource: TStream + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; +var + LResponse: TMemoryStream; +begin + LResponse := TMemoryStream.Create; + try + Put(AURL, ASource, LResponse); + LResponse.Position := 0; + Result := ReadStringAsCharset(LResponse, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); + // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... + finally + FreeAndNil(LResponse); + end; +end; + +function TIdCustomHTTP.Get(AURL: string + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; +begin + Result := Get(AURL, []{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); +end; + +function TIdCustomHTTP.Trace(AURL: string + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; +var + LResponse: TMemoryStream; +begin + LResponse := TMemoryStream.Create; + try + Trace(AURL, LResponse); + LResponse.Position := 0; + Result := ReadStringAsCharset(LResponse, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); + // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... + finally + FreeAndNil(LResponse); + end; +end; + +function TIdCustomHTTP.DoOnRedirect(var Location: string; var VMethod: TIdHTTPMethod; RedirectCount: integer): boolean; +begin + // TODO: convert relative URLs to full URLs here... + Result := HandleRedirects; + if Assigned(FOnRedirect) then begin + FOnRedirect(Self, Location, RedirectCount, Result, VMethod); + end; +end; + +procedure TIdCustomHTTP.SetCookies(AURL: TIdURI; ARequest: TIdHTTPRequest); +var + // under ARC, convert a weak reference to a strong reference before working with it + LCookieManager: TIdCookieManager; +begin + if AllowCookies then begin + LCookieManager := FCookieManager; + if Assigned(LCookieManager) then + begin + // Send secure cookies only if we have Secured connection + LCookieManager.GenerateClientCookies( + AURL, + TextIsSame(AURL.Protocol, 'HTTPS'), {do not localize} + ARequest.RawHeaders); + end; + end; +end; + +// This function sets the Host and Port and returns a boolean depending on +// whether a PROXY is being used or not. + +function TIdCustomHTTP.SetHostAndPort: TIdHTTPConnectionType; +var + LHost: string; + LPort: Integer; +begin + // First check to see if a Proxy has been specified. + if Length(ProxyParams.ProxyServer) > 0 then begin + if (not TextIsSame(FHost, ProxyParams.ProxyServer)) or (FPort <> ProxyParams.ProxyPort) then begin + if Connected then begin + Disconnect; + end; + end; + LHost := ProxyParams.ProxyServer; + LPort := ProxyParams.ProxyPort; + if TextIsSame(URL.Protocol, 'HTTPS') then begin {do not localize} + Result := ctSSLProxy; + end else begin + Result := ctProxy; + end; + end else begin + if Assigned(Socket) then begin + if Assigned(Socket.Binding) then begin + if URL.IPVersion <> Socket.Binding.IPVersion then begin + if Connected then begin + Disconnect; // get rid of current socket handle + end; + end; + end; + end; + LHost := URL.Host; + LPort := IndyStrToInt(URL.Port, IdPORT_HTTP); + if (not TextIsSame(FHost, LHost)) or (LPort <> FPort) then begin + if Connected then begin + Disconnect; + end; + end; + if TextIsSame(URL.Protocol, 'HTTPS') then begin {do not localize} + Result := ctSSL; + end else begin + Result := ctNormal; + end; + end; + Host := LHost; + Port := LPort; +end; + +// TODO: move the XML charset detector below to the IdGlobalProtocols unit so +// it can be used in other components, like TIdMessageClient and TIdIMAP4... + +type + XmlEncoding = (xmlUCS4BE, xmlUCS4BEOdd, xmlUCS4LE, xmlUCS4LEOdd, + xmlUTF16BE, xmlUTF16LE, xmlUTF8, xmlEBCDIC, xmlUnknown + ); + + XmlBomInfo = record + Charset: String; + BOMLen: Integer; + BOM: UInt32; + BOMMask: UInt32; + end; + + XmlNonBomInfo = record + CharLen: Integer; + FirstChar: UInt32; + LastChar: UInt32; + CharMask: UInt32; + end; + +const + XmlBOMs: array[xmlUCS4BE..xmlUTF8] of XmlBomInfo = ( + (Charset: 'UCS-4BE'; BOMLen: 4; BOM: $0000FEFF; BOMMask: $FFFFFFFF), {do not localize} + (Charset: ''; {UCS-4} BOMLen: 4; BOM: $0000FFFE; BOMMask: $FFFFFFFF), + (Charset: 'UCS-4LE'; BOMLen: 4; BOM: $FFFE0000; BOMMask: $FFFFFFFF), {do not localize} + (Charset: ''; {UCS-4} BOMLen: 4; BOM: $FEFF0000; BOMMask: $FFFFFFFF), + (Charset: 'UTF-16BE'; BOMLen: 2; BOM: $FEFF0000; BOMMask: $FFFF0000), {do not localize} + (Charset: 'UTF-16LE'; BOMLen: 2; BOM: $FFFE0000; BOMMask: $FFFF0000), {do not localize} + (Charset: 'UTF-8'; BOMLen: 3; BOM: $EFBBBF00; BOMMask: $FFFFFF00) {do not localize} + ); + + XmlNonBOMs: array[xmlUCS4BE..xmlEBCDIC] of XmlNonBomInfo = ( + (CharLen: 4; FirstChar: $0000003C; LastChar: $0000003E; CharMask: $FFFFFFFF), + (CharLen: 4; FirstChar: $00003C00; LastChar: $00003E00; CharMask: $FFFFFFFF), + (CharLen: 4; FirstChar: $3C000000; LastChar: $3E000000; CharMask: $FFFFFFFF), + (CharLen: 4; FirstChar: $003C0000; LastChar: $003E0000; CharMask: $FFFFFFFF), + (CharLen: 2; FirstChar: $003C003F; LastChar: $003E0000; CharMask: $FFFF0000), + (CharLen: 2; FirstChar: $3C003F00; LastChar: $3E000000; CharMask: $FFFF0000), + (CharLen: 1; FirstChar: $3C3F786D; LastChar: $3E000000; CharMask: $FF000000), + (CharLen: 1; FirstChar: $4C6FA794; LastChar: $6E000000; CharMask: $FF000000) + ); + + XmlUCS4AsciiIndex: array[xmlUCS4BE..xmlUCS4LEOdd] of Integer = (3, 2, 0, 1); + + // RLebeau: only interested in EBCDIC ASCII characters that are allowed in + // an XML declaration, we'll treat everything else as #01 for now... + XmlEBCDICTable: array[Byte] of Char = ( + { -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -A -B -C -D -E -F } + {0-} #01, #01, #01, #01, #01, #09, #01, #01, #01, #01, #01, #01, #01, #13, #01, #01, {do not localize} + {1-} #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, {do not localize} + {2-} #01, #01, #01, #01, #01, #10, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, {do not localize} + {3-} #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, {do not localize} + {4-} ' ', #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, '.', '<', #01, #01, #01, {do not localize} + {5-} #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, {do not localize} + {6-} '-', #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, '_', '>', '?', {do not localize} + {7-} #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #27, '=', '"', {do not localize} + {8-} #01, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', #01, #01, #01, #01, #01, #01, {do not localize} + {9-} #01, 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', #01, #01, #01, #01, #01, #01, {do not localize} + {A-} #01, #01, 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', #01, #01, #01, #01, #01, #01, {do not localize} + {B-} #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, #01, {do not localize} + {C-} #01, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', #01, #01, #01, #01, #01, #01, {do not localize} + {D-} #01, 'J', 'K', 'L', 'N', 'N', 'O', 'P', 'Q', 'R', #01, #01, #01, #01, #01, #01, {do not localize} + {E-} #01, #01, 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', #01, #01, #01, #01, #01, #01, {do not localize} + {F-} '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', #01, #01, #01, #01, #01, #01 {do not localize} + ); + +function DetectXmlCharset(AStream: TStream): String; +var + Buffer: TIdBytes; + InBuf, StreamPos, CurPos: TIdStreamSize; + XmlDec, XmlEnc: String; + {$IFDEF STRING_IS_IMMUTABLE} + LSB: TIdStringBuilder; + {$ENDIF} + I, Len: Integer; + Enc: XmlEncoding; + Signature: UInt32; + + function BufferToUInt32: UInt32; + begin + Result := (UInt32(Buffer[0]) shl 24) or + (UInt32(Buffer[1]) shl 16) or + (UInt32(Buffer[2]) shl 8) or + UInt32(Buffer[3]); + end; + +begin + // XML's default encoding is UTF-8 unless specified otherwise, either + // by a BOM or an explicit "encoding" in the XML's prolog... + + Result := 'UTF-8'; {do not localize} + + if AStream = nil then begin + Exit; + end; + + StreamPos := AStream.Position; + try + AStream.Position := 0; + + SetLength(Buffer, 4); + FillBytes(Buffer, 4, $00); + + InBuf := ReadTIdBytesFromStream(AStream, Buffer, 4); + if InBuf < 3 then begin + Exit; + end; + + Signature := BufferToUInt32; + + // check for known BOMs first... + + for Enc := Low(XmlBOMs) to High(XmlBOMs) do begin + if (Signature and XmlBOMs[Enc].BOMMask) = XmlBOMs[Enc].BOM then begin + Inc(StreamPos, XmlBOMs[Enc].BOMLen); + Result := XmlBOMs[Enc].Charset; + Exit; + end; + end; + + // check for non-BOM'ed encodings now... + + if InBuf <> 4 then begin + Exit; + end; + + XmlDec := ''; + + for Enc := Low(XmlNonBOMs) to High(XmlNonBOMs) do begin + if Signature = XmlNonBOMs[Enc].FirstChar then begin + FillBytes(Buffer, 4, $00); + while (AStream.Size - AStream.Position) >= XmlNonBOMs[Enc].CharLen do + begin + ReadTIdBytesFromStream(AStream, Buffer, XmlNonBOMs[Enc].CharLen); + Signature := BufferToUInt32; + if (Signature and XmlNonBOMs[Enc].CharMask) = XmlNonBOMs[Enc].LastChar then + begin + CurPos := AStream.Position; + AStream.Position := 0; + case Enc of + xmlUCS4BE, xmlUCS4LE, xmlUCS4BEOdd, xmlUCS4LEOdd: begin + // TODO: create UCS-4 IIdTextEncoding implementations... + Len := CurPos div XmlNonBOMs[Enc].CharLen; + {$IFDEF STRING_IS_IMMUTABLE} + LSB := TIdStringBuilder.Create(Len); + {$ELSE} + SetLength(XmlDec, Len); + {$ENDIF} + for I := 1 to Len do begin + ReadTIdBytesFromStream(AStream, Buffer, XmlNonBOMs[Enc].CharLen); + {$IFDEF STRING_IS_IMMUTABLE} + LSB.Append(Char(Buffer[XmlUCS4AsciiIndex[Enc]])); + {$ELSE} + XmlDec[I] := Char(Buffer[XmlUCS4AsciiIndex[Enc]]); + {$ENDIF} + end; + {$IFDEF STRING_IS_IMMUTABLE} + XmlDec := LSB.ToString; + LSB := nil; + {$ENDIF} + end; + xmlUTF16BE: begin + XmlDec := ReadStringFromStream(AStream, CurPos, IndyTextEncoding_UTF16BE); + end; + xmlUTF16LE: begin + XmlDec := ReadStringFromStream(AStream, CurPos, IndyTextEncoding_UTF16LE); + end; + xmlUTF8: begin + XmlDec := ReadStringFromStream(AStream, CurPos, IndyTextEncoding_UTF8); + end; + xmlEBCDIC: begin + // TODO: create an EBCDIC IIdTextEncoding implementation... + {$IFDEF STRING_IS_IMMUTABLE} + Len := ReadTIdBytesFromStream(AStream, Buffer, CurPos); + LSB := TStringBuilder.Create(Len); + for I := 0 to Len-1 do begin + LSB.Append(XmlEBCDICTable[Buffer[I]]); + end; + XmlDec := LSB.ToString; + {$ELSE} + XmlDec := ReadStringFromStream(AStream, CurPos, IndyTextEncoding_8Bit); + for I := 1 to Length(XmlDec) do begin + XmlDec[I] := XmlEBCDICTable[Byte(XmlDec[I])]; + end; + {$ENDIF} + end; + end; + Break; + end; + end; + Break; + end; + end; + + if XmlDec = '' then begin + Exit; + end; + + I := Pos('encoding', XmlDec); {do not localize} + if I = 0 then begin + Exit; + end; + + XmlDec := TrimLeft(Copy(XmlDec, I+8, MaxInt)); + if not CharEquals(XmlDec, 1, '=') then begin {do not localize} + Exit; + end; + + XmlDec := TrimLeft(Copy(XmlDec, 2, MaxInt)); + if XmlDec = '' then begin + Exit; + end; + + if XmlDec[1] = #$27 then begin + XmlDec := Copy(XmlDec, 2, MaxInt); + XmlEnc := Fetch(XmlDec, #$27); + end + else if XmlDec[1] = '"' then begin + XmlDec := Copy(XmlDec, 2, MaxInt); + XmlEnc := Fetch(XmlDec, '"'); + end; + + XmlEnc := Trim(XmlEnc); + if XmlEnc = '' then begin + Exit; + end; + + Result := XmlEnc; + finally + AStream.Position := StreamPos; + end; +end; + +procedure TIdCustomHTTP.ReadResult(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); +var + LS: TStream; + LOrigStream, LTmpStream : TStream; + LParseMeth : Integer; + //0 - no parsing + //1 - html + //2 - xml + LCreateTmpContent : Boolean; + LDecMeth : Integer; + //0 - no compression was used or we can't support that feature + //1 - deflate + //2 - gzip + // under ARC, convert a weak reference to a strong reference before working with it + LCompressor: TIdZLibCompressorBase; + + function CheckForPendingData(ATimeout: Integer): Boolean; + begin + Result := not IOHandler.InputBufferIsEmpty; + if not Result then begin + IOHandler.CheckForDataOnSource(ATimeout); + Result := not IOHandler.InputBufferIsEmpty; + end; + end; + + function ShouldRead: Boolean; + var + CanRead: Boolean; + begin + Result := False; + if IndyPos('chunked', LowerCase(AResponse.TransferEncoding)) > 0 then begin {do not localize} + CanRead := not (hoNoReadChunked in FOptions); + end + else if AResponse.HasContentLength then begin + CanRead := AResponse.ContentLength > 0; // If chunked then this is also 0 + end + else if IsHeaderMediaType(AResponse.ContentType, 'multipart') then begin {do not localize} + CanRead := not (hoNoReadMultipartMIME in FOptions); + end + else begin + CanRead := True; + end; + if CanRead then + begin + // DO NOT READ IF THE REQUEST IS HEAD!!! + // The server is supposed to send a 'Content-Length' header without sending + // the actual data. 1xx, 204, and 304 replies are not supposed to contain + // entity bodies, either... + if TextIsSame(ARequest.Method, Id_HTTPMethodHead) or + ({TextIsSame(ARequest.Method, Id_HTTPMethodPost) and} TextIsSame(ARequest.MethodOverride, Id_HTTPMethodHead)) or + // TODO: check for 'X-HTTP-Method' and 'X-METHOD-OVERRIDE' request headers as well... + ((AResponse.ResponseCode div 100) = 1) or + (AResponse.ResponseCode = 204) or + (AResponse.ResponseCode = 304) then + begin + // Have noticed one case where a non-conforming server did send an + // entity body in response to a HEAD request. If requested, ignore + // anything the server may send by accident + if not (hoWaitForUnexpectedData in FOptions) then begin + Exit; + end; + Result := CheckForPendingData(100); + end + else if (AResponse.ResponseCode div 100) = 3 then + begin + // This is a workaround for buggy HTTP 1.1 servers which + // does not return any body with 302 response code + Result := CheckForPendingData(5000); + end else begin + Result := True; + end; + end; + end; + + function ChunkSize: integer; + var + j: Integer; + s: string; + begin + s := InternalReadLn; + j := IndyPos(';', s); {do not localize} + if j > 0 then begin + s := Copy(s, 1, j - 1); + end; + Result := IndyStrToInt('$' + Trim(s), 0); {do not localize} + end; + + procedure ReadChunked; + var + LSize: Integer; + LTrailHeader: String; + LChunk : TIdBytes; + begin + DoStatus(hsStatusText, [RSHTTPChunkStarted]); + BeginWork(wmRead); + try + LSize := ChunkSize; + while LSize <> 0 do begin + // TODO: fire OnChunkReceived even if LS is nil? This way, the caller + // can choose to pass AContentStream=nil and rely solely on OnChunkReceived + // in cases where a chunked response is expected up front, like in + // server-side pushes... + if Assigned(LS) then begin + if Assigned(FOnChunkReceived) then begin + SetLength(LChunk, LSize); + IOHandler.ReadBytes(LChunk, LSize, False); + if Assigned(FOnChunkReceived) then begin + FOnChunkReceived(Self, LChunk); + end; + WriteTIdBytesToStream(LS, LChunk); + end else begin + IOHandler.ReadStream(LS, LSize); + end; + end else begin + IOHandler.Discard(LSize); + end; + InternalReadLn; // CRLF at end of chunk data + LSize := ChunkSize; + end; + // read trailer headers + LTrailHeader := InternalReadLn; + while LTrailHeader <> '' do begin + AResponse.RawHeaders.Add(LTrailHeader); + LTrailHeader := InternalReadLn; + end; + finally + EndWork(wmRead); + end; + end; + + procedure ReadMIME; + var + LMIMEBoundary: TIdBytes; + LIndex: Integer; + LSize: Integer; + begin + LMIMEBoundary := ToBytes('--' + ExtractHeaderSubItem(AResponse.ContentType, 'boundary', QuoteHTTP) + '--'); + BeginWork(wmRead); + try + try + repeat + LIndex := IOHandler.InputBuffer.IndexOf(LMIMEBoundary); + if LIndex <> -1 then + begin + LSize := LIndex + Length(LMIMEBoundary); + if Assigned(LS) then begin + // TODO: use TIdBuffer.ExtractToStream() instead, bypassing the + // overhead of TIdIOHandler.ReadStream() allocating a local buffer + // and calling IOHandler.ReadBytes() to fill that buffer in even + // multiples of the IOHandler's RecvBufferSize. The data we want + // is already in the Buffer's memory, so just read it directly... + // + // IOHandler.InputBuffer.ExtractToStream(LS, LSize); + IOHandler.ReadStream(LS, LSize); + end else begin + IOHandler.Discard(LSize); + end; + InternalReadLn; // CRLF at end of boundary + Break; + end; + LSize := IOHandler.InputBuffer.Size - (Length(LMIMEBoundary)-1); + if LSize > 0 then begin + if Assigned(LS) then begin + // TODO: use TIdBuffer.ExtractToStream() instead, bypassing the + // overhead of TIdIOHandler.ReadStream() allocating a local buffer + // and calling IOHandler.ReadBytes() to fill that buffer in even + // multiples of the IOHandler's RecvBufferSize. The data we want + // is already in the Buffer's memory, so just read it directly... + // + // IOHandler.InputBuffer.ExtractToStream(LS, LSize); + IOHandler.ReadStream(LS, LSize); + end else begin + IOHandler.Discard(LSize); + end; + end; + IOHandler.CheckForDataOnSource; + IOHandler.CheckForDisconnect(True, True); + until False; + except + on E: EIdConnClosedGracefully do begin + if Assigned(LS) then begin + IOHandler.InputBuffer.ExtractToStream(LS); + end else begin + IOHandler.InputBuffer.Clear; + end; + end; + end; + finally + EndWork(wmRead); + end; + end; + +begin + if not ShouldRead then begin + Exit; + end; + + LParseMeth := 0; + LDecMeth := 0; + + if Assigned(AResponse.ContentStream) then begin + if IsContentTypeHtml(AResponse) then begin + if not (hoNoParseMetaHTTPEquiv in FOptions) then begin + LParseMeth := 1; + end; + end + else if IsContentTypeAppXml(Response) then begin + if not (hoNoParseXmlCharset in FOptions) then begin + LParseMeth := 2; + end; + end; + end; + + // under ARC, AResponse.ContentStream uses weak referencing, so need to + // use local strong references to keep the streams alive... + LOrigStream := AResponse.ContentStream; + LCreateTmpContent := (LParseMeth <> 0) and not (LOrigStream is TCustomMemoryStream); + if LCreateTmpContent then begin + LTmpStream := TMemoryStream.Create; + end else begin + LTmpStream := nil; + end; + + try + if LCreateTmpContent then begin + AResponse.ContentStream := LTmpStream; + end; + + // we need to determine what type of decompression may need to be used + // before we read from the IOHandler. If there is compression, then we + // use a local stream to download the compressed data and decompress it. + // If no compression is used, ContentStream will be used directly + + LCompressor := Compressor; + if Assigned(AResponse.ContentStream) then begin + if Assigned(LCompressor) and LCompressor.IsReady then begin + LDecMeth := PosInStrArray(AResponse.ContentEncoding, ['deflate', 'gzip'], False) + 1; {do not localize} + end; + if LDecMeth > 0 then begin + LS := TMemoryStream.Create; + end else begin + LS := AResponse.ContentStream; + end; + end else + begin + LS := nil; + end; + + try + if IndyPos('chunked', LowerCase(AResponse.TransferEncoding)) > 0 then begin {do not localize} + ReadChunked; + end + else if AResponse.HasContentLength then begin + if AResponse.ContentLength > 0 then begin// If chunked then this is also 0 + try + if Assigned(LS) then begin + IOHandler.ReadStream(LS, AResponse.ContentLength); + end else begin + IOHandler.Discard(AResponse.ContentLength); + end; + except + // should this be caught here? We are being told the size, so a + // premature disconnect should be an error, right? + on E: EIdConnClosedGracefully do begin end; + end; + end; + end + else if IsHeaderMediaType(AResponse.ContentType, 'multipart') then begin {do not localize} + ReadMIME; + end else begin + if Assigned(LS) then begin + IOHandler.ReadStream(LS, -1, True); + end else begin + IOHandler.DiscardAll; + end; + end; + if LDecMeth > 0 then begin + LS.Position := 0; + case LDecMeth of + 1 : LCompressor.DecompressDeflateStream(LS, AResponse.ContentStream); + 2 : LCompressor.DecompressGZipStream(LS, AResponse.ContentStream); + end; + end; + finally + if LDecMeth > 0 then begin + FreeAndNil(LS); + end; + end; + case LParseMeth of + 1: begin + // RLebeau 1/30/2012: parse HTML tags, update Response.CharSet ... + AResponse.ProcessMetaHTTPEquiv; + end; + 2: begin + // the media type is not a 'text/...' based XML type, so ignore the + // charset from the headers, if present, and parse the XML itself... + AResponse.CharSet := DetectXmlCharset(AResponse.ContentStream); + end; + else + // TODO: if a Charset is not specified, return an appropriate value + // that is registered with IANA for the reported ContentType... + end; + finally + if LCreateTmpContent then + begin + try + LOrigStream.CopyFrom(LTmpStream, 0); + finally + {$IFNDEF USE_OBJECT_ARC} + LTmpStream.Free; + {$ENDIF} + AResponse.ContentStream := LOrigStream; + end; + end; + end; +end; + +const + Requires_HTTP_1_1: array[0..4] of String = (Id_HTTPMethodTrace, Id_HTTPMethodPut, Id_HTTPMethodOptions, Id_HTTPMethodDelete, Id_HTTPMethodPatch); + Requires_Content_Length: array[0..1] of String = (Id_HTTPMethodPost, Id_HTTPMethodPut); + +procedure TIdCustomHTTP.PrepareRequest(ARequest: TIdHTTPRequest); +var + LURI: TIdURI; + LHost: string; +begin + LURI := TIdURI.Create(ARequest.URL); + + try + if Length(LURI.Username) > 0 then begin + ARequest.Username := LURI.Username; + ARequest.Password := LURI.Password; + end; + + FURI.Username := ARequest.Username; + FURI.Password := ARequest.Password; + + FURI.Path := ProcessPath(FURI.Path, LURI.Path); + FURI.Document := LURI.Document; + FURI.Params := LURI.Params; + + if Length(LURI.Host) > 0 then begin + FURI.Host := LURI.Host; + end; + + if Length(LURI.Protocol) > 0 then begin + FURI.Protocol := LURI.Protocol; + end + // non elegant solution - to be recoded, only for pointing the bug / GREGOR + else if TextIsSame(FURI.Protocol, 'https') then begin {do not localize} + FURI.Protocol := 'https'; {do not localize} + end + else begin + FURI.Protocol := 'http'; {do not localize} + end; + + if Length(LURI.Port) > 0 then begin + FURI.Port := LURI.Port; + end + else if TextIsSame(LURI.Protocol, 'http') then begin {do not localize} + FURI.Port := IntToStr(IdPORT_HTTP); + end + else if TextIsSame(LURI.Protocol, 'https') then begin {do not localize} + FURI.Port := IntToStr(IdPORT_https); + end + else if Length(FURI.Port) = 0 then begin + raise EIdUnknownProtocol.Create(RSHTTPUnknownProtocol); + end; + + if (TextIsSame(ARequest.Method, Id_HTTPMethodOptions) or TextIsSame(ARequest.MethodOverride, Id_HTTPMethodOptions)) + and TextIsSame(LURI.Document, '*') then {do not localize} + begin + ARequest.URL := LURI.Document; + end else begin + // The URL part is not URL encoded at this place + ARequest.URL := URL.GetPathAndParams; + end; + + ARequest.IPVersion := LURI.IPVersion; + FURI.IPVersion := ARequest.IPVersion; + + // Check for valid HTTP request methods + if (PosInStrArray(ARequest.Method, Requires_HTTP_1_1, False) > -1) or + (PosInStrArray(ARequest.MethodOverride, Requires_HTTP_1_1, False) > -1) then + begin + if ProtocolVersion <> pv1_1 then begin + raise EIdException.Create(RSHTTPMethodRequiresVersion); // TODO: create a new Exception class for this + end; + end; + + if Assigned(ARequest.Source) then begin + ARequest.ContentLength := ARequest.Source.Size; + end + else if PosInStrArray(ARequest.Method, Requires_Content_Length, False) > -1 then begin + ARequest.ContentLength := 0; + end else begin + ARequest.ContentLength := -1; + end; + + // RLebeau: wrap an IPv6 address in brackets, per RFC 2732, and RFC 3986 section 3.2.2... + if (FURI.IPVersion = Id_IPv6) and (MakeCanonicalIPv6Address(FURI.Host) <> '') then begin + LHost := '[' + FURI.Host + ']'; {do not localize} + end else begin + LHost := FURI.Host; + end; + + if (TextIsSame(FURI.Protocol, 'http') and (FURI.Port = IntToStr(IdPORT_HTTP))) or {do not localize} + (TextIsSame(FURI.Protocol, 'https') and (FURI.Port = IntToStr(IdPORT_https))) then {do not localize} + begin + ARequest.Host := LHost; + end else begin + ARequest.Host := LHost + ':' + FURI.Port; {do not localize} + end; + finally + FreeAndNil(LURI); // Free URI Object + end; +end; + +procedure TIdCustomHTTP.CheckAndConnect(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); +begin + if not AResponse.KeepAlive then begin + Disconnect; + end; + + if Assigned(IOHandler) then begin + IOHandler.InputBuffer.Clear; + end; + + CheckForGracefulDisconnect(False); + + if not Connected then try + IPVersion := FURI.IPVersion; + + case ARequest.UseProxy of + ctNormal, ctProxy: + begin + if (IOHandler is TIdSSLIOHandlerSocketBase) then begin + TIdSSLIOHandlerSocketBase(IOHandler).PassThrough := True; + TIdSSLIOHandlerSocketBase(IOHandler).URIToCheck := FURI.URI; + end; + end; + + ctSSL, ctSSLProxy: + begin + // if an IOHandler has not been assigned yet, try to create a default SSL IOHandler object + // + // TODO: if an IOHandler has been assigned, but is not an SSL IOHandler, + // release it and try to create a default SSL IOHandler object? + // + if IOHandler = nil then begin + IOHandler := TIdIOHandler.TryMakeIOHandler(TIdSSLIOHandlerSocketBase, Self); + if IOHandler = nil then begin + raise EIdIOHandlerPropInvalid.Create(RSIOHandlerPropInvalid); + end; + ManagedIOHandler := True; + IOHandler.OnStatus := OnStatus; // TODO: assign DoStatus() instead of the handler directly... + end + else if not (IOHandler is TIdSSLIOHandlerSocketBase) then begin + raise EIdIOHandlerPropInvalid.Create(RSIOHandlerPropInvalid); + end; + TIdSSLIOHandlerSocketBase(IOHandler).URIToCheck := FURI.URI; + TIdSSLIOHandlerSocketBase(IOHandler).PassThrough := (ARequest.UseProxy = ctSSLProxy); + end; + end; + + Connect; + except + on E: EIdSSLProtocolReplyError do begin + Disconnect; + raise; + end; + end; +end; + +procedure TIdCustomHTTP.ConnectToHost(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); +var + LLocalHTTP: TIdHTTPProtocol; + LUseConnectVerb: Boolean; + // under ARC, convert a weak reference to a strong reference before working with it + LCompressor: TIdZLibCompressorBase; + LOldProxy: TIdHTTPConnectionType; + LNewDest: string; +begin + // RLebeau 5/29/2018: before doing anything else, clear the InputBuffer. If a + // previous HTTPS request through an SSL/TLS proxy fails due to a user-defined + // OnVerifyPeer handler returning False, the proxy tunnel is still established, + // but the underlying socket may be closed, and unread data left behind in the + // InputBuffer that will cause Connected() below to return True when it should + // be False instead. This leads to a situation where TIdHTTP can skip sending + // a CONNECT request when it creates a new socket connection to the proxy, but + // send an unencrypted HTTP request to the proxy, which may then get forwarded + // to the HTTPS server over a previously cached SSL/TLS tunnel... + + if Assigned(IOHandler) then begin + IOHandler.InputBuffer.Clear; + end; + + LNewDest := URL.Host + ':' + URL.Port; + + LOldProxy := ARequest.FUseProxy; + ARequest.FUseProxy := SetHostAndPort; + + if ARequest.UseProxy <> LOldProxy then begin + if Connected then begin + Disconnect; + end; + end + else if (ARequest.UseProxy = ctSSLProxy) and (not TextIsSame(ARequest.Destination, LNewDest)) then begin + if Connected then begin + Disconnect; + end; + end; + + ARequest.Destination := LNewDest; + + LUseConnectVerb := False; + + case ARequest.UseProxy of + ctNormal, ctSSL: + begin + if (ProtocolVersion = pv1_0) and (Length(ARequest.Connection) = 0) then + begin + ARequest.Connection := 'keep-alive'; {do not localize} + end; + end; + ctSSLProxy: + begin + // if already connected to an SSL proxy, DO NOT send another + // CONNECT request, as it will be sent directly to the target + // HTTP server and not to the proxy! + LUseConnectVerb := not Connected; + end; + ctProxy: + begin + ARequest.URL := FURI.URI; + if (ProtocolVersion = pv1_0) and (Length(ARequest.Connection) = 0) then + begin + // TODO: per RFC 7230: + // "clients are encouraged not to send the Proxy-Connection header field in any requests." + ARequest.ProxyConnection := 'keep-alive'; {do not localize} + end; + if hoNonSSLProxyUseConnectVerb in FOptions then begin + // if already connected to a proxy, DO NOT send another CONNECT + // request, as it will be sent directly to the target HTTP server + // and not to the proxy! + LUseConnectVerb := not Connected; + end; + end; + end; + + LCompressor := FCompressor; + if Assigned(LCompressor) and LCompressor.IsReady then begin + if IndyPos('deflate', ARequest.AcceptEncoding) = 0 then {do not localize} + begin + if ARequest.AcceptEncoding <> '' then begin {do not localize} + ARequest.AcceptEncoding := ARequest.AcceptEncoding + ', deflate'; {do not localize} + end else begin + ARequest.AcceptEncoding := 'deflate'; {do not localize} + end; + end; + if IndyPos('gzip', ARequest.AcceptEncoding) = 0 then {do not localize} + begin + if ARequest.AcceptEncoding <> '' then begin {do not localize} + ARequest.AcceptEncoding := ARequest.AcceptEncoding + ', gzip'; {do not localize} + end else begin + ARequest.AcceptEncoding := 'gzip'; {do not localize} + end; + end; + end else + begin + // TODO: if ARequest.AcceptEncoding is asking for deflate/gzip compression, + // remove it, unless the caller is prepared to decompress the data manually... + end; + {$IFDEF USE_OBJECT_ARC}LCompressor := nil;{$ENDIF} + + // RLebeau 1/10/2015: if AcceptEncoding is blank, DON'T set it to 'identity'! + // Oddly, some faulty servers do not understand 'identity' when explicitly + // stated. 'identity' is the default behavior when no "Accept-Encoding" header + // is present, so just let the server fallback to that normally... + if ARequest.AcceptEncoding <> '' then begin + if IndyPos('identity', ARequest.AcceptEncoding) = 0 then begin {do not localize} + ARequest.AcceptEncoding := ARequest.AcceptEncoding + ', identity'; {do not localize} + end; + // TODO: if AcceptEncoding is 'identity', set it to a blank string? + { + if TextIsSame(ARequest.AcceptEncoding, 'identity') then begin {do not localize + ARequest.AcceptEncoding := ''; + end; + } + end; + + if LUseConnectVerb then begin + LLocalHTTP := CreateProtocol; + try + LLocalHTTP.Request.UserAgent := ARequest.UserAgent; + LLocalHTTP.Request.Host := ARequest.Host; + LLocalHTTP.Request.Pragma := 'no-cache'; {do not localize} + LLocalHTTP.Request.URL := ARequest.Destination; + LLocalHTTP.Request.Method := Id_HTTPMethodConnect; + // TODO: per RFC 7230: + // "clients are encouraged not to send the Proxy-Connection header field in any requests." + LLocalHTTP.Request.ProxyConnection := 'keep-alive'; {do not localize} + LLocalHTTP.Request.FUseProxy := ARequest.UseProxy; + + // leaving LLocalHTTP.Response.ContentStream set to nil so response data is discarded without wasting memory + try + repeat + CheckAndConnect(LLocalHTTP.Request, LLocalHTTP.Response); + LLocalHTTP.BuildAndSendRequest(nil); + + LLocalHTTP.Response.ResponseText := InternalReadLn; + if Length(LLocalHTTP.Response.ResponseText) = 0 then begin + // Support for HTTP responses without status line and headers + LLocalHTTP.Response.ResponseText := 'HTTP/1.0 200 OK'; {do not localize} + LLocalHTTP.Response.Connection := 'close'; {do not localize} + end else begin + LLocalHTTP.RetrieveHeaders(MaxHeaderLines); + ProcessCookies(LLocalHTTP.Request, LLocalHTTP.Response); + end; + + if (LLocalHTTP.Response.ResponseCode div 100) = 2 then begin + // Connection established + if (ARequest.UseProxy = ctSSLProxy) and (IOHandler is TIdSSLIOHandlerSocketBase) then begin + TIdSSLIOHandlerSocketBase(IOHandler).PassThrough := False; + end; + Break; + end; + + case LLocalHTTP.ProcessResponse([]) of + wnAuthRequest: + begin + LLocalHTTP.Request.URL := ARequest.Destination; + end; + wnReadAndGo: + begin + ReadResult(LLocalHTTP.Request, LLocalHTTP.Response); + FAuthRetries := 0; + FAuthProxyRetries := 0; + end; + wnGoToURL: + begin + FAuthRetries := 0; + FAuthProxyRetries := 0; + end; + wnJustExit: + begin + Break; + end; + wnDontKnow: + begin + raise EIdException.Create(RSHTTPNotAcceptable); // TODO: create a new Exception class for this + end; + end; + until False; + except + raise; + // TODO: Add property that will contain the error messages. + end; + finally + FreeAndNil(LLocalHTTP); + end; + end else begin + CheckAndConnect(ARequest, AResponse); + end; + + FHTTPProto.BuildAndSendRequest(URL); + + // RLebeau 1/31/2008: in order for TIdWebDAV to post data correctly, don't + // restrict which HTTP methods can post (except logically for GET and HEAD), + // especially since TIdCustomHTTP.PrepareRequest() does not differentiate when + // setting up the 'Content-Length' header ... + + // TODO: when sending an HTTP 1.1 request with an 'Expect: 100-continue' header, + // do not send the Source data until the server replies with a 100 response code, + // or until a timeout occurs if the server does not send a 100... + + if ARequest.Source <> nil then begin + IOHandler.Write(ARequest.Source, 0, False); + end; +end; + +procedure TIdCustomHTTP.SetAllowCookies(AValue: Boolean); +begin + FAllowCookies := AValue; +end; + +procedure TIdCustomHTTP.ProcessCookies(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse); +var + LCookies: TStringList; + // under ARC, convert a weak reference to a strong reference before working with it + LCookieManager: TIdCookieManager; +begin + if AllowCookies then + begin + LCookieManager := FCookieManager; + + if not Assigned(LCookieManager) then begin + LCookieManager := TIdCookieManager.Create(Self); + SetCookieManager(LCookieManager); + FImplicitCookieManager := True; + end; + + LCookies := TStringList.Create; + try + AResponse.RawHeaders.Extract('Set-Cookie', LCookies); {do not localize} + AResponse.MetaHTTPEquiv.RawHeaders.Extract('Set-Cookie', LCookies); {do not localize} + LCookieManager.AddServerCookies(LCookies, FURI); + finally + FreeAndNil(LCookies); + end; + end; +end; + +// under ARC, all weak references to a freed object get nil'ed automatically +// so this is mostly redundant +procedure TIdCustomHTTP.Notification(AComponent: TComponent; Operation: TOperation); +begin + if Operation = opRemove then begin + if (AComponent = FCookieManager) then begin + FCookieManager := nil; + FImplicitCookieManager := False; + end + {$IFNDEF USE_OBJECT_ARC} + else if (AComponent = FAuthenticationManager) then begin + FAuthenticationManager := nil; + end else if (AComponent = FCompressor) then begin + FCompressor := nil; + end + {$ENDIF} + ; + end; + inherited Notification(AComponent, Operation); +end; + +procedure TIdCustomHTTP.SetCookieManager(ACookieManager: TIdCookieManager); +var + // under ARC, convert a weak reference to a strong reference before working with it + LCookieManager: TIdCookieManager; +begin + LCookieManager := FCookieManager; + + if LCookieManager <> ACookieManager then + begin + // under ARC, all weak references to a freed object get nil'ed automatically + + if Assigned(LCookieManager) then begin + if FImplicitCookieManager then begin + FCookieManager := nil; + FImplicitCookieManager := False; + IdDisposeAndNil(LCookieManager); + end else begin + {$IFNDEF USE_OBJECT_ARC} + LCookieManager.RemoveFreeNotification(Self); + {$ENDIF} + end; + end; + + FCookieManager := ACookieManager; + FImplicitCookieManager := False; + + {$IFNDEF USE_OBJECT_ARC} + if Assigned(ACookieManager) then begin + ACookieManager.FreeNotification(Self); + end; + {$ENDIF} + end; +end; + +function TIdCustomHTTP.DoOnAuthorization(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse): Boolean; +var + i: Integer; + S: string; + LAuthCls: TIdAuthenticationClass; + LAuth: TIdAuthentication; +begin + Inc(FAuthRetries); + + // TODO: trigger OnSelectAuthorization on every request, or at least if + // FAuthRetries is 1, or the server has sent a new 'WWW-Authenticate' + // list that does not include the class currently assigned... + if not Assigned(ARequest.Authentication) then begin + // Find wich Authentication method is supported from us. + LAuthCls := nil; + + for i := 0 to AResponse.WWWAuthenticate.Count - 1 do begin + S := AResponse.WWWAuthenticate[i]; + LAuthCls := FindAuthClass(Fetch(S)); + if Assigned(LAuthCls) then begin + Break; + end; + end; + + // let the user override us, if desired. + if Assigned(FOnSelectAuthorization) then begin + OnSelectAuthorization(Self, LAuthCls, AResponse.WWWAuthenticate); + end; + + if not Assigned(LAuthCls) then begin + Result := False; + Exit; + end; + + ARequest.Authentication := LAuthCls.Create; + end; + + { + this is commented out as it breaks SSPI and NTLM authentication. it is + normal and expected to get multiple 407 responses during negotiation. + + // Clear password and reset autorization if previous failed + if (AResponse.FResponseCode = 401) then begin + ARequest.Password := ''; + ARequest.Authentication.Reset; + end; + } + + // S.G. 20/10/2003: Added part about the password. Not testing user name as some + // S.G. 20/10/2003: web sites do not require user name, only password. + // + // RLebeau 11/18/2014: what about SSPI? It does not require an explicit + // username/password as it can use the identity of the user token associated + // with the calling thread! + + LAuth := ARequest.Authentication; + LAuth.Username := ARequest.Username; + LAuth.Password := ARequest.Password; + // S.G. 20/10/2003: ToDo: We need to have a marker here to prevent the code to test with the same username/password combo + // S.G. 20/10/2003: if they are picked up from properties. + LAuth.Params.Values['Authorization'] := ARequest.Authentication.Authentication; {do not localize} + LAuth.AuthParams := AResponse.WWWAuthenticate; + + Result := False; + + repeat + case LAuth.Next of + wnAskTheProgram: + begin // Ask the user porgram to supply us with authorization information + if not Assigned(FOnAuthorization) then + begin + Result := False; + Break; + end; + + LAuth.UserName := ARequest.Username; + LAuth.Password := ARequest.Password; + + OnAuthorization(Self, LAuth, Result); + if not Result then begin + Break; + end; + + ARequest.BasicAuthentication := True; + ARequest.Username := LAuth.UserName; + ARequest.Password := LAuth.Password; + end; + wnDoRequest: + begin + Result := True; + Break; + end; + wnFail: + begin + Result := False; + Break; + end; + end; + until False; +end; + +function TIdCustomHTTP.DoOnProxyAuthorization(ARequest: TIdHTTPRequest; AResponse: TIdHTTPResponse): Boolean; +var + i: Integer; + S: string; + LAuthCls: TIdAuthenticationClass; + LAuth: TIdAuthentication; +begin + Inc(FAuthProxyRetries); + + // TODO: trigger OnSelectProxyAuthorization on every request, or at least if + // FAuthProxyRetries is 1, or the server has sent a new 'Proxy-Authenticate' + // list that does not include the class currently assigned... + if not Assigned(ProxyParams.Authentication) then begin + // Find which Authentication method is supported from us. + LAuthCls := nil; + + for i := 0 to AResponse.ProxyAuthenticate.Count-1 do begin + S := AResponse.ProxyAuthenticate[i]; + LAuthCls := FindAuthClass(Fetch(S)); + if Assigned(LAuthCls) then begin + Break; + end; + end; + + // let the user override us, if desired. + if Assigned(FOnSelectProxyAuthorization) then begin + OnSelectProxyAuthorization(Self, LAuthCls, AResponse.ProxyAuthenticate); + end; + + if not Assigned(LAuthCls) then begin + Result := False; + Exit; + end; + + ProxyParams.Authentication := LAuthCls.Create; + end; + + { + this is commented out as it breaks SSPI and NTLM authentication. it is + normal and expected to get multiple 407 responses during negotiation. + + // Clear password and reset authorization if previous failed + if (AResponse.FResponseCode = 407) then begin + ProxyParams.ProxyPassword := ''; + ProxyParams.Authentication.Reset; + end; + } + + // RLebeau 11/18/2014: Added part about the password. Not testing user name + // as some proxies do not require user name, only password. + // + // RLebeau 11/18/2014: what about SSPI? It does not require an explicit + // username/password as it can use the identity of the user token associated + // with the calling thread! + + LAuth := ProxyParams.Authentication; + LAuth.Username := ProxyParams.ProxyUsername; + LAuth.Password := ProxyParams.ProxyPassword; + // TODO: do we need to set this, like DoOnAuthorization does? + //LAuth.Params.Values['Authorization'] := ProxyParams.Authentication; {do not localize} + LAuth.AuthParams := AResponse.ProxyAuthenticate; + + Result := False; + + repeat + case LAuth.Next of + wnAskTheProgram: // Ask the user porgram to supply us with authorization information + begin + if not Assigned(OnProxyAuthorization) then begin + Result := False; + Break; + end; + + LAuth.Username := ProxyParams.ProxyUsername; + LAuth.Password := ProxyParams.ProxyPassword; + + OnProxyAuthorization(Self, LAuth, Result); + if not Result then begin + Break; + end; + + // TODO: do we need to set this, like DoOnAuthorization does? + //ProxyParams.BasicAuthentication := True; + ProxyParams.ProxyUsername := LAuth.Username; + ProxyParams.ProxyPassword := LAuth.Password; + end; + wnDoRequest: + begin + Result := True; + Break; + end; + wnFail: + begin + Result := False; + Break; + end; + end; + until False; +end; + +function TIdCustomHTTP.GetResponseCode: Integer; +begin + Result := Response.ResponseCode; +end; + +function TIdCustomHTTP.GetResponseText: string; +begin + Result := Response.ResponseText; +end; + +function TIdCustomHTTP.GetResponse: TIdHTTPResponse; +begin + Result := FHTTPProto.Response; +end; + +function TIdCustomHTTP.GetRequest: TIdHTTPRequest; +begin + Result := FHTTPProto.Request; +end; + +function TIdCustomHTTP.GetMetaHTTPEquiv: TIdMetaHTTPEquiv; +begin + Result := Response.MetaHTTPEquiv; +end; + +procedure TIdCustomHTTP.DoOnDisconnected; +var + // under ARC, convert weak references to strong references before working with them + LAuthManager: TIdAuthenticationManager; + LAuth: TIdAuthentication; +begin + // TODO: in order to handle the case where authentications are used when + // keep-alives are in effect, move this logic somewhere more appropriate, + // like at the end of DoRequest()... + + inherited DoOnDisconnected; + + LAuth := Request.Authentication; + if Assigned(LAuth) and (LAuth.CurrentStep = LAuth.Steps) then + begin + LAuthManager := AuthenticationManager; + if Assigned(LAuthManager) then begin + LAuthManager.AddAuthentication(LAuth, URL); + end; + {$IFNDEF USE_OBJECT_ARC} + LAuth.Free; + {$ENDIF} + Request.Authentication := nil; + end; + + LAuth := ProxyParams.Authentication; + if Assigned(LAuth) and (LAuth.CurrentStep = LAuth.Steps) then begin + LAuth.Reset; + end; +end; + +procedure TIdCustomHTTP.SetAuthenticationManager(Value: TIdAuthenticationManager); +begin + {$IFDEF USE_OBJECT_ARC} + // under ARC, all weak references to a freed object get nil'ed automatically + FAuthenticationManager := Value; + {$ELSE} + if FAuthenticationManager <> Value then begin + if Assigned(FAuthenticationManager) then begin + FAuthenticationManager.RemoveFreeNotification(self); + end; + FAuthenticationManager := Value; + if Assigned(FAuthenticationManager) then begin + FAuthenticationManager.FreeNotification(Self); + end; + end; + {$ENDIF} +end; + +{ +procedure TIdCustomHTTP.SetHost(const Value: string); +begin + inherited SetHost(Value); + URL.Host := Value; +end; + +procedure TIdCustomHTTP.SetPort(const Value: integer); +begin + inherited SetPort(Value); + URL.Port := IntToStr(Value); +end; +} +procedure TIdCustomHTTP.SetRequest(Value: TIdHTTPRequest); +begin + FHTTPProto.Request.Assign(Value); +end; + +procedure TIdCustomHTTP.SetProxyParams(AValue: TIdProxyConnectionInfo); +begin + FProxyParameters.Assign(AValue); +end; + +procedure TIdCustomHTTP.Post(AURL: string; ASource: TIdMultiPartFormDataStream; + AResponseContent: TStream); +begin + Assert(ASource<>nil); + Request.ContentType := ASource.RequestContentType; + // TODO: Request.CharSet := ASource.RequestCharSet; + Post(AURL, TStream(ASource), AResponseContent); +end; + +function TIdCustomHTTP.Post(AURL: string; ASource: TIdMultiPartFormDataStream + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} +): string; +begin + Assert(ASource<>nil); + Request.ContentType := ASource.RequestContentType; + // TODO: Request.CharSet := ASource.RequestCharSet; + Result := Post(AURL, TStream(ASource){$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); +end; + +{ TIdHTTPResponse } + +constructor TIdHTTPResponse.Create(AHTTP: TIdCustomHTTP); +begin + inherited Create(AHTTP); + FHTTP := AHTTP; + FResponseCode := -1; + FMetaHTTPEquiv := TIdMetaHTTPEquiv.Create(AHTTP); +end; + +destructor TIdHTTPResponse.Destroy; +begin + FreeAndNil(FMetaHTTPEquiv); + inherited Destroy; +end; + +procedure TIdHTTPResponse.Clear; +begin + inherited Clear; + ResponseText := ''; + FMetaHTTPEquiv.Clear; +end; + +procedure TIdHTTPResponse.ProcessMetaHTTPEquiv; +var + StdValues: TStringList; + I: Integer; + Name: String; +begin + FMetaHTTPEquiv.ProcessMetaHTTPEquiv(ContentStream); + if FMetaHTTPEquiv.RawHeaders.Count > 0 then begin + // TODO: optimize this + StdValues := TStringList.Create; + try + FMetaHTTPEquiv.RawHeaders.ConvertToStdValues(StdValues); + for I := 0 to StdValues.Count-1 do begin + Name := StdValues.Names[I]; + if Name <> '' then begin + RawHeaders.Values[Name] := IndyValueFromIndex(StdValues, I); + end; + end; + finally + StdValues.Free; + end; + ProcessHeaders; + end; + if FMetaHTTPEquiv.CharSet <> '' then begin + FCharSet := FMetaHTTPEquiv.CharSet; + end; +end; + +function TIdHTTPResponse.GetKeepAlive: Boolean; +begin + if FHTTP.Connected then begin + FHTTP.IOHandler.CheckForDisconnect(False); + end; + + // has the connection already been closed? + FKeepAlive := FHTTP.Connected; + + if FKeepAlive then + begin + // did the client request the connection to be closed? + FKeepAlive := not TextIsSame(Trim(FHTTP.Request.Connection), 'CLOSE'); {do not localize} + if FKeepAlive and (FHTTP.Request.UseProxy in [ctProxy, ctSSLProxy]) then begin + FKeepAlive := not TextIsSame(Trim(FHTTP.Request.ProxyConnection), 'CLOSE'); {do not localize} + end; + end; + + if FKeepAlive then + begin + // did the server/proxy say the connection will be closed? + case FHTTP.ProtocolVersion of // TODO: use ResponseVersion instead? + pv1_1: + { By default we assume that keep-alive is used and will close + the connection only if there is "close" } + begin + FKeepAlive := not TextIsSame(Trim(Connection), 'CLOSE'); {do not localize} + if FKeepAlive and (FHTTP.Request.UseProxy in [ctProxy, ctSSLProxy]) then begin + FKeepAlive := not TextIsSame(Trim(ProxyConnection), 'CLOSE'); {do not localize} + end; + end; + pv1_0: + { By default we assume that keep-alive is not used and will keep + the connection only if there is "keep-alive" } + begin + FKeepAlive := TextIsSame(Trim(Connection), 'KEEP-ALIVE') {do not localize} + { or ((ResponseVersion = pv1_1) and (Trim(Connection) = '')) } + ; + if FKeepAlive and (FHTTP.Request.UseProxy in [ctProxy, ctSSLProxy]) then begin + FKeepAlive := TextIsSame(Trim(ProxyConnection), 'KEEP-ALIVE') {do not localize} + { or ((ResponseVersion = pv1_1) and (Trim(ProxyConnection) = '')) } + ; + end; + end; + end; + end; + + Result := FKeepAlive; +end; + +function TIdHTTPResponse.GetResponseCode: Integer; +var + S, Tmp: string; +begin + if FResponseCode = -1 then + begin + S := FResponseText; + Fetch(S); + S := Trim(S); + // RLebeau: IIS supports status codes with decimals in them, but it is not supposed to + // transmit them to clients, which is a violation of RFC 2616. But have seen it happen, + // so check for it... + Tmp := Fetch(S, ' ', False); {do not localize} + S := Fetch(Tmp, '.', False); {do not localize} + FResponseCode := IndyStrToInt(S, -1); + end; + Result := FResponseCode; +end; + +procedure TIdHTTPResponse.SetResponseText(const AValue: String); +var + S: String; + i: TIdHTTPProtocolVersion; +begin + FResponseText := AValue; + FResponseCode := -1; // re-parse the next time it is accessed + FResponseVersion := pv1_0; // default until determined otherwise... + S := Copy(FResponseText, 6, 3); + for i := Low(TIdHTTPProtocolVersion) to High(TIdHTTPProtocolVersion) do begin + if TextIsSame(ProtocolVersionString[i], S) then begin + FResponseVersion := i; + Exit; + end; + end; +end; + +{ TIdHTTPRequest } + +constructor TIdHTTPRequest.Create(AHTTP: TIdCustomHTTP); +begin + inherited Create(AHTTP); + FHTTP := AHTTP; + FUseProxy := ctNormal; + FIPVersion := ID_DEFAULT_IP_VERSION; +end; + +{ TIdHTTPProtocol } + +constructor TIdHTTPProtocol.Create(AConnection: TIdCustomHTTP); +begin + inherited Create; + FHTTP := AConnection; + // Create the headers + FRequest := TIdHTTPRequest.Create(FHTTP); + FResponse := TIdHTTPResponse.Create(FHTTP); +end; + +destructor TIdHTTPProtocol.Destroy; +begin + FreeAndNil(FRequest); + FreeAndNil(FResponse); + inherited Destroy; +end; + +procedure TIdHTTPProtocol.BuildAndSendRequest(AURI: TIdURI); +var + i: Integer; + LBufferingStarted: Boolean; +begin + Response.Clear; + + // needed for Digest authentication, but maybe others as well... + if Assigned(Request.Authentication) then begin + // TODO: include entity body for Digest "auth-int" qop... + Request.Authentication.SetRequest(Request.Method, Request.URL); + end; + + // TODO: disable header folding for HTTP 1.0 requests + Request.SetHeaders; + FHTTP.ProxyParams.SetHeaders(Request.RawHeaders); + if Assigned(AURI) then begin + FHTTP.SetCookies(AURI, Request); + end; + + // This is a workaround for some HTTP servers which do not implement + // the HTTP protocol properly + LBufferingStarted := not FHTTP.IOHandler.WriteBufferingActive; + if LBufferingStarted then begin + FHTTP.IOHandler.WriteBufferOpen; + end; + try + FHTTP.IOHandler.WriteLn(Request.Method + ' ' + Request.URL + ' HTTP/' + ProtocolVersionString[FHTTP.ProtocolVersion]); {do not localize} + // write the headers + for i := 0 to Request.RawHeaders.Count - 1 do begin + if Length(Request.RawHeaders.Strings[i]) > 0 then begin + FHTTP.IOHandler.WriteLn(Request.RawHeaders.Strings[i]); + end; + end; + FHTTP.IOHandler.WriteLn; + if LBufferingStarted then begin + FHTTP.IOHandler.WriteBufferClose; + end; + except + if LBufferingStarted then begin + FHTTP.IOHandler.WriteBufferCancel; + end; + raise; + end; +end; + +procedure TIdHTTPProtocol.RetrieveHeaders(AMaxHeaderCount: integer); +var + s: string; + LHeaderCount: Integer; +begin + // Set the response headers + // Don't use Capture. + // S.G. 6/4/2004: Added AmaxHeaderCount parameter to prevent the "header bombing" of the server + s := FHTTP.InternalReadLn; + try + LHeaderCount := 0; + while (s <> '') and ( (AMaxHeaderCount > 0) or (LHeaderCount < AMaxHeaderCount) ) do + begin + Response.RawHeaders.Add(S); + s := FHTTP.InternalReadLn; + Inc(LHeaderCount); + end; + except + on E: Exception do begin + FHTTP.Disconnect; + if not (E is EIdConnClosedGracefully) then begin + raise; + end; + end; + end; + Response.ProcessHeaders; +end; + +function TIdHTTPProtocol.ProcessResponse(AIgnoreReplies: array of Int16): TIdHTTPWhatsNext; +var + LResponseCode, LResponseDigit: Integer; + + procedure CheckException; + var + i: Integer; + LTempStream: TMemoryStream; + LOrigStream: TStream; + LRaiseException: Boolean; + LDiscardContent: Boolean; + begin + LRaiseException := True; + LDiscardContent := True; + + if hoNoProtocolErrorException in FHTTP.HTTPOptions then begin + LRaiseException := False; + LDiscardContent := not (hoWantProtocolErrorContent in FHTTP.HTTPOptions); + end + else if High(AIgnoreReplies) > -1 then begin + for i := Low(AIgnoreReplies) to High(AIgnoreReplies) do begin + if LResponseCode = AIgnoreReplies[i] then begin + LRaiseException := False; + LDiscardContent := not (hoWantProtocolErrorContent in FHTTP.HTTPOptions); + Break; + end; + end; + end; + + if LRaiseException then begin + LTempStream := TMemoryStream.Create; + end else begin + LTempStream := nil; + end; + try + if LRaiseException or LDiscardContent then begin + LOrigStream := Response.ContentStream; + Response.ContentStream := LTempStream; + end else begin + LOrigStream := nil; + end; + try + try + FHTTP.ReadResult(Request, Response); + except + on E: Exception do begin + FHTTP.Disconnect; + if not (E is EIdConnClosedGracefully) then begin + raise; + end; + end; + end; + if LRaiseException then begin + LTempStream.Position := 0; + raise EIdHTTPProtocolException.CreateError(LResponseCode, Response.ResponseText, + ReadStringAsCharset(LTempStream, Response.CharSet)); + end; + finally + if LRaiseException or LDiscardContent then begin + Response.ContentStream := LOrigStream; + end; + end; + finally + if LRaiseException then begin + LTempStream.Free; + end; + end; + end; + + procedure DiscardContent; + var + LOrigStream: TStream; + begin + LOrigStream := Response.ContentStream; + Response.ContentStream := nil; + try + try + FHTTP.ReadResult(Request, Response); + except + on E: Exception do begin + FHTTP.Disconnect; + if not (E is EIdConnClosedGracefully) then begin + raise; + end; + end; + end; + finally + Response.ContentStream := LOrigStream; + end; + end; + + function HeadersCanContinue: Boolean; + begin + Result := True; + if Assigned(FHTTP.OnHeadersAvailable) then begin + FHTTP.OnHeadersAvailable(FHTTP, Response.RawHeaders, Result); + end; + end; + +var + LLocation: string; + LMethod: TIdHTTPMethod; + LNeedAuth: Boolean; + //LTemp: Integer; +begin + + // provide the user with the headers and let the user decide + // whether the response processing should continue... + if not HeadersCanContinue then begin + // TODO: provide the user an option whether to force DoRequest() to disconnect the connection or not + Response.KeepAlive := False; + Response.Connection := 'close'; {do not localize} + Result := wnJustExit; + Exit; + end; + + // Cache this as ResponseCode calls GetResponseCode which parses it out + LResponseCode := Response.ResponseCode; + LResponseDigit := LResponseCode div 100; + LNeedAuth := False; + + // Handle Redirects + // RLebeau: All 3xx replies other than 304 are redirects. Reply 201 has a + // Location header but is NOT a redirect! + + // RLebeau 4/21/2011: Amazon S3 includes a Location header in its 200 reply + // to some PUT requests. Not sure if this is a bug or intentional, but we + // should NOT perform a redirect for any replies other than 3xx. Amazon S3 + // does NOT include a Location header in its 301 reply, though! This is + // intentional, per Amazon's documentation, as a way for developers to + // detect when URLs are addressed incorrectly... + + if (LResponseDigit = 3) and (LResponseCode <> 304) then + begin + if Response.Location = '' then begin + CheckException; + Result := wnJustExit; + Exit; + end; + + Inc(FHTTP.FRedirectCount); + + // LLocation := TIdURI.URLDecode(Response.Location); + LLocation := Response.Location; + LMethod := Request.Method; + + // fire the event + if not FHTTP.DoOnRedirect(LLocation, LMethod, FHTTP.FRedirectCount) then begin + CheckException; + Result := wnJustExit; + Exit; + end; + + if (FHTTP.FHandleRedirects) and (FHTTP.FRedirectCount < FHTTP.FRedirectMax) then begin + Result := wnGoToURL; + Request.URL := LLocation; + + // GDG 21/11/2003. If it's a 303, we should do a get this time + + // RLebeau 7/15/2004 - do a GET on 302 as well, as mentioned in RFC 2616 + + // RLebeau 1/11/2008 - turns out both situations are WRONG! RFCs 2068 and + // 2616 specifically state that changing the method to GET in response + // to 302 and 303 is errorneous. Indy 9 did it right by reusing the + // original method and source again and only changing the URL, so lets + // revert back to that same behavior! + + // RLebeau 12/28/2012 - one more time. RFCs 2068 and 2616 actually say that + // changing the method in response to 302 is erroneous, but changing the + // method to GET in response to 303 is intentional and why 303 was introduced + // in the first place. Erroneous clients treat 302 as 303, though. Now + // encountering servers that actually expect this 303 behavior, so we have + // to enable it again! Adding an optional HTTPOption flag so clients can + // enable the erroneous 302 behavior if they really need it. + + if ((LResponseCode = 302) and (hoTreat302Like303 in FHTTP.HTTPOptions)) or + (LResponseCode = 303) then + begin + Request.Source := nil; + Request.Method := Id_HTTPMethodGet; + // TODO: if the previous request was a POST with an 'application/x-www-webform-urlencoded' + // body, move the body data into the URL query string this time... + end else begin + Request.Method := LMethod; + end; + Request.MethodOverride := ''; + end else begin + Result := wnJustExit; + Response.Location := LLocation; + end; + + if FHTTP.Connected then begin + // This is a workaround for buggy HTTP 1.1 servers which + // does not return any body with 302 response code + DiscardContent; // may wait a few seconds for any kind of content + end; + end else begin + //Ciaran, 30th Nov 2004: I commented out the following code. When a https server + //sends a disconnect immediately after sending the requested page in an SSL + //session (which they sometimes do to indicate a "session" is finished), the code + //below causes a "Connection closed gracefully" exception BUT the returned page + //is lost (IOHandler.Request is empty). If the code below is re-enabled by + //someone for whatever reason, they MUST test for this case. + // GREGOR Workaround + // if we get an error we disconnect if we use SSLIOHandler + //if Assigned(FHTTP.IOHandler) then + //begin + // Response.KeepAlive := not (FHTTP.Connected and (FHTTP.IOHandler is TIdSSLIOHandlerSocketBase) and Response.KeepAlive); + //end; + + // RLebeau 2/15/2006: RFC 1945 states the following: + // + // For response messages, whether or not an entity body is included with + // a message is dependent on both the request method and the response + // code. All responses to the HEAD request method must not include a + // body, even though the presence of entity header fields may lead one + // to believe they do. All 1xx (informational), 204 (no content), and + // 304 (not modified) responses must not include a body. All other + // responses must include an entity body or a Content-Length header + // field defined with a value of zero (0). + + if LResponseDigit <> 2 then begin + case LResponseCode of + 101: + begin + Response.KeepAlive := True; + Result := wnJustExit; + Exit; + end; + 401: + begin // HTTP Server authorization required + if (FHTTP.AuthRetries >= FHTTP.MaxAuthRetries) or + (not FHTTP.DoOnAuthorization(Request, Response)) then begin + if Assigned(Request.Authentication) then begin + Request.Authentication.Reset; + end; + CheckException; + Result := wnJustExit; + Exit; + end else begin + LNeedAuth := hoInProcessAuth in FHTTP.HTTPOptions; + end; + end; + 407: + begin // Proxy Server authorization requered + if (FHTTP.AuthProxyRetries >= FHTTP.MaxAuthRetries) or + (not FHTTP.DoOnProxyAuthorization(Request, Response)) then + begin + if Assigned(FHTTP.ProxyParams.Authentication) then begin + FHTTP.ProxyParams.Authentication.Reset; + end; + CheckException; + Result := wnJustExit; + Exit; + end else begin + LNeedAuth := hoInProcessAuth in FHTTP.HTTPOptions; + end; + end; + else begin + CheckException; + Result := wnJustExit; + Exit; + end; + end; + end; + + if LNeedAuth then begin + // discard the content of Error message + DiscardContent; + Result := wnAuthRequest; + end else + begin + // RLebeau 6/30/2006: DO NOT READ IF THE REQUEST IS HEAD!!! + // The server is supposed to send a 'Content-Length' header + // without sending the actual data... + if TextIsSame(Request.Method, Id_HTTPMethodHead) or + TextIsSame(Request.MethodOverride, Id_HTTPMethodHead) or + (LResponseCode = 204) then + begin + // Have noticed one case where a non-conforming server did send an + // entity body in response to a HEAD request. If requested, ignore + // anything the server may send by accident + DiscardContent; + end else begin + FHTTP.ReadResult(Request, Response); + end; + Result := wnJustExit; + end; + end; +end; + +function TIdCustomHTTP.CreateProtocol: TIdHTTPProtocol; +begin + Result := TIdHTTPProtocol.Create(Self); +end; + +procedure TIdCustomHTTP.InitComponent; +begin + inherited; + FURI := TIdURI.Create(''); + + FAuthRetries := 0; + FAuthProxyRetries := 0; + AllowCookies := True; + FImplicitCookieManager := False; + FOptions := Id_TIdHTTP_HTTPOptions; + + FRedirectMax := Id_TIdHTTP_RedirectMax; + FHandleRedirects := Id_TIdHTTP_HandleRedirects; + // + FProtocolVersion := Id_TIdHTTP_ProtocolVersion; + + FHTTPProto := CreateProtocol; + FProxyParameters := TIdProxyConnectionInfo.Create; + FProxyParameters.Clear; + + FMaxAuthRetries := Id_TIdHTTP_MaxAuthRetries; + FMaxHeaderLines := Id_TIdHTTP_MaxHeaderLines; +end; + +function TIdCustomHTTP.InternalReadLn: String; +begin + // TODO: add ReadLnTimeoutAction property to TIdIOHandler... + Result := IOHandler.ReadLn; + if IOHandler.ReadLnTimedout then begin + raise EIdReadTimeout.Create(RSReadTimeout); + end; +end; + +function TIdCustomHTTP.Get(AURL: string; AIgnoreReplies: array of Int16 + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; +var + LStream: TMemoryStream; +begin + LStream := TMemoryStream.Create; + try + Get(AURL, LStream, AIgnoreReplies); + LStream.Position := 0; + Result := ReadStringAsCharset(LStream, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); + // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... + finally + FreeAndNil(LStream); + end; +end; + +procedure TIdCustomHTTP.Get(AURL: string; AResponseContent: TStream; + AIgnoreReplies: array of Int16); +begin + DoRequest(Id_HTTPMethodGet, AURL, nil, AResponseContent, AIgnoreReplies); +end; + +procedure TIdCustomHTTP.DoRequest(const AMethod: TIdHTTPMethod; + AURL: string; ASource, AResponseContent: TStream; + AIgnoreReplies: array of Int16); +var + LResponseLocation: TIdStreamSize; +begin + //reset any counters + FRedirectCount := 0; + FAuthRetries := 0; + FAuthProxyRetries := 0; + + if Assigned(AResponseContent) then begin + LResponseLocation := AResponseContent.Position; + end else begin + LResponseLocation := 0; // Just to avoid the warning message + end; + + Request.URL := AURL; + Request.Method := AMethod; + Request.Source := ASource; + Response.ContentStream := AResponseContent; + + try + repeat + PrepareRequest(Request); + if IOHandler is TIdSSLIOHandlerSocketBase then begin + TIdSSLIOHandlerSocketBase(IOHandler).URIToCheck := FURI.URI; + end; + ConnectToHost(Request, Response); + + // Workaround for servers which respond with 100 Continue on GET and HEAD + // This workaround is just for temporary use until we have final HTTP 1.1 + // realisation. HTTP 1.1 is ongoing because of all the buggy and conflicting servers. + // + // This is also necessary as servers are allowed to send any number of + // 1xx informational responses before sending the final response. + // + // Except in the case of 101 SWITCHING PROTOCOLS, which is a final response. + // The protocol on the line is then switched to the requested protocol, per + // the response's 'Upgrade' header, following the 101 response, so we need to + // stop and exit immediately if 101 is received, and let the caller handle + // the new protocol as needed. + repeat + Response.ResponseText := InternalReadLn; + FHTTPProto.RetrieveHeaders(MaxHeaderLines); + ProcessCookies(Request, Response); + if ((Response.ResponseCode div 100) <> 1) or (Response.ResponseCode = 101) then begin + Break; + end; + Response.Clear; + until False; + + case FHTTPProto.ProcessResponse(AIgnoreReplies) of + wnAuthRequest: + begin + Request.URL := AURL; + end; + wnReadAndGo: + begin + ReadResult(Request, Response); + if Assigned(AResponseContent) then begin + AResponseContent.Position := LResponseLocation; + AResponseContent.Size := LResponseLocation; + end; + FAuthRetries := 0; + FAuthProxyRetries := 0; + end; + wnGoToURL: + begin + if Assigned(AResponseContent) then begin + AResponseContent.Position := LResponseLocation; + AResponseContent.Size := LResponseLocation; + end; + FAuthRetries := 0; + FAuthProxyRetries := 0; + end; + wnJustExit: + begin + Break; + end; + wnDontKnow: + begin + raise EIdException.Create(RSHTTPNotAcceptable); // TODO: create a new Exception class for this + end; + end; + until False; + finally + if not ( + Response.KeepAlive or + ((hoNoReadMultipartMIME in FOptions) and IsHeaderMediaType(Response.ContentType, 'multipart')) or {do not localize} + ((hoNoReadChunked in FOptions) and (IndyPos('chunked', LowerCase(Response.TransferEncoding)) > 0)) {do not localize} + ) then + begin + Disconnect; + end; + end; +end; + +procedure TIdCustomHTTP.Patch(AURL: string; ASource, AResponseContent: TStream); +begin + DoRequest(Id_HTTPMethodPatch, AURL, ASource, AResponseContent, []); +end; + +function TIdCustomHTTP.Patch(AURL: string; ASource: TStream + {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF} + ): string; +var + LResponse: TMemoryStream; +begin + LResponse := TMemoryStream.Create; + try + Patch(AURL, ASource, LResponse); + LResponse.Position := 0; + Result := ReadStringAsCharset(LResponse, Response.Charset{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}); + // TODO: if the data is XML, add/update the declared encoding to 'UTF-16LE'... + finally + FreeAndNil(LResponse); + end; +end; + +end. + diff --git a/Lib/Protocols/IdIMAP4.pas b/Lib/Protocols/IdIMAP4.pas index 4348c31c0..81083adac 100644 --- a/Lib/Protocols/IdIMAP4.pas +++ b/Lib/Protocols/IdIMAP4.pas @@ -1,7262 +1,7262 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.66 3/24/2005 3:03:28 AM DSiders - Modified TIdIMAP4.ParseStatusResult to correct an endless loop parsing an odd - number of status messages/values in the server response. - - Rev 1.65 3/23/2005 3:03:40 PM DSiders - Modified TIdIMAP4.Destroy to free resources for Capabilities and MUtf7 - properties. - - Rev 1.64 3/4/2005 3:08:42 PM JPMugaas - Removed compiler warning with stream. You sometimes need to use IdStreamVCL. - - Rev 1.63 3/3/2005 12:54:04 PM JPMugaas - Replaced TStringList with TIdStringList. - - Rev 1.62 3/3/2005 12:09:04 PM JPMugaas - TStrings were replaced with TIdStrings. - - Rev 1.60 20/02/2005 20:41:06 CCostelloe - Cleanup and reorganisations - - Rev 1.59 11/29/2004 2:46:10 AM JPMugaas - I hope that this fixes a compile error. - - Rev 1.58 11/27/04 3:11:56 AM RLebeau - Fixed bug in ownership of SASLMechanisms property. - - Updated to use TextIsSame() instead of Uppercase() comparisons. - - Rev 1.57 11/8/2004 8:39:00 AM DSiders - Removed comment in TIdIMAP4.SearchMailBox implementation that caused DOM - problem when locating the symbol id. - - Rev 1.56 10/26/2004 10:19:58 PM JPMugaas - Updated refs. - - Rev 1.55 2004.10.26 2:19:56 PM czhower - Resolved alias conflict. - - Rev 1.54 6/11/2004 9:36:34 AM DSiders - Added "Do not Localize" comments. - - Rev 1.53 6/4/04 12:48:12 PM RLebeau - ContentTransferEncoding bug fix - - Rev 1.52 01/06/2004 19:03:46 CCostelloe - .NET bug fix - - Rev 1.51 01/06/2004 01:16:18 CCostelloe - Various improvements - - Rev 1.50 20/05/2004 22:04:14 CCostelloe - IdStreamVCL changes - - Rev 1.49 20/05/2004 08:43:12 CCostelloe - IdStream change - - Rev 1.48 16/05/2004 20:40:46 CCostelloe - New TIdText/TIdAttachment processing - - Rev 1.47 24/04/2004 23:54:42 CCostelloe - IMAP-style UTF-7 encoding/decoding of mailbox names added - - Rev 1.46 13/04/2004 22:24:28 CCostelloe - Bug fix (FCapabilities not created if not DOTNET) - - Rev 1.45 3/18/2004 2:32:40 AM JPMugaas - Should compile under D8 properly. - - Rev 1.44 3/8/2004 10:10:32 AM JPMugaas - IMAP4 should now have SASLMechanisms again. Those work in DotNET now. - SSL abstraction is now supported even in DotNET so that should not be - IFDEF'ed out. - - Rev 1.43 07/03/2004 17:55:16 CCostelloe - Updates to cover changes in other units - - Rev 1.42 2/4/2004 2:36:58 AM JPMugaas - Moved more units down to the implementation clause in the units to make them - easier to compile. - - Rev 1.41 2/3/2004 4:12:50 PM JPMugaas - Fixed up units so they should compile. - - Rev 1.40 2004.02.03 5:43:48 PM czhower - Name changes - - Rev 1.39 2004.02.03 2:12:10 PM czhower - $I path change - - Rev 1.38 1/27/2004 4:01:12 PM SPerry - StringStream ->IdStringStream - - Rev 1.37 1/25/2004 3:11:12 PM JPMugaas - SASL Interface reworked to make it easier for developers to use. - SSL and SASL reenabled components. - - Rev 1.36 23/01/2004 01:48:28 CCostelloe - Added BinHex4.0 encoding support for parts - - Rev 1.35 1/21/2004 3:10:40 PM JPMugaas - InitComponent - - Rev 1.34 31/12/2003 09:40:32 CCostelloe - ChangeReplyClass removed, replaced AnsiSameText with TextIsSame, stream code - not tested. - - Rev 1.33 28/12/2003 23:48:18 CCostelloe - More TEMPORARY fixes to get it to compile under D7 and D8 .NET - - Rev 1.32 22/12/2003 01:20:20 CCostelloe - .NET fixes. This is a TEMPORARY combined Indy9/10/.NET master file. - - Rev 1.31 14/12/2003 21:03:16 CCostelloe - First version for .NET - - Rev 1.30 10/17/2003 12:11:06 AM DSiders - Added localization comments. - Added resource strings for exception messages. - - Rev 1.29 2003.10.12 3:53:10 PM czhower - compile todos - - Rev 1.28 10/12/2003 1:49:50 PM BGooijen - Changed comment of last checkin - - Rev 1.27 10/12/2003 1:43:34 PM BGooijen - Changed IdCompilerDefines.inc to Core\IdCompilerDefines.inc - - Rev 1.26 20/09/2003 15:38:38 CCostelloe - More patches added for different IMAP servers - - Rev 1.25 12/08/2003 01:17:38 CCostelloe - Retrieve and AppendMsg updated to suit changes made to attachment encoding - changes in other units - - Rev 1.24 21/07/2003 01:22:24 CCostelloe - Added CopyMsg and UIDCopyMsgs. (UID)Receive(Peek) rewritten. AppendMsg - still buggy with attachments. Public variable FGreetingBanner added. Added - "if Connected then " to Destroy. Attachment filenames now decoded if - necessary. Added support for multisection parts. Resolved issue of some - servers leaving out the trailing "NIL NIL NIL" at the end of some body - structures. UIDRetrieveAllHeaders removed - - Rev 1.23 18/06/2003 21:53:36 CCostelloe - Rewrote GetResponse from scratch. Restored Capabilities for login. Compiles - and runs properly (may be a couple of minor bugs not yet discovered). - - Rev 1.22 6/16/2003 11:48:18 PM JPMugaas - Capabilities has to be restored for SASL and SSL support. - - Rev 1.21 17/06/2003 01:33:46 CCostelloe - Updated to support new LoginSASL. Compiles OK, may not yet run OK. - - Rev 1.20 12/06/2003 10:17:54 CCostelloe - Partial update for Indy 10's new Reply structure. Compiles but does not run - correctly. Checked in to show problem with Get/SetNumericCode in IdReplyIMAP. - - Rev 1.19 04/06/2003 02:33:44 CCostelloe - Compiles under Indy 10 with the revised Indy 10 structure, but does not yet - work properly due to some of the changes. Will be fixed by me in a later - check-in. - - Rev 1.18 14/05/2003 01:55:50 CCostelloe - This version (with the extra IMAP functionality recently added) now compiles - on Indy 10 and works in a real application. - - Rev 1.17 5/12/2003 02:19:56 AM JPMugaas - Now should work properly again. I also removed all warnings and errors in - Indy 10. - - Rev 1.16 5/11/2003 07:35:44 PM JPMugaas - - Rev 1.15 5/11/2003 07:11:06 PM JPMugaas - Fixed to eliminate some warnings and compile errors in Indy 10. - - Rev 1.14 11/05/2003 23:53:52 CCostelloe - Bug fix due to Windows 98 / 2000 discrepancies - - Rev 1.13 11/05/2003 23:08:36 CCostelloe - Lots more bug fixes, plus IMAP code moved up from IdRFCReply - - Rev 1.12 5/10/2003 07:31:22 PM JPMugaas - Updated with some bug fixes and some cleanups. - - Rev 1.11 5/9/2003 10:51:26 AM JPMugaas - Bug fixes. Now works as it should. Verified. - - Rev 1.9 5/9/2003 03:49:44 AM JPMugaas - IMAP4 now supports SASL. Merged some code from Ciaran which handles the + - SASL continue reply in IMAP4 and makes a few improvements. Verified to work - on two servers. - - Rev 1.8 5/8/2003 05:41:48 PM JPMugaas - Added constant for SASL continuation. - - Rev 1.7 5/8/2003 03:17:50 PM JPMugaas - Flattened ou the SASL authentication API, made a custom descendant of SASL - enabled TIdMessageClient classes. - - Rev 1.6 5/8/2003 11:27:52 AM JPMugaas - Moved feature negoation properties down to the ExplicitTLSClient level as - feature negotiation goes hand in hand with explicit TLS support. - - Rev 1.5 5/8/2003 02:17:44 AM JPMugaas - Fixed an AV in IdPOP3 with SASL list on forms. Made exceptions for SASL - mechanisms missing more consistant, made IdPOP3 support feature feature - negotiation, and consolidated some duplicate code. - - Rev 1.4 5/7/2003 10:20:32 PM JPMugaas - - Rev 1.3 5/7/2003 04:35:30 AM JPMugaas - IMAP4 should now compile. Started on prelimary SSL support (not finished - yet). - - Rev 1.2 15/04/2003 00:57:08 CCostelloe - - Rev 1.1 2/24/2003 09:03:06 PM JPMugaas - - Rev 1.0 11/13/2002 07:54:50 AM JPMugaas - - 2001-FEB-27 IC: First version most of the IMAP features are implemented and - the core IdPOP3 features are implemented to allow a seamless - switch. - The unit is currently oriented to a session connection and not - to constant connection, because of that server events that are - raised from another user actions are not supported. - - 2001-APR-18 IC: Added support for the session's connection state with a - special exception for commands preformed in wrong connection - states. Exceptions were also added for response errors. - - 2001-MAY-05 IC: - - 2001-Mar-13 DS: Fixed Bug # 494813 in CheckMsgSeen where LastCmdResult.Text - was not using the Ln index variable to access server - responses. - - 2002-Apr-12 DS: fixed bug # 506026 in TIdIMAP4.ListSubscribedMailBoxes. Call - ParseLSubResut instead of ParseListResult. - - 2003-Mar-31 CC: Added GetUID and UIDSearchMailBox, sorted out some bugs (details - shown in comments in those functions which start with "CC:"). - - 2003-Apr-15 CC2:Sorted out some more bugs (details shown in comments in those - functions which start with "CC2:"). Set FMailBoxSeparator - in ParseListResult and ParseLSubResult. - Some IMAP servers generally return "OK completed" even if they - returned no data, such as passing a non-existent message - number to them: they possibly should return NO or BAD; the - functions here have been changed to return FALSE unless they - get good data back, even if the server answers OK. Similar - change made for other functions. - There are a few exceptions, e.g. ListMailBoxes may only return - "OK completed" if the user has no mailboxes, these are noted. - Also, RetrieveStructure(), UIDRetrieveStructure, RetrievePart, - UIDRetrievePart, RetrievePartPeek and UIDRetrievePartPeek - added to allow user to find the structure of a message and - just retrieve the part or parts he needs. - - 2003-Apr-30 CC3:Added functionality to retrieve the text of a message (only) - via RetrieveText / UIDRetrieveText / RetrieveTextPeek / - UIDRetrieveTextPeek. - Return codes now generally reflect if the function succeeded - instead of returning True even though function fails. - - 2003-May-15 CC4:Added functionality to retrieve individual parts of a message - to a file, including the decoding of those parts. - - 2003-May-29 CC5:Response of some servers to UID version of commands varies, - code changed to deal with those (UID position varies). - Some servers return NO such as when you request an envelope - for a message number that does not exist: functions return - False instead of throwing an exception, as was done for other - servers. The general logic is that if a valid result is - returned from the IMAP server, return True; if there is no - result (but the command is validly structured), return FALSE; - if the command is badly structured or if it gives a response - that this code does not expect, throw an exception (typically - when we get a BAD response instead of OK or NO). - Added IsNumberValid, IsUIDValid to prevent rubbishy parameters - being passed through to IMAP functions. - Sender field now filled in correctly in ParseEnvelope - functions. - All fields in ParseEnvelopeAddress are cleared out first, - avoids an unwitting error where some entries, such as CC list, - will append entries to existing entries. - Full test script now used that tests every TIdIMAP command, - more bugs eradicated. - First version to pass testing against both CommuniGate and - Cyrus IMAP servers. - Not tested against Microsoft Exchange, don't have an Exchange - account to test it against. - - 2003-Jun-10 CC6:Added (UID)RetrieveEnvelopeRaw, in case the user wants to do - their own envelope parsing. - Code in RetrievePart altered to make it more consistent. - Altered to incorporate Indy 10's use of IdReplyIMAP4 (not - complete at this stage). - ReceiveBody added to IdIMAP4, due to the response of some - servers, which gets (UID)Receive(Peek) functions to work on - more servers. - - 2003-Jun-20 CC7:ReceiveBody altered to work with Indy 10. Made changes due to - LoginSASL moving from TIdMessageSASLClient to TIdSASLList. - Public variable FGreetingBanner added to help user identify - the IMAP server he is connected to (may help him decide the - best strategy). Made AppendMsg work a bit better (now uses - platform-independent EOL and supports ExtraHeaders field). - Added 2nd version of AppendMsg. Added "if Connected then " - to Destroy. Attachment filenames now decoded if necessary. - Added support for multisection parts. - - 2003-Jul-16 CC8:Added RemoveAnyAdditionalResponses. Resolved issue of some - servers leaving out the trailing "NIL NIL NIL" at the end of - some body structures. (UID)Retrieve(Peek) functions - integrated via InternalRetrieve, new method of implementing - these functions (all variations of Retrieve) added for Indy - 10 based on getting message by the byte-count and then feeding - it into the standard message parser. - UIDRetrieveAllHeaders removed: it was never implemented anyway - but it makes no sense to retrieve a non-contiguous list which - would have gaps due to missing UIDs. - In the Indy 10 version, AppendMsg functions were altered to - support the sending of attachments (attachments had never - been supported in AppendMsg prior to this). - Added CopyMsg and UIDCopyMsgs to complete the command set. - 2003-Jul-30 CC9:Removed wDoublePoint so that the code is compliant with - the guidelines. Allowed for servers that don't implement - search commands in Indy 9 (OK in 10). InternalRetrieve - altered to (hopefully) deal with optional "FLAGS (\Seen)" - in response. - 2003-Aug-22 CCA:Yet another IMAP oddity - a server returns NIL for the - mailbox separator, ParseListResult modified. Added "Length - (LLine) > 0)" test to stop GPF on empty line in ReceiveBody. - 2003-Sep-26 CCB:Changed SendCmd altered to try to remove anything that may - be unprocessed from a previous (probably failed) command. - This uses the property FMilliSecsToWaitToClearBuffer, which - defaults to 10ms. - Added EIdDisconnectedProbablyIdledOut, trapped in - GetInternalResponse. - Unsolicited responses now filtered out (they are now transferred - from FLastCmdResult.Text to a new field, FLastCmdResult.Extra, - leaving just the responses we want to our command in - FLastCmdResult.Text). - 2003-Oct-21 CCC:Original GetLineResponse merged with GetResponse to reduce - complexity and to add filtering unsolicited responses when - we are looking for single-line responses (which GetLineResponse - did), removed/coded-out much of these functions to make the - code much simpler. - Removed RemoveAnyAdditionalResponses, no longer needed. - Parsing of body structure reworked to support ParentPart concept - allowing parsing of indefinitely-nested MIME parts. Note that - a`MIME "alternative" message with a plain-text and a html part - will have part[0] marked "alternative" with size 0 and ImapPartNumber - of 1, a part[1] of type text/plain with a ParentPart of 0 and an - ImapPartNumber of 1.1, and finally a part[2] of type text/html - again with a ParentPart of 0 and an ImapPartNumber of 1.2. - Imap part number changed from an integer to string, allowing - retrieval of IMAP sub-parts, e.g. part '3.2' is the 2nd subpart - of part 3. - 2003-Nov-20 CCD:Added UIDRetrievePartHeader & RetrievePartHeader. Started to - use an abstracted parsing method for the command response in - UIDRetrieveFlags. Added function FindHowServerCreatesFolders. - 2003-Dec-04 CCE:Copied DotNet connection changes from IdSMTP to tempoarily bypass - the SASL authentications until they are ported. - 2004-Jan-23 CCF:Finished .NET port, added BinHex4.0 encoding. - 2004-Apr-16 CCG:Added UTF-7 decoding/encoding code kindly written and submitted by - Roman Puls for encoding/decoding mailbox names. IMAP does not use - standard UTF-7 code (what's new?!) so these routines are localised - to this unit. -} - -unit IdIMAP4; - -{ - IMAP 4 (Internet Message Access Protocol - Version 4 Rev 1) - By Idan Cohen i_cohen@yahoo.com -} - -interface - -{ Todo -oIC : -Change the mailbox list commands so that they receive TMailBoxTree -structures and so they can store in them the mailbox name and it's attributes. } - -{ Todo -oIC : -Add support for \* special flag in messages, and check for \Recent -flag in STORE command because it cant be stored (will get no reply!!!) } - -{ Todo -oIC : -5.1.2. Mailbox Namespace Naming Convention -By convention, the first hierarchical element of any mailbox name -which begins with "#" identifies the "namespace" of the remainder of -the name. This makes it possible to disambiguate between different -types of mailbox stores, each of which have their own namespaces. -For example, implementations which offer access to USENET -newsgroups MAY use the "#news" namespace to partition the USENET -newsgroup namespace from that of other mailboxes. Thus, the -comp.mail.misc newsgroup would have an mailbox name of -"#news.comp.mail.misc", and the name "comp.mail.misc" could refer -to a different object (e.g. a user's private mailbox). } - -{ TO BE CONSIDERED -CC : -Double-quotes in mailbox names can cause major but subtle failures. Maybe -add the automatic stripping of double-quotes if passed in mailbox names, -to avoid ending up with ""INBOX"" -} - -{CC3: WARNING - if the following gives a "File not found" error on compilation, -you need to add the path "C:\Program Files\Borland\Delphi7\Source\Indy" in -Project -> Options -> Directories/Conditionals -> Search Path} - -{$I IdCompilerDefines.inc} - -uses - Classes, - {$IFNDEF VCL_6_OR_ABOVE}IdCTypes,{$ENDIF} - IdMessage, - IdAssignedNumbers, - IdMailBox, - IdException, - IdGlobal, - IdMessageParts, - IdMessageClient, - IdReply, - IdComponent, - IdMessageCoder, - IdHeaderList, - IdCoderHeader, - IdCoderMIME, - IdCoderQuotedPrintable, - IdCoderBinHex4, - IdSASLCollection, - IdMessageCollection, - IdBaseComponent; - -{ MUTF7 } - -type - EmUTF7Error = class(EIdSilentException); - EmUTF7Encode = class(EmUTF7Error); - EmUTF7Decode = class(EmUTF7Error); - -type - // TODO: make an IIdTextEncoding implementation for Modified UTF-7 - TIdMUTF7 = class(TObject) - public - function Encode(const aString : TIdUnicodeString): String; - function Decode(const aString : String): TIdUnicodeString; - function Valid(const aMUTF7String : String): Boolean; - function Append(const aMUTF7String: String; const aStr: TIdUnicodeString): String; - end; - -{ TIdIMAP4 } - -const - wsOk = 1; - wsNo = 2; - wsBad = 3; - wsPreAuth = 4; - wsBye = 5; - wsContinue = 6; - -type - TIdIMAP4FolderTreatment = ( //Result codes from FindHowServerCreatesFolders - ftAllowsTopLevelCreation, //Folders can be created at the same level as Inbox (the top level) - ftFoldersMustBeUnderInbox, //Folders must be created under INBOX, such as INBOX.Sent - ftDoesNotAllowFolderCreation, //Wont allow you create folders at top level or under Inbox (may be read-only connection) - ftCannotTestBecauseHasNoInbox, //Wont allow top-level creation but cannot test creation under Inbox because it does not exist - ftCannotRetrieveAnyFolders //No folders present for that user, cannot be determined - ); - -type - TIdIMAP4AuthenticationType = ( - iatUserPass, - iatSASL - ); - -const - DEF_IMAP4_AUTH = iatUserPass; - IDF_DEFAULT_MS_TO_WAIT_TO_CLEAR_BUFFER = 10; - -{CC3: TIdImapMessagePart and TIdImapMessageParts added for retrieving -individual parts of a message via IMAP, because IMAP uses some additional -terms. -Note that (rarely) an IMAP can have two sub-"parts" in the one part - -they are sent in the one part by the server, typically a plain-text and -html version with a boundary at the start, in between, and at the end. -TIdIMAP fills in the boundary in that case, and the FSubpart holds the -info on the second part. I call these multisection parts.} - -type - TIdImapMessagePart = class(TCollectionItem) - protected - FBodyType: string; - FBodySubType: string; - FFileName: string; - FDescription: string; - FEncoding: TIdMessageEncoding; - FCharSet: string; - FContentTransferEncoding: string; - FSize: Int64; - FUnparsedEntry: string; {Text returned from server: useful for debugging or workarounds} - FBoundary: string; {Only used for multisection parts} - FParentPart: Integer; - FImapPartNumber: string; - public - constructor Create(Collection: TCollection); override; - property BodyType : String read FBodyType write FBodyType; - property BodySubType : String read FBodySubType write FBodySubType; - property FileName : String read FFileName write FFileName; - property Description : String read FDescription write FDescription; - property Encoding: TIdMessageEncoding read FEncoding write FEncoding; - property CharSet: string read FCharSet write FCharSet; - property ContentTransferEncoding : String read FContentTransferEncoding write FContentTransferEncoding; - property Size : Int64 read FSize write FSize; - property UnparsedEntry : string read FUnparsedEntry write FUnparsedEntry; - property Boundary : string read FBoundary write FBoundary; - property ParentPart: integer read FParentPart write FParentPart; - property ImapPartNumber: string read FImapPartNumber write FImapPartNumber; - end; - - {CC3: Added for validating message number} - EIdNumberInvalid = class(EIdException); - {CCB: Added for server disconnecting you if idle too long...} - EIdDisconnectedProbablyIdledOut = class(EIdException); - - TIdImapMessageParts = class(TOwnedCollection) - protected - function GetItem(Index: Integer): TIdImapMessagePart; - procedure SetItem(Index: Integer; const Value: TIdImapMessagePart); - public - constructor Create(AOwner: TPersistent); reintroduce; - function Add: TIdImapMessagePart; reintroduce; - property Items[Index: Integer]: TIdImapMessagePart read GetItem write SetItem; default; - end; - -{CCD: Added to parse out responses, because the order in which the responses appear -varies between servers. A typical line that gets parsed into this is: - * 9 FETCH (UID 1234 FLAGS (\Seen \Deleted)) -} - TIdIMAPLineStruct = class(TObject) - protected - HasStar: Boolean; //Line starts with a '*' - MessageNumber: string; //Line has a message number (after the *) - Command: string; //IMAP servers send back the command they are responding to, e.g. FETCH - UID: string; //Sometimes the UID is echoed back - Flags: TIdMessageFlagsSet; //Sometimes the FLAGS are echoed back - FlagsStr: string; //unparsed FLAGS for the message - Complete: Boolean; //If false, line has no closing bracket (response continues on following line(s)) - ByteCount: integer; //The value in a trailing byte count like {123}, -1 means not present - IMAPFunction: string; //E.g. FLAGS - IMAPValue: string; //E.g. '(\Seen \Deleted)' - GmailMsgID: string; //Gmail-specific unique identifier for the message - GmailThreadID: string; //Gmail-specific thread identifier for the message - GmailLabels: string; //Gmail-specific labels for the message - end; - - TIdIMAP4Commands = ( - cmdCAPABILITY, - cmdNOOP, - cmdLOGOUT, - cmdAUTHENTICATE, - cmdLOGIN, - cmdSELECT, - cmdEXAMINE, - cmdCREATE, - cmdDELETE, - cmdRENAME, - cmdSUBSCRIBE, - cmdUNSUBSCRIBE, - cmdLIST, - cmdLSUB, - cmdSTATUS, - cmdAPPEND, - cmdCHECK, - cmdCLOSE, - cmdEXPUNGE, - cmdSEARCH, - cmdFETCH, - cmdSTORE, - cmdCOPY, - cmdUID, - cmdXCmd - ); - - {CC3: Add csUnexpectedlyDisconnected for when we receive "Connection reset by peer"} - TIdIMAP4ConnectionState = ( - csAny, - csNonAuthenticated, - csAuthenticated, - csSelected, - csUnexpectedlyDisconnected - ); - - {**************************************************************************** - Universal commands CAPABILITY, NOOP, and LOGOUT - Authenticated state commands SELECT, EXAMINE, CREATE, DELETE, RENAME, - SUBSCRIBE, UNSUBSCRIBE, LIST, LSUB, STATUS, and APPEND - Selected state commands CHECK, CLOSE, EXPUNGE, SEARCH, FETCH, STORE, COPY, and UID - *****************************************************************************} - - TIdIMAP4SearchKey = ( - skAll, //All messages in the mailbox; the default initial key for ANDing. - skAnswered, //Messages with the \Answered flag set. - skBcc, //Messages that contain the specified string in the envelope structure's BCC field. - skBefore, //Messages whose internal date is earlier than the specified date. - skBody, //Messages that contain the specified string in the body of the message. - skCc, //Messages that contain the specified string in the envelope structure's CC field. - skDeleted, //Messages with the \Deleted flag set. - skDraft, //Messages with the \Draft flag set. - skFlagged, //Messages with the \Flagged flag set. - skFrom, //Messages that contain the specified string in the envelope structure's FROM field. - skHeader, //Messages that have a header with the specified field-name (as defined in [RFC-822]) - //and that contains the specified string in the [RFC-822] field-body. - skKeyword, //Messages with the specified keyword set. - skLarger, //Messages with an [RFC-822] size larger than the specified number of octets. - skNew, //Messages that have the \Recent flag set but not the \Seen flag. - //This is functionally equivalent to "(RECENT UNSEEN)". - skNot, //Messages that do not match the specified search key. - skOld, //Messages that do not have the \Recent flag set. This is functionally - //equivalent to "NOT RECENT" (as opposed to "NOT NEW"). - skOn, //Messages whose internal date is within the specified date. - skOr, //Messages that match either search key. - skRecent, //Messages that have the \Recent flag set. - skSeen, //Messages that have the \Seen flag set. - skSentBefore,//Messages whose [RFC-822] Date: header is earlier than the specified date. - skSentOn, //Messages whose [RFC-822] Date: header is within the specified date. - skSentSince, //Messages whose [RFC-822] Date: header is within or later than the specified date. - skSince, //Messages whose internal date is within or later than the specified date. - skSmaller, //Messages with an [RFC-822] size smaller than the specified number of octets. - skSubject, //Messages that contain the specified string in the envelope structure's SUBJECT field. - skText, //Messages that contain the specified string in the header or body of the message. - skTo, //Messages that contain the specified string in the envelope structure's TO field. - skUID, //Messages with unique identifiers corresponding to the specified unique identifier set. - skUnanswered,//Messages that do not have the \Answered flag set. - skUndeleted, //Messages that do not have the \Deleted flag set. - skUndraft, //Messages that do not have the \Draft flag set. - skUnflagged, //Messages that do not have the \Flagged flag set. - skUnKeyWord, //Messages that do not have the specified keyword set. - skUnseen, - skGmailRaw, //Gmail-specific extension to access full Gmail search syntax - skGmailMsgID, //Gmail-specific unique message identifier - skGmailThreadID, //Gmail-specific thread identifier - skGmailLabels //Gmail-specific labels - ); - - TIdIMAP4SearchKeyArray = array of TIdIMAP4SearchKey; - - TIdIMAP4SearchRec = record - Date: TDateTime; - Size: Int64; - Text: String; - SearchKey : TIdIMAP4SearchKey; - FieldName: String; - end; - - TIdIMAP4SearchRecArray = array of TIdIMAP4SearchRec; - - TIdIMAP4StatusDataItem = ( - mdMessages, - mdRecent, - mdUIDNext, - mdUIDValidity, - mdUnseen - ); - - TIdIMAP4StoreDataItem = ( - sdReplace, - sdReplaceSilent, - sdAdd, - sdAddSilent, - sdRemove, - sdRemoveSilent - ); - - TIdRetrieveOnSelect = ( - rsDisabled, - rsHeaders, - rsMessages - ); - - TIdAlertEvent = procedure(ASender: TObject; const AAlertMsg: String) of object; - - TIdIMAP4 = class(TIdMessageClient) - protected - FCmdCounter : Integer; - FConnectionState : TIdIMAP4ConnectionState; - FMailBox : TIdMailBox; - FMailBoxSeparator: Char; - FOnAlert: TIdAlertEvent; - FRetrieveOnSelect: TIdRetrieveOnSelect; - FMilliSecsToWaitToClearBuffer: integer; - FMUTF7: TIdMUTF7; - FOnWorkForPart: TWorkEvent; - FOnWorkBeginForPart: TWorkBeginEvent; - FOnWorkEndForPart: TWorkEndEvent; - FGreetingBanner : String; {CC7: Added because it may help identify the server} - FHasCapa : Boolean; - FSASLMechanisms : TIdSASLEntries; - FAuthType : TIdIMAP4AuthenticationType; - FLineStruct: TIdIMAPLineStruct; - function GetReplyClass:TIdReplyClass; override; - function GetSupportsTLS: Boolean; override; - function CheckConnectionState(AAllowedState: TIdIMAP4ConnectionState): TIdIMAP4ConnectionState; overload; - function CheckConnectionState(const AAllowedStates: array of TIdIMAP4ConnectionState): TIdIMAP4ConnectionState; overload; - function CheckReplyForCapabilities: Boolean; - procedure BeginWorkForPart(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); - procedure DoWorkForPart(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); - procedure EndWorkForPart(ASender: TObject; AWorkMode: TWorkMode); - //The following call FMUTF7 but do exception-handling on invalid strings... - function DoMUTFEncode(const aString : String): String; - function DoMUTFDecode(const aString : String): String; - function GetCmdCounter: String; - function GetConnectionStateName: String; - function GetNewCmdCounter: String; - property LastCmdCounter: String read GetCmdCounter; - property NewCmdCounter: String read GetNewCmdCounter; - { General Functions } - function ArrayToNumberStr (const AMsgNumList: array of UInt32): String; - function MessageFlagSetToStr (const AFlags: TIdMessageFlagsSet): String; - procedure StripCRLFs(var AText: string); overload; virtual; //Allow users to optimise - procedure StripCRLFs(ASourceStream, ADestStream: TStream); overload; - { Parser Functions } - procedure ParseImapPart(ABodyStructure: string; - AImapParts: TIdImapMessageParts; AThisImapPart: TIdImapMessagePart; - AParentImapPart: TIdImapMessagePart; APartNumber: integer); - procedure ParseMessagePart(ABodyStructure: string; AMessageParts: TIdMessageParts; - AThisMessagePart: TIdMessagePart; AParentMessagePart: TIdMessagePart; - APartNumber: integer); - procedure ParseBodyStructureResult(ABodyStructure: string; ATheParts: TIdMessageParts; AImapParts: TIdImapMessageParts); - procedure ParseBodyStructurePart(APartString: string; AThePart: TIdMessagePart; AImapPart: TIdImapMessagePart); - procedure ParseTheLine(ALine: string; APartsList: TStrings); - procedure ParseIntoParts(APartString: string; AParams: TStrings); - procedure ParseIntoBrackettedQuotedAndUnquotedParts(APartString: string; AParams: TStrings; AKeepBrackets: Boolean); - procedure BreakApartParamsInQuotes(const AParam: string; AParsedList: TStrings); - function GetNextWord(AParam: string): string; - function GetNextQuotedParam(AParam: string; ARemoveQuotes: Boolean): string; - procedure ParseExpungeResult (AMB: TIdMailBox; ACmdResultDetails: TStrings); - procedure ParseListResult (AMBList: TStrings; ACmdResultDetails: TStrings); - procedure ParseLSubResult(AMBList: TStrings; ACmdResultDetails: TStrings); - procedure InternalParseListResult(ACmd: string; AMBList: TStrings; ACmdResultDetails: TStrings); - procedure ParseMailBoxAttributeString(AAttributesList: String; var AAttributes: TIdMailBoxAttributesSet); - procedure ParseMessageFlagString (AFlagsList: String; var AFlags: TIdMessageFlagsSet); - procedure ParseSelectResult (AMB: TIdMailBox; ACmdResultDetails: TStrings); - procedure ParseStatusResult (AMB: TIdMailBox; ACmdResultDetails: TStrings); - procedure ParseSearchResult (AMB: TIdMailBox; ACmdResultDetails: TStrings); - procedure ParseEnvelopeResult (AMsg: TIdMessage; ACmdResultStr: String); - function ParseLastCmdResult(ALine: string; AExpectedCommand: string; AExpectedIMAPFunction: array of string): Boolean; - procedure ParseLastCmdResultButAppendInfo(ALine: string); - function InternalRetrieve(const AMsgNum: UInt32; AUseUID: Boolean; AUsePeek: Boolean; AMsg: TIdMessage): Boolean; - function InternalRetrievePart(const AMsgNum: UInt32; const APartNum: string; - AUseUID: Boolean; AUsePeek: Boolean; - ADestStream: TStream; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; {NOTE: var args cannot have default params} - ADestFileNameAndPath: string = ''; {Do not Localize} - AContentTransferEncoding: string = 'text'): Boolean; {Do not Localize} - //Retrieves the specified number of headers of the selected mailbox to the specified TIdMessageCollection. - function InternalRetrieveHeaders(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; - //Retrieves the specified number of messages of the selected mailbox to the specified TIdMessageCollection. - function InternalRetrieveMsgs(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; - function InternalSearchMailBox(const ASearchInfo: array of TIdIMAP4SearchRec; AUseUID: Boolean; const ACharSet: string): Boolean; - function ParseBodyStructureSectionAsEquates(AParam: string): string; - function ParseBodyStructureSectionAsEquates2(AParam: string): string; - function InternalRetrieveText(const AMsgNum: UInt32; var AText: string; - AUseUID: Boolean; AUsePeek: Boolean; AUseFirstPartInsteadOfText: Boolean): Boolean; - function IsCapabilityListed(ACapability: string): Boolean; - function InternalRetrieveEnvelope(const AMsgNum: UInt32; AMsg: TIdMessage; ADestList: TStrings): Boolean; - function UIDInternalRetrieveEnvelope(const AMsgUID: String; AMsg: TIdMessage; ADestList: TStrings): Boolean; - function InternalRetrievePartHeader(const AMsgNum: UInt32; const APartNum: string; const AUseUID: Boolean; - AHeaders: TIdHeaderList): Boolean; - function ReceiveHeader(AMsg: TIdMessage; const AAltTerm: string = ''): string; override; - {CC3: Need to validate message numbers (relative and UIDs) and part numbers, because otherwise - the routines wait for a response that never arrives and so functions never return. - Also used for validating part numbers.} - function IsNumberValid(const ANumber: UInt32): Boolean; - function IsUIDValid(const AUID: string): Boolean; - function IsImapPartNumberValid(const APartNum: Integer): Boolean; overload; - function IsImapPartNumberValid(const APartNum: string): Boolean; overload; - function IsItDigitsAndOptionallyPeriod(const AStr: string; AAllowPeriod: Boolean): Boolean; - {CC6: Override IdMessageClient's ReceiveBody due to the responses from some servers...} - procedure ReceiveBody(AMsg: TIdMessage; const ADelim: string = '.'); override; {Do not Localize} - procedure InitComponent; override; - procedure SetMailBox(const Value: TIdMailBox); - procedure SetSASLMechanisms(AValue: TIdSASLEntries); - public - { TIdIMAP4 Commands } - {$IFDEF WORKAROUND_INLINE_CONSTRUCTORS} - constructor Create(AOwner: TComponent); reintroduce; overload; - {$ENDIF} - destructor Destroy; override; - //Requests a listing of capabilities that the server supports... - function Capability: Boolean; overload; - function Capability(ASlCapability: TStrings): Boolean; overload; - function FindHowServerCreatesFolders: TIdIMAP4FolderTreatment; - procedure DoAlert(const AMsg: String); - property ConnectionState: TIdIMAP4ConnectionState read FConnectionState; - property MailBox: TIdMailBox read FMailBox write SetMailBox; - {CC7: Two versions of AppendMsg are provided. The first is the normal one you - would use. The second allows you to specify an alternative header list which - will be used in place of AMsg.Headers. - An email client may need the second type if it sends an email via IdSMTP and wants - to copy it to a "Sent" IMAP folder. In Indy 10, - IdSMTP puts the generated headers in the LastGeneratedHeaders field, so you - can use the second version of AppendMsg, passing it AMsg.LastGeneratedHeaders as - the AAlternativeHeaders field. Note that IdSMTP puts both the Headers and - the ExtraHeaders fields in LastGeneratedHeaders.} - function AppendMsg(const AMBName: String; AMsg: TIdMessage; const AFlags: TIdMessageFlagsSet = []; - const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; overload; - function AppendMsg(const AMBName: String; AMsg: TIdMessage; AAlternativeHeaders: TIdHeaderList; - const AFlags: TIdMessageFlagsSet = []; const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; overload; - //The following are used for raw (unparsed) messages in a file or stream... - function AppendMsgNoEncodeFromFile(const AMBName: String; ASourceFile: string; const AFlags: TIdMessageFlagsSet = []; - const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; - function AppendMsgNoEncodeFromStream(const AMBName: String; AStream: TStream; const AFlags: TIdMessageFlagsSet = []; - const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; - //Requests a checkpoint of the currently selected mailbox. Does NOTHING on most servers. - function CheckMailBox: Boolean; - //Checks if the message was read or not. - function CheckMsgSeen(const AMsgNum: UInt32): Boolean; - //Method for logging in manually if you didn't login at connect - procedure Login; virtual; - //Connects and logins to the IMAP4 account. - function Connect(const AAutoLogin: boolean = true): Boolean; reintroduce; virtual; - //Closes the current selected mailbox in the account. - function CloseMailBox: Boolean; - //Creates a new mailbox with the specified name in the account. - function CreateMailBox(const AMBName: String): Boolean; - //Deletes the specified mailbox from the account. - function DeleteMailBox(const AMBName: String): Boolean; - //Marks messages for deletion, it will be deleted when the mailbox is purged. - function DeleteMsgs(const AMsgNumList: array of UInt32): Boolean; - //Logouts and disconnects from the IMAP account. - procedure Disconnect(ANotifyPeer: Boolean); override; - procedure DisconnectNotifyPeer; override; - //Examines the specified mailbox and inserts the results to the TIdMailBox provided. - function ExamineMailBox(const AMBName: String; AMB: TIdMailBox): Boolean; - //Expunges (deletes the marked files) the current selected mailbox in the account. - function ExpungeMailBox: Boolean; - //Sends a NOOP (No Operation) to keep the account connection with the server alive. - procedure KeepAlive; - //Returns a list of all the child mailboxes (one level down) to the mailbox supplied. - //This should be used when you fear that there are too many mailboxes and the listing of - //all of them could be time consuming, so this should be used to retrieve specific mailboxes. - function ListInferiorMailBoxes(AMailBoxList, AInferiorMailBoxList: TStrings): Boolean; - //Returns a list of all the mailboxes in the user account. - function ListMailBoxes(AMailBoxList: TStrings): Boolean; - //Returns a list of all the subscribed mailboxes in the user account. - function ListSubscribedMailBoxes (AMailBoxList: TStrings): Boolean; - //Renames the specified mailbox in the account. - function RenameMailBox(const AOldMBName, ANewMBName: String): Boolean; - //Searches the current selected mailbox for messages matching the SearchRec and - //returns the results to the mailbox SearchResults array. - function SearchMailBox(const ASearchInfo: array of TIdIMAP4SearchRec; const ACharSet: string = ''): Boolean; - //Selects the current a mailbox in the account. - function SelectMailBox(const AMBName: String): Boolean; - //Retrieves the status of the indicated mailbox. - {CC2: It is pointless calling StatusMailBox with AStatusDataItems set to [] - because you are asking the IMAP server to update none of the status flags. - Instead, if called with no AStatusDataItems specified, we use the standard flags - returned by SelectMailBox, which allows the user to easily check if the mailbox - has changed.} - function StatusMailBox(const AMBName: String; AMB: TIdMailBox): Boolean; overload; - function StatusMailBox(const AMBName: String; AMB: TIdMailBox; - const AStatusDataItems: array of TIdIMAP4StatusDataItem): Boolean; overload; - //Changes (adds or removes) message flags. - function StoreFlags(const AMsgNumList: array of UInt32; const AStoreMethod: TIdIMAP4StoreDataItem; - const AFlags: TIdMessageFlagsSet): Boolean; - //Changes (adds or removes) a message value. - function StoreValue(const AMsgNumList: array of UInt32; const AStoreMethod: TIdIMAP4StoreDataItem; - const AField, AValue: String): Boolean; - //Adds the specified mailbox name to the server's set of "active" or "subscribed" - //mailboxes as returned by the LSUB command. - function SubscribeMailBox(const AMBName: String): Boolean; - {CC8: Added CopyMsg, should have always been there...} - function CopyMsg(const AMsgNum: UInt32; const AMBName: String): Boolean; - //Copies a message from the current selected mailbox to the specified mailbox. {Do not Localize} - function CopyMsgs(const AMsgNumList: array of UInt32; const AMBName: String): Boolean; - //Retrieves a whole message while marking it read. - function Retrieve(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; - //Retrieves a whole message "raw" and saves it to file, while marking it read. - function RetrieveNoDecodeToFile(const AMsgNum: UInt32; ADestFile: string): Boolean; - function RetrieveNoDecodeToFilePeek(const AMsgNum: UInt32; ADestFile: string): Boolean; - function RetrieveNoDecodeToStream(const AMsgNum: UInt32; AStream: TStream): Boolean; - function RetrieveNoDecodeToStreamPeek(const AMsgNum: UInt32; AStream: TStream): Boolean; - //Retrieves all envelope of the selected mailbox to the specified TIdMessageCollection. - function RetrieveAllEnvelopes(AMsgList: TIdMessageCollection): Boolean; - //Retrieves all headers of the selected mailbox to the specified TIdMessageCollection. - function RetrieveAllHeaders(AMsgList: TIdMessageCollection): Boolean; - //Retrieves the first NN headers of the selected mailbox to the specified TIdMessageCollection. - function RetrieveFirstHeaders(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; - //Retrieves all messages of the selected mailbox to the specified TIdMessageCollection. - function RetrieveAllMsgs(AMsgList: TIdMessageCollection): Boolean; - //Retrieves the first NN messages of the selected mailbox to the specified TIdMessageCollection. - function RetrieveFirstMsgs(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; - //Retrieves the message envelope, parses it, and discards the envelope. - function RetrieveEnvelope(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; - //Retrieves the message envelope into a TStringList but does NOT parse it. - function RetrieveEnvelopeRaw(const AMsgNum: UInt32; ADestList: TStrings): Boolean; - //Returnes the message flag values. - function RetrieveFlags(const AMsgNum: UInt32; var AFlags: TIdMessageFlagsSet): Boolean; - //Returnes a requested message value. - function RetrieveValue(const AMsgNum: UInt32; const AField: string; var AValue: string): Boolean; - {CC2: Following added for retrieving individual parts of a message...} - function InternalRetrieveStructure(const AMsgNum: UInt32; AMsg: TIdMessage; AParts: TIdImapMessageParts): Boolean; - //Retrieve only the message structure (this tells you what parts are in the message). - function RetrieveStructure(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; overload; - function RetrieveStructure(const AMsgNum: UInt32; AParts: TIdImapMessageParts): Boolean; overload; - {CC2: Following added for retrieving individual parts of a message...} - {Retrieve a specific individual part of a message to a stream (part/sub-part like '2' or '2.3')...} - function RetrievePart(const AMsgNum: UInt32; const APartNum: string; - ADestStream: TStream; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} - {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...} - function RetrievePart(const AMsgNum: UInt32; const APartNum: string; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} - {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...} - function RetrievePart(const AMsgNum: UInt32; const APartNum: Integer; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} - {Retrieve a specific individual part of a message to a stream (part/sub-part like '2' or '2.3') - without marking the message as "read"...} - function RetrievePartPeek(const AMsgNum: UInt32; const APartNum: string; - ADestStream: TStream; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} - {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3' - without marking the message as "read"...} - function RetrievePartPeek(const AMsgNum: UInt32; const APartNum: string; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} - {Retrieve a specific individual part of a message where part is an integer (for backward compatibility) - without marking the message as "read"...} - function RetrievePartPeek(const AMsgNum: UInt32; const APartNum: Integer; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} - {CC2: Following added for retrieving individual parts of a message...} - {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...} - function RetrievePartToFile(const AMsgNum: UInt32; const APartNum: Integer; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; - {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...} - function RetrievePartToFile(const AMsgNum: UInt32; const APartNum: string; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; - {CC2: Following added for retrieving individual parts of a message...} - {Retrieve a specific individual part of a message where part is an integer (for backward compatibility) - without marking the message as "read"...} - function RetrievePartToFilePeek(const AMsgNum: UInt32; const APartNum: Integer; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; - {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3' - without marking the message as "read"...} - function RetrievePartToFilePeek(const AMsgNum: UInt32; const APartNum: string; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; - {CC3: Following added for retrieving the text-only part of a message...} - function RetrieveText(const AMsgNum: UInt32; var AText: string): Boolean; - {CC4: An alternative for retrieving the text-only part of a message which - may give a better response from some IMAP implementations...} - function RetrieveText2(const AMsgNum: UInt32; var AText: string): Boolean; - {CC3: Following added for retrieving the text-only part of a message - without marking the message as "read"...} - function RetrieveTextPeek(const AMsgNum: UInt32; var AText: string): Boolean; - function RetrieveTextPeek2(const AMsgNum: UInt32; var AText: string): Boolean; - //Retrieves only the message header. - function RetrieveHeader (const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; - //CCD: Retrieve the header for a particular part... - function RetrievePartHeader(const AMsgNum: UInt32; const APartNum: string; AHeaders: TIdHeaderList): Boolean; - //Retrives the current selected mailbox size. - function RetrieveMailBoxSize: Int64; - //Returnes the message size. - function RetrieveMsgSize(const AMsgNum: UInt32): Int64; - //Retrieves a whole message while keeping its Seen flag unchanged - //(preserving the previous value). - function RetrievePeek(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; - //Get the UID corresponding to a relative message number. - function GetUID(const AMsgNum: UInt32; var AUID: string): Boolean; - //Copies a message from the current selected mailbox to the specified mailbox. - function UIDCopyMsg(const AMsgUID: String; const AMBName: String): Boolean; - {CC8: Added UID version of CopyMsgs...} - function UIDCopyMsgs(const AMsgUIDList: TStrings; const AMBName: String): Boolean; - //Checks if the message was read or not. - function UIDCheckMsgSeen(const AMsgUID: String): Boolean; - //Marks a message for deletion, it will be deleted when the mailbox will be purged. - function UIDDeleteMsg(const AMsgUID: String): Boolean; - function UIDDeleteMsgs(const AMsgUIDList: array of String): Boolean; - //Retrieves all envelope and UID of the selected mailbox to the specified TIdMessageCollection. - function UIDRetrieveAllEnvelopes(AMsgList: TIdMessageCollection): Boolean; - //Retrieves a whole message while marking it read. - function UIDRetrieve(const AMsgUID: String; AMsg: TIdMessage): Boolean; - //Retrieves a whole message "raw" and saves it to file, while marking it read. - function UIDRetrieveNoDecodeToFile(const AMsgUID: String; ADestFile: string): Boolean; - function UIDRetrieveNoDecodeToFilePeek(const AMsgUID: String; ADestFile: string): Boolean; - function UIDRetrieveNoDecodeToStream(const AMsgUID: String; AStream: TStream): Boolean; - function UIDRetrieveNoDecodeToStreamPeek(const AMsgUID: String; AStream: TStream): Boolean; - //Retrieves the message envelope, parses it, and discards the envelope. - function UIDRetrieveEnvelope(const AMsgUID: String; AMsg: TIdMessage): Boolean; - //Retrieves the message envelope into a TStringList but does NOT parse it. - function UIDRetrieveEnvelopeRaw(const AMsgUID: String; ADestList: TStrings): Boolean; - //Returnes the message flag values. - function UIDRetrieveFlags(const AMsgUID: String; var AFlags: TIdMessageFlagsSet): Boolean; - //Returnes a requested message value. - function UIDRetrieveValue(const AMsgUID: String; const AField: string; var AValue: string): Boolean; - {CC2: Following added for retrieving individual parts of a message...} - function UIDInternalRetrieveStructure(const AMsgUID: String; AMsg: TIdMessage; AParts: TIdImapMessageParts): Boolean; - //Retrieve only the message structure (this tells you what parts are in the message). - function UIDRetrieveStructure(const AMsgUID: String; AMsg: TIdMessage): Boolean; overload; - function UIDRetrieveStructure(const AMsgUID: String; AParts: TIdImapMessageParts): Boolean; overload; - {Retrieve a specific individual part of a message to a stream (part/sub-part like '2' or '2.3')...} - function UIDRetrievePart(const AMsgUID: String; const APartNum: string; - var ADestStream: TStream; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} - {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...} - function UIDRetrievePart(const AMsgUID: String; const APartNum: string; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} - {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...} - function UIDRetrievePart(const AMsgUID: String; const APartNum: Integer; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} - {Retrieve a specific individual part of a message to a stream (part/sub-part like '2' or '2.3') - without marking the message as "read"...} - function UIDRetrievePartPeek(const AMsgUID: String; const APartNum: string; - var ADestStream: TStream; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} - {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...} - function UIDRetrievePartPeek(const AMsgUID: String; const APartNum: string; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} - {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...} - function UIDRetrievePartPeek(const AMsgUID: String; const APartNum: Integer; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} - {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...} - function UIDRetrievePartToFile(const AMsgUID: String; const APartNum: Integer; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; - {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...} - function UIDRetrievePartToFile(const AMsgUID: String; const APartNum: string; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; - {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...} - function UIDRetrievePartToFilePeek(const AMsgUID: String; const APartNum: Integer; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; - {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...} - function UIDRetrievePartToFilePeek(const AMsgUID: String; const APartNum: string; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; - {Following added for retrieving the text-only part of a message...} - function UIDRetrieveText(const AMsgUID: String; var AText: string): Boolean; - function UIDRetrieveText2(const AMsgUID: String; var AText: string): Boolean; - {Following added for retrieving the text-only part of a message without marking the message as read...} - function UIDRetrieveTextPeek(const AMsgUID: String; var AText: string): Boolean; - function UIDRetrieveTextPeek2(const AMsgUID: String; var AText: string): Boolean; - //Retrieves only the message header. - function UIDRetrieveHeader(const AMsgUID: String; AMsg: TIdMessage): Boolean; - //Retrieve the header for a particular part... - function UIDRetrievePartHeader(const AMsgUID: String; const APartNum: string; AHeaders: TIdHeaderList): Boolean; - //Retrives the current selected mailbox size. - function UIDRetrieveMailBoxSize: Int64; - //Returnes the message size. - function UIDRetrieveMsgSize(const AMsgUID: String): Int64; - //Retrieves a whole message while keeping its Seen flag untucked - //(preserving the previous value). - function UIDRetrievePeek(const AMsgUID: String; AMsg: TIdMessage): Boolean; - //Searches the current selected mailbox for messages matching the SearchRec and - //returnes the results as UIDs to the mailbox SearchResults array. - function UIDSearchMailBox(const ASearchInfo: array of TIdIMAP4SearchRec; const ACharSet: String = ''): Boolean; - //Changes (adds or removes) message flags. - function UIDStoreFlags(const AMsgUID: String; const AStoreMethod: TIdIMAP4StoreDataItem; - const AFlags: TIdMessageFlagsSet): Boolean; overload; - function UIDStoreFlags(const AMsgUIDList: array of String; const AStoreMethod: TIdIMAP4StoreDataItem; - const AFlags: TIdMessageFlagsSet): Boolean; overload; - //Changes (adds or removes) a message value. - function UIDStoreValue(const AMsgUID: String; const AStoreMethod: TIdIMAP4StoreDataItem; - const AField, AValue: String): Boolean; overload; - function UIDStoreValue(const AMsgUIDList: array of String; const AStoreMethod: TIdIMAP4StoreDataItem; - const AField, AValue: string): Boolean; overload; - //Removes the specified mailbox name from the server's set of "active" or "subscribed" - //mailboxes as returned by the LSUB command. - function UnsubscribeMailBox(const AMBName: String): Boolean; - { IdTCPConnection Commands } - function GetInternalResponse(const ATag: String; AExpectedResponses: array of String; ASingleLineMode: Boolean; - ASingleLineMayBeSplit: Boolean = True): string; reintroduce; overload; - function GetResponse: string; reintroduce; overload; - function SendCmd(const AOut: string; AExpectedResponses: array of String; - ASingleLineMode: Boolean = False; ASingleLineMayBeSplit: Boolean = True): string; reintroduce; overload; - function SendCmd(const ATag, AOut: string; AExpectedResponses: array of String; - ASingleLineMode: Boolean = False; ASingleLineMayBeSplit: Boolean = True): string; overload; - function ReadLnWait: string; {$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use IOHandler.ReadLnWait()'{$ENDIF};{$ENDIF} - procedure WriteLn(const AOut: string = ''); {$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use IOHandler.WriteLn()'{$ENDIF};{$ENDIF} - { IdTCPConnection Commands } - - property IPVersion; - published - property OnAlert: TIdAlertEvent read FOnAlert write FOnAlert; - property Password; - property RetrieveOnSelect: TIdRetrieveOnSelect read FRetrieveOnSelect write FRetrieveOnSelect default rsDisabled; - property Port default IdPORT_IMAP4; - property Username; - property MailBoxSeparator: Char read FMailBoxSeparator write FMailBoxSeparator default '/'; {Do not Localize} - {GreetingBanner added because it may help identify the server...} - property GreetingBanner : string read FGreetingBanner; - property Host; - property UseTLS; - property SASLMechanisms : TIdSASLEntries read FSASLMechanisms write SetSASLMechanisms; - property AuthType : TIdIMAP4AuthenticationType read FAuthType write FAuthType default DEF_IMAP4_AUTH; - property MilliSecsToWaitToClearBuffer: integer read FMilliSecsToWaitToClearBuffer write FMilliSecsToWaitToClearBuffer; - {The following is the OnWork property for use when retrieving PARTS of a message. - It is also used for AppendMsg and Retrieve. This is in addition to the normal - OnWork property, which is exposed by TIdIMAP4, but which is only activated during - IMAP sending & receiving of commands (subject to the general OnWork caveats, i.e. - it is only called during certain methods, note OnWork[Begin][End] are all only - called in the methods AllData(), PerformCapture() and Read/WriteStream() ). - When a PART of a message is processed, use this for progress notification of - retrieval of IMAP parts, such as retrieving attachments. OnWorkBegin and - OnWorkEnd are not exposed, because they won't be activated during the processing - of a part.} - property OnWorkForPart: TWorkEvent read FOnWorkForPart write FOnWorkForPart; - property OnWorkBeginForPart: TWorkBeginEvent read FOnWorkBeginForPart write FOnWorkBeginForPart; - property OnWorkEndForPart: TWorkEndEvent read FOnWorkEndForPart write FOnWorkEndForPart; - end; - -implementation - -uses - //facilitate inlining on - {$IFDEF KYLIXCOMPAT} - Libc, - {$IFDEF MACOSX} - Posix.Unistd, - {$ENDIF} - {$ENDIF} - //facilitate inlining only. - {$IFDEF WINDOWS} - {$IFDEF USE_INLINE} - Windows, - {$ELSE} - //facilitate inlining only. - {$IFDEF VCL_2009_OR_ABOVE} - Windows, - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$IFDEF DOTNET} - {$IFDEF USE_INLINE} - System.IO, - {$ENDIF} - {$ENDIF} - {$IFDEF DOTNET} - IdStreamNET, - {$ELSE} - IdStreamVCL, - {$ENDIF} - {$IFDEF HAS_UNIT_Generics_Collections} - System.Generics.Collections, - {$ENDIF} - IdCoder, - IdEMailAddress, - IdExplicitTLSClientServerBase, - IdGlobalProtocols, - IdExceptionCore, - IdStack, - IdStackConsts, - IdStream, - IdTCPStream, - IdText, - IdAttachment, - IdResourceStringsProtocols, - IdBuffer, - IdAttachmentMemory, - IdReplyIMAP4, - IdTCPConnection, - IdSSL, - IdSASL, - IdMessageHelper, - SysUtils; - -type - TIdIMAP4FetchDataItem = ( - fdAll, //Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE) - fdBody, //Non-extensible form of BODYSTRUCTURE. - fdBodyExtensible, - fdBodyPeek, - fdBodyStructure, //The [MIME-IMB] body structure of the message. This - //is computed by the server by parsing the [MIME-IMB] - //header fields in the [RFC-822] header and [MIME-IMB] headers. - fdEnvelope, //The envelope structure of the message. This is - //computed by the server by parsing the [RFC-822] - //header into the component parts, defaulting various - //fields as necessary. - fdFast, //Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE) - fdFlags, //The flags that are set for this message. - fdFull, //Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY) - fdInternalDate, //The internal date of the message. - fdRFC822, //Functionally equivalent to BODY[], differing in the - //syntax of the resulting untagged FETCH data (RFC822 - //is returned). - fdRFC822Header, //Functionally equivalent to BODY.PEEK[HEADER], - //differing in the syntax of the resulting untagged - //FETCH data (RFC822.HEADER is returned). - fdRFC822Size, //The [RFC-822] size of the message. - fdRFC822Text, //Functionally equivalent to BODY[TEXT], differing in - //the syntax of the resulting untagged FETCH data - //(RFC822.TEXT is returned). - fdHeader, //CC: Added to get the header of a part - fdUID, //The unique identifier for the message. - fdGmailMsgID, //Gmail-specific unique identifier for the message. - fdGmailThreadID, //Gmail-specific thread identifier for the message. - fdGmailLabels //Gmail-specific labels for the message. - ); - -const - IMAP4Commands : array [TIdIMAP4Commands] of String = ( - { Client Commands - Any State} - 'CAPABILITY', {Do not Localize} - 'NOOP', {Do not Localize} - 'LOGOUT', {Do not Localize} - { Client Commands - Non Authenticated State} - 'AUTHENTICATE', {Do not Localize} - 'LOGIN', {Do not Localize} - { Client Commands - Authenticated State} - 'SELECT', {Do not Localize} - 'EXAMINE', {Do not Localize} - 'CREATE', {Do not Localize} - 'DELETE', {Do not Localize} - 'RENAME', {Do not Localize} - 'SUBSCRIBE', {Do not Localize} - 'UNSUBSCRIBE', {Do not Localize} - 'LIST', {Do not Localize} - 'LSUB', {Do not Localize} - 'STATUS', {Do not Localize} - 'APPEND', {Do not Localize} - { Client Commands - Selected State} - 'CHECK', {Do not Localize} - 'CLOSE', {Do not Localize} - 'EXPUNGE', {Do not Localize} - 'SEARCH', {Do not Localize} - 'FETCH', {Do not Localize} - 'STORE', {Do not Localize} - 'COPY', {Do not Localize} - 'UID', {Do not Localize} - { Client Commands - Experimental/ Expansion} - 'X' {Do not Localize} - ); - - IMAP4FetchDataItem : array [TIdIMAP4FetchDataItem] of String = ( - 'ALL', {Do not Localize} //Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE) - 'BODY', {Do not Localize} //Non-extensible form of BODYSTRUCTURE. - 'BODY[%s]<%s>', {Do not Localize} - 'BODY.PEEK[]', {Do not Localize} - 'BODYSTRUCTURE', {Do not Localize} //The [MIME-IMB] body structure of the message. This - //is computed by the server by parsing the [MIME-IMB] - //header fields in the [RFC-822] header and [MIME-IMB] headers. - 'ENVELOPE', {Do not Localize} //The envelope structure of the message. This is - //computed by the server by parsing the [RFC-822] - //header into the component parts, defaulting various - //fields as necessary. - 'FAST', {Do not Localize} //Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE) - 'FLAGS', {Do not Localize} //The flags that are set for this message. - 'FULL', {Do not Localize} //Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY) - 'INTERNALDATE', {Do not Localize} //The internal date of the message. - 'RFC822', {Do not Localize} //Functionally equivalent to BODY[], differing in the - //syntax of the resulting untagged FETCH data (RFC822 - //is returned). - 'RFC822.HEADER', {Do not Localize} //Functionally equivalent to BODY.PEEK[HEADER], - //differing in the syntax of the resulting untagged - //FETCH data (RFC822.HEADER is returned). - 'RFC822.SIZE', {Do not Localize} //The [RFC-822] size of the message. - 'RFC822.TEXT', {Do not Localize} //Functionally equivalent to BODY[TEXT], differing in - //the syntax of the resulting untagged FETCH data - //(RFC822.TEXT is returned). - 'HEADER', {Do not Localize} //CC: Added to get the header of a part - 'UID', {Do not Localize} //The unique identifier for the message. - 'X-GM-MSGID', {Do not Localize} //Gmail-specific unique identifier for the message. - 'X-GM-THRID', {Do not Localize} //Gmail-specific thread identifier for the message. - 'X-GM-LABELS' {Do not Localize} //Gmail-specific labels for the message. - ); - - IMAP4SearchKeys : array [TIdIMAP4SearchKey] of String = ( - 'ALL', {Do not Localize} //All messages in the mailbox; the default initial key for ANDing. - 'ANSWERED', {Do not Localize} //Messages with the \Answered flag set. - 'BCC', {Do not Localize} //Messages that contain the specified string in the envelope structure's BCC field. - 'BEFORE', {Do not Localize} //Messages whose internal date is earlier than the specified date. - 'BODY', {Do not Localize} //Messages that contain the specified string in the body of the message. - 'CC', {Do not Localize} //Messages that contain the specified string in the envelope structure's CC field. - 'DELETED', {Do not Localize} //Messages with the \Deleted flag set. - 'DRAFT', {Do not Localize} //Messages with the \Draft flag set. - 'FLAGGED', {Do not Localize} //Messages with the \Flagged flag set. - 'FROM', {Do not Localize} //Messages that contain the specified string in the envelope structure's FROM field. - 'HEADER', {Do not Localize} //Messages that have a header with the specified field-name (as defined in [RFC-822]) - //and that contains the specified string in the [RFC-822] field-body. - 'KEYWORD', {Do not Localize} //Messages with the specified keyword set. - 'LARGER', {Do not Localize} //Messages with an [RFC-822] size larger than the specified number of octets. - 'NEW', {Do not Localize} //Messages that have the \Recent flag set but not the \Seen flag. - //This is functionally equivalent to "(RECENT UNSEEN)". - 'NOT', {Do not Localize} //Messages that do not match the specified search key. - 'OLD', {Do not Localize} //Messages that do not have the \Recent flag set. This is functionally - //equivalent to "NOT RECENT" (as opposed to "NOT NEW"). - 'ON', {Do not Localize} //Messages whose internal date is within the specified date. - 'OR', {Do not Localize} //Messages that match either search key. - 'RECENT', {Do not Localize} //Messages that have the \Recent flag set. - 'SEEN', {Do not Localize} //Messages that have the \Seen flag set. - 'SENTBEFORE',{Do not Localize} //Messages whose [RFC-822] Date: header is earlier than the specified date. - 'SENTON', {Do not Localize} //Messages whose [RFC-822] Date: header is within the specified date. - 'SENTSINCE', {Do not Localize} //Messages whose [RFC-822] Date: header is within or later than the specified date. - 'SINCE', {Do not Localize} //Messages whose internal date is within or later than the specified date. - 'SMALLER', {Do not Localize} //Messages with an [RFC-822] size smaller than the specified number of octets. - 'SUBJECT', {Do not Localize} //Messages that contain the specified string in the envelope structure's SUBJECT field. - 'TEXT', {Do not Localize} //Messages that contain the specified string in the header or body of the message. - 'TO', {Do not Localize} //Messages that contain the specified string in the envelope structure's TO field. - 'UID', {Do not Localize} //Messages with unique identifiers corresponding to the specified unique identifier set. - 'UNANSWERED',{Do not Localize} //Messages that do not have the \Answered flag set. - 'UNDELETED', {Do not Localize} //Messages that do not have the \Deleted flag set. - 'UNDRAFT', {Do not Localize} //Messages that do not have the \Draft flag set. - 'UNFLAGGED', {Do not Localize} //Messages that do not have the \Flagged flag set. - 'UNKEYWORD', {Do not Localize} //Messages that do not have the specified keyword set. - 'UNSEEN', {Do not Localize} - 'X-GM-RAW', {Do not Localize} //Gmail extension to SEARCH command to allow full access to Gmail search syntax - 'X-GM-MSGID',{Do not Localize} //Gmail extension to SEARCH command to allow access to Gmail message identifier - 'X-GM-THRID',{Do not Localize} //Gmail extension to SEARCH command to allow access to Gmail thread identifier - 'X-GM-LABELS'{Do not Localize} //Gmail extension to SEARCH command to allow access to Gmail labels - ); - - IMAP4StatusDataItem : array [TIdIMAP4StatusDataItem] of String = ( - 'MESSAGES', {Do not Localize} - 'RECENT', {Do not Localize} - 'UIDNEXT', {Do not Localize} - 'UIDVALIDITY', {Do not Localize} - 'UNSEEN' {Do not Localize} - ); - -function IMAPQuotedStr(const S: String): String; -begin - Result := '"' + StringsReplace(S, ['\', '"'], ['\\', '\"']) + '"'; {Do not Localize} -end; - -{ TIdSASLEntriesIMAP4 } - -// RLebeau 2/8/2013 - TIdSASLEntries.LoginSASL() uses TIdTCPConnection.SendCmd() -// but TIdIMAP4 does not override the necessary virtuals to make that SendCmd() -// work correctly with IMAP. TIdIMAP reintroduces its own SendCmd() implementation, -// which TIdSASLEntries does not call. Until that can be changed, we will have -// to send the IMAP 'AUTHENTICATE' command manually! Doing it this way so as -// not to introduce an interface change that breaks backwards compatibility... - -function CheckStrFail(const AStr : String; const AOk, ACont: array of string) : Boolean; -begin - //Result := PosInStrArray(AStr, AOk + ACont) = -1; - Result := (PosInStrArray(AStr, AOk) = -1) and - (PosInStrArray(AStr, ACont) = -1); -end; - -function PerformSASLLogin_IMAP(ASASL: TIdSASL; AEncoder: TIdEncoder; - ADecoder: TIdDecoder; AClient : TIdIMAP4): Boolean; -const - AOkReplies: array[0..0] of string = (IMAP_OK); - AContinueReplies: array[0..0] of string = (IMAP_CONT); -var - S: String; - AuthStarted: Boolean; -begin - Result := False; - AuthStarted := False; - - // TODO: use UTF-8 when base64-encoding strings... - - if AClient.IsCapabilityListed('SASL-IR') then begin {Do not localize} - if ASASL.TryStartAuthenticate(AClient.Host, AClient.Port, IdGSKSSN_imap, S) then begin - AClient.SendCmd(AClient.NewCmdCounter, 'AUTHENTICATE ' + String(ASASL.ServiceName) + ' ' + AEncoder.Encode(S), [], True); {Do not Localize} - if CheckStrFail(AClient.LastCmdResult.Code, AOkReplies, AContinueReplies) then begin - ASASL.FinishAuthenticate; - Exit; // this mechanism is not supported - end; - AuthStarted := True; - end; - end; - if not AuthStarted then begin - AClient.SendCmd(AClient.NewCmdCounter, 'AUTHENTICATE ' + String(ASASL.ServiceName), [], True); {Do not Localize} - if CheckStrFail(AClient.LastCmdResult.Code, AOkReplies, AContinueReplies) then begin - Exit; // this mechanism is not supported - end; - end; - if (PosInStrArray(AClient.LastCmdResult.Code, AOkReplies) > -1) then begin - if AuthStarted then begin - ASASL.FinishAuthenticate; - end; - Result := True; - Exit; // we've authenticated successfully :) - end; - // must be a continue reply... - if not AuthStarted then begin - S := ADecoder.DecodeString(TrimRight(TIdReplyIMAP4(AClient.LastCmdResult).Extra.Text)); - S := ASASL.StartAuthenticate(S, AClient.Host, AClient.Port, IdGSKSSN_imap); - AClient.IOHandler.WriteLn(AEncoder.Encode(S)); - AClient.GetInternalResponse(AClient.LastCmdCounter, [], True); - if CheckStrFail(AClient.LastCmdResult.Code, AOkReplies, AContinueReplies) then - begin - ASASL.FinishAuthenticate; - Exit; - end; - end; - while PosInStrArray(AClient.LastCmdResult.Code, AContinueReplies) > -1 do begin - S := ADecoder.DecodeString(TrimRight(TIdReplyIMAP4(AClient.LastCmdResult).Extra.Text)); - S := ASASL.ContinueAuthenticate(S, AClient.Host, AClient.Port, IdGSKSSN_imap); - AClient.IOHandler.WriteLn(AEncoder.Encode(S)); - AClient.GetInternalResponse(AClient.LastCmdCounter, [], True); - if CheckStrFail(AClient.LastCmdResult.Code, AOkReplies, AContinueReplies) then - begin - ASASL.FinishAuthenticate; - Exit; - end; - end; - Result := (PosInStrArray(AClient.LastCmdResult.Code, AOkReplies) > -1); - ASASL.FinishAuthenticate; -end; - -type - {$IFDEF HAS_GENERICS_TList} - TIdSASLList = TList; - {$ELSE} - // TODO: flesh out to match TList for non-Generics compilers - TIdSASLList = TList; - {$ENDIF} - - TIdSASLEntriesIMAP4 = class(TIdSASLEntries) - public - procedure LoginSASL_IMAP(AClient: TIdIMAP4); - end; - -procedure TIdSASLEntriesIMAP4.LoginSASL_IMAP(AClient: TIdIMAP4); -var - i : Integer; - LE : TIdEncoderMIME; - LD : TIdDecoderMIME; - LSupportedSASL : TStrings; - LSASLList: TIdSASLList; - LSASL : TIdSASL; - LError : TIdReply; - - function SetupErrorReply: TIdReply; - begin - Result := TIdReplyClass(AClient.LastCmdResult.ClassType).Create(nil); - Result.Assign(AClient.LastCmdResult); - end; - -begin - // make sure the collection is not empty - CheckIfEmpty; - - //create a list of mechanisms that both parties support - LSASLList := TIdSASLList.Create; - try - LSupportedSASL := TStringList.Create; - try - ParseCapaReplyToList(AClient.FCapabilities, LSupportedSASL, 'AUTH'); {Do not Localize} - for i := Count-1 downto 0 do begin - LSASL := Items[i].SASL; - if LSASL <> nil then begin - if not LSASL.IsAuthProtocolAvailable(LSupportedSASL) then begin - Continue; - end; - if LSASLList.IndexOf(LSASL) = -1 then begin - LSASLList.Add(LSASL); - end; - end; - end; - finally - FreeAndNil(LSupportedSASL); - end; - - if LSASLList.Count = 0 then begin - raise EIdSASLNotSupported.Create(RSSASLNotSupported); - end; - - //now do it - LE := nil; - try - LD := nil; - try - LError := nil; - try - for i := 0 to LSASLList.Count-1 do begin - LSASL := {$IFDEF HAS_GENERICS_TList}LSASLList.Items[i]{$ELSE}TIdSASL(LSASLList.Items[i]){$ENDIF}; - if not LSASL.IsReadyToStart then begin - Continue; - end; - if not Assigned(LE) then begin - LE := TIdEncoderMIME.Create(nil); - end; - if not Assigned(LD) then begin - LD := TIdDecoderMIME.Create(nil); - end; - if PerformSASLLogin_IMAP(LSASL, LE, LD, AClient) then begin - Exit; - end; - if not Assigned(LError) then begin - LError := SetupErrorReply; - end; - end; - if Assigned(LError) then begin - LError.RaiseReplyError; - end else begin - raise EIdSASLNotReady.Create(RSSASLNotReady); - end; - finally - FreeAndNil(LError); - end; - finally - FreeAndNil(LD); - end; - finally - FreeAndNil(LE); - end; - finally - FreeAndNil(LSASLList); - end; -end; - -{ TIdIMAP4WorkHelper } - -type - TIdIMAP4WorkHelper = class(TIdComponent) - protected - fIMAP4: TIdIMAP4; - fOldTarget: TIdComponent; - public - constructor Create(AIMAP4: TIdIMAP4); reintroduce; - destructor Destroy; override; - end; - -constructor TIdIMAP4WorkHelper.Create(AIMAP4: TIdIMAP4); -begin - inherited Create(nil); - fIMAP4 := AIMAP4; - fOldTarget := fIMAP4.WorkTarget; - fIMAP4.WorkTarget := Self; - Self.OnWorkBegin := fIMAP4.BeginWorkForPart; - Self.OnWork := fIMAP4.DoWorkForPart; - Self.OnWorkEnd := fIMAP4.EndWorkForPart; -end; - -destructor TIdIMAP4WorkHelper.Destroy; -begin - fIMAP4.WorkTarget := fOldTarget; - inherited Destroy; -end; - -{ TIdEMUTF7 } - -const - b64Chars : String = - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,'; {Do not Localize} - - b64Index : array [0..127] of Integer = ( - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 16 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 32 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,63,-1,-1,-1, // 48 - 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, // 64 - -1,00,01,02,03,04,05,06,07,08,09,10,11,12,13,14, // 80 - 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, // 96 - -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, // 112 - 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1 // 128 - ); - - b64Table : array[0..127] of Integer = ( - $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, // 16 - $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, // 32 - $20,$21,$22,$23, $24,$25,$FF,$27, $28,$29,$2A,$2B, $2C,$2D,$2E,$2F, // 48 - $30,$31,$32,$33, $34,$35,$36,$37, $38,$39,$3A,$3B, $3C,$3D,$3E,$3F, // 64 - $40,$41,$42,$43, $44,$45,$46,$47, $48,$49,$4A,$4B, $4C,$4D,$4E,$4F, // 80 - $50,$51,$52,$53, $54,$55,$56,$57, $58,$59,$5A,$5B, $5C,$5D,$5E,$5F, // 96 - $60,$61,$62,$63, $64,$65,$66,$67, $68,$69,$6A,$6B, $6C,$6D,$6E,$6F, // 112 - $70,$71,$72,$73, $74,$75,$76,$77, $78,$79,$7A,$7B, $7C,$7D,$7E,$FF);// 128 - -// TODO: re-write this to derive from IdCoder3To4.pas or IdCoderMIME.pas classes... - -function TIdMUTF7.Encode(const aString: TIdUnicodeString): String; -{ -- MUTF7Encode ------------------------------------------------------------- -PRE: nothing -POST: returns a string encoded as described in IETF RFC 3501, section 5.1.3 - based upon RFC 2152 - - 2004-03-02 roman puls: speed improvements of around 2000 percent due to - replacement of pchar/while loops to delphi-style string/for - loops. Minor changes for '&' handling. Delphi 8 compatible. - 2004-02-29 roman puls: initial version ---} -var - c : Word; - bitBuf : UInt32; - bitShift : Integer; - x : Integer; - escaped : Boolean; - CharToAppend: Char; - {$IFDEF STRING_IS_IMMUTABLE} - LSB: TIdStringBuilder; - {$ENDIF} -begin - Result := ''; - escaped := False; - bitShift := 0; - bitBuf := 0; - - {$IFDEF STRING_IS_IMMUTABLE} - LSB := TIdStringBuilder.Create; - {$ENDIF} - - for x := 1 to Length(aString) do begin - c := Word(aString[x]); - // c must be < 128 _and_ in table b64table - if (c <= $7f) and (b64Table[c] <> $FF) or (aString[x] = '&') then begin // we can directly encode that char - if escaped then begin - if (bitShift > 0) then begin // flush bitbuffer if needed - CharToAppend := b64Chars[(bitBuf shl (6 - bitShift) and $3F) + 1]; - {$IFDEF STRING_IS_IMMUTABLE} - LSB.Append(CharToAppend); - {$ELSE} - Result := Result + CharToAppend; - {$ENDIF} - end; - {$IFDEF STRING_IS_IMMUTABLE} - LSB.Append(Char('-')); // leave escape sequence - {$ELSE} - Result := Result + '-'; // leave escape sequence - {$ENDIF} - escaped := False; - end; - if (aString[x] = '&') then begin // escape special char "&" - {$IFDEF STRING_IS_IMMUTABLE} - LSB.Append('&-'); - {$ELSE} - Result := Result + '&-'; - {$ENDIF} - end else begin - CharToAppend := Char(c); - {$IFDEF STRING_IS_IMMUTABLE} - LSB.Append(CharToAppend); // store direct translated char - {$ELSE} - Result := Result + CharToAppend; // store direct translated char - {$ENDIF} - end; - end else begin - if not escaped then begin - {$IFDEF STRING_IS_IMMUTABLE} - LSB.Append(Char('&')); - {$ELSE} - Result := Result + '&'; - {$ENDIF} - bitShift := 0; - bitBuf := 0; - escaped := True; - end; - bitbuf := (bitBuf shl 16) or c; // shift and store new bye - Inc(bitShift, 16); - while (bitShift >= 6) do begin // flush buffer as far as we can - Dec(bitShift, 6); - CharToAppend := b64Chars[((bitBuf shr bitShift) and $3F) + 1]; - {$IFDEF STRING_IS_IMMUTABLE} - LSB.Append(CharToAppend); - {$ELSE} - Result := Result + CharToAppend; - {$ENDIF} - end; - end; - end; - - // we love duplicate work but must test for flush buffers for the price - // of speed (loop) - if escaped then begin - if (bitShift > 0) then begin - CharToAppend := b64Chars[(bitBuf shl (6 - bitShift) and $3F) + 1]; - {$IFDEF STRING_IS_IMMUTABLE} - LSB.Append(CharToAppend); - {$ELSE} - Result := Result + CharToAppend; - {$ENDIF} - end; - {$IFDEF STRING_IS_IMMUTABLE} - LSB.Append(Char('-')); - {$ELSE} - Result := Result + '-'; - {$ENDIF} - end; - - {$IFDEF STRING_IS_IMMUTABLE} - Result := LSB.ToString; - {$ENDIF} -end; - -function TIdMUTF7.Decode(const aString: String): TIdUnicodeString; -{ -- mUTF7Decode ------------------------------------------------------------- -PRE: aString encoding must conform to IETF RFC 3501, section 5.1.3 -POST: SUCCESS: an 8bit string - FAILURE: an exception of type EMUTF7Decode - - 2004-03-02 roman puls: speed improvements of around 400 percent due to - replacement of pchar/while loops to delphi-style string/for - loops. Delphi 8 compatible. - 2004-02-29 roman puls: initial version ---} -const - bitMasks: array[0..4] of UInt32 = ($00000000, $00000001, $00000003, $00000007, $0000000F); -var - ch : Byte; - last : Char; - bitBuf : UInt32; - escaped : Boolean; - x, bitShift: Integer; - CharToAppend: WideChar; - {$IFDEF STRING_IS_IMMUTABLE} - LSB: TIdStringBuilder; - {$ENDIF} -begin - Result := ''; - escaped := False; - bitShift := 0; - last := #0; - bitBuf := 0; - - {$IFDEF STRING_IS_IMMUTABLE} - LSB := TIdStringBuilder.Create; - {$ENDIF} - - for x := 1 to Length(aString) do begin - ch := Byte(aString[x]); - if not escaped then begin - if (aString[x] = '&') then begin // escape sequence found - escaped := True; - bitBuf := 0; - bitShift := 0; - last := '&'; - end - else if (ch < $80) and (b64Table[ch] <> $FF) then begin - {$IFDEF STRING_IS_IMMUTABLE} - LSB.Append(WideChar(ch)); - {$ELSE} - Result := Result + WideChar(ch); - {$ENDIF} - end else begin - raise EMUTF7Decode.CreateFmt('Illegal char #%d in UTF7 sequence.', [Integer(ch)]); {do not localize} - end; - end else begin // we're escaped - { break out of escape mode } - if (aString[x] = '-') then begin - // extra check for pending bits - if (last = '&') then begin // special sequence '&-' ? - {$IFDEF STRING_IS_IMMUTABLE} - LSB.Append(Char('&')); - {$ELSE} - Result := Result + '&'; - {$ENDIF} - end else begin - if (bitShift >= 16) then begin - Dec(bitShift, 16); - CharToAppend := WideChar((bitBuf shr bitShift) and $FFFF); - {$IFDEF STRING_IS_IMMUTABLE} - LSB.Append(CharToAppend); - {$ELSE} - Result := Result + CharToAppend; - {$ENDIF} - end; - if (bitShift > 4) or ((bitBuf and bitMasks[bitShift]) <> 0) then begin // check for bitboundaries - raise EMUTF7Decode.Create('Illegal bit sequence in MUTF7 string'); {do not localize} - end; - end; - escaped := False; - end else begin // still escaped - // check range for ch: must be < 128 and in b64table - if (ch >= $80) or (b64Index[ch] = -1) then begin - raise EMUTF7Decode.CreateFmt('Illegal char #%d in UTF7 sequence.', [Integer(ch)]); {do not localize} - end; - ch := b64Index[ch]; - bitBuf := (bitBuf shl 6) or (ch and $3F); - Inc(bitShift, 6); - if (bitShift >= 16) then begin - Dec(bitShift, 16); - CharToAppend := WideChar((bitBuf shr bitShift) and $FFFF); - {$IFDEF STRING_IS_IMMUTABLE} - LSB.Append(CharToAppend); - {$ELSE} - Result := Result + CharToAppend; - {$ENDIF} - end; - end; - last := #0; - end; - end; - if escaped then begin - raise EmUTF7Decode.Create('Missing unescape in UTF7 sequence.'); {do not localize} - end; - - {$IFDEF STRING_IS_IMMUTABLE} - Result := LSB.ToString; - {$ENDIF} -end; - -function TIdMUTF7.Valid(const aMUTF7String : String): Boolean; -{ -- mUTF7valid ------------------------------------------------------------- -PRE: NIL -POST: returns true if string is correctly encoded (as described in mUTF7Encode) - returns false otherwise -} -begin - try - Result := (aMUTF7String = {mUTF7}Encode({mUTF7}Decode(aMUTF7String))); - except - on e: EmUTF7Error do begin - Result := False; - end; - // do not handle others - end; -end; - -function TIdMUTF7.Append(const aMUTF7String: String; const aStr : TIdUnicodeString): String; -{ -- mUTF7Append ------------------------------------------------------------- -PRE: aMUTF7String is complying to mUTF7Encode's description -POST: SUCCESS: a concatenation of both input strings in mUTF - FAILURE: an exception of EMUTF7Decode or EMUTF7Encode will be raised -} -begin - Result := {mUTF7}Encode({mUTF7}Decode(aMUTF7String) + aStr); -end; - -{ TIdImapMessageParts } - -constructor TIdImapMessagePart.Create(Collection: TCollection); -begin - {Make sure these are initialised properly...} - inherited Create(Collection); - FParentPart := -1; - FBoundary := ''; {Do not Localize} -end; - -constructor TIdImapMessageParts.Create(AOwner: TPersistent); -begin - inherited Create(AOwner, TIdImapMessagePart); -end; - -function TIdImapMessageParts.GetItem(Index: Integer): TIdImapMessagePart; -begin - Result := TIdImapMessagePart(inherited GetItem(Index)); -end; - -function TIdImapMessageParts.Add: TIdImapMessagePart; -begin - Result := TIdImapMessagePart(inherited Add); -end; - -procedure TIdImapMessageParts.SetItem(Index: Integer; const Value: TIdImapMessagePart); -begin - inherited SetItem(Index, Value); -end; - -{ TIdIMAP4 } - -procedure TIdIMAP4.BeginWorkForPart(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); -begin - if Assigned(FOnWorkBeginForPart) then begin - FOnWorkBeginForPart(Self, AWorkMode, AWorkCountMax); - end; -end; - -procedure TIdIMAP4.DoWorkForPart(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); -begin - if Assigned(FOnWorkForPart) then begin - FOnWorkForPart(Self, AWorkMode, AWorkCount); - end; -end; - -procedure TIdIMAP4.EndWorkForPart(ASender: TObject; AWorkMode: TWorkMode); -begin - if Assigned(FOnWorkEndForPart) then begin - FOnWorkEndForPart(Self, AWorkMode); - end; -end; - -//The following call FMUTF7 but do exception-handling on invalid strings... -function TIdIMAP4.DoMUTFEncode(const aString : String): String; -begin - // TODO: if the server advertises the "UTF8=ACCEPT" capability, use - // a UTF-8 quoted string instead of IMAP's Modified UTF-7... - try - Result := FMUTF7.Encode( - {$IFDEF STRING_IS_UNICODE} - aString - {$ELSE} - TIdUnicodeString(aString) // explicit convert to Unicode - {$ENDIF} - ); - except - Result := aString; - end; -end; - -function TIdIMAP4.DoMUTFDecode(const aString : String): String; -begin - try - {$IFDEF STRING_IS_UNICODE} - Result := FMUTF7.Decode(aString); - {$ELSE} - Result := String(FMUTF7.Decode(aString)); // explicit convert to Ansi - {$ENDIF} - except - Result := aString; - end; -end; - -function TIdIMAP4.GetReplyClass:TIdReplyClass; -begin - Result := TIdReplyIMAP4; -end; - -function TIdIMAP4.GetSupportsTLS: Boolean; -begin - Result := IsCapabilityListed('STARTTLS'); //do not localize -end; - -function TIdIMAP4.CheckConnectionState(AAllowedState: TIdIMAP4ConnectionState): TIdIMAP4ConnectionState; -begin - if FConnectionState = AAllowedState then begin - Result := FConnectionState; - end else begin - raise EIdConnectionStateError.CreateFmt(RSIMAP4ConnectionStateError, [GetConnectionStateName]); - end; -end; - -function TIdIMAP4.CheckConnectionState(const AAllowedStates: array of TIdIMAP4ConnectionState): TIdIMAP4ConnectionState; -var - i: integer; -begin - if High(AAllowedStates) > -1 then begin - // Cannot use PosInSmallIntArray() here... - for i := Low(AAllowedStates) to High(AAllowedStates) do begin - if FConnectionState = AAllowedStates[i] then begin - Result := FConnectionState; - Exit; - end; - end; - end; - raise EIdConnectionStateError.CreateFmt(RSIMAP4ConnectionStateError, [GetConnectionStateName]); -end; - -function TIdIMAP4.CheckReplyForCapabilities: Boolean; -var - I: Integer; - LExtra: TStrings; -begin - FCapabilities.Clear; - FHasCapa := False; - LExtra := TIdReplyIMAP4(FLastCmdResult).Extra; - for I := 0 to LExtra.Count-1 do begin - if TextStartsWith(LExtra.Strings[I], 'CAPABILITY ') then begin {Do not Localize} - BreakApart(LExtra.Strings[I], ' ', FCapabilities); {Do not Localize} - // RLebeau: do not delete the first item anymore! It specifies the IMAP - // version/revision, which is needed to support certain extensions, like - // 'IMAP4rev1'... - {FCapabilities.Delete(0);} - FHasCapa := True; - Break; - end; - end; - Result := FHasCapa; -end; - -function TIdIMAP4.FindHowServerCreatesFolders: TIdIMAP4FolderTreatment; -var - LUsersFolders: TStringList; - LN: integer; - LInbox: string; - LTestFolder: string; -begin - LUsersFolders := TStringList.Create; - try - {$IFDEF HAS_TStringList_CaseSensitive} - LUsersFolders.CaseSensitive := False; - {$ENDIF} - - //Get folder names... - if not ListMailBoxes(LUsersFolders) then begin - Result := ftCannotRetrieveAnyFolders; - Exit; - end; - - if LUsersFolders.Count = 0 then begin - Result := ftCannotRetrieveAnyFolders; - Exit; - end; - - //Do we have an Inbox? - LN := IndyIndexOf(LUsersFolders, 'INBOX'); {Do not Localize} - if LN = -1 then begin - Result := ftCannotTestBecauseHasNoInbox; - Exit; - end; - LInbox := LUsersFolders.Strings[LN]; - - //Make sure our test folder does not already exist at the top level... - LTestFolder := 'CiaransTestFolder'; {Do not Localize} - while IndyIndexOf(LUsersFolders, LTestFolder) <> -1 do begin - LTestFolder := LTestFolder + '9'; {Do not Localize} - end; - - //Try to create LTestFolder at the top level... - if CreateMailbox(LTestFolder) then begin - //We were able to create it at the top level - delete it and exit.. - DeleteMailbox(LTestFolder); - Result := ftAllowsTopLevelCreation; - Exit; - end; - - //See if our test folder does not exist under INBOX... - LTestFolder := LInbox + FMailBoxSeparator + 'CiaransTestFolder'; {Do not Localize} - while IndyIndexOf(LUsersFolders, LTestFolder) <> -1 do begin - LTestFolder := LTestFolder + '9'; {Do not Localize} - end; - - //Try to create LTestFolder under Inbox... - if CreateMailbox(LTestFolder) then begin - //We were able to create it under the top level - delete it and exit.. - DeleteMailbox(LTestFolder); - Result := ftFoldersMustBeUnderInbox; - Exit; - end; - - //It does not allow us create folders under any level (read-only?)... - Result := ftDoesNotAllowFolderCreation; - finally - FreeAndNil(LUsersFolders); - end; -end; - -function TIdIMAP4.IsNumberValid(const ANumber: UInt32): Boolean; - {CC3: Need to validate message numbers (relative and UIDs), because otherwise - the routines wait for a response that never arrives and so functions never return.} -begin - if ANumber < 1 then begin - raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); - end; - Result := True; -end; - -{$IFNDEF HAS_TryStrToInt64} -// TODO: move this to IdGlobalProtocols... -function TryStrToInt64(const S: string; out Value: Int64): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -var - E: Integer; -begin - Val(S, Value, E); - Result := E = 0; -end; -{$ENDIF} - -function UIDToUInt32(const AUID: String): UInt32; -var - LNumber: Int64; -begin - if Length(AUID) = 0 then begin - raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); - end; - if not TryStrToInt64(AUID, LNumber) then begin - raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); - end; - if (LNumber < 1) or (LNumber > Int64(High(UInt32))) then begin - raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); - end; - Result := UInt32(LNumber); -end; - -function TIdIMAP4.IsUIDValid(const AUID: string): Boolean; - {CC3: Need to validate message numbers (relative and UIDs), because otherwise - the routines wait for a response that never arrives and so functions never return.} -begin - //Must be digits only (no - or .) - IsItDigitsAndOptionallyPeriod(AUID, False); - UIDToUInt32(AUID); - Result := True; -end; - -function TIdIMAP4.IsImapPartNumberValid(const APartNum: Integer): Boolean; -begin - if APartNum < 1 then begin - raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); - end; - Result := True; -end; - -function TIdIMAP4.IsImapPartNumberValid(const APartNum: string): Boolean; - {CC3: IMAP part numbers are 3 or 4.5 etc, i.e. digits or period allowed} -begin - Result := IsItDigitsAndOptionallyPeriod(APartNum, True); -end; - -function TIdIMAP4.IsItDigitsAndOptionallyPeriod(const AStr: string; AAllowPeriod: Boolean): Boolean; -var - LN: integer; -begin - if Length(AStr) = 0 then begin - raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); - end; - if AAllowPeriod then begin - for LN := 1 to Length(AStr) do begin - if not IsNumeric(AStr[LN]) then begin - if AStr[LN] <> '.' then begin {Do not Localize} - raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); - end; - end; - end; - end - else if not IsNumeric(AStr) then begin - raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); - end; - Result := True; -end; - -function TIdIMAP4.GetUID(const AMsgNum: UInt32; var AUID: string): Boolean; -{This gets the message UID from the message relative number.} -begin - Result := False; - AUID := ''; {Do not Localize} - IsNumberValid(AMsgNum); - - CheckConnectionState(csSelected); - {Some servers return NO if the requested message number is not present - (e.g. Cyrus), others return OK but no data (CommuniGate).} - SendCmd(NewCmdCounter, - IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdUID] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch]]); - if LastCmdResult.Code = IMAP_OK then begin - //Might as well leave 3rd param as [] because ParseLastCmdResult always grabs the UID... - if LastCmdResult.Text.Count > 0 then begin - if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], []) then begin - AUID := FLineStruct.UID; - Result := True; - end; - end; - end; -end; - -{$I IdDeprecatedImplBugOff.inc} -procedure TIdIMAP4.WriteLn(const AOut: string = ''); -{$I IdDeprecatedImplBugOn.inc} -begin - IOHandler.WriteLn(AOut); -end; - -{$I IdDeprecatedImplBugOff.inc} -function TIdIMAP4.ReadLnWait: string; -{$I IdDeprecatedImplBugOn.inc} -begin - Result := IOHandler.ReadLnWait; {This can have hit an exception of Connection Reset By Peer (timeout)} -end; - -{ IdTCPConnection Commands... } - -function TIdIMAP4.GetInternalResponse(const ATag: String; AExpectedResponses: array of String; - ASingleLineMode: Boolean; ASingleLineMayBeSplit: Boolean {= True}): string; -{ASingleLineMode is True if the caller just wants the FIRST line of the response, -e.g., he may be looking only for "* FETCH (blah blah)", because he needs to parse -that line to figure out how the rest will follow. This arises with a number of the -FETCH commands where the caller needs to get the byte-count from the first line -before he can retrieve the rest of the response. -Note "FETCH" would have to be in AExpectedResponses. -When False, the caller wants everything up to and including the reply terminator -(e.g. "C45 OK Completed"). -In ASingleLineMode, we ignore any lines that dont have one of AExpectedResponses -at the start, otherwise we add all lines to .Text and later strip out any lines that -dont have one of AExpectedResponses at the start. -ASingleLineMayBeSplit (which should only be used with ASingleLineMode = True) deals -with the case where the server cannot or does not fit a single-line -response onto one line. This arises when FETCHing the BODYSTRUCTURE, which can -be very long. The server (Courier, anyway) signals it by adding a byte-count to -the end of the first line, that would not normally be present.} -//For example, for normal short responses, the server would send: -// * FETCH (BODYSTRUCTURE (Part1 Part2)) -//but if it splits it, it sends: -// * FETCH (BODYSTRUCTURE (Part1 {7} -// Part2)) -//The number in the curly brackets {7} is the byte count following the line break. -{WARNING: If you use ASingleLineMayBeSplit on a line that is EXPECTED to end -with a byte-count, the code will break, so don't use it unless absolutely -necessary.} -var - LLine: String; - LResponse: TStringList; - LWord: string; - LPos: integer; - LStrippedLineLength: Integer; - LGotALineWithAnExpectedResponse: Boolean; - LStrippedLine: string; - LSplitLine: string; -begin - LGotALineWithAnExpectedResponse := False; - LResponse := TStringList.Create; - try - repeat - LLine := IOHandler.ReadLnWait; - {CCB: Trap case of server telling you that you have been disconnected, usually because - you were inactive for too long (get "* BYE idle time too long"). } - if TextStartsWith(LLine, '* BYE') then begin {Do not Localize} - {If BYE is in AExpectedResponses, this means we are expecting to - disconnect, i.e. it is a LOGOUT.} - if PosInStrArray('BYE', AExpectedResponses) = -1 then begin {Do not Localize} - {We were not expecting a BYE response. - For the moment, throw an exception. Could modify this by adding a - ReconnectOnDisconnect property to automatically reconnect?} - FConnectionState := csUnexpectedlyDisconnected; - raise EIdDisconnectedProbablyIdledOut.Create(RSIMAP4DisconnectedProbablyIdledOut); - end; - end; - if ASingleLineMode then begin - //See if it may continue on the next line... - if ASingleLineMayBeSplit then begin - //If the line is split, it will have a byte-count field at the end... - if TextEndsWith(LLine, '}') then begin - //It is split. - LStrippedLine := LLine; - LLine := ''; - repeat - //First, remove the byte count... - LPos := Length(LStrippedLine)-1; - while LPos >= 1 do begin - if LStrippedLine[LPos] = '{' then begin - Break; - end; - Dec(LPos); - end; - LWord := Copy(LStrippedLine, LPos+1, (Length(LStrippedLine)-LPos)-1); - if TextIsSame(LWord, 'NIL') then begin - LStrippedLineLength := 0; - end else begin - LStrippedLineLength := StrToInt(LWord); - end; - LStrippedLine := Copy(LStrippedLine, 1, LPos-1); - //The rest of the reply is on the following line... - LSplitLine := IOHandler.ReadString(LStrippedLineLength); - // At this point LSplitLine should be parsed and the following characters should be escaped... " CR LF. - LLine := LLine + LStrippedLine + LSplitLine; - LStrippedLine := IOHandler.ReadLn; //Cannot thrash LLine, need it later - until not TextEndsWith(LStrippedLine, '}'); - LLine := LLine + LStrippedLine; - end; - end; - LStrippedLine := LLine; - if TextStartsWith(LLine, '* ') then begin {Do not Localize} - LStrippedLine := Copy(LLine, 3, MaxInt); - end; - LGotALineWithAnExpectedResponse := TIdReplyIMAP4(FLastCmdResult).DoesLineHaveExpectedResponse(LStrippedLine, AExpectedResponses); - if LGotALineWithAnExpectedResponse then begin - FLastCmdResult.Text.Clear; - TIdReplyIMAP4(FLastCmdResult).Extra.Clear; - FLastCmdResult.Text.Add(LStrippedLine); - end; - end else - begin - //If the line is split, it will have a byte-count field at the end... - if TextEndsWith(LLine, '}') then begin - LStrippedLine := LLine; - LLine := ''; - repeat - //It is split. - //First, remove the byte count... - LPos := Length(LStrippedLine)-1; - while LPos >= 1 do begin - if LStrippedLine[LPos] = '{' then begin - Break; - end; - Dec(LPos); - end; - LWord := Copy(LStrippedLine, LPos+1, (Length(LStrippedLine)-LPos)-1); - if TextIsSame(LWord, 'NIL') then begin - LStrippedLineLength := 0; - end else begin - LStrippedLineLength := StrToInt(LWord); - end; - LStrippedLine := Copy(LStrippedLine, 1, LPos-1); - //The rest of the reply is on the following line... - LSplitLine := IOHandler.ReadString(LStrippedLineLength); - // At this point LSplitLine should be parsed and the following characters should be escaped... " CR LF. - LLine := LLine + LStrippedLine + LSplitLine; - LStrippedLine := IOHandler.ReadLn; //Cannot thrash LLine, need it later - until not TextEndsWith(LStrippedLine, '}'); - LLine := LLine + LStrippedLine; - end; - end; - LResponse.Add(LLine); - //Need to get the 1st word on the line in case it is +, PREAUTH, etc... - LPos := Pos(' ', LLine); {Do not Localize} - if LPos <> 0 then begin - {There are at least two words on this line...} - LWord := Trim(Copy(LLine, 1, LPos-1)); - end else begin - {No space, so this line is a single word. A bit weird, but it - could be just an OK...} - LWord := LLine; {A bit pedantic, but emphasises we have a word, not a line} - end; - until - TextStartsWith(LLine, ATag) - or (PosInStrArray(LWord, VALID_TAGGEDREPLIES) <> -1) - or LGotALineWithAnExpectedResponse; - if LGotALineWithAnExpectedResponse then begin - //This only arises if ASingleLineMode is True... - FLastCmdResult.Code := IMAP_OK; - end else begin - FLastCmdResult.FormattedReply := LResponse; - TIdReplyIMAP4(FLastCmdResult).RemoveUnsolicitedResponses(AExpectedResponses); - end; - Result := FLastCmdResult.Code; - finally - FreeAndNil(LResponse); - end; -end; - -function TIdIMAP4.SendCmd(const AOut: string; AExpectedResponses: array of String; - ASingleLineMode: Boolean = False; ASingleLineMayBeSplit: Boolean = True): string; -begin - Result := SendCmd(NewCmdCounter, AOut, AExpectedResponses, ASingleLineMode, ASingleLineMayBeSplit); -end; - -function TIdIMAP4.SendCmd(const ATag, AOut: string; AExpectedResponses: array of String; - ASingleLineMode: Boolean = False; ASingleLineMayBeSplit: Boolean = True): string; -var - LCmd: String; -begin - {CC3: Catch "Connection reset by peer"...} - try - if (AOut <> #0) then begin - //Remove anything that may be unprocessed from a previous (probably failed) command... - repeat - IOHandler.InputBuffer.Clear; - until not IOHandler.CheckForDataOnSource(MilliSecsToWaitToClearBuffer); - LCmd := ATag + ' ' + AOut; - CheckConnected; - PrepareCmd(LCmd); - IOHandler.WriteLn(LCmd); - end; - Result := GetInternalResponse(ATag, AExpectedResponses, ASingleLineMode, ASingleLineMayBeSplit); - except - on E: EIdSocketError do begin - if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin - FConnectionState := csUnexpectedlyDisconnected; - end; - raise; - end; - end; -end; - -{ ...IdTCPConnection Commands } - -procedure TIdIMAP4.DoAlert(const AMsg: String); -begin - if Assigned(OnAlert) then begin - OnAlert(Self, AMsg); - end; -end; - -procedure TIdIMAP4.SetMailBox(const Value: TIdMailBox); -begin - FMailBox.Assign(Value); -end; - -procedure TIdIMAP4.SetSASLMechanisms(AValue: TIdSASLEntries); -begin - FSASLMechanisms.Assign(AValue); -end; - -procedure TIdIMAP4.Login; -var - LIO: TIdSSLIOHandlerSocketBase; -begin - try - if (IOHandler is TIdSSLIOHandlerSocketBase) and (UseTLS in ExplicitTLSVals) then begin - LIO := TIdSSLIOHandlerSocketBase(IOHandler); - //we check passthrough because we can either be using TLS currently with - //implicit TLS support or because STARTLS was issued previously. - if LIO.PassThrough then begin - if SupportsTLS then begin - if SendCmd(NewCmdCounter, 'STARTTLS', []) = IMAP_OK then begin {Do not Localize} - TLSHandshake; - //obtain capabilities again - RFC2595 - Capability; - end else begin - ProcessTLSNegCmdFailed; - end; - end else begin - ProcessTLSNotAvail; - end; - end; - end; - FConnectionState := csNonAuthenticated; - FCmdCounter := 0; - if FAuthType = iatUserPass then begin - if Length(Password) <> 0 then begin {Do not Localize} - SendCmd(NewCmdCounter, IMAP4Commands[cmdLogin] + ' ' + Username + ' ' + IMAPQuotedStr(Password), [IMAP_OK]); {Do not Localize} - end else begin - SendCmd(NewCmdCounter, IMAP4Commands[cmdLogin] + ' ' + Username, [IMAP_OK]); {Do not Localize} - end; - if LastCmdResult.Code <> IMAP_OK then begin - RaiseExceptionForLastCmdResult; - end; - end else - begin - if not FHasCapa then begin - Capability; - end; - // FSASLMechanisms.LoginSASL('AUTHENTICATE', FHost, FPort, IdGSKSSN_imap, [IMAP_OK], [IMAP_CONT], Self, FCapabilities, 'AUTH', IsCapabilityListed('SASL-IR')); {Do not Localize} - TIdSASLEntriesIMAP4(FSASLMechanisms).LoginSASL_IMAP(Self); - end; - FConnectionState := csAuthenticated; - // RLebeau: check if the response includes new Capabilities, if not then query for them... - if not CheckReplyForCapabilities then begin - Capability; - end; - except - Disconnect; - raise; - end; -end; - -function TIdIMAP4.Connect(const AAutoLogin: Boolean = True): Boolean; -begin - {CC2: Need to set FConnectionState to csNonAuthenticated here. If not, then - an unsuccessful connect after a previous successful connect (such as when a - client program changes users) can leave it as csAuthenticated.} - FConnectionState := csNonAuthenticated; - try - {CC2: Don't call Connect if already connected, this could be just a change of user} - if not Connected then begin - inherited Connect; - GetResponse; - // if PosInStrArray(LastCmdResult.Code, [IMAP_OK, IMAP_PREAUTH]) = -1 then begin - {Should have got OK or PREAUTH in the greeting. Happened with some server, - may need further investigation and coding...} - // end; - {CC7: Save FGreetingBanner so the user can use it to determine what type of - server he is connected to...} - if LastCmdResult.Text.Count > 0 then begin - FGreetingBanner := LastCmdResult.Text[0]; - end else begin - FGreetingBanner := ''; - end; - if LastCmdResult.Code = IMAP_PREAUTH then begin - FConnectionState := csAuthenticated; - FCmdCounter := 0; - // RLebeau: check if the greeting includes initial Capabilities, if not then query for them... - if not CheckReplyForCapabilities then begin - Capability; - end; - end else begin - // RLebeau: check if the greeting includes initial Capabilities... - CheckReplyForCapabilities; - end; - end; - if AAutoLogin then begin - Login; - end; - except - Disconnect(False); - raise; - end; - Result := True; -end; - -{$IFDEF WORKAROUND_INLINE_CONSTRUCTORS} -constructor TIdIMAP4.Create(AOwner: TComponent); -begin - inherited Create(AOwner); -end; -{$ENDIF} - -procedure TIdIMAP4.InitComponent; -begin - inherited InitComponent; - FMailBox := TIdMailBox.Create(Self); - //FSASLMechanisms := TIdSASLEntries.Create(Self); - FSASLMechanisms := TIdSASLEntriesIMAP4.Create(Self); - Port := IdPORT_IMAP4; - FLineStruct := TIdIMAPLineStruct.Create; - {$IFDEF HAS_TStringList_CaseSensitive} - TStringList(FCapabilities).CaseSensitive := False; // TODO: move this to TIdExplicitTLSClient.InitComponent() - {$ENDIF} - FMUTF7 := TIdMUTF7.Create; - - //Todo: Not sure which number is appropriate. Should be tested further. - FRegularProtPort := IdPORT_IMAP4; - FImplicitTLSProtPort := IdPORT_IMAP4S; - FExplicitTLSProtPort := IdPORT_IMAP4; - - FMilliSecsToWaitToClearBuffer := IDF_DEFAULT_MS_TO_WAIT_TO_CLEAR_BUFFER; - FCmdCounter := 0; - FConnectionState := csNonAuthenticated; - FRetrieveOnSelect := rsDisabled; - {CC2: FMailBoxSeparator is now detected when a mailbox is selected, following - line is probably redundant, but leave it here as a default just in case.} - FMailBoxSeparator := '/'; {Do not Localize} -end; - -procedure TIdIMAP4.Disconnect(ANotifyPeer: Boolean); -begin - try - inherited Disconnect(ANotifyPeer); - finally - FConnectionState := csNonAuthenticated; - FCapabilities.Clear; - end; -end; - -procedure TIdIMAP4.DisconnectNotifyPeer; -begin - inherited DisconnectNotifyPeer; - //IMPORTANT: Logout must pass 'BYE' as the first - //element of the AExpectedResponses array (the 3rd param in SendCmd - //below), because this flags to GetInternalResponse that this is the - //logout, and it must EXPECT the BYE response - SendCmd(NewCmdCounter, IMAP4Commands[cmdLogout], ['BYE']); {Do not Localize} -end; - -procedure TIdIMAP4.KeepAlive; -begin - //Available in any state. - SendCmd(NewCmdCounter, IMAP4Commands[cmdNoop], []); -end; - -function TIdIMAP4.IsCapabilityListed(ACapability: string):Boolean; -begin - if not FHasCapa then begin - Capability; - end; - Result := IndyIndexOf(TStringList(FCapabilities), ACapability) <> -1; -end; - -function TIdIMAP4.Capability: Boolean; -begin - FHasCapa := Capability(FCapabilities); - Result := FHasCapa; -end; - -function TIdIMAP4.Capability(ASlCapability: TStrings): Boolean; -begin - //Available in any state. - Result := False; - ASlCapability.BeginUpdate; - try - ASlCapability.Clear; - SendCmd(NewCmdCounter, IMAP4Commands[CmdCapability], [IMAP4Commands[CmdCapability]]); - if LastCmdResult.Code = IMAP_OK then begin - if LastCmdResult.Text.Count > 0 then begin - BreakApart(LastCmdResult.Text[0], ' ', ASlCapability); {Do not Localize} - end; - // RLebeau: do not delete the first item anymore! It specifies the IMAP - // version/revision, which is needed to support certain extensions, like - // 'IMAP4rev1'... - { - if ASlCapability.Count > 0 then begin - ASlCapability.Delete(0); - end; - } - Result := True; - end; - finally - ASlCapability.EndUpdate; - end; -end; - -function TIdIMAP4.GetCmdCounter: String; -begin - Result := 'C' + IntToStr(FCmdCounter); {Do not Localize} -end; - -function TIdIMAP4.GetNewCmdCounter: String; -begin - Inc(FCmdCounter); - Result := 'C' + IntToStr(FCmdCounter); {Do not Localize} -end; - -destructor TIdIMAP4.Destroy; -begin - {Disconnect before we die} - { Note we have to pass false to an overloaded method or an exception is - raised in the destructor. That can cause weirdness in the IDE. } - if Connected then begin - Disconnect(False); - end; - FreeAndNil(FMailBox); - FreeAndNil(FSASLMechanisms); - FreeAndNil(FLineStruct); - FreeAndNil(FMUTF7); - inherited Destroy; -end; - -function TIdIMAP4.SelectMailBox(const AMBName: String): Boolean; -begin - Result := False; - CheckConnectionState([csAuthenticated, csSelected]); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdSelect] + ' "' + DoMUTFEncode(AMBName) + '"', {Do not Localize} - ['FLAGS', 'OK', 'EXISTS', 'RECENT', '[READ-WRITE]', '[ALERT]']); {Do not Localize} - if LastCmdResult.Code = IMAP_OK then begin - //Put the parse in the IMAP Class and send the MB; - ParseSelectResult(FMailBox, LastCmdResult.Text); - FMailBox.Name := AMBName; - FConnectionState := csSelected; - case RetrieveOnSelect of - rsHeaders: RetrieveAllHeaders(FMailBox.MessageList); - rsMessages: RetrieveAllMsgs(FMailBox.MessageList); - end; - Result := True; - end; -end; - -function TIdIMAP4.ExamineMailBox(const AMBName: String; AMB: TIdMailBox): Boolean; -begin - Result := False; - CheckConnectionState([csAuthenticated, csSelected]); - //TO DO: Check that Examine's expected responses really are STATUS, FLAGS and OK... - SendCmd(NewCmdCounter, - IMAP4Commands[cmdExamine] + ' "' + DoMUTFEncode(AMBName) + '"', {Do not Localize} - ['STATUS', 'FLAGS', 'OK', 'EXISTS', 'RECENT', '[READ-WRITE]', '[ALERT]']); {Do not Localize} - if LastCmdResult.Code = IMAP_OK then begin - ParseSelectResult(AMB, LastCmdResult.Text); - AMB.Name := AMBName; - FConnectionState := csSelected; - Result := True; - end; -end; - -function TIdIMAP4.CloseMailBox: Boolean; -begin - Result := False; - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, IMAP4Commands[cmdClose], []); - if LastCmdResult.Code = IMAP_OK then begin - MailBox.Clear; - FConnectionState := csAuthenticated; - Result := True; - end; -end; - -function TIdIMAP4.CreateMailBox(const AMBName: String): Boolean; -begin - {CC5: Recode to return False if NO returned rather than throwing an exception...} - Result := False; - CheckConnectionState([csAuthenticated, csSelected]); - {CC5: The NO response is typically due to Permission Denied} - SendCmd(NewCmdCounter, IMAP4Commands[cmdCreate] + ' "' + DoMUTFEncode(AMBName) + '"', []); {Do not Localize} - if LastCmdResult.Code = IMAP_OK then begin - Result := True; - end; -end; - -function TIdIMAP4.DeleteMailBox(const AMBName: String): Boolean; -begin - {CC5: Recode to return False if NO returned rather than throwing an exception...} - Result := False; - CheckConnectionState([csAuthenticated, csSelected]); - {CC5: The NO response is typically due to Permission Denied} - SendCmd(NewCmdCounter, IMAP4Commands[cmdDelete] + ' "' + DoMUTFEncode(AMBName) + '"', []); {Do not Localize} - if LastCmdResult.Code = IMAP_OK then begin - Result := True; - end; -end; - -function TIdIMAP4.RenameMailBox(const AOldMBName, ANewMBName: String): Boolean; -begin - {CC5: Recode to return False if NO returned rather than throwing an exception...} - Result := False; - CheckConnectionState([csAuthenticated, csSelected]); - {CC5: The NO response is typically due to Permission Denied} - SendCmd(NewCmdCounter, - IMAP4Commands[cmdRename] + ' "' + DoMUTFEncode(AOldMBName) + '" "' + DoMUTFEncode(ANewMBName) + '"', {Do not Localize} - []); - if LastCmdResult.Code = IMAP_OK then begin - Result := True; - end; -end; - -function TIdIMAP4.StatusMailBox(const AMBName: String; AMB: TIdMailBox): Boolean; - {CC2: It is pointless calling StatusMailBox with AStatusDataItems set to [] - because you are asking the IMAP server to update none of the status flags. - Instead, if called with no AStatusDataItems specified, use the standard flags - returned by SelectMailBox, which allows the user to easily check if the mailbox - has changed. Overload the functions, since AStatusDataItems cannot be set - to nil.} -var - AStatusDataItems: array[1..5] of TIdIMAP4StatusDataItem; -begin - AStatusDataItems[1] := mdMessages; - AStatusDataItems[2] := mdRecent; - AStatusDataItems[3] := mdUIDNext; - AStatusDataItems[4] := mdUIDValidity; - AStatusDataItems[5] := mdUnseen; - Result := StatusMailBox(AMBName, AMB, AStatusDataItems); -end; - -function TIdIMAP4.StatusMailBox(const AMBName: String; AMB: TIdMailBox; const AStatusDataItems: array of TIdIMAP4StatusDataItem): Boolean; -var - LDataItems : string; - Ln : Integer; -begin - Result := False; - CheckConnectionState([csAuthenticated, csSelected]); - for Ln := Low(AStatusDataItems) to High(AStatusDataItems) do begin - case AStatusDataItems[Ln] of - mdMessages: LDataItems := LDataItems + IMAP4StatusDataItem[mdMessages] + ' '; {Do not Localize} - mdRecent: LDataItems := LDataItems + IMAP4StatusDataItem[mdRecent] + ' '; {Do not Localize} - mdUIDNext: LDataItems := LDataItems + IMAP4StatusDataItem[mdUIDNext] + ' '; {Do not Localize} - mdUIDValidity: LDataItems := LDataItems + IMAP4StatusDataItem[mdUIDValidity] + ' '; {Do not Localize} - mdUnseen: LDataItems := LDataItems + IMAP4StatusDataItem[mdUnseen] + ' '; {Do not Localize} - end; - end; - SendCmd(NewCmdCounter, - IMAP4Commands[cmdStatus] + ' "' + DoMUTFEncode(AMBName) + '" (' + Trim(LDataItems) + ')', {Do not Localize} - [IMAP4Commands[cmdStatus]]); - if LastCmdResult.Code = IMAP_OK then begin - ParseStatusResult(AMB, LastCmdResult.Text); - Result := True; - end; -end; - -function TIdIMAP4.CheckMailBox: Boolean; -begin - Result := False; - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, IMAP4Commands[cmdCheck], []); - if LastCmdResult.Code = IMAP_OK then begin - Result := True; - end; -end; - -function TIdIMAP4.ExpungeMailBox: Boolean; -begin - Result := False; - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, IMAP4Commands[cmdExpunge], []); - if LastCmdResult.Code = IMAP_OK then begin - ParseExpungeResult(FMailBox, LastCmdResult.Text); - Result := True; - end; -end; - -//This function is needed because when using the regular DateToStr with dd/MMM/yyyy -//(which is the IMAP needed convension) may give the month as the local language -//three letter month instead of the English month needed. -function DateToIMAPDateStr (const ADate: TDateTime): String; -var - LDay, LMonth, LYear : Word; -begin - {Do not use the global settings from the system unit here because: - 1) It might not be thread safe - 2) Changing the settings could create problems for a user who's local date conventions - are diffrent than dd-mm-yyyy. Some people prefer mm-dd-yyy. Don't mess with a user's display settings. - 3) Using the display settings for dates may not always work as expected if a user - changes their settings at a time between whn you do it but before the date is formatted. - } - DecodeDate(ADate, LYear, LMonth, LDay); - Result := IndyFormat('%.2d-%s-%.4d', [LDay, UpperCase(monthnames[LMonth]), LYear]); {Do not Localize} -end; - -function TIdIMAP4.InternalSearchMailBox(const ASearchInfo: array of TIdIMAP4SearchRec; - AUseUID: Boolean; const ACharSet: string): Boolean; -var - LCmd: String; - Ln : Integer; - LTextBuf: TIdBytes; - LCharSet: string; - LEncoding: IIdTextEncoding; - LLiteral: string; - LCanUseNonSyncLiteral, LNonSyncLiteralIsLimited, LUseNonSyncLiteral: Boolean; - LUseUTF8QuotedString: Boolean; - - function RequiresEncoding(const S: String): Boolean; - var - I: Integer; - begin - Result := False; - for I := 1 to Length(S) do begin - if Ord(S[I]) > $7F then begin - Result := True; - Exit; - end; - end; - end; - - function IsCharsetNeeded: Boolean; - var - I : Integer; - begin - Result := False; - for I := Low(ASearchInfo) to High(ASearchInfo) do begin - case ASearchInfo[I].SearchKey of - skBcc, - skBody, - skCc, - skFrom, - skHeader, - skSubject, - skText, - skTo, - skGmailRaw, - skGmailMsgID, - skGmailThreadID, - skGmailLabels: - if RequiresEncoding(ASearchInfo[I].Text) then begin - Result := True; - Exit; - end; - end; - end; - end; - -begin - Result := False; - LTextBuf := nil; // keep the compiler happy - CheckConnectionState(csSelected); - - LCmd := NewCmdCounter + ' '; {Do not Localize} - if AUseUID then begin - LCmd := LCmd + IMAP4Commands[cmdUID] + ' '; {Do not Localize} - end; - LCmd := LCmd + IMAP4Commands[cmdSearch]; - if IsCharsetNeeded then begin - LNonSyncLiteralIsLimited := IsCapabilityListed('LITERAL-'); {Do not localize} - LCanUseNonSyncLiteral := LNonSyncLiteralIsLimited or - IsCapabilityListed('LITERAL+'); {Do not localize} - LUseUTF8QuotedString := IsCapabilityListed('UTF8=ACCEPT') or {Do not localize} - IsCapabilityListed('UTF8=ONLY') or {Do not localize} - IsCapabilityListed('UTF8=ALL'); {Do not localize} - if LUseUTF8QuotedString then begin - LCharSet := 'UTF-8'; {Do not Localize} - end else begin - LCharSet := Trim(ACharSet); - if LCharSet = '' then begin - LCharSet := 'UTF-8'; {Do not Localize} - end; - end; - LCmd := LCmd + ' CHARSET ' + LCharSet; {Do not localize} - LEncoding := CharsetToEncoding(LCharSet); - end else begin - // keep the compiler happy... - LNonSyncLiteralIsLimited := False; - LCanUseNonSyncLiteral := False; - LUseUTF8QuotedString := False; - end; - - {CC3: Catch "Connection reset by peer"...} - try - //Remove anything that may be unprocessed from a previous (probably failed) command... - repeat - IOHandler.InputBuffer.Clear; - until not IOHandler.CheckForDataOnSource(MilliSecsToWaitToClearBuffer); - CheckConnected; - //IMAP.PrepareCmd(LCmd); - - // now encode the search values. Most values are ASCII and do not need - // special encoding. For text values that do need to be encoded, IMAP - // string literals have to be used in order to support 8-bit octets in - // charset encoded payloads... - for Ln := Low(ASearchInfo) to High(ASearchInfo) do begin - case ASearchInfo[Ln].SearchKey of - skAll, - skAnswered, - skDeleted, - skDraft, - skFlagged, - skNew, - skNot, - skOld, - skOr, - skRecent, - skSeen, - skUnanswered, - skUndeleted, - skUndraft, - skUnflagged, - skUnKeyWord, - skUnseen: - LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey]; {Do not Localize} - - skHeader: - begin - // TODO: support RFC 5738 to allow for UTF-8 encoded quoted strings - if not RequiresEncoding(ASearchInfo[Ln].Text) then begin - LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + ASearchInfo[Ln].FieldName + ' ' + IMAPQuotedStr(ASearchInfo[Ln].Text); {Do not Localize} - end else - begin - if LUseUTF8QuotedString then begin - LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + ASearchInfo[Ln].FieldName + ' *'; {Do not Localize} - IOHandler.Write(LCmd); - IOHandler.Write(IMAPQuotedStr(ASearchInfo[Ln].Text), LEncoding{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_OSDefault{$ENDIF}); - end else - begin - LTextBuf := ToBytes(ASearchInfo[Ln].Text, LEncoding{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_OSDefault{$ENDIF}); - LUseNonSyncLiteral := LCanUseNonSyncLiteral and ((not LNonSyncLiteralIsLimited) or (Length(LTextBuf) <= 4096)); - if LUseNonSyncLiteral then begin - LLiteral := '{' + IntToStr(Length(LTextBuf)) + '+}'; {Do not Localize} - end else begin - LLiteral := '{' + IntToStr(Length(LTextBuf)) + '}'; {Do not Localize} - end; - LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + ASearchInfo[Ln].FieldName + ' ' + LLiteral; {Do not Localize} - IOHandler.WriteLn(LCmd); - if not LUseNonSyncLiteral then begin - if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdSearch], IMAP4Commands[cmdUID]], False) <> IMAP_CONT then begin - RaiseExceptionForLastCmdResult; - end; - end; - IOHandler.Write(LTextBuf); - end; - LTextBuf := nil; - LCmd := ''; - end; - end; - - skKeyword, - skUID: - LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + ASearchInfo[Ln].Text; {Do not Localize} - - skBcc, - skBody, - skCc, - skFrom, - skSubject, - skText, - skTo, - skGmailRaw, - skGmailMsgID, - skGmailThreadID, - skGmailLabels: - begin - // TODO: support RFC 5738 to allow for UTF-8 encoded quoted strings - if not RequiresEncoding(ASearchInfo[Ln].Text) then begin - LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + IMAPQuotedStr(ASearchInfo[Ln].Text); {Do not Localize} - end else - begin - if LUseUTF8QuotedString then begin - LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' *'; {Do not Localize} - IOHandler.Write(LCmd); - IOHandler.Write(IMAPQuotedStr(ASearchInfo[Ln].Text), LEncoding{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_OSDefault{$ENDIF}); - end else - begin - LTextBuf := ToBytes(ASearchInfo[Ln].Text, LEncoding{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_OSDefault{$ENDIF}); - LUseNonSyncLiteral := LCanUseNonSyncLiteral and ((not LNonSyncLiteralIsLimited) or (Length(LTextBuf) <= 4096)); - if LUseNonSyncLiteral then begin - LLiteral := '{' + IntToStr(Length(LTextBuf)) + '+}'; {Do not Localize} - end else begin - LLiteral := '{' + IntToStr(Length(LTextBuf)) + '}'; {Do not Localize} - end; - LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + LLiteral; {Do not Localize} - IOHandler.WriteLn(LCmd); - if not LUseNonSyncLiteral then begin - if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdSearch], IMAP4Commands[cmdUID]], False) <> IMAP_CONT then begin - RaiseExceptionForLastCmdResult; - end; - end; - IOHandler.Write(LTextBuf); - end; - LTextBuf := nil; - LCmd := ''; - end; - end; - - skBefore, - skOn, - skSentBefore, - skSentOn, - skSentSince, - skSince: - LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + DateToIMAPDateStr(ASearchInfo[Ln].Date); {Do not Localize} - - skLarger, - skSmaller: - LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + IntToStr(ASearchInfo[Ln].Size); {Do not Localize} - end; - end; - - if LCmd <> '' then begin - IOHandler.Write(LCmd); - end; - - // After we send the last of the data, we need to send an EXTRA CRLF to terminates the SEARCH command... - IOHandler.WriteLn; - - if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdSearch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin - ParseSearchResult(FMailBox, LastCmdResult.Text); - Result := True; - end; - except - on E: EIdSocketError do begin - if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin - FConnectionState := csUnexpectedlyDisconnected; - end; - raise; - end; - end; -end; - -function TIdIMAP4.SearchMailBox(const ASearchInfo: array of TIdIMAP4SearchRec; - const ACharSet: string = ''): Boolean; -begin - Result := InternalSearchMailBox(ASearchInfo, False, ACharSet); -end; - -function TIdIMAP4.UIDSearchMailBox(const ASearchInfo: array of TIdIMAP4SearchRec; - const ACharSet: string = '') : Boolean; -begin - Result := InternalSearchMailBox(ASearchInfo, True, ACharSet); -end; - -function TIdIMAP4.SubscribeMailBox(const AMBName: String): Boolean; -begin - Result := False; - CheckConnectionState([csAuthenticated, csSelected]); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdSubscribe] + ' "' + DoMUTFEncode(AMBName) + '"', {Do not Localize} - []); - if LastCmdResult.Code = IMAP_OK then begin - Result := True; - end; -end; - -function TIdIMAP4.UnsubscribeMailBox(const AMBName: String): Boolean; -begin - Result := False; - CheckConnectionState([csAuthenticated, csSelected]); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdUnsubscribe] + ' "' + DoMUTFEncode(AMBName) + '"', {Do not Localize} - []); - if LastCmdResult.Code = IMAP_OK then begin - Result := True; - end; -end; - -function TIdIMAP4.ListMailBoxes(AMailBoxList: TStrings): Boolean; -begin - Result := False; - {CC2: This is one of the few cases where the server can return only "OK completed" - meaning that the user has no mailboxes.} - CheckConnectionState([csAuthenticated, csSelected]); - SendCmd(NewCmdCounter, IMAP4Commands[cmdList] + ' "" *', [IMAP4Commands[cmdList]]); {Do not Localize} - if LastCmdResult.Code = IMAP_OK then begin - ParseListResult(AMailBoxList, LastCmdResult.Text); - Result := True; - end; -end; - -function TIdIMAP4.ListInferiorMailBoxes(AMailBoxList, AInferiorMailBoxList: TStrings): Boolean; -var - Ln : Integer; - LAuxMailBoxList : TStringList; -begin - Result := False; - {CC2: This is one of the few cases where the server can return only "OK completed" - meaning that the user has no inferior mailboxes.} - CheckConnectionState([csAuthenticated, csSelected]); - if AMailBoxList = nil then begin - SendCmd(NewCmdCounter, IMAP4Commands[cmdList] + ' "" %', [IMAP4Commands[cmdList]]); {Do not Localize} - if LastCmdResult.Code = IMAP_OK then begin - ParseListResult(AInferiorMailBoxList, LastCmdResult.Text); - //The INBOX mailbox is added because I think it always has to exist - //in an IMAP4 account (default) but it does not list it in this command. - Result := True; - end; - end else begin - LAuxMailBoxList := TStringList.Create; - try - AInferiorMailBoxList.Clear; - for Ln := 0 to AMailBoxList.Count - 1 do begin - SendCmd(NewCmdCounter, - IMAP4Commands[cmdList] + ' "" "' + DoMUTFEncode(AMailBoxList[Ln]) + FMailBoxSeparator + '%"', {Do not Localize} - [IMAP4Commands[cmdList]]); - if LastCmdResult.Code = IMAP_OK then begin - ParseListResult(LAuxMailBoxList, LastCmdResult.Text); - AInferiorMailBoxList.AddStrings(LAuxMailBoxList); - Result := True; - end else begin - Break; - end; - end; - finally - FreeAndNil(LAuxMailBoxList); - end; - end; -end; - -function TIdIMAP4.ListSubscribedMailBoxes(AMailBoxList: TStrings): Boolean; -begin - {CC2: This is one of the few cases where the server can return only "OK completed" - meaning that the user has no subscribed mailboxes.} - Result := False; - CheckConnectionState([csAuthenticated, csSelected]); - SendCmd(NewCmdCounter, IMAP4Commands[cmdLSub] + ' "" *', [IMAP4Commands[cmdList], IMAP4Commands[cmdLSub]]); {Do not Localize} - if LastCmdResult.Code = IMAP_OK then begin - // ds - fixed bug # 506026 - ParseLSubResult(AMailBoxList, LastCmdResult.Text); - Result := True; - end; -end; - -function TIdIMAP4.StoreFlags(const AMsgNumList: array of UInt32; - const AStoreMethod: TIdIMAP4StoreDataItem; const AFlags: TIdMessageFlagsSet): Boolean; -begin - Result := StoreValue(AMsgNumList, AStoreMethod, IMAP4FetchDataItem[fdFlags], MessageFlagSetToStr(AFlags)); -end; - -function TIdIMAP4.StoreValue(const AMsgNumList: array of UInt32; - const AStoreMethod: TIdIMAP4StoreDataItem; const AField, AValue: String): Boolean; -var - LDataItem, - LMsgSet: string; -begin - Result := False; - if Length(AMsgNumList) > 0 then begin - LMsgSet := ArrayToNumberStr(AMsgNumList); - case AStoreMethod of - sdReplace, sdReplaceSilent: - LDataItem := AField+'.SILENT'; {Do not Localize} - sdAdd, sdAddSilent: - LDataItem := '+'+AField+'.SILENT'; {Do not Localize} - sdRemove, sdRemoveSilent: - LDataItem := '-'+AField+'.SILENT'; {Do not Localize} - else - Exit; - end; - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdStore] + ' ' + LMsgSet + ' ' + LDataItem + ' (' + AValue + ')', {Do not Localize} - []); - if LastCmdResult.Code = IMAP_OK then begin - Result := True; - end; - end; -end; - -function TIdIMAP4.UIDStoreFlags(const AMsgUID: String; - const AStoreMethod: TIdIMAP4StoreDataItem; const AFlags: TIdMessageFlagsSet): Boolean; -begin - Result := UIDStoreValue(AMsgUID, AStoreMethod, IMAP4FetchDataItem[fdFlags], MessageFlagSetToStr(AFlags)); -end; - -function TIdIMAP4.UIDStoreFlags(const AMsgUIDList: array of String; - const AStoreMethod: TIdIMAP4StoreDataItem; const AFlags: TIdMessageFlagsSet): Boolean; -begin - Result := UIDStoreValue(AMsgUIDList, AStoreMethod, IMAP4FetchDataItem[fdFlags], MessageFlagSetToStr(AFlags)); -end; - -function TIdIMAP4.UIDStoreValue(const AMsgUID: String; - const AStoreMethod: TIdIMAP4StoreDataItem; const AField, AValue: string): Boolean; -var - LDataItem : String; -begin - Result := False; - IsUIDValid(AMsgUID); - case AStoreMethod of - sdReplace, sdReplaceSilent: - LDataItem := AField+'.SILENT'; {Do not Localize} - sdAdd, sdAddSilent: - LDataItem := '+'+AField+'.SILENT'; {Do not localize} - sdRemove, sdRemoveSilent: - LDataItem := '-'+AField+'.SILENT'; {Do not Localize} - else - Exit; - end; - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdStore] + ' ' + AMsgUID + ' ' + LDataItem + ' (' + AValue + ')', {Do not Localize} - []); - if LastCmdResult.Code = IMAP_OK then begin - Result := True; - end; -end; - -function TIdIMAP4.UIDStoreValue(const AMsgUIDList: array of String; - const AStoreMethod: TIdIMAP4StoreDataItem; const AField, AValue: String): Boolean; -var - LDataItem, - LMsgSet : String; - LN: integer; -begin - Result := False; - LMsgSet := ''; - for LN := 0 to Length(AMsgUIDList) -1 do begin - IsUIDValid(AMsgUIDList[LN]); - if LN > 0 then begin - LMsgSet := LMsgSet + ','; {Do not Localize} - end; - LMsgSet := LMsgSet+AMsgUIDList[LN]; - end; - case AStoreMethod of - sdReplace, sdReplaceSilent: - LDataItem := AField+'.SILENT'; {Do not Localize} - sdAdd, sdAddSilent: - LDataItem := '+'+AField+'.SILENT'; {Do not Localize} - sdRemove, sdRemoveSilent: - LDataItem := '-'+AField+'.SILENT'; {Do not Localize} - else - Exit; - end; - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdStore] + ' ' + LMsgSet + ' ' + LDataItem + ' (' + AValue + ')', {Do not Localize} - []); - if LastCmdResult.Code = IMAP_OK then begin - Result := True; - end; -end; - -function TIdIMAP4.CopyMsgs(const AMsgNumList: array of UInt32; const AMBName: String): Boolean; -var - LMsgSet : String; -begin - Result := False; - if Length(AMsgNumList) > 0 then begin - LMsgSet := ArrayToNumberStr ( AMsgNumList ); - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, IMAP4Commands[cmdCopy] + ' ' + LMsgSet + ' "' + DoMUTFEncode(AMBName) + '"', []); {Do not Localize} - if LastCmdResult.Code = IMAP_OK then begin - Result := True; - end; - end; -end; - -function TIdIMAP4.UIDCopyMsgs(const AMsgUIDList: TStrings; const AMBName: String): Boolean; -var - LCmd : String; - LN: integer; -begin - Result := False; - if AMsgUIDList.Count > 0 then begin - LCmd := IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdCopy] + ' '; {Do not Localize} - for LN := 0 to AMsgUIDList.Count-1 do begin - IsUIDValid(AMsgUIDList.Strings[LN]); - if LN = 0 then begin - LCmd := LCmd + AMsgUIDList.Strings[LN]; - end else begin - LCmd := LCmd + ',' + AMsgUIDList.Strings[LN]; {Do not Localize} - end; - end; - LCmd := LCmd + ' "' + DoMUTFEncode(AMBName) + '"'; {Do not Localize} - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, LCmd, []); - if LastCmdResult.Code = IMAP_OK then begin - Result := True; - end; - end; -end; - -function TIdIMAP4.CopyMsg(const AMsgNum: UInt32; const AMBName: String): Boolean; -//Copies a message from the current selected mailbox to the specified mailbox. -begin - Result := False; - IsNumberValid(AMsgNum); - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, IMAP4Commands[cmdCopy] + ' ' + IntToStr(Int64(AMsgNum)) + ' "' + DoMUTFEncode(AMBName) + '"', []); {Do not Localize} - if LastCmdResult.Code = IMAP_OK then begin - Result := True; - end; -end; - -function TIdIMAP4.UIDCopyMsg(const AMsgUID: String; const AMBName: String): Boolean; -//Copies a message from the current selected mailbox to the specified mailbox. -begin - Result := False; - IsUIDValid(AMsgUID); - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdCopy] + ' ' + AMsgUID + ' "' + DoMUTFEncode(AMBName) + '"', []); {Do not Localize} - if LastCmdResult.Code = IMAP_OK then begin - Result := True; - end; -end; - - -function TIdIMAP4.AppendMsg(const AMBName: String; AMsg: TIdMessage; const AFlags: TIdMessageFlagsSet = []; - const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; -begin - Result := AppendMsg(AMBName, AMsg, nil, AFlags, AInternalDateTimeGMT); -end; - -function TIdIMAP4.AppendMsg(const AMBName: String; AMsg: TIdMessage; AAlternativeHeaders: TIdHeaderList; const AFlags: TIdMessageFlagsSet = []; - const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; -var - LFlags, - LMsgLiteral, LDateTime: String; - LUseNonSyncLiteral: Boolean; - Ln: Integer; - LCmd: string; - LLength: TIdStreamSize; - LHeadersToSend, LCopiedHeaders: TIdHeaderList; - LHeadersAsString: string; - LHeadersAsBytes: TIdBytes; - LMimeBoundary: string; - LStream: TStream; - LHelper: TIdIMAP4WorkHelper; -begin - Result := False; - LHeadersasBytes := nil; // keep the compiler happy - - CheckConnectionState([csAuthenticated, csSelected]); - if Length(AMBName) <> 0 then begin - LFlags := MessageFlagSetToStr(AFlags); - if LFlags <> '' then begin {Do not Localize} - LFlags := '(' + LFlags + ')'; {Do not Localize} - end; - if AInternalDateTimeGMT <> 0.0 then begin - // even though flags are optional, some servers, such as GMail, will - // fail to parse the command correctly if no flags are specified in - // front of the internal date... - if LFlags = '' then begin - LFlags := '()'; // TODO: should 'NIL' be used instead? {Do not Localize} - end; - LDateTime := '"' + DateTimeGMTToImapStr(AInternalDateTimeGMT) + '"'; {do not localize} - end; - - {CC8: In Indy 10, we want to support attachments (previous versions did - not). The problem is that we have to know the size of the message - in advance of sending it for the IMAP APPEND command. - The problem is that there is no way of calculating the size of a - message without generating the encoded message. Therefore, write the - message out to a temporary stream, and then get the size of the data, - which with a bit of adjustment, will give us the size of the message - we will send. - The "adjustment" is necessary because SaveToStream generates it's own - headers, which will be different to both the ones in AMsg and - AAlternativeHeaders, in the Date header, if nothing else.} - - LStream := TMemoryStream.Create; - try - {RLebeau 04/02/2014: if the user passed in AMsg.LastGeneratedHeaders - or AMsg.Headers as AAlternativeHeaders, then assume the user wants to - use the headers that existed prior to AMsg being saved below, which - may create new header values...} - - LCopiedHeaders := nil; - try - if (AAlternativeHeaders <> nil) and - ((AAlternativeHeaders = AMsg.LastGeneratedHeaders) or (AAlternativeHeaders = AMsg.Headers)) then - begin - LCopiedHeaders := TIdHeaderList.Create(QuoteRFC822); - LCopiedHeaders.Assign(AAlternativeHeaders); - end; - - {RLebeau 12/09/2012: this is a workaround to a design limitation in - TIdMessage.SaveToStream(). It always outputs the stream data in an - escaped format using SMTP dot transparency, but that is not used in - IMAP! Until this design is corrected, we have to use a workaround - for now. This logic is copied from TIdMessage.SaveToSteam() and - slightly tweaked...} - - //AMsg.SaveToStream(LStream); - {$IFDEF HAS_CLASS_HELPER} - AMsg.SaveToStream(LStream, False, False); - {$ELSE} - TIdMessageHelper_SaveToStream(AMsg, LStream, False, False); - {$ENDIF} - - LStream.Position := 0; - {We are better off making up the headers as a string first rather than predicting - its length. Slightly wasteful of memory, but it will not take up much.} - LHeadersAsString := ''; - - {Make sure the headers we end up using have the correct MIME boundary actually - used in the message being saved...} - if AMsg.NoEncode then begin - LMimeBoundary := AMsg.Headers.Params['Content-Type', 'boundary']; {do not localize} - end else begin - LMimeBoundary := AMsg.LastGeneratedHeaders.Params['Content-Type', 'boundary']; {do not localize} - end; - if (LCopiedHeaders = nil) and (AAlternativeHeaders <> nil) then begin - if AAlternativeHeaders.Params['Content-Type', 'boundary'] <> LMimeBoundary then {do not localize} - begin - LCopiedHeaders := TIdHeaderList.Create(QuoteRFC822); - LCopiedHeaders.Assign(AAlternativeHeaders); - end; - end; - - // TODO: if AInternalDateTimeGMT is not 0.0, should we adjust the 'Date' header of the sent email to match? - - if LCopiedHeaders <> nil then begin - {Use the copied headers that the user has passed to us, adjusting the MIME boundary...} - LCopiedHeaders.Params['Content-Type', 'boundary'] := LMimeBoundary; {do not localize} - LHeadersToSend := LCopiedHeaders; - end - else if AAlternativeHeaders <> nil then begin - {Use the headers that the user has passed to us...} - LHeadersToSend := AAlternativeHeaders; - end - else if AMsg.NoEncode then begin - {Use the headers that are in the message AMsg...} - LHeadersToSend := AMsg.Headers; - end else begin - {Use the headers that SaveToStream() generated...} - LHeadersToSend := AMsg.LastGeneratedHeaders; - end; - // not using LHeadersToSend.Text because it uses platform-specific line breaks - for Ln := 0 to Pred(LHeadersToSend.Count) do begin - LHeadersAsString := LHeadersAsString + LHeadersToSend[Ln] + EOL; - end; - finally - LCopiedHeaders.Free; - end; - - LHeadersAsBytes := ToBytes(LHeadersAsString + EOL); - LHeadersAsString := ''; - - {Get the size of the headers we are sending...} - repeat until Length(ReadLnFromStream(LStream)) = 0; - {We have to subtract the size of the headers in the file and - add back the size of the headers we are to use - to get the size of the message we are going to send...} - LLength := Length(LHeadersAsBytes) + (LStream.Size - LStream.Position); - - // TODO: check the server's APPENDLIMIT capability (RFC 7889) to see if - // LLength is too large, and if so then we can bail out here... - - if IsCapabilityListed('LITERAL-') then begin {Do not Localize} - LUseNonSyncLiteral := LLength <= 4096; - end else begin - LUseNonSyncLiteral := IsCapabilityListed('LITERAL+'); {Do not Localize} - end; - - if LUseNonSyncLiteral then begin - LMsgLiteral := '{' + IntToStr ( LLength ) + '+}'; {Do not Localize} - end else begin - LMsgLiteral := '{' + IntToStr ( LLength ) + '}'; {Do not Localize} - end; - {CC: The original code sent the APPEND command first, then followed it with the - message. Maybe this worked with some server, but most send a - response like "+ Send the additional command..." between the two, - which was not expected by the client and caused an exception.} - - //CC: Added double quotes around mailbox name, else mailbox names with spaces will cause server parsing error - LCmd := IMAP4Commands[cmdAppend] + ' "' + DoMUTFEncode(AMBName) + '" '; {Do not Localize} - if Length(LFlags) <> 0 then begin - LCmd := LCmd + LFlags + ' '; {Do not Localize} - end; - if Length(LDateTime) <> 0 then begin - LCmd := LCmd + LDateTime + ' '; {Do not Localize} - end; - LCmd := LCmd + LMsgLiteral; {Do not Localize} - - {CC3: Catch "Connection reset by peer"...} - try - if LUseNonSyncLiteral then begin - {Send the APPEND command and the message immediately, no + response needed...} - IOHandler.WriteLn(NewCmdCounter + ' ' + LCmd); - end else begin - {Try sending the APPEND command, get the + response, then send the message...} - SendCmd(NewCmdCounter, LCmd, []); - if LastCmdResult.Code <> IMAP_CONT then begin - Exit; - end; - end; - - LHelper := TIdIMAP4WorkHelper.Create(Self); - try - IOHandler.Write(LHeadersAsBytes); - {RLebeau: passing -1 to TIdIOHandler.Write(TStream) will send the - rest of the stream starting at its current Position...} - IOHandler.Write(LStream, -1, False); - finally - FreeAndNil(LHelper); - end; - - {WARNING: After we send the message (which should be exactly - LLength bytes long), we need to send an EXTRA CRLF which is in - addition to the count in LLength, because this CRLF terminates the - APPEND command...} - IOHandler.WriteLn; - if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdAppend]], False) = IMAP_OK then begin - Result := True; - end; - except - on E: EIdSocketError do begin - if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin - FConnectionState := csUnexpectedlyDisconnected; - end; - raise; - end; - end; - finally - LStream.Free; - end; - end; -end; - -function TIdIMAP4.AppendMsgNoEncodeFromFile(const AMBName: String; ASourceFile: string; const AFlags: TIdMessageFlagsSet = []; - const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; -var - LSourceStream: TIdReadFileExclusiveStream; -begin - LSourceStream := TIdReadFileExclusiveStream.Create(ASourceFile); - try - Result := AppendMsgNoEncodeFromStream(AMBName, LSourceStream, AFlags, AInternalDateTimeGMT); - finally - FreeAndNil(LSourceStream); - end; -end; - -function TIdIMAP4.AppendMsgNoEncodeFromStream(const AMBName: String; AStream: TStream; const AFlags: TIdMessageFlagsSet = []; - const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; -const - cTerminator: array[0..4] of Byte = (13, 10, Ord('.'), 13, 10); -var - LFlags, LDateTime, LMsgLiteral: String; - LUseNonSyncLiteral: Boolean; - I: Integer; - LFound: Boolean; - LCmd: string; - LLength: TIdStreamSize; - LTempStream: TMemoryStream; - LHelper: TIdIMAP4WorkHelper; - LBuf: TIdBytes; -begin - Result := False; - CheckConnectionState([csAuthenticated, csSelected]); - if Length(AMBName) <> 0 then begin - LFlags := MessageFlagSetToStr(AFlags); - if LFlags <> '' then begin {Do not Localize} - LFlags := '(' + LFlags + ')'; {Do not Localize} - end; - if AInternalDateTimeGMT <> 0.0 then begin - // even though flags are optional, some servers, such as GMail, will - // fail to parse the command correctly if no flags are specified in - // front of the internal date... - if LFlags = '' then begin - LFlags := '()'; // TODO: should 'NIL' be used instead? {Do not Localize} - end; - LDateTime := '"' + DateTimeGMTToImapStr(AInternalDateTimeGMT) + '"'; {Do not Localize} - end; - LLength := AStream.Size - AStream.Position; - if LLength < 0 then begin - LLength := 0; - end; - - LTempStream := TMemoryStream.Create; - try - //Hunt for CRLF.CRLF, if present then we need to remove it... - - // RLebeau: why? The lines of the message data are not required to be - // dot-prefixed like in SMTP, so why should TIdIMAP care about any - // termination sequences in the file? We are telling the server exactly - // how large the message actually is. What if the message data actually - // contains a valid line with just a dot on it? This code would end up - // truncating the message that is stored on the server... - - SetLength(LBuf, 5); - if LLength > 0 then begin - LTempStream.CopyFrom(AStream, LLength); - LTempStream.Position := 0; - end; - repeat - if TIdStreamHelper.ReadBytes(LTempStream, LBuf, 5) < 5 then begin - Break; - end; - LFound := True; - for I := 0 to 4 do begin - if LBuf[I] <> cTerminator[I] then begin - LFound := False; - Break; - end; - end; - if LFound then begin - LLength := LTempStream.Position-5; - Break; - end; - TIdStreamHelper.Seek(LTempStream, -4, soCurrent); - until False; - - if IsCapabilityListed('LITERAL-') then begin {Do not Localize} - LUseNonSyncLiteral := LLength <= 4096; - end else begin - LUseNonSyncLiteral := IsCapabilityListed('LITERAL+'); {Do not Localize} - end; - - if LUseNonSyncLiteral then begin - LMsgLiteral := '{' + IntToStr(LLength) + '+}'; {Do not Localize} - end else begin - LMsgLiteral := '{' + IntToStr(LLength) + '}'; {Do not Localize} - end; - - {CC: The original code sent the APPEND command first, then followed it with the - message. Maybe this worked with some server, but most send a - response like "+ Send the additional command..." between the two, - which was not expected by the client and caused an exception.} - - //CC: Added double quotes around mailbox name, else mailbox names with spaces will cause server parsing error - LCmd := IMAP4Commands[cmdAppend] + ' "' + DoMUTFEncode(AMBName) + '" '; {Do not Localize} - if Length(LFlags) <> 0 then begin - LCmd := LCmd + LFlags + ' '; {Do not Localize} - end; - if Length(LDateTime) <> 0 then begin - LCmd := LCmd + LDateTime + ' '; {Do not Localize} - end; - LCmd := LCmd + LMsgLiteral; {Do not Localize} - - {CC3: Catch "Connection reset by peer"...} - try - if LUseNonSyncLiteral then begin - {Send the APPEND command and the message immediately, no + response needed...} - IOHandler.WriteLn(NewCmdCounter + ' ' + LCmd); - end else begin - {Try sending the APPEND command, get the + response, then send the message...} - SendCmd(NewCmdCounter, LCmd, []); - if LastCmdResult.Code <> IMAP_CONT then begin - Exit; - end; - end; - - // TODO: if AInternalDateTimeGMT is not 0.0, should we adjust the 'Date' header of the sent email to match? - - LTempStream.Position := 0; - LHelper := TIdIMAP4WorkHelper.Create(Self); - try - IOHandler.Write(LTempStream, LLength); - finally - FreeAndNil(LHelper); - end; - - {WARNING: After we send the message (which should be exactly - LLength bytes long), we need to send an EXTRA CRLF which is in - addition to the count in LLength, because this CRLF terminates the - APPEND command...} - IOHandler.WriteLn; - if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdAppend]], False) = IMAP_OK then begin - Result := True; - end; - except - on E: EIdSocketError do begin - if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin - FConnectionState := csUnexpectedlyDisconnected; - end; - raise; - end; - end; - finally - FreeAndNil(LTempStream); - end; - end; -end; - -function TIdIMAP4.RetrieveEnvelope(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; -begin - Result := InternalRetrieveEnvelope(AMsgNum, AMsg, nil); -end; - -function TIdIMAP4.RetrieveEnvelopeRaw(const AMsgNum: UInt32; ADestList: TStrings): Boolean; -begin - Result := InternalRetrieveEnvelope(AMsgNum, nil, ADestList); -end; - -function TIdIMAP4.InternalRetrieveEnvelope(const AMsgNum: UInt32; AMsg: TIdMessage; ADestList: TStrings): Boolean; -begin - {CC2: Return False if message number is invalid...} - Result := False; - IsNumberValid(AMsgNum); - CheckConnectionState(csSelected); - {Some servers return NO if the requested message number is not present - (e.g. Cyrus), others return OK but no data (CommuniGate).} - SendCmd(NewCmdCounter, - IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdEnvelope] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch]]); - if LastCmdResult.Code = IMAP_OK then begin - if LastCmdResult.Text.Count > 0 then begin - if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdEnvelope]]) then begin - if ADestList <> nil then begin - ADestList.BeginUpdate; - try - ADestList.Clear; - ADestList.Add(FLineStruct.IMAPValue); - finally - ADestList.EndUpdate; - end; - end; - if AMsg <> nil then begin - ParseEnvelopeResult(AMsg, FLineStruct.IMAPValue); - end; - Result := True; - end; - end; - end; -end; - -function TIdIMAP4.UIDRetrieveEnvelope(const AMsgUID: String; AMsg: TIdMessage): Boolean; -begin - Result := UIDInternalRetrieveEnvelope(AMsgUID, AMsg, nil); -end; - -function TIdIMAP4.UIDRetrieveEnvelopeRaw(const AMsgUID: String; ADestList: TStrings): Boolean; -begin - Result := UIDInternalRetrieveEnvelope(AMsgUID, nil, ADestList); -end; - -function TIdIMAP4.UIDInternalRetrieveEnvelope(const AMsgUID: String; AMsg: TIdMessage; ADestList: TStrings): Boolean; -begin - {CC2: Return False if message number is invalid...} - Result := False; - IsUIDValid(AMsgUID); - CheckConnectionState(csSelected); - {Some servers return NO if the requested message number is not present - (e.g. Cyrus), others return OK but no data (CommuniGate).} - SendCmd(NewCmdCounter, - IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + IMAP4FetchDataItem[fdEnvelope] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]]); - if LastCmdResult.Code = IMAP_OK then begin - if LastCmdResult.Text.Count > 0 then begin - if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdEnvelope]]) then begin - if ADestList <> nil then begin - ADestList.BeginUpdate; - try - ADestList.Clear; - ADestList.Add(FLineStruct.IMAPValue); - finally - ADestList.EndUpdate; - end; - end; - if AMsg <> nil then begin - ParseEnvelopeResult(AMsg, FLineStruct.IMAPValue); - end; - Result := True; - end; - end; - end; -end; - -function TIdIMAP4.RetrieveAllEnvelopes(AMsgList: TIdMessageCollection): Boolean; -{NOTE: If AMsgList is empty or does not have enough records, records will be added. -If you pass a non-empty AMsgList, it is assumed the records are in relative record -number sequence: if not, pass in an empty AMsgList and copy the results to your -own AMsgList.} -var - Ln: Integer; - LMsg: TIdMessage; -begin - Result := False; - {CC2: This is one of the few cases where the server can return only "OK completed" - meaning that the user has no envelopes.} - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdFetch] + ' 1:* (' + IMAP4FetchDataItem[fdEnvelope] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch]]); - if LastCmdResult.Code = IMAP_OK then begin - for Ln := 0 to LastCmdResult.Text.Count-1 do begin - if ParseLastCmdResult(LastCmdResult.Text[Ln], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdEnvelope]]) then begin - if LN >= AMsgList.Count then begin - LMsg := AMsgList.Add.Msg; - end else begin - LMsg := AMsgList.Messages[LN]; - end; - ParseEnvelopeResult(LMsg, FLineStruct.IMAPValue); - end; - end; - Result := True; - end; -end; - -function TIdIMAP4.UIDRetrieveAllEnvelopes(AMsgList: TIdMessageCollection): Boolean; -{NOTE: If AMsgList is empty or does not have enough records, records will be added. -If you pass a non-empty AMsgList, it is assumed the records are in relative record -number sequence: if not, pass in an empty AMsgList and copy the results to your -own AMsgList.} -var - Ln: Integer; - LMsg: TIdMessage; -begin - Result := False; - {CC2: This is one of the few cases where the server can return only "OK completed" - meaning that the user has no envelopes.} - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' 1:* (' + IMAP4FetchDataItem[fdEnvelope] + ' ' + IMAP4FetchDataItem[fdFlags] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch]]); - if LastCmdResult.Code = IMAP_OK then begin - for Ln := 0 to LastCmdResult.Text.Count-1 do begin - if ParseLastCmdResult(LastCmdResult.Text[Ln], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdEnvelope]]) then begin - if LN >= AMsgList.Count then begin - LMsg := AMsgList.Add.Msg; - end else begin - LMsg := AMsgList.Messages[LN]; - end; - ParseEnvelopeResult(LMsg, FLineStruct.IMAPValue); - LMsg.UID := FLineStruct.UID; - LMsg.Flags := FLineStruct.Flags; - end; - end; - Result := True; - end; -end; - -function TIdIMAP4.RetrieveText(const AMsgNum: UInt32; var AText: string): Boolean; - //Retrieve a specific individual part of a message -begin - Result := InternalRetrieveText(AMsgNum, AText, False, False, False); -end; - -function TIdIMAP4.RetrieveText2(const AMsgNum: UInt32; var AText: string): Boolean; - //Retrieve a specific individual part of a message -begin - Result := InternalRetrieveText(AMsgNum, AText, False, False, True); -end; - -function TIdIMAP4.RetrieveTextPeek(const AMsgNum: UInt32; var AText: string): Boolean; - {CC3: Added: Retrieve the text part of the message...} -begin - Result := InternalRetrieveText(AMsgNum, AText, False, True, False); -end; - -function TIdIMAP4.RetrieveTextPeek2(const AMsgNum: UInt32; var AText: string): Boolean; - {CC3: Added: Retrieve the text part of the message...} -begin - Result := InternalRetrieveText(AMsgNum, AText, False, True, True); -end; - -function TIdIMAP4.UIDRetrieveText(const AMsgUID: String; var AText: string): Boolean; - {CC3: Added: Retrieve the text part of the message...} -begin - Result := InternalRetrieveText(UIDToUInt32(AMsgUID), AText, True, False, False); -end; - -function TIdIMAP4.UIDRetrieveText2(const AMsgUID: String; var AText: string): Boolean; - {CC3: Added: Retrieve the text part of the message...} -begin - Result := InternalRetrieveText(UIDToUInt32(AMsgUID), AText, True, False, True); -end; - -function TIdIMAP4.UIDRetrieveTextPeek(const AMsgUID: String; var AText: string): Boolean; - {CC3: Added: Retrieve the text part of the message...} -begin - Result := InternalRetrieveText(UIDToUInt32(AMsgUID), AText, True, True, False); -end; - -function TIdIMAP4.UIDRetrieveTextPeek2(const AMsgUID: String; var AText: string): Boolean; - {CC3: Added: Retrieve the text part of the message...} -begin - Result := InternalRetrieveText(UIDToUInt32(AMsgUID), AText, True, True, True); -end; - -function TIdIMAP4.InternalRetrieveText(const AMsgNum: UInt32; var AText: string; - AUseUID: Boolean; AUsePeek: Boolean; AUseFirstPartInsteadOfText: Boolean): Boolean; - {CC3: Added: Retrieve the text part of the message...} -var - LCmd: string; - LParts: TIdImapMessageParts; - LThePart: TIdImapMessagePart; - LCharSet: String; - LContentTransferEncoding: string; - LTextPart: integer; - LTextPartNum: string; - LHelper: TIdIMAP4WorkHelper; - - procedure DoDecode(ADecoderClass: TIdDecoderClass = nil; AStripCRLFs: Boolean = False); - var - LDecoder: TIdDecoder; - LStream: TStream; - LStrippedStream: TStringStream; - LUnstrippedStream: TStringStream; - LEncoding: IIdTextEncoding; - begin - LStream := TMemoryStream.Create; - try - if ADecoderClass <> nil then begin - LDecoder := ADecoderClass.Create(Self); - try - LDecoder.DecodeBegin(LStream); - try - LUnstrippedStream := TStringStream.Create(''); - try - IOHandler.ReadStream(LUnstrippedStream, FLineStruct.ByteCount); //ReadStream uses OnWork, most other methods dont - {This is more complicated than quoted-printable because we - have to strip CRLFs that have been inserted by the MTA to - avoid overly long lines...} - if AStripCRLFs then begin - LStrippedStream := TStringStream.Create(''); - try - StripCRLFs(LUnstrippedStream, LStrippedStream); - LDecoder.Decode(LStrippedStream.DataString); - finally - FreeAndNil(LStrippedStream); - end; - end else begin - LDecoder.Decode(LUnstrippedStream.DataString); - end; - finally - FreeAndNil(LUnstrippedStream); - end; - finally - LDecoder.DecodeEnd; - end; - finally - FreeAndNil(LDecoder); - end; - end else begin - IOHandler.ReadStream(LStream, FLineStruct.ByteCount); //ReadStream uses OnWork, most other methods dont - end; - LStream.Position := 0; - if LCharSet <> '' then begin - LEncoding := CharsetToEncoding(LCharSet); - AText := ReadStringFromStream(LStream, -1, LEncoding{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_OSDefault{$ENDIF}); - end else begin - AText := ReadStringFromStream(LStream, -1, IndyTextEncoding_8Bit{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_8Bit{$ENDIF}); - end; - finally - FreeAndNil(LStream); - end; - end; - -begin - Result := False; - AText := ''; {Do not Localize} - IsNumberValid(AMsgNum); - CheckConnectionState(csSelected); - if AUseFirstPartInsteadOfText then begin - {In this case, we need the body structure to find out what - encoding has been applied to part 1...} - LParts := TIdImapMessageParts.Create(nil); - try - if AUseUID then begin - if not UIDRetrieveStructure(IntToStr(Int64(AMsgNum)), LParts) then begin - Exit; - end; - end else begin - if not RetrieveStructure(AMsgNum, LParts) then begin - Exit; - end; - end; - - {Get the info we want out of LParts...} - {Some emails have their first parts empty, so search for the first non-empty part.} - LTextPartNum := ''; - for LTextPart := 0 to LParts.Count-1 do begin - LThePart := LParts.Items[LTextPart]; - if (LThePart.ImapPartNumber <> '') and (LThePart.FSize <> 0) then begin - LTextPartNum := LThePart.ImapPartNumber; - LCharSet := LThePart.CharSet; - LContentTransferEncoding := LThePart.ContentTransferEncoding; - Break; - end; - end; - - // RLebeau 7/27/2021: for backwards compatibility, if no item was selected above, - // use the last item in the structure. This is likely wrong, but it is what the - // previous logic was doing, so preserving it... - if (LTextPartNum = '') and (LParts.Count > 0) then begin - LThePart := LParts.Items[LParts.Count-1]; - LTextPartNum := LThePart.ImapPartNumber; - LCharSet := LThePart.CharSet; - LContentTransferEncoding := LThePart.ContentTransferEncoding; - end; - - finally - FreeAndNil(LParts); - end; - end else begin - // TODO: detect LCharSet and LContentTransferEncoding... - end; - LCmd := ''; - if AUseUID then begin - LCmd := LCmd + IMAP4Commands[cmdUID] + ' '; {Do not Localize} - end; - LCmd := LCmd + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' ('; {Do not Localize} - if AUsePeek then begin - LCmd := LCmd + IMAP4FetchDataItem[fdBody]+'.PEEK'; {Do not Localize} - end else begin - LCmd := LCmd + IMAP4FetchDataItem[fdBody]; - end; - if not AUseFirstPartInsteadOfText then begin - LCmd := LCmd + '[TEXT])'; {Do not Localize} - end else begin - LCmd := LCmd + '[' + LTextPartNum + '])'; {Do not Localize} - end; - - SendCmd(NewCmdCounter, LCmd, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], True, False); - if LastCmdResult.Code = IMAP_OK then begin - try - {For an invalid request (non-existent part or message), NIL is returned as the size...} - if (LastCmdResult.Text.Count < 1) - or (not ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], - [IMAP4FetchDataItem[fdBody]+'[TEXT]' , IMAP4FetchDataItem[fdBody]+'['+LTextPartNum+']'])) {do not localize} - or (PosInStrArray(FLineStruct.IMAPValue, ['NIL', '""'], False) <> -1) {do not localize} - or (FLineStruct.ByteCount < 1) then - begin - GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False); - Result := False; - Exit; - end; - - LHelper := TIdIMAP4WorkHelper.Create(Self); - try - case PosInStrArray(LContentTransferEncoding, ['base64', 'quoted-printable', 'binhex40'], False) of {Do not Localize} - 0: DoDecode(TIdDecoderMIME, True); - 1: DoDecode(TIdDecoderQuotedPrintable); - 2: DoDecode(TIdDecoderBinHex4); - else - {Assume no encoding (8bit) or something we cannot decode...} - DoDecode(); - end; - finally - FreeAndNil(LHelper); - end; - IOHandler.ReadLnWait; {Remove last line, ')' or 'UID 1)'} - if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin - Result := True; - end; - except - on E: EIdSocketError do begin - if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin - FConnectionState := csUnexpectedlyDisconnected; - end; - raise; - end; - end; - end; -end; - -function TIdIMAP4.RetrieveStructure(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; -begin - Result := InternalRetrieveStructure(AMsgNum, AMsg, nil); -end; - -function TIdIMAP4.RetrieveStructure(const AMsgNum: UInt32; AParts: TIdImapMessageParts): Boolean; -begin - Result := InternalRetrieveStructure(AMsgNum, nil, AParts); -end; - -function TIdIMAP4.InternalRetrieveStructure(const AMsgNum: UInt32; AMsg: TIdMessage; AParts: TIdImapMessageParts): Boolean; -var - LTheParts: TIdMessageParts; -begin - Result := False; - IsNumberValid(AMsgNum); - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdBodyStructure] + ')', - [IMAP4Commands[cmdFetch]], True, False); - if LastCmdResult.Code = IMAP_OK then begin - {CC3: Catch "Connection reset by peer"...} - try - if LastCmdResult.Text.Count > 0 then begin - if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdBodyStructure]]) then begin - if AMsg <> nil then begin - LTheParts := AMsg.MessageParts; - end else begin - LTheParts := nil; - end; - ParseBodyStructureResult(FLineStruct.IMAPValue, LTheParts, AParts); - if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch]], False) = IMAP_OK then begin - Result := True; - end; - end; - end; - except - on E: EIdSocketError do begin - if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin - FConnectionState := csUnexpectedlyDisconnected; - end; - raise; - end; - end; - end; -end; - -// retrieve a specific individual part of a message -function TIdIMAP4.RetrievePart(const AMsgNum: UInt32; const APartNum: string; - ADestStream: TStream; AContentTransferEncoding: string): Boolean; -var - LDummy1: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - LDummy2: Integer; -begin - if ADestStream = nil then begin - Result := False; - end else begin - Result := InternalRetrievePart(AMsgNum, APartNum, False, False, ADestStream, LDummy1, LDummy2, '', AContentTransferEncoding); {Do not Localize} - end; -end; - -function TIdIMAP4.RetrievePart(const AMsgNum: UInt32; const APartNum: Integer; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; -begin - IsImapPartNumberValid(APartNum); - Result := RetrievePart(AMsgNum, IntToStr(APartNum), ABuffer, ABufferLength, AContentTransferEncoding); -end; - -// Retrieve a specific individual part of a message -function TIdIMAP4.RetrievePart(const AMsgNum: UInt32; const APartNum: string; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; -begin - Result := InternalRetrievePart(AMsgNum, APartNum, False, False, nil, ABuffer, ABufferLength, '', AContentTransferEncoding); {Do not Localize} -end; - -// retrieve a specific individual part of a message -function TIdIMAP4.RetrievePartPeek(const AMsgNum: UInt32; const APartNum: string; - ADestStream: TStream; AContentTransferEncoding: string): Boolean; -var - LDummy1: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - LDummy2: Integer; -begin - if ADestStream = nil then begin - Result := False; - end else begin - Result := InternalRetrievePart(AMsgNum, APartNum, False, True, ADestStream, LDummy1, LDummy2, '', AContentTransferEncoding); {Do not Localize} - end; -end; - -function TIdIMAP4.RetrievePartPeek(const AMsgNum: UInt32; const APartNum: Integer; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; -begin - IsImapPartNumberValid(APartNum); - Result := RetrievePartPeek(AMsgNum, IntToStr(APartNum), ABuffer, ABufferLength, AContentTransferEncoding); -end; - -//Retrieve a specific individual part of a message -function TIdIMAP4.RetrievePartPeek(const AMsgNum: UInt32; const APartNum: string; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; -begin - Result := InternalRetrievePart(AMsgNum, APartNum, False, True, nil, ABuffer, ABufferLength, '', AContentTransferEncoding); {Do not Localize} -end; - -// Retrieve a specific individual part of a message -function TIdIMAP4.UIDRetrievePart(const AMsgUID: String; const APartNum: string; - var ADestStream: TStream; AContentTransferEncoding: string): Boolean; -var - LDummy1: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - LDummy2: Integer; -begin - if ADestStream = nil then begin - Result := False; - end else begin - Result := InternalRetrievePart(UIDToUInt32(AMsgUID), APartNum, True, False, ADestStream, LDummy1, LDummy2, '', AContentTransferEncoding); {Do not Localize} - end; -end; - -function TIdIMAP4.UIDRetrievePart(const AMsgUID: String; const APartNum: Integer; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; -begin - IsImapPartNumberValid(APartNum); - Result := UIDRetrievePart(AMsgUID, IntToStr(APartNum), ABuffer, ABufferLength, AContentTransferEncoding); -end; - -// Retrieve a specific individual part of a message -function TIdIMAP4.UIDRetrievePart(const AMsgUID: String; const APartNum: string; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; -begin - Result := InternalRetrievePart(UIDToUInt32(AMsgUID), APartNum, True, False, nil, ABuffer, ABufferLength, '', AContentTransferEncoding); {Do not Localize} -end; - -// retrieve a specific individual part of a message -function TIdIMAP4.UIDRetrievePartPeek(const AMsgUID: String; const APartNum: string; - var ADestStream: TStream; AContentTransferEncoding: string): Boolean; -var - LDummy1: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - LDummy2: Integer; -begin - if ADestStream = nil then begin - Result := False; - end else begin - Result := InternalRetrievePart(UIDToUInt32(AMsgUID), APartNum, True, True, ADestStream, LDummy1, LDummy2, '', AContentTransferEncoding); {Do not Localize} - end; -end; - -function TIdIMAP4.UIDRetrievePartPeek(const AMsgUID: String; const APartNum: Integer; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; -begin - IsImapPartNumberValid(APartNum); - Result := UIDRetrievePartPeek(AMsgUID, IntToStr(APartNum), ABuffer, ABufferLength, AContentTransferEncoding); -end; - -function TIdIMAP4.UIDRetrievePartPeek(const AMsgUID: String; const APartNum: string; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; - //Retrieve a specific individual part of a message -begin - Result := InternalRetrievePart(UIDToUInt32(AMsgUID), APartNum, True, True, nil, ABuffer, ABufferLength, '', AContentTransferEncoding); {Do not Localize} -end; - -function TIdIMAP4.RetrievePartToFile(const AMsgNum: UInt32; const APartNum: Integer; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; -begin - IsImapPartNumberValid(APartNum); - Result := RetrievePartToFile(AMsgNum, IntToStr(APartNum), ALength, ADestFileNameAndPath, AContentTransferEncoding); -end; - -// retrieve a specific individual part of a message -function TIdIMAP4.RetrievePartToFile(const AMsgNum: UInt32; const APartNum: string; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; -var - LDummy: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; -begin - if Length(ADestFileNameAndPath) = 0 then begin - Result := False; - end else begin - Result := InternalRetrievePart(AMsgNum, APartNum, False, False, nil, - LDummy, ALength, ADestFileNameAndPath, AContentTransferEncoding); - end; -end; - -function TIdIMAP4.RetrievePartToFilePeek(const AMsgNum: UInt32; const APartNum: Integer; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; -begin - IsImapPartNumberValid(APartNum); - Result := RetrievePartToFilePeek(AMsgNum, IntToStr(APartNum), ALength, ADestFileNameAndPath, AContentTransferEncoding); -end; - -// retrieve a specific individual part of a message -function TIdIMAP4.RetrievePartToFilePeek(const AMsgNum: UInt32; const APartNum: string; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; -var - LDummy: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; -begin - if Length(ADestFileNameAndPath) = 0 then begin - Result := False; - end else begin - Result := InternalRetrievePart(AMsgNum, APartNum, False, True, nil, - LDummy, ALength, ADestFileNameAndPath, AContentTransferEncoding); - end; -end; - -function TIdIMAP4.UIDRetrievePartToFile(const AMsgUID: String; const APartNum: Integer; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; -begin - IsImapPartNumberValid(APartNum); - Result := UIDRetrievePartToFile(AMsgUID, IntToStr(APartNum), ALength, ADestFileNameAndPath, AContentTransferEncoding); -end; - -// retrieve a specific individual part of a message -function TIdIMAP4.UIDRetrievePartToFile(const AMsgUID: String; const APartNum: string; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; -var - LDummy: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; -begin - if Length(ADestFileNameAndPath) = 0 then begin - Result := False; - end else begin - Result := InternalRetrievePart(UIDToUInt32(AMsgUID), APartNum, True, False, nil, - LDummy, ALength, ADestFileNameAndPath, AContentTransferEncoding); - end; -end; - -function TIdIMAP4.UIDRetrievePartToFilePeek(const AMsgUID: String; const APartNum: Integer; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; -begin - IsImapPartNumberValid(APartNum); - Result := UIDRetrievePartToFilePeek(AMsgUID, IntToStr(APartNum), ALength, ADestFileNameAndPath, AContentTransferEncoding); -end; - -// retrieve a specific individual part of a message -function TIdIMAP4.UIDRetrievePartToFilePeek(const AMsgUID: String; const APartNum: {Integer} string; - ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; -var - LDummy: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; -begin - if Length(ADestFileNameAndPath) = 0 then begin - Result := False; - end else begin - Result := InternalRetrievePart(UIDToUInt32(AMsgUID), APartNum, True, True, - nil, LDummy, ALength, ADestFileNameAndPath, AContentTransferEncoding); - end; -end; - -// retrieve a specific individual part of a message -// TODO: remove the ABufferLength output parameter under DOTNET, it is redundant... -function TIdIMAP4.InternalRetrievePart(const AMsgNum: UInt32; const APartNum: {Integer} string; - AUseUID: Boolean; AUsePeek: Boolean; ADestStream: TStream; - var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; - var ABufferLength: Integer; {NOTE: var args cannot have default params} - ADestFileNameAndPath: string; - AContentTransferEncoding: string): Boolean; -var - LCmd: string; - bCreatedStream: Boolean; - LDestStream: TStream; -// LPartSizeParam: string; - LHelper: TIdIMAP4WorkHelper; - - procedure DoDecode(ADecoderClass: TIdDecoderClass = nil; AStripCRLFs: Boolean = False); - var - LDecoder: TIdDecoder; - LStream: TStream; - LStrippedStream: TStringStream; - LUnstrippedStream: TStringStream; - begin - if LDestStream = nil then begin - LStream := TMemoryStream.Create; - end else begin - LStream := LDestStream; - end; - try - if ADecoderClass <> nil then begin - LDecoder := ADecoderClass.Create(Self); - try - LDecoder.DecodeBegin(LStream); - try - LUnstrippedStream := TStringStream.Create(''); - try - IOHandler.ReadStream(LUnstrippedStream, ABufferLength); //ReadStream uses OnWork, most other methods dont - {This is more complicated than quoted-printable because we - have to strip CRLFs that have been inserted by the MTA to - avoid overly long lines...} - if AStripCRLFs then begin - LStrippedStream := TStringStream.Create(''); - try - StripCRLFs(LUnstrippedStream, LStrippedStream); - LDecoder.Decode(LStrippedStream.DataString); - finally - FreeAndNil(LStrippedStream); - end; - end else begin - LDecoder.Decode(LUnstrippedStream.DataString); - end; - finally - FreeAndNil(LUnstrippedStream); - end; - finally - LDecoder.DecodeEnd; - end; - finally - FreeAndNil(LDecoder); - end; - end else begin - IOHandler.ReadStream(LStream, ABufferLength); //ReadStream uses OnWork, most other methods dont - end; - if LDestStream = nil then begin - ABufferLength := LStream.Size; - {$IFDEF DOTNET} - //ABuffer is a TIdBytes. - SetLength(ABuffer, ABufferLength); - if ABufferLength > 0 then begin - LStream.Position := 0; - ReadTIdBytesFromStream(LStream, ABuffer, ABufferLength); - end; - {$ELSE} - //ABuffer is a PByte. - GetMem(ABuffer, ABufferLength); - if ABufferLength > 0 then begin - LStream.Position := 0; - LStream.ReadBuffer(ABuffer^, ABufferLength); - end; - {$ENDIF} - end; - finally - if LDestStream = nil then begin - FreeAndNil(LStream); - end; - end; - end; - -begin - Result := False; - {CCC: Make sure part number is valid since it is now passed as a string...} - IsImapPartNumberValid(APartNum); - ABuffer := nil; - ABufferLength := 0; - CheckConnectionState(csSelected); - LCmd := ''; - if AUseUID then begin - LCmd := LCmd + IMAP4Commands[cmdUID] + ' '; {Do not Localize} - end; - LCmd := LCmd + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' ('; {Do not Localize} - if AUsePeek then begin - LCmd := LCmd + IMAP4FetchDataItem[fdBody]+'.PEEK'; {Do not Localize} - end else begin - LCmd := LCmd + IMAP4FetchDataItem[fdBody]; - end; - LCmd := LCmd + '[' + APartNum + '])'; {Do not Localize} - - SendCmd(NewCmdCounter, LCmd, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], True, False); - if LastCmdResult.Code = IMAP_OK then begin - {CC3: Catch "Connection reset by peer"...} - try - //LPartSizeParam := ''; {Do not Localize} - if ( (LastCmdResult.Text.Count < 1) or - (not ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [])) - or (PosInStrArray(FLineStruct.IMAPValue, ['NIL', '""'], False) <> -1) {do not localize} - or (FLineStruct.ByteCount < 1) ) then - begin - GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False); - Result := False; - Exit; - end; - {CC4: Some messages have an empty first part. These respond as: - 17 FETCH (BODY[1] "" UID 20) - instead of the more normal: - 17 FETCH (BODY[1] {11} {This bracket is not part of the response! - ... - UID 20) - } - ABufferLength := FLineStruct.ByteCount; - bCreatedStream := False; - - if ADestStream = nil then - begin - if Length(ADestFileNameAndPath) = 0 then begin - {User wants to write it to a memory block...} - LDestStream := nil; - end else begin - {User wants to write it to a file...} - LDestStream := TIdFileCreateStream.Create(ADestFileNameAndPath); - bCreatedStream := True; - end; - end else - begin - {User wants to write it to a stream ...} - LDestStream := ADestStream; - end; - try - LHelper := TIdIMAP4WorkHelper.Create(Self); - try - if TextIsSame(AContentTransferEncoding, 'base64') then begin {Do not Localize} - DoDecode(TIdDecoderMIME, True); - end else if TextIsSame(AContentTransferEncoding, 'quoted-printable') then begin {Do not Localize} - DoDecode(TIdDecoderQuotedPrintable); - end else if TextIsSame(AContentTransferEncoding, 'binhex40') then begin {Do not Localize} - DoDecode(TIdDecoderBinHex4); - end else begin - {Assume no encoding (8bit) or something we cannot decode...} - DoDecode; - end; - finally - FreeAndNil(LHelper); - end; - finally - if bCreatedStream then begin - FreeAndNil(LDestStream); - end; - end; - IOHandler.ReadLnWait; {Remove last line, ')' or 'UID 1)'} - if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin - Result := True; - end; - except - on E: EIdSocketError do begin - if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin - FConnectionState := csUnexpectedlyDisconnected; - end; - raise; - end; - end; - end; -end; - -function TIdIMAP4.UIDRetrieveStructure(const AMsgUID: String; AMsg: TIdMessage): Boolean; -begin - Result := UIDInternalRetrieveStructure(AMsgUID, AMsg, nil); -end; - -function TIdIMAP4.UIDRetrieveStructure(const AMsgUID: String; AParts: TIdImapMessageParts): Boolean; -begin - Result := UIDInternalRetrieveStructure(AMsgUID, nil, AParts); -end; - -function TIdIMAP4.UIDInternalRetrieveStructure(const AMsgUID: String; AMsg: TIdMessage; AParts: TIdImapMessageParts): Boolean; -var - //LSlRetrieve : TStringList; - //LStr: string; - LTheParts: TIdMessageParts; -begin - Result := False; - IsUIDValid(AMsgUID); - CheckConnectionState(csSelected); - - //Note: The normal single-line response may be split for huge bodystructures, - //allow for this by setting ASingleLineMayBeSplit to True... - SendCmd(NewCmdCounter, - IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + IMAP4FetchDataItem[fdBodyStructure] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], - True, True); - if LastCmdResult.Code = IMAP_OK then begin - {CC3: Catch "Connection reset by peer"...} - try - if LastCmdResult.Text.Count > 0 then begin - if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdBodyStructure]]) then begin - if AMsg <> nil then begin - LTheParts := AMsg.MessageParts; - end else begin - LTheParts := nil; - end; - ParseBodyStructureResult(FLineStruct.IMAPValue, LTheParts, AParts); - if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin - Result := True; - end; - end; - end; - except - on E: EIdSocketError do begin - if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin - FConnectionState := csUnexpectedlyDisconnected; - end; - raise; - end; - end; - end; -end; - -function TIdIMAP4.RetrieveHeader(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; -var - LStr: string; -begin - Result := False; - IsNumberValid(AMsgNum); - CheckConnectionState(csSelected); - - SendCmd(NewCmdCounter, - IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdRFC822Header] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch]], True, False); - if LastCmdResult.Code = IMAP_OK then begin - {CC3: Catch "Connection reset by peer"...} - try - if LastCmdResult.Text.Count > 0 then begin - if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdRFC822Header]]) - and (FLineStruct.ByteCount > 0) then - begin - BeginWork(wmRead, FLineStruct.ByteCount); //allow ReadString to use OnWork - try - LStr := IOHandler.ReadString(FLineStruct.ByteCount); - finally - EndWork(wmRead); - end; - {CC2: Clear out body so don't get multiple copies of bodies} - AMsg.Clear; - AMsg.Headers.Text := LStr; - AMsg.ProcessHeaders; - LStr := IOHandler.ReadLnWait; {Remove trailing line after the message, probably a ')' } - ParseLastCmdResultButAppendInfo(LStr); //There may be a UID or FLAGS in this - if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch]], False) = IMAP_OK then begin - AMsg.UID := FLineStruct.UID; - AMsg.Flags := FLineStruct.Flags; - Result := True; - end; - end; - end; - except - on E: EIdSocketError do begin - if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin - FConnectionState := csUnexpectedlyDisconnected; - end; - raise; - end; - end; - end; -end; - -function TIdIMAP4.UIDRetrieveHeader(const AMsgUID: String; AMsg: TIdMessage): Boolean; -var - LStr: string; -begin - Result := False; - IsUIDValid(AMsgUID); - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + IMAP4FetchDataItem[fdRFC822Header] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], True, False); - if LastCmdResult.Code = IMAP_OK then begin - {CC3: Catch "Connection reset by peer"...} - try - if LastCmdResult.Text.Count > 0 then begin - if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdRFC822Header]]) - and (FLineStruct.ByteCount > 0) then - begin - BeginWork(wmRead, FLineStruct.ByteCount); //allow ReadString to use OnWork - try - LStr := IOHandler.ReadString(FLineStruct.ByteCount); - finally - EndWork(wmRead); - end; - {CC2: Clear out body so don't get multiple copies of bodies} - AMsg.Clear; - AMsg.Headers.Text := LStr; - AMsg.ProcessHeaders; - LStr := IOHandler.ReadLnWait; {Remove trailing line after the message, probably a ')' } - ParseLastCmdResultButAppendInfo(LStr); //There may be a UID or FLAGS in this - if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin - AMsg.UID := FLineStruct.UID; - if AMsg.UID = '' then begin - AMsg.UID := AMsgUID; - end; - AMsg.Flags := FLineStruct.Flags; - Result := True; - end; - end; - end; - except - on E: EIdSocketError do begin - if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin - FConnectionState := csUnexpectedlyDisconnected; - end; - raise; - end; - end; - end; -end; - -function TIdIMAP4.RetrievePartHeader(const AMsgNum: UInt32; const APartNum: string; AHeaders: TIdHeaderList): Boolean; -begin - Result := InternalRetrievePartHeader(AMsgNum, APartNum, False, AHeaders); -end; - -function TIdIMAP4.UIDRetrievePartHeader(const AMsgUID: String; const APartNum: string; AHeaders: TIdHeaderList): Boolean; -begin - Result := InternalRetrievePartHeader(UIDToUInt32(AMsgUID), APartNum, True, AHeaders); -end; - -function TIdIMAP4.InternalRetrievePartHeader(const AMsgNum: UInt32; const APartNum: string; - const AUseUID: Boolean; AHeaders: TIdHeaderList): Boolean; -var - LCmd: string; -begin - Result := False; - IsNumberValid(AMsgNum); - CheckConnectionState(csSelected); - LCmd := ''; - if AUseUID then begin - LCmd := LCmd + IMAP4Commands[cmdUID] + ' '; {Do not Localize} - end; - LCmd := LCmd + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdBody] + '[' + APartNum + '.' + IMAP4FetchDataItem[fdHeader] + '])'; {Do not Localize} - - SendCmd(NewCmdCounter, LCmd, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], True, False); - if LastCmdResult.Code = IMAP_OK then begin - {CC3: Catch "Connection reset by peer"...} - try - if LastCmdResult.Text.Count > 0 then begin - if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], []) - and (PosInStrArray(FLineStruct.IMAPValue, ['NIL', '""'], False) = -1) - and (FLineStruct.ByteCount > 0) then - begin - {CC4: Some messages have an empty first part. These respond as: - 17 FETCH (BODY[1] "" UID 20) - instead of the more normal: - 17 FETCH (BODY[1] {11} {This bracket is not part of the response! - ... - UID 20) - } - BeginWork(wmRead, FLineStruct.ByteCount); //allow ReadString to use OnWork - try - AHeaders.Text := IOHandler.ReadString(FLineStruct.ByteCount); - finally - EndWork(wmRead); - end; - end; - end; - IOHandler.ReadLnWait; - if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin - Result := True; - end; - except - on E: EIdSocketError do begin - if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin - FConnectionState := csUnexpectedlyDisconnected; - end; - raise; - end; - end; - end; -end; - -//This code was just pulled up from IdMessageClient so that logging could be added. -function TIdIMAP4.ReceiveHeader(AMsg: TIdMessage; const AAltTerm: string = ''): string; -begin - repeat - Result := IOHandler.ReadLn; - // Exchange Bug: Exchange sometimes returns . when getting a message instead of - // '' then a . - That is there is no seperation between the header and the message for an - // empty message. - if ((Length(AAltTerm) = 0) and (Result = '.')) or (Result = AAltTerm) then begin - Break; - end else if Length(Result) <> 0 then begin - AMsg.Headers.Append(Result); - end; - until False; - AMsg.ProcessHeaders; -end; - -function TIdIMAP4.Retrieve(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; -begin - Result := InternalRetrieve(AMsgNum, False, False, AMsg); -end; - -//Retrieves a whole message "raw" and saves it to file, while marking it read. -function TIdIMAP4.RetrieveNoDecodeToFile(const AMsgNum: UInt32; ADestFile: string): Boolean; -var - LMsg: TIdMessage; -begin - Result := False; - LMsg := TIdMessage.Create(nil); - try - LMsg.NoDecode := True; - LMsg.NoEncode := True; - if InternalRetrieve(AMsgNum, False, False, LMsg) then begin - {RLebeau 12/09/2012: NOT currently using the same workaround here that - is being used in AppendMsg() to avoid SMTP dot transparent output from - TIdMessage.SaveToStream(). The reason for this is because I don't - know how this method is being used and I don't want to break anything - that may be depending on that transparent output being generated...} - LMsg.SaveToFile(ADestFile); - - {TODO: add an optional parameter to specify whether dot transparency - should be used or not, and then pass that to SaveToFile(). Or better, - just deprecate this method and implement a replacement that downloads - the message directly to the file without dot transparency, since it - has no meaning in IMAP. InternalRetrieve() uses an internal stream - anyway to receive the data, so let's just cut out TIdMessage here...} - - Result := True; - end; - finally - FreeAndNil(LMsg); - end; -end; - -//Retrieves a whole message "raw" and saves it to file -function TIdIMAP4.RetrieveNoDecodeToFilePeek(const AMsgNum: UInt32; ADestFile: string): Boolean; -var - LMsg: TIdMessage; -begin - Result := False; - LMsg := TIdMessage.Create(nil); - try - LMsg.NoDecode := True; - LMsg.NoEncode := True; - if InternalRetrieve(AMsgNum, False, True, LMsg) then begin - {RLebeau 12/09/2012: NOT currently using the same workaround here that - is being used in AppendMsg() to avoid SMTP dot transparent output from - TIdMessage.SaveToStream(). The reason for this is because I don't - know how this method is being used and I don't want to break anything - that may be depending on that transparent output being generated...} - LMsg.SaveToFile(ADestFile); - - {TODO: add an optional parameter to specify whether dot transparency - should be used or not, and then pass that to SaveToFile(). Or better, - just deprecate this method and implement a replacement that downloads - the message directly to the file without dot transparency, since it - has no meaning in IMAP. InternalRetrieve() uses an internal stream - anyway to receive the data, so let's just cut out TIdMessage here...} - - Result := True; - end; - finally - FreeAndNil(LMsg); - end; -end; - -//Retrieves a whole message "raw" and saves it to file, while marking it read. -function TIdIMAP4.RetrieveNoDecodeToStream(const AMsgNum: UInt32; AStream: TStream): Boolean; -var - LMsg: TIdMessage; -begin - Result := False; - LMsg := TIdMessage.Create(nil); - try - LMsg.NoDecode := True; - LMsg.NoEncode := True; - if InternalRetrieve(AMsgNum, False, False, LMsg) then begin - {RLebeau 12/09/2012: NOT currently using the same workaround here that - is being used in AppendMsg() to avoid SMTP dot transparent output from - TIdMessage.SaveToStream(). The reason for this is because I don't - know how this method is being used and I don't want to break anything - that may be depending on that transparent output being generated...} - LMsg.SaveToStream(AStream); - - {TODO: add an optional parameter to specify whether dot transparency - should be used or not, and then pass that to SaveToStream(). Or better, - just deprecate this method and implement a replacement that downloads - the message directly to the file without dot transparency, since it - has no meaning in IMAP. InternalRetrieve() uses an internal stream - anyway to receive the data, so let's just cut out TIdMessage here...} - - Result := True; - end; - finally - FreeAndNil(LMsg); - end; -end; - -//Retrieves a whole message "raw" and saves it to file -function TIdIMAP4.RetrieveNoDecodeToStreamPeek(const AMsgNum: UInt32; AStream: TStream): Boolean; -var - LMsg: TIdMessage; -begin - Result := False; - LMsg := TIdMessage.Create(nil); - try - LMsg.NoDecode := True; - LMsg.NoEncode := True; - if InternalRetrieve(AMsgNum, False, True, LMsg) then begin - {RLebeau 12/09/2012: NOT currently using the same workaround here that - is being used in AppendMsg() to avoid SMTP dot transparent output from - TIdMessage.SaveToStream(). The reason for this is because I don't - know how this method is being used and I don't want to break anything - that may be depending on that transparent output being generated...} - LMsg.SaveToStream(AStream); - - {TODO: add an optional parameter to specify whether dot transparency - should be used or not, and then pass that to SaveToStream(). Or better, - just deprecate this method and implement a replacement that downloads - the message directly to the file without dot transparency, since it - has no meaning in IMAP. InternalRetrieve() uses an internal stream - anyway to receive the data, so let's just cut out TIdMessage here...} - - Result := True; - end; - finally - FreeAndNil(LMsg); - end; -end; - -function TIdIMAP4.RetrievePeek(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; -begin - Result := InternalRetrieve(AMsgNum, False, True, AMsg); -end; - -function TIdIMAP4.UIDRetrieve(const AMsgUID: String; AMsg: TIdMessage): Boolean; -begin - Result := InternalRetrieve(UIDToUInt32(AMsgUID), True, False, AMsg); -end; - -//Retrieves a whole message "raw" and saves it to file, while marking it read. -function TIdIMAP4.UIDRetrieveNoDecodeToFile(const AMsgUID: String; ADestFile: string): Boolean; -var - LMsg: TIdMessage; -begin - Result := False; - LMsg := TIdMessage.Create(nil); - try - LMsg.NoDecode := True; - LMsg.NoEncode := True; - if InternalRetrieve(UIDToUInt32(AMsgUID), True, False, LMsg) then begin - {RLebeau 12/09/2012: NOT currently using the same workaround here that - is being used in AppendMsg() to avoid SMTP dot transparent output from - TIdMessage.SaveToStream(). The reason for this is because I don't - know how this method is being used and I don't want to break anything - that may be depending on that transparent output being generated...} - LMsg.SaveToFile(ADestFile); - - {TODO: add an optional parameter to specify whether dot transparency - should be used or not, and then pass that to SaveToFile(). Or better, - just deprecate this method and implement a replacement that downloads - the message directly to the file without dot transparency, since it - has no meaning in IMAP. InternalRetrieve() uses an internal stream - anyway to receive the data, so let's just cut out TIdMessage here...} - - Result := True; - end; - finally - FreeAndNil(LMsg); - end; -end; - -//Retrieves a whole message "raw" and saves it to file. -function TIdIMAP4.UIDRetrieveNoDecodeToFilePeek(const AMsgUID: String; ADestFile: string): Boolean; -var - LMsg: TIdMessage; -begin - Result := False; - LMsg := TIdMessage.Create(nil); - try - LMsg.NoDecode := True; - LMsg.NoEncode := True; - if InternalRetrieve(UIDToUInt32(AMsgUID), True, True, LMsg) then begin - {RLebeau 12/09/2012: NOT currently using the same workaround here that - is being used in AppendMsg() to avoid SMTP dot transparent output from - TIdMessage.SaveToStream(). The reason for this is because I don't - know how this method is being used and I don't want to break anything - that may be depending on that transparent output being generated...} - LMsg.SaveToFile(ADestFile); - - {TODO: add an optional parameter to specify whether dot transparency - should be used or not, and then pass that to SaveToFile(). Or better, - just deprecate this method and implement a replacement that downloads - the message directly to the file without dot transparency, since it - has no meaning in IMAP. InternalRetrieve() uses an internal stream - anyway to receive the data, so let's just cut out TIdMessage here...} - - Result := True; - end; - finally - FreeAndNil(LMsg); - end; -end; - -//Retrieves a whole message "raw" and saves it to file, while marking it read. -function TIdIMAP4.UIDRetrieveNoDecodeToStream(const AMsgUID: String; AStream: TStream): Boolean; -var - LMsg: TIdMessage; -begin - Result := False; - LMsg := TIdMessage.Create(nil); - try - LMsg.NoDecode := True; - LMsg.NoEncode := True; - if InternalRetrieve(UIDToUInt32(AMsgUID), True, False, LMsg) then begin - {RLebeau 12/09/2012: NOT currently using the same workaround here that - is being used in AppendMsg() to avoid SMTP dot transparent output from - TIdMessage.SaveToStream(). The reason for this is because I don't - know how this method is being used and I don't want to break anything - that may be depending on that transparent output being generated...} - LMsg.SaveToStream(AStream); - - {TODO: add an optional parameter to specify whether dot transparency - should be used or not, and then pass that to SaveToStream(). Or better, - just deprecate this method and implement a replacement that downloads - the message directly to the file without dot transparency, since it - has no meaning in IMAP. InternalRetrieve() uses an internal stream - anyway to receive the data, so let's just cut out TIdMessage here...} - - Result := True; - end; - finally - FreeAndNil(LMsg); - end; -end; - -//Retrieves a whole message "raw" and saves it to file. -function TIdIMAP4.UIDRetrieveNoDecodeToStreamPeek(const AMsgUID: String; AStream: TStream): Boolean; -var - LMsg: TIdMessage; -begin - Result := False; - LMsg := TIdMessage.Create(nil); - try - LMsg.NoDecode := True; - LMsg.NoEncode := True; - if InternalRetrieve(UIDToUInt32(AMsgUID), True, True, LMsg) then begin - {RLebeau 12/09/2012: NOT currently using the same workaround here that - is being used in AppendMsg() to avoid SMTP dot transparent output from - TIdMessage.SaveToStream(). The reason for this is because I don't - know how this method is being used and I don't want to break anything - that may be depending on that transparent output being generated...} - LMsg.SaveToStream(AStream); - - {TODO: add an optional parameter to specify whether dot transparency - should be used or not, and then pass that to SaveToStream(). Or better, - just deprecate this method and implement a replacement that downloads - the message directly to the file without dot transparency, since it - has no meaning in IMAP. InternalRetrieve() uses an internal stream - anyway to receive the data, so let's just cut out TIdMessage here...} - - Result := True; - end; - finally - FreeAndNil(LMsg); - end; -end; - -function TIdIMAP4.UIDRetrievePeek(const AMsgUID: String; AMsg: TIdMessage): Boolean; -begin - Result := InternalRetrieve(UIDToUInt32(AMsgUID), True, True, AMsg); -end; - -function TIdIMAP4.InternalRetrieve(const AMsgNum: UInt32; AUseUID: Boolean; AUsePeek: Boolean; AMsg: TIdMessage): Boolean; -var - LStr: String; - LCmd: string; - LDestStream: TStream; - LHelper: TIdIMAP4WorkHelper; -begin - Result := False; - IsNumberValid(AMsgNum); - CheckConnectionState(csSelected); - LCmd := ''; - if AUseUID then begin - LCmd := LCmd + IMAP4Commands[cmdUID] + ' '; {Do not Localize} - end; - LCmd := LCmd + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' ('; {Do not Localize} - if AUsePeek then begin - LCmd := LCmd + IMAP4FetchDataItem[fdBodyPeek]; {Do not Localize} - end else begin - LCmd := LCmd + IMAP4FetchDataItem[fdRFC822]; {Do not Localize} - end; - LCmd := LCmd + ')'; {Do not Localize} - - SendCmd(NewCmdCounter, LCmd, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], True, False); - if LastCmdResult.Code = IMAP_OK then begin - {CC3: Catch "Connection reset by peer"...} - try - //Leave 3rd param as [] because ParseLastCmdResult can get a number of odd - //replies ( variants on Body[] )... - if (LastCmdResult.Text.Count < 1) or - (not ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [])) then - begin - Exit; - end; - {CC8: Retrieve via byte count instead of looking for terminator, - which was impossible to get working with all the different IMAP - servers because some left the terminator (LExpectedResponse) at - the end of a message line, so you could not decide if it was - part of the message or the terminator.} - AMsg.Clear; - if FLineStruct.ByteCount > 0 then begin - {Use a temporary memory block to suck the message into...} - // TODO: use TIdTCPStream instead and let TIdIOHandlerStreamMsg below read - // from this IOHandler directly so we don't have to waste memory reading - // potentially large messages... - LDestStream := TMemoryStream.Create; - try - LHelper := TIdIMAP4WorkHelper.Create(Self); - try - IOHandler.ReadStream(LDestStream, FLineStruct.ByteCount); //ReadStream uses OnWork, most other methods dont - finally - FreeAndNil(LHelper); - end; - - {Feed stream into the standard message parser...} - LDestStream.Position := 0; - - {RLebeau 12/09/2012: this is a workaround to a design limitation in - TIdMessage.LoadFromStream(). It assumes the stream data is always - in an escaped format using SMTP dot transparency, but that is not - the case in IMAP! Until this design is corrected, we have to use a - workaround for now. This logic is copied from TIdMessage.LoadFromStream() - and slightly tweaked...} - - //AMsg.LoadFromStream(LDestStream); - {$IFDEF HAS_CLASS_HELPER} - AMsg.LoadFromStream(LDestStream, False, False); - {$ELSE} - TIdMessageHelper_LoadFromStream(AMsg, LDestStream, False, False); - {$ENDIF} - finally - FreeAndNil(LDestStream); - end; - end; - LStr := IOHandler.ReadLnWait; {Remove trailing line after the message, probably a ')' } - ParseLastCmdResultButAppendInfo(LStr); //There may be a UID or FLAGS in this - if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin - AMsg.UID := FLineStruct.UID; - if (AMsg.UID = '') and AUseUID then begin - AMsg.UID := IntToStr(Int64(AMsgNum)); - end; - AMsg.Flags := FLineStruct.Flags; - Result := True; - end; - except - on E: EIdSocketError do begin - if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin - FConnectionState := csUnexpectedlyDisconnected; - end; - raise; - end; - end; - end; -end; - -function TIdIMAP4.RetrieveAllHeaders(AMsgList: TIdMessageCollection): Boolean; -begin - Result := InternalRetrieveHeaders(AMsgList, -1); -end; - -function TIdIMAP4.RetrieveFirstHeaders(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; -begin - Result := InternalRetrieveHeaders(AMsgList, ACount); -end; - -function TIdIMAP4.InternalRetrieveHeaders(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; -var - LMsgItem : TIdMessageItem; - Ln : Integer; -begin - {CC2: This may get a response of "OK completed" if there are no messages} - CheckConnectionState(csSelected); - Result := False; - if AMsgList <> nil then begin - if (ACount < 0) or (ACount > FMailBox.TotalMsgs) then begin - ACount := FMailBox.TotalMsgs; - end; - // TODO: can this be accomplished using a single FETCH, similar to RetrieveAllEnvelopes()? - for Ln := 1 to ACount do begin - LMsgItem := AMsgList.Add; - if not RetrieveHeader(Ln, LMsgItem.Msg) then begin - Exit; - end; - end; - Result := True; - end; -end; - -function TIdIMAP4.RetrieveAllMsgs(AMsgList: TIdMessageCollection): Boolean; -begin - Result := InternalRetrieveMsgs(AMsgList, -1); -end; - -function TIdIMAP4.RetrieveFirstMsgs(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; -begin - Result := InternalRetrieveMsgs(AMsgList, ACount); -end; - -function TIdIMAP4.InternalRetrieveMsgs(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; -var - LMsgItem : TIdMessageItem; - Ln : Integer; -begin - {CC2: This may get a response of "OK completed" if there are no messages} - CheckConnectionState(csSelected); - Result := False; - if AMsgList <> nil then begin - if (ACount < 0) or (ACount > FMailBox.TotalMsgs) then begin - ACount := FMailBox.TotalMsgs; - end; - // TODO: can this be accomplished using a single FETCH, similar to RetrieveAllEnvelopes()? - for Ln := 1 to ACount do begin - LMsgItem := AMsgList.Add; - if not Retrieve(Ln, LMsgItem.Msg) then begin - Exit; - end; - end; - Result := True; - end; -end; - -function TIdIMAP4.DeleteMsgs(const AMsgNumList: array of UInt32): Boolean; -begin - Result := StoreFlags(AMsgNumList, sdAdd, [mfDeleted]); -end; - -function TIdIMAP4.UIDDeleteMsg(const AMsgUID: String): Boolean; -begin - Result := UIDStoreFlags(AMsgUID, sdAdd, [mfDeleted]); -end; - -function TIdIMAP4.UIDDeleteMsgs(const AMsgUIDList: array of String): Boolean; -begin - Result := UIDStoreFlags(AMsgUIDList, sdAdd, [mfDeleted]); -end; - -function TIdIMAP4.RetrieveMailBoxSize: Int64; -var - Ln : Integer; -begin - Result := -1; - CheckConnectionState(csSelected); - {CC2: This should not be checking FMailBox.TotalMsgs because the server may - have added messages to the mailbox unknown to us, and we are going to ask the - server anyway (if it's empty, we will return 0 anyway} - SendCmd(NewCmdCounter, - IMAP4Commands[cmdFetch] + ' 1:*' + ' (' + IMAP4FetchDataItem[fdRFC822Size] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch]]); - if LastCmdResult.Code = IMAP_OK then begin - Result := 0; - for Ln := 0 to FMailBox.TotalMsgs - 1 do begin - if ParseLastCmdResult(LastCmdResult.Text[Ln], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdRFC822Size]]) then begin - Result := Result + IndyStrToInt64( FLineStruct.IMAPValue ); - end else begin - {CC2: Return -1, not 0, if we cannot parse the result...} - Result := -1; - Exit; - end; - end; - end; -end; - -function TIdIMAP4.UIDRetrieveMailBoxSize: Int64; -var - Ln : Integer; -begin - Result := -1; - CheckConnectionState(csSelected); - {CC2: This should not be checking FMailBox.TotalMsgs because the server may - have added messages to the mailbox unknown to us, and we are going to ask the - server anyway (if it's empty, we will return 0 anyway} - SendCmd(NewCmdCounter, - IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' 1:*' + ' (' + IMAP4FetchDataItem[fdRFC822Size] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]]); - if LastCmdResult.Code = IMAP_OK then begin - Result := 0; - for Ln := 0 to FMailBox.TotalMsgs - 1 do begin - if ParseLastCmdResult(LastCmdResult.Text[Ln], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdRFC822Size]]) then begin - Result := Result + IndyStrToInt64(FLineStruct.IMAPValue); - end else begin - {CC2: Return -1, not 0, if we cannot parse the result...} - Result := -1; - Break; - end; - end; - end; -end; - -function TIdIMAP4.RetrieveMsgSize(const AMsgNum: UInt32): Int64; -begin - Result := -1; - IsNumberValid(AMsgNum); - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdRFC822Size] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch]]); - if LastCmdResult.Code = IMAP_OK then begin - if (LastCmdResult.Text.Count > 0) and - ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdRFC822Size]]) then begin - Result := IndyStrToInt64(FLineStruct.IMAPValue); - end; - end; -end; - -function TIdIMAP4.UIDRetrieveMsgSize(const AMsgUID: String): Int64; -begin - Result := -1; - IsUIDValid(AMsgUID); - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + IMAP4FetchDataItem[fdRFC822Size] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]]); - if LastCmdResult.Code = IMAP_OK then begin - if (LastCmdResult.Text.Count > 0) and - ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdRFC822Size]]) then begin - Result := IndyStrToInt64(FLineStruct.IMAPValue); - end; - end; -end; - -function TIdIMAP4.CheckMsgSeen(const AMsgNum: UInt32): Boolean; -begin - Result := False; - IsNumberValid(AMsgNum); - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdFlags] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch]]); - if LastCmdResult.Code = IMAP_OK then begin - if (LastCmdResult.Text.Count > 0) and - ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdFlags]]) then - begin - if mfSeen in FLineStruct.Flags then begin - Result := True; - end; - end; - end; -end; - -function TIdIMAP4.UIDCheckMsgSeen(const AMsgUID: String): Boolean; -begin - {Default to unseen, so if get no flags back (i.e. no \Seen flag) - we return False (i.e. we return it is unseen) - Some servers return nothing at all if no flags set (the better ones return an empty set).} - Result := False; - IsUIDValid(AMsgUID); - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + IMAP4FetchDataItem[fdFlags] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]]); - if LastCmdResult.Code = IMAP_OK then begin - if (LastCmdResult.Text.Count > 0) and - ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdFlags]]) then - begin - if mfSeen in FLineStruct.Flags then begin - Result := True; - end; - end; - end; -end; - -function TIdIMAP4.RetrieveFlags(const AMsgNum: UInt32; var AFlags: {Pointer}TIdMessageFlagsSet): Boolean; -begin - Result := False; - {CC: Empty set to avoid returning results from a previous call if call fails} - AFlags := []; - IsNumberValid(AMsgNum); - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdFlags] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch]]); - if LastCmdResult.Code = IMAP_OK then begin - if (LastCmdResult.Text.Count > 0) and - ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdFlags]]) then - begin - AFlags := FLineStruct.Flags; - Result := True; - end; - end; -end; - -function TIdIMAP4.UIDRetrieveFlags(const AMsgUID: String; var AFlags: TIdMessageFlagsSet): Boolean; -begin - Result := False; - {BUG FIX: Empty set to avoid returning results from a previous call if call fails} - AFlags := []; - IsUIDValid(AMsgUID); - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + IMAP4FetchDataItem[fdFlags] + ')', {Do not Localize} - [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]]); - if LastCmdResult.Code = IMAP_OK then begin - if (LastCmdResult.Text.Count > 0) and - ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdFlags]]) then - begin - AFlags := FLineStruct.Flags; - Result := True; - end; - end; -end; - -function TIdIMAP4.RetrieveValue(const AMsgNum: UInt32; const AField: String; var AValue: String): Boolean; -begin - Result := False; - {CC: Empty string to avoid returning results from a previous call if call fails} - AValue := ''; - IsNumberValid(AMsgNum); - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + AField + ')', {Do not Localize} - [IMAP4Commands[cmdFetch]]); - if LastCmdResult.Code = IMAP_OK then begin - if (LastCmdResult.Text.Count > 0) and - ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [AField]) then - begin - case PosInStrArray(AField, ['UID', 'FLAGS', 'X-GM-MSGID', 'X-GM-THRID', 'X-GM-LABELS'], False) of {Do not Localize} - 0: AValue := FLineStruct.UID; - 1: AValue := FLineStruct.FlagsStr; - 2: AValue := FLineStruct.GmailMsgID; - 3: AValue := FLineStruct.GmailThreadID; - 4: AValue := FLineStruct.GmailLabels; - else - AValue := FLineStruct.IMAPValue; - end; - Result := True; - end; - end; -end; - -function TIdIMAP4.UIDRetrieveValue(const AMsgUID: String; const AField: String; var AValue: String): Boolean; -begin - Result := False; - {CC: Empty string to avoid returning results from a previous call if call fails} - AValue := ''; - IsUIDValid(AMsgUID); - CheckConnectionState(csSelected); - SendCmd(NewCmdCounter, - IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + AField + ')', {Do not Localize} - [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]]); - if LastCmdResult.Code = IMAP_OK then begin - if (LastCmdResult.Text.Count > 0) and - ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [AField]) then - begin - case PosInStrArray(AField, ['UID', 'FLAGS', 'X-GM-MSGID', 'X-GM-THRID', 'X-GM-LABELS'], False) of {Do not Localize} - 0: AValue := FLineStruct.UID; - 1: AValue := FLineStruct.FlagsStr; - 2: AValue := FLineStruct.GmailMsgID; - 3: AValue := FLineStruct.GmailThreadID; - 4: AValue := FLineStruct.GmailLabels; - else - AValue := FLineStruct.IMAPValue; - end; - Result := True; - end; - end; -end; - -function TIdIMAP4.GetConnectionStateName: String; -begin - case FConnectionState of - csAny : Result := RSIMAP4ConnectionStateAny; - csNonAuthenticated : Result := RSIMAP4ConnectionStateNonAuthenticated; - csAuthenticated : Result := RSIMAP4ConnectionStateAuthenticated; - csSelected : Result := RSIMAP4ConnectionStateSelected; - csUnexpectedlyDisconnected : Result := RSIMAP4ConnectionStateUnexpectedlyDisconnected; - end; -end; - -{ TIdIMAP4 Commands } - -{ Parser Functions... } - -{This recursively parses down. It gets either a line like: - - "text" "plain" ("charset" "ISO-8859-1") NIL NIL "7bit" 40 1 NIL NIL NIL - - which it parses into AThisImapPart, and we are done (at the end of the - recursive calls), or a line like: - - ("text" "plain"...NIL)("text" "html"...NIL) "alternative" ("boundary" "----bdry") NIL NIL - - when we need to add "alternative" and the boundary to this part, but recurse - down for the 1st two parts. } - -procedure TIdIMAP4.ParseImapPart(ABodyStructure: string; - AImapParts: TIdImapMessageParts; AThisImapPart: TIdImapMessagePart; AParentImapPart: TIdImapMessagePart; //ImapPart version - APartNumber: integer); -var - LNextImapPart: TIdImapMessagePart; - LSubParts: TStringList; - LPartNumber: integer; -begin - ABodyStructure := Trim(ABodyStructure); - AThisImapPart.FUnparsedEntry := ABodyStructure; - if ABodyStructure[1] <> '(' then begin {Do not Localize} - //We are at the bottom. Parse the low-level '"text" "plain"...' into this part. - ParseBodyStructurePart(ABodyStructure, nil, AThisImapPart); - if AParentImapPart = nil then begin - //This is the top-level part, and it is "text" "plain" etc, so it is not MIME... - AThisImapPart.Encoding := mePlainText; - AThisImapPart.ImapPartNumber := '1'; {Do not Localize} - AThisImapPart.ParentPart := -1; - end else begin - AThisImapPart.Encoding := meMIME; - AThisImapPart.ImapPartNumber := AParentImapPart.ImapPartNumber+'.'+IntToStr(APartNumber); {Do not Localize} - //If we are the first level down in MIME, the parent part was '', so trim... - if AThisImapPart.ImapPartNumber[1] = '.' then begin {Do not Localize} - AThisImapPart.ImapPartNumber := Copy(AThisImapPart.ImapPartNumber, 2, MaxInt); - end; - AThisImapPart.ParentPart := AParentImapPart.Index; - end; - end else begin - AThisImapPart.Encoding := meMIME; - if AParentImapPart = nil then begin - AThisImapPart.ImapPartNumber := ''; - AThisImapPart.ParentPart := -1; - end else begin - AThisImapPart.ImapPartNumber := AParentImapPart.ImapPartNumber+'.'+IntToStr(APartNumber); {Do not Localize} - //If we are the first level down in MIME, the parent part was '', so trim... - if AThisImapPart.ImapPartNumber[1] = '.' then begin {Do not Localize} - AThisImapPart.ImapPartNumber := Copy(AThisImapPart.ImapPartNumber, 2, MaxInt); - end; - AThisImapPart.ParentPart := AParentImapPart.Index; - end; - LSubParts := TStringList.Create; - try - ParseIntoBrackettedQuotedAndUnquotedParts(ABodyStructure, LSubParts, True); - LPartNumber := 1; - while (LSubParts.Count > 0) and (LSubParts[0] <> '') and (LSubParts[0][1] = '(') do begin {Do not Localize} - LNextImapPart := AImapParts.Add; - ParseImapPart(Copy(LSubParts[0], 2, Length(LSubParts[0])-2), AImapParts, LNextImapPart, AThisImapPart, LPartNumber); - LSubParts.Delete(0); - Inc(LPartNumber); - end; - if LSubParts.Count > 0 then begin - //LSubParts now (only) holds the params for this part... - AThisImapPart.FBodyType := LowerCase(GetNextQuotedParam(LSubParts[0], True)); //mixed, alternative - end else begin - AThisImapPart.FBodyType := ''; - end; - finally - FreeAndNil(LSubParts); - end; - end; -end; - -{ WARNING: Not used by writer, may have bugs. - - Version of ParseImapPart except using TIdMessageParts. - Added for compatibility with TIdMessage.MessageParts, - but does not have enough functionality for many IMAP functions. } - -procedure TIdIMAP4.ParseMessagePart(ABodyStructure: string; - AMessageParts: TIdMessageParts; AThisMessagePart: TIdMessagePart; AParentMessagePart: TIdMessagePart; //MessageParts version - APartNumber: integer); -var - LNextMessagePart: TIdMessagePart; - LSubParts: TStringList; - LPartNumber: integer; -begin - ABodyStructure := Trim(ABodyStructure); - if ABodyStructure[1] <> '(' then begin {Do not Localize} - //We are at the bottom. Parse this into this part. - ParseBodyStructurePart(ABodyStructure, AThisMessagePart, nil); - if AParentMessagePart = nil then begin - //This is the top-level part, and it is "text" "plain" etc, so it is not MIME... - AThisMessagePart.ParentPart := -1; - end else begin - AThisMessagePart.ParentPart := AParentMessagePart.Index; - end; - end else begin - LSubParts := TStringList.Create; - try - ParseIntoBrackettedQuotedAndUnquotedParts(ABodyStructure, LSubParts, True); - LPartNumber := 1; - while (LSubParts.Count > 0) and (LSubParts[0] <> '') and (LSubParts[0][1] = '(') do begin {Do not Localize} - LNextMessagePart := TIdAttachmentMemory.Create(AMessageParts); - ParseMessagePart(Copy(LSubParts[0], 2, Length(LSubParts[0])-2), AMessageParts, LNextMessagePart, AThisMessagePart, LPartNumber); - LSubParts.Delete(0); - Inc(LPartNumber); - end; - //LSubParts now (only) holds the params for this part... - if AParentMessagePart = nil then begin - AThisMessagePart.ParentPart := -1; - end else begin - AThisMessagePart.ParentPart := AParentMessagePart.Index; - end; - finally - FreeAndNil(LSubParts); - end; - end; -end; - -{CC2: Function added to support individual part retreival} -{ - If it's a single-part message, it won't be enclosed in brackets - it will be: - "body type": "TEXT", "application", "image", "MESSAGE" (followed by subtype RFC822 for envelopes, ignore) - "body subtype": "PLAIN", "octet-stream", "tiff", "html" - "body parameter parenthesized list": bracketted list of pairs ("CHARSET" "US-ASCII" "NAME" "cc.tif" "format" "flowed"), ("charset" "ISO-8859-1") - "body id": NIL, 986767766767887@fg.com - "body description": NIL, "Compiler diff" - "body encoding": "7bit" "8bit" "binary" (NO encoding used with these), "quoted-printable" "base64" "ietf-token" "x-token" - "body size" 2279 - "body lines" 48 (only present for some types, only those with "body type=text" and "body subtype=plain" that I found, if not present it WONT be a NIL, it just won't be there! However, it won't be needed) - NIL - ("inline" ("filename" "classbd.h")), ("attachment" ("filename" "DEGDAY.WB3")) - NIL - Example: - * 4 FETCH (BODYSTRUCTURE ("text" "plain" ("charset" "ISO-8859-1") NIL NIL "7bit" 40 1 NIL NIL NIL)) - --------------------------------------------------------------------------- - For most multi-part messages, each part will be bracketted: - ( (part 1 stuff) (part 2 stuff) "mixed" (boundary) NIL NIL ) - Example: - * 1 FETCH (BODYSTRUCTURE (("text" "plain" ("charset" "us-ascii" "format" "flowed") - NIL NIL "7bit" 52 3 NIL NIL NIL)("text" "plain" ("name" "tnkin.txt") NIL NIL - "7bit" 28421 203 NIL ("inline" ("filename" "tnkin.txt")) NIL) "mixed" - ("boundary" "------------070105030104060407030601") NIL NIL)) - --------------------------------------------------------------------------- - Some multiparts are bracketted again. This is the "alternative" encoding, - part 1 has two parts, a plain-text part and a html part: - ( ( (part 1a stuff) (part 1b stuff) "alternative" (boundary) NIL NIL ) (part 2 stuff) "mixed" (boundary) NIL NIL ) - 1 2 2 1 - Example: - * 50 FETCH (BODYSTRUCTURE ((("text" "plain" ("charset" "ISO-8859-1") NIL NIL - "quoted-printable" 415 12 NIL NIL NIL)("text" "html" ("charset" "ISO-8859-1") - NIL NIL "quoted-printable" 1034 25 NIL NIL NIL) "alternative" ("boundary" - "----=_NextPart_001_0027_01C33A37.33CFE220") NIL NIL)("application" "x-zip-compressed" - ("name" "IdIMAP4.zip") NIL NIL "base64" 20572 NIL ("attachment" ("filename" - "IdIMAP4.zip")) NIL) "mixed" ("boundary" "----=_NextPart_000_0026_01C33A37.33CFE220") - NIL NIL) UID 62) -} -procedure TIdIMAP4.ParseBodyStructureResult(ABodyStructure: string; ATheParts: TIdMessageParts; AImapParts: TIdImapMessageParts); -begin - {CC7: New code uses a different parsing method that allows for multisection parts.} - if AImapParts <> nil then begin //Just sort out the ImapParts version for now - ParseImapPart(ABodyStructure, AImapParts, AImapParts.Add, nil, -1); - end; - if ATheParts <> nil then begin - ParseMessagePart(ABodyStructure, ATheParts, TIdAttachmentMemory.Create(ATheParts), nil, -1); - end; -end; - -procedure TIdIMAP4.ParseTheLine(ALine: string; APartsList: TStrings); -var - LTempList: TStringList; - LN: integer; - LStr, LWord: string; -begin - {Parse it and see what we get...} - LTempList := TStringList.Create; - try - ParseIntoParts(ALine, LTempList); - {Copy any parts from LTempList into the list of parts LPartsList...} - for LN := 0 to LTempList.Count-1 do begin - LStr := LTempList.Strings[LN]; - LWord := LowerCase(GetNextWord(LStr)); - if CharEquals(LStr, 1, '(') or (PosInStrArray(LWord, ['"text"', '"image"', '"application"'], False) <> -1) then begin {Do not Localize} - APartsList.Add(LStr); - end; - end; - finally - FreeAndNil(LTempList); - end; -end; - -procedure TIdIMAP4.ParseBodyStructurePart(APartString: string; AThePart: TIdMessagePart; - AImapPart: TIdImapMessagePart); - {CC3: Function added to support individual part retreival} -var - LParams: TStringList; -// LContentDispositionStuff: string; - LCharSet: String; - LFilename: string; - LDescription: string; - LTemp: string; - LSize: Int64; - LPos: Integer; -begin - {Individual parameters may be strings like "text", NIL, a number, or bracketted pairs like - ("CHARSET" "US-ASCII" "NAME" "cc.tif" "format" "flowed")...} - {There are three common line formats, with differing numbers of parameters: - (a) "TEXT" "HTML" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 2879 69 NIL NIL NIL - (a) "TEXT" "HTML" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 2879 69 NIL NIL - (c) "TEXT" "HTML" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 2879 69 - Note the last one only has 7 parameters, need to watch we don't index past the 7th!} - LParams := TStringList.Create; - try - ParseIntoParts(APartString, LParams); - {Build up strings into same format as used by message decoders...} - {Content Disposition: If present, may be at index 8 or 9...} - {CC8: Altered to allow for case where it may not be present at all (get "List - index out of bounds" error if try to access non-existent LParams[9])...} -// LContentDispositionStuff := ''; {Do not Localize} -// if LParams.Count > 9 then begin {Have an LParams[9]} -// if TextIsSame(LParams[9], 'NIL') then begin {Do not Localize} - {It's NIL at 9, must be at 8...} -// if TextIsSame(LParams[8], 'NIL') then begin {Do not Localize} -// LContentDispositionStuff := LParams[8]; -// end; -// end else begin - {It's not NIL, must be valid...} -// LContentDispositionStuff := LParams[9]; -// end; -// end else if LParams.Count > 8 then begin {Have an LParams[8]} -// if TextIsSame(LParams[8], 'NIL') then begin {Do not Localize} -// LContentDispositionStuff := LParams[8]; -// end; -// end; - - {Find and clean up the filename, if present...} - LFilename := ''; {Do not Localize} - LPos := IndyPos('"NAME"', UpperCase(APartString)); {Do not Localize} - if LPos > 0 then begin - LTemp := Copy(APartString, LPos+7, MaxInt); - LFilename := GetNextQuotedParam(LTemp, False); - end else - begin - LPos := IndyPos('"FILENAME"', UpperCase(APartString)); {Do not Localize} - if LPos > 0 then begin - LTemp := Copy(APartString, LPos+11, MaxInt); - LFilename := GetNextQuotedParam(LTemp, False); - end; - end; - {If the filename starts and ends with double-quotes, remove them...} - if Length(LFilename) > 1 then begin - if TextStartsWith(LFilename, '"') and TextEndsWith(LFilename, '"') then begin {Do not Localize} - LFilename := Copy(LFilename, 2, Length(LFilename)-2); - end; - end; - {CC7: The filename may be encoded, so decode it...} - if Length(LFilename) > 1 then begin - LFilename := DecodeHeader(LFilename); - end; - - LCharSet := ''; - if IndyPos('"CHARSET"', UpperCase(LParams[2])) > 0 then begin {Do not Localize} - LTemp := Copy(LParams[2], IndyPos('"CHARSET" ', UpperCase(LParams[2]))+10, MaxInt); {Do not Localize} - LCharSet := GetNextQuotedParam(LTemp, True); - end; - - LSize := 0; - if (not TextIsSame(LParams[6], 'NIL')) and (Length(LParams[6]) <> 0) then begin - LSize := IndyStrToInt64(LParams[6]); {Do not Localize} - end; - - LDescription := ''; {Do not Localize} - if (LParams.Count > 9) and (not TextIsSame(LParams[9], 'NIL')) then begin {Do not Localize} - LDescription := GetNextQuotedParam(LParams[9], False); - end else if (LParams.Count > 8) and (not TextIsSame(LParams[8], 'NIL')) then begin {Do not Localize} - LDescription := GetNextQuotedParam(LParams[8], False); - end; - - if AThePart <> nil then begin - {Put into the same format as TIdMessage MessageParts...} - AThePart.ContentType := LParams[0]+'/'+LParams[1]+ParseBodyStructureSectionAsEquates(LParams[2]); {Do not Localize} - AThePart.ContentTransfer := LParams[5]; - //Watch out for BinHex4.0, the encoding is inferred from the Content-Type... - if IsHeaderMediaType(AThePart.ContentType, 'application/mac-binhex40') then begin {do not localize} - AThePart.ContentTransfer := 'binhex40'; {do not localize} - end; - AThePart.DisplayName := LFilename; - end; - - if AImapPart <> nil then begin - AImapPart.FBodyType := LParams[0]; - AImapPart.FBodySubType := LParams[1]; - AImapPart.FFileName := LFilename; - AImapPart.FDescription := LDescription; - AImapPart.FCharSet := LCharSet; - AImapPart.FContentTransferEncoding := LParams[5]; - AImapPart.FSize := LSize; - //Watch out for BinHex4.0, the encoding is inferred from the Content-Type... - if ( (TextIsSame(AImapPart.FBodyType, 'application')) {do not localize} - and (TextIsSame(AImapPart.FBodySubType, 'mac-binhex40')) ) then begin {do not localize} - AImapPart.FContentTransferEncoding := 'binhex40'; {do not localize} - end; - end; - finally - FreeAndNil(LParams); - end; -end; - -function ResolveQuotedSpecials(const AParam: string): string; -begin - // Handle quoted_specials, RFC1730 - // \ with other chars than " or \ after, looks illegal in RFC1730, but leave them untouched - // TODO: use StringsReplace() instead - //Result := StringsReplace(AParam, ['\"', '\\'], ['"', '\']); - Result := ReplaceAll(AParam, '\"', '"'); - Result := ReplaceAll(Result, '\\', '\'); -end; - -procedure TIdIMAP4.ParseIntoParts(APartString: string; AParams: TStrings); -var - LInPart: Integer; - LStartPos: Integer; - //don't rename this LParam. That's the same asa windows identifier - LParamater: string; - LBracketLevel: Integer; - Ln: Integer; - LInQuotesInsideBrackets: Boolean; - LInQuotedSpecial: Boolean; -begin - LStartPos := 0; {Stop compiler whining} - LBracketLevel := 0; {Stop compiler whining} - LInQuotesInsideBrackets := False; {Stop compiler whining} - LInQuotedSpecial := False; {Stop compiler whining} - LInPart := 0; {0 is not in a part, 1 is in a quote-delimited part, 2 is in a bracketted parameter-pair list} - for Ln := 1 to Length(APartString) do begin - if (LInPart = 1) or ((LInPart = 2) and LInQuotesInsideBrackets) then begin - if LInQuotedSpecial then begin - LInQuotedSpecial := False; - end - else if APartString[Ln] = '\' then begin {Do not Localize} - LInQuotedSpecial := True; - end - else if APartString[Ln] = '"' then begin {Do not Localize} - if LInPart = 1 then begin - LParamater := Copy(APartString, LStartPos+1, Ln-LStartPos-1); - AParams.Add(ResolveQuotedSpecials(LParamater)); - LInPart := 0; - end else begin - LInQuotesInsideBrackets := False; - end; - end; - end else if LInPart = 2 then begin - //We have to watch out that we don't close this entry on a closing bracket within - //quotes, like ("Blah" "Blah)Blah"), so monitor if we are in quotes within brackets. - if APartString[Ln] = '"' then begin {Do not Localize} - LInQuotesInsideBrackets := True; - LInQuotedSpecial := False; - end - else if APartString[Ln] = '(' then begin {Do not Localize} - Inc(LBracketLevel); - end - else if APartString[Ln] = ')' then begin {Do not Localize} - Dec(LBracketLevel); - if LBracketLevel = 0 then begin - LParamater := Copy(APartString, LStartPos+1, Ln-LStartPos-1); - AParams.Add(ResolveQuotedSpecials(LParamater)); - LInPart := 0; - end; - end; - end else if LInPart = 3 then begin - if APartString[Ln] = 'L' then begin {Do not Localize} - LParamater := Copy(APartString, LStartPos, Ln-LStartPos+1); - AParams.Add(LParamater); - LInPart := 0; - end; - end else if LInPart = 4 then begin - if not IsNumeric(APartString[Ln]) then begin - LParamater := Copy(APartString, LStartPos, Ln-LStartPos); - AParams.Add(LParamater); - LInPart := 0; - end; - end else if APartString[Ln] = '"' then begin {Do not Localize} - {Start of a quoted param like "text"} - LStartPos := Ln; - LInPart := 1; - LInQuotedSpecial := False; - end else if APartString[Ln] = '(' then begin {Do not Localize} - {Start of a set of paired parameter/value strings within brackets, - such as ("charset" "us-ascii"). Note these can be nested (bracket pairs - within bracket pairs) } - LStartPos := Ln; - LInPart := 2; - LBracketLevel := 1; - LInQuotesInsideBrackets := False; - end else if TextIsSame(APartString[Ln], 'N') then begin {Do not Localize} - {Start of a NIL entry} - LStartPos := Ln; - LInPart := 3; - end else if IsNumeric(APartString[Ln]) then begin - {Start of a numeric entry like 12345} - LStartPos := Ln; - LInPart := 4; - end; - end; - {We could be in a numeric entry when we hit the end of the line...} - if LInPart = 4 then begin - LParamater := Copy(APartString, LStartPos, MaxInt); - AParams.Add(LParamater); - end; -end; - -procedure TIdIMAP4.ParseIntoBrackettedQuotedAndUnquotedParts(APartString: string; AParams: TStrings; AKeepBrackets: Boolean); -var - LInPart: Integer; - LStartPos: Integer; - //don't rename this back to LParam, that's a Windows identifier. - LParamater: string; - LBracketLevel: Integer; - Ln: Integer; - LInQuotesInsideBrackets: Boolean; - LInQuotedSpecial: Boolean; -begin - {Break: - * LIST (\UnMarked \AnotherFlag) "/" "Mailbox name" - into: - * - LIST - (\UnMarked \AnotherFlag) - "/" - "Mailbox name" - If AKeepBrackets is false, return '\UnMarked \AnotherFlag' instead of '(\UnMarked \AnotherFlag)' - } - AParams.BeginUpdate; - try - AParams.Clear; - LStartPos := 0; {Stop compiler whining} - LBracketLevel := 0; {Stop compiler whining} - LInQuotesInsideBrackets := False; {Stop compiler whining} - LInQuotedSpecial := False; {Stop compiler whining} - LInPart := 0; {0 is not in a part, 1 is in a quote-delimited part, 2 is in a bracketted part, 3 is a word} - APartString := Trim(APartString); - for Ln := 1 to Length(APartString) do begin - if (LInPart = 1) or ((LInPart = 2) and LInQuotesInsideBrackets) then begin - if LInQuotedSpecial then begin - LInQuotedSpecial := False; - end - else if APartString[Ln] = '\' then begin {Do not Localize} - LInQuotedSpecial := True; - end - else if APartString[Ln] = '"' then begin {Do not Localize} - if LInPart = 1 then begin - LParamater := Copy(APartString, LStartPos+1, Ln-LStartPos-1); - AParams.Add(ResolveQuotedSpecials(LParamater)); - LInPart := 0; - end else begin - LInQuotesInsideBrackets := False; - end; - end; - end else if LInPart = 2 then begin - //We have to watch out that we don't close this entry on a closing bracket within - //quotes, like ("Blah" "Blah)Blah"), so monitor if we are in quotes within brackets. - if APartString[Ln] = '"' then begin {Do not Localize} - LInQuotesInsideBrackets := True; - LInQuotedSpecial := False; - end - else if APartString[Ln] = '(' then begin {Do not Localize} - Inc(LBracketLevel); - end - else if APartString[Ln] = ')' then begin {Do not Localize} - Dec(LBracketLevel); - if LBracketLevel = 0 then begin - if AKeepBrackets then begin - LParamater := Copy(APartString, LStartPos, Ln-LStartPos+1); - end else begin - LParamater := Copy(APartString, LStartPos+1, Ln-LStartPos-1); - end; - AParams.Add(ResolveQuotedSpecials(LParamater)); - LInPart := 0; - end; - end; - end else if LInPart = 3 then begin - if APartString[Ln] = ' ' then begin {Do not Localize} - LParamater := Copy(APartString, LStartPos, Ln-LStartPos); - AParams.Add(LParamater); - LInPart := 0; - end; - end else if APartString[Ln] = '"' then begin {Do not Localize} - {Start of a quoted param like "text"} - LStartPos := Ln; - LInPart := 1; - LInQuotedSpecial := False; - end else if APartString[Ln] = '(' then begin {Do not Localize} - {Start of a set of paired parameter/value strings within brackets, - such as ("charset" "us-ascii"). Note these can be nested (bracket pairs - within bracket pairs) } - LStartPos := Ln; - LInPart := 2; - LBracketLevel := 1; - LInQuotesInsideBrackets := False; - end else if APartString[Ln] <> ' ' then begin {Do not Localize} - {Start of an entry like 12345} - LStartPos := Ln; - LInPart := 3; - end; - end; - {We could be in an entry when we hit the end of the line...} - if LInPart = 3 then begin - LParamater := Copy(APartString, LStartPos, MaxInt); - AParams.Add(LParamater); - end else if LInPart = 2 then begin - if AKeepBrackets then begin - LParamater := Copy(APartString, LStartPos, MaxInt); - end else begin - LParamater := Copy(APartString, LStartPos+1, MaxInt); - end; - if (not AKeepBrackets) and TextEndsWith(LParamater, ')') then begin {Do not Localize} - LParamater := Copy(LParamater, 1, Length(LParamater)-1); - end; - AParams.Add(ResolveQuotedSpecials(LParamater)); - end else if LInPart = 1 then begin - LParamater := Copy(APartString, LStartPos+1, MaxInt); - if TextEndsWith(LParamater, '"') then begin {Do not Localize} - LParamater := Copy(LParamater, 1, Length(LParamater)-1); - end; - AParams.Add(ResolveQuotedSpecials(LParamater)); - end; - finally - AParams.EndUpdate; - end; -end; - -function TIdIMAP4.ParseBodyStructureSectionAsEquates(AParam: string): string; - {Convert: - "Name1" "Value1" "Name2" "Value2" - to: - ; Name1="Value1"; Name2="Value2" - } -var - LParse: TStringList; - LN: integer; -begin - Result := ''; {Do not Localize} - if (Length(AParam) = 0) or TextIsSame(AParam, 'NIL') then begin {Do not Localize} - Exit; - end; - LParse := TStringList.Create; - try - BreakApartParamsInQuotes(AParam, LParse); - if LParse.Count < 2 then begin - Exit; - end; - if ((LParse.Count mod 2) <> 0) then begin - Exit; - end; - for LN := 0 to ((LParse.Count div 2)-1) do begin - Result := Result + '; ' + Copy(LParse[LN*2], 2, Length(LParse[LN*2])-2) + '=' + LParse[(LN*2)+1]; {Do not Localize} - end; - finally - FreeAndNil(LParse); - end; -end; - -function TIdIMAP4.ParseBodyStructureSectionAsEquates2(AParam: string): string; - {Convert: - "Name1" ("Name2" "Value2") - to: - Name1; Name2="Value2" - } -var - LParse: TStringList; - LParams: string; -begin - Result := ''; {Do not Localize} - if (Length(AParam) = 0) or TextIsSame(AParam, 'NIL') then begin {Do not Localize} - Exit; - end; - LParse := TStringList.Create; - try - BreakApart(AParam, ' ', LParse); {Do not Localize} - if LParse.Count < 3 then begin - Exit; - end; - LParams := Copy(AParam, Pos('(', AParam)+1, MaxInt); {Do not Localize} - LParams := Copy(LParams, 1, Length(LParams)-1); - LParams := ParseBodyStructureSectionAsEquates(LParams); - if Length(LParams) = 0 then begin {Do not Localize} - Result := Copy(LParse[0], 2, Length(LParse[0])-2) + LParams; - end; - finally - FreeAndNil(LParse); - end; -end; - -function TIdIMAP4.GetNextWord(AParam: string): string; -var - LPos: integer; -begin - Result := ''; {Do not Localize} - AParam := Trim(AParam); - LPos := Pos(' ', AParam); {Do not Localize} - if LPos = 0 then begin - Exit; - end; - Result := Copy(AParam, 1, LPos-1); -end; - -function TIdIMAP4.GetNextQuotedParam(AParam: string; ARemoveQuotes: Boolean): string; -{If AParam is: -"file name.ext" NIL NIL -then this returns: -"file name.ext" -Note it returns the quotes, UNLESS ARemoveQuotes is True. -Also note that if AParam does NOT start with a quote, it returns the next word. -} -var - LN: integer; - LPos: integer; -begin - Result := ''; - {CCB: Modified code so it did not access past the end of the string if - AParam was not actually in quotes (e.g. the MIME boundary parameter - is only optionally in quotes).} - LN := 1; - {Skip any preceding spaces...} - //TODO: use TrimLeft(AParam) instead - while (LN <= Length(AParam)) and (AParam[LN] = ' ') do begin {Do not Localize} - LN := LN + 1; - end; - if LN > Length(AParam) then begin - Exit; - end; - if AParam[LN] <> '"' then begin {Do not Localize} - {Not actually enclosed in quotes. Must be a single word.} - // TODO: use Fetch(AParam) instead - AParam := Copy(AParam, LN, MaxInt); - LPos := Pos(' ', AParam); {Do not Localize} - if LPos > 0 then begin - {Strip off this word...} - Result := Copy(AParam, 1, LPos-1); - end else begin - {This is the last word on the line, return it all...} - Result := AParam; - end; - end else begin - {It starts with a quote...} - // TODO: use Fetch(AParam, '"') instead - // TODO: do we need to handle escaped characters? - AParam := Copy(AParam, LN, MaxInt); - LN := 2; - while (LN <= Length(AParam)) and (AParam[LN] <> '"') do begin {Do not Localize} - LN := LN + 1; - end; - Result := Copy(AParam, 1, LN); - if ARemoveQuotes then begin - Result := Copy(Result, 2, Length(Result)-2); - end; - end; -end; - -procedure TIdIMAP4.BreakApartParamsInQuotes(const AParam: string; AParsedList: TStrings); -var - Ln : Integer; - LStartPos: Integer; -begin - LStartPos := -1; - AParsedList.BeginUpdate; - try - AParsedList.Clear; - for Ln := 1 to Length(AParam) do begin - if AParam[LN] = '"' then begin {Do not Localize} - if LStartPos > -1 then begin - {The end of a quoted parameter...} - AParsedList.Add(Copy(AParam, LStartPos, LN-LStartPos+1)); - LStartPos := -1; - end else begin - {The start of a quoted parameter...} - LStartPos := Ln; - end; - end; - end; - finally - AParsedList.EndUpdate; - end; -end; - -procedure TIdIMAP4.ParseExpungeResult(AMB: TIdMailBox; ACmdResultDetails: TStrings); -var - Ln, LCnt: Integer; - LSlExpunge : TStringList; -begin - SetLength(AMB.DeletedMsgs, 0); - if ACmdResultDetails.Count > 0 then begin - LSlExpunge := TStringList.Create; - try - // TODO: count the number of EXPUNGE entries and allocate the DeletedMsgs array one time... - LCnt := 0; - try - for Ln := 0 to ACmdResultDetails.Count - 1 do begin - // TODO: maybe use Fetch() instead and get rid of the TStringList altogether? - BreakApart(ACmdResultDetails[Ln], ' ', LSlExpunge); {Do not Localize} - if LSlExpunge.Count > 1 then begin - if TextIsSame(LSlExpunge[1], IMAP4Commands[cmdExpunge]) then begin - SetLength(AMB.DeletedMsgs, LCnt + 1); - AMB.DeletedMsgs[LCnt] := UInt32(IndyStrToInt64(LSlExpunge[0])); - Inc(LCnt); - end; - end; - LSlExpunge.Clear; - end; - finally - SetLength(AMB.DeletedMsgs, LCnt); - end; - finally - FreeAndNil(LSlExpunge); - end; - end; -end; - -procedure TIdIMAP4.ParseMessageFlagString(AFlagsList: String; var AFlags: TIdMessageFlagsSet); - {CC5: Note this only supports the system flags defined in RFC 2060.} -var - LSlFlags : TStringList; - Ln, I : Integer; -begin - AFlags := []; - LSlFlags := TStringList.Create; - try - BreakApart(AFlagsList, ' ', LSlFlags); {Do not Localize} - for Ln := 0 to LSlFlags.Count-1 do begin - I := PosInStrArray( - LSlFlags[Ln], - [MessageFlags[mfAnswered], MessageFlags[mfFlagged], MessageFlags[mfDeleted], MessageFlags[mfDraft], MessageFlags[mfSeen], MessageFlags[mfRecent]], - False); - case I of - 0..5: Include(AFlags, TIdMessageFlags(I)); - end; - end; - finally - FreeAndNil(LSlFlags); - end; -end; - -procedure TIdIMAP4.ParseMailBoxAttributeString(AAttributesList: String; var AAttributes: TIdMailBoxAttributesSet); -var - LSlAttributes : TStringList; - Ln : Integer; - I: Integer; -begin - AAttributes := []; - LSlAttributes := TStringList.Create; - try - BreakApart(AAttributesList, ' ', LSlAttributes); {Do not Localize} - for Ln := 0 to LSlAttributes.Count - 1 do begin - I := PosInStrArray( - LSlAttributes[Ln], - [MailBoxAttributes[maNoinferiors], MailBoxAttributes[maNoselect], MailBoxAttributes[maMarked], MailBoxAttributes[maUnmarked]], - False); - case I of - 0..3: Include(AAttributes, TIdMailBoxAttributes(I)); - end; - end; - finally - FreeAndNil(LSlAttributes); - end; -end; - -procedure TIdIMAP4.ParseSearchResult(AMB: TIdMailBox; ACmdResultDetails: TStrings); -var - Ln, LCnt: Integer; - LSlSearch: TStringList; -begin - SetLength(AMB.SearchResult, 0); - if ACmdResultDetails.Count > 0 then begin - LSlSearch := TStringList.Create; - try - // TODO: maybe use a Fetch() loop instead and get rid of the TStringList altogether? - BreakApart(ACmdResultDetails[0], ' ', LSlSearch); {Do not Localize} - if LSlSearch.Count > 0 then begin - if TextIsSame(LSlSearch[0], IMAP4Commands[cmdSearch]) then begin - SetLength(AMB.SearchResult, LSlSearch.Count - 1); - LCnt := 0; - try - for Ln := 1 to LSlSearch.Count - 1 do - begin - // TODO: for a UID search, store LSlSearch[Ln] as-is without converting it to an Integer... - AMB.SearchResult[LCnt] := UInt32(IndyStrToInt64(LSlSearch[Ln])); - Inc(LCnt); - end; - finally - SetLength(AMB.SearchResult, LCnt); - end; - end; - end; - finally - FreeAndNil(LSlSearch); - end; - end; -end; - -procedure TIdIMAP4.ParseStatusResult(AMB: TIdMailBox; ACmdResultDetails: TStrings); -var - Ln: Integer; - LRespStr : String; - LStatStr: String; - LStatPos: Integer; - LSlStatus : TStringList; -begin - LSlStatus := TStringList.Create; - try - if ACmdResultDetails.Count > 0 then - begin - // TODO: convert server response to uppercase? - LRespStr := Trim(ACmdResultDetails[0]); - LStatPos := Pos(IMAP4Commands[cmdStatus], LRespStr); - if (LStatPos > 0) then - begin - LStatStr := Trim(Copy(LRespStr, - LStatPos+Length(IMAP4Commands[cmdStatus]), Length(LRespStr))); - AMB.Name := Trim(Fetch(LStatStr, '(', True)); {do not localize} - if TextEndsWith(LStatStr, ')') then begin {do not localize} - IdDelete(LStatStr, Length(LStatStr), 1); - end; - BreakApart(LStatStr, ' ', LSlStatus); {do not localize} - // find status data items by name, values are on following line - Ln := LSlStatus.IndexOf(IMAP4StatusDataItem[mdMessages]); - if Ln <> -1 then begin - AMB.TotalMsgs := IndyStrToInt(LSlStatus[Ln + 1]); - end; - Ln := LSlStatus.IndexOf(IMAP4StatusDataItem[mdRecent]); - if Ln <> -1 then begin - AMB.RecentMsgs := IndyStrToInt(LSlStatus[Ln + 1]); - end; - Ln := LSlStatus.IndexOf(IMAP4StatusDataItem[mdUnseen]); - if Ln <> -1 then begin - AMB.UnseenMsgs := IndyStrToInt(LSlStatus[Ln + 1]); - end; - Ln := LSlStatus.IndexOf(IMAP4StatusDataItem[mdUIDNext]); - if Ln <> -1 then begin - AMB.UIDNext := LSlStatus[Ln + 1]; - end; - Ln := LSlStatus.IndexOf(IMAP4StatusDataItem[mdUIDValidity]); - if Ln <> -1 then begin - AMB.UIDValidity := LSlStatus[Ln + 1]; - end; - end; - end; - finally - FreeAndNil(LSlStatus); - end; -end; - -procedure TIdIMAP4.ParseSelectResult(AMB : TIdMailBox; ACmdResultDetails: TStrings); -var - Ln : Integer; - LStr : String; - LFlags: TIdMessageFlagsSet; - LLine: String; - LPos: Integer; -begin - AMB.Clear; - for Ln := 0 to ACmdResultDetails.Count - 1 do begin - LLine := ACmdResultDetails[Ln]; - LPos := Pos(' EXISTS', LLine); {Do not Localize} - if LPos > 0 then begin - AMB.TotalMsgs := IndyStrToInt(Copy(LLine, 1, LPos - 1)); - Continue; - end; - LPos := Pos(' RECENT', LLine); {Do not Localize} - if LPos > 0 then begin - AMB.RecentMsgs := IndyStrToInt(Copy(LLine, 1, LPos - 1)); {Do not Localize} - Continue; - end; - LPos := Pos('[UIDVALIDITY ', LLine); {Do not Localize} - if LPos > 0 then begin - Inc(LPos, 13); - AMB.UIDValidity := Trim(Copy(LLine, LPos, (Integer(PosIdx(']', LLine, LPos)) - LPos))); {Do not Localize} - Continue; - end; - LPos := Pos('[UIDNEXT ', LLine); {Do not Localize} - if LPos > 0 then begin - Inc(LPos, 9); - AMB.UIDNext := Trim(Copy(LLine, LPos, (Integer(PosIdx(']', LLine, LPos)) - LPos))); {Do not Localize} - Continue; - end; - LPos := Pos('[PERMANENTFLAGS ', LLine); {Do not Localize} - if LPos > 0 then begin {Do not Localize} - LPos := PosIdx('(', LLine, LPos + 16) + 1; {Do not Localize} - ParseMessageFlagString(Copy(LLine, LPos, Integer(PosIdx(')', LLine, LPos)) - LPos), LFlags); {Do not Localize} - AMB.ChangeableFlags := LFlags; - Continue; - end; - LPos := Pos('FLAGS ', LLine); {Do not Localize} - if LPos > 0 then begin - LPos := PosIdx('(', LLine, LPos + 6) + 1; {Do not Localize} - ParseMessageFlagString(Copy(LLine, LPos, (Integer(PosIdx(')', LLine, LPos)) - LPos)), LFlags); {Do not Localize} - AMB.Flags := LFlags; - Continue; - end; - LPos := Pos('[UNSEEN ', LLine); {Do not Localize} - if LPos> 0 then begin - Inc(LPos, 8); - AMB.FirstUnseenMsg := UInt32(IndyStrToInt64(Copy(LLine, LPos, (Integer(PosIdx(']', LLine, LPos)) - LPos)))); {Do not Localize} - Continue; - end; - LPos := Pos('[READ-', LLine); {Do not Localize} - if LPos > 0 then begin - Inc(LPos, 6); - LStr := Trim(Copy(LLine, LPos, Integer(PosIdx(']', LLine, LPos)) - LPos)); {Do not Localize} - {CCB: AMB.State ambiguous unless coded response received - default to msReadOnly...} - if TextIsSame(LStr, 'WRITE') then begin {Do not Localize} - AMB.State := msReadWrite; - end else {if TextIsSame(LStr, 'ONLY') then} begin {Do not Localize} - AMB.State := msReadOnly; - end; - Continue; - end; - LPos := Pos('[ALERT]', LLine); {Do not Localize} - if LPos > 0 then begin - LStr := Trim(Copy(LLine, LPos + 7, MaxInt)); - if Length(LStr) <> 0 then begin - DoAlert(LStr); - end; - Continue; - end; - end; -end; - -procedure TIdIMAP4.ParseListResult(AMBList: TStrings; ACmdResultDetails: TStrings); -begin - InternalParseListResult(IMAP4Commands[cmdList], AMBList, ACmdResultDetails); -end; - -procedure TIdIMAP4.InternalParseListResult(ACmd: string; AMBList: TStrings; ACmdResultDetails: TStrings); -var Ln : Integer; - LSlRetrieve : TStringList; - LStr : String; - LWord: string; -begin - AMBList.BeginUpdate; - try - AMBList.Clear; - LSlRetrieve := TStringList.Create; - try - for Ln := 0 to ACmdResultDetails.Count - 1 do begin - LStr := ACmdResultDetails[Ln]; - //Todo: Get mail box attributes here - {CC2: Could put mailbox attributes in AMBList's Objects property?} - {The line is of the form: - * LIST (\UnMarked \AnotherFlag) "/" "Mailbox name" - } - {CCA: code modified because some servers return NIL as the mailbox - separator, i.e.: - * LIST (\UnMarked \AnotherFlag) NIL "Mailbox name" - } - - ParseIntoBrackettedQuotedAndUnquotedParts(LStr, LSlRetrieve, False); - if LSlRetrieve.Count > 3 then begin - //Make sure 1st word is LIST (may be an unsolicited response)... - if TextIsSame(LSlRetrieve[0], {IMAP4Commands[cmdList]} ACmd) then begin - {Get the mailbox separator...} - LWord := Trim(LSlRetrieve[LSlRetrieve.Count-2]); - if TextIsSame(LWord, 'NIL') or (LWord = '') then begin {Do not Localize} - FMailBoxSeparator := #0; - end else begin - FMailBoxSeparator := LWord[1]; - end; - {Now get the mailbox name...} - LWord := Trim(LSlRetrieve[LSlRetrieve.Count-1]); - AMBList.Add(DoMUTFDecode(LWord)); - end; - end; - end; - finally - FreeAndNil(LSlRetrieve); - end; - finally - AMBList.EndUpdate; - end; -end; - -procedure TIdIMAP4.ParseLSubResult(AMBList: TStrings; ACmdResultDetails: TStrings); -begin - InternalParseListResult(IMAP4Commands[cmdLSub], AMBList, ACmdResultDetails); -end; - -procedure TIdIMAP4.ParseEnvelopeResult(AMsg: TIdMessage; ACmdResultStr: String); - - procedure DecodeEnvelopeAddress(const AAddressStr: String; AEmailAddressItem: TIdEmailAddressItem); overload; - var - LStr, LTemp: String; - I: Integer; - {$IFNDEF DOTNET} - LPChar: PChar; - {$ENDIF} - begin - if TextStartsWith(AAddressStr, '(') and TextEndsWith(AAddressStr, ')') and {Do not Localize} - Assigned(AEmailAddressItem) then begin - LStr := Copy(AAddressStr, 2, Length (AAddressStr) - 2); - //Gets the name part - if TextStartsWith(LStr, 'NIL ') then begin {Do not Localize} - LStr := Copy(LStr, 5, MaxInt); {Do not Localize} - end - else if TextStartsWith(LStr, '{') then begin {Do not Localize} - LStr := Copy(LStr, Pos('}', LStr) + 1, MaxInt); {Do not Localize} - I := Pos('" ', LStr); - AEmailAddressItem.Name := Copy(LStr, 1, I-1); {Do not Localize} - LStr := Copy(LStr, I+2, MaxInt); {Do not Localize} - end else begin - I := Pos('" ', LStr); - LTemp := Copy(LStr, 1, I); - {$IFDEF DOTNET} - AEmailAddressItem.Name := Copy(LTemp, 2, Length(LTemp)-2); {ExtractQuotedStr ( LTemp, '"' ); {Do not Localize} - {$ELSE} - LPChar := PChar(LTemp); - AEmailAddressItem.Name := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} - {$ENDIF} - LStr := Copy(LStr, I+2, MaxInt); {Do not Localize} - end; - //Gets the source root part - if TextStartsWith(LStr, 'NIL ') then begin {Do not Localize} - LStr := Copy(LStr, 5, MaxInt); {Do not Localize} - end else begin - I := Pos('" ', LStr); - LTemp := Copy(LStr, 1, I); - {$IFDEF DOTNET} - AEmailAddressItem.Name := Copy(LTemp, 2, Length(LTemp)-2); {AnsiExtractQuotedStr ( LTemp, '"' ); {Do not Localize} - {$ELSE} - LPChar := PChar(LTemp); - AEmailAddressItem.Name := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} - {$ENDIF} - LStr := Copy(LStr, I+2, MaxInt); {Do not Localize} - end; - //Gets the mailbox name part - if TextStartsWith(LStr, 'NIL ') then begin {Do not Localize} - LStr := Copy(LStr, 5, MaxInt); {Do not Localize} - end else begin - I := Pos('" ', LStr); - LTemp := Copy(LStr, 1, I); {Do not Localize} - {$IFDEF DOTNET} - AEmailAddressItem.Address := Copy(LTemp, 2, Length(LTemp)-2); {AnsiExtractQuotedStr ( LTemp, '"' ); {Do not Localize} - {$ELSE} - LPChar := PChar(LTemp); - AEmailAddressItem.Address := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} - {$ENDIF} - LStr := Copy(LStr, I+2, MaxInt); {Do not Localize} - end; - //Gets the host name part - if not TextIsSame(LStr, 'NIL') then begin {Do not Localize} - LTemp := Copy(LStr, 1, MaxInt); - {$IFDEF DOTNET} - AEmailAddressItem.Address := AEmailAddressItem.Address + '@' + {Do not Localize} - Copy(LTemp, 2, Length(LTemp)-2); {AnsiExtractQuotedStr ( LTemp, '"' ); {Do not Localize} - {$ELSE} - LPChar := PChar(LTemp); - AEmailAddressItem.Address := AEmailAddressItem.Address + '@' + {Do not Localize} - AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} - {$ENDIF} - end; - end; - end; - - procedure DecodeEnvelopeAddress(const AAddressStr: String; AEmailAddressList: TIdEmailAddressList); overload; - var - LStr: String; - I: Integer; - begin - if TextStartsWith(AAddressStr, '(') and TextEndsWith(AAddressStr, ')') and {Do not Localize} - Assigned(AEmailAddressList) then begin - LStr := Copy(AAddressStr, 2, Length (AAddressStr) - 2); - repeat - I := Pos(')', LStr); - if I = 0 then begin - Break; - end; - DecodeEnvelopeAddress(Copy(LStr, 1, I), AEmailAddressList.Add); {Do not Localize} - LStr := Trim(Copy(LStr, I+1, MaxInt)); {Do not Localize} - until False; - end; - end; - -var - LStr, LTemp: String; - I: Integer; - {$IFNDEF DOTNET} - LPChar: PChar; - {$ENDIF} -begin - //The fields of the envelope structure are in the - //following order: date, subject, from, sender, - //reply-to, to, cc, bcc, in-reply-to, and message-id. - //The date, subject, in-reply-to, and message-id - //fields are strings. The from, sender, reply-to, - //to, cc, and bcc fields are parenthesized lists of - //address structures. - - //An address structure is a parenthesized list that - //describes an electronic mail address. The fields - //of an address structure are in the following order: - //personal name, [SMTP] at-domain-list (source - //route), mailbox name, and host name. - - //* 4 FETCH (ENVELOPE ("Sun, 15 Jul 2001 02:56:45 -0700 (PDT)" "Your Borland Commu - //nity Account Activation Code" (("Borland Community" NIL "mailbot" "borland.com") - //) NIL NIL (("" NIL "name" "company.com")) NIL NIL NIL "<200107150956.CAA1 - //8152@borland.com>")) - - {CC5: Cleared out any existing fields to avoid mangling new entries with old/stale ones.} - //Extract envelope date field - AMsg.Date := 0; - if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} - ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); - end else begin - I := Pos('" ', ACmdResultStr); {Do not Localize} - LTemp := Copy(ACmdResultStr, 1, I); - {$IFDEF DOTNET} - LStr := Copy(LTemp, 2, Length(LTemp)-2); - {$ELSE} - LPChar := PChar(LTemp); - LStr := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} - {$ENDIF} - AMsg.Date := GMTToLocalDateTime(LStr); - ACmdResultStr := Copy(ACmdResultStr, I+2, MaxInt); - end; - //Extract envelope subject field - AMsg.Subject := ''; {Do not Localize} - if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} - ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); - end else begin - if TextStartsWith(ACmdResultStr, '{') then begin {Do not Localize} - ACmdResultStr := Copy(ACmdResultStr, Pos('}', ACmdResultStr) + 1, MaxInt); {Do not Localize} - I := Pos(' ', ACmdResultStr); {Do not Localize} - LStr := Copy(ACmdResultStr, 1, I-1); - AMsg.Subject := LStr; - ACmdResultStr := Copy(ACmdResultStr, I+1, MaxInt); {Do not Localize} - end else begin - I := Pos('" ', ACmdResultStr); {Do not Localize} - LTemp := Copy(ACmdResultStr, 1, I); - {$IFDEF DOTNET} - LStr := Copy(LTemp, 2, Length(LTemp)-2); - {$ELSE} - LPChar := PChar(LTemp); - LStr := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} - {$ENDIF} - AMsg.Subject := LStr; - ACmdResultStr := Copy(ACmdResultStr, I+2, MaxInt); {Do not Localize} - end; - end; - //Extract envelope from field - AMsg.FromList.Clear; - if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} - ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); - end else begin - I := Pos(')) ', ACmdResultStr); {Do not Localize} - LStr := Copy(ACmdResultStr, 1, I+1); - DecodeEnvelopeAddress(LStr, AMsg.FromList); - ACmdResultStr := Copy(ACmdResultStr, I+3, MaxInt); - end; - //Extract envelope sender field - AMsg.Sender.Name := ''; {Do not Localize} - AMsg.Sender.Address := ''; {Do not Localize} - if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} - ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); - end else begin - {CC5: Fix parsing of sender...} - I := Pos(')) ', ACmdResultStr); - LStr := Copy(ACmdResultStr, 2, I-1); - DecodeEnvelopeAddress(LStr, AMsg.Sender); - ACmdResultStr := Copy(ACmdResultStr, I+3, MaxInt); - end; - //Extract envelope reply-to field - AMsg.ReplyTo.Clear; - if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} - ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); - end else begin - I := Pos(')) ', ACmdResultStr); {Do not Localize} - LStr := Copy(ACmdResultStr, 1, I+1); - DecodeEnvelopeAddress(LStr, AMsg.ReplyTo); - ACmdResultStr := Copy(ACmdResultStr, I+3, MaxInt); - end; - //Extract envelope to field - AMsg.Recipients.Clear; - if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} - ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); - end else begin - I := Pos(')) ', ACmdResultStr); {Do not Localize} - LStr := Copy(ACmdResultStr, 1, I+1); - DecodeEnvelopeAddress(LStr, AMsg.Recipients); - ACmdResultStr := Copy(ACmdResultStr, I+3, MaxInt); - end; - //Extract envelope cc field - AMsg.CCList.Clear; - if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} - ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); - end else begin - I := Pos(')) ', ACmdResultStr); {Do not Localize} - LStr := Copy(ACmdResultStr, 1, I+1); - DecodeEnvelopeAddress(LStr, AMsg.CCList); - ACmdResultStr := Copy(ACmdResultStr, I+3, MaxInt); - end; - //Extract envelope bcc field - AMsg.BccList.Clear; - if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} - ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); - end else begin - I := Pos(')) ', ACmdResultStr); {Do not Localize} - LStr := Copy(ACmdResultStr, 1, I+1); - DecodeEnvelopeAddress(LStr, AMsg.BccList); - ACmdResultStr := Copy(ACmdResultStr, I+3, MaxInt); - end; - //Extract envelope in-reply-to field - if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} - ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); - end else begin - I := Pos('" ', ACmdResultStr); {Do not Localize} - LTemp := Copy(ACmdResultStr, 1, I); - {$IFDEF DOTNET} - LStr := Copy(LTemp, 2, Length(LTemp)-2); - {$ELSE} - LPChar := PChar(LTemp); - LStr := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} - {$ENDIF} - AMsg.InReplyTo := LStr; - ACmdResultStr := Copy(ACmdResultStr, I+2, MaxInt); - end; - //Extract envelope message-id field - AMsg.MsgId := ''; {Do not Localize} - if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} - ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); - end else begin - {$IFDEF DOTNET} - LStr := Copy(ACmdResultStr, 2, Length(ACmdResultStr)-2); - {$ELSE} - LPChar := PChar(ACmdResultStr); - LStr := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} - {$ENDIF} - AMsg.MsgId := Trim(LStr); - end; -end; - -function TIdIMAP4.ParseLastCmdResult(ALine: string; AExpectedCommand: string; AExpectedIMAPFunction: array of string): Boolean; -var - LPos: integer; - LWord: string; - LWords: TStringList; - LN: Integer; - LWordInExpectedIMAPFunction: Boolean; -begin - Result := False; - LWordInExpectedIMAPFunction := False; - FLineStruct.HasStar := False; - FLineStruct.MessageNumber := ''; - FLineStruct.Command := ''; - FLineStruct.UID := ''; - FLineStruct.Flags := []; - FLineStruct.FlagsStr := ''; - FLineStruct.Complete := True; - FLineStruct.IMAPFunction := ''; - FLineStruct.IMAPValue := ''; - FLineStruct.ByteCount := -1; - FLineStruct.GmailMsgID := ''; - FLineStruct.GmailThreadID := ''; - FLineStruct.GmailLabels := ''; - ALine := Trim(ALine); //Can get garbage like a spurious CR at start - //Look for (optional) * at start... - LPos := Pos(' ', ALine); {Do not Localize} - if LPos < 1 then begin - Exit; //Nothing on this line - end; - LWord := Copy(ALine, 1, LPos-1); - if LWord = '*' then begin {Do not Localize} - FLineStruct.HasStar := True; - ALine := Copy(ALine, LPos+1, MaxInt); - LPos := Pos(' ', ALine); {Do not Localize} - if LPos < 1 then begin - Exit; //Line ONLY had a * - end; - LWord := Copy(ALine, 1, LPos-1); - end; - //Look for (optional) message number next... - if IsNumeric(LWord) then begin - FLineStruct.MessageNumber := LWord; - ALine := Copy(ALine, LPos+1, MaxInt); - LPos := Pos(' ', ALine); {Do not Localize} - if LPos < 1 then begin - Exit; //Line ONLY had a * 67 - end; - LWord := Copy(ALine, 1, LPos-1); - end; - //We should have a valid IMAP command word now, like FETCH, LIST or SEARCH... - if PosInStrArray(LWord, IMAP4Commands) = -1 then begin - Exit; //Should have been a command, give up. - end; - FLineStruct.Command := LWord; - if ((AExpectedCommand = '') or (FLineStruct.Command = AExpectedCommand)) then begin - Result := True; - end; - ALine := Copy(ALine, Length(LWord)+2, MaxInt); - if ALine[1] <> '(' then begin {Do not Localize} - //This is a line like '* SEARCH 34 56', the '34 56' is the value (result)... - FLineStruct.IMAPValue := ALine; - Exit; - end; - //This is a line like '* 9 FETCH (UID 47 RFC822.SIZE 3456)', i.e. with a bracketted response. - //See is it complete (has a closing bracket) or does it continue on other lines... - ALine := Copy(ALine, 2, MaxInt); - if TextEndsWith(ALine, ')') then begin {Do not Localize} - ALine := Copy(ALine, 1, Length(ALine) - 1); //Strip trailing bracket - FLineStruct.Complete := True; - end else begin - FLineStruct.Complete := False; - end; - //These words left may occur in different order. Find & delete those we know. - LWords := TStringList.Create; - try - ParseIntoBrackettedQuotedAndUnquotedParts(ALine, LWords, False); - if LWords.Count > 0 then begin - //See does it have a trailing byte count... - LWord := LWords[LWords.Count-1]; - if TextStartsWith(LWord, '{') and TextEndsWith(LWord, '}') then begin - //It ends in a byte count... - LWord := Copy(LWord, 2, Length(LWord)-2); - if TextIsSame(LWord, 'NIL') then begin {do not localize} - FLineStruct.ByteCount := 0; - end else begin - FLineStruct.ByteCount := IndyStrToInt(LWord); - end; - LWords.Delete(LWords.Count-1); - end; - end; - if not FLineStruct.Complete then begin - //The command in this case should be the last word... - if LWords.Count > 0 then begin - FLineStruct.IMAPFunction := LWords[LWords.Count-1]; - LWords.Delete(LWords.Count-1); - end; - end; - //See is the UID present... - LPos := LWords.IndexOf(IMAP4FetchDataItem[fdUID]); {Do not Localize} - if LPos <> -1 then begin - //The UID is the word after 'UID'... - if LPos < LWords.Count-1 then begin - FLineStruct.UID := LWords[LPos+1]; - LWords.Delete(LPos+1); - LWords.Delete(LPos); - end; - if PosInStrArray(IMAP4FetchDataItem[fdUID], AExpectedIMAPFunction) > -1 then begin - LWordInExpectedIMAPFunction := True; - end; - end; - //See are the FLAGS present... - LPos := LWords.IndexOf(IMAP4FetchDataItem[fdFlags]); {Do not Localize} - if LPos <> -1 then begin - //The FLAGS are in the "word" (really a string) after 'FLAGS'... - if LPos < LWords.Count-1 then begin - FLineStruct.FlagsStr := LWords[LPos+1]; - ParseMessageFlagString(FLineStruct.FlagsStr, FLineStruct.Flags); - LWords.Delete(LPos+1); - LWords.Delete(LPos); - end; - if PosInStrArray(IMAP4FetchDataItem[fdFlags], AExpectedIMAPFunction) > -1 then begin - LWordInExpectedIMAPFunction := True; - end; - end; - //See is the X-GM-MSGID present... - LPos := LWords.IndexOf(IMAP4FetchDataItem[fdGmailMsgID]); {Do not Localize} - if LPos <> -1 then begin - //The MSGID is in the "word" (really a string) after 'X-GM-MSGID'... - if LPos < LWords.Count-1 then begin - FLineStruct.GmailMsgID := LWords[LPos+1]; - LWords.Delete(LPos+1); - LWords.Delete(LPos); - end; - if PosInStrArray(IMAP4FetchDataItem[fdGmailMsgID], AExpectedIMAPFunction) > -1 then begin - LWordInExpectedIMAPFunction := True; - end; - end; - //See is the X-GM-THRID present... - LPos := LWords.IndexOf(IMAP4FetchDataItem[fdGmailThreadID]); {Do not Localize} - if LPos <> -1 then begin - //The THREADID is in the "word" (really a string) after 'X-GM-THRID'... - if LPos < LWords.Count-1 then begin - FLineStruct.GmailThreadID := LWords[LPos+1]; - LWords.Delete(LPos+1); - LWords.Delete(LPos); - end; - if PosInStrArray(IMAP4FetchDataItem[fdGmailThreadID], AExpectedIMAPFunction) > -1 then begin - LWordInExpectedIMAPFunction := True; - end; - end; - //See is the X-GM-LABELS present... - LPos := LWords.IndexOf(IMAP4FetchDataItem[fdGmailLabels]); {Do not Localize} - if LPos <> -1 then begin - //The LABELS is in the "word" (really a string) after 'X-GM-LABELS'... - if LPos < LWords.Count-1 then begin - FLineStruct.GmailLabels := DoMUTFDecode(LWords[LPos+1]); - LWords.Delete(LPos+1); - LWords.Delete(LPos); - end; - if PosInStrArray(IMAP4FetchDataItem[fdGmailLabels], AExpectedIMAPFunction) > -1 then begin - LWordInExpectedIMAPFunction := True; - end; - end; - if Length(AExpectedIMAPFunction) > 0 then begin - //See is what we want present. - for LN := 0 to Length(AExpectedIMAPFunction)-1 do begin - //First check if we got it already in IMAPFunction... - if TextIsSame(FLineStruct.IMAPFunction, AExpectedIMAPFunction[LN]) then begin - LWordInExpectedIMAPFunction := True; - Break; - end; - //Now check if it is in any remaining words... - LPos := LWords.IndexOf(AExpectedIMAPFunction[LN]); {Do not Localize} - if LPos <> -1 then begin - FLineStruct.IMAPFunction := LWords[LPos]; - LWordInExpectedIMAPFunction := True; - if LPos < LWords.Count-1 then begin - //There is a parameter after our function... - FLineStruct.IMAPValue := LWords[LPos+1]; - end; - Break; - end; - end; - end else begin - //See is there function/value items left. There may not be, such as - //'* 9 FETCH (UID 45)' in response to a GetUID request. - if FLineStruct.Complete then begin - if LWords.Count > 1 then begin - FLineStruct.IMAPFunction := LWords[LWords.Count-2]; - FLineStruct.IMAPValue := LWords[LWords.Count-1]; - end; - end; - end; - Result := False; - if (AExpectedCommand = '') or (FLineStruct.Command = AExpectedCommand) then begin - //The AExpectedCommand is correct, now need to check the AExpectedIMAPFunction... - if (Length(AExpectedIMAPFunction) = 0) or LWordInExpectedIMAPFunction then begin - Result := True; - end; - end; - finally - FreeAndNil(LWords); - end; -end; - -{This ADDS any parseable info from ALine to FLineStruct (set up from a previous ParseLastCmdResult call)} -procedure TIdIMAP4.ParseLastCmdResultButAppendInfo(ALine: string); -var - LPos: integer; - LWords: TStringList; -begin - ALine := Trim(ALine); //Can get garbage like a spurious CR at start - {We may have an initial or ending bracket, like ") UID 5" or "UID 5)"} - if TextStartsWith(ALine, ')') then begin {Do not Localize} - ALine := Trim(Copy(ALine, 2, MaxInt)); - end; - if TextEndsWith(ALine, ')') then begin {Do not Localize} - ALine := Trim(Copy(ALine, 1, Length(ALine)-1)); - end; - //These words left may occur in different order. Find & delete those we know. - LWords := TStringList.Create; - try - ParseIntoBrackettedQuotedAndUnquotedParts(ALine, LWords, False); - //See is the UID present... - LPos := LWords.IndexOf('UID'); {Do not Localize} - if LPos <> -1 then begin - //The UID is the word after 'UID'... - FLineStruct.UID := LWords[LPos+1]; - LWords.Delete(LPos+1); - LWords.Delete(LPos); - end; - //See are the FLAGS present... - LPos := LWords.IndexOf('FLAGS'); {Do not Localize} - if LPos <> -1 then begin - //The FLAGS are in the "word" (really a string) after 'FLAGS'... - FLineStruct.FlagsStr := LWords[LPos+1]; - ParseMessageFlagString(FLineStruct.FlagsStr, FLineStruct.Flags); - LWords.Delete(LPos+1); - LWords.Delete(LPos); - end; - finally - FreeAndNil(LWords); - end; -end; - -{ ...Parser Functions } - -function TIdIMAP4.ArrayToNumberStr(const AMsgNumList: array of UInt32): String; -var - Ln : Integer; -begin - for Ln := 0 to Length(AMsgNumList) - 1 do begin - Result := Result + IntToStr(Int64(AMsgNumList[Ln])) + ','; {Do not Localize} - end; - SetLength(Result, (Length(Result) - 1 )); -end; - -function TIdIMAP4.MessageFlagSetToStr(const AFlags: TIdMessageFlagsSet): String; -begin - Result := ''; - if AFlags = [] then begin - Exit; - end; - if mfAnswered in AFlags then begin - Result := Result + MessageFlags[mfAnswered] + ' '; {Do not Localize} - end; - if mfFlagged in AFlags then begin - Result := Result + MessageFlags[mfFlagged] + ' '; {Do not Localize} - end; - if mfDeleted in AFlags then begin - Result := Result + MessageFlags[mfDeleted] + ' '; {Do not Localize} - end; - if mfDraft in AFlags then begin - Result := Result + MessageFlags[mfDraft] + ' '; {Do not Localize} - end; - if mfSeen in AFlags then begin - Result := Result + MessageFlags[mfSeen] + ' '; {Do not Localize} - end; - Result := Trim(Result); -end; - -procedure TIdIMAP4.StripCRLFs(ASourceStream, ADestStream: TStream); -var - LByte: TIdBytes; - LNumSourceBytes: TIdStreamSize; - LBytesRead: Int64; -begin - SetLength(LByte, 1); - ASourceStream.Position := 0; - ADestStream.Size := 0; - LNumSourceBytes := ASourceStream.Size; - LBytesRead := 0; - while LBytesRead < LNumSourceBytes do begin - TIdStreamHelper.ReadBytes(ASourceStream, LByte, 1); - if not ByteIsInEOL(LByte, 0) then begin - TIdStreamHelper.Write(ADestStream, LByte, 1); - end; - Inc(LBytesRead); - end; -end; - -procedure TIdIMAP4.StripCRLFs(var AText: string); -var - LPos: integer; - LLen: integer; - LTemp: string; - LDestPos: integer; -begin - //Optimised with the help of Guus Creuwels. - LPos := 1; - LLen := Length(AText); - SetLength(LTemp, LLen); - LDestPos := 1; - while LPos <= LLen do begin - if AText[LPos] = #13 then begin - //Don't GPF if this is the last char in the string... - if LPos < LLen then begin - if AText[LPos+1] = #10 then begin - Inc(LPos, 2); - end else begin - LTemp[LDestPos] := AText[LPos]; - Inc(LPos); - Inc(LDestPos); - end; - end else begin - LTemp[LDestPos] := AText[LPos]; - Inc(LPos); - Inc(LDestPos); - end; - end else begin - LTemp[LDestPos] := AText[LPos]; - Inc(LPos); - Inc(LDestPos); - end; - end; - SetLength(LTemp, LDestPos - 1); - AText := LTemp; -end; - -procedure TIdIMAP4.ReceiveBody(AMsg: TIdMessage; const ADelim: string = '.'); {Do not Localize} -var - LMsgEnd: Boolean; - LActiveDecoder: TIdMessageDecoder; - LLine: string; - LCheckForOptionalImapFlags: Boolean; - LDelim: string; - - {CC7: The following define SContentType is from IdMessageClient. It is defined here also - (with only local scope) because the one in IdMessageClient is defined locally - there also, so we cannot get at it.} -const - SContentType = 'Content-Type'; {do not localize} - - // TODO - move this procedure into TIdIOHandler as a new Capture method? - procedure CaptureAndDecodeCharset; - var - LMStream: TMemoryStream; - begin - LMStream := TMemoryStream.Create; - try - IOHandler.Capture(LMStream, LDelim, True, IndyTextEncoding_8Bit{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_8Bit{$ENDIF}); - LMStream.Position := 0; - // TODO: when String is AnsiString, TIdMessageClient uses AMsg.CharSet as - // the destination encoding, should this be doing the same? Otherwise, we - // could just use AMsg.Body.LoadFromStream() instead... - ReadStringsAsCharSet(LMStream, AMsg.Body, AMsg.CharSet{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_8Bit{$ENDIF}); - finally - LMStream.Free; - end; - end; - - function IsContentTypeHtml(const AContentType: String) : Boolean; - begin - Result := IsHeaderMediaTypes(AContentType, ['text/html', 'text/html-sandboxed','application/xhtml+xml']); {do not localize} - end; - - procedure ProcessTextPart(var VDecoder: TIdMessageDecoder); - var - LDestStream: TMemoryStream; - Li: integer; - LTxt: TIdText; - LNewDecoder: TIdMessageDecoder; - {$IFDEF STRING_IS_ANSI} - LAnsiEncoding: IIdTextEncoding; - {$ENDIF} - LContentType, LCharSet: string; - begin - LDestStream := TMemoryStream.Create; - try - LNewDecoder := VDecoder.ReadBody(LDestStream, LMsgEnd); - try - LDestStream.Position := 0; - LTxt := TIdText.Create(AMsg.MessageParts); - try - // if the Content-Type is HTML and does not specify a charset, parse - // the HTML looking for a tag that specifies a charset... - - // TODO: if the media type is not a 'text/...' based XML type, ignore - // the charset from the headers, if present, and parse the XML itself... - - LContentType := VDecoder.Headers.Values[SContentType]; - { - if IsContentTypeAppXml(LContentType) then begin - LCharSet := DetectXmlCharset(LDestStream); - LDestStream.Position := 0; - end else - begin - } - LCharSet := LTxt.GetCharSet(LContentType); - if (LCharSet = '') and IsContentTypeHtml(LContentType) then begin - ParseMetaHTTPEquiv(LDestStream, nil, LCharSet); - LDestStream.Position := 0; - end; - //end; - - LTxt.ContentType := LContentType; - LTxt.CharSet := LCharSet; - LTxt.ContentID := VDecoder.Headers.Values['Content-ID']; {Do not Localize} - LTxt.ContentLocation := VDecoder.Headers.Values['Content-Location']; {Do not Localize} - LTxt.ContentDescription := VDecoder.Headers.Values['Content-Description']; {Do not Localize} - LTxt.ContentDisposition := VDecoder.Headers.Values['Content-Disposition']; {Do not Localize} - LTxt.ContentTransfer := VDecoder.Headers.Values['Content-Transfer-Encoding']; {Do not Localize} - for Li := 0 to VDecoder.Headers.Count-1 do begin - if LTxt.Headers.IndexOfName(VDecoder.Headers.Names[Li]) < 0 then begin - LTxt.ExtraHeaders.AddValue( - VDecoder.Headers.Names[Li], - IndyValueFromIndex(VDecoder.Headers, Li) - ); - end; - end; - {$IFDEF STRING_IS_ANSI} - LAnsiEncoding := CharsetToEncoding(LCharSet); - {$ENDIF} - ReadStringsAsCharset(LDestStream, LTxt.Body, LCharSet{$IFDEF STRING_IS_ANSI}, LAnsiEncoding{$ENDIF}); - except - //this should also remove the Item from the TCollection. - //Note that Delete does not exist in the TCollection. - LTxt.Free; - raise; - end; - except - LNewDecoder.Free; - raise; - end; - VDecoder.Free; - VDecoder := LNewDecoder; - finally - FreeAndNil(LDestStream); - end; - end; - - procedure ProcessAttachment(var VDecoder: TIdMessageDecoder); - var - LDestStream: TStream; - Li: integer; - LAttachment: TIdAttachment; - LNewDecoder: TIdMessageDecoder; - begin - AMsg.DoCreateAttachment(VDecoder.Headers, LAttachment); - Assert(Assigned(LAttachment), 'Attachment must not be unassigned here!'); {Do not Localize} - try - LNewDecoder := nil; - try - LDestStream := LAttachment.PrepareTempStream; - try - LNewDecoder := VDecoder.ReadBody(LDestStream, LMsgEnd); - finally - LAttachment.FinishTempStream; - end; - LAttachment.ContentType := VDecoder.Headers.Values[SContentType]; - LAttachment.ContentTransfer := VDecoder.Headers.Values['Content-Transfer-Encoding']; {Do not Localize} - LAttachment.ContentDisposition := VDecoder.Headers.Values['Content-Disposition']; {Do not Localize} - LAttachment.ContentID := VDecoder.Headers.Values['Content-ID']; {Do not Localize} - LAttachment.ContentLocation := VDecoder.Headers.Values['Content-Location']; {Do not Localize} - LAttachment.ContentDescription := VDecoder.Headers.Values['Content-Description']; {Do not Localize} - LAttachment.Filename := VDecoder.Filename; - for Li := 0 to VDecoder.Headers.Count-1 do begin - if LAttachment.Headers.IndexOfName(VDecoder.Headers.Names[Li]) < 0 then begin - LAttachment.ExtraHeaders.AddValue( - VDecoder.Headers.Names[Li], - IndyValueFromIndex(VDecoder.Headers, Li) - ); - end; - end; - except - LNewDecoder.Free; - raise; - end; - except - //this should also remove the Item from the TCollection. - //Note that Delete does not exist in the TCollection. - LAttachment.Free; - raise; - end; - VDecoder.Free; - VDecoder := LNewDecoder; - end; - -Begin - {CC3: If IMAP calls this ReceiveBody, it prepends IMAP to delim, e.g. 'IMAP)', - to flag that this routine should expect IMAP FLAGS entries.} - LCheckForOptionalImapFlags := False; {CC3: IMAP hack inserted lines start here...} - LDelim := ADelim; - if TextStartsWith(ADelim, 'IMAP') then begin {do not localize} - LCheckForOptionalImapFlags := True; - LDelim := Copy(ADelim, 5, MaxInt); - end; {CC3: ...IMAP hack inserted lines end here} - LMsgEnd := False; - if AMsg.NoDecode then begin - CaptureAndDecodeCharSet; - end else begin - BeginWork(wmRead); - try - LActiveDecoder := nil; - try - repeat - LLine := IOHandler.ReadLn; - {CC3: Check for optional flags before delimiter in the case of IMAP...} - if LLine = LDelim then begin {CC3: IMAP hack ADelim -> LDelim} - Break; - end; {CC3: IMAP hack inserted lines start here...} - if LCheckForOptionalImapFlags and TextStartsWith(LLine, ' FLAGS (\') {do not localize} - and TextEndsWith(LLine, LDelim) then begin - Break; - end; - if LActiveDecoder = nil then begin - LActiveDecoder := TIdMessageDecoderList.CheckForStart(AMsg, LLine); - end; - if LActiveDecoder = nil then begin - {CC9: Per RFC821, the sender is required to add a prefixed '.' to any - line in an email that starts with '.' and the receiver is - required to strip it off. This ensures that the end-of-message - line '.' cannot appear in the message body.} - if TextStartsWith(LLine, '..') then begin {Do not Localize} - Delete(LLine,1,1); - end; - AMsg.Body.Add(LLine); - end else begin - while LActiveDecoder <> nil do begin - LActiveDecoder.SourceStream := TIdTCPStream.Create(Self); - LActiveDecoder.ReadHeader; - case LActiveDecoder.PartType of - mcptText: ProcessTextPart(LActiveDecoder); - mcptAttachment: ProcessAttachment(LActiveDecoder); - mcptIgnore: FreeAndNil(LActiveDecoder); - mcptEOF: begin FreeAndNil(LActiveDecoder); LMsgEnd := True; end; - end; - end; - end; - until LMsgEnd; - finally - FreeAndNil(LActiveDecoder); - end; - finally - EndWork(wmRead); - end; - end; -end; - -{########### Following only used by CONNECT? ###############} -function TIdIMAP4.GetResponse: string; -{CC: The purpose of this is to keep reading & accumulating lines until we hit -a line that has a valid response (that terminates the reading). We call -"FLastCmdResult.FormattedReply := LResponse;" to parse out the response we -received. - -The response sequences we need to deal with are: - -1) Many commands just give a simple result to the command issued: - C41 OK Completed -2) Some commands give you data first, then the result: - * LIST (\UnMarked) "/" INBOX - * LIST (\UnMarked) "/" Junk - * LIST (\UnMarked) "/" Junk/Subbox1 - C42 OK Completed -3) Some responses have a result but * instead of a command number (like C42): - * OK CommuniGate Pro IMAP Server 3.5.7 ready -4) Some have neither a * nor command number, but start with a result: - + Send the additional command text -or: - BAD Bad parameter - -Because you may get data first, which you need to skip, you need to -accept all the above possibilities. - -We MUST stop when we find a valid response code, like OK. -} -var - LLine: String; - LResponse: TStringList; - LWord: string; - LPos: integer; - LBuf: string; -begin - Result := ''; {Do not Localize} - LResponse := TStringList.Create; - try - repeat - LLine := IOHandler.ReadLnWait; - if LLine <> '' then begin {Do not Localize} - {It is not an empty line, add it to our list of stuff received (it is - not our job to interpret it)} - LResponse.Add(LLine); - {See if the last LLine contained a response code like OK or BAD.} - LPos := Pos(' ', LLine); {Do not Localize} - if LPos <> 0 then begin - {There are at least two words on this line...} - LWord := Trim(Copy(LLine, 1, LPos-1)); - LBuf := Trim(Copy(LLine, LPos+1, MaxInt)); {The rest of the line, without the 1st word} - end else begin - {No space, so this line is a single word. A bit weird, but it - could be just an OK...} - LWord := LLine; {A bit pedantic, but emphasises we have a word, not a line} - LBuf := ''; {Do not Localize} - end; - LPos := PosInStrArray(LWord, VALID_TAGGEDREPLIES); {Do not Localize} - if LPos > -1 then begin - {We got a valid response code as the first word...} - Result := LWord; - FLastCmdResult.FormattedReply := LResponse; - Exit; - end; - if Length(LBuf) = 0 then begin {Do not Localize} - Continue; {We hit a line with just one word which is not a valid IMAP response} - end; - {In all other cases, any valid response should be the second word...} - LPos := Pos(' ', LBuf); {Do not Localize} - if LPos <> 0 then begin - {There are at least three words on this line...} - LWord := Trim(Copy(LBuf, 1, LPos-1)); - LBuf := Trim(Copy(LBuf, LPos+1, MaxInt)); {The rest of the line, without the 1st word} - end else begin - {No space, so this line is two single words.} - LWord := LLine; {A bit pedantic, but emphasises we have a word, not a line} - LBuf := ''; {Do not Localize} - end; - LPos := PosInStrArray(LWord, VALID_TAGGEDREPLIES); {Do not Localize} - if LPos > -1 then begin - {We got a valid response code as the second word...} - Result := LWord; - FLastCmdResult.FormattedReply := LResponse; - Exit; - end; - end; - until False; - finally - FreeAndNil(LResponse); - end; -end; - -end. - +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.66 3/24/2005 3:03:28 AM DSiders + Modified TIdIMAP4.ParseStatusResult to correct an endless loop parsing an odd + number of status messages/values in the server response. + + Rev 1.65 3/23/2005 3:03:40 PM DSiders + Modified TIdIMAP4.Destroy to free resources for Capabilities and MUtf7 + properties. + + Rev 1.64 3/4/2005 3:08:42 PM JPMugaas + Removed compiler warning with stream. You sometimes need to use IdStreamVCL. + + Rev 1.63 3/3/2005 12:54:04 PM JPMugaas + Replaced TStringList with TIdStringList. + + Rev 1.62 3/3/2005 12:09:04 PM JPMugaas + TStrings were replaced with TIdStrings. + + Rev 1.60 20/02/2005 20:41:06 CCostelloe + Cleanup and reorganisations + + Rev 1.59 11/29/2004 2:46:10 AM JPMugaas + I hope that this fixes a compile error. + + Rev 1.58 11/27/04 3:11:56 AM RLebeau + Fixed bug in ownership of SASLMechanisms property. + + Updated to use TextIsSame() instead of Uppercase() comparisons. + + Rev 1.57 11/8/2004 8:39:00 AM DSiders + Removed comment in TIdIMAP4.SearchMailBox implementation that caused DOM + problem when locating the symbol id. + + Rev 1.56 10/26/2004 10:19:58 PM JPMugaas + Updated refs. + + Rev 1.55 2004.10.26 2:19:56 PM czhower + Resolved alias conflict. + + Rev 1.54 6/11/2004 9:36:34 AM DSiders + Added "Do not Localize" comments. + + Rev 1.53 6/4/04 12:48:12 PM RLebeau + ContentTransferEncoding bug fix + + Rev 1.52 01/06/2004 19:03:46 CCostelloe + .NET bug fix + + Rev 1.51 01/06/2004 01:16:18 CCostelloe + Various improvements + + Rev 1.50 20/05/2004 22:04:14 CCostelloe + IdStreamVCL changes + + Rev 1.49 20/05/2004 08:43:12 CCostelloe + IdStream change + + Rev 1.48 16/05/2004 20:40:46 CCostelloe + New TIdText/TIdAttachment processing + + Rev 1.47 24/04/2004 23:54:42 CCostelloe + IMAP-style UTF-7 encoding/decoding of mailbox names added + + Rev 1.46 13/04/2004 22:24:28 CCostelloe + Bug fix (FCapabilities not created if not DOTNET) + + Rev 1.45 3/18/2004 2:32:40 AM JPMugaas + Should compile under D8 properly. + + Rev 1.44 3/8/2004 10:10:32 AM JPMugaas + IMAP4 should now have SASLMechanisms again. Those work in DotNET now. + SSL abstraction is now supported even in DotNET so that should not be + IFDEF'ed out. + + Rev 1.43 07/03/2004 17:55:16 CCostelloe + Updates to cover changes in other units + + Rev 1.42 2/4/2004 2:36:58 AM JPMugaas + Moved more units down to the implementation clause in the units to make them + easier to compile. + + Rev 1.41 2/3/2004 4:12:50 PM JPMugaas + Fixed up units so they should compile. + + Rev 1.40 2004.02.03 5:43:48 PM czhower + Name changes + + Rev 1.39 2004.02.03 2:12:10 PM czhower + $I path change + + Rev 1.38 1/27/2004 4:01:12 PM SPerry + StringStream ->IdStringStream + + Rev 1.37 1/25/2004 3:11:12 PM JPMugaas + SASL Interface reworked to make it easier for developers to use. + SSL and SASL reenabled components. + + Rev 1.36 23/01/2004 01:48:28 CCostelloe + Added BinHex4.0 encoding support for parts + + Rev 1.35 1/21/2004 3:10:40 PM JPMugaas + InitComponent + + Rev 1.34 31/12/2003 09:40:32 CCostelloe + ChangeReplyClass removed, replaced AnsiSameText with TextIsSame, stream code + not tested. + + Rev 1.33 28/12/2003 23:48:18 CCostelloe + More TEMPORARY fixes to get it to compile under D7 and D8 .NET + + Rev 1.32 22/12/2003 01:20:20 CCostelloe + .NET fixes. This is a TEMPORARY combined Indy9/10/.NET master file. + + Rev 1.31 14/12/2003 21:03:16 CCostelloe + First version for .NET + + Rev 1.30 10/17/2003 12:11:06 AM DSiders + Added localization comments. + Added resource strings for exception messages. + + Rev 1.29 2003.10.12 3:53:10 PM czhower + compile todos + + Rev 1.28 10/12/2003 1:49:50 PM BGooijen + Changed comment of last checkin + + Rev 1.27 10/12/2003 1:43:34 PM BGooijen + Changed IdCompilerDefines.inc to Core\IdCompilerDefines.inc + + Rev 1.26 20/09/2003 15:38:38 CCostelloe + More patches added for different IMAP servers + + Rev 1.25 12/08/2003 01:17:38 CCostelloe + Retrieve and AppendMsg updated to suit changes made to attachment encoding + changes in other units + + Rev 1.24 21/07/2003 01:22:24 CCostelloe + Added CopyMsg and UIDCopyMsgs. (UID)Receive(Peek) rewritten. AppendMsg + still buggy with attachments. Public variable FGreetingBanner added. Added + "if Connected then " to Destroy. Attachment filenames now decoded if + necessary. Added support for multisection parts. Resolved issue of some + servers leaving out the trailing "NIL NIL NIL" at the end of some body + structures. UIDRetrieveAllHeaders removed + + Rev 1.23 18/06/2003 21:53:36 CCostelloe + Rewrote GetResponse from scratch. Restored Capabilities for login. Compiles + and runs properly (may be a couple of minor bugs not yet discovered). + + Rev 1.22 6/16/2003 11:48:18 PM JPMugaas + Capabilities has to be restored for SASL and SSL support. + + Rev 1.21 17/06/2003 01:33:46 CCostelloe + Updated to support new LoginSASL. Compiles OK, may not yet run OK. + + Rev 1.20 12/06/2003 10:17:54 CCostelloe + Partial update for Indy 10's new Reply structure. Compiles but does not run + correctly. Checked in to show problem with Get/SetNumericCode in IdReplyIMAP. + + Rev 1.19 04/06/2003 02:33:44 CCostelloe + Compiles under Indy 10 with the revised Indy 10 structure, but does not yet + work properly due to some of the changes. Will be fixed by me in a later + check-in. + + Rev 1.18 14/05/2003 01:55:50 CCostelloe + This version (with the extra IMAP functionality recently added) now compiles + on Indy 10 and works in a real application. + + Rev 1.17 5/12/2003 02:19:56 AM JPMugaas + Now should work properly again. I also removed all warnings and errors in + Indy 10. + + Rev 1.16 5/11/2003 07:35:44 PM JPMugaas + + Rev 1.15 5/11/2003 07:11:06 PM JPMugaas + Fixed to eliminate some warnings and compile errors in Indy 10. + + Rev 1.14 11/05/2003 23:53:52 CCostelloe + Bug fix due to Windows 98 / 2000 discrepancies + + Rev 1.13 11/05/2003 23:08:36 CCostelloe + Lots more bug fixes, plus IMAP code moved up from IdRFCReply + + Rev 1.12 5/10/2003 07:31:22 PM JPMugaas + Updated with some bug fixes and some cleanups. + + Rev 1.11 5/9/2003 10:51:26 AM JPMugaas + Bug fixes. Now works as it should. Verified. + + Rev 1.9 5/9/2003 03:49:44 AM JPMugaas + IMAP4 now supports SASL. Merged some code from Ciaran which handles the + + SASL continue reply in IMAP4 and makes a few improvements. Verified to work + on two servers. + + Rev 1.8 5/8/2003 05:41:48 PM JPMugaas + Added constant for SASL continuation. + + Rev 1.7 5/8/2003 03:17:50 PM JPMugaas + Flattened ou the SASL authentication API, made a custom descendant of SASL + enabled TIdMessageClient classes. + + Rev 1.6 5/8/2003 11:27:52 AM JPMugaas + Moved feature negoation properties down to the ExplicitTLSClient level as + feature negotiation goes hand in hand with explicit TLS support. + + Rev 1.5 5/8/2003 02:17:44 AM JPMugaas + Fixed an AV in IdPOP3 with SASL list on forms. Made exceptions for SASL + mechanisms missing more consistant, made IdPOP3 support feature feature + negotiation, and consolidated some duplicate code. + + Rev 1.4 5/7/2003 10:20:32 PM JPMugaas + + Rev 1.3 5/7/2003 04:35:30 AM JPMugaas + IMAP4 should now compile. Started on prelimary SSL support (not finished + yet). + + Rev 1.2 15/04/2003 00:57:08 CCostelloe + + Rev 1.1 2/24/2003 09:03:06 PM JPMugaas + + Rev 1.0 11/13/2002 07:54:50 AM JPMugaas + + 2001-FEB-27 IC: First version most of the IMAP features are implemented and + the core IdPOP3 features are implemented to allow a seamless + switch. + The unit is currently oriented to a session connection and not + to constant connection, because of that server events that are + raised from another user actions are not supported. + + 2001-APR-18 IC: Added support for the session's connection state with a + special exception for commands preformed in wrong connection + states. Exceptions were also added for response errors. + + 2001-MAY-05 IC: + + 2001-Mar-13 DS: Fixed Bug # 494813 in CheckMsgSeen where LastCmdResult.Text + was not using the Ln index variable to access server + responses. + + 2002-Apr-12 DS: fixed bug # 506026 in TIdIMAP4.ListSubscribedMailBoxes. Call + ParseLSubResut instead of ParseListResult. + + 2003-Mar-31 CC: Added GetUID and UIDSearchMailBox, sorted out some bugs (details + shown in comments in those functions which start with "CC:"). + + 2003-Apr-15 CC2:Sorted out some more bugs (details shown in comments in those + functions which start with "CC2:"). Set FMailBoxSeparator + in ParseListResult and ParseLSubResult. + Some IMAP servers generally return "OK completed" even if they + returned no data, such as passing a non-existent message + number to them: they possibly should return NO or BAD; the + functions here have been changed to return FALSE unless they + get good data back, even if the server answers OK. Similar + change made for other functions. + There are a few exceptions, e.g. ListMailBoxes may only return + "OK completed" if the user has no mailboxes, these are noted. + Also, RetrieveStructure(), UIDRetrieveStructure, RetrievePart, + UIDRetrievePart, RetrievePartPeek and UIDRetrievePartPeek + added to allow user to find the structure of a message and + just retrieve the part or parts he needs. + + 2003-Apr-30 CC3:Added functionality to retrieve the text of a message (only) + via RetrieveText / UIDRetrieveText / RetrieveTextPeek / + UIDRetrieveTextPeek. + Return codes now generally reflect if the function succeeded + instead of returning True even though function fails. + + 2003-May-15 CC4:Added functionality to retrieve individual parts of a message + to a file, including the decoding of those parts. + + 2003-May-29 CC5:Response of some servers to UID version of commands varies, + code changed to deal with those (UID position varies). + Some servers return NO such as when you request an envelope + for a message number that does not exist: functions return + False instead of throwing an exception, as was done for other + servers. The general logic is that if a valid result is + returned from the IMAP server, return True; if there is no + result (but the command is validly structured), return FALSE; + if the command is badly structured or if it gives a response + that this code does not expect, throw an exception (typically + when we get a BAD response instead of OK or NO). + Added IsNumberValid, IsUIDValid to prevent rubbishy parameters + being passed through to IMAP functions. + Sender field now filled in correctly in ParseEnvelope + functions. + All fields in ParseEnvelopeAddress are cleared out first, + avoids an unwitting error where some entries, such as CC list, + will append entries to existing entries. + Full test script now used that tests every TIdIMAP command, + more bugs eradicated. + First version to pass testing against both CommuniGate and + Cyrus IMAP servers. + Not tested against Microsoft Exchange, don't have an Exchange + account to test it against. + + 2003-Jun-10 CC6:Added (UID)RetrieveEnvelopeRaw, in case the user wants to do + their own envelope parsing. + Code in RetrievePart altered to make it more consistent. + Altered to incorporate Indy 10's use of IdReplyIMAP4 (not + complete at this stage). + ReceiveBody added to IdIMAP4, due to the response of some + servers, which gets (UID)Receive(Peek) functions to work on + more servers. + + 2003-Jun-20 CC7:ReceiveBody altered to work with Indy 10. Made changes due to + LoginSASL moving from TIdMessageSASLClient to TIdSASLList. + Public variable FGreetingBanner added to help user identify + the IMAP server he is connected to (may help him decide the + best strategy). Made AppendMsg work a bit better (now uses + platform-independent EOL and supports ExtraHeaders field). + Added 2nd version of AppendMsg. Added "if Connected then " + to Destroy. Attachment filenames now decoded if necessary. + Added support for multisection parts. + + 2003-Jul-16 CC8:Added RemoveAnyAdditionalResponses. Resolved issue of some + servers leaving out the trailing "NIL NIL NIL" at the end of + some body structures. (UID)Retrieve(Peek) functions + integrated via InternalRetrieve, new method of implementing + these functions (all variations of Retrieve) added for Indy + 10 based on getting message by the byte-count and then feeding + it into the standard message parser. + UIDRetrieveAllHeaders removed: it was never implemented anyway + but it makes no sense to retrieve a non-contiguous list which + would have gaps due to missing UIDs. + In the Indy 10 version, AppendMsg functions were altered to + support the sending of attachments (attachments had never + been supported in AppendMsg prior to this). + Added CopyMsg and UIDCopyMsgs to complete the command set. + 2003-Jul-30 CC9:Removed wDoublePoint so that the code is compliant with + the guidelines. Allowed for servers that don't implement + search commands in Indy 9 (OK in 10). InternalRetrieve + altered to (hopefully) deal with optional "FLAGS (\Seen)" + in response. + 2003-Aug-22 CCA:Yet another IMAP oddity - a server returns NIL for the + mailbox separator, ParseListResult modified. Added "Length + (LLine) > 0)" test to stop GPF on empty line in ReceiveBody. + 2003-Sep-26 CCB:Changed SendCmd altered to try to remove anything that may + be unprocessed from a previous (probably failed) command. + This uses the property FMilliSecsToWaitToClearBuffer, which + defaults to 10ms. + Added EIdDisconnectedProbablyIdledOut, trapped in + GetInternalResponse. + Unsolicited responses now filtered out (they are now transferred + from FLastCmdResult.Text to a new field, FLastCmdResult.Extra, + leaving just the responses we want to our command in + FLastCmdResult.Text). + 2003-Oct-21 CCC:Original GetLineResponse merged with GetResponse to reduce + complexity and to add filtering unsolicited responses when + we are looking for single-line responses (which GetLineResponse + did), removed/coded-out much of these functions to make the + code much simpler. + Removed RemoveAnyAdditionalResponses, no longer needed. + Parsing of body structure reworked to support ParentPart concept + allowing parsing of indefinitely-nested MIME parts. Note that + a`MIME "alternative" message with a plain-text and a html part + will have part[0] marked "alternative" with size 0 and ImapPartNumber + of 1, a part[1] of type text/plain with a ParentPart of 0 and an + ImapPartNumber of 1.1, and finally a part[2] of type text/html + again with a ParentPart of 0 and an ImapPartNumber of 1.2. + Imap part number changed from an integer to string, allowing + retrieval of IMAP sub-parts, e.g. part '3.2' is the 2nd subpart + of part 3. + 2003-Nov-20 CCD:Added UIDRetrievePartHeader & RetrievePartHeader. Started to + use an abstracted parsing method for the command response in + UIDRetrieveFlags. Added function FindHowServerCreatesFolders. + 2003-Dec-04 CCE:Copied DotNet connection changes from IdSMTP to tempoarily bypass + the SASL authentications until they are ported. + 2004-Jan-23 CCF:Finished .NET port, added BinHex4.0 encoding. + 2004-Apr-16 CCG:Added UTF-7 decoding/encoding code kindly written and submitted by + Roman Puls for encoding/decoding mailbox names. IMAP does not use + standard UTF-7 code (what's new?!) so these routines are localised + to this unit. +} + +unit IdIMAP4; + +{ + IMAP 4 (Internet Message Access Protocol - Version 4 Rev 1) + By Idan Cohen i_cohen@yahoo.com +} + +interface + +{ Todo -oIC : +Change the mailbox list commands so that they receive TMailBoxTree +structures and so they can store in them the mailbox name and it's attributes. } + +{ Todo -oIC : +Add support for \* special flag in messages, and check for \Recent +flag in STORE command because it cant be stored (will get no reply!!!) } + +{ Todo -oIC : +5.1.2. Mailbox Namespace Naming Convention +By convention, the first hierarchical element of any mailbox name +which begins with "#" identifies the "namespace" of the remainder of +the name. This makes it possible to disambiguate between different +types of mailbox stores, each of which have their own namespaces. +For example, implementations which offer access to USENET +newsgroups MAY use the "#news" namespace to partition the USENET +newsgroup namespace from that of other mailboxes. Thus, the +comp.mail.misc newsgroup would have an mailbox name of +"#news.comp.mail.misc", and the name "comp.mail.misc" could refer +to a different object (e.g. a user's private mailbox). } + +{ TO BE CONSIDERED -CC : +Double-quotes in mailbox names can cause major but subtle failures. Maybe +add the automatic stripping of double-quotes if passed in mailbox names, +to avoid ending up with ""INBOX"" +} + +{CC3: WARNING - if the following gives a "File not found" error on compilation, +you need to add the path "C:\Program Files\Borland\Delphi7\Source\Indy" in +Project -> Options -> Directories/Conditionals -> Search Path} + +{$I IdCompilerDefines.inc} + +uses + Classes, + {$IFNDEF VCL_6_OR_ABOVE}IdCTypes,{$ENDIF} + IdMessage, + IdAssignedNumbers, + IdMailBox, + IdException, + IdGlobal, + IdMessageParts, + IdMessageClient, + IdReply, + IdComponent, + IdMessageCoder, + IdHeaderList, + IdCoderHeader, + IdCoderMIME, + IdCoderQuotedPrintable, + IdCoderBinHex4, + IdSASLCollection, + IdMessageCollection, + IdBaseComponent; + +{ MUTF7 } + +type + EmUTF7Error = class(EIdSilentException); + EmUTF7Encode = class(EmUTF7Error); + EmUTF7Decode = class(EmUTF7Error); + +type + // TODO: make an IIdTextEncoding implementation for Modified UTF-7 + TIdMUTF7 = class(TObject) + public + function Encode(const aString : TIdUnicodeString): String; + function Decode(const aString : String): TIdUnicodeString; + function Valid(const aMUTF7String : String): Boolean; + function Append(const aMUTF7String: String; const aStr: TIdUnicodeString): String; + end; + +{ TIdIMAP4 } + +const + wsOk = 1; + wsNo = 2; + wsBad = 3; + wsPreAuth = 4; + wsBye = 5; + wsContinue = 6; + +type + TIdIMAP4FolderTreatment = ( //Result codes from FindHowServerCreatesFolders + ftAllowsTopLevelCreation, //Folders can be created at the same level as Inbox (the top level) + ftFoldersMustBeUnderInbox, //Folders must be created under INBOX, such as INBOX.Sent + ftDoesNotAllowFolderCreation, //Wont allow you create folders at top level or under Inbox (may be read-only connection) + ftCannotTestBecauseHasNoInbox, //Wont allow top-level creation but cannot test creation under Inbox because it does not exist + ftCannotRetrieveAnyFolders //No folders present for that user, cannot be determined + ); + +type + TIdIMAP4AuthenticationType = ( + iatUserPass, + iatSASL + ); + +const + DEF_IMAP4_AUTH = iatUserPass; + IDF_DEFAULT_MS_TO_WAIT_TO_CLEAR_BUFFER = 10; + +{CC3: TIdImapMessagePart and TIdImapMessageParts added for retrieving +individual parts of a message via IMAP, because IMAP uses some additional +terms. +Note that (rarely) an IMAP can have two sub-"parts" in the one part - +they are sent in the one part by the server, typically a plain-text and +html version with a boundary at the start, in between, and at the end. +TIdIMAP fills in the boundary in that case, and the FSubpart holds the +info on the second part. I call these multisection parts.} + +type + TIdImapMessagePart = class(TCollectionItem) + protected + FBodyType: string; + FBodySubType: string; + FFileName: string; + FDescription: string; + FEncoding: TIdMessageEncoding; + FCharSet: string; + FContentTransferEncoding: string; + FSize: Int64; + FUnparsedEntry: string; {Text returned from server: useful for debugging or workarounds} + FBoundary: string; {Only used for multisection parts} + FParentPart: Integer; + FImapPartNumber: string; + public + constructor Create(Collection: TCollection); override; + property BodyType : String read FBodyType write FBodyType; + property BodySubType : String read FBodySubType write FBodySubType; + property FileName : String read FFileName write FFileName; + property Description : String read FDescription write FDescription; + property Encoding: TIdMessageEncoding read FEncoding write FEncoding; + property CharSet: string read FCharSet write FCharSet; + property ContentTransferEncoding : String read FContentTransferEncoding write FContentTransferEncoding; + property Size : Int64 read FSize write FSize; + property UnparsedEntry : string read FUnparsedEntry write FUnparsedEntry; + property Boundary : string read FBoundary write FBoundary; + property ParentPart: integer read FParentPart write FParentPart; + property ImapPartNumber: string read FImapPartNumber write FImapPartNumber; + end; + + {CC3: Added for validating message number} + EIdNumberInvalid = class(EIdException); + {CCB: Added for server disconnecting you if idle too long...} + EIdDisconnectedProbablyIdledOut = class(EIdException); + + TIdImapMessageParts = class(TOwnedCollection) + protected + function GetItem(Index: Integer): TIdImapMessagePart; + procedure SetItem(Index: Integer; const Value: TIdImapMessagePart); + public + constructor Create(AOwner: TPersistent); reintroduce; + function Add: TIdImapMessagePart; reintroduce; + property Items[Index: Integer]: TIdImapMessagePart read GetItem write SetItem; default; + end; + +{CCD: Added to parse out responses, because the order in which the responses appear +varies between servers. A typical line that gets parsed into this is: + * 9 FETCH (UID 1234 FLAGS (\Seen \Deleted)) +} + TIdIMAPLineStruct = class(TObject) + protected + HasStar: Boolean; //Line starts with a '*' + MessageNumber: string; //Line has a message number (after the *) + Command: string; //IMAP servers send back the command they are responding to, e.g. FETCH + UID: string; //Sometimes the UID is echoed back + Flags: TIdMessageFlagsSet; //Sometimes the FLAGS are echoed back + FlagsStr: string; //unparsed FLAGS for the message + Complete: Boolean; //If false, line has no closing bracket (response continues on following line(s)) + ByteCount: integer; //The value in a trailing byte count like {123}, -1 means not present + IMAPFunction: string; //E.g. FLAGS + IMAPValue: string; //E.g. '(\Seen \Deleted)' + GmailMsgID: string; //Gmail-specific unique identifier for the message + GmailThreadID: string; //Gmail-specific thread identifier for the message + GmailLabels: string; //Gmail-specific labels for the message + end; + + TIdIMAP4Commands = ( + cmdCAPABILITY, + cmdNOOP, + cmdLOGOUT, + cmdAUTHENTICATE, + cmdLOGIN, + cmdSELECT, + cmdEXAMINE, + cmdCREATE, + cmdDELETE, + cmdRENAME, + cmdSUBSCRIBE, + cmdUNSUBSCRIBE, + cmdLIST, + cmdLSUB, + cmdSTATUS, + cmdAPPEND, + cmdCHECK, + cmdCLOSE, + cmdEXPUNGE, + cmdSEARCH, + cmdFETCH, + cmdSTORE, + cmdCOPY, + cmdUID, + cmdXCmd + ); + + {CC3: Add csUnexpectedlyDisconnected for when we receive "Connection reset by peer"} + TIdIMAP4ConnectionState = ( + csAny, + csNonAuthenticated, + csAuthenticated, + csSelected, + csUnexpectedlyDisconnected + ); + + {**************************************************************************** + Universal commands CAPABILITY, NOOP, and LOGOUT + Authenticated state commands SELECT, EXAMINE, CREATE, DELETE, RENAME, + SUBSCRIBE, UNSUBSCRIBE, LIST, LSUB, STATUS, and APPEND + Selected state commands CHECK, CLOSE, EXPUNGE, SEARCH, FETCH, STORE, COPY, and UID + *****************************************************************************} + + TIdIMAP4SearchKey = ( + skAll, //All messages in the mailbox; the default initial key for ANDing. + skAnswered, //Messages with the \Answered flag set. + skBcc, //Messages that contain the specified string in the envelope structure's BCC field. + skBefore, //Messages whose internal date is earlier than the specified date. + skBody, //Messages that contain the specified string in the body of the message. + skCc, //Messages that contain the specified string in the envelope structure's CC field. + skDeleted, //Messages with the \Deleted flag set. + skDraft, //Messages with the \Draft flag set. + skFlagged, //Messages with the \Flagged flag set. + skFrom, //Messages that contain the specified string in the envelope structure's FROM field. + skHeader, //Messages that have a header with the specified field-name (as defined in [RFC-822]) + //and that contains the specified string in the [RFC-822] field-body. + skKeyword, //Messages with the specified keyword set. + skLarger, //Messages with an [RFC-822] size larger than the specified number of octets. + skNew, //Messages that have the \Recent flag set but not the \Seen flag. + //This is functionally equivalent to "(RECENT UNSEEN)". + skNot, //Messages that do not match the specified search key. + skOld, //Messages that do not have the \Recent flag set. This is functionally + //equivalent to "NOT RECENT" (as opposed to "NOT NEW"). + skOn, //Messages whose internal date is within the specified date. + skOr, //Messages that match either search key. + skRecent, //Messages that have the \Recent flag set. + skSeen, //Messages that have the \Seen flag set. + skSentBefore,//Messages whose [RFC-822] Date: header is earlier than the specified date. + skSentOn, //Messages whose [RFC-822] Date: header is within the specified date. + skSentSince, //Messages whose [RFC-822] Date: header is within or later than the specified date. + skSince, //Messages whose internal date is within or later than the specified date. + skSmaller, //Messages with an [RFC-822] size smaller than the specified number of octets. + skSubject, //Messages that contain the specified string in the envelope structure's SUBJECT field. + skText, //Messages that contain the specified string in the header or body of the message. + skTo, //Messages that contain the specified string in the envelope structure's TO field. + skUID, //Messages with unique identifiers corresponding to the specified unique identifier set. + skUnanswered,//Messages that do not have the \Answered flag set. + skUndeleted, //Messages that do not have the \Deleted flag set. + skUndraft, //Messages that do not have the \Draft flag set. + skUnflagged, //Messages that do not have the \Flagged flag set. + skUnKeyWord, //Messages that do not have the specified keyword set. + skUnseen, + skGmailRaw, //Gmail-specific extension to access full Gmail search syntax + skGmailMsgID, //Gmail-specific unique message identifier + skGmailThreadID, //Gmail-specific thread identifier + skGmailLabels //Gmail-specific labels + ); + + TIdIMAP4SearchKeyArray = array of TIdIMAP4SearchKey; + + TIdIMAP4SearchRec = record + Date: TDateTime; + Size: Int64; + Text: String; + SearchKey : TIdIMAP4SearchKey; + FieldName: String; + end; + + TIdIMAP4SearchRecArray = array of TIdIMAP4SearchRec; + + TIdIMAP4StatusDataItem = ( + mdMessages, + mdRecent, + mdUIDNext, + mdUIDValidity, + mdUnseen + ); + + TIdIMAP4StoreDataItem = ( + sdReplace, + sdReplaceSilent, + sdAdd, + sdAddSilent, + sdRemove, + sdRemoveSilent + ); + + TIdRetrieveOnSelect = ( + rsDisabled, + rsHeaders, + rsMessages + ); + + TIdAlertEvent = procedure(ASender: TObject; const AAlertMsg: String) of object; + + TIdIMAP4 = class(TIdMessageClient) + protected + FCmdCounter : Integer; + FConnectionState : TIdIMAP4ConnectionState; + FMailBox : TIdMailBox; + FMailBoxSeparator: Char; + FOnAlert: TIdAlertEvent; + FRetrieveOnSelect: TIdRetrieveOnSelect; + FMilliSecsToWaitToClearBuffer: integer; + FMUTF7: TIdMUTF7; + FOnWorkForPart: TWorkEvent; + FOnWorkBeginForPart: TWorkBeginEvent; + FOnWorkEndForPart: TWorkEndEvent; + FGreetingBanner : String; {CC7: Added because it may help identify the server} + FHasCapa : Boolean; + FSASLMechanisms : TIdSASLEntries; + FAuthType : TIdIMAP4AuthenticationType; + FLineStruct: TIdIMAPLineStruct; + function GetReplyClass:TIdReplyClass; override; + function GetSupportsTLS: Boolean; override; + function CheckConnectionState(AAllowedState: TIdIMAP4ConnectionState): TIdIMAP4ConnectionState; overload; + function CheckConnectionState(const AAllowedStates: array of TIdIMAP4ConnectionState): TIdIMAP4ConnectionState; overload; + function CheckReplyForCapabilities: Boolean; + procedure BeginWorkForPart(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); + procedure DoWorkForPart(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); + procedure EndWorkForPart(ASender: TObject; AWorkMode: TWorkMode); + //The following call FMUTF7 but do exception-handling on invalid strings... + function DoMUTFEncode(const aString : String): String; + function DoMUTFDecode(const aString : String): String; + function GetCmdCounter: String; + function GetConnectionStateName: String; + function GetNewCmdCounter: String; + property LastCmdCounter: String read GetCmdCounter; + property NewCmdCounter: String read GetNewCmdCounter; + { General Functions } + function ArrayToNumberStr (const AMsgNumList: array of UInt32): String; + function MessageFlagSetToStr (const AFlags: TIdMessageFlagsSet): String; + procedure StripCRLFs(var AText: string); overload; virtual; //Allow users to optimise + procedure StripCRLFs(ASourceStream, ADestStream: TStream); overload; + { Parser Functions } + procedure ParseImapPart(ABodyStructure: string; + AImapParts: TIdImapMessageParts; AThisImapPart: TIdImapMessagePart; + AParentImapPart: TIdImapMessagePart; APartNumber: integer); + procedure ParseMessagePart(ABodyStructure: string; AMessageParts: TIdMessageParts; + AThisMessagePart: TIdMessagePart; AParentMessagePart: TIdMessagePart; + APartNumber: integer); + procedure ParseBodyStructureResult(ABodyStructure: string; ATheParts: TIdMessageParts; AImapParts: TIdImapMessageParts); + procedure ParseBodyStructurePart(APartString: string; AThePart: TIdMessagePart; AImapPart: TIdImapMessagePart); + procedure ParseTheLine(ALine: string; APartsList: TStrings); + procedure ParseIntoParts(APartString: string; AParams: TStrings); + procedure ParseIntoBrackettedQuotedAndUnquotedParts(APartString: string; AParams: TStrings; AKeepBrackets: Boolean); + procedure BreakApartParamsInQuotes(const AParam: string; AParsedList: TStrings); + function GetNextWord(AParam: string): string; + function GetNextQuotedParam(AParam: string; ARemoveQuotes: Boolean): string; + procedure ParseExpungeResult (AMB: TIdMailBox; ACmdResultDetails: TStrings); + procedure ParseListResult (AMBList: TStrings; ACmdResultDetails: TStrings); + procedure ParseLSubResult(AMBList: TStrings; ACmdResultDetails: TStrings); + procedure InternalParseListResult(ACmd: string; AMBList: TStrings; ACmdResultDetails: TStrings); + procedure ParseMailBoxAttributeString(AAttributesList: String; var AAttributes: TIdMailBoxAttributesSet); + procedure ParseMessageFlagString (AFlagsList: String; var AFlags: TIdMessageFlagsSet); + procedure ParseSelectResult (AMB: TIdMailBox; ACmdResultDetails: TStrings); + procedure ParseStatusResult (AMB: TIdMailBox; ACmdResultDetails: TStrings); + procedure ParseSearchResult (AMB: TIdMailBox; ACmdResultDetails: TStrings); + procedure ParseEnvelopeResult (AMsg: TIdMessage; ACmdResultStr: String); + function ParseLastCmdResult(ALine: string; AExpectedCommand: string; AExpectedIMAPFunction: array of string): Boolean; + procedure ParseLastCmdResultButAppendInfo(ALine: string); + function InternalRetrieve(const AMsgNum: UInt32; AUseUID: Boolean; AUsePeek: Boolean; AMsg: TIdMessage): Boolean; + function InternalRetrievePart(const AMsgNum: UInt32; const APartNum: string; + AUseUID: Boolean; AUsePeek: Boolean; + ADestStream: TStream; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; {NOTE: var args cannot have default params} + ADestFileNameAndPath: string = ''; {Do not Localize} + AContentTransferEncoding: string = 'text'): Boolean; {Do not Localize} + //Retrieves the specified number of headers of the selected mailbox to the specified TIdMessageCollection. + function InternalRetrieveHeaders(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; + //Retrieves the specified number of messages of the selected mailbox to the specified TIdMessageCollection. + function InternalRetrieveMsgs(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; + function InternalSearchMailBox(const ASearchInfo: array of TIdIMAP4SearchRec; AUseUID: Boolean; const ACharSet: string): Boolean; + function ParseBodyStructureSectionAsEquates(AParam: string): string; + function ParseBodyStructureSectionAsEquates2(AParam: string): string; + function InternalRetrieveText(const AMsgNum: UInt32; var AText: string; + AUseUID: Boolean; AUsePeek: Boolean; AUseFirstPartInsteadOfText: Boolean): Boolean; + function IsCapabilityListed(ACapability: string): Boolean; + function InternalRetrieveEnvelope(const AMsgNum: UInt32; AMsg: TIdMessage; ADestList: TStrings): Boolean; + function UIDInternalRetrieveEnvelope(const AMsgUID: String; AMsg: TIdMessage; ADestList: TStrings): Boolean; + function InternalRetrievePartHeader(const AMsgNum: UInt32; const APartNum: string; const AUseUID: Boolean; + AHeaders: TIdHeaderList): Boolean; + function ReceiveHeader(AMsg: TIdMessage; const AAltTerm: string = ''): string; override; + {CC3: Need to validate message numbers (relative and UIDs) and part numbers, because otherwise + the routines wait for a response that never arrives and so functions never return. + Also used for validating part numbers.} + function IsNumberValid(const ANumber: UInt32): Boolean; + function IsUIDValid(const AUID: string): Boolean; + function IsImapPartNumberValid(const APartNum: Integer): Boolean; overload; + function IsImapPartNumberValid(const APartNum: string): Boolean; overload; + function IsItDigitsAndOptionallyPeriod(const AStr: string; AAllowPeriod: Boolean): Boolean; + {CC6: Override IdMessageClient's ReceiveBody due to the responses from some servers...} + procedure ReceiveBody(AMsg: TIdMessage; const ADelim: string = '.'); override; {Do not Localize} + procedure InitComponent; override; + procedure SetMailBox(const Value: TIdMailBox); + procedure SetSASLMechanisms(AValue: TIdSASLEntries); + public + { TIdIMAP4 Commands } + {$IFDEF WORKAROUND_INLINE_CONSTRUCTORS} + constructor Create(AOwner: TComponent); reintroduce; overload; + {$ENDIF} + destructor Destroy; override; + //Requests a listing of capabilities that the server supports... + function Capability: Boolean; overload; + function Capability(ASlCapability: TStrings): Boolean; overload; + function FindHowServerCreatesFolders: TIdIMAP4FolderTreatment; + procedure DoAlert(const AMsg: String); + property ConnectionState: TIdIMAP4ConnectionState read FConnectionState; + property MailBox: TIdMailBox read FMailBox write SetMailBox; + {CC7: Two versions of AppendMsg are provided. The first is the normal one you + would use. The second allows you to specify an alternative header list which + will be used in place of AMsg.Headers. + An email client may need the second type if it sends an email via IdSMTP and wants + to copy it to a "Sent" IMAP folder. In Indy 10, + IdSMTP puts the generated headers in the LastGeneratedHeaders field, so you + can use the second version of AppendMsg, passing it AMsg.LastGeneratedHeaders as + the AAlternativeHeaders field. Note that IdSMTP puts both the Headers and + the ExtraHeaders fields in LastGeneratedHeaders.} + function AppendMsg(const AMBName: String; AMsg: TIdMessage; const AFlags: TIdMessageFlagsSet = []; + const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; overload; + function AppendMsg(const AMBName: String; AMsg: TIdMessage; AAlternativeHeaders: TIdHeaderList; + const AFlags: TIdMessageFlagsSet = []; const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; overload; + //The following are used for raw (unparsed) messages in a file or stream... + function AppendMsgNoEncodeFromFile(const AMBName: String; ASourceFile: string; const AFlags: TIdMessageFlagsSet = []; + const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; + function AppendMsgNoEncodeFromStream(const AMBName: String; AStream: TStream; const AFlags: TIdMessageFlagsSet = []; + const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; + //Requests a checkpoint of the currently selected mailbox. Does NOTHING on most servers. + function CheckMailBox: Boolean; + //Checks if the message was read or not. + function CheckMsgSeen(const AMsgNum: UInt32): Boolean; + //Method for logging in manually if you didn't login at connect + procedure Login; virtual; + //Connects and logins to the IMAP4 account. + function Connect(const AAutoLogin: boolean = true): Boolean; reintroduce; virtual; + //Closes the current selected mailbox in the account. + function CloseMailBox: Boolean; + //Creates a new mailbox with the specified name in the account. + function CreateMailBox(const AMBName: String): Boolean; + //Deletes the specified mailbox from the account. + function DeleteMailBox(const AMBName: String): Boolean; + //Marks messages for deletion, it will be deleted when the mailbox is purged. + function DeleteMsgs(const AMsgNumList: array of UInt32): Boolean; + //Logouts and disconnects from the IMAP account. + procedure Disconnect(ANotifyPeer: Boolean); override; + procedure DisconnectNotifyPeer; override; + //Examines the specified mailbox and inserts the results to the TIdMailBox provided. + function ExamineMailBox(const AMBName: String; AMB: TIdMailBox): Boolean; + //Expunges (deletes the marked files) the current selected mailbox in the account. + function ExpungeMailBox: Boolean; + //Sends a NOOP (No Operation) to keep the account connection with the server alive. + procedure KeepAlive; + //Returns a list of all the child mailboxes (one level down) to the mailbox supplied. + //This should be used when you fear that there are too many mailboxes and the listing of + //all of them could be time consuming, so this should be used to retrieve specific mailboxes. + function ListInferiorMailBoxes(AMailBoxList, AInferiorMailBoxList: TStrings): Boolean; + //Returns a list of all the mailboxes in the user account. + function ListMailBoxes(AMailBoxList: TStrings): Boolean; + //Returns a list of all the subscribed mailboxes in the user account. + function ListSubscribedMailBoxes (AMailBoxList: TStrings): Boolean; + //Renames the specified mailbox in the account. + function RenameMailBox(const AOldMBName, ANewMBName: String): Boolean; + //Searches the current selected mailbox for messages matching the SearchRec and + //returns the results to the mailbox SearchResults array. + function SearchMailBox(const ASearchInfo: array of TIdIMAP4SearchRec; const ACharSet: string = ''): Boolean; + //Selects the current a mailbox in the account. + function SelectMailBox(const AMBName: String): Boolean; + //Retrieves the status of the indicated mailbox. + {CC2: It is pointless calling StatusMailBox with AStatusDataItems set to [] + because you are asking the IMAP server to update none of the status flags. + Instead, if called with no AStatusDataItems specified, we use the standard flags + returned by SelectMailBox, which allows the user to easily check if the mailbox + has changed.} + function StatusMailBox(const AMBName: String; AMB: TIdMailBox): Boolean; overload; + function StatusMailBox(const AMBName: String; AMB: TIdMailBox; + const AStatusDataItems: array of TIdIMAP4StatusDataItem): Boolean; overload; + //Changes (adds or removes) message flags. + function StoreFlags(const AMsgNumList: array of UInt32; const AStoreMethod: TIdIMAP4StoreDataItem; + const AFlags: TIdMessageFlagsSet): Boolean; + //Changes (adds or removes) a message value. + function StoreValue(const AMsgNumList: array of UInt32; const AStoreMethod: TIdIMAP4StoreDataItem; + const AField, AValue: String): Boolean; + //Adds the specified mailbox name to the server's set of "active" or "subscribed" + //mailboxes as returned by the LSUB command. + function SubscribeMailBox(const AMBName: String): Boolean; + {CC8: Added CopyMsg, should have always been there...} + function CopyMsg(const AMsgNum: UInt32; const AMBName: String): Boolean; + //Copies a message from the current selected mailbox to the specified mailbox. {Do not Localize} + function CopyMsgs(const AMsgNumList: array of UInt32; const AMBName: String): Boolean; + //Retrieves a whole message while marking it read. + function Retrieve(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; + //Retrieves a whole message "raw" and saves it to file, while marking it read. + function RetrieveNoDecodeToFile(const AMsgNum: UInt32; ADestFile: string): Boolean; + function RetrieveNoDecodeToFilePeek(const AMsgNum: UInt32; ADestFile: string): Boolean; + function RetrieveNoDecodeToStream(const AMsgNum: UInt32; AStream: TStream): Boolean; + function RetrieveNoDecodeToStreamPeek(const AMsgNum: UInt32; AStream: TStream): Boolean; + //Retrieves all envelope of the selected mailbox to the specified TIdMessageCollection. + function RetrieveAllEnvelopes(AMsgList: TIdMessageCollection): Boolean; + //Retrieves all headers of the selected mailbox to the specified TIdMessageCollection. + function RetrieveAllHeaders(AMsgList: TIdMessageCollection): Boolean; + //Retrieves the first NN headers of the selected mailbox to the specified TIdMessageCollection. + function RetrieveFirstHeaders(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; + //Retrieves all messages of the selected mailbox to the specified TIdMessageCollection. + function RetrieveAllMsgs(AMsgList: TIdMessageCollection): Boolean; + //Retrieves the first NN messages of the selected mailbox to the specified TIdMessageCollection. + function RetrieveFirstMsgs(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; + //Retrieves the message envelope, parses it, and discards the envelope. + function RetrieveEnvelope(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; + //Retrieves the message envelope into a TStringList but does NOT parse it. + function RetrieveEnvelopeRaw(const AMsgNum: UInt32; ADestList: TStrings): Boolean; + //Returnes the message flag values. + function RetrieveFlags(const AMsgNum: UInt32; var AFlags: TIdMessageFlagsSet): Boolean; + //Returnes a requested message value. + function RetrieveValue(const AMsgNum: UInt32; const AField: string; var AValue: string): Boolean; + {CC2: Following added for retrieving individual parts of a message...} + function InternalRetrieveStructure(const AMsgNum: UInt32; AMsg: TIdMessage; AParts: TIdImapMessageParts): Boolean; + //Retrieve only the message structure (this tells you what parts are in the message). + function RetrieveStructure(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; overload; + function RetrieveStructure(const AMsgNum: UInt32; AParts: TIdImapMessageParts): Boolean; overload; + {CC2: Following added for retrieving individual parts of a message...} + {Retrieve a specific individual part of a message to a stream (part/sub-part like '2' or '2.3')...} + function RetrievePart(const AMsgNum: UInt32; const APartNum: string; + ADestStream: TStream; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} + {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...} + function RetrievePart(const AMsgNum: UInt32; const APartNum: string; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} + {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...} + function RetrievePart(const AMsgNum: UInt32; const APartNum: Integer; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} + {Retrieve a specific individual part of a message to a stream (part/sub-part like '2' or '2.3') + without marking the message as "read"...} + function RetrievePartPeek(const AMsgNum: UInt32; const APartNum: string; + ADestStream: TStream; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} + {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3' + without marking the message as "read"...} + function RetrievePartPeek(const AMsgNum: UInt32; const APartNum: string; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} + {Retrieve a specific individual part of a message where part is an integer (for backward compatibility) + without marking the message as "read"...} + function RetrievePartPeek(const AMsgNum: UInt32; const APartNum: Integer; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} + {CC2: Following added for retrieving individual parts of a message...} + {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...} + function RetrievePartToFile(const AMsgNum: UInt32; const APartNum: Integer; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; + {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...} + function RetrievePartToFile(const AMsgNum: UInt32; const APartNum: string; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; + {CC2: Following added for retrieving individual parts of a message...} + {Retrieve a specific individual part of a message where part is an integer (for backward compatibility) + without marking the message as "read"...} + function RetrievePartToFilePeek(const AMsgNum: UInt32; const APartNum: Integer; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; + {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3' + without marking the message as "read"...} + function RetrievePartToFilePeek(const AMsgNum: UInt32; const APartNum: string; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; + {CC3: Following added for retrieving the text-only part of a message...} + function RetrieveText(const AMsgNum: UInt32; var AText: string): Boolean; + {CC4: An alternative for retrieving the text-only part of a message which + may give a better response from some IMAP implementations...} + function RetrieveText2(const AMsgNum: UInt32; var AText: string): Boolean; + {CC3: Following added for retrieving the text-only part of a message + without marking the message as "read"...} + function RetrieveTextPeek(const AMsgNum: UInt32; var AText: string): Boolean; + function RetrieveTextPeek2(const AMsgNum: UInt32; var AText: string): Boolean; + //Retrieves only the message header. + function RetrieveHeader (const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; + //CCD: Retrieve the header for a particular part... + function RetrievePartHeader(const AMsgNum: UInt32; const APartNum: string; AHeaders: TIdHeaderList): Boolean; + //Retrives the current selected mailbox size. + function RetrieveMailBoxSize: Int64; + //Returnes the message size. + function RetrieveMsgSize(const AMsgNum: UInt32): Int64; + //Retrieves a whole message while keeping its Seen flag unchanged + //(preserving the previous value). + function RetrievePeek(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; + //Get the UID corresponding to a relative message number. + function GetUID(const AMsgNum: UInt32; var AUID: string): Boolean; + //Copies a message from the current selected mailbox to the specified mailbox. + function UIDCopyMsg(const AMsgUID: String; const AMBName: String): Boolean; + {CC8: Added UID version of CopyMsgs...} + function UIDCopyMsgs(const AMsgUIDList: TStrings; const AMBName: String): Boolean; + //Checks if the message was read or not. + function UIDCheckMsgSeen(const AMsgUID: String): Boolean; + //Marks a message for deletion, it will be deleted when the mailbox will be purged. + function UIDDeleteMsg(const AMsgUID: String): Boolean; + function UIDDeleteMsgs(const AMsgUIDList: array of String): Boolean; + //Retrieves all envelope and UID of the selected mailbox to the specified TIdMessageCollection. + function UIDRetrieveAllEnvelopes(AMsgList: TIdMessageCollection): Boolean; + //Retrieves a whole message while marking it read. + function UIDRetrieve(const AMsgUID: String; AMsg: TIdMessage): Boolean; + //Retrieves a whole message "raw" and saves it to file, while marking it read. + function UIDRetrieveNoDecodeToFile(const AMsgUID: String; ADestFile: string): Boolean; + function UIDRetrieveNoDecodeToFilePeek(const AMsgUID: String; ADestFile: string): Boolean; + function UIDRetrieveNoDecodeToStream(const AMsgUID: String; AStream: TStream): Boolean; + function UIDRetrieveNoDecodeToStreamPeek(const AMsgUID: String; AStream: TStream): Boolean; + //Retrieves the message envelope, parses it, and discards the envelope. + function UIDRetrieveEnvelope(const AMsgUID: String; AMsg: TIdMessage): Boolean; + //Retrieves the message envelope into a TStringList but does NOT parse it. + function UIDRetrieveEnvelopeRaw(const AMsgUID: String; ADestList: TStrings): Boolean; + //Returnes the message flag values. + function UIDRetrieveFlags(const AMsgUID: String; var AFlags: TIdMessageFlagsSet): Boolean; + //Returnes a requested message value. + function UIDRetrieveValue(const AMsgUID: String; const AField: string; var AValue: string): Boolean; + {CC2: Following added for retrieving individual parts of a message...} + function UIDInternalRetrieveStructure(const AMsgUID: String; AMsg: TIdMessage; AParts: TIdImapMessageParts): Boolean; + //Retrieve only the message structure (this tells you what parts are in the message). + function UIDRetrieveStructure(const AMsgUID: String; AMsg: TIdMessage): Boolean; overload; + function UIDRetrieveStructure(const AMsgUID: String; AParts: TIdImapMessageParts): Boolean; overload; + {Retrieve a specific individual part of a message to a stream (part/sub-part like '2' or '2.3')...} + function UIDRetrievePart(const AMsgUID: String; const APartNum: string; + var ADestStream: TStream; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} + {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...} + function UIDRetrievePart(const AMsgUID: String; const APartNum: string; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} + {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...} + function UIDRetrievePart(const AMsgUID: String; const APartNum: Integer; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} + {Retrieve a specific individual part of a message to a stream (part/sub-part like '2' or '2.3') + without marking the message as "read"...} + function UIDRetrievePartPeek(const AMsgUID: String; const APartNum: string; + var ADestStream: TStream; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} + {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...} + function UIDRetrievePartPeek(const AMsgUID: String; const APartNum: string; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} + {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...} + function UIDRetrievePartPeek(const AMsgUID: String; const APartNum: Integer; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string = 'text'): Boolean; overload; {Do not Localize} + {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...} + function UIDRetrievePartToFile(const AMsgUID: String; const APartNum: Integer; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; + {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...} + function UIDRetrievePartToFile(const AMsgUID: String; const APartNum: string; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; + {Retrieve a specific individual part of a message where part is an integer (for backward compatibility)...} + function UIDRetrievePartToFilePeek(const AMsgUID: String; const APartNum: Integer; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; + {Retrieve a specific individual part of a message where part is an integer or sub-part like '2.3'...} + function UIDRetrievePartToFilePeek(const AMsgUID: String; const APartNum: string; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; overload; + {Following added for retrieving the text-only part of a message...} + function UIDRetrieveText(const AMsgUID: String; var AText: string): Boolean; + function UIDRetrieveText2(const AMsgUID: String; var AText: string): Boolean; + {Following added for retrieving the text-only part of a message without marking the message as read...} + function UIDRetrieveTextPeek(const AMsgUID: String; var AText: string): Boolean; + function UIDRetrieveTextPeek2(const AMsgUID: String; var AText: string): Boolean; + //Retrieves only the message header. + function UIDRetrieveHeader(const AMsgUID: String; AMsg: TIdMessage): Boolean; + //Retrieve the header for a particular part... + function UIDRetrievePartHeader(const AMsgUID: String; const APartNum: string; AHeaders: TIdHeaderList): Boolean; + //Retrives the current selected mailbox size. + function UIDRetrieveMailBoxSize: Int64; + //Returnes the message size. + function UIDRetrieveMsgSize(const AMsgUID: String): Int64; + //Retrieves a whole message while keeping its Seen flag untucked + //(preserving the previous value). + function UIDRetrievePeek(const AMsgUID: String; AMsg: TIdMessage): Boolean; + //Searches the current selected mailbox for messages matching the SearchRec and + //returnes the results as UIDs to the mailbox SearchResults array. + function UIDSearchMailBox(const ASearchInfo: array of TIdIMAP4SearchRec; const ACharSet: String = ''): Boolean; + //Changes (adds or removes) message flags. + function UIDStoreFlags(const AMsgUID: String; const AStoreMethod: TIdIMAP4StoreDataItem; + const AFlags: TIdMessageFlagsSet): Boolean; overload; + function UIDStoreFlags(const AMsgUIDList: array of String; const AStoreMethod: TIdIMAP4StoreDataItem; + const AFlags: TIdMessageFlagsSet): Boolean; overload; + //Changes (adds or removes) a message value. + function UIDStoreValue(const AMsgUID: String; const AStoreMethod: TIdIMAP4StoreDataItem; + const AField, AValue: String): Boolean; overload; + function UIDStoreValue(const AMsgUIDList: array of String; const AStoreMethod: TIdIMAP4StoreDataItem; + const AField, AValue: string): Boolean; overload; + //Removes the specified mailbox name from the server's set of "active" or "subscribed" + //mailboxes as returned by the LSUB command. + function UnsubscribeMailBox(const AMBName: String): Boolean; + { IdTCPConnection Commands } + function GetInternalResponse(const ATag: String; AExpectedResponses: array of String; ASingleLineMode: Boolean; + ASingleLineMayBeSplit: Boolean = True): string; reintroduce; overload; + function GetResponse: string; reintroduce; overload; + function SendCmd(const AOut: string; AExpectedResponses: array of String; + ASingleLineMode: Boolean = False; ASingleLineMayBeSplit: Boolean = True): string; reintroduce; overload; + function SendCmd(const ATag, AOut: string; AExpectedResponses: array of String; + ASingleLineMode: Boolean = False; ASingleLineMayBeSplit: Boolean = True): string; overload; + function ReadLnWait: string; {$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use IOHandler.ReadLnWait()'{$ENDIF};{$ENDIF} + procedure WriteLn(const AOut: string = ''); {$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use IOHandler.WriteLn()'{$ENDIF};{$ENDIF} + { IdTCPConnection Commands } + + property IPVersion; + published + property OnAlert: TIdAlertEvent read FOnAlert write FOnAlert; + property Password; + property RetrieveOnSelect: TIdRetrieveOnSelect read FRetrieveOnSelect write FRetrieveOnSelect default rsDisabled; + property Port default IdPORT_IMAP4; + property Username; + property MailBoxSeparator: Char read FMailBoxSeparator write FMailBoxSeparator default '/'; {Do not Localize} + {GreetingBanner added because it may help identify the server...} + property GreetingBanner : string read FGreetingBanner; + property Host; + property UseTLS; + property SASLMechanisms : TIdSASLEntries read FSASLMechanisms write SetSASLMechanisms; + property AuthType : TIdIMAP4AuthenticationType read FAuthType write FAuthType default DEF_IMAP4_AUTH; + property MilliSecsToWaitToClearBuffer: integer read FMilliSecsToWaitToClearBuffer write FMilliSecsToWaitToClearBuffer; + {The following is the OnWork property for use when retrieving PARTS of a message. + It is also used for AppendMsg and Retrieve. This is in addition to the normal + OnWork property, which is exposed by TIdIMAP4, but which is only activated during + IMAP sending & receiving of commands (subject to the general OnWork caveats, i.e. + it is only called during certain methods, note OnWork[Begin][End] are all only + called in the methods AllData(), PerformCapture() and Read/WriteStream() ). + When a PART of a message is processed, use this for progress notification of + retrieval of IMAP parts, such as retrieving attachments. OnWorkBegin and + OnWorkEnd are not exposed, because they won't be activated during the processing + of a part.} + property OnWorkForPart: TWorkEvent read FOnWorkForPart write FOnWorkForPart; + property OnWorkBeginForPart: TWorkBeginEvent read FOnWorkBeginForPart write FOnWorkBeginForPart; + property OnWorkEndForPart: TWorkEndEvent read FOnWorkEndForPart write FOnWorkEndForPart; + end; + +implementation + +uses + //facilitate inlining on + {$IFDEF KYLIXCOMPAT} + Libc, + {$IFDEF MACOSX} + Posix.Unistd, + {$ENDIF} + {$ENDIF} + //facilitate inlining only. + {$IFDEF WINDOWS} + {$IFDEF USE_INLINE} + Windows, + {$ELSE} + //facilitate inlining only. + {$IFDEF VCL_2009_OR_ABOVE} + Windows, + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$IFDEF DOTNET} + {$IFDEF USE_INLINE} + System.IO, + {$ENDIF} + {$ENDIF} + {$IFDEF DOTNET} + IdStreamNET, + {$ELSE} + IdStreamVCL, + {$ENDIF} + {$IFDEF HAS_UNIT_Generics_Collections} + System.Generics.Collections, + {$ENDIF} + IdCoder, + IdEMailAddress, + IdExplicitTLSClientServerBase, + IdGlobalProtocols, + IdExceptionCore, + IdStack, + IdStackConsts, + IdStream, + IdTCPStream, + IdText, + IdAttachment, + IdResourceStringsProtocols, + IdBuffer, + IdAttachmentMemory, + IdReplyIMAP4, + IdTCPConnection, + IdSSL, + IdSASL, + IdMessageHelper, + SysUtils; + +type + TIdIMAP4FetchDataItem = ( + fdAll, //Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE) + fdBody, //Non-extensible form of BODYSTRUCTURE. + fdBodyExtensible, + fdBodyPeek, + fdBodyStructure, //The [MIME-IMB] body structure of the message. This + //is computed by the server by parsing the [MIME-IMB] + //header fields in the [RFC-822] header and [MIME-IMB] headers. + fdEnvelope, //The envelope structure of the message. This is + //computed by the server by parsing the [RFC-822] + //header into the component parts, defaulting various + //fields as necessary. + fdFast, //Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE) + fdFlags, //The flags that are set for this message. + fdFull, //Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY) + fdInternalDate, //The internal date of the message. + fdRFC822, //Functionally equivalent to BODY[], differing in the + //syntax of the resulting untagged FETCH data (RFC822 + //is returned). + fdRFC822Header, //Functionally equivalent to BODY.PEEK[HEADER], + //differing in the syntax of the resulting untagged + //FETCH data (RFC822.HEADER is returned). + fdRFC822Size, //The [RFC-822] size of the message. + fdRFC822Text, //Functionally equivalent to BODY[TEXT], differing in + //the syntax of the resulting untagged FETCH data + //(RFC822.TEXT is returned). + fdHeader, //CC: Added to get the header of a part + fdUID, //The unique identifier for the message. + fdGmailMsgID, //Gmail-specific unique identifier for the message. + fdGmailThreadID, //Gmail-specific thread identifier for the message. + fdGmailLabels //Gmail-specific labels for the message. + ); + +const + IMAP4Commands : array [TIdIMAP4Commands] of String = ( + { Client Commands - Any State} + 'CAPABILITY', {Do not Localize} + 'NOOP', {Do not Localize} + 'LOGOUT', {Do not Localize} + { Client Commands - Non Authenticated State} + 'AUTHENTICATE', {Do not Localize} + 'LOGIN', {Do not Localize} + { Client Commands - Authenticated State} + 'SELECT', {Do not Localize} + 'EXAMINE', {Do not Localize} + 'CREATE', {Do not Localize} + 'DELETE', {Do not Localize} + 'RENAME', {Do not Localize} + 'SUBSCRIBE', {Do not Localize} + 'UNSUBSCRIBE', {Do not Localize} + 'LIST', {Do not Localize} + 'LSUB', {Do not Localize} + 'STATUS', {Do not Localize} + 'APPEND', {Do not Localize} + { Client Commands - Selected State} + 'CHECK', {Do not Localize} + 'CLOSE', {Do not Localize} + 'EXPUNGE', {Do not Localize} + 'SEARCH', {Do not Localize} + 'FETCH', {Do not Localize} + 'STORE', {Do not Localize} + 'COPY', {Do not Localize} + 'UID', {Do not Localize} + { Client Commands - Experimental/ Expansion} + 'X' {Do not Localize} + ); + + IMAP4FetchDataItem : array [TIdIMAP4FetchDataItem] of String = ( + 'ALL', {Do not Localize} //Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE) + 'BODY', {Do not Localize} //Non-extensible form of BODYSTRUCTURE. + 'BODY[%s]<%s>', {Do not Localize} + 'BODY.PEEK[]', {Do not Localize} + 'BODYSTRUCTURE', {Do not Localize} //The [MIME-IMB] body structure of the message. This + //is computed by the server by parsing the [MIME-IMB] + //header fields in the [RFC-822] header and [MIME-IMB] headers. + 'ENVELOPE', {Do not Localize} //The envelope structure of the message. This is + //computed by the server by parsing the [RFC-822] + //header into the component parts, defaulting various + //fields as necessary. + 'FAST', {Do not Localize} //Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE) + 'FLAGS', {Do not Localize} //The flags that are set for this message. + 'FULL', {Do not Localize} //Macro equivalent to: (FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODY) + 'INTERNALDATE', {Do not Localize} //The internal date of the message. + 'RFC822', {Do not Localize} //Functionally equivalent to BODY[], differing in the + //syntax of the resulting untagged FETCH data (RFC822 + //is returned). + 'RFC822.HEADER', {Do not Localize} //Functionally equivalent to BODY.PEEK[HEADER], + //differing in the syntax of the resulting untagged + //FETCH data (RFC822.HEADER is returned). + 'RFC822.SIZE', {Do not Localize} //The [RFC-822] size of the message. + 'RFC822.TEXT', {Do not Localize} //Functionally equivalent to BODY[TEXT], differing in + //the syntax of the resulting untagged FETCH data + //(RFC822.TEXT is returned). + 'HEADER', {Do not Localize} //CC: Added to get the header of a part + 'UID', {Do not Localize} //The unique identifier for the message. + 'X-GM-MSGID', {Do not Localize} //Gmail-specific unique identifier for the message. + 'X-GM-THRID', {Do not Localize} //Gmail-specific thread identifier for the message. + 'X-GM-LABELS' {Do not Localize} //Gmail-specific labels for the message. + ); + + IMAP4SearchKeys : array [TIdIMAP4SearchKey] of String = ( + 'ALL', {Do not Localize} //All messages in the mailbox; the default initial key for ANDing. + 'ANSWERED', {Do not Localize} //Messages with the \Answered flag set. + 'BCC', {Do not Localize} //Messages that contain the specified string in the envelope structure's BCC field. + 'BEFORE', {Do not Localize} //Messages whose internal date is earlier than the specified date. + 'BODY', {Do not Localize} //Messages that contain the specified string in the body of the message. + 'CC', {Do not Localize} //Messages that contain the specified string in the envelope structure's CC field. + 'DELETED', {Do not Localize} //Messages with the \Deleted flag set. + 'DRAFT', {Do not Localize} //Messages with the \Draft flag set. + 'FLAGGED', {Do not Localize} //Messages with the \Flagged flag set. + 'FROM', {Do not Localize} //Messages that contain the specified string in the envelope structure's FROM field. + 'HEADER', {Do not Localize} //Messages that have a header with the specified field-name (as defined in [RFC-822]) + //and that contains the specified string in the [RFC-822] field-body. + 'KEYWORD', {Do not Localize} //Messages with the specified keyword set. + 'LARGER', {Do not Localize} //Messages with an [RFC-822] size larger than the specified number of octets. + 'NEW', {Do not Localize} //Messages that have the \Recent flag set but not the \Seen flag. + //This is functionally equivalent to "(RECENT UNSEEN)". + 'NOT', {Do not Localize} //Messages that do not match the specified search key. + 'OLD', {Do not Localize} //Messages that do not have the \Recent flag set. This is functionally + //equivalent to "NOT RECENT" (as opposed to "NOT NEW"). + 'ON', {Do not Localize} //Messages whose internal date is within the specified date. + 'OR', {Do not Localize} //Messages that match either search key. + 'RECENT', {Do not Localize} //Messages that have the \Recent flag set. + 'SEEN', {Do not Localize} //Messages that have the \Seen flag set. + 'SENTBEFORE',{Do not Localize} //Messages whose [RFC-822] Date: header is earlier than the specified date. + 'SENTON', {Do not Localize} //Messages whose [RFC-822] Date: header is within the specified date. + 'SENTSINCE', {Do not Localize} //Messages whose [RFC-822] Date: header is within or later than the specified date. + 'SINCE', {Do not Localize} //Messages whose internal date is within or later than the specified date. + 'SMALLER', {Do not Localize} //Messages with an [RFC-822] size smaller than the specified number of octets. + 'SUBJECT', {Do not Localize} //Messages that contain the specified string in the envelope structure's SUBJECT field. + 'TEXT', {Do not Localize} //Messages that contain the specified string in the header or body of the message. + 'TO', {Do not Localize} //Messages that contain the specified string in the envelope structure's TO field. + 'UID', {Do not Localize} //Messages with unique identifiers corresponding to the specified unique identifier set. + 'UNANSWERED',{Do not Localize} //Messages that do not have the \Answered flag set. + 'UNDELETED', {Do not Localize} //Messages that do not have the \Deleted flag set. + 'UNDRAFT', {Do not Localize} //Messages that do not have the \Draft flag set. + 'UNFLAGGED', {Do not Localize} //Messages that do not have the \Flagged flag set. + 'UNKEYWORD', {Do not Localize} //Messages that do not have the specified keyword set. + 'UNSEEN', {Do not Localize} + 'X-GM-RAW', {Do not Localize} //Gmail extension to SEARCH command to allow full access to Gmail search syntax + 'X-GM-MSGID',{Do not Localize} //Gmail extension to SEARCH command to allow access to Gmail message identifier + 'X-GM-THRID',{Do not Localize} //Gmail extension to SEARCH command to allow access to Gmail thread identifier + 'X-GM-LABELS'{Do not Localize} //Gmail extension to SEARCH command to allow access to Gmail labels + ); + + IMAP4StatusDataItem : array [TIdIMAP4StatusDataItem] of String = ( + 'MESSAGES', {Do not Localize} + 'RECENT', {Do not Localize} + 'UIDNEXT', {Do not Localize} + 'UIDVALIDITY', {Do not Localize} + 'UNSEEN' {Do not Localize} + ); + +function IMAPQuotedStr(const S: String): String; +begin + Result := '"' + StringsReplace(S, ['\', '"'], ['\\', '\"']) + '"'; {Do not Localize} +end; + +{ TIdSASLEntriesIMAP4 } + +// RLebeau 2/8/2013 - TIdSASLEntries.LoginSASL() uses TIdTCPConnection.SendCmd() +// but TIdIMAP4 does not override the necessary virtuals to make that SendCmd() +// work correctly with IMAP. TIdIMAP reintroduces its own SendCmd() implementation, +// which TIdSASLEntries does not call. Until that can be changed, we will have +// to send the IMAP 'AUTHENTICATE' command manually! Doing it this way so as +// not to introduce an interface change that breaks backwards compatibility... + +function CheckStrFail(const AStr : String; const AOk, ACont: array of string) : Boolean; +begin + //Result := PosInStrArray(AStr, AOk + ACont) = -1; + Result := (PosInStrArray(AStr, AOk) = -1) and + (PosInStrArray(AStr, ACont) = -1); +end; + +function PerformSASLLogin_IMAP(ASASL: TIdSASL; AEncoder: TIdEncoder; + ADecoder: TIdDecoder; AClient : TIdIMAP4): Boolean; +const + AOkReplies: array[0..0] of string = (IMAP_OK); + AContinueReplies: array[0..0] of string = (IMAP_CONT); +var + S: String; + AuthStarted: Boolean; +begin + Result := False; + AuthStarted := False; + + // TODO: use UTF-8 when base64-encoding strings... + + if AClient.IsCapabilityListed('SASL-IR') then begin {Do not localize} + if ASASL.TryStartAuthenticate(AClient.Host, AClient.Port, IdGSKSSN_imap, S) then begin + AClient.SendCmd(AClient.NewCmdCounter, 'AUTHENTICATE ' + String(ASASL.ServiceName) + ' ' + AEncoder.Encode(S), [], True); {Do not Localize} + if CheckStrFail(AClient.LastCmdResult.Code, AOkReplies, AContinueReplies) then begin + ASASL.FinishAuthenticate; + Exit; // this mechanism is not supported + end; + AuthStarted := True; + end; + end; + if not AuthStarted then begin + AClient.SendCmd(AClient.NewCmdCounter, 'AUTHENTICATE ' + String(ASASL.ServiceName), [], True); {Do not Localize} + if CheckStrFail(AClient.LastCmdResult.Code, AOkReplies, AContinueReplies) then begin + Exit; // this mechanism is not supported + end; + end; + if (PosInStrArray(AClient.LastCmdResult.Code, AOkReplies) > -1) then begin + if AuthStarted then begin + ASASL.FinishAuthenticate; + end; + Result := True; + Exit; // we've authenticated successfully :) + end; + // must be a continue reply... + if not AuthStarted then begin + S := ADecoder.DecodeString(TrimRight(TIdReplyIMAP4(AClient.LastCmdResult).Extra.Text)); + S := ASASL.StartAuthenticate(S, AClient.Host, AClient.Port, IdGSKSSN_imap); + AClient.IOHandler.WriteLn(AEncoder.Encode(S)); + AClient.GetInternalResponse(AClient.LastCmdCounter, [], True); + if CheckStrFail(AClient.LastCmdResult.Code, AOkReplies, AContinueReplies) then + begin + ASASL.FinishAuthenticate; + Exit; + end; + end; + while PosInStrArray(AClient.LastCmdResult.Code, AContinueReplies) > -1 do begin + S := ADecoder.DecodeString(TrimRight(TIdReplyIMAP4(AClient.LastCmdResult).Extra.Text)); + S := ASASL.ContinueAuthenticate(S, AClient.Host, AClient.Port, IdGSKSSN_imap); + AClient.IOHandler.WriteLn(AEncoder.Encode(S)); + AClient.GetInternalResponse(AClient.LastCmdCounter, [], True); + if CheckStrFail(AClient.LastCmdResult.Code, AOkReplies, AContinueReplies) then + begin + ASASL.FinishAuthenticate; + Exit; + end; + end; + Result := (PosInStrArray(AClient.LastCmdResult.Code, AOkReplies) > -1); + ASASL.FinishAuthenticate; +end; + +type + {$IFDEF HAS_GENERICS_TList} + TIdSASLList = TList; + {$ELSE} + // TODO: flesh out to match TList for non-Generics compilers + TIdSASLList = TList; + {$ENDIF} + + TIdSASLEntriesIMAP4 = class(TIdSASLEntries) + public + procedure LoginSASL_IMAP(AClient: TIdIMAP4); + end; + +procedure TIdSASLEntriesIMAP4.LoginSASL_IMAP(AClient: TIdIMAP4); +var + i : Integer; + LE : TIdEncoderMIME; + LD : TIdDecoderMIME; + LSupportedSASL : TStrings; + LSASLList: TIdSASLList; + LSASL : TIdSASL; + LError : TIdReply; + + function SetupErrorReply: TIdReply; + begin + Result := TIdReplyClass(AClient.LastCmdResult.ClassType).Create(nil); + Result.Assign(AClient.LastCmdResult); + end; + +begin + // make sure the collection is not empty + CheckIfEmpty; + + //create a list of mechanisms that both parties support + LSASLList := TIdSASLList.Create; + try + LSupportedSASL := TStringList.Create; + try + ParseCapaReplyToList(AClient.FCapabilities, LSupportedSASL, 'AUTH'); {Do not Localize} + for i := Count-1 downto 0 do begin + LSASL := Items[i].SASL; + if LSASL <> nil then begin + if not LSASL.IsAuthProtocolAvailable(LSupportedSASL) then begin + Continue; + end; + if LSASLList.IndexOf(LSASL) = -1 then begin + LSASLList.Add(LSASL); + end; + end; + end; + finally + FreeAndNil(LSupportedSASL); + end; + + if LSASLList.Count = 0 then begin + raise EIdSASLNotSupported.Create(RSSASLNotSupported); + end; + + //now do it + LE := nil; + try + LD := nil; + try + LError := nil; + try + for i := 0 to LSASLList.Count-1 do begin + LSASL := {$IFDEF HAS_GENERICS_TList}LSASLList.Items[i]{$ELSE}TIdSASL(LSASLList.Items[i]){$ENDIF}; + if not LSASL.IsReadyToStart then begin + Continue; + end; + if not Assigned(LE) then begin + LE := TIdEncoderMIME.Create(nil); + end; + if not Assigned(LD) then begin + LD := TIdDecoderMIME.Create(nil); + end; + if PerformSASLLogin_IMAP(LSASL, LE, LD, AClient) then begin + Exit; + end; + if not Assigned(LError) then begin + LError := SetupErrorReply; + end; + end; + if Assigned(LError) then begin + LError.RaiseReplyError; + end else begin + raise EIdSASLNotReady.Create(RSSASLNotReady); + end; + finally + FreeAndNil(LError); + end; + finally + FreeAndNil(LD); + end; + finally + FreeAndNil(LE); + end; + finally + FreeAndNil(LSASLList); + end; +end; + +{ TIdIMAP4WorkHelper } + +type + TIdIMAP4WorkHelper = class(TIdComponent) + protected + fIMAP4: TIdIMAP4; + fOldTarget: TIdComponent; + public + constructor Create(AIMAP4: TIdIMAP4); reintroduce; + destructor Destroy; override; + end; + +constructor TIdIMAP4WorkHelper.Create(AIMAP4: TIdIMAP4); +begin + inherited Create(nil); + fIMAP4 := AIMAP4; + fOldTarget := fIMAP4.WorkTarget; + fIMAP4.WorkTarget := Self; + Self.OnWorkBegin := fIMAP4.BeginWorkForPart; + Self.OnWork := fIMAP4.DoWorkForPart; + Self.OnWorkEnd := fIMAP4.EndWorkForPart; +end; + +destructor TIdIMAP4WorkHelper.Destroy; +begin + fIMAP4.WorkTarget := fOldTarget; + inherited Destroy; +end; + +{ TIdEMUTF7 } + +const + b64Chars : String = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,'; {Do not Localize} + + b64Index : array [0..127] of Integer = ( + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 16 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, // 32 + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,63,-1,-1,-1, // 48 + 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, // 64 + -1,00,01,02,03,04,05,06,07,08,09,10,11,12,13,14, // 80 + 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, // 96 + -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, // 112 + 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1 // 128 + ); + + b64Table : array[0..127] of Integer = ( + $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, // 16 + $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF, // 32 + $20,$21,$22,$23, $24,$25,$FF,$27, $28,$29,$2A,$2B, $2C,$2D,$2E,$2F, // 48 + $30,$31,$32,$33, $34,$35,$36,$37, $38,$39,$3A,$3B, $3C,$3D,$3E,$3F, // 64 + $40,$41,$42,$43, $44,$45,$46,$47, $48,$49,$4A,$4B, $4C,$4D,$4E,$4F, // 80 + $50,$51,$52,$53, $54,$55,$56,$57, $58,$59,$5A,$5B, $5C,$5D,$5E,$5F, // 96 + $60,$61,$62,$63, $64,$65,$66,$67, $68,$69,$6A,$6B, $6C,$6D,$6E,$6F, // 112 + $70,$71,$72,$73, $74,$75,$76,$77, $78,$79,$7A,$7B, $7C,$7D,$7E,$FF);// 128 + +// TODO: re-write this to derive from IdCoder3To4.pas or IdCoderMIME.pas classes... + +function TIdMUTF7.Encode(const aString: TIdUnicodeString): String; +{ -- MUTF7Encode ------------------------------------------------------------- +PRE: nothing +POST: returns a string encoded as described in IETF RFC 3501, section 5.1.3 + based upon RFC 2152 + + 2004-03-02 roman puls: speed improvements of around 2000 percent due to + replacement of pchar/while loops to delphi-style string/for + loops. Minor changes for '&' handling. Delphi 8 compatible. + 2004-02-29 roman puls: initial version ---} +var + c : Word; + bitBuf : UInt32; + bitShift : Integer; + x : Integer; + escaped : Boolean; + CharToAppend: Char; + {$IFDEF STRING_IS_IMMUTABLE} + LSB: TIdStringBuilder; + {$ENDIF} +begin + Result := ''; + escaped := False; + bitShift := 0; + bitBuf := 0; + + {$IFDEF STRING_IS_IMMUTABLE} + LSB := TIdStringBuilder.Create; + {$ENDIF} + + for x := 1 to Length(aString) do begin + c := Word(aString[x]); + // c must be < 128 _and_ in table b64table + if (c <= $7f) and (b64Table[c] <> $FF) or (aString[x] = '&') then begin // we can directly encode that char + if escaped then begin + if (bitShift > 0) then begin // flush bitbuffer if needed + CharToAppend := b64Chars[(bitBuf shl (6 - bitShift) and $3F) + 1]; + {$IFDEF STRING_IS_IMMUTABLE} + LSB.Append(CharToAppend); + {$ELSE} + Result := Result + CharToAppend; + {$ENDIF} + end; + {$IFDEF STRING_IS_IMMUTABLE} + LSB.Append(Char('-')); // leave escape sequence + {$ELSE} + Result := Result + '-'; // leave escape sequence + {$ENDIF} + escaped := False; + end; + if (aString[x] = '&') then begin // escape special char "&" + {$IFDEF STRING_IS_IMMUTABLE} + LSB.Append('&-'); + {$ELSE} + Result := Result + '&-'; + {$ENDIF} + end else begin + CharToAppend := Char(c); + {$IFDEF STRING_IS_IMMUTABLE} + LSB.Append(CharToAppend); // store direct translated char + {$ELSE} + Result := Result + CharToAppend; // store direct translated char + {$ENDIF} + end; + end else begin + if not escaped then begin + {$IFDEF STRING_IS_IMMUTABLE} + LSB.Append(Char('&')); + {$ELSE} + Result := Result + '&'; + {$ENDIF} + bitShift := 0; + bitBuf := 0; + escaped := True; + end; + bitbuf := (bitBuf shl 16) or c; // shift and store new bye + Inc(bitShift, 16); + while (bitShift >= 6) do begin // flush buffer as far as we can + Dec(bitShift, 6); + CharToAppend := b64Chars[((bitBuf shr bitShift) and $3F) + 1]; + {$IFDEF STRING_IS_IMMUTABLE} + LSB.Append(CharToAppend); + {$ELSE} + Result := Result + CharToAppend; + {$ENDIF} + end; + end; + end; + + // we love duplicate work but must test for flush buffers for the price + // of speed (loop) + if escaped then begin + if (bitShift > 0) then begin + CharToAppend := b64Chars[(bitBuf shl (6 - bitShift) and $3F) + 1]; + {$IFDEF STRING_IS_IMMUTABLE} + LSB.Append(CharToAppend); + {$ELSE} + Result := Result + CharToAppend; + {$ENDIF} + end; + {$IFDEF STRING_IS_IMMUTABLE} + LSB.Append(Char('-')); + {$ELSE} + Result := Result + '-'; + {$ENDIF} + end; + + {$IFDEF STRING_IS_IMMUTABLE} + Result := LSB.ToString; + {$ENDIF} +end; + +function TIdMUTF7.Decode(const aString: String): TIdUnicodeString; +{ -- mUTF7Decode ------------------------------------------------------------- +PRE: aString encoding must conform to IETF RFC 3501, section 5.1.3 +POST: SUCCESS: an 8bit string + FAILURE: an exception of type EMUTF7Decode + + 2004-03-02 roman puls: speed improvements of around 400 percent due to + replacement of pchar/while loops to delphi-style string/for + loops. Delphi 8 compatible. + 2004-02-29 roman puls: initial version ---} +const + bitMasks: array[0..4] of UInt32 = ($00000000, $00000001, $00000003, $00000007, $0000000F); +var + ch : Byte; + last : Char; + bitBuf : UInt32; + escaped : Boolean; + x, bitShift: Integer; + CharToAppend: WideChar; + {$IFDEF STRING_IS_IMMUTABLE} + LSB: TIdStringBuilder; + {$ENDIF} +begin + Result := ''; + escaped := False; + bitShift := 0; + last := #0; + bitBuf := 0; + + {$IFDEF STRING_IS_IMMUTABLE} + LSB := TIdStringBuilder.Create; + {$ENDIF} + + for x := 1 to Length(aString) do begin + ch := Byte(aString[x]); + if not escaped then begin + if (aString[x] = '&') then begin // escape sequence found + escaped := True; + bitBuf := 0; + bitShift := 0; + last := '&'; + end + else if (ch < $80) and (b64Table[ch] <> $FF) then begin + {$IFDEF STRING_IS_IMMUTABLE} + LSB.Append(WideChar(ch)); + {$ELSE} + Result := Result + WideChar(ch); + {$ENDIF} + end else begin + raise EMUTF7Decode.CreateFmt('Illegal char #%d in UTF7 sequence.', [Integer(ch)]); {do not localize} + end; + end else begin // we're escaped + { break out of escape mode } + if (aString[x] = '-') then begin + // extra check for pending bits + if (last = '&') then begin // special sequence '&-' ? + {$IFDEF STRING_IS_IMMUTABLE} + LSB.Append(Char('&')); + {$ELSE} + Result := Result + '&'; + {$ENDIF} + end else begin + if (bitShift >= 16) then begin + Dec(bitShift, 16); + CharToAppend := WideChar((bitBuf shr bitShift) and $FFFF); + {$IFDEF STRING_IS_IMMUTABLE} + LSB.Append(CharToAppend); + {$ELSE} + Result := Result + CharToAppend; + {$ENDIF} + end; + if (bitShift > 4) or ((bitBuf and bitMasks[bitShift]) <> 0) then begin // check for bitboundaries + raise EMUTF7Decode.Create('Illegal bit sequence in MUTF7 string'); {do not localize} + end; + end; + escaped := False; + end else begin // still escaped + // check range for ch: must be < 128 and in b64table + if (ch >= $80) or (b64Index[ch] = -1) then begin + raise EMUTF7Decode.CreateFmt('Illegal char #%d in UTF7 sequence.', [Integer(ch)]); {do not localize} + end; + ch := b64Index[ch]; + bitBuf := (bitBuf shl 6) or (ch and $3F); + Inc(bitShift, 6); + if (bitShift >= 16) then begin + Dec(bitShift, 16); + CharToAppend := WideChar((bitBuf shr bitShift) and $FFFF); + {$IFDEF STRING_IS_IMMUTABLE} + LSB.Append(CharToAppend); + {$ELSE} + Result := Result + CharToAppend; + {$ENDIF} + end; + end; + last := #0; + end; + end; + if escaped then begin + raise EmUTF7Decode.Create('Missing unescape in UTF7 sequence.'); {do not localize} + end; + + {$IFDEF STRING_IS_IMMUTABLE} + Result := LSB.ToString; + {$ENDIF} +end; + +function TIdMUTF7.Valid(const aMUTF7String : String): Boolean; +{ -- mUTF7valid ------------------------------------------------------------- +PRE: NIL +POST: returns true if string is correctly encoded (as described in mUTF7Encode) + returns false otherwise +} +begin + try + Result := (aMUTF7String = {mUTF7}Encode({mUTF7}Decode(aMUTF7String))); + except + on e: EmUTF7Error do begin + Result := False; + end; + // do not handle others + end; +end; + +function TIdMUTF7.Append(const aMUTF7String: String; const aStr : TIdUnicodeString): String; +{ -- mUTF7Append ------------------------------------------------------------- +PRE: aMUTF7String is complying to mUTF7Encode's description +POST: SUCCESS: a concatenation of both input strings in mUTF + FAILURE: an exception of EMUTF7Decode or EMUTF7Encode will be raised +} +begin + Result := {mUTF7}Encode({mUTF7}Decode(aMUTF7String) + aStr); +end; + +{ TIdImapMessageParts } + +constructor TIdImapMessagePart.Create(Collection: TCollection); +begin + {Make sure these are initialised properly...} + inherited Create(Collection); + FParentPart := -1; + FBoundary := ''; {Do not Localize} +end; + +constructor TIdImapMessageParts.Create(AOwner: TPersistent); +begin + inherited Create(AOwner, TIdImapMessagePart); +end; + +function TIdImapMessageParts.GetItem(Index: Integer): TIdImapMessagePart; +begin + Result := TIdImapMessagePart(inherited GetItem(Index)); +end; + +function TIdImapMessageParts.Add: TIdImapMessagePart; +begin + Result := TIdImapMessagePart(inherited Add); +end; + +procedure TIdImapMessageParts.SetItem(Index: Integer; const Value: TIdImapMessagePart); +begin + inherited SetItem(Index, Value); +end; + +{ TIdIMAP4 } + +procedure TIdIMAP4.BeginWorkForPart(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); +begin + if Assigned(FOnWorkBeginForPart) then begin + FOnWorkBeginForPart(Self, AWorkMode, AWorkCountMax); + end; +end; + +procedure TIdIMAP4.DoWorkForPart(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); +begin + if Assigned(FOnWorkForPart) then begin + FOnWorkForPart(Self, AWorkMode, AWorkCount); + end; +end; + +procedure TIdIMAP4.EndWorkForPart(ASender: TObject; AWorkMode: TWorkMode); +begin + if Assigned(FOnWorkEndForPart) then begin + FOnWorkEndForPart(Self, AWorkMode); + end; +end; + +//The following call FMUTF7 but do exception-handling on invalid strings... +function TIdIMAP4.DoMUTFEncode(const aString : String): String; +begin + // TODO: if the server advertises the "UTF8=ACCEPT" capability, use + // a UTF-8 quoted string instead of IMAP's Modified UTF-7... + try + Result := FMUTF7.Encode( + {$IFDEF STRING_IS_UNICODE} + aString + {$ELSE} + TIdUnicodeString(aString) // explicit convert to Unicode + {$ENDIF} + ); + except + Result := aString; + end; +end; + +function TIdIMAP4.DoMUTFDecode(const aString : String): String; +begin + try + {$IFDEF STRING_IS_UNICODE} + Result := FMUTF7.Decode(aString); + {$ELSE} + Result := String(FMUTF7.Decode(aString)); // explicit convert to Ansi + {$ENDIF} + except + Result := aString; + end; +end; + +function TIdIMAP4.GetReplyClass:TIdReplyClass; +begin + Result := TIdReplyIMAP4; +end; + +function TIdIMAP4.GetSupportsTLS: Boolean; +begin + Result := IsCapabilityListed('STARTTLS'); //do not localize +end; + +function TIdIMAP4.CheckConnectionState(AAllowedState: TIdIMAP4ConnectionState): TIdIMAP4ConnectionState; +begin + if FConnectionState = AAllowedState then begin + Result := FConnectionState; + end else begin + raise EIdConnectionStateError.CreateFmt(RSIMAP4ConnectionStateError, [GetConnectionStateName]); + end; +end; + +function TIdIMAP4.CheckConnectionState(const AAllowedStates: array of TIdIMAP4ConnectionState): TIdIMAP4ConnectionState; +var + i: integer; +begin + if High(AAllowedStates) > -1 then begin + // Cannot use PosInSmallIntArray() here... + for i := Low(AAllowedStates) to High(AAllowedStates) do begin + if FConnectionState = AAllowedStates[i] then begin + Result := FConnectionState; + Exit; + end; + end; + end; + raise EIdConnectionStateError.CreateFmt(RSIMAP4ConnectionStateError, [GetConnectionStateName]); +end; + +function TIdIMAP4.CheckReplyForCapabilities: Boolean; +var + I: Integer; + LExtra: TStrings; +begin + FCapabilities.Clear; + FHasCapa := False; + LExtra := TIdReplyIMAP4(FLastCmdResult).Extra; + for I := 0 to LExtra.Count-1 do begin + if TextStartsWith(LExtra.Strings[I], 'CAPABILITY ') then begin {Do not Localize} + BreakApart(LExtra.Strings[I], ' ', FCapabilities); {Do not Localize} + // RLebeau: do not delete the first item anymore! It specifies the IMAP + // version/revision, which is needed to support certain extensions, like + // 'IMAP4rev1'... + {FCapabilities.Delete(0);} + FHasCapa := True; + Break; + end; + end; + Result := FHasCapa; +end; + +function TIdIMAP4.FindHowServerCreatesFolders: TIdIMAP4FolderTreatment; +var + LUsersFolders: TStringList; + LN: integer; + LInbox: string; + LTestFolder: string; +begin + LUsersFolders := TStringList.Create; + try + {$IFDEF HAS_TStringList_CaseSensitive} + LUsersFolders.CaseSensitive := False; + {$ENDIF} + + //Get folder names... + if not ListMailBoxes(LUsersFolders) then begin + Result := ftCannotRetrieveAnyFolders; + Exit; + end; + + if LUsersFolders.Count = 0 then begin + Result := ftCannotRetrieveAnyFolders; + Exit; + end; + + //Do we have an Inbox? + LN := IndyIndexOf(LUsersFolders, 'INBOX'); {Do not Localize} + if LN = -1 then begin + Result := ftCannotTestBecauseHasNoInbox; + Exit; + end; + LInbox := LUsersFolders.Strings[LN]; + + //Make sure our test folder does not already exist at the top level... + LTestFolder := 'CiaransTestFolder'; {Do not Localize} + while IndyIndexOf(LUsersFolders, LTestFolder) <> -1 do begin + LTestFolder := LTestFolder + '9'; {Do not Localize} + end; + + //Try to create LTestFolder at the top level... + if CreateMailbox(LTestFolder) then begin + //We were able to create it at the top level - delete it and exit.. + DeleteMailbox(LTestFolder); + Result := ftAllowsTopLevelCreation; + Exit; + end; + + //See if our test folder does not exist under INBOX... + LTestFolder := LInbox + FMailBoxSeparator + 'CiaransTestFolder'; {Do not Localize} + while IndyIndexOf(LUsersFolders, LTestFolder) <> -1 do begin + LTestFolder := LTestFolder + '9'; {Do not Localize} + end; + + //Try to create LTestFolder under Inbox... + if CreateMailbox(LTestFolder) then begin + //We were able to create it under the top level - delete it and exit.. + DeleteMailbox(LTestFolder); + Result := ftFoldersMustBeUnderInbox; + Exit; + end; + + //It does not allow us create folders under any level (read-only?)... + Result := ftDoesNotAllowFolderCreation; + finally + FreeAndNil(LUsersFolders); + end; +end; + +function TIdIMAP4.IsNumberValid(const ANumber: UInt32): Boolean; + {CC3: Need to validate message numbers (relative and UIDs), because otherwise + the routines wait for a response that never arrives and so functions never return.} +begin + if ANumber < 1 then begin + raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); + end; + Result := True; +end; + +{$IFNDEF HAS_TryStrToInt64} +// TODO: move this to IdGlobalProtocols... +function TryStrToInt64(const S: string; out Value: Int64): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +var + E: Integer; +begin + Val(S, Value, E); + Result := E = 0; +end; +{$ENDIF} + +function UIDToUInt32(const AUID: String): UInt32; +var + LNumber: Int64; +begin + if Length(AUID) = 0 then begin + raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); + end; + if not TryStrToInt64(AUID, LNumber) then begin + raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); + end; + if (LNumber < 1) or (LNumber > Int64(High(UInt32))) then begin + raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); + end; + Result := UInt32(LNumber); +end; + +function TIdIMAP4.IsUIDValid(const AUID: string): Boolean; + {CC3: Need to validate message numbers (relative and UIDs), because otherwise + the routines wait for a response that never arrives and so functions never return.} +begin + //Must be digits only (no - or .) + IsItDigitsAndOptionallyPeriod(AUID, False); + UIDToUInt32(AUID); + Result := True; +end; + +function TIdIMAP4.IsImapPartNumberValid(const APartNum: Integer): Boolean; +begin + if APartNum < 1 then begin + raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); + end; + Result := True; +end; + +function TIdIMAP4.IsImapPartNumberValid(const APartNum: string): Boolean; + {CC3: IMAP part numbers are 3 or 4.5 etc, i.e. digits or period allowed} +begin + Result := IsItDigitsAndOptionallyPeriod(APartNum, True); +end; + +function TIdIMAP4.IsItDigitsAndOptionallyPeriod(const AStr: string; AAllowPeriod: Boolean): Boolean; +var + LN: integer; +begin + if Length(AStr) = 0 then begin + raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); + end; + if AAllowPeriod then begin + for LN := 1 to Length(AStr) do begin + if not IsNumeric(AStr[LN]) then begin + if AStr[LN] <> '.' then begin {Do not Localize} + raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); + end; + end; + end; + end + else if not IsNumeric(AStr) then begin + raise EIdNumberInvalid.Create(RSIMAP4NumberInvalid); + end; + Result := True; +end; + +function TIdIMAP4.GetUID(const AMsgNum: UInt32; var AUID: string): Boolean; +{This gets the message UID from the message relative number.} +begin + Result := False; + AUID := ''; {Do not Localize} + IsNumberValid(AMsgNum); + + CheckConnectionState(csSelected); + {Some servers return NO if the requested message number is not present + (e.g. Cyrus), others return OK but no data (CommuniGate).} + SendCmd(NewCmdCounter, + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdUID] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch]]); + if LastCmdResult.Code = IMAP_OK then begin + //Might as well leave 3rd param as [] because ParseLastCmdResult always grabs the UID... + if LastCmdResult.Text.Count > 0 then begin + if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], []) then begin + AUID := FLineStruct.UID; + Result := True; + end; + end; + end; +end; + +{$I IdDeprecatedImplBugOff.inc} +procedure TIdIMAP4.WriteLn(const AOut: string = ''); +{$I IdDeprecatedImplBugOn.inc} +begin + IOHandler.WriteLn(AOut); +end; + +{$I IdDeprecatedImplBugOff.inc} +function TIdIMAP4.ReadLnWait: string; +{$I IdDeprecatedImplBugOn.inc} +begin + Result := IOHandler.ReadLnWait; {This can have hit an exception of Connection Reset By Peer (timeout)} +end; + +{ IdTCPConnection Commands... } + +function TIdIMAP4.GetInternalResponse(const ATag: String; AExpectedResponses: array of String; + ASingleLineMode: Boolean; ASingleLineMayBeSplit: Boolean {= True}): string; +{ASingleLineMode is True if the caller just wants the FIRST line of the response, +e.g., he may be looking only for "* FETCH (blah blah)", because he needs to parse +that line to figure out how the rest will follow. This arises with a number of the +FETCH commands where the caller needs to get the byte-count from the first line +before he can retrieve the rest of the response. +Note "FETCH" would have to be in AExpectedResponses. +When False, the caller wants everything up to and including the reply terminator +(e.g. "C45 OK Completed"). +In ASingleLineMode, we ignore any lines that dont have one of AExpectedResponses +at the start, otherwise we add all lines to .Text and later strip out any lines that +dont have one of AExpectedResponses at the start. +ASingleLineMayBeSplit (which should only be used with ASingleLineMode = True) deals +with the case where the server cannot or does not fit a single-line +response onto one line. This arises when FETCHing the BODYSTRUCTURE, which can +be very long. The server (Courier, anyway) signals it by adding a byte-count to +the end of the first line, that would not normally be present.} +//For example, for normal short responses, the server would send: +// * FETCH (BODYSTRUCTURE (Part1 Part2)) +//but if it splits it, it sends: +// * FETCH (BODYSTRUCTURE (Part1 {7} +// Part2)) +//The number in the curly brackets {7} is the byte count following the line break. +{WARNING: If you use ASingleLineMayBeSplit on a line that is EXPECTED to end +with a byte-count, the code will break, so don't use it unless absolutely +necessary.} +var + LLine: String; + LResponse: TStringList; + LWord: string; + LPos: integer; + LStrippedLineLength: Integer; + LGotALineWithAnExpectedResponse: Boolean; + LStrippedLine: string; + LSplitLine: string; +begin + LGotALineWithAnExpectedResponse := False; + LResponse := TStringList.Create; + try + repeat + LLine := IOHandler.ReadLnWait; + {CCB: Trap case of server telling you that you have been disconnected, usually because + you were inactive for too long (get "* BYE idle time too long"). } + if TextStartsWith(LLine, '* BYE') then begin {Do not Localize} + {If BYE is in AExpectedResponses, this means we are expecting to + disconnect, i.e. it is a LOGOUT.} + if PosInStrArray('BYE', AExpectedResponses) = -1 then begin {Do not Localize} + {We were not expecting a BYE response. + For the moment, throw an exception. Could modify this by adding a + ReconnectOnDisconnect property to automatically reconnect?} + FConnectionState := csUnexpectedlyDisconnected; + raise EIdDisconnectedProbablyIdledOut.Create(RSIMAP4DisconnectedProbablyIdledOut); + end; + end; + if ASingleLineMode then begin + //See if it may continue on the next line... + if ASingleLineMayBeSplit then begin + //If the line is split, it will have a byte-count field at the end... + if TextEndsWith(LLine, '}') then begin + //It is split. + LStrippedLine := LLine; + LLine := ''; + repeat + //First, remove the byte count... + LPos := Length(LStrippedLine)-1; + while LPos >= 1 do begin + if LStrippedLine[LPos] = '{' then begin + Break; + end; + Dec(LPos); + end; + LWord := Copy(LStrippedLine, LPos+1, (Length(LStrippedLine)-LPos)-1); + if TextIsSame(LWord, 'NIL') then begin + LStrippedLineLength := 0; + end else begin + LStrippedLineLength := StrToInt(LWord); + end; + LStrippedLine := Copy(LStrippedLine, 1, LPos-1); + //The rest of the reply is on the following line... + LSplitLine := IOHandler.ReadString(LStrippedLineLength); + // At this point LSplitLine should be parsed and the following characters should be escaped... " CR LF. + LLine := LLine + LStrippedLine + LSplitLine; + LStrippedLine := IOHandler.ReadLn; //Cannot thrash LLine, need it later + until not TextEndsWith(LStrippedLine, '}'); + LLine := LLine + LStrippedLine; + end; + end; + LStrippedLine := LLine; + if TextStartsWith(LLine, '* ') then begin {Do not Localize} + LStrippedLine := Copy(LLine, 3, MaxInt); + end; + LGotALineWithAnExpectedResponse := TIdReplyIMAP4(FLastCmdResult).DoesLineHaveExpectedResponse(LStrippedLine, AExpectedResponses); + if LGotALineWithAnExpectedResponse then begin + FLastCmdResult.Text.Clear; + TIdReplyIMAP4(FLastCmdResult).Extra.Clear; + FLastCmdResult.Text.Add(LStrippedLine); + end; + end else + begin + //If the line is split, it will have a byte-count field at the end... + if TextEndsWith(LLine, '}') then begin + LStrippedLine := LLine; + LLine := ''; + repeat + //It is split. + //First, remove the byte count... + LPos := Length(LStrippedLine)-1; + while LPos >= 1 do begin + if LStrippedLine[LPos] = '{' then begin + Break; + end; + Dec(LPos); + end; + LWord := Copy(LStrippedLine, LPos+1, (Length(LStrippedLine)-LPos)-1); + if TextIsSame(LWord, 'NIL') then begin + LStrippedLineLength := 0; + end else begin + LStrippedLineLength := StrToInt(LWord); + end; + LStrippedLine := Copy(LStrippedLine, 1, LPos-1); + //The rest of the reply is on the following line... + LSplitLine := IOHandler.ReadString(LStrippedLineLength); + // At this point LSplitLine should be parsed and the following characters should be escaped... " CR LF. + LLine := LLine + LStrippedLine + LSplitLine; + LStrippedLine := IOHandler.ReadLn; //Cannot thrash LLine, need it later + until not TextEndsWith(LStrippedLine, '}'); + LLine := LLine + LStrippedLine; + end; + end; + LResponse.Add(LLine); + //Need to get the 1st word on the line in case it is +, PREAUTH, etc... + LPos := Pos(' ', LLine); {Do not Localize} + if LPos <> 0 then begin + {There are at least two words on this line...} + LWord := Trim(Copy(LLine, 1, LPos-1)); + end else begin + {No space, so this line is a single word. A bit weird, but it + could be just an OK...} + LWord := LLine; {A bit pedantic, but emphasises we have a word, not a line} + end; + until + TextStartsWith(LLine, ATag) + or (PosInStrArray(LWord, VALID_TAGGEDREPLIES) <> -1) + or LGotALineWithAnExpectedResponse; + if LGotALineWithAnExpectedResponse then begin + //This only arises if ASingleLineMode is True... + FLastCmdResult.Code := IMAP_OK; + end else begin + FLastCmdResult.FormattedReply := LResponse; + TIdReplyIMAP4(FLastCmdResult).RemoveUnsolicitedResponses(AExpectedResponses); + end; + Result := FLastCmdResult.Code; + finally + FreeAndNil(LResponse); + end; +end; + +function TIdIMAP4.SendCmd(const AOut: string; AExpectedResponses: array of String; + ASingleLineMode: Boolean = False; ASingleLineMayBeSplit: Boolean = True): string; +begin + Result := SendCmd(NewCmdCounter, AOut, AExpectedResponses, ASingleLineMode, ASingleLineMayBeSplit); +end; + +function TIdIMAP4.SendCmd(const ATag, AOut: string; AExpectedResponses: array of String; + ASingleLineMode: Boolean = False; ASingleLineMayBeSplit: Boolean = True): string; +var + LCmd: String; +begin + {CC3: Catch "Connection reset by peer"...} + try + if (AOut <> #0) then begin + //Remove anything that may be unprocessed from a previous (probably failed) command... + repeat + IOHandler.InputBuffer.Clear; + until not IOHandler.CheckForDataOnSource(MilliSecsToWaitToClearBuffer); + LCmd := ATag + ' ' + AOut; + CheckConnected; + PrepareCmd(LCmd); + IOHandler.WriteLn(LCmd); + end; + Result := GetInternalResponse(ATag, AExpectedResponses, ASingleLineMode, ASingleLineMayBeSplit); + except + on E: EIdSocketError do begin + if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin + FConnectionState := csUnexpectedlyDisconnected; + end; + raise; + end; + end; +end; + +{ ...IdTCPConnection Commands } + +procedure TIdIMAP4.DoAlert(const AMsg: String); +begin + if Assigned(OnAlert) then begin + OnAlert(Self, AMsg); + end; +end; + +procedure TIdIMAP4.SetMailBox(const Value: TIdMailBox); +begin + FMailBox.Assign(Value); +end; + +procedure TIdIMAP4.SetSASLMechanisms(AValue: TIdSASLEntries); +begin + FSASLMechanisms.Assign(AValue); +end; + +procedure TIdIMAP4.Login; +var + LIO: TIdSSLIOHandlerSocketBase; +begin + try + if (IOHandler is TIdSSLIOHandlerSocketBase) and (UseTLS in ExplicitTLSVals) then begin + LIO := TIdSSLIOHandlerSocketBase(IOHandler); + //we check passthrough because we can either be using TLS currently with + //implicit TLS support or because STARTLS was issued previously. + if LIO.PassThrough then begin + if SupportsTLS then begin + if SendCmd(NewCmdCounter, 'STARTTLS', []) = IMAP_OK then begin {Do not Localize} + TLSHandshake; + //obtain capabilities again - RFC2595 + Capability; + end else begin + ProcessTLSNegCmdFailed; + end; + end else begin + ProcessTLSNotAvail; + end; + end; + end; + FConnectionState := csNonAuthenticated; + FCmdCounter := 0; + if FAuthType = iatUserPass then begin + if Length(Password) <> 0 then begin {Do not Localize} + SendCmd(NewCmdCounter, IMAP4Commands[cmdLogin] + ' ' + Username + ' ' + IMAPQuotedStr(Password), [IMAP_OK]); {Do not Localize} + end else begin + SendCmd(NewCmdCounter, IMAP4Commands[cmdLogin] + ' ' + Username, [IMAP_OK]); {Do not Localize} + end; + if LastCmdResult.Code <> IMAP_OK then begin + RaiseExceptionForLastCmdResult; + end; + end else + begin + if not FHasCapa then begin + Capability; + end; + // FSASLMechanisms.LoginSASL('AUTHENTICATE', FHost, FPort, IdGSKSSN_imap, [IMAP_OK], [IMAP_CONT], Self, FCapabilities, 'AUTH', IsCapabilityListed('SASL-IR')); {Do not Localize} + TIdSASLEntriesIMAP4(FSASLMechanisms).LoginSASL_IMAP(Self); + end; + FConnectionState := csAuthenticated; + // RLebeau: check if the response includes new Capabilities, if not then query for them... + if not CheckReplyForCapabilities then begin + Capability; + end; + except + Disconnect; + raise; + end; +end; + +function TIdIMAP4.Connect(const AAutoLogin: Boolean = True): Boolean; +begin + {CC2: Need to set FConnectionState to csNonAuthenticated here. If not, then + an unsuccessful connect after a previous successful connect (such as when a + client program changes users) can leave it as csAuthenticated.} + FConnectionState := csNonAuthenticated; + try + {CC2: Don't call Connect if already connected, this could be just a change of user} + if not Connected then begin + inherited Connect; + GetResponse; + // if PosInStrArray(LastCmdResult.Code, [IMAP_OK, IMAP_PREAUTH]) = -1 then begin + {Should have got OK or PREAUTH in the greeting. Happened with some server, + may need further investigation and coding...} + // end; + {CC7: Save FGreetingBanner so the user can use it to determine what type of + server he is connected to...} + if LastCmdResult.Text.Count > 0 then begin + FGreetingBanner := LastCmdResult.Text[0]; + end else begin + FGreetingBanner := ''; + end; + if LastCmdResult.Code = IMAP_PREAUTH then begin + FConnectionState := csAuthenticated; + FCmdCounter := 0; + // RLebeau: check if the greeting includes initial Capabilities, if not then query for them... + if not CheckReplyForCapabilities then begin + Capability; + end; + end else begin + // RLebeau: check if the greeting includes initial Capabilities... + CheckReplyForCapabilities; + end; + end; + if AAutoLogin then begin + Login; + end; + except + Disconnect(False); + raise; + end; + Result := True; +end; + +{$IFDEF WORKAROUND_INLINE_CONSTRUCTORS} +constructor TIdIMAP4.Create(AOwner: TComponent); +begin + inherited Create(AOwner); +end; +{$ENDIF} + +procedure TIdIMAP4.InitComponent; +begin + inherited InitComponent; + FMailBox := TIdMailBox.Create(Self); + //FSASLMechanisms := TIdSASLEntries.Create(Self); + FSASLMechanisms := TIdSASLEntriesIMAP4.Create(Self); + Port := IdPORT_IMAP4; + FLineStruct := TIdIMAPLineStruct.Create; + {$IFDEF HAS_TStringList_CaseSensitive} + TStringList(FCapabilities).CaseSensitive := False; // TODO: move this to TIdExplicitTLSClient.InitComponent() + {$ENDIF} + FMUTF7 := TIdMUTF7.Create; + + //Todo: Not sure which number is appropriate. Should be tested further. + FRegularProtPort := IdPORT_IMAP4; + FImplicitTLSProtPort := IdPORT_IMAP4S; + FExplicitTLSProtPort := IdPORT_IMAP4; + + FMilliSecsToWaitToClearBuffer := IDF_DEFAULT_MS_TO_WAIT_TO_CLEAR_BUFFER; + FCmdCounter := 0; + FConnectionState := csNonAuthenticated; + FRetrieveOnSelect := rsDisabled; + {CC2: FMailBoxSeparator is now detected when a mailbox is selected, following + line is probably redundant, but leave it here as a default just in case.} + FMailBoxSeparator := '/'; {Do not Localize} +end; + +procedure TIdIMAP4.Disconnect(ANotifyPeer: Boolean); +begin + try + inherited Disconnect(ANotifyPeer); + finally + FConnectionState := csNonAuthenticated; + FCapabilities.Clear; + end; +end; + +procedure TIdIMAP4.DisconnectNotifyPeer; +begin + inherited DisconnectNotifyPeer; + //IMPORTANT: Logout must pass 'BYE' as the first + //element of the AExpectedResponses array (the 3rd param in SendCmd + //below), because this flags to GetInternalResponse that this is the + //logout, and it must EXPECT the BYE response + SendCmd(NewCmdCounter, IMAP4Commands[cmdLogout], ['BYE']); {Do not Localize} +end; + +procedure TIdIMAP4.KeepAlive; +begin + //Available in any state. + SendCmd(NewCmdCounter, IMAP4Commands[cmdNoop], []); +end; + +function TIdIMAP4.IsCapabilityListed(ACapability: string):Boolean; +begin + if not FHasCapa then begin + Capability; + end; + Result := IndyIndexOf(TStringList(FCapabilities), ACapability) <> -1; +end; + +function TIdIMAP4.Capability: Boolean; +begin + FHasCapa := Capability(FCapabilities); + Result := FHasCapa; +end; + +function TIdIMAP4.Capability(ASlCapability: TStrings): Boolean; +begin + //Available in any state. + Result := False; + ASlCapability.BeginUpdate; + try + ASlCapability.Clear; + SendCmd(NewCmdCounter, IMAP4Commands[CmdCapability], [IMAP4Commands[CmdCapability]]); + if LastCmdResult.Code = IMAP_OK then begin + if LastCmdResult.Text.Count > 0 then begin + BreakApart(LastCmdResult.Text[0], ' ', ASlCapability); {Do not Localize} + end; + // RLebeau: do not delete the first item anymore! It specifies the IMAP + // version/revision, which is needed to support certain extensions, like + // 'IMAP4rev1'... + { + if ASlCapability.Count > 0 then begin + ASlCapability.Delete(0); + end; + } + Result := True; + end; + finally + ASlCapability.EndUpdate; + end; +end; + +function TIdIMAP4.GetCmdCounter: String; +begin + Result := 'C' + IntToStr(FCmdCounter); {Do not Localize} +end; + +function TIdIMAP4.GetNewCmdCounter: String; +begin + Inc(FCmdCounter); + Result := 'C' + IntToStr(FCmdCounter); {Do not Localize} +end; + +destructor TIdIMAP4.Destroy; +begin + {Disconnect before we die} + { Note we have to pass false to an overloaded method or an exception is + raised in the destructor. That can cause weirdness in the IDE. } + if Connected then begin + Disconnect(False); + end; + FreeAndNil(FMailBox); + FreeAndNil(FSASLMechanisms); + FreeAndNil(FLineStruct); + FreeAndNil(FMUTF7); + inherited Destroy; +end; + +function TIdIMAP4.SelectMailBox(const AMBName: String): Boolean; +begin + Result := False; + CheckConnectionState([csAuthenticated, csSelected]); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdSelect] + ' "' + DoMUTFEncode(AMBName) + '"', {Do not Localize} + ['FLAGS', 'OK', 'EXISTS', 'RECENT', '[READ-WRITE]', '[ALERT]']); {Do not Localize} + if LastCmdResult.Code = IMAP_OK then begin + //Put the parse in the IMAP Class and send the MB; + ParseSelectResult(FMailBox, LastCmdResult.Text); + FMailBox.Name := AMBName; + FConnectionState := csSelected; + case RetrieveOnSelect of + rsHeaders: RetrieveAllHeaders(FMailBox.MessageList); + rsMessages: RetrieveAllMsgs(FMailBox.MessageList); + end; + Result := True; + end; +end; + +function TIdIMAP4.ExamineMailBox(const AMBName: String; AMB: TIdMailBox): Boolean; +begin + Result := False; + CheckConnectionState([csAuthenticated, csSelected]); + //TO DO: Check that Examine's expected responses really are STATUS, FLAGS and OK... + SendCmd(NewCmdCounter, + IMAP4Commands[cmdExamine] + ' "' + DoMUTFEncode(AMBName) + '"', {Do not Localize} + ['STATUS', 'FLAGS', 'OK', 'EXISTS', 'RECENT', '[READ-WRITE]', '[ALERT]']); {Do not Localize} + if LastCmdResult.Code = IMAP_OK then begin + ParseSelectResult(AMB, LastCmdResult.Text); + AMB.Name := AMBName; + FConnectionState := csSelected; + Result := True; + end; +end; + +function TIdIMAP4.CloseMailBox: Boolean; +begin + Result := False; + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, IMAP4Commands[cmdClose], []); + if LastCmdResult.Code = IMAP_OK then begin + MailBox.Clear; + FConnectionState := csAuthenticated; + Result := True; + end; +end; + +function TIdIMAP4.CreateMailBox(const AMBName: String): Boolean; +begin + {CC5: Recode to return False if NO returned rather than throwing an exception...} + Result := False; + CheckConnectionState([csAuthenticated, csSelected]); + {CC5: The NO response is typically due to Permission Denied} + SendCmd(NewCmdCounter, IMAP4Commands[cmdCreate] + ' "' + DoMUTFEncode(AMBName) + '"', []); {Do not Localize} + if LastCmdResult.Code = IMAP_OK then begin + Result := True; + end; +end; + +function TIdIMAP4.DeleteMailBox(const AMBName: String): Boolean; +begin + {CC5: Recode to return False if NO returned rather than throwing an exception...} + Result := False; + CheckConnectionState([csAuthenticated, csSelected]); + {CC5: The NO response is typically due to Permission Denied} + SendCmd(NewCmdCounter, IMAP4Commands[cmdDelete] + ' "' + DoMUTFEncode(AMBName) + '"', []); {Do not Localize} + if LastCmdResult.Code = IMAP_OK then begin + Result := True; + end; +end; + +function TIdIMAP4.RenameMailBox(const AOldMBName, ANewMBName: String): Boolean; +begin + {CC5: Recode to return False if NO returned rather than throwing an exception...} + Result := False; + CheckConnectionState([csAuthenticated, csSelected]); + {CC5: The NO response is typically due to Permission Denied} + SendCmd(NewCmdCounter, + IMAP4Commands[cmdRename] + ' "' + DoMUTFEncode(AOldMBName) + '" "' + DoMUTFEncode(ANewMBName) + '"', {Do not Localize} + []); + if LastCmdResult.Code = IMAP_OK then begin + Result := True; + end; +end; + +function TIdIMAP4.StatusMailBox(const AMBName: String; AMB: TIdMailBox): Boolean; + {CC2: It is pointless calling StatusMailBox with AStatusDataItems set to [] + because you are asking the IMAP server to update none of the status flags. + Instead, if called with no AStatusDataItems specified, use the standard flags + returned by SelectMailBox, which allows the user to easily check if the mailbox + has changed. Overload the functions, since AStatusDataItems cannot be set + to nil.} +var + AStatusDataItems: array[1..5] of TIdIMAP4StatusDataItem; +begin + AStatusDataItems[1] := mdMessages; + AStatusDataItems[2] := mdRecent; + AStatusDataItems[3] := mdUIDNext; + AStatusDataItems[4] := mdUIDValidity; + AStatusDataItems[5] := mdUnseen; + Result := StatusMailBox(AMBName, AMB, AStatusDataItems); +end; + +function TIdIMAP4.StatusMailBox(const AMBName: String; AMB: TIdMailBox; const AStatusDataItems: array of TIdIMAP4StatusDataItem): Boolean; +var + LDataItems : string; + Ln : Integer; +begin + Result := False; + CheckConnectionState([csAuthenticated, csSelected]); + for Ln := Low(AStatusDataItems) to High(AStatusDataItems) do begin + case AStatusDataItems[Ln] of + mdMessages: LDataItems := LDataItems + IMAP4StatusDataItem[mdMessages] + ' '; {Do not Localize} + mdRecent: LDataItems := LDataItems + IMAP4StatusDataItem[mdRecent] + ' '; {Do not Localize} + mdUIDNext: LDataItems := LDataItems + IMAP4StatusDataItem[mdUIDNext] + ' '; {Do not Localize} + mdUIDValidity: LDataItems := LDataItems + IMAP4StatusDataItem[mdUIDValidity] + ' '; {Do not Localize} + mdUnseen: LDataItems := LDataItems + IMAP4StatusDataItem[mdUnseen] + ' '; {Do not Localize} + end; + end; + SendCmd(NewCmdCounter, + IMAP4Commands[cmdStatus] + ' "' + DoMUTFEncode(AMBName) + '" (' + Trim(LDataItems) + ')', {Do not Localize} + [IMAP4Commands[cmdStatus]]); + if LastCmdResult.Code = IMAP_OK then begin + ParseStatusResult(AMB, LastCmdResult.Text); + Result := True; + end; +end; + +function TIdIMAP4.CheckMailBox: Boolean; +begin + Result := False; + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, IMAP4Commands[cmdCheck], []); + if LastCmdResult.Code = IMAP_OK then begin + Result := True; + end; +end; + +function TIdIMAP4.ExpungeMailBox: Boolean; +begin + Result := False; + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, IMAP4Commands[cmdExpunge], []); + if LastCmdResult.Code = IMAP_OK then begin + ParseExpungeResult(FMailBox, LastCmdResult.Text); + Result := True; + end; +end; + +//This function is needed because when using the regular DateToStr with dd/MMM/yyyy +//(which is the IMAP needed convension) may give the month as the local language +//three letter month instead of the English month needed. +function DateToIMAPDateStr (const ADate: TDateTime): String; +var + LDay, LMonth, LYear : Word; +begin + {Do not use the global settings from the system unit here because: + 1) It might not be thread safe + 2) Changing the settings could create problems for a user who's local date conventions + are diffrent than dd-mm-yyyy. Some people prefer mm-dd-yyy. Don't mess with a user's display settings. + 3) Using the display settings for dates may not always work as expected if a user + changes their settings at a time between whn you do it but before the date is formatted. + } + DecodeDate(ADate, LYear, LMonth, LDay); + Result := IndyFormat('%.2d-%s-%.4d', [LDay, UpperCase(monthnames[LMonth]), LYear]); {Do not Localize} +end; + +function TIdIMAP4.InternalSearchMailBox(const ASearchInfo: array of TIdIMAP4SearchRec; + AUseUID: Boolean; const ACharSet: string): Boolean; +var + LCmd: String; + Ln : Integer; + LTextBuf: TIdBytes; + LCharSet: string; + LEncoding: IIdTextEncoding; + LLiteral: string; + LCanUseNonSyncLiteral, LNonSyncLiteralIsLimited, LUseNonSyncLiteral: Boolean; + LUseUTF8QuotedString: Boolean; + + function RequiresEncoding(const S: String): Boolean; + var + I: Integer; + begin + Result := False; + for I := 1 to Length(S) do begin + if Ord(S[I]) > $7F then begin + Result := True; + Exit; + end; + end; + end; + + function IsCharsetNeeded: Boolean; + var + I : Integer; + begin + Result := False; + for I := Low(ASearchInfo) to High(ASearchInfo) do begin + case ASearchInfo[I].SearchKey of + skBcc, + skBody, + skCc, + skFrom, + skHeader, + skSubject, + skText, + skTo, + skGmailRaw, + skGmailMsgID, + skGmailThreadID, + skGmailLabels: + if RequiresEncoding(ASearchInfo[I].Text) then begin + Result := True; + Exit; + end; + end; + end; + end; + +begin + Result := False; + LTextBuf := nil; // keep the compiler happy + CheckConnectionState(csSelected); + + LCmd := NewCmdCounter + ' '; {Do not Localize} + if AUseUID then begin + LCmd := LCmd + IMAP4Commands[cmdUID] + ' '; {Do not Localize} + end; + LCmd := LCmd + IMAP4Commands[cmdSearch]; + if IsCharsetNeeded then begin + LNonSyncLiteralIsLimited := IsCapabilityListed('LITERAL-'); {Do not localize} + LCanUseNonSyncLiteral := LNonSyncLiteralIsLimited or + IsCapabilityListed('LITERAL+'); {Do not localize} + LUseUTF8QuotedString := IsCapabilityListed('UTF8=ACCEPT') or {Do not localize} + IsCapabilityListed('UTF8=ONLY') or {Do not localize} + IsCapabilityListed('UTF8=ALL'); {Do not localize} + if LUseUTF8QuotedString then begin + LCharSet := 'UTF-8'; {Do not Localize} + end else begin + LCharSet := Trim(ACharSet); + if LCharSet = '' then begin + LCharSet := 'UTF-8'; {Do not Localize} + end; + end; + LCmd := LCmd + ' CHARSET ' + LCharSet; {Do not localize} + LEncoding := CharsetToEncoding(LCharSet); + end else begin + // keep the compiler happy... + LNonSyncLiteralIsLimited := False; + LCanUseNonSyncLiteral := False; + LUseUTF8QuotedString := False; + end; + + {CC3: Catch "Connection reset by peer"...} + try + //Remove anything that may be unprocessed from a previous (probably failed) command... + repeat + IOHandler.InputBuffer.Clear; + until not IOHandler.CheckForDataOnSource(MilliSecsToWaitToClearBuffer); + CheckConnected; + //IMAP.PrepareCmd(LCmd); + + // now encode the search values. Most values are ASCII and do not need + // special encoding. For text values that do need to be encoded, IMAP + // string literals have to be used in order to support 8-bit octets in + // charset encoded payloads... + for Ln := Low(ASearchInfo) to High(ASearchInfo) do begin + case ASearchInfo[Ln].SearchKey of + skAll, + skAnswered, + skDeleted, + skDraft, + skFlagged, + skNew, + skNot, + skOld, + skOr, + skRecent, + skSeen, + skUnanswered, + skUndeleted, + skUndraft, + skUnflagged, + skUnKeyWord, + skUnseen: + LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey]; {Do not Localize} + + skHeader: + begin + // TODO: support RFC 5738 to allow for UTF-8 encoded quoted strings + if not RequiresEncoding(ASearchInfo[Ln].Text) then begin + LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + ASearchInfo[Ln].FieldName + ' ' + IMAPQuotedStr(ASearchInfo[Ln].Text); {Do not Localize} + end else + begin + if LUseUTF8QuotedString then begin + LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + ASearchInfo[Ln].FieldName + ' *'; {Do not Localize} + IOHandler.Write(LCmd); + IOHandler.Write(IMAPQuotedStr(ASearchInfo[Ln].Text), LEncoding{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_OSDefault{$ENDIF}); + end else + begin + LTextBuf := ToBytes(ASearchInfo[Ln].Text, LEncoding{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_OSDefault{$ENDIF}); + LUseNonSyncLiteral := LCanUseNonSyncLiteral and ((not LNonSyncLiteralIsLimited) or (Length(LTextBuf) <= 4096)); + if LUseNonSyncLiteral then begin + LLiteral := '{' + IntToStr(Length(LTextBuf)) + '+}'; {Do not Localize} + end else begin + LLiteral := '{' + IntToStr(Length(LTextBuf)) + '}'; {Do not Localize} + end; + LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + ASearchInfo[Ln].FieldName + ' ' + LLiteral; {Do not Localize} + IOHandler.WriteLn(LCmd); + if not LUseNonSyncLiteral then begin + if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdSearch], IMAP4Commands[cmdUID]], False) <> IMAP_CONT then begin + RaiseExceptionForLastCmdResult; + end; + end; + IOHandler.Write(LTextBuf); + end; + LTextBuf := nil; + LCmd := ''; + end; + end; + + skKeyword, + skUID: + LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + ASearchInfo[Ln].Text; {Do not Localize} + + skBcc, + skBody, + skCc, + skFrom, + skSubject, + skText, + skTo, + skGmailRaw, + skGmailMsgID, + skGmailThreadID, + skGmailLabels: + begin + // TODO: support RFC 5738 to allow for UTF-8 encoded quoted strings + if not RequiresEncoding(ASearchInfo[Ln].Text) then begin + LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + IMAPQuotedStr(ASearchInfo[Ln].Text); {Do not Localize} + end else + begin + if LUseUTF8QuotedString then begin + LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' *'; {Do not Localize} + IOHandler.Write(LCmd); + IOHandler.Write(IMAPQuotedStr(ASearchInfo[Ln].Text), LEncoding{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_OSDefault{$ENDIF}); + end else + begin + LTextBuf := ToBytes(ASearchInfo[Ln].Text, LEncoding{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_OSDefault{$ENDIF}); + LUseNonSyncLiteral := LCanUseNonSyncLiteral and ((not LNonSyncLiteralIsLimited) or (Length(LTextBuf) <= 4096)); + if LUseNonSyncLiteral then begin + LLiteral := '{' + IntToStr(Length(LTextBuf)) + '+}'; {Do not Localize} + end else begin + LLiteral := '{' + IntToStr(Length(LTextBuf)) + '}'; {Do not Localize} + end; + LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + LLiteral; {Do not Localize} + IOHandler.WriteLn(LCmd); + if not LUseNonSyncLiteral then begin + if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdSearch], IMAP4Commands[cmdUID]], False) <> IMAP_CONT then begin + RaiseExceptionForLastCmdResult; + end; + end; + IOHandler.Write(LTextBuf); + end; + LTextBuf := nil; + LCmd := ''; + end; + end; + + skBefore, + skOn, + skSentBefore, + skSentOn, + skSentSince, + skSince: + LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + DateToIMAPDateStr(ASearchInfo[Ln].Date); {Do not Localize} + + skLarger, + skSmaller: + LCmd := LCmd + ' ' + IMAP4SearchKeys[ASearchInfo[Ln].SearchKey] + ' ' + IntToStr(ASearchInfo[Ln].Size); {Do not Localize} + end; + end; + + if LCmd <> '' then begin + IOHandler.Write(LCmd); + end; + + // After we send the last of the data, we need to send an EXTRA CRLF to terminates the SEARCH command... + IOHandler.WriteLn; + + if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdSearch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin + ParseSearchResult(FMailBox, LastCmdResult.Text); + Result := True; + end; + except + on E: EIdSocketError do begin + if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin + FConnectionState := csUnexpectedlyDisconnected; + end; + raise; + end; + end; +end; + +function TIdIMAP4.SearchMailBox(const ASearchInfo: array of TIdIMAP4SearchRec; + const ACharSet: string = ''): Boolean; +begin + Result := InternalSearchMailBox(ASearchInfo, False, ACharSet); +end; + +function TIdIMAP4.UIDSearchMailBox(const ASearchInfo: array of TIdIMAP4SearchRec; + const ACharSet: string = '') : Boolean; +begin + Result := InternalSearchMailBox(ASearchInfo, True, ACharSet); +end; + +function TIdIMAP4.SubscribeMailBox(const AMBName: String): Boolean; +begin + Result := False; + CheckConnectionState([csAuthenticated, csSelected]); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdSubscribe] + ' "' + DoMUTFEncode(AMBName) + '"', {Do not Localize} + []); + if LastCmdResult.Code = IMAP_OK then begin + Result := True; + end; +end; + +function TIdIMAP4.UnsubscribeMailBox(const AMBName: String): Boolean; +begin + Result := False; + CheckConnectionState([csAuthenticated, csSelected]); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdUnsubscribe] + ' "' + DoMUTFEncode(AMBName) + '"', {Do not Localize} + []); + if LastCmdResult.Code = IMAP_OK then begin + Result := True; + end; +end; + +function TIdIMAP4.ListMailBoxes(AMailBoxList: TStrings): Boolean; +begin + Result := False; + {CC2: This is one of the few cases where the server can return only "OK completed" + meaning that the user has no mailboxes.} + CheckConnectionState([csAuthenticated, csSelected]); + SendCmd(NewCmdCounter, IMAP4Commands[cmdList] + ' "" *', [IMAP4Commands[cmdList]]); {Do not Localize} + if LastCmdResult.Code = IMAP_OK then begin + ParseListResult(AMailBoxList, LastCmdResult.Text); + Result := True; + end; +end; + +function TIdIMAP4.ListInferiorMailBoxes(AMailBoxList, AInferiorMailBoxList: TStrings): Boolean; +var + Ln : Integer; + LAuxMailBoxList : TStringList; +begin + Result := False; + {CC2: This is one of the few cases where the server can return only "OK completed" + meaning that the user has no inferior mailboxes.} + CheckConnectionState([csAuthenticated, csSelected]); + if AMailBoxList = nil then begin + SendCmd(NewCmdCounter, IMAP4Commands[cmdList] + ' "" %', [IMAP4Commands[cmdList]]); {Do not Localize} + if LastCmdResult.Code = IMAP_OK then begin + ParseListResult(AInferiorMailBoxList, LastCmdResult.Text); + //The INBOX mailbox is added because I think it always has to exist + //in an IMAP4 account (default) but it does not list it in this command. + Result := True; + end; + end else begin + LAuxMailBoxList := TStringList.Create; + try + AInferiorMailBoxList.Clear; + for Ln := 0 to AMailBoxList.Count - 1 do begin + SendCmd(NewCmdCounter, + IMAP4Commands[cmdList] + ' "" "' + DoMUTFEncode(AMailBoxList[Ln]) + FMailBoxSeparator + '%"', {Do not Localize} + [IMAP4Commands[cmdList]]); + if LastCmdResult.Code = IMAP_OK then begin + ParseListResult(LAuxMailBoxList, LastCmdResult.Text); + AInferiorMailBoxList.AddStrings(LAuxMailBoxList); + Result := True; + end else begin + Break; + end; + end; + finally + FreeAndNil(LAuxMailBoxList); + end; + end; +end; + +function TIdIMAP4.ListSubscribedMailBoxes(AMailBoxList: TStrings): Boolean; +begin + {CC2: This is one of the few cases where the server can return only "OK completed" + meaning that the user has no subscribed mailboxes.} + Result := False; + CheckConnectionState([csAuthenticated, csSelected]); + SendCmd(NewCmdCounter, IMAP4Commands[cmdLSub] + ' "" *', [IMAP4Commands[cmdList], IMAP4Commands[cmdLSub]]); {Do not Localize} + if LastCmdResult.Code = IMAP_OK then begin + // ds - fixed bug # 506026 + ParseLSubResult(AMailBoxList, LastCmdResult.Text); + Result := True; + end; +end; + +function TIdIMAP4.StoreFlags(const AMsgNumList: array of UInt32; + const AStoreMethod: TIdIMAP4StoreDataItem; const AFlags: TIdMessageFlagsSet): Boolean; +begin + Result := StoreValue(AMsgNumList, AStoreMethod, IMAP4FetchDataItem[fdFlags], MessageFlagSetToStr(AFlags)); +end; + +function TIdIMAP4.StoreValue(const AMsgNumList: array of UInt32; + const AStoreMethod: TIdIMAP4StoreDataItem; const AField, AValue: String): Boolean; +var + LDataItem, + LMsgSet: string; +begin + Result := False; + if Length(AMsgNumList) > 0 then begin + LMsgSet := ArrayToNumberStr(AMsgNumList); + case AStoreMethod of + sdReplace, sdReplaceSilent: + LDataItem := AField+'.SILENT'; {Do not Localize} + sdAdd, sdAddSilent: + LDataItem := '+'+AField+'.SILENT'; {Do not Localize} + sdRemove, sdRemoveSilent: + LDataItem := '-'+AField+'.SILENT'; {Do not Localize} + else + Exit; + end; + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdStore] + ' ' + LMsgSet + ' ' + LDataItem + ' (' + AValue + ')', {Do not Localize} + []); + if LastCmdResult.Code = IMAP_OK then begin + Result := True; + end; + end; +end; + +function TIdIMAP4.UIDStoreFlags(const AMsgUID: String; + const AStoreMethod: TIdIMAP4StoreDataItem; const AFlags: TIdMessageFlagsSet): Boolean; +begin + Result := UIDStoreValue(AMsgUID, AStoreMethod, IMAP4FetchDataItem[fdFlags], MessageFlagSetToStr(AFlags)); +end; + +function TIdIMAP4.UIDStoreFlags(const AMsgUIDList: array of String; + const AStoreMethod: TIdIMAP4StoreDataItem; const AFlags: TIdMessageFlagsSet): Boolean; +begin + Result := UIDStoreValue(AMsgUIDList, AStoreMethod, IMAP4FetchDataItem[fdFlags], MessageFlagSetToStr(AFlags)); +end; + +function TIdIMAP4.UIDStoreValue(const AMsgUID: String; + const AStoreMethod: TIdIMAP4StoreDataItem; const AField, AValue: string): Boolean; +var + LDataItem : String; +begin + Result := False; + IsUIDValid(AMsgUID); + case AStoreMethod of + sdReplace, sdReplaceSilent: + LDataItem := AField+'.SILENT'; {Do not Localize} + sdAdd, sdAddSilent: + LDataItem := '+'+AField+'.SILENT'; {Do not localize} + sdRemove, sdRemoveSilent: + LDataItem := '-'+AField+'.SILENT'; {Do not Localize} + else + Exit; + end; + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdStore] + ' ' + AMsgUID + ' ' + LDataItem + ' (' + AValue + ')', {Do not Localize} + []); + if LastCmdResult.Code = IMAP_OK then begin + Result := True; + end; +end; + +function TIdIMAP4.UIDStoreValue(const AMsgUIDList: array of String; + const AStoreMethod: TIdIMAP4StoreDataItem; const AField, AValue: String): Boolean; +var + LDataItem, + LMsgSet : String; + LN: integer; +begin + Result := False; + LMsgSet := ''; + for LN := 0 to Length(AMsgUIDList) -1 do begin + IsUIDValid(AMsgUIDList[LN]); + if LN > 0 then begin + LMsgSet := LMsgSet + ','; {Do not Localize} + end; + LMsgSet := LMsgSet+AMsgUIDList[LN]; + end; + case AStoreMethod of + sdReplace, sdReplaceSilent: + LDataItem := AField+'.SILENT'; {Do not Localize} + sdAdd, sdAddSilent: + LDataItem := '+'+AField+'.SILENT'; {Do not Localize} + sdRemove, sdRemoveSilent: + LDataItem := '-'+AField+'.SILENT'; {Do not Localize} + else + Exit; + end; + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdStore] + ' ' + LMsgSet + ' ' + LDataItem + ' (' + AValue + ')', {Do not Localize} + []); + if LastCmdResult.Code = IMAP_OK then begin + Result := True; + end; +end; + +function TIdIMAP4.CopyMsgs(const AMsgNumList: array of UInt32; const AMBName: String): Boolean; +var + LMsgSet : String; +begin + Result := False; + if Length(AMsgNumList) > 0 then begin + LMsgSet := ArrayToNumberStr ( AMsgNumList ); + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, IMAP4Commands[cmdCopy] + ' ' + LMsgSet + ' "' + DoMUTFEncode(AMBName) + '"', []); {Do not Localize} + if LastCmdResult.Code = IMAP_OK then begin + Result := True; + end; + end; +end; + +function TIdIMAP4.UIDCopyMsgs(const AMsgUIDList: TStrings; const AMBName: String): Boolean; +var + LCmd : String; + LN: integer; +begin + Result := False; + if AMsgUIDList.Count > 0 then begin + LCmd := IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdCopy] + ' '; {Do not Localize} + for LN := 0 to AMsgUIDList.Count-1 do begin + IsUIDValid(AMsgUIDList.Strings[LN]); + if LN = 0 then begin + LCmd := LCmd + AMsgUIDList.Strings[LN]; + end else begin + LCmd := LCmd + ',' + AMsgUIDList.Strings[LN]; {Do not Localize} + end; + end; + LCmd := LCmd + ' "' + DoMUTFEncode(AMBName) + '"'; {Do not Localize} + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, LCmd, []); + if LastCmdResult.Code = IMAP_OK then begin + Result := True; + end; + end; +end; + +function TIdIMAP4.CopyMsg(const AMsgNum: UInt32; const AMBName: String): Boolean; +//Copies a message from the current selected mailbox to the specified mailbox. +begin + Result := False; + IsNumberValid(AMsgNum); + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, IMAP4Commands[cmdCopy] + ' ' + IntToStr(Int64(AMsgNum)) + ' "' + DoMUTFEncode(AMBName) + '"', []); {Do not Localize} + if LastCmdResult.Code = IMAP_OK then begin + Result := True; + end; +end; + +function TIdIMAP4.UIDCopyMsg(const AMsgUID: String; const AMBName: String): Boolean; +//Copies a message from the current selected mailbox to the specified mailbox. +begin + Result := False; + IsUIDValid(AMsgUID); + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdCopy] + ' ' + AMsgUID + ' "' + DoMUTFEncode(AMBName) + '"', []); {Do not Localize} + if LastCmdResult.Code = IMAP_OK then begin + Result := True; + end; +end; + + +function TIdIMAP4.AppendMsg(const AMBName: String; AMsg: TIdMessage; const AFlags: TIdMessageFlagsSet = []; + const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; +begin + Result := AppendMsg(AMBName, AMsg, nil, AFlags, AInternalDateTimeGMT); +end; + +function TIdIMAP4.AppendMsg(const AMBName: String; AMsg: TIdMessage; AAlternativeHeaders: TIdHeaderList; const AFlags: TIdMessageFlagsSet = []; + const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; +var + LFlags, + LMsgLiteral, LDateTime: String; + LUseNonSyncLiteral: Boolean; + Ln: Integer; + LCmd: string; + LLength: TIdStreamSize; + LHeadersToSend, LCopiedHeaders: TIdHeaderList; + LHeadersAsString: string; + LHeadersAsBytes: TIdBytes; + LMimeBoundary: string; + LStream: TStream; + LHelper: TIdIMAP4WorkHelper; +begin + Result := False; + LHeadersasBytes := nil; // keep the compiler happy + + CheckConnectionState([csAuthenticated, csSelected]); + if Length(AMBName) <> 0 then begin + LFlags := MessageFlagSetToStr(AFlags); + if LFlags <> '' then begin {Do not Localize} + LFlags := '(' + LFlags + ')'; {Do not Localize} + end; + if AInternalDateTimeGMT <> 0.0 then begin + // even though flags are optional, some servers, such as GMail, will + // fail to parse the command correctly if no flags are specified in + // front of the internal date... + if LFlags = '' then begin + LFlags := '()'; // TODO: should 'NIL' be used instead? {Do not Localize} + end; + LDateTime := '"' + DateTimeGMTToImapStr(AInternalDateTimeGMT) + '"'; {do not localize} + end; + + {CC8: In Indy 10, we want to support attachments (previous versions did + not). The problem is that we have to know the size of the message + in advance of sending it for the IMAP APPEND command. + The problem is that there is no way of calculating the size of a + message without generating the encoded message. Therefore, write the + message out to a temporary stream, and then get the size of the data, + which with a bit of adjustment, will give us the size of the message + we will send. + The "adjustment" is necessary because SaveToStream generates it's own + headers, which will be different to both the ones in AMsg and + AAlternativeHeaders, in the Date header, if nothing else.} + + LStream := TMemoryStream.Create; + try + {RLebeau 04/02/2014: if the user passed in AMsg.LastGeneratedHeaders + or AMsg.Headers as AAlternativeHeaders, then assume the user wants to + use the headers that existed prior to AMsg being saved below, which + may create new header values...} + + LCopiedHeaders := nil; + try + if (AAlternativeHeaders <> nil) and + ((AAlternativeHeaders = AMsg.LastGeneratedHeaders) or (AAlternativeHeaders = AMsg.Headers)) then + begin + LCopiedHeaders := TIdHeaderList.Create(QuoteRFC822); + LCopiedHeaders.Assign(AAlternativeHeaders); + end; + + {RLebeau 12/09/2012: this is a workaround to a design limitation in + TIdMessage.SaveToStream(). It always outputs the stream data in an + escaped format using SMTP dot transparency, but that is not used in + IMAP! Until this design is corrected, we have to use a workaround + for now. This logic is copied from TIdMessage.SaveToSteam() and + slightly tweaked...} + + //AMsg.SaveToStream(LStream); + {$IFDEF HAS_CLASS_HELPER} + AMsg.SaveToStream(LStream, False, False); + {$ELSE} + TIdMessageHelper_SaveToStream(AMsg, LStream, False, False); + {$ENDIF} + + LStream.Position := 0; + {We are better off making up the headers as a string first rather than predicting + its length. Slightly wasteful of memory, but it will not take up much.} + LHeadersAsString := ''; + + {Make sure the headers we end up using have the correct MIME boundary actually + used in the message being saved...} + if AMsg.NoEncode then begin + LMimeBoundary := AMsg.Headers.Params['Content-Type', 'boundary']; {do not localize} + end else begin + LMimeBoundary := AMsg.LastGeneratedHeaders.Params['Content-Type', 'boundary']; {do not localize} + end; + if (LCopiedHeaders = nil) and (AAlternativeHeaders <> nil) then begin + if AAlternativeHeaders.Params['Content-Type', 'boundary'] <> LMimeBoundary then {do not localize} + begin + LCopiedHeaders := TIdHeaderList.Create(QuoteRFC822); + LCopiedHeaders.Assign(AAlternativeHeaders); + end; + end; + + // TODO: if AInternalDateTimeGMT is not 0.0, should we adjust the 'Date' header of the sent email to match? + + if LCopiedHeaders <> nil then begin + {Use the copied headers that the user has passed to us, adjusting the MIME boundary...} + LCopiedHeaders.Params['Content-Type', 'boundary'] := LMimeBoundary; {do not localize} + LHeadersToSend := LCopiedHeaders; + end + else if AAlternativeHeaders <> nil then begin + {Use the headers that the user has passed to us...} + LHeadersToSend := AAlternativeHeaders; + end + else if AMsg.NoEncode then begin + {Use the headers that are in the message AMsg...} + LHeadersToSend := AMsg.Headers; + end else begin + {Use the headers that SaveToStream() generated...} + LHeadersToSend := AMsg.LastGeneratedHeaders; + end; + // not using LHeadersToSend.Text because it uses platform-specific line breaks + for Ln := 0 to Pred(LHeadersToSend.Count) do begin + LHeadersAsString := LHeadersAsString + LHeadersToSend[Ln] + EOL; + end; + finally + LCopiedHeaders.Free; + end; + + LHeadersAsBytes := ToBytes(LHeadersAsString + EOL); + LHeadersAsString := ''; + + {Get the size of the headers we are sending...} + repeat until Length(ReadLnFromStream(LStream)) = 0; + {We have to subtract the size of the headers in the file and + add back the size of the headers we are to use + to get the size of the message we are going to send...} + LLength := Length(LHeadersAsBytes) + (LStream.Size - LStream.Position); + + // TODO: check the server's APPENDLIMIT capability (RFC 7889) to see if + // LLength is too large, and if so then we can bail out here... + + if IsCapabilityListed('LITERAL-') then begin {Do not Localize} + LUseNonSyncLiteral := LLength <= 4096; + end else begin + LUseNonSyncLiteral := IsCapabilityListed('LITERAL+'); {Do not Localize} + end; + + if LUseNonSyncLiteral then begin + LMsgLiteral := '{' + IntToStr ( LLength ) + '+}'; {Do not Localize} + end else begin + LMsgLiteral := '{' + IntToStr ( LLength ) + '}'; {Do not Localize} + end; + {CC: The original code sent the APPEND command first, then followed it with the + message. Maybe this worked with some server, but most send a + response like "+ Send the additional command..." between the two, + which was not expected by the client and caused an exception.} + + //CC: Added double quotes around mailbox name, else mailbox names with spaces will cause server parsing error + LCmd := IMAP4Commands[cmdAppend] + ' "' + DoMUTFEncode(AMBName) + '" '; {Do not Localize} + if Length(LFlags) <> 0 then begin + LCmd := LCmd + LFlags + ' '; {Do not Localize} + end; + if Length(LDateTime) <> 0 then begin + LCmd := LCmd + LDateTime + ' '; {Do not Localize} + end; + LCmd := LCmd + LMsgLiteral; {Do not Localize} + + {CC3: Catch "Connection reset by peer"...} + try + if LUseNonSyncLiteral then begin + {Send the APPEND command and the message immediately, no + response needed...} + IOHandler.WriteLn(NewCmdCounter + ' ' + LCmd); + end else begin + {Try sending the APPEND command, get the + response, then send the message...} + SendCmd(NewCmdCounter, LCmd, []); + if LastCmdResult.Code <> IMAP_CONT then begin + Exit; + end; + end; + + LHelper := TIdIMAP4WorkHelper.Create(Self); + try + IOHandler.Write(LHeadersAsBytes); + {RLebeau: passing -1 to TIdIOHandler.Write(TStream) will send the + rest of the stream starting at its current Position...} + IOHandler.Write(LStream, -1, False); + finally + FreeAndNil(LHelper); + end; + + {WARNING: After we send the message (which should be exactly + LLength bytes long), we need to send an EXTRA CRLF which is in + addition to the count in LLength, because this CRLF terminates the + APPEND command...} + IOHandler.WriteLn; + if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdAppend]], False) = IMAP_OK then begin + Result := True; + end; + except + on E: EIdSocketError do begin + if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin + FConnectionState := csUnexpectedlyDisconnected; + end; + raise; + end; + end; + finally + LStream.Free; + end; + end; +end; + +function TIdIMAP4.AppendMsgNoEncodeFromFile(const AMBName: String; ASourceFile: string; const AFlags: TIdMessageFlagsSet = []; + const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; +var + LSourceStream: TIdReadFileExclusiveStream; +begin + LSourceStream := TIdReadFileExclusiveStream.Create(ASourceFile); + try + Result := AppendMsgNoEncodeFromStream(AMBName, LSourceStream, AFlags, AInternalDateTimeGMT); + finally + FreeAndNil(LSourceStream); + end; +end; + +function TIdIMAP4.AppendMsgNoEncodeFromStream(const AMBName: String; AStream: TStream; const AFlags: TIdMessageFlagsSet = []; + const AInternalDateTimeGMT: TDateTime = 0.0): Boolean; +const + cTerminator: array[0..4] of Byte = (13, 10, Ord('.'), 13, 10); +var + LFlags, LDateTime, LMsgLiteral: String; + LUseNonSyncLiteral: Boolean; + I: Integer; + LFound: Boolean; + LCmd: string; + LLength: TIdStreamSize; + LTempStream: TMemoryStream; + LHelper: TIdIMAP4WorkHelper; + LBuf: TIdBytes; +begin + Result := False; + CheckConnectionState([csAuthenticated, csSelected]); + if Length(AMBName) <> 0 then begin + LFlags := MessageFlagSetToStr(AFlags); + if LFlags <> '' then begin {Do not Localize} + LFlags := '(' + LFlags + ')'; {Do not Localize} + end; + if AInternalDateTimeGMT <> 0.0 then begin + // even though flags are optional, some servers, such as GMail, will + // fail to parse the command correctly if no flags are specified in + // front of the internal date... + if LFlags = '' then begin + LFlags := '()'; // TODO: should 'NIL' be used instead? {Do not Localize} + end; + LDateTime := '"' + DateTimeGMTToImapStr(AInternalDateTimeGMT) + '"'; {Do not Localize} + end; + LLength := AStream.Size - AStream.Position; + if LLength < 0 then begin + LLength := 0; + end; + + LTempStream := TMemoryStream.Create; + try + //Hunt for CRLF.CRLF, if present then we need to remove it... + + // RLebeau: why? The lines of the message data are not required to be + // dot-prefixed like in SMTP, so why should TIdIMAP care about any + // termination sequences in the file? We are telling the server exactly + // how large the message actually is. What if the message data actually + // contains a valid line with just a dot on it? This code would end up + // truncating the message that is stored on the server... + + SetLength(LBuf, 5); + if LLength > 0 then begin + LTempStream.CopyFrom(AStream, LLength); + LTempStream.Position := 0; + end; + repeat + if TIdStreamHelper.ReadBytes(LTempStream, LBuf, 5) < 5 then begin + Break; + end; + LFound := True; + for I := 0 to 4 do begin + if LBuf[I] <> cTerminator[I] then begin + LFound := False; + Break; + end; + end; + if LFound then begin + LLength := LTempStream.Position-5; + Break; + end; + TIdStreamHelper.Seek(LTempStream, -4, soCurrent); + until False; + + if IsCapabilityListed('LITERAL-') then begin {Do not Localize} + LUseNonSyncLiteral := LLength <= 4096; + end else begin + LUseNonSyncLiteral := IsCapabilityListed('LITERAL+'); {Do not Localize} + end; + + if LUseNonSyncLiteral then begin + LMsgLiteral := '{' + IntToStr(LLength) + '+}'; {Do not Localize} + end else begin + LMsgLiteral := '{' + IntToStr(LLength) + '}'; {Do not Localize} + end; + + {CC: The original code sent the APPEND command first, then followed it with the + message. Maybe this worked with some server, but most send a + response like "+ Send the additional command..." between the two, + which was not expected by the client and caused an exception.} + + //CC: Added double quotes around mailbox name, else mailbox names with spaces will cause server parsing error + LCmd := IMAP4Commands[cmdAppend] + ' "' + DoMUTFEncode(AMBName) + '" '; {Do not Localize} + if Length(LFlags) <> 0 then begin + LCmd := LCmd + LFlags + ' '; {Do not Localize} + end; + if Length(LDateTime) <> 0 then begin + LCmd := LCmd + LDateTime + ' '; {Do not Localize} + end; + LCmd := LCmd + LMsgLiteral; {Do not Localize} + + {CC3: Catch "Connection reset by peer"...} + try + if LUseNonSyncLiteral then begin + {Send the APPEND command and the message immediately, no + response needed...} + IOHandler.WriteLn(NewCmdCounter + ' ' + LCmd); + end else begin + {Try sending the APPEND command, get the + response, then send the message...} + SendCmd(NewCmdCounter, LCmd, []); + if LastCmdResult.Code <> IMAP_CONT then begin + Exit; + end; + end; + + // TODO: if AInternalDateTimeGMT is not 0.0, should we adjust the 'Date' header of the sent email to match? + + LTempStream.Position := 0; + LHelper := TIdIMAP4WorkHelper.Create(Self); + try + IOHandler.Write(LTempStream, LLength); + finally + FreeAndNil(LHelper); + end; + + {WARNING: After we send the message (which should be exactly + LLength bytes long), we need to send an EXTRA CRLF which is in + addition to the count in LLength, because this CRLF terminates the + APPEND command...} + IOHandler.WriteLn; + if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdAppend]], False) = IMAP_OK then begin + Result := True; + end; + except + on E: EIdSocketError do begin + if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin + FConnectionState := csUnexpectedlyDisconnected; + end; + raise; + end; + end; + finally + FreeAndNil(LTempStream); + end; + end; +end; + +function TIdIMAP4.RetrieveEnvelope(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; +begin + Result := InternalRetrieveEnvelope(AMsgNum, AMsg, nil); +end; + +function TIdIMAP4.RetrieveEnvelopeRaw(const AMsgNum: UInt32; ADestList: TStrings): Boolean; +begin + Result := InternalRetrieveEnvelope(AMsgNum, nil, ADestList); +end; + +function TIdIMAP4.InternalRetrieveEnvelope(const AMsgNum: UInt32; AMsg: TIdMessage; ADestList: TStrings): Boolean; +begin + {CC2: Return False if message number is invalid...} + Result := False; + IsNumberValid(AMsgNum); + CheckConnectionState(csSelected); + {Some servers return NO if the requested message number is not present + (e.g. Cyrus), others return OK but no data (CommuniGate).} + SendCmd(NewCmdCounter, + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdEnvelope] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch]]); + if LastCmdResult.Code = IMAP_OK then begin + if LastCmdResult.Text.Count > 0 then begin + if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdEnvelope]]) then begin + if ADestList <> nil then begin + ADestList.BeginUpdate; + try + ADestList.Clear; + ADestList.Add(FLineStruct.IMAPValue); + finally + ADestList.EndUpdate; + end; + end; + if AMsg <> nil then begin + ParseEnvelopeResult(AMsg, FLineStruct.IMAPValue); + end; + Result := True; + end; + end; + end; +end; + +function TIdIMAP4.UIDRetrieveEnvelope(const AMsgUID: String; AMsg: TIdMessage): Boolean; +begin + Result := UIDInternalRetrieveEnvelope(AMsgUID, AMsg, nil); +end; + +function TIdIMAP4.UIDRetrieveEnvelopeRaw(const AMsgUID: String; ADestList: TStrings): Boolean; +begin + Result := UIDInternalRetrieveEnvelope(AMsgUID, nil, ADestList); +end; + +function TIdIMAP4.UIDInternalRetrieveEnvelope(const AMsgUID: String; AMsg: TIdMessage; ADestList: TStrings): Boolean; +begin + {CC2: Return False if message number is invalid...} + Result := False; + IsUIDValid(AMsgUID); + CheckConnectionState(csSelected); + {Some servers return NO if the requested message number is not present + (e.g. Cyrus), others return OK but no data (CommuniGate).} + SendCmd(NewCmdCounter, + IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + IMAP4FetchDataItem[fdEnvelope] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]]); + if LastCmdResult.Code = IMAP_OK then begin + if LastCmdResult.Text.Count > 0 then begin + if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdEnvelope]]) then begin + if ADestList <> nil then begin + ADestList.BeginUpdate; + try + ADestList.Clear; + ADestList.Add(FLineStruct.IMAPValue); + finally + ADestList.EndUpdate; + end; + end; + if AMsg <> nil then begin + ParseEnvelopeResult(AMsg, FLineStruct.IMAPValue); + end; + Result := True; + end; + end; + end; +end; + +function TIdIMAP4.RetrieveAllEnvelopes(AMsgList: TIdMessageCollection): Boolean; +{NOTE: If AMsgList is empty or does not have enough records, records will be added. +If you pass a non-empty AMsgList, it is assumed the records are in relative record +number sequence: if not, pass in an empty AMsgList and copy the results to your +own AMsgList.} +var + Ln: Integer; + LMsg: TIdMessage; +begin + Result := False; + {CC2: This is one of the few cases where the server can return only "OK completed" + meaning that the user has no envelopes.} + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdFetch] + ' 1:* (' + IMAP4FetchDataItem[fdEnvelope] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch]]); + if LastCmdResult.Code = IMAP_OK then begin + for Ln := 0 to LastCmdResult.Text.Count-1 do begin + if ParseLastCmdResult(LastCmdResult.Text[Ln], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdEnvelope]]) then begin + if LN >= AMsgList.Count then begin + LMsg := AMsgList.Add.Msg; + end else begin + LMsg := AMsgList.Messages[LN]; + end; + ParseEnvelopeResult(LMsg, FLineStruct.IMAPValue); + end; + end; + Result := True; + end; +end; + +function TIdIMAP4.UIDRetrieveAllEnvelopes(AMsgList: TIdMessageCollection): Boolean; +{NOTE: If AMsgList is empty or does not have enough records, records will be added. +If you pass a non-empty AMsgList, it is assumed the records are in relative record +number sequence: if not, pass in an empty AMsgList and copy the results to your +own AMsgList.} +var + Ln: Integer; + LMsg: TIdMessage; +begin + Result := False; + {CC2: This is one of the few cases where the server can return only "OK completed" + meaning that the user has no envelopes.} + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' 1:* (' + IMAP4FetchDataItem[fdEnvelope] + ' ' + IMAP4FetchDataItem[fdFlags] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch]]); + if LastCmdResult.Code = IMAP_OK then begin + for Ln := 0 to LastCmdResult.Text.Count-1 do begin + if ParseLastCmdResult(LastCmdResult.Text[Ln], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdEnvelope]]) then begin + if LN >= AMsgList.Count then begin + LMsg := AMsgList.Add.Msg; + end else begin + LMsg := AMsgList.Messages[LN]; + end; + ParseEnvelopeResult(LMsg, FLineStruct.IMAPValue); + LMsg.UID := FLineStruct.UID; + LMsg.Flags := FLineStruct.Flags; + end; + end; + Result := True; + end; +end; + +function TIdIMAP4.RetrieveText(const AMsgNum: UInt32; var AText: string): Boolean; + //Retrieve a specific individual part of a message +begin + Result := InternalRetrieveText(AMsgNum, AText, False, False, False); +end; + +function TIdIMAP4.RetrieveText2(const AMsgNum: UInt32; var AText: string): Boolean; + //Retrieve a specific individual part of a message +begin + Result := InternalRetrieveText(AMsgNum, AText, False, False, True); +end; + +function TIdIMAP4.RetrieveTextPeek(const AMsgNum: UInt32; var AText: string): Boolean; + {CC3: Added: Retrieve the text part of the message...} +begin + Result := InternalRetrieveText(AMsgNum, AText, False, True, False); +end; + +function TIdIMAP4.RetrieveTextPeek2(const AMsgNum: UInt32; var AText: string): Boolean; + {CC3: Added: Retrieve the text part of the message...} +begin + Result := InternalRetrieveText(AMsgNum, AText, False, True, True); +end; + +function TIdIMAP4.UIDRetrieveText(const AMsgUID: String; var AText: string): Boolean; + {CC3: Added: Retrieve the text part of the message...} +begin + Result := InternalRetrieveText(UIDToUInt32(AMsgUID), AText, True, False, False); +end; + +function TIdIMAP4.UIDRetrieveText2(const AMsgUID: String; var AText: string): Boolean; + {CC3: Added: Retrieve the text part of the message...} +begin + Result := InternalRetrieveText(UIDToUInt32(AMsgUID), AText, True, False, True); +end; + +function TIdIMAP4.UIDRetrieveTextPeek(const AMsgUID: String; var AText: string): Boolean; + {CC3: Added: Retrieve the text part of the message...} +begin + Result := InternalRetrieveText(UIDToUInt32(AMsgUID), AText, True, True, False); +end; + +function TIdIMAP4.UIDRetrieveTextPeek2(const AMsgUID: String; var AText: string): Boolean; + {CC3: Added: Retrieve the text part of the message...} +begin + Result := InternalRetrieveText(UIDToUInt32(AMsgUID), AText, True, True, True); +end; + +function TIdIMAP4.InternalRetrieveText(const AMsgNum: UInt32; var AText: string; + AUseUID: Boolean; AUsePeek: Boolean; AUseFirstPartInsteadOfText: Boolean): Boolean; + {CC3: Added: Retrieve the text part of the message...} +var + LCmd: string; + LParts: TIdImapMessageParts; + LThePart: TIdImapMessagePart; + LCharSet: String; + LContentTransferEncoding: string; + LTextPart: integer; + LTextPartNum: string; + LHelper: TIdIMAP4WorkHelper; + + procedure DoDecode(ADecoderClass: TIdDecoderClass = nil; AStripCRLFs: Boolean = False); + var + LDecoder: TIdDecoder; + LStream: TStream; + LStrippedStream: TStringStream; + LUnstrippedStream: TStringStream; + LEncoding: IIdTextEncoding; + begin + LStream := TMemoryStream.Create; + try + if ADecoderClass <> nil then begin + LDecoder := ADecoderClass.Create(Self); + try + LDecoder.DecodeBegin(LStream); + try + LUnstrippedStream := TStringStream.Create(''); + try + IOHandler.ReadStream(LUnstrippedStream, FLineStruct.ByteCount); //ReadStream uses OnWork, most other methods dont + {This is more complicated than quoted-printable because we + have to strip CRLFs that have been inserted by the MTA to + avoid overly long lines...} + if AStripCRLFs then begin + LStrippedStream := TStringStream.Create(''); + try + StripCRLFs(LUnstrippedStream, LStrippedStream); + LDecoder.Decode(LStrippedStream.DataString); + finally + FreeAndNil(LStrippedStream); + end; + end else begin + LDecoder.Decode(LUnstrippedStream.DataString); + end; + finally + FreeAndNil(LUnstrippedStream); + end; + finally + LDecoder.DecodeEnd; + end; + finally + FreeAndNil(LDecoder); + end; + end else begin + IOHandler.ReadStream(LStream, FLineStruct.ByteCount); //ReadStream uses OnWork, most other methods dont + end; + LStream.Position := 0; + if LCharSet <> '' then begin + LEncoding := CharsetToEncoding(LCharSet); + AText := ReadStringFromStream(LStream, -1, LEncoding{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_OSDefault{$ENDIF}); + end else begin + AText := ReadStringFromStream(LStream, -1, IndyTextEncoding_8Bit{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_8Bit{$ENDIF}); + end; + finally + FreeAndNil(LStream); + end; + end; + +begin + Result := False; + AText := ''; {Do not Localize} + IsNumberValid(AMsgNum); + CheckConnectionState(csSelected); + if AUseFirstPartInsteadOfText then begin + {In this case, we need the body structure to find out what + encoding has been applied to part 1...} + LParts := TIdImapMessageParts.Create(nil); + try + if AUseUID then begin + if not UIDRetrieveStructure(IntToStr(Int64(AMsgNum)), LParts) then begin + Exit; + end; + end else begin + if not RetrieveStructure(AMsgNum, LParts) then begin + Exit; + end; + end; + + {Get the info we want out of LParts...} + {Some emails have their first parts empty, so search for the first non-empty part.} + LTextPartNum := ''; + for LTextPart := 0 to LParts.Count-1 do begin + LThePart := LParts.Items[LTextPart]; + if (LThePart.ImapPartNumber <> '') and (LThePart.FSize <> 0) then begin + LTextPartNum := LThePart.ImapPartNumber; + LCharSet := LThePart.CharSet; + LContentTransferEncoding := LThePart.ContentTransferEncoding; + Break; + end; + end; + + // RLebeau 7/27/2021: for backwards compatibility, if no item was selected above, + // use the last item in the structure. This is likely wrong, but it is what the + // previous logic was doing, so preserving it... + if (LTextPartNum = '') and (LParts.Count > 0) then begin + LThePart := LParts.Items[LParts.Count-1]; + LTextPartNum := LThePart.ImapPartNumber; + LCharSet := LThePart.CharSet; + LContentTransferEncoding := LThePart.ContentTransferEncoding; + end; + + finally + FreeAndNil(LParts); + end; + end else begin + // TODO: detect LCharSet and LContentTransferEncoding... + end; + LCmd := ''; + if AUseUID then begin + LCmd := LCmd + IMAP4Commands[cmdUID] + ' '; {Do not Localize} + end; + LCmd := LCmd + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' ('; {Do not Localize} + if AUsePeek then begin + LCmd := LCmd + IMAP4FetchDataItem[fdBody]+'.PEEK'; {Do not Localize} + end else begin + LCmd := LCmd + IMAP4FetchDataItem[fdBody]; + end; + if not AUseFirstPartInsteadOfText then begin + LCmd := LCmd + '[TEXT])'; {Do not Localize} + end else begin + LCmd := LCmd + '[' + LTextPartNum + '])'; {Do not Localize} + end; + + SendCmd(NewCmdCounter, LCmd, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], True, False); + if LastCmdResult.Code = IMAP_OK then begin + try + {For an invalid request (non-existent part or message), NIL is returned as the size...} + if (LastCmdResult.Text.Count < 1) + or (not ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], + [IMAP4FetchDataItem[fdBody]+'[TEXT]' , IMAP4FetchDataItem[fdBody]+'['+LTextPartNum+']'])) {do not localize} + or (PosInStrArray(FLineStruct.IMAPValue, ['NIL', '""'], False) <> -1) {do not localize} + or (FLineStruct.ByteCount < 1) then + begin + GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False); + Result := False; + Exit; + end; + + LHelper := TIdIMAP4WorkHelper.Create(Self); + try + case PosInStrArray(LContentTransferEncoding, ['base64', 'quoted-printable', 'binhex40'], False) of {Do not Localize} + 0: DoDecode(TIdDecoderMIME, True); + 1: DoDecode(TIdDecoderQuotedPrintable); + 2: DoDecode(TIdDecoderBinHex4); + else + {Assume no encoding (8bit) or something we cannot decode...} + DoDecode(); + end; + finally + FreeAndNil(LHelper); + end; + IOHandler.ReadLnWait; {Remove last line, ')' or 'UID 1)'} + if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin + Result := True; + end; + except + on E: EIdSocketError do begin + if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin + FConnectionState := csUnexpectedlyDisconnected; + end; + raise; + end; + end; + end; +end; + +function TIdIMAP4.RetrieveStructure(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; +begin + Result := InternalRetrieveStructure(AMsgNum, AMsg, nil); +end; + +function TIdIMAP4.RetrieveStructure(const AMsgNum: UInt32; AParts: TIdImapMessageParts): Boolean; +begin + Result := InternalRetrieveStructure(AMsgNum, nil, AParts); +end; + +function TIdIMAP4.InternalRetrieveStructure(const AMsgNum: UInt32; AMsg: TIdMessage; AParts: TIdImapMessageParts): Boolean; +var + LTheParts: TIdMessageParts; +begin + Result := False; + IsNumberValid(AMsgNum); + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdBodyStructure] + ')', + [IMAP4Commands[cmdFetch]], True, False); + if LastCmdResult.Code = IMAP_OK then begin + {CC3: Catch "Connection reset by peer"...} + try + if LastCmdResult.Text.Count > 0 then begin + if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdBodyStructure]]) then begin + if AMsg <> nil then begin + LTheParts := AMsg.MessageParts; + end else begin + LTheParts := nil; + end; + ParseBodyStructureResult(FLineStruct.IMAPValue, LTheParts, AParts); + if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch]], False) = IMAP_OK then begin + Result := True; + end; + end; + end; + except + on E: EIdSocketError do begin + if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin + FConnectionState := csUnexpectedlyDisconnected; + end; + raise; + end; + end; + end; +end; + +// retrieve a specific individual part of a message +function TIdIMAP4.RetrievePart(const AMsgNum: UInt32; const APartNum: string; + ADestStream: TStream; AContentTransferEncoding: string): Boolean; +var + LDummy1: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + LDummy2: Integer; +begin + if ADestStream = nil then begin + Result := False; + end else begin + Result := InternalRetrievePart(AMsgNum, APartNum, False, False, ADestStream, LDummy1, LDummy2, '', AContentTransferEncoding); {Do not Localize} + end; +end; + +function TIdIMAP4.RetrievePart(const AMsgNum: UInt32; const APartNum: Integer; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; +begin + IsImapPartNumberValid(APartNum); + Result := RetrievePart(AMsgNum, IntToStr(APartNum), ABuffer, ABufferLength, AContentTransferEncoding); +end; + +// Retrieve a specific individual part of a message +function TIdIMAP4.RetrievePart(const AMsgNum: UInt32; const APartNum: string; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; +begin + Result := InternalRetrievePart(AMsgNum, APartNum, False, False, nil, ABuffer, ABufferLength, '', AContentTransferEncoding); {Do not Localize} +end; + +// retrieve a specific individual part of a message +function TIdIMAP4.RetrievePartPeek(const AMsgNum: UInt32; const APartNum: string; + ADestStream: TStream; AContentTransferEncoding: string): Boolean; +var + LDummy1: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + LDummy2: Integer; +begin + if ADestStream = nil then begin + Result := False; + end else begin + Result := InternalRetrievePart(AMsgNum, APartNum, False, True, ADestStream, LDummy1, LDummy2, '', AContentTransferEncoding); {Do not Localize} + end; +end; + +function TIdIMAP4.RetrievePartPeek(const AMsgNum: UInt32; const APartNum: Integer; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; +begin + IsImapPartNumberValid(APartNum); + Result := RetrievePartPeek(AMsgNum, IntToStr(APartNum), ABuffer, ABufferLength, AContentTransferEncoding); +end; + +//Retrieve a specific individual part of a message +function TIdIMAP4.RetrievePartPeek(const AMsgNum: UInt32; const APartNum: string; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; +begin + Result := InternalRetrievePart(AMsgNum, APartNum, False, True, nil, ABuffer, ABufferLength, '', AContentTransferEncoding); {Do not Localize} +end; + +// Retrieve a specific individual part of a message +function TIdIMAP4.UIDRetrievePart(const AMsgUID: String; const APartNum: string; + var ADestStream: TStream; AContentTransferEncoding: string): Boolean; +var + LDummy1: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + LDummy2: Integer; +begin + if ADestStream = nil then begin + Result := False; + end else begin + Result := InternalRetrievePart(UIDToUInt32(AMsgUID), APartNum, True, False, ADestStream, LDummy1, LDummy2, '', AContentTransferEncoding); {Do not Localize} + end; +end; + +function TIdIMAP4.UIDRetrievePart(const AMsgUID: String; const APartNum: Integer; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; +begin + IsImapPartNumberValid(APartNum); + Result := UIDRetrievePart(AMsgUID, IntToStr(APartNum), ABuffer, ABufferLength, AContentTransferEncoding); +end; + +// Retrieve a specific individual part of a message +function TIdIMAP4.UIDRetrievePart(const AMsgUID: String; const APartNum: string; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; +begin + Result := InternalRetrievePart(UIDToUInt32(AMsgUID), APartNum, True, False, nil, ABuffer, ABufferLength, '', AContentTransferEncoding); {Do not Localize} +end; + +// retrieve a specific individual part of a message +function TIdIMAP4.UIDRetrievePartPeek(const AMsgUID: String; const APartNum: string; + var ADestStream: TStream; AContentTransferEncoding: string): Boolean; +var + LDummy1: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + LDummy2: Integer; +begin + if ADestStream = nil then begin + Result := False; + end else begin + Result := InternalRetrievePart(UIDToUInt32(AMsgUID), APartNum, True, True, ADestStream, LDummy1, LDummy2, '', AContentTransferEncoding); {Do not Localize} + end; +end; + +function TIdIMAP4.UIDRetrievePartPeek(const AMsgUID: String; const APartNum: Integer; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; +begin + IsImapPartNumberValid(APartNum); + Result := UIDRetrievePartPeek(AMsgUID, IntToStr(APartNum), ABuffer, ABufferLength, AContentTransferEncoding); +end; + +function TIdIMAP4.UIDRetrievePartPeek(const AMsgUID: String; const APartNum: string; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; AContentTransferEncoding: string): Boolean; + //Retrieve a specific individual part of a message +begin + Result := InternalRetrievePart(UIDToUInt32(AMsgUID), APartNum, True, True, nil, ABuffer, ABufferLength, '', AContentTransferEncoding); {Do not Localize} +end; + +function TIdIMAP4.RetrievePartToFile(const AMsgNum: UInt32; const APartNum: Integer; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; +begin + IsImapPartNumberValid(APartNum); + Result := RetrievePartToFile(AMsgNum, IntToStr(APartNum), ALength, ADestFileNameAndPath, AContentTransferEncoding); +end; + +// retrieve a specific individual part of a message +function TIdIMAP4.RetrievePartToFile(const AMsgNum: UInt32; const APartNum: string; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; +var + LDummy: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; +begin + if Length(ADestFileNameAndPath) = 0 then begin + Result := False; + end else begin + Result := InternalRetrievePart(AMsgNum, APartNum, False, False, nil, + LDummy, ALength, ADestFileNameAndPath, AContentTransferEncoding); + end; +end; + +function TIdIMAP4.RetrievePartToFilePeek(const AMsgNum: UInt32; const APartNum: Integer; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; +begin + IsImapPartNumberValid(APartNum); + Result := RetrievePartToFilePeek(AMsgNum, IntToStr(APartNum), ALength, ADestFileNameAndPath, AContentTransferEncoding); +end; + +// retrieve a specific individual part of a message +function TIdIMAP4.RetrievePartToFilePeek(const AMsgNum: UInt32; const APartNum: string; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; +var + LDummy: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; +begin + if Length(ADestFileNameAndPath) = 0 then begin + Result := False; + end else begin + Result := InternalRetrievePart(AMsgNum, APartNum, False, True, nil, + LDummy, ALength, ADestFileNameAndPath, AContentTransferEncoding); + end; +end; + +function TIdIMAP4.UIDRetrievePartToFile(const AMsgUID: String; const APartNum: Integer; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; +begin + IsImapPartNumberValid(APartNum); + Result := UIDRetrievePartToFile(AMsgUID, IntToStr(APartNum), ALength, ADestFileNameAndPath, AContentTransferEncoding); +end; + +// retrieve a specific individual part of a message +function TIdIMAP4.UIDRetrievePartToFile(const AMsgUID: String; const APartNum: string; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; +var + LDummy: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; +begin + if Length(ADestFileNameAndPath) = 0 then begin + Result := False; + end else begin + Result := InternalRetrievePart(UIDToUInt32(AMsgUID), APartNum, True, False, nil, + LDummy, ALength, ADestFileNameAndPath, AContentTransferEncoding); + end; +end; + +function TIdIMAP4.UIDRetrievePartToFilePeek(const AMsgUID: String; const APartNum: Integer; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; +begin + IsImapPartNumberValid(APartNum); + Result := UIDRetrievePartToFilePeek(AMsgUID, IntToStr(APartNum), ALength, ADestFileNameAndPath, AContentTransferEncoding); +end; + +// retrieve a specific individual part of a message +function TIdIMAP4.UIDRetrievePartToFilePeek(const AMsgUID: String; const APartNum: {Integer} string; + ALength: Integer; ADestFileNameAndPath: string; AContentTransferEncoding: string): Boolean; +var + LDummy: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; +begin + if Length(ADestFileNameAndPath) = 0 then begin + Result := False; + end else begin + Result := InternalRetrievePart(UIDToUInt32(AMsgUID), APartNum, True, True, + nil, LDummy, ALength, ADestFileNameAndPath, AContentTransferEncoding); + end; +end; + +// retrieve a specific individual part of a message +// TODO: remove the ABufferLength output parameter under DOTNET, it is redundant... +function TIdIMAP4.InternalRetrievePart(const AMsgNum: UInt32; const APartNum: {Integer} string; + AUseUID: Boolean; AUsePeek: Boolean; ADestStream: TStream; + var ABuffer: {$IFDEF DOTNET}TIdBytes{$ELSE}PByte{$ENDIF}; + var ABufferLength: Integer; {NOTE: var args cannot have default params} + ADestFileNameAndPath: string; + AContentTransferEncoding: string): Boolean; +var + LCmd: string; + bCreatedStream: Boolean; + LDestStream: TStream; +// LPartSizeParam: string; + LHelper: TIdIMAP4WorkHelper; + + procedure DoDecode(ADecoderClass: TIdDecoderClass = nil; AStripCRLFs: Boolean = False); + var + LDecoder: TIdDecoder; + LStream: TStream; + LStrippedStream: TStringStream; + LUnstrippedStream: TStringStream; + begin + if LDestStream = nil then begin + LStream := TMemoryStream.Create; + end else begin + LStream := LDestStream; + end; + try + if ADecoderClass <> nil then begin + LDecoder := ADecoderClass.Create(Self); + try + LDecoder.DecodeBegin(LStream); + try + LUnstrippedStream := TStringStream.Create(''); + try + IOHandler.ReadStream(LUnstrippedStream, ABufferLength); //ReadStream uses OnWork, most other methods dont + {This is more complicated than quoted-printable because we + have to strip CRLFs that have been inserted by the MTA to + avoid overly long lines...} + if AStripCRLFs then begin + LStrippedStream := TStringStream.Create(''); + try + StripCRLFs(LUnstrippedStream, LStrippedStream); + LDecoder.Decode(LStrippedStream.DataString); + finally + FreeAndNil(LStrippedStream); + end; + end else begin + LDecoder.Decode(LUnstrippedStream.DataString); + end; + finally + FreeAndNil(LUnstrippedStream); + end; + finally + LDecoder.DecodeEnd; + end; + finally + FreeAndNil(LDecoder); + end; + end else begin + IOHandler.ReadStream(LStream, ABufferLength); //ReadStream uses OnWork, most other methods dont + end; + if LDestStream = nil then begin + ABufferLength := LStream.Size; + {$IFDEF DOTNET} + //ABuffer is a TIdBytes. + SetLength(ABuffer, ABufferLength); + if ABufferLength > 0 then begin + LStream.Position := 0; + ReadTIdBytesFromStream(LStream, ABuffer, ABufferLength); + end; + {$ELSE} + //ABuffer is a PByte. + GetMem(ABuffer, ABufferLength); + if ABufferLength > 0 then begin + LStream.Position := 0; + LStream.ReadBuffer(ABuffer^, ABufferLength); + end; + {$ENDIF} + end; + finally + if LDestStream = nil then begin + FreeAndNil(LStream); + end; + end; + end; + +begin + Result := False; + {CCC: Make sure part number is valid since it is now passed as a string...} + IsImapPartNumberValid(APartNum); + ABuffer := nil; + ABufferLength := 0; + CheckConnectionState(csSelected); + LCmd := ''; + if AUseUID then begin + LCmd := LCmd + IMAP4Commands[cmdUID] + ' '; {Do not Localize} + end; + LCmd := LCmd + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' ('; {Do not Localize} + if AUsePeek then begin + LCmd := LCmd + IMAP4FetchDataItem[fdBody]+'.PEEK'; {Do not Localize} + end else begin + LCmd := LCmd + IMAP4FetchDataItem[fdBody]; + end; + LCmd := LCmd + '[' + APartNum + '])'; {Do not Localize} + + SendCmd(NewCmdCounter, LCmd, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], True, False); + if LastCmdResult.Code = IMAP_OK then begin + {CC3: Catch "Connection reset by peer"...} + try + //LPartSizeParam := ''; {Do not Localize} + if ( (LastCmdResult.Text.Count < 1) or + (not ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [])) + or (PosInStrArray(FLineStruct.IMAPValue, ['NIL', '""'], False) <> -1) {do not localize} + or (FLineStruct.ByteCount < 1) ) then + begin + GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False); + Result := False; + Exit; + end; + {CC4: Some messages have an empty first part. These respond as: + 17 FETCH (BODY[1] "" UID 20) + instead of the more normal: + 17 FETCH (BODY[1] {11} {This bracket is not part of the response! + ... + UID 20) + } + ABufferLength := FLineStruct.ByteCount; + bCreatedStream := False; + + if ADestStream = nil then + begin + if Length(ADestFileNameAndPath) = 0 then begin + {User wants to write it to a memory block...} + LDestStream := nil; + end else begin + {User wants to write it to a file...} + LDestStream := TIdFileCreateStream.Create(ADestFileNameAndPath); + bCreatedStream := True; + end; + end else + begin + {User wants to write it to a stream ...} + LDestStream := ADestStream; + end; + try + LHelper := TIdIMAP4WorkHelper.Create(Self); + try + if TextIsSame(AContentTransferEncoding, 'base64') then begin {Do not Localize} + DoDecode(TIdDecoderMIME, True); + end else if TextIsSame(AContentTransferEncoding, 'quoted-printable') then begin {Do not Localize} + DoDecode(TIdDecoderQuotedPrintable); + end else if TextIsSame(AContentTransferEncoding, 'binhex40') then begin {Do not Localize} + DoDecode(TIdDecoderBinHex4); + end else begin + {Assume no encoding (8bit) or something we cannot decode...} + DoDecode; + end; + finally + FreeAndNil(LHelper); + end; + finally + if bCreatedStream then begin + FreeAndNil(LDestStream); + end; + end; + IOHandler.ReadLnWait; {Remove last line, ')' or 'UID 1)'} + if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin + Result := True; + end; + except + on E: EIdSocketError do begin + if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin + FConnectionState := csUnexpectedlyDisconnected; + end; + raise; + end; + end; + end; +end; + +function TIdIMAP4.UIDRetrieveStructure(const AMsgUID: String; AMsg: TIdMessage): Boolean; +begin + Result := UIDInternalRetrieveStructure(AMsgUID, AMsg, nil); +end; + +function TIdIMAP4.UIDRetrieveStructure(const AMsgUID: String; AParts: TIdImapMessageParts): Boolean; +begin + Result := UIDInternalRetrieveStructure(AMsgUID, nil, AParts); +end; + +function TIdIMAP4.UIDInternalRetrieveStructure(const AMsgUID: String; AMsg: TIdMessage; AParts: TIdImapMessageParts): Boolean; +var + //LSlRetrieve : TStringList; + //LStr: string; + LTheParts: TIdMessageParts; +begin + Result := False; + IsUIDValid(AMsgUID); + CheckConnectionState(csSelected); + + //Note: The normal single-line response may be split for huge bodystructures, + //allow for this by setting ASingleLineMayBeSplit to True... + SendCmd(NewCmdCounter, + IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + IMAP4FetchDataItem[fdBodyStructure] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], + True, True); + if LastCmdResult.Code = IMAP_OK then begin + {CC3: Catch "Connection reset by peer"...} + try + if LastCmdResult.Text.Count > 0 then begin + if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdBodyStructure]]) then begin + if AMsg <> nil then begin + LTheParts := AMsg.MessageParts; + end else begin + LTheParts := nil; + end; + ParseBodyStructureResult(FLineStruct.IMAPValue, LTheParts, AParts); + if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin + Result := True; + end; + end; + end; + except + on E: EIdSocketError do begin + if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin + FConnectionState := csUnexpectedlyDisconnected; + end; + raise; + end; + end; + end; +end; + +function TIdIMAP4.RetrieveHeader(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; +var + LStr: string; +begin + Result := False; + IsNumberValid(AMsgNum); + CheckConnectionState(csSelected); + + SendCmd(NewCmdCounter, + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdRFC822Header] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch]], True, False); + if LastCmdResult.Code = IMAP_OK then begin + {CC3: Catch "Connection reset by peer"...} + try + if LastCmdResult.Text.Count > 0 then begin + if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdRFC822Header]]) + and (FLineStruct.ByteCount > 0) then + begin + BeginWork(wmRead, FLineStruct.ByteCount); //allow ReadString to use OnWork + try + LStr := IOHandler.ReadString(FLineStruct.ByteCount); + finally + EndWork(wmRead); + end; + {CC2: Clear out body so don't get multiple copies of bodies} + AMsg.Clear; + AMsg.Headers.Text := LStr; + AMsg.ProcessHeaders; + LStr := IOHandler.ReadLnWait; {Remove trailing line after the message, probably a ')' } + ParseLastCmdResultButAppendInfo(LStr); //There may be a UID or FLAGS in this + if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch]], False) = IMAP_OK then begin + AMsg.UID := FLineStruct.UID; + AMsg.Flags := FLineStruct.Flags; + Result := True; + end; + end; + end; + except + on E: EIdSocketError do begin + if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin + FConnectionState := csUnexpectedlyDisconnected; + end; + raise; + end; + end; + end; +end; + +function TIdIMAP4.UIDRetrieveHeader(const AMsgUID: String; AMsg: TIdMessage): Boolean; +var + LStr: string; +begin + Result := False; + IsUIDValid(AMsgUID); + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + IMAP4FetchDataItem[fdRFC822Header] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], True, False); + if LastCmdResult.Code = IMAP_OK then begin + {CC3: Catch "Connection reset by peer"...} + try + if LastCmdResult.Text.Count > 0 then begin + if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdRFC822Header]]) + and (FLineStruct.ByteCount > 0) then + begin + BeginWork(wmRead, FLineStruct.ByteCount); //allow ReadString to use OnWork + try + LStr := IOHandler.ReadString(FLineStruct.ByteCount); + finally + EndWork(wmRead); + end; + {CC2: Clear out body so don't get multiple copies of bodies} + AMsg.Clear; + AMsg.Headers.Text := LStr; + AMsg.ProcessHeaders; + LStr := IOHandler.ReadLnWait; {Remove trailing line after the message, probably a ')' } + ParseLastCmdResultButAppendInfo(LStr); //There may be a UID or FLAGS in this + if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin + AMsg.UID := FLineStruct.UID; + if AMsg.UID = '' then begin + AMsg.UID := AMsgUID; + end; + AMsg.Flags := FLineStruct.Flags; + Result := True; + end; + end; + end; + except + on E: EIdSocketError do begin + if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin + FConnectionState := csUnexpectedlyDisconnected; + end; + raise; + end; + end; + end; +end; + +function TIdIMAP4.RetrievePartHeader(const AMsgNum: UInt32; const APartNum: string; AHeaders: TIdHeaderList): Boolean; +begin + Result := InternalRetrievePartHeader(AMsgNum, APartNum, False, AHeaders); +end; + +function TIdIMAP4.UIDRetrievePartHeader(const AMsgUID: String; const APartNum: string; AHeaders: TIdHeaderList): Boolean; +begin + Result := InternalRetrievePartHeader(UIDToUInt32(AMsgUID), APartNum, True, AHeaders); +end; + +function TIdIMAP4.InternalRetrievePartHeader(const AMsgNum: UInt32; const APartNum: string; + const AUseUID: Boolean; AHeaders: TIdHeaderList): Boolean; +var + LCmd: string; +begin + Result := False; + IsNumberValid(AMsgNum); + CheckConnectionState(csSelected); + LCmd := ''; + if AUseUID then begin + LCmd := LCmd + IMAP4Commands[cmdUID] + ' '; {Do not Localize} + end; + LCmd := LCmd + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdBody] + '[' + APartNum + '.' + IMAP4FetchDataItem[fdHeader] + '])'; {Do not Localize} + + SendCmd(NewCmdCounter, LCmd, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], True, False); + if LastCmdResult.Code = IMAP_OK then begin + {CC3: Catch "Connection reset by peer"...} + try + if LastCmdResult.Text.Count > 0 then begin + if ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], []) + and (PosInStrArray(FLineStruct.IMAPValue, ['NIL', '""'], False) = -1) + and (FLineStruct.ByteCount > 0) then + begin + {CC4: Some messages have an empty first part. These respond as: + 17 FETCH (BODY[1] "" UID 20) + instead of the more normal: + 17 FETCH (BODY[1] {11} {This bracket is not part of the response! + ... + UID 20) + } + BeginWork(wmRead, FLineStruct.ByteCount); //allow ReadString to use OnWork + try + AHeaders.Text := IOHandler.ReadString(FLineStruct.ByteCount); + finally + EndWork(wmRead); + end; + end; + end; + IOHandler.ReadLnWait; + if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin + Result := True; + end; + except + on E: EIdSocketError do begin + if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin + FConnectionState := csUnexpectedlyDisconnected; + end; + raise; + end; + end; + end; +end; + +//This code was just pulled up from IdMessageClient so that logging could be added. +function TIdIMAP4.ReceiveHeader(AMsg: TIdMessage; const AAltTerm: string = ''): string; +begin + repeat + Result := IOHandler.ReadLn; + // Exchange Bug: Exchange sometimes returns . when getting a message instead of + // '' then a . - That is there is no seperation between the header and the message for an + // empty message. + if ((Length(AAltTerm) = 0) and (Result = '.')) or (Result = AAltTerm) then begin + Break; + end else if Length(Result) <> 0 then begin + AMsg.Headers.Append(Result); + end; + until False; + AMsg.ProcessHeaders; +end; + +function TIdIMAP4.Retrieve(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; +begin + Result := InternalRetrieve(AMsgNum, False, False, AMsg); +end; + +//Retrieves a whole message "raw" and saves it to file, while marking it read. +function TIdIMAP4.RetrieveNoDecodeToFile(const AMsgNum: UInt32; ADestFile: string): Boolean; +var + LMsg: TIdMessage; +begin + Result := False; + LMsg := TIdMessage.Create(nil); + try + LMsg.NoDecode := True; + LMsg.NoEncode := True; + if InternalRetrieve(AMsgNum, False, False, LMsg) then begin + {RLebeau 12/09/2012: NOT currently using the same workaround here that + is being used in AppendMsg() to avoid SMTP dot transparent output from + TIdMessage.SaveToStream(). The reason for this is because I don't + know how this method is being used and I don't want to break anything + that may be depending on that transparent output being generated...} + LMsg.SaveToFile(ADestFile); + + {TODO: add an optional parameter to specify whether dot transparency + should be used or not, and then pass that to SaveToFile(). Or better, + just deprecate this method and implement a replacement that downloads + the message directly to the file without dot transparency, since it + has no meaning in IMAP. InternalRetrieve() uses an internal stream + anyway to receive the data, so let's just cut out TIdMessage here...} + + Result := True; + end; + finally + FreeAndNil(LMsg); + end; +end; + +//Retrieves a whole message "raw" and saves it to file +function TIdIMAP4.RetrieveNoDecodeToFilePeek(const AMsgNum: UInt32; ADestFile: string): Boolean; +var + LMsg: TIdMessage; +begin + Result := False; + LMsg := TIdMessage.Create(nil); + try + LMsg.NoDecode := True; + LMsg.NoEncode := True; + if InternalRetrieve(AMsgNum, False, True, LMsg) then begin + {RLebeau 12/09/2012: NOT currently using the same workaround here that + is being used in AppendMsg() to avoid SMTP dot transparent output from + TIdMessage.SaveToStream(). The reason for this is because I don't + know how this method is being used and I don't want to break anything + that may be depending on that transparent output being generated...} + LMsg.SaveToFile(ADestFile); + + {TODO: add an optional parameter to specify whether dot transparency + should be used or not, and then pass that to SaveToFile(). Or better, + just deprecate this method and implement a replacement that downloads + the message directly to the file without dot transparency, since it + has no meaning in IMAP. InternalRetrieve() uses an internal stream + anyway to receive the data, so let's just cut out TIdMessage here...} + + Result := True; + end; + finally + FreeAndNil(LMsg); + end; +end; + +//Retrieves a whole message "raw" and saves it to file, while marking it read. +function TIdIMAP4.RetrieveNoDecodeToStream(const AMsgNum: UInt32; AStream: TStream): Boolean; +var + LMsg: TIdMessage; +begin + Result := False; + LMsg := TIdMessage.Create(nil); + try + LMsg.NoDecode := True; + LMsg.NoEncode := True; + if InternalRetrieve(AMsgNum, False, False, LMsg) then begin + {RLebeau 12/09/2012: NOT currently using the same workaround here that + is being used in AppendMsg() to avoid SMTP dot transparent output from + TIdMessage.SaveToStream(). The reason for this is because I don't + know how this method is being used and I don't want to break anything + that may be depending on that transparent output being generated...} + LMsg.SaveToStream(AStream); + + {TODO: add an optional parameter to specify whether dot transparency + should be used or not, and then pass that to SaveToStream(). Or better, + just deprecate this method and implement a replacement that downloads + the message directly to the file without dot transparency, since it + has no meaning in IMAP. InternalRetrieve() uses an internal stream + anyway to receive the data, so let's just cut out TIdMessage here...} + + Result := True; + end; + finally + FreeAndNil(LMsg); + end; +end; + +//Retrieves a whole message "raw" and saves it to file +function TIdIMAP4.RetrieveNoDecodeToStreamPeek(const AMsgNum: UInt32; AStream: TStream): Boolean; +var + LMsg: TIdMessage; +begin + Result := False; + LMsg := TIdMessage.Create(nil); + try + LMsg.NoDecode := True; + LMsg.NoEncode := True; + if InternalRetrieve(AMsgNum, False, True, LMsg) then begin + {RLebeau 12/09/2012: NOT currently using the same workaround here that + is being used in AppendMsg() to avoid SMTP dot transparent output from + TIdMessage.SaveToStream(). The reason for this is because I don't + know how this method is being used and I don't want to break anything + that may be depending on that transparent output being generated...} + LMsg.SaveToStream(AStream); + + {TODO: add an optional parameter to specify whether dot transparency + should be used or not, and then pass that to SaveToStream(). Or better, + just deprecate this method and implement a replacement that downloads + the message directly to the file without dot transparency, since it + has no meaning in IMAP. InternalRetrieve() uses an internal stream + anyway to receive the data, so let's just cut out TIdMessage here...} + + Result := True; + end; + finally + FreeAndNil(LMsg); + end; +end; + +function TIdIMAP4.RetrievePeek(const AMsgNum: UInt32; AMsg: TIdMessage): Boolean; +begin + Result := InternalRetrieve(AMsgNum, False, True, AMsg); +end; + +function TIdIMAP4.UIDRetrieve(const AMsgUID: String; AMsg: TIdMessage): Boolean; +begin + Result := InternalRetrieve(UIDToUInt32(AMsgUID), True, False, AMsg); +end; + +//Retrieves a whole message "raw" and saves it to file, while marking it read. +function TIdIMAP4.UIDRetrieveNoDecodeToFile(const AMsgUID: String; ADestFile: string): Boolean; +var + LMsg: TIdMessage; +begin + Result := False; + LMsg := TIdMessage.Create(nil); + try + LMsg.NoDecode := True; + LMsg.NoEncode := True; + if InternalRetrieve(UIDToUInt32(AMsgUID), True, False, LMsg) then begin + {RLebeau 12/09/2012: NOT currently using the same workaround here that + is being used in AppendMsg() to avoid SMTP dot transparent output from + TIdMessage.SaveToStream(). The reason for this is because I don't + know how this method is being used and I don't want to break anything + that may be depending on that transparent output being generated...} + LMsg.SaveToFile(ADestFile); + + {TODO: add an optional parameter to specify whether dot transparency + should be used or not, and then pass that to SaveToFile(). Or better, + just deprecate this method and implement a replacement that downloads + the message directly to the file without dot transparency, since it + has no meaning in IMAP. InternalRetrieve() uses an internal stream + anyway to receive the data, so let's just cut out TIdMessage here...} + + Result := True; + end; + finally + FreeAndNil(LMsg); + end; +end; + +//Retrieves a whole message "raw" and saves it to file. +function TIdIMAP4.UIDRetrieveNoDecodeToFilePeek(const AMsgUID: String; ADestFile: string): Boolean; +var + LMsg: TIdMessage; +begin + Result := False; + LMsg := TIdMessage.Create(nil); + try + LMsg.NoDecode := True; + LMsg.NoEncode := True; + if InternalRetrieve(UIDToUInt32(AMsgUID), True, True, LMsg) then begin + {RLebeau 12/09/2012: NOT currently using the same workaround here that + is being used in AppendMsg() to avoid SMTP dot transparent output from + TIdMessage.SaveToStream(). The reason for this is because I don't + know how this method is being used and I don't want to break anything + that may be depending on that transparent output being generated...} + LMsg.SaveToFile(ADestFile); + + {TODO: add an optional parameter to specify whether dot transparency + should be used or not, and then pass that to SaveToFile(). Or better, + just deprecate this method and implement a replacement that downloads + the message directly to the file without dot transparency, since it + has no meaning in IMAP. InternalRetrieve() uses an internal stream + anyway to receive the data, so let's just cut out TIdMessage here...} + + Result := True; + end; + finally + FreeAndNil(LMsg); + end; +end; + +//Retrieves a whole message "raw" and saves it to file, while marking it read. +function TIdIMAP4.UIDRetrieveNoDecodeToStream(const AMsgUID: String; AStream: TStream): Boolean; +var + LMsg: TIdMessage; +begin + Result := False; + LMsg := TIdMessage.Create(nil); + try + LMsg.NoDecode := True; + LMsg.NoEncode := True; + if InternalRetrieve(UIDToUInt32(AMsgUID), True, False, LMsg) then begin + {RLebeau 12/09/2012: NOT currently using the same workaround here that + is being used in AppendMsg() to avoid SMTP dot transparent output from + TIdMessage.SaveToStream(). The reason for this is because I don't + know how this method is being used and I don't want to break anything + that may be depending on that transparent output being generated...} + LMsg.SaveToStream(AStream); + + {TODO: add an optional parameter to specify whether dot transparency + should be used or not, and then pass that to SaveToStream(). Or better, + just deprecate this method and implement a replacement that downloads + the message directly to the file without dot transparency, since it + has no meaning in IMAP. InternalRetrieve() uses an internal stream + anyway to receive the data, so let's just cut out TIdMessage here...} + + Result := True; + end; + finally + FreeAndNil(LMsg); + end; +end; + +//Retrieves a whole message "raw" and saves it to file. +function TIdIMAP4.UIDRetrieveNoDecodeToStreamPeek(const AMsgUID: String; AStream: TStream): Boolean; +var + LMsg: TIdMessage; +begin + Result := False; + LMsg := TIdMessage.Create(nil); + try + LMsg.NoDecode := True; + LMsg.NoEncode := True; + if InternalRetrieve(UIDToUInt32(AMsgUID), True, True, LMsg) then begin + {RLebeau 12/09/2012: NOT currently using the same workaround here that + is being used in AppendMsg() to avoid SMTP dot transparent output from + TIdMessage.SaveToStream(). The reason for this is because I don't + know how this method is being used and I don't want to break anything + that may be depending on that transparent output being generated...} + LMsg.SaveToStream(AStream); + + {TODO: add an optional parameter to specify whether dot transparency + should be used or not, and then pass that to SaveToStream(). Or better, + just deprecate this method and implement a replacement that downloads + the message directly to the file without dot transparency, since it + has no meaning in IMAP. InternalRetrieve() uses an internal stream + anyway to receive the data, so let's just cut out TIdMessage here...} + + Result := True; + end; + finally + FreeAndNil(LMsg); + end; +end; + +function TIdIMAP4.UIDRetrievePeek(const AMsgUID: String; AMsg: TIdMessage): Boolean; +begin + Result := InternalRetrieve(UIDToUInt32(AMsgUID), True, True, AMsg); +end; + +function TIdIMAP4.InternalRetrieve(const AMsgNum: UInt32; AUseUID: Boolean; AUsePeek: Boolean; AMsg: TIdMessage): Boolean; +var + LStr: String; + LCmd: string; + LDestStream: TStream; + LHelper: TIdIMAP4WorkHelper; +begin + Result := False; + IsNumberValid(AMsgNum); + CheckConnectionState(csSelected); + LCmd := ''; + if AUseUID then begin + LCmd := LCmd + IMAP4Commands[cmdUID] + ' '; {Do not Localize} + end; + LCmd := LCmd + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' ('; {Do not Localize} + if AUsePeek then begin + LCmd := LCmd + IMAP4FetchDataItem[fdBodyPeek]; {Do not Localize} + end else begin + LCmd := LCmd + IMAP4FetchDataItem[fdRFC822]; {Do not Localize} + end; + LCmd := LCmd + ')'; {Do not Localize} + + SendCmd(NewCmdCounter, LCmd, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], True, False); + if LastCmdResult.Code = IMAP_OK then begin + {CC3: Catch "Connection reset by peer"...} + try + //Leave 3rd param as [] because ParseLastCmdResult can get a number of odd + //replies ( variants on Body[] )... + if (LastCmdResult.Text.Count < 1) or + (not ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [])) then + begin + Exit; + end; + {CC8: Retrieve via byte count instead of looking for terminator, + which was impossible to get working with all the different IMAP + servers because some left the terminator (LExpectedResponse) at + the end of a message line, so you could not decide if it was + part of the message or the terminator.} + AMsg.Clear; + if FLineStruct.ByteCount > 0 then begin + {Use a temporary memory block to suck the message into...} + // TODO: use TIdTCPStream instead and let TIdIOHandlerStreamMsg below read + // from this IOHandler directly so we don't have to waste memory reading + // potentially large messages... + LDestStream := TMemoryStream.Create; + try + LHelper := TIdIMAP4WorkHelper.Create(Self); + try + IOHandler.ReadStream(LDestStream, FLineStruct.ByteCount); //ReadStream uses OnWork, most other methods dont + finally + FreeAndNil(LHelper); + end; + + {Feed stream into the standard message parser...} + LDestStream.Position := 0; + + {RLebeau 12/09/2012: this is a workaround to a design limitation in + TIdMessage.LoadFromStream(). It assumes the stream data is always + in an escaped format using SMTP dot transparency, but that is not + the case in IMAP! Until this design is corrected, we have to use a + workaround for now. This logic is copied from TIdMessage.LoadFromStream() + and slightly tweaked...} + + //AMsg.LoadFromStream(LDestStream); + {$IFDEF HAS_CLASS_HELPER} + AMsg.LoadFromStream(LDestStream, False, False); + {$ELSE} + TIdMessageHelper_LoadFromStream(AMsg, LDestStream, False, False); + {$ENDIF} + finally + FreeAndNil(LDestStream); + end; + end; + LStr := IOHandler.ReadLnWait; {Remove trailing line after the message, probably a ')' } + ParseLastCmdResultButAppendInfo(LStr); //There may be a UID or FLAGS in this + if GetInternalResponse(LastCmdCounter, [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]], False) = IMAP_OK then begin + AMsg.UID := FLineStruct.UID; + if (AMsg.UID = '') and AUseUID then begin + AMsg.UID := IntToStr(Int64(AMsgNum)); + end; + AMsg.Flags := FLineStruct.Flags; + Result := True; + end; + except + on E: EIdSocketError do begin + if ((E.LastError = Id_WSAECONNABORTED) or (E.LastError = Id_WSAECONNRESET)) then begin + FConnectionState := csUnexpectedlyDisconnected; + end; + raise; + end; + end; + end; +end; + +function TIdIMAP4.RetrieveAllHeaders(AMsgList: TIdMessageCollection): Boolean; +begin + Result := InternalRetrieveHeaders(AMsgList, -1); +end; + +function TIdIMAP4.RetrieveFirstHeaders(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; +begin + Result := InternalRetrieveHeaders(AMsgList, ACount); +end; + +function TIdIMAP4.InternalRetrieveHeaders(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; +var + LMsgItem : TIdMessageItem; + Ln : Integer; +begin + {CC2: This may get a response of "OK completed" if there are no messages} + CheckConnectionState(csSelected); + Result := False; + if AMsgList <> nil then begin + if (ACount < 0) or (ACount > FMailBox.TotalMsgs) then begin + ACount := FMailBox.TotalMsgs; + end; + // TODO: can this be accomplished using a single FETCH, similar to RetrieveAllEnvelopes()? + for Ln := 1 to ACount do begin + LMsgItem := AMsgList.Add; + if not RetrieveHeader(Ln, LMsgItem.Msg) then begin + Exit; + end; + end; + Result := True; + end; +end; + +function TIdIMAP4.RetrieveAllMsgs(AMsgList: TIdMessageCollection): Boolean; +begin + Result := InternalRetrieveMsgs(AMsgList, -1); +end; + +function TIdIMAP4.RetrieveFirstMsgs(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; +begin + Result := InternalRetrieveMsgs(AMsgList, ACount); +end; + +function TIdIMAP4.InternalRetrieveMsgs(AMsgList: TIdMessageCollection; ACount: Integer): Boolean; +var + LMsgItem : TIdMessageItem; + Ln : Integer; +begin + {CC2: This may get a response of "OK completed" if there are no messages} + CheckConnectionState(csSelected); + Result := False; + if AMsgList <> nil then begin + if (ACount < 0) or (ACount > FMailBox.TotalMsgs) then begin + ACount := FMailBox.TotalMsgs; + end; + // TODO: can this be accomplished using a single FETCH, similar to RetrieveAllEnvelopes()? + for Ln := 1 to ACount do begin + LMsgItem := AMsgList.Add; + if not Retrieve(Ln, LMsgItem.Msg) then begin + Exit; + end; + end; + Result := True; + end; +end; + +function TIdIMAP4.DeleteMsgs(const AMsgNumList: array of UInt32): Boolean; +begin + Result := StoreFlags(AMsgNumList, sdAdd, [mfDeleted]); +end; + +function TIdIMAP4.UIDDeleteMsg(const AMsgUID: String): Boolean; +begin + Result := UIDStoreFlags(AMsgUID, sdAdd, [mfDeleted]); +end; + +function TIdIMAP4.UIDDeleteMsgs(const AMsgUIDList: array of String): Boolean; +begin + Result := UIDStoreFlags(AMsgUIDList, sdAdd, [mfDeleted]); +end; + +function TIdIMAP4.RetrieveMailBoxSize: Int64; +var + Ln : Integer; +begin + Result := -1; + CheckConnectionState(csSelected); + {CC2: This should not be checking FMailBox.TotalMsgs because the server may + have added messages to the mailbox unknown to us, and we are going to ask the + server anyway (if it's empty, we will return 0 anyway} + SendCmd(NewCmdCounter, + IMAP4Commands[cmdFetch] + ' 1:*' + ' (' + IMAP4FetchDataItem[fdRFC822Size] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch]]); + if LastCmdResult.Code = IMAP_OK then begin + Result := 0; + for Ln := 0 to FMailBox.TotalMsgs - 1 do begin + if ParseLastCmdResult(LastCmdResult.Text[Ln], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdRFC822Size]]) then begin + Result := Result + IndyStrToInt64( FLineStruct.IMAPValue ); + end else begin + {CC2: Return -1, not 0, if we cannot parse the result...} + Result := -1; + Exit; + end; + end; + end; +end; + +function TIdIMAP4.UIDRetrieveMailBoxSize: Int64; +var + Ln : Integer; +begin + Result := -1; + CheckConnectionState(csSelected); + {CC2: This should not be checking FMailBox.TotalMsgs because the server may + have added messages to the mailbox unknown to us, and we are going to ask the + server anyway (if it's empty, we will return 0 anyway} + SendCmd(NewCmdCounter, + IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' 1:*' + ' (' + IMAP4FetchDataItem[fdRFC822Size] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]]); + if LastCmdResult.Code = IMAP_OK then begin + Result := 0; + for Ln := 0 to FMailBox.TotalMsgs - 1 do begin + if ParseLastCmdResult(LastCmdResult.Text[Ln], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdRFC822Size]]) then begin + Result := Result + IndyStrToInt64(FLineStruct.IMAPValue); + end else begin + {CC2: Return -1, not 0, if we cannot parse the result...} + Result := -1; + Break; + end; + end; + end; +end; + +function TIdIMAP4.RetrieveMsgSize(const AMsgNum: UInt32): Int64; +begin + Result := -1; + IsNumberValid(AMsgNum); + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdRFC822Size] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch]]); + if LastCmdResult.Code = IMAP_OK then begin + if (LastCmdResult.Text.Count > 0) and + ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdRFC822Size]]) then begin + Result := IndyStrToInt64(FLineStruct.IMAPValue); + end; + end; +end; + +function TIdIMAP4.UIDRetrieveMsgSize(const AMsgUID: String): Int64; +begin + Result := -1; + IsUIDValid(AMsgUID); + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + IMAP4FetchDataItem[fdRFC822Size] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]]); + if LastCmdResult.Code = IMAP_OK then begin + if (LastCmdResult.Text.Count > 0) and + ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdRFC822Size]]) then begin + Result := IndyStrToInt64(FLineStruct.IMAPValue); + end; + end; +end; + +function TIdIMAP4.CheckMsgSeen(const AMsgNum: UInt32): Boolean; +begin + Result := False; + IsNumberValid(AMsgNum); + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdFlags] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch]]); + if LastCmdResult.Code = IMAP_OK then begin + if (LastCmdResult.Text.Count > 0) and + ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdFlags]]) then + begin + if mfSeen in FLineStruct.Flags then begin + Result := True; + end; + end; + end; +end; + +function TIdIMAP4.UIDCheckMsgSeen(const AMsgUID: String): Boolean; +begin + {Default to unseen, so if get no flags back (i.e. no \Seen flag) + we return False (i.e. we return it is unseen) + Some servers return nothing at all if no flags set (the better ones return an empty set).} + Result := False; + IsUIDValid(AMsgUID); + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + IMAP4FetchDataItem[fdFlags] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]]); + if LastCmdResult.Code = IMAP_OK then begin + if (LastCmdResult.Text.Count > 0) and + ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdFlags]]) then + begin + if mfSeen in FLineStruct.Flags then begin + Result := True; + end; + end; + end; +end; + +function TIdIMAP4.RetrieveFlags(const AMsgNum: UInt32; var AFlags: {Pointer}TIdMessageFlagsSet): Boolean; +begin + Result := False; + {CC: Empty set to avoid returning results from a previous call if call fails} + AFlags := []; + IsNumberValid(AMsgNum); + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + IMAP4FetchDataItem[fdFlags] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch]]); + if LastCmdResult.Code = IMAP_OK then begin + if (LastCmdResult.Text.Count > 0) and + ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdFlags]]) then + begin + AFlags := FLineStruct.Flags; + Result := True; + end; + end; +end; + +function TIdIMAP4.UIDRetrieveFlags(const AMsgUID: String; var AFlags: TIdMessageFlagsSet): Boolean; +begin + Result := False; + {BUG FIX: Empty set to avoid returning results from a previous call if call fails} + AFlags := []; + IsUIDValid(AMsgUID); + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + IMAP4FetchDataItem[fdFlags] + ')', {Do not Localize} + [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]]); + if LastCmdResult.Code = IMAP_OK then begin + if (LastCmdResult.Text.Count > 0) and + ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [IMAP4FetchDataItem[fdFlags]]) then + begin + AFlags := FLineStruct.Flags; + Result := True; + end; + end; +end; + +function TIdIMAP4.RetrieveValue(const AMsgNum: UInt32; const AField: String; var AValue: String): Boolean; +begin + Result := False; + {CC: Empty string to avoid returning results from a previous call if call fails} + AValue := ''; + IsNumberValid(AMsgNum); + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdFetch] + ' ' + IntToStr(Int64(AMsgNum)) + ' (' + AField + ')', {Do not Localize} + [IMAP4Commands[cmdFetch]]); + if LastCmdResult.Code = IMAP_OK then begin + if (LastCmdResult.Text.Count > 0) and + ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [AField]) then + begin + case PosInStrArray(AField, ['UID', 'FLAGS', 'X-GM-MSGID', 'X-GM-THRID', 'X-GM-LABELS'], False) of {Do not Localize} + 0: AValue := FLineStruct.UID; + 1: AValue := FLineStruct.FlagsStr; + 2: AValue := FLineStruct.GmailMsgID; + 3: AValue := FLineStruct.GmailThreadID; + 4: AValue := FLineStruct.GmailLabels; + else + AValue := FLineStruct.IMAPValue; + end; + Result := True; + end; + end; +end; + +function TIdIMAP4.UIDRetrieveValue(const AMsgUID: String; const AField: String; var AValue: String): Boolean; +begin + Result := False; + {CC: Empty string to avoid returning results from a previous call if call fails} + AValue := ''; + IsUIDValid(AMsgUID); + CheckConnectionState(csSelected); + SendCmd(NewCmdCounter, + IMAP4Commands[cmdUID] + ' ' + IMAP4Commands[cmdFetch] + ' ' + AMsgUID + ' (' + AField + ')', {Do not Localize} + [IMAP4Commands[cmdFetch], IMAP4Commands[cmdUID]]); + if LastCmdResult.Code = IMAP_OK then begin + if (LastCmdResult.Text.Count > 0) and + ParseLastCmdResult(LastCmdResult.Text[0], IMAP4Commands[cmdFetch], [AField]) then + begin + case PosInStrArray(AField, ['UID', 'FLAGS', 'X-GM-MSGID', 'X-GM-THRID', 'X-GM-LABELS'], False) of {Do not Localize} + 0: AValue := FLineStruct.UID; + 1: AValue := FLineStruct.FlagsStr; + 2: AValue := FLineStruct.GmailMsgID; + 3: AValue := FLineStruct.GmailThreadID; + 4: AValue := FLineStruct.GmailLabels; + else + AValue := FLineStruct.IMAPValue; + end; + Result := True; + end; + end; +end; + +function TIdIMAP4.GetConnectionStateName: String; +begin + case FConnectionState of + csAny : Result := RSIMAP4ConnectionStateAny; + csNonAuthenticated : Result := RSIMAP4ConnectionStateNonAuthenticated; + csAuthenticated : Result := RSIMAP4ConnectionStateAuthenticated; + csSelected : Result := RSIMAP4ConnectionStateSelected; + csUnexpectedlyDisconnected : Result := RSIMAP4ConnectionStateUnexpectedlyDisconnected; + end; +end; + +{ TIdIMAP4 Commands } + +{ Parser Functions... } + +{This recursively parses down. It gets either a line like: + + "text" "plain" ("charset" "ISO-8859-1") NIL NIL "7bit" 40 1 NIL NIL NIL + + which it parses into AThisImapPart, and we are done (at the end of the + recursive calls), or a line like: + + ("text" "plain"...NIL)("text" "html"...NIL) "alternative" ("boundary" "----bdry") NIL NIL + + when we need to add "alternative" and the boundary to this part, but recurse + down for the 1st two parts. } + +procedure TIdIMAP4.ParseImapPart(ABodyStructure: string; + AImapParts: TIdImapMessageParts; AThisImapPart: TIdImapMessagePart; AParentImapPart: TIdImapMessagePart; //ImapPart version + APartNumber: integer); +var + LNextImapPart: TIdImapMessagePart; + LSubParts: TStringList; + LPartNumber: integer; +begin + ABodyStructure := Trim(ABodyStructure); + AThisImapPart.FUnparsedEntry := ABodyStructure; + if ABodyStructure[1] <> '(' then begin {Do not Localize} + //We are at the bottom. Parse the low-level '"text" "plain"...' into this part. + ParseBodyStructurePart(ABodyStructure, nil, AThisImapPart); + if AParentImapPart = nil then begin + //This is the top-level part, and it is "text" "plain" etc, so it is not MIME... + AThisImapPart.Encoding := mePlainText; + AThisImapPart.ImapPartNumber := '1'; {Do not Localize} + AThisImapPart.ParentPart := -1; + end else begin + AThisImapPart.Encoding := meMIME; + AThisImapPart.ImapPartNumber := AParentImapPart.ImapPartNumber+'.'+IntToStr(APartNumber); {Do not Localize} + //If we are the first level down in MIME, the parent part was '', so trim... + if AThisImapPart.ImapPartNumber[1] = '.' then begin {Do not Localize} + AThisImapPart.ImapPartNumber := Copy(AThisImapPart.ImapPartNumber, 2, MaxInt); + end; + AThisImapPart.ParentPart := AParentImapPart.Index; + end; + end else begin + AThisImapPart.Encoding := meMIME; + if AParentImapPart = nil then begin + AThisImapPart.ImapPartNumber := ''; + AThisImapPart.ParentPart := -1; + end else begin + AThisImapPart.ImapPartNumber := AParentImapPart.ImapPartNumber+'.'+IntToStr(APartNumber); {Do not Localize} + //If we are the first level down in MIME, the parent part was '', so trim... + if AThisImapPart.ImapPartNumber[1] = '.' then begin {Do not Localize} + AThisImapPart.ImapPartNumber := Copy(AThisImapPart.ImapPartNumber, 2, MaxInt); + end; + AThisImapPart.ParentPart := AParentImapPart.Index; + end; + LSubParts := TStringList.Create; + try + ParseIntoBrackettedQuotedAndUnquotedParts(ABodyStructure, LSubParts, True); + LPartNumber := 1; + while (LSubParts.Count > 0) and (LSubParts[0] <> '') and (LSubParts[0][1] = '(') do begin {Do not Localize} + LNextImapPart := AImapParts.Add; + ParseImapPart(Copy(LSubParts[0], 2, Length(LSubParts[0])-2), AImapParts, LNextImapPart, AThisImapPart, LPartNumber); + LSubParts.Delete(0); + Inc(LPartNumber); + end; + if LSubParts.Count > 0 then begin + //LSubParts now (only) holds the params for this part... + AThisImapPart.FBodyType := LowerCase(GetNextQuotedParam(LSubParts[0], True)); //mixed, alternative + end else begin + AThisImapPart.FBodyType := ''; + end; + finally + FreeAndNil(LSubParts); + end; + end; +end; + +{ WARNING: Not used by writer, may have bugs. + + Version of ParseImapPart except using TIdMessageParts. + Added for compatibility with TIdMessage.MessageParts, + but does not have enough functionality for many IMAP functions. } + +procedure TIdIMAP4.ParseMessagePart(ABodyStructure: string; + AMessageParts: TIdMessageParts; AThisMessagePart: TIdMessagePart; AParentMessagePart: TIdMessagePart; //MessageParts version + APartNumber: integer); +var + LNextMessagePart: TIdMessagePart; + LSubParts: TStringList; + LPartNumber: integer; +begin + ABodyStructure := Trim(ABodyStructure); + if ABodyStructure[1] <> '(' then begin {Do not Localize} + //We are at the bottom. Parse this into this part. + ParseBodyStructurePart(ABodyStructure, AThisMessagePart, nil); + if AParentMessagePart = nil then begin + //This is the top-level part, and it is "text" "plain" etc, so it is not MIME... + AThisMessagePart.ParentPart := -1; + end else begin + AThisMessagePart.ParentPart := AParentMessagePart.Index; + end; + end else begin + LSubParts := TStringList.Create; + try + ParseIntoBrackettedQuotedAndUnquotedParts(ABodyStructure, LSubParts, True); + LPartNumber := 1; + while (LSubParts.Count > 0) and (LSubParts[0] <> '') and (LSubParts[0][1] = '(') do begin {Do not Localize} + LNextMessagePart := TIdAttachmentMemory.Create(AMessageParts); + ParseMessagePart(Copy(LSubParts[0], 2, Length(LSubParts[0])-2), AMessageParts, LNextMessagePart, AThisMessagePart, LPartNumber); + LSubParts.Delete(0); + Inc(LPartNumber); + end; + //LSubParts now (only) holds the params for this part... + if AParentMessagePart = nil then begin + AThisMessagePart.ParentPart := -1; + end else begin + AThisMessagePart.ParentPart := AParentMessagePart.Index; + end; + finally + FreeAndNil(LSubParts); + end; + end; +end; + +{CC2: Function added to support individual part retreival} +{ + If it's a single-part message, it won't be enclosed in brackets - it will be: + "body type": "TEXT", "application", "image", "MESSAGE" (followed by subtype RFC822 for envelopes, ignore) + "body subtype": "PLAIN", "octet-stream", "tiff", "html" + "body parameter parenthesized list": bracketted list of pairs ("CHARSET" "US-ASCII" "NAME" "cc.tif" "format" "flowed"), ("charset" "ISO-8859-1") + "body id": NIL, 986767766767887@fg.com + "body description": NIL, "Compiler diff" + "body encoding": "7bit" "8bit" "binary" (NO encoding used with these), "quoted-printable" "base64" "ietf-token" "x-token" + "body size" 2279 + "body lines" 48 (only present for some types, only those with "body type=text" and "body subtype=plain" that I found, if not present it WONT be a NIL, it just won't be there! However, it won't be needed) + NIL + ("inline" ("filename" "classbd.h")), ("attachment" ("filename" "DEGDAY.WB3")) + NIL + Example: + * 4 FETCH (BODYSTRUCTURE ("text" "plain" ("charset" "ISO-8859-1") NIL NIL "7bit" 40 1 NIL NIL NIL)) + --------------------------------------------------------------------------- + For most multi-part messages, each part will be bracketted: + ( (part 1 stuff) (part 2 stuff) "mixed" (boundary) NIL NIL ) + Example: + * 1 FETCH (BODYSTRUCTURE (("text" "plain" ("charset" "us-ascii" "format" "flowed") + NIL NIL "7bit" 52 3 NIL NIL NIL)("text" "plain" ("name" "tnkin.txt") NIL NIL + "7bit" 28421 203 NIL ("inline" ("filename" "tnkin.txt")) NIL) "mixed" + ("boundary" "------------070105030104060407030601") NIL NIL)) + --------------------------------------------------------------------------- + Some multiparts are bracketted again. This is the "alternative" encoding, + part 1 has two parts, a plain-text part and a html part: + ( ( (part 1a stuff) (part 1b stuff) "alternative" (boundary) NIL NIL ) (part 2 stuff) "mixed" (boundary) NIL NIL ) + 1 2 2 1 + Example: + * 50 FETCH (BODYSTRUCTURE ((("text" "plain" ("charset" "ISO-8859-1") NIL NIL + "quoted-printable" 415 12 NIL NIL NIL)("text" "html" ("charset" "ISO-8859-1") + NIL NIL "quoted-printable" 1034 25 NIL NIL NIL) "alternative" ("boundary" + "----=_NextPart_001_0027_01C33A37.33CFE220") NIL NIL)("application" "x-zip-compressed" + ("name" "IdIMAP4.zip") NIL NIL "base64" 20572 NIL ("attachment" ("filename" + "IdIMAP4.zip")) NIL) "mixed" ("boundary" "----=_NextPart_000_0026_01C33A37.33CFE220") + NIL NIL) UID 62) +} +procedure TIdIMAP4.ParseBodyStructureResult(ABodyStructure: string; ATheParts: TIdMessageParts; AImapParts: TIdImapMessageParts); +begin + {CC7: New code uses a different parsing method that allows for multisection parts.} + if AImapParts <> nil then begin //Just sort out the ImapParts version for now + ParseImapPart(ABodyStructure, AImapParts, AImapParts.Add, nil, -1); + end; + if ATheParts <> nil then begin + ParseMessagePart(ABodyStructure, ATheParts, TIdAttachmentMemory.Create(ATheParts), nil, -1); + end; +end; + +procedure TIdIMAP4.ParseTheLine(ALine: string; APartsList: TStrings); +var + LTempList: TStringList; + LN: integer; + LStr, LWord: string; +begin + {Parse it and see what we get...} + LTempList := TStringList.Create; + try + ParseIntoParts(ALine, LTempList); + {Copy any parts from LTempList into the list of parts LPartsList...} + for LN := 0 to LTempList.Count-1 do begin + LStr := LTempList.Strings[LN]; + LWord := LowerCase(GetNextWord(LStr)); + if CharEquals(LStr, 1, '(') or (PosInStrArray(LWord, ['"text"', '"image"', '"application"'], False) <> -1) then begin {Do not Localize} + APartsList.Add(LStr); + end; + end; + finally + FreeAndNil(LTempList); + end; +end; + +procedure TIdIMAP4.ParseBodyStructurePart(APartString: string; AThePart: TIdMessagePart; + AImapPart: TIdImapMessagePart); + {CC3: Function added to support individual part retreival} +var + LParams: TStringList; +// LContentDispositionStuff: string; + LCharSet: String; + LFilename: string; + LDescription: string; + LTemp: string; + LSize: Int64; + LPos: Integer; +begin + {Individual parameters may be strings like "text", NIL, a number, or bracketted pairs like + ("CHARSET" "US-ASCII" "NAME" "cc.tif" "format" "flowed")...} + {There are three common line formats, with differing numbers of parameters: + (a) "TEXT" "HTML" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 2879 69 NIL NIL NIL + (a) "TEXT" "HTML" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 2879 69 NIL NIL + (c) "TEXT" "HTML" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 2879 69 + Note the last one only has 7 parameters, need to watch we don't index past the 7th!} + LParams := TStringList.Create; + try + ParseIntoParts(APartString, LParams); + {Build up strings into same format as used by message decoders...} + {Content Disposition: If present, may be at index 8 or 9...} + {CC8: Altered to allow for case where it may not be present at all (get "List + index out of bounds" error if try to access non-existent LParams[9])...} +// LContentDispositionStuff := ''; {Do not Localize} +// if LParams.Count > 9 then begin {Have an LParams[9]} +// if TextIsSame(LParams[9], 'NIL') then begin {Do not Localize} + {It's NIL at 9, must be at 8...} +// if TextIsSame(LParams[8], 'NIL') then begin {Do not Localize} +// LContentDispositionStuff := LParams[8]; +// end; +// end else begin + {It's not NIL, must be valid...} +// LContentDispositionStuff := LParams[9]; +// end; +// end else if LParams.Count > 8 then begin {Have an LParams[8]} +// if TextIsSame(LParams[8], 'NIL') then begin {Do not Localize} +// LContentDispositionStuff := LParams[8]; +// end; +// end; + + {Find and clean up the filename, if present...} + LFilename := ''; {Do not Localize} + LPos := IndyPos('"NAME"', UpperCase(APartString)); {Do not Localize} + if LPos > 0 then begin + LTemp := Copy(APartString, LPos+7, MaxInt); + LFilename := GetNextQuotedParam(LTemp, False); + end else + begin + LPos := IndyPos('"FILENAME"', UpperCase(APartString)); {Do not Localize} + if LPos > 0 then begin + LTemp := Copy(APartString, LPos+11, MaxInt); + LFilename := GetNextQuotedParam(LTemp, False); + end; + end; + {If the filename starts and ends with double-quotes, remove them...} + if Length(LFilename) > 1 then begin + if TextStartsWith(LFilename, '"') and TextEndsWith(LFilename, '"') then begin {Do not Localize} + LFilename := Copy(LFilename, 2, Length(LFilename)-2); + end; + end; + {CC7: The filename may be encoded, so decode it...} + if Length(LFilename) > 1 then begin + LFilename := DecodeHeader(LFilename); + end; + + LCharSet := ''; + if IndyPos('"CHARSET"', UpperCase(LParams[2])) > 0 then begin {Do not Localize} + LTemp := Copy(LParams[2], IndyPos('"CHARSET" ', UpperCase(LParams[2]))+10, MaxInt); {Do not Localize} + LCharSet := GetNextQuotedParam(LTemp, True); + end; + + LSize := 0; + if (not TextIsSame(LParams[6], 'NIL')) and (Length(LParams[6]) <> 0) then begin + LSize := IndyStrToInt64(LParams[6]); {Do not Localize} + end; + + LDescription := ''; {Do not Localize} + if (LParams.Count > 9) and (not TextIsSame(LParams[9], 'NIL')) then begin {Do not Localize} + LDescription := GetNextQuotedParam(LParams[9], False); + end else if (LParams.Count > 8) and (not TextIsSame(LParams[8], 'NIL')) then begin {Do not Localize} + LDescription := GetNextQuotedParam(LParams[8], False); + end; + + if AThePart <> nil then begin + {Put into the same format as TIdMessage MessageParts...} + AThePart.ContentType := LParams[0]+'/'+LParams[1]+ParseBodyStructureSectionAsEquates(LParams[2]); {Do not Localize} + AThePart.ContentTransfer := LParams[5]; + //Watch out for BinHex4.0, the encoding is inferred from the Content-Type... + if IsHeaderMediaType(AThePart.ContentType, 'application/mac-binhex40') then begin {do not localize} + AThePart.ContentTransfer := 'binhex40'; {do not localize} + end; + AThePart.DisplayName := LFilename; + end; + + if AImapPart <> nil then begin + AImapPart.FBodyType := LParams[0]; + AImapPart.FBodySubType := LParams[1]; + AImapPart.FFileName := LFilename; + AImapPart.FDescription := LDescription; + AImapPart.FCharSet := LCharSet; + AImapPart.FContentTransferEncoding := LParams[5]; + AImapPart.FSize := LSize; + //Watch out for BinHex4.0, the encoding is inferred from the Content-Type... + if ( (TextIsSame(AImapPart.FBodyType, 'application')) {do not localize} + and (TextIsSame(AImapPart.FBodySubType, 'mac-binhex40')) ) then begin {do not localize} + AImapPart.FContentTransferEncoding := 'binhex40'; {do not localize} + end; + end; + finally + FreeAndNil(LParams); + end; +end; + +function ResolveQuotedSpecials(const AParam: string): string; +begin + // Handle quoted_specials, RFC1730 + // \ with other chars than " or \ after, looks illegal in RFC1730, but leave them untouched + // TODO: use StringsReplace() instead + //Result := StringsReplace(AParam, ['\"', '\\'], ['"', '\']); + Result := ReplaceAll(AParam, '\"', '"'); + Result := ReplaceAll(Result, '\\', '\'); +end; + +procedure TIdIMAP4.ParseIntoParts(APartString: string; AParams: TStrings); +var + LInPart: Integer; + LStartPos: Integer; + //don't rename this LParam. That's the same asa windows identifier + LParamater: string; + LBracketLevel: Integer; + Ln: Integer; + LInQuotesInsideBrackets: Boolean; + LInQuotedSpecial: Boolean; +begin + LStartPos := 0; {Stop compiler whining} + LBracketLevel := 0; {Stop compiler whining} + LInQuotesInsideBrackets := False; {Stop compiler whining} + LInQuotedSpecial := False; {Stop compiler whining} + LInPart := 0; {0 is not in a part, 1 is in a quote-delimited part, 2 is in a bracketted parameter-pair list} + for Ln := 1 to Length(APartString) do begin + if (LInPart = 1) or ((LInPart = 2) and LInQuotesInsideBrackets) then begin + if LInQuotedSpecial then begin + LInQuotedSpecial := False; + end + else if APartString[Ln] = '\' then begin {Do not Localize} + LInQuotedSpecial := True; + end + else if APartString[Ln] = '"' then begin {Do not Localize} + if LInPart = 1 then begin + LParamater := Copy(APartString, LStartPos+1, Ln-LStartPos-1); + AParams.Add(ResolveQuotedSpecials(LParamater)); + LInPart := 0; + end else begin + LInQuotesInsideBrackets := False; + end; + end; + end else if LInPart = 2 then begin + //We have to watch out that we don't close this entry on a closing bracket within + //quotes, like ("Blah" "Blah)Blah"), so monitor if we are in quotes within brackets. + if APartString[Ln] = '"' then begin {Do not Localize} + LInQuotesInsideBrackets := True; + LInQuotedSpecial := False; + end + else if APartString[Ln] = '(' then begin {Do not Localize} + Inc(LBracketLevel); + end + else if APartString[Ln] = ')' then begin {Do not Localize} + Dec(LBracketLevel); + if LBracketLevel = 0 then begin + LParamater := Copy(APartString, LStartPos+1, Ln-LStartPos-1); + AParams.Add(ResolveQuotedSpecials(LParamater)); + LInPart := 0; + end; + end; + end else if LInPart = 3 then begin + if APartString[Ln] = 'L' then begin {Do not Localize} + LParamater := Copy(APartString, LStartPos, Ln-LStartPos+1); + AParams.Add(LParamater); + LInPart := 0; + end; + end else if LInPart = 4 then begin + if not IsNumeric(APartString[Ln]) then begin + LParamater := Copy(APartString, LStartPos, Ln-LStartPos); + AParams.Add(LParamater); + LInPart := 0; + end; + end else if APartString[Ln] = '"' then begin {Do not Localize} + {Start of a quoted param like "text"} + LStartPos := Ln; + LInPart := 1; + LInQuotedSpecial := False; + end else if APartString[Ln] = '(' then begin {Do not Localize} + {Start of a set of paired parameter/value strings within brackets, + such as ("charset" "us-ascii"). Note these can be nested (bracket pairs + within bracket pairs) } + LStartPos := Ln; + LInPart := 2; + LBracketLevel := 1; + LInQuotesInsideBrackets := False; + end else if TextIsSame(APartString[Ln], 'N') then begin {Do not Localize} + {Start of a NIL entry} + LStartPos := Ln; + LInPart := 3; + end else if IsNumeric(APartString[Ln]) then begin + {Start of a numeric entry like 12345} + LStartPos := Ln; + LInPart := 4; + end; + end; + {We could be in a numeric entry when we hit the end of the line...} + if LInPart = 4 then begin + LParamater := Copy(APartString, LStartPos, MaxInt); + AParams.Add(LParamater); + end; +end; + +procedure TIdIMAP4.ParseIntoBrackettedQuotedAndUnquotedParts(APartString: string; AParams: TStrings; AKeepBrackets: Boolean); +var + LInPart: Integer; + LStartPos: Integer; + //don't rename this back to LParam, that's a Windows identifier. + LParamater: string; + LBracketLevel: Integer; + Ln: Integer; + LInQuotesInsideBrackets: Boolean; + LInQuotedSpecial: Boolean; +begin + {Break: + * LIST (\UnMarked \AnotherFlag) "/" "Mailbox name" + into: + * + LIST + (\UnMarked \AnotherFlag) + "/" + "Mailbox name" + If AKeepBrackets is false, return '\UnMarked \AnotherFlag' instead of '(\UnMarked \AnotherFlag)' + } + AParams.BeginUpdate; + try + AParams.Clear; + LStartPos := 0; {Stop compiler whining} + LBracketLevel := 0; {Stop compiler whining} + LInQuotesInsideBrackets := False; {Stop compiler whining} + LInQuotedSpecial := False; {Stop compiler whining} + LInPart := 0; {0 is not in a part, 1 is in a quote-delimited part, 2 is in a bracketted part, 3 is a word} + APartString := Trim(APartString); + for Ln := 1 to Length(APartString) do begin + if (LInPart = 1) or ((LInPart = 2) and LInQuotesInsideBrackets) then begin + if LInQuotedSpecial then begin + LInQuotedSpecial := False; + end + else if APartString[Ln] = '\' then begin {Do not Localize} + LInQuotedSpecial := True; + end + else if APartString[Ln] = '"' then begin {Do not Localize} + if LInPart = 1 then begin + LParamater := Copy(APartString, LStartPos+1, Ln-LStartPos-1); + AParams.Add(ResolveQuotedSpecials(LParamater)); + LInPart := 0; + end else begin + LInQuotesInsideBrackets := False; + end; + end; + end else if LInPart = 2 then begin + //We have to watch out that we don't close this entry on a closing bracket within + //quotes, like ("Blah" "Blah)Blah"), so monitor if we are in quotes within brackets. + if APartString[Ln] = '"' then begin {Do not Localize} + LInQuotesInsideBrackets := True; + LInQuotedSpecial := False; + end + else if APartString[Ln] = '(' then begin {Do not Localize} + Inc(LBracketLevel); + end + else if APartString[Ln] = ')' then begin {Do not Localize} + Dec(LBracketLevel); + if LBracketLevel = 0 then begin + if AKeepBrackets then begin + LParamater := Copy(APartString, LStartPos, Ln-LStartPos+1); + end else begin + LParamater := Copy(APartString, LStartPos+1, Ln-LStartPos-1); + end; + AParams.Add(ResolveQuotedSpecials(LParamater)); + LInPart := 0; + end; + end; + end else if LInPart = 3 then begin + if APartString[Ln] = ' ' then begin {Do not Localize} + LParamater := Copy(APartString, LStartPos, Ln-LStartPos); + AParams.Add(LParamater); + LInPart := 0; + end; + end else if APartString[Ln] = '"' then begin {Do not Localize} + {Start of a quoted param like "text"} + LStartPos := Ln; + LInPart := 1; + LInQuotedSpecial := False; + end else if APartString[Ln] = '(' then begin {Do not Localize} + {Start of a set of paired parameter/value strings within brackets, + such as ("charset" "us-ascii"). Note these can be nested (bracket pairs + within bracket pairs) } + LStartPos := Ln; + LInPart := 2; + LBracketLevel := 1; + LInQuotesInsideBrackets := False; + end else if APartString[Ln] <> ' ' then begin {Do not Localize} + {Start of an entry like 12345} + LStartPos := Ln; + LInPart := 3; + end; + end; + {We could be in an entry when we hit the end of the line...} + if LInPart = 3 then begin + LParamater := Copy(APartString, LStartPos, MaxInt); + AParams.Add(LParamater); + end else if LInPart = 2 then begin + if AKeepBrackets then begin + LParamater := Copy(APartString, LStartPos, MaxInt); + end else begin + LParamater := Copy(APartString, LStartPos+1, MaxInt); + end; + if (not AKeepBrackets) and TextEndsWith(LParamater, ')') then begin {Do not Localize} + LParamater := Copy(LParamater, 1, Length(LParamater)-1); + end; + AParams.Add(ResolveQuotedSpecials(LParamater)); + end else if LInPart = 1 then begin + LParamater := Copy(APartString, LStartPos+1, MaxInt); + if TextEndsWith(LParamater, '"') then begin {Do not Localize} + LParamater := Copy(LParamater, 1, Length(LParamater)-1); + end; + AParams.Add(ResolveQuotedSpecials(LParamater)); + end; + finally + AParams.EndUpdate; + end; +end; + +function TIdIMAP4.ParseBodyStructureSectionAsEquates(AParam: string): string; + {Convert: + "Name1" "Value1" "Name2" "Value2" + to: + ; Name1="Value1"; Name2="Value2" + } +var + LParse: TStringList; + LN: integer; +begin + Result := ''; {Do not Localize} + if (Length(AParam) = 0) or TextIsSame(AParam, 'NIL') then begin {Do not Localize} + Exit; + end; + LParse := TStringList.Create; + try + BreakApartParamsInQuotes(AParam, LParse); + if LParse.Count < 2 then begin + Exit; + end; + if ((LParse.Count mod 2) <> 0) then begin + Exit; + end; + for LN := 0 to ((LParse.Count div 2)-1) do begin + Result := Result + '; ' + Copy(LParse[LN*2], 2, Length(LParse[LN*2])-2) + '=' + LParse[(LN*2)+1]; {Do not Localize} + end; + finally + FreeAndNil(LParse); + end; +end; + +function TIdIMAP4.ParseBodyStructureSectionAsEquates2(AParam: string): string; + {Convert: + "Name1" ("Name2" "Value2") + to: + Name1; Name2="Value2" + } +var + LParse: TStringList; + LParams: string; +begin + Result := ''; {Do not Localize} + if (Length(AParam) = 0) or TextIsSame(AParam, 'NIL') then begin {Do not Localize} + Exit; + end; + LParse := TStringList.Create; + try + BreakApart(AParam, ' ', LParse); {Do not Localize} + if LParse.Count < 3 then begin + Exit; + end; + LParams := Copy(AParam, Pos('(', AParam)+1, MaxInt); {Do not Localize} + LParams := Copy(LParams, 1, Length(LParams)-1); + LParams := ParseBodyStructureSectionAsEquates(LParams); + if Length(LParams) = 0 then begin {Do not Localize} + Result := Copy(LParse[0], 2, Length(LParse[0])-2) + LParams; + end; + finally + FreeAndNil(LParse); + end; +end; + +function TIdIMAP4.GetNextWord(AParam: string): string; +var + LPos: integer; +begin + Result := ''; {Do not Localize} + AParam := Trim(AParam); + LPos := Pos(' ', AParam); {Do not Localize} + if LPos = 0 then begin + Exit; + end; + Result := Copy(AParam, 1, LPos-1); +end; + +function TIdIMAP4.GetNextQuotedParam(AParam: string; ARemoveQuotes: Boolean): string; +{If AParam is: +"file name.ext" NIL NIL +then this returns: +"file name.ext" +Note it returns the quotes, UNLESS ARemoveQuotes is True. +Also note that if AParam does NOT start with a quote, it returns the next word. +} +var + LN: integer; + LPos: integer; +begin + Result := ''; + {CCB: Modified code so it did not access past the end of the string if + AParam was not actually in quotes (e.g. the MIME boundary parameter + is only optionally in quotes).} + LN := 1; + {Skip any preceding spaces...} + //TODO: use TrimLeft(AParam) instead + while (LN <= Length(AParam)) and (AParam[LN] = ' ') do begin {Do not Localize} + LN := LN + 1; + end; + if LN > Length(AParam) then begin + Exit; + end; + if AParam[LN] <> '"' then begin {Do not Localize} + {Not actually enclosed in quotes. Must be a single word.} + // TODO: use Fetch(AParam) instead + AParam := Copy(AParam, LN, MaxInt); + LPos := Pos(' ', AParam); {Do not Localize} + if LPos > 0 then begin + {Strip off this word...} + Result := Copy(AParam, 1, LPos-1); + end else begin + {This is the last word on the line, return it all...} + Result := AParam; + end; + end else begin + {It starts with a quote...} + // TODO: use Fetch(AParam, '"') instead + // TODO: do we need to handle escaped characters? + AParam := Copy(AParam, LN, MaxInt); + LN := 2; + while (LN <= Length(AParam)) and (AParam[LN] <> '"') do begin {Do not Localize} + LN := LN + 1; + end; + Result := Copy(AParam, 1, LN); + if ARemoveQuotes then begin + Result := Copy(Result, 2, Length(Result)-2); + end; + end; +end; + +procedure TIdIMAP4.BreakApartParamsInQuotes(const AParam: string; AParsedList: TStrings); +var + Ln : Integer; + LStartPos: Integer; +begin + LStartPos := -1; + AParsedList.BeginUpdate; + try + AParsedList.Clear; + for Ln := 1 to Length(AParam) do begin + if AParam[LN] = '"' then begin {Do not Localize} + if LStartPos > -1 then begin + {The end of a quoted parameter...} + AParsedList.Add(Copy(AParam, LStartPos, LN-LStartPos+1)); + LStartPos := -1; + end else begin + {The start of a quoted parameter...} + LStartPos := Ln; + end; + end; + end; + finally + AParsedList.EndUpdate; + end; +end; + +procedure TIdIMAP4.ParseExpungeResult(AMB: TIdMailBox; ACmdResultDetails: TStrings); +var + Ln, LCnt: Integer; + LSlExpunge : TStringList; +begin + SetLength(AMB.DeletedMsgs, 0); + if ACmdResultDetails.Count > 0 then begin + LSlExpunge := TStringList.Create; + try + // TODO: count the number of EXPUNGE entries and allocate the DeletedMsgs array one time... + LCnt := 0; + try + for Ln := 0 to ACmdResultDetails.Count - 1 do begin + // TODO: maybe use Fetch() instead and get rid of the TStringList altogether? + BreakApart(ACmdResultDetails[Ln], ' ', LSlExpunge); {Do not Localize} + if LSlExpunge.Count > 1 then begin + if TextIsSame(LSlExpunge[1], IMAP4Commands[cmdExpunge]) then begin + SetLength(AMB.DeletedMsgs, LCnt + 1); + AMB.DeletedMsgs[LCnt] := UInt32(IndyStrToInt64(LSlExpunge[0])); + Inc(LCnt); + end; + end; + LSlExpunge.Clear; + end; + finally + SetLength(AMB.DeletedMsgs, LCnt); + end; + finally + FreeAndNil(LSlExpunge); + end; + end; +end; + +procedure TIdIMAP4.ParseMessageFlagString(AFlagsList: String; var AFlags: TIdMessageFlagsSet); + {CC5: Note this only supports the system flags defined in RFC 2060.} +var + LSlFlags : TStringList; + Ln, I : Integer; +begin + AFlags := []; + LSlFlags := TStringList.Create; + try + BreakApart(AFlagsList, ' ', LSlFlags); {Do not Localize} + for Ln := 0 to LSlFlags.Count-1 do begin + I := PosInStrArray( + LSlFlags[Ln], + [MessageFlags[mfAnswered], MessageFlags[mfFlagged], MessageFlags[mfDeleted], MessageFlags[mfDraft], MessageFlags[mfSeen], MessageFlags[mfRecent]], + False); + case I of + 0..5: Include(AFlags, TIdMessageFlags(I)); + end; + end; + finally + FreeAndNil(LSlFlags); + end; +end; + +procedure TIdIMAP4.ParseMailBoxAttributeString(AAttributesList: String; var AAttributes: TIdMailBoxAttributesSet); +var + LSlAttributes : TStringList; + Ln : Integer; + I: Integer; +begin + AAttributes := []; + LSlAttributes := TStringList.Create; + try + BreakApart(AAttributesList, ' ', LSlAttributes); {Do not Localize} + for Ln := 0 to LSlAttributes.Count - 1 do begin + I := PosInStrArray( + LSlAttributes[Ln], + [MailBoxAttributes[maNoinferiors], MailBoxAttributes[maNoselect], MailBoxAttributes[maMarked], MailBoxAttributes[maUnmarked]], + False); + case I of + 0..3: Include(AAttributes, TIdMailBoxAttributes(I)); + end; + end; + finally + FreeAndNil(LSlAttributes); + end; +end; + +procedure TIdIMAP4.ParseSearchResult(AMB: TIdMailBox; ACmdResultDetails: TStrings); +var + Ln, LCnt: Integer; + LSlSearch: TStringList; +begin + SetLength(AMB.SearchResult, 0); + if ACmdResultDetails.Count > 0 then begin + LSlSearch := TStringList.Create; + try + // TODO: maybe use a Fetch() loop instead and get rid of the TStringList altogether? + BreakApart(ACmdResultDetails[0], ' ', LSlSearch); {Do not Localize} + if LSlSearch.Count > 0 then begin + if TextIsSame(LSlSearch[0], IMAP4Commands[cmdSearch]) then begin + SetLength(AMB.SearchResult, LSlSearch.Count - 1); + LCnt := 0; + try + for Ln := 1 to LSlSearch.Count - 1 do + begin + // TODO: for a UID search, store LSlSearch[Ln] as-is without converting it to an Integer... + AMB.SearchResult[LCnt] := UInt32(IndyStrToInt64(LSlSearch[Ln])); + Inc(LCnt); + end; + finally + SetLength(AMB.SearchResult, LCnt); + end; + end; + end; + finally + FreeAndNil(LSlSearch); + end; + end; +end; + +procedure TIdIMAP4.ParseStatusResult(AMB: TIdMailBox; ACmdResultDetails: TStrings); +var + Ln: Integer; + LRespStr : String; + LStatStr: String; + LStatPos: Integer; + LSlStatus : TStringList; +begin + LSlStatus := TStringList.Create; + try + if ACmdResultDetails.Count > 0 then + begin + // TODO: convert server response to uppercase? + LRespStr := Trim(ACmdResultDetails[0]); + LStatPos := Pos(IMAP4Commands[cmdStatus], LRespStr); + if (LStatPos > 0) then + begin + LStatStr := Trim(Copy(LRespStr, + LStatPos+Length(IMAP4Commands[cmdStatus]), Length(LRespStr))); + AMB.Name := Trim(Fetch(LStatStr, '(', True)); {do not localize} + if TextEndsWith(LStatStr, ')') then begin {do not localize} + IdDelete(LStatStr, Length(LStatStr), 1); + end; + BreakApart(LStatStr, ' ', LSlStatus); {do not localize} + // find status data items by name, values are on following line + Ln := LSlStatus.IndexOf(IMAP4StatusDataItem[mdMessages]); + if Ln <> -1 then begin + AMB.TotalMsgs := IndyStrToInt(LSlStatus[Ln + 1]); + end; + Ln := LSlStatus.IndexOf(IMAP4StatusDataItem[mdRecent]); + if Ln <> -1 then begin + AMB.RecentMsgs := IndyStrToInt(LSlStatus[Ln + 1]); + end; + Ln := LSlStatus.IndexOf(IMAP4StatusDataItem[mdUnseen]); + if Ln <> -1 then begin + AMB.UnseenMsgs := IndyStrToInt(LSlStatus[Ln + 1]); + end; + Ln := LSlStatus.IndexOf(IMAP4StatusDataItem[mdUIDNext]); + if Ln <> -1 then begin + AMB.UIDNext := LSlStatus[Ln + 1]; + end; + Ln := LSlStatus.IndexOf(IMAP4StatusDataItem[mdUIDValidity]); + if Ln <> -1 then begin + AMB.UIDValidity := LSlStatus[Ln + 1]; + end; + end; + end; + finally + FreeAndNil(LSlStatus); + end; +end; + +procedure TIdIMAP4.ParseSelectResult(AMB : TIdMailBox; ACmdResultDetails: TStrings); +var + Ln : Integer; + LStr : String; + LFlags: TIdMessageFlagsSet; + LLine: String; + LPos: Integer; +begin + AMB.Clear; + for Ln := 0 to ACmdResultDetails.Count - 1 do begin + LLine := ACmdResultDetails[Ln]; + LPos := Pos(' EXISTS', LLine); {Do not Localize} + if LPos > 0 then begin + AMB.TotalMsgs := IndyStrToInt(Copy(LLine, 1, LPos - 1)); + Continue; + end; + LPos := Pos(' RECENT', LLine); {Do not Localize} + if LPos > 0 then begin + AMB.RecentMsgs := IndyStrToInt(Copy(LLine, 1, LPos - 1)); {Do not Localize} + Continue; + end; + LPos := Pos('[UIDVALIDITY ', LLine); {Do not Localize} + if LPos > 0 then begin + Inc(LPos, 13); + AMB.UIDValidity := Trim(Copy(LLine, LPos, (Integer(PosIdx(']', LLine, LPos)) - LPos))); {Do not Localize} + Continue; + end; + LPos := Pos('[UIDNEXT ', LLine); {Do not Localize} + if LPos > 0 then begin + Inc(LPos, 9); + AMB.UIDNext := Trim(Copy(LLine, LPos, (Integer(PosIdx(']', LLine, LPos)) - LPos))); {Do not Localize} + Continue; + end; + LPos := Pos('[PERMANENTFLAGS ', LLine); {Do not Localize} + if LPos > 0 then begin {Do not Localize} + LPos := PosIdx('(', LLine, LPos + 16) + 1; {Do not Localize} + ParseMessageFlagString(Copy(LLine, LPos, Integer(PosIdx(')', LLine, LPos)) - LPos), LFlags); {Do not Localize} + AMB.ChangeableFlags := LFlags; + Continue; + end; + LPos := Pos('FLAGS ', LLine); {Do not Localize} + if LPos > 0 then begin + LPos := PosIdx('(', LLine, LPos + 6) + 1; {Do not Localize} + ParseMessageFlagString(Copy(LLine, LPos, (Integer(PosIdx(')', LLine, LPos)) - LPos)), LFlags); {Do not Localize} + AMB.Flags := LFlags; + Continue; + end; + LPos := Pos('[UNSEEN ', LLine); {Do not Localize} + if LPos> 0 then begin + Inc(LPos, 8); + AMB.FirstUnseenMsg := UInt32(IndyStrToInt64(Copy(LLine, LPos, (Integer(PosIdx(']', LLine, LPos)) - LPos)))); {Do not Localize} + Continue; + end; + LPos := Pos('[READ-', LLine); {Do not Localize} + if LPos > 0 then begin + Inc(LPos, 6); + LStr := Trim(Copy(LLine, LPos, Integer(PosIdx(']', LLine, LPos)) - LPos)); {Do not Localize} + {CCB: AMB.State ambiguous unless coded response received - default to msReadOnly...} + if TextIsSame(LStr, 'WRITE') then begin {Do not Localize} + AMB.State := msReadWrite; + end else {if TextIsSame(LStr, 'ONLY') then} begin {Do not Localize} + AMB.State := msReadOnly; + end; + Continue; + end; + LPos := Pos('[ALERT]', LLine); {Do not Localize} + if LPos > 0 then begin + LStr := Trim(Copy(LLine, LPos + 7, MaxInt)); + if Length(LStr) <> 0 then begin + DoAlert(LStr); + end; + Continue; + end; + end; +end; + +procedure TIdIMAP4.ParseListResult(AMBList: TStrings; ACmdResultDetails: TStrings); +begin + InternalParseListResult(IMAP4Commands[cmdList], AMBList, ACmdResultDetails); +end; + +procedure TIdIMAP4.InternalParseListResult(ACmd: string; AMBList: TStrings; ACmdResultDetails: TStrings); +var Ln : Integer; + LSlRetrieve : TStringList; + LStr : String; + LWord: string; +begin + AMBList.BeginUpdate; + try + AMBList.Clear; + LSlRetrieve := TStringList.Create; + try + for Ln := 0 to ACmdResultDetails.Count - 1 do begin + LStr := ACmdResultDetails[Ln]; + //Todo: Get mail box attributes here + {CC2: Could put mailbox attributes in AMBList's Objects property?} + {The line is of the form: + * LIST (\UnMarked \AnotherFlag) "/" "Mailbox name" + } + {CCA: code modified because some servers return NIL as the mailbox + separator, i.e.: + * LIST (\UnMarked \AnotherFlag) NIL "Mailbox name" + } + + ParseIntoBrackettedQuotedAndUnquotedParts(LStr, LSlRetrieve, False); + if LSlRetrieve.Count > 3 then begin + //Make sure 1st word is LIST (may be an unsolicited response)... + if TextIsSame(LSlRetrieve[0], {IMAP4Commands[cmdList]} ACmd) then begin + {Get the mailbox separator...} + LWord := Trim(LSlRetrieve[LSlRetrieve.Count-2]); + if TextIsSame(LWord, 'NIL') or (LWord = '') then begin {Do not Localize} + FMailBoxSeparator := #0; + end else begin + FMailBoxSeparator := LWord[1]; + end; + {Now get the mailbox name...} + LWord := Trim(LSlRetrieve[LSlRetrieve.Count-1]); + AMBList.Add(DoMUTFDecode(LWord)); + end; + end; + end; + finally + FreeAndNil(LSlRetrieve); + end; + finally + AMBList.EndUpdate; + end; +end; + +procedure TIdIMAP4.ParseLSubResult(AMBList: TStrings; ACmdResultDetails: TStrings); +begin + InternalParseListResult(IMAP4Commands[cmdLSub], AMBList, ACmdResultDetails); +end; + +procedure TIdIMAP4.ParseEnvelopeResult(AMsg: TIdMessage; ACmdResultStr: String); + + procedure DecodeEnvelopeAddress(const AAddressStr: String; AEmailAddressItem: TIdEmailAddressItem); overload; + var + LStr, LTemp: String; + I: Integer; + {$IFNDEF DOTNET} + LPChar: PChar; + {$ENDIF} + begin + if TextStartsWith(AAddressStr, '(') and TextEndsWith(AAddressStr, ')') and {Do not Localize} + Assigned(AEmailAddressItem) then begin + LStr := Copy(AAddressStr, 2, Length (AAddressStr) - 2); + //Gets the name part + if TextStartsWith(LStr, 'NIL ') then begin {Do not Localize} + LStr := Copy(LStr, 5, MaxInt); {Do not Localize} + end + else if TextStartsWith(LStr, '{') then begin {Do not Localize} + LStr := Copy(LStr, Pos('}', LStr) + 1, MaxInt); {Do not Localize} + I := Pos('" ', LStr); + AEmailAddressItem.Name := Copy(LStr, 1, I-1); {Do not Localize} + LStr := Copy(LStr, I+2, MaxInt); {Do not Localize} + end else begin + I := Pos('" ', LStr); + LTemp := Copy(LStr, 1, I); + {$IFDEF DOTNET} + AEmailAddressItem.Name := Copy(LTemp, 2, Length(LTemp)-2); {ExtractQuotedStr ( LTemp, '"' ); {Do not Localize} + {$ELSE} + LPChar := PChar(LTemp); + AEmailAddressItem.Name := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} + {$ENDIF} + LStr := Copy(LStr, I+2, MaxInt); {Do not Localize} + end; + //Gets the source root part + if TextStartsWith(LStr, 'NIL ') then begin {Do not Localize} + LStr := Copy(LStr, 5, MaxInt); {Do not Localize} + end else begin + I := Pos('" ', LStr); + LTemp := Copy(LStr, 1, I); + {$IFDEF DOTNET} + AEmailAddressItem.Name := Copy(LTemp, 2, Length(LTemp)-2); {AnsiExtractQuotedStr ( LTemp, '"' ); {Do not Localize} + {$ELSE} + LPChar := PChar(LTemp); + AEmailAddressItem.Name := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} + {$ENDIF} + LStr := Copy(LStr, I+2, MaxInt); {Do not Localize} + end; + //Gets the mailbox name part + if TextStartsWith(LStr, 'NIL ') then begin {Do not Localize} + LStr := Copy(LStr, 5, MaxInt); {Do not Localize} + end else begin + I := Pos('" ', LStr); + LTemp := Copy(LStr, 1, I); {Do not Localize} + {$IFDEF DOTNET} + AEmailAddressItem.Address := Copy(LTemp, 2, Length(LTemp)-2); {AnsiExtractQuotedStr ( LTemp, '"' ); {Do not Localize} + {$ELSE} + LPChar := PChar(LTemp); + AEmailAddressItem.Address := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} + {$ENDIF} + LStr := Copy(LStr, I+2, MaxInt); {Do not Localize} + end; + //Gets the host name part + if not TextIsSame(LStr, 'NIL') then begin {Do not Localize} + LTemp := Copy(LStr, 1, MaxInt); + {$IFDEF DOTNET} + AEmailAddressItem.Address := AEmailAddressItem.Address + '@' + {Do not Localize} + Copy(LTemp, 2, Length(LTemp)-2); {AnsiExtractQuotedStr ( LTemp, '"' ); {Do not Localize} + {$ELSE} + LPChar := PChar(LTemp); + AEmailAddressItem.Address := AEmailAddressItem.Address + '@' + {Do not Localize} + AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} + {$ENDIF} + end; + end; + end; + + procedure DecodeEnvelopeAddress(const AAddressStr: String; AEmailAddressList: TIdEmailAddressList); overload; + var + LStr: String; + I: Integer; + begin + if TextStartsWith(AAddressStr, '(') and TextEndsWith(AAddressStr, ')') and {Do not Localize} + Assigned(AEmailAddressList) then begin + LStr := Copy(AAddressStr, 2, Length (AAddressStr) - 2); + repeat + I := Pos(')', LStr); + if I = 0 then begin + Break; + end; + DecodeEnvelopeAddress(Copy(LStr, 1, I), AEmailAddressList.Add); {Do not Localize} + LStr := Trim(Copy(LStr, I+1, MaxInt)); {Do not Localize} + until False; + end; + end; + +var + LStr, LTemp: String; + I: Integer; + {$IFNDEF DOTNET} + LPChar: PChar; + {$ENDIF} +begin + //The fields of the envelope structure are in the + //following order: date, subject, from, sender, + //reply-to, to, cc, bcc, in-reply-to, and message-id. + //The date, subject, in-reply-to, and message-id + //fields are strings. The from, sender, reply-to, + //to, cc, and bcc fields are parenthesized lists of + //address structures. + + //An address structure is a parenthesized list that + //describes an electronic mail address. The fields + //of an address structure are in the following order: + //personal name, [SMTP] at-domain-list (source + //route), mailbox name, and host name. + + //* 4 FETCH (ENVELOPE ("Sun, 15 Jul 2001 02:56:45 -0700 (PDT)" "Your Borland Commu + //nity Account Activation Code" (("Borland Community" NIL "mailbot" "borland.com") + //) NIL NIL (("" NIL "name" "company.com")) NIL NIL NIL "<200107150956.CAA1 + //8152@borland.com>")) + + {CC5: Cleared out any existing fields to avoid mangling new entries with old/stale ones.} + //Extract envelope date field + AMsg.Date := 0; + if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} + ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); + end else begin + I := Pos('" ', ACmdResultStr); {Do not Localize} + LTemp := Copy(ACmdResultStr, 1, I); + {$IFDEF DOTNET} + LStr := Copy(LTemp, 2, Length(LTemp)-2); + {$ELSE} + LPChar := PChar(LTemp); + LStr := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} + {$ENDIF} + AMsg.Date := GMTToLocalDateTime(LStr); + ACmdResultStr := Copy(ACmdResultStr, I+2, MaxInt); + end; + //Extract envelope subject field + AMsg.Subject := ''; {Do not Localize} + if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} + ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); + end else begin + if TextStartsWith(ACmdResultStr, '{') then begin {Do not Localize} + ACmdResultStr := Copy(ACmdResultStr, Pos('}', ACmdResultStr) + 1, MaxInt); {Do not Localize} + I := Pos(' ', ACmdResultStr); {Do not Localize} + LStr := Copy(ACmdResultStr, 1, I-1); + AMsg.Subject := LStr; + ACmdResultStr := Copy(ACmdResultStr, I+1, MaxInt); {Do not Localize} + end else begin + I := Pos('" ', ACmdResultStr); {Do not Localize} + LTemp := Copy(ACmdResultStr, 1, I); + {$IFDEF DOTNET} + LStr := Copy(LTemp, 2, Length(LTemp)-2); + {$ELSE} + LPChar := PChar(LTemp); + LStr := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} + {$ENDIF} + AMsg.Subject := LStr; + ACmdResultStr := Copy(ACmdResultStr, I+2, MaxInt); {Do not Localize} + end; + end; + //Extract envelope from field + AMsg.FromList.Clear; + if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} + ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); + end else begin + I := Pos(')) ', ACmdResultStr); {Do not Localize} + LStr := Copy(ACmdResultStr, 1, I+1); + DecodeEnvelopeAddress(LStr, AMsg.FromList); + ACmdResultStr := Copy(ACmdResultStr, I+3, MaxInt); + end; + //Extract envelope sender field + AMsg.Sender.Name := ''; {Do not Localize} + AMsg.Sender.Address := ''; {Do not Localize} + if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} + ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); + end else begin + {CC5: Fix parsing of sender...} + I := Pos(')) ', ACmdResultStr); + LStr := Copy(ACmdResultStr, 2, I-1); + DecodeEnvelopeAddress(LStr, AMsg.Sender); + ACmdResultStr := Copy(ACmdResultStr, I+3, MaxInt); + end; + //Extract envelope reply-to field + AMsg.ReplyTo.Clear; + if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} + ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); + end else begin + I := Pos(')) ', ACmdResultStr); {Do not Localize} + LStr := Copy(ACmdResultStr, 1, I+1); + DecodeEnvelopeAddress(LStr, AMsg.ReplyTo); + ACmdResultStr := Copy(ACmdResultStr, I+3, MaxInt); + end; + //Extract envelope to field + AMsg.Recipients.Clear; + if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} + ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); + end else begin + I := Pos(')) ', ACmdResultStr); {Do not Localize} + LStr := Copy(ACmdResultStr, 1, I+1); + DecodeEnvelopeAddress(LStr, AMsg.Recipients); + ACmdResultStr := Copy(ACmdResultStr, I+3, MaxInt); + end; + //Extract envelope cc field + AMsg.CCList.Clear; + if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} + ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); + end else begin + I := Pos(')) ', ACmdResultStr); {Do not Localize} + LStr := Copy(ACmdResultStr, 1, I+1); + DecodeEnvelopeAddress(LStr, AMsg.CCList); + ACmdResultStr := Copy(ACmdResultStr, I+3, MaxInt); + end; + //Extract envelope bcc field + AMsg.BccList.Clear; + if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} + ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); + end else begin + I := Pos(')) ', ACmdResultStr); {Do not Localize} + LStr := Copy(ACmdResultStr, 1, I+1); + DecodeEnvelopeAddress(LStr, AMsg.BccList); + ACmdResultStr := Copy(ACmdResultStr, I+3, MaxInt); + end; + //Extract envelope in-reply-to field + if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} + ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); + end else begin + I := Pos('" ', ACmdResultStr); {Do not Localize} + LTemp := Copy(ACmdResultStr, 1, I); + {$IFDEF DOTNET} + LStr := Copy(LTemp, 2, Length(LTemp)-2); + {$ELSE} + LPChar := PChar(LTemp); + LStr := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} + {$ENDIF} + AMsg.InReplyTo := LStr; + ACmdResultStr := Copy(ACmdResultStr, I+2, MaxInt); + end; + //Extract envelope message-id field + AMsg.MsgId := ''; {Do not Localize} + if TextStartsWith(ACmdResultStr, 'NIL ') then begin {Do not Localize} + ACmdResultStr := Copy(ACmdResultStr, 5, MaxInt); + end else begin + {$IFDEF DOTNET} + LStr := Copy(ACmdResultStr, 2, Length(ACmdResultStr)-2); + {$ELSE} + LPChar := PChar(ACmdResultStr); + LStr := AnsiExtractQuotedStr(LPChar, '"'); {Do not Localize} + {$ENDIF} + AMsg.MsgId := Trim(LStr); + end; +end; + +function TIdIMAP4.ParseLastCmdResult(ALine: string; AExpectedCommand: string; AExpectedIMAPFunction: array of string): Boolean; +var + LPos: integer; + LWord: string; + LWords: TStringList; + LN: Integer; + LWordInExpectedIMAPFunction: Boolean; +begin + Result := False; + LWordInExpectedIMAPFunction := False; + FLineStruct.HasStar := False; + FLineStruct.MessageNumber := ''; + FLineStruct.Command := ''; + FLineStruct.UID := ''; + FLineStruct.Flags := []; + FLineStruct.FlagsStr := ''; + FLineStruct.Complete := True; + FLineStruct.IMAPFunction := ''; + FLineStruct.IMAPValue := ''; + FLineStruct.ByteCount := -1; + FLineStruct.GmailMsgID := ''; + FLineStruct.GmailThreadID := ''; + FLineStruct.GmailLabels := ''; + ALine := Trim(ALine); //Can get garbage like a spurious CR at start + //Look for (optional) * at start... + LPos := Pos(' ', ALine); {Do not Localize} + if LPos < 1 then begin + Exit; //Nothing on this line + end; + LWord := Copy(ALine, 1, LPos-1); + if LWord = '*' then begin {Do not Localize} + FLineStruct.HasStar := True; + ALine := Copy(ALine, LPos+1, MaxInt); + LPos := Pos(' ', ALine); {Do not Localize} + if LPos < 1 then begin + Exit; //Line ONLY had a * + end; + LWord := Copy(ALine, 1, LPos-1); + end; + //Look for (optional) message number next... + if IsNumeric(LWord) then begin + FLineStruct.MessageNumber := LWord; + ALine := Copy(ALine, LPos+1, MaxInt); + LPos := Pos(' ', ALine); {Do not Localize} + if LPos < 1 then begin + Exit; //Line ONLY had a * 67 + end; + LWord := Copy(ALine, 1, LPos-1); + end; + //We should have a valid IMAP command word now, like FETCH, LIST or SEARCH... + if PosInStrArray(LWord, IMAP4Commands) = -1 then begin + Exit; //Should have been a command, give up. + end; + FLineStruct.Command := LWord; + if ((AExpectedCommand = '') or (FLineStruct.Command = AExpectedCommand)) then begin + Result := True; + end; + ALine := Copy(ALine, Length(LWord)+2, MaxInt); + if ALine[1] <> '(' then begin {Do not Localize} + //This is a line like '* SEARCH 34 56', the '34 56' is the value (result)... + FLineStruct.IMAPValue := ALine; + Exit; + end; + //This is a line like '* 9 FETCH (UID 47 RFC822.SIZE 3456)', i.e. with a bracketted response. + //See is it complete (has a closing bracket) or does it continue on other lines... + ALine := Copy(ALine, 2, MaxInt); + if TextEndsWith(ALine, ')') then begin {Do not Localize} + ALine := Copy(ALine, 1, Length(ALine) - 1); //Strip trailing bracket + FLineStruct.Complete := True; + end else begin + FLineStruct.Complete := False; + end; + //These words left may occur in different order. Find & delete those we know. + LWords := TStringList.Create; + try + ParseIntoBrackettedQuotedAndUnquotedParts(ALine, LWords, False); + if LWords.Count > 0 then begin + //See does it have a trailing byte count... + LWord := LWords[LWords.Count-1]; + if TextStartsWith(LWord, '{') and TextEndsWith(LWord, '}') then begin + //It ends in a byte count... + LWord := Copy(LWord, 2, Length(LWord)-2); + if TextIsSame(LWord, 'NIL') then begin {do not localize} + FLineStruct.ByteCount := 0; + end else begin + FLineStruct.ByteCount := IndyStrToInt(LWord); + end; + LWords.Delete(LWords.Count-1); + end; + end; + if not FLineStruct.Complete then begin + //The command in this case should be the last word... + if LWords.Count > 0 then begin + FLineStruct.IMAPFunction := LWords[LWords.Count-1]; + LWords.Delete(LWords.Count-1); + end; + end; + //See is the UID present... + LPos := LWords.IndexOf(IMAP4FetchDataItem[fdUID]); {Do not Localize} + if LPos <> -1 then begin + //The UID is the word after 'UID'... + if LPos < LWords.Count-1 then begin + FLineStruct.UID := LWords[LPos+1]; + LWords.Delete(LPos+1); + LWords.Delete(LPos); + end; + if PosInStrArray(IMAP4FetchDataItem[fdUID], AExpectedIMAPFunction) > -1 then begin + LWordInExpectedIMAPFunction := True; + end; + end; + //See are the FLAGS present... + LPos := LWords.IndexOf(IMAP4FetchDataItem[fdFlags]); {Do not Localize} + if LPos <> -1 then begin + //The FLAGS are in the "word" (really a string) after 'FLAGS'... + if LPos < LWords.Count-1 then begin + FLineStruct.FlagsStr := LWords[LPos+1]; + ParseMessageFlagString(FLineStruct.FlagsStr, FLineStruct.Flags); + LWords.Delete(LPos+1); + LWords.Delete(LPos); + end; + if PosInStrArray(IMAP4FetchDataItem[fdFlags], AExpectedIMAPFunction) > -1 then begin + LWordInExpectedIMAPFunction := True; + end; + end; + //See is the X-GM-MSGID present... + LPos := LWords.IndexOf(IMAP4FetchDataItem[fdGmailMsgID]); {Do not Localize} + if LPos <> -1 then begin + //The MSGID is in the "word" (really a string) after 'X-GM-MSGID'... + if LPos < LWords.Count-1 then begin + FLineStruct.GmailMsgID := LWords[LPos+1]; + LWords.Delete(LPos+1); + LWords.Delete(LPos); + end; + if PosInStrArray(IMAP4FetchDataItem[fdGmailMsgID], AExpectedIMAPFunction) > -1 then begin + LWordInExpectedIMAPFunction := True; + end; + end; + //See is the X-GM-THRID present... + LPos := LWords.IndexOf(IMAP4FetchDataItem[fdGmailThreadID]); {Do not Localize} + if LPos <> -1 then begin + //The THREADID is in the "word" (really a string) after 'X-GM-THRID'... + if LPos < LWords.Count-1 then begin + FLineStruct.GmailThreadID := LWords[LPos+1]; + LWords.Delete(LPos+1); + LWords.Delete(LPos); + end; + if PosInStrArray(IMAP4FetchDataItem[fdGmailThreadID], AExpectedIMAPFunction) > -1 then begin + LWordInExpectedIMAPFunction := True; + end; + end; + //See is the X-GM-LABELS present... + LPos := LWords.IndexOf(IMAP4FetchDataItem[fdGmailLabels]); {Do not Localize} + if LPos <> -1 then begin + //The LABELS is in the "word" (really a string) after 'X-GM-LABELS'... + if LPos < LWords.Count-1 then begin + FLineStruct.GmailLabels := DoMUTFDecode(LWords[LPos+1]); + LWords.Delete(LPos+1); + LWords.Delete(LPos); + end; + if PosInStrArray(IMAP4FetchDataItem[fdGmailLabels], AExpectedIMAPFunction) > -1 then begin + LWordInExpectedIMAPFunction := True; + end; + end; + if Length(AExpectedIMAPFunction) > 0 then begin + //See is what we want present. + for LN := 0 to Length(AExpectedIMAPFunction)-1 do begin + //First check if we got it already in IMAPFunction... + if TextIsSame(FLineStruct.IMAPFunction, AExpectedIMAPFunction[LN]) then begin + LWordInExpectedIMAPFunction := True; + Break; + end; + //Now check if it is in any remaining words... + LPos := LWords.IndexOf(AExpectedIMAPFunction[LN]); {Do not Localize} + if LPos <> -1 then begin + FLineStruct.IMAPFunction := LWords[LPos]; + LWordInExpectedIMAPFunction := True; + if LPos < LWords.Count-1 then begin + //There is a parameter after our function... + FLineStruct.IMAPValue := LWords[LPos+1]; + end; + Break; + end; + end; + end else begin + //See is there function/value items left. There may not be, such as + //'* 9 FETCH (UID 45)' in response to a GetUID request. + if FLineStruct.Complete then begin + if LWords.Count > 1 then begin + FLineStruct.IMAPFunction := LWords[LWords.Count-2]; + FLineStruct.IMAPValue := LWords[LWords.Count-1]; + end; + end; + end; + Result := False; + if (AExpectedCommand = '') or (FLineStruct.Command = AExpectedCommand) then begin + //The AExpectedCommand is correct, now need to check the AExpectedIMAPFunction... + if (Length(AExpectedIMAPFunction) = 0) or LWordInExpectedIMAPFunction then begin + Result := True; + end; + end; + finally + FreeAndNil(LWords); + end; +end; + +{This ADDS any parseable info from ALine to FLineStruct (set up from a previous ParseLastCmdResult call)} +procedure TIdIMAP4.ParseLastCmdResultButAppendInfo(ALine: string); +var + LPos: integer; + LWords: TStringList; +begin + ALine := Trim(ALine); //Can get garbage like a spurious CR at start + {We may have an initial or ending bracket, like ") UID 5" or "UID 5)"} + if TextStartsWith(ALine, ')') then begin {Do not Localize} + ALine := Trim(Copy(ALine, 2, MaxInt)); + end; + if TextEndsWith(ALine, ')') then begin {Do not Localize} + ALine := Trim(Copy(ALine, 1, Length(ALine)-1)); + end; + //These words left may occur in different order. Find & delete those we know. + LWords := TStringList.Create; + try + ParseIntoBrackettedQuotedAndUnquotedParts(ALine, LWords, False); + //See is the UID present... + LPos := LWords.IndexOf('UID'); {Do not Localize} + if LPos <> -1 then begin + //The UID is the word after 'UID'... + FLineStruct.UID := LWords[LPos+1]; + LWords.Delete(LPos+1); + LWords.Delete(LPos); + end; + //See are the FLAGS present... + LPos := LWords.IndexOf('FLAGS'); {Do not Localize} + if LPos <> -1 then begin + //The FLAGS are in the "word" (really a string) after 'FLAGS'... + FLineStruct.FlagsStr := LWords[LPos+1]; + ParseMessageFlagString(FLineStruct.FlagsStr, FLineStruct.Flags); + LWords.Delete(LPos+1); + LWords.Delete(LPos); + end; + finally + FreeAndNil(LWords); + end; +end; + +{ ...Parser Functions } + +function TIdIMAP4.ArrayToNumberStr(const AMsgNumList: array of UInt32): String; +var + Ln : Integer; +begin + for Ln := 0 to Length(AMsgNumList) - 1 do begin + Result := Result + IntToStr(Int64(AMsgNumList[Ln])) + ','; {Do not Localize} + end; + SetLength(Result, (Length(Result) - 1 )); +end; + +function TIdIMAP4.MessageFlagSetToStr(const AFlags: TIdMessageFlagsSet): String; +begin + Result := ''; + if AFlags = [] then begin + Exit; + end; + if mfAnswered in AFlags then begin + Result := Result + MessageFlags[mfAnswered] + ' '; {Do not Localize} + end; + if mfFlagged in AFlags then begin + Result := Result + MessageFlags[mfFlagged] + ' '; {Do not Localize} + end; + if mfDeleted in AFlags then begin + Result := Result + MessageFlags[mfDeleted] + ' '; {Do not Localize} + end; + if mfDraft in AFlags then begin + Result := Result + MessageFlags[mfDraft] + ' '; {Do not Localize} + end; + if mfSeen in AFlags then begin + Result := Result + MessageFlags[mfSeen] + ' '; {Do not Localize} + end; + Result := Trim(Result); +end; + +procedure TIdIMAP4.StripCRLFs(ASourceStream, ADestStream: TStream); +var + LByte: TIdBytes; + LNumSourceBytes: TIdStreamSize; + LBytesRead: Int64; +begin + SetLength(LByte, 1); + ASourceStream.Position := 0; + ADestStream.Size := 0; + LNumSourceBytes := ASourceStream.Size; + LBytesRead := 0; + while LBytesRead < LNumSourceBytes do begin + TIdStreamHelper.ReadBytes(ASourceStream, LByte, 1); + if not ByteIsInEOL(LByte, 0) then begin + TIdStreamHelper.Write(ADestStream, LByte, 1); + end; + Inc(LBytesRead); + end; +end; + +procedure TIdIMAP4.StripCRLFs(var AText: string); +var + LPos: integer; + LLen: integer; + LTemp: string; + LDestPos: integer; +begin + //Optimised with the help of Guus Creuwels. + LPos := 1; + LLen := Length(AText); + SetLength(LTemp, LLen); + LDestPos := 1; + while LPos <= LLen do begin + if AText[LPos] = #13 then begin + //Don't GPF if this is the last char in the string... + if LPos < LLen then begin + if AText[LPos+1] = #10 then begin + Inc(LPos, 2); + end else begin + LTemp[LDestPos] := AText[LPos]; + Inc(LPos); + Inc(LDestPos); + end; + end else begin + LTemp[LDestPos] := AText[LPos]; + Inc(LPos); + Inc(LDestPos); + end; + end else begin + LTemp[LDestPos] := AText[LPos]; + Inc(LPos); + Inc(LDestPos); + end; + end; + SetLength(LTemp, LDestPos - 1); + AText := LTemp; +end; + +procedure TIdIMAP4.ReceiveBody(AMsg: TIdMessage; const ADelim: string = '.'); {Do not Localize} +var + LMsgEnd: Boolean; + LActiveDecoder: TIdMessageDecoder; + LLine: string; + LCheckForOptionalImapFlags: Boolean; + LDelim: string; + + {CC7: The following define SContentType is from IdMessageClient. It is defined here also + (with only local scope) because the one in IdMessageClient is defined locally + there also, so we cannot get at it.} +const + SContentType = 'Content-Type'; {do not localize} + + // TODO - move this procedure into TIdIOHandler as a new Capture method? + procedure CaptureAndDecodeCharset; + var + LMStream: TMemoryStream; + begin + LMStream := TMemoryStream.Create; + try + IOHandler.Capture(LMStream, LDelim, True, IndyTextEncoding_8Bit{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_8Bit{$ENDIF}); + LMStream.Position := 0; + // TODO: when String is AnsiString, TIdMessageClient uses AMsg.CharSet as + // the destination encoding, should this be doing the same? Otherwise, we + // could just use AMsg.Body.LoadFromStream() instead... + ReadStringsAsCharSet(LMStream, AMsg.Body, AMsg.CharSet{$IFDEF STRING_IS_ANSI}, IndyTextEncoding_8Bit{$ENDIF}); + finally + LMStream.Free; + end; + end; + + function IsContentTypeHtml(const AContentType: String) : Boolean; + begin + Result := IsHeaderMediaTypes(AContentType, ['text/html', 'text/html-sandboxed','application/xhtml+xml']); {do not localize} + end; + + procedure ProcessTextPart(var VDecoder: TIdMessageDecoder); + var + LDestStream: TMemoryStream; + Li: integer; + LTxt: TIdText; + LNewDecoder: TIdMessageDecoder; + {$IFDEF STRING_IS_ANSI} + LAnsiEncoding: IIdTextEncoding; + {$ENDIF} + LContentType, LCharSet: string; + begin + LDestStream := TMemoryStream.Create; + try + LNewDecoder := VDecoder.ReadBody(LDestStream, LMsgEnd); + try + LDestStream.Position := 0; + LTxt := TIdText.Create(AMsg.MessageParts); + try + // if the Content-Type is HTML and does not specify a charset, parse + // the HTML looking for a tag that specifies a charset... + + // TODO: if the media type is not a 'text/...' based XML type, ignore + // the charset from the headers, if present, and parse the XML itself... + + LContentType := VDecoder.Headers.Values[SContentType]; + { + if IsContentTypeAppXml(LContentType) then begin + LCharSet := DetectXmlCharset(LDestStream); + LDestStream.Position := 0; + end else + begin + } + LCharSet := LTxt.GetCharSet(LContentType); + if (LCharSet = '') and IsContentTypeHtml(LContentType) then begin + ParseMetaHTTPEquiv(LDestStream, nil, LCharSet); + LDestStream.Position := 0; + end; + //end; + + LTxt.ContentType := LContentType; + LTxt.CharSet := LCharSet; + LTxt.ContentID := VDecoder.Headers.Values['Content-ID']; {Do not Localize} + LTxt.ContentLocation := VDecoder.Headers.Values['Content-Location']; {Do not Localize} + LTxt.ContentDescription := VDecoder.Headers.Values['Content-Description']; {Do not Localize} + LTxt.ContentDisposition := VDecoder.Headers.Values['Content-Disposition']; {Do not Localize} + LTxt.ContentTransfer := VDecoder.Headers.Values['Content-Transfer-Encoding']; {Do not Localize} + for Li := 0 to VDecoder.Headers.Count-1 do begin + if LTxt.Headers.IndexOfName(VDecoder.Headers.Names[Li]) < 0 then begin + LTxt.ExtraHeaders.AddValue( + VDecoder.Headers.Names[Li], + IndyValueFromIndex(VDecoder.Headers, Li) + ); + end; + end; + {$IFDEF STRING_IS_ANSI} + LAnsiEncoding := CharsetToEncoding(LCharSet); + {$ENDIF} + ReadStringsAsCharset(LDestStream, LTxt.Body, LCharSet{$IFDEF STRING_IS_ANSI}, LAnsiEncoding{$ENDIF}); + except + //this should also remove the Item from the TCollection. + //Note that Delete does not exist in the TCollection. + LTxt.Free; + raise; + end; + except + LNewDecoder.Free; + raise; + end; + VDecoder.Free; + VDecoder := LNewDecoder; + finally + FreeAndNil(LDestStream); + end; + end; + + procedure ProcessAttachment(var VDecoder: TIdMessageDecoder); + var + LDestStream: TStream; + Li: integer; + LAttachment: TIdAttachment; + LNewDecoder: TIdMessageDecoder; + begin + AMsg.DoCreateAttachment(VDecoder.Headers, LAttachment); + Assert(Assigned(LAttachment), 'Attachment must not be unassigned here!'); {Do not Localize} + try + LNewDecoder := nil; + try + LDestStream := LAttachment.PrepareTempStream; + try + LNewDecoder := VDecoder.ReadBody(LDestStream, LMsgEnd); + finally + LAttachment.FinishTempStream; + end; + LAttachment.ContentType := VDecoder.Headers.Values[SContentType]; + LAttachment.ContentTransfer := VDecoder.Headers.Values['Content-Transfer-Encoding']; {Do not Localize} + LAttachment.ContentDisposition := VDecoder.Headers.Values['Content-Disposition']; {Do not Localize} + LAttachment.ContentID := VDecoder.Headers.Values['Content-ID']; {Do not Localize} + LAttachment.ContentLocation := VDecoder.Headers.Values['Content-Location']; {Do not Localize} + LAttachment.ContentDescription := VDecoder.Headers.Values['Content-Description']; {Do not Localize} + LAttachment.Filename := VDecoder.Filename; + for Li := 0 to VDecoder.Headers.Count-1 do begin + if LAttachment.Headers.IndexOfName(VDecoder.Headers.Names[Li]) < 0 then begin + LAttachment.ExtraHeaders.AddValue( + VDecoder.Headers.Names[Li], + IndyValueFromIndex(VDecoder.Headers, Li) + ); + end; + end; + except + LNewDecoder.Free; + raise; + end; + except + //this should also remove the Item from the TCollection. + //Note that Delete does not exist in the TCollection. + LAttachment.Free; + raise; + end; + VDecoder.Free; + VDecoder := LNewDecoder; + end; + +Begin + {CC3: If IMAP calls this ReceiveBody, it prepends IMAP to delim, e.g. 'IMAP)', + to flag that this routine should expect IMAP FLAGS entries.} + LCheckForOptionalImapFlags := False; {CC3: IMAP hack inserted lines start here...} + LDelim := ADelim; + if TextStartsWith(ADelim, 'IMAP') then begin {do not localize} + LCheckForOptionalImapFlags := True; + LDelim := Copy(ADelim, 5, MaxInt); + end; {CC3: ...IMAP hack inserted lines end here} + LMsgEnd := False; + if AMsg.NoDecode then begin + CaptureAndDecodeCharSet; + end else begin + BeginWork(wmRead); + try + LActiveDecoder := nil; + try + repeat + LLine := IOHandler.ReadLn; + {CC3: Check for optional flags before delimiter in the case of IMAP...} + if LLine = LDelim then begin {CC3: IMAP hack ADelim -> LDelim} + Break; + end; {CC3: IMAP hack inserted lines start here...} + if LCheckForOptionalImapFlags and TextStartsWith(LLine, ' FLAGS (\') {do not localize} + and TextEndsWith(LLine, LDelim) then begin + Break; + end; + if LActiveDecoder = nil then begin + LActiveDecoder := TIdMessageDecoderList.CheckForStart(AMsg, LLine); + end; + if LActiveDecoder = nil then begin + {CC9: Per RFC821, the sender is required to add a prefixed '.' to any + line in an email that starts with '.' and the receiver is + required to strip it off. This ensures that the end-of-message + line '.' cannot appear in the message body.} + if TextStartsWith(LLine, '..') then begin {Do not Localize} + Delete(LLine,1,1); + end; + AMsg.Body.Add(LLine); + end else begin + while LActiveDecoder <> nil do begin + LActiveDecoder.SourceStream := TIdTCPStream.Create(Self); + LActiveDecoder.ReadHeader; + case LActiveDecoder.PartType of + mcptText: ProcessTextPart(LActiveDecoder); + mcptAttachment: ProcessAttachment(LActiveDecoder); + mcptIgnore: FreeAndNil(LActiveDecoder); + mcptEOF: begin FreeAndNil(LActiveDecoder); LMsgEnd := True; end; + end; + end; + end; + until LMsgEnd; + finally + FreeAndNil(LActiveDecoder); + end; + finally + EndWork(wmRead); + end; + end; +end; + +{########### Following only used by CONNECT? ###############} +function TIdIMAP4.GetResponse: string; +{CC: The purpose of this is to keep reading & accumulating lines until we hit +a line that has a valid response (that terminates the reading). We call +"FLastCmdResult.FormattedReply := LResponse;" to parse out the response we +received. + +The response sequences we need to deal with are: + +1) Many commands just give a simple result to the command issued: + C41 OK Completed +2) Some commands give you data first, then the result: + * LIST (\UnMarked) "/" INBOX + * LIST (\UnMarked) "/" Junk + * LIST (\UnMarked) "/" Junk/Subbox1 + C42 OK Completed +3) Some responses have a result but * instead of a command number (like C42): + * OK CommuniGate Pro IMAP Server 3.5.7 ready +4) Some have neither a * nor command number, but start with a result: + + Send the additional command text +or: + BAD Bad parameter + +Because you may get data first, which you need to skip, you need to +accept all the above possibilities. + +We MUST stop when we find a valid response code, like OK. +} +var + LLine: String; + LResponse: TStringList; + LWord: string; + LPos: integer; + LBuf: string; +begin + Result := ''; {Do not Localize} + LResponse := TStringList.Create; + try + repeat + LLine := IOHandler.ReadLnWait; + if LLine <> '' then begin {Do not Localize} + {It is not an empty line, add it to our list of stuff received (it is + not our job to interpret it)} + LResponse.Add(LLine); + {See if the last LLine contained a response code like OK or BAD.} + LPos := Pos(' ', LLine); {Do not Localize} + if LPos <> 0 then begin + {There are at least two words on this line...} + LWord := Trim(Copy(LLine, 1, LPos-1)); + LBuf := Trim(Copy(LLine, LPos+1, MaxInt)); {The rest of the line, without the 1st word} + end else begin + {No space, so this line is a single word. A bit weird, but it + could be just an OK...} + LWord := LLine; {A bit pedantic, but emphasises we have a word, not a line} + LBuf := ''; {Do not Localize} + end; + LPos := PosInStrArray(LWord, VALID_TAGGEDREPLIES); {Do not Localize} + if LPos > -1 then begin + {We got a valid response code as the first word...} + Result := LWord; + FLastCmdResult.FormattedReply := LResponse; + Exit; + end; + if Length(LBuf) = 0 then begin {Do not Localize} + Continue; {We hit a line with just one word which is not a valid IMAP response} + end; + {In all other cases, any valid response should be the second word...} + LPos := Pos(' ', LBuf); {Do not Localize} + if LPos <> 0 then begin + {There are at least three words on this line...} + LWord := Trim(Copy(LBuf, 1, LPos-1)); + LBuf := Trim(Copy(LBuf, LPos+1, MaxInt)); {The rest of the line, without the 1st word} + end else begin + {No space, so this line is two single words.} + LWord := LLine; {A bit pedantic, but emphasises we have a word, not a line} + LBuf := ''; {Do not Localize} + end; + LPos := PosInStrArray(LWord, VALID_TAGGEDREPLIES); {Do not Localize} + if LPos > -1 then begin + {We got a valid response code as the second word...} + Result := LWord; + FLastCmdResult.FormattedReply := LResponse; + Exit; + end; + end; + until False; + finally + FreeAndNil(LResponse); + end; +end; + +end. + diff --git a/Lib/Protocols/IdMessageHelper.pas b/Lib/Protocols/IdMessageHelper.pas index 0b92274f5..caac94a6d 100644 --- a/Lib/Protocols/IdMessageHelper.pas +++ b/Lib/Protocols/IdMessageHelper.pas @@ -1,236 +1,236 @@ -unit IdMessageHelper; - -{$I IdCompilerDefines.inc} - -interface - -uses - Classes, IdMessage; - -{$IFDEF HAS_CLASS_HELPER} -type - TIdMessageHelper = class helper for TIdMessage - public - procedure LoadFromFile(const AFileName: string; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); overload; - procedure LoadFromStream(AStream: TStream; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); overload; - procedure SaveToFile(const AFileName: string; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); overload; - procedure SaveToStream(AStream: TStream; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); overload; - end; -{$ENDIF} - -procedure TIdMessageHelper_LoadFromFile(AMsg: TIdMessage; const AFileName: string; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); {$IFDEF HAS_CLASS_HELPER}{$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use TIdMessageHelper.LoadFromFile()'{$ENDIF};{$ENDIF}{$ENDIF} -procedure TIdMessageHelper_LoadFromStream(AMsg: TIdMessage; AStream: TStream; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); {$IFDEF HAS_CLASS_HELPER}{$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use TIdMessageHelper.LoadFromStream()'{$ENDIF};{$ENDIF}{$ENDIF} -procedure TIdMessageHelper_SaveToFile(AMsg: TIdMessage; const AFileName: string; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); {$IFDEF HAS_CLASS_HELPER}{$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use TIdMessageHelper.SaveToFile()'{$ENDIF};{$ENDIF}{$ENDIF} -procedure TIdMessageHelper_SaveToStream(AMsg: TIdMessage; AStream: TStream; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); {$IFDEF HAS_CLASS_HELPER}{$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use TIdMessageHelper.SaveToStream()'{$ENDIF};{$ENDIF}{$ENDIF} - -implementation - -uses - IdGlobal, IdMessageClient, SysUtils, IdResourceStringsProtocols; - -{ TIdMessageClientHelper } - -procedure Internal_TIdMessageClientHelper_ProcessMessage(AClient: TIdMessageClient; - AMsg: TIdMessage; AStream: TStream; AHeaderOnly: Boolean; - AUsesDotTransparency: Boolean); -var - LIOHandler: TIdIOHandlerStreamMsg; -begin - if AUsesDotTransparency then begin - AClient.ProcessMessage(AMsg, AStream, AHeaderOnly); - end else - begin - LIOHandler := TIdIOHandlerStreamMsg.Create(nil, AStream); - try - LIOHandler.FreeStreams := False; - LIOHandler.EscapeLines := True; // <-- this is the key! - AClient.IOHandler := LIOHandler; - try - LIOHandler.Open; - AClient.ProcessMessage(AMsg, AHeaderOnly); - finally - AClient.IOHandler := nil; - end; - finally - LIOHandler.Free; - end; - end; -end; - -{ TIdMessageHelper } - -procedure Internal_TIdMessageHelper_LoadFromStream(AMsg: TIdMessage; AStream: TStream; - const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); -var - LMsgClient: TIdMessageClient; -begin - if AUsesDotTransparency then begin - AMsg.LoadFromStream(AStream, AHeadersOnly); - end else - begin - // clear message properties, headers before loading - AMsg.Clear; - LMsgClient := TIdMessageClient.Create; - try - Internal_TIdMessageClientHelper_ProcessMessage(LMsgClient, AMsg, AStream, AHeadersOnly, False); - finally - LMsgClient.Free; - end; - end; -end; - -{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOff.inc}{$ENDIF} -procedure TIdMessageHelper_LoadFromStream(AMsg: TIdMessage; AStream: TStream; - const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); -{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOn.inc}{$ENDIF} -begin - Internal_TIdMessageHelper_LoadFromStream(AMsg, AStream, AHeadersOnly, AUsesDotTransparency); -end; - -{$IFDEF HAS_CLASS_HELPER} -procedure TIdMessageHelper.LoadFromStream(AStream: TStream; const AHeadersOnly: Boolean; - const AUsesDotTransparency: Boolean); -begin - Internal_TIdMessageHelper_LoadFromStream(Self, AStream, AHeadersOnly, AUsesDotTransparency); -end; -{$ENDIF} - -procedure Internal_TIdMessageHelper_LoadFromFile(AMsg: TIdMessage; const AFileName: string; - const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); -var - LStream: TIdReadFileExclusiveStream; -begin - if AUsesDotTransparency then begin - AMsg.LoadFromFile(AFileName, AHeadersOnly); - end else - begin - try - LStream := TIdReadFileExclusiveStream.Create(AFilename); - except - LStream := nil; // keep the compiler happy - IndyRaiseOuterException(EIdMessageCannotLoad.CreateFmt(RSIdMessageCannotLoad, [AFilename])); - end; - try - Internal_TIdMessageHelper_LoadFromStream(AMsg, LStream, AHeadersOnly, False); - finally - LStream.Free; - end; - end; -end; - -{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOff.inc}{$ENDIF} -procedure TIdMessageHelper_LoadFromFile(AMsg: TIdMessage; const AFileName: string; - const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); -{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOn.inc}{$ENDIF} -begin - Internal_TIdMessageHelper_LoadFromFile(AMsg, AFileName, AHeadersOnly, AUsesDotTransparency); -end; - -{$IFDEF HAS_CLASS_HELPER} -procedure TIdMessageHelper.LoadFromFile(const AFileName: string; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); -begin - Internal_TIdMessageHelper_LoadFromFile(Self, AFileName, AHeadersOnly, AUsesDotTransparency); -end; -{$ENDIF} - -procedure Internal_TIdMessageHelper_SaveToStream(AMsg: TIdMessage; AStream: TStream; - const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); -var - LMsgClient: TIdMessageClient; - LIOHandler: TIdIOHandlerStreamMsg; -begin - if AUseDotTransparency then begin - AMsg.SaveToStream(AStream, AHeadersOnly); - end else - begin - LMsgClient := TIdMessageClient.Create(nil); - try - LIOHandler := TIdIOHandlerStreamMsg.Create(nil, nil, AStream); - try - LIOHandler.FreeStreams := False; - LIOHandler.UnescapeLines := True; // <-- this is the key! - LMsgClient.IOHandler := LIOHandler; - try - LMsgClient.SendMsg(AMsg, AHeadersOnly); - { - // add the end of message marker when body is included - if not AHeadersOnly then begin - LIOHandler.WriteLn('.'); {do not localize - end; - } - finally - LMsgClient.IOHandler := nil; - end; - finally - LIOHandler.Free; - end; - finally - LMsgClient.Free; - end; - end; -end; - -{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOff.inc}{$ENDIF} -procedure TIdMessageHelper_SaveToStream(AMsg: TIdMessage; AStream: TStream; - const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); -{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOn.inc}{$ENDIF} -begin - Internal_TIdMessageHelper_SaveToStream(AMsg, AStream, AHeadersOnly, AUseDotTransparency); -end; - -{$IFDEF HAS_CLASS_HELPER} -procedure TIdMessageHelper.SaveToStream(AStream: TStream; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); -begin - Internal_TIdMessageHelper_SaveToStream(Self, AStream, AHeadersOnly, AUseDotTransparency); -end; -{$ENDIF} - -type - TIdMessageAccess = class(TIdMessage) - end; - -procedure Internal_TIdMessageHelper_SaveToFile(AMsg: TIdMessage; const AFileName: string; - const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); -var - LStream : TFileStream; - LMsgAccess: TIdMessageAccess; -begin - if AUseDotTransparency then begin - AMsg.SaveToFile(AFileName, AHeadersOnly); - end else - begin - LStream := TIdFileCreateStream.Create(AFileName); - try - {$I IdObjectChecksOff.inc} - LMsgAccess := TIdMessageAccess(AMsg); - {$I IdObjectChecksOn.inc} - - LMsgAccess.FSavingToFile := True; - try - Internal_TIdMessageHelper_SaveToStream(AMsg, LStream, AHeadersOnly, False); - finally - LMsgAccess.FSavingToFile := False; - end; - finally - LStream.Free; - end; - end; -end; - -{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOff.inc}{$ENDIF} -procedure TIdMessageHelper_SaveToFile(AMsg: TIdMessage; const AFileName: string; - const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); -{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOn.inc}{$ENDIF} -begin - Internal_TIdMessageHelper_SaveToFile(AMsg, AFileName, AHeadersOnly, AUseDotTransparency); -end; - -{$IFDEF HAS_CLASS_HELPER} -procedure TIdMessageHelper.SaveToFile(const AFileName: string; const AHeadersOnly: Boolean; - const AUseDotTransparency: Boolean); -begin - Internal_TIdMessageHelper_SaveToFile(Self, AFileName, AHeadersOnly, AUseDotTransparency); -end; -{$ENDIF} - +unit IdMessageHelper; + +{$I IdCompilerDefines.inc} + +interface + +uses + Classes, IdMessage; + +{$IFDEF HAS_CLASS_HELPER} +type + TIdMessageHelper = class helper for TIdMessage + public + procedure LoadFromFile(const AFileName: string; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); overload; + procedure LoadFromStream(AStream: TStream; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); overload; + procedure SaveToFile(const AFileName: string; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); overload; + procedure SaveToStream(AStream: TStream; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); overload; + end; +{$ENDIF} + +procedure TIdMessageHelper_LoadFromFile(AMsg: TIdMessage; const AFileName: string; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); {$IFDEF HAS_CLASS_HELPER}{$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use TIdMessageHelper.LoadFromFile()'{$ENDIF};{$ENDIF}{$ENDIF} +procedure TIdMessageHelper_LoadFromStream(AMsg: TIdMessage; AStream: TStream; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); {$IFDEF HAS_CLASS_HELPER}{$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use TIdMessageHelper.LoadFromStream()'{$ENDIF};{$ENDIF}{$ENDIF} +procedure TIdMessageHelper_SaveToFile(AMsg: TIdMessage; const AFileName: string; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); {$IFDEF HAS_CLASS_HELPER}{$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use TIdMessageHelper.SaveToFile()'{$ENDIF};{$ENDIF}{$ENDIF} +procedure TIdMessageHelper_SaveToStream(AMsg: TIdMessage; AStream: TStream; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); {$IFDEF HAS_CLASS_HELPER}{$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use TIdMessageHelper.SaveToStream()'{$ENDIF};{$ENDIF}{$ENDIF} + +implementation + +uses + IdGlobal, IdMessageClient, SysUtils, IdResourceStringsProtocols; + +{ TIdMessageClientHelper } + +procedure Internal_TIdMessageClientHelper_ProcessMessage(AClient: TIdMessageClient; + AMsg: TIdMessage; AStream: TStream; AHeaderOnly: Boolean; + AUsesDotTransparency: Boolean); +var + LIOHandler: TIdIOHandlerStreamMsg; +begin + if AUsesDotTransparency then begin + AClient.ProcessMessage(AMsg, AStream, AHeaderOnly); + end else + begin + LIOHandler := TIdIOHandlerStreamMsg.Create(nil, AStream); + try + LIOHandler.FreeStreams := False; + LIOHandler.EscapeLines := True; // <-- this is the key! + AClient.IOHandler := LIOHandler; + try + LIOHandler.Open; + AClient.ProcessMessage(AMsg, AHeaderOnly); + finally + AClient.IOHandler := nil; + end; + finally + LIOHandler.Free; + end; + end; +end; + +{ TIdMessageHelper } + +procedure Internal_TIdMessageHelper_LoadFromStream(AMsg: TIdMessage; AStream: TStream; + const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); +var + LMsgClient: TIdMessageClient; +begin + if AUsesDotTransparency then begin + AMsg.LoadFromStream(AStream, AHeadersOnly); + end else + begin + // clear message properties, headers before loading + AMsg.Clear; + LMsgClient := TIdMessageClient.Create; + try + Internal_TIdMessageClientHelper_ProcessMessage(LMsgClient, AMsg, AStream, AHeadersOnly, False); + finally + LMsgClient.Free; + end; + end; +end; + +{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOff.inc}{$ENDIF} +procedure TIdMessageHelper_LoadFromStream(AMsg: TIdMessage; AStream: TStream; + const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); +{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOn.inc}{$ENDIF} +begin + Internal_TIdMessageHelper_LoadFromStream(AMsg, AStream, AHeadersOnly, AUsesDotTransparency); +end; + +{$IFDEF HAS_CLASS_HELPER} +procedure TIdMessageHelper.LoadFromStream(AStream: TStream; const AHeadersOnly: Boolean; + const AUsesDotTransparency: Boolean); +begin + Internal_TIdMessageHelper_LoadFromStream(Self, AStream, AHeadersOnly, AUsesDotTransparency); +end; +{$ENDIF} + +procedure Internal_TIdMessageHelper_LoadFromFile(AMsg: TIdMessage; const AFileName: string; + const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); +var + LStream: TIdReadFileExclusiveStream; +begin + if AUsesDotTransparency then begin + AMsg.LoadFromFile(AFileName, AHeadersOnly); + end else + begin + try + LStream := TIdReadFileExclusiveStream.Create(AFilename); + except + LStream := nil; // keep the compiler happy + IndyRaiseOuterException(EIdMessageCannotLoad.CreateFmt(RSIdMessageCannotLoad, [AFilename])); + end; + try + Internal_TIdMessageHelper_LoadFromStream(AMsg, LStream, AHeadersOnly, False); + finally + LStream.Free; + end; + end; +end; + +{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOff.inc}{$ENDIF} +procedure TIdMessageHelper_LoadFromFile(AMsg: TIdMessage; const AFileName: string; + const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); +{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOn.inc}{$ENDIF} +begin + Internal_TIdMessageHelper_LoadFromFile(AMsg, AFileName, AHeadersOnly, AUsesDotTransparency); +end; + +{$IFDEF HAS_CLASS_HELPER} +procedure TIdMessageHelper.LoadFromFile(const AFileName: string; const AHeadersOnly: Boolean; const AUsesDotTransparency: Boolean); +begin + Internal_TIdMessageHelper_LoadFromFile(Self, AFileName, AHeadersOnly, AUsesDotTransparency); +end; +{$ENDIF} + +procedure Internal_TIdMessageHelper_SaveToStream(AMsg: TIdMessage; AStream: TStream; + const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); +var + LMsgClient: TIdMessageClient; + LIOHandler: TIdIOHandlerStreamMsg; +begin + if AUseDotTransparency then begin + AMsg.SaveToStream(AStream, AHeadersOnly); + end else + begin + LMsgClient := TIdMessageClient.Create(nil); + try + LIOHandler := TIdIOHandlerStreamMsg.Create(nil, nil, AStream); + try + LIOHandler.FreeStreams := False; + LIOHandler.UnescapeLines := True; // <-- this is the key! + LMsgClient.IOHandler := LIOHandler; + try + LMsgClient.SendMsg(AMsg, AHeadersOnly); + { + // add the end of message marker when body is included + if not AHeadersOnly then begin + LIOHandler.WriteLn('.'); {do not localize + end; + } + finally + LMsgClient.IOHandler := nil; + end; + finally + LIOHandler.Free; + end; + finally + LMsgClient.Free; + end; + end; +end; + +{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOff.inc}{$ENDIF} +procedure TIdMessageHelper_SaveToStream(AMsg: TIdMessage; AStream: TStream; + const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); +{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOn.inc}{$ENDIF} +begin + Internal_TIdMessageHelper_SaveToStream(AMsg, AStream, AHeadersOnly, AUseDotTransparency); +end; + +{$IFDEF HAS_CLASS_HELPER} +procedure TIdMessageHelper.SaveToStream(AStream: TStream; const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); +begin + Internal_TIdMessageHelper_SaveToStream(Self, AStream, AHeadersOnly, AUseDotTransparency); +end; +{$ENDIF} + +type + TIdMessageAccess = class(TIdMessage) + end; + +procedure Internal_TIdMessageHelper_SaveToFile(AMsg: TIdMessage; const AFileName: string; + const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); +var + LStream : TFileStream; + LMsgAccess: TIdMessageAccess; +begin + if AUseDotTransparency then begin + AMsg.SaveToFile(AFileName, AHeadersOnly); + end else + begin + LStream := TIdFileCreateStream.Create(AFileName); + try + {$I IdObjectChecksOff.inc} + LMsgAccess := TIdMessageAccess(AMsg); + {$I IdObjectChecksOn.inc} + + LMsgAccess.FSavingToFile := True; + try + Internal_TIdMessageHelper_SaveToStream(AMsg, LStream, AHeadersOnly, False); + finally + LMsgAccess.FSavingToFile := False; + end; + finally + LStream.Free; + end; + end; +end; + +{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOff.inc}{$ENDIF} +procedure TIdMessageHelper_SaveToFile(AMsg: TIdMessage; const AFileName: string; + const AHeadersOnly: Boolean; const AUseDotTransparency: Boolean); +{$IFDEF HAS_CLASS_HELPER}{$I IdDeprecatedImplBugOn.inc}{$ENDIF} +begin + Internal_TIdMessageHelper_SaveToFile(AMsg, AFileName, AHeadersOnly, AUseDotTransparency); +end; + +{$IFDEF HAS_CLASS_HELPER} +procedure TIdMessageHelper.SaveToFile(const AFileName: string; const AHeadersOnly: Boolean; + const AUseDotTransparency: Boolean); +begin + Internal_TIdMessageHelper_SaveToFile(Self, AFileName, AHeadersOnly, AUseDotTransparency); +end; +{$ENDIF} + end. \ No newline at end of file diff --git a/Lib/Protocols/IdProtocols90ASM90.inc b/Lib/Protocols/IdProtocols90ASM90.inc index 75bc946f0..470cdf5f4 100644 --- a/Lib/Protocols/IdProtocols90ASM90.inc +++ b/Lib/Protocols/IdProtocols90ASM90.inc @@ -1,12 +1,12 @@ -[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Protocols Run-Time Package for Borland Developer Studio')] -[assembly: AssemblyConfiguration('')] -[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] -[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyTrademark('')] -[assembly: AssemblyCulture('')] -[assembly: AssemblyTitle('Indy .NET Protocols Run-Time Package')] -[assembly: AssemblyVersion('10.7.0.*')] -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile('')] -[assembly: AssemblyKeyName('')] +[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Protocols Run-Time Package for Borland Developer Studio')] +[assembly: AssemblyConfiguration('')] +[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] +[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyTrademark('')] +[assembly: AssemblyCulture('')] +[assembly: AssemblyTitle('Indy .NET Protocols Run-Time Package')] +[assembly: AssemblyVersion('10.7.0.*')] +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile('')] +[assembly: AssemblyKeyName('')] diff --git a/Lib/Protocols/IdSSH.pas b/Lib/Protocols/IdSSH.pas index 7041275a8..55542179f 100644 --- a/Lib/Protocols/IdSSH.pas +++ b/Lib/Protocols/IdSSH.pas @@ -1,179 +1,179 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.0 4/6/2003 04:35:12 PM JPMugaas -} -{ - Note that this unit is for defining Base classes for SSH implementers. - - Much of this is a Cut and Paste job from Indy 10's Base SSL classes. We make - this separate in case we have to treat SSH far differently than SSL. -} - -unit IdSSH; - -interface - -{$i IdCompilerDefines.inc} - -uses - Classes, - IdContainers, - IdYarn, - IdGlobalCore, - IdIOHandler, - IdIOHandlerSocket, - IdIOHandlerStack, - IdScheduler, - IdServerIOHandler; - -type - //client - TIdSSHIOHandlerSocketBase = class(TIdIOHandlerStack) - protected - fPassThrough: Boolean; - fIsPeer : Boolean; - procedure InitComponent; override; - procedure SetPassThrough(const AValue: Boolean); virtual; - public - function Clone : TIdSSHIOHandlerSocketBase; virtual; abstract; - procedure StartSSH; virtual; abstract; - property PassThrough: Boolean read fPassThrough write SetPassThrough; - property IsPeer : Boolean read fIsPeer write fIsPeer; - end; - - //server - TIdServerIOHandlerSSHBase = class(TIdServerIOHandler) - protected - public - //this is for the FTP Server to make a client IOHandler for it's data connection's IOHandler - function MakeClientIOHandler(ATheThread:TIdYarn ): TIdIOHandler; overload; override; - function MakeClientIOHandler : TIdSSHIOHandlerSocketBase; reintroduce; overload; virtual; abstract; - function MakeFTPSvrPort : TIdSSHIOHandlerSocketBase; virtual; abstract; - function MakeFTPSvrPasv : TIdSSHIOHandlerSocketBase; virtual; abstract; - end; - -type - TIdClientSSHClass = class of TIdSSHIOHandlerSocketBase; - TIdServerSSHClass = class of TIdServerIOHandlerSSHBase; - -Procedure RegisterSSH(const AProduct, AVendor, ACopyright, - ADescription, AURL : String; - const AClientClass : TIdClientSSHClass; const AServerClass : TIdServerSSHClass); - -type - TIdSSHRegEntry = class(TCollectionItem) - protected - FProductName : String; - FVendor : String; - FCopyright : String; - FDescription : String; - FURL : String; - FClientClass : TIdClientSSHClass; - FServerClass : TIdServerSSHClass; - public - property ProductName : String read FProductName write FProductName; - property Vendor : String read FVendor write FVendor; - property Copyright : String read FCopyright write FCopyright; - property Description : String read FDescription write FDescription; - property URL : String read FURL write FURL; - property ClientClass : TIdClientSSHClass read FClientClass write FClientClass; - property ServerClass : TIdServerSSHClass read FServerClass write FServerClass; - end; - - TIdSSHRegistry = class(TCollection) - protected - function GetItem ( Index: Integer ) : TIdSSHRegEntry; - procedure SetItem ( Index: Integer; const Value: TIdSSHRegEntry ); - public - constructor Create; reintroduce; - function Add: TIdSSHRegEntry; - property Items [ Index: Integer ] : TIdSSHRegEntry read GetItem - write SetItem; default; - end; - -var - GSSHRegistry : TIdSSHRegistry; - -implementation - -uses SysUtils; - -Procedure RegisterSSH(const AProduct, AVendor, ACopyright, - ADescription, AURL : String; - const AClientClass : TIdClientSSHClass; const AServerClass : TIdServerSSHClass); -var LR : TIdSSHRegEntry; -begin - LR := GSSHRegistry.Add; - LR.ProductName := AProduct; - LR.Vendor := AVendor; - LR.Copyright := ACopyRight; - LR.Description := ADescription; - LR.URL := AURL; - LR.ClientClass := AClientClass; - LR.ServerClass := AServerClass; -end; - -{ TIdSSHIOHandlerSocketBase } - -procedure TIdSSHIOHandlerSocketBase.InitComponent; -begin - inherited; - fPassThrough := True; -end; - -procedure TIdSSHIOHandlerSocketBase.SetPassThrough(const AValue: Boolean); -begin - fPassThrough := AValue; -end; - -{ TIdServerIOHandlerSSHBase } - -function TIdServerIOHandlerSSHBase.MakeClientIOHandler(ATheThread:TIdYarn ): TIdIOHandler; -begin - Result := MakeClientIOHandler; -end; - -{ TIdSSHRegistry } - -function TIdSSHRegistry.Add: TIdSSHRegEntry; -begin - Result := TIdSSHRegEntry( inherited Add ); -end; - -constructor TIdSSHRegistry.Create; -begin - inherited Create(TIdSSHRegEntry); -end; - -function TIdSSHRegistry.GetItem(Index: Integer): TIdSSHRegEntry; -begin - Result := TIdSSHRegEntry ( inherited GetItem(Index) ); -end; - -procedure TIdSSHRegistry.SetItem(Index: Integer; - const Value: TIdSSHRegEntry); -begin - inherited SetItem(Index,Value); -end; - -initialization - GSSHRegistry := TIdSSHRegistry.Create; -finalization - FreeAndNil(GSSHRegistry); -end. +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.0 4/6/2003 04:35:12 PM JPMugaas +} +{ + Note that this unit is for defining Base classes for SSH implementers. + + Much of this is a Cut and Paste job from Indy 10's Base SSL classes. We make + this separate in case we have to treat SSH far differently than SSL. +} + +unit IdSSH; + +interface + +{$i IdCompilerDefines.inc} + +uses + Classes, + IdContainers, + IdYarn, + IdGlobalCore, + IdIOHandler, + IdIOHandlerSocket, + IdIOHandlerStack, + IdScheduler, + IdServerIOHandler; + +type + //client + TIdSSHIOHandlerSocketBase = class(TIdIOHandlerStack) + protected + fPassThrough: Boolean; + fIsPeer : Boolean; + procedure InitComponent; override; + procedure SetPassThrough(const AValue: Boolean); virtual; + public + function Clone : TIdSSHIOHandlerSocketBase; virtual; abstract; + procedure StartSSH; virtual; abstract; + property PassThrough: Boolean read fPassThrough write SetPassThrough; + property IsPeer : Boolean read fIsPeer write fIsPeer; + end; + + //server + TIdServerIOHandlerSSHBase = class(TIdServerIOHandler) + protected + public + //this is for the FTP Server to make a client IOHandler for it's data connection's IOHandler + function MakeClientIOHandler(ATheThread:TIdYarn ): TIdIOHandler; overload; override; + function MakeClientIOHandler : TIdSSHIOHandlerSocketBase; reintroduce; overload; virtual; abstract; + function MakeFTPSvrPort : TIdSSHIOHandlerSocketBase; virtual; abstract; + function MakeFTPSvrPasv : TIdSSHIOHandlerSocketBase; virtual; abstract; + end; + +type + TIdClientSSHClass = class of TIdSSHIOHandlerSocketBase; + TIdServerSSHClass = class of TIdServerIOHandlerSSHBase; + +Procedure RegisterSSH(const AProduct, AVendor, ACopyright, + ADescription, AURL : String; + const AClientClass : TIdClientSSHClass; const AServerClass : TIdServerSSHClass); + +type + TIdSSHRegEntry = class(TCollectionItem) + protected + FProductName : String; + FVendor : String; + FCopyright : String; + FDescription : String; + FURL : String; + FClientClass : TIdClientSSHClass; + FServerClass : TIdServerSSHClass; + public + property ProductName : String read FProductName write FProductName; + property Vendor : String read FVendor write FVendor; + property Copyright : String read FCopyright write FCopyright; + property Description : String read FDescription write FDescription; + property URL : String read FURL write FURL; + property ClientClass : TIdClientSSHClass read FClientClass write FClientClass; + property ServerClass : TIdServerSSHClass read FServerClass write FServerClass; + end; + + TIdSSHRegistry = class(TCollection) + protected + function GetItem ( Index: Integer ) : TIdSSHRegEntry; + procedure SetItem ( Index: Integer; const Value: TIdSSHRegEntry ); + public + constructor Create; reintroduce; + function Add: TIdSSHRegEntry; + property Items [ Index: Integer ] : TIdSSHRegEntry read GetItem + write SetItem; default; + end; + +var + GSSHRegistry : TIdSSHRegistry; + +implementation + +uses SysUtils; + +Procedure RegisterSSH(const AProduct, AVendor, ACopyright, + ADescription, AURL : String; + const AClientClass : TIdClientSSHClass; const AServerClass : TIdServerSSHClass); +var LR : TIdSSHRegEntry; +begin + LR := GSSHRegistry.Add; + LR.ProductName := AProduct; + LR.Vendor := AVendor; + LR.Copyright := ACopyRight; + LR.Description := ADescription; + LR.URL := AURL; + LR.ClientClass := AClientClass; + LR.ServerClass := AServerClass; +end; + +{ TIdSSHIOHandlerSocketBase } + +procedure TIdSSHIOHandlerSocketBase.InitComponent; +begin + inherited; + fPassThrough := True; +end; + +procedure TIdSSHIOHandlerSocketBase.SetPassThrough(const AValue: Boolean); +begin + fPassThrough := AValue; +end; + +{ TIdServerIOHandlerSSHBase } + +function TIdServerIOHandlerSSHBase.MakeClientIOHandler(ATheThread:TIdYarn ): TIdIOHandler; +begin + Result := MakeClientIOHandler; +end; + +{ TIdSSHRegistry } + +function TIdSSHRegistry.Add: TIdSSHRegEntry; +begin + Result := TIdSSHRegEntry( inherited Add ); +end; + +constructor TIdSSHRegistry.Create; +begin + inherited Create(TIdSSHRegEntry); +end; + +function TIdSSHRegistry.GetItem(Index: Integer): TIdSSHRegEntry; +begin + Result := TIdSSHRegEntry ( inherited GetItem(Index) ); +end; + +procedure TIdSSHRegistry.SetItem(Index: Integer; + const Value: TIdSSHRegEntry); +begin + inherited SetItem(Index,Value); +end; + +initialization + GSSHRegistry := TIdSSHRegistry.Create; +finalization + FreeAndNil(GSSHRegistry); +end. diff --git a/Lib/Protocols/IdSSL.pas b/Lib/Protocols/IdSSL.pas index e255c72a3..fa244ca74 100644 --- a/Lib/Protocols/IdSSL.pas +++ b/Lib/Protocols/IdSSL.pas @@ -1,310 +1,310 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.11 2004.02.03 5:45:36 PM czhower - Name changes - - Rev 1.10 10/5/2003 11:44:06 PM GGrieve - Remove IdContainers - - Rev 1.9 9/18/2003 10:20:28 AM JPMugaas - Updated for new API. - - Rev 1.8 3/30/2003 12:38:56 AM BGooijen - Removed warning - - Rev 1.7 3/30/2003 12:15:12 AM BGooijen - Added MakeFTPSvrPort/MakeFTPSvrPasv - - Rev 1.6 3/23/2003 11:44:24 PM BGooijen - Added MakeClientIOHandler(ATheThread:TIdThreadHandle ):... - - Rev 1.5 3/14/2003 10:00:36 PM BGooijen - Removed TIdServerIOHandlerSSLBase.PeerPassthrough, the ssl is now enabled in - the server-protocol-files - - Rev 1.3 3/13/2003 09:14:44 PM JPMugaas - Added property suggested by Henrick Hellström (StreamSec) for checking a - certificate against a URL provided by a user. - - Rev 1.2 3/13/2003 11:55:44 AM JPMugaas - Updated registration framework to give more information. - - Rev 1.1 3/13/2003 4:08:42 PM BGooijen - classes -> Classes - - Rev 1.0 3/13/2003 09:51:18 AM JPMugaas - Abstract SSL class to permit the clients and servers to use OpenSSL or - third-party components SSL IOHandler. -} - -unit IdSSL; - -interface - -{$i IdCompilerDefines.inc} - -uses - Classes, - IdGlobal, - IdIOHandler, - IdIOHandlerSocket, - IdIOHandlerStack, - IdServerIOHandler, - IdYarn; - -type - //client - TIdSSLIOHandlerSocketBase = class(TIdIOHandlerStack) - protected - fPassThrough: Boolean; - fIsPeer : Boolean; - FURIToCheck : String; - function GetProxyTargetHost: string; - function GetURIHost : string; - procedure InitComponent; override; - function RecvEnc(var ABuffer: TIdBytes): Integer; virtual; abstract; - function SendEnc(const ABuffer: TIdBytes; const AOffset, ALength: Integer): Integer; virtual; abstract; - function ReadDataFromSource(var VBuffer: TIdBytes): Integer; override; - function WriteDataToTarget(const ABuffer: TIdBytes; const AOffset, ALength: Integer): Integer; override; - procedure SetPassThrough(const AValue: Boolean); virtual; - procedure SetURIToCheck(const AValue: String); virtual; - public - // TODO: add an AOwner parameter - function Clone : TIdSSLIOHandlerSocketBase; virtual; abstract; - procedure StartSSL; virtual; abstract; - property PassThrough: Boolean read fPassThrough write SetPassThrough; - property IsPeer : Boolean read fIsPeer write fIsPeer; - { -Pasted from private corresponance from Henrick Hellström - StreamSec http://www.streamsec.com - - This property should be set to the exact value of the URI passed to e.g. -TIdHTTP.Get and should not be used or modified by any code outside of -the SSL handler implementation units. The reason for this is that the -SSL/TLS handler should verify that the URI entered by the client user -matches the identity information present in the server certificate. - } - property URIToCheck : String read FURIToCheck write SetURIToCheck; - end; - - //server - TIdServerIOHandlerSSLBase = class(TIdServerIOHandler) - protected - public - //this is for the FTP Server to make a client IOHandler for it's data connection's IOHandler - function MakeClientIOHandler(ATheThread:TIdYarn ): TIdIOHandler; overload; override; - function MakeClientIOHandler : TIdSSLIOHandlerSocketBase; reintroduce; overload; virtual; abstract; - function MakeFTPSvrPort : TIdSSLIOHandlerSocketBase; virtual; abstract; - function MakeFTPSvrPasv : TIdSSLIOHandlerSocketBase; virtual; abstract; - end; - -type - TIdClientSSLClass = class of TIdSSLIOHandlerSocketBase; - TIdServerSSLClass = class of TIdServerIOHandlerSSLBase; - -type - TIdSSLVersion = (sslvSSLv2, sslvSSLv23, sslvSSLv3, sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2, sslvTLSv1_3); - TIdSSLVersions = set of TIdSSLVersion; - TIdSSLMode = (sslmUnassigned, sslmClient, sslmServer, sslmBoth); - TIdSSLCtxMode = (sslCtxClient, sslCtxServer); - TIdSSLAction = (sslRead, sslWrite); - -Procedure RegisterSSL(const AProduct, AVendor, ACopyright, - ADescription, AURL : String; - const AClientClass : TIdClientSSLClass; const AServerClass : TIdServerSSLClass); {$IFDEF HAS_DEPRECATED}deprecated;{$ENDIF} - -type - TIdSSLRegEntry = class(TCollectionItem) - protected - FProductName : String; - FVendor : String; - FCopyright : String; - FDescription : String; - FURL : String; - FClientClass : TIdClientSSLClass; - FServerClass : TIdServerSSLClass; - public - property ProductName : String read FProductName write FProductName; - property Vendor : String read FVendor write FVendor; - property Copyright : String read FCopyright write FCopyright; - property Description : String read FDescription write FDescription; - property URL : String read FURL write FURL; - property ClientClass : TIdClientSSLClass read FClientClass write FClientClass; - property ServerClass : TIdServerSSLClass read FServerClass write FServerClass; - end {$IFDEF HAS_DEPRECATED}deprecated{$ENDIF}; - - {$I IdSymbolDeprecatedOff.inc} - - TIdSSLRegistry = class(TCollection) - protected - function GetItem ( Index: Integer ) : TIdSSLRegEntry; - procedure SetItem ( Index: Integer; const Value: TIdSSLRegEntry ); - public - constructor Create; reintroduce; - function Add: TIdSSLRegEntry; - property Items [ Index: Integer ] : TIdSSLRegEntry read GetItem - write SetItem; default; - end {$IFDEF HAS_DEPRECATED}deprecated{$ENDIF}; - -var - GSSLRegistry : TIdSSLRegistry{$IFDEF HAS_DEPRECATED}{$IFDEF USE_SEMICOLON_BEFORE_DEPRECATED};{$ENDIF} deprecated{$ENDIF}; - - {$I IdSymbolDeprecatedOn.inc} - -implementation - -uses - SysUtils, IdCustomTransparentProxy, IdURI; - -{$I IdSymbolDeprecatedOff.inc} - -Procedure RegisterSSL(const AProduct, AVendor, ACopyright, - ADescription, AURL : String; - const AClientClass : TIdClientSSLClass; const AServerClass : TIdServerSSLClass); -var - LR : TIdSSLRegEntry; -begin - LR := GSSLRegistry.Add; - LR.ProductName := AProduct; - LR.Vendor := AVendor; - LR.Copyright := ACopyRight; - LR.Description := ADescription; - LR.URL := AURL; - LR.ClientClass := AClientClass; - LR.ServerClass := AServerClass; -end; - -{$I IdSymbolDeprecatedOn.inc} - -{ TIdSSLIOHandlerSocketBase } - -function TIdSSLIOHandlerSocketBase.GetProxyTargetHost: string; -var - // under ARC, convert a weak reference to a strong reference before working with it - LTransparentProxy, LNextTransparentProxy: TIdCustomTransparentProxy; -begin - Result := ''; - // RLebeau: not reading from the property as it will create a - // default Proxy object if one is not already assigned... - LTransparentProxy := FTransparentProxy; - if Assigned(LTransparentProxy) then - begin - if LTransparentProxy.Enabled then - begin - repeat - LNextTransparentProxy := LTransparentProxy.ChainedProxy; - if not Assigned(LNextTransparentProxy) then - Break; - if not LNextTransparentProxy.Enabled then - Break; - LTransparentProxy := LNextTransparentProxy; - until False; - Result := LTransparentProxy.Host; - end; - end; - -end; - -function TIdSSLIOHandlerSocketBase.GetURIHost : string; -var - LURI: TIdURI; -begin - Result := ''; - if URIToCheck <> '' then - begin - LURI := TIdURI.Create(URIToCheck); - try - Result := LURI.Host; - finally - LURI.Free; - end; - end; -end; - -procedure TIdSSLIOHandlerSocketBase.InitComponent; -begin - inherited; - fPassThrough := True; -end; - -function TIdSSLIOHandlerSocketBase.ReadDataFromSource(var VBuffer: TIdBytes): Integer; -begin - if PassThrough then begin - Result := inherited ReadDataFromSource(VBuffer); - end else begin - Result := RecvEnc(VBuffer); - end; -end; - -function TIdSSLIOHandlerSocketBase.WriteDataToTarget(const ABuffer: TIdBytes; - const AOffset, ALength: Integer): Integer; -begin - if PassThrough then begin - Result := inherited WriteDataToTarget(ABuffer, AOffset, ALength); - end else begin - Result := SendEnc(ABuffer, AOffset, ALength); - end; -end; - -procedure TIdSSLIOHandlerSocketBase.SetPassThrough(const AValue: Boolean); -begin - fPassThrough := AValue; -end; - -procedure TIdSSLIOHandlerSocketBase.SetURIToCheck(const AValue: String); -begin - FURIToCheck := AValue; -end; - -{ TIdServerIOHandlerSSLBase } - -function TIdServerIOHandlerSSLBase.MakeClientIOHandler(ATheThread:TIdYarn ): TIdIOHandler; -begin - Result := MakeClientIOHandler; -end; - -{ TIdSSLRegistry } - -{$I IdSymbolDeprecatedOff.inc} - -function TIdSSLRegistry.Add: TIdSSLRegEntry; -begin - Result := TIdSSLRegEntry( inherited Add ); -end; - -constructor TIdSSLRegistry.Create; -begin - inherited Create(TIdSSLRegEntry); -end; - -function TIdSSLRegistry.GetItem(Index: Integer): TIdSSLRegEntry; -begin - Result := TIdSSLRegEntry ( inherited GetItem(Index) ); -end; - -procedure TIdSSLRegistry.SetItem(Index: Integer; - const Value: TIdSSLRegEntry); -begin - inherited SetItem(Index,Value); -end; - -initialization - GSSLRegistry := TIdSSLRegistry.Create; -finalization - FreeAndNil(GSSLRegistry); -end. +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.11 2004.02.03 5:45:36 PM czhower + Name changes + + Rev 1.10 10/5/2003 11:44:06 PM GGrieve + Remove IdContainers + + Rev 1.9 9/18/2003 10:20:28 AM JPMugaas + Updated for new API. + + Rev 1.8 3/30/2003 12:38:56 AM BGooijen + Removed warning + + Rev 1.7 3/30/2003 12:15:12 AM BGooijen + Added MakeFTPSvrPort/MakeFTPSvrPasv + + Rev 1.6 3/23/2003 11:44:24 PM BGooijen + Added MakeClientIOHandler(ATheThread:TIdThreadHandle ):... + + Rev 1.5 3/14/2003 10:00:36 PM BGooijen + Removed TIdServerIOHandlerSSLBase.PeerPassthrough, the ssl is now enabled in + the server-protocol-files + + Rev 1.3 3/13/2003 09:14:44 PM JPMugaas + Added property suggested by Henrick Hellström (StreamSec) for checking a + certificate against a URL provided by a user. + + Rev 1.2 3/13/2003 11:55:44 AM JPMugaas + Updated registration framework to give more information. + + Rev 1.1 3/13/2003 4:08:42 PM BGooijen + classes -> Classes + + Rev 1.0 3/13/2003 09:51:18 AM JPMugaas + Abstract SSL class to permit the clients and servers to use OpenSSL or + third-party components SSL IOHandler. +} + +unit IdSSL; + +interface + +{$i IdCompilerDefines.inc} + +uses + Classes, + IdGlobal, + IdIOHandler, + IdIOHandlerSocket, + IdIOHandlerStack, + IdServerIOHandler, + IdYarn; + +type + //client + TIdSSLIOHandlerSocketBase = class(TIdIOHandlerStack) + protected + fPassThrough: Boolean; + fIsPeer : Boolean; + FURIToCheck : String; + function GetProxyTargetHost: string; + function GetURIHost : string; + procedure InitComponent; override; + function RecvEnc(var ABuffer: TIdBytes): Integer; virtual; abstract; + function SendEnc(const ABuffer: TIdBytes; const AOffset, ALength: Integer): Integer; virtual; abstract; + function ReadDataFromSource(var VBuffer: TIdBytes): Integer; override; + function WriteDataToTarget(const ABuffer: TIdBytes; const AOffset, ALength: Integer): Integer; override; + procedure SetPassThrough(const AValue: Boolean); virtual; + procedure SetURIToCheck(const AValue: String); virtual; + public + // TODO: add an AOwner parameter + function Clone : TIdSSLIOHandlerSocketBase; virtual; abstract; + procedure StartSSL; virtual; abstract; + property PassThrough: Boolean read fPassThrough write SetPassThrough; + property IsPeer : Boolean read fIsPeer write fIsPeer; + { +Pasted from private corresponance from Henrick Hellström - StreamSec http://www.streamsec.com + + This property should be set to the exact value of the URI passed to e.g. +TIdHTTP.Get and should not be used or modified by any code outside of +the SSL handler implementation units. The reason for this is that the +SSL/TLS handler should verify that the URI entered by the client user +matches the identity information present in the server certificate. + } + property URIToCheck : String read FURIToCheck write SetURIToCheck; + end; + + //server + TIdServerIOHandlerSSLBase = class(TIdServerIOHandler) + protected + public + //this is for the FTP Server to make a client IOHandler for it's data connection's IOHandler + function MakeClientIOHandler(ATheThread:TIdYarn ): TIdIOHandler; overload; override; + function MakeClientIOHandler : TIdSSLIOHandlerSocketBase; reintroduce; overload; virtual; abstract; + function MakeFTPSvrPort : TIdSSLIOHandlerSocketBase; virtual; abstract; + function MakeFTPSvrPasv : TIdSSLIOHandlerSocketBase; virtual; abstract; + end; + +type + TIdClientSSLClass = class of TIdSSLIOHandlerSocketBase; + TIdServerSSLClass = class of TIdServerIOHandlerSSLBase; + +type + TIdSSLVersion = (sslvSSLv2, sslvSSLv23, sslvSSLv3, sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2, sslvTLSv1_3); + TIdSSLVersions = set of TIdSSLVersion; + TIdSSLMode = (sslmUnassigned, sslmClient, sslmServer, sslmBoth); + TIdSSLCtxMode = (sslCtxClient, sslCtxServer); + TIdSSLAction = (sslRead, sslWrite); + +Procedure RegisterSSL(const AProduct, AVendor, ACopyright, + ADescription, AURL : String; + const AClientClass : TIdClientSSLClass; const AServerClass : TIdServerSSLClass); {$IFDEF HAS_DEPRECATED}deprecated;{$ENDIF} + +type + TIdSSLRegEntry = class(TCollectionItem) + protected + FProductName : String; + FVendor : String; + FCopyright : String; + FDescription : String; + FURL : String; + FClientClass : TIdClientSSLClass; + FServerClass : TIdServerSSLClass; + public + property ProductName : String read FProductName write FProductName; + property Vendor : String read FVendor write FVendor; + property Copyright : String read FCopyright write FCopyright; + property Description : String read FDescription write FDescription; + property URL : String read FURL write FURL; + property ClientClass : TIdClientSSLClass read FClientClass write FClientClass; + property ServerClass : TIdServerSSLClass read FServerClass write FServerClass; + end {$IFDEF HAS_DEPRECATED}deprecated{$ENDIF}; + + {$I IdSymbolDeprecatedOff.inc} + + TIdSSLRegistry = class(TCollection) + protected + function GetItem ( Index: Integer ) : TIdSSLRegEntry; + procedure SetItem ( Index: Integer; const Value: TIdSSLRegEntry ); + public + constructor Create; reintroduce; + function Add: TIdSSLRegEntry; + property Items [ Index: Integer ] : TIdSSLRegEntry read GetItem + write SetItem; default; + end {$IFDEF HAS_DEPRECATED}deprecated{$ENDIF}; + +var + GSSLRegistry : TIdSSLRegistry{$IFDEF HAS_DEPRECATED}{$IFDEF USE_SEMICOLON_BEFORE_DEPRECATED};{$ENDIF} deprecated{$ENDIF}; + + {$I IdSymbolDeprecatedOn.inc} + +implementation + +uses + SysUtils, IdCustomTransparentProxy, IdURI; + +{$I IdSymbolDeprecatedOff.inc} + +Procedure RegisterSSL(const AProduct, AVendor, ACopyright, + ADescription, AURL : String; + const AClientClass : TIdClientSSLClass; const AServerClass : TIdServerSSLClass); +var + LR : TIdSSLRegEntry; +begin + LR := GSSLRegistry.Add; + LR.ProductName := AProduct; + LR.Vendor := AVendor; + LR.Copyright := ACopyRight; + LR.Description := ADescription; + LR.URL := AURL; + LR.ClientClass := AClientClass; + LR.ServerClass := AServerClass; +end; + +{$I IdSymbolDeprecatedOn.inc} + +{ TIdSSLIOHandlerSocketBase } + +function TIdSSLIOHandlerSocketBase.GetProxyTargetHost: string; +var + // under ARC, convert a weak reference to a strong reference before working with it + LTransparentProxy, LNextTransparentProxy: TIdCustomTransparentProxy; +begin + Result := ''; + // RLebeau: not reading from the property as it will create a + // default Proxy object if one is not already assigned... + LTransparentProxy := FTransparentProxy; + if Assigned(LTransparentProxy) then + begin + if LTransparentProxy.Enabled then + begin + repeat + LNextTransparentProxy := LTransparentProxy.ChainedProxy; + if not Assigned(LNextTransparentProxy) then + Break; + if not LNextTransparentProxy.Enabled then + Break; + LTransparentProxy := LNextTransparentProxy; + until False; + Result := LTransparentProxy.Host; + end; + end; + +end; + +function TIdSSLIOHandlerSocketBase.GetURIHost : string; +var + LURI: TIdURI; +begin + Result := ''; + if URIToCheck <> '' then + begin + LURI := TIdURI.Create(URIToCheck); + try + Result := LURI.Host; + finally + LURI.Free; + end; + end; +end; + +procedure TIdSSLIOHandlerSocketBase.InitComponent; +begin + inherited; + fPassThrough := True; +end; + +function TIdSSLIOHandlerSocketBase.ReadDataFromSource(var VBuffer: TIdBytes): Integer; +begin + if PassThrough then begin + Result := inherited ReadDataFromSource(VBuffer); + end else begin + Result := RecvEnc(VBuffer); + end; +end; + +function TIdSSLIOHandlerSocketBase.WriteDataToTarget(const ABuffer: TIdBytes; + const AOffset, ALength: Integer): Integer; +begin + if PassThrough then begin + Result := inherited WriteDataToTarget(ABuffer, AOffset, ALength); + end else begin + Result := SendEnc(ABuffer, AOffset, ALength); + end; +end; + +procedure TIdSSLIOHandlerSocketBase.SetPassThrough(const AValue: Boolean); +begin + fPassThrough := AValue; +end; + +procedure TIdSSLIOHandlerSocketBase.SetURIToCheck(const AValue: String); +begin + FURIToCheck := AValue; +end; + +{ TIdServerIOHandlerSSLBase } + +function TIdServerIOHandlerSSLBase.MakeClientIOHandler(ATheThread:TIdYarn ): TIdIOHandler; +begin + Result := MakeClientIOHandler; +end; + +{ TIdSSLRegistry } + +{$I IdSymbolDeprecatedOff.inc} + +function TIdSSLRegistry.Add: TIdSSLRegEntry; +begin + Result := TIdSSLRegEntry( inherited Add ); +end; + +constructor TIdSSLRegistry.Create; +begin + inherited Create(TIdSSLRegEntry); +end; + +function TIdSSLRegistry.GetItem(Index: Integer): TIdSSLRegEntry; +begin + Result := TIdSSLRegEntry ( inherited GetItem(Index) ); +end; + +procedure TIdSSLRegistry.SetItem(Index: Integer; + const Value: TIdSSLRegEntry); +begin + inherited SetItem(Index,Value); +end; + +initialization + GSSLRegistry := TIdSSLRegistry.Create; +finalization + FreeAndNil(GSSLRegistry); +end. diff --git a/Lib/Protocols/IdSSPI.pas b/Lib/Protocols/IdSSPI.pas index 9aefcf4d9..38ade4c1b 100644 --- a/Lib/Protocols/IdSSPI.pas +++ b/Lib/Protocols/IdSSPI.pas @@ -1,2902 +1,2902 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.1 13.1.2004 17:26:00 DBondzhev - Added Domain property - - Rev 1.0 11/13/2002 08:01:52 AM JPMugaas -} - -{ - SSPI interface and objects Unit - Copyright (c) 1999-2001, Eventree Systems - Translator: Eventree Systems - - this unit contains translation of: - Security.h, sspi.h, secext.h, rpcdce.h (some of) -} - -unit IdSSPI; - -{$ALIGN ON} -{$MINENUMSIZE 4} - -interface - -{$i IdCompilerDefines.inc} -{$IFDEF USE_SSPI} - - -uses - IdGlobal, - Windows; - -type - PPVOID = ^PVOID; - {$NODEFINE PPVOID} - PVOID = Pointer; - {$NODEFINE PVOID} - - PUSHORT = ^USHORT; - {$NODEFINE PUSHORT} - USHORT = Word; - {$NODEFINE USHORT} - - PUCHAR = ^UCHAR; - {$NODEFINE PUCHAR} - UCHAR = Byte; - {$NODEFINE UCHAR} - -(*$HPPEMIT '//#define SECURITY_WIN32'*) -(*$HPPEMIT '#include '*) - -//+----------------------------------------------------------------------- -// -// Microsoft Windows -// -// Copyright (c) Microsoft Corporation 1991-1999 -// -// File: Security.h -// -// Contents: Toplevel include file for security aware components -// -// -// History: 06 Aug 92 RichardW Created -// 23 Sep 92 PeterWi Add security object include files -// -//------------------------------------------------------------------------ - -// -// These are name that can be used to refer to the builtin packages -// - -const - - NTLMSP_NAME = 'NTLM'; {Do not Localize} - {$EXTERNALSYM NTLMSP_NAME} - - MICROSOFT_KERBEROS_NAME = 'Kerberos'; {Do not Localize} - {$EXTERNALSYM MICROSOFT_KERBEROS_NAME} - - NEGOSSP_NAME = 'Negotiate'; {Do not Localize} - {$EXTERNALSYM NEGOSSP_NAME} - -//+--------------------------------------------------------------------------- -// -// Microsoft Windows -// Copyright (C) Microsoft Corporation, 1992-1997. -// -// File: sspi.h -// -// Contents: Security Support Provider Interface -// Prototypes and structure definitions -// -// Functions: Security Support Provider API -// -// History: 11-24-93 RichardW Created -// -//---------------------------------------------------------------------------- - -type - - PSEC_WCHAR = PWideChar; - {$NODEFINE PSEC_WCHAR} - SEC_WCHAR = WideChar; - {$EXTERNALSYM SEC_WCHAR} - - PSEC_CHAR = PAnsiChar; - {$NODEFINE PSEC_CHAR} - SEC_CHAR = AnsiChar; - {$EXTERNALSYM SEC_CHAR} - - PSECURITY_STATUS = ^SECURITY_STATUS; - {$NODEFINE PSECURITY_STATUS} - SECURITY_STATUS = Longint{LONG}; // LONG is not defined in Windows.pas prior to Delphi 8 - {$EXTERNALSYM SECURITY_STATUS} - -// -// Decide what a string - 32 bits only since for 16 bits it is clear. -// - -type - {$IFDEF SSPI_UNICODE} - SECURITY_PSTR = ^SEC_WCHAR; - {$ELSE} - SECURITY_PSTR = ^SEC_CHAR; - {$ENDIF} - {$EXTERNALSYM SECURITY_PSTR} -// -// Okay, security specific types: -// - -type - - PSecHandle = ^SecHandle; - {$EXTERNALSYM PSecHandle} - //Define ULONG_PTR as PtrUInt so we can use this unit in FreePascal. - SecHandle = record - dwLower: PtrUInt; // ULONG_PTR - dwUpper: PtrUInt; // ULONG_PTR - end; - {$EXTERNALSYM SecHandle} - - CredHandle = SecHandle; - {$EXTERNALSYM CredHandle} - PCredHandle = PSecHandle; - {$EXTERNALSYM PCredHandle} - - CtxtHandle = SecHandle; - {$EXTERNALSYM CtxtHandle} - PCtxtHandle = PSecHandle; - {$EXTERNALSYM PCtxtHandle} - - PSECURITY_INTEGER = ^SECURITY_INTEGER; - {$EXTERNALSYM PSECURITY_INTEGER} - SECURITY_INTEGER = LARGE_INTEGER; - {$EXTERNALSYM SECURITY_INTEGER} - - PTimeStamp = ^TimeStamp; - {$EXTERNALSYM PTimeStamp} - TimeStamp = SECURITY_INTEGER; - {$EXTERNALSYM TimeStamp} - - procedure SecInvalidateHandle(var x: SecHandle); {$IFDEF USE_INLINE} inline; {$ENDIF} - {$EXTERNALSYM SecInvalidateHandle} - function SecIsValidHandle(x : SecHandle) : Boolean; {$IFDEF USE_INLINE} inline; {$ENDIF} - {$EXTERNALSYM SecIsValidHandle} - function SEC_SUCCESS(Status: SECURITY_STATUS): Boolean; {$IFDEF USE_INLINE} inline; {$ENDIF} - {$EXTERNALSYM SEC_SUCCESS} - -type - -// -// If we are in 32 bit mode, define the SECURITY_STRING structure, -// as a clone of the base UNICODE_STRING structure. This is used -// internally in security components, an as the string interface -// for kernel components (e.g. FSPs) -// - - PSECURITY_STRING = ^SECURITY_STRING; - {$EXTERNALSYM PSECURITY_STRING} - SECURITY_STRING = record - Length: USHORT; - MaximumLength: USHORT; - Buffer: PUSHORT; - end; - {$EXTERNALSYM SECURITY_STRING} - -// -// SecPkgInfo structure -// -// Provides general information about a security provider -// - -type - - PPSecPkgInfoW = ^PSecPkgInfoW; - {$NODEFINE PPSecPkgInfoW} - PSecPkgInfoW = ^SecPkgInfoW; - {$EXTERNALSYM PSecPkgInfoW} - SecPkgInfoW = record - fCapabilities: ULONG; // Capability bitmask - wVersion: USHORT; // Version of driver - wRPCID: USHORT; // ID for RPC Runtime - cbMaxToken: ULONG; // Size of authentication token (max) - Name: PSEC_WCHAR; // Text name - Comment: PSEC_WCHAR; // Comment - end; - {$EXTERNALSYM SecPkgInfoW} - - PPSecPkgInfoA = ^PSecPkgInfoA; - {$NODEFINE PPSecPkgInfoA} - PSecPkgInfoA = ^SecPkgInfoA; - {$EXTERNALSYM PSecPkgInfoA} - SecPkgInfoA = record - fCapabilities: ULONG; // Capability bitmask - wVersion: USHORT; // Version of driver - wRPCID: USHORT; // ID for RPC Runtime - cbMaxToken: ULONG; // Size of authentication token (max) - Name: PSEC_CHAR; // Text name - Comment: PSEC_CHAR; // Comment - end; - {$EXTERNALSYM SecPkgInfoA} - -{$IFDEF SSPI_UNICODE} - SecPkgInfo = SecPkgInfoW; - PSecPkgInfo = PSecPkgInfoW; -{$ELSE} - SecPkgInfo = SecPkgInfoA; - PSecPkgInfo = PSecPkgInfoA; -{$ENDIF} - {$EXTERNALSYM SecPkgInfo} - {$EXTERNALSYM PSecPkgInfo} - - -// -// Security Package Capabilities -// - -const - - SECPKG_FLAG_INTEGRITY = $00000001; // Supports integrity on messages - {$EXTERNALSYM SECPKG_FLAG_INTEGRITY} - SECPKG_FLAG_PRIVACY = $00000002; // Supports privacy (confidentiality) - {$EXTERNALSYM SECPKG_FLAG_PRIVACY} - SECPKG_FLAG_TOKEN_ONLY = $00000004; // Only security token needed - {$EXTERNALSYM SECPKG_FLAG_TOKEN_ONLY} - SECPKG_FLAG_DATAGRAM = $00000008; // Datagram RPC support - {$EXTERNALSYM SECPKG_FLAG_DATAGRAM} - SECPKG_FLAG_CONNECTION = $00000010; // Connection oriented RPC support - {$EXTERNALSYM SECPKG_FLAG_CONNECTION} - SECPKG_FLAG_MULTI_REQUIRED = $00000020; // Full 3-leg required for re-auth. - {$EXTERNALSYM SECPKG_FLAG_MULTI_REQUIRED} - SECPKG_FLAG_CLIENT_ONLY = $00000040; // Server side functionality not available - {$EXTERNALSYM SECPKG_FLAG_CLIENT_ONLY} - SECPKG_FLAG_EXTENDED_ERROR = $00000080; // Supports extended error msgs - {$EXTERNALSYM SECPKG_FLAG_EXTENDED_ERROR} - SECPKG_FLAG_IMPERSONATION = $00000100; // Supports impersonation - {$EXTERNALSYM SECPKG_FLAG_IMPERSONATION} - SECPKG_FLAG_ACCEPT_WIN32_NAME = $00000200; // Accepts Win32 names - {$EXTERNALSYM SECPKG_FLAG_ACCEPT_WIN32_NAME} - SECPKG_FLAG_STREAM = $00000400; // Supports stream semantics - {$EXTERNALSYM SECPKG_FLAG_STREAM} - SECPKG_FLAG_NEGOTIABLE = $00000800; // Can be used by the negotiate package - {$EXTERNALSYM SECPKG_FLAG_NEGOTIABLE} - SECPKG_FLAG_GSS_COMPATIBLE = $00001000; // GSS Compatibility Available - {$EXTERNALSYM SECPKG_FLAG_GSS_COMPATIBLE} - SECPKG_FLAG_LOGON = $00002000; // Supports common LsaLogonUser - {$EXTERNALSYM SECPKG_FLAG_LOGON} - SECPKG_FLAG_ASCII_BUFFERS = $00004000; // Token Buffers are in ASCII - {$EXTERNALSYM SECPKG_FLAG_ASCII_BUFFERS} - SECPKG_FLAG_FRAGMENT = $00008000; // Package can fragment to fit - {$EXTERNALSYM SECPKG_FLAG_FRAGMENT} - SECPKG_FLAG_MUTUAL_AUTH = $00010000; // Package can perform mutual authentication - {$EXTERNALSYM SECPKG_FLAG_MUTUAL_AUTH} - SECPKG_FLAG_DELEGATION = $00020000; // Package can delegate - {$EXTERNALSYM SECPKG_FLAG_DELEGATION} - SECPKG_FLAG_READONLY_WITH_CHECKSUM = $00040000; // Package can delegate - {$EXTERNALSYM SECPKG_FLAG_READONLY_WITH_CHECKSUM} - SECPKG_FLAG_RESTRICTED_TOKENS = $00080000; // Package supports restricted callers - {$EXTERNALSYM SECPKG_FLAG_RESTRICTED_TOKENS} - SECPKG_FLAG_NEGO_EXTENDER = $00100000; // this package extends SPNEGO, there is at most one - {$EXTERNALSYM SECPKG_FLAG_NEGO_EXTENDER} - SECPKG_FLAG_NEGOTIABLE2 = $00200000; // this package is negotiated under the NegoExtender - {$EXTERNALSYM SECPKG_FLAG_NEGOTIABLE2} - - SECPKG_ID_NONE = $FFFF; - {$EXTERNALSYM SECPKG_ID_NONE} - -// -// SecBuffer -// -// Generic memory descriptors for buffers passed in to the security -// API -// - -type - - PSecBuffer = ^SecBuffer; - {$EXTERNALSYM PSecBuffer} - SecBuffer = record - cbBuffer: ULONG; // Size of the buffer, in bytes - BufferType: ULONG; // Type of the buffer (below) - pvBuffer: PVOID; // Pointer to the buffer - end; - {$EXTERNALSYM SecBuffer} - - PSecBufferDesc = ^SecBufferDesc; - {$EXTERNALSYM PSecBufferDesc} - SecBufferDesc = record - ulVersion: ULONG; // Version number - cBuffers: ULONG; // Number of buffers - pBuffers: PSecBuffer; // Pointer to array of buffers - end; - {$EXTERNALSYM SecBufferDesc} - -const - - SECBUFFER_VERSION = 0; - {$EXTERNALSYM SECBUFFER_VERSION} - - SECBUFFER_EMPTY = 0; // Undefined, replaced by provider - {$EXTERNALSYM SECBUFFER_EMPTY} - SECBUFFER_DATA = 1; // Packet data - {$EXTERNALSYM SECBUFFER_DATA} - SECBUFFER_TOKEN = 2; // Security token - {$EXTERNALSYM SECBUFFER_TOKEN} - SECBUFFER_PKG_PARAMS = 3; // Package specific parameters - {$EXTERNALSYM SECBUFFER_PKG_PARAMS} - SECBUFFER_MISSING = 4; // Missing Data indicator - {$EXTERNALSYM SECBUFFER_MISSING} - SECBUFFER_EXTRA = 5; // Extra data - {$EXTERNALSYM SECBUFFER_EXTRA} - SECBUFFER_STREAM_TRAILER = 6; // Security Trailer - {$EXTERNALSYM SECBUFFER_STREAM_TRAILER} - SECBUFFER_STREAM_HEADER = 7; // Security Header - {$EXTERNALSYM SECBUFFER_STREAM_HEADER} - SECBUFFER_NEGOTIATION_INFO = 8; // Hints from the negotiation pkg - {$EXTERNALSYM SECBUFFER_NEGOTIATION_INFO} - SECBUFFER_PADDING = 9; // non-data padding - {$EXTERNALSYM SECBUFFER_PADDING} - SECBUFFER_STREAM = 10; // whole encrypted message - {$EXTERNALSYM SECBUFFER_STREAM} - SECBUFFER_MECHLIST = 11; - {$EXTERNALSYM SECBUFFER_MECHLIST} - SECBUFFER_MECHLIST_SIGNATURE = 12; - {$EXTERNALSYM SECBUFFER_MECHLIST_SIGNATURE} - SECBUFFER_TARGET = 13; // obsolete - {$EXTERNALSYM SECBUFFER_TARGET} - SECBUFFER_CHANNEL_BINDINGS = 14; - {$EXTERNALSYM SECBUFFER_CHANNEL_BINDINGS} - SECBUFFER_CHANGE_PASS_RESPONSE = 15; - {$EXTERNALSYM SECBUFFER_CHANGE_PASS_RESPONSE} - SECBUFFER_TARGET_HOST = 16; - {$EXTERNALSYM SECBUFFER_TARGET_HOST} - SECBUFFER_ALERT = 17; - {$EXTERNALSYM SECBUFFER_ALERT} - - SECBUFFER_ATTRMASK = $F0000000; - {$EXTERNALSYM SECBUFFER_ATTRMASK} - SECBUFFER_READONLY = $80000000; // Buffer is read-only - {$EXTERNALSYM SECBUFFER_READONLY} - SECBUFFER_READONLY_WITH_CHECKSUM = $10000000; // Buffer is read-only, and checksummed; - {$EXTERNALSYM SECBUFFER_READONLY_WITH_CHECKSUM} - SECBUFFER_RESERVED = $40000000; - {$EXTERNALSYM SECBUFFER_RESERVED} - -type - - PSEC_NEGOTIATION_INFO = ^SEC_NEGOTIATION_INFO; - {$EXTERNALSYM PSEC_NEGOTIATION_INFO} - SEC_NEGOTIATION_INFO = record - Size: ULONG; // Size of this structure - NameLength: ULONG; // Length of name hint - Name: PSEC_WCHAR; // Name hint - Reserved: PVOID; // Reserved - end; - {$EXTERNALSYM SEC_NEGOTIATION_INFO} - - PSEC_CHANNEL_BINDINGS = ^SEC_CHANNEL_BINDINGS; - {$EXTERNALSYM PSEC_CHANNEL_BINDINGS} - SEC_CHANNEL_BINDINGS = record - dwInitiatorAddrType: ULONG; - cbInitiatorLength: ULONG; - dwInitiatorOffset: ULONG; - dwAcceptorAddrType: ULONG; - cbAcceptorLength: ULONG; - dwAcceptorOffset: ULONG; - cbApplicationDataLength: ULONG; - dwApplicationDataOffset: ULONG; - end; - {$EXTERNALSYM SEC_CHANNEL_BINDINGS} - -// -// Data Representation Constant: -// - -const - - SECURITY_NATIVE_DREP = $00000010; - {$EXTERNALSYM SECURITY_NATIVE_DREP} - SECURITY_NETWORK_DREP = $00000000; - {$EXTERNALSYM SECURITY_NETWORK_DREP} - -// -// Credential Use Flags -// - -const - - SECPKG_CRED_INBOUND = $00000001; - {$EXTERNALSYM SECPKG_CRED_INBOUND} - SECPKG_CRED_OUTBOUND = $00000002; - {$EXTERNALSYM SECPKG_CRED_OUTBOUND} - SECPKG_CRED_BOTH = $00000003; - {$EXTERNALSYM SECPKG_CRED_BOTH} - SECPKG_CRED_DEFAULT = $00000004; - {$EXTERNALSYM SECPKG_CRED_DEFAULT} - SECPKG_CRED_RESERVED = $F0000000; - {$EXTERNALSYM SECPKG_CRED_RESERVED} - -// -// SSP SHOULD prompt the user for credentials/consent, independent -// of whether credentials to be used are the 'logged on' credentials -// or retrieved from credman. -// -// An SSP may choose not to prompt, however, in circumstances determined -// by the SSP. -// - - SECPKG_CRED_AUTOLOGON_RESTRICTED = $00000010; - {$EXTERNALSYM SECPKG_CRED_AUTOLOGON_RESTRICTED} - -// -// auth will always fail, ISC() is called to process policy data only -// - - SECPKG_CRED_PROCESS_POLICY_ONLY = $00000020; - {$EXTERNALSYM SECPKG_CRED_PROCESS_POLICY_ONLY} - -const -// -// InitializeSecurityContext Requirement and return flags: -// - ISC_REQ_DELEGATE = $00000001; - {$EXTERNALSYM ISC_REQ_DELEGATE} - ISC_REQ_MUTUAL_AUTH = $00000002; - {$EXTERNALSYM ISC_REQ_MUTUAL_AUTH} - ISC_REQ_REPLAY_DETECT = $00000004; - {$EXTERNALSYM ISC_REQ_REPLAY_DETECT} - ISC_REQ_SEQUENCE_DETECT = $00000008; - {$EXTERNALSYM ISC_REQ_SEQUENCE_DETECT} - ISC_REQ_CONFIDENTIALITY = $00000010; - {$EXTERNALSYM ISC_REQ_CONFIDENTIALITY} - ISC_REQ_USE_SESSION_KEY = $00000020; - {$EXTERNALSYM ISC_REQ_USE_SESSION_KEY} - ISC_REQ_PROMPT_FOR_CREDS = $00000040; - {$EXTERNALSYM ISC_REQ_PROMPT_FOR_CREDS} - ISC_REQ_USE_SUPPLIED_CREDS = $00000080; - {$EXTERNALSYM ISC_REQ_USE_SUPPLIED_CREDS} - ISC_REQ_ALLOCATE_MEMORY = $00000100; - {$EXTERNALSYM ISC_REQ_ALLOCATE_MEMORY} - ISC_REQ_USE_DCE_STYLE = $00000200; - {$EXTERNALSYM ISC_REQ_USE_DCE_STYLE} - ISC_REQ_DATAGRAM = $00000400; - {$EXTERNALSYM ISC_REQ_DATAGRAM} - ISC_REQ_CONNECTION = $00000800; - {$EXTERNALSYM ISC_REQ_CONNECTION} - ISC_REQ_CALL_LEVEL = $00001000; - {$EXTERNALSYM ISC_REQ_CALL_LEVEL} - ISC_REQ_FRAGMENT_SUPPLIED = $00002000; - {$EXTERNALSYM ISC_REQ_FRAGMENT_SUPPLIED} - ISC_REQ_EXTENDED_ERROR = $00004000; - {$EXTERNALSYM ISC_REQ_EXTENDED_ERROR} - ISC_REQ_STREAM = $00008000; - {$EXTERNALSYM ISC_REQ_STREAM} - ISC_REQ_INTEGRITY = $00010000; - {$EXTERNALSYM ISC_REQ_INTEGRITY} - ISC_REQ_IDENTIFY = $00020000; - {$EXTERNALSYM ISC_REQ_IDENTIFY} - ISC_REQ_NULL_SESSION = $00040000; - {$EXTERNALSYM ISC_REQ_NULL_SESSION} - ISC_REQ_MANUAL_CRED_VALIDATION = $00080000; - {$EXTERNALSYM ISC_REQ_MANUAL_CRED_VALIDATION} - ISC_REQ_RESERVED1 = $00100000; - {$EXTERNALSYM ISC_REQ_RESERVED1} - ISC_REQ_FRAGMENT_TO_FIT = $00200000; - {$EXTERNALSYM ISC_REQ_FRAGMENT_TO_FIT} -// This exists only in Windows Vista and greater - ISC_REQ_FORWARD_CREDENTIALS = $00400000; - {$EXTERNALSYM ISC_REQ_FORWARD_CREDENTIALS} - ISC_REQ_NO_INTEGRITY = $00800000; // honored only by SPNEGO - {$EXTERNALSYM ISC_REQ_NO_INTEGRITY} - ISC_REQ_USE_HTTP_STYLE = $01000000; - {$EXTERNALSYM ISC_REQ_USE_HTTP_STYLE} - - ISC_RET_DELEGATE = $00000001; - {$EXTERNALSYM ISC_RET_DELEGATE} - ISC_RET_MUTUAL_AUTH = $00000002; - {$EXTERNALSYM ISC_RET_MUTUAL_AUTH} - ISC_RET_REPLAY_DETECT = $00000004; - {$EXTERNALSYM ISC_RET_REPLAY_DETECT} - ISC_RET_SEQUENCE_DETECT = $00000008; - {$EXTERNALSYM ISC_RET_SEQUENCE_DETECT} - ISC_RET_CONFIDENTIALITY = $00000010; - {$EXTERNALSYM ISC_RET_CONFIDENTIALITY} - ISC_RET_USE_SESSION_KEY = $00000020; - {$EXTERNALSYM ISC_RET_USE_SESSION_KEY} - ISC_RET_USED_COLLECTED_CREDS = $00000040; - {$EXTERNALSYM ISC_RET_USED_COLLECTED_CREDS} - ISC_RET_USED_SUPPLIED_CREDS = $00000080; - {$EXTERNALSYM ISC_RET_USED_SUPPLIED_CREDS} - ISC_RET_ALLOCATED_MEMORY = $00000100; - {$EXTERNALSYM ISC_RET_ALLOCATED_MEMORY} - ISC_RET_USED_DCE_STYLE = $00000200; - {$EXTERNALSYM ISC_RET_USED_DCE_STYLE} - ISC_RET_DATAGRAM = $00000400; - {$EXTERNALSYM ISC_RET_DATAGRAM} - ISC_RET_CONNECTION = $00000800; - {$EXTERNALSYM ISC_RET_CONNECTION} - ISC_RET_INTERMEDIATE_RETURN = $00001000; - {$EXTERNALSYM ISC_RET_INTERMEDIATE_RETURN} - ISC_RET_CALL_LEVEL = $00002000; - {$EXTERNALSYM ISC_RET_CALL_LEVEL} - ISC_RET_EXTENDED_ERROR = $00004000; - {$EXTERNALSYM ISC_RET_EXTENDED_ERROR} - ISC_RET_STREAM = $00008000; - {$EXTERNALSYM ISC_RET_STREAM} - ISC_RET_INTEGRITY = $00010000; - {$EXTERNALSYM ISC_RET_INTEGRITY} - ISC_RET_IDENTIFY = $00020000; - {$EXTERNALSYM ISC_RET_IDENTIFY} - ISC_RET_NULL_SESSION = $00040000; - {$EXTERNALSYM ISC_RET_NULL_SESSION} - ISC_RET_MANUAL_CRED_VALIDATION = $00080000; - {$EXTERNALSYM ISC_RET_MANUAL_CRED_VALIDATION} - ISC_RET_RESERVED1 = $00100000; - {$EXTERNALSYM ISC_RET_RESERVED1} - ISC_RET_FRAGMENT_ONLY = $00200000; - {$EXTERNALSYM ISC_RET_FRAGMENT_ONLY} -// This exists only in Windows Vista and greater - ISC_RET_FORWARD_CREDENTIALS = $00400000; - {$EXTERNALSYM ISC_RET_FORWARD_CREDENTIALS} - - ISC_RET_USED_HTTP_STYLE = $01000000; - {$EXTERNALSYM ISC_RET_USED_HTTP_STYLE} - ISC_RET_NO_ADDITIONAL_TOKEN = $02000000; // *INTERNAL* - {$EXTERNALSYM ISC_RET_NO_ADDITIONAL_TOKEN} - ISC_RET_REAUTHENTICATION = $08000000; // *INTERNAL* - {$EXTERNALSYM ISC_RET_REAUTHENTICATION} - - ASC_REQ_DELEGATE = $00000001; - {$EXTERNALSYM ASC_REQ_DELEGATE} - ASC_REQ_MUTUAL_AUTH = $00000002; - {$EXTERNALSYM ASC_REQ_MUTUAL_AUTH} - ASC_REQ_REPLAY_DETECT = $00000004; - {$EXTERNALSYM ASC_REQ_REPLAY_DETECT} - ASC_REQ_SEQUENCE_DETECT = $00000008; - {$EXTERNALSYM ASC_REQ_SEQUENCE_DETECT} - ASC_REQ_CONFIDENTIALITY = $00000010; - {$EXTERNALSYM ASC_REQ_CONFIDENTIALITY} - ASC_REQ_USE_SESSION_KEY = $00000020; - {$EXTERNALSYM ASC_REQ_USE_SESSION_KEY} - ASC_REQ_ALLOCATE_MEMORY = $00000100; - {$EXTERNALSYM ASC_REQ_ALLOCATE_MEMORY} - ASC_REQ_USE_DCE_STYLE = $00000200; - {$EXTERNALSYM ASC_REQ_USE_DCE_STYLE} - ASC_REQ_DATAGRAM = $00000400; - {$EXTERNALSYM ASC_REQ_DATAGRAM} - ASC_REQ_CONNECTION = $00000800; - {$EXTERNALSYM ASC_REQ_CONNECTION} - ASC_REQ_CALL_LEVEL = $00001000; - {$EXTERNALSYM ASC_REQ_CALL_LEVEL} - ASC_REQ_EXTENDED_ERROR = $00008000; - {$EXTERNALSYM ASC_REQ_EXTENDED_ERROR} - ASC_REQ_STREAM = $00010000; - {$EXTERNALSYM ASC_REQ_STREAM} - ASC_REQ_INTEGRITY = $00020000; - {$EXTERNALSYM ASC_REQ_INTEGRITY} - ASC_REQ_LICENSING = $00040000; - {$EXTERNALSYM ASC_REQ_LICENSING} - ASC_REQ_IDENTIFY = $00080000; - {$EXTERNALSYM ASC_REQ_IDENTIFY} - ASC_REQ_ALLOW_NULL_SESSION = $00100000; - {$EXTERNALSYM ASC_REQ_ALLOW_NULL_SESSION} - ASC_REQ_ALLOW_NON_USER_LOGONS = $00200000; - {$EXTERNALSYM ASC_REQ_ALLOW_NON_USER_LOGONS} - ASC_REQ_ALLOW_CONTEXT_REPLAY = $00400000; - {$EXTERNALSYM ASC_REQ_ALLOW_CONTEXT_REPLAY} - ASC_REQ_FRAGMENT_TO_FIT = $00800000; - {$EXTERNALSYM ASC_REQ_FRAGMENT_TO_FIT} - ASC_REQ_FRAGMENT_SUPPLIED = $00002000; - {$EXTERNALSYM ASC_REQ_FRAGMENT_SUPPLIED} - ASC_REQ_NO_TOKEN = $01000000; - {$EXTERNALSYM ASC_REQ_NO_TOKEN} - ASC_REQ_PROXY_BINDINGS = $04000000; - {$EXTERNALSYM ASC_REQ_PROXY_BINDINGS} -// SSP_RET_REAUTHENTICATION = $08000000; // *INTERNAL* - {.$EXTERNALSYM SSP_RET_REAUTHENTICATION} - ASC_REQ_ALLOW_MISSING_BINDINGS = $10000000; - {$EXTERNALSYM ASC_REQ_ALLOW_MISSING_BINDINGS} - - ASC_RET_DELEGATE = $00000001; - {$EXTERNALSYM ASC_RET_DELEGATE} - ASC_RET_MUTUAL_AUTH = $00000002; - {$EXTERNALSYM ASC_RET_MUTUAL_AUTH} - ASC_RET_REPLAY_DETECT = $00000004; - {$EXTERNALSYM ASC_RET_REPLAY_DETECT} - ASC_RET_SEQUENCE_DETECT = $00000008; - {$EXTERNALSYM ASC_RET_SEQUENCE_DETECT} - ASC_RET_CONFIDENTIALITY = $00000010; - {$EXTERNALSYM ASC_RET_CONFIDENTIALITY} - ASC_RET_USE_SESSION_KEY = $00000020; - {$EXTERNALSYM ASC_RET_USE_SESSION_KEY} - ASC_RET_ALLOCATED_MEMORY = $00000100; - {$EXTERNALSYM ASC_RET_ALLOCATED_MEMORY} - ASC_RET_USED_DCE_STYLE = $00000200; - {$EXTERNALSYM ASC_RET_USED_DCE_STYLE} - ASC_RET_DATAGRAM = $00000400; - {$EXTERNALSYM ASC_RET_DATAGRAM} - ASC_RET_CONNECTION = $00000800; - {$EXTERNALSYM ASC_RET_CONNECTION} - ASC_RET_CALL_LEVEL = $00002000; // skipped 1000 to be like ISC_ - {$EXTERNALSYM ASC_RET_CALL_LEVEL} - ASC_RET_THIRD_LEG_FAILED = $00004000; - {$EXTERNALSYM ASC_RET_THIRD_LEG_FAILED} - ASC_RET_EXTENDED_ERROR = $00008000; - {$EXTERNALSYM ASC_RET_EXTENDED_ERROR} - ASC_RET_STREAM = $00010000; - {$EXTERNALSYM ASC_RET_STREAM} - ASC_RET_INTEGRITY = $00020000; - {$EXTERNALSYM ASC_RET_INTEGRITY} - ASC_RET_LICENSING = $00040000; - {$EXTERNALSYM ASC_RET_LICENSING} - ASC_RET_IDENTIFY = $00080000; - {$EXTERNALSYM ASC_RET_IDENTIFY} - ASC_RET_NULL_SESSION = $00100000; - {$EXTERNALSYM ASC_RET_NULL_SESSION} - ASC_RET_ALLOW_NON_USER_LOGONS = $00200000; - {$EXTERNALSYM ASC_RET_ALLOW_NON_USER_LOGONS} - ASC_RET_ALLOW_CONTEXT_REPLAY = $00400000; - {$EXTERNALSYM ASC_RET_ALLOW_CONTEXT_REPLAY} - ASC_RET_FRAGMENT_ONLY = $00800000; - {$EXTERNALSYM ASC_RET_FRAGMENT_ONLY} - ASC_RET_NO_TOKEN = $01000000; - {$EXTERNALSYM ASC_RET_NO_TOKEN} - ASC_RET_NO_ADDITIONAL_TOKEN = $02000000; // *INTERNAL* - {$EXTERNALSYM ASC_RET_NO_ADDITIONAL_TOKEN} - ASC_RET_NO_PROXY_BINDINGS = $04000000; - {$EXTERNALSYM ASC_RET_NO_PROXY_BINDINGS} -// SSP_RET_REAUTHENTICATION = $08000000; // *INTERNAL* - {.$EXTERNALSYM SSP_RET_REAUTHENTICATION} - ASC_RET_MISSING_BINDINGS = $10000000; - {$EXTERNALSYM ASC_RET_MISSING_BINDINGS} - -// -// Security Credentials Attributes: -// - -const - SECPKG_CRED_ATTR_NAMES = 1; - {$EXTERNALSYM SECPKG_CRED_ATTR_NAMES} - SECPKG_CRED_ATTR_SSI_PROVIDER = 2; - {$EXTERNALSYM SECPKG_CRED_ATTR_SSI_PROVIDER} - -type - - PSecPkgCredentials_NamesW = ^SecPkgCredentials_NamesW; - {$EXTERNALSYM PSecPkgCredentials_NamesW} - SecPkgCredentials_NamesW = record - sUserName: PSEC_WCHAR; - end; - {$EXTERNALSYM SecPkgCredentials_NamesW} - - PSecPkgCredentials_NamesA = ^SecPkgCredentials_NamesA; - {$EXTERNALSYM PSecPkgCredentials_NamesA} - SecPkgCredentials_NamesA = record - sUserName: PSEC_CHAR; - end; - {$EXTERNALSYM SecPkgCredentials_NamesA} - -{$IFDEF SSPI_UNICODE} - SecPkgCredentials_Names = SecPkgCredentials_NamesW; - PSecPkgCredentials_Names = PSecPkgCredentials_NamesW; -{$ELSE} - SecPkgCredentials_Names = SecPkgCredentials_NamesA; - PSecPkgCredentials_Names = PSecPkgCredentials_NamesA; -{$ENDIF} - {$EXTERNALSYM SecPkgCredentials_Names} - {$EXTERNALSYM PSecPkgCredentials_Names} - - PSecPkgCredentials_SSIProviderW = ^SecPkgCredentials_SSIProviderW; - {$EXTERNALSYM PSecPkgCredentials_SSIProviderW} - SecPkgCredentials_SSIProviderW = record - sProviderName: PSEC_WCHAR; - ProviderInfoLength: ULONG; - ProviderInfo: PAnsiChar; - end; - {$EXTERNALSYM SecPkgCredentials_SSIProviderW} - - PSecPkgCredentials_SSIProviderA = ^SecPkgCredentials_SSIProviderA; - {$EXTERNALSYM PSecPkgCredentials_SSIProviderA} - SecPkgCredentials_SSIProviderA = record - sProviderName: PSEC_CHAR; - ProviderInfoLength: ULONG; - ProviderInfo: PAnsiChar; - end; - {$EXTERNALSYM SecPkgCredentials_SSIProviderA} - -{$IFDEF SSPI_UNICODE} - SecPkgCredentials_SSIProvider = SecPkgCredentials_SSIProviderW; - PSecPkgCredentials_SSIProvider = PSecPkgCredentials_SSIProviderW; -{$ELSE} - SecPkgCredentials_SSIProvider = SecPkgCredentials_SSIProviderA; - PSecPkgCredentials_SSIProvider = PSecPkgCredentials_SSIProviderA; -{$ENDIF} - {$EXTERNALSYM SecPkgCredentials_SSIProvider} - {$EXTERNALSYM PSecPkgCredentials_SSIProvider} - -// -// Security Context Attributes: -// - -const - - SECPKG_ATTR_SIZES = 0; - {$EXTERNALSYM SECPKG_ATTR_SIZES} - SECPKG_ATTR_NAMES = 1; - {$EXTERNALSYM SECPKG_ATTR_NAMES} - SECPKG_ATTR_LIFESPAN = 2; - {$EXTERNALSYM SECPKG_ATTR_LIFESPAN} - SECPKG_ATTR_DCE_INFO = 3; - {$EXTERNALSYM SECPKG_ATTR_DCE_INFO} - SECPKG_ATTR_STREAM_SIZES = 4; - {$EXTERNALSYM SECPKG_ATTR_STREAM_SIZES} - SECPKG_ATTR_KEY_INFO = 5; - {$EXTERNALSYM SECPKG_ATTR_KEY_INFO} - SECPKG_ATTR_AUTHORITY = 6; - {$EXTERNALSYM SECPKG_ATTR_AUTHORITY} - SECPKG_ATTR_PROTO_INFO = 7; - {$EXTERNALSYM SECPKG_ATTR_PROTO_INFO} - SECPKG_ATTR_PASSWORD_EXPIRY = 8; - {$EXTERNALSYM SECPKG_ATTR_PASSWORD_EXPIRY} - SECPKG_ATTR_SESSION_KEY = 9; - {$EXTERNALSYM SECPKG_ATTR_SESSION_KEY} - SECPKG_ATTR_PACKAGE_INFO = 10; - {$EXTERNALSYM SECPKG_ATTR_PACKAGE_INFO} - SECPKG_ATTR_USER_FLAGS = 11; - {$EXTERNALSYM SECPKG_ATTR_USER_FLAGS} - SECPKG_ATTR_NEGOTIATION_INFO = 12; - {$EXTERNALSYM SECPKG_ATTR_NEGOTIATION_INFO} - SECPKG_ATTR_NATIVE_NAMES = 13; - {$EXTERNALSYM SECPKG_ATTR_NATIVE_NAMES} - SECPKG_ATTR_FLAGS = 14; - {$EXTERNALSYM SECPKG_ATTR_FLAGS} -// These attributes exist only in Win XP and greater - SECPKG_ATTR_USE_VALIDATED = 15; - {$EXTERNALSYM SECPKG_ATTR_USE_VALIDATED} - SECPKG_ATTR_CREDENTIAL_NAME = 16; - {$EXTERNALSYM SECPKG_ATTR_CREDENTIAL_NAME} - SECPKG_ATTR_TARGET_INFORMATION = 17; - {$EXTERNALSYM SECPKG_ATTR_TARGET_INFORMATION} - SECPKG_ATTR_ACCESS_TOKEN = 18; - {$EXTERNALSYM SECPKG_ATTR_ACCESS_TOKEN} -// These attributes exist only in Win2K3 and greater - SECPKG_ATTR_TARGET = 19; - {$EXTERNALSYM SECPKG_ATTR_TARGET} - SECPKG_ATTR_AUTHENTICATION_ID = 20; - {$EXTERNALSYM SECPKG_ATTR_AUTHENTICATION_ID} -// These attributes exist only in Win2K3SP1 and greater - SECPKG_ATTR_LOGOFF_TIME = 21; - {$EXTERNALSYM SECPKG_ATTR_LOGOFF_TIME} -// -// win7 or greater -// - SECPKG_ATTR_NEGO_KEYS = 22; - {$EXTERNALSYM SECPKG_ATTR_NEGO_KEYS} - SECPKG_ATTR_PROMPTING_NEEDED = 24; - {$EXTERNALSYM SECPKG_ATTR_PROMPTING_NEEDED} - SECPKG_ATTR_UNIQUE_BINDINGS = 25; - {$EXTERNALSYM SECPKG_ATTR_UNIQUE_BINDINGS} - SECPKG_ATTR_ENDPOINT_BINDINGS = 26; - {$EXTERNALSYM SECPKG_ATTR_ENDPOINT_BINDINGS} - SECPKG_ATTR_CLIENT_SPECIFIED_TARGET = 27; - {$EXTERNALSYM SECPKG_ATTR_CLIENT_SPECIFIED_TARGET} - - SECPKG_ATTR_LAST_CLIENT_TOKEN_STATUS = 30; - {$EXTERNALSYM SECPKG_ATTR_LAST_CLIENT_TOKEN_STATUS} - SECPKG_ATTR_NEGO_PKG_INFO = 31; // contains nego info of packages - {$EXTERNALSYM SECPKG_ATTR_NEGO_PKG_INFO} - SECPKG_ATTR_NEGO_STATUS = 32; // contains the last error - {$EXTERNALSYM SECPKG_ATTR_NEGO_STATUS} - SECPKG_ATTR_CONTEXT_DELETED = 33; // a context has been deleted - {$EXTERNALSYM SECPKG_ATTR_CONTEXT_DELETED} - - SECPKG_ATTR_SUBJECT_SECURITY_ATTRIBUTES = 128; - {$EXTERNALSYM SECPKG_ATTR_SUBJECT_SECURITY_ATTRIBUTES} - -type - - PSecPkgContext_SubjectAttributes = ^SecPkgContext_SubjectAttributes; - {$EXTERNALSYM PSecPkgContext_SubjectAttributes} - SecPkgContext_SubjectAttributes = record - AttributeInfo: PVOID; // contains a PAUTHZ_SECURITY_ATTRIBUTES_INFORMATION structure - end; - {$EXTERNALSYM SecPkgContext_SubjectAttributes} - -const - SECPKG_ATTR_NEGO_INFO_FLAG_NO_KERBEROS = $1; - {$EXTERNALSYM SECPKG_ATTR_NEGO_INFO_FLAG_NO_KERBEROS} - SECPKG_ATTR_NEGO_INFO_FLAG_NO_NTLM = $2; - {$EXTERNALSYM SECPKG_ATTR_NEGO_INFO_FLAG_NO_NTLM} - -type - -// -// types of credentials, used by SECPKG_ATTR_PROMPTING_NEEDED -// - - PSECPKG_CRED_CLASS = ^SECPKG_CRED_CLASS; - {$EXTERNALSYM PSECPKG_CRED_CLASS} - SECPKG_CRED_CLASS = ULONG; - {$EXTERNALSYM SECPKG_CRED_CLASS} - -const - SecPkgCredClass_None = 0; // no creds - {$EXTERNALSYM SecPkgCredClass_None} - SecPkgCredClass_Ephemeral = 10; // logon creds - {$EXTERNALSYM SecPkgCredClass_Ephemeral} - SecPkgCredClass_PersistedGeneric = 20; // saved creds, not target specific - {$EXTERNALSYM SecPkgCredClass_PersistedGeneric} - SecPkgCredClass_PersistedSpecific = 30; // saved creds, target specific - {$EXTERNALSYM SecPkgCredClass_PersistedSpecific} - SecPkgCredClass_Explicit = 40; // explicitly supplied creds - {$EXTERNALSYM SecPkgCredClass_Explicit} - -type - - PSecPkgContext_CredInfo = ^SecPkgContext_CredInfo; - {$EXTERNALSYM PSecPkgContext_CredInfo} - SecPkgContext_CredInfo = record - CredClass: SECPKG_CRED_CLASS; - IsPromptingNeeded: ULONG; - end; - {$EXTERNALSYM SecPkgContext_CredInfo} - - PSecPkgContext_NegoPackageInfo = ^SecPkgContext_NegoPackageInfo; - {$EXTERNALSYM PSecPkgContext_NegoPackageInfo} - SecPkgContext_NegoPackageInfo = record - PackageMask: ULONG; - end; - {$EXTERNALSYM SecPkgContext_NegoPackageInfo} - - PSecPkgContext_NegoStatus = ^SecPkgContext_NegoStatus; - {$EXTERNALSYM PSecPkgContext_NegoStatus} - SecPkgContext_NegoStatus = record - LastStatus: ULONG; - end; - {$EXTERNALSYM SecPkgContext_NegoStatus} - - PSecPkgContext_Sizes = ^SecPkgContext_Sizes; - {$EXTERNALSYM PSecPkgContext_Sizes} - SecPkgContext_Sizes = record - cbMaxToken: ULONG; - cbMaxSignature: ULONG; - cbBlockSize: ULONG; - cbSecurityTrailer: ULONG; - end; - {$EXTERNALSYM SecPkgContext_Sizes} - - PSecPkgContext_StreamSizes = ^SecPkgContext_StreamSizes; - {$EXTERNALSYM PSecPkgContext_StreamSizes} - SecPkgContext_StreamSizes = record - cbHeader: ULONG; - cbTrailer: ULONG; - cbMaximumMessage: ULONG; - cBuffers: ULONG; - cbBlockSize: ULONG; - end; - {$EXTERNALSYM SecPkgContext_StreamSizes} - - PSecPkgContext_NamesW = ^SecPkgContext_NamesW; - {$EXTERNALSYM PSecPkgContext_NamesW} - SecPkgContext_NamesW = record - sUserName: PSEC_WCHAR; - end; - {$EXTERNALSYM SecPkgContext_NamesW} - - PSECPKG_ATTR_LCT_STATUS = ^SECPKG_ATTR_LCT_STATUS; - {$EXTERNALSYM PSECPKG_ATTR_LCT_STATUS} - SECPKG_ATTR_LCT_STATUS = ( - SecPkgAttrLastClientTokenYes, - SecPkgAttrLastClientTokenNo, - SecPkgAttrLastClientTokenMaybe - ); - {$EXTERNALSYM SECPKG_ATTR_LCT_STATUS} - - PSecPkgContext_LastClientTokenStatus = ^SecPkgContext_LastClientTokenStatus; - {$EXTERNALSYM PSecPkgContext_LastClientTokenStatus} - SecPkgContext_LastClientTokenStatus = record - LastClientTokenStatus: SECPKG_ATTR_LCT_STATUS; - end; - {$EXTERNALSYM SecPkgContext_LastClientTokenStatus} - - PSecPkgContext_NamesA = ^SecPkgContext_NamesA; - {$EXTERNALSYM PSecPkgContext_NamesA} - SecPkgContext_NamesA = record - sUserName: PSEC_CHAR; - end; - {$EXTERNALSYM SecPkgContext_NamesA} - -{$IFDEF SSPI_UNICODE} - SecPkgContext_Names = SecPkgContext_NamesW; - PSecPkgContext_Names = PSecPkgContext_NamesW; -{$ELSE} - SecPkgContext_Names = SecPkgContext_NamesA; - PSecPkgContext_Names = PSecPkgContext_NamesA; -{$ENDIF} - {$EXTERNALSYM SecPkgContext_Names} - {$EXTERNALSYM PSecPkgContext_Names} - - PSecPkgContext_Lifespan = ^SecPkgContext_Lifespan; - {$EXTERNALSYM PSecPkgContext_Lifespan} - SecPkgContext_Lifespan = record - tsStart: TimeStamp; - tsExpiry: TimeStamp; - end; - {$EXTERNALSYM SecPkgContext_Lifespan} - - PSecPkgContext_DceInfo = ^SecPkgContext_DceInfo; - {$EXTERNALSYM PSecPkgContext_DceInfo} - SecPkgContext_DceInfo = record - AuthzSvc: ULONG; - pPac: PVOID; - end; - {$EXTERNALSYM SecPkgContext_DceInfo} - - PSecPkgContext_KeyInfoA = ^SecPkgContext_KeyInfoA; - {$EXTERNALSYM PSecPkgContext_KeyInfoA} - SecPkgContext_KeyInfoA = record - sSignatureAlgorithmName: PSEC_CHAR; - sEncryptAlgorithmName: PSEC_CHAR; - KeySize: ULONG; - SignatureAlgorithm: ULONG; - EncryptAlgorithm: ULONG; - end; - {$EXTERNALSYM SecPkgContext_KeyInfoA} - - PSecPkgContext_KeyInfoW = ^SecPkgContext_KeyInfoW; - {$EXTERNALSYM PSecPkgContext_KeyInfoW} - SecPkgContext_KeyInfoW = record - sSignatureAlgorithmName: PSEC_WCHAR; - sEncryptAlgorithmName: PSEC_WCHAR; - KeySize: ULONG; - SignatureAlgorithm: ULONG; - EncryptAlgorithm: ULONG; - end; - {$EXTERNALSYM SecPkgContext_KeyInfoW} - -{$IFDEF SSPI_UNICODE} - SecPkgContext_KeyInfo = SecPkgContext_KeyInfoW; - PSecPkgContext_KeyInfo = PSecPkgContext_KeyInfoW; -{$ELSE} - SecPkgContext_KeyInfo = SecPkgContext_KeyInfoA; - PSecPkgContext_KeyInfo = PSecPkgContext_KeyInfoA; -{$ENDIF} - {$EXTERNALSYM SecPkgContext_KeyInfo} - {$EXTERNALSYM PSecPkgContext_KeyInfo} - - PSecPkgContext_AuthorityA = ^SecPkgContext_AuthorityA; - {$EXTERNALSYM PSecPkgContext_AuthorityA} - SecPkgContext_AuthorityA = record - sAuthorityName: PSEC_CHAR; - end; - {$EXTERNALSYM SecPkgContext_AuthorityA} - - PSecPkgContext_AuthorityW = ^SecPkgContext_AuthorityW; - {$EXTERNALSYM PSecPkgContext_AuthorityW} - SecPkgContext_AuthorityW = record - sAuthorityName: PSEC_WCHAR; - end; - {$EXTERNALSYM SecPkgContext_AuthorityW} - -{$IFDEF SSPI_UNICODE} - SecPkgContext_Authority = SecPkgContext_AuthorityW; - PSecPkgContext_Authority = PSecPkgContext_AuthorityW; -{$ELSE} - SecPkgContext_Authority = SecPkgContext_AuthorityA; - PSecPkgContext_Authority = PSecPkgContext_AuthorityA; -{$ENDIF} - {$EXTERNALSYM SecPkgContext_Authority} - {$EXTERNALSYM PSecPkgContext_Authority} - - PSecPkgContext_ProtoInfoA = ^SecPkgContext_ProtoInfoA; - {$EXTERNALSYM PSecPkgContext_ProtoInfoA} - SecPkgContext_ProtoInfoA = record - sProtocolName: PSEC_CHAR; - majorVersion: ULONG; - minorVersion: ULONG; - end; - {$EXTERNALSYM SecPkgContext_ProtoInfoA} - - PSecPkgContext_ProtoInfoW = ^SecPkgContext_ProtoInfoW; - {$EXTERNALSYM PSecPkgContext_ProtoInfoW} - SecPkgContext_ProtoInfoW = record - sProtocolName: PSEC_WCHAR; - majorVersion: ULONG; - minorVersion: ULONG; - end; - {$EXTERNALSYM SecPkgContext_ProtoInfoW} - -{$IFDEF SSPI_UNICODE} - SecPkgContext_ProtoInfo = SecPkgContext_ProtoInfoW; - PSecPkgContext_ProtoInfo = PSecPkgContext_ProtoInfoW; -{$ELSE} - SecPkgContext_ProtoInfo = SecPkgContext_ProtoInfoA; - PSecPkgContext_ProtoInfo = PSecPkgContext_ProtoInfoA; -{$ENDIF} - {$EXTERNALSYM SecPkgContext_ProtoInfo} - {$EXTERNALSYM PSecPkgContext_ProtoInfo} - - PSecPkgContext_PasswordExpiry = ^SecPkgContext_PasswordExpiry; - {$EXTERNALSYM PSecPkgContext_PasswordExpiry} - SecPkgContext_PasswordExpiry = record - tsPasswordExpires: TimeStamp; - end; - {$EXTERNALSYM SecPkgContext_PasswordExpiry} - - PSecPkgContext_LogoffTime = ^SecPkgContext_LogoffTime; - {$EXTERNALSYM PSecPkgContext_LogoffTime} - SecPkgContext_LogoffTime = record - tsLogoffTime: TimeStamp; - end; - {$EXTERNALSYM SecPkgContext_LogoffTime} - - PSecPkgContext_SessionKey = ^SecPkgContext_SessionKey; - {$EXTERNALSYM PSecPkgContext_SessionKey} - SecPkgContext_SessionKey = record - SessionKeyLength: ULONG; - SessionKey: PUCHAR; - end; - {$EXTERNALSYM SecPkgContext_SessionKey} - - // used by nego2 - PSecPkgContext_NegoKeys = ^SecPkgContext_NegoKeys; - {$EXTERNALSYM PSecPkgContext_NegoKeys} - SecPkgContext_NegoKeys = record - KeyType: ULONG; - KeyLength: USHORT; - KeyValue: PUCHAR; - VerifyKeyType: ULONG; - VerifyKeyLength: USHORT; - VerifyKeyValue: PUCHAR; - end; - {$EXTERNALSYM SecPkgContext_NegoKeys} - - PSecPkgContext_PackageInfoW = ^SecPkgContext_PackageInfoW; - {$EXTERNALSYM PSecPkgContext_PackageInfoW} - SecPkgContext_PackageInfoW = record - PackageInfo: PSecPkgInfoW; - end; - {$EXTERNALSYM SecPkgContext_PackageInfoW} - - PSecPkgContext_PackageInfoA = ^SecPkgContext_PackageInfoA; - {$EXTERNALSYM PSecPkgContext_PackageInfoA} - SecPkgContext_PackageInfoA = record - PackageInfo: PSecPkgInfoA; - end; - {$EXTERNALSYM SecPkgContext_PackageInfoA} - - PSecPkgContext_UserFlags = ^SecPkgContext_UserFlags; - {$EXTERNALSYM PSecPkgContext_UserFlags} - SecPkgContext_UserFlags = record - UserFlags: ULONG; - end; - {$EXTERNALSYM SecPkgContext_UserFlags} - - PSecPkgContext_Flags = ^SecPkgContext_Flags; - {$EXTERNALSYM PSecPkgContext_Flags} - SecPkgContext_Flags = record - Flags: ULONG; - end; - {$EXTERNALSYM SecPkgContext_Flags} - -{$IFDEF SSPI_UNICODE} - SecPkgContext_PackageInfo = SecPkgContext_PackageInfoW; - PSecPkgContext_PackageInfo = PSecPkgContext_PackageInfoW; -{$ELSE} - SecPkgContext_PackageInfo = SecPkgContext_PackageInfoA; - PSecPkgContext_PackageInfo = PSecPkgContext_PackageInfoA; -{$ENDIF} - {$EXTERNALSYM SecPkgContext_PackageInfo} - {$EXTERNALSYM PSecPkgContext_PackageInfo} - - PSecPkgContext_NegotiationInfoA = ^SecPkgContext_NegotiationInfoA; - {$EXTERNALSYM PSecPkgContext_NegotiationInfoA} - SecPkgContext_NegotiationInfoA = record - PackageInfo: PSecPkgInfoA; - NegotiationState: ULONG; - end; - {$EXTERNALSYM SecPkgContext_NegotiationInfoA} - - PSecPkgContext_NegotiationInfoW = ^SecPkgContext_NegotiationInfoW; - {$EXTERNALSYM PSecPkgContext_NegotiationInfoW} - SecPkgContext_NegotiationInfoW = record - PackageInfo: PSecPkgInfoW; - NegotiationState: ULONG; - end; - {$EXTERNALSYM SecPkgContext_NegotiationInfoW} - -{$IFDEF SSPI_UNICODE} - SecPkgContext_NegotiationInfo = SecPkgContext_NegotiationInfoW; - PSecPkgContext_NegotiationInfo = PSecPkgContext_NegotiationInfoW; -{$ELSE} - SecPkgContext_NegotiationInfo = SecPkgContext_NegotiationInfoA; - PSecPkgContext_NegotiationInfo = PSecPkgContext_NegotiationInfoA; -{$ENDIF} - {$EXTERNALSYM SecPkgContext_NegotiationInfo} - {$EXTERNALSYM PSecPkgContext_NegotiationInfo} - -const - - SECPKG_NEGOTIATION_COMPLETE = 0; - {$EXTERNALSYM SECPKG_NEGOTIATION_COMPLETE} - SECPKG_NEGOTIATION_OPTIMISTIC = 1; - {$EXTERNALSYM SECPKG_NEGOTIATION_OPTIMISTIC} - SECPKG_NEGOTIATION_IN_PROGRESS = 2; - {$EXTERNALSYM SECPKG_NEGOTIATION_IN_PROGRESS} - SECPKG_NEGOTIATION_DIRECT = 3; - {$EXTERNALSYM SECPKG_NEGOTIATION_DIRECT} - SECPKG_NEGOTIATION_TRY_MULTICRED = 4; - {$EXTERNALSYM SECPKG_NEGOTIATION_TRY_MULTICRED} - -type - - PSecPkgContext_NativeNamesW = ^SecPkgContext_NativeNamesW; - {$EXTERNALSYM PSecPkgContext_NativeNamesW} - SecPkgContext_NativeNamesW = record - sClientName: PSEC_WCHAR; - sServerName: PSEC_WCHAR; - end; - {$EXTERNALSYM SecPkgContext_NativeNamesW} - - PSecPkgContext_NativeNamesA = ^SecPkgContext_NativeNamesA; - {$EXTERNALSYM PSecPkgContext_NativeNamesA} - SecPkgContext_NativeNamesA = record - sClientName: PSEC_CHAR; - sServerName: PSEC_CHAR; - end; - {$EXTERNALSYM SecPkgContext_NativeNamesA} - -{$IFDEF SSPI_UNICODE} - SecPkgContext_NativeNames = SecPkgContext_NativeNamesW; - PSecPkgContext_NativeNames = PSecPkgContext_NativeNamesW; -{$ELSE} - SecPkgContext_NativeNames = SecPkgContext_NativeNamesA; - PSecPkgContext_NativeNames = PSecPkgContext_NativeNamesA; -{$ENDIF} - {$EXTERNALSYM SecPkgContext_NativeNames} - {$EXTERNALSYM PSecPkgContext_NativeNames} - - PSecPkgContext_CredentialNameW = ^SecPkgContext_CredentialNameW; - {$EXTERNALSYM PSecPkgContext_CredentialNameW} - SecPkgContext_CredentialNameW = record - CredentialType: ULONG; - sCredentialName: PSEC_WCHAR; - end; - {$EXTERNALSYM SecPkgContext_CredentialNameW} - - PSecPkgContext_CredentialNameA = ^SecPkgContext_CredentialNameA; - {$EXTERNALSYM PSecPkgContext_CredentialNameA} - SecPkgContext_CredentialNameA = record - CredentialType: ULONG; - sCredentialName: PSEC_CHAR; - end; - {$EXTERNALSYM SecPkgContext_CredentialNameA} - -{$IFDEF SSPI_UNICODE} - SecPkgContext_CredentialName = SecPkgContext_CredentialNameW; - PSecPkgContext_CredentialName = PSecPkgContext_CredentialNameW; -{$ELSE} - SecPkgContext_CredentialName = SecPkgContext_CredentialNameA; - PSecPkgContext_CredentialName = PSecPkgContext_CredentialNameA; -{$ENDIF} - {$EXTERNALSYM SecPkgContext_CredentialName} - {$EXTERNALSYM PSecPkgContext_CredentialName} - - PSecPkgContext_AccessToken = ^SecPkgContext_AccessToken; - {$EXTERNALSYM PSecPkgContext_AccessToken} - SecPkgContext_AccessToken = record - AccessToken: PVOID; - end; - {$EXTERNALSYM SecPkgContext_AccessToken} - - PSecPkgContext_TargetInformation = ^SecPkgContext_TargetInformation; - {$EXTERNALSYM PSecPkgContext_TargetInformation} - SecPkgContext_TargetInformation = record - MarshalledTargetInfoLength: ULONG; - MarshalledTargetInfo: PUCHAR; - end; - {$EXTERNALSYM SecPkgContext_TargetInformation} - - PSecPkgContext_AuthzID = ^SecPkgContext_AuthzID; - {$EXTERNALSYM PSecPkgContext_AuthzID} - SecPkgContext_AuthzID = record - AuthzIDLength: ULONG; - AuthzID: PAnsiChar; - end; - {$EXTERNALSYM SecPkgContext_AuthzID} - - PSecPkgContext_Target = ^SecPkgContext_Target; - {$EXTERNALSYM PSecPkgContext_Target} - SecPkgContext_Target = record - TargetLength: ULONG; - Target: PAnsiChar; - end; - {$EXTERNALSYM SecPkgContext_Target} - - PSecPkgContext_ClientSpecifiedTarget = ^SecPkgContext_ClientSpecifiedTarget; - {$EXTERNALSYM PSecPkgContext_ClientSpecifiedTarget} - SecPkgContext_ClientSpecifiedTarget = record - sTargetName: PSEC_WCHAR; - end; - {$EXTERNALSYM SecPkgContext_ClientSpecifiedTarget} - - PSecPkgContext_Bindings = ^SecPkgContext_Bindings; - {$EXTERNALSYM PSecPkgContext_Bindings} - SecPkgContext_Bindings = record - BindingsLength: ULONG; - Bindings: PSEC_CHANNEL_BINDINGS; - end; - {$EXTERNALSYM SecPkgContext_Bindings} - - SEC_GET_KEY_FN = procedure( - Arg: PVOID; // Argument passed in - Principal: PVOID; // Principal ID - KeyVer: ULONG; // Key Version - Key: PPVOID; // Returned ptr to key - Status: PSECURITY_STATUS // returned status - ); stdcall; - {$EXTERNALSYM SEC_GET_KEY_FN} - -// -// Flags for ExportSecurityContext -// - -const - - SECPKG_CONTEXT_EXPORT_RESET_NEW = $00000001; // New context is reset to initial state - {$EXTERNALSYM SECPKG_CONTEXT_EXPORT_RESET_NEW} - SECPKG_CONTEXT_EXPORT_DELETE_OLD = $00000002; // Old context is deleted during export - {$EXTERNALSYM SECPKG_CONTEXT_EXPORT_DELETE_OLD} - // This is only valid in W2K3SP1 and greater - SECPKG_CONTEXT_EXPORT_TO_KERNEL = $00000004; // Context is to be transferred to the kernel - {$EXTERNALSYM SECPKG_CONTEXT_EXPORT_TO_KERNEL} - - -type - - ACQUIRE_CREDENTIALS_HANDLE_FN_W = function( // AcquireCredentialsHandleW - pszPrincipal: PSEC_WCHAR; // Name of principal - pszPackage: PSEC_WCHAR; // Name of package - fCredentialUse: ULONG; // Flags indicating use - pvLogonId: PVOID; // Pointer to logon ID - pAuthData: PVOID; // Package specific data - pGetKeyFn: SEC_GET_KEY_FN; // Pointer to GetKey() func - pvGetKeyArgument: PVOID; // Value to pass to GetKey() - phCredential: PCredHandle; // (out) Cred Handle - ptsExpiry: PTimeStamp // (out) Lifetime (optional) - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM ACQUIRE_CREDENTIALS_HANDLE_FN_W} - - ACQUIRE_CREDENTIALS_HANDLE_FN_A = function( // AcquireCredentialsHandleW - pszPrincipal: PSEC_CHAR; // Name of principal - pszPackage: PSEC_CHAR; // Name of package - fCredentialUse: ULONG; // Flags indicating use - pvLogonId: PVOID; // Pointer to logon ID - pAuthData: PVOID; // Package specific data - pGetKeyFn: SEC_GET_KEY_FN; // Pointer to GetKey() func - pvGetKeyArgument: PVOID; // Value to pass to GetKey() - phCredential: PCredHandle; // (out) Cred Handle - ptsExpiry: PTimeStamp // (out) Lifetime (optional) - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM ACQUIRE_CREDENTIALS_HANDLE_FN_A} - -{$IFDEF SSPI_UNICODE} - ACQUIRE_CREDENTIALS_HANDLE_FN = ACQUIRE_CREDENTIALS_HANDLE_FN_W; -{$ELSE} - ACQUIRE_CREDENTIALS_HANDLE_FN = ACQUIRE_CREDENTIALS_HANDLE_FN_A; -{$ENDIF} - {$EXTERNALSYM ACQUIRE_CREDENTIALS_HANDLE_FN} - - FREE_CREDENTIALS_HANDLE_FN = function( // FreeCredentialsHandle - phCredential: PCredHandle // Handle to free - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM FREE_CREDENTIALS_HANDLE_FN} - - ADD_CREDENTIALS_FN_W = function( // AddCredentialsW - hCredentials: PCredHandle; - pszPrincipal: PSEC_WCHAR; // Name of principal - pszPackage: PSEC_WCHAR; // Name of package - fCredentialUse: ULONG; // Flags indicating use - pAuthData: PVOID; // Package specific data - pGetKeyFn: SEC_GET_KEY_FN; // Pointer to GetKey() func - pvGetKeyArgument: PVOID; // Value to pass to GetKey() - ptsExpiry: PTimeStamp // (out) Lifetime (optional) - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM ADD_CREDENTIALS_FN_W} - - ADD_CREDENTIALS_FN_A = function( // AddCredentialsA - hCredentials: PCredHandle; - pszPrincipal: PSEC_CHAR; // Name of principal - pszPackage: PSEC_CHAR; // Name of package - fCredentialUse: ULONG; // Flags indicating use - pAuthData: PVOID; // Package specific data - pGetKeyFn: SEC_GET_KEY_FN; // Pointer to GetKey() func - pvGetKeyArgument: PVOID; // Value to pass to GetKey() - ptsExpiry: PTimeStamp // (out) Lifetime (optional) - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM ADD_CREDENTIALS_FN_A} - -{$IFDEF SSPI_UNICODE} - ADD_CREDENTIALS_FN = ADD_CREDENTIALS_FN_W; -{$ELSE} - ADD_CREDENTIALS_FN = ADD_CREDENTIALS_FN_A; -{$ENDIF} - {$EXTERNALSYM ADD_CREDENTIALS_FN} - -(* -#ifdef WIN32_CHICAGO -SECURITY_STATUS SEC_ENTRY -SspiLogonUserW( - SEC_WCHAR SEC_FAR * pszPackage, // Name of package - SEC_WCHAR SEC_FAR * pszUserName, // Name of package - SEC_WCHAR SEC_FAR * pszDomainName, // Name of package - SEC_WCHAR SEC_FAR * pszPassword // Name of package - ); - -typedef SECURITY_STATUS -(SEC_ENTRY * SSPI_LOGON_USER_FN_W)( - SEC_CHAR SEC_FAR *, - SEC_CHAR SEC_FAR *, - SEC_CHAR SEC_FAR *, - SEC_CHAR SEC_FAR * ); - -SECURITY_STATUS SEC_ENTRY -SspiLogonUserA( - SEC_CHAR SEC_FAR * pszPackage, // Name of package - SEC_CHAR SEC_FAR * pszUserName, // Name of package - SEC_CHAR SEC_FAR * pszDomainName, // Name of package - SEC_CHAR SEC_FAR * pszPassword // Name of package - ); - -typedef SECURITY_STATUS -(SEC_ENTRY * SSPI_LOGON_USER_FN_A)( - SEC_CHAR SEC_FAR *, - SEC_CHAR SEC_FAR *, - SEC_CHAR SEC_FAR *, - SEC_CHAR SEC_FAR * ); - -#ifdef UNICODE -#define SspiLogonUser SspiLogonUserW // ntifs -#define SSPI_LOGON_USER_FN SSPI_LOGON_USER_FN_W -#else -#define SspiLogonUser SspiLogonUserA -#define SSPI_LOGON_USER_FN SSPI_LOGON_USER_FN_A -#endif // !UNICODE -#endif // WIN32_CHICAGO -*) - -//////////////////////////////////////////////////////////////////////// -/// -/// Password Change Functions -/// -//////////////////////////////////////////////////////////////////////// - - CHANGE_PASSWORD_FN_W = function( // ChangeAccountPasswordW - pszPackageName: PSEC_WCHAR; - pszDomainName: PSEC_WCHAR; - pszAccountName: PSEC_WCHAR; - pszOldPassword: PSEC_WCHAR; - pszNewPassword: PSEC_WCHAR; - bImpersonating: BOOLEAN; - dwReserved: ULONG; - pOutput: PSecBufferDesc - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM CHANGE_PASSWORD_FN_W} - - CHANGE_PASSWORD_FN_A = function( // ChangeAccountPasswordA - pszPackageName: PSEC_CHAR; - pszDomainName: PSEC_CHAR; - pszAccountName: PSEC_CHAR; - pszOldPassword: PSEC_CHAR; - pszNewPassword: PSEC_CHAR; - bImpersonating: BOOLEAN; - dwReserved: ULONG; - pOutput: PSecBufferDesc - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM CHANGE_PASSWORD_FN_A} - -{$IFDEF SSPI_UNICODE} - CHANGE_PASSWORD_FN = CHANGE_PASSWORD_FN_W; -{$ELSE} - CHANGE_PASSWORD_FN = CHANGE_PASSWORD_FN_A; -{$ENDIF} - {$EXTERNALSYM CHANGE_PASSWORD_FN} - -//////////////////////////////////////////////////////////////////////// -/// -/// Context Management Functions -/// -//////////////////////////////////////////////////////////////////////// - - INITIALIZE_SECURITY_CONTEXT_FN_W = function( // InitializeSecurityContextW - phCredential: PCredHandle; // Cred to base context - phContext: PCtxtHandle; // Existing context (OPT) - pszTargetName: PSEC_WCHAR; // Name of target - fContextReq: ULONG; // Context Requirements - Reserved1: ULONG; // Reserved, MBZ - TargetDataRep: ULONG; // Data rep of target - pInput: PSecBufferDesc; // Input Buffers - Reserved2: ULONG; // Reserved, MBZ - phNewContext: PCtxtHandle; // (out) New Context handle - pOutput: PSecBufferDesc; // (inout) Output Buffers - pfContextAttr: PULONG; // (out) Context attrs - ptsExpiry: PTimeStamp // (out) Life span (OPT) - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM INITIALIZE_SECURITY_CONTEXT_FN_W} - - INITIALIZE_SECURITY_CONTEXT_FN_A = function( // InitializeSecurityContextA - phCredential: PCredHandle; // Cred to base context - phContext: PCtxtHandle; // Existing context (OPT) - pszTargetName: PSEC_CHAR; // Name of target - fContextReq: ULONG; // Context Requirements - Reserved1: ULONG; // Reserved, MBZ - TargetDataRep: ULONG; // Data rep of target - pInput: PSecBufferDesc; // Input Buffers - Reserved2: ULONG; // Reserved, MBZ - phNewContext: PCtxtHandle; // (out) New Context handle - pOutput: PSecBufferDesc; // (inout) Output Buffers - pfContextAttr: PULONG; // (out) Context attrs - ptsExpiry: PTimeStamp // (out) Life span (OPT) - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM INITIALIZE_SECURITY_CONTEXT_FN_A} - -{$IFDEF SSPI_UNICODE} - INITIALIZE_SECURITY_CONTEXT_FN = INITIALIZE_SECURITY_CONTEXT_FN_W; -{$ELSE} - INITIALIZE_SECURITY_CONTEXT_FN = INITIALIZE_SECURITY_CONTEXT_FN_A; -{$ENDIF} - {$EXTERNALSYM INITIALIZE_SECURITY_CONTEXT_FN} - - ACCEPT_SECURITY_CONTEXT_FN = function( // AcceptSecurityContext - phCredential: PCredHandle; // Cred to base context - phContext: PCtxtHandle; // Existing context (OPT) - pInput: PSecBufferDesc; // Input buffer - fContextReq: ULONG; // Context Requirements - TargetDataRep: ULONG; // Target Data Rep - phNewContext: PCtxtHandle; // (out) New context handle - pOutput: PSecBufferDesc; // (inout) Output buffers - pfContextAttr: PULONG; // (out) Context attributes - ptsExpiry: PTimeStamp // (out) Life span (OPT) - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM ACCEPT_SECURITY_CONTEXT_FN} - - COMPLETE_AUTH_TOKEN_FN = function( // CompleteAuthToken - phContext: PCtxtHandle; // Context to complete - pToken: PSecBufferDesc // Token to complete - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM COMPLETE_AUTH_TOKEN_FN} - - IMPERSONATE_SECURITY_CONTEXT_FN = function( // ImpersonateSecurityContext - phContext: PCtxtHandle - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM IMPERSONATE_SECURITY_CONTEXT_FN} - - REVERT_SECURITY_CONTEXT_FN = function( // RevertSecurityContext - phContext: PCtxtHandle - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM REVERT_SECURITY_CONTEXT_FN} - - QUERY_SECURITY_CONTEXT_TOKEN_FN = function( // QuerySecurityContextToken - phContext: PCtxtHandle; - Token: PPVOID - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM QUERY_SECURITY_CONTEXT_TOKEN_FN} - - DELETE_SECURITY_CONTEXT_FN = function( // DeleteSecurityContext - phContext: PCtxtHandle - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM DELETE_SECURITY_CONTEXT_FN} - - APPLY_CONTROL_TOKEN_FN = function( // ApplyControlToken - phContext: PCtxtHandle; // Context to modify - pInput: PSecBufferDesc // Input token to apply - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM APPLY_CONTROL_TOKEN_FN} - - QUERY_CONTEXT_ATTRIBUTES_FN_W = function( // QueryContextAttributesW - phContext: PCtxtHandle; // Context to query - ulAttribute: ULONG; // Attribute to query - pBuffer: PVOID // Buffer for attributes - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM QUERY_CONTEXT_ATTRIBUTES_FN_W} - - QUERY_CONTEXT_ATTRIBUTES_FN_A = function( // QueryContextAttributesA - phContext: PCtxtHandle; // Context to query - ulAttribute: ULONG; // Attribute to query - pBuffer: PVOID // Buffer for attributes - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM QUERY_CONTEXT_ATTRIBUTES_FN_A} - -{$IFDEF SSPI_UNICODE} - QUERY_CONTEXT_ATTRIBUTES_FN = QUERY_CONTEXT_ATTRIBUTES_FN_W; -{$ELSE} - QUERY_CONTEXT_ATTRIBUTES_FN = QUERY_CONTEXT_ATTRIBUTES_FN_A; -{$ENDIF} - {$EXTERNALSYM QUERY_CONTEXT_ATTRIBUTES_FN} - - SET_CONTEXT_ATTRIBUTES_FN_W = function( // SetContextAttributesW - phContext: PCtxtHandle; // Context to Set - ulAttribute: ULONG; // Attribute to Set - pBuffer: PVOID; // Buffer for attributes - cbBuffer: ULONG // Size (in bytes) of Buffer - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM SET_CONTEXT_ATTRIBUTES_FN_W} - - SET_CONTEXT_ATTRIBUTES_FN_A = function( // SetContextAttributesA - phContext: PCtxtHandle; // Context to Set - ulAttribute: ULONG; // Attribute to Set - pBuffer: PVOID; // Buffer for attributes - cbBuffer: ULONG // Size (in bytes) of Buffer - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM SET_CONTEXT_ATTRIBUTES_FN_A} - - QUERY_CREDENTIALS_ATTRIBUTES_FN_W = function( // QueryCredentialsAttributesW - phCredential: PCredHandle; // Credential to query - ulAttribute: ULONG; // Attribute to query - pBuffer: PVOID // Buffer for attributes - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM QUERY_CREDENTIALS_ATTRIBUTES_FN_W} - - QUERY_CREDENTIALS_ATTRIBUTES_FN_A = function( // QueryCredentialsAttributesA - phCredential: PCredHandle; // Credential to query - ulAttribute: ULONG; // Attribute to query - pBuffer: PVOID // Buffer for attributes - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM QUERY_CREDENTIALS_ATTRIBUTES_FN_A} - -{$IFDEF SSPI_UNICODE} - QUERY_CREDENTIALS_ATTRIBUTES_FN = QUERY_CREDENTIALS_ATTRIBUTES_FN_W; -{$ELSE} - QUERY_CREDENTIALS_ATTRIBUTES_FN = QUERY_CREDENTIALS_ATTRIBUTES_FN_A; -{$ENDIF} - {$EXTERNALSYM QUERY_CREDENTIALS_ATTRIBUTES_FN} - - SET_CREDENTIALS_ATTRIBUTES_FN_W = function( // SetCredentialsAttributesW - phCredential: PCredHandle; // Credential to Set - ulAttribute: ULONG; // Attribute to Set - pBuffer: PVOID; // Buffer for attributes - cbBuffer: ULONG // Size (in bytes) of Buffer - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM SET_CREDENTIALS_ATTRIBUTES_FN_W} - - SET_CREDENTIALS_ATTRIBUTES_FN_A = function( // SetCredentialsAttributesA - phCredential: PCredHandle; // Credential to Set - ulAttribute: ULONG; // Attribute to Set - pBuffer: PVOID; // Buffer for attributes - cbBuffer: ULONG // Size (in bytes) of Buffer - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM SET_CREDENTIALS_ATTRIBUTES_FN_A} - - FREE_CONTEXT_BUFFER_FN = function( // FreeContextBuffer - pvContextBuffer: PVOID // buffer to free - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM FREE_CONTEXT_BUFFER_FN} - -/////////////////////////////////////////////////////////////////// -//// -//// Message Support API -//// -////////////////////////////////////////////////////////////////// - -type - - MAKE_SIGNATURE_FN = function( // MakeSignature - phContext: PCtxtHandle; // Context to use - fQOP: ULONG; // Quality of Protection - pMessage: PSecBufferDesc; // Message to sign - MessageSeqNo: ULONG // Message Sequence Num. - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM MAKE_SIGNATURE_FN} - - VERIFY_SIGNATURE_FN = function( // VerifySignature - phContext: PCtxtHandle; // Context to use - pMessage: PSecBufferDesc; // Message to verify - MessageSeqNo: ULONG; // Sequence Num. - pfQOP: PULONG // QOP used - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM VERIFY_SIGNATURE_FN} - - ENCRYPT_MESSAGE_FN = function( // EncryptMessage - phContext: PCtxtHandle; - fQOP: ULONG; - pMessage: PSecBufferDesc; - MessageSeqNo: ULONG - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM ENCRYPT_MESSAGE_FN} - - DECRYPT_MESSAGE_FN = function( // DecryptMessage - phContext: PCtxtHandle; - pMessage: PSecBufferDesc; - MessageSeqNo: ULONG; - pfQOP: PULONG - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM DECRYPT_MESSAGE_FN} - -/////////////////////////////////////////////////////////////////////////// -//// -//// Misc. -//// -/////////////////////////////////////////////////////////////////////////// - -type - - ENUMERATE_SECURITY_PACKAGES_FN_W = function( // EnumerateSecurityPackagesW - pcPackages: PULONG; // Receives num. packages - ppPackageInfo: PPSecPkgInfoW // Receives array of info - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM ENUMERATE_SECURITY_PACKAGES_FN_W} - - ENUMERATE_SECURITY_PACKAGES_FN_A = function( // EnumerateSecurityPackagesA - pcPackages: PULONG; // Receives num. packages - ppPackageInfo: PPSecPkgInfoA // Receives array of info - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM ENUMERATE_SECURITY_PACKAGES_FN_A} - -{$IFDEF SSPI_UNICODE} - ENUMERATE_SECURITY_PACKAGES_FN = ENUMERATE_SECURITY_PACKAGES_FN_W; -{$ELSE} - ENUMERATE_SECURITY_PACKAGES_FN = ENUMERATE_SECURITY_PACKAGES_FN_A; -{$ENDIF} - {$EXTERNALSYM ENUMERATE_SECURITY_PACKAGES_FN} - - QUERY_SECURITY_PACKAGE_INFO_FN_W = function( // QuerySecurityPackageInfoW - pszPackageName: PSEC_WCHAR; // Name of package - ppPackageInfo: PPSecPkgInfoW // Receives package info - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM QUERY_SECURITY_PACKAGE_INFO_FN_W} - - QUERY_SECURITY_PACKAGE_INFO_FN_A = function( // QuerySecurityPackageInfoA - pszPackageName: PSEC_CHAR; // Name of package - ppPackageInfo: PPSecPkgInfoA // Receives package info - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM QUERY_SECURITY_PACKAGE_INFO_FN_A} - -{$IFDEF SSPI_UNICODE} - QUERY_SECURITY_PACKAGE_INFO_FN = QUERY_SECURITY_PACKAGE_INFO_FN_W; -{$ELSE} - QUERY_SECURITY_PACKAGE_INFO_FN = QUERY_SECURITY_PACKAGE_INFO_FN_A; -{$ENDIF} - {$EXTERNALSYM QUERY_SECURITY_PACKAGE_INFO_FN} - - PSecDelegationType = ^SecDelegationType; - {$EXTERNALSYM PSecDelegationType} - SecDelegationType = ( - SecFull, - SecService, - SecTree, - SecDirectory, - SecObject - ); - {$EXTERNALSYM SecDelegationType} - - DELEGATE_SECURITY_CONTEXT_FN = function( // DelegateSecurityContext - phContext: PCtxtHandle; // IN Active context to delegate - pszTarget: PSEC_CHAR; - DelegationType: SecDelegationType; // IN Type of delegation - pExpiry: PTimeStamp; // IN OPTIONAL time limit - pPackageParameters: PSecBuffer; // IN OPTIONAL package specific - pOutput: PSecBufferDesc // OUT Token for applycontroltoken. - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM DELEGATE_SECURITY_CONTEXT_FN} - -/////////////////////////////////////////////////////////////////////////// -//// -//// Proxies -//// -/////////////////////////////////////////////////////////////////////////// - -// -// Proxies are only available on NT platforms -// - -/////////////////////////////////////////////////////////////////////////// -//// -//// Context export/import -//// -/////////////////////////////////////////////////////////////////////////// - -type - - EXPORT_SECURITY_CONTEXT_FN = function( // ExportSecurityContext - phContext: PCtxtHandle; // (in) context to export - fFlags: ULONG; // (in) option flags - pPackedContext: PSecBuffer; // (out) marshalled context - pToken: PPVOID // (out, optional) token handle for impersonation - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM EXPORT_SECURITY_CONTEXT_FN} - - IMPORT_SECURITY_CONTEXT_FN_W = function( // ImportSecurityContextW - pszPackage: PSEC_WCHAR; - pPackedContext: PSecBuffer; // (in) marshalled context - Token: PVOID; // (in, optional) handle to token for context - phContext: PCtxtHandle // (out) new context handle - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM IMPORT_SECURITY_CONTEXT_FN_W} - - IMPORT_SECURITY_CONTEXT_FN_A = function( // ImportSecurityContextA - pszPackage: PSEC_CHAR; - pPackedContext: PSecBuffer; // (in) marshalled context - Token: PVOID; // (in, optional) handle to token for context - phContext: PCtxtHandle // (out) new context handle - ): SECURITY_STATUS; stdcall; - {$EXTERNALSYM IMPORT_SECURITY_CONTEXT_FN_A} - -{$IFDEF SSPI_UNICODE} - IMPORT_SECURITY_CONTEXT_FN = IMPORT_SECURITY_CONTEXT_FN_W; -{$ELSE} - IMPORT_SECURITY_CONTEXT_FN = IMPORT_SECURITY_CONTEXT_FN_A; -{$ENDIF} - {$EXTERNALSYM IMPORT_SECURITY_CONTEXT_FN} - -/////////////////////////////////////////////////////////////////////////////// -//// -//// Fast access for RPC: -//// -/////////////////////////////////////////////////////////////////////////////// - -const - - SECURITY_ENTRYPOINT_ANSIW = 'InitSecurityInterfaceW'; {Do not Localize} - {$EXTERNALSYM SECURITY_ENTRYPOINT_ANSIW} - SECURITY_ENTRYPOINT_ANSIA = 'InitSecurityInterfaceA'; {Do not Localize} - {$EXTERNALSYM SECURITY_ENTRYPOINT_ANSIA} - SECURITY_ENTRYPOINTW = 'InitSecurityInterfaceW'; {Do not Localize} - {$EXTERNALSYM SECURITY_ENTRYPOINTW} - SECURITY_ENTRYPOINTA = 'InitSecurityInterfaceA'; {Do not Localize} - {$EXTERNALSYM SECURITY_ENTRYPOINTA} - SECURITY_ENTRYPOINT16 = 'INITSECURITYINTERFACEA'; {Do not Localize} - {$EXTERNALSYM SECURITY_ENTRYPOINT16} - -{$IFDEF SSPI_UNICODE} - SECURITY_ENTRYPOINT = SECURITY_ENTRYPOINTW; - SECURITY_ENTRYPOINT_ANSI = SECURITY_ENTRYPOINTW; -{$ELSE} - SECURITY_ENTRYPOINT = SECURITY_ENTRYPOINTA; - SECURITY_ENTRYPOINT_ANSI = SECURITY_ENTRYPOINTA; -{$ENDIF} - {$EXTERNALSYM SECURITY_ENTRYPOINT} - {$EXTERNALSYM SECURITY_ENTRYPOINT_ANSI} - -type - - PSecurityFunctionTableW = ^SecurityFunctionTableW; - {$EXTERNALSYM PSecurityFunctionTableW} - SecurityFunctionTableW = record - dwVersion: ULONG; - EnumerateSecurityPackagesW: ENUMERATE_SECURITY_PACKAGES_FN_W; - QueryCredentialsAttributesW: QUERY_CREDENTIALS_ATTRIBUTES_FN_W; - AcquireCredentialsHandleW: ACQUIRE_CREDENTIALS_HANDLE_FN_W; - FreeCredentialsHandle: FREE_CREDENTIALS_HANDLE_FN; - Reserved2: PVOID; - InitializeSecurityContextW: INITIALIZE_SECURITY_CONTEXT_FN_W; - AcceptSecurityContext: ACCEPT_SECURITY_CONTEXT_FN; - CompleteAuthToken: COMPLETE_AUTH_TOKEN_FN; - DeleteSecurityContext: DELETE_SECURITY_CONTEXT_FN; - ApplyControlToken: APPLY_CONTROL_TOKEN_FN; - QueryContextAttributesW: QUERY_CONTEXT_ATTRIBUTES_FN_W; - ImpersonateSecurityContext: IMPERSONATE_SECURITY_CONTEXT_FN; - RevertSecurityContext: REVERT_SECURITY_CONTEXT_FN; - MakeSignature: MAKE_SIGNATURE_FN; - VerifySignature: VERIFY_SIGNATURE_FN; - FreeContextBuffer: FREE_CONTEXT_BUFFER_FN; - QuerySecurityPackageInfoW: QUERY_SECURITY_PACKAGE_INFO_FN_W; - Reserved3: PVOID; - Reserved4: PVOID; - ExportSecurityContext: EXPORT_SECURITY_CONTEXT_FN; - ImportSecurityContextW: IMPORT_SECURITY_CONTEXT_FN_W; - AddCredentialsW: ADD_CREDENTIALS_FN_W; - Reserved8: PVOID; - QuerySecurityContextToken: QUERY_SECURITY_CONTEXT_TOKEN_FN; - EncryptMessage: ENCRYPT_MESSAGE_FN; - DecryptMessage: DECRYPT_MESSAGE_FN; - // Fields below this are available in OSes after w2k - SetContextAttributesW: SET_CONTEXT_ATTRIBUTES_FN_W; - // Fields below this are available in OSes after W2k3SP1 - SetCredentialsAttributesW: SET_CREDENTIALS_ATTRIBUTES_FN_W; - ChangeAccountPasswordW: CHANGE_PASSWORD_FN_W; - end; - {$EXTERNALSYM SecurityFunctionTableW} - - PSecurityFunctionTableA = ^SecurityFunctionTableA; - {$EXTERNALSYM PSecurityFunctionTableA} - SecurityFunctionTableA = record - dwVersion: ULONG; - EnumerateSecurityPackagesA: ENUMERATE_SECURITY_PACKAGES_FN_A; - QueryCredentialsAttributesA: QUERY_CREDENTIALS_ATTRIBUTES_FN_A; - AcquireCredentialsHandleA: ACQUIRE_CREDENTIALS_HANDLE_FN_A; - FreeCredentialsHandle: FREE_CREDENTIALS_HANDLE_FN; - Reserved2: PVOID; - InitializeSecurityContextA: INITIALIZE_SECURITY_CONTEXT_FN_A; - AcceptSecurityContext: ACCEPT_SECURITY_CONTEXT_FN; - CompleteAuthToken: COMPLETE_AUTH_TOKEN_FN; - DeleteSecurityContext: DELETE_SECURITY_CONTEXT_FN; - ApplyControlToken: APPLY_CONTROL_TOKEN_FN; - QueryContextAttributesA: QUERY_CONTEXT_ATTRIBUTES_FN_A; - ImpersonateSecurityContext: IMPERSONATE_SECURITY_CONTEXT_FN; - RevertSecurityContext: REVERT_SECURITY_CONTEXT_FN; - MakeSignature: MAKE_SIGNATURE_FN; - VerifySignature: VERIFY_SIGNATURE_FN; - FreeContextBuffer: FREE_CONTEXT_BUFFER_FN; - QuerySecurityPackageInfoA: QUERY_SECURITY_PACKAGE_INFO_FN_A; - Reserved3: PVOID; - Reserved4: PVOID; - ExportSecurityContext: EXPORT_SECURITY_CONTEXT_FN; - ImportSecurityContextA: IMPORT_SECURITY_CONTEXT_FN_A; - AddCredentialsA: ADD_CREDENTIALS_FN_A; - Reserved8: PVOID; - QuerySecurityContextToken: QUERY_SECURITY_CONTEXT_TOKEN_FN; - EncryptMessage: ENCRYPT_MESSAGE_FN; - DecryptMessage: DECRYPT_MESSAGE_FN; - SetContextAttributesA: SET_CONTEXT_ATTRIBUTES_FN_A; - SetCredentialsAttributesA: SET_CREDENTIALS_ATTRIBUTES_FN_A; - ChangeAccountPasswordA: CHANGE_PASSWORD_FN_A; - end; - {$EXTERNALSYM SecurityFunctionTableA} - -{$IFDEF SSPI_UNICODE} - SecurityFunctionTable = SecurityFunctionTableW; - PSecurityFunctionTable = PSecurityFunctionTableW; -{$ELSE} - SecurityFunctionTable = SecurityFunctionTableA; - PSecurityFunctionTable = PSecurityFunctionTableA; -{$ENDIF} - {$EXTERNALSYM SecurityFunctionTable} - {$EXTERNALSYM PSecurityFunctionTable} - -const - - // Function table has all routines through DecryptMessage - SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION = 1; - {$EXTERNALSYM SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION} - - // Function table has all routines through SetContextAttributes - SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_2 = 2; - {$EXTERNALSYM SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_2} - - // Function table has all routines through SetCredentialsAttributes - SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_3 = 3; - {$EXTERNALSYM SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_3} - - // Function table has all routines through ChangeAccountPassword - SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_4 = 4; - {$EXTERNALSYM SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_4} - -type - - INIT_SECURITY_INTERFACE_A = function // InitSecurityInterfaceA - : PSecurityFunctionTableA; stdcall; - {$EXTERNALSYM INIT_SECURITY_INTERFACE_A} - - INIT_SECURITY_INTERFACE_W = function // InitSecurityInterfaceW - : PSecurityFunctionTableW; stdcall; - {$EXTERNALSYM INIT_SECURITY_INTERFACE_W} - -{$IFDEF SSPI_UNICODE} - INIT_SECURITY_INTERFACE = INIT_SECURITY_INTERFACE_W; -{$ELSE} - INIT_SECURITY_INTERFACE = INIT_SECURITY_INTERFACE_A; -{$ENDIF} - {$EXTERNALSYM INIT_SECURITY_INTERFACE} - - -(* TODO - -// -// SASL Profile Support -// - - -SECURITY_STATUS -SEC_ENTRY -SaslEnumerateProfilesA( - OUT LPSTR * ProfileList, - OUT ULONG * ProfileCount - ); - -SECURITY_STATUS -SEC_ENTRY -SaslEnumerateProfilesW( - OUT LPWSTR * ProfileList, - OUT ULONG * ProfileCount - ); - -#ifdef UNICODE -#define SaslEnumerateProfiles SaslEnumerateProfilesW -#else -#define SaslEnumerateProfiles SaslEnumerateProfilesA -#endif - - -SECURITY_STATUS -SEC_ENTRY -SaslGetProfilePackageA( - IN LPSTR ProfileName, - OUT PSecPkgInfoA * PackageInfo - ); - - -SECURITY_STATUS -SEC_ENTRY -SaslGetProfilePackageW( - IN LPWSTR ProfileName, - OUT PSecPkgInfoW * PackageInfo - ); - -#ifdef UNICODE -#define SaslGetProfilePackage SaslGetProfilePackageW -#else -#define SaslGetProfilePackage SaslGetProfilePackageA -#endif - -SECURITY_STATUS -SEC_ENTRY -SaslIdentifyPackageA( - IN PSecBufferDesc pInput, - OUT PSecPkgInfoA * PackageInfo - ); - -SECURITY_STATUS -SEC_ENTRY -SaslIdentifyPackageW( - IN PSecBufferDesc pInput, - OUT PSecPkgInfoW * PackageInfo - ); - -#ifdef UNICODE -#define SaslIdentifyPackage SaslIdentifyPackageW -#else -#define SaslIdentifyPackage SaslIdentifyPackageA -#endif - -SECURITY_STATUS -SEC_ENTRY -SaslInitializeSecurityContextW( - PCredHandle phCredential, // Cred to base context - PCtxtHandle phContext, // Existing context (OPT) - LPWSTR pszTargetName, // Name of target - unsigned long fContextReq, // Context Requirements - unsigned long Reserved1, // Reserved, MBZ - unsigned long TargetDataRep, // Data rep of target - PSecBufferDesc pInput, // Input Buffers - unsigned long Reserved2, // Reserved, MBZ - PCtxtHandle phNewContext, // (out) New Context handle - PSecBufferDesc pOutput, // (inout) Output Buffers - unsigned long SEC_FAR * pfContextAttr, // (out) Context attrs - PTimeStamp ptsExpiry // (out) Life span (OPT) - ); - -SECURITY_STATUS -SEC_ENTRY -SaslInitializeSecurityContextA( - PCredHandle phCredential, // Cred to base context - PCtxtHandle phContext, // Existing context (OPT) - LPSTR pszTargetName, // Name of target - unsigned long fContextReq, // Context Requirements - unsigned long Reserved1, // Reserved, MBZ - unsigned long TargetDataRep, // Data rep of target - PSecBufferDesc pInput, // Input Buffers - unsigned long Reserved2, // Reserved, MBZ - PCtxtHandle phNewContext, // (out) New Context handle - PSecBufferDesc pOutput, // (inout) Output Buffers - unsigned long SEC_FAR * pfContextAttr, // (out) Context attrs - PTimeStamp ptsExpiry // (out) Life span (OPT) - ); - -#ifdef UNICODE -#define SaslInitializeSecurityContext SaslInitializeSecurityContextW -#else -#define SaslInitializeSecurityContext SaslInitializeSecurityContextA -#endif - - -SECURITY_STATUS -SEC_ENTRY -SaslAcceptSecurityContext( - PCredHandle phCredential, // Cred to base context - PCtxtHandle phContext, // Existing context (OPT) - PSecBufferDesc pInput, // Input buffer - unsigned long fContextReq, // Context Requirements - unsigned long TargetDataRep, // Target Data Rep - PCtxtHandle phNewContext, // (out) New context handle - PSecBufferDesc pOutput, // (inout) Output buffers - unsigned long SEC_FAR * pfContextAttr, // (out) Context attributes - PTimeStamp ptsExpiry // (out) Life span (OPT) - ); - -#define SASL_OPTION_SEND_SIZE 1 // Maximum size to send to peer -#define SASL_OPTION_RECV_SIZE 2 // Maximum size willing to receive -#define SASL_OPTION_AUTHZ_STRING 3 // Authorization string -#define SASL_OPTION_AUTHZ_PROCESSING 4 // Authorization string processing - -typedef enum _SASL_AUTHZID_STATE { - Sasl_AuthZIDForbidden, // allow no AuthZID strings to be specified - error out (default) - Sasl_AuthZIDProcessed // AuthZID Strings processed by Application or SSP -} SASL_AUTHZID_STATE ; - -SECURITY_STATUS -SEC_ENTRY -SaslSetContextOption( - __in PCtxtHandle ContextHandle, - __in ULONG Option, - __in PVOID Value, - __in ULONG Size - ); - - -SECURITY_STATUS -SEC_ENTRY -SaslGetContextOption( - __in PCtxtHandle ContextHandle, - __in ULONG Option, - __out PVOID Value, - __in ULONG Size, - __out_opt PULONG Needed OPTIONAL - ); - -*) - -// -// This is the legacy credentials structure. -// The EX version below is preferred. - -const - - SEC_WINNT_AUTH_IDENTITY_VERSION_2 = $201; - {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_VERSION_2} - -type - - PSEC_WINNT_AUTH_IDENTITY_EX2 = ^SEC_WINNT_AUTH_IDENTITY_EX2; - {$EXTERNALSYM PSEC_WINNT_AUTH_IDENTITY_EX2} - SEC_WINNT_AUTH_IDENTITY_EX2 = record - Version: ULONG; // contains SEC_WINNT_AUTH_IDENTITY_VERSION_2 - cbHeaderLength: USHORT; - cbStructureLength: ULONG; - UserOffset: ULONG; // Non-NULL terminated string, unicode only - UserLength: USHORT; // # of bytes (NOT WCHARs), not including NULL. - DomainOffset: ULONG; // Non-NULL terminated string, unicode only - DomainLength: USHORT; // # of bytes (NOT WCHARs), not including NULL. - PackedCredentialsOffset: ULONG; // Non-NULL terminated string, unicode only - PackedCredentialsLength: USHORT; // # of bytes (NOT WCHARs), not including NULL. - Flags: ULONG; - PackageListOffset: ULONG; // Non-NULL terminated string, unicode only - PackageListLength: USHORT; - end; - {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_EX2} - -// -// This was not defined in NTIFS.h for windows 2000 however -// this struct has always been there and are safe to use -// in windows 2000 and above. -// - -const - - SEC_WINNT_AUTH_IDENTITY_ANSI = $1; - {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_ANSI} - SEC_WINNT_AUTH_IDENTITY_UNICODE = $2; - {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_UNICODE} - -type - - PSEC_WINNT_AUTH_IDENTITY_W = ^SEC_WINNT_AUTH_IDENTITY_W; - {$EXTERNALSYM PSEC_WINNT_AUTH_IDENTITY_W} - SEC_WINNT_AUTH_IDENTITY_W = record - User: PUSHORT; // Non-NULL terminated string. - UserLength: ULONG; // # of characters (NOT bytes), not including NULL. - Domain: PUSHORT; // Non-NULL terminated string. - DomainLength: ULONG; // # of characters (NOT bytes), not including NULL. - Password: PUSHORT; // Non-NULL terminated string. - PasswordLength: ULONG; // # of characters (NOT bytes), not including NULL. - Flags: ULONG; - end; - {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_W} - - PSEC_WINNT_AUTH_IDENTITY_A = ^SEC_WINNT_AUTH_IDENTITY_A; - {$EXTERNALSYM PSEC_WINNT_AUTH_IDENTITY_A} - SEC_WINNT_AUTH_IDENTITY_A = record - User: PUCHAR; // Non-NULL terminated string. - UserLength: ULONG; // # of characters (NOT bytes), not including NULL. - Domain: PUCHAR; // Non-NULL terminated string. - DomainLength: ULONG; // # of characters (NOT bytes), not including NULL. - Password: PUCHAR; // Non-NULL terminated string. - PasswordLength: ULONG; // # of characters (NOT bytes), not including NULL. - Flags: ULONG; - end; - {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_A} - -{$IFDEF SSPI_UNICODE} - SEC_WINNT_AUTH_IDENTITY = SEC_WINNT_AUTH_IDENTITY_W; - PSEC_WINNT_AUTH_IDENTITY = PSEC_WINNT_AUTH_IDENTITY_W; -{$ELSE} - SEC_WINNT_AUTH_IDENTITY = SEC_WINNT_AUTH_IDENTITY_A; - PSEC_WINNT_AUTH_IDENTITY = PSEC_WINNT_AUTH_IDENTITY_A; -{$ENDIF} - {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY} - {$EXTERNALSYM PSEC_WINNT_AUTH_IDENTITY} - -// -// This is the combined authentication identity structure that may be -// used with the negotiate package, NTLM, Kerberos, or SCHANNEL -// - -const - - SEC_WINNT_AUTH_IDENTITY_VERSION = $200; - {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_VERSION} - -type - - PSEC_WINNT_AUTH_IDENTITY_EXW = ^SEC_WINNT_AUTH_IDENTITY_EXW; - {$EXTERNALSYM PSEC_WINNT_AUTH_IDENTITY_EXW} - SEC_WINNT_AUTH_IDENTITY_EXW = record - Version: ULONG; - Length: ULONG; - User: PUSHORT; - UserLength: ULONG; - Domain: PUSHORT; - DomainLength: ULONG; - Password: PUSHORT; - PasswordLength: ULONG; - Flags: ULONG; - PackageList: PUSHORT; - PackageListLength: ULONG; - end; - {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_EXW} - - PSEC_WINNT_AUTH_IDENTITY_EXA = ^SEC_WINNT_AUTH_IDENTITY_EXA; - {$EXTERNALSYM PSEC_WINNT_AUTH_IDENTITY_EXA} - SEC_WINNT_AUTH_IDENTITY_EXA = record - Version: ULONG; - Length: ULONG; - User: PUCHAR; - UserLength: ULONG; - Domain: PUCHAR; - DomainLength: ULONG; - Password: PUCHAR; - PasswordLength: ULONG; - Flags: ULONG; - PackageList: PUCHAR; - PackageListLength: ULONG; - end; - {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_EXA} - -{$IFDEF SSPI_UNICODE} - SEC_WINNT_AUTH_IDENTITY_EX = SEC_WINNT_AUTH_IDENTITY_EXW; -{$ELSE} - SEC_WINNT_AUTH_IDENTITY_EX = SEC_WINNT_AUTH_IDENTITY_EXA; -{$ENDIF} - {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_EX} - -(* TODO - -// -// the procedure for how to parse a SEC_WINNT_AUTH_IDENTITY_INFO structure: -// -// 1) First check the first DWORD of SEC_WINNT_AUTH_IDENTITY_INFO, if the first -// DWORD is 0x200, it is either an AuthIdExw or AuthIdExA, otherwise if the first -// DWORD is 0x201, the structure is an AuthIdEx2 structure. Otherwise the structure -// is either an AuthId_a or an AuthId_w. -// -// 2) Secondly check the flags for SEC_WINNT_AUTH_IDENTITY_ANSI or -// SEC_WINNT_AUTH_IDENTITY_UNICODE, the presence of the former means the structure -// is an ANSI structure. Otherwise, the structure is the wide version. Note that -// AuthIdEx2 does not have an ANSI version so this check does not apply to it. -// - -typedef union _SEC_WINNT_AUTH_IDENTITY_INFO { - SEC_WINNT_AUTH_IDENTITY_EXW AuthIdExw; - SEC_WINNT_AUTH_IDENTITY_EXA AuthIdExa; - SEC_WINNT_AUTH_IDENTITY_A AuthId_a; - SEC_WINNT_AUTH_IDENTITY_W AuthId_w; - SEC_WINNT_AUTH_IDENTITY_EX2 AuthIdEx2; -} SEC_WINNT_AUTH_IDENTITY_INFO, *PSEC_WINNT_AUTH_IDENTITY_INFO; - -// the credential structure is encrypted via -// RtlEncryptMemory(OptionFlags = 0) -#define SEC_WINNT_AUTH_IDENTITY_FLAGS_PROCESS_ENCRYPTED 0x10 - -// the credential structure is protected by local system via -// RtlEncryptMemory(OptionFlags = -// IOCTL_KSEC_ENCRYPT_MEMORY_SAME_LOGON) -#define SEC_WINNT_AUTH_IDENTITY_FLAGS_SYSTEM_PROTECTED 0x20 - -#define SEC_WINNT_AUTH_IDENTITY_FLAGS_RESERVED 0x10000 -#define SEC_WINNT_AUTH_IDENTITY_FLAGS_NULL_USER 0x20000 -#define SEC_WINNT_AUTH_IDENTITY_FLAGS_NULL_DOMAIN 0x40000 - -// -// These bits are for communication between SspiPromptForCredentials() -// and the credential providers. Do not use these bits for any other -// purpose. -// - -#define SEC_WINNT_AUTH_IDENTITY_FLAGS_SSPIPFC_USE_MASK 0xFF000000 - -// -// Instructs the credential provider to not save credentials itself -// when caller selects the "Remember my credential" checkbox. -// - -#define SEC_WINNT_AUTH_IDENTITY_FLAGS_SSPIPFC_SAVE_CRED_BY_CALLER 0x80000000 - -// -// State of the "Remember my credentials" checkbox. -// When set, indicates checked; when cleared, indicates unchecked. -// - -#define SEC_WINNT_AUTH_IDENTITY_FLAGS_SSPIPFC_SAVE_CRED_CHECKED 0x40000000 - -#define SEC_WINNT_AUTH_IDENTITY_FLAGS_VALID_SSPIPFC_FLAGS \ - (SEC_WINNT_AUTH_IDENTITY_FLAGS_SSPIPFC_SAVE_CRED_BY_CALLER | \ - SEC_WINNT_AUTH_IDENTITY_FLAGS_SSPIPFC_SAVE_CRED_CHECKED) - - -#endif // _AUTH_IDENTITY_INFO_DEFINED - -#ifndef _SSPIPFC_NONE_ // the public view - -// begin_ntifs - -typedef PVOID PSEC_WINNT_AUTH_IDENTITY_OPAQUE; // the credential structure is opaque - -// end_ntifs - -#else // the internal view - -typedef PSEC_WINNT_AUTH_IDENTITY_INFO PSEC_WINNT_AUTH_IDENTITY_OPAQUE; - -#endif // _SSPIPFC_NONE_ - -// -// dwFlags parameter of SspiPromptForCredentials(): -// - -// -// Indicates that the credentials should not be saved if -// the user selects the 'save' (or 'remember my password') -// checkbox in the credential dialog box. The location pointed -// to by the pfSave parameter indicates whether or not the user -// selected the checkbox. -// -// Note that some credential providers won't honour this flag and -// may save the credentials in a persistent manner anyway if the -// user selects the 'save' checbox. -// - -#define SSPIPFC_SAVE_CRED_BY_CALLER 0x00000001 - -#define SSPIPFC_VALID_FLAGS (SSPIPFC_SAVE_CRED_BY_CALLER) - -#ifndef _SSPIPFC_NONE_ // the public view - -// Use SspiFreeAuthIdentity() to free the buffer returned -// in ppAuthIdentity. - -unsigned long -SEC_ENTRY -SspiPromptForCredentialsW( - __in PCWSTR pszTargetName, -#ifdef _CREDUI_INFO_DEFINED - __in_opt PCREDUI_INFOW pUiInfo, -#else - __in_opt PVOID pUiInfo, -#endif // _CREDUI_INFO_DEFINED - __in unsigned long dwAuthError, - __in PCWSTR pszPackage, - __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE pInputAuthIdentity, - __deref_out PSEC_WINNT_AUTH_IDENTITY_OPAQUE* ppAuthIdentity, - __inout_opt int* pfSave, - __in unsigned long dwFlags - ); - -// Use SspiFreeAuthIdentity() to free the buffer returned -// in ppAuthIdentity. - -unsigned long -SEC_ENTRY -SspiPromptForCredentialsA( - __in PCSTR pszTargetName, -#ifdef _CREDUI_INFO_DEFINED - __in_opt PCREDUI_INFOA pUiInfo, -#else - __in_opt PVOID pUiInfo, -#endif // _CREDUI_INFO_DEFINED - __in unsigned long dwAuthError, - __in PCSTR pszPackage, - __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE pInputAuthIdentity, - __deref_out PSEC_WINNT_AUTH_IDENTITY_OPAQUE* ppAuthIdentity, - __inout_opt int* pfSave, - __in unsigned long dwFlags - ); -#endif // _SSPIPFC_NONE_ - -#ifdef UNICODE -#define SspiPromptForCredentials SspiPromptForCredentialsW -#else -#define SspiPromptForCredentials SspiPromptForCredentialsA -#endif - -#ifdef _SEC_WINNT_AUTH_TYPES - -typedef struct _SEC_WINNT_AUTH_BYTE_VECTOR { - unsigned long ByteArrayOffset; // each element is a byte - unsigned short ByteArrayLength; // -} SEC_WINNT_AUTH_BYTE_VECTOR, *PSEC_WINNT_AUTH_BYTE_VECTOR; - -typedef struct _SEC_WINNT_AUTH_DATA { - GUID CredType; - SEC_WINNT_AUTH_BYTE_VECTOR CredData; -} SEC_WINNT_AUTH_DATA, *PSEC_WINNT_AUTH_DATA; - -typedef struct _SEC_WINNT_AUTH_PACKED_CREDENTIALS { - unsigned short cbHeaderLength; // the length of the header - unsigned short cbStructureLength; // pay load length including the header - SEC_WINNT_AUTH_DATA AuthData; -} SEC_WINNT_AUTH_PACKED_CREDENTIALS, *PSEC_WINNT_AUTH_PACKED_CREDENTIALS; - -// {28BFC32F-10F6-4738-98D1-1AC061DF716A} -static const GUID SEC_WINNT_AUTH_DATA_TYPE_PASSWORD = - { 0x28bfc32f, 0x10f6, 0x4738, { 0x98, 0xd1, 0x1a, 0xc0, 0x61, 0xdf, 0x71, 0x6a } }; - -// {235F69AD-73FB-4dbc-8203-0629E739339B} -static const GUID SEC_WINNT_AUTH_DATA_TYPE_CERT = - { 0x235f69ad, 0x73fb, 0x4dbc, { 0x82, 0x3, 0x6, 0x29, 0xe7, 0x39, 0x33, 0x9b } }; - -typedef struct _SEC_WINNT_AUTH_DATA_PASSWORD { - SEC_WINNT_AUTH_BYTE_VECTOR UnicodePassword; -} SEC_WINNT_AUTH_DATA_PASSWORD, PSEC_WINNT_AUTH_DATA_PASSWORD; - -// -// smartcard cred data -// -// {68FD9879-079C-4dfe-8281-578AADC1C100} - -static const GUID SEC_WINNT_AUTH_DATA_TYPE_CSP_DATA = - { 0x68fd9879, 0x79c, 0x4dfe, { 0x82, 0x81, 0x57, 0x8a, 0xad, 0xc1, 0xc1, 0x0 } }; - -typedef struct _SEC_WINNT_AUTH_CERTIFICATE_DATA { - unsigned short cbHeaderLength; - unsigned short cbStructureLength; - SEC_WINNT_AUTH_BYTE_VECTOR Certificate; -} SEC_WINNT_AUTH_CERTIFICATE_DATA, *PSEC_WINNT_AUTH_CERTIFICATE_DATA; - -typedef struct _SEC_WINNT_CREDUI_CONTEXT_VECTOR -{ - ULONG CredUIContextArrayOffset; // offset starts at the beginning of - // this structure, and each element is a SEC_WINNT_AUTH_BYTE_VECTOR that - // describes the flat CredUI context returned by SpGetCredUIContext() - USHORT CredUIContextCount; -} SEC_WINNT_CREDUI_CONTEXT_VECTOR, *PSEC_WINNT_CREDUI_CONTEXT_VECTOR; - -typedef struct _SEC_WINNT_AUTH_SHORT_VECTOR -{ - ULONG ShortArrayOffset; // each element is a short - USHORT ShortArrayCount; // number of characters -} SEC_WINNT_AUTH_SHORT_VECTOR, *PSEC_WINNT_AUTH_SHORT_VECTOR; - -// free the returned memory using SspiLocalFree - -SECURITY_STATUS -SEC_ENTRY -SspiGetCredUIContext( - __in HANDLE ContextHandle, - __in GUID* CredType, - __in_opt LUID* LogonId, // use this LogonId, the caller must be localsystem to supply a logon id - __deref_out PSEC_WINNT_CREDUI_CONTEXT_VECTOR* CredUIContexts, - __out_opt HANDLE* TokenHandle - ); - -SECURITY_STATUS -SEC_ENTRY -SspiUpdateCredentials( - __in HANDLE ContextHandle, - __in GUID* CredType, - __in ULONG FlatCredUIContextLength, - __in_bcount(FlatCredUIContextLength) PUCHAR FlatCredUIContext - ); - -typedef struct _CREDUIWIN_MARSHALED_CONTEXT -{ - GUID StructureType; - USHORT cbHeaderLength; - LUID LogonId; // user's logon id - GUID MarshaledDataType; - ULONG MarshaledDataOffset; - USHORT MarshaledDataLength; -} CREDUIWIN_MARSHALED_CONTEXT, *PCREDUIWIN_MARSHALED_CONTEXT; - -typedef struct _SEC_WINNT_CREDUI_CONTEXT -{ - USHORT cbHeaderLength; - HANDLE CredUIContextHandle; // the handle to call SspiGetCredUIContext() -#ifdef _CREDUI_INFO_DEFINED - PCREDUI_INFOW UIInfo; // input from SspiPromptForCredentials() -#else - PVOID UIInfo; -#endif // _CREDUI_INFO_DEFINED - ULONG dwAuthError; // the authentication error - PSEC_WINNT_AUTH_IDENTITY_OPAQUE pInputAuthIdentity; - PUNICODE_STRING TargetName; -} SEC_WINNT_CREDUI_CONTEXT, *PSEC_WINNT_CREDUI_CONTEXT; - -// {3C3E93D9-D96B-49b5-94A7-458592088337} -static const GUID CREDUIWIN_STRUCTURE_TYPE_SSPIPFC = -{ 0x3c3e93d9, 0xd96b, 0x49b5, { 0x94, 0xa7, 0x45, 0x85, 0x92, 0x8, 0x83, 0x37 } }; - -// {C2FFFE6F-503D-4c3d-A95E-BCE821213D44} -static const GUID SSPIPFC_STRUCTURE_TYPE_CREDUI_CONTEXT = -{ 0xc2fffe6f, 0x503d, 0x4c3d, { 0xa9, 0x5e, 0xbc, 0xe8, 0x21, 0x21, 0x3d, 0x44 } }; - -typedef struct _SEC_WINNT_AUTH_PACKED_CREDENTIALS_EX { - unsigned short cbHeaderLength; - unsigned long Flags; // contains the Flags field in - // SEC_WINNT_AUTH_IDENTITY_EX - SEC_WINNT_AUTH_BYTE_VECTOR PackedCredentials; - SEC_WINNT_AUTH_SHORT_VECTOR PackageList; -} SEC_WINNT_AUTH_PACKED_CREDENTIALS_EX, *PSEC_WINNT_AUTH_PACKED_CREDENTIALS_EX; - -// -// free the returned memory using SspiLocalFree -// - -SECURITY_STATUS -SEC_ENTRY -SspiUnmarshalCredUIContext( - __in_bcount(MarshaledCredUIContextLength) PUCHAR MarshaledCredUIContext, - __in ULONG MarshaledCredUIContextLength, - __deref_out PSEC_WINNT_CREDUI_CONTEXT* CredUIContext - ); - -#endif // _SEC_WINNT_AUTH_TYPES - -SECURITY_STATUS -SEC_ENTRY -SspiPrepareForCredRead( - __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, - __in PCWSTR pszTargetName, - __out PULONG pCredmanCredentialType, - __deref_out PCWSTR* ppszCredmanTargetName - ); - -SECURITY_STATUS -SEC_ENTRY -SspiPrepareForCredWrite( - __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, - __in_opt PCWSTR pszTargetName, // supply NULL for username-target credentials - __out PULONG pCredmanCredentialType, - __deref_out PCWSTR* ppszCredmanTargetName, - __deref_out PCWSTR* ppszCredmanUserName, - __deref_out_bcount(*pCredentialBlobSize) PUCHAR *ppCredentialBlob, - __out PULONG pCredentialBlobSize - ); - -SECURITY_STATUS -SEC_ENTRY -SspiEncryptAuthIdentity( - __inout PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData - ); - -SECURITY_STATUS -SEC_ENTRY -SspiDecryptAuthIdentity( - __inout PSEC_WINNT_AUTH_IDENTITY_OPAQUE EncryptedAuthData - ); - -BOOLEAN -SEC_ENTRY -SspiIsAuthIdentityEncrypted( - __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE EncryptedAuthData - ); - -// begin_ntifs - -#if (NTDDI_VERSION >= NTDDI_WIN7) -// -// Convert the _OPAQUE structure passed in to the -// 3 tuple . -// -// Note: The 'strings' returned need not necessarily be -// in user recognisable form. The purpose of this API -// is to 'flatten' the _OPAQUE structure into the 3 tuple. -// User recognisable can always be -// obtained by passing NULL to the pszPackedCredentialsString -// parameter. -// -// zero out the pszPackedCredentialsString then -// free the returned memory using SspiLocalFree() -// - -SECURITY_STATUS -SEC_ENTRY -SspiEncodeAuthIdentityAsStrings( - __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE pAuthIdentity, - __deref_out_opt PCWSTR* ppszUserName, - __deref_out_opt PCWSTR* ppszDomainName, - __deref_opt_out_opt PCWSTR* ppszPackedCredentialsString - ); - -SECURITY_STATUS -SEC_ENTRY -SspiValidateAuthIdentity( - __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData - ); - -// -// free the returned memory using SspiFreeAuthIdentity() -// - -SECURITY_STATUS -SEC_ENTRY -SspiCopyAuthIdentity( - __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData, - __deref_out PSEC_WINNT_AUTH_IDENTITY_OPAQUE* AuthDataCopy - ); - -// -// use only for the memory returned by SspiCopyAuthIdentity(). -// Internally calls SspiZeroAuthIdentity(). -// - -VOID -SEC_ENTRY -SspiFreeAuthIdentity( - __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData - ); - -VOID -SEC_ENTRY -SspiZeroAuthIdentity( - __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData - ); - -VOID -SEC_ENTRY -SspiLocalFree( - __in_opt PVOID DataBuffer - ); - -// -// call SspiFreeAuthIdentity to free the returned AuthIdentity -// which zeroes out the credentials blob before freeing it -// - -SECURITY_STATUS -SEC_ENTRY -SspiEncodeStringsAsAuthIdentity( - __in_opt PCWSTR pszUserName, - __in_opt PCWSTR pszDomainName, - __in_opt PCWSTR pszPackedCredentialsString, - __deref_out PSEC_WINNT_AUTH_IDENTITY_OPAQUE* ppAuthIdentity - ); - -SECURITY_STATUS -SEC_ENTRY -SspiCompareAuthIdentities( - __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity1, - __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity2, - __out_opt PBOOLEAN SameSuppliedUser, - __out_opt PBOOLEAN SameSuppliedIdentity - ); - -// -// zero out the returned AuthIdentityByteArray then -// free the returned memory using SspiLocalFree() -// - -SECURITY_STATUS -SEC_ENTRY -SspiMarshalAuthIdentity( - __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, - __out unsigned long* AuthIdentityLength, - __deref_out_bcount(*AuthIdentityLength) char** AuthIdentityByteArray - ); - -// -// free the returned auth identity using SspiFreeAuthIdentity() -// - -SECURITY_STATUS -SEC_ENTRY -SspiUnmarshalAuthIdentity( - __in unsigned long AuthIdentityLength, - __in_bcount(AuthIdentityLength) char* AuthIdentityByteArray, - __deref_out PSEC_WINNT_AUTH_IDENTITY_OPAQUE* ppAuthIdentity - ); - -BOOLEAN -SEC_ENTRY -SspiIsPromptingNeeded( - __in unsigned long ErrorOrNtStatus - ); - -SECURITY_STATUS -SEC_ENTRY -SspiGetTargetHostName( - __in PCWSTR pszTargetName, - __deref_out PWSTR* pszHostName - ); - -SECURITY_STATUS -SEC_ENTRY -SspiExcludePackage( - __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, - __in PCWSTR pszPackageName, - __deref_out PSEC_WINNT_AUTH_IDENTITY_OPAQUE* ppNewAuthIdentity - ); - -*) - -// -// Common types used by negotiable security packages -// - -const - - SEC_WINNT_AUTH_IDENTITY_MARSHALLED = $4; // all data is in one buffer - {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_MARSHALLED} - SEC_WINNT_AUTH_IDENTITY_ONLY = $8; // these credentials are for identity only - no PAC needed - {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_ONLY} - - -(* TODO - -// -// Routines for manipulating packages -// - -typedef struct _SECURITY_PACKAGE_OPTIONS { - unsigned long Size; - unsigned long Type; - unsigned long Flags; - unsigned long SignatureSize; - void SEC_FAR * Signature; -} SECURITY_PACKAGE_OPTIONS, SEC_FAR * PSECURITY_PACKAGE_OPTIONS; - -#define SECPKG_OPTIONS_TYPE_UNKNOWN 0 -#define SECPKG_OPTIONS_TYPE_LSA 1 -#define SECPKG_OPTIONS_TYPE_SSPI 2 - -#define SECPKG_OPTIONS_PERMANENT 0x00000001 - -SECURITY_STATUS -SEC_ENTRY -AddSecurityPackageA( - SEC_CHAR SEC_FAR * pszPackageName, - SECURITY_PACKAGE_OPTIONS SEC_FAR * Options - ); - -SECURITY_STATUS -SEC_ENTRY -AddSecurityPackageW( - SEC_WCHAR SEC_FAR * pszPackageName, - SECURITY_PACKAGE_OPTIONS SEC_FAR * Options - ); - -#ifdef UNICODE -#define AddSecurityPackage AddSecurityPackageW -#else -#define AddSecurityPackage AddSecurityPackageA -#endif - -SECURITY_STATUS -SEC_ENTRY -DeleteSecurityPackageA( - SEC_CHAR SEC_FAR * pszPackageName ); - -SECURITY_STATUS -SEC_ENTRY -DeleteSecurityPackageW( - SEC_WCHAR SEC_FAR * pszPackageName ); - -#ifdef UNICODE -#define DeleteSecurityPackage DeleteSecurityPackageW -#else -#define DeleteSecurityPackage DeleteSecurityPackageA -#endif - -//+----------------------------------------------------------------------- -// -// Microsoft Windows -// -// Copyright (c) Microsoft Corporation 1991-1999 -// -// File: secext.h -// -// Contents: Security function prototypes for functions not part of -// the SSPI interface. This file should not be directly -// included - include security.h instead. -// -// -// History: 22 Dec 92 RichardW Created -// -//------------------------------------------------------------------------ - -// -// Extended Name APIs for ADS -// - - -typedef enum -{ - // Examples for the following formats assume a fictitous company - // which hooks into the global X.500 and DNS name spaces as follows. - // - // Enterprise root domain in DNS is - // - // widget.com - // - // Enterprise root domain in X.500 (RFC 1779 format) is - // - // O=Widget, C=US - // - // There exists the child domain - // - // engineering.widget.com - // - // equivalent to - // - // OU=Engineering, O=Widget, C=US - // - // There exists a container within the Engineering domain - // - // OU=Software, OU=Engineering, O=Widget, C=US - // - // There exists the user - // - // CN=John Doe, OU=Software, OU=Engineering, O=Widget, C=US - // - // And this user's downlevel (pre-ADS) user name is {Do not Localize} - // - // Engineering\JohnDoe - - // unknown name type - NameUnknown = 0, - - // CN=John Doe, OU=Software, OU=Engineering, O=Widget, C=US - NameFullyQualifiedDN = 1, - - // Engineering\JohnDoe - NameSamCompatible = 2, - - // Probably "John Doe" but could be something else. I.e. The - // display name is not necessarily the defining RDN. - NameDisplay = 3, - - - // String-ized GUID as returned by IIDFromString(). - // eg: {4fa050f0-f561-11cf-bdd9-00aa003a77b6} - NameUniqueId = 6, - - // engineering.widget.com/software/John Doe - NameCanonical = 7, - - // johndoe@engineering.com - NameUserPrincipal = 8, - - // Same as NameCanonical except that rightmost '/' is {Do not Localize} - // replaced with '\n' - even in domain-only case. {Do not Localize} - // eg: engineering.widget.com/software\nJohn Doe - NameCanonicalEx = 9, - - // www/srv.engineering.com/engineering.com - NameServicePrincipal = 10 - -} EXTENDED_NAME_FORMAT, * PEXTENDED_NAME_FORMAT ; - -BOOLEAN -SEC_ENTRY -GetUserNameExA( - EXTENDED_NAME_FORMAT NameFormat, - LPSTR lpNameBuffer, - PULONG nSize - ); -BOOLEAN -SEC_ENTRY -GetUserNameExW( - EXTENDED_NAME_FORMAT NameFormat, - LPWSTR lpNameBuffer, - PULONG nSize - ); - -#ifdef UNICODE -#define GetUserNameEx GetUserNameExW -#else -#define GetUserNameEx GetUserNameExA -#endif - -BOOLEAN -SEC_ENTRY -GetComputerObjectNameA( - EXTENDED_NAME_FORMAT NameFormat, - LPSTR lpNameBuffer, - PULONG nSize - ); -BOOLEAN -SEC_ENTRY -GetComputerObjectNameW( - EXTENDED_NAME_FORMAT NameFormat, - LPWSTR lpNameBuffer, - PULONG nSize - ); - -#ifdef UNICODE -#define GetComputerObjectName GetComputerObjectNameW -#else -#define GetComputerObjectName GetComputerObjectNameA -#endif - -BOOLEAN -SEC_ENTRY -TranslateNameA( - LPCSTR lpAccountName, - EXTENDED_NAME_FORMAT AccountNameFormat, - EXTENDED_NAME_FORMAT DesiredNameFormat, - LPSTR lpTranslatedName, - PULONG nSize - ); -BOOLEAN -SEC_ENTRY -TranslateNameW( - LPCWSTR lpAccountName, - EXTENDED_NAME_FORMAT AccountNameFormat, - EXTENDED_NAME_FORMAT DesiredNameFormat, - LPWSTR lpTranslatedName, - PULONG nSize - ); -#ifdef UNICODE -#define TranslateName TranslateNameW -#else -#define TranslateName TranslateNameA -#endif - -*) - -{$ENDIF} -implementation -{$IFDEF USE_SSPI} - -procedure SecInvalidateHandle(var x: SecHandle); -begin - x.dwLower := PtrUInt(-1); - x.dwUpper := PtrUInt(-1); -end; - -function SecIsValidHandle(x : SecHandle) : Boolean; -begin - // RLebeau: workaround for a bug in D2009. Comparing PtrUInt values does not always work correctly. - // Sometimes it causes "W1023 Comparing signed and unsigned types" warnings, other times it causes - // "F2084 Internal Error: C12079" errors - {$IFDEF VCL_2009} - Result := (Integer(x.dwLower) <> Integer(PtrUInt(-1))) and - (Integer(x.dwUpper) <> Integer(PtrUInt(-1))); - {$ELSE} - Result := (x.dwLower <> PtrUInt(-1)) and (x.dwUpper <> PtrUInt(-1)); - {$ENDIF} -end; - -function SEC_SUCCESS(Status: SECURITY_STATUS): Boolean; -begin - Result := Status >= 0; -end; - -{$ENDIF} - -end. +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.1 13.1.2004 17:26:00 DBondzhev + Added Domain property + + Rev 1.0 11/13/2002 08:01:52 AM JPMugaas +} + +{ + SSPI interface and objects Unit + Copyright (c) 1999-2001, Eventree Systems + Translator: Eventree Systems + + this unit contains translation of: + Security.h, sspi.h, secext.h, rpcdce.h (some of) +} + +unit IdSSPI; + +{$ALIGN ON} +{$MINENUMSIZE 4} + +interface + +{$i IdCompilerDefines.inc} +{$IFDEF USE_SSPI} + + +uses + IdGlobal, + Windows; + +type + PPVOID = ^PVOID; + {$NODEFINE PPVOID} + PVOID = Pointer; + {$NODEFINE PVOID} + + PUSHORT = ^USHORT; + {$NODEFINE PUSHORT} + USHORT = Word; + {$NODEFINE USHORT} + + PUCHAR = ^UCHAR; + {$NODEFINE PUCHAR} + UCHAR = Byte; + {$NODEFINE UCHAR} + +(*$HPPEMIT '//#define SECURITY_WIN32'*) +(*$HPPEMIT '#include '*) + +//+----------------------------------------------------------------------- +// +// Microsoft Windows +// +// Copyright (c) Microsoft Corporation 1991-1999 +// +// File: Security.h +// +// Contents: Toplevel include file for security aware components +// +// +// History: 06 Aug 92 RichardW Created +// 23 Sep 92 PeterWi Add security object include files +// +//------------------------------------------------------------------------ + +// +// These are name that can be used to refer to the builtin packages +// + +const + + NTLMSP_NAME = 'NTLM'; {Do not Localize} + {$EXTERNALSYM NTLMSP_NAME} + + MICROSOFT_KERBEROS_NAME = 'Kerberos'; {Do not Localize} + {$EXTERNALSYM MICROSOFT_KERBEROS_NAME} + + NEGOSSP_NAME = 'Negotiate'; {Do not Localize} + {$EXTERNALSYM NEGOSSP_NAME} + +//+--------------------------------------------------------------------------- +// +// Microsoft Windows +// Copyright (C) Microsoft Corporation, 1992-1997. +// +// File: sspi.h +// +// Contents: Security Support Provider Interface +// Prototypes and structure definitions +// +// Functions: Security Support Provider API +// +// History: 11-24-93 RichardW Created +// +//---------------------------------------------------------------------------- + +type + + PSEC_WCHAR = PWideChar; + {$NODEFINE PSEC_WCHAR} + SEC_WCHAR = WideChar; + {$EXTERNALSYM SEC_WCHAR} + + PSEC_CHAR = PAnsiChar; + {$NODEFINE PSEC_CHAR} + SEC_CHAR = AnsiChar; + {$EXTERNALSYM SEC_CHAR} + + PSECURITY_STATUS = ^SECURITY_STATUS; + {$NODEFINE PSECURITY_STATUS} + SECURITY_STATUS = Longint{LONG}; // LONG is not defined in Windows.pas prior to Delphi 8 + {$EXTERNALSYM SECURITY_STATUS} + +// +// Decide what a string - 32 bits only since for 16 bits it is clear. +// + +type + {$IFDEF SSPI_UNICODE} + SECURITY_PSTR = ^SEC_WCHAR; + {$ELSE} + SECURITY_PSTR = ^SEC_CHAR; + {$ENDIF} + {$EXTERNALSYM SECURITY_PSTR} +// +// Okay, security specific types: +// + +type + + PSecHandle = ^SecHandle; + {$EXTERNALSYM PSecHandle} + //Define ULONG_PTR as PtrUInt so we can use this unit in FreePascal. + SecHandle = record + dwLower: PtrUInt; // ULONG_PTR + dwUpper: PtrUInt; // ULONG_PTR + end; + {$EXTERNALSYM SecHandle} + + CredHandle = SecHandle; + {$EXTERNALSYM CredHandle} + PCredHandle = PSecHandle; + {$EXTERNALSYM PCredHandle} + + CtxtHandle = SecHandle; + {$EXTERNALSYM CtxtHandle} + PCtxtHandle = PSecHandle; + {$EXTERNALSYM PCtxtHandle} + + PSECURITY_INTEGER = ^SECURITY_INTEGER; + {$EXTERNALSYM PSECURITY_INTEGER} + SECURITY_INTEGER = LARGE_INTEGER; + {$EXTERNALSYM SECURITY_INTEGER} + + PTimeStamp = ^TimeStamp; + {$EXTERNALSYM PTimeStamp} + TimeStamp = SECURITY_INTEGER; + {$EXTERNALSYM TimeStamp} + + procedure SecInvalidateHandle(var x: SecHandle); {$IFDEF USE_INLINE} inline; {$ENDIF} + {$EXTERNALSYM SecInvalidateHandle} + function SecIsValidHandle(x : SecHandle) : Boolean; {$IFDEF USE_INLINE} inline; {$ENDIF} + {$EXTERNALSYM SecIsValidHandle} + function SEC_SUCCESS(Status: SECURITY_STATUS): Boolean; {$IFDEF USE_INLINE} inline; {$ENDIF} + {$EXTERNALSYM SEC_SUCCESS} + +type + +// +// If we are in 32 bit mode, define the SECURITY_STRING structure, +// as a clone of the base UNICODE_STRING structure. This is used +// internally in security components, an as the string interface +// for kernel components (e.g. FSPs) +// + + PSECURITY_STRING = ^SECURITY_STRING; + {$EXTERNALSYM PSECURITY_STRING} + SECURITY_STRING = record + Length: USHORT; + MaximumLength: USHORT; + Buffer: PUSHORT; + end; + {$EXTERNALSYM SECURITY_STRING} + +// +// SecPkgInfo structure +// +// Provides general information about a security provider +// + +type + + PPSecPkgInfoW = ^PSecPkgInfoW; + {$NODEFINE PPSecPkgInfoW} + PSecPkgInfoW = ^SecPkgInfoW; + {$EXTERNALSYM PSecPkgInfoW} + SecPkgInfoW = record + fCapabilities: ULONG; // Capability bitmask + wVersion: USHORT; // Version of driver + wRPCID: USHORT; // ID for RPC Runtime + cbMaxToken: ULONG; // Size of authentication token (max) + Name: PSEC_WCHAR; // Text name + Comment: PSEC_WCHAR; // Comment + end; + {$EXTERNALSYM SecPkgInfoW} + + PPSecPkgInfoA = ^PSecPkgInfoA; + {$NODEFINE PPSecPkgInfoA} + PSecPkgInfoA = ^SecPkgInfoA; + {$EXTERNALSYM PSecPkgInfoA} + SecPkgInfoA = record + fCapabilities: ULONG; // Capability bitmask + wVersion: USHORT; // Version of driver + wRPCID: USHORT; // ID for RPC Runtime + cbMaxToken: ULONG; // Size of authentication token (max) + Name: PSEC_CHAR; // Text name + Comment: PSEC_CHAR; // Comment + end; + {$EXTERNALSYM SecPkgInfoA} + +{$IFDEF SSPI_UNICODE} + SecPkgInfo = SecPkgInfoW; + PSecPkgInfo = PSecPkgInfoW; +{$ELSE} + SecPkgInfo = SecPkgInfoA; + PSecPkgInfo = PSecPkgInfoA; +{$ENDIF} + {$EXTERNALSYM SecPkgInfo} + {$EXTERNALSYM PSecPkgInfo} + + +// +// Security Package Capabilities +// + +const + + SECPKG_FLAG_INTEGRITY = $00000001; // Supports integrity on messages + {$EXTERNALSYM SECPKG_FLAG_INTEGRITY} + SECPKG_FLAG_PRIVACY = $00000002; // Supports privacy (confidentiality) + {$EXTERNALSYM SECPKG_FLAG_PRIVACY} + SECPKG_FLAG_TOKEN_ONLY = $00000004; // Only security token needed + {$EXTERNALSYM SECPKG_FLAG_TOKEN_ONLY} + SECPKG_FLAG_DATAGRAM = $00000008; // Datagram RPC support + {$EXTERNALSYM SECPKG_FLAG_DATAGRAM} + SECPKG_FLAG_CONNECTION = $00000010; // Connection oriented RPC support + {$EXTERNALSYM SECPKG_FLAG_CONNECTION} + SECPKG_FLAG_MULTI_REQUIRED = $00000020; // Full 3-leg required for re-auth. + {$EXTERNALSYM SECPKG_FLAG_MULTI_REQUIRED} + SECPKG_FLAG_CLIENT_ONLY = $00000040; // Server side functionality not available + {$EXTERNALSYM SECPKG_FLAG_CLIENT_ONLY} + SECPKG_FLAG_EXTENDED_ERROR = $00000080; // Supports extended error msgs + {$EXTERNALSYM SECPKG_FLAG_EXTENDED_ERROR} + SECPKG_FLAG_IMPERSONATION = $00000100; // Supports impersonation + {$EXTERNALSYM SECPKG_FLAG_IMPERSONATION} + SECPKG_FLAG_ACCEPT_WIN32_NAME = $00000200; // Accepts Win32 names + {$EXTERNALSYM SECPKG_FLAG_ACCEPT_WIN32_NAME} + SECPKG_FLAG_STREAM = $00000400; // Supports stream semantics + {$EXTERNALSYM SECPKG_FLAG_STREAM} + SECPKG_FLAG_NEGOTIABLE = $00000800; // Can be used by the negotiate package + {$EXTERNALSYM SECPKG_FLAG_NEGOTIABLE} + SECPKG_FLAG_GSS_COMPATIBLE = $00001000; // GSS Compatibility Available + {$EXTERNALSYM SECPKG_FLAG_GSS_COMPATIBLE} + SECPKG_FLAG_LOGON = $00002000; // Supports common LsaLogonUser + {$EXTERNALSYM SECPKG_FLAG_LOGON} + SECPKG_FLAG_ASCII_BUFFERS = $00004000; // Token Buffers are in ASCII + {$EXTERNALSYM SECPKG_FLAG_ASCII_BUFFERS} + SECPKG_FLAG_FRAGMENT = $00008000; // Package can fragment to fit + {$EXTERNALSYM SECPKG_FLAG_FRAGMENT} + SECPKG_FLAG_MUTUAL_AUTH = $00010000; // Package can perform mutual authentication + {$EXTERNALSYM SECPKG_FLAG_MUTUAL_AUTH} + SECPKG_FLAG_DELEGATION = $00020000; // Package can delegate + {$EXTERNALSYM SECPKG_FLAG_DELEGATION} + SECPKG_FLAG_READONLY_WITH_CHECKSUM = $00040000; // Package can delegate + {$EXTERNALSYM SECPKG_FLAG_READONLY_WITH_CHECKSUM} + SECPKG_FLAG_RESTRICTED_TOKENS = $00080000; // Package supports restricted callers + {$EXTERNALSYM SECPKG_FLAG_RESTRICTED_TOKENS} + SECPKG_FLAG_NEGO_EXTENDER = $00100000; // this package extends SPNEGO, there is at most one + {$EXTERNALSYM SECPKG_FLAG_NEGO_EXTENDER} + SECPKG_FLAG_NEGOTIABLE2 = $00200000; // this package is negotiated under the NegoExtender + {$EXTERNALSYM SECPKG_FLAG_NEGOTIABLE2} + + SECPKG_ID_NONE = $FFFF; + {$EXTERNALSYM SECPKG_ID_NONE} + +// +// SecBuffer +// +// Generic memory descriptors for buffers passed in to the security +// API +// + +type + + PSecBuffer = ^SecBuffer; + {$EXTERNALSYM PSecBuffer} + SecBuffer = record + cbBuffer: ULONG; // Size of the buffer, in bytes + BufferType: ULONG; // Type of the buffer (below) + pvBuffer: PVOID; // Pointer to the buffer + end; + {$EXTERNALSYM SecBuffer} + + PSecBufferDesc = ^SecBufferDesc; + {$EXTERNALSYM PSecBufferDesc} + SecBufferDesc = record + ulVersion: ULONG; // Version number + cBuffers: ULONG; // Number of buffers + pBuffers: PSecBuffer; // Pointer to array of buffers + end; + {$EXTERNALSYM SecBufferDesc} + +const + + SECBUFFER_VERSION = 0; + {$EXTERNALSYM SECBUFFER_VERSION} + + SECBUFFER_EMPTY = 0; // Undefined, replaced by provider + {$EXTERNALSYM SECBUFFER_EMPTY} + SECBUFFER_DATA = 1; // Packet data + {$EXTERNALSYM SECBUFFER_DATA} + SECBUFFER_TOKEN = 2; // Security token + {$EXTERNALSYM SECBUFFER_TOKEN} + SECBUFFER_PKG_PARAMS = 3; // Package specific parameters + {$EXTERNALSYM SECBUFFER_PKG_PARAMS} + SECBUFFER_MISSING = 4; // Missing Data indicator + {$EXTERNALSYM SECBUFFER_MISSING} + SECBUFFER_EXTRA = 5; // Extra data + {$EXTERNALSYM SECBUFFER_EXTRA} + SECBUFFER_STREAM_TRAILER = 6; // Security Trailer + {$EXTERNALSYM SECBUFFER_STREAM_TRAILER} + SECBUFFER_STREAM_HEADER = 7; // Security Header + {$EXTERNALSYM SECBUFFER_STREAM_HEADER} + SECBUFFER_NEGOTIATION_INFO = 8; // Hints from the negotiation pkg + {$EXTERNALSYM SECBUFFER_NEGOTIATION_INFO} + SECBUFFER_PADDING = 9; // non-data padding + {$EXTERNALSYM SECBUFFER_PADDING} + SECBUFFER_STREAM = 10; // whole encrypted message + {$EXTERNALSYM SECBUFFER_STREAM} + SECBUFFER_MECHLIST = 11; + {$EXTERNALSYM SECBUFFER_MECHLIST} + SECBUFFER_MECHLIST_SIGNATURE = 12; + {$EXTERNALSYM SECBUFFER_MECHLIST_SIGNATURE} + SECBUFFER_TARGET = 13; // obsolete + {$EXTERNALSYM SECBUFFER_TARGET} + SECBUFFER_CHANNEL_BINDINGS = 14; + {$EXTERNALSYM SECBUFFER_CHANNEL_BINDINGS} + SECBUFFER_CHANGE_PASS_RESPONSE = 15; + {$EXTERNALSYM SECBUFFER_CHANGE_PASS_RESPONSE} + SECBUFFER_TARGET_HOST = 16; + {$EXTERNALSYM SECBUFFER_TARGET_HOST} + SECBUFFER_ALERT = 17; + {$EXTERNALSYM SECBUFFER_ALERT} + + SECBUFFER_ATTRMASK = $F0000000; + {$EXTERNALSYM SECBUFFER_ATTRMASK} + SECBUFFER_READONLY = $80000000; // Buffer is read-only + {$EXTERNALSYM SECBUFFER_READONLY} + SECBUFFER_READONLY_WITH_CHECKSUM = $10000000; // Buffer is read-only, and checksummed; + {$EXTERNALSYM SECBUFFER_READONLY_WITH_CHECKSUM} + SECBUFFER_RESERVED = $40000000; + {$EXTERNALSYM SECBUFFER_RESERVED} + +type + + PSEC_NEGOTIATION_INFO = ^SEC_NEGOTIATION_INFO; + {$EXTERNALSYM PSEC_NEGOTIATION_INFO} + SEC_NEGOTIATION_INFO = record + Size: ULONG; // Size of this structure + NameLength: ULONG; // Length of name hint + Name: PSEC_WCHAR; // Name hint + Reserved: PVOID; // Reserved + end; + {$EXTERNALSYM SEC_NEGOTIATION_INFO} + + PSEC_CHANNEL_BINDINGS = ^SEC_CHANNEL_BINDINGS; + {$EXTERNALSYM PSEC_CHANNEL_BINDINGS} + SEC_CHANNEL_BINDINGS = record + dwInitiatorAddrType: ULONG; + cbInitiatorLength: ULONG; + dwInitiatorOffset: ULONG; + dwAcceptorAddrType: ULONG; + cbAcceptorLength: ULONG; + dwAcceptorOffset: ULONG; + cbApplicationDataLength: ULONG; + dwApplicationDataOffset: ULONG; + end; + {$EXTERNALSYM SEC_CHANNEL_BINDINGS} + +// +// Data Representation Constant: +// + +const + + SECURITY_NATIVE_DREP = $00000010; + {$EXTERNALSYM SECURITY_NATIVE_DREP} + SECURITY_NETWORK_DREP = $00000000; + {$EXTERNALSYM SECURITY_NETWORK_DREP} + +// +// Credential Use Flags +// + +const + + SECPKG_CRED_INBOUND = $00000001; + {$EXTERNALSYM SECPKG_CRED_INBOUND} + SECPKG_CRED_OUTBOUND = $00000002; + {$EXTERNALSYM SECPKG_CRED_OUTBOUND} + SECPKG_CRED_BOTH = $00000003; + {$EXTERNALSYM SECPKG_CRED_BOTH} + SECPKG_CRED_DEFAULT = $00000004; + {$EXTERNALSYM SECPKG_CRED_DEFAULT} + SECPKG_CRED_RESERVED = $F0000000; + {$EXTERNALSYM SECPKG_CRED_RESERVED} + +// +// SSP SHOULD prompt the user for credentials/consent, independent +// of whether credentials to be used are the 'logged on' credentials +// or retrieved from credman. +// +// An SSP may choose not to prompt, however, in circumstances determined +// by the SSP. +// + + SECPKG_CRED_AUTOLOGON_RESTRICTED = $00000010; + {$EXTERNALSYM SECPKG_CRED_AUTOLOGON_RESTRICTED} + +// +// auth will always fail, ISC() is called to process policy data only +// + + SECPKG_CRED_PROCESS_POLICY_ONLY = $00000020; + {$EXTERNALSYM SECPKG_CRED_PROCESS_POLICY_ONLY} + +const +// +// InitializeSecurityContext Requirement and return flags: +// + ISC_REQ_DELEGATE = $00000001; + {$EXTERNALSYM ISC_REQ_DELEGATE} + ISC_REQ_MUTUAL_AUTH = $00000002; + {$EXTERNALSYM ISC_REQ_MUTUAL_AUTH} + ISC_REQ_REPLAY_DETECT = $00000004; + {$EXTERNALSYM ISC_REQ_REPLAY_DETECT} + ISC_REQ_SEQUENCE_DETECT = $00000008; + {$EXTERNALSYM ISC_REQ_SEQUENCE_DETECT} + ISC_REQ_CONFIDENTIALITY = $00000010; + {$EXTERNALSYM ISC_REQ_CONFIDENTIALITY} + ISC_REQ_USE_SESSION_KEY = $00000020; + {$EXTERNALSYM ISC_REQ_USE_SESSION_KEY} + ISC_REQ_PROMPT_FOR_CREDS = $00000040; + {$EXTERNALSYM ISC_REQ_PROMPT_FOR_CREDS} + ISC_REQ_USE_SUPPLIED_CREDS = $00000080; + {$EXTERNALSYM ISC_REQ_USE_SUPPLIED_CREDS} + ISC_REQ_ALLOCATE_MEMORY = $00000100; + {$EXTERNALSYM ISC_REQ_ALLOCATE_MEMORY} + ISC_REQ_USE_DCE_STYLE = $00000200; + {$EXTERNALSYM ISC_REQ_USE_DCE_STYLE} + ISC_REQ_DATAGRAM = $00000400; + {$EXTERNALSYM ISC_REQ_DATAGRAM} + ISC_REQ_CONNECTION = $00000800; + {$EXTERNALSYM ISC_REQ_CONNECTION} + ISC_REQ_CALL_LEVEL = $00001000; + {$EXTERNALSYM ISC_REQ_CALL_LEVEL} + ISC_REQ_FRAGMENT_SUPPLIED = $00002000; + {$EXTERNALSYM ISC_REQ_FRAGMENT_SUPPLIED} + ISC_REQ_EXTENDED_ERROR = $00004000; + {$EXTERNALSYM ISC_REQ_EXTENDED_ERROR} + ISC_REQ_STREAM = $00008000; + {$EXTERNALSYM ISC_REQ_STREAM} + ISC_REQ_INTEGRITY = $00010000; + {$EXTERNALSYM ISC_REQ_INTEGRITY} + ISC_REQ_IDENTIFY = $00020000; + {$EXTERNALSYM ISC_REQ_IDENTIFY} + ISC_REQ_NULL_SESSION = $00040000; + {$EXTERNALSYM ISC_REQ_NULL_SESSION} + ISC_REQ_MANUAL_CRED_VALIDATION = $00080000; + {$EXTERNALSYM ISC_REQ_MANUAL_CRED_VALIDATION} + ISC_REQ_RESERVED1 = $00100000; + {$EXTERNALSYM ISC_REQ_RESERVED1} + ISC_REQ_FRAGMENT_TO_FIT = $00200000; + {$EXTERNALSYM ISC_REQ_FRAGMENT_TO_FIT} +// This exists only in Windows Vista and greater + ISC_REQ_FORWARD_CREDENTIALS = $00400000; + {$EXTERNALSYM ISC_REQ_FORWARD_CREDENTIALS} + ISC_REQ_NO_INTEGRITY = $00800000; // honored only by SPNEGO + {$EXTERNALSYM ISC_REQ_NO_INTEGRITY} + ISC_REQ_USE_HTTP_STYLE = $01000000; + {$EXTERNALSYM ISC_REQ_USE_HTTP_STYLE} + + ISC_RET_DELEGATE = $00000001; + {$EXTERNALSYM ISC_RET_DELEGATE} + ISC_RET_MUTUAL_AUTH = $00000002; + {$EXTERNALSYM ISC_RET_MUTUAL_AUTH} + ISC_RET_REPLAY_DETECT = $00000004; + {$EXTERNALSYM ISC_RET_REPLAY_DETECT} + ISC_RET_SEQUENCE_DETECT = $00000008; + {$EXTERNALSYM ISC_RET_SEQUENCE_DETECT} + ISC_RET_CONFIDENTIALITY = $00000010; + {$EXTERNALSYM ISC_RET_CONFIDENTIALITY} + ISC_RET_USE_SESSION_KEY = $00000020; + {$EXTERNALSYM ISC_RET_USE_SESSION_KEY} + ISC_RET_USED_COLLECTED_CREDS = $00000040; + {$EXTERNALSYM ISC_RET_USED_COLLECTED_CREDS} + ISC_RET_USED_SUPPLIED_CREDS = $00000080; + {$EXTERNALSYM ISC_RET_USED_SUPPLIED_CREDS} + ISC_RET_ALLOCATED_MEMORY = $00000100; + {$EXTERNALSYM ISC_RET_ALLOCATED_MEMORY} + ISC_RET_USED_DCE_STYLE = $00000200; + {$EXTERNALSYM ISC_RET_USED_DCE_STYLE} + ISC_RET_DATAGRAM = $00000400; + {$EXTERNALSYM ISC_RET_DATAGRAM} + ISC_RET_CONNECTION = $00000800; + {$EXTERNALSYM ISC_RET_CONNECTION} + ISC_RET_INTERMEDIATE_RETURN = $00001000; + {$EXTERNALSYM ISC_RET_INTERMEDIATE_RETURN} + ISC_RET_CALL_LEVEL = $00002000; + {$EXTERNALSYM ISC_RET_CALL_LEVEL} + ISC_RET_EXTENDED_ERROR = $00004000; + {$EXTERNALSYM ISC_RET_EXTENDED_ERROR} + ISC_RET_STREAM = $00008000; + {$EXTERNALSYM ISC_RET_STREAM} + ISC_RET_INTEGRITY = $00010000; + {$EXTERNALSYM ISC_RET_INTEGRITY} + ISC_RET_IDENTIFY = $00020000; + {$EXTERNALSYM ISC_RET_IDENTIFY} + ISC_RET_NULL_SESSION = $00040000; + {$EXTERNALSYM ISC_RET_NULL_SESSION} + ISC_RET_MANUAL_CRED_VALIDATION = $00080000; + {$EXTERNALSYM ISC_RET_MANUAL_CRED_VALIDATION} + ISC_RET_RESERVED1 = $00100000; + {$EXTERNALSYM ISC_RET_RESERVED1} + ISC_RET_FRAGMENT_ONLY = $00200000; + {$EXTERNALSYM ISC_RET_FRAGMENT_ONLY} +// This exists only in Windows Vista and greater + ISC_RET_FORWARD_CREDENTIALS = $00400000; + {$EXTERNALSYM ISC_RET_FORWARD_CREDENTIALS} + + ISC_RET_USED_HTTP_STYLE = $01000000; + {$EXTERNALSYM ISC_RET_USED_HTTP_STYLE} + ISC_RET_NO_ADDITIONAL_TOKEN = $02000000; // *INTERNAL* + {$EXTERNALSYM ISC_RET_NO_ADDITIONAL_TOKEN} + ISC_RET_REAUTHENTICATION = $08000000; // *INTERNAL* + {$EXTERNALSYM ISC_RET_REAUTHENTICATION} + + ASC_REQ_DELEGATE = $00000001; + {$EXTERNALSYM ASC_REQ_DELEGATE} + ASC_REQ_MUTUAL_AUTH = $00000002; + {$EXTERNALSYM ASC_REQ_MUTUAL_AUTH} + ASC_REQ_REPLAY_DETECT = $00000004; + {$EXTERNALSYM ASC_REQ_REPLAY_DETECT} + ASC_REQ_SEQUENCE_DETECT = $00000008; + {$EXTERNALSYM ASC_REQ_SEQUENCE_DETECT} + ASC_REQ_CONFIDENTIALITY = $00000010; + {$EXTERNALSYM ASC_REQ_CONFIDENTIALITY} + ASC_REQ_USE_SESSION_KEY = $00000020; + {$EXTERNALSYM ASC_REQ_USE_SESSION_KEY} + ASC_REQ_ALLOCATE_MEMORY = $00000100; + {$EXTERNALSYM ASC_REQ_ALLOCATE_MEMORY} + ASC_REQ_USE_DCE_STYLE = $00000200; + {$EXTERNALSYM ASC_REQ_USE_DCE_STYLE} + ASC_REQ_DATAGRAM = $00000400; + {$EXTERNALSYM ASC_REQ_DATAGRAM} + ASC_REQ_CONNECTION = $00000800; + {$EXTERNALSYM ASC_REQ_CONNECTION} + ASC_REQ_CALL_LEVEL = $00001000; + {$EXTERNALSYM ASC_REQ_CALL_LEVEL} + ASC_REQ_EXTENDED_ERROR = $00008000; + {$EXTERNALSYM ASC_REQ_EXTENDED_ERROR} + ASC_REQ_STREAM = $00010000; + {$EXTERNALSYM ASC_REQ_STREAM} + ASC_REQ_INTEGRITY = $00020000; + {$EXTERNALSYM ASC_REQ_INTEGRITY} + ASC_REQ_LICENSING = $00040000; + {$EXTERNALSYM ASC_REQ_LICENSING} + ASC_REQ_IDENTIFY = $00080000; + {$EXTERNALSYM ASC_REQ_IDENTIFY} + ASC_REQ_ALLOW_NULL_SESSION = $00100000; + {$EXTERNALSYM ASC_REQ_ALLOW_NULL_SESSION} + ASC_REQ_ALLOW_NON_USER_LOGONS = $00200000; + {$EXTERNALSYM ASC_REQ_ALLOW_NON_USER_LOGONS} + ASC_REQ_ALLOW_CONTEXT_REPLAY = $00400000; + {$EXTERNALSYM ASC_REQ_ALLOW_CONTEXT_REPLAY} + ASC_REQ_FRAGMENT_TO_FIT = $00800000; + {$EXTERNALSYM ASC_REQ_FRAGMENT_TO_FIT} + ASC_REQ_FRAGMENT_SUPPLIED = $00002000; + {$EXTERNALSYM ASC_REQ_FRAGMENT_SUPPLIED} + ASC_REQ_NO_TOKEN = $01000000; + {$EXTERNALSYM ASC_REQ_NO_TOKEN} + ASC_REQ_PROXY_BINDINGS = $04000000; + {$EXTERNALSYM ASC_REQ_PROXY_BINDINGS} +// SSP_RET_REAUTHENTICATION = $08000000; // *INTERNAL* + {.$EXTERNALSYM SSP_RET_REAUTHENTICATION} + ASC_REQ_ALLOW_MISSING_BINDINGS = $10000000; + {$EXTERNALSYM ASC_REQ_ALLOW_MISSING_BINDINGS} + + ASC_RET_DELEGATE = $00000001; + {$EXTERNALSYM ASC_RET_DELEGATE} + ASC_RET_MUTUAL_AUTH = $00000002; + {$EXTERNALSYM ASC_RET_MUTUAL_AUTH} + ASC_RET_REPLAY_DETECT = $00000004; + {$EXTERNALSYM ASC_RET_REPLAY_DETECT} + ASC_RET_SEQUENCE_DETECT = $00000008; + {$EXTERNALSYM ASC_RET_SEQUENCE_DETECT} + ASC_RET_CONFIDENTIALITY = $00000010; + {$EXTERNALSYM ASC_RET_CONFIDENTIALITY} + ASC_RET_USE_SESSION_KEY = $00000020; + {$EXTERNALSYM ASC_RET_USE_SESSION_KEY} + ASC_RET_ALLOCATED_MEMORY = $00000100; + {$EXTERNALSYM ASC_RET_ALLOCATED_MEMORY} + ASC_RET_USED_DCE_STYLE = $00000200; + {$EXTERNALSYM ASC_RET_USED_DCE_STYLE} + ASC_RET_DATAGRAM = $00000400; + {$EXTERNALSYM ASC_RET_DATAGRAM} + ASC_RET_CONNECTION = $00000800; + {$EXTERNALSYM ASC_RET_CONNECTION} + ASC_RET_CALL_LEVEL = $00002000; // skipped 1000 to be like ISC_ + {$EXTERNALSYM ASC_RET_CALL_LEVEL} + ASC_RET_THIRD_LEG_FAILED = $00004000; + {$EXTERNALSYM ASC_RET_THIRD_LEG_FAILED} + ASC_RET_EXTENDED_ERROR = $00008000; + {$EXTERNALSYM ASC_RET_EXTENDED_ERROR} + ASC_RET_STREAM = $00010000; + {$EXTERNALSYM ASC_RET_STREAM} + ASC_RET_INTEGRITY = $00020000; + {$EXTERNALSYM ASC_RET_INTEGRITY} + ASC_RET_LICENSING = $00040000; + {$EXTERNALSYM ASC_RET_LICENSING} + ASC_RET_IDENTIFY = $00080000; + {$EXTERNALSYM ASC_RET_IDENTIFY} + ASC_RET_NULL_SESSION = $00100000; + {$EXTERNALSYM ASC_RET_NULL_SESSION} + ASC_RET_ALLOW_NON_USER_LOGONS = $00200000; + {$EXTERNALSYM ASC_RET_ALLOW_NON_USER_LOGONS} + ASC_RET_ALLOW_CONTEXT_REPLAY = $00400000; + {$EXTERNALSYM ASC_RET_ALLOW_CONTEXT_REPLAY} + ASC_RET_FRAGMENT_ONLY = $00800000; + {$EXTERNALSYM ASC_RET_FRAGMENT_ONLY} + ASC_RET_NO_TOKEN = $01000000; + {$EXTERNALSYM ASC_RET_NO_TOKEN} + ASC_RET_NO_ADDITIONAL_TOKEN = $02000000; // *INTERNAL* + {$EXTERNALSYM ASC_RET_NO_ADDITIONAL_TOKEN} + ASC_RET_NO_PROXY_BINDINGS = $04000000; + {$EXTERNALSYM ASC_RET_NO_PROXY_BINDINGS} +// SSP_RET_REAUTHENTICATION = $08000000; // *INTERNAL* + {.$EXTERNALSYM SSP_RET_REAUTHENTICATION} + ASC_RET_MISSING_BINDINGS = $10000000; + {$EXTERNALSYM ASC_RET_MISSING_BINDINGS} + +// +// Security Credentials Attributes: +// + +const + SECPKG_CRED_ATTR_NAMES = 1; + {$EXTERNALSYM SECPKG_CRED_ATTR_NAMES} + SECPKG_CRED_ATTR_SSI_PROVIDER = 2; + {$EXTERNALSYM SECPKG_CRED_ATTR_SSI_PROVIDER} + +type + + PSecPkgCredentials_NamesW = ^SecPkgCredentials_NamesW; + {$EXTERNALSYM PSecPkgCredentials_NamesW} + SecPkgCredentials_NamesW = record + sUserName: PSEC_WCHAR; + end; + {$EXTERNALSYM SecPkgCredentials_NamesW} + + PSecPkgCredentials_NamesA = ^SecPkgCredentials_NamesA; + {$EXTERNALSYM PSecPkgCredentials_NamesA} + SecPkgCredentials_NamesA = record + sUserName: PSEC_CHAR; + end; + {$EXTERNALSYM SecPkgCredentials_NamesA} + +{$IFDEF SSPI_UNICODE} + SecPkgCredentials_Names = SecPkgCredentials_NamesW; + PSecPkgCredentials_Names = PSecPkgCredentials_NamesW; +{$ELSE} + SecPkgCredentials_Names = SecPkgCredentials_NamesA; + PSecPkgCredentials_Names = PSecPkgCredentials_NamesA; +{$ENDIF} + {$EXTERNALSYM SecPkgCredentials_Names} + {$EXTERNALSYM PSecPkgCredentials_Names} + + PSecPkgCredentials_SSIProviderW = ^SecPkgCredentials_SSIProviderW; + {$EXTERNALSYM PSecPkgCredentials_SSIProviderW} + SecPkgCredentials_SSIProviderW = record + sProviderName: PSEC_WCHAR; + ProviderInfoLength: ULONG; + ProviderInfo: PAnsiChar; + end; + {$EXTERNALSYM SecPkgCredentials_SSIProviderW} + + PSecPkgCredentials_SSIProviderA = ^SecPkgCredentials_SSIProviderA; + {$EXTERNALSYM PSecPkgCredentials_SSIProviderA} + SecPkgCredentials_SSIProviderA = record + sProviderName: PSEC_CHAR; + ProviderInfoLength: ULONG; + ProviderInfo: PAnsiChar; + end; + {$EXTERNALSYM SecPkgCredentials_SSIProviderA} + +{$IFDEF SSPI_UNICODE} + SecPkgCredentials_SSIProvider = SecPkgCredentials_SSIProviderW; + PSecPkgCredentials_SSIProvider = PSecPkgCredentials_SSIProviderW; +{$ELSE} + SecPkgCredentials_SSIProvider = SecPkgCredentials_SSIProviderA; + PSecPkgCredentials_SSIProvider = PSecPkgCredentials_SSIProviderA; +{$ENDIF} + {$EXTERNALSYM SecPkgCredentials_SSIProvider} + {$EXTERNALSYM PSecPkgCredentials_SSIProvider} + +// +// Security Context Attributes: +// + +const + + SECPKG_ATTR_SIZES = 0; + {$EXTERNALSYM SECPKG_ATTR_SIZES} + SECPKG_ATTR_NAMES = 1; + {$EXTERNALSYM SECPKG_ATTR_NAMES} + SECPKG_ATTR_LIFESPAN = 2; + {$EXTERNALSYM SECPKG_ATTR_LIFESPAN} + SECPKG_ATTR_DCE_INFO = 3; + {$EXTERNALSYM SECPKG_ATTR_DCE_INFO} + SECPKG_ATTR_STREAM_SIZES = 4; + {$EXTERNALSYM SECPKG_ATTR_STREAM_SIZES} + SECPKG_ATTR_KEY_INFO = 5; + {$EXTERNALSYM SECPKG_ATTR_KEY_INFO} + SECPKG_ATTR_AUTHORITY = 6; + {$EXTERNALSYM SECPKG_ATTR_AUTHORITY} + SECPKG_ATTR_PROTO_INFO = 7; + {$EXTERNALSYM SECPKG_ATTR_PROTO_INFO} + SECPKG_ATTR_PASSWORD_EXPIRY = 8; + {$EXTERNALSYM SECPKG_ATTR_PASSWORD_EXPIRY} + SECPKG_ATTR_SESSION_KEY = 9; + {$EXTERNALSYM SECPKG_ATTR_SESSION_KEY} + SECPKG_ATTR_PACKAGE_INFO = 10; + {$EXTERNALSYM SECPKG_ATTR_PACKAGE_INFO} + SECPKG_ATTR_USER_FLAGS = 11; + {$EXTERNALSYM SECPKG_ATTR_USER_FLAGS} + SECPKG_ATTR_NEGOTIATION_INFO = 12; + {$EXTERNALSYM SECPKG_ATTR_NEGOTIATION_INFO} + SECPKG_ATTR_NATIVE_NAMES = 13; + {$EXTERNALSYM SECPKG_ATTR_NATIVE_NAMES} + SECPKG_ATTR_FLAGS = 14; + {$EXTERNALSYM SECPKG_ATTR_FLAGS} +// These attributes exist only in Win XP and greater + SECPKG_ATTR_USE_VALIDATED = 15; + {$EXTERNALSYM SECPKG_ATTR_USE_VALIDATED} + SECPKG_ATTR_CREDENTIAL_NAME = 16; + {$EXTERNALSYM SECPKG_ATTR_CREDENTIAL_NAME} + SECPKG_ATTR_TARGET_INFORMATION = 17; + {$EXTERNALSYM SECPKG_ATTR_TARGET_INFORMATION} + SECPKG_ATTR_ACCESS_TOKEN = 18; + {$EXTERNALSYM SECPKG_ATTR_ACCESS_TOKEN} +// These attributes exist only in Win2K3 and greater + SECPKG_ATTR_TARGET = 19; + {$EXTERNALSYM SECPKG_ATTR_TARGET} + SECPKG_ATTR_AUTHENTICATION_ID = 20; + {$EXTERNALSYM SECPKG_ATTR_AUTHENTICATION_ID} +// These attributes exist only in Win2K3SP1 and greater + SECPKG_ATTR_LOGOFF_TIME = 21; + {$EXTERNALSYM SECPKG_ATTR_LOGOFF_TIME} +// +// win7 or greater +// + SECPKG_ATTR_NEGO_KEYS = 22; + {$EXTERNALSYM SECPKG_ATTR_NEGO_KEYS} + SECPKG_ATTR_PROMPTING_NEEDED = 24; + {$EXTERNALSYM SECPKG_ATTR_PROMPTING_NEEDED} + SECPKG_ATTR_UNIQUE_BINDINGS = 25; + {$EXTERNALSYM SECPKG_ATTR_UNIQUE_BINDINGS} + SECPKG_ATTR_ENDPOINT_BINDINGS = 26; + {$EXTERNALSYM SECPKG_ATTR_ENDPOINT_BINDINGS} + SECPKG_ATTR_CLIENT_SPECIFIED_TARGET = 27; + {$EXTERNALSYM SECPKG_ATTR_CLIENT_SPECIFIED_TARGET} + + SECPKG_ATTR_LAST_CLIENT_TOKEN_STATUS = 30; + {$EXTERNALSYM SECPKG_ATTR_LAST_CLIENT_TOKEN_STATUS} + SECPKG_ATTR_NEGO_PKG_INFO = 31; // contains nego info of packages + {$EXTERNALSYM SECPKG_ATTR_NEGO_PKG_INFO} + SECPKG_ATTR_NEGO_STATUS = 32; // contains the last error + {$EXTERNALSYM SECPKG_ATTR_NEGO_STATUS} + SECPKG_ATTR_CONTEXT_DELETED = 33; // a context has been deleted + {$EXTERNALSYM SECPKG_ATTR_CONTEXT_DELETED} + + SECPKG_ATTR_SUBJECT_SECURITY_ATTRIBUTES = 128; + {$EXTERNALSYM SECPKG_ATTR_SUBJECT_SECURITY_ATTRIBUTES} + +type + + PSecPkgContext_SubjectAttributes = ^SecPkgContext_SubjectAttributes; + {$EXTERNALSYM PSecPkgContext_SubjectAttributes} + SecPkgContext_SubjectAttributes = record + AttributeInfo: PVOID; // contains a PAUTHZ_SECURITY_ATTRIBUTES_INFORMATION structure + end; + {$EXTERNALSYM SecPkgContext_SubjectAttributes} + +const + SECPKG_ATTR_NEGO_INFO_FLAG_NO_KERBEROS = $1; + {$EXTERNALSYM SECPKG_ATTR_NEGO_INFO_FLAG_NO_KERBEROS} + SECPKG_ATTR_NEGO_INFO_FLAG_NO_NTLM = $2; + {$EXTERNALSYM SECPKG_ATTR_NEGO_INFO_FLAG_NO_NTLM} + +type + +// +// types of credentials, used by SECPKG_ATTR_PROMPTING_NEEDED +// + + PSECPKG_CRED_CLASS = ^SECPKG_CRED_CLASS; + {$EXTERNALSYM PSECPKG_CRED_CLASS} + SECPKG_CRED_CLASS = ULONG; + {$EXTERNALSYM SECPKG_CRED_CLASS} + +const + SecPkgCredClass_None = 0; // no creds + {$EXTERNALSYM SecPkgCredClass_None} + SecPkgCredClass_Ephemeral = 10; // logon creds + {$EXTERNALSYM SecPkgCredClass_Ephemeral} + SecPkgCredClass_PersistedGeneric = 20; // saved creds, not target specific + {$EXTERNALSYM SecPkgCredClass_PersistedGeneric} + SecPkgCredClass_PersistedSpecific = 30; // saved creds, target specific + {$EXTERNALSYM SecPkgCredClass_PersistedSpecific} + SecPkgCredClass_Explicit = 40; // explicitly supplied creds + {$EXTERNALSYM SecPkgCredClass_Explicit} + +type + + PSecPkgContext_CredInfo = ^SecPkgContext_CredInfo; + {$EXTERNALSYM PSecPkgContext_CredInfo} + SecPkgContext_CredInfo = record + CredClass: SECPKG_CRED_CLASS; + IsPromptingNeeded: ULONG; + end; + {$EXTERNALSYM SecPkgContext_CredInfo} + + PSecPkgContext_NegoPackageInfo = ^SecPkgContext_NegoPackageInfo; + {$EXTERNALSYM PSecPkgContext_NegoPackageInfo} + SecPkgContext_NegoPackageInfo = record + PackageMask: ULONG; + end; + {$EXTERNALSYM SecPkgContext_NegoPackageInfo} + + PSecPkgContext_NegoStatus = ^SecPkgContext_NegoStatus; + {$EXTERNALSYM PSecPkgContext_NegoStatus} + SecPkgContext_NegoStatus = record + LastStatus: ULONG; + end; + {$EXTERNALSYM SecPkgContext_NegoStatus} + + PSecPkgContext_Sizes = ^SecPkgContext_Sizes; + {$EXTERNALSYM PSecPkgContext_Sizes} + SecPkgContext_Sizes = record + cbMaxToken: ULONG; + cbMaxSignature: ULONG; + cbBlockSize: ULONG; + cbSecurityTrailer: ULONG; + end; + {$EXTERNALSYM SecPkgContext_Sizes} + + PSecPkgContext_StreamSizes = ^SecPkgContext_StreamSizes; + {$EXTERNALSYM PSecPkgContext_StreamSizes} + SecPkgContext_StreamSizes = record + cbHeader: ULONG; + cbTrailer: ULONG; + cbMaximumMessage: ULONG; + cBuffers: ULONG; + cbBlockSize: ULONG; + end; + {$EXTERNALSYM SecPkgContext_StreamSizes} + + PSecPkgContext_NamesW = ^SecPkgContext_NamesW; + {$EXTERNALSYM PSecPkgContext_NamesW} + SecPkgContext_NamesW = record + sUserName: PSEC_WCHAR; + end; + {$EXTERNALSYM SecPkgContext_NamesW} + + PSECPKG_ATTR_LCT_STATUS = ^SECPKG_ATTR_LCT_STATUS; + {$EXTERNALSYM PSECPKG_ATTR_LCT_STATUS} + SECPKG_ATTR_LCT_STATUS = ( + SecPkgAttrLastClientTokenYes, + SecPkgAttrLastClientTokenNo, + SecPkgAttrLastClientTokenMaybe + ); + {$EXTERNALSYM SECPKG_ATTR_LCT_STATUS} + + PSecPkgContext_LastClientTokenStatus = ^SecPkgContext_LastClientTokenStatus; + {$EXTERNALSYM PSecPkgContext_LastClientTokenStatus} + SecPkgContext_LastClientTokenStatus = record + LastClientTokenStatus: SECPKG_ATTR_LCT_STATUS; + end; + {$EXTERNALSYM SecPkgContext_LastClientTokenStatus} + + PSecPkgContext_NamesA = ^SecPkgContext_NamesA; + {$EXTERNALSYM PSecPkgContext_NamesA} + SecPkgContext_NamesA = record + sUserName: PSEC_CHAR; + end; + {$EXTERNALSYM SecPkgContext_NamesA} + +{$IFDEF SSPI_UNICODE} + SecPkgContext_Names = SecPkgContext_NamesW; + PSecPkgContext_Names = PSecPkgContext_NamesW; +{$ELSE} + SecPkgContext_Names = SecPkgContext_NamesA; + PSecPkgContext_Names = PSecPkgContext_NamesA; +{$ENDIF} + {$EXTERNALSYM SecPkgContext_Names} + {$EXTERNALSYM PSecPkgContext_Names} + + PSecPkgContext_Lifespan = ^SecPkgContext_Lifespan; + {$EXTERNALSYM PSecPkgContext_Lifespan} + SecPkgContext_Lifespan = record + tsStart: TimeStamp; + tsExpiry: TimeStamp; + end; + {$EXTERNALSYM SecPkgContext_Lifespan} + + PSecPkgContext_DceInfo = ^SecPkgContext_DceInfo; + {$EXTERNALSYM PSecPkgContext_DceInfo} + SecPkgContext_DceInfo = record + AuthzSvc: ULONG; + pPac: PVOID; + end; + {$EXTERNALSYM SecPkgContext_DceInfo} + + PSecPkgContext_KeyInfoA = ^SecPkgContext_KeyInfoA; + {$EXTERNALSYM PSecPkgContext_KeyInfoA} + SecPkgContext_KeyInfoA = record + sSignatureAlgorithmName: PSEC_CHAR; + sEncryptAlgorithmName: PSEC_CHAR; + KeySize: ULONG; + SignatureAlgorithm: ULONG; + EncryptAlgorithm: ULONG; + end; + {$EXTERNALSYM SecPkgContext_KeyInfoA} + + PSecPkgContext_KeyInfoW = ^SecPkgContext_KeyInfoW; + {$EXTERNALSYM PSecPkgContext_KeyInfoW} + SecPkgContext_KeyInfoW = record + sSignatureAlgorithmName: PSEC_WCHAR; + sEncryptAlgorithmName: PSEC_WCHAR; + KeySize: ULONG; + SignatureAlgorithm: ULONG; + EncryptAlgorithm: ULONG; + end; + {$EXTERNALSYM SecPkgContext_KeyInfoW} + +{$IFDEF SSPI_UNICODE} + SecPkgContext_KeyInfo = SecPkgContext_KeyInfoW; + PSecPkgContext_KeyInfo = PSecPkgContext_KeyInfoW; +{$ELSE} + SecPkgContext_KeyInfo = SecPkgContext_KeyInfoA; + PSecPkgContext_KeyInfo = PSecPkgContext_KeyInfoA; +{$ENDIF} + {$EXTERNALSYM SecPkgContext_KeyInfo} + {$EXTERNALSYM PSecPkgContext_KeyInfo} + + PSecPkgContext_AuthorityA = ^SecPkgContext_AuthorityA; + {$EXTERNALSYM PSecPkgContext_AuthorityA} + SecPkgContext_AuthorityA = record + sAuthorityName: PSEC_CHAR; + end; + {$EXTERNALSYM SecPkgContext_AuthorityA} + + PSecPkgContext_AuthorityW = ^SecPkgContext_AuthorityW; + {$EXTERNALSYM PSecPkgContext_AuthorityW} + SecPkgContext_AuthorityW = record + sAuthorityName: PSEC_WCHAR; + end; + {$EXTERNALSYM SecPkgContext_AuthorityW} + +{$IFDEF SSPI_UNICODE} + SecPkgContext_Authority = SecPkgContext_AuthorityW; + PSecPkgContext_Authority = PSecPkgContext_AuthorityW; +{$ELSE} + SecPkgContext_Authority = SecPkgContext_AuthorityA; + PSecPkgContext_Authority = PSecPkgContext_AuthorityA; +{$ENDIF} + {$EXTERNALSYM SecPkgContext_Authority} + {$EXTERNALSYM PSecPkgContext_Authority} + + PSecPkgContext_ProtoInfoA = ^SecPkgContext_ProtoInfoA; + {$EXTERNALSYM PSecPkgContext_ProtoInfoA} + SecPkgContext_ProtoInfoA = record + sProtocolName: PSEC_CHAR; + majorVersion: ULONG; + minorVersion: ULONG; + end; + {$EXTERNALSYM SecPkgContext_ProtoInfoA} + + PSecPkgContext_ProtoInfoW = ^SecPkgContext_ProtoInfoW; + {$EXTERNALSYM PSecPkgContext_ProtoInfoW} + SecPkgContext_ProtoInfoW = record + sProtocolName: PSEC_WCHAR; + majorVersion: ULONG; + minorVersion: ULONG; + end; + {$EXTERNALSYM SecPkgContext_ProtoInfoW} + +{$IFDEF SSPI_UNICODE} + SecPkgContext_ProtoInfo = SecPkgContext_ProtoInfoW; + PSecPkgContext_ProtoInfo = PSecPkgContext_ProtoInfoW; +{$ELSE} + SecPkgContext_ProtoInfo = SecPkgContext_ProtoInfoA; + PSecPkgContext_ProtoInfo = PSecPkgContext_ProtoInfoA; +{$ENDIF} + {$EXTERNALSYM SecPkgContext_ProtoInfo} + {$EXTERNALSYM PSecPkgContext_ProtoInfo} + + PSecPkgContext_PasswordExpiry = ^SecPkgContext_PasswordExpiry; + {$EXTERNALSYM PSecPkgContext_PasswordExpiry} + SecPkgContext_PasswordExpiry = record + tsPasswordExpires: TimeStamp; + end; + {$EXTERNALSYM SecPkgContext_PasswordExpiry} + + PSecPkgContext_LogoffTime = ^SecPkgContext_LogoffTime; + {$EXTERNALSYM PSecPkgContext_LogoffTime} + SecPkgContext_LogoffTime = record + tsLogoffTime: TimeStamp; + end; + {$EXTERNALSYM SecPkgContext_LogoffTime} + + PSecPkgContext_SessionKey = ^SecPkgContext_SessionKey; + {$EXTERNALSYM PSecPkgContext_SessionKey} + SecPkgContext_SessionKey = record + SessionKeyLength: ULONG; + SessionKey: PUCHAR; + end; + {$EXTERNALSYM SecPkgContext_SessionKey} + + // used by nego2 + PSecPkgContext_NegoKeys = ^SecPkgContext_NegoKeys; + {$EXTERNALSYM PSecPkgContext_NegoKeys} + SecPkgContext_NegoKeys = record + KeyType: ULONG; + KeyLength: USHORT; + KeyValue: PUCHAR; + VerifyKeyType: ULONG; + VerifyKeyLength: USHORT; + VerifyKeyValue: PUCHAR; + end; + {$EXTERNALSYM SecPkgContext_NegoKeys} + + PSecPkgContext_PackageInfoW = ^SecPkgContext_PackageInfoW; + {$EXTERNALSYM PSecPkgContext_PackageInfoW} + SecPkgContext_PackageInfoW = record + PackageInfo: PSecPkgInfoW; + end; + {$EXTERNALSYM SecPkgContext_PackageInfoW} + + PSecPkgContext_PackageInfoA = ^SecPkgContext_PackageInfoA; + {$EXTERNALSYM PSecPkgContext_PackageInfoA} + SecPkgContext_PackageInfoA = record + PackageInfo: PSecPkgInfoA; + end; + {$EXTERNALSYM SecPkgContext_PackageInfoA} + + PSecPkgContext_UserFlags = ^SecPkgContext_UserFlags; + {$EXTERNALSYM PSecPkgContext_UserFlags} + SecPkgContext_UserFlags = record + UserFlags: ULONG; + end; + {$EXTERNALSYM SecPkgContext_UserFlags} + + PSecPkgContext_Flags = ^SecPkgContext_Flags; + {$EXTERNALSYM PSecPkgContext_Flags} + SecPkgContext_Flags = record + Flags: ULONG; + end; + {$EXTERNALSYM SecPkgContext_Flags} + +{$IFDEF SSPI_UNICODE} + SecPkgContext_PackageInfo = SecPkgContext_PackageInfoW; + PSecPkgContext_PackageInfo = PSecPkgContext_PackageInfoW; +{$ELSE} + SecPkgContext_PackageInfo = SecPkgContext_PackageInfoA; + PSecPkgContext_PackageInfo = PSecPkgContext_PackageInfoA; +{$ENDIF} + {$EXTERNALSYM SecPkgContext_PackageInfo} + {$EXTERNALSYM PSecPkgContext_PackageInfo} + + PSecPkgContext_NegotiationInfoA = ^SecPkgContext_NegotiationInfoA; + {$EXTERNALSYM PSecPkgContext_NegotiationInfoA} + SecPkgContext_NegotiationInfoA = record + PackageInfo: PSecPkgInfoA; + NegotiationState: ULONG; + end; + {$EXTERNALSYM SecPkgContext_NegotiationInfoA} + + PSecPkgContext_NegotiationInfoW = ^SecPkgContext_NegotiationInfoW; + {$EXTERNALSYM PSecPkgContext_NegotiationInfoW} + SecPkgContext_NegotiationInfoW = record + PackageInfo: PSecPkgInfoW; + NegotiationState: ULONG; + end; + {$EXTERNALSYM SecPkgContext_NegotiationInfoW} + +{$IFDEF SSPI_UNICODE} + SecPkgContext_NegotiationInfo = SecPkgContext_NegotiationInfoW; + PSecPkgContext_NegotiationInfo = PSecPkgContext_NegotiationInfoW; +{$ELSE} + SecPkgContext_NegotiationInfo = SecPkgContext_NegotiationInfoA; + PSecPkgContext_NegotiationInfo = PSecPkgContext_NegotiationInfoA; +{$ENDIF} + {$EXTERNALSYM SecPkgContext_NegotiationInfo} + {$EXTERNALSYM PSecPkgContext_NegotiationInfo} + +const + + SECPKG_NEGOTIATION_COMPLETE = 0; + {$EXTERNALSYM SECPKG_NEGOTIATION_COMPLETE} + SECPKG_NEGOTIATION_OPTIMISTIC = 1; + {$EXTERNALSYM SECPKG_NEGOTIATION_OPTIMISTIC} + SECPKG_NEGOTIATION_IN_PROGRESS = 2; + {$EXTERNALSYM SECPKG_NEGOTIATION_IN_PROGRESS} + SECPKG_NEGOTIATION_DIRECT = 3; + {$EXTERNALSYM SECPKG_NEGOTIATION_DIRECT} + SECPKG_NEGOTIATION_TRY_MULTICRED = 4; + {$EXTERNALSYM SECPKG_NEGOTIATION_TRY_MULTICRED} + +type + + PSecPkgContext_NativeNamesW = ^SecPkgContext_NativeNamesW; + {$EXTERNALSYM PSecPkgContext_NativeNamesW} + SecPkgContext_NativeNamesW = record + sClientName: PSEC_WCHAR; + sServerName: PSEC_WCHAR; + end; + {$EXTERNALSYM SecPkgContext_NativeNamesW} + + PSecPkgContext_NativeNamesA = ^SecPkgContext_NativeNamesA; + {$EXTERNALSYM PSecPkgContext_NativeNamesA} + SecPkgContext_NativeNamesA = record + sClientName: PSEC_CHAR; + sServerName: PSEC_CHAR; + end; + {$EXTERNALSYM SecPkgContext_NativeNamesA} + +{$IFDEF SSPI_UNICODE} + SecPkgContext_NativeNames = SecPkgContext_NativeNamesW; + PSecPkgContext_NativeNames = PSecPkgContext_NativeNamesW; +{$ELSE} + SecPkgContext_NativeNames = SecPkgContext_NativeNamesA; + PSecPkgContext_NativeNames = PSecPkgContext_NativeNamesA; +{$ENDIF} + {$EXTERNALSYM SecPkgContext_NativeNames} + {$EXTERNALSYM PSecPkgContext_NativeNames} + + PSecPkgContext_CredentialNameW = ^SecPkgContext_CredentialNameW; + {$EXTERNALSYM PSecPkgContext_CredentialNameW} + SecPkgContext_CredentialNameW = record + CredentialType: ULONG; + sCredentialName: PSEC_WCHAR; + end; + {$EXTERNALSYM SecPkgContext_CredentialNameW} + + PSecPkgContext_CredentialNameA = ^SecPkgContext_CredentialNameA; + {$EXTERNALSYM PSecPkgContext_CredentialNameA} + SecPkgContext_CredentialNameA = record + CredentialType: ULONG; + sCredentialName: PSEC_CHAR; + end; + {$EXTERNALSYM SecPkgContext_CredentialNameA} + +{$IFDEF SSPI_UNICODE} + SecPkgContext_CredentialName = SecPkgContext_CredentialNameW; + PSecPkgContext_CredentialName = PSecPkgContext_CredentialNameW; +{$ELSE} + SecPkgContext_CredentialName = SecPkgContext_CredentialNameA; + PSecPkgContext_CredentialName = PSecPkgContext_CredentialNameA; +{$ENDIF} + {$EXTERNALSYM SecPkgContext_CredentialName} + {$EXTERNALSYM PSecPkgContext_CredentialName} + + PSecPkgContext_AccessToken = ^SecPkgContext_AccessToken; + {$EXTERNALSYM PSecPkgContext_AccessToken} + SecPkgContext_AccessToken = record + AccessToken: PVOID; + end; + {$EXTERNALSYM SecPkgContext_AccessToken} + + PSecPkgContext_TargetInformation = ^SecPkgContext_TargetInformation; + {$EXTERNALSYM PSecPkgContext_TargetInformation} + SecPkgContext_TargetInformation = record + MarshalledTargetInfoLength: ULONG; + MarshalledTargetInfo: PUCHAR; + end; + {$EXTERNALSYM SecPkgContext_TargetInformation} + + PSecPkgContext_AuthzID = ^SecPkgContext_AuthzID; + {$EXTERNALSYM PSecPkgContext_AuthzID} + SecPkgContext_AuthzID = record + AuthzIDLength: ULONG; + AuthzID: PAnsiChar; + end; + {$EXTERNALSYM SecPkgContext_AuthzID} + + PSecPkgContext_Target = ^SecPkgContext_Target; + {$EXTERNALSYM PSecPkgContext_Target} + SecPkgContext_Target = record + TargetLength: ULONG; + Target: PAnsiChar; + end; + {$EXTERNALSYM SecPkgContext_Target} + + PSecPkgContext_ClientSpecifiedTarget = ^SecPkgContext_ClientSpecifiedTarget; + {$EXTERNALSYM PSecPkgContext_ClientSpecifiedTarget} + SecPkgContext_ClientSpecifiedTarget = record + sTargetName: PSEC_WCHAR; + end; + {$EXTERNALSYM SecPkgContext_ClientSpecifiedTarget} + + PSecPkgContext_Bindings = ^SecPkgContext_Bindings; + {$EXTERNALSYM PSecPkgContext_Bindings} + SecPkgContext_Bindings = record + BindingsLength: ULONG; + Bindings: PSEC_CHANNEL_BINDINGS; + end; + {$EXTERNALSYM SecPkgContext_Bindings} + + SEC_GET_KEY_FN = procedure( + Arg: PVOID; // Argument passed in + Principal: PVOID; // Principal ID + KeyVer: ULONG; // Key Version + Key: PPVOID; // Returned ptr to key + Status: PSECURITY_STATUS // returned status + ); stdcall; + {$EXTERNALSYM SEC_GET_KEY_FN} + +// +// Flags for ExportSecurityContext +// + +const + + SECPKG_CONTEXT_EXPORT_RESET_NEW = $00000001; // New context is reset to initial state + {$EXTERNALSYM SECPKG_CONTEXT_EXPORT_RESET_NEW} + SECPKG_CONTEXT_EXPORT_DELETE_OLD = $00000002; // Old context is deleted during export + {$EXTERNALSYM SECPKG_CONTEXT_EXPORT_DELETE_OLD} + // This is only valid in W2K3SP1 and greater + SECPKG_CONTEXT_EXPORT_TO_KERNEL = $00000004; // Context is to be transferred to the kernel + {$EXTERNALSYM SECPKG_CONTEXT_EXPORT_TO_KERNEL} + + +type + + ACQUIRE_CREDENTIALS_HANDLE_FN_W = function( // AcquireCredentialsHandleW + pszPrincipal: PSEC_WCHAR; // Name of principal + pszPackage: PSEC_WCHAR; // Name of package + fCredentialUse: ULONG; // Flags indicating use + pvLogonId: PVOID; // Pointer to logon ID + pAuthData: PVOID; // Package specific data + pGetKeyFn: SEC_GET_KEY_FN; // Pointer to GetKey() func + pvGetKeyArgument: PVOID; // Value to pass to GetKey() + phCredential: PCredHandle; // (out) Cred Handle + ptsExpiry: PTimeStamp // (out) Lifetime (optional) + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM ACQUIRE_CREDENTIALS_HANDLE_FN_W} + + ACQUIRE_CREDENTIALS_HANDLE_FN_A = function( // AcquireCredentialsHandleW + pszPrincipal: PSEC_CHAR; // Name of principal + pszPackage: PSEC_CHAR; // Name of package + fCredentialUse: ULONG; // Flags indicating use + pvLogonId: PVOID; // Pointer to logon ID + pAuthData: PVOID; // Package specific data + pGetKeyFn: SEC_GET_KEY_FN; // Pointer to GetKey() func + pvGetKeyArgument: PVOID; // Value to pass to GetKey() + phCredential: PCredHandle; // (out) Cred Handle + ptsExpiry: PTimeStamp // (out) Lifetime (optional) + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM ACQUIRE_CREDENTIALS_HANDLE_FN_A} + +{$IFDEF SSPI_UNICODE} + ACQUIRE_CREDENTIALS_HANDLE_FN = ACQUIRE_CREDENTIALS_HANDLE_FN_W; +{$ELSE} + ACQUIRE_CREDENTIALS_HANDLE_FN = ACQUIRE_CREDENTIALS_HANDLE_FN_A; +{$ENDIF} + {$EXTERNALSYM ACQUIRE_CREDENTIALS_HANDLE_FN} + + FREE_CREDENTIALS_HANDLE_FN = function( // FreeCredentialsHandle + phCredential: PCredHandle // Handle to free + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM FREE_CREDENTIALS_HANDLE_FN} + + ADD_CREDENTIALS_FN_W = function( // AddCredentialsW + hCredentials: PCredHandle; + pszPrincipal: PSEC_WCHAR; // Name of principal + pszPackage: PSEC_WCHAR; // Name of package + fCredentialUse: ULONG; // Flags indicating use + pAuthData: PVOID; // Package specific data + pGetKeyFn: SEC_GET_KEY_FN; // Pointer to GetKey() func + pvGetKeyArgument: PVOID; // Value to pass to GetKey() + ptsExpiry: PTimeStamp // (out) Lifetime (optional) + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM ADD_CREDENTIALS_FN_W} + + ADD_CREDENTIALS_FN_A = function( // AddCredentialsA + hCredentials: PCredHandle; + pszPrincipal: PSEC_CHAR; // Name of principal + pszPackage: PSEC_CHAR; // Name of package + fCredentialUse: ULONG; // Flags indicating use + pAuthData: PVOID; // Package specific data + pGetKeyFn: SEC_GET_KEY_FN; // Pointer to GetKey() func + pvGetKeyArgument: PVOID; // Value to pass to GetKey() + ptsExpiry: PTimeStamp // (out) Lifetime (optional) + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM ADD_CREDENTIALS_FN_A} + +{$IFDEF SSPI_UNICODE} + ADD_CREDENTIALS_FN = ADD_CREDENTIALS_FN_W; +{$ELSE} + ADD_CREDENTIALS_FN = ADD_CREDENTIALS_FN_A; +{$ENDIF} + {$EXTERNALSYM ADD_CREDENTIALS_FN} + +(* +#ifdef WIN32_CHICAGO +SECURITY_STATUS SEC_ENTRY +SspiLogonUserW( + SEC_WCHAR SEC_FAR * pszPackage, // Name of package + SEC_WCHAR SEC_FAR * pszUserName, // Name of package + SEC_WCHAR SEC_FAR * pszDomainName, // Name of package + SEC_WCHAR SEC_FAR * pszPassword // Name of package + ); + +typedef SECURITY_STATUS +(SEC_ENTRY * SSPI_LOGON_USER_FN_W)( + SEC_CHAR SEC_FAR *, + SEC_CHAR SEC_FAR *, + SEC_CHAR SEC_FAR *, + SEC_CHAR SEC_FAR * ); + +SECURITY_STATUS SEC_ENTRY +SspiLogonUserA( + SEC_CHAR SEC_FAR * pszPackage, // Name of package + SEC_CHAR SEC_FAR * pszUserName, // Name of package + SEC_CHAR SEC_FAR * pszDomainName, // Name of package + SEC_CHAR SEC_FAR * pszPassword // Name of package + ); + +typedef SECURITY_STATUS +(SEC_ENTRY * SSPI_LOGON_USER_FN_A)( + SEC_CHAR SEC_FAR *, + SEC_CHAR SEC_FAR *, + SEC_CHAR SEC_FAR *, + SEC_CHAR SEC_FAR * ); + +#ifdef UNICODE +#define SspiLogonUser SspiLogonUserW // ntifs +#define SSPI_LOGON_USER_FN SSPI_LOGON_USER_FN_W +#else +#define SspiLogonUser SspiLogonUserA +#define SSPI_LOGON_USER_FN SSPI_LOGON_USER_FN_A +#endif // !UNICODE +#endif // WIN32_CHICAGO +*) + +//////////////////////////////////////////////////////////////////////// +/// +/// Password Change Functions +/// +//////////////////////////////////////////////////////////////////////// + + CHANGE_PASSWORD_FN_W = function( // ChangeAccountPasswordW + pszPackageName: PSEC_WCHAR; + pszDomainName: PSEC_WCHAR; + pszAccountName: PSEC_WCHAR; + pszOldPassword: PSEC_WCHAR; + pszNewPassword: PSEC_WCHAR; + bImpersonating: BOOLEAN; + dwReserved: ULONG; + pOutput: PSecBufferDesc + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM CHANGE_PASSWORD_FN_W} + + CHANGE_PASSWORD_FN_A = function( // ChangeAccountPasswordA + pszPackageName: PSEC_CHAR; + pszDomainName: PSEC_CHAR; + pszAccountName: PSEC_CHAR; + pszOldPassword: PSEC_CHAR; + pszNewPassword: PSEC_CHAR; + bImpersonating: BOOLEAN; + dwReserved: ULONG; + pOutput: PSecBufferDesc + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM CHANGE_PASSWORD_FN_A} + +{$IFDEF SSPI_UNICODE} + CHANGE_PASSWORD_FN = CHANGE_PASSWORD_FN_W; +{$ELSE} + CHANGE_PASSWORD_FN = CHANGE_PASSWORD_FN_A; +{$ENDIF} + {$EXTERNALSYM CHANGE_PASSWORD_FN} + +//////////////////////////////////////////////////////////////////////// +/// +/// Context Management Functions +/// +//////////////////////////////////////////////////////////////////////// + + INITIALIZE_SECURITY_CONTEXT_FN_W = function( // InitializeSecurityContextW + phCredential: PCredHandle; // Cred to base context + phContext: PCtxtHandle; // Existing context (OPT) + pszTargetName: PSEC_WCHAR; // Name of target + fContextReq: ULONG; // Context Requirements + Reserved1: ULONG; // Reserved, MBZ + TargetDataRep: ULONG; // Data rep of target + pInput: PSecBufferDesc; // Input Buffers + Reserved2: ULONG; // Reserved, MBZ + phNewContext: PCtxtHandle; // (out) New Context handle + pOutput: PSecBufferDesc; // (inout) Output Buffers + pfContextAttr: PULONG; // (out) Context attrs + ptsExpiry: PTimeStamp // (out) Life span (OPT) + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM INITIALIZE_SECURITY_CONTEXT_FN_W} + + INITIALIZE_SECURITY_CONTEXT_FN_A = function( // InitializeSecurityContextA + phCredential: PCredHandle; // Cred to base context + phContext: PCtxtHandle; // Existing context (OPT) + pszTargetName: PSEC_CHAR; // Name of target + fContextReq: ULONG; // Context Requirements + Reserved1: ULONG; // Reserved, MBZ + TargetDataRep: ULONG; // Data rep of target + pInput: PSecBufferDesc; // Input Buffers + Reserved2: ULONG; // Reserved, MBZ + phNewContext: PCtxtHandle; // (out) New Context handle + pOutput: PSecBufferDesc; // (inout) Output Buffers + pfContextAttr: PULONG; // (out) Context attrs + ptsExpiry: PTimeStamp // (out) Life span (OPT) + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM INITIALIZE_SECURITY_CONTEXT_FN_A} + +{$IFDEF SSPI_UNICODE} + INITIALIZE_SECURITY_CONTEXT_FN = INITIALIZE_SECURITY_CONTEXT_FN_W; +{$ELSE} + INITIALIZE_SECURITY_CONTEXT_FN = INITIALIZE_SECURITY_CONTEXT_FN_A; +{$ENDIF} + {$EXTERNALSYM INITIALIZE_SECURITY_CONTEXT_FN} + + ACCEPT_SECURITY_CONTEXT_FN = function( // AcceptSecurityContext + phCredential: PCredHandle; // Cred to base context + phContext: PCtxtHandle; // Existing context (OPT) + pInput: PSecBufferDesc; // Input buffer + fContextReq: ULONG; // Context Requirements + TargetDataRep: ULONG; // Target Data Rep + phNewContext: PCtxtHandle; // (out) New context handle + pOutput: PSecBufferDesc; // (inout) Output buffers + pfContextAttr: PULONG; // (out) Context attributes + ptsExpiry: PTimeStamp // (out) Life span (OPT) + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM ACCEPT_SECURITY_CONTEXT_FN} + + COMPLETE_AUTH_TOKEN_FN = function( // CompleteAuthToken + phContext: PCtxtHandle; // Context to complete + pToken: PSecBufferDesc // Token to complete + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM COMPLETE_AUTH_TOKEN_FN} + + IMPERSONATE_SECURITY_CONTEXT_FN = function( // ImpersonateSecurityContext + phContext: PCtxtHandle + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM IMPERSONATE_SECURITY_CONTEXT_FN} + + REVERT_SECURITY_CONTEXT_FN = function( // RevertSecurityContext + phContext: PCtxtHandle + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM REVERT_SECURITY_CONTEXT_FN} + + QUERY_SECURITY_CONTEXT_TOKEN_FN = function( // QuerySecurityContextToken + phContext: PCtxtHandle; + Token: PPVOID + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM QUERY_SECURITY_CONTEXT_TOKEN_FN} + + DELETE_SECURITY_CONTEXT_FN = function( // DeleteSecurityContext + phContext: PCtxtHandle + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM DELETE_SECURITY_CONTEXT_FN} + + APPLY_CONTROL_TOKEN_FN = function( // ApplyControlToken + phContext: PCtxtHandle; // Context to modify + pInput: PSecBufferDesc // Input token to apply + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM APPLY_CONTROL_TOKEN_FN} + + QUERY_CONTEXT_ATTRIBUTES_FN_W = function( // QueryContextAttributesW + phContext: PCtxtHandle; // Context to query + ulAttribute: ULONG; // Attribute to query + pBuffer: PVOID // Buffer for attributes + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM QUERY_CONTEXT_ATTRIBUTES_FN_W} + + QUERY_CONTEXT_ATTRIBUTES_FN_A = function( // QueryContextAttributesA + phContext: PCtxtHandle; // Context to query + ulAttribute: ULONG; // Attribute to query + pBuffer: PVOID // Buffer for attributes + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM QUERY_CONTEXT_ATTRIBUTES_FN_A} + +{$IFDEF SSPI_UNICODE} + QUERY_CONTEXT_ATTRIBUTES_FN = QUERY_CONTEXT_ATTRIBUTES_FN_W; +{$ELSE} + QUERY_CONTEXT_ATTRIBUTES_FN = QUERY_CONTEXT_ATTRIBUTES_FN_A; +{$ENDIF} + {$EXTERNALSYM QUERY_CONTEXT_ATTRIBUTES_FN} + + SET_CONTEXT_ATTRIBUTES_FN_W = function( // SetContextAttributesW + phContext: PCtxtHandle; // Context to Set + ulAttribute: ULONG; // Attribute to Set + pBuffer: PVOID; // Buffer for attributes + cbBuffer: ULONG // Size (in bytes) of Buffer + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM SET_CONTEXT_ATTRIBUTES_FN_W} + + SET_CONTEXT_ATTRIBUTES_FN_A = function( // SetContextAttributesA + phContext: PCtxtHandle; // Context to Set + ulAttribute: ULONG; // Attribute to Set + pBuffer: PVOID; // Buffer for attributes + cbBuffer: ULONG // Size (in bytes) of Buffer + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM SET_CONTEXT_ATTRIBUTES_FN_A} + + QUERY_CREDENTIALS_ATTRIBUTES_FN_W = function( // QueryCredentialsAttributesW + phCredential: PCredHandle; // Credential to query + ulAttribute: ULONG; // Attribute to query + pBuffer: PVOID // Buffer for attributes + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM QUERY_CREDENTIALS_ATTRIBUTES_FN_W} + + QUERY_CREDENTIALS_ATTRIBUTES_FN_A = function( // QueryCredentialsAttributesA + phCredential: PCredHandle; // Credential to query + ulAttribute: ULONG; // Attribute to query + pBuffer: PVOID // Buffer for attributes + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM QUERY_CREDENTIALS_ATTRIBUTES_FN_A} + +{$IFDEF SSPI_UNICODE} + QUERY_CREDENTIALS_ATTRIBUTES_FN = QUERY_CREDENTIALS_ATTRIBUTES_FN_W; +{$ELSE} + QUERY_CREDENTIALS_ATTRIBUTES_FN = QUERY_CREDENTIALS_ATTRIBUTES_FN_A; +{$ENDIF} + {$EXTERNALSYM QUERY_CREDENTIALS_ATTRIBUTES_FN} + + SET_CREDENTIALS_ATTRIBUTES_FN_W = function( // SetCredentialsAttributesW + phCredential: PCredHandle; // Credential to Set + ulAttribute: ULONG; // Attribute to Set + pBuffer: PVOID; // Buffer for attributes + cbBuffer: ULONG // Size (in bytes) of Buffer + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM SET_CREDENTIALS_ATTRIBUTES_FN_W} + + SET_CREDENTIALS_ATTRIBUTES_FN_A = function( // SetCredentialsAttributesA + phCredential: PCredHandle; // Credential to Set + ulAttribute: ULONG; // Attribute to Set + pBuffer: PVOID; // Buffer for attributes + cbBuffer: ULONG // Size (in bytes) of Buffer + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM SET_CREDENTIALS_ATTRIBUTES_FN_A} + + FREE_CONTEXT_BUFFER_FN = function( // FreeContextBuffer + pvContextBuffer: PVOID // buffer to free + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM FREE_CONTEXT_BUFFER_FN} + +/////////////////////////////////////////////////////////////////// +//// +//// Message Support API +//// +////////////////////////////////////////////////////////////////// + +type + + MAKE_SIGNATURE_FN = function( // MakeSignature + phContext: PCtxtHandle; // Context to use + fQOP: ULONG; // Quality of Protection + pMessage: PSecBufferDesc; // Message to sign + MessageSeqNo: ULONG // Message Sequence Num. + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM MAKE_SIGNATURE_FN} + + VERIFY_SIGNATURE_FN = function( // VerifySignature + phContext: PCtxtHandle; // Context to use + pMessage: PSecBufferDesc; // Message to verify + MessageSeqNo: ULONG; // Sequence Num. + pfQOP: PULONG // QOP used + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM VERIFY_SIGNATURE_FN} + + ENCRYPT_MESSAGE_FN = function( // EncryptMessage + phContext: PCtxtHandle; + fQOP: ULONG; + pMessage: PSecBufferDesc; + MessageSeqNo: ULONG + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM ENCRYPT_MESSAGE_FN} + + DECRYPT_MESSAGE_FN = function( // DecryptMessage + phContext: PCtxtHandle; + pMessage: PSecBufferDesc; + MessageSeqNo: ULONG; + pfQOP: PULONG + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM DECRYPT_MESSAGE_FN} + +/////////////////////////////////////////////////////////////////////////// +//// +//// Misc. +//// +/////////////////////////////////////////////////////////////////////////// + +type + + ENUMERATE_SECURITY_PACKAGES_FN_W = function( // EnumerateSecurityPackagesW + pcPackages: PULONG; // Receives num. packages + ppPackageInfo: PPSecPkgInfoW // Receives array of info + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM ENUMERATE_SECURITY_PACKAGES_FN_W} + + ENUMERATE_SECURITY_PACKAGES_FN_A = function( // EnumerateSecurityPackagesA + pcPackages: PULONG; // Receives num. packages + ppPackageInfo: PPSecPkgInfoA // Receives array of info + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM ENUMERATE_SECURITY_PACKAGES_FN_A} + +{$IFDEF SSPI_UNICODE} + ENUMERATE_SECURITY_PACKAGES_FN = ENUMERATE_SECURITY_PACKAGES_FN_W; +{$ELSE} + ENUMERATE_SECURITY_PACKAGES_FN = ENUMERATE_SECURITY_PACKAGES_FN_A; +{$ENDIF} + {$EXTERNALSYM ENUMERATE_SECURITY_PACKAGES_FN} + + QUERY_SECURITY_PACKAGE_INFO_FN_W = function( // QuerySecurityPackageInfoW + pszPackageName: PSEC_WCHAR; // Name of package + ppPackageInfo: PPSecPkgInfoW // Receives package info + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM QUERY_SECURITY_PACKAGE_INFO_FN_W} + + QUERY_SECURITY_PACKAGE_INFO_FN_A = function( // QuerySecurityPackageInfoA + pszPackageName: PSEC_CHAR; // Name of package + ppPackageInfo: PPSecPkgInfoA // Receives package info + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM QUERY_SECURITY_PACKAGE_INFO_FN_A} + +{$IFDEF SSPI_UNICODE} + QUERY_SECURITY_PACKAGE_INFO_FN = QUERY_SECURITY_PACKAGE_INFO_FN_W; +{$ELSE} + QUERY_SECURITY_PACKAGE_INFO_FN = QUERY_SECURITY_PACKAGE_INFO_FN_A; +{$ENDIF} + {$EXTERNALSYM QUERY_SECURITY_PACKAGE_INFO_FN} + + PSecDelegationType = ^SecDelegationType; + {$EXTERNALSYM PSecDelegationType} + SecDelegationType = ( + SecFull, + SecService, + SecTree, + SecDirectory, + SecObject + ); + {$EXTERNALSYM SecDelegationType} + + DELEGATE_SECURITY_CONTEXT_FN = function( // DelegateSecurityContext + phContext: PCtxtHandle; // IN Active context to delegate + pszTarget: PSEC_CHAR; + DelegationType: SecDelegationType; // IN Type of delegation + pExpiry: PTimeStamp; // IN OPTIONAL time limit + pPackageParameters: PSecBuffer; // IN OPTIONAL package specific + pOutput: PSecBufferDesc // OUT Token for applycontroltoken. + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM DELEGATE_SECURITY_CONTEXT_FN} + +/////////////////////////////////////////////////////////////////////////// +//// +//// Proxies +//// +/////////////////////////////////////////////////////////////////////////// + +// +// Proxies are only available on NT platforms +// + +/////////////////////////////////////////////////////////////////////////// +//// +//// Context export/import +//// +/////////////////////////////////////////////////////////////////////////// + +type + + EXPORT_SECURITY_CONTEXT_FN = function( // ExportSecurityContext + phContext: PCtxtHandle; // (in) context to export + fFlags: ULONG; // (in) option flags + pPackedContext: PSecBuffer; // (out) marshalled context + pToken: PPVOID // (out, optional) token handle for impersonation + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM EXPORT_SECURITY_CONTEXT_FN} + + IMPORT_SECURITY_CONTEXT_FN_W = function( // ImportSecurityContextW + pszPackage: PSEC_WCHAR; + pPackedContext: PSecBuffer; // (in) marshalled context + Token: PVOID; // (in, optional) handle to token for context + phContext: PCtxtHandle // (out) new context handle + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM IMPORT_SECURITY_CONTEXT_FN_W} + + IMPORT_SECURITY_CONTEXT_FN_A = function( // ImportSecurityContextA + pszPackage: PSEC_CHAR; + pPackedContext: PSecBuffer; // (in) marshalled context + Token: PVOID; // (in, optional) handle to token for context + phContext: PCtxtHandle // (out) new context handle + ): SECURITY_STATUS; stdcall; + {$EXTERNALSYM IMPORT_SECURITY_CONTEXT_FN_A} + +{$IFDEF SSPI_UNICODE} + IMPORT_SECURITY_CONTEXT_FN = IMPORT_SECURITY_CONTEXT_FN_W; +{$ELSE} + IMPORT_SECURITY_CONTEXT_FN = IMPORT_SECURITY_CONTEXT_FN_A; +{$ENDIF} + {$EXTERNALSYM IMPORT_SECURITY_CONTEXT_FN} + +/////////////////////////////////////////////////////////////////////////////// +//// +//// Fast access for RPC: +//// +/////////////////////////////////////////////////////////////////////////////// + +const + + SECURITY_ENTRYPOINT_ANSIW = 'InitSecurityInterfaceW'; {Do not Localize} + {$EXTERNALSYM SECURITY_ENTRYPOINT_ANSIW} + SECURITY_ENTRYPOINT_ANSIA = 'InitSecurityInterfaceA'; {Do not Localize} + {$EXTERNALSYM SECURITY_ENTRYPOINT_ANSIA} + SECURITY_ENTRYPOINTW = 'InitSecurityInterfaceW'; {Do not Localize} + {$EXTERNALSYM SECURITY_ENTRYPOINTW} + SECURITY_ENTRYPOINTA = 'InitSecurityInterfaceA'; {Do not Localize} + {$EXTERNALSYM SECURITY_ENTRYPOINTA} + SECURITY_ENTRYPOINT16 = 'INITSECURITYINTERFACEA'; {Do not Localize} + {$EXTERNALSYM SECURITY_ENTRYPOINT16} + +{$IFDEF SSPI_UNICODE} + SECURITY_ENTRYPOINT = SECURITY_ENTRYPOINTW; + SECURITY_ENTRYPOINT_ANSI = SECURITY_ENTRYPOINTW; +{$ELSE} + SECURITY_ENTRYPOINT = SECURITY_ENTRYPOINTA; + SECURITY_ENTRYPOINT_ANSI = SECURITY_ENTRYPOINTA; +{$ENDIF} + {$EXTERNALSYM SECURITY_ENTRYPOINT} + {$EXTERNALSYM SECURITY_ENTRYPOINT_ANSI} + +type + + PSecurityFunctionTableW = ^SecurityFunctionTableW; + {$EXTERNALSYM PSecurityFunctionTableW} + SecurityFunctionTableW = record + dwVersion: ULONG; + EnumerateSecurityPackagesW: ENUMERATE_SECURITY_PACKAGES_FN_W; + QueryCredentialsAttributesW: QUERY_CREDENTIALS_ATTRIBUTES_FN_W; + AcquireCredentialsHandleW: ACQUIRE_CREDENTIALS_HANDLE_FN_W; + FreeCredentialsHandle: FREE_CREDENTIALS_HANDLE_FN; + Reserved2: PVOID; + InitializeSecurityContextW: INITIALIZE_SECURITY_CONTEXT_FN_W; + AcceptSecurityContext: ACCEPT_SECURITY_CONTEXT_FN; + CompleteAuthToken: COMPLETE_AUTH_TOKEN_FN; + DeleteSecurityContext: DELETE_SECURITY_CONTEXT_FN; + ApplyControlToken: APPLY_CONTROL_TOKEN_FN; + QueryContextAttributesW: QUERY_CONTEXT_ATTRIBUTES_FN_W; + ImpersonateSecurityContext: IMPERSONATE_SECURITY_CONTEXT_FN; + RevertSecurityContext: REVERT_SECURITY_CONTEXT_FN; + MakeSignature: MAKE_SIGNATURE_FN; + VerifySignature: VERIFY_SIGNATURE_FN; + FreeContextBuffer: FREE_CONTEXT_BUFFER_FN; + QuerySecurityPackageInfoW: QUERY_SECURITY_PACKAGE_INFO_FN_W; + Reserved3: PVOID; + Reserved4: PVOID; + ExportSecurityContext: EXPORT_SECURITY_CONTEXT_FN; + ImportSecurityContextW: IMPORT_SECURITY_CONTEXT_FN_W; + AddCredentialsW: ADD_CREDENTIALS_FN_W; + Reserved8: PVOID; + QuerySecurityContextToken: QUERY_SECURITY_CONTEXT_TOKEN_FN; + EncryptMessage: ENCRYPT_MESSAGE_FN; + DecryptMessage: DECRYPT_MESSAGE_FN; + // Fields below this are available in OSes after w2k + SetContextAttributesW: SET_CONTEXT_ATTRIBUTES_FN_W; + // Fields below this are available in OSes after W2k3SP1 + SetCredentialsAttributesW: SET_CREDENTIALS_ATTRIBUTES_FN_W; + ChangeAccountPasswordW: CHANGE_PASSWORD_FN_W; + end; + {$EXTERNALSYM SecurityFunctionTableW} + + PSecurityFunctionTableA = ^SecurityFunctionTableA; + {$EXTERNALSYM PSecurityFunctionTableA} + SecurityFunctionTableA = record + dwVersion: ULONG; + EnumerateSecurityPackagesA: ENUMERATE_SECURITY_PACKAGES_FN_A; + QueryCredentialsAttributesA: QUERY_CREDENTIALS_ATTRIBUTES_FN_A; + AcquireCredentialsHandleA: ACQUIRE_CREDENTIALS_HANDLE_FN_A; + FreeCredentialsHandle: FREE_CREDENTIALS_HANDLE_FN; + Reserved2: PVOID; + InitializeSecurityContextA: INITIALIZE_SECURITY_CONTEXT_FN_A; + AcceptSecurityContext: ACCEPT_SECURITY_CONTEXT_FN; + CompleteAuthToken: COMPLETE_AUTH_TOKEN_FN; + DeleteSecurityContext: DELETE_SECURITY_CONTEXT_FN; + ApplyControlToken: APPLY_CONTROL_TOKEN_FN; + QueryContextAttributesA: QUERY_CONTEXT_ATTRIBUTES_FN_A; + ImpersonateSecurityContext: IMPERSONATE_SECURITY_CONTEXT_FN; + RevertSecurityContext: REVERT_SECURITY_CONTEXT_FN; + MakeSignature: MAKE_SIGNATURE_FN; + VerifySignature: VERIFY_SIGNATURE_FN; + FreeContextBuffer: FREE_CONTEXT_BUFFER_FN; + QuerySecurityPackageInfoA: QUERY_SECURITY_PACKAGE_INFO_FN_A; + Reserved3: PVOID; + Reserved4: PVOID; + ExportSecurityContext: EXPORT_SECURITY_CONTEXT_FN; + ImportSecurityContextA: IMPORT_SECURITY_CONTEXT_FN_A; + AddCredentialsA: ADD_CREDENTIALS_FN_A; + Reserved8: PVOID; + QuerySecurityContextToken: QUERY_SECURITY_CONTEXT_TOKEN_FN; + EncryptMessage: ENCRYPT_MESSAGE_FN; + DecryptMessage: DECRYPT_MESSAGE_FN; + SetContextAttributesA: SET_CONTEXT_ATTRIBUTES_FN_A; + SetCredentialsAttributesA: SET_CREDENTIALS_ATTRIBUTES_FN_A; + ChangeAccountPasswordA: CHANGE_PASSWORD_FN_A; + end; + {$EXTERNALSYM SecurityFunctionTableA} + +{$IFDEF SSPI_UNICODE} + SecurityFunctionTable = SecurityFunctionTableW; + PSecurityFunctionTable = PSecurityFunctionTableW; +{$ELSE} + SecurityFunctionTable = SecurityFunctionTableA; + PSecurityFunctionTable = PSecurityFunctionTableA; +{$ENDIF} + {$EXTERNALSYM SecurityFunctionTable} + {$EXTERNALSYM PSecurityFunctionTable} + +const + + // Function table has all routines through DecryptMessage + SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION = 1; + {$EXTERNALSYM SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION} + + // Function table has all routines through SetContextAttributes + SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_2 = 2; + {$EXTERNALSYM SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_2} + + // Function table has all routines through SetCredentialsAttributes + SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_3 = 3; + {$EXTERNALSYM SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_3} + + // Function table has all routines through ChangeAccountPassword + SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_4 = 4; + {$EXTERNALSYM SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_4} + +type + + INIT_SECURITY_INTERFACE_A = function // InitSecurityInterfaceA + : PSecurityFunctionTableA; stdcall; + {$EXTERNALSYM INIT_SECURITY_INTERFACE_A} + + INIT_SECURITY_INTERFACE_W = function // InitSecurityInterfaceW + : PSecurityFunctionTableW; stdcall; + {$EXTERNALSYM INIT_SECURITY_INTERFACE_W} + +{$IFDEF SSPI_UNICODE} + INIT_SECURITY_INTERFACE = INIT_SECURITY_INTERFACE_W; +{$ELSE} + INIT_SECURITY_INTERFACE = INIT_SECURITY_INTERFACE_A; +{$ENDIF} + {$EXTERNALSYM INIT_SECURITY_INTERFACE} + + +(* TODO + +// +// SASL Profile Support +// + + +SECURITY_STATUS +SEC_ENTRY +SaslEnumerateProfilesA( + OUT LPSTR * ProfileList, + OUT ULONG * ProfileCount + ); + +SECURITY_STATUS +SEC_ENTRY +SaslEnumerateProfilesW( + OUT LPWSTR * ProfileList, + OUT ULONG * ProfileCount + ); + +#ifdef UNICODE +#define SaslEnumerateProfiles SaslEnumerateProfilesW +#else +#define SaslEnumerateProfiles SaslEnumerateProfilesA +#endif + + +SECURITY_STATUS +SEC_ENTRY +SaslGetProfilePackageA( + IN LPSTR ProfileName, + OUT PSecPkgInfoA * PackageInfo + ); + + +SECURITY_STATUS +SEC_ENTRY +SaslGetProfilePackageW( + IN LPWSTR ProfileName, + OUT PSecPkgInfoW * PackageInfo + ); + +#ifdef UNICODE +#define SaslGetProfilePackage SaslGetProfilePackageW +#else +#define SaslGetProfilePackage SaslGetProfilePackageA +#endif + +SECURITY_STATUS +SEC_ENTRY +SaslIdentifyPackageA( + IN PSecBufferDesc pInput, + OUT PSecPkgInfoA * PackageInfo + ); + +SECURITY_STATUS +SEC_ENTRY +SaslIdentifyPackageW( + IN PSecBufferDesc pInput, + OUT PSecPkgInfoW * PackageInfo + ); + +#ifdef UNICODE +#define SaslIdentifyPackage SaslIdentifyPackageW +#else +#define SaslIdentifyPackage SaslIdentifyPackageA +#endif + +SECURITY_STATUS +SEC_ENTRY +SaslInitializeSecurityContextW( + PCredHandle phCredential, // Cred to base context + PCtxtHandle phContext, // Existing context (OPT) + LPWSTR pszTargetName, // Name of target + unsigned long fContextReq, // Context Requirements + unsigned long Reserved1, // Reserved, MBZ + unsigned long TargetDataRep, // Data rep of target + PSecBufferDesc pInput, // Input Buffers + unsigned long Reserved2, // Reserved, MBZ + PCtxtHandle phNewContext, // (out) New Context handle + PSecBufferDesc pOutput, // (inout) Output Buffers + unsigned long SEC_FAR * pfContextAttr, // (out) Context attrs + PTimeStamp ptsExpiry // (out) Life span (OPT) + ); + +SECURITY_STATUS +SEC_ENTRY +SaslInitializeSecurityContextA( + PCredHandle phCredential, // Cred to base context + PCtxtHandle phContext, // Existing context (OPT) + LPSTR pszTargetName, // Name of target + unsigned long fContextReq, // Context Requirements + unsigned long Reserved1, // Reserved, MBZ + unsigned long TargetDataRep, // Data rep of target + PSecBufferDesc pInput, // Input Buffers + unsigned long Reserved2, // Reserved, MBZ + PCtxtHandle phNewContext, // (out) New Context handle + PSecBufferDesc pOutput, // (inout) Output Buffers + unsigned long SEC_FAR * pfContextAttr, // (out) Context attrs + PTimeStamp ptsExpiry // (out) Life span (OPT) + ); + +#ifdef UNICODE +#define SaslInitializeSecurityContext SaslInitializeSecurityContextW +#else +#define SaslInitializeSecurityContext SaslInitializeSecurityContextA +#endif + + +SECURITY_STATUS +SEC_ENTRY +SaslAcceptSecurityContext( + PCredHandle phCredential, // Cred to base context + PCtxtHandle phContext, // Existing context (OPT) + PSecBufferDesc pInput, // Input buffer + unsigned long fContextReq, // Context Requirements + unsigned long TargetDataRep, // Target Data Rep + PCtxtHandle phNewContext, // (out) New context handle + PSecBufferDesc pOutput, // (inout) Output buffers + unsigned long SEC_FAR * pfContextAttr, // (out) Context attributes + PTimeStamp ptsExpiry // (out) Life span (OPT) + ); + +#define SASL_OPTION_SEND_SIZE 1 // Maximum size to send to peer +#define SASL_OPTION_RECV_SIZE 2 // Maximum size willing to receive +#define SASL_OPTION_AUTHZ_STRING 3 // Authorization string +#define SASL_OPTION_AUTHZ_PROCESSING 4 // Authorization string processing + +typedef enum _SASL_AUTHZID_STATE { + Sasl_AuthZIDForbidden, // allow no AuthZID strings to be specified - error out (default) + Sasl_AuthZIDProcessed // AuthZID Strings processed by Application or SSP +} SASL_AUTHZID_STATE ; + +SECURITY_STATUS +SEC_ENTRY +SaslSetContextOption( + __in PCtxtHandle ContextHandle, + __in ULONG Option, + __in PVOID Value, + __in ULONG Size + ); + + +SECURITY_STATUS +SEC_ENTRY +SaslGetContextOption( + __in PCtxtHandle ContextHandle, + __in ULONG Option, + __out PVOID Value, + __in ULONG Size, + __out_opt PULONG Needed OPTIONAL + ); + +*) + +// +// This is the legacy credentials structure. +// The EX version below is preferred. + +const + + SEC_WINNT_AUTH_IDENTITY_VERSION_2 = $201; + {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_VERSION_2} + +type + + PSEC_WINNT_AUTH_IDENTITY_EX2 = ^SEC_WINNT_AUTH_IDENTITY_EX2; + {$EXTERNALSYM PSEC_WINNT_AUTH_IDENTITY_EX2} + SEC_WINNT_AUTH_IDENTITY_EX2 = record + Version: ULONG; // contains SEC_WINNT_AUTH_IDENTITY_VERSION_2 + cbHeaderLength: USHORT; + cbStructureLength: ULONG; + UserOffset: ULONG; // Non-NULL terminated string, unicode only + UserLength: USHORT; // # of bytes (NOT WCHARs), not including NULL. + DomainOffset: ULONG; // Non-NULL terminated string, unicode only + DomainLength: USHORT; // # of bytes (NOT WCHARs), not including NULL. + PackedCredentialsOffset: ULONG; // Non-NULL terminated string, unicode only + PackedCredentialsLength: USHORT; // # of bytes (NOT WCHARs), not including NULL. + Flags: ULONG; + PackageListOffset: ULONG; // Non-NULL terminated string, unicode only + PackageListLength: USHORT; + end; + {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_EX2} + +// +// This was not defined in NTIFS.h for windows 2000 however +// this struct has always been there and are safe to use +// in windows 2000 and above. +// + +const + + SEC_WINNT_AUTH_IDENTITY_ANSI = $1; + {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_ANSI} + SEC_WINNT_AUTH_IDENTITY_UNICODE = $2; + {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_UNICODE} + +type + + PSEC_WINNT_AUTH_IDENTITY_W = ^SEC_WINNT_AUTH_IDENTITY_W; + {$EXTERNALSYM PSEC_WINNT_AUTH_IDENTITY_W} + SEC_WINNT_AUTH_IDENTITY_W = record + User: PUSHORT; // Non-NULL terminated string. + UserLength: ULONG; // # of characters (NOT bytes), not including NULL. + Domain: PUSHORT; // Non-NULL terminated string. + DomainLength: ULONG; // # of characters (NOT bytes), not including NULL. + Password: PUSHORT; // Non-NULL terminated string. + PasswordLength: ULONG; // # of characters (NOT bytes), not including NULL. + Flags: ULONG; + end; + {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_W} + + PSEC_WINNT_AUTH_IDENTITY_A = ^SEC_WINNT_AUTH_IDENTITY_A; + {$EXTERNALSYM PSEC_WINNT_AUTH_IDENTITY_A} + SEC_WINNT_AUTH_IDENTITY_A = record + User: PUCHAR; // Non-NULL terminated string. + UserLength: ULONG; // # of characters (NOT bytes), not including NULL. + Domain: PUCHAR; // Non-NULL terminated string. + DomainLength: ULONG; // # of characters (NOT bytes), not including NULL. + Password: PUCHAR; // Non-NULL terminated string. + PasswordLength: ULONG; // # of characters (NOT bytes), not including NULL. + Flags: ULONG; + end; + {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_A} + +{$IFDEF SSPI_UNICODE} + SEC_WINNT_AUTH_IDENTITY = SEC_WINNT_AUTH_IDENTITY_W; + PSEC_WINNT_AUTH_IDENTITY = PSEC_WINNT_AUTH_IDENTITY_W; +{$ELSE} + SEC_WINNT_AUTH_IDENTITY = SEC_WINNT_AUTH_IDENTITY_A; + PSEC_WINNT_AUTH_IDENTITY = PSEC_WINNT_AUTH_IDENTITY_A; +{$ENDIF} + {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY} + {$EXTERNALSYM PSEC_WINNT_AUTH_IDENTITY} + +// +// This is the combined authentication identity structure that may be +// used with the negotiate package, NTLM, Kerberos, or SCHANNEL +// + +const + + SEC_WINNT_AUTH_IDENTITY_VERSION = $200; + {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_VERSION} + +type + + PSEC_WINNT_AUTH_IDENTITY_EXW = ^SEC_WINNT_AUTH_IDENTITY_EXW; + {$EXTERNALSYM PSEC_WINNT_AUTH_IDENTITY_EXW} + SEC_WINNT_AUTH_IDENTITY_EXW = record + Version: ULONG; + Length: ULONG; + User: PUSHORT; + UserLength: ULONG; + Domain: PUSHORT; + DomainLength: ULONG; + Password: PUSHORT; + PasswordLength: ULONG; + Flags: ULONG; + PackageList: PUSHORT; + PackageListLength: ULONG; + end; + {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_EXW} + + PSEC_WINNT_AUTH_IDENTITY_EXA = ^SEC_WINNT_AUTH_IDENTITY_EXA; + {$EXTERNALSYM PSEC_WINNT_AUTH_IDENTITY_EXA} + SEC_WINNT_AUTH_IDENTITY_EXA = record + Version: ULONG; + Length: ULONG; + User: PUCHAR; + UserLength: ULONG; + Domain: PUCHAR; + DomainLength: ULONG; + Password: PUCHAR; + PasswordLength: ULONG; + Flags: ULONG; + PackageList: PUCHAR; + PackageListLength: ULONG; + end; + {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_EXA} + +{$IFDEF SSPI_UNICODE} + SEC_WINNT_AUTH_IDENTITY_EX = SEC_WINNT_AUTH_IDENTITY_EXW; +{$ELSE} + SEC_WINNT_AUTH_IDENTITY_EX = SEC_WINNT_AUTH_IDENTITY_EXA; +{$ENDIF} + {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_EX} + +(* TODO + +// +// the procedure for how to parse a SEC_WINNT_AUTH_IDENTITY_INFO structure: +// +// 1) First check the first DWORD of SEC_WINNT_AUTH_IDENTITY_INFO, if the first +// DWORD is 0x200, it is either an AuthIdExw or AuthIdExA, otherwise if the first +// DWORD is 0x201, the structure is an AuthIdEx2 structure. Otherwise the structure +// is either an AuthId_a or an AuthId_w. +// +// 2) Secondly check the flags for SEC_WINNT_AUTH_IDENTITY_ANSI or +// SEC_WINNT_AUTH_IDENTITY_UNICODE, the presence of the former means the structure +// is an ANSI structure. Otherwise, the structure is the wide version. Note that +// AuthIdEx2 does not have an ANSI version so this check does not apply to it. +// + +typedef union _SEC_WINNT_AUTH_IDENTITY_INFO { + SEC_WINNT_AUTH_IDENTITY_EXW AuthIdExw; + SEC_WINNT_AUTH_IDENTITY_EXA AuthIdExa; + SEC_WINNT_AUTH_IDENTITY_A AuthId_a; + SEC_WINNT_AUTH_IDENTITY_W AuthId_w; + SEC_WINNT_AUTH_IDENTITY_EX2 AuthIdEx2; +} SEC_WINNT_AUTH_IDENTITY_INFO, *PSEC_WINNT_AUTH_IDENTITY_INFO; + +// the credential structure is encrypted via +// RtlEncryptMemory(OptionFlags = 0) +#define SEC_WINNT_AUTH_IDENTITY_FLAGS_PROCESS_ENCRYPTED 0x10 + +// the credential structure is protected by local system via +// RtlEncryptMemory(OptionFlags = +// IOCTL_KSEC_ENCRYPT_MEMORY_SAME_LOGON) +#define SEC_WINNT_AUTH_IDENTITY_FLAGS_SYSTEM_PROTECTED 0x20 + +#define SEC_WINNT_AUTH_IDENTITY_FLAGS_RESERVED 0x10000 +#define SEC_WINNT_AUTH_IDENTITY_FLAGS_NULL_USER 0x20000 +#define SEC_WINNT_AUTH_IDENTITY_FLAGS_NULL_DOMAIN 0x40000 + +// +// These bits are for communication between SspiPromptForCredentials() +// and the credential providers. Do not use these bits for any other +// purpose. +// + +#define SEC_WINNT_AUTH_IDENTITY_FLAGS_SSPIPFC_USE_MASK 0xFF000000 + +// +// Instructs the credential provider to not save credentials itself +// when caller selects the "Remember my credential" checkbox. +// + +#define SEC_WINNT_AUTH_IDENTITY_FLAGS_SSPIPFC_SAVE_CRED_BY_CALLER 0x80000000 + +// +// State of the "Remember my credentials" checkbox. +// When set, indicates checked; when cleared, indicates unchecked. +// + +#define SEC_WINNT_AUTH_IDENTITY_FLAGS_SSPIPFC_SAVE_CRED_CHECKED 0x40000000 + +#define SEC_WINNT_AUTH_IDENTITY_FLAGS_VALID_SSPIPFC_FLAGS \ + (SEC_WINNT_AUTH_IDENTITY_FLAGS_SSPIPFC_SAVE_CRED_BY_CALLER | \ + SEC_WINNT_AUTH_IDENTITY_FLAGS_SSPIPFC_SAVE_CRED_CHECKED) + + +#endif // _AUTH_IDENTITY_INFO_DEFINED + +#ifndef _SSPIPFC_NONE_ // the public view + +// begin_ntifs + +typedef PVOID PSEC_WINNT_AUTH_IDENTITY_OPAQUE; // the credential structure is opaque + +// end_ntifs + +#else // the internal view + +typedef PSEC_WINNT_AUTH_IDENTITY_INFO PSEC_WINNT_AUTH_IDENTITY_OPAQUE; + +#endif // _SSPIPFC_NONE_ + +// +// dwFlags parameter of SspiPromptForCredentials(): +// + +// +// Indicates that the credentials should not be saved if +// the user selects the 'save' (or 'remember my password') +// checkbox in the credential dialog box. The location pointed +// to by the pfSave parameter indicates whether or not the user +// selected the checkbox. +// +// Note that some credential providers won't honour this flag and +// may save the credentials in a persistent manner anyway if the +// user selects the 'save' checbox. +// + +#define SSPIPFC_SAVE_CRED_BY_CALLER 0x00000001 + +#define SSPIPFC_VALID_FLAGS (SSPIPFC_SAVE_CRED_BY_CALLER) + +#ifndef _SSPIPFC_NONE_ // the public view + +// Use SspiFreeAuthIdentity() to free the buffer returned +// in ppAuthIdentity. + +unsigned long +SEC_ENTRY +SspiPromptForCredentialsW( + __in PCWSTR pszTargetName, +#ifdef _CREDUI_INFO_DEFINED + __in_opt PCREDUI_INFOW pUiInfo, +#else + __in_opt PVOID pUiInfo, +#endif // _CREDUI_INFO_DEFINED + __in unsigned long dwAuthError, + __in PCWSTR pszPackage, + __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE pInputAuthIdentity, + __deref_out PSEC_WINNT_AUTH_IDENTITY_OPAQUE* ppAuthIdentity, + __inout_opt int* pfSave, + __in unsigned long dwFlags + ); + +// Use SspiFreeAuthIdentity() to free the buffer returned +// in ppAuthIdentity. + +unsigned long +SEC_ENTRY +SspiPromptForCredentialsA( + __in PCSTR pszTargetName, +#ifdef _CREDUI_INFO_DEFINED + __in_opt PCREDUI_INFOA pUiInfo, +#else + __in_opt PVOID pUiInfo, +#endif // _CREDUI_INFO_DEFINED + __in unsigned long dwAuthError, + __in PCSTR pszPackage, + __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE pInputAuthIdentity, + __deref_out PSEC_WINNT_AUTH_IDENTITY_OPAQUE* ppAuthIdentity, + __inout_opt int* pfSave, + __in unsigned long dwFlags + ); +#endif // _SSPIPFC_NONE_ + +#ifdef UNICODE +#define SspiPromptForCredentials SspiPromptForCredentialsW +#else +#define SspiPromptForCredentials SspiPromptForCredentialsA +#endif + +#ifdef _SEC_WINNT_AUTH_TYPES + +typedef struct _SEC_WINNT_AUTH_BYTE_VECTOR { + unsigned long ByteArrayOffset; // each element is a byte + unsigned short ByteArrayLength; // +} SEC_WINNT_AUTH_BYTE_VECTOR, *PSEC_WINNT_AUTH_BYTE_VECTOR; + +typedef struct _SEC_WINNT_AUTH_DATA { + GUID CredType; + SEC_WINNT_AUTH_BYTE_VECTOR CredData; +} SEC_WINNT_AUTH_DATA, *PSEC_WINNT_AUTH_DATA; + +typedef struct _SEC_WINNT_AUTH_PACKED_CREDENTIALS { + unsigned short cbHeaderLength; // the length of the header + unsigned short cbStructureLength; // pay load length including the header + SEC_WINNT_AUTH_DATA AuthData; +} SEC_WINNT_AUTH_PACKED_CREDENTIALS, *PSEC_WINNT_AUTH_PACKED_CREDENTIALS; + +// {28BFC32F-10F6-4738-98D1-1AC061DF716A} +static const GUID SEC_WINNT_AUTH_DATA_TYPE_PASSWORD = + { 0x28bfc32f, 0x10f6, 0x4738, { 0x98, 0xd1, 0x1a, 0xc0, 0x61, 0xdf, 0x71, 0x6a } }; + +// {235F69AD-73FB-4dbc-8203-0629E739339B} +static const GUID SEC_WINNT_AUTH_DATA_TYPE_CERT = + { 0x235f69ad, 0x73fb, 0x4dbc, { 0x82, 0x3, 0x6, 0x29, 0xe7, 0x39, 0x33, 0x9b } }; + +typedef struct _SEC_WINNT_AUTH_DATA_PASSWORD { + SEC_WINNT_AUTH_BYTE_VECTOR UnicodePassword; +} SEC_WINNT_AUTH_DATA_PASSWORD, PSEC_WINNT_AUTH_DATA_PASSWORD; + +// +// smartcard cred data +// +// {68FD9879-079C-4dfe-8281-578AADC1C100} + +static const GUID SEC_WINNT_AUTH_DATA_TYPE_CSP_DATA = + { 0x68fd9879, 0x79c, 0x4dfe, { 0x82, 0x81, 0x57, 0x8a, 0xad, 0xc1, 0xc1, 0x0 } }; + +typedef struct _SEC_WINNT_AUTH_CERTIFICATE_DATA { + unsigned short cbHeaderLength; + unsigned short cbStructureLength; + SEC_WINNT_AUTH_BYTE_VECTOR Certificate; +} SEC_WINNT_AUTH_CERTIFICATE_DATA, *PSEC_WINNT_AUTH_CERTIFICATE_DATA; + +typedef struct _SEC_WINNT_CREDUI_CONTEXT_VECTOR +{ + ULONG CredUIContextArrayOffset; // offset starts at the beginning of + // this structure, and each element is a SEC_WINNT_AUTH_BYTE_VECTOR that + // describes the flat CredUI context returned by SpGetCredUIContext() + USHORT CredUIContextCount; +} SEC_WINNT_CREDUI_CONTEXT_VECTOR, *PSEC_WINNT_CREDUI_CONTEXT_VECTOR; + +typedef struct _SEC_WINNT_AUTH_SHORT_VECTOR +{ + ULONG ShortArrayOffset; // each element is a short + USHORT ShortArrayCount; // number of characters +} SEC_WINNT_AUTH_SHORT_VECTOR, *PSEC_WINNT_AUTH_SHORT_VECTOR; + +// free the returned memory using SspiLocalFree + +SECURITY_STATUS +SEC_ENTRY +SspiGetCredUIContext( + __in HANDLE ContextHandle, + __in GUID* CredType, + __in_opt LUID* LogonId, // use this LogonId, the caller must be localsystem to supply a logon id + __deref_out PSEC_WINNT_CREDUI_CONTEXT_VECTOR* CredUIContexts, + __out_opt HANDLE* TokenHandle + ); + +SECURITY_STATUS +SEC_ENTRY +SspiUpdateCredentials( + __in HANDLE ContextHandle, + __in GUID* CredType, + __in ULONG FlatCredUIContextLength, + __in_bcount(FlatCredUIContextLength) PUCHAR FlatCredUIContext + ); + +typedef struct _CREDUIWIN_MARSHALED_CONTEXT +{ + GUID StructureType; + USHORT cbHeaderLength; + LUID LogonId; // user's logon id + GUID MarshaledDataType; + ULONG MarshaledDataOffset; + USHORT MarshaledDataLength; +} CREDUIWIN_MARSHALED_CONTEXT, *PCREDUIWIN_MARSHALED_CONTEXT; + +typedef struct _SEC_WINNT_CREDUI_CONTEXT +{ + USHORT cbHeaderLength; + HANDLE CredUIContextHandle; // the handle to call SspiGetCredUIContext() +#ifdef _CREDUI_INFO_DEFINED + PCREDUI_INFOW UIInfo; // input from SspiPromptForCredentials() +#else + PVOID UIInfo; +#endif // _CREDUI_INFO_DEFINED + ULONG dwAuthError; // the authentication error + PSEC_WINNT_AUTH_IDENTITY_OPAQUE pInputAuthIdentity; + PUNICODE_STRING TargetName; +} SEC_WINNT_CREDUI_CONTEXT, *PSEC_WINNT_CREDUI_CONTEXT; + +// {3C3E93D9-D96B-49b5-94A7-458592088337} +static const GUID CREDUIWIN_STRUCTURE_TYPE_SSPIPFC = +{ 0x3c3e93d9, 0xd96b, 0x49b5, { 0x94, 0xa7, 0x45, 0x85, 0x92, 0x8, 0x83, 0x37 } }; + +// {C2FFFE6F-503D-4c3d-A95E-BCE821213D44} +static const GUID SSPIPFC_STRUCTURE_TYPE_CREDUI_CONTEXT = +{ 0xc2fffe6f, 0x503d, 0x4c3d, { 0xa9, 0x5e, 0xbc, 0xe8, 0x21, 0x21, 0x3d, 0x44 } }; + +typedef struct _SEC_WINNT_AUTH_PACKED_CREDENTIALS_EX { + unsigned short cbHeaderLength; + unsigned long Flags; // contains the Flags field in + // SEC_WINNT_AUTH_IDENTITY_EX + SEC_WINNT_AUTH_BYTE_VECTOR PackedCredentials; + SEC_WINNT_AUTH_SHORT_VECTOR PackageList; +} SEC_WINNT_AUTH_PACKED_CREDENTIALS_EX, *PSEC_WINNT_AUTH_PACKED_CREDENTIALS_EX; + +// +// free the returned memory using SspiLocalFree +// + +SECURITY_STATUS +SEC_ENTRY +SspiUnmarshalCredUIContext( + __in_bcount(MarshaledCredUIContextLength) PUCHAR MarshaledCredUIContext, + __in ULONG MarshaledCredUIContextLength, + __deref_out PSEC_WINNT_CREDUI_CONTEXT* CredUIContext + ); + +#endif // _SEC_WINNT_AUTH_TYPES + +SECURITY_STATUS +SEC_ENTRY +SspiPrepareForCredRead( + __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, + __in PCWSTR pszTargetName, + __out PULONG pCredmanCredentialType, + __deref_out PCWSTR* ppszCredmanTargetName + ); + +SECURITY_STATUS +SEC_ENTRY +SspiPrepareForCredWrite( + __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, + __in_opt PCWSTR pszTargetName, // supply NULL for username-target credentials + __out PULONG pCredmanCredentialType, + __deref_out PCWSTR* ppszCredmanTargetName, + __deref_out PCWSTR* ppszCredmanUserName, + __deref_out_bcount(*pCredentialBlobSize) PUCHAR *ppCredentialBlob, + __out PULONG pCredentialBlobSize + ); + +SECURITY_STATUS +SEC_ENTRY +SspiEncryptAuthIdentity( + __inout PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData + ); + +SECURITY_STATUS +SEC_ENTRY +SspiDecryptAuthIdentity( + __inout PSEC_WINNT_AUTH_IDENTITY_OPAQUE EncryptedAuthData + ); + +BOOLEAN +SEC_ENTRY +SspiIsAuthIdentityEncrypted( + __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE EncryptedAuthData + ); + +// begin_ntifs + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// +// Convert the _OPAQUE structure passed in to the +// 3 tuple . +// +// Note: The 'strings' returned need not necessarily be +// in user recognisable form. The purpose of this API +// is to 'flatten' the _OPAQUE structure into the 3 tuple. +// User recognisable can always be +// obtained by passing NULL to the pszPackedCredentialsString +// parameter. +// +// zero out the pszPackedCredentialsString then +// free the returned memory using SspiLocalFree() +// + +SECURITY_STATUS +SEC_ENTRY +SspiEncodeAuthIdentityAsStrings( + __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE pAuthIdentity, + __deref_out_opt PCWSTR* ppszUserName, + __deref_out_opt PCWSTR* ppszDomainName, + __deref_opt_out_opt PCWSTR* ppszPackedCredentialsString + ); + +SECURITY_STATUS +SEC_ENTRY +SspiValidateAuthIdentity( + __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData + ); + +// +// free the returned memory using SspiFreeAuthIdentity() +// + +SECURITY_STATUS +SEC_ENTRY +SspiCopyAuthIdentity( + __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData, + __deref_out PSEC_WINNT_AUTH_IDENTITY_OPAQUE* AuthDataCopy + ); + +// +// use only for the memory returned by SspiCopyAuthIdentity(). +// Internally calls SspiZeroAuthIdentity(). +// + +VOID +SEC_ENTRY +SspiFreeAuthIdentity( + __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData + ); + +VOID +SEC_ENTRY +SspiZeroAuthIdentity( + __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthData + ); + +VOID +SEC_ENTRY +SspiLocalFree( + __in_opt PVOID DataBuffer + ); + +// +// call SspiFreeAuthIdentity to free the returned AuthIdentity +// which zeroes out the credentials blob before freeing it +// + +SECURITY_STATUS +SEC_ENTRY +SspiEncodeStringsAsAuthIdentity( + __in_opt PCWSTR pszUserName, + __in_opt PCWSTR pszDomainName, + __in_opt PCWSTR pszPackedCredentialsString, + __deref_out PSEC_WINNT_AUTH_IDENTITY_OPAQUE* ppAuthIdentity + ); + +SECURITY_STATUS +SEC_ENTRY +SspiCompareAuthIdentities( + __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity1, + __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity2, + __out_opt PBOOLEAN SameSuppliedUser, + __out_opt PBOOLEAN SameSuppliedIdentity + ); + +// +// zero out the returned AuthIdentityByteArray then +// free the returned memory using SspiLocalFree() +// + +SECURITY_STATUS +SEC_ENTRY +SspiMarshalAuthIdentity( + __in PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, + __out unsigned long* AuthIdentityLength, + __deref_out_bcount(*AuthIdentityLength) char** AuthIdentityByteArray + ); + +// +// free the returned auth identity using SspiFreeAuthIdentity() +// + +SECURITY_STATUS +SEC_ENTRY +SspiUnmarshalAuthIdentity( + __in unsigned long AuthIdentityLength, + __in_bcount(AuthIdentityLength) char* AuthIdentityByteArray, + __deref_out PSEC_WINNT_AUTH_IDENTITY_OPAQUE* ppAuthIdentity + ); + +BOOLEAN +SEC_ENTRY +SspiIsPromptingNeeded( + __in unsigned long ErrorOrNtStatus + ); + +SECURITY_STATUS +SEC_ENTRY +SspiGetTargetHostName( + __in PCWSTR pszTargetName, + __deref_out PWSTR* pszHostName + ); + +SECURITY_STATUS +SEC_ENTRY +SspiExcludePackage( + __in_opt PSEC_WINNT_AUTH_IDENTITY_OPAQUE AuthIdentity, + __in PCWSTR pszPackageName, + __deref_out PSEC_WINNT_AUTH_IDENTITY_OPAQUE* ppNewAuthIdentity + ); + +*) + +// +// Common types used by negotiable security packages +// + +const + + SEC_WINNT_AUTH_IDENTITY_MARSHALLED = $4; // all data is in one buffer + {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_MARSHALLED} + SEC_WINNT_AUTH_IDENTITY_ONLY = $8; // these credentials are for identity only - no PAC needed + {$EXTERNALSYM SEC_WINNT_AUTH_IDENTITY_ONLY} + + +(* TODO + +// +// Routines for manipulating packages +// + +typedef struct _SECURITY_PACKAGE_OPTIONS { + unsigned long Size; + unsigned long Type; + unsigned long Flags; + unsigned long SignatureSize; + void SEC_FAR * Signature; +} SECURITY_PACKAGE_OPTIONS, SEC_FAR * PSECURITY_PACKAGE_OPTIONS; + +#define SECPKG_OPTIONS_TYPE_UNKNOWN 0 +#define SECPKG_OPTIONS_TYPE_LSA 1 +#define SECPKG_OPTIONS_TYPE_SSPI 2 + +#define SECPKG_OPTIONS_PERMANENT 0x00000001 + +SECURITY_STATUS +SEC_ENTRY +AddSecurityPackageA( + SEC_CHAR SEC_FAR * pszPackageName, + SECURITY_PACKAGE_OPTIONS SEC_FAR * Options + ); + +SECURITY_STATUS +SEC_ENTRY +AddSecurityPackageW( + SEC_WCHAR SEC_FAR * pszPackageName, + SECURITY_PACKAGE_OPTIONS SEC_FAR * Options + ); + +#ifdef UNICODE +#define AddSecurityPackage AddSecurityPackageW +#else +#define AddSecurityPackage AddSecurityPackageA +#endif + +SECURITY_STATUS +SEC_ENTRY +DeleteSecurityPackageA( + SEC_CHAR SEC_FAR * pszPackageName ); + +SECURITY_STATUS +SEC_ENTRY +DeleteSecurityPackageW( + SEC_WCHAR SEC_FAR * pszPackageName ); + +#ifdef UNICODE +#define DeleteSecurityPackage DeleteSecurityPackageW +#else +#define DeleteSecurityPackage DeleteSecurityPackageA +#endif + +//+----------------------------------------------------------------------- +// +// Microsoft Windows +// +// Copyright (c) Microsoft Corporation 1991-1999 +// +// File: secext.h +// +// Contents: Security function prototypes for functions not part of +// the SSPI interface. This file should not be directly +// included - include security.h instead. +// +// +// History: 22 Dec 92 RichardW Created +// +//------------------------------------------------------------------------ + +// +// Extended Name APIs for ADS +// + + +typedef enum +{ + // Examples for the following formats assume a fictitous company + // which hooks into the global X.500 and DNS name spaces as follows. + // + // Enterprise root domain in DNS is + // + // widget.com + // + // Enterprise root domain in X.500 (RFC 1779 format) is + // + // O=Widget, C=US + // + // There exists the child domain + // + // engineering.widget.com + // + // equivalent to + // + // OU=Engineering, O=Widget, C=US + // + // There exists a container within the Engineering domain + // + // OU=Software, OU=Engineering, O=Widget, C=US + // + // There exists the user + // + // CN=John Doe, OU=Software, OU=Engineering, O=Widget, C=US + // + // And this user's downlevel (pre-ADS) user name is {Do not Localize} + // + // Engineering\JohnDoe + + // unknown name type + NameUnknown = 0, + + // CN=John Doe, OU=Software, OU=Engineering, O=Widget, C=US + NameFullyQualifiedDN = 1, + + // Engineering\JohnDoe + NameSamCompatible = 2, + + // Probably "John Doe" but could be something else. I.e. The + // display name is not necessarily the defining RDN. + NameDisplay = 3, + + + // String-ized GUID as returned by IIDFromString(). + // eg: {4fa050f0-f561-11cf-bdd9-00aa003a77b6} + NameUniqueId = 6, + + // engineering.widget.com/software/John Doe + NameCanonical = 7, + + // johndoe@engineering.com + NameUserPrincipal = 8, + + // Same as NameCanonical except that rightmost '/' is {Do not Localize} + // replaced with '\n' - even in domain-only case. {Do not Localize} + // eg: engineering.widget.com/software\nJohn Doe + NameCanonicalEx = 9, + + // www/srv.engineering.com/engineering.com + NameServicePrincipal = 10 + +} EXTENDED_NAME_FORMAT, * PEXTENDED_NAME_FORMAT ; + +BOOLEAN +SEC_ENTRY +GetUserNameExA( + EXTENDED_NAME_FORMAT NameFormat, + LPSTR lpNameBuffer, + PULONG nSize + ); +BOOLEAN +SEC_ENTRY +GetUserNameExW( + EXTENDED_NAME_FORMAT NameFormat, + LPWSTR lpNameBuffer, + PULONG nSize + ); + +#ifdef UNICODE +#define GetUserNameEx GetUserNameExW +#else +#define GetUserNameEx GetUserNameExA +#endif + +BOOLEAN +SEC_ENTRY +GetComputerObjectNameA( + EXTENDED_NAME_FORMAT NameFormat, + LPSTR lpNameBuffer, + PULONG nSize + ); +BOOLEAN +SEC_ENTRY +GetComputerObjectNameW( + EXTENDED_NAME_FORMAT NameFormat, + LPWSTR lpNameBuffer, + PULONG nSize + ); + +#ifdef UNICODE +#define GetComputerObjectName GetComputerObjectNameW +#else +#define GetComputerObjectName GetComputerObjectNameA +#endif + +BOOLEAN +SEC_ENTRY +TranslateNameA( + LPCSTR lpAccountName, + EXTENDED_NAME_FORMAT AccountNameFormat, + EXTENDED_NAME_FORMAT DesiredNameFormat, + LPSTR lpTranslatedName, + PULONG nSize + ); +BOOLEAN +SEC_ENTRY +TranslateNameW( + LPCWSTR lpAccountName, + EXTENDED_NAME_FORMAT AccountNameFormat, + EXTENDED_NAME_FORMAT DesiredNameFormat, + LPWSTR lpTranslatedName, + PULONG nSize + ); +#ifdef UNICODE +#define TranslateName TranslateNameW +#else +#define TranslateName TranslateNameA +#endif + +*) + +{$ENDIF} +implementation +{$IFDEF USE_SSPI} + +procedure SecInvalidateHandle(var x: SecHandle); +begin + x.dwLower := PtrUInt(-1); + x.dwUpper := PtrUInt(-1); +end; + +function SecIsValidHandle(x : SecHandle) : Boolean; +begin + // RLebeau: workaround for a bug in D2009. Comparing PtrUInt values does not always work correctly. + // Sometimes it causes "W1023 Comparing signed and unsigned types" warnings, other times it causes + // "F2084 Internal Error: C12079" errors + {$IFDEF VCL_2009} + Result := (Integer(x.dwLower) <> Integer(PtrUInt(-1))) and + (Integer(x.dwUpper) <> Integer(PtrUInt(-1))); + {$ELSE} + Result := (x.dwLower <> PtrUInt(-1)) and (x.dwUpper <> PtrUInt(-1)); + {$ENDIF} +end; + +function SEC_SUCCESS(Status: SECURITY_STATUS): Boolean; +begin + Result := Status >= 0; +end; + +{$ENDIF} + +end. diff --git a/Lib/Protocols/IdSecurity90ASM90.inc b/Lib/Protocols/IdSecurity90ASM90.inc index 3d7d18040..b1f2bbf5c 100644 --- a/Lib/Protocols/IdSecurity90ASM90.inc +++ b/Lib/Protocols/IdSecurity90ASM90.inc @@ -1,12 +1,12 @@ -[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Security Run-Time Package for Borland Developer Studio')] -[assembly: AssemblyConfiguration('')] -[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] -[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyTrademark('')] -[assembly: AssemblyCulture('')] -[assembly: AssemblyTitle('Indy .NET Security Run-Time Package')] -[assembly: AssemblyVersion('10.7.0.*')] -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile('')] -[assembly: AssemblyKeyName('')] +[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Security Run-Time Package for Borland Developer Studio')] +[assembly: AssemblyConfiguration('')] +[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] +[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyTrademark('')] +[assembly: AssemblyCulture('')] +[assembly: AssemblyTitle('Indy .NET Security Run-Time Package')] +[assembly: AssemblyVersion('10.7.0.*')] +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile('')] +[assembly: AssemblyKeyName('')] diff --git a/Lib/Protocols/IdZLib.pas b/Lib/Protocols/IdZLib.pas index 9503ec8a4..2aec503df 100644 --- a/Lib/Protocols/IdZLib.pas +++ b/Lib/Protocols/IdZLib.pas @@ -1,1157 +1,1157 @@ -(* - Enhanced zlib implementation - Gabriel Corneanu - - Base implementation follows the original zlib unit. - - Key features: - Using last zlib library (1.2.3). - Removed all imported functions, which are now in zlibpas. This can be used - standalone (as many other projects that need zlib do). - - The compression stream can create different type of streams: - zlib, gzip and raw deflate (see constructors). - - The decompression stream can read all type of streams (autodetect), - plus that the stream type and gzip info is available for public access. - If the stream is not zlib or gzip, it is assumed raw. An error will - occur during decompressing if the data format is not valid. - - The DecompressStream function is using the InflateBack call together - with direct memory access on the source stream - (if available, which means TStringStream or TCustomMemoryStream descendant). - It should be the fastest decompression routine! - - The CompressStreamEx function is using direct memory access on both - source and destination stream (if available). - It should be faster than CompressStream. - - CompressString or CompressStream can be used to compress a http response - -History: - - Aug 2005: Initial release -*) - -unit IdZLib; - -interface - -{$I IdCompilerDefines.inc} - -uses - SysUtils, - Classes, - {$IFDEF HAS_UNIT_System_ZLib} - {$IFDEF USE_INLINE} - System.ZLib, // here to facilitate inlining - {$ENDIF} - {$ENDIF} - IdCTypes, - IdGlobal, - IdZLibHeaders; - -type - // Abstract ancestor class - TCustomZlibStream = class(TIdBaseStream) - protected - FStrm: TStream; - FStrmPos: Integer; - FOnProgress: TNotifyEvent; - FZRec: TZStreamRec; - FBuffer: array [Word] of TIdAnsiChar; - FNameBuffer: array [0..255] of TIdAnsiChar; - FGZHeader : IdZLibHeaders.gz_header; - FStreamType : TZStreamType; - - procedure Progress; dynamic; - procedure IdSetSize(ASize: Int64); override; - property OnProgress: TNotifyEvent read FOnProgress write FOnProgress; - - public - constructor Create(Strm: TStream); - destructor Destroy; override; - - property GZHeader: gz_header read FGZHeader; - end; - - TCompressionLevel = (clNone, clFastest, clDefault, clMax); - - TCompressionStream = class(TCustomZlibStream) - protected - function GetCompressionRate: Single; - function IdRead(var VBuffer: TIdBytes; AOffset, ACount: Longint): Longint; override; - function IdWrite(const ABuffer: TIdBytes; AOffset, ACount: Longint): Longint; override; - function IdSeek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64; override; - public - constructor CreateEx(CompressionLevel: TCompressionLevel; Dest: TStream; - const StreamType: TZStreamType; - const AName: string = ''; ATime: Integer = 0); - constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream; const AIncludeHeaders : Boolean = True); - constructor CreateGZ(CompressionLevel: TCompressionLevel; Dest: TStream; - const AName: string = ''; ATime: Integer = 0); overload; - destructor Destroy; override; - property CompressionRate: Single read GetCompressionRate; - property OnProgress; - end; - - TDecompressionStream = class(TCustomZlibStream) - protected - FInitialPos : Int64; - function IdRead(var VBuffer: TIdBytes; AOffset, ACount: Longint): Longint; override; - function IdWrite(const ABuffer: TIdBytes; AOffset, ACount: Longint): Longint; override; - function IdSeek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64; override; - public - constructor Create(Source: TStream); - destructor Destroy; override; - procedure InitRead; - function IsGZip: boolean; - property OnProgress; - end; - -{ CompressBuf compresses data, buffer to buffer, in one call. - In: InBuf = ptr to compressed data - InBytes = number of bytes in InBuf - Out: OutBuf = ptr to newly allocated buffer containing decompressed data - OutBytes = number of bytes in OutBuf } -procedure CompressBuf(const InBuf: Pointer; InBytes: Integer; - out OutBuf: Pointer; out OutBytes: TIdC_UINT); - -//generic read header from a buffer -function GetStreamType(InBuffer: Pointer; InCount: TIdC_UINT; gzheader: gz_headerp; out HeaderSize: TIdC_UINT): TZStreamType; overload; - -//generic read header from a stream -//the stream position is preserved -function GetStreamType(InStream: TStream; gzheader: gz_headerp; out HeaderSize: TIdC_UINT): TZStreamType; overload; - -//Note that unlike other things in this unit, you specify things with number -//values. This is deliberate on my part because some things in Indy rely on -//API's where you specify the ZLib parameter as a number. This is for the -//utmost flexibility. In the FTP server, you can actually specify something -//like a compression level. -//The WinBits parameter is extremely powerful so do not underestimate it. -procedure IndyCompressStream(InStream, OutStream: TStream; - const level: Integer = Z_DEFAULT_COMPRESSION; - const WinBits : Integer = MAX_WBITS; - const MemLevel : Integer = MAX_MEM_LEVEL; - const Stratagy : Integer = Z_DEFAULT_STRATEGY); -//compress stream; tries to use direct memory access on input stream -procedure CompressStream(InStream, OutStream: TStream; level: TCompressionLevel; StreamType : TZStreamType); -//compress stream; tries to use direct memory access on both streams -procedure CompressStreamEx(InStream, OutStream: TStream; level: TCompressionLevel; StreamType : TZStreamType); -//compress a string -function CompressString(const InString: string; level: TCompressionLevel; StreamType : TZStreamType): string; - -//this is for where we know what the stream's WindowBits setting should be -//Note that this does have special handling for ZLIB values greater than -//32. I'm trying to treat it as the inflateInit2_ call would. I don't think -//InflateBack uses values greater than 16 so you have to make a workaround. -procedure IndyDecompressStream(InStream, OutStream: TStream; - const AWindowBits : Integer); -//fast decompress stream! -//using direct memory access to source stream (if available) and -//direct write (using inflateBack) -procedure DecompressStream(InStream, OutStream: TStream); - -{ DecompressBuf decompresses data, buffer to buffer, in one call. - In: InBuf = ptr to compressed data - InBytes = number of bytes in InBuf - OutEstimate = zero, or est. size of the decompressed data - Out: OutBuf = ptr to newly allocated buffer containing decompressed data - OutBytes = number of bytes in OutBuf } -procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; - OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); - -{ DecompressToUserBuf decompresses data, buffer to buffer, in one call. - In: InBuf = ptr to compressed data - InBytes = number of bytes in InBuf - Out: OutBuf = ptr to user-allocated buffer to contain decompressed data - BufSize = number of bytes in OutBuf } -procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; - const OutBuf: Pointer; BufSize: Integer); - -type - EZlibError = class(Exception) - {JPM Additions, we need to be able to provide diagnostic info in an exception} - protected - FErrorCode : Integer; - public - class procedure RaiseException(const AError: Integer); - // - property ErrorCode : Integer read FErrorCode; - end; - ECompressionError = class(EZlibError); - EDecompressionError = class(EZlibError); - -//ZLib error functions. They raise an exception for ZLib codes less than zero -function DCheck(code: Integer): Integer; -function CCheck(code: Integer): Integer; - -const - //winbit constants - MAX_WBITS = IdZLibHeaders.MAX_WBITS; - {$EXTERNALSYM MAX_WBITS} - GZIP_WINBITS = MAX_WBITS + 16; //GZip format - {$EXTERNALSYM GZIP_WINBITS} - //negative values mean do not add any headers - //adapted from "Enhanced zlib implementation" - //by Gabriel Corneanu - RAW_WBITS = -MAX_WBITS; //raw stream (without any header) - {$EXTERNALSYM RAW_WBITS} - -implementation - -uses - IdGlobalProtocols, IdStream, IdZLibConst - {$IFDEF HAS_AnsiStrings_StrPLCopy} - , AnsiStrings - {$ENDIF} - ; - -const - Levels: array [TCompressionLevel] of Int8 = - (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION); - -function CCheck(code: Integer): Integer; -{$IFDEF USE_INLINE} inline; {$ENDIF} -begin - Result := code; - if code < 0 then begin - ECompressionError.RaiseException(code); - end; -end; - -function DCheck(code: Integer): Integer; -{$IFDEF USE_INLINE} inline; {$ENDIF} -begin - Result := code; - if code < 0 then begin - EDecompressionError.RaiseException(code); - end; -end; - -procedure CompressBuf(const InBuf: Pointer; InBytes: Integer; - out OutBuf: Pointer; out OutBytes: TIdC_UINT); -var - strm: z_stream; - P: Pointer; -begin - FillChar(strm, sizeof(strm), 0); - OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255; - GetMem(OutBuf, OutBytes); - try - strm.next_in := InBuf; - strm.avail_in := InBytes; - strm.next_out := OutBuf; - strm.avail_out := OutBytes; - CCheck(deflateInit(strm, Z_BEST_COMPRESSION)); - try - while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do - begin - P := OutBuf; - Inc(OutBytes, 256); - ReallocMem(OutBuf, OutBytes); - strm.next_out := PByte(PtrUInt(OutBuf) + (PtrUInt(strm.next_out) - PtrUInt(P))); - strm.avail_out := 256; - end; - finally - CCheck(deflateEnd(strm)); - end; - ReallocMem(OutBuf, strm.total_out); - OutBytes := strm.total_out; - except - FreeMem(OutBuf); - raise; - end; -end; - -function DMAOfStream(AStream: TStream; out Available: TIdC_UINT): Pointer; -{$IFDEF USE_INLINE} inline; {$ENDIF} -begin - if AStream is TCustomMemoryStream then begin - Result := TCustomMemoryStream(AStream).Memory; - end - {$IFDEF STRING_IS_ANSI} - // In D2009, the DataString property was changed to use a getter method - // that returns a temporary string, so it is not a direct access to the - // stream contents anymore. TStringStream was updated to derive from - // TBytesStream now, which is a TCustomMemoryStream descendant, and so - // will be handled above... - else if AStream is TStringStream then begin - Result := Pointer(TStringStream(AStream).DataString); - end - {$ENDIF} - else begin - Result := nil; - end; - if Result <> nil then - begin - //handle integer overflow - {$IFDEF STREAM_SIZE_64} - Available := TIdC_UINT(IndyMin(AStream.Size - AStream.Position, High(TIdC_UINT))); - // TODO: account for a 64-bit position in a 32-bit environment - Inc(PtrUInt(Result), AStream.Position); - {$ELSE} - Available := AStream.Size - AStream.Position; - Inc(PtrUInt(Result), AStream.Position); - {$ENDIF} - end else begin - Available := 0; - end; -end; - -function CanResizeDMAStream(AStream: TStream): boolean; -{$IFDEF USE_INLINE} inline; {$ENDIF} -begin - Result := (AStream is TCustomMemoryStream) - {$IFDEF STRING_IS_ANSI} - // In D2009, TStringStream was updated to derive from TBytesStream now, - // which is a TCustomMemoryStream descendant, and so will be handled above... - or (AStream is TStringStream) - {$ENDIF} - ; -end; - -///tries to get the stream info -//strm.next_in and available_in needs enough data! -//strm should not contain an initialized inflate - -function TryStreamType(var strm: TZStreamRec; gzheader: PgzHeaderRec; const AWinBitsValue : Integer): boolean; -var - InitBuf: PByte; - InitIn : TIdC_UINT; -begin - InitBuf := strm.next_in; - InitIn := strm.avail_in; - DCheck(inflateInit2(strm, AWinBitsValue)); - - if (AWinBitsValue = GZIP_WINBITS) and (gzheader <> nil) then begin - DCheck(inflateGetHeader(strm, gzheader^)); - end; - - Result := inflate(strm, Z_BLOCK) = Z_OK; - DCheck(inflateEnd(strm)); - - if Result then begin - Exit; - end; - - //rollback - strm.next_in := InitBuf; - strm.avail_in := InitIn; -end; - -//tries to get the stream info -//strm.next_in and available_in needs enough data! -//strm should not contain an initialized inflate -function CheckInitInflateStream(var strm: TZStreamRec; gzheader: gz_headerp): TZStreamType; overload; -var - InitBuf: PByte; - InitIn: Integer; - - function LocalTryStreamType(AStreamType: TZStreamType): Boolean; - begin - DCheck(inflateInitEx(strm, AStreamType)); - - if (AStreamType = zsGZip) and (gzheader <> nil) then begin - DCheck(inflateGetHeader(strm, gzheader^)); - end; - - Result := inflate(strm, Z_BLOCK) = Z_OK; - DCheck(inflateEnd(strm)); - - if Result then begin - Exit; - end; - - //rollback - strm.next_in := InitBuf; - strm.avail_in := InitIn; - end; - -begin - if strm.next_out = nil then begin - //needed for reading, but not used - strm.next_out := strm.next_in; - end; - - InitBuf := strm.next_in; - InitIn := strm.avail_in; - - for Result := zsZLib to zsGZip do - begin - if LocalTryStreamType(Result) then begin - Exit; - end; - end; - - Result := zsRaw; -end; - -function GetStreamType(InBuffer: Pointer; InCount: TIdC_UINT; gzheader: gz_headerp; - out HeaderSize: TIdC_UINT): TZStreamType; -var - strm : TZStreamRec; -begin - FillChar(strm, SizeOf(strm), 0); - strm.next_in := InBuffer; - strm.avail_in := InCount; - Result := CheckInitInflateStream(strm, gzheader); - HeaderSize := InCount - strm.avail_in; -end; - -function GetStreamType(InStream: TStream; gzheader: gz_headerp; - out HeaderSize: TIdC_UINT): TZStreamType; -const - StepSize = 20; //one step be enough, but who knows... -var - N : TIdC_UINT; - Buff : PIdAnsiChar; - UseBuffer: Boolean; -begin - Buff := DMAOfStream(InStream, N); - UseBuffer := Buff = nil; - if UseBuffer then begin - GetMem(Buff, StepSize); - end; - try - repeat - if UseBuffer then begin - Inc(N, InStream.Read(Buff[N], StepSize)); - end; - Result := GetStreamType(Buff, N, gzheader, HeaderSize); - //do we need more data? - //N mod StepSize <> 0 means no more data available - if (HeaderSize < N) or (not UseBuffer) or ((N mod StepSize) <> 0) then begin - Break; - end; - ReallocMem(Buff, N + StepSize); - until False; - finally - if UseBuffer then - begin - try - TIdStreamHelper.Seek(InStream, -N, soCurrent); - finally - FreeMem(Buff); - end; - end; - end; -end; - -const - WindowSize = 1 shl MAX_WBITS; - -type - PZBack = ^TZBack; - TZBack = record - InStream : TStream; - OutStream : TStream; - InMem : Pointer; //direct memory access - InMemSize : TIdC_UINT; - ReadBuf : array[Word] of Byte; - Window : array[0..WindowSize] of Byte; - end; - -function Strm_in_func(opaque: Pointer; var buf: PByte): TIdC_UNSIGNED; cdecl; -var - S : TStream; - BackObj : PZBack; -begin - BackObj := PZBack( opaque ); - S := BackObj.InStream; //help optimizations - if BackObj.InMem <> nil then - begin - //direct memory access if available! - buf := PByte(BackObj.InMem); - //handle integer overflow - {$IFDEF STREAM_SIZE_64} - Result := TIdC_UNSIGNED(IndyMin(S.Size - S.Position, High(TIdC_UNSIGNED))); - {$ELSE} - Result := S.Size - S.Position; - {$ENDIF} - TIdStreamHelper.Seek(S, Result, soCurrent); - end else - begin - buf := @BackObj.ReadBuf; - Result := S.Read(buf^, SizeOf(BackObj.ReadBuf)); - end; -end; - -function Strm_out_func(opaque: Pointer; buf: PByte; size: TIdC_UNSIGNED): TIdC_INT; cdecl; -begin - Result := TIdC_INT(PZBack(opaque).OutStream.Write(buf^, size) - TIdC_SIGNED(size)); -end; - -procedure DecompressStream(InStream, OutStream: TStream); -var - strm : z_stream; - BackObj: PZBack; -begin - FillChar(strm, sizeof(strm), 0); - GetMem(BackObj, SizeOf(TZBack)); - try - //Darcy - FillChar(BackObj^, sizeof(TZBack), 0); - - //direct memory access if possible! - BackObj.InMem := DMAOfStream(InStream, BackObj.InMemSize); - - BackObj.InStream := InStream; - BackObj.OutStream := OutStream; - - //use our own function for reading - strm.avail_in := Strm_in_func(BackObj, PByte(strm.next_in)); - strm.next_out := @BackObj.Window[0]; - strm.avail_out := 0; - - CheckInitInflateStream(strm, nil); - - strm.next_out := nil; - strm.avail_out := 0; - DCheck(inflateBackInit(strm, MAX_WBITS, @BackObj.Window[0])); - try - DCheck(inflateBack(strm, Strm_in_func, BackObj, Strm_out_func, BackObj)); - // DCheck(inflateBack(strm, @Strm_in_func, BackObj, @Strm_out_func, BackObj)); - //seek back when unused data - TIdStreamHelper.Seek(InStream, -strm.avail_in, soCurrent); - //now trailer can be checked - finally - DCheck(inflateBackEnd(strm)); - end; - finally - FreeMem(BackObj); - end; -end; - -procedure IndyDecompressStream(InStream, OutStream: TStream; - const AWindowBits : Integer); -var - strm : TZStreamRec; - BackObj: PZBack; - LWindowBits : Integer; -begin - LWindowBits := AWindowBits; - FillChar(strm, sizeof(strm), 0); - GetMem(BackObj, SizeOf(TZBack)); - try - //direct memory access if possible! - BackObj.InMem := DMAOfStream(InStream, BackObj.InMemSize); - - BackObj.InStream := InStream; - BackObj.OutStream := OutStream; - - //use our own function for reading - strm.avail_in := Strm_in_func(BackObj, PByte(strm.next_in)); - strm.next_out := @BackObj.Window[0]; - strm.avail_out := 0; - - //note that you can not use a WinBits parameter greater than 32 with - //InflateBackInit. That was used in the inflate functions - //for automatic detection of header bytes and trailer bytes. - //Se lets try this ugly workaround for it. - if AWindowBits > 32 then - begin - LWindowBits := Abs(AWindowBits - 32); - if not TryStreamType(strm, nil, LWindowBits) then - begin - if TryStreamType(strm, nil, LWindowBits + 16) then - begin - Inc(LWindowBits, 16); - end else - begin - TryStreamType(strm, nil, -LWindowBits); - end; - end; - end; - strm.next_out := nil; - strm.avail_out := 0; - DCheck(inflateBackInit(strm, LWindowBits, @BackObj.Window[0])); - try - DCheck(inflateBack(strm, Strm_in_func, BackObj, Strm_out_func, BackObj)); - //seek back when unused data - TIdStreamHelper.Seek(InStream, -strm.avail_in, soCurrent); - //now trailer can be checked - finally - DCheck(inflateBackEnd(strm)); - end; - finally - FreeMem(BackObj); - end; -end; - -type - TMemStreamAccess = class(TMemoryStream); - -function ExpandStream(AStream: TStream; const ACapacity : TIdStreamSize): Boolean; -{$IFDEF USE_INLINE} inline; {$ENDIF} -begin - Result := True; - AStream.Size := ACapacity; - if AStream is TMemoryStream then begin - {$I IdObjectChecksOff.inc} - AStream.Size := TMemStreamAccess(AStream).Capacity; - {$I IdObjectChecksOn.inc} - end; -end; - -procedure DoCompressStream(var strm: z_stream; InStream, OutStream: TStream; UseDirectOut: boolean); -const - //64 KB buffer - BufSize = 65536; - -var - InBuf, OutBuf : array of Byte; - pLastOutBuf : PByte; - UseInBuf, UseOutBuf : boolean; - LastOutCount : TIdC_UINT; - - procedure WriteOut; - var - NumWritten : TIdC_UINT; - begin - if (LastOutCount > 0) and (strm.avail_out < LastOutCount) then begin - NumWritten := LastOutCount - strm.avail_out; - if UseOutBuf then begin - OutStream.Write(pLastOutBuf^, NumWritten); - end else begin - TIdStreamHelper.Seek(OutStream, NumWritten, soCurrent); - end; - end; - end; - - procedure NextOut; - begin - if UseOutBuf then - begin - strm.next_out := PByte(OutBuf); - strm.avail_out := Length(OutBuf); - end else - begin - ExpandStream(OutStream, OutStream.Size + BufSize); - strm.next_out := DMAOfStream(OutStream, strm.avail_out); - //because we can't really know how much resize is increasing! - end; - end; - - procedure ExpandOut; - begin - if UseOutBuf then begin - SetLength(OutBuf, Length(OutBuf) + BufSize); - end; - NextOut; - end; - - function DeflateOut(FlushFlag: TIdC_INT): TIdC_INT; - begin - if strm.avail_out = 0 then begin - NextOut; - end; - - repeat - pLastOutBuf := strm.next_out; - LastOutCount := strm.avail_out; - - Result := deflate(strm, FlushFlag); - if Result <> Z_BUF_ERROR then begin - Break; - end; - - ExpandOut; - until False; - - CCheck(Result); - WriteOut; - end; - -begin - pLastOutBuf := nil; - LastOutCount := 0; - - strm.next_in := DMAOfStream(InStream, strm.avail_in); - UseInBuf := strm.next_in = nil; - - if UseInBuf then begin - SetLength(InBuf, BufSize); - end; - - UseOutBuf := not (UseDirectOut and CanResizeDMAStream(OutStream)); - if UseOutBuf then begin - SetLength(OutBuf, BufSize); - end; - - { From the zlib manual at http://www.zlib.net/manual.html - - deflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if all input has been consumed and all - output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR - if the stream state was inconsistent (for example if next_in or next_out was - NULL), Z_BUF_ERROR if no progress is possible (for example avail_in or avail_out - was zero). Note that Z_BUF_ERROR is not fatal, and deflate() can be called again - with more input and more output space to continue compressing. - } - - { From the ZLIB FAQ at http://www.gzip.org/zlib/FAQ.txt - - 5. deflate() or inflate() returns Z_BUF_ERROR - - Before making the call, make sure that avail_in and avail_out are not - zero. When setting the parameter flush equal to Z_FINISH, also make sure - that avail_out is big enough to allow processing all pending input. - Note that a Z_BUF_ERROR is not fatal--another call to deflate() or - inflate() can be made with more input or output space. A Z_BUF_ERROR - may in fact be unavoidable depending on how the functions are used, since - it is not possible to tell whether or not there is more output pending - when strm.avail_out returns with zero. - } - - repeat - if strm.avail_in = 0 then - begin - if UseInBuf then - begin - strm.next_in := PByte(InBuf); - strm.avail_in := InStream.Read(strm.next_in^, Length(InBuf)); - // TODO: if Read() returns < 0, raise an exception - end; - if strm.avail_in = 0 then begin - Break; - end; - end; - DeflateOut(Z_NO_FLUSH); - until False; - - repeat until DeflateOut(Z_FINISH) = Z_STREAM_END; - - if not UseOutBuf then - begin - //truncate when using direct output - OutStream.Size := OutStream.Position; - end; - - if not UseInBuf then begin - //adjust position of direct input - TIdStreamHelper.Seek(InStream, strm.total_in, soCurrent); - end; -end; - -procedure IndyCompressStream(InStream, OutStream: TStream; - const level: Integer = Z_DEFAULT_COMPRESSION; - const WinBits : Integer = MAX_WBITS; - const MemLevel : Integer = MAX_MEM_LEVEL; - const Stratagy : Integer = Z_DEFAULT_STRATEGY); -var - strm : z_stream; -begin - FillChar(strm, SizeOf(strm), 0); - CCheck(deflateInit2(strm, level, Z_DEFLATED, WinBits, MemLevel, Stratagy)); - try - DoCompressStream(strm, InStream, OutStream, True); - finally - CCheck(deflateEnd(strm)); - end; -end; - -procedure CompressStream(InStream, OutStream: TStream; level: TCompressionLevel; StreamType : TZStreamType); -var - strm : z_stream; -begin - FillChar(strm, SizeOf(strm), 0); - CCheck(deflateInitEx(strm, Levels[level], StreamType)); - try - DoCompressStream(strm, InStream, OutStream, False); - finally - CCheck(deflateEnd(strm)); - end; -end; - -procedure CompressStreamEx(InStream, OutStream: TStream; level: TCompressionLevel; StreamType : TZStreamType); -var - strm : z_stream; -begin - FillChar(strm, SizeOf(strm), 0); - CCheck(deflateInitEx(strm, Levels[level], StreamType)); - try - DoCompressStream(strm, InStream, OutStream, True); - finally - CCheck(deflateEnd(strm)); - end; -end; - -function CompressString(const InString: string; level: TCompressionLevel; StreamType : TZStreamType): string; -var - S, D : TStringStream; -begin - S := TStringStream.Create(InString); - try - D := TStringStream.Create(''); - try - CompressStream(S, D, level, StreamType); - Result := D.DataString; - finally - D.Free; - end; - finally - S.Free; - end; -end; - -procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; - OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); -var - strm: z_stream; - P: Pointer; - BufInc: Integer; -begin - FillChar(strm, SizeOf(strm), 0); - BufInc := (InBytes + 255) and not 255; - if OutEstimate = 0 then begin - OutBytes := BufInc; - end else begin - OutBytes := OutEstimate; - end; - GetMem(OutBuf, OutBytes); - try - strm.next_in := InBuf; - strm.avail_in := InBytes; - strm.next_out := OutBuf; - strm.avail_out := OutBytes; - DCheck(inflateInit(strm)); - try - while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do - begin - P := OutBuf; - Inc(OutBytes, BufInc); - ReallocMem(OutBuf, OutBytes); - strm.next_out := PByte(PtrUInt(OutBuf) + (PtrUInt(strm.next_out) - PtrUInt(P))); - strm.avail_out := BufInc; - end; - finally - DCheck(inflateEnd(strm)); - end; - ReallocMem(OutBuf, strm.total_out); - OutBytes := strm.total_out; - except - FreeMem(OutBuf); - raise; - end; -end; - -procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; - const OutBuf: Pointer; BufSize: Integer); -var - strm: z_stream; -begin - FillChar(strm, SizeOf(strm), 0); - strm.next_in := InBuf; - strm.avail_in := InBytes; - strm.next_out := OutBuf; - strm.avail_out := BufSize; - DCheck(inflateInit(strm)); - try - if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then begin - raise EZlibError.Create(sTargetBufferTooSmall); - end; - finally - DCheck(inflateEnd(strm)); - end; -end; - -{ EZlibError } - -class procedure EZlibError.RaiseException(const AError: Integer); -var - LException: EZlibError; -begin - LException := CreateFmt(sZLibError, [AError]); - LException.FErrorCode := AError; - raise LException; -end; - -// TCustomZlibStream -constructor TCustomZLibStream.Create(Strm: TStream); -begin - inherited Create; - FStrm := Strm; - FStrmPos := Strm.Position; - fillchar(FZRec, SizeOf(FZRec), 0); - FZRec.next_out := @FBuffer[0]; - FZRec.avail_out := 0; - FZRec.next_in := @FBuffer[0]; - FZRec.avail_in := 0; - fillchar(FGZHeader, SizeOf(FGZHeader), 0); - FStreamType := zsZLib; - FGZHeader.name := @FNameBuffer[0]; - FGZHeader.name_max := SizeOf(FNameBuffer); -end; - -destructor TCustomZlibStream.Destroy; -begin - inherited Destroy; -end; - -procedure TCustomZLibStream.Progress; -begin - if Assigned(FOnProgress) then begin - FOnProgress(Self); - end; -end; - -procedure TCustomZLibStream.IdSetSize(ASize: Int64); -begin - // do nothing here. IdSetSize is abstract, so it has - // to be overriden, but we don't actually use it here -end; - -// TCompressionStream -constructor TCompressionStream.CreateEx(CompressionLevel: TCompressionLevel; - Dest: TStream; const StreamType: TZStreamType; - const AName: string = ''; ATime: Integer = 0); -{$IFDEF USE_MARSHALLED_PTRS} -type - TBytesPtr = ^TBytes; -{$ENDIF} -var - LBytes: TIdBytes; - {$IFDEF HAS_AnsiString} - LName: AnsiString; - {$ENDIF} -begin - inherited Create(Dest); - LBytes := nil; // keep the compiler happy - FZRec.next_out := @FBuffer[0]; - FZRec.avail_out := SizeOf(FBuffer); - FStreamType := StreamType; - CCheck(deflateInitEx(FZRec, Levels[CompressionLevel], StreamType)); - if StreamType = zsGZip then - begin - FGZHeader.time := ATime; - //zero-terminated file name - //RFC 1952 - // The name must consist of ISO - //8859-1 (LATIN-1) characters; on operating systems using - //EBCDIC or any other character set for file names, the name - //must be translated to the ISO LATIN-1 character set. - - // Rebeau 2/20/09: Indy's 8-bit encoding class currently uses ISO-8859-1 - // so we could technically use that, but since the RFC is very specific - // about the charset, we'll force it here in case Indy's 8-bit encoding - // class is changed later on... - LBytes := CharsetToEncoding('ISO-8859-1').GetBytes(AName); - {$IFDEF USE_MARSHALLED_PTRS} - // TODO: optimize this - FillChar(FGZHeader.name^, FGZHeader.name_max, 0); - TMarshal.Copy(TBytesPtr(@LBytes)^, 0, TPtrWrapper.Create(FGZHeader.name), IndyMin(Length(LBytes), FGZHeader.name_max)); - {$ELSE} - // TODO: use Move() instead... - SetString(LName, PAnsiChar(LBytes), Length(LBytes)); - {$IFDEF HAS_AnsiStrings_StrPLCopy}AnsiStrings.{$ENDIF}StrPLCopy(FGZHeader.name, LName, FGZHeader.name_max); - {$ENDIF} - deflateSetHeader(FZRec, FGZHeader); - end; -end; - -constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel; - Dest: TStream; const AIncludeHeaders : Boolean = True); -begin - if AIncludeHeaders then begin - CreateEx(CompressionLevel, Dest, zsZLib); - end else begin - CreateEx(CompressionLevel, Dest, zsRaw); - end; -end; - -constructor TCompressionStream.CreateGZ(CompressionLevel: TCompressionLevel; - Dest: TStream; const AName: string; ATime: Integer); -begin - CreateEx(CompressionLevel, Dest, zsGZip, AName, ATime); -end; - -destructor TCompressionStream.Destroy; -begin - FZRec.next_in := nil; - FZRec.avail_in := 0; - try - if FStrm.Position <> FStrmPos then begin - FStrm.Position := FStrmPos; - end; - while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END) and (FZRec.avail_out = 0) do - begin - FStrm.WriteBuffer(FBuffer[0], SizeOf(FBuffer)); - FZRec.next_out := @FBuffer[0]; - FZRec.avail_out := SizeOf(FBuffer); - end; - if FZRec.avail_out < SizeOf(FBuffer) then begin - FStrm.WriteBuffer(FBuffer, SizeOf(FBuffer) - FZRec.avail_out); - end; - finally - deflateEnd(FZRec); - end; - inherited Destroy; -end; - -function TCompressionStream.IdRead(var VBuffer: TIdBytes; AOffset, ACount: Longint): Longint; -begin - raise ECompressionError.Create(sInvalidStreamOp); -end; - -function TCompressionStream.IdWrite(const ABuffer: TIdBytes; AOffset, ACount: Longint): Longint; -begin - FZRec.next_in := @ABuffer[AOffset]; - FZRec.avail_in := ACount; - if FStrm.Position <> FStrmPos then begin - FStrm.Position := FStrmPos; - end; - while FZRec.avail_in > 0 do - begin - CCheck(deflate(FZRec, 0)); - if FZRec.avail_out = 0 then - begin - FStrm.WriteBuffer(FBuffer[0], SizeOf(FBuffer)); - FZRec.next_out := @FBuffer[0]; - FZRec.avail_out := SizeOf(FBuffer); - FStrmPos := FStrm.Position; - Progress; - end; - end; - Result := ACount; -end; - -function TCompressionStream.IdSeek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64; -begin - if (AOffset = 0) and (AOrigin = soCurrent) then begin - Result := FZRec.total_in; - end else begin - raise ECompressionError.Create(sInvalidStreamOp); - end; -end; - -function TCompressionStream.GetCompressionRate: Single; -begin - if FZRec.total_in = 0 then begin - Result := 0; - end else begin - Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0; - end; -end; - -// TDecompressionStream -constructor TDecompressionStream.Create(Source: TStream); -begin - inherited Create(Source); - FInitialPos := FStrmPos; - FStreamType := zsRaw; //unknown - InitRead; -end; - -destructor TDecompressionStream.Destroy; -begin - TIdStreamHelper.Seek(FStrm, -FZRec.avail_in, soCurrent); - inflateEnd(FZRec); - inherited Destroy; -end; - -procedure TDecompressionStream.InitRead; -var - N, S : TIdC_UINT; -begin - //never call this after starting! - if FZRec.total_in > 0 then begin - Exit; - end; - - N := FStrm.Read(FBuffer, SizeOf(FBuffer)); - //64k should always be enough - FStreamType := GetStreamType(@FBuffer, N, @FGZHeader, S); - if (S = N) or (FStreamType = zsGZip) and (FGZHeader.done = 0) then - //need more data??? - //theoretically it can happen with a veeeeery long gzip name or comment - //this is more generic, but some extra steps - begin - TIdStreamHelper.Seek(FStrm, -N, soCurrent); - FStreamType := GetStreamType(FStrm, @FGZHeader, S); - end; - - //open - FZRec.next_in := @FBuffer[0]; - FZRec.avail_in := N; - - DCheck(inflateInitEx(FZRec, FStreamType)); -end; - -function TDecompressionStream.IdRead(var VBuffer: TIdBytes; AOffset, - ACount: Longint): Longint; -begin - FZRec.next_out := @VBuffer[AOffset]; - FZRec.avail_out := ACount; - if FStrm.Position <> FStrmPos then begin - FStrm.Position := FStrmPos; - end; - while FZRec.avail_out > 0 do - begin - if FZRec.avail_in = 0 then - begin - //init read if necessary - //if FZRec.total_in = 0 then InitRead; - - FZRec.avail_in := FStrm.Read(FBuffer[0], SizeOf(FBuffer)); - if FZRec.avail_in = 0 then begin - Break; - end; - FZRec.next_in := @FBuffer[0]; - FStrmPos := FStrm.Position; - Progress; - end; - if CCheck(inflate(FZRec, 0)) = Z_STREAM_END then begin - Break; - end; - end; - Result := TIdC_UINT(ACount) - FZRec.avail_out; -end; - -function TDecompressionStream.IdWrite(const ABuffer: TIdBytes; AOffset, ACount: Longint): Longint; -begin - raise EDecompressionError.Create(sInvalidStreamOp); -end; - -function TDecompressionStream.IdSeek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64; -var - I: Integer; - Buf: array [0..4095] of TIdAnsiChar; - LOffset : Int64; -begin - if (AOffset = 0) and (AOrigin = soBeginning) then - begin - DCheck(inflateReset(FZRec)); - FZRec.next_in := @FBuffer[0]; - FZRec.avail_in := 0; - FStrm.Position := FInitialPos; - FStrmPos := FInitialPos; - end - else if ((AOffset >= 0) and (AOrigin = soCurrent)) or - (((TIdC_UINT(AOffset) - FZRec.total_out) > 0) and (AOrigin = soBeginning)) then - begin - LOffset := AOffset; - if AOrigin = soBeginning then begin - Dec(LOffset, FZRec.total_out); - end; - if LOffset > 0 then - begin - for I := 1 to LOffset div sizeof(Buf) do begin - ReadBuffer(Buf, sizeof(Buf)); - end; - ReadBuffer(Buf, LOffset mod sizeof(Buf)); - end; - end else - begin - // raise EDecompressionError.CreateRes(@sInvalidStreamOp); - raise EDecompressionError.Create(sInvalidStreamOp); - end; - Result := FZRec.total_out; -end; - -function TDecompressionStream.IsGZip: boolean; -begin - Result := (FStreamType = zsGZip) and (FGZHeader.done = 1); -end; - -end. +(* + Enhanced zlib implementation + Gabriel Corneanu + + Base implementation follows the original zlib unit. + + Key features: + Using last zlib library (1.2.3). + Removed all imported functions, which are now in zlibpas. This can be used + standalone (as many other projects that need zlib do). + + The compression stream can create different type of streams: + zlib, gzip and raw deflate (see constructors). + + The decompression stream can read all type of streams (autodetect), + plus that the stream type and gzip info is available for public access. + If the stream is not zlib or gzip, it is assumed raw. An error will + occur during decompressing if the data format is not valid. + + The DecompressStream function is using the InflateBack call together + with direct memory access on the source stream + (if available, which means TStringStream or TCustomMemoryStream descendant). + It should be the fastest decompression routine! + + The CompressStreamEx function is using direct memory access on both + source and destination stream (if available). + It should be faster than CompressStream. + + CompressString or CompressStream can be used to compress a http response + +History: + - Aug 2005: Initial release +*) + +unit IdZLib; + +interface + +{$I IdCompilerDefines.inc} + +uses + SysUtils, + Classes, + {$IFDEF HAS_UNIT_System_ZLib} + {$IFDEF USE_INLINE} + System.ZLib, // here to facilitate inlining + {$ENDIF} + {$ENDIF} + IdCTypes, + IdGlobal, + IdZLibHeaders; + +type + // Abstract ancestor class + TCustomZlibStream = class(TIdBaseStream) + protected + FStrm: TStream; + FStrmPos: Integer; + FOnProgress: TNotifyEvent; + FZRec: TZStreamRec; + FBuffer: array [Word] of TIdAnsiChar; + FNameBuffer: array [0..255] of TIdAnsiChar; + FGZHeader : IdZLibHeaders.gz_header; + FStreamType : TZStreamType; + + procedure Progress; dynamic; + procedure IdSetSize(ASize: Int64); override; + property OnProgress: TNotifyEvent read FOnProgress write FOnProgress; + + public + constructor Create(Strm: TStream); + destructor Destroy; override; + + property GZHeader: gz_header read FGZHeader; + end; + + TCompressionLevel = (clNone, clFastest, clDefault, clMax); + + TCompressionStream = class(TCustomZlibStream) + protected + function GetCompressionRate: Single; + function IdRead(var VBuffer: TIdBytes; AOffset, ACount: Longint): Longint; override; + function IdWrite(const ABuffer: TIdBytes; AOffset, ACount: Longint): Longint; override; + function IdSeek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64; override; + public + constructor CreateEx(CompressionLevel: TCompressionLevel; Dest: TStream; + const StreamType: TZStreamType; + const AName: string = ''; ATime: Integer = 0); + constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream; const AIncludeHeaders : Boolean = True); + constructor CreateGZ(CompressionLevel: TCompressionLevel; Dest: TStream; + const AName: string = ''; ATime: Integer = 0); overload; + destructor Destroy; override; + property CompressionRate: Single read GetCompressionRate; + property OnProgress; + end; + + TDecompressionStream = class(TCustomZlibStream) + protected + FInitialPos : Int64; + function IdRead(var VBuffer: TIdBytes; AOffset, ACount: Longint): Longint; override; + function IdWrite(const ABuffer: TIdBytes; AOffset, ACount: Longint): Longint; override; + function IdSeek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64; override; + public + constructor Create(Source: TStream); + destructor Destroy; override; + procedure InitRead; + function IsGZip: boolean; + property OnProgress; + end; + +{ CompressBuf compresses data, buffer to buffer, in one call. + In: InBuf = ptr to compressed data + InBytes = number of bytes in InBuf + Out: OutBuf = ptr to newly allocated buffer containing decompressed data + OutBytes = number of bytes in OutBuf } +procedure CompressBuf(const InBuf: Pointer; InBytes: Integer; + out OutBuf: Pointer; out OutBytes: TIdC_UINT); + +//generic read header from a buffer +function GetStreamType(InBuffer: Pointer; InCount: TIdC_UINT; gzheader: gz_headerp; out HeaderSize: TIdC_UINT): TZStreamType; overload; + +//generic read header from a stream +//the stream position is preserved +function GetStreamType(InStream: TStream; gzheader: gz_headerp; out HeaderSize: TIdC_UINT): TZStreamType; overload; + +//Note that unlike other things in this unit, you specify things with number +//values. This is deliberate on my part because some things in Indy rely on +//API's where you specify the ZLib parameter as a number. This is for the +//utmost flexibility. In the FTP server, you can actually specify something +//like a compression level. +//The WinBits parameter is extremely powerful so do not underestimate it. +procedure IndyCompressStream(InStream, OutStream: TStream; + const level: Integer = Z_DEFAULT_COMPRESSION; + const WinBits : Integer = MAX_WBITS; + const MemLevel : Integer = MAX_MEM_LEVEL; + const Stratagy : Integer = Z_DEFAULT_STRATEGY); +//compress stream; tries to use direct memory access on input stream +procedure CompressStream(InStream, OutStream: TStream; level: TCompressionLevel; StreamType : TZStreamType); +//compress stream; tries to use direct memory access on both streams +procedure CompressStreamEx(InStream, OutStream: TStream; level: TCompressionLevel; StreamType : TZStreamType); +//compress a string +function CompressString(const InString: string; level: TCompressionLevel; StreamType : TZStreamType): string; + +//this is for where we know what the stream's WindowBits setting should be +//Note that this does have special handling for ZLIB values greater than +//32. I'm trying to treat it as the inflateInit2_ call would. I don't think +//InflateBack uses values greater than 16 so you have to make a workaround. +procedure IndyDecompressStream(InStream, OutStream: TStream; + const AWindowBits : Integer); +//fast decompress stream! +//using direct memory access to source stream (if available) and +//direct write (using inflateBack) +procedure DecompressStream(InStream, OutStream: TStream); + +{ DecompressBuf decompresses data, buffer to buffer, in one call. + In: InBuf = ptr to compressed data + InBytes = number of bytes in InBuf + OutEstimate = zero, or est. size of the decompressed data + Out: OutBuf = ptr to newly allocated buffer containing decompressed data + OutBytes = number of bytes in OutBuf } +procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; + OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); + +{ DecompressToUserBuf decompresses data, buffer to buffer, in one call. + In: InBuf = ptr to compressed data + InBytes = number of bytes in InBuf + Out: OutBuf = ptr to user-allocated buffer to contain decompressed data + BufSize = number of bytes in OutBuf } +procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; + const OutBuf: Pointer; BufSize: Integer); + +type + EZlibError = class(Exception) + {JPM Additions, we need to be able to provide diagnostic info in an exception} + protected + FErrorCode : Integer; + public + class procedure RaiseException(const AError: Integer); + // + property ErrorCode : Integer read FErrorCode; + end; + ECompressionError = class(EZlibError); + EDecompressionError = class(EZlibError); + +//ZLib error functions. They raise an exception for ZLib codes less than zero +function DCheck(code: Integer): Integer; +function CCheck(code: Integer): Integer; + +const + //winbit constants + MAX_WBITS = IdZLibHeaders.MAX_WBITS; + {$EXTERNALSYM MAX_WBITS} + GZIP_WINBITS = MAX_WBITS + 16; //GZip format + {$EXTERNALSYM GZIP_WINBITS} + //negative values mean do not add any headers + //adapted from "Enhanced zlib implementation" + //by Gabriel Corneanu + RAW_WBITS = -MAX_WBITS; //raw stream (without any header) + {$EXTERNALSYM RAW_WBITS} + +implementation + +uses + IdGlobalProtocols, IdStream, IdZLibConst + {$IFDEF HAS_AnsiStrings_StrPLCopy} + , AnsiStrings + {$ENDIF} + ; + +const + Levels: array [TCompressionLevel] of Int8 = + (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION); + +function CCheck(code: Integer): Integer; +{$IFDEF USE_INLINE} inline; {$ENDIF} +begin + Result := code; + if code < 0 then begin + ECompressionError.RaiseException(code); + end; +end; + +function DCheck(code: Integer): Integer; +{$IFDEF USE_INLINE} inline; {$ENDIF} +begin + Result := code; + if code < 0 then begin + EDecompressionError.RaiseException(code); + end; +end; + +procedure CompressBuf(const InBuf: Pointer; InBytes: Integer; + out OutBuf: Pointer; out OutBytes: TIdC_UINT); +var + strm: z_stream; + P: Pointer; +begin + FillChar(strm, sizeof(strm), 0); + OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255; + GetMem(OutBuf, OutBytes); + try + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := OutBytes; + CCheck(deflateInit(strm, Z_BEST_COMPRESSION)); + try + while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do + begin + P := OutBuf; + Inc(OutBytes, 256); + ReallocMem(OutBuf, OutBytes); + strm.next_out := PByte(PtrUInt(OutBuf) + (PtrUInt(strm.next_out) - PtrUInt(P))); + strm.avail_out := 256; + end; + finally + CCheck(deflateEnd(strm)); + end; + ReallocMem(OutBuf, strm.total_out); + OutBytes := strm.total_out; + except + FreeMem(OutBuf); + raise; + end; +end; + +function DMAOfStream(AStream: TStream; out Available: TIdC_UINT): Pointer; +{$IFDEF USE_INLINE} inline; {$ENDIF} +begin + if AStream is TCustomMemoryStream then begin + Result := TCustomMemoryStream(AStream).Memory; + end + {$IFDEF STRING_IS_ANSI} + // In D2009, the DataString property was changed to use a getter method + // that returns a temporary string, so it is not a direct access to the + // stream contents anymore. TStringStream was updated to derive from + // TBytesStream now, which is a TCustomMemoryStream descendant, and so + // will be handled above... + else if AStream is TStringStream then begin + Result := Pointer(TStringStream(AStream).DataString); + end + {$ENDIF} + else begin + Result := nil; + end; + if Result <> nil then + begin + //handle integer overflow + {$IFDEF STREAM_SIZE_64} + Available := TIdC_UINT(IndyMin(AStream.Size - AStream.Position, High(TIdC_UINT))); + // TODO: account for a 64-bit position in a 32-bit environment + Inc(PtrUInt(Result), AStream.Position); + {$ELSE} + Available := AStream.Size - AStream.Position; + Inc(PtrUInt(Result), AStream.Position); + {$ENDIF} + end else begin + Available := 0; + end; +end; + +function CanResizeDMAStream(AStream: TStream): boolean; +{$IFDEF USE_INLINE} inline; {$ENDIF} +begin + Result := (AStream is TCustomMemoryStream) + {$IFDEF STRING_IS_ANSI} + // In D2009, TStringStream was updated to derive from TBytesStream now, + // which is a TCustomMemoryStream descendant, and so will be handled above... + or (AStream is TStringStream) + {$ENDIF} + ; +end; + +///tries to get the stream info +//strm.next_in and available_in needs enough data! +//strm should not contain an initialized inflate + +function TryStreamType(var strm: TZStreamRec; gzheader: PgzHeaderRec; const AWinBitsValue : Integer): boolean; +var + InitBuf: PByte; + InitIn : TIdC_UINT; +begin + InitBuf := strm.next_in; + InitIn := strm.avail_in; + DCheck(inflateInit2(strm, AWinBitsValue)); + + if (AWinBitsValue = GZIP_WINBITS) and (gzheader <> nil) then begin + DCheck(inflateGetHeader(strm, gzheader^)); + end; + + Result := inflate(strm, Z_BLOCK) = Z_OK; + DCheck(inflateEnd(strm)); + + if Result then begin + Exit; + end; + + //rollback + strm.next_in := InitBuf; + strm.avail_in := InitIn; +end; + +//tries to get the stream info +//strm.next_in and available_in needs enough data! +//strm should not contain an initialized inflate +function CheckInitInflateStream(var strm: TZStreamRec; gzheader: gz_headerp): TZStreamType; overload; +var + InitBuf: PByte; + InitIn: Integer; + + function LocalTryStreamType(AStreamType: TZStreamType): Boolean; + begin + DCheck(inflateInitEx(strm, AStreamType)); + + if (AStreamType = zsGZip) and (gzheader <> nil) then begin + DCheck(inflateGetHeader(strm, gzheader^)); + end; + + Result := inflate(strm, Z_BLOCK) = Z_OK; + DCheck(inflateEnd(strm)); + + if Result then begin + Exit; + end; + + //rollback + strm.next_in := InitBuf; + strm.avail_in := InitIn; + end; + +begin + if strm.next_out = nil then begin + //needed for reading, but not used + strm.next_out := strm.next_in; + end; + + InitBuf := strm.next_in; + InitIn := strm.avail_in; + + for Result := zsZLib to zsGZip do + begin + if LocalTryStreamType(Result) then begin + Exit; + end; + end; + + Result := zsRaw; +end; + +function GetStreamType(InBuffer: Pointer; InCount: TIdC_UINT; gzheader: gz_headerp; + out HeaderSize: TIdC_UINT): TZStreamType; +var + strm : TZStreamRec; +begin + FillChar(strm, SizeOf(strm), 0); + strm.next_in := InBuffer; + strm.avail_in := InCount; + Result := CheckInitInflateStream(strm, gzheader); + HeaderSize := InCount - strm.avail_in; +end; + +function GetStreamType(InStream: TStream; gzheader: gz_headerp; + out HeaderSize: TIdC_UINT): TZStreamType; +const + StepSize = 20; //one step be enough, but who knows... +var + N : TIdC_UINT; + Buff : PIdAnsiChar; + UseBuffer: Boolean; +begin + Buff := DMAOfStream(InStream, N); + UseBuffer := Buff = nil; + if UseBuffer then begin + GetMem(Buff, StepSize); + end; + try + repeat + if UseBuffer then begin + Inc(N, InStream.Read(Buff[N], StepSize)); + end; + Result := GetStreamType(Buff, N, gzheader, HeaderSize); + //do we need more data? + //N mod StepSize <> 0 means no more data available + if (HeaderSize < N) or (not UseBuffer) or ((N mod StepSize) <> 0) then begin + Break; + end; + ReallocMem(Buff, N + StepSize); + until False; + finally + if UseBuffer then + begin + try + TIdStreamHelper.Seek(InStream, -N, soCurrent); + finally + FreeMem(Buff); + end; + end; + end; +end; + +const + WindowSize = 1 shl MAX_WBITS; + +type + PZBack = ^TZBack; + TZBack = record + InStream : TStream; + OutStream : TStream; + InMem : Pointer; //direct memory access + InMemSize : TIdC_UINT; + ReadBuf : array[Word] of Byte; + Window : array[0..WindowSize] of Byte; + end; + +function Strm_in_func(opaque: Pointer; var buf: PByte): TIdC_UNSIGNED; cdecl; +var + S : TStream; + BackObj : PZBack; +begin + BackObj := PZBack( opaque ); + S := BackObj.InStream; //help optimizations + if BackObj.InMem <> nil then + begin + //direct memory access if available! + buf := PByte(BackObj.InMem); + //handle integer overflow + {$IFDEF STREAM_SIZE_64} + Result := TIdC_UNSIGNED(IndyMin(S.Size - S.Position, High(TIdC_UNSIGNED))); + {$ELSE} + Result := S.Size - S.Position; + {$ENDIF} + TIdStreamHelper.Seek(S, Result, soCurrent); + end else + begin + buf := @BackObj.ReadBuf; + Result := S.Read(buf^, SizeOf(BackObj.ReadBuf)); + end; +end; + +function Strm_out_func(opaque: Pointer; buf: PByte; size: TIdC_UNSIGNED): TIdC_INT; cdecl; +begin + Result := TIdC_INT(PZBack(opaque).OutStream.Write(buf^, size) - TIdC_SIGNED(size)); +end; + +procedure DecompressStream(InStream, OutStream: TStream); +var + strm : z_stream; + BackObj: PZBack; +begin + FillChar(strm, sizeof(strm), 0); + GetMem(BackObj, SizeOf(TZBack)); + try + //Darcy + FillChar(BackObj^, sizeof(TZBack), 0); + + //direct memory access if possible! + BackObj.InMem := DMAOfStream(InStream, BackObj.InMemSize); + + BackObj.InStream := InStream; + BackObj.OutStream := OutStream; + + //use our own function for reading + strm.avail_in := Strm_in_func(BackObj, PByte(strm.next_in)); + strm.next_out := @BackObj.Window[0]; + strm.avail_out := 0; + + CheckInitInflateStream(strm, nil); + + strm.next_out := nil; + strm.avail_out := 0; + DCheck(inflateBackInit(strm, MAX_WBITS, @BackObj.Window[0])); + try + DCheck(inflateBack(strm, Strm_in_func, BackObj, Strm_out_func, BackObj)); + // DCheck(inflateBack(strm, @Strm_in_func, BackObj, @Strm_out_func, BackObj)); + //seek back when unused data + TIdStreamHelper.Seek(InStream, -strm.avail_in, soCurrent); + //now trailer can be checked + finally + DCheck(inflateBackEnd(strm)); + end; + finally + FreeMem(BackObj); + end; +end; + +procedure IndyDecompressStream(InStream, OutStream: TStream; + const AWindowBits : Integer); +var + strm : TZStreamRec; + BackObj: PZBack; + LWindowBits : Integer; +begin + LWindowBits := AWindowBits; + FillChar(strm, sizeof(strm), 0); + GetMem(BackObj, SizeOf(TZBack)); + try + //direct memory access if possible! + BackObj.InMem := DMAOfStream(InStream, BackObj.InMemSize); + + BackObj.InStream := InStream; + BackObj.OutStream := OutStream; + + //use our own function for reading + strm.avail_in := Strm_in_func(BackObj, PByte(strm.next_in)); + strm.next_out := @BackObj.Window[0]; + strm.avail_out := 0; + + //note that you can not use a WinBits parameter greater than 32 with + //InflateBackInit. That was used in the inflate functions + //for automatic detection of header bytes and trailer bytes. + //Se lets try this ugly workaround for it. + if AWindowBits > 32 then + begin + LWindowBits := Abs(AWindowBits - 32); + if not TryStreamType(strm, nil, LWindowBits) then + begin + if TryStreamType(strm, nil, LWindowBits + 16) then + begin + Inc(LWindowBits, 16); + end else + begin + TryStreamType(strm, nil, -LWindowBits); + end; + end; + end; + strm.next_out := nil; + strm.avail_out := 0; + DCheck(inflateBackInit(strm, LWindowBits, @BackObj.Window[0])); + try + DCheck(inflateBack(strm, Strm_in_func, BackObj, Strm_out_func, BackObj)); + //seek back when unused data + TIdStreamHelper.Seek(InStream, -strm.avail_in, soCurrent); + //now trailer can be checked + finally + DCheck(inflateBackEnd(strm)); + end; + finally + FreeMem(BackObj); + end; +end; + +type + TMemStreamAccess = class(TMemoryStream); + +function ExpandStream(AStream: TStream; const ACapacity : TIdStreamSize): Boolean; +{$IFDEF USE_INLINE} inline; {$ENDIF} +begin + Result := True; + AStream.Size := ACapacity; + if AStream is TMemoryStream then begin + {$I IdObjectChecksOff.inc} + AStream.Size := TMemStreamAccess(AStream).Capacity; + {$I IdObjectChecksOn.inc} + end; +end; + +procedure DoCompressStream(var strm: z_stream; InStream, OutStream: TStream; UseDirectOut: boolean); +const + //64 KB buffer + BufSize = 65536; + +var + InBuf, OutBuf : array of Byte; + pLastOutBuf : PByte; + UseInBuf, UseOutBuf : boolean; + LastOutCount : TIdC_UINT; + + procedure WriteOut; + var + NumWritten : TIdC_UINT; + begin + if (LastOutCount > 0) and (strm.avail_out < LastOutCount) then begin + NumWritten := LastOutCount - strm.avail_out; + if UseOutBuf then begin + OutStream.Write(pLastOutBuf^, NumWritten); + end else begin + TIdStreamHelper.Seek(OutStream, NumWritten, soCurrent); + end; + end; + end; + + procedure NextOut; + begin + if UseOutBuf then + begin + strm.next_out := PByte(OutBuf); + strm.avail_out := Length(OutBuf); + end else + begin + ExpandStream(OutStream, OutStream.Size + BufSize); + strm.next_out := DMAOfStream(OutStream, strm.avail_out); + //because we can't really know how much resize is increasing! + end; + end; + + procedure ExpandOut; + begin + if UseOutBuf then begin + SetLength(OutBuf, Length(OutBuf) + BufSize); + end; + NextOut; + end; + + function DeflateOut(FlushFlag: TIdC_INT): TIdC_INT; + begin + if strm.avail_out = 0 then begin + NextOut; + end; + + repeat + pLastOutBuf := strm.next_out; + LastOutCount := strm.avail_out; + + Result := deflate(strm, FlushFlag); + if Result <> Z_BUF_ERROR then begin + Break; + end; + + ExpandOut; + until False; + + CCheck(Result); + WriteOut; + end; + +begin + pLastOutBuf := nil; + LastOutCount := 0; + + strm.next_in := DMAOfStream(InStream, strm.avail_in); + UseInBuf := strm.next_in = nil; + + if UseInBuf then begin + SetLength(InBuf, BufSize); + end; + + UseOutBuf := not (UseDirectOut and CanResizeDMAStream(OutStream)); + if UseOutBuf then begin + SetLength(OutBuf, BufSize); + end; + + { From the zlib manual at http://www.zlib.net/manual.html + + deflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if all input has been consumed and all + output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR + if the stream state was inconsistent (for example if next_in or next_out was + NULL), Z_BUF_ERROR if no progress is possible (for example avail_in or avail_out + was zero). Note that Z_BUF_ERROR is not fatal, and deflate() can be called again + with more input and more output space to continue compressing. + } + + { From the ZLIB FAQ at http://www.gzip.org/zlib/FAQ.txt + + 5. deflate() or inflate() returns Z_BUF_ERROR + + Before making the call, make sure that avail_in and avail_out are not + zero. When setting the parameter flush equal to Z_FINISH, also make sure + that avail_out is big enough to allow processing all pending input. + Note that a Z_BUF_ERROR is not fatal--another call to deflate() or + inflate() can be made with more input or output space. A Z_BUF_ERROR + may in fact be unavoidable depending on how the functions are used, since + it is not possible to tell whether or not there is more output pending + when strm.avail_out returns with zero. + } + + repeat + if strm.avail_in = 0 then + begin + if UseInBuf then + begin + strm.next_in := PByte(InBuf); + strm.avail_in := InStream.Read(strm.next_in^, Length(InBuf)); + // TODO: if Read() returns < 0, raise an exception + end; + if strm.avail_in = 0 then begin + Break; + end; + end; + DeflateOut(Z_NO_FLUSH); + until False; + + repeat until DeflateOut(Z_FINISH) = Z_STREAM_END; + + if not UseOutBuf then + begin + //truncate when using direct output + OutStream.Size := OutStream.Position; + end; + + if not UseInBuf then begin + //adjust position of direct input + TIdStreamHelper.Seek(InStream, strm.total_in, soCurrent); + end; +end; + +procedure IndyCompressStream(InStream, OutStream: TStream; + const level: Integer = Z_DEFAULT_COMPRESSION; + const WinBits : Integer = MAX_WBITS; + const MemLevel : Integer = MAX_MEM_LEVEL; + const Stratagy : Integer = Z_DEFAULT_STRATEGY); +var + strm : z_stream; +begin + FillChar(strm, SizeOf(strm), 0); + CCheck(deflateInit2(strm, level, Z_DEFLATED, WinBits, MemLevel, Stratagy)); + try + DoCompressStream(strm, InStream, OutStream, True); + finally + CCheck(deflateEnd(strm)); + end; +end; + +procedure CompressStream(InStream, OutStream: TStream; level: TCompressionLevel; StreamType : TZStreamType); +var + strm : z_stream; +begin + FillChar(strm, SizeOf(strm), 0); + CCheck(deflateInitEx(strm, Levels[level], StreamType)); + try + DoCompressStream(strm, InStream, OutStream, False); + finally + CCheck(deflateEnd(strm)); + end; +end; + +procedure CompressStreamEx(InStream, OutStream: TStream; level: TCompressionLevel; StreamType : TZStreamType); +var + strm : z_stream; +begin + FillChar(strm, SizeOf(strm), 0); + CCheck(deflateInitEx(strm, Levels[level], StreamType)); + try + DoCompressStream(strm, InStream, OutStream, True); + finally + CCheck(deflateEnd(strm)); + end; +end; + +function CompressString(const InString: string; level: TCompressionLevel; StreamType : TZStreamType): string; +var + S, D : TStringStream; +begin + S := TStringStream.Create(InString); + try + D := TStringStream.Create(''); + try + CompressStream(S, D, level, StreamType); + Result := D.DataString; + finally + D.Free; + end; + finally + S.Free; + end; +end; + +procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer; + OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer); +var + strm: z_stream; + P: Pointer; + BufInc: Integer; +begin + FillChar(strm, SizeOf(strm), 0); + BufInc := (InBytes + 255) and not 255; + if OutEstimate = 0 then begin + OutBytes := BufInc; + end else begin + OutBytes := OutEstimate; + end; + GetMem(OutBuf, OutBytes); + try + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := OutBytes; + DCheck(inflateInit(strm)); + try + while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do + begin + P := OutBuf; + Inc(OutBytes, BufInc); + ReallocMem(OutBuf, OutBytes); + strm.next_out := PByte(PtrUInt(OutBuf) + (PtrUInt(strm.next_out) - PtrUInt(P))); + strm.avail_out := BufInc; + end; + finally + DCheck(inflateEnd(strm)); + end; + ReallocMem(OutBuf, strm.total_out); + OutBytes := strm.total_out; + except + FreeMem(OutBuf); + raise; + end; +end; + +procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; + const OutBuf: Pointer; BufSize: Integer); +var + strm: z_stream; +begin + FillChar(strm, SizeOf(strm), 0); + strm.next_in := InBuf; + strm.avail_in := InBytes; + strm.next_out := OutBuf; + strm.avail_out := BufSize; + DCheck(inflateInit(strm)); + try + if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then begin + raise EZlibError.Create(sTargetBufferTooSmall); + end; + finally + DCheck(inflateEnd(strm)); + end; +end; + +{ EZlibError } + +class procedure EZlibError.RaiseException(const AError: Integer); +var + LException: EZlibError; +begin + LException := CreateFmt(sZLibError, [AError]); + LException.FErrorCode := AError; + raise LException; +end; + +// TCustomZlibStream +constructor TCustomZLibStream.Create(Strm: TStream); +begin + inherited Create; + FStrm := Strm; + FStrmPos := Strm.Position; + fillchar(FZRec, SizeOf(FZRec), 0); + FZRec.next_out := @FBuffer[0]; + FZRec.avail_out := 0; + FZRec.next_in := @FBuffer[0]; + FZRec.avail_in := 0; + fillchar(FGZHeader, SizeOf(FGZHeader), 0); + FStreamType := zsZLib; + FGZHeader.name := @FNameBuffer[0]; + FGZHeader.name_max := SizeOf(FNameBuffer); +end; + +destructor TCustomZlibStream.Destroy; +begin + inherited Destroy; +end; + +procedure TCustomZLibStream.Progress; +begin + if Assigned(FOnProgress) then begin + FOnProgress(Self); + end; +end; + +procedure TCustomZLibStream.IdSetSize(ASize: Int64); +begin + // do nothing here. IdSetSize is abstract, so it has + // to be overriden, but we don't actually use it here +end; + +// TCompressionStream +constructor TCompressionStream.CreateEx(CompressionLevel: TCompressionLevel; + Dest: TStream; const StreamType: TZStreamType; + const AName: string = ''; ATime: Integer = 0); +{$IFDEF USE_MARSHALLED_PTRS} +type + TBytesPtr = ^TBytes; +{$ENDIF} +var + LBytes: TIdBytes; + {$IFDEF HAS_AnsiString} + LName: AnsiString; + {$ENDIF} +begin + inherited Create(Dest); + LBytes := nil; // keep the compiler happy + FZRec.next_out := @FBuffer[0]; + FZRec.avail_out := SizeOf(FBuffer); + FStreamType := StreamType; + CCheck(deflateInitEx(FZRec, Levels[CompressionLevel], StreamType)); + if StreamType = zsGZip then + begin + FGZHeader.time := ATime; + //zero-terminated file name + //RFC 1952 + // The name must consist of ISO + //8859-1 (LATIN-1) characters; on operating systems using + //EBCDIC or any other character set for file names, the name + //must be translated to the ISO LATIN-1 character set. + + // Rebeau 2/20/09: Indy's 8-bit encoding class currently uses ISO-8859-1 + // so we could technically use that, but since the RFC is very specific + // about the charset, we'll force it here in case Indy's 8-bit encoding + // class is changed later on... + LBytes := CharsetToEncoding('ISO-8859-1').GetBytes(AName); + {$IFDEF USE_MARSHALLED_PTRS} + // TODO: optimize this + FillChar(FGZHeader.name^, FGZHeader.name_max, 0); + TMarshal.Copy(TBytesPtr(@LBytes)^, 0, TPtrWrapper.Create(FGZHeader.name), IndyMin(Length(LBytes), FGZHeader.name_max)); + {$ELSE} + // TODO: use Move() instead... + SetString(LName, PAnsiChar(LBytes), Length(LBytes)); + {$IFDEF HAS_AnsiStrings_StrPLCopy}AnsiStrings.{$ENDIF}StrPLCopy(FGZHeader.name, LName, FGZHeader.name_max); + {$ENDIF} + deflateSetHeader(FZRec, FGZHeader); + end; +end; + +constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel; + Dest: TStream; const AIncludeHeaders : Boolean = True); +begin + if AIncludeHeaders then begin + CreateEx(CompressionLevel, Dest, zsZLib); + end else begin + CreateEx(CompressionLevel, Dest, zsRaw); + end; +end; + +constructor TCompressionStream.CreateGZ(CompressionLevel: TCompressionLevel; + Dest: TStream; const AName: string; ATime: Integer); +begin + CreateEx(CompressionLevel, Dest, zsGZip, AName, ATime); +end; + +destructor TCompressionStream.Destroy; +begin + FZRec.next_in := nil; + FZRec.avail_in := 0; + try + if FStrm.Position <> FStrmPos then begin + FStrm.Position := FStrmPos; + end; + while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END) and (FZRec.avail_out = 0) do + begin + FStrm.WriteBuffer(FBuffer[0], SizeOf(FBuffer)); + FZRec.next_out := @FBuffer[0]; + FZRec.avail_out := SizeOf(FBuffer); + end; + if FZRec.avail_out < SizeOf(FBuffer) then begin + FStrm.WriteBuffer(FBuffer, SizeOf(FBuffer) - FZRec.avail_out); + end; + finally + deflateEnd(FZRec); + end; + inherited Destroy; +end; + +function TCompressionStream.IdRead(var VBuffer: TIdBytes; AOffset, ACount: Longint): Longint; +begin + raise ECompressionError.Create(sInvalidStreamOp); +end; + +function TCompressionStream.IdWrite(const ABuffer: TIdBytes; AOffset, ACount: Longint): Longint; +begin + FZRec.next_in := @ABuffer[AOffset]; + FZRec.avail_in := ACount; + if FStrm.Position <> FStrmPos then begin + FStrm.Position := FStrmPos; + end; + while FZRec.avail_in > 0 do + begin + CCheck(deflate(FZRec, 0)); + if FZRec.avail_out = 0 then + begin + FStrm.WriteBuffer(FBuffer[0], SizeOf(FBuffer)); + FZRec.next_out := @FBuffer[0]; + FZRec.avail_out := SizeOf(FBuffer); + FStrmPos := FStrm.Position; + Progress; + end; + end; + Result := ACount; +end; + +function TCompressionStream.IdSeek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64; +begin + if (AOffset = 0) and (AOrigin = soCurrent) then begin + Result := FZRec.total_in; + end else begin + raise ECompressionError.Create(sInvalidStreamOp); + end; +end; + +function TCompressionStream.GetCompressionRate: Single; +begin + if FZRec.total_in = 0 then begin + Result := 0; + end else begin + Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0; + end; +end; + +// TDecompressionStream +constructor TDecompressionStream.Create(Source: TStream); +begin + inherited Create(Source); + FInitialPos := FStrmPos; + FStreamType := zsRaw; //unknown + InitRead; +end; + +destructor TDecompressionStream.Destroy; +begin + TIdStreamHelper.Seek(FStrm, -FZRec.avail_in, soCurrent); + inflateEnd(FZRec); + inherited Destroy; +end; + +procedure TDecompressionStream.InitRead; +var + N, S : TIdC_UINT; +begin + //never call this after starting! + if FZRec.total_in > 0 then begin + Exit; + end; + + N := FStrm.Read(FBuffer, SizeOf(FBuffer)); + //64k should always be enough + FStreamType := GetStreamType(@FBuffer, N, @FGZHeader, S); + if (S = N) or (FStreamType = zsGZip) and (FGZHeader.done = 0) then + //need more data??? + //theoretically it can happen with a veeeeery long gzip name or comment + //this is more generic, but some extra steps + begin + TIdStreamHelper.Seek(FStrm, -N, soCurrent); + FStreamType := GetStreamType(FStrm, @FGZHeader, S); + end; + + //open + FZRec.next_in := @FBuffer[0]; + FZRec.avail_in := N; + + DCheck(inflateInitEx(FZRec, FStreamType)); +end; + +function TDecompressionStream.IdRead(var VBuffer: TIdBytes; AOffset, + ACount: Longint): Longint; +begin + FZRec.next_out := @VBuffer[AOffset]; + FZRec.avail_out := ACount; + if FStrm.Position <> FStrmPos then begin + FStrm.Position := FStrmPos; + end; + while FZRec.avail_out > 0 do + begin + if FZRec.avail_in = 0 then + begin + //init read if necessary + //if FZRec.total_in = 0 then InitRead; + + FZRec.avail_in := FStrm.Read(FBuffer[0], SizeOf(FBuffer)); + if FZRec.avail_in = 0 then begin + Break; + end; + FZRec.next_in := @FBuffer[0]; + FStrmPos := FStrm.Position; + Progress; + end; + if CCheck(inflate(FZRec, 0)) = Z_STREAM_END then begin + Break; + end; + end; + Result := TIdC_UINT(ACount) - FZRec.avail_out; +end; + +function TDecompressionStream.IdWrite(const ABuffer: TIdBytes; AOffset, ACount: Longint): Longint; +begin + raise EDecompressionError.Create(sInvalidStreamOp); +end; + +function TDecompressionStream.IdSeek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64; +var + I: Integer; + Buf: array [0..4095] of TIdAnsiChar; + LOffset : Int64; +begin + if (AOffset = 0) and (AOrigin = soBeginning) then + begin + DCheck(inflateReset(FZRec)); + FZRec.next_in := @FBuffer[0]; + FZRec.avail_in := 0; + FStrm.Position := FInitialPos; + FStrmPos := FInitialPos; + end + else if ((AOffset >= 0) and (AOrigin = soCurrent)) or + (((TIdC_UINT(AOffset) - FZRec.total_out) > 0) and (AOrigin = soBeginning)) then + begin + LOffset := AOffset; + if AOrigin = soBeginning then begin + Dec(LOffset, FZRec.total_out); + end; + if LOffset > 0 then + begin + for I := 1 to LOffset div sizeof(Buf) do begin + ReadBuffer(Buf, sizeof(Buf)); + end; + ReadBuffer(Buf, LOffset mod sizeof(Buf)); + end; + end else + begin + // raise EDecompressionError.CreateRes(@sInvalidStreamOp); + raise EDecompressionError.Create(sInvalidStreamOp); + end; + Result := FZRec.total_out; +end; + +function TDecompressionStream.IsGZip: boolean; +begin + Result := (FStreamType = zsGZip) and (FGZHeader.done = 1); +end; + +end. diff --git a/Lib/Protocols/IdZLibHeaders.pas b/Lib/Protocols/IdZLibHeaders.pas index 2ced91849..91e31bab6 100644 --- a/Lib/Protocols/IdZLibHeaders.pas +++ b/Lib/Protocols/IdZLibHeaders.pas @@ -1,1626 +1,1626 @@ -unit IdZLibHeaders; - -{ - zlibpas -- Pascal interface to the zlib data compression library - * Gabriel Corneanu (gabrielcorneanu(AT)yahoo.com) - Derived from original sources by Bob Dellaca and Cosmin Truta. - - TZStreamType - - deflateInitEx - - inflateInitEx -*} -{ -JPM - note that I made dynamic loading for FreePascal (since that still may not -suppport external .obj files properly. It also makes it easier to support several -different platforms in one file. -} - -interface - -{$I IdCompilerDefines.inc} - -{$WRITEABLECONST OFF} - -{$IFDEF HAS_UNIT_System_ZLib} - - {$DEFINE STATICLOAD_ZLIB} - -{$ELSE} -{ -TODO: Wait for Emb to decide how to approach ZLib for their 64-bit support -before we proceed at our end. -} -{$UNDEF STATICLOAD_ZLIB} -{$UNDEF STATIC_CDECL_PROCS} -{$IFDEF DCC} - {$IFDEF WIN32} -{ -For Win32, we use some .obj files. These .objs were compiled from the ZLib -source-code folder with "make -f contrib\delphi\zlibd32.mak" using Borland's -"make" and "bcc32". The .objs are compiled with the -"-DZEXPORT=__fastcall -DZEXPORTVA=__cdecl" parameter. Do NOT change -the function calling conventions unless you know what you are doing and -the C++ objects are compiled appropriately. - -The only things that still are cdecl are the callback functions. -} - {$IFNDEF BCB5_DUMMY_BUILD} - {$DEFINE STATICLOAD_ZLIB} - {$IFDEF VCL_XE2_OR_ABOVE} - {$DEFINE STATIC_CDECL_PROCS} - {$ENDIF} - {$ENDIF} - {$ALIGN OFF} - {$ENDIF} - {$IFDEF WIN64} - {$ALIGN ON} - {$MINENUMSIZE 4} - {$IFNDEF BCB5_DUMMY_BUILD} - {$DEFINE STATICLOAD_ZLIB} - {$ENDIF} - {$ENDIF} -{$ELSE} - {$packrecords C} -{$ENDIF} - -{$ENDIF} - -uses - {$IFDEF HAS_UNIT_System_ZLib} - System.ZLib, - IdCTypes; - {$ELSE} - //reference off_t - {$IFDEF USE_VCL_POSIX} - Posix.SysTypes, - {$ENDIF} - {$IFDEF KYLIXCOMPAT} - libc, - {$ENDIF} - {$IFDEF USE_BASEUNIX} - baseunix, - {$ENDIF} - IdGlobal, IdCTypes - {$IFNDEF STATICLOAD_ZLIB} - , IdException - {$ENDIF}; - {$ENDIF} - -{$IFNDEF HAS_UNIT_System_ZLib} - -{$DEFINE USE_PRAGMA_PACK_1} -{$IFDEF LINUX64} - {$UNDEF USE_PRAGMA_PACK_1} -{$ENDIF} -{$IFDEF IOS64} - {$UNDEF USE_PRAGMA_PACK_1} -{$ENDIF} - -{$IFDEF STATICLOAD_ZLIB} -(*$HPPEMIT '// For Win32, we use some .obj files. These .objs were compiled from the ZLib'*) -(*$HPPEMIT '// source-code folder with "make -f contrib\delphi\zlibd32.mak" using Borland's'*) -(*$HPPEMIT '// "make" and "bcc32". The .objs are compiled with the'*) -(*$HPPEMIT '// "-DZEXPORT=__fastcall -DZEXPORTVA=__cdecl" parameter. Do NOT change'*) -(*$HPPEMIT '// the function calling conventions unless you know what you are doing and'*) -(*$HPPEMIT '// the C++ objects are compiled appropriately.'*) -(*$HPPEMIT '//'*) -(*$HPPEMIT '// The only things that still are cdecl are the callback functions.'*) -(*$HPPEMIT ''*) - {$IFDEF STATIC_CDECL_PROCS} -(*$HPPEMIT '#define ZEXPORT __cdecl'*) - {$ELSE} -(*$HPPEMIT '#define ZEXPORT __fastcall'*) - {$ENDIF} -{$ELSE} -(*$HPPEMIT '#define ZEXPORT __cdecl'*) -{$ENDIF} -(*$HPPEMIT '#define ZEXPORTVA __cdecl'*) -(*$HPPEMIT '#if !defined(__MACTYPES__)'*) -(*$HPPEMIT ' // We are defining __MACTYPES__ in order to skip the declaration of "Byte" as it causes'*) -(*$HPPEMIT ' // ambiguity with System::Byte'*) -(*$HPPEMIT ' #define __MACTYPES__'*) -(*$HPPEMIT ' #define __REMOVE_MACTYPES__'*) -(*$HPPEMIT '#endif'*) -(*$HPPEMIT '#if defined(__USE_ZLIBH__)'*) -(*$HPPEMIT ' #include "ZLib\zlib.h"'*) -(*$HPPEMIT '#else'*) -(*$HPPEMIT 'typedef void * __cdecl (*alloc_func)(void * opaque, unsigned items, unsigned size);'*) -(*$HPPEMIT ''*) -(*$HPPEMIT 'typedef void __cdecl (*free_func)(void * opaque, void * address);'*) -(*$HPPEMIT ''*) -{$IFDEF USE_PRAGMA_PACK_1} -(*$HPPEMIT '#pragma pack(push,1)'*) -{$ENDIF} -{$IFDEF VCL_XE_OR_ABOVE} -(*$HPPEMIT 'struct DECLSPEC_DRECORD z_stream'*) -{$ELSE} -(*$HPPEMIT 'struct z_stream'*) -{$ENDIF} -(*$HPPEMIT '{'*) -(*$HPPEMIT ' '*) -(*$HPPEMIT 'public:'*) -(*$HPPEMIT ' char *next_in;'*) -(*$HPPEMIT ' unsigned avail_in;'*) -(*$HPPEMIT ' unsigned long total_in;'*) -(*$HPPEMIT ' char *next_out;'*) -(*$HPPEMIT ' unsigned avail_out;'*) -(*$HPPEMIT ' unsigned long total_out;'*) -(*$HPPEMIT ' char *msg;'*) -(*$HPPEMIT ' void *state;'*) -(*$HPPEMIT ' alloc_func zalloc;'*) -(*$HPPEMIT ' free_func zfree;'*) -(*$HPPEMIT ' void *opaque;'*) -(*$HPPEMIT ' int data_type;'*) -(*$HPPEMIT ' unsigned long adler;'*) -(*$HPPEMIT ' unsigned long reserved;'*) -(*$HPPEMIT '};'*) -{$IFDEF USE_PRAGMA_PACK_1} -(*$HPPEMIT '#pragma pack(pop)'*) -{$ENDIF} -(*$HPPEMIT ''*) -(*$HPPEMIT '#if !defined(__clang__) && !defined(__CPP__)'*) -(*$HPPEMIT '#if sizeof(z_stream) < 56'*) -(*$HPPEMIT '#pragma message "Pascal/C++ size mismatch: (C++) sizeof(z_stream) < (Pascal) [size: 56, align: 1] (WARNING)"'*) -(*$HPPEMIT '#pragma sizeof(z_stream)'*) -(*$HPPEMIT '#endif'*) -(*$HPPEMIT ''*) -(*$HPPEMIT '#if sizeof(z_stream) > 56'*) -(*$HPPEMIT '#pragma message "Pascal/C++ size mismatch: (C++) sizeof(z_stream) > (Pascal) [size: 56, align: 1] (WARNING)"'*) -(*$HPPEMIT '#pragma sizeof(z_stream)'*) -(*$HPPEMIT '#endif'*) -(*$HPPEMIT ''*) -{$IFDEF VCL_2009_OR_ABOVE} -(*$HPPEMIT '#if alignof(z_stream) < 1'*) -(*$HPPEMIT '#pragma message "Pascal/C++ alignment mismatch: (C++) alignof(z_stream) < (Pascal) [size: 56, align: 1] (WARNING)"'*) -(*$HPPEMIT '#endif'*) -(*$HPPEMIT ''*) -(*$HPPEMIT '#if alignof(z_stream) > 1'*) -(*$HPPEMIT '#pragma message "Pascal/C++ alignment mismatch: (C++) alignof(z_stream) > (Pascal) [size: 56, align: 1] (WARNING)"'*) -(*$HPPEMIT '#endif'*) -{$ELSE} -// TODO: what to put here for older C++Builder compilers that do not have alignof()? -// see http://www.wambold.com/Martin/writings/alignof.html for ideas... -{$ENDIF} -(*$HPPEMIT '#endif'*) -(*$HPPEMIT ''*) -(*$HPPEMIT ''*) -(*$HPPEMIT 'struct gz_header;'*) -(*$HPPEMIT 'typedef gz_header *gz_headerp;'*) -(*$HPPEMIT ''*) -{$IFDEF USE_PRAGMA_PACK_1} -(*$HPPEMIT '#pragma pack(push,1)'*) -{$ENDIF} -{$IFDEF VCL_XE_OR_ABOVE} -(*$HPPEMIT 'struct DECLSPEC_DRECORD gz_header'*) -{$ELSE} -(*$HPPEMIT 'struct gz_header'*) -{$ENDIF} -(*$HPPEMIT '{'*) -(*$HPPEMIT ' '*) -(*$HPPEMIT 'public:'*) -(*$HPPEMIT ' int text;'*) -(*$HPPEMIT ' unsigned long time;'*) -(*$HPPEMIT ' int xflags;'*) -(*$HPPEMIT ' int os;'*) -(*$HPPEMIT ' System::Byte *extra;'*) -(*$HPPEMIT ' unsigned extra_len;'*) -(*$HPPEMIT ' unsigned extra_max;'*) -(*$HPPEMIT ' char *name;'*) -(*$HPPEMIT ' unsigned name_max;'*) -(*$HPPEMIT ' char *comment;'*) -(*$HPPEMIT ' unsigned comm_max;'*) -(*$HPPEMIT ' int hcrc;'*) -(*$HPPEMIT ' int done;'*) -(*$HPPEMIT '};'*) -{$IFDEF USE_PRAGMA_PACK_1} -(*$HPPEMIT '#pragma pack(pop)'*) -{$ENDIF} -(*$HPPEMIT ''*) -(*$HPPEMIT '#if !defined(__clang__) && !defined(__CPP__)'*) -(*$HPPEMIT '#if sizeof(gz_header) < 52'*) -(*$HPPEMIT '#pragma message "Pascal/C++ size mismatch: (C++) sizeof(gz_header) < (Pascal) [size: 52, align: 1] (WARNING)"'*) -(*$HPPEMIT '#pragma sizeof(gz_header)'*) -(*$HPPEMIT '#endif'*) -(*$HPPEMIT ''*) -(*$HPPEMIT '#if sizeof(gz_header) > 52'*) -(*$HPPEMIT '#pragma message "Pascal/C++ size mismatch: (C++) sizeof(gz_header) > (Pascal) [size: 52, align: 1] (WARNING)"'*) -(*$HPPEMIT '#pragma sizeof(gz_header)'*) -(*$HPPEMIT '#endif'*) -(*$HPPEMIT ''*) -{$IFDEF VCL_2009_OR_ABOVE} -(*$HPPEMIT '#if alignof(gz_header) < 1'*) -(*$HPPEMIT '#pragma message "Pascal/C++ alignment mismatch: (C++) alignof(gz_header) < (Pascal) [size: 52, align: 1] (WARNING)"'*) -(*$HPPEMIT '#endif'*) -(*$HPPEMIT ''*) -(*$HPPEMIT '#if alignof(gz_header) > 1'*) -(*$HPPEMIT '#pragma message "Pascal/C++ alignment mismatch: (C++) alignof(gz_header) > (Pascal) [size: 52, align: 1] (WARNING)"'*) -(*$HPPEMIT '#endif'*) -{$ELSE} -// TODO: what to put here for older C++Builder compilers that do not have alignof()? -// see http://www.wambold.com/Martin/writings/alignof.html for ideas... -{$ENDIF} -(*$HPPEMIT '#endif'*) -(*$HPPEMIT '#endif'*) -(*$HPPEMIT '#if defined(__REMOVE_MACTYPES__)'*) -(*$HPPEMIT ' // Cleanup workaround for "Byte" ambiguity'*) -(*$HPPEMIT ' #if defined(__MACTYPES__)'*) -(*$HPPEMIT ' #undef __MACTYPES__'*) -(*$HPPEMIT ' #endif'*) -(*$HPPEMIT ' #undef __REMOVE_MACTYPES__'*) -(*$HPPEMIT '#endif'*) - -{$ENDIF} - -{$IFDEF HAS_UNIT_System_ZLib} -type - // In Delphi XE3+, Indy uses MarshaledAString only on mobile platforms, - // but System.ZLib uses MarshaledAString regardless of platform... - {.$IFDEF HAS_MarshaledAString} - {$IFDEF VCL_XE3_OR_ABOVE} - ZLibAString = MarshaledAString; - {$ELSE} - ZLibAString = PIdAnsiChar; - {$ENDIF} -{$ENDIF} - -{$EXTERNALSYM ZLIB_VERSION} -{$EXTERNALSYM ZLIB_VERNUM} -{$EXTERNALSYM ZLIB_VER_MAJOR} -{$EXTERNALSYM ZLIB_VER_MINOR} -{$EXTERNALSYM ZLIB_VER_REVISION} -{$EXTERNALSYM ZLIB_VER_SUBREVISION} - -{$IFDEF HAS_UNIT_System_ZLib} -// System.ZLib.ZLIB_VERSION is a TYPED constant (why?), so it can't be aliased as a const here! -var - ZLIB_VERSION: ZLibAString absolute System.ZLib.ZLIB_VERSION; -const - //ZLIB_VERSION: ZLibAString = System.ZLib.ZLIB_VERSION; - ZLIB_VERNUM = System.ZLib.ZLIB_VERNUM; - ZLIB_VER_MAJOR = System.ZLib.ZLIB_VER_MAJOR; - ZLIB_VER_MINOR = System.ZLib.ZLIB_VER_MINOR; - ZLIB_VER_REVISION = System.ZLib.ZLIB_VER_REVSION; // Typo on Embarcadero's side! - ZLIB_VER_SUBREVISION = System.ZLib.ZLIB_VER_SUBREVISION; -{$ELSE} -const - ZLIB_VERSION = '1.2.5'; - ZLIB_VERNUM = $1250; - ZLIB_VER_MAJOR = 1; - ZLIB_VER_MINOR = 2; - ZLIB_VER_REVISION = 5; - ZLIB_VER_SUBREVISION = 0; -{$ENDIF} - -type - {$EXTERNALSYM z_off_t} - {$IFDEF HAS_UNIT_System_ZLib} - z_off_t = System.ZLib.z_off_t; - {$ELSE} -{JPM - I made some types from our old header to the new C types defined originally - for compatability.} - {$IFDEF WINDOWS} - z_off_t = TIdC_LONG; - {$ELSE} - {$IFDEF USE_VCL_POSIX} - z_off_t = off_t; - {$ELSE} - {$IFDEF KYLIXCOMPAT} - z_off_t = off_t; - {$ELSE} - {$IFDEF USE_BASEUNIX} - z_off_t = off_t; - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} - - {$EXTERNALSYM alloc_func} - {$EXTERNALSYM free_func} - {$EXTERNALSYM in_func} - {$EXTERNALSYM out_func} - {$EXTERNALSYM z_streamp} - {$EXTERNALSYM z_stream} - {$EXTERNALSYM gz_headerp} - {$EXTERNALSYM gz_header} - - {$IFDEF HAS_UNIT_SYSTEM_ZLib} - - alloc_func = System.ZLib.alloc_func; - free_func = System.ZLib.free_func; - in_func = System.ZLib.in_func; - out_func = System.ZLib.out_func; - z_streamp = System.ZLib.z_streamp; - z_stream = System.ZLib.z_stream; - gz_headerp = System.ZLib.gz_headerp; - gz_header = System.ZLib.gz_header; - - {$ELSE} - - alloc_func = function(opaque: Pointer; items, size: TIdC_UINT): Pointer; cdecl; - free_func = procedure(opaque, address: Pointer); cdecl; - in_func = function(opaque: Pointer; var buf: PByte): TIdC_UNSIGNED; cdecl; - out_func = function(opaque: Pointer; buf: PByte; size: TIdC_UNSIGNED): TIdC_INT; cdecl; - z_streamp = ^z_stream; - z_stream = record - next_in: PByte; (* next input byte *) - avail_in: TIdC_UINT; (* number of bytes available at next_in *) - total_in: TIdC_ULONG; (* total nb of input bytes read so far *) - - next_out: PByte; (* next output byte should be put there *) - avail_out: TIdC_UINT; (* remaining free space at next_out *) - total_out: TIdC_ULONG; (* total nb of bytes output so far *) - - msg: PIdAnsiChar; (* last error message, NULL if no error *) - state: Pointer; (* not visible by applications *) - - zalloc: alloc_func; (* used to allocate the internal state *) - zfree: free_func; (* used to free the internal state *) - opaque: Pointer; (* private data object passed to zalloc and zfree *) - - data_type: TIdC_INT; (* best guess about the data type: ascii or binary *) - adler: TIdC_ULONG; (* adler32 value of the uncompressed data *) - reserved: TIdC_ULONG; (* reserved for future use *) - end; - -(* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*) - gz_headerp = ^gz_header; - gz_header = record - text : TIdC_INT; //* true if compressed data believed to be text */ - time : TIdC_ULONG; //* modification time */ - xflags : TIdC_INT; //* extra flags (not used when writing a gzip file) */ - os : TIdC_INT; //* operating system */ - extra : PByte; //* pointer to extra field or Z_NULL if none */ - extra_len : TIdC_UINT; //* extra field length (valid if extra != Z_NULL) */ - extra_max : TIdC_UINT; //* space at extra (only when reading header) */ - name : PIdAnsiChar; //* pointer to zero-terminated file name or Z_NULL */ - name_max : TIdC_UINT; //* space at name (only when reading header) */ - comment : PIdAnsiChar; //* pointer to zero-terminated comment or Z_NULL */ - comm_max : TIdC_UINT; //* space at comment (only when reading header) */ - hcrc : TIdC_INT; //* true if there was or will be a header crc */ - done : TIdC_INT; //* true when done reading gzip header (not used when writing a gzip file) */ - end; - - {$ENDIF} - - {$EXTERNALSYM TAlloc} - TAlloc = alloc_func; - {$EXTERNALSYM TFree} - TFree = free_func; - {$EXTERNALSYM TInFunc} - TInFunc = in_func; - {$EXTERNALSYM TOutFunc} - TOutFunc = out_func; - {$EXTERNALSYM TZStreamRec} - TZStreamRec = z_stream; - {$EXTERNALSYM PZStreamRec} - PZStreamRec = z_streamp; - {$EXTERNALSYM PgzHeaderRec} - PgzHeaderRec = gz_headerp; - {$EXTERNALSYM TgzHeaderRec} - TgzHeaderRec = gz_header; - -type - TZStreamType = ( - zsZLib, //standard zlib stream - zsGZip, //gzip stream - zsRaw); //raw stream (without any header) - -(* constants *) -const - {$EXTERNALSYM Z_NO_FLUSH} - {$EXTERNALSYM Z_PARTIAL_FLUSH} - {$EXTERNALSYM Z_SYNC_FLUSH} - {$EXTERNALSYM Z_FULL_FLUSH} - {$EXTERNALSYM Z_FINISH} - {$EXTERNALSYM Z_BLOCK} - {$EXTERNALSYM Z_TREES} - {$EXTERNALSYM Z_OK} - {$EXTERNALSYM Z_STREAM_END} - {$EXTERNALSYM Z_NEED_DICT} - {$EXTERNALSYM Z_ERRNO} - {$EXTERNALSYM Z_STREAM_ERROR} - {$EXTERNALSYM Z_DATA_ERROR} - {$EXTERNALSYM Z_MEM_ERROR} - {$EXTERNALSYM Z_BUF_ERROR} - {$EXTERNALSYM Z_VERSION_ERROR} - - {$EXTERNALSYM Z_NO_COMPRESSION} - {$EXTERNALSYM Z_BEST_SPEED} - {$EXTERNALSYM Z_BEST_COMPRESSION} - {$EXTERNALSYM Z_DEFAULT_COMPRESSION} - - {$EXTERNALSYM Z_FILTERED} - {$EXTERNALSYM Z_HUFFMAN_ONLY} - {$EXTERNALSYM Z_RLE} - {$EXTERNALSYM Z_DEFAULT_STRATEGY} - - {$EXTERNALSYM Z_BINARY} - {$EXTERNALSYM Z_TEXT} - {$EXTERNALSYM Z_ASCII} - {$EXTERNALSYM Z_UNKNOWN} - - {$EXTERNALSYM Z_DEFLATED} - {$EXTERNALSYM Z_NULL} - - {$IFDEF HAS_UNIT_System_ZLib} - - Z_NO_FLUSH = System.ZLib.Z_NO_FLUSH; - Z_PARTIAL_FLUSH = System.ZLib.Z_PARTIAL_FLUSH; - Z_SYNC_FLUSH = System.ZLib.Z_SYNC_FLUSH; - Z_FULL_FLUSH = System.ZLib.Z_FULL_FLUSH; - Z_FINISH = System.ZLib.Z_FINISH; - Z_BLOCK = System.ZLib.Z_BLOCK; - Z_TREES = System.ZLib.Z_TREES; - Z_OK = System.ZLib.Z_OK; - Z_STREAM_END = System.ZLib.Z_STREAM_END; - Z_NEED_DICT = System.ZLib.Z_NEED_DICT; - Z_ERRNO = System.ZLib.Z_ERRNO; - Z_STREAM_ERROR = System.ZLib.Z_STREAM_ERROR; - Z_DATA_ERROR = System.ZLib.Z_DATA_ERROR; - Z_MEM_ERROR = System.ZLib.Z_MEM_ERROR; - Z_BUF_ERROR = System.ZLib.Z_BUF_ERROR; - Z_VERSION_ERROR = System.ZLib.Z_VERSION_ERROR; - - Z_NO_COMPRESSION = System.ZLib.Z_NO_COMPRESSION; - Z_BEST_SPEED = System.ZLib.Z_BEST_SPEED; - Z_BEST_COMPRESSION = System.ZLib.Z_BEST_COMPRESSION; - Z_DEFAULT_COMPRESSION = System.ZLib.Z_DEFAULT_COMPRESSION; - - Z_FILTERED = System.ZLib.Z_FILTERED; - Z_HUFFMAN_ONLY = System.ZLib.Z_HUFFMAN_ONLY; - Z_RLE = System.ZLib.Z_RLE; - Z_DEFAULT_STRATEGY = System.ZLib.Z_DEFAULT_STRATEGY; - - Z_BINARY = System.ZLib.Z_BINARY; - Z_TEXT = System.ZLib.Z_TEXT; - Z_ASCII = System.ZLib.Z_ASCII; - Z_UNKNOWN = System.ZLib.Z_UNKNOWN; - - Z_DEFLATED = System.ZLib.Z_DEFLATED; - Z_NULL = System.ZLib.Z_NULL; - - {$ELSE} - - Z_NO_FLUSH = 0; - Z_PARTIAL_FLUSH = 1; - Z_SYNC_FLUSH = 2; - Z_FULL_FLUSH = 3; - Z_FINISH = 4; - Z_BLOCK = 5; - Z_TREES = 6; - Z_OK = 0; - Z_STREAM_END = 1; - Z_NEED_DICT = 2; - Z_ERRNO = -1; - Z_STREAM_ERROR = -2; - Z_DATA_ERROR = -3; - Z_MEM_ERROR = -4; - Z_BUF_ERROR = -5; - Z_VERSION_ERROR = -6; - - Z_NO_COMPRESSION = 0; - Z_BEST_SPEED = 1; - Z_BEST_COMPRESSION = 9; - Z_DEFAULT_COMPRESSION = -1; - - Z_FILTERED = 1; - Z_HUFFMAN_ONLY = 2; - Z_RLE = 3; - Z_DEFAULT_STRATEGY = 0; - - Z_BINARY = 0; - Z_TEXT = 1; - Z_ASCII = Z_TEXT; //* for compatibility with 1.2.2 and earlier */ - Z_UNKNOWN = 2; - - Z_DEFLATED = 8; - Z_NULL = 0; //* for initializing zalloc, zfree, opaque */ - - {$ENDIF} - - {$EXTERNALSYM MAX_WBITS} - MAX_WBITS = 15; { 32K LZ77 window } - - {$EXTERNALSYM MAX_MEM_LEVEL} - MAX_MEM_LEVEL = 9; - {$EXTERNALSYM DEF_MEM_LEVEL} - DEF_MEM_LEVEL = 8; { if MAX_MEM_LEVEL > 8 } - -{$EXTERNALSYM inflateInit} -function inflateInit(var strm: z_stream): TIdC_INT; -{$IFDEF USE_INLINE} inline; {$ENDIF} - -{$EXTERNALSYM inflateBackInit} -function inflateBackInit(var strm: z_stream; - windowBits: TIdC_INT; window: PByte): TIdC_INT; -{$IFDEF USE_INLINE} inline; {$ENDIF} - -{$EXTERNALSYM inflateInit2} -function inflateInit2(var strm: z_stream; windowBits: TIdC_INT): TIdC_INT; -{$IFDEF USE_INLINE} inline; {$ENDIF} - -{$EXTERNALSYM deflateInit} -function deflateInit(var strm: z_stream; level: TIdC_INT): TIdC_INT; -{$IFDEF USE_INLINE} inline; {$ENDIF} - -{$EXTERNALSYM deflateInit2} -function deflateInit2(var strm: z_stream; level, method, windowBits, - memLevel, strategy: TIdC_INT): TIdC_INT; -{$IFDEF USE_INLINE} inline; {$ENDIF} - -{not sure if these should be externalsymed but might not be a bad idea} - -{$EXTERNALSYM deflateInitEx} -function deflateInitEx(var strm: z_stream; level: TIdC_INT; streamtype: TZStreamType = zsZLib): TIdC_INT; - -{$EXTERNALSYM inflateInitEx} -function inflateInitEx(var strm: z_stream; streamtype: TZStreamType = zsZLib): TIdC_INT; - -{$EXTERNALSYM adler32} -{$EXTERNALSYM adler32_combine} -{$EXTERNALSYM compress} -{$EXTERNALSYM compress2} -{$EXTERNALSYM compressBound} -{$EXTERNALSYM crc32} -{$EXTERNALSYM crc32_combine} -{$EXTERNALSYM deflate} -{$EXTERNALSYM deflateBound} -{$EXTERNALSYM deflateCopy} -{$EXTERNALSYM deflateEnd} -{$EXTERNALSYM deflateInit_} -{$EXTERNALSYM deflateInit2_} -{$EXTERNALSYM deflateParams} -{$EXTERNALSYM deflatePrime} -{$EXTERNALSYM deflateTune} -{$EXTERNALSYM deflateReset} -{$EXTERNALSYM deflateSetDictionary} -{$EXTERNALSYM inflate} -{$EXTERNALSYM inflateBack} -{$EXTERNALSYM inflateBackEnd} -{$EXTERNALSYM inflateBackInit_} -{$EXTERNALSYM inflateCopy} -{$EXTERNALSYM inflateEnd; external} -{$EXTERNALSYM inflateInit_} -{$EXTERNALSYM inflateInit2_} -{$EXTERNALSYM inflateReset} -{$EXTERNALSYM inflateReset2} -{$EXTERNALSYM inflateSetDictionary} -{$EXTERNALSYM inflateSync} -{$EXTERNALSYM uncompress} -{$EXTERNALSYM zlibCompileFlags} -{$EXTERNALSYM zError} -{$EXTERNALSYM inflateSyncPoint} -{$EXTERNALSYM get_crc_table} -{$EXTERNALSYM inflateUndermine} -{$EXTERNALSYM zlibVersion} -{$EXTERNALSYM deflateSetHeader} -{$EXTERNALSYM inflatePrime} -{$EXTERNALSYM inflateMark} -{$EXTERNALSYM inflateGetHeader} - -{$EXTERNALSYM zlibAllocMem} -{$EXTERNALSYM zlibFreeMem} - -{$IFDEF HAS_UNIT_System_ZLib} - -const - adler32 : function(adler: LongWord; buf: PByte; len: Cardinal): LongWord; cdecl = System.ZLib.adler32; - adler32_combine : function(adler1, adler2: LongWord; len2: z_off_t): LongWord; cdecl = System.ZLib.adler32_combine; - compress : function(dest: PByte; var destLen: LongWord; source: PByte; sourceLen: LongWord): Integer; cdecl = System.ZLib.compress; - compress2 : function(dest: PByte; var destLen: LongWord; source: PByte; sourceLen: LongWord; level: Integer): Integer; cdecl = System.ZLib.compress2; - compressBound : function(sourceLen: LongWord): LongWord; cdecl = System.ZLib.compressBound; - crc32 : function(crc: LongWord; buf: PByte; len: Cardinal): LongWord; cdecl = System.ZLib.crc32; - crc32_combine : function(crc1, crc2: LongWord; len2: z_off_t): LongWord; cdecl = System.ZLib.crc32_combine; - deflate : function(var strm: z_stream; flush: Integer): Integer; cdecl = System.ZLib.deflate; - deflateBound : function(var strm: z_stream; sourceLen: Cardinal): LongWord; cdecl = System.ZLib.deflateBound; - deflateCopy : function(var dest: z_stream; const source: z_stream): Integer; cdecl = System.ZLib.deflateCopy; - deflateEnd : function(var strm: z_stream): Integer; cdecl = System.ZLib.deflateEnd; - deflateInit_ : function(var strm: z_stream; level: Integer; version: ZLibAString; stream_size: Integer): Integer; cdecl = System.ZLib.deflateInit_; - deflateInit2_ : function(var strm: z_stream; level, method, windowBits, memLevel, strategy: Integer; version: ZLibAString; stream_size: Integer): Integer; cdecl = System.ZLib.deflateInit2_; - deflateParams : function(var strm: z_stream; level, strategy: Integer): Integer; cdecl = System.ZLib.deflateParams; - deflatePrime : function(var strm: z_stream; bits, value: Integer): Integer; cdecl = System.ZLib.deflatePrime; - deflateTune : function(var strm: z_stream; good_length, max_lazy, nice_length, max_chain: Integer): Integer; cdecl = System.ZLib.deflateTune; - deflateReset : function(var strm: z_stream): Integer; cdecl = System.ZLib.deflateReset; - deflateSetDictionary : function(var strm: z_stream; dictionary: PByte; dictLength: Cardinal): Integer; cdecl = System.ZLib.deflateSetDictionary; - inflate : function(var strm: z_stream; flush: Integer): Integer; cdecl = System.ZLib.inflate; - inflateBack : function(var strm: z_stream; in_: in_func; in_desc: Pointer; out_: out_func; out_desc: Pointer): Integer; cdecl = System.ZLib.inflateBack; - inflateBackEnd : function(var strm: z_stream): Integer; cdecl = System.ZLib.inflateBackEnd; - inflateBackInit_ : function(var strm: z_stream; windowBits: Integer; window: PByte; version: ZLibAString; stream_size: Integer): Integer; cdecl = System.ZLib.inflateBackInit_; - inflateCopy : function(var dest, source: z_stream): Integer; cdecl = System.ZLib.inflateCopy; - inflateEnd : function(var strm: z_stream): Integer; cdecl = System.ZLib.inflateEnd; - inflateInit_ : function(var strm: z_stream; version: ZLibAString; stream_size: Integer): Integer; cdecl = System.ZLib.inflateInit_; - inflateInit2_ : function(var strm: z_stream; windowBits: Integer; version: ZLibAString; stream_size: Integer): Integer; cdecl = System.ZLib.inflateInit2_; - inflateReset : function(var strm: z_stream): Integer; cdecl = System.ZLib.inflateReset; - inflateReset2 : function(var strm: z_stream; windowBits: Integer): Integer; cdecl = System.ZLib.inflateReset2; - inflateSetDictionary : function(var strm: z_stream; dictionary: PByte; dictLength: Cardinal): Integer; cdecl = System.ZLib.inflateSetDictionary; - inflateSync : function(var strm: z_stream): Integer; cdecl = System.ZLib.inflateSync; - uncompress : function(dest: PByte; var destLen: LongWord; source: PByte; sourceLen: LongWord): Integer; cdecl = System.ZLib.uncompress; - zlibCompileFlags : function: LongWord; cdecl = System.ZLib.zlibCompileFlags; - zError : function(Err: Integer): ZLibAString; cdecl = System.ZLib.zError; - inflateSyncPoint : function(stream: z_streamp): Integer; cdecl = System.ZLib.inflateSyncPoint; - get_crc_table : function: PLongWord; cdecl = System.ZLib.get_crc_table; - inflateUndermine : function(stream: z_streamp; size: Integer): Integer; cdecl = System.ZLib.inflateUndermine; - zlibVersion : function: ZLibAString; cdecl = System.ZLib.zlibVersion; - deflateSetHeader : function(var strm: z_stream; var head: gz_header): Integer; cdecl = System.ZLib.deflateSetHeader; - inflatePrime : function(var strm: z_stream; bits, value: Integer): Integer; cdecl = System.ZLib.inflatePrime; - inflateMark : function(var strm: z_stream): LongInt; cdecl = System.ZLib.inflateMark; - inflateGetHeader : function(var strm: z_stream; var head: gz_header): Integer; cdecl = System.ZLib.inflateGetHeader; - - zlibAllocMem : function(AppData: Pointer; Items, Size: Cardinal): Pointer; cdecl = System.ZLib.zlibAllocMem; - zlibFreeMem : procedure(AppData, Block: Pointer); cdecl = System.ZLib.zlibFreeMem; - -{$ELSE} - -{$IFNDEF STATICLOAD_ZLIB} -type - EIdZLibStubError = class(EIdException) - protected - FError : UInt32; - FErrorMessage : String; - FTitle : String; - public - constructor Build(const ATitle : String; AError : UInt32); - property Error : UInt32 read FError; - property ErrorMessage : String read FErrorMessage; - property Title : String read FTitle; - end; - -type - {$EXTERNALSYM LPN_adler32} - LPN_adler32 = function (adler: TIdC_ULONG; - const buf: PByte; len: TIdC_UINT): TIdC_ULONG; cdecl; - {$EXTERNALSYM LPN_adler32_combine} - LPN_adler32_combine = function (crc1, crc2 : TIdC_ULONG; - len2 : z_off_t) : TIdC_ULONG; cdecl; - {$EXTERNALSYM LPN_compress} - LPN_compress = function (dest: PByte; var destLen: TIdC_ULONG; - const source: PByte; sourceLen: TIdC_ULONG): TIdC_INT;cdecl; - {$EXTERNALSYM LPN_compress2} - LPN_compress2 = function(dest: PByte; var destLen: TIdC_ULONG; - const source: PByte; sourceLen: TIdC_ULONG; - level: TIdC_INT): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_compressBound} - LPN_compressBound = function (sourceLen: TIdC_ULONG): TIdC_ULONG;cdecl; - {$EXTERNALSYM LPN_crc32} - LPN_crc32 = function (crc: TIdC_ULONG; const buf: PByte; - len: TIdC_UINT): TIdC_ULONG; cdecl; - {$EXTERNALSYM LPN_crc32_combine} - LPN_crc32_combine = function (crc1, crc2 : TIdC_ULONG; - len2 : z_off_t) : TIdC_ULONG; cdecl; - {$EXTERNALSYM LPN_deflate} - LPN_deflate = function (var strm: z_stream; flush: TIdC_INT): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_deflateBound} - LPN_deflateBound = function (var strm: z_stream; - sourceLen: TIdC_ULONG): TIdC_ULONG; cdecl; - {$EXTERNALSYM LPN_deflateCopy} - LPN_deflateCopy = function (var dest, source: z_stream): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_deflateEnd} - LPN_deflateEnd = function (var strm: z_stream): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_deflateInit_} - LPN_deflateInit_ = function (var strm: z_stream; level: TIdC_INT; - const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT;cdecl; - {$EXTERNALSYM LPN_deflateInit2_} - LPN_deflateInit2_ = function (var strm: z_stream; - level, method, windowBits, memLevel, strategy: TIdC_INT; - const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT;cdecl; - {$EXTERNALSYM LPN_deflateParams} - LPN_deflateParams = function (var strm: z_stream; level, strategy: TIdC_INT): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_deflatePrime} - LPN_deflatePrime = function (var strm: z_stream; bits, value: TIdC_INT): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_deflateTune} - LPN_deflateTune = function (var strm : z_stream; good_length : TIdC_INT; - max_lazy, nice_length, max_chain : TIdC_INT) : TIdC_INT; cdecl; - {$EXTERNALSYM LPN_deflateReset} - LPN_deflateReset = function (var strm: z_stream): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_deflateSetDictionary} - LPN_deflateSetDictionary = function (var strm: z_stream; const dictionary: PByte; - dictLength: TIdC_UINT): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_inflate} - LPN_inflate = function (var strm: z_stream; flush: TIdC_INT): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_inflateBack} - LPN_inflateBack = function (var strm: z_stream; in_fn: in_func; in_desc: Pointer; - out_fn: out_func; out_desc: Pointer): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_inflateBackEnd} - LPN_inflateBackEnd = function (var strm: z_stream): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_inflateBackInit_} - LPN_inflateBackInit_ = function (var strm: z_stream; - windowBits: TIdC_INT; window: PByte; - const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_inflateCopy} - LPN_inflateCopy = function (var dest, source: z_stream): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_inflateEnd} - LPN_inflateEnd = function (var strm: z_stream): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_inflateInit_} - LPN_inflateInit_ = function (var strm: z_stream; const version: PIdAnsiChar; - stream_size: TIdC_INT): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_inflateInit2_} - LPN_inflateInit2_ = function (var strm: z_stream; windowBits: TIdC_INT; - const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT;cdecl; - {$EXTERNALSYM LPN_inflateReset} - LPN_inflateReset = function (var strm: z_stream): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_inflateReset2} - LPN_inflateReset2 = function (var strm : z_stream; windowBits : TIdC_INT) : TIdC_INT; cdecl; - {$EXTERNALSYM LPN_inflatePrime} - LPN_inflatePrime = function (var strm : z_stream; bits, value : TIdC_INT ) : TIdC_INT; cdecl; - {$EXTERNALSYM LPN_inflateMark} - LPN_inflateMark = function (var strm : z_stream) : TIdC_LONG; cdecl; - {$EXTERNALSYM LPN_inflateSetDictionary} - LPN_inflateSetDictionary = function (var strm: z_stream; const dictionary: PByte; - dictLength: TIdC_UINT): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_inflateSync} - LPN_inflateSync = function (var strm: z_stream): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_uncompress} - LPN_uncompress = function (dest: PByte; var destLen: TIdC_ULONG; - const source: PByte; sourceLen: TIdC_ULONG): TIdC_INT;cdecl; - {$EXTERNALSYM LPN_zlibCompileFlags} - LPN_zlibCompileFlags = function : TIdC_ULONG; cdecl; - {$EXTERNALSYM LPN_zError} - LPN_zError = function (err : TIdC_INT) : PIdAnsiChar; cdecl; - {$EXTERNALSYM LPN_inflateSyncPoint} - LPN_inflateSyncPoint = function (var z : TZStreamRec) : TIdC_INT; cdecl; - {$EXTERNALSYM LPN_get_crc_table} - LPN_get_crc_table = function : PIdC_ULONG; cdecl; - {$EXTERNALSYM LPN_zlibVersion} - LPN_zlibVersion = function : PIdAnsiChar; cdecl; - {$EXTERNALSYM LPN_inflateUndermine} - LPN_inflateUndermine = function (var strm: z_stream; subvert : TIdC_INT ) : TIdC_INT; cdecl; - {$EXTERNALSYM LPN_deflateSetHeader} - LPN_deflateSetHeader = function (var strm: z_stream; var head: gz_header): TIdC_INT; cdecl; - {$EXTERNALSYM LPN_inflateGetHeader} - LPN_inflateGetHeader = function (var strm: z_stream; var head: gz_header): TIdC_INT; cdecl; - -{Vars} -var - adler32 : LPN_adler32 = nil; - adler32_combine : LPN_adler32_combine = nil; - compress : LPN_compress = nil; - compress2 : LPN_compress2 = nil; - compressBound : LPN_compressBound = nil; - crc32 : LPN_crc32 = nil; - crc32_combine : LPN_crc32_combine = nil; - deflate : LPN_deflate = nil; - deflateBound : LPN_deflateBound = nil; - deflateCopy : LPN_deflateCopy = nil; - deflateEnd : LPN_deflateEnd = nil; - deflateInit_ : LPN_deflateInit_ = nil; - deflateInit2_ : LPN_deflateInit2_ = nil; - deflateParams : LPN_deflateParams = nil; - - deflatePrime :LPN_deflatePrime = nil; - deflateTune : LPN_deflateTune = nil; - deflateReset : LPN_deflateReset = nil; - deflateSetDictionary : LPN_deflateSetDictionary = nil; - inflate : LPN_inflate = nil; - inflateBack : LPN_inflateBack = nil; - inflateBackEnd : LPN_inflateBackEnd = nil; - inflateEnd : LPN_inflateEnd = nil; - inflateBackInit_ : LPN_inflateBackInit_ = nil; - inflateCopy : LPN_inflateCopy = nil; - inflateInit_ : LPN_inflateInit_ = nil; - inflateInit2_ : LPN_inflateInit2_ = nil; - inflateReset : LPN_inflateReset = nil; - - inflateReset2 : LPN_inflateReset2 = nil; - inflatePrime : LPN_inflatePrime = nil; - inflateMark : LPN_inflateMark = nil; - - inflateSetDictionary : LPN_inflateSetDictionary = nil; - inflateSync : LPN_inflateSync = nil; - uncompress : LPN_uncompress = nil; - zlibCompileFlags : LPN_zlibCompileFlags = nil; - zError : LPN_zError = nil; - inflateSyncPoint : LPN_inflateSyncPoint = nil; - get_crc_table : LPN_get_crc_table = nil; - inflateUndermine : LPN_inflateUndermine = nil; - zlibVersion : LPN_zlibVersion = nil; - deflateSetHeader : LPN_deflateSetHeader = nil; - inflateGetHeader : LPN_inflateGetHeader = nil; - -procedure IdZLibSetLibPath(const APath: String); - -{$ELSE} - -(* basic functions *) -function zlibVersion: PIdAnsiChar; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} - -function deflate(var strm: z_stream; flush: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function deflateEnd(var strm: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} - -function inflate(var strm: z_stream; flush: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflateEnd(var strm: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} - -(* advanced functions *) - -function deflateSetDictionary(var strm: z_stream; const dictionary: PByte; - dictLength: TIdC_UINT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function deflateCopy(var dest, source: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function deflateReset(var strm: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function deflateParams(var strm: z_stream; level, strategy: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -{JPM Addition} -function deflateTune(var strm : z_stream; good_length : TIdC_INT; - max_lazy, nice_length, max_chain : TIdC_INT) : TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function deflateBound(var strm: z_stream; - sourceLen: TIdC_ULONG): TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function deflatePrime(var strm: z_stream; bits, value: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} - -function inflateSetDictionary(var strm: z_stream; const dictionary: PByte; - dictLength: TIdC_UINT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflateSync(var strm: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflateCopy(var dest, source: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflateReset(var strm: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflateReset2(var strm : z_stream; windowBits : TIdC_INT) : TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflatePrime(var strm : z_stream; bits, value : TIdC_INT ) : TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflateMark(var strm : z_stream) : TIdC_LONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer; - out_fn: out_func; out_desc: Pointer): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflateBackEnd(var strm: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} - -function zlibCompileFlags: TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} - -{JPM Additional functions} -function zError (err : TIdC_INT) : PIdAnsiChar; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflateSyncPoint(var z : TZStreamRec) : TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -//const uLongf * get_crc_table (void); -function inflateUndermine(var strm: z_stream; subvert : TIdC_INT ) : TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} - -function get_crc_table : PIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -{end JPM additions} - -(* utility functions *) -function compress(dest: PByte; var destLen: TIdC_ULONG; - const source: PByte; sourceLen: TIdC_ULONG): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function compress2(dest: PByte; var destLen: TIdC_ULONG; - const source: PByte; sourceLen: TIdC_ULONG; - level: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function compressBound(sourceLen: TIdC_ULONG): TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function uncompress(dest: PByte; var destLen: TIdC_ULONG; - const source: PByte; sourceLen: TIdC_ULONG): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} - -(* checksum functions *) -function adler32(adler: TIdC_ULONG; - const buf: PByte; len: TIdC_UINT): TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function adler32_combine(crc1, crc2 : TIdC_ULONG; len2 : z_off_t) : TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function crc32(crc: TIdC_ULONG; const buf: PByte; - len: TIdC_UINT): TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function crc32_combine(crc1, crc2 : TIdC_ULONG; len2 : z_off_t) : TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -(* various hacks, don't look :) *) -function deflateInit_(var strm: z_stream; level: TIdC_INT; - const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflateInit_(var strm: z_stream; const version: PIdAnsiChar; - stream_size: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function deflateInit2_(var strm: z_stream; - level, method, windowBits, memLevel, strategy: TIdC_INT; - const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflateInit2_(var strm: z_stream; windowBits: TIdC_INT; - const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflateBackInit_(var strm: z_stream; - windowBits: TIdC_INT; window: PByte; - const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} - -function deflateSetHeader(var strm: z_stream; var head: gz_header): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -function inflateGetHeader(var strm: z_stream; var head: gz_header): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} -{$ENDIF} - -function zlibAllocMem(AppData: Pointer; Items, Size: TIdC_UINT): Pointer; cdecl; -procedure zlibFreeMem(AppData, Block: Pointer); cdecl; - -{$ENDIF} - -{$EXTERNALSYM Load} -function Load : Boolean; -{$EXTERNALSYM Unload} -procedure Unload; -{$EXTERNALSYM Loaded} -function Loaded : Boolean; - -{minor additional helper functions} -{$EXTERNALSYM _malloc} -function _malloc(Size: Integer): Pointer; cdecl; -{$EXTERNALSYM _free} -procedure _free(Block: Pointer); cdecl; -{$EXTERNALSYM _memset} -procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl; -{$EXTERNALSYM _memcpy} -procedure _memcpy(dest, source: Pointer; count: Integer); cdecl; - -implementation - -{$IFNDEF HAS_UNIT_System_ZLib} - -uses - SysUtils - {$IFNDEF STATICLOAD_ZLIB} - , IdZLibConst - {$IFDEF KYLIXCOMPAT} - , libc - {$ENDIF} - {$IFDEF FPC} - , DynLibs // better add DynLibs only for fpc - {$ENDIF} - {$IFDEF WINDOWS} - , Windows - {$ENDIF} - {$ELSE} - {$IFDEF VCL_XE2_OR_ABOVE} - , System.Win.Crtl {$NOINCLUDE System.Win.Crtl} - {$ENDIF} - {$ENDIF}; - -{$IFDEF STATICLOAD_ZLIB} -{$IFNDEF VCL_XE2_OR_ABOVE} - {$L adler32.obj} - {$L compress.obj} - {$L crc32.obj} - {$L deflate.obj} - {$L infback.obj} - {$L inffast.obj} - {$L inflate.obj} - {$L inftrees.obj} - {$L trees.obj} - {$L uncompr.obj} - {$L zutil.obj} -{$ELSE} - {$IFDEF WIN32} - {$L ZLib\i386-Win32-ZLib\zlibudec.obj} // undecorated stubs which are not needed for x64 compilation - {$L ZLib\i386-Win32-ZLib\deflate.obj} - {$L ZLib\i386-Win32-ZLib\inflate.obj} - {$L ZLib\i386-Win32-ZLib\infback.obj} - {$L ZLib\i386-Win32-ZLib\inffast.obj} - {$L ZLib\i386-Win32-ZLib\inftrees.obj} - {$L ZLib\i386-Win32-ZLib\trees.obj} - {$L ZLib\i386-Win32-ZLib\compress.obj} - {$L ZLib\i386-Win32-ZLib\uncompr.obj} - {$L ZLib\i386-Win32-ZLib\adler32.obj} - {$L ZLib\i386-Win32-ZLib\crc32.obj} - {$L ZLib\i386-Win32-ZLib\zutil.obj} - {$L ZLib\i386-Win32-ZLib\gzclose.obj} - {$L ZLib\i386-Win32-ZLib\gzread.obj} - {$L ZLib\i386-Win32-ZLib\gzwrite.obj} - {$L ZLib\i386-Win32-ZLib\gzlib.obj} - {$ENDIF} - {$IFDEF WIN64} - {$L ZLib\x86_64-Win64-ZLib\deflate.obj} - {$L ZLib\x86_64-Win64-ZLib\inflate.obj} - {$L ZLib\x86_64-Win64-ZLib\infback.obj} - {$L ZLib\x86_64-Win64-ZLib\inffast.obj} - {$L ZLib\x86_64-Win64-ZLib\inftrees.obj} - {$L ZLib\x86_64-Win64-ZLib\trees.obj} - {$L ZLib\x86_64-Win64-ZLib\compress.obj} - {$L ZLib\x86_64-Win64-ZLib\uncompr.obj} - {$L ZLib\x86_64-Win64-ZLib\adler32.obj} - {$L ZLib\x86_64-Win64-ZLib\crc32.obj} - {$L ZLib\x86_64-Win64-ZLib\zutil.obj} - {$L ZLib\x86_64-Win64-ZLib\gzclose.obj} - {$L ZLib\x86_64-Win64-ZLib\gzread.obj} - {$L ZLib\x86_64-Win64-ZLib\gzwrite.obj} - {$L ZLib\x86_64-Win64-ZLib\gzlib.obj} - {$ENDIF} -{$ENDIF} - -function adler32; external; -function adler32_combine; external; -function compress; external; -function compress2; external; -function compressBound; external; -function crc32; external; -function crc32_combine; external; -function deflate; external; -function deflateBound; external; -function deflateCopy; external; -function deflateEnd; external; -function deflateInit_; external; -function deflateInit2_; external; -function deflateParams; external; -function deflatePrime; external; -function deflateTune; external; -function deflateReset; external; -function deflateSetDictionary; external; -function inflate; external; -function inflateBack; external; -function inflateBackEnd; external; -function inflateBackInit_; external; -function inflateCopy; external; -function inflateEnd; external; -function inflateInit_; external; -function inflateInit2_; external; -function inflateReset; external; -function inflateReset2; external; -function inflateSetDictionary; external; -function inflateSync; external; -function uncompress; external; -function zlibCompileFlags; external; -function zError; external; -function inflateSyncPoint; external; -function get_crc_table; external; -function inflateUndermine; external; -function zlibVersion; external; -function deflateSetHeader; external; -function inflatePrime; external; -function inflateMark; external; -function inflateGetHeader; external; -{$ELSE} -var - hZLib: TIdLibHandle = IdNilHandle; - - {$IFDEF UNIX} -const - //The extensions will be resolved by IdGlobal.HackLoad - //This is a little messy because symbolic links to libraries may not always be the same - //in various Unix types. Even then, there could possibly be differences. - libzlib = 'libz'; - // TODO: setup this array more like the SSLDLLVers arrays in the IdSSLOpenSSLHeaders unit... - libvers : array [0..3] of string = ('.1','','.3','.2'); - {$ENDIF} - {$IFDEF NETWARE} {zlib.nlm comes with netware6} -const - libzlib = 'zlib'; - {$ENDIF} - //Do not use IFDEF WINDOWS because that may catch WindowsCE. - {$IFDEF WIN32} - //Note that this is not an official ZLIB .DLL. It was created by running - //CMake in Visual Studio 2022. -const - libzlib = 'zlib.dll'; - {$ENDIF} - {$IFDEF WIN64} - //Note that this is not an official ZLIB .DLL. It was created by running - //CMake in Visual Studio 2022. -const - libzlib = 'zlib.dll'; - {$ENDIF} - {$IFDEF WINCE} - //Note that zlibce can be found at http://www.tenik.co.jp/~adachi/wince/zlibce/ -const - libzlib = 'zlibce'; - {$ENDIF} - -constructor EIdZLibStubError.Build(const ATitle : String; AError : UInt32); -begin - FTitle := ATitle; - FError := AError; - if AError = 0 then begin - inherited Create(ATitle); - end else begin - FErrorMessage := SysUtils.SysErrorMessage(AError); - inherited Create(ATitle + ': ' + FErrorMessage); {Do not Localize} - end; -end; - -function FixupStub(const AName: TIdLibFuncName): Pointer; -begin - if hZLib = IdNilHandle then begin - if not Load then begin - raise EIdZLibStubError.Build(Format(RSZLibCallError, [AName]), 0); - end; - end; - Result := LoadLibFunction(hZLib, AName); - if Result = nil then begin - raise EIdZLibStubError.Build(Format(RSZLibCallError, [AName]), 10022); - end; -end; - -function stub_adler32(adler: TIdC_ULONG; const buf: PByte; - len: TIdC_UINT): TIdC_ULONG; cdecl; -begin - adler32 := FixupStub('adler32'); {Do not Localize} - Result := adler32(adler, buf, len); -end; - -function stub_adler32_combine (crc1, crc2 : TIdC_ULONG; - len2 : z_off_t) : TIdC_ULONG; cdecl; -begin - adler32_combine := FixupStub('adler32_combine'); {Do not Localize} - Result := adler32_combine(crc1, crc2, len2); -end; - -function stub_compress(dest: PByte; var destLen: TIdC_ULONG; - const source: PByte; sourceLen: TIdC_ULONG): TIdC_INT; cdecl; -begin - compress := FixupStub('compress'); {Do not Localize} - Result := compress(dest,destLen,source,sourceLen); -end; - -function stub_compress2(dest: PByte; var destLen: TIdC_ULONG; - const source: PByte; sourceLen: TIdC_ULONG; - level: TIdC_INT): TIdC_INT; cdecl; -begin - compress2 := FixupStub('compress2'); {Do not Localize} - Result := compress2(dest, destLen, source, sourceLen, level); -end; - - -function stub_compressBound(sourceLen: TIdC_ULONG): TIdC_ULONG; cdecl; -begin - compressBound := FixupStub('compressBound'); {Do not Localize} - Result := compressBound(sourcelen); -end; - -function stub_crc32(crc: TIdC_ULONG; const buf: PByte; - len: TIdC_UINT): TIdC_ULONG; cdecl; -begin - crc32 := FixupStub('crc32'); {Do not Localize} - Result := crc32(crc, buf, len); -end; - -function stub_crc32_combine (crc1, crc2 : TIdC_ULONG; - len2 : z_off_t) : TIdC_ULONG; cdecl; -begin - crc32_combine := FixupStub('crc32_combine'); {Do not Localize} - Result := crc32_combine(crc1, crc2, len2); -end; - -function stub_deflate(var strm: z_stream; flush: TIdC_INT): TIdC_INT; cdecl; -begin - deflate := FixupStub('deflate'); {Do not Localize} - Result := deflate(strm, flush); -end; - -function stub_deflateBound(var strm: z_stream; - sourceLen: TIdC_ULONG): TIdC_ULONG; cdecl; -begin - deflateBound := FixupStub('deflateBound'); {Do not Localize} - Result := deflateBound(strm, sourceLen); -end; - -function stub_deflateCopy(var dest, source: z_stream): TIdC_INT; cdecl; -begin - deflateCopy := FixupStub('deflateCopy'); {Do not Localize} - Result := deflateCopy(dest, source); -end; - -function stub_deflateEnd(var strm: z_stream): TIdC_INT; cdecl; -begin - deflateEnd := FixupStub('deflateEnd'); {Do not Localize} - Result := deflateEnd(strm); -end; - -function stub_deflateInit_(var strm: z_stream; level: TIdC_INT; - const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT;cdecl; -begin - deflateInit_ := FixupStub('deflateInit_'); {Do not Localize} - Result := deflateInit_(strm, level, version, stream_size); -end; - -function stub_deflateInit2_(var strm: z_stream; - level, method, windowBits, memLevel, strategy: TIdC_INT; - const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT;cdecl; -begin - deflateInit2_ := FixupStub('deflateInit2_'); {Do not Localize} - Result := deflateInit2_(strm,level, method, windowBits, memLevel, strategy, - version, stream_size); -end; - -function stub_deflateParams (var strm: z_stream; level, strategy: TIdC_INT): TIdC_INT; cdecl; -begin - deflateParams := FixupStub('deflateParams'); {Do not Localize} - Result := deflateParams (strm, level, strategy); -end; - -function stub_deflatePrime (var strm: z_stream; bits, value: TIdC_INT): TIdC_INT; cdecl; -begin - deflatePrime := FixupStub('deflatePrime'); {Do not Localize} - Result := deflateParams (strm, bits, value); -end; - -function stub_deflateTune(var strm : z_stream; good_length : TIdC_INT; - max_lazy, nice_length, max_chain : TIdC_INT) : TIdC_INT; cdecl; -begin - deflateTune := FixupStub('deflateTune'); {Do not Localize} - Result := deflateTune(strm, good_length, max_lazy, nice_length, max_chain) ; -end; - -function stub_deflateReset (var strm: z_stream): TIdC_INT; cdecl; -begin - deflateReset := FixupStub('deflateReset'); {Do not Localize} - Result := deflateReset(strm); -end; - -function stub_deflateSetDictionary(var strm: z_stream; const dictionary: PByte; - dictLength: TIdC_UINT): TIdC_INT; cdecl; -begin - deflateSetDictionary := FixupStub('deflateSetDictionary'); {Do not Localize} - Result := deflateSetDictionary(strm, dictionary, dictLength); -end; - -function stub_inflate(var strm: z_stream; flush: TIdC_INT): TIdC_INT; cdecl; -begin - inflate := FixupStub('inflate'); {Do not Localize} - Result := inflate(strm, flush); -end; - -function stub_inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer; - out_fn: out_func; out_desc: Pointer): TIdC_INT; cdecl; -begin - inflateBack := FixupStub('inflateBack'); {Do not Localize} - Result := inflateBack(strm, in_fn, in_desc, out_fn, out_desc); -end; - -function stub_inflateBackEnd(var strm: z_stream): TIdC_INT; cdecl; -begin - inflateBackEnd := FixupStub('inflateBackEnd'); {Do not Localize} - Result := inflateBackEnd(strm); -end; - -function stub_inflateEnd(var strm: z_stream): TIdC_INT; cdecl; -begin - inflateEnd := FixupStub('inflateEnd'); {Do not Localize} - Result := inflateEnd(strm); -end; - -function stub_inflateBackInit_(var strm: z_stream; - windowBits: TIdC_INT; window: PByte; - const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT; cdecl; -begin - inflateBackInit_ := FixupStub('inflateBackInit_'); {Do not Localize} - Result := inflateBackInit_(strm, windowBits, window, version, stream_size); -end; - -function stub_inflateInit2_(var strm: z_stream; windowBits: TIdC_INT; - const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT;cdecl; -begin - inflateInit2_ := FixupStub('inflateInit2_'); {Do not Localize} - Result := inflateInit2_(strm, windowBits, version, stream_size); -end; - -function stub_inflateCopy(var dest, source: z_stream): TIdC_INT; cdecl; -begin - inflateCopy := FixupStub('inflateCopy'); {Do not Localize} - Result := inflateCopy(dest, source); -end; - - -function stub_inflateInit_(var strm: z_stream; const version: PIdAnsiChar; - stream_size: TIdC_INT): TIdC_INT; cdecl; -begin - inflateInit_ := FixupStub('inflateInit_'); {Do not Localize} - Result := inflateInit_(strm, version, stream_size); -end; - -function stub_inflateReset(var strm: z_stream): TIdC_INT; cdecl; -begin - inflateReset := FixupStub('inflateReset'); {Do not Localize} - Result := inflateReset(strm); -end; - -function stub_inflateReset2(var strm : z_stream; windowBits : TIdC_INT) : TIdC_INT; cdecl; -begin - inflateReset2 := FixupStub('inflateReset2'); {Do not Localize} - Result := inflateReset2(strm, windowBits); -end; - -function stub_inflatePrime(var strm : z_stream; bits, value : TIdC_INT ) : TIdC_INT; cdecl; -begin - inflatePrime := FixupStub('inflatePrime'); {Do not Localize} - Result := inflatePrime(strm, bits, value); -end; - -function stub_inflateMark(var strm : z_stream) : TIdC_LONG; cdecl; -begin - inflateMark := FixupStub('inflateMark'); {Do not Localize} - Result := inflateMark(strm); -end; - -function stub_inflateSetDictionary(var strm: z_stream; const dictionary: PByte; - dictLength: TIdC_UINT): TIdC_INT;cdecl; -begin - inflateSetDictionary := FixupStub('inflateSetDictionary'); {Do not Localize} - Result := inflateSetDictionary(strm, dictionary, dictLength); -end; - -function stub_inflateSync(var strm: z_stream): TIdC_INT; cdecl; -begin - inflateSync := FixupStub('inflateSync'); {Do not Localize} - Result := inflateSync(strm); -end; - -function stub_uncompress (dest: PByte; var destLen: TIdC_ULONG; - const source: PByte; sourceLen: TIdC_ULONG): TIdC_INT;cdecl; -begin - uncompress := FixupStub('uncompress'); {Do not Localize} - Result := uncompress (dest, destLen, source, sourceLen); -end; - -function stub_zlibCompileFlags : TIdC_ULONG; cdecl; -begin - zlibCompileFlags := FixupStub('zlibCompileFlags'); {Do not Localize} - Result := zlibCompileFlags; -end; - -function stub_zError(err : TIdC_INT) : PIdAnsiChar; cdecl; -begin - zError := FixupStub('zError'); {Do not Localize} - Result := zError(err); -end; - -function stub_inflateSyncPoint(var z : TZStreamRec) : TIdC_INT; cdecl; -begin - inflateSyncPoint := FixupStub('inflateSyncPoint'); {Do not Localize} - Result := inflateSyncPoint(z); -end; - -function stub_get_crc_table : PIdC_ULONG; cdecl; -begin - get_crc_table := FixupStub('get_crc_table'); {Do not Localize} - Result := get_crc_table; -end; - -function stub_inflateUndermine(var strm: z_stream; subvert : TIdC_INT ) : TIdC_INT; cdecl; -begin - inflateUndermine := FixupStub('inflateUndermine'); {Do not Localize} - Result := inflateUndermine(strm,subvert); -end; - -function stub_zlibVersion : PIdAnsiChar; cdecl; -begin - Result := ''; - zlibVersion := FixupStub('zlibVersion'); {Do not Localize} - if Assigned(zlibVersion) then begin - Result := zlibVersion; - end; -end; - -function stub_deflateSetHeader(var strm: z_stream; var head: gz_header): TIdC_INT; cdecl; -begin - deflateSetHeader := FixupStub('deflateSetHeader'); {Do not Localize} - Result := deflateSetHeader(strm, head); -end; - -function stub_inflateGetHeader(var strm: z_stream; var head: gz_header): TIdC_INT; cdecl; -begin - inflateGetHeader := FixupStub('inflateGetHeader'); {Do not Localize} - Result := inflateGetHeader(strm, head); -end; - -procedure InitializeStubs; -begin - adler32 := stub_adler32; - adler32_combine := stub_adler32_combine; - compress := stub_compress; - compress2 := stub_compress2; - compressBound := stub_compressBound; - crc32 := stub_crc32; - crc32_combine := stub_crc32_combine; - deflate := stub_deflate; - deflateBound := stub_deflateBound; - deflateCopy := stub_deflateCopy; - deflateEnd := stub_deflateEnd; - deflateInit_ := stub_deflateInit_; - deflateInit2_ := stub_deflateInit2_; - deflateParams := stub_deflateParams; - deflatePrime := stub_deflatePrime; - deflateTune := stub_deflateTune; - deflateReset := stub_deflateReset; - deflateSetDictionary := stub_deflateSetDictionary; - inflate := stub_inflate; - inflateBack := stub_inflateBack; - inflateBackEnd := stub_inflateBackEnd; - inflateBackInit_ := stub_inflateBackInit_; - inflateCopy := stub_inflateCopy; - inflateEnd := stub_inflateEnd; - inflateInit_ := stub_inflateInit_; - inflateInit2_ := stub_inflateInit2_; - inflateReset := stub_inflateReset; - inflateReset2 := stub_inflateReset2; - inflatePrime := stub_inflatePrime; - inflateMark := stub_inflateMark; - - inflateSetDictionary := stub_inflateSetDictionary; - inflateSync := stub_inflateSync; - uncompress := stub_uncompress; - zlibCompileFlags := stub_zlibCompileFlags; - zError := stub_zError; - inflateUndermine := stub_inflateUndermine; - inflateSyncPoint := stub_inflateSyncPoint; - - get_crc_table := stub_get_crc_table; - zlibVersion := stub_zlibVersion; - deflateSetHeader := stub_deflateSetHeader; - inflateGetHeader := stub_inflateGetHeader; -end; -{$ENDIF} - -{$ENDIF} - -function deflateInit(var strm: z_stream; level: TIdC_INT): TIdC_INT; -begin - {$IFDEF HAS_UNIT_System_ZLib} - Result := System.ZLib.deflateInit(strm, level); - {$ELSE} - // if not Assigned(strm.zalloc) then strm.zalloc := zlibAllocMem; - // if not Assigned(strm.zfree) then strm.zfree := zlibFreeMem; - Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream)); - {$ENDIF} -end; - -function deflateInit2(var strm: z_stream; level, method, windowBits, - memLevel, strategy: TIdC_INT): TIdC_INT; -begin - {$IFDEF HAS_UNIT_System_ZLib} - Result := System.ZLib.deflateInit2(strm, level, method, windowBits, memLevel, strategy); - {$ELSE} - // if not Assigned(strm.zalloc) then strm.zalloc := zlibAllocMem; - // if not Assigned(strm.zfree) then strm.zfree := zlibFreeMem; - Result := deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - ZLIB_VERSION, sizeof(z_stream)); - {$ENDIF} -end; - -const - WBits : array[TZStreamType] of TIdC_INT = (MAX_WBITS, MAX_WBITS + 16, -MAX_WBITS); - -function deflateInitEx(var strm: z_stream; level: TIdC_INT; streamtype: TZStreamType = zsZLib): TIdC_INT; -begin - {$IFDEF HAS_UNIT_System_ZLib} - Result := System.ZLib.deflateInit2(strm, level, Z_DEFLATED, WBits[streamtype], - MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); - {$ELSE} - Result := deflateInit2(strm, level, Z_DEFLATED, WBits[streamtype], - MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); - {$ENDIF} -end; - -function inflateInitEx(var strm: z_stream; streamtype: TZStreamType = zsZLib): TIdC_INT; -begin - {$IFDEF HAS_UNIT_System_ZLib} - Result := System.ZLib.inflateInit2(strm, WBits[streamtype]); - {$ELSE} - Result := inflateInit2(strm, WBits[streamtype]); - {$ENDIF} -end; - -function inflateInit(var strm: z_stream): TIdC_INT; -begin - {$IFDEF HAS_UNIT_System_ZLib} - Result := System.ZLib.inflateInit(strm); - {$ELSE} - // if not Assigned(strm.zalloc) then strm.zalloc := zlibAllocMem; - // if not Assigned(strm.zfree) then strm.zfree := zlibFreeMem; - Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream)); - {$ENDIF} -end; - -function inflateInit2(var strm: z_stream; windowBits: TIdC_INT): TIdC_INT; -begin - // RLebeau: System.ZLib.inflateInit2() simply calls ZLib's inflateInit2_(), - // so I'm not sure how the stream's zalloc and zfree fields are initialized. - // Since we were explicitly initializing them before, let's keep doing so - // for now, unless told otherwise... - if not Assigned(strm.zalloc) then begin - strm.zalloc := zlibAllocMem; - end; - if not Assigned(strm.zfree) then begin - strm.zfree := zlibFreeMem; - end; - {$IFDEF HAS_UNIT_System_ZLib} - Result := System.ZLib.inflateInit2(strm, windowBits); - {$ELSE} - Result := inflateInit2_(strm, windowBits, ZLIB_VERSION, SizeOf(z_stream)); - {$ENDIF} -end; - -function inflateBackInit(var strm: z_stream; windowBits: TIdC_INT; - window: PByte): TIdC_INT; -begin - {$IFDEF HAS_UNIT_System_ZLib} - Result := System.ZLib.inflateBackInit(strm, windowBits, window); - {$ELSE} - Result := inflateBackInit_(strm, windowBits, window, ZLIB_VERSION, SizeOf(z_stream)); - {$ENDIF} -end; - - -{minor additional helper functions} -function _malloc(Size: Integer): Pointer; cdecl; -begin - GetMem(Result, Size); -end; - -procedure _free(Block: Pointer); cdecl; -begin - FreeMem(Block); -end; - -procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl; -begin - FillChar(P^, count, B); -end; - -procedure _memcpy(dest, source: Pointer; count: Integer); cdecl; -begin - Move(source^, dest^, count); -end; - -{$IFNDEF HAS_UNIT_System_ZLib} -function zlibAllocMem(AppData: Pointer; Items, Size: TIdC_UINT): Pointer; cdecl; -begin - GetMem(Result, Items*Size); -// Result := AllocMem(Items * Size); -end; - -procedure zlibFreeMem(AppData, Block: Pointer); cdecl; -begin - FreeMem(Block); -end; -{$ENDIF} - -{$IFDEF STATICLOAD_ZLIB} -function Load : Boolean; -begin - Result := True; -end; - -procedure Unload; -begin -end; - -function Loaded : Boolean; -begin - Result := True; -end; -{$ELSE} - -var - GIdZLibPath: String = ''; - -procedure IdZLibSetLibPath(const APath: String); -begin - if APath <> '' then begin - GIdZLibPath := IndyIncludeTrailingPathDelimiter(APath); - end else begin - GIdZLibPath := ''; - end; -end; - -function Load : Boolean; -begin - Result := Loaded; - if not Result then begin - //In Windows, you should use SafeLoadLibrary instead of the LoadLibrary API - //call because LoadLibrary messes with the FPU control word. - {$IFDEF WINDOWS} - hZLib := SafeLoadLibrary(GIdZLibPath + libzlib); - {$ELSE} - {$IFDEF UNIX} - hZLib := HackLoad(GIdZLibPath + libzlib, libvers); - {$ELSE} - hZLib := LoadLibrary(GIdZLibPath + libzlib); - {$IFDEF USE_INVALIDATE_MOD_CACHE} - InvalidateModuleCache; - {$ENDIF} - {$ENDIF} - {$ENDIF} - Result := Loaded; - end; -end; - -procedure Unload; -begin - if Loaded then begin - FreeLibrary(hZLib); - {$IFDEF DELPHI_CROSS} - InvalidateModuleCache; - {$ENDIF} - hZLib := IdNilHandle; - InitializeStubs; - end; -end; - -function Loaded : Boolean; -begin - Result := (hZLib <> IdNilHandle); -end; -{$ENDIF} - -{$IFNDEF STATICLOAD_ZLIB} -initialization - InitializeStubs; - -finalization - Unload; - InitializeStubs; -{$ENDIF} - -end. +unit IdZLibHeaders; + +{ + zlibpas -- Pascal interface to the zlib data compression library + * Gabriel Corneanu (gabrielcorneanu(AT)yahoo.com) + Derived from original sources by Bob Dellaca and Cosmin Truta. + - TZStreamType + - deflateInitEx + - inflateInitEx +*} +{ +JPM - note that I made dynamic loading for FreePascal (since that still may not +suppport external .obj files properly. It also makes it easier to support several +different platforms in one file. +} + +interface + +{$I IdCompilerDefines.inc} + +{$WRITEABLECONST OFF} + +{$IFDEF HAS_UNIT_System_ZLib} + + {$DEFINE STATICLOAD_ZLIB} + +{$ELSE} +{ +TODO: Wait for Emb to decide how to approach ZLib for their 64-bit support +before we proceed at our end. +} +{$UNDEF STATICLOAD_ZLIB} +{$UNDEF STATIC_CDECL_PROCS} +{$IFDEF DCC} + {$IFDEF WIN32} +{ +For Win32, we use some .obj files. These .objs were compiled from the ZLib +source-code folder with "make -f contrib\delphi\zlibd32.mak" using Borland's +"make" and "bcc32". The .objs are compiled with the +"-DZEXPORT=__fastcall -DZEXPORTVA=__cdecl" parameter. Do NOT change +the function calling conventions unless you know what you are doing and +the C++ objects are compiled appropriately. + +The only things that still are cdecl are the callback functions. +} + {$IFNDEF BCB5_DUMMY_BUILD} + {$DEFINE STATICLOAD_ZLIB} + {$IFDEF VCL_XE2_OR_ABOVE} + {$DEFINE STATIC_CDECL_PROCS} + {$ENDIF} + {$ENDIF} + {$ALIGN OFF} + {$ENDIF} + {$IFDEF WIN64} + {$ALIGN ON} + {$MINENUMSIZE 4} + {$IFNDEF BCB5_DUMMY_BUILD} + {$DEFINE STATICLOAD_ZLIB} + {$ENDIF} + {$ENDIF} +{$ELSE} + {$packrecords C} +{$ENDIF} + +{$ENDIF} + +uses + {$IFDEF HAS_UNIT_System_ZLib} + System.ZLib, + IdCTypes; + {$ELSE} + //reference off_t + {$IFDEF USE_VCL_POSIX} + Posix.SysTypes, + {$ENDIF} + {$IFDEF KYLIXCOMPAT} + libc, + {$ENDIF} + {$IFDEF USE_BASEUNIX} + baseunix, + {$ENDIF} + IdGlobal, IdCTypes + {$IFNDEF STATICLOAD_ZLIB} + , IdException + {$ENDIF}; + {$ENDIF} + +{$IFNDEF HAS_UNIT_System_ZLib} + +{$DEFINE USE_PRAGMA_PACK_1} +{$IFDEF LINUX64} + {$UNDEF USE_PRAGMA_PACK_1} +{$ENDIF} +{$IFDEF IOS64} + {$UNDEF USE_PRAGMA_PACK_1} +{$ENDIF} + +{$IFDEF STATICLOAD_ZLIB} +(*$HPPEMIT '// For Win32, we use some .obj files. These .objs were compiled from the ZLib'*) +(*$HPPEMIT '// source-code folder with "make -f contrib\delphi\zlibd32.mak" using Borland's'*) +(*$HPPEMIT '// "make" and "bcc32". The .objs are compiled with the'*) +(*$HPPEMIT '// "-DZEXPORT=__fastcall -DZEXPORTVA=__cdecl" parameter. Do NOT change'*) +(*$HPPEMIT '// the function calling conventions unless you know what you are doing and'*) +(*$HPPEMIT '// the C++ objects are compiled appropriately.'*) +(*$HPPEMIT '//'*) +(*$HPPEMIT '// The only things that still are cdecl are the callback functions.'*) +(*$HPPEMIT ''*) + {$IFDEF STATIC_CDECL_PROCS} +(*$HPPEMIT '#define ZEXPORT __cdecl'*) + {$ELSE} +(*$HPPEMIT '#define ZEXPORT __fastcall'*) + {$ENDIF} +{$ELSE} +(*$HPPEMIT '#define ZEXPORT __cdecl'*) +{$ENDIF} +(*$HPPEMIT '#define ZEXPORTVA __cdecl'*) +(*$HPPEMIT '#if !defined(__MACTYPES__)'*) +(*$HPPEMIT ' // We are defining __MACTYPES__ in order to skip the declaration of "Byte" as it causes'*) +(*$HPPEMIT ' // ambiguity with System::Byte'*) +(*$HPPEMIT ' #define __MACTYPES__'*) +(*$HPPEMIT ' #define __REMOVE_MACTYPES__'*) +(*$HPPEMIT '#endif'*) +(*$HPPEMIT '#if defined(__USE_ZLIBH__)'*) +(*$HPPEMIT ' #include "ZLib\zlib.h"'*) +(*$HPPEMIT '#else'*) +(*$HPPEMIT 'typedef void * __cdecl (*alloc_func)(void * opaque, unsigned items, unsigned size);'*) +(*$HPPEMIT ''*) +(*$HPPEMIT 'typedef void __cdecl (*free_func)(void * opaque, void * address);'*) +(*$HPPEMIT ''*) +{$IFDEF USE_PRAGMA_PACK_1} +(*$HPPEMIT '#pragma pack(push,1)'*) +{$ENDIF} +{$IFDEF VCL_XE_OR_ABOVE} +(*$HPPEMIT 'struct DECLSPEC_DRECORD z_stream'*) +{$ELSE} +(*$HPPEMIT 'struct z_stream'*) +{$ENDIF} +(*$HPPEMIT '{'*) +(*$HPPEMIT ' '*) +(*$HPPEMIT 'public:'*) +(*$HPPEMIT ' char *next_in;'*) +(*$HPPEMIT ' unsigned avail_in;'*) +(*$HPPEMIT ' unsigned long total_in;'*) +(*$HPPEMIT ' char *next_out;'*) +(*$HPPEMIT ' unsigned avail_out;'*) +(*$HPPEMIT ' unsigned long total_out;'*) +(*$HPPEMIT ' char *msg;'*) +(*$HPPEMIT ' void *state;'*) +(*$HPPEMIT ' alloc_func zalloc;'*) +(*$HPPEMIT ' free_func zfree;'*) +(*$HPPEMIT ' void *opaque;'*) +(*$HPPEMIT ' int data_type;'*) +(*$HPPEMIT ' unsigned long adler;'*) +(*$HPPEMIT ' unsigned long reserved;'*) +(*$HPPEMIT '};'*) +{$IFDEF USE_PRAGMA_PACK_1} +(*$HPPEMIT '#pragma pack(pop)'*) +{$ENDIF} +(*$HPPEMIT ''*) +(*$HPPEMIT '#if !defined(__clang__) && !defined(__CPP__)'*) +(*$HPPEMIT '#if sizeof(z_stream) < 56'*) +(*$HPPEMIT '#pragma message "Pascal/C++ size mismatch: (C++) sizeof(z_stream) < (Pascal) [size: 56, align: 1] (WARNING)"'*) +(*$HPPEMIT '#pragma sizeof(z_stream)'*) +(*$HPPEMIT '#endif'*) +(*$HPPEMIT ''*) +(*$HPPEMIT '#if sizeof(z_stream) > 56'*) +(*$HPPEMIT '#pragma message "Pascal/C++ size mismatch: (C++) sizeof(z_stream) > (Pascal) [size: 56, align: 1] (WARNING)"'*) +(*$HPPEMIT '#pragma sizeof(z_stream)'*) +(*$HPPEMIT '#endif'*) +(*$HPPEMIT ''*) +{$IFDEF VCL_2009_OR_ABOVE} +(*$HPPEMIT '#if alignof(z_stream) < 1'*) +(*$HPPEMIT '#pragma message "Pascal/C++ alignment mismatch: (C++) alignof(z_stream) < (Pascal) [size: 56, align: 1] (WARNING)"'*) +(*$HPPEMIT '#endif'*) +(*$HPPEMIT ''*) +(*$HPPEMIT '#if alignof(z_stream) > 1'*) +(*$HPPEMIT '#pragma message "Pascal/C++ alignment mismatch: (C++) alignof(z_stream) > (Pascal) [size: 56, align: 1] (WARNING)"'*) +(*$HPPEMIT '#endif'*) +{$ELSE} +// TODO: what to put here for older C++Builder compilers that do not have alignof()? +// see http://www.wambold.com/Martin/writings/alignof.html for ideas... +{$ENDIF} +(*$HPPEMIT '#endif'*) +(*$HPPEMIT ''*) +(*$HPPEMIT ''*) +(*$HPPEMIT 'struct gz_header;'*) +(*$HPPEMIT 'typedef gz_header *gz_headerp;'*) +(*$HPPEMIT ''*) +{$IFDEF USE_PRAGMA_PACK_1} +(*$HPPEMIT '#pragma pack(push,1)'*) +{$ENDIF} +{$IFDEF VCL_XE_OR_ABOVE} +(*$HPPEMIT 'struct DECLSPEC_DRECORD gz_header'*) +{$ELSE} +(*$HPPEMIT 'struct gz_header'*) +{$ENDIF} +(*$HPPEMIT '{'*) +(*$HPPEMIT ' '*) +(*$HPPEMIT 'public:'*) +(*$HPPEMIT ' int text;'*) +(*$HPPEMIT ' unsigned long time;'*) +(*$HPPEMIT ' int xflags;'*) +(*$HPPEMIT ' int os;'*) +(*$HPPEMIT ' System::Byte *extra;'*) +(*$HPPEMIT ' unsigned extra_len;'*) +(*$HPPEMIT ' unsigned extra_max;'*) +(*$HPPEMIT ' char *name;'*) +(*$HPPEMIT ' unsigned name_max;'*) +(*$HPPEMIT ' char *comment;'*) +(*$HPPEMIT ' unsigned comm_max;'*) +(*$HPPEMIT ' int hcrc;'*) +(*$HPPEMIT ' int done;'*) +(*$HPPEMIT '};'*) +{$IFDEF USE_PRAGMA_PACK_1} +(*$HPPEMIT '#pragma pack(pop)'*) +{$ENDIF} +(*$HPPEMIT ''*) +(*$HPPEMIT '#if !defined(__clang__) && !defined(__CPP__)'*) +(*$HPPEMIT '#if sizeof(gz_header) < 52'*) +(*$HPPEMIT '#pragma message "Pascal/C++ size mismatch: (C++) sizeof(gz_header) < (Pascal) [size: 52, align: 1] (WARNING)"'*) +(*$HPPEMIT '#pragma sizeof(gz_header)'*) +(*$HPPEMIT '#endif'*) +(*$HPPEMIT ''*) +(*$HPPEMIT '#if sizeof(gz_header) > 52'*) +(*$HPPEMIT '#pragma message "Pascal/C++ size mismatch: (C++) sizeof(gz_header) > (Pascal) [size: 52, align: 1] (WARNING)"'*) +(*$HPPEMIT '#pragma sizeof(gz_header)'*) +(*$HPPEMIT '#endif'*) +(*$HPPEMIT ''*) +{$IFDEF VCL_2009_OR_ABOVE} +(*$HPPEMIT '#if alignof(gz_header) < 1'*) +(*$HPPEMIT '#pragma message "Pascal/C++ alignment mismatch: (C++) alignof(gz_header) < (Pascal) [size: 52, align: 1] (WARNING)"'*) +(*$HPPEMIT '#endif'*) +(*$HPPEMIT ''*) +(*$HPPEMIT '#if alignof(gz_header) > 1'*) +(*$HPPEMIT '#pragma message "Pascal/C++ alignment mismatch: (C++) alignof(gz_header) > (Pascal) [size: 52, align: 1] (WARNING)"'*) +(*$HPPEMIT '#endif'*) +{$ELSE} +// TODO: what to put here for older C++Builder compilers that do not have alignof()? +// see http://www.wambold.com/Martin/writings/alignof.html for ideas... +{$ENDIF} +(*$HPPEMIT '#endif'*) +(*$HPPEMIT '#endif'*) +(*$HPPEMIT '#if defined(__REMOVE_MACTYPES__)'*) +(*$HPPEMIT ' // Cleanup workaround for "Byte" ambiguity'*) +(*$HPPEMIT ' #if defined(__MACTYPES__)'*) +(*$HPPEMIT ' #undef __MACTYPES__'*) +(*$HPPEMIT ' #endif'*) +(*$HPPEMIT ' #undef __REMOVE_MACTYPES__'*) +(*$HPPEMIT '#endif'*) + +{$ENDIF} + +{$IFDEF HAS_UNIT_System_ZLib} +type + // In Delphi XE3+, Indy uses MarshaledAString only on mobile platforms, + // but System.ZLib uses MarshaledAString regardless of platform... + {.$IFDEF HAS_MarshaledAString} + {$IFDEF VCL_XE3_OR_ABOVE} + ZLibAString = MarshaledAString; + {$ELSE} + ZLibAString = PIdAnsiChar; + {$ENDIF} +{$ENDIF} + +{$EXTERNALSYM ZLIB_VERSION} +{$EXTERNALSYM ZLIB_VERNUM} +{$EXTERNALSYM ZLIB_VER_MAJOR} +{$EXTERNALSYM ZLIB_VER_MINOR} +{$EXTERNALSYM ZLIB_VER_REVISION} +{$EXTERNALSYM ZLIB_VER_SUBREVISION} + +{$IFDEF HAS_UNIT_System_ZLib} +// System.ZLib.ZLIB_VERSION is a TYPED constant (why?), so it can't be aliased as a const here! +var + ZLIB_VERSION: ZLibAString absolute System.ZLib.ZLIB_VERSION; +const + //ZLIB_VERSION: ZLibAString = System.ZLib.ZLIB_VERSION; + ZLIB_VERNUM = System.ZLib.ZLIB_VERNUM; + ZLIB_VER_MAJOR = System.ZLib.ZLIB_VER_MAJOR; + ZLIB_VER_MINOR = System.ZLib.ZLIB_VER_MINOR; + ZLIB_VER_REVISION = System.ZLib.ZLIB_VER_REVSION; // Typo on Embarcadero's side! + ZLIB_VER_SUBREVISION = System.ZLib.ZLIB_VER_SUBREVISION; +{$ELSE} +const + ZLIB_VERSION = '1.2.5'; + ZLIB_VERNUM = $1250; + ZLIB_VER_MAJOR = 1; + ZLIB_VER_MINOR = 2; + ZLIB_VER_REVISION = 5; + ZLIB_VER_SUBREVISION = 0; +{$ENDIF} + +type + {$EXTERNALSYM z_off_t} + {$IFDEF HAS_UNIT_System_ZLib} + z_off_t = System.ZLib.z_off_t; + {$ELSE} +{JPM - I made some types from our old header to the new C types defined originally + for compatability.} + {$IFDEF WINDOWS} + z_off_t = TIdC_LONG; + {$ELSE} + {$IFDEF USE_VCL_POSIX} + z_off_t = off_t; + {$ELSE} + {$IFDEF KYLIXCOMPAT} + z_off_t = off_t; + {$ELSE} + {$IFDEF USE_BASEUNIX} + z_off_t = off_t; + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$ENDIF} + + {$EXTERNALSYM alloc_func} + {$EXTERNALSYM free_func} + {$EXTERNALSYM in_func} + {$EXTERNALSYM out_func} + {$EXTERNALSYM z_streamp} + {$EXTERNALSYM z_stream} + {$EXTERNALSYM gz_headerp} + {$EXTERNALSYM gz_header} + + {$IFDEF HAS_UNIT_SYSTEM_ZLib} + + alloc_func = System.ZLib.alloc_func; + free_func = System.ZLib.free_func; + in_func = System.ZLib.in_func; + out_func = System.ZLib.out_func; + z_streamp = System.ZLib.z_streamp; + z_stream = System.ZLib.z_stream; + gz_headerp = System.ZLib.gz_headerp; + gz_header = System.ZLib.gz_header; + + {$ELSE} + + alloc_func = function(opaque: Pointer; items, size: TIdC_UINT): Pointer; cdecl; + free_func = procedure(opaque, address: Pointer); cdecl; + in_func = function(opaque: Pointer; var buf: PByte): TIdC_UNSIGNED; cdecl; + out_func = function(opaque: Pointer; buf: PByte; size: TIdC_UNSIGNED): TIdC_INT; cdecl; + z_streamp = ^z_stream; + z_stream = record + next_in: PByte; (* next input byte *) + avail_in: TIdC_UINT; (* number of bytes available at next_in *) + total_in: TIdC_ULONG; (* total nb of input bytes read so far *) + + next_out: PByte; (* next output byte should be put there *) + avail_out: TIdC_UINT; (* remaining free space at next_out *) + total_out: TIdC_ULONG; (* total nb of bytes output so far *) + + msg: PIdAnsiChar; (* last error message, NULL if no error *) + state: Pointer; (* not visible by applications *) + + zalloc: alloc_func; (* used to allocate the internal state *) + zfree: free_func; (* used to free the internal state *) + opaque: Pointer; (* private data object passed to zalloc and zfree *) + + data_type: TIdC_INT; (* best guess about the data type: ascii or binary *) + adler: TIdC_ULONG; (* adler32 value of the uncompressed data *) + reserved: TIdC_ULONG; (* reserved for future use *) + end; + +(* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*) + gz_headerp = ^gz_header; + gz_header = record + text : TIdC_INT; //* true if compressed data believed to be text */ + time : TIdC_ULONG; //* modification time */ + xflags : TIdC_INT; //* extra flags (not used when writing a gzip file) */ + os : TIdC_INT; //* operating system */ + extra : PByte; //* pointer to extra field or Z_NULL if none */ + extra_len : TIdC_UINT; //* extra field length (valid if extra != Z_NULL) */ + extra_max : TIdC_UINT; //* space at extra (only when reading header) */ + name : PIdAnsiChar; //* pointer to zero-terminated file name or Z_NULL */ + name_max : TIdC_UINT; //* space at name (only when reading header) */ + comment : PIdAnsiChar; //* pointer to zero-terminated comment or Z_NULL */ + comm_max : TIdC_UINT; //* space at comment (only when reading header) */ + hcrc : TIdC_INT; //* true if there was or will be a header crc */ + done : TIdC_INT; //* true when done reading gzip header (not used when writing a gzip file) */ + end; + + {$ENDIF} + + {$EXTERNALSYM TAlloc} + TAlloc = alloc_func; + {$EXTERNALSYM TFree} + TFree = free_func; + {$EXTERNALSYM TInFunc} + TInFunc = in_func; + {$EXTERNALSYM TOutFunc} + TOutFunc = out_func; + {$EXTERNALSYM TZStreamRec} + TZStreamRec = z_stream; + {$EXTERNALSYM PZStreamRec} + PZStreamRec = z_streamp; + {$EXTERNALSYM PgzHeaderRec} + PgzHeaderRec = gz_headerp; + {$EXTERNALSYM TgzHeaderRec} + TgzHeaderRec = gz_header; + +type + TZStreamType = ( + zsZLib, //standard zlib stream + zsGZip, //gzip stream + zsRaw); //raw stream (without any header) + +(* constants *) +const + {$EXTERNALSYM Z_NO_FLUSH} + {$EXTERNALSYM Z_PARTIAL_FLUSH} + {$EXTERNALSYM Z_SYNC_FLUSH} + {$EXTERNALSYM Z_FULL_FLUSH} + {$EXTERNALSYM Z_FINISH} + {$EXTERNALSYM Z_BLOCK} + {$EXTERNALSYM Z_TREES} + {$EXTERNALSYM Z_OK} + {$EXTERNALSYM Z_STREAM_END} + {$EXTERNALSYM Z_NEED_DICT} + {$EXTERNALSYM Z_ERRNO} + {$EXTERNALSYM Z_STREAM_ERROR} + {$EXTERNALSYM Z_DATA_ERROR} + {$EXTERNALSYM Z_MEM_ERROR} + {$EXTERNALSYM Z_BUF_ERROR} + {$EXTERNALSYM Z_VERSION_ERROR} + + {$EXTERNALSYM Z_NO_COMPRESSION} + {$EXTERNALSYM Z_BEST_SPEED} + {$EXTERNALSYM Z_BEST_COMPRESSION} + {$EXTERNALSYM Z_DEFAULT_COMPRESSION} + + {$EXTERNALSYM Z_FILTERED} + {$EXTERNALSYM Z_HUFFMAN_ONLY} + {$EXTERNALSYM Z_RLE} + {$EXTERNALSYM Z_DEFAULT_STRATEGY} + + {$EXTERNALSYM Z_BINARY} + {$EXTERNALSYM Z_TEXT} + {$EXTERNALSYM Z_ASCII} + {$EXTERNALSYM Z_UNKNOWN} + + {$EXTERNALSYM Z_DEFLATED} + {$EXTERNALSYM Z_NULL} + + {$IFDEF HAS_UNIT_System_ZLib} + + Z_NO_FLUSH = System.ZLib.Z_NO_FLUSH; + Z_PARTIAL_FLUSH = System.ZLib.Z_PARTIAL_FLUSH; + Z_SYNC_FLUSH = System.ZLib.Z_SYNC_FLUSH; + Z_FULL_FLUSH = System.ZLib.Z_FULL_FLUSH; + Z_FINISH = System.ZLib.Z_FINISH; + Z_BLOCK = System.ZLib.Z_BLOCK; + Z_TREES = System.ZLib.Z_TREES; + Z_OK = System.ZLib.Z_OK; + Z_STREAM_END = System.ZLib.Z_STREAM_END; + Z_NEED_DICT = System.ZLib.Z_NEED_DICT; + Z_ERRNO = System.ZLib.Z_ERRNO; + Z_STREAM_ERROR = System.ZLib.Z_STREAM_ERROR; + Z_DATA_ERROR = System.ZLib.Z_DATA_ERROR; + Z_MEM_ERROR = System.ZLib.Z_MEM_ERROR; + Z_BUF_ERROR = System.ZLib.Z_BUF_ERROR; + Z_VERSION_ERROR = System.ZLib.Z_VERSION_ERROR; + + Z_NO_COMPRESSION = System.ZLib.Z_NO_COMPRESSION; + Z_BEST_SPEED = System.ZLib.Z_BEST_SPEED; + Z_BEST_COMPRESSION = System.ZLib.Z_BEST_COMPRESSION; + Z_DEFAULT_COMPRESSION = System.ZLib.Z_DEFAULT_COMPRESSION; + + Z_FILTERED = System.ZLib.Z_FILTERED; + Z_HUFFMAN_ONLY = System.ZLib.Z_HUFFMAN_ONLY; + Z_RLE = System.ZLib.Z_RLE; + Z_DEFAULT_STRATEGY = System.ZLib.Z_DEFAULT_STRATEGY; + + Z_BINARY = System.ZLib.Z_BINARY; + Z_TEXT = System.ZLib.Z_TEXT; + Z_ASCII = System.ZLib.Z_ASCII; + Z_UNKNOWN = System.ZLib.Z_UNKNOWN; + + Z_DEFLATED = System.ZLib.Z_DEFLATED; + Z_NULL = System.ZLib.Z_NULL; + + {$ELSE} + + Z_NO_FLUSH = 0; + Z_PARTIAL_FLUSH = 1; + Z_SYNC_FLUSH = 2; + Z_FULL_FLUSH = 3; + Z_FINISH = 4; + Z_BLOCK = 5; + Z_TREES = 6; + Z_OK = 0; + Z_STREAM_END = 1; + Z_NEED_DICT = 2; + Z_ERRNO = -1; + Z_STREAM_ERROR = -2; + Z_DATA_ERROR = -3; + Z_MEM_ERROR = -4; + Z_BUF_ERROR = -5; + Z_VERSION_ERROR = -6; + + Z_NO_COMPRESSION = 0; + Z_BEST_SPEED = 1; + Z_BEST_COMPRESSION = 9; + Z_DEFAULT_COMPRESSION = -1; + + Z_FILTERED = 1; + Z_HUFFMAN_ONLY = 2; + Z_RLE = 3; + Z_DEFAULT_STRATEGY = 0; + + Z_BINARY = 0; + Z_TEXT = 1; + Z_ASCII = Z_TEXT; //* for compatibility with 1.2.2 and earlier */ + Z_UNKNOWN = 2; + + Z_DEFLATED = 8; + Z_NULL = 0; //* for initializing zalloc, zfree, opaque */ + + {$ENDIF} + + {$EXTERNALSYM MAX_WBITS} + MAX_WBITS = 15; { 32K LZ77 window } + + {$EXTERNALSYM MAX_MEM_LEVEL} + MAX_MEM_LEVEL = 9; + {$EXTERNALSYM DEF_MEM_LEVEL} + DEF_MEM_LEVEL = 8; { if MAX_MEM_LEVEL > 8 } + +{$EXTERNALSYM inflateInit} +function inflateInit(var strm: z_stream): TIdC_INT; +{$IFDEF USE_INLINE} inline; {$ENDIF} + +{$EXTERNALSYM inflateBackInit} +function inflateBackInit(var strm: z_stream; + windowBits: TIdC_INT; window: PByte): TIdC_INT; +{$IFDEF USE_INLINE} inline; {$ENDIF} + +{$EXTERNALSYM inflateInit2} +function inflateInit2(var strm: z_stream; windowBits: TIdC_INT): TIdC_INT; +{$IFDEF USE_INLINE} inline; {$ENDIF} + +{$EXTERNALSYM deflateInit} +function deflateInit(var strm: z_stream; level: TIdC_INT): TIdC_INT; +{$IFDEF USE_INLINE} inline; {$ENDIF} + +{$EXTERNALSYM deflateInit2} +function deflateInit2(var strm: z_stream; level, method, windowBits, + memLevel, strategy: TIdC_INT): TIdC_INT; +{$IFDEF USE_INLINE} inline; {$ENDIF} + +{not sure if these should be externalsymed but might not be a bad idea} + +{$EXTERNALSYM deflateInitEx} +function deflateInitEx(var strm: z_stream; level: TIdC_INT; streamtype: TZStreamType = zsZLib): TIdC_INT; + +{$EXTERNALSYM inflateInitEx} +function inflateInitEx(var strm: z_stream; streamtype: TZStreamType = zsZLib): TIdC_INT; + +{$EXTERNALSYM adler32} +{$EXTERNALSYM adler32_combine} +{$EXTERNALSYM compress} +{$EXTERNALSYM compress2} +{$EXTERNALSYM compressBound} +{$EXTERNALSYM crc32} +{$EXTERNALSYM crc32_combine} +{$EXTERNALSYM deflate} +{$EXTERNALSYM deflateBound} +{$EXTERNALSYM deflateCopy} +{$EXTERNALSYM deflateEnd} +{$EXTERNALSYM deflateInit_} +{$EXTERNALSYM deflateInit2_} +{$EXTERNALSYM deflateParams} +{$EXTERNALSYM deflatePrime} +{$EXTERNALSYM deflateTune} +{$EXTERNALSYM deflateReset} +{$EXTERNALSYM deflateSetDictionary} +{$EXTERNALSYM inflate} +{$EXTERNALSYM inflateBack} +{$EXTERNALSYM inflateBackEnd} +{$EXTERNALSYM inflateBackInit_} +{$EXTERNALSYM inflateCopy} +{$EXTERNALSYM inflateEnd; external} +{$EXTERNALSYM inflateInit_} +{$EXTERNALSYM inflateInit2_} +{$EXTERNALSYM inflateReset} +{$EXTERNALSYM inflateReset2} +{$EXTERNALSYM inflateSetDictionary} +{$EXTERNALSYM inflateSync} +{$EXTERNALSYM uncompress} +{$EXTERNALSYM zlibCompileFlags} +{$EXTERNALSYM zError} +{$EXTERNALSYM inflateSyncPoint} +{$EXTERNALSYM get_crc_table} +{$EXTERNALSYM inflateUndermine} +{$EXTERNALSYM zlibVersion} +{$EXTERNALSYM deflateSetHeader} +{$EXTERNALSYM inflatePrime} +{$EXTERNALSYM inflateMark} +{$EXTERNALSYM inflateGetHeader} + +{$EXTERNALSYM zlibAllocMem} +{$EXTERNALSYM zlibFreeMem} + +{$IFDEF HAS_UNIT_System_ZLib} + +const + adler32 : function(adler: LongWord; buf: PByte; len: Cardinal): LongWord; cdecl = System.ZLib.adler32; + adler32_combine : function(adler1, adler2: LongWord; len2: z_off_t): LongWord; cdecl = System.ZLib.adler32_combine; + compress : function(dest: PByte; var destLen: LongWord; source: PByte; sourceLen: LongWord): Integer; cdecl = System.ZLib.compress; + compress2 : function(dest: PByte; var destLen: LongWord; source: PByte; sourceLen: LongWord; level: Integer): Integer; cdecl = System.ZLib.compress2; + compressBound : function(sourceLen: LongWord): LongWord; cdecl = System.ZLib.compressBound; + crc32 : function(crc: LongWord; buf: PByte; len: Cardinal): LongWord; cdecl = System.ZLib.crc32; + crc32_combine : function(crc1, crc2: LongWord; len2: z_off_t): LongWord; cdecl = System.ZLib.crc32_combine; + deflate : function(var strm: z_stream; flush: Integer): Integer; cdecl = System.ZLib.deflate; + deflateBound : function(var strm: z_stream; sourceLen: Cardinal): LongWord; cdecl = System.ZLib.deflateBound; + deflateCopy : function(var dest: z_stream; const source: z_stream): Integer; cdecl = System.ZLib.deflateCopy; + deflateEnd : function(var strm: z_stream): Integer; cdecl = System.ZLib.deflateEnd; + deflateInit_ : function(var strm: z_stream; level: Integer; version: ZLibAString; stream_size: Integer): Integer; cdecl = System.ZLib.deflateInit_; + deflateInit2_ : function(var strm: z_stream; level, method, windowBits, memLevel, strategy: Integer; version: ZLibAString; stream_size: Integer): Integer; cdecl = System.ZLib.deflateInit2_; + deflateParams : function(var strm: z_stream; level, strategy: Integer): Integer; cdecl = System.ZLib.deflateParams; + deflatePrime : function(var strm: z_stream; bits, value: Integer): Integer; cdecl = System.ZLib.deflatePrime; + deflateTune : function(var strm: z_stream; good_length, max_lazy, nice_length, max_chain: Integer): Integer; cdecl = System.ZLib.deflateTune; + deflateReset : function(var strm: z_stream): Integer; cdecl = System.ZLib.deflateReset; + deflateSetDictionary : function(var strm: z_stream; dictionary: PByte; dictLength: Cardinal): Integer; cdecl = System.ZLib.deflateSetDictionary; + inflate : function(var strm: z_stream; flush: Integer): Integer; cdecl = System.ZLib.inflate; + inflateBack : function(var strm: z_stream; in_: in_func; in_desc: Pointer; out_: out_func; out_desc: Pointer): Integer; cdecl = System.ZLib.inflateBack; + inflateBackEnd : function(var strm: z_stream): Integer; cdecl = System.ZLib.inflateBackEnd; + inflateBackInit_ : function(var strm: z_stream; windowBits: Integer; window: PByte; version: ZLibAString; stream_size: Integer): Integer; cdecl = System.ZLib.inflateBackInit_; + inflateCopy : function(var dest, source: z_stream): Integer; cdecl = System.ZLib.inflateCopy; + inflateEnd : function(var strm: z_stream): Integer; cdecl = System.ZLib.inflateEnd; + inflateInit_ : function(var strm: z_stream; version: ZLibAString; stream_size: Integer): Integer; cdecl = System.ZLib.inflateInit_; + inflateInit2_ : function(var strm: z_stream; windowBits: Integer; version: ZLibAString; stream_size: Integer): Integer; cdecl = System.ZLib.inflateInit2_; + inflateReset : function(var strm: z_stream): Integer; cdecl = System.ZLib.inflateReset; + inflateReset2 : function(var strm: z_stream; windowBits: Integer): Integer; cdecl = System.ZLib.inflateReset2; + inflateSetDictionary : function(var strm: z_stream; dictionary: PByte; dictLength: Cardinal): Integer; cdecl = System.ZLib.inflateSetDictionary; + inflateSync : function(var strm: z_stream): Integer; cdecl = System.ZLib.inflateSync; + uncompress : function(dest: PByte; var destLen: LongWord; source: PByte; sourceLen: LongWord): Integer; cdecl = System.ZLib.uncompress; + zlibCompileFlags : function: LongWord; cdecl = System.ZLib.zlibCompileFlags; + zError : function(Err: Integer): ZLibAString; cdecl = System.ZLib.zError; + inflateSyncPoint : function(stream: z_streamp): Integer; cdecl = System.ZLib.inflateSyncPoint; + get_crc_table : function: PLongWord; cdecl = System.ZLib.get_crc_table; + inflateUndermine : function(stream: z_streamp; size: Integer): Integer; cdecl = System.ZLib.inflateUndermine; + zlibVersion : function: ZLibAString; cdecl = System.ZLib.zlibVersion; + deflateSetHeader : function(var strm: z_stream; var head: gz_header): Integer; cdecl = System.ZLib.deflateSetHeader; + inflatePrime : function(var strm: z_stream; bits, value: Integer): Integer; cdecl = System.ZLib.inflatePrime; + inflateMark : function(var strm: z_stream): LongInt; cdecl = System.ZLib.inflateMark; + inflateGetHeader : function(var strm: z_stream; var head: gz_header): Integer; cdecl = System.ZLib.inflateGetHeader; + + zlibAllocMem : function(AppData: Pointer; Items, Size: Cardinal): Pointer; cdecl = System.ZLib.zlibAllocMem; + zlibFreeMem : procedure(AppData, Block: Pointer); cdecl = System.ZLib.zlibFreeMem; + +{$ELSE} + +{$IFNDEF STATICLOAD_ZLIB} +type + EIdZLibStubError = class(EIdException) + protected + FError : UInt32; + FErrorMessage : String; + FTitle : String; + public + constructor Build(const ATitle : String; AError : UInt32); + property Error : UInt32 read FError; + property ErrorMessage : String read FErrorMessage; + property Title : String read FTitle; + end; + +type + {$EXTERNALSYM LPN_adler32} + LPN_adler32 = function (adler: TIdC_ULONG; + const buf: PByte; len: TIdC_UINT): TIdC_ULONG; cdecl; + {$EXTERNALSYM LPN_adler32_combine} + LPN_adler32_combine = function (crc1, crc2 : TIdC_ULONG; + len2 : z_off_t) : TIdC_ULONG; cdecl; + {$EXTERNALSYM LPN_compress} + LPN_compress = function (dest: PByte; var destLen: TIdC_ULONG; + const source: PByte; sourceLen: TIdC_ULONG): TIdC_INT;cdecl; + {$EXTERNALSYM LPN_compress2} + LPN_compress2 = function(dest: PByte; var destLen: TIdC_ULONG; + const source: PByte; sourceLen: TIdC_ULONG; + level: TIdC_INT): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_compressBound} + LPN_compressBound = function (sourceLen: TIdC_ULONG): TIdC_ULONG;cdecl; + {$EXTERNALSYM LPN_crc32} + LPN_crc32 = function (crc: TIdC_ULONG; const buf: PByte; + len: TIdC_UINT): TIdC_ULONG; cdecl; + {$EXTERNALSYM LPN_crc32_combine} + LPN_crc32_combine = function (crc1, crc2 : TIdC_ULONG; + len2 : z_off_t) : TIdC_ULONG; cdecl; + {$EXTERNALSYM LPN_deflate} + LPN_deflate = function (var strm: z_stream; flush: TIdC_INT): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_deflateBound} + LPN_deflateBound = function (var strm: z_stream; + sourceLen: TIdC_ULONG): TIdC_ULONG; cdecl; + {$EXTERNALSYM LPN_deflateCopy} + LPN_deflateCopy = function (var dest, source: z_stream): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_deflateEnd} + LPN_deflateEnd = function (var strm: z_stream): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_deflateInit_} + LPN_deflateInit_ = function (var strm: z_stream; level: TIdC_INT; + const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT;cdecl; + {$EXTERNALSYM LPN_deflateInit2_} + LPN_deflateInit2_ = function (var strm: z_stream; + level, method, windowBits, memLevel, strategy: TIdC_INT; + const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT;cdecl; + {$EXTERNALSYM LPN_deflateParams} + LPN_deflateParams = function (var strm: z_stream; level, strategy: TIdC_INT): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_deflatePrime} + LPN_deflatePrime = function (var strm: z_stream; bits, value: TIdC_INT): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_deflateTune} + LPN_deflateTune = function (var strm : z_stream; good_length : TIdC_INT; + max_lazy, nice_length, max_chain : TIdC_INT) : TIdC_INT; cdecl; + {$EXTERNALSYM LPN_deflateReset} + LPN_deflateReset = function (var strm: z_stream): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_deflateSetDictionary} + LPN_deflateSetDictionary = function (var strm: z_stream; const dictionary: PByte; + dictLength: TIdC_UINT): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_inflate} + LPN_inflate = function (var strm: z_stream; flush: TIdC_INT): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_inflateBack} + LPN_inflateBack = function (var strm: z_stream; in_fn: in_func; in_desc: Pointer; + out_fn: out_func; out_desc: Pointer): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_inflateBackEnd} + LPN_inflateBackEnd = function (var strm: z_stream): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_inflateBackInit_} + LPN_inflateBackInit_ = function (var strm: z_stream; + windowBits: TIdC_INT; window: PByte; + const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_inflateCopy} + LPN_inflateCopy = function (var dest, source: z_stream): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_inflateEnd} + LPN_inflateEnd = function (var strm: z_stream): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_inflateInit_} + LPN_inflateInit_ = function (var strm: z_stream; const version: PIdAnsiChar; + stream_size: TIdC_INT): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_inflateInit2_} + LPN_inflateInit2_ = function (var strm: z_stream; windowBits: TIdC_INT; + const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT;cdecl; + {$EXTERNALSYM LPN_inflateReset} + LPN_inflateReset = function (var strm: z_stream): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_inflateReset2} + LPN_inflateReset2 = function (var strm : z_stream; windowBits : TIdC_INT) : TIdC_INT; cdecl; + {$EXTERNALSYM LPN_inflatePrime} + LPN_inflatePrime = function (var strm : z_stream; bits, value : TIdC_INT ) : TIdC_INT; cdecl; + {$EXTERNALSYM LPN_inflateMark} + LPN_inflateMark = function (var strm : z_stream) : TIdC_LONG; cdecl; + {$EXTERNALSYM LPN_inflateSetDictionary} + LPN_inflateSetDictionary = function (var strm: z_stream; const dictionary: PByte; + dictLength: TIdC_UINT): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_inflateSync} + LPN_inflateSync = function (var strm: z_stream): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_uncompress} + LPN_uncompress = function (dest: PByte; var destLen: TIdC_ULONG; + const source: PByte; sourceLen: TIdC_ULONG): TIdC_INT;cdecl; + {$EXTERNALSYM LPN_zlibCompileFlags} + LPN_zlibCompileFlags = function : TIdC_ULONG; cdecl; + {$EXTERNALSYM LPN_zError} + LPN_zError = function (err : TIdC_INT) : PIdAnsiChar; cdecl; + {$EXTERNALSYM LPN_inflateSyncPoint} + LPN_inflateSyncPoint = function (var z : TZStreamRec) : TIdC_INT; cdecl; + {$EXTERNALSYM LPN_get_crc_table} + LPN_get_crc_table = function : PIdC_ULONG; cdecl; + {$EXTERNALSYM LPN_zlibVersion} + LPN_zlibVersion = function : PIdAnsiChar; cdecl; + {$EXTERNALSYM LPN_inflateUndermine} + LPN_inflateUndermine = function (var strm: z_stream; subvert : TIdC_INT ) : TIdC_INT; cdecl; + {$EXTERNALSYM LPN_deflateSetHeader} + LPN_deflateSetHeader = function (var strm: z_stream; var head: gz_header): TIdC_INT; cdecl; + {$EXTERNALSYM LPN_inflateGetHeader} + LPN_inflateGetHeader = function (var strm: z_stream; var head: gz_header): TIdC_INT; cdecl; + +{Vars} +var + adler32 : LPN_adler32 = nil; + adler32_combine : LPN_adler32_combine = nil; + compress : LPN_compress = nil; + compress2 : LPN_compress2 = nil; + compressBound : LPN_compressBound = nil; + crc32 : LPN_crc32 = nil; + crc32_combine : LPN_crc32_combine = nil; + deflate : LPN_deflate = nil; + deflateBound : LPN_deflateBound = nil; + deflateCopy : LPN_deflateCopy = nil; + deflateEnd : LPN_deflateEnd = nil; + deflateInit_ : LPN_deflateInit_ = nil; + deflateInit2_ : LPN_deflateInit2_ = nil; + deflateParams : LPN_deflateParams = nil; + + deflatePrime :LPN_deflatePrime = nil; + deflateTune : LPN_deflateTune = nil; + deflateReset : LPN_deflateReset = nil; + deflateSetDictionary : LPN_deflateSetDictionary = nil; + inflate : LPN_inflate = nil; + inflateBack : LPN_inflateBack = nil; + inflateBackEnd : LPN_inflateBackEnd = nil; + inflateEnd : LPN_inflateEnd = nil; + inflateBackInit_ : LPN_inflateBackInit_ = nil; + inflateCopy : LPN_inflateCopy = nil; + inflateInit_ : LPN_inflateInit_ = nil; + inflateInit2_ : LPN_inflateInit2_ = nil; + inflateReset : LPN_inflateReset = nil; + + inflateReset2 : LPN_inflateReset2 = nil; + inflatePrime : LPN_inflatePrime = nil; + inflateMark : LPN_inflateMark = nil; + + inflateSetDictionary : LPN_inflateSetDictionary = nil; + inflateSync : LPN_inflateSync = nil; + uncompress : LPN_uncompress = nil; + zlibCompileFlags : LPN_zlibCompileFlags = nil; + zError : LPN_zError = nil; + inflateSyncPoint : LPN_inflateSyncPoint = nil; + get_crc_table : LPN_get_crc_table = nil; + inflateUndermine : LPN_inflateUndermine = nil; + zlibVersion : LPN_zlibVersion = nil; + deflateSetHeader : LPN_deflateSetHeader = nil; + inflateGetHeader : LPN_inflateGetHeader = nil; + +procedure IdZLibSetLibPath(const APath: String); + +{$ELSE} + +(* basic functions *) +function zlibVersion: PIdAnsiChar; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} + +function deflate(var strm: z_stream; flush: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function deflateEnd(var strm: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} + +function inflate(var strm: z_stream; flush: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflateEnd(var strm: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} + +(* advanced functions *) + +function deflateSetDictionary(var strm: z_stream; const dictionary: PByte; + dictLength: TIdC_UINT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function deflateCopy(var dest, source: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function deflateReset(var strm: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function deflateParams(var strm: z_stream; level, strategy: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +{JPM Addition} +function deflateTune(var strm : z_stream; good_length : TIdC_INT; + max_lazy, nice_length, max_chain : TIdC_INT) : TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function deflateBound(var strm: z_stream; + sourceLen: TIdC_ULONG): TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function deflatePrime(var strm: z_stream; bits, value: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} + +function inflateSetDictionary(var strm: z_stream; const dictionary: PByte; + dictLength: TIdC_UINT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflateSync(var strm: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflateCopy(var dest, source: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflateReset(var strm: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflateReset2(var strm : z_stream; windowBits : TIdC_INT) : TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflatePrime(var strm : z_stream; bits, value : TIdC_INT ) : TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflateMark(var strm : z_stream) : TIdC_LONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer; + out_fn: out_func; out_desc: Pointer): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflateBackEnd(var strm: z_stream): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} + +function zlibCompileFlags: TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} + +{JPM Additional functions} +function zError (err : TIdC_INT) : PIdAnsiChar; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflateSyncPoint(var z : TZStreamRec) : TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +//const uLongf * get_crc_table (void); +function inflateUndermine(var strm: z_stream; subvert : TIdC_INT ) : TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} + +function get_crc_table : PIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +{end JPM additions} + +(* utility functions *) +function compress(dest: PByte; var destLen: TIdC_ULONG; + const source: PByte; sourceLen: TIdC_ULONG): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function compress2(dest: PByte; var destLen: TIdC_ULONG; + const source: PByte; sourceLen: TIdC_ULONG; + level: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function compressBound(sourceLen: TIdC_ULONG): TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function uncompress(dest: PByte; var destLen: TIdC_ULONG; + const source: PByte; sourceLen: TIdC_ULONG): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} + +(* checksum functions *) +function adler32(adler: TIdC_ULONG; + const buf: PByte; len: TIdC_UINT): TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function adler32_combine(crc1, crc2 : TIdC_ULONG; len2 : z_off_t) : TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function crc32(crc: TIdC_ULONG; const buf: PByte; + len: TIdC_UINT): TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function crc32_combine(crc1, crc2 : TIdC_ULONG; len2 : z_off_t) : TIdC_ULONG; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +(* various hacks, don't look :) *) +function deflateInit_(var strm: z_stream; level: TIdC_INT; + const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflateInit_(var strm: z_stream; const version: PIdAnsiChar; + stream_size: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function deflateInit2_(var strm: z_stream; + level, method, windowBits, memLevel, strategy: TIdC_INT; + const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflateInit2_(var strm: z_stream; windowBits: TIdC_INT; + const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflateBackInit_(var strm: z_stream; + windowBits: TIdC_INT; window: PByte; + const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} + +function deflateSetHeader(var strm: z_stream; var head: gz_header): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +function inflateGetHeader(var strm: z_stream; var head: gz_header): TIdC_INT; {$IFDEF STATIC_CDECL_PROCS} cdecl; {$ENDIF} +{$ENDIF} + +function zlibAllocMem(AppData: Pointer; Items, Size: TIdC_UINT): Pointer; cdecl; +procedure zlibFreeMem(AppData, Block: Pointer); cdecl; + +{$ENDIF} + +{$EXTERNALSYM Load} +function Load : Boolean; +{$EXTERNALSYM Unload} +procedure Unload; +{$EXTERNALSYM Loaded} +function Loaded : Boolean; + +{minor additional helper functions} +{$EXTERNALSYM _malloc} +function _malloc(Size: Integer): Pointer; cdecl; +{$EXTERNALSYM _free} +procedure _free(Block: Pointer); cdecl; +{$EXTERNALSYM _memset} +procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl; +{$EXTERNALSYM _memcpy} +procedure _memcpy(dest, source: Pointer; count: Integer); cdecl; + +implementation + +{$IFNDEF HAS_UNIT_System_ZLib} + +uses + SysUtils + {$IFNDEF STATICLOAD_ZLIB} + , IdZLibConst + {$IFDEF KYLIXCOMPAT} + , libc + {$ENDIF} + {$IFDEF FPC} + , DynLibs // better add DynLibs only for fpc + {$ENDIF} + {$IFDEF WINDOWS} + , Windows + {$ENDIF} + {$ELSE} + {$IFDEF VCL_XE2_OR_ABOVE} + , System.Win.Crtl {$NOINCLUDE System.Win.Crtl} + {$ENDIF} + {$ENDIF}; + +{$IFDEF STATICLOAD_ZLIB} +{$IFNDEF VCL_XE2_OR_ABOVE} + {$L adler32.obj} + {$L compress.obj} + {$L crc32.obj} + {$L deflate.obj} + {$L infback.obj} + {$L inffast.obj} + {$L inflate.obj} + {$L inftrees.obj} + {$L trees.obj} + {$L uncompr.obj} + {$L zutil.obj} +{$ELSE} + {$IFDEF WIN32} + {$L ZLib\i386-Win32-ZLib\zlibudec.obj} // undecorated stubs which are not needed for x64 compilation + {$L ZLib\i386-Win32-ZLib\deflate.obj} + {$L ZLib\i386-Win32-ZLib\inflate.obj} + {$L ZLib\i386-Win32-ZLib\infback.obj} + {$L ZLib\i386-Win32-ZLib\inffast.obj} + {$L ZLib\i386-Win32-ZLib\inftrees.obj} + {$L ZLib\i386-Win32-ZLib\trees.obj} + {$L ZLib\i386-Win32-ZLib\compress.obj} + {$L ZLib\i386-Win32-ZLib\uncompr.obj} + {$L ZLib\i386-Win32-ZLib\adler32.obj} + {$L ZLib\i386-Win32-ZLib\crc32.obj} + {$L ZLib\i386-Win32-ZLib\zutil.obj} + {$L ZLib\i386-Win32-ZLib\gzclose.obj} + {$L ZLib\i386-Win32-ZLib\gzread.obj} + {$L ZLib\i386-Win32-ZLib\gzwrite.obj} + {$L ZLib\i386-Win32-ZLib\gzlib.obj} + {$ENDIF} + {$IFDEF WIN64} + {$L ZLib\x86_64-Win64-ZLib\deflate.obj} + {$L ZLib\x86_64-Win64-ZLib\inflate.obj} + {$L ZLib\x86_64-Win64-ZLib\infback.obj} + {$L ZLib\x86_64-Win64-ZLib\inffast.obj} + {$L ZLib\x86_64-Win64-ZLib\inftrees.obj} + {$L ZLib\x86_64-Win64-ZLib\trees.obj} + {$L ZLib\x86_64-Win64-ZLib\compress.obj} + {$L ZLib\x86_64-Win64-ZLib\uncompr.obj} + {$L ZLib\x86_64-Win64-ZLib\adler32.obj} + {$L ZLib\x86_64-Win64-ZLib\crc32.obj} + {$L ZLib\x86_64-Win64-ZLib\zutil.obj} + {$L ZLib\x86_64-Win64-ZLib\gzclose.obj} + {$L ZLib\x86_64-Win64-ZLib\gzread.obj} + {$L ZLib\x86_64-Win64-ZLib\gzwrite.obj} + {$L ZLib\x86_64-Win64-ZLib\gzlib.obj} + {$ENDIF} +{$ENDIF} + +function adler32; external; +function adler32_combine; external; +function compress; external; +function compress2; external; +function compressBound; external; +function crc32; external; +function crc32_combine; external; +function deflate; external; +function deflateBound; external; +function deflateCopy; external; +function deflateEnd; external; +function deflateInit_; external; +function deflateInit2_; external; +function deflateParams; external; +function deflatePrime; external; +function deflateTune; external; +function deflateReset; external; +function deflateSetDictionary; external; +function inflate; external; +function inflateBack; external; +function inflateBackEnd; external; +function inflateBackInit_; external; +function inflateCopy; external; +function inflateEnd; external; +function inflateInit_; external; +function inflateInit2_; external; +function inflateReset; external; +function inflateReset2; external; +function inflateSetDictionary; external; +function inflateSync; external; +function uncompress; external; +function zlibCompileFlags; external; +function zError; external; +function inflateSyncPoint; external; +function get_crc_table; external; +function inflateUndermine; external; +function zlibVersion; external; +function deflateSetHeader; external; +function inflatePrime; external; +function inflateMark; external; +function inflateGetHeader; external; +{$ELSE} +var + hZLib: TIdLibHandle = IdNilHandle; + + {$IFDEF UNIX} +const + //The extensions will be resolved by IdGlobal.HackLoad + //This is a little messy because symbolic links to libraries may not always be the same + //in various Unix types. Even then, there could possibly be differences. + libzlib = 'libz'; + // TODO: setup this array more like the SSLDLLVers arrays in the IdSSLOpenSSLHeaders unit... + libvers : array [0..3] of string = ('.1','','.3','.2'); + {$ENDIF} + {$IFDEF NETWARE} {zlib.nlm comes with netware6} +const + libzlib = 'zlib'; + {$ENDIF} + //Do not use IFDEF WINDOWS because that may catch WindowsCE. + {$IFDEF WIN32} + //Note that this is not an official ZLIB .DLL. It was created by running + //CMake in Visual Studio 2022. +const + libzlib = 'zlib.dll'; + {$ENDIF} + {$IFDEF WIN64} + //Note that this is not an official ZLIB .DLL. It was created by running + //CMake in Visual Studio 2022. +const + libzlib = 'zlib.dll'; + {$ENDIF} + {$IFDEF WINCE} + //Note that zlibce can be found at http://www.tenik.co.jp/~adachi/wince/zlibce/ +const + libzlib = 'zlibce'; + {$ENDIF} + +constructor EIdZLibStubError.Build(const ATitle : String; AError : UInt32); +begin + FTitle := ATitle; + FError := AError; + if AError = 0 then begin + inherited Create(ATitle); + end else begin + FErrorMessage := SysUtils.SysErrorMessage(AError); + inherited Create(ATitle + ': ' + FErrorMessage); {Do not Localize} + end; +end; + +function FixupStub(const AName: TIdLibFuncName): Pointer; +begin + if hZLib = IdNilHandle then begin + if not Load then begin + raise EIdZLibStubError.Build(Format(RSZLibCallError, [AName]), 0); + end; + end; + Result := LoadLibFunction(hZLib, AName); + if Result = nil then begin + raise EIdZLibStubError.Build(Format(RSZLibCallError, [AName]), 10022); + end; +end; + +function stub_adler32(adler: TIdC_ULONG; const buf: PByte; + len: TIdC_UINT): TIdC_ULONG; cdecl; +begin + adler32 := FixupStub('adler32'); {Do not Localize} + Result := adler32(adler, buf, len); +end; + +function stub_adler32_combine (crc1, crc2 : TIdC_ULONG; + len2 : z_off_t) : TIdC_ULONG; cdecl; +begin + adler32_combine := FixupStub('adler32_combine'); {Do not Localize} + Result := adler32_combine(crc1, crc2, len2); +end; + +function stub_compress(dest: PByte; var destLen: TIdC_ULONG; + const source: PByte; sourceLen: TIdC_ULONG): TIdC_INT; cdecl; +begin + compress := FixupStub('compress'); {Do not Localize} + Result := compress(dest,destLen,source,sourceLen); +end; + +function stub_compress2(dest: PByte; var destLen: TIdC_ULONG; + const source: PByte; sourceLen: TIdC_ULONG; + level: TIdC_INT): TIdC_INT; cdecl; +begin + compress2 := FixupStub('compress2'); {Do not Localize} + Result := compress2(dest, destLen, source, sourceLen, level); +end; + + +function stub_compressBound(sourceLen: TIdC_ULONG): TIdC_ULONG; cdecl; +begin + compressBound := FixupStub('compressBound'); {Do not Localize} + Result := compressBound(sourcelen); +end; + +function stub_crc32(crc: TIdC_ULONG; const buf: PByte; + len: TIdC_UINT): TIdC_ULONG; cdecl; +begin + crc32 := FixupStub('crc32'); {Do not Localize} + Result := crc32(crc, buf, len); +end; + +function stub_crc32_combine (crc1, crc2 : TIdC_ULONG; + len2 : z_off_t) : TIdC_ULONG; cdecl; +begin + crc32_combine := FixupStub('crc32_combine'); {Do not Localize} + Result := crc32_combine(crc1, crc2, len2); +end; + +function stub_deflate(var strm: z_stream; flush: TIdC_INT): TIdC_INT; cdecl; +begin + deflate := FixupStub('deflate'); {Do not Localize} + Result := deflate(strm, flush); +end; + +function stub_deflateBound(var strm: z_stream; + sourceLen: TIdC_ULONG): TIdC_ULONG; cdecl; +begin + deflateBound := FixupStub('deflateBound'); {Do not Localize} + Result := deflateBound(strm, sourceLen); +end; + +function stub_deflateCopy(var dest, source: z_stream): TIdC_INT; cdecl; +begin + deflateCopy := FixupStub('deflateCopy'); {Do not Localize} + Result := deflateCopy(dest, source); +end; + +function stub_deflateEnd(var strm: z_stream): TIdC_INT; cdecl; +begin + deflateEnd := FixupStub('deflateEnd'); {Do not Localize} + Result := deflateEnd(strm); +end; + +function stub_deflateInit_(var strm: z_stream; level: TIdC_INT; + const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT;cdecl; +begin + deflateInit_ := FixupStub('deflateInit_'); {Do not Localize} + Result := deflateInit_(strm, level, version, stream_size); +end; + +function stub_deflateInit2_(var strm: z_stream; + level, method, windowBits, memLevel, strategy: TIdC_INT; + const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT;cdecl; +begin + deflateInit2_ := FixupStub('deflateInit2_'); {Do not Localize} + Result := deflateInit2_(strm,level, method, windowBits, memLevel, strategy, + version, stream_size); +end; + +function stub_deflateParams (var strm: z_stream; level, strategy: TIdC_INT): TIdC_INT; cdecl; +begin + deflateParams := FixupStub('deflateParams'); {Do not Localize} + Result := deflateParams (strm, level, strategy); +end; + +function stub_deflatePrime (var strm: z_stream; bits, value: TIdC_INT): TIdC_INT; cdecl; +begin + deflatePrime := FixupStub('deflatePrime'); {Do not Localize} + Result := deflateParams (strm, bits, value); +end; + +function stub_deflateTune(var strm : z_stream; good_length : TIdC_INT; + max_lazy, nice_length, max_chain : TIdC_INT) : TIdC_INT; cdecl; +begin + deflateTune := FixupStub('deflateTune'); {Do not Localize} + Result := deflateTune(strm, good_length, max_lazy, nice_length, max_chain) ; +end; + +function stub_deflateReset (var strm: z_stream): TIdC_INT; cdecl; +begin + deflateReset := FixupStub('deflateReset'); {Do not Localize} + Result := deflateReset(strm); +end; + +function stub_deflateSetDictionary(var strm: z_stream; const dictionary: PByte; + dictLength: TIdC_UINT): TIdC_INT; cdecl; +begin + deflateSetDictionary := FixupStub('deflateSetDictionary'); {Do not Localize} + Result := deflateSetDictionary(strm, dictionary, dictLength); +end; + +function stub_inflate(var strm: z_stream; flush: TIdC_INT): TIdC_INT; cdecl; +begin + inflate := FixupStub('inflate'); {Do not Localize} + Result := inflate(strm, flush); +end; + +function stub_inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer; + out_fn: out_func; out_desc: Pointer): TIdC_INT; cdecl; +begin + inflateBack := FixupStub('inflateBack'); {Do not Localize} + Result := inflateBack(strm, in_fn, in_desc, out_fn, out_desc); +end; + +function stub_inflateBackEnd(var strm: z_stream): TIdC_INT; cdecl; +begin + inflateBackEnd := FixupStub('inflateBackEnd'); {Do not Localize} + Result := inflateBackEnd(strm); +end; + +function stub_inflateEnd(var strm: z_stream): TIdC_INT; cdecl; +begin + inflateEnd := FixupStub('inflateEnd'); {Do not Localize} + Result := inflateEnd(strm); +end; + +function stub_inflateBackInit_(var strm: z_stream; + windowBits: TIdC_INT; window: PByte; + const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT; cdecl; +begin + inflateBackInit_ := FixupStub('inflateBackInit_'); {Do not Localize} + Result := inflateBackInit_(strm, windowBits, window, version, stream_size); +end; + +function stub_inflateInit2_(var strm: z_stream; windowBits: TIdC_INT; + const version: PIdAnsiChar; stream_size: TIdC_INT): TIdC_INT;cdecl; +begin + inflateInit2_ := FixupStub('inflateInit2_'); {Do not Localize} + Result := inflateInit2_(strm, windowBits, version, stream_size); +end; + +function stub_inflateCopy(var dest, source: z_stream): TIdC_INT; cdecl; +begin + inflateCopy := FixupStub('inflateCopy'); {Do not Localize} + Result := inflateCopy(dest, source); +end; + + +function stub_inflateInit_(var strm: z_stream; const version: PIdAnsiChar; + stream_size: TIdC_INT): TIdC_INT; cdecl; +begin + inflateInit_ := FixupStub('inflateInit_'); {Do not Localize} + Result := inflateInit_(strm, version, stream_size); +end; + +function stub_inflateReset(var strm: z_stream): TIdC_INT; cdecl; +begin + inflateReset := FixupStub('inflateReset'); {Do not Localize} + Result := inflateReset(strm); +end; + +function stub_inflateReset2(var strm : z_stream; windowBits : TIdC_INT) : TIdC_INT; cdecl; +begin + inflateReset2 := FixupStub('inflateReset2'); {Do not Localize} + Result := inflateReset2(strm, windowBits); +end; + +function stub_inflatePrime(var strm : z_stream; bits, value : TIdC_INT ) : TIdC_INT; cdecl; +begin + inflatePrime := FixupStub('inflatePrime'); {Do not Localize} + Result := inflatePrime(strm, bits, value); +end; + +function stub_inflateMark(var strm : z_stream) : TIdC_LONG; cdecl; +begin + inflateMark := FixupStub('inflateMark'); {Do not Localize} + Result := inflateMark(strm); +end; + +function stub_inflateSetDictionary(var strm: z_stream; const dictionary: PByte; + dictLength: TIdC_UINT): TIdC_INT;cdecl; +begin + inflateSetDictionary := FixupStub('inflateSetDictionary'); {Do not Localize} + Result := inflateSetDictionary(strm, dictionary, dictLength); +end; + +function stub_inflateSync(var strm: z_stream): TIdC_INT; cdecl; +begin + inflateSync := FixupStub('inflateSync'); {Do not Localize} + Result := inflateSync(strm); +end; + +function stub_uncompress (dest: PByte; var destLen: TIdC_ULONG; + const source: PByte; sourceLen: TIdC_ULONG): TIdC_INT;cdecl; +begin + uncompress := FixupStub('uncompress'); {Do not Localize} + Result := uncompress (dest, destLen, source, sourceLen); +end; + +function stub_zlibCompileFlags : TIdC_ULONG; cdecl; +begin + zlibCompileFlags := FixupStub('zlibCompileFlags'); {Do not Localize} + Result := zlibCompileFlags; +end; + +function stub_zError(err : TIdC_INT) : PIdAnsiChar; cdecl; +begin + zError := FixupStub('zError'); {Do not Localize} + Result := zError(err); +end; + +function stub_inflateSyncPoint(var z : TZStreamRec) : TIdC_INT; cdecl; +begin + inflateSyncPoint := FixupStub('inflateSyncPoint'); {Do not Localize} + Result := inflateSyncPoint(z); +end; + +function stub_get_crc_table : PIdC_ULONG; cdecl; +begin + get_crc_table := FixupStub('get_crc_table'); {Do not Localize} + Result := get_crc_table; +end; + +function stub_inflateUndermine(var strm: z_stream; subvert : TIdC_INT ) : TIdC_INT; cdecl; +begin + inflateUndermine := FixupStub('inflateUndermine'); {Do not Localize} + Result := inflateUndermine(strm,subvert); +end; + +function stub_zlibVersion : PIdAnsiChar; cdecl; +begin + Result := ''; + zlibVersion := FixupStub('zlibVersion'); {Do not Localize} + if Assigned(zlibVersion) then begin + Result := zlibVersion; + end; +end; + +function stub_deflateSetHeader(var strm: z_stream; var head: gz_header): TIdC_INT; cdecl; +begin + deflateSetHeader := FixupStub('deflateSetHeader'); {Do not Localize} + Result := deflateSetHeader(strm, head); +end; + +function stub_inflateGetHeader(var strm: z_stream; var head: gz_header): TIdC_INT; cdecl; +begin + inflateGetHeader := FixupStub('inflateGetHeader'); {Do not Localize} + Result := inflateGetHeader(strm, head); +end; + +procedure InitializeStubs; +begin + adler32 := stub_adler32; + adler32_combine := stub_adler32_combine; + compress := stub_compress; + compress2 := stub_compress2; + compressBound := stub_compressBound; + crc32 := stub_crc32; + crc32_combine := stub_crc32_combine; + deflate := stub_deflate; + deflateBound := stub_deflateBound; + deflateCopy := stub_deflateCopy; + deflateEnd := stub_deflateEnd; + deflateInit_ := stub_deflateInit_; + deflateInit2_ := stub_deflateInit2_; + deflateParams := stub_deflateParams; + deflatePrime := stub_deflatePrime; + deflateTune := stub_deflateTune; + deflateReset := stub_deflateReset; + deflateSetDictionary := stub_deflateSetDictionary; + inflate := stub_inflate; + inflateBack := stub_inflateBack; + inflateBackEnd := stub_inflateBackEnd; + inflateBackInit_ := stub_inflateBackInit_; + inflateCopy := stub_inflateCopy; + inflateEnd := stub_inflateEnd; + inflateInit_ := stub_inflateInit_; + inflateInit2_ := stub_inflateInit2_; + inflateReset := stub_inflateReset; + inflateReset2 := stub_inflateReset2; + inflatePrime := stub_inflatePrime; + inflateMark := stub_inflateMark; + + inflateSetDictionary := stub_inflateSetDictionary; + inflateSync := stub_inflateSync; + uncompress := stub_uncompress; + zlibCompileFlags := stub_zlibCompileFlags; + zError := stub_zError; + inflateUndermine := stub_inflateUndermine; + inflateSyncPoint := stub_inflateSyncPoint; + + get_crc_table := stub_get_crc_table; + zlibVersion := stub_zlibVersion; + deflateSetHeader := stub_deflateSetHeader; + inflateGetHeader := stub_inflateGetHeader; +end; +{$ENDIF} + +{$ENDIF} + +function deflateInit(var strm: z_stream; level: TIdC_INT): TIdC_INT; +begin + {$IFDEF HAS_UNIT_System_ZLib} + Result := System.ZLib.deflateInit(strm, level); + {$ELSE} + // if not Assigned(strm.zalloc) then strm.zalloc := zlibAllocMem; + // if not Assigned(strm.zfree) then strm.zfree := zlibFreeMem; + Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream)); + {$ENDIF} +end; + +function deflateInit2(var strm: z_stream; level, method, windowBits, + memLevel, strategy: TIdC_INT): TIdC_INT; +begin + {$IFDEF HAS_UNIT_System_ZLib} + Result := System.ZLib.deflateInit2(strm, level, method, windowBits, memLevel, strategy); + {$ELSE} + // if not Assigned(strm.zalloc) then strm.zalloc := zlibAllocMem; + // if not Assigned(strm.zfree) then strm.zfree := zlibFreeMem; + Result := deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + ZLIB_VERSION, sizeof(z_stream)); + {$ENDIF} +end; + +const + WBits : array[TZStreamType] of TIdC_INT = (MAX_WBITS, MAX_WBITS + 16, -MAX_WBITS); + +function deflateInitEx(var strm: z_stream; level: TIdC_INT; streamtype: TZStreamType = zsZLib): TIdC_INT; +begin + {$IFDEF HAS_UNIT_System_ZLib} + Result := System.ZLib.deflateInit2(strm, level, Z_DEFLATED, WBits[streamtype], + MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); + {$ELSE} + Result := deflateInit2(strm, level, Z_DEFLATED, WBits[streamtype], + MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); + {$ENDIF} +end; + +function inflateInitEx(var strm: z_stream; streamtype: TZStreamType = zsZLib): TIdC_INT; +begin + {$IFDEF HAS_UNIT_System_ZLib} + Result := System.ZLib.inflateInit2(strm, WBits[streamtype]); + {$ELSE} + Result := inflateInit2(strm, WBits[streamtype]); + {$ENDIF} +end; + +function inflateInit(var strm: z_stream): TIdC_INT; +begin + {$IFDEF HAS_UNIT_System_ZLib} + Result := System.ZLib.inflateInit(strm); + {$ELSE} + // if not Assigned(strm.zalloc) then strm.zalloc := zlibAllocMem; + // if not Assigned(strm.zfree) then strm.zfree := zlibFreeMem; + Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream)); + {$ENDIF} +end; + +function inflateInit2(var strm: z_stream; windowBits: TIdC_INT): TIdC_INT; +begin + // RLebeau: System.ZLib.inflateInit2() simply calls ZLib's inflateInit2_(), + // so I'm not sure how the stream's zalloc and zfree fields are initialized. + // Since we were explicitly initializing them before, let's keep doing so + // for now, unless told otherwise... + if not Assigned(strm.zalloc) then begin + strm.zalloc := zlibAllocMem; + end; + if not Assigned(strm.zfree) then begin + strm.zfree := zlibFreeMem; + end; + {$IFDEF HAS_UNIT_System_ZLib} + Result := System.ZLib.inflateInit2(strm, windowBits); + {$ELSE} + Result := inflateInit2_(strm, windowBits, ZLIB_VERSION, SizeOf(z_stream)); + {$ENDIF} +end; + +function inflateBackInit(var strm: z_stream; windowBits: TIdC_INT; + window: PByte): TIdC_INT; +begin + {$IFDEF HAS_UNIT_System_ZLib} + Result := System.ZLib.inflateBackInit(strm, windowBits, window); + {$ELSE} + Result := inflateBackInit_(strm, windowBits, window, ZLIB_VERSION, SizeOf(z_stream)); + {$ENDIF} +end; + + +{minor additional helper functions} +function _malloc(Size: Integer): Pointer; cdecl; +begin + GetMem(Result, Size); +end; + +procedure _free(Block: Pointer); cdecl; +begin + FreeMem(Block); +end; + +procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl; +begin + FillChar(P^, count, B); +end; + +procedure _memcpy(dest, source: Pointer; count: Integer); cdecl; +begin + Move(source^, dest^, count); +end; + +{$IFNDEF HAS_UNIT_System_ZLib} +function zlibAllocMem(AppData: Pointer; Items, Size: TIdC_UINT): Pointer; cdecl; +begin + GetMem(Result, Items*Size); +// Result := AllocMem(Items * Size); +end; + +procedure zlibFreeMem(AppData, Block: Pointer); cdecl; +begin + FreeMem(Block); +end; +{$ENDIF} + +{$IFDEF STATICLOAD_ZLIB} +function Load : Boolean; +begin + Result := True; +end; + +procedure Unload; +begin +end; + +function Loaded : Boolean; +begin + Result := True; +end; +{$ELSE} + +var + GIdZLibPath: String = ''; + +procedure IdZLibSetLibPath(const APath: String); +begin + if APath <> '' then begin + GIdZLibPath := IndyIncludeTrailingPathDelimiter(APath); + end else begin + GIdZLibPath := ''; + end; +end; + +function Load : Boolean; +begin + Result := Loaded; + if not Result then begin + //In Windows, you should use SafeLoadLibrary instead of the LoadLibrary API + //call because LoadLibrary messes with the FPU control word. + {$IFDEF WINDOWS} + hZLib := SafeLoadLibrary(GIdZLibPath + libzlib); + {$ELSE} + {$IFDEF UNIX} + hZLib := HackLoad(GIdZLibPath + libzlib, libvers); + {$ELSE} + hZLib := LoadLibrary(GIdZLibPath + libzlib); + {$IFDEF USE_INVALIDATE_MOD_CACHE} + InvalidateModuleCache; + {$ENDIF} + {$ENDIF} + {$ENDIF} + Result := Loaded; + end; +end; + +procedure Unload; +begin + if Loaded then begin + FreeLibrary(hZLib); + {$IFDEF DELPHI_CROSS} + InvalidateModuleCache; + {$ENDIF} + hZLib := IdNilHandle; + InitializeStubs; + end; +end; + +function Loaded : Boolean; +begin + Result := (hZLib <> IdNilHandle); +end; +{$ENDIF} + +{$IFNDEF STATICLOAD_ZLIB} +initialization + InitializeStubs; + +finalization + Unload; + InitializeStubs; +{$ENDIF} + +end. diff --git a/Lib/Protocols/IddclProtocols90ASM90.inc b/Lib/Protocols/IddclProtocols90ASM90.inc index eb85ed0c4..0ce3324ff 100644 --- a/Lib/Protocols/IddclProtocols90ASM90.inc +++ b/Lib/Protocols/IddclProtocols90ASM90.inc @@ -1,12 +1,12 @@ -[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Protocols Design-Time Package for Borland Developer Studio')] -[assembly: AssemblyConfiguration('')] -[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] -[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyTrademark('')] -[assembly: AssemblyCulture('')] -[assembly: AssemblyTitle('Indy .NET Protocols Design-Time Package')] -[assembly: AssemblyVersion('10.7.0.*')] -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile('')] -[assembly: AssemblyKeyName('')] +[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Protocols Design-Time Package for Borland Developer Studio')] +[assembly: AssemblyConfiguration('')] +[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] +[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyTrademark('')] +[assembly: AssemblyCulture('')] +[assembly: AssemblyTitle('Indy .NET Protocols Design-Time Package')] +[assembly: AssemblyVersion('10.7.0.*')] +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile('')] +[assembly: AssemblyKeyName('')] diff --git a/Lib/Protocols/IndyProtocols100.dpk b/Lib/Protocols/IndyProtocols100.dpk index b829c6879..70c885a29 100644 --- a/Lib/Protocols/IndyProtocols100.dpk +++ b/Lib/Protocols/IndyProtocols100.dpk @@ -1,270 +1,270 @@ -package IndyProtocols100; - -{$R *.res} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - rtl, - IndySystem100, - IndyCore100; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSPI in 'IdSSPI.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols100; + +{$R *.res} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + rtl, + IndySystem100, + IndyCore100; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSPI in 'IdSSPI.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols100Net.dpk b/Lib/Protocols/IndyProtocols100Net.dpk index da921bb92..d6266a0e2 100644 --- a/Lib/Protocols/IndyProtocols100Net.dpk +++ b/Lib/Protocols/IndyProtocols100Net.dpk @@ -1,260 +1,260 @@ -package IndyProtocols100Net; - -{$ALIGN 0} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - Borland.Delphi, - Borland.VclRtl, - IndySystem100Net, - IndyCore100Net; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas'; -{$I IdProtocols90ASM90.inc} - -end. +package IndyProtocols100Net; + +{$ALIGN 0} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + Borland.Delphi, + Borland.VclRtl, + IndySystem100Net, + IndyCore100Net; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas'; +{$I IdProtocols90ASM90.inc} + +end. diff --git a/Lib/Protocols/IndyProtocols110.dpk b/Lib/Protocols/IndyProtocols110.dpk index b04e5c985..b65e4f462 100644 --- a/Lib/Protocols/IndyProtocols110.dpk +++ b/Lib/Protocols/IndyProtocols110.dpk @@ -1,270 +1,270 @@ -package IndyProtocols110; - -{$R *.res} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - rtl, - IndySystem110, - IndyCore110; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSPI in 'IdSSPI.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols110; + +{$R *.res} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + rtl, + IndySystem110, + IndyCore110; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSPI in 'IdSSPI.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols110Net.dpk b/Lib/Protocols/IndyProtocols110Net.dpk index 1dc034c10..1a0dd57df 100644 --- a/Lib/Protocols/IndyProtocols110Net.dpk +++ b/Lib/Protocols/IndyProtocols110Net.dpk @@ -1,261 +1,261 @@ -package IndyProtocols110Net; - -{$ALIGN 0} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - Borland.Delphi, - Borland.VclRtl, - IndySystem110Net, - IndyCore110Net; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSLDotNET in 'IdSSLDotNET.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas'; -{$I IdProtocols90ASM90.inc} - -end. +package IndyProtocols110Net; + +{$ALIGN 0} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + Borland.Delphi, + Borland.VclRtl, + IndySystem110Net, + IndyCore110Net; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSLDotNET in 'IdSSLDotNET.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas'; +{$I IdProtocols90ASM90.inc} + +end. diff --git a/Lib/Protocols/IndyProtocols120.dpk b/Lib/Protocols/IndyProtocols120.dpk index 4ce1f96d0..22f098bd2 100644 --- a/Lib/Protocols/IndyProtocols120.dpk +++ b/Lib/Protocols/IndyProtocols120.dpk @@ -1,270 +1,270 @@ -package IndyProtocols120; - -{$R *.res} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - rtl, - IndySystem120, - IndyCore120; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSPI in 'IdSSPI.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols120; + +{$R *.res} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + rtl, + IndySystem120, + IndyCore120; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSPI in 'IdSSPI.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols120Net.dpk b/Lib/Protocols/IndyProtocols120Net.dpk index 206d54591..5265ec67e 100644 --- a/Lib/Protocols/IndyProtocols120Net.dpk +++ b/Lib/Protocols/IndyProtocols120Net.dpk @@ -1,261 +1,261 @@ -package IndyProtocols120Net; - -{$ALIGN 0} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - Borland.Delphi, - Borland.VclRtl, - IndySystem120Net, - IndyCore120Net; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSLDotNET in 'IdSSLDotNET.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas'; -{$I IdProtocols90ASM90.inc} - -end. +package IndyProtocols120Net; + +{$ALIGN 0} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + Borland.Delphi, + Borland.VclRtl, + IndySystem120Net, + IndyCore120Net; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSLDotNET in 'IdSSLDotNET.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas'; +{$I IdProtocols90ASM90.inc} + +end. diff --git a/Lib/Protocols/IndyProtocols130.dpk b/Lib/Protocols/IndyProtocols130.dpk index 6106123f8..fce79237b 100644 --- a/Lib/Protocols/IndyProtocols130.dpk +++ b/Lib/Protocols/IndyProtocols130.dpk @@ -1,270 +1,270 @@ -package IndyProtocols130; - -{$R *.res} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - rtl, - IndySystem130, - IndyCore130; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSPI in 'IdSSPI.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols130; + +{$R *.res} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + rtl, + IndySystem130, + IndyCore130; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSPI in 'IdSSPI.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols130Net.dpk b/Lib/Protocols/IndyProtocols130Net.dpk index 518e65ef8..0e9075a92 100644 --- a/Lib/Protocols/IndyProtocols130Net.dpk +++ b/Lib/Protocols/IndyProtocols130Net.dpk @@ -1,261 +1,261 @@ -package IndyProtocols130Net; - -{$ALIGN 0} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - Borland.Delphi, - Borland.VclRtl, - IndySystem130Net, - IndyCore130Net; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSLDotNET in 'IdSSLDotNET.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas'; -{$I IdProtocols90ASM90.inc} - -end. +package IndyProtocols130Net; + +{$ALIGN 0} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + Borland.Delphi, + Borland.VclRtl, + IndySystem130Net, + IndyCore130Net; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSLDotNET in 'IdSSLDotNET.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas'; +{$I IdProtocols90ASM90.inc} + +end. diff --git a/Lib/Protocols/IndyProtocols140.dpk b/Lib/Protocols/IndyProtocols140.dpk index 78e88c26b..93b53fcf9 100644 --- a/Lib/Protocols/IndyProtocols140.dpk +++ b/Lib/Protocols/IndyProtocols140.dpk @@ -1,271 +1,271 @@ -package IndyProtocols140; - -{$R *.res} -{$ALIGN 8} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - rtl, - IndySystem140, - IndyCore140; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSPI in 'IdSSPI.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols140; + +{$R *.res} +{$ALIGN 8} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + rtl, + IndySystem140, + IndyCore140; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSPI in 'IdSSPI.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols150.dpk b/Lib/Protocols/IndyProtocols150.dpk index 6dd9e180e..7ff17eacc 100644 --- a/Lib/Protocols/IndyProtocols150.dpk +++ b/Lib/Protocols/IndyProtocols150.dpk @@ -1,271 +1,271 @@ -package IndyProtocols150; - -{$R *.res} -{$ALIGN 8} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - rtl, - IndySystem150, - IndyCore150; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSPI in 'IdSSPI.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols150; + +{$R *.res} +{$ALIGN 8} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + rtl, + IndySystem150, + IndyCore150; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSPI in 'IdSSPI.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols160.dpk b/Lib/Protocols/IndyProtocols160.dpk index 0463f7853..07dd3003c 100644 --- a/Lib/Protocols/IndyProtocols160.dpk +++ b/Lib/Protocols/IndyProtocols160.dpk @@ -1,291 +1,291 @@ -package IndyProtocols160; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -// RLebeau: cannot use IdCompilerDefines.inc here! - -requires - rtl, - IndySystem160, - IndyCore160; - -{$IFNDEF WINDOWS} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} -{$ENDIF} - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - {$IFDEF WINDOWS} - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - {$ENDIF} - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - {$IFDEF WINDOWS} - IdSSPI in 'IdSSPI.pas', - {$ENDIF} - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols160; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO ON} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$ENDIF IMPLICITBUILDING} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +// RLebeau: cannot use IdCompilerDefines.inc here! + +requires + rtl, + IndySystem160, + IndyCore160; + +{$IFNDEF WINDOWS} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} +{$ENDIF} + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + {$IFDEF WINDOWS} + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + {$ENDIF} + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + {$IFDEF WINDOWS} + IdSSPI in 'IdSSPI.pas', + {$ENDIF} + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols160.dproj b/Lib/Protocols/IndyProtocols160.dproj index 95d65c09f..5cff779dc 100644 --- a/Lib/Protocols/IndyProtocols160.dproj +++ b/Lib/Protocols/IndyProtocols160.dproj @@ -1,423 +1,423 @@ - - - {EDA5B84B-7D45-478B-A75C-DA65C6591B6A} - IndyProtocols160.dpk - True - Debug - 7 - Package - None - 13.4 - Win32 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - All - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - true - Indy 10 Protocols - System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - true - 1033 - false - false - true - false - false - false - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - true - IndyProtocols_Icon.ico - - - CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName) - - - All - IndyProtocols_Icon.ico - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - true - 1033 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - - - false - false - 0 - RELEASE;$(DCC_Define) - - - DEBUG;$(DCC_Define) - false - true - - - All - true - - - true - - - All - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - IndyProtocols160.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Embarcadero MyBase DataAccess Components - Embarcadero DataSnap Connection Components - - - - True - True - True - - - 12 - - - - + + + {EDA5B84B-7D45-478B-A75C-DA65C6591B6A} + IndyProtocols160.dpk + True + Debug + 7 + Package + None + 13.4 + Win32 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + All + 00400000 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + true + Indy 10 Protocols + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + true + 1033 + false + false + true + false + false + false + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + true + IndyProtocols_Icon.ico + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName) + + + All + IndyProtocols_Icon.ico + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + true + 1033 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + false + false + 0 + RELEASE;$(DCC_Define) + + + DEBUG;$(DCC_Define) + false + true + + + All + true + + + true + + + All + true + + + + MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Package + + + + IndyProtocols160.dpk + + + True + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1033 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + Embarcadero MyBase DataAccess Components + Embarcadero DataSnap Connection Components + + + + True + True + True + + + 12 + + + + diff --git a/Lib/Protocols/IndyProtocols170.dpk b/Lib/Protocols/IndyProtocols170.dpk index b8c7b2bf7..859a6d7a9 100644 --- a/Lib/Protocols/IndyProtocols170.dpk +++ b/Lib/Protocols/IndyProtocols170.dpk @@ -1,293 +1,293 @@ -package IndyProtocols170; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -// RLebeau: cannot use IdCompilerDefines.inc here! - -requires - {$IFNDEF NEXTGEN} - rtl, - {$ENDIF} - IndySystem170, - IndyCore170; - -{$IFNDEF WINDOWS} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} -{$ENDIF} - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - {$IFDEF WINDOWS} - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - {$ENDIF} - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - {$IFDEF WINDOWS} - IdSSPI in 'IdSSPI.pas', - {$ENDIF} - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols170; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO ON} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$ENDIF IMPLICITBUILDING} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +// RLebeau: cannot use IdCompilerDefines.inc here! + +requires + {$IFNDEF NEXTGEN} + rtl, + {$ENDIF} + IndySystem170, + IndyCore170; + +{$IFNDEF WINDOWS} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} +{$ENDIF} + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + {$IFDEF WINDOWS} + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + {$ENDIF} + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + {$IFDEF WINDOWS} + IdSSPI in 'IdSSPI.pas', + {$ENDIF} + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols170.dproj b/Lib/Protocols/IndyProtocols170.dproj index 08b09f281..af7575c81 100644 --- a/Lib/Protocols/IndyProtocols170.dproj +++ b/Lib/Protocols/IndyProtocols170.dproj @@ -1,385 +1,385 @@ - - - {78E42009-9193-492B-9190-33D0EFCF966E} - IndyProtocols170.dpk - True - Debug - 1 - Package - None - 14.3 - Win32 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - All - ..\DCP;$(DCC_UnitSearchPath) - ..\BPI - ..\DCP - false - true - 1033 - true - false - false - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - false - 00400000 - System;Xml;Data;Datasnap;Web;Soap;Winapi;Vcl;$(DCC_Namespace) - true - Indy 10 Protocols - false - - - 1033 - true - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - - - false - false - 0 - RELEASE;$(DCC_Define) - - - DEBUG;$(DCC_Define) - true - false - - - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - IndyProtocols170.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - False - True - False - - - 12 - - - - + + + {78E42009-9193-492B-9190-33D0EFCF966E} + IndyProtocols170.dpk + True + Debug + 1 + Package + None + 14.3 + Win32 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + All + ..\DCP;$(DCC_UnitSearchPath) + ..\BPI + ..\DCP + false + true + 1033 + true + false + false + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + false + 00400000 + System;Xml;Data;Datasnap;Web;Soap;Winapi;Vcl;$(DCC_Namespace) + true + Indy 10 Protocols + false + + + 1033 + true + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + false + false + 0 + RELEASE;$(DCC_Define) + + + DEBUG;$(DCC_Define) + true + false + + + true + + + + MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Package + + + + IndyProtocols170.dpk + + + True + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1033 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + False + True + False + + + 12 + + + + diff --git a/Lib/Protocols/IndyProtocols180.dpk b/Lib/Protocols/IndyProtocols180.dpk index 70a578892..1726f9295 100644 --- a/Lib/Protocols/IndyProtocols180.dpk +++ b/Lib/Protocols/IndyProtocols180.dpk @@ -1,302 +1,302 @@ -package IndyProtocols180; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$DEFINE VER250} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -// RLebeau: cannot use IdCompilerDefines.inc here! - -{$DEFINE HAS_PKG_RTL} -{$IFDEF NEXTGEN} - {$IFDEF IOS} - // there is no RTL package available for iOS - {$UNDEF HAS_PKG_RTL} - {$ENDIF} -{$ENDIF} - -requires - {$IFDEF HAS_PKG_RTL} - rtl, - {$ENDIF} - IndySystem180, - IndyCore180; - -{$IFNDEF WINDOWS} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} -{$ENDIF} - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - {$IFDEF WINDOWS} - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - {$ENDIF} - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - {$IFDEF WINDOWS} - IdSSPI in 'IdSSPI.pas', - {$ENDIF} - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols180; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO ON} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$DEFINE VER250} +{$ENDIF IMPLICITBUILDING} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD OFF} + +// RLebeau: cannot use IdCompilerDefines.inc here! + +{$DEFINE HAS_PKG_RTL} +{$IFDEF NEXTGEN} + {$IFDEF IOS} + // there is no RTL package available for iOS + {$UNDEF HAS_PKG_RTL} + {$ENDIF} +{$ENDIF} + +requires + {$IFDEF HAS_PKG_RTL} + rtl, + {$ENDIF} + IndySystem180, + IndyCore180; + +{$IFNDEF WINDOWS} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} +{$ENDIF} + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + {$IFDEF WINDOWS} + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + {$ENDIF} + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + {$IFDEF WINDOWS} + IdSSPI in 'IdSSPI.pas', + {$ENDIF} + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols180.dproj b/Lib/Protocols/IndyProtocols180.dproj index a213aae8e..23e2c3212 100644 --- a/Lib/Protocols/IndyProtocols180.dproj +++ b/Lib/Protocols/IndyProtocols180.dproj @@ -1,422 +1,422 @@ - - - {9165FD9C-BA6D-4584-A9B4-0858F66AC0CA} - IndyProtocols180.dpk - True - Release - 79 - Package - None - 14.6 - Win32 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - true - ..\Output\OBJ\$(Platform)\$(Config) - ..\Output\DCU\$(Platform)\$(Config) - ..\Output\BPI\$(Platform)\$(Config) - ..\Output\HPP\$(Platform)\$(Config) - ..\Output\DCP\$(Platform)\$(Config);$(DCC_UnitSearchPath) - ..\Output\BPI\$(Platform)\$(Config) - ..\Output\DCP\$(Platform)\$(Config) - All - VER250;$(DCC_Define) - true - false - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;CFBundleExecutable= - true - Indy 10 Protocols - true - 1033 - false - false - false - 00400000 - System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - false - - - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - true - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - - - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - - - RELEASE;$(DCC_Define) - false - false - 0 - - - DEBUG;$(DCC_Define) - true - false - - - Debug - - - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - IndyProtocols180.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - - - - - - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - True - True - True - True - - - 12 - - - - + + + {9165FD9C-BA6D-4584-A9B4-0858F66AC0CA} + IndyProtocols180.dpk + True + Release + 79 + Package + None + 14.6 + Win32 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + true + ..\Output\OBJ\$(Platform)\$(Config) + ..\Output\DCU\$(Platform)\$(Config) + ..\Output\BPI\$(Platform)\$(Config) + ..\Output\HPP\$(Platform)\$(Config) + ..\Output\DCP\$(Platform)\$(Config);$(DCC_UnitSearchPath) + ..\Output\BPI\$(Platform)\$(Config) + ..\Output\DCP\$(Platform)\$(Config) + All + VER250;$(DCC_Define) + true + false + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;CFBundleExecutable= + true + Indy 10 Protocols + true + 1033 + false + false + false + 00400000 + System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) + false + + + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + true + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + + + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + + + RELEASE;$(DCC_Define) + false + false + 0 + + + DEBUG;$(DCC_Define) + true + false + + + Debug + + + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + true + + + + MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Package + + + + IndyProtocols180.dpk + + + True + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1033 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + + + + + + + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + True + True + True + True + True + + + 12 + + + + diff --git a/Lib/Protocols/IndyProtocols190.dpk b/Lib/Protocols/IndyProtocols190.dpk index f40d925ce..34a04c81c 100644 --- a/Lib/Protocols/IndyProtocols190.dpk +++ b/Lib/Protocols/IndyProtocols190.dpk @@ -1,302 +1,302 @@ -package IndyProtocols190; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$DEFINE VER260} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -// RLebeau: cannot use IdCompilerDefines.inc here! - -{$DEFINE HAS_PKG_RTL} -{$IFDEF NEXTGEN} - {$IFDEF IOS} - // there is no RTL package available for iOS - {$UNDEF HAS_PKG_RTL} - {$ENDIF} -{$ENDIF} - -requires - {$IFDEF HAS_PKG_RTL} - rtl, - {$ENDIF} - IndySystem190, - IndyCore190; - -{$IFNDEF WINDOWS} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} -{$ENDIF} - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - {$IFDEF WINDOWS} - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - {$ENDIF} - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - {$IFDEF WINDOWS} - IdSSPI in 'IdSSPI.pas', - {$ENDIF} - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols190; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO ON} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$DEFINE VER260} +{$ENDIF IMPLICITBUILDING} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD OFF} + +// RLebeau: cannot use IdCompilerDefines.inc here! + +{$DEFINE HAS_PKG_RTL} +{$IFDEF NEXTGEN} + {$IFDEF IOS} + // there is no RTL package available for iOS + {$UNDEF HAS_PKG_RTL} + {$ENDIF} +{$ENDIF} + +requires + {$IFDEF HAS_PKG_RTL} + rtl, + {$ENDIF} + IndySystem190, + IndyCore190; + +{$IFNDEF WINDOWS} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} +{$ENDIF} + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + {$IFDEF WINDOWS} + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + {$ENDIF} + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + {$IFDEF WINDOWS} + IdSSPI in 'IdSSPI.pas', + {$ENDIF} + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols190.dproj b/Lib/Protocols/IndyProtocols190.dproj index 5a1e5aa8e..2d3965589 100644 --- a/Lib/Protocols/IndyProtocols190.dproj +++ b/Lib/Protocols/IndyProtocols190.dproj @@ -1,470 +1,470 @@ - - - {ADC196E7-3C9E-443C-B330-B9615BE3D6C4} - IndyProtocols190.dpk - True - Release - 95 - Package - None - 15.3 - Win32 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - ..\Output\BPI\$(Platform)\$(Config) - All - ..\Output\OBJ\$(Platform)\$(Config) - ..\Output\HPP\$(Platform)\$(Config) - Vcl;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - true - true - true - false - false - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=;package=;label=;versionCode=0;versionName=;persistent=;restoreAnyVersion=;installLocation= - false - true - Indy 10 Protocols - false - false - 1033 - - - iPhoneAndiPad - true - $(MSBuildProjectName) - Debug - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=6.0;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist - - - true - iPhoneAndiPad - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=6.0;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist - - - CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities - - - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - true - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - - - true - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - - - false - 0 - 0 - RELEASE;$(DCC_Define) - - - true - DEBUG;$(DCC_Define) - false - - - true - - - true - - - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - IndyProtocols190.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - - - - - - - - - - - - - - - - - - - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - True - True - True - True - True - - - 12 - - - - + + + {ADC196E7-3C9E-443C-B330-B9615BE3D6C4} + IndyProtocols190.dpk + True + Release + 95 + Package + None + 15.3 + Win32 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + ..\Output\BPI\$(Platform)\$(Config) + All + ..\Output\OBJ\$(Platform)\$(Config) + ..\Output\HPP\$(Platform)\$(Config) + Vcl;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) + true + true + true + false + false + 00400000 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=;package=;label=;versionCode=0;versionName=;persistent=;restoreAnyVersion=;installLocation= + false + true + Indy 10 Protocols + false + false + 1033 + + + iPhoneAndiPad + true + $(MSBuildProjectName) + Debug + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=6.0;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist + + + true + iPhoneAndiPad + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=6.0;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities + + + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + true + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + true + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + false + 0 + 0 + RELEASE;$(DCC_Define) + + + true + DEBUG;$(DCC_Define) + false + + + true + + + true + + + true + + + + MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Package + + + + IndyProtocols190.dpk + + + True + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1033 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + + + + + + + + + + + + + + + + + + + + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + True + True + True + True + True + True + + + 12 + + + + diff --git a/Lib/Protocols/IndyProtocols200.dpk b/Lib/Protocols/IndyProtocols200.dpk index 92b941ac4..f304c6c9e 100644 --- a/Lib/Protocols/IndyProtocols200.dpk +++ b/Lib/Protocols/IndyProtocols200.dpk @@ -1,302 +1,302 @@ -package IndyProtocols200; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$DEFINE VER270} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -// RLebeau: cannot use IdCompilerDefines.inc here! - -{$DEFINE HAS_PKG_RTL} -{$IFDEF NEXTGEN} - {$IFDEF IOS} - // there is no RTL package available for iOS - {$UNDEF HAS_PKG_RTL} - {$ENDIF} -{$ENDIF} - -requires - {$IFDEF HAS_PKG_RTL} - rtl, - {$ENDIF} - IndySystem200, - IndyCore200; - -{$IFNDEF WINDOWS} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} -{$ENDIF} - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - {$IFDEF WINDOWS} - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - {$ENDIF} - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - {$IFDEF WINDOWS} - IdSSPI in 'IdSSPI.pas', - {$ENDIF} - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols200; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO ON} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$DEFINE VER270} +{$ENDIF IMPLICITBUILDING} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD OFF} + +// RLebeau: cannot use IdCompilerDefines.inc here! + +{$DEFINE HAS_PKG_RTL} +{$IFDEF NEXTGEN} + {$IFDEF IOS} + // there is no RTL package available for iOS + {$UNDEF HAS_PKG_RTL} + {$ENDIF} +{$ENDIF} + +requires + {$IFDEF HAS_PKG_RTL} + rtl, + {$ENDIF} + IndySystem200, + IndyCore200; + +{$IFNDEF WINDOWS} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} +{$ENDIF} + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + {$IFDEF WINDOWS} + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + {$ENDIF} + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + {$IFDEF WINDOWS} + IdSSPI in 'IdSSPI.pas', + {$ENDIF} + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols200.dproj b/Lib/Protocols/IndyProtocols200.dproj index aaec9a93a..0b0c31425 100644 --- a/Lib/Protocols/IndyProtocols200.dproj +++ b/Lib/Protocols/IndyProtocols200.dproj @@ -1,458 +1,458 @@ - - - {5B71C9C6-617B-4EEF-83D8-5CBB6648FF18} - IndyProtocols200.dpk - True - Debug - 95 - Package - None - 15.4 - Win32 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - false - true - false - 00400000 - All - System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - true - HAS_PKG_RTL;$(DCC_Define) - Indy 10 Protocols - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=;package=;label=;versionCode=;versionName=;persistent=;restoreAnyVersion=;installLocation=;largeHeap=;theme=;hardwareAccelerated= - false - 1033 - true - false - false - - - iPhoneAndiPad - $(MSBuildProjectName) - true - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=6.0;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist - Debug - - - iPhoneAndiPad - true - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=6.0;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist - - - CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities - - - ..\Output\HPP\$(Platform)\$(Config) - ..\Output\OBJ\$(Platform)\$(Config) - ..\Output\BPI\$(Platform)\$(Config) - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - true - - - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - true - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - - - 0 - 0 - false - RELEASE;$(DCC_Define) - - - true - DEBUG;$(DCC_Define) - false - - - true - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - IndyProtocols200.dpk - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - LiveBinding Expression Components FireDac - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - True - True - True - True - True - - - 12 - - - - + + + {5B71C9C6-617B-4EEF-83D8-5CBB6648FF18} + IndyProtocols200.dpk + True + Debug + 95 + Package + None + 15.4 + Win32 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + false + true + false + 00400000 + All + System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) + true + HAS_PKG_RTL;$(DCC_Define) + Indy 10 Protocols + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;UIDeviceFamily=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;UISupportedInterfaceOrientations=;CFBundleExecutable=;CFBundleResourceSpecification=;LSRequiresIPhoneOS=;CFBundleInfoDictionaryVersion=;CFBundleDevelopmentRegion=;package=;label=;versionCode=;versionName=;persistent=;restoreAnyVersion=;installLocation=;largeHeap=;theme=;hardwareAccelerated= + false + 1033 + true + false + false + + + iPhoneAndiPad + $(MSBuildProjectName) + true + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=6.0;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist + Debug + + + iPhoneAndiPad + true + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=6.0;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities + + + ..\Output\HPP\$(Platform)\$(Config) + ..\Output\OBJ\$(Platform)\$(Config) + ..\Output\BPI\$(Platform)\$(Config) + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + true + + + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + true + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + 0 + 0 + false + RELEASE;$(DCC_Define) + + + true + DEBUG;$(DCC_Define) + false + + + true + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + + MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Package + + + + IndyProtocols200.dpk + + + True + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1033 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + LiveBinding Expression Components FireDac + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + True + True + True + True + True + True + + + 12 + + + + diff --git a/Lib/Protocols/IndyProtocols210.dpk b/Lib/Protocols/IndyProtocols210.dpk index 4653563c6..617e7cf42 100644 --- a/Lib/Protocols/IndyProtocols210.dpk +++ b/Lib/Protocols/IndyProtocols210.dpk @@ -1,302 +1,302 @@ -package IndyProtocols210; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO ON} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$DEFINE VER280} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -// RLebeau: cannot use IdCompilerDefines.inc here! - -{$DEFINE HAS_PKG_RTL} -{$IFDEF NEXTGEN} - {$IFDEF IOS} - // there is no RTL package available for iOS - {$UNDEF HAS_PKG_RTL} - {$ENDIF} -{$ENDIF} - -requires - {$IFDEF HAS_PKG_RTL} - rtl, - {$ENDIF} - IndySystem210, - IndyCore210; - -{$IFNDEF WINDOWS} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} -{$ENDIF} - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - {$IFDEF WINDOWS} - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - {$ENDIF} - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - {$IFDEF WINDOWS} - IdSSPI in 'IdSSPI.pas', - {$ENDIF} - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols210; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO ON} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$DEFINE VER280} +{$ENDIF IMPLICITBUILDING} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD OFF} + +// RLebeau: cannot use IdCompilerDefines.inc here! + +{$DEFINE HAS_PKG_RTL} +{$IFDEF NEXTGEN} + {$IFDEF IOS} + // there is no RTL package available for iOS + {$UNDEF HAS_PKG_RTL} + {$ENDIF} +{$ENDIF} + +requires + {$IFDEF HAS_PKG_RTL} + rtl, + {$ENDIF} + IndySystem210, + IndyCore210; + +{$IFNDEF WINDOWS} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} +{$ENDIF} + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + {$IFDEF WINDOWS} + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + {$ENDIF} + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + {$IFDEF WINDOWS} + IdSSPI in 'IdSSPI.pas', + {$ENDIF} + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols210.dproj b/Lib/Protocols/IndyProtocols210.dproj index fd378e486..359dec4e6 100644 --- a/Lib/Protocols/IndyProtocols210.dproj +++ b/Lib/Protocols/IndyProtocols210.dproj @@ -1,428 +1,428 @@ - - - {F186C433-64A7-4462-B16E-16BDEC0A8AC3} - IndyProtocols210.dpk - True - Debug - 95 - Package - None - 16.0 - Win32 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - false - System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - true - false - IndyProtocols210 - false - true - 00400000 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= - HAS_PKG_RTL;$(DCC_Define) - 1033 - true - Indy 10 Protocols - true - false - false - - - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=preferExternal;largeHeap=False;theme=TitleBar;hardwareAccelerated=true - Debug - - - true - iPhoneAndiPad - $(MSBuildProjectName) - Debug - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist - - - iPhoneAndiPad - true - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist - - - CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities - - - ..\Output\OBJ\$(Platform)\$(Config) - ..\Output\HPP\$(Platform)\$(Config) - ..\Output\BPI\$(Platform)\$(Config) - All - true - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - 1033 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - - - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - true - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - - - RELEASE;$(DCC_Define) - false - 0 - 0 - - - false - DEBUG;$(DCC_Define) - true - - - true - - - true - - - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - IndyProtocols210.dpk - - - - True - True - True - True - True - True - - - 12 - - - - + + + {F186C433-64A7-4462-B16E-16BDEC0A8AC3} + IndyProtocols210.dpk + True + Debug + 95 + Package + None + 16.0 + Win32 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + false + System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) + true + false + IndyProtocols210 + false + true + 00400000 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= + HAS_PKG_RTL;$(DCC_Define) + 1033 + true + Indy 10 Protocols + true + false + false + + + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=preferExternal;largeHeap=False;theme=TitleBar;hardwareAccelerated=true + Debug + + + true + iPhoneAndiPad + $(MSBuildProjectName) + Debug + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist + + + iPhoneAndiPad + true + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities + + + ..\Output\OBJ\$(Platform)\$(Config) + ..\Output\HPP\$(Platform)\$(Config) + ..\Output\BPI\$(Platform)\$(Config) + All + true + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + 1033 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) + true + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + + + RELEASE;$(DCC_Define) + false + 0 + 0 + + + false + DEBUG;$(DCC_Define) + true + + + true + + + true + + + true + + + + MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Package + + + + IndyProtocols210.dpk + + + + True + True + True + True + True + True + + + 12 + + + + diff --git a/Lib/Protocols/IndyProtocols220.dpk b/Lib/Protocols/IndyProtocols220.dpk index ddbe9ecb1..9c350de68 100644 --- a/Lib/Protocols/IndyProtocols220.dpk +++ b/Lib/Protocols/IndyProtocols220.dpk @@ -1,302 +1,302 @@ -package IndyProtocols220; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$DEFINE VER290} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -// RLebeau: cannot use IdCompilerDefines.inc here! - -{$DEFINE HAS_PKG_RTL} -{$IFDEF NEXTGEN} - {$IFDEF IOS} - // there is no RTL package available for iOS - {$UNDEF HAS_PKG_RTL} - {$ENDIF} -{$ENDIF} - -requires - {$IFDEF HAS_PKG_RTL} - rtl, - {$ENDIF} - IndySystem220, - IndyCore220; - -{$IFNDEF WINDOWS} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} -{$ENDIF} - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - {$IFDEF WINDOWS} - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - {$ENDIF} - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - {$IFDEF WINDOWS} - IdSSPI in 'IdSSPI.pas', - {$ENDIF} - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols220; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$DEFINE VER290} +{$ENDIF IMPLICITBUILDING} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD OFF} + +// RLebeau: cannot use IdCompilerDefines.inc here! + +{$DEFINE HAS_PKG_RTL} +{$IFDEF NEXTGEN} + {$IFDEF IOS} + // there is no RTL package available for iOS + {$UNDEF HAS_PKG_RTL} + {$ENDIF} +{$ENDIF} + +requires + {$IFDEF HAS_PKG_RTL} + rtl, + {$ENDIF} + IndySystem220, + IndyCore220; + +{$IFNDEF WINDOWS} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} +{$ENDIF} + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + {$IFDEF WINDOWS} + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + {$ENDIF} + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + {$IFDEF WINDOWS} + IdSSPI in 'IdSSPI.pas', + {$ENDIF} + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols220.dproj b/Lib/Protocols/IndyProtocols220.dproj index ecf1cabe6..c834f66a6 100644 --- a/Lib/Protocols/IndyProtocols220.dproj +++ b/Lib/Protocols/IndyProtocols220.dproj @@ -1,469 +1,469 @@ - - - {3BCFEC11-6408-4BCB-9993-99C61936CB8A} - IndyProtocols220.dpk - True - Debug - 1119 - Package - None - 17.2 - Win32 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - Indy 10 Protocols - true - false - true - false - true - false - IndyProtocols220 - 00400000 - false - System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - 1033 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= - true - false - - - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=preferExternal;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar - - - true - iPhoneAndiPad - $(MSBuildProjectName) - Debug - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false - - - true - iPhoneAndiPad - $(MSBuildProjectName) - Debug - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false - - - iPhoneAndiPad - true - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false - - - CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user - - - ..\Output\OBJ\$(Platform)\$(Config) - ..\Output\BPI\$(Platform)\$(Config) - ..\Output\HPP\$(Platform)\$(Config) - All - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - true - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) - - - true - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) - - - false - 0 - RELEASE;$(DCC_Define) - 0 - - - true - DEBUG;$(DCC_Define) - false - - - $(MSBuildProjectName) - true - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false - iPhoneAndiPad - true - - - true - - - true - - - true - - - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - IndyProtocols220.dpk - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - True - True - True - True - True - True - - - 12 - - - - + + + {3BCFEC11-6408-4BCB-9993-99C61936CB8A} + IndyProtocols220.dpk + True + Debug + 1119 + Package + None + 17.2 + Win32 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + Indy 10 Protocols + true + false + true + false + true + false + IndyProtocols220 + 00400000 + false + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + 1033 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= + true + false + + + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=preferExternal;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar + + + true + iPhoneAndiPad + $(MSBuildProjectName) + Debug + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false + + + true + iPhoneAndiPad + $(MSBuildProjectName) + Debug + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false + + + iPhoneAndiPad + true + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user + + + ..\Output\OBJ\$(Platform)\$(Config) + ..\Output\BPI\$(Platform)\$(Config) + ..\Output\HPP\$(Platform)\$(Config) + All + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + true + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) + + + true + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) + + + false + 0 + RELEASE;$(DCC_Define) + 0 + + + true + DEBUG;$(DCC_Define) + false + + + $(MSBuildProjectName) + true + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false + iPhoneAndiPad + true + + + true + + + true + + + true + + + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + true + + + + MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Package + + + + IndyProtocols220.dpk + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + True + True + True + True + True + True + True + + + 12 + + + + diff --git a/Lib/Protocols/IndyProtocols230.dpk b/Lib/Protocols/IndyProtocols230.dpk index 1d8778e82..6e4088fc3 100644 --- a/Lib/Protocols/IndyProtocols230.dpk +++ b/Lib/Protocols/IndyProtocols230.dpk @@ -1,302 +1,302 @@ -package IndyProtocols230; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$DEFINE VER300} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -// RLebeau: cannot use IdCompilerDefines.inc here! - -{$DEFINE HAS_PKG_RTL} -{$IFDEF NEXTGEN} - {$IFDEF IOS} - // there is no RTL package available for iOS - {$UNDEF HAS_PKG_RTL} - {$ENDIF} -{$ENDIF} - -requires - {$IFDEF HAS_PKG_RTL} - rtl, - {$ENDIF} - IndySystem230, - IndyCore230; - -{$IFNDEF WINDOWS} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} -{$ENDIF} - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - {$IFDEF WINDOWS} - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - {$ENDIF} - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - {$IFDEF WINDOWS} - IdSSPI in 'IdSSPI.pas', - {$ENDIF} - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols230; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$DEFINE VER300} +{$ENDIF IMPLICITBUILDING} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD OFF} + +// RLebeau: cannot use IdCompilerDefines.inc here! + +{$DEFINE HAS_PKG_RTL} +{$IFDEF NEXTGEN} + {$IFDEF IOS} + // there is no RTL package available for iOS + {$UNDEF HAS_PKG_RTL} + {$ENDIF} +{$ENDIF} + +requires + {$IFDEF HAS_PKG_RTL} + rtl, + {$ENDIF} + IndySystem230, + IndyCore230; + +{$IFNDEF WINDOWS} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} +{$ENDIF} + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + {$IFDEF WINDOWS} + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + {$ENDIF} + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + {$IFDEF WINDOWS} + IdSSPI in 'IdSSPI.pas', + {$ENDIF} + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols230.dproj b/Lib/Protocols/IndyProtocols230.dproj index dc8ac0276..4dddf9319 100644 --- a/Lib/Protocols/IndyProtocols230.dproj +++ b/Lib/Protocols/IndyProtocols230.dproj @@ -1,469 +1,469 @@ - - - {BCD92888-FF79-4B06-AA77-E9DA2D5B6E4B} - IndyProtocols230.dpk - True - Debug - 1119 - Package - None - 17.2 - Win32 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - Indy 10 Protocols - true - false - true - false - true - false - IndyProtocols230 - 00400000 - false - System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - 1033 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= - true - false - - - package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=preferExternal;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= - Debug - android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar - - - true - iPhoneAndiPad - $(MSBuildProjectName) - Debug - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false - - - true - iPhoneAndiPad - $(MSBuildProjectName) - Debug - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false - - - iPhoneAndiPad - true - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false - - - CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user - - - ..\Output\OBJ\$(Platform)\$(Config) - ..\Output\BPI\$(Platform)\$(Config) - ..\Output\HPP\$(Platform)\$(Config) - All - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - true - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) - - - true - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) - - - false - 0 - RELEASE;$(DCC_Define) - 0 - - - true - DEBUG;$(DCC_Define) - false - - - $(MSBuildProjectName) - true - CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false - iPhoneAndiPad - true - - - true - - - true - - - true - - - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - IndyProtocols230.dpk - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - True - True - True - True - True - True - - - 12 - - - - + + + {BCD92888-FF79-4B06-AA77-E9DA2D5B6E4B} + IndyProtocols230.dpk + True + Debug + 1119 + Package + None + 17.2 + Win32 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + Indy 10 Protocols + true + false + true + false + true + false + IndyProtocols230 + 00400000 + false + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + 1033 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= + true + false + + + package=com.embarcadero.$(MSBuildProjectName);label=$(MSBuildProjectName);versionCode=1;versionName=1.0.0;persistent=False;restoreAnyVersion=False;installLocation=preferExternal;largeHeap=False;theme=TitleBar;hardwareAccelerated=true;apiKey= + Debug + android-support-v4.dex.jar;apk-expansion.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar + + + true + iPhoneAndiPad + $(MSBuildProjectName) + Debug + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false + + + true + iPhoneAndiPad + $(MSBuildProjectName) + Debug + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false + + + iPhoneAndiPad + true + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false + + + CFBundleName=$(MSBuildProjectName);CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleVersion=1.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);NSHighResolutionCapable=true;LSApplicationCategoryType=public.app-category.utilities;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user + + + ..\Output\OBJ\$(Platform)\$(Config) + ..\Output\BPI\$(Platform)\$(Config) + ..\Output\HPP\$(Platform)\$(Config) + All + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + true + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) + + + true + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) + + + false + 0 + RELEASE;$(DCC_Define) + 0 + + + true + DEBUG;$(DCC_Define) + false + + + $(MSBuildProjectName) + true + CFBundleName=$(MSBuildProjectName);CFBundleDevelopmentRegion=en;CFBundleDisplayName=$(MSBuildProjectName);CFBundleIdentifier=$(MSBuildProjectName);CFBundleInfoDictionaryVersion=7.1;CFBundleVersion=1.0.0.0;CFBundlePackageType=APPL;CFBundleSignature=????;LSRequiresIPhoneOS=true;CFBundleAllowMixedLocalizations=YES;CFBundleExecutable=$(MSBuildProjectName);UIDeviceFamily=iPhone & iPad;CFBundleResourceSpecification=ResourceRules.plist;NSLocationWhenInUseUsageDescription=The reason for accessing the location information of the user;NSLocationAlwaysUsageDescription=The reason for accessing the location information of the user;FMLocalNotificationPermission=false + iPhoneAndiPad + true + + + true + + + true + + + true + + + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + true + + + + MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Package + + + + IndyProtocols230.dpk + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + True + True + True + True + True + True + True + + + 12 + + + + diff --git a/Lib/Protocols/IndyProtocols240.dpk b/Lib/Protocols/IndyProtocols240.dpk index f57dde463..1b35e3022 100644 --- a/Lib/Protocols/IndyProtocols240.dpk +++ b/Lib/Protocols/IndyProtocols240.dpk @@ -1,302 +1,302 @@ -package IndyProtocols240; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$DEFINE VER310} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -// RLebeau: cannot use IdCompilerDefines.inc here! - -{$DEFINE HAS_PKG_RTL} -{$IFDEF NEXTGEN} - {$IFDEF IOS} - // there is no RTL package available for iOS - {$UNDEF HAS_PKG_RTL} - {$ENDIF} -{$ENDIF} - -requires - {$IFDEF HAS_PKG_RTL} - rtl, - {$ENDIF} - IndySystem240, - IndyCore240; - -{$IFNDEF WINDOWS} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} -{$ENDIF} - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - {$IFDEF WINDOWS} - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - {$ENDIF} - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - {$IFDEF WINDOWS} - IdSSPI in 'IdSSPI.pas', - {$ENDIF} - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols240; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$DEFINE VER310} +{$ENDIF IMPLICITBUILDING} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD OFF} + +// RLebeau: cannot use IdCompilerDefines.inc here! + +{$DEFINE HAS_PKG_RTL} +{$IFDEF NEXTGEN} + {$IFDEF IOS} + // there is no RTL package available for iOS + {$UNDEF HAS_PKG_RTL} + {$ENDIF} +{$ENDIF} + +requires + {$IFDEF HAS_PKG_RTL} + rtl, + {$ENDIF} + IndySystem240, + IndyCore240; + +{$IFNDEF WINDOWS} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} +{$ENDIF} + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + {$IFDEF WINDOWS} + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + {$ENDIF} + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + {$IFDEF WINDOWS} + IdSSPI in 'IdSSPI.pas', + {$ENDIF} + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols240.dproj b/Lib/Protocols/IndyProtocols240.dproj index d582444a5..ffd62245e 100644 --- a/Lib/Protocols/IndyProtocols240.dproj +++ b/Lib/Protocols/IndyProtocols240.dproj @@ -1,752 +1,752 @@ - - - {BCD92888-FF79-4B06-AA77-E9DA2D5B6E4B} - IndyProtocols240.dpk - True - Debug - 3 - Package - None - 18.2 - Win32 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - Indy 10 Protocols - true - false - true - false - true - false - IndyProtocols240 - 00400000 - false - System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - 1033 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= - true - false - - - ..\Output\OBJ\$(Platform)\$(Config) - ..\Output\BPI\$(Platform)\$(Config) - ..\Output\HPP\$(Platform)\$(Config) - All - CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) - true - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) - - - true - CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) - - - false - 0 - RELEASE;$(DCC_Define) - 0 - - - true - DEBUG;$(DCC_Define) - false - - - CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - IndyProtocols240.dpk - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - True - - - - - true - - - - - true - - - - - true - - - - - true - - - - - 0 - .dll;.bpl - - - 1 - .dylib - - - - - Contents\Resources - 1 - - - - - classes - 1 - - - - - Contents\MacOS - 0 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable-xxhdpi - 1 - - - - - library\lib\mips - 1 - - - - - 1 - - - 1 - - - 0 - - - 1 - - - 1 - - - library\lib\armeabi-v7a - 1 - - - 1 - - - - - 0 - - - 1 - .framework - - - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - 1 - - - 1 - - - 1 - - - - - - library\lib\armeabi - 1 - - - - - 0 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable-normal - 1 - - - - - res\drawable-xhdpi - 1 - - - - - res\drawable-large - 1 - - - - - 1 - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - - res\drawable-hdpi - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - - - Assets - 1 - - - Assets - 1 - - - - - 1 - - - 1 - - - 1 - - - - - res\values - 1 - - - - - res\drawable-small - 1 - - - - - res\drawable - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - - - res\drawable - 1 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - library\lib\armeabi-v7a - 1 - - - - - 0 - .bpl - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - - - res\drawable-mdpi - 1 - - - - - res\drawable-xlarge - 1 - - - - - res\drawable-ldpi - 1 - - - - - - - - - - - - - - 12 - - - - - + + + {BCD92888-FF79-4B06-AA77-E9DA2D5B6E4B} + IndyProtocols240.dpk + True + Debug + 3 + Package + None + 18.2 + Win32 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + Indy 10 Protocols + true + false + true + false + true + false + IndyProtocols240 + 00400000 + false + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + 1033 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= + true + false + + + ..\Output\OBJ\$(Platform)\$(Config) + ..\Output\BPI\$(Platform)\$(Config) + ..\Output\HPP\$(Platform)\$(Config) + All + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) + true + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) + + + true + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) + + + false + 0 + RELEASE;$(DCC_Define) + 0 + + + true + DEBUG;$(DCC_Define) + false + + + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) + true + + + + MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Package + + + + IndyProtocols240.dpk + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + True + True + + + + + true + + + + + true + + + + + true + + + + + true + + + + + 0 + .dll;.bpl + + + 1 + .dylib + + + + + Contents\Resources + 1 + + + + + classes + 1 + + + + + Contents\MacOS + 0 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + res\drawable-xxhdpi + 1 + + + + + library\lib\mips + 1 + + + + + 1 + + + 1 + + + 0 + + + 1 + + + 1 + + + library\lib\armeabi-v7a + 1 + + + 1 + + + + + 0 + + + 1 + .framework + + + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + 1 + + + 1 + + + 1 + + + + + + library\lib\armeabi + 1 + + + + + 0 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + res\drawable-normal + 1 + + + + + res\drawable-xhdpi + 1 + + + + + res\drawable-large + 1 + + + + + 1 + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + res\drawable-hdpi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + + + Assets + 1 + + + Assets + 1 + + + + + 1 + + + 1 + + + 1 + + + + + res\values + 1 + + + + + res\drawable-small + 1 + + + + + res\drawable + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + + + res\drawable + 1 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 0 + .bpl + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + + + res\drawable-mdpi + 1 + + + + + res\drawable-xlarge + 1 + + + + + res\drawable-ldpi + 1 + + + + + + + + + + + + + + 12 + + + + + diff --git a/Lib/Protocols/IndyProtocols250.dpk b/Lib/Protocols/IndyProtocols250.dpk index b9062ae26..7897182de 100644 --- a/Lib/Protocols/IndyProtocols250.dpk +++ b/Lib/Protocols/IndyProtocols250.dpk @@ -1,302 +1,302 @@ -package IndyProtocols250; - -{$R *.res} -{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} -{$ALIGN 8} -{$ASSERTIONS ON} -{$BOOLEVAL OFF} -{$DEBUGINFO OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$IOCHECKS ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION OFF} -{$OVERFLOWCHECKS OFF} -{$RANGECHECKS OFF} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES ON} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DEFINE DEBUG} -{$DEFINE VER320} -{$ENDIF IMPLICITBUILDING} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD OFF} - -// RLebeau: cannot use IdCompilerDefines.inc here! - -{$DEFINE HAS_PKG_RTL} -{$IFDEF NEXTGEN} - {$IFDEF IOS} - // there is no RTL package available for iOS - {$UNDEF HAS_PKG_RTL} - {$ENDIF} -{$ENDIF} - -requires - {$IFDEF HAS_PKG_RTL} - rtl, - {$ENDIF} - IndySystem250, - IndyCore250; - -{$IFNDEF WINDOWS} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} -{$ENDIF} - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - {$IFDEF WINDOWS} - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - {$ENDIF} - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - {$IFDEF WINDOWS} - IdSSPI in 'IdSSPI.pas', - {$ENDIF} - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols250; + +{$R *.res} +{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} +{$ALIGN 8} +{$ASSERTIONS ON} +{$BOOLEVAL OFF} +{$DEBUGINFO OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$IOCHECKS ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION OFF} +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES ON} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DEFINE DEBUG} +{$DEFINE VER320} +{$ENDIF IMPLICITBUILDING} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD OFF} + +// RLebeau: cannot use IdCompilerDefines.inc here! + +{$DEFINE HAS_PKG_RTL} +{$IFDEF NEXTGEN} + {$IFDEF IOS} + // there is no RTL package available for iOS + {$UNDEF HAS_PKG_RTL} + {$ENDIF} +{$ENDIF} + +requires + {$IFDEF HAS_PKG_RTL} + rtl, + {$ENDIF} + IndySystem250, + IndyCore250; + +{$IFNDEF WINDOWS} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} +{$ENDIF} + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + {$IFDEF WINDOWS} + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + {$ENDIF} + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + {$IFDEF WINDOWS} + IdSSPI in 'IdSSPI.pas', + {$ENDIF} + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols250.dproj b/Lib/Protocols/IndyProtocols250.dproj index 3a9046887..05f0b9f56 100644 --- a/Lib/Protocols/IndyProtocols250.dproj +++ b/Lib/Protocols/IndyProtocols250.dproj @@ -1,753 +1,753 @@ - - - {8FD9C2F5-B7A5-4EB0-B38D-2AFB4981533F} - IndyProtocols250.dpk - True - Debug - 3 - Package - None - 18.3 - Win32 - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - Indy 10 Protocols - true - false - true - false - true - false - IndyProtocols250 - 00400000 - false - System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - 1033 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= - true - false - - - ..\Output\OBJ\$(Platform)\$(Config) - ..\Output\BPI\$(Platform)\$(Config) - ..\Output\HPP\$(Platform)\$(Config) - All - CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) - true - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) - - - true - CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) - - - false - 0 - RELEASE;$(DCC_Define) - 0 - - - true - DEBUG;$(DCC_Define) - false - - - CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) - true - - - - MainSource - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - - - - Delphi.Personality.12 - Package - - - - IndyProtocols250.dpk - - - Embarcadero C++Builder Office 2000 Servers Package - Embarcadero C++Builder Office XP Servers Package - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - False - True - True - - - - - true - - - - - true - - - - - true - - - - - true - - - - - 0 - .dll;.bpl - - - 1 - .dylib - - - - - Contents\Resources - 1 - - - - - classes - 1 - - - - - Contents\MacOS - 0 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable-xxhdpi - 1 - - - - - library\lib\mips - 1 - - - - - 1 - - - 1 - - - 0 - - - 1 - - - 1 - - - library\lib\armeabi-v7a - 1 - - - 1 - - - - - 0 - - - 1 - .framework - - - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - 1 - - - 1 - - - 1 - - - - - - library\lib\armeabi - 1 - - - - - 0 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - res\drawable-normal - 1 - - - - - res\drawable-xhdpi - 1 - - - - - res\drawable-large - 1 - - - - - 1 - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - - res\drawable-hdpi - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - - - Assets - 1 - - - Assets - 1 - - - - - 1 - - - 1 - - - 1 - - - - - res\values - 1 - - - - - res\drawable-small - 1 - - - - - res\drawable - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - - - res\drawable - 1 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - library\lib\armeabi-v7a - 1 - - - - - 0 - .bpl - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - - - res\drawable-mdpi - 1 - - - - - res\drawable-xlarge - 1 - - - - - res\drawable-ldpi - 1 - - - - - - - - - - - - - - 12 - - - - - + + + {8FD9C2F5-B7A5-4EB0-B38D-2AFB4981533F} + IndyProtocols250.dpk + True + Debug + 3 + Package + None + 18.3 + Win32 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + Indy 10 Protocols + true + false + true + false + true + false + IndyProtocols250 + 00400000 + false + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + 1033 + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName= + true + false + + + ..\Output\OBJ\$(Platform)\$(Config) + ..\Output\BPI\$(Platform)\$(Config) + ..\Output\HPP\$(Platform)\$(Config) + All + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) + true + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) + + + true + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) + System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Winapi;$(DCC_Namespace) + + + false + 0 + RELEASE;$(DCC_Define) + 0 + + + true + DEBUG;$(DCC_Define) + false + + + CompanyName=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(ModuleName);FileDescription=$(ModuleName);ProductName=$(ModuleName) + true + + + + MainSource + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Package + + + + IndyProtocols250.dpk + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + False + True + True + + + + + true + + + + + true + + + + + true + + + + + true + + + + + 0 + .dll;.bpl + + + 1 + .dylib + + + + + Contents\Resources + 1 + + + + + classes + 1 + + + + + Contents\MacOS + 0 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + res\drawable-xxhdpi + 1 + + + + + library\lib\mips + 1 + + + + + 1 + + + 1 + + + 0 + + + 1 + + + 1 + + + library\lib\armeabi-v7a + 1 + + + 1 + + + + + 0 + + + 1 + .framework + + + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + 1 + + + 1 + + + 1 + + + + + + library\lib\armeabi + 1 + + + + + 0 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + res\drawable-normal + 1 + + + + + res\drawable-xhdpi + 1 + + + + + res\drawable-large + 1 + + + + + 1 + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + res\drawable-hdpi + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + + + Assets + 1 + + + Assets + 1 + + + + + 1 + + + 1 + + + 1 + + + + + res\values + 1 + + + + + res\drawable-small + 1 + + + + + res\drawable + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + + + res\drawable + 1 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + library\lib\armeabi-v7a + 1 + + + + + 0 + .bpl + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + + + res\drawable-mdpi + 1 + + + + + res\drawable-xlarge + 1 + + + + + res\drawable-ldpi + 1 + + + + + + + + + + + + + + 12 + + + + + diff --git a/Lib/Protocols/IndyProtocols40.dpk b/Lib/Protocols/IndyProtocols40.dpk index 1a3f9f8ea..47e8285b5 100644 --- a/Lib/Protocols/IndyProtocols40.dpk +++ b/Lib/Protocols/IndyProtocols40.dpk @@ -1,269 +1,269 @@ -package IndyProtocols40; - -{$R *.res} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - IndySystem40, - IndyCore40; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSPI in 'IdSSPI.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols40; + +{$R *.res} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + IndySystem40, + IndyCore40; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSPI in 'IdSSPI.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols50.dpk b/Lib/Protocols/IndyProtocols50.dpk index 5b0dd77f4..a4ca5712d 100644 --- a/Lib/Protocols/IndyProtocols50.dpk +++ b/Lib/Protocols/IndyProtocols50.dpk @@ -1,269 +1,269 @@ -package IndyProtocols50; - -{$R *.res} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - IndySystem50, - IndyCore50; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSPI in 'IdSSPI.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols50; + +{$R *.res} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + IndySystem50, + IndyCore50; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSPI in 'IdSSPI.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols60.dpk b/Lib/Protocols/IndyProtocols60.dpk index 3770d5ee8..2f15496ba 100644 --- a/Lib/Protocols/IndyProtocols60.dpk +++ b/Lib/Protocols/IndyProtocols60.dpk @@ -1,270 +1,270 @@ -package IndyProtocols60; - -{$R *.res} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - rtl, - IndySystem60, - IndyCore60; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSPI in 'IdSSPI.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols60; + +{$R *.res} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + rtl, + IndySystem60, + IndyCore60; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSPI in 'IdSSPI.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols70.dpk b/Lib/Protocols/IndyProtocols70.dpk index f4ec84dcc..e1dbf78c3 100644 --- a/Lib/Protocols/IndyProtocols70.dpk +++ b/Lib/Protocols/IndyProtocols70.dpk @@ -1,270 +1,270 @@ -package IndyProtocols70; - -{$R *.res} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - rtl, - IndySystem70, - IndyCore70; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSPI in 'IdSSPI.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols70; + +{$R *.res} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + rtl, + IndySystem70, + IndyCore70; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSPI in 'IdSSPI.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols80.dpk b/Lib/Protocols/IndyProtocols80.dpk index 1f80bc019..cc41535d3 100644 --- a/Lib/Protocols/IndyProtocols80.dpk +++ b/Lib/Protocols/IndyProtocols80.dpk @@ -1,270 +1,270 @@ -package IndyProtocols80; - -{$R *.res} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - rtl, - IndySystem80, - IndyCore80; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSPI in 'IdSSPI.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols80; + +{$R *.res} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + rtl, + IndySystem80, + IndyCore80; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSPI in 'IdSSPI.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols80Net.dpk b/Lib/Protocols/IndyProtocols80Net.dpk index 0901ffe95..e0886b2ec 100644 --- a/Lib/Protocols/IndyProtocols80Net.dpk +++ b/Lib/Protocols/IndyProtocols80Net.dpk @@ -1,260 +1,260 @@ -package IndyProtocols80Net; - -{$ALIGN 0} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - Borland.Delphi, - Borland.VclRtl, - IndySystem80Net, - IndyCore80Net; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas'; -{$I IdProtocols90ASM90.inc} - -end. +package IndyProtocols80Net; + +{$ALIGN 0} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + Borland.Delphi, + Borland.VclRtl, + IndySystem80Net, + IndyCore80Net; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas'; +{$I IdProtocols90ASM90.inc} + +end. diff --git a/Lib/Protocols/IndyProtocols90.dpk b/Lib/Protocols/IndyProtocols90.dpk index 51a3063d2..52d83e29b 100644 --- a/Lib/Protocols/IndyProtocols90.dpk +++ b/Lib/Protocols/IndyProtocols90.dpk @@ -1,271 +1,271 @@ -package IndyProtocols90; - -{$R *.res} -{$ALIGN 8} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - rtl, - IndySystem90, - IndyCore90; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSPI in 'IdSSPI.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocols90; + +{$R *.res} +{$ALIGN 8} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + rtl, + IndySystem90, + IndyCore90; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSPI in 'IdSSPI.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Protocols/IndyProtocols90Net.dpk b/Lib/Protocols/IndyProtocols90Net.dpk index 8d31614d5..5f30aa5fd 100644 --- a/Lib/Protocols/IndyProtocols90Net.dpk +++ b/Lib/Protocols/IndyProtocols90Net.dpk @@ -1,260 +1,260 @@ -package IndyProtocols90Net; - -{$ALIGN 0} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - Borland.Delphi, - Borland.VclRtl, - IndySystem90Net, - IndyCore90Net; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas'; -{$I IdProtocols90ASM90.inc} - -end. +package IndyProtocols90Net; + +{$ALIGN 0} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + Borland.Delphi, + Borland.VclRtl, + IndySystem90Net, + IndyCore90Net; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas'; +{$I IdProtocols90ASM90.inc} + +end. diff --git a/Lib/Protocols/IndyProtocolsK3.dpk b/Lib/Protocols/IndyProtocolsK3.dpk index d4671ed38..6be00e124 100644 --- a/Lib/Protocols/IndyProtocolsK3.dpk +++ b/Lib/Protocols/IndyProtocolsK3.dpk @@ -1,270 +1,270 @@ -package IndyProtocolsK3; - -{$R *.res} -{$BOOLEVAL OFF} -{$EXTENDEDSYNTAX ON} -{$IMPORTEDDATA ON} -{$LOCALSYMBOLS ON} -{$LONGSTRINGS ON} -{$OPENSTRINGS ON} -{$OPTIMIZATION ON} -{$REFERENCEINFO ON} -{$SAFEDIVIDE OFF} -{$STACKFRAMES OFF} -{$TYPEDADDRESS OFF} -{$VARSTRINGCHECKS ON} -{$WRITEABLECONST OFF} -{$MINENUMSIZE 1} -{$IMAGEBASE $400000} -{$DESCRIPTION 'Indy 10 Protocols'} -{$RUNONLY} -{$IMPLICITBUILD ON} - -requires - rtl, - IndySystemK3, - IndyCoreK3; - -contains - IdASN1Util in 'IdASN1Util.pas', - IdAllAuthentications in 'IdAllAuthentications.pas', - IdAllFTPListParsers in 'IdAllFTPListParsers.pas', - IdAllHeaderCoders in 'IdAllHeaderCoders.pas', - IdAttachment in 'IdAttachment.pas', - IdAttachmentFile in 'IdAttachmentFile.pas', - IdAttachmentMemory in 'IdAttachmentMemory.pas', - IdAuthentication in 'IdAuthentication.pas', - IdAuthenticationDigest in 'IdAuthenticationDigest.pas', - IdAuthenticationManager in 'IdAuthenticationManager.pas', - IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', - IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', - IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', - IdChargenServer in 'IdChargenServer.pas', - IdChargenUDPServer in 'IdChargenUDPServer.pas', - IdCharsets in 'IdCharsets.pas', - IdCoder in 'IdCoder.pas', - IdCoder00E in 'IdCoder00E.pas', - IdCoder3to4 in 'IdCoder3to4.pas', - IdCoderBinHex4 in 'IdCoderBinHex4.pas', - IdCoderHeader in 'IdCoderHeader.pas', - IdCoderMIME in 'IdCoderMIME.pas', - IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', - IdCoderUUE in 'IdCoderUUE.pas', - IdCoderXXE in 'IdCoderXXE.pas', - IdCompressionIntercept in 'IdCompressionIntercept.pas', - IdCompressorZLib in 'IdCompressorZLib.pas', - IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', - IdContainers in 'IdContainers.pas', - IdCookie in 'IdCookie.pas', - IdCookieManager in 'IdCookieManager.pas', - IdCustomHTTPServer in 'IdCustomHTTPServer.pas', - IdDICT in 'IdDICT.pas', - IdDICTCommon in 'IdDICTCommon.pas', - IdDICTServer in 'IdDICTServer.pas', - IdDNSCommon in 'IdDNSCommon.pas', - IdDNSResolver in 'IdDNSResolver.pas', - IdDNSServer in 'IdDNSServer.pas', - IdDateTimeStamp in 'IdDateTimeStamp.pas', - IdDayTime in 'IdDayTime.pas', - IdDayTimeServer in 'IdDayTimeServer.pas', - IdDayTimeUDP in 'IdDayTimeUDP.pas', - IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', - IdDiscardServer in 'IdDiscardServer.pas', - IdDiscardUDPServer in 'IdDiscardUDPServer.pas', - IdEMailAddress in 'IdEMailAddress.pas', - IdEcho in 'IdEcho.pas', - IdEchoServer in 'IdEchoServer.pas', - IdEchoUDP in 'IdEchoUDP.pas', - IdEchoUDPServer in 'IdEchoUDPServer.pas', - IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', - IdFIPS in 'IdFIPS.pas', - IdFSP in 'IdFSP.pas', - IdFTP in 'IdFTP.pas', - IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', - IdFTPCommon in 'IdFTPCommon.pas', - IdFTPList in 'IdFTPList.pas', - IdFTPListOutput in 'IdFTPListOutput.pas', - IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', - IdFTPListParseBase in 'IdFTPListParseBase.pas', - IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', - IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', - IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', - IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', - IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', - IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', - IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', - IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', - IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', - IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', - IdFTPListParseMVS in 'IdFTPListParseMVS.pas', - IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', - IdFTPListParseMusic in 'IdFTPListParseMusic.pas', - IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', - IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', - IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', - IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', - IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', - IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', - IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', - IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', - IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', - IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', - IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', - IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', - IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', - IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', - IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', - IdFTPListParseUnix in 'IdFTPListParseUnix.pas', - IdFTPListParseVM in 'IdFTPListParseVM.pas', - IdFTPListParseVMS in 'IdFTPListParseVMS.pas', - IdFTPListParseVSE in 'IdFTPListParseVSE.pas', - IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', - IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', - IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', - IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', - IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', - IdFTPListTypes in 'IdFTPListTypes.pas', - IdFTPServer in 'IdFTPServer.pas', - IdFTPServerContextBase in 'IdFTPServerContextBase.pas', - IdFinger in 'IdFinger.pas', - IdFingerServer in 'IdFingerServer.pas', - IdGlobalProtocols in 'IdGlobalProtocols.pas', - IdGopher in 'IdGopher.pas', - IdGopherConsts in 'IdGopherConsts.pas', - IdGopherServer in 'IdGopherServer.pas', - IdHL7 in 'IdHL7.pas', - IdHMAC in 'IdHMAC.pas', - IdHMACMD5 in 'IdHMACMD5.pas', - IdHMACSHA1 in 'IdHMACSHA1.pas', - IdHTTP in 'IdHTTP.pas', - IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', - IdHTTPHelper in 'IdHTTPHelper.pas', - IdHTTPProxyServer in 'IdHTTPProxyServer.pas', - IdHTTPServer in 'IdHTTPServer.pas', - IdHash in 'IdHash.pas', - IdHashCRC in 'IdHashCRC.pas', - IdHashElf in 'IdHashElf.pas', - IdHashMessageDigest in 'IdHashMessageDigest.pas', - IdHashSHA in 'IdHashSHA.pas', - IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', - IdHeaderCoderBase in 'IdHeaderCoderBase.pas', - IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', - IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', - IdHeaderList in 'IdHeaderList.pas', - IdIMAP4 in 'IdIMAP4.pas', - IdIMAP4Server in 'IdIMAP4Server.pas', - IdIPAddrMon in 'IdIPAddrMon.pas', - IdIPWatch in 'IdIPWatch.pas', - IdIRC in 'IdIRC.pas', - IdIdent in 'IdIdent.pas', - IdIdentServer in 'IdIdentServer.pas', - IdIrcServer in 'IdIrcServer.pas', - IdLPR in 'IdLPR.pas', - IdMailBox in 'IdMailBox.pas', - IdMappedFTP in 'IdMappedFTP.pas', - IdMappedPOP3 in 'IdMappedPOP3.pas', - IdMappedPortTCP in 'IdMappedPortTCP.pas', - IdMappedPortUDP in 'IdMappedPortUDP.pas', - IdMappedTelnet in 'IdMappedTelnet.pas', - IdMessage in 'IdMessage.pas', - IdMessageBuilder in 'IdMessageBuilder.pas', - IdMessageClient in 'IdMessageClient.pas', - IdMessageCoder in 'IdMessageCoder.pas', - IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', - IdMessageCoderMIME in 'IdMessageCoderMIME.pas', - IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', - IdMessageCoderUUE in 'IdMessageCoderUUE.pas', - IdMessageCoderXXE in 'IdMessageCoderXXE.pas', - IdMessageCoderYenc in 'IdMessageCoderYenc.pas', - IdMessageCollection in 'IdMessageCollection.pas', - IdMessageHelper in 'IdMessageHelper.pas', - IdMessageParts in 'IdMessageParts.pas', - IdMultipartFormData in 'IdMultipartFormData.pas', - IdNNTP in 'IdNNTP.pas', - IdNNTPServer in 'IdNNTPServer.pas', - IdNTLM in 'IdNTLM.pas', - IdNetworkCalculator in 'IdNetworkCalculator.pas', - IdOSFileName in 'IdOSFileName.pas', - IdOTPCalculator in 'IdOTPCalculator.pas', - IdPOP3 in 'IdPOP3.pas', - IdPOP3Server in 'IdPOP3Server.pas', - IdQOTDUDP in 'IdQOTDUDP.pas', - IdQOTDUDPServer in 'IdQOTDUDPServer.pas', - IdQotd in 'IdQotd.pas', - IdQotdServer in 'IdQotdServer.pas', - IdRSH in 'IdRSH.pas', - IdRSHServer in 'IdRSHServer.pas', - IdRemoteCMDClient in 'IdRemoteCMDClient.pas', - IdRemoteCMDServer in 'IdRemoteCMDServer.pas', - IdReplyFTP in 'IdReplyFTP.pas', - IdReplyIMAP4 in 'IdReplyIMAP4.pas', - IdReplyPOP3 in 'IdReplyPOP3.pas', - IdReplySMTP in 'IdReplySMTP.pas', - IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', - IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', - IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', - IdRexec in 'IdRexec.pas', - IdRexecServer in 'IdRexecServer.pas', - IdSASL in 'IdSASL.pas', - IdSASLAnonymous in 'IdSASLAnonymous.pas', - IdSASLCollection in 'IdSASLCollection.pas', - IdSASLDigest in 'IdSASLDigest.pas', - IdSASLExternal in 'IdSASLExternal.pas', - IdSASLLogin in 'IdSASLLogin.pas', - IdSASLOAuth in 'IdSASLOAuth.pas', - IdSASLOTP in 'IdSASLOTP.pas', - IdSASLPlain in 'IdSASLPlain.pas', - IdSASLSKey in 'IdSASLSKey.pas', - IdSASLUserPass in 'IdSASLUserPass.pas', - IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', - IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', - IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', - IdSMTP in 'IdSMTP.pas', - IdSMTPBase in 'IdSMTPBase.pas', - IdSMTPRelay in 'IdSMTPRelay.pas', - IdSMTPServer in 'IdSMTPServer.pas', - IdSNMP in 'IdSNMP.pas', - IdSNPP in 'IdSNPP.pas', - IdSNTP in 'IdSNTP.pas', - IdSSL in 'IdSSL.pas', - IdSSPI in 'IdSSPI.pas', - IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', - IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', - IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', - IdSocksServer in 'IdSocksServer.pas', - IdStrings in 'IdStrings.pas', - IdSysLog in 'IdSysLog.pas', - IdSysLogMessage in 'IdSysLogMessage.pas', - IdSysLogServer in 'IdSysLogServer.pas', - IdSystat in 'IdSystat.pas', - IdSystatServer in 'IdSystatServer.pas', - IdSystatUDP in 'IdSystatUDP.pas', - IdSystatUDPServer in 'IdSystatUDPServer.pas', - IdTelnet in 'IdTelnet.pas', - IdTelnetServer in 'IdTelnetServer.pas', - IdText in 'IdText.pas', - IdTime in 'IdTime.pas', - IdTimeServer in 'IdTimeServer.pas', - IdTimeUDP in 'IdTimeUDP.pas', - IdTimeUDPServer in 'IdTimeUDPServer.pas', - IdTrivialFTP in 'IdTrivialFTP.pas', - IdTrivialFTPBase in 'IdTrivialFTPBase.pas', - IdTrivialFTPServer in 'IdTrivialFTPServer.pas', - IdURI in 'IdURI.pas', - IdUnixTime in 'IdUnixTime.pas', - IdUnixTimeServer in 'IdUnixTimeServer.pas', - IdUnixTimeUDP in 'IdUnixTimeUDP.pas', - IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', - IdUriUtils in 'IdUriUtils.pas', - IdUserAccounts in 'IdUserAccounts.pas', - IdUserPassProvider in 'IdUserPassProvider.pas', - IdVCard in 'IdVCard.pas', - IdWebDAV in 'IdWebDAV.pas', - IdWhoIsServer in 'IdWhoIsServer.pas', - IdWhois in 'IdWhois.pas', - IdZLib in 'IdZLib.pas', - IdZLibCompressorBase in 'IdZLibCompressorBase.pas', - IdZLibConst in 'IdZLibConst.pas', - IdZLibHeaders in 'IdZLibHeaders.pas'; - -end. +package IndyProtocolsK3; + +{$R *.res} +{$BOOLEVAL OFF} +{$EXTENDEDSYNTAX ON} +{$IMPORTEDDATA ON} +{$LOCALSYMBOLS ON} +{$LONGSTRINGS ON} +{$OPENSTRINGS ON} +{$OPTIMIZATION ON} +{$REFERENCEINFO ON} +{$SAFEDIVIDE OFF} +{$STACKFRAMES OFF} +{$TYPEDADDRESS OFF} +{$VARSTRINGCHECKS ON} +{$WRITEABLECONST OFF} +{$MINENUMSIZE 1} +{$IMAGEBASE $400000} +{$DESCRIPTION 'Indy 10 Protocols'} +{$RUNONLY} +{$IMPLICITBUILD ON} + +requires + rtl, + IndySystemK3, + IndyCoreK3; + +contains + IdASN1Util in 'IdASN1Util.pas', + IdAllAuthentications in 'IdAllAuthentications.pas', + IdAllFTPListParsers in 'IdAllFTPListParsers.pas', + IdAllHeaderCoders in 'IdAllHeaderCoders.pas', + IdAttachment in 'IdAttachment.pas', + IdAttachmentFile in 'IdAttachmentFile.pas', + IdAttachmentMemory in 'IdAttachmentMemory.pas', + IdAuthentication in 'IdAuthentication.pas', + IdAuthenticationDigest in 'IdAuthenticationDigest.pas', + IdAuthenticationManager in 'IdAuthenticationManager.pas', + IdAuthenticationNTLM in 'IdAuthenticationNTLM.pas', + IdAuthenticationSSPI in 'IdAuthenticationSSPI.pas', + IdBlockCipherIntercept in 'IdBlockCipherIntercept.pas', + IdChargenServer in 'IdChargenServer.pas', + IdChargenUDPServer in 'IdChargenUDPServer.pas', + IdCharsets in 'IdCharsets.pas', + IdCoder in 'IdCoder.pas', + IdCoder00E in 'IdCoder00E.pas', + IdCoder3to4 in 'IdCoder3to4.pas', + IdCoderBinHex4 in 'IdCoderBinHex4.pas', + IdCoderHeader in 'IdCoderHeader.pas', + IdCoderMIME in 'IdCoderMIME.pas', + IdCoderQuotedPrintable in 'IdCoderQuotedPrintable.pas', + IdCoderUUE in 'IdCoderUUE.pas', + IdCoderXXE in 'IdCoderXXE.pas', + IdCompressionIntercept in 'IdCompressionIntercept.pas', + IdCompressorZLib in 'IdCompressorZLib.pas', + IdConnectThroughHttpProxy in 'IdConnectThroughHttpProxy.pas', + IdContainers in 'IdContainers.pas', + IdCookie in 'IdCookie.pas', + IdCookieManager in 'IdCookieManager.pas', + IdCustomHTTPServer in 'IdCustomHTTPServer.pas', + IdDICT in 'IdDICT.pas', + IdDICTCommon in 'IdDICTCommon.pas', + IdDICTServer in 'IdDICTServer.pas', + IdDNSCommon in 'IdDNSCommon.pas', + IdDNSResolver in 'IdDNSResolver.pas', + IdDNSServer in 'IdDNSServer.pas', + IdDateTimeStamp in 'IdDateTimeStamp.pas', + IdDayTime in 'IdDayTime.pas', + IdDayTimeServer in 'IdDayTimeServer.pas', + IdDayTimeUDP in 'IdDayTimeUDP.pas', + IdDayTimeUDPServer in 'IdDayTimeUDPServer.pas', + IdDiscardServer in 'IdDiscardServer.pas', + IdDiscardUDPServer in 'IdDiscardUDPServer.pas', + IdEMailAddress in 'IdEMailAddress.pas', + IdEcho in 'IdEcho.pas', + IdEchoServer in 'IdEchoServer.pas', + IdEchoUDP in 'IdEchoUDP.pas', + IdEchoUDPServer in 'IdEchoUDPServer.pas', + IdExplicitTLSClientServerBase in 'IdExplicitTLSClientServerBase.pas', + IdFIPS in 'IdFIPS.pas', + IdFSP in 'IdFSP.pas', + IdFTP in 'IdFTP.pas', + IdFTPBaseFileSystem in 'IdFTPBaseFileSystem.pas', + IdFTPCommon in 'IdFTPCommon.pas', + IdFTPList in 'IdFTPList.pas', + IdFTPListOutput in 'IdFTPListOutput.pas', + IdFTPListParseAS400 in 'IdFTPListParseAS400.pas', + IdFTPListParseBase in 'IdFTPListParseBase.pas', + IdFTPListParseBullGCOS7 in 'IdFTPListParseBullGCOS7.pas', + IdFTPListParseBullGCOS8 in 'IdFTPListParseBullGCOS8.pas', + IdFTPListParseChameleonNewt in 'IdFTPListParseChameleonNewt.pas', + IdFTPListParseCiscoIOS in 'IdFTPListParseCiscoIOS.pas', + IdFTPListParseDistinctTCPIP in 'IdFTPListParseDistinctTCPIP.pas', + IdFTPListParseEPLF in 'IdFTPListParseEPLF.pas', + IdFTPListParseHellSoft in 'IdFTPListParseHellSoft.pas', + IdFTPListParseIEFTPGateway in 'IdFTPListParseIEFTPGateway.pas', + IdFTPListParseKA9Q in 'IdFTPListParseKA9Q.pas', + IdFTPListParseMPEiX in 'IdFTPListParseMPEiX.pas', + IdFTPListParseMVS in 'IdFTPListParseMVS.pas', + IdFTPListParseMicrowareOS9 in 'IdFTPListParseMicrowareOS9.pas', + IdFTPListParseMusic in 'IdFTPListParseMusic.pas', + IdFTPListParseNCSAForDOS in 'IdFTPListParseNCSAForDOS.pas', + IdFTPListParseNCSAForMACOS in 'IdFTPListParseNCSAForMACOS.pas', + IdFTPListParseNovellNetware in 'IdFTPListParseNovellNetware.pas', + IdFTPListParseNovellNetwarePSU in 'IdFTPListParseNovellNetwarePSU.pas', + IdFTPListParseOS2 in 'IdFTPListParseOS2.pas', + IdFTPListParsePCNFSD in 'IdFTPListParsePCNFSD.pas', + IdFTPListParsePCTCP in 'IdFTPListParsePCTCP.pas', + IdFTPListParseStercomOS390Exp in 'IdFTPListParseStercomOS390Exp.pas', + IdFTPListParseStercomUnixEnt in 'IdFTPListParseStercomUnixEnt.pas', + IdFTPListParseStratusVOS in 'IdFTPListParseStratusVOS.pas', + IdFTPListParseSuperTCP in 'IdFTPListParseSuperTCP.pas', + IdFTPListParseTOPS20 in 'IdFTPListParseTOPS20.pas', + IdFTPListParseTSXPlus in 'IdFTPListParseTSXPlus.pas', + IdFTPListParseTandemGuardian in 'IdFTPListParseTandemGuardian.pas', + IdFTPListParseUnisysClearPath in 'IdFTPListParseUnisysClearPath.pas', + IdFTPListParseUnix in 'IdFTPListParseUnix.pas', + IdFTPListParseVM in 'IdFTPListParseVM.pas', + IdFTPListParseVMS in 'IdFTPListParseVMS.pas', + IdFTPListParseVSE in 'IdFTPListParseVSE.pas', + IdFTPListParseVxWorks in 'IdFTPListParseVxWorks.pas', + IdFTPListParseWfFTP in 'IdFTPListParseWfFTP.pas', + IdFTPListParseWinQVTNET in 'IdFTPListParseWinQVTNET.pas', + IdFTPListParseWindowsNT in 'IdFTPListParseWindowsNT.pas', + IdFTPListParseXecomMicroRTOS in 'IdFTPListParseXecomMicroRTOS.pas', + IdFTPListTypes in 'IdFTPListTypes.pas', + IdFTPServer in 'IdFTPServer.pas', + IdFTPServerContextBase in 'IdFTPServerContextBase.pas', + IdFinger in 'IdFinger.pas', + IdFingerServer in 'IdFingerServer.pas', + IdGlobalProtocols in 'IdGlobalProtocols.pas', + IdGopher in 'IdGopher.pas', + IdGopherConsts in 'IdGopherConsts.pas', + IdGopherServer in 'IdGopherServer.pas', + IdHL7 in 'IdHL7.pas', + IdHMAC in 'IdHMAC.pas', + IdHMACMD5 in 'IdHMACMD5.pas', + IdHMACSHA1 in 'IdHMACSHA1.pas', + IdHTTP in 'IdHTTP.pas', + IdHTTPHeaderInfo in 'IdHTTPHeaderInfo.pas', + IdHTTPHelper in 'IdHTTPHelper.pas', + IdHTTPProxyServer in 'IdHTTPProxyServer.pas', + IdHTTPServer in 'IdHTTPServer.pas', + IdHash in 'IdHash.pas', + IdHashCRC in 'IdHashCRC.pas', + IdHashElf in 'IdHashElf.pas', + IdHashMessageDigest in 'IdHashMessageDigest.pas', + IdHashSHA in 'IdHashSHA.pas', + IdHeaderCoder2022JP in 'IdHeaderCoder2022JP.pas', + IdHeaderCoderBase in 'IdHeaderCoderBase.pas', + IdHeaderCoderIndy in 'IdHeaderCoderIndy.pas', + IdHeaderCoderPlain in 'IdHeaderCoderPlain.pas', + IdHeaderList in 'IdHeaderList.pas', + IdIMAP4 in 'IdIMAP4.pas', + IdIMAP4Server in 'IdIMAP4Server.pas', + IdIPAddrMon in 'IdIPAddrMon.pas', + IdIPWatch in 'IdIPWatch.pas', + IdIRC in 'IdIRC.pas', + IdIdent in 'IdIdent.pas', + IdIdentServer in 'IdIdentServer.pas', + IdIrcServer in 'IdIrcServer.pas', + IdLPR in 'IdLPR.pas', + IdMailBox in 'IdMailBox.pas', + IdMappedFTP in 'IdMappedFTP.pas', + IdMappedPOP3 in 'IdMappedPOP3.pas', + IdMappedPortTCP in 'IdMappedPortTCP.pas', + IdMappedPortUDP in 'IdMappedPortUDP.pas', + IdMappedTelnet in 'IdMappedTelnet.pas', + IdMessage in 'IdMessage.pas', + IdMessageBuilder in 'IdMessageBuilder.pas', + IdMessageClient in 'IdMessageClient.pas', + IdMessageCoder in 'IdMessageCoder.pas', + IdMessageCoderBinHex4 in 'IdMessageCoderBinHex4.pas', + IdMessageCoderMIME in 'IdMessageCoderMIME.pas', + IdMessageCoderQuotedPrintable in 'IdMessageCoderQuotedPrintable.pas', + IdMessageCoderUUE in 'IdMessageCoderUUE.pas', + IdMessageCoderXXE in 'IdMessageCoderXXE.pas', + IdMessageCoderYenc in 'IdMessageCoderYenc.pas', + IdMessageCollection in 'IdMessageCollection.pas', + IdMessageHelper in 'IdMessageHelper.pas', + IdMessageParts in 'IdMessageParts.pas', + IdMultipartFormData in 'IdMultipartFormData.pas', + IdNNTP in 'IdNNTP.pas', + IdNNTPServer in 'IdNNTPServer.pas', + IdNTLM in 'IdNTLM.pas', + IdNetworkCalculator in 'IdNetworkCalculator.pas', + IdOSFileName in 'IdOSFileName.pas', + IdOTPCalculator in 'IdOTPCalculator.pas', + IdPOP3 in 'IdPOP3.pas', + IdPOP3Server in 'IdPOP3Server.pas', + IdQOTDUDP in 'IdQOTDUDP.pas', + IdQOTDUDPServer in 'IdQOTDUDPServer.pas', + IdQotd in 'IdQotd.pas', + IdQotdServer in 'IdQotdServer.pas', + IdRSH in 'IdRSH.pas', + IdRSHServer in 'IdRSHServer.pas', + IdRemoteCMDClient in 'IdRemoteCMDClient.pas', + IdRemoteCMDServer in 'IdRemoteCMDServer.pas', + IdReplyFTP in 'IdReplyFTP.pas', + IdReplyIMAP4 in 'IdReplyIMAP4.pas', + IdReplyPOP3 in 'IdReplyPOP3.pas', + IdReplySMTP in 'IdReplySMTP.pas', + IdResourceStringsProtocols in 'IdResourceStringsProtocols.pas', + IdResourceStringsSSPI in 'IdResourceStringsSSPI.pas', + IdResourceStringsUriUtils in 'IdResourceStringsUriUtils.pas', + IdRexec in 'IdRexec.pas', + IdRexecServer in 'IdRexecServer.pas', + IdSASL in 'IdSASL.pas', + IdSASLAnonymous in 'IdSASLAnonymous.pas', + IdSASLCollection in 'IdSASLCollection.pas', + IdSASLDigest in 'IdSASLDigest.pas', + IdSASLExternal in 'IdSASLExternal.pas', + IdSASLLogin in 'IdSASLLogin.pas', + IdSASLOAuth in 'IdSASLOAuth.pas', + IdSASLOTP in 'IdSASLOTP.pas', + IdSASLPlain in 'IdSASLPlain.pas', + IdSASLSKey in 'IdSASLSKey.pas', + IdSASLUserPass in 'IdSASLUserPass.pas', + IdSASL_CRAMBase in 'IdSASL_CRAMBase.pas', + IdSASL_CRAM_MD5 in 'IdSASL_CRAM_MD5.pas', + IdSASL_CRAM_SHA1 in 'IdSASL_CRAM_SHA1.pas', + IdSMTP in 'IdSMTP.pas', + IdSMTPBase in 'IdSMTPBase.pas', + IdSMTPRelay in 'IdSMTPRelay.pas', + IdSMTPServer in 'IdSMTPServer.pas', + IdSNMP in 'IdSNMP.pas', + IdSNPP in 'IdSNPP.pas', + IdSNTP in 'IdSNTP.pas', + IdSSL in 'IdSSL.pas', + IdSSPI in 'IdSSPI.pas', + IdServerInterceptLogBase in 'IdServerInterceptLogBase.pas', + IdServerInterceptLogEvent in 'IdServerInterceptLogEvent.pas', + IdServerInterceptLogFile in 'IdServerInterceptLogFile.pas', + IdSocksServer in 'IdSocksServer.pas', + IdStrings in 'IdStrings.pas', + IdSysLog in 'IdSysLog.pas', + IdSysLogMessage in 'IdSysLogMessage.pas', + IdSysLogServer in 'IdSysLogServer.pas', + IdSystat in 'IdSystat.pas', + IdSystatServer in 'IdSystatServer.pas', + IdSystatUDP in 'IdSystatUDP.pas', + IdSystatUDPServer in 'IdSystatUDPServer.pas', + IdTelnet in 'IdTelnet.pas', + IdTelnetServer in 'IdTelnetServer.pas', + IdText in 'IdText.pas', + IdTime in 'IdTime.pas', + IdTimeServer in 'IdTimeServer.pas', + IdTimeUDP in 'IdTimeUDP.pas', + IdTimeUDPServer in 'IdTimeUDPServer.pas', + IdTrivialFTP in 'IdTrivialFTP.pas', + IdTrivialFTPBase in 'IdTrivialFTPBase.pas', + IdTrivialFTPServer in 'IdTrivialFTPServer.pas', + IdURI in 'IdURI.pas', + IdUnixTime in 'IdUnixTime.pas', + IdUnixTimeServer in 'IdUnixTimeServer.pas', + IdUnixTimeUDP in 'IdUnixTimeUDP.pas', + IdUnixTimeUDPServer in 'IdUnixTimeUDPServer.pas', + IdUriUtils in 'IdUriUtils.pas', + IdUserAccounts in 'IdUserAccounts.pas', + IdUserPassProvider in 'IdUserPassProvider.pas', + IdVCard in 'IdVCard.pas', + IdWebDAV in 'IdWebDAV.pas', + IdWhoIsServer in 'IdWhoIsServer.pas', + IdWhois in 'IdWhois.pas', + IdZLib in 'IdZLib.pas', + IdZLibCompressorBase in 'IdZLibCompressorBase.pas', + IdZLibConst in 'IdZLibConst.pas', + IdZLibHeaders in 'IdZLibHeaders.pas'; + +end. diff --git a/Lib/Security/IdSecurity90ASM90.inc b/Lib/Security/IdSecurity90ASM90.inc index 3d7d18040..b1f2bbf5c 100644 --- a/Lib/Security/IdSecurity90ASM90.inc +++ b/Lib/Security/IdSecurity90ASM90.inc @@ -1,12 +1,12 @@ -[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Security Run-Time Package for Borland Developer Studio')] -[assembly: AssemblyConfiguration('')] -[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] -[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyTrademark('')] -[assembly: AssemblyCulture('')] -[assembly: AssemblyTitle('Indy .NET Security Run-Time Package')] -[assembly: AssemblyVersion('10.7.0.*')] -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile('')] -[assembly: AssemblyKeyName('')] +[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Security Run-Time Package for Borland Developer Studio')] +[assembly: AssemblyConfiguration('')] +[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] +[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyTrademark('')] +[assembly: AssemblyCulture('')] +[assembly: AssemblyTitle('Indy .NET Security Run-Time Package')] +[assembly: AssemblyVersion('10.7.0.*')] +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile('')] +[assembly: AssemblyKeyName('')] diff --git a/Lib/Security/IddclSecurity90ASM90.inc b/Lib/Security/IddclSecurity90ASM90.inc index 91d39e131..40711f30b 100644 --- a/Lib/Security/IddclSecurity90ASM90.inc +++ b/Lib/Security/IddclSecurity90ASM90.inc @@ -1,12 +1,12 @@ -[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Security Design-Time Package for Borland Developer Studio')] -[assembly: AssemblyConfiguration('')] -[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] -[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyTrademark('')] -[assembly: AssemblyCulture('')] -[assembly: AssemblyTitle('Indy .NET Security Design-Time Package')] -[assembly: AssemblyVersion('10.7.0.*')] -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile('')] -[assembly: AssemblyKeyName('')] +[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 Security Design-Time Package for Borland Developer Studio')] +[assembly: AssemblyConfiguration('')] +[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] +[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyTrademark('')] +[assembly: AssemblyCulture('')] +[assembly: AssemblyTitle('Indy .NET Security Design-Time Package')] +[assembly: AssemblyVersion('10.7.0.*')] +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile('')] +[assembly: AssemblyKeyName('')] diff --git a/Lib/SuperCore/IdCompilerDefines.inc b/Lib/SuperCore/IdCompilerDefines.inc index 8ce7d254c..24f902e86 100644 --- a/Lib/SuperCore/IdCompilerDefines.inc +++ b/Lib/SuperCore/IdCompilerDefines.inc @@ -1,2091 +1,2091 @@ -{$IFDEF CONDITIONALEXPRESSIONS} - // Must be at the top... - {$IF CompilerVersion >= 24.0} - {$LEGACYIFEND ON} - {$IFEND} -{$ENDIF} - -// General - -// Make this $DEFINE to use the 16 color icons required by Borland -// or DEFINE to use the 256 color Indy versions -{.$DEFINE Borland} - -// S.G. 4/9/2002: IPv4/IPv6 general switch (for defaults only) -{$DEFINE IdIPv4} // use IPv4 by default -{.$IFDEF IdIPv6} // use IPv6 by default - -{$DEFINE INDY100} -{$DEFINE 10_7_0} //so developers can IFDEF for this product version -{$DEFINE 10_7_0_0} //so developers can IFDEF for this specific version - -// When generating C++Builder output files, certain workarounds to compiler -// problems need to be enabled! When invoking DCC on the command-line, use -// the -DBCB parameter. When invoking MSBUILD, include the DCC_Define="BCB" -// attribute in the /p parameter. -{$IFDEF BCB} - {$DEFINE CBUILDER} -{$ELSE} - {$DEFINE DELPHI} -{$ENDIF} - -{$UNDEF USE_OPENSSL} -{$UNDEF STATICLOAD_OPENSSL} - -{$UNDEF USE_ZLIB_UNIT} -{$UNDEF USE_SSPI} - -// $DEFINE the following if the global objects in the IdStack and IdThread -// units should be freed on finalization -{.$DEFINE FREE_ON_FINAL} -{$UNDEF FREE_ON_FINAL} - -// Make sure the following is $DEFINE'd only for suitable environments -// as specified further below. This works in conjunction with the -// FREE_ON_FINAL define above. -{$UNDEF REGISTER_EXPECTED_MEMORY_LEAK} -{$UNDEF HAS_System_RegisterExpectedMemoryLeak} - -// FastMM is natively available in BDS 2006 and higher. $DEFINE the -// following if FastMM has been installed manually in earlier versions -{.$DEFINE USE_FASTMM4} -{$UNDEF USE_FASTMM4} - -// $DEFINE the following if MadExcept has been installed manually in -// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced -// in BDS 2006) -{.$DEFINE USE_MADEXCEPT} -{$UNDEF USE_MADEXCEPT} - -// $DEFINE the following if LeakCheck has been installed manually in -// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced -// in BDS 2006) -{.$DEFINE USE_LEAKCHECK} -{$UNDEF USE_LEAKCHECK} - -// Make sure the following are $DEFINE'd only for Delphi/C++Builder 2009 onwards -// as specified further below. The VCL is fully Unicode, where the 'String' -// type maps to System.UnicodeString, not System.AnsiString anymore -{$UNDEF STRING_IS_UNICODE} -{$UNDEF STRING_IS_ANSI} -{$UNDEF STRING_UNICODE_MISMATCH} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. Delphi/C++Builder Mobile/NextGen compilers -// do not support Ansi data types anymore, and is moving away from raw -// pointers as well. -// -// UPDATE: in Delphi/C++Builder 10.4, all Ansi types are supported again on -// all platforms, including the mobile compilers. -{$DEFINE HAS_AnsiString} -{$DEFINE HAS_AnsiChar} -{$DEFINE HAS_PAnsiChar} -{$UNDEF HAS_PPAnsiChar} -{$UNDEF NO_ANSI_TYPES} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. Delphi/C++Builder Mobile/NextGen compilers -// use ARC for TObject life time management. -// -// UPDATE: ARC for TObject lifetime management has been removed in -// Delphi/C++Builder 10.4 mobile compilers. All platforms now use a single -// unified memory management model! -{$UNDEF USE_MARSHALLED_PTRS} -{$UNDEF HAS_MarshaledAString} -{$UNDEF USE_OBJECT_ARC} - -// Make sure the following is $DEFINE'd only for suitable environments -// as specified further below. -{$UNDEF STRING_IS_IMMUTABLE} -{$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. -{$UNDEF HAS_TEncoding} -{$UNDEF HAS_TEncoding_GetEncoding_ByEncodingName} -{$UNDEF HAS_Exception_RaiseOuterException} -{$UNDEF HAS_System_ReturnAddress} -{$UNDEF HAS_TCharacter} -{$UNDEF HAS_TInterlocked} -{$UNDEF HAS_TNetEncoding} - -// Make sure that this is defined only for environments where we are using -// the iconv library to charactor conversions. -{.$UNDEF USE_ICONV} -{.$UNDEF USE_LCONVENC} - -//Define for Delphi cross-compiler targetting Posix -{$UNDEF USE_VCL_POSIX} -{$UNDEF HAS_ComponentPlatformsAttribute} -{$UNDEF HAS_ComponentPlatformsAttribute_Win32} -{$UNDEF HAS_ComponentPlatformsAttribute_Win64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSX32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator32} -{$UNDEF HAS_ComponentPlatformsAttribute_Android} -{$UNDEF HAS_ComponentPlatformsAttribute_Android32Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device32} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux64} -{$UNDEF HAS_ComponentPlatformsAttribute_WinNX32} -{$UNDEF HAS_ComponentPlatformsAttribute_WinIoT32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device64} -{$UNDEF HAS_ComponentPlatformsAttribute_WinARM} -{$UNDEF HAS_ComponentPlatformsAttribute_WinARM32} -{$UNDEF HAS_ComponentPlatformsAttribute_OSX64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux32Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux64Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Android64} -{$UNDEF HAS_ComponentPlatformsAttribute_Android64Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator64} -{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm32} -{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSXArm64} -{$UNDEF HAS_ComponentPlatformsAttribute_AllPlatforms} -{$UNDEF HAS_DIRECTIVE_WARN_DEFAULT} - -// Define for Delphi to auto-generate platform-appropriate '#pragma link' statements in HPP files -{$UNDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT} - -// detect compiler versions - -{$IFNDEF FPC} - - // TODO: to detect features in Delphi/C++Builder v6 and later, use CompilerVersion - // and RTLVersion constants instead of VERXXX defines. We still support v5, which - // does not have such constants. - - // Delphi 4 - {$IFDEF VER120} - {$DEFINE DCC} - {$DEFINE VCL_40} - {$DEFINE DELPHI_4} - {$ENDIF} - - // C++Builder 4 - {$IFDEF VER125} - {$DEFINE DCC} - {$DEFINE VCL_40} - {$DEFINE CBUILDER_4} - {$ENDIF} - - // Delphi & C++Builder 5 - {$IFDEF VER130} - {$DEFINE DCC} - {$DEFINE VCL_50} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_5} - {$ELSE} - {$DEFINE DELPHI_5} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 6 - {$IFDEF VER140} - {$DEFINE DCC} - {$DEFINE VCL_60} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_6} - {$ELSE} - {$DEFINE DELPHI_6} - {$ENDIF} - {$ENDIF} - - //Delphi 7 - {$IFDEF VER150} - {$DEFINE DCC} - {$DEFINE VCL_70} - {$DEFINE DELPHI_7} // there was no C++ Builder 7 - {$ENDIF} - - //Delphi 8 - {$IFDEF VER160} - {$DEFINE DCC} - {$DEFINE VCL_80} - {$DEFINE DELPHI_8} // there was no C++ Builder 8 - {$ENDIF} - - //Delphi 2005 - {$IFDEF VER170} - {$DEFINE DCC} - {$DEFINE VCL_2005} - {$DEFINE DELPHI_2005} // there was no C++Builder 2005 - {$ENDIF} - - // NOTE: CodeGear decided to make Highlander be a non-breaking release - // (no interface changes, thus fully backwards compatible without any - // end user code changes), so VER180 applies to both BDS 2006 and - // Highlander prior to the release of RAD Studio 2007. Use VER185 to - // identify Highlanger specifically. - - //Delphi & C++Builder 2006 - //Delphi & C++Builder 2007 (Highlander) - {$IFDEF VER180} - {$DEFINE DCC} - {$DEFINE VCL_2006} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2006} - {$ELSE} - {$DEFINE DELPHI_2006} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2007 (Highlander) - {$IFDEF VER185} - {$DEFINE DCC} - {$UNDEF VCL_2006} - {$DEFINE VCL_2007} - {$IFDEF CBUILDER} - {$UNDEF CBUILDER_2006} - {$DEFINE CBUILDER_2007} - {$ELSE} - {$UNDEF DELPHI_2006} - {$DEFINE DELPHI_2007} - {$ENDIF} - {$ENDIF} - - // BDS 2007 NET personality uses VER190 instead of 185. - //Delphi .NET 2007 - {$IFDEF VER190} - {$DEFINE DCC} - {$IFDEF CIL} - //Delphi 2007 - {$DEFINE VCL_2007} - {$DEFINE DELPHI_2007} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2009 (Tiburon) - {$IFDEF VER200} - {$DEFINE DCC} - {$DEFINE VCL_2009} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2009} - {$ELSE} - {$DEFINE DELPHI_2009} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2010 (Weaver) - {$IFDEF VER210} - {$DEFINE DCC} - {$DEFINE VCL_2010} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2010} - {$ELSE} - {$DEFINE DELPHI_2010} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder XE (Fulcrum) - {$IFDEF VER220} - //REMOVE DCC DEFINE after the next Fulcrum beta. - //It will be defined there. - {$IFNDEF DCC} - {$DEFINE DCC} - {$ENDIF} - {$DEFINE VCL_XE} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE} - {$ELSE} - {$DEFINE DELPHI_XE} - {$ENDIF} - {$ENDIF} - - // DCC is now defined by the Delphi compiler starting in XE2 - - //Delphi & CBuilder XE2 (Pulsar) - {$IFDEF VER230} - {$DEFINE VCL_XE2} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE2} - {$ELSE} - {$DEFINE DELPHI_XE2} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE3 (Waterdragon) - //Delphi & CBuilder XE3.5 (Quintessence - early betas only) - {$IFDEF VER240} - {$DEFINE VCL_XE3} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE3} - {$ELSE} - {$DEFINE DELPHI_XE3} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE4 (Quintessence) - {$IFDEF VER250} - {$UNDEF VCL_XE3} - {$DEFINE VCL_XE4} - {$IFDEF CBUILDER} - {$UNDEF CBUILDER_XE3} - {$DEFINE CBUILDER_XE4} - {$ELSE} - {$UNDEF DELPHI_XE3} - {$DEFINE DELPHI_XE4} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE5 (Zephyr) - {$IFDEF VER260} - {$DEFINE VCL_XE5} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE5} - {$ELSE} - {$DEFINE DELPHI_XE5} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder AppMethod - //AppMethod is just XE5 for mobile only, VCL is removed - {$IFDEF VER265} - {$DEFINE VCL_XE5} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE5} - {$ELSE} - {$DEFINE DELPHI_XE5} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE6 (Proteus) - {$IFDEF VER270} - {$DEFINE VCL_XE6} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE6} - {$ELSE} - {$DEFINE DELPHI_XE6} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE7 (Carpathia) - {$IFDEF VER280} - {$DEFINE VCL_XE7} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE7} - {$ELSE} - {$DEFINE DELPHI_XE7} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE8 (Elbrus) - {$IFDEF VER290} - {$DEFINE VCL_XE8} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE8} - {$ELSE} - {$DEFINE DELPHI_XE8} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.0 Seattle (Aitana) - {$IFDEF VER300} - {$DEFINE VCL_10_0} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_VCL_10_0} - {$ELSE} - {$DEFINE DELPHI_VCL_10_0} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.1 Berlin (BigBen) - {$IFDEF VER310} - {$DEFINE VCL_10_1} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_1} - {$ELSE} - {$DEFINE DELPHI_10_1} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.2 Tokyo (Godzilla) - {$IFDEF VER320} - {$DEFINE VCL_10_2} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_2} - {$ELSE} - {$DEFINE DELPHI_10_2} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.3 Rio (Carnival) - {$IFDEF VER330} - {$DEFINE VCL_10_3} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_3} - {$ELSE} - {$DEFINE DELPHI_10_3} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.4 Sydney (Denali) - {$IFDEF VER340} - {$DEFINE VCL_10_4} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_4} - {$ELSE} - {$DEFINE DELPHI_10_4} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 11.0 Alexandria (Olympus) - {$IFDEF VER350} - {$DEFINE VCL_11} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_11} - {$ELSE} - {$DEFINE DELPHI_11} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 12.0 Athens (Yukon) - {$IFDEF VER360} - {$DEFINE VCL_12} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_12} - {$ELSE} - {$DEFINE DELPHI_12} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 13.0+ (?) - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF CompilerVersion >= 37} - {$MESSAGE WARN 'Unknown compiler version detected! Assuming >= 13.x '} - {$DEFINE VCL_UNKNOWN_VERSION} - {$DEFINE VCL_13} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_13} - {$ELSE} - {$DEFINE DELPHI_13} - {$ENDIF} - {$IFEND} - {$ENDIF} - - // Kylix - // - //Important: Don't use CompilerVersion here as IF's are evaluated before - //IFDEF's and Kylix 1 does not have CompilerVersion defined at all. - {$IFDEF LINUX} - {$DEFINE UNIX} - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF (RTLVersion >= 14.0) and (RTLVersion <= 14.5) } - {$DEFINE KYLIX} - {$IF RTLVersion = 14.5} - {$DEFINE KYLIX_3} - {$ELSEIF RTLVersion >= 14.2} - {$DEFINE KYLIX_2} - {$ELSE} - {$DEFINE KYLIX_1} - {$IFEND} - {$IFEND} - {$ENDIF} - {$ENDIF} - -{$ENDIF} - -// Delphi.NET -// Covers D8+ -{$IFDEF CIL} - // Platform specific conditional. Used for platform specific code. - {$DEFINE DOTNET} - {$DEFINE STRING_IS_UNICODE} - {$DEFINE STRING_IS_IMMUTABLE} - {.$DEFINE HAS_Int8} - {.$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_UInt64} -{$ENDIF} - -{$IFDEF KYLIX} - {$DEFINE VCL_60} - {$DEFINE INT_THREAD_PRIORITY} - {$DEFINE CPUI386} - {$UNDEF USE_BASEUNIX} - - {$IFDEF KYLIX_3} - {$DEFINE KYLIX_3_OR_ABOVE} - {$ENDIF} - - {$IFDEF KYLIX_3_OR_ABOVE} - {$DEFINE KYLIX_2_OR_ABOVE} - {$ELSE} - {$IFDEF KYLIX_2} - {$DEFINE KYLIX_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF KYLIX_2_OR_ABOVE} - {$DEFINE KYLIX_1_OR_ABOVE} - {$ELSE} - {$IFDEF KYLIX_1} - {$DEFINE KYLIX_1_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFNDEF KYLIX_3_OR_ABOVE} - {$DEFINE KYLIXCOMPAT} - {$ENDIF} - - {$IFDEF KYLIX_2_OR_ABOVE} - {$DEFINE USE_ZLIB_UNIT} - {$ENDIF} -{$ENDIF} - -// FPC (2+) - -{$IFDEF FPC} - // TODO: In FreePascal 4.2.0+, a Delphi-like UnicodeString type is supported. - // However, String/(P)Char do not map to UnicodeString/(P)WideChar unless - // either {$MODE DelphiUnicode} or {$MODESWITCH UnicodeStrings} is used. - // We should consider enabling one of them so Indy uses the same Unicode logic - // in Delphi 2009+ and FreePascal 4.2.0+ and reduces IFDEFs (in particular, - // STRING_UNICODE_MISMATCH, see further below). However, FreePascal's RTL - // is largely not UnicodeString-enabled yet. Maybe we should enable - // {$MODE DelphiUnicode} anyway, and then deal with any RTL function issues - // on an as-needed basis... - {$MODE Delphi} - //note that we may need further defines for widget types depending on - //what we do and what platforms we support in FPC. - //I'll let Marco think about that one. - {$IFDEF UNIX} - {$DEFINE USE_BASEUNIX} - {$IFDEF LINUX} - //In Linux for I386, you can choose between a Kylix-libc API or - //the standard RTL Unix API. Just pass -dKYLIXCOMPAT to the FPC compiler. - //I will see what I can do about the Makefile. - {$IFDEF KYLIXCOMPAT} - {$IFDEF CPUI386} - {$UNDEF USE_BASEUNIX} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$IFDEF USE_BASEUNIX} - {$UNDEF KYLIXCOMPAT} - {$ENDIF} - {$ENDIF} - - // FPC_FULLVERSION was added in FPC 2.2.4 - // Have to use Defined() or else Delphi compiler chokes, since it - // evaluates $IF statements before $IFDEF statements... - - {$MACRO ON} // must be on in order to use versioning macros - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30101)} - {$DEFINE FPC_3_1_1_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30000)} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20701)} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20604)} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20602)} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20600)} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20404)} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20402)} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20400)} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20204)} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20202)} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20105)} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$IFEND} - - // just in case - {$IFDEF FPC_3_1_1} - {$DEFINE FPC_3_1_1_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_3_0_0} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_7_1} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_4} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_2} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_0} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_4} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_2} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_0} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_2_4} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_2_2} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_1_5} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ENDIF} - - {$IFDEF FPC_3_1_1_OR_ABOVE} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_3_0_0} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_3_0_0_OR_ABOVE} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_7_1} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_7_1_OR_ABOVE} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_4} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_4_OR_ABOVE} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_2} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_0} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_0_OR_ABOVE} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_4} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_4_OR_ABOVE} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_2} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_2_OR_ABOVE} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_0} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_0_OR_ABOVE} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_2_4} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_4_OR_ABOVE} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_2_2} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_2_OR_ABOVE} - {$DEFINE FPC_2_2_0_OR_ABOVE} - {$ELSE} - {$IFDEF VER2_2} - {$DEFINE FPC_2_2_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_0_OR_ABOVE} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_1_5} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {.$IFDEF FPC_2_7_1_OR_ABOVE} - // support for RawByteString and UnicodeString - {.$MODE DelphiUnicode} - {.$MODESWITCH UnicodeStrings} - {.$CODEPAGE UTF8} // needed for Unicode string literals to work properly - {.$DEFINE VCL_2009} - {.$DEFINE DELPHI_2009} - {.$ELSE} - {$DEFINE VCL_70} - {$DEFINE DELPHI_7} - {.$ENDIF} -{$ENDIF} - -// end FPC - -{$IFDEF VCL_13} - {$DEFINE VCL_13_OR_ABOVE} -{$ENDIF} - -{$IFDEF VCL_13_OR_ABOVE} - {$DEFINE VCL_12_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_12} - {$DEFINE VCL_12_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_12_OR_ABOVE} - {$DEFINE VCL_11_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_11} - {$DEFINE VCL_11_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_11_OR_ABOVE} - {$DEFINE VCL_10_4_OR_ABOVE} - {$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_4} - {$DEFINE VCL_10_4_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_4_OR_ABOVE} - {$DEFINE VCL_10_3_OR_ABOVE} - {$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_3} - {$DEFINE VCL_10_3_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_OR_ABOVE} - {$DEFINE VCL_10_2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_2} - {$DEFINE VCL_10_2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_2_OR_ABOVE} - {$DEFINE VCL_10_1_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_1} - {$DEFINE VCL_10_1_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_1_OR_ABOVE} - {$DEFINE VCL_10_0_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_0} - {$DEFINE VCL_10_0_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_0_OR_ABOVE} - {$DEFINE VCL_XE8_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE8} - {$DEFINE VCL_XE8_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE VCL_XE7_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE7} - {$DEFINE VCL_XE7_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE7_OR_ABOVE} - {$DEFINE VCL_XE6_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE6} - {$DEFINE VCL_XE6_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE6_OR_ABOVE} - {$DEFINE VCL_XE5_OR_ABOVE} - {$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE5} - {$DEFINE VCL_XE5_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE5_OR_ABOVE} - {$DEFINE VCL_XE4_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE4} - {$DEFINE VCL_XE4_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE4_OR_ABOVE} - {$DEFINE VCL_XE3_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE3} - {$DEFINE VCL_XE3_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE3_OR_ABOVE} - {$DEFINE VCL_XE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE2} - {$DEFINE VCL_XE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE2_OR_ABOVE} - {$DEFINE VCL_XE_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE} - {$DEFINE VCL_XE_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE_OR_ABOVE} - {$DEFINE VCL_2010_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2010} - {$DEFINE VCL_2010_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2010_OR_ABOVE} - {$DEFINE VCL_2009_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2009} - {$DEFINE VCL_2009_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2009_OR_ABOVE} - {$DEFINE VCL_2007_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2007} - {$DEFINE VCL_2007_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2007_OR_ABOVE} - {$DEFINE VCL_2006_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2006} - {$DEFINE VCL_2006_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2006_OR_ABOVE} - {$DEFINE VCL_2005_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2005} - {$DEFINE VCL_2005_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2005_OR_ABOVE} - {$DEFINE VCL_8_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_80} - {$DEFINE VCL_8_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_8_OR_ABOVE} - {$DEFINE VCL_7_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_70} - {$DEFINE VCL_7_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_7_OR_ABOVE} - {$DEFINE VCL_6_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_60} - {$DEFINE VCL_6_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_6_OR_ABOVE} - {$DEFINE VCL_5_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_50} - {$DEFINE VCL_5_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_5_OR_ABOVE} - {$DEFINE VCL_4_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_40} - {$DEFINE VCL_4_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -// Normalize Delphi compiler defines to match FPC for consistency: -// -// CPU32 - any 32-bit CPU -// CPU64 - any 64-bit CPU -// WINDOWS - any Windows platform (32-bit, 64-bit, CE) -// WIN32 - Windows 32-bit -// WIN64 - Windows 64-bit -// WINCE - Windows CE -// -// Consult the "Free Pascal Programmer's Guide", Appendix G for the complete -// list of defines that are used. Do not work on this unless you understand -// what the FreePascal developers are doing. Not only do you have to -// descriminate with operating systems, but also with chip architectures -// are well. -// -// DCC Pulsar+ define the following values: -// ASSEMBLER -// DCC -// CONDITIONALEXPRESSIONS -// NATIVECODE -// UNICODE -// MACOS -// MACOS32 -// MACOS64 -// MSWINDOWS -// WIN32 -// WIN64 -// LINUX -// POSIX -// POSIX32 -// CPU386 -// CPUX86 -// CPUX64 -// -// Kylix defines the following values: -// LINUX -// (others??) -// - -{$IFNDEF FPC} - // TODO: We need to use ENDIAN_BIG for big endian chip architectures, - // such as 680x0, PowerPC, Sparc, and MIPS, once DCC supports them, - // provided it does not already define its own ENDIAN values by then... - {$DEFINE ENDIAN_LITTLE} - {$IFNDEF VCL_6_OR_ABOVE} - {$DEFINE MSWINDOWS} - {$ENDIF} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} - // TODO: map Pulsar's non-Windows platform defines... - {$IFDEF VCL_XE2_OR_ABOVE} - {$IFDEF VCL_XE8_OR_ABOVE} - {$IFDEF CPU32BITS} - //any 32-bit CPU - {$DEFINE CPU32} - {$ENDIF} - {$IFDEF CPU64BITS} - {$DEFINE CPU64} - {$ENDIF} - {$ELSE} - {$IFDEF CPU386} - //any 32-bit CPU - {$DEFINE CPU32} - //Intel 386 compatible chip architecture - {$DEFINE CPUI386} - {$ENDIF} - {$IFDEF CPUX86} - {$DEFINE CPU32} - {$ENDIF} - {$IFDEF CPUX64} - //any 64-bit CPU - {$DEFINE CPU64} - //AMD64 compatible chip architecture - {$DEFINE CPUX86_64} //historical name for AMD64 - {$DEFINE CPUAMD64} - {$ENDIF} - {$ENDIF} - {$ELSE} - {$IFNDEF DOTNET} - {$IFNDEF KYLIX} - {$DEFINE I386} - {$ENDIF} - {$ENDIF} - {$DEFINE CPU32} - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - //differences in DotNET Framework versions. - {$IFDEF VCL_2007_OR_ABOVE} - {$DEFINE DOTNET_2} - {$DEFINE DOTNET_2_OR_ABOVE} - {$ELSE} - {$DEFINE DOTNET_1_1} - {$ENDIF} - {$DEFINE DOTNET_1_1_OR_ABOVE} - // Extra include used in D7 for testing. Remove later when all comps are - // ported. Used to selectively exclude non ported parts. Allowed in places - // IFDEFs are otherwise not permitted. - {$DEFINE DOTNET_EXCLUDE} -{$ENDIF} - -// Check for available features - -{$IFDEF CBUILDER} - // When generating a C++ HPP file, if a class has no explicit constructor - // defined and contains compiler-managed members (xxxString, TDateTime, - // Variant, DelphiInterface, etc), the HPP will contain a forwarding - // inline constructor that implicitly initializes those managed members, - // which will overwrite any non-default initializations performed inside - // of InitComponent() overrides! In this situation, the workaround is to - // define an explicit constructor that calls the base class constructor - // manually, allowing those managed members to be initialized by the - // compiler before InitComponent() overrides then re-assign them. - {$DEFINE WORKAROUND_INLINE_CONSTRUCTORS} -{$ENDIF} - -{$IFDEF VCL_5_OR_ABOVE} - {$IFNDEF FPC} - {$IFNDEF KYLIX} - {$DEFINE HAS_RemoveFreeNotification} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_GetObjectProp} - {$DEFINE HAS_TObjectList} - {$DEFINE HAS_StrToInt64Def} -{$ENDIF} - -{$IFDEF VCL_6_OR_ABOVE} - {$DEFINE HAS_PCardinal} - {$DEFINE HAS_PByte} - {$DEFINE HAS_PWord} - {$DEFINE HAS_PPointer} - {$DEFINE HAS_TList_Assign} - {$DEFINE HAS_sLineBreak} - {$DEFINE HAS_RaiseLastOSError} - {$DEFINE HAS_SysUtils_IncludeExcludeTrailingPathDelimiter} - {$DEFINE HAS_SysUtils_DirectoryExists} - {$DEFINE HAS_UNIT_DateUtils} - {$DEFINE HAS_UNIT_StrUtils} - {$DEFINE HAS_UNIT_Types} - {$DEFINE HAS_TryStrToInt} - {$DEFINE HAS_TryStrToInt64} - {$DEFINE HAS_TryEncodeDate} - {$DEFINE HAS_TryEncodeTime} - {$DEFINE HAS_ENUM_ELEMENT_VALUES} - {$IFNDEF FPC} - {$DEFINE HAS_IInterface} - {$DEFINE HAS_TSelectionEditor} - {$DEFINE HAS_TStringList_CaseSensitive} - {$DEFINE HAS_AcquireExceptionObject} - {$IFNDEF KYLIX} - {$DEFINE HAS_DEPRECATED} - {$DEFINE HAS_SYMBOL_PLATFORM} - {$DEFINE HAS_UNIT_PLATFORM} - {$IFNDEF VCL_8_OR_ABOVE} - // Delphi 6 and 7 have an annoying bug that if a class method is declared as - // deprecated, the compiler will emit a "symbol is deprecated" warning - // on the method's implementation! So we will have to wrap implementations - // of deprecated methods with {$WARN SYMBOL_DEPRECATED OFF} directives - // to disable that warning. - {$DEFINE DEPRECATED_IMPL_BUG} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$IFNDEF DOTNET} - //Widget defines are omitted in .NET - {$DEFINE VCL_60_PLUS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_7_OR_ABOVE} - {$IFNDEF FPC} - {$DEFINE HAS_UInt64} // Note: it was just an alias for Int64 until D2006! - {$DEFINE HAS_NAMED_THREADS} - {$DEFINE HAS_TStrings_NameValueSeparator} - {$DEFINE HAS_TStrings_ValueFromIndex} - // Note: there is a ZLib unit available, but it doesn't have everything - // that is available in the System.ZLib unit in Delphi XE2+, so we are - // not going to use this ZLib unit yet... - {.$DEFINE HAS_UNIT_ZLib} - {$ENDIF} - {$DEFINE HAS_TFormatSettings} - {$DEFINE HAS_PosEx} - {$IFNDEF VCL_70} - // not implemented in D7 - {$DEFINE HAS_STATIC_TThread_Queue} - {$ENDIF} - {$IFNDEF CIL} - {$IFNDEF VCL_80} - // not implemented in D8 or .NET - {$DEFINE HAS_STATIC_TThread_Synchronize} - {$ENDIF} - {$ENDIF} -{$ELSE} - {$IFDEF CBUILDER_6} - {$DEFINE HAS_NAMED_THREADS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2005_OR_ABOVE} - {$IFDEF DCC} - // class helpers were first introduced in D2005, but were buggy and not - // officially supported until D2006... - {.$DEFINE HAS_CLASS_HELPER} - {$ENDIF} -{$ELSE} - {$IFDEF DCC} - // InterlockedCompareExchange() was declared in the Windows unit using Pointer - // parameters until Delphi 2005, when it was switched to Longint parameters - // instead to match the actual Win32 API declaration. - {$DEFINE HAS_InterlockedCompareExchange_Pointers} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2006_OR_ABOVE} - {$DEFINE USE_INLINE} - {$DEFINE HAS_2PARAM_FileAge} - {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? - {$DEFINE HAS_CLASS_HELPER} - {$IFDEF WINDOWS} - // System.RegisterExpectedMemoryLeak() is only available on Windows at this time - {$DEFINE HAS_System_RegisterExpectedMemoryLeak} - {$ENDIF} - // In C++Builder 2006 and 2007, UInt64 is emitted as signed __int64 in HPP - // files instead of as unsigned __int64. This causes conflicts in overloaded - // routines that have (U)Int64 parameters. This was fixed in C++Builder 2009... - {$IFDEF CBUILDER} - {$DEFINE BROKEN_UINT64_HPPEMIT} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2007_OR_ABOVE} - {$IFNDEF CBUILDER_2007} - // class properties are broken in C++Builder 2007, causing AVs at compile-time - {$DEFINE HAS_CLASSPROPERTIES} - {$ENDIF} - // Native(U)Int exist but are buggy, so do not use them yet - {.$DEFINE HAS_NativeInt} - {.$DEFINE HAS_NativeUInt} - {$DEFINE HAS_DWORD_PTR} - {$DEFINE HAS_ULONG_PTR} - {$DEFINE HAS_ULONGLONG} - {$DEFINE HAS_PGUID} - {$DEFINE HAS_PPAnsiChar} - {$DEFINE HAS_CurrentYear} - {$IFNDEF DOTNET} - {$DEFINE HAS_TIMEUNITS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2009_OR_ABOVE} - {$IFNDEF DOTNET} - {$DEFINE STRING_IS_UNICODE} - {$DEFINE HAS_UnicodeString} - {$DEFINE HAS_TEncoding} - {$DEFINE HAS_TCharacter} - {$DEFINE HAS_InterlockedCompareExchangePointer} - {$DEFINE HAS_WIDE_TCharArray} - {$DEFINE HAS_PUInt64} - {$IFDEF VCL_2009} - // TODO: need to differentiate between RTM and Update 1 - // FmtStr() is broken in RTM but was fixed in Update 1 - {$DEFINE BROKEN_FmtStr} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_CLASSVARS} - {$DEFINE HAS_DEPRECATED_MSG} - {$DEFINE HAS_TBytes} - // Native(U)Int are still buggy, so do not use them yet - {.$DEFINE HAS_NativeInt} - {.$DEFINE HAS_NativeUInt} - {$DEFINE HAS_Int8} - {$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_UIntToStr} - // UInt64 is now emitted as unsigned __int64 in HPP files - {$IFDEF CBUILDER} - {$UNDEF BROKEN_UINT64_HPPEMIT} - {$ENDIF} - {$IFDEF DCC} - {$IFDEF WINDOWS} - // Exception.RaiseOuterException() is only available on Windows at this time - {$DEFINE HAS_Exception_RaiseOuterException} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_SetCodePage} - {$DEFINE HAS_PRawByteString} - {$DEFINE HAS_TThreadProcedure} -{$ENDIF} - -{$IFDEF VCL_2010_OR_ABOVE} - {$DEFINE HAS_CLASSCONSTRUCTOR} - {$DEFINE HAS_CLASSDESTRUCTOR} - {$DEFINE HAS_DELAYLOAD} - {$DEFINE HAS_TThread_NameThreadForDebugging} - {$DEFINE DEPRECATED_TThread_SuspendResume} - // Native(U)Int are finally ok to use now - {$DEFINE HAS_NativeInt} - {$DEFINE HAS_NativeUInt} - {$DEFINE HAS_USHORT} - {$DEFINE HAS_IOUtils_TPath} -{$ENDIF} - -{$IFDEF VCL_XE_OR_ABOVE} - {$DEFINE HAS_TFormatSettings_Object} - {$DEFINE HAS_LocaleCharsFromUnicode} - {$DEFINE HAS_UnicodeFromLocaleChars} - {$DEFINE HAS_PLongBool} - {$DEFINE HAS_PVOID} - {$DEFINE HAS_ULONG64} - {$DEFINE HAS_TEncoding_GetEncoding_ByEncodingName} - {$DEFINE HAS_DateUtils_TTimeZone} - {$IFDEF DCC} - // Exception.RaiseOuterException() is now available on all platforms - {$DEFINE HAS_Exception_RaiseOuterException} - {$ENDIF} - {$IFNDEF DOTNET} - {$DEFINE HAS_TInterlocked} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE2_OR_ABOVE} - {$DEFINE HAS_SIZE_T} - {$DEFINE HAS_PSIZE_T} - {$DEFINE HAS_SSIZE_T} - {$DEFINE HAS_PSSIZE_T} - {$DEFINE HAS_LONG} - {$DEFINE HAS_ComponentPlatformsAttribute} - {$DEFINE HAS_ComponentPlatformsAttribute_Win32} - {$DEFINE HAS_ComponentPlatformsAttribute_Win64} - {$DEFINE HAS_ComponentPlatformsAttribute_OSX32} - {$DEFINE HAS_System_ReturnAddress} - {$DEFINE HAS_DIRECTIVE_WARN_DEFAULT} - {$DEFINE HAS_UNIT_System_ZLib} -{$ENDIF} - -{$IFDEF VCL_XE3_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_ZEROBASEDSTRINGS} - {$DEFINE HAS_SysUtils_TStringHelper} - {$IFDEF NEXTGEN} - {$DEFINE DCC_NEXTGEN} - {$DEFINE HAS_MarshaledAString} - {$DEFINE USE_MARSHALLED_PTRS} - {$IFDEF AUTOREFCOUNT} - {$DEFINE USE_OBJECT_ARC} - {$ENDIF} - {$ENDIF} - // technically, these are present in XE3, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} - {.$DEFINE HAS_ComponentPlatformsAttribute_Android} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32} - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} - {.$DEFINE HAS_ComponentPlatformsAttribute_WinNX32} -{$ENDIF} - -{$IFDEF VCL_XE4_OR_ABOVE} - {$DEFINE HAS_AnsiStrings_StrPLCopy} - {$DEFINE HAS_AnsiStrings_StrLen} - {$DEFINE HAS_Character_TCharHelper} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} -{$ENDIF} - -{$IFDEF VCL_XE5_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_Android} -{$ENDIF} - -{$IFDEF VCL_XE5_UPDATE2_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_LINKUNIT} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_NAMESPACE} -{$ENDIF} - -{$IFDEF VCL_XE7_OR_ABOVE} - {$DEFINE HAS_TNetEncoding} -{$ENDIF} - -{$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device32} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device64} - // technically, these are present in XE8, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64} - {.$DEFINE HAS_ComponentPlatformsAttribute_WinIoT32} -{$ENDIF} - -{$IFDEF VCL_10_0_OR_ABOVE} - {$IFDEF ANDROID} - {$DEFINE HAS_TAndroidHelper} - {$ENDIF} - // technically, these are present in 10.0 Seattle, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_WinARM} -{$ENDIF} - -{$IFDEF VCL_10_1_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_LEGACYHPP} - {$DEFINE HAS_TStrings_AddPair} - // technically, these are present in 10.1 Berlin, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_OSX64} - {.$DEFINE HAS_ComponentPlatformsAttribute_OSXNX64} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32Arm} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64Arm} - {.$DEFINE HAS_ComponentPlatformsAttribute_Android64} -{$ENDIF} - -{$IFDEF VCL_10_2_OR_ABOVE} - {.$WARN IMPLICIT_INTEGER_CAST_LOSS OFF} - {.$WARN IMPLICIT_CONVERSION_LOSS OFF} - {.$WARN COMBINING_SIGNED_UNSIGNED64 OFF} - {$DEFINE HAS_STATIC_TThread_ForceQueue} - // In Delphi 10.2 Tokyo, TThread.ForceQueue() is broken on Android, the - // passed in procedure is called immediately instead of being delayed! - {$IFDEF ANDROID} - {$DEFINE BROKEN_TThread_ForceQueue} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator32} - {$DEFINE HAS_ComponentPlatformsAttribute_Android32Arm} - {$DEFINE HAS_ComponentPlatformsAttribute_WinARM32} - {$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} // removed in 10.3 Rio - // technically, these are present in 10.3 Rio, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator64} - {$IFDEF DCC} - {$IFDEF LINUX} - // RLebeau 9/25/2019: there is a bug in the IDE when debugging Linux projects - // where the EThreadNameException exception raised by TThread.NameThreadForDebugging() - // is not handled correctly. - {$UNDEF HAS_NAMED_THREADS} - {$ENDIF} - {$ENDIF} - {$IFDEF ANDROID} - {$UNDEF BROKEN_TThread_ForceQueue} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_UPDATE2_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_AllPlatforms} - {$DEFINE HAS_ComponentPlatformsAttribute_OSX64} -{$ENDIF} - -{$IFDEF VCL_10_4_OR_ABOVE} - // 0-based string indexing via '[]' is turned off by default in Delphi 10.4. - // TStringHelper is always 0-indexed, flat RTL functions are always 1-indexed, - // and now '[]' is 1-indexed again on all platforms - {$ZEROBASEDSTRINGS OFF} - // is the default. - {.$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} -{$ENDIF} - -{$IFDEF VCL_11_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm32} - {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm64} - {$DEFINE HAS_ComponentPlatformsAttribute_OSXArm64} -{$ENDIF} - -// Delphi XE+ cross-compiling -{$IFNDEF FPC} - {$IFDEF POSIX} - {$IF RTLVersion >= 22.0} - {$DEFINE UNIX} - {$UNDEF USE_BASEUNIX} - {$DEFINE VCL_CROSS_COMPILE} - {$DEFINE USE_VCL_POSIX} - {$IFEND} - {$ENDIF} - {$IFDEF LINUX} - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF RTLVersion >= 22.0} - {$DEFINE VCL_CROSS_COMPILE} - {$DEFINE USE_VCL_POSIX} - {$IFEND} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_CROSS_COMPILE} - {$UNDEF KYLIXCOMPAT} -{$ELSE} - {$IFDEF KYLIXCOMPAT} - {$linklib c} - {$ENDIF} -{$ENDIF} - -{$IFDEF FPC} - {$DEFINE USE_INLINE} - {$DEFINE USE_CLASSINLINE} - {$DEFINE USE_TBitBtn} //use Bit Buttons instead of Buttons - {$DEFINE FPC_REINTRODUCE_BUG} - {$DEFINE FPC_CIRCULAR_BUG} - {$DEFINE NO_REDECLARE} - {$DEFINE BYTE_COMPARE_SETS} - {$DEFINE HAS_QWord} // TODO: when was QWord introduced? - {$DEFINE HAS_PQWord} // TODO: when was PQWord introduced? - {$IFDEF FPC_2_1_5_OR_ABOVE} - {$DEFINE HAS_UInt64} - {.$DEFINE HAS_PUInt64} // TODO: is this defined? - {$ENDIF} - {$IFDEF FPC_2_2_0_OR_ABOVE} - {$DEFINE HAS_InterlockedCompareExchange_Pointers} - {$ENDIF} - {$IFDEF FPC_2_2_2_OR_ABOVE} - {$DEFINE HAS_SharedSuffix} - {$ENDIF} - {$IFDEF FPC_2_2_4_OR_ABOVE} - // these types are only available on Unix systems (FreeBSD, Linux, etc) - {$IFDEF UNIX} - {$DEFINE HAS_UNIT_UnixType} - {$DEFINE HAS_SIZE_T} - {$DEFINE HAS_PSIZE_T} - {$DEFINE HAS_SSIZE_T} - {$DEFINE HAS_PSSIZE_T} - {$DEFINE HAS_TIME_T} - {$DEFINE HAS_PTIME_T} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_PtrInt} - {$DEFINE HAS_PtrUInt} - {$DEFINE HAS_PGUID} - {$DEFINE HAS_LPGUID} - {$DEFINE HAS_PPAnsiChar} - {$DEFINE HAS_ENUM_ELEMENT_VALUES} - {$DEFINE HAS_AcquireExceptionObject} // TODO: when was AcquireExceptionObject introduced? - {$IFDEF WINDOWS} - {$DEFINE HAS_ULONG_PTR} - {.$DEFINE HAS_ULONGLONG} // TODO: is this defined? - {$ENDIF} - {$DEFINE HAS_UNIT_ctypes} - {$DEFINE HAS_sLineBreak} - {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? - {$IFDEF FPC_HAS_UNICODESTRING} - {$DEFINE HAS_UnicodeString} - {$ELSE} - {$IFDEF FPC_2_4_0_OR_ABOVE} - {$DEFINE HAS_UnicodeString} - {$ENDIF} - {$ENDIF} - {$IFDEF FPC_2_4_4_OR_ABOVE} - {$DEFINE DEPRECATED_TThread_SuspendResume} - {$DEFINE HAS_DEPRECATED} // TODO: when was deprecated introduced? Possibly 1.9.x - {$DEFINE HAS_DEPRECATED_MSG} // TODO: when was message support added? Possibly 2.4.x - {$DEFINE HAS_STATIC_TThread_Synchronize} - {$IFNDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE USE_SEMICOLON_BEFORE_DEPRECATED} // TODO: which earlier versions require a semicolon? - {$ENDIF} - {$ENDIF} - {$IFDEF FPC_2_6_0_OR_ABOVE} - {$DEFINE HAS_NativeInt} - {$DEFINE HAS_NativeUInt} - {$DEFINE HAS_CLASS_HELPER} - {$ENDIF} - {$IFDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE HAS_Int8} - {$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_GetLocalTimeOffset} - {$DEFINE HAS_UniversalTimeToLocal} - {$DEFINE HAS_LocalTimeToUniversal} - {$ENDIF} - {$IFDEF FPC_2_6_4_OR_ABOVE} - {$DEFINE HAS_PInt8} - {$DEFINE HAS_PUInt8} - {$DEFINE HAS_PInt16} - {$DEFINE HAS_PUInt16} - {$DEFINE HAS_PInt32} - {$DEFINE HAS_PUInt32} - {$ENDIF} - {$IFDEF FPC_3_0_0_OR_ABOVE} - {$DEFINE HAS_STATIC_TThread_Queue} - {$DEFINE HAS_SetCodePage} - {$ENDIF} - {$IFDEF FPC_UNICODESTRINGS} - {$DEFINE STRING_IS_UNICODE} - {$ENDIF} - {$IFDEF FPC_3_1_1_OR_ABOVE} - {$DEFINE HAS_STATIC_TThread_ForceQueue} // requires rev 37359+ - {$DEFINE HAS_PRawByteString} - {$DEFINE HAS_UIntToStr} // requires rev 40529+ - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - {$DEFINE WIDGET_WINFORMS} -{$ELSE} - {$DEFINE WIDGET_VCL_LIKE} // LCL included. - {$DEFINE WIDGET_VCL_LIKE_OR_KYLIX} - {$IFDEF FPC} - {$DEFINE WIDGET_LCL} - {$ELSE} - {$IFDEF KYLIX} - {$DEFINE WIDGET_KYLIX} - {$ELSE} - {$DEFINE WIDGET_VCL} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -// .NET and Delphi 2009+ support UNICODE strings natively! -// -// FreePascal 2.4.0+ supports UnicodeString, but does not map its -// native String type to UnicodeString except when {$MODE DelphiUnicode} -// or {$MODESWITCH UnicodeStrings} is enabled. However, UNICODE is not -// defined in that mode yet until its RTL has been updated to support -// UnicodeString. STRING_UNICODE_MISMATCH is defined when the native -// String/Char types do not map to the same types that APIs are expecting -// based on whether UNICODE is defined or not. -// -// NOTE: Do not define UNICODE here. The compiler defines -// the symbol automatically. -{$IFDEF STRING_IS_UNICODE} - {$IFNDEF UNICODE} - {$DEFINE STRING_UNICODE_MISMATCH} - {$ENDIF} -{$ELSE} - {$DEFINE STRING_IS_ANSI} - {$IFDEF UNICODE} - {$DEFINE STRING_UNICODE_MISMATCH} - {$ENDIF} -{$ENDIF} - -{$IFDEF DCC_NEXTGEN} - {$DEFINE NO_ANSI_TYPES} - {.$DEFINE STRING_IS_IMMUTABLE} // Strings are NOT immutable in NEXTGEN yet - {$IFDEF USE_OBJECT_ARC} - // TODO: move these to an appropriate section. Not doing this yet because - // it is a major interface change to switch to Generics and we should - // maintain backwards compatibility with earlier compilers for the time - // being. Defining them only here for now because the non-Generic versions - // of these classes have become deprecated by ARC and so we need to start - // taking advantage of the Generics versions... - {$DEFINE HAS_UNIT_Generics_Collections} - {$DEFINE HAS_UNIT_Generics_Defaults} - {$DEFINE HAS_GENERICS_TDictionary} - {$DEFINE HAS_GENERICS_TList} - {$DEFINE HAS_GENERICS_TObjectList} - {$DEFINE HAS_GENERICS_TThreadList} - // TArray.Copy() was introduced in XE7 but was buggy. It was fixed in XE8: - // - // RSP-9763 TArray.Copy copies from destination to source for unmanaged types - // https://quality.embarcadero.com/browse/RSP-9763 - // - {$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE HAS_GENERICS_TArray_Copy} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -// TODO: Ansi data types were disabled on mobile platforms in XE3, but -// UTF8String and RawByteString were re-enabled in 10.1 Berlin! What else, -// if anything, was re-enabled to facilitate that? -// -// UPDATE: In 10.4 Sydney, AnsiChar and AnsiString were re-enabled on -// mobile platforms! NEXTGEN is no longer defined in the mobile compilers. -{$IFDEF NO_ANSI_TYPES} - {$UNDEF HAS_AnsiString} - {$UNDEF HAS_AnsiChar} - {$UNDEF HAS_PAnsiChar} - {$UNDEF HAS_PPAnsiChar} - {$UNDEF HAS_AnsiStrings_StrPLCopy} - {$UNDEF HAS_AnsiStrings_StrLen} -{$ENDIF} - -{$IFDEF WIN32} - {$DEFINE WIN32_OR_WIN64} -{$ENDIF} -{$IFDEF WIN64} - {$DEFINE WIN32_OR_WIN64} -{$ENDIF} - -{$IFDEF WIN32_OR_WIN64} - {$DEFINE USE_ZLIB_UNIT} - {$IFNDEF DCC_NEXTGEN} - {$DEFINE USE_OPENSSL} // !!! MOVED HERE BY EMBT - {$DEFINE USE_SSPI} - {$IFDEF STRING_IS_UNICODE} - {$DEFINE SSPI_UNICODE} - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF WINCE} - {$DEFINE USE_OPENSSL} - // RLebeau: not sure if the above Win32/64 defines also apply to WinCE, - // so keeping them separate for now... -{$ENDIF} - -// High-performance counters are not reliable on multi-core systems, and have -// been known to cause problems with TIdIOHandler.ReadLn() timeouts in Windows -// XP SP3, both 32-bit and 64-bit. Refer to these discussions for more info: -// -// http://www.virtualdub.org/blog/pivot/entry.php?id=106 -// http://blogs.msdn.com/oldnewthing/archive/2008/09/08/8931563.aspx -// -// Do not enable thus unless you know it will work correctly on your systems! -{$IFDEF WINDOWS} - {.$DEFINE USE_HI_PERF_COUNTER_FOR_TICKS} -{$ENDIF} - -{$IFDEF UNIX} - {$DEFINE USE_OPENSSL} - {$DEFINE USE_ZLIB_UNIT} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF MACOS} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF DARWIN} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF LINUX} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF IOS} - {$DEFINE HAS_getifaddrs} - {$DEFINE USE_OPENSSL} - - // Support for 64-bit ARM iOS Simulator was added in Delphi 11.2 - // TODO: how to detect iOS Simulator in FPC? Does it support 64-bit ARM? - {$IFDEF CPUARM} - {$IFNDEF IOSSIMULATOR} - // RLebeau: For iOS devices, OpenSSL cannot be used as an external library, - // it must be statically linked into the app. For the iOS simulator, this - // is not true. Users who want to use OpenSSL in iOS device apps will need - // to add the static OpenSSL library to the project and then include the - // IdSSLOpenSSLHeaders_static unit in their uses clause. It hooks up the - // statically linked functions for the IdSSLOpenSSLHeaders unit to use... - {$DEFINE STATICLOAD_OPENSSL} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{$IFDEF FREEBSD} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF ANDROID} - {$UNDEF HAS_getifaddrs} -{$ENDIF} - -{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} - {$DEFINE REQUIRES_PROPER_ALIGNMENT} -{$ENDIF} - -// -//iconv defines section. -{$DEFINE USE_ICONV_UNIT} -{$DEFINE USE_ICONV_ENC} -{$IFDEF UNIX} - {$DEFINE USE_ICONV} - {$IFDEF USE_BASEUNIX} - {$IFDEF FPC} - {$UNDEF USE_ICONV_UNIT} - {$ELSE} - {$UNDEF USE_ICONV_ENC} - {$ENDIF} - {$ENDIF} - {$IFDEF KYLIXCOMPAT} - //important!! Iconv functions are defined in the libc.pas Kylix compatible unit. - {$UNDEF USE_ICONV_ENC} - {$UNDEF USE_ICONV_UNIT} - {$ENDIF} -{$ENDIF} -{$IFDEF NETWARELIBC} - {$DEFINE USE_ICONV} - //important!!! iconv functions are defined in the libc.pas Novell Netware header. - //Do not define USE_ICONV_UNIT - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} -{$ENDIF} - -{$UNDEF USE_SAFELOADLIBRARY} -{$IFDEF WINDOWS} - {$UNDEF USE_ICONV_ENC} - {$DEFINE USE_SAFELOADLIBRARY} -{$ENDIF} -// Use here for all *nix systems that you do not want to use iconv library -{$IFDEF FPC} - {$IFDEF ANDROID} - {$UNDEF USE_ICONV} - {$DEFINE USE_LCONVENC} - {$ENDIF} -{$ENDIF} - -{$UNDEF USE_INVALIDATE_MOD_CACHE} -{$UNDEF USE_SAFELOADLIBRARY} -//This must come after the iconv defines because this compiler targets a Unix-like -//operating system. One key difference is that it does have a TEncoding class. -//If this comes before the ICONV defines, it creates problems. -//This also must go before the THandle size calculations. -{$IFDEF VCL_CROSS_COMPILE} - {$IFDEF POSIX} - {$IFNDEF LINUX} - {$DEFINE BSD} - {$ENDIF} - {$DEFINE USE_SAFELOADLIBRARY} - {$DEFINE USE_INVALIDATE_MOD_CACHE} - {$ENDIF} - //important!!! iconv functions are defined in the libc.pas Novell Netware header. - //Do not define USE_ICONVUNIT - {$UNDEF USE_ICONV} - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} - {$DEFINE INT_THREAD_PRIORITY} -{$ENDIF} - -{$IFNDEF USE_ICONV} - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} -{$ENDIF} - -//IMPORTANT!!!! -// -//Do not remove this!!! This is to work around a conflict. In DCC, MACOS -//will mean OS X. In FreePascal, the DEFINE MACOS means MacIntosh System OS Classic. -{$IFDEF DCC} - // DCC defines MACOS for both iOS and OS X platforms, need to differentiate - {$IFDEF MACOS} - {$IFNDEF IOS} - {$DEFINE OSX} - {$DEFINE DARWIN} - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF FPC} - // FPC defines DARWIN for both OSX and iOS, need to differentiate - {$IFDEF DARWIN} - {$IFNDEF IOS} - {$DEFINE OSX} - {$ENDIF} - {$ENDIF} - {$IFDEF MACOS} - {$DEFINE MACOS_CLASSIC} - {$ENDIF} -{$ENDIF} - -{ -BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit -word to an 8 bit byte and an 8 bit byte field named sa_len was added. -} -//Place this only after DARWIN has been defined for Delphi MACOS -{$IFDEF FREEBSD} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF DARWIN} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF MORPHOS} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} - -// Do NOT remove these IFDEF's. They are here because InterlockedExchange -// only handles 32bit values. Some Operating Systems may have 64bit -// THandles. This is not always tied to the platform architecture. - -{$IFDEF AMIGA} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF ATARI} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF BEOS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF BSD} - //I think BSD might handle FreeBSD, NetBSD, OpenBSD, and Darwin - {$IFDEF IOS} - {$IFDEF CPUARM64} - {$DEFINE CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$IFDEF CPUARM32} - {$DEFINE CPU32} - {$ENDIF} - {$DEFINE THANDLE_32} - {$ENDIF} - {$ENDIF} - {$IFDEF OSX} - {$IFDEF FPC} - {$DEFINE THANDLE_32} - {$ELSE} - {$DEFINE THANDLE_CPUBITS} // !!! ADDED OSX BY EMBT - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF EMBEDDED} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF EMX} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF GBA} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF GO32} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF LINUX} - {$IFDEF LINUX64} - {$DEFINE CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$IFDEF LINUX32} - {$DEFINE CPU32} - {$ENDIF} - {$DEFINE THANDLE_32} - {$ENDIF} -{$ENDIF} -{$IFDEF MACOS_CLASSIC} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF MORPHOS} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF NATIVENT} //Native NT for kernel level drivers - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF NDS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF NETWARE} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF NETWARELIBC} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF OS2} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF PALMOS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF SOLARIS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF SYMBIAN} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WII} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WATCOM} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WINDOWS} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} - -// end platform specific stuff for THandle size - -{$IFDEF THANDLE_CPUBITS} - {$IFDEF CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$DEFINE THANDLE_32} - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - {$DEFINE DOTNET_OR_ICONV} -{$ENDIF} -{$IFDEF USE_ICONV} - {$DEFINE DOTNET_OR_ICONV} -{$ENDIF} - -{$UNDEF STREAM_SIZE_64} -{$IFDEF FPC} - {$DEFINE STREAM_SIZE_64} -{$ELSE} - {$IFDEF VCL_6_OR_ABOVE} - {$DEFINE STREAM_SIZE_64} - {$ENDIF} -{$ENDIF} - -{$IFNDEF FREE_ON_FINAL} - {$IFNDEF DOTNET} - {$IFDEF HAS_System_RegisterExpectedMemoryLeak} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_FASTMM4} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_MADEXCEPT} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_LEAKCHECK} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{ -We must determine what the SocketType parameter is for the Socket function. -In DotNET, it's SocketType. In Kylix and the libc.pas Kylix-compatibility -library, it's a __socket_type. In BaseUnix, it's a C-type Integer. In Windows, -it's a LongInt. - -} -{$UNDEF SOCKETTYPE_IS_SOCKETTYPE} -{$UNDEF SOCKETTYPE_IS_CINT} -{$UNDEF SOCKETTYPE_IS___SOCKETTYPE} -{$UNDEF SOCKETTYPE_IS_LONGINT} -{$UNDEF SOCKETTYPE_IS_NUMERIC} -{$UNDEF SOCKET_LEN_IS_socklen_t} -{$IFDEF DOTNET} - {$DEFINE SOCKETTYPE_IS_SOCKETTYPE} -{$ENDIF} -{$IFDEF USE_BASEUNIX} - {$DEFINE SOCKETTYPE_IS_CINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF KYLIXCOMPAT} - {$DEFINE SOCKETTYPE_IS___SOCKETTYPE} -{$ENDIF} -{$IFDEF USE_VCL_POSIX} - {$DEFINE SOCKETTYPE_IS_NUMERIC} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKET_LEN_IS_socklen_t} -{$ENDIF} -{$IFDEF WINDOWS} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF OS2} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF NETWARE} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} - -{Take advantage of some TCP features specific to some stacks. -They work somewhat similarly but there's a key difference. -In Linux, TCP_CORK is turned on to send fixed packet sizes and -when turned-off (uncorked), any remaining data is sent. With -TCP_NOPUSH, this might not happen and remaining data is only sent -before disconnect. TCP_KEEPIDLE and TCP_KEEPINTVL so the IFDEF LINUX and IFDEF -SOLARIS instead of IFDEF UNIX is not an error, it's deliberate.} -{$UNDEF HAS_TCP_NOPUSH} -{$UNDEF HAS_TCP_CORK} -{$UNDEF HAS_TCP_KEEPIDLE} -{$UNDEF HAS_TCP_KEEPINTVL} -{$UNDEF HAS_SOCKET_NOSIGPIPE} -{$IFDEF BSD} - {$DEFINE HAS_TCP_NOPUSH} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE HAS_TCP_NOPUSH} -{$ENDIF} -{$IFDEF LINUX} - {$DEFINE HAS_TCP_CORK} - {$DEFINE HAS_TCP_KEEPIDLE} - {$DEFINE HAS_TCP_KEEPINTVL} -{$ENDIF} -{$IFDEF SOLARIS} - {$DEFINE HAS_TCP_CORK} -{$ENDIF} -{$IFDEF NETBSD} - {$DEFINE HAS_TCP_CORK} - {$DEFINE HAS_TCP_KEEPIDLE} - {$DEFINE HAS_TCP_KEEPINTVL} -{$ENDIF} -{$IFDEF USE_VCL_POSIX} - // TODO: which platforms actually have SO_NOSIGPIPE available? - {$DEFINE HAS_SOCKET_NOSIGPIPE} - {$IFDEF ANDROID} - {$UNDEF HAS_SOCKET_NOSIGPIPE} - {$ENDIF} - {$IFDEF LINUX} - {$UNDEF HAS_SOCKET_NOSIGPIPE} - {$ENDIF} -{$ENDIF} -{end Unix OS specific stuff} -{$IFDEF DEBUG} - {$UNDEF USE_INLINE} -{$ENDIF} - -// RLebeau 5/24/2015: In C++Builder 2006 and 2007, UInt64 is emitted as -// signed __int64 in HPP files instead of as unsigned __int64. This causes -// conflicts in overloaded routines that have (U)Int64 parameters. This -// was fixed in C++Builder 2009. For compilers that do not have a native -// UInt64 type, or for C++Builder 2006/2007, let's define a record type -// that can hold UInt64 values... -{$IFDEF HAS_UInt64} - {$IFDEF BROKEN_UINT64_HPPEMIT} - {$DEFINE TIdUInt64_HAS_QuadPart} - {$ENDIF} -{$ELSE} - {$IFNDEF HAS_QWord} - {$DEFINE TIdUInt64_HAS_QuadPart} - {$ENDIF} -{$ENDIF} - -// RLebeau 9/5/2013: it would take a lot of work to re-write Indy to support -// both 0-based and 1-based string indexing, so we'll just turn off 0-based -// indexing for now... -{$IFDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} - {$ZEROBASEDSTRINGS OFF} -{$ENDIF} +{$IFDEF CONDITIONALEXPRESSIONS} + // Must be at the top... + {$IF CompilerVersion >= 24.0} + {$LEGACYIFEND ON} + {$IFEND} +{$ENDIF} + +// General + +// Make this $DEFINE to use the 16 color icons required by Borland +// or DEFINE to use the 256 color Indy versions +{.$DEFINE Borland} + +// S.G. 4/9/2002: IPv4/IPv6 general switch (for defaults only) +{$DEFINE IdIPv4} // use IPv4 by default +{.$IFDEF IdIPv6} // use IPv6 by default + +{$DEFINE INDY100} +{$DEFINE 10_7_0} //so developers can IFDEF for this product version +{$DEFINE 10_7_0_0} //so developers can IFDEF for this specific version + +// When generating C++Builder output files, certain workarounds to compiler +// problems need to be enabled! When invoking DCC on the command-line, use +// the -DBCB parameter. When invoking MSBUILD, include the DCC_Define="BCB" +// attribute in the /p parameter. +{$IFDEF BCB} + {$DEFINE CBUILDER} +{$ELSE} + {$DEFINE DELPHI} +{$ENDIF} + +{$UNDEF USE_OPENSSL} +{$UNDEF STATICLOAD_OPENSSL} + +{$UNDEF USE_ZLIB_UNIT} +{$UNDEF USE_SSPI} + +// $DEFINE the following if the global objects in the IdStack and IdThread +// units should be freed on finalization +{.$DEFINE FREE_ON_FINAL} +{$UNDEF FREE_ON_FINAL} + +// Make sure the following is $DEFINE'd only for suitable environments +// as specified further below. This works in conjunction with the +// FREE_ON_FINAL define above. +{$UNDEF REGISTER_EXPECTED_MEMORY_LEAK} +{$UNDEF HAS_System_RegisterExpectedMemoryLeak} + +// FastMM is natively available in BDS 2006 and higher. $DEFINE the +// following if FastMM has been installed manually in earlier versions +{.$DEFINE USE_FASTMM4} +{$UNDEF USE_FASTMM4} + +// $DEFINE the following if MadExcept has been installed manually in +// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced +// in BDS 2006) +{.$DEFINE USE_MADEXCEPT} +{$UNDEF USE_MADEXCEPT} + +// $DEFINE the following if LeakCheck has been installed manually in +// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced +// in BDS 2006) +{.$DEFINE USE_LEAKCHECK} +{$UNDEF USE_LEAKCHECK} + +// Make sure the following are $DEFINE'd only for Delphi/C++Builder 2009 onwards +// as specified further below. The VCL is fully Unicode, where the 'String' +// type maps to System.UnicodeString, not System.AnsiString anymore +{$UNDEF STRING_IS_UNICODE} +{$UNDEF STRING_IS_ANSI} +{$UNDEF STRING_UNICODE_MISMATCH} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. Delphi/C++Builder Mobile/NextGen compilers +// do not support Ansi data types anymore, and is moving away from raw +// pointers as well. +// +// UPDATE: in Delphi/C++Builder 10.4, all Ansi types are supported again on +// all platforms, including the mobile compilers. +{$DEFINE HAS_AnsiString} +{$DEFINE HAS_AnsiChar} +{$DEFINE HAS_PAnsiChar} +{$UNDEF HAS_PPAnsiChar} +{$UNDEF NO_ANSI_TYPES} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. Delphi/C++Builder Mobile/NextGen compilers +// use ARC for TObject life time management. +// +// UPDATE: ARC for TObject lifetime management has been removed in +// Delphi/C++Builder 10.4 mobile compilers. All platforms now use a single +// unified memory management model! +{$UNDEF USE_MARSHALLED_PTRS} +{$UNDEF HAS_MarshaledAString} +{$UNDEF USE_OBJECT_ARC} + +// Make sure the following is $DEFINE'd only for suitable environments +// as specified further below. +{$UNDEF STRING_IS_IMMUTABLE} +{$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. +{$UNDEF HAS_TEncoding} +{$UNDEF HAS_TEncoding_GetEncoding_ByEncodingName} +{$UNDEF HAS_Exception_RaiseOuterException} +{$UNDEF HAS_System_ReturnAddress} +{$UNDEF HAS_TCharacter} +{$UNDEF HAS_TInterlocked} +{$UNDEF HAS_TNetEncoding} + +// Make sure that this is defined only for environments where we are using +// the iconv library to charactor conversions. +{.$UNDEF USE_ICONV} +{.$UNDEF USE_LCONVENC} + +//Define for Delphi cross-compiler targetting Posix +{$UNDEF USE_VCL_POSIX} +{$UNDEF HAS_ComponentPlatformsAttribute} +{$UNDEF HAS_ComponentPlatformsAttribute_Win32} +{$UNDEF HAS_ComponentPlatformsAttribute_Win64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSX32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator32} +{$UNDEF HAS_ComponentPlatformsAttribute_Android} +{$UNDEF HAS_ComponentPlatformsAttribute_Android32Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device32} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux64} +{$UNDEF HAS_ComponentPlatformsAttribute_WinNX32} +{$UNDEF HAS_ComponentPlatformsAttribute_WinIoT32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device64} +{$UNDEF HAS_ComponentPlatformsAttribute_WinARM} +{$UNDEF HAS_ComponentPlatformsAttribute_WinARM32} +{$UNDEF HAS_ComponentPlatformsAttribute_OSX64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux32Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux64Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Android64} +{$UNDEF HAS_ComponentPlatformsAttribute_Android64Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator64} +{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm32} +{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSXArm64} +{$UNDEF HAS_ComponentPlatformsAttribute_AllPlatforms} +{$UNDEF HAS_DIRECTIVE_WARN_DEFAULT} + +// Define for Delphi to auto-generate platform-appropriate '#pragma link' statements in HPP files +{$UNDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT} + +// detect compiler versions + +{$IFNDEF FPC} + + // TODO: to detect features in Delphi/C++Builder v6 and later, use CompilerVersion + // and RTLVersion constants instead of VERXXX defines. We still support v5, which + // does not have such constants. + + // Delphi 4 + {$IFDEF VER120} + {$DEFINE DCC} + {$DEFINE VCL_40} + {$DEFINE DELPHI_4} + {$ENDIF} + + // C++Builder 4 + {$IFDEF VER125} + {$DEFINE DCC} + {$DEFINE VCL_40} + {$DEFINE CBUILDER_4} + {$ENDIF} + + // Delphi & C++Builder 5 + {$IFDEF VER130} + {$DEFINE DCC} + {$DEFINE VCL_50} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_5} + {$ELSE} + {$DEFINE DELPHI_5} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 6 + {$IFDEF VER140} + {$DEFINE DCC} + {$DEFINE VCL_60} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_6} + {$ELSE} + {$DEFINE DELPHI_6} + {$ENDIF} + {$ENDIF} + + //Delphi 7 + {$IFDEF VER150} + {$DEFINE DCC} + {$DEFINE VCL_70} + {$DEFINE DELPHI_7} // there was no C++ Builder 7 + {$ENDIF} + + //Delphi 8 + {$IFDEF VER160} + {$DEFINE DCC} + {$DEFINE VCL_80} + {$DEFINE DELPHI_8} // there was no C++ Builder 8 + {$ENDIF} + + //Delphi 2005 + {$IFDEF VER170} + {$DEFINE DCC} + {$DEFINE VCL_2005} + {$DEFINE DELPHI_2005} // there was no C++Builder 2005 + {$ENDIF} + + // NOTE: CodeGear decided to make Highlander be a non-breaking release + // (no interface changes, thus fully backwards compatible without any + // end user code changes), so VER180 applies to both BDS 2006 and + // Highlander prior to the release of RAD Studio 2007. Use VER185 to + // identify Highlanger specifically. + + //Delphi & C++Builder 2006 + //Delphi & C++Builder 2007 (Highlander) + {$IFDEF VER180} + {$DEFINE DCC} + {$DEFINE VCL_2006} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2006} + {$ELSE} + {$DEFINE DELPHI_2006} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2007 (Highlander) + {$IFDEF VER185} + {$DEFINE DCC} + {$UNDEF VCL_2006} + {$DEFINE VCL_2007} + {$IFDEF CBUILDER} + {$UNDEF CBUILDER_2006} + {$DEFINE CBUILDER_2007} + {$ELSE} + {$UNDEF DELPHI_2006} + {$DEFINE DELPHI_2007} + {$ENDIF} + {$ENDIF} + + // BDS 2007 NET personality uses VER190 instead of 185. + //Delphi .NET 2007 + {$IFDEF VER190} + {$DEFINE DCC} + {$IFDEF CIL} + //Delphi 2007 + {$DEFINE VCL_2007} + {$DEFINE DELPHI_2007} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2009 (Tiburon) + {$IFDEF VER200} + {$DEFINE DCC} + {$DEFINE VCL_2009} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2009} + {$ELSE} + {$DEFINE DELPHI_2009} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2010 (Weaver) + {$IFDEF VER210} + {$DEFINE DCC} + {$DEFINE VCL_2010} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2010} + {$ELSE} + {$DEFINE DELPHI_2010} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder XE (Fulcrum) + {$IFDEF VER220} + //REMOVE DCC DEFINE after the next Fulcrum beta. + //It will be defined there. + {$IFNDEF DCC} + {$DEFINE DCC} + {$ENDIF} + {$DEFINE VCL_XE} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE} + {$ELSE} + {$DEFINE DELPHI_XE} + {$ENDIF} + {$ENDIF} + + // DCC is now defined by the Delphi compiler starting in XE2 + + //Delphi & CBuilder XE2 (Pulsar) + {$IFDEF VER230} + {$DEFINE VCL_XE2} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE2} + {$ELSE} + {$DEFINE DELPHI_XE2} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE3 (Waterdragon) + //Delphi & CBuilder XE3.5 (Quintessence - early betas only) + {$IFDEF VER240} + {$DEFINE VCL_XE3} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE3} + {$ELSE} + {$DEFINE DELPHI_XE3} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE4 (Quintessence) + {$IFDEF VER250} + {$UNDEF VCL_XE3} + {$DEFINE VCL_XE4} + {$IFDEF CBUILDER} + {$UNDEF CBUILDER_XE3} + {$DEFINE CBUILDER_XE4} + {$ELSE} + {$UNDEF DELPHI_XE3} + {$DEFINE DELPHI_XE4} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE5 (Zephyr) + {$IFDEF VER260} + {$DEFINE VCL_XE5} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE5} + {$ELSE} + {$DEFINE DELPHI_XE5} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder AppMethod + //AppMethod is just XE5 for mobile only, VCL is removed + {$IFDEF VER265} + {$DEFINE VCL_XE5} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE5} + {$ELSE} + {$DEFINE DELPHI_XE5} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE6 (Proteus) + {$IFDEF VER270} + {$DEFINE VCL_XE6} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE6} + {$ELSE} + {$DEFINE DELPHI_XE6} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE7 (Carpathia) + {$IFDEF VER280} + {$DEFINE VCL_XE7} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE7} + {$ELSE} + {$DEFINE DELPHI_XE7} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE8 (Elbrus) + {$IFDEF VER290} + {$DEFINE VCL_XE8} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE8} + {$ELSE} + {$DEFINE DELPHI_XE8} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.0 Seattle (Aitana) + {$IFDEF VER300} + {$DEFINE VCL_10_0} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_VCL_10_0} + {$ELSE} + {$DEFINE DELPHI_VCL_10_0} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.1 Berlin (BigBen) + {$IFDEF VER310} + {$DEFINE VCL_10_1} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_1} + {$ELSE} + {$DEFINE DELPHI_10_1} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.2 Tokyo (Godzilla) + {$IFDEF VER320} + {$DEFINE VCL_10_2} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_2} + {$ELSE} + {$DEFINE DELPHI_10_2} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.3 Rio (Carnival) + {$IFDEF VER330} + {$DEFINE VCL_10_3} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_3} + {$ELSE} + {$DEFINE DELPHI_10_3} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.4 Sydney (Denali) + {$IFDEF VER340} + {$DEFINE VCL_10_4} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_4} + {$ELSE} + {$DEFINE DELPHI_10_4} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 11.0 Alexandria (Olympus) + {$IFDEF VER350} + {$DEFINE VCL_11} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_11} + {$ELSE} + {$DEFINE DELPHI_11} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 12.0 Athens (Yukon) + {$IFDEF VER360} + {$DEFINE VCL_12} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_12} + {$ELSE} + {$DEFINE DELPHI_12} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 13.0+ (?) + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF CompilerVersion >= 37} + {$MESSAGE WARN 'Unknown compiler version detected! Assuming >= 13.x '} + {$DEFINE VCL_UNKNOWN_VERSION} + {$DEFINE VCL_13} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_13} + {$ELSE} + {$DEFINE DELPHI_13} + {$ENDIF} + {$IFEND} + {$ENDIF} + + // Kylix + // + //Important: Don't use CompilerVersion here as IF's are evaluated before + //IFDEF's and Kylix 1 does not have CompilerVersion defined at all. + {$IFDEF LINUX} + {$DEFINE UNIX} + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF (RTLVersion >= 14.0) and (RTLVersion <= 14.5) } + {$DEFINE KYLIX} + {$IF RTLVersion = 14.5} + {$DEFINE KYLIX_3} + {$ELSEIF RTLVersion >= 14.2} + {$DEFINE KYLIX_2} + {$ELSE} + {$DEFINE KYLIX_1} + {$IFEND} + {$IFEND} + {$ENDIF} + {$ENDIF} + +{$ENDIF} + +// Delphi.NET +// Covers D8+ +{$IFDEF CIL} + // Platform specific conditional. Used for platform specific code. + {$DEFINE DOTNET} + {$DEFINE STRING_IS_UNICODE} + {$DEFINE STRING_IS_IMMUTABLE} + {.$DEFINE HAS_Int8} + {.$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_UInt64} +{$ENDIF} + +{$IFDEF KYLIX} + {$DEFINE VCL_60} + {$DEFINE INT_THREAD_PRIORITY} + {$DEFINE CPUI386} + {$UNDEF USE_BASEUNIX} + + {$IFDEF KYLIX_3} + {$DEFINE KYLIX_3_OR_ABOVE} + {$ENDIF} + + {$IFDEF KYLIX_3_OR_ABOVE} + {$DEFINE KYLIX_2_OR_ABOVE} + {$ELSE} + {$IFDEF KYLIX_2} + {$DEFINE KYLIX_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF KYLIX_2_OR_ABOVE} + {$DEFINE KYLIX_1_OR_ABOVE} + {$ELSE} + {$IFDEF KYLIX_1} + {$DEFINE KYLIX_1_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFNDEF KYLIX_3_OR_ABOVE} + {$DEFINE KYLIXCOMPAT} + {$ENDIF} + + {$IFDEF KYLIX_2_OR_ABOVE} + {$DEFINE USE_ZLIB_UNIT} + {$ENDIF} +{$ENDIF} + +// FPC (2+) + +{$IFDEF FPC} + // TODO: In FreePascal 4.2.0+, a Delphi-like UnicodeString type is supported. + // However, String/(P)Char do not map to UnicodeString/(P)WideChar unless + // either {$MODE DelphiUnicode} or {$MODESWITCH UnicodeStrings} is used. + // We should consider enabling one of them so Indy uses the same Unicode logic + // in Delphi 2009+ and FreePascal 4.2.0+ and reduces IFDEFs (in particular, + // STRING_UNICODE_MISMATCH, see further below). However, FreePascal's RTL + // is largely not UnicodeString-enabled yet. Maybe we should enable + // {$MODE DelphiUnicode} anyway, and then deal with any RTL function issues + // on an as-needed basis... + {$MODE Delphi} + //note that we may need further defines for widget types depending on + //what we do and what platforms we support in FPC. + //I'll let Marco think about that one. + {$IFDEF UNIX} + {$DEFINE USE_BASEUNIX} + {$IFDEF LINUX} + //In Linux for I386, you can choose between a Kylix-libc API or + //the standard RTL Unix API. Just pass -dKYLIXCOMPAT to the FPC compiler. + //I will see what I can do about the Makefile. + {$IFDEF KYLIXCOMPAT} + {$IFDEF CPUI386} + {$UNDEF USE_BASEUNIX} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$IFDEF USE_BASEUNIX} + {$UNDEF KYLIXCOMPAT} + {$ENDIF} + {$ENDIF} + + // FPC_FULLVERSION was added in FPC 2.2.4 + // Have to use Defined() or else Delphi compiler chokes, since it + // evaluates $IF statements before $IFDEF statements... + + {$MACRO ON} // must be on in order to use versioning macros + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30101)} + {$DEFINE FPC_3_1_1_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30000)} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20701)} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20604)} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20602)} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20600)} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20404)} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20402)} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20400)} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20204)} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20202)} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20105)} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$IFEND} + + // just in case + {$IFDEF FPC_3_1_1} + {$DEFINE FPC_3_1_1_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_3_0_0} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_7_1} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_4} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_2} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_0} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_4} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_2} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_0} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_2_4} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_2_2} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_1_5} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ENDIF} + + {$IFDEF FPC_3_1_1_OR_ABOVE} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_3_0_0} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_3_0_0_OR_ABOVE} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_7_1} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_7_1_OR_ABOVE} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_4} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_4_OR_ABOVE} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_2} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_0} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_0_OR_ABOVE} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_4} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_4_OR_ABOVE} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_2} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_2_OR_ABOVE} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_0} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_0_OR_ABOVE} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_2_4} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_4_OR_ABOVE} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_2_2} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_2_OR_ABOVE} + {$DEFINE FPC_2_2_0_OR_ABOVE} + {$ELSE} + {$IFDEF VER2_2} + {$DEFINE FPC_2_2_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_0_OR_ABOVE} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_1_5} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {.$IFDEF FPC_2_7_1_OR_ABOVE} + // support for RawByteString and UnicodeString + {.$MODE DelphiUnicode} + {.$MODESWITCH UnicodeStrings} + {.$CODEPAGE UTF8} // needed for Unicode string literals to work properly + {.$DEFINE VCL_2009} + {.$DEFINE DELPHI_2009} + {.$ELSE} + {$DEFINE VCL_70} + {$DEFINE DELPHI_7} + {.$ENDIF} +{$ENDIF} + +// end FPC + +{$IFDEF VCL_13} + {$DEFINE VCL_13_OR_ABOVE} +{$ENDIF} + +{$IFDEF VCL_13_OR_ABOVE} + {$DEFINE VCL_12_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_12} + {$DEFINE VCL_12_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_12_OR_ABOVE} + {$DEFINE VCL_11_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_11} + {$DEFINE VCL_11_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_11_OR_ABOVE} + {$DEFINE VCL_10_4_OR_ABOVE} + {$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_4} + {$DEFINE VCL_10_4_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_4_OR_ABOVE} + {$DEFINE VCL_10_3_OR_ABOVE} + {$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_3} + {$DEFINE VCL_10_3_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_OR_ABOVE} + {$DEFINE VCL_10_2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_2} + {$DEFINE VCL_10_2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_2_OR_ABOVE} + {$DEFINE VCL_10_1_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_1} + {$DEFINE VCL_10_1_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_1_OR_ABOVE} + {$DEFINE VCL_10_0_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_0} + {$DEFINE VCL_10_0_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_0_OR_ABOVE} + {$DEFINE VCL_XE8_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE8} + {$DEFINE VCL_XE8_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE VCL_XE7_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE7} + {$DEFINE VCL_XE7_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE7_OR_ABOVE} + {$DEFINE VCL_XE6_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE6} + {$DEFINE VCL_XE6_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE6_OR_ABOVE} + {$DEFINE VCL_XE5_OR_ABOVE} + {$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE5} + {$DEFINE VCL_XE5_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE5_OR_ABOVE} + {$DEFINE VCL_XE4_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE4} + {$DEFINE VCL_XE4_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE4_OR_ABOVE} + {$DEFINE VCL_XE3_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE3} + {$DEFINE VCL_XE3_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE3_OR_ABOVE} + {$DEFINE VCL_XE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE2} + {$DEFINE VCL_XE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE2_OR_ABOVE} + {$DEFINE VCL_XE_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE} + {$DEFINE VCL_XE_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE_OR_ABOVE} + {$DEFINE VCL_2010_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2010} + {$DEFINE VCL_2010_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2010_OR_ABOVE} + {$DEFINE VCL_2009_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2009} + {$DEFINE VCL_2009_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2009_OR_ABOVE} + {$DEFINE VCL_2007_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2007} + {$DEFINE VCL_2007_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2007_OR_ABOVE} + {$DEFINE VCL_2006_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2006} + {$DEFINE VCL_2006_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2006_OR_ABOVE} + {$DEFINE VCL_2005_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2005} + {$DEFINE VCL_2005_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2005_OR_ABOVE} + {$DEFINE VCL_8_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_80} + {$DEFINE VCL_8_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_8_OR_ABOVE} + {$DEFINE VCL_7_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_70} + {$DEFINE VCL_7_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_7_OR_ABOVE} + {$DEFINE VCL_6_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_60} + {$DEFINE VCL_6_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_6_OR_ABOVE} + {$DEFINE VCL_5_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_50} + {$DEFINE VCL_5_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_5_OR_ABOVE} + {$DEFINE VCL_4_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_40} + {$DEFINE VCL_4_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +// Normalize Delphi compiler defines to match FPC for consistency: +// +// CPU32 - any 32-bit CPU +// CPU64 - any 64-bit CPU +// WINDOWS - any Windows platform (32-bit, 64-bit, CE) +// WIN32 - Windows 32-bit +// WIN64 - Windows 64-bit +// WINCE - Windows CE +// +// Consult the "Free Pascal Programmer's Guide", Appendix G for the complete +// list of defines that are used. Do not work on this unless you understand +// what the FreePascal developers are doing. Not only do you have to +// descriminate with operating systems, but also with chip architectures +// are well. +// +// DCC Pulsar+ define the following values: +// ASSEMBLER +// DCC +// CONDITIONALEXPRESSIONS +// NATIVECODE +// UNICODE +// MACOS +// MACOS32 +// MACOS64 +// MSWINDOWS +// WIN32 +// WIN64 +// LINUX +// POSIX +// POSIX32 +// CPU386 +// CPUX86 +// CPUX64 +// +// Kylix defines the following values: +// LINUX +// (others??) +// + +{$IFNDEF FPC} + // TODO: We need to use ENDIAN_BIG for big endian chip architectures, + // such as 680x0, PowerPC, Sparc, and MIPS, once DCC supports them, + // provided it does not already define its own ENDIAN values by then... + {$DEFINE ENDIAN_LITTLE} + {$IFNDEF VCL_6_OR_ABOVE} + {$DEFINE MSWINDOWS} + {$ENDIF} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} + // TODO: map Pulsar's non-Windows platform defines... + {$IFDEF VCL_XE2_OR_ABOVE} + {$IFDEF VCL_XE8_OR_ABOVE} + {$IFDEF CPU32BITS} + //any 32-bit CPU + {$DEFINE CPU32} + {$ENDIF} + {$IFDEF CPU64BITS} + {$DEFINE CPU64} + {$ENDIF} + {$ELSE} + {$IFDEF CPU386} + //any 32-bit CPU + {$DEFINE CPU32} + //Intel 386 compatible chip architecture + {$DEFINE CPUI386} + {$ENDIF} + {$IFDEF CPUX86} + {$DEFINE CPU32} + {$ENDIF} + {$IFDEF CPUX64} + //any 64-bit CPU + {$DEFINE CPU64} + //AMD64 compatible chip architecture + {$DEFINE CPUX86_64} //historical name for AMD64 + {$DEFINE CPUAMD64} + {$ENDIF} + {$ENDIF} + {$ELSE} + {$IFNDEF DOTNET} + {$IFNDEF KYLIX} + {$DEFINE I386} + {$ENDIF} + {$ENDIF} + {$DEFINE CPU32} + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + //differences in DotNET Framework versions. + {$IFDEF VCL_2007_OR_ABOVE} + {$DEFINE DOTNET_2} + {$DEFINE DOTNET_2_OR_ABOVE} + {$ELSE} + {$DEFINE DOTNET_1_1} + {$ENDIF} + {$DEFINE DOTNET_1_1_OR_ABOVE} + // Extra include used in D7 for testing. Remove later when all comps are + // ported. Used to selectively exclude non ported parts. Allowed in places + // IFDEFs are otherwise not permitted. + {$DEFINE DOTNET_EXCLUDE} +{$ENDIF} + +// Check for available features + +{$IFDEF CBUILDER} + // When generating a C++ HPP file, if a class has no explicit constructor + // defined and contains compiler-managed members (xxxString, TDateTime, + // Variant, DelphiInterface, etc), the HPP will contain a forwarding + // inline constructor that implicitly initializes those managed members, + // which will overwrite any non-default initializations performed inside + // of InitComponent() overrides! In this situation, the workaround is to + // define an explicit constructor that calls the base class constructor + // manually, allowing those managed members to be initialized by the + // compiler before InitComponent() overrides then re-assign them. + {$DEFINE WORKAROUND_INLINE_CONSTRUCTORS} +{$ENDIF} + +{$IFDEF VCL_5_OR_ABOVE} + {$IFNDEF FPC} + {$IFNDEF KYLIX} + {$DEFINE HAS_RemoveFreeNotification} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_GetObjectProp} + {$DEFINE HAS_TObjectList} + {$DEFINE HAS_StrToInt64Def} +{$ENDIF} + +{$IFDEF VCL_6_OR_ABOVE} + {$DEFINE HAS_PCardinal} + {$DEFINE HAS_PByte} + {$DEFINE HAS_PWord} + {$DEFINE HAS_PPointer} + {$DEFINE HAS_TList_Assign} + {$DEFINE HAS_sLineBreak} + {$DEFINE HAS_RaiseLastOSError} + {$DEFINE HAS_SysUtils_IncludeExcludeTrailingPathDelimiter} + {$DEFINE HAS_SysUtils_DirectoryExists} + {$DEFINE HAS_UNIT_DateUtils} + {$DEFINE HAS_UNIT_StrUtils} + {$DEFINE HAS_UNIT_Types} + {$DEFINE HAS_TryStrToInt} + {$DEFINE HAS_TryStrToInt64} + {$DEFINE HAS_TryEncodeDate} + {$DEFINE HAS_TryEncodeTime} + {$DEFINE HAS_ENUM_ELEMENT_VALUES} + {$IFNDEF FPC} + {$DEFINE HAS_IInterface} + {$DEFINE HAS_TSelectionEditor} + {$DEFINE HAS_TStringList_CaseSensitive} + {$DEFINE HAS_AcquireExceptionObject} + {$IFNDEF KYLIX} + {$DEFINE HAS_DEPRECATED} + {$DEFINE HAS_SYMBOL_PLATFORM} + {$DEFINE HAS_UNIT_PLATFORM} + {$IFNDEF VCL_8_OR_ABOVE} + // Delphi 6 and 7 have an annoying bug that if a class method is declared as + // deprecated, the compiler will emit a "symbol is deprecated" warning + // on the method's implementation! So we will have to wrap implementations + // of deprecated methods with {$WARN SYMBOL_DEPRECATED OFF} directives + // to disable that warning. + {$DEFINE DEPRECATED_IMPL_BUG} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$IFNDEF DOTNET} + //Widget defines are omitted in .NET + {$DEFINE VCL_60_PLUS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_7_OR_ABOVE} + {$IFNDEF FPC} + {$DEFINE HAS_UInt64} // Note: it was just an alias for Int64 until D2006! + {$DEFINE HAS_NAMED_THREADS} + {$DEFINE HAS_TStrings_NameValueSeparator} + {$DEFINE HAS_TStrings_ValueFromIndex} + // Note: there is a ZLib unit available, but it doesn't have everything + // that is available in the System.ZLib unit in Delphi XE2+, so we are + // not going to use this ZLib unit yet... + {.$DEFINE HAS_UNIT_ZLib} + {$ENDIF} + {$DEFINE HAS_TFormatSettings} + {$DEFINE HAS_PosEx} + {$IFNDEF VCL_70} + // not implemented in D7 + {$DEFINE HAS_STATIC_TThread_Queue} + {$ENDIF} + {$IFNDEF CIL} + {$IFNDEF VCL_80} + // not implemented in D8 or .NET + {$DEFINE HAS_STATIC_TThread_Synchronize} + {$ENDIF} + {$ENDIF} +{$ELSE} + {$IFDEF CBUILDER_6} + {$DEFINE HAS_NAMED_THREADS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2005_OR_ABOVE} + {$IFDEF DCC} + // class helpers were first introduced in D2005, but were buggy and not + // officially supported until D2006... + {.$DEFINE HAS_CLASS_HELPER} + {$ENDIF} +{$ELSE} + {$IFDEF DCC} + // InterlockedCompareExchange() was declared in the Windows unit using Pointer + // parameters until Delphi 2005, when it was switched to Longint parameters + // instead to match the actual Win32 API declaration. + {$DEFINE HAS_InterlockedCompareExchange_Pointers} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2006_OR_ABOVE} + {$DEFINE USE_INLINE} + {$DEFINE HAS_2PARAM_FileAge} + {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? + {$DEFINE HAS_CLASS_HELPER} + {$IFDEF WINDOWS} + // System.RegisterExpectedMemoryLeak() is only available on Windows at this time + {$DEFINE HAS_System_RegisterExpectedMemoryLeak} + {$ENDIF} + // In C++Builder 2006 and 2007, UInt64 is emitted as signed __int64 in HPP + // files instead of as unsigned __int64. This causes conflicts in overloaded + // routines that have (U)Int64 parameters. This was fixed in C++Builder 2009... + {$IFDEF CBUILDER} + {$DEFINE BROKEN_UINT64_HPPEMIT} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2007_OR_ABOVE} + {$IFNDEF CBUILDER_2007} + // class properties are broken in C++Builder 2007, causing AVs at compile-time + {$DEFINE HAS_CLASSPROPERTIES} + {$ENDIF} + // Native(U)Int exist but are buggy, so do not use them yet + {.$DEFINE HAS_NativeInt} + {.$DEFINE HAS_NativeUInt} + {$DEFINE HAS_DWORD_PTR} + {$DEFINE HAS_ULONG_PTR} + {$DEFINE HAS_ULONGLONG} + {$DEFINE HAS_PGUID} + {$DEFINE HAS_PPAnsiChar} + {$DEFINE HAS_CurrentYear} + {$IFNDEF DOTNET} + {$DEFINE HAS_TIMEUNITS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2009_OR_ABOVE} + {$IFNDEF DOTNET} + {$DEFINE STRING_IS_UNICODE} + {$DEFINE HAS_UnicodeString} + {$DEFINE HAS_TEncoding} + {$DEFINE HAS_TCharacter} + {$DEFINE HAS_InterlockedCompareExchangePointer} + {$DEFINE HAS_WIDE_TCharArray} + {$DEFINE HAS_PUInt64} + {$IFDEF VCL_2009} + // TODO: need to differentiate between RTM and Update 1 + // FmtStr() is broken in RTM but was fixed in Update 1 + {$DEFINE BROKEN_FmtStr} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_CLASSVARS} + {$DEFINE HAS_DEPRECATED_MSG} + {$DEFINE HAS_TBytes} + // Native(U)Int are still buggy, so do not use them yet + {.$DEFINE HAS_NativeInt} + {.$DEFINE HAS_NativeUInt} + {$DEFINE HAS_Int8} + {$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_UIntToStr} + // UInt64 is now emitted as unsigned __int64 in HPP files + {$IFDEF CBUILDER} + {$UNDEF BROKEN_UINT64_HPPEMIT} + {$ENDIF} + {$IFDEF DCC} + {$IFDEF WINDOWS} + // Exception.RaiseOuterException() is only available on Windows at this time + {$DEFINE HAS_Exception_RaiseOuterException} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_SetCodePage} + {$DEFINE HAS_PRawByteString} + {$DEFINE HAS_TThreadProcedure} +{$ENDIF} + +{$IFDEF VCL_2010_OR_ABOVE} + {$DEFINE HAS_CLASSCONSTRUCTOR} + {$DEFINE HAS_CLASSDESTRUCTOR} + {$DEFINE HAS_DELAYLOAD} + {$DEFINE HAS_TThread_NameThreadForDebugging} + {$DEFINE DEPRECATED_TThread_SuspendResume} + // Native(U)Int are finally ok to use now + {$DEFINE HAS_NativeInt} + {$DEFINE HAS_NativeUInt} + {$DEFINE HAS_USHORT} + {$DEFINE HAS_IOUtils_TPath} +{$ENDIF} + +{$IFDEF VCL_XE_OR_ABOVE} + {$DEFINE HAS_TFormatSettings_Object} + {$DEFINE HAS_LocaleCharsFromUnicode} + {$DEFINE HAS_UnicodeFromLocaleChars} + {$DEFINE HAS_PLongBool} + {$DEFINE HAS_PVOID} + {$DEFINE HAS_ULONG64} + {$DEFINE HAS_TEncoding_GetEncoding_ByEncodingName} + {$DEFINE HAS_DateUtils_TTimeZone} + {$IFDEF DCC} + // Exception.RaiseOuterException() is now available on all platforms + {$DEFINE HAS_Exception_RaiseOuterException} + {$ENDIF} + {$IFNDEF DOTNET} + {$DEFINE HAS_TInterlocked} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE2_OR_ABOVE} + {$DEFINE HAS_SIZE_T} + {$DEFINE HAS_PSIZE_T} + {$DEFINE HAS_SSIZE_T} + {$DEFINE HAS_PSSIZE_T} + {$DEFINE HAS_LONG} + {$DEFINE HAS_ComponentPlatformsAttribute} + {$DEFINE HAS_ComponentPlatformsAttribute_Win32} + {$DEFINE HAS_ComponentPlatformsAttribute_Win64} + {$DEFINE HAS_ComponentPlatformsAttribute_OSX32} + {$DEFINE HAS_System_ReturnAddress} + {$DEFINE HAS_DIRECTIVE_WARN_DEFAULT} + {$DEFINE HAS_UNIT_System_ZLib} +{$ENDIF} + +{$IFDEF VCL_XE3_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_ZEROBASEDSTRINGS} + {$DEFINE HAS_SysUtils_TStringHelper} + {$IFDEF NEXTGEN} + {$DEFINE DCC_NEXTGEN} + {$DEFINE HAS_MarshaledAString} + {$DEFINE USE_MARSHALLED_PTRS} + {$IFDEF AUTOREFCOUNT} + {$DEFINE USE_OBJECT_ARC} + {$ENDIF} + {$ENDIF} + // technically, these are present in XE3, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} + {.$DEFINE HAS_ComponentPlatformsAttribute_Android} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32} + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} + {.$DEFINE HAS_ComponentPlatformsAttribute_WinNX32} +{$ENDIF} + +{$IFDEF VCL_XE4_OR_ABOVE} + {$DEFINE HAS_AnsiStrings_StrPLCopy} + {$DEFINE HAS_AnsiStrings_StrLen} + {$DEFINE HAS_Character_TCharHelper} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} +{$ENDIF} + +{$IFDEF VCL_XE5_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_Android} +{$ENDIF} + +{$IFDEF VCL_XE5_UPDATE2_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_LINKUNIT} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_NAMESPACE} +{$ENDIF} + +{$IFDEF VCL_XE7_OR_ABOVE} + {$DEFINE HAS_TNetEncoding} +{$ENDIF} + +{$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device32} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device64} + // technically, these are present in XE8, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64} + {.$DEFINE HAS_ComponentPlatformsAttribute_WinIoT32} +{$ENDIF} + +{$IFDEF VCL_10_0_OR_ABOVE} + {$IFDEF ANDROID} + {$DEFINE HAS_TAndroidHelper} + {$ENDIF} + // technically, these are present in 10.0 Seattle, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_WinARM} +{$ENDIF} + +{$IFDEF VCL_10_1_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_LEGACYHPP} + {$DEFINE HAS_TStrings_AddPair} + // technically, these are present in 10.1 Berlin, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_OSX64} + {.$DEFINE HAS_ComponentPlatformsAttribute_OSXNX64} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32Arm} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64Arm} + {.$DEFINE HAS_ComponentPlatformsAttribute_Android64} +{$ENDIF} + +{$IFDEF VCL_10_2_OR_ABOVE} + {.$WARN IMPLICIT_INTEGER_CAST_LOSS OFF} + {.$WARN IMPLICIT_CONVERSION_LOSS OFF} + {.$WARN COMBINING_SIGNED_UNSIGNED64 OFF} + {$DEFINE HAS_STATIC_TThread_ForceQueue} + // In Delphi 10.2 Tokyo, TThread.ForceQueue() is broken on Android, the + // passed in procedure is called immediately instead of being delayed! + {$IFDEF ANDROID} + {$DEFINE BROKEN_TThread_ForceQueue} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator32} + {$DEFINE HAS_ComponentPlatformsAttribute_Android32Arm} + {$DEFINE HAS_ComponentPlatformsAttribute_WinARM32} + {$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} // removed in 10.3 Rio + // technically, these are present in 10.3 Rio, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator64} + {$IFDEF DCC} + {$IFDEF LINUX} + // RLebeau 9/25/2019: there is a bug in the IDE when debugging Linux projects + // where the EThreadNameException exception raised by TThread.NameThreadForDebugging() + // is not handled correctly. + {$UNDEF HAS_NAMED_THREADS} + {$ENDIF} + {$ENDIF} + {$IFDEF ANDROID} + {$UNDEF BROKEN_TThread_ForceQueue} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_UPDATE2_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_AllPlatforms} + {$DEFINE HAS_ComponentPlatformsAttribute_OSX64} +{$ENDIF} + +{$IFDEF VCL_10_4_OR_ABOVE} + // 0-based string indexing via '[]' is turned off by default in Delphi 10.4. + // TStringHelper is always 0-indexed, flat RTL functions are always 1-indexed, + // and now '[]' is 1-indexed again on all platforms - {$ZEROBASEDSTRINGS OFF} + // is the default. + {.$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} +{$ENDIF} + +{$IFDEF VCL_11_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm32} + {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm64} + {$DEFINE HAS_ComponentPlatformsAttribute_OSXArm64} +{$ENDIF} + +// Delphi XE+ cross-compiling +{$IFNDEF FPC} + {$IFDEF POSIX} + {$IF RTLVersion >= 22.0} + {$DEFINE UNIX} + {$UNDEF USE_BASEUNIX} + {$DEFINE VCL_CROSS_COMPILE} + {$DEFINE USE_VCL_POSIX} + {$IFEND} + {$ENDIF} + {$IFDEF LINUX} + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF RTLVersion >= 22.0} + {$DEFINE VCL_CROSS_COMPILE} + {$DEFINE USE_VCL_POSIX} + {$IFEND} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_CROSS_COMPILE} + {$UNDEF KYLIXCOMPAT} +{$ELSE} + {$IFDEF KYLIXCOMPAT} + {$linklib c} + {$ENDIF} +{$ENDIF} + +{$IFDEF FPC} + {$DEFINE USE_INLINE} + {$DEFINE USE_CLASSINLINE} + {$DEFINE USE_TBitBtn} //use Bit Buttons instead of Buttons + {$DEFINE FPC_REINTRODUCE_BUG} + {$DEFINE FPC_CIRCULAR_BUG} + {$DEFINE NO_REDECLARE} + {$DEFINE BYTE_COMPARE_SETS} + {$DEFINE HAS_QWord} // TODO: when was QWord introduced? + {$DEFINE HAS_PQWord} // TODO: when was PQWord introduced? + {$IFDEF FPC_2_1_5_OR_ABOVE} + {$DEFINE HAS_UInt64} + {.$DEFINE HAS_PUInt64} // TODO: is this defined? + {$ENDIF} + {$IFDEF FPC_2_2_0_OR_ABOVE} + {$DEFINE HAS_InterlockedCompareExchange_Pointers} + {$ENDIF} + {$IFDEF FPC_2_2_2_OR_ABOVE} + {$DEFINE HAS_SharedSuffix} + {$ENDIF} + {$IFDEF FPC_2_2_4_OR_ABOVE} + // these types are only available on Unix systems (FreeBSD, Linux, etc) + {$IFDEF UNIX} + {$DEFINE HAS_UNIT_UnixType} + {$DEFINE HAS_SIZE_T} + {$DEFINE HAS_PSIZE_T} + {$DEFINE HAS_SSIZE_T} + {$DEFINE HAS_PSSIZE_T} + {$DEFINE HAS_TIME_T} + {$DEFINE HAS_PTIME_T} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_PtrInt} + {$DEFINE HAS_PtrUInt} + {$DEFINE HAS_PGUID} + {$DEFINE HAS_LPGUID} + {$DEFINE HAS_PPAnsiChar} + {$DEFINE HAS_ENUM_ELEMENT_VALUES} + {$DEFINE HAS_AcquireExceptionObject} // TODO: when was AcquireExceptionObject introduced? + {$IFDEF WINDOWS} + {$DEFINE HAS_ULONG_PTR} + {.$DEFINE HAS_ULONGLONG} // TODO: is this defined? + {$ENDIF} + {$DEFINE HAS_UNIT_ctypes} + {$DEFINE HAS_sLineBreak} + {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? + {$IFDEF FPC_HAS_UNICODESTRING} + {$DEFINE HAS_UnicodeString} + {$ELSE} + {$IFDEF FPC_2_4_0_OR_ABOVE} + {$DEFINE HAS_UnicodeString} + {$ENDIF} + {$ENDIF} + {$IFDEF FPC_2_4_4_OR_ABOVE} + {$DEFINE DEPRECATED_TThread_SuspendResume} + {$DEFINE HAS_DEPRECATED} // TODO: when was deprecated introduced? Possibly 1.9.x + {$DEFINE HAS_DEPRECATED_MSG} // TODO: when was message support added? Possibly 2.4.x + {$DEFINE HAS_STATIC_TThread_Synchronize} + {$IFNDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE USE_SEMICOLON_BEFORE_DEPRECATED} // TODO: which earlier versions require a semicolon? + {$ENDIF} + {$ENDIF} + {$IFDEF FPC_2_6_0_OR_ABOVE} + {$DEFINE HAS_NativeInt} + {$DEFINE HAS_NativeUInt} + {$DEFINE HAS_CLASS_HELPER} + {$ENDIF} + {$IFDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE HAS_Int8} + {$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_GetLocalTimeOffset} + {$DEFINE HAS_UniversalTimeToLocal} + {$DEFINE HAS_LocalTimeToUniversal} + {$ENDIF} + {$IFDEF FPC_2_6_4_OR_ABOVE} + {$DEFINE HAS_PInt8} + {$DEFINE HAS_PUInt8} + {$DEFINE HAS_PInt16} + {$DEFINE HAS_PUInt16} + {$DEFINE HAS_PInt32} + {$DEFINE HAS_PUInt32} + {$ENDIF} + {$IFDEF FPC_3_0_0_OR_ABOVE} + {$DEFINE HAS_STATIC_TThread_Queue} + {$DEFINE HAS_SetCodePage} + {$ENDIF} + {$IFDEF FPC_UNICODESTRINGS} + {$DEFINE STRING_IS_UNICODE} + {$ENDIF} + {$IFDEF FPC_3_1_1_OR_ABOVE} + {$DEFINE HAS_STATIC_TThread_ForceQueue} // requires rev 37359+ + {$DEFINE HAS_PRawByteString} + {$DEFINE HAS_UIntToStr} // requires rev 40529+ + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + {$DEFINE WIDGET_WINFORMS} +{$ELSE} + {$DEFINE WIDGET_VCL_LIKE} // LCL included. + {$DEFINE WIDGET_VCL_LIKE_OR_KYLIX} + {$IFDEF FPC} + {$DEFINE WIDGET_LCL} + {$ELSE} + {$IFDEF KYLIX} + {$DEFINE WIDGET_KYLIX} + {$ELSE} + {$DEFINE WIDGET_VCL} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +// .NET and Delphi 2009+ support UNICODE strings natively! +// +// FreePascal 2.4.0+ supports UnicodeString, but does not map its +// native String type to UnicodeString except when {$MODE DelphiUnicode} +// or {$MODESWITCH UnicodeStrings} is enabled. However, UNICODE is not +// defined in that mode yet until its RTL has been updated to support +// UnicodeString. STRING_UNICODE_MISMATCH is defined when the native +// String/Char types do not map to the same types that APIs are expecting +// based on whether UNICODE is defined or not. +// +// NOTE: Do not define UNICODE here. The compiler defines +// the symbol automatically. +{$IFDEF STRING_IS_UNICODE} + {$IFNDEF UNICODE} + {$DEFINE STRING_UNICODE_MISMATCH} + {$ENDIF} +{$ELSE} + {$DEFINE STRING_IS_ANSI} + {$IFDEF UNICODE} + {$DEFINE STRING_UNICODE_MISMATCH} + {$ENDIF} +{$ENDIF} + +{$IFDEF DCC_NEXTGEN} + {$DEFINE NO_ANSI_TYPES} + {.$DEFINE STRING_IS_IMMUTABLE} // Strings are NOT immutable in NEXTGEN yet + {$IFDEF USE_OBJECT_ARC} + // TODO: move these to an appropriate section. Not doing this yet because + // it is a major interface change to switch to Generics and we should + // maintain backwards compatibility with earlier compilers for the time + // being. Defining them only here for now because the non-Generic versions + // of these classes have become deprecated by ARC and so we need to start + // taking advantage of the Generics versions... + {$DEFINE HAS_UNIT_Generics_Collections} + {$DEFINE HAS_UNIT_Generics_Defaults} + {$DEFINE HAS_GENERICS_TDictionary} + {$DEFINE HAS_GENERICS_TList} + {$DEFINE HAS_GENERICS_TObjectList} + {$DEFINE HAS_GENERICS_TThreadList} + // TArray.Copy() was introduced in XE7 but was buggy. It was fixed in XE8: + // + // RSP-9763 TArray.Copy copies from destination to source for unmanaged types + // https://quality.embarcadero.com/browse/RSP-9763 + // + {$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE HAS_GENERICS_TArray_Copy} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +// TODO: Ansi data types were disabled on mobile platforms in XE3, but +// UTF8String and RawByteString were re-enabled in 10.1 Berlin! What else, +// if anything, was re-enabled to facilitate that? +// +// UPDATE: In 10.4 Sydney, AnsiChar and AnsiString were re-enabled on +// mobile platforms! NEXTGEN is no longer defined in the mobile compilers. +{$IFDEF NO_ANSI_TYPES} + {$UNDEF HAS_AnsiString} + {$UNDEF HAS_AnsiChar} + {$UNDEF HAS_PAnsiChar} + {$UNDEF HAS_PPAnsiChar} + {$UNDEF HAS_AnsiStrings_StrPLCopy} + {$UNDEF HAS_AnsiStrings_StrLen} +{$ENDIF} + +{$IFDEF WIN32} + {$DEFINE WIN32_OR_WIN64} +{$ENDIF} +{$IFDEF WIN64} + {$DEFINE WIN32_OR_WIN64} +{$ENDIF} + +{$IFDEF WIN32_OR_WIN64} + {$DEFINE USE_ZLIB_UNIT} + {$IFNDEF DCC_NEXTGEN} + {$DEFINE USE_OPENSSL} // !!! MOVED HERE BY EMBT + {$DEFINE USE_SSPI} + {$IFDEF STRING_IS_UNICODE} + {$DEFINE SSPI_UNICODE} + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF WINCE} + {$DEFINE USE_OPENSSL} + // RLebeau: not sure if the above Win32/64 defines also apply to WinCE, + // so keeping them separate for now... +{$ENDIF} + +// High-performance counters are not reliable on multi-core systems, and have +// been known to cause problems with TIdIOHandler.ReadLn() timeouts in Windows +// XP SP3, both 32-bit and 64-bit. Refer to these discussions for more info: +// +// http://www.virtualdub.org/blog/pivot/entry.php?id=106 +// http://blogs.msdn.com/oldnewthing/archive/2008/09/08/8931563.aspx +// +// Do not enable thus unless you know it will work correctly on your systems! +{$IFDEF WINDOWS} + {.$DEFINE USE_HI_PERF_COUNTER_FOR_TICKS} +{$ENDIF} + +{$IFDEF UNIX} + {$DEFINE USE_OPENSSL} + {$DEFINE USE_ZLIB_UNIT} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF MACOS} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF DARWIN} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF LINUX} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF IOS} + {$DEFINE HAS_getifaddrs} + {$DEFINE USE_OPENSSL} + + // Support for 64-bit ARM iOS Simulator was added in Delphi 11.2 + // TODO: how to detect iOS Simulator in FPC? Does it support 64-bit ARM? + {$IFDEF CPUARM} + {$IFNDEF IOSSIMULATOR} + // RLebeau: For iOS devices, OpenSSL cannot be used as an external library, + // it must be statically linked into the app. For the iOS simulator, this + // is not true. Users who want to use OpenSSL in iOS device apps will need + // to add the static OpenSSL library to the project and then include the + // IdSSLOpenSSLHeaders_static unit in their uses clause. It hooks up the + // statically linked functions for the IdSSLOpenSSLHeaders unit to use... + {$DEFINE STATICLOAD_OPENSSL} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF FREEBSD} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF ANDROID} + {$UNDEF HAS_getifaddrs} +{$ENDIF} + +{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} + {$DEFINE REQUIRES_PROPER_ALIGNMENT} +{$ENDIF} + +// +//iconv defines section. +{$DEFINE USE_ICONV_UNIT} +{$DEFINE USE_ICONV_ENC} +{$IFDEF UNIX} + {$DEFINE USE_ICONV} + {$IFDEF USE_BASEUNIX} + {$IFDEF FPC} + {$UNDEF USE_ICONV_UNIT} + {$ELSE} + {$UNDEF USE_ICONV_ENC} + {$ENDIF} + {$ENDIF} + {$IFDEF KYLIXCOMPAT} + //important!! Iconv functions are defined in the libc.pas Kylix compatible unit. + {$UNDEF USE_ICONV_ENC} + {$UNDEF USE_ICONV_UNIT} + {$ENDIF} +{$ENDIF} +{$IFDEF NETWARELIBC} + {$DEFINE USE_ICONV} + //important!!! iconv functions are defined in the libc.pas Novell Netware header. + //Do not define USE_ICONV_UNIT + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} +{$ENDIF} + +{$UNDEF USE_SAFELOADLIBRARY} +{$IFDEF WINDOWS} + {$UNDEF USE_ICONV_ENC} + {$DEFINE USE_SAFELOADLIBRARY} +{$ENDIF} +// Use here for all *nix systems that you do not want to use iconv library +{$IFDEF FPC} + {$IFDEF ANDROID} + {$UNDEF USE_ICONV} + {$DEFINE USE_LCONVENC} + {$ENDIF} +{$ENDIF} + +{$UNDEF USE_INVALIDATE_MOD_CACHE} +{$UNDEF USE_SAFELOADLIBRARY} +//This must come after the iconv defines because this compiler targets a Unix-like +//operating system. One key difference is that it does have a TEncoding class. +//If this comes before the ICONV defines, it creates problems. +//This also must go before the THandle size calculations. +{$IFDEF VCL_CROSS_COMPILE} + {$IFDEF POSIX} + {$IFNDEF LINUX} + {$DEFINE BSD} + {$ENDIF} + {$DEFINE USE_SAFELOADLIBRARY} + {$DEFINE USE_INVALIDATE_MOD_CACHE} + {$ENDIF} + //important!!! iconv functions are defined in the libc.pas Novell Netware header. + //Do not define USE_ICONVUNIT + {$UNDEF USE_ICONV} + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} + {$DEFINE INT_THREAD_PRIORITY} +{$ENDIF} + +{$IFNDEF USE_ICONV} + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} +{$ENDIF} + +//IMPORTANT!!!! +// +//Do not remove this!!! This is to work around a conflict. In DCC, MACOS +//will mean OS X. In FreePascal, the DEFINE MACOS means MacIntosh System OS Classic. +{$IFDEF DCC} + // DCC defines MACOS for both iOS and OS X platforms, need to differentiate + {$IFDEF MACOS} + {$IFNDEF IOS} + {$DEFINE OSX} + {$DEFINE DARWIN} + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF FPC} + // FPC defines DARWIN for both OSX and iOS, need to differentiate + {$IFDEF DARWIN} + {$IFNDEF IOS} + {$DEFINE OSX} + {$ENDIF} + {$ENDIF} + {$IFDEF MACOS} + {$DEFINE MACOS_CLASSIC} + {$ENDIF} +{$ENDIF} + +{ +BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit +word to an 8 bit byte and an 8 bit byte field named sa_len was added. +} +//Place this only after DARWIN has been defined for Delphi MACOS +{$IFDEF FREEBSD} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF DARWIN} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF MORPHOS} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} + +// Do NOT remove these IFDEF's. They are here because InterlockedExchange +// only handles 32bit values. Some Operating Systems may have 64bit +// THandles. This is not always tied to the platform architecture. + +{$IFDEF AMIGA} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF ATARI} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF BEOS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF BSD} + //I think BSD might handle FreeBSD, NetBSD, OpenBSD, and Darwin + {$IFDEF IOS} + {$IFDEF CPUARM64} + {$DEFINE CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$IFDEF CPUARM32} + {$DEFINE CPU32} + {$ENDIF} + {$DEFINE THANDLE_32} + {$ENDIF} + {$ENDIF} + {$IFDEF OSX} + {$IFDEF FPC} + {$DEFINE THANDLE_32} + {$ELSE} + {$DEFINE THANDLE_CPUBITS} // !!! ADDED OSX BY EMBT + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF EMBEDDED} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF EMX} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF GBA} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF GO32} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF LINUX} + {$IFDEF LINUX64} + {$DEFINE CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$IFDEF LINUX32} + {$DEFINE CPU32} + {$ENDIF} + {$DEFINE THANDLE_32} + {$ENDIF} +{$ENDIF} +{$IFDEF MACOS_CLASSIC} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF MORPHOS} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF NATIVENT} //Native NT for kernel level drivers + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF NDS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF NETWARE} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF NETWARELIBC} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF OS2} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF PALMOS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF SOLARIS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF SYMBIAN} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WII} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WATCOM} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WINDOWS} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} + +// end platform specific stuff for THandle size + +{$IFDEF THANDLE_CPUBITS} + {$IFDEF CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$DEFINE THANDLE_32} + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + {$DEFINE DOTNET_OR_ICONV} +{$ENDIF} +{$IFDEF USE_ICONV} + {$DEFINE DOTNET_OR_ICONV} +{$ENDIF} + +{$UNDEF STREAM_SIZE_64} +{$IFDEF FPC} + {$DEFINE STREAM_SIZE_64} +{$ELSE} + {$IFDEF VCL_6_OR_ABOVE} + {$DEFINE STREAM_SIZE_64} + {$ENDIF} +{$ENDIF} + +{$IFNDEF FREE_ON_FINAL} + {$IFNDEF DOTNET} + {$IFDEF HAS_System_RegisterExpectedMemoryLeak} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_FASTMM4} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_MADEXCEPT} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_LEAKCHECK} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{ +We must determine what the SocketType parameter is for the Socket function. +In DotNET, it's SocketType. In Kylix and the libc.pas Kylix-compatibility +library, it's a __socket_type. In BaseUnix, it's a C-type Integer. In Windows, +it's a LongInt. + +} +{$UNDEF SOCKETTYPE_IS_SOCKETTYPE} +{$UNDEF SOCKETTYPE_IS_CINT} +{$UNDEF SOCKETTYPE_IS___SOCKETTYPE} +{$UNDEF SOCKETTYPE_IS_LONGINT} +{$UNDEF SOCKETTYPE_IS_NUMERIC} +{$UNDEF SOCKET_LEN_IS_socklen_t} +{$IFDEF DOTNET} + {$DEFINE SOCKETTYPE_IS_SOCKETTYPE} +{$ENDIF} +{$IFDEF USE_BASEUNIX} + {$DEFINE SOCKETTYPE_IS_CINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF KYLIXCOMPAT} + {$DEFINE SOCKETTYPE_IS___SOCKETTYPE} +{$ENDIF} +{$IFDEF USE_VCL_POSIX} + {$DEFINE SOCKETTYPE_IS_NUMERIC} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKET_LEN_IS_socklen_t} +{$ENDIF} +{$IFDEF WINDOWS} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF OS2} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF NETWARE} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} + +{Take advantage of some TCP features specific to some stacks. +They work somewhat similarly but there's a key difference. +In Linux, TCP_CORK is turned on to send fixed packet sizes and +when turned-off (uncorked), any remaining data is sent. With +TCP_NOPUSH, this might not happen and remaining data is only sent +before disconnect. TCP_KEEPIDLE and TCP_KEEPINTVL so the IFDEF LINUX and IFDEF +SOLARIS instead of IFDEF UNIX is not an error, it's deliberate.} +{$UNDEF HAS_TCP_NOPUSH} +{$UNDEF HAS_TCP_CORK} +{$UNDEF HAS_TCP_KEEPIDLE} +{$UNDEF HAS_TCP_KEEPINTVL} +{$UNDEF HAS_SOCKET_NOSIGPIPE} +{$IFDEF BSD} + {$DEFINE HAS_TCP_NOPUSH} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE HAS_TCP_NOPUSH} +{$ENDIF} +{$IFDEF LINUX} + {$DEFINE HAS_TCP_CORK} + {$DEFINE HAS_TCP_KEEPIDLE} + {$DEFINE HAS_TCP_KEEPINTVL} +{$ENDIF} +{$IFDEF SOLARIS} + {$DEFINE HAS_TCP_CORK} +{$ENDIF} +{$IFDEF NETBSD} + {$DEFINE HAS_TCP_CORK} + {$DEFINE HAS_TCP_KEEPIDLE} + {$DEFINE HAS_TCP_KEEPINTVL} +{$ENDIF} +{$IFDEF USE_VCL_POSIX} + // TODO: which platforms actually have SO_NOSIGPIPE available? + {$DEFINE HAS_SOCKET_NOSIGPIPE} + {$IFDEF ANDROID} + {$UNDEF HAS_SOCKET_NOSIGPIPE} + {$ENDIF} + {$IFDEF LINUX} + {$UNDEF HAS_SOCKET_NOSIGPIPE} + {$ENDIF} +{$ENDIF} +{end Unix OS specific stuff} +{$IFDEF DEBUG} + {$UNDEF USE_INLINE} +{$ENDIF} + +// RLebeau 5/24/2015: In C++Builder 2006 and 2007, UInt64 is emitted as +// signed __int64 in HPP files instead of as unsigned __int64. This causes +// conflicts in overloaded routines that have (U)Int64 parameters. This +// was fixed in C++Builder 2009. For compilers that do not have a native +// UInt64 type, or for C++Builder 2006/2007, let's define a record type +// that can hold UInt64 values... +{$IFDEF HAS_UInt64} + {$IFDEF BROKEN_UINT64_HPPEMIT} + {$DEFINE TIdUInt64_HAS_QuadPart} + {$ENDIF} +{$ELSE} + {$IFNDEF HAS_QWord} + {$DEFINE TIdUInt64_HAS_QuadPart} + {$ENDIF} +{$ENDIF} + +// RLebeau 9/5/2013: it would take a lot of work to re-write Indy to support +// both 0-based and 1-based string indexing, so we'll just turn off 0-based +// indexing for now... +{$IFDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} + {$ZEROBASEDSTRINGS OFF} +{$ENDIF} diff --git a/Lib/System/IdCompilerDefines.inc b/Lib/System/IdCompilerDefines.inc index 157bc07ec..ccfd332fe 100644 --- a/Lib/System/IdCompilerDefines.inc +++ b/Lib/System/IdCompilerDefines.inc @@ -1,2094 +1,2094 @@ -{$IFDEF CONDITIONALEXPRESSIONS} - // Must be at the top... - {$IF CompilerVersion >= 24.0} - {$LEGACYIFEND ON} - {$IFEND} -{$ENDIF} - -// General - -// Make this $DEFINE to use the 16 color icons required by Borland -// or DEFINE to use the 256 color Indy versions -{.$DEFINE Borland} - -// S.G. 4/9/2002: IPv4/IPv6 general switch (for defaults only) -{$DEFINE IdIPv4} // use IPv4 by default -{.$IFDEF IdIPv6} // use IPv6 by default - -{$DEFINE INDY100} -{$DEFINE 10_7_0} //so developers can IFDEF for this product version -{$DEFINE 10_7_0_0} //so developers can IFDEF for this specific version - -// When generating C++Builder output files, certain workarounds to compiler -// problems need to be enabled! When invoking DCC on the command-line, use -// the -DBCB parameter. When invoking MSBUILD, include the DCC_Define="BCB" -// attribute in the /p parameter. -{$IFDEF BCB} - {$DEFINE CBUILDER} -{$ELSE} - {$DEFINE DELPHI} -{$ENDIF} - -{$UNDEF USE_OPENSSL} -{$UNDEF STATICLOAD_OPENSSL} - -{$UNDEF USE_ZLIB_UNIT} -{$UNDEF USE_SSPI} - -// $DEFINE the following if the global objects in the IdStack and IdThread -// units should be freed on finalization -{$IFDEF FPC} -{$DEFINE FREE_ON_FINAL} -{$ELSE} -{$UNDEF FREE_ON_FINAL} -{$ENDIF} - -// Make sure the following is $DEFINE'd only for suitable environments -// as specified further below. This works in conjunction with the -// FREE_ON_FINAL define above. -{$UNDEF REGISTER_EXPECTED_MEMORY_LEAK} -{$UNDEF HAS_System_RegisterExpectedMemoryLeak} - -// FastMM is natively available in BDS 2006 and higher. $DEFINE the -// following if FastMM has been installed manually in earlier versions -{.$DEFINE USE_FASTMM4} -{$UNDEF USE_FASTMM4} - -// $DEFINE the following if MadExcept has been installed manually in -// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced -// in BDS 2006) -{.$DEFINE USE_MADEXCEPT} -{$UNDEF USE_MADEXCEPT} - -// $DEFINE the following if LeakCheck has been installed manually in -// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced -// in BDS 2006) -{.$DEFINE USE_LEAKCHECK} -{$UNDEF USE_LEAKCHECK} - -// Make sure the following are $DEFINE'd only for Delphi/C++Builder 2009 onwards -// as specified further below. The VCL is fully Unicode, where the 'String' -// type maps to System.UnicodeString, not System.AnsiString anymore -{$UNDEF STRING_IS_UNICODE} -{$UNDEF STRING_IS_ANSI} -{$UNDEF STRING_UNICODE_MISMATCH} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. Delphi/C++Builder Mobile/NextGen compilers -// do not support Ansi data types anymore, and is moving away from raw -// pointers as well. -// -// UPDATE: in Delphi/C++Builder 10.4, all Ansi types are supported again on -// all platforms, including the mobile compilers. -{$DEFINE HAS_AnsiString} -{$DEFINE HAS_AnsiChar} -{$DEFINE HAS_PAnsiChar} -{$UNDEF HAS_PPAnsiChar} -{$UNDEF NO_ANSI_TYPES} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. Delphi/C++Builder Mobile/NextGen compilers -// use ARC for TObject life time management. -// -// UPDATE: ARC for TObject lifetime management has been removed in -// Delphi/C++Builder 10.4 mobile compilers. All platforms now use a single -// unified memory management model! -{$UNDEF USE_MARSHALLED_PTRS} -{$UNDEF HAS_MarshaledAString} -{$UNDEF USE_OBJECT_ARC} - -// Make sure the following is $DEFINE'd only for suitable environments -// as specified further below. -{$UNDEF STRING_IS_IMMUTABLE} -{$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} - -// Make sure the following are $DEFINE'd only for suitable environments -// as specified further below. -{$UNDEF HAS_TEncoding} -{$UNDEF HAS_TEncoding_GetEncoding_ByEncodingName} -{$UNDEF HAS_Exception_RaiseOuterException} -{$UNDEF HAS_System_ReturnAddress} -{$UNDEF HAS_TCharacter} -{$UNDEF HAS_TInterlocked} -{$UNDEF HAS_TNetEncoding} - -// Make sure that this is defined only for environments where we are using -// the iconv library to charactor conversions. -{.$UNDEF USE_ICONV} -{.$UNDEF USE_LCONVENC} - -//Define for Delphi cross-compiler targetting Posix -{$UNDEF USE_VCL_POSIX} -{$UNDEF HAS_ComponentPlatformsAttribute} -{$UNDEF HAS_ComponentPlatformsAttribute_Win32} -{$UNDEF HAS_ComponentPlatformsAttribute_Win64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSX32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator32} -{$UNDEF HAS_ComponentPlatformsAttribute_Android} -{$UNDEF HAS_ComponentPlatformsAttribute_Android32Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device32} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux64} -{$UNDEF HAS_ComponentPlatformsAttribute_WinNX32} -{$UNDEF HAS_ComponentPlatformsAttribute_WinIoT32} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device64} -{$UNDEF HAS_ComponentPlatformsAttribute_WinARM} -{$UNDEF HAS_ComponentPlatformsAttribute_WinARM32} -{$UNDEF HAS_ComponentPlatformsAttribute_OSX64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux32Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Linux64Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_Android64} -{$UNDEF HAS_ComponentPlatformsAttribute_Android64Arm} -{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator64} -{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm32} -{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm64} -{$UNDEF HAS_ComponentPlatformsAttribute_OSXArm64} -{$UNDEF HAS_ComponentPlatformsAttribute_AllPlatforms} -{$UNDEF HAS_DIRECTIVE_WARN_DEFAULT} - -// Define for Delphi to auto-generate platform-appropriate '#pragma link' statements in HPP files -{$UNDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT} - -// detect compiler versions - -{$IFNDEF FPC} - - // TODO: to detect features in Delphi/C++Builder v6 and later, use CompilerVersion - // and RTLVersion constants instead of VERXXX defines. We still support v5, which - // does not have such constants. - - // Delphi 4 - {$IFDEF VER120} - {$DEFINE DCC} - {$DEFINE VCL_40} - {$DEFINE DELPHI_4} - {$ENDIF} - - // C++Builder 4 - {$IFDEF VER125} - {$DEFINE DCC} - {$DEFINE VCL_40} - {$DEFINE CBUILDER_4} - {$ENDIF} - - // Delphi & C++Builder 5 - {$IFDEF VER130} - {$DEFINE DCC} - {$DEFINE VCL_50} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_5} - {$ELSE} - {$DEFINE DELPHI_5} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 6 - {$IFDEF VER140} - {$DEFINE DCC} - {$DEFINE VCL_60} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_6} - {$ELSE} - {$DEFINE DELPHI_6} - {$ENDIF} - {$ENDIF} - - //Delphi 7 - {$IFDEF VER150} - {$DEFINE DCC} - {$DEFINE VCL_70} - {$DEFINE DELPHI_7} // there was no C++ Builder 7 - {$ENDIF} - - //Delphi 8 - {$IFDEF VER160} - {$DEFINE DCC} - {$DEFINE VCL_80} - {$DEFINE DELPHI_8} // there was no C++ Builder 8 - {$ENDIF} - - //Delphi 2005 - {$IFDEF VER170} - {$DEFINE DCC} - {$DEFINE VCL_2005} - {$DEFINE DELPHI_2005} // there was no C++Builder 2005 - {$ENDIF} - - // NOTE: CodeGear decided to make Highlander be a non-breaking release - // (no interface changes, thus fully backwards compatible without any - // end user code changes), so VER180 applies to both BDS 2006 and - // Highlander prior to the release of RAD Studio 2007. Use VER185 to - // identify Highlanger specifically. - - //Delphi & C++Builder 2006 - //Delphi & C++Builder 2007 (Highlander) - {$IFDEF VER180} - {$DEFINE DCC} - {$DEFINE VCL_2006} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2006} - {$ELSE} - {$DEFINE DELPHI_2006} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2007 (Highlander) - {$IFDEF VER185} - {$DEFINE DCC} - {$UNDEF VCL_2006} - {$DEFINE VCL_2007} - {$IFDEF CBUILDER} - {$UNDEF CBUILDER_2006} - {$DEFINE CBUILDER_2007} - {$ELSE} - {$UNDEF DELPHI_2006} - {$DEFINE DELPHI_2007} - {$ENDIF} - {$ENDIF} - - // BDS 2007 NET personality uses VER190 instead of 185. - //Delphi .NET 2007 - {$IFDEF VER190} - {$DEFINE DCC} - {$IFDEF CIL} - //Delphi 2007 - {$DEFINE VCL_2007} - {$DEFINE DELPHI_2007} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2009 (Tiburon) - {$IFDEF VER200} - {$DEFINE DCC} - {$DEFINE VCL_2009} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2009} - {$ELSE} - {$DEFINE DELPHI_2009} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder 2010 (Weaver) - {$IFDEF VER210} - {$DEFINE DCC} - {$DEFINE VCL_2010} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_2010} - {$ELSE} - {$DEFINE DELPHI_2010} - {$ENDIF} - {$ENDIF} - - //Delphi & C++Builder XE (Fulcrum) - {$IFDEF VER220} - //REMOVE DCC DEFINE after the next Fulcrum beta. - //It will be defined there. - {$IFNDEF DCC} - {$DEFINE DCC} - {$ENDIF} - {$DEFINE VCL_XE} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE} - {$ELSE} - {$DEFINE DELPHI_XE} - {$ENDIF} - {$ENDIF} - - // DCC is now defined by the Delphi compiler starting in XE2 - - //Delphi & CBuilder XE2 (Pulsar) - {$IFDEF VER230} - {$DEFINE VCL_XE2} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE2} - {$ELSE} - {$DEFINE DELPHI_XE2} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE3 (Waterdragon) - //Delphi & CBuilder XE3.5 (Quintessence - early betas only) - {$IFDEF VER240} - {$DEFINE VCL_XE3} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE3} - {$ELSE} - {$DEFINE DELPHI_XE3} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE4 (Quintessence) - {$IFDEF VER250} - {$UNDEF VCL_XE3} - {$DEFINE VCL_XE4} - {$IFDEF CBUILDER} - {$UNDEF CBUILDER_XE3} - {$DEFINE CBUILDER_XE4} - {$ELSE} - {$UNDEF DELPHI_XE3} - {$DEFINE DELPHI_XE4} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE5 (Zephyr) - {$IFDEF VER260} - {$DEFINE VCL_XE5} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE5} - {$ELSE} - {$DEFINE DELPHI_XE5} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder AppMethod - //AppMethod is just XE5 for mobile only, VCL is removed - {$IFDEF VER265} - {$DEFINE VCL_XE5} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE5} - {$ELSE} - {$DEFINE DELPHI_XE5} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE6 (Proteus) - {$IFDEF VER270} - {$DEFINE VCL_XE6} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE6} - {$ELSE} - {$DEFINE DELPHI_XE6} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE7 (Carpathia) - {$IFDEF VER280} - {$DEFINE VCL_XE7} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE7} - {$ELSE} - {$DEFINE DELPHI_XE7} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder XE8 (Elbrus) - {$IFDEF VER290} - {$DEFINE VCL_XE8} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_XE8} - {$ELSE} - {$DEFINE DELPHI_XE8} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.0 Seattle (Aitana) - {$IFDEF VER300} - {$DEFINE VCL_10_0} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_VCL_10_0} - {$ELSE} - {$DEFINE DELPHI_VCL_10_0} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.1 Berlin (BigBen) - {$IFDEF VER310} - {$DEFINE VCL_10_1} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_1} - {$ELSE} - {$DEFINE DELPHI_10_1} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.2 Tokyo (Godzilla) - {$IFDEF VER320} - {$DEFINE VCL_10_2} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_2} - {$ELSE} - {$DEFINE DELPHI_10_2} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.3 Rio (Carnival) - {$IFDEF VER330} - {$DEFINE VCL_10_3} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_3} - {$ELSE} - {$DEFINE DELPHI_10_3} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 10.4 Sydney (Denali) - {$IFDEF VER340} - {$DEFINE VCL_10_4} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_10_4} - {$ELSE} - {$DEFINE DELPHI_10_4} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 11.0 Alexandria (Olympus) - {$IFDEF VER350} - {$DEFINE VCL_11} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_11} - {$ELSE} - {$DEFINE DELPHI_11} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 12.0 Athens (Yukon) - {$IFDEF VER360} - {$DEFINE VCL_12} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_12} - {$ELSE} - {$DEFINE DELPHI_12} - {$ENDIF} - {$ENDIF} - - //Delphi & CBuilder 13.0+ (?) - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF CompilerVersion >= 37} - {$MESSAGE WARN 'Unknown compiler version detected! Assuming >= 13.x '} - {$DEFINE VCL_UNKNOWN_VERSION} - {$DEFINE VCL_13} - {$IFDEF CBUILDER} - {$DEFINE CBUILDER_13} - {$ELSE} - {$DEFINE DELPHI_13} - {$ENDIF} - {$IFEND} - {$ENDIF} - - // Kylix - // - //Important: Don't use CompilerVersion here as IF's are evaluated before - //IFDEF's and Kylix 1 does not have CompilerVersion defined at all. - {$IFDEF LINUX} - {$DEFINE UNIX} - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF (RTLVersion >= 14.0) and (RTLVersion <= 14.5) } - {$DEFINE KYLIX} - {$IF RTLVersion = 14.5} - {$DEFINE KYLIX_3} - {$ELSEIF RTLVersion >= 14.2} - {$DEFINE KYLIX_2} - {$ELSE} - {$DEFINE KYLIX_1} - {$IFEND} - {$IFEND} - {$ENDIF} - {$ENDIF} - -{$ENDIF} - -// Delphi.NET -// Covers D8+ -{$IFDEF CIL} - // Platform specific conditional. Used for platform specific code. - {$DEFINE DOTNET} - {$DEFINE STRING_IS_UNICODE} - {$DEFINE STRING_IS_IMMUTABLE} - {.$DEFINE HAS_Int8} - {.$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_UInt64} -{$ENDIF} - -{$IFDEF KYLIX} - {$DEFINE VCL_60} - {$DEFINE INT_THREAD_PRIORITY} - {$DEFINE CPUI386} - {$UNDEF USE_BASEUNIX} - - {$IFDEF KYLIX_3} - {$DEFINE KYLIX_3_OR_ABOVE} - {$ENDIF} - - {$IFDEF KYLIX_3_OR_ABOVE} - {$DEFINE KYLIX_2_OR_ABOVE} - {$ELSE} - {$IFDEF KYLIX_2} - {$DEFINE KYLIX_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF KYLIX_2_OR_ABOVE} - {$DEFINE KYLIX_1_OR_ABOVE} - {$ELSE} - {$IFDEF KYLIX_1} - {$DEFINE KYLIX_1_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFNDEF KYLIX_3_OR_ABOVE} - {$DEFINE KYLIXCOMPAT} - {$ENDIF} - - {$IFDEF KYLIX_2_OR_ABOVE} - {$DEFINE USE_ZLIB_UNIT} - {$ENDIF} -{$ENDIF} - -// FPC (2+) - -{$IFDEF FPC} - // TODO: In FreePascal 4.2.0+, a Delphi-like UnicodeString type is supported. - // However, String/(P)Char do not map to UnicodeString/(P)WideChar unless - // either {$MODE DelphiUnicode} or {$MODESWITCH UnicodeStrings} is used. - // We should consider enabling one of them so Indy uses the same Unicode logic - // in Delphi 2009+ and FreePascal 4.2.0+ and reduces IFDEFs (in particular, - // STRING_UNICODE_MISMATCH, see further below). However, FreePascal's RTL - // is largely not UnicodeString-enabled yet. Maybe we should enable - // {$MODE DelphiUnicode} anyway, and then deal with any RTL function issues - // on an as-needed basis... - {$MODE Delphi} - //note that we may need further defines for widget types depending on - //what we do and what platforms we support in FPC. - //I'll let Marco think about that one. - {$IFDEF UNIX} - {$DEFINE USE_BASEUNIX} - {$IFDEF LINUX} - //In Linux for I386, you can choose between a Kylix-libc API or - //the standard RTL Unix API. Just pass -dKYLIXCOMPAT to the FPC compiler. - //I will see what I can do about the Makefile. - {$IFDEF KYLIXCOMPAT} - {$IFDEF CPUI386} - {$UNDEF USE_BASEUNIX} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$IFDEF USE_BASEUNIX} - {$UNDEF KYLIXCOMPAT} - {$ENDIF} - {$ENDIF} - - // FPC_FULLVERSION was added in FPC 2.2.4 - // Have to use Defined() or else Delphi compiler chokes, since it - // evaluates $IF statements before $IFDEF statements... - - {$MACRO ON} // must be on in order to use versioning macros - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30101)} - {$DEFINE FPC_3_1_1_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30000)} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20701)} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20604)} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20602)} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20600)} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20404)} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20402)} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20400)} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20204)} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20202)} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$IFEND} - {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20105)} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$IFEND} - - // just in case - {$IFDEF FPC_3_1_1} - {$DEFINE FPC_3_1_1_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_3_0_0} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_7_1} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_4} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_2} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_6_0} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_4} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_2} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_4_0} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_2_4} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_2_2} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ENDIF} - {$IFDEF FPC_2_1_5} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ENDIF} - - {$IFDEF FPC_3_1_1_OR_ABOVE} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_3_0_0} - {$DEFINE FPC_3_0_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_3_0_0_OR_ABOVE} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_7_1} - {$DEFINE FPC_2_7_1_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_7_1_OR_ABOVE} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_4} - {$DEFINE FPC_2_6_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_4_OR_ABOVE} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_2} - {$DEFINE FPC_2_6_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_6_0} - {$DEFINE FPC_2_6_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_6_0_OR_ABOVE} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_4} - {$DEFINE FPC_2_4_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_4_OR_ABOVE} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_2} - {$DEFINE FPC_2_4_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_2_OR_ABOVE} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_4_0} - {$DEFINE FPC_2_4_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_4_0_OR_ABOVE} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_2_4} - {$DEFINE FPC_2_2_4_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_4_OR_ABOVE} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_2_2} - {$DEFINE FPC_2_2_2_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_2_OR_ABOVE} - {$DEFINE FPC_2_2_0_OR_ABOVE} - {$ELSE} - {$IFDEF VER2_2} - {$DEFINE FPC_2_2_0_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {$IFDEF FPC_2_2_0_OR_ABOVE} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ELSE} - {$IFDEF FPC_2_1_5} - {$DEFINE FPC_2_1_5_OR_ABOVE} - {$ENDIF} - {$ENDIF} - - {.$IFDEF FPC_2_7_1_OR_ABOVE} - // support for RawByteString and UnicodeString - {.$MODE DelphiUnicode} - {.$MODESWITCH UnicodeStrings} - {.$CODEPAGE UTF8} // needed for Unicode string literals to work properly - {.$DEFINE VCL_2009} - {.$DEFINE DELPHI_2009} - {.$ELSE} - {$DEFINE VCL_70} - {$DEFINE DELPHI_7} - {.$ENDIF} -{$ENDIF} - -// end FPC - -{$IFDEF VCL_13} - {$DEFINE VCL_13_OR_ABOVE} -{$ENDIF} - -{$IFDEF VCL_13_OR_ABOVE} - {$DEFINE VCL_12_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_12} - {$DEFINE VCL_12_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_12_OR_ABOVE} - {$DEFINE VCL_11_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_11} - {$DEFINE VCL_11_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_11_OR_ABOVE} - {$DEFINE VCL_10_4_OR_ABOVE} - {$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_4} - {$DEFINE VCL_10_4_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_4_OR_ABOVE} - {$DEFINE VCL_10_3_OR_ABOVE} - {$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_3} - {$DEFINE VCL_10_3_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_OR_ABOVE} - {$DEFINE VCL_10_2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_2} - {$DEFINE VCL_10_2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_2_OR_ABOVE} - {$DEFINE VCL_10_1_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_1} - {$DEFINE VCL_10_1_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_1_OR_ABOVE} - {$DEFINE VCL_10_0_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_10_0} - {$DEFINE VCL_10_0_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_0_OR_ABOVE} - {$DEFINE VCL_XE8_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE8} - {$DEFINE VCL_XE8_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE VCL_XE7_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE7} - {$DEFINE VCL_XE7_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE7_OR_ABOVE} - {$DEFINE VCL_XE6_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE6} - {$DEFINE VCL_XE6_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE6_OR_ABOVE} - {$DEFINE VCL_XE5_OR_ABOVE} - {$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE5} - {$DEFINE VCL_XE5_OR_ABOVE} - // TODO: figure out how to detect this version - {.$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE5_OR_ABOVE} - {$DEFINE VCL_XE4_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE4} - {$DEFINE VCL_XE4_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE4_OR_ABOVE} - {$DEFINE VCL_XE3_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE3} - {$DEFINE VCL_XE3_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE3_OR_ABOVE} - {$DEFINE VCL_XE2_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE2} - {$DEFINE VCL_XE2_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE2_OR_ABOVE} - {$DEFINE VCL_XE_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_XE} - {$DEFINE VCL_XE_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE_OR_ABOVE} - {$DEFINE VCL_2010_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2010} - {$DEFINE VCL_2010_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2010_OR_ABOVE} - {$DEFINE VCL_2009_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2009} - {$DEFINE VCL_2009_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2009_OR_ABOVE} - {$DEFINE VCL_2007_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2007} - {$DEFINE VCL_2007_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2007_OR_ABOVE} - {$DEFINE VCL_2006_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2006} - {$DEFINE VCL_2006_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2006_OR_ABOVE} - {$DEFINE VCL_2005_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_2005} - {$DEFINE VCL_2005_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2005_OR_ABOVE} - {$DEFINE VCL_8_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_80} - {$DEFINE VCL_8_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_8_OR_ABOVE} - {$DEFINE VCL_7_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_70} - {$DEFINE VCL_7_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_7_OR_ABOVE} - {$DEFINE VCL_6_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_60} - {$DEFINE VCL_6_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_6_OR_ABOVE} - {$DEFINE VCL_5_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_50} - {$DEFINE VCL_5_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_5_OR_ABOVE} - {$DEFINE VCL_4_OR_ABOVE} -{$ELSE} - {$IFDEF VCL_40} - {$DEFINE VCL_4_OR_ABOVE} - {$ENDIF} -{$ENDIF} - -// Normalize Delphi compiler defines to match FPC for consistency: -// -// CPU32 - any 32-bit CPU -// CPU64 - any 64-bit CPU -// WINDOWS - any Windows platform (32-bit, 64-bit, CE) -// WIN32 - Windows 32-bit -// WIN64 - Windows 64-bit -// WINCE - Windows CE -// -// Consult the "Free Pascal Programmer's Guide", Appendix G for the complete -// list of defines that are used. Do not work on this unless you understand -// what the FreePascal developers are doing. Not only do you have to -// descriminate with operating systems, but also with chip architectures -// are well. -// -// DCC Pulsar+ define the following values: -// ASSEMBLER -// DCC -// CONDITIONALEXPRESSIONS -// NATIVECODE -// UNICODE -// MACOS -// MACOS32 -// MACOS64 -// MSWINDOWS -// WIN32 -// WIN64 -// LINUX -// POSIX -// POSIX32 -// CPU386 -// CPUX86 -// CPUX64 -// -// Kylix defines the following values: -// LINUX -// (others??) -// - -{$IFNDEF FPC} - // TODO: We need to use ENDIAN_BIG for big endian chip architectures, - // such as 680x0, PowerPC, Sparc, and MIPS, once DCC supports them, - // provided it does not already define its own ENDIAN values by then... - {$DEFINE ENDIAN_LITTLE} - {$IFNDEF VCL_6_OR_ABOVE} - {$DEFINE MSWINDOWS} - {$ENDIF} - {$IFDEF MSWINDOWS} - {$DEFINE WINDOWS} - {$ENDIF} - // TODO: map Pulsar's non-Windows platform defines... - {$IFDEF VCL_XE2_OR_ABOVE} - {$IFDEF VCL_XE8_OR_ABOVE} - {$IFDEF CPU32BITS} - //any 32-bit CPU - {$DEFINE CPU32} - {$ENDIF} - {$IFDEF CPU64BITS} - {$DEFINE CPU64} - {$ENDIF} - {$ELSE} - {$IFDEF CPU386} - //any 32-bit CPU - {$DEFINE CPU32} - //Intel 386 compatible chip architecture - {$DEFINE CPUI386} - {$ENDIF} - {$IFDEF CPUX86} - {$DEFINE CPU32} - {$ENDIF} - {$IFDEF CPUX64} - //any 64-bit CPU - {$DEFINE CPU64} - //AMD64 compatible chip architecture - {$DEFINE CPUX86_64} //historical name for AMD64 - {$DEFINE CPUAMD64} - {$ENDIF} - {$ENDIF} - {$ELSE} - {$IFNDEF DOTNET} - {$IFNDEF KYLIX} - {$DEFINE I386} - {$ENDIF} - {$ENDIF} - {$DEFINE CPU32} - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - //differences in DotNET Framework versions. - {$IFDEF VCL_2007_OR_ABOVE} - {$DEFINE DOTNET_2} - {$DEFINE DOTNET_2_OR_ABOVE} - {$ELSE} - {$DEFINE DOTNET_1_1} - {$ENDIF} - {$DEFINE DOTNET_1_1_OR_ABOVE} - // Extra include used in D7 for testing. Remove later when all comps are - // ported. Used to selectively exclude non ported parts. Allowed in places - // IFDEFs are otherwise not permitted. - {$DEFINE DOTNET_EXCLUDE} -{$ENDIF} - -// Check for available features - -{$IFDEF CBUILDER} - // When generating a C++ HPP file, if a class has no explicit constructor - // defined and contains compiler-managed members (xxxString, TDateTime, - // Variant, DelphiInterface, etc), the HPP will contain a forwarding - // inline constructor that implicitly initializes those managed members, - // which will overwrite any non-default initializations performed inside - // of InitComponent() overrides! In this situation, the workaround is to - // define an explicit constructor that calls the base class constructor - // manually, allowing those managed members to be initialized by the - // compiler before InitComponent() overrides then re-assign them. - {$DEFINE WORKAROUND_INLINE_CONSTRUCTORS} -{$ENDIF} - -{$IFDEF VCL_5_OR_ABOVE} - {$IFNDEF FPC} - {$IFNDEF KYLIX} - {$DEFINE HAS_RemoveFreeNotification} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_GetObjectProp} - {$DEFINE HAS_TObjectList} - {$DEFINE HAS_StrToInt64Def} -{$ENDIF} - -{$IFDEF VCL_6_OR_ABOVE} - {$DEFINE HAS_PCardinal} - {$DEFINE HAS_PByte} - {$DEFINE HAS_PWord} - {$DEFINE HAS_PPointer} - {$DEFINE HAS_TList_Assign} - {$DEFINE HAS_sLineBreak} - {$DEFINE HAS_RaiseLastOSError} - {$DEFINE HAS_SysUtils_IncludeExcludeTrailingPathDelimiter} - {$DEFINE HAS_SysUtils_DirectoryExists} - {$DEFINE HAS_UNIT_DateUtils} - {$DEFINE HAS_UNIT_StrUtils} - {$DEFINE HAS_UNIT_Types} - {$DEFINE HAS_TryStrToInt} - {$DEFINE HAS_TryStrToInt64} - {$DEFINE HAS_TryEncodeDate} - {$DEFINE HAS_TryEncodeTime} - {$DEFINE HAS_ENUM_ELEMENT_VALUES} - {$IFNDEF FPC} - {$DEFINE HAS_IInterface} - {$DEFINE HAS_TSelectionEditor} - {$DEFINE HAS_TStringList_CaseSensitive} - {$DEFINE HAS_AcquireExceptionObject} - {$IFNDEF KYLIX} - {$DEFINE HAS_DEPRECATED} - {$DEFINE HAS_SYMBOL_PLATFORM} - {$DEFINE HAS_UNIT_PLATFORM} - {$IFNDEF VCL_8_OR_ABOVE} - // Delphi 6 and 7 have an annoying bug that if a class method is declared as - // deprecated, the compiler will emit a "symbol is deprecated" warning - // on the method's implementation! So we will have to wrap implementations - // of deprecated methods with {$WARN SYMBOL_DEPRECATED OFF} directives - // to disable that warning. - {$DEFINE DEPRECATED_IMPL_BUG} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$IFNDEF DOTNET} - //Widget defines are omitted in .NET - {$DEFINE VCL_60_PLUS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_7_OR_ABOVE} - {$IFNDEF FPC} - {$DEFINE HAS_UInt64} // Note: it was just an alias for Int64 until D2006! - {$DEFINE HAS_NAMED_THREADS} - {$DEFINE HAS_TStrings_NameValueSeparator} - {$DEFINE HAS_TStrings_ValueFromIndex} - // Note: there is a ZLib unit available, but it doesn't have everything - // that is available in the System.ZLib unit in Delphi XE2+, so we are - // not going to use this ZLib unit yet... - {.$DEFINE HAS_UNIT_ZLib} - {$ENDIF} - {$DEFINE HAS_TFormatSettings} - {$DEFINE HAS_PosEx} - {$IFNDEF VCL_70} - // not implemented in D7 - {$DEFINE HAS_STATIC_TThread_Queue} - {$ENDIF} - {$IFNDEF CIL} - {$IFNDEF VCL_80} - // not implemented in D8 or .NET - {$DEFINE HAS_STATIC_TThread_Synchronize} - {$ENDIF} - {$ENDIF} -{$ELSE} - {$IFDEF CBUILDER_6} - {$DEFINE HAS_NAMED_THREADS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2005_OR_ABOVE} - {$IFDEF DCC} - // class helpers were first introduced in D2005, but were buggy and not - // officially supported until D2006... - {.$DEFINE HAS_CLASS_HELPER} - {$ENDIF} -{$ELSE} - {$IFDEF DCC} - // InterlockedCompareExchange() was declared in the Windows unit using Pointer - // parameters until Delphi 2005, when it was switched to Longint parameters - // instead to match the actual Win32 API declaration. - {$DEFINE HAS_InterlockedCompareExchange_Pointers} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2006_OR_ABOVE} - {$DEFINE USE_INLINE} - {$DEFINE HAS_2PARAM_FileAge} - {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? - {$DEFINE HAS_CLASS_HELPER} - {$IFDEF WINDOWS} - // System.RegisterExpectedMemoryLeak() is only available on Windows at this time - {$DEFINE HAS_System_RegisterExpectedMemoryLeak} - {$ENDIF} - // In C++Builder 2006 and 2007, UInt64 is emitted as signed __int64 in HPP - // files instead of as unsigned __int64. This causes conflicts in overloaded - // routines that have (U)Int64 parameters. This was fixed in C++Builder 2009... - {$IFDEF CBUILDER} - {$DEFINE BROKEN_UINT64_HPPEMIT} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2007_OR_ABOVE} - {$IFNDEF CBUILDER_2007} - // class properties are broken in C++Builder 2007, causing AVs at compile-time - {$DEFINE HAS_CLASSPROPERTIES} - {$ENDIF} - // Native(U)Int exist but are buggy, so do not use them yet - {.$DEFINE HAS_NativeInt} - {.$DEFINE HAS_NativeUInt} - {$DEFINE HAS_DWORD_PTR} - {$DEFINE HAS_ULONG_PTR} - {$DEFINE HAS_ULONGLONG} - {$DEFINE HAS_PGUID} - {$DEFINE HAS_PPAnsiChar} - {$DEFINE HAS_CurrentYear} - {$IFNDEF DOTNET} - {$DEFINE HAS_TIMEUNITS} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_2009_OR_ABOVE} - {$IFNDEF DOTNET} - {$DEFINE STRING_IS_UNICODE} - {$DEFINE HAS_UnicodeString} - {$DEFINE HAS_TEncoding} - {$DEFINE HAS_TCharacter} - {$DEFINE HAS_InterlockedCompareExchangePointer} - {$DEFINE HAS_WIDE_TCharArray} - {$DEFINE HAS_PUInt64} - {$IFDEF VCL_2009} - // TODO: need to differentiate between RTM and Update 1 - // FmtStr() is broken in RTM but was fixed in Update 1 - {$DEFINE BROKEN_FmtStr} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_CLASSVARS} - {$DEFINE HAS_DEPRECATED_MSG} - {$DEFINE HAS_TBytes} - // Native(U)Int are still buggy, so do not use them yet - {.$DEFINE HAS_NativeInt} - {.$DEFINE HAS_NativeUInt} - {$DEFINE HAS_Int8} - {$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_UIntToStr} - // UInt64 is now emitted as unsigned __int64 in HPP files - {$IFDEF CBUILDER} - {$UNDEF BROKEN_UINT64_HPPEMIT} - {$ENDIF} - {$IFDEF DCC} - {$IFDEF WINDOWS} - // Exception.RaiseOuterException() is only available on Windows at this time - {$DEFINE HAS_Exception_RaiseOuterException} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_SetCodePage} - {$DEFINE HAS_PRawByteString} - {$DEFINE HAS_TThreadProcedure} -{$ENDIF} - -{$IFDEF VCL_2010_OR_ABOVE} - {$DEFINE HAS_CLASSCONSTRUCTOR} - {$DEFINE HAS_CLASSDESTRUCTOR} - {$DEFINE HAS_DELAYLOAD} - {$DEFINE HAS_TThread_NameThreadForDebugging} - {$DEFINE DEPRECATED_TThread_SuspendResume} - // Native(U)Int are finally ok to use now - {$DEFINE HAS_NativeInt} - {$DEFINE HAS_NativeUInt} - {$DEFINE HAS_USHORT} - {$DEFINE HAS_IOUtils_TPath} -{$ENDIF} - -{$IFDEF VCL_XE_OR_ABOVE} - {$DEFINE HAS_TFormatSettings_Object} - {$DEFINE HAS_LocaleCharsFromUnicode} - {$DEFINE HAS_UnicodeFromLocaleChars} - {$DEFINE HAS_PLongBool} - {$DEFINE HAS_PVOID} - {$DEFINE HAS_ULONG64} - {$DEFINE HAS_TEncoding_GetEncoding_ByEncodingName} - {$DEFINE HAS_DateUtils_TTimeZone} - {$IFDEF DCC} - // Exception.RaiseOuterException() is now available on all platforms - {$DEFINE HAS_Exception_RaiseOuterException} - {$ENDIF} - {$IFNDEF DOTNET} - {$DEFINE HAS_TInterlocked} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_XE2_OR_ABOVE} - {$DEFINE HAS_SIZE_T} - {$DEFINE HAS_PSIZE_T} - {$DEFINE HAS_SSIZE_T} - {$DEFINE HAS_PSSIZE_T} - {$DEFINE HAS_LONG} - {$DEFINE HAS_ComponentPlatformsAttribute} - {$DEFINE HAS_ComponentPlatformsAttribute_Win32} - {$DEFINE HAS_ComponentPlatformsAttribute_Win64} - {$DEFINE HAS_ComponentPlatformsAttribute_OSX32} - {$DEFINE HAS_System_ReturnAddress} - {$DEFINE HAS_DIRECTIVE_WARN_DEFAULT} - {$DEFINE HAS_UNIT_System_ZLib} -{$ENDIF} - -{$IFDEF VCL_XE3_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_ZEROBASEDSTRINGS} - {$DEFINE HAS_SysUtils_TStringHelper} - {$IFDEF NEXTGEN} - {$DEFINE DCC_NEXTGEN} - {$DEFINE HAS_MarshaledAString} - {$DEFINE USE_MARSHALLED_PTRS} - {$IFDEF AUTOREFCOUNT} - {$DEFINE USE_OBJECT_ARC} - {$ENDIF} - {$ENDIF} - // technically, these are present in XE3, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} - {.$DEFINE HAS_ComponentPlatformsAttribute_Android} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32} - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} - {.$DEFINE HAS_ComponentPlatformsAttribute_WinNX32} -{$ENDIF} - -{$IFDEF VCL_XE4_OR_ABOVE} - {$DEFINE HAS_AnsiStrings_StrPLCopy} - {$DEFINE HAS_AnsiStrings_StrLen} - {$DEFINE HAS_Character_TCharHelper} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} -{$ENDIF} - -{$IFDEF VCL_XE5_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_Android} -{$ENDIF} - -{$IFDEF VCL_XE5_UPDATE2_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_LINKUNIT} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_NAMESPACE} -{$ENDIF} - -{$IFDEF VCL_XE7_OR_ABOVE} - {$DEFINE HAS_TNetEncoding} -{$ENDIF} - -{$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device32} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device64} - // technically, these are present in XE8, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64} - {.$DEFINE HAS_ComponentPlatformsAttribute_WinIoT32} -{$ENDIF} - -{$IFDEF VCL_10_0_OR_ABOVE} - {$IFDEF ANDROID} - {$DEFINE HAS_TAndroidHelper} - {$ENDIF} - // technically, these are present in 10.0 Seattle, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_WinARM} -{$ENDIF} - -{$IFDEF VCL_10_1_OR_ABOVE} - {$DEFINE HAS_DIRECTIVE_HPPEMIT_LEGACYHPP} - {$DEFINE HAS_TStrings_AddPair} - // technically, these are present in 10.1 Berlin, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_OSX64} - {.$DEFINE HAS_ComponentPlatformsAttribute_OSXNX64} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32Arm} - {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64Arm} - {.$DEFINE HAS_ComponentPlatformsAttribute_Android64} -{$ENDIF} - -{$IFDEF VCL_10_2_OR_ABOVE} - {.$WARN IMPLICIT_INTEGER_CAST_LOSS OFF} - {.$WARN IMPLICIT_CONVERSION_LOSS OFF} - {.$WARN COMBINING_SIGNED_UNSIGNED64 OFF} - {$DEFINE HAS_STATIC_TThread_ForceQueue} - // In Delphi 10.2 Tokyo, TThread.ForceQueue() is broken on Android, the - // passed in procedure is called immediately instead of being delayed! - {$IFDEF ANDROID} - {$DEFINE BROKEN_TThread_ForceQueue} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator32} - {$DEFINE HAS_ComponentPlatformsAttribute_Android32Arm} - {$DEFINE HAS_ComponentPlatformsAttribute_WinARM32} - {$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} // removed in 10.3 Rio - // technically, these are present in 10.3 Rio, but they are not used yet - {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator64} - {$IFDEF DCC} - {$IFDEF LINUX} - // RLebeau 9/25/2019: there is a bug in the IDE when debugging Linux projects - // where the EThreadNameException exception raised by TThread.NameThreadForDebugging() - // is not handled correctly. - {$UNDEF HAS_NAMED_THREADS} - {$ENDIF} - {$ENDIF} - {$IFDEF ANDROID} - {$UNDEF BROKEN_TThread_ForceQueue} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_10_3_UPDATE2_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_AllPlatforms} - {$DEFINE HAS_ComponentPlatformsAttribute_OSX64} -{$ENDIF} - -{$IFDEF VCL_10_4_OR_ABOVE} - // 0-based string indexing via '[]' is turned off by default in Delphi 10.4. - // TStringHelper is always 0-indexed, flat RTL functions are always 1-indexed, - // and now '[]' is 1-indexed again on all platforms - {$ZEROBASEDSTRINGS OFF} - // is the default. - {.$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} -{$ENDIF} - -{$IFDEF VCL_11_OR_ABOVE} - {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm32} - {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm64} - {$DEFINE HAS_ComponentPlatformsAttribute_OSXArm64} -{$ENDIF} - -// Delphi XE+ cross-compiling -{$IFNDEF FPC} - {$IFDEF POSIX} - {$IF RTLVersion >= 22.0} - {$DEFINE UNIX} - {$UNDEF USE_BASEUNIX} - {$DEFINE VCL_CROSS_COMPILE} - {$DEFINE USE_VCL_POSIX} - {$IFEND} - {$ENDIF} - {$IFDEF LINUX} - {$IFDEF CONDITIONALEXPRESSIONS} - {$IF RTLVersion >= 22.0} - {$DEFINE VCL_CROSS_COMPILE} - {$DEFINE USE_VCL_POSIX} - {$IFEND} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{$IFDEF VCL_CROSS_COMPILE} - {$UNDEF KYLIXCOMPAT} -{$ELSE} - {$IFDEF KYLIXCOMPAT} - {$linklib c} - {$ENDIF} -{$ENDIF} - -{$IFDEF FPC} - {$DEFINE USE_INLINE} - {$DEFINE USE_CLASSINLINE} - {$DEFINE USE_TBitBtn} //use Bit Buttons instead of Buttons - {$DEFINE FPC_REINTRODUCE_BUG} - {$DEFINE FPC_CIRCULAR_BUG} - {$DEFINE NO_REDECLARE} - {$DEFINE BYTE_COMPARE_SETS} - {$DEFINE HAS_QWord} // TODO: when was QWord introduced? - {$DEFINE HAS_PQWord} // TODO: when was PQWord introduced? - {$IFDEF FPC_2_1_5_OR_ABOVE} - {$DEFINE HAS_UInt64} - {.$DEFINE HAS_PUInt64} // TODO: is this defined? - {$ENDIF} - {$IFDEF FPC_2_2_0_OR_ABOVE} - {$DEFINE HAS_InterlockedCompareExchange_Pointers} - {$ENDIF} - {$IFDEF FPC_2_2_2_OR_ABOVE} - {$DEFINE HAS_SharedSuffix} - {$ENDIF} - {$IFDEF FPC_2_2_4_OR_ABOVE} - // these types are only available on Unix systems (FreeBSD, Linux, etc) - {$IFDEF UNIX} - {$DEFINE HAS_UNIT_UnixType} - {$DEFINE HAS_SIZE_T} - {$DEFINE HAS_PSIZE_T} - {$DEFINE HAS_SSIZE_T} - {$DEFINE HAS_PSSIZE_T} - {$DEFINE HAS_TIME_T} - {$DEFINE HAS_PTIME_T} - {$ENDIF} - {$ENDIF} - {$DEFINE HAS_PtrInt} - {$DEFINE HAS_PtrUInt} - {$DEFINE HAS_PGUID} - {$DEFINE HAS_LPGUID} - {$DEFINE HAS_PPAnsiChar} - {$DEFINE HAS_ENUM_ELEMENT_VALUES} - {$DEFINE HAS_AcquireExceptionObject} // TODO: when was AcquireExceptionObject introduced? - {$IFDEF WINDOWS} - {$DEFINE HAS_ULONG_PTR} - {.$DEFINE HAS_ULONGLONG} // TODO: is this defined? - {$ENDIF} - {$DEFINE HAS_UNIT_ctypes} - {$DEFINE HAS_sLineBreak} - {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? - {$IFDEF FPC_HAS_UNICODESTRING} - {$DEFINE HAS_UnicodeString} - {$ELSE} - {$IFDEF FPC_2_4_0_OR_ABOVE} - {$DEFINE HAS_UnicodeString} - {$ENDIF} - {$ENDIF} - {$IFDEF FPC_2_4_4_OR_ABOVE} - {$DEFINE DEPRECATED_TThread_SuspendResume} - {$DEFINE HAS_DEPRECATED} // TODO: when was deprecated introduced? Possibly 1.9.x - {$DEFINE HAS_DEPRECATED_MSG} // TODO: when was message support added? Possibly 2.4.x - {$DEFINE HAS_STATIC_TThread_Synchronize} - {$IFNDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE USE_SEMICOLON_BEFORE_DEPRECATED} // TODO: which earlier versions require a semicolon? - {$ENDIF} - {$ENDIF} - {$IFDEF FPC_2_6_0_OR_ABOVE} - {$DEFINE HAS_NativeInt} - {$DEFINE HAS_NativeUInt} - {$DEFINE HAS_CLASS_HELPER} - {$ENDIF} - {$IFDEF FPC_2_6_2_OR_ABOVE} - {$DEFINE HAS_Int8} - {$DEFINE HAS_UInt8} - {$DEFINE HAS_Int16} - {$DEFINE HAS_UInt16} - {$DEFINE HAS_Int32} - {$DEFINE HAS_UInt32} - {$DEFINE HAS_GetLocalTimeOffset} - {$DEFINE HAS_UniversalTimeToLocal} - {$DEFINE HAS_LocalTimeToUniversal} - {$ENDIF} - {$IFDEF FPC_2_6_4_OR_ABOVE} - {$DEFINE HAS_PInt8} - {$DEFINE HAS_PUInt8} - {$DEFINE HAS_PInt16} - {$DEFINE HAS_PUInt16} - {$DEFINE HAS_PInt32} - {$DEFINE HAS_PUInt32} - {$ENDIF} - {$IFDEF FPC_3_0_0_OR_ABOVE} - {$DEFINE HAS_STATIC_TThread_Queue} - {$DEFINE HAS_SetCodePage} - {$ENDIF} - {$IFDEF FPC_UNICODESTRINGS} - {$DEFINE STRING_IS_UNICODE} - {$ENDIF} - {$IFDEF FPC_3_1_1_OR_ABOVE} - {$DEFINE HAS_STATIC_TThread_ForceQueue} // requires rev 37359+ - {$DEFINE HAS_PRawByteString} - {$DEFINE HAS_UIntToStr} // requires rev 40529+ - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - {$DEFINE WIDGET_WINFORMS} -{$ELSE} - {$DEFINE WIDGET_VCL_LIKE} // LCL included. - {$DEFINE WIDGET_VCL_LIKE_OR_KYLIX} - {$IFDEF FPC} - {$DEFINE WIDGET_LCL} - {$ELSE} - {$IFDEF KYLIX} - {$DEFINE WIDGET_KYLIX} - {$ELSE} - {$DEFINE WIDGET_VCL} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -// .NET and Delphi 2009+ support UNICODE strings natively! -// -// FreePascal 2.4.0+ supports UnicodeString, but does not map its -// native String type to UnicodeString except when {$MODE DelphiUnicode} -// or {$MODESWITCH UnicodeStrings} is enabled. However, UNICODE is not -// defined in that mode yet until its RTL has been updated to support -// UnicodeString. STRING_UNICODE_MISMATCH is defined when the native -// String/Char types do not map to the same types that APIs are expecting -// based on whether UNICODE is defined or not. -// -// NOTE: Do not define UNICODE here. The compiler defines -// the symbol automatically. -{$IFDEF STRING_IS_UNICODE} - {$IFNDEF UNICODE} - {$DEFINE STRING_UNICODE_MISMATCH} - {$ENDIF} -{$ELSE} - {$DEFINE STRING_IS_ANSI} - {$IFDEF UNICODE} - {$DEFINE STRING_UNICODE_MISMATCH} - {$ENDIF} -{$ENDIF} - -{$IFDEF DCC_NEXTGEN} - {$DEFINE NO_ANSI_TYPES} - {.$DEFINE STRING_IS_IMMUTABLE} // Strings are NOT immutable in NEXTGEN yet - {$IFDEF USE_OBJECT_ARC} - // TODO: move these to an appropriate section. Not doing this yet because - // it is a major interface change to switch to Generics and we should - // maintain backwards compatibility with earlier compilers for the time - // being. Defining them only here for now because the non-Generic versions - // of these classes have become deprecated by ARC and so we need to start - // taking advantage of the Generics versions... - {$DEFINE HAS_UNIT_Generics_Collections} - {$DEFINE HAS_UNIT_Generics_Defaults} - {$DEFINE HAS_GENERICS_TDictionary} - {$DEFINE HAS_GENERICS_TList} - {$DEFINE HAS_GENERICS_TObjectList} - {$DEFINE HAS_GENERICS_TThreadList} - // TArray.Copy() was introduced in XE7 but was buggy. It was fixed in XE8: - // - // RSP-9763 TArray.Copy copies from destination to source for unmanaged types - // https://quality.embarcadero.com/browse/RSP-9763 - // - {$IFDEF VCL_XE8_OR_ABOVE} - {$DEFINE HAS_GENERICS_TArray_Copy} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -// TODO: Ansi data types were disabled on mobile platforms in XE3, but -// UTF8String and RawByteString were re-enabled in 10.1 Berlin! What else, -// if anything, was re-enabled to facilitate that? -// -// UPDATE: In 10.4 Sydney, AnsiChar and AnsiString were re-enabled on -// mobile platforms! NEXTGEN is no longer defined in the mobile compilers. -{$IFDEF NO_ANSI_TYPES} - {$UNDEF HAS_AnsiString} - {$UNDEF HAS_AnsiChar} - {$UNDEF HAS_PAnsiChar} - {$UNDEF HAS_PPAnsiChar} - {$UNDEF HAS_AnsiStrings_StrPLCopy} - {$UNDEF HAS_AnsiStrings_StrLen} -{$ENDIF} - -{$IFDEF WIN32} - {$DEFINE WIN32_OR_WIN64} -{$ENDIF} -{$IFDEF WIN64} - {$DEFINE WIN32_OR_WIN64} -{$ENDIF} - -{$IFDEF WIN32_OR_WIN64} - {$DEFINE USE_ZLIB_UNIT} - {$IFNDEF DCC_NEXTGEN} - {$DEFINE USE_OPENSSL} // !!! MOVED HERE BY EMBT - {$DEFINE USE_SSPI} - {$IFDEF STRING_IS_UNICODE} - {$DEFINE SSPI_UNICODE} - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF WINCE} - {$DEFINE USE_OPENSSL} - // RLebeau: not sure if the above Win32/64 defines also apply to WinCE, - // so keeping them separate for now... -{$ENDIF} - -// High-performance counters are not reliable on multi-core systems, and have -// been known to cause problems with TIdIOHandler.ReadLn() timeouts in Windows -// XP SP3, both 32-bit and 64-bit. Refer to these discussions for more info: -// -// http://www.virtualdub.org/blog/pivot/entry.php?id=106 -// http://blogs.msdn.com/oldnewthing/archive/2008/09/08/8931563.aspx -// -// Do not enable thus unless you know it will work correctly on your systems! -{$IFDEF WINDOWS} - {.$DEFINE USE_HI_PERF_COUNTER_FOR_TICKS} -{$ENDIF} - -{$IFDEF UNIX} - {$DEFINE USE_OPENSSL} - {$DEFINE USE_ZLIB_UNIT} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF MACOS} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF DARWIN} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF LINUX} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF IOS} - {$DEFINE HAS_getifaddrs} - {$DEFINE USE_OPENSSL} - - // Support for 64-bit ARM iOS Simulator was added in Delphi 11.2 - // TODO: how to detect iOS Simulator in FPC? Does it support 64-bit ARM? - {$IFDEF CPUARM} - {$IFNDEF IOSSIMULATOR} - // RLebeau: For iOS devices, OpenSSL cannot be used as an external library, - // it must be statically linked into the app. For the iOS simulator, this - // is not true. Users who want to use OpenSSL in iOS device apps will need - // to add the static OpenSSL library to the project and then include the - // IdSSLOpenSSLHeaders_static unit in their uses clause. It hooks up the - // statically linked functions for the IdSSLOpenSSLHeaders unit to use... - {$DEFINE STATICLOAD_OPENSSL} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{$IFDEF FREEBSD} - {$DEFINE HAS_getifaddrs} -{$ENDIF} - -{$IFDEF ANDROID} - {$UNDEF HAS_getifaddrs} -{$ENDIF} - -{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} - {$DEFINE REQUIRES_PROPER_ALIGNMENT} -{$ENDIF} - -// -//iconv defines section. -{$DEFINE USE_ICONV_UNIT} -{$DEFINE USE_ICONV_ENC} -{$IFDEF UNIX} - {$DEFINE USE_ICONV} - {$IFDEF USE_BASEUNIX} - {$IFDEF FPC} - {$UNDEF USE_ICONV_UNIT} - {$ELSE} - {$UNDEF USE_ICONV_ENC} - {$ENDIF} - {$ENDIF} - {$IFDEF KYLIXCOMPAT} - //important!! Iconv functions are defined in the libc.pas Kylix compatible unit. - {$UNDEF USE_ICONV_ENC} - {$UNDEF USE_ICONV_UNIT} - {$ENDIF} -{$ENDIF} -{$IFDEF NETWARELIBC} - {$DEFINE USE_ICONV} - //important!!! iconv functions are defined in the libc.pas Novell Netware header. - //Do not define USE_ICONV_UNIT - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} -{$ENDIF} - -{$UNDEF USE_SAFELOADLIBRARY} -{$IFDEF WINDOWS} - {$UNDEF USE_ICONV_ENC} - {$DEFINE USE_SAFELOADLIBRARY} -{$ENDIF} -// Use here for all *nix systems that you do not want to use iconv library -{$IFDEF FPC} - {$IFDEF ANDROID} - {$UNDEF USE_ICONV} - {$DEFINE USE_LCONVENC} - {$ENDIF} -{$ENDIF} - -{$UNDEF USE_INVALIDATE_MOD_CACHE} -{$UNDEF USE_SAFELOADLIBRARY} -//This must come after the iconv defines because this compiler targets a Unix-like -//operating system. One key difference is that it does have a TEncoding class. -//If this comes before the ICONV defines, it creates problems. -//This also must go before the THandle size calculations. -{$IFDEF VCL_CROSS_COMPILE} - {$IFDEF POSIX} - {$IFNDEF LINUX} - {$DEFINE BSD} - {$ENDIF} - {$DEFINE USE_SAFELOADLIBRARY} - {$DEFINE USE_INVALIDATE_MOD_CACHE} - {$ENDIF} - //important!!! iconv functions are defined in the libc.pas Novell Netware header. - //Do not define USE_ICONVUNIT - {$UNDEF USE_ICONV} - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} - {$DEFINE INT_THREAD_PRIORITY} -{$ENDIF} - -{$IFNDEF USE_ICONV} - {$UNDEF USE_ICONV_UNIT} - {$UNDEF USE_ICONV_ENC} -{$ENDIF} - -//IMPORTANT!!!! -// -//Do not remove this!!! This is to work around a conflict. In DCC, MACOS -//will mean OS X. In FreePascal, the DEFINE MACOS means MacIntosh System OS Classic. -{$IFDEF DCC} - // DCC defines MACOS for both iOS and OS X platforms, need to differentiate - {$IFDEF MACOS} - {$IFNDEF IOS} - {$DEFINE OSX} - {$DEFINE DARWIN} - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF FPC} - // FPC defines DARWIN for both OSX and iOS, need to differentiate - {$IFDEF DARWIN} - {$IFNDEF IOS} - {$DEFINE OSX} - {$ENDIF} - {$ENDIF} - {$IFDEF MACOS} - {$DEFINE MACOS_CLASSIC} - {$ENDIF} -{$ENDIF} - -{ -BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit -word to an 8 bit byte and an 8 bit byte field named sa_len was added. -} -//Place this only after DARWIN has been defined for Delphi MACOS -{$IFDEF FREEBSD} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF DARWIN} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF MORPHOS} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} - -// Do NOT remove these IFDEF's. They are here because InterlockedExchange -// only handles 32bit values. Some Operating Systems may have 64bit -// THandles. This is not always tied to the platform architecture. - -{$IFDEF AMIGA} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF ATARI} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF BEOS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF BSD} - //I think BSD might handle FreeBSD, NetBSD, OpenBSD, and Darwin - {$IFDEF IOS} - {$IFDEF CPUARM64} - {$DEFINE CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$IFDEF CPUARM32} - {$DEFINE CPU32} - {$ENDIF} - {$DEFINE THANDLE_32} - {$ENDIF} - {$ENDIF} - {$IFDEF OSX} - {$IFDEF FPC} - {$DEFINE THANDLE_32} - {$ELSE} - {$DEFINE THANDLE_CPUBITS} // !!! ADDED OSX BY EMBT - {$ENDIF} - {$ENDIF} -{$ENDIF} -{$IFDEF EMBEDDED} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF EMX} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF GBA} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF GO32} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF LINUX} - {$IFDEF LINUX64} - {$DEFINE CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$IFDEF LINUX32} - {$DEFINE CPU32} - {$ENDIF} - {$DEFINE THANDLE_32} - {$ENDIF} -{$ENDIF} -{$IFDEF MACOS_CLASSIC} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF MORPHOS} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF NATIVENT} //Native NT for kernel level drivers - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} -{$IFDEF NDS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF NETWARE} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF NETWARELIBC} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF OS2} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF PALMOS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF SOLARIS} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF SYMBIAN} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WII} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WATCOM} - {$DEFINE THANDLE_32} -{$ENDIF} -{$IFDEF WINDOWS} - {$DEFINE THANDLE_CPUBITS} -{$ENDIF} - -// end platform specific stuff for THandle size - -{$IFDEF THANDLE_CPUBITS} - {$IFDEF CPU64} - {$DEFINE THANDLE_64} - {$ELSE} - {$DEFINE THANDLE_32} - {$ENDIF} -{$ENDIF} - -{$IFDEF DOTNET} - {$DEFINE DOTNET_OR_ICONV} -{$ENDIF} -{$IFDEF USE_ICONV} - {$DEFINE DOTNET_OR_ICONV} -{$ENDIF} - -{$UNDEF STREAM_SIZE_64} -{$IFDEF FPC} - {$DEFINE STREAM_SIZE_64} -{$ELSE} - {$IFDEF VCL_6_OR_ABOVE} - {$DEFINE STREAM_SIZE_64} - {$ENDIF} -{$ENDIF} - -{$IFNDEF FREE_ON_FINAL} - {$IFNDEF DOTNET} - {$IFDEF HAS_System_RegisterExpectedMemoryLeak} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_FASTMM4} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_MADEXCEPT} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$IFDEF USE_LEAKCHECK} - {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -{ -We must determine what the SocketType parameter is for the Socket function. -In DotNET, it's SocketType. In Kylix and the libc.pas Kylix-compatibility -library, it's a __socket_type. In BaseUnix, it's a C-type Integer. In Windows, -it's a LongInt. - -} -{$UNDEF SOCKETTYPE_IS_SOCKETTYPE} -{$UNDEF SOCKETTYPE_IS_CINT} -{$UNDEF SOCKETTYPE_IS___SOCKETTYPE} -{$UNDEF SOCKETTYPE_IS_LONGINT} -{$UNDEF SOCKETTYPE_IS_NUMERIC} -{$UNDEF SOCKET_LEN_IS_socklen_t} -{$IFDEF DOTNET} - {$DEFINE SOCKETTYPE_IS_SOCKETTYPE} -{$ENDIF} -{$IFDEF USE_BASEUNIX} - {$DEFINE SOCKETTYPE_IS_CINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF KYLIXCOMPAT} - {$DEFINE SOCKETTYPE_IS___SOCKETTYPE} -{$ENDIF} -{$IFDEF USE_VCL_POSIX} - {$DEFINE SOCKETTYPE_IS_NUMERIC} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKET_LEN_IS_socklen_t} -{$ENDIF} -{$IFDEF WINDOWS} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF OS2} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} -{$IFDEF NETWARE} - {$DEFINE SOCKETTYPE_IS_LONGINT} - {$DEFINE SOCKETTYPE_IS_NUMERIC} -{$ENDIF} - -{Take advantage of some TCP features specific to some stacks. -They work somewhat similarly but there's a key difference. -In Linux, TCP_CORK is turned on to send fixed packet sizes and -when turned-off (uncorked), any remaining data is sent. With -TCP_NOPUSH, this might not happen and remaining data is only sent -before disconnect. TCP_KEEPIDLE and TCP_KEEPINTVL so the IFDEF LINUX and IFDEF -SOLARIS instead of IFDEF UNIX is not an error, it's deliberate.} -{$UNDEF HAS_TCP_NOPUSH} -{$UNDEF HAS_TCP_CORK} -{$UNDEF HAS_TCP_KEEPIDLE} -{$UNDEF HAS_TCP_KEEPINTVL} -{$UNDEF HAS_SOCKET_NOSIGPIPE} -{$IFDEF BSD} - {$DEFINE HAS_TCP_NOPUSH} -{$ENDIF} -{$IFDEF HAIKU} - {$DEFINE HAS_TCP_NOPUSH} -{$ENDIF} -{$IFDEF LINUX} - {$DEFINE HAS_TCP_CORK} - {$DEFINE HAS_TCP_KEEPIDLE} - {$DEFINE HAS_TCP_KEEPINTVL} -{$ENDIF} -{$IFDEF SOLARIS} - {$DEFINE HAS_TCP_CORK} -{$ENDIF} -{$IFDEF NETBSD} - {$DEFINE HAS_TCP_CORK} - {$DEFINE HAS_TCP_KEEPIDLE} - {$DEFINE HAS_TCP_KEEPINTVL} -{$ENDIF} -{$IFDEF USE_VCL_POSIX} - // TODO: which platforms actually have SO_NOSIGPIPE available? - {$DEFINE HAS_SOCKET_NOSIGPIPE} - {$IFDEF ANDROID} - {$UNDEF HAS_SOCKET_NOSIGPIPE} - {$ENDIF} - {$IFDEF LINUX} - {$UNDEF HAS_SOCKET_NOSIGPIPE} - {$ENDIF} -{$ENDIF} -{end Unix OS specific stuff} -{$IFDEF DEBUG} - {$UNDEF USE_INLINE} -{$ENDIF} - -// RLebeau 5/24/2015: In C++Builder 2006 and 2007, UInt64 is emitted as -// signed __int64 in HPP files instead of as unsigned __int64. This causes -// conflicts in overloaded routines that have (U)Int64 parameters. This -// was fixed in C++Builder 2009. For compilers that do not have a native -// UInt64 type, or for C++Builder 2006/2007, let's define a record type -// that can hold UInt64 values... -{$IFDEF HAS_UInt64} - {$IFDEF BROKEN_UINT64_HPPEMIT} - {$DEFINE TIdUInt64_HAS_QuadPart} - {$ENDIF} -{$ELSE} - {$IFNDEF HAS_QWord} - {$DEFINE TIdUInt64_HAS_QuadPart} - {$ENDIF} -{$ENDIF} - -// RLebeau 9/5/2013: it would take a lot of work to re-write Indy to support -// both 0-based and 1-based string indexing, so we'll just turn off 0-based -// indexing for now... -{$IFDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} - {$ZEROBASEDSTRINGS OFF} -{$ENDIF} +{$IFDEF CONDITIONALEXPRESSIONS} + // Must be at the top... + {$IF CompilerVersion >= 24.0} + {$LEGACYIFEND ON} + {$IFEND} +{$ENDIF} + +// General + +// Make this $DEFINE to use the 16 color icons required by Borland +// or DEFINE to use the 256 color Indy versions +{.$DEFINE Borland} + +// S.G. 4/9/2002: IPv4/IPv6 general switch (for defaults only) +{$DEFINE IdIPv4} // use IPv4 by default +{.$IFDEF IdIPv6} // use IPv6 by default + +{$DEFINE INDY100} +{$DEFINE 10_7_0} //so developers can IFDEF for this product version +{$DEFINE 10_7_0_0} //so developers can IFDEF for this specific version + +// When generating C++Builder output files, certain workarounds to compiler +// problems need to be enabled! When invoking DCC on the command-line, use +// the -DBCB parameter. When invoking MSBUILD, include the DCC_Define="BCB" +// attribute in the /p parameter. +{$IFDEF BCB} + {$DEFINE CBUILDER} +{$ELSE} + {$DEFINE DELPHI} +{$ENDIF} + +{$UNDEF USE_OPENSSL} +{$UNDEF STATICLOAD_OPENSSL} + +{$UNDEF USE_ZLIB_UNIT} +{$UNDEF USE_SSPI} + +// $DEFINE the following if the global objects in the IdStack and IdThread +// units should be freed on finalization +{$IFDEF FPC} +{$DEFINE FREE_ON_FINAL} +{$ELSE} +{$UNDEF FREE_ON_FINAL} +{$ENDIF} + +// Make sure the following is $DEFINE'd only for suitable environments +// as specified further below. This works in conjunction with the +// FREE_ON_FINAL define above. +{$UNDEF REGISTER_EXPECTED_MEMORY_LEAK} +{$UNDEF HAS_System_RegisterExpectedMemoryLeak} + +// FastMM is natively available in BDS 2006 and higher. $DEFINE the +// following if FastMM has been installed manually in earlier versions +{.$DEFINE USE_FASTMM4} +{$UNDEF USE_FASTMM4} + +// $DEFINE the following if MadExcept has been installed manually in +// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced +// in BDS 2006) +{.$DEFINE USE_MADEXCEPT} +{$UNDEF USE_MADEXCEPT} + +// $DEFINE the following if LeakCheck has been installed manually in +// BDS 2005 or earlier (System.RegisterExpectedMemoryLeak() was introduced +// in BDS 2006) +{.$DEFINE USE_LEAKCHECK} +{$UNDEF USE_LEAKCHECK} + +// Make sure the following are $DEFINE'd only for Delphi/C++Builder 2009 onwards +// as specified further below. The VCL is fully Unicode, where the 'String' +// type maps to System.UnicodeString, not System.AnsiString anymore +{$UNDEF STRING_IS_UNICODE} +{$UNDEF STRING_IS_ANSI} +{$UNDEF STRING_UNICODE_MISMATCH} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. Delphi/C++Builder Mobile/NextGen compilers +// do not support Ansi data types anymore, and is moving away from raw +// pointers as well. +// +// UPDATE: in Delphi/C++Builder 10.4, all Ansi types are supported again on +// all platforms, including the mobile compilers. +{$DEFINE HAS_AnsiString} +{$DEFINE HAS_AnsiChar} +{$DEFINE HAS_PAnsiChar} +{$UNDEF HAS_PPAnsiChar} +{$UNDEF NO_ANSI_TYPES} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. Delphi/C++Builder Mobile/NextGen compilers +// use ARC for TObject life time management. +// +// UPDATE: ARC for TObject lifetime management has been removed in +// Delphi/C++Builder 10.4 mobile compilers. All platforms now use a single +// unified memory management model! +{$UNDEF USE_MARSHALLED_PTRS} +{$UNDEF HAS_MarshaledAString} +{$UNDEF USE_OBJECT_ARC} + +// Make sure the following is $DEFINE'd only for suitable environments +// as specified further below. +{$UNDEF STRING_IS_IMMUTABLE} +{$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} + +// Make sure the following are $DEFINE'd only for suitable environments +// as specified further below. +{$UNDEF HAS_TEncoding} +{$UNDEF HAS_TEncoding_GetEncoding_ByEncodingName} +{$UNDEF HAS_Exception_RaiseOuterException} +{$UNDEF HAS_System_ReturnAddress} +{$UNDEF HAS_TCharacter} +{$UNDEF HAS_TInterlocked} +{$UNDEF HAS_TNetEncoding} + +// Make sure that this is defined only for environments where we are using +// the iconv library to charactor conversions. +{.$UNDEF USE_ICONV} +{.$UNDEF USE_LCONVENC} + +//Define for Delphi cross-compiler targetting Posix +{$UNDEF USE_VCL_POSIX} +{$UNDEF HAS_ComponentPlatformsAttribute} +{$UNDEF HAS_ComponentPlatformsAttribute_Win32} +{$UNDEF HAS_ComponentPlatformsAttribute_Win64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSX32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator32} +{$UNDEF HAS_ComponentPlatformsAttribute_Android} +{$UNDEF HAS_ComponentPlatformsAttribute_Android32Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device32} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux64} +{$UNDEF HAS_ComponentPlatformsAttribute_WinNX32} +{$UNDEF HAS_ComponentPlatformsAttribute_WinIoT32} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Device64} +{$UNDEF HAS_ComponentPlatformsAttribute_WinARM} +{$UNDEF HAS_ComponentPlatformsAttribute_WinARM32} +{$UNDEF HAS_ComponentPlatformsAttribute_OSX64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux32Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Linux64Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_Android64} +{$UNDEF HAS_ComponentPlatformsAttribute_Android64Arm} +{$UNDEF HAS_ComponentPlatformsAttribute_iOS_Simulator64} +{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm32} +{$UNDEF HAS_ComponentPlatformsAttribute_AndroidArm64} +{$UNDEF HAS_ComponentPlatformsAttribute_OSXArm64} +{$UNDEF HAS_ComponentPlatformsAttribute_AllPlatforms} +{$UNDEF HAS_DIRECTIVE_WARN_DEFAULT} + +// Define for Delphi to auto-generate platform-appropriate '#pragma link' statements in HPP files +{$UNDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT} + +// detect compiler versions + +{$IFNDEF FPC} + + // TODO: to detect features in Delphi/C++Builder v6 and later, use CompilerVersion + // and RTLVersion constants instead of VERXXX defines. We still support v5, which + // does not have such constants. + + // Delphi 4 + {$IFDEF VER120} + {$DEFINE DCC} + {$DEFINE VCL_40} + {$DEFINE DELPHI_4} + {$ENDIF} + + // C++Builder 4 + {$IFDEF VER125} + {$DEFINE DCC} + {$DEFINE VCL_40} + {$DEFINE CBUILDER_4} + {$ENDIF} + + // Delphi & C++Builder 5 + {$IFDEF VER130} + {$DEFINE DCC} + {$DEFINE VCL_50} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_5} + {$ELSE} + {$DEFINE DELPHI_5} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 6 + {$IFDEF VER140} + {$DEFINE DCC} + {$DEFINE VCL_60} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_6} + {$ELSE} + {$DEFINE DELPHI_6} + {$ENDIF} + {$ENDIF} + + //Delphi 7 + {$IFDEF VER150} + {$DEFINE DCC} + {$DEFINE VCL_70} + {$DEFINE DELPHI_7} // there was no C++ Builder 7 + {$ENDIF} + + //Delphi 8 + {$IFDEF VER160} + {$DEFINE DCC} + {$DEFINE VCL_80} + {$DEFINE DELPHI_8} // there was no C++ Builder 8 + {$ENDIF} + + //Delphi 2005 + {$IFDEF VER170} + {$DEFINE DCC} + {$DEFINE VCL_2005} + {$DEFINE DELPHI_2005} // there was no C++Builder 2005 + {$ENDIF} + + // NOTE: CodeGear decided to make Highlander be a non-breaking release + // (no interface changes, thus fully backwards compatible without any + // end user code changes), so VER180 applies to both BDS 2006 and + // Highlander prior to the release of RAD Studio 2007. Use VER185 to + // identify Highlanger specifically. + + //Delphi & C++Builder 2006 + //Delphi & C++Builder 2007 (Highlander) + {$IFDEF VER180} + {$DEFINE DCC} + {$DEFINE VCL_2006} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2006} + {$ELSE} + {$DEFINE DELPHI_2006} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2007 (Highlander) + {$IFDEF VER185} + {$DEFINE DCC} + {$UNDEF VCL_2006} + {$DEFINE VCL_2007} + {$IFDEF CBUILDER} + {$UNDEF CBUILDER_2006} + {$DEFINE CBUILDER_2007} + {$ELSE} + {$UNDEF DELPHI_2006} + {$DEFINE DELPHI_2007} + {$ENDIF} + {$ENDIF} + + // BDS 2007 NET personality uses VER190 instead of 185. + //Delphi .NET 2007 + {$IFDEF VER190} + {$DEFINE DCC} + {$IFDEF CIL} + //Delphi 2007 + {$DEFINE VCL_2007} + {$DEFINE DELPHI_2007} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2009 (Tiburon) + {$IFDEF VER200} + {$DEFINE DCC} + {$DEFINE VCL_2009} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2009} + {$ELSE} + {$DEFINE DELPHI_2009} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder 2010 (Weaver) + {$IFDEF VER210} + {$DEFINE DCC} + {$DEFINE VCL_2010} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_2010} + {$ELSE} + {$DEFINE DELPHI_2010} + {$ENDIF} + {$ENDIF} + + //Delphi & C++Builder XE (Fulcrum) + {$IFDEF VER220} + //REMOVE DCC DEFINE after the next Fulcrum beta. + //It will be defined there. + {$IFNDEF DCC} + {$DEFINE DCC} + {$ENDIF} + {$DEFINE VCL_XE} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE} + {$ELSE} + {$DEFINE DELPHI_XE} + {$ENDIF} + {$ENDIF} + + // DCC is now defined by the Delphi compiler starting in XE2 + + //Delphi & CBuilder XE2 (Pulsar) + {$IFDEF VER230} + {$DEFINE VCL_XE2} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE2} + {$ELSE} + {$DEFINE DELPHI_XE2} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE3 (Waterdragon) + //Delphi & CBuilder XE3.5 (Quintessence - early betas only) + {$IFDEF VER240} + {$DEFINE VCL_XE3} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE3} + {$ELSE} + {$DEFINE DELPHI_XE3} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE4 (Quintessence) + {$IFDEF VER250} + {$UNDEF VCL_XE3} + {$DEFINE VCL_XE4} + {$IFDEF CBUILDER} + {$UNDEF CBUILDER_XE3} + {$DEFINE CBUILDER_XE4} + {$ELSE} + {$UNDEF DELPHI_XE3} + {$DEFINE DELPHI_XE4} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE5 (Zephyr) + {$IFDEF VER260} + {$DEFINE VCL_XE5} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE5} + {$ELSE} + {$DEFINE DELPHI_XE5} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder AppMethod + //AppMethod is just XE5 for mobile only, VCL is removed + {$IFDEF VER265} + {$DEFINE VCL_XE5} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE5} + {$ELSE} + {$DEFINE DELPHI_XE5} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE6 (Proteus) + {$IFDEF VER270} + {$DEFINE VCL_XE6} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE6} + {$ELSE} + {$DEFINE DELPHI_XE6} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE7 (Carpathia) + {$IFDEF VER280} + {$DEFINE VCL_XE7} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE7} + {$ELSE} + {$DEFINE DELPHI_XE7} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder XE8 (Elbrus) + {$IFDEF VER290} + {$DEFINE VCL_XE8} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_XE8} + {$ELSE} + {$DEFINE DELPHI_XE8} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.0 Seattle (Aitana) + {$IFDEF VER300} + {$DEFINE VCL_10_0} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_VCL_10_0} + {$ELSE} + {$DEFINE DELPHI_VCL_10_0} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.1 Berlin (BigBen) + {$IFDEF VER310} + {$DEFINE VCL_10_1} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_1} + {$ELSE} + {$DEFINE DELPHI_10_1} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.2 Tokyo (Godzilla) + {$IFDEF VER320} + {$DEFINE VCL_10_2} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_2} + {$ELSE} + {$DEFINE DELPHI_10_2} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.3 Rio (Carnival) + {$IFDEF VER330} + {$DEFINE VCL_10_3} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_3} + {$ELSE} + {$DEFINE DELPHI_10_3} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 10.4 Sydney (Denali) + {$IFDEF VER340} + {$DEFINE VCL_10_4} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_10_4} + {$ELSE} + {$DEFINE DELPHI_10_4} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 11.0 Alexandria (Olympus) + {$IFDEF VER350} + {$DEFINE VCL_11} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_11} + {$ELSE} + {$DEFINE DELPHI_11} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 12.0 Athens (Yukon) + {$IFDEF VER360} + {$DEFINE VCL_12} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_12} + {$ELSE} + {$DEFINE DELPHI_12} + {$ENDIF} + {$ENDIF} + + //Delphi & CBuilder 13.0+ (?) + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF CompilerVersion >= 37} + {$MESSAGE WARN 'Unknown compiler version detected! Assuming >= 13.x '} + {$DEFINE VCL_UNKNOWN_VERSION} + {$DEFINE VCL_13} + {$IFDEF CBUILDER} + {$DEFINE CBUILDER_13} + {$ELSE} + {$DEFINE DELPHI_13} + {$ENDIF} + {$IFEND} + {$ENDIF} + + // Kylix + // + //Important: Don't use CompilerVersion here as IF's are evaluated before + //IFDEF's and Kylix 1 does not have CompilerVersion defined at all. + {$IFDEF LINUX} + {$DEFINE UNIX} + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF (RTLVersion >= 14.0) and (RTLVersion <= 14.5) } + {$DEFINE KYLIX} + {$IF RTLVersion = 14.5} + {$DEFINE KYLIX_3} + {$ELSEIF RTLVersion >= 14.2} + {$DEFINE KYLIX_2} + {$ELSE} + {$DEFINE KYLIX_1} + {$IFEND} + {$IFEND} + {$ENDIF} + {$ENDIF} + +{$ENDIF} + +// Delphi.NET +// Covers D8+ +{$IFDEF CIL} + // Platform specific conditional. Used for platform specific code. + {$DEFINE DOTNET} + {$DEFINE STRING_IS_UNICODE} + {$DEFINE STRING_IS_IMMUTABLE} + {.$DEFINE HAS_Int8} + {.$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_UInt64} +{$ENDIF} + +{$IFDEF KYLIX} + {$DEFINE VCL_60} + {$DEFINE INT_THREAD_PRIORITY} + {$DEFINE CPUI386} + {$UNDEF USE_BASEUNIX} + + {$IFDEF KYLIX_3} + {$DEFINE KYLIX_3_OR_ABOVE} + {$ENDIF} + + {$IFDEF KYLIX_3_OR_ABOVE} + {$DEFINE KYLIX_2_OR_ABOVE} + {$ELSE} + {$IFDEF KYLIX_2} + {$DEFINE KYLIX_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF KYLIX_2_OR_ABOVE} + {$DEFINE KYLIX_1_OR_ABOVE} + {$ELSE} + {$IFDEF KYLIX_1} + {$DEFINE KYLIX_1_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFNDEF KYLIX_3_OR_ABOVE} + {$DEFINE KYLIXCOMPAT} + {$ENDIF} + + {$IFDEF KYLIX_2_OR_ABOVE} + {$DEFINE USE_ZLIB_UNIT} + {$ENDIF} +{$ENDIF} + +// FPC (2+) + +{$IFDEF FPC} + // TODO: In FreePascal 4.2.0+, a Delphi-like UnicodeString type is supported. + // However, String/(P)Char do not map to UnicodeString/(P)WideChar unless + // either {$MODE DelphiUnicode} or {$MODESWITCH UnicodeStrings} is used. + // We should consider enabling one of them so Indy uses the same Unicode logic + // in Delphi 2009+ and FreePascal 4.2.0+ and reduces IFDEFs (in particular, + // STRING_UNICODE_MISMATCH, see further below). However, FreePascal's RTL + // is largely not UnicodeString-enabled yet. Maybe we should enable + // {$MODE DelphiUnicode} anyway, and then deal with any RTL function issues + // on an as-needed basis... + {$MODE Delphi} + //note that we may need further defines for widget types depending on + //what we do and what platforms we support in FPC. + //I'll let Marco think about that one. + {$IFDEF UNIX} + {$DEFINE USE_BASEUNIX} + {$IFDEF LINUX} + //In Linux for I386, you can choose between a Kylix-libc API or + //the standard RTL Unix API. Just pass -dKYLIXCOMPAT to the FPC compiler. + //I will see what I can do about the Makefile. + {$IFDEF KYLIXCOMPAT} + {$IFDEF CPUI386} + {$UNDEF USE_BASEUNIX} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$IFDEF USE_BASEUNIX} + {$UNDEF KYLIXCOMPAT} + {$ENDIF} + {$ENDIF} + + // FPC_FULLVERSION was added in FPC 2.2.4 + // Have to use Defined() or else Delphi compiler chokes, since it + // evaluates $IF statements before $IFDEF statements... + + {$MACRO ON} // must be on in order to use versioning macros + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30101)} + {$DEFINE FPC_3_1_1_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30000)} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20701)} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20604)} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20602)} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20600)} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20404)} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20402)} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20400)} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20204)} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20202)} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$IFEND} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 20105)} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$IFEND} + + // just in case + {$IFDEF FPC_3_1_1} + {$DEFINE FPC_3_1_1_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_3_0_0} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_7_1} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_4} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_2} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_6_0} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_4} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_2} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_4_0} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_2_4} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_2_2} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ENDIF} + {$IFDEF FPC_2_1_5} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ENDIF} + + {$IFDEF FPC_3_1_1_OR_ABOVE} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_3_0_0} + {$DEFINE FPC_3_0_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_3_0_0_OR_ABOVE} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_7_1} + {$DEFINE FPC_2_7_1_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_7_1_OR_ABOVE} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_4} + {$DEFINE FPC_2_6_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_4_OR_ABOVE} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_2} + {$DEFINE FPC_2_6_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_6_0} + {$DEFINE FPC_2_6_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_6_0_OR_ABOVE} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_4} + {$DEFINE FPC_2_4_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_4_OR_ABOVE} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_2} + {$DEFINE FPC_2_4_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_2_OR_ABOVE} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_4_0} + {$DEFINE FPC_2_4_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_4_0_OR_ABOVE} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_2_4} + {$DEFINE FPC_2_2_4_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_4_OR_ABOVE} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_2_2} + {$DEFINE FPC_2_2_2_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_2_OR_ABOVE} + {$DEFINE FPC_2_2_0_OR_ABOVE} + {$ELSE} + {$IFDEF VER2_2} + {$DEFINE FPC_2_2_0_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {$IFDEF FPC_2_2_0_OR_ABOVE} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ELSE} + {$IFDEF FPC_2_1_5} + {$DEFINE FPC_2_1_5_OR_ABOVE} + {$ENDIF} + {$ENDIF} + + {.$IFDEF FPC_2_7_1_OR_ABOVE} + // support for RawByteString and UnicodeString + {.$MODE DelphiUnicode} + {.$MODESWITCH UnicodeStrings} + {.$CODEPAGE UTF8} // needed for Unicode string literals to work properly + {.$DEFINE VCL_2009} + {.$DEFINE DELPHI_2009} + {.$ELSE} + {$DEFINE VCL_70} + {$DEFINE DELPHI_7} + {.$ENDIF} +{$ENDIF} + +// end FPC + +{$IFDEF VCL_13} + {$DEFINE VCL_13_OR_ABOVE} +{$ENDIF} + +{$IFDEF VCL_13_OR_ABOVE} + {$DEFINE VCL_12_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_12} + {$DEFINE VCL_12_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_12_OR_ABOVE} + {$DEFINE VCL_11_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_11} + {$DEFINE VCL_11_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_11_OR_ABOVE} + {$DEFINE VCL_10_4_OR_ABOVE} + {$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_4} + {$DEFINE VCL_10_4_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_10_4_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_4_OR_ABOVE} + {$DEFINE VCL_10_3_OR_ABOVE} + {$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_3} + {$DEFINE VCL_10_3_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_10_3_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_OR_ABOVE} + {$DEFINE VCL_10_2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_2} + {$DEFINE VCL_10_2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_2_OR_ABOVE} + {$DEFINE VCL_10_1_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_1} + {$DEFINE VCL_10_1_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_1_OR_ABOVE} + {$DEFINE VCL_10_0_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_10_0} + {$DEFINE VCL_10_0_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_0_OR_ABOVE} + {$DEFINE VCL_XE8_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE8} + {$DEFINE VCL_XE8_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE VCL_XE7_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE7} + {$DEFINE VCL_XE7_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE7_OR_ABOVE} + {$DEFINE VCL_XE6_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE6} + {$DEFINE VCL_XE6_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE6_OR_ABOVE} + {$DEFINE VCL_XE5_OR_ABOVE} + {$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE5} + {$DEFINE VCL_XE5_OR_ABOVE} + // TODO: figure out how to detect this version + {.$DEFINE VCL_XE5_UPDATE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE5_OR_ABOVE} + {$DEFINE VCL_XE4_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE4} + {$DEFINE VCL_XE4_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE4_OR_ABOVE} + {$DEFINE VCL_XE3_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE3} + {$DEFINE VCL_XE3_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE3_OR_ABOVE} + {$DEFINE VCL_XE2_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE2} + {$DEFINE VCL_XE2_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE2_OR_ABOVE} + {$DEFINE VCL_XE_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_XE} + {$DEFINE VCL_XE_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE_OR_ABOVE} + {$DEFINE VCL_2010_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2010} + {$DEFINE VCL_2010_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2010_OR_ABOVE} + {$DEFINE VCL_2009_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2009} + {$DEFINE VCL_2009_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2009_OR_ABOVE} + {$DEFINE VCL_2007_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2007} + {$DEFINE VCL_2007_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2007_OR_ABOVE} + {$DEFINE VCL_2006_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2006} + {$DEFINE VCL_2006_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2006_OR_ABOVE} + {$DEFINE VCL_2005_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_2005} + {$DEFINE VCL_2005_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2005_OR_ABOVE} + {$DEFINE VCL_8_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_80} + {$DEFINE VCL_8_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_8_OR_ABOVE} + {$DEFINE VCL_7_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_70} + {$DEFINE VCL_7_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_7_OR_ABOVE} + {$DEFINE VCL_6_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_60} + {$DEFINE VCL_6_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_6_OR_ABOVE} + {$DEFINE VCL_5_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_50} + {$DEFINE VCL_5_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_5_OR_ABOVE} + {$DEFINE VCL_4_OR_ABOVE} +{$ELSE} + {$IFDEF VCL_40} + {$DEFINE VCL_4_OR_ABOVE} + {$ENDIF} +{$ENDIF} + +// Normalize Delphi compiler defines to match FPC for consistency: +// +// CPU32 - any 32-bit CPU +// CPU64 - any 64-bit CPU +// WINDOWS - any Windows platform (32-bit, 64-bit, CE) +// WIN32 - Windows 32-bit +// WIN64 - Windows 64-bit +// WINCE - Windows CE +// +// Consult the "Free Pascal Programmer's Guide", Appendix G for the complete +// list of defines that are used. Do not work on this unless you understand +// what the FreePascal developers are doing. Not only do you have to +// descriminate with operating systems, but also with chip architectures +// are well. +// +// DCC Pulsar+ define the following values: +// ASSEMBLER +// DCC +// CONDITIONALEXPRESSIONS +// NATIVECODE +// UNICODE +// MACOS +// MACOS32 +// MACOS64 +// MSWINDOWS +// WIN32 +// WIN64 +// LINUX +// POSIX +// POSIX32 +// CPU386 +// CPUX86 +// CPUX64 +// +// Kylix defines the following values: +// LINUX +// (others??) +// + +{$IFNDEF FPC} + // TODO: We need to use ENDIAN_BIG for big endian chip architectures, + // such as 680x0, PowerPC, Sparc, and MIPS, once DCC supports them, + // provided it does not already define its own ENDIAN values by then... + {$DEFINE ENDIAN_LITTLE} + {$IFNDEF VCL_6_OR_ABOVE} + {$DEFINE MSWINDOWS} + {$ENDIF} + {$IFDEF MSWINDOWS} + {$DEFINE WINDOWS} + {$ENDIF} + // TODO: map Pulsar's non-Windows platform defines... + {$IFDEF VCL_XE2_OR_ABOVE} + {$IFDEF VCL_XE8_OR_ABOVE} + {$IFDEF CPU32BITS} + //any 32-bit CPU + {$DEFINE CPU32} + {$ENDIF} + {$IFDEF CPU64BITS} + {$DEFINE CPU64} + {$ENDIF} + {$ELSE} + {$IFDEF CPU386} + //any 32-bit CPU + {$DEFINE CPU32} + //Intel 386 compatible chip architecture + {$DEFINE CPUI386} + {$ENDIF} + {$IFDEF CPUX86} + {$DEFINE CPU32} + {$ENDIF} + {$IFDEF CPUX64} + //any 64-bit CPU + {$DEFINE CPU64} + //AMD64 compatible chip architecture + {$DEFINE CPUX86_64} //historical name for AMD64 + {$DEFINE CPUAMD64} + {$ENDIF} + {$ENDIF} + {$ELSE} + {$IFNDEF DOTNET} + {$IFNDEF KYLIX} + {$DEFINE I386} + {$ENDIF} + {$ENDIF} + {$DEFINE CPU32} + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + //differences in DotNET Framework versions. + {$IFDEF VCL_2007_OR_ABOVE} + {$DEFINE DOTNET_2} + {$DEFINE DOTNET_2_OR_ABOVE} + {$ELSE} + {$DEFINE DOTNET_1_1} + {$ENDIF} + {$DEFINE DOTNET_1_1_OR_ABOVE} + // Extra include used in D7 for testing. Remove later when all comps are + // ported. Used to selectively exclude non ported parts. Allowed in places + // IFDEFs are otherwise not permitted. + {$DEFINE DOTNET_EXCLUDE} +{$ENDIF} + +// Check for available features + +{$IFDEF CBUILDER} + // When generating a C++ HPP file, if a class has no explicit constructor + // defined and contains compiler-managed members (xxxString, TDateTime, + // Variant, DelphiInterface, etc), the HPP will contain a forwarding + // inline constructor that implicitly initializes those managed members, + // which will overwrite any non-default initializations performed inside + // of InitComponent() overrides! In this situation, the workaround is to + // define an explicit constructor that calls the base class constructor + // manually, allowing those managed members to be initialized by the + // compiler before InitComponent() overrides then re-assign them. + {$DEFINE WORKAROUND_INLINE_CONSTRUCTORS} +{$ENDIF} + +{$IFDEF VCL_5_OR_ABOVE} + {$IFNDEF FPC} + {$IFNDEF KYLIX} + {$DEFINE HAS_RemoveFreeNotification} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_GetObjectProp} + {$DEFINE HAS_TObjectList} + {$DEFINE HAS_StrToInt64Def} +{$ENDIF} + +{$IFDEF VCL_6_OR_ABOVE} + {$DEFINE HAS_PCardinal} + {$DEFINE HAS_PByte} + {$DEFINE HAS_PWord} + {$DEFINE HAS_PPointer} + {$DEFINE HAS_TList_Assign} + {$DEFINE HAS_sLineBreak} + {$DEFINE HAS_RaiseLastOSError} + {$DEFINE HAS_SysUtils_IncludeExcludeTrailingPathDelimiter} + {$DEFINE HAS_SysUtils_DirectoryExists} + {$DEFINE HAS_UNIT_DateUtils} + {$DEFINE HAS_UNIT_StrUtils} + {$DEFINE HAS_UNIT_Types} + {$DEFINE HAS_TryStrToInt} + {$DEFINE HAS_TryStrToInt64} + {$DEFINE HAS_TryEncodeDate} + {$DEFINE HAS_TryEncodeTime} + {$DEFINE HAS_ENUM_ELEMENT_VALUES} + {$IFNDEF FPC} + {$DEFINE HAS_IInterface} + {$DEFINE HAS_TSelectionEditor} + {$DEFINE HAS_TStringList_CaseSensitive} + {$DEFINE HAS_AcquireExceptionObject} + {$IFNDEF KYLIX} + {$DEFINE HAS_DEPRECATED} + {$DEFINE HAS_SYMBOL_PLATFORM} + {$DEFINE HAS_UNIT_PLATFORM} + {$IFNDEF VCL_8_OR_ABOVE} + // Delphi 6 and 7 have an annoying bug that if a class method is declared as + // deprecated, the compiler will emit a "symbol is deprecated" warning + // on the method's implementation! So we will have to wrap implementations + // of deprecated methods with {$WARN SYMBOL_DEPRECATED OFF} directives + // to disable that warning. + {$DEFINE DEPRECATED_IMPL_BUG} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$IFNDEF DOTNET} + //Widget defines are omitted in .NET + {$DEFINE VCL_60_PLUS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_7_OR_ABOVE} + {$IFNDEF FPC} + {$DEFINE HAS_UInt64} // Note: it was just an alias for Int64 until D2006! + {$DEFINE HAS_NAMED_THREADS} + {$DEFINE HAS_TStrings_NameValueSeparator} + {$DEFINE HAS_TStrings_ValueFromIndex} + // Note: there is a ZLib unit available, but it doesn't have everything + // that is available in the System.ZLib unit in Delphi XE2+, so we are + // not going to use this ZLib unit yet... + {.$DEFINE HAS_UNIT_ZLib} + {$ENDIF} + {$DEFINE HAS_TFormatSettings} + {$DEFINE HAS_PosEx} + {$IFNDEF VCL_70} + // not implemented in D7 + {$DEFINE HAS_STATIC_TThread_Queue} + {$ENDIF} + {$IFNDEF CIL} + {$IFNDEF VCL_80} + // not implemented in D8 or .NET + {$DEFINE HAS_STATIC_TThread_Synchronize} + {$ENDIF} + {$ENDIF} +{$ELSE} + {$IFDEF CBUILDER_6} + {$DEFINE HAS_NAMED_THREADS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2005_OR_ABOVE} + {$IFDEF DCC} + // class helpers were first introduced in D2005, but were buggy and not + // officially supported until D2006... + {.$DEFINE HAS_CLASS_HELPER} + {$ENDIF} +{$ELSE} + {$IFDEF DCC} + // InterlockedCompareExchange() was declared in the Windows unit using Pointer + // parameters until Delphi 2005, when it was switched to Longint parameters + // instead to match the actual Win32 API declaration. + {$DEFINE HAS_InterlockedCompareExchange_Pointers} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2006_OR_ABOVE} + {$DEFINE USE_INLINE} + {$DEFINE HAS_2PARAM_FileAge} + {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? + {$DEFINE HAS_CLASS_HELPER} + {$IFDEF WINDOWS} + // System.RegisterExpectedMemoryLeak() is only available on Windows at this time + {$DEFINE HAS_System_RegisterExpectedMemoryLeak} + {$ENDIF} + // In C++Builder 2006 and 2007, UInt64 is emitted as signed __int64 in HPP + // files instead of as unsigned __int64. This causes conflicts in overloaded + // routines that have (U)Int64 parameters. This was fixed in C++Builder 2009... + {$IFDEF CBUILDER} + {$DEFINE BROKEN_UINT64_HPPEMIT} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2007_OR_ABOVE} + {$IFNDEF CBUILDER_2007} + // class properties are broken in C++Builder 2007, causing AVs at compile-time + {$DEFINE HAS_CLASSPROPERTIES} + {$ENDIF} + // Native(U)Int exist but are buggy, so do not use them yet + {.$DEFINE HAS_NativeInt} + {.$DEFINE HAS_NativeUInt} + {$DEFINE HAS_DWORD_PTR} + {$DEFINE HAS_ULONG_PTR} + {$DEFINE HAS_ULONGLONG} + {$DEFINE HAS_PGUID} + {$DEFINE HAS_PPAnsiChar} + {$DEFINE HAS_CurrentYear} + {$IFNDEF DOTNET} + {$DEFINE HAS_TIMEUNITS} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_2009_OR_ABOVE} + {$IFNDEF DOTNET} + {$DEFINE STRING_IS_UNICODE} + {$DEFINE HAS_UnicodeString} + {$DEFINE HAS_TEncoding} + {$DEFINE HAS_TCharacter} + {$DEFINE HAS_InterlockedCompareExchangePointer} + {$DEFINE HAS_WIDE_TCharArray} + {$DEFINE HAS_PUInt64} + {$IFDEF VCL_2009} + // TODO: need to differentiate between RTM and Update 1 + // FmtStr() is broken in RTM but was fixed in Update 1 + {$DEFINE BROKEN_FmtStr} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_CLASSVARS} + {$DEFINE HAS_DEPRECATED_MSG} + {$DEFINE HAS_TBytes} + // Native(U)Int are still buggy, so do not use them yet + {.$DEFINE HAS_NativeInt} + {.$DEFINE HAS_NativeUInt} + {$DEFINE HAS_Int8} + {$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_UIntToStr} + // UInt64 is now emitted as unsigned __int64 in HPP files + {$IFDEF CBUILDER} + {$UNDEF BROKEN_UINT64_HPPEMIT} + {$ENDIF} + {$IFDEF DCC} + {$IFDEF WINDOWS} + // Exception.RaiseOuterException() is only available on Windows at this time + {$DEFINE HAS_Exception_RaiseOuterException} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_SetCodePage} + {$DEFINE HAS_PRawByteString} + {$DEFINE HAS_TThreadProcedure} +{$ENDIF} + +{$IFDEF VCL_2010_OR_ABOVE} + {$DEFINE HAS_CLASSCONSTRUCTOR} + {$DEFINE HAS_CLASSDESTRUCTOR} + {$DEFINE HAS_DELAYLOAD} + {$DEFINE HAS_TThread_NameThreadForDebugging} + {$DEFINE DEPRECATED_TThread_SuspendResume} + // Native(U)Int are finally ok to use now + {$DEFINE HAS_NativeInt} + {$DEFINE HAS_NativeUInt} + {$DEFINE HAS_USHORT} + {$DEFINE HAS_IOUtils_TPath} +{$ENDIF} + +{$IFDEF VCL_XE_OR_ABOVE} + {$DEFINE HAS_TFormatSettings_Object} + {$DEFINE HAS_LocaleCharsFromUnicode} + {$DEFINE HAS_UnicodeFromLocaleChars} + {$DEFINE HAS_PLongBool} + {$DEFINE HAS_PVOID} + {$DEFINE HAS_ULONG64} + {$DEFINE HAS_TEncoding_GetEncoding_ByEncodingName} + {$DEFINE HAS_DateUtils_TTimeZone} + {$IFDEF DCC} + // Exception.RaiseOuterException() is now available on all platforms + {$DEFINE HAS_Exception_RaiseOuterException} + {$ENDIF} + {$IFNDEF DOTNET} + {$DEFINE HAS_TInterlocked} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_XE2_OR_ABOVE} + {$DEFINE HAS_SIZE_T} + {$DEFINE HAS_PSIZE_T} + {$DEFINE HAS_SSIZE_T} + {$DEFINE HAS_PSSIZE_T} + {$DEFINE HAS_LONG} + {$DEFINE HAS_ComponentPlatformsAttribute} + {$DEFINE HAS_ComponentPlatformsAttribute_Win32} + {$DEFINE HAS_ComponentPlatformsAttribute_Win64} + {$DEFINE HAS_ComponentPlatformsAttribute_OSX32} + {$DEFINE HAS_System_ReturnAddress} + {$DEFINE HAS_DIRECTIVE_WARN_DEFAULT} + {$DEFINE HAS_UNIT_System_ZLib} +{$ENDIF} + +{$IFDEF VCL_XE3_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_ZEROBASEDSTRINGS} + {$DEFINE HAS_SysUtils_TStringHelper} + {$IFDEF NEXTGEN} + {$DEFINE DCC_NEXTGEN} + {$DEFINE HAS_MarshaledAString} + {$DEFINE USE_MARSHALLED_PTRS} + {$IFDEF AUTOREFCOUNT} + {$DEFINE USE_OBJECT_ARC} + {$ENDIF} + {$ENDIF} + // technically, these are present in XE3, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} + {.$DEFINE HAS_ComponentPlatformsAttribute_Android} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32} + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} + {.$DEFINE HAS_ComponentPlatformsAttribute_WinNX32} +{$ENDIF} + +{$IFDEF VCL_XE4_OR_ABOVE} + {$DEFINE HAS_AnsiStrings_StrPLCopy} + {$DEFINE HAS_AnsiStrings_StrLen} + {$DEFINE HAS_Character_TCharHelper} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device} +{$ENDIF} + +{$IFDEF VCL_XE5_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_Android} +{$ENDIF} + +{$IFDEF VCL_XE5_UPDATE2_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_LINKUNIT} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_NAMESPACE} +{$ENDIF} + +{$IFDEF VCL_XE7_OR_ABOVE} + {$DEFINE HAS_TNetEncoding} +{$ENDIF} + +{$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device32} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Device64} + // technically, these are present in XE8, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64} + {.$DEFINE HAS_ComponentPlatformsAttribute_WinIoT32} +{$ENDIF} + +{$IFDEF VCL_10_0_OR_ABOVE} + {$IFDEF ANDROID} + {$DEFINE HAS_TAndroidHelper} + {$ENDIF} + // technically, these are present in 10.0 Seattle, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_WinARM} +{$ENDIF} + +{$IFDEF VCL_10_1_OR_ABOVE} + {$DEFINE HAS_DIRECTIVE_HPPEMIT_LEGACYHPP} + {$DEFINE HAS_TStrings_AddPair} + // technically, these are present in 10.1 Berlin, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_OSX64} + {.$DEFINE HAS_ComponentPlatformsAttribute_OSXNX64} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux32Arm} + {.$DEFINE HAS_ComponentPlatformsAttribute_Linux64Arm} + {.$DEFINE HAS_ComponentPlatformsAttribute_Android64} +{$ENDIF} + +{$IFDEF VCL_10_2_OR_ABOVE} + {.$WARN IMPLICIT_INTEGER_CAST_LOSS OFF} + {.$WARN IMPLICIT_CONVERSION_LOSS OFF} + {.$WARN COMBINING_SIGNED_UNSIGNED64 OFF} + {$DEFINE HAS_STATIC_TThread_ForceQueue} + // In Delphi 10.2 Tokyo, TThread.ForceQueue() is broken on Android, the + // passed in procedure is called immediately instead of being delayed! + {$IFDEF ANDROID} + {$DEFINE BROKEN_TThread_ForceQueue} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator32} + {$DEFINE HAS_ComponentPlatformsAttribute_Android32Arm} + {$DEFINE HAS_ComponentPlatformsAttribute_WinARM32} + {$UNDEF HAS_ComponentPlatformsAttribute_OSXNX64} // removed in 10.3 Rio + // technically, these are present in 10.3 Rio, but they are not used yet + {.$DEFINE HAS_ComponentPlatformsAttribute_iOS_Simulator64} + {$IFDEF DCC} + {$IFDEF LINUX} + // RLebeau 9/25/2019: there is a bug in the IDE when debugging Linux projects + // where the EThreadNameException exception raised by TThread.NameThreadForDebugging() + // is not handled correctly. + {$UNDEF HAS_NAMED_THREADS} + {$ENDIF} + {$ENDIF} + {$IFDEF ANDROID} + {$UNDEF BROKEN_TThread_ForceQueue} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_10_3_UPDATE2_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_AllPlatforms} + {$DEFINE HAS_ComponentPlatformsAttribute_OSX64} +{$ENDIF} + +{$IFDEF VCL_10_4_OR_ABOVE} + // 0-based string indexing via '[]' is turned off by default in Delphi 10.4. + // TStringHelper is always 0-indexed, flat RTL functions are always 1-indexed, + // and now '[]' is 1-indexed again on all platforms - {$ZEROBASEDSTRINGS OFF} + // is the default. + {.$UNDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} +{$ENDIF} + +{$IFDEF VCL_11_OR_ABOVE} + {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm32} + {$DEFINE HAS_ComponentPlatformsAttribute_AndroidArm64} + {$DEFINE HAS_ComponentPlatformsAttribute_OSXArm64} +{$ENDIF} + +// Delphi XE+ cross-compiling +{$IFNDEF FPC} + {$IFDEF POSIX} + {$IF RTLVersion >= 22.0} + {$DEFINE UNIX} + {$UNDEF USE_BASEUNIX} + {$DEFINE VCL_CROSS_COMPILE} + {$DEFINE USE_VCL_POSIX} + {$IFEND} + {$ENDIF} + {$IFDEF LINUX} + {$IFDEF CONDITIONALEXPRESSIONS} + {$IF RTLVersion >= 22.0} + {$DEFINE VCL_CROSS_COMPILE} + {$DEFINE USE_VCL_POSIX} + {$IFEND} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF VCL_CROSS_COMPILE} + {$UNDEF KYLIXCOMPAT} +{$ELSE} + {$IFDEF KYLIXCOMPAT} + {$linklib c} + {$ENDIF} +{$ENDIF} + +{$IFDEF FPC} + {$DEFINE USE_INLINE} + {$DEFINE USE_CLASSINLINE} + {$DEFINE USE_TBitBtn} //use Bit Buttons instead of Buttons + {$DEFINE FPC_REINTRODUCE_BUG} + {$DEFINE FPC_CIRCULAR_BUG} + {$DEFINE NO_REDECLARE} + {$DEFINE BYTE_COMPARE_SETS} + {$DEFINE HAS_QWord} // TODO: when was QWord introduced? + {$DEFINE HAS_PQWord} // TODO: when was PQWord introduced? + {$IFDEF FPC_2_1_5_OR_ABOVE} + {$DEFINE HAS_UInt64} + {.$DEFINE HAS_PUInt64} // TODO: is this defined? + {$ENDIF} + {$IFDEF FPC_2_2_0_OR_ABOVE} + {$DEFINE HAS_InterlockedCompareExchange_Pointers} + {$ENDIF} + {$IFDEF FPC_2_2_2_OR_ABOVE} + {$DEFINE HAS_SharedSuffix} + {$ENDIF} + {$IFDEF FPC_2_2_4_OR_ABOVE} + // these types are only available on Unix systems (FreeBSD, Linux, etc) + {$IFDEF UNIX} + {$DEFINE HAS_UNIT_UnixType} + {$DEFINE HAS_SIZE_T} + {$DEFINE HAS_PSIZE_T} + {$DEFINE HAS_SSIZE_T} + {$DEFINE HAS_PSSIZE_T} + {$DEFINE HAS_TIME_T} + {$DEFINE HAS_PTIME_T} + {$ENDIF} + {$ENDIF} + {$DEFINE HAS_PtrInt} + {$DEFINE HAS_PtrUInt} + {$DEFINE HAS_PGUID} + {$DEFINE HAS_LPGUID} + {$DEFINE HAS_PPAnsiChar} + {$DEFINE HAS_ENUM_ELEMENT_VALUES} + {$DEFINE HAS_AcquireExceptionObject} // TODO: when was AcquireExceptionObject introduced? + {$IFDEF WINDOWS} + {$DEFINE HAS_ULONG_PTR} + {.$DEFINE HAS_ULONGLONG} // TODO: is this defined? + {$ENDIF} + {$DEFINE HAS_UNIT_ctypes} + {$DEFINE HAS_sLineBreak} + {$DEFINE HAS_TStrings_LineBreak} // TODO: when was LineBreak introduced? + {$IFDEF FPC_HAS_UNICODESTRING} + {$DEFINE HAS_UnicodeString} + {$ELSE} + {$IFDEF FPC_2_4_0_OR_ABOVE} + {$DEFINE HAS_UnicodeString} + {$ENDIF} + {$ENDIF} + {$IFDEF FPC_2_4_4_OR_ABOVE} + {$DEFINE DEPRECATED_TThread_SuspendResume} + {$DEFINE HAS_DEPRECATED} // TODO: when was deprecated introduced? Possibly 1.9.x + {$DEFINE HAS_DEPRECATED_MSG} // TODO: when was message support added? Possibly 2.4.x + {$DEFINE HAS_STATIC_TThread_Synchronize} + {$IFNDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE USE_SEMICOLON_BEFORE_DEPRECATED} // TODO: which earlier versions require a semicolon? + {$ENDIF} + {$ENDIF} + {$IFDEF FPC_2_6_0_OR_ABOVE} + {$DEFINE HAS_NativeInt} + {$DEFINE HAS_NativeUInt} + {$DEFINE HAS_CLASS_HELPER} + {$ENDIF} + {$IFDEF FPC_2_6_2_OR_ABOVE} + {$DEFINE HAS_Int8} + {$DEFINE HAS_UInt8} + {$DEFINE HAS_Int16} + {$DEFINE HAS_UInt16} + {$DEFINE HAS_Int32} + {$DEFINE HAS_UInt32} + {$DEFINE HAS_GetLocalTimeOffset} + {$DEFINE HAS_UniversalTimeToLocal} + {$DEFINE HAS_LocalTimeToUniversal} + {$ENDIF} + {$IFDEF FPC_2_6_4_OR_ABOVE} + {$DEFINE HAS_PInt8} + {$DEFINE HAS_PUInt8} + {$DEFINE HAS_PInt16} + {$DEFINE HAS_PUInt16} + {$DEFINE HAS_PInt32} + {$DEFINE HAS_PUInt32} + {$ENDIF} + {$IFDEF FPC_3_0_0_OR_ABOVE} + {$DEFINE HAS_STATIC_TThread_Queue} + {$DEFINE HAS_SetCodePage} + {$ENDIF} + {$IFDEF FPC_UNICODESTRINGS} + {$DEFINE STRING_IS_UNICODE} + {$ENDIF} + {$IFDEF FPC_3_1_1_OR_ABOVE} + {$DEFINE HAS_STATIC_TThread_ForceQueue} // requires rev 37359+ + {$DEFINE HAS_PRawByteString} + {$DEFINE HAS_UIntToStr} // requires rev 40529+ + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + {$DEFINE WIDGET_WINFORMS} +{$ELSE} + {$DEFINE WIDGET_VCL_LIKE} // LCL included. + {$DEFINE WIDGET_VCL_LIKE_OR_KYLIX} + {$IFDEF FPC} + {$DEFINE WIDGET_LCL} + {$ELSE} + {$IFDEF KYLIX} + {$DEFINE WIDGET_KYLIX} + {$ELSE} + {$DEFINE WIDGET_VCL} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +// .NET and Delphi 2009+ support UNICODE strings natively! +// +// FreePascal 2.4.0+ supports UnicodeString, but does not map its +// native String type to UnicodeString except when {$MODE DelphiUnicode} +// or {$MODESWITCH UnicodeStrings} is enabled. However, UNICODE is not +// defined in that mode yet until its RTL has been updated to support +// UnicodeString. STRING_UNICODE_MISMATCH is defined when the native +// String/Char types do not map to the same types that APIs are expecting +// based on whether UNICODE is defined or not. +// +// NOTE: Do not define UNICODE here. The compiler defines +// the symbol automatically. +{$IFDEF STRING_IS_UNICODE} + {$IFNDEF UNICODE} + {$DEFINE STRING_UNICODE_MISMATCH} + {$ENDIF} +{$ELSE} + {$DEFINE STRING_IS_ANSI} + {$IFDEF UNICODE} + {$DEFINE STRING_UNICODE_MISMATCH} + {$ENDIF} +{$ENDIF} + +{$IFDEF DCC_NEXTGEN} + {$DEFINE NO_ANSI_TYPES} + {.$DEFINE STRING_IS_IMMUTABLE} // Strings are NOT immutable in NEXTGEN yet + {$IFDEF USE_OBJECT_ARC} + // TODO: move these to an appropriate section. Not doing this yet because + // it is a major interface change to switch to Generics and we should + // maintain backwards compatibility with earlier compilers for the time + // being. Defining them only here for now because the non-Generic versions + // of these classes have become deprecated by ARC and so we need to start + // taking advantage of the Generics versions... + {$DEFINE HAS_UNIT_Generics_Collections} + {$DEFINE HAS_UNIT_Generics_Defaults} + {$DEFINE HAS_GENERICS_TDictionary} + {$DEFINE HAS_GENERICS_TList} + {$DEFINE HAS_GENERICS_TObjectList} + {$DEFINE HAS_GENERICS_TThreadList} + // TArray.Copy() was introduced in XE7 but was buggy. It was fixed in XE8: + // + // RSP-9763 TArray.Copy copies from destination to source for unmanaged types + // https://quality.embarcadero.com/browse/RSP-9763 + // + {$IFDEF VCL_XE8_OR_ABOVE} + {$DEFINE HAS_GENERICS_TArray_Copy} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +// TODO: Ansi data types were disabled on mobile platforms in XE3, but +// UTF8String and RawByteString were re-enabled in 10.1 Berlin! What else, +// if anything, was re-enabled to facilitate that? +// +// UPDATE: In 10.4 Sydney, AnsiChar and AnsiString were re-enabled on +// mobile platforms! NEXTGEN is no longer defined in the mobile compilers. +{$IFDEF NO_ANSI_TYPES} + {$UNDEF HAS_AnsiString} + {$UNDEF HAS_AnsiChar} + {$UNDEF HAS_PAnsiChar} + {$UNDEF HAS_PPAnsiChar} + {$UNDEF HAS_AnsiStrings_StrPLCopy} + {$UNDEF HAS_AnsiStrings_StrLen} +{$ENDIF} + +{$IFDEF WIN32} + {$DEFINE WIN32_OR_WIN64} +{$ENDIF} +{$IFDEF WIN64} + {$DEFINE WIN32_OR_WIN64} +{$ENDIF} + +{$IFDEF WIN32_OR_WIN64} + {$DEFINE USE_ZLIB_UNIT} + {$IFNDEF DCC_NEXTGEN} + {$DEFINE USE_OPENSSL} // !!! MOVED HERE BY EMBT + {$DEFINE USE_SSPI} + {$IFDEF STRING_IS_UNICODE} + {$DEFINE SSPI_UNICODE} + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF WINCE} + {$DEFINE USE_OPENSSL} + // RLebeau: not sure if the above Win32/64 defines also apply to WinCE, + // so keeping them separate for now... +{$ENDIF} + +// High-performance counters are not reliable on multi-core systems, and have +// been known to cause problems with TIdIOHandler.ReadLn() timeouts in Windows +// XP SP3, both 32-bit and 64-bit. Refer to these discussions for more info: +// +// http://www.virtualdub.org/blog/pivot/entry.php?id=106 +// http://blogs.msdn.com/oldnewthing/archive/2008/09/08/8931563.aspx +// +// Do not enable thus unless you know it will work correctly on your systems! +{$IFDEF WINDOWS} + {.$DEFINE USE_HI_PERF_COUNTER_FOR_TICKS} +{$ENDIF} + +{$IFDEF UNIX} + {$DEFINE USE_OPENSSL} + {$DEFINE USE_ZLIB_UNIT} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF MACOS} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF DARWIN} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF LINUX} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF IOS} + {$DEFINE HAS_getifaddrs} + {$DEFINE USE_OPENSSL} + + // Support for 64-bit ARM iOS Simulator was added in Delphi 11.2 + // TODO: how to detect iOS Simulator in FPC? Does it support 64-bit ARM? + {$IFDEF CPUARM} + {$IFNDEF IOSSIMULATOR} + // RLebeau: For iOS devices, OpenSSL cannot be used as an external library, + // it must be statically linked into the app. For the iOS simulator, this + // is not true. Users who want to use OpenSSL in iOS device apps will need + // to add the static OpenSSL library to the project and then include the + // IdSSLOpenSSLHeaders_static unit in their uses clause. It hooks up the + // statically linked functions for the IdSSLOpenSSLHeaders unit to use... + {$DEFINE STATICLOAD_OPENSSL} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{$IFDEF FREEBSD} + {$DEFINE HAS_getifaddrs} +{$ENDIF} + +{$IFDEF ANDROID} + {$UNDEF HAS_getifaddrs} +{$ENDIF} + +{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} + {$DEFINE REQUIRES_PROPER_ALIGNMENT} +{$ENDIF} + +// +//iconv defines section. +{$DEFINE USE_ICONV_UNIT} +{$DEFINE USE_ICONV_ENC} +{$IFDEF UNIX} + {$DEFINE USE_ICONV} + {$IFDEF USE_BASEUNIX} + {$IFDEF FPC} + {$UNDEF USE_ICONV_UNIT} + {$ELSE} + {$UNDEF USE_ICONV_ENC} + {$ENDIF} + {$ENDIF} + {$IFDEF KYLIXCOMPAT} + //important!! Iconv functions are defined in the libc.pas Kylix compatible unit. + {$UNDEF USE_ICONV_ENC} + {$UNDEF USE_ICONV_UNIT} + {$ENDIF} +{$ENDIF} +{$IFDEF NETWARELIBC} + {$DEFINE USE_ICONV} + //important!!! iconv functions are defined in the libc.pas Novell Netware header. + //Do not define USE_ICONV_UNIT + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} +{$ENDIF} + +{$UNDEF USE_SAFELOADLIBRARY} +{$IFDEF WINDOWS} + {$UNDEF USE_ICONV_ENC} + {$DEFINE USE_SAFELOADLIBRARY} +{$ENDIF} +// Use here for all *nix systems that you do not want to use iconv library +{$IFDEF FPC} + {$IFDEF ANDROID} + {$UNDEF USE_ICONV} + {$DEFINE USE_LCONVENC} + {$ENDIF} +{$ENDIF} + +{$UNDEF USE_INVALIDATE_MOD_CACHE} +{$UNDEF USE_SAFELOADLIBRARY} +//This must come after the iconv defines because this compiler targets a Unix-like +//operating system. One key difference is that it does have a TEncoding class. +//If this comes before the ICONV defines, it creates problems. +//This also must go before the THandle size calculations. +{$IFDEF VCL_CROSS_COMPILE} + {$IFDEF POSIX} + {$IFNDEF LINUX} + {$DEFINE BSD} + {$ENDIF} + {$DEFINE USE_SAFELOADLIBRARY} + {$DEFINE USE_INVALIDATE_MOD_CACHE} + {$ENDIF} + //important!!! iconv functions are defined in the libc.pas Novell Netware header. + //Do not define USE_ICONVUNIT + {$UNDEF USE_ICONV} + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} + {$DEFINE INT_THREAD_PRIORITY} +{$ENDIF} + +{$IFNDEF USE_ICONV} + {$UNDEF USE_ICONV_UNIT} + {$UNDEF USE_ICONV_ENC} +{$ENDIF} + +//IMPORTANT!!!! +// +//Do not remove this!!! This is to work around a conflict. In DCC, MACOS +//will mean OS X. In FreePascal, the DEFINE MACOS means MacIntosh System OS Classic. +{$IFDEF DCC} + // DCC defines MACOS for both iOS and OS X platforms, need to differentiate + {$IFDEF MACOS} + {$IFNDEF IOS} + {$DEFINE OSX} + {$DEFINE DARWIN} + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF FPC} + // FPC defines DARWIN for both OSX and iOS, need to differentiate + {$IFDEF DARWIN} + {$IFNDEF IOS} + {$DEFINE OSX} + {$ENDIF} + {$ENDIF} + {$IFDEF MACOS} + {$DEFINE MACOS_CLASSIC} + {$ENDIF} +{$ENDIF} + +{ +BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit +word to an 8 bit byte and an 8 bit byte field named sa_len was added. +} +//Place this only after DARWIN has been defined for Delphi MACOS +{$IFDEF FREEBSD} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF DARWIN} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF MORPHOS} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} + +// Do NOT remove these IFDEF's. They are here because InterlockedExchange +// only handles 32bit values. Some Operating Systems may have 64bit +// THandles. This is not always tied to the platform architecture. + +{$IFDEF AMIGA} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF ATARI} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF BEOS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF BSD} + //I think BSD might handle FreeBSD, NetBSD, OpenBSD, and Darwin + {$IFDEF IOS} + {$IFDEF CPUARM64} + {$DEFINE CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$IFDEF CPUARM32} + {$DEFINE CPU32} + {$ENDIF} + {$DEFINE THANDLE_32} + {$ENDIF} + {$ENDIF} + {$IFDEF OSX} + {$IFDEF FPC} + {$DEFINE THANDLE_32} + {$ELSE} + {$DEFINE THANDLE_CPUBITS} // !!! ADDED OSX BY EMBT + {$ENDIF} + {$ENDIF} +{$ENDIF} +{$IFDEF EMBEDDED} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF EMX} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF GBA} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF GO32} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF LINUX} + {$IFDEF LINUX64} + {$DEFINE CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$IFDEF LINUX32} + {$DEFINE CPU32} + {$ENDIF} + {$DEFINE THANDLE_32} + {$ENDIF} +{$ENDIF} +{$IFDEF MACOS_CLASSIC} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF MORPHOS} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF NATIVENT} //Native NT for kernel level drivers + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} +{$IFDEF NDS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF NETWARE} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF NETWARELIBC} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF OS2} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF PALMOS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF SOLARIS} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF SYMBIAN} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WII} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WATCOM} + {$DEFINE THANDLE_32} +{$ENDIF} +{$IFDEF WINDOWS} + {$DEFINE THANDLE_CPUBITS} +{$ENDIF} + +// end platform specific stuff for THandle size + +{$IFDEF THANDLE_CPUBITS} + {$IFDEF CPU64} + {$DEFINE THANDLE_64} + {$ELSE} + {$DEFINE THANDLE_32} + {$ENDIF} +{$ENDIF} + +{$IFDEF DOTNET} + {$DEFINE DOTNET_OR_ICONV} +{$ENDIF} +{$IFDEF USE_ICONV} + {$DEFINE DOTNET_OR_ICONV} +{$ENDIF} + +{$UNDEF STREAM_SIZE_64} +{$IFDEF FPC} + {$DEFINE STREAM_SIZE_64} +{$ELSE} + {$IFDEF VCL_6_OR_ABOVE} + {$DEFINE STREAM_SIZE_64} + {$ENDIF} +{$ENDIF} + +{$IFNDEF FREE_ON_FINAL} + {$IFNDEF DOTNET} + {$IFDEF HAS_System_RegisterExpectedMemoryLeak} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_FASTMM4} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_MADEXCEPT} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$IFDEF USE_LEAKCHECK} + {$DEFINE REGISTER_EXPECTED_MEMORY_LEAK} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +{ +We must determine what the SocketType parameter is for the Socket function. +In DotNET, it's SocketType. In Kylix and the libc.pas Kylix-compatibility +library, it's a __socket_type. In BaseUnix, it's a C-type Integer. In Windows, +it's a LongInt. + +} +{$UNDEF SOCKETTYPE_IS_SOCKETTYPE} +{$UNDEF SOCKETTYPE_IS_CINT} +{$UNDEF SOCKETTYPE_IS___SOCKETTYPE} +{$UNDEF SOCKETTYPE_IS_LONGINT} +{$UNDEF SOCKETTYPE_IS_NUMERIC} +{$UNDEF SOCKET_LEN_IS_socklen_t} +{$IFDEF DOTNET} + {$DEFINE SOCKETTYPE_IS_SOCKETTYPE} +{$ENDIF} +{$IFDEF USE_BASEUNIX} + {$DEFINE SOCKETTYPE_IS_CINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF KYLIXCOMPAT} + {$DEFINE SOCKETTYPE_IS___SOCKETTYPE} +{$ENDIF} +{$IFDEF USE_VCL_POSIX} + {$DEFINE SOCKETTYPE_IS_NUMERIC} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKET_LEN_IS_socklen_t} +{$ENDIF} +{$IFDEF WINDOWS} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF OS2} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} +{$IFDEF NETWARE} + {$DEFINE SOCKETTYPE_IS_LONGINT} + {$DEFINE SOCKETTYPE_IS_NUMERIC} +{$ENDIF} + +{Take advantage of some TCP features specific to some stacks. +They work somewhat similarly but there's a key difference. +In Linux, TCP_CORK is turned on to send fixed packet sizes and +when turned-off (uncorked), any remaining data is sent. With +TCP_NOPUSH, this might not happen and remaining data is only sent +before disconnect. TCP_KEEPIDLE and TCP_KEEPINTVL so the IFDEF LINUX and IFDEF +SOLARIS instead of IFDEF UNIX is not an error, it's deliberate.} +{$UNDEF HAS_TCP_NOPUSH} +{$UNDEF HAS_TCP_CORK} +{$UNDEF HAS_TCP_KEEPIDLE} +{$UNDEF HAS_TCP_KEEPINTVL} +{$UNDEF HAS_SOCKET_NOSIGPIPE} +{$IFDEF BSD} + {$DEFINE HAS_TCP_NOPUSH} +{$ENDIF} +{$IFDEF HAIKU} + {$DEFINE HAS_TCP_NOPUSH} +{$ENDIF} +{$IFDEF LINUX} + {$DEFINE HAS_TCP_CORK} + {$DEFINE HAS_TCP_KEEPIDLE} + {$DEFINE HAS_TCP_KEEPINTVL} +{$ENDIF} +{$IFDEF SOLARIS} + {$DEFINE HAS_TCP_CORK} +{$ENDIF} +{$IFDEF NETBSD} + {$DEFINE HAS_TCP_CORK} + {$DEFINE HAS_TCP_KEEPIDLE} + {$DEFINE HAS_TCP_KEEPINTVL} +{$ENDIF} +{$IFDEF USE_VCL_POSIX} + // TODO: which platforms actually have SO_NOSIGPIPE available? + {$DEFINE HAS_SOCKET_NOSIGPIPE} + {$IFDEF ANDROID} + {$UNDEF HAS_SOCKET_NOSIGPIPE} + {$ENDIF} + {$IFDEF LINUX} + {$UNDEF HAS_SOCKET_NOSIGPIPE} + {$ENDIF} +{$ENDIF} +{end Unix OS specific stuff} +{$IFDEF DEBUG} + {$UNDEF USE_INLINE} +{$ENDIF} + +// RLebeau 5/24/2015: In C++Builder 2006 and 2007, UInt64 is emitted as +// signed __int64 in HPP files instead of as unsigned __int64. This causes +// conflicts in overloaded routines that have (U)Int64 parameters. This +// was fixed in C++Builder 2009. For compilers that do not have a native +// UInt64 type, or for C++Builder 2006/2007, let's define a record type +// that can hold UInt64 values... +{$IFDEF HAS_UInt64} + {$IFDEF BROKEN_UINT64_HPPEMIT} + {$DEFINE TIdUInt64_HAS_QuadPart} + {$ENDIF} +{$ELSE} + {$IFNDEF HAS_QWord} + {$DEFINE TIdUInt64_HAS_QuadPart} + {$ENDIF} +{$ENDIF} + +// RLebeau 9/5/2013: it would take a lot of work to re-write Indy to support +// both 0-based and 1-based string indexing, so we'll just turn off 0-based +// indexing for now... +{$IFDEF HAS_DIRECTIVE_ZEROBASEDSTRINGS} + {$ZEROBASEDSTRINGS OFF} +{$ENDIF} diff --git a/Lib/System/IdStack.pas b/Lib/System/IdStack.pas index b0bc5b9df..016243b30 100644 --- a/Lib/System/IdStack.pas +++ b/Lib/System/IdStack.pas @@ -1,1246 +1,1246 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.7 1/17/2005 7:25:48 PM JPMugaas - Moved some stack management code here to so that we can reuse it in - non-TIdComponent classes. - Made HostToNetwork and NetworkToHost byte order overload functions for IPv6 - addresses. - - Rev 1.6 10/26/2004 8:12:30 PM JPMugaas - Now uses TIdStrings and TIdStringList for portability. - - Rev 1.5 6/30/2004 12:41:14 PM BGooijen - Added SetStackClass - - Rev 1.4 6/11/2004 8:28:50 AM DSiders - Added "Do not Localize" comments. - - Rev 1.3 4/18/04 2:45:38 PM RLebeau - Conversion support for Int64 values - - Rev 1.2 2004.03.07 11:45:22 AM czhower - Flushbuffer fix + other minor ones found - - Rev 1.1 3/6/2004 5:16:20 PM JPMugaas - Bug 67 fixes. Do not write to const values. - - Rev 1.0 2004.02.03 3:14:42 PM czhower - Move and updates - - Rev 1.39 2/1/2004 6:10:50 PM JPMugaas - GetSockOpt. - - Rev 1.38 2/1/2004 3:28:24 AM JPMugaas - Changed WSGetLocalAddress to GetLocalAddress and moved into IdStack since - that will work the same in the DotNET as elsewhere. This is required to - reenable IPWatch. - - Rev 1.37 2/1/2004 1:54:56 AM JPMugaas - Missapplied fix. IP 0.0.0.0 should now be accepted. - - Rev 1.36 1/31/2004 4:39:12 PM JPMugaas - Removed empty methods. - - Rev 1.35 1/31/2004 1:13:04 PM JPMugaas - Minor stack changes required as DotNET does support getting all IP addresses - just like the other stacks. - - Rev 1.34 2004.01.22 5:59:10 PM czhower - IdCriticalSection - - Rev 1.33 1/18/2004 11:15:52 AM JPMugaas - IsIP was not handling "0" in an IP address. This caused the address - "127.0.0.1" to be treated as a hostname. - - Rev 1.32 12/4/2003 3:14:50 PM BGooijen - Added HostByAddress - - Rev 1.31 1/3/2004 12:21:44 AM BGooijen - Added function SupportsIPv6 - - Rev 1.30 12/31/2003 9:54:16 PM BGooijen - Added IPv6 support - - Rev 1.29 2003.12.31 3:47:42 PM czhower - Changed to use TextIsSame - - Rev 1.28 10/21/2003 9:24:32 PM BGooijen - Started on SendTo, ReceiveFrom - - Rev 1.27 10/19/2003 5:21:28 PM BGooijen - SetSocketOption - - Rev 1.26 10/15/2003 7:21:02 PM DSiders - Added resource strings in TIdStack.Make. - - Rev 1.25 2003.10.11 5:51:02 PM czhower - -VCL fixes for servers - -Chain suport for servers (Super core) - -Scheduler upgrades - -Full yarn support - - Rev 1.24 10/5/2003 9:55:30 PM BGooijen - TIdTCPServer works on D7 and DotNet now - - Rev 1.23 04/10/2003 22:31:56 HHariri - moving of WSNXXX method to IdStack and renaming of the DotNet ones - - Rev 1.22 10/2/2003 7:31:18 PM BGooijen - .net - - Rev 1.21 10/2/2003 6:05:16 PM GGrieve - DontNet - - Rev 1.20 2003.10.02 10:16:30 AM czhower - .Net - - Rev 1.19 2003.10.01 9:11:20 PM czhower - .Net - - Rev 1.18 2003.10.01 5:05:16 PM czhower - .Net - - Rev 1.17 2003.10.01 2:30:40 PM czhower - .Net - - Rev 1.16 2003.10.01 12:30:08 PM czhower - .Net - - Rev 1.14 2003.10.01 1:37:36 AM czhower - .Net - - Rev 1.12 9/30/2003 7:15:46 PM BGooijen - IdCompilerDefines.inc is included now - - Rev 1.11 2003.09.30 1:23:04 PM czhower - Stack split for DotNet -} - -unit IdStack; - -interface - -{$I IdCompilerDefines.inc} - -uses - Classes, - IdException, IdStackConsts, IdGlobal, SysUtils; - -type - EIdSocketError = class(EIdException) - protected - FLastError: Integer; - public - // Params must be in this order to avoid conflict with CreateHelp - // constructor in CBuilder as CB does not differentiate constructors - // by name as Delphi does - constructor CreateError(const AErr: Integer; const AMsg: string); virtual; - // - property LastError: Integer read FLastError; - end; - - { resolving hostnames } - EIdStackError = class (EIdException); - EIdIPVersionUnsupported = class (EIdStackError); - {$IFDEF UNIX} - EIdResolveError = class(EIdSocketError); - EIdReverseResolveError = class(EIdSocketError); - EIdMaliciousPtrRecord = class(EIdReverseResolveError); - {$ELSE} - EIdMaliciousPtrRecord = class(EIdSocketError); - {$ENDIF} - - EIdNotASocket = class(EIdSocketError); - - // TODO: move this to IdStackVCLPosix... - {$IFDEF USE_VCL_POSIX} - {$IFDEF ANDROID} - EIdAndroidPermissionNeeded = class(EIdSocketError); - EIdInternetPermissionNeeded = class(EIdAndroidPermissionNeeded); - {$ENDIF} - {$ENDIF} - - TIdServeFile = function(ASocket: TIdStackSocketHandle; const AFileName: string): Int64; - - TIdPacketInfo = class - protected - FSourceIP: String; - FSourcePort : TIdPort; - FSourceIF: UInt32; - FSourceIPVersion: TIdIPVersion; - FDestIP: String; - FDestPort : TIdPort; - FDestIF: UInt32; - FDestIPVersion: TIdIPVersion; - FTTL: Byte; - public - procedure Reset; - - property TTL : Byte read FTTL write FTTL; - //The computer that sent it to you - property SourceIP : String read FSourceIP write FSourceIP; - property SourcePort : TIdPort read FSourcePort write FSourcePort; - property SourceIF : UInt32 read FSourceIF write FSourceIF; - property SourceIPVersion : TIdIPVersion read FSourceIPVersion write FSourceIPVersion; - //you, the receiver - this is provided for multihomed machines - property DestIP : String read FDestIP write FDestIP; - property DestPort : TIdPort read FDestPort write FDestPort; - property DestIF : UInt32 read FDestIF write FDestIF; - property DestIPVersion : TIdIPVersion read FDestIPVersion write FDestIPVersion; - end; - - // Descend from only TObject. This objects is created a lot and should be fast - // and small - TIdSocketList = class(TObject) - protected - FLock: TIdCriticalSection; - // - function GetItem(AIndex: Integer): TIdStackSocketHandle; virtual; abstract; - public - constructor Create; virtual; - destructor Destroy; override; - procedure Add(AHandle: TIdStackSocketHandle); virtual; abstract; - function Clone: TIdSocketList; virtual; abstract; - function Count: Integer; virtual; abstract; - class function CreateSocketList: TIdSocketList; - property Items[AIndex: Integer]: TIdStackSocketHandle read GetItem; default; - procedure Remove(AHandle: TIdStackSocketHandle); virtual; abstract; - procedure Clear; virtual; abstract; - function ContainsSocket(AHandle: TIdStackSocketHandle): boolean; virtual; abstract; - procedure Lock; - class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; - AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; virtual; - function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; virtual; abstract; - function SelectReadList(var VSocketList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; virtual; abstract; - procedure Unlock; - end; - - TIdSocketListClass = class of TIdSocketList; - - TIdStackLocalAddress = class(TCollectionItem) - protected - FIPVersion: TIdIPVersion; - FIPAddress: String; - FInterfaceName: String; - FInterfaceIndex: UInt32; - FDescription: String; - FFriendlyName: String; - public - constructor Create(ACollection: TCollection; const AIPVersion: TIdIPVersion; const AIPAddress: string); reintroduce; - property IPVersion: TIdIPVersion read FIPVersion; - property IPAddress: String read FIPAddress; - property InterfaceName: String read FInterfaceName; - property InterfaceIndex: UInt32 read FInterfaceIndex; - property Description: String read FDescription; - property FriendlyName: String read FFriendlyName; - end; - - TIdStackLocalAddressIPv4 = class(TIdStackLocalAddress) - protected - FSubNetMask: String; - public - constructor Create(ACollection: TCollection; const AIPAddress, ASubNetMask: string); reintroduce; - property SubNetMask: String read FSubNetMask; - // TODO: add BroadcastIP - end; - - TIdStackLocalAddressIPv6 = class(TIdStackLocalAddress) - public - constructor Create(ACollection: TCollection; const AIPAddress: string); reintroduce; - end; - - TIdStackLocalAddressList = class(TCollection) - protected - function GetAddress(AIndex: Integer): TIdStackLocalAddress; - public - constructor Create; reintroduce; - function IndexOfIP(const AIP: String): Integer; overload; - function IndexOfIP(const AIP: String; AIPVersion: TIdIPVersion): Integer; overload; - property Addresses[AIndex: Integer]: TIdStackLocalAddress read GetAddress; default; - end; - - TIdStack = class(TObject) - protected - FLocalAddresses: TStrings; - // - procedure IPVersionUnsupported; - function HostByName(const AHostName: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; virtual; abstract; - function MakeCanonicalIPv6Address(const AAddr: string): string; {$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use IdGlobal.MakeCanonicalIPv6Address()'{$ENDIF};{$ENDIF} - function ReadHostName: string; virtual; abstract; - function GetLocalAddress: string; - function GetLocalAddresses: TStrings; - public - function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort): TIdStackSocketHandle; overload; - function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; - var VIPVersion: TIdIPVersion): TIdStackSocketHandle; overload; virtual; abstract; - procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION ); virtual; abstract; - procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual; abstract; - constructor Create; virtual; - destructor Destroy; override; - procedure Disconnect(ASocket: TIdStackSocketHandle); virtual; abstract; - function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; - var arg: UInt32): Integer; virtual; abstract; - class procedure IncUsage; //create stack if necessary and inc counter - class procedure DecUsage; //decrement counter and free if it gets to zero - procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort); overload; - procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); overload; virtual; abstract; - procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort); overload; - procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); overload; virtual; abstract; - function HostByAddress(const AAddress: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; virtual; abstract; - function HostToNetwork(AValue: UInt16): UInt16; overload; virtual; abstract; - function HostToNetwork(AValue: UInt32): UInt32; overload; virtual; abstract; - function HostToNetwork(AValue: TIdUInt64): TIdUInt64; overload; virtual; abstract; - function HostToNetwork(const AValue: TIdIPv6Address): TIdIPv6Address; overload; virtual; - function IsIP(AIP: string): Boolean; - procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); virtual; abstract; - function WSGetLastError: Integer; virtual; abstract; - procedure WSSetLastError(const AErr : Integer); virtual; abstract; - function WSTranslateSocketErrorMsg(const AErr: integer): string; virtual; - function CheckForSocketError(const AResult: Integer): Integer; overload; - function CheckForSocketError(const AResult: Integer; const AIgnore: array of Integer): Integer; overload; - procedure RaiseLastSocketError; - procedure RaiseSocketError(AErr: integer); virtual; - function NewSocketHandle(const ASocketType: TIdSocketType; const AProtocol: TIdSocketProtocol; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION; const ANonBlocking: Boolean = False) - : TIdStackSocketHandle; virtual; abstract; - function NetworkToHost(AValue: UInt16): UInt16; overload; virtual; abstract; - function NetworkToHost(AValue: UInt32): UInt32; overload; virtual; abstract; - function NetworkToHost(AValue: TIdUInt64): TIdUInt64; overload; virtual; abstract; - function NetworkToHost(const AValue: TIdIPv6Address): TIdIPv6Address; overload; virtual; - procedure GetSocketOption(ASocket: TIdStackSocketHandle; - ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; - out AOptVal: Integer); overload; virtual; abstract; - procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; AOptVal: Integer); overload; virtual; abstract; - function ResolveHost(const AHost: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; - - // Result: - // > 0: Number of bytes received - // 0: Connection closed gracefully - // Will raise exceptions in other cases - function Receive(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes): Integer; virtual; abstract; - function Send(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; - const AOffset: Integer = 0; const ASize: Integer = -1): Integer; virtual; abstract; - - function ReceiveFrom(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; virtual; abstract; - function SendTo(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; - const AOffset: Integer; const AIP: string; const APort: TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): Integer; overload; - function SendTo(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; - const AOffset: Integer; const ASize: Integer; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION) - : Integer; overload; virtual; abstract; - function ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; - APkt: TIdPacketInfo): UInt32; virtual; abstract; - function SupportsIPv4: Boolean; virtual; abstract; - function SupportsIPv6: Boolean; virtual; abstract; - - //multicast stuff Kudzu permitted me to add here. - function IsValidIPv4MulticastGroup(const Value: string): Boolean; - function IsValidIPv6MulticastGroup(const Value: string): Boolean; - procedure SetKeepAliveValues(ASocket: TIdStackSocketHandle; - const AEnabled: Boolean; const ATimeMS, AInterval: Integer); virtual; - procedure SetMulticastTTL(AHandle: TIdStackSocketHandle; - const AValue : Byte; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual; abstract; - procedure SetLoopBack(AHandle: TIdStackSocketHandle; const AValue: Boolean; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual; abstract; - procedure DropMulticastMembership(AHandle: TIdStackSocketHandle; - const AGroupIP, ALocalIP : String; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual; abstract; - procedure AddMulticastMembership(AHandle: TIdStackSocketHandle; - const AGroupIP, ALocalIP : String; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual; abstract; - //I know this looks like an odd place to put a function for calculating a - //packet checksum. There is a reason for it though. The reason is that - //you need it for ICMPv6 and in Windows, you do that with some other stuff - //in the stack descendants - function CalcCheckSum(const AData : TIdBytes): UInt16; virtual; - //In Windows, this writes a checksum into a buffer. In Linux, it would probably - //simply have the kernal write the checksum with something like this (RFC 2292): - // - // int offset = 2; - // setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)); - // - // Note that this should be called - //IMMEDIATELY before you do a SendTo because the Local IPv6 address might change - procedure WriteChecksum(s : TIdStackSocketHandle; - var VBuffer : TIdBytes; const AOffset : Integer; const AIP : String; - const APort : TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual; abstract; - // - procedure AddLocalAddressesToList(AAddresses: TStrings); {$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'use GetLocalAddressList()'{$ENDIF};{$ENDIF} - procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); virtual; abstract; - // - // Properties - // - property HostName: string read ReadHostName; - property LocalAddress: string read GetLocalAddress; // {$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'use GetLocalAddressList()'{$ENDIF};{$ENDIF} - property LocalAddresses: TStrings read GetLocalAddresses; // {$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'use GetLocalAddressList()'{$ENDIF};{$ENDIF} - end; - - TIdStackClass = class of TIdStack; - -var - GStack: TIdStack = nil; - GServeFileProc: TIdServeFile = nil; - GSocketListClass: TIdSocketListClass; - -// Procedures - procedure SetStackClass( AStackClass: TIdStackClass ); - -// TODO: move this to IdStackVCLPosix... -{$IFDEF USE_VCL_POSIX} - {$IFDEF ANDROID} -function HasAndroidPermission(const Permission: string): Boolean; - {$ENDIF} -{$ENDIF} - -implementation - -{$O-} - -uses - //done this way so we can have a separate stack for FPC under Unix systems - {$IFDEF DOTNET} - IdStackDotNet, - {$ELSE} - {$IFDEF WINDOWS} - {$IFDEF USE_INLINE} - Windows, - {$ENDIF} - IdStackWindows, - {$ELSE} - {$IFDEF USE_VCL_POSIX} - IdStackVCLPosix, - {$ELSE} - {$IFDEF UNIX} - {$IFDEF KYLIXCOMPAT} - IdStackLibc, - {$ELSE} - {$IFDEF USE_BASEUNIX} - IdStackUnix, - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} - - // TODO: move this to IdStackVCLPosix... - {$IFDEF USE_VCL_POSIX} - {$IFDEF ANDROID} - {$IFNDEF VCL_XE6_OR_ABOVE} - // StringToJString() is here in XE5 - Androidapi.JNI.JavaTypes, - {$ENDIF} - {$IFNDEF VCL_XE7_OR_ABOVE} - // SharedActivityContext() is here in XE5 and XE6 - FMX.Helpers.Android, - {$ENDIF} - {$IFDEF VCL_XE6_OR_ABOVE} - {$IFDEF VCL_10_0_OR_ABOVE} - // StringToJString() is inline in Seattle and later, so we need JavaTypes again... - Androidapi.JNI.JavaTypes, - {$ENDIF} - // StringToJString() was moved here in XE6 - // SharedActivityContext() was moved here in XE7 - // TAndroidHelper was added here in Seattle - Androidapi.Helpers, - {$ENDIF} - Androidapi.JNI.GraphicsContentViewText, - {$ENDIF} - {$ENDIF} - - IdResourceStrings; - -var - GStackClass: TIdStackClass = nil; - -var - {$IFNDEF USE_OBJECT_ARC} - GInstanceCount: UInt32 = 0; - {$ENDIF} - GStackCriticalSection: TIdCriticalSection = nil; - -//for IPv4 Multicast address chacking -const - IPv4MCastLo = 224; - IPv4MCastHi = 239; - -procedure SetStackClass(AStackClass: TIdStackClass); -begin - GStackClass := AStackClass; -end; - -procedure TIdPacketInfo.Reset; -begin - FSourceIP := ''; - FSourcePort := 0; - FSourceIF := 0; - FSourceIPVersion := ID_DEFAULT_IP_VERSION; - FDestIP := ''; - FDestPort:= 0; - FDestIF := 0; - FDestIPVersion := ID_DEFAULT_IP_VERSION; - FTTL := 0; -end; - -{ TIdSocketList } - -constructor TIdSocketList.Create; -begin - inherited Create; - FLock := TIdCriticalSection.Create; -end; - -class function TIdSocketList.CreateSocketList: TIdSocketList; -Begin - Result := GSocketListClass.Create; -End; - -destructor TIdSocketList.Destroy; -begin - FreeAndNil(FLock); - inherited Destroy; -end; - -procedure TIdSocketList.Lock; -begin - FLock.Acquire; -end; - -class function TIdSocketList.Select(AReadList, AWriteList, - AExceptList: TIdSocketList; const ATimeout: Integer): Boolean; -begin - // C++ Builder cannot have abstract class functions thus we need this base - Result := False; -end; - -procedure TIdSocketList.Unlock; -begin - FLock.Release; -end; - -{ EIdSocketError } - -constructor EIdSocketError.CreateError(const AErr: Integer; const AMsg: string); -begin - inherited Create(AMsg); - FLastError := AErr; -end; - -{ TIdStackLocalAddressList } - -constructor TIdStackLocalAddress.Create(ACollection: TCollection; const AIPVersion: TIdIPVersion; const AIPAddress: string); -begin - inherited Create(ACollection); - FIPVersion := AIPVersion; - FIPAddress := AIPAddress; - FInterfaceIndex := 0; -end; - -constructor TIdStackLocalAddressIPv4.Create(ACollection: TCollection; const AIPAddress, ASubNetMask: string); -begin - inherited Create(ACollection, Id_IPv4, AIPAddress); - FSubNetMask := ASubNetMask; -end; - -constructor TIdStackLocalAddressIPv6.Create(ACollection: TCollection; const AIPAddress: string); -begin - inherited Create(ACollection, Id_IPv6, AIPAddress); -end; - -constructor TIdStackLocalAddressList.Create; -begin - inherited Create(TIdStackLocalAddress); -end; - -function TIdStackLocalAddressList.GetAddress(AIndex: Integer): TIdStackLocalAddress; -begin - Result := TIdStackLocalAddress(inherited Items[AIndex]); -end; - -function TIdStackLocalAddressList.IndexOfIP(const AIP: String): Integer; -var - I: Integer; -begin - Result := -1; - for I := 0 to Count-1 do begin - if Addresses[I].IPAddress = AIP then begin - Result := I; - Exit; - end; - end; -end; - -function TIdStackLocalAddressList.IndexOfIP(const AIP: String; AIPVersion: TIdIPVersion): Integer; -var - I: Integer; - LAddr: TIdStackLocalAddress; -begin - Result := -1; - for I := 0 to Count-1 do begin - LAddr := Addresses[I]; - if (LAddr.IPVersion = AIPVersion) and (LAddr.IPAddress = AIP) then begin - Result := I; - Exit; - end; - end; -end; - -{ TIdStack } - -constructor TIdStack.Create; -begin - // Here for .net - inherited Create; -end; - -destructor TIdStack.Destroy; -begin - FreeAndNil(FLocalAddresses); - inherited Destroy; -end; - -procedure TIdStack.IPVersionUnsupported; -begin - raise EIdIPVersionUnsupported.Create(RSIPVersionUnsupported); -end; - -function TIdStack.Accept(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort): TIdStackSocketHandle; -var - LIPVersion: TIdIPVersion; -begin - Result := Accept(ASocket, VIP, VPort, LIPVersion); -end; - -procedure TIdStack.GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort); -var - LIPVersion: TIdIPVersion; -begin - GetPeerName(ASocket, VIP, VPort, LIPVersion); -end; - -procedure TIdStack.GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort); -var - LIPVersion: TIdIPVersion; -begin - GetSocketName(ASocket, VIP, VPort, LIPVersion); -end; - -{$I IdDeprecatedImplBugOff.inc} -procedure TIdStack.AddLocalAddressesToList(AAddresses: TStrings); -{$I IdDeprecatedImplBugOn.inc} -var - LList: TIdStackLocalAddressList; - I: Integer; -begin - LList := TIdStackLocalAddressList.Create; - try - // for backwards compatibility, return only IPv4 addresses - GetLocalAddressList(LList); - if LList.Count > 0 then begin - AAddresses.BeginUpdate; - try - for I := 0 to LList.Count-1 do begin - if LList[I].IPVersion = Id_IPv4 then begin - AAddresses.Add(LList[I].IPAddress); - end; - end; - finally - AAddresses.EndUpdate; - end; - end; - finally - LList.Free; - end; -end; - -function TIdStack.GetLocalAddresses: TStrings; -var - LList: TIdStackLocalAddressList; - I: Integer; -begin - if FLocalAddresses = nil then begin - FLocalAddresses := TStringList.Create; - end; - FLocalAddresses.BeginUpdate; - try - FLocalAddresses.Clear; - LList := TIdStackLocalAddressList.Create; - try - // for backwards compatibility, return only IPv4 addresses - GetLocalAddressList(LList); - for I := 0 to LList.Count-1 do begin - if LList[I].IPVersion = Id_IPv4 then begin - FLocalAddresses.Add(LList[I].IPAddress); - end; - end; - finally - LList.Free; - end; - finally - FLocalAddresses.EndUpdate; - end; - Result := FLocalAddresses; -end; - -function TIdStack.GetLocalAddress: string; -var - LList: TIdStackLocalAddressList; - I: Integer; -begin - // RLebeau: using a local list instead of the LocalAddresses - // property so this method can be thread-safe... - // - // old code: - // Result := LocalAddresses[0]; - - Result := ''; - LList := TIdStackLocalAddressList.Create; - try - // for backwards compatibility, return only IPv4 addresses - GetLocalAddressList(LList); - for I := 0 to LList.Count-1 do begin - if LList[I].IPVersion = Id_IPv4 then begin - Result := LList[I].IPAddress; - Exit; - end; - end; - finally - LList.Free; - end; -end; - -function TIdStack.IsIP(AIP: string): Boolean; -var - i: Integer; -begin - // TODO: support IPv6 - -// -//Result := Result and ((i > 0) and (i < 256)); -// - i := IndyStrToInt(Fetch(AIP, '.'), -1); {Do not Localize} - Result := (i > -1) and (i < 256); - i := IndyStrToInt(Fetch(AIP, '.'), -1); {Do not Localize} - Result := Result and ((i > -1) and (i < 256)); - i := IndyStrToInt(Fetch(AIP, '.'), -1); {Do not Localize} - Result := Result and ((i > -1) and (i < 256)); - i := IndyStrToInt(Fetch(AIP, '.'), -1); {Do not Localize} - Result := Result and ((i > -1) and (i < 256)) and (AIP = ''); -end; - -{$I IdDeprecatedImplBugOff.inc} -function TIdStack.MakeCanonicalIPv6Address(const AAddr: string): string; -{$I IdDeprecatedImplBugOn.inc} -begin - Result := IdGlobal.MakeCanonicalIPv6Address(AAddr); -end; - -function TIdStack.ResolveHost(const AHost: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; -begin - Result := ''; - case AIPVersion of - Id_IPv4: begin - // Sometimes 95 forgets who localhost is - if TextIsSame(AHost, 'LOCALHOST') then begin {Do not Localize} - Result := '127.0.0.1'; {Do not Localize} - end else if IsIP(AHost) then begin - Result := AHost; - end else begin - Result := HostByName(AHost, Id_IPv4); - end; - end; - Id_IPv6: begin - if TextIsSame(AHost, 'LOCALHOST') then begin {Do not Localize} - Result := '::1'; {Do not Localize} - end else begin - Result := IdGlobal.MakeCanonicalIPv6Address(AHost); - if Result = '' then begin - Result := HostByName(AHost, Id_IPv6); - end; - end; - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -function TIdStack.SendTo(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; - const AOffset: Integer; const AIP: string; const APort: TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): Integer; -begin - Result := SendTo(ASocket, ABuffer, AOffset, -1, AIP, APort, AIPVersion); -end; - -class procedure TIdStack.DecUsage; -var - // under ARC, increment the lock's reference count before working with it - LLock: TIdCriticalSection; -begin - LLock := GStackCriticalSection; - if not Assigned(LLock) then begin - raise EIdStackError.Create('GStackCriticalSection is nil in TIdStack.DecUsage'); {do not localize} - end; - LLock.Acquire; - try - // This CS will guarantee that during the FreeAndNil nobody - // will try to use or construct GStack - {$IFDEF USE_OBJECT_ARC} - if GStack <> nil then begin - if GStack.__ObjRelease = 0 then begin - Pointer(GStack) := nil; - end; - end; - {$ELSE} - if GInstanceCount > 0 then begin - Dec(GInstanceCount); - if GInstanceCount = 0 then begin - FreeAndNil(GStack); - end; - end; - {$ENDIF} - finally - LLock.Release; - end; -end; - -class procedure TIdStack.IncUsage; -var - // under ARC, increment the lock's reference count before working with it - LLock: TIdCriticalSection; -begin - LLock := GStackCriticalSection; - if not Assigned(LLock) then begin - raise EIdStackError.Create('GStackCriticalSection is nil in TIdStack.IncUsage'); {do not localize} - end; - LLock.Acquire; - try - {$IFDEF USE_OBJECT_ARC} - if GStack = nil then begin - if GStackClass = nil then begin - raise EIdStackError.Create(RSStackClassUndefined); - end; - GStack := GStackClass.Create; - end else begin - GStack.__ObjAddRef; - end; - {$ELSE} - if GInstanceCount = 0 then begin - if GStack <> nil then begin - raise EIdStackError.Create(RSStackAlreadyCreated); - end; - if GStackClass = nil then begin - raise EIdStackError.Create(RSStackClassUndefined); - end; - GStack := GStackClass.Create; - end; - Inc(GInstanceCount); - {$ENDIF} - finally - LLock.Release; - end; -end; - -function TIdStack.CheckForSocketError(const AResult: Integer): Integer; -begin - if AResult = Integer(Id_SOCKET_ERROR) then begin - RaiseLastSocketError; - end; - Result := AResult; -end; - -function TIdStack.CheckForSocketError(const AResult: Integer; - const AIgnore: array of integer): Integer; -var - i: Integer; - LLastError: Integer; -begin - Result := AResult; - if AResult = Integer(Id_SOCKET_ERROR) then begin - LLastError := WSGetLastError; - for i := Low(AIgnore) to High(AIgnore) do begin - if LLastError = AIgnore[i] then begin - Result := LLastError; - Exit; - end; - end; - RaiseSocketError(LLastError); - end; -end; - -procedure TIdStack.RaiseLastSocketError; -begin - RaiseSocketError(WSGetLastError); -end; - -// TODO: move this to IdStackVCLPosix... -{$IFDEF USE_VCL_POSIX} - {$IFDEF ANDROID} -function GetActivityContext: JContext; {$IFDEF USE_INLINE}inline;{$ENDIF} -begin - {$IFDEF HAS_TAndroidHelper} - Result := TAndroidHelper.Context; - {$ELSE} - Result := SharedActivityContext; - {$ENDIF} -end; - -function HasAndroidPermission(const Permission: string): Boolean; -begin - Result := GetActivityContext.checkCallingOrSelfPermission(StringToJString(Permission)) = TJPackageManager.JavaClass.PERMISSION_GRANTED; -end; - {$ENDIF} -{$ENDIF} - -procedure TIdStack.RaiseSocketError(AErr: integer); -begin - (* - RRRRR EEEEEE AAAA DDDDD MM MM EEEEEE !! !! !! - RR RR EE AA AA DD DD MMMM MMMM EE !! !! !! - RRRRR EEEE AAAAAA DD DD MM MMM MM EEEE !! !! !! - RR RR EE AA AA DD DD MM MM EE - RR RR EEEEEE AA AA DDDDD MM MM EEEEEE .. .. .. - - Please read the note in the next comment. - *) - if AErr = Id_WSAENOTSOCK then begin - // You can add this to your exception ignore list for easier debugging. - // However please note that sometimes it is a true error. Your program - // will still run correctly, but the debugger will not stop on it if you - // list it in the ignore list. But for most times its fine to put it in - // the ignore list, it only affects your debugging. - raise EIdNotASocket.CreateError(AErr, WSTranslateSocketErrorMsg(AErr)); - end; - - // TODO: move this to IdStackVCLPosix... - {$IFDEF USE_VCL_POSIX} - {$IFDEF ANDROID} - if (AErr = 9{EBADF}) or (AErr = 12{EBADR?}) or (AErr = 13{EACCES}) then begin - if not HasAndroidPermission('android.permission.INTERNET') then begin {Do not Localize} - raise EIdInternetPermissionNeeded.CreateError(AErr, WSTranslateSocketErrorMsg(AErr)); - end; - end; - {$ENDIF} - {$ENDIF} - - (* - It is normal to receive a 10038 exception (10038, NOT others!) here when - *shutting down* (NOT at other times!) servers (NOT clients!). - - If you receive a 10038 exception here please see the FAQ at: - http://www.IndyProject.org/ - - If you insist upon requesting help via our email boxes on the 10038 error - that is already answered in the FAQ and you are simply too slothful to - search for your answer and ask your question in the public forums you may be - publicly flogged, tarred and feathered and your name may be added to every - chain letter / EMail in existence today." - - Otherwise, if you DID read the FAQ and have further questions, please feel - free to ask using one of the methods (Carefullly note that these methods do - not list email) listed on the Tech Support link at: - http://www.IndyProject.org/ - - RRRRR EEEEEE AAAA DDDDD MM MM EEEEEE !! !! !! - RR RR EE AA AA DD DD MMMM MMMM EE !! !! !! - RRRRR EEEE AAAAAA DD DD MM MMM MM EEEE !! !! !! - RR RR EE AA AA DD DD MM MM EE - RR RR EEEEEE AA AA DDDDD MM MM EEEEEE .. .. .. - *) - raise EIdSocketError.CreateError(AErr, WSTranslateSocketErrorMsg(AErr)); -end; - -function TIdStack.WSTranslateSocketErrorMsg(const AErr: integer): string; -begin - Result := ''; {Do not Localize} - case AErr of - Id_WSAEINTR: Result := RSStackEINTR; - Id_WSAEBADF: Result := RSStackEBADF; - Id_WSAEACCES: Result := RSStackEACCES; - Id_WSAEFAULT: Result := RSStackEFAULT; - Id_WSAEINVAL: Result := RSStackEINVAL; - Id_WSAEMFILE: Result := RSStackEMFILE; - Id_WSAEWOULDBLOCK: Result := RSStackEWOULDBLOCK; - Id_WSAEINPROGRESS: Result := RSStackEINPROGRESS; - Id_WSAEALREADY: Result := RSStackEALREADY; - Id_WSAENOTSOCK: Result := RSStackENOTSOCK; - Id_WSAEDESTADDRREQ: Result := RSStackEDESTADDRREQ; - Id_WSAEMSGSIZE: Result := RSStackEMSGSIZE; - Id_WSAEPROTOTYPE: Result := RSStackEPROTOTYPE; - Id_WSAENOPROTOOPT: Result := RSStackENOPROTOOPT; - - Id_WSAEPROTONOSUPPORT: Result := RSStackEPROTONOSUPPORT; - {$IFNDEF BEOS} - Id_WSAESOCKTNOSUPPORT: Result := RSStackESOCKTNOSUPPORT; - {$ENDIF} - Id_WSAEOPNOTSUPP: Result := RSStackEOPNOTSUPP; - Id_WSAEPFNOSUPPORT: Result := RSStackEPFNOSUPPORT; - Id_WSAEAFNOSUPPORT: Result := RSStackEAFNOSUPPORT; - Id_WSAEADDRINUSE: Result := RSStackEADDRINUSE; - Id_WSAEADDRNOTAVAIL: Result := RSStackEADDRNOTAVAIL; - Id_WSAENETDOWN: Result := RSStackENETDOWN; - Id_WSAENETUNREACH: Result := RSStackENETUNREACH; - Id_WSAENETRESET: Result := RSStackENETRESET; - Id_WSAECONNABORTED: Result := RSStackECONNABORTED; - Id_WSAECONNRESET: Result := RSStackECONNRESET; - Id_WSAENOBUFS: Result := RSStackENOBUFS; - Id_WSAEISCONN: Result := RSStackEISCONN; - Id_WSAENOTCONN: Result := RSStackENOTCONN; - Id_WSAESHUTDOWN: Result := RSStackESHUTDOWN; - {$IFNDEF BEOS} - Id_WSAETOOMANYREFS: Result := RSStackETOOMANYREFS; - {$ENDIF} - Id_WSAETIMEDOUT: Result := RSStackETIMEDOUT; - Id_WSAECONNREFUSED: Result := RSStackECONNREFUSED; - Id_WSAELOOP: Result := RSStackELOOP; - Id_WSAENAMETOOLONG: Result := RSStackENAMETOOLONG; - Id_WSAEHOSTDOWN: Result := RSStackEHOSTDOWN; - Id_WSAEHOSTUNREACH: Result := RSStackEHOSTUNREACH; - Id_WSAENOTEMPTY: Result := RSStackENOTEMPTY; - end; - Result := IndyFormat(RSStackError, [AErr, Result]); -end; - -function TIdStack.HostToNetwork(const AValue: TIdIPv6Address): TIdIPv6Address; -var - i : Integer; -begin - for i := 0 to 7 do begin - Result[i] := HostToNetwork(AValue[i]); - end; -end; - -function TIdStack.NetworkToHost(const AValue: TIdIPv6Address): TIdIPv6Address; -var - i : Integer; -begin - for i := 0 to 7 do begin - Result[i] := NetworkToHost(AValue[i]); - end; -end; - -function TIdStack.IsValidIPv4MulticastGroup(const Value: string): Boolean; -var - LIP: string; - LVal: Integer; -begin - Result := False; - if IsIP(Value) then - begin - LIP := Value; - LVal := IndyStrToInt(Fetch(LIP, '.')); {Do not Localize} - Result := (LVal >= IPv4MCastLo) and (LVal <= IPv4MCastHi); - end; -end; - -{ From "rfc 2373" - -2.7 Multicast Addresses - - An IPv6 multicast address is an identifier for a group of nodes. A - node may belong to any number of multicast groups. Multicast - addresses have the following format: - -# - | 8 | 4 | 4 | 112 bits | - +------ -+----+----+---------------------------------------------+ - |11111111|flgs|scop| group ID | - +--------+----+----+---------------------------------------------+ - - 11111111 at the start of the address identifies the address as - being a multicast address. - - +-+-+-+-+ - flgs is a set of 4 flags: |0|0|0|T| - +-+-+-+-+ - - The high-order 3 flags are reserved, and must be initialized to - 0. - - T = 0 indicates a permanently-assigned ("well-known") multicast - address, assigned by the global internet numbering authority. - - T = 1 indicates a non-permanently-assigned ("transient") - multicast address. - - scop is a 4-bit multicast scope value used to limit the scope of - the multicast group. The values are: - - 0 reserved - 1 node-local scope - 2 link-local scope - 3 (unassigned) - 4 (unassigned) - 5 site-local scope - 6 (unassigned) - 7 (unassigned) - 8 organization-local scope - 9 (unassigned) - A (unassigned) - B (unassigned) - C (unassigned) - - D (unassigned) - E global scope - F reserved - - group ID identifies the multicast group, either permanent or - transient, within the given scope. - - The "meaning" of a permanently-assigned multicast address is - independent of the scope value. For example, if the "NTP servers - group" is assigned a permanent multicast address with a group ID of - 101 (hex), then: - - FF01:0:0:0:0:0:0:101 means all NTP servers on the same node as the - sender. - - FF02:0:0:0:0:0:0:101 means all NTP servers on the same link as the - sender. - - FF05:0:0:0:0:0:0:101 means all NTP servers at the same site as the - sender. - - FF0E:0:0:0:0:0:0:101 means all NTP servers in the internet. - - Non-permanently-assigned multicast addresses are meaningful only - within a given scope. For example, a group identified by the non- - permanent, site-local multicast address FF15:0:0:0:0:0:0:101 at one - site bears no relationship to a group using the same address at a - different site, nor to a non-permanent group using the same group ID - with different scope, nor to a permanent group with the same group - ID. - - Multicast addresses must not be used as source addresses in IPv6 - packets or appear in any routing header. -} -function TIdStack.IsValidIPv6MulticastGroup(const Value: string): Boolean; -var - LTmp : String; -begin - LTmp := IdGlobal.MakeCanonicalIPv6Address(Value); - if LTmp <> '' then - begin - Result := TextStartsWith(LTmp, 'FF'); - end else begin - Result := False; - end; -end; - -function TIdStack.CalcCheckSum(const AData: TIdBytes): UInt16; -var - i : Integer; - LSize : Integer; - LCRC : UInt32; -begin - LCRC := 0; - i := 0; - LSize := Length(AData); - while LSize > 1 do - begin - LCRC := LCRC + BytesToUInt16(AData, i); - Dec(LSize, 2); - Inc(i, 2); - end; - if LSize > 0 then begin - LCRC := LCRC + AData[i]; - end; - LCRC := (LCRC shr 16) + (LCRC and $ffff); //(LCRC >> 16) - LCRC := LCRC + (LCRC shr 16); - Result := not UInt16(LCRC); -end; - -{$UNDEF HAS_TCP_KEEPIDLE_OR_KEEPINTVL} -{$IFDEF HAS_TCP_KEEPIDLE} - {$DEFINE HAS_TCP_KEEPIDLE_OR_KEEPINTVL} -{$ENDIF} -{$IFDEF HAS_TCP_KEEPINTVL} - {$DEFINE HAS_TCP_KEEPIDLE_OR_KEEPINTVL} -{$ENDIF} - -procedure TIdStack.SetKeepAliveValues(ASocket: TIdStackSocketHandle; - const AEnabled: Boolean; const ATimeMS, AInterval: Integer); -begin - SetSocketOption(ASocket, Id_SOL_SOCKET, Id_SO_KEEPALIVE, iif(AEnabled, 1, 0)); - {$IFDEF HAS_TCP_KEEPIDLE_OR_KEEPINTVL} - if AEnabled then - begin - // TODO: support TCP_KEEPCNT - {$IFDEF HAS_TCP_KEEPIDLE} - SetSocketOption(ASocket, Id_SOL_TCP, Id_TCP_KEEPIDLE, ATimeMS div MSecsPerSec); - {$ENDIF} - {$IFDEF HAS_TCP_KEEPINTVL} - SetSocketOption(ASocket, Id_SOL_TCP, Id_TCP_KEEPINTVL, AInterval div MSecsPerSec); - {$ENDIF} - end; - {$ENDIF} -end; - -initialization - //done this way so we can have a separate stack just for FPC under Unix systems - GStackClass := - {$IFDEF DOTNET} - TIdStackDotNet - {$ELSE} - {$IFDEF WINDOWS} - TIdStackWindows - {$ELSE} - {$IFDEF USE_VCL_POSIX} - TIdStackVCLPosix - {$ELSE} - {$IFDEF UNIX} - {$IFDEF KYLIXCOMPAT} - TIdStackLibc - {$ELSE} - {$IFDEF USE_BASEUNIX} - TIdStackUnix - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} - ; - GStackCriticalSection := TIdCriticalSection.Create; - {$IFNDEF DOTNET} - {$IFDEF REGISTER_EXPECTED_MEMORY_LEAK} - IndyRegisterExpectedMemoryLeak(GStackCriticalSection); - {$ENDIF} - {$ENDIF} -finalization - // Dont Free. If shutdown is from another Init section, it can cause GPF when stack - // tries to access it. App will kill it off anyways, so just let it leak - {$IFDEF FREE_ON_FINAL} - FreeAndNil(GStackCriticalSection); - {$ENDIF} -end. +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.7 1/17/2005 7:25:48 PM JPMugaas + Moved some stack management code here to so that we can reuse it in + non-TIdComponent classes. + Made HostToNetwork and NetworkToHost byte order overload functions for IPv6 + addresses. + + Rev 1.6 10/26/2004 8:12:30 PM JPMugaas + Now uses TIdStrings and TIdStringList for portability. + + Rev 1.5 6/30/2004 12:41:14 PM BGooijen + Added SetStackClass + + Rev 1.4 6/11/2004 8:28:50 AM DSiders + Added "Do not Localize" comments. + + Rev 1.3 4/18/04 2:45:38 PM RLebeau + Conversion support for Int64 values + + Rev 1.2 2004.03.07 11:45:22 AM czhower + Flushbuffer fix + other minor ones found + + Rev 1.1 3/6/2004 5:16:20 PM JPMugaas + Bug 67 fixes. Do not write to const values. + + Rev 1.0 2004.02.03 3:14:42 PM czhower + Move and updates + + Rev 1.39 2/1/2004 6:10:50 PM JPMugaas + GetSockOpt. + + Rev 1.38 2/1/2004 3:28:24 AM JPMugaas + Changed WSGetLocalAddress to GetLocalAddress and moved into IdStack since + that will work the same in the DotNET as elsewhere. This is required to + reenable IPWatch. + + Rev 1.37 2/1/2004 1:54:56 AM JPMugaas + Missapplied fix. IP 0.0.0.0 should now be accepted. + + Rev 1.36 1/31/2004 4:39:12 PM JPMugaas + Removed empty methods. + + Rev 1.35 1/31/2004 1:13:04 PM JPMugaas + Minor stack changes required as DotNET does support getting all IP addresses + just like the other stacks. + + Rev 1.34 2004.01.22 5:59:10 PM czhower + IdCriticalSection + + Rev 1.33 1/18/2004 11:15:52 AM JPMugaas + IsIP was not handling "0" in an IP address. This caused the address + "127.0.0.1" to be treated as a hostname. + + Rev 1.32 12/4/2003 3:14:50 PM BGooijen + Added HostByAddress + + Rev 1.31 1/3/2004 12:21:44 AM BGooijen + Added function SupportsIPv6 + + Rev 1.30 12/31/2003 9:54:16 PM BGooijen + Added IPv6 support + + Rev 1.29 2003.12.31 3:47:42 PM czhower + Changed to use TextIsSame + + Rev 1.28 10/21/2003 9:24:32 PM BGooijen + Started on SendTo, ReceiveFrom + + Rev 1.27 10/19/2003 5:21:28 PM BGooijen + SetSocketOption + + Rev 1.26 10/15/2003 7:21:02 PM DSiders + Added resource strings in TIdStack.Make. + + Rev 1.25 2003.10.11 5:51:02 PM czhower + -VCL fixes for servers + -Chain suport for servers (Super core) + -Scheduler upgrades + -Full yarn support + + Rev 1.24 10/5/2003 9:55:30 PM BGooijen + TIdTCPServer works on D7 and DotNet now + + Rev 1.23 04/10/2003 22:31:56 HHariri + moving of WSNXXX method to IdStack and renaming of the DotNet ones + + Rev 1.22 10/2/2003 7:31:18 PM BGooijen + .net + + Rev 1.21 10/2/2003 6:05:16 PM GGrieve + DontNet + + Rev 1.20 2003.10.02 10:16:30 AM czhower + .Net + + Rev 1.19 2003.10.01 9:11:20 PM czhower + .Net + + Rev 1.18 2003.10.01 5:05:16 PM czhower + .Net + + Rev 1.17 2003.10.01 2:30:40 PM czhower + .Net + + Rev 1.16 2003.10.01 12:30:08 PM czhower + .Net + + Rev 1.14 2003.10.01 1:37:36 AM czhower + .Net + + Rev 1.12 9/30/2003 7:15:46 PM BGooijen + IdCompilerDefines.inc is included now + + Rev 1.11 2003.09.30 1:23:04 PM czhower + Stack split for DotNet +} + +unit IdStack; + +interface + +{$I IdCompilerDefines.inc} + +uses + Classes, + IdException, IdStackConsts, IdGlobal, SysUtils; + +type + EIdSocketError = class(EIdException) + protected + FLastError: Integer; + public + // Params must be in this order to avoid conflict with CreateHelp + // constructor in CBuilder as CB does not differentiate constructors + // by name as Delphi does + constructor CreateError(const AErr: Integer; const AMsg: string); virtual; + // + property LastError: Integer read FLastError; + end; + + { resolving hostnames } + EIdStackError = class (EIdException); + EIdIPVersionUnsupported = class (EIdStackError); + {$IFDEF UNIX} + EIdResolveError = class(EIdSocketError); + EIdReverseResolveError = class(EIdSocketError); + EIdMaliciousPtrRecord = class(EIdReverseResolveError); + {$ELSE} + EIdMaliciousPtrRecord = class(EIdSocketError); + {$ENDIF} + + EIdNotASocket = class(EIdSocketError); + + // TODO: move this to IdStackVCLPosix... + {$IFDEF USE_VCL_POSIX} + {$IFDEF ANDROID} + EIdAndroidPermissionNeeded = class(EIdSocketError); + EIdInternetPermissionNeeded = class(EIdAndroidPermissionNeeded); + {$ENDIF} + {$ENDIF} + + TIdServeFile = function(ASocket: TIdStackSocketHandle; const AFileName: string): Int64; + + TIdPacketInfo = class + protected + FSourceIP: String; + FSourcePort : TIdPort; + FSourceIF: UInt32; + FSourceIPVersion: TIdIPVersion; + FDestIP: String; + FDestPort : TIdPort; + FDestIF: UInt32; + FDestIPVersion: TIdIPVersion; + FTTL: Byte; + public + procedure Reset; + + property TTL : Byte read FTTL write FTTL; + //The computer that sent it to you + property SourceIP : String read FSourceIP write FSourceIP; + property SourcePort : TIdPort read FSourcePort write FSourcePort; + property SourceIF : UInt32 read FSourceIF write FSourceIF; + property SourceIPVersion : TIdIPVersion read FSourceIPVersion write FSourceIPVersion; + //you, the receiver - this is provided for multihomed machines + property DestIP : String read FDestIP write FDestIP; + property DestPort : TIdPort read FDestPort write FDestPort; + property DestIF : UInt32 read FDestIF write FDestIF; + property DestIPVersion : TIdIPVersion read FDestIPVersion write FDestIPVersion; + end; + + // Descend from only TObject. This objects is created a lot and should be fast + // and small + TIdSocketList = class(TObject) + protected + FLock: TIdCriticalSection; + // + function GetItem(AIndex: Integer): TIdStackSocketHandle; virtual; abstract; + public + constructor Create; virtual; + destructor Destroy; override; + procedure Add(AHandle: TIdStackSocketHandle); virtual; abstract; + function Clone: TIdSocketList; virtual; abstract; + function Count: Integer; virtual; abstract; + class function CreateSocketList: TIdSocketList; + property Items[AIndex: Integer]: TIdStackSocketHandle read GetItem; default; + procedure Remove(AHandle: TIdStackSocketHandle); virtual; abstract; + procedure Clear; virtual; abstract; + function ContainsSocket(AHandle: TIdStackSocketHandle): boolean; virtual; abstract; + procedure Lock; + class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; + AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; virtual; + function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; virtual; abstract; + function SelectReadList(var VSocketList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; virtual; abstract; + procedure Unlock; + end; + + TIdSocketListClass = class of TIdSocketList; + + TIdStackLocalAddress = class(TCollectionItem) + protected + FIPVersion: TIdIPVersion; + FIPAddress: String; + FInterfaceName: String; + FInterfaceIndex: UInt32; + FDescription: String; + FFriendlyName: String; + public + constructor Create(ACollection: TCollection; const AIPVersion: TIdIPVersion; const AIPAddress: string); reintroduce; + property IPVersion: TIdIPVersion read FIPVersion; + property IPAddress: String read FIPAddress; + property InterfaceName: String read FInterfaceName; + property InterfaceIndex: UInt32 read FInterfaceIndex; + property Description: String read FDescription; + property FriendlyName: String read FFriendlyName; + end; + + TIdStackLocalAddressIPv4 = class(TIdStackLocalAddress) + protected + FSubNetMask: String; + public + constructor Create(ACollection: TCollection; const AIPAddress, ASubNetMask: string); reintroduce; + property SubNetMask: String read FSubNetMask; + // TODO: add BroadcastIP + end; + + TIdStackLocalAddressIPv6 = class(TIdStackLocalAddress) + public + constructor Create(ACollection: TCollection; const AIPAddress: string); reintroduce; + end; + + TIdStackLocalAddressList = class(TCollection) + protected + function GetAddress(AIndex: Integer): TIdStackLocalAddress; + public + constructor Create; reintroduce; + function IndexOfIP(const AIP: String): Integer; overload; + function IndexOfIP(const AIP: String; AIPVersion: TIdIPVersion): Integer; overload; + property Addresses[AIndex: Integer]: TIdStackLocalAddress read GetAddress; default; + end; + + TIdStack = class(TObject) + protected + FLocalAddresses: TStrings; + // + procedure IPVersionUnsupported; + function HostByName(const AHostName: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; virtual; abstract; + function MakeCanonicalIPv6Address(const AAddr: string): string; {$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use IdGlobal.MakeCanonicalIPv6Address()'{$ENDIF};{$ENDIF} + function ReadHostName: string; virtual; abstract; + function GetLocalAddress: string; + function GetLocalAddresses: TStrings; + public + function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort): TIdStackSocketHandle; overload; + function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; + var VIPVersion: TIdIPVersion): TIdStackSocketHandle; overload; virtual; abstract; + procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION ); virtual; abstract; + procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual; abstract; + constructor Create; virtual; + destructor Destroy; override; + procedure Disconnect(ASocket: TIdStackSocketHandle); virtual; abstract; + function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; + var arg: UInt32): Integer; virtual; abstract; + class procedure IncUsage; //create stack if necessary and inc counter + class procedure DecUsage; //decrement counter and free if it gets to zero + procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort); overload; + procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); overload; virtual; abstract; + procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort); overload; + procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); overload; virtual; abstract; + function HostByAddress(const AAddress: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; virtual; abstract; + function HostToNetwork(AValue: UInt16): UInt16; overload; virtual; abstract; + function HostToNetwork(AValue: UInt32): UInt32; overload; virtual; abstract; + function HostToNetwork(AValue: TIdUInt64): TIdUInt64; overload; virtual; abstract; + function HostToNetwork(const AValue: TIdIPv6Address): TIdIPv6Address; overload; virtual; + function IsIP(AIP: string): Boolean; + procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); virtual; abstract; + function WSGetLastError: Integer; virtual; abstract; + procedure WSSetLastError(const AErr : Integer); virtual; abstract; + function WSTranslateSocketErrorMsg(const AErr: integer): string; virtual; + function CheckForSocketError(const AResult: Integer): Integer; overload; + function CheckForSocketError(const AResult: Integer; const AIgnore: array of Integer): Integer; overload; + procedure RaiseLastSocketError; + procedure RaiseSocketError(AErr: integer); virtual; + function NewSocketHandle(const ASocketType: TIdSocketType; const AProtocol: TIdSocketProtocol; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION; const ANonBlocking: Boolean = False) + : TIdStackSocketHandle; virtual; abstract; + function NetworkToHost(AValue: UInt16): UInt16; overload; virtual; abstract; + function NetworkToHost(AValue: UInt32): UInt32; overload; virtual; abstract; + function NetworkToHost(AValue: TIdUInt64): TIdUInt64; overload; virtual; abstract; + function NetworkToHost(const AValue: TIdIPv6Address): TIdIPv6Address; overload; virtual; + procedure GetSocketOption(ASocket: TIdStackSocketHandle; + ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; + out AOptVal: Integer); overload; virtual; abstract; + procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; AOptVal: Integer); overload; virtual; abstract; + function ResolveHost(const AHost: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; + + // Result: + // > 0: Number of bytes received + // 0: Connection closed gracefully + // Will raise exceptions in other cases + function Receive(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes): Integer; virtual; abstract; + function Send(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; + const AOffset: Integer = 0; const ASize: Integer = -1): Integer; virtual; abstract; + + function ReceiveFrom(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; virtual; abstract; + function SendTo(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; + const AOffset: Integer; const AIP: string; const APort: TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): Integer; overload; + function SendTo(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; + const AOffset: Integer; const ASize: Integer; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION) + : Integer; overload; virtual; abstract; + function ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; + APkt: TIdPacketInfo): UInt32; virtual; abstract; + function SupportsIPv4: Boolean; virtual; abstract; + function SupportsIPv6: Boolean; virtual; abstract; + + //multicast stuff Kudzu permitted me to add here. + function IsValidIPv4MulticastGroup(const Value: string): Boolean; + function IsValidIPv6MulticastGroup(const Value: string): Boolean; + procedure SetKeepAliveValues(ASocket: TIdStackSocketHandle; + const AEnabled: Boolean; const ATimeMS, AInterval: Integer); virtual; + procedure SetMulticastTTL(AHandle: TIdStackSocketHandle; + const AValue : Byte; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual; abstract; + procedure SetLoopBack(AHandle: TIdStackSocketHandle; const AValue: Boolean; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual; abstract; + procedure DropMulticastMembership(AHandle: TIdStackSocketHandle; + const AGroupIP, ALocalIP : String; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual; abstract; + procedure AddMulticastMembership(AHandle: TIdStackSocketHandle; + const AGroupIP, ALocalIP : String; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual; abstract; + //I know this looks like an odd place to put a function for calculating a + //packet checksum. There is a reason for it though. The reason is that + //you need it for ICMPv6 and in Windows, you do that with some other stuff + //in the stack descendants + function CalcCheckSum(const AData : TIdBytes): UInt16; virtual; + //In Windows, this writes a checksum into a buffer. In Linux, it would probably + //simply have the kernal write the checksum with something like this (RFC 2292): + // + // int offset = 2; + // setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)); + // + // Note that this should be called + //IMMEDIATELY before you do a SendTo because the Local IPv6 address might change + procedure WriteChecksum(s : TIdStackSocketHandle; + var VBuffer : TIdBytes; const AOffset : Integer; const AIP : String; + const APort : TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual; abstract; + // + procedure AddLocalAddressesToList(AAddresses: TStrings); {$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'use GetLocalAddressList()'{$ENDIF};{$ENDIF} + procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); virtual; abstract; + // + // Properties + // + property HostName: string read ReadHostName; + property LocalAddress: string read GetLocalAddress; // {$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'use GetLocalAddressList()'{$ENDIF};{$ENDIF} + property LocalAddresses: TStrings read GetLocalAddresses; // {$IFDEF HAS_DEPRECATED}deprecated{$IFDEF HAS_DEPRECATED_MSG} 'use GetLocalAddressList()'{$ENDIF};{$ENDIF} + end; + + TIdStackClass = class of TIdStack; + +var + GStack: TIdStack = nil; + GServeFileProc: TIdServeFile = nil; + GSocketListClass: TIdSocketListClass; + +// Procedures + procedure SetStackClass( AStackClass: TIdStackClass ); + +// TODO: move this to IdStackVCLPosix... +{$IFDEF USE_VCL_POSIX} + {$IFDEF ANDROID} +function HasAndroidPermission(const Permission: string): Boolean; + {$ENDIF} +{$ENDIF} + +implementation + +{$O-} + +uses + //done this way so we can have a separate stack for FPC under Unix systems + {$IFDEF DOTNET} + IdStackDotNet, + {$ELSE} + {$IFDEF WINDOWS} + {$IFDEF USE_INLINE} + Windows, + {$ENDIF} + IdStackWindows, + {$ELSE} + {$IFDEF USE_VCL_POSIX} + IdStackVCLPosix, + {$ELSE} + {$IFDEF UNIX} + {$IFDEF KYLIXCOMPAT} + IdStackLibc, + {$ELSE} + {$IFDEF USE_BASEUNIX} + IdStackUnix, + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$ENDIF} + + // TODO: move this to IdStackVCLPosix... + {$IFDEF USE_VCL_POSIX} + {$IFDEF ANDROID} + {$IFNDEF VCL_XE6_OR_ABOVE} + // StringToJString() is here in XE5 + Androidapi.JNI.JavaTypes, + {$ENDIF} + {$IFNDEF VCL_XE7_OR_ABOVE} + // SharedActivityContext() is here in XE5 and XE6 + FMX.Helpers.Android, + {$ENDIF} + {$IFDEF VCL_XE6_OR_ABOVE} + {$IFDEF VCL_10_0_OR_ABOVE} + // StringToJString() is inline in Seattle and later, so we need JavaTypes again... + Androidapi.JNI.JavaTypes, + {$ENDIF} + // StringToJString() was moved here in XE6 + // SharedActivityContext() was moved here in XE7 + // TAndroidHelper was added here in Seattle + Androidapi.Helpers, + {$ENDIF} + Androidapi.JNI.GraphicsContentViewText, + {$ENDIF} + {$ENDIF} + + IdResourceStrings; + +var + GStackClass: TIdStackClass = nil; + +var + {$IFNDEF USE_OBJECT_ARC} + GInstanceCount: UInt32 = 0; + {$ENDIF} + GStackCriticalSection: TIdCriticalSection = nil; + +//for IPv4 Multicast address chacking +const + IPv4MCastLo = 224; + IPv4MCastHi = 239; + +procedure SetStackClass(AStackClass: TIdStackClass); +begin + GStackClass := AStackClass; +end; + +procedure TIdPacketInfo.Reset; +begin + FSourceIP := ''; + FSourcePort := 0; + FSourceIF := 0; + FSourceIPVersion := ID_DEFAULT_IP_VERSION; + FDestIP := ''; + FDestPort:= 0; + FDestIF := 0; + FDestIPVersion := ID_DEFAULT_IP_VERSION; + FTTL := 0; +end; + +{ TIdSocketList } + +constructor TIdSocketList.Create; +begin + inherited Create; + FLock := TIdCriticalSection.Create; +end; + +class function TIdSocketList.CreateSocketList: TIdSocketList; +Begin + Result := GSocketListClass.Create; +End; + +destructor TIdSocketList.Destroy; +begin + FreeAndNil(FLock); + inherited Destroy; +end; + +procedure TIdSocketList.Lock; +begin + FLock.Acquire; +end; + +class function TIdSocketList.Select(AReadList, AWriteList, + AExceptList: TIdSocketList; const ATimeout: Integer): Boolean; +begin + // C++ Builder cannot have abstract class functions thus we need this base + Result := False; +end; + +procedure TIdSocketList.Unlock; +begin + FLock.Release; +end; + +{ EIdSocketError } + +constructor EIdSocketError.CreateError(const AErr: Integer; const AMsg: string); +begin + inherited Create(AMsg); + FLastError := AErr; +end; + +{ TIdStackLocalAddressList } + +constructor TIdStackLocalAddress.Create(ACollection: TCollection; const AIPVersion: TIdIPVersion; const AIPAddress: string); +begin + inherited Create(ACollection); + FIPVersion := AIPVersion; + FIPAddress := AIPAddress; + FInterfaceIndex := 0; +end; + +constructor TIdStackLocalAddressIPv4.Create(ACollection: TCollection; const AIPAddress, ASubNetMask: string); +begin + inherited Create(ACollection, Id_IPv4, AIPAddress); + FSubNetMask := ASubNetMask; +end; + +constructor TIdStackLocalAddressIPv6.Create(ACollection: TCollection; const AIPAddress: string); +begin + inherited Create(ACollection, Id_IPv6, AIPAddress); +end; + +constructor TIdStackLocalAddressList.Create; +begin + inherited Create(TIdStackLocalAddress); +end; + +function TIdStackLocalAddressList.GetAddress(AIndex: Integer): TIdStackLocalAddress; +begin + Result := TIdStackLocalAddress(inherited Items[AIndex]); +end; + +function TIdStackLocalAddressList.IndexOfIP(const AIP: String): Integer; +var + I: Integer; +begin + Result := -1; + for I := 0 to Count-1 do begin + if Addresses[I].IPAddress = AIP then begin + Result := I; + Exit; + end; + end; +end; + +function TIdStackLocalAddressList.IndexOfIP(const AIP: String; AIPVersion: TIdIPVersion): Integer; +var + I: Integer; + LAddr: TIdStackLocalAddress; +begin + Result := -1; + for I := 0 to Count-1 do begin + LAddr := Addresses[I]; + if (LAddr.IPVersion = AIPVersion) and (LAddr.IPAddress = AIP) then begin + Result := I; + Exit; + end; + end; +end; + +{ TIdStack } + +constructor TIdStack.Create; +begin + // Here for .net + inherited Create; +end; + +destructor TIdStack.Destroy; +begin + FreeAndNil(FLocalAddresses); + inherited Destroy; +end; + +procedure TIdStack.IPVersionUnsupported; +begin + raise EIdIPVersionUnsupported.Create(RSIPVersionUnsupported); +end; + +function TIdStack.Accept(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort): TIdStackSocketHandle; +var + LIPVersion: TIdIPVersion; +begin + Result := Accept(ASocket, VIP, VPort, LIPVersion); +end; + +procedure TIdStack.GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort); +var + LIPVersion: TIdIPVersion; +begin + GetPeerName(ASocket, VIP, VPort, LIPVersion); +end; + +procedure TIdStack.GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort); +var + LIPVersion: TIdIPVersion; +begin + GetSocketName(ASocket, VIP, VPort, LIPVersion); +end; + +{$I IdDeprecatedImplBugOff.inc} +procedure TIdStack.AddLocalAddressesToList(AAddresses: TStrings); +{$I IdDeprecatedImplBugOn.inc} +var + LList: TIdStackLocalAddressList; + I: Integer; +begin + LList := TIdStackLocalAddressList.Create; + try + // for backwards compatibility, return only IPv4 addresses + GetLocalAddressList(LList); + if LList.Count > 0 then begin + AAddresses.BeginUpdate; + try + for I := 0 to LList.Count-1 do begin + if LList[I].IPVersion = Id_IPv4 then begin + AAddresses.Add(LList[I].IPAddress); + end; + end; + finally + AAddresses.EndUpdate; + end; + end; + finally + LList.Free; + end; +end; + +function TIdStack.GetLocalAddresses: TStrings; +var + LList: TIdStackLocalAddressList; + I: Integer; +begin + if FLocalAddresses = nil then begin + FLocalAddresses := TStringList.Create; + end; + FLocalAddresses.BeginUpdate; + try + FLocalAddresses.Clear; + LList := TIdStackLocalAddressList.Create; + try + // for backwards compatibility, return only IPv4 addresses + GetLocalAddressList(LList); + for I := 0 to LList.Count-1 do begin + if LList[I].IPVersion = Id_IPv4 then begin + FLocalAddresses.Add(LList[I].IPAddress); + end; + end; + finally + LList.Free; + end; + finally + FLocalAddresses.EndUpdate; + end; + Result := FLocalAddresses; +end; + +function TIdStack.GetLocalAddress: string; +var + LList: TIdStackLocalAddressList; + I: Integer; +begin + // RLebeau: using a local list instead of the LocalAddresses + // property so this method can be thread-safe... + // + // old code: + // Result := LocalAddresses[0]; + + Result := ''; + LList := TIdStackLocalAddressList.Create; + try + // for backwards compatibility, return only IPv4 addresses + GetLocalAddressList(LList); + for I := 0 to LList.Count-1 do begin + if LList[I].IPVersion = Id_IPv4 then begin + Result := LList[I].IPAddress; + Exit; + end; + end; + finally + LList.Free; + end; +end; + +function TIdStack.IsIP(AIP: string): Boolean; +var + i: Integer; +begin + // TODO: support IPv6 + +// +//Result := Result and ((i > 0) and (i < 256)); +// + i := IndyStrToInt(Fetch(AIP, '.'), -1); {Do not Localize} + Result := (i > -1) and (i < 256); + i := IndyStrToInt(Fetch(AIP, '.'), -1); {Do not Localize} + Result := Result and ((i > -1) and (i < 256)); + i := IndyStrToInt(Fetch(AIP, '.'), -1); {Do not Localize} + Result := Result and ((i > -1) and (i < 256)); + i := IndyStrToInt(Fetch(AIP, '.'), -1); {Do not Localize} + Result := Result and ((i > -1) and (i < 256)) and (AIP = ''); +end; + +{$I IdDeprecatedImplBugOff.inc} +function TIdStack.MakeCanonicalIPv6Address(const AAddr: string): string; +{$I IdDeprecatedImplBugOn.inc} +begin + Result := IdGlobal.MakeCanonicalIPv6Address(AAddr); +end; + +function TIdStack.ResolveHost(const AHost: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; +begin + Result := ''; + case AIPVersion of + Id_IPv4: begin + // Sometimes 95 forgets who localhost is + if TextIsSame(AHost, 'LOCALHOST') then begin {Do not Localize} + Result := '127.0.0.1'; {Do not Localize} + end else if IsIP(AHost) then begin + Result := AHost; + end else begin + Result := HostByName(AHost, Id_IPv4); + end; + end; + Id_IPv6: begin + if TextIsSame(AHost, 'LOCALHOST') then begin {Do not Localize} + Result := '::1'; {Do not Localize} + end else begin + Result := IdGlobal.MakeCanonicalIPv6Address(AHost); + if Result = '' then begin + Result := HostByName(AHost, Id_IPv6); + end; + end; + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +function TIdStack.SendTo(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; + const AOffset: Integer; const AIP: string; const APort: TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): Integer; +begin + Result := SendTo(ASocket, ABuffer, AOffset, -1, AIP, APort, AIPVersion); +end; + +class procedure TIdStack.DecUsage; +var + // under ARC, increment the lock's reference count before working with it + LLock: TIdCriticalSection; +begin + LLock := GStackCriticalSection; + if not Assigned(LLock) then begin + raise EIdStackError.Create('GStackCriticalSection is nil in TIdStack.DecUsage'); {do not localize} + end; + LLock.Acquire; + try + // This CS will guarantee that during the FreeAndNil nobody + // will try to use or construct GStack + {$IFDEF USE_OBJECT_ARC} + if GStack <> nil then begin + if GStack.__ObjRelease = 0 then begin + Pointer(GStack) := nil; + end; + end; + {$ELSE} + if GInstanceCount > 0 then begin + Dec(GInstanceCount); + if GInstanceCount = 0 then begin + FreeAndNil(GStack); + end; + end; + {$ENDIF} + finally + LLock.Release; + end; +end; + +class procedure TIdStack.IncUsage; +var + // under ARC, increment the lock's reference count before working with it + LLock: TIdCriticalSection; +begin + LLock := GStackCriticalSection; + if not Assigned(LLock) then begin + raise EIdStackError.Create('GStackCriticalSection is nil in TIdStack.IncUsage'); {do not localize} + end; + LLock.Acquire; + try + {$IFDEF USE_OBJECT_ARC} + if GStack = nil then begin + if GStackClass = nil then begin + raise EIdStackError.Create(RSStackClassUndefined); + end; + GStack := GStackClass.Create; + end else begin + GStack.__ObjAddRef; + end; + {$ELSE} + if GInstanceCount = 0 then begin + if GStack <> nil then begin + raise EIdStackError.Create(RSStackAlreadyCreated); + end; + if GStackClass = nil then begin + raise EIdStackError.Create(RSStackClassUndefined); + end; + GStack := GStackClass.Create; + end; + Inc(GInstanceCount); + {$ENDIF} + finally + LLock.Release; + end; +end; + +function TIdStack.CheckForSocketError(const AResult: Integer): Integer; +begin + if AResult = Integer(Id_SOCKET_ERROR) then begin + RaiseLastSocketError; + end; + Result := AResult; +end; + +function TIdStack.CheckForSocketError(const AResult: Integer; + const AIgnore: array of integer): Integer; +var + i: Integer; + LLastError: Integer; +begin + Result := AResult; + if AResult = Integer(Id_SOCKET_ERROR) then begin + LLastError := WSGetLastError; + for i := Low(AIgnore) to High(AIgnore) do begin + if LLastError = AIgnore[i] then begin + Result := LLastError; + Exit; + end; + end; + RaiseSocketError(LLastError); + end; +end; + +procedure TIdStack.RaiseLastSocketError; +begin + RaiseSocketError(WSGetLastError); +end; + +// TODO: move this to IdStackVCLPosix... +{$IFDEF USE_VCL_POSIX} + {$IFDEF ANDROID} +function GetActivityContext: JContext; {$IFDEF USE_INLINE}inline;{$ENDIF} +begin + {$IFDEF HAS_TAndroidHelper} + Result := TAndroidHelper.Context; + {$ELSE} + Result := SharedActivityContext; + {$ENDIF} +end; + +function HasAndroidPermission(const Permission: string): Boolean; +begin + Result := GetActivityContext.checkCallingOrSelfPermission(StringToJString(Permission)) = TJPackageManager.JavaClass.PERMISSION_GRANTED; +end; + {$ENDIF} +{$ENDIF} + +procedure TIdStack.RaiseSocketError(AErr: integer); +begin + (* + RRRRR EEEEEE AAAA DDDDD MM MM EEEEEE !! !! !! + RR RR EE AA AA DD DD MMMM MMMM EE !! !! !! + RRRRR EEEE AAAAAA DD DD MM MMM MM EEEE !! !! !! + RR RR EE AA AA DD DD MM MM EE + RR RR EEEEEE AA AA DDDDD MM MM EEEEEE .. .. .. + + Please read the note in the next comment. + *) + if AErr = Id_WSAENOTSOCK then begin + // You can add this to your exception ignore list for easier debugging. + // However please note that sometimes it is a true error. Your program + // will still run correctly, but the debugger will not stop on it if you + // list it in the ignore list. But for most times its fine to put it in + // the ignore list, it only affects your debugging. + raise EIdNotASocket.CreateError(AErr, WSTranslateSocketErrorMsg(AErr)); + end; + + // TODO: move this to IdStackVCLPosix... + {$IFDEF USE_VCL_POSIX} + {$IFDEF ANDROID} + if (AErr = 9{EBADF}) or (AErr = 12{EBADR?}) or (AErr = 13{EACCES}) then begin + if not HasAndroidPermission('android.permission.INTERNET') then begin {Do not Localize} + raise EIdInternetPermissionNeeded.CreateError(AErr, WSTranslateSocketErrorMsg(AErr)); + end; + end; + {$ENDIF} + {$ENDIF} + + (* + It is normal to receive a 10038 exception (10038, NOT others!) here when + *shutting down* (NOT at other times!) servers (NOT clients!). + + If you receive a 10038 exception here please see the FAQ at: + http://www.IndyProject.org/ + + If you insist upon requesting help via our email boxes on the 10038 error + that is already answered in the FAQ and you are simply too slothful to + search for your answer and ask your question in the public forums you may be + publicly flogged, tarred and feathered and your name may be added to every + chain letter / EMail in existence today." + + Otherwise, if you DID read the FAQ and have further questions, please feel + free to ask using one of the methods (Carefullly note that these methods do + not list email) listed on the Tech Support link at: + http://www.IndyProject.org/ + + RRRRR EEEEEE AAAA DDDDD MM MM EEEEEE !! !! !! + RR RR EE AA AA DD DD MMMM MMMM EE !! !! !! + RRRRR EEEE AAAAAA DD DD MM MMM MM EEEE !! !! !! + RR RR EE AA AA DD DD MM MM EE + RR RR EEEEEE AA AA DDDDD MM MM EEEEEE .. .. .. + *) + raise EIdSocketError.CreateError(AErr, WSTranslateSocketErrorMsg(AErr)); +end; + +function TIdStack.WSTranslateSocketErrorMsg(const AErr: integer): string; +begin + Result := ''; {Do not Localize} + case AErr of + Id_WSAEINTR: Result := RSStackEINTR; + Id_WSAEBADF: Result := RSStackEBADF; + Id_WSAEACCES: Result := RSStackEACCES; + Id_WSAEFAULT: Result := RSStackEFAULT; + Id_WSAEINVAL: Result := RSStackEINVAL; + Id_WSAEMFILE: Result := RSStackEMFILE; + Id_WSAEWOULDBLOCK: Result := RSStackEWOULDBLOCK; + Id_WSAEINPROGRESS: Result := RSStackEINPROGRESS; + Id_WSAEALREADY: Result := RSStackEALREADY; + Id_WSAENOTSOCK: Result := RSStackENOTSOCK; + Id_WSAEDESTADDRREQ: Result := RSStackEDESTADDRREQ; + Id_WSAEMSGSIZE: Result := RSStackEMSGSIZE; + Id_WSAEPROTOTYPE: Result := RSStackEPROTOTYPE; + Id_WSAENOPROTOOPT: Result := RSStackENOPROTOOPT; + + Id_WSAEPROTONOSUPPORT: Result := RSStackEPROTONOSUPPORT; + {$IFNDEF BEOS} + Id_WSAESOCKTNOSUPPORT: Result := RSStackESOCKTNOSUPPORT; + {$ENDIF} + Id_WSAEOPNOTSUPP: Result := RSStackEOPNOTSUPP; + Id_WSAEPFNOSUPPORT: Result := RSStackEPFNOSUPPORT; + Id_WSAEAFNOSUPPORT: Result := RSStackEAFNOSUPPORT; + Id_WSAEADDRINUSE: Result := RSStackEADDRINUSE; + Id_WSAEADDRNOTAVAIL: Result := RSStackEADDRNOTAVAIL; + Id_WSAENETDOWN: Result := RSStackENETDOWN; + Id_WSAENETUNREACH: Result := RSStackENETUNREACH; + Id_WSAENETRESET: Result := RSStackENETRESET; + Id_WSAECONNABORTED: Result := RSStackECONNABORTED; + Id_WSAECONNRESET: Result := RSStackECONNRESET; + Id_WSAENOBUFS: Result := RSStackENOBUFS; + Id_WSAEISCONN: Result := RSStackEISCONN; + Id_WSAENOTCONN: Result := RSStackENOTCONN; + Id_WSAESHUTDOWN: Result := RSStackESHUTDOWN; + {$IFNDEF BEOS} + Id_WSAETOOMANYREFS: Result := RSStackETOOMANYREFS; + {$ENDIF} + Id_WSAETIMEDOUT: Result := RSStackETIMEDOUT; + Id_WSAECONNREFUSED: Result := RSStackECONNREFUSED; + Id_WSAELOOP: Result := RSStackELOOP; + Id_WSAENAMETOOLONG: Result := RSStackENAMETOOLONG; + Id_WSAEHOSTDOWN: Result := RSStackEHOSTDOWN; + Id_WSAEHOSTUNREACH: Result := RSStackEHOSTUNREACH; + Id_WSAENOTEMPTY: Result := RSStackENOTEMPTY; + end; + Result := IndyFormat(RSStackError, [AErr, Result]); +end; + +function TIdStack.HostToNetwork(const AValue: TIdIPv6Address): TIdIPv6Address; +var + i : Integer; +begin + for i := 0 to 7 do begin + Result[i] := HostToNetwork(AValue[i]); + end; +end; + +function TIdStack.NetworkToHost(const AValue: TIdIPv6Address): TIdIPv6Address; +var + i : Integer; +begin + for i := 0 to 7 do begin + Result[i] := NetworkToHost(AValue[i]); + end; +end; + +function TIdStack.IsValidIPv4MulticastGroup(const Value: string): Boolean; +var + LIP: string; + LVal: Integer; +begin + Result := False; + if IsIP(Value) then + begin + LIP := Value; + LVal := IndyStrToInt(Fetch(LIP, '.')); {Do not Localize} + Result := (LVal >= IPv4MCastLo) and (LVal <= IPv4MCastHi); + end; +end; + +{ From "rfc 2373" + +2.7 Multicast Addresses + + An IPv6 multicast address is an identifier for a group of nodes. A + node may belong to any number of multicast groups. Multicast + addresses have the following format: + +# + | 8 | 4 | 4 | 112 bits | + +------ -+----+----+---------------------------------------------+ + |11111111|flgs|scop| group ID | + +--------+----+----+---------------------------------------------+ + + 11111111 at the start of the address identifies the address as + being a multicast address. + + +-+-+-+-+ + flgs is a set of 4 flags: |0|0|0|T| + +-+-+-+-+ + + The high-order 3 flags are reserved, and must be initialized to + 0. + + T = 0 indicates a permanently-assigned ("well-known") multicast + address, assigned by the global internet numbering authority. + + T = 1 indicates a non-permanently-assigned ("transient") + multicast address. + + scop is a 4-bit multicast scope value used to limit the scope of + the multicast group. The values are: + + 0 reserved + 1 node-local scope + 2 link-local scope + 3 (unassigned) + 4 (unassigned) + 5 site-local scope + 6 (unassigned) + 7 (unassigned) + 8 organization-local scope + 9 (unassigned) + A (unassigned) + B (unassigned) + C (unassigned) + + D (unassigned) + E global scope + F reserved + + group ID identifies the multicast group, either permanent or + transient, within the given scope. + + The "meaning" of a permanently-assigned multicast address is + independent of the scope value. For example, if the "NTP servers + group" is assigned a permanent multicast address with a group ID of + 101 (hex), then: + + FF01:0:0:0:0:0:0:101 means all NTP servers on the same node as the + sender. + + FF02:0:0:0:0:0:0:101 means all NTP servers on the same link as the + sender. + + FF05:0:0:0:0:0:0:101 means all NTP servers at the same site as the + sender. + + FF0E:0:0:0:0:0:0:101 means all NTP servers in the internet. + + Non-permanently-assigned multicast addresses are meaningful only + within a given scope. For example, a group identified by the non- + permanent, site-local multicast address FF15:0:0:0:0:0:0:101 at one + site bears no relationship to a group using the same address at a + different site, nor to a non-permanent group using the same group ID + with different scope, nor to a permanent group with the same group + ID. + + Multicast addresses must not be used as source addresses in IPv6 + packets or appear in any routing header. +} +function TIdStack.IsValidIPv6MulticastGroup(const Value: string): Boolean; +var + LTmp : String; +begin + LTmp := IdGlobal.MakeCanonicalIPv6Address(Value); + if LTmp <> '' then + begin + Result := TextStartsWith(LTmp, 'FF'); + end else begin + Result := False; + end; +end; + +function TIdStack.CalcCheckSum(const AData: TIdBytes): UInt16; +var + i : Integer; + LSize : Integer; + LCRC : UInt32; +begin + LCRC := 0; + i := 0; + LSize := Length(AData); + while LSize > 1 do + begin + LCRC := LCRC + BytesToUInt16(AData, i); + Dec(LSize, 2); + Inc(i, 2); + end; + if LSize > 0 then begin + LCRC := LCRC + AData[i]; + end; + LCRC := (LCRC shr 16) + (LCRC and $ffff); //(LCRC >> 16) + LCRC := LCRC + (LCRC shr 16); + Result := not UInt16(LCRC); +end; + +{$UNDEF HAS_TCP_KEEPIDLE_OR_KEEPINTVL} +{$IFDEF HAS_TCP_KEEPIDLE} + {$DEFINE HAS_TCP_KEEPIDLE_OR_KEEPINTVL} +{$ENDIF} +{$IFDEF HAS_TCP_KEEPINTVL} + {$DEFINE HAS_TCP_KEEPIDLE_OR_KEEPINTVL} +{$ENDIF} + +procedure TIdStack.SetKeepAliveValues(ASocket: TIdStackSocketHandle; + const AEnabled: Boolean; const ATimeMS, AInterval: Integer); +begin + SetSocketOption(ASocket, Id_SOL_SOCKET, Id_SO_KEEPALIVE, iif(AEnabled, 1, 0)); + {$IFDEF HAS_TCP_KEEPIDLE_OR_KEEPINTVL} + if AEnabled then + begin + // TODO: support TCP_KEEPCNT + {$IFDEF HAS_TCP_KEEPIDLE} + SetSocketOption(ASocket, Id_SOL_TCP, Id_TCP_KEEPIDLE, ATimeMS div MSecsPerSec); + {$ENDIF} + {$IFDEF HAS_TCP_KEEPINTVL} + SetSocketOption(ASocket, Id_SOL_TCP, Id_TCP_KEEPINTVL, AInterval div MSecsPerSec); + {$ENDIF} + end; + {$ENDIF} +end; + +initialization + //done this way so we can have a separate stack just for FPC under Unix systems + GStackClass := + {$IFDEF DOTNET} + TIdStackDotNet + {$ELSE} + {$IFDEF WINDOWS} + TIdStackWindows + {$ELSE} + {$IFDEF USE_VCL_POSIX} + TIdStackVCLPosix + {$ELSE} + {$IFDEF UNIX} + {$IFDEF KYLIXCOMPAT} + TIdStackLibc + {$ELSE} + {$IFDEF USE_BASEUNIX} + TIdStackUnix + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$ENDIF} + {$ENDIF} + ; + GStackCriticalSection := TIdCriticalSection.Create; + {$IFNDEF DOTNET} + {$IFDEF REGISTER_EXPECTED_MEMORY_LEAK} + IndyRegisterExpectedMemoryLeak(GStackCriticalSection); + {$ENDIF} + {$ENDIF} +finalization + // Dont Free. If shutdown is from another Init section, it can cause GPF when stack + // tries to access it. App will kill it off anyways, so just let it leak + {$IFDEF FREE_ON_FINAL} + FreeAndNil(GStackCriticalSection); + {$ENDIF} +end. diff --git a/Lib/System/IdStackDotNet.pas b/Lib/System/IdStackDotNet.pas index ced86bf01..593031e24 100644 --- a/Lib/System/IdStackDotNet.pas +++ b/Lib/System/IdStackDotNet.pas @@ -1,1418 +1,1418 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.8 10/26/2004 8:12:30 PM JPMugaas - Now uses TIdStrings and TIdStringList for portability. - - Rev 1.7 6/11/2004 8:28:56 AM DSiders - Added "Do not Localize" comments. - - Rev 1.6 5/14/2004 12:14:50 PM BGooijen - Fix for weird dotnet bug when querying the local binding - - Rev 1.5 4/18/04 2:45:54 PM RLebeau - Conversion support for Int64 values - - Rev 1.4 2004.03.07 11:45:26 AM czhower - Flushbuffer fix + other minor ones found - - Rev 1.3 3/6/2004 5:16:30 PM JPMugaas - Bug 67 fixes. Do not write to const values. - - Rev 1.2 2/10/2004 7:33:26 PM JPMugaas - I had to move the wrapper exception here for DotNET stack because Borland's - update 1 does not permit unlisted units from being put into a package. That - now would report an error and I didn't want to move IdExceptionCore into the - System package. - - Rev 1.1 2/4/2004 8:48:30 AM JPMugaas - Should compile. - - Rev 1.0 2004.02.03 3:14:46 PM czhower - Move and updates - - Rev 1.32 2/1/2004 6:10:54 PM JPMugaas - GetSockOpt. - - Rev 1.31 2/1/2004 3:28:32 AM JPMugaas - Changed WSGetLocalAddress to GetLocalAddress and moved into IdStack since - that will work the same in the DotNET as elsewhere. This is required to - reenable IPWatch. - - Rev 1.30 1/31/2004 1:12:54 PM JPMugaas - Minor stack changes required as DotNET does support getting all IP addresses - just like the other stacks. - - Rev 1.29 2004.01.22 2:46:52 PM czhower - Warning fixed. - - Rev 1.28 12/4/2003 3:14:54 PM BGooijen - Added HostByAddress - - Rev 1.27 1/3/2004 12:22:14 AM BGooijen - Added function SupportsIPv6 - - Rev 1.26 1/2/2004 4:24:08 PM BGooijen - This time both IPv4 and IPv6 work - - Rev 1.25 02/01/2004 15:58:00 HHariri - fix for bind - - Rev 1.24 12/31/2003 9:52:00 PM BGooijen - Added IPv6 support - - Rev 1.23 10/28/2003 10:12:36 PM BGooijen - DotNet - - Rev 1.22 10/26/2003 10:31:16 PM BGooijen - oops, checked in debug version , this is the right one - - Rev 1.21 10/26/2003 5:04:26 PM BGooijen - UDP Server and Client - - Rev 1.20 10/21/2003 11:03:50 PM BGooijen - More SendTo, ReceiveFrom - - Rev 1.19 10/21/2003 9:24:32 PM BGooijen - Started on SendTo, ReceiveFrom - - Rev 1.18 10/19/2003 5:21:30 PM BGooijen - SetSocketOption - - Rev 1.17 10/11/2003 4:16:40 PM BGooijen - Compiles again - - Rev 1.16 10/5/2003 9:55:28 PM BGooijen - TIdTCPServer works on D7 and DotNet now - - Rev 1.15 10/5/2003 3:10:42 PM BGooijen - forgot to clone the Sockets list in some Select methods, + added Listen and - Accept - - Rev 1.14 10/5/2003 1:52:14 AM BGooijen - Added typecasts with network ordering calls, there are required for some - reason - - Rev 1.13 10/4/2003 10:39:38 PM BGooijen - Renamed WSXXX functions in implementation section too - - Rev 1.12 04/10/2003 22:32:00 HHariri - moving of WSNXXX method to IdStack and renaming of the DotNet ones - - Rev 1.11 04/10/2003 21:28:42 HHariri - Netowkr ordering functions - - Rev 1.10 10/3/2003 11:02:02 PM BGooijen - fixed calls to Socket.Select - - Rev 1.9 10/3/2003 11:39:38 PM GGrieve - more work - - Rev 1.8 10/3/2003 12:09:32 AM BGooijen - DotNet - - Rev 1.7 10/2/2003 8:23:52 PM BGooijen - .net - - Rev 1.6 10/2/2003 8:08:52 PM BGooijen - .Connect works not in .net - - Rev 1.5 10/2/2003 7:31:20 PM BGooijen - .net - - Rev 1.4 10/2/2003 6:12:36 PM GGrieve - work in progress (hardly started) - - Rev 1.3 2003.10.01 9:11:24 PM czhower - .Net - - Rev 1.2 2003.10.01 5:05:18 PM czhower - .Net - - Rev 1.1 2003.10.01 1:12:40 AM czhower - .Net - - Rev 1.0 2003.09.30 10:35:40 AM czhower - Initial Checkin -} - -unit IdStackDotNet; - -interface - -{$i IdCompilerDefines.inc} - -uses - Classes, - IdGlobal, IdStack, IdStackConsts, - System.Collections, System.IO, System.Net, System.Net.Sockets; - -type - TIdStackDotNet = class(TIdStack) - protected - //Stuff for ICMPv6 - {$IFDEF DOTNET_2_OR_ABOVE} - procedure QueryRoute(s : TIdStackSocketHandle; const AIP: String; - const APort: TIdPort; var VSource, VDest : TIdBytes); - procedure WriteChecksumIPv6(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort); - {$ENDIF} - function ReadHostName: string; override; - function HostByName(const AHostName: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; - //internal IP Mutlicasting membership stuff - procedure MembershipSockOpt(AHandle: TIdStackSocketHandle; - const AGroupIP, ALocalIP : String; const ASockOpt : TIdSocketOption; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); - public - [ThreadStatic] - LastSocketError: Integer; //static; - constructor Create; override; - destructor Destroy; override; - procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; const APort: TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION ); override; - procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - procedure Disconnect(ASocket: TIdStackSocketHandle); override; - procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; - procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; - function WSGetLastError: Integer; override; - procedure WSSetLastError(const AErr : Integer); override; - function NewSocketHandle(const ASocketType: TIdSocketType; - const AProtocol: TIdSocketProtocol; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION; - const ANonBlocking: Boolean = False) : TIdStackSocketHandle; override; - // Result: - // > 0: Number of bytes received - // 0: Connection closed gracefully - // Will raise exceptions in other cases - function Receive(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes) : Integer; override; - function Send(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; - const AOffset: Integer = 0; const ASize: Integer = -1): Integer; override; - function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; - var arg: UInt32): Integer; override; - function ReceiveFrom(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; override; - function ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; - APkt: TIdPacketInfo): UInt32; override; - function SendTo(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; - const AOffset: Integer; const ASize: Integer; const AIP: string; const APort: TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): Integer; override; - function HostToNetwork(AValue: UInt16): UInt16; override; - function NetworkToHost(AValue: UInt16): UInt16; override; - function HostToNetwork(AValue: UInt32): UInt32; override; - function NetworkToHost(AValue: UInt32): UInt32; override; - function HostToNetwork(AValue: TIdUInt64): TIdUInt64; override; - function NetworkToHost(AValue: TIdUInt64): TIdUInt64; override; - function HostByAddress(const AAddress: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; - procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer);override; - function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; - var VIPVersion: TIdIPVersion): TIdStackSocketHandle; override; - procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; out AOptVal: Integer); override; - procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel:TIdSocketOptionLevel; - AOptName: TIdSocketOption; AOptVal: Integer); overload; override; - function SupportsIPv4: Boolean; override; - function SupportsIPv6: Boolean; override; - //multicast stuff Kudzu permitted me to add here. - procedure SetMulticastTTL(AHandle: TIdStackSocketHandle; const AValue : Byte; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - procedure SetLoopBack(AHandle: TIdStackSocketHandle; const AValue: Boolean; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - procedure DropMulticastMembership(AHandle: TIdStackSocketHandle; - const AGroupIP, ALocalIP : String; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - procedure AddMulticastMembership(AHandle: TIdStackSocketHandle; - const AGroupIP, ALocalIP : String; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - procedure WriteChecksum(s : TIdStackSocketHandle; var VBuffer : TIdBytes; - const AOffset : Integer; const AIP : String; const APort : TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); override; - procedure SetKeepAliveValues(ASocket: TIdStackSocketHandle; - const AEnabled: Boolean; const ATimeMS, AInterval: Integer); override; - end; - {$IFDEF DOTNET_1_1} - EIdNotSupportedInMicrosoftNET11 = class(EIdStackError); - {$ENDIF} - -var - GDotNETStack : TIdStackDotNet = nil; - -implementation - -uses - IdException, IdResourceStrings; - -const - IdIPFamily : array[TIdIPVersion] of AddressFamily = (AddressFamily.InterNetwork, AddressFamily.InterNetworkV6); - -{ TIdStackDotNet } - -procedure DoRaiseException(AStack: TIdStackDotNet; AException: System.Exception); -var - LSocketError : System.Net.Sockets.SocketException; - E: EIdException; -begin - if AException is System.Net.Sockets.SocketException then - begin - LSocketError := AException as System.Net.Sockets.SocketException; - AStack.LastSocketError := LSocketError.ErrorCode; - E := EIdSocketError.CreateError(LSocketError.ErrorCode, LSocketError.Message) - end else begin - E := EIdWrapperException.Create(AException.Message, AException); - end; - IndyRaiseOuterException(E); -end; - -{ TIdStackDotNet } - -constructor TIdStackDotNet.Create; -begin - inherited Create; - GDotNETStack := Self; -end; - -destructor TIdStackDotNet.Destroy; -begin - GDotNETStack := nil; - inherited Destroy; -end; - -procedure TIdStackDotNet.Bind(ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LIPAddr : IPAddress; - LEndPoint : IPEndPoint; - LIP: String; -begin - try - if not (AIPVersion in [Id_IPv4, Id_IPv6]) then - begin - IPVersionUnsupported; - end; - LIP := AIP; - if LIP = '' then begin - if AIPVersion = Id_IPv4 then begin - LIPAddr := IPAddress.Any; - end else begin - LIPAddr := IPAddress.IPv6Any; - end; - end else begin - LIPAddr := IPAddress.Parse(LIP); - end; - LEndPoint := IPEndPoint.Create(LIPAddr, APort); - ASocket.Bind(LEndPoint); - except - on e: Exception do begin - DoRaiseException(Self, e); - end; - end; -end; - -procedure TIdStackDotNet.Connect(const ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LEndPoint : IPEndPoint; -begin - try - LEndPoint := IPEndPoint.Create(IPAddress.Parse(AIP), APort); - ASocket.Connect(LEndPoint); - except - on e: Exception do begin - DoRaiseException(Self, e); - end; - end; -end; - -procedure TIdStackDotNet.Disconnect(ASocket: TIdStackSocketHandle); -begin - try - ASocket.Close; - except - on e: Exception do begin - DoRaiseException(Self, e); - end; - end; -end; - -procedure TIdStackDotNet.Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); -begin - try - ASocket.Listen(ABackLog); - except - on e: Exception do begin - DoRaiseException(Self, e); - end; - end; -end; - -function TIdStackDotNet.Accept(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): TIdStackSocketHandle; -var - LEndPoint: IPEndPoint; -begin - try - Result := ASocket.Accept(); - LEndPoint := Result.RemoteEndPoint as IPEndPoint; - - if (Result.AddressFamily = AddressFamily.InterNetwork) or - (Result.AddressFamily = AddressFamily.InterNetworkV6) then - begin - VIP := LEndPoint.Address.ToString(); - VPort := LEndPoint.Port; - if Result.AddressFamily = AddressFamily.InterNetworkV6 then begin - VIPVersion := Id_IPv6; - end else begin - VIPVersion := Id_IPv4; - end; - end else - begin - Result := Id_INVALID_SOCKET; - IPVersionUnsupported; - end; - except - on e: Exception do begin - DoRaiseException(Self, e); - end; - end; -end; - -procedure TIdStackDotNet.GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); -var - LEndPoint : IPEndPoint; -begin - try - if (ASocket.AddressFamily = AddressFamily.InterNetwork) or - (ASocket.AddressFamily = AddressFamily.InterNetworkV6) then - begin - LEndPoint := ASocket.RemoteEndPoint as IPEndPoint; - - VIP := LEndPoint.Address.ToString; - VPort := LEndPoint.Port; - if ASocket.AddressFamily = AddressFamily.InterNetworkV6 then begin - VIPVersion := Id_IPv6; - end else begin - VIPVersion := Id_IPv4; - end; - end else begin - IPVersionUnsupported; - end; - except - on e: Exception do begin - DoRaiseException(Self, e); - end; - end; -end; - -procedure TIdStackDotNet.GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); -var - LEndPoint : IPEndPoint; -begin - try - if (ASocket.AddressFamily = AddressFamily.InterNetwork) or - (ASocket.AddressFamily = AddressFamily.InterNetworkV6) then - begin - LEndPoint := ASocket.LocalEndPoint as IPEndPoint; - - VIP := LEndPoint.Address.ToString; - VPort := LEndPoint.Port; - if ASocket.AddressFamily = AddressFamily.InterNetworkV6 then begin - VIPVersion := Id_IPv6; - end else begin - VIPVersion := Id_IPv4; - end; - end else begin - IPVersionUnsupported; - end; - except - on e: Exception do begin - DoRaiseException(Self, e); - end; - end; -end; - -function TIdStackDotNet.HostByName(const AHostName: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; -var - LIP: array of IPAddress; - a: Integer; -begin - try - { - [Warning] IdStackDotNet.pas(417): W1000 Symbol 'Resolve' is deprecated: - 'Resolve is obsoleted for this type, please use GetHostEntry instead. - http://go.microsoft.com/fwlink/?linkid=14202' - } - {$IFDEF DOTNET_2_OR_ABOVE} - LIP := Dns.GetHostEntry(AHostName).AddressList; - {$ENDIF} - {$IFDEF DOTNET_1_1} - LIP := Dns.Resolve(AHostName).AddressList; - {$ENDIF} - for a := Low(LIP) to High(LIP) do begin - if LIP[a].AddressFamily = IdIPFamily[AIPVersion] then begin - Result := LIP[a].ToString; - Exit; - end; - end; - raise System.Net.Sockets.SocketException.Create(11001); - except - on e: Exception do begin - DoRaiseException(Self, e); - end; - end; -end; - -function TIdStackDotNet.HostByAddress(const AAddress: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; -begin - try - {$IFDEF DOTNET_2_OR_ABOVE} - Result := Dns.GetHostEntry(AAddress).HostName; - {$ENDIF} - {$IFDEF DOTNET_1_1} - Result := Dns.GetHostByAddress(AAddress).HostName; - {$ENDIF} - except - on e: Exception do begin - DoRaiseException(Self, e); - end; - end; -end; - -function TIdStackDotNet.WSGetLastError: Integer; -begin - Result := LastSocketError; -end; - -procedure TIdStackDotNet.WSSetLastError(const AErr : Integer); -begin - LastSocketError := AErr; -end; - -function TIdStackDotNet.NewSocketHandle(const ASocketType: TIdSocketType; - const AProtocol: TIdSocketProtocol; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION; - const ANonBlocking: Boolean = False): TIdStackSocketHandle; -begin - try - Result := Socket.Create(IdIPFamily[AIPVersion], ASocketType, AProtocol); - Result.Blocking := not ANonBlocking; - except - on E: Exception do begin - DoRaiseException(Self, E); - end; - end; -end; - -function TIdStackDotNet.ReadHostName: string; -begin - try - Result := System.Net.DNS.GetHostName; - except - on E: Exception do begin - DoRaiseException(Self, e); - end; - end; -end; - -function TIdStackDotNet.Receive(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes): Integer; -begin - try - Result := ASocket.Receive(VBuffer, Length(VBuffer), SocketFlags.None); - except - on e: Exception do begin - DoRaiseException(Self, e); - end; - end; -end; - -function TIdStackDotNet.Send(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; - const AOffset: Integer = 0; const ASize: Integer = -1): Integer; -var - Tmp: TIdBytes; -begin - Result := IndyLength(ABuffer, ASize, AOffset); - try - if Result > 0 then begin - Result := ASocket.Send(ABuffer, AOffset, Result, SocketFlags.None); - end else - begin - // RLebeau: this is to allow UDP sockets to send 0-length packets. Send() - // raises an exception if its buffer parameter is nil, and a 0-length byte - // array is nil... - // - // TODO: check the socket type and only allow this for UDP sockets... - // - SetLength(Tmp, 1); - Tmp[0] := $00; - Result := ASocket.Send(Tmp, 0, 0, SocketFlags.None); - end; - except - on E: Exception do begin - DoRaiseException(Self, E); - end; - end; -end; - -function TIdStackDotNet.ReceiveFrom(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; -var - LIPAddr : IPAddress; - LEndPoint : EndPoint; -begin - Result := 0; // to make the compiler happy - case ASocket.AddressFamily of - AddressFamily.InterNetwork: LIPAddr := IPAddress.Any; - AddressFamily.InterNetworkV6: LIPAddr := IPAddress.IPv6Any; - else - IPVersionUnsupported; - end; - LEndPoint := IPEndPoint.Create(LIPAddr, 0); - try - try - Result := ASocket.ReceiveFrom(VBuffer, SocketFlags.None, LEndPoint); - except - on e: Exception do begin - DoRaiseException(Self, e); - end; - end; - VIP := IPEndPoint(LEndPoint).Address.ToString; - VPort := IPEndPoint(LEndPoint).Port; - case IPEndPoint(LEndPoint).AddressFamily of - AddressFamily.InterNetwork: VIPVersion := Id_IPv4; - AddressFamily.InterNetworkV6: VIPVersion := Id_IPv6; - end; - finally - LEndPoint.Free; - end; -end; - -function TIdStackDotNet.SendTo(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; - const AOffset: Integer; const ASize: Integer; const AIP: string; const APort: TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): Integer; -var - LEndPoint : EndPoint; - Tmp: TIdBytes; -begin - Result := IndyLength(ABuffer, ASize, AOffset); - try - LEndPoint := IPEndPoint.Create(IPAddress.Parse(AIP), APort); - try - if Result > 0 then begin - Result := ASocket.SendTo(ABuffer, AOffset, Result, SocketFlags.None, LEndPoint); - end else - begin - // RLebeau: this is to allow UDP sockets to send 0-length packets. SendTo() - // raises an exception if its buffer parameter is nil, and a 0-length byte - // array is nil... - // - // TODO: check the socket type and only allow this for UDP sockets... - // - SetLength(Tmp, 1); - Tmp[0] := $00; - Result := ASocket.SendTo(Tmp, 0, 0, SocketFlags.None, LEndPoint); - end. - finally - LEndPoint.Free; - end; - except - on e: Exception do begin - DoRaiseException(Self, e); - end; - end; -end; - -////////////////////////////////////////////////////////////// - -type - TIdSocketListDotNet = class(TIdSocketList) - protected - FSockets: ArrayList; - function GetItem(AIndex: Integer): TIdStackSocketHandle; override; - public - constructor Create; override; - destructor Destroy; override; - procedure Add(AHandle: TIdStackSocketHandle); override; - procedure Remove(AHandle: TIdStackSocketHandle); override; - function Count: Integer; override; - procedure Clear; override; - function Clone: TIdSocketList; override; - function ContainsSocket(AHandle: TIdStackSocketHandle): boolean; override; - class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; - AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - function SelectReadList(var VSocketList: TIdSocketList; - const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - end; - -constructor TIdSocketListDotNet.Create; -begin - inherited Create; - FSockets := ArrayList.Create; -end; - -destructor TIdSocketListDotNet.Destroy; -begin - FSockets.Free; - inherited Destroy; -end; - -procedure TIdSocketListDotNet.Add(AHandle: TIdStackSocketHandle); -begin - FSockets.Add(AHandle); -end; - -procedure TIdSocketListDotNet.Clear; -begin - FSockets.Clear; -end; - -function TIdSocketListDotNet.ContainsSocket(AHandle: TIdStackSocketHandle): Boolean; -begin - Result := FSockets.Contains(AHandle); -end; - -function TIdSocketListDotNet.Count: Integer; -begin - Result := FSockets.Count; -end; - -function TIdSocketListDotNet.GetItem(AIndex: Integer): TIdStackSocketHandle; -begin - Result := (FSockets.Item[AIndex]) as TIdStackSocketHandle; -end; - -procedure TIdSocketListDotNet.Remove(AHandle: TIdStackSocketHandle); -begin - FSockets.Remove(AHandle); -end; - -const - cMaxMSPerLoop = MaxInt div 1000; // max milliseconds per Socket.Select() call - -function TIdSocketListDotNet.SelectRead(const ATimeout: Integer): Boolean; -var - LTimeout: Integer; - - function DoSelect(const AInterval: Integer): Boolean; - var - LTemp: ArrayList; - begin - // DotNet updates this object on return, so we need to copy it each time we need it - LTemp := ArrayList(FSockets.Clone); - try - Socket.Select(LTemp, nil, nil, AInterval); - Result := LTemp.Count > 0; - finally - LTemp.Free; - end; - end; - -begin - Result := False; - try - // RLebeau 8/27/2007: the .NET docs say that -1 is supposed to - // cause an infinite timeout, but it doesn't actually work! - // So loop manually instead until Microsoft fixes it... - if ATimeout = IdTimeoutInfinite then - begin - repeat - Result := DoSelect(MaxInt); - until Result; - end else - begin - // RLebeau: Select() accepts a timeout in microseconds, not - // milliseconds, so have to loop anyway to handle timeouts - // that are greater then 35 minutes... - LTimeout := ATimeout; - while LTimeout >= cMaxMSPerLoop do - begin - Result := DoSelect(cMaxMSPerLoop * 1000); - if Result then begin - Exit; - end; - Dec(LTimeout, cMaxMSPerLoop); - end; - if (not Result) and (LTimeout > 0) then begin - Result := DoSelect(LTimeout * 1000); - end; - end; - except - on e: ArgumentNullException do begin - Result := False; - end; - on e: Exception do begin - DoRaiseException(GDotNETStack, e); - end; - end; -end; - -function TIdSocketListDotNet.SelectReadList(var VSocketList: TIdSocketList; - const ATimeout: Integer): Boolean; -var - LTemp: ArrayList; - LTimeout: Integer; - - function DoSelect(const AInterval: Integer; var VList: ArrayList): Boolean; - var - LLTemp: ArrayList; - begin - // DotNet updates this object on return, so we need to copy it each time we need it - LLTemp := ArrayList(FSockets.Clone); - try - Socket.Select(LLTemp, nil, nil, AInterval); - Result := LLTemp.Count > 0; - if Result then - begin - VList := LLTemp; - LLTemp := nil; - end; - finally - LLTemp.Free; - end; - end; - -begin - Result := False; - try - // RLebeau 8/27/2007: the .NET docs say that -1 is supposed to - // cause an infinite timeout, but it doesn't actually work! - // So loop manually instead until Microsoft fixes it... - if ATimeout = IdTimeoutInfinite then - begin - repeat - Result := DoSelect(MaxInt, LTemp); - until Result; - end else - begin - // RLebeau: Select() accepts a timeout in microseconds, not - // milliseconds, so have to loop anyway to handle timeouts - // that are greater then 35 minutes... - LTimeout := ATimeout; - while LTimeout >= cMaxMSPerLoop do - begin - Result := DoSelect(cMaxMSPerLoop * 1000, LTemp); - if Result then begin - Break; - end; - Dec(LTimeout, cMaxMSPerLoop); - end; - if (not Result) and (LTimeout > 0) then begin - Result := DoSelect(LTimeout * 1000, LTemp); - end; - end; - if Result then - begin - try - if VSocketList = nil then begin - VSocketList := TIdSocketList.CreateSocketList; - end; - TIdSocketListDotNet(VSocketList).FSockets.Free; - TIdSocketListDotNet(VSocketList).FSockets := LTemp; - except - LTemp.Free; - raise; - end; - end; - except - on e: ArgumentNullException do begin - Result := False; - end; - on e: Exception do begin - DoRaiseException(GDotNETStack, e); - end; - end; -end; - -class function TIdSocketListDotNet.Select(AReadList, AWriteList, AExceptList: TIdSocketList; - const ATimeout: Integer): Boolean; -var - LTimeout: Integer; - LReadTemp, LWriteTemp, LExceptTemp: ArrayList; - - function DoSelect(var VReadList, VWriteList, VExceptList: ArrayList; - const AInterval: Integer): Boolean; - var - LLReadTemp: ArrayList; - LLWriteTemp: ArrayList; - LLExceptTemp: ArrayList; - begin - LLReadTemp := nil; - LLWriteTemp := nil; - LLExceptTemp := nil; - - VReadList := nil; - VWriteList := nil; - VExceptList := nil; - - // DotNet updates these objects on return, so we need to copy them each time we need them - if Assigned(AReadList) and Assigned(TIdSocketListDotNet(AReadList).FSockets) then begin - LLReadTemp := ArrayList(TIdSocketListDotNet(AReadList).FSockets.Clone); - end; - try - if Assigned(AWriteList) and Assigned(TIdSocketListDotNet(AWriteList).FSockets) then begin - LLWriteTemp := ArrayList(TIdSocketListDotNet(AWriteList).FSockets.Clone); - end; - try - if Assigned(AExceptList) and Assigned(TIdSocketListDotNet(AExceptList).FSockets) then begin - LLExceptTemp := ArrayList(TIdSocketListDotNet(AExceptList).FSockets.Clone); - end; - try - Socket.Select(LLReadTemp, LLWriteTemp, LLExceptTemp, AInterval); - Result := (LLReadTemp.Count > 0) or - (LLWriteTemp.Count > 0) or - (LLExceptTemp.Count > 0); - if Result then - begin - VReadList := LLReadTemp; - LLReadTemp:= nil; - - VWriteList := LLWriteTemp; - LLWriteTemp:= nil; - - VExceptList := LLExceptTemp; - LLExceptTemp:= nil; - end; - finally - LLExceptTemp.Free; - end; - finally - LLWriteTemp.Free; - end; - finally - LLReadTemp.Free; - end; - end; - -begin - Result := False; - try - // RLebeau 8/27/2007: the .NET docs say that -1 is supposed to - // cause an infinite timeout, but it doesn't actually work! - // So loop manually instead until Microsoft fixes it... - if ATimeout = IdTimeoutInfinite then - begin - repeat - Result := DoSelect( - LReadTemp, LWriteTemp, LExceptTemp, - MaxInt); - until Result; - end else - begin - // RLebeau: Select() accepts a timeout in microseconds, not - // milliseconds, so have to loop anyway to handle timeouts - // that are greater then 35 minutes... - LTimeout := ATimeout; - while LTimeout >= cMaxMSPerLoop do - begin - Result := DoSelect( - LReadTemp, LWriteTemp, LExceptTemp, - cMaxMSPerLoop * 1000); - if Result then begin - Break; - end; - Dec(LTimeout, cMaxMSPerLoop); - end; - if (not Result) and (LTimeout > 0) then - begin - Result := DoSelect( - LReadTemp, LWriteTemp, LExceptTemp, - LTimeout * 1000); - end; - end; - // RLebeau: this method is meant to update the - // source lists inlined regardless of the Result... - if Assigned(AReadList) then - begin - TIdSocketListDotNet(AReadList).FSockets.Free; - TIdSocketListDotNet(AReadList).FSockets := LReadTemp; - end; - if Assigned(AWriteList) then - begin - TIdSocketListDotNet(AWriteList).FSockets.Free; - TIdSocketListDotNet(AWriteList).FSockets := LWriteTemp; - end; - if Assigned(AExceptList) then - begin - TIdSocketListDotNet(AExceptList).FSockets.Free; - TIdSocketListDotNet(AExceptList).FSockets := LExceptTemp; - end; - except - on e: ArgumentNullException do begin - Result := False; - end; - on e: Exception do begin - DoRaiseException(GDotNETStack, e); - end; - end; -end; - -function TIdSocketListDotNet.Clone: TIdSocketList; -begin - Result := TIdSocketListDotNet.Create; //BGO: TODO: make prettier - TIdSocketListDotNet(Result).FSockets.Free; - TIdSocketListDotNet(Result).FSockets := ArrayList(FSockets.Clone); -end; - -function TIdStackDotNet.HostToNetwork(AValue: UInt16): UInt16; -begin - Result := UInt16(IPAddress.HostToNetworkOrder(Int16(AValue))); -end; - -function TIdStackDotNet.HostToNetwork(AValue: UInt32): UInt32; -begin - Result := UInt32(IPAddress.HostToNetworkOrder(Int32(AValue))); -end; - -function TIdStackDotNet.HostToNetwork(AValue: TIdUInt64): TIdUInt64; -begin - Result := TIdUInt64(IPAddress.HostToNetworkOrder(Int64(AValue))); -end; - -function TIdStackDotNet.NetworkToHost(AValue: UInt16): UInt16; -begin - Result := UInt16(IPAddress.NetworkToHostOrder(Int16(AValue))); -end; - -function TIdStackDotNet.NetworkToHost(AValue: UInt32): UInt32; -begin - Result := UInt32(IPAddress.NetworkToHostOrder(Int32(AValue))); -end; - -function TIdStackDotNet.NetworkToHost(AValue: TIdUInt64): TIdUInt64; -begin - Result := TIdUInt64(IPAddress.NetworkToHostOrder(Int64(AValue)); -end; - -procedure TIdStackDotNet.GetSocketOption(ASocket: TIdStackSocketHandle; - ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; out AOptVal: Integer); -var - L : System.Object; -begin - L := ASocket.GetSocketOption(ALevel, AoptName); - AOptVal := Integer(L); -end; - -procedure TIdStackDotNet.SetSocketOption(ASocket: TIdStackSocketHandle; - ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; AOptVal: Integer); -begin - ASocket.SetSocketOption(ALevel, AOptName, AOptVal); -end; - -function TIdStackDotNet.SupportsIPv4: Boolean; -begin - { - [Warning] IdStackDotNet.pas(734): W1000 Symbol 'SupportsIPv4' is deprecated: - 'SupportsIPv4 is obsoleted for this type, please use OSSupportsIPv4 instead. - http://go.microsoft.com/fwlink/?linkid=14202' - } - {$IFDEF DOTNET_2_OR_ABOVE} - Result := Socket.OSSupportsIPv4; - {$ENDIF} - {$IFDEF DOTNET_1_1} - Result := Socket.SupportsIPv4; - {$ENDIF} -end; - -function TIdStackDotNet.SupportsIPv6: Boolean; -begin - { - [Warning] IdStackDotNet.pas(734): W1000 Symbol 'SupportsIPv6' is deprecated: - 'SupportsIPv6 is obsoleted for this type, please use OSSupportsIPv6 instead. - http://go.microsoft.com/fwlink/?linkid=14202' - } - {$IFDEF DOTNET_2_OR_ABOVE} - Result := Socket.OSSupportsIPv6; - {$ENDIF} - {$IFDEF DOTNET_1_1} - Result := Socket.SupportsIPv6; - {$ENDIF} -end; - -procedure TIdStackDotNet.GetLocalAddressList(AAddresses: TIdStackLocalAddressList); -var - {$IFDEF DOTNET_1_1} - LAddr : IPAddress; - {$ENDIF} - LHost : IPHostEntry; - LIPAddresses: array of IPAddress; - LIPAddress: IPAddress; - i : Integer; -begin - {$IFDEF DOTNET_2_OR_ABOVE} - // TODO: use NetworkInterface.GetAllNetworkInterfaces() instead. - // See this article for an example: - // http://blogs.msdn.com/b/dgorti/archive/2005/10/04/477078.aspx - LHost := DNS.GetHostEntry(DNS.GetHostName); - {$ENDIF} - {$IFDEF DOTNET_1_1} - LAddr := IPAddress.Any; - LHost := DNS.GetHostByAddress(LAddr); - {$ENDIF} - LIPAddresses := LHost.AddressList; - if Length(LIPAddresses) > 0 then - begin - AAddresses.BeginUpdate; - try - for i := Low(LIPAddresses) to High(LIPAddresses) do - begin - LIPAddress := LIPAddresses[i]; - //This may be returning various types of addresses. - case LIPAddress.AddressFamily of - AddressFamily.InterNetwork: begin - TIdStackLocalAddressIPv4.Create(AAddresses, LIPAddress.ToString, ''); // TODO: SubNet - end; - AddressFamily.InterNetworkV6: begin - TIdStackLocalAddressIPv6.Create(AAddresses, LIPAddress.ToString); - end; - end; - end; - finally - AAddresses.EndUpdate; - end; - end; -end; - -procedure TIdStackDotNet.SetLoopBack(AHandle: TIdStackSocketHandle; - const AValue: Boolean; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -begin - //necessary because SetSocketOption only accepts an integer - //see: http://groups-beta.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/6a35c6d9052cfc2b/f01fea11f9a24508?q=SetSocketOption+DotNET&rnum=2&hl=en#f01fea11f9a24508 - AHandle.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, iif(AValue, 1, 0)); -end; - -procedure TIdStackDotNet.DropMulticastMembership(AHandle: TIdStackSocketHandle; - const AGroupIP, ALocalIP: String; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -begin - MembershipSockOpt(AHandle, AGroupIP, ALocalIP, SocketOptionName.DropMembership); -end; - -procedure TIdStackDotNet.AddMulticastMembership(AHandle: TIdStackSocketHandle; - const AGroupIP, ALocalIP: String; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -begin - MembershipSockOpt(AHandle, AGroupIP, ALocalIP, SocketOptionName.AddMembership); -end; - -procedure TIdStackDotNet.SetMulticastTTL(AHandle: TIdStackSocketHandle; - const AValue: Byte; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -begin - if AIPVersion = Id_IPv4 then begin - AHandle.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, AValue); - end else begin - AHandle.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.MulticastTimeToLive, AValue); - end; -end; - -procedure TIdStackDotNet.MembershipSockOpt(AHandle: TIdStackSocketHandle; - const AGroupIP, ALocalIP: String; const ASockOpt: TIdSocketOption; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LM4 : MulticastOption; - LM6 : IPv6MulticastOption; - LGroupIP, LLocalIP : System.Net.IPAddress; -begin - LGroupIP := IPAddress.Parse(AGroupIP); - if LGroupIP.AddressFamily = AddressFamily.InterNetworkV6 then - begin - LM6 := IPv6MulticastOption.Create(LGroupIP); - AHandle.SetSocketOption(SocketOptionLevel.IPv6, ASockOpt, LM6); - end else - begin - if ALocalIP.Length = 0 then begin - LM4 := System.Net.Sockets.MulticastOption.Create(LGroupIP); - end else - begin - LLocalIP := IPAddress.Parse(ALocalIP); - LM4 := System.Net.Sockets.MulticastOption.Create(LGroupIP, LLocalIP); - end; - AHandle.SetSocketOption(SocketOptionLevel.IP, ASockOpt, LM4); - end; -end; - -function TIdStackDotNet.ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; - APkt: TIdPacketInfo): UInt32; -var - {$IFDEF DOTNET_1_1} - LIP : String; - LPort : TIdPort; - LIPVersion: TIdIPVersion; - {$ELSE} - LSF : SocketFlags; - LIPAddr : IPAddress; - LRemEP : EndPoint; - LPki : IPPacketInformation; - {$ENDIF} -begin - {$IFDEF DOTNET_1_1} - Result := ReceiveFrom(ASocket, VBuffer, LIP, LPort, LIPVersion); - APkt.Reset; - APkt.SourceIP := LIP; - APkt.SourcePort := LPort; - APkt.SourceIPVersion := LIPVersion; - APkt.DestIPVersion := LIPVersion; - {$ELSE} - LSF := SocketFlags.None; - { - The AddressFamily of the EndPoint used in ReceiveFrom needs to match the - AddressFamily of the EndPoint used in SendTo. - } - case ASocket.AddressFamily of - AddressFamily.InterNetwork: LIPAddr := IPAddress.Any; - AddressFamily.InterNetworkV6: LIPAddr := IPAddress.IPv6Any; - else - Result := 0; // keep the compiler happy - IPVersionUnsupported; - end; - LRemEP := IPEndPoint.Create(LIPAddr, 0); - Result := ASocket.ReceiveMessageFrom(VBuffer, 0, Length(VBUffer), LSF, LRemEP, lpki); - APkt.Reset; - APkt.SourceIP := IPEndPoint(LRemEP).Address.ToString; - APkt.SourcePort := IPEndPoint(LRemEP).Port; - case IPEndPoint(LRemEP).AddressFamily of - AddressFamily.InterNetwork: APkt.SourceIPVersion := Id_IPv4; - AddressFamily.InterNetworkV6: APkt.SourceIPVersion := Id_IPv6; - end; - APkt.DestIP := LPki.Address.ToString; - APkt.DestIF := LPki.&Interface; - APkt.DestIPVersion := APkt.SourceIPVersion; - {$ENDIF} -end; - -{ -This extracts an IP address as a series of bytes from a TIdBytes that contains -one SockAddress structure. -} -procedure SockAddrToIPBytes(const ASockAddr : TIdBytes; var VIPAddr : TIdBytes); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - case BytesToUInt16(ASockAddr,0) of - 23 : //AddressFamily.InterNetworkV6 : - begin - //16 = size of SOCKADDR_IN6.sin6_addr - SetLength(VIPAddr,16); -// 8 = offset of sin6_addr in SOCKADDR_IN6 -// sin6_family : Smallint; // AF_INET6 -// sin6_port : u_short; // Transport level port number -// sin6_flowinfo : u_long; // IPv6 flow information - - System.array.Copy(ASockAddr,8, VIPAddr, 0, 16); - end; - 2 : //AddressFamily.InterNetwork : - begin - //size of sockaddr_in.sin_addr - SetLength(VIPAddr,4); -// 4 = offset of sockaddr_in.sin_addr -// sin_family : u_short; -// sin_port : u_short; - System.array.Copy(ASockAddr,4, VIPAddr, 0, 4); - end; - end; -end; - -procedure TIdStackDotNet.QueryRoute(s : TIdStackSocketHandle; const AIP: String; - const APort: TIdPort; var VSource, VDest : TIdBytes); -{$IFDEF DOTNET_2_OR_ABOVE} -const - SIO_ROUTING_INTERFACE_QUERY = 3355443220; -{$ENDIF} -var - LEP : IPEndPoint; - LDestIF : SocketAddress; - LIn, LOut : TBytes; - i : Integer; -begin - LEP := IPEndPoint.Create(IPAddress.Parse(AIP),APort); - LDestIf := LEP.Serialize; -{ -The first 2 bytes of the underlying buffer are reserved for the AddressFamily -enumerated value. When the SocketAddress is used to store a serialized -IPEndPoint, the third and fourth bytes are used to store port number -information. The next bytes are used to store the IP address. You can access any -information within this underlying byte buffer by referring to its index -position; the byte buffer uses zero-based indexing. You can also use the Family -and Size properties to get the AddressFamily value and the buffer size, -respectively. To view any of this information as a string, use the ToString -method. -} - SetLength(LIn,LDestIf.Size); - for i := 0 to LDestIf.Size - 1 do - begin - LIn[i] := LDestIf[i]; - end; - SetLength(LOut,LDestIf.Size); -{ -IMPORTANT!!!! - -We can not do something like: - - s.IOControl( IOControlCode.RoutingInterfaceQuery, LIn, LOut); - - because to IOControlCode.RoutingInterfaceQuery has a value of -539371432 - and that is not correct. I found that out the hard way. -} - s.IOControl(LongInt(SIO_ROUTING_INTERFACE_QUERY),Lin,LOut); - SockAddrToIPBytes(LOut,VSource); - SockAddrToIPBytes(LIn,VDest); -end; - -procedure TIdStackDotNet.WriteChecksumIPv6(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort); -var - LSource : TIdBytes; - LDest : TIdBytes; - LTmp : TIdBytes; - LIdx : Integer; - LC : UInt32; -{ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - + + - | | - + Source Address + - | | - + + - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - + + - | | - + Destination Address + - | | - + + - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Upper-Layer Packet Length | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | zero | Next Header | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -} -begin - - QueryRoute(s, AIP, APort, LSource, LDest); - SetLength(LTmp, 40+Length(VBuffer)); - System.&Array.Clear(LTmp,0,Length(LTmp)); - //16 - CopyTIdBytes(LSource, 0, LTmp, 0, 16); - LIdx := 16; - //32 - CopyTIdBytes(LDest, 0, LTmp,LIdx, 16); - Inc(LIdx, 16); - //use a word so you don't wind up using the wrong network byte order function - LC := Length(VBuffer); - CopyTIdUInt32(HostToNetwork(LC), LTmp, LIdx); - Inc(LIdx, 4); - //36 - //zero the next three bytes - //done in the begging - Inc(LIdx, 3); - //next header (protocol type determines it - LTmp[LIdx] := Ord(Id_IPPROTO_ICMPv6); - Inc(LIdx); - //combine the two - CopyTIdBytes(VBuffer, 0, LTmp, LIdx, Length(VBuffer)); - //zero out the checksum field - CopyTIdUInt16(0, LTmp, LIdx+AOffset); - - CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(LTmp)), VBuffer, AOffset); -end; -{$ENDIF} - -procedure TIdStackDotNet.WriteChecksum(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort; const AIPVersion: TIdIPVersion); -begin - if AIPVersion = Id_IPv4 then begin - CopyTIdUInt16(CalcCheckSum(VBuffer), VBuffer, AOffset); - end else - begin - {$IFDEF DOTNET_1_1} - {This is a todo because to do a checksum for ICMPv6, you need to obtain - the address for the IP the packet will come from (query the network interfaces). - You then have to make a IPv6 pseudo header. About the only other alternative is - to have the kernel (or DotNET Framework) generate the checksum but we don't have - an API for it. - - I'm not sure if we have an API for it at all. Even if we did, would it be worth - doing when you consider that Microsoft's NET Framework 1.1 does not support ICMPv6 - in its enumerations.} - raise EIdNotSupportedInMicrosoftNET11.Create(RSNotSupportedInMicrosoftNET11); - {$ELSE} - WriteChecksumIPv6(s,VBuffer,AOffset,AIP,APort); - {$ENDIF} - end; -end; - -function TIdStackDotNet.IOControl(const s: TIdStackSocketHandle; - const cmd: UInt32; var arg: UInt32): Integer; -var - LTmp : TIdBytes; -begin - LTmp := ToBytes(arg); - s.IOControl(cmd, ToBytes(arg), LTmp); - arg := BytesToUInt32(LTmp); - Result := 0; -end; - -{$IFDEF DOTNET_2_OR_ABOVE} -function ServeFile(ASocket: TIdStackSocketHandle; const AFileName: string): Int64; -var - LFile : FileInfo; -begin - ASocket.SendFile(AFileName); - LFile := System.IO.FileInfo.Create(AFileName); - Result := LFile.Length; -end; -{$ENDIF} - -procedure TIdStackDotNet.SetKeepAliveValues(ASocket: TIdStackSocketHandle; - const AEnabled: Boolean; const ATimeMS, AInterval: Integer); -{$IFNDEF DOTNET_2_OR_ABOVE} -const - SIO_KEEPALIVE_VALS = 2550136836; -{$ENDIF} -var - LBuf: TIdBytes; -begin - // SIO_KEEPALIVE_VALS is supported on Win2K+ only - if AEnabled and (System.OperatingSystem.Version.Major >= 5) then - begin - SetLength(LBuf, 12); - CopyTIdUInt32(1, LBuf, 0); - CopyTIdUInt32(ATimeMS, LBuf, 4); - CopyTIdUInt32(AInterval, LBuf, 8); - ASocket.IOControl( - {$IFDEF DOTNET_2_OR_ABOVE}IOControlCode.KeepAliveValues{$ELSE}SIO_KEEPALIVE_VALS{$ENDIF}, - LBuf, nil); - end else begin - LBuf := nil; - ASocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, iif(AEnabled, 1, 0)); - end; -end; - -initialization - GSocketListClass := TIdSocketListDotNet; - {$IFDEF DOTNET_2_OR_ABOVE} - GServeFileProc := ServeFile; - {$ENDIF} -end. +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.8 10/26/2004 8:12:30 PM JPMugaas + Now uses TIdStrings and TIdStringList for portability. + + Rev 1.7 6/11/2004 8:28:56 AM DSiders + Added "Do not Localize" comments. + + Rev 1.6 5/14/2004 12:14:50 PM BGooijen + Fix for weird dotnet bug when querying the local binding + + Rev 1.5 4/18/04 2:45:54 PM RLebeau + Conversion support for Int64 values + + Rev 1.4 2004.03.07 11:45:26 AM czhower + Flushbuffer fix + other minor ones found + + Rev 1.3 3/6/2004 5:16:30 PM JPMugaas + Bug 67 fixes. Do not write to const values. + + Rev 1.2 2/10/2004 7:33:26 PM JPMugaas + I had to move the wrapper exception here for DotNET stack because Borland's + update 1 does not permit unlisted units from being put into a package. That + now would report an error and I didn't want to move IdExceptionCore into the + System package. + + Rev 1.1 2/4/2004 8:48:30 AM JPMugaas + Should compile. + + Rev 1.0 2004.02.03 3:14:46 PM czhower + Move and updates + + Rev 1.32 2/1/2004 6:10:54 PM JPMugaas + GetSockOpt. + + Rev 1.31 2/1/2004 3:28:32 AM JPMugaas + Changed WSGetLocalAddress to GetLocalAddress and moved into IdStack since + that will work the same in the DotNET as elsewhere. This is required to + reenable IPWatch. + + Rev 1.30 1/31/2004 1:12:54 PM JPMugaas + Minor stack changes required as DotNET does support getting all IP addresses + just like the other stacks. + + Rev 1.29 2004.01.22 2:46:52 PM czhower + Warning fixed. + + Rev 1.28 12/4/2003 3:14:54 PM BGooijen + Added HostByAddress + + Rev 1.27 1/3/2004 12:22:14 AM BGooijen + Added function SupportsIPv6 + + Rev 1.26 1/2/2004 4:24:08 PM BGooijen + This time both IPv4 and IPv6 work + + Rev 1.25 02/01/2004 15:58:00 HHariri + fix for bind + + Rev 1.24 12/31/2003 9:52:00 PM BGooijen + Added IPv6 support + + Rev 1.23 10/28/2003 10:12:36 PM BGooijen + DotNet + + Rev 1.22 10/26/2003 10:31:16 PM BGooijen + oops, checked in debug version , this is the right one + + Rev 1.21 10/26/2003 5:04:26 PM BGooijen + UDP Server and Client + + Rev 1.20 10/21/2003 11:03:50 PM BGooijen + More SendTo, ReceiveFrom + + Rev 1.19 10/21/2003 9:24:32 PM BGooijen + Started on SendTo, ReceiveFrom + + Rev 1.18 10/19/2003 5:21:30 PM BGooijen + SetSocketOption + + Rev 1.17 10/11/2003 4:16:40 PM BGooijen + Compiles again + + Rev 1.16 10/5/2003 9:55:28 PM BGooijen + TIdTCPServer works on D7 and DotNet now + + Rev 1.15 10/5/2003 3:10:42 PM BGooijen + forgot to clone the Sockets list in some Select methods, + added Listen and + Accept + + Rev 1.14 10/5/2003 1:52:14 AM BGooijen + Added typecasts with network ordering calls, there are required for some + reason + + Rev 1.13 10/4/2003 10:39:38 PM BGooijen + Renamed WSXXX functions in implementation section too + + Rev 1.12 04/10/2003 22:32:00 HHariri + moving of WSNXXX method to IdStack and renaming of the DotNet ones + + Rev 1.11 04/10/2003 21:28:42 HHariri + Netowkr ordering functions + + Rev 1.10 10/3/2003 11:02:02 PM BGooijen + fixed calls to Socket.Select + + Rev 1.9 10/3/2003 11:39:38 PM GGrieve + more work + + Rev 1.8 10/3/2003 12:09:32 AM BGooijen + DotNet + + Rev 1.7 10/2/2003 8:23:52 PM BGooijen + .net + + Rev 1.6 10/2/2003 8:08:52 PM BGooijen + .Connect works not in .net + + Rev 1.5 10/2/2003 7:31:20 PM BGooijen + .net + + Rev 1.4 10/2/2003 6:12:36 PM GGrieve + work in progress (hardly started) + + Rev 1.3 2003.10.01 9:11:24 PM czhower + .Net + + Rev 1.2 2003.10.01 5:05:18 PM czhower + .Net + + Rev 1.1 2003.10.01 1:12:40 AM czhower + .Net + + Rev 1.0 2003.09.30 10:35:40 AM czhower + Initial Checkin +} + +unit IdStackDotNet; + +interface + +{$i IdCompilerDefines.inc} + +uses + Classes, + IdGlobal, IdStack, IdStackConsts, + System.Collections, System.IO, System.Net, System.Net.Sockets; + +type + TIdStackDotNet = class(TIdStack) + protected + //Stuff for ICMPv6 + {$IFDEF DOTNET_2_OR_ABOVE} + procedure QueryRoute(s : TIdStackSocketHandle; const AIP: String; + const APort: TIdPort; var VSource, VDest : TIdBytes); + procedure WriteChecksumIPv6(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort); + {$ENDIF} + function ReadHostName: string; override; + function HostByName(const AHostName: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; + //internal IP Mutlicasting membership stuff + procedure MembershipSockOpt(AHandle: TIdStackSocketHandle; + const AGroupIP, ALocalIP : String; const ASockOpt : TIdSocketOption; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); + public + [ThreadStatic] + LastSocketError: Integer; //static; + constructor Create; override; + destructor Destroy; override; + procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; const APort: TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION ); override; + procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + procedure Disconnect(ASocket: TIdStackSocketHandle); override; + procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; + procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; + function WSGetLastError: Integer; override; + procedure WSSetLastError(const AErr : Integer); override; + function NewSocketHandle(const ASocketType: TIdSocketType; + const AProtocol: TIdSocketProtocol; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION; + const ANonBlocking: Boolean = False) : TIdStackSocketHandle; override; + // Result: + // > 0: Number of bytes received + // 0: Connection closed gracefully + // Will raise exceptions in other cases + function Receive(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes) : Integer; override; + function Send(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; + const AOffset: Integer = 0; const ASize: Integer = -1): Integer; override; + function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; + var arg: UInt32): Integer; override; + function ReceiveFrom(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; override; + function ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; + APkt: TIdPacketInfo): UInt32; override; + function SendTo(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; + const AOffset: Integer; const ASize: Integer; const AIP: string; const APort: TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): Integer; override; + function HostToNetwork(AValue: UInt16): UInt16; override; + function NetworkToHost(AValue: UInt16): UInt16; override; + function HostToNetwork(AValue: UInt32): UInt32; override; + function NetworkToHost(AValue: UInt32): UInt32; override; + function HostToNetwork(AValue: TIdUInt64): TIdUInt64; override; + function NetworkToHost(AValue: TIdUInt64): TIdUInt64; override; + function HostByAddress(const AAddress: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; + procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer);override; + function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; + var VIPVersion: TIdIPVersion): TIdStackSocketHandle; override; + procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; out AOptVal: Integer); override; + procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel:TIdSocketOptionLevel; + AOptName: TIdSocketOption; AOptVal: Integer); overload; override; + function SupportsIPv4: Boolean; override; + function SupportsIPv6: Boolean; override; + //multicast stuff Kudzu permitted me to add here. + procedure SetMulticastTTL(AHandle: TIdStackSocketHandle; const AValue : Byte; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + procedure SetLoopBack(AHandle: TIdStackSocketHandle; const AValue: Boolean; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + procedure DropMulticastMembership(AHandle: TIdStackSocketHandle; + const AGroupIP, ALocalIP : String; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + procedure AddMulticastMembership(AHandle: TIdStackSocketHandle; + const AGroupIP, ALocalIP : String; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + procedure WriteChecksum(s : TIdStackSocketHandle; var VBuffer : TIdBytes; + const AOffset : Integer; const AIP : String; const APort : TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); override; + procedure SetKeepAliveValues(ASocket: TIdStackSocketHandle; + const AEnabled: Boolean; const ATimeMS, AInterval: Integer); override; + end; + {$IFDEF DOTNET_1_1} + EIdNotSupportedInMicrosoftNET11 = class(EIdStackError); + {$ENDIF} + +var + GDotNETStack : TIdStackDotNet = nil; + +implementation + +uses + IdException, IdResourceStrings; + +const + IdIPFamily : array[TIdIPVersion] of AddressFamily = (AddressFamily.InterNetwork, AddressFamily.InterNetworkV6); + +{ TIdStackDotNet } + +procedure DoRaiseException(AStack: TIdStackDotNet; AException: System.Exception); +var + LSocketError : System.Net.Sockets.SocketException; + E: EIdException; +begin + if AException is System.Net.Sockets.SocketException then + begin + LSocketError := AException as System.Net.Sockets.SocketException; + AStack.LastSocketError := LSocketError.ErrorCode; + E := EIdSocketError.CreateError(LSocketError.ErrorCode, LSocketError.Message) + end else begin + E := EIdWrapperException.Create(AException.Message, AException); + end; + IndyRaiseOuterException(E); +end; + +{ TIdStackDotNet } + +constructor TIdStackDotNet.Create; +begin + inherited Create; + GDotNETStack := Self; +end; + +destructor TIdStackDotNet.Destroy; +begin + GDotNETStack := nil; + inherited Destroy; +end; + +procedure TIdStackDotNet.Bind(ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LIPAddr : IPAddress; + LEndPoint : IPEndPoint; + LIP: String; +begin + try + if not (AIPVersion in [Id_IPv4, Id_IPv6]) then + begin + IPVersionUnsupported; + end; + LIP := AIP; + if LIP = '' then begin + if AIPVersion = Id_IPv4 then begin + LIPAddr := IPAddress.Any; + end else begin + LIPAddr := IPAddress.IPv6Any; + end; + end else begin + LIPAddr := IPAddress.Parse(LIP); + end; + LEndPoint := IPEndPoint.Create(LIPAddr, APort); + ASocket.Bind(LEndPoint); + except + on e: Exception do begin + DoRaiseException(Self, e); + end; + end; +end; + +procedure TIdStackDotNet.Connect(const ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LEndPoint : IPEndPoint; +begin + try + LEndPoint := IPEndPoint.Create(IPAddress.Parse(AIP), APort); + ASocket.Connect(LEndPoint); + except + on e: Exception do begin + DoRaiseException(Self, e); + end; + end; +end; + +procedure TIdStackDotNet.Disconnect(ASocket: TIdStackSocketHandle); +begin + try + ASocket.Close; + except + on e: Exception do begin + DoRaiseException(Self, e); + end; + end; +end; + +procedure TIdStackDotNet.Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); +begin + try + ASocket.Listen(ABackLog); + except + on e: Exception do begin + DoRaiseException(Self, e); + end; + end; +end; + +function TIdStackDotNet.Accept(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): TIdStackSocketHandle; +var + LEndPoint: IPEndPoint; +begin + try + Result := ASocket.Accept(); + LEndPoint := Result.RemoteEndPoint as IPEndPoint; + + if (Result.AddressFamily = AddressFamily.InterNetwork) or + (Result.AddressFamily = AddressFamily.InterNetworkV6) then + begin + VIP := LEndPoint.Address.ToString(); + VPort := LEndPoint.Port; + if Result.AddressFamily = AddressFamily.InterNetworkV6 then begin + VIPVersion := Id_IPv6; + end else begin + VIPVersion := Id_IPv4; + end; + end else + begin + Result := Id_INVALID_SOCKET; + IPVersionUnsupported; + end; + except + on e: Exception do begin + DoRaiseException(Self, e); + end; + end; +end; + +procedure TIdStackDotNet.GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); +var + LEndPoint : IPEndPoint; +begin + try + if (ASocket.AddressFamily = AddressFamily.InterNetwork) or + (ASocket.AddressFamily = AddressFamily.InterNetworkV6) then + begin + LEndPoint := ASocket.RemoteEndPoint as IPEndPoint; + + VIP := LEndPoint.Address.ToString; + VPort := LEndPoint.Port; + if ASocket.AddressFamily = AddressFamily.InterNetworkV6 then begin + VIPVersion := Id_IPv6; + end else begin + VIPVersion := Id_IPv4; + end; + end else begin + IPVersionUnsupported; + end; + except + on e: Exception do begin + DoRaiseException(Self, e); + end; + end; +end; + +procedure TIdStackDotNet.GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); +var + LEndPoint : IPEndPoint; +begin + try + if (ASocket.AddressFamily = AddressFamily.InterNetwork) or + (ASocket.AddressFamily = AddressFamily.InterNetworkV6) then + begin + LEndPoint := ASocket.LocalEndPoint as IPEndPoint; + + VIP := LEndPoint.Address.ToString; + VPort := LEndPoint.Port; + if ASocket.AddressFamily = AddressFamily.InterNetworkV6 then begin + VIPVersion := Id_IPv6; + end else begin + VIPVersion := Id_IPv4; + end; + end else begin + IPVersionUnsupported; + end; + except + on e: Exception do begin + DoRaiseException(Self, e); + end; + end; +end; + +function TIdStackDotNet.HostByName(const AHostName: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; +var + LIP: array of IPAddress; + a: Integer; +begin + try + { + [Warning] IdStackDotNet.pas(417): W1000 Symbol 'Resolve' is deprecated: + 'Resolve is obsoleted for this type, please use GetHostEntry instead. + http://go.microsoft.com/fwlink/?linkid=14202' + } + {$IFDEF DOTNET_2_OR_ABOVE} + LIP := Dns.GetHostEntry(AHostName).AddressList; + {$ENDIF} + {$IFDEF DOTNET_1_1} + LIP := Dns.Resolve(AHostName).AddressList; + {$ENDIF} + for a := Low(LIP) to High(LIP) do begin + if LIP[a].AddressFamily = IdIPFamily[AIPVersion] then begin + Result := LIP[a].ToString; + Exit; + end; + end; + raise System.Net.Sockets.SocketException.Create(11001); + except + on e: Exception do begin + DoRaiseException(Self, e); + end; + end; +end; + +function TIdStackDotNet.HostByAddress(const AAddress: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; +begin + try + {$IFDEF DOTNET_2_OR_ABOVE} + Result := Dns.GetHostEntry(AAddress).HostName; + {$ENDIF} + {$IFDEF DOTNET_1_1} + Result := Dns.GetHostByAddress(AAddress).HostName; + {$ENDIF} + except + on e: Exception do begin + DoRaiseException(Self, e); + end; + end; +end; + +function TIdStackDotNet.WSGetLastError: Integer; +begin + Result := LastSocketError; +end; + +procedure TIdStackDotNet.WSSetLastError(const AErr : Integer); +begin + LastSocketError := AErr; +end; + +function TIdStackDotNet.NewSocketHandle(const ASocketType: TIdSocketType; + const AProtocol: TIdSocketProtocol; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION; + const ANonBlocking: Boolean = False): TIdStackSocketHandle; +begin + try + Result := Socket.Create(IdIPFamily[AIPVersion], ASocketType, AProtocol); + Result.Blocking := not ANonBlocking; + except + on E: Exception do begin + DoRaiseException(Self, E); + end; + end; +end; + +function TIdStackDotNet.ReadHostName: string; +begin + try + Result := System.Net.DNS.GetHostName; + except + on E: Exception do begin + DoRaiseException(Self, e); + end; + end; +end; + +function TIdStackDotNet.Receive(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes): Integer; +begin + try + Result := ASocket.Receive(VBuffer, Length(VBuffer), SocketFlags.None); + except + on e: Exception do begin + DoRaiseException(Self, e); + end; + end; +end; + +function TIdStackDotNet.Send(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; + const AOffset: Integer = 0; const ASize: Integer = -1): Integer; +var + Tmp: TIdBytes; +begin + Result := IndyLength(ABuffer, ASize, AOffset); + try + if Result > 0 then begin + Result := ASocket.Send(ABuffer, AOffset, Result, SocketFlags.None); + end else + begin + // RLebeau: this is to allow UDP sockets to send 0-length packets. Send() + // raises an exception if its buffer parameter is nil, and a 0-length byte + // array is nil... + // + // TODO: check the socket type and only allow this for UDP sockets... + // + SetLength(Tmp, 1); + Tmp[0] := $00; + Result := ASocket.Send(Tmp, 0, 0, SocketFlags.None); + end; + except + on E: Exception do begin + DoRaiseException(Self, E); + end; + end; +end; + +function TIdStackDotNet.ReceiveFrom(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; +var + LIPAddr : IPAddress; + LEndPoint : EndPoint; +begin + Result := 0; // to make the compiler happy + case ASocket.AddressFamily of + AddressFamily.InterNetwork: LIPAddr := IPAddress.Any; + AddressFamily.InterNetworkV6: LIPAddr := IPAddress.IPv6Any; + else + IPVersionUnsupported; + end; + LEndPoint := IPEndPoint.Create(LIPAddr, 0); + try + try + Result := ASocket.ReceiveFrom(VBuffer, SocketFlags.None, LEndPoint); + except + on e: Exception do begin + DoRaiseException(Self, e); + end; + end; + VIP := IPEndPoint(LEndPoint).Address.ToString; + VPort := IPEndPoint(LEndPoint).Port; + case IPEndPoint(LEndPoint).AddressFamily of + AddressFamily.InterNetwork: VIPVersion := Id_IPv4; + AddressFamily.InterNetworkV6: VIPVersion := Id_IPv6; + end; + finally + LEndPoint.Free; + end; +end; + +function TIdStackDotNet.SendTo(ASocket: TIdStackSocketHandle; const ABuffer: TIdBytes; + const AOffset: Integer; const ASize: Integer; const AIP: string; const APort: TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): Integer; +var + LEndPoint : EndPoint; + Tmp: TIdBytes; +begin + Result := IndyLength(ABuffer, ASize, AOffset); + try + LEndPoint := IPEndPoint.Create(IPAddress.Parse(AIP), APort); + try + if Result > 0 then begin + Result := ASocket.SendTo(ABuffer, AOffset, Result, SocketFlags.None, LEndPoint); + end else + begin + // RLebeau: this is to allow UDP sockets to send 0-length packets. SendTo() + // raises an exception if its buffer parameter is nil, and a 0-length byte + // array is nil... + // + // TODO: check the socket type and only allow this for UDP sockets... + // + SetLength(Tmp, 1); + Tmp[0] := $00; + Result := ASocket.SendTo(Tmp, 0, 0, SocketFlags.None, LEndPoint); + end. + finally + LEndPoint.Free; + end; + except + on e: Exception do begin + DoRaiseException(Self, e); + end; + end; +end; + +////////////////////////////////////////////////////////////// + +type + TIdSocketListDotNet = class(TIdSocketList) + protected + FSockets: ArrayList; + function GetItem(AIndex: Integer): TIdStackSocketHandle; override; + public + constructor Create; override; + destructor Destroy; override; + procedure Add(AHandle: TIdStackSocketHandle); override; + procedure Remove(AHandle: TIdStackSocketHandle); override; + function Count: Integer; override; + procedure Clear; override; + function Clone: TIdSocketList; override; + function ContainsSocket(AHandle: TIdStackSocketHandle): boolean; override; + class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; + AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + function SelectReadList(var VSocketList: TIdSocketList; + const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + end; + +constructor TIdSocketListDotNet.Create; +begin + inherited Create; + FSockets := ArrayList.Create; +end; + +destructor TIdSocketListDotNet.Destroy; +begin + FSockets.Free; + inherited Destroy; +end; + +procedure TIdSocketListDotNet.Add(AHandle: TIdStackSocketHandle); +begin + FSockets.Add(AHandle); +end; + +procedure TIdSocketListDotNet.Clear; +begin + FSockets.Clear; +end; + +function TIdSocketListDotNet.ContainsSocket(AHandle: TIdStackSocketHandle): Boolean; +begin + Result := FSockets.Contains(AHandle); +end; + +function TIdSocketListDotNet.Count: Integer; +begin + Result := FSockets.Count; +end; + +function TIdSocketListDotNet.GetItem(AIndex: Integer): TIdStackSocketHandle; +begin + Result := (FSockets.Item[AIndex]) as TIdStackSocketHandle; +end; + +procedure TIdSocketListDotNet.Remove(AHandle: TIdStackSocketHandle); +begin + FSockets.Remove(AHandle); +end; + +const + cMaxMSPerLoop = MaxInt div 1000; // max milliseconds per Socket.Select() call + +function TIdSocketListDotNet.SelectRead(const ATimeout: Integer): Boolean; +var + LTimeout: Integer; + + function DoSelect(const AInterval: Integer): Boolean; + var + LTemp: ArrayList; + begin + // DotNet updates this object on return, so we need to copy it each time we need it + LTemp := ArrayList(FSockets.Clone); + try + Socket.Select(LTemp, nil, nil, AInterval); + Result := LTemp.Count > 0; + finally + LTemp.Free; + end; + end; + +begin + Result := False; + try + // RLebeau 8/27/2007: the .NET docs say that -1 is supposed to + // cause an infinite timeout, but it doesn't actually work! + // So loop manually instead until Microsoft fixes it... + if ATimeout = IdTimeoutInfinite then + begin + repeat + Result := DoSelect(MaxInt); + until Result; + end else + begin + // RLebeau: Select() accepts a timeout in microseconds, not + // milliseconds, so have to loop anyway to handle timeouts + // that are greater then 35 minutes... + LTimeout := ATimeout; + while LTimeout >= cMaxMSPerLoop do + begin + Result := DoSelect(cMaxMSPerLoop * 1000); + if Result then begin + Exit; + end; + Dec(LTimeout, cMaxMSPerLoop); + end; + if (not Result) and (LTimeout > 0) then begin + Result := DoSelect(LTimeout * 1000); + end; + end; + except + on e: ArgumentNullException do begin + Result := False; + end; + on e: Exception do begin + DoRaiseException(GDotNETStack, e); + end; + end; +end; + +function TIdSocketListDotNet.SelectReadList(var VSocketList: TIdSocketList; + const ATimeout: Integer): Boolean; +var + LTemp: ArrayList; + LTimeout: Integer; + + function DoSelect(const AInterval: Integer; var VList: ArrayList): Boolean; + var + LLTemp: ArrayList; + begin + // DotNet updates this object on return, so we need to copy it each time we need it + LLTemp := ArrayList(FSockets.Clone); + try + Socket.Select(LLTemp, nil, nil, AInterval); + Result := LLTemp.Count > 0; + if Result then + begin + VList := LLTemp; + LLTemp := nil; + end; + finally + LLTemp.Free; + end; + end; + +begin + Result := False; + try + // RLebeau 8/27/2007: the .NET docs say that -1 is supposed to + // cause an infinite timeout, but it doesn't actually work! + // So loop manually instead until Microsoft fixes it... + if ATimeout = IdTimeoutInfinite then + begin + repeat + Result := DoSelect(MaxInt, LTemp); + until Result; + end else + begin + // RLebeau: Select() accepts a timeout in microseconds, not + // milliseconds, so have to loop anyway to handle timeouts + // that are greater then 35 minutes... + LTimeout := ATimeout; + while LTimeout >= cMaxMSPerLoop do + begin + Result := DoSelect(cMaxMSPerLoop * 1000, LTemp); + if Result then begin + Break; + end; + Dec(LTimeout, cMaxMSPerLoop); + end; + if (not Result) and (LTimeout > 0) then begin + Result := DoSelect(LTimeout * 1000, LTemp); + end; + end; + if Result then + begin + try + if VSocketList = nil then begin + VSocketList := TIdSocketList.CreateSocketList; + end; + TIdSocketListDotNet(VSocketList).FSockets.Free; + TIdSocketListDotNet(VSocketList).FSockets := LTemp; + except + LTemp.Free; + raise; + end; + end; + except + on e: ArgumentNullException do begin + Result := False; + end; + on e: Exception do begin + DoRaiseException(GDotNETStack, e); + end; + end; +end; + +class function TIdSocketListDotNet.Select(AReadList, AWriteList, AExceptList: TIdSocketList; + const ATimeout: Integer): Boolean; +var + LTimeout: Integer; + LReadTemp, LWriteTemp, LExceptTemp: ArrayList; + + function DoSelect(var VReadList, VWriteList, VExceptList: ArrayList; + const AInterval: Integer): Boolean; + var + LLReadTemp: ArrayList; + LLWriteTemp: ArrayList; + LLExceptTemp: ArrayList; + begin + LLReadTemp := nil; + LLWriteTemp := nil; + LLExceptTemp := nil; + + VReadList := nil; + VWriteList := nil; + VExceptList := nil; + + // DotNet updates these objects on return, so we need to copy them each time we need them + if Assigned(AReadList) and Assigned(TIdSocketListDotNet(AReadList).FSockets) then begin + LLReadTemp := ArrayList(TIdSocketListDotNet(AReadList).FSockets.Clone); + end; + try + if Assigned(AWriteList) and Assigned(TIdSocketListDotNet(AWriteList).FSockets) then begin + LLWriteTemp := ArrayList(TIdSocketListDotNet(AWriteList).FSockets.Clone); + end; + try + if Assigned(AExceptList) and Assigned(TIdSocketListDotNet(AExceptList).FSockets) then begin + LLExceptTemp := ArrayList(TIdSocketListDotNet(AExceptList).FSockets.Clone); + end; + try + Socket.Select(LLReadTemp, LLWriteTemp, LLExceptTemp, AInterval); + Result := (LLReadTemp.Count > 0) or + (LLWriteTemp.Count > 0) or + (LLExceptTemp.Count > 0); + if Result then + begin + VReadList := LLReadTemp; + LLReadTemp:= nil; + + VWriteList := LLWriteTemp; + LLWriteTemp:= nil; + + VExceptList := LLExceptTemp; + LLExceptTemp:= nil; + end; + finally + LLExceptTemp.Free; + end; + finally + LLWriteTemp.Free; + end; + finally + LLReadTemp.Free; + end; + end; + +begin + Result := False; + try + // RLebeau 8/27/2007: the .NET docs say that -1 is supposed to + // cause an infinite timeout, but it doesn't actually work! + // So loop manually instead until Microsoft fixes it... + if ATimeout = IdTimeoutInfinite then + begin + repeat + Result := DoSelect( + LReadTemp, LWriteTemp, LExceptTemp, + MaxInt); + until Result; + end else + begin + // RLebeau: Select() accepts a timeout in microseconds, not + // milliseconds, so have to loop anyway to handle timeouts + // that are greater then 35 minutes... + LTimeout := ATimeout; + while LTimeout >= cMaxMSPerLoop do + begin + Result := DoSelect( + LReadTemp, LWriteTemp, LExceptTemp, + cMaxMSPerLoop * 1000); + if Result then begin + Break; + end; + Dec(LTimeout, cMaxMSPerLoop); + end; + if (not Result) and (LTimeout > 0) then + begin + Result := DoSelect( + LReadTemp, LWriteTemp, LExceptTemp, + LTimeout * 1000); + end; + end; + // RLebeau: this method is meant to update the + // source lists inlined regardless of the Result... + if Assigned(AReadList) then + begin + TIdSocketListDotNet(AReadList).FSockets.Free; + TIdSocketListDotNet(AReadList).FSockets := LReadTemp; + end; + if Assigned(AWriteList) then + begin + TIdSocketListDotNet(AWriteList).FSockets.Free; + TIdSocketListDotNet(AWriteList).FSockets := LWriteTemp; + end; + if Assigned(AExceptList) then + begin + TIdSocketListDotNet(AExceptList).FSockets.Free; + TIdSocketListDotNet(AExceptList).FSockets := LExceptTemp; + end; + except + on e: ArgumentNullException do begin + Result := False; + end; + on e: Exception do begin + DoRaiseException(GDotNETStack, e); + end; + end; +end; + +function TIdSocketListDotNet.Clone: TIdSocketList; +begin + Result := TIdSocketListDotNet.Create; //BGO: TODO: make prettier + TIdSocketListDotNet(Result).FSockets.Free; + TIdSocketListDotNet(Result).FSockets := ArrayList(FSockets.Clone); +end; + +function TIdStackDotNet.HostToNetwork(AValue: UInt16): UInt16; +begin + Result := UInt16(IPAddress.HostToNetworkOrder(Int16(AValue))); +end; + +function TIdStackDotNet.HostToNetwork(AValue: UInt32): UInt32; +begin + Result := UInt32(IPAddress.HostToNetworkOrder(Int32(AValue))); +end; + +function TIdStackDotNet.HostToNetwork(AValue: TIdUInt64): TIdUInt64; +begin + Result := TIdUInt64(IPAddress.HostToNetworkOrder(Int64(AValue))); +end; + +function TIdStackDotNet.NetworkToHost(AValue: UInt16): UInt16; +begin + Result := UInt16(IPAddress.NetworkToHostOrder(Int16(AValue))); +end; + +function TIdStackDotNet.NetworkToHost(AValue: UInt32): UInt32; +begin + Result := UInt32(IPAddress.NetworkToHostOrder(Int32(AValue))); +end; + +function TIdStackDotNet.NetworkToHost(AValue: TIdUInt64): TIdUInt64; +begin + Result := TIdUInt64(IPAddress.NetworkToHostOrder(Int64(AValue)); +end; + +procedure TIdStackDotNet.GetSocketOption(ASocket: TIdStackSocketHandle; + ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; out AOptVal: Integer); +var + L : System.Object; +begin + L := ASocket.GetSocketOption(ALevel, AoptName); + AOptVal := Integer(L); +end; + +procedure TIdStackDotNet.SetSocketOption(ASocket: TIdStackSocketHandle; + ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; AOptVal: Integer); +begin + ASocket.SetSocketOption(ALevel, AOptName, AOptVal); +end; + +function TIdStackDotNet.SupportsIPv4: Boolean; +begin + { + [Warning] IdStackDotNet.pas(734): W1000 Symbol 'SupportsIPv4' is deprecated: + 'SupportsIPv4 is obsoleted for this type, please use OSSupportsIPv4 instead. + http://go.microsoft.com/fwlink/?linkid=14202' + } + {$IFDEF DOTNET_2_OR_ABOVE} + Result := Socket.OSSupportsIPv4; + {$ENDIF} + {$IFDEF DOTNET_1_1} + Result := Socket.SupportsIPv4; + {$ENDIF} +end; + +function TIdStackDotNet.SupportsIPv6: Boolean; +begin + { + [Warning] IdStackDotNet.pas(734): W1000 Symbol 'SupportsIPv6' is deprecated: + 'SupportsIPv6 is obsoleted for this type, please use OSSupportsIPv6 instead. + http://go.microsoft.com/fwlink/?linkid=14202' + } + {$IFDEF DOTNET_2_OR_ABOVE} + Result := Socket.OSSupportsIPv6; + {$ENDIF} + {$IFDEF DOTNET_1_1} + Result := Socket.SupportsIPv6; + {$ENDIF} +end; + +procedure TIdStackDotNet.GetLocalAddressList(AAddresses: TIdStackLocalAddressList); +var + {$IFDEF DOTNET_1_1} + LAddr : IPAddress; + {$ENDIF} + LHost : IPHostEntry; + LIPAddresses: array of IPAddress; + LIPAddress: IPAddress; + i : Integer; +begin + {$IFDEF DOTNET_2_OR_ABOVE} + // TODO: use NetworkInterface.GetAllNetworkInterfaces() instead. + // See this article for an example: + // http://blogs.msdn.com/b/dgorti/archive/2005/10/04/477078.aspx + LHost := DNS.GetHostEntry(DNS.GetHostName); + {$ENDIF} + {$IFDEF DOTNET_1_1} + LAddr := IPAddress.Any; + LHost := DNS.GetHostByAddress(LAddr); + {$ENDIF} + LIPAddresses := LHost.AddressList; + if Length(LIPAddresses) > 0 then + begin + AAddresses.BeginUpdate; + try + for i := Low(LIPAddresses) to High(LIPAddresses) do + begin + LIPAddress := LIPAddresses[i]; + //This may be returning various types of addresses. + case LIPAddress.AddressFamily of + AddressFamily.InterNetwork: begin + TIdStackLocalAddressIPv4.Create(AAddresses, LIPAddress.ToString, ''); // TODO: SubNet + end; + AddressFamily.InterNetworkV6: begin + TIdStackLocalAddressIPv6.Create(AAddresses, LIPAddress.ToString); + end; + end; + end; + finally + AAddresses.EndUpdate; + end; + end; +end; + +procedure TIdStackDotNet.SetLoopBack(AHandle: TIdStackSocketHandle; + const AValue: Boolean; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +begin + //necessary because SetSocketOption only accepts an integer + //see: http://groups-beta.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/6a35c6d9052cfc2b/f01fea11f9a24508?q=SetSocketOption+DotNET&rnum=2&hl=en#f01fea11f9a24508 + AHandle.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastLoopback, iif(AValue, 1, 0)); +end; + +procedure TIdStackDotNet.DropMulticastMembership(AHandle: TIdStackSocketHandle; + const AGroupIP, ALocalIP: String; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +begin + MembershipSockOpt(AHandle, AGroupIP, ALocalIP, SocketOptionName.DropMembership); +end; + +procedure TIdStackDotNet.AddMulticastMembership(AHandle: TIdStackSocketHandle; + const AGroupIP, ALocalIP: String; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +begin + MembershipSockOpt(AHandle, AGroupIP, ALocalIP, SocketOptionName.AddMembership); +end; + +procedure TIdStackDotNet.SetMulticastTTL(AHandle: TIdStackSocketHandle; + const AValue: Byte; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +begin + if AIPVersion = Id_IPv4 then begin + AHandle.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, AValue); + end else begin + AHandle.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.MulticastTimeToLive, AValue); + end; +end; + +procedure TIdStackDotNet.MembershipSockOpt(AHandle: TIdStackSocketHandle; + const AGroupIP, ALocalIP: String; const ASockOpt: TIdSocketOption; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LM4 : MulticastOption; + LM6 : IPv6MulticastOption; + LGroupIP, LLocalIP : System.Net.IPAddress; +begin + LGroupIP := IPAddress.Parse(AGroupIP); + if LGroupIP.AddressFamily = AddressFamily.InterNetworkV6 then + begin + LM6 := IPv6MulticastOption.Create(LGroupIP); + AHandle.SetSocketOption(SocketOptionLevel.IPv6, ASockOpt, LM6); + end else + begin + if ALocalIP.Length = 0 then begin + LM4 := System.Net.Sockets.MulticastOption.Create(LGroupIP); + end else + begin + LLocalIP := IPAddress.Parse(ALocalIP); + LM4 := System.Net.Sockets.MulticastOption.Create(LGroupIP, LLocalIP); + end; + AHandle.SetSocketOption(SocketOptionLevel.IP, ASockOpt, LM4); + end; +end; + +function TIdStackDotNet.ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; + APkt: TIdPacketInfo): UInt32; +var + {$IFDEF DOTNET_1_1} + LIP : String; + LPort : TIdPort; + LIPVersion: TIdIPVersion; + {$ELSE} + LSF : SocketFlags; + LIPAddr : IPAddress; + LRemEP : EndPoint; + LPki : IPPacketInformation; + {$ENDIF} +begin + {$IFDEF DOTNET_1_1} + Result := ReceiveFrom(ASocket, VBuffer, LIP, LPort, LIPVersion); + APkt.Reset; + APkt.SourceIP := LIP; + APkt.SourcePort := LPort; + APkt.SourceIPVersion := LIPVersion; + APkt.DestIPVersion := LIPVersion; + {$ELSE} + LSF := SocketFlags.None; + { + The AddressFamily of the EndPoint used in ReceiveFrom needs to match the + AddressFamily of the EndPoint used in SendTo. + } + case ASocket.AddressFamily of + AddressFamily.InterNetwork: LIPAddr := IPAddress.Any; + AddressFamily.InterNetworkV6: LIPAddr := IPAddress.IPv6Any; + else + Result := 0; // keep the compiler happy + IPVersionUnsupported; + end; + LRemEP := IPEndPoint.Create(LIPAddr, 0); + Result := ASocket.ReceiveMessageFrom(VBuffer, 0, Length(VBUffer), LSF, LRemEP, lpki); + APkt.Reset; + APkt.SourceIP := IPEndPoint(LRemEP).Address.ToString; + APkt.SourcePort := IPEndPoint(LRemEP).Port; + case IPEndPoint(LRemEP).AddressFamily of + AddressFamily.InterNetwork: APkt.SourceIPVersion := Id_IPv4; + AddressFamily.InterNetworkV6: APkt.SourceIPVersion := Id_IPv6; + end; + APkt.DestIP := LPki.Address.ToString; + APkt.DestIF := LPki.&Interface; + APkt.DestIPVersion := APkt.SourceIPVersion; + {$ENDIF} +end; + +{ +This extracts an IP address as a series of bytes from a TIdBytes that contains +one SockAddress structure. +} +procedure SockAddrToIPBytes(const ASockAddr : TIdBytes; var VIPAddr : TIdBytes); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + case BytesToUInt16(ASockAddr,0) of + 23 : //AddressFamily.InterNetworkV6 : + begin + //16 = size of SOCKADDR_IN6.sin6_addr + SetLength(VIPAddr,16); +// 8 = offset of sin6_addr in SOCKADDR_IN6 +// sin6_family : Smallint; // AF_INET6 +// sin6_port : u_short; // Transport level port number +// sin6_flowinfo : u_long; // IPv6 flow information + + System.array.Copy(ASockAddr,8, VIPAddr, 0, 16); + end; + 2 : //AddressFamily.InterNetwork : + begin + //size of sockaddr_in.sin_addr + SetLength(VIPAddr,4); +// 4 = offset of sockaddr_in.sin_addr +// sin_family : u_short; +// sin_port : u_short; + System.array.Copy(ASockAddr,4, VIPAddr, 0, 4); + end; + end; +end; + +procedure TIdStackDotNet.QueryRoute(s : TIdStackSocketHandle; const AIP: String; + const APort: TIdPort; var VSource, VDest : TIdBytes); +{$IFDEF DOTNET_2_OR_ABOVE} +const + SIO_ROUTING_INTERFACE_QUERY = 3355443220; +{$ENDIF} +var + LEP : IPEndPoint; + LDestIF : SocketAddress; + LIn, LOut : TBytes; + i : Integer; +begin + LEP := IPEndPoint.Create(IPAddress.Parse(AIP),APort); + LDestIf := LEP.Serialize; +{ +The first 2 bytes of the underlying buffer are reserved for the AddressFamily +enumerated value. When the SocketAddress is used to store a serialized +IPEndPoint, the third and fourth bytes are used to store port number +information. The next bytes are used to store the IP address. You can access any +information within this underlying byte buffer by referring to its index +position; the byte buffer uses zero-based indexing. You can also use the Family +and Size properties to get the AddressFamily value and the buffer size, +respectively. To view any of this information as a string, use the ToString +method. +} + SetLength(LIn,LDestIf.Size); + for i := 0 to LDestIf.Size - 1 do + begin + LIn[i] := LDestIf[i]; + end; + SetLength(LOut,LDestIf.Size); +{ +IMPORTANT!!!! + +We can not do something like: + + s.IOControl( IOControlCode.RoutingInterfaceQuery, LIn, LOut); + + because to IOControlCode.RoutingInterfaceQuery has a value of -539371432 + and that is not correct. I found that out the hard way. +} + s.IOControl(LongInt(SIO_ROUTING_INTERFACE_QUERY),Lin,LOut); + SockAddrToIPBytes(LOut,VSource); + SockAddrToIPBytes(LIn,VDest); +end; + +procedure TIdStackDotNet.WriteChecksumIPv6(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort); +var + LSource : TIdBytes; + LDest : TIdBytes; + LTmp : TIdBytes; + LIdx : Integer; + LC : UInt32; +{ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + + + | | + + Source Address + + | | + + + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + + + | | + + Destination Address + + | | + + + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Upper-Layer Packet Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | zero | Next Header | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +} +begin + + QueryRoute(s, AIP, APort, LSource, LDest); + SetLength(LTmp, 40+Length(VBuffer)); + System.&Array.Clear(LTmp,0,Length(LTmp)); + //16 + CopyTIdBytes(LSource, 0, LTmp, 0, 16); + LIdx := 16; + //32 + CopyTIdBytes(LDest, 0, LTmp,LIdx, 16); + Inc(LIdx, 16); + //use a word so you don't wind up using the wrong network byte order function + LC := Length(VBuffer); + CopyTIdUInt32(HostToNetwork(LC), LTmp, LIdx); + Inc(LIdx, 4); + //36 + //zero the next three bytes + //done in the begging + Inc(LIdx, 3); + //next header (protocol type determines it + LTmp[LIdx] := Ord(Id_IPPROTO_ICMPv6); + Inc(LIdx); + //combine the two + CopyTIdBytes(VBuffer, 0, LTmp, LIdx, Length(VBuffer)); + //zero out the checksum field + CopyTIdUInt16(0, LTmp, LIdx+AOffset); + + CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(LTmp)), VBuffer, AOffset); +end; +{$ENDIF} + +procedure TIdStackDotNet.WriteChecksum(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort; const AIPVersion: TIdIPVersion); +begin + if AIPVersion = Id_IPv4 then begin + CopyTIdUInt16(CalcCheckSum(VBuffer), VBuffer, AOffset); + end else + begin + {$IFDEF DOTNET_1_1} + {This is a todo because to do a checksum for ICMPv6, you need to obtain + the address for the IP the packet will come from (query the network interfaces). + You then have to make a IPv6 pseudo header. About the only other alternative is + to have the kernel (or DotNET Framework) generate the checksum but we don't have + an API for it. + + I'm not sure if we have an API for it at all. Even if we did, would it be worth + doing when you consider that Microsoft's NET Framework 1.1 does not support ICMPv6 + in its enumerations.} + raise EIdNotSupportedInMicrosoftNET11.Create(RSNotSupportedInMicrosoftNET11); + {$ELSE} + WriteChecksumIPv6(s,VBuffer,AOffset,AIP,APort); + {$ENDIF} + end; +end; + +function TIdStackDotNet.IOControl(const s: TIdStackSocketHandle; + const cmd: UInt32; var arg: UInt32): Integer; +var + LTmp : TIdBytes; +begin + LTmp := ToBytes(arg); + s.IOControl(cmd, ToBytes(arg), LTmp); + arg := BytesToUInt32(LTmp); + Result := 0; +end; + +{$IFDEF DOTNET_2_OR_ABOVE} +function ServeFile(ASocket: TIdStackSocketHandle; const AFileName: string): Int64; +var + LFile : FileInfo; +begin + ASocket.SendFile(AFileName); + LFile := System.IO.FileInfo.Create(AFileName); + Result := LFile.Length; +end; +{$ENDIF} + +procedure TIdStackDotNet.SetKeepAliveValues(ASocket: TIdStackSocketHandle; + const AEnabled: Boolean; const ATimeMS, AInterval: Integer); +{$IFNDEF DOTNET_2_OR_ABOVE} +const + SIO_KEEPALIVE_VALS = 2550136836; +{$ENDIF} +var + LBuf: TIdBytes; +begin + // SIO_KEEPALIVE_VALS is supported on Win2K+ only + if AEnabled and (System.OperatingSystem.Version.Major >= 5) then + begin + SetLength(LBuf, 12); + CopyTIdUInt32(1, LBuf, 0); + CopyTIdUInt32(ATimeMS, LBuf, 4); + CopyTIdUInt32(AInterval, LBuf, 8); + ASocket.IOControl( + {$IFDEF DOTNET_2_OR_ABOVE}IOControlCode.KeepAliveValues{$ELSE}SIO_KEEPALIVE_VALS{$ENDIF}, + LBuf, nil); + end else begin + LBuf := nil; + ASocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, iif(AEnabled, 1, 0)); + end; +end; + +initialization + GSocketListClass := TIdSocketListDotNet; + {$IFDEF DOTNET_2_OR_ABOVE} + GServeFileProc := ServeFile; + {$ENDIF} +end. diff --git a/Lib/System/IdStackLibc.pas b/Lib/System/IdStackLibc.pas index 477c88587..79fb9c886 100644 --- a/Lib/System/IdStackLibc.pas +++ b/Lib/System/IdStackLibc.pas @@ -1,1484 +1,1484 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.7 10/26/2004 8:20:04 PM JPMugaas - Fixed some oversights with conversion. OOPS!!! - - Rev 1.6 10/26/2004 8:12:32 PM JPMugaas - Now uses TIdStrings and TIdStringList for portability. - - Rev 1.5 12/06/2004 15:17:20 CCostelloe - Restructured to correspond with IdStackWindows, now works. - - Rev 1.4 07/06/2004 21:31:02 CCostelloe - Kylix 3 changes - - Rev 1.3 4/18/04 10:43:22 PM RLebeau - Fixed syntax error - - Rev 1.2 4/18/04 10:29:46 PM RLebeau - Renamed Int64Parts structure to TIdInt64Parts - - Rev 1.1 4/18/04 2:47:28 PM RLebeau - Conversion support for Int64 values - - Removed WSHToNs(), WSNToHs(), WSHToNL(), and WSNToHL() methods, obsolete - - Rev 1.0 2004.02.03 3:14:48 PM czhower - Move and updates - - Rev 1.3 10/19/2003 5:35:14 PM BGooijen - SetSocketOption - - Rev 1.2 2003.10.01 9:11:24 PM czhower - .Net - - Rev 1.1 7/5/2003 07:25:50 PM JPMugaas - Added functions to the Linux stack which use the new TIdIPAddress record type - for IP address parameters. I also fixed a compile bug. - - Rev 1.0 11/13/2002 08:59:24 AM JPMugaas -} - -unit IdStackLibc; - -interface - -{$i IdCompilerDefines.inc} - -uses - Classes, - Libc, - IdStack, - IdStackConsts, - IdGlobal, - IdStackBSDBase; - -{$UNDEF LIBCPASS_STRUCT} -{$IFDEF KYLIX} - {$DEFINE LIBCPASS_STRUCT} -{$ENDIF} -{$IFDEF DELPHI_CROSS} - {$DEFINE LIBCPASS_STRUCT} -{$ENDIF} -type - TIdStackLibc = class(TIdStackBSDBase) - private - procedure WriteChecksumIPv6(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort); - protected - function GetLastError : Integer; - procedure SetLastError(Const AError : Integer); - function HostByName(const AHostName: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; - function ReadHostName: string; override; - function WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; override; - function WSRecv(ASocket: TIdStackSocketHandle; - var ABuffer; const ABufferLength, AFlags: Integer): Integer; override; - function WSSend(ASocket: TIdStackSocketHandle; const ABuffer; const ABufferLength, AFlags: Integer): Integer; override; - function WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; override; - {$IFNDEF VCL_XE3_OR_ABOVE} - procedure WSGetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; - procedure WSSetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; - {$ENDIF} - public - procedure SetBlocking(ASocket: TIdStackSocketHandle; - const ABlocking: Boolean); override; - function WouldBlock(const AResult: Integer): Boolean; override; - function WSTranslateSocketErrorMsg(const AErr: Integer): string; override; - function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; - var VIPVersion: TIdIPVersion): TIdStackSocketHandle; override; - procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - function HostByAddress(const AAddress: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; - function WSGetLastError: Integer; override; - procedure WSSetLastError(const AErr : Integer); override; - function WSGetServByName(const AServiceName: string): TIdPort; override; - function WSGetServByPort(const APortNumber: TIdPort): TStrings; override; - procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; - procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; - procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); override; - function HostToNetwork(AValue: UInt16): UInt16; override; - function NetworkToHost(AValue: UInt16): UInt16; override; - function HostToNetwork(AValue: UInt32): UInt32; override; - function NetworkToHost(AValue: UInt32): UInt32; override; - function HostToNetwork(AValue: TIdUInt64): TIdUInt64; override; - function NetworkToHost(AValue: TIdUInt64): TIdUInt64; override; - function RecvFrom(const ASocket: TIdStackSocketHandle; var VBuffer; - const ALength, AFlags: Integer; var VIP: string; var VPort: TIdPort; - AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): Integer; override; - function ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; - APkt: TIdPacketInfo): UInt32; override; - procedure WSSendTo(ASocket: TIdStackSocketHandle; const ABuffer; - const ABufferLength, AFlags: Integer; - const AIP: string; const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - function WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; - const ANonBlocking: Boolean = False): TIdStackSocketHandle; override; - procedure Disconnect(ASocket: TIdStackSocketHandle); override; - {$IFDEF VCL_XE3_OR_ABOVE} - procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; - procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; - {$ENDIF} - procedure SetKeepAliveValues(ASocket: TIdStackSocketHandle; - const AEnabled: Boolean; const ATimeMS, AInterval: Integer); override; - function SupportsIPv4: Boolean; overload; override; - function SupportsIPv6: Boolean; overload; override; - function CheckIPVersionSupport(const AIPVersion: TIdIPVersion): boolean; override; - constructor Create; override; - destructor Destroy; override; - //In Windows, this writes a checksum into a buffer. In Linux, it would probably - //simply have the kernal write the checksum with something like this (RFC 2292): -// -// int offset = 2; -// setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)); -// -// Note that this should be called - //IMMEDIATELY before you do a SendTo because the Local IPv6 address might change - - procedure WriteChecksum(s : TIdStackSocketHandle; - var VBuffer : TIdBytes; - const AOffset : Integer; - const AIP : String; - const APort : TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; - var arg: UInt32): Integer; override; - - procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); override; - end; - - TLinger = record - l_onoff: UInt16; - l_linger: UInt16; - end; - TIdLinger = TLinger; - -implementation - -uses - IdResourceStrings, - IdException, - SysUtils; - -type - psockaddr_in6 = ^sockaddr_in6; - -const - Id_MSG_NOSIGNAL = MSG_NOSIGNAL; - Id_WSAEPIPE = EPIPE; - -constructor TIdStackLibc.Create; -begin - inherited Create; -end; - -destructor TIdStackLibc.Destroy; -begin - inherited Destroy; -end; - -function TIdStackLibc.GetLastError : Integer; -begin - Result := errno; -end; - -procedure TIdStackLibc.SetLastError(Const AError : Integer); -begin - __errno_location^ := AError; -end; - -procedure TIdStackLibc.WSSetLastError(const AErr : Integer); -begin - SetLastError(AErr); -end; - -function TIdStackLibc.Accept(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): TIdStackSocketHandle; -var - LN: UInt32; - LAddr: sockaddr_in6; -begin - LN := SizeOf(LAddr); - Result := Libc.accept(ASocket, PSockAddr(@LAddr), @LN); - if Result <> SOCKET_ERROR then begin - case LAddr.sin6_family of - Id_PF_INET4: begin - with Psockaddr(@LAddr)^ do - begin - VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); - VPort := Ntohs(sin_port); - end; - VIPVersion := Id_IPV4; - end; - Id_PF_INET6: begin - with LAddr do - begin - VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); - VPort := ntohs(sin6_port); - end; - VIPVersion := Id_IPV6; - end; - else begin - Libc.__close(Result); - Result := Id_INVALID_SOCKET; - IPVersionUnsupported; - end; - end; - end else begin - if GetLastError = EBADF then begin - SetLastError(EINTR); - end; - end; -end; - -procedure TIdStackLibc.Bind(ASocket: TIdStackSocketHandle; - const AIP: string; const APort: TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LAddr: sockaddr_in6; -begin - FillChar(LAddr, SizeOf(LAddr), 0); - case AIPVersion of - Id_IPv4: begin - with Psockaddr(@LAddr)^ do - begin - sin_family := Id_PF_INET4; - if AIP <> '' then begin - TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); - end; - sin_port := htons(APort); - end; - CheckForSocketError(Libc.bind(ASocket, {$IFDEF LIBCPASS_STRUCT}PSockAddr(@LAddr)^ {$ELSE} Psockaddr(@LAddr) {$ENDIF},SizeOf(sockaddr))); - end; - Id_IPv6: begin - with LAddr do - begin - sin6_family := Id_PF_INET6; - if AIP <> '' then begin - TranslateStringToTInAddr(AIP, sin6_addr, Id_IPv6); - end; - sin6_port := htons(APort); - end; - CheckForSocketError(Libc.bind(ASocket, {$IFDEF LIBCPASS_STRUCT}Psockaddr(@LAddr)^ {$ELSE}Psockaddr(@LAddr){$ENDIF}, SizeOf(sockaddr_in6))); - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -function TIdStackLibc.WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; -begin - Result := Libc.__close(ASocket); -end; - -procedure TIdStackLibc.Connect(const ASocket: TIdStackSocketHandle; - const AIP: string; const APort: TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LAddr: sockAddr_in6; -begin - FillChar(LAddr, SizeOf(LAddr), 0); - case AIPVersion of - Id_IPv4: begin - with Psockaddr(@LAddr)^ do - begin - sin_family := Id_PF_INET4; - TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); - sin_port := htons(APort); - end; - CheckForSocketError(Libc.connect( - ASocket, - {$IFDEF LIBCPASS_STRUCT}PSockAddr(@LAddr)^{$ELSE}Psockaddr(@LAddr){$ENDIF}, - SizeOf(sockaddr))); - end; - Id_IPv6: begin - with LAddr do - begin - sin6_family := Id_PF_INET6; - TranslateStringToTInAddr(AIP, sin6_addr, Id_IPv6); - sin6_port := htons(APort); - end; - CheckForSocketError(Libc.connect( - ASocket, - {$IFDEF LIBCPASS_STRUCT}Psockaddr(@LAddr)^{$ELSE}Psockaddr(@LAddr){$ENDIF}, - SizeOf(sockaddr_in6))); - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -function TIdStackLibc.HostByName(const AHostName: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; -var - Lpa: PAnsiChar; - Lsa: TInAddr; - LHost: PHostEnt; -// ipv6 - LHints: TAddressInfo; - {$IFDEF LIBCPASS_STRUCT} - LAddrInfo: PAddressInfo; - {$ELSE} - LAddrInfo: PAddrInfo; - {$ENDIF} - LRetVal: Integer; - {$IFDEF STRING_IS_UNICODE} - LAStr: AnsiString; - {$ENDIF} -begin - case AIPVersion of - Id_IPv4: begin - {$IFDEF STRING_IS_UNICODE} - LAStr := AnsiString(AHostName); // explicit convert to Ansi - {$ENDIF} - // TODO: use getaddrinfo() instead for IPv4 as well... - LHost := Libc.gethostbyname( - PAnsiChar({$IFDEF STRING_IS_UNICODE}LAStr{$ELSE}AHostName{$ENDIF})); - if LHost <> nil then begin - // TODO: gethostbynaame() might return other things besides IPv4 - // addresses, so we should be validating the address type before - // attempting the conversion... - Lpa := LHost^.h_addr_list^; - Lsa.S_un_b.s_b1 := Ord(Lpa[0]); - Lsa.S_un_b.s_b2 := Ord(Lpa[1]); - Lsa.S_un_b.s_b3 := Ord(Lpa[2]); - Lsa.S_un_b.s_b4 := Ord(Lpa[3]); - Result := TranslateTInAddrToString(Lsa, Id_IPv4); - end else begin - //RaiseSocketError(h_errno); - RaiseLastSocketError; - end; - end; - Id_IPv6: begin - FillChar(LHints, SizeOf(LHints), 0); - LHints.ai_family := IdIPFamily[AIPVersion]; - LHints.ai_socktype := Integer(SOCK_STREAM); - LAddrInfo := nil; - - {$IFDEF STRING_IS_UNICODE} - LAStr := AnsiString(AHostName); // explicit convert to Ansi - {$ENDIF} - LRetVal := getaddrinfo( - PAnsiChar({$IFDEF STRING_IS_UNICODE}LAStr{$ELSE}AHostName{$ENDIF}), - nil, @LHints, {$IFDEF LIBCPASS_STRUCT}LAddrInfo{$ELSE}@LAddrInfo{$ENDIF}); - if LRetVal <> 0 then begin - if LRetVal = EAI_SYSTEM then begin - IndyRaiseLastError; - end else begin - raise EIdResolveError.CreateFmt(RSResolveError, [AHostName, gai_strerror(LRetVal), LRetVal]); - end; - end; - try - Result := TranslateTInAddrToString(LAddrInfo^.ai_addr^.sin_zero, Id_IPv6); - finally - freeaddrinfo(LAddrInfo); - end; - end - else - Result := ''; // avoid warning - IPVersionUnsupported; - end; -end; - -function TIdStackLibc.ReadHostName: string; -var - LStr: array[0..250] of AnsiChar; -begin - if Libc.gethostname(LStr, 250) = 0 then begin - LStr[250] := #0; - Result := String(LStr); - end else begin - Result := ''; - end; -end; - -procedure TIdStackLibc.Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); -begin - CheckForSocketError(Libc.listen(ASocket, ABacklog)); -end; - -function TIdStackLibc.WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; - const ABufferLength, AFlags: Integer): Integer; -begin - //IdStackWindows is just: Result := Recv(ASocket, ABuffer, ABufferLength, AFlags); - Result := Recv(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); -end; - -function TIdStackLibc.RecvFrom(const ASocket: TIdStackSocketHandle; - var VBuffer; const ALength, AFlags: Integer; var VIP: string; - var VPort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION ): Integer; -var - LiSize: UInt32; - LAddr: sockaddr_in6; -begin - case AIPVersion of - Id_IPv4, - Id_IPv6: begin - if AIPVersion = Id_IPv4 then begin - LiSize := SizeOf(sockaddr); - end else begin - LiSize := SizeOf(sockaddr_in6); - end; - Result := Libc.recvfrom(ASocket, VBuffer, ALength, AFlags or Id_MSG_NOSIGNAL, PSockAddr(@LAddr), @LiSize); - if AIPVersion = Id_IPv4 then begin - with Psockaddr(@LAddr)^ do begin - VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); - VPort := ntohs(sin_port); - end; - end else begin - with LAddr do begin - VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); - VPort := ntohs(sin6_port); - end; - end; - end; - else begin - Result := 0; - IPVersionUnsupported; - end; - end; -end; - -function TIdStackLibc.ReceiveMsg(ASocket: TIdStackSocketHandle; - var VBuffer: TIdBytes; APkt: TIdPacketInfo): UInt32; -{var - LIP : String; - LPort : TIdPort; - LSize: UInt32; - LAddr: SockAddr_In6; - LMsg : msghdr; - LMsgBuf : BUF; - LControl : TIdBytes; - LCurCmsg : CMSGHDR; //for iterating through the control buffer - LCurPt : Pin_pktinfo; - LCurPt6 : Pin6_pktinfo; - LByte : PByte; - LDummy, LDummy2 : UInt32; - -begin - //we call the macro twice because we specified two possible structures. - //Id_IPV6_HOPLIMIT and Id_IPV6_PKTINFO - LSize := CMSG_SPACE(SizeOf(Byte)) + CMSG_SPACE(SizeOf(in6_pktinfo)); - SetLength(LControl, LSize); - - LMsgBuf.len := Length(VBuffer); // Length(VMsgData); - LMsgBuf.buf := @VBuffer[0]; // @VMsgData[0]; - - FillChar(LMsg,SizeOf(LMsg),0); - - LMsg.lpBuffers := @LMsgBuf; - LMsg.dwBufferCount := 1; - - LMsg.Control.Len := LSize; - LMsg.Control.buf := @LControl[0]; - - LMsg.name := PSOCKADDR(@LAddr); - LMsg.namelen := SizeOf(LAddr); - - CheckForSocketError(RecvMsg(ASocket, @LMsg, Result, @LDummy, LPwsaoverlapped_COMPLETION_ROUTINE(@LDummy2))); - APkt.Reset; - - case LAddr.sin6_family of - Id_PF_INET4: begin - with PSOCKADDR(@LAddr)^ do - begin - APkt.SourceIP := TranslateTInAddrToString(sin_addr, Id_IPv4); - APkt.SourcePort := NToHs(sin_port); - end; - APkt.SourceIPVersion := Id_IPv4; - end; - Id_PF_INET6: begin - with LAddr do - begin - APkt.SourceIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); - APkt.SourcePort := NToHs(sin6_port); - end; - APkt.SourceIPVersion := Id_IPv6; - end; - else begin - Result := 0; // avoid warning - IPVersionUnsupported; - end; - end; - LCurCmsg := nil; - repeat - LCurCmsg := CMSG_NXTHDR(@LMsg,LCurCmsg); - if LCurCmsg=nil then - begin - break; - end; - case LCurCmsg^.cmsg_type of - IP_PKTINFO : //done this way because IPV6_PKTINF and IP_PKTINFO are both 19 - begin - case LAddr.sin6_family of - Id_PF_INET4: - begin - LCurPt := WSA_CMSG_DATA(LCurCmsg); - APkt.DestIP := GWindowsStack.TranslateTInAddrToString(LCurPt^.ipi_addr,Id_IPv4); - APkt.DestIF := LCurPt^.ipi_ifindex; - APkt.DestIPVersion := Id_IPv4; - end; - Id_PF_INET6: - begin - LCurPt6 := WSA_CMSG_DATA(LCurCmsg); - APkt.DestIP := GWindowsStack.TranslateTInAddrToString(LCurPt6^.ipi6_addr,Id_IPv6); - APkt.DestIF := LCurPt6^.ipi6_ifindex; - APkt.DestIPVersion := Id_IPv6; - end; - end; - end; - Id_IPV6_HOPLIMIT : - begin - LByte := PByte(WSA_CMSG_DATA(LCurCmsg)); - APkt.TTL := LByte^; - end; - end; - until False; } -begin - APkt.Reset; - Result := 0; // avoid warning -end; - -function TIdStackLibc.WSSend(ASocket: TIdStackSocketHandle; - const ABuffer; const ABufferLength, AFlags: Integer): Integer; -begin - //CC: Should Id_MSG_NOSIGNAL be included? - // Result := Send(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); - Result := CheckForSocketError(Libc.send(ASocket, ABuffer, ABufferLength, AFlags)); -end; - -procedure TIdStackLibc.WSSendTo(ASocket: TIdStackSocketHandle; - const ABuffer; const ABufferLength, AFlags: Integer; const AIP: string; - const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LAddr: sockaddr_in6; - LiSize, LBytesOut: Integer; -begin - case AIPVersion of - Id_IPv4, Id_IPv6: - begin - FillChar(LAddr, SizeOf(LAddr), 0); - if AIPVersion = Id_IPv4 then begin - with PsockAddr(@LAddr)^ do begin - sin_family := Id_PF_INET4; - TranslateStringToTInAddr(AIP, sin_addr, Id_IPV4); - sin_port := htons(APort); - end; - LiSize := SizeOf(sockaddr); - end else begin - with LAddr do begin - sin6_family := Id_PF_INET6; - TranslateStringToTInAddr(AIP, sin6_addr, AIPVersion); - sin6_port := htons(APort); - end; - LiSize := SizeOf(sockaddr_in6); - end; - LBytesOut := Libc.sendto( - ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL, - {$IFDEF LIBCPASS_STRUCT}Psockaddr(@LAddr)^{$ELSE}Psockaddr(@LAddr){$ENDIF}, - LiSize); - end; - else begin - LBytesOut := 0; // avoid warning - IPVersionUnsupported; - end; - end; - if LBytesOut = Id_SOCKET_ERROR then begin - // TODO: move this into RaiseLastSocketError directly - if WSGetLastError() = Id_WSAEMSGSIZE then begin - raise EIdPackageSizeTooBig.Create(RSPackageSizeTooBig); - end else begin - RaiseLastSocketError; - end; - end else if LBytesOut <> ABufferLength then begin - raise EIdNotAllBytesSent.Create(RSNotAllBytesSent); - end; -end; - -procedure TIdStackLibc.{$IFDEF VCL_XE3_OR_ABOVE}GetSocketOption{$ELSE}WSGetSocketOption{$ENDIF} - (ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; - var AOptVal; var AOptLen: Integer); -var - LLen: UInt32; -begin - LLen := AOptLen; - CheckForSocketError(Libc.getsockopt(ASocket, ALevel, AOptName, PIdAnsiChar(@AOptVal), LLen)); - AOptLen := LLen; -end; - -procedure TIdStackLibc.{$IFDEF VCL_XE3_OR_ABOVE}SetSocketOption{$ELSE}WSSetSocketOption{$ENDIF} - (ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; - const AOptVal; const AOptLen: Integer); -begin - CheckForSocketError(Libc.setsockopt(ASocket, ALevel, AOptName, PIdAnsiChar(@AOptVal), AOptLen)); -end; - -function TIdStackLibc.WSGetLastError: Integer; -begin - //IdStackWindows just uses result := WSAGetLastError; - Result := GetLastError; //System.GetLastOSError; - FPC doesn't define it in System - if Result = Id_WSAEPIPE then begin - Result := Id_WSAECONNRESET; - end; -end; - -function TIdStackLibc.WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; - const ANonBlocking: Boolean = False): TIdStackSocketHandle; override; -begin - Result := Libc.socket(AFamily, AStruct or iif(ANonBlocking, SOCK_NONBLOCK, 0), AProtocol); -end; - -function TIdStackLibc.WSGetServByName(const AServiceName: string): TIdPort; -var - Lps: PServEnt; - {$IFDEF STRING_IS_UNICODE} - LAStr: AnsiString; - {$ENDIF} -begin - {$IFDEF STRING_IS_UNICODE} - LAStr := AnsiString(AServiceName); // explicit convert to Ansi - {$ENDIF} - Lps := Libc.getservbyname( - PAnsiChar({$IFDEF STRING_IS_UNICODE}LAStr{$ELSE}AServiceName{$ENDIF}), - nil); - if Lps <> nil then begin - Result := ntohs(Lps^.s_port); - end else begin - try - Result := IndyStrToInt(AServiceName); - except - on EConvertError do begin - IndyRaiseOuterException(EIdInvalidServiceName.CreateFmt(RSInvalidServiceName, [AServiceName])); - end; - end; - end; -end; - -function TIdStackLibc.WSGetServByPort(const APortNumber: TIdPort): TStrings; -type - PPAnsiCharArray = ^TPAnsiCharArray; - TPAnsiCharArray = packed array[0..(Maxint div SizeOf(PAnsiChar))-1] of PAnsiChar; -var - Lps: PServEnt; - Li: Integer; - Lp: PPAnsiCharArray; -begin - Result := TStringList.Create; - try - Lps := Libc.getservbyport(htons(APortNumber), nil); - if Lps <> nil then begin - Result.Add(String(Lps^.s_name)); - Li := 0; - Lp := Pointer(Lps^.s_aliases); - while Lp[Li] <> nil do begin - Result.Add(String(Lp[Li])); - Inc(Li); - end; - end; - except - FreeAndNil(Result); - raise; - end; -end; - -function TIdStackLibc.HostToNetwork(AValue: UInt16): UInt16; -begin - Result := htons(AValue); -end; - -function TIdStackLibc.NetworkToHost(AValue: UInt16): UInt16; -begin - Result := ntohs(AValue); -end; - -function TIdStackLibc.HostToNetwork(AValue: UInt32): UInt32; -begin - Result := htonl(AValue); -end; - -function TIdStackLibc.NetworkToHost(AValue: UInt32): UInt32; -begin - Result := ntohl(AValue); -end; - -{ RP - I'm not sure what endian Linux natively uses, thus the -check to see if the bytes need swapping or not ... } -function TIdStackLibc.HostToNetwork(AValue: TIdUInt64): TIdUInt64; -var - LParts: TIdUInt64Parts; - L: UInt32; -begin - if (htonl(1) <> 1) then begin - LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - L := htonl(LParts.HighPart); - LParts.HighPart := htonl(LParts.LowPart); - LParts.LowPart := L; - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; - end else begin - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - end; -end; - -function TIdStackLibc.NetworkToHost(AValue: TIdUInt64): TIdUInt64; -var - LParts: TIdUInt64Parts; - L: UInt32; -begin - if (ntohl(1) <> 1) then begin - LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - L := ntohl(LParts.HighPart); - LParts.HighPart := ntohl(LParts.LowPart); - LParts.LowPart := L; - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; - end else begin - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - end; -end; - -{$IFDEF HAS_getifaddrs} -type - TIdStackLocalAddressAccess = class(TIdStackLocalAddress) - end; -{$ENDIF} - -procedure TIdStackLibc.GetLocalAddressList(AAddresses: TIdStackLocalAddressList); -{$IFNDEF HAS_getifaddrs} -type - TaPInAddr = array[0..250] of PInAddr; - PaPInAddr = ^TaPInAddr; - TaPIn6Addr = array[0..250] of PIn6Addr; - PaPIn6Addr = ^TaPIn6Addr; -{$ENDIF} -var - {$IFDEF HAS_getifaddrs} - LAddrList, LAddrInfo: pifaddrs; - LSubNetStr: string; - LAddress: TIdStackLocalAddress; - LName: string; - {$ELSE} - Li: Integer; - LAHost: PHostEnt; - LPAdrPtr: PaPInAddr; - LPAdr6Ptr: PaPIn6Addr; - LHostName: AnsiString; - {$ENDIF} -begin - // TODO: Using gethostname() and gethostbyname() like this may not always - // return just the machine's IP addresses. Technically speaking, they will - // return the local hostname, and then return the address(es) to which that - // hostname resolves. It is possible for a machine to (a) be configured such - // that its name does not resolve to an IP, or (b) be configured such that - // its name resolves to multiple IPs, only one of which belongs to the local - // machine. For better results, we should use getifaddrs() on platforms that - // support it... - - {$IFDEF HAS_getifaddrs} - - if getifaddrs(@LAddrList) = 0 then // TODO: raise an exception if it fails - try - AAddresses.BeginUpdate; - try - LAddrInfo := LAddrList; - repeat - if (LAddrInfo^.ifa_addr <> nil) and ((LAddrInfo^.ifa_flags and IFF_LOOPBACK) = 0) then - begin - LAddress := nil; - case LAddrInfo^.ifa_addr^.sa_family of - Id_PF_INET4: begin - if LAddrInfo^.ifa_netmask <> nil then begin - LSubNetStr := TranslateTInAddrToString(PSockAddr_In(LAddrInfo^.ifa_netmask)^.sin_addr, Id_IPv4); - end else begin - LSubNetStr := ''; - end; - LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, TranslateTInAddrToString(PSockAddr_In(LAddrInfo^.ifa_addr)^.sin_addr, Id_IPv4), LSubNetStr); - end; - Id_PF_INET6: begin - LAddress := TIdStackLocalAddressIPv6.Create(AAddresses, TranslateTInAddrToString(PSockAddr_In6(LAddrInfo^.ifa_addr)^.sin6_addr, Id_IPv6)); - end; - end; - if LAddress <> nil then begin - LName := LAddrInfo^.ifa_name; - {$I IdObjectChecksOff.inc} - TIdStackLocalAddressAccess(LAddress).FDescription := LName; - TIdStackLocalAddressAccess(LAddress).FFriendlyName := LName; - TIdStackLocalAddressAccess(LAddress).FInterfaceName := LName; - {$IFDEF HAS_if_nametoindex} - TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := if_nametoindex(LAddrInfo^.ifa_name); - {$ENDIF} - {$I IdObjectChecksOn.inc} - end; - end; - LAddrInfo := LAddrInfo^.ifa_next; - until LAddrInfo = nil; - finally - AAddresses.EndUpdate; - end; - finally - freeifaddrs(LAddrList); - end; - - {$ELSE} - - // this won't get IPv6 addresses as I didn't find a way - // to enumerate IPv6 addresses on a linux machine - - LHostName := AnsiString(HostName); - LAHost := Libc.gethostbyname(PAnsiChar(LHostName)); - if LAHost = nil then begin - RaiseLastSocketError; - end; - - // gethostbyname() might return other things besides IPv4 addresses, so we - // need to validate the address type before attempting the conversion... - - case LAHost^.h_addrtype of - Id_PF_INET4: begin - LPAdrPtr := PAPInAddr(LAHost^.h_addr_list); - Li := 0; - if LPAdrPtr^[Li] <> nil then begin - AAddresses.BeginUpdate; - try - repeat - TIdStackLocalAddressIPv4.Create(Addresses, TranslateTInAddrToString(LPAdrPtr^[Li]^, Id_IPv4), ''); // TODO: SubNet - Inc(Li); - until LPAdrPtr^[Li] = nil; - finally - AAddresses.EndUpdate; - end; - end; - end; - Id_PF_INET6: begin - LPAdr6Ptr := PAPIn6Addr(LAHost^.h_addr_list); - Li := 0; - if LPAdr6Ptr^[Li] <> nil then begin - AAddresses.BeginUpdate; - try - repeat - TIdStackLocalAddressIPv6.Create(Addresses, TranslateTInAddrToString(LPAdr6Ptr^[Li]^, Id_IPv6)); - Inc(Li); - until LPAdr6Ptr^[Li] = nil; - finally - AAddresses.EndUpdate; - end; - end; - end; - end; - - {$ENDIF} -end; - -function TIdStackLibc.HostByAddress(const AAddress: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; -var - LAddr: sockaddr_in6; - LSize: UInt32; - LHostName : array[0..NI_MAXHOST] of TIdAnsiChar; - {$IFDEF USE_MARSHALLED_PTRS} - LHostNamePtr: TPtrWrapper; - {$ENDIF} - LRet : Integer; - {$IFDEF LIBCPASS_STRUCT} - LHints: TAddressInfo; - LAddrInfo: PAddressInfo; - {$ELSE} - LHints: AddrInfo; //The T is no omission - that's what I found in the header - LAddrInfo: PAddrInfo; - {$ENDIF} -begin - FillChar(LAddr, SizeOf(LAddr), 0); - case AIPVersion of - Id_IPv4: begin - with Psockaddr(@LAddr)^ do begin - sin_family := Id_PF_INET4; - TranslateStringToTInAddr(AAddress, sin_addr, Id_IPv4); - end; - LSize := SizeOf(sockaddr); - end; - Id_IPv6: begin - with LAddr do begin - sin6_family := Id_PF_INET6; - TranslateStringToTInAddr(AAddress, sin6_addr, Id_IPv6); - end; - LSize := SizeOf(sockaddr_in6); - end; - else begin - LSize := 0; // avoid warning - IPVersionUnsupported; - end; - end; - FillChar(LHostName[0],Length(LHostName),0); - {$IFDEF USE_MARSHALLED_PTRS} - LHostNamePtr := TPtrWrapper.Create(@LHostName[0]); - {$ENDIF} - LRet := getnameinfo( - {$IFDEF LIBCPASS_STRUCT}Psockaddr(@LAddr)^{$ELSE}Psockaddr(@LAddr){$ENDIF}, - LSize, - {$IFDEF USE_MARSHALLED_PTRS} - LHostNamePtr.ToPointer - {$ELSE} - LHostName - {$ENDIF}, - NI_MAXHOST,nil,0,NI_NAMEREQD ); - if LRet <> 0 then begin - if LRet = EAI_SYSTEM then begin - RaiseLastOSError; - end else begin - raise EIdReverseResolveError.CreateFmt(RSReverseResolveError, [AAddress, gai_strerror(LRet), LRet]); - end; - end; -{ -IMPORTANT!!! - -getnameinfo can return either results from a numeric to text conversion or -results from a DNS reverse lookup. Someone could make a malicous PTR record -such as - - 1.0.0.127.in-addr.arpa. IN PTR 10.1.1.1 - -and trick a caller into beleiving the socket address is 10.1.1.1 instead of -127.0.0.1. If there is a numeric host in LAddr, than this is the case and -we disregard the result and raise an exception. -} - FillChar(LHints,SizeOf(LHints),0); - LHints.ai_socktype := SOCK_DGRAM; //*dummy*/ - LHints.ai_flags := AI_NUMERICHOST; - if getaddrinfo( - {$IFDEF USE_MARSHALLED_PTRS} - LHostNamePtr.ToPointer - {$ELSE} - LHostName - {$ENDIF}, - '0', LHints, LAddrInfo) = 0 then - begin - freeaddrinfo(LAddrInfo^); - Result := ''; - raise EIdMaliciousPtrRecord.Create(RSMaliciousPtrRecord); - end; - - {$IFDEF USE_MARSHALLED_PTRS} - Result := TMarshal.ReadStringAsAnsi(LHostNamePtr); - {$ELSE} - Result := String(LHostName); - {$ENDIF} -(* JMB: I left this in here just in case someone - complains, but the other code works on all - linux systems for all addresses and is thread-safe - -variables for it: - Host: PHostEnt; - LAddr: u_long; - - Id_IPv4: begin - // GetHostByAddr is thread-safe in Linux. - // It might not be safe in Solaris or BSD Unix - LAddr := inet_addr(PAnsiChar(AAddress)); - Host := GetHostByAddr(@LAddr,SizeOf(LAddr),AF_INET); - if (Host <> nil) then begin - Result := Host^.h_name; - end else begin - RaiseSocketError(h_errno); - end; - end; -*) -end; - -function TIdStackLibc.WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; -begin - Result := Libc.shutdown(ASocket, AHow); -end; - -procedure TIdStackLibc.Disconnect(ASocket: TIdStackSocketHandle); -begin - // Windows uses Id_SD_Send, Linux should use Id_SD_Both - WSShutdown(ASocket, Id_SD_Both); - // SO_LINGER is false - socket may take a little while to actually close after this - WSCloseSocket(ASocket); -end; - -procedure TIdStackLibc.GetPeerName(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); -var - i: UInt32; - LAddr: sockaddr_in6; -begin - i := SizeOf(LAddr); - CheckForSocketError(Libc.getpeername(ASocket, Psockaddr(@LAddr)^, i)); - case LAddr.sin6_family of - Id_PF_INET4: begin - with Psockaddr(@LAddr)^ do - begin - VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); - VPort := ntohs(sin_port); - end; - VIPVersion := Id_IPV4; - end; - Id_PF_INET6: begin - with LAddr do - begin - VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); - VPort := Ntohs(sin6_port); - end; - VIPVersion := Id_IPV6; - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -procedure TIdStackLibc.GetSocketName(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); -var - i: UInt32; - LAddr: sockaddr_in6; -begin - i := SizeOf(LAddr); - CheckForSocketError(Libc.getsockname(ASocket, Psockaddr(@LAddr)^, i)); - case LAddr.sin6_family of - Id_PF_INET4: begin - with Psockaddr(@LAddr)^ do - begin - VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); - VPort := ntohs(sin_port); - end; - VIPVersion := Id_IPV4; - end; - Id_PF_INET6: begin - with LAddr do - begin - VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); - VPort := ntohs(sin6_port); - end; - VIPVersion := Id_IPV6; - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -function TIdStackLibc.WouldBlock(const AResult: Integer): Boolean; -begin - // using if-else instead of in..range because EAGAIN and EWOULDBLOCK - // have often the same value and so FPC might report a range error - Result := (AResult = Id_WSAEAGAIN) or - (AResult = Id_WSAEWOULDBLOCK) or - (AResult = Id_WSAEINPROGRESS); -end; - -function TIdStackLibc.SupportsIPv4: Boolean; -begin - //In Windows, this does something else. It checks the LSP's installed. - Result := CheckIPVersionSupport(Id_IPv4); -end; - -function TIdStackLibc.SupportsIPv6: Boolean; -begin - //In Windows, this does something else. It checks the LSP's installed. - Result := CheckIPVersionSupport(Id_IPv6); -end; - -function TIdStackLibc.CheckIPVersionSupport(const AIPVersion: TIdIPVersion): Boolean; -var - LTmpSocket: TIdStackSocketHandle; -begin - // TODO: on nix systems (or maybe just Linux?), an alternative would be to - // check for the existance of the '/proc/net/if_inet6' kernel pseudo-file - LTmpSocket := WSSocket(IdIPFamily[AIPVersion], Integer(Id_SOCK_STREAM), Id_IPPROTO_IP ); - Result := LTmpSocket <> Id_INVALID_SOCKET; - if Result then begin - WSCloseSocket(LTmpSocket); - end; -end; - -procedure TIdStackLibc.WriteChecksum(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort; const AIPVersion: TIdIPVersion); -begin - case AIPVersion of - Id_IPv4 : CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(VBuffer)), VBuffer, AOffset); - Id_IPv6 : WriteChecksumIPv6(s, VBuffer, AOffset, AIP, APort); - else - IPVersionUnsupported; - end; -end; - -procedure TIdStackLibc.WriteChecksumIPv6(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort); -begin -//we simply request that the kernal write the checksum when the data -//is sent. All of the parameters required are because Windows is bonked -//because it doesn't have the IPV6CHECKSUM socket option meaning we have -//to querry the network interface in TIdStackWindows -- yuck!! - SetSocketOption(s, IPPROTO_IPV6, IPV6_CHECKSUM, AOffset); -end; - -function TIdStackLibc.IOControl(const s: TIdStackSocketHandle; - const cmd: UInt32; var arg: UInt32): Integer; -begin - Result := ioctl(s, cmd, @arg); -end; - -procedure TIdStackLibc.SetKeepAliveValues(ASocket: TIdStackSocketHandle; - const AEnabled: Boolean; const ATimeMS, AInterval: Integer); -begin - inherited; // turn SO_KEEPALIVE on/off first... - // TODO: remove below, as it should be handled by TIdStack.SetKeepAliveValues() now... - if AEnabled then begin - SetSocketOption(ASocket, Id_SOL_TCP, Id_TCP_KEEPIDLE, ATimeMS div MSecsPerSec); - SetSocketOption(ASocket, Id_SOL_TCP, Id_TCP_KEEPINTVL, AInterval div MSecsPerSec); - end; -end; - -{ TIdSocketListLibc } - -type - // TODO: rewrite this to use poll() instead of select(), similar to TIdSocketListVCLPosix - TIdSocketListLibc = class (TIdSocketList) - protected - FCount: integer; - FFDSet: TFDSet; - // - class function FDSelect(AReadSet: PFDSet; AWriteSet: PFDSet; AExceptSet: PFDSet; - const ATimeout: Integer = IdTimeoutInfinite): integer; - function GetItem(AIndex: Integer): TIdStackSocketHandle; override; - public - procedure Add(AHandle: TIdStackSocketHandle); override; - procedure Remove(AHandle: TIdStackSocketHandle); override; - function Count: Integer; override; - procedure Clear; override; - function Clone: TIdSocketList; override; - function ContainsSocket(AHandle: TIdStackSocketHandle): boolean; override; - procedure GetFDSet(var VSet: TFDSet); - procedure SetFDSet(var VSet: TFDSet); - class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; - AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; - override; - function SelectReadList(var VSocketList: TIdSocketList; - const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - End;//TIdSocketList - -procedure TIdSocketListLibc.Add(AHandle: TIdStackSocketHandle); -begin - Lock; - try - if not FD_ISSET(AHandle, FFDSet) then begin - if AHandle >= __FD_SETSIZE then begin - raise EIdStackSetSizeExceeded.Create(RSSetSizeExceeded); - end; - FD_SET(AHandle, FFDSet); - Inc(FCount); - end; - finally - Unlock; - end; -end;// - -procedure TIdSocketListLibc.Clear; -begin - Lock; - try - FD_ZERO(FFDSet); - FCount := 0; - finally - Unlock; - end; -end; - -function TIdSocketListLibc.ContainsSocket( - AHandle: TIdStackSocketHandle): boolean; -begin - Lock; - try - Result := FD_ISSET(AHandle, FFDSet); - finally - Unlock; - end; -end; - -function TIdSocketListLibc.Count: Integer; -begin - Lock; - try - Result := FCount; - finally - Unlock; - end; -end;// - -class function TIdSocketListLibc.FDSelect(AReadSet, AWriteSet, - AExceptSet: PFDSet; const ATimeout: Integer): integer; -var - LTime: TTimeVal; - LTimePtr: PTimeVal; -begin - if ATimeout = IdTimeoutInfinite then begin - LTimePtr := nil; - end else begin - LTime.tv_sec := ATimeout div 1000; - LTime.tv_usec := (ATimeout mod 1000) * 1000; - LTimePtr := @LTime; - end; - // TODO: calculate the actual nfds value based on the Sets provided... - // TODO: use poll() instead of select() to remove limit on how many sockets can be queried - Result := Libc.select(__FD_SETSIZE, AReadSet, AWriteSet, AExceptSet, LTimePtr); -end; - -procedure TIdSocketListLibc.GetFDSet(var VSet: TFDSet); -begin - Lock; - try - VSet := FFDSet; - finally - Unlock; - end; -end; - -function TIdSocketListLibc.GetItem(AIndex: Integer): TIdStackSocketHandle; -var - LIndex, i: Integer; -begin - Result := 0; - Lock; - try - LIndex := 0; - //? use FMaxHandle div x - for i:= 0 to __FD_SETSIZE - 1 do begin - if FD_ISSET(i, FFDSet) then begin - if LIndex = AIndex then begin - Result := i; - Break; - end; - Inc(LIndex); - end; - end; - finally - Unlock; - end; -end;// - -procedure TIdSocketListLibc.Remove(AHandle: TIdStackSocketHandle); -begin - Lock; - try - if FD_ISSET(AHandle, FFDSet) then begin - Dec(FCount); - FD_CLR(AHandle, FFDSet); - end; - finally - Unlock; - end; -end;// - - -function TIdStackLibc.WSTranslateSocketErrorMsg(const AErr: Integer): string; -begin - //we override this function for the herr constants that - //are returned by the DNS functions - case AErr of - Libc.HOST_NOT_FOUND: Result := RSStackHOST_NOT_FOUND; - Libc.TRY_AGAIN: Result := RSStackTRY_AGAIN; - Libc.NO_RECOVERY: Result := RSStackNO_RECOVERY; - Libc.NO_DATA: Result := RSStackNO_DATA; - else - Result := inherited WSTranslateSocketErrorMsg(AErr); - end; -end; - -procedure TIdSocketListLibc.SetFDSet(var VSet: TFDSet); -begin - Lock; - try - FFDSet := VSet; - finally - Unlock; - end; -end; - -class function TIdSocketListLibc.Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; - AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; -var - LReadSet: TFDSet; - LWriteSet: TFDSet; - LExceptSet: TFDSet; - LPReadSet: PFDSet; - LPWriteSet: PFDSet; - LPExceptSet: PFDSet; - - procedure ReadSet(AList: TIdSocketList; var ASet: TFDSet; var APSet: PFDSet); - begin - if AList <> nil then begin - TIdSocketListLibc(AList).GetFDSet(ASet); - APSet := @ASet; - end else begin - APSet := nil; - end; - end; - -begin - ReadSet(AReadList, LReadSet, LPReadSet); - ReadSet(AWriteList, LWriteSet, LPWriteSet); - ReadSet(AExceptList, LExceptSet, LPExceptSet); - // - Result := FDSelect(LPReadSet, LPWriteSet, LPExceptSet, ATimeout) >0; - // - if AReadList <> nil then begin - TIdSocketListLibc(AReadList).SetFDSet(LReadSet); - end; - if AWriteList <> nil then begin - TIdSocketListLibc(AWriteList).SetFDSet(LWriteSet); - end; - if AExceptList <> nil then begin - TIdSocketListLibc(AExceptList).SetFDSet(LExceptSet); - end; -end; - -function TIdSocketListLibc.SelectRead(const ATimeout: Integer): Boolean; -var - LSet: TFDSet; -begin - Lock; - try - LSet := FFDSet; - // select() updates this structure on return, - // so we need to copy it each time we need it - finally - Unlock; - end; - Result := FDSelect(@LSet, nil, nil, ATimeout) > 0; -end; - -function TIdSocketListLibc.SelectReadList(var VSocketList: TIdSocketList; - const ATimeout: Integer = IdTimeoutInfinite): Boolean; -var - LSet: TFDSet; -begin - Lock; - try - LSet := FFDSet; - // select() updates this structure on return, - // so we need to copy it each time we need it - finally - Unlock; - end; - Result := FDSelect(@LSet, nil, nil, ATimeout) > 0; - if Result then begin - if VSocketList = nil then begin - VSocketList := TIdSocketList.CreateSocketList; - end; - TIdSocketListLibc(VSocketList).SetFDSet(LSet); - end; -end; - -procedure TIdStackLibc.SetBlocking(ASocket: TIdStackSocketHandle; - const ABlocking: Boolean); -var - LFlags: Integer; - //LValue: UInt32; -begin - LFlags := CheckForSocketError(Libc.fcntl(ASocket, F_GETFL, 0)); - if ABlocking then begin - LFlags := LFlags and not O_NONBLOCK; - end else begin - LFlags := LFlags or O_NONBLOCK; - end; - CheckForSocketError(Libc.fcntl(ASocket, F_SETFL, LFlags)); - { - LValue := UInt32(not ABlocking); - CheckForSocketError(Libc.ioctl(ASocket, FIONBIO, @LValue)); - } -end; - -(* -Why did I remove this again? - - 1) it sends SIGPIPE even if the socket is created with the no-sigpipe bit set - that could be solved by blocking sigpipe within this thread - This is probably a bug in the Linux kernel, but we could work around it - by blocking that signal for the time of sending the file (just get the - sigprocmask, see if pipe bit is set, if not set it and remove again after - sending the file) - -But the more serious reason is another one, which exists in Windows too: - 2) I think that ServeFile is misdesigned: - ServeFile does not raise an exception if it didn't send all the bytes. - Now what happens if I have OnExecute assigned like this - AThread.Connection.ServeFile('...', True); // <-- true to send via kernel - is that it will return 0, but notice that in this case I didn't ask for the - result. Net effect is that the thread will loop in OnExecute even if the - socket is long gone. This doesn't fit Indy semantics at all, exceptions are - always raised if the remote end disconnects. Even if I would do - AThread.Connection.ServeFile('...', False); - then it would raise an exception. - I think this is a big flaw in the design of the ServeFile function. - Maybe GServeFile should only return the bytes sent, but then - TCPConnection.ServeFile() should raise an exception if GServeFile didn't - send all the bytes. - -JM Berg, 2002-09-09 - -function ServeFile(ASocket: TIdStackSocketHandle; AFileName: string): UInt32; -var - LFileHandle: integer; - offset: integer; - stat: _stat; -begin - LFileHandle := open(PAnsiChar(AFileName), O_RDONLY); - try - offset := 0; - fstat(LFileHandle, stat); - Result := sendfile(ASocket, LFileHandle, offset, stat.st_size); -//** if Result = UInt32(-1) then RaiseLastOSError; - finally libc.__close(LFileHandle); end; -end; -*) -function TIdSocketListLibc.Clone: TIdSocketList; -begin - Result := TIdSocketListLibc.Create; - try - Lock; - try - TIdSocketListLibc(Result).SetFDSet(FFDSet); - finally - Unlock; - end; - except - FreeAndNil(Result); - raise; - end; -end; - -initialization - GSocketListClass := TIdSocketListLibc; - -end. - +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.7 10/26/2004 8:20:04 PM JPMugaas + Fixed some oversights with conversion. OOPS!!! + + Rev 1.6 10/26/2004 8:12:32 PM JPMugaas + Now uses TIdStrings and TIdStringList for portability. + + Rev 1.5 12/06/2004 15:17:20 CCostelloe + Restructured to correspond with IdStackWindows, now works. + + Rev 1.4 07/06/2004 21:31:02 CCostelloe + Kylix 3 changes + + Rev 1.3 4/18/04 10:43:22 PM RLebeau + Fixed syntax error + + Rev 1.2 4/18/04 10:29:46 PM RLebeau + Renamed Int64Parts structure to TIdInt64Parts + + Rev 1.1 4/18/04 2:47:28 PM RLebeau + Conversion support for Int64 values + + Removed WSHToNs(), WSNToHs(), WSHToNL(), and WSNToHL() methods, obsolete + + Rev 1.0 2004.02.03 3:14:48 PM czhower + Move and updates + + Rev 1.3 10/19/2003 5:35:14 PM BGooijen + SetSocketOption + + Rev 1.2 2003.10.01 9:11:24 PM czhower + .Net + + Rev 1.1 7/5/2003 07:25:50 PM JPMugaas + Added functions to the Linux stack which use the new TIdIPAddress record type + for IP address parameters. I also fixed a compile bug. + + Rev 1.0 11/13/2002 08:59:24 AM JPMugaas +} + +unit IdStackLibc; + +interface + +{$i IdCompilerDefines.inc} + +uses + Classes, + Libc, + IdStack, + IdStackConsts, + IdGlobal, + IdStackBSDBase; + +{$UNDEF LIBCPASS_STRUCT} +{$IFDEF KYLIX} + {$DEFINE LIBCPASS_STRUCT} +{$ENDIF} +{$IFDEF DELPHI_CROSS} + {$DEFINE LIBCPASS_STRUCT} +{$ENDIF} +type + TIdStackLibc = class(TIdStackBSDBase) + private + procedure WriteChecksumIPv6(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort); + protected + function GetLastError : Integer; + procedure SetLastError(Const AError : Integer); + function HostByName(const AHostName: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; + function ReadHostName: string; override; + function WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; override; + function WSRecv(ASocket: TIdStackSocketHandle; + var ABuffer; const ABufferLength, AFlags: Integer): Integer; override; + function WSSend(ASocket: TIdStackSocketHandle; const ABuffer; const ABufferLength, AFlags: Integer): Integer; override; + function WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; override; + {$IFNDEF VCL_XE3_OR_ABOVE} + procedure WSGetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; + procedure WSSetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; + {$ENDIF} + public + procedure SetBlocking(ASocket: TIdStackSocketHandle; + const ABlocking: Boolean); override; + function WouldBlock(const AResult: Integer): Boolean; override; + function WSTranslateSocketErrorMsg(const AErr: Integer): string; override; + function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; + var VIPVersion: TIdIPVersion): TIdStackSocketHandle; override; + procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + function HostByAddress(const AAddress: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; + function WSGetLastError: Integer; override; + procedure WSSetLastError(const AErr : Integer); override; + function WSGetServByName(const AServiceName: string): TIdPort; override; + function WSGetServByPort(const APortNumber: TIdPort): TStrings; override; + procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; + procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; + procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); override; + function HostToNetwork(AValue: UInt16): UInt16; override; + function NetworkToHost(AValue: UInt16): UInt16; override; + function HostToNetwork(AValue: UInt32): UInt32; override; + function NetworkToHost(AValue: UInt32): UInt32; override; + function HostToNetwork(AValue: TIdUInt64): TIdUInt64; override; + function NetworkToHost(AValue: TIdUInt64): TIdUInt64; override; + function RecvFrom(const ASocket: TIdStackSocketHandle; var VBuffer; + const ALength, AFlags: Integer; var VIP: string; var VPort: TIdPort; + AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): Integer; override; + function ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; + APkt: TIdPacketInfo): UInt32; override; + procedure WSSendTo(ASocket: TIdStackSocketHandle; const ABuffer; + const ABufferLength, AFlags: Integer; + const AIP: string; const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + function WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; + const ANonBlocking: Boolean = False): TIdStackSocketHandle; override; + procedure Disconnect(ASocket: TIdStackSocketHandle); override; + {$IFDEF VCL_XE3_OR_ABOVE} + procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; + procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; + {$ENDIF} + procedure SetKeepAliveValues(ASocket: TIdStackSocketHandle; + const AEnabled: Boolean; const ATimeMS, AInterval: Integer); override; + function SupportsIPv4: Boolean; overload; override; + function SupportsIPv6: Boolean; overload; override; + function CheckIPVersionSupport(const AIPVersion: TIdIPVersion): boolean; override; + constructor Create; override; + destructor Destroy; override; + //In Windows, this writes a checksum into a buffer. In Linux, it would probably + //simply have the kernal write the checksum with something like this (RFC 2292): +// +// int offset = 2; +// setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)); +// +// Note that this should be called + //IMMEDIATELY before you do a SendTo because the Local IPv6 address might change + + procedure WriteChecksum(s : TIdStackSocketHandle; + var VBuffer : TIdBytes; + const AOffset : Integer; + const AIP : String; + const APort : TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; + var arg: UInt32): Integer; override; + + procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); override; + end; + + TLinger = record + l_onoff: UInt16; + l_linger: UInt16; + end; + TIdLinger = TLinger; + +implementation + +uses + IdResourceStrings, + IdException, + SysUtils; + +type + psockaddr_in6 = ^sockaddr_in6; + +const + Id_MSG_NOSIGNAL = MSG_NOSIGNAL; + Id_WSAEPIPE = EPIPE; + +constructor TIdStackLibc.Create; +begin + inherited Create; +end; + +destructor TIdStackLibc.Destroy; +begin + inherited Destroy; +end; + +function TIdStackLibc.GetLastError : Integer; +begin + Result := errno; +end; + +procedure TIdStackLibc.SetLastError(Const AError : Integer); +begin + __errno_location^ := AError; +end; + +procedure TIdStackLibc.WSSetLastError(const AErr : Integer); +begin + SetLastError(AErr); +end; + +function TIdStackLibc.Accept(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): TIdStackSocketHandle; +var + LN: UInt32; + LAddr: sockaddr_in6; +begin + LN := SizeOf(LAddr); + Result := Libc.accept(ASocket, PSockAddr(@LAddr), @LN); + if Result <> SOCKET_ERROR then begin + case LAddr.sin6_family of + Id_PF_INET4: begin + with Psockaddr(@LAddr)^ do + begin + VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); + VPort := Ntohs(sin_port); + end; + VIPVersion := Id_IPV4; + end; + Id_PF_INET6: begin + with LAddr do + begin + VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); + VPort := ntohs(sin6_port); + end; + VIPVersion := Id_IPV6; + end; + else begin + Libc.__close(Result); + Result := Id_INVALID_SOCKET; + IPVersionUnsupported; + end; + end; + end else begin + if GetLastError = EBADF then begin + SetLastError(EINTR); + end; + end; +end; + +procedure TIdStackLibc.Bind(ASocket: TIdStackSocketHandle; + const AIP: string; const APort: TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LAddr: sockaddr_in6; +begin + FillChar(LAddr, SizeOf(LAddr), 0); + case AIPVersion of + Id_IPv4: begin + with Psockaddr(@LAddr)^ do + begin + sin_family := Id_PF_INET4; + if AIP <> '' then begin + TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); + end; + sin_port := htons(APort); + end; + CheckForSocketError(Libc.bind(ASocket, {$IFDEF LIBCPASS_STRUCT}PSockAddr(@LAddr)^ {$ELSE} Psockaddr(@LAddr) {$ENDIF},SizeOf(sockaddr))); + end; + Id_IPv6: begin + with LAddr do + begin + sin6_family := Id_PF_INET6; + if AIP <> '' then begin + TranslateStringToTInAddr(AIP, sin6_addr, Id_IPv6); + end; + sin6_port := htons(APort); + end; + CheckForSocketError(Libc.bind(ASocket, {$IFDEF LIBCPASS_STRUCT}Psockaddr(@LAddr)^ {$ELSE}Psockaddr(@LAddr){$ENDIF}, SizeOf(sockaddr_in6))); + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +function TIdStackLibc.WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; +begin + Result := Libc.__close(ASocket); +end; + +procedure TIdStackLibc.Connect(const ASocket: TIdStackSocketHandle; + const AIP: string; const APort: TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LAddr: sockAddr_in6; +begin + FillChar(LAddr, SizeOf(LAddr), 0); + case AIPVersion of + Id_IPv4: begin + with Psockaddr(@LAddr)^ do + begin + sin_family := Id_PF_INET4; + TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); + sin_port := htons(APort); + end; + CheckForSocketError(Libc.connect( + ASocket, + {$IFDEF LIBCPASS_STRUCT}PSockAddr(@LAddr)^{$ELSE}Psockaddr(@LAddr){$ENDIF}, + SizeOf(sockaddr))); + end; + Id_IPv6: begin + with LAddr do + begin + sin6_family := Id_PF_INET6; + TranslateStringToTInAddr(AIP, sin6_addr, Id_IPv6); + sin6_port := htons(APort); + end; + CheckForSocketError(Libc.connect( + ASocket, + {$IFDEF LIBCPASS_STRUCT}Psockaddr(@LAddr)^{$ELSE}Psockaddr(@LAddr){$ENDIF}, + SizeOf(sockaddr_in6))); + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +function TIdStackLibc.HostByName(const AHostName: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; +var + Lpa: PAnsiChar; + Lsa: TInAddr; + LHost: PHostEnt; +// ipv6 + LHints: TAddressInfo; + {$IFDEF LIBCPASS_STRUCT} + LAddrInfo: PAddressInfo; + {$ELSE} + LAddrInfo: PAddrInfo; + {$ENDIF} + LRetVal: Integer; + {$IFDEF STRING_IS_UNICODE} + LAStr: AnsiString; + {$ENDIF} +begin + case AIPVersion of + Id_IPv4: begin + {$IFDEF STRING_IS_UNICODE} + LAStr := AnsiString(AHostName); // explicit convert to Ansi + {$ENDIF} + // TODO: use getaddrinfo() instead for IPv4 as well... + LHost := Libc.gethostbyname( + PAnsiChar({$IFDEF STRING_IS_UNICODE}LAStr{$ELSE}AHostName{$ENDIF})); + if LHost <> nil then begin + // TODO: gethostbynaame() might return other things besides IPv4 + // addresses, so we should be validating the address type before + // attempting the conversion... + Lpa := LHost^.h_addr_list^; + Lsa.S_un_b.s_b1 := Ord(Lpa[0]); + Lsa.S_un_b.s_b2 := Ord(Lpa[1]); + Lsa.S_un_b.s_b3 := Ord(Lpa[2]); + Lsa.S_un_b.s_b4 := Ord(Lpa[3]); + Result := TranslateTInAddrToString(Lsa, Id_IPv4); + end else begin + //RaiseSocketError(h_errno); + RaiseLastSocketError; + end; + end; + Id_IPv6: begin + FillChar(LHints, SizeOf(LHints), 0); + LHints.ai_family := IdIPFamily[AIPVersion]; + LHints.ai_socktype := Integer(SOCK_STREAM); + LAddrInfo := nil; + + {$IFDEF STRING_IS_UNICODE} + LAStr := AnsiString(AHostName); // explicit convert to Ansi + {$ENDIF} + LRetVal := getaddrinfo( + PAnsiChar({$IFDEF STRING_IS_UNICODE}LAStr{$ELSE}AHostName{$ENDIF}), + nil, @LHints, {$IFDEF LIBCPASS_STRUCT}LAddrInfo{$ELSE}@LAddrInfo{$ENDIF}); + if LRetVal <> 0 then begin + if LRetVal = EAI_SYSTEM then begin + IndyRaiseLastError; + end else begin + raise EIdResolveError.CreateFmt(RSResolveError, [AHostName, gai_strerror(LRetVal), LRetVal]); + end; + end; + try + Result := TranslateTInAddrToString(LAddrInfo^.ai_addr^.sin_zero, Id_IPv6); + finally + freeaddrinfo(LAddrInfo); + end; + end + else + Result := ''; // avoid warning + IPVersionUnsupported; + end; +end; + +function TIdStackLibc.ReadHostName: string; +var + LStr: array[0..250] of AnsiChar; +begin + if Libc.gethostname(LStr, 250) = 0 then begin + LStr[250] := #0; + Result := String(LStr); + end else begin + Result := ''; + end; +end; + +procedure TIdStackLibc.Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); +begin + CheckForSocketError(Libc.listen(ASocket, ABacklog)); +end; + +function TIdStackLibc.WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; + const ABufferLength, AFlags: Integer): Integer; +begin + //IdStackWindows is just: Result := Recv(ASocket, ABuffer, ABufferLength, AFlags); + Result := Recv(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); +end; + +function TIdStackLibc.RecvFrom(const ASocket: TIdStackSocketHandle; + var VBuffer; const ALength, AFlags: Integer; var VIP: string; + var VPort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION ): Integer; +var + LiSize: UInt32; + LAddr: sockaddr_in6; +begin + case AIPVersion of + Id_IPv4, + Id_IPv6: begin + if AIPVersion = Id_IPv4 then begin + LiSize := SizeOf(sockaddr); + end else begin + LiSize := SizeOf(sockaddr_in6); + end; + Result := Libc.recvfrom(ASocket, VBuffer, ALength, AFlags or Id_MSG_NOSIGNAL, PSockAddr(@LAddr), @LiSize); + if AIPVersion = Id_IPv4 then begin + with Psockaddr(@LAddr)^ do begin + VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); + VPort := ntohs(sin_port); + end; + end else begin + with LAddr do begin + VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); + VPort := ntohs(sin6_port); + end; + end; + end; + else begin + Result := 0; + IPVersionUnsupported; + end; + end; +end; + +function TIdStackLibc.ReceiveMsg(ASocket: TIdStackSocketHandle; + var VBuffer: TIdBytes; APkt: TIdPacketInfo): UInt32; +{var + LIP : String; + LPort : TIdPort; + LSize: UInt32; + LAddr: SockAddr_In6; + LMsg : msghdr; + LMsgBuf : BUF; + LControl : TIdBytes; + LCurCmsg : CMSGHDR; //for iterating through the control buffer + LCurPt : Pin_pktinfo; + LCurPt6 : Pin6_pktinfo; + LByte : PByte; + LDummy, LDummy2 : UInt32; + +begin + //we call the macro twice because we specified two possible structures. + //Id_IPV6_HOPLIMIT and Id_IPV6_PKTINFO + LSize := CMSG_SPACE(SizeOf(Byte)) + CMSG_SPACE(SizeOf(in6_pktinfo)); + SetLength(LControl, LSize); + + LMsgBuf.len := Length(VBuffer); // Length(VMsgData); + LMsgBuf.buf := @VBuffer[0]; // @VMsgData[0]; + + FillChar(LMsg,SizeOf(LMsg),0); + + LMsg.lpBuffers := @LMsgBuf; + LMsg.dwBufferCount := 1; + + LMsg.Control.Len := LSize; + LMsg.Control.buf := @LControl[0]; + + LMsg.name := PSOCKADDR(@LAddr); + LMsg.namelen := SizeOf(LAddr); + + CheckForSocketError(RecvMsg(ASocket, @LMsg, Result, @LDummy, LPwsaoverlapped_COMPLETION_ROUTINE(@LDummy2))); + APkt.Reset; + + case LAddr.sin6_family of + Id_PF_INET4: begin + with PSOCKADDR(@LAddr)^ do + begin + APkt.SourceIP := TranslateTInAddrToString(sin_addr, Id_IPv4); + APkt.SourcePort := NToHs(sin_port); + end; + APkt.SourceIPVersion := Id_IPv4; + end; + Id_PF_INET6: begin + with LAddr do + begin + APkt.SourceIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); + APkt.SourcePort := NToHs(sin6_port); + end; + APkt.SourceIPVersion := Id_IPv6; + end; + else begin + Result := 0; // avoid warning + IPVersionUnsupported; + end; + end; + LCurCmsg := nil; + repeat + LCurCmsg := CMSG_NXTHDR(@LMsg,LCurCmsg); + if LCurCmsg=nil then + begin + break; + end; + case LCurCmsg^.cmsg_type of + IP_PKTINFO : //done this way because IPV6_PKTINF and IP_PKTINFO are both 19 + begin + case LAddr.sin6_family of + Id_PF_INET4: + begin + LCurPt := WSA_CMSG_DATA(LCurCmsg); + APkt.DestIP := GWindowsStack.TranslateTInAddrToString(LCurPt^.ipi_addr,Id_IPv4); + APkt.DestIF := LCurPt^.ipi_ifindex; + APkt.DestIPVersion := Id_IPv4; + end; + Id_PF_INET6: + begin + LCurPt6 := WSA_CMSG_DATA(LCurCmsg); + APkt.DestIP := GWindowsStack.TranslateTInAddrToString(LCurPt6^.ipi6_addr,Id_IPv6); + APkt.DestIF := LCurPt6^.ipi6_ifindex; + APkt.DestIPVersion := Id_IPv6; + end; + end; + end; + Id_IPV6_HOPLIMIT : + begin + LByte := PByte(WSA_CMSG_DATA(LCurCmsg)); + APkt.TTL := LByte^; + end; + end; + until False; } +begin + APkt.Reset; + Result := 0; // avoid warning +end; + +function TIdStackLibc.WSSend(ASocket: TIdStackSocketHandle; + const ABuffer; const ABufferLength, AFlags: Integer): Integer; +begin + //CC: Should Id_MSG_NOSIGNAL be included? + // Result := Send(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); + Result := CheckForSocketError(Libc.send(ASocket, ABuffer, ABufferLength, AFlags)); +end; + +procedure TIdStackLibc.WSSendTo(ASocket: TIdStackSocketHandle; + const ABuffer; const ABufferLength, AFlags: Integer; const AIP: string; + const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LAddr: sockaddr_in6; + LiSize, LBytesOut: Integer; +begin + case AIPVersion of + Id_IPv4, Id_IPv6: + begin + FillChar(LAddr, SizeOf(LAddr), 0); + if AIPVersion = Id_IPv4 then begin + with PsockAddr(@LAddr)^ do begin + sin_family := Id_PF_INET4; + TranslateStringToTInAddr(AIP, sin_addr, Id_IPV4); + sin_port := htons(APort); + end; + LiSize := SizeOf(sockaddr); + end else begin + with LAddr do begin + sin6_family := Id_PF_INET6; + TranslateStringToTInAddr(AIP, sin6_addr, AIPVersion); + sin6_port := htons(APort); + end; + LiSize := SizeOf(sockaddr_in6); + end; + LBytesOut := Libc.sendto( + ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL, + {$IFDEF LIBCPASS_STRUCT}Psockaddr(@LAddr)^{$ELSE}Psockaddr(@LAddr){$ENDIF}, + LiSize); + end; + else begin + LBytesOut := 0; // avoid warning + IPVersionUnsupported; + end; + end; + if LBytesOut = Id_SOCKET_ERROR then begin + // TODO: move this into RaiseLastSocketError directly + if WSGetLastError() = Id_WSAEMSGSIZE then begin + raise EIdPackageSizeTooBig.Create(RSPackageSizeTooBig); + end else begin + RaiseLastSocketError; + end; + end else if LBytesOut <> ABufferLength then begin + raise EIdNotAllBytesSent.Create(RSNotAllBytesSent); + end; +end; + +procedure TIdStackLibc.{$IFDEF VCL_XE3_OR_ABOVE}GetSocketOption{$ELSE}WSGetSocketOption{$ENDIF} + (ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; + var AOptVal; var AOptLen: Integer); +var + LLen: UInt32; +begin + LLen := AOptLen; + CheckForSocketError(Libc.getsockopt(ASocket, ALevel, AOptName, PIdAnsiChar(@AOptVal), LLen)); + AOptLen := LLen; +end; + +procedure TIdStackLibc.{$IFDEF VCL_XE3_OR_ABOVE}SetSocketOption{$ELSE}WSSetSocketOption{$ENDIF} + (ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; + const AOptVal; const AOptLen: Integer); +begin + CheckForSocketError(Libc.setsockopt(ASocket, ALevel, AOptName, PIdAnsiChar(@AOptVal), AOptLen)); +end; + +function TIdStackLibc.WSGetLastError: Integer; +begin + //IdStackWindows just uses result := WSAGetLastError; + Result := GetLastError; //System.GetLastOSError; - FPC doesn't define it in System + if Result = Id_WSAEPIPE then begin + Result := Id_WSAECONNRESET; + end; +end; + +function TIdStackLibc.WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; + const ANonBlocking: Boolean = False): TIdStackSocketHandle; override; +begin + Result := Libc.socket(AFamily, AStruct or iif(ANonBlocking, SOCK_NONBLOCK, 0), AProtocol); +end; + +function TIdStackLibc.WSGetServByName(const AServiceName: string): TIdPort; +var + Lps: PServEnt; + {$IFDEF STRING_IS_UNICODE} + LAStr: AnsiString; + {$ENDIF} +begin + {$IFDEF STRING_IS_UNICODE} + LAStr := AnsiString(AServiceName); // explicit convert to Ansi + {$ENDIF} + Lps := Libc.getservbyname( + PAnsiChar({$IFDEF STRING_IS_UNICODE}LAStr{$ELSE}AServiceName{$ENDIF}), + nil); + if Lps <> nil then begin + Result := ntohs(Lps^.s_port); + end else begin + try + Result := IndyStrToInt(AServiceName); + except + on EConvertError do begin + IndyRaiseOuterException(EIdInvalidServiceName.CreateFmt(RSInvalidServiceName, [AServiceName])); + end; + end; + end; +end; + +function TIdStackLibc.WSGetServByPort(const APortNumber: TIdPort): TStrings; +type + PPAnsiCharArray = ^TPAnsiCharArray; + TPAnsiCharArray = packed array[0..(Maxint div SizeOf(PAnsiChar))-1] of PAnsiChar; +var + Lps: PServEnt; + Li: Integer; + Lp: PPAnsiCharArray; +begin + Result := TStringList.Create; + try + Lps := Libc.getservbyport(htons(APortNumber), nil); + if Lps <> nil then begin + Result.Add(String(Lps^.s_name)); + Li := 0; + Lp := Pointer(Lps^.s_aliases); + while Lp[Li] <> nil do begin + Result.Add(String(Lp[Li])); + Inc(Li); + end; + end; + except + FreeAndNil(Result); + raise; + end; +end; + +function TIdStackLibc.HostToNetwork(AValue: UInt16): UInt16; +begin + Result := htons(AValue); +end; + +function TIdStackLibc.NetworkToHost(AValue: UInt16): UInt16; +begin + Result := ntohs(AValue); +end; + +function TIdStackLibc.HostToNetwork(AValue: UInt32): UInt32; +begin + Result := htonl(AValue); +end; + +function TIdStackLibc.NetworkToHost(AValue: UInt32): UInt32; +begin + Result := ntohl(AValue); +end; + +{ RP - I'm not sure what endian Linux natively uses, thus the +check to see if the bytes need swapping or not ... } +function TIdStackLibc.HostToNetwork(AValue: TIdUInt64): TIdUInt64; +var + LParts: TIdUInt64Parts; + L: UInt32; +begin + if (htonl(1) <> 1) then begin + LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + L := htonl(LParts.HighPart); + LParts.HighPart := htonl(LParts.LowPart); + LParts.LowPart := L; + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; + end else begin + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + end; +end; + +function TIdStackLibc.NetworkToHost(AValue: TIdUInt64): TIdUInt64; +var + LParts: TIdUInt64Parts; + L: UInt32; +begin + if (ntohl(1) <> 1) then begin + LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + L := ntohl(LParts.HighPart); + LParts.HighPart := ntohl(LParts.LowPart); + LParts.LowPart := L; + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; + end else begin + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + end; +end; + +{$IFDEF HAS_getifaddrs} +type + TIdStackLocalAddressAccess = class(TIdStackLocalAddress) + end; +{$ENDIF} + +procedure TIdStackLibc.GetLocalAddressList(AAddresses: TIdStackLocalAddressList); +{$IFNDEF HAS_getifaddrs} +type + TaPInAddr = array[0..250] of PInAddr; + PaPInAddr = ^TaPInAddr; + TaPIn6Addr = array[0..250] of PIn6Addr; + PaPIn6Addr = ^TaPIn6Addr; +{$ENDIF} +var + {$IFDEF HAS_getifaddrs} + LAddrList, LAddrInfo: pifaddrs; + LSubNetStr: string; + LAddress: TIdStackLocalAddress; + LName: string; + {$ELSE} + Li: Integer; + LAHost: PHostEnt; + LPAdrPtr: PaPInAddr; + LPAdr6Ptr: PaPIn6Addr; + LHostName: AnsiString; + {$ENDIF} +begin + // TODO: Using gethostname() and gethostbyname() like this may not always + // return just the machine's IP addresses. Technically speaking, they will + // return the local hostname, and then return the address(es) to which that + // hostname resolves. It is possible for a machine to (a) be configured such + // that its name does not resolve to an IP, or (b) be configured such that + // its name resolves to multiple IPs, only one of which belongs to the local + // machine. For better results, we should use getifaddrs() on platforms that + // support it... + + {$IFDEF HAS_getifaddrs} + + if getifaddrs(@LAddrList) = 0 then // TODO: raise an exception if it fails + try + AAddresses.BeginUpdate; + try + LAddrInfo := LAddrList; + repeat + if (LAddrInfo^.ifa_addr <> nil) and ((LAddrInfo^.ifa_flags and IFF_LOOPBACK) = 0) then + begin + LAddress := nil; + case LAddrInfo^.ifa_addr^.sa_family of + Id_PF_INET4: begin + if LAddrInfo^.ifa_netmask <> nil then begin + LSubNetStr := TranslateTInAddrToString(PSockAddr_In(LAddrInfo^.ifa_netmask)^.sin_addr, Id_IPv4); + end else begin + LSubNetStr := ''; + end; + LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, TranslateTInAddrToString(PSockAddr_In(LAddrInfo^.ifa_addr)^.sin_addr, Id_IPv4), LSubNetStr); + end; + Id_PF_INET6: begin + LAddress := TIdStackLocalAddressIPv6.Create(AAddresses, TranslateTInAddrToString(PSockAddr_In6(LAddrInfo^.ifa_addr)^.sin6_addr, Id_IPv6)); + end; + end; + if LAddress <> nil then begin + LName := LAddrInfo^.ifa_name; + {$I IdObjectChecksOff.inc} + TIdStackLocalAddressAccess(LAddress).FDescription := LName; + TIdStackLocalAddressAccess(LAddress).FFriendlyName := LName; + TIdStackLocalAddressAccess(LAddress).FInterfaceName := LName; + {$IFDEF HAS_if_nametoindex} + TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := if_nametoindex(LAddrInfo^.ifa_name); + {$ENDIF} + {$I IdObjectChecksOn.inc} + end; + end; + LAddrInfo := LAddrInfo^.ifa_next; + until LAddrInfo = nil; + finally + AAddresses.EndUpdate; + end; + finally + freeifaddrs(LAddrList); + end; + + {$ELSE} + + // this won't get IPv6 addresses as I didn't find a way + // to enumerate IPv6 addresses on a linux machine + + LHostName := AnsiString(HostName); + LAHost := Libc.gethostbyname(PAnsiChar(LHostName)); + if LAHost = nil then begin + RaiseLastSocketError; + end; + + // gethostbyname() might return other things besides IPv4 addresses, so we + // need to validate the address type before attempting the conversion... + + case LAHost^.h_addrtype of + Id_PF_INET4: begin + LPAdrPtr := PAPInAddr(LAHost^.h_addr_list); + Li := 0; + if LPAdrPtr^[Li] <> nil then begin + AAddresses.BeginUpdate; + try + repeat + TIdStackLocalAddressIPv4.Create(Addresses, TranslateTInAddrToString(LPAdrPtr^[Li]^, Id_IPv4), ''); // TODO: SubNet + Inc(Li); + until LPAdrPtr^[Li] = nil; + finally + AAddresses.EndUpdate; + end; + end; + end; + Id_PF_INET6: begin + LPAdr6Ptr := PAPIn6Addr(LAHost^.h_addr_list); + Li := 0; + if LPAdr6Ptr^[Li] <> nil then begin + AAddresses.BeginUpdate; + try + repeat + TIdStackLocalAddressIPv6.Create(Addresses, TranslateTInAddrToString(LPAdr6Ptr^[Li]^, Id_IPv6)); + Inc(Li); + until LPAdr6Ptr^[Li] = nil; + finally + AAddresses.EndUpdate; + end; + end; + end; + end; + + {$ENDIF} +end; + +function TIdStackLibc.HostByAddress(const AAddress: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; +var + LAddr: sockaddr_in6; + LSize: UInt32; + LHostName : array[0..NI_MAXHOST] of TIdAnsiChar; + {$IFDEF USE_MARSHALLED_PTRS} + LHostNamePtr: TPtrWrapper; + {$ENDIF} + LRet : Integer; + {$IFDEF LIBCPASS_STRUCT} + LHints: TAddressInfo; + LAddrInfo: PAddressInfo; + {$ELSE} + LHints: AddrInfo; //The T is no omission - that's what I found in the header + LAddrInfo: PAddrInfo; + {$ENDIF} +begin + FillChar(LAddr, SizeOf(LAddr), 0); + case AIPVersion of + Id_IPv4: begin + with Psockaddr(@LAddr)^ do begin + sin_family := Id_PF_INET4; + TranslateStringToTInAddr(AAddress, sin_addr, Id_IPv4); + end; + LSize := SizeOf(sockaddr); + end; + Id_IPv6: begin + with LAddr do begin + sin6_family := Id_PF_INET6; + TranslateStringToTInAddr(AAddress, sin6_addr, Id_IPv6); + end; + LSize := SizeOf(sockaddr_in6); + end; + else begin + LSize := 0; // avoid warning + IPVersionUnsupported; + end; + end; + FillChar(LHostName[0],Length(LHostName),0); + {$IFDEF USE_MARSHALLED_PTRS} + LHostNamePtr := TPtrWrapper.Create(@LHostName[0]); + {$ENDIF} + LRet := getnameinfo( + {$IFDEF LIBCPASS_STRUCT}Psockaddr(@LAddr)^{$ELSE}Psockaddr(@LAddr){$ENDIF}, + LSize, + {$IFDEF USE_MARSHALLED_PTRS} + LHostNamePtr.ToPointer + {$ELSE} + LHostName + {$ENDIF}, + NI_MAXHOST,nil,0,NI_NAMEREQD ); + if LRet <> 0 then begin + if LRet = EAI_SYSTEM then begin + RaiseLastOSError; + end else begin + raise EIdReverseResolveError.CreateFmt(RSReverseResolveError, [AAddress, gai_strerror(LRet), LRet]); + end; + end; +{ +IMPORTANT!!! + +getnameinfo can return either results from a numeric to text conversion or +results from a DNS reverse lookup. Someone could make a malicous PTR record +such as + + 1.0.0.127.in-addr.arpa. IN PTR 10.1.1.1 + +and trick a caller into beleiving the socket address is 10.1.1.1 instead of +127.0.0.1. If there is a numeric host in LAddr, than this is the case and +we disregard the result and raise an exception. +} + FillChar(LHints,SizeOf(LHints),0); + LHints.ai_socktype := SOCK_DGRAM; //*dummy*/ + LHints.ai_flags := AI_NUMERICHOST; + if getaddrinfo( + {$IFDEF USE_MARSHALLED_PTRS} + LHostNamePtr.ToPointer + {$ELSE} + LHostName + {$ENDIF}, + '0', LHints, LAddrInfo) = 0 then + begin + freeaddrinfo(LAddrInfo^); + Result := ''; + raise EIdMaliciousPtrRecord.Create(RSMaliciousPtrRecord); + end; + + {$IFDEF USE_MARSHALLED_PTRS} + Result := TMarshal.ReadStringAsAnsi(LHostNamePtr); + {$ELSE} + Result := String(LHostName); + {$ENDIF} +(* JMB: I left this in here just in case someone + complains, but the other code works on all + linux systems for all addresses and is thread-safe + +variables for it: + Host: PHostEnt; + LAddr: u_long; + + Id_IPv4: begin + // GetHostByAddr is thread-safe in Linux. + // It might not be safe in Solaris or BSD Unix + LAddr := inet_addr(PAnsiChar(AAddress)); + Host := GetHostByAddr(@LAddr,SizeOf(LAddr),AF_INET); + if (Host <> nil) then begin + Result := Host^.h_name; + end else begin + RaiseSocketError(h_errno); + end; + end; +*) +end; + +function TIdStackLibc.WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; +begin + Result := Libc.shutdown(ASocket, AHow); +end; + +procedure TIdStackLibc.Disconnect(ASocket: TIdStackSocketHandle); +begin + // Windows uses Id_SD_Send, Linux should use Id_SD_Both + WSShutdown(ASocket, Id_SD_Both); + // SO_LINGER is false - socket may take a little while to actually close after this + WSCloseSocket(ASocket); +end; + +procedure TIdStackLibc.GetPeerName(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); +var + i: UInt32; + LAddr: sockaddr_in6; +begin + i := SizeOf(LAddr); + CheckForSocketError(Libc.getpeername(ASocket, Psockaddr(@LAddr)^, i)); + case LAddr.sin6_family of + Id_PF_INET4: begin + with Psockaddr(@LAddr)^ do + begin + VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); + VPort := ntohs(sin_port); + end; + VIPVersion := Id_IPV4; + end; + Id_PF_INET6: begin + with LAddr do + begin + VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); + VPort := Ntohs(sin6_port); + end; + VIPVersion := Id_IPV6; + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +procedure TIdStackLibc.GetSocketName(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); +var + i: UInt32; + LAddr: sockaddr_in6; +begin + i := SizeOf(LAddr); + CheckForSocketError(Libc.getsockname(ASocket, Psockaddr(@LAddr)^, i)); + case LAddr.sin6_family of + Id_PF_INET4: begin + with Psockaddr(@LAddr)^ do + begin + VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); + VPort := ntohs(sin_port); + end; + VIPVersion := Id_IPV4; + end; + Id_PF_INET6: begin + with LAddr do + begin + VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); + VPort := ntohs(sin6_port); + end; + VIPVersion := Id_IPV6; + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +function TIdStackLibc.WouldBlock(const AResult: Integer): Boolean; +begin + // using if-else instead of in..range because EAGAIN and EWOULDBLOCK + // have often the same value and so FPC might report a range error + Result := (AResult = Id_WSAEAGAIN) or + (AResult = Id_WSAEWOULDBLOCK) or + (AResult = Id_WSAEINPROGRESS); +end; + +function TIdStackLibc.SupportsIPv4: Boolean; +begin + //In Windows, this does something else. It checks the LSP's installed. + Result := CheckIPVersionSupport(Id_IPv4); +end; + +function TIdStackLibc.SupportsIPv6: Boolean; +begin + //In Windows, this does something else. It checks the LSP's installed. + Result := CheckIPVersionSupport(Id_IPv6); +end; + +function TIdStackLibc.CheckIPVersionSupport(const AIPVersion: TIdIPVersion): Boolean; +var + LTmpSocket: TIdStackSocketHandle; +begin + // TODO: on nix systems (or maybe just Linux?), an alternative would be to + // check for the existance of the '/proc/net/if_inet6' kernel pseudo-file + LTmpSocket := WSSocket(IdIPFamily[AIPVersion], Integer(Id_SOCK_STREAM), Id_IPPROTO_IP ); + Result := LTmpSocket <> Id_INVALID_SOCKET; + if Result then begin + WSCloseSocket(LTmpSocket); + end; +end; + +procedure TIdStackLibc.WriteChecksum(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort; const AIPVersion: TIdIPVersion); +begin + case AIPVersion of + Id_IPv4 : CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(VBuffer)), VBuffer, AOffset); + Id_IPv6 : WriteChecksumIPv6(s, VBuffer, AOffset, AIP, APort); + else + IPVersionUnsupported; + end; +end; + +procedure TIdStackLibc.WriteChecksumIPv6(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort); +begin +//we simply request that the kernal write the checksum when the data +//is sent. All of the parameters required are because Windows is bonked +//because it doesn't have the IPV6CHECKSUM socket option meaning we have +//to querry the network interface in TIdStackWindows -- yuck!! + SetSocketOption(s, IPPROTO_IPV6, IPV6_CHECKSUM, AOffset); +end; + +function TIdStackLibc.IOControl(const s: TIdStackSocketHandle; + const cmd: UInt32; var arg: UInt32): Integer; +begin + Result := ioctl(s, cmd, @arg); +end; + +procedure TIdStackLibc.SetKeepAliveValues(ASocket: TIdStackSocketHandle; + const AEnabled: Boolean; const ATimeMS, AInterval: Integer); +begin + inherited; // turn SO_KEEPALIVE on/off first... + // TODO: remove below, as it should be handled by TIdStack.SetKeepAliveValues() now... + if AEnabled then begin + SetSocketOption(ASocket, Id_SOL_TCP, Id_TCP_KEEPIDLE, ATimeMS div MSecsPerSec); + SetSocketOption(ASocket, Id_SOL_TCP, Id_TCP_KEEPINTVL, AInterval div MSecsPerSec); + end; +end; + +{ TIdSocketListLibc } + +type + // TODO: rewrite this to use poll() instead of select(), similar to TIdSocketListVCLPosix + TIdSocketListLibc = class (TIdSocketList) + protected + FCount: integer; + FFDSet: TFDSet; + // + class function FDSelect(AReadSet: PFDSet; AWriteSet: PFDSet; AExceptSet: PFDSet; + const ATimeout: Integer = IdTimeoutInfinite): integer; + function GetItem(AIndex: Integer): TIdStackSocketHandle; override; + public + procedure Add(AHandle: TIdStackSocketHandle); override; + procedure Remove(AHandle: TIdStackSocketHandle); override; + function Count: Integer; override; + procedure Clear; override; + function Clone: TIdSocketList; override; + function ContainsSocket(AHandle: TIdStackSocketHandle): boolean; override; + procedure GetFDSet(var VSet: TFDSet); + procedure SetFDSet(var VSet: TFDSet); + class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; + AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; + override; + function SelectReadList(var VSocketList: TIdSocketList; + const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + End;//TIdSocketList + +procedure TIdSocketListLibc.Add(AHandle: TIdStackSocketHandle); +begin + Lock; + try + if not FD_ISSET(AHandle, FFDSet) then begin + if AHandle >= __FD_SETSIZE then begin + raise EIdStackSetSizeExceeded.Create(RSSetSizeExceeded); + end; + FD_SET(AHandle, FFDSet); + Inc(FCount); + end; + finally + Unlock; + end; +end;// + +procedure TIdSocketListLibc.Clear; +begin + Lock; + try + FD_ZERO(FFDSet); + FCount := 0; + finally + Unlock; + end; +end; + +function TIdSocketListLibc.ContainsSocket( + AHandle: TIdStackSocketHandle): boolean; +begin + Lock; + try + Result := FD_ISSET(AHandle, FFDSet); + finally + Unlock; + end; +end; + +function TIdSocketListLibc.Count: Integer; +begin + Lock; + try + Result := FCount; + finally + Unlock; + end; +end;// + +class function TIdSocketListLibc.FDSelect(AReadSet, AWriteSet, + AExceptSet: PFDSet; const ATimeout: Integer): integer; +var + LTime: TTimeVal; + LTimePtr: PTimeVal; +begin + if ATimeout = IdTimeoutInfinite then begin + LTimePtr := nil; + end else begin + LTime.tv_sec := ATimeout div 1000; + LTime.tv_usec := (ATimeout mod 1000) * 1000; + LTimePtr := @LTime; + end; + // TODO: calculate the actual nfds value based on the Sets provided... + // TODO: use poll() instead of select() to remove limit on how many sockets can be queried + Result := Libc.select(__FD_SETSIZE, AReadSet, AWriteSet, AExceptSet, LTimePtr); +end; + +procedure TIdSocketListLibc.GetFDSet(var VSet: TFDSet); +begin + Lock; + try + VSet := FFDSet; + finally + Unlock; + end; +end; + +function TIdSocketListLibc.GetItem(AIndex: Integer): TIdStackSocketHandle; +var + LIndex, i: Integer; +begin + Result := 0; + Lock; + try + LIndex := 0; + //? use FMaxHandle div x + for i:= 0 to __FD_SETSIZE - 1 do begin + if FD_ISSET(i, FFDSet) then begin + if LIndex = AIndex then begin + Result := i; + Break; + end; + Inc(LIndex); + end; + end; + finally + Unlock; + end; +end;// + +procedure TIdSocketListLibc.Remove(AHandle: TIdStackSocketHandle); +begin + Lock; + try + if FD_ISSET(AHandle, FFDSet) then begin + Dec(FCount); + FD_CLR(AHandle, FFDSet); + end; + finally + Unlock; + end; +end;// + + +function TIdStackLibc.WSTranslateSocketErrorMsg(const AErr: Integer): string; +begin + //we override this function for the herr constants that + //are returned by the DNS functions + case AErr of + Libc.HOST_NOT_FOUND: Result := RSStackHOST_NOT_FOUND; + Libc.TRY_AGAIN: Result := RSStackTRY_AGAIN; + Libc.NO_RECOVERY: Result := RSStackNO_RECOVERY; + Libc.NO_DATA: Result := RSStackNO_DATA; + else + Result := inherited WSTranslateSocketErrorMsg(AErr); + end; +end; + +procedure TIdSocketListLibc.SetFDSet(var VSet: TFDSet); +begin + Lock; + try + FFDSet := VSet; + finally + Unlock; + end; +end; + +class function TIdSocketListLibc.Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; + AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; +var + LReadSet: TFDSet; + LWriteSet: TFDSet; + LExceptSet: TFDSet; + LPReadSet: PFDSet; + LPWriteSet: PFDSet; + LPExceptSet: PFDSet; + + procedure ReadSet(AList: TIdSocketList; var ASet: TFDSet; var APSet: PFDSet); + begin + if AList <> nil then begin + TIdSocketListLibc(AList).GetFDSet(ASet); + APSet := @ASet; + end else begin + APSet := nil; + end; + end; + +begin + ReadSet(AReadList, LReadSet, LPReadSet); + ReadSet(AWriteList, LWriteSet, LPWriteSet); + ReadSet(AExceptList, LExceptSet, LPExceptSet); + // + Result := FDSelect(LPReadSet, LPWriteSet, LPExceptSet, ATimeout) >0; + // + if AReadList <> nil then begin + TIdSocketListLibc(AReadList).SetFDSet(LReadSet); + end; + if AWriteList <> nil then begin + TIdSocketListLibc(AWriteList).SetFDSet(LWriteSet); + end; + if AExceptList <> nil then begin + TIdSocketListLibc(AExceptList).SetFDSet(LExceptSet); + end; +end; + +function TIdSocketListLibc.SelectRead(const ATimeout: Integer): Boolean; +var + LSet: TFDSet; +begin + Lock; + try + LSet := FFDSet; + // select() updates this structure on return, + // so we need to copy it each time we need it + finally + Unlock; + end; + Result := FDSelect(@LSet, nil, nil, ATimeout) > 0; +end; + +function TIdSocketListLibc.SelectReadList(var VSocketList: TIdSocketList; + const ATimeout: Integer = IdTimeoutInfinite): Boolean; +var + LSet: TFDSet; +begin + Lock; + try + LSet := FFDSet; + // select() updates this structure on return, + // so we need to copy it each time we need it + finally + Unlock; + end; + Result := FDSelect(@LSet, nil, nil, ATimeout) > 0; + if Result then begin + if VSocketList = nil then begin + VSocketList := TIdSocketList.CreateSocketList; + end; + TIdSocketListLibc(VSocketList).SetFDSet(LSet); + end; +end; + +procedure TIdStackLibc.SetBlocking(ASocket: TIdStackSocketHandle; + const ABlocking: Boolean); +var + LFlags: Integer; + //LValue: UInt32; +begin + LFlags := CheckForSocketError(Libc.fcntl(ASocket, F_GETFL, 0)); + if ABlocking then begin + LFlags := LFlags and not O_NONBLOCK; + end else begin + LFlags := LFlags or O_NONBLOCK; + end; + CheckForSocketError(Libc.fcntl(ASocket, F_SETFL, LFlags)); + { + LValue := UInt32(not ABlocking); + CheckForSocketError(Libc.ioctl(ASocket, FIONBIO, @LValue)); + } +end; + +(* +Why did I remove this again? + + 1) it sends SIGPIPE even if the socket is created with the no-sigpipe bit set + that could be solved by blocking sigpipe within this thread + This is probably a bug in the Linux kernel, but we could work around it + by blocking that signal for the time of sending the file (just get the + sigprocmask, see if pipe bit is set, if not set it and remove again after + sending the file) + +But the more serious reason is another one, which exists in Windows too: + 2) I think that ServeFile is misdesigned: + ServeFile does not raise an exception if it didn't send all the bytes. + Now what happens if I have OnExecute assigned like this + AThread.Connection.ServeFile('...', True); // <-- true to send via kernel + is that it will return 0, but notice that in this case I didn't ask for the + result. Net effect is that the thread will loop in OnExecute even if the + socket is long gone. This doesn't fit Indy semantics at all, exceptions are + always raised if the remote end disconnects. Even if I would do + AThread.Connection.ServeFile('...', False); + then it would raise an exception. + I think this is a big flaw in the design of the ServeFile function. + Maybe GServeFile should only return the bytes sent, but then + TCPConnection.ServeFile() should raise an exception if GServeFile didn't + send all the bytes. + +JM Berg, 2002-09-09 + +function ServeFile(ASocket: TIdStackSocketHandle; AFileName: string): UInt32; +var + LFileHandle: integer; + offset: integer; + stat: _stat; +begin + LFileHandle := open(PAnsiChar(AFileName), O_RDONLY); + try + offset := 0; + fstat(LFileHandle, stat); + Result := sendfile(ASocket, LFileHandle, offset, stat.st_size); +//** if Result = UInt32(-1) then RaiseLastOSError; + finally libc.__close(LFileHandle); end; +end; +*) +function TIdSocketListLibc.Clone: TIdSocketList; +begin + Result := TIdSocketListLibc.Create; + try + Lock; + try + TIdSocketListLibc(Result).SetFDSet(FFDSet); + finally + Unlock; + end; + except + FreeAndNil(Result); + raise; + end; +end; + +initialization + GSocketListClass := TIdSocketListLibc; + +end. + diff --git a/Lib/System/IdStackLinux.pas b/Lib/System/IdStackLinux.pas index df6587115..ca6c8b10d 100644 --- a/Lib/System/IdStackLinux.pas +++ b/Lib/System/IdStackLinux.pas @@ -1,1459 +1,1459 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.7 10/26/2004 8:20:04 PM JPMugaas - Fixed some oversights with conversion. OOPS!!! - - Rev 1.6 10/26/2004 8:12:32 PM JPMugaas - Now uses TIdStrings and TIdStringList for portability. - - Rev 1.5 12/06/2004 15:17:20 CCostelloe - Restructured to correspond with IdStackWindows, now works. - - Rev 1.4 07/06/2004 21:31:02 CCostelloe - Kylix 3 changes - - Rev 1.3 4/18/04 10:43:22 PM RLebeau - Fixed syntax error - - Rev 1.2 4/18/04 10:29:46 PM RLebeau - Renamed Int64Parts structure to TIdInt64Parts - - Rev 1.1 4/18/04 2:47:28 PM RLebeau - Conversion support for Int64 values - - Removed WSHToNs(), WSNToHs(), WSHToNL(), and WSNToHL() methods, obsolete - - Rev 1.0 2004.02.03 3:14:48 PM czhower - Move and updates - - Rev 1.3 10/19/2003 5:35:14 PM BGooijen - SetSocketOption - - Rev 1.2 2003.10.01 9:11:24 PM czhower - .Net - - Rev 1.1 7/5/2003 07:25:50 PM JPMugaas - Added functions to the Linux stack which use the new TIdIPAddress record type - for IP address parameters. I also fixed a compile bug. - - Rev 1.0 11/13/2002 08:59:24 AM JPMugaas -} - -unit IdStackLinux; - -interface - -{$i IdCompilerDefines.inc} - -uses - Classes, - Libc, - IdStack, - IdStackConsts, - IdGlobal, - IdStackBSDBase; - -type - TIdStackLinux = class(TIdStackBSDBase) - private - procedure WriteChecksumIPv6(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort); - protected - function GetLastError : Integer; - procedure SetLastError(Const AError : Integer); - function HostByName(const AHostName: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; - function ReadHostName: string; override; - function WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; override; - function WSRecv(ASocket: TIdStackSocketHandle; - var ABuffer; const ABufferLength, AFlags: Integer): Integer; override; - function WSSend(ASocket: TIdStackSocketHandle; const ABuffer; const ABufferLength, AFlags: Integer): Integer; override; - function WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; override; - {$IFNDEF VCL_XE3_OR_ABOVE} - procedure WSGetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; - procedure WSSetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; - {$ENDIF} - public - procedure SetBlocking(ASocket: TIdStackSocketHandle; - const ABlocking: Boolean); override; - function WouldBlock(const AResult: Integer): Boolean; override; - function WSTranslateSocketErrorMsg(const AErr: Integer): string; override; - function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; - var VIPVersion: TIdIPVersion): TIdStackSocketHandle; override; - procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - function HostByAddress(const AAddress: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; - function WSGetLastError: Integer; override; - procedure WSSetLastError(const AErr : Integer); override; - function WSGetServByName(const AServiceName: string): TIdPort; override; - function WSGetServByPort(const APortNumber: TIdPort): TStrings; override; - procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; - procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; - procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); override; - function HostToNetwork(AValue: UInt16): UInt16; override; - function NetworkToHost(AValue: UInt16): UInt16; override; - function HostToNetwork(AValue: UInt32): UInt32; override; - function NetworkToHost(AValue: UInt32): UInt32; override; - function HostToNetwork(AValue: TIdUInt64): TIdUInt64; override; - function NetworkToHost(AValue: TIdUInt64): TIdUInt64; override; - function RecvFrom(const ASocket: TIdStackSocketHandle; var VBuffer; - const ALength, AFlags: Integer; var VIP: string; var VPort: TIdPort; - var VIPVersion: TIdIPVersion): Integer; override; - function ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; - APkt: TIdPacketInfo): UInt32; override; - procedure WSSendTo(ASocket: TIdStackSocketHandle; const ABuffer; - const ABufferLength, AFlags: Integer; - const AIP: string; const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - function WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; - const ANonBlocking: Boolean = False): TIdStackSocketHandle; override; - procedure Disconnect(ASocket: TIdStackSocketHandle); override; - {$IFDEF VCL_XE3_OR_ABOVE} - procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; - procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; - {$ENDIF} - function SupportsIPv4: Boolean; overload; override; - function SupportsIPv6: Boolean; overload; override; - function CheckIPVersionSupport(const AIPVersion: TIdIPVersion): boolean; override; - constructor Create; override; - destructor Destroy; override; - //In Windows, this writes a checksum into a buffer. In Linux, it would probably - //simply have the kernal write the checksum with something like this (RFC 2292): -// -// int offset = 2; -// setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)); -// -// Note that this should be called - //IMMEDIATELY before you do a SendTo because the Local IPv6 address might change - - procedure WriteChecksum(s : TIdStackSocketHandle; - var VBuffer : TIdBytes; - const AOffset : Integer; - const AIP : String; - const APort : TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; - var arg: UInt32): Integer; override; - - procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); override; - end; - - TLinger = record - l_onoff: UInt16; - l_linger: UInt16; - end; - TIdLinger = TLinger; - -implementation - -uses - IdResourceStrings, - IdResourceStringsKylixCompat, - IdResourceStringsUnix, - IdException, - SysUtils; - -type - psockaddr_in6 = ^sockaddr_in6; - -const - Id_MSG_NOSIGNAL = MSG_NOSIGNAL; - Id_WSAEPIPE = EPIPE; - -constructor TIdStackLinux.Create; -begin - inherited Create; -end; - -destructor TIdStackLinux.Destroy; -begin - inherited Destroy; -end; - -function TIdStackLinux.GetLastError : Integer; -begin - Result := errno; -end; - -procedure TIdStackLinux.SetLastError(Const AError : Integer); -begin - __errno_location^ := AError; -end; - -procedure TIdStackLinux.WSSetLastError(const AErr : Integer); -begin - SetLastError(AErr); -end; - -function TIdStackLinux.Accept(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): TIdStackSocketHandle; -var - LN: UInt32; - LAddr: sockaddr_in6; -begin - LN := SizeOf(LAddr); - Result := Libc.accept(ASocket, PSockAddr(@LAddr), @LN); - if Result <> SOCKET_ERROR then begin - case LAddr.sin6_family of - Id_PF_INET4: begin - with Psockaddr(@LAddr)^ do - begin - VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); - VPort := Ntohs(sin_port); - end; - VIPVersion := Id_IPV4; - end; - Id_PF_INET6: begin - with LAddr do begin - VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); - VPort := ntohs(sin6_port); - end; - VIPVersion := Id_IPV6; - end; - else begin - Libc.__close(Result); - Result := Id_INVALID_SOCKET; - IPVersionUnsupported; - end; - end; - end else begin - if GetLastError = EBADF then begin - SetLastError(EINTR); - end; - end; -end; - -procedure TIdStackLinux.Bind(ASocket: TIdStackSocketHandle; - const AIP: string; const APort: TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LAddr: sockaddr_in6; - LSize: UInt32; -begin - FillChar(LAddr, SizeOf(LAddr), 0); - case AIPVersion of - Id_IPv4: begin - with Psockaddr(@LAddr)^ do begin - sin_family := Id_PF_INET4; - if AIP <> '' then begin - TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); - end; - sin_port := htons(APort); - end; - LSize := SizeOf(sockaddr); - end; - Id_IPv6: begin - with LAddr do - begin - sin6_family := Id_PF_INET6; - if AIP <> '' then begin - TranslateStringToTInAddr(AIP, sin6_addr, Id_IPv6); - end; - sin6_port := htons(APort); - end; - LSize := SizeOf(sockaddr_in6); - end; - else begin - LSize := 0; // avoid warning - IPVersionUnsupported; - end; - end; - CheckForSocketError(Libc.bind(ASocket, Psockaddr(@LAddr), LSize); -end; - -function TIdStackLinux.WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; -begin - Result := Libc.__close(ASocket); -end; - -procedure TIdStackLinux.Connect(const ASocket: TIdStackSocketHandle; - const AIP: string; const APort: TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LAddr: sockaddr_in6; - LSize: UInt32; -begin - FillChar(LAddr, SizeOf(LAddr), 0); - case AIPVersion of - Id_IPv4: begin - with Psockaddr(@LAddr)^ do begin - sin_family := Id_PF_INET4; - TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); - sin_port := htons(APort); - end; - LSize := SizeOf(sockaddr); - end; - Id_IPv6: begin - with LAddr do begin - sin6_family := Id_PF_INET6; - TranslateStringToTInAddr(AIP, sin6_addr, Id_IPv6); - sin6_port := htons(APort); - end; - LSize := SizeOf(sockaddr_in6); - end; - else begin - LSize := 0; // avoid warning - IPVersionUnsupported; - end; - end; - CheckForSocketError(Libc.connect( - ASocket, - {$IFDEF KYLIX}Psockaddr(@LAddr)^{$ELSE}Psockaddr(@LAddr){$ENDIF}, - LSize)); -end; - -function TIdStackLinux.HostByName(const AHostName: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; -var - Lpa: PAnsiChar; - Lsa: TInAddr; - LHost: PHostEnt; -// ipv6 - LHints: TAddressInfo; - {$IFDEF KYLIX} - LAddrInfo: PAddressInfo; - {$ELSE} - LAddrInfo: PAddrInfo; - {$ENDIF} - LRetVal: Integer; - {$IFDEF STRING_IS_UNICODE} - LAStr: AnsiString; - {$ENDIF} -begin - case AIPVersion of - Id_IPv4: begin - {$IFDEF STRING_IS_UNICODE} - LAStr := AnsiString(AHostName); // explicit convert to Ansi - {$ENDIF} - // TODO: use getaddrinfo() instead for IPv4 as well... - LHost := Libc.gethostbyname( - PAnsiChar({$IFDEF STRING_IS_UNICODE}LAStr{$ELSE}AHostName{$ENDIF})); - if LHost <> nil then begin - // TODO: gethostbyname() might return other things besides IPv4 - // addresses, so we should be validating the address type before - // attempting the conversion... - Lpa := LHost^.h_addr_list^; - Lsa.S_un_b.s_b1 := Ord(Lpa[0]); - Lsa.S_un_b.s_b2 := Ord(Lpa[1]); - Lsa.S_un_b.s_b3 := Ord(Lpa[2]); - Lsa.S_un_b.s_b4 := Ord(Lpa[3]); - Result := TranslateTInAddrToString(Lsa, Id_IPv4); - end else begin - //RaiseSocketError(h_errno); - RaiseLastSocketError; - end; - end; - Id_IPv6: begin - FillChar(LHints, SizeOf(LHints), 0); - LHints.ai_family := IdIPFamily[AIPVersion]; - LHints.ai_socktype := Integer(SOCK_STREAM); - LAddrInfo := nil; - - {$IFDEF STRING_IS_UNICODE} - LAStr := AnsiString(AHostName); // explicit convert to Ansi - {$ENDIF} - LRetVal := getaddrinfo( - PAnsiChar({$IFDEF STRING_IS_UNICODE}LAStr{$ELSE}AHostName{$ENDIF}), - nil, @LHints, {$IFDEF KYLIX}LAddrInfo{$ELSE}@LAddrInfo{$ENDIF}); - if LRetVal <> 0 then begin - if LRetVal = EAI_SYSTEM then begin - IndyRaiseLastError; - end else begin - raise EIdResolveError.CreateFmt(RSResolveError, [AHostName, gai_strerror(LRetVal), LRetVal]); - end; - end; - try - Result := TranslateTInAddrToString(LAddrInfo^.ai_addr^.sin_zero, Id_IPv6); - finally - freeaddrinfo(LAddrInfo); - end; - end; - else - Result := ''; // avoid warning - IPVersionUnsupported; - end; -end; - -function TIdStackLinux.ReadHostName: string; -var - LStr: array[0..250] of AnsiChar; -begin - if Libc.gethostname(LStr, 250) = 0 then begin - LStr[250] := #0; - Result := String(LStr); - end else begin - Result := ''; - end; -end; - -procedure TIdStackLinux.Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); -begin - CheckForSocketError(Libc.listen(ASocket, ABacklog)); -end; - -function TIdStackLinux.WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; - const ABufferLength, AFlags: Integer): Integer; -begin - //IdStackWindows is just: Result := Recv(ASocket, ABuffer, ABufferLength, AFlags); - Result := Recv(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); -end; - -function TIdStackLinux.RecvFrom(const ASocket: TIdStackSocketHandle; - var VBuffer; const ALength, AFlags: Integer; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; -var - LiSize: UInt32; - LAddr: sockaddr_in6; -begin - LiSize := SizeOf(sockaddr_in6); - Result := Libc.recvfrom(ASocket, VBuffer, ALength, AFlags or Id_MSG_NOSIGNAL, PSockAddr(@LAddr), @LiSize); - if Result >= 0 then - begin - case LAddr.sin6_family of - Id_PF_INET4: begin - with Psockaddr(@LAddr)^ do begin - VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); - VPort := Ntohs(sin_port); - end; - VIPVersion := Id_IPV4; - end; - Id_PF_INET6: begin - with LAddr do begin - VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); - VPort := ntohs(sin6_port); - end; - VIPVersion := Id_IPV6; - end; - else begin - Result := 0; - IPVersionUnsupported; - end; - end; - end; -end; - -function TIdStackLinux.ReceiveMsg(ASocket: TIdStackSocketHandle; - var VBuffer: TIdBytes; APkt: TIdPacketInfo): UInt32; -{var - LIP : String; - LPort : TIdPort; - LSize: UInt32; - LAddr: SockAddr_In6; - LMsg : msghdr; - LMsgBuf : BUF; - LControl : TIdBytes; - LCurCmsg : CMSGHDR; //for iterating through the control buffer - LByte : PByte; - LDummy, LDummy2 : UInt32; - -begin - //we call the macro twice because we specified two possible structures. - //Id_IPV6_HOPLIMIT and Id_IPV6_PKTINFO - LSize := CMSG_SPACE(SizeOf(Byte)) + CMSG_SPACE(SizeOf(in6_pktinfo)); - SetLength(LControl, LSize); - - LMsgBuf.len := Length(VBuffer); // Length(VMsgData); - LMsgBuf.buf := @VBuffer[0]; // @VMsgData[0]; - - FillChar(LMsg,SizeOf(LMsg),0); - - LMsg.lpBuffers := @LMsgBuf; - LMsg.dwBufferCount := 1; - - LMsg.Control.Len := LSize; - LMsg.Control.buf := @LControl[0]; - - LMsg.name := PSOCKADDR(@LAddr); - LMsg.namelen := SizeOf(LAddr); - - CheckForSocketError(RecvMsg(ASocket, @LMsg, Result, @LDummy, LPwsaoverlapped_COMPLETION_ROUTINE(@LDummy2))); - APkt.Reset; - - case LAddr.sin6_family of - Id_PF_INET4: begin - with Psockaddr(@LAddr)^ do - begin - APkt.SourceIP := TranslateTInAddrToString(sin_addr, Id_IPv4); - APkt.SourcePort := ntohs(sin_port); - end; - APkt.SourceIPVersion := Id_IPv4; - end; - Id_PF_INET6: begin - with LAddr do - begin - APkt.SourceIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); - APkt.SourcePort := ntohs(sin6_port); - end; - APkt.SourceIPVersion := Id_IPv6; - end; - else begin - Result := 0; // avoid warning - IPVersionUnsupported; - end; - end; - - LCurCmsg := nil; - repeat - LCurCmsg := CMSG_NXTHDR(@LMsg,LCurCmsg); - if LCurCmsg=nil then - begin - break; - end; - case LCurCmsg^.cmsg_type of - IP_PKTINFO : //done this way because IPV6_PKTINF and IP_PKTINFO - //are both 19 - begin - case LAddr.sin6_family of - Id_PF_INET4: begin - with Pin_pktinfo(WSA_CMSG_DATA(LCurCmsg))^ do - begin - APkt.DestIP := GWindowsStack.TranslateTInAddrToString(ipi_addr, Id_IPv4); - APkt.DestIF := ipi_ifindex; - end; - APkt.DestIPVersion := Id_IPv4; - end; - Id_PF_INET6: begin - with Pin6_pktinfo(WSA_CMSG_DATA(LCurCmsg))^ do - begin - APkt.DestIP := GWindowsStack.TranslateTInAddrToString(ipi6_addr, Id_IPv6); - APkt.DestIF := ipi6_ifindex; - end; - APkt.DestIPVersion := Id_IPv6; - end; - end; - end; - Id_IPV6_HOPLIMIT : - begin - LByte := PByte(WSA_CMSG_DATA(LCurCmsg)); - APkt.TTL := LByte^; - end; - end; - until False; } -begin - APkt.Reset; - Result := 0; // avoid warning -end; - -function TIdStackLinux.WSSend(ASocket: TIdStackSocketHandle; - const ABuffer; const ABufferLength, AFlags: Integer): Integer; -begin - //CC: Should Id_MSG_NOSIGNAL be included? - // Result := Send(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); - Result := CheckForSocketError(Libc.send(ASocket, ABuffer, ABufferLength, AFlags)); -end; - -procedure TIdStackLinux.WSSendTo(ASocket: TIdStackSocketHandle; - const ABuffer; const ABufferLength, AFlags: Integer; const AIP: string; - const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LAddr: sockaddr_in6; - LiSize: Integer; -begin - FillChar(LAddr, SizeOf(LAddr), 0); - case AIPVersion of - Id_IPv4: begin - with Psockaddr(@LAddr)^ do begin - sin_family := Id_PF_INET4; - TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); - sin_port := htons(APort); - end; - LiSize := SizeOf(sockaddr); - end; - Id_IPv6: begin - with LAddr do begin - sin6_family := Id_PF_INET6; - TranslateStringToTInAddr(AIP, sin6_addr, Id_IPv6); - sin6_port := htons(APort); - end; - LiSize := SizeOf(sockaddr_in6); - end; - else begin - LiSize := 0; // avoid warning - IPVersionUnsupported; - end; - end; - LiSize := Libc.sendto( - ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL, - {$IFDEF KYLIX}Psockaddr(@LAddr)^{$ELSE}Psockaddr(@LAddr){$ENDIF}, - LiSize); - end; - if LiSize = Id_SOCKET_ERROR then begin - // TODO: move this into RaiseLastSocketError directly - if WSGetLastError() = Id_WSAEMSGSIZE then begin - raise EIdPackageSizeTooBig.Create(RSPackageSizeTooBig); - end else begin - RaiseLastSocketError; - end; - end - else if LiSize <> ABufferLength then begin - raise EIdNotAllBytesSent.Create(RSNotAllBytesSent); - end; -end; - -procedure TIdStackLinux.{$IFDEF VCL_XE3_OR_ABOVE}GetSocketOption{$ELSE}WSGetSocketOption{$ENDIF} - (ASocket: TIdStackSocketHandle; ALevel: TIdSocketProtocol; AOptName: TIdSocketOption; - var AOptVal; var AOptLen: Integer); -var - LLen: UInt32; -begin - LLen := AOptLen; - CheckForSocketError(Libc.getsockopt(ASocket, ALevel, AOptName, PAnsiChar(@AOptVal), LLen)); - AOptLen := LLen; -end; - -procedure TIdStackLinux.{$IFDEF VCL_XE3_OR_ABOVE}SetSocketOption{$ELSE}WSSetSocketOption{$ENDIF} - (ASocket: TIdStackSocketHandle; ALevel: TIdSocketProtocol; AOptName: TIdSocketOption; - const AOptVal; const AOptLen: Integer); -begin - CheckForSocketError(Libc.setsockopt(ASocket, ALevel, AOptName, PAnsiChar(@AOptVal), AOptLen)); -end; - -function TIdStackLinux.WSGetLastError: Integer; -begin - //IdStackWindows just uses result := WSAGetLastError; - Result := GetLastError; //System.GetLastOSError; - FPC doesn't define it in System - if Result = Id_WSAEPIPE then begin - Result := Id_WSAECONNRESET; - end; -end; - -function TIdStackLinux.WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; - const ANonBlocking: Boolean = False): TIdStackSocketHandle; -begin - Result := Libc.socket(AFamily, AStruct or iif(ANonBlocking, SOCK_NONBLOCK, 0), AProtocol); -end; - -function TIdStackLinux.WSGetServByName(const AServiceName: string): TIdPort; -var - Lps: PServEnt; - {$IFDEF STRING_IS_UNICODE} - LAStr: AnsiString; - {$ENDIF} -begin - {$IFDEF STRING_IS_UNICODE} - LAStr := AnsiString(AServiceName); // explicit convert to Ansi - {$ENDIF} - Lps := Libc.getservbyname( - PAnsiChar({$IFDEF STRING_IS_UNICODE}LAStr{$ELSE}AServiceName{$ENDIF}, - nil); - if Lps <> nil then begin - Result := ntohs(Lps^.s_port); - end else begin - try - Result := IndyStrToInt(AServiceName); - except - on EConvertError do begin - IndyRaiseOuterException(EIdInvalidServiceName.CreateFmt(RSInvalidServiceName, [AServiceName])); - end; - end; - end; -end; - -function TIdStackLinux.WSGetServByPort(const APortNumber: TIdPort): TStrings; -type - PPAnsiCharArray = ^TPAnsiCharArray; - TPAnsiCharArray = packed array[0..(Maxint div SizeOf(PAnsiChar))-1] of PAnsiChar; -var - Lps: PServEnt; - Li: Integer; - Lp: PPAnsiCharArray; -begin - Result := TStringList.Create; - Lp := nil; - try - Lps := Libc.getservbyport(htons(APortNumber), nil); - if Lps <> nil then begin - Result.Add(Lps^.s_name); - Li := 0; - Lp := Pointer(Lps^.s_aliases); - while Lp[Li] <> nil do begin - Result.Add(Lp[Li]); - Inc(Li); - end; - end; - except - FreeAndNil(Result); - raise; - end; -end; - -function TIdStackLinux.HostToNetwork(AValue: UInt16): UInt16; -begin - Result := htons(AValue); -end; - -function TIdStackLinux.NetworkToHost(AValue: UInt16): UInt16; -begin - Result := ntohs(AValue); -end; - -function TIdStackLinux.HostToNetwork(AValue: UInt32): UInt32; -begin - Result := htonl(AValue); -end; - -function TIdStackLinux.NetworkToHost(AValue: UInt32): UInt32; -begin - Result := ntohl(AValue); -end; - -{ RP - I'm not sure what endian Linux natively uses, thus the -check to see if the bytes need swapping or not ... } -function TIdStackLinux.HostToNetwork(AValue: TIdUInt64): TIdUInt64; -var - LParts: TIdUInt64Parts; - L: UInt32; -begin - if (htonl(1) <> 1) then begin - LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - L := htonl(LParts.HighPart); - LParts.HighPart := htonl(LParts.LowPart); - LParts.LowPart := L; - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; - end else begin - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - end; -end; - -function TIdStackLinux.NetworkToHost(AValue: TIdUInt64): TIdUInt64; -var - LParts: TIdUInt64Parts; - L: UInt32; -begin - if (ntohl(1) <> 1) then begin - LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - L := ntohl(LParts.HighPart); - LParts.HighPart := ntohl(LParts.LowPart); - LParts.LowPart := L; - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; - end else begin - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - end; -end; - -{$IFDEF HAS_getifaddrs} -type - TIdStackLocalAddressAccess = class(TIdStackLocalAddress) - end; -{$ENDIF} - -procedure TIdStackLinux.GetLocalAddressList(AAddresses: TIdStackLocalAddressList); -{$IFNDEF HAS_getifaddrs} -type - TaPInAddr = array[0..250] of PInAddr; - PaPInAddr = ^TaPInAddr; - TaPIn6Addr = array[0..250] of PIn6Addr; - PaPIn6Addr = ^TaPIn6Addr; -{$ENDIF} -var - {$IFDEF HAS_getifaddrs} - LAddrList, LAddrInfo: pifaddrs; - LSubNetStr: string; - LAddress: TIdStackLocalAddress; - LName: string; - {$ELSE} - Li: Integer; - LAHost: PHostEnt; - LPAdrPtr: PaPInAddr; - LHostName: AnsiString; - {$ENDIF} -begin - // TODO: Using gethostname() and gethostbyname() like this may not always - // return just the machine's IP addresses. Technically speaking, they will - // return the local hostname, and then return the address(es) to which that - // hostname resolves. It is possible for a machine to (a) be configured such - // that its name does not resolve to an IP, or (b) be configured such that - // its name resolves to multiple IPs, only one of which belongs to the local - // machine. For better results, we should use getifaddrs() on platforms that - // support it... - - {$IFDEF HAS_getifaddrs} - - if getifaddrs(@LAddrList) = 0 then // TODO: raise an exception if it fails - try - AAddresses.BeginUpdate; - try - LAddrInfo := LAddrList; - repeat - if (LAddrInfo^.ifa_addr <> nil) and ((LAddrInfo^.ifa_flags and IFF_LOOPBACK) = 0) then - begin - LAddress := nil; - case LAddrInfo^.ifa_addr^.sa_family of - Id_PF_INET4: begin - if LAddrInfo^.ifa_netmask <> nil then begin - LSubNetStr := TranslateTInAddrToString(PSockAddr_In(LAddrInfo^.ifa_netmask)^.sin_addr, Id_IPv4); - end else begin - LSubNetStr := ''; - end; - LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, TranslateTInAddrToString(PSockAddr_In(LAddrInfo^.ifa_addr)^.sin_addr, Id_IPv4), LSubNetStr); - end; - Id_PF_INET6: begin - LAddress := TIdStackLocalAddressIPv6.Create(AAddresses, TranslateTInAddrToString(PSockAddr_In6(LAddrInfo^.ifa_addr)^.sin6_addr, Id_IPv6)); - end; - end; - if LAddress <> nil then begin - LName := LAddrInfo^.ifa_name; - {$I IdObjectChecksOff.inc} - TIdStackLocalAddressAccess(LAddress).FDescription := LName; - TIdStackLocalAddressAccess(LAddress).FFriendlyName := LName; - TIdStackLocalAddressAccess(LAddress).FInterfaceName := LName; - {$IFDEF HAS_if_nametoindex} - TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := if_nametoindex(LAddrInfo^.ifa_name); - {$ENDIF} - {$I IdObjectChecksOn.inc} - end; - end; - LAddrInfo := LAddrInfo^.ifa_next; - until LAddrInfo = nil; - finally - AAddresses.EndUpdate; - end; - finally - freeifaddrs(LAddrList); - end; - - {$ELSE} - - // this won't get IPv6 addresses as I didn't find a way - // to enumerate IPv6 addresses on a linux machine - - LHostName := HostName; - LAHost := Libc.gethostbyname(PAnsiChar(LHostName)); - if LAHost = nil then begin - RaiseLastSocketError; - end; - - // gethostbyname() might return other things besides IPv4 addresses, so we - // need to validate the address type before attempting the conversion... - - case LAHost^.h_addrtype of - Id_PF_INET4: begin - LPAdrPtr := PAPInAddr(LAHost^.h_addr_list); - Li := 0; - if LPAdrPtr^[Li] <> nil then begin - AAddresses.BeginUpdate; - try - repeat - TIdStackLocalAddressIPv4.Create(AAddresses, TranslateTInAddrToString(LPAdrPtr^[Li]^, Id_IPv4), ''); // TODO: SubNet - Inc(Li); - until LPAdrPtr^[Li] = nil; - finally - AAddresses.EndUpdate; - end; - end; - end; - Id_PF_INET6: begin - LPAdr6Ptr := PAPIn6Addr(LAHost^.h_addr_list); - Li := 0; - if LPAdr6Ptr^[Li] <> nil then begin - AAddresses.BeginUpdate; - try - repeat - TIdStackLocalAddressIPv6.Create(AAddresses, TranslateTInAddrToString(LPAdr6Ptr^[Li]^, Id_IPv6)); - Inc(Li); - until LPAdr6Ptr^[Li] = nil; - finally - AAddresses.EndUpdate; - end; - end; - end; - end; - - {$ENDIF} -end; - -function TIdStackLinux.HostByAddress(const AAddress: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; -var - LAddr: sockaddr_in6; - LSize: UInt32; - LHostName : array[0..NI_MAXHOST] of TIdAnsiChar; - {$IFDEF USE_MARSHALLED_PTRS} - LHostNamePtr: TPtrWrapper; - {$ENDIF} - LRet : Integer; - {$IFDEF KYLIX} - LHints: TAddressInfo; - LAddrInfo: PAddressInfo; - {$ELSE} - LHints: AddrInfo; //The T is no omission - that's what I found in the header - LAddrInfo: PAddrInfo; - {$ENDIF} -begin - FillChar(LAddr, SizeOf(LAddr), 0); - case AIPVersion of - Id_IPv4: begin - with Psockaddr(@LAddr)^ do begin - sin_family := Id_PF_INET4; - TranslateStringToTInAddr(AAddress, sin_addr, Id_IPv4); - end; - LSize := SizeOf(sockaddr); - end; - Id_IPv6: begin - with LAddr do begin - sin6_family := Id_PF_INET6; - TranslateStringToTInAddr(AAddress, sin6_addr, Id_IPv6); - end; - LSize := SizeOf(sockaddr_in6); - end; - else begin - LSize := 0; // avoid warning - IPVersionUnsupported; - end; - end; - FillChar(LHostName[0],Length(LHostName),0); - {$IFDEF USE_MARSHALLED_PTRS} - LHostNamePtr := TPtrWrapper.Create(@LHostName[0]); - {$ENDIF} - LRet := getnameinfo(Psockaddr(@LAddr)^, LSize, - {$IFDEF USE_MARSHALLED_PTRS} - LHostNamePtr.ToPointer - {$ELSE} - LHostName - {$ENDIF}, - NI_MAXHOST,nil,0,NI_NAMEREQD ); - if LRet <> 0 then begin - if LRet = EAI_SYSTEM then begin - RaiseLastOSError; - end else begin - raise EIdReverseResolveError.CreateFmt(RSReverseResolveError, [AAddress, gai_strerror(LRet), LRet]); - end; - end; -{ -IMPORTANT!!! - -getnameinfo can return either results from a numeric to text conversion or -results from a DNS reverse lookup. Someone could make a malicous PTR record -such as - - 1.0.0.127.in-addr.arpa. IN PTR 10.1.1.1 - -and trick a caller into beleiving the socket address is 10.1.1.1 instead of -127.0.0.1. If there is a numeric host in LAddr, than this is the case and -we disregard the result and raise an exception. -} - FillChar(LHints,SizeOf(LHints),0); - LHints.ai_socktype := SOCK_DGRAM; //*dummy*/ - LHints.ai_flags := AI_NUMERICHOST; - if getaddrinfo( - {$IFDEF USE_MARSHALLED_PTRS} - LHostNamePtr.ToPointer - {$ELSE} - LHostName - {$ENDIF}, - '0', LHints, LAddrInfo) = 0 then - begin - freeaddrinfo(LAddrInfo^); - Result := ''; - raise EIdMaliciousPtrRecord.Create(RSMaliciousPtrRecord); - end; - - {$IFDEF USE_MARSHALLED_PTRS} - Result := TMarshal.ReadStringAsAnsi(LHostNamePtr); - {$ELSE} - Result := String(LHostName); - {$ENDIF} -(* JMB: I left this in here just in case someone - complains, but the other code works on all - linux systems for all addresses and is thread-safe - -variables for it: - Host: PHostEnt; - LAddr: u_long; - - Id_IPv4: begin - // GetHostByAddr is thread-safe in Linux. - // It might not be safe in Solaris or BSD Unix - LAddr := inet_addr(PAnsiChar(AAddress)); - Host := GetHostByAddr(@LAddr,SizeOf(LAddr),AF_INET); - if (Host <> nil) then begin - Result := Host^.h_name; - end else begin - RaiseSocketError(h_errno); - end; - end; -*) -end; - -function TIdStackLinux.WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; -begin - Result := Libc.shutdown(ASocket, AHow); -end; - -procedure TIdStackLinux.Disconnect(ASocket: TIdStackSocketHandle); -begin - // Windows uses Id_SD_Send, Linux should use Id_SD_Both - WSShutdown(ASocket, Id_SD_Both); - // SO_LINGER is false - socket may take a little while to actually close after this - WSCloseSocket(ASocket); -end; - -procedure TIdStackLinux.GetPeerName(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); -var - LiSize: UInt32; - LAddr: sockaddr_in6; -begin - LiSize := SizeOf(LAddr); - CheckForSocketError(Libc.getpeername(ASocket, Psockaddr(@LAddr)^, LiSize)); - case LAddr.sin6_family of - Id_PF_INET4: begin - with Psockaddr(@LAddr6)^ do begin - VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); - VPort := ntohs(sin_port); - end; - VIPVersion := Id_IPV4; - end; - Id_PF_INET6: begin - with LAddr do begin - VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); - VPort := Ntohs(sin6_port); - end; - VIPVersion := Id_IPV6; - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -procedure TIdStackLinux.GetSocketName(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); -var - LiSize: UInt32; - LAddr: sockaddr_in6; -begin - LiSize := SizeOf(LAddr); - CheckForSocketError(Libc.getsockname(ASocket, Psockaddr(@LAddr)^, LiSize)); - case LAddr.sin6_family of - Id_PF_INET4: begin - with Psockaddr(@LAddr6)^ do begin - VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); - VPort := ntohs(sin_port); - end; - VIPVersion := Id_IPV4; - end; - Id_PF_INET6: begin - with LAddr do begin - VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); - VPort := ntohs(sin6_port); - end; - VIPVersion := Id_IPV6; - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -function TIdStackLinux.WouldBlock(const AResult: Integer): Boolean; -begin - // using if-else instead of in..range because EAGAIN and EWOULDBLOCK - // have often the same value and so FPC might report a range error - Result := (AResult = Id_WSAEAGAIN) or - (AResult = Id_WSAEWOULDBLOCK) or - (AResult = Id_WSAEINPROGRESS); -end; - -function TIdStackLinux.SupportsIPv4: Boolean; -begin - //In Windows, this does something else. It checks the LSP's installed. - Result := CheckIPVersionSupport(Id_IPv4); -end; - -function TIdStackLinux.SupportsIPv6: Boolean; -begin - //In Windows, this does something else. It checks the LSP's installed. - Result := CheckIPVersionSupport(Id_IPv6); -end; - -function TIdStackLinux.CheckIPVersionSupport(const AIPVersion: TIdIPVersion): Boolean; -var - LTmpSocket: TIdStackSocketHandle; -begin - // TODO: an alternative would be to check for the existance of the '/proc/net/if_inet6' kernel pseudo-file - LTmpSocket := WSSocket(IdIPFamily[AIPVersion], Id_SOCK_STREAM, Id_IPPROTO_IP ); - Result := LTmpSocket <> Id_INVALID_SOCKET; - if Result then begin - WSCloseSocket(LTmpSocket); - end; -end; - -procedure TIdStackLinux.WriteChecksum(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort; const AIPVersion: TIdIPVersion); -begin - case AIPVersion of - Id_IPv4 : CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(VBuffer)), VBuffer, AOffset); - Id_IPv6 : WriteChecksumIPv6(s, VBuffer, AOffset, AIP, APort); - else - IPVersionUnsupported; - end; -end; - -procedure TIdStackLinux.WriteChecksumIPv6(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort); -begin -//we simply request that the kernal write the checksum when the data -//is sent. All of the parameters required are because Windows is bonked -//because it doesn't have the IPV6CHECKSUM socket option meaning we have -//to querry the network interface in TIdStackWindows -- yuck!! - SetSocketOption(s, IPPROTO_IPV6, IPV6_CHECKSUM, AOffset); -end; - -function TIdStackLinux.IOControl(const s: TIdStackSocketHandle; - const cmd: UInt32; var arg: UInt32): Integer; -begin - Result := ioctl(s, cmd, @arg); -end; - -{ TIdSocketListLinux } - -type - // TODO: rewrite this to use poll() instead of select(), similar to TIdSocketListVCLPosix - TIdSocketListLinux = class (TIdSocketList) - protected - FCount: integer; - FFDSet: TFDSet; - // - class function FDSelect(AReadSet: PFDSet; AWriteSet: PFDSet; AExceptSet: PFDSet; - const ATimeout: Integer = IdTimeoutInfinite): integer; - function GetItem(AIndex: Integer): TIdStackSocketHandle; override; - public - procedure Add(AHandle: TIdStackSocketHandle); override; - procedure Remove(AHandle: TIdStackSocketHandle); override; - function Count: Integer; override; - procedure Clear; override; - function Clone: TIdSocketList; override; - function ContainsSocket(AHandle: TIdStackSocketHandle): boolean; override; - procedure GetFDSet(var VSet: TFDSet); - procedure SetFDSet(var VSet: TFDSet); - class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; - AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; - override; - function SelectReadList(var VSocketList: TIdSocketList; - const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - End;//TIdSocketList - -procedure TIdSocketListLinux.Add(AHandle: TIdStackSocketHandle); -begin - Lock; - try - if not FD_ISSET(AHandle, FFDSet) then begin - if AHandle >= __FD_SETSIZE{MaxLongint} then begin - raise EIdStackSetSizeExceeded.Create(RSSetSizeExceeded); - end; - FD_SET(AHandle, FFDSet); - Inc(FCount); - end; - finally - Unlock; - end; -end;// - -procedure TIdSocketListLinux.Clear; -begin - Lock; - try - FD_ZERO(FFDSet); - FCount := 0; - finally - Unlock; - end; -end; - -function TIdSocketListLinux.ContainsSocket( - AHandle: TIdStackSocketHandle): boolean; -begin - Lock; - try - Result := FD_ISSET(AHandle, FFDSet); - finally - Unlock; - end; -end; - -function TIdSocketListLinux.Count: Integer; -begin - Lock; - try - Result := FCount; - finally - Unlock; - end; -end;// - -class function TIdSocketListLinux.FDSelect(AReadSet, AWriteSet, - AExceptSet: PFDSet; const ATimeout: Integer): integer; -var - LTime: TTimeVal; - LTimePtr: PTimeVal; -begin - if ATimeout = IdTimeoutInfinite then begin - LTimePtr := nil; - end else begin - LTime.tv_sec := ATimeout div 1000; - LTime.tv_usec := (ATimeout mod 1000) * 1000; - LTimePtr := @LTime; - end; - // TODO: calculate the actual nfds value based on the Sets provided... - // TODO: use poll() instead of select() to remove limit on how many sockets can be queried - Result := Libc.select({__FD_SETSIZE}MaxLongint, AReadSet, AWriteSet, AExceptSet, LTimePtr); -end; - -procedure TIdSocketListLinux.GetFDSet(var VSet: TFDSet); -begin - Lock; - try - VSet := FFDSet; - finally - Unlock; - end; -end; - -function TIdSocketListLinux.GetItem(AIndex: Integer): TIdStackSocketHandle; -var - LIndex, i: Integer; -begin - Result := 0; - Lock; - try - LIndex := 0; - //? use FMaxHandle div x - for i:= 0 to __FD_SETSIZE - 1 do begin - if FD_ISSET(i, FFDSet) then begin - if LIndex = AIndex then begin - Result := i; - Break; - end; - Inc(LIndex); - end; - end; - finally - Unlock; - end; -end;// - -procedure TIdSocketListLinux.Remove(AHandle: TIdStackSocketHandle); -begin - Lock; - try - if FD_ISSET(AHandle, FFDSet) then begin - Dec(FCount); - FD_CLR(AHandle, FFDSet); - end; - finally - Unlock; - end; -end;// - - -function TIdStackLinux.WSTranslateSocketErrorMsg(const AErr: Integer): string; -begin - //we override this function for the herr constants that - //are returned by the DNS functions - case AErr of - Libc.HOST_NOT_FOUND: Result := RSStackHOST_NOT_FOUND; - Libc.TRY_AGAIN: Result := RSStackTRY_AGAIN; - Libc.NO_RECOVERY: Result := RSStackNO_RECOVERY; - Libc.NO_DATA: Result := RSStackNO_DATA; - else - Result := inherited WSTranslateSocketErrorMsg(AErr); - end; -end; - -procedure TIdSocketListLinux.SetFDSet(var VSet: TFDSet); -begin - Lock; - try - FFDSet := VSet; - finally - Unlock; - end; -end; - -class function TIdSocketListLinux.Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; - AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; -var - LReadSet: TFDSet; - LWriteSet: TFDSet; - LExceptSet: TFDSet; - LPReadSet: PFDSet; - LPWriteSet: PFDSet; - LPExceptSet: PFDSet; - - procedure ReadSet(AList: TIdSocketList; var ASet: TFDSet; var APSet: PFDSet); - begin - if AList <> nil then begin - TIdSocketListLinux(AList).GetFDSet(ASet); - APSet := @ASet; - end else begin - APSet := nil; - end; - end; - -begin - ReadSet(AReadList, LReadSet, LPReadSet); - ReadSet(AWriteList, LWriteSet, LPWriteSet); - ReadSet(AExceptList, LExceptSet, LPExceptSet); - // - Result := FDSelect(LPReadSet, LPWriteSet, LPExceptSet, ATimeout) >0; - // - if AReadList <> nil then begin - TIdSocketListLinux(AReadList).SetFDSet(LReadSet); - end; - if AWriteList <> nil then begin - TIdSocketListLinux(AWriteList).SetFDSet(LWriteSet); - end; - if AExceptList <> nil then begin - TIdSocketListLinux(AExceptList).SetFDSet(LExceptSet); - end; -end; - -function TIdSocketListLinux.SelectRead(const ATimeout: Integer): Boolean; -var - LSet: TFDSet; -begin - Lock; - try - LSet := FFDSet; - // select() updates this structure on return, - // so we need to copy it each time we need it - finally - Unlock; - end; - Result := FDSelect(@LSet, nil, nil, ATimeout) > 0; -end; - -function TIdSocketListLinux.SelectReadList(var VSocketList: TIdSocketList; - const ATimeout: Integer = IdTimeoutInfinite): Boolean; -var - LSet: TFDSet; -begin - Lock; - try - LSet := FFDSet; - // select() updates this structure on return, - // so we need to copy it each time we need it - finally - Unlock; - end; - Result := FDSelect(@LSet, nil, nil, ATimeout) > 0; - if Result then begin - if VSocketList = nil then begin - VSocketList := TIdSocketList.CreateSocketList; - end; - TIdSocketListLinux(VSocketList).SetFDSet(LSet); - end; -end; - -procedure TIdStackLinux.SetBlocking(ASocket: TIdStackSocketHandle; - const ABlocking: Boolean); -var - LFlags: Integer; - //LValue: UInt32; -begin - LFlags := CheckForSocketError(Libc.fcntl(ASocket, F_GETFL, 0)); - if ABlocking then begin - LFlags := LFlags and not O_NONBLOCK; - end else begin - LFlags := LFlags or O_NONBLOCK; - end; - CheckForSocketError(Libc.fcntl(ASocket, F_SETFL, LFlags)); - { - LValue := UInt32(not ABlocking); - CheckForSocketError(Libc.ioctl(ASocket, FIONBIO, @LValue)); - } -end; - -(* -Why did I remove this again? - - 1) it sends SIGPIPE even if the socket is created with the no-sigpipe bit set - that could be solved by blocking sigpipe within this thread - This is probably a bug in the Linux kernel, but we could work around it - by blocking that signal for the time of sending the file (just get the - sigprocmask, see if pipe bit is set, if not set it and remove again after - sending the file) - -But the more serious reason is another one, which exists in Windows too: - 2) I think that ServeFile is misdesigned: - ServeFile does not raise an exception if it didn't send all the bytes. - Now what happens if I have OnExecute assigned like this - AThread.Connection.ServeFile('...', True); // <-- true to send via kernel - is that it will return 0, but notice that in this case I didn't ask for the - result. Net effect is that the thread will loop in OnExecute even if the - socket is long gone. This doesn't fit Indy semantics at all, exceptions are - always raised if the remote end disconnects. Even if I would do - AThread.Connection.ServeFile('...', False); - then it would raise an exception. - I think this is a big flaw in the design of the ServeFile function. - Maybe GServeFile should only return the bytes sent, but then - TCPConnection.ServeFile() should raise an exception if GServeFile didn't - send all the bytes. - -JM Berg, 2002-09-09 - -function ServeFile(ASocket: TIdStackSocketHandle; AFileName: string): UInt32; -var - LFileHandle: integer; - offset: integer; - stat: _stat; -begin - LFileHandle := open(PAnsiChar(AFileName), O_RDONLY); - try - offset := 0; - fstat(LFileHandle, stat); - Result := sendfile(ASocket, LFileHandle, offset, stat.st_size); -//** if Result = UInt32(-1) then RaiseLastOSError; - finally libc.__close(LFileHandle); end; -end; -*) -function TIdSocketListLinux.Clone: TIdSocketList; -begin - Result := TIdSocketListLinux.Create; - try - Lock; - try - TIdSocketListLinux(Result).SetFDSet(FFDSet); - finally - Unlock; - end; - except - FreeAndNil(Result); - raise; - end; -end; - -initialization - GSocketListClass := TIdSocketListLinux; - -end. - +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.7 10/26/2004 8:20:04 PM JPMugaas + Fixed some oversights with conversion. OOPS!!! + + Rev 1.6 10/26/2004 8:12:32 PM JPMugaas + Now uses TIdStrings and TIdStringList for portability. + + Rev 1.5 12/06/2004 15:17:20 CCostelloe + Restructured to correspond with IdStackWindows, now works. + + Rev 1.4 07/06/2004 21:31:02 CCostelloe + Kylix 3 changes + + Rev 1.3 4/18/04 10:43:22 PM RLebeau + Fixed syntax error + + Rev 1.2 4/18/04 10:29:46 PM RLebeau + Renamed Int64Parts structure to TIdInt64Parts + + Rev 1.1 4/18/04 2:47:28 PM RLebeau + Conversion support for Int64 values + + Removed WSHToNs(), WSNToHs(), WSHToNL(), and WSNToHL() methods, obsolete + + Rev 1.0 2004.02.03 3:14:48 PM czhower + Move and updates + + Rev 1.3 10/19/2003 5:35:14 PM BGooijen + SetSocketOption + + Rev 1.2 2003.10.01 9:11:24 PM czhower + .Net + + Rev 1.1 7/5/2003 07:25:50 PM JPMugaas + Added functions to the Linux stack which use the new TIdIPAddress record type + for IP address parameters. I also fixed a compile bug. + + Rev 1.0 11/13/2002 08:59:24 AM JPMugaas +} + +unit IdStackLinux; + +interface + +{$i IdCompilerDefines.inc} + +uses + Classes, + Libc, + IdStack, + IdStackConsts, + IdGlobal, + IdStackBSDBase; + +type + TIdStackLinux = class(TIdStackBSDBase) + private + procedure WriteChecksumIPv6(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort); + protected + function GetLastError : Integer; + procedure SetLastError(Const AError : Integer); + function HostByName(const AHostName: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; + function ReadHostName: string; override; + function WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; override; + function WSRecv(ASocket: TIdStackSocketHandle; + var ABuffer; const ABufferLength, AFlags: Integer): Integer; override; + function WSSend(ASocket: TIdStackSocketHandle; const ABuffer; const ABufferLength, AFlags: Integer): Integer; override; + function WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; override; + {$IFNDEF VCL_XE3_OR_ABOVE} + procedure WSGetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; + procedure WSSetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; + {$ENDIF} + public + procedure SetBlocking(ASocket: TIdStackSocketHandle; + const ABlocking: Boolean); override; + function WouldBlock(const AResult: Integer): Boolean; override; + function WSTranslateSocketErrorMsg(const AErr: Integer): string; override; + function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; + var VIPVersion: TIdIPVersion): TIdStackSocketHandle; override; + procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + function HostByAddress(const AAddress: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; + function WSGetLastError: Integer; override; + procedure WSSetLastError(const AErr : Integer); override; + function WSGetServByName(const AServiceName: string): TIdPort; override; + function WSGetServByPort(const APortNumber: TIdPort): TStrings; override; + procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; + procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; + procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); override; + function HostToNetwork(AValue: UInt16): UInt16; override; + function NetworkToHost(AValue: UInt16): UInt16; override; + function HostToNetwork(AValue: UInt32): UInt32; override; + function NetworkToHost(AValue: UInt32): UInt32; override; + function HostToNetwork(AValue: TIdUInt64): TIdUInt64; override; + function NetworkToHost(AValue: TIdUInt64): TIdUInt64; override; + function RecvFrom(const ASocket: TIdStackSocketHandle; var VBuffer; + const ALength, AFlags: Integer; var VIP: string; var VPort: TIdPort; + var VIPVersion: TIdIPVersion): Integer; override; + function ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; + APkt: TIdPacketInfo): UInt32; override; + procedure WSSendTo(ASocket: TIdStackSocketHandle; const ABuffer; + const ABufferLength, AFlags: Integer; + const AIP: string; const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + function WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; + const ANonBlocking: Boolean = False): TIdStackSocketHandle; override; + procedure Disconnect(ASocket: TIdStackSocketHandle); override; + {$IFDEF VCL_XE3_OR_ABOVE} + procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; + procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; + {$ENDIF} + function SupportsIPv4: Boolean; overload; override; + function SupportsIPv6: Boolean; overload; override; + function CheckIPVersionSupport(const AIPVersion: TIdIPVersion): boolean; override; + constructor Create; override; + destructor Destroy; override; + //In Windows, this writes a checksum into a buffer. In Linux, it would probably + //simply have the kernal write the checksum with something like this (RFC 2292): +// +// int offset = 2; +// setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)); +// +// Note that this should be called + //IMMEDIATELY before you do a SendTo because the Local IPv6 address might change + + procedure WriteChecksum(s : TIdStackSocketHandle; + var VBuffer : TIdBytes; + const AOffset : Integer; + const AIP : String; + const APort : TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; + var arg: UInt32): Integer; override; + + procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); override; + end; + + TLinger = record + l_onoff: UInt16; + l_linger: UInt16; + end; + TIdLinger = TLinger; + +implementation + +uses + IdResourceStrings, + IdResourceStringsKylixCompat, + IdResourceStringsUnix, + IdException, + SysUtils; + +type + psockaddr_in6 = ^sockaddr_in6; + +const + Id_MSG_NOSIGNAL = MSG_NOSIGNAL; + Id_WSAEPIPE = EPIPE; + +constructor TIdStackLinux.Create; +begin + inherited Create; +end; + +destructor TIdStackLinux.Destroy; +begin + inherited Destroy; +end; + +function TIdStackLinux.GetLastError : Integer; +begin + Result := errno; +end; + +procedure TIdStackLinux.SetLastError(Const AError : Integer); +begin + __errno_location^ := AError; +end; + +procedure TIdStackLinux.WSSetLastError(const AErr : Integer); +begin + SetLastError(AErr); +end; + +function TIdStackLinux.Accept(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): TIdStackSocketHandle; +var + LN: UInt32; + LAddr: sockaddr_in6; +begin + LN := SizeOf(LAddr); + Result := Libc.accept(ASocket, PSockAddr(@LAddr), @LN); + if Result <> SOCKET_ERROR then begin + case LAddr.sin6_family of + Id_PF_INET4: begin + with Psockaddr(@LAddr)^ do + begin + VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); + VPort := Ntohs(sin_port); + end; + VIPVersion := Id_IPV4; + end; + Id_PF_INET6: begin + with LAddr do begin + VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); + VPort := ntohs(sin6_port); + end; + VIPVersion := Id_IPV6; + end; + else begin + Libc.__close(Result); + Result := Id_INVALID_SOCKET; + IPVersionUnsupported; + end; + end; + end else begin + if GetLastError = EBADF then begin + SetLastError(EINTR); + end; + end; +end; + +procedure TIdStackLinux.Bind(ASocket: TIdStackSocketHandle; + const AIP: string; const APort: TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LAddr: sockaddr_in6; + LSize: UInt32; +begin + FillChar(LAddr, SizeOf(LAddr), 0); + case AIPVersion of + Id_IPv4: begin + with Psockaddr(@LAddr)^ do begin + sin_family := Id_PF_INET4; + if AIP <> '' then begin + TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); + end; + sin_port := htons(APort); + end; + LSize := SizeOf(sockaddr); + end; + Id_IPv6: begin + with LAddr do + begin + sin6_family := Id_PF_INET6; + if AIP <> '' then begin + TranslateStringToTInAddr(AIP, sin6_addr, Id_IPv6); + end; + sin6_port := htons(APort); + end; + LSize := SizeOf(sockaddr_in6); + end; + else begin + LSize := 0; // avoid warning + IPVersionUnsupported; + end; + end; + CheckForSocketError(Libc.bind(ASocket, Psockaddr(@LAddr), LSize); +end; + +function TIdStackLinux.WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; +begin + Result := Libc.__close(ASocket); +end; + +procedure TIdStackLinux.Connect(const ASocket: TIdStackSocketHandle; + const AIP: string; const APort: TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LAddr: sockaddr_in6; + LSize: UInt32; +begin + FillChar(LAddr, SizeOf(LAddr), 0); + case AIPVersion of + Id_IPv4: begin + with Psockaddr(@LAddr)^ do begin + sin_family := Id_PF_INET4; + TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); + sin_port := htons(APort); + end; + LSize := SizeOf(sockaddr); + end; + Id_IPv6: begin + with LAddr do begin + sin6_family := Id_PF_INET6; + TranslateStringToTInAddr(AIP, sin6_addr, Id_IPv6); + sin6_port := htons(APort); + end; + LSize := SizeOf(sockaddr_in6); + end; + else begin + LSize := 0; // avoid warning + IPVersionUnsupported; + end; + end; + CheckForSocketError(Libc.connect( + ASocket, + {$IFDEF KYLIX}Psockaddr(@LAddr)^{$ELSE}Psockaddr(@LAddr){$ENDIF}, + LSize)); +end; + +function TIdStackLinux.HostByName(const AHostName: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; +var + Lpa: PAnsiChar; + Lsa: TInAddr; + LHost: PHostEnt; +// ipv6 + LHints: TAddressInfo; + {$IFDEF KYLIX} + LAddrInfo: PAddressInfo; + {$ELSE} + LAddrInfo: PAddrInfo; + {$ENDIF} + LRetVal: Integer; + {$IFDEF STRING_IS_UNICODE} + LAStr: AnsiString; + {$ENDIF} +begin + case AIPVersion of + Id_IPv4: begin + {$IFDEF STRING_IS_UNICODE} + LAStr := AnsiString(AHostName); // explicit convert to Ansi + {$ENDIF} + // TODO: use getaddrinfo() instead for IPv4 as well... + LHost := Libc.gethostbyname( + PAnsiChar({$IFDEF STRING_IS_UNICODE}LAStr{$ELSE}AHostName{$ENDIF})); + if LHost <> nil then begin + // TODO: gethostbyname() might return other things besides IPv4 + // addresses, so we should be validating the address type before + // attempting the conversion... + Lpa := LHost^.h_addr_list^; + Lsa.S_un_b.s_b1 := Ord(Lpa[0]); + Lsa.S_un_b.s_b2 := Ord(Lpa[1]); + Lsa.S_un_b.s_b3 := Ord(Lpa[2]); + Lsa.S_un_b.s_b4 := Ord(Lpa[3]); + Result := TranslateTInAddrToString(Lsa, Id_IPv4); + end else begin + //RaiseSocketError(h_errno); + RaiseLastSocketError; + end; + end; + Id_IPv6: begin + FillChar(LHints, SizeOf(LHints), 0); + LHints.ai_family := IdIPFamily[AIPVersion]; + LHints.ai_socktype := Integer(SOCK_STREAM); + LAddrInfo := nil; + + {$IFDEF STRING_IS_UNICODE} + LAStr := AnsiString(AHostName); // explicit convert to Ansi + {$ENDIF} + LRetVal := getaddrinfo( + PAnsiChar({$IFDEF STRING_IS_UNICODE}LAStr{$ELSE}AHostName{$ENDIF}), + nil, @LHints, {$IFDEF KYLIX}LAddrInfo{$ELSE}@LAddrInfo{$ENDIF}); + if LRetVal <> 0 then begin + if LRetVal = EAI_SYSTEM then begin + IndyRaiseLastError; + end else begin + raise EIdResolveError.CreateFmt(RSResolveError, [AHostName, gai_strerror(LRetVal), LRetVal]); + end; + end; + try + Result := TranslateTInAddrToString(LAddrInfo^.ai_addr^.sin_zero, Id_IPv6); + finally + freeaddrinfo(LAddrInfo); + end; + end; + else + Result := ''; // avoid warning + IPVersionUnsupported; + end; +end; + +function TIdStackLinux.ReadHostName: string; +var + LStr: array[0..250] of AnsiChar; +begin + if Libc.gethostname(LStr, 250) = 0 then begin + LStr[250] := #0; + Result := String(LStr); + end else begin + Result := ''; + end; +end; + +procedure TIdStackLinux.Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); +begin + CheckForSocketError(Libc.listen(ASocket, ABacklog)); +end; + +function TIdStackLinux.WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; + const ABufferLength, AFlags: Integer): Integer; +begin + //IdStackWindows is just: Result := Recv(ASocket, ABuffer, ABufferLength, AFlags); + Result := Recv(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); +end; + +function TIdStackLinux.RecvFrom(const ASocket: TIdStackSocketHandle; + var VBuffer; const ALength, AFlags: Integer; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; +var + LiSize: UInt32; + LAddr: sockaddr_in6; +begin + LiSize := SizeOf(sockaddr_in6); + Result := Libc.recvfrom(ASocket, VBuffer, ALength, AFlags or Id_MSG_NOSIGNAL, PSockAddr(@LAddr), @LiSize); + if Result >= 0 then + begin + case LAddr.sin6_family of + Id_PF_INET4: begin + with Psockaddr(@LAddr)^ do begin + VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); + VPort := Ntohs(sin_port); + end; + VIPVersion := Id_IPV4; + end; + Id_PF_INET6: begin + with LAddr do begin + VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); + VPort := ntohs(sin6_port); + end; + VIPVersion := Id_IPV6; + end; + else begin + Result := 0; + IPVersionUnsupported; + end; + end; + end; +end; + +function TIdStackLinux.ReceiveMsg(ASocket: TIdStackSocketHandle; + var VBuffer: TIdBytes; APkt: TIdPacketInfo): UInt32; +{var + LIP : String; + LPort : TIdPort; + LSize: UInt32; + LAddr: SockAddr_In6; + LMsg : msghdr; + LMsgBuf : BUF; + LControl : TIdBytes; + LCurCmsg : CMSGHDR; //for iterating through the control buffer + LByte : PByte; + LDummy, LDummy2 : UInt32; + +begin + //we call the macro twice because we specified two possible structures. + //Id_IPV6_HOPLIMIT and Id_IPV6_PKTINFO + LSize := CMSG_SPACE(SizeOf(Byte)) + CMSG_SPACE(SizeOf(in6_pktinfo)); + SetLength(LControl, LSize); + + LMsgBuf.len := Length(VBuffer); // Length(VMsgData); + LMsgBuf.buf := @VBuffer[0]; // @VMsgData[0]; + + FillChar(LMsg,SizeOf(LMsg),0); + + LMsg.lpBuffers := @LMsgBuf; + LMsg.dwBufferCount := 1; + + LMsg.Control.Len := LSize; + LMsg.Control.buf := @LControl[0]; + + LMsg.name := PSOCKADDR(@LAddr); + LMsg.namelen := SizeOf(LAddr); + + CheckForSocketError(RecvMsg(ASocket, @LMsg, Result, @LDummy, LPwsaoverlapped_COMPLETION_ROUTINE(@LDummy2))); + APkt.Reset; + + case LAddr.sin6_family of + Id_PF_INET4: begin + with Psockaddr(@LAddr)^ do + begin + APkt.SourceIP := TranslateTInAddrToString(sin_addr, Id_IPv4); + APkt.SourcePort := ntohs(sin_port); + end; + APkt.SourceIPVersion := Id_IPv4; + end; + Id_PF_INET6: begin + with LAddr do + begin + APkt.SourceIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); + APkt.SourcePort := ntohs(sin6_port); + end; + APkt.SourceIPVersion := Id_IPv6; + end; + else begin + Result := 0; // avoid warning + IPVersionUnsupported; + end; + end; + + LCurCmsg := nil; + repeat + LCurCmsg := CMSG_NXTHDR(@LMsg,LCurCmsg); + if LCurCmsg=nil then + begin + break; + end; + case LCurCmsg^.cmsg_type of + IP_PKTINFO : //done this way because IPV6_PKTINF and IP_PKTINFO + //are both 19 + begin + case LAddr.sin6_family of + Id_PF_INET4: begin + with Pin_pktinfo(WSA_CMSG_DATA(LCurCmsg))^ do + begin + APkt.DestIP := GWindowsStack.TranslateTInAddrToString(ipi_addr, Id_IPv4); + APkt.DestIF := ipi_ifindex; + end; + APkt.DestIPVersion := Id_IPv4; + end; + Id_PF_INET6: begin + with Pin6_pktinfo(WSA_CMSG_DATA(LCurCmsg))^ do + begin + APkt.DestIP := GWindowsStack.TranslateTInAddrToString(ipi6_addr, Id_IPv6); + APkt.DestIF := ipi6_ifindex; + end; + APkt.DestIPVersion := Id_IPv6; + end; + end; + end; + Id_IPV6_HOPLIMIT : + begin + LByte := PByte(WSA_CMSG_DATA(LCurCmsg)); + APkt.TTL := LByte^; + end; + end; + until False; } +begin + APkt.Reset; + Result := 0; // avoid warning +end; + +function TIdStackLinux.WSSend(ASocket: TIdStackSocketHandle; + const ABuffer; const ABufferLength, AFlags: Integer): Integer; +begin + //CC: Should Id_MSG_NOSIGNAL be included? + // Result := Send(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); + Result := CheckForSocketError(Libc.send(ASocket, ABuffer, ABufferLength, AFlags)); +end; + +procedure TIdStackLinux.WSSendTo(ASocket: TIdStackSocketHandle; + const ABuffer; const ABufferLength, AFlags: Integer; const AIP: string; + const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LAddr: sockaddr_in6; + LiSize: Integer; +begin + FillChar(LAddr, SizeOf(LAddr), 0); + case AIPVersion of + Id_IPv4: begin + with Psockaddr(@LAddr)^ do begin + sin_family := Id_PF_INET4; + TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); + sin_port := htons(APort); + end; + LiSize := SizeOf(sockaddr); + end; + Id_IPv6: begin + with LAddr do begin + sin6_family := Id_PF_INET6; + TranslateStringToTInAddr(AIP, sin6_addr, Id_IPv6); + sin6_port := htons(APort); + end; + LiSize := SizeOf(sockaddr_in6); + end; + else begin + LiSize := 0; // avoid warning + IPVersionUnsupported; + end; + end; + LiSize := Libc.sendto( + ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL, + {$IFDEF KYLIX}Psockaddr(@LAddr)^{$ELSE}Psockaddr(@LAddr){$ENDIF}, + LiSize); + end; + if LiSize = Id_SOCKET_ERROR then begin + // TODO: move this into RaiseLastSocketError directly + if WSGetLastError() = Id_WSAEMSGSIZE then begin + raise EIdPackageSizeTooBig.Create(RSPackageSizeTooBig); + end else begin + RaiseLastSocketError; + end; + end + else if LiSize <> ABufferLength then begin + raise EIdNotAllBytesSent.Create(RSNotAllBytesSent); + end; +end; + +procedure TIdStackLinux.{$IFDEF VCL_XE3_OR_ABOVE}GetSocketOption{$ELSE}WSGetSocketOption{$ENDIF} + (ASocket: TIdStackSocketHandle; ALevel: TIdSocketProtocol; AOptName: TIdSocketOption; + var AOptVal; var AOptLen: Integer); +var + LLen: UInt32; +begin + LLen := AOptLen; + CheckForSocketError(Libc.getsockopt(ASocket, ALevel, AOptName, PAnsiChar(@AOptVal), LLen)); + AOptLen := LLen; +end; + +procedure TIdStackLinux.{$IFDEF VCL_XE3_OR_ABOVE}SetSocketOption{$ELSE}WSSetSocketOption{$ENDIF} + (ASocket: TIdStackSocketHandle; ALevel: TIdSocketProtocol; AOptName: TIdSocketOption; + const AOptVal; const AOptLen: Integer); +begin + CheckForSocketError(Libc.setsockopt(ASocket, ALevel, AOptName, PAnsiChar(@AOptVal), AOptLen)); +end; + +function TIdStackLinux.WSGetLastError: Integer; +begin + //IdStackWindows just uses result := WSAGetLastError; + Result := GetLastError; //System.GetLastOSError; - FPC doesn't define it in System + if Result = Id_WSAEPIPE then begin + Result := Id_WSAECONNRESET; + end; +end; + +function TIdStackLinux.WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; + const ANonBlocking: Boolean = False): TIdStackSocketHandle; +begin + Result := Libc.socket(AFamily, AStruct or iif(ANonBlocking, SOCK_NONBLOCK, 0), AProtocol); +end; + +function TIdStackLinux.WSGetServByName(const AServiceName: string): TIdPort; +var + Lps: PServEnt; + {$IFDEF STRING_IS_UNICODE} + LAStr: AnsiString; + {$ENDIF} +begin + {$IFDEF STRING_IS_UNICODE} + LAStr := AnsiString(AServiceName); // explicit convert to Ansi + {$ENDIF} + Lps := Libc.getservbyname( + PAnsiChar({$IFDEF STRING_IS_UNICODE}LAStr{$ELSE}AServiceName{$ENDIF}, + nil); + if Lps <> nil then begin + Result := ntohs(Lps^.s_port); + end else begin + try + Result := IndyStrToInt(AServiceName); + except + on EConvertError do begin + IndyRaiseOuterException(EIdInvalidServiceName.CreateFmt(RSInvalidServiceName, [AServiceName])); + end; + end; + end; +end; + +function TIdStackLinux.WSGetServByPort(const APortNumber: TIdPort): TStrings; +type + PPAnsiCharArray = ^TPAnsiCharArray; + TPAnsiCharArray = packed array[0..(Maxint div SizeOf(PAnsiChar))-1] of PAnsiChar; +var + Lps: PServEnt; + Li: Integer; + Lp: PPAnsiCharArray; +begin + Result := TStringList.Create; + Lp := nil; + try + Lps := Libc.getservbyport(htons(APortNumber), nil); + if Lps <> nil then begin + Result.Add(Lps^.s_name); + Li := 0; + Lp := Pointer(Lps^.s_aliases); + while Lp[Li] <> nil do begin + Result.Add(Lp[Li]); + Inc(Li); + end; + end; + except + FreeAndNil(Result); + raise; + end; +end; + +function TIdStackLinux.HostToNetwork(AValue: UInt16): UInt16; +begin + Result := htons(AValue); +end; + +function TIdStackLinux.NetworkToHost(AValue: UInt16): UInt16; +begin + Result := ntohs(AValue); +end; + +function TIdStackLinux.HostToNetwork(AValue: UInt32): UInt32; +begin + Result := htonl(AValue); +end; + +function TIdStackLinux.NetworkToHost(AValue: UInt32): UInt32; +begin + Result := ntohl(AValue); +end; + +{ RP - I'm not sure what endian Linux natively uses, thus the +check to see if the bytes need swapping or not ... } +function TIdStackLinux.HostToNetwork(AValue: TIdUInt64): TIdUInt64; +var + LParts: TIdUInt64Parts; + L: UInt32; +begin + if (htonl(1) <> 1) then begin + LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + L := htonl(LParts.HighPart); + LParts.HighPart := htonl(LParts.LowPart); + LParts.LowPart := L; + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; + end else begin + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + end; +end; + +function TIdStackLinux.NetworkToHost(AValue: TIdUInt64): TIdUInt64; +var + LParts: TIdUInt64Parts; + L: UInt32; +begin + if (ntohl(1) <> 1) then begin + LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + L := ntohl(LParts.HighPart); + LParts.HighPart := ntohl(LParts.LowPart); + LParts.LowPart := L; + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; + end else begin + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + end; +end; + +{$IFDEF HAS_getifaddrs} +type + TIdStackLocalAddressAccess = class(TIdStackLocalAddress) + end; +{$ENDIF} + +procedure TIdStackLinux.GetLocalAddressList(AAddresses: TIdStackLocalAddressList); +{$IFNDEF HAS_getifaddrs} +type + TaPInAddr = array[0..250] of PInAddr; + PaPInAddr = ^TaPInAddr; + TaPIn6Addr = array[0..250] of PIn6Addr; + PaPIn6Addr = ^TaPIn6Addr; +{$ENDIF} +var + {$IFDEF HAS_getifaddrs} + LAddrList, LAddrInfo: pifaddrs; + LSubNetStr: string; + LAddress: TIdStackLocalAddress; + LName: string; + {$ELSE} + Li: Integer; + LAHost: PHostEnt; + LPAdrPtr: PaPInAddr; + LHostName: AnsiString; + {$ENDIF} +begin + // TODO: Using gethostname() and gethostbyname() like this may not always + // return just the machine's IP addresses. Technically speaking, they will + // return the local hostname, and then return the address(es) to which that + // hostname resolves. It is possible for a machine to (a) be configured such + // that its name does not resolve to an IP, or (b) be configured such that + // its name resolves to multiple IPs, only one of which belongs to the local + // machine. For better results, we should use getifaddrs() on platforms that + // support it... + + {$IFDEF HAS_getifaddrs} + + if getifaddrs(@LAddrList) = 0 then // TODO: raise an exception if it fails + try + AAddresses.BeginUpdate; + try + LAddrInfo := LAddrList; + repeat + if (LAddrInfo^.ifa_addr <> nil) and ((LAddrInfo^.ifa_flags and IFF_LOOPBACK) = 0) then + begin + LAddress := nil; + case LAddrInfo^.ifa_addr^.sa_family of + Id_PF_INET4: begin + if LAddrInfo^.ifa_netmask <> nil then begin + LSubNetStr := TranslateTInAddrToString(PSockAddr_In(LAddrInfo^.ifa_netmask)^.sin_addr, Id_IPv4); + end else begin + LSubNetStr := ''; + end; + LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, TranslateTInAddrToString(PSockAddr_In(LAddrInfo^.ifa_addr)^.sin_addr, Id_IPv4), LSubNetStr); + end; + Id_PF_INET6: begin + LAddress := TIdStackLocalAddressIPv6.Create(AAddresses, TranslateTInAddrToString(PSockAddr_In6(LAddrInfo^.ifa_addr)^.sin6_addr, Id_IPv6)); + end; + end; + if LAddress <> nil then begin + LName := LAddrInfo^.ifa_name; + {$I IdObjectChecksOff.inc} + TIdStackLocalAddressAccess(LAddress).FDescription := LName; + TIdStackLocalAddressAccess(LAddress).FFriendlyName := LName; + TIdStackLocalAddressAccess(LAddress).FInterfaceName := LName; + {$IFDEF HAS_if_nametoindex} + TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := if_nametoindex(LAddrInfo^.ifa_name); + {$ENDIF} + {$I IdObjectChecksOn.inc} + end; + end; + LAddrInfo := LAddrInfo^.ifa_next; + until LAddrInfo = nil; + finally + AAddresses.EndUpdate; + end; + finally + freeifaddrs(LAddrList); + end; + + {$ELSE} + + // this won't get IPv6 addresses as I didn't find a way + // to enumerate IPv6 addresses on a linux machine + + LHostName := HostName; + LAHost := Libc.gethostbyname(PAnsiChar(LHostName)); + if LAHost = nil then begin + RaiseLastSocketError; + end; + + // gethostbyname() might return other things besides IPv4 addresses, so we + // need to validate the address type before attempting the conversion... + + case LAHost^.h_addrtype of + Id_PF_INET4: begin + LPAdrPtr := PAPInAddr(LAHost^.h_addr_list); + Li := 0; + if LPAdrPtr^[Li] <> nil then begin + AAddresses.BeginUpdate; + try + repeat + TIdStackLocalAddressIPv4.Create(AAddresses, TranslateTInAddrToString(LPAdrPtr^[Li]^, Id_IPv4), ''); // TODO: SubNet + Inc(Li); + until LPAdrPtr^[Li] = nil; + finally + AAddresses.EndUpdate; + end; + end; + end; + Id_PF_INET6: begin + LPAdr6Ptr := PAPIn6Addr(LAHost^.h_addr_list); + Li := 0; + if LPAdr6Ptr^[Li] <> nil then begin + AAddresses.BeginUpdate; + try + repeat + TIdStackLocalAddressIPv6.Create(AAddresses, TranslateTInAddrToString(LPAdr6Ptr^[Li]^, Id_IPv6)); + Inc(Li); + until LPAdr6Ptr^[Li] = nil; + finally + AAddresses.EndUpdate; + end; + end; + end; + end; + + {$ENDIF} +end; + +function TIdStackLinux.HostByAddress(const AAddress: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; +var + LAddr: sockaddr_in6; + LSize: UInt32; + LHostName : array[0..NI_MAXHOST] of TIdAnsiChar; + {$IFDEF USE_MARSHALLED_PTRS} + LHostNamePtr: TPtrWrapper; + {$ENDIF} + LRet : Integer; + {$IFDEF KYLIX} + LHints: TAddressInfo; + LAddrInfo: PAddressInfo; + {$ELSE} + LHints: AddrInfo; //The T is no omission - that's what I found in the header + LAddrInfo: PAddrInfo; + {$ENDIF} +begin + FillChar(LAddr, SizeOf(LAddr), 0); + case AIPVersion of + Id_IPv4: begin + with Psockaddr(@LAddr)^ do begin + sin_family := Id_PF_INET4; + TranslateStringToTInAddr(AAddress, sin_addr, Id_IPv4); + end; + LSize := SizeOf(sockaddr); + end; + Id_IPv6: begin + with LAddr do begin + sin6_family := Id_PF_INET6; + TranslateStringToTInAddr(AAddress, sin6_addr, Id_IPv6); + end; + LSize := SizeOf(sockaddr_in6); + end; + else begin + LSize := 0; // avoid warning + IPVersionUnsupported; + end; + end; + FillChar(LHostName[0],Length(LHostName),0); + {$IFDEF USE_MARSHALLED_PTRS} + LHostNamePtr := TPtrWrapper.Create(@LHostName[0]); + {$ENDIF} + LRet := getnameinfo(Psockaddr(@LAddr)^, LSize, + {$IFDEF USE_MARSHALLED_PTRS} + LHostNamePtr.ToPointer + {$ELSE} + LHostName + {$ENDIF}, + NI_MAXHOST,nil,0,NI_NAMEREQD ); + if LRet <> 0 then begin + if LRet = EAI_SYSTEM then begin + RaiseLastOSError; + end else begin + raise EIdReverseResolveError.CreateFmt(RSReverseResolveError, [AAddress, gai_strerror(LRet), LRet]); + end; + end; +{ +IMPORTANT!!! + +getnameinfo can return either results from a numeric to text conversion or +results from a DNS reverse lookup. Someone could make a malicous PTR record +such as + + 1.0.0.127.in-addr.arpa. IN PTR 10.1.1.1 + +and trick a caller into beleiving the socket address is 10.1.1.1 instead of +127.0.0.1. If there is a numeric host in LAddr, than this is the case and +we disregard the result and raise an exception. +} + FillChar(LHints,SizeOf(LHints),0); + LHints.ai_socktype := SOCK_DGRAM; //*dummy*/ + LHints.ai_flags := AI_NUMERICHOST; + if getaddrinfo( + {$IFDEF USE_MARSHALLED_PTRS} + LHostNamePtr.ToPointer + {$ELSE} + LHostName + {$ENDIF}, + '0', LHints, LAddrInfo) = 0 then + begin + freeaddrinfo(LAddrInfo^); + Result := ''; + raise EIdMaliciousPtrRecord.Create(RSMaliciousPtrRecord); + end; + + {$IFDEF USE_MARSHALLED_PTRS} + Result := TMarshal.ReadStringAsAnsi(LHostNamePtr); + {$ELSE} + Result := String(LHostName); + {$ENDIF} +(* JMB: I left this in here just in case someone + complains, but the other code works on all + linux systems for all addresses and is thread-safe + +variables for it: + Host: PHostEnt; + LAddr: u_long; + + Id_IPv4: begin + // GetHostByAddr is thread-safe in Linux. + // It might not be safe in Solaris or BSD Unix + LAddr := inet_addr(PAnsiChar(AAddress)); + Host := GetHostByAddr(@LAddr,SizeOf(LAddr),AF_INET); + if (Host <> nil) then begin + Result := Host^.h_name; + end else begin + RaiseSocketError(h_errno); + end; + end; +*) +end; + +function TIdStackLinux.WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; +begin + Result := Libc.shutdown(ASocket, AHow); +end; + +procedure TIdStackLinux.Disconnect(ASocket: TIdStackSocketHandle); +begin + // Windows uses Id_SD_Send, Linux should use Id_SD_Both + WSShutdown(ASocket, Id_SD_Both); + // SO_LINGER is false - socket may take a little while to actually close after this + WSCloseSocket(ASocket); +end; + +procedure TIdStackLinux.GetPeerName(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); +var + LiSize: UInt32; + LAddr: sockaddr_in6; +begin + LiSize := SizeOf(LAddr); + CheckForSocketError(Libc.getpeername(ASocket, Psockaddr(@LAddr)^, LiSize)); + case LAddr.sin6_family of + Id_PF_INET4: begin + with Psockaddr(@LAddr6)^ do begin + VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); + VPort := ntohs(sin_port); + end; + VIPVersion := Id_IPV4; + end; + Id_PF_INET6: begin + with LAddr do begin + VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); + VPort := Ntohs(sin6_port); + end; + VIPVersion := Id_IPV6; + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +procedure TIdStackLinux.GetSocketName(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); +var + LiSize: UInt32; + LAddr: sockaddr_in6; +begin + LiSize := SizeOf(LAddr); + CheckForSocketError(Libc.getsockname(ASocket, Psockaddr(@LAddr)^, LiSize)); + case LAddr.sin6_family of + Id_PF_INET4: begin + with Psockaddr(@LAddr6)^ do begin + VIP := TranslateTInAddrToString(sin_addr, Id_IPv4); + VPort := ntohs(sin_port); + end; + VIPVersion := Id_IPV4; + end; + Id_PF_INET6: begin + with LAddr do begin + VIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); + VPort := ntohs(sin6_port); + end; + VIPVersion := Id_IPV6; + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +function TIdStackLinux.WouldBlock(const AResult: Integer): Boolean; +begin + // using if-else instead of in..range because EAGAIN and EWOULDBLOCK + // have often the same value and so FPC might report a range error + Result := (AResult = Id_WSAEAGAIN) or + (AResult = Id_WSAEWOULDBLOCK) or + (AResult = Id_WSAEINPROGRESS); +end; + +function TIdStackLinux.SupportsIPv4: Boolean; +begin + //In Windows, this does something else. It checks the LSP's installed. + Result := CheckIPVersionSupport(Id_IPv4); +end; + +function TIdStackLinux.SupportsIPv6: Boolean; +begin + //In Windows, this does something else. It checks the LSP's installed. + Result := CheckIPVersionSupport(Id_IPv6); +end; + +function TIdStackLinux.CheckIPVersionSupport(const AIPVersion: TIdIPVersion): Boolean; +var + LTmpSocket: TIdStackSocketHandle; +begin + // TODO: an alternative would be to check for the existance of the '/proc/net/if_inet6' kernel pseudo-file + LTmpSocket := WSSocket(IdIPFamily[AIPVersion], Id_SOCK_STREAM, Id_IPPROTO_IP ); + Result := LTmpSocket <> Id_INVALID_SOCKET; + if Result then begin + WSCloseSocket(LTmpSocket); + end; +end; + +procedure TIdStackLinux.WriteChecksum(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort; const AIPVersion: TIdIPVersion); +begin + case AIPVersion of + Id_IPv4 : CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(VBuffer)), VBuffer, AOffset); + Id_IPv6 : WriteChecksumIPv6(s, VBuffer, AOffset, AIP, APort); + else + IPVersionUnsupported; + end; +end; + +procedure TIdStackLinux.WriteChecksumIPv6(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort); +begin +//we simply request that the kernal write the checksum when the data +//is sent. All of the parameters required are because Windows is bonked +//because it doesn't have the IPV6CHECKSUM socket option meaning we have +//to querry the network interface in TIdStackWindows -- yuck!! + SetSocketOption(s, IPPROTO_IPV6, IPV6_CHECKSUM, AOffset); +end; + +function TIdStackLinux.IOControl(const s: TIdStackSocketHandle; + const cmd: UInt32; var arg: UInt32): Integer; +begin + Result := ioctl(s, cmd, @arg); +end; + +{ TIdSocketListLinux } + +type + // TODO: rewrite this to use poll() instead of select(), similar to TIdSocketListVCLPosix + TIdSocketListLinux = class (TIdSocketList) + protected + FCount: integer; + FFDSet: TFDSet; + // + class function FDSelect(AReadSet: PFDSet; AWriteSet: PFDSet; AExceptSet: PFDSet; + const ATimeout: Integer = IdTimeoutInfinite): integer; + function GetItem(AIndex: Integer): TIdStackSocketHandle; override; + public + procedure Add(AHandle: TIdStackSocketHandle); override; + procedure Remove(AHandle: TIdStackSocketHandle); override; + function Count: Integer; override; + procedure Clear; override; + function Clone: TIdSocketList; override; + function ContainsSocket(AHandle: TIdStackSocketHandle): boolean; override; + procedure GetFDSet(var VSet: TFDSet); + procedure SetFDSet(var VSet: TFDSet); + class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; + AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; + override; + function SelectReadList(var VSocketList: TIdSocketList; + const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + End;//TIdSocketList + +procedure TIdSocketListLinux.Add(AHandle: TIdStackSocketHandle); +begin + Lock; + try + if not FD_ISSET(AHandle, FFDSet) then begin + if AHandle >= __FD_SETSIZE{MaxLongint} then begin + raise EIdStackSetSizeExceeded.Create(RSSetSizeExceeded); + end; + FD_SET(AHandle, FFDSet); + Inc(FCount); + end; + finally + Unlock; + end; +end;// + +procedure TIdSocketListLinux.Clear; +begin + Lock; + try + FD_ZERO(FFDSet); + FCount := 0; + finally + Unlock; + end; +end; + +function TIdSocketListLinux.ContainsSocket( + AHandle: TIdStackSocketHandle): boolean; +begin + Lock; + try + Result := FD_ISSET(AHandle, FFDSet); + finally + Unlock; + end; +end; + +function TIdSocketListLinux.Count: Integer; +begin + Lock; + try + Result := FCount; + finally + Unlock; + end; +end;// + +class function TIdSocketListLinux.FDSelect(AReadSet, AWriteSet, + AExceptSet: PFDSet; const ATimeout: Integer): integer; +var + LTime: TTimeVal; + LTimePtr: PTimeVal; +begin + if ATimeout = IdTimeoutInfinite then begin + LTimePtr := nil; + end else begin + LTime.tv_sec := ATimeout div 1000; + LTime.tv_usec := (ATimeout mod 1000) * 1000; + LTimePtr := @LTime; + end; + // TODO: calculate the actual nfds value based on the Sets provided... + // TODO: use poll() instead of select() to remove limit on how many sockets can be queried + Result := Libc.select({__FD_SETSIZE}MaxLongint, AReadSet, AWriteSet, AExceptSet, LTimePtr); +end; + +procedure TIdSocketListLinux.GetFDSet(var VSet: TFDSet); +begin + Lock; + try + VSet := FFDSet; + finally + Unlock; + end; +end; + +function TIdSocketListLinux.GetItem(AIndex: Integer): TIdStackSocketHandle; +var + LIndex, i: Integer; +begin + Result := 0; + Lock; + try + LIndex := 0; + //? use FMaxHandle div x + for i:= 0 to __FD_SETSIZE - 1 do begin + if FD_ISSET(i, FFDSet) then begin + if LIndex = AIndex then begin + Result := i; + Break; + end; + Inc(LIndex); + end; + end; + finally + Unlock; + end; +end;// + +procedure TIdSocketListLinux.Remove(AHandle: TIdStackSocketHandle); +begin + Lock; + try + if FD_ISSET(AHandle, FFDSet) then begin + Dec(FCount); + FD_CLR(AHandle, FFDSet); + end; + finally + Unlock; + end; +end;// + + +function TIdStackLinux.WSTranslateSocketErrorMsg(const AErr: Integer): string; +begin + //we override this function for the herr constants that + //are returned by the DNS functions + case AErr of + Libc.HOST_NOT_FOUND: Result := RSStackHOST_NOT_FOUND; + Libc.TRY_AGAIN: Result := RSStackTRY_AGAIN; + Libc.NO_RECOVERY: Result := RSStackNO_RECOVERY; + Libc.NO_DATA: Result := RSStackNO_DATA; + else + Result := inherited WSTranslateSocketErrorMsg(AErr); + end; +end; + +procedure TIdSocketListLinux.SetFDSet(var VSet: TFDSet); +begin + Lock; + try + FFDSet := VSet; + finally + Unlock; + end; +end; + +class function TIdSocketListLinux.Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; + AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; +var + LReadSet: TFDSet; + LWriteSet: TFDSet; + LExceptSet: TFDSet; + LPReadSet: PFDSet; + LPWriteSet: PFDSet; + LPExceptSet: PFDSet; + + procedure ReadSet(AList: TIdSocketList; var ASet: TFDSet; var APSet: PFDSet); + begin + if AList <> nil then begin + TIdSocketListLinux(AList).GetFDSet(ASet); + APSet := @ASet; + end else begin + APSet := nil; + end; + end; + +begin + ReadSet(AReadList, LReadSet, LPReadSet); + ReadSet(AWriteList, LWriteSet, LPWriteSet); + ReadSet(AExceptList, LExceptSet, LPExceptSet); + // + Result := FDSelect(LPReadSet, LPWriteSet, LPExceptSet, ATimeout) >0; + // + if AReadList <> nil then begin + TIdSocketListLinux(AReadList).SetFDSet(LReadSet); + end; + if AWriteList <> nil then begin + TIdSocketListLinux(AWriteList).SetFDSet(LWriteSet); + end; + if AExceptList <> nil then begin + TIdSocketListLinux(AExceptList).SetFDSet(LExceptSet); + end; +end; + +function TIdSocketListLinux.SelectRead(const ATimeout: Integer): Boolean; +var + LSet: TFDSet; +begin + Lock; + try + LSet := FFDSet; + // select() updates this structure on return, + // so we need to copy it each time we need it + finally + Unlock; + end; + Result := FDSelect(@LSet, nil, nil, ATimeout) > 0; +end; + +function TIdSocketListLinux.SelectReadList(var VSocketList: TIdSocketList; + const ATimeout: Integer = IdTimeoutInfinite): Boolean; +var + LSet: TFDSet; +begin + Lock; + try + LSet := FFDSet; + // select() updates this structure on return, + // so we need to copy it each time we need it + finally + Unlock; + end; + Result := FDSelect(@LSet, nil, nil, ATimeout) > 0; + if Result then begin + if VSocketList = nil then begin + VSocketList := TIdSocketList.CreateSocketList; + end; + TIdSocketListLinux(VSocketList).SetFDSet(LSet); + end; +end; + +procedure TIdStackLinux.SetBlocking(ASocket: TIdStackSocketHandle; + const ABlocking: Boolean); +var + LFlags: Integer; + //LValue: UInt32; +begin + LFlags := CheckForSocketError(Libc.fcntl(ASocket, F_GETFL, 0)); + if ABlocking then begin + LFlags := LFlags and not O_NONBLOCK; + end else begin + LFlags := LFlags or O_NONBLOCK; + end; + CheckForSocketError(Libc.fcntl(ASocket, F_SETFL, LFlags)); + { + LValue := UInt32(not ABlocking); + CheckForSocketError(Libc.ioctl(ASocket, FIONBIO, @LValue)); + } +end; + +(* +Why did I remove this again? + + 1) it sends SIGPIPE even if the socket is created with the no-sigpipe bit set + that could be solved by blocking sigpipe within this thread + This is probably a bug in the Linux kernel, but we could work around it + by blocking that signal for the time of sending the file (just get the + sigprocmask, see if pipe bit is set, if not set it and remove again after + sending the file) + +But the more serious reason is another one, which exists in Windows too: + 2) I think that ServeFile is misdesigned: + ServeFile does not raise an exception if it didn't send all the bytes. + Now what happens if I have OnExecute assigned like this + AThread.Connection.ServeFile('...', True); // <-- true to send via kernel + is that it will return 0, but notice that in this case I didn't ask for the + result. Net effect is that the thread will loop in OnExecute even if the + socket is long gone. This doesn't fit Indy semantics at all, exceptions are + always raised if the remote end disconnects. Even if I would do + AThread.Connection.ServeFile('...', False); + then it would raise an exception. + I think this is a big flaw in the design of the ServeFile function. + Maybe GServeFile should only return the bytes sent, but then + TCPConnection.ServeFile() should raise an exception if GServeFile didn't + send all the bytes. + +JM Berg, 2002-09-09 + +function ServeFile(ASocket: TIdStackSocketHandle; AFileName: string): UInt32; +var + LFileHandle: integer; + offset: integer; + stat: _stat; +begin + LFileHandle := open(PAnsiChar(AFileName), O_RDONLY); + try + offset := 0; + fstat(LFileHandle, stat); + Result := sendfile(ASocket, LFileHandle, offset, stat.st_size); +//** if Result = UInt32(-1) then RaiseLastOSError; + finally libc.__close(LFileHandle); end; +end; +*) +function TIdSocketListLinux.Clone: TIdSocketList; +begin + Result := TIdSocketListLinux.Create; + try + Lock; + try + TIdSocketListLinux(Result).SetFDSet(FFDSet); + finally + Unlock; + end; + except + FreeAndNil(Result); + raise; + end; +end; + +initialization + GSocketListClass := TIdSocketListLinux; + +end. + diff --git a/Lib/System/IdStackUnix.pas b/Lib/System/IdStackUnix.pas index 4f27b94e8..90d1d0a3f 100644 --- a/Lib/System/IdStackUnix.pas +++ b/Lib/System/IdStackUnix.pas @@ -1,1380 +1,1380 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. - - - $Log$ - - - Rev 1.7 10/26/2004 8:20:04 PM JPMugaas - Fixed some oversights with conversion. OOPS!!! - - - Rev 1.6 10/26/2004 8:12:32 PM JPMugaas - Now uses TIdStrings and TIdStringList for portability. - - - Rev 1.5 12/06/2004 15:17:20 CCostelloe - Restructured to correspond with IdStackWindows, now works. - - - Rev 1.4 07/06/2004 21:31:02 CCostelloe - Kylix 3 changes - - - Rev 1.3 4/18/04 10:43:22 PM RLebeau - Fixed syntax error - - - Rev 1.2 4/18/04 10:29:46 PM RLebeau - Renamed Int64Parts structure to TIdInt64Parts - - - Rev 1.1 4/18/04 2:47:28 PM RLebeau - Conversion support for Int64 values - - Removed WSHToNs(), WSNToHs(), WSHToNL(), and WSNToHL() methods, obsolete - - - Rev 1.0 2004.02.03 3:14:48 PM czhower - Move and updates - - - Rev 1.3 10/19/2003 5:35:14 PM BGooijen - SetSocketOption - - - Rev 1.2 2003.10.01 9:11:24 PM czhower - .Net - - - Rev 1.1 7/5/2003 07:25:50 PM JPMugaas - Added functions to the Linux stack which use the new TIdIPAddress record type - for IP address parameters. I also fixed a compile bug. - - - Rev 1.0 11/13/2002 08:59:24 AM JPMugaas -} -unit IdStackUnix; -interface - -{$i IdCompilerDefines.inc} - -{$IFNDEF FPC} - {$Message Fatal 'IdStackUnix is only for FreePascal.'} -{$ENDIF} -uses - Classes, - sockets, - baseunix, - IdStack, - IdStackConsts, - IdGlobal, - IdStackBSDBase; - -{$IFDEF FREEBSD} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} -{$IFDEF DARWIN} - {$DEFINE SOCK_HAS_SINLEN} -{$ENDIF} - -type - {$IFNDEF NO_REDECLARE} - Psockaddr = ^sockaddr; - {$ENDIF} - - TIdStackUnix = class(TIdStackBSDBase) - protected - procedure WriteChecksumIPv6(s: TIdStackSocketHandle; var VBuffer: TIdBytes; - const AOffset: Integer; const AIP: String; const APort: TIdPort); - function GetLastError: Integer; - procedure SetLastError(const AError: Integer); - function HostByName(const AHostName: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; - function ReadHostName: string; override; - function WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; override; - function WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; - const ABufferLength, AFlags: Integer): Integer; override; - function WSSend(ASocket: TIdStackSocketHandle; const ABuffer; - const ABufferLength, AFlags: Integer): Integer; override; - function WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; override; - {$IFNDEF VCL_XE3_OR_ABOVE} - procedure WSGetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; - procedure WSSetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; - {$ENDIF} - public - constructor Create; override; - destructor Destroy; override; - procedure SetBlocking(ASocket: TIdStackSocketHandle; const ABlocking: Boolean); override; - function WouldBlock(const AResult: Integer): Boolean; override; - function WSTranslateSocketErrorMsg(const AErr: Integer): string; override; - function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; - var VIPVersion: TIdIPVersion): TIdStackSocketHandle; override; - procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - function HostByAddress(const AAddress: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; - function WSGetLastError: Integer; override; - procedure WSSetLastError(const AErr : Integer); override; - function WSGetServByName(const AServiceName: string): TIdPort; override; - procedure AddServByPortToList(const APortNumber: TIdPort; AAddresses: TStrings); override; - procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; - procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; - procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); override; - function HostToNetwork(AValue: UInt16): UInt16; override; - function NetworkToHost(AValue: UInt16): UInt16; override; - function HostToNetwork(AValue: UInt32): UInt32; override; - function NetworkToHost(AValue: UInt32): UInt32; override; - function HostToNetwork(AValue: TIdUInt64): TIdUInt64; override; - function NetworkToHost(AValue: TIdUInt64): TIdUInt64; override; - function RecvFrom(const ASocket: TIdStackSocketHandle; var VBuffer; - const ALength, AFlags: Integer; var VIP: string; var VPort: TIdPort; - var VIPVersion: TIdIPVersion): Integer; override; - function ReceiveMsg(ASocket: TIdStackSocketHandle; - var VBuffer: TIdBytes; APkt: TIdPacketInfo): UInt32; override; - procedure WSSendTo(ASocket: TIdStackSocketHandle; const ABuffer; - const ABufferLength, AFlags: Integer; const AIP: string; const APort: TIdPort; - AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - function WSSocket(AFamily, AStruct, AProtocol: Integer; - const ANonBlocking: Boolean = False): TIdStackSocketHandle; override; - procedure Disconnect(ASocket: TIdStackSocketHandle); override; - {$IFDEF VCL_XE3_OR_ABOVE} - procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; - procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; - {$ENDIF} - procedure SetKeepAliveValues(ASocket: TIdStackSocketHandle; - const AEnabled: Boolean; const ATimeMS, AInterval: Integer); override; - function SupportsIPv4: Boolean; overload; override; - function SupportsIPv6: Boolean; overload; override; - function CheckIPVersionSupport(const AIPVersion: TIdIPVersion): boolean; override; - //In Windows, this writes a checksum into a buffer. In Linux, it would probably - //simply have the kernal write the checksum with something like this (RFC 2292): -// -// int offset = 2; -// setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)); -// -// Note that this should be called - //IMMEDIATELY before you do a SendTo because the Local IPv6 address might change - - procedure WriteChecksum(s : TIdStackSocketHandle; var VBuffer : TIdBytes; - const AOffset : Integer; const AIP : String; const APort : TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; - var arg: UInt32): Integer; override; - - procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); override; - end; - - {$IFNDEF NO_REDECLARE} - TLinger = record - l_onoff: UInt16; - l_linger: UInt16; - end; - {$ENDIF} - TIdLinger = TLinger; - -implementation - -uses - netdb, - unix, - termio, - IdResourceStrings, - IdResourceStringsUnix, - IdException, - SysUtils; - - -//from: netdbh.inc, we can not include it with the I derrective and netdb.pas -//does not expose it. -{const - EAI_SYSTEM = -(11);} - -const - FD_SETSIZE = FD_MAXFDSET; - __FD_SETSIZE = FD_MAXFDSET; - {$IFDEF DARWIN} - { MSG_NOSIGNAL does not exist in OS X. Instead we have SO_NOSIGPIPE, which we set in Connect. } - Id_MSG_NOSIGNAL = 0; - {$ELSE} - Id_MSG_NOSIGNAL = MSG_NOSIGNAL; - {$ENDIF} - ESysEPIPE = ESysEPIPE; - -//helper functions for some structs - -{Note: These hide an API difference in structures. - -BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit -word to an 8 bit byteee and an 8 bit byte feild named sa_len was added. - -} -procedure InitSockaddr(var VSock : Sockaddr); -{$IFDEF USE_INLINE} inline; {$ENDIF} -begin - FillChar(VSock, SizeOf(Sockaddr), 0); - VSock.sin_family := PF_INET; - {$IFDEF SOCK_HAS_SINLEN} - VSock.sa_len := SizeOf(Sockaddr); - {$ENDIF} -end; - -procedure InitSockAddr_in6(var VSock : SockAddr_in6); -{$IFDEF USE_INLINE} inline; {$ENDIF} -begin - FillChar(VSock, SizeOf(SockAddr_in6), 0); - {$IFDEF SOCK_HAS_SINLEN} - VSock.sin6_len := SizeOf(SockAddr_in6); - {$ENDIF} - VSock.sin6_family := PF_INET6; -end; -// -constructor TIdStackUnix.Create; -begin - inherited Create; -end; - -destructor TIdStackUnix.Destroy; -begin - inherited Destroy; -end; - -function TIdStackUnix.GetLastError : Integer; -begin - Result := SocketError; -end; - -procedure TIdStackUnix.SetLastError(Const AError : Integer); -begin - errno := AError; -end; - -function TIdStackUnix.Accept(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): TIdStackSocketHandle; -var - LA : socklen_t; - LAddr: sockaddr_in6; -begin - LA := SizeOf(LAddr); - Result := fpaccept(ASocket, @LAddr, @LA); - //calls prefixed by fp to avoid clashing with libc - - if Result <> ID_SOCKET_ERROR then begin - case LAddr.sin6_family of - PF_INET : begin - with Psockaddr(@LAddr)^ do - begin - VIP := NetAddrToStr(sin_addr); - VPort := ntohs(sin_port); - end; - VIPVersion := Id_IPv4; - end; - PF_INET6: begin - with LAddr do - begin - VIP := NetAddrToStr6(sin6_addr); - VPort := Ntohs(sin6_port); - end; - VIPVersion := Id_IPv6; - end; - else begin - fpclose(Result); - Result := Id_INVALID_SOCKET; - IPVersionUnsupported; - end; - end; - end else begin - if GetLastError = ESysEBADF then begin - SetLastError(ESysEINTR); - end; - end; -end; - -procedure TIdStackUnix.Bind(ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LAddr: sockaddr_in6; -begin - case AIPVersion of - Id_IPv4: begin - InitSockAddr(Psockaddr(@LAddr)^); - with Psockaddr(@LAddr)^ do - begin - if AIP <> '' then begin - sin_addr := StrToNetAddr(AIP); - //TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); - end; - sin_port := htons(APort); - end; - CheckForSocketError(fpBind(ASocket, Psockaddr(@LAddr), SizeOf(sockaddr))); - end; - Id_IPv6: begin - InitSockAddr_in6(LAddr); - with LAddr do - begin - if AIP <> '' then begin - sin6_addr := StrToNetAddr6(AIP); - //TranslateStringToTInAddr(AIP, sin6_addr, Id_IPv6); - end; - sin6_port := htons(APort); - end; - CheckForSocketError(fpBind(ASocket, Psockaddr(@LAddr), SizeOf(Sockaddr_in6))); - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -function TIdStackUnix.WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; -begin - Result := fpclose(ASocket); -end; - -procedure TIdStackUnix.Connect(const ASocket: TIdStackSocketHandle; - const AIP: string; const APort: TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LAddr: sockaddr_in6; -begin - case AIPVersion of - Id_IPv4: begin - InitSockAddr(Psockaddr(@LAddr)^); - with Psockaddr(@LAddr)^ do - begin - sin_addr := StrToNetAddr(AIP); - //TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); - sin_port := htons(APort); - end; - CheckForSocketError(fpConnect(ASocket, Psockaddr(@LAddr), SizeOf(sockaddr))); - end; - Id_IPv6: begin - InitSockAddr_in6(LAddr); - with LAddr do - begin - sin6_addr := StrToNetAddr6(AIP); - //TranslateStringToTInAddr(AIP, LAddr6.sin6_addr, Id_IPv6); - sin6_port := htons(APort); - end; - CheckForSocketError(fpConnect(ASocket, Psockaddr(@LAddr), SizeOf(sockaddr_in6))); - end; - else begin - IPVersionUnsupported; - end; - end; - {$IFDEF DARWIN} // TODO: use HAS_SOCKET_NOSIGPIPE instead... - SetSocketOption(ASocket, Id_SOL_SOCKET, SO_NOSIGPIPE, 1); - {$ENDIF} -end; - -function TIdStackUnix.HostByName(const AHostName: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; -var - LI4 : array of THostAddr; - LI6 : array of THostAddr6; - LH4 : THostEntry; - LRetVal : Integer; -begin - case AIPVersion of - Id_IPv4 : - begin - if GetHostByName(AHostName, LH4) then - begin - Result := HostAddrToStr(LH4.Addr); - Exit; - end; - SetLength(LI4, 10); - LRetVal := ResolveName(AHostName, LI4); - if LRetVal < 1 then begin - raise EIdResolveError.CreateFmt(RSResolveError, [AHostName, 'Error', LRetVal]); {do not localize} - end; - Result := NetAddrToStr(LI4[0]); - end; - Id_IPv6 : - begin - SetLength(LI6, 10); - LRetVal := ResolveName6(AHostName, LI6); - if LRetVal < 1 then begin - raise EIdResolveError.CreateFmt(RSResolveError, [AHostName, LRetVal]); - end; - Result := NetAddrToStr6(LI6[0]); - end; - end; -end; - -function TIdStackUnix.ReadHostName: string; -begin - Result := GetHostName; -end; - -procedure TIdStackUnix.Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); -begin - CheckForSocketError(fpListen(ASocket, ABacklog)); -end; - -function TIdStackUnix.WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; - const ABufferLength, AFlags: Integer): Integer; -begin - //IdStackWindows is just: Result := Recv(ASocket, ABuffer, ABufferLength, AFlags); - Result := fpRecv(ASocket, @ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); -end; - -function TIdStackUnix.RecvFrom(const ASocket: TIdStackSocketHandle; var VBuffer; - const ALength, AFlags: Integer; var VIP: string; var VPort: TIdPort; - var VIPVersion: TIdIPVersion): Integer; -var - LiSize: tsocklen; - LAddr: sockaddr_in6; -begin - LiSize := SizeOf(sockaddr_in6); - Result := fpRecvFrom(ASocket, @VBuffer, ALength, AFlags or Id_MSG_NOSIGNAL, Psockaddr(@LAddr), @LiSize); - if Result >= 0 then - begin - case LAddr.sin6_family of - Id_PF_INET4 : - begin - with Psockaddr(@LAddr)^ do - begin - VIP := NetAddrToStr(sin_addr); - VPort := ntohs(sin_port); - end; - VIPVersion := Id_IPV4; - end; - Id_PF_INET6: - begin - with LAddr do - begin - VIP := NetAddrToStr6(sin6_addr); - VPort := ntohs(sin6_port); - end; - VIPVersion := Id_IPV6; - end; - end; - end; -end; - -function TIdStackUnix.ReceiveMsg(ASocket: TIdStackSocketHandle; - var VBuffer: TIdBytes; APkt: TIdPacketInfo): UInt32; -var - LIP : String; - LPort : TIdPort; - LIPVersion : TIdIPVersion; -begin - Result := RecvFrom(ASocket, VBuffer, Length(VBuffer), 0, LIP, LPort, LIPVersion); - APkt.Reset; - APkt.SourceIP := LIP; - APkt.SourcePort := LPort; - APkt.SourceIPVersion := LIPVersion; - APkt.DestIPVersion := LIPVersion; - - SetLength(VBuffer, Result); -end; -{The stuff below is commented out until I figure out what to do} -{var - LIP : String; - LPort : TIdPort; - LSize: UInt32; - LAddr: SockAddr_In6; - LMsg : msghdr; - LMsgBuf : BUF; - LControl : TIdBytes; - LCurCmsg : CMSGHDR; //for iterating through the control buffer - LCurPt : Pin_pktinfo; - LCurPt6 : Pin6_pktinfo; - LByte : PByte; - LDummy, LDummy2 : UInt32; -begin - //we call the macro twice because we specified two possible structures. - //Id_IPV6_HOPLIMIT and Id_IPV6_PKTINFO - LSize := CMSG_SPACE(SizeOf(Byte)) + CMSG_SPACE(SizeOf(in6_pktinfo)); - SetLength(LControl, LSize); - - LMsgBuf.len := Length(VBuffer); // Length(VMsgData); - LMsgBuf.buf := @VBuffer[0]; // @VMsgData[0]; - - FillChar(LMsg,SizeOf(LMsg),0); - - LMsg.lpBuffers := @LMsgBuf; - LMsg.dwBufferCount := 1; - - LMsg.Control.Len := LSize; - LMsg.Control.buf := @LControl[0]; - - LMsg.name := PSOCKADDR(@LAddr); - LMsg.namelen := SizeOf(LAddr); - CheckForSocketError( RecvMsg(ASocket,@LMsg,Result,@LDummy,LPwsaoverlapped_COMPLETION_ROUTINE(@LDummy2))); - - case LAddr.sin6_family of - Id_PF_INET4: begin - with PSOCKADDR(@LAddr)^do - begin - APkt.SourceIP := TranslateTInAddrToString(sin_addr,Id_IPv4); - APkt.SourcePort := NToHs(sin_port); - end; - APkt.SourceIPVersion := Id_IPv4; - end; - Id_PF_INET6: begin - with LAddr do - begin - APkt.SourceIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); - APkt.SourcePort := NToHs(sin6_port); - end; - APkt.SourceIPVersion := Id_IPv6; - end; - else begin - Result := 0; // avoid warning - IPVersionUnsupported; - end; - end; - LCurCmsg := nil; - repeat - LCurCmsg := CMSG_NXTHDR(@LMsg,LCurCmsg); - if LCurCmsg = nil then - begin - break; - end; - case LCurCmsg^.cmsg_type of - IP_PKTINFO : //done this way because IPV6_PKTINF and IP_PKTINFO - //are both 19 - begin - case LAddr.sin6_family of - Id_PF_INET4: - begin - LCurPt := WSA_CMSG_DATA(LCurCmsg); - APkt.DestIP := GWindowsStack.TranslateTInAddrToString(LCurPt^.ipi_addr,Id_IPv4); - APkt.DestIF := LCurPt^.ipi_ifindex; - APkt.DestIPVersion := Id_IPv4; - end; - Id_PF_INET6: - begin - LCurPt6 := WSA_CMSG_DATA(LCurCmsg); - APkt.DestIP := GWindowsStack.TranslateTInAddrToString(LCurPt6^.ipi6_addr,Id_IPv6); - APkt.DestIF := LCurPt6^.ipi6_ifindex; - APkt.DestIPVersion := Id_IPv6; - end; - end; - end; - Id_IPV6_HOPLIMIT : - begin - LByte := PByte(WSA_CMSG_DATA(LCurCmsg)); - APkt.TTL := LByte^; - end; - end; - until False; } - -function TIdStackUnix.WSSend(ASocket: TIdStackSocketHandle; - const ABuffer; const ABufferLength, AFlags: Integer): Integer; -begin - //CC: Should Id_MSG_NOSIGNAL be included? - // Result := Send(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); - Result := CheckForSocketError(fpsend(ASocket, @ABuffer, ABufferLength, AFlags)); -end; - -procedure TIdStackUnix.WSSendTo(ASocket: TIdStackSocketHandle; - const ABuffer; const ABufferLength, AFlags: Integer; const AIP: string; - const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LAddr : sockaddr_in6; - LBytesOut: Integer; -begin - case AIPVersion of - Id_IPv4 : - begin - InitSockAddr(Psockaddr(@LAddr)^); - with Psockaddr(@LAddr)^ do - begin - sin_addr := StrToNetAddr(AIP); - sin_port := htons(APort); - end; - LBytesOut := fpSendTo(ASocket, @ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL, Psockaddr(@LAddr), SizeOf(sockaddr)); - end; - Id_IPv6: - begin - InitSockAddr_in6(LAddr); - with LAddr do - begin - sin6_addr := StrToHostAddr6(AIP); - //TranslateStringToTInAddr(AIP, sin6_addr, AIPVersion); - sin6_port := htons(APort); - end; - LBytesOut := fpSendTo(ASocket, @ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL, Psockaddr(@LAddr), SizeOf(sockaddr_in6)); - end; - else begin - LBytesOut := 0; // avoid warning - IPVersionUnsupported; - end; - end; - if LBytesOut = -1 then begin - // TODO: move this into RaiseLastSocketError() directly - if WSGetLastError() = Id_WSAEMSGSIZE then begin - raise EIdPackageSizeTooBig.Create(RSPackageSizeTooBig); - end else begin - RaiseLastSocketError; - end; - end else if LBytesOut <> ABufferLength then begin - raise EIdNotAllBytesSent.Create(RSNotAllBytesSent); - end; -end; - -procedure TIdStackUnix.{$IFDEF VCL_XE3_OR_ABOVE}GetSocketOption{$ELSE}WSGetSocketOption{$ENDIF} - (ASocket: TIdStackSocketHandle; ALevel: TIdSocketProtocol; AOptName: TIdSocketOption; - var AOptVal; var AOptLen: Integer); -var - LLen : TSockLen; -begin - LLen := AOptLen; - CheckForSocketError(fpGetSockOpt(ASocket, ALevel, AOptName, PAnsiChar(@AOptVal), @LLen)); - AOptLen := LLen; -end; - -procedure TIdStackUnix.{$IFDEF VCL_XE3_OR_ABOVE}SetSocketOption{$ELSE}WSSetSocketOption{$ENDIF} - (ASocket: TIdStackSocketHandle; ALevel: TIdSocketProtocol; AOptName: TIdSocketOption; - const AOptVal; const AOptLen: Integer); -begin - CheckForSocketError(fpSetSockOpt(ASocket, ALevel, AOptName, PAnsiChar(@AOptVal), AOptLen)); -end; - -function TIdStackUnix.WSGetLastError: Integer; -begin - //IdStackWindows just uses result := WSAGetLastError; - Result := GetLastError; //System.GetLastOSError; - FPC doesn't define it in System - if Result = ESysEPIPE then begin - Result := Id_WSAECONNRESET; - end; -end; - -procedure TIdStackUnix.WSSetLastError(const AErr : Integer); -begin - SetLastError(AErr); -end; - -function TIdStackUnix.WSSocket(AFamily, AStruct, AProtocol: Integer; - const ANonBlocking: Boolean = False): TIdStackSocketHandle; -var - LValue: UInt32; -begin - Result := fpsocket(AFamily, AStruct, AProtocol); - if Result <> Id_INVALID_SOCKET then begin - //SetBlocking(Result, not ANonBlocking); - LValue := UInt32(ANonBlocking); - fpioctl(Result, FIONBIO, @LValue); - end; -end; - -function TIdStackUnix.WSGetServByName(const AServiceName: string): TIdPort; -var - LS : TServiceEntry; -begin - if GetServiceByName(AServiceName, '', LS) then begin - Result := LS.Port; - end else begin - raise EIdInvalidServiceName.CreateFmt(RSInvalidServiceName, [AServiceName]); - end; -end; - -function TIdStackUnix.HostToNetwork(AValue: UInt16): UInt16; -begin - Result := htons(AValue); -end; - -function TIdStackUnix.NetworkToHost(AValue: UInt16): UInt16; -begin - Result := ntohs(AValue); -end; - -function TIdStackUnix.HostToNetwork(AValue: UInt32): UInt32; -begin - {$i IdRangeCheckingOff.inc} // disable range checking - Result := htonl(AValue); - {$i IdRangeCheckingOn.inc} // Restore range checking -end; - -function TIdStackUnix.NetworkToHost(AValue: UInt32): UInt32; -begin - {$i IdRangeCheckingOff.inc} // disable range checking - Result := ntohl(AValue); - // Restore range checking - {$i IdRangeCheckingOn.inc} // Restore range checking -end; - -{ RP - I'm not sure what endian Linux natively uses, thus the -check to see if the bytes need swapping or not ... } -function TIdStackUnix.HostToNetwork(AValue: TIdUInt64): TIdUInt64; -var - LParts: TIdUInt64Parts; - L: UInt32; -begin - {$i IdRangeCheckingOff.inc} // disable range checking - if (htonl(1) <> 1) then begin - LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - L := htonl(LParts.HighPart); - LParts.HighPart := htonl(LParts.LowPart); - LParts.LowPart := L; - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; - end else begin - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - end; - {$i IdRangeCheckingOn.inc} // Restore range checking -end; - -function TIdStackUnix.NetworkToHost(AValue: TIdUInt64): TIdUInt64; -var - LParts: TIdUInt64Parts; - L: UInt32; -begin - {$i IdRangeCheckingOff.inc} // disable range checking - if (ntohl(1) <> 1) then begin - LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - L := ntohl(LParts.HighPart); - LParts.HighPart := NetworkToHost(LParts.LowPart); - LParts.LowPart := L; - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; - end else begin - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - end; - {$i IdRangeCheckingOn.inc} // Restore range checking -end; - -{$IFDEF HAS_getifaddrs} -// TODO: does FreePascal already define these anywhere? - -type - pifaddrs = ^ifaddrs; - ifaddrs = record - ifa_next: pifaddrs; { Pointer to next struct } - ifa_name: PIdAnsiChar; { Interface name } -// Solaris ifaddrs struct implements 64bit ifa_flags. (Details: https://docs.oracle.com/cd/E88353_01/html/E37843/getifaddrs-3c.html) -{$IFDEF SOLARIS} - ifa_flags: UInt64; { Interface flags } -{$ELSE} - ifa_flags: Cardinal; { Interface flags } -{$ENDIF} - ifa_addr: psockaddr; { Interface address } - ifa_netmask: psockaddr; { Interface netmask } - ifa_broadaddr: psockaddr; { Interface broadcast address } - ifa_dstaddr: psockaddr; { P2P interface destination } - ifa_data: Pointer; { Address specific data } - end; - -const - IFF_LOOPBACK = $8; - -function getifaddrs(var ifap: pifaddrs): Integer; cdecl; external 'libc.so' name 'getifaddrs'; {do not localize} -procedure freeifaddrs(ifap: pifaddrs); cdecl; external 'libc.so' name 'freeifaddrs'; {do not localize} - {$IFDEF HAS_if_nametoindex} -procedure if_nametoindex(const ifname: PIdAnsiChar): UInt32; cdecl; external 'libc.so' name 'if_nametoindex'; {do not localize} - {$ENDIF} - -type - TIdStackLocalAddressAccess = class(TIdStackLocalAddress) - end; -{$ENDIF} - -procedure TIdStackUnix.GetLocalAddressList(AAddresses: TIdStackLocalAddressList); -var - {$IFDEF HAS_getifaddrs} - LAddrList, LAddrInfo: pifaddrs; - LSubNetStr: String; - LAddress: TIdStackLocalAddress; - LName: string; - {$ELSE} - LI4 : array of THostAddr; - LI6 : array of THostAddr6; - i : Integer; - LHostName : String; - {$ENDIF} -begin - // TODO: Using gethostname() and ResolveName() like this may not always - // return just the machine's IP addresses. Technically speaking, they will - // return the local hostname, and then return the address(es) to which that - // hostname resolves. It is possible for a machine to (a) be configured such - // that its name does not resolve to an IP, or (b) be configured such that - // its name resolves to multiple IPs, only one of which belongs to the local - // machine. For better results, we should use getifaddrs() on platforms that - // support it... - - {$IFDEF HAS_getifaddrs} - - if getifaddrs(LAddrList) = 0 then // TODO: raise an exception if it fails - try - AAddresses.BeginUpdate; - try - LAddrInfo := LAddrList; - repeat - if (LAddrInfo^.ifa_addr <> nil) and ((LAddrInfo^.ifa_flags and IFF_LOOPBACK) = 0) then - begin - LAddress := nil; - case LAddrInfo^.ifa_addr^.sa_family of - Id_PF_INET4: begin - if LAddrInfo^.ifa_netmask <> nil then begin - LSubNetStr := TranslateTInAddrToString( PSockAddr_In(LAddrInfo^.ifa_netmask)^.sin_addr, Id_IPv4); - end else begin - LSubNetStr := ''; - end; - LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, TranslateTInAddrToString( PSockAddr_In(LAddrInfo^.ifa_addr)^.sin_addr, Id_IPv4), LSubNetStr); - end; - Id_PF_INET6: begin - LAddress := TIdStackLocalAddressIPv6.Create(AAddresses, TranslateTInAddrToString( PSockAddr_In6(LAddrInfo^.ifa_addr)^.sin6_addr, Id_IPv6)); - end; - end; - if LAddress <> nil then begin - LName := String(LAddrInfo^.ifa_name); - {$I IdObjectChecksOff.inc} - TIdStackLocalAddressAccess(LAddress).FDescription := LName; - TIdStackLocalAddressAccess(LAddress).FFriendlyName := LName; - TIdStackLocalAddressAccess(LAddress).FInterfaceName := LName; - {$IFDEF HAS_if_nametoindex} - TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := if_nametoindex(LAddrInfo^.ifa_name); - {$ENDIF} - {$I IdObjectChecksOn.inc} - end; - end; - LAddrInfo := LAddrInfo^.ifa_next; - until LAddrInfo = nil; - finally - AAddresses.EndUpdate; - end; - finally - freeifaddrs(LAddrList); - end; - - {$ELSE} - - LHostName := GetHostName; - if LHostName = '' then begin - RaiseLastSocketError; - end; - AAddresses.BeginUpdate; - try - if ResolveName(LHostName, LI4) = 0 then - begin - for i := Low(LI4) to High(LI4) do - begin - TIdStackLocalAddressIPv4.Create(AAddresses, NetAddrToStr(LI4[i]), ''); // TODO: SubNet - end; - end; - if ResolveName6(LHostName, LI6) = 0 then - begin - for i := Low(LI6) to High(LI6) do - begin - TIdStackLocalAddressIPv6.Create(AAddresses, NetAddrToStr6(LI6[i])); - end; - end; - finally - AAddresses.EndUpdate; - end; - - {$ENDIF} -end; - -function TIdStackUnix.HostByAddress(const AAddress: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; -var - LI : Array of string; - LAddr4: THostAddr; - LAddr6: THostAddr6; -begin - Result := ''; - case AIPVersion of - Id_IPv4 : - begin - LAddr4 := StrToNetAddr(AAddress); - if ResolveAddress(LAddr4, LI) = 0 then begin - Result := LI[0]; - end; - end; - Id_IPv6 : - begin - LAddr6 := StrToNetAddr6(AAddress); - if ResolveAddress6(LAddr6, LI) = 0 then begin - Result := LI[0]; - end; - end; - end; -end; - -function TIdStackUnix.WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; -begin - Result := fpShutdown(ASocket, AHow); -end; - -procedure TIdStackUnix.Disconnect(ASocket: TIdStackSocketHandle); -begin - // Windows uses Id_SD_Send, Linux should use Id_SD_Both - WSShutdown(ASocket, Id_SD_Both); - // SO_LINGER is false - socket may take a little while to actually close after this - WSCloseSocket(ASocket); -end; - -procedure TIdStackUnix.GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); -var - i: tsocklen; - LAddr: sockaddr_in6; -begin - i := SizeOf(LAddr); - CheckForSocketError(fpGetPeerName(ASocket, @LAddr, @i)); - case LAddr.sin6_family of - PF_INET: begin - with Psockaddr(@LAddr)^ do - begin - VIP := NetAddrToStr(sin_addr); - VPort := ntohs(sin_port); - end; - VIPVersion := Id_IPv4; - end; - PF_INET6: begin - with LAddr do - begin - VIP := NetAddrToStr6(sin6_addr); - VPort := ntohs(sin6_port); - end; - VIPVersion := Id_IPv6; - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -procedure TIdStackUnix.GetSocketName(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); -var - i: tsocklen; - LAddr: sockaddr_in6; -begin - i := SizeOf(LAddr); - CheckForSocketError(fpGetSockName(ASocket, @LAddr, @i)); - case LAddr.sin6_family of - PF_INET : begin - with Psockaddr(@LAddr)^ do - begin - VIP := NetAddrToStr(sin_addr); - VPort := ntohs(sin_port); - end; - VIPVersion := Id_IPV4; - end; - PF_INET6: begin - with LAddr do - begin - VIP := NetAddrToStr6(sin6_addr); - VPort := ntohs(sin6_port); - end; - VIPVersion := Id_IPv6; - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -procedure TIdStackUnix.AddServByPortToList(const APortNumber: TIdPort; AAddresses: TStrings); -var - LS : TServiceEntry; -begin - if GetServiceByPort(APortNumber, '', LS) then begin - AAddresses.Add(LS.Name); - end; -end; - -function TIdStackUnix.WSTranslateSocketErrorMsg(const AErr: Integer): string; -begin - //we override this function for the herr constants that - //are returned by the DNS functions - //note that this is not really applicable because we are using some - //FPC functions that do direct DNS lookups without the standard Unix - //DNS functions. It sounds odd but I think there's a good reason for it. - Result := inherited WSTranslateSocketErrorMsg(AErr); -end; - -procedure TIdStackUnix.SetBlocking(ASocket: TIdStackSocketHandle; - const ABlocking: Boolean); -var - LValue: UInt32; -begin - LValue := UInt32(not ABlocking); - CheckForSocketError(fpioctl(ASocket, FIONBIO, @LValue)); -end; - -function TIdStackUnix.WouldBlock(const AResult: Integer): Boolean; -begin - // using if-else instead of in..range because EAGAIN and EWOULDBLOCK - // have often the same value and so FPC might report a range error - Result := (AResult = Id_WSAEAGAIN) or - (AResult = Id_WSAEWOULDBLOCK) or - (AResult = Id_WSAEINPROGRESS); -end; - -function TIdStackUnix.SupportsIPv4: Boolean; -//In Windows, this does something else. It checks the LSP's installed. -begin - Result := CheckIPVersionSupport(Id_IPv4); -end; - -function TIdStackUnix.SupportsIPv6: Boolean; -//In Windows, this does something else. It checks the LSP's installed. -begin - Result := CheckIPVersionSupport(Id_IPv6); -end; - -function TIdStackUnix.CheckIPVersionSupport(const AIPVersion: TIdIPVersion): Boolean; -var - LTmpSocket: TIdStackSocketHandle; -begin - // TODO: on nix systems (or maybe just Linux?), an alternative would be to - // check for the existance of the '/proc/net/if_inet6' kernel pseudo-file - LTmpSocket := WSSocket(IdIPFamily[AIPVersion], Integer(Id_SOCK_STREAM), Id_IPPROTO_IP); - Result := LTmpSocket <> Id_INVALID_SOCKET; - if Result then begin - WSCloseSocket(LTmpSocket); - end; -end; - -procedure TIdStackUnix.WriteChecksum(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort; const AIPVersion: TIdIPVersion); -begin - case AIPVersion of - Id_IPv4 : CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(VBuffer)), VBuffer, AOffset); - Id_IPv6 : WriteChecksumIPv6(s, VBuffer, AOffset, AIP, APort); - else - IPVersionUnsupported; - end; -end; - -procedure TIdStackUnix.WriteChecksumIPv6(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort); -begin -//we simply request that the kernal write the checksum when the data -//is sent. All of the parameters required are because Windows is bonked -//because it doesn't have the IPV6CHECKSUM socket option meaning we have -//to querry the network interface in TIdStackWindows -- yuck!! - SetSocketOption(s, Id_IPPROTO_IPV6, IPV6_CHECKSUM, AOffset); -end; - -function TIdStackUnix.IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; - var arg: UInt32): Integer; -begin - Result := fpioctl(s, cmd, @arg); -end; -(* -Why did I remove this again? - - 1) it sends SIGPIPE even if the socket is created with the no-sigpipe bit set - that could be solved by blocking sigpipe within this thread - This is probably a bug in the Linux kernel, but we could work around it - by blocking that signal for the time of sending the file (just get the - sigprocmask, see if pipe bit is set, if not set it and remove again after - sending the file) - -But the more serious reason is another one, which exists in Windows too: - 2) I think that ServeFile is misdesigned: - ServeFile does not raise an exception if it didn't send all the bytes. - Now what happens if I have OnExecute assigned like this - AThread.Connection.ServeFile('...', True); // <-- true to send via kernel - is that it will return 0, but notice that in this case I didn't ask for the - result. Net effect is that the thread will loop in OnExecute even if the - socket is long gone. This doesn't fit Indy semantics at all, exceptions are - always raised if the remote end disconnects. Even if I would do - AThread.Connection.ServeFile('...', False); - then it would raise an exception. - I think this is a big flaw in the design of the ServeFile function. - Maybe GServeFile should only return the bytes sent, but then - TCPConnection.ServeFile() should raise an exception if GServeFile didn't - send all the bytes. - -JM Berg, 2002-09-09 - -function ServeFile(ASocket: TIdStackSocketHandle; AFileName: string): UInt32; -var - LFileHandle: integer; - offset: integer; - stat: _stat; -begin - LFileHandle := open(PChar(AFileName), O_RDONLY); - try - offset := 0; - fstat(LFileHandle, stat); - Result := sendfile(ASocket, LFileHandle, offset, stat.st_size); -//** if Result = UInt32(-1) then RaiseLastOSError; - finally libc.__close(LFileHandle); end; -end; -*) - -procedure TIdStackUnix.SetKeepAliveValues(ASocket: TIdStackSocketHandle; - const AEnabled: Boolean; const ATimeMS, AInterval: Integer); -begin - inherited; // turn SO_KEEPALIVE on/off first... - // TODO: remove below, as it should be handled by TIdStack.SetKeepAliveValues() now... - if AEnabled then begin - {$IFDEF HAS_TCP_KEEPIDLE} - SetSocketOption(ASocket, Id_SOL_TCP, Id_TCP_KEEPIDLE, ATimeMS div MSecsPerSec); - {$ENDIF} - {$IFDEF HAS_TCP_KEEPINTVL} - SetSocketOption(ASocket, Id_SOL_TCP, Id_TCP_KEEPINTVL, AInterval div MSecsPerSec); - {$ENDIF} - end; -end; - -{ TIdSocketListUnix } - -type - // TODO: rewrite this to use poll() instead of select(), similar to TIdSocketListVCLPosix - TIdSocketListUnix = class (TIdSocketList) - protected - FCount: Integer; - FFDSet: TFDSet; - // - class function FDSelect(AReadSet: PFDSet; AWriteSet: PFDSet; AExceptSet: PFDSet; - const ATimeout: Integer = IdTimeoutInfinite): Integer; - function GetItem(AIndex: Integer): TIdStackSocketHandle; override; - public - procedure Add(AHandle: TIdStackSocketHandle); override; - procedure Remove(AHandle: TIdStackSocketHandle); override; - function Count: Integer; override; - procedure Clear; override; - function Clone: TIdSocketList; override; - function ContainsSocket(AHandle: TIdStackSocketHandle): Boolean; override; - procedure GetFDSet(var VSet: TFDSet); - procedure SetFDSet(var VSet: TFDSet); - class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; - AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - function SelectReadList(var VSocketList: TIdSocketList; - const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - end; - -procedure TIdSocketListUnix.Add(AHandle: TIdStackSocketHandle); -begin - Lock; - try - if fpFD_ISSET(AHandle, FFDSet) = 0 then begin - if AHandle >= FD_SETSIZE then begin - raise EIdStackSetSizeExceeded.Create(RSSetSizeExceeded); - end; - fpFD_SET(AHandle, FFDSet); - Inc(FCount); - end; - finally - Unlock; - end; -end;// - -procedure TIdSocketListUnix.Clear; -begin - Lock; - try - fpFD_ZERO(FFDSet); - FCount := 0; - finally - Unlock; - end; -end; - -function TIdSocketListUnix.ContainsSocket(AHandle: TIdStackSocketHandle): Boolean; -begin - Lock; - try - Result := fpFD_ISSET(AHandle, FFDSet) > 0; - finally - Unlock; - end; -end; - -function TIdSocketListUnix.Count: Integer; -begin - Lock; - try - Result := FCount; - finally - Unlock; - end; -end;// - -class function TIdSocketListUnix.FDSelect(AReadSet, AWriteSet, AExceptSet: PFDSet; - const ATimeout: Integer): Integer; -var - LTime: TTimeVal; - LTimePtr: PTimeVal; -begin - if ATimeout = IdTimeoutInfinite then begin - LTimePtr := nil; - end else begin - LTime.tv_sec := ATimeout div 1000; - LTime.tv_usec := (ATimeout mod 1000) * 1000; - LTimePtr := @LTime; - end; - // TODO: calculate the actual nfds value based on the Sets provided... - // TODO: use poll() instead of select() to remove limit on how many sockets can be queried - Result := fpSelect(FD_SETSIZE, AReadSet, AWriteSet, AExceptSet, LTimePtr); -end; - -procedure TIdSocketListUnix.GetFDSet(var VSet: TFDSet); -begin - Lock; - try - VSet := FFDSet; - finally - Unlock; - end; -end; - -function TIdSocketListUnix.GetItem(AIndex: Integer): TIdStackSocketHandle; -var - LIndex, i: Integer; -begin - Result := 0; - // TODO: is this missing Lock/Unlock calls? - LIndex := 0; - //? use FMaxHandle div x - for i:= 0 to __FD_SETSIZE - 1 do begin - if fpFD_ISSET(i, FFDSet) = 1 then begin - if LIndex = AIndex then begin - Result := i; - Break; - end; - Inc(LIndex); - end; - end; -end; - -procedure TIdSocketListUnix.Remove(AHandle: TIdStackSocketHandle); -begin - Lock; - try - if fpFD_ISSET(AHandle, FFDSet) = 1 then - begin - Dec(FCount); - fpFD_CLR(AHandle, FFDSet); - end; - finally - Unlock; - end; -end;// - -procedure TIdSocketListUnix.SetFDSet(var VSet: TFDSet); -begin - Lock; - try - FFDSet := VSet; - finally - Unlock; - end; -end; - -class function TIdSocketListUnix.Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; - AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; -var - LReadSet: TFDSet; - LWriteSet: TFDSet; - LExceptSet: TFDSet; - LPReadSet: PFDSet; - LPWriteSet: PFDSet; - LPExceptSet: PFDSet; - - procedure ReadSet(AList: TIdSocketList; var ASet: TFDSet; var APSet: PFDSet); - begin - if AList <> nil then begin - TIdSocketListUnix(AList).GetFDSet(ASet); - APSet := @ASet; - end else begin - APSet := nil; - end; - end; - -begin - ReadSet(AReadList, LReadSet, LPReadSet); - ReadSet(AWriteList, LWriteSet, LPWriteSet); - ReadSet(AExceptList, LExceptSet, LPExceptSet); - // - Result := FDSelect(LPReadSet, LPWriteSet, LPExceptSet, ATimeout) <> 0; - // - if AReadList <> nil then begin - TIdSocketListUnix(AReadList).SetFDSet(LReadSet); - end; - if AWriteList <> nil then begin - TIdSocketListUnix(AWriteList).SetFDSet(LWriteSet); - end; - if AExceptList <> nil then begin - TIdSocketListUnix(AExceptList).SetFDSet(LExceptSet); - end; -end; - -function TIdSocketListUnix.SelectRead(const ATimeout: Integer): Boolean; -var - LSet: TFDSet; -begin - Lock; - try - LSet := FFDSet; - // select() updates this structure on return, - // so we need to copy it each time we need it - finally - Unlock; - end; - Result := FDSelect(@LSet, nil, nil, ATimeout) > 0; -end; - -function TIdSocketListUnix.SelectReadList(var VSocketList: TIdSocketList; - const ATimeout: Integer = IdTimeoutInfinite): Boolean; -var - LSet: TFDSet; -begin - Lock; - try - LSet := FFDSet; - // select() updates this structure on return, - // so we need to copy it each time we need it - finally - Unlock; - end; - Result := FDSelect(@LSet, nil, nil, ATimeout) > 0; - if Result then begin - if VSocketList = nil then begin - VSocketList := TIdSocketList.CreateSocketList; - end; - TIdSocketListUnix(VSocketList).SetFDSet(LSet); - end; -end; - -function TIdSocketListUnix.Clone: TIdSocketList; -begin - Result := TIdSocketListUnix.Create; - try - Lock; - try - TIdSocketListUnix(Result).SetFDSet(FFDSet); - finally - Unlock; - end; - except - FreeAndNil(Result); - raise; - end; -end; - -initialization - GSocketListClass := TIdSocketListUnix; - -end. - +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. + + + $Log$ + + + Rev 1.7 10/26/2004 8:20:04 PM JPMugaas + Fixed some oversights with conversion. OOPS!!! + + + Rev 1.6 10/26/2004 8:12:32 PM JPMugaas + Now uses TIdStrings and TIdStringList for portability. + + + Rev 1.5 12/06/2004 15:17:20 CCostelloe + Restructured to correspond with IdStackWindows, now works. + + + Rev 1.4 07/06/2004 21:31:02 CCostelloe + Kylix 3 changes + + + Rev 1.3 4/18/04 10:43:22 PM RLebeau + Fixed syntax error + + + Rev 1.2 4/18/04 10:29:46 PM RLebeau + Renamed Int64Parts structure to TIdInt64Parts + + + Rev 1.1 4/18/04 2:47:28 PM RLebeau + Conversion support for Int64 values + + Removed WSHToNs(), WSNToHs(), WSHToNL(), and WSNToHL() methods, obsolete + + + Rev 1.0 2004.02.03 3:14:48 PM czhower + Move and updates + + + Rev 1.3 10/19/2003 5:35:14 PM BGooijen + SetSocketOption + + + Rev 1.2 2003.10.01 9:11:24 PM czhower + .Net + + + Rev 1.1 7/5/2003 07:25:50 PM JPMugaas + Added functions to the Linux stack which use the new TIdIPAddress record type + for IP address parameters. I also fixed a compile bug. + + + Rev 1.0 11/13/2002 08:59:24 AM JPMugaas +} +unit IdStackUnix; +interface + +{$i IdCompilerDefines.inc} + +{$IFNDEF FPC} + {$Message Fatal 'IdStackUnix is only for FreePascal.'} +{$ENDIF} +uses + Classes, + sockets, + baseunix, + IdStack, + IdStackConsts, + IdGlobal, + IdStackBSDBase; + +{$IFDEF FREEBSD} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} +{$IFDEF DARWIN} + {$DEFINE SOCK_HAS_SINLEN} +{$ENDIF} + +type + {$IFNDEF NO_REDECLARE} + Psockaddr = ^sockaddr; + {$ENDIF} + + TIdStackUnix = class(TIdStackBSDBase) + protected + procedure WriteChecksumIPv6(s: TIdStackSocketHandle; var VBuffer: TIdBytes; + const AOffset: Integer; const AIP: String; const APort: TIdPort); + function GetLastError: Integer; + procedure SetLastError(const AError: Integer); + function HostByName(const AHostName: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; + function ReadHostName: string; override; + function WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; override; + function WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; + const ABufferLength, AFlags: Integer): Integer; override; + function WSSend(ASocket: TIdStackSocketHandle; const ABuffer; + const ABufferLength, AFlags: Integer): Integer; override; + function WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; override; + {$IFNDEF VCL_XE3_OR_ABOVE} + procedure WSGetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; + procedure WSSetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; + {$ENDIF} + public + constructor Create; override; + destructor Destroy; override; + procedure SetBlocking(ASocket: TIdStackSocketHandle; const ABlocking: Boolean); override; + function WouldBlock(const AResult: Integer): Boolean; override; + function WSTranslateSocketErrorMsg(const AErr: Integer): string; override; + function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; + var VIPVersion: TIdIPVersion): TIdStackSocketHandle; override; + procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + function HostByAddress(const AAddress: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; + function WSGetLastError: Integer; override; + procedure WSSetLastError(const AErr : Integer); override; + function WSGetServByName(const AServiceName: string): TIdPort; override; + procedure AddServByPortToList(const APortNumber: TIdPort; AAddresses: TStrings); override; + procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; + procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; + procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); override; + function HostToNetwork(AValue: UInt16): UInt16; override; + function NetworkToHost(AValue: UInt16): UInt16; override; + function HostToNetwork(AValue: UInt32): UInt32; override; + function NetworkToHost(AValue: UInt32): UInt32; override; + function HostToNetwork(AValue: TIdUInt64): TIdUInt64; override; + function NetworkToHost(AValue: TIdUInt64): TIdUInt64; override; + function RecvFrom(const ASocket: TIdStackSocketHandle; var VBuffer; + const ALength, AFlags: Integer; var VIP: string; var VPort: TIdPort; + var VIPVersion: TIdIPVersion): Integer; override; + function ReceiveMsg(ASocket: TIdStackSocketHandle; + var VBuffer: TIdBytes; APkt: TIdPacketInfo): UInt32; override; + procedure WSSendTo(ASocket: TIdStackSocketHandle; const ABuffer; + const ABufferLength, AFlags: Integer; const AIP: string; const APort: TIdPort; + AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + function WSSocket(AFamily, AStruct, AProtocol: Integer; + const ANonBlocking: Boolean = False): TIdStackSocketHandle; override; + procedure Disconnect(ASocket: TIdStackSocketHandle); override; + {$IFDEF VCL_XE3_OR_ABOVE} + procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; + procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; + {$ENDIF} + procedure SetKeepAliveValues(ASocket: TIdStackSocketHandle; + const AEnabled: Boolean; const ATimeMS, AInterval: Integer); override; + function SupportsIPv4: Boolean; overload; override; + function SupportsIPv6: Boolean; overload; override; + function CheckIPVersionSupport(const AIPVersion: TIdIPVersion): boolean; override; + //In Windows, this writes a checksum into a buffer. In Linux, it would probably + //simply have the kernal write the checksum with something like this (RFC 2292): +// +// int offset = 2; +// setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)); +// +// Note that this should be called + //IMMEDIATELY before you do a SendTo because the Local IPv6 address might change + + procedure WriteChecksum(s : TIdStackSocketHandle; var VBuffer : TIdBytes; + const AOffset : Integer; const AIP : String; const APort : TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; + var arg: UInt32): Integer; override; + + procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); override; + end; + + {$IFNDEF NO_REDECLARE} + TLinger = record + l_onoff: UInt16; + l_linger: UInt16; + end; + {$ENDIF} + TIdLinger = TLinger; + +implementation + +uses + netdb, + unix, + termio, + IdResourceStrings, + IdResourceStringsUnix, + IdException, + SysUtils; + + +//from: netdbh.inc, we can not include it with the I derrective and netdb.pas +//does not expose it. +{const + EAI_SYSTEM = -(11);} + +const + FD_SETSIZE = FD_MAXFDSET; + __FD_SETSIZE = FD_MAXFDSET; + {$IFDEF DARWIN} + { MSG_NOSIGNAL does not exist in OS X. Instead we have SO_NOSIGPIPE, which we set in Connect. } + Id_MSG_NOSIGNAL = 0; + {$ELSE} + Id_MSG_NOSIGNAL = MSG_NOSIGNAL; + {$ENDIF} + ESysEPIPE = ESysEPIPE; + +//helper functions for some structs + +{Note: These hide an API difference in structures. + +BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit +word to an 8 bit byteee and an 8 bit byte feild named sa_len was added. + +} +procedure InitSockaddr(var VSock : Sockaddr); +{$IFDEF USE_INLINE} inline; {$ENDIF} +begin + FillChar(VSock, SizeOf(Sockaddr), 0); + VSock.sin_family := PF_INET; + {$IFDEF SOCK_HAS_SINLEN} + VSock.sa_len := SizeOf(Sockaddr); + {$ENDIF} +end; + +procedure InitSockAddr_in6(var VSock : SockAddr_in6); +{$IFDEF USE_INLINE} inline; {$ENDIF} +begin + FillChar(VSock, SizeOf(SockAddr_in6), 0); + {$IFDEF SOCK_HAS_SINLEN} + VSock.sin6_len := SizeOf(SockAddr_in6); + {$ENDIF} + VSock.sin6_family := PF_INET6; +end; +// +constructor TIdStackUnix.Create; +begin + inherited Create; +end; + +destructor TIdStackUnix.Destroy; +begin + inherited Destroy; +end; + +function TIdStackUnix.GetLastError : Integer; +begin + Result := SocketError; +end; + +procedure TIdStackUnix.SetLastError(Const AError : Integer); +begin + errno := AError; +end; + +function TIdStackUnix.Accept(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): TIdStackSocketHandle; +var + LA : socklen_t; + LAddr: sockaddr_in6; +begin + LA := SizeOf(LAddr); + Result := fpaccept(ASocket, @LAddr, @LA); + //calls prefixed by fp to avoid clashing with libc + + if Result <> ID_SOCKET_ERROR then begin + case LAddr.sin6_family of + PF_INET : begin + with Psockaddr(@LAddr)^ do + begin + VIP := NetAddrToStr(sin_addr); + VPort := ntohs(sin_port); + end; + VIPVersion := Id_IPv4; + end; + PF_INET6: begin + with LAddr do + begin + VIP := NetAddrToStr6(sin6_addr); + VPort := Ntohs(sin6_port); + end; + VIPVersion := Id_IPv6; + end; + else begin + fpclose(Result); + Result := Id_INVALID_SOCKET; + IPVersionUnsupported; + end; + end; + end else begin + if GetLastError = ESysEBADF then begin + SetLastError(ESysEINTR); + end; + end; +end; + +procedure TIdStackUnix.Bind(ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LAddr: sockaddr_in6; +begin + case AIPVersion of + Id_IPv4: begin + InitSockAddr(Psockaddr(@LAddr)^); + with Psockaddr(@LAddr)^ do + begin + if AIP <> '' then begin + sin_addr := StrToNetAddr(AIP); + //TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); + end; + sin_port := htons(APort); + end; + CheckForSocketError(fpBind(ASocket, Psockaddr(@LAddr), SizeOf(sockaddr))); + end; + Id_IPv6: begin + InitSockAddr_in6(LAddr); + with LAddr do + begin + if AIP <> '' then begin + sin6_addr := StrToNetAddr6(AIP); + //TranslateStringToTInAddr(AIP, sin6_addr, Id_IPv6); + end; + sin6_port := htons(APort); + end; + CheckForSocketError(fpBind(ASocket, Psockaddr(@LAddr), SizeOf(Sockaddr_in6))); + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +function TIdStackUnix.WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; +begin + Result := fpclose(ASocket); +end; + +procedure TIdStackUnix.Connect(const ASocket: TIdStackSocketHandle; + const AIP: string; const APort: TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LAddr: sockaddr_in6; +begin + case AIPVersion of + Id_IPv4: begin + InitSockAddr(Psockaddr(@LAddr)^); + with Psockaddr(@LAddr)^ do + begin + sin_addr := StrToNetAddr(AIP); + //TranslateStringToTInAddr(AIP, sin_addr, Id_IPv4); + sin_port := htons(APort); + end; + CheckForSocketError(fpConnect(ASocket, Psockaddr(@LAddr), SizeOf(sockaddr))); + end; + Id_IPv6: begin + InitSockAddr_in6(LAddr); + with LAddr do + begin + sin6_addr := StrToNetAddr6(AIP); + //TranslateStringToTInAddr(AIP, LAddr6.sin6_addr, Id_IPv6); + sin6_port := htons(APort); + end; + CheckForSocketError(fpConnect(ASocket, Psockaddr(@LAddr), SizeOf(sockaddr_in6))); + end; + else begin + IPVersionUnsupported; + end; + end; + {$IFDEF DARWIN} // TODO: use HAS_SOCKET_NOSIGPIPE instead... + SetSocketOption(ASocket, Id_SOL_SOCKET, SO_NOSIGPIPE, 1); + {$ENDIF} +end; + +function TIdStackUnix.HostByName(const AHostName: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; +var + LI4 : array of THostAddr; + LI6 : array of THostAddr6; + LH4 : THostEntry; + LRetVal : Integer; +begin + case AIPVersion of + Id_IPv4 : + begin + if GetHostByName(AHostName, LH4) then + begin + Result := HostAddrToStr(LH4.Addr); + Exit; + end; + SetLength(LI4, 10); + LRetVal := ResolveName(AHostName, LI4); + if LRetVal < 1 then begin + raise EIdResolveError.CreateFmt(RSResolveError, [AHostName, 'Error', LRetVal]); {do not localize} + end; + Result := NetAddrToStr(LI4[0]); + end; + Id_IPv6 : + begin + SetLength(LI6, 10); + LRetVal := ResolveName6(AHostName, LI6); + if LRetVal < 1 then begin + raise EIdResolveError.CreateFmt(RSResolveError, [AHostName, LRetVal]); + end; + Result := NetAddrToStr6(LI6[0]); + end; + end; +end; + +function TIdStackUnix.ReadHostName: string; +begin + Result := GetHostName; +end; + +procedure TIdStackUnix.Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); +begin + CheckForSocketError(fpListen(ASocket, ABacklog)); +end; + +function TIdStackUnix.WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; + const ABufferLength, AFlags: Integer): Integer; +begin + //IdStackWindows is just: Result := Recv(ASocket, ABuffer, ABufferLength, AFlags); + Result := fpRecv(ASocket, @ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); +end; + +function TIdStackUnix.RecvFrom(const ASocket: TIdStackSocketHandle; var VBuffer; + const ALength, AFlags: Integer; var VIP: string; var VPort: TIdPort; + var VIPVersion: TIdIPVersion): Integer; +var + LiSize: tsocklen; + LAddr: sockaddr_in6; +begin + LiSize := SizeOf(sockaddr_in6); + Result := fpRecvFrom(ASocket, @VBuffer, ALength, AFlags or Id_MSG_NOSIGNAL, Psockaddr(@LAddr), @LiSize); + if Result >= 0 then + begin + case LAddr.sin6_family of + Id_PF_INET4 : + begin + with Psockaddr(@LAddr)^ do + begin + VIP := NetAddrToStr(sin_addr); + VPort := ntohs(sin_port); + end; + VIPVersion := Id_IPV4; + end; + Id_PF_INET6: + begin + with LAddr do + begin + VIP := NetAddrToStr6(sin6_addr); + VPort := ntohs(sin6_port); + end; + VIPVersion := Id_IPV6; + end; + end; + end; +end; + +function TIdStackUnix.ReceiveMsg(ASocket: TIdStackSocketHandle; + var VBuffer: TIdBytes; APkt: TIdPacketInfo): UInt32; +var + LIP : String; + LPort : TIdPort; + LIPVersion : TIdIPVersion; +begin + Result := RecvFrom(ASocket, VBuffer, Length(VBuffer), 0, LIP, LPort, LIPVersion); + APkt.Reset; + APkt.SourceIP := LIP; + APkt.SourcePort := LPort; + APkt.SourceIPVersion := LIPVersion; + APkt.DestIPVersion := LIPVersion; + + SetLength(VBuffer, Result); +end; +{The stuff below is commented out until I figure out what to do} +{var + LIP : String; + LPort : TIdPort; + LSize: UInt32; + LAddr: SockAddr_In6; + LMsg : msghdr; + LMsgBuf : BUF; + LControl : TIdBytes; + LCurCmsg : CMSGHDR; //for iterating through the control buffer + LCurPt : Pin_pktinfo; + LCurPt6 : Pin6_pktinfo; + LByte : PByte; + LDummy, LDummy2 : UInt32; +begin + //we call the macro twice because we specified two possible structures. + //Id_IPV6_HOPLIMIT and Id_IPV6_PKTINFO + LSize := CMSG_SPACE(SizeOf(Byte)) + CMSG_SPACE(SizeOf(in6_pktinfo)); + SetLength(LControl, LSize); + + LMsgBuf.len := Length(VBuffer); // Length(VMsgData); + LMsgBuf.buf := @VBuffer[0]; // @VMsgData[0]; + + FillChar(LMsg,SizeOf(LMsg),0); + + LMsg.lpBuffers := @LMsgBuf; + LMsg.dwBufferCount := 1; + + LMsg.Control.Len := LSize; + LMsg.Control.buf := @LControl[0]; + + LMsg.name := PSOCKADDR(@LAddr); + LMsg.namelen := SizeOf(LAddr); + CheckForSocketError( RecvMsg(ASocket,@LMsg,Result,@LDummy,LPwsaoverlapped_COMPLETION_ROUTINE(@LDummy2))); + + case LAddr.sin6_family of + Id_PF_INET4: begin + with PSOCKADDR(@LAddr)^do + begin + APkt.SourceIP := TranslateTInAddrToString(sin_addr,Id_IPv4); + APkt.SourcePort := NToHs(sin_port); + end; + APkt.SourceIPVersion := Id_IPv4; + end; + Id_PF_INET6: begin + with LAddr do + begin + APkt.SourceIP := TranslateTInAddrToString(sin6_addr, Id_IPv6); + APkt.SourcePort := NToHs(sin6_port); + end; + APkt.SourceIPVersion := Id_IPv6; + end; + else begin + Result := 0; // avoid warning + IPVersionUnsupported; + end; + end; + LCurCmsg := nil; + repeat + LCurCmsg := CMSG_NXTHDR(@LMsg,LCurCmsg); + if LCurCmsg = nil then + begin + break; + end; + case LCurCmsg^.cmsg_type of + IP_PKTINFO : //done this way because IPV6_PKTINF and IP_PKTINFO + //are both 19 + begin + case LAddr.sin6_family of + Id_PF_INET4: + begin + LCurPt := WSA_CMSG_DATA(LCurCmsg); + APkt.DestIP := GWindowsStack.TranslateTInAddrToString(LCurPt^.ipi_addr,Id_IPv4); + APkt.DestIF := LCurPt^.ipi_ifindex; + APkt.DestIPVersion := Id_IPv4; + end; + Id_PF_INET6: + begin + LCurPt6 := WSA_CMSG_DATA(LCurCmsg); + APkt.DestIP := GWindowsStack.TranslateTInAddrToString(LCurPt6^.ipi6_addr,Id_IPv6); + APkt.DestIF := LCurPt6^.ipi6_ifindex; + APkt.DestIPVersion := Id_IPv6; + end; + end; + end; + Id_IPV6_HOPLIMIT : + begin + LByte := PByte(WSA_CMSG_DATA(LCurCmsg)); + APkt.TTL := LByte^; + end; + end; + until False; } + +function TIdStackUnix.WSSend(ASocket: TIdStackSocketHandle; + const ABuffer; const ABufferLength, AFlags: Integer): Integer; +begin + //CC: Should Id_MSG_NOSIGNAL be included? + // Result := Send(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); + Result := CheckForSocketError(fpsend(ASocket, @ABuffer, ABufferLength, AFlags)); +end; + +procedure TIdStackUnix.WSSendTo(ASocket: TIdStackSocketHandle; + const ABuffer; const ABufferLength, AFlags: Integer; const AIP: string; + const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LAddr : sockaddr_in6; + LBytesOut: Integer; +begin + case AIPVersion of + Id_IPv4 : + begin + InitSockAddr(Psockaddr(@LAddr)^); + with Psockaddr(@LAddr)^ do + begin + sin_addr := StrToNetAddr(AIP); + sin_port := htons(APort); + end; + LBytesOut := fpSendTo(ASocket, @ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL, Psockaddr(@LAddr), SizeOf(sockaddr)); + end; + Id_IPv6: + begin + InitSockAddr_in6(LAddr); + with LAddr do + begin + sin6_addr := StrToHostAddr6(AIP); + //TranslateStringToTInAddr(AIP, sin6_addr, AIPVersion); + sin6_port := htons(APort); + end; + LBytesOut := fpSendTo(ASocket, @ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL, Psockaddr(@LAddr), SizeOf(sockaddr_in6)); + end; + else begin + LBytesOut := 0; // avoid warning + IPVersionUnsupported; + end; + end; + if LBytesOut = -1 then begin + // TODO: move this into RaiseLastSocketError() directly + if WSGetLastError() = Id_WSAEMSGSIZE then begin + raise EIdPackageSizeTooBig.Create(RSPackageSizeTooBig); + end else begin + RaiseLastSocketError; + end; + end else if LBytesOut <> ABufferLength then begin + raise EIdNotAllBytesSent.Create(RSNotAllBytesSent); + end; +end; + +procedure TIdStackUnix.{$IFDEF VCL_XE3_OR_ABOVE}GetSocketOption{$ELSE}WSGetSocketOption{$ENDIF} + (ASocket: TIdStackSocketHandle; ALevel: TIdSocketProtocol; AOptName: TIdSocketOption; + var AOptVal; var AOptLen: Integer); +var + LLen : TSockLen; +begin + LLen := AOptLen; + CheckForSocketError(fpGetSockOpt(ASocket, ALevel, AOptName, PAnsiChar(@AOptVal), @LLen)); + AOptLen := LLen; +end; + +procedure TIdStackUnix.{$IFDEF VCL_XE3_OR_ABOVE}SetSocketOption{$ELSE}WSSetSocketOption{$ENDIF} + (ASocket: TIdStackSocketHandle; ALevel: TIdSocketProtocol; AOptName: TIdSocketOption; + const AOptVal; const AOptLen: Integer); +begin + CheckForSocketError(fpSetSockOpt(ASocket, ALevel, AOptName, PAnsiChar(@AOptVal), AOptLen)); +end; + +function TIdStackUnix.WSGetLastError: Integer; +begin + //IdStackWindows just uses result := WSAGetLastError; + Result := GetLastError; //System.GetLastOSError; - FPC doesn't define it in System + if Result = ESysEPIPE then begin + Result := Id_WSAECONNRESET; + end; +end; + +procedure TIdStackUnix.WSSetLastError(const AErr : Integer); +begin + SetLastError(AErr); +end; + +function TIdStackUnix.WSSocket(AFamily, AStruct, AProtocol: Integer; + const ANonBlocking: Boolean = False): TIdStackSocketHandle; +var + LValue: UInt32; +begin + Result := fpsocket(AFamily, AStruct, AProtocol); + if Result <> Id_INVALID_SOCKET then begin + //SetBlocking(Result, not ANonBlocking); + LValue := UInt32(ANonBlocking); + fpioctl(Result, FIONBIO, @LValue); + end; +end; + +function TIdStackUnix.WSGetServByName(const AServiceName: string): TIdPort; +var + LS : TServiceEntry; +begin + if GetServiceByName(AServiceName, '', LS) then begin + Result := LS.Port; + end else begin + raise EIdInvalidServiceName.CreateFmt(RSInvalidServiceName, [AServiceName]); + end; +end; + +function TIdStackUnix.HostToNetwork(AValue: UInt16): UInt16; +begin + Result := htons(AValue); +end; + +function TIdStackUnix.NetworkToHost(AValue: UInt16): UInt16; +begin + Result := ntohs(AValue); +end; + +function TIdStackUnix.HostToNetwork(AValue: UInt32): UInt32; +begin + {$i IdRangeCheckingOff.inc} // disable range checking + Result := htonl(AValue); + {$i IdRangeCheckingOn.inc} // Restore range checking +end; + +function TIdStackUnix.NetworkToHost(AValue: UInt32): UInt32; +begin + {$i IdRangeCheckingOff.inc} // disable range checking + Result := ntohl(AValue); + // Restore range checking + {$i IdRangeCheckingOn.inc} // Restore range checking +end; + +{ RP - I'm not sure what endian Linux natively uses, thus the +check to see if the bytes need swapping or not ... } +function TIdStackUnix.HostToNetwork(AValue: TIdUInt64): TIdUInt64; +var + LParts: TIdUInt64Parts; + L: UInt32; +begin + {$i IdRangeCheckingOff.inc} // disable range checking + if (htonl(1) <> 1) then begin + LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + L := htonl(LParts.HighPart); + LParts.HighPart := htonl(LParts.LowPart); + LParts.LowPart := L; + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; + end else begin + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + end; + {$i IdRangeCheckingOn.inc} // Restore range checking +end; + +function TIdStackUnix.NetworkToHost(AValue: TIdUInt64): TIdUInt64; +var + LParts: TIdUInt64Parts; + L: UInt32; +begin + {$i IdRangeCheckingOff.inc} // disable range checking + if (ntohl(1) <> 1) then begin + LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + L := ntohl(LParts.HighPart); + LParts.HighPart := NetworkToHost(LParts.LowPart); + LParts.LowPart := L; + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; + end else begin + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + end; + {$i IdRangeCheckingOn.inc} // Restore range checking +end; + +{$IFDEF HAS_getifaddrs} +// TODO: does FreePascal already define these anywhere? + +type + pifaddrs = ^ifaddrs; + ifaddrs = record + ifa_next: pifaddrs; { Pointer to next struct } + ifa_name: PIdAnsiChar; { Interface name } +// Solaris ifaddrs struct implements 64bit ifa_flags. (Details: https://docs.oracle.com/cd/E88353_01/html/E37843/getifaddrs-3c.html) +{$IFDEF SOLARIS} + ifa_flags: UInt64; { Interface flags } +{$ELSE} + ifa_flags: Cardinal; { Interface flags } +{$ENDIF} + ifa_addr: psockaddr; { Interface address } + ifa_netmask: psockaddr; { Interface netmask } + ifa_broadaddr: psockaddr; { Interface broadcast address } + ifa_dstaddr: psockaddr; { P2P interface destination } + ifa_data: Pointer; { Address specific data } + end; + +const + IFF_LOOPBACK = $8; + +function getifaddrs(var ifap: pifaddrs): Integer; cdecl; external 'libc.so' name 'getifaddrs'; {do not localize} +procedure freeifaddrs(ifap: pifaddrs); cdecl; external 'libc.so' name 'freeifaddrs'; {do not localize} + {$IFDEF HAS_if_nametoindex} +procedure if_nametoindex(const ifname: PIdAnsiChar): UInt32; cdecl; external 'libc.so' name 'if_nametoindex'; {do not localize} + {$ENDIF} + +type + TIdStackLocalAddressAccess = class(TIdStackLocalAddress) + end; +{$ENDIF} + +procedure TIdStackUnix.GetLocalAddressList(AAddresses: TIdStackLocalAddressList); +var + {$IFDEF HAS_getifaddrs} + LAddrList, LAddrInfo: pifaddrs; + LSubNetStr: String; + LAddress: TIdStackLocalAddress; + LName: string; + {$ELSE} + LI4 : array of THostAddr; + LI6 : array of THostAddr6; + i : Integer; + LHostName : String; + {$ENDIF} +begin + // TODO: Using gethostname() and ResolveName() like this may not always + // return just the machine's IP addresses. Technically speaking, they will + // return the local hostname, and then return the address(es) to which that + // hostname resolves. It is possible for a machine to (a) be configured such + // that its name does not resolve to an IP, or (b) be configured such that + // its name resolves to multiple IPs, only one of which belongs to the local + // machine. For better results, we should use getifaddrs() on platforms that + // support it... + + {$IFDEF HAS_getifaddrs} + + if getifaddrs(LAddrList) = 0 then // TODO: raise an exception if it fails + try + AAddresses.BeginUpdate; + try + LAddrInfo := LAddrList; + repeat + if (LAddrInfo^.ifa_addr <> nil) and ((LAddrInfo^.ifa_flags and IFF_LOOPBACK) = 0) then + begin + LAddress := nil; + case LAddrInfo^.ifa_addr^.sa_family of + Id_PF_INET4: begin + if LAddrInfo^.ifa_netmask <> nil then begin + LSubNetStr := TranslateTInAddrToString( PSockAddr_In(LAddrInfo^.ifa_netmask)^.sin_addr, Id_IPv4); + end else begin + LSubNetStr := ''; + end; + LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, TranslateTInAddrToString( PSockAddr_In(LAddrInfo^.ifa_addr)^.sin_addr, Id_IPv4), LSubNetStr); + end; + Id_PF_INET6: begin + LAddress := TIdStackLocalAddressIPv6.Create(AAddresses, TranslateTInAddrToString( PSockAddr_In6(LAddrInfo^.ifa_addr)^.sin6_addr, Id_IPv6)); + end; + end; + if LAddress <> nil then begin + LName := String(LAddrInfo^.ifa_name); + {$I IdObjectChecksOff.inc} + TIdStackLocalAddressAccess(LAddress).FDescription := LName; + TIdStackLocalAddressAccess(LAddress).FFriendlyName := LName; + TIdStackLocalAddressAccess(LAddress).FInterfaceName := LName; + {$IFDEF HAS_if_nametoindex} + TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := if_nametoindex(LAddrInfo^.ifa_name); + {$ENDIF} + {$I IdObjectChecksOn.inc} + end; + end; + LAddrInfo := LAddrInfo^.ifa_next; + until LAddrInfo = nil; + finally + AAddresses.EndUpdate; + end; + finally + freeifaddrs(LAddrList); + end; + + {$ELSE} + + LHostName := GetHostName; + if LHostName = '' then begin + RaiseLastSocketError; + end; + AAddresses.BeginUpdate; + try + if ResolveName(LHostName, LI4) = 0 then + begin + for i := Low(LI4) to High(LI4) do + begin + TIdStackLocalAddressIPv4.Create(AAddresses, NetAddrToStr(LI4[i]), ''); // TODO: SubNet + end; + end; + if ResolveName6(LHostName, LI6) = 0 then + begin + for i := Low(LI6) to High(LI6) do + begin + TIdStackLocalAddressIPv6.Create(AAddresses, NetAddrToStr6(LI6[i])); + end; + end; + finally + AAddresses.EndUpdate; + end; + + {$ENDIF} +end; + +function TIdStackUnix.HostByAddress(const AAddress: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; +var + LI : Array of string; + LAddr4: THostAddr; + LAddr6: THostAddr6; +begin + Result := ''; + case AIPVersion of + Id_IPv4 : + begin + LAddr4 := StrToNetAddr(AAddress); + if ResolveAddress(LAddr4, LI) = 0 then begin + Result := LI[0]; + end; + end; + Id_IPv6 : + begin + LAddr6 := StrToNetAddr6(AAddress); + if ResolveAddress6(LAddr6, LI) = 0 then begin + Result := LI[0]; + end; + end; + end; +end; + +function TIdStackUnix.WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; +begin + Result := fpShutdown(ASocket, AHow); +end; + +procedure TIdStackUnix.Disconnect(ASocket: TIdStackSocketHandle); +begin + // Windows uses Id_SD_Send, Linux should use Id_SD_Both + WSShutdown(ASocket, Id_SD_Both); + // SO_LINGER is false - socket may take a little while to actually close after this + WSCloseSocket(ASocket); +end; + +procedure TIdStackUnix.GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); +var + i: tsocklen; + LAddr: sockaddr_in6; +begin + i := SizeOf(LAddr); + CheckForSocketError(fpGetPeerName(ASocket, @LAddr, @i)); + case LAddr.sin6_family of + PF_INET: begin + with Psockaddr(@LAddr)^ do + begin + VIP := NetAddrToStr(sin_addr); + VPort := ntohs(sin_port); + end; + VIPVersion := Id_IPv4; + end; + PF_INET6: begin + with LAddr do + begin + VIP := NetAddrToStr6(sin6_addr); + VPort := ntohs(sin6_port); + end; + VIPVersion := Id_IPv6; + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +procedure TIdStackUnix.GetSocketName(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); +var + i: tsocklen; + LAddr: sockaddr_in6; +begin + i := SizeOf(LAddr); + CheckForSocketError(fpGetSockName(ASocket, @LAddr, @i)); + case LAddr.sin6_family of + PF_INET : begin + with Psockaddr(@LAddr)^ do + begin + VIP := NetAddrToStr(sin_addr); + VPort := ntohs(sin_port); + end; + VIPVersion := Id_IPV4; + end; + PF_INET6: begin + with LAddr do + begin + VIP := NetAddrToStr6(sin6_addr); + VPort := ntohs(sin6_port); + end; + VIPVersion := Id_IPv6; + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +procedure TIdStackUnix.AddServByPortToList(const APortNumber: TIdPort; AAddresses: TStrings); +var + LS : TServiceEntry; +begin + if GetServiceByPort(APortNumber, '', LS) then begin + AAddresses.Add(LS.Name); + end; +end; + +function TIdStackUnix.WSTranslateSocketErrorMsg(const AErr: Integer): string; +begin + //we override this function for the herr constants that + //are returned by the DNS functions + //note that this is not really applicable because we are using some + //FPC functions that do direct DNS lookups without the standard Unix + //DNS functions. It sounds odd but I think there's a good reason for it. + Result := inherited WSTranslateSocketErrorMsg(AErr); +end; + +procedure TIdStackUnix.SetBlocking(ASocket: TIdStackSocketHandle; + const ABlocking: Boolean); +var + LValue: UInt32; +begin + LValue := UInt32(not ABlocking); + CheckForSocketError(fpioctl(ASocket, FIONBIO, @LValue)); +end; + +function TIdStackUnix.WouldBlock(const AResult: Integer): Boolean; +begin + // using if-else instead of in..range because EAGAIN and EWOULDBLOCK + // have often the same value and so FPC might report a range error + Result := (AResult = Id_WSAEAGAIN) or + (AResult = Id_WSAEWOULDBLOCK) or + (AResult = Id_WSAEINPROGRESS); +end; + +function TIdStackUnix.SupportsIPv4: Boolean; +//In Windows, this does something else. It checks the LSP's installed. +begin + Result := CheckIPVersionSupport(Id_IPv4); +end; + +function TIdStackUnix.SupportsIPv6: Boolean; +//In Windows, this does something else. It checks the LSP's installed. +begin + Result := CheckIPVersionSupport(Id_IPv6); +end; + +function TIdStackUnix.CheckIPVersionSupport(const AIPVersion: TIdIPVersion): Boolean; +var + LTmpSocket: TIdStackSocketHandle; +begin + // TODO: on nix systems (or maybe just Linux?), an alternative would be to + // check for the existance of the '/proc/net/if_inet6' kernel pseudo-file + LTmpSocket := WSSocket(IdIPFamily[AIPVersion], Integer(Id_SOCK_STREAM), Id_IPPROTO_IP); + Result := LTmpSocket <> Id_INVALID_SOCKET; + if Result then begin + WSCloseSocket(LTmpSocket); + end; +end; + +procedure TIdStackUnix.WriteChecksum(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort; const AIPVersion: TIdIPVersion); +begin + case AIPVersion of + Id_IPv4 : CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(VBuffer)), VBuffer, AOffset); + Id_IPv6 : WriteChecksumIPv6(s, VBuffer, AOffset, AIP, APort); + else + IPVersionUnsupported; + end; +end; + +procedure TIdStackUnix.WriteChecksumIPv6(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort); +begin +//we simply request that the kernal write the checksum when the data +//is sent. All of the parameters required are because Windows is bonked +//because it doesn't have the IPV6CHECKSUM socket option meaning we have +//to querry the network interface in TIdStackWindows -- yuck!! + SetSocketOption(s, Id_IPPROTO_IPV6, IPV6_CHECKSUM, AOffset); +end; + +function TIdStackUnix.IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; + var arg: UInt32): Integer; +begin + Result := fpioctl(s, cmd, @arg); +end; +(* +Why did I remove this again? + + 1) it sends SIGPIPE even if the socket is created with the no-sigpipe bit set + that could be solved by blocking sigpipe within this thread + This is probably a bug in the Linux kernel, but we could work around it + by blocking that signal for the time of sending the file (just get the + sigprocmask, see if pipe bit is set, if not set it and remove again after + sending the file) + +But the more serious reason is another one, which exists in Windows too: + 2) I think that ServeFile is misdesigned: + ServeFile does not raise an exception if it didn't send all the bytes. + Now what happens if I have OnExecute assigned like this + AThread.Connection.ServeFile('...', True); // <-- true to send via kernel + is that it will return 0, but notice that in this case I didn't ask for the + result. Net effect is that the thread will loop in OnExecute even if the + socket is long gone. This doesn't fit Indy semantics at all, exceptions are + always raised if the remote end disconnects. Even if I would do + AThread.Connection.ServeFile('...', False); + then it would raise an exception. + I think this is a big flaw in the design of the ServeFile function. + Maybe GServeFile should only return the bytes sent, but then + TCPConnection.ServeFile() should raise an exception if GServeFile didn't + send all the bytes. + +JM Berg, 2002-09-09 + +function ServeFile(ASocket: TIdStackSocketHandle; AFileName: string): UInt32; +var + LFileHandle: integer; + offset: integer; + stat: _stat; +begin + LFileHandle := open(PChar(AFileName), O_RDONLY); + try + offset := 0; + fstat(LFileHandle, stat); + Result := sendfile(ASocket, LFileHandle, offset, stat.st_size); +//** if Result = UInt32(-1) then RaiseLastOSError; + finally libc.__close(LFileHandle); end; +end; +*) + +procedure TIdStackUnix.SetKeepAliveValues(ASocket: TIdStackSocketHandle; + const AEnabled: Boolean; const ATimeMS, AInterval: Integer); +begin + inherited; // turn SO_KEEPALIVE on/off first... + // TODO: remove below, as it should be handled by TIdStack.SetKeepAliveValues() now... + if AEnabled then begin + {$IFDEF HAS_TCP_KEEPIDLE} + SetSocketOption(ASocket, Id_SOL_TCP, Id_TCP_KEEPIDLE, ATimeMS div MSecsPerSec); + {$ENDIF} + {$IFDEF HAS_TCP_KEEPINTVL} + SetSocketOption(ASocket, Id_SOL_TCP, Id_TCP_KEEPINTVL, AInterval div MSecsPerSec); + {$ENDIF} + end; +end; + +{ TIdSocketListUnix } + +type + // TODO: rewrite this to use poll() instead of select(), similar to TIdSocketListVCLPosix + TIdSocketListUnix = class (TIdSocketList) + protected + FCount: Integer; + FFDSet: TFDSet; + // + class function FDSelect(AReadSet: PFDSet; AWriteSet: PFDSet; AExceptSet: PFDSet; + const ATimeout: Integer = IdTimeoutInfinite): Integer; + function GetItem(AIndex: Integer): TIdStackSocketHandle; override; + public + procedure Add(AHandle: TIdStackSocketHandle); override; + procedure Remove(AHandle: TIdStackSocketHandle); override; + function Count: Integer; override; + procedure Clear; override; + function Clone: TIdSocketList; override; + function ContainsSocket(AHandle: TIdStackSocketHandle): Boolean; override; + procedure GetFDSet(var VSet: TFDSet); + procedure SetFDSet(var VSet: TFDSet); + class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; + AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + function SelectReadList(var VSocketList: TIdSocketList; + const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + end; + +procedure TIdSocketListUnix.Add(AHandle: TIdStackSocketHandle); +begin + Lock; + try + if fpFD_ISSET(AHandle, FFDSet) = 0 then begin + if AHandle >= FD_SETSIZE then begin + raise EIdStackSetSizeExceeded.Create(RSSetSizeExceeded); + end; + fpFD_SET(AHandle, FFDSet); + Inc(FCount); + end; + finally + Unlock; + end; +end;// + +procedure TIdSocketListUnix.Clear; +begin + Lock; + try + fpFD_ZERO(FFDSet); + FCount := 0; + finally + Unlock; + end; +end; + +function TIdSocketListUnix.ContainsSocket(AHandle: TIdStackSocketHandle): Boolean; +begin + Lock; + try + Result := fpFD_ISSET(AHandle, FFDSet) > 0; + finally + Unlock; + end; +end; + +function TIdSocketListUnix.Count: Integer; +begin + Lock; + try + Result := FCount; + finally + Unlock; + end; +end;// + +class function TIdSocketListUnix.FDSelect(AReadSet, AWriteSet, AExceptSet: PFDSet; + const ATimeout: Integer): Integer; +var + LTime: TTimeVal; + LTimePtr: PTimeVal; +begin + if ATimeout = IdTimeoutInfinite then begin + LTimePtr := nil; + end else begin + LTime.tv_sec := ATimeout div 1000; + LTime.tv_usec := (ATimeout mod 1000) * 1000; + LTimePtr := @LTime; + end; + // TODO: calculate the actual nfds value based on the Sets provided... + // TODO: use poll() instead of select() to remove limit on how many sockets can be queried + Result := fpSelect(FD_SETSIZE, AReadSet, AWriteSet, AExceptSet, LTimePtr); +end; + +procedure TIdSocketListUnix.GetFDSet(var VSet: TFDSet); +begin + Lock; + try + VSet := FFDSet; + finally + Unlock; + end; +end; + +function TIdSocketListUnix.GetItem(AIndex: Integer): TIdStackSocketHandle; +var + LIndex, i: Integer; +begin + Result := 0; + // TODO: is this missing Lock/Unlock calls? + LIndex := 0; + //? use FMaxHandle div x + for i:= 0 to __FD_SETSIZE - 1 do begin + if fpFD_ISSET(i, FFDSet) = 1 then begin + if LIndex = AIndex then begin + Result := i; + Break; + end; + Inc(LIndex); + end; + end; +end; + +procedure TIdSocketListUnix.Remove(AHandle: TIdStackSocketHandle); +begin + Lock; + try + if fpFD_ISSET(AHandle, FFDSet) = 1 then + begin + Dec(FCount); + fpFD_CLR(AHandle, FFDSet); + end; + finally + Unlock; + end; +end;// + +procedure TIdSocketListUnix.SetFDSet(var VSet: TFDSet); +begin + Lock; + try + FFDSet := VSet; + finally + Unlock; + end; +end; + +class function TIdSocketListUnix.Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; + AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; +var + LReadSet: TFDSet; + LWriteSet: TFDSet; + LExceptSet: TFDSet; + LPReadSet: PFDSet; + LPWriteSet: PFDSet; + LPExceptSet: PFDSet; + + procedure ReadSet(AList: TIdSocketList; var ASet: TFDSet; var APSet: PFDSet); + begin + if AList <> nil then begin + TIdSocketListUnix(AList).GetFDSet(ASet); + APSet := @ASet; + end else begin + APSet := nil; + end; + end; + +begin + ReadSet(AReadList, LReadSet, LPReadSet); + ReadSet(AWriteList, LWriteSet, LPWriteSet); + ReadSet(AExceptList, LExceptSet, LPExceptSet); + // + Result := FDSelect(LPReadSet, LPWriteSet, LPExceptSet, ATimeout) <> 0; + // + if AReadList <> nil then begin + TIdSocketListUnix(AReadList).SetFDSet(LReadSet); + end; + if AWriteList <> nil then begin + TIdSocketListUnix(AWriteList).SetFDSet(LWriteSet); + end; + if AExceptList <> nil then begin + TIdSocketListUnix(AExceptList).SetFDSet(LExceptSet); + end; +end; + +function TIdSocketListUnix.SelectRead(const ATimeout: Integer): Boolean; +var + LSet: TFDSet; +begin + Lock; + try + LSet := FFDSet; + // select() updates this structure on return, + // so we need to copy it each time we need it + finally + Unlock; + end; + Result := FDSelect(@LSet, nil, nil, ATimeout) > 0; +end; + +function TIdSocketListUnix.SelectReadList(var VSocketList: TIdSocketList; + const ATimeout: Integer = IdTimeoutInfinite): Boolean; +var + LSet: TFDSet; +begin + Lock; + try + LSet := FFDSet; + // select() updates this structure on return, + // so we need to copy it each time we need it + finally + Unlock; + end; + Result := FDSelect(@LSet, nil, nil, ATimeout) > 0; + if Result then begin + if VSocketList = nil then begin + VSocketList := TIdSocketList.CreateSocketList; + end; + TIdSocketListUnix(VSocketList).SetFDSet(LSet); + end; +end; + +function TIdSocketListUnix.Clone: TIdSocketList; +begin + Result := TIdSocketListUnix.Create; + try + Lock; + try + TIdSocketListUnix(Result).SetFDSet(FFDSet); + finally + Unlock; + end; + except + FreeAndNil(Result); + raise; + end; +end; + +initialization + GSocketListClass := TIdSocketListUnix; + +end. + diff --git a/Lib/System/IdStackVCLPosix.pas b/Lib/System/IdStackVCLPosix.pas index ce2b3783d..042525d6f 100644 --- a/Lib/System/IdStackVCLPosix.pas +++ b/Lib/System/IdStackVCLPosix.pas @@ -1,1594 +1,1594 @@ -unit IdStackVCLPosix; - -interface - -{$I IdCompilerDefines.inc} - -{IMPORTANT!!! - -Platform warnings in this unit should be disabled because Indy we have no -intention of porting this unit to Windows or any non-Unix-like operating system. - -Any differences between Unix-like operating systems have to dealt with in other -ways. -} - -{$I IdSymbolPlatformOff.inc} -{$I IdUnitPlatformOff.inc} - -uses - Classes, - IdCTypes, - Posix.SysSelect, - Posix.SysSocket, - Posix.SysTime, - IdStack, - IdStackConsts, - IdGlobal, - IdStackBSDBase; - -type - {$IFDEF USE_VCL_POSIX} - {$IFDEF ANDROID} - EIdAccessWifiStatePermissionNeeded = class(EIdAndroidPermissionNeeded); - EIdAccessNetworkStatePermissionNeeded = class(EIdAndroidPermissionNeeded); - {$ENDIF} - {$ENDIF} - - TIdStackVCLPosix = class(TIdStackBSDBase) - protected - procedure WriteChecksumIPv6(s: TIdStackSocketHandle; var VBuffer: TIdBytes; - const AOffset: Integer; const AIP: String; const APort: TIdPort); - function GetLastError: Integer; - procedure SetLastError(const AError: Integer); - function HostByName(const AHostName: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; - function ReadHostName: string; override; - function WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; override; - function WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; - const ABufferLength, AFlags: Integer): Integer; override; - function WSSend(ASocket: TIdStackSocketHandle; const ABuffer; - const ABufferLength, AFlags: Integer): Integer; override; - function WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; override; - {$IFNDEF VCL_XE3_OR_ABOVE} - procedure WSGetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; - procedure WSSetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; - {$ENDIF} - public - constructor Create; override; - destructor Destroy; override; - procedure SetBlocking(ASocket: TIdStackSocketHandle; const ABlocking: Boolean); override; - function WouldBlock(const AResult: Integer): Boolean; override; - function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; - var VIPVersion: TIdIPVersion): TIdStackSocketHandle; override; - procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - function HostByAddress(const AAddress: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; - function WSGetLastError: Integer; override; - procedure WSSetLastError(const AErr : Integer); override; - function WSGetServByName(const AServiceName: string): TIdPort; override; - procedure AddServByPortToList(const APortNumber: TIdPort; AAddresses: TStrings); override; - procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; - procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; - procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); override; - function HostToNetwork(AValue: UInt16): UInt16; override; - function NetworkToHost(AValue: UInt16): UInt16; override; - function HostToNetwork(AValue: UInt32): UInt32; override; - function NetworkToHost(AValue: UInt32): UInt32; override; - function HostToNetwork(AValue: TIdUInt64): TIdUInt64; override; - function NetworkToHost(AValue: TIdUInt64): TIdUInt64; override; - function RecvFrom(const ASocket: TIdStackSocketHandle; - var VBuffer; const ALength, AFlags: Integer; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; override; - function ReceiveMsg(ASocket: TIdStackSocketHandle; - var VBuffer: TIdBytes; APkt: TIdPacketInfo): UInt32; override; - procedure WSSendTo(ASocket: TIdStackSocketHandle; const ABuffer; - const ABufferLength, AFlags: Integer; const AIP: string; const APort: TIdPort; - AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - function WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; - const ANonBlocking: Boolean = False): TIdStackSocketHandle; override; - procedure Disconnect(ASocket: TIdStackSocketHandle); override; - {$IFDEF VCL_XE3_OR_ABOVE} - procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; - procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; - {$ENDIF} - function SupportsIPv4: Boolean; overload; override; - function SupportsIPv6: Boolean; overload; override; - function CheckIPVersionSupport(const AIPVersion: TIdIPVersion): boolean; override; - //In Windows, this writes a checksum into a buffer. In Linux, it would probably - //simply have the kernal write the checksum with something like this (RFC 2292): -// -// int offset = 2; -// setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)); -// -// Note that this should be called - //IMMEDIATELY before you do a SendTo because the Local IPv6 address might change - - procedure WriteChecksum(s : TIdStackSocketHandle; var VBuffer : TIdBytes; - const AOffset : Integer; const AIP : String; const APort : TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; - var arg: UInt32): Integer; override; - - procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); override; - end; - -implementation - -{$O-} - -uses - IdResourceStrings, - IdResourceStringsUnix, - IdResourceStringsVCLPosix, - IdException, - IdVCLPosixSupplemental, - Posix.Base, - Posix.ArpaInet, - Posix.Errno, - Posix.NetDB, - {$IFDEF HAS_getifaddrs} - Posix.NetIf, - {$ENDIF} - Posix.NetinetIn, - Posix.StrOpts, - Posix.SysTypes, - Posix.SysUio, - Posix.Unistd, - Posix.Fcntl, - {$IFDEF HAS_UNIT_Generics_Collections} - System.Generics.Collections, - {$ENDIF} - SysUtils; - - {$UNDEF HAS_MSG_NOSIGNAL} - {$IFDEF LINUX} //this LINUX ifdef is deliberate - {$DEFINE HAS_MSG_NOSIGNAL} - {$ENDIF} - - -const - {$IFDEF HAS_MSG_NOSIGNAL} - //fancy little trick since OS X does not have MSG_NOSIGNAL - Id_MSG_NOSIGNAL = MSG_NOSIGNAL; - {$ELSE} - Id_MSG_NOSIGNAL = 0; - {$ENDIF} - Id_WSAEPIPE = EPIPE; - - // TODO: is there an RTL unit that already defines these constants? - POLLIN = $0001; - POLLPRI = $0002; - POLLOUT = $0004; - POLLERR = $0008; - POLLHUP = $0010; - POLLNVAL = $0020; - POLLRDNORM = $0040; - POLLRDBAND = $0080; - POLLWRNORM = $0100; - POLLWRBAND = $0200; - POLLMSG = $0400; - POLLREMOVE = $1000; - POLLRDHUP = $2000; - - -//helper functions for some structs - -{Note: These hide an API difference in structures. - -BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit -word to an 8 bit byteee and an 8 bit byte feild named sa_len was added. - -} -procedure InitSockAddr_In(var VSock : SockAddr_In); -{$IFDEF USE_INLINE} inline; {$ENDIF} -begin - FillChar(VSock, SizeOf(SockAddr_In), 0); - VSock.sin_family := PF_INET; - {$IFDEF SOCK_HAS_SINLEN} - VSock.sin_len := SizeOf(SockAddr_In); - {$ENDIF} -end; - -procedure InitSockAddr_in6(var VSock : SockAddr_in6); -{$IFDEF USE_INLINE} inline; {$ENDIF} -begin - FillChar(VSock, SizeOf(SockAddr_in6), 0); - {$IFDEF SOCK_HAS_SINLEN} - VSock.sin6_len := SizeOf(SockAddr_in6); - {$ENDIF} - VSock.sin6_family := PF_INET6; -end; -// - -{ TIdSocketListVCLPosix } - -type - // TODO: is there an RTL unit that already defines these types? - ppollfd = ^pollfd; - pollfd = record - fd : TIdStackSocketHandle; - events : Int16; - revents : Int16; - end; - pollfdArray = array of pollfd; - nfds_t = TIdC_ULONG; // TODO: some platforms use 'C_UINT' instead! How to detect those? - - {$IFDEF HAS_GENERICS_TList} - TIdStackSocketHandleList = TList; - {$ELSE} - // TODO: flesh out to match TList for non-Generics compilers - TIdStackSocketHandleList = TList; - {$ENDIF} - - TIdSocketListVCLPosix = class(TIdSocketList) - protected - FSockets: TIdStackSocketHandleList; - // - class function FDPoll(ASet: ppollfd; const ACount: nfds_t; const ATimeout: Integer): Boolean; - function GetItem(AIndex: Integer): TIdStackSocketHandle; override; - procedure GetPollFds(var VSet: pollfdArray; var VOffset: nfds_t; const AEvents: Int16); - procedure SetPollFds(const VSet: pollfdArray; const AEvents: Int16); - public - constructor Create; override; - destructor Destroy; override; - procedure Add(AHandle: TIdStackSocketHandle); override; - procedure Remove(AHandle: TIdStackSocketHandle); override; - function Count: Integer; override; - procedure Clear; override; - function Clone: TIdSocketList; override; - function ContainsSocket(AHandle: TIdStackSocketHandle): Boolean; override; - class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; - AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - function SelectReadList(var VSocketList: TIdSocketList; - const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - end; - -constructor TIdSocketListVCLPosix.Create; -begin - inherited; - FSockets := TIdStackSocketHandleList.Create; -end; - -destructor TIdSocketListVCLPosix.Destroy; -begin - FSockets.Free; - inherited; -end; - -procedure TIdSocketListVCLPosix.Add(AHandle: TIdStackSocketHandle); -begin - Lock; - try - {$IFDEF HAS_GENERICS_TList} - if not FSockets.Contains(AHandle) then begin - FSockets.Add(AHandle); - end; - {$ELSE} - if FSockets.IndexOf(Pointer(AHandle)) = -1 then begin - FSockets.Add(Pointer(AHandle)); - end; - {$ENDIF} - finally - Unlock; - end; -end; - -procedure TIdSocketListVCLPosix.Clear; -begin - Lock; - try - FSockets.Clear; - finally - Unlock; - end; -end; - -function TIdSocketListVCLPosix.Clone: TIdSocketList; -begin - Result := TIdSocketListVCLPosix.Create; - try - Lock; - try - {$IFDEF HAS_GENERICS_TList} - TIdSocketListVCLPosix(Result).FSockets.AddRange(FSockets); - {$ELSE} - TIdSocketListVCLPosix(Result).FSockets.Assign(FSockets); - {$ENDIF} - finally - Unlock; - end; - except - FreeAndNil(Result); - raise; - end; -end; - -function TIdSocketListVCLPosix.ContainsSocket( - AHandle: TIdStackSocketHandle): Boolean; -begin - Lock; - try - {$IFDEF HAS_GENERICS_TList} - Result := FSockets.Contains(AHandle); - {$ELSE} - Result := FSockets.IndexOf(Pointer(AHandle)) <> -1; - {$ENDIF} - finally - Unlock; - end; -end; - -function TIdSocketListVCLPosix.Count: Integer; -begin - Lock; - try - Result := FSockets.Count; - finally - Unlock; - end; -end; - -// TODO: is there an RTL unit that already defines this? -function poll(Ptr: ppollfd; nfds : nfds_t; timeout : Integer) : Integer; cdecl; external libc name _PU+'poll'; - -class function TIdSocketListVCLPosix.FDPoll(ASet: ppollfd; - const ACount: nfds_t; const ATimeout: Integer): Boolean; -var - LTimeout: Integer; -begin - if ATimeout = IdTimeoutInfinite then begin - LTimeout := -1; - end else begin - LTimeout := ATimeout; - end; - Result := poll(ASet, ACount, LTimeout) > 0; -end; - -procedure TIdSocketListVCLPosix.GetPollFds(var VSet: pollfdArray; - var VOffset: nfds_t; const AEvents: Int16); -var - LPollFD: ppollfd; - I: Integer; -begin - Lock; - try - for I := 0 to FSockets.Count-1 do begin - LPollFD := @VSet[VOffset]; - {$IFDEF HAS_GENERICS_TList} - LPollFD^.fd := FSockets[i]; - {$ELSE} - LPollFD^.fd := TIdStackSocketHandle(FSockets[i]); - {$ENDIF} - LPollFD^.events := AEvents; - LPollFD^.revents := 0; - Inc(VOffset); - end; - finally - Unlock; - end; -end; - -function TIdSocketListVCLPosix.GetItem(AIndex: Integer): TIdStackSocketHandle; -begin - Lock; - try - if (AIndex >= 0) and (AIndex < FSockets.Count) then begin - {$IFDEF HAS_GENERICS_TList} - Result := FSockets[AIndex]; - {$ELSE} - Result := TIdStackSocketHandle(FSockets[AIndex]); - {$ENDIF} - end else begin - Result := Id_INVALID_SOCKET; - end; - finally - Unlock; - end; -end; - -procedure TIdSocketListVCLPosix.Remove(AHandle: TIdStackSocketHandle); -begin - Lock; - try - {$IFDEF HAS_GENERICS_TList} - FSockets.Remove(AHandle); - {$ELSE} - FSockets.Remove(Pointer(AHandle)); - {$ENDIF} - finally - Unlock; - end; -end; - -class function TIdSocketListVCLPosix.Select(AReadList, AWriteList, - AExceptList: TIdSocketList; const ATimeout: Integer): Boolean; -var - LPollFds: pollfdArray; - LOffset: nfds_t; - - function SetCount(AList: TIdSocketList) : Integer; - begin - if AList <> nil then begin - Result := AList.Count; - end else begin - Result := 0; - end; - end; - - procedure ReadSet(AList: TIdSocketList; const AEvents: Int16); - begin - if AList <> nil then begin - TIdSocketListVCLPosix(AList).GetPollFds(LPollFds, LOffset, AEvents); - end; - end; - -begin - SetLength(LPollFds, SetCount(AReadList) + SetCount(AWriteList) + SetCount(AExceptList)); - - LOffset := 0; - ReadSet(AReadList, POLLIN or POLLRDHUP); - ReadSet(AWriteList, POLLOUT); - ReadSet(AExceptList, POLLPRI); - // - Result := FDPoll(ppollfd(LPollFds), LOffset, ATimeout); - // - if AReadList <> nil then begin - TIdSocketListVCLPosix(AReadList).SetPollFds(LPollFds, POLLIN or POLLHUP); - end; - if AWriteList <> nil then begin - TIdSocketListVCLPosix(AWriteList).SetPollFds(LPollFds, POLLOUT); - end; - if AExceptList <> nil then begin - TIdSocketListVCLPosix(AExceptList).SetPollFds(LPollFds, POLLPRI); - end; -end; - -function TIdSocketListVCLPosix.SelectRead(const ATimeout: Integer): Boolean; -var - LPollFds: pollfdArray; - LCount: nfds_t; -begin - Lock; - try - SetLength(LPollFds, FSockets.Count); - LCount := GetPollFds(LPollFds, 0, POLLIN or POLLRDHUP); - finally - Unlock; - end; - Result := FDPoll(ppollfd(LPollFds), LCount, ATimeout); -end; - -function TIdSocketListVCLPosix.SelectReadList(var VSocketList: TIdSocketList; - const ATimeout: Integer): Boolean; -var - LPollFds: pollfdArray; - LCount: nfds_t; -begin - Lock; - try - SetLength(LPollFds, FSockets.Count); - LCount := GetPollFds(LPollFds, 0, POLLIN or POLLRDHUP); - finally - Unlock; - end; - Result := FDPoll(ppollfd(LPollFds), LCount, ATimeout); - if Result then begin - if VSocketList = nil then begin - VSocketList := TIdSocketList.CreateSocketList; - end; - TIdSocketListVCLPosix(VSocketList).SetPollFds(LPollFds, POLLIN or POLLRDHUP); - end; -end; - -procedure TIdSocketListVCLPosix.SetPollFds(const VSet: pollfdArray; - const AEvents: Int16); -var - LPollFD: ppollfd; - I: Integer; -begin - Lock; - try - FSockets.Clear; - for I := Low(VSet) to High(VSet) do begin - LPollFD := @VSet[I]; - if (AEvents = 0) or ((LPollFD^.revents and AEvents) <> 0) then begin - {$IFDEF HAS_GENERICS_TList} - FSockets.Add(LPollFD^.fd); - {$ELSE} - FSockets.Add(Pointer(LPollFD^.fd)); - {$ENDIF} - end; - end; - finally - Unlock; - end; -end; - -{ TIdStackVCLPosix } - -{ -IMPORTANT!!! - -Throughout much of this code, you will see stuff such as: - -var - LAddrStore: sockaddr_storage; - LAddrIPv4 : SockAddr_In absolute LAddrStore; - LAddrIPv6 : sockaddr_in6 absolute LAddrStore; - LAddr : sockaddr absolute LAddrStore; - -This is just a fancy way to do typecasting with various types of address type. -Many functions take a sockaddr parameter but that parameter is typecast for various -address types. The structures mentioned above are designed just for such -typecasting. The reason we use sockaddr_storage instead of sockaddr is that -we need something that is guaranteed to be able to contain various address types -and sockaddr would be too short for some of them and we can't know what -someone else will add to Indy as time goes by. -} - -function TIdStackVCLPosix.Accept(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion): TIdStackSocketHandle; -var - LN: socklen_t; - LAddrStore: sockaddr_storage; - LAddrIPv4 : SockAddr_In absolute LAddrStore; - LAddrIPv6 : sockaddr_in6 absolute LAddrStore; - LAddr : sockaddr absolute LAddrStore; - -begin - LN := SizeOf(LAddrStore); - Result := Posix.SysSocket.accept(ASocket, LAddr, LN); - if Result <> -1 then begin - {$IFDEF HAS_SOCKET_NOSIGPIPE} - SetSocketOption(Result, SOL_SOCKET, SO_NOSIGPIPE, 1); - {$ENDIF} - case LAddrStore.ss_family of - Id_PF_INET4: begin - VIP := TranslateTInAddrToString( LAddrIPv4.sin_addr, Id_IPv4); - VPort := ntohs(LAddrIPv4.sin_port); - VIPVersion := Id_IPV4; - end; - Id_PF_INET6: begin - VIP := TranslateTInAddrToString(LAddrIPv6.sin6_addr, Id_IPv6); - VPort := ntohs(LAddrIPv6.sin6_port); - VIPVersion := Id_IPV6; - end - else begin - __close(Result); - Result := Id_INVALID_SOCKET; - IPVersionUnsupported; - end; - end; - end else begin - if GetLastError = EBADF then begin - SetLastError(EINTR); - end; - end; -end; - -{$IFDEF HAS_getifaddrs} -function getifaddrs(var ifap: pifaddrs): Integer; cdecl; external libc name _PU + 'getifaddrs'; {do not localize} -procedure freeifaddrs(ifap: pifaddrs); cdecl; external libc name _PU + 'freeifaddrs'; {do not localize} - {$IFDEF HAS_if_nametoindex} -function if_nametoindex(const ifname: PIdAnsiChar): UInt32; cdecl; external libc name _PU + 'if_nametoindex'; {do not localize} - {$ENDIF} - -type - TIdStackLocalAddressAccess = class(TIdStackLocalAddress) - end; - -{$ELSE} - {$IFDEF ANDROID} - // TODO: implement getifaddrs() manually using code from https://github.com/morristech/android-ifaddrs - {.$DEFINE HAS_getifaddrs} - {$ENDIF} -{$ENDIF} - -procedure TIdStackVCLPosix.GetLocalAddressList(AAddresses: TIdStackLocalAddressList); -var - {$IFDEF HAS_getifaddrs} - LAddrList, LAddrInfo: pifaddrs; - LSubNetStr: String; - LAddress: TIdStackLocalAddress; - LName: string; - {$ELSE} - LRetVal: Integer; - LHostName: string; - Hints: AddrInfo; - LAddrList, LAddrInfo: pAddrInfo; - {$IFDEF USE_MARSHALLED_PTRS} - M: TMarshaller; - {$ENDIF} - {$ENDIF} -begin - // TODO: Using gethostname() and getaddrinfo() like this may not always return just - // the machine's IP addresses. Technically speaking, they will return the local - // hostname, and then return the address(es) to which that hostname resolves. - // It is possible for a machine to (a) be configured such that its name does - // not resolve to an IP, or (b) be configured such that its name resolves to - // multiple IPs, only one of which belongs to the local machine. For better - // results, we should use getifaddrs() on platforms that support it... - - {$IFDEF HAS_getifaddrs} - - if getifaddrs(LAddrList) = 0 then // TODO: raise an exception if it fails - try - AAddresses.BeginUpdate; - try - LAddrInfo := LAddrList; - repeat - if (LAddrInfo^.ifa_addr <> nil) and ((LAddrInfo^.ifa_flags and IFF_LOOPBACK) = 0) then - begin - LAddress := nil; - case LAddrInfo^.ifa_addr^.sa_family of - Id_PF_INET4: begin - if LAddrInfo^.ifa_netmask <> nil then begin - LSubNetStr := TranslateTInAddrToString( PSockAddr_In(LAddrInfo^.ifa_netmask)^.sin_addr, Id_IPv4); - end else begin - LSubNetStr := ''; - end; - LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, TranslateTInAddrToString( PSockAddr_In(LAddrInfo^.ifa_addr)^.sin_addr, Id_IPv4), LSubNetStr); - end; - Id_PF_INET6: begin - LAddress := TIdStackLocalAddressIPv6.Create(AAddresses, TranslateTInAddrToString( PSockAddr_In6(LAddrInfo^.ifa_addr)^.sin6_addr, Id_IPv6)); - end; - end; - if LAddress <> nil then begin - LName := String(LAddrInfo^.ifa_name); - {$I IdObjectChecksOff.inc} - TIdStackLocalAddressAccess(LAddress).FDescription := LName; - TIdStackLocalAddressAccess(LAddress).FFriendlyName := LName; - TIdStackLocalAddressAccess(LAddress).FInterfaceName := LName; - {$IFDEF HAS_if_nametoindex} - TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := if_nametoindex(LAddrInfo^.ifa_name); - {$ENDIF} - {$I IdObjectChecksOn.inc} - end; - end; - LAddrInfo := LAddrInfo^.ifa_next; - until LAddrInfo = nil; - finally - AAddresses.EndUpdate; - end; - finally - freeifaddrs(LAddrList); - end; - - {$ELSE} - - // TODO: on Android, either implement getifaddrs() (https://github.com/morristech/android-ifaddrs) - // or use the Java API to enumerate the local network interfaces and their IP addresses, eg: - { - var - en, enumIpAddr: Enumeration; - intf: NetworkInterface; - inetAddress: InetAddress; - LAddress: TIdStackLocalAddress; - begin - try - en := NetworkInterface.getNetworkInterfaces; - if en.hasMoreElements then begin - AAddresses.BeginUpdate; - try - repeat - intf := en.nextElement; - enumIpAddr := intf.getInetAddresses; - while enumIpAddr.hasMoreElements do begin - inetAddress := enumIpAddr.nextElement; - if not inetAddress.isLoopbackAddress then begin - LAddress := nil; - if (inetAddress instanceof Inet4Address) then begin - LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, inetAddress.getHostAddress.toString, ''); // TODO: subnet mask - end - else if (inetAddress instanceof Inet6Address) then begin - LAddress := TIdStackLocalAddressIPv6.Create(AAddresses, inetAddress.getHostAddress.toString); - end; - if LAddress <> nil then begin - ($I IdObjectChecksOff.inc) - TIdStackLocalAddressAccess(LAddress).FDescription := intf.getDisplayName; - TIdStackLocalAddressAccess(LAddress).FInterfaceName := intf.getName; - TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := intf.getIndex (+1?); - ($I IdObjectChecksOn.inc) - end; - end; - end; - until not en.hasMoreElements; - finally - AAddresses.EndUpdate; - end; - end; - except - if not HasAndroidPermission('android.permission.ACCESS_NETWORK_STATE') then begin - IndyRaiseOuterException(EIdAccessNetworkStatePermissionNeeded.CreateError(0, '')); - end; - if not HasAndroidPermission('android.permission.INTERNET') then begin - IndyRaiseOuterException(EIdInternetPermissionNeeded.CreateError(0, '')); - end; - raise; - end; - end; - - Note that this requires the application to have ACCESS_NETWORK_STATE and INTERNET permissions. - - Or: - - uses - if XE7+ - Androidapi.Helpers - else - FMX.Helpers.Android - ; - - var - LWifiManager: WifiManager; - LWifiInfo: WifiInfo; - LIPAddress: Integer; - LAddress: TIdStackLocalAddressIPv4; - begin - try - LWifiManager := (WifiManager) GetActivityContext.getSystemService(WIFI_SERVICE); - LWifiInfo := LWifiManager.getConnectionInfo; - LIPAddress := LWifiInfo.getIpAddress; - // TODO: can we use the NetworkId or MacAddress to help find the network interface name and index? - except - if not HasAndroidPermission('android.permission.ACCESS_WIFI_STATE') then begin - IndyRaiseOuterException(EIdAccessWifiStatePermissionNeeded.CreateError(0, '')); - end; - raise; - end; - - // WiFiInfo only supports IPv4 - LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, - Format('%d.%d.%d.%d', [LIPAddress and $ff, (LIPAddress shr 8) and $ff, (LIPAddress shr 16) and $ff, (LIPAddress shr 24) and $ff]), - '' // TODO: subnet mask - ); - LAddress.FDescription := ?; // LWifiInfo.getNetworkId()? LWifiInfo.getSSID()? LWifiInfo.toString()? - LAddress.FInterfaceName := ?; - LAddress.FInterfaceIndex := ?; - end; - - This requires only ACCESS_WIFI_STATE permission. - } - - //IMPORTANT!!! - // - //The Hints structure must be zeroed out or you might get an AV. - //I've seen this in Mac OS X - FillChar(Hints, SizeOf(Hints), 0); - Hints.ai_family := PF_UNSPEC; // returns both IPv4 and IPv6 addresses - Hints.ai_socktype := SOCK_STREAM; - - LHostName := HostName; - - LRetVal := getaddrinfo( - {$IFDEF USE_MARSHALLED_PTRS} - M.AsAnsi(LHostName).ToPointer - {$ELSE} - PAnsiChar( - {$IFDEF STRING_IS_ANSI} - LHostName - {$ELSE} - AnsiString(LHostName) // explicit convert to Ansi - {$ENDIF} - ) - {$ENDIF}, - nil, Hints, LAddrList); - if LRetVal <> 0 then begin - if LRetVal = EAI_SYSTEM then begin - RaiseLastOSError; - end else begin - raise EIdReverseResolveError.CreateFmt(RSReverseResolveError, [LHostName, gai_strerror(LRetVal), LRetVal]); - end; - end; - try - AAddresses.BeginUpdate; - try - LAddrInfo := LAddrList; - repeat - case LAddrInfo^.ai_addr^.sa_family of - Id_PF_INET4 : - begin - TIdStackLocalAddressIPv4.Create(AAddresses, TranslateTInAddrToString( PSockAddr_In(LAddrInfo^.ai_addr)^.sin_addr, Id_IPv4), ''); // TODO: SubNet - end; - Id_PF_INET6 : - begin - TIdStackLocalAddressIPv6.Create(AAddresses, TranslateTInAddrToString( PSockAddr_In6(LAddrInfo^.ai_addr)^.sin6_addr, Id_IPv6)); - end; - end; - LAddrInfo := LAddrInfo^.ai_next; - until LAddrInfo = nil; - finally - AAddresses.EndUpdate; - end; - finally - freeaddrinfo(LAddrList^); - end; - - {$ENDIF} -end; - -procedure TIdStackVCLPosix.Bind(ASocket: TIdStackSocketHandle; - const AIP: string; const APort: TIdPort; const AIPVersion: TIdIPVersion); -var - LAddrStore: sockaddr_storage; - LAddrIPv4 : SockAddr_In absolute LAddrStore; - LAddrIPv6 : sockaddr_in6 absolute LAddrStore; - LAddr : sockaddr absolute LAddrStore; -begin - case AIPVersion of - Id_IPv4: begin - InitSockAddr_In(LAddrIPv4); - if AIP <> '' then begin - TranslateStringToTInAddr(AIP, LAddrIPv4.sin_addr, Id_IPv4); - end; - LAddrIPv4.sin_port := htons(APort); - CheckForSocketError(Posix.SysSocket.bind(ASocket, LAddr, SizeOf(LAddrIPv4))); - end; - Id_IPv6: begin - InitSockAddr_in6(LAddrIPv6); - if AIP <> '' then begin - TranslateStringToTInAddr(AIP, LAddrIPv6.sin6_addr, Id_IPv6); - end; - LAddrIPv6.sin6_port := htons(APort); - CheckForSocketError(Posix.SysSocket.bind(ASocket,LAddr, SizeOf(LAddrIPv6))); - end; - else begin - IPVersionUnsupported; - end; - end; - -end; - -function TIdStackVCLPosix.CheckIPVersionSupport( - const AIPVersion: TIdIPVersion): boolean; -var - LTmpSocket: TIdStackSocketHandle; -begin - // TODO: on nix systems (or maybe just Linux?), an alternative would be to - // check for the existance of the '/proc/net/if_inet6' kernel pseudo-file - LTmpSocket := WSSocket(IdIPFamily[AIPVersion], Id_SOCK_STREAM, Id_IPPROTO_IP ); - Result := LTmpSocket <> Id_INVALID_SOCKET; - if Result then begin - WSCloseSocket(LTmpSocket); - end; -end; - -procedure TIdStackVCLPosix.Connect(const ASocket: TIdStackSocketHandle; - const AIP: string; const APort: TIdPort; const AIPVersion: TIdIPVersion); -var - LAddrStore: sockaddr_storage; - LAddrIPv4 : SockAddr_In absolute LAddrStore; - LAddrIPv6 : sockaddr_in6 absolute LAddrStore; - LAddr : sockaddr absolute LAddrStore; -begin - case AIPVersion of - Id_IPv4: begin - InitSockAddr_In(LAddrIPv4); - TranslateStringToTInAddr(AIP, LAddrIPv4.sin_addr, Id_IPv4); - LAddrIPv4.sin_port := htons(APort); - CheckForSocketError(Posix.SysSocket.connect(ASocket, LAddr, SizeOf(LAddrIPv4))); - end; - Id_IPv6: begin - InitSockAddr_in6(LAddrIPv6); - TranslateStringToTInAddr(AIP, LAddrIPv6.sin6_addr, Id_IPv6); - LAddrIPv6.sin6_port := htons(APort); - CheckForSocketError(Posix.SysSocket.connect(ASocket, LAddr, SizeOf(LAddrIPv6))); - end; - else begin - IPVersionUnsupported; - end; - end; - -end; - -constructor TIdStackVCLPosix.Create; -begin - inherited Create; -end; - -destructor TIdStackVCLPosix.Destroy; -begin - inherited Destroy; -end; - -procedure TIdStackVCLPosix.Disconnect(ASocket: TIdStackSocketHandle); -begin - // Windows uses Id_SD_Send, Linux should use Id_SD_Both - WSShutdown(ASocket, Id_SD_Both); - // SO_LINGER is false - socket may take a little while to actually close after this - WSCloseSocket(ASocket); -end; - -function TIdStackVCLPosix.GetLastError: Integer; -begin - Result := errno; -end; - -procedure TIdStackVCLPosix.GetPeerName(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); -var - i: socklen_t; - LAddrStore: sockaddr_storage; - LAddrIPv4 : SockAddr_In absolute LAddrStore; - LAddrIPv6 : sockaddr_in6 absolute LAddrStore; - LAddr : sockaddr absolute LAddrStore; -begin - i := SizeOf(LAddrStore); - CheckForSocketError(Posix.SysSocket.getpeername(ASocket, LAddr, i)); - case LAddrStore.ss_family of - Id_PF_INET4: begin - VIP := TranslateTInAddrToString(LAddrIPv4.sin_addr, Id_IPv4); - VPort := ntohs(LAddrIPv4.sin_port); - VIPVersion := Id_IPV4; - end; - Id_PF_INET6: begin - VIP := TranslateTInAddrToString(LAddrIPv6.sin6_addr, Id_IPv6); - VPort := ntohs(LAddrIPv6.sin6_port); - VIPVersion := Id_IPV6; - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -procedure TIdStackVCLPosix.GetSocketName(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); -var - LiSize: socklen_t; - LAddrStore: sockaddr_storage; - LAddrIPv4 : SockAddr_In absolute LAddrStore; - LAddrIPv6 : sockaddr_in6 absolute LAddrStore; - LAddr : sockaddr absolute LAddrStore; -begin - LiSize := SizeOf(LAddrStore); - CheckForSocketError(getsockname(ASocket, LAddr, LiSize)); - case LAddrStore.ss_family of - Id_PF_INET4: begin - VIP := TranslateTInAddrToString(LAddrIPv4.sin_addr, Id_IPv4); - VPort := ntohs(LAddrIPv4.sin_port); - VIPVersion := Id_IPV4; - end; - Id_PF_INET6: begin - VIP := TranslateTInAddrToString(LAddrIPv6.sin6_addr, Id_IPv6); - VPort := ntohs(LAddrIPv6.sin6_port); - VIPVersion := Id_IPV6; - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -function TIdStackVCLPosix.HostByAddress(const AAddress: string; - const AIPVersion: TIdIPVersion): string; -var - LiSize: socklen_t; - LAddrStore: sockaddr_storage; - LAddrIPv4 : SockAddr_In absolute LAddrStore; - LAddrIPv6 : sockaddr_in6 absolute LAddrStore; - LAddr : sockaddr absolute LAddrStore; - LHostName : array[0..NI_MAXHOST] of TIdAnsiChar; - {$IFDEF USE_MARSHALLED_PTRS} - LHostNamePtr: TPtrWrapper; - {$ENDIF} - LRet : Integer; - LHints : addrinfo; - LAddrInfo: pAddrInfo; -begin - LiSize := 0; - case AIPVersion of - Id_IPv4 : - begin - InitSockAddr_In(LAddrIPv4); - TranslateStringToTInAddr(AAddress,LAddrIPv4.sin_addr,Id_IPv4); - LiSize := SizeOf(SockAddr_In); - end; - Id_IPv6 : - begin - InitSockAddr_In6(LAddrIPv6); - TranslateStringToTInAddr(AAddress,LAddrIPv6.sin6_addr,Id_IPv6); - LiSize := SizeOf(SockAddr_In6); - end - else - IPVersionUnsupported; - end; - FillChar(LHostName[0],Length(LHostName),0); - {$IFDEF USE_MARSHALLED_PTRS} - LHostNamePtr := TPtrWrapper.Create(@LHostName[0]); - {$ENDIF} - LRet := getnameinfo(LAddr,LiSize, - {$IFDEF USE_MARSHALLED_PTRS} - LHostNamePtr.ToPointer - {$ELSE} - LHostName - {$ENDIF}, - NI_MAXHOST,nil,0,NI_NAMEREQD ); - if LRet <> 0 then begin - if LRet = EAI_SYSTEM then begin - RaiseLastOSError; - end else begin - raise EIdReverseResolveError.CreateFmt(RSReverseResolveError, [AAddress, gai_strerror(LRet), LRet]); - end; - end; -{ -IMPORTANT!!! - -getnameinfo can return either results from a numeric to text conversion or -results from a DNS reverse lookup. Someone could make a malicous PTR record -such as - - 1.0.0.127.in-addr.arpa. IN PTR 10.1.1.1 - -and trick a caller into beleiving the socket address is 10.1.1.1 instead of -127.0.0.1. If there is a numeric host in LAddr, than this is the case and -we disregard the result and raise an exception. -} - FillChar(LHints, SizeOf(LHints), 0); - LHints.ai_socktype := SOCK_DGRAM; //*dummy*/ - LHints.ai_flags := AI_NUMERICHOST; - if getaddrinfo( - {$IFDEF USE_MARSHALLED_PTRS} - LHostNamePtr.ToPointer - {$ELSE} - LHostName - {$ENDIF}, - '0', LHints, LAddrInfo) = 0 then - begin - freeaddrinfo(LAddrInfo^); - Result := ''; - raise EIdMaliciousPtrRecord.Create(RSMaliciousPtrRecord); - end; - - {$IFDEF USE_MARSHALLED_PTRS} - Result := TMarshal.ReadStringAsAnsi(LHostNamePtr); - {$ELSE} - Result := String(LHostName); - {$ENDIF} -end; - -function TIdStackVCLPosix.HostByName(const AHostName: string; - const AIPVersion: TIdIPVersion): string; -var - LAddrInfo: pAddrInfo; - LHints: AddrInfo; - LRetVal: Integer; - {$IFDEF USE_MARSHALLED_PTRS} - M: TMarshaller; - {$ENDIF} -begin - if not (AIPVersion in [Id_IPv4, Id_IPv6]) then begin - IPVersionUnsupported; - end; - //IMPORTANT!!! - // - //The Hints structure must be zeroed out or you might get an AV. - //I've seen this in Mac OS X - FillChar(LHints, SizeOf(LHints), 0); - LHints.ai_family := IdIPFamily[AIPVersion]; - LHints.ai_socktype := SOCK_STREAM; - LAddrInfo := nil; - - LRetVal := getaddrinfo( - {$IFDEF USE_MARSHALLED_PTRS} - M.AsAnsi(AHostName).ToPointer - {$ELSE} - PAnsiChar( - {$IFDEF STRING_IS_ANSI} - AHostName - {$ELSE} - AnsiString(AHostName) // explicit convert to Ansi - {$ENDIF} - ) - {$ENDIF}, - nil, LHints, LAddrInfo); - if LRetVal <> 0 then begin - if LRetVal = EAI_SYSTEM then begin - RaiseLastOSError; - end else begin - raise EIdResolveError.CreateFmt(RSReverseResolveError, [AHostName, gai_strerror(LRetVal), LRetVal]); - end; - end; - try - if AIPVersion = Id_IPv4 then begin - Result := TranslateTInAddrToString( PSockAddr_In( LAddrInfo^.ai_addr)^.sin_addr, AIPVersion); - end else begin - Result := TranslateTInAddrToString( PSockAddr_In6( LAddrInfo^.ai_addr)^.sin6_addr, AIPVersion); - end; - finally - freeaddrinfo(LAddrInfo^); - end; -end; - -function TIdStackVCLPosix.HostToNetwork(AValue: UInt32): UInt32; -begin - Result := htonl(AValue); -end; - -function TIdStackVCLPosix.HostToNetwork(AValue: UInt16): UInt16; -begin - Result := htons(AValue); -end; - -function TIdStackVCLPosix.HostToNetwork(AValue: TIdUInt64): TIdUInt64; -var - LParts: TIdUInt64Parts; - L: UInt32; -begin - if (htonl(1) <> 1) then begin - LParts.QuadPart := AValue; - L := htonl(LParts.HighPart); - LParts.HighPart := htonl(LParts.LowPart); - LParts.LowPart := L; - Result := LParts.QuadPart; - end else begin - Result := AValue; - end; -end; - -function TIdStackVCLPosix.IOControl(const s: TIdStackSocketHandle; - const cmd: UInt32; var arg: UInt32): Integer; -begin - Result := ioctl(s, cmd, @arg); -end; - -procedure TIdStackVCLPosix.Listen(ASocket: TIdStackSocketHandle; - ABackLog: Integer); -begin - CheckForSocketError(Posix.SysSocket.listen(ASocket, ABacklog)); -end; - -function TIdStackVCLPosix.NetworkToHost(AValue: UInt32): UInt32; -begin - Result := ntohl(AValue); -end; - -function TIdStackVCLPosix.NetworkToHost(AValue: TIdUInt64): TIdUInt64; -var - LParts: TIdUInt64Parts; - L: UInt32; -begin - if (ntohl(1) <> 1) then begin - LParts.QuadPart := AValue; - L := ntohl(LParts.HighPart); - LParts.HighPart := ntohl(LParts.LowPart); - LParts.LowPart := L; - Result := LParts.QuadPart; - end else begin - Result := AValue; - end; -end; - -function TIdStackVCLPosix.NetworkToHost(AValue: UInt16): UInt16; -begin - Result := ntohs(AValue); -end; - -function TIdStackVCLPosix.ReadHostName: string; -const - sMaxHostSize = 250; -var - LStr: array[0..sMaxHostSize] of TIdAnsiChar; - {$IFDEF USE_MARSHALLED_PTRS} - LStrPtr: TPtrWrapper; - {$ENDIF} -begin - {$IFDEF USE_MARSHALLED_PTRS} - LStrPtr := TPtrWrapper.Create(@LStr[0]); - {$ENDIF} - if gethostname( - {$IFDEF USE_MARSHALLED_PTRS} - LStrPtr.ToPointer - {$ELSE} - LStr - {$ENDIF}, sMaxHostSize) = 0 then - begin - {$IFDEF USE_MARSHALLED_PTRS} - Result := TMarshal.ReadStringAsAnsiUpTo(0, LStrPtr, sMaxHostSize); - {$ELSE} - LStr[sMaxHostSize] := TIdAnsiChar(0); - Result := String(LStr); - {$ENDIF} - end else begin - Result := ''; - end; -end; - -function TIdStackVCLPosix.ReceiveMsg(ASocket: TIdStackSocketHandle; - var VBuffer: TIdBytes; APkt: TIdPacketInfo): UInt32; -var - LSize: socklen_t; - LAddrStore: sockaddr_storage; - LAddrIPv4 : SockAddr_In absolute LAddrStore; - LAddrIPv6 : sockaddr_in6 absolute LAddrStore; - LAddr : sockaddr absolute LAddrStore; - LMsg : msghdr; - LIOV : iovec; - LControl : TIdBytes; - LCurCmsg : Pcmsghdr; //for iterating through the control buffer - LByte : PByte; - -begin - //we call the macro twice because we specified two possible structures. - //Id_IPV6_HOPLIMIT and Id_IPV6_PKTINFO - LSize := CMSG_SPACE(SizeOf(Byte)) + CMSG_SPACE(SizeOf(in6_pktinfo)); - SetLength(LControl, LSize); - - LIOV.iov_len := Length(VBuffer); // Length(VMsgData); - LIOV.iov_base := @VBuffer[0]; // @VMsgData[0]; - - FillChar(LMsg,SizeOf(LMsg),0); - - LMsg.msg_iov := @LIOV;//lpBuffers := @LMsgBuf; - LMsg.msg_iovlen := 1; - - LMsg.msg_controllen := LSize; - LMsg.msg_control := @LControl[0]; - - LMsg.msg_name := @LAddr; - LMsg.msg_namelen := SizeOf(LAddrStore); - - Result := 0; - CheckForSocketError(RecvMsg(ASocket, LMsg, Result)); - APkt.Reset; - - case LAddrStore.ss_family of - Id_PF_INET4: begin - APkt.SourceIP := TranslateTInAddrToString(LAddrIPv4.sin_addr, Id_IPv4); - APkt.SourcePort := ntohs(LAddrIPv4.sin_port); - APkt.SourceIPVersion := Id_IPv4; - end; - Id_PF_INET6: begin - APkt.SourceIP := TranslateTInAddrToString(LAddrIPv6.sin6_addr, Id_IPv6); - APkt.SourcePort := ntohs(LAddrIPv6.sin6_port); - APkt.SourceIPVersion := Id_IPv6; - end; - else begin - Result := 0; // avoid warning - IPVersionUnsupported; - end; - end; - - LCurCmsg := nil; - repeat - LCurCmsg := CMSG_NXTHDR(@LMsg, LCurCmsg); - if LCurCmsg = nil then begin - break; - end; - case LCurCmsg^.cmsg_type of - IPV6_PKTINFO : //done this way because IPV6_PKTINF and IP_PKTINFO are both 19 - begin - case LAddrStore.ss_family of - Id_PF_INET4: begin - {$IFDEF IOS} - ToDo('PKTINFO not implemented for IPv4 under iOS yet'); - {$ELSE} - {$IFNDEF OSX} - //This is not supported in OS X. - with Pin_pktinfo(CMSG_DATA(LCurCmsg))^ do begin - APkt.DestIP := TranslateTInAddrToString(ipi_addr, Id_IPv4); - APkt.DestIF := ipi_ifindex; - end; - APkt.DestIPVersion := Id_IPv4; - {$ENDIF} - {$ENDIF} - end; - Id_PF_INET6: begin - with pin6_pktinfo(CMSG_DATA(LCurCmsg))^ do begin - APkt.DestIP := TranslateTInAddrToString(ipi6_addr, Id_IPv6); - APkt.DestIF := ipi6_ifindex; - end; - APkt.DestIPVersion := Id_IPv6; - end; - end; - end; - Id_IPV6_HOPLIMIT : - begin - LByte := PByte(CMSG_DATA(LCurCmsg)); - APkt.TTL := LByte^; - end; - end; - until False; -end; - -function TIdStackVCLPosix.RecvFrom(const ASocket: TIdStackSocketHandle; - var VBuffer; const ALength, AFlags: Integer; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; -var - LiSize: socklen_t; - LAddrStore: sockaddr_storage; - LAddrIPv4 : SockAddr_In absolute LAddrStore; - LAddrIPv6 : sockaddr_in6 absolute LAddrStore; - LAddr : sockaddr absolute LAddrStore; - -begin - LiSize := SizeOf(LAddrStore); - // TODO: only include MSG_NOSIGNAL if SO_NOSIGPIPE is not enabled? - Result := Posix.SysSocket.recvfrom(ASocket,VBuffer, ALength, AFlags or Id_MSG_NOSIGNAL, LAddr, LiSize); - if Result >= 0 then - begin - case LAddrStore.ss_family of - Id_PF_INET4: begin - VIP := TranslateTInAddrToString(LAddrIPv4.sin_addr, Id_IPv4); - VPort := ntohs(LAddrIPv4.sin_port); - VIPVersion := Id_IPV4; - end; - Id_PF_INET6: begin - VIP := TranslateTInAddrToString(LAddrIPv6.sin6_addr, Id_IPv6); - VPort := ntohs(LAddrIPv6.sin6_port); - VIPVersion := Id_IPV6; - end; - else begin - Result := 0; - IPVersionUnsupported; - end; - end; - end; -end; - -procedure TIdStackVCLPosix.SetBlocking(ASocket: TIdStackSocketHandle; - const ABlocking: Boolean); -var - LFlags: Integer; -begin - LFlags := CheckForSocketError(fcntl(ASocket, F_GETFL, 0)); - if ABlocking then begin - LFlags := LFlags and not O_NONBLOCK; - end else begin - LFlags := LFlags or O_NONBLOCK; - end; - CheckForSocketError(fcntl(ASocket, F_SETFL, LFlags)); -end; - -procedure TIdStackVCLPosix.SetLastError(const AError: Integer); -begin - __error^ := AError; -end; - -procedure TIdStackVCLPosix.{$IFDEF VCL_XE3_OR_ABOVE}GetSocketOption{$ELSE}WSGetSocketOption{$ENDIF} - (ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; - var AOptVal; var AOptLen: Integer); -var - LLen : socklen_t; -begin - LLen := AOptLen; - CheckForSocketError(Posix.SysSocket.getsockopt(ASocket, ALevel, AOptName, AOptVal, LLen)); - AOptLen := LLen; -end; - -procedure TIdStackVCLPosix.{$IFDEF VCL_XE3_OR_ABOVE}SetSocketOption{$ELSE}WSSetSocketOption{$ENDIF} - (ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; - const AOptVal; const AOptLen: Integer); -begin - CheckForSocketError(Posix.SysSocket.setsockopt(ASocket, ALevel, AOptName, AOptVal, AOptLen)); -end; - -function TIdStackVCLPosix.SupportsIPv4: Boolean; -begin - {$IFDEF IOS} - // TODO: iOS 9+ is IPv6-only... - //Result := ([[[UIDevice currentDevice] systemVersion] compare:'9.0' options:NSNumericSearch] == NSOrderedAscending); - {$ENDIF} - //In Windows, this does something else. It checks the LSP's installed. - Result := CheckIPVersionSupport(Id_IPv4); -end; - -function TIdStackVCLPosix.SupportsIPv6: Boolean; -begin - //In Windows, this does something else. It checks the LSP's installed. - Result := CheckIPVersionSupport(Id_IPv6); -end; - -function TIdStackVCLPosix.WouldBlock(const AResult: Integer): Boolean; -begin - // using if-else instead of in..range because EAGAIN and EWOULDBLOCK - // have often the same value and so FPC might report a range error - Result := (AResult = Id_WSAEAGAIN) or - (AResult = Id_WSAEWOULDBLOCK) or - (AResult = Id_WSAEINPROGRESS); -end; - -procedure TIdStackVCLPosix.WriteChecksum(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort; const AIPVersion: TIdIPVersion); -begin - case AIPVersion of - Id_IPv4 : CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(VBuffer)), VBuffer, AOffset); - Id_IPv6 : WriteChecksumIPv6(s, VBuffer, AOffset, AIP, APort); - else - IPVersionUnsupported; - end; -end; - -procedure TIdStackVCLPosix.WriteChecksumIPv6(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort); -begin -//we simply request that the kernal write the checksum when the data -//is sent. All of the parameters required are because Windows is bonked -//because it doesn't have the IPV6CHECKSUM socket option meaning we have -//to querry the network interface in TIdStackWindows -- yuck!! - SetSocketOption(s, Id_IPPROTO_IPV6, IPV6_CHECKSUM, AOffset); -end; - -function TIdStackVCLPosix.WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; -begin - Result := __close(ASocket); -end; - -function TIdStackVCLPosix.WSGetLastError: Integer; -begin - //IdStackWindows just uses result := WSAGetLastError; - Result := GetLastError; //System.GetLastOSError; - FPC doesn't define it in System - if Result = Id_WSAEPIPE then begin - Result := Id_WSAECONNRESET; - end; -end; - -function TIdStackVCLPosix.WSGetServByName(const AServiceName: string): TIdPort; -var - Lps: PServEnt; - {$IFDEF USE_MARSHALLED_PTRS} - M: TMarshaller; - {$ENDIF} -begin - Lps := Posix.NetDB.getservbyname( - {$IFDEF USE_MARSHALLED_PTRS} - M.AsAnsi(AServiceName).ToPointer - {$ELSE} - PAnsiChar( - {$IFDEF STRING_IS_ANSI} - AServiceName - {$ELSE} - AnsiString(AServiceName) // explicit convert to Ansi - {$ENDIF} - ) - {$ENDIF}, - nil); - if Lps <> nil then begin - Result := ntohs(Lps^.s_port); - end else begin - try - Result := IndyStrToInt(AServiceName); - except - on EConvertError do begin - Result := 0; - IndyRaiseOuterException(EIdInvalidServiceName.CreateFmt(RSInvalidServiceName, [AServiceName])); - end; - end; - end; -end; - -procedure TIdStackVCLPosix.AddServByPortToList(const APortNumber: TIdPort; AAddresses: TStrings); -//function TIdStackVCLPosix.WSGetServByPort(const APortNumber: TIdPort): TStrings; -type - PPAnsiCharArray = ^TPAnsiCharArray; - TPAnsiCharArray = packed array[0..(MaxInt div SizeOf(PIdAnsiChar))-1] of PIdAnsiChar; -var - Lps: PServEnt; - Li: Integer; - Lp: PPAnsiCharArray; -begin - Lps := Posix.NetDB.getservbyport(htons(APortNumber), nil); - if Lps <> nil then begin - AAddresses.BeginUpdate; - try - AAddresses.Add(String(Lps^.s_name)); - Li := 0; - Lp := Pointer(Lps^.s_aliases); - while Lp[Li] <> nil do begin - AAddresses.Add(String(Lp[Li])); - Inc(Li); - end; - finally - AAddresses.EndUpdate; - end; - end; -end; - -function TIdStackVCLPosix.WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; - const ABufferLength, AFlags: Integer): Integer; -begin - //IdStackWindows is just: Result := Recv(ASocket, ABuffer, ABufferLength, AFlags); - // TODO: only include MSG_NOSIGNAL if SO_NOSIGPIPE is not enabled? - Result := Posix.SysSocket.Recv(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); -end; - -function TIdStackVCLPosix.WSSend(ASocket: TIdStackSocketHandle; const ABuffer; - const ABufferLength, AFlags: Integer): Integer; -begin - // TODO: only include MSG_NOSIGNAL if SO_NOSIGPIPE is not enabled? - Result := CheckForSocketError(Posix.SysSocket.send(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL)); -end; - -procedure TIdStackVCLPosix.WSSendTo(ASocket: TIdStackSocketHandle; - const ABuffer; const ABufferLength, AFlags: Integer; const AIP: string; - const APort: TIdPort; AIPVersion: TIdIPVersion); -var - LAddrStore: sockaddr_storage; - LAddrIPv4 : SockAddr_In absolute LAddrStore; - LAddrIPv6 : sockaddr_in6 absolute LAddrStore; - LAddr : sockaddr absolute LAddrStore; - LiSize: socklen_t; - LBytesSent: Integer; -begin - case AIPVersion of - Id_IPv4: begin - InitSockAddr_In(LAddrIPv4); - TranslateStringToTInAddr(AIP, LAddrIPv4.sin_addr, Id_IPv4); - LAddrIPv4.sin_port := htons(APort); - LiSize := SizeOf(LAddrIPv4); - end; - Id_IPv6: begin - InitSockAddr_in6(LAddrIPv6); - TranslateStringToTInAddr(AIP, LAddrIPv6.sin6_addr, Id_IPv6); - LAddrIPv6.sin6_port := htons(APort); - LiSize := SizeOf(LAddrIPv6); - end; - else - LiSize := 0; // avoid warning - IPVersionUnsupported; - end; - // TODO: only include MSG_NOSIGNAL if SO_NOSIGPIPE is not enabled? - LBytesSent := Posix.SysSocket.sendto( - ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL, LAddr, LiSize); - if LBytesSent = Id_SOCKET_ERROR then begin - // TODO: move this into RaiseLastSocketError directly - if WSGetLastError() = Id_WSAEMSGSIZE then begin - raise EIdPackageSizeTooBig.Create(RSPackageSizeTooBig); - end else begin - RaiseLastSocketError; - end; - end - else if LBytesSent <> ABufferLength then begin - raise EIdNotAllBytesSent.Create(RSNotAllBytesSent); - end; - -end; - -procedure TIdStackVCLPosix.WSSetLastError(const AErr: Integer); -begin - __error^ := AErr; -end; - -function TIdStackVCLPosix.WSShutdown(ASocket: TIdStackSocketHandle; - AHow: Integer): Integer; -begin - Result := Posix.SysSocket.shutdown(ASocket, AHow); -end; - -function TIdStackVCLPosix.WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; - const ANonBlocking: Boolean = False): TIdStackSocketHandle; -var - LFlags: Integer; -begin - Result := Posix.SysSocket.socket(AFamily, AStruct, AProtocol); - if Result <> INVALID_SOCKET then begin - {$IFDEF HAS_SOCKET_NOSIGPIPE} - SetSocketOption(Result, SOL_SOCKET, SO_NOSIGPIPE, 1); - {$ENDIF} - //SetBlocking(Result, not ANonBlocking); - if ANonBlocking then begin - LFlags := fcntl(Result, F_GETFL, 0); - LFlags := LFlags or O_NONBLOCK; - fcntl(Result, F_SETFL, LFlags); - end; - end; -end; - -{$I IdUnitPlatformOn.inc} -{$I IdSymbolPlatformOn.inc} -initialization - GSocketListClass := TIdSocketListVCLPosix; -end. +unit IdStackVCLPosix; + +interface + +{$I IdCompilerDefines.inc} + +{IMPORTANT!!! + +Platform warnings in this unit should be disabled because Indy we have no +intention of porting this unit to Windows or any non-Unix-like operating system. + +Any differences between Unix-like operating systems have to dealt with in other +ways. +} + +{$I IdSymbolPlatformOff.inc} +{$I IdUnitPlatformOff.inc} + +uses + Classes, + IdCTypes, + Posix.SysSelect, + Posix.SysSocket, + Posix.SysTime, + IdStack, + IdStackConsts, + IdGlobal, + IdStackBSDBase; + +type + {$IFDEF USE_VCL_POSIX} + {$IFDEF ANDROID} + EIdAccessWifiStatePermissionNeeded = class(EIdAndroidPermissionNeeded); + EIdAccessNetworkStatePermissionNeeded = class(EIdAndroidPermissionNeeded); + {$ENDIF} + {$ENDIF} + + TIdStackVCLPosix = class(TIdStackBSDBase) + protected + procedure WriteChecksumIPv6(s: TIdStackSocketHandle; var VBuffer: TIdBytes; + const AOffset: Integer; const AIP: String; const APort: TIdPort); + function GetLastError: Integer; + procedure SetLastError(const AError: Integer); + function HostByName(const AHostName: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; + function ReadHostName: string; override; + function WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; override; + function WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; + const ABufferLength, AFlags: Integer): Integer; override; + function WSSend(ASocket: TIdStackSocketHandle; const ABuffer; + const ABufferLength, AFlags: Integer): Integer; override; + function WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; override; + {$IFNDEF VCL_XE3_OR_ABOVE} + procedure WSGetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; + procedure WSSetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; + {$ENDIF} + public + constructor Create; override; + destructor Destroy; override; + procedure SetBlocking(ASocket: TIdStackSocketHandle; const ABlocking: Boolean); override; + function WouldBlock(const AResult: Integer): Boolean; override; + function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; + var VIPVersion: TIdIPVersion): TIdStackSocketHandle; override; + procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + function HostByAddress(const AAddress: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; + function WSGetLastError: Integer; override; + procedure WSSetLastError(const AErr : Integer); override; + function WSGetServByName(const AServiceName: string): TIdPort; override; + procedure AddServByPortToList(const APortNumber: TIdPort; AAddresses: TStrings); override; + procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; + procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; + procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); override; + function HostToNetwork(AValue: UInt16): UInt16; override; + function NetworkToHost(AValue: UInt16): UInt16; override; + function HostToNetwork(AValue: UInt32): UInt32; override; + function NetworkToHost(AValue: UInt32): UInt32; override; + function HostToNetwork(AValue: TIdUInt64): TIdUInt64; override; + function NetworkToHost(AValue: TIdUInt64): TIdUInt64; override; + function RecvFrom(const ASocket: TIdStackSocketHandle; + var VBuffer; const ALength, AFlags: Integer; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; override; + function ReceiveMsg(ASocket: TIdStackSocketHandle; + var VBuffer: TIdBytes; APkt: TIdPacketInfo): UInt32; override; + procedure WSSendTo(ASocket: TIdStackSocketHandle; const ABuffer; + const ABufferLength, AFlags: Integer; const AIP: string; const APort: TIdPort; + AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + function WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; + const ANonBlocking: Boolean = False): TIdStackSocketHandle; override; + procedure Disconnect(ASocket: TIdStackSocketHandle); override; + {$IFDEF VCL_XE3_OR_ABOVE} + procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; + procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; + {$ENDIF} + function SupportsIPv4: Boolean; overload; override; + function SupportsIPv6: Boolean; overload; override; + function CheckIPVersionSupport(const AIPVersion: TIdIPVersion): boolean; override; + //In Windows, this writes a checksum into a buffer. In Linux, it would probably + //simply have the kernal write the checksum with something like this (RFC 2292): +// +// int offset = 2; +// setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)); +// +// Note that this should be called + //IMMEDIATELY before you do a SendTo because the Local IPv6 address might change + + procedure WriteChecksum(s : TIdStackSocketHandle; var VBuffer : TIdBytes; + const AOffset : Integer; const AIP : String; const APort : TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; + var arg: UInt32): Integer; override; + + procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); override; + end; + +implementation + +{$O-} + +uses + IdResourceStrings, + IdResourceStringsUnix, + IdResourceStringsVCLPosix, + IdException, + IdVCLPosixSupplemental, + Posix.Base, + Posix.ArpaInet, + Posix.Errno, + Posix.NetDB, + {$IFDEF HAS_getifaddrs} + Posix.NetIf, + {$ENDIF} + Posix.NetinetIn, + Posix.StrOpts, + Posix.SysTypes, + Posix.SysUio, + Posix.Unistd, + Posix.Fcntl, + {$IFDEF HAS_UNIT_Generics_Collections} + System.Generics.Collections, + {$ENDIF} + SysUtils; + + {$UNDEF HAS_MSG_NOSIGNAL} + {$IFDEF LINUX} //this LINUX ifdef is deliberate + {$DEFINE HAS_MSG_NOSIGNAL} + {$ENDIF} + + +const + {$IFDEF HAS_MSG_NOSIGNAL} + //fancy little trick since OS X does not have MSG_NOSIGNAL + Id_MSG_NOSIGNAL = MSG_NOSIGNAL; + {$ELSE} + Id_MSG_NOSIGNAL = 0; + {$ENDIF} + Id_WSAEPIPE = EPIPE; + + // TODO: is there an RTL unit that already defines these constants? + POLLIN = $0001; + POLLPRI = $0002; + POLLOUT = $0004; + POLLERR = $0008; + POLLHUP = $0010; + POLLNVAL = $0020; + POLLRDNORM = $0040; + POLLRDBAND = $0080; + POLLWRNORM = $0100; + POLLWRBAND = $0200; + POLLMSG = $0400; + POLLREMOVE = $1000; + POLLRDHUP = $2000; + + +//helper functions for some structs + +{Note: These hide an API difference in structures. + +BSD 4.4 introduced a minor API change. sa_family was changed from a 16bit +word to an 8 bit byteee and an 8 bit byte feild named sa_len was added. + +} +procedure InitSockAddr_In(var VSock : SockAddr_In); +{$IFDEF USE_INLINE} inline; {$ENDIF} +begin + FillChar(VSock, SizeOf(SockAddr_In), 0); + VSock.sin_family := PF_INET; + {$IFDEF SOCK_HAS_SINLEN} + VSock.sin_len := SizeOf(SockAddr_In); + {$ENDIF} +end; + +procedure InitSockAddr_in6(var VSock : SockAddr_in6); +{$IFDEF USE_INLINE} inline; {$ENDIF} +begin + FillChar(VSock, SizeOf(SockAddr_in6), 0); + {$IFDEF SOCK_HAS_SINLEN} + VSock.sin6_len := SizeOf(SockAddr_in6); + {$ENDIF} + VSock.sin6_family := PF_INET6; +end; +// + +{ TIdSocketListVCLPosix } + +type + // TODO: is there an RTL unit that already defines these types? + ppollfd = ^pollfd; + pollfd = record + fd : TIdStackSocketHandle; + events : Int16; + revents : Int16; + end; + pollfdArray = array of pollfd; + nfds_t = TIdC_ULONG; // TODO: some platforms use 'C_UINT' instead! How to detect those? + + {$IFDEF HAS_GENERICS_TList} + TIdStackSocketHandleList = TList; + {$ELSE} + // TODO: flesh out to match TList for non-Generics compilers + TIdStackSocketHandleList = TList; + {$ENDIF} + + TIdSocketListVCLPosix = class(TIdSocketList) + protected + FSockets: TIdStackSocketHandleList; + // + class function FDPoll(ASet: ppollfd; const ACount: nfds_t; const ATimeout: Integer): Boolean; + function GetItem(AIndex: Integer): TIdStackSocketHandle; override; + procedure GetPollFds(var VSet: pollfdArray; var VOffset: nfds_t; const AEvents: Int16); + procedure SetPollFds(const VSet: pollfdArray; const AEvents: Int16); + public + constructor Create; override; + destructor Destroy; override; + procedure Add(AHandle: TIdStackSocketHandle); override; + procedure Remove(AHandle: TIdStackSocketHandle); override; + function Count: Integer; override; + procedure Clear; override; + function Clone: TIdSocketList; override; + function ContainsSocket(AHandle: TIdStackSocketHandle): Boolean; override; + class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; + AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + function SelectReadList(var VSocketList: TIdSocketList; + const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + end; + +constructor TIdSocketListVCLPosix.Create; +begin + inherited; + FSockets := TIdStackSocketHandleList.Create; +end; + +destructor TIdSocketListVCLPosix.Destroy; +begin + FSockets.Free; + inherited; +end; + +procedure TIdSocketListVCLPosix.Add(AHandle: TIdStackSocketHandle); +begin + Lock; + try + {$IFDEF HAS_GENERICS_TList} + if not FSockets.Contains(AHandle) then begin + FSockets.Add(AHandle); + end; + {$ELSE} + if FSockets.IndexOf(Pointer(AHandle)) = -1 then begin + FSockets.Add(Pointer(AHandle)); + end; + {$ENDIF} + finally + Unlock; + end; +end; + +procedure TIdSocketListVCLPosix.Clear; +begin + Lock; + try + FSockets.Clear; + finally + Unlock; + end; +end; + +function TIdSocketListVCLPosix.Clone: TIdSocketList; +begin + Result := TIdSocketListVCLPosix.Create; + try + Lock; + try + {$IFDEF HAS_GENERICS_TList} + TIdSocketListVCLPosix(Result).FSockets.AddRange(FSockets); + {$ELSE} + TIdSocketListVCLPosix(Result).FSockets.Assign(FSockets); + {$ENDIF} + finally + Unlock; + end; + except + FreeAndNil(Result); + raise; + end; +end; + +function TIdSocketListVCLPosix.ContainsSocket( + AHandle: TIdStackSocketHandle): Boolean; +begin + Lock; + try + {$IFDEF HAS_GENERICS_TList} + Result := FSockets.Contains(AHandle); + {$ELSE} + Result := FSockets.IndexOf(Pointer(AHandle)) <> -1; + {$ENDIF} + finally + Unlock; + end; +end; + +function TIdSocketListVCLPosix.Count: Integer; +begin + Lock; + try + Result := FSockets.Count; + finally + Unlock; + end; +end; + +// TODO: is there an RTL unit that already defines this? +function poll(Ptr: ppollfd; nfds : nfds_t; timeout : Integer) : Integer; cdecl; external libc name _PU+'poll'; + +class function TIdSocketListVCLPosix.FDPoll(ASet: ppollfd; + const ACount: nfds_t; const ATimeout: Integer): Boolean; +var + LTimeout: Integer; +begin + if ATimeout = IdTimeoutInfinite then begin + LTimeout := -1; + end else begin + LTimeout := ATimeout; + end; + Result := poll(ASet, ACount, LTimeout) > 0; +end; + +procedure TIdSocketListVCLPosix.GetPollFds(var VSet: pollfdArray; + var VOffset: nfds_t; const AEvents: Int16); +var + LPollFD: ppollfd; + I: Integer; +begin + Lock; + try + for I := 0 to FSockets.Count-1 do begin + LPollFD := @VSet[VOffset]; + {$IFDEF HAS_GENERICS_TList} + LPollFD^.fd := FSockets[i]; + {$ELSE} + LPollFD^.fd := TIdStackSocketHandle(FSockets[i]); + {$ENDIF} + LPollFD^.events := AEvents; + LPollFD^.revents := 0; + Inc(VOffset); + end; + finally + Unlock; + end; +end; + +function TIdSocketListVCLPosix.GetItem(AIndex: Integer): TIdStackSocketHandle; +begin + Lock; + try + if (AIndex >= 0) and (AIndex < FSockets.Count) then begin + {$IFDEF HAS_GENERICS_TList} + Result := FSockets[AIndex]; + {$ELSE} + Result := TIdStackSocketHandle(FSockets[AIndex]); + {$ENDIF} + end else begin + Result := Id_INVALID_SOCKET; + end; + finally + Unlock; + end; +end; + +procedure TIdSocketListVCLPosix.Remove(AHandle: TIdStackSocketHandle); +begin + Lock; + try + {$IFDEF HAS_GENERICS_TList} + FSockets.Remove(AHandle); + {$ELSE} + FSockets.Remove(Pointer(AHandle)); + {$ENDIF} + finally + Unlock; + end; +end; + +class function TIdSocketListVCLPosix.Select(AReadList, AWriteList, + AExceptList: TIdSocketList; const ATimeout: Integer): Boolean; +var + LPollFds: pollfdArray; + LOffset: nfds_t; + + function SetCount(AList: TIdSocketList) : Integer; + begin + if AList <> nil then begin + Result := AList.Count; + end else begin + Result := 0; + end; + end; + + procedure ReadSet(AList: TIdSocketList; const AEvents: Int16); + begin + if AList <> nil then begin + TIdSocketListVCLPosix(AList).GetPollFds(LPollFds, LOffset, AEvents); + end; + end; + +begin + SetLength(LPollFds, SetCount(AReadList) + SetCount(AWriteList) + SetCount(AExceptList)); + + LOffset := 0; + ReadSet(AReadList, POLLIN or POLLRDHUP); + ReadSet(AWriteList, POLLOUT); + ReadSet(AExceptList, POLLPRI); + // + Result := FDPoll(ppollfd(LPollFds), LOffset, ATimeout); + // + if AReadList <> nil then begin + TIdSocketListVCLPosix(AReadList).SetPollFds(LPollFds, POLLIN or POLLHUP); + end; + if AWriteList <> nil then begin + TIdSocketListVCLPosix(AWriteList).SetPollFds(LPollFds, POLLOUT); + end; + if AExceptList <> nil then begin + TIdSocketListVCLPosix(AExceptList).SetPollFds(LPollFds, POLLPRI); + end; +end; + +function TIdSocketListVCLPosix.SelectRead(const ATimeout: Integer): Boolean; +var + LPollFds: pollfdArray; + LCount: nfds_t; +begin + Lock; + try + SetLength(LPollFds, FSockets.Count); + LCount := GetPollFds(LPollFds, 0, POLLIN or POLLRDHUP); + finally + Unlock; + end; + Result := FDPoll(ppollfd(LPollFds), LCount, ATimeout); +end; + +function TIdSocketListVCLPosix.SelectReadList(var VSocketList: TIdSocketList; + const ATimeout: Integer): Boolean; +var + LPollFds: pollfdArray; + LCount: nfds_t; +begin + Lock; + try + SetLength(LPollFds, FSockets.Count); + LCount := GetPollFds(LPollFds, 0, POLLIN or POLLRDHUP); + finally + Unlock; + end; + Result := FDPoll(ppollfd(LPollFds), LCount, ATimeout); + if Result then begin + if VSocketList = nil then begin + VSocketList := TIdSocketList.CreateSocketList; + end; + TIdSocketListVCLPosix(VSocketList).SetPollFds(LPollFds, POLLIN or POLLRDHUP); + end; +end; + +procedure TIdSocketListVCLPosix.SetPollFds(const VSet: pollfdArray; + const AEvents: Int16); +var + LPollFD: ppollfd; + I: Integer; +begin + Lock; + try + FSockets.Clear; + for I := Low(VSet) to High(VSet) do begin + LPollFD := @VSet[I]; + if (AEvents = 0) or ((LPollFD^.revents and AEvents) <> 0) then begin + {$IFDEF HAS_GENERICS_TList} + FSockets.Add(LPollFD^.fd); + {$ELSE} + FSockets.Add(Pointer(LPollFD^.fd)); + {$ENDIF} + end; + end; + finally + Unlock; + end; +end; + +{ TIdStackVCLPosix } + +{ +IMPORTANT!!! + +Throughout much of this code, you will see stuff such as: + +var + LAddrStore: sockaddr_storage; + LAddrIPv4 : SockAddr_In absolute LAddrStore; + LAddrIPv6 : sockaddr_in6 absolute LAddrStore; + LAddr : sockaddr absolute LAddrStore; + +This is just a fancy way to do typecasting with various types of address type. +Many functions take a sockaddr parameter but that parameter is typecast for various +address types. The structures mentioned above are designed just for such +typecasting. The reason we use sockaddr_storage instead of sockaddr is that +we need something that is guaranteed to be able to contain various address types +and sockaddr would be too short for some of them and we can't know what +someone else will add to Indy as time goes by. +} + +function TIdStackVCLPosix.Accept(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion): TIdStackSocketHandle; +var + LN: socklen_t; + LAddrStore: sockaddr_storage; + LAddrIPv4 : SockAddr_In absolute LAddrStore; + LAddrIPv6 : sockaddr_in6 absolute LAddrStore; + LAddr : sockaddr absolute LAddrStore; + +begin + LN := SizeOf(LAddrStore); + Result := Posix.SysSocket.accept(ASocket, LAddr, LN); + if Result <> -1 then begin + {$IFDEF HAS_SOCKET_NOSIGPIPE} + SetSocketOption(Result, SOL_SOCKET, SO_NOSIGPIPE, 1); + {$ENDIF} + case LAddrStore.ss_family of + Id_PF_INET4: begin + VIP := TranslateTInAddrToString( LAddrIPv4.sin_addr, Id_IPv4); + VPort := ntohs(LAddrIPv4.sin_port); + VIPVersion := Id_IPV4; + end; + Id_PF_INET6: begin + VIP := TranslateTInAddrToString(LAddrIPv6.sin6_addr, Id_IPv6); + VPort := ntohs(LAddrIPv6.sin6_port); + VIPVersion := Id_IPV6; + end + else begin + __close(Result); + Result := Id_INVALID_SOCKET; + IPVersionUnsupported; + end; + end; + end else begin + if GetLastError = EBADF then begin + SetLastError(EINTR); + end; + end; +end; + +{$IFDEF HAS_getifaddrs} +function getifaddrs(var ifap: pifaddrs): Integer; cdecl; external libc name _PU + 'getifaddrs'; {do not localize} +procedure freeifaddrs(ifap: pifaddrs); cdecl; external libc name _PU + 'freeifaddrs'; {do not localize} + {$IFDEF HAS_if_nametoindex} +function if_nametoindex(const ifname: PIdAnsiChar): UInt32; cdecl; external libc name _PU + 'if_nametoindex'; {do not localize} + {$ENDIF} + +type + TIdStackLocalAddressAccess = class(TIdStackLocalAddress) + end; + +{$ELSE} + {$IFDEF ANDROID} + // TODO: implement getifaddrs() manually using code from https://github.com/morristech/android-ifaddrs + {.$DEFINE HAS_getifaddrs} + {$ENDIF} +{$ENDIF} + +procedure TIdStackVCLPosix.GetLocalAddressList(AAddresses: TIdStackLocalAddressList); +var + {$IFDEF HAS_getifaddrs} + LAddrList, LAddrInfo: pifaddrs; + LSubNetStr: String; + LAddress: TIdStackLocalAddress; + LName: string; + {$ELSE} + LRetVal: Integer; + LHostName: string; + Hints: AddrInfo; + LAddrList, LAddrInfo: pAddrInfo; + {$IFDEF USE_MARSHALLED_PTRS} + M: TMarshaller; + {$ENDIF} + {$ENDIF} +begin + // TODO: Using gethostname() and getaddrinfo() like this may not always return just + // the machine's IP addresses. Technically speaking, they will return the local + // hostname, and then return the address(es) to which that hostname resolves. + // It is possible for a machine to (a) be configured such that its name does + // not resolve to an IP, or (b) be configured such that its name resolves to + // multiple IPs, only one of which belongs to the local machine. For better + // results, we should use getifaddrs() on platforms that support it... + + {$IFDEF HAS_getifaddrs} + + if getifaddrs(LAddrList) = 0 then // TODO: raise an exception if it fails + try + AAddresses.BeginUpdate; + try + LAddrInfo := LAddrList; + repeat + if (LAddrInfo^.ifa_addr <> nil) and ((LAddrInfo^.ifa_flags and IFF_LOOPBACK) = 0) then + begin + LAddress := nil; + case LAddrInfo^.ifa_addr^.sa_family of + Id_PF_INET4: begin + if LAddrInfo^.ifa_netmask <> nil then begin + LSubNetStr := TranslateTInAddrToString( PSockAddr_In(LAddrInfo^.ifa_netmask)^.sin_addr, Id_IPv4); + end else begin + LSubNetStr := ''; + end; + LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, TranslateTInAddrToString( PSockAddr_In(LAddrInfo^.ifa_addr)^.sin_addr, Id_IPv4), LSubNetStr); + end; + Id_PF_INET6: begin + LAddress := TIdStackLocalAddressIPv6.Create(AAddresses, TranslateTInAddrToString( PSockAddr_In6(LAddrInfo^.ifa_addr)^.sin6_addr, Id_IPv6)); + end; + end; + if LAddress <> nil then begin + LName := String(LAddrInfo^.ifa_name); + {$I IdObjectChecksOff.inc} + TIdStackLocalAddressAccess(LAddress).FDescription := LName; + TIdStackLocalAddressAccess(LAddress).FFriendlyName := LName; + TIdStackLocalAddressAccess(LAddress).FInterfaceName := LName; + {$IFDEF HAS_if_nametoindex} + TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := if_nametoindex(LAddrInfo^.ifa_name); + {$ENDIF} + {$I IdObjectChecksOn.inc} + end; + end; + LAddrInfo := LAddrInfo^.ifa_next; + until LAddrInfo = nil; + finally + AAddresses.EndUpdate; + end; + finally + freeifaddrs(LAddrList); + end; + + {$ELSE} + + // TODO: on Android, either implement getifaddrs() (https://github.com/morristech/android-ifaddrs) + // or use the Java API to enumerate the local network interfaces and their IP addresses, eg: + { + var + en, enumIpAddr: Enumeration; + intf: NetworkInterface; + inetAddress: InetAddress; + LAddress: TIdStackLocalAddress; + begin + try + en := NetworkInterface.getNetworkInterfaces; + if en.hasMoreElements then begin + AAddresses.BeginUpdate; + try + repeat + intf := en.nextElement; + enumIpAddr := intf.getInetAddresses; + while enumIpAddr.hasMoreElements do begin + inetAddress := enumIpAddr.nextElement; + if not inetAddress.isLoopbackAddress then begin + LAddress := nil; + if (inetAddress instanceof Inet4Address) then begin + LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, inetAddress.getHostAddress.toString, ''); // TODO: subnet mask + end + else if (inetAddress instanceof Inet6Address) then begin + LAddress := TIdStackLocalAddressIPv6.Create(AAddresses, inetAddress.getHostAddress.toString); + end; + if LAddress <> nil then begin + ($I IdObjectChecksOff.inc) + TIdStackLocalAddressAccess(LAddress).FDescription := intf.getDisplayName; + TIdStackLocalAddressAccess(LAddress).FInterfaceName := intf.getName; + TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := intf.getIndex (+1?); + ($I IdObjectChecksOn.inc) + end; + end; + end; + until not en.hasMoreElements; + finally + AAddresses.EndUpdate; + end; + end; + except + if not HasAndroidPermission('android.permission.ACCESS_NETWORK_STATE') then begin + IndyRaiseOuterException(EIdAccessNetworkStatePermissionNeeded.CreateError(0, '')); + end; + if not HasAndroidPermission('android.permission.INTERNET') then begin + IndyRaiseOuterException(EIdInternetPermissionNeeded.CreateError(0, '')); + end; + raise; + end; + end; + + Note that this requires the application to have ACCESS_NETWORK_STATE and INTERNET permissions. + + Or: + + uses + if XE7+ + Androidapi.Helpers + else + FMX.Helpers.Android + ; + + var + LWifiManager: WifiManager; + LWifiInfo: WifiInfo; + LIPAddress: Integer; + LAddress: TIdStackLocalAddressIPv4; + begin + try + LWifiManager := (WifiManager) GetActivityContext.getSystemService(WIFI_SERVICE); + LWifiInfo := LWifiManager.getConnectionInfo; + LIPAddress := LWifiInfo.getIpAddress; + // TODO: can we use the NetworkId or MacAddress to help find the network interface name and index? + except + if not HasAndroidPermission('android.permission.ACCESS_WIFI_STATE') then begin + IndyRaiseOuterException(EIdAccessWifiStatePermissionNeeded.CreateError(0, '')); + end; + raise; + end; + + // WiFiInfo only supports IPv4 + LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, + Format('%d.%d.%d.%d', [LIPAddress and $ff, (LIPAddress shr 8) and $ff, (LIPAddress shr 16) and $ff, (LIPAddress shr 24) and $ff]), + '' // TODO: subnet mask + ); + LAddress.FDescription := ?; // LWifiInfo.getNetworkId()? LWifiInfo.getSSID()? LWifiInfo.toString()? + LAddress.FInterfaceName := ?; + LAddress.FInterfaceIndex := ?; + end; + + This requires only ACCESS_WIFI_STATE permission. + } + + //IMPORTANT!!! + // + //The Hints structure must be zeroed out or you might get an AV. + //I've seen this in Mac OS X + FillChar(Hints, SizeOf(Hints), 0); + Hints.ai_family := PF_UNSPEC; // returns both IPv4 and IPv6 addresses + Hints.ai_socktype := SOCK_STREAM; + + LHostName := HostName; + + LRetVal := getaddrinfo( + {$IFDEF USE_MARSHALLED_PTRS} + M.AsAnsi(LHostName).ToPointer + {$ELSE} + PAnsiChar( + {$IFDEF STRING_IS_ANSI} + LHostName + {$ELSE} + AnsiString(LHostName) // explicit convert to Ansi + {$ENDIF} + ) + {$ENDIF}, + nil, Hints, LAddrList); + if LRetVal <> 0 then begin + if LRetVal = EAI_SYSTEM then begin + RaiseLastOSError; + end else begin + raise EIdReverseResolveError.CreateFmt(RSReverseResolveError, [LHostName, gai_strerror(LRetVal), LRetVal]); + end; + end; + try + AAddresses.BeginUpdate; + try + LAddrInfo := LAddrList; + repeat + case LAddrInfo^.ai_addr^.sa_family of + Id_PF_INET4 : + begin + TIdStackLocalAddressIPv4.Create(AAddresses, TranslateTInAddrToString( PSockAddr_In(LAddrInfo^.ai_addr)^.sin_addr, Id_IPv4), ''); // TODO: SubNet + end; + Id_PF_INET6 : + begin + TIdStackLocalAddressIPv6.Create(AAddresses, TranslateTInAddrToString( PSockAddr_In6(LAddrInfo^.ai_addr)^.sin6_addr, Id_IPv6)); + end; + end; + LAddrInfo := LAddrInfo^.ai_next; + until LAddrInfo = nil; + finally + AAddresses.EndUpdate; + end; + finally + freeaddrinfo(LAddrList^); + end; + + {$ENDIF} +end; + +procedure TIdStackVCLPosix.Bind(ASocket: TIdStackSocketHandle; + const AIP: string; const APort: TIdPort; const AIPVersion: TIdIPVersion); +var + LAddrStore: sockaddr_storage; + LAddrIPv4 : SockAddr_In absolute LAddrStore; + LAddrIPv6 : sockaddr_in6 absolute LAddrStore; + LAddr : sockaddr absolute LAddrStore; +begin + case AIPVersion of + Id_IPv4: begin + InitSockAddr_In(LAddrIPv4); + if AIP <> '' then begin + TranslateStringToTInAddr(AIP, LAddrIPv4.sin_addr, Id_IPv4); + end; + LAddrIPv4.sin_port := htons(APort); + CheckForSocketError(Posix.SysSocket.bind(ASocket, LAddr, SizeOf(LAddrIPv4))); + end; + Id_IPv6: begin + InitSockAddr_in6(LAddrIPv6); + if AIP <> '' then begin + TranslateStringToTInAddr(AIP, LAddrIPv6.sin6_addr, Id_IPv6); + end; + LAddrIPv6.sin6_port := htons(APort); + CheckForSocketError(Posix.SysSocket.bind(ASocket,LAddr, SizeOf(LAddrIPv6))); + end; + else begin + IPVersionUnsupported; + end; + end; + +end; + +function TIdStackVCLPosix.CheckIPVersionSupport( + const AIPVersion: TIdIPVersion): boolean; +var + LTmpSocket: TIdStackSocketHandle; +begin + // TODO: on nix systems (or maybe just Linux?), an alternative would be to + // check for the existance of the '/proc/net/if_inet6' kernel pseudo-file + LTmpSocket := WSSocket(IdIPFamily[AIPVersion], Id_SOCK_STREAM, Id_IPPROTO_IP ); + Result := LTmpSocket <> Id_INVALID_SOCKET; + if Result then begin + WSCloseSocket(LTmpSocket); + end; +end; + +procedure TIdStackVCLPosix.Connect(const ASocket: TIdStackSocketHandle; + const AIP: string; const APort: TIdPort; const AIPVersion: TIdIPVersion); +var + LAddrStore: sockaddr_storage; + LAddrIPv4 : SockAddr_In absolute LAddrStore; + LAddrIPv6 : sockaddr_in6 absolute LAddrStore; + LAddr : sockaddr absolute LAddrStore; +begin + case AIPVersion of + Id_IPv4: begin + InitSockAddr_In(LAddrIPv4); + TranslateStringToTInAddr(AIP, LAddrIPv4.sin_addr, Id_IPv4); + LAddrIPv4.sin_port := htons(APort); + CheckForSocketError(Posix.SysSocket.connect(ASocket, LAddr, SizeOf(LAddrIPv4))); + end; + Id_IPv6: begin + InitSockAddr_in6(LAddrIPv6); + TranslateStringToTInAddr(AIP, LAddrIPv6.sin6_addr, Id_IPv6); + LAddrIPv6.sin6_port := htons(APort); + CheckForSocketError(Posix.SysSocket.connect(ASocket, LAddr, SizeOf(LAddrIPv6))); + end; + else begin + IPVersionUnsupported; + end; + end; + +end; + +constructor TIdStackVCLPosix.Create; +begin + inherited Create; +end; + +destructor TIdStackVCLPosix.Destroy; +begin + inherited Destroy; +end; + +procedure TIdStackVCLPosix.Disconnect(ASocket: TIdStackSocketHandle); +begin + // Windows uses Id_SD_Send, Linux should use Id_SD_Both + WSShutdown(ASocket, Id_SD_Both); + // SO_LINGER is false - socket may take a little while to actually close after this + WSCloseSocket(ASocket); +end; + +function TIdStackVCLPosix.GetLastError: Integer; +begin + Result := errno; +end; + +procedure TIdStackVCLPosix.GetPeerName(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); +var + i: socklen_t; + LAddrStore: sockaddr_storage; + LAddrIPv4 : SockAddr_In absolute LAddrStore; + LAddrIPv6 : sockaddr_in6 absolute LAddrStore; + LAddr : sockaddr absolute LAddrStore; +begin + i := SizeOf(LAddrStore); + CheckForSocketError(Posix.SysSocket.getpeername(ASocket, LAddr, i)); + case LAddrStore.ss_family of + Id_PF_INET4: begin + VIP := TranslateTInAddrToString(LAddrIPv4.sin_addr, Id_IPv4); + VPort := ntohs(LAddrIPv4.sin_port); + VIPVersion := Id_IPV4; + end; + Id_PF_INET6: begin + VIP := TranslateTInAddrToString(LAddrIPv6.sin6_addr, Id_IPv6); + VPort := ntohs(LAddrIPv6.sin6_port); + VIPVersion := Id_IPV6; + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +procedure TIdStackVCLPosix.GetSocketName(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); +var + LiSize: socklen_t; + LAddrStore: sockaddr_storage; + LAddrIPv4 : SockAddr_In absolute LAddrStore; + LAddrIPv6 : sockaddr_in6 absolute LAddrStore; + LAddr : sockaddr absolute LAddrStore; +begin + LiSize := SizeOf(LAddrStore); + CheckForSocketError(getsockname(ASocket, LAddr, LiSize)); + case LAddrStore.ss_family of + Id_PF_INET4: begin + VIP := TranslateTInAddrToString(LAddrIPv4.sin_addr, Id_IPv4); + VPort := ntohs(LAddrIPv4.sin_port); + VIPVersion := Id_IPV4; + end; + Id_PF_INET6: begin + VIP := TranslateTInAddrToString(LAddrIPv6.sin6_addr, Id_IPv6); + VPort := ntohs(LAddrIPv6.sin6_port); + VIPVersion := Id_IPV6; + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +function TIdStackVCLPosix.HostByAddress(const AAddress: string; + const AIPVersion: TIdIPVersion): string; +var + LiSize: socklen_t; + LAddrStore: sockaddr_storage; + LAddrIPv4 : SockAddr_In absolute LAddrStore; + LAddrIPv6 : sockaddr_in6 absolute LAddrStore; + LAddr : sockaddr absolute LAddrStore; + LHostName : array[0..NI_MAXHOST] of TIdAnsiChar; + {$IFDEF USE_MARSHALLED_PTRS} + LHostNamePtr: TPtrWrapper; + {$ENDIF} + LRet : Integer; + LHints : addrinfo; + LAddrInfo: pAddrInfo; +begin + LiSize := 0; + case AIPVersion of + Id_IPv4 : + begin + InitSockAddr_In(LAddrIPv4); + TranslateStringToTInAddr(AAddress,LAddrIPv4.sin_addr,Id_IPv4); + LiSize := SizeOf(SockAddr_In); + end; + Id_IPv6 : + begin + InitSockAddr_In6(LAddrIPv6); + TranslateStringToTInAddr(AAddress,LAddrIPv6.sin6_addr,Id_IPv6); + LiSize := SizeOf(SockAddr_In6); + end + else + IPVersionUnsupported; + end; + FillChar(LHostName[0],Length(LHostName),0); + {$IFDEF USE_MARSHALLED_PTRS} + LHostNamePtr := TPtrWrapper.Create(@LHostName[0]); + {$ENDIF} + LRet := getnameinfo(LAddr,LiSize, + {$IFDEF USE_MARSHALLED_PTRS} + LHostNamePtr.ToPointer + {$ELSE} + LHostName + {$ENDIF}, + NI_MAXHOST,nil,0,NI_NAMEREQD ); + if LRet <> 0 then begin + if LRet = EAI_SYSTEM then begin + RaiseLastOSError; + end else begin + raise EIdReverseResolveError.CreateFmt(RSReverseResolveError, [AAddress, gai_strerror(LRet), LRet]); + end; + end; +{ +IMPORTANT!!! + +getnameinfo can return either results from a numeric to text conversion or +results from a DNS reverse lookup. Someone could make a malicous PTR record +such as + + 1.0.0.127.in-addr.arpa. IN PTR 10.1.1.1 + +and trick a caller into beleiving the socket address is 10.1.1.1 instead of +127.0.0.1. If there is a numeric host in LAddr, than this is the case and +we disregard the result and raise an exception. +} + FillChar(LHints, SizeOf(LHints), 0); + LHints.ai_socktype := SOCK_DGRAM; //*dummy*/ + LHints.ai_flags := AI_NUMERICHOST; + if getaddrinfo( + {$IFDEF USE_MARSHALLED_PTRS} + LHostNamePtr.ToPointer + {$ELSE} + LHostName + {$ENDIF}, + '0', LHints, LAddrInfo) = 0 then + begin + freeaddrinfo(LAddrInfo^); + Result := ''; + raise EIdMaliciousPtrRecord.Create(RSMaliciousPtrRecord); + end; + + {$IFDEF USE_MARSHALLED_PTRS} + Result := TMarshal.ReadStringAsAnsi(LHostNamePtr); + {$ELSE} + Result := String(LHostName); + {$ENDIF} +end; + +function TIdStackVCLPosix.HostByName(const AHostName: string; + const AIPVersion: TIdIPVersion): string; +var + LAddrInfo: pAddrInfo; + LHints: AddrInfo; + LRetVal: Integer; + {$IFDEF USE_MARSHALLED_PTRS} + M: TMarshaller; + {$ENDIF} +begin + if not (AIPVersion in [Id_IPv4, Id_IPv6]) then begin + IPVersionUnsupported; + end; + //IMPORTANT!!! + // + //The Hints structure must be zeroed out or you might get an AV. + //I've seen this in Mac OS X + FillChar(LHints, SizeOf(LHints), 0); + LHints.ai_family := IdIPFamily[AIPVersion]; + LHints.ai_socktype := SOCK_STREAM; + LAddrInfo := nil; + + LRetVal := getaddrinfo( + {$IFDEF USE_MARSHALLED_PTRS} + M.AsAnsi(AHostName).ToPointer + {$ELSE} + PAnsiChar( + {$IFDEF STRING_IS_ANSI} + AHostName + {$ELSE} + AnsiString(AHostName) // explicit convert to Ansi + {$ENDIF} + ) + {$ENDIF}, + nil, LHints, LAddrInfo); + if LRetVal <> 0 then begin + if LRetVal = EAI_SYSTEM then begin + RaiseLastOSError; + end else begin + raise EIdResolveError.CreateFmt(RSReverseResolveError, [AHostName, gai_strerror(LRetVal), LRetVal]); + end; + end; + try + if AIPVersion = Id_IPv4 then begin + Result := TranslateTInAddrToString( PSockAddr_In( LAddrInfo^.ai_addr)^.sin_addr, AIPVersion); + end else begin + Result := TranslateTInAddrToString( PSockAddr_In6( LAddrInfo^.ai_addr)^.sin6_addr, AIPVersion); + end; + finally + freeaddrinfo(LAddrInfo^); + end; +end; + +function TIdStackVCLPosix.HostToNetwork(AValue: UInt32): UInt32; +begin + Result := htonl(AValue); +end; + +function TIdStackVCLPosix.HostToNetwork(AValue: UInt16): UInt16; +begin + Result := htons(AValue); +end; + +function TIdStackVCLPosix.HostToNetwork(AValue: TIdUInt64): TIdUInt64; +var + LParts: TIdUInt64Parts; + L: UInt32; +begin + if (htonl(1) <> 1) then begin + LParts.QuadPart := AValue; + L := htonl(LParts.HighPart); + LParts.HighPart := htonl(LParts.LowPart); + LParts.LowPart := L; + Result := LParts.QuadPart; + end else begin + Result := AValue; + end; +end; + +function TIdStackVCLPosix.IOControl(const s: TIdStackSocketHandle; + const cmd: UInt32; var arg: UInt32): Integer; +begin + Result := ioctl(s, cmd, @arg); +end; + +procedure TIdStackVCLPosix.Listen(ASocket: TIdStackSocketHandle; + ABackLog: Integer); +begin + CheckForSocketError(Posix.SysSocket.listen(ASocket, ABacklog)); +end; + +function TIdStackVCLPosix.NetworkToHost(AValue: UInt32): UInt32; +begin + Result := ntohl(AValue); +end; + +function TIdStackVCLPosix.NetworkToHost(AValue: TIdUInt64): TIdUInt64; +var + LParts: TIdUInt64Parts; + L: UInt32; +begin + if (ntohl(1) <> 1) then begin + LParts.QuadPart := AValue; + L := ntohl(LParts.HighPart); + LParts.HighPart := ntohl(LParts.LowPart); + LParts.LowPart := L; + Result := LParts.QuadPart; + end else begin + Result := AValue; + end; +end; + +function TIdStackVCLPosix.NetworkToHost(AValue: UInt16): UInt16; +begin + Result := ntohs(AValue); +end; + +function TIdStackVCLPosix.ReadHostName: string; +const + sMaxHostSize = 250; +var + LStr: array[0..sMaxHostSize] of TIdAnsiChar; + {$IFDEF USE_MARSHALLED_PTRS} + LStrPtr: TPtrWrapper; + {$ENDIF} +begin + {$IFDEF USE_MARSHALLED_PTRS} + LStrPtr := TPtrWrapper.Create(@LStr[0]); + {$ENDIF} + if gethostname( + {$IFDEF USE_MARSHALLED_PTRS} + LStrPtr.ToPointer + {$ELSE} + LStr + {$ENDIF}, sMaxHostSize) = 0 then + begin + {$IFDEF USE_MARSHALLED_PTRS} + Result := TMarshal.ReadStringAsAnsiUpTo(0, LStrPtr, sMaxHostSize); + {$ELSE} + LStr[sMaxHostSize] := TIdAnsiChar(0); + Result := String(LStr); + {$ENDIF} + end else begin + Result := ''; + end; +end; + +function TIdStackVCLPosix.ReceiveMsg(ASocket: TIdStackSocketHandle; + var VBuffer: TIdBytes; APkt: TIdPacketInfo): UInt32; +var + LSize: socklen_t; + LAddrStore: sockaddr_storage; + LAddrIPv4 : SockAddr_In absolute LAddrStore; + LAddrIPv6 : sockaddr_in6 absolute LAddrStore; + LAddr : sockaddr absolute LAddrStore; + LMsg : msghdr; + LIOV : iovec; + LControl : TIdBytes; + LCurCmsg : Pcmsghdr; //for iterating through the control buffer + LByte : PByte; + +begin + //we call the macro twice because we specified two possible structures. + //Id_IPV6_HOPLIMIT and Id_IPV6_PKTINFO + LSize := CMSG_SPACE(SizeOf(Byte)) + CMSG_SPACE(SizeOf(in6_pktinfo)); + SetLength(LControl, LSize); + + LIOV.iov_len := Length(VBuffer); // Length(VMsgData); + LIOV.iov_base := @VBuffer[0]; // @VMsgData[0]; + + FillChar(LMsg,SizeOf(LMsg),0); + + LMsg.msg_iov := @LIOV;//lpBuffers := @LMsgBuf; + LMsg.msg_iovlen := 1; + + LMsg.msg_controllen := LSize; + LMsg.msg_control := @LControl[0]; + + LMsg.msg_name := @LAddr; + LMsg.msg_namelen := SizeOf(LAddrStore); + + Result := 0; + CheckForSocketError(RecvMsg(ASocket, LMsg, Result)); + APkt.Reset; + + case LAddrStore.ss_family of + Id_PF_INET4: begin + APkt.SourceIP := TranslateTInAddrToString(LAddrIPv4.sin_addr, Id_IPv4); + APkt.SourcePort := ntohs(LAddrIPv4.sin_port); + APkt.SourceIPVersion := Id_IPv4; + end; + Id_PF_INET6: begin + APkt.SourceIP := TranslateTInAddrToString(LAddrIPv6.sin6_addr, Id_IPv6); + APkt.SourcePort := ntohs(LAddrIPv6.sin6_port); + APkt.SourceIPVersion := Id_IPv6; + end; + else begin + Result := 0; // avoid warning + IPVersionUnsupported; + end; + end; + + LCurCmsg := nil; + repeat + LCurCmsg := CMSG_NXTHDR(@LMsg, LCurCmsg); + if LCurCmsg = nil then begin + break; + end; + case LCurCmsg^.cmsg_type of + IPV6_PKTINFO : //done this way because IPV6_PKTINF and IP_PKTINFO are both 19 + begin + case LAddrStore.ss_family of + Id_PF_INET4: begin + {$IFDEF IOS} + ToDo('PKTINFO not implemented for IPv4 under iOS yet'); + {$ELSE} + {$IFNDEF OSX} + //This is not supported in OS X. + with Pin_pktinfo(CMSG_DATA(LCurCmsg))^ do begin + APkt.DestIP := TranslateTInAddrToString(ipi_addr, Id_IPv4); + APkt.DestIF := ipi_ifindex; + end; + APkt.DestIPVersion := Id_IPv4; + {$ENDIF} + {$ENDIF} + end; + Id_PF_INET6: begin + with pin6_pktinfo(CMSG_DATA(LCurCmsg))^ do begin + APkt.DestIP := TranslateTInAddrToString(ipi6_addr, Id_IPv6); + APkt.DestIF := ipi6_ifindex; + end; + APkt.DestIPVersion := Id_IPv6; + end; + end; + end; + Id_IPV6_HOPLIMIT : + begin + LByte := PByte(CMSG_DATA(LCurCmsg)); + APkt.TTL := LByte^; + end; + end; + until False; +end; + +function TIdStackVCLPosix.RecvFrom(const ASocket: TIdStackSocketHandle; + var VBuffer; const ALength, AFlags: Integer; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; +var + LiSize: socklen_t; + LAddrStore: sockaddr_storage; + LAddrIPv4 : SockAddr_In absolute LAddrStore; + LAddrIPv6 : sockaddr_in6 absolute LAddrStore; + LAddr : sockaddr absolute LAddrStore; + +begin + LiSize := SizeOf(LAddrStore); + // TODO: only include MSG_NOSIGNAL if SO_NOSIGPIPE is not enabled? + Result := Posix.SysSocket.recvfrom(ASocket,VBuffer, ALength, AFlags or Id_MSG_NOSIGNAL, LAddr, LiSize); + if Result >= 0 then + begin + case LAddrStore.ss_family of + Id_PF_INET4: begin + VIP := TranslateTInAddrToString(LAddrIPv4.sin_addr, Id_IPv4); + VPort := ntohs(LAddrIPv4.sin_port); + VIPVersion := Id_IPV4; + end; + Id_PF_INET6: begin + VIP := TranslateTInAddrToString(LAddrIPv6.sin6_addr, Id_IPv6); + VPort := ntohs(LAddrIPv6.sin6_port); + VIPVersion := Id_IPV6; + end; + else begin + Result := 0; + IPVersionUnsupported; + end; + end; + end; +end; + +procedure TIdStackVCLPosix.SetBlocking(ASocket: TIdStackSocketHandle; + const ABlocking: Boolean); +var + LFlags: Integer; +begin + LFlags := CheckForSocketError(fcntl(ASocket, F_GETFL, 0)); + if ABlocking then begin + LFlags := LFlags and not O_NONBLOCK; + end else begin + LFlags := LFlags or O_NONBLOCK; + end; + CheckForSocketError(fcntl(ASocket, F_SETFL, LFlags)); +end; + +procedure TIdStackVCLPosix.SetLastError(const AError: Integer); +begin + __error^ := AError; +end; + +procedure TIdStackVCLPosix.{$IFDEF VCL_XE3_OR_ABOVE}GetSocketOption{$ELSE}WSGetSocketOption{$ENDIF} + (ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; + var AOptVal; var AOptLen: Integer); +var + LLen : socklen_t; +begin + LLen := AOptLen; + CheckForSocketError(Posix.SysSocket.getsockopt(ASocket, ALevel, AOptName, AOptVal, LLen)); + AOptLen := LLen; +end; + +procedure TIdStackVCLPosix.{$IFDEF VCL_XE3_OR_ABOVE}SetSocketOption{$ELSE}WSSetSocketOption{$ENDIF} + (ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; + const AOptVal; const AOptLen: Integer); +begin + CheckForSocketError(Posix.SysSocket.setsockopt(ASocket, ALevel, AOptName, AOptVal, AOptLen)); +end; + +function TIdStackVCLPosix.SupportsIPv4: Boolean; +begin + {$IFDEF IOS} + // TODO: iOS 9+ is IPv6-only... + //Result := ([[[UIDevice currentDevice] systemVersion] compare:'9.0' options:NSNumericSearch] == NSOrderedAscending); + {$ENDIF} + //In Windows, this does something else. It checks the LSP's installed. + Result := CheckIPVersionSupport(Id_IPv4); +end; + +function TIdStackVCLPosix.SupportsIPv6: Boolean; +begin + //In Windows, this does something else. It checks the LSP's installed. + Result := CheckIPVersionSupport(Id_IPv6); +end; + +function TIdStackVCLPosix.WouldBlock(const AResult: Integer): Boolean; +begin + // using if-else instead of in..range because EAGAIN and EWOULDBLOCK + // have often the same value and so FPC might report a range error + Result := (AResult = Id_WSAEAGAIN) or + (AResult = Id_WSAEWOULDBLOCK) or + (AResult = Id_WSAEINPROGRESS); +end; + +procedure TIdStackVCLPosix.WriteChecksum(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort; const AIPVersion: TIdIPVersion); +begin + case AIPVersion of + Id_IPv4 : CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(VBuffer)), VBuffer, AOffset); + Id_IPv6 : WriteChecksumIPv6(s, VBuffer, AOffset, AIP, APort); + else + IPVersionUnsupported; + end; +end; + +procedure TIdStackVCLPosix.WriteChecksumIPv6(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort); +begin +//we simply request that the kernal write the checksum when the data +//is sent. All of the parameters required are because Windows is bonked +//because it doesn't have the IPV6CHECKSUM socket option meaning we have +//to querry the network interface in TIdStackWindows -- yuck!! + SetSocketOption(s, Id_IPPROTO_IPV6, IPV6_CHECKSUM, AOffset); +end; + +function TIdStackVCLPosix.WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; +begin + Result := __close(ASocket); +end; + +function TIdStackVCLPosix.WSGetLastError: Integer; +begin + //IdStackWindows just uses result := WSAGetLastError; + Result := GetLastError; //System.GetLastOSError; - FPC doesn't define it in System + if Result = Id_WSAEPIPE then begin + Result := Id_WSAECONNRESET; + end; +end; + +function TIdStackVCLPosix.WSGetServByName(const AServiceName: string): TIdPort; +var + Lps: PServEnt; + {$IFDEF USE_MARSHALLED_PTRS} + M: TMarshaller; + {$ENDIF} +begin + Lps := Posix.NetDB.getservbyname( + {$IFDEF USE_MARSHALLED_PTRS} + M.AsAnsi(AServiceName).ToPointer + {$ELSE} + PAnsiChar( + {$IFDEF STRING_IS_ANSI} + AServiceName + {$ELSE} + AnsiString(AServiceName) // explicit convert to Ansi + {$ENDIF} + ) + {$ENDIF}, + nil); + if Lps <> nil then begin + Result := ntohs(Lps^.s_port); + end else begin + try + Result := IndyStrToInt(AServiceName); + except + on EConvertError do begin + Result := 0; + IndyRaiseOuterException(EIdInvalidServiceName.CreateFmt(RSInvalidServiceName, [AServiceName])); + end; + end; + end; +end; + +procedure TIdStackVCLPosix.AddServByPortToList(const APortNumber: TIdPort; AAddresses: TStrings); +//function TIdStackVCLPosix.WSGetServByPort(const APortNumber: TIdPort): TStrings; +type + PPAnsiCharArray = ^TPAnsiCharArray; + TPAnsiCharArray = packed array[0..(MaxInt div SizeOf(PIdAnsiChar))-1] of PIdAnsiChar; +var + Lps: PServEnt; + Li: Integer; + Lp: PPAnsiCharArray; +begin + Lps := Posix.NetDB.getservbyport(htons(APortNumber), nil); + if Lps <> nil then begin + AAddresses.BeginUpdate; + try + AAddresses.Add(String(Lps^.s_name)); + Li := 0; + Lp := Pointer(Lps^.s_aliases); + while Lp[Li] <> nil do begin + AAddresses.Add(String(Lp[Li])); + Inc(Li); + end; + finally + AAddresses.EndUpdate; + end; + end; +end; + +function TIdStackVCLPosix.WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; + const ABufferLength, AFlags: Integer): Integer; +begin + //IdStackWindows is just: Result := Recv(ASocket, ABuffer, ABufferLength, AFlags); + // TODO: only include MSG_NOSIGNAL if SO_NOSIGPIPE is not enabled? + Result := Posix.SysSocket.Recv(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL); +end; + +function TIdStackVCLPosix.WSSend(ASocket: TIdStackSocketHandle; const ABuffer; + const ABufferLength, AFlags: Integer): Integer; +begin + // TODO: only include MSG_NOSIGNAL if SO_NOSIGPIPE is not enabled? + Result := CheckForSocketError(Posix.SysSocket.send(ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL)); +end; + +procedure TIdStackVCLPosix.WSSendTo(ASocket: TIdStackSocketHandle; + const ABuffer; const ABufferLength, AFlags: Integer; const AIP: string; + const APort: TIdPort; AIPVersion: TIdIPVersion); +var + LAddrStore: sockaddr_storage; + LAddrIPv4 : SockAddr_In absolute LAddrStore; + LAddrIPv6 : sockaddr_in6 absolute LAddrStore; + LAddr : sockaddr absolute LAddrStore; + LiSize: socklen_t; + LBytesSent: Integer; +begin + case AIPVersion of + Id_IPv4: begin + InitSockAddr_In(LAddrIPv4); + TranslateStringToTInAddr(AIP, LAddrIPv4.sin_addr, Id_IPv4); + LAddrIPv4.sin_port := htons(APort); + LiSize := SizeOf(LAddrIPv4); + end; + Id_IPv6: begin + InitSockAddr_in6(LAddrIPv6); + TranslateStringToTInAddr(AIP, LAddrIPv6.sin6_addr, Id_IPv6); + LAddrIPv6.sin6_port := htons(APort); + LiSize := SizeOf(LAddrIPv6); + end; + else + LiSize := 0; // avoid warning + IPVersionUnsupported; + end; + // TODO: only include MSG_NOSIGNAL if SO_NOSIGPIPE is not enabled? + LBytesSent := Posix.SysSocket.sendto( + ASocket, ABuffer, ABufferLength, AFlags or Id_MSG_NOSIGNAL, LAddr, LiSize); + if LBytesSent = Id_SOCKET_ERROR then begin + // TODO: move this into RaiseLastSocketError directly + if WSGetLastError() = Id_WSAEMSGSIZE then begin + raise EIdPackageSizeTooBig.Create(RSPackageSizeTooBig); + end else begin + RaiseLastSocketError; + end; + end + else if LBytesSent <> ABufferLength then begin + raise EIdNotAllBytesSent.Create(RSNotAllBytesSent); + end; + +end; + +procedure TIdStackVCLPosix.WSSetLastError(const AErr: Integer); +begin + __error^ := AErr; +end; + +function TIdStackVCLPosix.WSShutdown(ASocket: TIdStackSocketHandle; + AHow: Integer): Integer; +begin + Result := Posix.SysSocket.shutdown(ASocket, AHow); +end; + +function TIdStackVCLPosix.WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; + const ANonBlocking: Boolean = False): TIdStackSocketHandle; +var + LFlags: Integer; +begin + Result := Posix.SysSocket.socket(AFamily, AStruct, AProtocol); + if Result <> INVALID_SOCKET then begin + {$IFDEF HAS_SOCKET_NOSIGPIPE} + SetSocketOption(Result, SOL_SOCKET, SO_NOSIGPIPE, 1); + {$ENDIF} + //SetBlocking(Result, not ANonBlocking); + if ANonBlocking then begin + LFlags := fcntl(Result, F_GETFL, 0); + LFlags := LFlags or O_NONBLOCK; + fcntl(Result, F_SETFL, LFlags); + end; + end; +end; + +{$I IdUnitPlatformOn.inc} +{$I IdSymbolPlatformOn.inc} +initialization + GSocketListClass := TIdSocketListVCLPosix; +end. diff --git a/Lib/System/IdStackWindows.pas b/Lib/System/IdStackWindows.pas index f84002978..bf9479c60 100644 --- a/Lib/System/IdStackWindows.pas +++ b/Lib/System/IdStackWindows.pas @@ -1,2597 +1,2597 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. - - - $Log$ - - - Rev 1.8 10/26/2004 8:20:04 PM JPMugaas - Fixed some oversights with conversion. OOPS!!! - - - Rev 1.7 07/06/2004 21:31:24 CCostelloe - Kylix 3 changes - - - Rev 1.6 4/18/04 10:43:24 PM RLebeau - Fixed syntax error - - - Rev 1.5 4/18/04 10:29:58 PM RLebeau - Renamed Int64Parts structure to TIdInt64Parts - - - Rev 1.4 4/18/04 2:47:46 PM RLebeau - Conversion support for Int64 values - - - Rev 1.3 2004.03.07 11:45:28 AM czhower - Flushbuffer fix + other minor ones found - - - Rev 1.2 3/6/2004 5:16:34 PM JPMugaas - Bug 67 fixes. Do not write to const values. - - - Rev 1.1 3/6/2004 4:23:52 PM JPMugaas - Error #62 fix. This seems to work in my tests. - - - Rev 1.0 2004.02.03 3:14:48 PM czhower - Move and updates - - - Rev 1.33 2/1/2004 6:10:56 PM JPMugaas - GetSockOpt. - - - Rev 1.32 2/1/2004 3:28:36 AM JPMugaas - Changed WSGetLocalAddress to GetLocalAddress and moved into IdStack since - that will work the same in the DotNET as elsewhere. This is required to - reenable IPWatch. - - - Rev 1.31 1/31/2004 1:12:48 PM JPMugaas - Minor stack changes required as DotNET does support getting all IP addresses - just like the other stacks. - - - Rev 1.30 12/4/2003 3:14:52 PM BGooijen - Added HostByAddress - - - Rev 1.29 1/3/2004 12:38:56 AM BGooijen - Added function SupportsIPv6 - - - Rev 1.28 12/31/2003 9:52:02 PM BGooijen - Added IPv6 support - - - Rev 1.27 10/26/2003 05:33:14 PM JPMugaas - LocalAddresses should work. - - - Rev 1.26 10/26/2003 5:04:28 PM BGooijen - UDP Server and Client - - - Rev 1.25 10/26/2003 09:10:26 AM JPMugaas - Calls necessary for IPMulticasting. - - - Rev 1.24 10/22/2003 04:40:52 PM JPMugaas - Should compile with some restored functionality. Still not finished. - - - Rev 1.23 10/21/2003 11:04:20 PM BGooijen - Fixed name collision - - - Rev 1.22 10/21/2003 01:20:02 PM JPMugaas - Restore GWindowsStack because it was needed by SuperCore. - - - Rev 1.21 10/21/2003 06:24:28 AM JPMugaas - BSD Stack now have a global variable for refercing by platform specific - things. Removed corresponding var from Windows stack. - - - Rev 1.20 10/19/2003 5:21:32 PM BGooijen - SetSocketOption - - - Rev 1.19 2003.10.11 5:51:16 PM czhower - -VCL fixes for servers - -Chain suport for servers (Super core) - -Scheduler upgrades - -Full yarn support - - - Rev 1.18 2003.10.02 8:01:08 PM czhower - .Net - - - Rev 1.17 2003.10.02 12:44:44 PM czhower - Fix for Bind, Connect - - - Rev 1.16 2003.10.02 10:16:32 AM czhower - .Net - - - Rev 1.15 2003.10.01 9:11:26 PM czhower - .Net - - - Rev 1.14 2003.10.01 12:30:08 PM czhower - .Net - - - Rev 1.12 10/1/2003 12:14:12 AM BGooijen - DotNet: removing CheckForSocketError - - - Rev 1.11 2003.10.01 1:12:40 AM czhower - .Net - - - Rev 1.10 2003.09.30 1:23:04 PM czhower - Stack split for DotNet - - - Rev 1.9 9/8/2003 02:13:10 PM JPMugaas - SupportsIP6 function added for determining if IPv6 is installed on a system. - - - Rev 1.8 2003.07.14 1:57:24 PM czhower - -First set of IOCP fixes. - -Fixed a threadsafe problem with the stack class. - - - Rev 1.7 7/1/2003 05:20:44 PM JPMugaas - Minor optimizations. Illiminated some unnecessary string operations. - - - Rev 1.5 7/1/2003 03:39:58 PM JPMugaas - Started numeric IP function API calls for more efficiency. - - - Rev 1.4 7/1/2003 12:46:06 AM JPMugaas - Preliminary stack functions taking an IP address numerical structure instead - of a string. - - - Rev 1.3 5/19/2003 6:00:28 PM BGooijen - TIdStackWindows.WSGetHostByAddr raised an ERangeError when the last number in - the ip>127 - - - Rev 1.2 5/10/2003 4:01:28 PM BGooijen - - - Rev 1.1 2003.05.09 10:59:28 PM czhower - - - Rev 1.0 11/13/2002 08:59:38 AM JPMugaas -} -unit IdStackWindows; - -interface - -{$I IdCompilerDefines.inc} - -uses - Classes, - IdGlobal, IdException, IdStackBSDBase, IdStackConsts, IdWinsock2, IdStack, - SysUtils, - Windows; - -type - EIdIPv6Unavailable = class(EIdException); - - TIdStackWindows = class(TIdStackBSDBase) - protected - procedure WSQuerryIPv6Route(ASocket: TIdStackSocketHandle; - const AIP: String; const APort : UInt16; var VSource; var VDest); - procedure WriteChecksumIPv6(s : TIdStackSocketHandle; var VBuffer : TIdBytes; - const AOffset : Integer; const AIP : String; const APort : TIdPort); - function HostByName(const AHostName: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; - function ReadHostName: string; override; - function WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; override; - function WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; - const ABufferLength, AFlags: Integer): Integer; override; - function WSSend(ASocket: TIdStackSocketHandle; const ABuffer; - const ABufferLength, AFlags: Integer): Integer; override; - function WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; override; - {$IFNDEF VCL_XE3_OR_ABOVE} - procedure WSGetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; - procedure WSSetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; - {$ENDIF} - public - function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; - var VIPVersion: TIdIPVersion): TIdStackSocketHandle; override; - function HostToNetwork(AValue: UInt16): UInt16; override; - function HostToNetwork(AValue: UInt32): UInt32; override; - function HostToNetwork(AValue: TIdUInt64): TIdUInt64; override; - procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); override; - function NetworkToHost(AValue: UInt16): UInt16; override; - function NetworkToHost(AValue: UInt32): UInt32; override; - function NetworkToHost(AValue: TIdUInt64): TIdUInt64; override; - procedure SetBlocking(ASocket: TIdStackSocketHandle; const ABlocking: Boolean); override; - function WouldBlock(const AResult: Integer): Boolean; override; - // - function HostByAddress(const AAddress: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; - - function WSGetServByName(const AServiceName: string): TIdPort; override; - procedure AddServByPortToList(const APortNumber: TIdPort; AAddresses: TStrings); override; - - function RecvFrom(const ASocket: TIdStackSocketHandle; var VBuffer; - const ALength, AFlags: Integer; var VIP: string; var VPort: TIdPort; - var VIPVersion: TIdIPVersion): Integer; override; - function ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; - APkt : TIdPacketInfo): UInt32; override; - - procedure WSSendTo(ASocket: TIdStackSocketHandle; const ABuffer; - const ABufferLength, AFlags: Integer; const AIP: string; const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - - function WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; - const ANonBlocking: Boolean = False): TIdStackSocketHandle; override; - function WSTranslateSocketErrorMsg(const AErr: integer): string; override; - function WSGetLastError: Integer; override; - procedure WSSetLastError(const AErr : Integer); override; - // - procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; - const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - constructor Create; override; - destructor Destroy; override; - procedure Disconnect(ASocket: TIdStackSocketHandle); override; - procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; - procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; - {$IFDEF VCL_XE3_OR_ABOVE} - procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; - procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; - AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; - {$ENDIF} - function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; var arg: UInt32): Integer; override; - function SupportsIPv4: Boolean; override; - function SupportsIPv6: Boolean; override; - function CheckIPVersionSupport(const AIPVersion: TIdIPVersion): boolean; override; - procedure WriteChecksum(s : TIdStackSocketHandle; - var VBuffer : TIdBytes; - const AOffset : Integer; - const AIP : String; - const APort : TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; - procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); override; - procedure SetKeepAliveValues(ASocket: TIdStackSocketHandle; - const AEnabled: Boolean; const ATimeMS, AInterval: Integer); override; - end; - -var -//This is for the Win32-only package (SuperCore) - GWindowsStack : TIdStackWindows = nil{$IFDEF HAS_DEPRECATED}{$IFDEF USE_SEMICOLON_BEFORE_DEPRECATED};{$ENDIF} deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use GStack or GBSDStack instead'{$ENDIF}{$ENDIF}; - -implementation - -{$DEFINE USE_IPHLPAPI} - -{$IFDEF USE_IPHLPAPI} - // TODO: Move this to IdCompilerDefines.inc - {$IFDEF VCL_XE2_OR_ABOVE} - {$DEFINE HAS_UNIT_IpTypes} - {$DEFINE HAS_UNIT_IpHlpApi} - {$ENDIF} -{$ENDIF} - -uses - IdIDN, IdResourceStrings, IdWship6 - {$IFDEF USE_IPHLPAPI} - {$IFDEF HAS_UNIT_IpTypes} - , Winapi.IpTypes - {$ENDIF} - {$IFDEF HAS_UNIT_IpHlpApi} - , Winapi.IpHlpApi - {$ENDIF} - {$ENDIF} - ; - -{$IFNDEF WINCE} -type - TGetFileSizeEx = function(hFile : THandle; var lpFileSize : LARGE_INTEGER) : BOOL; stdcall; -{$ENDIF} - -const - SIZE_HOSTNAME = 250; - -var - GStarted: Boolean = False; - {$IFNDEF WINCE} - GetFileSizeEx : TGetFileSizeEx = nil; - {$ENDIF} - -{ IPHLPAPI support } - -{$IFDEF USE_IPHLPAPI} - -const - IPHLPAPI_DLL = 'iphlpapi.dll'; - {$IFNDEF HAS_UNIT_IpTypes} - MAX_ADAPTER_DESCRIPTION_LENGTH = 128; - MAX_ADAPTER_NAME_LENGTH = 256; - MAX_ADAPTER_ADDRESS_LENGTH = 8; - MAX_DHCPV6_DUID_LENGTH = 130; - MAX_DNS_SUFFIX_STRING_LENGTH = 256; - GAA_FLAG_SKIP_UNICAST = $0001; - GAA_FLAG_SKIP_ANYCAST = $0002; - GAA_FLAG_SKIP_MULTICAST = $0004; - GAA_FLAG_SKIP_DNS_SERVER = $0008; - GAA_FLAG_INCLUDE_PREFIX = $0010; - GAA_FLAG_SKIP_FRIENDLY_NAME = $0020; - IP_ADAPTER_RECEIVE_ONLY = $08; - {$ENDIF} - IF_TYPE_SOFTWARE_LOOPBACK = 24; - -type - PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS = ^IP_UNIDIRECTIONAL_ADAPTER_ADDRESS; - IP_UNIDIRECTIONAL_ADAPTER_ADDRESS = record - NumAdapters: ULONG; - Address: array[0..0] of TInAddr; - end; - - {$IFNDEF HAS_UNIT_IpTypes} - {$MINENUMSIZE 4} - - time_t = TIdNativeInt; - IFTYPE = ULONG; - IF_INDEX = ULONG; - NET_IF_COMPARTMENT_ID = UINT32; - NET_IF_NETWORK_GUID = TGUID; - - IP_PREFIX_ORIGIN = ( - IpPrefixOriginOther, - IpPrefixOriginManual, - IpPrefixOriginWellKnown, - IpPrefixOriginDhcp, - IpPrefixOriginRouterAdvertisement, - {$IFNDEF HAS_ENUM_ELEMENT_VALUES} - ippoUnused5, - ippoUnused6, - ippoUnused7, - ippoUnused8, - ippoUnused9, - ippoUnused10, - ippoUnused11, - ippoUnused12, - ippoUnused13, - ippoUnused14, - ippoUnused15, - {$ENDIF} - IpPrefixOriginUnchanged); - - IP_SUFFIX_ORIGIN = ( - IpSuffixOriginOther, - IpSuffixOriginManual, - IpSuffixOriginWellKnown, - IpSuffixOriginDhcp, - IpSuffixOriginLinkLayerAddress, - IpSuffixOriginRandom, - {$IFNDEF HAS_ENUM_ELEMENT_VALUES} - ipsoUnued6, - ipsoUnued7, - ipsoUnued8, - ipsoUnued9, - ipsoUnued10, - ipsoUnued11, - ipsoUnued12, - ipsoUnued13, - ipsoUnued14, - ipsoUnued15, - {$ENDIF} - IpSuffixOriginUnchanged); - - IP_DAD_STATE = ( - IpDadStateInvalid, - IpDadStateTentative, - IpDadStateDuplicate, - IpDadStateDeprecated, - IpDadStatePreferred); - - IF_OPER_STATUS = ( - {$IFNDEF HAS_ENUM_ELEMENT_VALUES} - ifosUnused, - IfOperStatusUp, - {$ELSE} - IfOperStatusUp = 1, - {$ENDIF} - IfOperStatusDown, - IfOperStatusTesting, - IfOperStatusUnknown, - IfOperStatusDormant, - IfOperStatusNotPresent, - IfOperStatusLowerLayerDown); - - NET_IF_CONNECTION_TYPE = ( - {$IFNDEF HAS_ENUM_ELEMENT_VALUES} - nictUnused, - NetIfConnectionDedicated, - {$ELSE} - NetIfConnectionDedicated = 1, - {$ENDIF} - NetIfConnectionPassive, - NetIfConnectionDemand, - NetIfConnectionMaximum); - - TUNNEL_TYPE = ( - TunnelTypeNone, - TunnelTypeOther, - TunnelTypeDirect, - TunnelType6To4, - TunnelTypeIsatap, - TunnelTypeTeredo, - TunnelTypeIPHTTPS); - - IP_ADDRESS_STRING = record - S: array [0..15] of TIdAnsiChar; - end; - IP_MASK_STRING = IP_ADDRESS_STRING; - - PIP_ADDR_STRING = ^IP_ADDR_STRING; - IP_ADDR_STRING = record - Next: PIP_ADDR_STRING; - IpAddress: IP_ADDRESS_STRING; - IpMask: IP_MASK_STRING; - Context: DWORD; - end; - - PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO; - IP_ADAPTER_INFO = record - Next: PIP_ADAPTER_INFO; - ComboIndex: DWORD; - AdapterName: array [0..MAX_ADAPTER_NAME_LENGTH + 3] of TIdAnsiChar; - Description: array [0..MAX_ADAPTER_DESCRIPTION_LENGTH + 3] of TIdAnsiChar; - AddressLength: UINT; - Address: array [0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE; - Index: DWORD; - Type_: UINT; - DhcpEnabled: UINT; - CurrentIpAddress: PIP_ADDR_STRING; - IpAddressList: IP_ADDR_STRING; - GatewayList: IP_ADDR_STRING; - DhcpServer: IP_ADDR_STRING; - HaveWins: BOOL; - PrimaryWinsServer: IP_ADDR_STRING; - SecondaryWinsServer: IP_ADDR_STRING; - LeaseObtained: time_t; - LeaseExpires: time_t; - end; - - SOCKET_ADDRESS = record - lpSockaddr: IdWinsock2.LPSOCKADDR; - iSockaddrLength: Integer; - end; - - PIP_ADAPTER_UNICAST_ADDRESS = ^IP_ADAPTER_UNICAST_ADDRESS; - IP_ADAPTER_UNICAST_ADDRESS = record - Union: record - case Integer of - 0: ( - Alignment: ULONGLONG); - 1: ( - Length: ULONG; - Flags: DWORD); - end; - Next: PIP_ADAPTER_UNICAST_ADDRESS; - Address: SOCKET_ADDRESS; - PrefixOrigin: IP_PREFIX_ORIGIN; - SuffixOrigin: IP_SUFFIX_ORIGIN; - DadState: IP_DAD_STATE; - ValidLifetime: ULONG; - PreferredLifetime: ULONG; - LeaseLifetime: ULONG; - - // This structure member is only available on Windows Vista and later - OnLinkPrefixLength: UCHAR; - end; - - PIP_ADAPTER_ANYCAST_ADDRESS = ^IP_ADAPTER_ANYCAST_ADDRESS; - IP_ADAPTER_ANYCAST_ADDRESS = record - Union: record - case Integer of - 0: ( - Alignment: ULONGLONG); - 1: ( - Length: ULONG; - Flags: DWORD); - end; - Next: PIP_ADAPTER_ANYCAST_ADDRESS; - Address: SOCKET_ADDRESS; - end; - - PIP_ADAPTER_MULTICAST_ADDRESS = ^IP_ADAPTER_MULTICAST_ADDRESS; - IP_ADAPTER_MULTICAST_ADDRESS = record - Union: record - case Integer of - 0: ( - Alignment: ULONGLONG); - 1: ( - Length: ULONG; - Flags: DWORD); - end; - Next: PIP_ADAPTER_MULTICAST_ADDRESS; - Address: SOCKET_ADDRESS; - end; - - PIP_ADAPTER_DNS_SERVER_ADDRESS = ^IP_ADAPTER_DNS_SERVER_ADDRESS; - IP_ADAPTER_DNS_SERVER_ADDRESS = record - Union: record - case Integer of - 0: ( - Alignment: ULONGLONG); - 1: ( - Length: ULONG; - Reserved: DWORD); - end; - Next: PIP_ADAPTER_DNS_SERVER_ADDRESS; - Address: SOCKET_ADDRESS; - end; - - PIP_ADAPTER_PREFIX = ^IP_ADAPTER_PREFIX; - IP_ADAPTER_PREFIX = record - Union: record - case Integer of - 0: ( - Alignment: ULONGLONG); - 1: ( - Length: ULONG; - Flags: DWORD); - end; - Next: PIP_ADAPTER_PREFIX; - Address: SOCKET_ADDRESS; - PrefixLength: ULONG; - end; - - PIP_ADAPTER_WINS_SERVER_ADDRESS_LH = ^IP_ADAPTER_WINS_SERVER_ADDRESS_LH; - IP_ADAPTER_WINS_SERVER_ADDRESS_LH = record - Union: record - case Integer of - 0: ( - Alignment: ULONGLONG); - 1: ( - Length: ULONG; - Reserved: DWORD); - end; - Next: PIP_ADAPTER_WINS_SERVER_ADDRESS_LH; - Address: SOCKET_ADDRESS; - end; - - PIP_ADAPTER_GATEWAY_ADDRESS_LH = ^IP_ADAPTER_GATEWAY_ADDRESS_LH; - IP_ADAPTER_GATEWAY_ADDRESS_LH = record - Union: record - case Integer of - 0: ( - Alignment: ULONGLONG); - 1: ( - Length: ULONG; - Reserved: DWORD); - end; - Next: PIP_ADAPTER_GATEWAY_ADDRESS_LH; - Address: SOCKET_ADDRESS; - end; - - IF_LUID = record - case Integer of - 0: ( - Value: ULONG64); - 1: ( - Info: ULONG64); - end; - - PIP_ADAPTER_DNS_SUFFIX = ^IP_ADAPTER_DNS_SUFFIX; - IP_ADAPTER_DNS_SUFFIX = record - Next: PIP_ADAPTER_DNS_SUFFIX; - AString: array[0..MAX_DNS_SUFFIX_STRING_LENGTH - 1] of WCHAR; - end; - - PIP_ADAPTER_ADDRESSES = ^IP_ADAPTER_ADDRESSES; - IP_ADAPTER_ADDRESSES = record - Union: record - case Integer of - 0: ( - Alignment: ULONGLONG); - 1: ( - Length: ULONG; - IfIndex: DWORD); - end; - Next: PIP_ADAPTER_ADDRESSES; - AdapterName: PIdAnsiChar; - FirstUnicastAddress: PIP_ADAPTER_UNICAST_ADDRESS; - FirstAnycastAddress: PIP_ADAPTER_ANYCAST_ADDRESS; - FirstMulticastAddress: PIP_ADAPTER_MULTICAST_ADDRESS; - FirstDnsServerAddress: PIP_ADAPTER_DNS_SERVER_ADDRESS; - DnsSuffix: PWCHAR; - Description: PWCHAR; - FriendlyName: PWCHAR; - PhysicalAddress: array [0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE; - PhysicalAddressLength: DWORD; - Flags: DWORD; - Mtu: DWORD; - IfType: IFTYPE; - OperStatus: IF_OPER_STATUS; - Ipv6IfIndex: IF_INDEX; - ZoneIndices: array [0..15] of DWORD; - FirstPrefix: PIP_ADAPTER_PREFIX; - TransmitLinkSpeed: ULONG64; - ReceiveLinkSpeed: ULONG64; - FirstWinsServerAddress: PIP_ADAPTER_WINS_SERVER_ADDRESS_LH; - FirstGatewayAddress: PIP_ADAPTER_GATEWAY_ADDRESS_LH; - Ipv4Metric: ULONG; - Ipv6Metric: ULONG; - Luid: IF_LUID; - Dhcpv4Server: SOCKET_ADDRESS; - CompartmentId: NET_IF_COMPARTMENT_ID; - NetworkGuid: NET_IF_NETWORK_GUID; - ConnectionType: NET_IF_CONNECTION_TYPE; - TunnelType: TUNNEL_TYPE; - // - // DHCP v6 Info. - // - Dhcpv6Server: SOCKET_ADDRESS; - Dhcpv6ClientDuid: array [0..MAX_DHCPV6_DUID_LENGTH - 1] of Byte; - Dhcpv6ClientDuidLength: ULONG; - Dhcpv6Iaid: ULONG; - FirstDnsSuffix: PIP_ADAPTER_DNS_SUFFIX; - end; - - {$ENDIF} - - PMIB_IPADDRROW = ^MIB_IPADDRROW; - MIB_IPADDRROW = record - dwAddr: DWORD; - dwIndex: DWORD; - dwMask: DWORD; - dwBCastAddr: DWORD; - dwReasmSize: DWORD; - unused1: Word; - wType: Word; - end; - - PMIB_IPADDRTABLE = ^MIB_IPADDRTABLE; - MIB_IPADDRTABLE = record - dwNumEntries: DWORD; - table: array[0..0] of MIB_IPADDRROW; - end; - - NETIO_STATUS = DWORD; - - TGetIpAddrTable = function(pIpAddrTable: PMIB_IPADDRTABLE; var pdwSize: ULONG; bOrder: BOOL): DWORD; stdcall; - TGetUniDirectionalAdapterInfo = function(pIPIfInfo: PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS; var dwOutBufLen: ULONG): DWORD; stdcall; - TGetAdaptersInfo = function(pAdapterInfo: PIP_ADAPTER_INFO; var pOutBufLen: ULONG): DWORD; stdcall; - TGetAdaptersAddresses = function(Family: ULONG; Flags: DWORD; Reserved: PVOID; pAdapterAddresses: PIP_ADAPTER_ADDRESSES; var OutBufLen: ULONG): DWORD; stdcall; - TConvertLengthToIpv4Mask = function(MaskLength: ULONG; var Mask: ULONG): NETIO_STATUS; stdcall; - -var - hIpHlpApi: TIdLibHandle = IdNilHandle; - GetIpAddrTable: TGetIpAddrTable = nil; - GetUniDirectionalAdapterInfo: TGetUniDirectionalAdapterInfo = nil; - GetAdaptersInfo: TGetAdaptersInfo = nil; - GetAdaptersAddresses: TGetAdaptersAddresses = nil; - ConvertLengthToIpv4Mask: TConvertLengthToIpv4Mask = nil; - -function FixupIPHelperStub(const AName: TIdLibFuncName; DefImpl: Pointer): Pointer; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := nil; - if hIpHlpApi <> IdNilHandle then begin - Result := LoadLibFunction(hIpHlpApi, AName); - end; - if Result = nil then begin - Result := DefImpl; - end; -end; - -function Impl_GetIpAddrTable(pIpAddrTable: PMIB_IPADDRTABLE; var pdwSize: ULONG; bOrder: BOOL): DWORD; stdcall; -begin - pdwSize := 0; - Result := ERROR_NOT_SUPPORTED; -end; - -function Stub_GetIpAddrTable(pIpAddrTable: PMIB_IPADDRTABLE; var pdwSize: ULONG; bOrder: BOOL): DWORD; stdcall; -begin - @GetIpAddrTable := FixupIPHelperStub('GetIpAddrTable', @Impl_GetIpAddrTable); {Do not localize} - Result := GetIpAddrTable(pIpAddrTable, pdwSize, bOrder); -end; - -function Impl_GetUniDirectionalAdapterInfo(pIPIfInfo: PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS; var dwOutBufLen: ULONG): DWORD; stdcall; -begin - dwOutBufLen := 0; - Result := ERROR_NOT_SUPPORTED; -end; - -function Stub_GetUniDirectionalAdapterInfo(pIPIfInfo: PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS; var dwOutBufLen: ULONG): DWORD; stdcall; -begin - @GetUniDirectionalAdapterInfo := FixupIPHelperStub('GetUniDirectionalAdapterInfo', @Impl_GetUniDirectionalAdapterInfo); {Do not localize} - Result := GetUniDirectionalAdapterInfo(pIPIfInfo, dwOutBufLen); -end; - -function Impl_GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO; var pOutBufLen: ULONG): DWORD; stdcall; -begin - pOutBufLen := 0; - Result := ERROR_NOT_SUPPORTED; -end; - -function Stub_GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO; var pOutBufLen: ULONG): DWORD; stdcall; -begin - @GetAdaptersInfo := FixupIPHelperStub('GetAdaptersInfo', @Impl_GetAdaptersInfo); {Do not localize} - Result := GetAdaptersInfo(pAdapterInfo, pOutBufLen); -end; - -function Impl_GetAdaptersAddresses(Family: ULONG; Flags: DWORD; Reserved: PVOID; pAdapterAddresses: PIP_ADAPTER_ADDRESSES; var OutBufLen: ULONG): DWORD; stdcall; -begin - OutBufLen := 0; - Result := ERROR_NOT_SUPPORTED; -end; - -function Stub_GetAdaptersAddresses(Family: ULONG; Flags: DWORD; Reserved: PVOID; pAdapterAddresses: PIP_ADAPTER_ADDRESSES; var OutBufLen: ULONG): DWORD; stdcall; -begin - @GetAdaptersAddresses := FixupIPHelperStub('GetAdaptersAddresses', @Impl_GetAdaptersAddresses); {Do not localize} - Result := GetAdaptersAddresses(Family, Flags, Reserved, pAdapterAddresses, OutBufLen); -end; - -function Impl_ConvertLengthToIpv4Mask(MaskLength: ULONG; var Mask: ULONG): NETIO_STATUS; stdcall; -begin - // TODO: implement manually - Mask := INADDR_NONE; - if MaskLength > 32 then begin - Result := ERROR_INVALID_PARAMETER; - end else begin - Result := ERROR_NOT_SUPPORTED; - end; -end; - -function Stub_ConvertLengthToIpv4Mask(MaskLength: ULONG; var Mask: ULONG): NETIO_STATUS; stdcall; -begin - @ConvertLengthToIpv4Mask := FixupIPHelperStub('ConvertLengthToIpv4Mask', @Impl_ConvertLengthToIpv4Mask); {Do not localize} - Result := ConvertLengthToIpv4Mask(MaskLength, Mask); -end; - -procedure InitializeIPHelperStubs; -begin - GetIpAddrTable := Stub_GetIpAddrTable; - GetUniDirectionalAdapterInfo := Stub_GetUniDirectionalAdapterInfo; - GetAdaptersInfo := Stub_GetAdaptersInfo; - GetAdaptersAddresses := Stub_GetAdaptersAddresses; - ConvertLengthToIpv4Mask := Stub_ConvertLengthToIpv4Mask; -end; - -procedure InitializeIPHelperAPI; -begin - if hIpHlpApi = IdNilHandle then begin - hIpHlpApi := SafeLoadLibrary(IPHLPAPI_DLL); - end; -end; - -procedure UninitializeIPHelperAPI; -begin - if hIpHlpApi <> IdNilHandle then - begin - FreeLibrary(hIpHlpApi); - hIpHlpApi := IdNilHandle; - end; - InitializeIPHelperStubs; -end; - -{$ENDIF} - -{ TIdStackWindows } - -constructor TIdStackWindows.Create; -begin - inherited Create; - if not GStarted then begin - try - InitializeWinSock; - IdWship6.InitLibrary; - IdIDN.InitIDNLibrary; - {$IFDEF USE_IPHLPAPI} - InitializeIPHelperAPI; - {$ENDIF} - except - on E: Exception do begin - IndyRaiseOuterException(EIdStackInitializationFailed.Create(E.Message)); - end; - end; - GStarted := True; - end; - {$I IdSymbolDeprecatedOff.inc} - GWindowsStack := Self; - {$I IdSymbolDeprecatedOn.inc} -end; - -destructor TIdStackWindows.Destroy; -begin - //DLL Unloading and Cleanup is done at finalization - inherited Destroy; -end; - -function TIdStackWindows.Accept(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): TIdStackSocketHandle; -var - LSize: Integer; - LAddr: SOCKADDR_STORAGE; -begin - LSize := SizeOf(LAddr); - Result := IdWinsock2.accept(ASocket, IdWinsock2.PSOCKADDR(@LAddr), @LSize); - if Result <> INVALID_SOCKET then begin - case LAddr.ss_family of - Id_PF_INET4: begin - VIP := TranslateTInAddrToString(PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); - VPort := ntohs(PSockAddrIn(@LAddr)^.sin_port); - VIPVersion := Id_IPv4; - end; - Id_PF_INET6: begin - VIP := TranslateTInAddrToString(PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); - VPort := ntohs(PSockAddrIn6(@LAddr)^.sin6_port); - VIPVersion := Id_IPv6; - end; - else begin - CloseSocket(Result); - Result := INVALID_SOCKET; - IPVersionUnsupported; - end; - end; - end; -end; - -procedure TIdStackWindows.Bind(ASocket: TIdStackSocketHandle; - const AIP: string; const APort: TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LAddr: SOCKADDR_STORAGE; - LSize: Integer; -begin - FillChar(LAddr, SizeOf(LAddr), 0); - case AIPVersion of - Id_IPv4: begin - PSockAddrIn(@LAddr)^.sin_family := Id_PF_INET4; - if AIP <> '' then begin - TranslateStringToTInAddr(AIP, PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); - end; - PSockAddrIn(@LAddr)^.sin_port := htons(APort); - LSize := SIZE_TSOCKADDRIN; - end; - Id_IPv6: begin - PSockAddrIn6(@LAddr)^.sin6_family := Id_PF_INET6; - if AIP <> '' then begin - TranslateStringToTInAddr(AIP, PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); - end; - PSockAddrIn6(@LAddr)^.sin6_port := htons(APort); - LSize := SIZE_TSOCKADDRIN6; - end; - else begin - LSize := 0; // avoid warning - IPVersionUnsupported; - end; - end; - CheckForSocketError(IdWinsock2.bind(ASocket, IdWinsock2.PSOCKADDR(@LAddr), LSize)); -end; - -function TIdStackWindows.WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; -begin - Result := CloseSocket(ASocket); -end; - -function TIdStackWindows.HostByAddress(const AAddress: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; -var - {$IFDEF UNICODE} - Hints: TAddrInfoW; - LAddrInfo: pAddrInfoW; - {$ELSE} - Hints: TAddrInfo; - LAddrInfo: pAddrInfo; - {$ENDIF} - RetVal: Integer; - {$IFDEF STRING_UNICODE_MISMATCH} - LTemp: TIdPlatformString; - {$ENDIF} -begin - if not (AIPVersion in [Id_IPv4, Id_IPv6]) then begin - IPVersionUnsupported; - end; - - // TODO: should this be calling getnameinfo() first and then getaddrinfo() - // to check for a malicious PTR record, like the other TIdStack classes do? - - // TODO: use TranslateStringToTInAddr() instead of getaddrinfo() to convert - // the IP address to a sockaddr struct for getnameinfo(), like other TIdStack - // classes do. - - FillChar(Hints, SizeOf(Hints), 0); - Hints.ai_family := IdIPFamily[AIPVersion]; - Hints.ai_socktype := Integer(SOCK_STREAM); - Hints.ai_flags := AI_NUMERICHOST; - LAddrInfo := nil; - - {$IFDEF STRING_UNICODE_MISMATCH} - LTemp := TIdPlatformString(AAddress); // explicit convert to Ansi/Unicode - {$ENDIF} - - RetVal := getaddrinfo( - {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(AAddress){$ENDIF}, - nil, @Hints, @LAddrInfo); - if RetVal <> 0 then begin - RaiseSocketError(gaiErrorToWsaError(RetVal)); - end; - try - SetLength( - {$IFDEF STRING_UNICODE_MISMATCH}LTemp{$ELSE}Result{$ENDIF}, - NI_MAXHOST); - RetVal := getnameinfo( - LAddrInfo.ai_addr, LAddrInfo.ai_addrlen, - {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(Result){$ENDIF}, - NI_MAXHOST, nil, 0, NI_NAMEREQD); - if RetVal <> 0 then begin - RaiseSocketError(gaiErrorToWsaError(RetVal)); - end; - Result := {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(Result){$ENDIF}; - finally - freeaddrinfo(LAddrInfo); - end; -end; - -function TIdStackWindows.ReadHostName: string; -var - // Note that there is no Unicode version of gethostname. - // Maybe use getnameinfo() instead? - LStr: array[0..SIZE_HOSTNAME] of TIdAnsiChar; - {$IFDEF USE_MARSHALLED_PTRS} - LStrPtr: TPtrWrapper; - {$ENDIF} -begin - {$IFDEF USE_MARSHALLED_PTRS} - LStrPtr := TPtrWrapper.Create(@LStr[0]); - {$ENDIF} - if gethostname( - {$IFDEF USE_MARSHALLED_PTRS} - LStrPtr.ToPointer - {$ELSE} - LStr - {$ENDIF}, SIZE_HOSTNAME) <> Id_SOCKET_ERROR then - begin - {$IFDEF USE_MARSHALLED_PTRS} - Result := TMarshal.ReadStringAsAnsiUpTo(CP_ACP, LStrPtr, SIZE_HOSTNAME); - {$ELSE} - //we have to specifically type cast a PIdAnsiChar to a string for D2009+. - //otherwise, we will get a warning about implicit typecast from AnsiString - //to string - LStr[SIZE_HOSTNAME] := TIdAnsiChar(0); - Result := String(LStr); - {$ENDIF} - end else begin - Result := ''; - end; -end; - -procedure TIdStackWindows.Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); -begin - CheckForSocketError(IdWinsock2.listen(ASocket, ABacklog)); -end; - -// RLebeau 12/16/09: MS Hotfix #971383 supposedly fixes a bug in Windows -// Server 2003 when client and server are running on the same machine. -// The bug can cause recv() to return 0 bytes prematurely even though data -// is actually pending. Uncomment the below define if you do not want to -// rely on the Hotfix always being installed. The workaround described by -// MS is to simply call recv() again to make sure data is really not pending. -// -{.$DEFINE IGNORE_KB971383_FIX} - -function TIdStackWindows.WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; - const ABufferLength, AFlags: Integer) : Integer; -begin - Result := recv(ASocket, ABuffer, ABufferLength, AFlags); - {$IFDEF IGNORE_KB971383_FIX} - if Result = 0 then begin - Result := recv(ASocket, ABuffer, ABufferLength, AFlags); - end; - {$ENDIF} -end; - -function TIdStackWindows.RecvFrom(const ASocket: TIdStackSocketHandle; - var VBuffer; const ALength, AFlags: Integer; var VIP: string; - var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; -var - LSize: Integer; - LAddr: SOCKADDR_STORAGE; -begin - LSize := SizeOf(LAddr); - Result := IdWinsock2.recvfrom(ASocket, VBuffer, ALength, AFlags, IdWinsock2.PSOCKADDR(@LAddr), @LSize); - if Result >= 0 then - begin - case LAddr.ss_family of - Id_PF_INET4: begin - VIP := TranslateTInAddrToString(PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); - VPort := ntohs(PSockAddrIn(@LAddr)^.sin_port); - VIPVersion := Id_IPv4; - end; - Id_PF_INET6: begin - VIP := TranslateTInAddrToString(PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); - VPort := ntohs(PSockAddrIn6(@LAddr)^.sin6_port); - VIPVersion := Id_IPv6; - end; - else begin - IPVersionUnsupported; - end; - end; - end; -end; - -function TIdStackWindows.WSSend(ASocket: TIdStackSocketHandle; - const ABuffer; const ABufferLength, AFlags: Integer): Integer; -begin - Result := CheckForSocketError(IdWinsock2.send(ASocket, ABuffer, ABufferLength, AFlags)); -end; - -procedure TIdStackWindows.WSSendTo(ASocket: TIdStackSocketHandle; - const ABuffer; const ABufferLength, AFlags: Integer; const AIP: string; - const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LAddr: SOCKADDR_STORAGE; - LSize: Integer; -begin - FillChar(LAddr, SizeOf(LAddr), 0); - case AIPVersion of - Id_IPv4: begin - PSockAddrIn(@LAddr)^.sin_family := Id_PF_INET4; - TranslateStringToTInAddr(AIP, PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); - PSockAddrIn(@LAddr)^.sin_port := htons(APort); - LSize := SIZE_TSOCKADDRIN; - end; - Id_IPv6: begin - PSockAddrIn6(@LAddr)^.sin6_family := Id_PF_INET6; - TranslateStringToTInAddr(AIP, PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); - PSockAddrIn6(@LAddr)^.sin6_port := htons(APort); - LSize := SIZE_TSOCKADDRIN6; - end; - else begin - LSize := 0; // avoid warning - IPVersionUnsupported; - end; - end; - LSize := IdWinsock2.sendto(ASocket, ABuffer, ABufferLength, AFlags, IdWinsock2.PSOCKADDR(@LAddr), LSize); - // TODO: call CheckForSocketError() here - if LSize = Id_SOCKET_ERROR then begin - // TODO: move this into RaiseLastSocketError() directly - if WSGetLastError() = Id_WSAEMSGSIZE then begin - raise EIdPackageSizeTooBig.Create(RSPackageSizeTooBig); - end else begin - RaiseLastSocketError; - end; - end - else if LSize <> ABufferLength then begin - raise EIdNotAllBytesSent.Create(RSNotAllBytesSent); - end; -end; - -function TIdStackWindows.WSGetLastError: Integer; -begin - Result := WSAGetLastError; - if Result = -1073741251{STATUS_HOST_UNREACHABLE} then begin - Result := WSAEHOSTUNREACH; - end -end; - -procedure TIdStackWindows.WSSetLastError(const AErr : Integer); -begin - WSASetLastError(AErr); -end; - -function TIdStackWindows.WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; - const ANonBlocking: Boolean = False): TIdStackSocketHandle; -{ -var - LValue: UInt32; -} -begin - if ANonBlocking then begin - Result := WSASocket(AFamily, AStruct, AProtocol, nil, 0, WSA_FLAG_OVERLAPPED); - // TODO: do this instead? - { - Result := IdWinsock2.socket(AFamily, AStruct, AProtocol); - if Result <> INVALID_SOCKET then begin - //SetBlocking(Result, False); - LValue := 1; - ioctlsocket(Result, FIONBIO, LValue); - end; - } - end else begin - Result := IdWinsock2.socket(AFamily, AStruct, AProtocol); - end; -end; - -function TIdStackWindows.WSGetServByName(const AServiceName: string): TIdPort; -var - // Note that there is no Unicode version of getservbyname. - // Maybe use getaddrinfo() instead? - ps: PServEnt; - LPort: Integer; - {$IFDEF USE_MARSHALLED_PTRS} - M: TMarshaller; - {$ENDIF} -begin - ps := getservbyname( - {$IFDEF USE_MARSHALLED_PTRS} - M.AsAnsi(AServiceName).ToPointer - {$ELSE} - PIdAnsiChar( - {$IFDEF STRING_IS_ANSI} - AServiceName - {$ELSE} - AnsiString(AServiceName) // explicit convert to Ansi - {$ENDIF} - ) - {$ENDIF}, - nil); - if ps <> nil then begin - Result := ntohs(ps^.s_port); - end else - begin - // TODO: use TryStrToInt() instead... - try - LPort := IndyStrToInt(AServiceName); - except - on EConvertError do begin - LPort := -1; - IndyRaiseOuterException(EIdInvalidServiceName.CreateFmt(RSInvalidServiceName, [AServiceName])); - end; - end; - if (LPort < 0) or (LPort > High(TIdPort)) then begin - raise EIdInvalidServiceName.CreateFmt(RSInvalidServiceName, [AServiceName]); - end; - Result := TIdPort(LPort); - end; -end; - -procedure TIdStackWindows.AddServByPortToList(const APortNumber: TIdPort; AAddresses: TStrings); -type - // Note that there is no Unicode version of getservbyport. - PPAnsiCharArray = ^TPAnsiCharArray; - TPAnsiCharArray = packed array[0..(MaxInt div SizeOf(PIdAnsiChar))-1] of PIdAnsiChar; -var - ps: PServEnt; - i: integer; - p: PPAnsiCharArray; -begin - ps := getservbyport(htons(APortNumber), nil); - if ps = nil then begin - RaiseLastSocketError; - end; - AAddresses.BeginUpdate; - try - //we have to specifically type cast a PIdAnsiChar to a string for D2009+. - //otherwise, we will get a warning about implicit typecast from AnsiString - //to string - AAddresses.Add(String(ps^.s_name)); - i := 0; - p := Pointer(ps^.s_aliases); - while p[i] <> nil do - begin - AAddresses.Add(String(p[i])); - Inc(i); - end; - finally - AAddresses.EndUpdate; - end; -end; - -function TIdStackWindows.HostToNetwork(AValue: UInt16): UInt16; -begin - Result := htons(AValue); -end; - -function TIdStackWindows.NetworkToHost(AValue: UInt16): UInt16; -begin - Result := ntohs(AValue); -end; - -function TIdStackWindows.HostToNetwork(AValue: UInt32): UInt32; -begin - Result := htonl(AValue); -end; - -function TIdStackWindows.NetworkToHost(AValue: UInt32): UInt32; -begin - Result := ntohl(AValue); -end; - -function TIdStackWindows.HostToNetwork(AValue: TIdUInt64): TIdUInt64; -var - LParts: TIdUInt64Parts; - L: UInt32; -begin - // TODO: ARM is bi-endian, so if Windows is running on ARM instead of x86, - // can it ever be big endian? Or do ARM manufacturers put it in little endian - // for Windows installations? - - //if (htonl(1) <> 1) then begin - LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - L := htonl(LParts.HighPart); - LParts.HighPart := htonl(LParts.LowPart); - LParts.LowPart := L; - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; - //end else begin - // Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - //end; -end; - -function TIdStackWindows.NetworkToHost(AValue: TIdUInt64): TIdUInt64; -var - LParts: TIdUInt64Parts; - L: UInt32; -begin - // TODO: ARM is bi-endian, so if Windows is running on ARM instead of x86, - // can it ever be big endian? Or do ARM manufacturers put it in little endian - // for Windows installations? - - //if (ntohl(1) <> 1) then begin - LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - L := ntohl(LParts.HighPart); - LParts.HighPart := ntohl(LParts.LowPart); - LParts.LowPart := L; - Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; - //end else begin - // Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; - //end; -end; - -type - TIdStackLocalAddressAccess = class(TIdStackLocalAddress) - end; - -procedure TIdStackWindows.GetLocalAddressList(AAddresses: TIdStackLocalAddressList); - - {$IFDEF USE_IPHLPAPI} - - function IPv4MaskLengthToString(MaskLength: ULONG): String; - var - Mask: ULONG; - begin - if ConvertLengthToIpv4Mask(MaskLength, Mask) = ERROR_SUCCESS then begin - Result := TranslateTInAddrToString(Mask, Id_IPv4); - end else begin - Result := ''; - end; - end; - - procedure GetIPv4SubNetMasks(ASubNetMasks: TStrings); - var - Ret: DWORD; - BufLen: ULONG; - Table: PMIB_IPADDRTABLE; - pRow: PMIB_IPADDRROW; - I: ULONG; - begin - BufLen := 0; - Table := nil; - try - repeat - // Alternatively, use WSAIoctl(SIO_GET_INTERFACE_LIST), but - // I have noticed it does not always return IPv4 subnets! - Ret := GetIpAddrTable(Table, BufLen, FALSE); - case Ret of - ERROR_SUCCESS: - begin - if BufLen = 0 then begin - Exit; - end; - Break; - end; - ERROR_NOT_SUPPORTED: - Exit; - ERROR_INSUFFICIENT_BUFFER: - ReallocMem(Table, BufLen); - else - SetLastError(Ret); - IndyRaiseLastError; - end; - until False; - - if Ret = ERROR_SUCCESS then - begin - if Table^.dwNumEntries > 0 then - begin - pRow := @(Table^.table[0]); - for I := 0 to Table^.dwNumEntries-1 do begin - IndyAddPair(ASubNetMasks, - TranslateTInAddrToString(pRow^.dwAddr, Id_IPv4), - TranslateTInAddrToString(pRow^.dwMask, Id_IPv4)); - Inc(pRow); - end; - end; - end; - finally - FreeMem(Table); - end; - end; - - function GetLocalAddressesByAdaptersAddresses: Boolean; - var - Ret: DWORD; - BufLen: ULONG; - Adapter, Adapters: PIP_ADAPTER_ADDRESSES; - UnicastAddr: PIP_ADAPTER_UNICAST_ADDRESS; - IPAddr: string; - SubNetStr: String; - SubNetMasks: TStringList; - LAddress: TIdStackLocalAddress; - begin - // assume True unless ERROR_NOT_SUPPORTED is reported... - Result := True; - - // MSDN says: - // The recommended method of calling the GetAdaptersAddresses function is - // to pre-allocate a 15KB working buffer pointed to by the AdapterAddresses - // parameter. On typical computers, this dramatically reduces the chances - // that the GetAdaptersAddresses function returns ERROR_BUFFER_OVERFLOW, - // which would require calling GetAdaptersAddresses function multiple times. - - BufLen := 1024*15; - GetMem(Adapters, BufLen); - try - repeat - // TODO: include GAA_FLAG_INCLUDE_PREFIX on XPSP1+? - // TODO: include GAA_FLAG_INCLUDE_ALL_INTERFACES on Vista+? - Ret := GetAdaptersAddresses(PF_UNSPEC, GAA_FLAG_SKIP_ANYCAST or GAA_FLAG_SKIP_MULTICAST or GAA_FLAG_SKIP_DNS_SERVER, nil, Adapters, BufLen); - case Ret of - ERROR_SUCCESS: - begin - // Windows CE versions earlier than 4.1 may return ERROR_SUCCESS and - // BufLen=0 if no adapter info is available, instead of returning - // ERROR_NO_DATA as documented... - if BufLen = 0 then begin - Exit; - end; - Break; - end; - ERROR_NOT_SUPPORTED: - begin - Result := False; - Exit; - end; - ERROR_NO_DATA, - ERROR_ADDRESS_NOT_ASSOCIATED: - Exit; - ERROR_BUFFER_OVERFLOW: - ReallocMem(Adapters, BufLen); - else - SetLastError(Ret); - IndyRaiseLastError; - end; - until False; - - if Ret = ERROR_SUCCESS then - begin - SubNetMasks := nil; - try - AAddresses.BeginUpdate; - try - Adapter := Adapters; - repeat - if (Adapter.IfType <> IF_TYPE_SOFTWARE_LOOPBACK) and - ((Adapter.Flags and IP_ADAPTER_RECEIVE_ONLY) = 0) then - begin - UnicastAddr := Adapter^.FirstUnicastAddress; - while UnicastAddr <> nil do - begin - if UnicastAddr^.DadState = IpDadStatePreferred then - begin - LAddress := nil; - case UnicastAddr^.Address.lpSockaddr.sin_family of - AF_INET: begin - IPAddr := TranslateTInAddrToString(PSockAddrIn(UnicastAddr^.Address.lpSockaddr)^.sin_addr, Id_IPv4); - // TODO: use the UnicastAddr^.Length field to determine which version of - // IP_ADAPTER_UNICAST_ADDRESS is being provided, rather than checking the - // OS version number... - if IndyCheckWindowsVersion(6) then begin - // The OnLinkPrefixLength member is only available on Windows Vista and later - SubNetStr := IPv4MaskLengthToString(UnicastAddr^.OnLinkPrefixLength); - end else - begin - // TODO: on XP SP1+, can the subnet mask be determined - // by analyzing the Adapter's Prefix list without resorting - // to reading the Registry? - if SubNetMasks = nil then - begin - SubNetMasks := TStringList.Create; - GetIPv4SubNetMasks(SubNetMasks); - end; - SubNetStr := SubNetMasks.Values[IPAddr]; - end; - LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, IPAddr, SubNetStr); - {$I IdObjectChecksOff.inc} - TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := Adapter^.Union.IfIndex; - {$I IdObjectChecksOn.inc} - end; - AF_INET6: begin - LAddress := TIdStackLocalAddressIPv6.Create(AAddresses, - TranslateTInAddrToString(PSockAddrIn6(UnicastAddr^.Address.lpSockaddr)^.sin6_addr, Id_IPv6)); - // The Ipv6IfIndex member is only available on Windows XP SP1 and later - if IndyCheckWindowsVersion(5, 2) or (IndyCheckWindowsVersion(5, 1) {TODO: and SP1+}) then begin - {$I IdObjectChecksOff.inc} - TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := Adapter^.Ipv6IfIndex; - {$I IdObjectChecksOn.inc} - end; - end; - end; - if LAddress <> nil then begin - {$I IdObjectChecksOff.inc} - TIdStackLocalAddressAccess(LAddress).FDescription := String(Adapter^.Description); - TIdStackLocalAddressAccess(LAddress).FFriendlyName := String(Adapter^.FriendlyName); - TIdStackLocalAddressAccess(LAddress).FInterfaceName := String(Adapter^.AdapterName); - {$I IdObjectChecksOn.inc} - end; - end; - UnicastAddr := UnicastAddr^.Next; - end; - end; - Adapter := Adapter^.Next; - until Adapter = nil; - finally - AAddresses.EndUpdate; - end; - finally - SubNetMasks.Free; - end; - end; - finally - FreeMem(Adapters); - end; - end; - - procedure GetUniDirAddresseses(AUniDirAddresses: TStrings); - var - Ret: DWORD; - BufLen: ULONG; - Adapters: PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS; - pUniDirAddr: PInAddr; - I: ULONG; - begin - BufLen := 1024*15; - GetMem(Adapters, BufLen); - try - repeat - Ret := GetUniDirectionalAdapterInfo(Adapters, BufLen); - case Ret of - ERROR_SUCCESS: - begin - if BufLen = 0 then begin - Exit; - end; - Break; - end; - ERROR_NOT_SUPPORTED, - ERROR_NO_DATA: - Exit; - ERROR_MORE_DATA: - ReallocMem(Adapters, BufLen); - else - SetLastError(Ret); - IndyRaiseLastError; - end; - until False; - - if Ret = ERROR_SUCCESS then - begin - if Adapters^.NumAdapters > 0 then - begin - pUniDirAddr := @(Adapters^.Address[0]); - for I := 0 to Adapters^.NumAdapters-1 do begin - AUniDirAddresses.Add(TranslateTInAddrToString(pUniDirAddr^, Id_IPv4)); - Inc(pUniDirAddr); - end; - end; - end; - finally - FreeMem(Adapters); - end; - end; - - procedure GetLocalAddressesByAdaptersInfo; - var - Ret: DWORD; - BufLen: ULONG; - UniDirAddresses: TStringList; - Adapter, Adapters: PIP_ADAPTER_INFO; - IPAddr: PIP_ADDR_STRING; - IPStr, MaskStr: String; - LAddress: TIdStackLocalAddress; - begin - BufLen := 1024*15; - GetMem(Adapters, BufLen); - try - repeat - Ret := GetAdaptersInfo(Adapters, BufLen); - case Ret of - ERROR_SUCCESS: - begin - // Windows CE versions earlier than 4.1 may return ERROR_SUCCESS and - // BufLen=0 if no adapter info is available, instead of returning - // ERROR_NO_DATA as documented... - if BufLen = 0 then begin - Exit; - end; - Break; - end; - ERROR_NOT_SUPPORTED, - ERROR_NO_DATA: - Exit; - ERROR_BUFFER_OVERFLOW: - ReallocMem(Adapters, BufLen); - else - SetLastError(Ret); - IndyRaiseLastError; - end; - until False; - - if Ret = ERROR_SUCCESS then - begin - // on XP and later, GetAdaptersInfo() includes uni-directional adapters. - // Need to use GetUniDirectionalAdapterInfo() to filter them out of the - // list ... - - if IndyCheckWindowsVersion(5, 1) then begin - UniDirAddresses := TStringList.Create; - end else begin - UniDirAddresses := nil; - end; - try - if UniDirAddresses <> nil then begin - GetUniDirAddresseses(UniDirAddresses); - end; - AAddresses.BeginUpdate; - try - Adapter := Adapters; - repeat - IPAddr := @(Adapter^.IpAddressList); - repeat - {$IFDEF USE_MARSHALLED_PTRS} - IPStr := TMarshal.ReadStringAsAnsiUpTo(CP_ACP, TPtrWrapper.Create(@(IPAddr^.IpAddress.S[0]), 15); - {$ELSE} - IPStr := String(IPAddr^.IpAddress.S); - {$ENDIF} - if (IPStr <> '') and (IPStr <> '0.0.0.0') then - begin - if UniDirAddresses <> nil then begin - if UniDirAddresses.IndexOf(IPStr) <> -1 then begin - IPAddr := IPAddr^.Next; - Continue; - end; - end; - {$IFDEF USE_MARSHALLED_PTRS} - MaskStr := TMarshal.ReadStringAsAnsiUpTo(CP_ACP, TPtrWrapper.Create(@(IPAddr^.IpMask.S[0]), 15); - {$ELSE} - MaskStr := String(IPAddr^.IpMask.S); - {$ENDIF} - LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, IPStr, MaskStr); - {$I IdObjectChecksOff.inc} - TIdStackLocalAddressAccess(LAddress).FDescription := String(Adapter^.Description); - TIdStackLocalAddressAccess(LAddress).FFriendlyName := String(Adapter^.AdapterName); - TIdStackLocalAddressAccess(LAddress).FInterfaceName := String(Adapter^.AdapterName); - TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := Adapter^.Index; - {$I IdObjectChecksOn.inc} - end; - IPAddr := IPAddr^.Next; - until IPAddr = nil; - Adapter := Adapter^.Next; - until Adapter = nil; - finally - AAddresses.EndUpdate; - end; - finally - UniDirAddresses.Free; - end; - end; - finally - FreeMem(Adapters); - end; - end; - - {$ELSE} - - procedure GetLocalAddressesByHostName; - var - {$IFDEF UNICODE} - Hints: TAddrInfoW; - LAddrList, LAddrInfo: pAddrInfoW; - {$ELSE} - Hints: TAddrInfo; - LAddrList, LAddrInfo: pAddrInfo; - {$ENDIF} - RetVal: Integer; - LHostName: String; - {$IFDEF STRING_UNICODE_MISMATCH} - LTemp: TIdPlatformString; - {$ENDIF} - //LAddress: TIdStackLocalAddress; - begin - LHostName := HostName; - - ZeroMemory(@Hints, SIZE_TADDRINFO); - Hints.ai_family := PF_UNSPEC; // returns both IPv4 and IPv6 addresses - Hints.ai_socktype := SOCK_STREAM; - LAddrList := nil; - - {$IFDEF STRING_UNICODE_MISMATCH} - LTemp := TIdPlatformString(LHostName); // explicit convert to Ansi/Unicode - {$ENDIF} - - RetVal := getaddrinfo( - {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(LHostName){$ENDIF}, - nil, @Hints, @LAddrList); - if RetVal <> 0 then begin - RaiseSocketError(gaiErrorToWsaError(RetVal)); - end; - try - AAddresses.BeginUpdate; - try - LAddrInfo := LAddrList; - repeat - //LAddress := nil; - case LAddrInfo^.ai_addr^.sa_family of - AF_INET: begin - {LAddress :=} TIdStackLocalAddressIPv4.Create(AAddresses, - TranslateTInAddrToString(PSockAddrIn(LAddrInfo^.ai_addr)^.sin_addr, Id_IPv4), - ''); // TODO: SubNet - end; - AF_INET6: begin - {LAddress :=} TIdStackLocalAddressIPv6.Create(AAddresses, - TranslateTInAddrToString(PSockAddrIn6(LAddrInfo^.ai_addr)^.sin6_addr, Id_IPv6)); - end; - end; - // TODO: implement this... - { - if LAddress <> nil then begin - ($I IdObjectChecksOff.inc) - TIdStackLocalAddressAccess(LAddress).FDescription := ?; - TIdStackLocalAddressAccess(LAddress).FFriendlyName := ?; - TIdStackLocalAddressAccess(LAddress).FInterfaceName := ?; - TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := ?; - ($I IdObjectChecksOn.inc) - end; - } - LAddrInfo := LAddrInfo^.ai_next; - until LAddrInfo = nil; - finally - AAddresses.EndUpdate; - end; - finally - freeaddrinfo(LAddrList); - end; - end; - - {$ENDIF} -begin - // Using gethostname() and (gethostbyname|getaddrinfo)() may not always return - // just the machine's IP addresses. Technically speaking, they will return - // the local hostname, and then return the address(es) to which that hostname - // resolves. It is possible for a machine to (a) be configured such that its - // name does not resolve to an IP, or (b) be configured such that its name - // resolves to multiple IPs, only one of which belongs to the local machine. - // For better results, we should use the Win32 API GetAdaptersInfo() and/or - // GetAdaptersAddresses() functions instead. GetAdaptersInfo() only supports - // IPv4, but GetAdaptersAddresses() supports both IPv4 and IPv6... - - {$IFDEF USE_IPHLPAPI} - // try GetAdaptersAddresses() first, then fall back to GetAdaptersInfo()... - if not GetLocalAddressesByAdaptersAddresses then begin - GetLocalAddressesByAdaptersInfo; - end; - {$ELSE} - GetLocalAddressesByHostName; - {$ENDIF} -end; - -{ TIdStackVersionWinsock } - -function TIdStackWindows.WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; -begin - Result := Shutdown(ASocket, AHow); -end; - -procedure TIdStackWindows.GetSocketName(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); -var - LSize: Integer; - LAddr: SOCKADDR_STORAGE; -begin - LSize := SizeOf(LAddr); - CheckForSocketError(getsockname(ASocket, IdWinsock2.PSOCKADDR(@LAddr), LSize)); - case LAddr.ss_family of - Id_PF_INET4: begin - VIP := TranslateTInAddrToString(PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); - VPort := ntohs(PSockAddrIn(@LAddr)^.sin_port); - VIPVersion := Id_IPv4; - end; - Id_PF_INET6: begin - VIP := TranslateTInAddrToString(PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); - VPort := Ntohs(PSockAddrIn6(@LAddr)^.sin6_port); - VIPVersion := Id_IPv6; - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -{ TIdSocketListWindows } - -type - // WARNING: If you are thinking of rewriting this to use WSAPoll() instead of select(), - // similar to TIdSocketListVCLPosix, then note that WSAPoll() is broken prior to - // Windows 10 version 2004! See: - // - // https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/ - // https://stackoverflow.com/questions/21653003/is-this-wsapoll-bug-for-non-blocking-sockets-fixed - // - TIdSocketListWindows = class(TIdSocketList) - protected - FFDSet: TFDSet; - // - class function FDSelect(AReadSet: PFDSet; AWriteSet: PFDSet; AExceptSet: PFDSet; - const ATimeout: Integer = IdTimeoutInfinite): Boolean; - function GetItem(AIndex: Integer): TIdStackSocketHandle; override; - public - procedure Add(AHandle: TIdStackSocketHandle); override; - procedure Remove(AHandle: TIdStackSocketHandle); override; - function Count: Integer; override; - procedure Clear; override; - function Clone: TIdSocketList; override; - function ContainsSocket(AHandle: TIdStackSocketHandle): boolean; override; - procedure GetFDSet(var VSet: TFDSet); - procedure SetFDSet(var VSet: TFDSet); - class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; - AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - function SelectReadList(var VSocketList: TIdSocketList; - const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; - end; - -procedure TIdSocketListWindows.Add(AHandle: TIdStackSocketHandle); -begin - Lock; - try - // TODO: on Windows, the number of sockets that select() can query is limited only - // by available memory, unlike other platforms which are limited to querying sockets - // whose descriptors are less than FD_SETSIZE (1024). However, the Winsock SDK does - // define FD_SETSIZE for compatibilty with other platforms, but it is a meesely 64 - // by default, and the IdWinSock2 unit does use FD_SETSIZE in its definition of - // TFDSet. C/C++ programs can freely override the value of FD_SETSIZE at compile-time, - // but that is not an option for Pascal programs. So, we need to find a way to make - // this more dynamic/configurable. For instance, by having this class hold a dynamic - // byte array that is casted to PFDSet when needed... - if not fd_isset(AHandle, FFDSet) then begin - if FFDSet.fd_count >= u_int(Length(FFDSet.fd_array)){FD_SETSIZE} then begin - raise EIdStackSetSizeExceeded.Create(RSSetSizeExceeded); - end; - FFDSet.fd_array[FFDSet.fd_count] := AHandle; - Inc(FFDSet.fd_count); - end; - finally - Unlock; - end; -end; - -procedure TIdSocketListWindows.Clear; -begin - Lock; - try - fd_zero(FFDSet); - finally - Unlock; - end; -end; - -function TIdSocketListWindows.ContainsSocket(AHandle: TIdStackSocketHandle): Boolean; -begin - Lock; - try - Result := fd_isset(AHandle, FFDSet); - finally - Unlock; - end; -end; - -function TIdSocketListWindows.Count: Integer; -begin - Lock; - try - Result := FFDSet.fd_count; - finally - Unlock; - end; -end; - -function TIdSocketListWindows.GetItem(AIndex: Integer): TIdStackSocketHandle; -begin - // keep the compiler happy (when was this fixed exactly?) - {$IFDEF DCC}{$IFNDEF VCL_8_OR_ABOVE} - Result := INVALID_SOCKET; - {$ENDIF}{$ENDIF} - - Lock; - try - //We can't redefine AIndex to be a UInt32 because the libc Interface - //and DotNET define it as a LongInt. OS/2 defines it as a UInt16. - if (AIndex < 0) or (u_int(AIndex) >= FFDSet.fd_count) then begin - // TODO: just return 0/invalid, like most of the other Stack classes do? - raise EIdStackSetSizeExceeded.Create(RSSetSizeExceeded); - end; - Result := FFDSet.fd_array[AIndex]; - finally - Unlock; - end; -end; - -procedure TIdSocketListWindows.Remove(AHandle: TIdStackSocketHandle); -var - i: Integer; -begin - Lock; - try - { - IMPORTANT!!! - - Sometimes, there may not be a member of the FDSET. If you attempt to "remove" - an item, the loop would execute once. - } - if FFDSet.fd_count > 0 then - begin - for i:= 0 to FFDSet.fd_count - 1 do - begin - if FFDSet.fd_array[i] = AHandle then - begin - Dec(FFDSet.fd_count); - FFDSet.fd_array[i] := FFDSet.fd_array[FFDSet.fd_count]; - FFDSet.fd_array[FFDSet.fd_count] := 0; //extra purity - Break; - end;//if found - end; - end; - finally - Unlock; - end; -end; - -function TIdStackWindows.WSTranslateSocketErrorMsg(const AErr: Integer): string; -begin - if AErr = WSAHOST_NOT_FOUND then begin - Result := IndyFormat(RSStackError, [AErr, RSStackHOST_NOT_FOUND]); - end else begin - Result := inherited WSTranslateSocketErrorMsg(AErr); - end; -end; - -function TIdSocketListWindows.SelectRead(const ATimeout: Integer): Boolean; -var - LSet: TFDSet; -begin - // Windows updates this structure on return, so we need to copy it each time we need it - GetFDSet(LSet); - Result := FDSelect(@LSet, nil, nil, ATimeout); -end; - -class function TIdSocketListWindows.FDSelect(AReadSet, AWriteSet, - AExceptSet: PFDSet; const ATimeout: Integer): Boolean; -var - LResult: Integer; - LTime: TTimeVal; - LTimePtr: PTimeVal; -begin - if ATimeout = IdTimeoutInfinite then begin - LTimePtr := nil; - end else begin - LTime.tv_sec := ATimeout div 1000; - LTime.tv_usec := (ATimeout mod 1000) * 1000; - LTimePtr := @LTime; - end; - LResult := IdWinsock2.select(0, AReadSet, AWriteSet, AExceptSet, LTimePtr); - //TODO: Remove this cast - Result := GStack.CheckForSocketError(LResult) > 0; -end; - -function TIdSocketListWindows.SelectReadList(var VSocketList: TIdSocketList; - const ATimeout: Integer): Boolean; -var - LSet: TFDSet; -begin - // Windows updates this structure on return, so we need to copy it each time we need it - GetFDSet(LSet); - Result := FDSelect(@LSet, nil, nil, ATimeout); - if Result then - begin - if VSocketList = nil then begin - VSocketList := TIdSocketList.CreateSocketList; - end; - TIdSocketListWindows(VSocketList).SetFDSet(LSet); - end; -end; - -class function TIdSocketListWindows.Select(AReadList, AWriteList, - AExceptList: TIdSocketList; const ATimeout: Integer): Boolean; -var - LReadSet: TFDSet; - LWriteSet: TFDSet; - LExceptSet: TFDSet; - LPReadSet: PFDSet; - LPWriteSet: PFDSet; - LPExceptSet: PFDSet; - - procedure ReadSet(AList: TIdSocketList; var ASet: TFDSet; var APSet: PFDSet); - begin - if AList <> nil then begin - TIdSocketListWindows(AList).GetFDSet(ASet); - APSet := @ASet; - end else begin - APSet := nil; - end; - end; - -begin - ReadSet(AReadList, LReadSet, LPReadSet); - ReadSet(AWriteList, LWriteSet, LPWriteSet); - ReadSet(AExceptList, LExceptSet, LPExceptSet); - - Result := FDSelect(LPReadSet, LPWriteSet, LPExceptSet, ATimeout); - - if AReadList <> nil then begin - TIdSocketListWindows(AReadList).SetFDSet(LReadSet); - end; - if AWriteList <> nil then begin - TIdSocketListWindows(AWriteList).SetFDSet(LWriteSet); - end; - if AExceptList <> nil then begin - TIdSocketListWindows(AExceptList).SetFDSet(LExceptSet); - end; -end; - -procedure TIdSocketListWindows.SetFDSet(var VSet: TFDSet); -begin - Lock; - try - FFDSet := VSet; - finally - Unlock; - end; -end; - -procedure TIdSocketListWindows.GetFDSet(var VSet: TFDSet); -begin - Lock; - try - VSet := FFDSet; - finally - Unlock; - end; -end; - -procedure TIdStackWindows.SetBlocking(ASocket: TIdStackSocketHandle; - const ABlocking: Boolean); -var - LValue: UInt32; -begin - LValue := UInt32(not ABlocking); - CheckForSocketError(ioctlsocket(ASocket, FIONBIO, LValue)); -end; - -function TIdSocketListWindows.Clone: TIdSocketList; -begin - Result := TIdSocketListWindows.Create; - try - Lock; - try - TIdSocketListWindows(Result).SetFDSet(FFDSet); - finally - Unlock; - end; - except - FreeAndNil(Result); - raise; - end; -end; - -function TIdStackWindows.WouldBlock(const AResult: Integer): Boolean; -begin - Result := (AResult = WSAEWOULDBLOCK); -end; - -function TIdStackWindows.HostByName(const AHostName: string; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; -var - {$IFDEF UNICODE} - LAddrInfo: pAddrInfoW; - Hints: TAddrInfoW; - {$ELSE} - LAddrInfo: pAddrInfo; - Hints: TAddrInfo; - {$ENDIF} - RetVal: Integer; - LHostName: String; - {$IFDEF STRING_UNICODE_MISMATCH} - LTemp: TIdPlatformString; - {$ENDIF} -begin - if not (AIPVersion in [Id_IPv4, Id_IPv6]) then begin - IPVersionUnsupported; - end; - - ZeroMemory(@Hints, SIZE_TADDRINFO); - Hints.ai_family := IdIPFamily[AIPVersion]; - Hints.ai_socktype := SOCK_STREAM; - LAddrInfo := nil; - - if UseIDNAPI then begin - LHostName := IDNToPunnyCode( - {$IFDEF STRING_IS_UNICODE} - AHostName - {$ELSE} - TIdUnicodeString(AHostName) // explicit convert to Unicode - {$ENDIF} - ); - end else begin - LHostName := AHostName; - end; - - {$IFDEF STRING_UNICODE_MISMATCH} - LTemp := TIdPlatformString(LHostName); // explicit convert to Ansi/Unicode - {$ENDIF} - - RetVal := getaddrinfo( - {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(LHostName){$ENDIF}, - nil, @Hints, @LAddrInfo); - if RetVal <> 0 then begin - RaiseSocketError(gaiErrorToWsaError(RetVal)); - end; - try - if AIPVersion = Id_IPv4 then begin - Result := TranslateTInAddrToString(PSockAddrIn(LAddrInfo^.ai_addr)^.sin_addr, Id_IPv4) - end else begin - Result := TranslateTInAddrToString(PSockAddrIn6(LAddrInfo^.ai_addr)^.sin6_addr, Id_IPv6); - end; - finally - freeaddrinfo(LAddrInfo); - end; -end; - -procedure TIdStackWindows.Connect(const ASocket: TIdStackSocketHandle; - const AIP: string; const APort: TIdPort; - const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); -var - LAddr: SOCKADDR_STORAGE; - LSize: Integer; -begin - FillChar(LAddr, SizeOf(LAddr), 0); - case AIPVersion of - Id_IPv4: begin - PSockAddrIn(@LAddr)^.sin_family := Id_PF_INET4; - TranslateStringToTInAddr(AIP, PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); - PSockAddrIn(@LAddr)^.sin_port := htons(APort); - LSize := SIZE_TSOCKADDRIN; - end; - Id_IPv6: begin - PSockAddrIn6(@LAddr)^.sin6_family := Id_PF_INET6; - TranslateStringToTInAddr(AIP, PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); - PSockAddrIn6(@LAddr)^.sin6_port := htons(APort); - LSize := SIZE_TSOCKADDRIN6; - end; - else begin - LSize := 0; // avoid warning - IPVersionUnsupported; - end; - end; - CheckForSocketError(IdWinsock2.connect(ASocket, IdWinsock2.PSOCKADDR(@LAddr), LSize)); -end; - -procedure TIdStackWindows.GetPeerName(ASocket: TIdStackSocketHandle; - var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); -var - LSize: Integer; - LAddr: SOCKADDR_STORAGE; -begin - LSize := SizeOf(LAddr); - CheckForSocketError(IdWinsock2.getpeername(ASocket, IdWinsock2.PSOCKADDR(@LAddr), LSize)); - case LAddr.ss_family of - Id_PF_INET4: begin - VIP := TranslateTInAddrToString(PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); - VPort := ntohs(PSockAddrIn(@LAddr)^.sin_port); - VIPVersion := Id_IPv4; - end; - Id_PF_INET6: begin - VIP := TranslateTInAddrToString(PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); - VPort := ntohs(PSockAddrIn6(@LAddr)^.sin6_port); - VIPVersion := Id_IPv6; - end; - else begin - IPVersionUnsupported; - end; - end; -end; - -procedure TIdStackWindows.Disconnect(ASocket: TIdStackSocketHandle); -begin - // Windows uses Id_SD_Send, Linux should use Id_SD_Both - // RLebeau: why Id_SD_Send and not Id_SD_Both on Windows? What if a blocking read is in progress? - WSShutdown(ASocket, Id_SD_Send); - // SO_LINGER is false - socket may take a little while to actually close after this - WSCloseSocket(ASocket); -end; - -procedure TIdStackWindows.{$IFDEF VCL_XE3_OR_ABOVE}GetSocketOption{$ELSE}WSGetSocketOption{$ENDIF} - (ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; - var AOptVal; var AOptLen: Integer); -begin - CheckForSocketError( - getsockopt(ASocket, ALevel, AOptName, - {$IFNDEF HAS_PAnsiChar} - // TODO: use TPtrWrapper here? - {PIdAnsiChar}@AOptVal - {$ELSE} - PIdAnsiChar(@AOptVal) - {$ENDIF}, - AOptLen - ) - ); -end; - -procedure TIdStackWindows.{$IFDEF VCL_XE3_OR_ABOVE}SetSocketOption{$ELSE}WSSetSocketOption{$ENDIF} - (ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; - const AOptVal; const AOptLen: Integer); -begin - CheckForSocketError( - setsockopt(ASocket, ALevel, Aoptname, - {$IFNDEF HAS_PAnsiChar} - // TODO: use TPtrWrapper here? - {PIdAnsiChar}@AOptVal - {$ELSE} - PIdAnsiChar(@AOptVal) - {$ENDIF}, - AOptLen - ) - ); -end; - -function TIdStackWindows.SupportsIPv4: Boolean; -var - LLen : DWORD; - LPInfo, LPCurPtr: LPWSAPROTOCOL_INFO; - LCount : Integer; - i : Integer; -begin - // TODO: move this logic into CheckIPVersionSupport() instead... - // Result := CheckIPVersionSupport(Id_IPv4); - - Result := False; - LPInfo := nil; - try - LLen := 0; - // Note: WSAEnumProtocols returns -1 when it is just called to get the needed Buffer Size! - repeat - LCount := IdWinsock2.WSAEnumProtocols(nil, LPInfo, LLen); - if LCount = SOCKET_ERROR then - begin - if WSAGetLastError() <> WSAENOBUFS then begin - Exit; - end; - ReallocMem(LPInfo, LLen); - end else begin - Break; - end; - until False; - - if LCount > 0 then - begin - LPCurPtr := LPInfo; - for i := 0 to LCount-1 do - begin - if LPCurPtr^.iAddressFamily = AF_INET then - begin - Result := True; - Exit; - end; - Inc(LPCurPtr); - end; - end; - finally - FreeMem(LPInfo); - end; -end; - -{ -based on -http://groups.google.com/groups?q=Winsock2+Delphi+protocol&hl=en&lr=&ie=UTF-8&oe=utf-8&selm=3cebe697_2%40dnews&rnum=9 -} -function TIdStackWindows.SupportsIPv6: Boolean; -var - LLen : DWORD; - LPInfo, LPCurPtr: LPWSAPROTOCOL_INFO; - LCount : Integer; - i : Integer; -begin - // TODO: move this logic into CheckIPVersionSupport() instead... - // Result := CheckIPVersionSupport(Id_IPv6); - - Result := False; - LPInfo := nil; - try - LLen := 0; - // Note: WSAEnumProtocols returns -1 when it is just called to get the needed Buffer Size! - repeat - LCount := IdWinsock2.WSAEnumProtocols(nil, LPInfo, LLen); - if LCount = SOCKET_ERROR then - begin - if WSAGetLastError() <> WSAENOBUFS then begin - Exit; - end; - ReallocMem(LPInfo, LLen); - end else begin - Break; - end; - until False; - - if LCount > 0 then - begin - LPCurPtr := LPInfo; - for i := 0 to LCount-1 do - begin - if LPCurPtr^.iAddressFamily = AF_INET6 then - begin - Result := True; - Exit; - end; - Inc(LPCurPtr); - end; - end; - finally - FreeMem(LPInfo); - end; -end; - -function TIdStackWindows.IOControl(const s: TIdStackSocketHandle; - const cmd: UInt32; var arg: UInt32): Integer; -begin - Result := IdWinsock2.ioctlsocket(s, cmd, arg); -end; - -procedure TIdStackWindows.WSQuerryIPv6Route(ASocket: TIdStackSocketHandle; - const AIP: String; const APort: TIdPort; var VSource; var VDest); -var - Llocalif : TSockAddrIn6; - LAddr : TSockAddrIn6; - Bytes : DWORD; -begin - //make our LAddrInfo structure - FillChar(LAddr, SizeOf(LAddr), 0); - LAddr.sin6_family := AF_INET6; - TranslateStringToTInAddr(AIP, LAddr.sin6_addr, Id_IPv6); - Move(LAddr.sin6_addr, VDest, SizeOf(in6_addr)); - LAddr.sin6_port := htons(APort); - // Find out which local interface for the destination - // RLebeau: in XE4+, PDWORD is NOT defined as ^DWORD, so we have to use a type-cast! - CheckForSocketError(WSAIoctl(ASocket, SIO_ROUTING_INTERFACE_QUERY, - @LAddr, SizeOf(LAddr), @Llocalif, SizeOf(Llocalif), PDWORD(@Bytes), nil, nil)); - Move(Llocalif.sin6_addr, VSource, SizeOf(in6_addr)); -end; - -procedure TIdStackWindows.WriteChecksum(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort; const AIPVersion: TIdIPVersion); -begin - case AIPVersion of - Id_IPv4 : CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(VBuffer)), VBuffer, AOffset); - Id_IPv6 : WriteChecksumIPv6(s, VBuffer, AOffset, AIP, APort); - else - IPVersionUnsupported; - end; -end; - -procedure TIdStackWindows.WriteChecksumIPv6(s: TIdStackSocketHandle; - var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; - const APort: TIdPort); -var - LSource : TIdIn6Addr; - LDest : TIdIn6Addr; - LTmp : TIdBytes; - LIdx : Integer; - LC : UInt32; -{ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - + + - | | - + Source Address + - | | - + + - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - + + - | | - + Destination Address + - | | - + + - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Upper-Layer Packet Length | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | zero | Next Header | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -} -begin - WSQuerryIPv6Route(s, AIP, APort, LSource, LDest); - SetLength(LTmp, 40+Length(VBuffer)); - - //16 - Move(LSource, LTmp[0], SIZE_TIN6ADDR); - LIdx := SIZE_TIN6ADDR; - //32 - Move(LDest, LTmp[LIdx], SIZE_TIN6ADDR); - Inc(LIdx, SIZE_TIN6ADDR); - //use a word so you don't wind up using the wrong network byte order function - LC := UInt32(Length(VBuffer)); - CopyTIdUInt32(HostToNetwork(LC), LTmp, LIdx); - Inc(LIdx, 4); - //36 - //zero the next three bytes - FillChar(LTmp[LIdx], 3, 0); - Inc(LIdx, 3); - //next header (protocol type determines it - LTmp[LIdx] := Id_IPPROTO_ICMPV6; // Id_IPPROTO_ICMP6; - Inc(LIdx); - //combine the two - CopyTIdBytes(VBuffer, 0, LTmp, LIdx, Length(VBuffer)); - //zero out the checksum field - CopyTIdUInt16(0, LTmp, LIdx+AOffset); - - CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(LTmp)), VBuffer, AOffset); -end; - -function TIdStackWindows.ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer : TIdBytes; - APkt: TIdPacketInfo): UInt32; -var - LIP : String; - LPort : TIdPort; - LIPVersion : TIdIPVersion; - {Windows CE does not have WSARecvMsg} - {$IFNDEF WINCE} - LSize: PtrUInt; - LAddr: TIdBytes; - PAddr: PSOCKADDR_STORAGE; - LMsg : TWSAMSG; - LMsgBuf : TWSABUF; - LControl : TIdBytes; - LCurCmsg : LPWSACMSGHDR; //for iterating through the control buffer - PPktInfo: PInPktInfo; - PPktInfo6: PIn6PktInfo; - {$ENDIF} -begin - {$IFNDEF WINCE} - //This runs only on WIndows XP or later - // XP 5.1 at least, Vista 6.0 - if IndyCheckWindowsVersion(5, 1) then - begin - //we call the macro twice because we specified two possible structures. - //Id_IPV6_HOPLIMIT and Id_IPV6_PKTINFO - LSize := WSA_CMSG_SPACE(SizeOf(Byte)) + WSA_CMSG_SPACE(SizeOf(IN6_PKTINFO)); - SetLength(LControl, LSize); - - LMsgBuf.len := Length(VBuffer); // Length(VMsgData); - LMsgBuf.buf := PIdAnsiChar(Pointer(VBuffer)); // @VMsgData[0]; - - FillChar(LMsg, SIZE_TWSAMSG, 0); - - LMsg.lpBuffers := @LMsgBuf; - LMsg.dwBufferCount := 1; - - LMsg.Control.Len := LSize; - LMsg.Control.buf := PIdAnsiChar(Pointer(LControl)); - - // RLebeau: despite that we are not performing an overlapped I/O operation, - // WSARecvMsg() does not like the SOCKADDR variable being allocated on the - // stack, at least on my tests with Windows 7. So we will allocate it on - // the heap instead to keep WinSock happy... - SetLength(LAddr, SizeOf(SOCKADDR_STORAGE)); - PAddr := PSOCKADDR_STORAGE(@LAddr[0]); - - LMsg.name := IdWinsock2.PSOCKADDR(PAddr); - LMsg.namelen := Length(LAddr); - - CheckForSocketError(WSARecvMsg(ASocket, @LMsg, Result, nil, nil)); - APkt.Reset; - - case PAddr^.ss_family of - Id_PF_INET4: begin - APkt.SourceIP := TranslateTInAddrToString(PSockAddrIn(PAddr)^.sin_addr, Id_IPv4); - APkt.SourcePort := ntohs(PSockAddrIn(PAddr)^.sin_port); - APkt.SourceIPVersion := Id_IPv4; - end; - Id_PF_INET6: begin - APkt.SourceIP := TranslateTInAddrToString(PSockAddrIn6(PAddr)^.sin6_addr, Id_IPv6); - APkt.SourcePort := ntohs(PSockAddrIn6(PAddr)^.sin6_port); - APkt.SourceIPVersion := Id_IPv6; - end; - else begin - Result := 0; // avoid warning - IPVersionUnsupported; - end; - end; - - LCurCmsg := nil; - repeat - LCurCmsg := WSA_CMSG_NXTHDR(@LMsg, LCurCmsg); - if LCurCmsg = nil then begin - Break; - end; - case LCurCmsg^.cmsg_type of - IP_PKTINFO : //done this way because IPV6_PKTINF and IP_PKTINFO are both 19 - begin - case PAddr^.ss_family of - Id_PF_INET4: begin - PPktInfo := PInPktInfo(WSA_CMSG_DATA(LCurCmsg)); - APkt.DestIP := TranslateTInAddrToString(PPktInfo^.ipi_addr, Id_IPv4); - APkt.DestIF := PPktInfo^.ipi_ifindex; - APkt.DestIPVersion := Id_IPv4; - end; - Id_PF_INET6: begin - PPktInfo6 := PIn6PktInfo(WSA_CMSG_DATA(LCurCmsg)); - APkt.DestIP := TranslateTInAddrToString(PPktInfo6^.ipi6_addr, Id_IPv6); - APkt.DestIF := PPktInfo6^.ipi6_ifindex; - APkt.DestIPVersion := Id_IPv6; - end; - end; - end; - Id_IPV6_HOPLIMIT : - begin - APkt.TTL := WSA_CMSG_DATA(LCurCmsg)^; - end; - end; - until False; - end else - begin - {$ENDIF} - Result := RecvFrom(ASocket, VBuffer, Length(VBuffer), 0, LIP, LPort, LIPVersion); - APkt.Reset; - APkt.SourceIP := LIP; - APkt.SourcePort := LPort; - APkt.SourceIPVersion := LIPVersion; - APkt.DestIPVersion := LIPVersion; - {$IFNDEF WINCE} - end; - {$ENDIF} -end; - -function TIdStackWindows.CheckIPVersionSupport(const AIPVersion: TIdIPVersion): Boolean; -var - LTmpSocket: TIdStackSocketHandle; -begin - LTmpSocket := WSSocket(IdIPFamily[AIPVersion], Id_SOCK_STREAM, Id_IPPROTO_IP); - Result := LTmpSocket <> Id_INVALID_SOCKET; - if Result then begin - WSCloseSocket(LTmpSocket); - end; -end; - -{$IFNDEF WINCE} -{ -This is somewhat messy but I wanted to do things this way to support Int64 -file sizes. -} -function ServeFile(ASocket: TIdStackSocketHandle; const AFileName: string): Int64; -var - LFileHandle: THandle; - LSize: LARGE_INTEGER; - {$IFDEF STRING_UNICODE_MISMATCH} - LTemp: TIdPlatformString; - {$ENDIF} -begin - Result := 0; - - {$IFDEF STRING_UNICODE_MISMATCH} - LTemp := TIdPlatformString(AFileName); // explicit convert to Ansi/Unicode - {$ENDIF} - - LFileHandle := CreateFile( - {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(AFileName){$ENDIF}, - GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0); - - if LFileHandle <> INVALID_HANDLE_VALUE then - begin - try - if TransmitFile(ASocket, LFileHandle, 0, 0, nil, nil, 0) then - begin - if Assigned(GetFileSizeEx) then - begin - if not GetFileSizeEx(LFileHandle, LSize) then begin - Exit; - end; - end else - begin - LSize.LowPart := GetFileSize(LFileHandle, @LSize.HighPart); - if (LSize.LowPart = $FFFFFFFF) and (GetLastError() <> 0) then begin - Exit; - end; - end; - Result := LSize.QuadPart; - end; - finally - CloseHandle(LFileHandle); - end; - end; -end; -{$ENDIF} - -procedure TIdStackWindows.SetKeepAliveValues(ASocket: TIdStackSocketHandle; - const AEnabled: Boolean; const ATimeMS, AInterval: Integer); -var - ka: _tcp_keepalive; - Bytes: DWORD; -begin - // TODO: instead of doing an OS version check, always call SIO_KEEPALIVE_VALS - // when AEnabled is True, and then fallback to SO_KEEPALIVE if WSAIoctl() - // reports that SIO_KEEPALIVE_VALS is not supported... - - // SIO_KEEPALIVE_VALS is supported on Win2K+ and WinCE 4.x only - if AEnabled and IndyCheckWindowsVersion({$IFDEF WINCE}4{$ELSE}5{$ENDIF}) then - begin - ka.onoff := 1; - ka.keepalivetime := ATimeMS; - ka.keepaliveinterval := AInterval; - // RLebeau: in XE4+, PDWORD is NOT defined as ^DWORD, so we have to use a type-cast! - WSAIoctl(ASocket, SIO_KEEPALIVE_VALS, @ka, SizeOf(ka), nil, 0, PDWORD(@Bytes), nil, nil); - end else begin - SetSocketOption(ASocket, Id_SOL_SOCKET, Id_SO_KEEPALIVE, iif(AEnabled, 1, 0)); - end; -end; - -initialization - GStarted := False; - GSocketListClass := TIdSocketListWindows; - // Check if we are running under windows NT - {$IFNDEF WINCE} - if IndyWindowsPlatform = VER_PLATFORM_WIN32_NT then begin - GetFileSizeEx := LoadLibFunction(GetModuleHandle('Kernel32.dll'), 'GetFileSizeEx'); - GServeFileProc := ServeFile; - end; - {$ENDIF} - {$IFDEF USE_IPHLPAPI} - InitializeIPHelperStubs; - {$ENDIF} -finalization - IdWship6.CloseLibrary; - UninitializeWinSock; - {$IFDEF USE_IPHLPAPI} - UninitializeIPHelperAPI; - {$ENDIF} - GStarted := False; - -end. +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. + + + $Log$ + + + Rev 1.8 10/26/2004 8:20:04 PM JPMugaas + Fixed some oversights with conversion. OOPS!!! + + + Rev 1.7 07/06/2004 21:31:24 CCostelloe + Kylix 3 changes + + + Rev 1.6 4/18/04 10:43:24 PM RLebeau + Fixed syntax error + + + Rev 1.5 4/18/04 10:29:58 PM RLebeau + Renamed Int64Parts structure to TIdInt64Parts + + + Rev 1.4 4/18/04 2:47:46 PM RLebeau + Conversion support for Int64 values + + + Rev 1.3 2004.03.07 11:45:28 AM czhower + Flushbuffer fix + other minor ones found + + + Rev 1.2 3/6/2004 5:16:34 PM JPMugaas + Bug 67 fixes. Do not write to const values. + + + Rev 1.1 3/6/2004 4:23:52 PM JPMugaas + Error #62 fix. This seems to work in my tests. + + + Rev 1.0 2004.02.03 3:14:48 PM czhower + Move and updates + + + Rev 1.33 2/1/2004 6:10:56 PM JPMugaas + GetSockOpt. + + + Rev 1.32 2/1/2004 3:28:36 AM JPMugaas + Changed WSGetLocalAddress to GetLocalAddress and moved into IdStack since + that will work the same in the DotNET as elsewhere. This is required to + reenable IPWatch. + + + Rev 1.31 1/31/2004 1:12:48 PM JPMugaas + Minor stack changes required as DotNET does support getting all IP addresses + just like the other stacks. + + + Rev 1.30 12/4/2003 3:14:52 PM BGooijen + Added HostByAddress + + + Rev 1.29 1/3/2004 12:38:56 AM BGooijen + Added function SupportsIPv6 + + + Rev 1.28 12/31/2003 9:52:02 PM BGooijen + Added IPv6 support + + + Rev 1.27 10/26/2003 05:33:14 PM JPMugaas + LocalAddresses should work. + + + Rev 1.26 10/26/2003 5:04:28 PM BGooijen + UDP Server and Client + + + Rev 1.25 10/26/2003 09:10:26 AM JPMugaas + Calls necessary for IPMulticasting. + + + Rev 1.24 10/22/2003 04:40:52 PM JPMugaas + Should compile with some restored functionality. Still not finished. + + + Rev 1.23 10/21/2003 11:04:20 PM BGooijen + Fixed name collision + + + Rev 1.22 10/21/2003 01:20:02 PM JPMugaas + Restore GWindowsStack because it was needed by SuperCore. + + + Rev 1.21 10/21/2003 06:24:28 AM JPMugaas + BSD Stack now have a global variable for refercing by platform specific + things. Removed corresponding var from Windows stack. + + + Rev 1.20 10/19/2003 5:21:32 PM BGooijen + SetSocketOption + + + Rev 1.19 2003.10.11 5:51:16 PM czhower + -VCL fixes for servers + -Chain suport for servers (Super core) + -Scheduler upgrades + -Full yarn support + + + Rev 1.18 2003.10.02 8:01:08 PM czhower + .Net + + + Rev 1.17 2003.10.02 12:44:44 PM czhower + Fix for Bind, Connect + + + Rev 1.16 2003.10.02 10:16:32 AM czhower + .Net + + + Rev 1.15 2003.10.01 9:11:26 PM czhower + .Net + + + Rev 1.14 2003.10.01 12:30:08 PM czhower + .Net + + + Rev 1.12 10/1/2003 12:14:12 AM BGooijen + DotNet: removing CheckForSocketError + + + Rev 1.11 2003.10.01 1:12:40 AM czhower + .Net + + + Rev 1.10 2003.09.30 1:23:04 PM czhower + Stack split for DotNet + + + Rev 1.9 9/8/2003 02:13:10 PM JPMugaas + SupportsIP6 function added for determining if IPv6 is installed on a system. + + + Rev 1.8 2003.07.14 1:57:24 PM czhower + -First set of IOCP fixes. + -Fixed a threadsafe problem with the stack class. + + + Rev 1.7 7/1/2003 05:20:44 PM JPMugaas + Minor optimizations. Illiminated some unnecessary string operations. + + + Rev 1.5 7/1/2003 03:39:58 PM JPMugaas + Started numeric IP function API calls for more efficiency. + + + Rev 1.4 7/1/2003 12:46:06 AM JPMugaas + Preliminary stack functions taking an IP address numerical structure instead + of a string. + + + Rev 1.3 5/19/2003 6:00:28 PM BGooijen + TIdStackWindows.WSGetHostByAddr raised an ERangeError when the last number in + the ip>127 + + + Rev 1.2 5/10/2003 4:01:28 PM BGooijen + + + Rev 1.1 2003.05.09 10:59:28 PM czhower + + + Rev 1.0 11/13/2002 08:59:38 AM JPMugaas +} +unit IdStackWindows; + +interface + +{$I IdCompilerDefines.inc} + +uses + Classes, + IdGlobal, IdException, IdStackBSDBase, IdStackConsts, IdWinsock2, IdStack, + SysUtils, + Windows; + +type + EIdIPv6Unavailable = class(EIdException); + + TIdStackWindows = class(TIdStackBSDBase) + protected + procedure WSQuerryIPv6Route(ASocket: TIdStackSocketHandle; + const AIP: String; const APort : UInt16; var VSource; var VDest); + procedure WriteChecksumIPv6(s : TIdStackSocketHandle; var VBuffer : TIdBytes; + const AOffset : Integer; const AIP : String; const APort : TIdPort); + function HostByName(const AHostName: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; + function ReadHostName: string; override; + function WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; override; + function WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; + const ABufferLength, AFlags: Integer): Integer; override; + function WSSend(ASocket: TIdStackSocketHandle; const ABuffer; + const ABufferLength, AFlags: Integer): Integer; override; + function WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; override; + {$IFNDEF VCL_XE3_OR_ABOVE} + procedure WSGetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; + procedure WSSetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; + {$ENDIF} + public + function Accept(ASocket: TIdStackSocketHandle; var VIP: string; var VPort: TIdPort; + var VIPVersion: TIdIPVersion): TIdStackSocketHandle; override; + function HostToNetwork(AValue: UInt16): UInt16; override; + function HostToNetwork(AValue: UInt32): UInt32; override; + function HostToNetwork(AValue: TIdUInt64): TIdUInt64; override; + procedure Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); override; + function NetworkToHost(AValue: UInt16): UInt16; override; + function NetworkToHost(AValue: UInt32): UInt32; override; + function NetworkToHost(AValue: TIdUInt64): TIdUInt64; override; + procedure SetBlocking(ASocket: TIdStackSocketHandle; const ABlocking: Boolean); override; + function WouldBlock(const AResult: Integer): Boolean; override; + // + function HostByAddress(const AAddress: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; override; + + function WSGetServByName(const AServiceName: string): TIdPort; override; + procedure AddServByPortToList(const APortNumber: TIdPort; AAddresses: TStrings); override; + + function RecvFrom(const ASocket: TIdStackSocketHandle; var VBuffer; + const ALength, AFlags: Integer; var VIP: string; var VPort: TIdPort; + var VIPVersion: TIdIPVersion): Integer; override; + function ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer: TIdBytes; + APkt : TIdPacketInfo): UInt32; override; + + procedure WSSendTo(ASocket: TIdStackSocketHandle; const ABuffer; + const ABufferLength, AFlags: Integer; const AIP: string; const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + + function WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; + const ANonBlocking: Boolean = False): TIdStackSocketHandle; override; + function WSTranslateSocketErrorMsg(const AErr: integer): string; override; + function WSGetLastError: Integer; override; + procedure WSSetLastError(const AErr : Integer); override; + // + procedure Bind(ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + procedure Connect(const ASocket: TIdStackSocketHandle; const AIP: string; + const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + constructor Create; override; + destructor Destroy; override; + procedure Disconnect(ASocket: TIdStackSocketHandle); override; + procedure GetPeerName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; + procedure GetSocketName(ASocket: TIdStackSocketHandle; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion); override; + {$IFDEF VCL_XE3_OR_ABOVE} + procedure GetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; var AOptVal; var AOptLen: Integer); override; + procedure SetSocketOption(ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; + AOptName: TIdSocketOption; const AOptVal; const AOptLen: Integer); override; + {$ENDIF} + function IOControl(const s: TIdStackSocketHandle; const cmd: UInt32; var arg: UInt32): Integer; override; + function SupportsIPv4: Boolean; override; + function SupportsIPv6: Boolean; override; + function CheckIPVersionSupport(const AIPVersion: TIdIPVersion): boolean; override; + procedure WriteChecksum(s : TIdStackSocketHandle; + var VBuffer : TIdBytes; + const AOffset : Integer; + const AIP : String; + const APort : TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); override; + procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); override; + procedure SetKeepAliveValues(ASocket: TIdStackSocketHandle; + const AEnabled: Boolean; const ATimeMS, AInterval: Integer); override; + end; + +var +//This is for the Win32-only package (SuperCore) + GWindowsStack : TIdStackWindows = nil{$IFDEF HAS_DEPRECATED}{$IFDEF USE_SEMICOLON_BEFORE_DEPRECATED};{$ENDIF} deprecated{$IFDEF HAS_DEPRECATED_MSG} 'Use GStack or GBSDStack instead'{$ENDIF}{$ENDIF}; + +implementation + +{$DEFINE USE_IPHLPAPI} + +{$IFDEF USE_IPHLPAPI} + // TODO: Move this to IdCompilerDefines.inc + {$IFDEF VCL_XE2_OR_ABOVE} + {$DEFINE HAS_UNIT_IpTypes} + {$DEFINE HAS_UNIT_IpHlpApi} + {$ENDIF} +{$ENDIF} + +uses + IdIDN, IdResourceStrings, IdWship6 + {$IFDEF USE_IPHLPAPI} + {$IFDEF HAS_UNIT_IpTypes} + , Winapi.IpTypes + {$ENDIF} + {$IFDEF HAS_UNIT_IpHlpApi} + , Winapi.IpHlpApi + {$ENDIF} + {$ENDIF} + ; + +{$IFNDEF WINCE} +type + TGetFileSizeEx = function(hFile : THandle; var lpFileSize : LARGE_INTEGER) : BOOL; stdcall; +{$ENDIF} + +const + SIZE_HOSTNAME = 250; + +var + GStarted: Boolean = False; + {$IFNDEF WINCE} + GetFileSizeEx : TGetFileSizeEx = nil; + {$ENDIF} + +{ IPHLPAPI support } + +{$IFDEF USE_IPHLPAPI} + +const + IPHLPAPI_DLL = 'iphlpapi.dll'; + {$IFNDEF HAS_UNIT_IpTypes} + MAX_ADAPTER_DESCRIPTION_LENGTH = 128; + MAX_ADAPTER_NAME_LENGTH = 256; + MAX_ADAPTER_ADDRESS_LENGTH = 8; + MAX_DHCPV6_DUID_LENGTH = 130; + MAX_DNS_SUFFIX_STRING_LENGTH = 256; + GAA_FLAG_SKIP_UNICAST = $0001; + GAA_FLAG_SKIP_ANYCAST = $0002; + GAA_FLAG_SKIP_MULTICAST = $0004; + GAA_FLAG_SKIP_DNS_SERVER = $0008; + GAA_FLAG_INCLUDE_PREFIX = $0010; + GAA_FLAG_SKIP_FRIENDLY_NAME = $0020; + IP_ADAPTER_RECEIVE_ONLY = $08; + {$ENDIF} + IF_TYPE_SOFTWARE_LOOPBACK = 24; + +type + PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS = ^IP_UNIDIRECTIONAL_ADAPTER_ADDRESS; + IP_UNIDIRECTIONAL_ADAPTER_ADDRESS = record + NumAdapters: ULONG; + Address: array[0..0] of TInAddr; + end; + + {$IFNDEF HAS_UNIT_IpTypes} + {$MINENUMSIZE 4} + + time_t = TIdNativeInt; + IFTYPE = ULONG; + IF_INDEX = ULONG; + NET_IF_COMPARTMENT_ID = UINT32; + NET_IF_NETWORK_GUID = TGUID; + + IP_PREFIX_ORIGIN = ( + IpPrefixOriginOther, + IpPrefixOriginManual, + IpPrefixOriginWellKnown, + IpPrefixOriginDhcp, + IpPrefixOriginRouterAdvertisement, + {$IFNDEF HAS_ENUM_ELEMENT_VALUES} + ippoUnused5, + ippoUnused6, + ippoUnused7, + ippoUnused8, + ippoUnused9, + ippoUnused10, + ippoUnused11, + ippoUnused12, + ippoUnused13, + ippoUnused14, + ippoUnused15, + {$ENDIF} + IpPrefixOriginUnchanged); + + IP_SUFFIX_ORIGIN = ( + IpSuffixOriginOther, + IpSuffixOriginManual, + IpSuffixOriginWellKnown, + IpSuffixOriginDhcp, + IpSuffixOriginLinkLayerAddress, + IpSuffixOriginRandom, + {$IFNDEF HAS_ENUM_ELEMENT_VALUES} + ipsoUnued6, + ipsoUnued7, + ipsoUnued8, + ipsoUnued9, + ipsoUnued10, + ipsoUnued11, + ipsoUnued12, + ipsoUnued13, + ipsoUnued14, + ipsoUnued15, + {$ENDIF} + IpSuffixOriginUnchanged); + + IP_DAD_STATE = ( + IpDadStateInvalid, + IpDadStateTentative, + IpDadStateDuplicate, + IpDadStateDeprecated, + IpDadStatePreferred); + + IF_OPER_STATUS = ( + {$IFNDEF HAS_ENUM_ELEMENT_VALUES} + ifosUnused, + IfOperStatusUp, + {$ELSE} + IfOperStatusUp = 1, + {$ENDIF} + IfOperStatusDown, + IfOperStatusTesting, + IfOperStatusUnknown, + IfOperStatusDormant, + IfOperStatusNotPresent, + IfOperStatusLowerLayerDown); + + NET_IF_CONNECTION_TYPE = ( + {$IFNDEF HAS_ENUM_ELEMENT_VALUES} + nictUnused, + NetIfConnectionDedicated, + {$ELSE} + NetIfConnectionDedicated = 1, + {$ENDIF} + NetIfConnectionPassive, + NetIfConnectionDemand, + NetIfConnectionMaximum); + + TUNNEL_TYPE = ( + TunnelTypeNone, + TunnelTypeOther, + TunnelTypeDirect, + TunnelType6To4, + TunnelTypeIsatap, + TunnelTypeTeredo, + TunnelTypeIPHTTPS); + + IP_ADDRESS_STRING = record + S: array [0..15] of TIdAnsiChar; + end; + IP_MASK_STRING = IP_ADDRESS_STRING; + + PIP_ADDR_STRING = ^IP_ADDR_STRING; + IP_ADDR_STRING = record + Next: PIP_ADDR_STRING; + IpAddress: IP_ADDRESS_STRING; + IpMask: IP_MASK_STRING; + Context: DWORD; + end; + + PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO; + IP_ADAPTER_INFO = record + Next: PIP_ADAPTER_INFO; + ComboIndex: DWORD; + AdapterName: array [0..MAX_ADAPTER_NAME_LENGTH + 3] of TIdAnsiChar; + Description: array [0..MAX_ADAPTER_DESCRIPTION_LENGTH + 3] of TIdAnsiChar; + AddressLength: UINT; + Address: array [0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE; + Index: DWORD; + Type_: UINT; + DhcpEnabled: UINT; + CurrentIpAddress: PIP_ADDR_STRING; + IpAddressList: IP_ADDR_STRING; + GatewayList: IP_ADDR_STRING; + DhcpServer: IP_ADDR_STRING; + HaveWins: BOOL; + PrimaryWinsServer: IP_ADDR_STRING; + SecondaryWinsServer: IP_ADDR_STRING; + LeaseObtained: time_t; + LeaseExpires: time_t; + end; + + SOCKET_ADDRESS = record + lpSockaddr: IdWinsock2.LPSOCKADDR; + iSockaddrLength: Integer; + end; + + PIP_ADAPTER_UNICAST_ADDRESS = ^IP_ADAPTER_UNICAST_ADDRESS; + IP_ADAPTER_UNICAST_ADDRESS = record + Union: record + case Integer of + 0: ( + Alignment: ULONGLONG); + 1: ( + Length: ULONG; + Flags: DWORD); + end; + Next: PIP_ADAPTER_UNICAST_ADDRESS; + Address: SOCKET_ADDRESS; + PrefixOrigin: IP_PREFIX_ORIGIN; + SuffixOrigin: IP_SUFFIX_ORIGIN; + DadState: IP_DAD_STATE; + ValidLifetime: ULONG; + PreferredLifetime: ULONG; + LeaseLifetime: ULONG; + + // This structure member is only available on Windows Vista and later + OnLinkPrefixLength: UCHAR; + end; + + PIP_ADAPTER_ANYCAST_ADDRESS = ^IP_ADAPTER_ANYCAST_ADDRESS; + IP_ADAPTER_ANYCAST_ADDRESS = record + Union: record + case Integer of + 0: ( + Alignment: ULONGLONG); + 1: ( + Length: ULONG; + Flags: DWORD); + end; + Next: PIP_ADAPTER_ANYCAST_ADDRESS; + Address: SOCKET_ADDRESS; + end; + + PIP_ADAPTER_MULTICAST_ADDRESS = ^IP_ADAPTER_MULTICAST_ADDRESS; + IP_ADAPTER_MULTICAST_ADDRESS = record + Union: record + case Integer of + 0: ( + Alignment: ULONGLONG); + 1: ( + Length: ULONG; + Flags: DWORD); + end; + Next: PIP_ADAPTER_MULTICAST_ADDRESS; + Address: SOCKET_ADDRESS; + end; + + PIP_ADAPTER_DNS_SERVER_ADDRESS = ^IP_ADAPTER_DNS_SERVER_ADDRESS; + IP_ADAPTER_DNS_SERVER_ADDRESS = record + Union: record + case Integer of + 0: ( + Alignment: ULONGLONG); + 1: ( + Length: ULONG; + Reserved: DWORD); + end; + Next: PIP_ADAPTER_DNS_SERVER_ADDRESS; + Address: SOCKET_ADDRESS; + end; + + PIP_ADAPTER_PREFIX = ^IP_ADAPTER_PREFIX; + IP_ADAPTER_PREFIX = record + Union: record + case Integer of + 0: ( + Alignment: ULONGLONG); + 1: ( + Length: ULONG; + Flags: DWORD); + end; + Next: PIP_ADAPTER_PREFIX; + Address: SOCKET_ADDRESS; + PrefixLength: ULONG; + end; + + PIP_ADAPTER_WINS_SERVER_ADDRESS_LH = ^IP_ADAPTER_WINS_SERVER_ADDRESS_LH; + IP_ADAPTER_WINS_SERVER_ADDRESS_LH = record + Union: record + case Integer of + 0: ( + Alignment: ULONGLONG); + 1: ( + Length: ULONG; + Reserved: DWORD); + end; + Next: PIP_ADAPTER_WINS_SERVER_ADDRESS_LH; + Address: SOCKET_ADDRESS; + end; + + PIP_ADAPTER_GATEWAY_ADDRESS_LH = ^IP_ADAPTER_GATEWAY_ADDRESS_LH; + IP_ADAPTER_GATEWAY_ADDRESS_LH = record + Union: record + case Integer of + 0: ( + Alignment: ULONGLONG); + 1: ( + Length: ULONG; + Reserved: DWORD); + end; + Next: PIP_ADAPTER_GATEWAY_ADDRESS_LH; + Address: SOCKET_ADDRESS; + end; + + IF_LUID = record + case Integer of + 0: ( + Value: ULONG64); + 1: ( + Info: ULONG64); + end; + + PIP_ADAPTER_DNS_SUFFIX = ^IP_ADAPTER_DNS_SUFFIX; + IP_ADAPTER_DNS_SUFFIX = record + Next: PIP_ADAPTER_DNS_SUFFIX; + AString: array[0..MAX_DNS_SUFFIX_STRING_LENGTH - 1] of WCHAR; + end; + + PIP_ADAPTER_ADDRESSES = ^IP_ADAPTER_ADDRESSES; + IP_ADAPTER_ADDRESSES = record + Union: record + case Integer of + 0: ( + Alignment: ULONGLONG); + 1: ( + Length: ULONG; + IfIndex: DWORD); + end; + Next: PIP_ADAPTER_ADDRESSES; + AdapterName: PIdAnsiChar; + FirstUnicastAddress: PIP_ADAPTER_UNICAST_ADDRESS; + FirstAnycastAddress: PIP_ADAPTER_ANYCAST_ADDRESS; + FirstMulticastAddress: PIP_ADAPTER_MULTICAST_ADDRESS; + FirstDnsServerAddress: PIP_ADAPTER_DNS_SERVER_ADDRESS; + DnsSuffix: PWCHAR; + Description: PWCHAR; + FriendlyName: PWCHAR; + PhysicalAddress: array [0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE; + PhysicalAddressLength: DWORD; + Flags: DWORD; + Mtu: DWORD; + IfType: IFTYPE; + OperStatus: IF_OPER_STATUS; + Ipv6IfIndex: IF_INDEX; + ZoneIndices: array [0..15] of DWORD; + FirstPrefix: PIP_ADAPTER_PREFIX; + TransmitLinkSpeed: ULONG64; + ReceiveLinkSpeed: ULONG64; + FirstWinsServerAddress: PIP_ADAPTER_WINS_SERVER_ADDRESS_LH; + FirstGatewayAddress: PIP_ADAPTER_GATEWAY_ADDRESS_LH; + Ipv4Metric: ULONG; + Ipv6Metric: ULONG; + Luid: IF_LUID; + Dhcpv4Server: SOCKET_ADDRESS; + CompartmentId: NET_IF_COMPARTMENT_ID; + NetworkGuid: NET_IF_NETWORK_GUID; + ConnectionType: NET_IF_CONNECTION_TYPE; + TunnelType: TUNNEL_TYPE; + // + // DHCP v6 Info. + // + Dhcpv6Server: SOCKET_ADDRESS; + Dhcpv6ClientDuid: array [0..MAX_DHCPV6_DUID_LENGTH - 1] of Byte; + Dhcpv6ClientDuidLength: ULONG; + Dhcpv6Iaid: ULONG; + FirstDnsSuffix: PIP_ADAPTER_DNS_SUFFIX; + end; + + {$ENDIF} + + PMIB_IPADDRROW = ^MIB_IPADDRROW; + MIB_IPADDRROW = record + dwAddr: DWORD; + dwIndex: DWORD; + dwMask: DWORD; + dwBCastAddr: DWORD; + dwReasmSize: DWORD; + unused1: Word; + wType: Word; + end; + + PMIB_IPADDRTABLE = ^MIB_IPADDRTABLE; + MIB_IPADDRTABLE = record + dwNumEntries: DWORD; + table: array[0..0] of MIB_IPADDRROW; + end; + + NETIO_STATUS = DWORD; + + TGetIpAddrTable = function(pIpAddrTable: PMIB_IPADDRTABLE; var pdwSize: ULONG; bOrder: BOOL): DWORD; stdcall; + TGetUniDirectionalAdapterInfo = function(pIPIfInfo: PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS; var dwOutBufLen: ULONG): DWORD; stdcall; + TGetAdaptersInfo = function(pAdapterInfo: PIP_ADAPTER_INFO; var pOutBufLen: ULONG): DWORD; stdcall; + TGetAdaptersAddresses = function(Family: ULONG; Flags: DWORD; Reserved: PVOID; pAdapterAddresses: PIP_ADAPTER_ADDRESSES; var OutBufLen: ULONG): DWORD; stdcall; + TConvertLengthToIpv4Mask = function(MaskLength: ULONG; var Mask: ULONG): NETIO_STATUS; stdcall; + +var + hIpHlpApi: TIdLibHandle = IdNilHandle; + GetIpAddrTable: TGetIpAddrTable = nil; + GetUniDirectionalAdapterInfo: TGetUniDirectionalAdapterInfo = nil; + GetAdaptersInfo: TGetAdaptersInfo = nil; + GetAdaptersAddresses: TGetAdaptersAddresses = nil; + ConvertLengthToIpv4Mask: TConvertLengthToIpv4Mask = nil; + +function FixupIPHelperStub(const AName: TIdLibFuncName; DefImpl: Pointer): Pointer; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := nil; + if hIpHlpApi <> IdNilHandle then begin + Result := LoadLibFunction(hIpHlpApi, AName); + end; + if Result = nil then begin + Result := DefImpl; + end; +end; + +function Impl_GetIpAddrTable(pIpAddrTable: PMIB_IPADDRTABLE; var pdwSize: ULONG; bOrder: BOOL): DWORD; stdcall; +begin + pdwSize := 0; + Result := ERROR_NOT_SUPPORTED; +end; + +function Stub_GetIpAddrTable(pIpAddrTable: PMIB_IPADDRTABLE; var pdwSize: ULONG; bOrder: BOOL): DWORD; stdcall; +begin + @GetIpAddrTable := FixupIPHelperStub('GetIpAddrTable', @Impl_GetIpAddrTable); {Do not localize} + Result := GetIpAddrTable(pIpAddrTable, pdwSize, bOrder); +end; + +function Impl_GetUniDirectionalAdapterInfo(pIPIfInfo: PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS; var dwOutBufLen: ULONG): DWORD; stdcall; +begin + dwOutBufLen := 0; + Result := ERROR_NOT_SUPPORTED; +end; + +function Stub_GetUniDirectionalAdapterInfo(pIPIfInfo: PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS; var dwOutBufLen: ULONG): DWORD; stdcall; +begin + @GetUniDirectionalAdapterInfo := FixupIPHelperStub('GetUniDirectionalAdapterInfo', @Impl_GetUniDirectionalAdapterInfo); {Do not localize} + Result := GetUniDirectionalAdapterInfo(pIPIfInfo, dwOutBufLen); +end; + +function Impl_GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO; var pOutBufLen: ULONG): DWORD; stdcall; +begin + pOutBufLen := 0; + Result := ERROR_NOT_SUPPORTED; +end; + +function Stub_GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO; var pOutBufLen: ULONG): DWORD; stdcall; +begin + @GetAdaptersInfo := FixupIPHelperStub('GetAdaptersInfo', @Impl_GetAdaptersInfo); {Do not localize} + Result := GetAdaptersInfo(pAdapterInfo, pOutBufLen); +end; + +function Impl_GetAdaptersAddresses(Family: ULONG; Flags: DWORD; Reserved: PVOID; pAdapterAddresses: PIP_ADAPTER_ADDRESSES; var OutBufLen: ULONG): DWORD; stdcall; +begin + OutBufLen := 0; + Result := ERROR_NOT_SUPPORTED; +end; + +function Stub_GetAdaptersAddresses(Family: ULONG; Flags: DWORD; Reserved: PVOID; pAdapterAddresses: PIP_ADAPTER_ADDRESSES; var OutBufLen: ULONG): DWORD; stdcall; +begin + @GetAdaptersAddresses := FixupIPHelperStub('GetAdaptersAddresses', @Impl_GetAdaptersAddresses); {Do not localize} + Result := GetAdaptersAddresses(Family, Flags, Reserved, pAdapterAddresses, OutBufLen); +end; + +function Impl_ConvertLengthToIpv4Mask(MaskLength: ULONG; var Mask: ULONG): NETIO_STATUS; stdcall; +begin + // TODO: implement manually + Mask := INADDR_NONE; + if MaskLength > 32 then begin + Result := ERROR_INVALID_PARAMETER; + end else begin + Result := ERROR_NOT_SUPPORTED; + end; +end; + +function Stub_ConvertLengthToIpv4Mask(MaskLength: ULONG; var Mask: ULONG): NETIO_STATUS; stdcall; +begin + @ConvertLengthToIpv4Mask := FixupIPHelperStub('ConvertLengthToIpv4Mask', @Impl_ConvertLengthToIpv4Mask); {Do not localize} + Result := ConvertLengthToIpv4Mask(MaskLength, Mask); +end; + +procedure InitializeIPHelperStubs; +begin + GetIpAddrTable := Stub_GetIpAddrTable; + GetUniDirectionalAdapterInfo := Stub_GetUniDirectionalAdapterInfo; + GetAdaptersInfo := Stub_GetAdaptersInfo; + GetAdaptersAddresses := Stub_GetAdaptersAddresses; + ConvertLengthToIpv4Mask := Stub_ConvertLengthToIpv4Mask; +end; + +procedure InitializeIPHelperAPI; +begin + if hIpHlpApi = IdNilHandle then begin + hIpHlpApi := SafeLoadLibrary(IPHLPAPI_DLL); + end; +end; + +procedure UninitializeIPHelperAPI; +begin + if hIpHlpApi <> IdNilHandle then + begin + FreeLibrary(hIpHlpApi); + hIpHlpApi := IdNilHandle; + end; + InitializeIPHelperStubs; +end; + +{$ENDIF} + +{ TIdStackWindows } + +constructor TIdStackWindows.Create; +begin + inherited Create; + if not GStarted then begin + try + InitializeWinSock; + IdWship6.InitLibrary; + IdIDN.InitIDNLibrary; + {$IFDEF USE_IPHLPAPI} + InitializeIPHelperAPI; + {$ENDIF} + except + on E: Exception do begin + IndyRaiseOuterException(EIdStackInitializationFailed.Create(E.Message)); + end; + end; + GStarted := True; + end; + {$I IdSymbolDeprecatedOff.inc} + GWindowsStack := Self; + {$I IdSymbolDeprecatedOn.inc} +end; + +destructor TIdStackWindows.Destroy; +begin + //DLL Unloading and Cleanup is done at finalization + inherited Destroy; +end; + +function TIdStackWindows.Accept(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion): TIdStackSocketHandle; +var + LSize: Integer; + LAddr: SOCKADDR_STORAGE; +begin + LSize := SizeOf(LAddr); + Result := IdWinsock2.accept(ASocket, IdWinsock2.PSOCKADDR(@LAddr), @LSize); + if Result <> INVALID_SOCKET then begin + case LAddr.ss_family of + Id_PF_INET4: begin + VIP := TranslateTInAddrToString(PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); + VPort := ntohs(PSockAddrIn(@LAddr)^.sin_port); + VIPVersion := Id_IPv4; + end; + Id_PF_INET6: begin + VIP := TranslateTInAddrToString(PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); + VPort := ntohs(PSockAddrIn6(@LAddr)^.sin6_port); + VIPVersion := Id_IPv6; + end; + else begin + CloseSocket(Result); + Result := INVALID_SOCKET; + IPVersionUnsupported; + end; + end; + end; +end; + +procedure TIdStackWindows.Bind(ASocket: TIdStackSocketHandle; + const AIP: string; const APort: TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LAddr: SOCKADDR_STORAGE; + LSize: Integer; +begin + FillChar(LAddr, SizeOf(LAddr), 0); + case AIPVersion of + Id_IPv4: begin + PSockAddrIn(@LAddr)^.sin_family := Id_PF_INET4; + if AIP <> '' then begin + TranslateStringToTInAddr(AIP, PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); + end; + PSockAddrIn(@LAddr)^.sin_port := htons(APort); + LSize := SIZE_TSOCKADDRIN; + end; + Id_IPv6: begin + PSockAddrIn6(@LAddr)^.sin6_family := Id_PF_INET6; + if AIP <> '' then begin + TranslateStringToTInAddr(AIP, PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); + end; + PSockAddrIn6(@LAddr)^.sin6_port := htons(APort); + LSize := SIZE_TSOCKADDRIN6; + end; + else begin + LSize := 0; // avoid warning + IPVersionUnsupported; + end; + end; + CheckForSocketError(IdWinsock2.bind(ASocket, IdWinsock2.PSOCKADDR(@LAddr), LSize)); +end; + +function TIdStackWindows.WSCloseSocket(ASocket: TIdStackSocketHandle): Integer; +begin + Result := CloseSocket(ASocket); +end; + +function TIdStackWindows.HostByAddress(const AAddress: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; +var + {$IFDEF UNICODE} + Hints: TAddrInfoW; + LAddrInfo: pAddrInfoW; + {$ELSE} + Hints: TAddrInfo; + LAddrInfo: pAddrInfo; + {$ENDIF} + RetVal: Integer; + {$IFDEF STRING_UNICODE_MISMATCH} + LTemp: TIdPlatformString; + {$ENDIF} +begin + if not (AIPVersion in [Id_IPv4, Id_IPv6]) then begin + IPVersionUnsupported; + end; + + // TODO: should this be calling getnameinfo() first and then getaddrinfo() + // to check for a malicious PTR record, like the other TIdStack classes do? + + // TODO: use TranslateStringToTInAddr() instead of getaddrinfo() to convert + // the IP address to a sockaddr struct for getnameinfo(), like other TIdStack + // classes do. + + FillChar(Hints, SizeOf(Hints), 0); + Hints.ai_family := IdIPFamily[AIPVersion]; + Hints.ai_socktype := Integer(SOCK_STREAM); + Hints.ai_flags := AI_NUMERICHOST; + LAddrInfo := nil; + + {$IFDEF STRING_UNICODE_MISMATCH} + LTemp := TIdPlatformString(AAddress); // explicit convert to Ansi/Unicode + {$ENDIF} + + RetVal := getaddrinfo( + {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(AAddress){$ENDIF}, + nil, @Hints, @LAddrInfo); + if RetVal <> 0 then begin + RaiseSocketError(gaiErrorToWsaError(RetVal)); + end; + try + SetLength( + {$IFDEF STRING_UNICODE_MISMATCH}LTemp{$ELSE}Result{$ENDIF}, + NI_MAXHOST); + RetVal := getnameinfo( + LAddrInfo.ai_addr, LAddrInfo.ai_addrlen, + {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(Result){$ENDIF}, + NI_MAXHOST, nil, 0, NI_NAMEREQD); + if RetVal <> 0 then begin + RaiseSocketError(gaiErrorToWsaError(RetVal)); + end; + Result := {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(Result){$ENDIF}; + finally + freeaddrinfo(LAddrInfo); + end; +end; + +function TIdStackWindows.ReadHostName: string; +var + // Note that there is no Unicode version of gethostname. + // Maybe use getnameinfo() instead? + LStr: array[0..SIZE_HOSTNAME] of TIdAnsiChar; + {$IFDEF USE_MARSHALLED_PTRS} + LStrPtr: TPtrWrapper; + {$ENDIF} +begin + {$IFDEF USE_MARSHALLED_PTRS} + LStrPtr := TPtrWrapper.Create(@LStr[0]); + {$ENDIF} + if gethostname( + {$IFDEF USE_MARSHALLED_PTRS} + LStrPtr.ToPointer + {$ELSE} + LStr + {$ENDIF}, SIZE_HOSTNAME) <> Id_SOCKET_ERROR then + begin + {$IFDEF USE_MARSHALLED_PTRS} + Result := TMarshal.ReadStringAsAnsiUpTo(CP_ACP, LStrPtr, SIZE_HOSTNAME); + {$ELSE} + //we have to specifically type cast a PIdAnsiChar to a string for D2009+. + //otherwise, we will get a warning about implicit typecast from AnsiString + //to string + LStr[SIZE_HOSTNAME] := TIdAnsiChar(0); + Result := String(LStr); + {$ENDIF} + end else begin + Result := ''; + end; +end; + +procedure TIdStackWindows.Listen(ASocket: TIdStackSocketHandle; ABackLog: Integer); +begin + CheckForSocketError(IdWinsock2.listen(ASocket, ABacklog)); +end; + +// RLebeau 12/16/09: MS Hotfix #971383 supposedly fixes a bug in Windows +// Server 2003 when client and server are running on the same machine. +// The bug can cause recv() to return 0 bytes prematurely even though data +// is actually pending. Uncomment the below define if you do not want to +// rely on the Hotfix always being installed. The workaround described by +// MS is to simply call recv() again to make sure data is really not pending. +// +{.$DEFINE IGNORE_KB971383_FIX} + +function TIdStackWindows.WSRecv(ASocket: TIdStackSocketHandle; var ABuffer; + const ABufferLength, AFlags: Integer) : Integer; +begin + Result := recv(ASocket, ABuffer, ABufferLength, AFlags); + {$IFDEF IGNORE_KB971383_FIX} + if Result = 0 then begin + Result := recv(ASocket, ABuffer, ABufferLength, AFlags); + end; + {$ENDIF} +end; + +function TIdStackWindows.RecvFrom(const ASocket: TIdStackSocketHandle; + var VBuffer; const ALength, AFlags: Integer; var VIP: string; + var VPort: TIdPort; var VIPVersion: TIdIPVersion): Integer; +var + LSize: Integer; + LAddr: SOCKADDR_STORAGE; +begin + LSize := SizeOf(LAddr); + Result := IdWinsock2.recvfrom(ASocket, VBuffer, ALength, AFlags, IdWinsock2.PSOCKADDR(@LAddr), @LSize); + if Result >= 0 then + begin + case LAddr.ss_family of + Id_PF_INET4: begin + VIP := TranslateTInAddrToString(PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); + VPort := ntohs(PSockAddrIn(@LAddr)^.sin_port); + VIPVersion := Id_IPv4; + end; + Id_PF_INET6: begin + VIP := TranslateTInAddrToString(PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); + VPort := ntohs(PSockAddrIn6(@LAddr)^.sin6_port); + VIPVersion := Id_IPv6; + end; + else begin + IPVersionUnsupported; + end; + end; + end; +end; + +function TIdStackWindows.WSSend(ASocket: TIdStackSocketHandle; + const ABuffer; const ABufferLength, AFlags: Integer): Integer; +begin + Result := CheckForSocketError(IdWinsock2.send(ASocket, ABuffer, ABufferLength, AFlags)); +end; + +procedure TIdStackWindows.WSSendTo(ASocket: TIdStackSocketHandle; + const ABuffer; const ABufferLength, AFlags: Integer; const AIP: string; + const APort: TIdPort; AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LAddr: SOCKADDR_STORAGE; + LSize: Integer; +begin + FillChar(LAddr, SizeOf(LAddr), 0); + case AIPVersion of + Id_IPv4: begin + PSockAddrIn(@LAddr)^.sin_family := Id_PF_INET4; + TranslateStringToTInAddr(AIP, PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); + PSockAddrIn(@LAddr)^.sin_port := htons(APort); + LSize := SIZE_TSOCKADDRIN; + end; + Id_IPv6: begin + PSockAddrIn6(@LAddr)^.sin6_family := Id_PF_INET6; + TranslateStringToTInAddr(AIP, PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); + PSockAddrIn6(@LAddr)^.sin6_port := htons(APort); + LSize := SIZE_TSOCKADDRIN6; + end; + else begin + LSize := 0; // avoid warning + IPVersionUnsupported; + end; + end; + LSize := IdWinsock2.sendto(ASocket, ABuffer, ABufferLength, AFlags, IdWinsock2.PSOCKADDR(@LAddr), LSize); + // TODO: call CheckForSocketError() here + if LSize = Id_SOCKET_ERROR then begin + // TODO: move this into RaiseLastSocketError() directly + if WSGetLastError() = Id_WSAEMSGSIZE then begin + raise EIdPackageSizeTooBig.Create(RSPackageSizeTooBig); + end else begin + RaiseLastSocketError; + end; + end + else if LSize <> ABufferLength then begin + raise EIdNotAllBytesSent.Create(RSNotAllBytesSent); + end; +end; + +function TIdStackWindows.WSGetLastError: Integer; +begin + Result := WSAGetLastError; + if Result = -1073741251{STATUS_HOST_UNREACHABLE} then begin + Result := WSAEHOSTUNREACH; + end +end; + +procedure TIdStackWindows.WSSetLastError(const AErr : Integer); +begin + WSASetLastError(AErr); +end; + +function TIdStackWindows.WSSocket(AFamily : Integer; AStruct : TIdSocketType; AProtocol: Integer; + const ANonBlocking: Boolean = False): TIdStackSocketHandle; +{ +var + LValue: UInt32; +} +begin + if ANonBlocking then begin + Result := WSASocket(AFamily, AStruct, AProtocol, nil, 0, WSA_FLAG_OVERLAPPED); + // TODO: do this instead? + { + Result := IdWinsock2.socket(AFamily, AStruct, AProtocol); + if Result <> INVALID_SOCKET then begin + //SetBlocking(Result, False); + LValue := 1; + ioctlsocket(Result, FIONBIO, LValue); + end; + } + end else begin + Result := IdWinsock2.socket(AFamily, AStruct, AProtocol); + end; +end; + +function TIdStackWindows.WSGetServByName(const AServiceName: string): TIdPort; +var + // Note that there is no Unicode version of getservbyname. + // Maybe use getaddrinfo() instead? + ps: PServEnt; + LPort: Integer; + {$IFDEF USE_MARSHALLED_PTRS} + M: TMarshaller; + {$ENDIF} +begin + ps := getservbyname( + {$IFDEF USE_MARSHALLED_PTRS} + M.AsAnsi(AServiceName).ToPointer + {$ELSE} + PIdAnsiChar( + {$IFDEF STRING_IS_ANSI} + AServiceName + {$ELSE} + AnsiString(AServiceName) // explicit convert to Ansi + {$ENDIF} + ) + {$ENDIF}, + nil); + if ps <> nil then begin + Result := ntohs(ps^.s_port); + end else + begin + // TODO: use TryStrToInt() instead... + try + LPort := IndyStrToInt(AServiceName); + except + on EConvertError do begin + LPort := -1; + IndyRaiseOuterException(EIdInvalidServiceName.CreateFmt(RSInvalidServiceName, [AServiceName])); + end; + end; + if (LPort < 0) or (LPort > High(TIdPort)) then begin + raise EIdInvalidServiceName.CreateFmt(RSInvalidServiceName, [AServiceName]); + end; + Result := TIdPort(LPort); + end; +end; + +procedure TIdStackWindows.AddServByPortToList(const APortNumber: TIdPort; AAddresses: TStrings); +type + // Note that there is no Unicode version of getservbyport. + PPAnsiCharArray = ^TPAnsiCharArray; + TPAnsiCharArray = packed array[0..(MaxInt div SizeOf(PIdAnsiChar))-1] of PIdAnsiChar; +var + ps: PServEnt; + i: integer; + p: PPAnsiCharArray; +begin + ps := getservbyport(htons(APortNumber), nil); + if ps = nil then begin + RaiseLastSocketError; + end; + AAddresses.BeginUpdate; + try + //we have to specifically type cast a PIdAnsiChar to a string for D2009+. + //otherwise, we will get a warning about implicit typecast from AnsiString + //to string + AAddresses.Add(String(ps^.s_name)); + i := 0; + p := Pointer(ps^.s_aliases); + while p[i] <> nil do + begin + AAddresses.Add(String(p[i])); + Inc(i); + end; + finally + AAddresses.EndUpdate; + end; +end; + +function TIdStackWindows.HostToNetwork(AValue: UInt16): UInt16; +begin + Result := htons(AValue); +end; + +function TIdStackWindows.NetworkToHost(AValue: UInt16): UInt16; +begin + Result := ntohs(AValue); +end; + +function TIdStackWindows.HostToNetwork(AValue: UInt32): UInt32; +begin + Result := htonl(AValue); +end; + +function TIdStackWindows.NetworkToHost(AValue: UInt32): UInt32; +begin + Result := ntohl(AValue); +end; + +function TIdStackWindows.HostToNetwork(AValue: TIdUInt64): TIdUInt64; +var + LParts: TIdUInt64Parts; + L: UInt32; +begin + // TODO: ARM is bi-endian, so if Windows is running on ARM instead of x86, + // can it ever be big endian? Or do ARM manufacturers put it in little endian + // for Windows installations? + + //if (htonl(1) <> 1) then begin + LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + L := htonl(LParts.HighPart); + LParts.HighPart := htonl(LParts.LowPart); + LParts.LowPart := L; + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; + //end else begin + // Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + //end; +end; + +function TIdStackWindows.NetworkToHost(AValue: TIdUInt64): TIdUInt64; +var + LParts: TIdUInt64Parts; + L: UInt32; +begin + // TODO: ARM is bi-endian, so if Windows is running on ARM instead of x86, + // can it ever be big endian? Or do ARM manufacturers put it in little endian + // for Windows installations? + + //if (ntohl(1) <> 1) then begin + LParts.QuadPart := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + L := ntohl(LParts.HighPart); + LParts.HighPart := ntohl(LParts.LowPart); + LParts.LowPart := L; + Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := LParts.QuadPart; + //end else begin + // Result{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF} := AValue{$IFDEF TIdUInt64_HAS_QuadPart}.QuadPart{$ENDIF}; + //end; +end; + +type + TIdStackLocalAddressAccess = class(TIdStackLocalAddress) + end; + +procedure TIdStackWindows.GetLocalAddressList(AAddresses: TIdStackLocalAddressList); + + {$IFDEF USE_IPHLPAPI} + + function IPv4MaskLengthToString(MaskLength: ULONG): String; + var + Mask: ULONG; + begin + if ConvertLengthToIpv4Mask(MaskLength, Mask) = ERROR_SUCCESS then begin + Result := TranslateTInAddrToString(Mask, Id_IPv4); + end else begin + Result := ''; + end; + end; + + procedure GetIPv4SubNetMasks(ASubNetMasks: TStrings); + var + Ret: DWORD; + BufLen: ULONG; + Table: PMIB_IPADDRTABLE; + pRow: PMIB_IPADDRROW; + I: ULONG; + begin + BufLen := 0; + Table := nil; + try + repeat + // Alternatively, use WSAIoctl(SIO_GET_INTERFACE_LIST), but + // I have noticed it does not always return IPv4 subnets! + Ret := GetIpAddrTable(Table, BufLen, FALSE); + case Ret of + ERROR_SUCCESS: + begin + if BufLen = 0 then begin + Exit; + end; + Break; + end; + ERROR_NOT_SUPPORTED: + Exit; + ERROR_INSUFFICIENT_BUFFER: + ReallocMem(Table, BufLen); + else + SetLastError(Ret); + IndyRaiseLastError; + end; + until False; + + if Ret = ERROR_SUCCESS then + begin + if Table^.dwNumEntries > 0 then + begin + pRow := @(Table^.table[0]); + for I := 0 to Table^.dwNumEntries-1 do begin + IndyAddPair(ASubNetMasks, + TranslateTInAddrToString(pRow^.dwAddr, Id_IPv4), + TranslateTInAddrToString(pRow^.dwMask, Id_IPv4)); + Inc(pRow); + end; + end; + end; + finally + FreeMem(Table); + end; + end; + + function GetLocalAddressesByAdaptersAddresses: Boolean; + var + Ret: DWORD; + BufLen: ULONG; + Adapter, Adapters: PIP_ADAPTER_ADDRESSES; + UnicastAddr: PIP_ADAPTER_UNICAST_ADDRESS; + IPAddr: string; + SubNetStr: String; + SubNetMasks: TStringList; + LAddress: TIdStackLocalAddress; + begin + // assume True unless ERROR_NOT_SUPPORTED is reported... + Result := True; + + // MSDN says: + // The recommended method of calling the GetAdaptersAddresses function is + // to pre-allocate a 15KB working buffer pointed to by the AdapterAddresses + // parameter. On typical computers, this dramatically reduces the chances + // that the GetAdaptersAddresses function returns ERROR_BUFFER_OVERFLOW, + // which would require calling GetAdaptersAddresses function multiple times. + + BufLen := 1024*15; + GetMem(Adapters, BufLen); + try + repeat + // TODO: include GAA_FLAG_INCLUDE_PREFIX on XPSP1+? + // TODO: include GAA_FLAG_INCLUDE_ALL_INTERFACES on Vista+? + Ret := GetAdaptersAddresses(PF_UNSPEC, GAA_FLAG_SKIP_ANYCAST or GAA_FLAG_SKIP_MULTICAST or GAA_FLAG_SKIP_DNS_SERVER, nil, Adapters, BufLen); + case Ret of + ERROR_SUCCESS: + begin + // Windows CE versions earlier than 4.1 may return ERROR_SUCCESS and + // BufLen=0 if no adapter info is available, instead of returning + // ERROR_NO_DATA as documented... + if BufLen = 0 then begin + Exit; + end; + Break; + end; + ERROR_NOT_SUPPORTED: + begin + Result := False; + Exit; + end; + ERROR_NO_DATA, + ERROR_ADDRESS_NOT_ASSOCIATED: + Exit; + ERROR_BUFFER_OVERFLOW: + ReallocMem(Adapters, BufLen); + else + SetLastError(Ret); + IndyRaiseLastError; + end; + until False; + + if Ret = ERROR_SUCCESS then + begin + SubNetMasks := nil; + try + AAddresses.BeginUpdate; + try + Adapter := Adapters; + repeat + if (Adapter.IfType <> IF_TYPE_SOFTWARE_LOOPBACK) and + ((Adapter.Flags and IP_ADAPTER_RECEIVE_ONLY) = 0) then + begin + UnicastAddr := Adapter^.FirstUnicastAddress; + while UnicastAddr <> nil do + begin + if UnicastAddr^.DadState = IpDadStatePreferred then + begin + LAddress := nil; + case UnicastAddr^.Address.lpSockaddr.sin_family of + AF_INET: begin + IPAddr := TranslateTInAddrToString(PSockAddrIn(UnicastAddr^.Address.lpSockaddr)^.sin_addr, Id_IPv4); + // TODO: use the UnicastAddr^.Length field to determine which version of + // IP_ADAPTER_UNICAST_ADDRESS is being provided, rather than checking the + // OS version number... + if IndyCheckWindowsVersion(6) then begin + // The OnLinkPrefixLength member is only available on Windows Vista and later + SubNetStr := IPv4MaskLengthToString(UnicastAddr^.OnLinkPrefixLength); + end else + begin + // TODO: on XP SP1+, can the subnet mask be determined + // by analyzing the Adapter's Prefix list without resorting + // to reading the Registry? + if SubNetMasks = nil then + begin + SubNetMasks := TStringList.Create; + GetIPv4SubNetMasks(SubNetMasks); + end; + SubNetStr := SubNetMasks.Values[IPAddr]; + end; + LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, IPAddr, SubNetStr); + {$I IdObjectChecksOff.inc} + TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := Adapter^.Union.IfIndex; + {$I IdObjectChecksOn.inc} + end; + AF_INET6: begin + LAddress := TIdStackLocalAddressIPv6.Create(AAddresses, + TranslateTInAddrToString(PSockAddrIn6(UnicastAddr^.Address.lpSockaddr)^.sin6_addr, Id_IPv6)); + // The Ipv6IfIndex member is only available on Windows XP SP1 and later + if IndyCheckWindowsVersion(5, 2) or (IndyCheckWindowsVersion(5, 1) {TODO: and SP1+}) then begin + {$I IdObjectChecksOff.inc} + TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := Adapter^.Ipv6IfIndex; + {$I IdObjectChecksOn.inc} + end; + end; + end; + if LAddress <> nil then begin + {$I IdObjectChecksOff.inc} + TIdStackLocalAddressAccess(LAddress).FDescription := String(Adapter^.Description); + TIdStackLocalAddressAccess(LAddress).FFriendlyName := String(Adapter^.FriendlyName); + TIdStackLocalAddressAccess(LAddress).FInterfaceName := String(Adapter^.AdapterName); + {$I IdObjectChecksOn.inc} + end; + end; + UnicastAddr := UnicastAddr^.Next; + end; + end; + Adapter := Adapter^.Next; + until Adapter = nil; + finally + AAddresses.EndUpdate; + end; + finally + SubNetMasks.Free; + end; + end; + finally + FreeMem(Adapters); + end; + end; + + procedure GetUniDirAddresseses(AUniDirAddresses: TStrings); + var + Ret: DWORD; + BufLen: ULONG; + Adapters: PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS; + pUniDirAddr: PInAddr; + I: ULONG; + begin + BufLen := 1024*15; + GetMem(Adapters, BufLen); + try + repeat + Ret := GetUniDirectionalAdapterInfo(Adapters, BufLen); + case Ret of + ERROR_SUCCESS: + begin + if BufLen = 0 then begin + Exit; + end; + Break; + end; + ERROR_NOT_SUPPORTED, + ERROR_NO_DATA: + Exit; + ERROR_MORE_DATA: + ReallocMem(Adapters, BufLen); + else + SetLastError(Ret); + IndyRaiseLastError; + end; + until False; + + if Ret = ERROR_SUCCESS then + begin + if Adapters^.NumAdapters > 0 then + begin + pUniDirAddr := @(Adapters^.Address[0]); + for I := 0 to Adapters^.NumAdapters-1 do begin + AUniDirAddresses.Add(TranslateTInAddrToString(pUniDirAddr^, Id_IPv4)); + Inc(pUniDirAddr); + end; + end; + end; + finally + FreeMem(Adapters); + end; + end; + + procedure GetLocalAddressesByAdaptersInfo; + var + Ret: DWORD; + BufLen: ULONG; + UniDirAddresses: TStringList; + Adapter, Adapters: PIP_ADAPTER_INFO; + IPAddr: PIP_ADDR_STRING; + IPStr, MaskStr: String; + LAddress: TIdStackLocalAddress; + begin + BufLen := 1024*15; + GetMem(Adapters, BufLen); + try + repeat + Ret := GetAdaptersInfo(Adapters, BufLen); + case Ret of + ERROR_SUCCESS: + begin + // Windows CE versions earlier than 4.1 may return ERROR_SUCCESS and + // BufLen=0 if no adapter info is available, instead of returning + // ERROR_NO_DATA as documented... + if BufLen = 0 then begin + Exit; + end; + Break; + end; + ERROR_NOT_SUPPORTED, + ERROR_NO_DATA: + Exit; + ERROR_BUFFER_OVERFLOW: + ReallocMem(Adapters, BufLen); + else + SetLastError(Ret); + IndyRaiseLastError; + end; + until False; + + if Ret = ERROR_SUCCESS then + begin + // on XP and later, GetAdaptersInfo() includes uni-directional adapters. + // Need to use GetUniDirectionalAdapterInfo() to filter them out of the + // list ... + + if IndyCheckWindowsVersion(5, 1) then begin + UniDirAddresses := TStringList.Create; + end else begin + UniDirAddresses := nil; + end; + try + if UniDirAddresses <> nil then begin + GetUniDirAddresseses(UniDirAddresses); + end; + AAddresses.BeginUpdate; + try + Adapter := Adapters; + repeat + IPAddr := @(Adapter^.IpAddressList); + repeat + {$IFDEF USE_MARSHALLED_PTRS} + IPStr := TMarshal.ReadStringAsAnsiUpTo(CP_ACP, TPtrWrapper.Create(@(IPAddr^.IpAddress.S[0]), 15); + {$ELSE} + IPStr := String(IPAddr^.IpAddress.S); + {$ENDIF} + if (IPStr <> '') and (IPStr <> '0.0.0.0') then + begin + if UniDirAddresses <> nil then begin + if UniDirAddresses.IndexOf(IPStr) <> -1 then begin + IPAddr := IPAddr^.Next; + Continue; + end; + end; + {$IFDEF USE_MARSHALLED_PTRS} + MaskStr := TMarshal.ReadStringAsAnsiUpTo(CP_ACP, TPtrWrapper.Create(@(IPAddr^.IpMask.S[0]), 15); + {$ELSE} + MaskStr := String(IPAddr^.IpMask.S); + {$ENDIF} + LAddress := TIdStackLocalAddressIPv4.Create(AAddresses, IPStr, MaskStr); + {$I IdObjectChecksOff.inc} + TIdStackLocalAddressAccess(LAddress).FDescription := String(Adapter^.Description); + TIdStackLocalAddressAccess(LAddress).FFriendlyName := String(Adapter^.AdapterName); + TIdStackLocalAddressAccess(LAddress).FInterfaceName := String(Adapter^.AdapterName); + TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := Adapter^.Index; + {$I IdObjectChecksOn.inc} + end; + IPAddr := IPAddr^.Next; + until IPAddr = nil; + Adapter := Adapter^.Next; + until Adapter = nil; + finally + AAddresses.EndUpdate; + end; + finally + UniDirAddresses.Free; + end; + end; + finally + FreeMem(Adapters); + end; + end; + + {$ELSE} + + procedure GetLocalAddressesByHostName; + var + {$IFDEF UNICODE} + Hints: TAddrInfoW; + LAddrList, LAddrInfo: pAddrInfoW; + {$ELSE} + Hints: TAddrInfo; + LAddrList, LAddrInfo: pAddrInfo; + {$ENDIF} + RetVal: Integer; + LHostName: String; + {$IFDEF STRING_UNICODE_MISMATCH} + LTemp: TIdPlatformString; + {$ENDIF} + //LAddress: TIdStackLocalAddress; + begin + LHostName := HostName; + + ZeroMemory(@Hints, SIZE_TADDRINFO); + Hints.ai_family := PF_UNSPEC; // returns both IPv4 and IPv6 addresses + Hints.ai_socktype := SOCK_STREAM; + LAddrList := nil; + + {$IFDEF STRING_UNICODE_MISMATCH} + LTemp := TIdPlatformString(LHostName); // explicit convert to Ansi/Unicode + {$ENDIF} + + RetVal := getaddrinfo( + {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(LHostName){$ENDIF}, + nil, @Hints, @LAddrList); + if RetVal <> 0 then begin + RaiseSocketError(gaiErrorToWsaError(RetVal)); + end; + try + AAddresses.BeginUpdate; + try + LAddrInfo := LAddrList; + repeat + //LAddress := nil; + case LAddrInfo^.ai_addr^.sa_family of + AF_INET: begin + {LAddress :=} TIdStackLocalAddressIPv4.Create(AAddresses, + TranslateTInAddrToString(PSockAddrIn(LAddrInfo^.ai_addr)^.sin_addr, Id_IPv4), + ''); // TODO: SubNet + end; + AF_INET6: begin + {LAddress :=} TIdStackLocalAddressIPv6.Create(AAddresses, + TranslateTInAddrToString(PSockAddrIn6(LAddrInfo^.ai_addr)^.sin6_addr, Id_IPv6)); + end; + end; + // TODO: implement this... + { + if LAddress <> nil then begin + ($I IdObjectChecksOff.inc) + TIdStackLocalAddressAccess(LAddress).FDescription := ?; + TIdStackLocalAddressAccess(LAddress).FFriendlyName := ?; + TIdStackLocalAddressAccess(LAddress).FInterfaceName := ?; + TIdStackLocalAddressAccess(LAddress).FInterfaceIndex := ?; + ($I IdObjectChecksOn.inc) + end; + } + LAddrInfo := LAddrInfo^.ai_next; + until LAddrInfo = nil; + finally + AAddresses.EndUpdate; + end; + finally + freeaddrinfo(LAddrList); + end; + end; + + {$ENDIF} +begin + // Using gethostname() and (gethostbyname|getaddrinfo)() may not always return + // just the machine's IP addresses. Technically speaking, they will return + // the local hostname, and then return the address(es) to which that hostname + // resolves. It is possible for a machine to (a) be configured such that its + // name does not resolve to an IP, or (b) be configured such that its name + // resolves to multiple IPs, only one of which belongs to the local machine. + // For better results, we should use the Win32 API GetAdaptersInfo() and/or + // GetAdaptersAddresses() functions instead. GetAdaptersInfo() only supports + // IPv4, but GetAdaptersAddresses() supports both IPv4 and IPv6... + + {$IFDEF USE_IPHLPAPI} + // try GetAdaptersAddresses() first, then fall back to GetAdaptersInfo()... + if not GetLocalAddressesByAdaptersAddresses then begin + GetLocalAddressesByAdaptersInfo; + end; + {$ELSE} + GetLocalAddressesByHostName; + {$ENDIF} +end; + +{ TIdStackVersionWinsock } + +function TIdStackWindows.WSShutdown(ASocket: TIdStackSocketHandle; AHow: Integer): Integer; +begin + Result := Shutdown(ASocket, AHow); +end; + +procedure TIdStackWindows.GetSocketName(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); +var + LSize: Integer; + LAddr: SOCKADDR_STORAGE; +begin + LSize := SizeOf(LAddr); + CheckForSocketError(getsockname(ASocket, IdWinsock2.PSOCKADDR(@LAddr), LSize)); + case LAddr.ss_family of + Id_PF_INET4: begin + VIP := TranslateTInAddrToString(PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); + VPort := ntohs(PSockAddrIn(@LAddr)^.sin_port); + VIPVersion := Id_IPv4; + end; + Id_PF_INET6: begin + VIP := TranslateTInAddrToString(PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); + VPort := Ntohs(PSockAddrIn6(@LAddr)^.sin6_port); + VIPVersion := Id_IPv6; + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +{ TIdSocketListWindows } + +type + // WARNING: If you are thinking of rewriting this to use WSAPoll() instead of select(), + // similar to TIdSocketListVCLPosix, then note that WSAPoll() is broken prior to + // Windows 10 version 2004! See: + // + // https://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/ + // https://stackoverflow.com/questions/21653003/is-this-wsapoll-bug-for-non-blocking-sockets-fixed + // + TIdSocketListWindows = class(TIdSocketList) + protected + FFDSet: TFDSet; + // + class function FDSelect(AReadSet: PFDSet; AWriteSet: PFDSet; AExceptSet: PFDSet; + const ATimeout: Integer = IdTimeoutInfinite): Boolean; + function GetItem(AIndex: Integer): TIdStackSocketHandle; override; + public + procedure Add(AHandle: TIdStackSocketHandle); override; + procedure Remove(AHandle: TIdStackSocketHandle); override; + function Count: Integer; override; + procedure Clear; override; + function Clone: TIdSocketList; override; + function ContainsSocket(AHandle: TIdStackSocketHandle): boolean; override; + procedure GetFDSet(var VSet: TFDSet); + procedure SetFDSet(var VSet: TFDSet); + class function Select(AReadList: TIdSocketList; AWriteList: TIdSocketList; + AExceptList: TIdSocketList; const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + function SelectRead(const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + function SelectReadList(var VSocketList: TIdSocketList; + const ATimeout: Integer = IdTimeoutInfinite): Boolean; override; + end; + +procedure TIdSocketListWindows.Add(AHandle: TIdStackSocketHandle); +begin + Lock; + try + // TODO: on Windows, the number of sockets that select() can query is limited only + // by available memory, unlike other platforms which are limited to querying sockets + // whose descriptors are less than FD_SETSIZE (1024). However, the Winsock SDK does + // define FD_SETSIZE for compatibilty with other platforms, but it is a meesely 64 + // by default, and the IdWinSock2 unit does use FD_SETSIZE in its definition of + // TFDSet. C/C++ programs can freely override the value of FD_SETSIZE at compile-time, + // but that is not an option for Pascal programs. So, we need to find a way to make + // this more dynamic/configurable. For instance, by having this class hold a dynamic + // byte array that is casted to PFDSet when needed... + if not fd_isset(AHandle, FFDSet) then begin + if FFDSet.fd_count >= u_int(Length(FFDSet.fd_array)){FD_SETSIZE} then begin + raise EIdStackSetSizeExceeded.Create(RSSetSizeExceeded); + end; + FFDSet.fd_array[FFDSet.fd_count] := AHandle; + Inc(FFDSet.fd_count); + end; + finally + Unlock; + end; +end; + +procedure TIdSocketListWindows.Clear; +begin + Lock; + try + fd_zero(FFDSet); + finally + Unlock; + end; +end; + +function TIdSocketListWindows.ContainsSocket(AHandle: TIdStackSocketHandle): Boolean; +begin + Lock; + try + Result := fd_isset(AHandle, FFDSet); + finally + Unlock; + end; +end; + +function TIdSocketListWindows.Count: Integer; +begin + Lock; + try + Result := FFDSet.fd_count; + finally + Unlock; + end; +end; + +function TIdSocketListWindows.GetItem(AIndex: Integer): TIdStackSocketHandle; +begin + // keep the compiler happy (when was this fixed exactly?) + {$IFDEF DCC}{$IFNDEF VCL_8_OR_ABOVE} + Result := INVALID_SOCKET; + {$ENDIF}{$ENDIF} + + Lock; + try + //We can't redefine AIndex to be a UInt32 because the libc Interface + //and DotNET define it as a LongInt. OS/2 defines it as a UInt16. + if (AIndex < 0) or (u_int(AIndex) >= FFDSet.fd_count) then begin + // TODO: just return 0/invalid, like most of the other Stack classes do? + raise EIdStackSetSizeExceeded.Create(RSSetSizeExceeded); + end; + Result := FFDSet.fd_array[AIndex]; + finally + Unlock; + end; +end; + +procedure TIdSocketListWindows.Remove(AHandle: TIdStackSocketHandle); +var + i: Integer; +begin + Lock; + try + { + IMPORTANT!!! + + Sometimes, there may not be a member of the FDSET. If you attempt to "remove" + an item, the loop would execute once. + } + if FFDSet.fd_count > 0 then + begin + for i:= 0 to FFDSet.fd_count - 1 do + begin + if FFDSet.fd_array[i] = AHandle then + begin + Dec(FFDSet.fd_count); + FFDSet.fd_array[i] := FFDSet.fd_array[FFDSet.fd_count]; + FFDSet.fd_array[FFDSet.fd_count] := 0; //extra purity + Break; + end;//if found + end; + end; + finally + Unlock; + end; +end; + +function TIdStackWindows.WSTranslateSocketErrorMsg(const AErr: Integer): string; +begin + if AErr = WSAHOST_NOT_FOUND then begin + Result := IndyFormat(RSStackError, [AErr, RSStackHOST_NOT_FOUND]); + end else begin + Result := inherited WSTranslateSocketErrorMsg(AErr); + end; +end; + +function TIdSocketListWindows.SelectRead(const ATimeout: Integer): Boolean; +var + LSet: TFDSet; +begin + // Windows updates this structure on return, so we need to copy it each time we need it + GetFDSet(LSet); + Result := FDSelect(@LSet, nil, nil, ATimeout); +end; + +class function TIdSocketListWindows.FDSelect(AReadSet, AWriteSet, + AExceptSet: PFDSet; const ATimeout: Integer): Boolean; +var + LResult: Integer; + LTime: TTimeVal; + LTimePtr: PTimeVal; +begin + if ATimeout = IdTimeoutInfinite then begin + LTimePtr := nil; + end else begin + LTime.tv_sec := ATimeout div 1000; + LTime.tv_usec := (ATimeout mod 1000) * 1000; + LTimePtr := @LTime; + end; + LResult := IdWinsock2.select(0, AReadSet, AWriteSet, AExceptSet, LTimePtr); + //TODO: Remove this cast + Result := GStack.CheckForSocketError(LResult) > 0; +end; + +function TIdSocketListWindows.SelectReadList(var VSocketList: TIdSocketList; + const ATimeout: Integer): Boolean; +var + LSet: TFDSet; +begin + // Windows updates this structure on return, so we need to copy it each time we need it + GetFDSet(LSet); + Result := FDSelect(@LSet, nil, nil, ATimeout); + if Result then + begin + if VSocketList = nil then begin + VSocketList := TIdSocketList.CreateSocketList; + end; + TIdSocketListWindows(VSocketList).SetFDSet(LSet); + end; +end; + +class function TIdSocketListWindows.Select(AReadList, AWriteList, + AExceptList: TIdSocketList; const ATimeout: Integer): Boolean; +var + LReadSet: TFDSet; + LWriteSet: TFDSet; + LExceptSet: TFDSet; + LPReadSet: PFDSet; + LPWriteSet: PFDSet; + LPExceptSet: PFDSet; + + procedure ReadSet(AList: TIdSocketList; var ASet: TFDSet; var APSet: PFDSet); + begin + if AList <> nil then begin + TIdSocketListWindows(AList).GetFDSet(ASet); + APSet := @ASet; + end else begin + APSet := nil; + end; + end; + +begin + ReadSet(AReadList, LReadSet, LPReadSet); + ReadSet(AWriteList, LWriteSet, LPWriteSet); + ReadSet(AExceptList, LExceptSet, LPExceptSet); + + Result := FDSelect(LPReadSet, LPWriteSet, LPExceptSet, ATimeout); + + if AReadList <> nil then begin + TIdSocketListWindows(AReadList).SetFDSet(LReadSet); + end; + if AWriteList <> nil then begin + TIdSocketListWindows(AWriteList).SetFDSet(LWriteSet); + end; + if AExceptList <> nil then begin + TIdSocketListWindows(AExceptList).SetFDSet(LExceptSet); + end; +end; + +procedure TIdSocketListWindows.SetFDSet(var VSet: TFDSet); +begin + Lock; + try + FFDSet := VSet; + finally + Unlock; + end; +end; + +procedure TIdSocketListWindows.GetFDSet(var VSet: TFDSet); +begin + Lock; + try + VSet := FFDSet; + finally + Unlock; + end; +end; + +procedure TIdStackWindows.SetBlocking(ASocket: TIdStackSocketHandle; + const ABlocking: Boolean); +var + LValue: UInt32; +begin + LValue := UInt32(not ABlocking); + CheckForSocketError(ioctlsocket(ASocket, FIONBIO, LValue)); +end; + +function TIdSocketListWindows.Clone: TIdSocketList; +begin + Result := TIdSocketListWindows.Create; + try + Lock; + try + TIdSocketListWindows(Result).SetFDSet(FFDSet); + finally + Unlock; + end; + except + FreeAndNil(Result); + raise; + end; +end; + +function TIdStackWindows.WouldBlock(const AResult: Integer): Boolean; +begin + Result := (AResult = WSAEWOULDBLOCK); +end; + +function TIdStackWindows.HostByName(const AHostName: string; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION): string; +var + {$IFDEF UNICODE} + LAddrInfo: pAddrInfoW; + Hints: TAddrInfoW; + {$ELSE} + LAddrInfo: pAddrInfo; + Hints: TAddrInfo; + {$ENDIF} + RetVal: Integer; + LHostName: String; + {$IFDEF STRING_UNICODE_MISMATCH} + LTemp: TIdPlatformString; + {$ENDIF} +begin + if not (AIPVersion in [Id_IPv4, Id_IPv6]) then begin + IPVersionUnsupported; + end; + + ZeroMemory(@Hints, SIZE_TADDRINFO); + Hints.ai_family := IdIPFamily[AIPVersion]; + Hints.ai_socktype := SOCK_STREAM; + LAddrInfo := nil; + + if UseIDNAPI then begin + LHostName := IDNToPunnyCode( + {$IFDEF STRING_IS_UNICODE} + AHostName + {$ELSE} + TIdUnicodeString(AHostName) // explicit convert to Unicode + {$ENDIF} + ); + end else begin + LHostName := AHostName; + end; + + {$IFDEF STRING_UNICODE_MISMATCH} + LTemp := TIdPlatformString(LHostName); // explicit convert to Ansi/Unicode + {$ENDIF} + + RetVal := getaddrinfo( + {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(LHostName){$ENDIF}, + nil, @Hints, @LAddrInfo); + if RetVal <> 0 then begin + RaiseSocketError(gaiErrorToWsaError(RetVal)); + end; + try + if AIPVersion = Id_IPv4 then begin + Result := TranslateTInAddrToString(PSockAddrIn(LAddrInfo^.ai_addr)^.sin_addr, Id_IPv4) + end else begin + Result := TranslateTInAddrToString(PSockAddrIn6(LAddrInfo^.ai_addr)^.sin6_addr, Id_IPv6); + end; + finally + freeaddrinfo(LAddrInfo); + end; +end; + +procedure TIdStackWindows.Connect(const ASocket: TIdStackSocketHandle; + const AIP: string; const APort: TIdPort; + const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); +var + LAddr: SOCKADDR_STORAGE; + LSize: Integer; +begin + FillChar(LAddr, SizeOf(LAddr), 0); + case AIPVersion of + Id_IPv4: begin + PSockAddrIn(@LAddr)^.sin_family := Id_PF_INET4; + TranslateStringToTInAddr(AIP, PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); + PSockAddrIn(@LAddr)^.sin_port := htons(APort); + LSize := SIZE_TSOCKADDRIN; + end; + Id_IPv6: begin + PSockAddrIn6(@LAddr)^.sin6_family := Id_PF_INET6; + TranslateStringToTInAddr(AIP, PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); + PSockAddrIn6(@LAddr)^.sin6_port := htons(APort); + LSize := SIZE_TSOCKADDRIN6; + end; + else begin + LSize := 0; // avoid warning + IPVersionUnsupported; + end; + end; + CheckForSocketError(IdWinsock2.connect(ASocket, IdWinsock2.PSOCKADDR(@LAddr), LSize)); +end; + +procedure TIdStackWindows.GetPeerName(ASocket: TIdStackSocketHandle; + var VIP: string; var VPort: TIdPort; var VIPVersion: TIdIPVersion); +var + LSize: Integer; + LAddr: SOCKADDR_STORAGE; +begin + LSize := SizeOf(LAddr); + CheckForSocketError(IdWinsock2.getpeername(ASocket, IdWinsock2.PSOCKADDR(@LAddr), LSize)); + case LAddr.ss_family of + Id_PF_INET4: begin + VIP := TranslateTInAddrToString(PSockAddrIn(@LAddr)^.sin_addr, Id_IPv4); + VPort := ntohs(PSockAddrIn(@LAddr)^.sin_port); + VIPVersion := Id_IPv4; + end; + Id_PF_INET6: begin + VIP := TranslateTInAddrToString(PSockAddrIn6(@LAddr)^.sin6_addr, Id_IPv6); + VPort := ntohs(PSockAddrIn6(@LAddr)^.sin6_port); + VIPVersion := Id_IPv6; + end; + else begin + IPVersionUnsupported; + end; + end; +end; + +procedure TIdStackWindows.Disconnect(ASocket: TIdStackSocketHandle); +begin + // Windows uses Id_SD_Send, Linux should use Id_SD_Both + // RLebeau: why Id_SD_Send and not Id_SD_Both on Windows? What if a blocking read is in progress? + WSShutdown(ASocket, Id_SD_Send); + // SO_LINGER is false - socket may take a little while to actually close after this + WSCloseSocket(ASocket); +end; + +procedure TIdStackWindows.{$IFDEF VCL_XE3_OR_ABOVE}GetSocketOption{$ELSE}WSGetSocketOption{$ENDIF} + (ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; + var AOptVal; var AOptLen: Integer); +begin + CheckForSocketError( + getsockopt(ASocket, ALevel, AOptName, + {$IFNDEF HAS_PAnsiChar} + // TODO: use TPtrWrapper here? + {PIdAnsiChar}@AOptVal + {$ELSE} + PIdAnsiChar(@AOptVal) + {$ENDIF}, + AOptLen + ) + ); +end; + +procedure TIdStackWindows.{$IFDEF VCL_XE3_OR_ABOVE}SetSocketOption{$ELSE}WSSetSocketOption{$ENDIF} + (ASocket: TIdStackSocketHandle; ALevel: TIdSocketOptionLevel; AOptName: TIdSocketOption; + const AOptVal; const AOptLen: Integer); +begin + CheckForSocketError( + setsockopt(ASocket, ALevel, Aoptname, + {$IFNDEF HAS_PAnsiChar} + // TODO: use TPtrWrapper here? + {PIdAnsiChar}@AOptVal + {$ELSE} + PIdAnsiChar(@AOptVal) + {$ENDIF}, + AOptLen + ) + ); +end; + +function TIdStackWindows.SupportsIPv4: Boolean; +var + LLen : DWORD; + LPInfo, LPCurPtr: LPWSAPROTOCOL_INFO; + LCount : Integer; + i : Integer; +begin + // TODO: move this logic into CheckIPVersionSupport() instead... + // Result := CheckIPVersionSupport(Id_IPv4); + + Result := False; + LPInfo := nil; + try + LLen := 0; + // Note: WSAEnumProtocols returns -1 when it is just called to get the needed Buffer Size! + repeat + LCount := IdWinsock2.WSAEnumProtocols(nil, LPInfo, LLen); + if LCount = SOCKET_ERROR then + begin + if WSAGetLastError() <> WSAENOBUFS then begin + Exit; + end; + ReallocMem(LPInfo, LLen); + end else begin + Break; + end; + until False; + + if LCount > 0 then + begin + LPCurPtr := LPInfo; + for i := 0 to LCount-1 do + begin + if LPCurPtr^.iAddressFamily = AF_INET then + begin + Result := True; + Exit; + end; + Inc(LPCurPtr); + end; + end; + finally + FreeMem(LPInfo); + end; +end; + +{ +based on +http://groups.google.com/groups?q=Winsock2+Delphi+protocol&hl=en&lr=&ie=UTF-8&oe=utf-8&selm=3cebe697_2%40dnews&rnum=9 +} +function TIdStackWindows.SupportsIPv6: Boolean; +var + LLen : DWORD; + LPInfo, LPCurPtr: LPWSAPROTOCOL_INFO; + LCount : Integer; + i : Integer; +begin + // TODO: move this logic into CheckIPVersionSupport() instead... + // Result := CheckIPVersionSupport(Id_IPv6); + + Result := False; + LPInfo := nil; + try + LLen := 0; + // Note: WSAEnumProtocols returns -1 when it is just called to get the needed Buffer Size! + repeat + LCount := IdWinsock2.WSAEnumProtocols(nil, LPInfo, LLen); + if LCount = SOCKET_ERROR then + begin + if WSAGetLastError() <> WSAENOBUFS then begin + Exit; + end; + ReallocMem(LPInfo, LLen); + end else begin + Break; + end; + until False; + + if LCount > 0 then + begin + LPCurPtr := LPInfo; + for i := 0 to LCount-1 do + begin + if LPCurPtr^.iAddressFamily = AF_INET6 then + begin + Result := True; + Exit; + end; + Inc(LPCurPtr); + end; + end; + finally + FreeMem(LPInfo); + end; +end; + +function TIdStackWindows.IOControl(const s: TIdStackSocketHandle; + const cmd: UInt32; var arg: UInt32): Integer; +begin + Result := IdWinsock2.ioctlsocket(s, cmd, arg); +end; + +procedure TIdStackWindows.WSQuerryIPv6Route(ASocket: TIdStackSocketHandle; + const AIP: String; const APort: TIdPort; var VSource; var VDest); +var + Llocalif : TSockAddrIn6; + LAddr : TSockAddrIn6; + Bytes : DWORD; +begin + //make our LAddrInfo structure + FillChar(LAddr, SizeOf(LAddr), 0); + LAddr.sin6_family := AF_INET6; + TranslateStringToTInAddr(AIP, LAddr.sin6_addr, Id_IPv6); + Move(LAddr.sin6_addr, VDest, SizeOf(in6_addr)); + LAddr.sin6_port := htons(APort); + // Find out which local interface for the destination + // RLebeau: in XE4+, PDWORD is NOT defined as ^DWORD, so we have to use a type-cast! + CheckForSocketError(WSAIoctl(ASocket, SIO_ROUTING_INTERFACE_QUERY, + @LAddr, SizeOf(LAddr), @Llocalif, SizeOf(Llocalif), PDWORD(@Bytes), nil, nil)); + Move(Llocalif.sin6_addr, VSource, SizeOf(in6_addr)); +end; + +procedure TIdStackWindows.WriteChecksum(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort; const AIPVersion: TIdIPVersion); +begin + case AIPVersion of + Id_IPv4 : CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(VBuffer)), VBuffer, AOffset); + Id_IPv6 : WriteChecksumIPv6(s, VBuffer, AOffset, AIP, APort); + else + IPVersionUnsupported; + end; +end; + +procedure TIdStackWindows.WriteChecksumIPv6(s: TIdStackSocketHandle; + var VBuffer: TIdBytes; const AOffset: Integer; const AIP: String; + const APort: TIdPort); +var + LSource : TIdIn6Addr; + LDest : TIdIn6Addr; + LTmp : TIdBytes; + LIdx : Integer; + LC : UInt32; +{ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + + + | | + + Source Address + + | | + + + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + + + + | | + + Destination Address + + | | + + + + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Upper-Layer Packet Length | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | zero | Next Header | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +} +begin + WSQuerryIPv6Route(s, AIP, APort, LSource, LDest); + SetLength(LTmp, 40+Length(VBuffer)); + + //16 + Move(LSource, LTmp[0], SIZE_TIN6ADDR); + LIdx := SIZE_TIN6ADDR; + //32 + Move(LDest, LTmp[LIdx], SIZE_TIN6ADDR); + Inc(LIdx, SIZE_TIN6ADDR); + //use a word so you don't wind up using the wrong network byte order function + LC := UInt32(Length(VBuffer)); + CopyTIdUInt32(HostToNetwork(LC), LTmp, LIdx); + Inc(LIdx, 4); + //36 + //zero the next three bytes + FillChar(LTmp[LIdx], 3, 0); + Inc(LIdx, 3); + //next header (protocol type determines it + LTmp[LIdx] := Id_IPPROTO_ICMPV6; // Id_IPPROTO_ICMP6; + Inc(LIdx); + //combine the two + CopyTIdBytes(VBuffer, 0, LTmp, LIdx, Length(VBuffer)); + //zero out the checksum field + CopyTIdUInt16(0, LTmp, LIdx+AOffset); + + CopyTIdUInt16(HostToLittleEndian(CalcCheckSum(LTmp)), VBuffer, AOffset); +end; + +function TIdStackWindows.ReceiveMsg(ASocket: TIdStackSocketHandle; var VBuffer : TIdBytes; + APkt: TIdPacketInfo): UInt32; +var + LIP : String; + LPort : TIdPort; + LIPVersion : TIdIPVersion; + {Windows CE does not have WSARecvMsg} + {$IFNDEF WINCE} + LSize: PtrUInt; + LAddr: TIdBytes; + PAddr: PSOCKADDR_STORAGE; + LMsg : TWSAMSG; + LMsgBuf : TWSABUF; + LControl : TIdBytes; + LCurCmsg : LPWSACMSGHDR; //for iterating through the control buffer + PPktInfo: PInPktInfo; + PPktInfo6: PIn6PktInfo; + {$ENDIF} +begin + {$IFNDEF WINCE} + //This runs only on WIndows XP or later + // XP 5.1 at least, Vista 6.0 + if IndyCheckWindowsVersion(5, 1) then + begin + //we call the macro twice because we specified two possible structures. + //Id_IPV6_HOPLIMIT and Id_IPV6_PKTINFO + LSize := WSA_CMSG_SPACE(SizeOf(Byte)) + WSA_CMSG_SPACE(SizeOf(IN6_PKTINFO)); + SetLength(LControl, LSize); + + LMsgBuf.len := Length(VBuffer); // Length(VMsgData); + LMsgBuf.buf := PIdAnsiChar(Pointer(VBuffer)); // @VMsgData[0]; + + FillChar(LMsg, SIZE_TWSAMSG, 0); + + LMsg.lpBuffers := @LMsgBuf; + LMsg.dwBufferCount := 1; + + LMsg.Control.Len := LSize; + LMsg.Control.buf := PIdAnsiChar(Pointer(LControl)); + + // RLebeau: despite that we are not performing an overlapped I/O operation, + // WSARecvMsg() does not like the SOCKADDR variable being allocated on the + // stack, at least on my tests with Windows 7. So we will allocate it on + // the heap instead to keep WinSock happy... + SetLength(LAddr, SizeOf(SOCKADDR_STORAGE)); + PAddr := PSOCKADDR_STORAGE(@LAddr[0]); + + LMsg.name := IdWinsock2.PSOCKADDR(PAddr); + LMsg.namelen := Length(LAddr); + + CheckForSocketError(WSARecvMsg(ASocket, @LMsg, Result, nil, nil)); + APkt.Reset; + + case PAddr^.ss_family of + Id_PF_INET4: begin + APkt.SourceIP := TranslateTInAddrToString(PSockAddrIn(PAddr)^.sin_addr, Id_IPv4); + APkt.SourcePort := ntohs(PSockAddrIn(PAddr)^.sin_port); + APkt.SourceIPVersion := Id_IPv4; + end; + Id_PF_INET6: begin + APkt.SourceIP := TranslateTInAddrToString(PSockAddrIn6(PAddr)^.sin6_addr, Id_IPv6); + APkt.SourcePort := ntohs(PSockAddrIn6(PAddr)^.sin6_port); + APkt.SourceIPVersion := Id_IPv6; + end; + else begin + Result := 0; // avoid warning + IPVersionUnsupported; + end; + end; + + LCurCmsg := nil; + repeat + LCurCmsg := WSA_CMSG_NXTHDR(@LMsg, LCurCmsg); + if LCurCmsg = nil then begin + Break; + end; + case LCurCmsg^.cmsg_type of + IP_PKTINFO : //done this way because IPV6_PKTINF and IP_PKTINFO are both 19 + begin + case PAddr^.ss_family of + Id_PF_INET4: begin + PPktInfo := PInPktInfo(WSA_CMSG_DATA(LCurCmsg)); + APkt.DestIP := TranslateTInAddrToString(PPktInfo^.ipi_addr, Id_IPv4); + APkt.DestIF := PPktInfo^.ipi_ifindex; + APkt.DestIPVersion := Id_IPv4; + end; + Id_PF_INET6: begin + PPktInfo6 := PIn6PktInfo(WSA_CMSG_DATA(LCurCmsg)); + APkt.DestIP := TranslateTInAddrToString(PPktInfo6^.ipi6_addr, Id_IPv6); + APkt.DestIF := PPktInfo6^.ipi6_ifindex; + APkt.DestIPVersion := Id_IPv6; + end; + end; + end; + Id_IPV6_HOPLIMIT : + begin + APkt.TTL := WSA_CMSG_DATA(LCurCmsg)^; + end; + end; + until False; + end else + begin + {$ENDIF} + Result := RecvFrom(ASocket, VBuffer, Length(VBuffer), 0, LIP, LPort, LIPVersion); + APkt.Reset; + APkt.SourceIP := LIP; + APkt.SourcePort := LPort; + APkt.SourceIPVersion := LIPVersion; + APkt.DestIPVersion := LIPVersion; + {$IFNDEF WINCE} + end; + {$ENDIF} +end; + +function TIdStackWindows.CheckIPVersionSupport(const AIPVersion: TIdIPVersion): Boolean; +var + LTmpSocket: TIdStackSocketHandle; +begin + LTmpSocket := WSSocket(IdIPFamily[AIPVersion], Id_SOCK_STREAM, Id_IPPROTO_IP); + Result := LTmpSocket <> Id_INVALID_SOCKET; + if Result then begin + WSCloseSocket(LTmpSocket); + end; +end; + +{$IFNDEF WINCE} +{ +This is somewhat messy but I wanted to do things this way to support Int64 +file sizes. +} +function ServeFile(ASocket: TIdStackSocketHandle; const AFileName: string): Int64; +var + LFileHandle: THandle; + LSize: LARGE_INTEGER; + {$IFDEF STRING_UNICODE_MISMATCH} + LTemp: TIdPlatformString; + {$ENDIF} +begin + Result := 0; + + {$IFDEF STRING_UNICODE_MISMATCH} + LTemp := TIdPlatformString(AFileName); // explicit convert to Ansi/Unicode + {$ENDIF} + + LFileHandle := CreateFile( + {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(AFileName){$ENDIF}, + GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0); + + if LFileHandle <> INVALID_HANDLE_VALUE then + begin + try + if TransmitFile(ASocket, LFileHandle, 0, 0, nil, nil, 0) then + begin + if Assigned(GetFileSizeEx) then + begin + if not GetFileSizeEx(LFileHandle, LSize) then begin + Exit; + end; + end else + begin + LSize.LowPart := GetFileSize(LFileHandle, @LSize.HighPart); + if (LSize.LowPart = $FFFFFFFF) and (GetLastError() <> 0) then begin + Exit; + end; + end; + Result := LSize.QuadPart; + end; + finally + CloseHandle(LFileHandle); + end; + end; +end; +{$ENDIF} + +procedure TIdStackWindows.SetKeepAliveValues(ASocket: TIdStackSocketHandle; + const AEnabled: Boolean; const ATimeMS, AInterval: Integer); +var + ka: _tcp_keepalive; + Bytes: DWORD; +begin + // TODO: instead of doing an OS version check, always call SIO_KEEPALIVE_VALS + // when AEnabled is True, and then fallback to SO_KEEPALIVE if WSAIoctl() + // reports that SIO_KEEPALIVE_VALS is not supported... + + // SIO_KEEPALIVE_VALS is supported on Win2K+ and WinCE 4.x only + if AEnabled and IndyCheckWindowsVersion({$IFDEF WINCE}4{$ELSE}5{$ENDIF}) then + begin + ka.onoff := 1; + ka.keepalivetime := ATimeMS; + ka.keepaliveinterval := AInterval; + // RLebeau: in XE4+, PDWORD is NOT defined as ^DWORD, so we have to use a type-cast! + WSAIoctl(ASocket, SIO_KEEPALIVE_VALS, @ka, SizeOf(ka), nil, 0, PDWORD(@Bytes), nil, nil); + end else begin + SetSocketOption(ASocket, Id_SOL_SOCKET, Id_SO_KEEPALIVE, iif(AEnabled, 1, 0)); + end; +end; + +initialization + GStarted := False; + GSocketListClass := TIdSocketListWindows; + // Check if we are running under windows NT + {$IFNDEF WINCE} + if IndyWindowsPlatform = VER_PLATFORM_WIN32_NT then begin + GetFileSizeEx := LoadLibFunction(GetModuleHandle('Kernel32.dll'), 'GetFileSizeEx'); + GServeFileProc := ServeFile; + end; + {$ENDIF} + {$IFDEF USE_IPHLPAPI} + InitializeIPHelperStubs; + {$ENDIF} +finalization + IdWship6.CloseLibrary; + UninitializeWinSock; + {$IFDEF USE_IPHLPAPI} + UninitializeIPHelperAPI; + {$ENDIF} + GStarted := False; + +end. diff --git a/Lib/System/IdSystem90ASM90.inc b/Lib/System/IdSystem90ASM90.inc index 27a70b095..e8d2c3940 100644 --- a/Lib/System/IdSystem90ASM90.inc +++ b/Lib/System/IdSystem90ASM90.inc @@ -1,12 +1,12 @@ -[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 System Run-Time Package for Borland Developer Studio')] -[assembly: AssemblyConfiguration('')] -[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] -[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] -[assembly: AssemblyTrademark('')] -[assembly: AssemblyCulture('')] -[assembly: AssemblyTitle('Indy .NET System Run-Time Package')] -[assembly: AssemblyVersion('10.7.0.*')] -[assembly: AssemblyDelaySign(false)] -[assembly: AssemblyKeyFile('')] -[assembly: AssemblyKeyName('')] +[assembly: AssemblyDescription('Internet Direct (Indy) 10.7.0 System Run-Time Package for Borland Developer Studio')] +[assembly: AssemblyConfiguration('')] +[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')] +[assembly: AssemblyCopyright('Copyright © 1993 - 2024 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')] +[assembly: AssemblyTrademark('')] +[assembly: AssemblyCulture('')] +[assembly: AssemblyTitle('Indy .NET System Run-Time Package')] +[assembly: AssemblyVersion('10.7.0.*')] +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile('')] +[assembly: AssemblyKeyName('')] diff --git a/Lib/System/IdTransactedFileStream.pas b/Lib/System/IdTransactedFileStream.pas index 456f6233d..5038e7abc 100644 --- a/Lib/System/IdTransactedFileStream.pas +++ b/Lib/System/IdTransactedFileStream.pas @@ -1,362 +1,362 @@ -unit IdTransactedFileStream; -interface -{$I IdCompilerDefines.inc} - -{ -Original author: Grahame Grieve - -His notes are: - -If you want transactional file handling, with commit and rollback, -then this is the unit for you. It provides transactional safety on -Vista, win7, and windows server 2008, and just falls through to -normal file handling on earlier versions of windows. - -There's a couple of issues with the wrapper classes TKernelTransaction -and TIdTransactedFileStream: -- you can specify how you want file reading to work with a transactional - isolation. I don't surface this. - - - you can elevate the transactions to coordinate with DTC. They don't - do this (for instance, you could put your file handling in the same - transaction as an SQLServer transaction). I haven't done this - but if - you do this, I'd love a copy ;-) - -you use it like this: - -procedure StringToFile(const AStr, AFilename: String); -var - oFileStream: TIdTransactedFileStream; - oTransaction : TKernelTransaction; -begin - oTransaction := TIdKernelTransaction.Create('Save Content to file '+aFilename, false); - Try - Try - oFileStream := TIdTransactedFileStream.Create(AFilename, fmCreate); - try - if Length(AStr) > 0 then - WriteStringToStream(LFileStream, AStr, IndyTextEncoding_8Bit); - finally - LFileStream.Free; - end; - oTransaction.Commit; - Except - oTransaction.Rollback; - raise; - End; - Finally - oTransaction.Free; - End; -end; - -anyway - maybe useful in temporary file handling with file and email? I've -been burnt with temporary files and server crashes before. - -} -uses - {$IFDEF WIN32_OR_WIN64} - Windows, - Consts, - {$ENDIF} - Classes, SysUtils, IdGlobal; - - {$IFDEF WIN32_OR_WIN64} -const - TRANSACTION_DO_NOT_PROMOTE = 1; - - TXFS_MINIVERSION_COMMITTED_VIEW : Word = $0000; // The view of the file as of its last commit. - TXFS_MINIVERSION_DIRTY_VIEW : Word = $FFFE; // The view of the file as it is being modified by the transaction. - TXFS_MINIVERSION_DEFAULT_VIEW : Word = $FFFF; // Either the committed or dirty view of the file, depending on the context. - // A transaction that is modifying the file gets the dirty view, while a transaction - // that is not modifying the file gets the committed view. - -// remember to close the transaction handle. Use the CloseTransaction function here to avoid problems if the transactions are not available -type - TktmCreateTransaction = function (lpSecurityAttributes: PSecurityAttributes; - pUow : Pointer; - CreateOptions, IsolationLevel, IsolationFlags, Timeout : DWORD; - Description : PWideChar) : THandle; stdcall; - TktmCreateFileTransacted = function (lpFileName: PChar; - dwDesiredAccess, dwShareMode: DWORD; - lpSecurityAttributes: PSecurityAttributes; - dwCreationDisposition, dwFlagsAndAttributes: DWORD; - hTemplateFile: THandle; - hTransaction : THandle; - MiniVersion : Word; - pExtendedParameter : Pointer): THandle; stdcall; - TktmCommitTransaction = function (hTransaction : THandle) : Boolean; stdcall; - TktmRollbackTransaction = function (hTransaction : THandle) : - Boolean; stdcall; - TktmCloseTransaction = function (hTransaction : THandle) : Boolean; stdcall; - -var - CreateTransaction : TktmCreateTransaction; - CreateFileTransacted : TktmCreateFileTransacted; - CommitTransaction : TktmCommitTransaction; - RollbackTransaction : TktmRollbackTransaction; - CloseTransaction : TktmCloseTransaction; - - {$ENDIF} - -Function IsTransactionsWorking : Boolean; - -type - TIdKernelTransaction = class (TObject) - protected - FHandle : THandle; - public - constructor Create(Const sDescription : String; bCanPromote : Boolean = false); - destructor Destroy; override; - - function IsTransactional : Boolean; - procedure Commit; - procedure RollBack; - end; - - TIdTransactedFileStream = class(THandleStream) - {$IFNDEF WIN32_OR_WIN64} - protected - FFileStream : TFileStream; - {$ENDIF} - public - constructor Create(const FileName: string; Mode: Word; oTransaction : TIdKernelTransaction); - destructor Destroy; override; - end; - -implementation -uses RTLConsts; - - {$IFDEF WIN32_OR_WIN64} - -var - GHandleKtm : HModule; - GHandleKernel : HModule; - -function DummyCreateTransaction(lpSecurityAttributes: PSecurityAttributes; - pUow : Pointer; CreateOptions, IsolationLevel, - IsolationFlags, Timeout : DWORD; - Description : PWideChar) : THandle; stdcall; -begin - result := 1; -end; - -function DummyCreateFileTransacted(lpFileName: PChar; - dwDesiredAccess, dwShareMode: DWORD; - lpSecurityAttributes: PSecurityAttributes; - dwCreationDisposition, dwFlagsAndAttributes: DWORD; - hTemplateFile: THandle; - hTransaction : THandle; - MiniVersion : Word; - pExtendedParameter : Pointer): THandle; stdcall; -begin - result := CreateFile(lpFilename, dwDesiredAccess, dwShareMode, - lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, - hTemplateFile); -end; - -function DummyCommitTransaction(hTransaction : THandle) : Boolean; stdcall; -begin - assert(hTransaction = 1); - result := true; -end; - -function DummyRollbackTransaction(hTransaction : THandle) : Boolean; stdcall; -begin - assert(hTransaction = 1); - result := true; -end; - -function DummyCloseTransaction(hTransaction : THandle) : Boolean; stdcall; -begin - assert(hTransaction = 1); - result := true; -end; - -procedure LoadDll; -begin - GHandleKtm := LoadLibrary('ktmw32.dll'); - if GHandleKtm <> 0 Then begin - GHandleKernel := GetModuleHandle('Kernel32.dll'); //LoadLibrary('kernel32.dll'); - @CreateTransaction := LoadLibFunction(GHandleKtm, 'CreateTransaction'); - @CommitTransaction := LoadLibFunction(GHandleKtm, 'CommitTransaction'); - @RollbackTransaction := LoadLibFunction(GHandleKtm, 'RollbackTransaction'); - @CloseTransaction := LoadLibFunction(GHandleKernel, 'CloseHandle'); - {$IFDEF UNICODE} - @CreateFileTransacted := LoadLibFunction(GHandleKernel, 'CreateFileTransactedW'); - {$ELSE} - @CreateFileTransacted := LoadLibFunction(GHandleKernel, 'CreateFileTransactedA'); - {$ENDIF} - end else begin - @CreateTransaction := @DummyCreateTransaction; - @CommitTransaction := @DummyCommitTransaction; - @RollbackTransaction := @DummyRollbackTransaction; - @CloseTransaction := @DummyCloseTransaction; - @CreateFileTransacted := @DummyCreateFileTransacted; - end; -end; - -procedure UnloadDll; -begin - if GHandleKtm <> 0 then begin - freelibrary(GHandleKtm); - // freelibrary(GHandleKernel); - end -end; - -function IsTransactionsWorking : Boolean; -{$IFDEF USE_INLINE} inline; {$ENDIF} -begin - result := GHandleKtm <> 0; -end; - -{$ELSE} - -function IsTransactionsWorking : Boolean; -{$IFDEF USE_INLINE} inline; {$ENDIF} -begin - result := False; -end; -{$ENDIF} - -{ TIdKernelTransaction } - -constructor TIdKernelTransaction.Create(const sDescription: String; bCanPromote : Boolean); -var - pDesc : PWideChar; -begin - inherited Create; - {$IFDEF UNICODE} - GetMem(pDesc, length(sDescription) + 2); - try - StringToWideChar(sDescription, pDesc, length(sDescription) + 2); - {$ELSE} - GetMem(pDesc, length(sDescription) * 2 + 4); - try - StringToWideChar(sDescription, pDesc, length(sDescription) * 2 + 4); - {$ENDIF} - {$IFDEF WIN32_OR_WIN64} - if bCanPromote Then begin - FHandle := CreateTransaction(nil, nil, 0, 0, 0, 0, pDesc); - end else begin - FHandle := CreateTransaction(nil, nil, TRANSACTION_DO_NOT_PROMOTE, 0, 0, 0, pDesc); - end; - {$ENDIF} - finally - FreeMem(pDesc); - end; -end; - -destructor TIdKernelTransaction.Destroy; -begin - {$IFDEF WIN32_OR_WIN64} - CloseTransaction(FHandle); - {$ENDIF} - inherited Destroy; -end; - -procedure TIdKernelTransaction.Commit; -begin - {$IFDEF WIN32_OR_WIN64} - if not CommitTransaction(FHandle) then begin - IndyRaiseLastError; - end; - {$ENDIF} -end; - -function TIdKernelTransaction.IsTransactional: Boolean; -begin - result := IsTransactionsWorking; -end; - -procedure TIdKernelTransaction.RollBack; -begin - {$IFDEF WIN32_OR_WIN64} - if not RollbackTransaction(FHandle) then begin - IndyRaiseLastError; - end; - {$ENDIF} -end; - - {$IFDEF WIN32_OR_WIN64} -function FileCreateTransacted(const FileName: string; hTransaction : THandle): THandle; -begin - Result := THandle(CreateFileTransacted(PChar(FileName), GENERIC_READ or GENERIC_WRITE, - 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0, hTransaction, 0, nil)); - if result = INVALID_HANDLE_VALUE Then begin - IndyRaiseLastError; - end; -end; - -function FileOpenTransacted(const FileName: string; Mode: LongWord; hTransaction : THandle): THandle; -const - AccessMode: array[0..2] of LongWord = ( - GENERIC_READ, - GENERIC_WRITE, - GENERIC_READ or GENERIC_WRITE); - ShareMode: array[0..4] of LongWord = ( - 0, - 0, - FILE_SHARE_READ, - FILE_SHARE_WRITE, - FILE_SHARE_READ or FILE_SHARE_WRITE); -begin - Result := THandle(CreateFileTransacted(PChar(FileName),AccessMode[Mode and 3], - ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, 0, hTransaction,TXFS_MINIVERSION_DEFAULT_VIEW, nil)); -end; - {$ENDIF} - -{ TIdTransactedFileStream } - - {$IFDEF WIN32_OR_WIN64} -constructor TIdTransactedFileStream.Create(const FileName: string; Mode: Word; oTransaction: TIdKernelTransaction); -var - aHandle : THandle; -begin - if Mode = fmCreate then begin - aHandle := FileCreateTransacted(FileName, oTransaction.FHandle); - if aHandle = INVALID_HANDLE_VALUE then begin - raise EFCreateError.CreateResFmt(@SFCreateError, [FileName]); - end; - end else begin - aHandle := FileOpenTransacted(FileName, Mode, oTransaction.FHandle); - if aHandle = INVALID_HANDLE_VALUE then begin - raise EFOpenError.CreateResFmt(@SFOpenError, [FileName]); - end; - end; - inherited Create(ahandle); -end; -{$ELSE} -constructor TIdTransactedFileStream.Create(const FileName: string; Mode: Word; oTransaction: TIdKernelTransaction); -var LStream : TFileStream; -begin - LStream := FFileStream.Create(FileName,Mode); - inherited Create ( LStream.Handle); - FFileStream := LStream; -end; -{$ENDIF} - -destructor TIdTransactedFileStream.Destroy ; -begin - {$IFDEF WIN32_OR_WIN64} - if Handle = INVALID_HANDLE_VALUE then begin - FileClose(Handle); - end; - inherited Destroy; - {$ELSE} - //we have to deference our copy of the THandle so we don't free it twice. - {$IFNDEF FPC} {not accessible for FPC} - FHandle := INVALID_HANDLE_VALUE; - {$ENDIF} - FreeAndNil( FFileStream ); - inherited Destroy; - {$ENDIF} -end; - - {$IFDEF WIN32_OR_WIN64} -initialization - LoadDLL; -finalization - UnloadDLL; -{$ENDIF} -End. +unit IdTransactedFileStream; +interface +{$I IdCompilerDefines.inc} + +{ +Original author: Grahame Grieve + +His notes are: + +If you want transactional file handling, with commit and rollback, +then this is the unit for you. It provides transactional safety on +Vista, win7, and windows server 2008, and just falls through to +normal file handling on earlier versions of windows. + +There's a couple of issues with the wrapper classes TKernelTransaction +and TIdTransactedFileStream: +- you can specify how you want file reading to work with a transactional + isolation. I don't surface this. + + - you can elevate the transactions to coordinate with DTC. They don't + do this (for instance, you could put your file handling in the same + transaction as an SQLServer transaction). I haven't done this - but if + you do this, I'd love a copy ;-) + +you use it like this: + +procedure StringToFile(const AStr, AFilename: String); +var + oFileStream: TIdTransactedFileStream; + oTransaction : TKernelTransaction; +begin + oTransaction := TIdKernelTransaction.Create('Save Content to file '+aFilename, false); + Try + Try + oFileStream := TIdTransactedFileStream.Create(AFilename, fmCreate); + try + if Length(AStr) > 0 then + WriteStringToStream(LFileStream, AStr, IndyTextEncoding_8Bit); + finally + LFileStream.Free; + end; + oTransaction.Commit; + Except + oTransaction.Rollback; + raise; + End; + Finally + oTransaction.Free; + End; +end; + +anyway - maybe useful in temporary file handling with file and email? I've +been burnt with temporary files and server crashes before. + +} +uses + {$IFDEF WIN32_OR_WIN64} + Windows, + Consts, + {$ENDIF} + Classes, SysUtils, IdGlobal; + + {$IFDEF WIN32_OR_WIN64} +const + TRANSACTION_DO_NOT_PROMOTE = 1; + + TXFS_MINIVERSION_COMMITTED_VIEW : Word = $0000; // The view of the file as of its last commit. + TXFS_MINIVERSION_DIRTY_VIEW : Word = $FFFE; // The view of the file as it is being modified by the transaction. + TXFS_MINIVERSION_DEFAULT_VIEW : Word = $FFFF; // Either the committed or dirty view of the file, depending on the context. + // A transaction that is modifying the file gets the dirty view, while a transaction + // that is not modifying the file gets the committed view. + +// remember to close the transaction handle. Use the CloseTransaction function here to avoid problems if the transactions are not available +type + TktmCreateTransaction = function (lpSecurityAttributes: PSecurityAttributes; + pUow : Pointer; + CreateOptions, IsolationLevel, IsolationFlags, Timeout : DWORD; + Description : PWideChar) : THandle; stdcall; + TktmCreateFileTransacted = function (lpFileName: PChar; + dwDesiredAccess, dwShareMode: DWORD; + lpSecurityAttributes: PSecurityAttributes; + dwCreationDisposition, dwFlagsAndAttributes: DWORD; + hTemplateFile: THandle; + hTransaction : THandle; + MiniVersion : Word; + pExtendedParameter : Pointer): THandle; stdcall; + TktmCommitTransaction = function (hTransaction : THandle) : Boolean; stdcall; + TktmRollbackTransaction = function (hTransaction : THandle) : + Boolean; stdcall; + TktmCloseTransaction = function (hTransaction : THandle) : Boolean; stdcall; + +var + CreateTransaction : TktmCreateTransaction; + CreateFileTransacted : TktmCreateFileTransacted; + CommitTransaction : TktmCommitTransaction; + RollbackTransaction : TktmRollbackTransaction; + CloseTransaction : TktmCloseTransaction; + + {$ENDIF} + +Function IsTransactionsWorking : Boolean; + +type + TIdKernelTransaction = class (TObject) + protected + FHandle : THandle; + public + constructor Create(Const sDescription : String; bCanPromote : Boolean = false); + destructor Destroy; override; + + function IsTransactional : Boolean; + procedure Commit; + procedure RollBack; + end; + + TIdTransactedFileStream = class(THandleStream) + {$IFNDEF WIN32_OR_WIN64} + protected + FFileStream : TFileStream; + {$ENDIF} + public + constructor Create(const FileName: string; Mode: Word; oTransaction : TIdKernelTransaction); + destructor Destroy; override; + end; + +implementation +uses RTLConsts; + + {$IFDEF WIN32_OR_WIN64} + +var + GHandleKtm : HModule; + GHandleKernel : HModule; + +function DummyCreateTransaction(lpSecurityAttributes: PSecurityAttributes; + pUow : Pointer; CreateOptions, IsolationLevel, + IsolationFlags, Timeout : DWORD; + Description : PWideChar) : THandle; stdcall; +begin + result := 1; +end; + +function DummyCreateFileTransacted(lpFileName: PChar; + dwDesiredAccess, dwShareMode: DWORD; + lpSecurityAttributes: PSecurityAttributes; + dwCreationDisposition, dwFlagsAndAttributes: DWORD; + hTemplateFile: THandle; + hTransaction : THandle; + MiniVersion : Word; + pExtendedParameter : Pointer): THandle; stdcall; +begin + result := CreateFile(lpFilename, dwDesiredAccess, dwShareMode, + lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, + hTemplateFile); +end; + +function DummyCommitTransaction(hTransaction : THandle) : Boolean; stdcall; +begin + assert(hTransaction = 1); + result := true; +end; + +function DummyRollbackTransaction(hTransaction : THandle) : Boolean; stdcall; +begin + assert(hTransaction = 1); + result := true; +end; + +function DummyCloseTransaction(hTransaction : THandle) : Boolean; stdcall; +begin + assert(hTransaction = 1); + result := true; +end; + +procedure LoadDll; +begin + GHandleKtm := LoadLibrary('ktmw32.dll'); + if GHandleKtm <> 0 Then begin + GHandleKernel := GetModuleHandle('Kernel32.dll'); //LoadLibrary('kernel32.dll'); + @CreateTransaction := LoadLibFunction(GHandleKtm, 'CreateTransaction'); + @CommitTransaction := LoadLibFunction(GHandleKtm, 'CommitTransaction'); + @RollbackTransaction := LoadLibFunction(GHandleKtm, 'RollbackTransaction'); + @CloseTransaction := LoadLibFunction(GHandleKernel, 'CloseHandle'); + {$IFDEF UNICODE} + @CreateFileTransacted := LoadLibFunction(GHandleKernel, 'CreateFileTransactedW'); + {$ELSE} + @CreateFileTransacted := LoadLibFunction(GHandleKernel, 'CreateFileTransactedA'); + {$ENDIF} + end else begin + @CreateTransaction := @DummyCreateTransaction; + @CommitTransaction := @DummyCommitTransaction; + @RollbackTransaction := @DummyRollbackTransaction; + @CloseTransaction := @DummyCloseTransaction; + @CreateFileTransacted := @DummyCreateFileTransacted; + end; +end; + +procedure UnloadDll; +begin + if GHandleKtm <> 0 then begin + freelibrary(GHandleKtm); + // freelibrary(GHandleKernel); + end +end; + +function IsTransactionsWorking : Boolean; +{$IFDEF USE_INLINE} inline; {$ENDIF} +begin + result := GHandleKtm <> 0; +end; + +{$ELSE} + +function IsTransactionsWorking : Boolean; +{$IFDEF USE_INLINE} inline; {$ENDIF} +begin + result := False; +end; +{$ENDIF} + +{ TIdKernelTransaction } + +constructor TIdKernelTransaction.Create(const sDescription: String; bCanPromote : Boolean); +var + pDesc : PWideChar; +begin + inherited Create; + {$IFDEF UNICODE} + GetMem(pDesc, length(sDescription) + 2); + try + StringToWideChar(sDescription, pDesc, length(sDescription) + 2); + {$ELSE} + GetMem(pDesc, length(sDescription) * 2 + 4); + try + StringToWideChar(sDescription, pDesc, length(sDescription) * 2 + 4); + {$ENDIF} + {$IFDEF WIN32_OR_WIN64} + if bCanPromote Then begin + FHandle := CreateTransaction(nil, nil, 0, 0, 0, 0, pDesc); + end else begin + FHandle := CreateTransaction(nil, nil, TRANSACTION_DO_NOT_PROMOTE, 0, 0, 0, pDesc); + end; + {$ENDIF} + finally + FreeMem(pDesc); + end; +end; + +destructor TIdKernelTransaction.Destroy; +begin + {$IFDEF WIN32_OR_WIN64} + CloseTransaction(FHandle); + {$ENDIF} + inherited Destroy; +end; + +procedure TIdKernelTransaction.Commit; +begin + {$IFDEF WIN32_OR_WIN64} + if not CommitTransaction(FHandle) then begin + IndyRaiseLastError; + end; + {$ENDIF} +end; + +function TIdKernelTransaction.IsTransactional: Boolean; +begin + result := IsTransactionsWorking; +end; + +procedure TIdKernelTransaction.RollBack; +begin + {$IFDEF WIN32_OR_WIN64} + if not RollbackTransaction(FHandle) then begin + IndyRaiseLastError; + end; + {$ENDIF} +end; + + {$IFDEF WIN32_OR_WIN64} +function FileCreateTransacted(const FileName: string; hTransaction : THandle): THandle; +begin + Result := THandle(CreateFileTransacted(PChar(FileName), GENERIC_READ or GENERIC_WRITE, + 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0, hTransaction, 0, nil)); + if result = INVALID_HANDLE_VALUE Then begin + IndyRaiseLastError; + end; +end; + +function FileOpenTransacted(const FileName: string; Mode: LongWord; hTransaction : THandle): THandle; +const + AccessMode: array[0..2] of LongWord = ( + GENERIC_READ, + GENERIC_WRITE, + GENERIC_READ or GENERIC_WRITE); + ShareMode: array[0..4] of LongWord = ( + 0, + 0, + FILE_SHARE_READ, + FILE_SHARE_WRITE, + FILE_SHARE_READ or FILE_SHARE_WRITE); +begin + Result := THandle(CreateFileTransacted(PChar(FileName),AccessMode[Mode and 3], + ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, 0, hTransaction,TXFS_MINIVERSION_DEFAULT_VIEW, nil)); +end; + {$ENDIF} + +{ TIdTransactedFileStream } + + {$IFDEF WIN32_OR_WIN64} +constructor TIdTransactedFileStream.Create(const FileName: string; Mode: Word; oTransaction: TIdKernelTransaction); +var + aHandle : THandle; +begin + if Mode = fmCreate then begin + aHandle := FileCreateTransacted(FileName, oTransaction.FHandle); + if aHandle = INVALID_HANDLE_VALUE then begin + raise EFCreateError.CreateResFmt(@SFCreateError, [FileName]); + end; + end else begin + aHandle := FileOpenTransacted(FileName, Mode, oTransaction.FHandle); + if aHandle = INVALID_HANDLE_VALUE then begin + raise EFOpenError.CreateResFmt(@SFOpenError, [FileName]); + end; + end; + inherited Create(ahandle); +end; +{$ELSE} +constructor TIdTransactedFileStream.Create(const FileName: string; Mode: Word; oTransaction: TIdKernelTransaction); +var LStream : TFileStream; +begin + LStream := FFileStream.Create(FileName,Mode); + inherited Create ( LStream.Handle); + FFileStream := LStream; +end; +{$ENDIF} + +destructor TIdTransactedFileStream.Destroy ; +begin + {$IFDEF WIN32_OR_WIN64} + if Handle = INVALID_HANDLE_VALUE then begin + FileClose(Handle); + end; + inherited Destroy; + {$ELSE} + //we have to deference our copy of the THandle so we don't free it twice. + {$IFNDEF FPC} {not accessible for FPC} + FHandle := INVALID_HANDLE_VALUE; + {$ENDIF} + FreeAndNil( FFileStream ); + inherited Destroy; + {$ENDIF} +end; + + {$IFDEF WIN32_OR_WIN64} +initialization + LoadDLL; +finalization + UnloadDLL; +{$ENDIF} +End. diff --git a/Lib/System/IdVers.inc b/Lib/System/IdVers.inc index b2c553572..316666f1b 100644 --- a/Lib/System/IdVers.inc +++ b/Lib/System/IdVers.inc @@ -1,18 +1,18 @@ - gsIdVersionMajor = 10; - {$NODEFINE gsIdVersionMajor} - gsIdVersionMinor = 7; - {$NODEFINE gsIdVersionMinor} - gsIdVersionRelease = 0; - {$NODEFINE gsIdVersionRelease} - gsIdVersionBuild = 0; - {$NODEFINE gsIdVersionBuild} - - (*$HPPEMIT '#define gsIdVersionMajor 10'*) - (*$HPPEMIT '#define gsIdVersionMinor 7'*) - (*$HPPEMIT '#define gsIdVersionRelease 0'*) - (*$HPPEMIT '#define gsIdVersionBuild 0'*) - (*$HPPEMIT ''*) - - gsIdVersion = '10.7.0.0'; {do not localize} - gsIdProductName = 'Indy'; {do not localize} - gsIdProductVersion = '10.7.0'; {do not localize} + gsIdVersionMajor = 10; + {$NODEFINE gsIdVersionMajor} + gsIdVersionMinor = 7; + {$NODEFINE gsIdVersionMinor} + gsIdVersionRelease = 0; + {$NODEFINE gsIdVersionRelease} + gsIdVersionBuild = 0; + {$NODEFINE gsIdVersionBuild} + + (*$HPPEMIT '#define gsIdVersionMajor 10'*) + (*$HPPEMIT '#define gsIdVersionMinor 7'*) + (*$HPPEMIT '#define gsIdVersionRelease 0'*) + (*$HPPEMIT '#define gsIdVersionBuild 0'*) + (*$HPPEMIT ''*) + + gsIdVersion = '10.7.0.0'; {do not localize} + gsIdProductName = 'Indy'; {do not localize} + gsIdProductVersion = '10.7.0'; {do not localize} diff --git a/Lib/System/IdWinsock2.pas b/Lib/System/IdWinsock2.pas index 23c72e596..392da1ed4 100644 --- a/Lib/System/IdWinsock2.pas +++ b/Lib/System/IdWinsock2.pas @@ -1,9027 +1,9027 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Log: 56400: IdWinsock2.pas - - Rev 1.0 2004.02.03 3:14:50 PM czhower - Move and updates - - - Rev 1.15 1/3/2004 12:41:48 AM BGooijen - Fixed WSAEnumProtocols - - - Rev 1.14 10/15/2003 1:20:48 PM DSiders - Added localization comments. - - - Rev 1.13 2003.10.01 11:16:38 AM czhower - .Net - - - Rev 1.12 9/24/2003 09:18:24 AM JPMugaas - Fixed an AV that happened when a stack call was made. - - - Rev 1.11 24/9/2003 3:11:34 PM SGrobety - First wave of fixes for compiling in dotnet. Still not functional, needed to - unlock to fix critical failure in Delphi code - - - Rev 1.10 9/22/2003 11:20:14 PM EHill - Removed assembly code and replaced with defined API stubs. - - - Rev 1.9 7/7/2003 12:55:10 PM BGooijen - Fixed ServiceQueryTransmitFile, and made it public - - - Rev 1.8 2003.05.09 10:59:30 PM czhower - - - Rev 1.7 4/19/2003 10:28:24 PM BGooijen - some functions were linked to the wrong dll - - - Rev 1.6 4/19/2003 11:14:40 AM JPMugaas - Made some tentitive wrapper functions for some things that should be called - from the Service Provider. Fixed WSARecvMsg. - - - Rev 1.5 4/19/2003 02:29:26 AM JPMugaas - Added TransmitPackets API function call. Note that this is only supported in - Windows XP or later. - - - Rev 1.4 4/19/2003 12:22:58 AM BGooijen - fixed: ConnectEx DisconnectEx WSARecvMsg - - - Rev 1.3 4/18/2003 12:00:58 AM JPMugaas - added - ConnectEx - DisconnectEx - WSARecvMsg - - Changed header procedure type names to be consistant with the old - IdWinsock.pas in Indy 8.0 and with the rest of the unit. - - - Rev 1.2 3/22/2003 10:01:26 PM JPMugaas - WSACreateEvent couldn't load because of a space. - - - Rev 1.1 3/22/2003 09:46:54 PM JPMugaas - It turns out that we really do not need the TGUID defination in the header at - all. It's defined in D4, D5, D6, and D7. - - - Rev 1.0 11/13/2002 09:02:54 AM JPMugaas -} -//------------------------------------------------------------- -// -// Borland Delphi Runtime Library -// interface unit -// -// Portions created by Microsoft are -// Copyright (C) 1995-1999 Microsoft Corporation. -// All Rights Reserved. -// -// The original file is: Winsock2.h from CBuilder5 distribution. -// The original Pascal code is: winsock2.pas, released 03 Mar 2001. -// The initial developer of the Pascal code is Alex Konshin -// (alexk@mtgroup.ru). -//------------------------------------------------------------- - - -{ Winsock2.h -- definitions to be used with the WinSock 2 DLL and WinSock 2 applications. - This header file corresponds to version 2.2.x of the WinSock API specification. - This file includes parts which are Copyright (c) 1982-1986 Regents - of the University of California. All rights reserved. - The Berkeley Software License Agreement specifies the terms and - conditions for redistribution. } - -// Note that the original unit is copyrighted by the original author and I did obtain his -// permission to port and use this as part of Indy - J. Peter Mugaas - -// 2002-01-28 - Hadi Hariri. Fixes for C++ Builder. Thanks to Chuck Smith. -// 2001 - Oct -25 J. Peter Mugaas -// Made adjustments for Indy usage by -// 1) including removing Trace logging -// 2) renaming and consolidating some .INC files as appropriate -// 3) modifying the unit to follow Indy conventions -// 4) Adding TransmitFile support for the HTTP Server -// 5) Removing all static loading code that was IFDEF'ed. {Do not Localize} -// 2001 - Mar - 1 Alex Konshin -// Revision 3 -// converted by Alex Konshin, mailto:alexk@mtgroup.ru -// revision 3, March,1 2001 - - -unit IdWinsock2; - -interface - -{$I IdCompilerDefines.inc} - -{ -Important!!! - -With the ARM architecture, you may get an EBusError exception sating that -data is misaligned. Sometimes, that architecture does not have the ability to -read misaligned data. On an i386 and x86_64 architecure, you can do this but it -is inefficient. For the ARM chip architecture, we have to make sure our records -are aligned on a 4 byte boundery. See: - -http://wiki.lazarus.freepascal.org/Windows_CE_Development_Notes - -This is not necessary and can cause problems -when using the standard Win32 API (win32 and win64) where records are packed -instead of aligned. - -To deal with this, I use the FPC predefined FPC_REQUIRES_PROPER_ALIGNMENT. - -} - -{$IFDEF WINDOWS} - -{$I IdRangeCheckingOff.inc} - -{$IFDEF FPC} - {$IFDEF WIN32} - {$ALIGN OFF} - {$ELSE} - //It turns out that Win64 and WinCE require record alignment - {$PACKRECORDS C} - {$ENDIF} -{$ELSE} - {$IFDEF WIN64} - {$ALIGN ON} - {$MINENUMSIZE 4} - {$ELSE} - {$MINENUMSIZE 4} - {$IFDEF REQUIRES_PROPER_ALIGNMENT} - {$ALIGN ON} - {$ELSE} - {$ALIGN OFF} - {$WRITEABLECONST OFF} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -uses - IdException, IdGlobal, SysUtils, Windows; - -type - EIdWinsockStubError = class(EIdException) - protected - FWin32Error : DWORD; - FWin32ErrorMessage : String; - FTitle : String; - public - constructor Build(AWin32Error: DWORD; const ATitle: String; AArgs: array of const); - property Win32Error : DWORD read FWin32Error; - property Win32ErrorMessage : String read FWin32ErrorMessage; - property Title : String read FTitle; - end; - -const - {$IFDEF WINCE} - WINSOCK2_DLL = 'ws2.dll'; {Do not Localize} - {$ELSE} - WINSOCK2_DLL = 'WS2_32.DLL'; {Do not Localize} - MSWSOCK_DLL = 'MSWSOCK.DLL'; {Do not Localize} - {$ENDIF} - {$EXTERNALSYM WINSOCK_VERSION} - WINSOCK_VERSION = $0202; - -{$DEFINE WS2_DLL_FUNC_VARS} -{$DEFINE INCL_WINSOCK_API_PROTOTYPES} -{$DEFINE INCL_WINSOCK_API_TYPEDEFS} - -type - {$EXTERNALSYM u_char} - u_char = Byte; - {$EXTERNALSYM u_short} - u_short = Word; - {$EXTERNALSYM u_int} - u_int = DWord; //Integer; - {$EXTERNALSYM u_long} - u_long = DWORD; -// The new type to be used in all instances which refer to sockets. - {$EXTERNALSYM TSocket} - TSocket = PtrUInt; - {$EXTERNALSYM WSAEVENT} - WSAEVENT = THandle; - {$NODEFINE PWSAEVENT} - PWSAEVENT = ^WSAEVENT; - {$EXTERNALSYM LPWSAEVENT} - LPWSAEVENT = PWSAEVENT; - - // Must define the following types because the older versions of Delphi do not support them - - {$IFNDEF HAS_ULONG_PTR} - {$EXTERNALSYM ULONG_PTR} - ULONG_PTR = PtrUInt; - {$ENDIF} - - {$IFNDEF HAS_DWORD_PTR} - {$EXTERNALSYM DWORD_PTR} - DWORD_PTR = PtrUInt; - {$ENDIF} - - {$IFNDEF HAS_USHORT} - {$EXTERNALSYM USHORT} - USHORT = UInt16; - {$ENDIF} - - {$IFNDEF HAS_PVOID} - {$EXTERNALSYM PVOID} - PVOID = Pointer; - {$ENDIF} - - {$IFNDEF HAS_ULONG64} - {$EXTERNALSYM ULONG64} - ULONG64 = UInt64; - {$ENDIF} - - {$IFNDEF HAS_LONG} - {$EXTERNALSYM LONG} - LONG = Longint; - {$ENDIF} - - {$IFNDEF HAS_ULONGLONG} - {$EXTERNALSYM ULONGLONG} - ULONGLONG = UInt64; - {$ENDIF} - -const - {$EXTERNALSYM FD_SETSIZE} - FD_SETSIZE = 64; - -// the following emits are a workaround to the name conflicts -// with the winsock2 header files -(*$HPPEMIT '#include '*) -(*$HPPEMIT '#include '*) -(*$HPPEMIT '#include '*) -(*$HPPEMIT '// workaround for a bug in wsnwlink.h where a couple of commented lines are not terminated property'*) -(*$HPPEMIT '#pragma option push -C-'*) -(*$HPPEMIT '#include '*) -(*$HPPEMIT '#pragma option pop'*) -(*$HPPEMIT '#include '*) -(*$HPPEMIT '#include '*) -(*$HPPEMIT '#include '*) -(*$HPPEMIT ''*) - -{$IFDEF HAS_DIRECTIVE_HPPEMIT_NAMESPACE} -{$HPPEMIT OPENNAMESPACE} -{$ELSE} -(*$HPPEMIT 'namespace Idwinsock2'*) -(*$HPPEMIT '{'*) -{$ENDIF} -(*$HPPEMIT ' typedef fd_set *PFDSet;'*) // due to name conflict with procedure FD_SET -(*$HPPEMIT ' typedef fd_set TFDSet;'*) // due to name conflict with procedure FD_SET -{$IFDEF HAS_DIRECTIVE_HPPEMIT_NAMESPACE} -{$HPPEMIT CLOSENAMESPACE} -{$ELSE} -(*$HPPEMIT '}'*) -{$ENDIF} -(*$HPPEMIT ''*) - -type - {$NODEFINE PFDSet} - PFDSet = ^TFDSet; - {$NODEFINE TFDSet} - TFDSet = record - fd_count: u_int; - fd_array: array[0..FD_SETSIZE-1] of TSocket; - end; - - {$EXTERNALSYM timeval} - timeval = record - tv_sec: Longint; - tv_usec: Longint; - end; - {$NODEFINE TTimeVal} - TTimeVal = timeval; - {$NODEFINE PTimeVal} - PTimeVal = ^TTimeVal; - -const - {$EXTERNALSYM IOCPARM_MASK} - IOCPARM_MASK = $7F; - {$EXTERNALSYM IOC_VOID} - IOC_VOID = $20000000; - {$EXTERNALSYM IOC_OUT} - IOC_OUT = $40000000; - {$EXTERNALSYM IOC_IN} - IOC_IN = $80000000; - {$EXTERNALSYM IOC_INOUT} - IOC_INOUT = (IOC_IN or IOC_OUT); - -// get # bytes to read - {$EXTERNALSYM FIONREAD} - FIONREAD = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('f') shl 8) or 127; {Do not Localize} -// set/clear non-blocking i/o - {$EXTERNALSYM FIONBIO} - FIONBIO = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('f') shl 8) or 126; {Do not Localize} -// set/clear async i/o - {$EXTERNALSYM FIOASYNC} - FIOASYNC = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('f') shl 8) or 125; {Do not Localize} - -// Socket I/O Controls - -// set high watermark - {$EXTERNALSYM SIOCSHIWAT} - SIOCSHIWAT = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('s') shl 8) or 0; {Do not Localize} -// get high watermark - {$EXTERNALSYM SIOCGHIWAT} - SIOCGHIWAT = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('s') shl 8) or 1; {Do not Localize} -// set low watermark - {$EXTERNALSYM SIOCSLOWAT} - SIOCSLOWAT = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('s') shl 8) or 2; {Do not Localize} -// get low watermark - {$EXTERNALSYM SIOCGLOWAT} - SIOCGLOWAT = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('s') shl 8) or 3; {Do not Localize} -// at oob mark? - {$EXTERNALSYM SIOCATMARK} - SIOCATMARK = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('s') shl 8) or 7; {Do not Localize} - - -// Structures returned by network data base library, taken from the -// BSD file netdb.h. All addresses are supplied in host order, and -// returned in network order (suitable for use in system calls). -type - {$EXTERNALSYM hostent} - hostent = record - h_name: PIdAnsiChar; // official name of host - h_aliases: PPIdAnsiChar; // alias list - h_addrtype: short; // host address type - h_length: short; // length of address - case Byte of - 0: (h_address_list: PPIdAnsiChar); - 1: (h_addr: PIdAnsiChar); // address, for backward compat - end; - {$NODEFINE THostEnt} - THostEnt = hostent; - {$NODEFINE PHostEnt} - PHostEnt = ^THostEnt; - -// It is assumed here that a network number -// fits in 32 bits. - {$EXTERNALSYM netent} - netent = record - n_name: PIdAnsiChar; // official name of net - n_aliases: PPIdAnsiChar; // alias list - n_addrtype: short; // net address type - n_net: u_long; // network # - end; - {$NODEFINE TNetEnt} - TNetEnt = netent; - {$NODEFINE PNetEnt} - PNetEnt = ^TNetEnt; - - {$EXTERNALSYM servent} - servent = record - s_name: PIdAnsiChar; // official service name - s_aliases: PPIdAnsiChar; // alias list - {$IFDEF _WIN64} - s_proto: PIdAnsiChar; // protocol to use - s_port: short; // port # - {$ELSE} - s_port: short; // port # - s_proto: PIdAnsiChar; // protocol to use - {$ENDIF} - end; - {$NODEFINE TServEnt} - TServEnt = servent; - {$NODEFINE PServEnt} - PServEnt = ^TServEnt; - - {$EXTERNALSYM protoent} - protoent = record - p_name: PIdAnsiChar; // official protocol name - p_aliases: PPIdAnsiChar; // alias list - p_proto: short; // protocol # - end; - {$NODEFINE TProtoEnt} - TProtoEnt = protoent; - {$NODEFINE PProtoEnt} - PProtoEnt = ^TProtoEnt; - {$EXTERNALSYM NL_ADDRESS_TYPE} - NL_ADDRESS_TYPE = ( - NlatUnspecified, - NlatUnicast, - NlatAnycast, - NlatMulticast, - NlatBroadcast, - NlatInvalid); -// Constants and structures defined by the internet system, -// Per RFC 790, September 1981, taken from the BSD file netinet/in.h. -const - -// Protocols - {$EXTERNALSYM IPPROTO_IP} - IPPROTO_IP = 0; // dummy for IP - {$EXTERNALSYM IPPROTO_ICMP} - IPPROTO_ICMP = 1; // control message protocol - {$EXTERNALSYM IPPROTO_IGMP} - IPPROTO_IGMP = 2; // group management protocol - {$EXTERNALSYM IPPROTO_GGP} - IPPROTO_GGP = 3; // gateway^2 (deprecated) - {$EXTERNALSYM IPPROTO_TCP} - IPPROTO_TCP = 6; // TCP - {$EXTERNALSYM IPPROTO_PUP} - IPPROTO_PUP = 12; // pup - {$EXTERNALSYM IPPROTO_UDP} - IPPROTO_UDP = 17; // UDP - user datagram protocol - {$EXTERNALSYM IPPROTO_IDP} - IPPROTO_IDP = 22; // xns idp - {$EXTERNALSYM IPPROTO_ND} - IPPROTO_ND = 77; // UNOFFICIAL net disk proto - - {$EXTERNALSYM IPPROTO_IPV6} - IPPROTO_IPV6 = 41; // IPv6 - {$EXTERNALSYM IPPROTO_ICLFXBM} - IPPROTO_ICLFXBM = 78; - - {$EXTERNALSYM IPPROTO_ICMPV6} - IPPROTO_ICMPV6 = 58; // control message protocol - - {$EXTERNALSYM IPPROTO_RAW} - IPPROTO_RAW = 255; // raw IP packet - {$EXTERNALSYM IPPROTO_MAX} - IPPROTO_MAX = 256; - -// Port/socket numbers: network standard functions - {$EXTERNALSYM IPPORT_ECHO} - IPPORT_ECHO = 7; - {$EXTERNALSYM IPPORT_DISCARD} - IPPORT_DISCARD = 9; - {$EXTERNALSYM IPPORT_SYSTAT} - IPPORT_SYSTAT = 11; - {$EXTERNALSYM IPPORT_DAYTIME} - IPPORT_DAYTIME = 13; - {$EXTERNALSYM IPPORT_NETSTAT} - IPPORT_NETSTAT = 15; - {$EXTERNALSYM IPPORT_FTP} - IPPORT_FTP = 21; - {$EXTERNALSYM IPPORT_TELNET} - IPPORT_TELNET = 23; - {$EXTERNALSYM IPPORT_SMTP} - IPPORT_SMTP = 25; - {$EXTERNALSYM IPPORT_TIMESERVER} - IPPORT_TIMESERVER = 37; - {$EXTERNALSYM IPPORT_NAMESERVER} - IPPORT_NAMESERVER = 42; - {$EXTERNALSYM IPPORT_WHOIS} - IPPORT_WHOIS = 43; - {$EXTERNALSYM IPPORT_MTP} - IPPORT_MTP = 57; - -// Port/socket numbers: host specific functions - {$EXTERNALSYM IPPORT_TFTP} - IPPORT_TFTP = 69; - {$EXTERNALSYM IPPORT_RJE} - IPPORT_RJE = 77; - {$EXTERNALSYM IPPORT_FINGER} - IPPORT_FINGER = 79; - {$EXTERNALSYM ipport_ttylink} - IPPORT_TTYLINK = 87; - {$EXTERNALSYM IPPORT_SUPDUP} - IPPORT_SUPDUP = 95; - -// UNIX TCP sockets - {$EXTERNALSYM IPPORT_EXECSERVER} - IPPORT_EXECSERVER = 512; - {$EXTERNALSYM IPPORT_LOGINSERVER} - IPPORT_LOGINSERVER = 513; - {$EXTERNALSYM IPPORT_CMDSERVER} - IPPORT_CMDSERVER = 514; - {$EXTERNALSYM IPPORT_EFSSERVER} - IPPORT_EFSSERVER = 520; - -// UNIX UDP sockets - {$EXTERNALSYM IPPORT_BIFFUDP} - IPPORT_BIFFUDP = 512; - {$EXTERNALSYM IPPORT_WHOSERVER} - IPPORT_WHOSERVER = 513; - {$EXTERNALSYM IPPORT_ROUTESERVER} - IPPORT_ROUTESERVER = 520; - -// Ports < IPPORT_RESERVED are reserved for privileged processes (e.g. root). - {$EXTERNALSYM IPPORT_RESERVED} - IPPORT_RESERVED = 1024; - - {$EXTERNALSYM IPPORT_REGISTERED_MIN} - IPPORT_REGISTERED_MIN = IPPORT_RESERVED; - - {$IFNDEF WINCE} - {$EXTERNALSYM IPPORT_REGISTERED_MAX} - IPPORT_REGISTERED_MAX = $bfff; - {$EXTERNALSYM IPPORT_DYNAMIC_MIN} - IPPORT_DYNAMIC_MIN = $c000; - {$EXTERNALSYM IPPORT_DYNAMIC_MAX} - IPPORT_DYNAMIC_MAX = $ffff; - {$ENDIF} - -// Link numbers - {$EXTERNALSYM IMPLINK_IP} - IMPLINK_IP = 155; - {$EXTERNALSYM IMPLINK_LOWEXPER} - IMPLINK_LOWEXPER = 156; - {$EXTERNALSYM IMPLINK_HIGHEXPER} - IMPLINK_HIGHEXPER = 158; - - {$EXTERNALSYM TF_DISCONNECT} - TF_DISCONNECT = $01; - {$EXTERNALSYM TF_REUSE_SOCKET} - TF_REUSE_SOCKET = $02; - {$EXTERNALSYM TF_WRITE_BEHIND} - TF_WRITE_BEHIND = $04; - {$EXTERNALSYM TF_USE_DEFAULT_WORKER} - TF_USE_DEFAULT_WORKER = $00; - {$EXTERNALSYM TF_USE_SYSTEM_THREAD} - TF_USE_SYSTEM_THREAD = $10; - {$EXTERNALSYM TF_USE_KERNEL_APC} - TF_USE_KERNEL_APC = $20; - -// This is used instead of -1, since the TSocket type is unsigned. - {$EXTERNALSYM INVALID_SOCKET} - INVALID_SOCKET = TSocket(not(0)); - {$EXTERNALSYM SOCKET_ERROR} - SOCKET_ERROR = -1; - -// The following may be used in place of the address family, socket type, or -// protocol in a call to WSASocket to indicate that the corresponding value -// should be taken from the supplied WSAPROTOCOL_INFO structure instead of the -// parameter itself. - {$EXTERNALSYM FROM_PROTOCOL_INFO} - FROM_PROTOCOL_INFO = -1; - - -// Types - {$EXTERNALSYM SOCK_STREAM} - SOCK_STREAM = 1; { stream socket } - {$EXTERNALSYM SOCK_DGRAM} - SOCK_DGRAM = 2; { datagram socket } - {$EXTERNALSYM SOCK_RAW} - SOCK_RAW = 3; { raw-protocol interface } - {$EXTERNALSYM SOCK_RDM} - SOCK_RDM = 4; { reliably-delivered message } - {$EXTERNALSYM SOCK_SEQPACKET} - SOCK_SEQPACKET = 5; { sequenced packet stream } - -// option flags per-socket. - {$EXTERNALSYM SO_DEBUG} - SO_DEBUG = $0001; // turn on debugging info recording - {$EXTERNALSYM SO_ACCEPTCONN} - SO_ACCEPTCONN = $0002; // socket has had listen() - {$EXTERNALSYM SO_REUSEADDR} - SO_REUSEADDR = $0004; // allow local address reuse - {$EXTERNALSYM SO_KEEPALIVE} - SO_KEEPALIVE = $0008; // keep connections alive - {$EXTERNALSYM SO_DONTROUTE} - SO_DONTROUTE = $0010; // just use interface addresses - {$EXTERNALSYM SO_BROADCAST} - SO_BROADCAST = $0020; // permit sending of broadcast msgs - {$EXTERNALSYM SO_USELOOPBACK} - SO_USELOOPBACK = $0040; // bypass hardware when possible - {$EXTERNALSYM SO_LINGER} - SO_LINGER = $0080; // linger on close if data present - {$EXTERNALSYM SO_OOBINLINE} - SO_OOBINLINE = $0100; // leave received OOB data in line - - {$EXTERNALSYM SO_DONTLINGER} - SO_DONTLINGER = not SO_LINGER; - {$EXTERNALSYM SO_EXCLUSIVEADDRUSE} - SO_EXCLUSIVEADDRUSE = not SO_REUSEADDR; // disallow local address reuse - -// additional options. - - {$EXTERNALSYM SO_SNDBUF} - SO_SNDBUF = $1001; // send buffer size - {$EXTERNALSYM SO_RCVBUF} - SO_RCVBUF = $1002; // receive buffer size - {$EXTERNALSYM SO_SNDLOWAT} - SO_SNDLOWAT = $1003; // send low-water mark - {$EXTERNALSYM SO_RCVLOWAT} - SO_RCVLOWAT = $1004; // receive low-water mark - {$EXTERNALSYM SO_SNDTIMEO} - SO_SNDTIMEO = $1005; // send timeout - {$EXTERNALSYM SO_RCVTIMEO} - SO_RCVTIMEO = $1006; // receive timeout - {$EXTERNALSYM SO_ERROR} - SO_ERROR = $1007; // get error status and clear - {$EXTERNALSYM SO_TYPE} - SO_TYPE = $1008; // get socket type - -// options for connect and disconnect data and options. -// used only by non-tcp/ip transports such as DECNet, OSI TP4, etc. - {$EXTERNALSYM SO_CONNDATA} - SO_CONNDATA = $7000; - {$EXTERNALSYM SO_CONNOPT} - SO_CONNOPT = $7001; - {$EXTERNALSYM SO_DISCDATA} - SO_DISCDATA = $7002; - {$EXTERNALSYM SO_DISCOPT} - SO_DISCOPT = $7003; - {$EXTERNALSYM SO_CONNDATALEN} - SO_CONNDATALEN = $7004; - {$EXTERNALSYM SO_CONNOPTLEN} - SO_CONNOPTLEN = $7005; - {$EXTERNALSYM SO_DISCDATALEN} - SO_DISCDATALEN = $7006; - {$EXTERNALSYM SO_DISCOPTLEN} - SO_DISCOPTLEN = $7007; - -// option for opening sockets for synchronous access. - {$EXTERNALSYM SO_OPENTYPE} - SO_OPENTYPE = $7008; - {$EXTERNALSYM SO_SYNCHRONOUS_ALERT} - SO_SYNCHRONOUS_ALERT = $10; - {$EXTERNALSYM SO_SYNCHRONOUS_NONALERT} - SO_SYNCHRONOUS_NONALERT = $20; - -// other nt-specific options. - {$EXTERNALSYM SO_MAXDG} - SO_MAXDG = $7009; - {$EXTERNALSYM SO_MAXPATHDG} - SO_MAXPATHDG = $700A; - {$EXTERNALSYM SO_UPDATE_ACCEPT_CONTEXT} - SO_UPDATE_ACCEPT_CONTEXT = $700B; - {$EXTERNALSYM SO_CONNECT_TIME} - SO_CONNECT_TIME = $700C; - {$EXTERNALSYM SO_UPDATE_CONNECT_CONTEXT} - SO_UPDATE_CONNECT_CONTEXT = $7010; - -// tcp options. - {$EXTERNALSYM TCP_NODELAY} - TCP_NODELAY = $0001; - {$EXTERNALSYM TCP_BSDURGENT} - TCP_BSDURGENT = $7000; - -// winsock 2 extension -- new options - {$EXTERNALSYM SO_GROUP_ID} - SO_GROUP_ID = $2001; // ID of a socket group - {$EXTERNALSYM SO_GROUP_PRIORITY} - SO_GROUP_PRIORITY = $2002; // the relative priority within a group - {$EXTERNALSYM SO_MAX_MSG_SIZE} - SO_MAX_MSG_SIZE = $2003; // maximum message size - {$EXTERNALSYM SO_PROTOCOL_INFOA} - SO_PROTOCOL_INFOA = $2004; // WSAPROTOCOL_INFOA structure - {$EXTERNALSYM SO_PROTOCOL_INFOW} - SO_PROTOCOL_INFOW = $2005; // WSAPROTOCOL_INFOW structure - {$EXTERNALSYM SO_PROTOCOL_INFO} - {$IFDEF UNICODE} - SO_PROTOCOL_INFO = SO_PROTOCOL_INFOW; - {$ELSE} - SO_PROTOCOL_INFO = SO_PROTOCOL_INFOA; - {$ENDIF} - {$EXTERNALSYM PVD_CONFIG} - PVD_CONFIG = $3001; // configuration info for service provider - {$EXTERNALSYM SO_CONDITIONAL_ACCEPT} - SO_CONDITIONAL_ACCEPT = $3002; // enable true conditional accept: - // connection is not ack-ed to the - // other side until conditional - // function returns CF_ACCEPT - {$EXTERNALSYM SO_REUSE_UNICASTPORT} - SO_REUSE_UNICASTPORT = $3007; // defer ephemeral port allocation for - // outbound connections - {$EXTERNALSYM SO_REUSE_MULTICASTPORT} - SO_REUSE_MULTICASTPORT = $3008; // enable port reuse and disable unicast - //reception. - {$IFNDEF WINCE} - {$EXTERNALSYM SO_RANDOMIZE_PORT} - SO_RANDOMIZE_PORT = $3005; // randomize assignment of wildcard ports - {$EXTERNALSYM SO_PORT_SCALABILITY} - SO_PORT_SCALABILITY = $3006; // enable port scalability - {$ENDIF} -// Address families. - {$EXTERNALSYM AF_UNSPEC} - AF_UNSPEC = 0; // unspecified - {$EXTERNALSYM AF_UNIX} - AF_UNIX = 1; // local to host (pipes, portals) - {$EXTERNALSYM AF_INET} - AF_INET = 2; // internetwork: UDP, TCP, etc. - {$EXTERNALSYM AF_IMPLINK} - AF_IMPLINK = 3; // arpanet imp addresses - {$EXTERNALSYM AF_PUP} - AF_PUP = 4; // pup protocols: e.g. BSP - {$EXTERNALSYM AF_CHAOS} - AF_CHAOS = 5; // mit CHAOS protocols - {$EXTERNALSYM AF_IPX} - AF_IPX = 6; // ipx and SPX - {$EXTERNALSYM AF_NS} - AF_NS = AF_IPX; // xerOX NS protocols - {$EXTERNALSYM AF_ISO} - AF_ISO = 7; // iso protocols - {$EXTERNALSYM AF_OSI} - AF_OSI = AF_ISO; // osi is ISO - {$EXTERNALSYM AF_ECMA} - AF_ECMA = 8; // european computer manufacturers - {$EXTERNALSYM AF_DATAKIT} - AF_DATAKIT = 9; // datakit protocols - {$EXTERNALSYM AF_CCITT} - AF_CCITT = 10; // cciTT protocols, X.25 etc - {$EXTERNALSYM AF_SNA} - AF_SNA = 11; // ibm SNA - {$EXTERNALSYM AF_DECNET} - AF_DECNET = 12; // decnet - {$EXTERNALSYM AF_DLI} - AF_DLI = 13; // direct data link interface - {$EXTERNALSYM AF_LAT} - AF_LAT = 14; // lat - {$EXTERNALSYM AF_HYLINK} - AF_HYLINK = 15; // nsc Hyperchannel - {$EXTERNALSYM AF_APPLETALK} - AF_APPLETALK = 16; // appleTalk - {$EXTERNALSYM AF_NETBIOS} - AF_NETBIOS = 17; // netBios-style addresses - {$EXTERNALSYM AF_VOICEVIEW} - AF_VOICEVIEW = 18; // voiceView - {$EXTERNALSYM AF_FIREFOX} - AF_FIREFOX = 19; // fireFox - {$EXTERNALSYM AF_UNKNOWN1} - AF_UNKNOWN1 = 20; // somebody is using this! - {$EXTERNALSYM AF_BAN} - AF_BAN = 21; // banyan - {$IFDEF WINCE} - {$EXTERNALSYM AF_IRDA} - AF_IRDA = 22; //* IrDA */ - {$ELSE} - {$EXTERNALSYM AF_ATM} - AF_ATM = 22; // native ATM Services - {$ENDIF} - {$EXTERNALSYM AF_INET6} - AF_INET6 = 23; // internetwork Version 6 - {$EXTERNALSYM AF_CLUSTER} - AF_CLUSTER = 24; // microsoft Wolfpack - {$EXTERNALSYM AF_12844} - AF_12844 = 25; // ieeE 1284.4 WG AF - {$IFDEF WINCE} - {$EXTERNALSYM AF_ATM} - AF_ATM = 26; //* Native ATM Services */ - {$ELSE} - {$EXTERNALSYM AF_IRDA} - AF_IRDA = 26; // irdA - {$ENDIF} - {$EXTERNALSYM AF_NETDES} - AF_NETDES = 28; // network Designers OSI & gateway enabled protocols - {$EXTERNALSYM AF_TCNPROCESS} - AF_TCNPROCESS = 29; - {$EXTERNALSYM AF_TCNMESSAGE} - AF_TCNMESSAGE = 30; - {$EXTERNALSYM AF_ICLFXBM} - AF_ICLFXBM = 31; - - {$EXTERNALSYM AF_HYPERV} - AF_HYPERV = 34; - {$EXTERNALSYM AF_MAX} - AF_MAX = 35; //was 32 - -// protocol families, same as address families for now. - - {$EXTERNALSYM PF_UNSPEC} - PF_UNSPEC = AF_UNSPEC; - {$EXTERNALSYM PF_UNIX} - PF_UNIX = AF_UNIX; - {$EXTERNALSYM PF_INET} - PF_INET = AF_INET; - {$EXTERNALSYM PF_IMPLINK} - PF_IMPLINK = AF_IMPLINK; - {$EXTERNALSYM PF_PUP} - PF_PUP = AF_PUP; - {$EXTERNALSYM PF_CHAOS} - PF_CHAOS = AF_CHAOS; - {$EXTERNALSYM PF_NS} - PF_NS = AF_NS; - {$EXTERNALSYM PF_IPX} - PF_IPX = AF_IPX; - {$EXTERNALSYM PF_ISO} - PF_ISO = AF_ISO; - {$EXTERNALSYM PF_OSI} - PF_OSI = AF_OSI; - {$EXTERNALSYM PF_ECMA} - PF_ECMA = AF_ECMA; - {$EXTERNALSYM PF_DATAKIT} - PF_DATAKIT = AF_DATAKIT; - {$EXTERNALSYM PF_CCITT} - PF_CCITT = AF_CCITT; - {$EXTERNALSYM PF_SNA} - PF_SNA = AF_SNA; - {$EXTERNALSYM PF_DECNET} - PF_DECNET = AF_DECNET; - {$EXTERNALSYM PF_DLI} - PF_DLI = AF_DLI; - {$EXTERNALSYM PF_LAT} - PF_LAT = AF_LAT; - {$EXTERNALSYM PF_HYLINK} - PF_HYLINK = AF_HYLINK; - {$EXTERNALSYM PF_APPLETALK} - PF_APPLETALK = AF_APPLETALK; - {$EXTERNALSYM PF_VOICEVIEW} - PF_VOICEVIEW = AF_VOICEVIEW; - {$EXTERNALSYM PF_FIREFOX} - PF_FIREFOX = AF_FIREFOX; - {$EXTERNALSYM PF_UNKNOWN1} - PF_UNKNOWN1 = AF_UNKNOWN1; - {$EXTERNALSYM pf_ban} - PF_BAN = AF_BAN; - {$EXTERNALSYM PF_ATM} - PF_ATM = AF_ATM; - {$EXTERNALSYM PF_INET6} - PF_INET6 = AF_INET6; - - {$EXTERNALSYM PF_MAX} - PF_MAX = AF_MAX; - - {$EXTERNALSYM _SS_MAXSIZE} - _SS_MAXSIZE = 128; - {$EXTERNALSYM _SS_ALIGNSIZE} - _SS_ALIGNSIZE = SizeOf(Int64); - {$EXTERNALSYM _SS_PAD1SIZE} - _SS_PAD1SIZE = _SS_ALIGNSIZE - SizeOf(short); - {$EXTERNALSYM _SS_PAD2SIZE} - _SS_PAD2SIZE = _SS_MAXSIZE - (SizeOf(short) + _SS_PAD1SIZE + _SS_ALIGNSIZE); - -type - {$NODEFINE SunB} - SunB = record - s_b1, s_b2, s_b3, s_b4: u_char; - end; - - {$NODEFINE SunW} - SunW = record - s_w1, s_w2: u_short; - end; - - {$EXTERNALSYM in_addr} - in_addr = record - case integer of - 0: (S_un_b: SunB); - 1: (S_un_w: SunW); - 2: (S_addr: u_long); - end; - {$NODEFINE TInAddr} - TInAddr = in_addr; - {$NODEFINE PInAddr} - PInAddr = ^TInAddr; - - // Structure used by kernel to store most addresses. - - {$EXTERNALSYM sockaddr_in} - sockaddr_in = record - case Integer of - 0: (sin_family : u_short; - sin_port : u_short; - sin_addr : TInAddr; - sin_zero : array[0..7] of TIdAnsiChar); - 1: (sa_family : u_short; - sa_data : array[0..13] of TIdAnsiChar) - end; - {$NODEFINE TSockAddrIn} - TSockAddrIn = sockaddr_in; - {$NODEFINE PSockAddrIn} - PSockAddrIn = ^TSockAddrIn; - {$NODEFINE PSockAddr_In} - PSockAddr_In = PSockAddrIn; - {$NODEFINE TSockAddr} - TSockAddr = TSockAddrIn; - {$EXTERNALSYM SOCKADDR} - SOCKADDR = TSockAddr; - {$EXTERNALSYM PSOCKADDR} - PSOCKADDR = ^TSockAddr; - {$EXTERNALSYM LPSOCKADDR} - LPSOCKADDR = PSOCKADDR; - - {$EXTERNALSYM SOCKADDR_STORAGE} - SOCKADDR_STORAGE = record - ss_family: short; // Address family. - __ss_pad1: array[0.._SS_PAD1SIZE-1] of TIdAnsiChar; // 6 byte pad, this is to make - // implementation specific pad up to - // alignment field that follows explicit - // in the data structure. - __ss_align: Int64; // Field to force desired structure. - __ss_pad2: array[0.._SS_PAD2SIZE-1] of TIdAnsiChar; // 112 byte pad to achieve desired size; - // _SS_MAXSIZE value minus size of - // ss_family, __ss_pad1, and - // __ss_align fields is 112. - end; - {$NODEFINE TSockAddrStorage} - TSockAddrStorage = SOCKADDR_STORAGE; - {$NODEFINE PSockAddrStorage} - PSockAddrStorage = ^TSockAddrStorage; - {$EXTERNALSYM PSOCKADDR_STORAGE} - PSOCKADDR_STORAGE = PSockAddrStorage; - {$EXTERNALSYM LPSOCKADDR_STORAGE} - LPSOCKADDR_STORAGE = PSOCKADDR_STORAGE; - - // Structure used by kernel to pass protocol information in raw sockets. - {$EXTERNALSYM sockproto} - sockproto = record - sp_family : u_short; - sp_protocol : u_short; - end; - {$NODEFINE TSockProto} - TSockProto = sockproto; - {$NODEFINE PSockProto} - PSockProto = ^TSockProto; - -// Structure used for manipulating linger option. - {$EXTERNALSYM linger} - linger = record - l_onoff: u_short; - l_linger: u_short; - end; - {$NODEFINE TLinger} - TLinger = linger; - {$EXTERNALSYM PLINGER} - PLINGER = ^TLinger; - {$EXTERNALSYM LPLINGER} - LPLINGER = PLINGER; - -const - {$EXTERNALSYM INADDR_ANY} - INADDR_ANY = $00000000; - {$EXTERNALSYM INADDR_LOOPBACK} - INADDR_LOOPBACK = $7F000001; - {$EXTERNALSYM INADDR_BROADCAST} - INADDR_BROADCAST = $FFFFFFFF; - {$EXTERNALSYM INADDR_NONE} - INADDR_NONE = $FFFFFFFF; - - {$EXTERNALSYM ADDR_ANY} - ADDR_ANY = INADDR_ANY; - - {$EXTERNALSYM SOL_SOCKET} - SOL_SOCKET = $FFFF; // options for socket level - - {$EXTERNALSYM MSG_OOB} - MSG_OOB = $1; // process out-of-band data - {$EXTERNALSYM MSG_PEEK} - MSG_PEEK = $2; // peek at incoming message - {$EXTERNALSYM MSG_DONTROUTE} - MSG_DONTROUTE = $4; // send without using routing tables - - {$EXTERNALSYM MSG_PARTIAL} - MSG_PARTIAL = $8000; // partial send or recv for message xport - -// WinSock 2 extension -- new flags for WSASend(), WSASendTo(), WSARecv() and WSARecvFrom() - {$EXTERNALSYM MSG_INTERRUPT} - MSG_INTERRUPT = $10; // send/recv in the interrupt context - {$EXTERNALSYM MSG_MAXIOVLEN} - MSG_MAXIOVLEN = 16; - -// Define constant based on rfc883, used by gethostbyxxxx() calls. - - {$EXTERNALSYM MAXGETHOSTSTRUCT} - MAXGETHOSTSTRUCT = 1024; - -// Maximum queue length specifiable by listen. - {$EXTERNALSYM SOMAXCONN} - SOMAXCONN = $7FFFFFFF; - -// WinSock 2 extension -- bit values and indices for FD_XXX network events - {$EXTERNALSYM FD_READ_BIT} - FD_READ_BIT = 0; - {$EXTERNALSYM FD_WRITE_BIT} - FD_WRITE_BIT = 1; - {$EXTERNALSYM FD_OOB_BIT} - FD_OOB_BIT = 2; - {$EXTERNALSYM FD_ACCEPT_BIT} - FD_ACCEPT_BIT = 3; - {$EXTERNALSYM FD_CONNECT_BIT} - FD_CONNECT_BIT = 4; - {$EXTERNALSYM FD_CLOSE_BIT} - FD_CLOSE_BIT = 5; - {$EXTERNALSYM fd_qos_bit} - FD_QOS_BIT = 6; - {$EXTERNALSYM FD_GROUP_QOS_BIT} - FD_GROUP_QOS_BIT = 7; - {$EXTERNALSYM FD_ROUTING_INTERFACE_CHANGE_BIT} - FD_ROUTING_INTERFACE_CHANGE_BIT = 8; - {$EXTERNALSYM FD_ADDRESS_LIST_CHANGE_BIT} - FD_ADDRESS_LIST_CHANGE_BIT = 9; - - {$EXTERNALSYM FD_MAX_EVENTS} - FD_MAX_EVENTS = 10; - - {$EXTERNALSYM FD_READ} - FD_READ = (1 shl FD_READ_BIT); - {$EXTERNALSYM FD_WRITE} - FD_WRITE = (1 shl FD_WRITE_BIT); - {$EXTERNALSYM FD_OOB} - FD_OOB = (1 shl FD_OOB_BIT); - {$EXTERNALSYM FD_ACCEPT} - FD_ACCEPT = (1 shl FD_ACCEPT_BIT); - {$EXTERNALSYM FD_CONNECT} - FD_CONNECT = (1 shl FD_CONNECT_BIT); - {$EXTERNALSYM FD_CLOSE} - FD_CLOSE = (1 shl FD_CLOSE_BIT); - {$EXTERNALSYM FD_QOS} - FD_QOS = (1 shl FD_QOS_BIT); - {$EXTERNALSYM FD_GROUP_QOS} - FD_GROUP_QOS = (1 shl FD_GROUP_QOS_BIT); - {$EXTERNALSYM FD_ROUTING_INTERFACE_CHANGE} - FD_ROUTING_INTERFACE_CHANGE = (1 shl FD_ROUTING_INTERFACE_CHANGE_BIT); - {$EXTERNALSYM FD_ADDRESS_LIST_CHANGE} - FD_ADDRESS_LIST_CHANGE = (1 shl FD_ADDRESS_LIST_CHANGE_BIT); - - {$EXTERNALSYM FD_ALL_EVENTS} - FD_ALL_EVENTS = (1 shl FD_MAX_EVENTS) - 1; - -// All Windows Sockets error constants are biased by WSABASEERR from the "normal" - - {$EXTERNALSYM WSABASEERR} - WSABASEERR = 10000; - -// Windows Sockets definitions of regular Microsoft C error constants - - {$EXTERNALSYM WSAEINTR} - WSAEINTR = WSABASEERR+ 4; - {$EXTERNALSYM WSAEBADF} - WSAEBADF = WSABASEERR+ 9; - {$EXTERNALSYM WSAEACCES} - WSAEACCES = WSABASEERR+ 13; - {$EXTERNALSYM WSAEFAULT} - WSAEFAULT = WSABASEERR+ 14; - {$EXTERNALSYM WSAEINVAL} - WSAEINVAL = WSABASEERR+ 22; - {$EXTERNALSYM WSAEMFILE} - WSAEMFILE = WSABASEERR+ 24; - -// Windows Sockets definitions of regular Berkeley error constants - - {$EXTERNALSYM WSAEWOULDBLOCK} - WSAEWOULDBLOCK = WSABASEERR+ 35; - {$EXTERNALSYM WSAEINPROGRESS} - WSAEINPROGRESS = WSABASEERR+ 36; - {$EXTERNALSYM WSAEALREADY} - WSAEALREADY = WSABASEERR+ 37; - {$EXTERNALSYM WSAENOTSOCK} - WSAENOTSOCK = WSABASEERR+ 38; - {$EXTERNALSYM WSAEDESTADDRREQ} - WSAEDESTADDRREQ = WSABASEERR+ 39; - {$EXTERNALSYM WSAEMSGSIZE} - WSAEMSGSIZE = WSABASEERR+ 40; - {$EXTERNALSYM WSAEPROTOTYPE} - WSAEPROTOTYPE = WSABASEERR+ 41; - {$EXTERNALSYM WSAENOPROTOOPT} - WSAENOPROTOOPT = WSABASEERR+ 42; - {$EXTERNALSYM WSAEPROTONOSUPPORT} - WSAEPROTONOSUPPORT = WSABASEERR+ 43; - {$EXTERNALSYM WSAESOCKTNOSUPPORT} - WSAESOCKTNOSUPPORT = WSABASEERR+ 44; - {$EXTERNALSYM WSAEOPNOTSUPP} - WSAEOPNOTSUPP = WSABASEERR+ 45; - {$EXTERNALSYM WSAEPFNOSUPPORT} - WSAEPFNOSUPPORT = WSABASEERR+ 46; - {$EXTERNALSYM WSAEAFNOSUPPORT} - WSAEAFNOSUPPORT = WSABASEERR+ 47; - {$EXTERNALSYM WSAEADDRINUSE} - WSAEADDRINUSE = WSABASEERR+ 48; - {$EXTERNALSYM WSAEADDRNOTAVAIL} - WSAEADDRNOTAVAIL = WSABASEERR+ 49; - {$EXTERNALSYM WSAENETDOWN} - WSAENETDOWN = WSABASEERR+ 50; - {$EXTERNALSYM WSAENETUNREACH} - WSAENETUNREACH = WSABASEERR+ 51; - {$EXTERNALSYM WSAENETRESET} - WSAENETRESET = WSABASEERR+ 52; - {$EXTERNALSYM WSAECONNABORTED} - WSAECONNABORTED = WSABASEERR+ 53; - {$EXTERNALSYM WSAECONNRESET} - WSAECONNRESET = WSABASEERR+ 54; - {$EXTERNALSYM WSAENOBUFS} - WSAENOBUFS = WSABASEERR+ 55; - {$EXTERNALSYM WSAEISCONN} - WSAEISCONN = WSABASEERR+ 56; - {$EXTERNALSYM WSAENOTCONN} - WSAENOTCONN = WSABASEERR+ 57; - {$EXTERNALSYM WSAESHUTDOWN} - WSAESHUTDOWN = WSABASEERR+ 58; - {$EXTERNALSYM WSAETOOMANYREFS} - WSAETOOMANYREFS = WSABASEERR+ 59; - {$EXTERNALSYM WSAETIMEDOUT} - WSAETIMEDOUT = WSABASEERR+ 60; - {$EXTERNALSYM WSAECONNREFUSED} - WSAECONNREFUSED = WSABASEERR+ 61; - {$EXTERNALSYM WSAELOOP} - WSAELOOP = WSABASEERR+ 62; - {$EXTERNALSYM WSAENAMETOOLONG} - WSAENAMETOOLONG = WSABASEERR+ 63; - {$EXTERNALSYM WSAEHOSTDOWN} - WSAEHOSTDOWN = WSABASEERR+ 64; - {$EXTERNALSYM WSAEHOSTUNREACH} - WSAEHOSTUNREACH = WSABASEERR+ 65; - {$EXTERNALSYM wsaenotempty} - WSAENOTEMPTY = WSABASEERR+ 66; - {$EXTERNALSYM WSAEPROCLIM} - WSAEPROCLIM = WSABASEERR+ 67; - {$EXTERNALSYM WSAEUSERS} - WSAEUSERS = WSABASEERR+ 68; - {$EXTERNALSYM WSAEDQUOT} - WSAEDQUOT = WSABASEERR+ 69; - {$EXTERNALSYM WSAESTALE} - WSAESTALE = WSABASEERR+ 70; - {$EXTERNALSYM WSAEREMOTE} - WSAEREMOTE = WSABASEERR+ 71; - -// Extended Windows Sockets error constant definitions - - {$EXTERNALSYM WSASYSNOTREADY} - WSASYSNOTREADY = WSABASEERR+ 91; - {$EXTERNALSYM WSAVERNOTSUPPORTED} - WSAVERNOTSUPPORTED = WSABASEERR+ 92; - {$EXTERNALSYM WSANOTINITIALISED} - WSANOTINITIALISED = WSABASEERR+ 93; - {$EXTERNALSYM WSAEDISCON} - WSAEDISCON = WSABASEERR+101; - {$EXTERNALSYM WSAENOMORE} - WSAENOMORE = WSABASEERR+102; - {$EXTERNALSYM WSAECANCELLED} - WSAECANCELLED = WSABASEERR+103; - {$EXTERNALSYM WSAEINVALIDPROCTABLE} - WSAEINVALIDPROCTABLE = WSABASEERR+104; - {$EXTERNALSYM WSAEINVALIDPROVIDER} - WSAEINVALIDPROVIDER = WSABASEERR+105; - {$EXTERNALSYM WSAEPROVIDERFAILEDINIT} - WSAEPROVIDERFAILEDINIT = WSABASEERR+106; - {$EXTERNALSYM WSASYSCALLFAILURE} - WSASYSCALLFAILURE = WSABASEERR+107; - {$EXTERNALSYM WSASERVICE_NOT_FOUND} - WSASERVICE_NOT_FOUND = WSABASEERR+108; - {$EXTERNALSYM WSATYPE_NOT_FOUND} - WSATYPE_NOT_FOUND = WSABASEERR+109; - {$EXTERNALSYM WSA_E_NO_MORE} - WSA_E_NO_MORE = WSABASEERR+110; - {$EXTERNALSYM WSA_E_CANCELLED} - WSA_E_CANCELLED = WSABASEERR+111; - {$EXTERNALSYM WSAEREFUSED} - WSAEREFUSED = WSABASEERR+112; - - {$IFDEF WINCE} - WSAEDUPLICATE_NAME = WSABASEERR+900; - {$ENDIF} - -{ Error return codes from gethostbyname() and gethostbyaddr() - (when using the resolver). Note that these errors are - retrieved via WSAGetLastError() and must therefore follow - the rules for avoiding clashes with error numbers from - specific implementations or language run-time systems. - For this reason the codes are based at WSABASEERR+1001. - Note also that [WSA]NO_ADDRESS is defined only for - compatibility purposes. } - -// Authoritative Answer: Host not found - {$EXTERNALSYM WSAHOST_NOT_FOUND} - WSAHOST_NOT_FOUND = WSABASEERR+1001; - {$EXTERNALSYM HOST_NOT_FOUND} - HOST_NOT_FOUND = WSAHOST_NOT_FOUND; - -// Non-Authoritative: Host not found, or SERVERFAIL - {$EXTERNALSYM WSATRY_AGAIN} - WSATRY_AGAIN = WSABASEERR+1002; - {$EXTERNALSYM TRY_AGAIN} - TRY_AGAIN = WSATRY_AGAIN; - -// Non recoverable errors, FORMERR, REFUSED, NOTIMP - {$EXTERNALSYM WSANO_RECOVERY} - WSANO_RECOVERY = WSABASEERR+1003; - {$EXTERNALSYM NO_RECOVERY} - NO_RECOVERY = WSANO_RECOVERY; - -// Valid name, no data record of requested type - {$EXTERNALSYM WSANO_DATA} - WSANO_DATA = WSABASEERR+1004; - {$EXTERNALSYM NO_DATA} - NO_DATA = WSANO_DATA; - -// no address, look for MX record - {$EXTERNALSYM WSANO_ADDRESS} - WSANO_ADDRESS = WSANO_DATA; - {$EXTERNALSYM NO_ADDRESS} - NO_ADDRESS = WSANO_ADDRESS; - -// Define QOS related error return codes - - {$EXTERNALSYM WSA_QOS_RECEIVERS} - WSA_QOS_RECEIVERS = WSABASEERR+1005; // at least one reserve has arrived - {$EXTERNALSYM WSA_QOS_SENDERS} - WSA_QOS_SENDERS = WSABASEERR+1006; // at least one path has arrived - {$EXTERNALSYM WSA_QOS_NO_SENDERS} - WSA_QOS_NO_SENDERS = WSABASEERR+1007; // there are no senders - {$EXTERNALSYM WSA_QOS_NO_RECEIVERS} - WSA_QOS_NO_RECEIVERS = WSABASEERR+1008; // there are no receivers - {$EXTERNALSYM WSA_QOS_REQUEST_CONFIRMED} - WSA_QOS_REQUEST_CONFIRMED = WSABASEERR+1009; // reserve has been confirmed - {$EXTERNALSYM WSA_QOS_ADMISSION_FAILURE} - WSA_QOS_ADMISSION_FAILURE = WSABASEERR+1010; // error due to lack of resources - {$EXTERNALSYM WSA_QOS_POLICY_FAILURE} - WSA_QOS_POLICY_FAILURE = WSABASEERR+1011; // rejected for administrative reasons - bad credentials - {$EXTERNALSYM WSA_QOS_BAD_STYLE} - WSA_QOS_BAD_STYLE = WSABASEERR+1012; // unknown or conflicting style - {$EXTERNALSYM WSA_QOS_BAD_OBJECT} - WSA_QOS_BAD_OBJECT = WSABASEERR+1013; // problem with some part of the filterspec or providerspecific buffer in general - {$EXTERNALSYM WSA_QOS_TRAFFIC_CTRL_ERROR} - WSA_QOS_TRAFFIC_CTRL_ERROR = WSABASEERR+1014; // problem with some part of the flowspec - {$EXTERNALSYM WSA_QOS_GENERIC_ERROR} - WSA_QOS_GENERIC_ERROR = WSABASEERR+1015; // general error - {$EXTERNALSYM WSA_QOS_ESERVICETYPE} - WSA_QOS_ESERVICETYPE = WSABASEERR+1016; // invalid service type in flowspec - {$EXTERNALSYM WSA_QOS_EFLOWSPEC} - WSA_QOS_EFLOWSPEC = WSABASEERR+1017; // invalid flowspec - {$EXTERNALSYM WSA_QOS_EPROVSPECBUF} - WSA_QOS_EPROVSPECBUF = WSABASEERR+1018; // invalid provider specific buffer - {$EXTERNALSYM WSA_QOS_EFILTERSTYLE} - WSA_QOS_EFILTERSTYLE = WSABASEERR+1019; // invalid filter style - {$EXTERNALSYM WSA_QOS_EFILTERTYPE} - WSA_QOS_EFILTERTYPE = WSABASEERR+1020; // invalid filter type - {$EXTERNALSYM WSA_QOS_EFILTERCOUNT} - WSA_QOS_EFILTERCOUNT = WSABASEERR+1021; // incorrect number of filters - {$EXTERNALSYM WSA_QOS_EOBJLENGTH} - WSA_QOS_EOBJLENGTH = WSABASEERR+1022; // invalid object length - {$EXTERNALSYM WSA_QOS_EFLOWCOUNT} - WSA_QOS_EFLOWCOUNT = WSABASEERR+1023; // incorrect number of flows - {$EXTERNALSYM WSA_QOS_EUNKOWNPSOBJ} - WSA_QOS_EUNKOWNPSOBJ = WSABASEERR+1024; // unknown object in provider specific buffer - {$EXTERNALSYM WSA_QOS_EPOLICYOBJ} - WSA_QOS_EPOLICYOBJ = WSABASEERR+1025; // invalid policy object in provider specific buffer - {$EXTERNALSYM WSA_QOS_EFLOWDESC} - WSA_QOS_EFLOWDESC = WSABASEERR+1026; // invalid flow descriptor in the list - {$EXTERNALSYM WSA_QOS_EPSFLOWSPEC} - WSA_QOS_EPSFLOWSPEC = WSABASEERR+1027; // inconsistent flow spec in provider specific buffer - {$EXTERNALSYM WSA_QOS_EPSFILTERSPEC} - WSA_QOS_EPSFILTERSPEC = WSABASEERR+1028; // invalid filter spec in provider specific buffer - {$EXTERNALSYM WSA_QOS_ESDMODEOBJ} - WSA_QOS_ESDMODEOBJ = WSABASEERR+1029; // invalid shape discard mode object in provider specific buffer - {$EXTERNALSYM WSA_QOS_ESHAPERATEOBJ} - WSA_QOS_ESHAPERATEOBJ = WSABASEERR+1030; // invalid shaping rate object in provider specific buffer - {$EXTERNALSYM WSA_QOS_RESERVED_PETYPE} - WSA_QOS_RESERVED_PETYPE = WSABASEERR+1031; // reserved policy element in provider specific buffer - - -{ WinSock 2 extension -- new error codes and type definition } - {$EXTERNALSYM WSA_IO_PENDING} - WSA_IO_PENDING = ERROR_IO_PENDING; - {$EXTERNALSYM WSA_IO_INCOMPLETE} - WSA_IO_INCOMPLETE = ERROR_IO_INCOMPLETE; - {$EXTERNALSYM WSA_INVALID_HANDLE} - WSA_INVALID_HANDLE = ERROR_INVALID_HANDLE; - {$EXTERNALSYM WSA_INVALID_PARAMETER} - WSA_INVALID_PARAMETER = ERROR_INVALID_PARAMETER; - {$EXTERNALSYM WSA_NOT_ENOUGH_MEMORY} - WSA_NOT_ENOUGH_MEMORY = ERROR_NOT_ENOUGH_MEMORY; - {$EXTERNALSYM WSA_OPERATION_ABORTED} - WSA_OPERATION_ABORTED = ERROR_OPERATION_ABORTED; - {$EXTERNALSYM WSA_INVALID_EVENT} - WSA_INVALID_EVENT = WSAEVENT(nil); - {$EXTERNALSYM WSA_MAXIMUM_WAIT_EVENTS} - WSA_MAXIMUM_WAIT_EVENTS = MAXIMUM_WAIT_OBJECTS; - {$EXTERNALSYM WSA_WAIT_FAILED} - WSA_WAIT_FAILED = $FFFFFFFF; - {$EXTERNALSYM WSA_WAIT_EVENT_0} - WSA_WAIT_EVENT_0 = WAIT_OBJECT_0; - {$EXTERNALSYM WSA_WAIT_IO_COMPLETION} - WSA_WAIT_IO_COMPLETION = WAIT_IO_COMPLETION; - {$EXTERNALSYM WSA_WAIT_TIMEOUT} - WSA_WAIT_TIMEOUT = WAIT_TIMEOUT; - {$EXTERNALSYM WSA_INFINITE} - WSA_INFINITE = INFINITE; - -{ Windows Sockets errors redefined as regular Berkeley error constants. - These are commented out in Windows NT to avoid conflicts with errno.h. - Use the WSA constants instead. } - - {$EXTERNALSYM EWOULDBLOCK} - EWOULDBLOCK = WSAEWOULDBLOCK; - {$EXTERNALSYM EINPROGRESS} - EINPROGRESS = WSAEINPROGRESS; - {$EXTERNALSYM EALREADY} - EALREADY = WSAEALREADY; - {$EXTERNALSYM ENOTSOCK} - ENOTSOCK = WSAENOTSOCK; - {$EXTERNALSYM EDESTADDRREQ} - EDESTADDRREQ = WSAEDESTADDRREQ; - {$EXTERNALSYM EMSGSIZE} - EMSGSIZE = WSAEMSGSIZE; - {$EXTERNALSYM EPROTOTYPE} - EPROTOTYPE = WSAEPROTOTYPE; - {$EXTERNALSYM ENOPROTOOPT} - ENOPROTOOPT = WSAENOPROTOOPT; - {$EXTERNALSYM EPROTONOSUPPORT} - EPROTONOSUPPORT = WSAEPROTONOSUPPORT; - {$EXTERNALSYM ESOCKTNOSUPPORT} - ESOCKTNOSUPPORT = WSAESOCKTNOSUPPORT; - {$EXTERNALSYM EOPNOTSUPP} - EOPNOTSUPP = WSAEOPNOTSUPP; - {$EXTERNALSYM EPFNOSUPPORT} - EPFNOSUPPORT = WSAEPFNOSUPPORT; - {$EXTERNALSYM EAFNOSUPPORT} - EAFNOSUPPORT = WSAEAFNOSUPPORT; - {$EXTERNALSYM EADDRINUSE} - EADDRINUSE = WSAEADDRINUSE; - {$EXTERNALSYM EADDRNOTAVAIL} - EADDRNOTAVAIL = WSAEADDRNOTAVAIL; - {$EXTERNALSYM ENETDOWN} - ENETDOWN = WSAENETDOWN; - {$EXTERNALSYM ENETUNREACH} - ENETUNREACH = WSAENETUNREACH; - {$EXTERNALSYM ENETRESET} - ENETRESET = WSAENETRESET; - {$EXTERNALSYM ECONNABORTED} - ECONNABORTED = WSAECONNABORTED; - {$EXTERNALSYM ECONNRESET} - ECONNRESET = WSAECONNRESET; - {$EXTERNALSYM ENOBUFS} - ENOBUFS = WSAENOBUFS; - {$EXTERNALSYM EISCONN} - EISCONN = WSAEISCONN; - {$EXTERNALSYM ENOTCONN} - ENOTCONN = WSAENOTCONN; - {$EXTERNALSYM ESHUTDOWN} - ESHUTDOWN = WSAESHUTDOWN; - {$EXTERNALSYM ETOOMANYREFS} - ETOOMANYREFS = WSAETOOMANYREFS; - {$EXTERNALSYM ETIMEDOUT} - ETIMEDOUT = WSAETIMEDOUT; - {$EXTERNALSYM ECONNREFUSED} - ECONNREFUSED = WSAECONNREFUSED; - {$EXTERNALSYM ELOOP} - ELOOP = WSAELOOP; - {$EXTERNALSYM ENAMETOOLONG} - ENAMETOOLONG = WSAENAMETOOLONG; - {$EXTERNALSYM EHOSTDOWN} - EHOSTDOWN = WSAEHOSTDOWN; - {$EXTERNALSYM EHOSTUNREACH} - EHOSTUNREACH = WSAEHOSTUNREACH; - {$EXTERNALSYM ENOTEMPTY} - ENOTEMPTY = WSAENOTEMPTY; - {$EXTERNALSYM EPROCLIM} - EPROCLIM = WSAEPROCLIM; - {$EXTERNALSYM EUSERS} - EUSERS = WSAEUSERS; - {$EXTERNALSYM EDQUOT} - EDQUOT = WSAEDQUOT; - {$EXTERNALSYM ESTALE} - ESTALE = WSAESTALE; - {$EXTERNALSYM EREMOTE} - EREMOTE = WSAEREMOTE; - - {$EXTERNALSYM WSADESCRIPTION_LEN} - WSADESCRIPTION_LEN = 256; - {$EXTERNALSYM WSASYS_STATUS_LEN} - WSASYS_STATUS_LEN = 128; - -type - {$EXTERNALSYM WSADATA} - WSADATA = record - wVersion : Word; - wHighVersion : Word; - {$IFDEF _WIN64} - iMaxSockets : Word; - iMaxUdpDg : Word; - lpVendorInfo : PIdAnsiChar; - szDescription : array[0..WSADESCRIPTION_LEN] of TIdAnsiChar; - szSystemStatus : array[0..WSASYS_STATUS_LEN] of TIdAnsiChar; - {$ELSE} - szDescription : array[0..WSADESCRIPTION_LEN] of TIdAnsiChar; - szSystemStatus : array[0..WSASYS_STATUS_LEN] of TIdAnsiChar; - iMaxSockets : Word; - iMaxUdpDg : Word; - lpVendorInfo : PIdAnsiChar; - {$ENDIF} - end; - {$NODEFINE TWSAData} - TWSAData = WSADATA; - {$NODEFINE PWSAData} - PWSAData = ^TWSAData; - {$EXTERNALSYM LPWSADATA} - LPWSADATA = PWSAData; - - {$EXTERNALSYM WSAOVERLAPPED} - WSAOVERLAPPED = TOverlapped; - {$NODEFINE TWSAOverlapped} - TWSAOverlapped = WSAOVERLAPPED; - {$NODEFINE PWSAOverlapped} - PWSAOverlapped = ^TWSAOverlapped; - {$EXTERNALSYM LPWSAOVERLAPPED} - LPWSAOVERLAPPED = PWSAOverlapped; - {$IFNDEF WINCE} - {$EXTERNALSYM WSC_PROVIDER_INFO_TYPE} - {$EXTERNALSYM ProviderInfoLspCategories} - {$EXTERNALSYM ProviderInfoAudit} - WSC_PROVIDER_INFO_TYPE = ( - ProviderInfoLspCategories, - ProviderInfoAudit); - {$ENDIF} - -{ WinSock 2 extension -- WSABUF and QOS struct, include qos.h } -{ to pull in FLOWSPEC and related definitions } - - {$EXTERNALSYM WSABUF} - WSABUF = record - len: u_long; { the length of the buffer } - buf: PIdAnsiChar; { the pointer to the buffer } - end; - {$NODEFINE TWSABuf} - TWSABuf = WSABUF; - {$NODEFINE PWSABuf} - PWSABuf = ^TWSABuf; - {$EXTERNALSYM LPWSABUF} - LPWSABUF = PWSABUF; - - {$EXTERNALSYM SERVICETYPE} - SERVICETYPE = ULONG; - {$NODEFINE TServiceType} - TServiceType = SERVICETYPE; - - {$EXTERNALSYM FLOWSPEC} - FLOWSPEC = record - TokenRate, // In Bytes/sec - TokenBucketSize, // In Bytes - PeakBandwidth, // In Bytes/sec - Latency, // In microseconds - DelayVariation : ULONG; // In microseconds - ServiceType : TServiceType; - MaxSduSize, MinimumPolicedSize : ULONG;// In Bytes - end; - {$NODEFINE TFlowSpec} - TFlowSpec = FLOWSPEC; - {$EXTERNALSYM PFLOWSPEC} - PFLOWSPEC = ^TFlowSpec; - {$EXTERNALSYM LPFLOWSPEC} - LPFLOWSPEC = PFLOWSPEC; - - {$EXTERNALSYM QOS} - QOS = record - SendingFlowspec: TFlowSpec; { the flow spec for data sending } - ReceivingFlowspec: TFlowSpec; { the flow spec for data receiving } - ProviderSpecific: TWSABuf; { additional provider specific stuff } - end; - {$NODEFINE TQualityOfService} - TQualityOfService = QOS; - {$NODEFINE PQOS} - PQOS = ^QOS; - {$EXTERNALSYM LPQOS} - LPQOS = PQOS; - -const - {$EXTERNALSYM SERVICETYPE_NOTRAFFIC} - SERVICETYPE_NOTRAFFIC = $00000000; // No data in this direction - {$EXTERNALSYM SERVICETYPE_BESTEFFORT} - SERVICETYPE_BESTEFFORT = $00000001; // Best Effort - {$EXTERNALSYM SERVICETYPE_CONTROLLEDLOAD} - SERVICETYPE_CONTROLLEDLOAD = $00000002; // Controlled Load - {$EXTERNALSYM SERVICETYPE_GUARANTEED} - SERVICETYPE_GUARANTEED = $00000003; // Guaranteed - {$EXTERNALSYM SERVICETYPE_NETWORK_UNAVAILABLE} - SERVICETYPE_NETWORK_UNAVAILABLE = $00000004; // Used to notify change to user - {$EXTERNALSYM SERVICETYPE_GENERAL_INFORMATION} - SERVICETYPE_GENERAL_INFORMATION = $00000005; // corresponds to "General Parameters" defined by IntServ - {$EXTERNALSYM SERVICETYPE_NOCHANGE} - SERVICETYPE_NOCHANGE = $00000006; // used to indicate that the flow spec contains no change from any previous one -// to turn on immediate traffic control, OR this flag with the ServiceType field in the FLOWSPEC - {$EXTERNALSYM SERVICE_IMMEDIATE_TRAFFIC_CONTROL} - SERVICE_IMMEDIATE_TRAFFIC_CONTROL = $80000000; - -// WinSock 2 extension -- manifest constants for return values of the condition function - {$EXTERNALSYM CF_ACCEPT} - CF_ACCEPT = $0000; - {$EXTERNALSYM CF_REJECT} - CF_REJECT = $0001; - {$EXTERNALSYM CF_DEFER} - CF_DEFER = $0002; - -// WinSock 2 extension -- manifest constants for shutdown() - {$EXTERNALSYM SD_RECEIVE} - SD_RECEIVE = $00; - {$EXTERNALSYM SD_SEND} - SD_SEND = $01; - {$EXTERNALSYM SD_BOTH} - SD_BOTH = $02; - -// WinSock 2 extension -- data type and manifest constants for socket groups - {$EXTERNALSYM SG_UNCONSTRAINED_GROUP} - SG_UNCONSTRAINED_GROUP = $01; - {$EXTERNALSYM SG_CONSTRAINED_GROUP} - SG_CONSTRAINED_GROUP = $02; - -type - {$EXTERNALSYM GROUP} - GROUP = DWORD; - {$EXTERNALSYM PGROUP} - PGROUP = ^GROUP; - -// WinSock 2 extension -- data type for WSAEnumNetworkEvents() - {$EXTERNALSYM WSANETWORKEVENTS} - WSANETWORKEVENTS = record - lNetworkEvents: LongInt; - iErrorCode: Array[0..FD_MAX_EVENTS-1] of Integer; - end; - {$NODEFINE TWSANetworkEvents} - TWSANetworkEvents = WSANETWORKEVENTS; - {$NODEFINE PWSANetworkEvents} - PWSANetworkEvents = ^TWSANetworkEvents; - {$EXTERNALSYM LPWSANETWORKEVENTS} - LPWSANETWORKEVENTS = PWSANetworkEvents; - -//TransmitFile types used for the TransmitFile API function in WinNT/2000/XP -//not sure why its defined in WinCE when TransmitFile is not available. - {$IFNDEF NO_REDECLARE} - {$EXTERNALSYM TRANSMIT_FILE_BUFFERS} - TRANSMIT_FILE_BUFFERS = record - Head: Pointer; - HeadLength: DWORD; - Tail: Pointer; - TailLength: DWORD; - end; - {$NODEFINE TTransmitFileBuffers} - TTransmitFileBuffers = TRANSMIT_FILE_BUFFERS; - {$NODEFINE PTransmitFileBuffers} - PTransmitFileBuffers = ^TTransmitFileBuffers; - {$ENDIF} - {$EXTERNALSYM LPTRANSMIT_FILE_BUFFERS} - LPTRANSMIT_FILE_BUFFERS = PTransmitFileBuffers; - -const - {$EXTERNALSYM TP_ELEMENT_MEMORY} - TP_ELEMENT_MEMORY = 1; - {$EXTERNALSYM TP_ELEMENT_FILE} - TP_ELEMENT_FILE = 2; - {$EXTERNALSYM TP_ELEMENT_EOP} - TP_ELEMENT_EOP = 4; - - {$EXTERNALSYM TP_DISCONNECT} - TP_DISCONNECT = TF_DISCONNECT; - {$EXTERNALSYM TP_REUSE_SOCKET} - TP_REUSE_SOCKET = TF_REUSE_SOCKET; - {$EXTERNALSYM TP_USE_DEFAULT_WORKER} - TP_USE_DEFAULT_WORKER = TF_USE_DEFAULT_WORKER; - {$EXTERNALSYM TP_USE_SYSTEM_THREAD} - TP_USE_SYSTEM_THREAD = TF_USE_SYSTEM_THREAD; - {$EXTERNALSYM TP_USE_KERNEL_APC} - TP_USE_KERNEL_APC = TF_USE_KERNEL_APC; - -type - {$EXTERNALSYM TRANSMIT_PACKETS_ELEMENT} - TRANSMIT_PACKETS_ELEMENT = record - dwElFlags: ULONG; - cLength: ULONG; - case Integer of - 1: (nFileOffset: TLargeInteger; - hFile: THandle); - 2: (pBuffer: Pointer); - end; - {$NODEFINE TTransmitPacketsElement} - TTransmitPacketsElement = TRANSMIT_PACKETS_ELEMENT; - {$NODEFINE PTransmitPacketsElement} - PTransmitPacketsElement = ^TTransmitPacketsElement; - {$NODEFINE LPTransmitPacketsElement} - LPTransmitPacketsElement = PTransmitPacketsElement; - - {$EXTERNALSYM PTRANSMIT_PACKETS_ELEMENT} - PTRANSMIT_PACKETS_ELEMENT = ^TTransmitPacketsElement; - {$EXTERNALSYM LPTRANSMIT_PACKETS_ELEMENT} - LPTRANSMIT_PACKETS_ELEMENT = PTRANSMIT_PACKETS_ELEMENT; - -// WinSock 2 extension -- WSAPROTOCOL_INFO structure - -{$IFNDEF HAS_LPGUID} -type - {$IFNDEF HAS_PGUID} - {$NODEFINE PGUID} - PGUID = ^TGUID; - {$ENDIF} - {$EXTERNALSYM LPGUID} - LPGUID = PGUID; -{$ENDIF} - -// WinSock 2 extension -- WSAPROTOCOL_INFO manifest constants - -const - {$EXTERNALSYM MAX_PROTOCOL_CHAIN} - MAX_PROTOCOL_CHAIN = 7; - {$EXTERNALSYM BASE_PROTOCOL} - BASE_PROTOCOL = 1; - {$EXTERNALSYM LAYERED_PROTOCOL} - LAYERED_PROTOCOL = 0; - {$EXTERNALSYM WSAPROTOCOL_LEN} - WSAPROTOCOL_LEN = 255; - -type - {$EXTERNALSYM WSAPROTOCOLCHAIN} - WSAPROTOCOLCHAIN = record - ChainLen: Integer; // the length of the chain, - // length = 0 means layered protocol, - // length = 1 means base protocol, - // length > 1 means protocol chain - ChainEntries: Array[0..MAX_PROTOCOL_CHAIN-1] of DWORD; // a list of dwCatalogEntryIds - end; - {$NODEFINE TWSAProtocolChain} - TWSAProtocolChain = WSAPROTOCOLCHAIN; - {$EXTERNALSYM LPWSAPROTOCOLCHAIN} - LPWSAPROTOCOLCHAIN = ^TWSAProtocolChain; - -type - {$EXTERNALSYM WSAPROTOCOL_INFOA} - WSAPROTOCOL_INFOA = record - dwServiceFlags1: DWORD; - dwServiceFlags2: DWORD; - dwServiceFlags3: DWORD; - dwServiceFlags4: DWORD; - dwProviderFlags: DWORD; - ProviderId: TGUID; - dwCatalogEntryId: DWORD; - ProtocolChain: TWSAProtocolChain; - iVersion: Integer; - iAddressFamily: Integer; - iMaxSockAddr: Integer; - iMinSockAddr: Integer; - iSocketType: Integer; - iProtocol: Integer; - iProtocolMaxOffset: Integer; - iNetworkByteOrder: Integer; - iSecurityScheme: Integer; - dwMessageSize: DWORD; - dwProviderReserved: DWORD; - szProtocol: Array[0..WSAPROTOCOL_LEN+1-1] of TIdAnsiChar; - end; - {$NODEFINE TWSAProtocol_InfoA} - TWSAProtocol_InfoA = WSAPROTOCOL_INFOA; - {$NODEFINE PWSAProtocol_InfoA} - PWSAProtocol_InfoA = ^WSAPROTOCOL_INFOA; - {$EXTERNALSYM LPWSAPROTOCOL_INFOA} - LPWSAPROTOCOL_INFOA = PWSAProtocol_InfoA; - - {$EXTERNALSYM WSAPROTOCOL_INFOW} - WSAPROTOCOL_INFOW = record - dwServiceFlags1: DWORD; - dwServiceFlags2: DWORD; - dwServiceFlags3: DWORD; - dwServiceFlags4: DWORD; - dwProviderFlags: DWORD; - ProviderId: TGUID; - dwCatalogEntryId: DWORD; - ProtocolChain: TWSAProtocolChain; - iVersion: Integer; - iAddressFamily: Integer; - iMaxSockAddr: Integer; - iMinSockAddr: Integer; - iSocketType: Integer; - iProtocol: Integer; - iProtocolMaxOffset: Integer; - iNetworkByteOrder: Integer; - iSecurityScheme: Integer; - dwMessageSize: DWORD; - dwProviderReserved: DWORD; - szProtocol: Array[0..WSAPROTOCOL_LEN+1-1] of WideChar; - end; - {$NODEFINE TWSAProtocol_InfoW} - TWSAProtocol_InfoW = WSAPROTOCOL_INFOW; - {$NODEFINE PWSAProtocol_InfoW} - PWSAProtocol_InfoW = ^TWSAProtocol_InfoW; - {$EXTERNALSYM LPWSAPROTOCOL_INFOW} - LPWSAPROTOCOL_INFOW = PWSAProtocol_InfoW; - - {$EXTERNALSYM WSAPROTOCOL_INFO} - {$EXTERNALSYM LPWSAPROTOCOL_INFO} - {$NODEFINE TWSAProtocol_Info} - {$NODEFINE PWSAProtocol_Info} - {$IFDEF UNICODE} - WSAPROTOCOL_INFO = TWSAProtocol_InfoW; - TWSAProtocol_Info = TWSAProtocol_InfoW; - PWSAProtocol_Info = PWSAProtocol_InfoW; - LPWSAPROTOCOL_INFO = PWSAProtocol_InfoW; - {$ELSE} - WSAPROTOCOL_INFO = TWSAProtocol_InfoA; - TWSAProtocol_Info = TWSAProtocol_InfoA; - PWSAProtocol_Info = PWSAProtocol_InfoA; - LPWSAPROTOCOL_INFO = PWSAProtocol_InfoA; - {$ENDIF} - -const -// flag bit definitions for dwProviderFlags - {$EXTERNALSYM PFL_MULTIPLE_PROTO_ENTRIES} - PFL_MULTIPLE_PROTO_ENTRIES = $00000001; - {$EXTERNALSYM PFL_RECOMMENTED_PROTO_ENTRY} - PFL_RECOMMENTED_PROTO_ENTRY = $00000002; - {$EXTERNALSYM PFL_HIDDEN} - PFL_HIDDEN = $00000004; - {$EXTERNALSYM PFL_MATCHES_PROTOCOL_ZERO} - PFL_MATCHES_PROTOCOL_ZERO = $00000008; - -// flag bit definitions for dwServiceFlags1 - {$EXTERNALSYM XP1_CONNECTIONLESS} - XP1_CONNECTIONLESS = $00000001; - {$EXTERNALSYM XP1_GUARANTEED_DELIVERY} - XP1_GUARANTEED_DELIVERY = $00000002; - {$EXTERNALSYM XP1_GUARANTEED_ORDER} - XP1_GUARANTEED_ORDER = $00000004; - {$EXTERNALSYM XP1_MESSAGE_ORIENTED} - XP1_MESSAGE_ORIENTED = $00000008; - {$EXTERNALSYM XP1_PSEUDO_STREAM} - XP1_PSEUDO_STREAM = $00000010; - {$EXTERNALSYM XP1_GRACEFUL_CLOSE} - XP1_GRACEFUL_CLOSE = $00000020; - {$EXTERNALSYM XP1_EXPEDITED_DATA} - XP1_EXPEDITED_DATA = $00000040; - {$EXTERNALSYM XP1_CONNECT_DATA} - XP1_CONNECT_DATA = $00000080; - {$EXTERNALSYM XP1_DISCONNECT_DATA} - XP1_DISCONNECT_DATA = $00000100; - {$EXTERNALSYM XP1_SUPPORT_BROADCAST} - XP1_SUPPORT_BROADCAST = $00000200; - {$EXTERNALSYM XP1_SUPPORT_MULTIPOINT} - XP1_SUPPORT_MULTIPOINT = $00000400; - {$EXTERNALSYM XP1_MULTIPOINT_CONTROL_PLANE} - XP1_MULTIPOINT_CONTROL_PLANE = $00000800; - {$EXTERNALSYM XP1_MULTIPOINT_DATA_PLANE} - XP1_MULTIPOINT_DATA_PLANE = $00001000; - {$EXTERNALSYM XP1_QOS_SUPPORTED} - XP1_QOS_SUPPORTED = $00002000; - {$EXTERNALSYM XP1_INTERRUPT} - XP1_INTERRUPT = $00004000; - {$EXTERNALSYM XP1_UNI_SEND} - XP1_UNI_SEND = $00008000; - {$EXTERNALSYM XP1_UNI_RECV} - XP1_UNI_RECV = $00010000; - {$EXTERNALSYM XP1_IFS_HANDLES} - XP1_IFS_HANDLES = $00020000; - {$EXTERNALSYM XP1_PARTIAL_MESSAGE} - XP1_PARTIAL_MESSAGE = $00040000; - - {$EXTERNALSYM BIGENDIAN} - BIGENDIAN = $0000; - {$EXTERNALSYM LITTLEENDIAN} - LITTLEENDIAN = $0001; - - {$EXTERNALSYM SECURITY_PROTOCOL_NONE} - SECURITY_PROTOCOL_NONE = $0000; - -// WinSock 2 extension -- manifest constants for WSAJoinLeaf() - {$EXTERNALSYM JL_SENDER_ONLY} - JL_SENDER_ONLY = $01; - {$EXTERNALSYM JL_RECEIVER_ONLY} - JL_RECEIVER_ONLY = $02; - {$EXTERNALSYM JL_BOTH} - JL_BOTH = $04; - -// WinSock 2 extension -- manifest constants for WSASocket() - {$EXTERNALSYM WSA_FLAG_OVERLAPPED} - WSA_FLAG_OVERLAPPED = $01; - {$EXTERNALSYM WSA_FLAG_MULTIPOINT_C_ROOT} - WSA_FLAG_MULTIPOINT_C_ROOT = $02; - {$EXTERNALSYM WSA_FLAG_MULTIPOINT_C_LEAF} - WSA_FLAG_MULTIPOINT_C_LEAF = $04; - {$EXTERNALSYM WSA_FLAG_MULTIPOINT_D_ROOT} - WSA_FLAG_MULTIPOINT_D_ROOT = $08; - {$EXTERNALSYM WSA_FLAG_MULTIPOINT_D_LEAF} - WSA_FLAG_MULTIPOINT_D_LEAF = $10; - -// WinSock 2 extension -- manifest constants for WSAIoctl() - {$EXTERNALSYM IOC_UNIX} - IOC_UNIX = $00000000; - {$EXTERNALSYM IOC_WS2} - IOC_WS2 = $08000000; - {$EXTERNALSYM IOC_PROTOCOL} - IOC_PROTOCOL = $10000000; - {$EXTERNALSYM IOC_VENDOR} - IOC_VENDOR = $18000000; - - {$IFNDEF WINCE} -///* -// * WSK-specific IO control codes are Winsock2 codes with the highest-order -// * 3 bits of the Vendor/AddressFamily-specific field set to 1. -// */ - {$EXTERNALSYM IOC_WSK} - IOC_WSK = IOC_WS2 or $07000000; - {$ENDIF} - {$EXTERNALSYM SIO_ASSOCIATE_HANDLE} - SIO_ASSOCIATE_HANDLE = DWORD(IOC_IN or IOC_WS2 or 1); - {$EXTERNALSYM SIO_ENABLE_CIRCULAR_QUEUEING} - SIO_ENABLE_CIRCULAR_QUEUEING = DWORD(IOC_VOID or IOC_WS2 or 2); - {$EXTERNALSYM SIO_FIND_ROUTE} - SIO_FIND_ROUTE = DWORD(IOC_OUT or IOC_WS2 or 3); - {$EXTERNALSYM SIO_FLUSH} - SIO_FLUSH = DWORD(IOC_VOID or IOC_WS2 or 4); - {$EXTERNALSYM SIO_GET_BROADCAST_ADDRESS} - SIO_GET_BROADCAST_ADDRESS = DWORD(IOC_OUT or IOC_WS2 or 5); - {$EXTERNALSYM SIO_GET_EXTENSION_FUNCTION_POINTER} - SIO_GET_EXTENSION_FUNCTION_POINTER = DWORD(IOC_INOUT or IOC_WS2 or 6); - {$EXTERNALSYM SIO_GET_QOS} - SIO_GET_QOS = DWORD(IOC_INOUT or IOC_WS2 or 7); - {$EXTERNALSYM SIO_GET_GROUP_QOS} - SIO_GET_GROUP_QOS = DWORD(IOC_INOUT or IOC_WS2 or 8); - {$EXTERNALSYM SIO_MULTIPOINT_LOOPBACK} - SIO_MULTIPOINT_LOOPBACK = DWORD(IOC_IN or IOC_WS2 or 9); - {$EXTERNALSYM SIO_MULTICAST_SCOPE} - SIO_MULTICAST_SCOPE = DWORD(IOC_IN or IOC_WS2 or 10); - {$EXTERNALSYM SIO_SET_QOS} - SIO_SET_QOS = DWORD(IOC_IN or IOC_WS2 or 11); - {$EXTERNALSYM SIO_SET_GROUP_QOS} - SIO_SET_GROUP_QOS = DWORD(IOC_IN or IOC_WS2 or 12); - {$EXTERNALSYM SIO_TRANSLATE_HANDLE} - SIO_TRANSLATE_HANDLE = DWORD(IOC_INOUT or IOC_WS2 or 13); - {$EXTERNALSYM SIO_ROUTING_INTERFACE_QUERY} - SIO_ROUTING_INTERFACE_QUERY = DWORD(IOC_INOUT or IOC_WS2 or 20); - {$EXTERNALSYM SIO_ROUTING_INTERFACE_CHANGE} - SIO_ROUTING_INTERFACE_CHANGE = DWORD(IOC_IN or IOC_WS2 or 21); - {$EXTERNALSYM SIO_ADDRESS_LIST_QUERY} - SIO_ADDRESS_LIST_QUERY = DWORD(IOC_OUT or IOC_WS2 or 22); // see below SOCKET_ADDRESS_LIST - {$EXTERNALSYM SIO_ADDRESS_LIST_CHANGE} - SIO_ADDRESS_LIST_CHANGE = DWORD(IOC_VOID or IOC_WS2 or 23); - {$EXTERNALSYM SIO_QUERY_TARGET_PNP_HANDLE} - SIO_QUERY_TARGET_PNP_HANDLE = DWORD(IOC_OUT or IOC_WS2 or 24); - {$EXTERNALSYM SIO_NSP_NOTIFY_CHANGE} - SIO_NSP_NOTIFY_CHANGE = DWORD(IOC_IN or IOC_WS2 or 25); - {$EXTERNALSYM SIO_ADDRESS_LIST_SORT} - SIO_ADDRESS_LIST_SORT = DWORD(IOC_INOUT or IOC_WS2 or 25); - {$EXTERNALSYM SIO_QUERY_RSS_PROCESSOR_INFO} - SIO_QUERY_RSS_PROCESSOR_INFO = DWORD(IOC_INOUT or IOC_WS2 or 37); - - {$IFNDEF WINCE} - {$EXTERNALSYM SIO_RESERVED_1} - SIO_RESERVED_1 = DWORD(IOC_IN or IOC_WS2 or 26); - {$EXTERNALSYM SIO_RESERVED_2} - SIO_RESERVED_2 = DWORD(IOC_IN or IOC_WS2 or 33); - {$ENDIF} - -// WinSock 2 extension -- manifest constants for SIO_TRANSLATE_HANDLE ioctl - {$EXTERNALSYM TH_NETDEV} - TH_NETDEV = $00000001; - {$EXTERNALSYM TH_TAPI} - TH_TAPI = $00000002; - -type -// Manifest constants and type definitions related to name resolution and -// registration (RNR) API - {$IFNDEF NO_REDECLARE} - {$EXTERNALSYM BLOB} - BLOB = record - cbSize : U_LONG; - pBlobData : PBYTE; - end; - {$NODEFINE TBLOB} - TBLOB = BLOB; - {$NODEFINE PBLOB} - PBLOB = ^TBLOB; - {$ENDIF} - {$EXTERNALSYM LPBLOB} - LPBLOB = PBLOB; - - {$EXTERNALSYM RIO_BUFFERID} - RIO_BUFFERID = Pointer; - {$EXTERNALSYM RIO_CQ} - RIO_CQ = Pointer; - {$EXTERNALSYM RIO_RQ} - RIO_RQ = Pointer; - - {$EXTERNALSYM PRIO_BUFFERID} - PRIO_BUFFERID = ^RIO_BUFFERID; - {$EXTERNALSYM _RIORESULT} - _RIORESULT = record - Status : LONG; - BytesTransferred : ULONG; - SocketContext : ULONGLONG; - RequestContext : ULONGLONG; - end; - {$EXTERNALSYM RIORESULT} - RIORESULT = _RIORESULT; - {$EXTERNALSYM PRIORESULT} - PRIORESULT = ^RIORESULT; - {$EXTERNALSYM _RIO_BUF} - _RIO_BUF = record - BufferId : RIO_BUFFERID; - Offset : ULONG; - Length : ULONG; - end; - {$EXTERNALSYM RIO_BUF} - RIO_BUF = _RIO_BUF; - {$EXTERNALSYM PRIO_BUF} - PRIO_BUF = ^RIO_BUF; - {$EXTERNALSYM _RIO_CMSG_BUFFER} - _RIO_CMSG_BUFFER = record - TotalLength : ULONG; - //* followed by CMSG_HDR */ - end; - {$EXTERNALSYM RIO_CMSG_BUFFER} - RIO_CMSG_BUFFER = _RIO_CMSG_BUFFER; - {$EXTERNALSYM PRIO_CMSG_BUFFER} - PRIO_CMSG_BUFFER = ^RIO_CMSG_BUFFER; - -// Service Install Flags - -const - {$EXTERNALSYM SERVICE_MULTIPLE} - SERVICE_MULTIPLE = $00000001; - -// & name spaces - {$EXTERNALSYM NS_ALL} - NS_ALL = 0; - - {$EXTERNALSYM NS_SAP} - NS_SAP = 1; - {$EXTERNALSYM NS_NDS} - NS_NDS = 2; - {$EXTERNALSYM NS_PEER_BROWSE} - NS_PEER_BROWSE = 3; - {$EXTERNALSYM NS_SLP} - NS_SLP = 5; - {$EXTERNALSYM NS_DHCP} - NS_DHCP = 6; - - {$EXTERNALSYM NS_TCPIP_LOCAL} - NS_TCPIP_LOCAL = 10; - {$EXTERNALSYM NS_TCPIP_HOSTS} - NS_TCPIP_HOSTS = 11; - {$EXTERNALSYM NS_DNS} - NS_DNS = 12; - {$EXTERNALSYM NS_NETBT} - NS_NETBT = 13; - {$EXTERNALSYM NS_WINS} - NS_WINS = 14; - {$EXTERNALSYM NS_NLA} - NS_NLA = 15; //* Network Location Awareness*/ - WindowsXP - {$EXTERNALSYM NS_BTH} - NS_BTH = 16; //* Bluetooth SDP Namespace */ - Windows Vista - - {$EXTERNALSYM NS_NBP} - NS_NBP = 20; - - {$EXTERNALSYM NS_MS} - NS_MS = 30; - {$EXTERNALSYM NS_STDA} - NS_STDA = 31; - {$EXTERNALSYM NS_NTDS} - NS_NTDS = 32; - - //Windows Vista namespaces - {$EXTERNALSYM NS_EMAIL} - NS_EMAIL = 37; - {$EXTERNALSYM NS_PNRPNAME} - NS_PNRPNAME = 38; - {$EXTERNALSYM NS_PNRPCLOUD} - NS_PNRPCLOUD = 39; - // - - {$EXTERNALSYM NS_X500} - NS_X500 = 40; - {$EXTERNALSYM NS_NIS} - NS_NIS = 41; - {$EXTERNALSYM NS_NISPLUS} - NS_NISPLUS = 42; - - {$EXTERNALSYM NS_WRQ} - NS_WRQ = 50; - - {$EXTERNALSYM NS_NETDES} - NS_NETDES = 60; // Network Designers Limited - -{ Resolution flags for WSAGetAddressByName(). - Note these are also used by the 1.1 API GetAddressByName, so leave them around. } - {$EXTERNALSYM RES_UNUSED_1} - RES_UNUSED_1 = $00000001; - {$EXTERNALSYM RES_FLUSH_CACHE} - RES_FLUSH_CACHE = $00000002; - {$EXTERNALSYM RES_SERVICE} - RES_SERVICE = $00000004; - {$EXTERNALSYM RIO_MSG_DONT_NOTIFY} - RIO_MSG_DONT_NOTIFY = $00000001; - {$EXTERNALSYM RIO_MSG_DEFER} - RIO_MSG_DEFER = $00000002; - {$EXTERNALSYM RIO_MSG_WAITALL} - RIO_MSG_WAITALL = $00000004; - {$EXTERNALSYM RIO_MSG_COMMIT_ONLY} - RIO_MSG_COMMIT_ONLY = $00000008; - - {$EXTERNALSYM RIO_INVALID_BUFFERID} - RIO_INVALID_BUFFERID = RIO_BUFFERID($FFFFFFFF); - {$EXTERNALSYM RIO_INVALID_CQ} - RIO_INVALID_CQ = RIO_CQ(0); - {$EXTERNALSYM RIO_INVALID_RQ} - RIO_INVALID_RQ = RIO_RQ(0); - {$EXTERNALSYM RIO_MAX_CQ_SIZE} - RIO_MAX_CQ_SIZE = $8000000; - {$EXTERNALSYM RIO_CORRUPT_CQ} - RIO_CORRUPT_CQ = $FFFFFFFF; - -{ Well known value names for Service Types } - {$EXTERNALSYM SERVICE_TYPE_VALUE_IPXPORTA} - SERVICE_TYPE_VALUE_IPXPORTA : PIdAnsiChar = 'IpxSocket'; {Do not Localize} - {$EXTERNALSYM SERVICE_TYPE_VALUE_SAPIDA} - SERVICE_TYPE_VALUE_SAPIDA : PIdAnsiChar = 'SapId'; {Do not Localize} - {$EXTERNALSYM SERVICE_TYPE_VALUE_TCPPORTA} - SERVICE_TYPE_VALUE_TCPPORTA : PIdAnsiChar = 'TcpPort'; {Do not Localize} - {$EXTERNALSYM SERVICE_TYPE_VALUE_UDPPORTA} - SERVICE_TYPE_VALUE_UDPPORTA : PIdAnsiChar = 'UdpPort'; {Do not Localize} - {$EXTERNALSYM SERVICE_TYPE_VALUE_OBJECTIDA} - SERVICE_TYPE_VALUE_OBJECTIDA : PIdAnsiChar = 'ObjectId'; {Do not Localize} - - {$EXTERNALSYM SERVICE_TYPE_VALUE_IPXPORTW} - SERVICE_TYPE_VALUE_IPXPORTW : PWideChar = 'IpxSocket'; {Do not Localize} - {$EXTERNALSYM SERVICE_TYPE_VALUE_SAPIDW} - SERVICE_TYPE_VALUE_SAPIDW : PWideChar = 'SapId'; {Do not Localize} - {$EXTERNALSYM SERVICE_TYPE_VALUE_TCPPORTW} - SERVICE_TYPE_VALUE_TCPPORTW : PWideChar = 'TcpPort'; {Do not Localize} - {$EXTERNALSYM SERVICE_TYPE_VALUE_UDPPORTW} - SERVICE_TYPE_VALUE_UDPPORTW : PWideChar = 'UdpPort'; {Do not Localize} - {$EXTERNALSYM SERVICE_TYPE_VALUE_OBJECTIDW} - SERVICE_TYPE_VALUE_OBJECTIDW : PWideChar = 'ObjectId'; {Do not Localize} - - {$EXTERNALSYM SERVICE_TYPE_VALUE_SAPID} - {$EXTERNALSYM SERVICE_TYPE_VALUE_TCPPORT} - {$EXTERNALSYM SERVICE_TYPE_VALUE_UDPPORT} - {$EXTERNALSYM SERVICE_TYPE_VALUE_OBJECTID} - {$IFDEF UNICODE} - SERVICE_TYPE_VALUE_SAPID : PWideChar = 'SapId'; {Do not Localize} - SERVICE_TYPE_VALUE_TCPPORT : PWideChar = 'TcpPort'; {Do not Localize} - SERVICE_TYPE_VALUE_UDPPORT : PWideChar = 'UdpPort'; {Do not Localize} - SERVICE_TYPE_VALUE_OBJECTID : PWideChar = 'ObjectId'; {Do not Localize} - {$ELSE} - SERVICE_TYPE_VALUE_SAPID : PIdAnsiChar = 'SapId'; {Do not Localize} - SERVICE_TYPE_VALUE_TCPPORT : PIdAnsiChar = 'TcpPort'; {Do not Localize} - SERVICE_TYPE_VALUE_UDPPORT : PIdAnsiChar = 'UdpPort'; {Do not Localize} - SERVICE_TYPE_VALUE_OBJECTID : PIdAnsiChar = 'ObjectId'; {Do not Localize} - {$ENDIF} - -// SockAddr Information -type - {$EXTERNALSYM SOCKET_ADDRESS} - SOCKET_ADDRESS = record - lpSockaddr : PSOCKADDR; - iSockaddrLength : Integer; - end; - {$NODEFINE TSocket_Address} - TSocket_Address = SOCKET_ADDRESS; - {$EXTERNALSYM PSOCKET_ADDRESS} - PSOCKET_ADDRESS = ^TSocket_Address; - - {$EXTERNALSYM SOCKET_ADDRESS_LIST} - SOCKET_ADDRESS_LIST = record - iAddressCount : Integer; - Address : SOCKET_ADDRESS; - end; - {$NODEFINE TSocket_Address_List} - TSocket_Address_List = SOCKET_ADDRESS_LIST; - {$EXTERNALSYM PSOCKET_ADDRESS_LIST} - PSOCKET_ADDRESS_LIST = ^TSocket_Address_List; - {$EXTERNALSYM LPSOCKET_ADDRESS_LIST} - LPSOCKET_ADDRESS_LIST = PSOCKET_ADDRESS_LIST; - -// CSAddr Information - {$EXTERNALSYM CSADDR_INFO} - CSADDR_INFO = record - LocalAddr, - RemoteAddr : TSocket_Address; - iSocketType, - iProtocol : Integer; - end; - {$NODEFINE TCSAddr_Info} - TCSAddr_Info = CSADDR_INFO; - {$EXTERNALSYM PCSADDR_INFO} - PCSADDR_INFO = ^TCSAddr_Info; - {$EXTERNALSYM LPCSADDR_INFO} - LPCSADDR_INFO = PCSADDR_INFO; - -// Address Family/Protocol Tuples - {$EXTERNALSYM AFPROTOCOLS} - AFPROTOCOLS = record - iAddressFamily : Integer; - iProtocol : Integer; - end; - {$NODEFINE TAFProtocols} - TAFProtocols = AFPROTOCOLS; - {$EXTERNALSYM PAFPROTOCOLS} - PAFPROTOCOLS = ^TAFProtocols; - {$EXTERNALSYM LPAFPROTOCOLS} - LPAFPROTOCOLS = PAFPROTOCOLS; - -// Client Query API Typedefs - -// The comparators - {$EXTERNALSYM WSAECOMPARATOR} - WSAECOMPARATOR = (COMP_EQUAL {= 0}, COMP_NOTLESS); - {$NODEFINE TWSAEComparator} - TWSAEComparator = WSAECOMPARATOR; - {$EXTERNALSYM PWSAECOMPARATOR} - PWSAECOMPARATOR = ^WSAECOMPARATOR; - - {$EXTERNALSYM WSAVERSION} - WSAVERSION = record - dwVersion : DWORD; - ecHow : TWSAEComparator; - end; - {$NODEFINE TWSAVersion} - TWSAVersion = WSAVERSION; - {$EXTERNALSYM PWSAVERSION} - PWSAVERSION = ^TWSAVersion; - {$EXTERNALSYM LPWSAVERSION} - LPWSAVERSION = PWSAVERSION; - - {$EXTERNALSYM WSAQUERYSETA} - WSAQUERYSETA = record - dwSize : DWORD; - lpszServiceInstanceName : PIdAnsiChar; - lpServiceClassId : PGUID; - lpVersion : LPWSAVERSION; - lpszComment : PIdAnsiChar; - dwNameSpace : DWORD; - lpNSProviderId : PGUID; - lpszContext : PIdAnsiChar; - dwNumberOfProtocols : DWORD; - lpafpProtocols : LPAFPROTOCOLS; - lpszQueryString : PIdAnsiChar; - dwNumberOfCsAddrs : DWORD; - lpcsaBuffer : LPCSADDR_INFO; - dwOutputFlags : DWORD; - lpBlob : LPBLOB; - end; - {$NODEFINE TWSAQuerySetA} - TWSAQuerySetA = WSAQUERYSETA; - {$EXTERNALSYM PWSAQUERYSETA} - PWSAQUERYSETA = ^TWSAQuerySetA; - {$EXTERNALSYM LPWSAQUERYSETA} - LPWSAQUERYSETA = PWSAQUERYSETA; - - {$EXTERNALSYM WSAQUERYSETW} - WSAQUERYSETW = record - dwSize : DWORD; - lpszServiceInstanceName : PWideChar; - lpServiceClassId : PGUID; - lpVersion : LPWSAVERSION; - lpszComment : PWideChar; - dwNameSpace : DWORD; - lpNSProviderId : PGUID; - lpszContext : PWideChar; - dwNumberOfProtocols : DWORD; - lpafpProtocols : LPAFPROTOCOLS; - lpszQueryString : PWideChar; - dwNumberOfCsAddrs : DWORD; - lpcsaBuffer : LPCSADDR_INFO; - dwOutputFlags : DWORD; - lpBlob : LPBLOB; - end; - {$NODEFINE TWSAQuerySetW} - TWSAQuerySetW = WSAQUERYSETW; - {$EXTERNALSYM PWSAQUERYSETW} - PWSAQUERYSETW = ^TWSAQuerySetW; - {$EXTERNALSYM LPWSAQUERYSETW} - LPWSAQUERYSETW = PWSAQUERYSETW; - - {$NODEFINE TWSAQuerySet} - {$EXTERNALSYM PWSAQUERYSET} - {$EXTERNALSYM LPWSAQUERYSET} - {$IFDEF UNICODE} - TWSAQuerySet = TWSAQuerySetW; - PWSAQUERYSET = PWSAQUERYSETW; - LPWSAQUERYSET = LPWSAQUERYSETW; - {$ELSE} - TWSAQuerySet = TWSAQuerySetA; - PWSAQUERYSET = PWSAQUERYSETA; - LPWSAQUERYSET = LPWSAQUERYSETA; - {$ENDIF} - -const - {$EXTERNALSYM LUP_DEEP} - LUP_DEEP = $0001; - {$EXTERNALSYM LUP_CONTAINERS} - LUP_CONTAINERS = $0002; - {$EXTERNALSYM LUP_NOCONTAINERS} - LUP_NOCONTAINERS = $0004; - {$EXTERNALSYM LUP_NEAREST} - LUP_NEAREST = $0008; - {$EXTERNALSYM LUP_RETURN_NAME} - LUP_RETURN_NAME = $0010; - {$EXTERNALSYM LUP_RETURN_TYPE} - LUP_RETURN_TYPE = $0020; - {$EXTERNALSYM LUP_RETURN_VERSION} - LUP_RETURN_VERSION = $0040; - {$EXTERNALSYM LUP_RETURN_COMMENT} - LUP_RETURN_COMMENT = $0080; - {$EXTERNALSYM LUP_RETURN_ADDR} - LUP_RETURN_ADDR = $0100; - {$EXTERNALSYM LUP_RETURN_BLOB} - LUP_RETURN_BLOB = $0200; - {$EXTERNALSYM LUP_RETURN_ALIASES} - LUP_RETURN_ALIASES = $0400; - {$EXTERNALSYM LUP_RETURN_QUERY_STRING} - LUP_RETURN_QUERY_STRING = $0800; - {$EXTERNALSYM LUP_RETURN_ALL} - LUP_RETURN_ALL = $0FF0; - {$EXTERNALSYM LUP_RES_SERVICE} - LUP_RES_SERVICE = $8000; - - {$EXTERNALSYM LUP_FLUSHCACHE} - LUP_FLUSHCACHE = $1000; - {$EXTERNALSYM LUP_FLUSHPREVIOUS} - LUP_FLUSHPREVIOUS = $2000; - -// Return flags - {$EXTERNALSYM RESULT_IS_ALIAS} - RESULT_IS_ALIAS = $0001; - //These are not supported in WinCE 4.2 but are available in later versions. - {$EXTERNALSYM RESULT_IS_ADDED} - RESULT_IS_ADDED = $0010; - {$EXTERNALSYM RESULT_IS_CHANGED} - RESULT_IS_CHANGED = $0020; - {$EXTERNALSYM RESULT_IS_DELETED} - RESULT_IS_DELETED = $0040; - - {$EXTERNALSYM MAX_NATURAL_ALIGNMENT} - {$IFDEF _WIN64} - MAX_NATURAL_ALIGNMENT = SizeOf(Int64); - {$ELSE} - MAX_NATURAL_ALIGNMENT = SizeOf(DWORD); - {$ENDIF} - -// WSARecvMsg flags - {$EXTERNALSYM MSG_TRUNC} - MSG_TRUNC = $0100; - {$EXTERNALSYM MSG_CTRUNC} - MSG_CTRUNC = $0200; - {$EXTERNALSYM MSG_BCAST} - MSG_BCAST = $0400; - {$EXTERNALSYM MSG_MCAST} - MSG_MCAST = $0800; - -{$IFNDEF WINCE} - //Windows Vista WSAPoll -//* Event flag definitions for WSAPoll(). */ - {$EXTERNALSYM POLLRDNORM} - POLLRDNORM = $0100; - {$EXTERNALSYM POLLRDBAND} - POLLRDBAND = $0200; - {$EXTERNALSYM POLLIN} - POLLIN = (POLLRDNORM or POLLRDBAND); - {$EXTERNALSYM POLLPRI} - POLLPRI = $0400; - {$EXTERNALSYM POLLWRNORM} - POLLWRNORM = $0010; - {$EXTERNALSYM POLLOUT} - POLLOUT = (POLLWRNORM); - {$EXTERNALSYM POLLWRBAND} - POLLWRBAND = $0020; - {$EXTERNALSYM POLLERR} - POLLERR = $0001; - {$EXTERNALSYM POLLHUP} - POLLHUP = $0002; - {$EXTERNALSYM POLLNVAL} - POLLNVAL = $0004; -{$ENDIF} - -type -// Service Address Registration and Deregistration Data Types. - {$EXTERNALSYM WSAESETSERVICEOP} - WSAESETSERVICEOP = (RNRSERVICE_REGISTER{=0}, RNRSERVICE_DEREGISTER, RNRSERVICE_DELETE); - {$NODEFINE TWSAESetServiceOp} - TWSAESetServiceOp = WSAESETSERVICEOP; - -{ Service Installation/Removal Data Types. } - {$EXTERNALSYM WSANSCLASSINFOA} - WSANSCLASSINFOA = record - lpszName : PIdAnsiChar; - dwNameSpace : DWORD; - dwValueType : DWORD; - dwValueSize : DWORD; - lpValue : Pointer; - end; - {$NODEFINE TWSANSClassInfoA} - TWSANSClassInfoA = WSANSCLASSINFOA; - {$EXTERNALSYM PWSANSClassInfoA} - PWSANSCLASSINFOA = ^TWSANSClassInfoA; - {$EXTERNALSYM LPWSANSCLASSINFOA} - LPWSANSCLASSINFOA = PWSANSCLASSINFOA; - - {$EXTERNALSYM WSANSCLASSINFOW} - WSANSCLASSINFOW = record - lpszName : PWideChar; - dwNameSpace : DWORD; - dwValueType : DWORD; - dwValueSize : DWORD; - lpValue : Pointer; - end; - {$NODEFINE TWSANSClassInfoW} - TWSANSClassInfoW = WSANSCLASSINFOW; - {$EXTERNALSYM PWSANSClassInfoW} - PWSANSCLASSINFOW = ^TWSANSClassInfoW; - {$EXTERNALSYM LPWSANSCLASSINFOW} - LPWSANSCLASSINFOW = PWSANSCLASSINFOW; - - {$NODEFINE TWSANSClassInfo} - {$EXTERNALSYM WSANSCLASSINFO} - {$EXTERNALSYM PWSANSCLASSINFO} - {$EXTERNALSYM LPWSANSCLASSINFO} - {$IFDEF UNICODE} - TWSANSClassInfo = TWSANSClassInfoW; - WSANSCLASSINFO = TWSANSClassInfoW; - PWSANSCLASSINFO = PWSANSCLASSINFOW; - LPWSANSCLASSINFO = LPWSANSCLASSINFOW; - {$ELSE} - TWSANSClassInfo = TWSANSClassInfoA; - WSANSCLASSINFO = TWSANSClassInfoA; - PWSANSCLASSINFO = PWSANSCLASSINFOA; - LPWSANSCLASSINFO = LPWSANSCLASSINFOA; - {$ENDIF // UNICODE} - - {$EXTERNALSYM WSASERVICECLASSINFOA} - WSASERVICECLASSINFOA = record - lpServiceClassId : PGUID; - lpszServiceClassName : PIdAnsiChar; - dwCount : DWORD; - lpClassInfos : LPWSANSCLASSINFOA; - end; - {$NODEFINE TWSAServiceClassInfoA} - TWSAServiceClassInfoA = WSASERVICECLASSINFOA; - {$EXTERNALSYM PWSASERVICECLASSINFOA} - PWSASERVICECLASSINFOA = ^TWSAServiceClassInfoA; - {$EXTERNALSYM LPWSASERVICECLASSINFOA} - LPWSASERVICECLASSINFOA = PWSASERVICECLASSINFOA; - - {$EXTERNALSYM WSASERVICECLASSINFOW} - WSASERVICECLASSINFOW = record - lpServiceClassId : PGUID; - lpszServiceClassName : PWideChar; - dwCount : DWORD; - lpClassInfos : LPWSANSCLASSINFOW; - end; - {$NODEFINE TWSAServiceClassInfoW} - TWSAServiceClassInfoW = WSASERVICECLASSINFOW; - {$EXTERNALSYM PWSASERVICECLASSINFOW} - PWSASERVICECLASSINFOW = ^TWSAServiceClassInfoW; - {$EXTERNALSYM LPWSASERVICECLASSINFOW} - LPWSASERVICECLASSINFOW = PWSASERVICECLASSINFOW; - - {$NODEFINE TWSAServiceClassInfo} - {$EXTERNALSYM WSASERVICECLASSINFO} - {$EXTERNALSYM PWSASERVICECLASSINFO} - {$EXTERNALSYM LPWSASERVICECLASSINFO} - {$IFDEF UNICODE} - TWSAServiceClassInfo = TWSAServiceClassInfoW; - WSASERVICECLASSINFO = TWSAServiceClassInfoW; - PWSASERVICECLASSINFO = PWSASERVICECLASSINFOW; - LPWSASERVICECLASSINFO = LPWSASERVICECLASSINFOW; - {$ELSE} - TWSAServiceClassInfo = TWSAServiceClassInfoA; - WSASERVICECLASSINFO = TWSAServiceClassInfoA; - PWSASERVICECLASSINFO = PWSASERVICECLASSINFOA; - LPWSASERVICECLASSINFO = LPWSASERVICECLASSINFOA; - {$ENDIF} - - {$EXTERNALSYM WSANAMESPACE_INFOA} - WSANAMESPACE_INFOA = record - NSProviderId : TGUID; - dwNameSpace : DWORD; - fActive : DWORD{Bool}; - dwVersion : DWORD; - lpszIdentifier : PIdAnsiChar; - end; - {$NODEFINE TWSANameSpace_InfoA} - TWSANameSpace_InfoA = WSANAMESPACE_INFOA; - {$EXTERNALSYM PWSANAMESPACE_INFOA} - PWSANAMESPACE_INFOA = ^TWSANameSpace_InfoA; - {$EXTERNALSYM LPWSANAMESPACE_INFOA} - LPWSANAMESPACE_INFOA = PWSANAMESPACE_INFOA; - - {$EXTERNALSYM WSANAMESPACE_INFOW} - WSANAMESPACE_INFOW = record - NSProviderId : TGUID; - dwNameSpace : DWORD; - fActive : DWORD{Bool}; - dwVersion : DWORD; - lpszIdentifier : PWideChar; - end; - {$NODEFINE TWSANameSpace_InfoW} - TWSANameSpace_InfoW = WSANAMESPACE_INFOW; - {$EXTERNALSYM PWSANAMESPACE_INFOW} - PWSANAMESPACE_INFOW = ^TWSANameSpace_InfoW; - {$EXTERNALSYM LPWSANAMESPACE_INFOW} - LPWSANAMESPACE_INFOW = PWSANAMESPACE_INFOW; - -{$IFNDEF WINCE} - {$EXTERNALSYM WSANAMESPACE_INFOEXW} - WSANAMESPACE_INFOEXW = record - NSProviderId : TGUID; - dwNameSpace : DWord; - fActive : LongBool; - lpszIdentifier : LPWSTR; - ProviderSpecific : BLOB; - end; - {$NODEFINE TWSANameSpace_InfoExW} - TWSANameSpace_InfoExW = WSANAMESPACE_INFOEXW; - {$EXTERNALSYM PWSANAMESPACE_INFOEXW} - PWSANAMESPACE_INFOEXW = ^TWSANameSpace_InfoExW; - {$EXTERNALSYM LPWSANAMESPACE_INFOEXW} - LPWSANAMESPACE_INFOEXW = PWSANAMESPACE_INFOEXW; - - {$EXTERNALSYM WSANAMESPACE_INFOEXA} - WSANAMESPACE_INFOEXA = record - NSProviderId : TGUID; - dwNameSpace : DWord; - fActive : LongBool; - lpszIdentifier : LPSTR; - ProviderSpecific : BLOB; - end; - {$NODEFINE TWSANameSpace_InfoExA} - TWSANameSpace_InfoExA = WSANAMESPACE_INFOEXA; - {$EXTERNALSYM PWSANAMESPACE_INFOEXA} - PWSANAMESPACE_INFOEXA = ^TWSANameSpace_InfoExA; - {$EXTERNALSYM LPWSANAMESPACE_INFOEXA} - LPWSANAMESPACE_INFOEXA = PWSANAMESPACE_INFOEXA; - - {$EXTERNALSYM LPFN_WSAENUMNAMESPACEPROVIDERSEXW} - LPFN_WSAENUMNAMESPACEPROVIDERSEXW = function (var lpdwBufferLength : DWord; - lpnspBuffer : PWSANAMESPACE_INFOEXW): Integer; stdcall; - {$EXTERNALSYM LPFN_WSAENUMNAMESPACEPROVIDERSEXA} - LPFN_WSAENUMNAMESPACEPROVIDERSEXA = function (var lpdwBufferLength : DWord; - lpnspBuffer : PWSANAMESPACE_INFOEXA): Integer; stdcall; - - {$NODEFINE TWSANameSpace_InfoEx} - {$EXTERNALSYM WSANAMESPACE_INFOEX} - {$EXTERNALSYM PWSANAMESPACE_INFOEX} - {$EXTERNALSYM LPWSANAMESPACE_INFOEX} - {$EXTERNALSYM LPFN_WSAENUMNAMESPACEPROVIDERSEX} - {$IFDEF UNICODE} - WSANAMESPACE_INFOEX = WSANAMESPACE_INFOEXW; - TWSANameSpace_InfoEx = TWSANameSpace_InfoExW; - PWSANAMESPACE_INFOEX = PWSANAMESPACE_INFOEXW; - LPWSANAMESPACE_INFOEX = PWSANAMESPACE_INFOEX; - LPFN_WSAENUMNAMESPACEPROVIDERSEX = LPFN_WSAENUMNAMESPACEPROVIDERSEXW; - {$ELSE} - WSANAMESPACE_INFOEX = WSANAMESPACE_INFOEXA; - TWSANameSpace_InfoEx = TWSANameSpace_InfoExA; - PWSANAMESPACE_INFOEX = PWSANAMESPACE_INFOEXA; - LPWSANAMESPACE_INFOEX = PWSANAMESPACE_INFOEX; - LPFN_WSAENUMNAMESPACEPROVIDERSEX = LPFN_WSAENUMNAMESPACEPROVIDERSEXA; - {$ENDIF} -{$ENDIF} // WINCE - - {$NODEFINE TWSANameSpace_Info} - {$EXTERNALSYM WSANAMESPACE_INFO} - {$EXTERNALSYM PWSANAMESPACE_INFO} - {$EXTERNALSYM LPWSANAMESPACE_INFO} - {$IFDEF UNICODE} - TWSANameSpace_Info = TWSANameSpace_InfoW; - WSANAMESPACE_INFO = TWSANameSpace_InfoW; - PWSANAMESPACE_INFO = PWSANAMESPACE_INFOW; - LPWSANAMESPACE_INFO = LPWSANAMESPACE_INFOW; - {$ELSE} - TWSANameSpace_Info = TWSANameSpace_InfoA; - WSANAMESPACE_INFO = TWSANameSpace_InfoA; - PWSANAMESPACE_INFO = PWSANAMESPACE_INFOA; - LPWSANAMESPACE_INFO = LPWSANAMESPACE_INFOA; - {$ENDIF} - - {$IFDEF WINCE} - {$EXTERNALSYM DSCP_TRAFFIC_TYPE} - {$EXTERNALSYM DSCPTypeNotSet} - {$EXTERNALSYM DSCPBestEffort} - {$EXTERNALSYM DSCPBackground} - {$EXTERNALSYM DSCPExcellentEffort} - {$EXTERNALSYM DSCPVideo} - {$EXTERNALSYM DSCPAudio} - {$EXTERNALSYM DSCPControl} - {$EXTERNALSYM NumDSCPTrafficTypes} - DSCP_TRAFFIC_TYPE = ( - DSCPTypeNotSet = 0, - DSCPBestEffort = 1, - DSCPBackground = 2, - DSCPExcellentEffort = 3, - DSCPVideo = 4, - DSCPAudio = 5, - DSCPControl = 6); -// Define NumDSCPTrafficTypes as DSCPControl -//because FPC warns that enumerations must be descending. -//The original definition for DSCP_TRAFFIC_TYPE is: -// -///* differential service traffic types */ -//typedef enum _DSCP_TRAFFIC_TYPE -//{ -// DSCPTypeNotSet = 0, -// DSCPBestEffort = 1, -// DSCPBackground = 2, -// DSCPExcellentEffort = 3, -// DSCPVideo = 4, -// DSCPAudio = 5, -// DSCPControl = 6, -// NumDSCPTrafficTypes = 6 -//} //DSCP_TRAFFIC_TYPE; -const - NumDSCPTrafficTypes : DSCP_TRAFFIC_TYPE = DSCPControl; - -type - {$ENDIF} - - {$EXTERNALSYM WSAMSG} - WSAMSG = record - name : PSOCKADDR; ///* Remote address */ - namelen : Integer; ///* Remote address length * - lpBuffers : LPWSABUF; // /* Data buffer array */ - dwBufferCount : DWord; // /* Number of elements in the array */ - Control : WSABUF; // /* Control buffer */ - dwFlags : DWord; // /* Flags */ - end; - {$NODEFINE TWSAMSG} - TWSAMSG = WSAMSG; - {$EXTERNALSYM PWSAMSG} - PWSAMSG = ^TWSAMSG; - {$EXTERNALSYM LPWSAMSG} - LPWSAMSG = PWSAMSG; - - {$EXTERNALSYM _WSACMSGHDR} - _WSACMSGHDR = record - cmsg_len: SIZE_T; - cmsg_level: Integer; - cmsg_type: Integer; - { followed by UCHAR cmsg_data[] } - end; - {$EXTERNALSYM WSACMSGHDR} - WSACMSGHDR = _WSACMSGHDR; - {$EXTERNALSYM cmsghdr} - cmsghdr = _WSACMSGHDR; - {$NODEFINE TWSACMsgHdr} - TWSACMsgHdr = WSACMSGHDR; - {$EXTERNALSYM PWSACMSGHDR} - PWSACMSGHDR = ^TWSACMsgHdr; - {$EXTERNALSYM LPWSACMSGHDR} - LPWSACMSGHDR = PWSACMSGHDR; - {$EXTERNALSYM PCMSGHDR} - PCMSGHDR = ^CMSGHDR; -{$IFNDEF WINCE} - {$EXTERNALSYM WSAPOLLFD} - WSAPOLLFD = record - fd : TSocket; - events : SHORT; - revents : SHORT; - end; - {$NODEFINE TWSAPOLLFD} - TWSAPOLLFD = WSAPOLLFD; - {$EXTERNALSYM PWSAPOLLFD} - PWSAPOLLFD = ^TWSAPOLLFD; - {$EXTERNALSYM LPWSAPOLLFD} - LPWSAPOLLFD = PWSAPOLLFD; -{$ENDIF} - -{ WinSock 2 extensions -- data types for the condition function in } -{ WSAAccept() and overlapped I/O completion routine. } -type - {$EXTERNALSYM LPCONDITIONPROC} - LPCONDITIONPROC = function(lpCallerId: LPWSABUF; lpCallerData: LPWSABUF; lpSQOS, pGQOS: LPQOS; - lpCalleeId,lpCalleeData: LPWSABUF; g: PGROUP; dwCallbackData: DWORD_PTR): Integer; stdcall; - {$EXTERNALSYM LPWSAOVERLAPPED_COMPLETION_ROUTINE} - LPWSAOVERLAPPED_COMPLETION_ROUTINE = procedure(dwError, cbTransferred: DWORD; - lpOverlapped: LPWSAOVERLAPPED; dwFlags: DWORD); stdcall; - - {$EXTERNALSYM WSACOMPLETIONTYPE} - {$EXTERNALSYM NSP_NOTIFY_IMMEDIATELY} - {$EXTERNALSYM NSP_NOTIFY_HWND} - {$EXTERNALSYM NSP_NOTIFY_EVENT} - {$EXTERNALSYM NSP_NOTIFY_PORT} - {$EXTERNALSYM NSP_NOTIFY_APC} - WSACOMPLETIONTYPE = ( - NSP_NOTIFY_IMMEDIATELY, - NSP_NOTIFY_HWND, - NSP_NOTIFY_EVENT, - NSP_NOTIFY_PORT, - NSP_NOTIFY_APC); - {$EXTERNALSYM WSACOMPLETION_WINDOWMESSAGE} - WSACOMPLETION_WINDOWMESSAGE = record - hWnd : HWND; - uMsg : UINT; - context : WPARAM; - end; - {$EXTERNALSYM WSACOMPLETION_EVENT} - WSACOMPLETION_EVENT = record - lpOverlapped : LPWSAOVERLAPPED; - end; - {$EXTERNALSYM WSACOMPLETION_APC} - WSACOMPLETION_APC = record - lpOverlapped : LPWSAOVERLAPPED; - lpfnCompletionProc : LPWSAOVERLAPPED_COMPLETION_ROUTINE; - end; - {$EXTERNALSYM WSACOMPLETION_PORT} - WSACOMPLETION_PORT = record - lpOverlapped : LPWSAOVERLAPPED; - hPort : THandle; - Key : ULONG_PTR; - end; - {$EXTERNALSYM WSACOMPLETION_UNION} - WSACOMPLETION_union = record - case Integer of - 0: (WindowMessage : WSACOMPLETION_WINDOWMESSAGE); - 1: (Event : WSACOMPLETION_EVENT); - 2: (Apc : WSACOMPLETION_APC); - 3: (Port : WSACOMPLETION_PORT); - end; - {$EXTERNALSYM WSACOMPLETION} - WSACOMPLETION = record - _Type : WSACOMPLETIONTYPE; - Parameters : WSACOMPLETION_union; - end; - {$EXTERNALSYM PWSACOMPLETION} - PWSACOMPLETION = ^WSACOMPLETION; - {$EXTERNALSYM LPWSACOMPLETION} - LPWSACOMPLETION = PWSACOMPLETION; -{$IFNDEF WINCE} - {$EXTERNALSYM _RIO_NOTIFICATION_COMPLETION_TYPE} - {$EXTERNALSYM RIO_EVENT_COMPLETION} - {$EXTERNALSYM RIO_IOCP_COMPLETION} - {$IFNDEF HAS_ENUM_ELEMENT_VALUES} - {$NODEFINE rnctUnused} - {$ENDIF} - // The Pascal compiler in Delphi/BCB prior to v6 does not - // support specifying values for individual enum items - _RIO_NOTIFICATION_COMPLETION_TYPE = ( - {$IFDEF HAS_ENUM_ELEMENT_VALUES} - RIO_EVENT_COMPLETION = 1, - RIO_IOCP_COMPLETION = 2 - {$ELSE} - rnctUnused, // do not use - RIO_EVENT_COMPLETION, - RIO_IOCP_COMPLETION - {$ENDIF} - ); - {$EXTERNALSYM RIO_NOTIFICATION_COMPLETION_TYPE} - RIO_NOTIFICATION_COMPLETION_TYPE = _RIO_NOTIFICATION_COMPLETION_TYPE; - {$EXTERNALSYM PRIO_NOTIFICATION_COMPLETION_TYPE} - PRIO_NOTIFICATION_COMPLETION_TYPE = ^RIO_NOTIFICATION_COMPLETION_TYPE; - {$EXTERNALSYM _RIO_NOTIFICATION_COMPLETION} - {$EXTERNALSYM RIO_NOTIFICATION_COMPLETION} - {$EXTERNALSYM PRIO_NOTIFICATION_COMPLETION} - {$EXTERNALSYM _RIO_NOTIFICATION_COMPLETION_UNION} - {$EXTERNALSYM _RIO_NOTIFICATION_COMPLETION_IOCP} - {$EXTERNALSYM _RIO_NOTIFICATION_COMPLETION_EVENT} - _RIO_NOTIFICATION_COMPLETION_EVENT = record - EventHandle : THandle; - NotifyReset : BOOL; - end; - _RIO_NOTIFICATION_COMPLETION_IOCP = record - IocpHandle : THANDLE; - CompletionKey : PVOID; - Overlapped : PVOID; - end; - _RIO_NOTIFICATION_COMPLETION_UNION = record - case Integer of - 0 : (Event : _RIO_NOTIFICATION_COMPLETION_EVENT); - 1 : (Iocp : _RIO_NOTIFICATION_COMPLETION_IOCP); - end; - _RIO_NOTIFICATION_COMPLETION = record - _Type : RIO_NOTIFICATION_COMPLETION_TYPE; - a : _RIO_NOTIFICATION_COMPLETION_UNION; - end; - {$EXTERNALSYM RIO_NOTIFICATION_COMPLETION} - RIO_NOTIFICATION_COMPLETION = _RIO_NOTIFICATION_COMPLETION; - {$EXTERNALSYM PRIO_NOTIFICATION_COMPLETION} - PRIO_NOTIFICATION_COMPLETION = ^RIO_NOTIFICATION_COMPLETION; -{$ENDIF} - -type -{$IFDEF INCL_WINSOCK_API_TYPEDEFS} - {$EXTERNALSYM LPFN_WSASTARTUP} - LPFN_WSASTARTUP = function(const wVersionRequired: WORD; out WSData: TWSAData): Integer; stdcall; - {$EXTERNALSYM LPFN_WSACLEANUP} - LPFN_WSACLEANUP = function: Integer; stdcall; - {$EXTERNALSYM LPFN_ACCEPT} - LPFN_ACCEPT = function(const s: TSocket; AAddr: PSOCKADDR; addrlen: PInteger): TSocket; stdcall; - {$EXTERNALSYM LPFN_BIND} - LPFN_BIND = function(const s: TSocket; const name: PSOCKADDR; const namelen: Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_CLOSESOCKET} - LPFN_CLOSESOCKET = function(const s: TSocket): Integer; stdcall; - {$EXTERNALSYM LPFN_CONNECT} - LPFN_CONNECT = function(const s: TSocket; const name: PSOCKADDR; const namelen: Integer): Integer; stdcall; - {$EXTERNALSYM lpfn_IOCTLSOCKET} - LPFN_IOCTLSOCKET = function(const s: TSocket; const cmd: DWORD; var arg: u_long): Integer; stdcall; - {$EXTERNALSYM LPFN_GETPEERNAME} - LPFN_GETPEERNAME = function(const s: TSocket; const name: PSOCKADDR; var namelen: Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_GETSOCKNAME} - LPFN_GETSOCKNAME = function(const s: TSocket; const name: PSOCKADDR; var namelen: Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_GETSOCKOPT} - LPFN_GETSOCKOPT = function(const s: TSocket; const level, optname: Integer; optval: PIdAnsiChar; var optlen: Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_HTONL} - LPFN_HTONL = function(hostlong: u_long): u_long; stdcall; - {$EXTERNALSYM LPFN_HTONS} - LPFN_HTONS = function(hostshort: u_short): u_short; stdcall; - {$EXTERNALSYM LPFN_INET_ADDR} - LPFN_INET_ADDR = function(cp: PIdAnsiChar): u_long; stdcall; - {$EXTERNALSYM LPFN_INET_NTOA} - LPFN_INET_NTOA = function(inaddr: TInAddr): PIdAnsiChar; stdcall; - {$EXTERNALSYM LPFN_LISTEN} - LPFN_LISTEN = function(const s: TSocket; backlog: Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_NTOHL} - LPFN_NTOHL = function(netlong: u_long): u_long; stdcall; - {$EXTERNALSYM LPFN_NTOHS} - LPFN_NTOHS = function(netshort: u_short): u_short; stdcall; - {$EXTERNALSYM LPFN_RECV} - LPFN_RECV = function(const s: TSocket; var Buf; len, flags: Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_RECVFROM} - LPFN_RECVFROM = function(const s: TSocket; var Buf; len, flags: Integer; from: PSOCKADDR; fromlen: PInteger): Integer; stdcall; - {$EXTERNALSYM LPFN_SELECT} - LPFN_SELECT = function(nfds: Integer; readfds, writefds, exceptfds: PFDSet; timeout: PTimeVal): Integer; stdcall; - {$EXTERNALSYM LPFN_SEND} - LPFN_SEND = function(const s: TSocket; const Buf; len, flags: Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_SENDTO} - LPFN_SENDTO = function(const s: TSocket; const Buf; const len, flags: Integer; const addrto: PSOCKADDR; const tolen: Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_SETSOCKOPT} - LPFN_SETSOCKOPT = function(const s: TSocket; const level, optname: Integer; optval: PIdAnsiChar; const optlen: Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_SHUTDOWN} - LPFN_SHUTDOWN = function(const s: TSocket; const how: Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_SOCKET} - LPFN_SOCKET = function(const af, istruct, protocol: Integer): TSocket; stdcall; - {$EXTERNALSYM LPFN_GETHOSTBYADDR} - LPFN_GETHOSTBYADDR = function(AAddr: Pointer; const len, addrtype: Integer): PHostEnt; stdcall; - {$EXTERNALSYM LPFN_GETHOSTBYNAME} - LPFN_GETHOSTBYNAME = function(name: PIdAnsiChar): PHostEnt; stdcall; - {$EXTERNALSYM LPFN_GETHOSTNAME} - LPFN_GETHOSTNAME = function(name: PIdAnsiChar; len: Integer): Integer; stdcall; -{$IFDEF WINCE} - // WinCE specific for setting the host name - {$EXTERNALSYM LPFN_SETHOSTNAME} - LPFN_SETHOSTNAME = function(pName : PIdAnsiChar; len : Integer) : Integer; stdcall; -{$ENDIF} - {$EXTERNALSYM LPFN_GETSERVBYPORT} - LPFN_GETSERVBYPORT = function(const port: Integer; const proto: PIdAnsiChar): PServEnt; stdcall; - {$EXTERNALSYM LPFN_GETSERVBYNAME} - LPFN_GETSERVBYNAME = function(const name, proto: PIdAnsiChar): PServEnt; stdcall; - {$EXTERNALSYM LPFN_GETPROTOBYNUMBER} - LPFN_GETPROTOBYNUMBER = function(const proto: Integer): PProtoEnt; stdcall; - {$EXTERNALSYM LPFN_GETPROTOBYNAME} - LPFN_GETPROTOBYNAME = function(const name: PIdAnsiChar): PProtoEnt; stdcall; - {$EXTERNALSYM LPFN_WSASETLASTERROR} - LPFN_WSASETLASTERROR = procedure(const iError: Integer); stdcall; - {$EXTERNALSYM LPFN_WSAGETLASTERROR} - LPFN_WSAGETLASTERROR = function: Integer; stdcall; -{$IFNDEF WINCE} - {$EXTERNALSYM LPFN_WSACANCELASYNCREQUEST} - LPFN_WSACANCELASYNCREQUEST = function(hAsyncTaskHandle: THandle): Integer; stdcall; - {$EXTERNALSYM LPFN_WSAISBLOCKING} - LPFN_WSAISBLOCKING = function: BOOL; stdcall; - {$EXTERNALSYM LPFN_WSAUNHOOKBLOCKINGHOOK} - LPFN_WSAUNHOOKBLOCKINGHOOK = function: Integer; stdcall; - {$EXTERNALSYM LPFN_WSASETBLOCKINGHOOK} - LPFN_WSASETBLOCKINGHOOK = function(lpBlockFunc: TFarProc): TFarProc; stdcall; - {$EXTERNALSYM LPFN_WSACANCELBLOCKINGCALL} - LPFN_WSACANCELBLOCKINGCALL = function: Integer; stdcall; - {$EXTERNALSYM LPFN_WSAASYNCGETSERVBYNAME} - LPFN_WSAASYNCGETSERVBYNAME = function(HWindow: HWND; wMsg: u_int; name, proto, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; - {$EXTERNALSYM LPFN_WSAASYNCGETSERVBYPORT} - LPFN_WSAASYNCGETSERVBYPORT = function(HWindow: HWND; wMsg, port: u_int; proto, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; - {$EXTERNALSYM LPFN_WSAASYNCGETPROTOBYNAME} - LPFN_WSAASYNCGETPROTOBYNAME = function(HWindow: HWND; wMsg: u_int; name, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; - {$EXTERNALSYM LPFN_WSAASYNCGETPROTOBYNUMBER} - LPFN_WSAASYNCGETPROTOBYNUMBER = function(HWindow: HWND; wMsg: u_int; number: Integer; buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; - {$EXTERNALSYM LPFN_WSAASYNCGETHOSTBYNAME} - LPFN_WSAASYNCGETHOSTBYNAME = function(HWindow: HWND; wMsg: u_int; name, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; - {$EXTERNALSYM LPFN_WSAASYNCGETHOSTBYADDR} - LPFN_WSAASYNCGETHOSTBYADDR = function(HWindow: HWND; wMsg: u_int; AAddr: PIdAnsiChar; len, istruct: Integer; buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; - {$EXTERNALSYM LPFN_WSAASYNCSELECT} - LPFN_WSAASYNCSELECT = function(const s: TSocket; HWindow: HWND; wMsg: u_int; lEvent: Longint): Integer; stdcall; -{$ENDIF} - {$EXTERNALSYM LPFN___WSAFDISSET} - LPFN___WSAFDISSET = function(const s: TSocket; var FDSet: TFDSet): Bool; stdcall; - -// WinSock 2 API new function prototypes - {$EXTERNALSYM LPFN_WSAACCEPT} - LPFN_WSAACCEPT = function(const s : TSocket; AAddr : PSOCKADDR; addrlen : PInteger; lpfnCondition : LPCONDITIONPROC; const dwCallbackData : DWORD): TSocket; stdcall; - {$EXTERNALSYM LPFN_WSAENUMPROTOCOLSA} - LPFN_WSAENUMPROTOCOLSA = function(lpiProtocols : PInteger; lpProtocolBuffer : LPWSAPROTOCOL_INFOA; var lpdwBufferLength : DWORD) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSAENUMPROTOCOLSW} - LPFN_WSAENUMPROTOCOLSW = function(lpiProtocols : PInteger; lpProtocolBuffer : LPWSAPROTOCOL_INFOW; var lpdwBufferLength : DWORD) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSAGETOVERLAPPEDRESULT} - LPFN_WSAGETOVERLAPPEDRESULT = function(const s : TSocket; AOverlapped: Pointer; lpcbTransfer : LPDWORD; fWait : BOOL; var lpdwFlags : DWORD) : WordBool; stdcall; - {$EXTERNALSYM LPFN_WSAIOCTL} - LPFN_WSAIOCTL = function(const s : TSocket; dwIoControlCode : DWORD; lpvInBuffer : Pointer; cbInBuffer : DWORD; lpvOutBuffer : Pointer; cbOutBuffer : DWORD; - lpcbBytesReturned : LPDWORD; AOverlapped: Pointer; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSARECVFROM} - LPFN_WSARECVFROM = function(const s : TSocket; lpBuffers : LPWSABUF; dwBufferCount : DWORD; var lpNumberOfBytesRecvd : DWORD; var lpFlags : DWORD; - lpFrom : PSOCKADDR; lpFromlen : PInteger; AOverlapped: Pointer; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; - - {$EXTERNALSYM LPFN_TRANSMITFILE} - LPFN_TRANSMITFILE = function(hSocket: TSocket; hFile: THandle; nNumberOfBytesToWrite, nNumberOfBytesPerSend: DWORD; - lpOverlapped: POverlapped; lpTransmitBuffers: LPTRANSMIT_FILE_BUFFERS; dwReserved: DWORD): BOOL; stdcall; - {$EXTERNALSYM LPFN_ACCEPTEX} - LPFN_ACCEPTEX = function(sListenSocket, sAcceptSocket: TSocket; - lpOutputBuffer: Pointer; dwReceiveDataLength, dwLocalAddressLength, - dwRemoteAddressLength: DWORD; var lpdwBytesReceived: DWORD; - lpOverlapped: POverlapped): BOOL; stdcall; - {$IFNDEF WINCE} - {$EXTERNALSYM LPFN_WSACONNECTBYLIST} - LPFN_WSACONNECTBYLIST = function(const s : TSocket; SocketAddressList : PSOCKET_ADDRESS_LIST; - var LocalAddressLength : DWORD; LocalAddress : LPSOCKADDR; - var RemoteAddressLength : DWORD; RemoteAddress : LPSOCKADDR; - timeout : Ptimeval; Reserved : LPWSAOVERLAPPED):LongBool; stdcall; - {$EXTERNALSYM LPFN_WSACONNECTBYNAMEA} - LPFN_WSACONNECTBYNAMEA = function(const s : TSOCKET; - nodename : PIdAnsiChar; servicename : PIdAnsiChar; - var LocalAddressLength : DWORD; LocalAddress : LPSOCKADDR; - var RemoteAddressLength : DWORD; RemoteAddress : LPSOCKADDR; - timeout : Ptimeval; Reserved : LPWSAOVERLAPPED) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSACONNECTBYNAMEW} - LPFN_WSACONNECTBYNAMEW = function(const s : TSOCKET; - nodename : PWChar; servicename : PWChar; - var LocalAddressLength : DWORD; LocalAddress : LPSOCKADDR; - var RemoteAddressLength : DWORD; RemoteAddress : LPSOCKADDR; - timeout : Ptimeval; Reserved : LPWSAOVERLAPPED) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSACONNECTBYNAME} - {$IFDEF UNICODE} - LPFN_WSACONNECTBYNAME = LPFN_WSACONNECTBYNAMEW; - {$ELSE} - LPFN_WSACONNECTBYNAME = LPFN_WSACONNECTBYNAMEA; - {$ENDIF} -{$ENDIF} - - {$EXTERNALSYM LPFN_WSAENUMPROTOCOLS} - {wince} - {$IFDEF UNICODE} - LPFN_WSAENUMPROTOCOLS = LPFN_WSAENUMPROTOCOLSW; - {$ELSE} - LPFN_WSAENUMPROTOCOLS = LPFN_WSAENUMPROTOCOLSA; - {$ENDIF} - - {$EXTERNALSYM LPFN_WSACLOSEEVENT} - LPFN_WSACLOSEEVENT = function(const hEvent : WSAEVENT) : WordBool; stdcall; - {$EXTERNALSYM LPFN_WSACONNECT} - LPFN_WSACONNECT = function(const s : TSocket; const name : PSOCKADDR; const namelen : Integer; lpCallerData, lpCalleeData : LPWSABUF; lpSQOS, lpGQOS : LPQOS) : Integer; stdcall; - - {$EXTERNALSYM LPFN_WSACREATEEVENT} - LPFN_WSACREATEEVENT = function: WSAEVENT; stdcall; - - {$IFNDEF WINCE} - {$EXTERNALSYM LPFN_WSADUPLICATESOCKETA} - LPFN_WSADUPLICATESOCKETA = function(const s : TSocket; const dwProcessId : DWORD; lpProtocolInfo : LPWSAPROTOCOL_INFOA) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSADUPLICATESOCKETW} - LPFN_WSADUPLICATESOCKETW = function(const s : TSocket; const dwProcessId : DWORD; lpProtocolInfo : LPWSAPROTOCOL_INFOW) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSADUPLICATESOCKET} - {$IFDEF UNICODE} - LPFN_WSADUPLICATESOCKET = LPFN_WSADUPLICATESOCKETW; - {$ELSE} - LPFN_WSADUPLICATESOCKET = LPFN_WSADUPLICATESOCKETA; - {$ENDIF} - {$ENDIF} - - {$EXTERNALSYM LPFN_WSAENUMNETWORKEVENTS} - LPFN_WSAENUMNETWORKEVENTS = function(const s : TSocket; const hEventObject : WSAEVENT; lpNetworkEvents : LPWSANETWORKEVENTS) :Integer; stdcall; - - {$EXTERNALSYM LPFN_WSAEVENTSELECT} - LPFN_WSAEVENTSELECT = function(const s : TSocket; const hEventObject : WSAEVENT; lNetworkEvents : LongInt): Integer; stdcall; - {$EXTERNALSYM LPFN_WSAGETQOSBYNAME} - LPFN_WSAGETQOSBYNAME = function(const s : TSocket; lpQOSName : LPWSABUF; lpQOS : LPQOS): WordBool; stdcall; - {$EXTERNALSYM LPFN_WSAHTONL} - LPFN_WSAHTONL = function(const s : TSocket; hostlong : u_long; var lpnetlong : DWORD): Integer; stdcall; - {$EXTERNALSYM LPFN_WSAHTONS} - LPFN_WSAHTONS = function(const s : TSocket; hostshort : u_short; var lpnetshort : WORD): Integer; stdcall; - - {$EXTERNALSYM LPFN_WSAJOINLEAF} - LPFN_WSAJOINLEAF = function(const s : TSocket; name : PSOCKADDR; namelen : Integer; lpCallerData, lpCalleeData : LPWSABUF; - lpSQOS,lpGQOS : LPQOS; dwFlags : DWORD) : TSocket; stdcall; - - {$EXTERNALSYM LPFN_WSANTOHL} - LPFN_WSANTOHL = function(const s : TSocket; netlong : u_long; var lphostlong : DWORD): Integer; stdcall; - {$EXTERNALSYM LPFN_WSANTOHS} - LPFN_WSANTOHS = function(const s : TSocket; netshort : u_short; var lphostshort : WORD): Integer; stdcall; - - {$EXTERNALSYM LPFN_WSARECV} - LPFN_WSARECV = function(const s : TSocket; lpBuffers : LPWSABUF; dwBufferCount : DWORD; var lpNumberOfBytesRecvd : DWORD; var lpFlags : DWORD; - lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; - {$EXTERNALSYM LPFN_WSARECVDISCONNECT} - LPFN_WSARECVDISCONNECT = function(const s : TSocket; lpInboundDisconnectData : LPWSABUF): Integer; stdcall; - - {$EXTERNALSYM LPFN_WSARESETEVENT} - LPFN_WSARESETEVENT = function(hEvent : WSAEVENT): WordBool; stdcall; - - {$EXTERNALSYM LPFN_WSASEND} - LPFN_WSASEND = function(const s : TSocket; lpBuffers : LPWSABUF; dwBufferCount : DWORD; var lpNumberOfBytesSent : DWORD; dwFlags : DWORD; - lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; - {$EXTERNALSYM LPFN_WSASENDDISCONNECT} - LPFN_WSASENDDISCONNECT = function(const s : TSocket; lpOutboundDisconnectData : LPWSABUF): Integer; stdcall; - {$EXTERNALSYM LPFN_WSASENDTO} - LPFN_WSASENDTO = function(const s : TSocket; lpBuffers : LPWSABUF; dwBufferCount : DWORD; var lpNumberOfBytesSent : DWORD; dwFlags : DWORD; - lpTo : LPSOCKADDR; iTolen : Integer; lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; - - {$EXTERNALSYM LPFN_WSASETEVENT} - LPFN_WSASETEVENT = function(hEvent : WSAEVENT): WordBool; stdcall; - - {$EXTERNALSYM LPFN_WSASOCKETA} - LPFN_WSASOCKETA = function(af, iType, protocol : Integer; lpProtocolInfo : LPWSAPROTOCOL_INFOA; g : GROUP; dwFlags : DWORD): TSocket; stdcall; - {$EXTERNALSYM LPFN_WSASOCKETW} - LPFN_WSASOCKETW = function(af, iType, protocol : Integer; lpProtocolInfo : LPWSAPROTOCOL_INFOW; g : GROUP; dwFlags : DWORD): TSocket; stdcall; - {$EXTERNALSYM LPFN_WSASOCKET} - {$IFDEF UNICODE} - LPFN_WSASOCKET = LPFN_WSASOCKETW; - {$ELSE} - LPFN_WSASOCKET = LPFN_WSASOCKETA; - {$ENDIF} - - {$EXTERNALSYM LPFN_WSAWAITFORMULTIPLEEVENTS} - LPFN_WSAWAITFORMULTIPLEEVENTS = function(cEvents : DWORD; lphEvents : PWSAEVENT; fWaitAll : LongBool; - dwTimeout : DWORD; fAlertable : LongBool): DWORD; stdcall; - - {$EXTERNALSYM LPFN_WSAADDRESSTOSTRINGA} - LPFN_WSAADDRESSTOSTRINGA = function(lpsaAddress : PSOCKADDR; const dwAddressLength : DWORD; const lpProtocolInfo : LPWSAPROTOCOL_INFOA; - const lpszAddressString : PIdAnsiChar; var lpdwAddressStringLength : DWORD): Integer; stdcall; - {$EXTERNALSYM LPFN_WSAADDRESSTOSTRINGW} - LPFN_WSAADDRESSTOSTRINGW = function(lpsaAddress : PSOCKADDR; const dwAddressLength : DWORD; const lpProtocolInfo : LPWSAPROTOCOL_INFOW; - const lpszAddressString : PWideChar; var lpdwAddressStringLength : DWORD): Integer; stdcall; - {$EXTERNALSYM LPFN_WSAADDRESSTOSTRING} - {$IFDEF UNICODE} - LPFN_WSAADDRESSTOSTRING = LPFN_WSAADDRESSTOSTRINGW; - {$ELSE} - LPFN_WSAADDRESSTOSTRING = LPFN_WSAADDRESSTOSTRINGA; - {$ENDIF} - - {$EXTERNALSYM LPFN_WSASTRINGTOADDRESSA} - LPFN_WSASTRINGTOADDRESSA = function(const AddressString : PIdAnsiChar; const AddressFamily: Integer; const lpProtocolInfo : LPWSAPROTOCOL_INFOA; - var lpAddress : TSockAddr; var lpAddressLength : Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_WSASTRINGTOADDRESSW} - LPFN_WSASTRINGTOADDRESSW = function(const AddressString : PWideChar; const AddressFamily: Integer; const lpProtocolInfo : LPWSAPROTOCOL_INFOW; - var lpAddress : TSockAddr; var lpAddressLength : Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_WSASTRINGTOADDRESS} - {$IFDEF UNICODE} - LPFN_WSASTRINGTOADDRESS = LPFN_WSASTRINGTOADDRESSW; - {$ELSE} - LPFN_WSASTRINGTOADDRESS = LPFN_WSASTRINGTOADDRESSA; - {$ENDIF} - -// Registration and Name Resolution API functions - {$EXTERNALSYM LPFN_WSALOOKUPSERVICEBEGINA} - LPFN_WSALOOKUPSERVICEBEGINA = function(var qsRestrictions : TWSAQuerySetA; const dwControlFlags : DWORD; var hLookup : THandle): Integer; stdcall; - {$EXTERNALSYM LPFN_WSALOOKUPSERVICEBEGINw} - LPFN_WSALOOKUPSERVICEBEGINW = function(var qsRestrictions : TWSAQuerySetW; const dwControlFlags : DWORD; var hLookup : THandle): Integer; stdcall; - {$EXTERNALSYM LPFN_WSALOOKUPSERVICEBEGIN} - {$IFDEF UNICODE} - LPFN_WSALOOKUPSERVICEBEGIN = LPFN_WSALOOKUPSERVICEBEGINW; - {$ELSE} - LPFN_WSALOOKUPSERVICEBEGIN = LPFN_WSALOOKUPSERVICEBEGINA; - {$ENDIF} - - {$EXTERNALSYM LPFN_WSALOOKUPSERVICENEXTA} - LPFN_WSALOOKUPSERVICENEXTA = function(const hLookup : THandle; const dwControlFlags : DWORD; var dwBufferLength : DWORD; lpqsResults : PWSAQUERYSETA): Integer; stdcall; - {$EXTERNALSYM LPFN_WSALOOKUPSERVICENEXTW} - LPFN_WSALOOKUPSERVICENEXTW = function(const hLookup : THandle; const dwControlFlags : DWORD; var dwBufferLength : DWORD; lpqsResults : PWSAQUERYSETW): Integer; stdcall; - {$EXTERNALSYM LPFN_WSALOOKUPSERVICENEXT} - {$IFDEF UNICODE} - LPFN_WSALOOKUPSERVICENEXT = LPFN_WSALOOKUPSERVICENEXTW; - {$ELSE} - LPFN_WSALOOKUPSERVICENEXT = LPFN_WSALOOKUPSERVICENEXTA; - {$ENDIF} - - //WinCE 4.20 doesn't support WSANSPIoctl but later versions do. - {$EXTERNALSYM LPFN_WSANSPIOCTL} - LPFN_WSANSPIOCTL = function(const hLookup : THANDLE; const dwControlCode : DWORD; lpvInBuffer : Pointer; var cbInBuffer : DWORD; lpvOutBuffer : Pointer; var cbOutBuffer : DWORD; var lpcbBytesReturned : DWORD; lpCompletion : LPWSACOMPLETION) : Integer; stdcall; - - {$EXTERNALSYM LPFN_WSALOOKUPSERVICEEND} - LPFN_WSALOOKUPSERVICEEND = function(const hLookup : THandle): Integer; stdcall; - - - {$EXTERNALSYM LPFN_WSAINSTALLSERVICECLASSA} - LPFN_WSAINSTALLSERVICECLASSA = function(const lpServiceClassInfo : LPWSASERVICECLASSINFOA) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSAINSTALLSERVICECLASSW} - LPFN_WSAINSTALLSERVICECLASSW = function(const lpServiceClassInfo : LPWSASERVICECLASSINFOW) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSAINSTALLSERVICECLASS} - {$IFDEF UNICODE} - LPFN_WSAINSTALLSERVICECLASS = LPFN_WSAINSTALLSERVICECLASSW; - {$ELSE} - LPFN_WSAINSTALLSERVICECLASS = LPFN_WSAINSTALLSERVICECLASSA; - {$ENDIF} - - {$EXTERNALSYM LPFN_WSAREMOVESERVICECLASS} - LPFN_WSAREMOVESERVICECLASS = function(const lpServiceClassId : LPGUID) : Integer; stdcall; - - {$EXTERNALSYM LPFN_WSAGETSERVICECLASSINFOA} - LPFN_WSAGETSERVICECLASSINFOA = function(const lpProviderId : LPGUID; const lpServiceClassId : LPGUID; var lpdwBufSize : DWORD; - lpServiceClassInfo : LPWSASERVICECLASSINFOA): Integer; stdcall; - {$EXTERNALSYM LPFN_WSAGETSERVICECLASSINFOW} - LPFN_WSAGETSERVICECLASSINFOW = function(const lpProviderId : LPGUID; const lpServiceClassId : LPGUID; var lpdwBufSize : DWORD; - lpServiceClassInfo : LPWSASERVICECLASSINFOW): Integer; stdcall; - {$EXTERNALSYM LPFN_WSAGETSERVICECLASSINFO} - {$IFDEF UNICODE} - LPFN_WSAGETSERVICECLASSINFO = LPFN_WSAGETSERVICECLASSINFOW; - {$ELSE} - LPFN_WSAGETSERVICECLASSINFO = LPFN_WSAGETSERVICECLASSINFOA; - {$ENDIF} - {$ENDIF} - - {$EXTERNALSYM LPFN_WSAENUMNAMESPACEPROVIDERSA} - LPFN_WSAENUMNAMESPACEPROVIDERSA = function(var lpdwBufferLength: DWORD; const lpnspBuffer: LPWSANAMESPACE_INFOA): Integer; stdcall; - {$EXTERNALSYM LPFN_WSAENUMNAMESPACEPROVIDERSW} - LPFN_WSAENUMNAMESPACEPROVIDERSW = function(var lpdwBufferLength: DWORD; const lpnspBuffer: LPWSANAMESPACE_INFOW): Integer; stdcall; - {$EXTERNALSYM LPFN_WSAENUMNAMESPACEPROVIDERS} - {$IFDEF UNICODE} - LPFN_WSAENUMNAMESPACEPROVIDERS = LPFN_WSAENUMNAMESPACEPROVIDERSW; - {$ELSE} - LPFN_WSAENUMNAMESPACEPROVIDERS = LPFN_WSAENUMNAMESPACEPROVIDERSA; - {$ENDIF} - - {$EXTERNALSYM LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDA} - LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDA = function(const lpServiceClassId: LPGUID; lpszServiceClassName: PIdAnsiChar; var lpdwBufferLength: DWORD): Integer; stdcall; - {$EXTERNALSYM LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDW} - LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDW = function(const lpServiceClassId: LPGUID; lpszServiceClassName: PWideChar; var lpdwBufferLength: DWORD): Integer; stdcall; - {$EXTERNALSYM LPFN_WSAGETSERVICECLASSNAMEBYCLASSID} - {$IFDEF UNICODE} - LPFN_WSAGETSERVICECLASSNAMEBYCLASSID = LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDW; - {$ELSE} - LPFN_WSAGETSERVICECLASSNAMEBYCLASSID = LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDA; - {$ENDIF} - - {$EXTERNALSYM LPFN_WSASETSERVICEA} - LPFN_WSASETSERVICEA = function(const lpqsRegInfo: LPWSAQUERYSETA; const essoperation: WSAESETSERVICEOP; const dwControlFlags: DWORD): Integer; stdcall; - {$EXTERNALSYM LPFN_WSASETSERVICEW} - LPFN_WSASETSERVICEW = function(const lpqsRegInfo: LPWSAQUERYSETW; const essoperation: WSAESETSERVICEOP; const dwControlFlags: DWORD): Integer; stdcall; - {$EXTERNALSYM LPFN_WSASETSERVICE} - {$IFDEF UNICODE} - LPFN_WSASETSERVICE = LPFN_WSASETSERVICEW; - {$ELSE} - LPFN_WSASETSERVICE = LPFN_WSASETSERVICEA; - {$ENDIF} - - {$EXTERNALSYM LPFN_WSAPROVIDERCONFIGCHANGE} - LPFN_WSAPROVIDERCONFIGCHANGE = function(var lpNotificationHandle : THandle; lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; - - //microsoft specific extension - {$EXTERNALSYM LPFN_GETACCEPTEXSOCKADDRS} - LPFN_GETACCEPTEXSOCKADDRS = procedure(lpOutputBuffer: Pointer; - dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: DWORD; - var LocalSockaddr: TSockAddr; var LocalSockaddrLength: Integer; - var RemoteSockaddr: TSockAddr; var RemoteSockaddrLength: Integer); stdcall; - - {$IFNDEF WINCE} - //This is defined in the Windows Mobile 6 Standard SDK Refresh - //but I'm not sure what .DLL the function is in. I also couldn't find a WSAID - //constant for it. - {$EXTERNALSYM LPFN_WSARECVEX} - LPFN_WSARECVEX = function(s: TSocket; var buf; len: Integer; var flags: Integer): Integer; stdcall; - {$ENDIF} - - //Windows Server 2003, Windows Vista - {$EXTERNALSYM LPFN_CONNECTEX} - LPFN_CONNECTEX = function(const s : TSocket; const name: PSOCKADDR; const namelen: Integer; lpSendBuffer : Pointer; dwSendDataLength : DWORD; var lpdwBytesSent : DWORD; lpOverlapped : LPWSAOVERLAPPED) : BOOL; stdcall; - {$EXTERNALSYM LPFN_DISCONNECTEX} - LPFN_DISCONNECTEX = function(const hSocket : TSocket; AOverlapped: Pointer; const dwFlags : DWORD; const dwReserved : DWORD) : BOOL; stdcall; - {$EXTERNALSYM LPFN_WSARECVMSG} //XP and Server 2003 only - LPFN_WSARECVMSG = function(const s : TSocket; lpMsg : LPWSAMSG; var lpNumberOfBytesRecvd : DWORD; AOverlapped: Pointer; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; - {$EXTERNALSYM LPFN_TRANSMITPACKETS} - LPFN_TRANSMITPACKETS = function(s: TSocket; lpPacketArray: LPTRANSMIT_PACKETS_ELEMENT; nElementCount: DWORD; nSendSize: DWORD; lpOverlapped: LPWSAOVERLAPPED; dwFlags: DWORD): BOOL; stdcall; - //Windows Vista, Windows Server 2008 -{$IFNDEF WINCE} - {$EXTERNALSYM LPFN_WSASENDMSG} - LPFN_WSASENDMSG = function(const s : TSocket; lpMsg : LPWSAMSG; const dwFlags : DWORD; var lpNumberOfBytesSent : DWORD; lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSAPOLL} - LPFN_WSAPOLL = function(fdarray : LPWSAPOLLFD; const nfds : u_long; const timeout : Integer) : Integer; stdcall; - {$EXTERNALSYM LPFN_RIORECEIVE} - LPFN_RIORECEIVE = function (SocketQueue : RIO_RQ; - pData : PRIO_BUF; - const DataBufferCount : ULONG; - Flags : DWORD; - RequestContext : PVOID) : BOOL stdcall; - {$EXTERNALSYM LPFN_RIORECEIVEEX} - LPFN_RIORECEIVEEX = function (SocketQueu : RIO_RQ; - pData : PRIO_BUF; - const DataBufferCount : ULONG; - pLocalAddress, pRemoteAddress, pControlContext, pFlags : PRIO_BUF; - const Flags : DWORD; RequestContext : PVOID) : Integer stdcall; - {$EXTERNALSYM LPFN_RIOSEND} - LPFN_RIOSEND = function(SocketQueue : RIO_RQ; - pData : PRIO_BUF; - const DataBufferCount : ULONG; - const Flags : DWORD; - const RequestContext : PVOID) : Boolean stdcall; - {$EXTERNALSYM LPFN_RIOSENDEX} - LPFN_RIOSENDEX = function (SocketQueue : RIO_RQ; - pData : PRIO_BUF; - const DataBufferCount : ULONG; - pLocalAddress, pRemoteAddress, pControlContext, pFlags : PRIO_BUF; - const Flags : DWORD; - RequestContext : PVOID) : Boolean stdcall; - {$EXTERNALSYM LPFN_RIOCREATECOMPLETIONQUEUE} - LPFN_RIOCREATECOMPLETIONQUEUE = function (const QueueSize : DWORD; - NotificationCompletion : PRIO_NOTIFICATION_COMPLETION) : RIO_CQ stdcall; - {$EXTERNALSYM LPFN_RIOCREATEREQUESTQUEUE} - LPFN_RIOCREATEREQUESTQUEUE = function (const Socket : TSOCKET; - const MaxOutstandingReceive, MaxReceiveDataBuffers, MaxOutstandingSend, MaxSendDataBuffers : ULONG; - const ReceiveCQ, SendCQ : RIO_CQ; SocketContext : PVOID) : RIO_RQ stdcall; - {$EXTERNALSYM LPFN_RIODEQUEUECOMPLETION} - LPFN_RIODEQUEUECOMPLETION = function (const CQ : RIO_CQ; _Array : PRIORESULT; const ArraySize : ULONG) : ULONG stdcall; - {$EXTERNALSYM LPFN_RIODEREGISTERBUFFER} - LPFN_RIODEREGISTERBUFFER = procedure (const BufferId : RIO_BUFFERID) stdcall; - {$EXTERNALSYM LPFN_RIONOTIFY} - LPFN_RIONOTIFY = function (CQ : RIO_CQ) : Integer stdcall; - {$EXTERNALSYM LPFN_RIOREGISTERBUFFER} - LPFN_RIOREGISTERBUFFER = function (DataBuffer : PIdAnsiChar; const DataLength : DWORD) : BOOL stdcall; - {$EXTERNALSYM LPFN_RIORESIZECOMPLETIONQUEUE} - LPFN_RIORESIZECOMPLETIONQUEUE = function(const CQ : RIO_CQ; const QueueSize : DWORD) : BOOL stdcall; - {$EXTERNALSYM LPFN_RIORESIZEREQUESTQUEUE} - LPFN_RIORESIZEREQUESTQUEUE = function(const RQ : RIO_RQ; const MaxOutstandingReceive, MaxOutstandingSend : DWORD) : BOOL stdcall; - {$EXTERNALSYM LPFN_RIOCLOSECOMPLETIONQUEUE} - LPFN_RIOCLOSECOMPLETIONQUEUE = procedure (const CQ : RIO_CQ) stdcall; - {$EXTERNALSYM _RIO_EXTENSION_FUNCTION_TABLE} - _RIO_EXTENSION_FUNCTION_TABLE = record - cbSize : DWORD; - RIOReceive : LPFN_RIORECEIVE; - RIOReceiveEx : LPFN_RIORECEIVEEX; - RIOSend : LPFN_RIOSEND; - RIOSendEx : LPFN_RIOSENDEX; - RIOCloseCompletionQueue : LPFN_RIOCLOSECOMPLETIONQUEUE; - RIOCreateCompletionQueue : LPFN_RIOCREATECOMPLETIONQUEUE; - RIOCreateRequestQueue : LPFN_RIOCREATEREQUESTQUEUE; - RIODequeueCompletion : LPFN_RIODEQUEUECOMPLETION; - RIODeregisterBuffer : LPFN_RIODEREGISTERBUFFER; - RIONotify : LPFN_RIONOTIFY; - RIORegisterBuffer : LPFN_RIOREGISTERBUFFER; - RIOResizeCompletionQueue : LPFN_RIORESIZECOMPLETIONQUEUE; - RIOResizeRequestQueue : LPFN_RIORESIZEREQUESTQUEUE; - end; - {$EXTERNALSYM RIO_EXTENSION_FUNCTION_TABLE} - RIO_EXTENSION_FUNCTION_TABLE = _RIO_EXTENSION_FUNCTION_TABLE; - {$EXTERNALSYM PRIO_EXTENSION_FUNCTION_TABLE} - PRIO_EXTENSION_FUNCTION_TABLE = ^RIO_EXTENSION_FUNCTION_TABLE; -{$ENDIF} // $IFDEF INCL_WINSOCK_API_TYPEDEFS - - -const - //GUID's for Microsoft extensions - {$EXTERNALSYM WSAID_ACCEPTEX} - WSAID_ACCEPTEX: TGuid = (D1:$b5367df1;D2:$cbac;D3:$11cf;D4:($95,$ca,$00,$80,$5f,$48,$a1,$92)); - {$EXTERNALSYM WSAID_CONNECTEX} - WSAID_CONNECTEX: TGuid = (D1:$25a207b9;D2:$ddf3;D3:$4660;D4:($8e,$e9,$76,$e5,$8c,$74,$06,$3e)); - {$EXTERNALSYM WSAID_DISCONNECTEX} - WSAID_DISCONNECTEX: TGuid = (D1:$7fda2e11;D2:$8630;D3:$436f;D4:($a0,$31,$f5,$36,$a6,$ee,$c1,$57)); - {$EXTERNALSYM WSAID_GETACCEPTEXSOCKADDRS} - WSAID_GETACCEPTEXSOCKADDRS: TGuid = (D1:$b5367df2;D2:$cbac;D3:$11cf;D4:($95,$ca,$00,$80,$5f,$48,$a1,$92)); - {$EXTERNALSYM WSAID_TRANSMITFILE} - WSAID_TRANSMITFILE: TGuid = (D1:$b5367df0; D2:$cbac; D3:$11cf; D4:($95, $ca, $00, $80, $5f, $48, $a1, $92)); - {$EXTERNALSYM WSAID_TRANSMITPACKETS} - WSAID_TRANSMITPACKETS: TGuid = (D1:$d9689da0;D2:$1f90;D3:$11d3;D4:($99,$71,$00,$c0,$4f,$68,$c8,$76)); -{$IFNDEF WINCE} - {$EXTERNALSYM WSAID_WSAPOLL} - WSAID_WSAPOLL: TGuid = (D1:$18C76F85;D2:$DC66;D3:$4964;D4:($97,$2E,$23,$C2,$72,$38,$31,$2B)); -{$ENDIF} - {$EXTERNALSYM WSAID_WSARECVMSG} - WSAID_WSARECVMSG: TGuid = (D1:$f689d7c8;D2:$6f1f;D3:$436b;D4:($8a,$53,$e5,$4f,$e3,$51,$c3,$22)); -{$IFNDEF WINCE} - {$EXTERNALSYM WSAID_WSASENDMSG} - WSAID_WSASENDMSG : TGuid = (D1:$a441e712;D2:$754f;D3:$43ca;D4:($84,$a7,$0d,$ee,$44,$cf,$60,$6d)); - {$EXTERNALSYM WSAID_MULTIPLE_RIO} - WSAID_MULTIPLE_RIO : TGuid = (D1:$8509e081;D2:$96dd;D3:$4005;D4:($b1,$65,$9e,$2e,$e8,$c7,$9e,$3f)); -{$ENDIF} - -{$IFDEF WS2_DLL_FUNC_VARS} -var - {$EXTERNALSYM WSAStartup} - WSAStartup : LPFN_WSASTARTUP = nil; - {$EXTERNALSYM WSACleanup} - WSACleanup : LPFN_WSACLEANUP = nil; - {$EXTERNALSYM accept} - accept : LPFN_ACCEPT = nil; - {$EXTERNALSYM bind} - bind : LPFN_BIND = nil; - {$EXTERNALSYM closesocket} - closesocket : LPFN_CLOSESOCKET = nil; - {$EXTERNALSYM connect} - connect : LPFN_CONNECT = nil; - {$EXTERNALSYM ioctlsocket} - ioctlsocket : LPFN_IOCTLSOCKET = nil; - {$EXTERNALSYM getpeername} - getpeername : LPFN_GETPEERNAME = nil; - {$EXTERNALSYM getsockname} - getsockname : LPFN_GETSOCKNAME = nil; - {$EXTERNALSYM getsockopt} - getsockopt : LPFN_GETSOCKOPT = nil; - {$EXTERNALSYM htonl} - htonl : LPFN_HTONL = nil; - {$EXTERNALSYM htons} - htons : LPFN_HTONS = nil; - {$EXTERNALSYM inet_addr} - inet_addr : LPFN_INET_ADDR = nil; - {$EXTERNALSYM inet_ntoa} - inet_ntoa : LPFN_INET_NTOA = nil; - {$EXTERNALSYM listen} - listen : LPFN_LISTEN = nil; - {$EXTERNALSYM ntohl} - ntohl : LPFN_NTOHL = nil; - {$EXTERNALSYM ntohs} - ntohs : LPFN_NTOHS = nil; - {$EXTERNALSYM recv} - recv : LPFN_RECV = nil; - {$EXTERNALSYM recvfrom} - recvfrom : LPFN_RECVFROM = nil; - {$EXTERNALSYM select} - select : LPFN_SELECT = nil; - {$EXTERNALSYM send} - send : LPFN_SEND = nil; - {$EXTERNALSYM sendto} - sendto : LPFN_SENDTO = nil; - {$EXTERNALSYM setsockopt} - setsockopt : LPFN_SETSOCKOPT = nil; - {$EXTERNALSYM shutdown} - shutdown : LPFN_SHUTDOWN = nil; - {$EXTERNALSYM socket} - socket : LPFN_SOCKET = nil; - {$EXTERNALSYM gethostbyaddr} - gethostbyaddr : LPFN_GETHOSTBYADDR = nil; - {$EXTERNALSYM gethostbyname} - gethostbyname : LPFN_GETHOSTBYNAME = nil; - {$EXTERNALSYM gethostname} - gethostname : LPFN_GETHOSTNAME = nil; - {$IFDEF WINCE} - {$EXTERNALSYM sethostname} - sethostname : LPFN_SETHOSTNAME = nil; - {$ENDIF} - {$EXTERNALSYM getservbyport} - getservbyport : LPFN_GETSERVBYPORT = nil; - {$EXTERNALSYM getservbyname} - getservbyname : LPFN_GETSERVBYNAME = nil; - {$EXTERNALSYM getprotobynumber} - getprotobynumber : LPFN_GETPROTOBYNUMBER = nil; - {$EXTERNALSYM getprotobyname} - getprotobyname : LPFN_GETPROTOBYNAME = nil; - {$EXTERNALSYM WSASetLastError} - WSASetLastError : LPFN_WSASETLASTERROR = nil; - {$EXTERNALSYM WSAGetLastError} - WSAGetLastError : LPFN_WSAGETLASTERROR = nil; -{$IFNDEF WINCE} - {$EXTERNALSYM WSAIsblocking} - WSAIsBlocking : LPFN_WSAISBLOCKING = nil; - {$EXTERNALSYM WSAUnhookBlockingHook} - WSAUnhookBlockingHook : LPFN_WSAUNHOOKBLOCKINGHOOK = nil; - {$EXTERNALSYM WSASetBlockingHook} - WSASetBlockingHook : LPFN_WSASETBLOCKINGHOOK = nil; - {$EXTERNALSYM WSACancelBlockingCall} - WSACancelBlockingCall : LPFN_WSACANCELBLOCKINGCALL = nil; - {$EXTERNALSYM WSAAsyncGetServByName} - WSAAsyncGetServByName : LPFN_WSAASYNCGETSERVBYNAME = nil; - {$EXTERNALSYM WSAAsyncGetServByPort} - WSAAsyncGetServByPort : LPFN_WSAASYNCGETSERVBYPORT = nil; - {$EXTERNALSYM WSAAsyncGetProtoByName} - WSAAsyncGetProtoByName : LPFN_WSAASYNCGETPROTOBYNAME = nil; - {$EXTERNALSYM WSAAsyncGetProtoByNumber} - WSAAsyncGetProtoByNumber : LPFN_WSAASYNCGETPROTOBYNUMBER = nil; - {$EXTERNALSYM WSAAsyncGetHostByName} - WSAAsyncGetHostByName : LPFN_WSAASYNCGETHOSTBYNAME = nil; - {$EXTERNALSYM WSAAsyncGetHostByAddr} - WSAAsyncGetHostByAddr : LPFN_WSAASYNCGETHOSTBYADDR = nil; - {$EXTERNALSYM WSACancelAsyncRequest} - WSACancelAsyncRequest : LPFN_WSACANCELASYNCREQUEST = nil; - {$EXTERNALSYM WSAAsyncSelect} - WSAAsyncSelect : LPFN_WSAASYNCSELECT = nil; -{$ENDIF} - {$EXTERNALSYM __WSAFDIsSet} - __WSAFDIsSet : LPFN___WSAFDISSET = nil; - {$EXTERNALSYM WSAAccept} - WSAAccept : LPFN_WSAACCEPT = nil; - {$EXTERNALSYM WSAAddressToStringA} - WSAAddressToStringA : LPFN_WSAADDRESSTOSTRINGA = nil; - {$EXTERNALSYM WSAAddressToStringW} - WSAAddressToStringW : LPFN_WSAADDRESSTOSTRINGW = nil; - {$EXTERNALSYM WSAAddressToString} - WSAAddressToString : LPFN_WSAADDRESSTOSTRING = nil; - {$EXTERNALSYM WSACloseEvent} - WSACloseEvent : LPFN_WSACLOSEEVENT = nil; - {$EXTERNALSYM WSAConnect} - WSAConnect : LPFN_WSACONNECT = nil; - {$EXTERNALSYM WSACreateEvent} - WSACreateEvent : LPFN_WSACREATEEVENT = nil; - {$IFNDEF WINCE} - {$EXTERNALSYM WSADuplicateSocketA} - WSADuplicateSocketA : LPFN_WSADUPLICATESOCKETA = nil; - {$EXTERNALSYM WSADuplicateSocketW} - WSADuplicateSocketW : LPFN_WSADUPLICATESOCKETW = nil; - {$EXTERNALSYM WSADuplicateSocket} - WSADuplicateSocket : LPFN_WSADUPLICATESOCKET = nil; - {$ENDIF} - {$EXTERNALSYM WSAEnumNetworkEvents} - WSAEnumNetworkEvents : LPFN_WSAENUMNETWORKEVENTS = nil; - {$EXTERNALSYM WSAEnumProtocolsA} - WSAEnumProtocolsA : LPFN_WSAENUMPROTOCOLSA = nil; - {$EXTERNALSYM WSAEnumProtocolsW} - WSAEnumProtocolsW : LPFN_WSAENUMPROTOCOLSW = nil; - {$EXTERNALSYM WSAEnumProtocols} - WSAEnumProtocols : LPFN_WSAENUMPROTOCOLS = nil; - {$EXTERNALSYM WSAEnumNameSpaceProvidersA} - WSAEnumNameSpaceProvidersA : LPFN_WSAENUMNAMESPACEPROVIDERSA = nil; - {$EXTERNALSYM WSAEnumNameSpaceProvidersW} - WSAEnumNameSpaceProvidersW : LPFN_WSAENUMNAMESPACEPROVIDERSW = nil; - {$EXTERNALSYM WSAEnumNameSpaceProviders} - WSAEnumNameSpaceProviders : LPFN_WSAENUMNAMESPACEPROVIDERS = nil; - {$EXTERNALSYM WSAEventSelect} - WSAEventSelect : LPFN_WSAEVENTSELECT = nil; - {$EXTERNALSYM WSAGetOverlappedResult} - WSAGetOverlappedResult : LPFN_WSAGETOVERLAPPEDRESULT = nil; - - {$EXTERNALSYM WSAGetQosByName} - WSAGetQosByName : LPFN_WSAGETQOSBYNAME = nil; - {$EXTERNALSYM WSAGetServiceClassInfoA} - WSAGetServiceClassInfoA : LPFN_WSAGETSERVICECLASSINFOA = nil; - {$EXTERNALSYM WSAGetServiceClassInfoW} - WSAGetServiceClassInfoW : LPFN_WSAGETSERVICECLASSINFOW = nil; - {$EXTERNALSYM WSAGetServiceClassInfo} - WSAGetServiceClassInfo : LPFN_WSAGETSERVICECLASSINFO = nil; - {$EXTERNALSYM WSAGetServiceClassNameByClassIdA} - WSAGetServiceClassNameByClassIdA : LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDA = nil; - {$EXTERNALSYM WSAGetServiceClassNameByClassIdW} - WSAGetServiceClassNameByClassIdW : LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDW = nil; - {$EXTERNALSYM WSAGetServiceClassNameByClassId} - WSAGetServiceClassNameByClassId : LPFN_WSAGETSERVICECLASSNAMEBYCLASSID = nil; - - {$EXTERNALSYM WSAHtonl} - WSAHtonl : LPFN_WSAHTONL = nil; - {$EXTERNALSYM WSAHtons} - WSAHtons : LPFN_WSAHTONS = nil; - {$EXTERNALSYM WSAIoctl} - WSAIoctl : LPFN_WSAIOCTL = nil; - {$EXTERNALSYM WSAInstallServiceClassA} - WSAInstallServiceClassA : LPFN_WSAINSTALLSERVICECLASSA = nil; - {$EXTERNALSYM WSAInstallServiceClassW} - WSAInstallServiceClassW : LPFN_WSAINSTALLSERVICECLASSW = nil; - {$EXTERNALSYM WSAInstallServiceClass} - WSAInstallServiceClass : LPFN_WSAINSTALLSERVICECLASS = nil; - {$EXTERNALSYM WSAJoinLeaf} - WSAJoinLeaf : LPFN_WSAJOINLEAF = nil; - {$EXTERNALSYM WSALookupServiceBeginA} - WSALookupServiceBeginA : LPFN_WSALOOKUPSERVICEBEGINA = nil; - {$EXTERNALSYM WSALookupServiceBeginW} - WSALookupServiceBeginW : LPFN_WSALOOKUPSERVICEBEGINW = nil; - {$EXTERNALSYM WSALookupServiceBegin} - WSALookupServiceBegin : LPFN_WSALOOKUPSERVICEBEGIN = nil; - {$EXTERNALSYM WSALookupServiceEnd} - WSALookupServiceEnd : LPFN_WSALOOKUPSERVICEEND = nil; - {$EXTERNALSYM WSALookupServiceNextA} - WSALookupServiceNextA : LPFN_WSALOOKUPSERVICENEXTA = nil; - {$EXTERNALSYM WSALookupServiceNextW} - WSALookupServiceNextW : LPFN_WSALOOKUPSERVICENEXTW = nil; - {$EXTERNALSYM WSALookupServiceNext} - WSALookupServiceNext : LPFN_WSALOOKUPSERVICENEXT = nil; - {$EXTERNALSYM WSANtohl} - WSANtohl : LPFN_WSANTOHL = nil; - {$EXTERNALSYM WSANtohs} - WSANtohs : LPFN_WSANTOHS = nil; - {$EXTERNALSYM WSARecv} - WSARecv : LPFN_WSARECV = nil; - {$EXTERNALSYM WSARecvDisconnect} - WSARecvDisconnect : LPFN_WSARECVDISCONNECT = nil; - {$EXTERNALSYM WSARecvFrom} - WSARecvFrom : LPFN_WSARECVFROM = nil; - {$EXTERNALSYM WSARemoveServiceClass} - WSARemoveServiceClass : LPFN_WSAREMOVESERVICECLASS = nil; - {$EXTERNALSYM WSAResetEvent} - WSAResetEvent : LPFN_WSARESETEVENT = nil; - {$EXTERNALSYM WSASend} - WSASend : LPFN_WSASEND = nil; - {$EXTERNALSYM WSASendDisconnect} - WSASendDisconnect : LPFN_WSASENDDISCONNECT = nil; - {$EXTERNALSYM WSASendTo} - WSASendTo : LPFN_WSASENDTO = nil; - {$EXTERNALSYM WSASetEvent} - WSASetEvent : LPFN_WSASETEVENT = nil; - {$EXTERNALSYM WSASetServiceA} - WSASetServiceA : LPFN_WSASETSERVICEA = nil; - {$EXTERNALSYM WSASetServiceW} - WSASetServiceW : LPFN_WSASETSERVICEW = nil; - {$EXTERNALSYM WSASetService} - WSASetService : LPFN_WSASETSERVICE = nil; - {$EXTERNALSYM WSASocketA} - WSASocketA : LPFN_WSASOCKETA = nil; - {$EXTERNALSYM WSASocketW} - WSASocketW : LPFN_WSASOCKETW = nil; - {$EXTERNALSYM WSASocket} - WSASocket : LPFN_WSASOCKET = nil; - {$EXTERNALSYM WSAStringToAddressA} - WSAStringToAddressA : LPFN_WSASTRINGTOADDRESSA = nil; - {$EXTERNALSYM WSAStringToAddressW} - WSAStringToAddressW : LPFN_WSASTRINGTOADDRESSW = nil; - {$EXTERNALSYM WSAStringToAddress} - WSAStringToAddress : LPFN_WSASTRINGTOADDRESS = nil; - - {$EXTERNALSYM WSAWaitForMultipleEvents} - WSAWaitForMultipleEvents : LPFN_WSAWAITFORMULTIPLEEVENTS = nil; - {$EXTERNALSYM WSAProviderConfigChange} - WSAProviderConfigChange : LPFN_WSAPROVIDERCONFIGCHANGE = nil; - {$EXTERNALSYM TransmitFile} - TransmitFile : LPFN_TRANSMITFILE = nil; - {$EXTERNALSYM AcceptEx} - AcceptEx : LPFN_ACCEPTEX = nil; - {$EXTERNALSYM GetAcceptExSockaddrs} - GetAcceptExSockaddrs : LPFN_GETACCEPTEXSOCKADDRS = nil; - {$IFNDEF WINCE} - //This is defined in the Windows Mobile 6 Standard SDK Refresh - //but I'm not sure what .DLL the function is in. I also couldn't find a WSAID - //constant for it. - {$EXTERNALSYM WSARecvEx} - WSARecvEx : LPFN_WSARECVEX = nil; - {$ENDIF} - {$EXTERNALSYM ConnectEx} - ConnectEx : LPFN_CONNECTEX = nil; - {$EXTERNALSYM DisconnectEx} - DisconnectEx : LPFN_DISCONNECTEX = nil; - {$EXTERNALSYM WSARecvMsg} - WSARecvMsg : LPFN_WSARECVMSG = nil; - {$EXTERNALSYM TransmitPackets} - TransmitPackets : LPFN_TRANSMITPACKETS = nil; - {$IFNDEF WINCE} - //Windows Vista, Windows Server 2008 - {$EXTERNALSYM WSASendMsg} - WSASendMsg: LPFN_WSASENDMSG = nil; - {$EXTERNALSYM WSAPoll} - WSAPoll: LPFN_WSAPOLL = nil; - {$ENDIF} - //WSANSPIoctl is not supported in WinCE 4.20 but is supported in later versions. - {$EXTERNALSYM WSANSPIoctl} - WSANSPIoctl : LPFN_WSANSPIOCTL = nil; -{$ENDIF} // $IFDEF WS2_DLL_FUNC_VARS - - { Macros } - {$EXTERNALSYM WSAMakeSyncReply} - function WSAMakeSyncReply(Buflen, AError: Word): Longint; - {$EXTERNALSYM WSAMakeSelectReply} - function WSAMakeSelectReply(Event, AError: Word): Longint; - {$EXTERNALSYM WSAGetAsyncBuflen} - function WSAGetAsyncBuflen(Param: LPARAM): Word; - {$EXTERNALSYM WSAGetAsyncError} - function WSAGetAsyncError(Param: LPARAM): Word; - {$EXTERNALSYM WSAGetSelectEvent} - function WSAGetSelectEvent(Param: LPARAM): Word; - {$EXTERNALSYM WSAGetSelectError} - function WSAGetSelectError(Param: LPARAM): Word; - - {$EXTERNALSYM FD_CLR} - procedure FD_CLR(ASocket: TSocket; var FDSet: TFDSet); - {$EXTERNALSYM FD_ISSET} - function FD_ISSET(ASocket: TSocket; var FDSet: TFDSet): Boolean; - {$EXTERNALSYM FD_SET} - procedure FD_SET(ASocket: TSocket; var FDSet: TFDSet); - {$EXTERNALSYM FD_ZERO} - procedure FD_ZERO(var FDSet: TFDSet); - - {$IFNDEF WINCE} -//Posix aliases for helper macros -// #define CMSGHDR_ALIGN WSA_CMSGHDR_ALIGN - {$EXTERNALSYM CMSGHDR_ALIGN} - function CMSGHDR_ALIGN(const Alength: SIZE_T): SIZE_T; -// #define CMSGDATA_ALIGN WSA_CMSGDATA_ALIGN - {$EXTERNALSYM CMSGDATA_ALIGN} - function CMSGDATA_ALIGN(const Alength: PtrUInt): PtrUInt; -//#define CMSG_FIRSTHDR WSA_CMSG_FIRSTHDR - {$EXTERNALSYM CMSG_FIRSTHDR} - function CMSG_FIRSTHDR(const msg: LPWSAMSG): LPWSACMSGHDR; -// #define CMSG_NXTHDR WSA_CMSG_NXTHDR - {$EXTERNALSYM CMSG_NXTHDR} - function CMSG_NXTHDR(const msg: LPWSAMSG; const cmsg: LPWSACMSGHDR): LPWSACMSGHDR; -// #define CMSG_SPACE WSA_CMSG_SPACE - {$EXTERNALSYM CMSG_SPACE} - function CMSG_SPACE(const Alength: PtrUInt): PtrUInt; -// #define CMSG_LEN WSA_CMSG_LEN - {$EXTERNALSYM CMSG_LEN} - function CMSG_LEN(const Alength: SIZE_T): SIZE_T; -// - {$EXTERNALSYM WSA_CMSGHDR_ALIGN} - function WSA_CMSGHDR_ALIGN(const Alength: PtrUInt): PtrUInt; - {$EXTERNALSYM WSA_CMSGDATA_ALIGN} - function WSA_CMSGDATA_ALIGN(const Alength: PtrUInt): PtrUInt; - {$EXTERNALSYM WSA_CMSG_FIRSTHDR} - function WSA_CMSG_FIRSTHDR(const msg: LPWSAMSG): LPWSACMSGHDR; -// #define CMSG_FIRSTHDR WSA_CMSG_FIRSTHDR - {$EXTERNALSYM WSA_CMSG_NXTHDR} - function WSA_CMSG_NXTHDR(const msg: LPWSAMSG; const cmsg: LPWSACMSGHDR): LPWSACMSGHDR; - - {$EXTERNALSYM WSA_CMSG_DATA} - function WSA_CMSG_DATA(const cmsg: LPWSACMSGHDR): PByte; - {$EXTERNALSYM WSA_CMSG_SPACE} - function WSA_CMSG_SPACE(const Alength: SIZE_T): SIZE_T; - {$EXTERNALSYM WSA_CMSG_LEN} - function WSA_CMSG_LEN(const Alength: SIZE_T): SIZE_T; - {$ENDIF} - -//============================================================= - -{ - WS2TCPIP.H - WinSock2 Extension for TCP/IP protocols - - This file contains TCP/IP specific information for use - by WinSock2 compatible applications. - - Copyright (c) 1995-1999 Microsoft Corporation - - To provide the backward compatibility, all the TCP/IP - specific definitions that were included in the WINSOCK.H - file are now included in WINSOCK2.H file. WS2TCPIP.H - file includes only the definitions introduced in the - "WinSock 2 Protocol-Specific Annex" document. - - Rev 0.3 Nov 13, 1995 - Rev 0.4 Dec 15, 1996 -} - -type -// Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP - {$EXTERNALSYM ip_mreq} - ip_mreq = record - imr_multiaddr : TInAddr; // IP multicast address of group - imr_interface : TInAddr; // local IP address of interface - end; - -// Argument structure for IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_SOURCE_MEMBERSHIP, -// IP_BLOCK_SOURCE, and IP_UNBLOCK_SOURCE - {$EXTERNALSYM ip_mreq_source} - ip_mreq_source = record - imr_multiaddr: TInAddr; // IP multicast address of group - imr_sourceaddr: TInAddr; // IP address of source - imr_interface: TInAddr; // local IP address of interface - end; - -// Argument structure for SIO_{GET,SET}_MULTICAST_FILTER - {$EXTERNALSYM ip_msfilter} - ip_msfilter = record - imsf_multiaddr: TInAddr; // IP multicast address of group - imsf_interface: TInAddr; // local IP address of interface - imsf_fmode: u_long; // filter mode - INCLUDE or EXCLUDE - imsf_numsrc: u_long; // number of sources in src_list - imsf_slist: Array[0..0] of TInAddr; - end; - - {$EXTERNALSYM IP_MSFILTER_SIZE} - function IP_MSFILTER_SIZE(const numsrc: DWORD): PtrUInt; - -// TCP/IP specific Ioctl codes -const - {$EXTERNALSYM SIO_GET_INTERFACE_LIST} - SIO_GET_INTERFACE_LIST = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or 127; {Do not Localize} -// New IOCTL with address size independent address array - {$EXTERNALSYM SIO_GET_INTERFACE_LIST_EX} - SIO_GET_INTERFACE_LIST_EX = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or 126; {Do not Localize} - {$EXTERNALSYM SIO_SET_MULTICAST_FILTER} - SIO_SET_MULTICAST_FILTER = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or 125; {Do not Localize} - {$EXTERNALSYM SIO_GET_MULTICAST_FILTER} - SIO_GET_MULTICAST_FILTER = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or (124 or IOC_IN); {Do not Localize} - {$EXTERNALSYM SIOCSIPMSFILTER} - SIOCSIPMSFILTER = SIO_SET_MULTICAST_FILTER; - {$EXTERNALSYM SIOCGIPMSFILTER} - SIOCGIPMSFILTER = SIO_GET_MULTICAST_FILTER; -// -// Protocol independent ioctls for setting and retrieving multicast filters. -// - {$EXTERNALSYM SIOCSMSFILTER} - SIOCSMSFILTER = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or 126; {Do not Localize} - {$EXTERNALSYM SIOCGMSFILTER} - SIOCGMSFILTER = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or (127 or IOC_IN); {Do not Localize} - - {$IFNDEF WINCE} - //Windows 2008 and Windows Vista SP1 additions - {$EXTERNALSYM SIO_IDEAL_SEND_BACKLOG_QUERY} - SIO_IDEAL_SEND_BACKLOG_QUERY = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or 123; - {$EXTERNALSYM SIO_IDEAL_SEND_BACKLOG_CHANGE} - SIO_IDEAL_SEND_BACKLOG_CHANGE = IOC_VOID or (Ord('t') shl 8) or 122; - {$ENDIF} - - {$IFNDEF WINCE} -// Options for use with [gs]etsockopt at the IP level. - {$EXTERNALSYM IP_OPTIONS} - IP_OPTIONS = 1; // set/get IP options - {$EXTERNALSYM IP_HDRINCL} - IP_HDRINCL = 2; // header is included with data - {$EXTERNALSYM IP_TOS} - IP_TOS = 3; // IP type of service and preced - {$EXTERNALSYM IP_TTL} - IP_TTL = 4; // IP time to live - {$EXTERNALSYM IP_MULTICAST_IF} - IP_MULTICAST_IF = 9; // set/get IP multicast i/f - {$EXTERNALSYM IP_MULTICAST_TTL} - IP_MULTICAST_TTL = 10; // set/get IP multicast ttl - {$EXTERNALSYM IP_MULTICAST_LOOP} - IP_MULTICAST_LOOP = 11; // set/get IP multicast loopback - {$EXTERNALSYM IP_ADD_MEMBERSHIP} - IP_ADD_MEMBERSHIP = 12; // add an IP group membership - {$EXTERNALSYM IP_DROP_MEMBERSHIP} - IP_DROP_MEMBERSHIP = 13; // drop an IP group membership - {$ELSE} - {$EXTERNALSYM IP_TOS} - IP_TOS = 8; //* IP type of service and preced*/ - {$EXTERNALSYM IP_TTL} - IP_TTL = 7; //* IP time to live */ - {$EXTERNALSYM IP_MULTICAST_IF} - IP_MULTICAST_IF = 2; //* set/get IP multicast i/f */ - {$EXTERNALSYM IP_MULTICAST_TTL} - IP_MULTICAST_TTL = 3; //* set/get IP multicast ttl */ - {$EXTERNALSYM IP_MULTICAST_LOOP} - IP_MULTICAST_LOOP = 4; //*set/get IP multicast loopback */ - {$EXTERNALSYM IP_ADD_MEMBERSHIP} - IP_ADD_MEMBERSHIP = 5; //* add an IP group membership */ - {$EXTERNALSYM IP_DROP_MEMBERSHIP} - IP_DROP_MEMBERSHIP = 6; //* drop an IP group membership */ - //JPM Notes. IP_HDRINCL is not supported in WinCE 4.0. - {$EXTERNALSYM IP_HDRINCL} - IP_HDRINCL = 9; //* header is included with data */ - {$ENDIF} - - {$EXTERNALSYM IP_DONTFRAGMENT} - IP_DONTFRAGMENT = 14; // don't fragment IP datagrams {Do not Localize} - {$EXTERNALSYM IP_ADD_SOURCE_MEMBERSHIP} - IP_ADD_SOURCE_MEMBERSHIP = 15; // join IP group/source - {$EXTERNALSYM IP_DROP_SOURCE_MEMBERSHIP} - IP_DROP_SOURCE_MEMBERSHIP = 16; // leave IP group/source - {$EXTERNALSYM IP_BLOCK_SOURCE} - IP_BLOCK_SOURCE = 17; // block IP group/source - {$EXTERNALSYM IP_UNBLOCK_SOURCE} - IP_UNBLOCK_SOURCE = 18; // unblock IP group/source - {$EXTERNALSYM IP_PKTINFO} - IP_PKTINFO = 19; // receive packet information for ipv4 - {$EXTERNALSYM IP_RECEIVE_BROADCAST} - IP_RECEIVE_BROADCAST = 22; // Allow/block broadcast reception. - {$EXTERNALSYM IP_RECVIF} - IP_RECVIF = 24; // Receive arrival interface. - {$EXTERNALSYM IP_RECVDSTADDR} - IP_RECVDSTADDR = 25; // Receive destination address. - {$EXTERNALSYM IP_IFLIST} - IP_IFLIST = 28; // Enable/Disable an interface list. - {$EXTERNALSYM IP_ADD_IFLIST} - IP_ADD_IFLIST = 29; // Add an interface list entry. - {$EXTERNALSYM IP_DEL_IFLIST} - IP_DEL_IFLIST = 30; // Delete an interface list entry. - {$EXTERNALSYM IP_UNICAST_IF} - IP_UNICAST_IF = 31; // IP unicast interface. - {$EXTERNALSYM IP_RTHDR} - IP_RTHDR = 32; // Set/get IPv6 routing header. - {$EXTERNALSYM IP_GET_IFLIST} - IP_GET_IFLIST = 33; // Get an interface list. - {$EXTERNALSYM IP_RECVRTHDR} - IP_RECVRTHDR = 38; // Receive the routing header. - {$EXTERNALSYM IP_TCLASS} - IP_TCLASS = 39; // Packet traffic class. - {$EXTERNALSYM IP_RECVTCLASS} - IP_RECVTCLASS = 40; // Receive packet traffic class. - {$EXTERNALSYM IP_ORIGINAL_ARRIVAL_IF} - IP_ORIGINAL_ARRIVAL_IF = 47; // Original Arrival Interface Index. (Windows 7) - - - {$IFDEF WINCE} - {$EXTERNALSYM IP_DSCP_TRAFFIC_TYPE} - IP_DSCP_TRAFFIC_TYPE = 100; //* differential services */ - {$EXTERNALSYM IP_RELOAD_DSCP_MAPPINGS} - IP_RELOAD_DSCP_MAPPINGS = 101; //* reload DSCP registry mappings */ - {$ENDIF} - - {$EXTERNALSYM IP_DEFAULT_MULTICAST_TTL} - IP_DEFAULT_MULTICAST_TTL = 1; // normally limit m'casts to 1 hop {Do not Localize} - {$EXTERNALSYM IP_DEFAULT_MULTICAST_LOOP} - IP_DEFAULT_MULTICAST_LOOP = 1; // normally hear sends if a member - {$EXTERNALSYM IP_MAX_MEMBERSHIPS} - IP_MAX_MEMBERSHIPS = 20; // per socket; must fit in one mbuf - - - // Option to use with [gs]etsockopt at the IPPROTO_IPV6 level - {$EXTERNALSYM IPV6_HDRINCL} - IPV6_HDRINCL = 2; // Header is included with data - {$EXTERNALSYM IPV6_UNICAST_HOPS} - IPV6_UNICAST_HOPS = 4; // Set/get IP unicast hop limit - {$EXTERNALSYM IPV6_MULTICAST_IF} - IPV6_MULTICAST_IF = 9; // Set/get IP multicast interface - {$EXTERNALSYM IPV6_MULTICAST_HOPS} - IPV6_MULTICAST_HOPS = 10; // Set/get IP multicast ttl - {$EXTERNALSYM IPV6_MULTICAST_LOOP} - IPV6_MULTICAST_LOOP = 11; // Set/get IP multicast loopback - {$EXTERNALSYM IPV6_ADD_MEMBERSHIP} - IPV6_ADD_MEMBERSHIP = 12; // Add an IP group membership - {$EXTERNALSYM IPV6_DROP_MEMBERSHIP} - IPV6_DROP_MEMBERSHIP = 13; // Drop an IP group membership - {$EXTERNALSYM IPV6_JOIN_GROUP} - IPV6_JOIN_GROUP = IPV6_ADD_MEMBERSHIP; - {$EXTERNALSYM IPV6_LEAVE_GROUP} - IPV6_LEAVE_GROUP = IPV6_DROP_MEMBERSHIP; - {$EXTERNALSYM IPV6_PKTINFO} - IPV6_PKTINFO = 19; // Receive packet information for ipv6 - {$EXTERNALSYM IPV6_HOPLIMIT} - IPV6_HOPLIMIT = 21; // Receive packet hop limit - //Note that IPV6_PROTECTION_LEVEL is not supported for WinCE 4.2 - {$EXTERNALSYM IPV6_PROTECTION_LEVEL} - IPV6_PROTECTION_LEVEL = 23; // Set/get IPv6 protection level - - {$EXTERNALSYM IPV6_RECVIF} - IPV6_RECVIF = 24; // Receive arrival interface. - {$EXTERNALSYM IPV6_RECVDSTADDR} - IPV6_RECVDSTADDR = 25; // Receive destination address. - {$EXTERNALSYM IPV6_CHECKSUM} - IPV6_CHECKSUM = 26; // Offset to checksum for raw IP socket send. - {$EXTERNALSYM IPV6_V6ONLY} - IPV6_V6ONLY = 27; // Treat wildcard bind as AF_INET6-only. - {$EXTERNALSYM IPV6_IFLIST} - IPV6_IFLIST = 28; // Enable/Disable an interface list. - {$EXTERNALSYM IPV6_ADD_IFLIST} - IPV6_ADD_IFLIST = 29; // Add an interface list entry. - {$EXTERNALSYM IPV6_DEL_IFLIST} - IPV6_DEL_IFLIST = 30; // Delete an interface list entry. - {$EXTERNALSYM IPV6_UNICAST_IF} - IPV6_UNICAST_IF = 31; // IP unicast interface. - {$EXTERNALSYM IPV6_RTHDR} - IPV6_RTHDR = 32; // Set/get IPv6 routing header. - {$EXTERNALSYM IPV6_GET_IFLIST} - IPV6_GET_IFLIST = 33; // Get an interface list. - {$EXTERNALSYM IPV6_RECVRTHDR} - IPV6_RECVRTHDR = 38; // Receive the routing header. - {$EXTERNALSYM IPV6_TCLASS} - IPV6_TCLASS = 39; // Packet traffic class. - {$EXTERNALSYM IPV6_RECVTCLASS} - IPV6_RECVTCLASS = 40; // Receive packet traffic class. - {$EXTERNALSYM IPV6_ECN} - IPV6_ECN = 50; // Receive ECN codepoints in the IP header. - {$EXTERNALSYM IPV6_PKTINFO_EX} - IPV6_PKTINFO_EX = 51; // Receive extended packet information. - {$EXTERNALSYM IPV6_WFP_REDIRECT_RECORDS} - IPV6_WFP_REDIRECT_RECORDS = 60; // WFP's Connection Redirect Records - {$EXTERNALSYM IPV6_WFP_REDIRECT_CONTEXT} - IPV6_WFP_REDIRECT_CONTEXT = 70; // WFP's Connection Redirect Context - - - // Option to use with [gs]etsockopt at the IPPROTO_UDP level - {$EXTERNALSYM UDP_NOCHECKSUM} - UDP_NOCHECKSUM = 1; - {$EXTERNALSYM UDP_CHECKSUM_COVERAGE} - UDP_CHECKSUM_COVERAGE = 20; // Set/get UDP-Lite checksum coverage - -// Option to use with [gs]etsockopt at the IPPROTO_TCP level - {$EXTERNALSYM TCP_EXPEDITED_1122} - TCP_EXPEDITED_1122 = $0002; - {$EXTERNALSYM TCP_KEEPALIVE} - TCP_KEEPALIVE = 3; - {$EXTERNALSYM TCP_MAXSEG} - TCP_MAXSEG = 4; - {$EXTERNALSYM TCP_MAXRT} - TCP_MAXRT = 5; - {$EXTERNALSYM TCP_STDURG} - TCP_STDURG = 6; - {$EXTERNALSYM TCP_NOURG} - TCP_NOURG = 7; - {$EXTERNALSYM TCP_ATMARK} - TCP_ATMARK = 8; - {$EXTERNALSYM TCP_NOSYNRETRIES} - TCP_NOSYNRETRIES = 9; - {$EXTERNALSYM TCP_TIMESTAMPS} - TCP_TIMESTAMPS = 10; - {$EXTERNALSYM TCP_OFFLOAD_PREFERENCE} - TCP_OFFLOAD_PREFERENCE = 11; - {$EXTERNALSYM TCP_CONGESTION_ALGORITHM} - TCP_CONGESTION_ALGORITHM = 12; - {$EXTERNALSYM TCP_DELAY_FIN_ACK} - TCP_DELAY_FIN_ACK = 13; - {$EXTERNALSYM TCP_MAXRTMS} - TCP_MAXRTMS = 14; - -// IPv6 definitions -type - {$EXTERNALSYM IN6_ADDR} - IN6_ADDR = record - case Integer of - 0: (s6_bytes: array[0..15] of u_char); - 1: (s6_words: array[0..7] of u_short); - end; - {$NODEFINE TIn6Addr} - TIn6Addr = IN6_ADDR; - {$NODEFINE PIn6Addr} - PIn6Addr = ^TIn6Addr; - {$EXTERNALSYM PIN6_ADDR} - PIN6_ADDR = PIn6Addr; - {$EXTERNALSYM LPIN6_ADDR} - LPIN6_ADDR = PIN6_ADDR; - -{$IFNDEF WINCE} - {$IFNDEF NO_REDECLARE} - // Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP - {$EXTERNALSYM ipv6_mreq} - ipv6_mreq = record - ipv6mr_multiaddr: TIn6Addr; // IPv6 multicast address - ipv6mr_interface: u_int; // Interface index - end; - {$NODEFINE TIPv6_MReq} - TIPv6_MReq = IPV6_MREQ; - {$NODEFINE PIPv6_MReq} - PIPv6_MReq = ^TIPv6_MReq; - {$ENDIF} -{$ENDIF} - {$EXTERNALSYM SCOPE_LEVEL} - // The Pascal compiler in Delphi/BCB prior to v6 does not - // support specifying values for individual enum items - SCOPE_LEVEL = ( - {$IFDEF HAS_ENUM_ELEMENT_VALUES} - ScopeLevelInterface = 1, - ScopeLevelLink = 2, - ScopeLevelSubnet = 3, - ScopeLevelAdmin = 4, - ScopeLevelSite = 5, - ScopeLevelOrganization = 8, - ScopeLevelGlobal = 14, - ScopeLevelCount = 16 - {$ELSE} - slUnused0, // do not use - ScopeLevelInterface, - ScopeLevelLink, - ScopeLevelSubnet, - ScopeLevelAdmin, - ScopeLevelSite, - slUnused6, // do not use - slUnused7, // do not use - ScopeLevelOrganization, - slUnused9, // do not use - slUnused10, // do not use - slUnused11, // do not use - slUnused12, // do not use - slUnused13, // do not use - ScopeLevelGlobal, - slUnused15, // do not use - ScopeLevelCount - {$ENDIF} - ); - // Old IPv6 socket address structure (retained for sockaddr_gen definition below) - {$EXTERNALSYM sockaddr_in6_old} - sockaddr_in6_old = record - sin6_family : short; // AF_INET6 - sin6_port : u_short; // Transport level port number - sin6_flowinfo : u_long; // IPv6 flow information - sin6_addr : TIn6Addr; // IPv6 address - end; - -// IPv6 socket address structure, RFC 2553 -{$IFDEF WINCE} - {$EXTERNALSYM SOCKADDR_IN6} - SOCKADDR_IN6 = record - sin6_family : short; // AF_INET6 - sin6_port : u_short; // Transport level port number - sin6_flowinfo : u_long; // IPv6 flow information - sin6_addr : TIn6Addr; // IPv6 address - sin6_scope_id : u_long; // set of interfaces for a scope - end; -{$ELSE} - {$EXTERNALSYM ADDRESS_FAMILY} - ADDRESS_FAMILY = USHORT; -// -// IPv6 socket address structure, RFC 3493. -// - -// -// NB: The LH version of sockaddr_in6 has the struct tag sockaddr_in6 rather -// than sockaddr_in6_lh. This is to make sure that standard sockets apps -// that conform to RFC 2553 (Basic Socket Interface Extensions for IPv6). -// - {$EXTERNALSYM SCOPE_ID} - SCOPE_ID = record -// union { -// struct { -// ULONG Zone : 28; -// ULONG Level : 4; -// }; -// ULONG Value; -// }; - Value : ULONG; - end; - {$EXTERNALSYM PSCOPE_ID} - PSCOPE_ID = ^SCOPE_ID; - - {$EXTERNALSYM SCOPEID_UNSPECIFIED_INIT} - function SCOPEID_UNSPECIFIED_INIT: SCOPE_ID; - -type - {$EXTERNALSYM sockaddr_in6_union} - sockaddr_in6_union = record - case Integer of - 0 : (sin6_scope_id : ULONG); // Set of interfaces for a scope. - 1 : (sin6_scope_struct : SCOPE_ID); - end; - {$EXTERNALSYM SOCKADDR_IN6_LH} - SOCKADDR_IN6_LH = record - sin6_family : ADDRESS_FAMILY; // AF_INET6. - sin6_port : USHORT; // Transport level port number. - sin6_flowinfo : ULONG; // IPv6 flow information. - sin6_addr : IN6_ADDR; // IPv6 address. - a : sockaddr_in6_union; - end; - {$EXTERNALSYM SOCKADDR_IN6_W2KSP1} - SOCKADDR_IN6_W2KSP1 = record - sin6_family : short; //* AF_INET6 */ - sin6_port : USHORT; //* Transport level port number */ - sin6_flowinfo : ULONG; //* IPv6 flow information */ - sin6_addr : in6_addr; //* IPv6 address */ - sin6_scope_id : ULONG; //* set of interfaces for a scope */ - end; - {$EXTERNALSYM PSOCKADDR_IN6_LH} - PSOCKADDR_IN6_LH = ^SOCKADDR_IN6_LH; - {$EXTERNALSYM SOCKADDR_IN6} - SOCKADDR_IN6 = SOCKADDR_IN6_LH; -{$ENDIF} - - {$NODEFINE TSockAddrIn6} - TSockAddrIn6 = SOCKADDR_IN6; - {$NODEFINE PSockAddrIn6} - PSockAddrIn6 = ^TSockAddrIn6; - {$EXTERNALSYM PSOCKADDR_IN6} - PSOCKADDR_IN6 = PSockAddrIn6; - {$EXTERNALSYM LPSOCKADDR_IN6} - LPSOCKADDR_IN6 = PSOCKADDR_IN6; - - {$EXTERNALSYM sockaddr_gen} - sockaddr_gen = record - case Integer of - 1 : ( Address : TSockAddr; ); - 2 : ( AddressIn : TSockAddrIn; ); - 3 : ( AddressIn6 : sockaddr_in6_old; ); - end; - {$NODEFINE TSockAddrGen} - TSockAddrGen = sockaddr_gen; - -// Structure to keep interface specific information - {$EXTERNALSYM INTERFACE_INFO} - INTERFACE_INFO = record - iiFlags : u_long; // Interface flags - iiAddress : TSockAddrGen; // Interface address - iiBroadcastAddress : TSockAddrGen; // Broadcast address - iiNetmask : TSockAddrGen; // Network mask - end; - {$NODEFINE TInterface_Info} - TInterface_Info = INTERFACE_INFO; - {$EXTERNALSYM PINTERFACE_INFO} - PINTERFACE_INFO = ^TInterface_Info; - {$EXTERNALSYM LPINTERFACE_INFO} - LPINTERFACE_INFO = PINTERFACE_INFO; - -// New structure that does not have dependency on the address size - {$EXTERNALSYM INTERFACE_INFO_EX} - INTERFACE_INFO_EX = record - iiFlags : u_long; // Interface flags - iiAddress : TSocket_Address; // Interface address - iiBroadcastAddress : TSocket_Address; // Broadcast address - iiNetmask : TSocket_Address; // Network mask - end; - {$NODEFINE TInterface_Info_Ex} - TInterface_Info_Ex = INTERFACE_INFO_EX; - {$EXTERNALSYM PINTERFACE_INFO_EX} - PINTERFACE_INFO_EX = ^TInterface_Info_Ex; - {$EXTERNALSYM LPINTERFACE_INFO_EX} - LPINTERFACE_INFO_EX = PINTERFACE_INFO_EX; - -// Macro that works for both IPv4 and IPv6 - {$EXTERNALSYM SS_PORT} - function SS_PORT(ssp: PSockAddrIn): u_short; - - {$EXTERNALSYM IN6ADDR_ANY_INIT} - function IN6ADDR_ANY_INIT: TIn6Addr; - {$EXTERNALSYM IN6ADDR_LOOPBACK_INIT} - function IN6ADDR_LOOPBACK_INIT: TIn6Addr; - {$EXTERNALSYM IN6ADDR_ALLNODESONNODE_INIT} - function IN6ADDR_ALLNODESONNODE_INIT : TIn6Addr; - {$EXTERNALSYM IN6ADDR_ALLNODESONLINK_INIT} - function IN6ADDR_ALLNODESONLINK_INIT : TIn6Addr; - {$EXTERNALSYM IN6ADDR_ALLROUTERSONLINK_INIT} - function IN6ADDR_ALLROUTERSONLINK_INIT : TIn6Addr; - {$EXTERNALSYM IN6ADDR_ALLMLDV2ROUTERSONLINK_INIT} - function IN6ADDR_ALLMLDV2ROUTERSONLINK_INIT : TIn6Addr; - {$EXTERNALSYM IN6ADDR_TEREDOINITIALLINKLOCALADDRESS_INIT} - function IN6ADDR_TEREDOINITIALLINKLOCALADDRESS_INIT : TIn6Addr; - {$EXTERNALSYM IN6ADDR_TEREDOOLDLINKLOCALADDRESSXP_INIT} - function IN6ADDR_TEREDOOLDLINKLOCALADDRESSXP_INIT : TIn6Addr; - {$EXTERNALSYM IN6ADDR_TEREDOOLDLINKLOCALADDRESSVISTA_INIT} - function IN6ADDR_TEREDOOLDLINKLOCALADDRESSVISTA_INIT : TIn6Addr; - - {$EXTERNALSYM IN6ADDR_SETANY} - procedure IN6ADDR_SETANY(sa: PSockAddrIn6); - {$EXTERNALSYM IN6ADDR_SETLOOPBACK} - procedure IN6ADDR_SETLOOPBACK(sa: PSockAddrIn6); - {$EXTERNALSYM IN6ADDR_ISANY} - function IN6ADDR_ISANY(sa: PSockAddrIn6): Boolean; - {$EXTERNALSYM IN6ADDR_ISLOOPBACK} - function IN6ADDR_ISLOOPBACK(sa: PSockAddrIn6): Boolean; - - {$EXTERNALSYM IN6_IS_ADDR_SUBNET_ROUTER_ANYCAST} - function IN6_IS_ADDR_SUBNET_ROUTER_ANYCAST(const a : PIn6Addr) : Boolean; - {$EXTERNALSYM IN6_IS_ADDR_SUBNET_RESERVED_ANYCAST} - function IN6_IS_ADDR_SUBNET_RESERVED_ANYCAST(const a: PIn6Addr) : Boolean; - {$EXTERNALSYM IN6_IS_ADDR_ANYCAST} - function IN6_IS_ADDR_ANYCAST(const a: PIn6Addr) : Boolean; - {$EXTERNALSYM IN6_ADDR_EQUAL} - function IN6_ADDR_EQUAL(const a: PIn6Addr; const b: PIn6Addr): Boolean; - {$EXTERNALSYM IN6_IS_ADDR_UNSPECIFIED} - function IN6_IS_ADDR_UNSPECIFIED(const a: PIn6Addr): Boolean; - {$EXTERNALSYM IN6_IS_ADDR_LOOPBACK} - function IN6_IS_ADDR_LOOPBACK(const a: PIn6Addr): Boolean; - {$EXTERNALSYM IN6_IS_ADDR_MULTICAST} - function IN6_IS_ADDR_MULTICAST(const a: PIn6Addr): Boolean; - {$EXTERNALSYM IN6_IS_ADDR_EUI64} - function IN6_IS_ADDR_EUI64(const a : PIn6Addr) : Boolean; - - {$EXTERNALSYM IN6_IS_ADDR_LINKLOCAL} - function IN6_IS_ADDR_LINKLOCAL(const a: PIn6Addr): Boolean; - {$EXTERNALSYM IN6_IS_ADDR_SITELOCAL} - function IN6_IS_ADDR_SITELOCAL(const a: PIn6Addr): Boolean; - {$EXTERNALSYM IN6_IS_ADDR_V4MAPPED} - function IN6_IS_ADDR_V4MAPPED(const a: PIn6Addr): Boolean; - {$EXTERNALSYM IN6_IS_ADDR_V4COMPAT} - function IN6_IS_ADDR_V4COMPAT(const a: PIn6Addr): Boolean; - {$EXTERNALSYM IN6_IS_ADDR_V4TRANSLATED} - function IN6_IS_ADDR_V4TRANSLATED(const a: PIn6Addr): Boolean; - {$EXTERNALSYM IN6_IS_ADDR_MC_NODELOCAL} - function IN6_IS_ADDR_MC_NODELOCAL(const a: PIn6Addr): Boolean; - {$EXTERNALSYM IN6_IS_ADDR_MC_LINKLOCAL} - function IN6_IS_ADDR_MC_LINKLOCAL(const a: PIn6Addr): Boolean; - {$EXTERNALSYM IN6_IS_ADDR_MC_SITELOCAL} - function IN6_IS_ADDR_MC_SITELOCAL(const a: PIn6Addr): Boolean; - {$EXTERNALSYM IN6_IS_ADDR_MC_ORGLOCAL} - function IN6_IS_ADDR_MC_ORGLOCAL(const a: PIn6Addr): Boolean; - {$EXTERNALSYM IN6_IS_ADDR_MC_GLOBAL} - function IN6_IS_ADDR_MC_GLOBAL(const a: PIn6Addr): Boolean; - - {$EXTERNALSYM IN6_SET_ADDR_UNSPECIFIED} - procedure IN6_SET_ADDR_UNSPECIFIED(a : PIN6_ADDR); - -// Possible flags for the iiFlags - bitmask -const - {$EXTERNALSYM IFF_UP} - IFF_UP = $00000001; // Interface is up - {$EXTERNALSYM IFF_BROADCAST} - IFF_BROADCAST = $00000002; // Broadcast is supported - {$EXTERNALSYM IFF_LOOPBACK} - IFF_LOOPBACK = $00000004; // this is loopback interface - {$EXTERNALSYM IFF_POINTTOPOINT} - IFF_POINTTOPOINT = $00000008; // this is point-to-point interface - {$EXTERNALSYM IFF_MULTICAST} - IFF_MULTICAST = $00000010; // multicast is supported - -type - {$EXTERNALSYM MULTICAST_MODE_TYPE} - {$EXTERNALSYM MCAST_INCLUDE} - {$EXTERNALSYM MCAST_EXCLUDE} - MULTICAST_MODE_TYPE = (MCAST_INCLUDE, MCAST_EXCLUDE); - {$EXTERNALSYM GROUP_FILTER} - GROUP_FILTER = record - gf_interface : PULONG; // Interface index. - gf_group : SOCKADDR_STORAGE; // Multicast address. - gf_fmode : MULTICAST_MODE_TYPE; // Filter mode. - gf_numsrc : ULONG; // Number of sources. - gf_slist : SOCKADDR_STORAGE; //gf_slist[1] : SOCKADDR_STORAGE; // Source address. - end; - {$EXTERNALSYM PGROUP_FILTER} - PGROUP_FILTER = ^GROUP_FILTER; - - {$EXTERNALSYM GROUP_REQ} - GROUP_REQ = record - gr_interface : ULONG; // Interface index. - gr_group : SOCKADDR_STORAGE; // Multicast address. - end; - {$EXTERNALSYM PGROUP_REQ} - PGROUP_REQ = ^GROUP_REQ; - - {$EXTERNALSYM GROUP_SOURCE_REQ} - GROUP_SOURCE_REQ = record - gsr_interface : ULONG; // Interface index. - gsr_group : SOCKADDR_STORAGE; // Group address. - gsr_source : SOCKADDR_STORAGE; // Source address. - end; - {$EXTERNALSYM PGROUP_SOURCE_REQ} - PGROUP_SOURCE_REQ = ^GROUP_SOURCE_REQ; - -{$EXTERNALSYM GROUP_FILTER_SIZE} -function GROUP_FILTER_SIZE(const numsrc : DWord) : PtrUInt; - -type - {$EXTERNALSYM WSAQUERYSET2} - WSAQUERYSET2 = record - dwSize : DWORD; - lpszServiceInstanceName : LPTSTR; - lpVersion : LPWSAVERSION; - lpszComment : LPTSTR; - dwNameSpace : DWORD; - lpNSProviderId : LPGUID; - lpszContext : LPTSTR; - dwNumberOfProtocols : DWORD; - lpafpProtocols : LPAFPROTOCOLS; - lpszQueryString : LPTSTR; - dwNumberOfCsAddrs : DWORD; - lpcsaBuffer : LPCSADDR_INFO; - dwOutputFlags : DWORD; - lpBlob : LPBLOB; - end; - {$EXTERNALSYM PWSAQUERYSET2} - PWSAQUERYSET2 = ^WSAQUERYSET2; - {$EXTERNALSYM LPWSAQUERYSET2} - LPWSAQUERYSET2 = PWSAQUERYSET2; - - {$EXTERNALSYM NAPI_PROVIDER_TYPE} - {$EXTERNALSYM ProviderType_Application} - {$EXTERNALSYM ProviderType_Service} - {$IFNDEF HAS_ENUM_ELEMENT_VALUES} - {$NODEFINE nptUnused} - {$ENDIF} - // The Pascal compiler in Delphi/BCB prior to v6 does not - // support specifying values for individual enum items - NAPI_PROVIDER_TYPE = ( - {$IFDEF HAS_ENUM_ELEMENT_VALUES} - ProviderType_Application = 1, - {$ELSE} - nptUnused, // Do not use - ProviderType_Application, - {$ENDIF} - ProviderType_Service); - {$EXTERNALSYM NAPI_DOMAIN_DESCRIPTION_BLOB} - NAPI_DOMAIN_DESCRIPTION_BLOB = record - AuthLevel : DWORD; - cchDomainName : DWORD; - OffsetNextDomainDescription : DWORD; - OffsetThisDomainName : DWORD; - end; - {$EXTERNALSYM PNAPI_DOMAIN_DESCRIPTION_BLOB} - PNAPI_DOMAIN_DESCRIPTION_BLOB = ^NAPI_DOMAIN_DESCRIPTION_BLOB; - - {$EXTERNALSYM NAPI_PROVIDER_LEVEL} - {$EXTERNALSYM PROVIDERLEVEL_NONE} - {$EXTERNALSYM PROVIDERLEVEL_SECONDARY} - {$EXTERNALSYM PROVIDERLEVEL_PRIMARY} - NAPI_PROVIDER_LEVEL = ( - PROVIDERLEVEL_NONE, - PROVIDERLEVEL_SECONDARY, - PROVIDERLEVEL_PRIMARY - ); - - {$EXTERNALSYM NAPI_PROVIDER_INSTALLATION_BLOB} - NAPI_PROVIDER_INSTALLATION_BLOB = record - dwVersion : DWORD; - dwProviderType : DWORD; - fSupportsWildCard : DWORD; - cDomains : DWORD; - OffsetFirstDomain : DWORD; - end; - {$EXTERNALSYM PNAPI_PROVIDER_INSTALLATION_BLOB} - PNAPI_PROVIDER_INSTALLATION_BLOB = ^NAPI_PROVIDER_INSTALLATION_BLOB; - - {$IFNDEF NOREDECLARE} - {$EXTERNALSYM SERVICE_ADDRESS} - SERVICE_ADDRESS = record - dwAddressType : DWORD; - dwAddressFlags : DWORD; - dwAddressLength : DWORD; - dwPrincipalLength : DWORD; - lpAddress : PByte; - lpPrincipal : PByte; - end; - {$ENDIF} - {$EXTERNALSYM PSERVICE_ADDRESS} - PSERVICE_ADDRESS = ^SERVICE_ADDRESS; - {$EXTERNALSYM LPSERVICE_ADDRESS} - LPSERVICE_ADDRESS = PSERVICE_ADDRESS; - - {$IFNDEF NOREDECLARE} - {$EXTERNALSYM SERVICE_ADDRESSES} - SERVICE_ADDRESSES = record - dwAddressCount : DWORD; -//#ifdef MIDL_PASS -// [size_is(dwAddressCount)] SERVICE_ADDRESS Addressses[*]; -//#else // MIDL_PASS -// SERVICE_ADDRESS Addresses[1] ; -//#endif // MIDL_PASS - Addresses : SERVICE_ADDRESS; - end; - {$EXTERNALSYM PSERVICE_ADDRESSES} - PSERVICE_ADDRESSES = ^SERVICE_ADDRESSES; - {$EXTERNALSYM LPSERVICE_ADDRESSES} - LPSERVICE_ADDRESSES = PSERVICE_ADDRESSES; - {$ENDIF} - -{$IFNDEF VCL_2007_OR_ABOVE} -const - {$EXTERNALSYM RESOURCEDISPLAYTYPE_GENERIC} - RESOURCEDISPLAYTYPE_GENERIC = $00000000; - {$EXTERNALSYM RESOURCEDISPLAYTYPE_DOMAIN} - RESOURCEDISPLAYTYPE_DOMAIN = $00000001; - {$EXTERNALSYM RESOURCEDISPLAYTYPE_SERVER} - RESOURCEDISPLAYTYPE_SERVER = $00000002; - {$EXTERNALSYM RESOURCEDISPLAYTYPE_SHARE} - RESOURCEDISPLAYTYPE_SHARE = $00000003; - {$EXTERNALSYM RESOURCEDISPLAYTYPE_FILE} - RESOURCEDISPLAYTYPE_FILE = $00000004; - {$EXTERNALSYM RESOURCEDISPLAYTYPE_GROUP} - RESOURCEDISPLAYTYPE_GROUP = $00000005; - {$EXTERNALSYM RESOURCEDISPLAYTYPE_NETWORK} - RESOURCEDISPLAYTYPE_NETWORK = $00000006; - {$EXTERNALSYM RESOURCEDISPLAYTYPE_ROOT} - RESOURCEDISPLAYTYPE_ROOT = $00000007; - {$EXTERNALSYM RESOURCEDISPLAYTYPE_SHAREADMIN} - RESOURCEDISPLAYTYPE_SHAREADMIN = $00000008; - {$EXTERNALSYM RESOURCEDISPLAYTYPE_DIRECTORY} - RESOURCEDISPLAYTYPE_DIRECTORY = $00000009; - {$EXTERNALSYM RESOURCEDISPLAYTYPE_TREE} - RESOURCEDISPLAYTYPE_TREE = $0000000A; - {$EXTERNALSYM RESOURCEDISPLAYTYPE_NDSCONTAINER} - RESOURCEDISPLAYTYPE_NDSCONTAINER = $0000000B; -{$ENDIF} - -type - {$EXTERNALSYM SERVICE_TYPE_VALUE_ABSA} - SERVICE_TYPE_VALUE_ABSA = record - dwNameSpace : DWORD; - dwValueType : DWORD; - dwValueSize : DWORD; - lpValueName : LPSTR; - lpValue : Pointer; - end; - {$EXTERNALSYM PSERVICE_TYPE_VALUE_ABSA} - PSERVICE_TYPE_VALUE_ABSA = ^SERVICE_TYPE_VALUE_ABSA; - {$EXTERNALSYM LPSERVICE_TYPE_VALUE_ABSA} - LPSERVICE_TYPE_VALUE_ABSA = PSERVICE_TYPE_VALUE_ABSA; - - {$EXTERNALSYM SERVICE_INFOA} - SERVICE_INFOA = record - lpServiceType : LPGUID; - lpServiceName : PIdAnsiChar; - lpComment : PIdAnsiChar; - lpLocale : PIdAnsiChar; - dwDisplayHint : DWORD; - dwVersion : DWORD; - dwTime : DWORD; - lpMachineName : PIdAnsiChar; - lpServiceAddress : LPSERVICE_ADDRESSES; - ServiceSpecificInfo : BLOB; - end; - {$EXTERNALSYM SERVICE_INFOW} - SERVICE_INFOW = record - lpServiceType : LPGUID; - lpServiceName : PWideChar; - lpComment : PWideChar; - lpLocale : PWideChar; - dwDisplayHint : DWORD; - dwVersion : DWORD; - dwTime : DWORD; - lpMachineName : PWideChar; - lpServiceAddress : LPSERVICE_ADDRESSES; - ServiceSpecificInfo : BLOB; - end; - - {$EXTERNALSYM SOCKET_USAGE_TYPE} - {$EXTERNALSYM SYSTEM_CRITICAL_SOCKET} - {$IFNDEF HAS_ENUM_ELEMENT_VALUES} - {$NODEFINE sutUnused} - {$ENDIF} - // The Pascal compiler in Delphi/BCB prior to v6 does not - // support specifying values for individual enum items - SOCKET_USAGE_TYPE = ( - {$IFDEF HAS_ENUM_ELEMENT_VALUES} - SYSTEM_CRITICAL_SOCKET = 1 - {$ELSE} - sutUnused, // do not use - SYSTEM_CRITICAL_SOCKET - {$ENDIF} - ); - {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL} - {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL_DEFAULT} - {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL_IPSEC} - {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL_IPSEC2} - SOCKET_SECURITY_PROTOCOL = ( - SOCKET_SECURITY_PROTOCOL_DEFAULT, - SOCKET_SECURITY_PROTOCOL_IPSEC, - SOCKET_SECURITY_PROTOCOL_IPSEC2); - {$IFNDEF NO_REDECLARE} - {$EXTERNALSYM SERVICE_INFO} - {$IFDEF UNICODE} - SERVICE_INFO = SERVICE_INFOW; - {$ELSE} - SERVICE_INFO = SERVICE_INFOA; - {$ENDIF} - {$ENDIF} - {$EXTERNALSYM NS_SERVICE_INFOA} - NS_SERVICE_INFOA = record - dwNameSpace : DWORD; - ServiceInfo : SERVICE_INFOA; - end; - {$EXTERNALSYM PNS_SERVICE_INFOA} - PNS_SERVICE_INFOA = ^NS_SERVICE_INFOA; - {$EXTERNALSYM LPNS_SERVICE_INFOA} - LPNS_SERVICE_INFOA = NS_SERVICE_INFOA; - {$EXTERNALSYM NS_SERVICE_INFOW} - NS_SERVICE_INFOW = record - dwNameSpace : DWORD; - ServiceInfo : SERVICE_INFOW; - end; - {$EXTERNALSYM PNS_SERVICE_INFOW} - PNS_SERVICE_INFOW = ^NS_SERVICE_INFOW; - {$EXTERNALSYM LPNS_SERVICE_INFOW} - LPNS_SERVICE_INFOW = NS_SERVICE_INFOW; - {$IFNDEF NO_REDECLARE} - {$EXTERNALSYM NS_SERVICE_INFO} - {$EXTERNALSYM PNS_SERVICE_INFO} - {$EXTERNALSYM LPNS_SERVICE_INFO} - {$IFDEF UNICODE} - NS_SERVICE_INFO = NS_SERVICE_INFOW; - PNS_SERVICE_INFO = PNS_SERVICE_INFOW; - LPNS_SERVICE_INFO = LPNS_SERVICE_INFOW; - {$ELSE} - NS_SERVICE_INFO = NS_SERVICE_INFOA; - PNS_SERVICE_INFO = PNS_SERVICE_INFOA; - LPNS_SERVICE_INFO = LPNS_SERVICE_INFOA; - {$ENDIF} - {$ENDIF} - -{$IFNDEF WINCE} -type -// structure for IP_PKTINFO option - {$EXTERNALSYM IN_PKTINFO} - IN_PKTINFO = record - ipi_addr : TInAddr; // destination IPv4 address - ipi_ifindex : UINT; // received interface index - end; - {$NODEFINE TInPktInfo} - TInPktInfo = IN_PKTINFO; - {$NODEFINE PInPktInfo} - PInPktInfo = ^IN_PKTINFO; - -// structure for IPV6_PKTINFO option - {$EXTERNALSYM IN6_PKTINFO} - IN6_PKTINFO = record - ipi6_addr : TIn6Addr; // destination IPv6 address - ipi6_ifindex : UINT; // received interface index - end; - {$NODEFINE TIn6PktInfo} - TIn6PktInfo = IN6_PKTINFO; - {$NODEFINE PIn6PktInfo} - PIn6PktInfo = ^TIn6PktInfo; -{$ENDIF} - -// Error codes from getaddrinfo() -const - {$EXTERNALSYM EAI_AGAIN} - EAI_AGAIN = WSATRY_AGAIN; - {$EXTERNALSYM EAI_BADFLAGS} - EAI_BADFLAGS = WSAEINVAL; - {$EXTERNALSYM EAI_FAIL} - EAI_FAIL = WSANO_RECOVERY; - {$EXTERNALSYM EAI_FAMILY} - EAI_FAMILY = WSAEAFNOSUPPORT; - {$EXTERNALSYM EAI_MEMORY} - EAI_MEMORY = WSA_NOT_ENOUGH_MEMORY; -// {$EXTERNALSYM EAI_NODATA} -// EAI_NODATA = WSANO_DATA; - {$EXTERNALSYM EAI_NONAME} - EAI_NONAME = WSAHOST_NOT_FOUND; - {$EXTERNALSYM EAI_SERVICE} - EAI_SERVICE = WSATYPE_NOT_FOUND; - {$EXTERNALSYM EAI_SOCKTYPE} - EAI_SOCKTYPE = WSAESOCKTNOSUPPORT; - -// DCR_FIX: EAI_NODATA remove or fix -// -// EAI_NODATA was removed from rfc2553bis -// need to find out from the authors why and -// determine the error for "no records of this type" -// temporarily, we'll keep #define to avoid changing -// code that could change back; use NONAME - {$EXTERNALSYM EAI_NODATA} - EAI_NODATA = EAI_NONAME; - -// Structure used in getaddrinfo() call -type - {$NODEFINE PAddrInfo} - PAddrInfo = ^ADDRINFO; - {$NODEFINE PPaddrinfo} - PPaddrinfo = ^PAddrInfo; - {$NODEFINE PPaddrinfoW} - PPaddrinfoW = ^PAddrInfoW; - {$EXTERNALSYM ADDRINFO} - ADDRINFO = record - ai_flags : Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST - ai_family : Integer; // PF_xxx - ai_socktype : Integer; // SOCK_xxx - ai_protocol : Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6 - ai_addrlen : size_t; // Length of ai_addr - ai_canonname : PIdAnsiChar; // Canonical name for nodename - ai_addr : PSOCKADDR; // Binary address - ai_next : PAddrInfo; // Next structure in linked list - end; - {$NODEFINE TAddrInfo} - TAddrInfo = ADDRINFO; - {$EXTERNALSYM LPADDRINFO} - LPADDRINFO = PAddrInfo; - - {$NODEFINE PAddrInfoW} - PAddrInfoW = ^ADDRINFOW; - {$EXTERNALSYM ADDRINFOW} - ADDRINFOW = record - ai_flags : Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST - ai_family : Integer; // PF_xxx - ai_socktype : Integer; // SOCK_xxx - ai_protocol : Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6 - ai_addrlen : size_t; // Length of ai_addr - ai_canonname : PWideChar; // Canonical name for nodename - ai_addr : PSOCKADDR; // Binary address - ai_next : PAddrInfoW; // Next structure in linked list - end; - {$NODEFINE TAddrInfoW} - TAddrInfoW = ADDRINFOW; - {$EXTERNALSYM LPADDRINFOW} - LPADDRINFOW = PAddrInfoW; - -// Flags used in "hints" argument to getaddrinfo() -const - {$EXTERNALSYM AI_PASSIVE} - AI_PASSIVE = $00000001; // Socket address will be used in bind() call - {$EXTERNALSYM AI_CANONNAME} - AI_CANONNAME = $00000002; // Return canonical name in first ai_canonname - {$EXTERNALSYM AI_NUMERICHOST} - AI_NUMERICHOST = $00000004; // Nodename must be a numeric address string - {$EXTERNALSYM AI_NUMERICSERV} - AI_NUMERICSERV = $00000008; // Servicename must be a numeric port number - {$EXTERNALSYM AI_ALL} - AI_ALL = $00000100; // Query both IP6 and IP4 with AI_V4MAPPED - {$EXTERNALSYM AI_ADDRCONFIG} - AI_ADDRCONFIG = $00000400; // Resolution only if global address configured - {$EXTERNALSYM AI_V4MAPPED} - AI_V4MAPPED = $00000800; // On v6 failure, query v4 and convert to V4MAPPED format (Vista or later) - {$EXTERNALSYM AI_NON_AUTHORITATIVE} - AI_NON_AUTHORITATIVE = $00004000; // LUP_NON_AUTHORITATIVE (Vista or later) - {$EXTERNALSYM AI_SECURE} - AI_SECURE = $00008000; // LUP_SECURE (Vista or later and applies only to NS_EMAIL namespace.) - {$EXTERNALSYM AI_RETURN_PREFERRED_NAMES} - AI_RETURN_PREFERRED_NAMES = $00010000; // LUP_RETURN_PREFERRED_NAMES (Vista or later and applies only to NS_EMAIL namespace.) - {$EXTERNALSYM AI_FQDN} - AI_FQDN = $00020000; // Return the FQDN in ai_canonname (Windows 7 or later) - {$EXTERNALSYM AI_FILESERVER} - AI_FILESERVER = $00040000; // Resolving fileserver name resolution (Windows 7 or later) - {$EXTERNALSYM AI_DISABLE_IDN_ENCODING} - AI_DISABLE_IDN_ENCODING = $00080000; // Disable Internationalized Domain Names handling - - -type - {$EXTERNALSYM PADDRINFOEXA} - PADDRINFOEXA = ^TAddrInfoEXA; - {$EXTERNALSYM ADDRINFOEXA} - ADDRINFOEXA = record - ai_flags : Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST - ai_family : Integer; // PF_xxx - ai_socktype : Integer; // SOCK_xxx - ai_protocol : Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6 - ai_addrlen : size_t; // Length of ai_addr - ai_canonname : PIdAnsiChar; // Canonical name for nodename - ai_addr : Psockaddr; // Binary address - ai_blob : Pointer; - ai_bloblen : size_t; - ai_provider : LPGUID; - ai_next : PADDRINFOEXA; // Next structure in linked list - end; - {$NODEFINE TAddrInfoEXA} - TAddrInfoExA = ADDRINFOEXA; - {$EXTERNALSYM LPADDRINFOEXA} - LPADDRINFOEXA = PADDRINFOEXA; - - {$EXTERNALSYM PADDRINFOEXW} - PADDRINFOEXW = ^TAddrInfoEXW; - {$EXTERNALSYM ADDRINFOEXW} - ADDRINFOEXW = record - ai_flags : Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST - ai_family : Integer; // PF_xxx - ai_socktype : Integer; // SOCK_xxx - ai_protocol : Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6 - ai_addrlen : size_t; // Length of ai_addr - ai_canonname : PWideChar; // Canonical name for nodename - ai_addr : Psockaddr; // Binary address - ai_blob : Pointer; - ai_bloblen : size_t; - ai_provider : LPGUID; - ai_next : PADDRINFOEXW; // Next structure in linked list - end; - {$NODEFINE TAddrInfoExW} - TAddrInfoExW = ADDRINFOEXW; - {$EXTERNALSYM LPADDRINFOEXW} - LPADDRINFOEXW = PADDRINFOEXW; - - {$EXTERNALSYM Paddrinfoex2A} - Paddrinfoex2A = ^addrinfoex2A; - {$EXTERNALSYM addrinfoex2A} - addrinfoex2A = record - ai_flags : Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST - ai_family : Integer; // PF_xxx - ai_socktype : Integer; // SOCK_xxx - ai_protocol : Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6 - ai_addrlen : size_t; // Length of ai_addr - ai_canonname : PIdAnsiChar; // Canonical name for nodename - ai_addr : Psockaddr; // Binary address - ai_blob : Pointer; - ai_bloblen : size_t; - ai_provider : LPGUID; - ai_next : Paddrinfoex2A; // Next structure in linked list - ai_version : Integer; - ai_fqdn : PIdAnsiChar; - end; - {$NODEFINE TAddrInfoEx2A} - TAddrInfoEx2A = addrinfoex2A; - {$EXTERNALSYM LPADDRINFOEX2A} - LPADDRINFOEX2A = Paddrinfoex2A; - - {$EXTERNALSYM Paddrinfoex2W} - Paddrinfoex2W = ^addrinfoex2W; - {$EXTERNALSYM addrinfoex2W} - addrinfoex2W = record - ai_flags : Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST - ai_family : Integer; // PF_xxx - ai_socktype : Integer; // SOCK_xxx - ai_protocol : Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6 - ai_addrlen : size_t; // Length of ai_addr - ai_canonname : PWideChar; // Canonical name for nodename - ai_addr : Psockaddr; //_Field_size_bytes_(ai_addrlen) // Binary address - ai_blob : Pointer; //_Field_size_(ai_bloblen) - ai_bloblen : size_t; - ai_provider : LPGUID; - ai_next : Paddrinfoex2W; // Next structure in linked list - ai_version : Integer; - ai_fqdn : PWideChar; - end; - {$NODEFINE TAddrInfoEx2W} - TAddrInfoEx2W = addrinfoex2W; - {$EXTERNALSYM LPADDRINFOEX2W} - LPADDRINFOEX2W = Paddrinfoex2W; - -var - {$EXTERNALSYM scopeid_unspecified} - scopeid_unspecified: {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; - - // RLebeau: the in4addr_any, _in4addr_loopback, and _in4addr_broadcast variables - // clash with the IN4ADDR_ANY, IN4ADDR_LOOPBACK, and IN4ADDR_BROADCAST constants - {$EXTERNALSYM in4addr_any} - {$NODEFINE _in4addr_any} - _in4addr_any: TInAddr; - {$EXTERNALSYM in4addr_loopback} - {$NODEFINE _in4addr_loopback} - _in4addr_loopback: TInAddr; - {$EXTERNALSYM in4addr_broadcast} - {$NODEFINE _in4addr_broadcast} - _in4addr_broadcast: TInAddr; - - {$EXTERNALSYM in4addr_allnodesonlink} - in4addr_allnodesonlink: TInAddr; - {$EXTERNALSYM in4addr_allroutersonlink} - in4addr_allroutersonlink: TInAddr; - {$EXTERNALSYM in4addr_alligmpv3routersonlink} - in4addr_alligmpv3routersonlink: TInAddr; - {$EXTERNALSYM in4addr_allteredohostsonlink} - in4addr_allteredohostsonlink: TInAddr; - {$EXTERNALSYM in4addr_linklocalprefix} - in4addr_linklocalprefix: TInAddr; - {$EXTERNALSYM in4addr_multicastprefix} - in4addr_multicastprefix: TInAddr; - - {$EXTERNALSYM in6addr_any} - in6addr_any: TIn6Addr; - {$EXTERNALSYM in6addr_loopback} - in6addr_loopback: TIn6Addr; - {$EXTERNALSYM in6addr_allnodesonnode} - in6addr_allnodesonnode: TIn6Addr; - {$EXTERNALSYM in6addr_allnodesonlink} - in6addr_allnodesonlink: TIn6Addr; - {$EXTERNALSYM in6addr_allroutersonlink} - in6addr_allroutersonlink: TIn6Addr; - {$EXTERNALSYM in6addr_solicitednodemulticastprefix} - in6addr_solicitednodemulticastprefix: TIn6Addr; - {$EXTERNALSYM in6addr_v4mappedprefix} - in6addr_v4mappedprefix: TIn6Addr; - {$EXTERNALSYM in6addr_6to4prefix} - in6addr_6to4prefix: TIn6Addr; - {$EXTERNALSYM in6addr_teredoprefix} - in6addr_teredoprefix: TIn6Addr; - -//============================================================= - -{ - wsipx.h - - Microsoft Windows - Copyright (C) Microsoft Corporation, 1992-1999. - - Windows Sockets include file for IPX/SPX. This file contains all - standardized IPX/SPX information. Include this header file after - winsock.h. - - To open an IPX socket, call socket() with an address family of - AF_IPX, a socket type of SOCK_DGRAM, and protocol NSPROTO_IPX. - Note that the protocol value must be specified, it cannot be 0. - All IPX packets are sent with the packet type field of the IPX - header set to 0. - - To open an SPX or SPXII socket, call socket() with an address - family of AF_IPX, socket type of SOCK_SEQPACKET or SOCK_STREAM, - and protocol of NSPROTO_SPX or NSPROTO_SPXII. If SOCK_SEQPACKET - is specified, then the end of message bit is respected, and - recv() calls are not completed until a packet is received with - the end of message bit set. If SOCK_STREAM is specified, then - the end of message bit is not respected, and recv() completes - as soon as any data is received, regardless of the setting of the - end of message bit. Send coalescing is never performed, and sends - smaller than a single packet are always sent with the end of - message bit set. Sends larger than a single packet are packetized - with the end of message bit set on only the last packet of the - send. -} - -// This is the structure of the SOCKADDR structure for IPX and SPX. -type - {$EXTERNALSYM SOCKADDR_IPX} - SOCKADDR_IPX = record - sa_family : u_short; - sa_netnum : Array [0..3] of TIdAnsiChar; - sa_nodenum : Array [0..5] of TIdAnsiChar; - sa_socket : u_short; - end; - {$NODEFINE TSockAddrIPX} - TSockAddrIPX = SOCKADDR_IPX; - {$NODEFINE PSockAddrIPX} - PSockAddrIPX = ^TSockAddrIPX; - {$EXTERNALSYM PSOCKADDR_IPX} - PSOCKADDR_IPX = PSockAddrIPX; - {$EXTERNALSYM LPSOCKADDR_IPX} - LPSOCKADDR_IPX = PSOCKADDR_IPX; - -// Protocol families used in the "protocol" parameter of the socket() API. -const - {$EXTERNALSYM NSPROTO_IPX} - NSPROTO_IPX = 1000; - {$EXTERNALSYM NSPROTO_SPX} - NSPROTO_SPX = 1256; - {$EXTERNALSYM NSPROTO_SPXII} - NSPROTO_SPXII = 1257; - - -//============================================================= - -{ - wsnwlink.h - - Microsoft Windows - Copyright (C) Microsoft Corporation, 1992-1999. - Microsoft-specific extensions to the Windows NT IPX/SPX Windows - Sockets interface. These extensions are provided for use as - necessary for compatibility with existing applications. They are - otherwise not recommended for use, as they are only guaranteed to - work over the Microsoft IPX/SPX stack. An application which - uses these extensions may not work over other IPX/SPX - implementations. Include this header file after winsock.h and - wsipx.h. - - To open an IPX socket where a particular packet type is sent in - the IPX header, specify NSPROTO_IPX + n as the protocol parameter - of the socket() API. For example, to open an IPX socket that - sets the packet type to 34, use the following socket() call: - - s = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX + 34); -} - -// Below are socket option that may be set or retrieved by specifying -// the appropriate manifest in the "optname" parameter of getsockopt() -// or setsockopt(). Use NSPROTO_IPX as the "level" argument for the -// call. -const - -// Set/get the IPX packet type. The value specified in the -// optval argument will be set as the packet type on every IPX -// packet sent from this socket. The optval parameter of -// getsockopt()/setsockopt() points to an int. - {$EXTERNALSYM IPX_PTYPE} - IPX_PTYPE = $4000; - -// Set/get the receive filter packet type. Only IPX packets with -// a packet type equal to the value specified in the optval -// argument will be returned; packets with a packet type that -// does not match are discarded. optval points to an int. - {$EXTERNALSYM IPX_FILTERPTYPE} - IPX_FILTERPTYPE = $4001; - -// Stop filtering on packet type set with IPX_FILTERPTYPE. - {$EXTERNALSYM IPX_STOPFILTERPTYPE} - IPX_STOPFILTERPTYPE = $4003; - -// Set/get the value of the datastream field in the SPX header on -// every packet sent. optval points to an int. - {$EXTERNALSYM IPX_DSTYPE} - IPX_DSTYPE = $4002; - -// Enable extended addressing. On sends, adds the element -// "unsigned char sa_ptype" to the SOCKADDR_IPX structure, -// making the total length 15 bytes. On receives, add both -// the sa_ptype and "unsigned char sa_flags" to the SOCKADDR_IPX -// structure, making the total length 16 bytes. The current -// bits defined in sa_flags are: -// 0x01 - the received frame was sent as a broadcast -// 0x02 - the received frame was sent from this machine -// optval points to a BOOL. - {$EXTERNALSYM IPX_EXTENDED_ADDRESS} - IPX_EXTENDED_ADDRESS = $4004; - -// Send protocol header up on all receive packets. optval points -// to a BOOL. - {$EXTERNALSYM IPX_RECVHDR} - IPX_RECVHDR = $4005; - -// Get the maximum data size that can be sent. Not valid with -// setsockopt(). optval points to an int where the value is -// returned. - {$EXTERNALSYM IPX_MAXSIZE} - IPX_MAXSIZE = $4006; - -// Query information about a specific adapter that IPX is bound -// to. In a system with n adapters they are numbered 0 through n-1. -// Callers can issue the IPX_MAX_ADAPTER_NUM getsockopt() to find -// out the number of adapters present, or call IPX_ADDRESS with -// increasing values of adapternum until it fails. Not valid -// with setsockopt(). optval points to an instance of the -// IPX_ADDRESS_DATA structure with the adapternum filled in. - {$EXTERNALSYM IPX_ADDRESS} - IPX_ADDRESS = $4007; - -type - {$EXTERNALSYM IPX_ADDRESS_DATA} - IPX_ADDRESS_DATA = record - adapternum : Integer; // input: 0-based adapter number - netnum : Array [0..3] of Byte; // output: IPX network number - nodenum : Array [0..5] of Byte; // output: IPX node address - wan : Boolean; // output: TRUE = adapter is on a wan link - status : Boolean; // output: TRUE = wan link is up (or adapter is not wan) - maxpkt : Integer; // output: max packet size, not including IPX header - linkspeed : ULONG; // output: link speed in 100 bytes/sec (i.e. 96 == 9600 bps) - end; - {$NODEFINE TIPXAddressData} - TIPXAddressData = IPX_ADDRESS_DATA; - {$NODEFINE PIPXAddressData} - PIPXAddressData = ^TIPXAddressData; - {$EXTERNALSYM PIPX_ADDRESS_DATA} - PIPX_ADDRESS_DATA = PIPXAddressData; - -const -// Query information about a specific IPX network number. If the -// network is in IPX's cache it will return the information directly, {Do not Localize} -// otherwise it will issue RIP requests to find it. Not valid with -// setsockopt(). optval points to an instance of the IPX_NETNUM_DATA -// structure with the netnum filled in. - {$EXTERNALSYM IPX_GETNETINFO} - IPX_GETNETINFO = $4008; - -type - {$EXTERNALSYM IPX_NETNUM_DATA} - IPX_NETNUM_DATA = record - netnum : Array [0..3] of Byte; // input: IPX network number - hopcount : Word; // output: hop count to this network, in machine order - netdelay : Word; // output: tick count to this network, in machine order - cardnum : Integer; // output: 0-based adapter number used to route to this net; - // can be used as adapternum input to IPX_ADDRESS - router : Array [0..5] of Byte; // output: MAC address of the next hop router, zeroed if - // the network is directly attached - end; - {$NODEFINE TIPXNetNumData} - TIPXNetNumData = IPX_NETNUM_DATA; - {$NODEFINE PIPXNetNumData} - PIPXNetNumData = ^TIPXNetNumData; - {$EXTERNALSYM PIPX_NETNUM_DATA} - PIPX_NETNUM_DATA = PIPXNetNumData; - -const -// Like IPX_GETNETINFO except it does not issue RIP requests. If the -// network is in IPX's cache it will return the information, otherwise {Do not Localize} -// it will fail (see also IPX_RERIPNETNUMBER which always forces a -// re-RIP). Not valid with setsockopt(). optval points to an instance of -// the IPX_NETNUM_DATA structure with the netnum filled in. - {$EXTERNALSYM IPX_GETNETINFO_NORIP} - IPX_GETNETINFO_NORIP = $4009; - -// Get information on a connected SPX socket. optval points -// to an instance of the IPX_SPXCONNSTATUS_DATA structure. -// *** All numbers are in Novell (high-low) order. *** - {$EXTERNALSYM IPX_SPXGETCONNECTIONSTATUS} - IPX_SPXGETCONNECTIONSTATUS = $400B; - -type - {$EXTERNALSYM IPX_SPXCONNSTATUS_DATA} - IPX_SPXCONNSTATUS_DATA = record - ConnectionState : Byte; - WatchDogActive : Byte; - LocalConnectionId : Word; - RemoteConnectionId : Word; - LocalSequenceNumber : Word; - LocalAckNumber : Word; - LocalAllocNumber : Word; - RemoteAckNumber : Word; - RemoteAllocNumber : Word; - LocalSocket : Word; - ImmediateAddress : Array [0..5] of Byte; - RemoteNetwork : Array [0..3] of Byte; - RemoteNode : Array [0..5] of Byte; - RemoteSocket : Word; - RetransmissionCount : Word; - EstimatedRoundTripDelay : Word; // In milliseconds - RetransmittedPackets : Word; - SuppressedPacket : Word; - end; - {$NODEFINE TIPXSPXConnStatusData} - TIPXSPXConnStatusData = IPX_SPXCONNSTATUS_DATA; - {$NODEFINE PIPXSPXConnStatusData} - PIPXSPXConnStatusData = ^TIPXSPXConnStatusData; - {$EXTERNALSYM PIPX_SPXCONNSTATUS_DATA} - PIPX_SPXCONNSTATUS_DATA = PIPXSPXConnStatusData; - -const -// Get notification when the status of an adapter that IPX is -// bound to changes. Typically this will happen when a wan line -// goes up or down. Not valid with setsockopt(). optval points -// to a buffer which contains an IPX_ADDRESS_DATA structure -// followed immediately by a HANDLE to an unsignaled event. -// -// When the getsockopt() query is submitted, it will complete -// successfully. However, the IPX_ADDRESS_DATA pointed to by -// optval will not be updated at that point. Instead the -// request is queued internally inside the transport. -// -// When the status of an adapter changes, IPX will locate a -// queued getsockopt() query and fill in all the fields in the -// IPX_ADDRESS_DATA structure. It will then signal the event -// pointed to by the HANDLE in the optval buffer. This handle -// should be obtained before calling getsockopt() by calling -// CreateEvent(). If multiple getsockopts() are submitted at -// once, different events must be used. -// -// The event is used because the call needs to be asynchronous -// but currently getsockopt() does not support this. -// -// WARNING: In the current implementation, the transport will -// only signal one queued query for each status change. Therefore -// only one service which uses this query should be running at -// once. - {$EXTERNALSYM IPX_ADDRESS_NOTIFY} - IPX_ADDRESS_NOTIFY = $400C; - -// Get the maximum number of adapters present. If this call returns -// n then the adapters are numbered 0 through n-1. Not valid -// with setsockopt(). optval points to an int where the value -// is returned. - {$EXTERNALSYM IPX_MAX_ADAPTER_NUM} - IPX_MAX_ADAPTER_NUM = $400D; - -// Like IPX_GETNETINFO except it forces IPX to re-RIP even if the -// network is in its cache (but not if it is directly attached to). -// Not valid with setsockopt(). optval points to an instance of -// the IPX_NETNUM_DATA structure with the netnum filled in. - {$EXTERNALSYM IPX_RERIPNETNUMBER} - IPX_RERIPNETNUMBER = $400E; - -// A hint that broadcast packets may be received. The default is -// TRUE. Applications that do not need to receive broadcast packets -// should set this sockopt to FALSE which may cause better system -// performance (note that it does not necessarily cause broadcasts -// to be filtered for the application). Not valid with getsockopt(). -// optval points to a BOOL. - {$EXTERNALSYM IPX_RECEIVE_BROADCAST} - IPX_RECEIVE_BROADCAST = $400F; - -// On SPX connections, don't delay before sending ack. Applications {Do not Localize} -// that do not tend to have back-and-forth traffic over SPX should -// set this; it will increase the number of acks sent but will remove -// delays in sending acks. optval points to a BOOL. - {$EXTERNALSYM IPX_IMMEDIATESPXACK} - IPX_IMMEDIATESPXACK = $4010; - - -//============================================================= - -// wsnetbs.h -// Copyright (c) 1994-1999, Microsoft Corp. All rights reserved. -// -// Windows Sockets include file for NETBIOS. This file contains all -// standardized NETBIOS information. Include this header file after -// winsock.h. - -// To open a NetBIOS socket, call the socket() function as follows: -// -// s = socket( AF_NETBIOS, {SOCK_SEQPACKET|SOCK_DGRAM}, -Lana ); -// -// where Lana is the NetBIOS Lana number of interest. For example, to -// open a socket for Lana 2, specify -2 as the "protocol" parameter -// to the socket() function. - - -// This is the structure of the SOCKADDR structure for NETBIOS. - -const - {$EXTERNALSYM NETBIOS_NAME_LENGTH} - NETBIOS_NAME_LENGTH = 16; - -type - {$EXTERNALSYM SOCKADDR_NB} - SOCKADDR_NB = record - snb_family : short; - snb_type : u_short; - snb_name : array[0..NETBIOS_NAME_LENGTH-1] of TIdAnsiChar; - end; - {$NODEFINE TSockAddrNB} - TSockAddrNB = SOCKADDR_NB; - {$NODEFINE PSockAddrNB} - PSockAddrNB = ^TSockAddrNB; - {$EXTERNALSYM PSOCKADDR_NB} - PSOCKADDR_NB = PSockAddrNB; - {$EXTERNALSYM LPSOCKADDR_NB} - LPSOCKADDR_NB = PSOCKADDR_NB; - -// Bit values for the snb_type field of SOCKADDR_NB. -const - {$EXTERNALSYM NETBIOS_UNIQUE_NAME} - NETBIOS_UNIQUE_NAME = $0000; - {$EXTERNALSYM NETBIOS_GROUP_NAME} - NETBIOS_GROUP_NAME = $0001; - {$EXTERNALSYM NETBIOS_TYPE_QUICK_UNIQUE} - NETBIOS_TYPE_QUICK_UNIQUE = $0002; - {$EXTERNALSYM NETBIOS_TYPE_QUICK_GROUP} - NETBIOS_TYPE_QUICK_GROUP = $0003; - -// A macro convenient for setting up NETBIOS SOCKADDRs. -{$EXTERNALSYM SET_NETBIOS_SOCKADDR} -procedure SET_NETBIOS_SOCKADDR(snb : PSockAddrNB; const SnbType : Word; const Name : PIdAnsiChar; const Port : TIdAnsiChar); - - -//============================================================= - -// Copyright 1997 - 1998 Microsoft Corporation -// -// Module Name: -// -// ws2atm.h -// -// Abstract: -// -// Winsock 2 ATM Annex definitions. - -const - {$EXTERNALSYM ATMPROTO_AALUSER} - ATMPROTO_AALUSER = $00; // User-defined AAL - {$EXTERNALSYM ATMPROTO_AAL1} - ATMPROTO_AAL1 = $01; // AAL 1 - {$EXTERNALSYM ATMPROTO_AAL2} - ATMPROTO_AAL2 = $02; // AAL 2 - {$EXTERNALSYM ATMPROTO_AAL34} - ATMPROTO_AAL34 = $03; // AAL 3/4 - {$EXTERNALSYM ATMPROTO_AAL5} - ATMPROTO_AAL5 = $05; // AAL 5 - - {$EXTERNALSYM SAP_FIELD_ABSENT} - SAP_FIELD_ABSENT = $FFFFFFFE; - {$EXTERNALSYM SAP_FIELD_ANY} - SAP_FIELD_ANY = $FFFFFFFF; - {$EXTERNALSYM SAP_FIELD_ANY_AESA_SEL} - SAP_FIELD_ANY_AESA_SEL = $FFFFFFFA; - {$EXTERNALSYM SAP_FIELD_ANY_AESA_REST} - SAP_FIELD_ANY_AESA_REST = $FFFFFFFB; - - // values used for AddressType in struct ATM_ADDRESS - {$EXTERNALSYM ATM_E164} - ATM_E164 = $01; // E.164 addressing scheme - {$EXTERNALSYM ATM_NSAP} - ATM_NSAP = $02; // NSAP-style ATM Endsystem Address scheme - {$EXTERNALSYM ATM_AESA} - ATM_AESA = $02; // NSAP-style ATM Endsystem Address scheme - - {$EXTERNALSYM ATM_ADDR_SIZE} - ATM_ADDR_SIZE = 20; - -type - {$EXTERNALSYM ATM_ADDRESS} - ATM_ADDRESS = record - AddressType : DWORD; // E.164 or NSAP-style ATM Endsystem Address - NumofDigits : DWORD; // number of digits; - Addr : Array[0..ATM_ADDR_SIZE-1] of Byte; // IA5 digits for E164, BCD encoding for NSAP - // format as defined in the ATM Forum UNI 3.1 - end; - -// values used for Layer2Protocol in B-LLI -const - {$EXTERNALSYM BLLI_L2_ISO_1745} - BLLI_L2_ISO_1745 = $01; // Basic mode ISO 1745 - {$EXTERNALSYM BLLI_L2_Q921} - BLLI_L2_Q921 = $02; // CCITT Rec. Q.921 - {$EXTERNALSYM BLLI_L2_X25L} - BLLI_L2_X25L = $06; // CCITT Rec. X.25, link layer - {$EXTERNALSYM BLLI_L2_X25M} - BLLI_L2_X25M = $07; // CCITT Rec. X.25, multilink - {$EXTERNALSYM BLLI_L2_ELAPB} - BLLI_L2_ELAPB = $08; // Extended LAPB; for half duplex operation - {$EXTERNALSYM BLLI_L2_HDLC_NRM} - BLLI_L2_HDLC_NRM = $09; // HDLC NRM (ISO 4335) - {$EXTERNALSYM BLLI_L2_HDLC_ABM} - BLLI_L2_HDLC_ABM = $0A; // HDLC ABM (ISO 4335) - {$EXTERNALSYM BLLI_L2_HDLC_ARM} - BLLI_L2_HDLC_ARM = $0B; // HDLC ARM (ISO 4335) - {$EXTERNALSYM BLLI_L2_LLC} - BLLI_L2_LLC = $0C; // LAN logical link control (ISO 8802/2) - {$EXTERNALSYM BLLI_L2_X75} - BLLI_L2_X75 = $0D; // CCITT Rec. X.75, single link procedure - {$EXTERNALSYM BLLI_L2_Q922} - BLLI_L2_Q922 = $0E; // CCITT Rec. Q.922 - {$EXTERNALSYM BLLI_L2_USER_SPECIFIED} - BLLI_L2_USER_SPECIFIED = $10; // User Specified - {$EXTERNALSYM BLLI_L2_ISO_7776} - BLLI_L2_ISO_7776 = $11; // ISO 7776 DTE-DTE operation - -// values used for Layer3Protocol in B-LLI - {$EXTERNALSYM BLLI_L3_X25} - BLLI_L3_X25 = $06; // CCITT Rec. X.25, packet layer - {$EXTERNALSYM BLLI_L3_ISO_8208} - BLLI_L3_ISO_8208 = $07; // ISO/IEC 8208 (X.25 packet layer for DTE - {$EXTERNALSYM BLLI_L3_X223} - BLLI_L3_X223 = $08; // X.223/ISO 8878 - {$EXTERNALSYM BLLI_L3_SIO_8473} - BLLI_L3_SIO_8473 = $09; // ISO/IEC 8473 (OSI connectionless) - {$EXTERNALSYM BLLI_L3_T70} - BLLI_L3_T70 = $0A; // CCITT Rec. T.70 min. network layer - {$EXTERNALSYM BLLI_L3_ISO_TR9577} - BLLI_L3_ISO_TR9577 = $0B; // ISO/IEC TR 9577 Network Layer Protocol ID - {$EXTERNALSYM BLLI_L3_USER_SPECIFIED} - BLLI_L3_USER_SPECIFIED = $10; // User Specified - -// values used for Layer3IPI in B-LLI - {$EXTERNALSYM BLLI_L3_IPI_SNAP} - BLLI_L3_IPI_SNAP = $80; // IEEE 802.1 SNAP identifier - {$EXTERNALSYM BLLI_L3_IPI_IP} - BLLI_L3_IPI_IP = $CC; // Internet Protocol (IP) identifier - -type - {$EXTERNALSYM ATM_BLLI} - ATM_BLLI = record - // Identifies the layer-two protocol. - // Corresponds to the User information layer 2 protocol field in the B-LLI information element. - // A value of SAP_FIELD_ABSENT indicates that this field is not used, and a value of SAP_FIELD_ANY means wildcard. - Layer2Protocol : DWORD; // User information layer 2 protocol - // Identifies the user-specified layer-two protocol. - // Only used if the Layer2Protocol parameter is set to BLLI_L2_USER_SPECIFIED. - // The valid values range from zero-127. - // Corresponds to the User specified layer 2 protocol information field in the B-LLI information element. - Layer2UserSpecifiedProtocol : DWORD; // User specified layer 2 protocol information - // Identifies the layer-three protocol. - // Corresponds to the User information layer 3 protocol field in the B-LLI information element. - // A value of SAP_FIELD_ABSENT indicates that this field is not used, and a value of SAP_FIELD_ANY means wildcard. - Layer3Protocol : DWORD; // User information layer 3 protocol - // Identifies the user-specified layer-three protocol. - // Only used if the Layer3Protocol parameter is set to BLLI_L3_USER_SPECIFIED. - // The valid values range from zero-127. - // Corresponds to the User specified layer 3 protocol information field in the B-LLI information element. - Layer3UserSpecifiedProtocol : DWORD; // User specified layer 3 protocol information - // Identifies the layer-three Initial Protocol Identifier. - // Only used if the Layer3Protocol parameter is set to BLLI_L3_ISO_TR9577. - // Corresponds to the ISO/IEC TR 9577 Initial Protocol Identifier field in the B-LLI information element. - Layer3IPI : DWORD; // ISO/IEC TR 9577 Initial Protocol Identifier - // Identifies the 802.1 SNAP identifier. - // Only used if the Layer3Protocol parameter is set to BLLI_L3_ISO_TR9577 and Layer3IPI is set to BLLI_L3_IPI_SNAP, - // indicating an IEEE 802.1 SNAP identifier. Corresponds to the OUI and PID fields in the B-LLI information element. - SnapID : Array[0..4] of Byte; // SNAP ID consisting of OUI and PID - end; - -// values used for the HighLayerInfoType field in ATM_BHLI -const - {$EXTERNALSYM BHLI_ISO} - BHLI_ISO = $00; // ISO - {$EXTERNALSYM BHLI_UserSpecific} - BHLI_UserSpecific = $01; // User Specific - {$EXTERNALSYM BHLI_HighLayerProfile} - BHLI_HighLayerProfile = $02; // High layer profile (only in UNI3.0) - {$EXTERNALSYM BHLI_VendorSpecificAppId} - BHLI_VendorSpecificAppId = $03; // Vendor-Specific Application ID - -type - {$EXTERNALSYM ATM_BHLI} - ATM_BHLI = record - // Identifies the high layer information type field in the B-LLI information element. - // Note that the type BHLI_HighLayerProfile has been eliminated in UNI 3.1. - // A value of SAP_FIELD_ABSENT indicates that B-HLI is not present, and a value of SAP_FIELD_ANY means wildcard. - HighLayerInfoType : DWORD; // High Layer Information Type - // Identifies the number of bytes from one to eight in the HighLayerInfo array. - // Valid values include eight for the cases of BHLI_ISO and BHLI_UserSpecific, - // four for BHLI_HighLayerProfile, and seven for BHLI_VendorSpecificAppId. - HighLayerInfoLength : DWORD; // number of bytes in HighLayerInfo - // Identifies the high layer information field in the B-LLI information element. - // In the case of HighLayerInfoType being BHLI_VendorSpecificAppId, - // the first 3 bytes consist of a globally-administered Organizationally Unique Identifier (OUI) - // (as per IEEE standard 802-1990), followed by a 4-byte application identifier, - // which is administered by the vendor identified by the OUI. - // Value for the case of BHLI_UserSpecific is user defined and requires bilateral agreement between two end users. - HighLayerInfo : Array[0..7] of Byte; // the value dependent on the HighLayerInfoType field - end; - -// A new address family, AF_ATM, is introduced for native ATM services, -// and the corresponding SOCKADDR structure, sockaddr_atm, is defined in the following. -// To open a socket for native ATM services, parameters in socket should contain -// AF_ATM, SOCK_RAW, and ATMPROTO_AAL5 or ATMPROTO_AALUSER, respectively. - {$EXTERNALSYM SOCKADDR_ATM} - SOCKADDR_ATM = record - // Identifies the address family, which is AF_ATM in this case. - satm_family : u_short; - // Identifies the ATM address that could be either in E.164 or NSAP-style ATM End Systems Address format. - // This field will be mapped to the Called Party Number IE (Information Element) - // if it is specified in bind and WSPBind for a listening socket, or in connect, WSAConnect, WSPConnect, - // WSAJoinLeaf, or WSPJoinLeaf for a connecting socket. - // It will be mapped to the Calling Party Number IE if specified in bind and WSPBind for a connecting socket. - satm_number : ATM_ADDRESS; - // Identifies the fields in the B-LLI Information Element that are used along with satm_bhli to identify an application. - // Note that the B-LLI layer two information is treated as not present - // if its Layer2Protocol field contains SAP_FIELD_ABSENT, or as a wildcard if it contains SAP_FIELD_ANY. - // Similarly, the B-LLI layer three information is treated as not present - // if its Layer3Protocol field contains SAP_FIELD_ABSENT, or as a wildcard if it contains SAP_FIELD_ANY. - satm_blli : ATM_BLLI; // B-LLI - // Identifies the fields in the B-HLI Information Element that are used along with satm_blli to identify an application. - satm_bhli : ATM_BHLI; // B-HLI - end; - {$NODEFINE TSockAddrATM} - TSockAddrATM = SOCKADDR_ATM; - {$NODEFINE PSockAddrATM} - PSockAddrATM = ^TSockAddrATM; - {$EXTERNALSYM PSOCKADDR_ATM} - PSOCKADDR_ATM = PSockAddrATM; - {$EXTERNALSYM LPSOCKADDR_ATM} - LPSOCKADDR_ATM = PSOCKADDR_ATM; - - {$EXTERNALSYM Q2931_IE_TYPE} - Q2931_IE_TYPE = ( - IE_AALParameters, - IE_TrafficDescriptor, - IE_BroadbandBearerCapability, - IE_BHLI, - IE_BLLI, - IE_CalledPartyNumber, - IE_CalledPartySubaddress, - IE_CallingPartyNumber, - IE_CallingPartySubaddress, - IE_Cause, - IE_QOSClass, - IE_TransitNetworkSelection); - - {$EXTERNALSYM Q2931_IE} - Q2931_IE = record - IEType : Q2931_IE_TYPE; - IELength : ULONG; - IE : Array[0..0] of Byte; - end; - -// manifest constants for the AALType field in struct AAL_PARAMETERS_IE - {$EXTERNALSYM AAL_TYPE} - AAL_TYPE = LongInt; - -const - {$EXTERNALSYM AALTYPE_5} - AALTYPE_5 = 5; // AAL 5 - {$EXTERNALSYM AALTYPE_USER} - AALTYPE_USER = 16; // user-defined AAL - - // values used for the Mode field in struct AAL5_PARAMETERS - {$EXTERNALSYM AAL5_MODE_MESSAGE} - AAL5_MODE_MESSAGE = $01; - {$EXTERNALSYM AAL5_MODE_STREAMING} - AAL5_MODE_STREAMING = $02; - -// values used for the SSCSType field in struct AAL5_PARAMETERS - {$EXTERNALSYM AAL5_SSCS_NULL} - AAL5_SSCS_NULL = $00; - {$EXTERNALSYM AAL5_SSCS_SSCOP_ASSURED} - AAL5_SSCS_SSCOP_ASSURED = $01; - {$EXTERNALSYM AAL5_SSCS_SSCOP_NON_ASSURED} - AAL5_SSCS_SSCOP_NON_ASSURED = $02; - {$EXTERNALSYM AAL5_SSCS_FRAME_RELAY} - AAL5_SSCS_FRAME_RELAY = $04; - -type - {$EXTERNALSYM AAL5_PARAMETERS} - AAL5_PARAMETERS = record - ForwardMaxCPCSSDUSize : ULONG; - BackwardMaxCPCSSDUSize : ULONG; - Mode : Byte; // only available in UNI 3.0 - SSCSType : Byte; - end; - - {$EXTERNALSYM AALUSER_PARAMETERS} - AALUSER_PARAMETERS = record - UserDefined : ULONG; - end; - - {$EXTERNALSYM AAL_PARAMETERS_IE} - AAL_PARAMETERS_IE = record - AALType : AAL_TYPE; - case Byte of - 0: ( AAL5Parameters : AAL5_PARAMETERS ); - 1: ( AALUserParameters : AALUSER_PARAMETERS ); - end; - - {$EXTERNALSYM ATM_TD} - ATM_TD = record - PeakCellRate_CLP0 : ULONG; - PeakCellRate_CLP01 : ULONG; - SustainableCellRate_CLP0 : ULONG; - SustainableCellRate_CLP01 : ULONG; - MaxBurstSize_CLP0 : ULONG; - MaxBurstSize_CLP01 : ULONG; - Tagging : LongBool; - end; - - {$EXTERNALSYM ATM_TRAFFIC_DESCRIPTOR_IE} - ATM_TRAFFIC_DESCRIPTOR_IE = record - _Forward : ATM_TD; - Backward : ATM_TD; - BestEffort : LongBool; - end; - -// values used for the BearerClass field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE -const - {$EXTERNALSYM BCOB_A} - BCOB_A = $01; // Bearer class A - {$EXTERNALSYM BCOB_C} - BCOB_C = $03; // Bearer class C - {$EXTERNALSYM BCOB_X} - BCOB_X = $10; // Bearer class X - -// values used for the TrafficType field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE - {$EXTERNALSYM TT_NOIND} - TT_NOIND = $00; // No indication of traffic type - {$EXTERNALSYM TT_CBR} - TT_CBR = $04; // Constant bit rate - {$EXTERNALSYM TT_VBR} - TT_VBR = $06; // Variable bit rate - -// values used for the TimingRequirements field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE - {$EXTERNALSYM TR_NOIND} - TR_NOIND = $00; // No timing requirement indication - {$EXTERNALSYM TR_END_TO_END} - TR_END_TO_END = $01; // End-to-end timing required - {$EXTERNALSYM TR_NO_END_TO_END} - TR_NO_END_TO_END = $02; // End-to-end timing not required - -// values used for the ClippingSusceptability field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE - {$EXTERNALSYM CLIP_NOT} - CLIP_NOT = $00; // Not susceptible to clipping - {$EXTERNALSYM CLIP_SUS} - CLIP_SUS = $20; // Susceptible to clipping - -// values used for the UserPlaneConnectionConfig field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE - {$EXTERNALSYM UP_P2P} - UP_P2P = $00; // Point-to-point connection - {$EXTERNALSYM UP_P2MP} - UP_P2MP = $01; // Point-to-multipoint connection - -type - {$EXTERNALSYM ATM_BROADBAND_BEARER_CAPABILITY_IE} - ATM_BROADBAND_BEARER_CAPABILITY_IE = record - BearerClass : Byte; - TrafficType : Byte; - TimingRequirements : Byte; - ClippingSusceptability : Byte; - UserPlaneConnectionConfig : Byte; - end; - {$EXTERNALSYM ATM_BHLI_IE} - ATM_BHLI_IE = ATM_BHLI; - -// values used for the Layer2Mode field in struct ATM_BLLI_IE -const - {$EXTERNALSYM BLLI_L2_MODE_NORMAL} - BLLI_L2_MODE_NORMAL = $40; - {$EXTERNALSYM BLLI_L2_MODE_EXT} - BLLI_L2_MODE_EXT = $80; - -// values used for the Layer3Mode field in struct ATM_BLLI_IE - {$EXTERNALSYM BLLI_L3_MODE_NORMAL} - BLLI_L3_MODE_NORMAL = $40; - {$EXTERNALSYM BLLI_L3_MODE_EXT} - BLLI_L3_MODE_EXT = $80; - -// values used for the Layer3DefaultPacketSize field in struct ATM_BLLI_IE - {$EXTERNALSYM BLLI_L3_PACKET_16} - BLLI_L3_PACKET_16 = $04; - {$EXTERNALSYM BLLI_L3_PACKET_32} - BLLI_L3_PACKET_32 = $05; - {$EXTERNALSYM BLLI_L3_PACKET_64} - BLLI_L3_PACKET_64 = $06; - {$EXTERNALSYM BLLI_L3_PACKET_128} - BLLI_L3_PACKET_128 = $07; - {$EXTERNALSYM BLLI_L3_PACKET_256} - BLLI_L3_PACKET_256 = $08; - {$EXTERNALSYM BLLI_L3_PACKET_512} - BLLI_L3_PACKET_512 = $09; - {$EXTERNALSYM BLLI_L3_PACKET_1024} - BLLI_L3_PACKET_1024 = $0A; - {$EXTERNALSYM BLLI_L3_PACKET_2048} - BLLI_L3_PACKET_2048 = $0B; - {$EXTERNALSYM BLLI_L3_PACKET_4096} - BLLI_L3_PACKET_4096 = $0C; - -type - {$EXTERNALSYM ATM_BLLI_IE} - ATM_BLLI_IE = record - Layer2Protocol : DWORD; // User information layer 2 protocol - Layer2Mode : Byte; - Layer2WindowSize : Byte; - Layer2UserSpecifiedProtocol : DWORD; // User specified layer 2 protocol information - Layer3Protocol : DWORD; // User information layer 3 protocol - Layer3Mode : Byte; - Layer3DefaultPacketSize : Byte; - Layer3PacketWindowSize : Byte; - Layer3UserSpecifiedProtocol : DWORD; // User specified layer 3 protocol information - Layer3IPI : DWORD; // ISO/IEC TR 9577 Initial Protocol Identifier - SnapID : Array[0..4] of Byte; // SNAP ID consisting of OUI and PID - end; - {$EXTERNALSYM ATM_CALLED_PARTY_NUMBER_IE} - ATM_CALLED_PARTY_NUMBER_IE = ATM_ADDRESS; - {$EXTERNALSYM ATM_CALLED_PARTY_SUBADDRESS_IE} - ATM_CALLED_PARTY_SUBADDRESS_IE = ATM_ADDRESS; - -// values used for the Presentation_Indication field in struct ATM_CALLING_PARTY_NUMBER_IE -const - {$EXTERNALSYM PI_ALLOWED} - PI_ALLOWED = $00; - {$EXTERNALSYM PI_RESTRICTED} - PI_RESTRICTED = $40; - {$EXTERNALSYM PI_NUMBER_NOT_AVAILABLE} - PI_NUMBER_NOT_AVAILABLE = $80; - -// values used for the Screening_Indicator field in struct ATM_CALLING_PARTY_NUMBER_IE - {$EXTERNALSYM SI_USER_NOT_SCREENED} - SI_USER_NOT_SCREENED = $00; - {$EXTERNALSYM SI_USER_PASSED} - SI_USER_PASSED = $01; - {$EXTERNALSYM SI_USER_FAILED} - SI_USER_FAILED = $02; - {$EXTERNALSYM SI_NETWORK} - SI_NETWORK = $03; - -type - {$EXTERNALSYM ATM_CALLING_PARTY_NUMBER_IE} - ATM_CALLING_PARTY_NUMBER_IE = record - ATM_Number : ATM_ADDRESS; - Presentation_Indication : Byte; - Screening_Indicator : Byte; - end; - {$EXTERNALSYM ATM_CALLING_PARTY_SUBADDRESS_IE} - ATM_CALLING_PARTY_SUBADDRESS_IE = ATM_ADDRESS; - -// values used for the Location field in struct ATM_CAUSE_IE -const - {$EXTERNALSYM CAUSE_LOC_USER} - CAUSE_LOC_USER = $00; - {$EXTERNALSYM CAUSE_LOC_PRIVATE_LOCAL} - CAUSE_LOC_PRIVATE_LOCAL = $01; - {$EXTERNALSYM CAUSE_LOC_PUBLIC_LOCAL} - CAUSE_LOC_PUBLIC_LOCAL = $02; - {$EXTERNALSYM CAUSE_LOC_TRANSIT_NETWORK} - CAUSE_LOC_TRANSIT_NETWORK = $03; - {$EXTERNALSYM CAUSE_LOC_PUBLIC_REMOTE} - CAUSE_LOC_PUBLIC_REMOTE = $04; - {$EXTERNALSYM CAUSE_LOC_PRIVATE_REMOTE} - CAUSE_LOC_PRIVATE_REMOTE = $05; - {$EXTERNALSYM CAUSE_LOC_INTERNATIONAL_NETWORK} - CAUSE_LOC_INTERNATIONAL_NETWORK = $06; - {$EXTERNALSYM CAUSE_LOC_BEYOND_INTERWORKING} - CAUSE_LOC_BEYOND_INTERWORKING = $0A; - -// values used for the Cause field in struct ATM_CAUSE_IE - {$EXTERNALSYM CAUSE_UNALLOCATED_NUMBER} - CAUSE_UNALLOCATED_NUMBER = $01; - {$EXTERNALSYM CAUSE_NO_ROUTE_TO_TRANSIT_NETWORK} - CAUSE_NO_ROUTE_TO_TRANSIT_NETWORK = $02; - {$EXTERNALSYM CAUSE_NO_ROUTE_TO_DESTINATION} - CAUSE_NO_ROUTE_TO_DESTINATION = $03; - {$EXTERNALSYM CAUSE_VPI_VCI_UNACCEPTABLE} - CAUSE_VPI_VCI_UNACCEPTABLE = $0A; - {$EXTERNALSYM CAUSE_NORMAL_CALL_CLEARING} - CAUSE_NORMAL_CALL_CLEARING = $10; - {$EXTERNALSYM CAUSE_USER_BUSY} - CAUSE_USER_BUSY = $11; - {$EXTERNALSYM CAUSE_NO_USER_RESPONDING} - CAUSE_NO_USER_RESPONDING = $12; - {$EXTERNALSYM CAUSE_CALL_REJECTED} - CAUSE_CALL_REJECTED = $15; - {$EXTERNALSYM CAUSE_NUMBER_CHANGED} - CAUSE_NUMBER_CHANGED = $16; - {$EXTERNALSYM CAUSE_USER_REJECTS_CLIR} - CAUSE_USER_REJECTS_CLIR = $17; - {$EXTERNALSYM CAUSE_DESTINATION_OUT_OF_ORDER} - CAUSE_DESTINATION_OUT_OF_ORDER = $1B; - {$EXTERNALSYM CAUSE_INVALID_NUMBER_FORMAT} - CAUSE_INVALID_NUMBER_FORMAT = $1C; - {$EXTERNALSYM CAUSE_STATUS_ENQUIRY_RESPONSE} - CAUSE_STATUS_ENQUIRY_RESPONSE = $1E; - {$EXTERNALSYM CAUSE_NORMAL_UNSPECIFIED} - CAUSE_NORMAL_UNSPECIFIED = $1F; - {$EXTERNALSYM CAUSE_VPI_VCI_UNAVAILABLE} - CAUSE_VPI_VCI_UNAVAILABLE = $23; - {$EXTERNALSYM CAUSE_NETWORK_OUT_OF_ORDER} - CAUSE_NETWORK_OUT_OF_ORDER = $26; - {$EXTERNALSYM CAUSE_TEMPORARY_FAILURE} - CAUSE_TEMPORARY_FAILURE = $29; - {$EXTERNALSYM CAUSE_ACCESS_INFORMAION_DISCARDED} - CAUSE_ACCESS_INFORMAION_DISCARDED = $2B; - {$EXTERNALSYM CAUSE_NO_VPI_VCI_AVAILABLE} - CAUSE_NO_VPI_VCI_AVAILABLE = $2D; - {$EXTERNALSYM CAUSE_RESOURCE_UNAVAILABLE} - CAUSE_RESOURCE_UNAVAILABLE = $2F; - {$EXTERNALSYM CAUSE_QOS_UNAVAILABLE} - CAUSE_QOS_UNAVAILABLE = $31; - {$EXTERNALSYM CAUSE_USER_CELL_RATE_UNAVAILABLE} - CAUSE_USER_CELL_RATE_UNAVAILABLE = $33; - {$EXTERNALSYM CAUSE_BEARER_CAPABILITY_UNAUTHORIZED} - CAUSE_BEARER_CAPABILITY_UNAUTHORIZED = $39; - {$EXTERNALSYM CAUSE_BEARER_CAPABILITY_UNAVAILABLE} - CAUSE_BEARER_CAPABILITY_UNAVAILABLE = $3A; - {$EXTERNALSYM CAUSE_OPTION_UNAVAILABLE} - CAUSE_OPTION_UNAVAILABLE = $3F; - {$EXTERNALSYM CAUSE_BEARER_CAPABILITY_UNIMPLEMENTED} - CAUSE_BEARER_CAPABILITY_UNIMPLEMENTED = $41; - {$EXTERNALSYM CAUSE_UNSUPPORTED_TRAFFIC_PARAMETERS} - CAUSE_UNSUPPORTED_TRAFFIC_PARAMETERS = $49; - {$EXTERNALSYM CAUSE_INVALID_CALL_REFERENCE} - CAUSE_INVALID_CALL_REFERENCE = $51; - {$EXTERNALSYM CAUSE_CHANNEL_NONEXISTENT} - CAUSE_CHANNEL_NONEXISTENT = $52; - {$EXTERNALSYM CAUSE_INCOMPATIBLE_DESTINATION} - CAUSE_INCOMPATIBLE_DESTINATION = $58; - {$EXTERNALSYM CAUSE_INVALID_ENDPOINT_REFERENCE} - CAUSE_INVALID_ENDPOINT_REFERENCE = $59; - {$EXTERNALSYM CAUSE_INVALID_TRANSIT_NETWORK_SELECTION} - CAUSE_INVALID_TRANSIT_NETWORK_SELECTION = $5B; - {$EXTERNALSYM CAUSE_TOO_MANY_PENDING_ADD_PARTY} - CAUSE_TOO_MANY_PENDING_ADD_PARTY = $5C; - {$EXTERNALSYM CAUSE_AAL_PARAMETERS_UNSUPPORTED} - CAUSE_AAL_PARAMETERS_UNSUPPORTED = $5D; - {$EXTERNALSYM CAUSE_MANDATORY_IE_MISSING} - CAUSE_MANDATORY_IE_MISSING = $60; - {$EXTERNALSYM CAUSE_UNIMPLEMENTED_MESSAGE_TYPE} - CAUSE_UNIMPLEMENTED_MESSAGE_TYPE = $61; - {$EXTERNALSYM CAUSE_UNIMPLEMENTED_IE} - CAUSE_UNIMPLEMENTED_IE = $63; - {$EXTERNALSYM CAUSE_INVALID_IE_CONTENTS} - CAUSE_INVALID_IE_CONTENTS = $64; - {$EXTERNALSYM CAUSE_INVALID_STATE_FOR_MESSAGE} - CAUSE_INVALID_STATE_FOR_MESSAGE = $65; - {$EXTERNALSYM CAUSE_RECOVERY_ON_TIMEOUT} - CAUSE_RECOVERY_ON_TIMEOUT = $66; - {$EXTERNALSYM CAUSE_INCORRECT_MESSAGE_LENGTH} - CAUSE_INCORRECT_MESSAGE_LENGTH = $68; - {$EXTERNALSYM CAUSE_PROTOCOL_ERROR} - CAUSE_PROTOCOL_ERROR = $6F; - -// values used for the Condition portion of the Diagnostics field -// in struct ATM_CAUSE_IE, for certain Cause values - {$EXTERNALSYM CAUSE_COND_UNKNOWN} - CAUSE_COND_UNKNOWN = $00; - {$EXTERNALSYM CAUSE_COND_PERMANENT} - CAUSE_COND_PERMANENT = $01; - {$EXTERNALSYM CAUSE_COND_TRANSIENT} - CAUSE_COND_TRANSIENT = $02; - -// values used for the Rejection Reason portion of the Diagnostics field -// in struct ATM_CAUSE_IE, for certain Cause values - {$EXTERNALSYM CAUSE_REASON_USER} - CAUSE_REASON_USER = $00; - {$EXTERNALSYM CAUSE_REASON_IE_MISSING} - CAUSE_REASON_IE_MISSING = $04; - {$EXTERNALSYM CAUSE_REASON_IE_INSUFFICIENT} - CAUSE_REASON_IE_INSUFFICIENT = $08; - -// values used for the P-U flag of the Diagnostics field -// in struct ATM_CAUSE_IE, for certain Cause values - {$EXTERNALSYM CAUSE_PU_PROVIDER} - CAUSE_PU_PROVIDER = $00; - {$EXTERNALSYM CAUSE_PU_USER} - CAUSE_PU_USER = $08; - -// values used for the N-A flag of the Diagnostics field -// in struct ATM_CAUSE_IE, for certain Cause values - {$EXTERNALSYM CAUSE_NA_NORMAL} - CAUSE_NA_NORMAL = $00; - {$EXTERNALSYM CAUSE_NA_ABNORMAL} - CAUSE_NA_ABNORMAL = $04; - -type - {$EXTERNALSYM ATM_CAUSE_IE} - ATM_CAUSE_IE = record - Location : Byte; - Cause : Byte; - DiagnosticsLength : Byte; - Diagnostics : Array[0..3] of Byte; - end; - -// values used for the QOSClassForward and QOSClassBackward -// field in struct ATM_QOS_CLASS_IE -const - {$EXTERNALSYM QOS_CLASS0} - QOS_CLASS0 = $00; - {$EXTERNALSYM QOS_CLASS1} - QOS_CLASS1 = $01; - {$EXTERNALSYM QOS_CLASS2} - QOS_CLASS2 = $02; - {$EXTERNALSYM QOS_CLASS3} - QOS_CLASS3 = $03; - {$EXTERNALSYM QOS_CLASS4} - QOS_CLASS4 = $04; - -type - {$EXTERNALSYM ATM_QOS_CLASS_IE} - ATM_QOS_CLASS_IE = record - QOSClassForward : Byte; - QOSClassBackward : Byte; - end; - -// values used for the TypeOfNetworkId field in struct ATM_TRANSIT_NETWORK_SELECTION_IE -const - {$EXTERNALSYM TNS_TYPE_NATIONAL} - TNS_TYPE_NATIONAL = $40; - -// values used for the NetworkIdPlan field in struct ATM_TRANSIT_NETWORK_SELECTION_IE - {$EXTERNALSYM TNS_PLAN_CARRIER_ID_CODE} - TNS_PLAN_CARRIER_ID_CODE = $01; - -type - {$EXTERNALSYM ATM_TRANSIT_NETWORK_SELECTION_IE} - ATM_TRANSIT_NETWORK_SELECTION_IE = record - TypeOfNetworkId : Byte; - NetworkIdPlan : Byte; - NetworkIdLength : Byte; - NetworkId : Array[0..0] of Byte; - end; - -// ATM specific Ioctl codes -const - {$EXTERNALSYM SIO_GET_NUMBER_OF_ATM_DEVICES} - SIO_GET_NUMBER_OF_ATM_DEVICES = $50160001; - {$EXTERNALSYM SIO_GET_ATM_ADDRESS} - SIO_GET_ATM_ADDRESS = $d0160002; - {$EXTERNALSYM SIO_ASSOCIATE_PVC} - SIO_ASSOCIATE_PVC = $90160003; - {$EXTERNALSYM SIO_GET_ATM_CONNECTION_ID} - SIO_GET_ATM_CONNECTION_ID = $50160004; - -// ATM Connection Identifier -type - {$EXTERNALSYM ATM_CONNECTION_ID} - ATM_CONNECTION_ID = record - DeviceNumber : DWORD; - VPI : DWORD; - VCI : DWORD; - end; - -// Input buffer format for SIO_ASSOCIATE_PVC - {$EXTERNALSYM ATM_PVC_PARAMS} - ATM_PVC_PARAMS = record - PvcConnectionId : ATM_CONNECTION_ID; - PvcQos : QOS; - end; - - {$NODEFINE InitializeWinSock} - procedure InitializeWinSock; - {$NODEFINE UninitializeWinSock} - procedure UninitializeWinSock; - function Winsock2Loaded: Boolean; - function WinsockHandle : TIdLibHandle; - -//JPM -{ -I made these symbols up so to prevent range check warnings in FreePascal. -SizeOf is a SmallInt when an expression is evaluated at run-time. This -run-time evaluation makes no sense because the compiler knows these when compiling -so it should give us the numbers. - -} -const - {$EXTERNALSYM SIZE_WSACMSGHDR} - SIZE_WSACMSGHDR = DWORD(SizeOf(WSACMSGHDR)); - {$EXTERNALSYM SIZE_FARPROC} - SIZE_FARPROC = DWORD(SizeOf(FARPROC)); - {$EXTERNALSYM MAX_NATURAL_ALIGNMENT_SUB_1} - MAX_NATURAL_ALIGNMENT_SUB_1 = DWORD(MAX_NATURAL_ALIGNMENT - 1); - {$EXTERNALSYM SIZE_IP_MSFILTER} - SIZE_IP_MSFILTER = DWORD(SizeOf(ip_msfilter)); - {$EXTERNALSYM SIZE_TINADDR} - SIZE_TINADDR = DWORD(SizeOf(TInAddr)); - {$EXTERNALSYM SIZE_TIN6ADDR} - SIZE_TIN6ADDR = DWORD(SizeOf(TIn6Addr)); - {$EXTERNALSYM SIZE_TSOCKADDRIN} - SIZE_TSOCKADDRIN = DWORD(SizeOf(TSockAddrIn)); - {$EXTERNALSYM SIZE_TSOCKADDRIN6} - SIZE_TSOCKADDRIN6 = DWORD(SizeOf(TSockAddrIn6)); - {$EXTERNALSYM SIZE_GROUP_FILTER} - SIZE_GROUP_FILTER = DWORD(SizeOf(GROUP_FILTER)); - {$EXTERNALSYM SIZE_TADDRINFO} - SIZE_TADDRINFO = DWORD(SizeOf(TAddrInfo)); - {$EXTERNALSYM SIZE_SOCKADDR_STORAGE} - SIZE_SOCKADDR_STORAGE = DWORD(sizeof(SOCKADDR_STORAGE)); - {$IFNDEF WINCE} - {$EXTERNALSYM SIZE_TWSAMSG} - SIZE_TWSAMSG = DWORD(SizeOf(TWSAMSG)); - {$ENDIF} - {$EXTERNALSYM SIZE_GUID} - SIZE_GUID = DWORD(SizeOf(TGuid)); - {$EXTERNALSYM SIZE_INTEGER} - SIZE_INTEGER = DWORD(SizeOf(Integer)); - -//============================================================= - -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// Module Name: -// -// mstcpip.h -// -// Abstract: -// -// This module contains Microsoft-specific extensions to the core -// Winsock definitions. -// -// Environment: -// -// user mode or kernel mode - -type - {$EXTERNALSYM TRANSPORT_SETTING_ID} - TRANSPORT_SETTING_ID = record - Guid : TGUID; - end; - {$EXTERNALSYM PTRANSPORT_SETTING_ID} - PTRANSPORT_SETTING_ID = ^TRANSPORT_SETTING_ID; - {$EXTERNALSYM _tcp_keepalive} - _tcp_keepalive = record - onoff: u_long; - keepalivetime: u_long; - keepaliveinterval: u_long; - end; - {$EXTERNALSYM TCP_INITIAL_RTO_PARAMETERS} - TCP_INITIAL_RTO_PARAMETERS = record - // - // Supplies the initial RTT in milliseconds. - // - Rtt : USHORT; - - // - // Supplies the number of retransmissions attempted before the connection - // setup fails. - // - - MaxSynRetransmissions : UCHAR; - end; - {$EXTERNALSYM PTCP_INITIAL_RTO_PARAMETERS} - PTCP_INITIAL_RTO_PARAMETERS = ^TCP_INITIAL_RTO_PARAMETERS; - {$EXTERNALSYM _INET_PORT_RANGE} - _INET_PORT_RANGE = record - StartPort : USHORT; - NumberOfPorts : USHORT; - end; - {$EXTERNALSYM INET_PORT_RANGE} - INET_PORT_RANGE = _INET_PORT_RANGE; - {$EXTERNALSYM PINET_PORT_RANGE} - PINET_PORT_RANGE = ^INET_PORT_RANGE; - {$EXTERNALSYM INET_PORT_RESERVATION} - INET_PORT_RESERVATION = _INET_PORT_RANGE; - {$EXTERNALSYM PINET_PORT_RESERVATION} - PINET_PORT_RESERVATION = ^INET_PORT_RESERVATION; - {$EXTERNALSYM INET_PORT_RESERVATION_TOKEN} - INET_PORT_RESERVATION_TOKEN = record - Token : ULONG64; - end; - {$EXTERNALSYM PINET_PORT_RESERVATION_TOKEN} - PINET_PORT_RESERVATION_TOKEN = ^INET_PORT_RESERVATION_TOKEN; - {$EXTERNALSYM INET_PORT_RESERVATION_INSTANCE} - INET_PORT_RESERVATION_INSTANCE = record - Reservation : INET_PORT_RESERVATION; - Token : INET_PORT_RESERVATION_TOKEN; - end; - {$EXTERNALSYM PINET_PORT_RESERVATION_INSTANCE} - PINET_PORT_RESERVATION_INSTANCE = ^INET_PORT_RESERVATION_INSTANCE; - - {$EXTERNALSYM INET_PORT_RESERVATION_INFORMATION} - INET_PORT_RESERVATION_INFORMATION = record - AssignmentCount : ULONG; - OwningPid : ULONG; - end; - {$EXTERNALSYM PINET_PORT_RESERVATION_INFORMATION} - PINET_PORT_RESERVATION_INFORMATION = ^INET_PORT_RESERVATION_INFORMATION; - {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS} - {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_INVALID} - {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_SOFTWARE_SLOT_ALLOCATED} - {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_HARDWARE_SLOT_ALLOCATED} - {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_POLICY_ERROR} - {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_SYSTEM_ERROR} - {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_TRANSPORT_DISCONNECTED} - {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_SERVICE_UNAVAILABLE} - CONTROL_CHANNEL_TRIGGER_STATUS = ( - CONTROL_CHANNEL_TRIGGER_STATUS_INVALID, - CONTROL_CHANNEL_TRIGGER_STATUS_SOFTWARE_SLOT_ALLOCATED, - CONTROL_CHANNEL_TRIGGER_STATUS_HARDWARE_SLOT_ALLOCATED, - CONTROL_CHANNEL_TRIGGER_STATUS_POLICY_ERROR, - CONTROL_CHANNEL_TRIGGER_STATUS_SYSTEM_ERROR, - CONTROL_CHANNEL_TRIGGER_STATUS_TRANSPORT_DISCONNECTED, - CONTROL_CHANNEL_TRIGGER_STATUS_SERVICE_UNAVAILABLE); - {$EXTERNALSYM PCONTROL_CHANNEL_TRIGGER_STATUS} - PCONTROL_CHANNEL_TRIGGER_STATUS = ^CONTROL_CHANNEL_TRIGGER_STATUS; - {$EXTERNALSYM REAL_TIME_NOTIFICATION_SETTING_INPUT} - REAL_TIME_NOTIFICATION_SETTING_INPUT = record - TransportSettingId : TRANSPORT_SETTING_ID; - BrokerEventGuid : TGUID; - end; - {$EXTERNALSYM PREAL_TIME_NOTIFICATION_SETTING_INPUT} - PREAL_TIME_NOTIFICATION_SETTING_INPUT = ^REAL_TIME_NOTIFICATION_SETTING_INPUT; - {$EXTERNALSYM REAL_TIME_NOTIFICATION_SETTING_OUTPUT} - REAL_TIME_NOTIFICATION_SETTING_OUTPUT = record - ChannelStatus : CONTROL_CHANNEL_TRIGGER_STATUS; - end; - {$EXTERNALSYM PREAL_TIME_NOTIFICATION_SETTING_OUTPUT} - PREAL_TIME_NOTIFICATION_SETTING_OUTPUT = ^REAL_TIME_NOTIFICATION_SETTING_OUTPUT; - {$EXTERNALSYM RCVALL_VALUE} - {$EXTERNALSYM RCVALL_OFF} - {$EXTERNALSYM RCVALL_ON} - {$EXTERNALSYM RCVALL_SOCKETLEVELONLY} - {$EXTERNALSYM RCVALL_IPLEVEL} - RCVALL_VALUE = ( - RCVALL_OFF, - RCVALL_ON, - RCVALL_SOCKETLEVELONLY, - RCVALL_IPLEVEL - ); - {$EXTERNALSYM PRCVALL_VALUE} - PRCVALL_VALUE = ^RCVALL_VALUE; - {$EXTERNALSYM RCVALL_IF} - RCVALL_IF = record - Mode : RCVALL_VALUE; - _Interface : ULONG; - end; - {$EXTERNALSYM PRCVALL_IF} - PRCVALL_IF = ^RCVALL_IF; - {$EXTERNALSYM SOCKET_SECURITY_QUERY_INFO_IPSEC2} - SOCKET_SECURITY_QUERY_INFO_IPSEC2 = record - SecurityProtocol : SOCKET_SECURITY_PROTOCOL; - Flags : ULONG; - PeerApplicationAccessTokenHandle : UINT64; - PeerMachineAccessTokenHandle : UINT64; - MmSaId : UINT64; - QmSaId : UINT64; - NegotiationWinerr : UINT32; - SaLookupContext : TGuid; - end; - {$EXTERNALSYM PSOCKET_SECURITY_QUERY_INFO_IPSEC2} - PSOCKET_SECURITY_QUERY_INFO_IPSEC2 = ^SOCKET_SECURITY_QUERY_INFO_IPSEC2; - {$EXTERNALSYM RSS_SCALABILITY_INFO} - RSS_SCALABILITY_INFO = record - RssEnabled : BOOL; - end; - {$EXTERNALSYM PRSS_SCALABILITY_INFO} - PRSS_SCALABILITY_INFO = ^RSS_SCALABILITY_INFO; - -const -// -// Argument structures for SIO_QUERY_TRANSPORT_SETTING and -// SIO_QUERY_TRANSPORT_SETTING. -// - - {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_MAX} - CONTROL_CHANNEL_TRIGGER_STATUS_MAX = CONTROL_CHANNEL_TRIGGER_STATUS_SYSTEM_ERROR; - -// -// New WSAIoctl Options -// - {$EXTERNALSYM SIO_RCVALL} - SIO_RCVALL = (IOC_IN or IOC_VENDOR or 1); - {$EXTERNALSYM SIO_RCVALL_MCAST} - SIO_RCVALL_MCAST = (IOC_IN or IOC_VENDOR or 2); - {$EXTERNALSYM SIO_RCVALL_IGMPMCAST} - SIO_RCVALL_IGMPMCAST = (IOC_IN or IOC_VENDOR or 3); - {$EXTERNALSYM SIO_KEEPALIVE_VALS} - SIO_KEEPALIVE_VALS = (IOC_IN or IOC_VENDOR or 4); - {$EXTERNALSYM SIO_ABSORB_RTRALERT} - SIO_ABSORB_RTRALERT = (IOC_IN or IOC_VENDOR or 5); - {$EXTERNALSYM SIO_UCAST_IF} - SIO_UCAST_IF = (IOC_IN or IOC_VENDOR or 6); - {$EXTERNALSYM SIO_LIMIT_BROADCASTS} - SIO_LIMIT_BROADCASTS = (IOC_IN or IOC_VENDOR or 7); - {$EXTERNALSYM SIO_INDEX_BIND} - SIO_INDEX_BIND = (IOC_IN or IOC_VENDOR or 8); - {$EXTERNALSYM SIO_INDEX_MCASTIF} - SIO_INDEX_MCASTIF = (IOC_IN or IOC_VENDOR or 9); - {$EXTERNALSYM SIO_INDEX_ADD_MCAST} - SIO_INDEX_ADD_MCAST = (IOC_IN or IOC_VENDOR or 10); - {$EXTERNALSYM SIO_INDEX_DEL_MCAST} - SIO_INDEX_DEL_MCAST = (IOC_IN or IOC_VENDOR or 11); -// SIO_UDP_CONNRESET = _WSAIOW(IOC_VENDOR,12) - {$EXTERNALSYM SIO_RCVALL_MCAST_IF} - SIO_RCVALL_MCAST_IF = (IOC_IN or IOC_VENDOR or 13); - {$EXTERNALSYM SIO_RCVALL_IF} - SIO_RCVALL_IF = (IOC_IN or IOC_VENDOR or 14); - {$EXTERNALSYM SIO_LOOPBACK_FAST_PATH} - SIO_LOOPBACK_FAST_PATH = (IOC_IN or IOC_VENDOR or 16); - {$EXTERNALSYM SIO_TCP_INITIAL_RTO} - SIO_TCP_INITIAL_RTO = (IOC_IN or IOC_VENDOR or 17); - {$EXTERNALSYM SIO_APPLY_TRANSPORT_SETTING} - SIO_APPLY_TRANSPORT_SETTING = (IOC_IN or IOC_VENDOR or 19); - {$EXTERNALSYM SIO_QUERY_TRANSPORT_SETTING} - SIO_QUERY_TRANSPORT_SETTING = (IOC_IN or IOC_VENDOR or 20); -// -// Values for use with SIO_RCVALL* options -// - {$EXTERNALSYM RCVALL_MAX} - RCVALL_MAX = RCVALL_IPLEVEL; -// -// Parameters to configure the initial RTT. -// - {$EXTERNALSYM TCP_INITIAL_RTO_UNSPECIFIED_RTT} - TCP_INITIAL_RTO_UNSPECIFIED_RTT = USHORT(-1); - {$EXTERNALSYM TCP_INITIAL_RTO_UNSPECIFIED_MAX_SYN_RETRANSMISSIONS} - TCP_INITIAL_RTO_UNSPECIFIED_MAX_SYN_RETRANSMISSIONS = UCHAR(-1); - {$EXTERNALSYM TCP_INITIAL_RTO_DEFAULT_RTT} - TCP_INITIAL_RTO_DEFAULT_RTT = (0); - {$EXTERNALSYM TCP_INITIAL_RTO_DEFAULT_MAX_SYN_RETRANSMISSIONS} - TCP_INITIAL_RTO_DEFAULT_MAX_SYN_RETRANSMISSIONS = (0); - -// -// TCP/UDP port management definitions. -// - {$EXTERNALSYM SIO_ACQUIRE_PORT_RESERVATION} - SIO_ACQUIRE_PORT_RESERVATION = (IOC_IN or IOC_VENDOR or 100); - {$EXTERNALSYM SIO_RELEASE_PORT_RESERVATION} - SIO_RELEASE_PORT_RESERVATION = (IOC_IN or IOC_VENDOR or 101); - {$EXTERNALSYM SIO_ASSOCIATE_PORT_RESERVATION} - SIO_ASSOCIATE_PORT_RESERVATION = (IOC_IN or IOC_VENDOR or 102); - - {$EXTERNALSYM INVALID_PORT_RESERVATION_TOKEN} - INVALID_PORT_RESERVATION_TOKEN = ULONG64(0); - -// -// Secure socket API type definitions. -// - {$EXTERNALSYM SIO_SET_SECURITY} - SIO_SET_SECURITY = (IOC_IN or IOC_VENDOR or 200); - {$EXTERNALSYM SIO_QUERY_SECURITY} - SIO_QUERY_SECURITY = (IOC_INOUT or IOC_VENDOR or 201); - {$EXTERNALSYM SIO_SET_PEER_TARGET_NAME} - SIO_SET_PEER_TARGET_NAME = (IOC_IN or IOC_VENDOR or 202); - {$EXTERNALSYM SIO_DELETE_PEER_TARGET_NAME} - SIO_DELETE_PEER_TARGET_NAME = (IOC_IN or IOC_VENDOR or 203); - -// -// WFP Proxy Connection Tracking API type definitions. -// - {$EXTERNALSYM SIO_QUERY_WFP_CONNECTION_REDIRECT_RECORDS} - SIO_QUERY_WFP_CONNECTION_REDIRECT_RECORDS = (IOC_IN or IOC_VENDOR or 220); - {$EXTERNALSYM SIO_QUERY_WFP_CONNECTION_REDIRECT_CONTEXT} - SIO_QUERY_WFP_CONNECTION_REDIRECT_CONTEXT = (IOC_IN or IOC_VENDOR or 221); - {$EXTERNALSYM SIO_SET_WFP_CONNECTION_REDIRECT_RECORDS} - SIO_SET_WFP_CONNECTION_REDIRECT_RECORDS = (IOC_IN or IOC_VENDOR or 222); - - {$EXTERNALSYM SIO_SOCKET_USAGE_NOTIFICATION} - SIO_SOCKET_USAGE_NOTIFICATION = (IOC_IN or IOC_VENDOR or 204); -// Flags for generic security settings - {$EXTERNALSYM SOCKET_SETTINGS_GUARANTEE_ENCRYPTION} - SOCKET_SETTINGS_GUARANTEE_ENCRYPTION = $1; - {$EXTERNALSYM SOCKET_SETTINGS_ALLOW_INSECURE} - SOCKET_SETTINGS_ALLOW_INSECURE = $2; - -// Flags specific to IPsec security settings. -// NOTE: these flags must be specified under the -// SOCKET_SECURITY_SETTINGS_IPSEC->IpsecFlags field. - {$EXTERNALSYM SOCKET_SETTINGS_IPSEC_SKIP_FILTER_INSTANTIATION} - SOCKET_SETTINGS_IPSEC_SKIP_FILTER_INSTANTIATION = $1; - {$EXTERNALSYM SOCKET_SETTINGS_IPSEC_OPTIONAL_PEER_NAME_VERIFICATION} - SOCKET_SETTINGS_IPSEC_OPTIONAL_PEER_NAME_VERIFICATION = $2; - {$EXTERNALSYM SOCKET_SETTINGS_IPSEC_ALLOW_FIRST_INBOUND_PKT_UNENCRYPTED} - SOCKET_SETTINGS_IPSEC_ALLOW_FIRST_INBOUND_PKT_UNENCRYPTED = $4; - {$EXTERNALSYM SOCKET_SETTINGS_IPSEC_PEER_NAME_IS_RAW_FORMAT} - SOCKET_SETTINGS_IPSEC_PEER_NAME_IS_RAW_FORMAT = $8; - {$EXTERNALSYM SOCKET_QUERY_IPSEC2_ABORT_CONNECTION_ON_FIELD_CHANGE} - SOCKET_QUERY_IPSEC2_ABORT_CONNECTION_ON_FIELD_CHANGE = $1; - {$EXTERNALSYM SOCKET_QUERY_IPSEC2_FIELD_MASK_MM_SA_ID} - SOCKET_QUERY_IPSEC2_FIELD_MASK_MM_SA_ID = $1; - {$EXTERNALSYM SOCKET_QUERY_IPSEC2_FIELD_MASK_QM_SA_ID} - SOCKET_QUERY_IPSEC2_FIELD_MASK_QM_SA_ID = $2; -// Flags corresponding to the security query info - {$EXTERNALSYM SOCKET_INFO_CONNECTION_SECURED} - SOCKET_INFO_CONNECTION_SECURED = $1; - {$EXTERNALSYM SOCKET_INFO_CONNECTION_ENCRYPTED} - SOCKET_INFO_CONNECTION_ENCRYPTED = $2; - {$EXTERNALSYM SOCKET_INFO_CONNECTION_IMPERSONATED} - SOCKET_INFO_CONNECTION_IMPERSONATED = $4; -// -// WFP ALE endpoint handle query type definition -// - {$EXTERNALSYM SIO_QUERY_WFP_ALE_ENDPOINT_HANDLE} - SIO_QUERY_WFP_ALE_ENDPOINT_HANDLE = (IOC_OUT or IOC_VENDOR or 205); - // -// Scalability type definitions -// - {$EXTERNALSYM SIO_QUERY_RSS_SCALABILITY_INFO} - SIO_QUERY_RSS_SCALABILITY_INFO = (IOC_OUT or IOC_VENDOR or 210); -// GUID definition for use with Secure Sockets API -// aec2ef9c-3a4d-4d3e-8842-239942e39a47 - {$EXTERNALSYM SOCKET_DEFAULT2_QM_POLICY} - SOCKET_DEFAULT2_QM_POLICY : TGuid = (D1:$aec2ef9c;D2:$3a4d;D3:$4d3e;D4:($88,$42,$23,$99,$42,$e3,$9a,$47)); -// GUID definition for use with Real Time Notification setting API. -// 6b59819a-5cae-492d-a901-2a3c2c50164f - {$EXTERNALSYM REAL_TIME_NOTIFICATION_CAPABILITY)} - REAL_TIME_NOTIFICATION_CAPABILITY : TGuid = (D1:$6b59819a;D2:$5cae;D3:$492d;D4:($a9, $01, $2a, $3c, $2c, $50, $16, $4f)); - -// -// Microsoft-specific IPv4 definitions. -// - {$EXTERNALSYM IN4ADDR_ANY} - IN4ADDR_ANY = INADDR_ANY; - {$EXTERNALSYM IN4ADDR_LOOPBACK} - IN4ADDR_LOOPBACK = $0100007f; - {$EXTERNALSYM IN4ADDR_BROADCAST} - IN4ADDR_BROADCAST = INADDR_BROADCAST; - {$EXTERNALSYM IN4ADDR_NONE} - IN4ADDR_NONE = INADDR_NONE; - - {$EXTERNALSYM IN4ADDR_ANY_INIT} - function IN4ADDR_ANY_INIT: TInAddr; - {$EXTERNALSYM IN4ADDR_LOOPBACK_INIT} - function IN4ADDR_LOOPBACK_INIT: TInAddr; - {$EXTERNALSYM IN4ADDR_BROADCAST_INIT} - function IN4ADDR_BROADCAST_INIT: TInAddr; - {$EXTERNALSYM IN4ADDR_ALLNODESONLINK_INIT} - function IN4ADDR_ALLNODESONLINK_INIT: TInAddr; - {$EXTERNALSYM IN4ADDR_ALLROUTERSONLINK_INIT} - function IN4ADDR_ALLROUTERSONLINK_INIT: TInAddr; - {$EXTERNALSYM IN4ADDR_ALLIGMPV3ROUTERSONLINK_INIT} - function IN4ADDR_ALLIGMPV3ROUTERSONLINK_INIT: TInAddr; - {$EXTERNALSYM IN4ADDR_ALLTEREDONODESONLINK_INIT} - function IN4ADDR_ALLTEREDONODESONLINK_INIT: TInAddr; - {$EXTERNALSYM IN4ADDR_LINKLOCALPREFIX_INIT} - function IN4ADDR_LINKLOCALPREFIX_INIT: TInAddr; - {$EXTERNALSYM IN4ADDR_MULTICASTPREFIX_INIT} - function IN4ADDR_MULTICASTPREFIX_INIT: TInAddr; - -const - {$EXTERNALSYM IN4ADDR_LOOPBACKPREFIX_LENGTH} - IN4ADDR_LOOPBACKPREFIX_LENGTH = 8; - {$EXTERNALSYM IN4ADDR_LINKLOCALPREFIX_LENGTH} - IN4ADDR_LINKLOCALPREFIX_LENGTH = 16; - {$EXTERNALSYM IN4ADDR_MULTICASTPREFIX_LENGTH} - IN4ADDR_MULTICASTPREFIX_LENGTH = 4; - - {$EXTERNALSYM IN6ADDR_LINKLOCALPREFIX_LENGTH} - IN6ADDR_LINKLOCALPREFIX_LENGTH = 64; - {$EXTERNALSYM IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH} - IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH = 104; - {$EXTERNALSYM IN6ADDR_V4MAPPEDPREFIX_LENGTH} - IN6ADDR_V4MAPPEDPREFIX_LENGTH = 96; - {$EXTERNALSYM IN6ADDR_6TO4PREFIX_LENGTH} - IN6ADDR_6TO4PREFIX_LENGTH = 16; - {$EXTERNALSYM IN6ADDR_TEREDOPREFIX_LENGTH} - IN6ADDR_TEREDOPREFIX_LENGTH = 32; - -{$ENDIF} -//============================================================= -implementation -//============================================================= -{$IFDEF WINDOWS} -uses - IdResourceStrings - {$IFDEF HAS_AnsiStrings_StrLen}, AnsiStrings{$ENDIF} - ; - // (c) March 2001, "Alex Konshin" - -var - hWinSockDll : TIdLibHandle = IdNilHandle; // WS2_32.DLL handle - {$IFNDEF WINCE} - hMSWSockDll : TIdLibHandle = IdNilHandle; // MSWSOCK.DLL handle - {$ENDIF} - -function WinsockHandle : TIdLibHandle; -begin - Result := hWinSockDll; -end; - -function Winsock2Loaded : Boolean; -begin - Result := hWinSockDll <> IdNilHandle; -end; - -procedure InitializeWinSock; -var - LData: TWSAData; - LError: DWORD; -begin - if hWinSockDll = IdNilHandle then begin - hWinSockDll := SafeLoadLibrary(WINSOCK2_DLL); - if hWinSockDll <> IdNilHandle then begin - LError := WSAStartup($202, LData); - if LError = 0 then begin - Exit; - end; - Windows.FreeLibrary(hWinSockDll); - hWinSockDll := IdNilHandle; - end else begin - LError := Windows.GetLastError; - end; - raise EIdWinsockStubError.Build(LError, RSWinsockLoadError, [WINSOCK2_DLL]); - end; -end; - -{$IFNDEF WINCE} -procedure LoadMSWSock; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if hMSWSockDll = IdNilHandle then begin - hMSWSockDll := SafeLoadLibrary(MSWSOCK_DLL); - if hMSWSockDll = IdNilHandle then begin - raise EIdWinsockStubError.Build(Windows.GetLastError, RSWinsockLoadError, [MSWSOCK_DLL]); - end; - end; -end; -{$ENDIF} - -procedure UninitializeWinSock; -begin -{$IFNDEF WINCE} - if hMSWSockDll <> IdNilHandle then - begin - FreeLibrary(hMSWSockDll); - hMSWSockDll := IdNilHandle; - end; -{$ENDIF} - if hWinSockDll <> IdNilHandle then - begin - WSACleanup; - FreeLibrary(hWinSockDll); - hWinSockDll := IdNilHandle; - end; -end; - -constructor EIdWinsockStubError.Build(AWin32Error: DWORD; const ATitle: String; AArgs: array of const); -begin - FTitle := IndyFormat(ATitle, AArgs); - FWin32Error := AWin32Error; - if AWin32Error = 0 then begin - inherited Create(FTitle); - end else - begin - FWin32ErrorMessage := SysUtils.SysErrorMessage(AWin32Error); - inherited Create(FTitle + ': ' + FWin32ErrorMessage); {Do not Localize} - end; -end; - -function FixupStub(hDll: TIdLibHandle; const AName: TIdLibFuncName): Pointer; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if hDll = IdNilHandle then begin - raise EIdWinsockStubError.Build(WSANOTINITIALISED, RSWinsockCallError, [AName]); - end; - Result := LoadLibFunction(hDll, AName); - if Result = nil then begin - raise EIdWinsockStubError.Build(WSAEINVAL, RSWinsockCallError, [AName]); - end; -end; - -function FixupStubEx(hSocket: TSocket; const AName: string; const AGuid: TGUID): Pointer; -var - LBytesSend: DWORD; -begin - // RLebeau: in XE4+, PDWORD is NOT defined as ^DWORD, so we have to use a type-cast! - if WSAIoctl(hSocket, SIO_GET_EXTENSION_FUNCTION_POINTER, @AGuid, DWORD(SIZE_GUID), - @Result, SIZE_FARPROC, PDWORD(@LBytesSend), nil, nil) <> 0 then - begin - raise EIdWinsockStubError.Build(WSAGetLastError, RSWinsockCallError, [AName]); - end; -end; - -function Stub_WSAStartup(const wVersionRequired: word; out WSData: TWSAData): Integer; stdcall; -begin - @WSAStartup := FixupStub(hWinSockDll, 'WSAStartup'); {Do not Localize} - Result := WSAStartup(wVersionRequired, WSData); -end; - -function Stub_WSACleanup: Integer; stdcall; -begin - @WSACleanup := FixupStub(hWinSockDll, 'WSACleanup'); {Do not Localize} - Result := WSACleanup; -end; - -function Stub_accept(const s: TSocket; AAddr: PSockAddr; addrlen: PInteger): TSocket; stdcall; -begin - @accept := FixupStub(hWinSockDll, 'accept'); {Do not Localize} - Result := accept(s, AAddr, addrlen); -end; - -function Stub_bind(const s: TSocket; const name: PSockAddr; const namelen: Integer): Integer; stdcall; -begin - @bind := FixupStub(hWinSockDll, 'bind'); {Do not Localize} - Result := bind(s, name, namelen); -end; - -function Stub_closesocket(const s: TSocket): Integer; stdcall; -begin - @closesocket := FixupStub(hWinSockDll, 'closesocket'); {Do not Localize} - Result := closesocket(s); -end; - -function Stub_connect(const s: TSocket; const name: PSockAddr; const namelen: Integer): Integer; stdcall; -begin - @connect := FixupStub(hWinSockDll, 'connect'); {Do not Localize} - Result := connect(s, name, namelen); -end; - -function Stub_ioctlsocket(const s: TSocket; const cmd: DWORD; var arg: u_long): Integer; stdcall; -begin - @ioctlsocket := FixupStub(hWinSockDll, 'ioctlsocket'); {Do not Localize} - Result := ioctlsocket(s, cmd, arg); -end; - -function Stub_getpeername(const s: TSocket; const name: PSockAddr; var namelen: Integer): Integer; stdcall; -begin - @getpeername := FixupStub(hWinSockDll, 'getpeername'); {Do not Localize} - Result := getpeername(s, name, namelen); -end; - -function Stub_getsockname(const s: TSocket; const name: PSockAddr; var namelen: Integer): Integer; stdcall; -begin - @getsockname := FixupStub(hWinSockDll, 'getsockname'); {Do not Localize} - Result := getsockname(s, name, namelen); -end; - -function Stub_getsockopt(const s: TSocket; const level, optname: Integer; optval: PIdAnsiChar; var optlen: Integer): Integer; stdcall; -begin - @getsockopt := FixupStub(hWinSockDll, 'getsockopt'); {Do not Localize} - Result := getsockopt(s, level, optname, optval, optlen); -end; - -function Stub_htonl(hostlong: u_long): u_long; stdcall; -begin - @htonl := FixupStub(hWinSockDll, 'htonl'); {Do not Localize} - Result := htonl(hostlong); -end; - -function Stub_htons(hostshort: u_short): u_short; stdcall; -begin - @htons := FixupStub(hWinSockDll, 'htons'); {Do not Localize} - Result := htons(hostshort); -end; - -function Stub_inet_addr(cp: PIdAnsiChar): u_long; stdcall; -begin - @inet_addr := FixupStub(hWinSockDll, 'inet_addr'); {Do not Localize} - Result := inet_addr(cp); -end; - -function Stub_inet_ntoa(inaddr: TInAddr): PIdAnsiChar; stdcall; -begin - @inet_ntoa := FixupStub(hWinSockDll, 'inet_ntoa'); {Do not Localize} - Result := inet_ntoa(inaddr); -end; - -function Stub_listen(const s: TSocket; backlog: Integer): Integer; stdcall; -begin - @listen := FixupStub(hWinSockDll, 'listen'); {Do not Localize} - Result := listen(s, backlog); -end; - -function Stub_ntohl(netlong: u_long): u_long; stdcall; -begin - @ntohl := FixupStub(hWinSockDll, 'ntohl'); {Do not Localize} - Result := ntohl(netlong); -end; - -function Stub_ntohs(netshort: u_short): u_short; stdcall; -begin - @ntohs := FixupStub(hWinSockDll, 'ntohs'); {Do not Localize} - Result := ntohs(netshort); -end; - -function Stub_recv(const s: TSocket; var Buf; len, flags: Integer): Integer; stdcall; -begin - @recv := FixupStub(hWinSockDll, 'recv'); {Do not Localize} - Result := recv(s, Buf, len, flags); -end; - -function Stub_recvfrom(const s: TSocket; var Buf; len, flags: Integer; from: PSockAddr; fromlen: PInteger): Integer; stdcall; -begin - @recvfrom := FixupStub(hWinSockDll, 'recvfrom'); {Do not Localize} - Result := recvfrom(s, Buf, len, flags, from, fromlen); -end; - -function Stub_select(nfds: Integer; readfds, writefds, exceptfds: PFDSet; timeout: PTimeVal): Integer; stdcall; -begin - @select := FixupStub(hWinSockDll, 'select'); {Do not Localize} - Result := select(nfds, readfds, writefds, exceptfds, timeout); -end; - -function Stub_send(const s: TSocket; const Buf; len, flags: Integer): Integer; stdcall; -begin - @send := FixupStub(hWinSockDll, 'send'); {Do not Localize} - Result := send(s, Buf, len, flags); -end; - -function Stub_sendto(const s: TSocket; const Buf; const len, flags: Integer; const addrto: PSockAddr; const tolen: Integer): Integer; stdcall; -begin - @sendto := FixupStub(hWinSockDll, 'sendto'); {Do not Localize} - Result := sendto(s, Buf, len, flags, addrto, tolen); -end; - -function Stub_setsockopt(const s: TSocket; const level, optname: Integer; optval: PIdAnsiChar; const optlen: Integer): Integer; stdcall; -begin - @setsockopt := FixupStub(hWinSockDll, 'setsockopt'); {Do not Localize} - Result := setsockopt(s, level, optname, optval, optlen); -end; - -function Stub_shutdown(const s: TSocket; const how: Integer): Integer; stdcall; -begin - @shutdown := FixupStub(hWinSockDll, 'shutdown'); {Do not Localize} - Result := shutdown(s, how); -end; - -function Stub_socket(const af, istruct, protocol: Integer): TSocket; stdcall; -begin - @socket := FixupStub(hWinSockDll, 'socket'); {Do not Localize} - Result := socket(af, istruct, protocol); -end; - -function Stub_gethostbyaddr(AAddr: Pointer; const len, addrtype: Integer): PHostEnt; stdcall; -begin - @gethostbyaddr := FixupStub(hWinSockDll, 'gethostbyaddr'); {Do not Localize} - Result := gethostbyaddr(AAddr, len, addrtype); -end; - -function Stub_gethostbyname(name: PIdAnsiChar): PHostEnt; stdcall; -begin - @gethostbyname := FixupStub(hWinSockDll, 'gethostbyname'); {Do not Localize} - Result := gethostbyname(name); -end; - -{$IFDEF WINCE} -function Stub_sethostname(pName : PIdAnsiChar; cName : Integer) : Integer; stdcall; -begin - @sethostname := FixupStub(hWinSockDll, 'sethostname'); {Do not Localize} - Result := sethostname(pName, cName); -end; -{$ENDIF} - -function Stub_gethostname(name: PIdAnsiChar; len: Integer): Integer; stdcall; -begin - @gethostname := FixupStub(hWinSockDll, 'gethostname'); {Do not Localize} - Result := gethostname(name, len); -end; - -function Stub_getservbyport(const port: Integer; const proto: PIdAnsiChar): PServEnt; stdcall; -begin - @getservbyport := FixupStub(hWinSockDll, 'getservbyport'); {Do not Localize} - Result := getservbyport(port, proto); -end; - -function Stub_getservbyname(const name, proto: PIdAnsiChar): PServEnt; stdcall; -begin - @getservbyname := FixupStub(hWinSockDll, 'getservbyname'); {Do not Localize} - Result := getservbyname(name, proto); -end; - -function Stub_getprotobynumber(const proto: Integer): PProtoEnt; stdcall; -begin - @getprotobynumber := FixupStub(hWinSockDll, 'getprotobynumber'); {Do not Localize} - Result := getprotobynumber(proto); -end; - -function Stub_getprotobyname(const name: PIdAnsiChar): PProtoEnt; stdcall; -begin - @getprotobyname := FixupStub(hWinSockDll, 'getprotobyname'); {Do not Localize} - Result := getprotobyname(name); -end; - -procedure Stub_WSASetLastError(const iError: Integer); stdcall; -begin - @WSASetLastError := FixupStub(hWinSockDll, 'WSASetLastError'); {Do not Localize} - WSASetLastError(iError); -end; - -function Stub_WSAGetLastError: Integer; stdcall; -begin - @WSAGetLastError := FixupStub(hWinSockDll, 'WSAGetLastError'); {Do not Localize} - Result := WSAGetLastError; -end; - -{$IFNDEF WINCE} -function Stub_WSAIsBlocking: BOOL; stdcall; -begin - @WSAIsBlocking := FixupStub(hWinSockDll, 'WSAIsBlocking'); {Do not Localize} - Result := WSAIsBlocking; -end; - -function Stub_WSAUnhookBlockingHook: Integer; stdcall; -begin - @WSAUnhookBlockingHook := FixupStub(hWinSockDll, 'WSAUnhookBlockingHook'); {Do not Localize} - Result := WSAUnhookBlockingHook; -end; - -function Stub_WSASetBlockingHook(lpBlockFunc: TFarProc): TFarProc; stdcall; -begin - @WSASetBlockingHook := FixupStub(hWinSockDll, 'WSASetBlockingHook'); {Do not Localize} - Result := WSASetBlockingHook(lpBlockFunc); -end; - -function Stub_WSACancelBlockingCall: Integer; stdcall; -begin - @WSACancelBlockingCall := FixupStub(hWinSockDll, 'WSACancelBlockingCall'); {Do not Localize} - Result := WSACancelBlockingCall; -end; - -function Stub_WSAAsyncGetServByName(HWindow: HWND; wMsg: u_int; name, proto, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; -begin - @WSAAsyncGetServByName := FixupStub(hWinSockDll, 'WSAAsyncGetServByName'); {Do not Localize} - Result := WSAAsyncGetServByName(HWindow, wMsg, name, proto, buf, buflen); -end; - -function Stub_WSAAsyncGetServByPort(HWindow: HWND; wMsg, port: u_int; proto, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; -begin - @WSAAsyncGetServByPort := FixupStub(hWinSockDll, 'WSAAsyncGetServByPort'); {Do not Localize} - Result := WSAAsyncGetServByPort(HWindow, wMsg, port, proto, buf, buflen); -end; - -function Stub_WSAAsyncGetProtoByName(HWindow: HWND; wMsg: u_int; name, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; -begin - @WSAAsyncGetProtoByName := FixupStub(hWinSockDll, 'WSAAsyncGetProtoByName'); {Do not Localize} - Result := WSAAsyncGetProtoByName(HWindow, wMsg, name, buf, buflen); -end; - -function Stub_WSAAsyncGetProtoByNumber(HWindow: HWND; wMsg: u_int; number: Integer; buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; -begin - @WSAAsyncGetProtoByNumber := FixupStub(hWinSockDll, 'WSAAsyncGetProtoByNumber'); {Do not Localize} - Result := WSAAsyncGetProtoByNumber(HWindow, wMsg, number, buf, buflen); -end; - -function Stub_WSAAsyncGetHostByName(HWindow: HWND; wMsg: u_int; name, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; -begin - @WSAAsyncGetHostByName := FixupStub(hWinSockDll, 'WSAAsyncGetHostByName'); {Do not Localize} - Result := WSAAsyncGetHostByName(HWindow, wMsg, name, buf, buflen); -end; - -function Stub_WSAAsyncGetHostByAddr(HWindow: HWND; wMsg: u_int; AAddr: PIdAnsiChar; len, istruct: Integer; buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; -begin - @WSAAsyncGetHostByAddr := FixupStub(hWinSockDll, 'WSAAsyncGetHostByAddr'); {Do not Localize} - Result := WSAAsyncGetHostByAddr(HWindow, wMsg, AAddr, len, istruct, buf, buflen); -end; - -function Stub_WSACancelAsyncRequest(hAsyncTaskHandle: THandle): Integer; stdcall; -begin - @WSACancelAsyncRequest := FixupStub(hWinSockDll, 'WSACancelAsyncRequest'); {Do not Localize} - Result := WSACancelAsyncRequest(hAsyncTaskHandle); -end; - -function Stub_WSAAsyncSelect(const s: TSocket; HWindow: HWND; wMsg: u_int; lEvent: Longint): Integer; stdcall; -begin - @WSAAsyncSelect := FixupStub(hWinSockDll, 'WSAAsyncSelect'); {Do not Localize} - Result := WSAAsyncSelect(s, HWindow, wMsg, lEvent); -end; -{$ENDIF} - -function Stub___WSAFDIsSet(const s: TSocket; var FDSet: TFDSet): Bool; stdcall; -begin - @__WSAFDIsSet := FixupStub(hWinSockDll, '__WSAFDIsSet'); {Do not Localize} - Result := __WSAFDIsSet(s, FDSet); -end; - -function Stub_WSAAccept(const s: TSocket; AAddr: PSockAddr; addrlen: PInteger; lpfnCondition: LPCONDITIONPROC; const dwCallbackData: DWORD): TSocket; stdcall; -begin - @WSAAccept := FixupStub(hWinSockDll, 'WSAAccept'); {Do not Localize} - Result := WSAAccept(s, AAddr, addrlen, lpfnCondition, dwCallbackData); -end; - -function Stub_WSACloseEvent(const hEvent: wsaevent): WordBool; stdcall; -begin - @WSACloseEvent := FixupStub(hWinSockDll, 'WSACloseEvent'); {Do not Localize} - Result := WSACloseEvent(hEvent); -end; - -function Stub_WSAConnect(const s: TSocket; const name: PSockAddr; const namelen: Integer; lpCallerData, lpCalleeData: LPWSABUF; lpSQOS, lpGQOS: LPQOS): Integer; stdcall; -begin - @WSAConnect := FixupStub(hWinSockDll, 'WSAConnect'); {Do not Localize} - Result := WSAConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS); -end; - -function Stub_WSACreateEvent: wsaevent; stdcall; -begin - @WSACreateEvent := FixupStub(hWinSockDll, 'WSACreateEvent'); {Do not Localize} - Result := WSACreateEvent; -end; - -{$IFNDEF WINCE} -function Stub_WSADuplicateSocketA(const s: TSocket; const dwProcessId: DWORD; lpProtocolInfo: LPWSAPROTOCOL_INFOA): Integer; stdcall; -begin - @WSADuplicateSocketA := FixupStub(hWinSockDll, 'WSADuplicateSocketA'); {Do not Localize} - Result := WSADuplicateSocketA(s, dwProcessId, lpProtocolInfo); -end; - -function Stub_WSADuplicateSocketW(const s: TSocket; const dwProcessId: DWORD; lpProtocolInfo: LPWSAPROTOCOL_INFOW): Integer; stdcall; -begin - @WSADuplicateSocketW := FixupStub(hWinSockDll, 'WSADuplicateSocketW'); {Do not Localize} - Result := WSADuplicateSocketW(s, dwProcessId, lpProtocolInfo); -end; - -function Stub_WSADuplicateSocket(const s: TSocket; const dwProcessId: DWORD; lpProtocolInfo: LPWSAPROTOCOL_INFO): Integer; stdcall; -begin - {$IFDEF UNICODE} - @WSADuplicateSocket := FixupStub(hWinSockDll, 'WSADuplicateSocketW'); {Do not Localize} - {$ELSE} - @WSADuplicateSocket := FixupStub(hWinSockDll, 'WSADuplicateSocketA'); {Do not Localize} - {$ENDIF} - Result := WSADuplicateSocket(s, dwProcessId, lpProtocolInfo); -end; -{$ENDIF} - -function Stub_WSAEnumNetworkEvents(const s: TSocket; const hEventObject: WSAEVENT; lpNetworkEvents: LPWSANETWORKEVENTS): Integer; stdcall; -begin - @WSAEnumNetworkEvents := FixupStub(hWinSockDll, 'WSAEnumNetworkEvents'); {Do not Localize} - Result := WSAEnumNetworkEvents(s, hEventObject, lpNetworkEvents); -end; - -function Stub_WSAEnumProtocolsA(lpiProtocols: PInteger; lpProtocolBuffer: LPWSAPROTOCOL_INFOA; var lpdwBufferLength: DWORD): Integer; stdcall; -begin - @WSAEnumProtocolsA := FixupStub(hWinSockDll, 'WSAEnumProtocolsA'); {Do not Localize} - Result := WSAEnumProtocolsA(lpiProtocols, lpProtocolBuffer, lpdwBufferLength); -end; - -function Stub_WSAEnumProtocolsW(lpiProtocols: PInteger; lpProtocolBuffer: LPWSAPROTOCOL_INFOW; var lpdwBufferLength: DWORD): Integer; stdcall; -begin - @WSAEnumProtocolsW := FixupStub(hWinSockDll, 'WSAEnumProtocolsW'); {Do not Localize} - Result := WSAEnumProtocolsW(lpiProtocols, lpProtocolBuffer, lpdwBufferLength); -end; - -function Stub_WSAEnumProtocols(lpiProtocols: PInteger; lpProtocolBuffer: LPWSAPROTOCOL_INFO; var lpdwBufferLength: DWORD): Integer; stdcall; -begin - {$IFDEF UNICODE} - @WSAEnumProtocols := FixupStub(hWinSockDll, 'WSAEnumProtocolsW'); {Do not Localize} - {$ELSE} - @WSAEnumProtocols := FixupStub(hWinSockDll, 'WSAEnumProtocolsA'); {Do not Localize} - {$ENDIF} - Result := WSAEnumProtocols(lpiProtocols, lpProtocolBuffer, lpdwBufferLength); -end; - -function Stub_WSAEventSelect(const s: TSocket; const hEventObject: WSAEVENT; lNetworkEvents: LongInt): Integer; stdcall; -begin - @WSAEventSelect := FixupStub(hWinSockDll, 'WSAEventSelect'); {Do not Localize} - Result := WSAEventSelect(s, hEventObject, lNetworkEvents); -end; - -function Stub_WSAGetOverlappedResult(const s: TSocket; AOverlapped: Pointer; lpcbTransfer: LPDWORD; fWait: BOOL; var lpdwFlags: DWORD): WordBool; stdcall; -begin - @WSAGetOverlappedResult := FixupStub(hWinSockDll, 'WSAGetOverlappedResult'); {Do not Localize} - Result := WSAGetOverlappedResult(s, AOverlapped, lpcbTransfer, fWait, lpdwFlags); -end; - -{$IFNDEF WINCE} -function Stub_WSAGetQOSByName(const s: TSocket; lpQOSName: LPWSABUF; lpQOS: LPQOS): WordBool; stdcall; -begin - @WSAGetQOSByName := FixupStub(hWinSockDll, 'WSAGetQOSByName'); {Do not Localize} - Result := WSAGetQOSByName(s, lpQOSName, lpQOS); -end; -{$ENDIF} - -function Stub_WSAHtonl(const s: TSocket; hostlong: u_long; var lpnetlong: DWORD): Integer; stdcall; -begin - @WSAHtonl := FixupStub(hWinSockDll, 'WSAHtonl'); {Do not Localize} - Result := WSAHtonl(s, hostlong, lpnetlong); -end; - -function Stub_WSAHtons(const s: TSocket; hostshort: u_short; var lpnetshort: WORD): Integer; stdcall; -begin - @WSAHtons := FixupStub(hWinSockDll, 'WSAHtons'); {Do not Localize} - Result := WSAHtons(s, hostshort, lpnetshort); -end; - -function Stub_WSAIoctl(const s: TSocket; dwIoControlCode: DWORD; lpvInBuffer: Pointer; cbInBuffer: DWORD; lpvOutBuffer: Pointer; cbOutBuffer: DWORD; lpcbBytesReturned: LPDWORD; AOverlapped: Pointer; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; -begin - @WSAIoctl := FixupStub(hWinSockDll, 'WSAIoctl'); {Do not Localize} - Result := WSAIoctl(s, dwIoControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, AOverlapped, lpCompletionRoutine); -end; - -function Stub_WSAJoinLeaf(const s: TSocket; name: PSockAddr; namelen: Integer; lpCallerData, lpCalleeData: LPWSABUF; lpSQOS, lpGQOS: LPQOS; dwFlags: DWORD): TSocket; stdcall; -begin - @WSAJoinLeaf := FixupStub(hWinSockDll, 'WSAJoinLeaf'); {Do not Localize} - Result := WSAJoinLeaf(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, dwFlags); -end; - -function Stub_WSANtohl(const s: TSocket; netlong: u_long; var lphostlong: DWORD): Integer; stdcall; -begin - @WSANtohl := FixupStub(hWinSockDll, 'WSANtohl'); {Do not Localize} - Result := WSANtohl(s, netlong, lphostlong); -end; - -function Stub_WSANtohs(const s: TSocket; netshort: u_short; var lphostshort: WORD): Integer; stdcall; -begin - @WSANtohs := FixupStub(hWinSockDll, 'WSANtohs'); {Do not Localize} - Result := WSANtohs(s, netshort, lphostshort); -end; - -function Stub_WSARecv(const s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD; var lpNumberOfBytesRecvd: DWORD; var lpFlags: DWORD; AOverlapped: LPWSAOVERLAPPED; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; -begin - @WSARecv := FixupStub(hWinSockDll, 'WSARecv'); {Do not Localize} - Result := WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, AOverlapped, lpCompletionRoutine); -end; - -function Stub_WSARecvDisconnect(const s: TSocket; lpInboundDisconnectData: LPWSABUF): Integer; stdcall; -begin - @WSARecvDisconnect := FixupStub(hWinSockDll, 'WSARecvDisconnect'); {Do not Localize} - Result := WSARecvDisconnect(s, lpInboundDisconnectData); -end; - -function Stub_WSARecvFrom(const s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD; var lpNumberOfBytesRecvd: DWORD; var lpFlags: DWORD; lpFrom: PSockAddr; lpFromlen: PInteger; AOverlapped: Pointer; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; -begin - @WSARecvFrom := FixupStub(hWinSockDll, 'WSARecvFrom'); {Do not Localize} - Result := WSARecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, AOverlapped, lpCompletionRoutine); -end; - -function Stub_WSAResetEvent(hEvent: wsaevent): WordBool; stdcall; -begin - @WSAResetEvent := FixupStub(hWinSockDll, 'WSAResetEvent'); {Do not Localize} - Result := WSAResetEvent(hEvent); -end; - -function Stub_WSASend(const s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD; var lpNumberOfBytesSent: DWORD; dwFlags: DWORD; AOverlapped: LPWSAOVERLAPPED; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; -begin - @WSASend := FixupStub(hWinSockDll, 'WSASend'); {Do not Localize} - Result := WSASend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, AOverlapped, lpCompletionRoutine); -end; - -{$IFNDEF WINCE} -function Stub_WSASendDisconnect(const s: TSocket; lpOutboundDisconnectData: LPWSABUF): Integer; stdcall; -begin - @WSASendDisconnect := FixupStub(hWinSockDll, 'WSASendDisconnect'); {Do not Localize} - Result := WSASendDisconnect(s, lpOutboundDisconnectData); -end; -{$ENDIF} - -function Stub_WSASendTo(const s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD; var lpNumberOfBytesSent: DWORD; dwFlags: DWORD; lpTo: PSOCKADDR; iTolen: Integer; AOverlapped: LPWSAOVERLAPPED; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; -begin - @WSASendTo := FixupStub(hWinSockDll, 'WSASendTo'); {Do not Localize} - Result := WSASendTo(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpTo, iTolen, AOverlapped, lpCompletionRoutine); -end; - -function Stub_WSASetEvent(hEvent: WSAEVENT): WordBool; stdcall; -begin - @WSASetEvent := FixupStub(hWinSockDll, 'WSASetEvent'); {Do not Localize} - Result := WSASetEvent(hEvent); -end; - -function Stub_WSASocketA(af, iType, protocol: Integer; lpProtocolInfo: LPWSAPROTOCOL_INFOA; g: GROUP; dwFlags: DWORD): TSocket; stdcall; -begin - @WSASocketA := FixupStub(hWinSockDll, 'WSASocketA'); {Do not Localize} - Result := WSASocketA(af, iType, protocol, lpProtocolInfo, g, dwFlags); -end; - -function Stub_WSASocketW(af, iType, protocol: Integer; lpProtocolInfo: LPWSAPROTOCOL_INFOW; g: GROUP; dwFlags: DWORD): TSocket; stdcall; -begin - @WSASocketW := FixupStub(hWinSockDll, 'WSASocketW'); {Do not Localize} - Result := WSASocketW(af, iType, protocol, lpProtocolInfo, g, dwFlags); -end; - -function Stub_WSASocket(af, iType, protocol: Integer; lpProtocolInfo: LPWSAPROTOCOL_INFO; g: GROUP; dwFlags: DWORD): TSocket; stdcall; -begin - {$IFDEF UNICODE} - @WSASocket := FixupStub(hWinSockDll, 'WSASocketW'); {Do not Localize} - {$ELSE} - @WSASocket := FixupStub(hWinSockDll, 'WSASocketA'); {Do not Localize} - {$ENDIF} - Result := WSASocket(af, iType, protocol, lpProtocolInfo, g, dwFlags); -end; - -function Stub_WSAWaitForMultipleEvents(cEvents: DWORD; lphEvents: Pwsaevent; fWaitAll: LongBool; dwTimeout: DWORD; fAlertable: LongBool): DWORD; stdcall; -begin - @WSAWaitForMultipleEvents := FixupStub(hWinSockDll, 'WSAWaitForMultipleEvents'); {Do not Localize} - Result := WSAWaitForMultipleEvents(cEvents, lphEvents, fWaitAll, dwTimeout, fAlertable); -end; - -function Stub_WSAAddressToStringA(lpsaAddress: PSockAddr; const dwAddressLength: DWORD; const lpProtocolInfo: LPWSAPROTOCOL_INFOA; const lpszAddressString: PIdAnsiChar; var lpdwAddressStringLength: DWORD): Integer; stdcall; -begin - @WSAAddressToStringA := FixupStub(hWinSockDll, 'WSAAddressToStringA'); {Do not Localize} - Result := WSAAddressToStringA(lpsaAddress, dwAddressLength, lpProtocolInfo, lpszAddressString, lpdwAddressStringLength); -end; - -function Stub_WSAAddressToStringW(lpsaAddress: PSockAddr; const dwAddressLength: DWORD; const lpProtocolInfo: LPWSAPROTOCOL_INFOW; const lpszAddressString: PWideChar; var lpdwAddressStringLength: DWORD): Integer; stdcall; -begin - @WSAAddressToStringW := FixupStub(hWinSockDll, 'WSAAddressToStringW'); {Do not Localize} - Result := WSAAddressToStringW(lpsaAddress, dwAddressLength, lpProtocolInfo, lpszAddressString, lpdwAddressStringLength); -end; - -function Stub_WSAAddressToString(lpsaAddress: PSockAddr; const dwAddressLength: DWORD; const lpProtocolInfo: LPWSAPROTOCOL_INFO; - const lpszAddressString: PIdPlatformChar; var lpdwAddressStringLength: DWORD): Integer; stdcall; -begin - {$IFDEF UNICODE} - @WSAAddressToString := FixupStub(hWinSockDll, 'WSAAddressToStringW'); {Do not Localize} - {$ELSE} - @WSAAddressToString := FixupStub(hWinSockDll, 'WSAAddressToStringA'); {Do not Localize} - {$ENDIF} - Result := WSAAddressToString(lpsaAddress, dwAddressLength, lpProtocolInfo, lpszAddressString, lpdwAddressStringLength); -end; - -function Stub_WSAStringToAddressA(const AddressString: PIdAnsiChar; const AddressFamily: Integer; const lpProtocolInfo: LPWSAPROTOCOL_INFOA; var lpAddress: TSockAddr; var lpAddressLength: Integer): Integer; stdcall; -begin - @WSAStringToAddressA := FixupStub(hWinSockDll, 'WSAStringToAddressA'); {Do not Localize} - Result := WSAStringToAddressA(AddressString, AddressFamily, lpProtocolInfo, lpAddress, lpAddressLength); -end; - -function Stub_WSAStringToAddressW(const AddressString: PWideChar; const AddressFamily: Integer; const lpProtocolInfo: LPWSAPROTOCOL_INFOW; var lpAddress: TSockAddr; var lpAddressLength: Integer): Integer; stdcall; -begin - @WSAStringToAddressW := FixupStub(hWinSockDll, 'WSAStringToAddressW'); {Do not Localize} - Result := WSAStringToAddressW(AddressString, AddressFamily, lpProtocolInfo, lpAddress, lpAddressLength); -end; - -function Stub_WSAStringToAddress (const AddressString: PIdPlatformChar; - const AddressFamily: Integer; const lpProtocolInfo: LPWSAProtocol_Info; - var lpAddress: TSockAddr; var lpAddressLength: Integer): Integer; stdcall; -begin - {$IFDEF UNICODE} - @WSAStringToAddress := FixupStub(hWinSockDll, 'WSAStringToAddressW'); {Do not Localize} - {$ELSE} - @WSAStringToAddress := FixupStub(hWinSockDll, 'WSAStringToAddressA'); {Do not Localize} - {$ENDIF} - Result := WSAStringToAddress(AddressString, AddressFamily, lpProtocolInfo, lpAddress, lpAddressLength); -end; - -function Stub_WSALookupServiceBeginA(var qsRestrictions: TWSAQuerySetA; const dwControlFlags: DWORD; var hLookup: THandle): Integer; stdcall; -begin - @WSALookupServiceBeginA := FixupStub(hWinSockDll, 'WSALookupServiceBeginA'); {Do not Localize} - Result := WSALookupServiceBeginA(qsRestrictions, dwControlFlags, hLookup); -end; - -function Stub_WSALookupServiceBeginW(var qsRestrictions: TWSAQuerySetW; const dwControlFlags: DWORD; var hLookup: THandle): Integer; stdcall; -begin - @WSALookupServiceBeginW := FixupStub(hWinSockDll, 'WSALookupServiceBeginW'); {Do not Localize} - Result := WSALookupServiceBeginW(qsRestrictions, dwControlFlags, hLookup); -end; - -function Stub_WSALookupServiceBegin(var qsRestrictions: TWSAQuerySet; const dwControlFlags: DWORD; var hLookup: THandle): Integer; stdcall; -begin - {$IFDEF UNICODE} - @WSALookupServiceBegin := FixupStub(hWinSockDll, 'WSALookupServiceBeginW'); {Do not Localize} - {$ELSE} - @WSALookupServiceBegin := FixupStub(hWinSockDll, 'WSALookupServiceBeginA'); {Do not Localize} - {$ENDIF} - Result := WSALookupServiceBegin(qsRestrictions, dwControlFlags, hLookup); -end; - -function Stub_WSALookupServiceNextA(const hLookup: THandle; const dwControlFlags: DWORD; var dwBufferLength: DWORD; lpqsResults: LPWSAQUERYSETA): Integer; stdcall; -begin - @WSALookupServiceNextA := FixupStub(hWinSockDll, 'WSALookupServiceNextA'); {Do not Localize} - Result := WSALookupServiceNextA(hLookup, dwControlFlags, dwBufferLength, lpqsResults); -end; - -function Stub_WSALookupServiceNextW(const hLookup: THandle; const dwControlFlags: DWORD; var dwBufferLength: DWORD; lpqsResults: LPWSAQUERYSETW): Integer; stdcall; -begin - @WSALookupServiceNextW := FixupStub(hWinSockDll, 'WSALookupServiceNextW'); {Do not Localize} - Result := WSALookupServiceNextW(hLookup, dwControlFlags, dwBufferLength, lpqsResults); -end; - -function Stub_WSALookupServiceNext(const hLookup: THandle; const dwControlFlags: DWORD; var dwBufferLength: DWORD; lpqsResults: LPWSAQUERYSET): Integer; stdcall; -begin - {$IFDEF UNICODE} - @WSALookupServiceNext := FixupStub(hWinSockDll, 'WSALookupServiceNextW'); {Do not Localize} - {$ELSE} - @WSALookupServiceNext := FixupStub(hWinSockDll, 'WSALookupServiceNextA'); {Do not Localize} - {$ENDIF} - Result := WSALookupServiceNext(hLookup, dwControlFlags, dwBufferLength, lpqsResults); -end; - -function Stub_WSALookupServiceEnd(const hLookup: THandle): Integer; stdcall; -begin - @WSALookupServiceEnd := FixupStub(hWinSockDll, 'WSALookupServiceEnd'); {Do not Localize} - Result := WSALookupServiceEnd(hLookup); -end; - - -function Stub_WSANSPIoctl(const hLookup : THANDLE; const dwControlCode : DWORD; - lpvInBuffer : Pointer; var cbInBuffer : DWORD; lpvOutBuffer : Pointer; - var cbOutBuffer : DWORD; var lpcbBytesReturned : DWORD; - lpCompletion : LPWSACOMPLETION) : Integer; stdcall; -begin - @WSANSPIoctl := FixupStub(hWinSockDLL, 'WSANSPIoctl'); {Do not Localize} - Result := WSANSPIoctl(hLookup,dwControlCode,lpvInBuffer,cbInBuffer,lpvOutBuffer, - cbOutBuffer, lpcbBytesReturned,lpCompletion); -end; - -function Stub_WSAInstallServiceClassA(const lpServiceClassInfo: LPWSASERVICECLASSINFOA): Integer; stdcall; -begin - @WSAInstallServiceClassA := FixupStub(hWinSockDll, 'WSAInstallServiceClassA'); {Do not Localize} - Result := WSAInstallServiceClassA(lpServiceClassInfo); -end; - -function Stub_WSAInstallServiceClassW(const lpServiceClassInfo: LPWSASERVICECLASSINFOW): Integer; stdcall; -begin - @WSAInstallServiceClassW := FixupStub(hWinSockDll, 'WSAInstallServiceClassW'); {Do not Localize} - Result := WSAInstallServiceClassW(lpServiceClassInfo); -end; - -function Stub_WSAInstallServiceClass(const lpServiceClassInfo: LPWSASERVICECLASSINFO): Integer; stdcall; -begin - {$IFDEF UNICODE} - @WSAInstallServiceClass := FixupStub(hWinSockDll, 'WSAInstallServiceClassW'); {Do not Localize} - {$ELSE} - @WSAInstallServiceClass := FixupStub(hWinSockDll, 'WSAInstallServiceClassA'); {Do not Localize} - {$ENDIF} - Result := WSAInstallServiceClass(lpServiceClassInfo); -end; - -function Stub_WSARemoveServiceClass(const lpServiceClassId: PGUID): Integer; stdcall; -begin - @WSARemoveServiceClass := FixupStub(hWinSockDll, 'WSARemoveServiceClass'); {Do not Localize} - Result := WSARemoveServiceClass(lpServiceClassId); -end; - -function Stub_WSAGetServiceClassInfoA(const lpProviderId: PGUID; const lpServiceClassId: PGUID; var lpdwBufSize: DWORD; lpServiceClassInfo: LPWSASERVICECLASSINFOA): Integer; stdcall; -begin - @WSAGetServiceClassInfoA := FixupStub(hWinSockDll, 'WSAGetServiceClassInfoA'); {Do not Localize} - Result := WSAGetServiceClassInfoA(lpProviderId, lpServiceClassId, lpdwBufSize, lpServiceClassInfo); -end; - -function Stub_WSAGetServiceClassInfoW(const lpProviderId: PGUID; const lpServiceClassId: PGUID; var lpdwBufSize: DWORD; lpServiceClassInfo: LPWSASERVICECLASSINFOW): Integer; stdcall; -begin - @WSAGetServiceClassInfoW := FixupStub(hWinSockDll, 'WSAGetServiceClassInfoW'); {Do not Localize} - Result := WSAGetServiceClassInfoW(lpProviderId, lpServiceClassId, lpdwBufSize, lpServiceClassInfo); -end; - -function Stub_WSAGetServiceClassInfo(const lpProviderId: PGUID; const lpServiceClassId: PGUID; var lpdwBufSize: DWORD; lpServiceClassInfo: LPWSASERVICECLASSINFO): Integer; stdcall; -begin - {$IFDEF UNICODE} - @WSAGetServiceClassInfo := FixupStub(hWinSockDll, 'WSAGetServiceClassInfoW'); {Do not Localize} - {$ELSE} - @WSAGetServiceClassInfo := FixupStub(hWinSockDll, 'WSAGetServiceClassInfoA'); {Do not Localize} - {$ENDIF} - Result := WSAGetServiceClassInfo(lpProviderId, lpServiceClassId, lpdwBufSize, lpServiceClassInfo); -end; - -function Stub_WSAEnumNameSpaceProvidersA(var lpdwBufferLength: DWORD; const lpnspBuffer: LPWSANAMESPACE_INFOA): Integer; stdcall; -begin - @WSAEnumNameSpaceProvidersA := FixupStub(hWinSockDll, 'WSAEnumNameSpaceProvidersA'); {Do not Localize} - Result := WSAEnumNameSpaceProvidersA(lpdwBufferLength, lpnspBuffer); -end; - -function Stub_WSAEnumNameSpaceProvidersW(var lpdwBufferLength: DWORD; const lpnspBuffer: LPWSANAMESPACE_INFOW): Integer; stdcall; -begin - @WSAEnumNameSpaceProvidersW := FixupStub(hWinSockDll, 'WSAEnumNameSpaceProvidersW'); {Do not Localize} - Result := WSAEnumNameSpaceProvidersW(lpdwBufferLength, lpnspBuffer); -end; - -function Stub_WSAEnumNameSpaceProviders(var lpdwBufferLength: DWORD; const lpnspBuffer: LPWSANAMESPACE_INFO): Integer; stdcall; -begin - {$IFDEF UNICODE} - @WSAEnumNameSpaceProviders := FixupStub(hWinSockDll, 'WSAEnumNameSpaceProvidersW'); {Do not Localize} - {$ELSE} - @WSAEnumNameSpaceProviders := FixupStub(hWinSockDll, 'WSAEnumNameSpaceProvidersA'); {Do not Localize} - {$ENDIF} - Result := WSAEnumNameSpaceProviders(lpdwBufferLength, lpnspBuffer); -end; - -function Stub_WSAGetServiceClassNameByClassIdA(const lpServiceClassId: PGUID; lpszServiceClassName: PIdAnsiChar; var lpdwBufferLength: DWORD): Integer; stdcall; -begin - @WSAGetServiceClassNameByClassIdA := FixupStub(hWinSockDll, 'WSAGetServiceClassNameByClassIdA'); {Do not Localize} - Result := WSAGetServiceClassNameByClassIdA(lpServiceClassId, lpszServiceClassName, lpdwBufferLength); -end; - -function Stub_WSAGetServiceClassNameByClassIdW(const lpServiceClassId: PGUID; lpszServiceClassName: PWideChar; var lpdwBufferLength: DWORD): Integer; stdcall; -begin - @WSAGetServiceClassNameByClassIdW := FixupStub(hWinSockDll, 'WSAGetServiceClassNameByClassIdW'); {Do not Localize} - Result := WSAGetServiceClassNameByClassIdW(lpServiceClassId, lpszServiceClassName, lpdwBufferLength); -end; - -function Stub_WSAGetServiceClassNameByClassId(const lpServiceClassId: PGUID; - lpszServiceClassName: PIdPlatformChar; var lpdwBufferLength: DWORD): Integer; stdcall; -begin - {$IFDEF UNICODE} - @WSAGetServiceClassNameByClassId := FixupStub(hWinSockDll, 'WSAGetServiceClassNameByClassIdW'); {Do not Localize} - {$ELSE} - @WSAGetServiceClassNameByClassId := FixupStub(hWinSockDll, 'WSAGetServiceClassNameByClassIdA'); {Do not Localize} - {$ENDIF} - Result := WSAGetServiceClassNameByClassId(lpServiceClassId, lpszServiceClassName, lpdwBufferLength); -end; - -function Stub_WSASetServiceA(const lpqsRegInfo: LPWSAQUERYSETA; const essoperation: WSAESETSERVICEOP; const dwControlFlags: DWORD): Integer; stdcall; -begin - @WSASetServiceA := FixupStub(hWinSockDll, 'WSASetServiceA'); {Do not Localize} - Result := WSASetServiceA(lpqsRegInfo, essoperation, dwControlFlags); -end; - -function Stub_WSASetServiceW(const lpqsRegInfo: LPWSAQUERYSETW; const essoperation: WSAESETSERVICEOP; const dwControlFlags: DWORD): Integer; stdcall; -begin - @WSASetServiceW := FixupStub(hWinSockDll, 'WSASetServiceW'); {Do not Localize} - Result := WSASetServiceW(lpqsRegInfo, essoperation, dwControlFlags); -end; - -function Stub_WSASetService(const lpqsRegInfo: LPWSAQUERYSET; const essoperation: WSAESETSERVICEOP; const dwControlFlags: DWORD): Integer; stdcall; -begin - {$IFDEF UNICODE} - @WSASetService := FixupStub(hWinSockDll, 'WSASetServiceW'); {Do not Localize} - {$ELSE} - @WSASetService := FixupStub(hWinSockDll, 'WSASetServiceA'); {Do not Localize} - {$ENDIF} - Result := WSASetService(lpqsRegInfo, essoperation, dwControlFlags); -end; - -function Stub_WSAProviderConfigChange(var lpNotificationHandle: THandle; AOverlapped: LPWSAOVERLAPPED; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; -begin - @WSAProviderConfigChange := FixupStub(hWinSockDll, 'WSAProviderConfigChange'); {Do not Localize} - Result := WSAProviderConfigChange(lpNotificationHandle, AOverlapped, lpCompletionRoutine); -end; - -function Stub_TransmitFile(hSocket: TSocket; hFile: THandle; nNumberOfBytesToWrite: DWORD; - nNumberOfBytesPerSend: DWORD; lpOverlapped: POverlapped; - lpTransmitBuffers: LPTRANSMIT_FILE_BUFFERS; dwReserved: DWORD): BOOL; stdcall; -begin - @TransmitFile := FixupStubEx(hSocket, 'TransmitFile', WSAID_TRANSMITFILE); {Do not localize} - Result := TransmitFile(hSocket, hFile, nNumberOfBytesToWrite, nNumberOfBytesPerSend, lpOverlapped, lpTransmitBuffers, dwReserved); -end; - -{RLebeau 1/26/2006 - loading GetAcceptExSockaddrs() at the same time as AcceptEx(). -This is because GetAcceptExSockaddrs() is not passed a SOCKET that can be passed to -WSAIoCtrl() to get the function pointer. Also, GetAcceptExSockaddrs() is needed to -parse AcceptEx()'s return data, so there is no point in calling AcceptEx() unless -its data can be parsed afterwards.} -function Stub_AcceptEx(sListenSocket, sAcceptSocket: TSocket; - lpOutputBuffer: Pointer; dwReceiveDataLength, dwLocalAddressLength, - dwRemoteAddressLength: DWORD; var lpdwBytesReceived: DWORD; - lpOverlapped: POverlapped): BOOL; stdcall; -begin - {RLebeau - loading GetAcceptExSockaddrs() first in case it fails} - @GetAcceptExSockaddrs := FixupStubEx(sListenSocket, 'GetAcceptExSockaddrs', WSAID_GETACCEPTEXSOCKADDRS); {Do not localize} - @AcceptEx := FixupStubEx(sListenSocket, 'AcceptEx', WSAID_ACCEPTEX); {Do not localize} - Result := AcceptEx(sListenSocket, sAcceptSocket, lpOutputBuffer, dwReceiveDataLength, - dwLocalAddressLength, dwRemoteAddressLength, lpdwBytesReceived, lpOverlapped); -end; - -{$IFNDEF WINCE} -function Stub_WSARecvEx(s: TSocket; var buf; len: Integer; var flags: Integer): Integer; stdcall; -begin - LoadMSWSock; - @WSARecvEx := FixupStub(hMSWSockDll, 'WSARecvEx'); {Do not localize} - Result := WSARecvEx(s, buf, len, flags); -end; -{$ENDIF} - -function Stub_ConnectEx(const s : TSocket; const name: PSockAddr; const namelen: Integer; lpSendBuffer : Pointer; - dwSendDataLength : DWORD; var lpdwBytesSent : DWORD; lpOverlapped : LPWSAOVERLAPPED) : BOOL; stdcall; -begin - @ConnectEx := FixupStubEx(s, 'ConnectEx', WSAID_CONNECTEX); {Do not localize} - Result := ConnectEx(s, name, namelen, lpSendBuffer, dwSendDataLength, lpdwBytesSent, lpOverlapped); -end; - -function Stub_DisconnectEx(const s : TSocket; AOverlapped: Pointer; const dwFlags : DWord; const dwReserved : DWORD) : BOOL; stdcall; -begin - @DisconnectEx := FixupStubEx(s, 'DisconnectEx', WSAID_DISCONNECTEX); {Do not localize} - Result := DisconnectEx(s, AOverlapped, dwFlags, dwReserved); -end; - -function Stub_WSARecvMsg(const s : TSocket; lpMsg : LPWSAMSG; var lpNumberOfBytesRecvd : DWORD; AOverlapped: Pointer; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; -begin - @WSARecvMsg := FixupStubEx(s, 'WSARecvMsg', WSAID_WSARECVMSG); {Do not localize} - Result := WSARecvMsg(s, lpMsg, lpNumberOfBytesRecvd, AOverlapped, lpCompletionRoutine); -end; - -function Stub_TransmitPackets(s: TSocket; lpPacketArray: LPTRANSMIT_PACKETS_ELEMENT; - nElementCount: DWORD; nSendSize: DWORD; lpOverlapped: LPWSAOVERLAPPED; dwFlags: DWORD): BOOL; stdcall; -begin - @TransmitPackets := FixupStubEx(s, 'TransmitPackets', WSAID_TRANSMITPACKETS); {Do not localize} - Result := TransmitPackets(s, lpPacketArray, nElementCount, nSendSize, lpOverlapped, dwFlags); -end; - -{$IFNDEF WINCE} -function Stub_WSASendMsg(const s : TSocket; lpMsg : LPWSAMSG; const dwFlags : DWORD; var lpNumberOfBytesSent : DWORD; lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; -begin - @WSASendMsg := FixupStubEx(s, 'WSASendMsg', WSAID_WSASENDMSG); {Do not localize} - Result := WSASendMsg(s, lpMsg, dwFlags, lpNumberOfBytesSent, lpOverlapped, lpCompletionRoutine); -end; - -function Stub_WSAPoll(fdarray : LPWSAPOLLFD; const nfds : u_long; const timeout : Integer) : Integer; stdcall; -begin - @WSAPoll := FixupStubEx(fdarray.fd, 'WSAPoll', WSAID_WSAPOLL); {Do not localize} - Result := WSAPoll(fdarray, nfds, timeout); -end; -{$ENDIF} - -procedure InitializeStubs; -{Alphabetize these so we can more easily determine what's available on a platform. -by section in Winsock SDK reference} -begin - accept := Stub_accept; - bind := Stub_bind; - closesocket := Stub_closesocket; - connect := Stub_connect; - ioctlsocket := Stub_ioctlsocket; - getpeername := Stub_getpeername; - getsockname := Stub_getsockname; - getsockopt := Stub_getsockopt; - htonl := Stub_htonl; - htons := Stub_htons; - inet_addr := Stub_inet_addr; - inet_ntoa := Stub_inet_ntoa; - listen := Stub_listen; - ntohl := Stub_ntohl; - ntohs := Stub_ntohs; - recv := Stub_recv; - recvfrom := Stub_recvfrom; - select := Stub_select; - send := Stub_send; - sendto := Stub_sendto; - {$IFDEF WINCE} - sethostname := Stub_sethostname; - {$ENDIF} - setsockopt := Stub_setsockopt; - shutdown := Stub_shutdown; - socket := Stub_socket; - gethostbyaddr := Stub_gethostbyaddr; - gethostbyname := Stub_gethostbyname; - gethostname := Stub_gethostname; - getservbyport := Stub_getservbyport; - getservbyname := Stub_getservbyname; - getprotobynumber := Stub_getprotobynumber; - getprotobyname := Stub_getprotobyname; - //extensions - __WSAFDIsSet := Stub___WSAFDIsSet; - {$IFNDEF WINCE} - AcceptEx := Stub_AcceptEx; - //GetAcceptExSockaddrs is loaded by Stub_AcceptEx - ConnectEx := Stub_ConnectEx; - DisconnectEx := Stub_DisconnectEx; - TransmitFile := Stub_TransmitFile; - TransmitPackets := Stub_TransmitPackets; - {$ENDIF} - WSAAccept := Stub_WSAAccept; - {$IFNDEF WINCE} - WSACancelAsyncRequest := Stub_WSACancelAsyncRequest; - WSAAsyncGetHostByAddr := Stub_WSAAsyncGetHostByAddr; - WSAAsyncGetHostByName := Stub_WSAAsyncGetHostByName; - WSAAsyncGetProtoByName := Stub_WSAAsyncGetProtoByName; - WSAAsyncGetProtoByNumber := Stub_WSAAsyncGetProtoByNumber; - WSAAsyncGetServByName := Stub_WSAAsyncGetServByName; - WSAAsyncGetServByPort := Stub_WSAAsyncGetServByPort; - WSAAsyncSelect := Stub_WSAAsyncSelect; - {$ENDIF} - WSAAddressToStringA := Stub_WSAAddressToStringA; - WSAAddressToStringW := Stub_WSAAddressToStringW; - WSAAddressToString := Stub_WSAAddressToString; - {$IFNDEF WINCE} - WSACancelBlockingCall := Stub_WSACancelBlockingCall; - {$ENDIF} - WSACleanup := Stub_WSACleanup; - WSACloseEvent := Stub_WSACloseEvent; - WSAConnect := Stub_WSAConnect; - WSACreateEvent := Stub_WSACreateEvent; - {$IFNDEF WINCE} - WSADuplicateSocketA := Stub_WSADuplicateSocketA; - WSADuplicateSocketW := Stub_WSADuplicateSocketW; - WSADuplicateSocket := Stub_WSADuplicateSocket; - {$ENDIF} - WSAEnumNameSpaceProvidersA := Stub_WSAEnumNameSpaceProvidersA; - WSAEnumNameSpaceProvidersW := Stub_WSAEnumNameSpaceProvidersW; - WSAEnumNameSpaceProviders := Stub_WSAEnumNameSpaceProviders; - WSAEnumNetworkEvents := Stub_WSAEnumNetworkEvents; - WSAEnumProtocolsA := Stub_WSAEnumProtocolsA; - WSAEnumProtocolsW := Stub_WSAEnumProtocolsW; - WSAEnumProtocols := Stub_WSAEnumProtocols; - WSAEventSelect := Stub_WSAEventSelect; - WSAGetLastError := Stub_WSAGetLastError; - WSAGetOverlappedResult := Stub_WSAGetOverlappedResult; - {$IFNDEF WINCE} - WSAGetQOSByName := Stub_WSAGetQOSByName; - WSAGetServiceClassInfoA := Stub_WSAGetServiceClassInfoA; - WSAGetServiceClassInfoW := Stub_WSAGetServiceClassInfoW; - WSAGetServiceClassInfo := Stub_WSAGetServiceClassInfo; - WSAGetServiceClassNameByClassIdA := Stub_WSAGetServiceClassNameByClassIdA; - WSAGetServiceClassNameByClassIdW := Stub_WSAGetServiceClassNameByClassIdW; - WSAGetServiceClassNameByClassId := Stub_WSAGetServiceClassNameByClassId; - {$ENDIF} - WSAHtonl := Stub_WSAHtonl; - WSAHtons := Stub_WSAHtons; - {$IFNDEF WINCE} - WSAInstallServiceClassA := Stub_WSAInstallServiceClassA; - WSAInstallServiceClassW := Stub_WSAInstallServiceClassW; - WSAInstallServiceClass := Stub_WSAInstallServiceClass; - {$ENDIF} - WSAIoctl := Stub_WSAIoctl; - {$IFNDEF WINCE} - WSAIsBlocking := Stub_WSAIsBlocking; - {$ENDIF} - WSAJoinLeaf := Stub_WSAJoinLeaf; - WSALookupServiceBeginA := Stub_WSALookupServiceBeginA; - WSALookupServiceBeginW := Stub_WSALookupServiceBeginW; - WSALookupServiceBegin := Stub_WSALookupServiceBegin; - WSALookupServiceEnd := Stub_WSALookupServiceEnd; - WSALookupServiceNextA := Stub_WSALookupServiceNextA; - WSALookupServiceNextW := Stub_WSALookupServiceNextW; - WSALookupServiceNext := Stub_WSALookupServiceNext; - - // WSANSPIoctl is not supported in WinCE 4.20 but is in later versions. - WSANSPIoctl := Stub_WSANSPIoctl; - - WSANtohl := Stub_WSANtohl; - WSANtohs := Stub_WSANtohs; - {$IFNDEF WINCE} - WSAPoll := Stub_WSAPoll; - WSAProviderConfigChange := Stub_WSAProviderConfigChange; - {$ENDIF} - WSARecv := Stub_WSARecv; - {$IFNDEF WINCE} - WSARecvDisconnect := Stub_WSARecvDisconnect; - WSARecvEx := Stub_WSARecvEx; - {$ENDIF} - WSARecvFrom := Stub_WSARecvFrom; - WSARecvMsg := Stub_WSARecvMsg; - WSARemoveServiceClass := Stub_WSARemoveServiceClass; - WSAResetEvent := Stub_WSAResetEvent; - WSASend := Stub_WSASend; - {$IFNDEF WINCE} - WSASendDisconnect := Stub_WSASendDisconnect; - WSASendMsg := Stub_WSASendMsg; - {$ENDIF} - WSASendTo := Stub_WSASendTo; - {$IFNDEF WINCE} - WSASetBlockingHook := Stub_WSASetBlockingHook; - {$ENDIF} - WSASetEvent := Stub_WSASetEvent; - WSASetLastError := Stub_WSASetLastError; - WSASetServiceA := Stub_WSASetServiceA; - WSASetServiceW := Stub_WSASetServiceW; - WSASetService := Stub_WSASetService; - WSASocketA := Stub_WSASocketA; - WSASocketW := Stub_WSASocketW; - WSASocket := Stub_WSASocket; - WSAStartup := Stub_WSAStartup; - WSAStringToAddressA := Stub_WSAStringToAddressA; - WSAStringToAddressW := Stub_WSAStringToAddressW; - WSAStringToAddress := Stub_WSAStringToAddress; - {$IFNDEF WINCE} - WSAUnhookBlockingHook := Stub_WSAUnhookBlockingHook; - {$ENDIF} - WSAWaitForMultipleEvents := Stub_WSAWaitForMultipleEvents; -end; - -function WSAMakeSyncReply(Buflen, AError: Word): Longint; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := MakeLong(Buflen, AError); -end; - -function WSAMakeSelectReply(Event, AError: Word): Longint; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := MakeLong(Event, AError); -end; - -function WSAGetAsyncBuflen(Param: LPARAM): Word; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := LOWORD(Param); -end; - -function WSAGetAsyncError(Param: LPARAM): Word; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := HIWORD(Param); -end; - -function WSAGetSelectEvent(Param: LPARAM): Word; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := LOWORD(Param); -end; - -function WSAGetSelectError(Param: LPARAM): Word; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - WSAGetSelectError := HIWORD(Param); -end; - -procedure FD_CLR(ASocket: TSocket; var FDSet: TFDSet); -var - i: u_int; -begin - i := 0; - while i < FDSet.fd_count do - begin - if FDSet.fd_array[i] = ASocket then - begin - while i < FDSet.fd_count - 1 do - begin - FDSet.fd_array[i] := FDSet.fd_array[i+1]; - Inc(i); - end; - Dec(FDSet.fd_count); - Break; - end; - Inc(i); - end; -end; - -function FD_ISSET(ASocket: TSocket; var FDSet: TFDSet): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := __WSAFDIsSet(ASocket, FDSet); -end; - -procedure FD_SET(ASocket: TSocket; var FDSet: TFDSet); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if FDSet.fd_count < fd_setsize then - begin - FDSet.fd_array[FDSet.fd_count] := ASocket; - Inc(FDSet.fd_count); - end; -end; - -procedure FD_ZERO(var FDSet: TFDSet); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - FDSet.fd_count := 0; -end; - -{$IFNDEF WINCE} - -//Posix aliases -// #define CMSGHDR_ALIGN WSA_CMSGHDR_ALIGN -function CMSGHDR_ALIGN(const Alength: SIZE_T): SIZE_T; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := WSA_CMSGHDR_ALIGN(Alength); -end; - -// #define CMSGDATA_ALIGN WSA_CMSGDATA_ALIGN -function CMSGDATA_ALIGN(const Alength: PtrUInt): PtrUInt; - {$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := WSA_CMSGDATA_ALIGN(Alength); -end; - -//#define CMSG_FIRSTHDR WSA_CMSG_FIRSTHDR -function CMSG_FIRSTHDR(const msg: LPWSAMSG): LPWSACMSGHDR; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := WSA_CMSG_FIRSTHDR(msg); -end; - -// #define CMSG_NXTHDR WSA_CMSG_NXTHDR -function CMSG_NXTHDR(const msg: LPWSAMSG; const cmsg: LPWSACMSGHDR): LPWSACMSGHDR; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := WSA_CMSG_NXTHDR(msg, cmsg); -end; - -// #define CMSG_SPACE WSA_CMSG_SPACE -function CMSG_SPACE(const Alength: PtrUInt): PtrUInt; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := WSA_CMSG_SPACE(ALength); -end; - -// #define CMSG_LEN WSA_CMSG_LEN -function CMSG_LEN(const Alength: SIZE_T): SIZE_T; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := WSA_CMSG_LEN(ALength); -end; - -// -function WSA_CMSGHDR_ALIGN(const Alength: SIZE_T): SIZE_T; -type - {$IFDEF WIN32} - {$ALIGN ON} - TempRec = record - x: TIdAnsiChar; - test: WSACMSGHDR; - end; - {$ALIGN OFF} - {$ELSE} - //Win64 and WinCE seem to require alignment for API records - TempRec = record - x: TIdAnsiChar; - test: WSACMSGHDR; - end; - {$ENDIF} -var - Alignment: SIZE_T; - Tmp: ^TempRec; -begin - Tmp := nil; - Alignment := PtrUInt(@(Tmp^.test)); - Result := (Alength + (Alignment-1)) and not (Alignment-1); -end; - -function WSA_CMSGDATA_ALIGN(const Alength: PtrUInt): PtrUInt; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := (Alength + MAX_NATURAL_ALIGNMENT_SUB_1) and not (MAX_NATURAL_ALIGNMENT_SUB_1); -end; - -function WSA_CMSG_FIRSTHDR(const msg: LPWSAMSG): LPWSACMSGHDR; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (msg <> nil) and (msg^.Control.len >= SIZE_WSACMSGHDR) then begin - Result := LPWSACMSGHDR(msg^.Control.buf); - end else begin - Result := nil; - end; -end; - -function WSA_CMSG_NXTHDR(const msg: LPWSAMSG; const cmsg: LPWSACMSGHDR): LPWSACMSGHDR; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if cmsg = nil then begin - Result := WSA_CMSG_FIRSTHDR(msg); - end else begin - if (PtrUInt(cmsg) + WSA_CMSGHDR_ALIGN(cmsg^.cmsg_len) + SIZE_WSACMSGHDR) > (PtrUInt(msg^.Control.buf) + msg^.Control.len) then begin - Result := nil; - end else begin - Result := LPWSACMSGHDR(PtrUInt(cmsg) + WSA_CMSGHDR_ALIGN(cmsg^.cmsg_len)); - end; - end; -end; - -function WSA_CMSG_DATA(const cmsg: LPWSACMSGHDR): PByte; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := PByte(PtrUInt(cmsg) + WSA_CMSGDATA_ALIGN(SIZE_WSACMSGHDR)); -end; - -function WSA_CMSG_SPACE(const Alength: PtrUInt): PtrUInt; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := WSA_CMSGDATA_ALIGN(PtrUInt(SIZE_WSACMSGHDR + WSA_CMSGHDR_ALIGN(Alength))); -end; - -function WSA_CMSG_LEN(const Alength: SIZE_T): SIZE_T; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := (WSA_CMSGDATA_ALIGN(SizeOf(WSACMSGHDR)) + Alength); -end; - -function RIO_CMSG_BASE_SIZE : SIZE_T; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := WSA_CMSGHDR_ALIGN(sizeof(RIO_CMSG_BUFFER)); -end; - -function RIO_CMSG_FIRSTHDR(buffer : PRIO_CMSG_BUFFER) : PWSACMSGHDR; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if ((buffer)^.TotalLength >= RIO_CMSG_BASE_SIZE) then - begin - if (((buffer)^.TotalLength - RIO_CMSG_BASE_SIZE) >= sizeof(WSACMSGHDR)) then begin - Result := PWSACMSGHDR((PIdAnsiChar(buffer)) + RIO_CMSG_BASE_SIZE); - end else begin - Result := PWSACMSGHDR(nil); - end; - end else begin - Result := PWSACMSGHDR(nil); - end; -end; - -function RIO_CMSG_NEXTHDR(buffer : PRIO_CMSG_BUFFER; cmsg : PWSACMSGHDR) : PWSACMSGHDR; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if ((cmsg) = nil) then begin - Result := RIO_CMSG_FIRSTHDR(buffer); - end else begin - if (PIdAnsiChar(cmsg) + WSA_CMSGHDR_ALIGN((cmsg^.cmsg_len) + sizeof(WSACMSGHDR)) > (PIdAnsiChar(buffer) + (buffer)^.TotalLength)) then begin - Result := (PWSACMSGHDR(nil)); - end else begin - Result :=(PWSACMSGHDR(PIdAnsiChar(cmsg) + WSA_CMSGHDR_ALIGN(cmsg^.cmsg_len))); - end; - end; -end; - -{$ENDIF} // {$IFNDEF WINCE} - -function IP_MSFILTER_SIZE(const numsrc: DWORD): PtrUInt; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := SIZE_IP_MSFILTER - SIZE_TINADDR + (numsrc*SIZE_TINADDR); -end; - -function SS_PORT(ssp: PSockAddrIn): u_short; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if ssp <> nil then begin - Result := ssp^.sin_port; - end else begin - Result := 0; - end; -end; - -// -// Microsoft-specific IPv4 definitions. -// -function IN4_CLASSA(const i : UInt32) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := ((i and $00000080) = 0); -end; - -function IN4_CLASSB(const i : UInt32) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := ((i and $000000c0) = $00000080); -end; - -function IN4_CLASSC(const i : UInt32) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := ((i and $000000e0) = $000000c0); -end; - -function IN4_CLASSD(const i : UInt32) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := ((i and $000000f0) = $000000e0); -end; - -function IN4_MULTICAST(const i : UInt32) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := IN4_CLASSD(i); -end; - -function IN4_ADDR_EQUAL(const a, b : PInAddr ) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := a^.S_addr = b^.S_addr; -end; - -function IN4_UNALIGNED_ADDR_EQUAL(const a, b : PInAddr ) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := a^.S_addr = b^.S_addr -end; - -function IN4_IS_ADDR_UNSPECIFIED(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := a^.S_addr = IN4ADDR_ANY; -end; - -function IN4_IS_UNALIGNED_ADDR_UNSPECIFIED(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := a^.S_addr = IN4ADDR_ANY; -end; - -function IN4_IS_ADDR_LOOPBACK(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := PByte(a)^ = $7f; // 127/8 -end; - -function IN4_IS_UNALIGNED_ADDR_LOOPBACK(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := PByte(a)^ = $7f; // 127/8 -end; - -function IN4_IS_ADDR_BROADCAST(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := a^.S_addr = IN4ADDR_BROADCAST; -end; - -function IN4_IS_UNALIGNED_ADDR_BROADCAST(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := a^.S_addr = IN4ADDR_BROADCAST; -end; - -function IN4_IS_ADDR_MULTICAST(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := IN4_MULTICAST(a^.S_addr); -end; - -function IN4_IS_UNALIGNED_ADDR_MULTICAST(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := IN4_MULTICAST(a^.S_addr); -end; - -function IN4_IS_ADDR_LINKLOCAL(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := ((a^.s_addr and $ffff) = $fea9); // 169.254/16 -end; - -function IN4_IS_UNALIGNED_ADDR_LINKLOCAL(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := ((a^.s_addr and $ffff) = $fea9); // 169.254/16 -end; - -function IN4_IS_ADDR_SITELOCAL(const a :PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - //UNREFERENCED_PARAMETER(a); - // - // For existing scenarios (e.g. ICS) to work as expected, RFC-1918 prefixes - // are deemed to be global scoped. When appropriate, site border routers - // must explicitly filter packets with these addresses. - // - Result := False; -end; - -function IN4_IS_UNALIGNED_ADDR_SITELOCAL(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := IN4_IS_ADDR_SITELOCAL(a); -end; - -function IN4_IS_ADDR_RFC1918(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := (((a^.s_addr and $00ff) = $0a) or // 10/8 - ((a^.s_addr and $f0ff) = $10ac) or // 172.16/12 - ((a^.s_addr and $ffff) = $a8c0)); // 192.168/16 -end; - -function IN4_IS_UNALIGNED_ADDR_RFC1918(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -var - Ipv4Address : IN_ADDR; -begin - //JPM Notes: Done this way because pointers may not be aligned at all. - Ipv4Address := a^; - Result := IN4_IS_ADDR_RFC1918( @Ipv4Address ); -end; - -function IN4_IS_ADDR_MC_LINKLOCAL(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := ((a^.s_addr and $ffffff) = $e0); // 224.0.0/24 -end; - -function IN4_IS_ADDR_MC_ADMINLOCAL(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := ((a^.s_addr and $ffff) = $ffef); // 239.255/16 -end; - -function IN4_IS_ADDR_MC_SITELOCAL(const a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := ((a^.s_addr and $ff) = $ef) and - (not IN4_IS_ADDR_MC_ADMINLOCAL(a)); -end; - -function SCOPEID_UNSPECIFIED_INIT: {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result{$IFNDEF WINCE}.Value{$ENDIF} := 0; -end; - -function IN4ADDR_ANY_INIT: TInAddr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result.S_addr := 0; -end; - -function IN4ADDR_LOOPBACK_INIT: TInAddr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result.S_un_b.s_b1 := $7f; - Result.S_un_b.s_b2 := $00; - Result.S_un_b.s_b3 := $00; - Result.S_un_b.s_b4 := $01; -end; - -function IN4ADDR_BROADCAST_INIT: TInAddr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result.S_un_b.s_b1 := $ff; - Result.S_un_b.s_b2 := $ff; - Result.S_un_b.s_b3 := $ff; - Result.S_un_b.s_b4 := $ff; -end; - -function IN4ADDR_ALLNODESONLINK_INIT: TInAddr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result.S_un_b.s_b1 := $e0; - Result.S_un_b.s_b2 := $00; - Result.S_un_b.s_b3 := $00; - Result.S_un_b.s_b4 := $01; -end; - -function IN4ADDR_ALLROUTERSONLINK_INIT: TInAddr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result.S_un_b.s_b1 := $e0; - Result.S_un_b.s_b2 := $00; - Result.S_un_b.s_b3 := $00; - Result.S_un_b.s_b4 := $02; -end; - -function IN4ADDR_ALLIGMPV3ROUTERSONLINK_INIT: TInAddr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result.S_un_b.s_b1 := $e0; - Result.S_un_b.s_b2 := $00; - Result.S_un_b.s_b3 := $00; - Result.S_un_b.s_b4 := $16; -end; - -function IN4ADDR_ALLTEREDONODESONLINK_INIT: TInAddr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result.S_un_b.s_b1 := $e0; - Result.S_un_b.s_b2 := $00; - Result.S_un_b.s_b3 := $00; - Result.S_un_b.s_b4 := $fd; -end; - -function IN4ADDR_LINKLOCALPREFIX_INIT: TInAddr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result.S_un_b.s_b1 := $a9; - Result.S_un_b.s_b2 := $fe; - Result.S_un_b.s_b3 := $00; - Result.S_un_b.s_b4 := $00; -end; - -function IN4ADDR_MULTICASTPREFIX_INIT: TInAddr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result.S_un_b.s_b1 := $e0; - Result.S_un_b.s_b2 := $00; - Result.S_un_b.s_b3 := $00; - Result.S_un_b.s_b4 := $00; -end; - -procedure IN4ADDR_SETSOCKADDR(a : PSockAddrIn; const addr : PInAddr; const port : USHORT); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - a^.sin_family := AF_INET; - a^.sin_port := port; - a^.sin_addr.S_addr := addr^.S_addr; - FillChar(a^.sin_zero,SizeOf(a^.sin_zero),0); -end; - -procedure IN4ADDR_SETANY(a : PSockAddrIn); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - a^.sin_family := AF_INET; - a^.sin_port := 0; - a^.sin_addr.S_addr := IN4ADDR_ANY; - FillChar(a^.sin_zero,SizeOf(a^.sin_zero),0); -end; - -procedure IN4ADDR_SETLOOPBACK(a : PSockAddrIn); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - a^.sin_family := AF_INET; - a^.sin_port := 0; - a^.sin_addr.S_addr := IN4ADDR_LOOPBACK; - FillChar(a^.sin_zero,SizeOf(a^.sin_zero),0); -end; - -function IN4ADDR_ISANY(const a : PSockAddrIn) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - ASSERT(a^.sin_family = AF_INET); - Result := IN4_IS_ADDR_UNSPECIFIED(@a^.sin_addr ); -end; - -function IN4ADDR_ISLOOPBACK(const a : PSockAddrIn) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - ASSERT(a^.sin_family = AF_INET); - Result := IN4_IS_ADDR_LOOPBACK(@a^.sin_addr); -end; - -function IN4ADDR_SCOPE_ID(const a : PSockAddrIn) : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - //SCOPE_ID UnspecifiedScopeId = {0}; - //UNREFERENCED_PARAMETER(a); - //return UnspecifiedScopeId; - Result{$IFNDEF WINCE}.Value{$ENDIF} := 0; -end; - -function IN4ADDR_ISEQUAL(a, b : PSockAddrIn) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - ASSERT(a^.sin_family = AF_INET); - Result := (IN4ADDR_SCOPE_ID(a){$IFNDEF WINCE}.Value{$ENDIF} = IN4ADDR_SCOPE_ID(b){$IFNDEF WINCE}.Value{$ENDIF}) and - IN4_ADDR_EQUAL(@a^.sin_addr , @b^.sin_addr); -end; - -function IN4ADDR_ISUNSPECIFIED(a : PSockAddrIn) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - ASSERT(a^.sin_family = AF_INET); - Result := (IN4ADDR_SCOPE_ID(a){$IFNDEF WINCE}.Value{$ENDIF} = 0) and - IN4_IS_ADDR_UNSPECIFIED(@a^.sin_addr); -end; - -{Important!!! INET_IS_ALIGNED doesn't seem to translate well to -Delphi. The best I could think of is to make a function -for testing with specific types. I wish Pascal had an AlignOf function} - -//#define INET_IS_ALIGNED(Pointer, Type) \ -// (((ULONG_PTR)Pointer & (__builtin_alignof(Type)-1)) == 0) - - -function INET_IS_ALIGNED_IN_ADDR(Ptr : Pointer) : Boolean; -type - {$IFDEF WIN32} - {$ALIGN ON} - TempRec = record - test: IN_ADDR; - end; - {$ALIGN OFF} - {$ELSE} - //Win64 and WinCE seem to require alignment for API records - TempRec = record - test: IN_ADDR; - end; - {$ENDIF} -var - Alignment : SIZE_T; -begin - Alignment := SizeOf(TempRec); - Result := ((ULONG_PTR(Ptr) and (Alignment - 1)) = 0); -end; - - -function INET_IS_ALIGNED_IN6_ADDR(Ptr : Pointer) : Boolean; -type - {$IFDEF WIN32} - {$ALIGN ON} - TempRec = record - test: IN6_ADDR; - end; - {$ALIGN OFF} - {$ELSE} - //Win64 and WinCE seem to require alignment for API records - TempRec = record - test: IN6_ADDR; - end; - {$ENDIF} -var - Alignment : SIZE_T; -begin - Alignment := SizeOf(TempRec); - Result := ((ULONG_PTR(Ptr) and (Alignment - 1)) = 0); -end; - -{ - -Routine Description: - - Determines the scope of an IPv4 unicast address. - - For existing scenarios (e.g. ICS) to work as expected, RFC-1918 prefixes - are deemed to be global scoped. When appropriate, site border routers - must explicitly filter packets with these addresses. - -Arguments: - - Address - Supplies the IPv4 unicast address. - -Return Value: - - Returns the scope level of the address. - -Caller IRQL: - - May be called at PASSIVE through DISPATCH level. - ---*/ -} - -function Ipv4UnicastAddressScope(const Address : PUChar) : SCOPE_LEVEL; -{$IFDEF USE_INLINE}inline;{$ENDIF} -var - Ipv4Address : IN_ADDR; - AddrPtr: PInAddr; -begin - if not INET_IS_ALIGNED_IN_ADDR(Address) then begin - Ipv4Address := PInAddr(Address)^; - AddrPtr := @Ipv4Address; - end else begin - AddrPtr := PInAddr(Address); - end; - if IN4_IS_ADDR_LINKLOCAL(AddrPtr) or - IN4_IS_ADDR_LOOPBACK(AddrPtr) then - begin - Result := ScopeLevelLink; - end else begin - Result := ScopeLevelGlobal; - end; -end; - -{ -/*++ - -Routine Description: - - Determines the scope of an IPv4 multicast address. - See RFC 2365. - -Arguments: - - Address - Supplies the IPv4 multicast address. - -Return Value: - - Returns the scope level of the multicast address. - -Caller IRQL: - - May be called at PASSIVE through DISPATCH level. - ---*/ -} -function Ipv4MulticastAddressScope(const Address : PUCHAR) : SCOPE_LEVEL; -var - Ipv4Address : IN_ADDR; - AddrPtr : PInAddr; -begin - if not INET_IS_ALIGNED_IN_ADDR(Address) then begin - Ipv4Address := PInAddr(Address)^; - AddrPtr := @Ipv4Address; - end else begin - AddrPtr := PInAddr(Address); - end; - if IN4_IS_ADDR_MC_LINKLOCAL(AddrPtr) then begin - Result := ScopeLevelLink; - end - else if IN4_IS_ADDR_MC_ADMINLOCAL(AddrPtr) then begin - Result := ScopeLevelAdmin; - end - else if IN4_IS_ADDR_MC_SITELOCAL(AddrPtr) then begin - Result := ScopeLevelSite; - end else begin - Result := ScopeLevelGlobal; - end; -end; - -{ -/*++ - -Routine Description: - - Examines an IPv4 address and determines its scope. - -Arguments: - - Address - Supplies the address to test. - -Return Value: - - Returns the scope level of the address. - -Caller IRQL: - - May be called at PASSIVE through DISPATCH level. - ---*/ -} -function Ipv4AddressScope(Address : PUChar) : SCOPE_LEVEL; -{$IFDEF USE_INLINE}inline;{$ENDIF} -var - Ipv4Address : IN_ADDR; -begin - Ipv4Address := PInAddr(Address)^; - if IN4_IS_ADDR_BROADCAST(@Ipv4Address) then begin - Result := ScopeLevelLink; - end - else if IN4_IS_ADDR_MULTICAST(@Ipv4Address) then begin - Result := Ipv4MulticastAddressScope(PUCHAR(@Ipv4Address)); - end else begin - Result := Ipv4UnicastAddressScope(PUCHAR(@Ipv4Address)); - end; -end; - -function Ipv4AddressType(Address : PUChar) : NL_ADDRESS_TYPE; -{$IFDEF USE_INLINE}inline;{$ENDIF} -var - Ipv4Address : TInAddr; -begin - Ipv4Address := PInAddr(Address)^; - if IN4_IS_ADDR_MULTICAST(@Ipv4Address) then begin - Result := NlatMulticast; - Exit; - end; - if IN4_IS_ADDR_BROADCAST(@Ipv4Address) then begin - Result := NlatBroadcast; - Exit; - end; - if IN4_IS_ADDR_UNSPECIFIED(@Ipv4Address) then begin - Result := NlatUnspecified; - Exit; - end; - // - // Following prefixes are invalid: - // 1. 0.0.0.0/8 (except 0.0.0.0/32). - // 2. 240.0.0.0/4 (except 255.255.255.255/32). - // - if ((Ipv4Address.s_addr and $000000ff) = 0) or - ((Ipv4Address.s_addr and $000000f0) = 240) then - begin - Result := NlatInvalid; - Exit; - end; - // - // Loopback and anycast addresses are treated as unicast. - // - Result := NlatUnicast; -end; - -{$IFNDEF WINCE} -// SCOPE_ID = record -// union { -// struct { -// ULONG Zone : 28; -// ULONG Level : 4; -// }; -// ULONG Value; -// }; -// Value : ULONG; -// end; - -function SCOPE_ID_GetZone(const ScopeId : SCOPE_ID) : ULONG; -begin - Result := (ScopeId.Value and $FFFFFFF0) shr 4; -end; - -procedure SCOPE_ID_SetZone(var ScopeId : SCOPE_ID; Value: ULONG); -begin - ScopeId.Value := ((Value and $0FFFFFFF) shl 4) or (ScopeId.Value and $F); -end; - -function SCOPE_ID_GetLevel(const ScopeId : SCOPE_ID) : SCOPE_LEVEL; -begin - Result := SCOPE_LEVEL(ScopeId.Value and $F); -end; - -procedure SCOPE_ID_SetLevel(var ScopeId : SCOPE_ID; Value: ULONG); -begin - ScopeId.Value := (ScopeId.Value and $FFFFFFF0) or (Value and $F); -end; - -procedure IN4_UNCANONICALIZE_SCOPE_ID(Address : PInAddr; ScopeId : PSCOPE_ID); -{$IFDEF USE_INLINE}inline;{$ENDIF} -var - ScopeLevel : SCOPE_LEVEL; -begin - ScopeLevel := Ipv4AddressScope(PUCHAR(Address)); - if IN4_IS_ADDR_LOOPBACK(Address) or (ScopeLevel = ScopeLevelGlobal) then begin - ScopeId^.Value := 0; - end; - if SCOPE_ID_GetLevel(ScopeId^) = ScopeLevel then begin - SCOPE_ID_SetLevel(ScopeId^, 0); - end; -end; -{$ENDIF} - -function IN4_IS_ADDR_6TO4ELIGIBLE(a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := (Ipv4AddressType(PUChar(a)) = NlatUnicast) and - (not (IN4_IS_ADDR_LOOPBACK(a) or - IN4_IS_ADDR_LINKLOCAL(a) or - IN4_IS_ADDR_SITELOCAL(a) or - IN4_IS_ADDR_RFC1918(a))); -end; - -function IN4_IS_UNALIGNED_ADDR_6TO4ELIGIBLE(a : PInAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -var - Ipv4Address : TInAddr; -begin - Ipv4Address := a^; - Result := IN4_IS_ADDR_6TO4ELIGIBLE(@Ipv4Address); -end; - -// -// Microsoft-specific IPv6 definitions. -// - -function IN6_PREFIX_EQUAL(const a, b : PIN6_ADDR; const len : UINT8) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -var - Bytes : UINT8; - Bits : UINT8; - Mask : UINT8; -begin - Bytes := len div 8; - Bits := len mod 8; - Mask := $ff shl (8 - Bits); - ASSERT(len <= (SizeOf(IN6_ADDR) * 8)); - Result := CompareMem(a,b,len) and ((Bits = 0) or ((a^.s6_bytes[Bytes] or Mask) = (b^.s6_bytes[Bytes] or Mask))); -end; - -function IN6_IS_ADDR_ALLNODESONNODE(a : PIN6_ADDR) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := IN6_ADDR_EQUAL(a, @in6addr_allnodesonnode); -end; - -function IN6_IS_ADDR_ALLNODESONLINK(a : PIN6_ADDR) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := IN6_ADDR_EQUAL(a, @in6addr_allnodesonlink); -end; - -function IN6_IS_ADDR_ALLROUTERSONLINK(a : PIN6_ADDR) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := IN6_ADDR_EQUAL(a, @in6addr_allroutersonlink); -end; - -function IN6_IS_ADDR_SOLICITEDNODE(a : PIN6_ADDR) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := IN6_PREFIX_EQUAL( - a, - @in6addr_solicitednodemulticastprefix, - IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH); -end; - -function IN6_IS_ADDR_ISATAP(a : PIN6_ADDR) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - // - // Disregard the u/g bit and compare the first byte of the interface id. - // - Result := ((a^.s6_words[4] and $fffd) = $0000) and (a^.s6_words[5] = $fe5e); -end; - -function IN6_IS_ADDR_6TO4(a : PIN6_ADDR) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - //C_ASSERT(IN6ADDR_6TO4PREFIX_LENGTH = RTL_BITS_OF(USHORT)); - Result := (a^.s6_words[0] = in6addr_6to4prefix.s6_words[0]); -end; - -function IN6_IS_ADDR_TEREDO(a : PIN6_ADDR) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - //C_ASSERT(IN6ADDR_TEREDOPREFIX_LENGTH == 2 * RTL_BITS_OF(USHORT)); - Result := (a^.s6_words[0] = in6addr_teredoprefix.s6_words[0]) and - (a^.s6_words[1] = in6addr_teredoprefix.s6_words[1]); -end; - -function IN6ADDR_ISV4MAPPED(a : PSOCKADDR_IN6) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - ASSERT(a^.sin6_family = AF_INET6); - Result := IN6_IS_ADDR_V4MAPPED(@a^.sin6_addr); -end; - -function IN6ADDR_ISISATAP(a : PSOCKADDR_IN6) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - ASSERT(a^.sin6_family = AF_INET6); - Result := IN6_IS_ADDR_ISATAP(@a^.sin6_addr);; -end; - -function IN6ADDR_IS6TO4(a : PSOCKADDR_IN6) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - ASSERT(a^.sin6_family = AF_INET6); - Result := IN6_IS_ADDR_6TO4(@a^.sin6_addr); -end; - -function IN6ADDR_ISTEREDO(a : PSOCKADDR_IN6) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - ASSERT(a^.sin6_family = AF_INET6); - Result := IN6_IS_ADDR_TEREDO(@a^.sin6_addr); -end; - -function IN6_GET_ADDR_V4MAPPED(Ipv6Address : PIN6_ADDR) : PUCHAR; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := PUChar(@Ipv6Address^.s6_words[6]); -end; - -function IN6_GET_ADDR_V4COMPAT(Ipv6Address : PIN6_ADDR) : PUCHAR; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := PUChar(@Ipv6Address^.s6_words[6]); -end; - -function IN6_EXTRACT_V4ADDR_FROM_ISATAP(Ipv6Address : PIN6_ADDR) : PUCHAR; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := PUChar(@Ipv6Address^.s6_words[6]); -end; - -function IN6_EXTRACT_V4ADDR_FROM_6TO4(Ipv6Address : PIN6_ADDR) : PUCHAR; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := PUChar(@Ipv6Address^.s6_words[1]); -end; - -procedure IN6_SET_ADDR_V4MAPPED(out a6 : IN6_ADDR; a4 : PInAddr ); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - a6 := in6addr_v4mappedprefix; - a6.s6_bytes[12] := a4^.S_un_b.s_b1; - a6.s6_bytes[13] := a4^.S_un_b.s_b2; - a6.s6_bytes[14] := a4^.S_un_b.s_b3; - a6.s6_bytes[15] := a4^.S_un_b.s_b4; -end; - -procedure IN6_SET_ADDR_V4COMPAT(out a6 : IN6_ADDR; a4 : PInAddr ); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - a6 := in6addr_any; - a6.s6_bytes[12] := a4^.S_un_b.s_b1; - a6.s6_bytes[13] := a4^.S_un_b.s_b2; - a6.s6_bytes[14] := a4^.S_un_b.s_b3; - a6.s6_bytes[15] := a4^.S_un_b.s_b4; -end; - -procedure IN6_SET_ADDR_SOLICITEDNODE(out Multicast : IN6_ADDR; Unicast : PIN6_ADDR); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Multicast := in6addr_solicitednodemulticastprefix; - Multicast.s6_bytes[13] := Unicast^.s6_bytes[13]; - Multicast.s6_bytes[14] := Unicast^.s6_bytes[14]; - Multicast.s6_bytes[15] := Unicast^.s6_bytes[15]; -end; - -procedure IN6_SET_ISATAP_IDENTIFIER(Ipv6Address : PIN6_ADDR; Ipv4Address : PInAddr); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if IN4_IS_ADDR_6TO4ELIGIBLE(Ipv4Address) then begin - Ipv6Address^.s6_words[4] := $0002; - end else begin - Ipv6Address^.s6_words[4] := $0000; - end; - // - // 24-bit IANA OUI 00-00-5E and the 8-bit hex value 0xFE. - // See section 6.1 of RFC 4214. - // - Ipv6Address^.s6_words[5] := $FE5E; - PInAddr(@Ipv6Address^.s6_words[6])^ := Ipv4Address^; -end; - -procedure IN6_SET_6TO4_PREFIX(Ipv6Address : PIN6_ADDR; Ipv4Address : PInAddr); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Ipv6Address^.s6_words[0] := $0220; - PInAddr(@Ipv6Address^.s6_words[1])^ := Ipv4Address^; - Ipv6Address^.s6_words[3] := $0000; -end; - -function Ipv6UnicastAddressScope(const Address : PUChar) : SCOPE_LEVEL; -{$IFDEF USE_INLINE}inline;{$ENDIF} -{*++ - -Routine Description: - - Examines a unicast address and determines its scope. - - Note that v4-compatible and 6to4 addresses are deemed to have global scope; - it is not legal to derive them from non IN4_IS_ADDR_6TO4ELIGIBLE addresses - (IPv4 loopback, link-local, site-local, and RFC-1918 addresses). - -Arguments: - - Address - Supplies an IPv6 unicast address. - -Return Value: - - Returns the scope level of the address. - -Caller IRQL: - - May be called at PASSIVE through DISPATCH level. - ---*} -var - Ipv6Address : TIn6Addr; - AddrPtr : PIn6Addr; -begin - if not INET_IS_ALIGNED_IN6_ADDR(Address) then begin - Ipv6Address := PIn6Addr(Address)^; - AddrPtr := @Ipv6Address; - end else begin - AddrPtr := PIn6Addr(Address); - end; - if IN6_IS_ADDR_LINKLOCAL(AddrPtr) or - IN6_IS_ADDR_LOOPBACK(AddrPtr) then - begin - Result := ScopeLevelLink; - end - else if IN6_IS_ADDR_SITELOCAL(AddrPtr) then begin - Result := ScopeLevelSite; - end else begin - Result := ScopeLevelGlobal; - end; -end; - -function IN6_MULTICAST_SCOPE(Address : PUCHAR ) : SCOPE_LEVEL; -{$IFDEF USE_INLINE}inline;{$ENDIF} -var - Ipv6Address : PIN6_ADDR; -begin - Ipv6Address := PIN6_ADDR(Address); - Result := SCOPE_LEVEL(Ipv6Address^.s6_bytes[1] and $f); -end; - -function Ipv6AddressScope(Address : PUCHAR ) : SCOPE_LEVEL; -{$IFDEF USE_INLINE}inline;{$ENDIF} -{*++ - -Routine Description: - - Examines an IPv6 address and determines its scope. - -Arguments: - - Address - Supplies an IPv6 address. - -Return Value: - - Returns the scope level of the address. - -Caller IRQL: - - May be called at PASSIVE through DISPATCH level. - ---*} -begin - if IN6_IS_ADDR_MULTICAST(PIn6Addr(Address)) then begin - Result := IN6_MULTICAST_SCOPE(Address); - end else begin - Result := Ipv6UnicastAddressScope(Address); - end; -end; - -function Ipv6AddressType( Address : PUCHAR) : NL_ADDRESS_TYPE; -{$IFDEF USE_INLINE}inline;{$ENDIF} -var - Ipv6Address : PIN6_ADDR; - Ipv4Address : PUCHAR; -begin - Ipv6Address := PIN6_ADDR(Address); - if IN6_IS_ADDR_MULTICAST(Ipv6Address) then begin - Result := NlatMulticast; - Exit; - end; - if IN6_IS_ADDR_UNSPECIFIED(Ipv6Address) then begin - Result := NlatUnspecified; - Exit; - end; - - // - // Extract embedded IPv4 address, if any. - // - if IN6_IS_ADDR_ISATAP(Ipv6Address) or - IN6_IS_ADDR_V4COMPAT(Ipv6Address) or - IN6_IS_ADDR_V4MAPPED(Ipv6Address) or - IN6_IS_ADDR_V4TRANSLATED(Ipv6Address) then - begin - Ipv4Address := IN6_EXTRACT_V4ADDR_FROM_ISATAP(Ipv6Address); - end - else if IN6_IS_ADDR_6TO4(Ipv6Address) then begin - Ipv4Address := IN6_EXTRACT_V4ADDR_FROM_6TO4(Ipv6Address); - end else begin - // - // Anycast and loopback addresses are treated unicast address. - // - Result := NlatUnicast; - Exit; - end; - // - // Ensure that the embedded IPv4 address is unicast. - // - if Ipv4AddressType(Ipv4Address) <> NlatUnicast then begin - Result := NlatInvalid; - Exit; - end; - Result := NlatUnicast; -end; - -{$IFNDEF WINCE} -procedure IN6_UNCANONICALIZE_SCOPE_ID(Address : PIN6_ADDR; ScopeId : PSCOPE_ID); -{$IFDEF USE_INLINE}inline;{$ENDIF} -var - ScopeLevel : SCOPE_LEVEL; -begin - ScopeLevel := Ipv6AddressScope(PUCHAR(Address)); - if IN6_IS_ADDR_LOOPBACK(Address) or (ScopeLevel = ScopeLevelGlobal) then begin - ScopeId^.Value := 0; - end; - if (SCOPE_LEVEL(ScopeId^.Value shr 28) = ScopeLevel) then begin - SCOPE_ID_SetLevel(ScopeId^, 0); - end; -end; -{$ENDIF} - -procedure IN6ADDR_SETSOCKADDR(a : PSOCKADDR_IN6; addr : PIN6_ADDR; - const scope : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; const port : USHORT ); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - a^.sin6_family := AF_INET6; - a^.sin6_port := port; - a^.sin6_flowinfo := 0; - a^.sin6_addr := addr^; - {$IFDEF WINCE} - a^.sin6_scope_id := scope; - {$ELSE} - a^.a.sin6_scope_struct := scope; - IN6_UNCANONICALIZE_SCOPE_ID(@a^.sin6_addr, @a^.a.sin6_scope_struct); - {$ENDIF} -end; - -procedure IN6ADDR_SETV4MAPPED(a6 : PSOCKADDR_IN6; a4 : PInAddr; - const scope : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; const port : USHORT ); -begin - a6^.sin6_family := AF_INET6; - a6^.sin6_port := port; - a6^.sin6_flowinfo := 0; - IN6_SET_ADDR_V4MAPPED(a6^.sin6_addr, a4); - {$IFDEF WINCE} - a6^.sin6_scope_id := scope; - {$ELSE} - a6^.a.sin6_scope_struct := scope; - IN4_UNCANONICALIZE_SCOPE_ID(a4, @a6^.a.sin6_scope_struct); - {$ENDIF} -end; - -// -// Define address-family-independent routines. -// -function INET_ADDR_EQUAL(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; - const a, b : Pointer) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (af = AF_INET6) then begin - Result := IN6_ADDR_EQUAL(PIN6_ADDR(a), PIN6_ADDR(b)); - end else begin - ASSERT(af = AF_INET); - Result := IN4_ADDR_EQUAL(PInAddr(a), PInAddr(b)); - end; -end; - -function INET_UNALIGNED_ADDR_EQUAL(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; - const a, b : Pointer ) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (af = AF_INET6) then begin - Result := IN6_ADDR_EQUAL(PIN6_ADDR(a), PIN6_ADDR(b)); - end else begin - ASSERT(af = AF_INET); - Result := IN4_UNALIGNED_ADDR_EQUAL(PInAddr(a), PInAddr(b)); - end; -end; - -function INET_IS_ADDR_UNSPECIFIED(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; - const a : Pointer) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (af = AF_INET6) then begin - Result := IN6_IS_ADDR_UNSPECIFIED(PIN6_ADDR(a)); - end else begin - ASSERT(af = AF_INET); - Result := IN4_IS_ADDR_UNSPECIFIED(PInAddr(a)); - end; -end; - -function INET_IS_UNALIGNED_ADDR_UNSPECIFIED(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; - const a : Pointer) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (af = AF_INET6) then begin - Result := IN6_IS_ADDR_LOOPBACK(PIN6_ADDR(a)); - end else begin - ASSERT(af = AF_INET); - Result := IN4_IS_ADDR_LOOPBACK(PInAddr(a)); - end; -end; - -function INET_IS_ADDR_LOOPBACK(const af: {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; - const a: Pointer): Boolean; -begin - if (af = AF_INET6) then begin - Result := IN6_IS_ADDR_LOOPBACK(PIn6Addr(a)); - end else begin - ASSERT(af = AF_INET); - Result := IN4_IS_ADDR_LOOPBACK(PInAddr(a)); - end; -end; - -function INET_IS_ADDR_BROADCAST(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; - const a : Pointer) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (af = AF_INET6) then begin - Result := False; - end else begin - ASSERT(af = AF_INET); - Result := IN4_IS_ADDR_BROADCAST(PInAddr(a)); - end; -end; - -function INET_IS_ADDR_MULTICAST(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; - const a : Pointer) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (af = AF_INET6) then begin - Result := IN6_IS_ADDR_MULTICAST(PIN6_ADDR(a)); - end else begin - ASSERT(af = AF_INET); - Result := IN4_IS_ADDR_MULTICAST(PInAddr(a)); - end; -end; - -function INET_ADDR_UNSPECIFIED(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}) : PUCHAR; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (af = AF_INET6) then begin - Result := PUCHAR(@in6addr_any); - end else begin - ASSERT(af = AF_INET); - Result := PUCHAR(@_in4addr_any); - end; -end; - -procedure INET_SET_ADDRESS( Family : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; - Address : PUCHAR; Value : PUCHAR); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (Family = AF_INET6) then begin - PIn6Addr(Address)^ := PIn6Addr(Value)^; - end else begin - ASSERT(Family = AF_INET); - PInAddr(Address)^ := PInAddr(Value)^; - end; -end; - -function INET_ADDR_LENGTH(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF} ) : Size_t; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (af = AF_INET6) then begin - Result := SizeOf(IN6_ADDR); - end else begin - ASSERT(af = AF_INET); - Result := SizeOf(IN_ADDR); - end; -end; - -function INET_SOCKADDR_LENGTH(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}) : Size_t; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (af = AF_INET6) then begin - Result := SizeOf(SOCKADDR_IN6); - end else begin - ASSERT(af = AF_INET); - Result := SizeOf(SOCKADDR_IN); - end; -end; -// -function IN6ADDR_ANY_INIT: TIn6Addr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} -end; - -function IN6ADDR_LOOPBACK_INIT: TIn6Addr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} - Result.s6_bytes[15] := 1; -end; - -function IN6ADDR_ALLNODESONNODE_INIT : TIn6Addr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} - - Result.s6_bytes[0] := $ff; - Result.s6_bytes[1] := $01; - Result.s6_bytes[15] := $01; -end; - -function IN6ADDR_ALLNODESONLINK_INIT : TIn6Addr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} - - Result.s6_bytes[0] := $ff; - Result.s6_bytes[1] := $02; - Result.s6_bytes[15] := $01; -end; - -function IN6ADDR_ALLROUTERSONLINK_INIT : TIn6Addr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} - - Result.s6_bytes[0] := $ff; - Result.s6_bytes[1] := $02; - Result.s6_bytes[15] := $02; -end; - -function IN6ADDR_ALLMLDV2ROUTERSONLINK_INIT : TIn6Addr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} - - Result.s6_bytes[0] := $ff; - Result.s6_bytes[1] := $02; - Result.s6_bytes[15] := $16; -end; - -function IN6ADDR_TEREDOINITIALLINKLOCALADDRESS_INIT : TIn6Addr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} - - Result.s6_bytes[0] := $fe; - Result.s6_bytes[1] := $80; - - Result.s6_bytes[10] := $ff; - Result.s6_bytes[11] := $ff; - Result.s6_bytes[12] := $ff; - Result.s6_bytes[13] := $ff; - Result.s6_bytes[14] := $ff; - Result.s6_bytes[15] := $fe; -end; - -// -// The old link local address for XP-SP2/Win2K3 machines. -// -function IN6ADDR_TEREDOOLDLINKLOCALADDRESSXP_INIT : TIn6Addr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} - - Result.s6_bytes[0] := $fe; - Result.s6_bytes[1] := $80; - - Result.s6_bytes[10] := Ord('T'); - Result.s6_bytes[11] := Ord('E'); - Result.s6_bytes[12] := Ord('R'); - Result.s6_bytes[13] := Ord('E'); - Result.s6_bytes[14] := Ord('D'); - Result.s6_bytes[15] := Ord('O'); -end; - -// -// The old link local address for Vista Beta-2 and earlier machines. -// -function IN6ADDR_TEREDOOLDLINKLOCALADDRESSVISTA_INIT : TIn6Addr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} - - Result.s6_bytes[0] := $fe; - Result.s6_bytes[1] := $80; - - Result.s6_bytes[10] := $ff; - Result.s6_bytes[11] := $ff; - Result.s6_bytes[12] := $ff; - Result.s6_bytes[13] := $ff; - Result.s6_bytes[14] := $ff; - Result.s6_bytes[15] := $ff; -end; - -function IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_INIT : IN6_ADDR; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} - Result.s6_bytes[0] := $FF; - Result.s6_bytes[1] := $02; - Result.s6_bytes[11] := $01; - Result.s6_bytes[12] := $ff; -end; - -function IN6ADDR_V4MAPPEDPREFIX_INIT : TIn6Addr; -begin - System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} - Result.s6_bytes[10] := $ff; - Result.s6_bytes[11] := $ff; -end; - -function IN6ADDR_6TO4PREFIX_INIT : TIn6Addr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} - Result.s6_bytes[0] := $20; - Result.s6_bytes[1] := $02; -end; - -function IN6ADDR_TEREDOPREFIX_INIT : TIn6Addr; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} - Result.s6_bytes[0] := $20; - Result.s6_bytes[1] := $01; -end; - -procedure IN6ADDR_SETANY(sa: PSockAddrIn6); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if sa <> nil then begin - sa^.sin6_family := AF_INET6; - sa^.sin6_port := 0; - sa^.sin6_flowinfo := 0; - PULONG(@sa^.sin6_addr.s6_bytes[0])^ := 0; - PULONG(@sa^.sin6_addr.s6_bytes[4])^ := 0; - PULONG(@sa^.sin6_addr.s6_bytes[8])^ := 0; - PULONG(@sa^.sin6_addr.s6_bytes[12])^ := 0; - end; -end; - -procedure IN6ADDR_SETLOOPBACK(sa: PSockAddrIn6); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if sa <> nil then begin - sa^.sin6_family := AF_INET6; - sa^.sin6_port := 0; - sa^.sin6_flowinfo := 0; - PULONG(@sa^.sin6_addr.s6_bytes[0])^ := 0; - PULONG(@sa^.sin6_addr.s6_bytes[4])^ := 0; - PULONG(@sa^.sin6_addr.s6_bytes[8])^ := 0; - PULONG(@sa^.sin6_addr.s6_bytes[12])^ := 1; - end; -end; - -function IN6ADDR_ISANY(sa: PSockAddrIn6): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if sa <> nil then begin - Result := (sa^.sin6_family = AF_INET6) and - (PULONG(@sa^.sin6_addr.s6_bytes[0])^ = 0) and - (PULONG(@sa^.sin6_addr.s6_bytes[4])^ = 0) and - (PULONG(@sa^.sin6_addr.s6_bytes[8])^ = 0) and - (PULONG(@sa^.sin6_addr.s6_bytes[12])^ = 0); - end else begin - Result := False; - end; -end; - -function IN6ADDR_ISLOOPBACK(sa: PSockAddrIn6): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if sa <> nil then begin - Result := (sa^.sin6_family = AF_INET6) and - (PULONG(@sa^.sin6_addr.s6_bytes[0])^ = 0) and - (PULONG(@sa^.sin6_addr.s6_bytes[4])^ = 0) and - (PULONG(@sa^.sin6_addr.s6_bytes[8])^ = 0) and - (PULONG(@sa^.sin6_addr.s6_bytes[12])^ = 1); - end else begin - Result := False; - end; -end; - -function IN6_ADDR_EQUAL(const a: PIn6Addr; const b: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := SysUtils.CompareMem(a, b, SIZE_TIN6ADDR); -end; - -function IN6_IS_ADDR_UNSPECIFIED(const a: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := IN6_ADDR_EQUAL(a, @in6addr_any); -end; - -function IN6_IS_ADDR_LOOPBACK(const a: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := IN6_ADDR_EQUAL(a, @in6addr_loopback); -end; - -function IN6_IS_ADDR_MULTICAST(const a: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if a <> nil then begin - Result := (a^.s6_bytes[0] = $FF); - end else begin - Result := False; - end; -end; - -function IN6_IS_ADDR_EUI64(const a : PIn6Addr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} - // - // Format prefixes 001 through 111, except for multicast. - // -begin - if a <> nil then begin - Result := ((a^.s6_bytes[0] and $e0) <> 0 ) and (not IN6_IS_ADDR_MULTICAST(a)); - end else begin - Result := False; - end; -end; - -function IN6_IS_ADDR_SUBNET_ROUTER_ANYCAST(const a : PIn6Addr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -// -// Is this the subnet router anycast address? -// See RFC 2373. -// -begin - if a <> nil then begin - Result := IN6_IS_ADDR_EUI64(a) and (a^.s6_words[4] = 0) and - (a^.s6_words[5] = 0) and (a^.s6_words[6]=0) and (a^.s6_words[7]=0); - end else begin - Result := False; - end; -end; - -function IN6_IS_ADDR_SUBNET_RESERVED_ANYCAST(const a: PIn6Addr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if a <> nil then begin - Result := IN6_IS_ADDR_EUI64(a) and (a^.s6_words[4] = $fffd) and - (a^.s6_words[5] = $ffff) and (a^.s6_words[6] = $ffff) and - ((a^.s6_words[7] and $80ff) = $80ff); - end else begin - Result := False; - end; -end; - -function IN6_IS_ADDR_ANYCAST(const a: PIn6Addr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if a <> nil then begin - Result := IN6_IS_ADDR_SUBNET_RESERVED_ANYCAST(a) or IN6_IS_ADDR_SUBNET_ROUTER_ANYCAST(a); - end else begin - Result := False; - end; -end; - -function IN6_IS_ADDR_LINKLOCAL(const a: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if a <> nil then begin - Result := (a^.s6_bytes[0] = $FE) and ((a^.s6_bytes[1] and $C0) = $80); - end else begin - Result := False; - end; -end; - -function IN6_IS_ADDR_SITELOCAL(const a: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if a <> nil then begin - Result := (a^.s6_bytes[0] = $FE) and ((a^.s6_bytes[1] and $C0) = $C0); - end else begin - Result := False; - end; -end; - -function IN6_IS_ADDR_V4MAPPED(const a: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if a <> nil then begin - Result := (a^.s6_words[0] = 0) and - (a^.s6_words[1] = 0) and - (a^.s6_words[2] = 0) and - (a^.s6_words[3] = 0) and - (a^.s6_words[4] = 0) and - (a^.s6_words[5] = $FFFF); - end else begin - Result := False; - end; -end; - -function IN6_IS_ADDR_V4COMPAT(const a: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if a <> nil then begin - Result := (a^.s6_words[0] = 0) and - (a^.s6_words[1] = 0) and - (a^.s6_words[2] = 0) and - (a^.s6_words[3] = 0) and - (a^.s6_words[4] = 0) and - (a^.s6_words[5] = 0) and - not ((a^.s6_words[6] = 0) and (a^.s6_bytes[14] = 0) and - ((a^.s6_bytes[15] = 0) or (a^.s6_bytes[15] = 1))); - end else begin - Result := False; - end; -end; - -function IN6_IS_ADDR_V4TRANSLATED(const a: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := ((a^.s6_words[0] = 0) and - (a^.s6_words[1] = 0) and - (a^.s6_words[2] = 0) and - (a^.s6_words[3] = 0) and - (a^.s6_words[4] = $ffff) and - (a^.s6_words[5] = 0)); -end; - -procedure INETADDR_SETSOCKADDR(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; - a : PSOCKADDR; addr : Pointer; const scope : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; const port : USHORT); -{$IFDEF USE_INLINE}inline;{$ENDIF} -var - addr4 : IN_ADDR; -begin - if (af = AF_INET6) then begin - IN6ADDR_SETSOCKADDR(PSOCKADDR_IN6( a), PIN6_ADDR( addr ), scope, port); - end else begin - addr4 := PInAddr(addr)^; - ASSERT(af = AF_INET); - IN4ADDR_SETSOCKADDR(PSockAddrIn(a),PInAddr( @addr4), port); - end; -end; - -procedure INETADDR_SETANY(a : PSOCKADDR); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (a^.sa_family = AF_INET6) then begin - IN6ADDR_SETANY(PSOCKADDR_IN6(a)); - end else begin - ASSERT(a^.sa_family = AF_INET); - IN4ADDR_SETANY(PSockAddrIn(a)); - end; -end; - -procedure INETADDR_SETLOOPBACK(a : PSOCKADDR); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (a^.sa_family = AF_INET6) then begin - IN6ADDR_SETLOOPBACK(PSOCKADDR_IN6(a)); - end else begin - ASSERT(a^.sa_family = AF_INET); - IN4ADDR_SETLOOPBACK(PSockAddrIn(a)); - end; -end; - -function INETADDR_ISANY(const a : PSOCKADDR) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (a^.sa_family = AF_INET6) then begin - Result := IN6ADDR_ISANY(PSOCKADDR_IN6(a)); - end else begin - ASSERT(a^.sa_family = AF_INET); - Result := IN4ADDR_ISANY(PSockAddrIn(a)); - end; -end; - -function INETADDR_ISLOOPBACK(const a : PSockAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (a^.sa_family = AF_INET6) then begin - Result := IN6ADDR_ISLOOPBACK(PSOCKADDR_IN6(a)); - end else begin - ASSERT(a^.sa_family = AF_INET); - Result := IN4ADDR_ISLOOPBACK(PSockAddrIn(a)); - end; -end; - -function INETADDR_ISV4MAPPED(const a : PSockAddr) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (a^.sa_family = AF_INET6) then begin - Result := IN6ADDR_ISV4MAPPED(PSOCKADDR_IN6(a)); - end else begin - Result := False; - end; -end; - -function NL_ADDR_EQUAL(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; - const sa : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; - const aa : PUCHAR; - const sb : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; - const ab : PUCHAR) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := ((sa{$IFNDEF WINCE}.Value{$ENDIF} = sb{$IFNDEF WINCE}.Value{$ENDIF}) and - INET_ADDR_EQUAL(af, aa, ab)); -end; - -function NL_IS_ADDR_UNSPECIFIED(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; - const s : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; - const a : PUCHAR) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := ((s{$IFNDEF WINCE}.Value{$ENDIF} = 0) and INET_IS_ADDR_UNSPECIFIED(af, a)); -end; - -function IN6ADDR_ISEQUAL(const a,b : PSOCKADDR_IN6 ) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - ASSERT(a^.sin6_family = AF_INET6); - Result := (a^.{$IFNDEF WINCE}a.{$ENDIF}sin6_scope_id = b^.{$IFNDEF WINCE}a.{$ENDIF}sin6_scope_id) and - IN6_ADDR_EQUAL(@a^.sin6_addr, @b^.sin6_addr); -end; - -function INETADDR_ISEQUAL(const a,b : PSOCKADDR) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (a^.sa_family = AF_INET6) then begin - Result := (b^.sa_family = AF_INET6) and - IN6ADDR_ISEQUAL(PSOCKADDR_IN6(a), PSOCKADDR_IN6(b)); - end else begin - ASSERT(a^.sa_family = AF_INET); - Result := (b^.sa_family = AF_INET) and - IN4ADDR_ISEQUAL(PSOCKADDR_IN(a), PSOCKADDR_IN(b)); - end; -end; - -function IN6ADDR_ISUNSPECIFIED(a : PSOCKADDR_IN6) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - ASSERT(a^.sin6_family = AF_INET6); - Result := (a^.{$IFNDEF WINCE}a.{$ENDIF}sin6_scope_id = 0) and - IN6_IS_ADDR_UNSPECIFIED(@a^.sin6_addr); -end; - -function INETADDR_ISUNSPECIFIED(const a : PSOCKADDR) : Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (a^.sa_family = AF_INET6) then begin - Result := IN6ADDR_ISUNSPECIFIED( PSOCKADDR_IN6(a)); - end else begin - ASSERT(a^.sa_family = AF_INET); - Result := IN4ADDR_ISUNSPECIFIED(PSOCKADDR_IN(a)); - end; -end; - -function INETADDR_SCOPE_ID(const a : PSOCKADDR) : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (a^.sa_family = AF_INET6) then begin - Result := PSOCKADDR_IN6(a)^.{$IFDEF WINCE}sin6_scope_id{$ELSE}a.sin6_scope_struct{$ENDIF}; - end else begin - ASSERT(a^.sa_family = AF_INET); - Result := IN4ADDR_SCOPE_ID(PSOCKADDR_IN(a)); - end; -end; - -function INETADDR_PORT(const a : PSOCKADDR) : USHORT; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (a^.sa_family = AF_INET6) then begin - Result := PSOCKADDR_IN6(a)^.sin6_port; - end else begin - ASSERT(a^.sa_family = AF_INET); - Result := PSOCKADDR_IN(a)^.sin_port; - end; -end; - -function INETADDR_ADDRESS(const a : PSOCKADDR) : PUCHAR; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (a^.sa_family = AF_INET6) then begin - Result := PUCHAR(@(PSOCKADDR_IN6(a))^.sin6_addr); - end else begin - ASSERT(a^.sa_family = AF_INET); - Result := PUCHAR(@(PSOCKADDR_IN(a))^.sin_addr); - end; -end; - -procedure INETADDR_SET_PORT(const a : PSOCKADDR; Port : USHORT); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - a^.sin_port := Port; -end; - -procedure INETADDR_SET_ADDRESS(const a : PSOCKADDR; Address : PUCHAR); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (a^.sa_family = AF_INET6) then begin - PSOCKADDR_IN6(a)^.sin6_addr := PIN6_ADDR(Address)^; - end else begin - ASSERT(PSOCKADDR_IN(a)^.sa_family = AF_INET); - PSOCKADDR_IN(a)^.sin_addr := PInAddr(Address)^; - end; -end; - -{$IFNDEF WINCE} -procedure INET_UNCANONICALIZE_SCOPE_ID( AddressFamily : ADDRESS_FAMILY; - Address : PUCHAR; ScopeId : PSCOPE_ID); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if (AddressFamily = AF_INET6) then begin - IN6_UNCANONICALIZE_SCOPE_ID(PIn6Addr( Address), ScopeId); - end else begin - IN4_UNCANONICALIZE_SCOPE_ID(PInAddr( Address), ScopeId); - end; -end; -{$ENDIF} - -function IN6_IS_ADDR_MC_NODELOCAL(const a: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if a <> nil then begin - Result := IN6_IS_ADDR_MULTICAST(a) and ((a^.s6_bytes[1] and $F) = 1); - end else begin - Result := False; - end; -end; - -function IN6_IS_ADDR_MC_LINKLOCAL(const a: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if a <> nil then begin - Result := IN6_IS_ADDR_MULTICAST(a) and ((a^.s6_bytes[1] and $F) = 2); - end else begin - Result := False; - end; -end; - -function IN6_IS_ADDR_MC_SITELOCAL(const a: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if a <> nil then begin - Result := IN6_IS_ADDR_MULTICAST(a) and ((a^.s6_bytes[1] and $F) = 5); - end else begin - Result := False; - end; -end; - -function IN6_IS_ADDR_MC_ORGLOCAL(const a: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if a <> nil then begin - Result := IN6_IS_ADDR_MULTICAST(a) and ((a^.s6_bytes[1] and $F) = 8); - end else begin - Result := False; - end; -end; - -function IN6_IS_ADDR_MC_GLOBAL(const a: PIn6Addr): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if a <> nil then begin - Result := IN6_IS_ADDR_MULTICAST(a) and ((a^.s6_bytes[1] and $F) = $E); - end else begin - Result := False; - end; -end; - -procedure IN6_SET_ADDR_UNSPECIFIED(a : PIN6_ADDR); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(a^.s6_bytes, SizeOf(IN6_ADDR), 0 ); -end; - -procedure IN6_SET_ADDR_LOOPBACK(a : PIN6_ADDR); -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - System.FillChar(a^.s6_bytes, SizeOf(IN6_ADDR), 0 ); - a^.s6_bytes[15] := 1; -end; - -// A macro convenient for setting up NETBIOS SOCKADDRs. -procedure SET_NETBIOS_SOCKADDR(snb : PSockAddrNB; const SnbType : Word; const Name : PIdAnsiChar; const Port : TIdAnsiChar); -var - len : {$IFDEF FPC}sizeint{$ELSE}DWord{$ENDIF}; -begin - if snb <> nil then begin - snb^.snb_family := AF_NETBIOS; - snb^.snb_type := SnbType; - {$IFDEF NEXTGEN} - len := Length(Name); - {$ELSE} - len := {$IFDEF HAS_AnsiStrings_StrLen}AnsiStrings.{$ENDIF}StrLen(Name); - {$ENDIF} - if len >= NETBIOS_NAME_LENGTH-1 then begin - System.Move(Name^, snb^.snb_name, NETBIOS_NAME_LENGTH-1); - end else begin - if len > 0 then begin - System.Move(Name^, snb^.snb_name, LongInt(len)); - end; - System.FillChar((PIdAnsiChar(@snb^.snb_name)+len)^, NETBIOS_NAME_LENGTH-1-len, ' '); {Do not Localize} - end; - snb^.snb_name[NETBIOS_NAME_LENGTH-1] := Port; - end; -end; - -function GROUP_FILTER_SIZE(const numsrc : DWord) : PtrUInt; -{$IFDEF USE_INLINE}inline;{$ENDIF} -begin - Result := (SIZE_GROUP_FILTER - SIZE_SOCKADDR_STORAGE) + (numsrc * SIZE_SOCKADDR_STORAGE); -end; - -initialization - scopeid_unspecified := SCOPEID_UNSPECIFIED_INIT; - - _in4addr_any := IN4ADDR_ANY_INIT; - _in4addr_loopback := IN4ADDR_LOOPBACK_INIT; - _in4addr_broadcast := IN4ADDR_BROADCAST_INIT; - in4addr_allnodesonlink := IN4ADDR_ALLNODESONLINK_INIT; - in4addr_allroutersonlink := IN4ADDR_ALLROUTERSONLINK_INIT; - in4addr_alligmpv3routersonlink := IN4ADDR_ALLIGMPV3ROUTERSONLINK_INIT; - in4addr_allteredohostsonlink := IN4ADDR_ALLTEREDONODESONLINK_INIT; - in4addr_linklocalprefix := IN4ADDR_LINKLOCALPREFIX_INIT; - in4addr_multicastprefix := IN4ADDR_MULTICASTPREFIX_INIT; - - in6addr_any := IN6ADDR_ANY_INIT; - in6addr_loopback := IN6ADDR_LOOPBACK_INIT; - in6addr_allnodesonnode := IN6ADDR_ALLNODESONNODE_INIT; - in6addr_allnodesonlink := IN6ADDR_ALLNODESONLINK_INIT; - in6addr_allroutersonlink := IN6ADDR_ALLROUTERSONLINK_INIT; - in6addr_solicitednodemulticastprefix := IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_INIT; - in6addr_v4mappedprefix := IN6ADDR_V4MAPPEDPREFIX_INIT; - in6addr_6to4prefix := IN6ADDR_6TO4PREFIX_INIT; - in6addr_teredoprefix := IN6ADDR_TEREDOPREFIX_INIT; - - InitializeStubs; - -{$ENDIF} - -end. - +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Log: 56400: IdWinsock2.pas + + Rev 1.0 2004.02.03 3:14:50 PM czhower + Move and updates + + + Rev 1.15 1/3/2004 12:41:48 AM BGooijen + Fixed WSAEnumProtocols + + + Rev 1.14 10/15/2003 1:20:48 PM DSiders + Added localization comments. + + + Rev 1.13 2003.10.01 11:16:38 AM czhower + .Net + + + Rev 1.12 9/24/2003 09:18:24 AM JPMugaas + Fixed an AV that happened when a stack call was made. + + + Rev 1.11 24/9/2003 3:11:34 PM SGrobety + First wave of fixes for compiling in dotnet. Still not functional, needed to + unlock to fix critical failure in Delphi code + + + Rev 1.10 9/22/2003 11:20:14 PM EHill + Removed assembly code and replaced with defined API stubs. + + + Rev 1.9 7/7/2003 12:55:10 PM BGooijen + Fixed ServiceQueryTransmitFile, and made it public + + + Rev 1.8 2003.05.09 10:59:30 PM czhower + + + Rev 1.7 4/19/2003 10:28:24 PM BGooijen + some functions were linked to the wrong dll + + + Rev 1.6 4/19/2003 11:14:40 AM JPMugaas + Made some tentitive wrapper functions for some things that should be called + from the Service Provider. Fixed WSARecvMsg. + + + Rev 1.5 4/19/2003 02:29:26 AM JPMugaas + Added TransmitPackets API function call. Note that this is only supported in + Windows XP or later. + + + Rev 1.4 4/19/2003 12:22:58 AM BGooijen + fixed: ConnectEx DisconnectEx WSARecvMsg + + + Rev 1.3 4/18/2003 12:00:58 AM JPMugaas + added + ConnectEx + DisconnectEx + WSARecvMsg + + Changed header procedure type names to be consistant with the old + IdWinsock.pas in Indy 8.0 and with the rest of the unit. + + + Rev 1.2 3/22/2003 10:01:26 PM JPMugaas + WSACreateEvent couldn't load because of a space. + + + Rev 1.1 3/22/2003 09:46:54 PM JPMugaas + It turns out that we really do not need the TGUID defination in the header at + all. It's defined in D4, D5, D6, and D7. + + + Rev 1.0 11/13/2002 09:02:54 AM JPMugaas +} +//------------------------------------------------------------- +// +// Borland Delphi Runtime Library +// interface unit +// +// Portions created by Microsoft are +// Copyright (C) 1995-1999 Microsoft Corporation. +// All Rights Reserved. +// +// The original file is: Winsock2.h from CBuilder5 distribution. +// The original Pascal code is: winsock2.pas, released 03 Mar 2001. +// The initial developer of the Pascal code is Alex Konshin +// (alexk@mtgroup.ru). +//------------------------------------------------------------- + + +{ Winsock2.h -- definitions to be used with the WinSock 2 DLL and WinSock 2 applications. + This header file corresponds to version 2.2.x of the WinSock API specification. + This file includes parts which are Copyright (c) 1982-1986 Regents + of the University of California. All rights reserved. + The Berkeley Software License Agreement specifies the terms and + conditions for redistribution. } + +// Note that the original unit is copyrighted by the original author and I did obtain his +// permission to port and use this as part of Indy - J. Peter Mugaas + +// 2002-01-28 - Hadi Hariri. Fixes for C++ Builder. Thanks to Chuck Smith. +// 2001 - Oct -25 J. Peter Mugaas +// Made adjustments for Indy usage by +// 1) including removing Trace logging +// 2) renaming and consolidating some .INC files as appropriate +// 3) modifying the unit to follow Indy conventions +// 4) Adding TransmitFile support for the HTTP Server +// 5) Removing all static loading code that was IFDEF'ed. {Do not Localize} +// 2001 - Mar - 1 Alex Konshin +// Revision 3 +// converted by Alex Konshin, mailto:alexk@mtgroup.ru +// revision 3, March,1 2001 + + +unit IdWinsock2; + +interface + +{$I IdCompilerDefines.inc} + +{ +Important!!! + +With the ARM architecture, you may get an EBusError exception sating that +data is misaligned. Sometimes, that architecture does not have the ability to +read misaligned data. On an i386 and x86_64 architecure, you can do this but it +is inefficient. For the ARM chip architecture, we have to make sure our records +are aligned on a 4 byte boundery. See: + +http://wiki.lazarus.freepascal.org/Windows_CE_Development_Notes + +This is not necessary and can cause problems +when using the standard Win32 API (win32 and win64) where records are packed +instead of aligned. + +To deal with this, I use the FPC predefined FPC_REQUIRES_PROPER_ALIGNMENT. + +} + +{$IFDEF WINDOWS} + +{$I IdRangeCheckingOff.inc} + +{$IFDEF FPC} + {$IFDEF WIN32} + {$ALIGN OFF} + {$ELSE} + //It turns out that Win64 and WinCE require record alignment + {$PACKRECORDS C} + {$ENDIF} +{$ELSE} + {$IFDEF WIN64} + {$ALIGN ON} + {$MINENUMSIZE 4} + {$ELSE} + {$MINENUMSIZE 4} + {$IFDEF REQUIRES_PROPER_ALIGNMENT} + {$ALIGN ON} + {$ELSE} + {$ALIGN OFF} + {$WRITEABLECONST OFF} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +uses + IdException, IdGlobal, SysUtils, Windows; + +type + EIdWinsockStubError = class(EIdException) + protected + FWin32Error : DWORD; + FWin32ErrorMessage : String; + FTitle : String; + public + constructor Build(AWin32Error: DWORD; const ATitle: String; AArgs: array of const); + property Win32Error : DWORD read FWin32Error; + property Win32ErrorMessage : String read FWin32ErrorMessage; + property Title : String read FTitle; + end; + +const + {$IFDEF WINCE} + WINSOCK2_DLL = 'ws2.dll'; {Do not Localize} + {$ELSE} + WINSOCK2_DLL = 'WS2_32.DLL'; {Do not Localize} + MSWSOCK_DLL = 'MSWSOCK.DLL'; {Do not Localize} + {$ENDIF} + {$EXTERNALSYM WINSOCK_VERSION} + WINSOCK_VERSION = $0202; + +{$DEFINE WS2_DLL_FUNC_VARS} +{$DEFINE INCL_WINSOCK_API_PROTOTYPES} +{$DEFINE INCL_WINSOCK_API_TYPEDEFS} + +type + {$EXTERNALSYM u_char} + u_char = Byte; + {$EXTERNALSYM u_short} + u_short = Word; + {$EXTERNALSYM u_int} + u_int = DWord; //Integer; + {$EXTERNALSYM u_long} + u_long = DWORD; +// The new type to be used in all instances which refer to sockets. + {$EXTERNALSYM TSocket} + TSocket = PtrUInt; + {$EXTERNALSYM WSAEVENT} + WSAEVENT = THandle; + {$NODEFINE PWSAEVENT} + PWSAEVENT = ^WSAEVENT; + {$EXTERNALSYM LPWSAEVENT} + LPWSAEVENT = PWSAEVENT; + + // Must define the following types because the older versions of Delphi do not support them + + {$IFNDEF HAS_ULONG_PTR} + {$EXTERNALSYM ULONG_PTR} + ULONG_PTR = PtrUInt; + {$ENDIF} + + {$IFNDEF HAS_DWORD_PTR} + {$EXTERNALSYM DWORD_PTR} + DWORD_PTR = PtrUInt; + {$ENDIF} + + {$IFNDEF HAS_USHORT} + {$EXTERNALSYM USHORT} + USHORT = UInt16; + {$ENDIF} + + {$IFNDEF HAS_PVOID} + {$EXTERNALSYM PVOID} + PVOID = Pointer; + {$ENDIF} + + {$IFNDEF HAS_ULONG64} + {$EXTERNALSYM ULONG64} + ULONG64 = UInt64; + {$ENDIF} + + {$IFNDEF HAS_LONG} + {$EXTERNALSYM LONG} + LONG = Longint; + {$ENDIF} + + {$IFNDEF HAS_ULONGLONG} + {$EXTERNALSYM ULONGLONG} + ULONGLONG = UInt64; + {$ENDIF} + +const + {$EXTERNALSYM FD_SETSIZE} + FD_SETSIZE = 64; + +// the following emits are a workaround to the name conflicts +// with the winsock2 header files +(*$HPPEMIT '#include '*) +(*$HPPEMIT '#include '*) +(*$HPPEMIT '#include '*) +(*$HPPEMIT '// workaround for a bug in wsnwlink.h where a couple of commented lines are not terminated property'*) +(*$HPPEMIT '#pragma option push -C-'*) +(*$HPPEMIT '#include '*) +(*$HPPEMIT '#pragma option pop'*) +(*$HPPEMIT '#include '*) +(*$HPPEMIT '#include '*) +(*$HPPEMIT '#include '*) +(*$HPPEMIT ''*) + +{$IFDEF HAS_DIRECTIVE_HPPEMIT_NAMESPACE} +{$HPPEMIT OPENNAMESPACE} +{$ELSE} +(*$HPPEMIT 'namespace Idwinsock2'*) +(*$HPPEMIT '{'*) +{$ENDIF} +(*$HPPEMIT ' typedef fd_set *PFDSet;'*) // due to name conflict with procedure FD_SET +(*$HPPEMIT ' typedef fd_set TFDSet;'*) // due to name conflict with procedure FD_SET +{$IFDEF HAS_DIRECTIVE_HPPEMIT_NAMESPACE} +{$HPPEMIT CLOSENAMESPACE} +{$ELSE} +(*$HPPEMIT '}'*) +{$ENDIF} +(*$HPPEMIT ''*) + +type + {$NODEFINE PFDSet} + PFDSet = ^TFDSet; + {$NODEFINE TFDSet} + TFDSet = record + fd_count: u_int; + fd_array: array[0..FD_SETSIZE-1] of TSocket; + end; + + {$EXTERNALSYM timeval} + timeval = record + tv_sec: Longint; + tv_usec: Longint; + end; + {$NODEFINE TTimeVal} + TTimeVal = timeval; + {$NODEFINE PTimeVal} + PTimeVal = ^TTimeVal; + +const + {$EXTERNALSYM IOCPARM_MASK} + IOCPARM_MASK = $7F; + {$EXTERNALSYM IOC_VOID} + IOC_VOID = $20000000; + {$EXTERNALSYM IOC_OUT} + IOC_OUT = $40000000; + {$EXTERNALSYM IOC_IN} + IOC_IN = $80000000; + {$EXTERNALSYM IOC_INOUT} + IOC_INOUT = (IOC_IN or IOC_OUT); + +// get # bytes to read + {$EXTERNALSYM FIONREAD} + FIONREAD = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('f') shl 8) or 127; {Do not Localize} +// set/clear non-blocking i/o + {$EXTERNALSYM FIONBIO} + FIONBIO = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('f') shl 8) or 126; {Do not Localize} +// set/clear async i/o + {$EXTERNALSYM FIOASYNC} + FIOASYNC = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('f') shl 8) or 125; {Do not Localize} + +// Socket I/O Controls + +// set high watermark + {$EXTERNALSYM SIOCSHIWAT} + SIOCSHIWAT = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('s') shl 8) or 0; {Do not Localize} +// get high watermark + {$EXTERNALSYM SIOCGHIWAT} + SIOCGHIWAT = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('s') shl 8) or 1; {Do not Localize} +// set low watermark + {$EXTERNALSYM SIOCSLOWAT} + SIOCSLOWAT = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('s') shl 8) or 2; {Do not Localize} +// get low watermark + {$EXTERNALSYM SIOCGLOWAT} + SIOCGLOWAT = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('s') shl 8) or 3; {Do not Localize} +// at oob mark? + {$EXTERNALSYM SIOCATMARK} + SIOCATMARK = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('s') shl 8) or 7; {Do not Localize} + + +// Structures returned by network data base library, taken from the +// BSD file netdb.h. All addresses are supplied in host order, and +// returned in network order (suitable for use in system calls). +type + {$EXTERNALSYM hostent} + hostent = record + h_name: PIdAnsiChar; // official name of host + h_aliases: PPIdAnsiChar; // alias list + h_addrtype: short; // host address type + h_length: short; // length of address + case Byte of + 0: (h_address_list: PPIdAnsiChar); + 1: (h_addr: PIdAnsiChar); // address, for backward compat + end; + {$NODEFINE THostEnt} + THostEnt = hostent; + {$NODEFINE PHostEnt} + PHostEnt = ^THostEnt; + +// It is assumed here that a network number +// fits in 32 bits. + {$EXTERNALSYM netent} + netent = record + n_name: PIdAnsiChar; // official name of net + n_aliases: PPIdAnsiChar; // alias list + n_addrtype: short; // net address type + n_net: u_long; // network # + end; + {$NODEFINE TNetEnt} + TNetEnt = netent; + {$NODEFINE PNetEnt} + PNetEnt = ^TNetEnt; + + {$EXTERNALSYM servent} + servent = record + s_name: PIdAnsiChar; // official service name + s_aliases: PPIdAnsiChar; // alias list + {$IFDEF _WIN64} + s_proto: PIdAnsiChar; // protocol to use + s_port: short; // port # + {$ELSE} + s_port: short; // port # + s_proto: PIdAnsiChar; // protocol to use + {$ENDIF} + end; + {$NODEFINE TServEnt} + TServEnt = servent; + {$NODEFINE PServEnt} + PServEnt = ^TServEnt; + + {$EXTERNALSYM protoent} + protoent = record + p_name: PIdAnsiChar; // official protocol name + p_aliases: PPIdAnsiChar; // alias list + p_proto: short; // protocol # + end; + {$NODEFINE TProtoEnt} + TProtoEnt = protoent; + {$NODEFINE PProtoEnt} + PProtoEnt = ^TProtoEnt; + {$EXTERNALSYM NL_ADDRESS_TYPE} + NL_ADDRESS_TYPE = ( + NlatUnspecified, + NlatUnicast, + NlatAnycast, + NlatMulticast, + NlatBroadcast, + NlatInvalid); +// Constants and structures defined by the internet system, +// Per RFC 790, September 1981, taken from the BSD file netinet/in.h. +const + +// Protocols + {$EXTERNALSYM IPPROTO_IP} + IPPROTO_IP = 0; // dummy for IP + {$EXTERNALSYM IPPROTO_ICMP} + IPPROTO_ICMP = 1; // control message protocol + {$EXTERNALSYM IPPROTO_IGMP} + IPPROTO_IGMP = 2; // group management protocol + {$EXTERNALSYM IPPROTO_GGP} + IPPROTO_GGP = 3; // gateway^2 (deprecated) + {$EXTERNALSYM IPPROTO_TCP} + IPPROTO_TCP = 6; // TCP + {$EXTERNALSYM IPPROTO_PUP} + IPPROTO_PUP = 12; // pup + {$EXTERNALSYM IPPROTO_UDP} + IPPROTO_UDP = 17; // UDP - user datagram protocol + {$EXTERNALSYM IPPROTO_IDP} + IPPROTO_IDP = 22; // xns idp + {$EXTERNALSYM IPPROTO_ND} + IPPROTO_ND = 77; // UNOFFICIAL net disk proto + + {$EXTERNALSYM IPPROTO_IPV6} + IPPROTO_IPV6 = 41; // IPv6 + {$EXTERNALSYM IPPROTO_ICLFXBM} + IPPROTO_ICLFXBM = 78; + + {$EXTERNALSYM IPPROTO_ICMPV6} + IPPROTO_ICMPV6 = 58; // control message protocol + + {$EXTERNALSYM IPPROTO_RAW} + IPPROTO_RAW = 255; // raw IP packet + {$EXTERNALSYM IPPROTO_MAX} + IPPROTO_MAX = 256; + +// Port/socket numbers: network standard functions + {$EXTERNALSYM IPPORT_ECHO} + IPPORT_ECHO = 7; + {$EXTERNALSYM IPPORT_DISCARD} + IPPORT_DISCARD = 9; + {$EXTERNALSYM IPPORT_SYSTAT} + IPPORT_SYSTAT = 11; + {$EXTERNALSYM IPPORT_DAYTIME} + IPPORT_DAYTIME = 13; + {$EXTERNALSYM IPPORT_NETSTAT} + IPPORT_NETSTAT = 15; + {$EXTERNALSYM IPPORT_FTP} + IPPORT_FTP = 21; + {$EXTERNALSYM IPPORT_TELNET} + IPPORT_TELNET = 23; + {$EXTERNALSYM IPPORT_SMTP} + IPPORT_SMTP = 25; + {$EXTERNALSYM IPPORT_TIMESERVER} + IPPORT_TIMESERVER = 37; + {$EXTERNALSYM IPPORT_NAMESERVER} + IPPORT_NAMESERVER = 42; + {$EXTERNALSYM IPPORT_WHOIS} + IPPORT_WHOIS = 43; + {$EXTERNALSYM IPPORT_MTP} + IPPORT_MTP = 57; + +// Port/socket numbers: host specific functions + {$EXTERNALSYM IPPORT_TFTP} + IPPORT_TFTP = 69; + {$EXTERNALSYM IPPORT_RJE} + IPPORT_RJE = 77; + {$EXTERNALSYM IPPORT_FINGER} + IPPORT_FINGER = 79; + {$EXTERNALSYM ipport_ttylink} + IPPORT_TTYLINK = 87; + {$EXTERNALSYM IPPORT_SUPDUP} + IPPORT_SUPDUP = 95; + +// UNIX TCP sockets + {$EXTERNALSYM IPPORT_EXECSERVER} + IPPORT_EXECSERVER = 512; + {$EXTERNALSYM IPPORT_LOGINSERVER} + IPPORT_LOGINSERVER = 513; + {$EXTERNALSYM IPPORT_CMDSERVER} + IPPORT_CMDSERVER = 514; + {$EXTERNALSYM IPPORT_EFSSERVER} + IPPORT_EFSSERVER = 520; + +// UNIX UDP sockets + {$EXTERNALSYM IPPORT_BIFFUDP} + IPPORT_BIFFUDP = 512; + {$EXTERNALSYM IPPORT_WHOSERVER} + IPPORT_WHOSERVER = 513; + {$EXTERNALSYM IPPORT_ROUTESERVER} + IPPORT_ROUTESERVER = 520; + +// Ports < IPPORT_RESERVED are reserved for privileged processes (e.g. root). + {$EXTERNALSYM IPPORT_RESERVED} + IPPORT_RESERVED = 1024; + + {$EXTERNALSYM IPPORT_REGISTERED_MIN} + IPPORT_REGISTERED_MIN = IPPORT_RESERVED; + + {$IFNDEF WINCE} + {$EXTERNALSYM IPPORT_REGISTERED_MAX} + IPPORT_REGISTERED_MAX = $bfff; + {$EXTERNALSYM IPPORT_DYNAMIC_MIN} + IPPORT_DYNAMIC_MIN = $c000; + {$EXTERNALSYM IPPORT_DYNAMIC_MAX} + IPPORT_DYNAMIC_MAX = $ffff; + {$ENDIF} + +// Link numbers + {$EXTERNALSYM IMPLINK_IP} + IMPLINK_IP = 155; + {$EXTERNALSYM IMPLINK_LOWEXPER} + IMPLINK_LOWEXPER = 156; + {$EXTERNALSYM IMPLINK_HIGHEXPER} + IMPLINK_HIGHEXPER = 158; + + {$EXTERNALSYM TF_DISCONNECT} + TF_DISCONNECT = $01; + {$EXTERNALSYM TF_REUSE_SOCKET} + TF_REUSE_SOCKET = $02; + {$EXTERNALSYM TF_WRITE_BEHIND} + TF_WRITE_BEHIND = $04; + {$EXTERNALSYM TF_USE_DEFAULT_WORKER} + TF_USE_DEFAULT_WORKER = $00; + {$EXTERNALSYM TF_USE_SYSTEM_THREAD} + TF_USE_SYSTEM_THREAD = $10; + {$EXTERNALSYM TF_USE_KERNEL_APC} + TF_USE_KERNEL_APC = $20; + +// This is used instead of -1, since the TSocket type is unsigned. + {$EXTERNALSYM INVALID_SOCKET} + INVALID_SOCKET = TSocket(not(0)); + {$EXTERNALSYM SOCKET_ERROR} + SOCKET_ERROR = -1; + +// The following may be used in place of the address family, socket type, or +// protocol in a call to WSASocket to indicate that the corresponding value +// should be taken from the supplied WSAPROTOCOL_INFO structure instead of the +// parameter itself. + {$EXTERNALSYM FROM_PROTOCOL_INFO} + FROM_PROTOCOL_INFO = -1; + + +// Types + {$EXTERNALSYM SOCK_STREAM} + SOCK_STREAM = 1; { stream socket } + {$EXTERNALSYM SOCK_DGRAM} + SOCK_DGRAM = 2; { datagram socket } + {$EXTERNALSYM SOCK_RAW} + SOCK_RAW = 3; { raw-protocol interface } + {$EXTERNALSYM SOCK_RDM} + SOCK_RDM = 4; { reliably-delivered message } + {$EXTERNALSYM SOCK_SEQPACKET} + SOCK_SEQPACKET = 5; { sequenced packet stream } + +// option flags per-socket. + {$EXTERNALSYM SO_DEBUG} + SO_DEBUG = $0001; // turn on debugging info recording + {$EXTERNALSYM SO_ACCEPTCONN} + SO_ACCEPTCONN = $0002; // socket has had listen() + {$EXTERNALSYM SO_REUSEADDR} + SO_REUSEADDR = $0004; // allow local address reuse + {$EXTERNALSYM SO_KEEPALIVE} + SO_KEEPALIVE = $0008; // keep connections alive + {$EXTERNALSYM SO_DONTROUTE} + SO_DONTROUTE = $0010; // just use interface addresses + {$EXTERNALSYM SO_BROADCAST} + SO_BROADCAST = $0020; // permit sending of broadcast msgs + {$EXTERNALSYM SO_USELOOPBACK} + SO_USELOOPBACK = $0040; // bypass hardware when possible + {$EXTERNALSYM SO_LINGER} + SO_LINGER = $0080; // linger on close if data present + {$EXTERNALSYM SO_OOBINLINE} + SO_OOBINLINE = $0100; // leave received OOB data in line + + {$EXTERNALSYM SO_DONTLINGER} + SO_DONTLINGER = not SO_LINGER; + {$EXTERNALSYM SO_EXCLUSIVEADDRUSE} + SO_EXCLUSIVEADDRUSE = not SO_REUSEADDR; // disallow local address reuse + +// additional options. + + {$EXTERNALSYM SO_SNDBUF} + SO_SNDBUF = $1001; // send buffer size + {$EXTERNALSYM SO_RCVBUF} + SO_RCVBUF = $1002; // receive buffer size + {$EXTERNALSYM SO_SNDLOWAT} + SO_SNDLOWAT = $1003; // send low-water mark + {$EXTERNALSYM SO_RCVLOWAT} + SO_RCVLOWAT = $1004; // receive low-water mark + {$EXTERNALSYM SO_SNDTIMEO} + SO_SNDTIMEO = $1005; // send timeout + {$EXTERNALSYM SO_RCVTIMEO} + SO_RCVTIMEO = $1006; // receive timeout + {$EXTERNALSYM SO_ERROR} + SO_ERROR = $1007; // get error status and clear + {$EXTERNALSYM SO_TYPE} + SO_TYPE = $1008; // get socket type + +// options for connect and disconnect data and options. +// used only by non-tcp/ip transports such as DECNet, OSI TP4, etc. + {$EXTERNALSYM SO_CONNDATA} + SO_CONNDATA = $7000; + {$EXTERNALSYM SO_CONNOPT} + SO_CONNOPT = $7001; + {$EXTERNALSYM SO_DISCDATA} + SO_DISCDATA = $7002; + {$EXTERNALSYM SO_DISCOPT} + SO_DISCOPT = $7003; + {$EXTERNALSYM SO_CONNDATALEN} + SO_CONNDATALEN = $7004; + {$EXTERNALSYM SO_CONNOPTLEN} + SO_CONNOPTLEN = $7005; + {$EXTERNALSYM SO_DISCDATALEN} + SO_DISCDATALEN = $7006; + {$EXTERNALSYM SO_DISCOPTLEN} + SO_DISCOPTLEN = $7007; + +// option for opening sockets for synchronous access. + {$EXTERNALSYM SO_OPENTYPE} + SO_OPENTYPE = $7008; + {$EXTERNALSYM SO_SYNCHRONOUS_ALERT} + SO_SYNCHRONOUS_ALERT = $10; + {$EXTERNALSYM SO_SYNCHRONOUS_NONALERT} + SO_SYNCHRONOUS_NONALERT = $20; + +// other nt-specific options. + {$EXTERNALSYM SO_MAXDG} + SO_MAXDG = $7009; + {$EXTERNALSYM SO_MAXPATHDG} + SO_MAXPATHDG = $700A; + {$EXTERNALSYM SO_UPDATE_ACCEPT_CONTEXT} + SO_UPDATE_ACCEPT_CONTEXT = $700B; + {$EXTERNALSYM SO_CONNECT_TIME} + SO_CONNECT_TIME = $700C; + {$EXTERNALSYM SO_UPDATE_CONNECT_CONTEXT} + SO_UPDATE_CONNECT_CONTEXT = $7010; + +// tcp options. + {$EXTERNALSYM TCP_NODELAY} + TCP_NODELAY = $0001; + {$EXTERNALSYM TCP_BSDURGENT} + TCP_BSDURGENT = $7000; + +// winsock 2 extension -- new options + {$EXTERNALSYM SO_GROUP_ID} + SO_GROUP_ID = $2001; // ID of a socket group + {$EXTERNALSYM SO_GROUP_PRIORITY} + SO_GROUP_PRIORITY = $2002; // the relative priority within a group + {$EXTERNALSYM SO_MAX_MSG_SIZE} + SO_MAX_MSG_SIZE = $2003; // maximum message size + {$EXTERNALSYM SO_PROTOCOL_INFOA} + SO_PROTOCOL_INFOA = $2004; // WSAPROTOCOL_INFOA structure + {$EXTERNALSYM SO_PROTOCOL_INFOW} + SO_PROTOCOL_INFOW = $2005; // WSAPROTOCOL_INFOW structure + {$EXTERNALSYM SO_PROTOCOL_INFO} + {$IFDEF UNICODE} + SO_PROTOCOL_INFO = SO_PROTOCOL_INFOW; + {$ELSE} + SO_PROTOCOL_INFO = SO_PROTOCOL_INFOA; + {$ENDIF} + {$EXTERNALSYM PVD_CONFIG} + PVD_CONFIG = $3001; // configuration info for service provider + {$EXTERNALSYM SO_CONDITIONAL_ACCEPT} + SO_CONDITIONAL_ACCEPT = $3002; // enable true conditional accept: + // connection is not ack-ed to the + // other side until conditional + // function returns CF_ACCEPT + {$EXTERNALSYM SO_REUSE_UNICASTPORT} + SO_REUSE_UNICASTPORT = $3007; // defer ephemeral port allocation for + // outbound connections + {$EXTERNALSYM SO_REUSE_MULTICASTPORT} + SO_REUSE_MULTICASTPORT = $3008; // enable port reuse and disable unicast + //reception. + {$IFNDEF WINCE} + {$EXTERNALSYM SO_RANDOMIZE_PORT} + SO_RANDOMIZE_PORT = $3005; // randomize assignment of wildcard ports + {$EXTERNALSYM SO_PORT_SCALABILITY} + SO_PORT_SCALABILITY = $3006; // enable port scalability + {$ENDIF} +// Address families. + {$EXTERNALSYM AF_UNSPEC} + AF_UNSPEC = 0; // unspecified + {$EXTERNALSYM AF_UNIX} + AF_UNIX = 1; // local to host (pipes, portals) + {$EXTERNALSYM AF_INET} + AF_INET = 2; // internetwork: UDP, TCP, etc. + {$EXTERNALSYM AF_IMPLINK} + AF_IMPLINK = 3; // arpanet imp addresses + {$EXTERNALSYM AF_PUP} + AF_PUP = 4; // pup protocols: e.g. BSP + {$EXTERNALSYM AF_CHAOS} + AF_CHAOS = 5; // mit CHAOS protocols + {$EXTERNALSYM AF_IPX} + AF_IPX = 6; // ipx and SPX + {$EXTERNALSYM AF_NS} + AF_NS = AF_IPX; // xerOX NS protocols + {$EXTERNALSYM AF_ISO} + AF_ISO = 7; // iso protocols + {$EXTERNALSYM AF_OSI} + AF_OSI = AF_ISO; // osi is ISO + {$EXTERNALSYM AF_ECMA} + AF_ECMA = 8; // european computer manufacturers + {$EXTERNALSYM AF_DATAKIT} + AF_DATAKIT = 9; // datakit protocols + {$EXTERNALSYM AF_CCITT} + AF_CCITT = 10; // cciTT protocols, X.25 etc + {$EXTERNALSYM AF_SNA} + AF_SNA = 11; // ibm SNA + {$EXTERNALSYM AF_DECNET} + AF_DECNET = 12; // decnet + {$EXTERNALSYM AF_DLI} + AF_DLI = 13; // direct data link interface + {$EXTERNALSYM AF_LAT} + AF_LAT = 14; // lat + {$EXTERNALSYM AF_HYLINK} + AF_HYLINK = 15; // nsc Hyperchannel + {$EXTERNALSYM AF_APPLETALK} + AF_APPLETALK = 16; // appleTalk + {$EXTERNALSYM AF_NETBIOS} + AF_NETBIOS = 17; // netBios-style addresses + {$EXTERNALSYM AF_VOICEVIEW} + AF_VOICEVIEW = 18; // voiceView + {$EXTERNALSYM AF_FIREFOX} + AF_FIREFOX = 19; // fireFox + {$EXTERNALSYM AF_UNKNOWN1} + AF_UNKNOWN1 = 20; // somebody is using this! + {$EXTERNALSYM AF_BAN} + AF_BAN = 21; // banyan + {$IFDEF WINCE} + {$EXTERNALSYM AF_IRDA} + AF_IRDA = 22; //* IrDA */ + {$ELSE} + {$EXTERNALSYM AF_ATM} + AF_ATM = 22; // native ATM Services + {$ENDIF} + {$EXTERNALSYM AF_INET6} + AF_INET6 = 23; // internetwork Version 6 + {$EXTERNALSYM AF_CLUSTER} + AF_CLUSTER = 24; // microsoft Wolfpack + {$EXTERNALSYM AF_12844} + AF_12844 = 25; // ieeE 1284.4 WG AF + {$IFDEF WINCE} + {$EXTERNALSYM AF_ATM} + AF_ATM = 26; //* Native ATM Services */ + {$ELSE} + {$EXTERNALSYM AF_IRDA} + AF_IRDA = 26; // irdA + {$ENDIF} + {$EXTERNALSYM AF_NETDES} + AF_NETDES = 28; // network Designers OSI & gateway enabled protocols + {$EXTERNALSYM AF_TCNPROCESS} + AF_TCNPROCESS = 29; + {$EXTERNALSYM AF_TCNMESSAGE} + AF_TCNMESSAGE = 30; + {$EXTERNALSYM AF_ICLFXBM} + AF_ICLFXBM = 31; + + {$EXTERNALSYM AF_HYPERV} + AF_HYPERV = 34; + {$EXTERNALSYM AF_MAX} + AF_MAX = 35; //was 32 + +// protocol families, same as address families for now. + + {$EXTERNALSYM PF_UNSPEC} + PF_UNSPEC = AF_UNSPEC; + {$EXTERNALSYM PF_UNIX} + PF_UNIX = AF_UNIX; + {$EXTERNALSYM PF_INET} + PF_INET = AF_INET; + {$EXTERNALSYM PF_IMPLINK} + PF_IMPLINK = AF_IMPLINK; + {$EXTERNALSYM PF_PUP} + PF_PUP = AF_PUP; + {$EXTERNALSYM PF_CHAOS} + PF_CHAOS = AF_CHAOS; + {$EXTERNALSYM PF_NS} + PF_NS = AF_NS; + {$EXTERNALSYM PF_IPX} + PF_IPX = AF_IPX; + {$EXTERNALSYM PF_ISO} + PF_ISO = AF_ISO; + {$EXTERNALSYM PF_OSI} + PF_OSI = AF_OSI; + {$EXTERNALSYM PF_ECMA} + PF_ECMA = AF_ECMA; + {$EXTERNALSYM PF_DATAKIT} + PF_DATAKIT = AF_DATAKIT; + {$EXTERNALSYM PF_CCITT} + PF_CCITT = AF_CCITT; + {$EXTERNALSYM PF_SNA} + PF_SNA = AF_SNA; + {$EXTERNALSYM PF_DECNET} + PF_DECNET = AF_DECNET; + {$EXTERNALSYM PF_DLI} + PF_DLI = AF_DLI; + {$EXTERNALSYM PF_LAT} + PF_LAT = AF_LAT; + {$EXTERNALSYM PF_HYLINK} + PF_HYLINK = AF_HYLINK; + {$EXTERNALSYM PF_APPLETALK} + PF_APPLETALK = AF_APPLETALK; + {$EXTERNALSYM PF_VOICEVIEW} + PF_VOICEVIEW = AF_VOICEVIEW; + {$EXTERNALSYM PF_FIREFOX} + PF_FIREFOX = AF_FIREFOX; + {$EXTERNALSYM PF_UNKNOWN1} + PF_UNKNOWN1 = AF_UNKNOWN1; + {$EXTERNALSYM pf_ban} + PF_BAN = AF_BAN; + {$EXTERNALSYM PF_ATM} + PF_ATM = AF_ATM; + {$EXTERNALSYM PF_INET6} + PF_INET6 = AF_INET6; + + {$EXTERNALSYM PF_MAX} + PF_MAX = AF_MAX; + + {$EXTERNALSYM _SS_MAXSIZE} + _SS_MAXSIZE = 128; + {$EXTERNALSYM _SS_ALIGNSIZE} + _SS_ALIGNSIZE = SizeOf(Int64); + {$EXTERNALSYM _SS_PAD1SIZE} + _SS_PAD1SIZE = _SS_ALIGNSIZE - SizeOf(short); + {$EXTERNALSYM _SS_PAD2SIZE} + _SS_PAD2SIZE = _SS_MAXSIZE - (SizeOf(short) + _SS_PAD1SIZE + _SS_ALIGNSIZE); + +type + {$NODEFINE SunB} + SunB = record + s_b1, s_b2, s_b3, s_b4: u_char; + end; + + {$NODEFINE SunW} + SunW = record + s_w1, s_w2: u_short; + end; + + {$EXTERNALSYM in_addr} + in_addr = record + case integer of + 0: (S_un_b: SunB); + 1: (S_un_w: SunW); + 2: (S_addr: u_long); + end; + {$NODEFINE TInAddr} + TInAddr = in_addr; + {$NODEFINE PInAddr} + PInAddr = ^TInAddr; + + // Structure used by kernel to store most addresses. + + {$EXTERNALSYM sockaddr_in} + sockaddr_in = record + case Integer of + 0: (sin_family : u_short; + sin_port : u_short; + sin_addr : TInAddr; + sin_zero : array[0..7] of TIdAnsiChar); + 1: (sa_family : u_short; + sa_data : array[0..13] of TIdAnsiChar) + end; + {$NODEFINE TSockAddrIn} + TSockAddrIn = sockaddr_in; + {$NODEFINE PSockAddrIn} + PSockAddrIn = ^TSockAddrIn; + {$NODEFINE PSockAddr_In} + PSockAddr_In = PSockAddrIn; + {$NODEFINE TSockAddr} + TSockAddr = TSockAddrIn; + {$EXTERNALSYM SOCKADDR} + SOCKADDR = TSockAddr; + {$EXTERNALSYM PSOCKADDR} + PSOCKADDR = ^TSockAddr; + {$EXTERNALSYM LPSOCKADDR} + LPSOCKADDR = PSOCKADDR; + + {$EXTERNALSYM SOCKADDR_STORAGE} + SOCKADDR_STORAGE = record + ss_family: short; // Address family. + __ss_pad1: array[0.._SS_PAD1SIZE-1] of TIdAnsiChar; // 6 byte pad, this is to make + // implementation specific pad up to + // alignment field that follows explicit + // in the data structure. + __ss_align: Int64; // Field to force desired structure. + __ss_pad2: array[0.._SS_PAD2SIZE-1] of TIdAnsiChar; // 112 byte pad to achieve desired size; + // _SS_MAXSIZE value minus size of + // ss_family, __ss_pad1, and + // __ss_align fields is 112. + end; + {$NODEFINE TSockAddrStorage} + TSockAddrStorage = SOCKADDR_STORAGE; + {$NODEFINE PSockAddrStorage} + PSockAddrStorage = ^TSockAddrStorage; + {$EXTERNALSYM PSOCKADDR_STORAGE} + PSOCKADDR_STORAGE = PSockAddrStorage; + {$EXTERNALSYM LPSOCKADDR_STORAGE} + LPSOCKADDR_STORAGE = PSOCKADDR_STORAGE; + + // Structure used by kernel to pass protocol information in raw sockets. + {$EXTERNALSYM sockproto} + sockproto = record + sp_family : u_short; + sp_protocol : u_short; + end; + {$NODEFINE TSockProto} + TSockProto = sockproto; + {$NODEFINE PSockProto} + PSockProto = ^TSockProto; + +// Structure used for manipulating linger option. + {$EXTERNALSYM linger} + linger = record + l_onoff: u_short; + l_linger: u_short; + end; + {$NODEFINE TLinger} + TLinger = linger; + {$EXTERNALSYM PLINGER} + PLINGER = ^TLinger; + {$EXTERNALSYM LPLINGER} + LPLINGER = PLINGER; + +const + {$EXTERNALSYM INADDR_ANY} + INADDR_ANY = $00000000; + {$EXTERNALSYM INADDR_LOOPBACK} + INADDR_LOOPBACK = $7F000001; + {$EXTERNALSYM INADDR_BROADCAST} + INADDR_BROADCAST = $FFFFFFFF; + {$EXTERNALSYM INADDR_NONE} + INADDR_NONE = $FFFFFFFF; + + {$EXTERNALSYM ADDR_ANY} + ADDR_ANY = INADDR_ANY; + + {$EXTERNALSYM SOL_SOCKET} + SOL_SOCKET = $FFFF; // options for socket level + + {$EXTERNALSYM MSG_OOB} + MSG_OOB = $1; // process out-of-band data + {$EXTERNALSYM MSG_PEEK} + MSG_PEEK = $2; // peek at incoming message + {$EXTERNALSYM MSG_DONTROUTE} + MSG_DONTROUTE = $4; // send without using routing tables + + {$EXTERNALSYM MSG_PARTIAL} + MSG_PARTIAL = $8000; // partial send or recv for message xport + +// WinSock 2 extension -- new flags for WSASend(), WSASendTo(), WSARecv() and WSARecvFrom() + {$EXTERNALSYM MSG_INTERRUPT} + MSG_INTERRUPT = $10; // send/recv in the interrupt context + {$EXTERNALSYM MSG_MAXIOVLEN} + MSG_MAXIOVLEN = 16; + +// Define constant based on rfc883, used by gethostbyxxxx() calls. + + {$EXTERNALSYM MAXGETHOSTSTRUCT} + MAXGETHOSTSTRUCT = 1024; + +// Maximum queue length specifiable by listen. + {$EXTERNALSYM SOMAXCONN} + SOMAXCONN = $7FFFFFFF; + +// WinSock 2 extension -- bit values and indices for FD_XXX network events + {$EXTERNALSYM FD_READ_BIT} + FD_READ_BIT = 0; + {$EXTERNALSYM FD_WRITE_BIT} + FD_WRITE_BIT = 1; + {$EXTERNALSYM FD_OOB_BIT} + FD_OOB_BIT = 2; + {$EXTERNALSYM FD_ACCEPT_BIT} + FD_ACCEPT_BIT = 3; + {$EXTERNALSYM FD_CONNECT_BIT} + FD_CONNECT_BIT = 4; + {$EXTERNALSYM FD_CLOSE_BIT} + FD_CLOSE_BIT = 5; + {$EXTERNALSYM fd_qos_bit} + FD_QOS_BIT = 6; + {$EXTERNALSYM FD_GROUP_QOS_BIT} + FD_GROUP_QOS_BIT = 7; + {$EXTERNALSYM FD_ROUTING_INTERFACE_CHANGE_BIT} + FD_ROUTING_INTERFACE_CHANGE_BIT = 8; + {$EXTERNALSYM FD_ADDRESS_LIST_CHANGE_BIT} + FD_ADDRESS_LIST_CHANGE_BIT = 9; + + {$EXTERNALSYM FD_MAX_EVENTS} + FD_MAX_EVENTS = 10; + + {$EXTERNALSYM FD_READ} + FD_READ = (1 shl FD_READ_BIT); + {$EXTERNALSYM FD_WRITE} + FD_WRITE = (1 shl FD_WRITE_BIT); + {$EXTERNALSYM FD_OOB} + FD_OOB = (1 shl FD_OOB_BIT); + {$EXTERNALSYM FD_ACCEPT} + FD_ACCEPT = (1 shl FD_ACCEPT_BIT); + {$EXTERNALSYM FD_CONNECT} + FD_CONNECT = (1 shl FD_CONNECT_BIT); + {$EXTERNALSYM FD_CLOSE} + FD_CLOSE = (1 shl FD_CLOSE_BIT); + {$EXTERNALSYM FD_QOS} + FD_QOS = (1 shl FD_QOS_BIT); + {$EXTERNALSYM FD_GROUP_QOS} + FD_GROUP_QOS = (1 shl FD_GROUP_QOS_BIT); + {$EXTERNALSYM FD_ROUTING_INTERFACE_CHANGE} + FD_ROUTING_INTERFACE_CHANGE = (1 shl FD_ROUTING_INTERFACE_CHANGE_BIT); + {$EXTERNALSYM FD_ADDRESS_LIST_CHANGE} + FD_ADDRESS_LIST_CHANGE = (1 shl FD_ADDRESS_LIST_CHANGE_BIT); + + {$EXTERNALSYM FD_ALL_EVENTS} + FD_ALL_EVENTS = (1 shl FD_MAX_EVENTS) - 1; + +// All Windows Sockets error constants are biased by WSABASEERR from the "normal" + + {$EXTERNALSYM WSABASEERR} + WSABASEERR = 10000; + +// Windows Sockets definitions of regular Microsoft C error constants + + {$EXTERNALSYM WSAEINTR} + WSAEINTR = WSABASEERR+ 4; + {$EXTERNALSYM WSAEBADF} + WSAEBADF = WSABASEERR+ 9; + {$EXTERNALSYM WSAEACCES} + WSAEACCES = WSABASEERR+ 13; + {$EXTERNALSYM WSAEFAULT} + WSAEFAULT = WSABASEERR+ 14; + {$EXTERNALSYM WSAEINVAL} + WSAEINVAL = WSABASEERR+ 22; + {$EXTERNALSYM WSAEMFILE} + WSAEMFILE = WSABASEERR+ 24; + +// Windows Sockets definitions of regular Berkeley error constants + + {$EXTERNALSYM WSAEWOULDBLOCK} + WSAEWOULDBLOCK = WSABASEERR+ 35; + {$EXTERNALSYM WSAEINPROGRESS} + WSAEINPROGRESS = WSABASEERR+ 36; + {$EXTERNALSYM WSAEALREADY} + WSAEALREADY = WSABASEERR+ 37; + {$EXTERNALSYM WSAENOTSOCK} + WSAENOTSOCK = WSABASEERR+ 38; + {$EXTERNALSYM WSAEDESTADDRREQ} + WSAEDESTADDRREQ = WSABASEERR+ 39; + {$EXTERNALSYM WSAEMSGSIZE} + WSAEMSGSIZE = WSABASEERR+ 40; + {$EXTERNALSYM WSAEPROTOTYPE} + WSAEPROTOTYPE = WSABASEERR+ 41; + {$EXTERNALSYM WSAENOPROTOOPT} + WSAENOPROTOOPT = WSABASEERR+ 42; + {$EXTERNALSYM WSAEPROTONOSUPPORT} + WSAEPROTONOSUPPORT = WSABASEERR+ 43; + {$EXTERNALSYM WSAESOCKTNOSUPPORT} + WSAESOCKTNOSUPPORT = WSABASEERR+ 44; + {$EXTERNALSYM WSAEOPNOTSUPP} + WSAEOPNOTSUPP = WSABASEERR+ 45; + {$EXTERNALSYM WSAEPFNOSUPPORT} + WSAEPFNOSUPPORT = WSABASEERR+ 46; + {$EXTERNALSYM WSAEAFNOSUPPORT} + WSAEAFNOSUPPORT = WSABASEERR+ 47; + {$EXTERNALSYM WSAEADDRINUSE} + WSAEADDRINUSE = WSABASEERR+ 48; + {$EXTERNALSYM WSAEADDRNOTAVAIL} + WSAEADDRNOTAVAIL = WSABASEERR+ 49; + {$EXTERNALSYM WSAENETDOWN} + WSAENETDOWN = WSABASEERR+ 50; + {$EXTERNALSYM WSAENETUNREACH} + WSAENETUNREACH = WSABASEERR+ 51; + {$EXTERNALSYM WSAENETRESET} + WSAENETRESET = WSABASEERR+ 52; + {$EXTERNALSYM WSAECONNABORTED} + WSAECONNABORTED = WSABASEERR+ 53; + {$EXTERNALSYM WSAECONNRESET} + WSAECONNRESET = WSABASEERR+ 54; + {$EXTERNALSYM WSAENOBUFS} + WSAENOBUFS = WSABASEERR+ 55; + {$EXTERNALSYM WSAEISCONN} + WSAEISCONN = WSABASEERR+ 56; + {$EXTERNALSYM WSAENOTCONN} + WSAENOTCONN = WSABASEERR+ 57; + {$EXTERNALSYM WSAESHUTDOWN} + WSAESHUTDOWN = WSABASEERR+ 58; + {$EXTERNALSYM WSAETOOMANYREFS} + WSAETOOMANYREFS = WSABASEERR+ 59; + {$EXTERNALSYM WSAETIMEDOUT} + WSAETIMEDOUT = WSABASEERR+ 60; + {$EXTERNALSYM WSAECONNREFUSED} + WSAECONNREFUSED = WSABASEERR+ 61; + {$EXTERNALSYM WSAELOOP} + WSAELOOP = WSABASEERR+ 62; + {$EXTERNALSYM WSAENAMETOOLONG} + WSAENAMETOOLONG = WSABASEERR+ 63; + {$EXTERNALSYM WSAEHOSTDOWN} + WSAEHOSTDOWN = WSABASEERR+ 64; + {$EXTERNALSYM WSAEHOSTUNREACH} + WSAEHOSTUNREACH = WSABASEERR+ 65; + {$EXTERNALSYM wsaenotempty} + WSAENOTEMPTY = WSABASEERR+ 66; + {$EXTERNALSYM WSAEPROCLIM} + WSAEPROCLIM = WSABASEERR+ 67; + {$EXTERNALSYM WSAEUSERS} + WSAEUSERS = WSABASEERR+ 68; + {$EXTERNALSYM WSAEDQUOT} + WSAEDQUOT = WSABASEERR+ 69; + {$EXTERNALSYM WSAESTALE} + WSAESTALE = WSABASEERR+ 70; + {$EXTERNALSYM WSAEREMOTE} + WSAEREMOTE = WSABASEERR+ 71; + +// Extended Windows Sockets error constant definitions + + {$EXTERNALSYM WSASYSNOTREADY} + WSASYSNOTREADY = WSABASEERR+ 91; + {$EXTERNALSYM WSAVERNOTSUPPORTED} + WSAVERNOTSUPPORTED = WSABASEERR+ 92; + {$EXTERNALSYM WSANOTINITIALISED} + WSANOTINITIALISED = WSABASEERR+ 93; + {$EXTERNALSYM WSAEDISCON} + WSAEDISCON = WSABASEERR+101; + {$EXTERNALSYM WSAENOMORE} + WSAENOMORE = WSABASEERR+102; + {$EXTERNALSYM WSAECANCELLED} + WSAECANCELLED = WSABASEERR+103; + {$EXTERNALSYM WSAEINVALIDPROCTABLE} + WSAEINVALIDPROCTABLE = WSABASEERR+104; + {$EXTERNALSYM WSAEINVALIDPROVIDER} + WSAEINVALIDPROVIDER = WSABASEERR+105; + {$EXTERNALSYM WSAEPROVIDERFAILEDINIT} + WSAEPROVIDERFAILEDINIT = WSABASEERR+106; + {$EXTERNALSYM WSASYSCALLFAILURE} + WSASYSCALLFAILURE = WSABASEERR+107; + {$EXTERNALSYM WSASERVICE_NOT_FOUND} + WSASERVICE_NOT_FOUND = WSABASEERR+108; + {$EXTERNALSYM WSATYPE_NOT_FOUND} + WSATYPE_NOT_FOUND = WSABASEERR+109; + {$EXTERNALSYM WSA_E_NO_MORE} + WSA_E_NO_MORE = WSABASEERR+110; + {$EXTERNALSYM WSA_E_CANCELLED} + WSA_E_CANCELLED = WSABASEERR+111; + {$EXTERNALSYM WSAEREFUSED} + WSAEREFUSED = WSABASEERR+112; + + {$IFDEF WINCE} + WSAEDUPLICATE_NAME = WSABASEERR+900; + {$ENDIF} + +{ Error return codes from gethostbyname() and gethostbyaddr() + (when using the resolver). Note that these errors are + retrieved via WSAGetLastError() and must therefore follow + the rules for avoiding clashes with error numbers from + specific implementations or language run-time systems. + For this reason the codes are based at WSABASEERR+1001. + Note also that [WSA]NO_ADDRESS is defined only for + compatibility purposes. } + +// Authoritative Answer: Host not found + {$EXTERNALSYM WSAHOST_NOT_FOUND} + WSAHOST_NOT_FOUND = WSABASEERR+1001; + {$EXTERNALSYM HOST_NOT_FOUND} + HOST_NOT_FOUND = WSAHOST_NOT_FOUND; + +// Non-Authoritative: Host not found, or SERVERFAIL + {$EXTERNALSYM WSATRY_AGAIN} + WSATRY_AGAIN = WSABASEERR+1002; + {$EXTERNALSYM TRY_AGAIN} + TRY_AGAIN = WSATRY_AGAIN; + +// Non recoverable errors, FORMERR, REFUSED, NOTIMP + {$EXTERNALSYM WSANO_RECOVERY} + WSANO_RECOVERY = WSABASEERR+1003; + {$EXTERNALSYM NO_RECOVERY} + NO_RECOVERY = WSANO_RECOVERY; + +// Valid name, no data record of requested type + {$EXTERNALSYM WSANO_DATA} + WSANO_DATA = WSABASEERR+1004; + {$EXTERNALSYM NO_DATA} + NO_DATA = WSANO_DATA; + +// no address, look for MX record + {$EXTERNALSYM WSANO_ADDRESS} + WSANO_ADDRESS = WSANO_DATA; + {$EXTERNALSYM NO_ADDRESS} + NO_ADDRESS = WSANO_ADDRESS; + +// Define QOS related error return codes + + {$EXTERNALSYM WSA_QOS_RECEIVERS} + WSA_QOS_RECEIVERS = WSABASEERR+1005; // at least one reserve has arrived + {$EXTERNALSYM WSA_QOS_SENDERS} + WSA_QOS_SENDERS = WSABASEERR+1006; // at least one path has arrived + {$EXTERNALSYM WSA_QOS_NO_SENDERS} + WSA_QOS_NO_SENDERS = WSABASEERR+1007; // there are no senders + {$EXTERNALSYM WSA_QOS_NO_RECEIVERS} + WSA_QOS_NO_RECEIVERS = WSABASEERR+1008; // there are no receivers + {$EXTERNALSYM WSA_QOS_REQUEST_CONFIRMED} + WSA_QOS_REQUEST_CONFIRMED = WSABASEERR+1009; // reserve has been confirmed + {$EXTERNALSYM WSA_QOS_ADMISSION_FAILURE} + WSA_QOS_ADMISSION_FAILURE = WSABASEERR+1010; // error due to lack of resources + {$EXTERNALSYM WSA_QOS_POLICY_FAILURE} + WSA_QOS_POLICY_FAILURE = WSABASEERR+1011; // rejected for administrative reasons - bad credentials + {$EXTERNALSYM WSA_QOS_BAD_STYLE} + WSA_QOS_BAD_STYLE = WSABASEERR+1012; // unknown or conflicting style + {$EXTERNALSYM WSA_QOS_BAD_OBJECT} + WSA_QOS_BAD_OBJECT = WSABASEERR+1013; // problem with some part of the filterspec or providerspecific buffer in general + {$EXTERNALSYM WSA_QOS_TRAFFIC_CTRL_ERROR} + WSA_QOS_TRAFFIC_CTRL_ERROR = WSABASEERR+1014; // problem with some part of the flowspec + {$EXTERNALSYM WSA_QOS_GENERIC_ERROR} + WSA_QOS_GENERIC_ERROR = WSABASEERR+1015; // general error + {$EXTERNALSYM WSA_QOS_ESERVICETYPE} + WSA_QOS_ESERVICETYPE = WSABASEERR+1016; // invalid service type in flowspec + {$EXTERNALSYM WSA_QOS_EFLOWSPEC} + WSA_QOS_EFLOWSPEC = WSABASEERR+1017; // invalid flowspec + {$EXTERNALSYM WSA_QOS_EPROVSPECBUF} + WSA_QOS_EPROVSPECBUF = WSABASEERR+1018; // invalid provider specific buffer + {$EXTERNALSYM WSA_QOS_EFILTERSTYLE} + WSA_QOS_EFILTERSTYLE = WSABASEERR+1019; // invalid filter style + {$EXTERNALSYM WSA_QOS_EFILTERTYPE} + WSA_QOS_EFILTERTYPE = WSABASEERR+1020; // invalid filter type + {$EXTERNALSYM WSA_QOS_EFILTERCOUNT} + WSA_QOS_EFILTERCOUNT = WSABASEERR+1021; // incorrect number of filters + {$EXTERNALSYM WSA_QOS_EOBJLENGTH} + WSA_QOS_EOBJLENGTH = WSABASEERR+1022; // invalid object length + {$EXTERNALSYM WSA_QOS_EFLOWCOUNT} + WSA_QOS_EFLOWCOUNT = WSABASEERR+1023; // incorrect number of flows + {$EXTERNALSYM WSA_QOS_EUNKOWNPSOBJ} + WSA_QOS_EUNKOWNPSOBJ = WSABASEERR+1024; // unknown object in provider specific buffer + {$EXTERNALSYM WSA_QOS_EPOLICYOBJ} + WSA_QOS_EPOLICYOBJ = WSABASEERR+1025; // invalid policy object in provider specific buffer + {$EXTERNALSYM WSA_QOS_EFLOWDESC} + WSA_QOS_EFLOWDESC = WSABASEERR+1026; // invalid flow descriptor in the list + {$EXTERNALSYM WSA_QOS_EPSFLOWSPEC} + WSA_QOS_EPSFLOWSPEC = WSABASEERR+1027; // inconsistent flow spec in provider specific buffer + {$EXTERNALSYM WSA_QOS_EPSFILTERSPEC} + WSA_QOS_EPSFILTERSPEC = WSABASEERR+1028; // invalid filter spec in provider specific buffer + {$EXTERNALSYM WSA_QOS_ESDMODEOBJ} + WSA_QOS_ESDMODEOBJ = WSABASEERR+1029; // invalid shape discard mode object in provider specific buffer + {$EXTERNALSYM WSA_QOS_ESHAPERATEOBJ} + WSA_QOS_ESHAPERATEOBJ = WSABASEERR+1030; // invalid shaping rate object in provider specific buffer + {$EXTERNALSYM WSA_QOS_RESERVED_PETYPE} + WSA_QOS_RESERVED_PETYPE = WSABASEERR+1031; // reserved policy element in provider specific buffer + + +{ WinSock 2 extension -- new error codes and type definition } + {$EXTERNALSYM WSA_IO_PENDING} + WSA_IO_PENDING = ERROR_IO_PENDING; + {$EXTERNALSYM WSA_IO_INCOMPLETE} + WSA_IO_INCOMPLETE = ERROR_IO_INCOMPLETE; + {$EXTERNALSYM WSA_INVALID_HANDLE} + WSA_INVALID_HANDLE = ERROR_INVALID_HANDLE; + {$EXTERNALSYM WSA_INVALID_PARAMETER} + WSA_INVALID_PARAMETER = ERROR_INVALID_PARAMETER; + {$EXTERNALSYM WSA_NOT_ENOUGH_MEMORY} + WSA_NOT_ENOUGH_MEMORY = ERROR_NOT_ENOUGH_MEMORY; + {$EXTERNALSYM WSA_OPERATION_ABORTED} + WSA_OPERATION_ABORTED = ERROR_OPERATION_ABORTED; + {$EXTERNALSYM WSA_INVALID_EVENT} + WSA_INVALID_EVENT = WSAEVENT(nil); + {$EXTERNALSYM WSA_MAXIMUM_WAIT_EVENTS} + WSA_MAXIMUM_WAIT_EVENTS = MAXIMUM_WAIT_OBJECTS; + {$EXTERNALSYM WSA_WAIT_FAILED} + WSA_WAIT_FAILED = $FFFFFFFF; + {$EXTERNALSYM WSA_WAIT_EVENT_0} + WSA_WAIT_EVENT_0 = WAIT_OBJECT_0; + {$EXTERNALSYM WSA_WAIT_IO_COMPLETION} + WSA_WAIT_IO_COMPLETION = WAIT_IO_COMPLETION; + {$EXTERNALSYM WSA_WAIT_TIMEOUT} + WSA_WAIT_TIMEOUT = WAIT_TIMEOUT; + {$EXTERNALSYM WSA_INFINITE} + WSA_INFINITE = INFINITE; + +{ Windows Sockets errors redefined as regular Berkeley error constants. + These are commented out in Windows NT to avoid conflicts with errno.h. + Use the WSA constants instead. } + + {$EXTERNALSYM EWOULDBLOCK} + EWOULDBLOCK = WSAEWOULDBLOCK; + {$EXTERNALSYM EINPROGRESS} + EINPROGRESS = WSAEINPROGRESS; + {$EXTERNALSYM EALREADY} + EALREADY = WSAEALREADY; + {$EXTERNALSYM ENOTSOCK} + ENOTSOCK = WSAENOTSOCK; + {$EXTERNALSYM EDESTADDRREQ} + EDESTADDRREQ = WSAEDESTADDRREQ; + {$EXTERNALSYM EMSGSIZE} + EMSGSIZE = WSAEMSGSIZE; + {$EXTERNALSYM EPROTOTYPE} + EPROTOTYPE = WSAEPROTOTYPE; + {$EXTERNALSYM ENOPROTOOPT} + ENOPROTOOPT = WSAENOPROTOOPT; + {$EXTERNALSYM EPROTONOSUPPORT} + EPROTONOSUPPORT = WSAEPROTONOSUPPORT; + {$EXTERNALSYM ESOCKTNOSUPPORT} + ESOCKTNOSUPPORT = WSAESOCKTNOSUPPORT; + {$EXTERNALSYM EOPNOTSUPP} + EOPNOTSUPP = WSAEOPNOTSUPP; + {$EXTERNALSYM EPFNOSUPPORT} + EPFNOSUPPORT = WSAEPFNOSUPPORT; + {$EXTERNALSYM EAFNOSUPPORT} + EAFNOSUPPORT = WSAEAFNOSUPPORT; + {$EXTERNALSYM EADDRINUSE} + EADDRINUSE = WSAEADDRINUSE; + {$EXTERNALSYM EADDRNOTAVAIL} + EADDRNOTAVAIL = WSAEADDRNOTAVAIL; + {$EXTERNALSYM ENETDOWN} + ENETDOWN = WSAENETDOWN; + {$EXTERNALSYM ENETUNREACH} + ENETUNREACH = WSAENETUNREACH; + {$EXTERNALSYM ENETRESET} + ENETRESET = WSAENETRESET; + {$EXTERNALSYM ECONNABORTED} + ECONNABORTED = WSAECONNABORTED; + {$EXTERNALSYM ECONNRESET} + ECONNRESET = WSAECONNRESET; + {$EXTERNALSYM ENOBUFS} + ENOBUFS = WSAENOBUFS; + {$EXTERNALSYM EISCONN} + EISCONN = WSAEISCONN; + {$EXTERNALSYM ENOTCONN} + ENOTCONN = WSAENOTCONN; + {$EXTERNALSYM ESHUTDOWN} + ESHUTDOWN = WSAESHUTDOWN; + {$EXTERNALSYM ETOOMANYREFS} + ETOOMANYREFS = WSAETOOMANYREFS; + {$EXTERNALSYM ETIMEDOUT} + ETIMEDOUT = WSAETIMEDOUT; + {$EXTERNALSYM ECONNREFUSED} + ECONNREFUSED = WSAECONNREFUSED; + {$EXTERNALSYM ELOOP} + ELOOP = WSAELOOP; + {$EXTERNALSYM ENAMETOOLONG} + ENAMETOOLONG = WSAENAMETOOLONG; + {$EXTERNALSYM EHOSTDOWN} + EHOSTDOWN = WSAEHOSTDOWN; + {$EXTERNALSYM EHOSTUNREACH} + EHOSTUNREACH = WSAEHOSTUNREACH; + {$EXTERNALSYM ENOTEMPTY} + ENOTEMPTY = WSAENOTEMPTY; + {$EXTERNALSYM EPROCLIM} + EPROCLIM = WSAEPROCLIM; + {$EXTERNALSYM EUSERS} + EUSERS = WSAEUSERS; + {$EXTERNALSYM EDQUOT} + EDQUOT = WSAEDQUOT; + {$EXTERNALSYM ESTALE} + ESTALE = WSAESTALE; + {$EXTERNALSYM EREMOTE} + EREMOTE = WSAEREMOTE; + + {$EXTERNALSYM WSADESCRIPTION_LEN} + WSADESCRIPTION_LEN = 256; + {$EXTERNALSYM WSASYS_STATUS_LEN} + WSASYS_STATUS_LEN = 128; + +type + {$EXTERNALSYM WSADATA} + WSADATA = record + wVersion : Word; + wHighVersion : Word; + {$IFDEF _WIN64} + iMaxSockets : Word; + iMaxUdpDg : Word; + lpVendorInfo : PIdAnsiChar; + szDescription : array[0..WSADESCRIPTION_LEN] of TIdAnsiChar; + szSystemStatus : array[0..WSASYS_STATUS_LEN] of TIdAnsiChar; + {$ELSE} + szDescription : array[0..WSADESCRIPTION_LEN] of TIdAnsiChar; + szSystemStatus : array[0..WSASYS_STATUS_LEN] of TIdAnsiChar; + iMaxSockets : Word; + iMaxUdpDg : Word; + lpVendorInfo : PIdAnsiChar; + {$ENDIF} + end; + {$NODEFINE TWSAData} + TWSAData = WSADATA; + {$NODEFINE PWSAData} + PWSAData = ^TWSAData; + {$EXTERNALSYM LPWSADATA} + LPWSADATA = PWSAData; + + {$EXTERNALSYM WSAOVERLAPPED} + WSAOVERLAPPED = TOverlapped; + {$NODEFINE TWSAOverlapped} + TWSAOverlapped = WSAOVERLAPPED; + {$NODEFINE PWSAOverlapped} + PWSAOverlapped = ^TWSAOverlapped; + {$EXTERNALSYM LPWSAOVERLAPPED} + LPWSAOVERLAPPED = PWSAOverlapped; + {$IFNDEF WINCE} + {$EXTERNALSYM WSC_PROVIDER_INFO_TYPE} + {$EXTERNALSYM ProviderInfoLspCategories} + {$EXTERNALSYM ProviderInfoAudit} + WSC_PROVIDER_INFO_TYPE = ( + ProviderInfoLspCategories, + ProviderInfoAudit); + {$ENDIF} + +{ WinSock 2 extension -- WSABUF and QOS struct, include qos.h } +{ to pull in FLOWSPEC and related definitions } + + {$EXTERNALSYM WSABUF} + WSABUF = record + len: u_long; { the length of the buffer } + buf: PIdAnsiChar; { the pointer to the buffer } + end; + {$NODEFINE TWSABuf} + TWSABuf = WSABUF; + {$NODEFINE PWSABuf} + PWSABuf = ^TWSABuf; + {$EXTERNALSYM LPWSABUF} + LPWSABUF = PWSABUF; + + {$EXTERNALSYM SERVICETYPE} + SERVICETYPE = ULONG; + {$NODEFINE TServiceType} + TServiceType = SERVICETYPE; + + {$EXTERNALSYM FLOWSPEC} + FLOWSPEC = record + TokenRate, // In Bytes/sec + TokenBucketSize, // In Bytes + PeakBandwidth, // In Bytes/sec + Latency, // In microseconds + DelayVariation : ULONG; // In microseconds + ServiceType : TServiceType; + MaxSduSize, MinimumPolicedSize : ULONG;// In Bytes + end; + {$NODEFINE TFlowSpec} + TFlowSpec = FLOWSPEC; + {$EXTERNALSYM PFLOWSPEC} + PFLOWSPEC = ^TFlowSpec; + {$EXTERNALSYM LPFLOWSPEC} + LPFLOWSPEC = PFLOWSPEC; + + {$EXTERNALSYM QOS} + QOS = record + SendingFlowspec: TFlowSpec; { the flow spec for data sending } + ReceivingFlowspec: TFlowSpec; { the flow spec for data receiving } + ProviderSpecific: TWSABuf; { additional provider specific stuff } + end; + {$NODEFINE TQualityOfService} + TQualityOfService = QOS; + {$NODEFINE PQOS} + PQOS = ^QOS; + {$EXTERNALSYM LPQOS} + LPQOS = PQOS; + +const + {$EXTERNALSYM SERVICETYPE_NOTRAFFIC} + SERVICETYPE_NOTRAFFIC = $00000000; // No data in this direction + {$EXTERNALSYM SERVICETYPE_BESTEFFORT} + SERVICETYPE_BESTEFFORT = $00000001; // Best Effort + {$EXTERNALSYM SERVICETYPE_CONTROLLEDLOAD} + SERVICETYPE_CONTROLLEDLOAD = $00000002; // Controlled Load + {$EXTERNALSYM SERVICETYPE_GUARANTEED} + SERVICETYPE_GUARANTEED = $00000003; // Guaranteed + {$EXTERNALSYM SERVICETYPE_NETWORK_UNAVAILABLE} + SERVICETYPE_NETWORK_UNAVAILABLE = $00000004; // Used to notify change to user + {$EXTERNALSYM SERVICETYPE_GENERAL_INFORMATION} + SERVICETYPE_GENERAL_INFORMATION = $00000005; // corresponds to "General Parameters" defined by IntServ + {$EXTERNALSYM SERVICETYPE_NOCHANGE} + SERVICETYPE_NOCHANGE = $00000006; // used to indicate that the flow spec contains no change from any previous one +// to turn on immediate traffic control, OR this flag with the ServiceType field in the FLOWSPEC + {$EXTERNALSYM SERVICE_IMMEDIATE_TRAFFIC_CONTROL} + SERVICE_IMMEDIATE_TRAFFIC_CONTROL = $80000000; + +// WinSock 2 extension -- manifest constants for return values of the condition function + {$EXTERNALSYM CF_ACCEPT} + CF_ACCEPT = $0000; + {$EXTERNALSYM CF_REJECT} + CF_REJECT = $0001; + {$EXTERNALSYM CF_DEFER} + CF_DEFER = $0002; + +// WinSock 2 extension -- manifest constants for shutdown() + {$EXTERNALSYM SD_RECEIVE} + SD_RECEIVE = $00; + {$EXTERNALSYM SD_SEND} + SD_SEND = $01; + {$EXTERNALSYM SD_BOTH} + SD_BOTH = $02; + +// WinSock 2 extension -- data type and manifest constants for socket groups + {$EXTERNALSYM SG_UNCONSTRAINED_GROUP} + SG_UNCONSTRAINED_GROUP = $01; + {$EXTERNALSYM SG_CONSTRAINED_GROUP} + SG_CONSTRAINED_GROUP = $02; + +type + {$EXTERNALSYM GROUP} + GROUP = DWORD; + {$EXTERNALSYM PGROUP} + PGROUP = ^GROUP; + +// WinSock 2 extension -- data type for WSAEnumNetworkEvents() + {$EXTERNALSYM WSANETWORKEVENTS} + WSANETWORKEVENTS = record + lNetworkEvents: LongInt; + iErrorCode: Array[0..FD_MAX_EVENTS-1] of Integer; + end; + {$NODEFINE TWSANetworkEvents} + TWSANetworkEvents = WSANETWORKEVENTS; + {$NODEFINE PWSANetworkEvents} + PWSANetworkEvents = ^TWSANetworkEvents; + {$EXTERNALSYM LPWSANETWORKEVENTS} + LPWSANETWORKEVENTS = PWSANetworkEvents; + +//TransmitFile types used for the TransmitFile API function in WinNT/2000/XP +//not sure why its defined in WinCE when TransmitFile is not available. + {$IFNDEF NO_REDECLARE} + {$EXTERNALSYM TRANSMIT_FILE_BUFFERS} + TRANSMIT_FILE_BUFFERS = record + Head: Pointer; + HeadLength: DWORD; + Tail: Pointer; + TailLength: DWORD; + end; + {$NODEFINE TTransmitFileBuffers} + TTransmitFileBuffers = TRANSMIT_FILE_BUFFERS; + {$NODEFINE PTransmitFileBuffers} + PTransmitFileBuffers = ^TTransmitFileBuffers; + {$ENDIF} + {$EXTERNALSYM LPTRANSMIT_FILE_BUFFERS} + LPTRANSMIT_FILE_BUFFERS = PTransmitFileBuffers; + +const + {$EXTERNALSYM TP_ELEMENT_MEMORY} + TP_ELEMENT_MEMORY = 1; + {$EXTERNALSYM TP_ELEMENT_FILE} + TP_ELEMENT_FILE = 2; + {$EXTERNALSYM TP_ELEMENT_EOP} + TP_ELEMENT_EOP = 4; + + {$EXTERNALSYM TP_DISCONNECT} + TP_DISCONNECT = TF_DISCONNECT; + {$EXTERNALSYM TP_REUSE_SOCKET} + TP_REUSE_SOCKET = TF_REUSE_SOCKET; + {$EXTERNALSYM TP_USE_DEFAULT_WORKER} + TP_USE_DEFAULT_WORKER = TF_USE_DEFAULT_WORKER; + {$EXTERNALSYM TP_USE_SYSTEM_THREAD} + TP_USE_SYSTEM_THREAD = TF_USE_SYSTEM_THREAD; + {$EXTERNALSYM TP_USE_KERNEL_APC} + TP_USE_KERNEL_APC = TF_USE_KERNEL_APC; + +type + {$EXTERNALSYM TRANSMIT_PACKETS_ELEMENT} + TRANSMIT_PACKETS_ELEMENT = record + dwElFlags: ULONG; + cLength: ULONG; + case Integer of + 1: (nFileOffset: TLargeInteger; + hFile: THandle); + 2: (pBuffer: Pointer); + end; + {$NODEFINE TTransmitPacketsElement} + TTransmitPacketsElement = TRANSMIT_PACKETS_ELEMENT; + {$NODEFINE PTransmitPacketsElement} + PTransmitPacketsElement = ^TTransmitPacketsElement; + {$NODEFINE LPTransmitPacketsElement} + LPTransmitPacketsElement = PTransmitPacketsElement; + + {$EXTERNALSYM PTRANSMIT_PACKETS_ELEMENT} + PTRANSMIT_PACKETS_ELEMENT = ^TTransmitPacketsElement; + {$EXTERNALSYM LPTRANSMIT_PACKETS_ELEMENT} + LPTRANSMIT_PACKETS_ELEMENT = PTRANSMIT_PACKETS_ELEMENT; + +// WinSock 2 extension -- WSAPROTOCOL_INFO structure + +{$IFNDEF HAS_LPGUID} +type + {$IFNDEF HAS_PGUID} + {$NODEFINE PGUID} + PGUID = ^TGUID; + {$ENDIF} + {$EXTERNALSYM LPGUID} + LPGUID = PGUID; +{$ENDIF} + +// WinSock 2 extension -- WSAPROTOCOL_INFO manifest constants + +const + {$EXTERNALSYM MAX_PROTOCOL_CHAIN} + MAX_PROTOCOL_CHAIN = 7; + {$EXTERNALSYM BASE_PROTOCOL} + BASE_PROTOCOL = 1; + {$EXTERNALSYM LAYERED_PROTOCOL} + LAYERED_PROTOCOL = 0; + {$EXTERNALSYM WSAPROTOCOL_LEN} + WSAPROTOCOL_LEN = 255; + +type + {$EXTERNALSYM WSAPROTOCOLCHAIN} + WSAPROTOCOLCHAIN = record + ChainLen: Integer; // the length of the chain, + // length = 0 means layered protocol, + // length = 1 means base protocol, + // length > 1 means protocol chain + ChainEntries: Array[0..MAX_PROTOCOL_CHAIN-1] of DWORD; // a list of dwCatalogEntryIds + end; + {$NODEFINE TWSAProtocolChain} + TWSAProtocolChain = WSAPROTOCOLCHAIN; + {$EXTERNALSYM LPWSAPROTOCOLCHAIN} + LPWSAPROTOCOLCHAIN = ^TWSAProtocolChain; + +type + {$EXTERNALSYM WSAPROTOCOL_INFOA} + WSAPROTOCOL_INFOA = record + dwServiceFlags1: DWORD; + dwServiceFlags2: DWORD; + dwServiceFlags3: DWORD; + dwServiceFlags4: DWORD; + dwProviderFlags: DWORD; + ProviderId: TGUID; + dwCatalogEntryId: DWORD; + ProtocolChain: TWSAProtocolChain; + iVersion: Integer; + iAddressFamily: Integer; + iMaxSockAddr: Integer; + iMinSockAddr: Integer; + iSocketType: Integer; + iProtocol: Integer; + iProtocolMaxOffset: Integer; + iNetworkByteOrder: Integer; + iSecurityScheme: Integer; + dwMessageSize: DWORD; + dwProviderReserved: DWORD; + szProtocol: Array[0..WSAPROTOCOL_LEN+1-1] of TIdAnsiChar; + end; + {$NODEFINE TWSAProtocol_InfoA} + TWSAProtocol_InfoA = WSAPROTOCOL_INFOA; + {$NODEFINE PWSAProtocol_InfoA} + PWSAProtocol_InfoA = ^WSAPROTOCOL_INFOA; + {$EXTERNALSYM LPWSAPROTOCOL_INFOA} + LPWSAPROTOCOL_INFOA = PWSAProtocol_InfoA; + + {$EXTERNALSYM WSAPROTOCOL_INFOW} + WSAPROTOCOL_INFOW = record + dwServiceFlags1: DWORD; + dwServiceFlags2: DWORD; + dwServiceFlags3: DWORD; + dwServiceFlags4: DWORD; + dwProviderFlags: DWORD; + ProviderId: TGUID; + dwCatalogEntryId: DWORD; + ProtocolChain: TWSAProtocolChain; + iVersion: Integer; + iAddressFamily: Integer; + iMaxSockAddr: Integer; + iMinSockAddr: Integer; + iSocketType: Integer; + iProtocol: Integer; + iProtocolMaxOffset: Integer; + iNetworkByteOrder: Integer; + iSecurityScheme: Integer; + dwMessageSize: DWORD; + dwProviderReserved: DWORD; + szProtocol: Array[0..WSAPROTOCOL_LEN+1-1] of WideChar; + end; + {$NODEFINE TWSAProtocol_InfoW} + TWSAProtocol_InfoW = WSAPROTOCOL_INFOW; + {$NODEFINE PWSAProtocol_InfoW} + PWSAProtocol_InfoW = ^TWSAProtocol_InfoW; + {$EXTERNALSYM LPWSAPROTOCOL_INFOW} + LPWSAPROTOCOL_INFOW = PWSAProtocol_InfoW; + + {$EXTERNALSYM WSAPROTOCOL_INFO} + {$EXTERNALSYM LPWSAPROTOCOL_INFO} + {$NODEFINE TWSAProtocol_Info} + {$NODEFINE PWSAProtocol_Info} + {$IFDEF UNICODE} + WSAPROTOCOL_INFO = TWSAProtocol_InfoW; + TWSAProtocol_Info = TWSAProtocol_InfoW; + PWSAProtocol_Info = PWSAProtocol_InfoW; + LPWSAPROTOCOL_INFO = PWSAProtocol_InfoW; + {$ELSE} + WSAPROTOCOL_INFO = TWSAProtocol_InfoA; + TWSAProtocol_Info = TWSAProtocol_InfoA; + PWSAProtocol_Info = PWSAProtocol_InfoA; + LPWSAPROTOCOL_INFO = PWSAProtocol_InfoA; + {$ENDIF} + +const +// flag bit definitions for dwProviderFlags + {$EXTERNALSYM PFL_MULTIPLE_PROTO_ENTRIES} + PFL_MULTIPLE_PROTO_ENTRIES = $00000001; + {$EXTERNALSYM PFL_RECOMMENTED_PROTO_ENTRY} + PFL_RECOMMENTED_PROTO_ENTRY = $00000002; + {$EXTERNALSYM PFL_HIDDEN} + PFL_HIDDEN = $00000004; + {$EXTERNALSYM PFL_MATCHES_PROTOCOL_ZERO} + PFL_MATCHES_PROTOCOL_ZERO = $00000008; + +// flag bit definitions for dwServiceFlags1 + {$EXTERNALSYM XP1_CONNECTIONLESS} + XP1_CONNECTIONLESS = $00000001; + {$EXTERNALSYM XP1_GUARANTEED_DELIVERY} + XP1_GUARANTEED_DELIVERY = $00000002; + {$EXTERNALSYM XP1_GUARANTEED_ORDER} + XP1_GUARANTEED_ORDER = $00000004; + {$EXTERNALSYM XP1_MESSAGE_ORIENTED} + XP1_MESSAGE_ORIENTED = $00000008; + {$EXTERNALSYM XP1_PSEUDO_STREAM} + XP1_PSEUDO_STREAM = $00000010; + {$EXTERNALSYM XP1_GRACEFUL_CLOSE} + XP1_GRACEFUL_CLOSE = $00000020; + {$EXTERNALSYM XP1_EXPEDITED_DATA} + XP1_EXPEDITED_DATA = $00000040; + {$EXTERNALSYM XP1_CONNECT_DATA} + XP1_CONNECT_DATA = $00000080; + {$EXTERNALSYM XP1_DISCONNECT_DATA} + XP1_DISCONNECT_DATA = $00000100; + {$EXTERNALSYM XP1_SUPPORT_BROADCAST} + XP1_SUPPORT_BROADCAST = $00000200; + {$EXTERNALSYM XP1_SUPPORT_MULTIPOINT} + XP1_SUPPORT_MULTIPOINT = $00000400; + {$EXTERNALSYM XP1_MULTIPOINT_CONTROL_PLANE} + XP1_MULTIPOINT_CONTROL_PLANE = $00000800; + {$EXTERNALSYM XP1_MULTIPOINT_DATA_PLANE} + XP1_MULTIPOINT_DATA_PLANE = $00001000; + {$EXTERNALSYM XP1_QOS_SUPPORTED} + XP1_QOS_SUPPORTED = $00002000; + {$EXTERNALSYM XP1_INTERRUPT} + XP1_INTERRUPT = $00004000; + {$EXTERNALSYM XP1_UNI_SEND} + XP1_UNI_SEND = $00008000; + {$EXTERNALSYM XP1_UNI_RECV} + XP1_UNI_RECV = $00010000; + {$EXTERNALSYM XP1_IFS_HANDLES} + XP1_IFS_HANDLES = $00020000; + {$EXTERNALSYM XP1_PARTIAL_MESSAGE} + XP1_PARTIAL_MESSAGE = $00040000; + + {$EXTERNALSYM BIGENDIAN} + BIGENDIAN = $0000; + {$EXTERNALSYM LITTLEENDIAN} + LITTLEENDIAN = $0001; + + {$EXTERNALSYM SECURITY_PROTOCOL_NONE} + SECURITY_PROTOCOL_NONE = $0000; + +// WinSock 2 extension -- manifest constants for WSAJoinLeaf() + {$EXTERNALSYM JL_SENDER_ONLY} + JL_SENDER_ONLY = $01; + {$EXTERNALSYM JL_RECEIVER_ONLY} + JL_RECEIVER_ONLY = $02; + {$EXTERNALSYM JL_BOTH} + JL_BOTH = $04; + +// WinSock 2 extension -- manifest constants for WSASocket() + {$EXTERNALSYM WSA_FLAG_OVERLAPPED} + WSA_FLAG_OVERLAPPED = $01; + {$EXTERNALSYM WSA_FLAG_MULTIPOINT_C_ROOT} + WSA_FLAG_MULTIPOINT_C_ROOT = $02; + {$EXTERNALSYM WSA_FLAG_MULTIPOINT_C_LEAF} + WSA_FLAG_MULTIPOINT_C_LEAF = $04; + {$EXTERNALSYM WSA_FLAG_MULTIPOINT_D_ROOT} + WSA_FLAG_MULTIPOINT_D_ROOT = $08; + {$EXTERNALSYM WSA_FLAG_MULTIPOINT_D_LEAF} + WSA_FLAG_MULTIPOINT_D_LEAF = $10; + +// WinSock 2 extension -- manifest constants for WSAIoctl() + {$EXTERNALSYM IOC_UNIX} + IOC_UNIX = $00000000; + {$EXTERNALSYM IOC_WS2} + IOC_WS2 = $08000000; + {$EXTERNALSYM IOC_PROTOCOL} + IOC_PROTOCOL = $10000000; + {$EXTERNALSYM IOC_VENDOR} + IOC_VENDOR = $18000000; + + {$IFNDEF WINCE} +///* +// * WSK-specific IO control codes are Winsock2 codes with the highest-order +// * 3 bits of the Vendor/AddressFamily-specific field set to 1. +// */ + {$EXTERNALSYM IOC_WSK} + IOC_WSK = IOC_WS2 or $07000000; + {$ENDIF} + {$EXTERNALSYM SIO_ASSOCIATE_HANDLE} + SIO_ASSOCIATE_HANDLE = DWORD(IOC_IN or IOC_WS2 or 1); + {$EXTERNALSYM SIO_ENABLE_CIRCULAR_QUEUEING} + SIO_ENABLE_CIRCULAR_QUEUEING = DWORD(IOC_VOID or IOC_WS2 or 2); + {$EXTERNALSYM SIO_FIND_ROUTE} + SIO_FIND_ROUTE = DWORD(IOC_OUT or IOC_WS2 or 3); + {$EXTERNALSYM SIO_FLUSH} + SIO_FLUSH = DWORD(IOC_VOID or IOC_WS2 or 4); + {$EXTERNALSYM SIO_GET_BROADCAST_ADDRESS} + SIO_GET_BROADCAST_ADDRESS = DWORD(IOC_OUT or IOC_WS2 or 5); + {$EXTERNALSYM SIO_GET_EXTENSION_FUNCTION_POINTER} + SIO_GET_EXTENSION_FUNCTION_POINTER = DWORD(IOC_INOUT or IOC_WS2 or 6); + {$EXTERNALSYM SIO_GET_QOS} + SIO_GET_QOS = DWORD(IOC_INOUT or IOC_WS2 or 7); + {$EXTERNALSYM SIO_GET_GROUP_QOS} + SIO_GET_GROUP_QOS = DWORD(IOC_INOUT or IOC_WS2 or 8); + {$EXTERNALSYM SIO_MULTIPOINT_LOOPBACK} + SIO_MULTIPOINT_LOOPBACK = DWORD(IOC_IN or IOC_WS2 or 9); + {$EXTERNALSYM SIO_MULTICAST_SCOPE} + SIO_MULTICAST_SCOPE = DWORD(IOC_IN or IOC_WS2 or 10); + {$EXTERNALSYM SIO_SET_QOS} + SIO_SET_QOS = DWORD(IOC_IN or IOC_WS2 or 11); + {$EXTERNALSYM SIO_SET_GROUP_QOS} + SIO_SET_GROUP_QOS = DWORD(IOC_IN or IOC_WS2 or 12); + {$EXTERNALSYM SIO_TRANSLATE_HANDLE} + SIO_TRANSLATE_HANDLE = DWORD(IOC_INOUT or IOC_WS2 or 13); + {$EXTERNALSYM SIO_ROUTING_INTERFACE_QUERY} + SIO_ROUTING_INTERFACE_QUERY = DWORD(IOC_INOUT or IOC_WS2 or 20); + {$EXTERNALSYM SIO_ROUTING_INTERFACE_CHANGE} + SIO_ROUTING_INTERFACE_CHANGE = DWORD(IOC_IN or IOC_WS2 or 21); + {$EXTERNALSYM SIO_ADDRESS_LIST_QUERY} + SIO_ADDRESS_LIST_QUERY = DWORD(IOC_OUT or IOC_WS2 or 22); // see below SOCKET_ADDRESS_LIST + {$EXTERNALSYM SIO_ADDRESS_LIST_CHANGE} + SIO_ADDRESS_LIST_CHANGE = DWORD(IOC_VOID or IOC_WS2 or 23); + {$EXTERNALSYM SIO_QUERY_TARGET_PNP_HANDLE} + SIO_QUERY_TARGET_PNP_HANDLE = DWORD(IOC_OUT or IOC_WS2 or 24); + {$EXTERNALSYM SIO_NSP_NOTIFY_CHANGE} + SIO_NSP_NOTIFY_CHANGE = DWORD(IOC_IN or IOC_WS2 or 25); + {$EXTERNALSYM SIO_ADDRESS_LIST_SORT} + SIO_ADDRESS_LIST_SORT = DWORD(IOC_INOUT or IOC_WS2 or 25); + {$EXTERNALSYM SIO_QUERY_RSS_PROCESSOR_INFO} + SIO_QUERY_RSS_PROCESSOR_INFO = DWORD(IOC_INOUT or IOC_WS2 or 37); + + {$IFNDEF WINCE} + {$EXTERNALSYM SIO_RESERVED_1} + SIO_RESERVED_1 = DWORD(IOC_IN or IOC_WS2 or 26); + {$EXTERNALSYM SIO_RESERVED_2} + SIO_RESERVED_2 = DWORD(IOC_IN or IOC_WS2 or 33); + {$ENDIF} + +// WinSock 2 extension -- manifest constants for SIO_TRANSLATE_HANDLE ioctl + {$EXTERNALSYM TH_NETDEV} + TH_NETDEV = $00000001; + {$EXTERNALSYM TH_TAPI} + TH_TAPI = $00000002; + +type +// Manifest constants and type definitions related to name resolution and +// registration (RNR) API + {$IFNDEF NO_REDECLARE} + {$EXTERNALSYM BLOB} + BLOB = record + cbSize : U_LONG; + pBlobData : PBYTE; + end; + {$NODEFINE TBLOB} + TBLOB = BLOB; + {$NODEFINE PBLOB} + PBLOB = ^TBLOB; + {$ENDIF} + {$EXTERNALSYM LPBLOB} + LPBLOB = PBLOB; + + {$EXTERNALSYM RIO_BUFFERID} + RIO_BUFFERID = Pointer; + {$EXTERNALSYM RIO_CQ} + RIO_CQ = Pointer; + {$EXTERNALSYM RIO_RQ} + RIO_RQ = Pointer; + + {$EXTERNALSYM PRIO_BUFFERID} + PRIO_BUFFERID = ^RIO_BUFFERID; + {$EXTERNALSYM _RIORESULT} + _RIORESULT = record + Status : LONG; + BytesTransferred : ULONG; + SocketContext : ULONGLONG; + RequestContext : ULONGLONG; + end; + {$EXTERNALSYM RIORESULT} + RIORESULT = _RIORESULT; + {$EXTERNALSYM PRIORESULT} + PRIORESULT = ^RIORESULT; + {$EXTERNALSYM _RIO_BUF} + _RIO_BUF = record + BufferId : RIO_BUFFERID; + Offset : ULONG; + Length : ULONG; + end; + {$EXTERNALSYM RIO_BUF} + RIO_BUF = _RIO_BUF; + {$EXTERNALSYM PRIO_BUF} + PRIO_BUF = ^RIO_BUF; + {$EXTERNALSYM _RIO_CMSG_BUFFER} + _RIO_CMSG_BUFFER = record + TotalLength : ULONG; + //* followed by CMSG_HDR */ + end; + {$EXTERNALSYM RIO_CMSG_BUFFER} + RIO_CMSG_BUFFER = _RIO_CMSG_BUFFER; + {$EXTERNALSYM PRIO_CMSG_BUFFER} + PRIO_CMSG_BUFFER = ^RIO_CMSG_BUFFER; + +// Service Install Flags + +const + {$EXTERNALSYM SERVICE_MULTIPLE} + SERVICE_MULTIPLE = $00000001; + +// & name spaces + {$EXTERNALSYM NS_ALL} + NS_ALL = 0; + + {$EXTERNALSYM NS_SAP} + NS_SAP = 1; + {$EXTERNALSYM NS_NDS} + NS_NDS = 2; + {$EXTERNALSYM NS_PEER_BROWSE} + NS_PEER_BROWSE = 3; + {$EXTERNALSYM NS_SLP} + NS_SLP = 5; + {$EXTERNALSYM NS_DHCP} + NS_DHCP = 6; + + {$EXTERNALSYM NS_TCPIP_LOCAL} + NS_TCPIP_LOCAL = 10; + {$EXTERNALSYM NS_TCPIP_HOSTS} + NS_TCPIP_HOSTS = 11; + {$EXTERNALSYM NS_DNS} + NS_DNS = 12; + {$EXTERNALSYM NS_NETBT} + NS_NETBT = 13; + {$EXTERNALSYM NS_WINS} + NS_WINS = 14; + {$EXTERNALSYM NS_NLA} + NS_NLA = 15; //* Network Location Awareness*/ - WindowsXP + {$EXTERNALSYM NS_BTH} + NS_BTH = 16; //* Bluetooth SDP Namespace */ - Windows Vista + + {$EXTERNALSYM NS_NBP} + NS_NBP = 20; + + {$EXTERNALSYM NS_MS} + NS_MS = 30; + {$EXTERNALSYM NS_STDA} + NS_STDA = 31; + {$EXTERNALSYM NS_NTDS} + NS_NTDS = 32; + + //Windows Vista namespaces + {$EXTERNALSYM NS_EMAIL} + NS_EMAIL = 37; + {$EXTERNALSYM NS_PNRPNAME} + NS_PNRPNAME = 38; + {$EXTERNALSYM NS_PNRPCLOUD} + NS_PNRPCLOUD = 39; + // + + {$EXTERNALSYM NS_X500} + NS_X500 = 40; + {$EXTERNALSYM NS_NIS} + NS_NIS = 41; + {$EXTERNALSYM NS_NISPLUS} + NS_NISPLUS = 42; + + {$EXTERNALSYM NS_WRQ} + NS_WRQ = 50; + + {$EXTERNALSYM NS_NETDES} + NS_NETDES = 60; // Network Designers Limited + +{ Resolution flags for WSAGetAddressByName(). + Note these are also used by the 1.1 API GetAddressByName, so leave them around. } + {$EXTERNALSYM RES_UNUSED_1} + RES_UNUSED_1 = $00000001; + {$EXTERNALSYM RES_FLUSH_CACHE} + RES_FLUSH_CACHE = $00000002; + {$EXTERNALSYM RES_SERVICE} + RES_SERVICE = $00000004; + {$EXTERNALSYM RIO_MSG_DONT_NOTIFY} + RIO_MSG_DONT_NOTIFY = $00000001; + {$EXTERNALSYM RIO_MSG_DEFER} + RIO_MSG_DEFER = $00000002; + {$EXTERNALSYM RIO_MSG_WAITALL} + RIO_MSG_WAITALL = $00000004; + {$EXTERNALSYM RIO_MSG_COMMIT_ONLY} + RIO_MSG_COMMIT_ONLY = $00000008; + + {$EXTERNALSYM RIO_INVALID_BUFFERID} + RIO_INVALID_BUFFERID = RIO_BUFFERID($FFFFFFFF); + {$EXTERNALSYM RIO_INVALID_CQ} + RIO_INVALID_CQ = RIO_CQ(0); + {$EXTERNALSYM RIO_INVALID_RQ} + RIO_INVALID_RQ = RIO_RQ(0); + {$EXTERNALSYM RIO_MAX_CQ_SIZE} + RIO_MAX_CQ_SIZE = $8000000; + {$EXTERNALSYM RIO_CORRUPT_CQ} + RIO_CORRUPT_CQ = $FFFFFFFF; + +{ Well known value names for Service Types } + {$EXTERNALSYM SERVICE_TYPE_VALUE_IPXPORTA} + SERVICE_TYPE_VALUE_IPXPORTA : PIdAnsiChar = 'IpxSocket'; {Do not Localize} + {$EXTERNALSYM SERVICE_TYPE_VALUE_SAPIDA} + SERVICE_TYPE_VALUE_SAPIDA : PIdAnsiChar = 'SapId'; {Do not Localize} + {$EXTERNALSYM SERVICE_TYPE_VALUE_TCPPORTA} + SERVICE_TYPE_VALUE_TCPPORTA : PIdAnsiChar = 'TcpPort'; {Do not Localize} + {$EXTERNALSYM SERVICE_TYPE_VALUE_UDPPORTA} + SERVICE_TYPE_VALUE_UDPPORTA : PIdAnsiChar = 'UdpPort'; {Do not Localize} + {$EXTERNALSYM SERVICE_TYPE_VALUE_OBJECTIDA} + SERVICE_TYPE_VALUE_OBJECTIDA : PIdAnsiChar = 'ObjectId'; {Do not Localize} + + {$EXTERNALSYM SERVICE_TYPE_VALUE_IPXPORTW} + SERVICE_TYPE_VALUE_IPXPORTW : PWideChar = 'IpxSocket'; {Do not Localize} + {$EXTERNALSYM SERVICE_TYPE_VALUE_SAPIDW} + SERVICE_TYPE_VALUE_SAPIDW : PWideChar = 'SapId'; {Do not Localize} + {$EXTERNALSYM SERVICE_TYPE_VALUE_TCPPORTW} + SERVICE_TYPE_VALUE_TCPPORTW : PWideChar = 'TcpPort'; {Do not Localize} + {$EXTERNALSYM SERVICE_TYPE_VALUE_UDPPORTW} + SERVICE_TYPE_VALUE_UDPPORTW : PWideChar = 'UdpPort'; {Do not Localize} + {$EXTERNALSYM SERVICE_TYPE_VALUE_OBJECTIDW} + SERVICE_TYPE_VALUE_OBJECTIDW : PWideChar = 'ObjectId'; {Do not Localize} + + {$EXTERNALSYM SERVICE_TYPE_VALUE_SAPID} + {$EXTERNALSYM SERVICE_TYPE_VALUE_TCPPORT} + {$EXTERNALSYM SERVICE_TYPE_VALUE_UDPPORT} + {$EXTERNALSYM SERVICE_TYPE_VALUE_OBJECTID} + {$IFDEF UNICODE} + SERVICE_TYPE_VALUE_SAPID : PWideChar = 'SapId'; {Do not Localize} + SERVICE_TYPE_VALUE_TCPPORT : PWideChar = 'TcpPort'; {Do not Localize} + SERVICE_TYPE_VALUE_UDPPORT : PWideChar = 'UdpPort'; {Do not Localize} + SERVICE_TYPE_VALUE_OBJECTID : PWideChar = 'ObjectId'; {Do not Localize} + {$ELSE} + SERVICE_TYPE_VALUE_SAPID : PIdAnsiChar = 'SapId'; {Do not Localize} + SERVICE_TYPE_VALUE_TCPPORT : PIdAnsiChar = 'TcpPort'; {Do not Localize} + SERVICE_TYPE_VALUE_UDPPORT : PIdAnsiChar = 'UdpPort'; {Do not Localize} + SERVICE_TYPE_VALUE_OBJECTID : PIdAnsiChar = 'ObjectId'; {Do not Localize} + {$ENDIF} + +// SockAddr Information +type + {$EXTERNALSYM SOCKET_ADDRESS} + SOCKET_ADDRESS = record + lpSockaddr : PSOCKADDR; + iSockaddrLength : Integer; + end; + {$NODEFINE TSocket_Address} + TSocket_Address = SOCKET_ADDRESS; + {$EXTERNALSYM PSOCKET_ADDRESS} + PSOCKET_ADDRESS = ^TSocket_Address; + + {$EXTERNALSYM SOCKET_ADDRESS_LIST} + SOCKET_ADDRESS_LIST = record + iAddressCount : Integer; + Address : SOCKET_ADDRESS; + end; + {$NODEFINE TSocket_Address_List} + TSocket_Address_List = SOCKET_ADDRESS_LIST; + {$EXTERNALSYM PSOCKET_ADDRESS_LIST} + PSOCKET_ADDRESS_LIST = ^TSocket_Address_List; + {$EXTERNALSYM LPSOCKET_ADDRESS_LIST} + LPSOCKET_ADDRESS_LIST = PSOCKET_ADDRESS_LIST; + +// CSAddr Information + {$EXTERNALSYM CSADDR_INFO} + CSADDR_INFO = record + LocalAddr, + RemoteAddr : TSocket_Address; + iSocketType, + iProtocol : Integer; + end; + {$NODEFINE TCSAddr_Info} + TCSAddr_Info = CSADDR_INFO; + {$EXTERNALSYM PCSADDR_INFO} + PCSADDR_INFO = ^TCSAddr_Info; + {$EXTERNALSYM LPCSADDR_INFO} + LPCSADDR_INFO = PCSADDR_INFO; + +// Address Family/Protocol Tuples + {$EXTERNALSYM AFPROTOCOLS} + AFPROTOCOLS = record + iAddressFamily : Integer; + iProtocol : Integer; + end; + {$NODEFINE TAFProtocols} + TAFProtocols = AFPROTOCOLS; + {$EXTERNALSYM PAFPROTOCOLS} + PAFPROTOCOLS = ^TAFProtocols; + {$EXTERNALSYM LPAFPROTOCOLS} + LPAFPROTOCOLS = PAFPROTOCOLS; + +// Client Query API Typedefs + +// The comparators + {$EXTERNALSYM WSAECOMPARATOR} + WSAECOMPARATOR = (COMP_EQUAL {= 0}, COMP_NOTLESS); + {$NODEFINE TWSAEComparator} + TWSAEComparator = WSAECOMPARATOR; + {$EXTERNALSYM PWSAECOMPARATOR} + PWSAECOMPARATOR = ^WSAECOMPARATOR; + + {$EXTERNALSYM WSAVERSION} + WSAVERSION = record + dwVersion : DWORD; + ecHow : TWSAEComparator; + end; + {$NODEFINE TWSAVersion} + TWSAVersion = WSAVERSION; + {$EXTERNALSYM PWSAVERSION} + PWSAVERSION = ^TWSAVersion; + {$EXTERNALSYM LPWSAVERSION} + LPWSAVERSION = PWSAVERSION; + + {$EXTERNALSYM WSAQUERYSETA} + WSAQUERYSETA = record + dwSize : DWORD; + lpszServiceInstanceName : PIdAnsiChar; + lpServiceClassId : PGUID; + lpVersion : LPWSAVERSION; + lpszComment : PIdAnsiChar; + dwNameSpace : DWORD; + lpNSProviderId : PGUID; + lpszContext : PIdAnsiChar; + dwNumberOfProtocols : DWORD; + lpafpProtocols : LPAFPROTOCOLS; + lpszQueryString : PIdAnsiChar; + dwNumberOfCsAddrs : DWORD; + lpcsaBuffer : LPCSADDR_INFO; + dwOutputFlags : DWORD; + lpBlob : LPBLOB; + end; + {$NODEFINE TWSAQuerySetA} + TWSAQuerySetA = WSAQUERYSETA; + {$EXTERNALSYM PWSAQUERYSETA} + PWSAQUERYSETA = ^TWSAQuerySetA; + {$EXTERNALSYM LPWSAQUERYSETA} + LPWSAQUERYSETA = PWSAQUERYSETA; + + {$EXTERNALSYM WSAQUERYSETW} + WSAQUERYSETW = record + dwSize : DWORD; + lpszServiceInstanceName : PWideChar; + lpServiceClassId : PGUID; + lpVersion : LPWSAVERSION; + lpszComment : PWideChar; + dwNameSpace : DWORD; + lpNSProviderId : PGUID; + lpszContext : PWideChar; + dwNumberOfProtocols : DWORD; + lpafpProtocols : LPAFPROTOCOLS; + lpszQueryString : PWideChar; + dwNumberOfCsAddrs : DWORD; + lpcsaBuffer : LPCSADDR_INFO; + dwOutputFlags : DWORD; + lpBlob : LPBLOB; + end; + {$NODEFINE TWSAQuerySetW} + TWSAQuerySetW = WSAQUERYSETW; + {$EXTERNALSYM PWSAQUERYSETW} + PWSAQUERYSETW = ^TWSAQuerySetW; + {$EXTERNALSYM LPWSAQUERYSETW} + LPWSAQUERYSETW = PWSAQUERYSETW; + + {$NODEFINE TWSAQuerySet} + {$EXTERNALSYM PWSAQUERYSET} + {$EXTERNALSYM LPWSAQUERYSET} + {$IFDEF UNICODE} + TWSAQuerySet = TWSAQuerySetW; + PWSAQUERYSET = PWSAQUERYSETW; + LPWSAQUERYSET = LPWSAQUERYSETW; + {$ELSE} + TWSAQuerySet = TWSAQuerySetA; + PWSAQUERYSET = PWSAQUERYSETA; + LPWSAQUERYSET = LPWSAQUERYSETA; + {$ENDIF} + +const + {$EXTERNALSYM LUP_DEEP} + LUP_DEEP = $0001; + {$EXTERNALSYM LUP_CONTAINERS} + LUP_CONTAINERS = $0002; + {$EXTERNALSYM LUP_NOCONTAINERS} + LUP_NOCONTAINERS = $0004; + {$EXTERNALSYM LUP_NEAREST} + LUP_NEAREST = $0008; + {$EXTERNALSYM LUP_RETURN_NAME} + LUP_RETURN_NAME = $0010; + {$EXTERNALSYM LUP_RETURN_TYPE} + LUP_RETURN_TYPE = $0020; + {$EXTERNALSYM LUP_RETURN_VERSION} + LUP_RETURN_VERSION = $0040; + {$EXTERNALSYM LUP_RETURN_COMMENT} + LUP_RETURN_COMMENT = $0080; + {$EXTERNALSYM LUP_RETURN_ADDR} + LUP_RETURN_ADDR = $0100; + {$EXTERNALSYM LUP_RETURN_BLOB} + LUP_RETURN_BLOB = $0200; + {$EXTERNALSYM LUP_RETURN_ALIASES} + LUP_RETURN_ALIASES = $0400; + {$EXTERNALSYM LUP_RETURN_QUERY_STRING} + LUP_RETURN_QUERY_STRING = $0800; + {$EXTERNALSYM LUP_RETURN_ALL} + LUP_RETURN_ALL = $0FF0; + {$EXTERNALSYM LUP_RES_SERVICE} + LUP_RES_SERVICE = $8000; + + {$EXTERNALSYM LUP_FLUSHCACHE} + LUP_FLUSHCACHE = $1000; + {$EXTERNALSYM LUP_FLUSHPREVIOUS} + LUP_FLUSHPREVIOUS = $2000; + +// Return flags + {$EXTERNALSYM RESULT_IS_ALIAS} + RESULT_IS_ALIAS = $0001; + //These are not supported in WinCE 4.2 but are available in later versions. + {$EXTERNALSYM RESULT_IS_ADDED} + RESULT_IS_ADDED = $0010; + {$EXTERNALSYM RESULT_IS_CHANGED} + RESULT_IS_CHANGED = $0020; + {$EXTERNALSYM RESULT_IS_DELETED} + RESULT_IS_DELETED = $0040; + + {$EXTERNALSYM MAX_NATURAL_ALIGNMENT} + {$IFDEF _WIN64} + MAX_NATURAL_ALIGNMENT = SizeOf(Int64); + {$ELSE} + MAX_NATURAL_ALIGNMENT = SizeOf(DWORD); + {$ENDIF} + +// WSARecvMsg flags + {$EXTERNALSYM MSG_TRUNC} + MSG_TRUNC = $0100; + {$EXTERNALSYM MSG_CTRUNC} + MSG_CTRUNC = $0200; + {$EXTERNALSYM MSG_BCAST} + MSG_BCAST = $0400; + {$EXTERNALSYM MSG_MCAST} + MSG_MCAST = $0800; + +{$IFNDEF WINCE} + //Windows Vista WSAPoll +//* Event flag definitions for WSAPoll(). */ + {$EXTERNALSYM POLLRDNORM} + POLLRDNORM = $0100; + {$EXTERNALSYM POLLRDBAND} + POLLRDBAND = $0200; + {$EXTERNALSYM POLLIN} + POLLIN = (POLLRDNORM or POLLRDBAND); + {$EXTERNALSYM POLLPRI} + POLLPRI = $0400; + {$EXTERNALSYM POLLWRNORM} + POLLWRNORM = $0010; + {$EXTERNALSYM POLLOUT} + POLLOUT = (POLLWRNORM); + {$EXTERNALSYM POLLWRBAND} + POLLWRBAND = $0020; + {$EXTERNALSYM POLLERR} + POLLERR = $0001; + {$EXTERNALSYM POLLHUP} + POLLHUP = $0002; + {$EXTERNALSYM POLLNVAL} + POLLNVAL = $0004; +{$ENDIF} + +type +// Service Address Registration and Deregistration Data Types. + {$EXTERNALSYM WSAESETSERVICEOP} + WSAESETSERVICEOP = (RNRSERVICE_REGISTER{=0}, RNRSERVICE_DEREGISTER, RNRSERVICE_DELETE); + {$NODEFINE TWSAESetServiceOp} + TWSAESetServiceOp = WSAESETSERVICEOP; + +{ Service Installation/Removal Data Types. } + {$EXTERNALSYM WSANSCLASSINFOA} + WSANSCLASSINFOA = record + lpszName : PIdAnsiChar; + dwNameSpace : DWORD; + dwValueType : DWORD; + dwValueSize : DWORD; + lpValue : Pointer; + end; + {$NODEFINE TWSANSClassInfoA} + TWSANSClassInfoA = WSANSCLASSINFOA; + {$EXTERNALSYM PWSANSClassInfoA} + PWSANSCLASSINFOA = ^TWSANSClassInfoA; + {$EXTERNALSYM LPWSANSCLASSINFOA} + LPWSANSCLASSINFOA = PWSANSCLASSINFOA; + + {$EXTERNALSYM WSANSCLASSINFOW} + WSANSCLASSINFOW = record + lpszName : PWideChar; + dwNameSpace : DWORD; + dwValueType : DWORD; + dwValueSize : DWORD; + lpValue : Pointer; + end; + {$NODEFINE TWSANSClassInfoW} + TWSANSClassInfoW = WSANSCLASSINFOW; + {$EXTERNALSYM PWSANSClassInfoW} + PWSANSCLASSINFOW = ^TWSANSClassInfoW; + {$EXTERNALSYM LPWSANSCLASSINFOW} + LPWSANSCLASSINFOW = PWSANSCLASSINFOW; + + {$NODEFINE TWSANSClassInfo} + {$EXTERNALSYM WSANSCLASSINFO} + {$EXTERNALSYM PWSANSCLASSINFO} + {$EXTERNALSYM LPWSANSCLASSINFO} + {$IFDEF UNICODE} + TWSANSClassInfo = TWSANSClassInfoW; + WSANSCLASSINFO = TWSANSClassInfoW; + PWSANSCLASSINFO = PWSANSCLASSINFOW; + LPWSANSCLASSINFO = LPWSANSCLASSINFOW; + {$ELSE} + TWSANSClassInfo = TWSANSClassInfoA; + WSANSCLASSINFO = TWSANSClassInfoA; + PWSANSCLASSINFO = PWSANSCLASSINFOA; + LPWSANSCLASSINFO = LPWSANSCLASSINFOA; + {$ENDIF // UNICODE} + + {$EXTERNALSYM WSASERVICECLASSINFOA} + WSASERVICECLASSINFOA = record + lpServiceClassId : PGUID; + lpszServiceClassName : PIdAnsiChar; + dwCount : DWORD; + lpClassInfos : LPWSANSCLASSINFOA; + end; + {$NODEFINE TWSAServiceClassInfoA} + TWSAServiceClassInfoA = WSASERVICECLASSINFOA; + {$EXTERNALSYM PWSASERVICECLASSINFOA} + PWSASERVICECLASSINFOA = ^TWSAServiceClassInfoA; + {$EXTERNALSYM LPWSASERVICECLASSINFOA} + LPWSASERVICECLASSINFOA = PWSASERVICECLASSINFOA; + + {$EXTERNALSYM WSASERVICECLASSINFOW} + WSASERVICECLASSINFOW = record + lpServiceClassId : PGUID; + lpszServiceClassName : PWideChar; + dwCount : DWORD; + lpClassInfos : LPWSANSCLASSINFOW; + end; + {$NODEFINE TWSAServiceClassInfoW} + TWSAServiceClassInfoW = WSASERVICECLASSINFOW; + {$EXTERNALSYM PWSASERVICECLASSINFOW} + PWSASERVICECLASSINFOW = ^TWSAServiceClassInfoW; + {$EXTERNALSYM LPWSASERVICECLASSINFOW} + LPWSASERVICECLASSINFOW = PWSASERVICECLASSINFOW; + + {$NODEFINE TWSAServiceClassInfo} + {$EXTERNALSYM WSASERVICECLASSINFO} + {$EXTERNALSYM PWSASERVICECLASSINFO} + {$EXTERNALSYM LPWSASERVICECLASSINFO} + {$IFDEF UNICODE} + TWSAServiceClassInfo = TWSAServiceClassInfoW; + WSASERVICECLASSINFO = TWSAServiceClassInfoW; + PWSASERVICECLASSINFO = PWSASERVICECLASSINFOW; + LPWSASERVICECLASSINFO = LPWSASERVICECLASSINFOW; + {$ELSE} + TWSAServiceClassInfo = TWSAServiceClassInfoA; + WSASERVICECLASSINFO = TWSAServiceClassInfoA; + PWSASERVICECLASSINFO = PWSASERVICECLASSINFOA; + LPWSASERVICECLASSINFO = LPWSASERVICECLASSINFOA; + {$ENDIF} + + {$EXTERNALSYM WSANAMESPACE_INFOA} + WSANAMESPACE_INFOA = record + NSProviderId : TGUID; + dwNameSpace : DWORD; + fActive : DWORD{Bool}; + dwVersion : DWORD; + lpszIdentifier : PIdAnsiChar; + end; + {$NODEFINE TWSANameSpace_InfoA} + TWSANameSpace_InfoA = WSANAMESPACE_INFOA; + {$EXTERNALSYM PWSANAMESPACE_INFOA} + PWSANAMESPACE_INFOA = ^TWSANameSpace_InfoA; + {$EXTERNALSYM LPWSANAMESPACE_INFOA} + LPWSANAMESPACE_INFOA = PWSANAMESPACE_INFOA; + + {$EXTERNALSYM WSANAMESPACE_INFOW} + WSANAMESPACE_INFOW = record + NSProviderId : TGUID; + dwNameSpace : DWORD; + fActive : DWORD{Bool}; + dwVersion : DWORD; + lpszIdentifier : PWideChar; + end; + {$NODEFINE TWSANameSpace_InfoW} + TWSANameSpace_InfoW = WSANAMESPACE_INFOW; + {$EXTERNALSYM PWSANAMESPACE_INFOW} + PWSANAMESPACE_INFOW = ^TWSANameSpace_InfoW; + {$EXTERNALSYM LPWSANAMESPACE_INFOW} + LPWSANAMESPACE_INFOW = PWSANAMESPACE_INFOW; + +{$IFNDEF WINCE} + {$EXTERNALSYM WSANAMESPACE_INFOEXW} + WSANAMESPACE_INFOEXW = record + NSProviderId : TGUID; + dwNameSpace : DWord; + fActive : LongBool; + lpszIdentifier : LPWSTR; + ProviderSpecific : BLOB; + end; + {$NODEFINE TWSANameSpace_InfoExW} + TWSANameSpace_InfoExW = WSANAMESPACE_INFOEXW; + {$EXTERNALSYM PWSANAMESPACE_INFOEXW} + PWSANAMESPACE_INFOEXW = ^TWSANameSpace_InfoExW; + {$EXTERNALSYM LPWSANAMESPACE_INFOEXW} + LPWSANAMESPACE_INFOEXW = PWSANAMESPACE_INFOEXW; + + {$EXTERNALSYM WSANAMESPACE_INFOEXA} + WSANAMESPACE_INFOEXA = record + NSProviderId : TGUID; + dwNameSpace : DWord; + fActive : LongBool; + lpszIdentifier : LPSTR; + ProviderSpecific : BLOB; + end; + {$NODEFINE TWSANameSpace_InfoExA} + TWSANameSpace_InfoExA = WSANAMESPACE_INFOEXA; + {$EXTERNALSYM PWSANAMESPACE_INFOEXA} + PWSANAMESPACE_INFOEXA = ^TWSANameSpace_InfoExA; + {$EXTERNALSYM LPWSANAMESPACE_INFOEXA} + LPWSANAMESPACE_INFOEXA = PWSANAMESPACE_INFOEXA; + + {$EXTERNALSYM LPFN_WSAENUMNAMESPACEPROVIDERSEXW} + LPFN_WSAENUMNAMESPACEPROVIDERSEXW = function (var lpdwBufferLength : DWord; + lpnspBuffer : PWSANAMESPACE_INFOEXW): Integer; stdcall; + {$EXTERNALSYM LPFN_WSAENUMNAMESPACEPROVIDERSEXA} + LPFN_WSAENUMNAMESPACEPROVIDERSEXA = function (var lpdwBufferLength : DWord; + lpnspBuffer : PWSANAMESPACE_INFOEXA): Integer; stdcall; + + {$NODEFINE TWSANameSpace_InfoEx} + {$EXTERNALSYM WSANAMESPACE_INFOEX} + {$EXTERNALSYM PWSANAMESPACE_INFOEX} + {$EXTERNALSYM LPWSANAMESPACE_INFOEX} + {$EXTERNALSYM LPFN_WSAENUMNAMESPACEPROVIDERSEX} + {$IFDEF UNICODE} + WSANAMESPACE_INFOEX = WSANAMESPACE_INFOEXW; + TWSANameSpace_InfoEx = TWSANameSpace_InfoExW; + PWSANAMESPACE_INFOEX = PWSANAMESPACE_INFOEXW; + LPWSANAMESPACE_INFOEX = PWSANAMESPACE_INFOEX; + LPFN_WSAENUMNAMESPACEPROVIDERSEX = LPFN_WSAENUMNAMESPACEPROVIDERSEXW; + {$ELSE} + WSANAMESPACE_INFOEX = WSANAMESPACE_INFOEXA; + TWSANameSpace_InfoEx = TWSANameSpace_InfoExA; + PWSANAMESPACE_INFOEX = PWSANAMESPACE_INFOEXA; + LPWSANAMESPACE_INFOEX = PWSANAMESPACE_INFOEX; + LPFN_WSAENUMNAMESPACEPROVIDERSEX = LPFN_WSAENUMNAMESPACEPROVIDERSEXA; + {$ENDIF} +{$ENDIF} // WINCE + + {$NODEFINE TWSANameSpace_Info} + {$EXTERNALSYM WSANAMESPACE_INFO} + {$EXTERNALSYM PWSANAMESPACE_INFO} + {$EXTERNALSYM LPWSANAMESPACE_INFO} + {$IFDEF UNICODE} + TWSANameSpace_Info = TWSANameSpace_InfoW; + WSANAMESPACE_INFO = TWSANameSpace_InfoW; + PWSANAMESPACE_INFO = PWSANAMESPACE_INFOW; + LPWSANAMESPACE_INFO = LPWSANAMESPACE_INFOW; + {$ELSE} + TWSANameSpace_Info = TWSANameSpace_InfoA; + WSANAMESPACE_INFO = TWSANameSpace_InfoA; + PWSANAMESPACE_INFO = PWSANAMESPACE_INFOA; + LPWSANAMESPACE_INFO = LPWSANAMESPACE_INFOA; + {$ENDIF} + + {$IFDEF WINCE} + {$EXTERNALSYM DSCP_TRAFFIC_TYPE} + {$EXTERNALSYM DSCPTypeNotSet} + {$EXTERNALSYM DSCPBestEffort} + {$EXTERNALSYM DSCPBackground} + {$EXTERNALSYM DSCPExcellentEffort} + {$EXTERNALSYM DSCPVideo} + {$EXTERNALSYM DSCPAudio} + {$EXTERNALSYM DSCPControl} + {$EXTERNALSYM NumDSCPTrafficTypes} + DSCP_TRAFFIC_TYPE = ( + DSCPTypeNotSet = 0, + DSCPBestEffort = 1, + DSCPBackground = 2, + DSCPExcellentEffort = 3, + DSCPVideo = 4, + DSCPAudio = 5, + DSCPControl = 6); +// Define NumDSCPTrafficTypes as DSCPControl +//because FPC warns that enumerations must be descending. +//The original definition for DSCP_TRAFFIC_TYPE is: +// +///* differential service traffic types */ +//typedef enum _DSCP_TRAFFIC_TYPE +//{ +// DSCPTypeNotSet = 0, +// DSCPBestEffort = 1, +// DSCPBackground = 2, +// DSCPExcellentEffort = 3, +// DSCPVideo = 4, +// DSCPAudio = 5, +// DSCPControl = 6, +// NumDSCPTrafficTypes = 6 +//} //DSCP_TRAFFIC_TYPE; +const + NumDSCPTrafficTypes : DSCP_TRAFFIC_TYPE = DSCPControl; + +type + {$ENDIF} + + {$EXTERNALSYM WSAMSG} + WSAMSG = record + name : PSOCKADDR; ///* Remote address */ + namelen : Integer; ///* Remote address length * + lpBuffers : LPWSABUF; // /* Data buffer array */ + dwBufferCount : DWord; // /* Number of elements in the array */ + Control : WSABUF; // /* Control buffer */ + dwFlags : DWord; // /* Flags */ + end; + {$NODEFINE TWSAMSG} + TWSAMSG = WSAMSG; + {$EXTERNALSYM PWSAMSG} + PWSAMSG = ^TWSAMSG; + {$EXTERNALSYM LPWSAMSG} + LPWSAMSG = PWSAMSG; + + {$EXTERNALSYM _WSACMSGHDR} + _WSACMSGHDR = record + cmsg_len: SIZE_T; + cmsg_level: Integer; + cmsg_type: Integer; + { followed by UCHAR cmsg_data[] } + end; + {$EXTERNALSYM WSACMSGHDR} + WSACMSGHDR = _WSACMSGHDR; + {$EXTERNALSYM cmsghdr} + cmsghdr = _WSACMSGHDR; + {$NODEFINE TWSACMsgHdr} + TWSACMsgHdr = WSACMSGHDR; + {$EXTERNALSYM PWSACMSGHDR} + PWSACMSGHDR = ^TWSACMsgHdr; + {$EXTERNALSYM LPWSACMSGHDR} + LPWSACMSGHDR = PWSACMSGHDR; + {$EXTERNALSYM PCMSGHDR} + PCMSGHDR = ^CMSGHDR; +{$IFNDEF WINCE} + {$EXTERNALSYM WSAPOLLFD} + WSAPOLLFD = record + fd : TSocket; + events : SHORT; + revents : SHORT; + end; + {$NODEFINE TWSAPOLLFD} + TWSAPOLLFD = WSAPOLLFD; + {$EXTERNALSYM PWSAPOLLFD} + PWSAPOLLFD = ^TWSAPOLLFD; + {$EXTERNALSYM LPWSAPOLLFD} + LPWSAPOLLFD = PWSAPOLLFD; +{$ENDIF} + +{ WinSock 2 extensions -- data types for the condition function in } +{ WSAAccept() and overlapped I/O completion routine. } +type + {$EXTERNALSYM LPCONDITIONPROC} + LPCONDITIONPROC = function(lpCallerId: LPWSABUF; lpCallerData: LPWSABUF; lpSQOS, pGQOS: LPQOS; + lpCalleeId,lpCalleeData: LPWSABUF; g: PGROUP; dwCallbackData: DWORD_PTR): Integer; stdcall; + {$EXTERNALSYM LPWSAOVERLAPPED_COMPLETION_ROUTINE} + LPWSAOVERLAPPED_COMPLETION_ROUTINE = procedure(dwError, cbTransferred: DWORD; + lpOverlapped: LPWSAOVERLAPPED; dwFlags: DWORD); stdcall; + + {$EXTERNALSYM WSACOMPLETIONTYPE} + {$EXTERNALSYM NSP_NOTIFY_IMMEDIATELY} + {$EXTERNALSYM NSP_NOTIFY_HWND} + {$EXTERNALSYM NSP_NOTIFY_EVENT} + {$EXTERNALSYM NSP_NOTIFY_PORT} + {$EXTERNALSYM NSP_NOTIFY_APC} + WSACOMPLETIONTYPE = ( + NSP_NOTIFY_IMMEDIATELY, + NSP_NOTIFY_HWND, + NSP_NOTIFY_EVENT, + NSP_NOTIFY_PORT, + NSP_NOTIFY_APC); + {$EXTERNALSYM WSACOMPLETION_WINDOWMESSAGE} + WSACOMPLETION_WINDOWMESSAGE = record + hWnd : HWND; + uMsg : UINT; + context : WPARAM; + end; + {$EXTERNALSYM WSACOMPLETION_EVENT} + WSACOMPLETION_EVENT = record + lpOverlapped : LPWSAOVERLAPPED; + end; + {$EXTERNALSYM WSACOMPLETION_APC} + WSACOMPLETION_APC = record + lpOverlapped : LPWSAOVERLAPPED; + lpfnCompletionProc : LPWSAOVERLAPPED_COMPLETION_ROUTINE; + end; + {$EXTERNALSYM WSACOMPLETION_PORT} + WSACOMPLETION_PORT = record + lpOverlapped : LPWSAOVERLAPPED; + hPort : THandle; + Key : ULONG_PTR; + end; + {$EXTERNALSYM WSACOMPLETION_UNION} + WSACOMPLETION_union = record + case Integer of + 0: (WindowMessage : WSACOMPLETION_WINDOWMESSAGE); + 1: (Event : WSACOMPLETION_EVENT); + 2: (Apc : WSACOMPLETION_APC); + 3: (Port : WSACOMPLETION_PORT); + end; + {$EXTERNALSYM WSACOMPLETION} + WSACOMPLETION = record + _Type : WSACOMPLETIONTYPE; + Parameters : WSACOMPLETION_union; + end; + {$EXTERNALSYM PWSACOMPLETION} + PWSACOMPLETION = ^WSACOMPLETION; + {$EXTERNALSYM LPWSACOMPLETION} + LPWSACOMPLETION = PWSACOMPLETION; +{$IFNDEF WINCE} + {$EXTERNALSYM _RIO_NOTIFICATION_COMPLETION_TYPE} + {$EXTERNALSYM RIO_EVENT_COMPLETION} + {$EXTERNALSYM RIO_IOCP_COMPLETION} + {$IFNDEF HAS_ENUM_ELEMENT_VALUES} + {$NODEFINE rnctUnused} + {$ENDIF} + // The Pascal compiler in Delphi/BCB prior to v6 does not + // support specifying values for individual enum items + _RIO_NOTIFICATION_COMPLETION_TYPE = ( + {$IFDEF HAS_ENUM_ELEMENT_VALUES} + RIO_EVENT_COMPLETION = 1, + RIO_IOCP_COMPLETION = 2 + {$ELSE} + rnctUnused, // do not use + RIO_EVENT_COMPLETION, + RIO_IOCP_COMPLETION + {$ENDIF} + ); + {$EXTERNALSYM RIO_NOTIFICATION_COMPLETION_TYPE} + RIO_NOTIFICATION_COMPLETION_TYPE = _RIO_NOTIFICATION_COMPLETION_TYPE; + {$EXTERNALSYM PRIO_NOTIFICATION_COMPLETION_TYPE} + PRIO_NOTIFICATION_COMPLETION_TYPE = ^RIO_NOTIFICATION_COMPLETION_TYPE; + {$EXTERNALSYM _RIO_NOTIFICATION_COMPLETION} + {$EXTERNALSYM RIO_NOTIFICATION_COMPLETION} + {$EXTERNALSYM PRIO_NOTIFICATION_COMPLETION} + {$EXTERNALSYM _RIO_NOTIFICATION_COMPLETION_UNION} + {$EXTERNALSYM _RIO_NOTIFICATION_COMPLETION_IOCP} + {$EXTERNALSYM _RIO_NOTIFICATION_COMPLETION_EVENT} + _RIO_NOTIFICATION_COMPLETION_EVENT = record + EventHandle : THandle; + NotifyReset : BOOL; + end; + _RIO_NOTIFICATION_COMPLETION_IOCP = record + IocpHandle : THANDLE; + CompletionKey : PVOID; + Overlapped : PVOID; + end; + _RIO_NOTIFICATION_COMPLETION_UNION = record + case Integer of + 0 : (Event : _RIO_NOTIFICATION_COMPLETION_EVENT); + 1 : (Iocp : _RIO_NOTIFICATION_COMPLETION_IOCP); + end; + _RIO_NOTIFICATION_COMPLETION = record + _Type : RIO_NOTIFICATION_COMPLETION_TYPE; + a : _RIO_NOTIFICATION_COMPLETION_UNION; + end; + {$EXTERNALSYM RIO_NOTIFICATION_COMPLETION} + RIO_NOTIFICATION_COMPLETION = _RIO_NOTIFICATION_COMPLETION; + {$EXTERNALSYM PRIO_NOTIFICATION_COMPLETION} + PRIO_NOTIFICATION_COMPLETION = ^RIO_NOTIFICATION_COMPLETION; +{$ENDIF} + +type +{$IFDEF INCL_WINSOCK_API_TYPEDEFS} + {$EXTERNALSYM LPFN_WSASTARTUP} + LPFN_WSASTARTUP = function(const wVersionRequired: WORD; out WSData: TWSAData): Integer; stdcall; + {$EXTERNALSYM LPFN_WSACLEANUP} + LPFN_WSACLEANUP = function: Integer; stdcall; + {$EXTERNALSYM LPFN_ACCEPT} + LPFN_ACCEPT = function(const s: TSocket; AAddr: PSOCKADDR; addrlen: PInteger): TSocket; stdcall; + {$EXTERNALSYM LPFN_BIND} + LPFN_BIND = function(const s: TSocket; const name: PSOCKADDR; const namelen: Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_CLOSESOCKET} + LPFN_CLOSESOCKET = function(const s: TSocket): Integer; stdcall; + {$EXTERNALSYM LPFN_CONNECT} + LPFN_CONNECT = function(const s: TSocket; const name: PSOCKADDR; const namelen: Integer): Integer; stdcall; + {$EXTERNALSYM lpfn_IOCTLSOCKET} + LPFN_IOCTLSOCKET = function(const s: TSocket; const cmd: DWORD; var arg: u_long): Integer; stdcall; + {$EXTERNALSYM LPFN_GETPEERNAME} + LPFN_GETPEERNAME = function(const s: TSocket; const name: PSOCKADDR; var namelen: Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_GETSOCKNAME} + LPFN_GETSOCKNAME = function(const s: TSocket; const name: PSOCKADDR; var namelen: Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_GETSOCKOPT} + LPFN_GETSOCKOPT = function(const s: TSocket; const level, optname: Integer; optval: PIdAnsiChar; var optlen: Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_HTONL} + LPFN_HTONL = function(hostlong: u_long): u_long; stdcall; + {$EXTERNALSYM LPFN_HTONS} + LPFN_HTONS = function(hostshort: u_short): u_short; stdcall; + {$EXTERNALSYM LPFN_INET_ADDR} + LPFN_INET_ADDR = function(cp: PIdAnsiChar): u_long; stdcall; + {$EXTERNALSYM LPFN_INET_NTOA} + LPFN_INET_NTOA = function(inaddr: TInAddr): PIdAnsiChar; stdcall; + {$EXTERNALSYM LPFN_LISTEN} + LPFN_LISTEN = function(const s: TSocket; backlog: Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_NTOHL} + LPFN_NTOHL = function(netlong: u_long): u_long; stdcall; + {$EXTERNALSYM LPFN_NTOHS} + LPFN_NTOHS = function(netshort: u_short): u_short; stdcall; + {$EXTERNALSYM LPFN_RECV} + LPFN_RECV = function(const s: TSocket; var Buf; len, flags: Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_RECVFROM} + LPFN_RECVFROM = function(const s: TSocket; var Buf; len, flags: Integer; from: PSOCKADDR; fromlen: PInteger): Integer; stdcall; + {$EXTERNALSYM LPFN_SELECT} + LPFN_SELECT = function(nfds: Integer; readfds, writefds, exceptfds: PFDSet; timeout: PTimeVal): Integer; stdcall; + {$EXTERNALSYM LPFN_SEND} + LPFN_SEND = function(const s: TSocket; const Buf; len, flags: Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_SENDTO} + LPFN_SENDTO = function(const s: TSocket; const Buf; const len, flags: Integer; const addrto: PSOCKADDR; const tolen: Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_SETSOCKOPT} + LPFN_SETSOCKOPT = function(const s: TSocket; const level, optname: Integer; optval: PIdAnsiChar; const optlen: Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_SHUTDOWN} + LPFN_SHUTDOWN = function(const s: TSocket; const how: Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_SOCKET} + LPFN_SOCKET = function(const af, istruct, protocol: Integer): TSocket; stdcall; + {$EXTERNALSYM LPFN_GETHOSTBYADDR} + LPFN_GETHOSTBYADDR = function(AAddr: Pointer; const len, addrtype: Integer): PHostEnt; stdcall; + {$EXTERNALSYM LPFN_GETHOSTBYNAME} + LPFN_GETHOSTBYNAME = function(name: PIdAnsiChar): PHostEnt; stdcall; + {$EXTERNALSYM LPFN_GETHOSTNAME} + LPFN_GETHOSTNAME = function(name: PIdAnsiChar; len: Integer): Integer; stdcall; +{$IFDEF WINCE} + // WinCE specific for setting the host name + {$EXTERNALSYM LPFN_SETHOSTNAME} + LPFN_SETHOSTNAME = function(pName : PIdAnsiChar; len : Integer) : Integer; stdcall; +{$ENDIF} + {$EXTERNALSYM LPFN_GETSERVBYPORT} + LPFN_GETSERVBYPORT = function(const port: Integer; const proto: PIdAnsiChar): PServEnt; stdcall; + {$EXTERNALSYM LPFN_GETSERVBYNAME} + LPFN_GETSERVBYNAME = function(const name, proto: PIdAnsiChar): PServEnt; stdcall; + {$EXTERNALSYM LPFN_GETPROTOBYNUMBER} + LPFN_GETPROTOBYNUMBER = function(const proto: Integer): PProtoEnt; stdcall; + {$EXTERNALSYM LPFN_GETPROTOBYNAME} + LPFN_GETPROTOBYNAME = function(const name: PIdAnsiChar): PProtoEnt; stdcall; + {$EXTERNALSYM LPFN_WSASETLASTERROR} + LPFN_WSASETLASTERROR = procedure(const iError: Integer); stdcall; + {$EXTERNALSYM LPFN_WSAGETLASTERROR} + LPFN_WSAGETLASTERROR = function: Integer; stdcall; +{$IFNDEF WINCE} + {$EXTERNALSYM LPFN_WSACANCELASYNCREQUEST} + LPFN_WSACANCELASYNCREQUEST = function(hAsyncTaskHandle: THandle): Integer; stdcall; + {$EXTERNALSYM LPFN_WSAISBLOCKING} + LPFN_WSAISBLOCKING = function: BOOL; stdcall; + {$EXTERNALSYM LPFN_WSAUNHOOKBLOCKINGHOOK} + LPFN_WSAUNHOOKBLOCKINGHOOK = function: Integer; stdcall; + {$EXTERNALSYM LPFN_WSASETBLOCKINGHOOK} + LPFN_WSASETBLOCKINGHOOK = function(lpBlockFunc: TFarProc): TFarProc; stdcall; + {$EXTERNALSYM LPFN_WSACANCELBLOCKINGCALL} + LPFN_WSACANCELBLOCKINGCALL = function: Integer; stdcall; + {$EXTERNALSYM LPFN_WSAASYNCGETSERVBYNAME} + LPFN_WSAASYNCGETSERVBYNAME = function(HWindow: HWND; wMsg: u_int; name, proto, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; + {$EXTERNALSYM LPFN_WSAASYNCGETSERVBYPORT} + LPFN_WSAASYNCGETSERVBYPORT = function(HWindow: HWND; wMsg, port: u_int; proto, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; + {$EXTERNALSYM LPFN_WSAASYNCGETPROTOBYNAME} + LPFN_WSAASYNCGETPROTOBYNAME = function(HWindow: HWND; wMsg: u_int; name, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; + {$EXTERNALSYM LPFN_WSAASYNCGETPROTOBYNUMBER} + LPFN_WSAASYNCGETPROTOBYNUMBER = function(HWindow: HWND; wMsg: u_int; number: Integer; buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; + {$EXTERNALSYM LPFN_WSAASYNCGETHOSTBYNAME} + LPFN_WSAASYNCGETHOSTBYNAME = function(HWindow: HWND; wMsg: u_int; name, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; + {$EXTERNALSYM LPFN_WSAASYNCGETHOSTBYADDR} + LPFN_WSAASYNCGETHOSTBYADDR = function(HWindow: HWND; wMsg: u_int; AAddr: PIdAnsiChar; len, istruct: Integer; buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; + {$EXTERNALSYM LPFN_WSAASYNCSELECT} + LPFN_WSAASYNCSELECT = function(const s: TSocket; HWindow: HWND; wMsg: u_int; lEvent: Longint): Integer; stdcall; +{$ENDIF} + {$EXTERNALSYM LPFN___WSAFDISSET} + LPFN___WSAFDISSET = function(const s: TSocket; var FDSet: TFDSet): Bool; stdcall; + +// WinSock 2 API new function prototypes + {$EXTERNALSYM LPFN_WSAACCEPT} + LPFN_WSAACCEPT = function(const s : TSocket; AAddr : PSOCKADDR; addrlen : PInteger; lpfnCondition : LPCONDITIONPROC; const dwCallbackData : DWORD): TSocket; stdcall; + {$EXTERNALSYM LPFN_WSAENUMPROTOCOLSA} + LPFN_WSAENUMPROTOCOLSA = function(lpiProtocols : PInteger; lpProtocolBuffer : LPWSAPROTOCOL_INFOA; var lpdwBufferLength : DWORD) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSAENUMPROTOCOLSW} + LPFN_WSAENUMPROTOCOLSW = function(lpiProtocols : PInteger; lpProtocolBuffer : LPWSAPROTOCOL_INFOW; var lpdwBufferLength : DWORD) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSAGETOVERLAPPEDRESULT} + LPFN_WSAGETOVERLAPPEDRESULT = function(const s : TSocket; AOverlapped: Pointer; lpcbTransfer : LPDWORD; fWait : BOOL; var lpdwFlags : DWORD) : WordBool; stdcall; + {$EXTERNALSYM LPFN_WSAIOCTL} + LPFN_WSAIOCTL = function(const s : TSocket; dwIoControlCode : DWORD; lpvInBuffer : Pointer; cbInBuffer : DWORD; lpvOutBuffer : Pointer; cbOutBuffer : DWORD; + lpcbBytesReturned : LPDWORD; AOverlapped: Pointer; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSARECVFROM} + LPFN_WSARECVFROM = function(const s : TSocket; lpBuffers : LPWSABUF; dwBufferCount : DWORD; var lpNumberOfBytesRecvd : DWORD; var lpFlags : DWORD; + lpFrom : PSOCKADDR; lpFromlen : PInteger; AOverlapped: Pointer; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; + + {$EXTERNALSYM LPFN_TRANSMITFILE} + LPFN_TRANSMITFILE = function(hSocket: TSocket; hFile: THandle; nNumberOfBytesToWrite, nNumberOfBytesPerSend: DWORD; + lpOverlapped: POverlapped; lpTransmitBuffers: LPTRANSMIT_FILE_BUFFERS; dwReserved: DWORD): BOOL; stdcall; + {$EXTERNALSYM LPFN_ACCEPTEX} + LPFN_ACCEPTEX = function(sListenSocket, sAcceptSocket: TSocket; + lpOutputBuffer: Pointer; dwReceiveDataLength, dwLocalAddressLength, + dwRemoteAddressLength: DWORD; var lpdwBytesReceived: DWORD; + lpOverlapped: POverlapped): BOOL; stdcall; + {$IFNDEF WINCE} + {$EXTERNALSYM LPFN_WSACONNECTBYLIST} + LPFN_WSACONNECTBYLIST = function(const s : TSocket; SocketAddressList : PSOCKET_ADDRESS_LIST; + var LocalAddressLength : DWORD; LocalAddress : LPSOCKADDR; + var RemoteAddressLength : DWORD; RemoteAddress : LPSOCKADDR; + timeout : Ptimeval; Reserved : LPWSAOVERLAPPED):LongBool; stdcall; + {$EXTERNALSYM LPFN_WSACONNECTBYNAMEA} + LPFN_WSACONNECTBYNAMEA = function(const s : TSOCKET; + nodename : PIdAnsiChar; servicename : PIdAnsiChar; + var LocalAddressLength : DWORD; LocalAddress : LPSOCKADDR; + var RemoteAddressLength : DWORD; RemoteAddress : LPSOCKADDR; + timeout : Ptimeval; Reserved : LPWSAOVERLAPPED) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSACONNECTBYNAMEW} + LPFN_WSACONNECTBYNAMEW = function(const s : TSOCKET; + nodename : PWChar; servicename : PWChar; + var LocalAddressLength : DWORD; LocalAddress : LPSOCKADDR; + var RemoteAddressLength : DWORD; RemoteAddress : LPSOCKADDR; + timeout : Ptimeval; Reserved : LPWSAOVERLAPPED) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSACONNECTBYNAME} + {$IFDEF UNICODE} + LPFN_WSACONNECTBYNAME = LPFN_WSACONNECTBYNAMEW; + {$ELSE} + LPFN_WSACONNECTBYNAME = LPFN_WSACONNECTBYNAMEA; + {$ENDIF} +{$ENDIF} + + {$EXTERNALSYM LPFN_WSAENUMPROTOCOLS} + {wince} + {$IFDEF UNICODE} + LPFN_WSAENUMPROTOCOLS = LPFN_WSAENUMPROTOCOLSW; + {$ELSE} + LPFN_WSAENUMPROTOCOLS = LPFN_WSAENUMPROTOCOLSA; + {$ENDIF} + + {$EXTERNALSYM LPFN_WSACLOSEEVENT} + LPFN_WSACLOSEEVENT = function(const hEvent : WSAEVENT) : WordBool; stdcall; + {$EXTERNALSYM LPFN_WSACONNECT} + LPFN_WSACONNECT = function(const s : TSocket; const name : PSOCKADDR; const namelen : Integer; lpCallerData, lpCalleeData : LPWSABUF; lpSQOS, lpGQOS : LPQOS) : Integer; stdcall; + + {$EXTERNALSYM LPFN_WSACREATEEVENT} + LPFN_WSACREATEEVENT = function: WSAEVENT; stdcall; + + {$IFNDEF WINCE} + {$EXTERNALSYM LPFN_WSADUPLICATESOCKETA} + LPFN_WSADUPLICATESOCKETA = function(const s : TSocket; const dwProcessId : DWORD; lpProtocolInfo : LPWSAPROTOCOL_INFOA) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSADUPLICATESOCKETW} + LPFN_WSADUPLICATESOCKETW = function(const s : TSocket; const dwProcessId : DWORD; lpProtocolInfo : LPWSAPROTOCOL_INFOW) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSADUPLICATESOCKET} + {$IFDEF UNICODE} + LPFN_WSADUPLICATESOCKET = LPFN_WSADUPLICATESOCKETW; + {$ELSE} + LPFN_WSADUPLICATESOCKET = LPFN_WSADUPLICATESOCKETA; + {$ENDIF} + {$ENDIF} + + {$EXTERNALSYM LPFN_WSAENUMNETWORKEVENTS} + LPFN_WSAENUMNETWORKEVENTS = function(const s : TSocket; const hEventObject : WSAEVENT; lpNetworkEvents : LPWSANETWORKEVENTS) :Integer; stdcall; + + {$EXTERNALSYM LPFN_WSAEVENTSELECT} + LPFN_WSAEVENTSELECT = function(const s : TSocket; const hEventObject : WSAEVENT; lNetworkEvents : LongInt): Integer; stdcall; + {$EXTERNALSYM LPFN_WSAGETQOSBYNAME} + LPFN_WSAGETQOSBYNAME = function(const s : TSocket; lpQOSName : LPWSABUF; lpQOS : LPQOS): WordBool; stdcall; + {$EXTERNALSYM LPFN_WSAHTONL} + LPFN_WSAHTONL = function(const s : TSocket; hostlong : u_long; var lpnetlong : DWORD): Integer; stdcall; + {$EXTERNALSYM LPFN_WSAHTONS} + LPFN_WSAHTONS = function(const s : TSocket; hostshort : u_short; var lpnetshort : WORD): Integer; stdcall; + + {$EXTERNALSYM LPFN_WSAJOINLEAF} + LPFN_WSAJOINLEAF = function(const s : TSocket; name : PSOCKADDR; namelen : Integer; lpCallerData, lpCalleeData : LPWSABUF; + lpSQOS,lpGQOS : LPQOS; dwFlags : DWORD) : TSocket; stdcall; + + {$EXTERNALSYM LPFN_WSANTOHL} + LPFN_WSANTOHL = function(const s : TSocket; netlong : u_long; var lphostlong : DWORD): Integer; stdcall; + {$EXTERNALSYM LPFN_WSANTOHS} + LPFN_WSANTOHS = function(const s : TSocket; netshort : u_short; var lphostshort : WORD): Integer; stdcall; + + {$EXTERNALSYM LPFN_WSARECV} + LPFN_WSARECV = function(const s : TSocket; lpBuffers : LPWSABUF; dwBufferCount : DWORD; var lpNumberOfBytesRecvd : DWORD; var lpFlags : DWORD; + lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; + {$EXTERNALSYM LPFN_WSARECVDISCONNECT} + LPFN_WSARECVDISCONNECT = function(const s : TSocket; lpInboundDisconnectData : LPWSABUF): Integer; stdcall; + + {$EXTERNALSYM LPFN_WSARESETEVENT} + LPFN_WSARESETEVENT = function(hEvent : WSAEVENT): WordBool; stdcall; + + {$EXTERNALSYM LPFN_WSASEND} + LPFN_WSASEND = function(const s : TSocket; lpBuffers : LPWSABUF; dwBufferCount : DWORD; var lpNumberOfBytesSent : DWORD; dwFlags : DWORD; + lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; + {$EXTERNALSYM LPFN_WSASENDDISCONNECT} + LPFN_WSASENDDISCONNECT = function(const s : TSocket; lpOutboundDisconnectData : LPWSABUF): Integer; stdcall; + {$EXTERNALSYM LPFN_WSASENDTO} + LPFN_WSASENDTO = function(const s : TSocket; lpBuffers : LPWSABUF; dwBufferCount : DWORD; var lpNumberOfBytesSent : DWORD; dwFlags : DWORD; + lpTo : LPSOCKADDR; iTolen : Integer; lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; + + {$EXTERNALSYM LPFN_WSASETEVENT} + LPFN_WSASETEVENT = function(hEvent : WSAEVENT): WordBool; stdcall; + + {$EXTERNALSYM LPFN_WSASOCKETA} + LPFN_WSASOCKETA = function(af, iType, protocol : Integer; lpProtocolInfo : LPWSAPROTOCOL_INFOA; g : GROUP; dwFlags : DWORD): TSocket; stdcall; + {$EXTERNALSYM LPFN_WSASOCKETW} + LPFN_WSASOCKETW = function(af, iType, protocol : Integer; lpProtocolInfo : LPWSAPROTOCOL_INFOW; g : GROUP; dwFlags : DWORD): TSocket; stdcall; + {$EXTERNALSYM LPFN_WSASOCKET} + {$IFDEF UNICODE} + LPFN_WSASOCKET = LPFN_WSASOCKETW; + {$ELSE} + LPFN_WSASOCKET = LPFN_WSASOCKETA; + {$ENDIF} + + {$EXTERNALSYM LPFN_WSAWAITFORMULTIPLEEVENTS} + LPFN_WSAWAITFORMULTIPLEEVENTS = function(cEvents : DWORD; lphEvents : PWSAEVENT; fWaitAll : LongBool; + dwTimeout : DWORD; fAlertable : LongBool): DWORD; stdcall; + + {$EXTERNALSYM LPFN_WSAADDRESSTOSTRINGA} + LPFN_WSAADDRESSTOSTRINGA = function(lpsaAddress : PSOCKADDR; const dwAddressLength : DWORD; const lpProtocolInfo : LPWSAPROTOCOL_INFOA; + const lpszAddressString : PIdAnsiChar; var lpdwAddressStringLength : DWORD): Integer; stdcall; + {$EXTERNALSYM LPFN_WSAADDRESSTOSTRINGW} + LPFN_WSAADDRESSTOSTRINGW = function(lpsaAddress : PSOCKADDR; const dwAddressLength : DWORD; const lpProtocolInfo : LPWSAPROTOCOL_INFOW; + const lpszAddressString : PWideChar; var lpdwAddressStringLength : DWORD): Integer; stdcall; + {$EXTERNALSYM LPFN_WSAADDRESSTOSTRING} + {$IFDEF UNICODE} + LPFN_WSAADDRESSTOSTRING = LPFN_WSAADDRESSTOSTRINGW; + {$ELSE} + LPFN_WSAADDRESSTOSTRING = LPFN_WSAADDRESSTOSTRINGA; + {$ENDIF} + + {$EXTERNALSYM LPFN_WSASTRINGTOADDRESSA} + LPFN_WSASTRINGTOADDRESSA = function(const AddressString : PIdAnsiChar; const AddressFamily: Integer; const lpProtocolInfo : LPWSAPROTOCOL_INFOA; + var lpAddress : TSockAddr; var lpAddressLength : Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_WSASTRINGTOADDRESSW} + LPFN_WSASTRINGTOADDRESSW = function(const AddressString : PWideChar; const AddressFamily: Integer; const lpProtocolInfo : LPWSAPROTOCOL_INFOW; + var lpAddress : TSockAddr; var lpAddressLength : Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_WSASTRINGTOADDRESS} + {$IFDEF UNICODE} + LPFN_WSASTRINGTOADDRESS = LPFN_WSASTRINGTOADDRESSW; + {$ELSE} + LPFN_WSASTRINGTOADDRESS = LPFN_WSASTRINGTOADDRESSA; + {$ENDIF} + +// Registration and Name Resolution API functions + {$EXTERNALSYM LPFN_WSALOOKUPSERVICEBEGINA} + LPFN_WSALOOKUPSERVICEBEGINA = function(var qsRestrictions : TWSAQuerySetA; const dwControlFlags : DWORD; var hLookup : THandle): Integer; stdcall; + {$EXTERNALSYM LPFN_WSALOOKUPSERVICEBEGINw} + LPFN_WSALOOKUPSERVICEBEGINW = function(var qsRestrictions : TWSAQuerySetW; const dwControlFlags : DWORD; var hLookup : THandle): Integer; stdcall; + {$EXTERNALSYM LPFN_WSALOOKUPSERVICEBEGIN} + {$IFDEF UNICODE} + LPFN_WSALOOKUPSERVICEBEGIN = LPFN_WSALOOKUPSERVICEBEGINW; + {$ELSE} + LPFN_WSALOOKUPSERVICEBEGIN = LPFN_WSALOOKUPSERVICEBEGINA; + {$ENDIF} + + {$EXTERNALSYM LPFN_WSALOOKUPSERVICENEXTA} + LPFN_WSALOOKUPSERVICENEXTA = function(const hLookup : THandle; const dwControlFlags : DWORD; var dwBufferLength : DWORD; lpqsResults : PWSAQUERYSETA): Integer; stdcall; + {$EXTERNALSYM LPFN_WSALOOKUPSERVICENEXTW} + LPFN_WSALOOKUPSERVICENEXTW = function(const hLookup : THandle; const dwControlFlags : DWORD; var dwBufferLength : DWORD; lpqsResults : PWSAQUERYSETW): Integer; stdcall; + {$EXTERNALSYM LPFN_WSALOOKUPSERVICENEXT} + {$IFDEF UNICODE} + LPFN_WSALOOKUPSERVICENEXT = LPFN_WSALOOKUPSERVICENEXTW; + {$ELSE} + LPFN_WSALOOKUPSERVICENEXT = LPFN_WSALOOKUPSERVICENEXTA; + {$ENDIF} + + //WinCE 4.20 doesn't support WSANSPIoctl but later versions do. + {$EXTERNALSYM LPFN_WSANSPIOCTL} + LPFN_WSANSPIOCTL = function(const hLookup : THANDLE; const dwControlCode : DWORD; lpvInBuffer : Pointer; var cbInBuffer : DWORD; lpvOutBuffer : Pointer; var cbOutBuffer : DWORD; var lpcbBytesReturned : DWORD; lpCompletion : LPWSACOMPLETION) : Integer; stdcall; + + {$EXTERNALSYM LPFN_WSALOOKUPSERVICEEND} + LPFN_WSALOOKUPSERVICEEND = function(const hLookup : THandle): Integer; stdcall; + + + {$EXTERNALSYM LPFN_WSAINSTALLSERVICECLASSA} + LPFN_WSAINSTALLSERVICECLASSA = function(const lpServiceClassInfo : LPWSASERVICECLASSINFOA) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSAINSTALLSERVICECLASSW} + LPFN_WSAINSTALLSERVICECLASSW = function(const lpServiceClassInfo : LPWSASERVICECLASSINFOW) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSAINSTALLSERVICECLASS} + {$IFDEF UNICODE} + LPFN_WSAINSTALLSERVICECLASS = LPFN_WSAINSTALLSERVICECLASSW; + {$ELSE} + LPFN_WSAINSTALLSERVICECLASS = LPFN_WSAINSTALLSERVICECLASSA; + {$ENDIF} + + {$EXTERNALSYM LPFN_WSAREMOVESERVICECLASS} + LPFN_WSAREMOVESERVICECLASS = function(const lpServiceClassId : LPGUID) : Integer; stdcall; + + {$EXTERNALSYM LPFN_WSAGETSERVICECLASSINFOA} + LPFN_WSAGETSERVICECLASSINFOA = function(const lpProviderId : LPGUID; const lpServiceClassId : LPGUID; var lpdwBufSize : DWORD; + lpServiceClassInfo : LPWSASERVICECLASSINFOA): Integer; stdcall; + {$EXTERNALSYM LPFN_WSAGETSERVICECLASSINFOW} + LPFN_WSAGETSERVICECLASSINFOW = function(const lpProviderId : LPGUID; const lpServiceClassId : LPGUID; var lpdwBufSize : DWORD; + lpServiceClassInfo : LPWSASERVICECLASSINFOW): Integer; stdcall; + {$EXTERNALSYM LPFN_WSAGETSERVICECLASSINFO} + {$IFDEF UNICODE} + LPFN_WSAGETSERVICECLASSINFO = LPFN_WSAGETSERVICECLASSINFOW; + {$ELSE} + LPFN_WSAGETSERVICECLASSINFO = LPFN_WSAGETSERVICECLASSINFOA; + {$ENDIF} + {$ENDIF} + + {$EXTERNALSYM LPFN_WSAENUMNAMESPACEPROVIDERSA} + LPFN_WSAENUMNAMESPACEPROVIDERSA = function(var lpdwBufferLength: DWORD; const lpnspBuffer: LPWSANAMESPACE_INFOA): Integer; stdcall; + {$EXTERNALSYM LPFN_WSAENUMNAMESPACEPROVIDERSW} + LPFN_WSAENUMNAMESPACEPROVIDERSW = function(var lpdwBufferLength: DWORD; const lpnspBuffer: LPWSANAMESPACE_INFOW): Integer; stdcall; + {$EXTERNALSYM LPFN_WSAENUMNAMESPACEPROVIDERS} + {$IFDEF UNICODE} + LPFN_WSAENUMNAMESPACEPROVIDERS = LPFN_WSAENUMNAMESPACEPROVIDERSW; + {$ELSE} + LPFN_WSAENUMNAMESPACEPROVIDERS = LPFN_WSAENUMNAMESPACEPROVIDERSA; + {$ENDIF} + + {$EXTERNALSYM LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDA} + LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDA = function(const lpServiceClassId: LPGUID; lpszServiceClassName: PIdAnsiChar; var lpdwBufferLength: DWORD): Integer; stdcall; + {$EXTERNALSYM LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDW} + LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDW = function(const lpServiceClassId: LPGUID; lpszServiceClassName: PWideChar; var lpdwBufferLength: DWORD): Integer; stdcall; + {$EXTERNALSYM LPFN_WSAGETSERVICECLASSNAMEBYCLASSID} + {$IFDEF UNICODE} + LPFN_WSAGETSERVICECLASSNAMEBYCLASSID = LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDW; + {$ELSE} + LPFN_WSAGETSERVICECLASSNAMEBYCLASSID = LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDA; + {$ENDIF} + + {$EXTERNALSYM LPFN_WSASETSERVICEA} + LPFN_WSASETSERVICEA = function(const lpqsRegInfo: LPWSAQUERYSETA; const essoperation: WSAESETSERVICEOP; const dwControlFlags: DWORD): Integer; stdcall; + {$EXTERNALSYM LPFN_WSASETSERVICEW} + LPFN_WSASETSERVICEW = function(const lpqsRegInfo: LPWSAQUERYSETW; const essoperation: WSAESETSERVICEOP; const dwControlFlags: DWORD): Integer; stdcall; + {$EXTERNALSYM LPFN_WSASETSERVICE} + {$IFDEF UNICODE} + LPFN_WSASETSERVICE = LPFN_WSASETSERVICEW; + {$ELSE} + LPFN_WSASETSERVICE = LPFN_WSASETSERVICEA; + {$ENDIF} + + {$EXTERNALSYM LPFN_WSAPROVIDERCONFIGCHANGE} + LPFN_WSAPROVIDERCONFIGCHANGE = function(var lpNotificationHandle : THandle; lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; + + //microsoft specific extension + {$EXTERNALSYM LPFN_GETACCEPTEXSOCKADDRS} + LPFN_GETACCEPTEXSOCKADDRS = procedure(lpOutputBuffer: Pointer; + dwReceiveDataLength, dwLocalAddressLength, dwRemoteAddressLength: DWORD; + var LocalSockaddr: TSockAddr; var LocalSockaddrLength: Integer; + var RemoteSockaddr: TSockAddr; var RemoteSockaddrLength: Integer); stdcall; + + {$IFNDEF WINCE} + //This is defined in the Windows Mobile 6 Standard SDK Refresh + //but I'm not sure what .DLL the function is in. I also couldn't find a WSAID + //constant for it. + {$EXTERNALSYM LPFN_WSARECVEX} + LPFN_WSARECVEX = function(s: TSocket; var buf; len: Integer; var flags: Integer): Integer; stdcall; + {$ENDIF} + + //Windows Server 2003, Windows Vista + {$EXTERNALSYM LPFN_CONNECTEX} + LPFN_CONNECTEX = function(const s : TSocket; const name: PSOCKADDR; const namelen: Integer; lpSendBuffer : Pointer; dwSendDataLength : DWORD; var lpdwBytesSent : DWORD; lpOverlapped : LPWSAOVERLAPPED) : BOOL; stdcall; + {$EXTERNALSYM LPFN_DISCONNECTEX} + LPFN_DISCONNECTEX = function(const hSocket : TSocket; AOverlapped: Pointer; const dwFlags : DWORD; const dwReserved : DWORD) : BOOL; stdcall; + {$EXTERNALSYM LPFN_WSARECVMSG} //XP and Server 2003 only + LPFN_WSARECVMSG = function(const s : TSocket; lpMsg : LPWSAMSG; var lpNumberOfBytesRecvd : DWORD; AOverlapped: Pointer; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; + {$EXTERNALSYM LPFN_TRANSMITPACKETS} + LPFN_TRANSMITPACKETS = function(s: TSocket; lpPacketArray: LPTRANSMIT_PACKETS_ELEMENT; nElementCount: DWORD; nSendSize: DWORD; lpOverlapped: LPWSAOVERLAPPED; dwFlags: DWORD): BOOL; stdcall; + //Windows Vista, Windows Server 2008 +{$IFNDEF WINCE} + {$EXTERNALSYM LPFN_WSASENDMSG} + LPFN_WSASENDMSG = function(const s : TSocket; lpMsg : LPWSAMSG; const dwFlags : DWORD; var lpNumberOfBytesSent : DWORD; lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSAPOLL} + LPFN_WSAPOLL = function(fdarray : LPWSAPOLLFD; const nfds : u_long; const timeout : Integer) : Integer; stdcall; + {$EXTERNALSYM LPFN_RIORECEIVE} + LPFN_RIORECEIVE = function (SocketQueue : RIO_RQ; + pData : PRIO_BUF; + const DataBufferCount : ULONG; + Flags : DWORD; + RequestContext : PVOID) : BOOL stdcall; + {$EXTERNALSYM LPFN_RIORECEIVEEX} + LPFN_RIORECEIVEEX = function (SocketQueu : RIO_RQ; + pData : PRIO_BUF; + const DataBufferCount : ULONG; + pLocalAddress, pRemoteAddress, pControlContext, pFlags : PRIO_BUF; + const Flags : DWORD; RequestContext : PVOID) : Integer stdcall; + {$EXTERNALSYM LPFN_RIOSEND} + LPFN_RIOSEND = function(SocketQueue : RIO_RQ; + pData : PRIO_BUF; + const DataBufferCount : ULONG; + const Flags : DWORD; + const RequestContext : PVOID) : Boolean stdcall; + {$EXTERNALSYM LPFN_RIOSENDEX} + LPFN_RIOSENDEX = function (SocketQueue : RIO_RQ; + pData : PRIO_BUF; + const DataBufferCount : ULONG; + pLocalAddress, pRemoteAddress, pControlContext, pFlags : PRIO_BUF; + const Flags : DWORD; + RequestContext : PVOID) : Boolean stdcall; + {$EXTERNALSYM LPFN_RIOCREATECOMPLETIONQUEUE} + LPFN_RIOCREATECOMPLETIONQUEUE = function (const QueueSize : DWORD; + NotificationCompletion : PRIO_NOTIFICATION_COMPLETION) : RIO_CQ stdcall; + {$EXTERNALSYM LPFN_RIOCREATEREQUESTQUEUE} + LPFN_RIOCREATEREQUESTQUEUE = function (const Socket : TSOCKET; + const MaxOutstandingReceive, MaxReceiveDataBuffers, MaxOutstandingSend, MaxSendDataBuffers : ULONG; + const ReceiveCQ, SendCQ : RIO_CQ; SocketContext : PVOID) : RIO_RQ stdcall; + {$EXTERNALSYM LPFN_RIODEQUEUECOMPLETION} + LPFN_RIODEQUEUECOMPLETION = function (const CQ : RIO_CQ; _Array : PRIORESULT; const ArraySize : ULONG) : ULONG stdcall; + {$EXTERNALSYM LPFN_RIODEREGISTERBUFFER} + LPFN_RIODEREGISTERBUFFER = procedure (const BufferId : RIO_BUFFERID) stdcall; + {$EXTERNALSYM LPFN_RIONOTIFY} + LPFN_RIONOTIFY = function (CQ : RIO_CQ) : Integer stdcall; + {$EXTERNALSYM LPFN_RIOREGISTERBUFFER} + LPFN_RIOREGISTERBUFFER = function (DataBuffer : PIdAnsiChar; const DataLength : DWORD) : BOOL stdcall; + {$EXTERNALSYM LPFN_RIORESIZECOMPLETIONQUEUE} + LPFN_RIORESIZECOMPLETIONQUEUE = function(const CQ : RIO_CQ; const QueueSize : DWORD) : BOOL stdcall; + {$EXTERNALSYM LPFN_RIORESIZEREQUESTQUEUE} + LPFN_RIORESIZEREQUESTQUEUE = function(const RQ : RIO_RQ; const MaxOutstandingReceive, MaxOutstandingSend : DWORD) : BOOL stdcall; + {$EXTERNALSYM LPFN_RIOCLOSECOMPLETIONQUEUE} + LPFN_RIOCLOSECOMPLETIONQUEUE = procedure (const CQ : RIO_CQ) stdcall; + {$EXTERNALSYM _RIO_EXTENSION_FUNCTION_TABLE} + _RIO_EXTENSION_FUNCTION_TABLE = record + cbSize : DWORD; + RIOReceive : LPFN_RIORECEIVE; + RIOReceiveEx : LPFN_RIORECEIVEEX; + RIOSend : LPFN_RIOSEND; + RIOSendEx : LPFN_RIOSENDEX; + RIOCloseCompletionQueue : LPFN_RIOCLOSECOMPLETIONQUEUE; + RIOCreateCompletionQueue : LPFN_RIOCREATECOMPLETIONQUEUE; + RIOCreateRequestQueue : LPFN_RIOCREATEREQUESTQUEUE; + RIODequeueCompletion : LPFN_RIODEQUEUECOMPLETION; + RIODeregisterBuffer : LPFN_RIODEREGISTERBUFFER; + RIONotify : LPFN_RIONOTIFY; + RIORegisterBuffer : LPFN_RIOREGISTERBUFFER; + RIOResizeCompletionQueue : LPFN_RIORESIZECOMPLETIONQUEUE; + RIOResizeRequestQueue : LPFN_RIORESIZEREQUESTQUEUE; + end; + {$EXTERNALSYM RIO_EXTENSION_FUNCTION_TABLE} + RIO_EXTENSION_FUNCTION_TABLE = _RIO_EXTENSION_FUNCTION_TABLE; + {$EXTERNALSYM PRIO_EXTENSION_FUNCTION_TABLE} + PRIO_EXTENSION_FUNCTION_TABLE = ^RIO_EXTENSION_FUNCTION_TABLE; +{$ENDIF} // $IFDEF INCL_WINSOCK_API_TYPEDEFS + + +const + //GUID's for Microsoft extensions + {$EXTERNALSYM WSAID_ACCEPTEX} + WSAID_ACCEPTEX: TGuid = (D1:$b5367df1;D2:$cbac;D3:$11cf;D4:($95,$ca,$00,$80,$5f,$48,$a1,$92)); + {$EXTERNALSYM WSAID_CONNECTEX} + WSAID_CONNECTEX: TGuid = (D1:$25a207b9;D2:$ddf3;D3:$4660;D4:($8e,$e9,$76,$e5,$8c,$74,$06,$3e)); + {$EXTERNALSYM WSAID_DISCONNECTEX} + WSAID_DISCONNECTEX: TGuid = (D1:$7fda2e11;D2:$8630;D3:$436f;D4:($a0,$31,$f5,$36,$a6,$ee,$c1,$57)); + {$EXTERNALSYM WSAID_GETACCEPTEXSOCKADDRS} + WSAID_GETACCEPTEXSOCKADDRS: TGuid = (D1:$b5367df2;D2:$cbac;D3:$11cf;D4:($95,$ca,$00,$80,$5f,$48,$a1,$92)); + {$EXTERNALSYM WSAID_TRANSMITFILE} + WSAID_TRANSMITFILE: TGuid = (D1:$b5367df0; D2:$cbac; D3:$11cf; D4:($95, $ca, $00, $80, $5f, $48, $a1, $92)); + {$EXTERNALSYM WSAID_TRANSMITPACKETS} + WSAID_TRANSMITPACKETS: TGuid = (D1:$d9689da0;D2:$1f90;D3:$11d3;D4:($99,$71,$00,$c0,$4f,$68,$c8,$76)); +{$IFNDEF WINCE} + {$EXTERNALSYM WSAID_WSAPOLL} + WSAID_WSAPOLL: TGuid = (D1:$18C76F85;D2:$DC66;D3:$4964;D4:($97,$2E,$23,$C2,$72,$38,$31,$2B)); +{$ENDIF} + {$EXTERNALSYM WSAID_WSARECVMSG} + WSAID_WSARECVMSG: TGuid = (D1:$f689d7c8;D2:$6f1f;D3:$436b;D4:($8a,$53,$e5,$4f,$e3,$51,$c3,$22)); +{$IFNDEF WINCE} + {$EXTERNALSYM WSAID_WSASENDMSG} + WSAID_WSASENDMSG : TGuid = (D1:$a441e712;D2:$754f;D3:$43ca;D4:($84,$a7,$0d,$ee,$44,$cf,$60,$6d)); + {$EXTERNALSYM WSAID_MULTIPLE_RIO} + WSAID_MULTIPLE_RIO : TGuid = (D1:$8509e081;D2:$96dd;D3:$4005;D4:($b1,$65,$9e,$2e,$e8,$c7,$9e,$3f)); +{$ENDIF} + +{$IFDEF WS2_DLL_FUNC_VARS} +var + {$EXTERNALSYM WSAStartup} + WSAStartup : LPFN_WSASTARTUP = nil; + {$EXTERNALSYM WSACleanup} + WSACleanup : LPFN_WSACLEANUP = nil; + {$EXTERNALSYM accept} + accept : LPFN_ACCEPT = nil; + {$EXTERNALSYM bind} + bind : LPFN_BIND = nil; + {$EXTERNALSYM closesocket} + closesocket : LPFN_CLOSESOCKET = nil; + {$EXTERNALSYM connect} + connect : LPFN_CONNECT = nil; + {$EXTERNALSYM ioctlsocket} + ioctlsocket : LPFN_IOCTLSOCKET = nil; + {$EXTERNALSYM getpeername} + getpeername : LPFN_GETPEERNAME = nil; + {$EXTERNALSYM getsockname} + getsockname : LPFN_GETSOCKNAME = nil; + {$EXTERNALSYM getsockopt} + getsockopt : LPFN_GETSOCKOPT = nil; + {$EXTERNALSYM htonl} + htonl : LPFN_HTONL = nil; + {$EXTERNALSYM htons} + htons : LPFN_HTONS = nil; + {$EXTERNALSYM inet_addr} + inet_addr : LPFN_INET_ADDR = nil; + {$EXTERNALSYM inet_ntoa} + inet_ntoa : LPFN_INET_NTOA = nil; + {$EXTERNALSYM listen} + listen : LPFN_LISTEN = nil; + {$EXTERNALSYM ntohl} + ntohl : LPFN_NTOHL = nil; + {$EXTERNALSYM ntohs} + ntohs : LPFN_NTOHS = nil; + {$EXTERNALSYM recv} + recv : LPFN_RECV = nil; + {$EXTERNALSYM recvfrom} + recvfrom : LPFN_RECVFROM = nil; + {$EXTERNALSYM select} + select : LPFN_SELECT = nil; + {$EXTERNALSYM send} + send : LPFN_SEND = nil; + {$EXTERNALSYM sendto} + sendto : LPFN_SENDTO = nil; + {$EXTERNALSYM setsockopt} + setsockopt : LPFN_SETSOCKOPT = nil; + {$EXTERNALSYM shutdown} + shutdown : LPFN_SHUTDOWN = nil; + {$EXTERNALSYM socket} + socket : LPFN_SOCKET = nil; + {$EXTERNALSYM gethostbyaddr} + gethostbyaddr : LPFN_GETHOSTBYADDR = nil; + {$EXTERNALSYM gethostbyname} + gethostbyname : LPFN_GETHOSTBYNAME = nil; + {$EXTERNALSYM gethostname} + gethostname : LPFN_GETHOSTNAME = nil; + {$IFDEF WINCE} + {$EXTERNALSYM sethostname} + sethostname : LPFN_SETHOSTNAME = nil; + {$ENDIF} + {$EXTERNALSYM getservbyport} + getservbyport : LPFN_GETSERVBYPORT = nil; + {$EXTERNALSYM getservbyname} + getservbyname : LPFN_GETSERVBYNAME = nil; + {$EXTERNALSYM getprotobynumber} + getprotobynumber : LPFN_GETPROTOBYNUMBER = nil; + {$EXTERNALSYM getprotobyname} + getprotobyname : LPFN_GETPROTOBYNAME = nil; + {$EXTERNALSYM WSASetLastError} + WSASetLastError : LPFN_WSASETLASTERROR = nil; + {$EXTERNALSYM WSAGetLastError} + WSAGetLastError : LPFN_WSAGETLASTERROR = nil; +{$IFNDEF WINCE} + {$EXTERNALSYM WSAIsblocking} + WSAIsBlocking : LPFN_WSAISBLOCKING = nil; + {$EXTERNALSYM WSAUnhookBlockingHook} + WSAUnhookBlockingHook : LPFN_WSAUNHOOKBLOCKINGHOOK = nil; + {$EXTERNALSYM WSASetBlockingHook} + WSASetBlockingHook : LPFN_WSASETBLOCKINGHOOK = nil; + {$EXTERNALSYM WSACancelBlockingCall} + WSACancelBlockingCall : LPFN_WSACANCELBLOCKINGCALL = nil; + {$EXTERNALSYM WSAAsyncGetServByName} + WSAAsyncGetServByName : LPFN_WSAASYNCGETSERVBYNAME = nil; + {$EXTERNALSYM WSAAsyncGetServByPort} + WSAAsyncGetServByPort : LPFN_WSAASYNCGETSERVBYPORT = nil; + {$EXTERNALSYM WSAAsyncGetProtoByName} + WSAAsyncGetProtoByName : LPFN_WSAASYNCGETPROTOBYNAME = nil; + {$EXTERNALSYM WSAAsyncGetProtoByNumber} + WSAAsyncGetProtoByNumber : LPFN_WSAASYNCGETPROTOBYNUMBER = nil; + {$EXTERNALSYM WSAAsyncGetHostByName} + WSAAsyncGetHostByName : LPFN_WSAASYNCGETHOSTBYNAME = nil; + {$EXTERNALSYM WSAAsyncGetHostByAddr} + WSAAsyncGetHostByAddr : LPFN_WSAASYNCGETHOSTBYADDR = nil; + {$EXTERNALSYM WSACancelAsyncRequest} + WSACancelAsyncRequest : LPFN_WSACANCELASYNCREQUEST = nil; + {$EXTERNALSYM WSAAsyncSelect} + WSAAsyncSelect : LPFN_WSAASYNCSELECT = nil; +{$ENDIF} + {$EXTERNALSYM __WSAFDIsSet} + __WSAFDIsSet : LPFN___WSAFDISSET = nil; + {$EXTERNALSYM WSAAccept} + WSAAccept : LPFN_WSAACCEPT = nil; + {$EXTERNALSYM WSAAddressToStringA} + WSAAddressToStringA : LPFN_WSAADDRESSTOSTRINGA = nil; + {$EXTERNALSYM WSAAddressToStringW} + WSAAddressToStringW : LPFN_WSAADDRESSTOSTRINGW = nil; + {$EXTERNALSYM WSAAddressToString} + WSAAddressToString : LPFN_WSAADDRESSTOSTRING = nil; + {$EXTERNALSYM WSACloseEvent} + WSACloseEvent : LPFN_WSACLOSEEVENT = nil; + {$EXTERNALSYM WSAConnect} + WSAConnect : LPFN_WSACONNECT = nil; + {$EXTERNALSYM WSACreateEvent} + WSACreateEvent : LPFN_WSACREATEEVENT = nil; + {$IFNDEF WINCE} + {$EXTERNALSYM WSADuplicateSocketA} + WSADuplicateSocketA : LPFN_WSADUPLICATESOCKETA = nil; + {$EXTERNALSYM WSADuplicateSocketW} + WSADuplicateSocketW : LPFN_WSADUPLICATESOCKETW = nil; + {$EXTERNALSYM WSADuplicateSocket} + WSADuplicateSocket : LPFN_WSADUPLICATESOCKET = nil; + {$ENDIF} + {$EXTERNALSYM WSAEnumNetworkEvents} + WSAEnumNetworkEvents : LPFN_WSAENUMNETWORKEVENTS = nil; + {$EXTERNALSYM WSAEnumProtocolsA} + WSAEnumProtocolsA : LPFN_WSAENUMPROTOCOLSA = nil; + {$EXTERNALSYM WSAEnumProtocolsW} + WSAEnumProtocolsW : LPFN_WSAENUMPROTOCOLSW = nil; + {$EXTERNALSYM WSAEnumProtocols} + WSAEnumProtocols : LPFN_WSAENUMPROTOCOLS = nil; + {$EXTERNALSYM WSAEnumNameSpaceProvidersA} + WSAEnumNameSpaceProvidersA : LPFN_WSAENUMNAMESPACEPROVIDERSA = nil; + {$EXTERNALSYM WSAEnumNameSpaceProvidersW} + WSAEnumNameSpaceProvidersW : LPFN_WSAENUMNAMESPACEPROVIDERSW = nil; + {$EXTERNALSYM WSAEnumNameSpaceProviders} + WSAEnumNameSpaceProviders : LPFN_WSAENUMNAMESPACEPROVIDERS = nil; + {$EXTERNALSYM WSAEventSelect} + WSAEventSelect : LPFN_WSAEVENTSELECT = nil; + {$EXTERNALSYM WSAGetOverlappedResult} + WSAGetOverlappedResult : LPFN_WSAGETOVERLAPPEDRESULT = nil; + + {$EXTERNALSYM WSAGetQosByName} + WSAGetQosByName : LPFN_WSAGETQOSBYNAME = nil; + {$EXTERNALSYM WSAGetServiceClassInfoA} + WSAGetServiceClassInfoA : LPFN_WSAGETSERVICECLASSINFOA = nil; + {$EXTERNALSYM WSAGetServiceClassInfoW} + WSAGetServiceClassInfoW : LPFN_WSAGETSERVICECLASSINFOW = nil; + {$EXTERNALSYM WSAGetServiceClassInfo} + WSAGetServiceClassInfo : LPFN_WSAGETSERVICECLASSINFO = nil; + {$EXTERNALSYM WSAGetServiceClassNameByClassIdA} + WSAGetServiceClassNameByClassIdA : LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDA = nil; + {$EXTERNALSYM WSAGetServiceClassNameByClassIdW} + WSAGetServiceClassNameByClassIdW : LPFN_WSAGETSERVICECLASSNAMEBYCLASSIDW = nil; + {$EXTERNALSYM WSAGetServiceClassNameByClassId} + WSAGetServiceClassNameByClassId : LPFN_WSAGETSERVICECLASSNAMEBYCLASSID = nil; + + {$EXTERNALSYM WSAHtonl} + WSAHtonl : LPFN_WSAHTONL = nil; + {$EXTERNALSYM WSAHtons} + WSAHtons : LPFN_WSAHTONS = nil; + {$EXTERNALSYM WSAIoctl} + WSAIoctl : LPFN_WSAIOCTL = nil; + {$EXTERNALSYM WSAInstallServiceClassA} + WSAInstallServiceClassA : LPFN_WSAINSTALLSERVICECLASSA = nil; + {$EXTERNALSYM WSAInstallServiceClassW} + WSAInstallServiceClassW : LPFN_WSAINSTALLSERVICECLASSW = nil; + {$EXTERNALSYM WSAInstallServiceClass} + WSAInstallServiceClass : LPFN_WSAINSTALLSERVICECLASS = nil; + {$EXTERNALSYM WSAJoinLeaf} + WSAJoinLeaf : LPFN_WSAJOINLEAF = nil; + {$EXTERNALSYM WSALookupServiceBeginA} + WSALookupServiceBeginA : LPFN_WSALOOKUPSERVICEBEGINA = nil; + {$EXTERNALSYM WSALookupServiceBeginW} + WSALookupServiceBeginW : LPFN_WSALOOKUPSERVICEBEGINW = nil; + {$EXTERNALSYM WSALookupServiceBegin} + WSALookupServiceBegin : LPFN_WSALOOKUPSERVICEBEGIN = nil; + {$EXTERNALSYM WSALookupServiceEnd} + WSALookupServiceEnd : LPFN_WSALOOKUPSERVICEEND = nil; + {$EXTERNALSYM WSALookupServiceNextA} + WSALookupServiceNextA : LPFN_WSALOOKUPSERVICENEXTA = nil; + {$EXTERNALSYM WSALookupServiceNextW} + WSALookupServiceNextW : LPFN_WSALOOKUPSERVICENEXTW = nil; + {$EXTERNALSYM WSALookupServiceNext} + WSALookupServiceNext : LPFN_WSALOOKUPSERVICENEXT = nil; + {$EXTERNALSYM WSANtohl} + WSANtohl : LPFN_WSANTOHL = nil; + {$EXTERNALSYM WSANtohs} + WSANtohs : LPFN_WSANTOHS = nil; + {$EXTERNALSYM WSARecv} + WSARecv : LPFN_WSARECV = nil; + {$EXTERNALSYM WSARecvDisconnect} + WSARecvDisconnect : LPFN_WSARECVDISCONNECT = nil; + {$EXTERNALSYM WSARecvFrom} + WSARecvFrom : LPFN_WSARECVFROM = nil; + {$EXTERNALSYM WSARemoveServiceClass} + WSARemoveServiceClass : LPFN_WSAREMOVESERVICECLASS = nil; + {$EXTERNALSYM WSAResetEvent} + WSAResetEvent : LPFN_WSARESETEVENT = nil; + {$EXTERNALSYM WSASend} + WSASend : LPFN_WSASEND = nil; + {$EXTERNALSYM WSASendDisconnect} + WSASendDisconnect : LPFN_WSASENDDISCONNECT = nil; + {$EXTERNALSYM WSASendTo} + WSASendTo : LPFN_WSASENDTO = nil; + {$EXTERNALSYM WSASetEvent} + WSASetEvent : LPFN_WSASETEVENT = nil; + {$EXTERNALSYM WSASetServiceA} + WSASetServiceA : LPFN_WSASETSERVICEA = nil; + {$EXTERNALSYM WSASetServiceW} + WSASetServiceW : LPFN_WSASETSERVICEW = nil; + {$EXTERNALSYM WSASetService} + WSASetService : LPFN_WSASETSERVICE = nil; + {$EXTERNALSYM WSASocketA} + WSASocketA : LPFN_WSASOCKETA = nil; + {$EXTERNALSYM WSASocketW} + WSASocketW : LPFN_WSASOCKETW = nil; + {$EXTERNALSYM WSASocket} + WSASocket : LPFN_WSASOCKET = nil; + {$EXTERNALSYM WSAStringToAddressA} + WSAStringToAddressA : LPFN_WSASTRINGTOADDRESSA = nil; + {$EXTERNALSYM WSAStringToAddressW} + WSAStringToAddressW : LPFN_WSASTRINGTOADDRESSW = nil; + {$EXTERNALSYM WSAStringToAddress} + WSAStringToAddress : LPFN_WSASTRINGTOADDRESS = nil; + + {$EXTERNALSYM WSAWaitForMultipleEvents} + WSAWaitForMultipleEvents : LPFN_WSAWAITFORMULTIPLEEVENTS = nil; + {$EXTERNALSYM WSAProviderConfigChange} + WSAProviderConfigChange : LPFN_WSAPROVIDERCONFIGCHANGE = nil; + {$EXTERNALSYM TransmitFile} + TransmitFile : LPFN_TRANSMITFILE = nil; + {$EXTERNALSYM AcceptEx} + AcceptEx : LPFN_ACCEPTEX = nil; + {$EXTERNALSYM GetAcceptExSockaddrs} + GetAcceptExSockaddrs : LPFN_GETACCEPTEXSOCKADDRS = nil; + {$IFNDEF WINCE} + //This is defined in the Windows Mobile 6 Standard SDK Refresh + //but I'm not sure what .DLL the function is in. I also couldn't find a WSAID + //constant for it. + {$EXTERNALSYM WSARecvEx} + WSARecvEx : LPFN_WSARECVEX = nil; + {$ENDIF} + {$EXTERNALSYM ConnectEx} + ConnectEx : LPFN_CONNECTEX = nil; + {$EXTERNALSYM DisconnectEx} + DisconnectEx : LPFN_DISCONNECTEX = nil; + {$EXTERNALSYM WSARecvMsg} + WSARecvMsg : LPFN_WSARECVMSG = nil; + {$EXTERNALSYM TransmitPackets} + TransmitPackets : LPFN_TRANSMITPACKETS = nil; + {$IFNDEF WINCE} + //Windows Vista, Windows Server 2008 + {$EXTERNALSYM WSASendMsg} + WSASendMsg: LPFN_WSASENDMSG = nil; + {$EXTERNALSYM WSAPoll} + WSAPoll: LPFN_WSAPOLL = nil; + {$ENDIF} + //WSANSPIoctl is not supported in WinCE 4.20 but is supported in later versions. + {$EXTERNALSYM WSANSPIoctl} + WSANSPIoctl : LPFN_WSANSPIOCTL = nil; +{$ENDIF} // $IFDEF WS2_DLL_FUNC_VARS + + { Macros } + {$EXTERNALSYM WSAMakeSyncReply} + function WSAMakeSyncReply(Buflen, AError: Word): Longint; + {$EXTERNALSYM WSAMakeSelectReply} + function WSAMakeSelectReply(Event, AError: Word): Longint; + {$EXTERNALSYM WSAGetAsyncBuflen} + function WSAGetAsyncBuflen(Param: LPARAM): Word; + {$EXTERNALSYM WSAGetAsyncError} + function WSAGetAsyncError(Param: LPARAM): Word; + {$EXTERNALSYM WSAGetSelectEvent} + function WSAGetSelectEvent(Param: LPARAM): Word; + {$EXTERNALSYM WSAGetSelectError} + function WSAGetSelectError(Param: LPARAM): Word; + + {$EXTERNALSYM FD_CLR} + procedure FD_CLR(ASocket: TSocket; var FDSet: TFDSet); + {$EXTERNALSYM FD_ISSET} + function FD_ISSET(ASocket: TSocket; var FDSet: TFDSet): Boolean; + {$EXTERNALSYM FD_SET} + procedure FD_SET(ASocket: TSocket; var FDSet: TFDSet); + {$EXTERNALSYM FD_ZERO} + procedure FD_ZERO(var FDSet: TFDSet); + + {$IFNDEF WINCE} +//Posix aliases for helper macros +// #define CMSGHDR_ALIGN WSA_CMSGHDR_ALIGN + {$EXTERNALSYM CMSGHDR_ALIGN} + function CMSGHDR_ALIGN(const Alength: SIZE_T): SIZE_T; +// #define CMSGDATA_ALIGN WSA_CMSGDATA_ALIGN + {$EXTERNALSYM CMSGDATA_ALIGN} + function CMSGDATA_ALIGN(const Alength: PtrUInt): PtrUInt; +//#define CMSG_FIRSTHDR WSA_CMSG_FIRSTHDR + {$EXTERNALSYM CMSG_FIRSTHDR} + function CMSG_FIRSTHDR(const msg: LPWSAMSG): LPWSACMSGHDR; +// #define CMSG_NXTHDR WSA_CMSG_NXTHDR + {$EXTERNALSYM CMSG_NXTHDR} + function CMSG_NXTHDR(const msg: LPWSAMSG; const cmsg: LPWSACMSGHDR): LPWSACMSGHDR; +// #define CMSG_SPACE WSA_CMSG_SPACE + {$EXTERNALSYM CMSG_SPACE} + function CMSG_SPACE(const Alength: PtrUInt): PtrUInt; +// #define CMSG_LEN WSA_CMSG_LEN + {$EXTERNALSYM CMSG_LEN} + function CMSG_LEN(const Alength: SIZE_T): SIZE_T; +// + {$EXTERNALSYM WSA_CMSGHDR_ALIGN} + function WSA_CMSGHDR_ALIGN(const Alength: PtrUInt): PtrUInt; + {$EXTERNALSYM WSA_CMSGDATA_ALIGN} + function WSA_CMSGDATA_ALIGN(const Alength: PtrUInt): PtrUInt; + {$EXTERNALSYM WSA_CMSG_FIRSTHDR} + function WSA_CMSG_FIRSTHDR(const msg: LPWSAMSG): LPWSACMSGHDR; +// #define CMSG_FIRSTHDR WSA_CMSG_FIRSTHDR + {$EXTERNALSYM WSA_CMSG_NXTHDR} + function WSA_CMSG_NXTHDR(const msg: LPWSAMSG; const cmsg: LPWSACMSGHDR): LPWSACMSGHDR; + + {$EXTERNALSYM WSA_CMSG_DATA} + function WSA_CMSG_DATA(const cmsg: LPWSACMSGHDR): PByte; + {$EXTERNALSYM WSA_CMSG_SPACE} + function WSA_CMSG_SPACE(const Alength: SIZE_T): SIZE_T; + {$EXTERNALSYM WSA_CMSG_LEN} + function WSA_CMSG_LEN(const Alength: SIZE_T): SIZE_T; + {$ENDIF} + +//============================================================= + +{ + WS2TCPIP.H - WinSock2 Extension for TCP/IP protocols + + This file contains TCP/IP specific information for use + by WinSock2 compatible applications. + + Copyright (c) 1995-1999 Microsoft Corporation + + To provide the backward compatibility, all the TCP/IP + specific definitions that were included in the WINSOCK.H + file are now included in WINSOCK2.H file. WS2TCPIP.H + file includes only the definitions introduced in the + "WinSock 2 Protocol-Specific Annex" document. + + Rev 0.3 Nov 13, 1995 + Rev 0.4 Dec 15, 1996 +} + +type +// Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP + {$EXTERNALSYM ip_mreq} + ip_mreq = record + imr_multiaddr : TInAddr; // IP multicast address of group + imr_interface : TInAddr; // local IP address of interface + end; + +// Argument structure for IP_ADD_SOURCE_MEMBERSHIP, IP_DROP_SOURCE_MEMBERSHIP, +// IP_BLOCK_SOURCE, and IP_UNBLOCK_SOURCE + {$EXTERNALSYM ip_mreq_source} + ip_mreq_source = record + imr_multiaddr: TInAddr; // IP multicast address of group + imr_sourceaddr: TInAddr; // IP address of source + imr_interface: TInAddr; // local IP address of interface + end; + +// Argument structure for SIO_{GET,SET}_MULTICAST_FILTER + {$EXTERNALSYM ip_msfilter} + ip_msfilter = record + imsf_multiaddr: TInAddr; // IP multicast address of group + imsf_interface: TInAddr; // local IP address of interface + imsf_fmode: u_long; // filter mode - INCLUDE or EXCLUDE + imsf_numsrc: u_long; // number of sources in src_list + imsf_slist: Array[0..0] of TInAddr; + end; + + {$EXTERNALSYM IP_MSFILTER_SIZE} + function IP_MSFILTER_SIZE(const numsrc: DWORD): PtrUInt; + +// TCP/IP specific Ioctl codes +const + {$EXTERNALSYM SIO_GET_INTERFACE_LIST} + SIO_GET_INTERFACE_LIST = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or 127; {Do not Localize} +// New IOCTL with address size independent address array + {$EXTERNALSYM SIO_GET_INTERFACE_LIST_EX} + SIO_GET_INTERFACE_LIST_EX = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or 126; {Do not Localize} + {$EXTERNALSYM SIO_SET_MULTICAST_FILTER} + SIO_SET_MULTICAST_FILTER = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or 125; {Do not Localize} + {$EXTERNALSYM SIO_GET_MULTICAST_FILTER} + SIO_GET_MULTICAST_FILTER = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or (124 or IOC_IN); {Do not Localize} + {$EXTERNALSYM SIOCSIPMSFILTER} + SIOCSIPMSFILTER = SIO_SET_MULTICAST_FILTER; + {$EXTERNALSYM SIOCGIPMSFILTER} + SIOCGIPMSFILTER = SIO_GET_MULTICAST_FILTER; +// +// Protocol independent ioctls for setting and retrieving multicast filters. +// + {$EXTERNALSYM SIOCSMSFILTER} + SIOCSMSFILTER = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or 126; {Do not Localize} + {$EXTERNALSYM SIOCGMSFILTER} + SIOCGMSFILTER = IOC_IN or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or (127 or IOC_IN); {Do not Localize} + + {$IFNDEF WINCE} + //Windows 2008 and Windows Vista SP1 additions + {$EXTERNALSYM SIO_IDEAL_SEND_BACKLOG_QUERY} + SIO_IDEAL_SEND_BACKLOG_QUERY = IOC_OUT or ((SizeOf(u_long) and IOCPARM_MASK) shl 16) or (Ord('t') shl 8) or 123; + {$EXTERNALSYM SIO_IDEAL_SEND_BACKLOG_CHANGE} + SIO_IDEAL_SEND_BACKLOG_CHANGE = IOC_VOID or (Ord('t') shl 8) or 122; + {$ENDIF} + + {$IFNDEF WINCE} +// Options for use with [gs]etsockopt at the IP level. + {$EXTERNALSYM IP_OPTIONS} + IP_OPTIONS = 1; // set/get IP options + {$EXTERNALSYM IP_HDRINCL} + IP_HDRINCL = 2; // header is included with data + {$EXTERNALSYM IP_TOS} + IP_TOS = 3; // IP type of service and preced + {$EXTERNALSYM IP_TTL} + IP_TTL = 4; // IP time to live + {$EXTERNALSYM IP_MULTICAST_IF} + IP_MULTICAST_IF = 9; // set/get IP multicast i/f + {$EXTERNALSYM IP_MULTICAST_TTL} + IP_MULTICAST_TTL = 10; // set/get IP multicast ttl + {$EXTERNALSYM IP_MULTICAST_LOOP} + IP_MULTICAST_LOOP = 11; // set/get IP multicast loopback + {$EXTERNALSYM IP_ADD_MEMBERSHIP} + IP_ADD_MEMBERSHIP = 12; // add an IP group membership + {$EXTERNALSYM IP_DROP_MEMBERSHIP} + IP_DROP_MEMBERSHIP = 13; // drop an IP group membership + {$ELSE} + {$EXTERNALSYM IP_TOS} + IP_TOS = 8; //* IP type of service and preced*/ + {$EXTERNALSYM IP_TTL} + IP_TTL = 7; //* IP time to live */ + {$EXTERNALSYM IP_MULTICAST_IF} + IP_MULTICAST_IF = 2; //* set/get IP multicast i/f */ + {$EXTERNALSYM IP_MULTICAST_TTL} + IP_MULTICAST_TTL = 3; //* set/get IP multicast ttl */ + {$EXTERNALSYM IP_MULTICAST_LOOP} + IP_MULTICAST_LOOP = 4; //*set/get IP multicast loopback */ + {$EXTERNALSYM IP_ADD_MEMBERSHIP} + IP_ADD_MEMBERSHIP = 5; //* add an IP group membership */ + {$EXTERNALSYM IP_DROP_MEMBERSHIP} + IP_DROP_MEMBERSHIP = 6; //* drop an IP group membership */ + //JPM Notes. IP_HDRINCL is not supported in WinCE 4.0. + {$EXTERNALSYM IP_HDRINCL} + IP_HDRINCL = 9; //* header is included with data */ + {$ENDIF} + + {$EXTERNALSYM IP_DONTFRAGMENT} + IP_DONTFRAGMENT = 14; // don't fragment IP datagrams {Do not Localize} + {$EXTERNALSYM IP_ADD_SOURCE_MEMBERSHIP} + IP_ADD_SOURCE_MEMBERSHIP = 15; // join IP group/source + {$EXTERNALSYM IP_DROP_SOURCE_MEMBERSHIP} + IP_DROP_SOURCE_MEMBERSHIP = 16; // leave IP group/source + {$EXTERNALSYM IP_BLOCK_SOURCE} + IP_BLOCK_SOURCE = 17; // block IP group/source + {$EXTERNALSYM IP_UNBLOCK_SOURCE} + IP_UNBLOCK_SOURCE = 18; // unblock IP group/source + {$EXTERNALSYM IP_PKTINFO} + IP_PKTINFO = 19; // receive packet information for ipv4 + {$EXTERNALSYM IP_RECEIVE_BROADCAST} + IP_RECEIVE_BROADCAST = 22; // Allow/block broadcast reception. + {$EXTERNALSYM IP_RECVIF} + IP_RECVIF = 24; // Receive arrival interface. + {$EXTERNALSYM IP_RECVDSTADDR} + IP_RECVDSTADDR = 25; // Receive destination address. + {$EXTERNALSYM IP_IFLIST} + IP_IFLIST = 28; // Enable/Disable an interface list. + {$EXTERNALSYM IP_ADD_IFLIST} + IP_ADD_IFLIST = 29; // Add an interface list entry. + {$EXTERNALSYM IP_DEL_IFLIST} + IP_DEL_IFLIST = 30; // Delete an interface list entry. + {$EXTERNALSYM IP_UNICAST_IF} + IP_UNICAST_IF = 31; // IP unicast interface. + {$EXTERNALSYM IP_RTHDR} + IP_RTHDR = 32; // Set/get IPv6 routing header. + {$EXTERNALSYM IP_GET_IFLIST} + IP_GET_IFLIST = 33; // Get an interface list. + {$EXTERNALSYM IP_RECVRTHDR} + IP_RECVRTHDR = 38; // Receive the routing header. + {$EXTERNALSYM IP_TCLASS} + IP_TCLASS = 39; // Packet traffic class. + {$EXTERNALSYM IP_RECVTCLASS} + IP_RECVTCLASS = 40; // Receive packet traffic class. + {$EXTERNALSYM IP_ORIGINAL_ARRIVAL_IF} + IP_ORIGINAL_ARRIVAL_IF = 47; // Original Arrival Interface Index. (Windows 7) + + + {$IFDEF WINCE} + {$EXTERNALSYM IP_DSCP_TRAFFIC_TYPE} + IP_DSCP_TRAFFIC_TYPE = 100; //* differential services */ + {$EXTERNALSYM IP_RELOAD_DSCP_MAPPINGS} + IP_RELOAD_DSCP_MAPPINGS = 101; //* reload DSCP registry mappings */ + {$ENDIF} + + {$EXTERNALSYM IP_DEFAULT_MULTICAST_TTL} + IP_DEFAULT_MULTICAST_TTL = 1; // normally limit m'casts to 1 hop {Do not Localize} + {$EXTERNALSYM IP_DEFAULT_MULTICAST_LOOP} + IP_DEFAULT_MULTICAST_LOOP = 1; // normally hear sends if a member + {$EXTERNALSYM IP_MAX_MEMBERSHIPS} + IP_MAX_MEMBERSHIPS = 20; // per socket; must fit in one mbuf + + + // Option to use with [gs]etsockopt at the IPPROTO_IPV6 level + {$EXTERNALSYM IPV6_HDRINCL} + IPV6_HDRINCL = 2; // Header is included with data + {$EXTERNALSYM IPV6_UNICAST_HOPS} + IPV6_UNICAST_HOPS = 4; // Set/get IP unicast hop limit + {$EXTERNALSYM IPV6_MULTICAST_IF} + IPV6_MULTICAST_IF = 9; // Set/get IP multicast interface + {$EXTERNALSYM IPV6_MULTICAST_HOPS} + IPV6_MULTICAST_HOPS = 10; // Set/get IP multicast ttl + {$EXTERNALSYM IPV6_MULTICAST_LOOP} + IPV6_MULTICAST_LOOP = 11; // Set/get IP multicast loopback + {$EXTERNALSYM IPV6_ADD_MEMBERSHIP} + IPV6_ADD_MEMBERSHIP = 12; // Add an IP group membership + {$EXTERNALSYM IPV6_DROP_MEMBERSHIP} + IPV6_DROP_MEMBERSHIP = 13; // Drop an IP group membership + {$EXTERNALSYM IPV6_JOIN_GROUP} + IPV6_JOIN_GROUP = IPV6_ADD_MEMBERSHIP; + {$EXTERNALSYM IPV6_LEAVE_GROUP} + IPV6_LEAVE_GROUP = IPV6_DROP_MEMBERSHIP; + {$EXTERNALSYM IPV6_PKTINFO} + IPV6_PKTINFO = 19; // Receive packet information for ipv6 + {$EXTERNALSYM IPV6_HOPLIMIT} + IPV6_HOPLIMIT = 21; // Receive packet hop limit + //Note that IPV6_PROTECTION_LEVEL is not supported for WinCE 4.2 + {$EXTERNALSYM IPV6_PROTECTION_LEVEL} + IPV6_PROTECTION_LEVEL = 23; // Set/get IPv6 protection level + + {$EXTERNALSYM IPV6_RECVIF} + IPV6_RECVIF = 24; // Receive arrival interface. + {$EXTERNALSYM IPV6_RECVDSTADDR} + IPV6_RECVDSTADDR = 25; // Receive destination address. + {$EXTERNALSYM IPV6_CHECKSUM} + IPV6_CHECKSUM = 26; // Offset to checksum for raw IP socket send. + {$EXTERNALSYM IPV6_V6ONLY} + IPV6_V6ONLY = 27; // Treat wildcard bind as AF_INET6-only. + {$EXTERNALSYM IPV6_IFLIST} + IPV6_IFLIST = 28; // Enable/Disable an interface list. + {$EXTERNALSYM IPV6_ADD_IFLIST} + IPV6_ADD_IFLIST = 29; // Add an interface list entry. + {$EXTERNALSYM IPV6_DEL_IFLIST} + IPV6_DEL_IFLIST = 30; // Delete an interface list entry. + {$EXTERNALSYM IPV6_UNICAST_IF} + IPV6_UNICAST_IF = 31; // IP unicast interface. + {$EXTERNALSYM IPV6_RTHDR} + IPV6_RTHDR = 32; // Set/get IPv6 routing header. + {$EXTERNALSYM IPV6_GET_IFLIST} + IPV6_GET_IFLIST = 33; // Get an interface list. + {$EXTERNALSYM IPV6_RECVRTHDR} + IPV6_RECVRTHDR = 38; // Receive the routing header. + {$EXTERNALSYM IPV6_TCLASS} + IPV6_TCLASS = 39; // Packet traffic class. + {$EXTERNALSYM IPV6_RECVTCLASS} + IPV6_RECVTCLASS = 40; // Receive packet traffic class. + {$EXTERNALSYM IPV6_ECN} + IPV6_ECN = 50; // Receive ECN codepoints in the IP header. + {$EXTERNALSYM IPV6_PKTINFO_EX} + IPV6_PKTINFO_EX = 51; // Receive extended packet information. + {$EXTERNALSYM IPV6_WFP_REDIRECT_RECORDS} + IPV6_WFP_REDIRECT_RECORDS = 60; // WFP's Connection Redirect Records + {$EXTERNALSYM IPV6_WFP_REDIRECT_CONTEXT} + IPV6_WFP_REDIRECT_CONTEXT = 70; // WFP's Connection Redirect Context + + + // Option to use with [gs]etsockopt at the IPPROTO_UDP level + {$EXTERNALSYM UDP_NOCHECKSUM} + UDP_NOCHECKSUM = 1; + {$EXTERNALSYM UDP_CHECKSUM_COVERAGE} + UDP_CHECKSUM_COVERAGE = 20; // Set/get UDP-Lite checksum coverage + +// Option to use with [gs]etsockopt at the IPPROTO_TCP level + {$EXTERNALSYM TCP_EXPEDITED_1122} + TCP_EXPEDITED_1122 = $0002; + {$EXTERNALSYM TCP_KEEPALIVE} + TCP_KEEPALIVE = 3; + {$EXTERNALSYM TCP_MAXSEG} + TCP_MAXSEG = 4; + {$EXTERNALSYM TCP_MAXRT} + TCP_MAXRT = 5; + {$EXTERNALSYM TCP_STDURG} + TCP_STDURG = 6; + {$EXTERNALSYM TCP_NOURG} + TCP_NOURG = 7; + {$EXTERNALSYM TCP_ATMARK} + TCP_ATMARK = 8; + {$EXTERNALSYM TCP_NOSYNRETRIES} + TCP_NOSYNRETRIES = 9; + {$EXTERNALSYM TCP_TIMESTAMPS} + TCP_TIMESTAMPS = 10; + {$EXTERNALSYM TCP_OFFLOAD_PREFERENCE} + TCP_OFFLOAD_PREFERENCE = 11; + {$EXTERNALSYM TCP_CONGESTION_ALGORITHM} + TCP_CONGESTION_ALGORITHM = 12; + {$EXTERNALSYM TCP_DELAY_FIN_ACK} + TCP_DELAY_FIN_ACK = 13; + {$EXTERNALSYM TCP_MAXRTMS} + TCP_MAXRTMS = 14; + +// IPv6 definitions +type + {$EXTERNALSYM IN6_ADDR} + IN6_ADDR = record + case Integer of + 0: (s6_bytes: array[0..15] of u_char); + 1: (s6_words: array[0..7] of u_short); + end; + {$NODEFINE TIn6Addr} + TIn6Addr = IN6_ADDR; + {$NODEFINE PIn6Addr} + PIn6Addr = ^TIn6Addr; + {$EXTERNALSYM PIN6_ADDR} + PIN6_ADDR = PIn6Addr; + {$EXTERNALSYM LPIN6_ADDR} + LPIN6_ADDR = PIN6_ADDR; + +{$IFNDEF WINCE} + {$IFNDEF NO_REDECLARE} + // Argument structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP + {$EXTERNALSYM ipv6_mreq} + ipv6_mreq = record + ipv6mr_multiaddr: TIn6Addr; // IPv6 multicast address + ipv6mr_interface: u_int; // Interface index + end; + {$NODEFINE TIPv6_MReq} + TIPv6_MReq = IPV6_MREQ; + {$NODEFINE PIPv6_MReq} + PIPv6_MReq = ^TIPv6_MReq; + {$ENDIF} +{$ENDIF} + {$EXTERNALSYM SCOPE_LEVEL} + // The Pascal compiler in Delphi/BCB prior to v6 does not + // support specifying values for individual enum items + SCOPE_LEVEL = ( + {$IFDEF HAS_ENUM_ELEMENT_VALUES} + ScopeLevelInterface = 1, + ScopeLevelLink = 2, + ScopeLevelSubnet = 3, + ScopeLevelAdmin = 4, + ScopeLevelSite = 5, + ScopeLevelOrganization = 8, + ScopeLevelGlobal = 14, + ScopeLevelCount = 16 + {$ELSE} + slUnused0, // do not use + ScopeLevelInterface, + ScopeLevelLink, + ScopeLevelSubnet, + ScopeLevelAdmin, + ScopeLevelSite, + slUnused6, // do not use + slUnused7, // do not use + ScopeLevelOrganization, + slUnused9, // do not use + slUnused10, // do not use + slUnused11, // do not use + slUnused12, // do not use + slUnused13, // do not use + ScopeLevelGlobal, + slUnused15, // do not use + ScopeLevelCount + {$ENDIF} + ); + // Old IPv6 socket address structure (retained for sockaddr_gen definition below) + {$EXTERNALSYM sockaddr_in6_old} + sockaddr_in6_old = record + sin6_family : short; // AF_INET6 + sin6_port : u_short; // Transport level port number + sin6_flowinfo : u_long; // IPv6 flow information + sin6_addr : TIn6Addr; // IPv6 address + end; + +// IPv6 socket address structure, RFC 2553 +{$IFDEF WINCE} + {$EXTERNALSYM SOCKADDR_IN6} + SOCKADDR_IN6 = record + sin6_family : short; // AF_INET6 + sin6_port : u_short; // Transport level port number + sin6_flowinfo : u_long; // IPv6 flow information + sin6_addr : TIn6Addr; // IPv6 address + sin6_scope_id : u_long; // set of interfaces for a scope + end; +{$ELSE} + {$EXTERNALSYM ADDRESS_FAMILY} + ADDRESS_FAMILY = USHORT; +// +// IPv6 socket address structure, RFC 3493. +// + +// +// NB: The LH version of sockaddr_in6 has the struct tag sockaddr_in6 rather +// than sockaddr_in6_lh. This is to make sure that standard sockets apps +// that conform to RFC 2553 (Basic Socket Interface Extensions for IPv6). +// + {$EXTERNALSYM SCOPE_ID} + SCOPE_ID = record +// union { +// struct { +// ULONG Zone : 28; +// ULONG Level : 4; +// }; +// ULONG Value; +// }; + Value : ULONG; + end; + {$EXTERNALSYM PSCOPE_ID} + PSCOPE_ID = ^SCOPE_ID; + + {$EXTERNALSYM SCOPEID_UNSPECIFIED_INIT} + function SCOPEID_UNSPECIFIED_INIT: SCOPE_ID; + +type + {$EXTERNALSYM sockaddr_in6_union} + sockaddr_in6_union = record + case Integer of + 0 : (sin6_scope_id : ULONG); // Set of interfaces for a scope. + 1 : (sin6_scope_struct : SCOPE_ID); + end; + {$EXTERNALSYM SOCKADDR_IN6_LH} + SOCKADDR_IN6_LH = record + sin6_family : ADDRESS_FAMILY; // AF_INET6. + sin6_port : USHORT; // Transport level port number. + sin6_flowinfo : ULONG; // IPv6 flow information. + sin6_addr : IN6_ADDR; // IPv6 address. + a : sockaddr_in6_union; + end; + {$EXTERNALSYM SOCKADDR_IN6_W2KSP1} + SOCKADDR_IN6_W2KSP1 = record + sin6_family : short; //* AF_INET6 */ + sin6_port : USHORT; //* Transport level port number */ + sin6_flowinfo : ULONG; //* IPv6 flow information */ + sin6_addr : in6_addr; //* IPv6 address */ + sin6_scope_id : ULONG; //* set of interfaces for a scope */ + end; + {$EXTERNALSYM PSOCKADDR_IN6_LH} + PSOCKADDR_IN6_LH = ^SOCKADDR_IN6_LH; + {$EXTERNALSYM SOCKADDR_IN6} + SOCKADDR_IN6 = SOCKADDR_IN6_LH; +{$ENDIF} + + {$NODEFINE TSockAddrIn6} + TSockAddrIn6 = SOCKADDR_IN6; + {$NODEFINE PSockAddrIn6} + PSockAddrIn6 = ^TSockAddrIn6; + {$EXTERNALSYM PSOCKADDR_IN6} + PSOCKADDR_IN6 = PSockAddrIn6; + {$EXTERNALSYM LPSOCKADDR_IN6} + LPSOCKADDR_IN6 = PSOCKADDR_IN6; + + {$EXTERNALSYM sockaddr_gen} + sockaddr_gen = record + case Integer of + 1 : ( Address : TSockAddr; ); + 2 : ( AddressIn : TSockAddrIn; ); + 3 : ( AddressIn6 : sockaddr_in6_old; ); + end; + {$NODEFINE TSockAddrGen} + TSockAddrGen = sockaddr_gen; + +// Structure to keep interface specific information + {$EXTERNALSYM INTERFACE_INFO} + INTERFACE_INFO = record + iiFlags : u_long; // Interface flags + iiAddress : TSockAddrGen; // Interface address + iiBroadcastAddress : TSockAddrGen; // Broadcast address + iiNetmask : TSockAddrGen; // Network mask + end; + {$NODEFINE TInterface_Info} + TInterface_Info = INTERFACE_INFO; + {$EXTERNALSYM PINTERFACE_INFO} + PINTERFACE_INFO = ^TInterface_Info; + {$EXTERNALSYM LPINTERFACE_INFO} + LPINTERFACE_INFO = PINTERFACE_INFO; + +// New structure that does not have dependency on the address size + {$EXTERNALSYM INTERFACE_INFO_EX} + INTERFACE_INFO_EX = record + iiFlags : u_long; // Interface flags + iiAddress : TSocket_Address; // Interface address + iiBroadcastAddress : TSocket_Address; // Broadcast address + iiNetmask : TSocket_Address; // Network mask + end; + {$NODEFINE TInterface_Info_Ex} + TInterface_Info_Ex = INTERFACE_INFO_EX; + {$EXTERNALSYM PINTERFACE_INFO_EX} + PINTERFACE_INFO_EX = ^TInterface_Info_Ex; + {$EXTERNALSYM LPINTERFACE_INFO_EX} + LPINTERFACE_INFO_EX = PINTERFACE_INFO_EX; + +// Macro that works for both IPv4 and IPv6 + {$EXTERNALSYM SS_PORT} + function SS_PORT(ssp: PSockAddrIn): u_short; + + {$EXTERNALSYM IN6ADDR_ANY_INIT} + function IN6ADDR_ANY_INIT: TIn6Addr; + {$EXTERNALSYM IN6ADDR_LOOPBACK_INIT} + function IN6ADDR_LOOPBACK_INIT: TIn6Addr; + {$EXTERNALSYM IN6ADDR_ALLNODESONNODE_INIT} + function IN6ADDR_ALLNODESONNODE_INIT : TIn6Addr; + {$EXTERNALSYM IN6ADDR_ALLNODESONLINK_INIT} + function IN6ADDR_ALLNODESONLINK_INIT : TIn6Addr; + {$EXTERNALSYM IN6ADDR_ALLROUTERSONLINK_INIT} + function IN6ADDR_ALLROUTERSONLINK_INIT : TIn6Addr; + {$EXTERNALSYM IN6ADDR_ALLMLDV2ROUTERSONLINK_INIT} + function IN6ADDR_ALLMLDV2ROUTERSONLINK_INIT : TIn6Addr; + {$EXTERNALSYM IN6ADDR_TEREDOINITIALLINKLOCALADDRESS_INIT} + function IN6ADDR_TEREDOINITIALLINKLOCALADDRESS_INIT : TIn6Addr; + {$EXTERNALSYM IN6ADDR_TEREDOOLDLINKLOCALADDRESSXP_INIT} + function IN6ADDR_TEREDOOLDLINKLOCALADDRESSXP_INIT : TIn6Addr; + {$EXTERNALSYM IN6ADDR_TEREDOOLDLINKLOCALADDRESSVISTA_INIT} + function IN6ADDR_TEREDOOLDLINKLOCALADDRESSVISTA_INIT : TIn6Addr; + + {$EXTERNALSYM IN6ADDR_SETANY} + procedure IN6ADDR_SETANY(sa: PSockAddrIn6); + {$EXTERNALSYM IN6ADDR_SETLOOPBACK} + procedure IN6ADDR_SETLOOPBACK(sa: PSockAddrIn6); + {$EXTERNALSYM IN6ADDR_ISANY} + function IN6ADDR_ISANY(sa: PSockAddrIn6): Boolean; + {$EXTERNALSYM IN6ADDR_ISLOOPBACK} + function IN6ADDR_ISLOOPBACK(sa: PSockAddrIn6): Boolean; + + {$EXTERNALSYM IN6_IS_ADDR_SUBNET_ROUTER_ANYCAST} + function IN6_IS_ADDR_SUBNET_ROUTER_ANYCAST(const a : PIn6Addr) : Boolean; + {$EXTERNALSYM IN6_IS_ADDR_SUBNET_RESERVED_ANYCAST} + function IN6_IS_ADDR_SUBNET_RESERVED_ANYCAST(const a: PIn6Addr) : Boolean; + {$EXTERNALSYM IN6_IS_ADDR_ANYCAST} + function IN6_IS_ADDR_ANYCAST(const a: PIn6Addr) : Boolean; + {$EXTERNALSYM IN6_ADDR_EQUAL} + function IN6_ADDR_EQUAL(const a: PIn6Addr; const b: PIn6Addr): Boolean; + {$EXTERNALSYM IN6_IS_ADDR_UNSPECIFIED} + function IN6_IS_ADDR_UNSPECIFIED(const a: PIn6Addr): Boolean; + {$EXTERNALSYM IN6_IS_ADDR_LOOPBACK} + function IN6_IS_ADDR_LOOPBACK(const a: PIn6Addr): Boolean; + {$EXTERNALSYM IN6_IS_ADDR_MULTICAST} + function IN6_IS_ADDR_MULTICAST(const a: PIn6Addr): Boolean; + {$EXTERNALSYM IN6_IS_ADDR_EUI64} + function IN6_IS_ADDR_EUI64(const a : PIn6Addr) : Boolean; + + {$EXTERNALSYM IN6_IS_ADDR_LINKLOCAL} + function IN6_IS_ADDR_LINKLOCAL(const a: PIn6Addr): Boolean; + {$EXTERNALSYM IN6_IS_ADDR_SITELOCAL} + function IN6_IS_ADDR_SITELOCAL(const a: PIn6Addr): Boolean; + {$EXTERNALSYM IN6_IS_ADDR_V4MAPPED} + function IN6_IS_ADDR_V4MAPPED(const a: PIn6Addr): Boolean; + {$EXTERNALSYM IN6_IS_ADDR_V4COMPAT} + function IN6_IS_ADDR_V4COMPAT(const a: PIn6Addr): Boolean; + {$EXTERNALSYM IN6_IS_ADDR_V4TRANSLATED} + function IN6_IS_ADDR_V4TRANSLATED(const a: PIn6Addr): Boolean; + {$EXTERNALSYM IN6_IS_ADDR_MC_NODELOCAL} + function IN6_IS_ADDR_MC_NODELOCAL(const a: PIn6Addr): Boolean; + {$EXTERNALSYM IN6_IS_ADDR_MC_LINKLOCAL} + function IN6_IS_ADDR_MC_LINKLOCAL(const a: PIn6Addr): Boolean; + {$EXTERNALSYM IN6_IS_ADDR_MC_SITELOCAL} + function IN6_IS_ADDR_MC_SITELOCAL(const a: PIn6Addr): Boolean; + {$EXTERNALSYM IN6_IS_ADDR_MC_ORGLOCAL} + function IN6_IS_ADDR_MC_ORGLOCAL(const a: PIn6Addr): Boolean; + {$EXTERNALSYM IN6_IS_ADDR_MC_GLOBAL} + function IN6_IS_ADDR_MC_GLOBAL(const a: PIn6Addr): Boolean; + + {$EXTERNALSYM IN6_SET_ADDR_UNSPECIFIED} + procedure IN6_SET_ADDR_UNSPECIFIED(a : PIN6_ADDR); + +// Possible flags for the iiFlags - bitmask +const + {$EXTERNALSYM IFF_UP} + IFF_UP = $00000001; // Interface is up + {$EXTERNALSYM IFF_BROADCAST} + IFF_BROADCAST = $00000002; // Broadcast is supported + {$EXTERNALSYM IFF_LOOPBACK} + IFF_LOOPBACK = $00000004; // this is loopback interface + {$EXTERNALSYM IFF_POINTTOPOINT} + IFF_POINTTOPOINT = $00000008; // this is point-to-point interface + {$EXTERNALSYM IFF_MULTICAST} + IFF_MULTICAST = $00000010; // multicast is supported + +type + {$EXTERNALSYM MULTICAST_MODE_TYPE} + {$EXTERNALSYM MCAST_INCLUDE} + {$EXTERNALSYM MCAST_EXCLUDE} + MULTICAST_MODE_TYPE = (MCAST_INCLUDE, MCAST_EXCLUDE); + {$EXTERNALSYM GROUP_FILTER} + GROUP_FILTER = record + gf_interface : PULONG; // Interface index. + gf_group : SOCKADDR_STORAGE; // Multicast address. + gf_fmode : MULTICAST_MODE_TYPE; // Filter mode. + gf_numsrc : ULONG; // Number of sources. + gf_slist : SOCKADDR_STORAGE; //gf_slist[1] : SOCKADDR_STORAGE; // Source address. + end; + {$EXTERNALSYM PGROUP_FILTER} + PGROUP_FILTER = ^GROUP_FILTER; + + {$EXTERNALSYM GROUP_REQ} + GROUP_REQ = record + gr_interface : ULONG; // Interface index. + gr_group : SOCKADDR_STORAGE; // Multicast address. + end; + {$EXTERNALSYM PGROUP_REQ} + PGROUP_REQ = ^GROUP_REQ; + + {$EXTERNALSYM GROUP_SOURCE_REQ} + GROUP_SOURCE_REQ = record + gsr_interface : ULONG; // Interface index. + gsr_group : SOCKADDR_STORAGE; // Group address. + gsr_source : SOCKADDR_STORAGE; // Source address. + end; + {$EXTERNALSYM PGROUP_SOURCE_REQ} + PGROUP_SOURCE_REQ = ^GROUP_SOURCE_REQ; + +{$EXTERNALSYM GROUP_FILTER_SIZE} +function GROUP_FILTER_SIZE(const numsrc : DWord) : PtrUInt; + +type + {$EXTERNALSYM WSAQUERYSET2} + WSAQUERYSET2 = record + dwSize : DWORD; + lpszServiceInstanceName : LPTSTR; + lpVersion : LPWSAVERSION; + lpszComment : LPTSTR; + dwNameSpace : DWORD; + lpNSProviderId : LPGUID; + lpszContext : LPTSTR; + dwNumberOfProtocols : DWORD; + lpafpProtocols : LPAFPROTOCOLS; + lpszQueryString : LPTSTR; + dwNumberOfCsAddrs : DWORD; + lpcsaBuffer : LPCSADDR_INFO; + dwOutputFlags : DWORD; + lpBlob : LPBLOB; + end; + {$EXTERNALSYM PWSAQUERYSET2} + PWSAQUERYSET2 = ^WSAQUERYSET2; + {$EXTERNALSYM LPWSAQUERYSET2} + LPWSAQUERYSET2 = PWSAQUERYSET2; + + {$EXTERNALSYM NAPI_PROVIDER_TYPE} + {$EXTERNALSYM ProviderType_Application} + {$EXTERNALSYM ProviderType_Service} + {$IFNDEF HAS_ENUM_ELEMENT_VALUES} + {$NODEFINE nptUnused} + {$ENDIF} + // The Pascal compiler in Delphi/BCB prior to v6 does not + // support specifying values for individual enum items + NAPI_PROVIDER_TYPE = ( + {$IFDEF HAS_ENUM_ELEMENT_VALUES} + ProviderType_Application = 1, + {$ELSE} + nptUnused, // Do not use + ProviderType_Application, + {$ENDIF} + ProviderType_Service); + {$EXTERNALSYM NAPI_DOMAIN_DESCRIPTION_BLOB} + NAPI_DOMAIN_DESCRIPTION_BLOB = record + AuthLevel : DWORD; + cchDomainName : DWORD; + OffsetNextDomainDescription : DWORD; + OffsetThisDomainName : DWORD; + end; + {$EXTERNALSYM PNAPI_DOMAIN_DESCRIPTION_BLOB} + PNAPI_DOMAIN_DESCRIPTION_BLOB = ^NAPI_DOMAIN_DESCRIPTION_BLOB; + + {$EXTERNALSYM NAPI_PROVIDER_LEVEL} + {$EXTERNALSYM PROVIDERLEVEL_NONE} + {$EXTERNALSYM PROVIDERLEVEL_SECONDARY} + {$EXTERNALSYM PROVIDERLEVEL_PRIMARY} + NAPI_PROVIDER_LEVEL = ( + PROVIDERLEVEL_NONE, + PROVIDERLEVEL_SECONDARY, + PROVIDERLEVEL_PRIMARY + ); + + {$EXTERNALSYM NAPI_PROVIDER_INSTALLATION_BLOB} + NAPI_PROVIDER_INSTALLATION_BLOB = record + dwVersion : DWORD; + dwProviderType : DWORD; + fSupportsWildCard : DWORD; + cDomains : DWORD; + OffsetFirstDomain : DWORD; + end; + {$EXTERNALSYM PNAPI_PROVIDER_INSTALLATION_BLOB} + PNAPI_PROVIDER_INSTALLATION_BLOB = ^NAPI_PROVIDER_INSTALLATION_BLOB; + + {$IFNDEF NOREDECLARE} + {$EXTERNALSYM SERVICE_ADDRESS} + SERVICE_ADDRESS = record + dwAddressType : DWORD; + dwAddressFlags : DWORD; + dwAddressLength : DWORD; + dwPrincipalLength : DWORD; + lpAddress : PByte; + lpPrincipal : PByte; + end; + {$ENDIF} + {$EXTERNALSYM PSERVICE_ADDRESS} + PSERVICE_ADDRESS = ^SERVICE_ADDRESS; + {$EXTERNALSYM LPSERVICE_ADDRESS} + LPSERVICE_ADDRESS = PSERVICE_ADDRESS; + + {$IFNDEF NOREDECLARE} + {$EXTERNALSYM SERVICE_ADDRESSES} + SERVICE_ADDRESSES = record + dwAddressCount : DWORD; +//#ifdef MIDL_PASS +// [size_is(dwAddressCount)] SERVICE_ADDRESS Addressses[*]; +//#else // MIDL_PASS +// SERVICE_ADDRESS Addresses[1] ; +//#endif // MIDL_PASS + Addresses : SERVICE_ADDRESS; + end; + {$EXTERNALSYM PSERVICE_ADDRESSES} + PSERVICE_ADDRESSES = ^SERVICE_ADDRESSES; + {$EXTERNALSYM LPSERVICE_ADDRESSES} + LPSERVICE_ADDRESSES = PSERVICE_ADDRESSES; + {$ENDIF} + +{$IFNDEF VCL_2007_OR_ABOVE} +const + {$EXTERNALSYM RESOURCEDISPLAYTYPE_GENERIC} + RESOURCEDISPLAYTYPE_GENERIC = $00000000; + {$EXTERNALSYM RESOURCEDISPLAYTYPE_DOMAIN} + RESOURCEDISPLAYTYPE_DOMAIN = $00000001; + {$EXTERNALSYM RESOURCEDISPLAYTYPE_SERVER} + RESOURCEDISPLAYTYPE_SERVER = $00000002; + {$EXTERNALSYM RESOURCEDISPLAYTYPE_SHARE} + RESOURCEDISPLAYTYPE_SHARE = $00000003; + {$EXTERNALSYM RESOURCEDISPLAYTYPE_FILE} + RESOURCEDISPLAYTYPE_FILE = $00000004; + {$EXTERNALSYM RESOURCEDISPLAYTYPE_GROUP} + RESOURCEDISPLAYTYPE_GROUP = $00000005; + {$EXTERNALSYM RESOURCEDISPLAYTYPE_NETWORK} + RESOURCEDISPLAYTYPE_NETWORK = $00000006; + {$EXTERNALSYM RESOURCEDISPLAYTYPE_ROOT} + RESOURCEDISPLAYTYPE_ROOT = $00000007; + {$EXTERNALSYM RESOURCEDISPLAYTYPE_SHAREADMIN} + RESOURCEDISPLAYTYPE_SHAREADMIN = $00000008; + {$EXTERNALSYM RESOURCEDISPLAYTYPE_DIRECTORY} + RESOURCEDISPLAYTYPE_DIRECTORY = $00000009; + {$EXTERNALSYM RESOURCEDISPLAYTYPE_TREE} + RESOURCEDISPLAYTYPE_TREE = $0000000A; + {$EXTERNALSYM RESOURCEDISPLAYTYPE_NDSCONTAINER} + RESOURCEDISPLAYTYPE_NDSCONTAINER = $0000000B; +{$ENDIF} + +type + {$EXTERNALSYM SERVICE_TYPE_VALUE_ABSA} + SERVICE_TYPE_VALUE_ABSA = record + dwNameSpace : DWORD; + dwValueType : DWORD; + dwValueSize : DWORD; + lpValueName : LPSTR; + lpValue : Pointer; + end; + {$EXTERNALSYM PSERVICE_TYPE_VALUE_ABSA} + PSERVICE_TYPE_VALUE_ABSA = ^SERVICE_TYPE_VALUE_ABSA; + {$EXTERNALSYM LPSERVICE_TYPE_VALUE_ABSA} + LPSERVICE_TYPE_VALUE_ABSA = PSERVICE_TYPE_VALUE_ABSA; + + {$EXTERNALSYM SERVICE_INFOA} + SERVICE_INFOA = record + lpServiceType : LPGUID; + lpServiceName : PIdAnsiChar; + lpComment : PIdAnsiChar; + lpLocale : PIdAnsiChar; + dwDisplayHint : DWORD; + dwVersion : DWORD; + dwTime : DWORD; + lpMachineName : PIdAnsiChar; + lpServiceAddress : LPSERVICE_ADDRESSES; + ServiceSpecificInfo : BLOB; + end; + {$EXTERNALSYM SERVICE_INFOW} + SERVICE_INFOW = record + lpServiceType : LPGUID; + lpServiceName : PWideChar; + lpComment : PWideChar; + lpLocale : PWideChar; + dwDisplayHint : DWORD; + dwVersion : DWORD; + dwTime : DWORD; + lpMachineName : PWideChar; + lpServiceAddress : LPSERVICE_ADDRESSES; + ServiceSpecificInfo : BLOB; + end; + + {$EXTERNALSYM SOCKET_USAGE_TYPE} + {$EXTERNALSYM SYSTEM_CRITICAL_SOCKET} + {$IFNDEF HAS_ENUM_ELEMENT_VALUES} + {$NODEFINE sutUnused} + {$ENDIF} + // The Pascal compiler in Delphi/BCB prior to v6 does not + // support specifying values for individual enum items + SOCKET_USAGE_TYPE = ( + {$IFDEF HAS_ENUM_ELEMENT_VALUES} + SYSTEM_CRITICAL_SOCKET = 1 + {$ELSE} + sutUnused, // do not use + SYSTEM_CRITICAL_SOCKET + {$ENDIF} + ); + {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL} + {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL_DEFAULT} + {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL_IPSEC} + {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL_IPSEC2} + SOCKET_SECURITY_PROTOCOL = ( + SOCKET_SECURITY_PROTOCOL_DEFAULT, + SOCKET_SECURITY_PROTOCOL_IPSEC, + SOCKET_SECURITY_PROTOCOL_IPSEC2); + {$IFNDEF NO_REDECLARE} + {$EXTERNALSYM SERVICE_INFO} + {$IFDEF UNICODE} + SERVICE_INFO = SERVICE_INFOW; + {$ELSE} + SERVICE_INFO = SERVICE_INFOA; + {$ENDIF} + {$ENDIF} + {$EXTERNALSYM NS_SERVICE_INFOA} + NS_SERVICE_INFOA = record + dwNameSpace : DWORD; + ServiceInfo : SERVICE_INFOA; + end; + {$EXTERNALSYM PNS_SERVICE_INFOA} + PNS_SERVICE_INFOA = ^NS_SERVICE_INFOA; + {$EXTERNALSYM LPNS_SERVICE_INFOA} + LPNS_SERVICE_INFOA = NS_SERVICE_INFOA; + {$EXTERNALSYM NS_SERVICE_INFOW} + NS_SERVICE_INFOW = record + dwNameSpace : DWORD; + ServiceInfo : SERVICE_INFOW; + end; + {$EXTERNALSYM PNS_SERVICE_INFOW} + PNS_SERVICE_INFOW = ^NS_SERVICE_INFOW; + {$EXTERNALSYM LPNS_SERVICE_INFOW} + LPNS_SERVICE_INFOW = NS_SERVICE_INFOW; + {$IFNDEF NO_REDECLARE} + {$EXTERNALSYM NS_SERVICE_INFO} + {$EXTERNALSYM PNS_SERVICE_INFO} + {$EXTERNALSYM LPNS_SERVICE_INFO} + {$IFDEF UNICODE} + NS_SERVICE_INFO = NS_SERVICE_INFOW; + PNS_SERVICE_INFO = PNS_SERVICE_INFOW; + LPNS_SERVICE_INFO = LPNS_SERVICE_INFOW; + {$ELSE} + NS_SERVICE_INFO = NS_SERVICE_INFOA; + PNS_SERVICE_INFO = PNS_SERVICE_INFOA; + LPNS_SERVICE_INFO = LPNS_SERVICE_INFOA; + {$ENDIF} + {$ENDIF} + +{$IFNDEF WINCE} +type +// structure for IP_PKTINFO option + {$EXTERNALSYM IN_PKTINFO} + IN_PKTINFO = record + ipi_addr : TInAddr; // destination IPv4 address + ipi_ifindex : UINT; // received interface index + end; + {$NODEFINE TInPktInfo} + TInPktInfo = IN_PKTINFO; + {$NODEFINE PInPktInfo} + PInPktInfo = ^IN_PKTINFO; + +// structure for IPV6_PKTINFO option + {$EXTERNALSYM IN6_PKTINFO} + IN6_PKTINFO = record + ipi6_addr : TIn6Addr; // destination IPv6 address + ipi6_ifindex : UINT; // received interface index + end; + {$NODEFINE TIn6PktInfo} + TIn6PktInfo = IN6_PKTINFO; + {$NODEFINE PIn6PktInfo} + PIn6PktInfo = ^TIn6PktInfo; +{$ENDIF} + +// Error codes from getaddrinfo() +const + {$EXTERNALSYM EAI_AGAIN} + EAI_AGAIN = WSATRY_AGAIN; + {$EXTERNALSYM EAI_BADFLAGS} + EAI_BADFLAGS = WSAEINVAL; + {$EXTERNALSYM EAI_FAIL} + EAI_FAIL = WSANO_RECOVERY; + {$EXTERNALSYM EAI_FAMILY} + EAI_FAMILY = WSAEAFNOSUPPORT; + {$EXTERNALSYM EAI_MEMORY} + EAI_MEMORY = WSA_NOT_ENOUGH_MEMORY; +// {$EXTERNALSYM EAI_NODATA} +// EAI_NODATA = WSANO_DATA; + {$EXTERNALSYM EAI_NONAME} + EAI_NONAME = WSAHOST_NOT_FOUND; + {$EXTERNALSYM EAI_SERVICE} + EAI_SERVICE = WSATYPE_NOT_FOUND; + {$EXTERNALSYM EAI_SOCKTYPE} + EAI_SOCKTYPE = WSAESOCKTNOSUPPORT; + +// DCR_FIX: EAI_NODATA remove or fix +// +// EAI_NODATA was removed from rfc2553bis +// need to find out from the authors why and +// determine the error for "no records of this type" +// temporarily, we'll keep #define to avoid changing +// code that could change back; use NONAME + {$EXTERNALSYM EAI_NODATA} + EAI_NODATA = EAI_NONAME; + +// Structure used in getaddrinfo() call +type + {$NODEFINE PAddrInfo} + PAddrInfo = ^ADDRINFO; + {$NODEFINE PPaddrinfo} + PPaddrinfo = ^PAddrInfo; + {$NODEFINE PPaddrinfoW} + PPaddrinfoW = ^PAddrInfoW; + {$EXTERNALSYM ADDRINFO} + ADDRINFO = record + ai_flags : Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST + ai_family : Integer; // PF_xxx + ai_socktype : Integer; // SOCK_xxx + ai_protocol : Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6 + ai_addrlen : size_t; // Length of ai_addr + ai_canonname : PIdAnsiChar; // Canonical name for nodename + ai_addr : PSOCKADDR; // Binary address + ai_next : PAddrInfo; // Next structure in linked list + end; + {$NODEFINE TAddrInfo} + TAddrInfo = ADDRINFO; + {$EXTERNALSYM LPADDRINFO} + LPADDRINFO = PAddrInfo; + + {$NODEFINE PAddrInfoW} + PAddrInfoW = ^ADDRINFOW; + {$EXTERNALSYM ADDRINFOW} + ADDRINFOW = record + ai_flags : Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST + ai_family : Integer; // PF_xxx + ai_socktype : Integer; // SOCK_xxx + ai_protocol : Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6 + ai_addrlen : size_t; // Length of ai_addr + ai_canonname : PWideChar; // Canonical name for nodename + ai_addr : PSOCKADDR; // Binary address + ai_next : PAddrInfoW; // Next structure in linked list + end; + {$NODEFINE TAddrInfoW} + TAddrInfoW = ADDRINFOW; + {$EXTERNALSYM LPADDRINFOW} + LPADDRINFOW = PAddrInfoW; + +// Flags used in "hints" argument to getaddrinfo() +const + {$EXTERNALSYM AI_PASSIVE} + AI_PASSIVE = $00000001; // Socket address will be used in bind() call + {$EXTERNALSYM AI_CANONNAME} + AI_CANONNAME = $00000002; // Return canonical name in first ai_canonname + {$EXTERNALSYM AI_NUMERICHOST} + AI_NUMERICHOST = $00000004; // Nodename must be a numeric address string + {$EXTERNALSYM AI_NUMERICSERV} + AI_NUMERICSERV = $00000008; // Servicename must be a numeric port number + {$EXTERNALSYM AI_ALL} + AI_ALL = $00000100; // Query both IP6 and IP4 with AI_V4MAPPED + {$EXTERNALSYM AI_ADDRCONFIG} + AI_ADDRCONFIG = $00000400; // Resolution only if global address configured + {$EXTERNALSYM AI_V4MAPPED} + AI_V4MAPPED = $00000800; // On v6 failure, query v4 and convert to V4MAPPED format (Vista or later) + {$EXTERNALSYM AI_NON_AUTHORITATIVE} + AI_NON_AUTHORITATIVE = $00004000; // LUP_NON_AUTHORITATIVE (Vista or later) + {$EXTERNALSYM AI_SECURE} + AI_SECURE = $00008000; // LUP_SECURE (Vista or later and applies only to NS_EMAIL namespace.) + {$EXTERNALSYM AI_RETURN_PREFERRED_NAMES} + AI_RETURN_PREFERRED_NAMES = $00010000; // LUP_RETURN_PREFERRED_NAMES (Vista or later and applies only to NS_EMAIL namespace.) + {$EXTERNALSYM AI_FQDN} + AI_FQDN = $00020000; // Return the FQDN in ai_canonname (Windows 7 or later) + {$EXTERNALSYM AI_FILESERVER} + AI_FILESERVER = $00040000; // Resolving fileserver name resolution (Windows 7 or later) + {$EXTERNALSYM AI_DISABLE_IDN_ENCODING} + AI_DISABLE_IDN_ENCODING = $00080000; // Disable Internationalized Domain Names handling + + +type + {$EXTERNALSYM PADDRINFOEXA} + PADDRINFOEXA = ^TAddrInfoEXA; + {$EXTERNALSYM ADDRINFOEXA} + ADDRINFOEXA = record + ai_flags : Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST + ai_family : Integer; // PF_xxx + ai_socktype : Integer; // SOCK_xxx + ai_protocol : Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6 + ai_addrlen : size_t; // Length of ai_addr + ai_canonname : PIdAnsiChar; // Canonical name for nodename + ai_addr : Psockaddr; // Binary address + ai_blob : Pointer; + ai_bloblen : size_t; + ai_provider : LPGUID; + ai_next : PADDRINFOEXA; // Next structure in linked list + end; + {$NODEFINE TAddrInfoEXA} + TAddrInfoExA = ADDRINFOEXA; + {$EXTERNALSYM LPADDRINFOEXA} + LPADDRINFOEXA = PADDRINFOEXA; + + {$EXTERNALSYM PADDRINFOEXW} + PADDRINFOEXW = ^TAddrInfoEXW; + {$EXTERNALSYM ADDRINFOEXW} + ADDRINFOEXW = record + ai_flags : Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST + ai_family : Integer; // PF_xxx + ai_socktype : Integer; // SOCK_xxx + ai_protocol : Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6 + ai_addrlen : size_t; // Length of ai_addr + ai_canonname : PWideChar; // Canonical name for nodename + ai_addr : Psockaddr; // Binary address + ai_blob : Pointer; + ai_bloblen : size_t; + ai_provider : LPGUID; + ai_next : PADDRINFOEXW; // Next structure in linked list + end; + {$NODEFINE TAddrInfoExW} + TAddrInfoExW = ADDRINFOEXW; + {$EXTERNALSYM LPADDRINFOEXW} + LPADDRINFOEXW = PADDRINFOEXW; + + {$EXTERNALSYM Paddrinfoex2A} + Paddrinfoex2A = ^addrinfoex2A; + {$EXTERNALSYM addrinfoex2A} + addrinfoex2A = record + ai_flags : Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST + ai_family : Integer; // PF_xxx + ai_socktype : Integer; // SOCK_xxx + ai_protocol : Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6 + ai_addrlen : size_t; // Length of ai_addr + ai_canonname : PIdAnsiChar; // Canonical name for nodename + ai_addr : Psockaddr; // Binary address + ai_blob : Pointer; + ai_bloblen : size_t; + ai_provider : LPGUID; + ai_next : Paddrinfoex2A; // Next structure in linked list + ai_version : Integer; + ai_fqdn : PIdAnsiChar; + end; + {$NODEFINE TAddrInfoEx2A} + TAddrInfoEx2A = addrinfoex2A; + {$EXTERNALSYM LPADDRINFOEX2A} + LPADDRINFOEX2A = Paddrinfoex2A; + + {$EXTERNALSYM Paddrinfoex2W} + Paddrinfoex2W = ^addrinfoex2W; + {$EXTERNALSYM addrinfoex2W} + addrinfoex2W = record + ai_flags : Integer; // AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST + ai_family : Integer; // PF_xxx + ai_socktype : Integer; // SOCK_xxx + ai_protocol : Integer; // 0 or IPPROTO_xxx for IPv4 and IPv6 + ai_addrlen : size_t; // Length of ai_addr + ai_canonname : PWideChar; // Canonical name for nodename + ai_addr : Psockaddr; //_Field_size_bytes_(ai_addrlen) // Binary address + ai_blob : Pointer; //_Field_size_(ai_bloblen) + ai_bloblen : size_t; + ai_provider : LPGUID; + ai_next : Paddrinfoex2W; // Next structure in linked list + ai_version : Integer; + ai_fqdn : PWideChar; + end; + {$NODEFINE TAddrInfoEx2W} + TAddrInfoEx2W = addrinfoex2W; + {$EXTERNALSYM LPADDRINFOEX2W} + LPADDRINFOEX2W = Paddrinfoex2W; + +var + {$EXTERNALSYM scopeid_unspecified} + scopeid_unspecified: {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; + + // RLebeau: the in4addr_any, _in4addr_loopback, and _in4addr_broadcast variables + // clash with the IN4ADDR_ANY, IN4ADDR_LOOPBACK, and IN4ADDR_BROADCAST constants + {$EXTERNALSYM in4addr_any} + {$NODEFINE _in4addr_any} + _in4addr_any: TInAddr; + {$EXTERNALSYM in4addr_loopback} + {$NODEFINE _in4addr_loopback} + _in4addr_loopback: TInAddr; + {$EXTERNALSYM in4addr_broadcast} + {$NODEFINE _in4addr_broadcast} + _in4addr_broadcast: TInAddr; + + {$EXTERNALSYM in4addr_allnodesonlink} + in4addr_allnodesonlink: TInAddr; + {$EXTERNALSYM in4addr_allroutersonlink} + in4addr_allroutersonlink: TInAddr; + {$EXTERNALSYM in4addr_alligmpv3routersonlink} + in4addr_alligmpv3routersonlink: TInAddr; + {$EXTERNALSYM in4addr_allteredohostsonlink} + in4addr_allteredohostsonlink: TInAddr; + {$EXTERNALSYM in4addr_linklocalprefix} + in4addr_linklocalprefix: TInAddr; + {$EXTERNALSYM in4addr_multicastprefix} + in4addr_multicastprefix: TInAddr; + + {$EXTERNALSYM in6addr_any} + in6addr_any: TIn6Addr; + {$EXTERNALSYM in6addr_loopback} + in6addr_loopback: TIn6Addr; + {$EXTERNALSYM in6addr_allnodesonnode} + in6addr_allnodesonnode: TIn6Addr; + {$EXTERNALSYM in6addr_allnodesonlink} + in6addr_allnodesonlink: TIn6Addr; + {$EXTERNALSYM in6addr_allroutersonlink} + in6addr_allroutersonlink: TIn6Addr; + {$EXTERNALSYM in6addr_solicitednodemulticastprefix} + in6addr_solicitednodemulticastprefix: TIn6Addr; + {$EXTERNALSYM in6addr_v4mappedprefix} + in6addr_v4mappedprefix: TIn6Addr; + {$EXTERNALSYM in6addr_6to4prefix} + in6addr_6to4prefix: TIn6Addr; + {$EXTERNALSYM in6addr_teredoprefix} + in6addr_teredoprefix: TIn6Addr; + +//============================================================= + +{ + wsipx.h + + Microsoft Windows + Copyright (C) Microsoft Corporation, 1992-1999. + + Windows Sockets include file for IPX/SPX. This file contains all + standardized IPX/SPX information. Include this header file after + winsock.h. + + To open an IPX socket, call socket() with an address family of + AF_IPX, a socket type of SOCK_DGRAM, and protocol NSPROTO_IPX. + Note that the protocol value must be specified, it cannot be 0. + All IPX packets are sent with the packet type field of the IPX + header set to 0. + + To open an SPX or SPXII socket, call socket() with an address + family of AF_IPX, socket type of SOCK_SEQPACKET or SOCK_STREAM, + and protocol of NSPROTO_SPX or NSPROTO_SPXII. If SOCK_SEQPACKET + is specified, then the end of message bit is respected, and + recv() calls are not completed until a packet is received with + the end of message bit set. If SOCK_STREAM is specified, then + the end of message bit is not respected, and recv() completes + as soon as any data is received, regardless of the setting of the + end of message bit. Send coalescing is never performed, and sends + smaller than a single packet are always sent with the end of + message bit set. Sends larger than a single packet are packetized + with the end of message bit set on only the last packet of the + send. +} + +// This is the structure of the SOCKADDR structure for IPX and SPX. +type + {$EXTERNALSYM SOCKADDR_IPX} + SOCKADDR_IPX = record + sa_family : u_short; + sa_netnum : Array [0..3] of TIdAnsiChar; + sa_nodenum : Array [0..5] of TIdAnsiChar; + sa_socket : u_short; + end; + {$NODEFINE TSockAddrIPX} + TSockAddrIPX = SOCKADDR_IPX; + {$NODEFINE PSockAddrIPX} + PSockAddrIPX = ^TSockAddrIPX; + {$EXTERNALSYM PSOCKADDR_IPX} + PSOCKADDR_IPX = PSockAddrIPX; + {$EXTERNALSYM LPSOCKADDR_IPX} + LPSOCKADDR_IPX = PSOCKADDR_IPX; + +// Protocol families used in the "protocol" parameter of the socket() API. +const + {$EXTERNALSYM NSPROTO_IPX} + NSPROTO_IPX = 1000; + {$EXTERNALSYM NSPROTO_SPX} + NSPROTO_SPX = 1256; + {$EXTERNALSYM NSPROTO_SPXII} + NSPROTO_SPXII = 1257; + + +//============================================================= + +{ + wsnwlink.h + + Microsoft Windows + Copyright (C) Microsoft Corporation, 1992-1999. + Microsoft-specific extensions to the Windows NT IPX/SPX Windows + Sockets interface. These extensions are provided for use as + necessary for compatibility with existing applications. They are + otherwise not recommended for use, as they are only guaranteed to + work over the Microsoft IPX/SPX stack. An application which + uses these extensions may not work over other IPX/SPX + implementations. Include this header file after winsock.h and + wsipx.h. + + To open an IPX socket where a particular packet type is sent in + the IPX header, specify NSPROTO_IPX + n as the protocol parameter + of the socket() API. For example, to open an IPX socket that + sets the packet type to 34, use the following socket() call: + + s = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX + 34); +} + +// Below are socket option that may be set or retrieved by specifying +// the appropriate manifest in the "optname" parameter of getsockopt() +// or setsockopt(). Use NSPROTO_IPX as the "level" argument for the +// call. +const + +// Set/get the IPX packet type. The value specified in the +// optval argument will be set as the packet type on every IPX +// packet sent from this socket. The optval parameter of +// getsockopt()/setsockopt() points to an int. + {$EXTERNALSYM IPX_PTYPE} + IPX_PTYPE = $4000; + +// Set/get the receive filter packet type. Only IPX packets with +// a packet type equal to the value specified in the optval +// argument will be returned; packets with a packet type that +// does not match are discarded. optval points to an int. + {$EXTERNALSYM IPX_FILTERPTYPE} + IPX_FILTERPTYPE = $4001; + +// Stop filtering on packet type set with IPX_FILTERPTYPE. + {$EXTERNALSYM IPX_STOPFILTERPTYPE} + IPX_STOPFILTERPTYPE = $4003; + +// Set/get the value of the datastream field in the SPX header on +// every packet sent. optval points to an int. + {$EXTERNALSYM IPX_DSTYPE} + IPX_DSTYPE = $4002; + +// Enable extended addressing. On sends, adds the element +// "unsigned char sa_ptype" to the SOCKADDR_IPX structure, +// making the total length 15 bytes. On receives, add both +// the sa_ptype and "unsigned char sa_flags" to the SOCKADDR_IPX +// structure, making the total length 16 bytes. The current +// bits defined in sa_flags are: +// 0x01 - the received frame was sent as a broadcast +// 0x02 - the received frame was sent from this machine +// optval points to a BOOL. + {$EXTERNALSYM IPX_EXTENDED_ADDRESS} + IPX_EXTENDED_ADDRESS = $4004; + +// Send protocol header up on all receive packets. optval points +// to a BOOL. + {$EXTERNALSYM IPX_RECVHDR} + IPX_RECVHDR = $4005; + +// Get the maximum data size that can be sent. Not valid with +// setsockopt(). optval points to an int where the value is +// returned. + {$EXTERNALSYM IPX_MAXSIZE} + IPX_MAXSIZE = $4006; + +// Query information about a specific adapter that IPX is bound +// to. In a system with n adapters they are numbered 0 through n-1. +// Callers can issue the IPX_MAX_ADAPTER_NUM getsockopt() to find +// out the number of adapters present, or call IPX_ADDRESS with +// increasing values of adapternum until it fails. Not valid +// with setsockopt(). optval points to an instance of the +// IPX_ADDRESS_DATA structure with the adapternum filled in. + {$EXTERNALSYM IPX_ADDRESS} + IPX_ADDRESS = $4007; + +type + {$EXTERNALSYM IPX_ADDRESS_DATA} + IPX_ADDRESS_DATA = record + adapternum : Integer; // input: 0-based adapter number + netnum : Array [0..3] of Byte; // output: IPX network number + nodenum : Array [0..5] of Byte; // output: IPX node address + wan : Boolean; // output: TRUE = adapter is on a wan link + status : Boolean; // output: TRUE = wan link is up (or adapter is not wan) + maxpkt : Integer; // output: max packet size, not including IPX header + linkspeed : ULONG; // output: link speed in 100 bytes/sec (i.e. 96 == 9600 bps) + end; + {$NODEFINE TIPXAddressData} + TIPXAddressData = IPX_ADDRESS_DATA; + {$NODEFINE PIPXAddressData} + PIPXAddressData = ^TIPXAddressData; + {$EXTERNALSYM PIPX_ADDRESS_DATA} + PIPX_ADDRESS_DATA = PIPXAddressData; + +const +// Query information about a specific IPX network number. If the +// network is in IPX's cache it will return the information directly, {Do not Localize} +// otherwise it will issue RIP requests to find it. Not valid with +// setsockopt(). optval points to an instance of the IPX_NETNUM_DATA +// structure with the netnum filled in. + {$EXTERNALSYM IPX_GETNETINFO} + IPX_GETNETINFO = $4008; + +type + {$EXTERNALSYM IPX_NETNUM_DATA} + IPX_NETNUM_DATA = record + netnum : Array [0..3] of Byte; // input: IPX network number + hopcount : Word; // output: hop count to this network, in machine order + netdelay : Word; // output: tick count to this network, in machine order + cardnum : Integer; // output: 0-based adapter number used to route to this net; + // can be used as adapternum input to IPX_ADDRESS + router : Array [0..5] of Byte; // output: MAC address of the next hop router, zeroed if + // the network is directly attached + end; + {$NODEFINE TIPXNetNumData} + TIPXNetNumData = IPX_NETNUM_DATA; + {$NODEFINE PIPXNetNumData} + PIPXNetNumData = ^TIPXNetNumData; + {$EXTERNALSYM PIPX_NETNUM_DATA} + PIPX_NETNUM_DATA = PIPXNetNumData; + +const +// Like IPX_GETNETINFO except it does not issue RIP requests. If the +// network is in IPX's cache it will return the information, otherwise {Do not Localize} +// it will fail (see also IPX_RERIPNETNUMBER which always forces a +// re-RIP). Not valid with setsockopt(). optval points to an instance of +// the IPX_NETNUM_DATA structure with the netnum filled in. + {$EXTERNALSYM IPX_GETNETINFO_NORIP} + IPX_GETNETINFO_NORIP = $4009; + +// Get information on a connected SPX socket. optval points +// to an instance of the IPX_SPXCONNSTATUS_DATA structure. +// *** All numbers are in Novell (high-low) order. *** + {$EXTERNALSYM IPX_SPXGETCONNECTIONSTATUS} + IPX_SPXGETCONNECTIONSTATUS = $400B; + +type + {$EXTERNALSYM IPX_SPXCONNSTATUS_DATA} + IPX_SPXCONNSTATUS_DATA = record + ConnectionState : Byte; + WatchDogActive : Byte; + LocalConnectionId : Word; + RemoteConnectionId : Word; + LocalSequenceNumber : Word; + LocalAckNumber : Word; + LocalAllocNumber : Word; + RemoteAckNumber : Word; + RemoteAllocNumber : Word; + LocalSocket : Word; + ImmediateAddress : Array [0..5] of Byte; + RemoteNetwork : Array [0..3] of Byte; + RemoteNode : Array [0..5] of Byte; + RemoteSocket : Word; + RetransmissionCount : Word; + EstimatedRoundTripDelay : Word; // In milliseconds + RetransmittedPackets : Word; + SuppressedPacket : Word; + end; + {$NODEFINE TIPXSPXConnStatusData} + TIPXSPXConnStatusData = IPX_SPXCONNSTATUS_DATA; + {$NODEFINE PIPXSPXConnStatusData} + PIPXSPXConnStatusData = ^TIPXSPXConnStatusData; + {$EXTERNALSYM PIPX_SPXCONNSTATUS_DATA} + PIPX_SPXCONNSTATUS_DATA = PIPXSPXConnStatusData; + +const +// Get notification when the status of an adapter that IPX is +// bound to changes. Typically this will happen when a wan line +// goes up or down. Not valid with setsockopt(). optval points +// to a buffer which contains an IPX_ADDRESS_DATA structure +// followed immediately by a HANDLE to an unsignaled event. +// +// When the getsockopt() query is submitted, it will complete +// successfully. However, the IPX_ADDRESS_DATA pointed to by +// optval will not be updated at that point. Instead the +// request is queued internally inside the transport. +// +// When the status of an adapter changes, IPX will locate a +// queued getsockopt() query and fill in all the fields in the +// IPX_ADDRESS_DATA structure. It will then signal the event +// pointed to by the HANDLE in the optval buffer. This handle +// should be obtained before calling getsockopt() by calling +// CreateEvent(). If multiple getsockopts() are submitted at +// once, different events must be used. +// +// The event is used because the call needs to be asynchronous +// but currently getsockopt() does not support this. +// +// WARNING: In the current implementation, the transport will +// only signal one queued query for each status change. Therefore +// only one service which uses this query should be running at +// once. + {$EXTERNALSYM IPX_ADDRESS_NOTIFY} + IPX_ADDRESS_NOTIFY = $400C; + +// Get the maximum number of adapters present. If this call returns +// n then the adapters are numbered 0 through n-1. Not valid +// with setsockopt(). optval points to an int where the value +// is returned. + {$EXTERNALSYM IPX_MAX_ADAPTER_NUM} + IPX_MAX_ADAPTER_NUM = $400D; + +// Like IPX_GETNETINFO except it forces IPX to re-RIP even if the +// network is in its cache (but not if it is directly attached to). +// Not valid with setsockopt(). optval points to an instance of +// the IPX_NETNUM_DATA structure with the netnum filled in. + {$EXTERNALSYM IPX_RERIPNETNUMBER} + IPX_RERIPNETNUMBER = $400E; + +// A hint that broadcast packets may be received. The default is +// TRUE. Applications that do not need to receive broadcast packets +// should set this sockopt to FALSE which may cause better system +// performance (note that it does not necessarily cause broadcasts +// to be filtered for the application). Not valid with getsockopt(). +// optval points to a BOOL. + {$EXTERNALSYM IPX_RECEIVE_BROADCAST} + IPX_RECEIVE_BROADCAST = $400F; + +// On SPX connections, don't delay before sending ack. Applications {Do not Localize} +// that do not tend to have back-and-forth traffic over SPX should +// set this; it will increase the number of acks sent but will remove +// delays in sending acks. optval points to a BOOL. + {$EXTERNALSYM IPX_IMMEDIATESPXACK} + IPX_IMMEDIATESPXACK = $4010; + + +//============================================================= + +// wsnetbs.h +// Copyright (c) 1994-1999, Microsoft Corp. All rights reserved. +// +// Windows Sockets include file for NETBIOS. This file contains all +// standardized NETBIOS information. Include this header file after +// winsock.h. + +// To open a NetBIOS socket, call the socket() function as follows: +// +// s = socket( AF_NETBIOS, {SOCK_SEQPACKET|SOCK_DGRAM}, -Lana ); +// +// where Lana is the NetBIOS Lana number of interest. For example, to +// open a socket for Lana 2, specify -2 as the "protocol" parameter +// to the socket() function. + + +// This is the structure of the SOCKADDR structure for NETBIOS. + +const + {$EXTERNALSYM NETBIOS_NAME_LENGTH} + NETBIOS_NAME_LENGTH = 16; + +type + {$EXTERNALSYM SOCKADDR_NB} + SOCKADDR_NB = record + snb_family : short; + snb_type : u_short; + snb_name : array[0..NETBIOS_NAME_LENGTH-1] of TIdAnsiChar; + end; + {$NODEFINE TSockAddrNB} + TSockAddrNB = SOCKADDR_NB; + {$NODEFINE PSockAddrNB} + PSockAddrNB = ^TSockAddrNB; + {$EXTERNALSYM PSOCKADDR_NB} + PSOCKADDR_NB = PSockAddrNB; + {$EXTERNALSYM LPSOCKADDR_NB} + LPSOCKADDR_NB = PSOCKADDR_NB; + +// Bit values for the snb_type field of SOCKADDR_NB. +const + {$EXTERNALSYM NETBIOS_UNIQUE_NAME} + NETBIOS_UNIQUE_NAME = $0000; + {$EXTERNALSYM NETBIOS_GROUP_NAME} + NETBIOS_GROUP_NAME = $0001; + {$EXTERNALSYM NETBIOS_TYPE_QUICK_UNIQUE} + NETBIOS_TYPE_QUICK_UNIQUE = $0002; + {$EXTERNALSYM NETBIOS_TYPE_QUICK_GROUP} + NETBIOS_TYPE_QUICK_GROUP = $0003; + +// A macro convenient for setting up NETBIOS SOCKADDRs. +{$EXTERNALSYM SET_NETBIOS_SOCKADDR} +procedure SET_NETBIOS_SOCKADDR(snb : PSockAddrNB; const SnbType : Word; const Name : PIdAnsiChar; const Port : TIdAnsiChar); + + +//============================================================= + +// Copyright 1997 - 1998 Microsoft Corporation +// +// Module Name: +// +// ws2atm.h +// +// Abstract: +// +// Winsock 2 ATM Annex definitions. + +const + {$EXTERNALSYM ATMPROTO_AALUSER} + ATMPROTO_AALUSER = $00; // User-defined AAL + {$EXTERNALSYM ATMPROTO_AAL1} + ATMPROTO_AAL1 = $01; // AAL 1 + {$EXTERNALSYM ATMPROTO_AAL2} + ATMPROTO_AAL2 = $02; // AAL 2 + {$EXTERNALSYM ATMPROTO_AAL34} + ATMPROTO_AAL34 = $03; // AAL 3/4 + {$EXTERNALSYM ATMPROTO_AAL5} + ATMPROTO_AAL5 = $05; // AAL 5 + + {$EXTERNALSYM SAP_FIELD_ABSENT} + SAP_FIELD_ABSENT = $FFFFFFFE; + {$EXTERNALSYM SAP_FIELD_ANY} + SAP_FIELD_ANY = $FFFFFFFF; + {$EXTERNALSYM SAP_FIELD_ANY_AESA_SEL} + SAP_FIELD_ANY_AESA_SEL = $FFFFFFFA; + {$EXTERNALSYM SAP_FIELD_ANY_AESA_REST} + SAP_FIELD_ANY_AESA_REST = $FFFFFFFB; + + // values used for AddressType in struct ATM_ADDRESS + {$EXTERNALSYM ATM_E164} + ATM_E164 = $01; // E.164 addressing scheme + {$EXTERNALSYM ATM_NSAP} + ATM_NSAP = $02; // NSAP-style ATM Endsystem Address scheme + {$EXTERNALSYM ATM_AESA} + ATM_AESA = $02; // NSAP-style ATM Endsystem Address scheme + + {$EXTERNALSYM ATM_ADDR_SIZE} + ATM_ADDR_SIZE = 20; + +type + {$EXTERNALSYM ATM_ADDRESS} + ATM_ADDRESS = record + AddressType : DWORD; // E.164 or NSAP-style ATM Endsystem Address + NumofDigits : DWORD; // number of digits; + Addr : Array[0..ATM_ADDR_SIZE-1] of Byte; // IA5 digits for E164, BCD encoding for NSAP + // format as defined in the ATM Forum UNI 3.1 + end; + +// values used for Layer2Protocol in B-LLI +const + {$EXTERNALSYM BLLI_L2_ISO_1745} + BLLI_L2_ISO_1745 = $01; // Basic mode ISO 1745 + {$EXTERNALSYM BLLI_L2_Q921} + BLLI_L2_Q921 = $02; // CCITT Rec. Q.921 + {$EXTERNALSYM BLLI_L2_X25L} + BLLI_L2_X25L = $06; // CCITT Rec. X.25, link layer + {$EXTERNALSYM BLLI_L2_X25M} + BLLI_L2_X25M = $07; // CCITT Rec. X.25, multilink + {$EXTERNALSYM BLLI_L2_ELAPB} + BLLI_L2_ELAPB = $08; // Extended LAPB; for half duplex operation + {$EXTERNALSYM BLLI_L2_HDLC_NRM} + BLLI_L2_HDLC_NRM = $09; // HDLC NRM (ISO 4335) + {$EXTERNALSYM BLLI_L2_HDLC_ABM} + BLLI_L2_HDLC_ABM = $0A; // HDLC ABM (ISO 4335) + {$EXTERNALSYM BLLI_L2_HDLC_ARM} + BLLI_L2_HDLC_ARM = $0B; // HDLC ARM (ISO 4335) + {$EXTERNALSYM BLLI_L2_LLC} + BLLI_L2_LLC = $0C; // LAN logical link control (ISO 8802/2) + {$EXTERNALSYM BLLI_L2_X75} + BLLI_L2_X75 = $0D; // CCITT Rec. X.75, single link procedure + {$EXTERNALSYM BLLI_L2_Q922} + BLLI_L2_Q922 = $0E; // CCITT Rec. Q.922 + {$EXTERNALSYM BLLI_L2_USER_SPECIFIED} + BLLI_L2_USER_SPECIFIED = $10; // User Specified + {$EXTERNALSYM BLLI_L2_ISO_7776} + BLLI_L2_ISO_7776 = $11; // ISO 7776 DTE-DTE operation + +// values used for Layer3Protocol in B-LLI + {$EXTERNALSYM BLLI_L3_X25} + BLLI_L3_X25 = $06; // CCITT Rec. X.25, packet layer + {$EXTERNALSYM BLLI_L3_ISO_8208} + BLLI_L3_ISO_8208 = $07; // ISO/IEC 8208 (X.25 packet layer for DTE + {$EXTERNALSYM BLLI_L3_X223} + BLLI_L3_X223 = $08; // X.223/ISO 8878 + {$EXTERNALSYM BLLI_L3_SIO_8473} + BLLI_L3_SIO_8473 = $09; // ISO/IEC 8473 (OSI connectionless) + {$EXTERNALSYM BLLI_L3_T70} + BLLI_L3_T70 = $0A; // CCITT Rec. T.70 min. network layer + {$EXTERNALSYM BLLI_L3_ISO_TR9577} + BLLI_L3_ISO_TR9577 = $0B; // ISO/IEC TR 9577 Network Layer Protocol ID + {$EXTERNALSYM BLLI_L3_USER_SPECIFIED} + BLLI_L3_USER_SPECIFIED = $10; // User Specified + +// values used for Layer3IPI in B-LLI + {$EXTERNALSYM BLLI_L3_IPI_SNAP} + BLLI_L3_IPI_SNAP = $80; // IEEE 802.1 SNAP identifier + {$EXTERNALSYM BLLI_L3_IPI_IP} + BLLI_L3_IPI_IP = $CC; // Internet Protocol (IP) identifier + +type + {$EXTERNALSYM ATM_BLLI} + ATM_BLLI = record + // Identifies the layer-two protocol. + // Corresponds to the User information layer 2 protocol field in the B-LLI information element. + // A value of SAP_FIELD_ABSENT indicates that this field is not used, and a value of SAP_FIELD_ANY means wildcard. + Layer2Protocol : DWORD; // User information layer 2 protocol + // Identifies the user-specified layer-two protocol. + // Only used if the Layer2Protocol parameter is set to BLLI_L2_USER_SPECIFIED. + // The valid values range from zero-127. + // Corresponds to the User specified layer 2 protocol information field in the B-LLI information element. + Layer2UserSpecifiedProtocol : DWORD; // User specified layer 2 protocol information + // Identifies the layer-three protocol. + // Corresponds to the User information layer 3 protocol field in the B-LLI information element. + // A value of SAP_FIELD_ABSENT indicates that this field is not used, and a value of SAP_FIELD_ANY means wildcard. + Layer3Protocol : DWORD; // User information layer 3 protocol + // Identifies the user-specified layer-three protocol. + // Only used if the Layer3Protocol parameter is set to BLLI_L3_USER_SPECIFIED. + // The valid values range from zero-127. + // Corresponds to the User specified layer 3 protocol information field in the B-LLI information element. + Layer3UserSpecifiedProtocol : DWORD; // User specified layer 3 protocol information + // Identifies the layer-three Initial Protocol Identifier. + // Only used if the Layer3Protocol parameter is set to BLLI_L3_ISO_TR9577. + // Corresponds to the ISO/IEC TR 9577 Initial Protocol Identifier field in the B-LLI information element. + Layer3IPI : DWORD; // ISO/IEC TR 9577 Initial Protocol Identifier + // Identifies the 802.1 SNAP identifier. + // Only used if the Layer3Protocol parameter is set to BLLI_L3_ISO_TR9577 and Layer3IPI is set to BLLI_L3_IPI_SNAP, + // indicating an IEEE 802.1 SNAP identifier. Corresponds to the OUI and PID fields in the B-LLI information element. + SnapID : Array[0..4] of Byte; // SNAP ID consisting of OUI and PID + end; + +// values used for the HighLayerInfoType field in ATM_BHLI +const + {$EXTERNALSYM BHLI_ISO} + BHLI_ISO = $00; // ISO + {$EXTERNALSYM BHLI_UserSpecific} + BHLI_UserSpecific = $01; // User Specific + {$EXTERNALSYM BHLI_HighLayerProfile} + BHLI_HighLayerProfile = $02; // High layer profile (only in UNI3.0) + {$EXTERNALSYM BHLI_VendorSpecificAppId} + BHLI_VendorSpecificAppId = $03; // Vendor-Specific Application ID + +type + {$EXTERNALSYM ATM_BHLI} + ATM_BHLI = record + // Identifies the high layer information type field in the B-LLI information element. + // Note that the type BHLI_HighLayerProfile has been eliminated in UNI 3.1. + // A value of SAP_FIELD_ABSENT indicates that B-HLI is not present, and a value of SAP_FIELD_ANY means wildcard. + HighLayerInfoType : DWORD; // High Layer Information Type + // Identifies the number of bytes from one to eight in the HighLayerInfo array. + // Valid values include eight for the cases of BHLI_ISO and BHLI_UserSpecific, + // four for BHLI_HighLayerProfile, and seven for BHLI_VendorSpecificAppId. + HighLayerInfoLength : DWORD; // number of bytes in HighLayerInfo + // Identifies the high layer information field in the B-LLI information element. + // In the case of HighLayerInfoType being BHLI_VendorSpecificAppId, + // the first 3 bytes consist of a globally-administered Organizationally Unique Identifier (OUI) + // (as per IEEE standard 802-1990), followed by a 4-byte application identifier, + // which is administered by the vendor identified by the OUI. + // Value for the case of BHLI_UserSpecific is user defined and requires bilateral agreement between two end users. + HighLayerInfo : Array[0..7] of Byte; // the value dependent on the HighLayerInfoType field + end; + +// A new address family, AF_ATM, is introduced for native ATM services, +// and the corresponding SOCKADDR structure, sockaddr_atm, is defined in the following. +// To open a socket for native ATM services, parameters in socket should contain +// AF_ATM, SOCK_RAW, and ATMPROTO_AAL5 or ATMPROTO_AALUSER, respectively. + {$EXTERNALSYM SOCKADDR_ATM} + SOCKADDR_ATM = record + // Identifies the address family, which is AF_ATM in this case. + satm_family : u_short; + // Identifies the ATM address that could be either in E.164 or NSAP-style ATM End Systems Address format. + // This field will be mapped to the Called Party Number IE (Information Element) + // if it is specified in bind and WSPBind for a listening socket, or in connect, WSAConnect, WSPConnect, + // WSAJoinLeaf, or WSPJoinLeaf for a connecting socket. + // It will be mapped to the Calling Party Number IE if specified in bind and WSPBind for a connecting socket. + satm_number : ATM_ADDRESS; + // Identifies the fields in the B-LLI Information Element that are used along with satm_bhli to identify an application. + // Note that the B-LLI layer two information is treated as not present + // if its Layer2Protocol field contains SAP_FIELD_ABSENT, or as a wildcard if it contains SAP_FIELD_ANY. + // Similarly, the B-LLI layer three information is treated as not present + // if its Layer3Protocol field contains SAP_FIELD_ABSENT, or as a wildcard if it contains SAP_FIELD_ANY. + satm_blli : ATM_BLLI; // B-LLI + // Identifies the fields in the B-HLI Information Element that are used along with satm_blli to identify an application. + satm_bhli : ATM_BHLI; // B-HLI + end; + {$NODEFINE TSockAddrATM} + TSockAddrATM = SOCKADDR_ATM; + {$NODEFINE PSockAddrATM} + PSockAddrATM = ^TSockAddrATM; + {$EXTERNALSYM PSOCKADDR_ATM} + PSOCKADDR_ATM = PSockAddrATM; + {$EXTERNALSYM LPSOCKADDR_ATM} + LPSOCKADDR_ATM = PSOCKADDR_ATM; + + {$EXTERNALSYM Q2931_IE_TYPE} + Q2931_IE_TYPE = ( + IE_AALParameters, + IE_TrafficDescriptor, + IE_BroadbandBearerCapability, + IE_BHLI, + IE_BLLI, + IE_CalledPartyNumber, + IE_CalledPartySubaddress, + IE_CallingPartyNumber, + IE_CallingPartySubaddress, + IE_Cause, + IE_QOSClass, + IE_TransitNetworkSelection); + + {$EXTERNALSYM Q2931_IE} + Q2931_IE = record + IEType : Q2931_IE_TYPE; + IELength : ULONG; + IE : Array[0..0] of Byte; + end; + +// manifest constants for the AALType field in struct AAL_PARAMETERS_IE + {$EXTERNALSYM AAL_TYPE} + AAL_TYPE = LongInt; + +const + {$EXTERNALSYM AALTYPE_5} + AALTYPE_5 = 5; // AAL 5 + {$EXTERNALSYM AALTYPE_USER} + AALTYPE_USER = 16; // user-defined AAL + + // values used for the Mode field in struct AAL5_PARAMETERS + {$EXTERNALSYM AAL5_MODE_MESSAGE} + AAL5_MODE_MESSAGE = $01; + {$EXTERNALSYM AAL5_MODE_STREAMING} + AAL5_MODE_STREAMING = $02; + +// values used for the SSCSType field in struct AAL5_PARAMETERS + {$EXTERNALSYM AAL5_SSCS_NULL} + AAL5_SSCS_NULL = $00; + {$EXTERNALSYM AAL5_SSCS_SSCOP_ASSURED} + AAL5_SSCS_SSCOP_ASSURED = $01; + {$EXTERNALSYM AAL5_SSCS_SSCOP_NON_ASSURED} + AAL5_SSCS_SSCOP_NON_ASSURED = $02; + {$EXTERNALSYM AAL5_SSCS_FRAME_RELAY} + AAL5_SSCS_FRAME_RELAY = $04; + +type + {$EXTERNALSYM AAL5_PARAMETERS} + AAL5_PARAMETERS = record + ForwardMaxCPCSSDUSize : ULONG; + BackwardMaxCPCSSDUSize : ULONG; + Mode : Byte; // only available in UNI 3.0 + SSCSType : Byte; + end; + + {$EXTERNALSYM AALUSER_PARAMETERS} + AALUSER_PARAMETERS = record + UserDefined : ULONG; + end; + + {$EXTERNALSYM AAL_PARAMETERS_IE} + AAL_PARAMETERS_IE = record + AALType : AAL_TYPE; + case Byte of + 0: ( AAL5Parameters : AAL5_PARAMETERS ); + 1: ( AALUserParameters : AALUSER_PARAMETERS ); + end; + + {$EXTERNALSYM ATM_TD} + ATM_TD = record + PeakCellRate_CLP0 : ULONG; + PeakCellRate_CLP01 : ULONG; + SustainableCellRate_CLP0 : ULONG; + SustainableCellRate_CLP01 : ULONG; + MaxBurstSize_CLP0 : ULONG; + MaxBurstSize_CLP01 : ULONG; + Tagging : LongBool; + end; + + {$EXTERNALSYM ATM_TRAFFIC_DESCRIPTOR_IE} + ATM_TRAFFIC_DESCRIPTOR_IE = record + _Forward : ATM_TD; + Backward : ATM_TD; + BestEffort : LongBool; + end; + +// values used for the BearerClass field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE +const + {$EXTERNALSYM BCOB_A} + BCOB_A = $01; // Bearer class A + {$EXTERNALSYM BCOB_C} + BCOB_C = $03; // Bearer class C + {$EXTERNALSYM BCOB_X} + BCOB_X = $10; // Bearer class X + +// values used for the TrafficType field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE + {$EXTERNALSYM TT_NOIND} + TT_NOIND = $00; // No indication of traffic type + {$EXTERNALSYM TT_CBR} + TT_CBR = $04; // Constant bit rate + {$EXTERNALSYM TT_VBR} + TT_VBR = $06; // Variable bit rate + +// values used for the TimingRequirements field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE + {$EXTERNALSYM TR_NOIND} + TR_NOIND = $00; // No timing requirement indication + {$EXTERNALSYM TR_END_TO_END} + TR_END_TO_END = $01; // End-to-end timing required + {$EXTERNALSYM TR_NO_END_TO_END} + TR_NO_END_TO_END = $02; // End-to-end timing not required + +// values used for the ClippingSusceptability field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE + {$EXTERNALSYM CLIP_NOT} + CLIP_NOT = $00; // Not susceptible to clipping + {$EXTERNALSYM CLIP_SUS} + CLIP_SUS = $20; // Susceptible to clipping + +// values used for the UserPlaneConnectionConfig field in struct ATM_BROADBAND_BEARER_CAPABILITY_IE + {$EXTERNALSYM UP_P2P} + UP_P2P = $00; // Point-to-point connection + {$EXTERNALSYM UP_P2MP} + UP_P2MP = $01; // Point-to-multipoint connection + +type + {$EXTERNALSYM ATM_BROADBAND_BEARER_CAPABILITY_IE} + ATM_BROADBAND_BEARER_CAPABILITY_IE = record + BearerClass : Byte; + TrafficType : Byte; + TimingRequirements : Byte; + ClippingSusceptability : Byte; + UserPlaneConnectionConfig : Byte; + end; + {$EXTERNALSYM ATM_BHLI_IE} + ATM_BHLI_IE = ATM_BHLI; + +// values used for the Layer2Mode field in struct ATM_BLLI_IE +const + {$EXTERNALSYM BLLI_L2_MODE_NORMAL} + BLLI_L2_MODE_NORMAL = $40; + {$EXTERNALSYM BLLI_L2_MODE_EXT} + BLLI_L2_MODE_EXT = $80; + +// values used for the Layer3Mode field in struct ATM_BLLI_IE + {$EXTERNALSYM BLLI_L3_MODE_NORMAL} + BLLI_L3_MODE_NORMAL = $40; + {$EXTERNALSYM BLLI_L3_MODE_EXT} + BLLI_L3_MODE_EXT = $80; + +// values used for the Layer3DefaultPacketSize field in struct ATM_BLLI_IE + {$EXTERNALSYM BLLI_L3_PACKET_16} + BLLI_L3_PACKET_16 = $04; + {$EXTERNALSYM BLLI_L3_PACKET_32} + BLLI_L3_PACKET_32 = $05; + {$EXTERNALSYM BLLI_L3_PACKET_64} + BLLI_L3_PACKET_64 = $06; + {$EXTERNALSYM BLLI_L3_PACKET_128} + BLLI_L3_PACKET_128 = $07; + {$EXTERNALSYM BLLI_L3_PACKET_256} + BLLI_L3_PACKET_256 = $08; + {$EXTERNALSYM BLLI_L3_PACKET_512} + BLLI_L3_PACKET_512 = $09; + {$EXTERNALSYM BLLI_L3_PACKET_1024} + BLLI_L3_PACKET_1024 = $0A; + {$EXTERNALSYM BLLI_L3_PACKET_2048} + BLLI_L3_PACKET_2048 = $0B; + {$EXTERNALSYM BLLI_L3_PACKET_4096} + BLLI_L3_PACKET_4096 = $0C; + +type + {$EXTERNALSYM ATM_BLLI_IE} + ATM_BLLI_IE = record + Layer2Protocol : DWORD; // User information layer 2 protocol + Layer2Mode : Byte; + Layer2WindowSize : Byte; + Layer2UserSpecifiedProtocol : DWORD; // User specified layer 2 protocol information + Layer3Protocol : DWORD; // User information layer 3 protocol + Layer3Mode : Byte; + Layer3DefaultPacketSize : Byte; + Layer3PacketWindowSize : Byte; + Layer3UserSpecifiedProtocol : DWORD; // User specified layer 3 protocol information + Layer3IPI : DWORD; // ISO/IEC TR 9577 Initial Protocol Identifier + SnapID : Array[0..4] of Byte; // SNAP ID consisting of OUI and PID + end; + {$EXTERNALSYM ATM_CALLED_PARTY_NUMBER_IE} + ATM_CALLED_PARTY_NUMBER_IE = ATM_ADDRESS; + {$EXTERNALSYM ATM_CALLED_PARTY_SUBADDRESS_IE} + ATM_CALLED_PARTY_SUBADDRESS_IE = ATM_ADDRESS; + +// values used for the Presentation_Indication field in struct ATM_CALLING_PARTY_NUMBER_IE +const + {$EXTERNALSYM PI_ALLOWED} + PI_ALLOWED = $00; + {$EXTERNALSYM PI_RESTRICTED} + PI_RESTRICTED = $40; + {$EXTERNALSYM PI_NUMBER_NOT_AVAILABLE} + PI_NUMBER_NOT_AVAILABLE = $80; + +// values used for the Screening_Indicator field in struct ATM_CALLING_PARTY_NUMBER_IE + {$EXTERNALSYM SI_USER_NOT_SCREENED} + SI_USER_NOT_SCREENED = $00; + {$EXTERNALSYM SI_USER_PASSED} + SI_USER_PASSED = $01; + {$EXTERNALSYM SI_USER_FAILED} + SI_USER_FAILED = $02; + {$EXTERNALSYM SI_NETWORK} + SI_NETWORK = $03; + +type + {$EXTERNALSYM ATM_CALLING_PARTY_NUMBER_IE} + ATM_CALLING_PARTY_NUMBER_IE = record + ATM_Number : ATM_ADDRESS; + Presentation_Indication : Byte; + Screening_Indicator : Byte; + end; + {$EXTERNALSYM ATM_CALLING_PARTY_SUBADDRESS_IE} + ATM_CALLING_PARTY_SUBADDRESS_IE = ATM_ADDRESS; + +// values used for the Location field in struct ATM_CAUSE_IE +const + {$EXTERNALSYM CAUSE_LOC_USER} + CAUSE_LOC_USER = $00; + {$EXTERNALSYM CAUSE_LOC_PRIVATE_LOCAL} + CAUSE_LOC_PRIVATE_LOCAL = $01; + {$EXTERNALSYM CAUSE_LOC_PUBLIC_LOCAL} + CAUSE_LOC_PUBLIC_LOCAL = $02; + {$EXTERNALSYM CAUSE_LOC_TRANSIT_NETWORK} + CAUSE_LOC_TRANSIT_NETWORK = $03; + {$EXTERNALSYM CAUSE_LOC_PUBLIC_REMOTE} + CAUSE_LOC_PUBLIC_REMOTE = $04; + {$EXTERNALSYM CAUSE_LOC_PRIVATE_REMOTE} + CAUSE_LOC_PRIVATE_REMOTE = $05; + {$EXTERNALSYM CAUSE_LOC_INTERNATIONAL_NETWORK} + CAUSE_LOC_INTERNATIONAL_NETWORK = $06; + {$EXTERNALSYM CAUSE_LOC_BEYOND_INTERWORKING} + CAUSE_LOC_BEYOND_INTERWORKING = $0A; + +// values used for the Cause field in struct ATM_CAUSE_IE + {$EXTERNALSYM CAUSE_UNALLOCATED_NUMBER} + CAUSE_UNALLOCATED_NUMBER = $01; + {$EXTERNALSYM CAUSE_NO_ROUTE_TO_TRANSIT_NETWORK} + CAUSE_NO_ROUTE_TO_TRANSIT_NETWORK = $02; + {$EXTERNALSYM CAUSE_NO_ROUTE_TO_DESTINATION} + CAUSE_NO_ROUTE_TO_DESTINATION = $03; + {$EXTERNALSYM CAUSE_VPI_VCI_UNACCEPTABLE} + CAUSE_VPI_VCI_UNACCEPTABLE = $0A; + {$EXTERNALSYM CAUSE_NORMAL_CALL_CLEARING} + CAUSE_NORMAL_CALL_CLEARING = $10; + {$EXTERNALSYM CAUSE_USER_BUSY} + CAUSE_USER_BUSY = $11; + {$EXTERNALSYM CAUSE_NO_USER_RESPONDING} + CAUSE_NO_USER_RESPONDING = $12; + {$EXTERNALSYM CAUSE_CALL_REJECTED} + CAUSE_CALL_REJECTED = $15; + {$EXTERNALSYM CAUSE_NUMBER_CHANGED} + CAUSE_NUMBER_CHANGED = $16; + {$EXTERNALSYM CAUSE_USER_REJECTS_CLIR} + CAUSE_USER_REJECTS_CLIR = $17; + {$EXTERNALSYM CAUSE_DESTINATION_OUT_OF_ORDER} + CAUSE_DESTINATION_OUT_OF_ORDER = $1B; + {$EXTERNALSYM CAUSE_INVALID_NUMBER_FORMAT} + CAUSE_INVALID_NUMBER_FORMAT = $1C; + {$EXTERNALSYM CAUSE_STATUS_ENQUIRY_RESPONSE} + CAUSE_STATUS_ENQUIRY_RESPONSE = $1E; + {$EXTERNALSYM CAUSE_NORMAL_UNSPECIFIED} + CAUSE_NORMAL_UNSPECIFIED = $1F; + {$EXTERNALSYM CAUSE_VPI_VCI_UNAVAILABLE} + CAUSE_VPI_VCI_UNAVAILABLE = $23; + {$EXTERNALSYM CAUSE_NETWORK_OUT_OF_ORDER} + CAUSE_NETWORK_OUT_OF_ORDER = $26; + {$EXTERNALSYM CAUSE_TEMPORARY_FAILURE} + CAUSE_TEMPORARY_FAILURE = $29; + {$EXTERNALSYM CAUSE_ACCESS_INFORMAION_DISCARDED} + CAUSE_ACCESS_INFORMAION_DISCARDED = $2B; + {$EXTERNALSYM CAUSE_NO_VPI_VCI_AVAILABLE} + CAUSE_NO_VPI_VCI_AVAILABLE = $2D; + {$EXTERNALSYM CAUSE_RESOURCE_UNAVAILABLE} + CAUSE_RESOURCE_UNAVAILABLE = $2F; + {$EXTERNALSYM CAUSE_QOS_UNAVAILABLE} + CAUSE_QOS_UNAVAILABLE = $31; + {$EXTERNALSYM CAUSE_USER_CELL_RATE_UNAVAILABLE} + CAUSE_USER_CELL_RATE_UNAVAILABLE = $33; + {$EXTERNALSYM CAUSE_BEARER_CAPABILITY_UNAUTHORIZED} + CAUSE_BEARER_CAPABILITY_UNAUTHORIZED = $39; + {$EXTERNALSYM CAUSE_BEARER_CAPABILITY_UNAVAILABLE} + CAUSE_BEARER_CAPABILITY_UNAVAILABLE = $3A; + {$EXTERNALSYM CAUSE_OPTION_UNAVAILABLE} + CAUSE_OPTION_UNAVAILABLE = $3F; + {$EXTERNALSYM CAUSE_BEARER_CAPABILITY_UNIMPLEMENTED} + CAUSE_BEARER_CAPABILITY_UNIMPLEMENTED = $41; + {$EXTERNALSYM CAUSE_UNSUPPORTED_TRAFFIC_PARAMETERS} + CAUSE_UNSUPPORTED_TRAFFIC_PARAMETERS = $49; + {$EXTERNALSYM CAUSE_INVALID_CALL_REFERENCE} + CAUSE_INVALID_CALL_REFERENCE = $51; + {$EXTERNALSYM CAUSE_CHANNEL_NONEXISTENT} + CAUSE_CHANNEL_NONEXISTENT = $52; + {$EXTERNALSYM CAUSE_INCOMPATIBLE_DESTINATION} + CAUSE_INCOMPATIBLE_DESTINATION = $58; + {$EXTERNALSYM CAUSE_INVALID_ENDPOINT_REFERENCE} + CAUSE_INVALID_ENDPOINT_REFERENCE = $59; + {$EXTERNALSYM CAUSE_INVALID_TRANSIT_NETWORK_SELECTION} + CAUSE_INVALID_TRANSIT_NETWORK_SELECTION = $5B; + {$EXTERNALSYM CAUSE_TOO_MANY_PENDING_ADD_PARTY} + CAUSE_TOO_MANY_PENDING_ADD_PARTY = $5C; + {$EXTERNALSYM CAUSE_AAL_PARAMETERS_UNSUPPORTED} + CAUSE_AAL_PARAMETERS_UNSUPPORTED = $5D; + {$EXTERNALSYM CAUSE_MANDATORY_IE_MISSING} + CAUSE_MANDATORY_IE_MISSING = $60; + {$EXTERNALSYM CAUSE_UNIMPLEMENTED_MESSAGE_TYPE} + CAUSE_UNIMPLEMENTED_MESSAGE_TYPE = $61; + {$EXTERNALSYM CAUSE_UNIMPLEMENTED_IE} + CAUSE_UNIMPLEMENTED_IE = $63; + {$EXTERNALSYM CAUSE_INVALID_IE_CONTENTS} + CAUSE_INVALID_IE_CONTENTS = $64; + {$EXTERNALSYM CAUSE_INVALID_STATE_FOR_MESSAGE} + CAUSE_INVALID_STATE_FOR_MESSAGE = $65; + {$EXTERNALSYM CAUSE_RECOVERY_ON_TIMEOUT} + CAUSE_RECOVERY_ON_TIMEOUT = $66; + {$EXTERNALSYM CAUSE_INCORRECT_MESSAGE_LENGTH} + CAUSE_INCORRECT_MESSAGE_LENGTH = $68; + {$EXTERNALSYM CAUSE_PROTOCOL_ERROR} + CAUSE_PROTOCOL_ERROR = $6F; + +// values used for the Condition portion of the Diagnostics field +// in struct ATM_CAUSE_IE, for certain Cause values + {$EXTERNALSYM CAUSE_COND_UNKNOWN} + CAUSE_COND_UNKNOWN = $00; + {$EXTERNALSYM CAUSE_COND_PERMANENT} + CAUSE_COND_PERMANENT = $01; + {$EXTERNALSYM CAUSE_COND_TRANSIENT} + CAUSE_COND_TRANSIENT = $02; + +// values used for the Rejection Reason portion of the Diagnostics field +// in struct ATM_CAUSE_IE, for certain Cause values + {$EXTERNALSYM CAUSE_REASON_USER} + CAUSE_REASON_USER = $00; + {$EXTERNALSYM CAUSE_REASON_IE_MISSING} + CAUSE_REASON_IE_MISSING = $04; + {$EXTERNALSYM CAUSE_REASON_IE_INSUFFICIENT} + CAUSE_REASON_IE_INSUFFICIENT = $08; + +// values used for the P-U flag of the Diagnostics field +// in struct ATM_CAUSE_IE, for certain Cause values + {$EXTERNALSYM CAUSE_PU_PROVIDER} + CAUSE_PU_PROVIDER = $00; + {$EXTERNALSYM CAUSE_PU_USER} + CAUSE_PU_USER = $08; + +// values used for the N-A flag of the Diagnostics field +// in struct ATM_CAUSE_IE, for certain Cause values + {$EXTERNALSYM CAUSE_NA_NORMAL} + CAUSE_NA_NORMAL = $00; + {$EXTERNALSYM CAUSE_NA_ABNORMAL} + CAUSE_NA_ABNORMAL = $04; + +type + {$EXTERNALSYM ATM_CAUSE_IE} + ATM_CAUSE_IE = record + Location : Byte; + Cause : Byte; + DiagnosticsLength : Byte; + Diagnostics : Array[0..3] of Byte; + end; + +// values used for the QOSClassForward and QOSClassBackward +// field in struct ATM_QOS_CLASS_IE +const + {$EXTERNALSYM QOS_CLASS0} + QOS_CLASS0 = $00; + {$EXTERNALSYM QOS_CLASS1} + QOS_CLASS1 = $01; + {$EXTERNALSYM QOS_CLASS2} + QOS_CLASS2 = $02; + {$EXTERNALSYM QOS_CLASS3} + QOS_CLASS3 = $03; + {$EXTERNALSYM QOS_CLASS4} + QOS_CLASS4 = $04; + +type + {$EXTERNALSYM ATM_QOS_CLASS_IE} + ATM_QOS_CLASS_IE = record + QOSClassForward : Byte; + QOSClassBackward : Byte; + end; + +// values used for the TypeOfNetworkId field in struct ATM_TRANSIT_NETWORK_SELECTION_IE +const + {$EXTERNALSYM TNS_TYPE_NATIONAL} + TNS_TYPE_NATIONAL = $40; + +// values used for the NetworkIdPlan field in struct ATM_TRANSIT_NETWORK_SELECTION_IE + {$EXTERNALSYM TNS_PLAN_CARRIER_ID_CODE} + TNS_PLAN_CARRIER_ID_CODE = $01; + +type + {$EXTERNALSYM ATM_TRANSIT_NETWORK_SELECTION_IE} + ATM_TRANSIT_NETWORK_SELECTION_IE = record + TypeOfNetworkId : Byte; + NetworkIdPlan : Byte; + NetworkIdLength : Byte; + NetworkId : Array[0..0] of Byte; + end; + +// ATM specific Ioctl codes +const + {$EXTERNALSYM SIO_GET_NUMBER_OF_ATM_DEVICES} + SIO_GET_NUMBER_OF_ATM_DEVICES = $50160001; + {$EXTERNALSYM SIO_GET_ATM_ADDRESS} + SIO_GET_ATM_ADDRESS = $d0160002; + {$EXTERNALSYM SIO_ASSOCIATE_PVC} + SIO_ASSOCIATE_PVC = $90160003; + {$EXTERNALSYM SIO_GET_ATM_CONNECTION_ID} + SIO_GET_ATM_CONNECTION_ID = $50160004; + +// ATM Connection Identifier +type + {$EXTERNALSYM ATM_CONNECTION_ID} + ATM_CONNECTION_ID = record + DeviceNumber : DWORD; + VPI : DWORD; + VCI : DWORD; + end; + +// Input buffer format for SIO_ASSOCIATE_PVC + {$EXTERNALSYM ATM_PVC_PARAMS} + ATM_PVC_PARAMS = record + PvcConnectionId : ATM_CONNECTION_ID; + PvcQos : QOS; + end; + + {$NODEFINE InitializeWinSock} + procedure InitializeWinSock; + {$NODEFINE UninitializeWinSock} + procedure UninitializeWinSock; + function Winsock2Loaded: Boolean; + function WinsockHandle : TIdLibHandle; + +//JPM +{ +I made these symbols up so to prevent range check warnings in FreePascal. +SizeOf is a SmallInt when an expression is evaluated at run-time. This +run-time evaluation makes no sense because the compiler knows these when compiling +so it should give us the numbers. + +} +const + {$EXTERNALSYM SIZE_WSACMSGHDR} + SIZE_WSACMSGHDR = DWORD(SizeOf(WSACMSGHDR)); + {$EXTERNALSYM SIZE_FARPROC} + SIZE_FARPROC = DWORD(SizeOf(FARPROC)); + {$EXTERNALSYM MAX_NATURAL_ALIGNMENT_SUB_1} + MAX_NATURAL_ALIGNMENT_SUB_1 = DWORD(MAX_NATURAL_ALIGNMENT - 1); + {$EXTERNALSYM SIZE_IP_MSFILTER} + SIZE_IP_MSFILTER = DWORD(SizeOf(ip_msfilter)); + {$EXTERNALSYM SIZE_TINADDR} + SIZE_TINADDR = DWORD(SizeOf(TInAddr)); + {$EXTERNALSYM SIZE_TIN6ADDR} + SIZE_TIN6ADDR = DWORD(SizeOf(TIn6Addr)); + {$EXTERNALSYM SIZE_TSOCKADDRIN} + SIZE_TSOCKADDRIN = DWORD(SizeOf(TSockAddrIn)); + {$EXTERNALSYM SIZE_TSOCKADDRIN6} + SIZE_TSOCKADDRIN6 = DWORD(SizeOf(TSockAddrIn6)); + {$EXTERNALSYM SIZE_GROUP_FILTER} + SIZE_GROUP_FILTER = DWORD(SizeOf(GROUP_FILTER)); + {$EXTERNALSYM SIZE_TADDRINFO} + SIZE_TADDRINFO = DWORD(SizeOf(TAddrInfo)); + {$EXTERNALSYM SIZE_SOCKADDR_STORAGE} + SIZE_SOCKADDR_STORAGE = DWORD(sizeof(SOCKADDR_STORAGE)); + {$IFNDEF WINCE} + {$EXTERNALSYM SIZE_TWSAMSG} + SIZE_TWSAMSG = DWORD(SizeOf(TWSAMSG)); + {$ENDIF} + {$EXTERNALSYM SIZE_GUID} + SIZE_GUID = DWORD(SizeOf(TGuid)); + {$EXTERNALSYM SIZE_INTEGER} + SIZE_INTEGER = DWORD(SizeOf(Integer)); + +//============================================================= + +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// Module Name: +// +// mstcpip.h +// +// Abstract: +// +// This module contains Microsoft-specific extensions to the core +// Winsock definitions. +// +// Environment: +// +// user mode or kernel mode + +type + {$EXTERNALSYM TRANSPORT_SETTING_ID} + TRANSPORT_SETTING_ID = record + Guid : TGUID; + end; + {$EXTERNALSYM PTRANSPORT_SETTING_ID} + PTRANSPORT_SETTING_ID = ^TRANSPORT_SETTING_ID; + {$EXTERNALSYM _tcp_keepalive} + _tcp_keepalive = record + onoff: u_long; + keepalivetime: u_long; + keepaliveinterval: u_long; + end; + {$EXTERNALSYM TCP_INITIAL_RTO_PARAMETERS} + TCP_INITIAL_RTO_PARAMETERS = record + // + // Supplies the initial RTT in milliseconds. + // + Rtt : USHORT; + + // + // Supplies the number of retransmissions attempted before the connection + // setup fails. + // + + MaxSynRetransmissions : UCHAR; + end; + {$EXTERNALSYM PTCP_INITIAL_RTO_PARAMETERS} + PTCP_INITIAL_RTO_PARAMETERS = ^TCP_INITIAL_RTO_PARAMETERS; + {$EXTERNALSYM _INET_PORT_RANGE} + _INET_PORT_RANGE = record + StartPort : USHORT; + NumberOfPorts : USHORT; + end; + {$EXTERNALSYM INET_PORT_RANGE} + INET_PORT_RANGE = _INET_PORT_RANGE; + {$EXTERNALSYM PINET_PORT_RANGE} + PINET_PORT_RANGE = ^INET_PORT_RANGE; + {$EXTERNALSYM INET_PORT_RESERVATION} + INET_PORT_RESERVATION = _INET_PORT_RANGE; + {$EXTERNALSYM PINET_PORT_RESERVATION} + PINET_PORT_RESERVATION = ^INET_PORT_RESERVATION; + {$EXTERNALSYM INET_PORT_RESERVATION_TOKEN} + INET_PORT_RESERVATION_TOKEN = record + Token : ULONG64; + end; + {$EXTERNALSYM PINET_PORT_RESERVATION_TOKEN} + PINET_PORT_RESERVATION_TOKEN = ^INET_PORT_RESERVATION_TOKEN; + {$EXTERNALSYM INET_PORT_RESERVATION_INSTANCE} + INET_PORT_RESERVATION_INSTANCE = record + Reservation : INET_PORT_RESERVATION; + Token : INET_PORT_RESERVATION_TOKEN; + end; + {$EXTERNALSYM PINET_PORT_RESERVATION_INSTANCE} + PINET_PORT_RESERVATION_INSTANCE = ^INET_PORT_RESERVATION_INSTANCE; + + {$EXTERNALSYM INET_PORT_RESERVATION_INFORMATION} + INET_PORT_RESERVATION_INFORMATION = record + AssignmentCount : ULONG; + OwningPid : ULONG; + end; + {$EXTERNALSYM PINET_PORT_RESERVATION_INFORMATION} + PINET_PORT_RESERVATION_INFORMATION = ^INET_PORT_RESERVATION_INFORMATION; + {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS} + {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_INVALID} + {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_SOFTWARE_SLOT_ALLOCATED} + {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_HARDWARE_SLOT_ALLOCATED} + {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_POLICY_ERROR} + {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_SYSTEM_ERROR} + {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_TRANSPORT_DISCONNECTED} + {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_SERVICE_UNAVAILABLE} + CONTROL_CHANNEL_TRIGGER_STATUS = ( + CONTROL_CHANNEL_TRIGGER_STATUS_INVALID, + CONTROL_CHANNEL_TRIGGER_STATUS_SOFTWARE_SLOT_ALLOCATED, + CONTROL_CHANNEL_TRIGGER_STATUS_HARDWARE_SLOT_ALLOCATED, + CONTROL_CHANNEL_TRIGGER_STATUS_POLICY_ERROR, + CONTROL_CHANNEL_TRIGGER_STATUS_SYSTEM_ERROR, + CONTROL_CHANNEL_TRIGGER_STATUS_TRANSPORT_DISCONNECTED, + CONTROL_CHANNEL_TRIGGER_STATUS_SERVICE_UNAVAILABLE); + {$EXTERNALSYM PCONTROL_CHANNEL_TRIGGER_STATUS} + PCONTROL_CHANNEL_TRIGGER_STATUS = ^CONTROL_CHANNEL_TRIGGER_STATUS; + {$EXTERNALSYM REAL_TIME_NOTIFICATION_SETTING_INPUT} + REAL_TIME_NOTIFICATION_SETTING_INPUT = record + TransportSettingId : TRANSPORT_SETTING_ID; + BrokerEventGuid : TGUID; + end; + {$EXTERNALSYM PREAL_TIME_NOTIFICATION_SETTING_INPUT} + PREAL_TIME_NOTIFICATION_SETTING_INPUT = ^REAL_TIME_NOTIFICATION_SETTING_INPUT; + {$EXTERNALSYM REAL_TIME_NOTIFICATION_SETTING_OUTPUT} + REAL_TIME_NOTIFICATION_SETTING_OUTPUT = record + ChannelStatus : CONTROL_CHANNEL_TRIGGER_STATUS; + end; + {$EXTERNALSYM PREAL_TIME_NOTIFICATION_SETTING_OUTPUT} + PREAL_TIME_NOTIFICATION_SETTING_OUTPUT = ^REAL_TIME_NOTIFICATION_SETTING_OUTPUT; + {$EXTERNALSYM RCVALL_VALUE} + {$EXTERNALSYM RCVALL_OFF} + {$EXTERNALSYM RCVALL_ON} + {$EXTERNALSYM RCVALL_SOCKETLEVELONLY} + {$EXTERNALSYM RCVALL_IPLEVEL} + RCVALL_VALUE = ( + RCVALL_OFF, + RCVALL_ON, + RCVALL_SOCKETLEVELONLY, + RCVALL_IPLEVEL + ); + {$EXTERNALSYM PRCVALL_VALUE} + PRCVALL_VALUE = ^RCVALL_VALUE; + {$EXTERNALSYM RCVALL_IF} + RCVALL_IF = record + Mode : RCVALL_VALUE; + _Interface : ULONG; + end; + {$EXTERNALSYM PRCVALL_IF} + PRCVALL_IF = ^RCVALL_IF; + {$EXTERNALSYM SOCKET_SECURITY_QUERY_INFO_IPSEC2} + SOCKET_SECURITY_QUERY_INFO_IPSEC2 = record + SecurityProtocol : SOCKET_SECURITY_PROTOCOL; + Flags : ULONG; + PeerApplicationAccessTokenHandle : UINT64; + PeerMachineAccessTokenHandle : UINT64; + MmSaId : UINT64; + QmSaId : UINT64; + NegotiationWinerr : UINT32; + SaLookupContext : TGuid; + end; + {$EXTERNALSYM PSOCKET_SECURITY_QUERY_INFO_IPSEC2} + PSOCKET_SECURITY_QUERY_INFO_IPSEC2 = ^SOCKET_SECURITY_QUERY_INFO_IPSEC2; + {$EXTERNALSYM RSS_SCALABILITY_INFO} + RSS_SCALABILITY_INFO = record + RssEnabled : BOOL; + end; + {$EXTERNALSYM PRSS_SCALABILITY_INFO} + PRSS_SCALABILITY_INFO = ^RSS_SCALABILITY_INFO; + +const +// +// Argument structures for SIO_QUERY_TRANSPORT_SETTING and +// SIO_QUERY_TRANSPORT_SETTING. +// + + {$EXTERNALSYM CONTROL_CHANNEL_TRIGGER_STATUS_MAX} + CONTROL_CHANNEL_TRIGGER_STATUS_MAX = CONTROL_CHANNEL_TRIGGER_STATUS_SYSTEM_ERROR; + +// +// New WSAIoctl Options +// + {$EXTERNALSYM SIO_RCVALL} + SIO_RCVALL = (IOC_IN or IOC_VENDOR or 1); + {$EXTERNALSYM SIO_RCVALL_MCAST} + SIO_RCVALL_MCAST = (IOC_IN or IOC_VENDOR or 2); + {$EXTERNALSYM SIO_RCVALL_IGMPMCAST} + SIO_RCVALL_IGMPMCAST = (IOC_IN or IOC_VENDOR or 3); + {$EXTERNALSYM SIO_KEEPALIVE_VALS} + SIO_KEEPALIVE_VALS = (IOC_IN or IOC_VENDOR or 4); + {$EXTERNALSYM SIO_ABSORB_RTRALERT} + SIO_ABSORB_RTRALERT = (IOC_IN or IOC_VENDOR or 5); + {$EXTERNALSYM SIO_UCAST_IF} + SIO_UCAST_IF = (IOC_IN or IOC_VENDOR or 6); + {$EXTERNALSYM SIO_LIMIT_BROADCASTS} + SIO_LIMIT_BROADCASTS = (IOC_IN or IOC_VENDOR or 7); + {$EXTERNALSYM SIO_INDEX_BIND} + SIO_INDEX_BIND = (IOC_IN or IOC_VENDOR or 8); + {$EXTERNALSYM SIO_INDEX_MCASTIF} + SIO_INDEX_MCASTIF = (IOC_IN or IOC_VENDOR or 9); + {$EXTERNALSYM SIO_INDEX_ADD_MCAST} + SIO_INDEX_ADD_MCAST = (IOC_IN or IOC_VENDOR or 10); + {$EXTERNALSYM SIO_INDEX_DEL_MCAST} + SIO_INDEX_DEL_MCAST = (IOC_IN or IOC_VENDOR or 11); +// SIO_UDP_CONNRESET = _WSAIOW(IOC_VENDOR,12) + {$EXTERNALSYM SIO_RCVALL_MCAST_IF} + SIO_RCVALL_MCAST_IF = (IOC_IN or IOC_VENDOR or 13); + {$EXTERNALSYM SIO_RCVALL_IF} + SIO_RCVALL_IF = (IOC_IN or IOC_VENDOR or 14); + {$EXTERNALSYM SIO_LOOPBACK_FAST_PATH} + SIO_LOOPBACK_FAST_PATH = (IOC_IN or IOC_VENDOR or 16); + {$EXTERNALSYM SIO_TCP_INITIAL_RTO} + SIO_TCP_INITIAL_RTO = (IOC_IN or IOC_VENDOR or 17); + {$EXTERNALSYM SIO_APPLY_TRANSPORT_SETTING} + SIO_APPLY_TRANSPORT_SETTING = (IOC_IN or IOC_VENDOR or 19); + {$EXTERNALSYM SIO_QUERY_TRANSPORT_SETTING} + SIO_QUERY_TRANSPORT_SETTING = (IOC_IN or IOC_VENDOR or 20); +// +// Values for use with SIO_RCVALL* options +// + {$EXTERNALSYM RCVALL_MAX} + RCVALL_MAX = RCVALL_IPLEVEL; +// +// Parameters to configure the initial RTT. +// + {$EXTERNALSYM TCP_INITIAL_RTO_UNSPECIFIED_RTT} + TCP_INITIAL_RTO_UNSPECIFIED_RTT = USHORT(-1); + {$EXTERNALSYM TCP_INITIAL_RTO_UNSPECIFIED_MAX_SYN_RETRANSMISSIONS} + TCP_INITIAL_RTO_UNSPECIFIED_MAX_SYN_RETRANSMISSIONS = UCHAR(-1); + {$EXTERNALSYM TCP_INITIAL_RTO_DEFAULT_RTT} + TCP_INITIAL_RTO_DEFAULT_RTT = (0); + {$EXTERNALSYM TCP_INITIAL_RTO_DEFAULT_MAX_SYN_RETRANSMISSIONS} + TCP_INITIAL_RTO_DEFAULT_MAX_SYN_RETRANSMISSIONS = (0); + +// +// TCP/UDP port management definitions. +// + {$EXTERNALSYM SIO_ACQUIRE_PORT_RESERVATION} + SIO_ACQUIRE_PORT_RESERVATION = (IOC_IN or IOC_VENDOR or 100); + {$EXTERNALSYM SIO_RELEASE_PORT_RESERVATION} + SIO_RELEASE_PORT_RESERVATION = (IOC_IN or IOC_VENDOR or 101); + {$EXTERNALSYM SIO_ASSOCIATE_PORT_RESERVATION} + SIO_ASSOCIATE_PORT_RESERVATION = (IOC_IN or IOC_VENDOR or 102); + + {$EXTERNALSYM INVALID_PORT_RESERVATION_TOKEN} + INVALID_PORT_RESERVATION_TOKEN = ULONG64(0); + +// +// Secure socket API type definitions. +// + {$EXTERNALSYM SIO_SET_SECURITY} + SIO_SET_SECURITY = (IOC_IN or IOC_VENDOR or 200); + {$EXTERNALSYM SIO_QUERY_SECURITY} + SIO_QUERY_SECURITY = (IOC_INOUT or IOC_VENDOR or 201); + {$EXTERNALSYM SIO_SET_PEER_TARGET_NAME} + SIO_SET_PEER_TARGET_NAME = (IOC_IN or IOC_VENDOR or 202); + {$EXTERNALSYM SIO_DELETE_PEER_TARGET_NAME} + SIO_DELETE_PEER_TARGET_NAME = (IOC_IN or IOC_VENDOR or 203); + +// +// WFP Proxy Connection Tracking API type definitions. +// + {$EXTERNALSYM SIO_QUERY_WFP_CONNECTION_REDIRECT_RECORDS} + SIO_QUERY_WFP_CONNECTION_REDIRECT_RECORDS = (IOC_IN or IOC_VENDOR or 220); + {$EXTERNALSYM SIO_QUERY_WFP_CONNECTION_REDIRECT_CONTEXT} + SIO_QUERY_WFP_CONNECTION_REDIRECT_CONTEXT = (IOC_IN or IOC_VENDOR or 221); + {$EXTERNALSYM SIO_SET_WFP_CONNECTION_REDIRECT_RECORDS} + SIO_SET_WFP_CONNECTION_REDIRECT_RECORDS = (IOC_IN or IOC_VENDOR or 222); + + {$EXTERNALSYM SIO_SOCKET_USAGE_NOTIFICATION} + SIO_SOCKET_USAGE_NOTIFICATION = (IOC_IN or IOC_VENDOR or 204); +// Flags for generic security settings + {$EXTERNALSYM SOCKET_SETTINGS_GUARANTEE_ENCRYPTION} + SOCKET_SETTINGS_GUARANTEE_ENCRYPTION = $1; + {$EXTERNALSYM SOCKET_SETTINGS_ALLOW_INSECURE} + SOCKET_SETTINGS_ALLOW_INSECURE = $2; + +// Flags specific to IPsec security settings. +// NOTE: these flags must be specified under the +// SOCKET_SECURITY_SETTINGS_IPSEC->IpsecFlags field. + {$EXTERNALSYM SOCKET_SETTINGS_IPSEC_SKIP_FILTER_INSTANTIATION} + SOCKET_SETTINGS_IPSEC_SKIP_FILTER_INSTANTIATION = $1; + {$EXTERNALSYM SOCKET_SETTINGS_IPSEC_OPTIONAL_PEER_NAME_VERIFICATION} + SOCKET_SETTINGS_IPSEC_OPTIONAL_PEER_NAME_VERIFICATION = $2; + {$EXTERNALSYM SOCKET_SETTINGS_IPSEC_ALLOW_FIRST_INBOUND_PKT_UNENCRYPTED} + SOCKET_SETTINGS_IPSEC_ALLOW_FIRST_INBOUND_PKT_UNENCRYPTED = $4; + {$EXTERNALSYM SOCKET_SETTINGS_IPSEC_PEER_NAME_IS_RAW_FORMAT} + SOCKET_SETTINGS_IPSEC_PEER_NAME_IS_RAW_FORMAT = $8; + {$EXTERNALSYM SOCKET_QUERY_IPSEC2_ABORT_CONNECTION_ON_FIELD_CHANGE} + SOCKET_QUERY_IPSEC2_ABORT_CONNECTION_ON_FIELD_CHANGE = $1; + {$EXTERNALSYM SOCKET_QUERY_IPSEC2_FIELD_MASK_MM_SA_ID} + SOCKET_QUERY_IPSEC2_FIELD_MASK_MM_SA_ID = $1; + {$EXTERNALSYM SOCKET_QUERY_IPSEC2_FIELD_MASK_QM_SA_ID} + SOCKET_QUERY_IPSEC2_FIELD_MASK_QM_SA_ID = $2; +// Flags corresponding to the security query info + {$EXTERNALSYM SOCKET_INFO_CONNECTION_SECURED} + SOCKET_INFO_CONNECTION_SECURED = $1; + {$EXTERNALSYM SOCKET_INFO_CONNECTION_ENCRYPTED} + SOCKET_INFO_CONNECTION_ENCRYPTED = $2; + {$EXTERNALSYM SOCKET_INFO_CONNECTION_IMPERSONATED} + SOCKET_INFO_CONNECTION_IMPERSONATED = $4; +// +// WFP ALE endpoint handle query type definition +// + {$EXTERNALSYM SIO_QUERY_WFP_ALE_ENDPOINT_HANDLE} + SIO_QUERY_WFP_ALE_ENDPOINT_HANDLE = (IOC_OUT or IOC_VENDOR or 205); + // +// Scalability type definitions +// + {$EXTERNALSYM SIO_QUERY_RSS_SCALABILITY_INFO} + SIO_QUERY_RSS_SCALABILITY_INFO = (IOC_OUT or IOC_VENDOR or 210); +// GUID definition for use with Secure Sockets API +// aec2ef9c-3a4d-4d3e-8842-239942e39a47 + {$EXTERNALSYM SOCKET_DEFAULT2_QM_POLICY} + SOCKET_DEFAULT2_QM_POLICY : TGuid = (D1:$aec2ef9c;D2:$3a4d;D3:$4d3e;D4:($88,$42,$23,$99,$42,$e3,$9a,$47)); +// GUID definition for use with Real Time Notification setting API. +// 6b59819a-5cae-492d-a901-2a3c2c50164f + {$EXTERNALSYM REAL_TIME_NOTIFICATION_CAPABILITY)} + REAL_TIME_NOTIFICATION_CAPABILITY : TGuid = (D1:$6b59819a;D2:$5cae;D3:$492d;D4:($a9, $01, $2a, $3c, $2c, $50, $16, $4f)); + +// +// Microsoft-specific IPv4 definitions. +// + {$EXTERNALSYM IN4ADDR_ANY} + IN4ADDR_ANY = INADDR_ANY; + {$EXTERNALSYM IN4ADDR_LOOPBACK} + IN4ADDR_LOOPBACK = $0100007f; + {$EXTERNALSYM IN4ADDR_BROADCAST} + IN4ADDR_BROADCAST = INADDR_BROADCAST; + {$EXTERNALSYM IN4ADDR_NONE} + IN4ADDR_NONE = INADDR_NONE; + + {$EXTERNALSYM IN4ADDR_ANY_INIT} + function IN4ADDR_ANY_INIT: TInAddr; + {$EXTERNALSYM IN4ADDR_LOOPBACK_INIT} + function IN4ADDR_LOOPBACK_INIT: TInAddr; + {$EXTERNALSYM IN4ADDR_BROADCAST_INIT} + function IN4ADDR_BROADCAST_INIT: TInAddr; + {$EXTERNALSYM IN4ADDR_ALLNODESONLINK_INIT} + function IN4ADDR_ALLNODESONLINK_INIT: TInAddr; + {$EXTERNALSYM IN4ADDR_ALLROUTERSONLINK_INIT} + function IN4ADDR_ALLROUTERSONLINK_INIT: TInAddr; + {$EXTERNALSYM IN4ADDR_ALLIGMPV3ROUTERSONLINK_INIT} + function IN4ADDR_ALLIGMPV3ROUTERSONLINK_INIT: TInAddr; + {$EXTERNALSYM IN4ADDR_ALLTEREDONODESONLINK_INIT} + function IN4ADDR_ALLTEREDONODESONLINK_INIT: TInAddr; + {$EXTERNALSYM IN4ADDR_LINKLOCALPREFIX_INIT} + function IN4ADDR_LINKLOCALPREFIX_INIT: TInAddr; + {$EXTERNALSYM IN4ADDR_MULTICASTPREFIX_INIT} + function IN4ADDR_MULTICASTPREFIX_INIT: TInAddr; + +const + {$EXTERNALSYM IN4ADDR_LOOPBACKPREFIX_LENGTH} + IN4ADDR_LOOPBACKPREFIX_LENGTH = 8; + {$EXTERNALSYM IN4ADDR_LINKLOCALPREFIX_LENGTH} + IN4ADDR_LINKLOCALPREFIX_LENGTH = 16; + {$EXTERNALSYM IN4ADDR_MULTICASTPREFIX_LENGTH} + IN4ADDR_MULTICASTPREFIX_LENGTH = 4; + + {$EXTERNALSYM IN6ADDR_LINKLOCALPREFIX_LENGTH} + IN6ADDR_LINKLOCALPREFIX_LENGTH = 64; + {$EXTERNALSYM IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH} + IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH = 104; + {$EXTERNALSYM IN6ADDR_V4MAPPEDPREFIX_LENGTH} + IN6ADDR_V4MAPPEDPREFIX_LENGTH = 96; + {$EXTERNALSYM IN6ADDR_6TO4PREFIX_LENGTH} + IN6ADDR_6TO4PREFIX_LENGTH = 16; + {$EXTERNALSYM IN6ADDR_TEREDOPREFIX_LENGTH} + IN6ADDR_TEREDOPREFIX_LENGTH = 32; + +{$ENDIF} +//============================================================= +implementation +//============================================================= +{$IFDEF WINDOWS} +uses + IdResourceStrings + {$IFDEF HAS_AnsiStrings_StrLen}, AnsiStrings{$ENDIF} + ; + // (c) March 2001, "Alex Konshin" + +var + hWinSockDll : TIdLibHandle = IdNilHandle; // WS2_32.DLL handle + {$IFNDEF WINCE} + hMSWSockDll : TIdLibHandle = IdNilHandle; // MSWSOCK.DLL handle + {$ENDIF} + +function WinsockHandle : TIdLibHandle; +begin + Result := hWinSockDll; +end; + +function Winsock2Loaded : Boolean; +begin + Result := hWinSockDll <> IdNilHandle; +end; + +procedure InitializeWinSock; +var + LData: TWSAData; + LError: DWORD; +begin + if hWinSockDll = IdNilHandle then begin + hWinSockDll := SafeLoadLibrary(WINSOCK2_DLL); + if hWinSockDll <> IdNilHandle then begin + LError := WSAStartup($202, LData); + if LError = 0 then begin + Exit; + end; + Windows.FreeLibrary(hWinSockDll); + hWinSockDll := IdNilHandle; + end else begin + LError := Windows.GetLastError; + end; + raise EIdWinsockStubError.Build(LError, RSWinsockLoadError, [WINSOCK2_DLL]); + end; +end; + +{$IFNDEF WINCE} +procedure LoadMSWSock; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if hMSWSockDll = IdNilHandle then begin + hMSWSockDll := SafeLoadLibrary(MSWSOCK_DLL); + if hMSWSockDll = IdNilHandle then begin + raise EIdWinsockStubError.Build(Windows.GetLastError, RSWinsockLoadError, [MSWSOCK_DLL]); + end; + end; +end; +{$ENDIF} + +procedure UninitializeWinSock; +begin +{$IFNDEF WINCE} + if hMSWSockDll <> IdNilHandle then + begin + FreeLibrary(hMSWSockDll); + hMSWSockDll := IdNilHandle; + end; +{$ENDIF} + if hWinSockDll <> IdNilHandle then + begin + WSACleanup; + FreeLibrary(hWinSockDll); + hWinSockDll := IdNilHandle; + end; +end; + +constructor EIdWinsockStubError.Build(AWin32Error: DWORD; const ATitle: String; AArgs: array of const); +begin + FTitle := IndyFormat(ATitle, AArgs); + FWin32Error := AWin32Error; + if AWin32Error = 0 then begin + inherited Create(FTitle); + end else + begin + FWin32ErrorMessage := SysUtils.SysErrorMessage(AWin32Error); + inherited Create(FTitle + ': ' + FWin32ErrorMessage); {Do not Localize} + end; +end; + +function FixupStub(hDll: TIdLibHandle; const AName: TIdLibFuncName): Pointer; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if hDll = IdNilHandle then begin + raise EIdWinsockStubError.Build(WSANOTINITIALISED, RSWinsockCallError, [AName]); + end; + Result := LoadLibFunction(hDll, AName); + if Result = nil then begin + raise EIdWinsockStubError.Build(WSAEINVAL, RSWinsockCallError, [AName]); + end; +end; + +function FixupStubEx(hSocket: TSocket; const AName: string; const AGuid: TGUID): Pointer; +var + LBytesSend: DWORD; +begin + // RLebeau: in XE4+, PDWORD is NOT defined as ^DWORD, so we have to use a type-cast! + if WSAIoctl(hSocket, SIO_GET_EXTENSION_FUNCTION_POINTER, @AGuid, DWORD(SIZE_GUID), + @Result, SIZE_FARPROC, PDWORD(@LBytesSend), nil, nil) <> 0 then + begin + raise EIdWinsockStubError.Build(WSAGetLastError, RSWinsockCallError, [AName]); + end; +end; + +function Stub_WSAStartup(const wVersionRequired: word; out WSData: TWSAData): Integer; stdcall; +begin + @WSAStartup := FixupStub(hWinSockDll, 'WSAStartup'); {Do not Localize} + Result := WSAStartup(wVersionRequired, WSData); +end; + +function Stub_WSACleanup: Integer; stdcall; +begin + @WSACleanup := FixupStub(hWinSockDll, 'WSACleanup'); {Do not Localize} + Result := WSACleanup; +end; + +function Stub_accept(const s: TSocket; AAddr: PSockAddr; addrlen: PInteger): TSocket; stdcall; +begin + @accept := FixupStub(hWinSockDll, 'accept'); {Do not Localize} + Result := accept(s, AAddr, addrlen); +end; + +function Stub_bind(const s: TSocket; const name: PSockAddr; const namelen: Integer): Integer; stdcall; +begin + @bind := FixupStub(hWinSockDll, 'bind'); {Do not Localize} + Result := bind(s, name, namelen); +end; + +function Stub_closesocket(const s: TSocket): Integer; stdcall; +begin + @closesocket := FixupStub(hWinSockDll, 'closesocket'); {Do not Localize} + Result := closesocket(s); +end; + +function Stub_connect(const s: TSocket; const name: PSockAddr; const namelen: Integer): Integer; stdcall; +begin + @connect := FixupStub(hWinSockDll, 'connect'); {Do not Localize} + Result := connect(s, name, namelen); +end; + +function Stub_ioctlsocket(const s: TSocket; const cmd: DWORD; var arg: u_long): Integer; stdcall; +begin + @ioctlsocket := FixupStub(hWinSockDll, 'ioctlsocket'); {Do not Localize} + Result := ioctlsocket(s, cmd, arg); +end; + +function Stub_getpeername(const s: TSocket; const name: PSockAddr; var namelen: Integer): Integer; stdcall; +begin + @getpeername := FixupStub(hWinSockDll, 'getpeername'); {Do not Localize} + Result := getpeername(s, name, namelen); +end; + +function Stub_getsockname(const s: TSocket; const name: PSockAddr; var namelen: Integer): Integer; stdcall; +begin + @getsockname := FixupStub(hWinSockDll, 'getsockname'); {Do not Localize} + Result := getsockname(s, name, namelen); +end; + +function Stub_getsockopt(const s: TSocket; const level, optname: Integer; optval: PIdAnsiChar; var optlen: Integer): Integer; stdcall; +begin + @getsockopt := FixupStub(hWinSockDll, 'getsockopt'); {Do not Localize} + Result := getsockopt(s, level, optname, optval, optlen); +end; + +function Stub_htonl(hostlong: u_long): u_long; stdcall; +begin + @htonl := FixupStub(hWinSockDll, 'htonl'); {Do not Localize} + Result := htonl(hostlong); +end; + +function Stub_htons(hostshort: u_short): u_short; stdcall; +begin + @htons := FixupStub(hWinSockDll, 'htons'); {Do not Localize} + Result := htons(hostshort); +end; + +function Stub_inet_addr(cp: PIdAnsiChar): u_long; stdcall; +begin + @inet_addr := FixupStub(hWinSockDll, 'inet_addr'); {Do not Localize} + Result := inet_addr(cp); +end; + +function Stub_inet_ntoa(inaddr: TInAddr): PIdAnsiChar; stdcall; +begin + @inet_ntoa := FixupStub(hWinSockDll, 'inet_ntoa'); {Do not Localize} + Result := inet_ntoa(inaddr); +end; + +function Stub_listen(const s: TSocket; backlog: Integer): Integer; stdcall; +begin + @listen := FixupStub(hWinSockDll, 'listen'); {Do not Localize} + Result := listen(s, backlog); +end; + +function Stub_ntohl(netlong: u_long): u_long; stdcall; +begin + @ntohl := FixupStub(hWinSockDll, 'ntohl'); {Do not Localize} + Result := ntohl(netlong); +end; + +function Stub_ntohs(netshort: u_short): u_short; stdcall; +begin + @ntohs := FixupStub(hWinSockDll, 'ntohs'); {Do not Localize} + Result := ntohs(netshort); +end; + +function Stub_recv(const s: TSocket; var Buf; len, flags: Integer): Integer; stdcall; +begin + @recv := FixupStub(hWinSockDll, 'recv'); {Do not Localize} + Result := recv(s, Buf, len, flags); +end; + +function Stub_recvfrom(const s: TSocket; var Buf; len, flags: Integer; from: PSockAddr; fromlen: PInteger): Integer; stdcall; +begin + @recvfrom := FixupStub(hWinSockDll, 'recvfrom'); {Do not Localize} + Result := recvfrom(s, Buf, len, flags, from, fromlen); +end; + +function Stub_select(nfds: Integer; readfds, writefds, exceptfds: PFDSet; timeout: PTimeVal): Integer; stdcall; +begin + @select := FixupStub(hWinSockDll, 'select'); {Do not Localize} + Result := select(nfds, readfds, writefds, exceptfds, timeout); +end; + +function Stub_send(const s: TSocket; const Buf; len, flags: Integer): Integer; stdcall; +begin + @send := FixupStub(hWinSockDll, 'send'); {Do not Localize} + Result := send(s, Buf, len, flags); +end; + +function Stub_sendto(const s: TSocket; const Buf; const len, flags: Integer; const addrto: PSockAddr; const tolen: Integer): Integer; stdcall; +begin + @sendto := FixupStub(hWinSockDll, 'sendto'); {Do not Localize} + Result := sendto(s, Buf, len, flags, addrto, tolen); +end; + +function Stub_setsockopt(const s: TSocket; const level, optname: Integer; optval: PIdAnsiChar; const optlen: Integer): Integer; stdcall; +begin + @setsockopt := FixupStub(hWinSockDll, 'setsockopt'); {Do not Localize} + Result := setsockopt(s, level, optname, optval, optlen); +end; + +function Stub_shutdown(const s: TSocket; const how: Integer): Integer; stdcall; +begin + @shutdown := FixupStub(hWinSockDll, 'shutdown'); {Do not Localize} + Result := shutdown(s, how); +end; + +function Stub_socket(const af, istruct, protocol: Integer): TSocket; stdcall; +begin + @socket := FixupStub(hWinSockDll, 'socket'); {Do not Localize} + Result := socket(af, istruct, protocol); +end; + +function Stub_gethostbyaddr(AAddr: Pointer; const len, addrtype: Integer): PHostEnt; stdcall; +begin + @gethostbyaddr := FixupStub(hWinSockDll, 'gethostbyaddr'); {Do not Localize} + Result := gethostbyaddr(AAddr, len, addrtype); +end; + +function Stub_gethostbyname(name: PIdAnsiChar): PHostEnt; stdcall; +begin + @gethostbyname := FixupStub(hWinSockDll, 'gethostbyname'); {Do not Localize} + Result := gethostbyname(name); +end; + +{$IFDEF WINCE} +function Stub_sethostname(pName : PIdAnsiChar; cName : Integer) : Integer; stdcall; +begin + @sethostname := FixupStub(hWinSockDll, 'sethostname'); {Do not Localize} + Result := sethostname(pName, cName); +end; +{$ENDIF} + +function Stub_gethostname(name: PIdAnsiChar; len: Integer): Integer; stdcall; +begin + @gethostname := FixupStub(hWinSockDll, 'gethostname'); {Do not Localize} + Result := gethostname(name, len); +end; + +function Stub_getservbyport(const port: Integer; const proto: PIdAnsiChar): PServEnt; stdcall; +begin + @getservbyport := FixupStub(hWinSockDll, 'getservbyport'); {Do not Localize} + Result := getservbyport(port, proto); +end; + +function Stub_getservbyname(const name, proto: PIdAnsiChar): PServEnt; stdcall; +begin + @getservbyname := FixupStub(hWinSockDll, 'getservbyname'); {Do not Localize} + Result := getservbyname(name, proto); +end; + +function Stub_getprotobynumber(const proto: Integer): PProtoEnt; stdcall; +begin + @getprotobynumber := FixupStub(hWinSockDll, 'getprotobynumber'); {Do not Localize} + Result := getprotobynumber(proto); +end; + +function Stub_getprotobyname(const name: PIdAnsiChar): PProtoEnt; stdcall; +begin + @getprotobyname := FixupStub(hWinSockDll, 'getprotobyname'); {Do not Localize} + Result := getprotobyname(name); +end; + +procedure Stub_WSASetLastError(const iError: Integer); stdcall; +begin + @WSASetLastError := FixupStub(hWinSockDll, 'WSASetLastError'); {Do not Localize} + WSASetLastError(iError); +end; + +function Stub_WSAGetLastError: Integer; stdcall; +begin + @WSAGetLastError := FixupStub(hWinSockDll, 'WSAGetLastError'); {Do not Localize} + Result := WSAGetLastError; +end; + +{$IFNDEF WINCE} +function Stub_WSAIsBlocking: BOOL; stdcall; +begin + @WSAIsBlocking := FixupStub(hWinSockDll, 'WSAIsBlocking'); {Do not Localize} + Result := WSAIsBlocking; +end; + +function Stub_WSAUnhookBlockingHook: Integer; stdcall; +begin + @WSAUnhookBlockingHook := FixupStub(hWinSockDll, 'WSAUnhookBlockingHook'); {Do not Localize} + Result := WSAUnhookBlockingHook; +end; + +function Stub_WSASetBlockingHook(lpBlockFunc: TFarProc): TFarProc; stdcall; +begin + @WSASetBlockingHook := FixupStub(hWinSockDll, 'WSASetBlockingHook'); {Do not Localize} + Result := WSASetBlockingHook(lpBlockFunc); +end; + +function Stub_WSACancelBlockingCall: Integer; stdcall; +begin + @WSACancelBlockingCall := FixupStub(hWinSockDll, 'WSACancelBlockingCall'); {Do not Localize} + Result := WSACancelBlockingCall; +end; + +function Stub_WSAAsyncGetServByName(HWindow: HWND; wMsg: u_int; name, proto, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; +begin + @WSAAsyncGetServByName := FixupStub(hWinSockDll, 'WSAAsyncGetServByName'); {Do not Localize} + Result := WSAAsyncGetServByName(HWindow, wMsg, name, proto, buf, buflen); +end; + +function Stub_WSAAsyncGetServByPort(HWindow: HWND; wMsg, port: u_int; proto, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; +begin + @WSAAsyncGetServByPort := FixupStub(hWinSockDll, 'WSAAsyncGetServByPort'); {Do not Localize} + Result := WSAAsyncGetServByPort(HWindow, wMsg, port, proto, buf, buflen); +end; + +function Stub_WSAAsyncGetProtoByName(HWindow: HWND; wMsg: u_int; name, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; +begin + @WSAAsyncGetProtoByName := FixupStub(hWinSockDll, 'WSAAsyncGetProtoByName'); {Do not Localize} + Result := WSAAsyncGetProtoByName(HWindow, wMsg, name, buf, buflen); +end; + +function Stub_WSAAsyncGetProtoByNumber(HWindow: HWND; wMsg: u_int; number: Integer; buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; +begin + @WSAAsyncGetProtoByNumber := FixupStub(hWinSockDll, 'WSAAsyncGetProtoByNumber'); {Do not Localize} + Result := WSAAsyncGetProtoByNumber(HWindow, wMsg, number, buf, buflen); +end; + +function Stub_WSAAsyncGetHostByName(HWindow: HWND; wMsg: u_int; name, buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; +begin + @WSAAsyncGetHostByName := FixupStub(hWinSockDll, 'WSAAsyncGetHostByName'); {Do not Localize} + Result := WSAAsyncGetHostByName(HWindow, wMsg, name, buf, buflen); +end; + +function Stub_WSAAsyncGetHostByAddr(HWindow: HWND; wMsg: u_int; AAddr: PIdAnsiChar; len, istruct: Integer; buf: PIdAnsiChar; buflen: Integer): THandle; stdcall; +begin + @WSAAsyncGetHostByAddr := FixupStub(hWinSockDll, 'WSAAsyncGetHostByAddr'); {Do not Localize} + Result := WSAAsyncGetHostByAddr(HWindow, wMsg, AAddr, len, istruct, buf, buflen); +end; + +function Stub_WSACancelAsyncRequest(hAsyncTaskHandle: THandle): Integer; stdcall; +begin + @WSACancelAsyncRequest := FixupStub(hWinSockDll, 'WSACancelAsyncRequest'); {Do not Localize} + Result := WSACancelAsyncRequest(hAsyncTaskHandle); +end; + +function Stub_WSAAsyncSelect(const s: TSocket; HWindow: HWND; wMsg: u_int; lEvent: Longint): Integer; stdcall; +begin + @WSAAsyncSelect := FixupStub(hWinSockDll, 'WSAAsyncSelect'); {Do not Localize} + Result := WSAAsyncSelect(s, HWindow, wMsg, lEvent); +end; +{$ENDIF} + +function Stub___WSAFDIsSet(const s: TSocket; var FDSet: TFDSet): Bool; stdcall; +begin + @__WSAFDIsSet := FixupStub(hWinSockDll, '__WSAFDIsSet'); {Do not Localize} + Result := __WSAFDIsSet(s, FDSet); +end; + +function Stub_WSAAccept(const s: TSocket; AAddr: PSockAddr; addrlen: PInteger; lpfnCondition: LPCONDITIONPROC; const dwCallbackData: DWORD): TSocket; stdcall; +begin + @WSAAccept := FixupStub(hWinSockDll, 'WSAAccept'); {Do not Localize} + Result := WSAAccept(s, AAddr, addrlen, lpfnCondition, dwCallbackData); +end; + +function Stub_WSACloseEvent(const hEvent: wsaevent): WordBool; stdcall; +begin + @WSACloseEvent := FixupStub(hWinSockDll, 'WSACloseEvent'); {Do not Localize} + Result := WSACloseEvent(hEvent); +end; + +function Stub_WSAConnect(const s: TSocket; const name: PSockAddr; const namelen: Integer; lpCallerData, lpCalleeData: LPWSABUF; lpSQOS, lpGQOS: LPQOS): Integer; stdcall; +begin + @WSAConnect := FixupStub(hWinSockDll, 'WSAConnect'); {Do not Localize} + Result := WSAConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS); +end; + +function Stub_WSACreateEvent: wsaevent; stdcall; +begin + @WSACreateEvent := FixupStub(hWinSockDll, 'WSACreateEvent'); {Do not Localize} + Result := WSACreateEvent; +end; + +{$IFNDEF WINCE} +function Stub_WSADuplicateSocketA(const s: TSocket; const dwProcessId: DWORD; lpProtocolInfo: LPWSAPROTOCOL_INFOA): Integer; stdcall; +begin + @WSADuplicateSocketA := FixupStub(hWinSockDll, 'WSADuplicateSocketA'); {Do not Localize} + Result := WSADuplicateSocketA(s, dwProcessId, lpProtocolInfo); +end; + +function Stub_WSADuplicateSocketW(const s: TSocket; const dwProcessId: DWORD; lpProtocolInfo: LPWSAPROTOCOL_INFOW): Integer; stdcall; +begin + @WSADuplicateSocketW := FixupStub(hWinSockDll, 'WSADuplicateSocketW'); {Do not Localize} + Result := WSADuplicateSocketW(s, dwProcessId, lpProtocolInfo); +end; + +function Stub_WSADuplicateSocket(const s: TSocket; const dwProcessId: DWORD; lpProtocolInfo: LPWSAPROTOCOL_INFO): Integer; stdcall; +begin + {$IFDEF UNICODE} + @WSADuplicateSocket := FixupStub(hWinSockDll, 'WSADuplicateSocketW'); {Do not Localize} + {$ELSE} + @WSADuplicateSocket := FixupStub(hWinSockDll, 'WSADuplicateSocketA'); {Do not Localize} + {$ENDIF} + Result := WSADuplicateSocket(s, dwProcessId, lpProtocolInfo); +end; +{$ENDIF} + +function Stub_WSAEnumNetworkEvents(const s: TSocket; const hEventObject: WSAEVENT; lpNetworkEvents: LPWSANETWORKEVENTS): Integer; stdcall; +begin + @WSAEnumNetworkEvents := FixupStub(hWinSockDll, 'WSAEnumNetworkEvents'); {Do not Localize} + Result := WSAEnumNetworkEvents(s, hEventObject, lpNetworkEvents); +end; + +function Stub_WSAEnumProtocolsA(lpiProtocols: PInteger; lpProtocolBuffer: LPWSAPROTOCOL_INFOA; var lpdwBufferLength: DWORD): Integer; stdcall; +begin + @WSAEnumProtocolsA := FixupStub(hWinSockDll, 'WSAEnumProtocolsA'); {Do not Localize} + Result := WSAEnumProtocolsA(lpiProtocols, lpProtocolBuffer, lpdwBufferLength); +end; + +function Stub_WSAEnumProtocolsW(lpiProtocols: PInteger; lpProtocolBuffer: LPWSAPROTOCOL_INFOW; var lpdwBufferLength: DWORD): Integer; stdcall; +begin + @WSAEnumProtocolsW := FixupStub(hWinSockDll, 'WSAEnumProtocolsW'); {Do not Localize} + Result := WSAEnumProtocolsW(lpiProtocols, lpProtocolBuffer, lpdwBufferLength); +end; + +function Stub_WSAEnumProtocols(lpiProtocols: PInteger; lpProtocolBuffer: LPWSAPROTOCOL_INFO; var lpdwBufferLength: DWORD): Integer; stdcall; +begin + {$IFDEF UNICODE} + @WSAEnumProtocols := FixupStub(hWinSockDll, 'WSAEnumProtocolsW'); {Do not Localize} + {$ELSE} + @WSAEnumProtocols := FixupStub(hWinSockDll, 'WSAEnumProtocolsA'); {Do not Localize} + {$ENDIF} + Result := WSAEnumProtocols(lpiProtocols, lpProtocolBuffer, lpdwBufferLength); +end; + +function Stub_WSAEventSelect(const s: TSocket; const hEventObject: WSAEVENT; lNetworkEvents: LongInt): Integer; stdcall; +begin + @WSAEventSelect := FixupStub(hWinSockDll, 'WSAEventSelect'); {Do not Localize} + Result := WSAEventSelect(s, hEventObject, lNetworkEvents); +end; + +function Stub_WSAGetOverlappedResult(const s: TSocket; AOverlapped: Pointer; lpcbTransfer: LPDWORD; fWait: BOOL; var lpdwFlags: DWORD): WordBool; stdcall; +begin + @WSAGetOverlappedResult := FixupStub(hWinSockDll, 'WSAGetOverlappedResult'); {Do not Localize} + Result := WSAGetOverlappedResult(s, AOverlapped, lpcbTransfer, fWait, lpdwFlags); +end; + +{$IFNDEF WINCE} +function Stub_WSAGetQOSByName(const s: TSocket; lpQOSName: LPWSABUF; lpQOS: LPQOS): WordBool; stdcall; +begin + @WSAGetQOSByName := FixupStub(hWinSockDll, 'WSAGetQOSByName'); {Do not Localize} + Result := WSAGetQOSByName(s, lpQOSName, lpQOS); +end; +{$ENDIF} + +function Stub_WSAHtonl(const s: TSocket; hostlong: u_long; var lpnetlong: DWORD): Integer; stdcall; +begin + @WSAHtonl := FixupStub(hWinSockDll, 'WSAHtonl'); {Do not Localize} + Result := WSAHtonl(s, hostlong, lpnetlong); +end; + +function Stub_WSAHtons(const s: TSocket; hostshort: u_short; var lpnetshort: WORD): Integer; stdcall; +begin + @WSAHtons := FixupStub(hWinSockDll, 'WSAHtons'); {Do not Localize} + Result := WSAHtons(s, hostshort, lpnetshort); +end; + +function Stub_WSAIoctl(const s: TSocket; dwIoControlCode: DWORD; lpvInBuffer: Pointer; cbInBuffer: DWORD; lpvOutBuffer: Pointer; cbOutBuffer: DWORD; lpcbBytesReturned: LPDWORD; AOverlapped: Pointer; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; +begin + @WSAIoctl := FixupStub(hWinSockDll, 'WSAIoctl'); {Do not Localize} + Result := WSAIoctl(s, dwIoControlCode, lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, AOverlapped, lpCompletionRoutine); +end; + +function Stub_WSAJoinLeaf(const s: TSocket; name: PSockAddr; namelen: Integer; lpCallerData, lpCalleeData: LPWSABUF; lpSQOS, lpGQOS: LPQOS; dwFlags: DWORD): TSocket; stdcall; +begin + @WSAJoinLeaf := FixupStub(hWinSockDll, 'WSAJoinLeaf'); {Do not Localize} + Result := WSAJoinLeaf(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, dwFlags); +end; + +function Stub_WSANtohl(const s: TSocket; netlong: u_long; var lphostlong: DWORD): Integer; stdcall; +begin + @WSANtohl := FixupStub(hWinSockDll, 'WSANtohl'); {Do not Localize} + Result := WSANtohl(s, netlong, lphostlong); +end; + +function Stub_WSANtohs(const s: TSocket; netshort: u_short; var lphostshort: WORD): Integer; stdcall; +begin + @WSANtohs := FixupStub(hWinSockDll, 'WSANtohs'); {Do not Localize} + Result := WSANtohs(s, netshort, lphostshort); +end; + +function Stub_WSARecv(const s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD; var lpNumberOfBytesRecvd: DWORD; var lpFlags: DWORD; AOverlapped: LPWSAOVERLAPPED; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; +begin + @WSARecv := FixupStub(hWinSockDll, 'WSARecv'); {Do not Localize} + Result := WSARecv(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, AOverlapped, lpCompletionRoutine); +end; + +function Stub_WSARecvDisconnect(const s: TSocket; lpInboundDisconnectData: LPWSABUF): Integer; stdcall; +begin + @WSARecvDisconnect := FixupStub(hWinSockDll, 'WSARecvDisconnect'); {Do not Localize} + Result := WSARecvDisconnect(s, lpInboundDisconnectData); +end; + +function Stub_WSARecvFrom(const s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD; var lpNumberOfBytesRecvd: DWORD; var lpFlags: DWORD; lpFrom: PSockAddr; lpFromlen: PInteger; AOverlapped: Pointer; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; +begin + @WSARecvFrom := FixupStub(hWinSockDll, 'WSARecvFrom'); {Do not Localize} + Result := WSARecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpFrom, lpFromlen, AOverlapped, lpCompletionRoutine); +end; + +function Stub_WSAResetEvent(hEvent: wsaevent): WordBool; stdcall; +begin + @WSAResetEvent := FixupStub(hWinSockDll, 'WSAResetEvent'); {Do not Localize} + Result := WSAResetEvent(hEvent); +end; + +function Stub_WSASend(const s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD; var lpNumberOfBytesSent: DWORD; dwFlags: DWORD; AOverlapped: LPWSAOVERLAPPED; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; +begin + @WSASend := FixupStub(hWinSockDll, 'WSASend'); {Do not Localize} + Result := WSASend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, AOverlapped, lpCompletionRoutine); +end; + +{$IFNDEF WINCE} +function Stub_WSASendDisconnect(const s: TSocket; lpOutboundDisconnectData: LPWSABUF): Integer; stdcall; +begin + @WSASendDisconnect := FixupStub(hWinSockDll, 'WSASendDisconnect'); {Do not Localize} + Result := WSASendDisconnect(s, lpOutboundDisconnectData); +end; +{$ENDIF} + +function Stub_WSASendTo(const s: TSocket; lpBuffers: LPWSABUF; dwBufferCount: DWORD; var lpNumberOfBytesSent: DWORD; dwFlags: DWORD; lpTo: PSOCKADDR; iTolen: Integer; AOverlapped: LPWSAOVERLAPPED; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; +begin + @WSASendTo := FixupStub(hWinSockDll, 'WSASendTo'); {Do not Localize} + Result := WSASendTo(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpTo, iTolen, AOverlapped, lpCompletionRoutine); +end; + +function Stub_WSASetEvent(hEvent: WSAEVENT): WordBool; stdcall; +begin + @WSASetEvent := FixupStub(hWinSockDll, 'WSASetEvent'); {Do not Localize} + Result := WSASetEvent(hEvent); +end; + +function Stub_WSASocketA(af, iType, protocol: Integer; lpProtocolInfo: LPWSAPROTOCOL_INFOA; g: GROUP; dwFlags: DWORD): TSocket; stdcall; +begin + @WSASocketA := FixupStub(hWinSockDll, 'WSASocketA'); {Do not Localize} + Result := WSASocketA(af, iType, protocol, lpProtocolInfo, g, dwFlags); +end; + +function Stub_WSASocketW(af, iType, protocol: Integer; lpProtocolInfo: LPWSAPROTOCOL_INFOW; g: GROUP; dwFlags: DWORD): TSocket; stdcall; +begin + @WSASocketW := FixupStub(hWinSockDll, 'WSASocketW'); {Do not Localize} + Result := WSASocketW(af, iType, protocol, lpProtocolInfo, g, dwFlags); +end; + +function Stub_WSASocket(af, iType, protocol: Integer; lpProtocolInfo: LPWSAPROTOCOL_INFO; g: GROUP; dwFlags: DWORD): TSocket; stdcall; +begin + {$IFDEF UNICODE} + @WSASocket := FixupStub(hWinSockDll, 'WSASocketW'); {Do not Localize} + {$ELSE} + @WSASocket := FixupStub(hWinSockDll, 'WSASocketA'); {Do not Localize} + {$ENDIF} + Result := WSASocket(af, iType, protocol, lpProtocolInfo, g, dwFlags); +end; + +function Stub_WSAWaitForMultipleEvents(cEvents: DWORD; lphEvents: Pwsaevent; fWaitAll: LongBool; dwTimeout: DWORD; fAlertable: LongBool): DWORD; stdcall; +begin + @WSAWaitForMultipleEvents := FixupStub(hWinSockDll, 'WSAWaitForMultipleEvents'); {Do not Localize} + Result := WSAWaitForMultipleEvents(cEvents, lphEvents, fWaitAll, dwTimeout, fAlertable); +end; + +function Stub_WSAAddressToStringA(lpsaAddress: PSockAddr; const dwAddressLength: DWORD; const lpProtocolInfo: LPWSAPROTOCOL_INFOA; const lpszAddressString: PIdAnsiChar; var lpdwAddressStringLength: DWORD): Integer; stdcall; +begin + @WSAAddressToStringA := FixupStub(hWinSockDll, 'WSAAddressToStringA'); {Do not Localize} + Result := WSAAddressToStringA(lpsaAddress, dwAddressLength, lpProtocolInfo, lpszAddressString, lpdwAddressStringLength); +end; + +function Stub_WSAAddressToStringW(lpsaAddress: PSockAddr; const dwAddressLength: DWORD; const lpProtocolInfo: LPWSAPROTOCOL_INFOW; const lpszAddressString: PWideChar; var lpdwAddressStringLength: DWORD): Integer; stdcall; +begin + @WSAAddressToStringW := FixupStub(hWinSockDll, 'WSAAddressToStringW'); {Do not Localize} + Result := WSAAddressToStringW(lpsaAddress, dwAddressLength, lpProtocolInfo, lpszAddressString, lpdwAddressStringLength); +end; + +function Stub_WSAAddressToString(lpsaAddress: PSockAddr; const dwAddressLength: DWORD; const lpProtocolInfo: LPWSAPROTOCOL_INFO; + const lpszAddressString: PIdPlatformChar; var lpdwAddressStringLength: DWORD): Integer; stdcall; +begin + {$IFDEF UNICODE} + @WSAAddressToString := FixupStub(hWinSockDll, 'WSAAddressToStringW'); {Do not Localize} + {$ELSE} + @WSAAddressToString := FixupStub(hWinSockDll, 'WSAAddressToStringA'); {Do not Localize} + {$ENDIF} + Result := WSAAddressToString(lpsaAddress, dwAddressLength, lpProtocolInfo, lpszAddressString, lpdwAddressStringLength); +end; + +function Stub_WSAStringToAddressA(const AddressString: PIdAnsiChar; const AddressFamily: Integer; const lpProtocolInfo: LPWSAPROTOCOL_INFOA; var lpAddress: TSockAddr; var lpAddressLength: Integer): Integer; stdcall; +begin + @WSAStringToAddressA := FixupStub(hWinSockDll, 'WSAStringToAddressA'); {Do not Localize} + Result := WSAStringToAddressA(AddressString, AddressFamily, lpProtocolInfo, lpAddress, lpAddressLength); +end; + +function Stub_WSAStringToAddressW(const AddressString: PWideChar; const AddressFamily: Integer; const lpProtocolInfo: LPWSAPROTOCOL_INFOW; var lpAddress: TSockAddr; var lpAddressLength: Integer): Integer; stdcall; +begin + @WSAStringToAddressW := FixupStub(hWinSockDll, 'WSAStringToAddressW'); {Do not Localize} + Result := WSAStringToAddressW(AddressString, AddressFamily, lpProtocolInfo, lpAddress, lpAddressLength); +end; + +function Stub_WSAStringToAddress (const AddressString: PIdPlatformChar; + const AddressFamily: Integer; const lpProtocolInfo: LPWSAProtocol_Info; + var lpAddress: TSockAddr; var lpAddressLength: Integer): Integer; stdcall; +begin + {$IFDEF UNICODE} + @WSAStringToAddress := FixupStub(hWinSockDll, 'WSAStringToAddressW'); {Do not Localize} + {$ELSE} + @WSAStringToAddress := FixupStub(hWinSockDll, 'WSAStringToAddressA'); {Do not Localize} + {$ENDIF} + Result := WSAStringToAddress(AddressString, AddressFamily, lpProtocolInfo, lpAddress, lpAddressLength); +end; + +function Stub_WSALookupServiceBeginA(var qsRestrictions: TWSAQuerySetA; const dwControlFlags: DWORD; var hLookup: THandle): Integer; stdcall; +begin + @WSALookupServiceBeginA := FixupStub(hWinSockDll, 'WSALookupServiceBeginA'); {Do not Localize} + Result := WSALookupServiceBeginA(qsRestrictions, dwControlFlags, hLookup); +end; + +function Stub_WSALookupServiceBeginW(var qsRestrictions: TWSAQuerySetW; const dwControlFlags: DWORD; var hLookup: THandle): Integer; stdcall; +begin + @WSALookupServiceBeginW := FixupStub(hWinSockDll, 'WSALookupServiceBeginW'); {Do not Localize} + Result := WSALookupServiceBeginW(qsRestrictions, dwControlFlags, hLookup); +end; + +function Stub_WSALookupServiceBegin(var qsRestrictions: TWSAQuerySet; const dwControlFlags: DWORD; var hLookup: THandle): Integer; stdcall; +begin + {$IFDEF UNICODE} + @WSALookupServiceBegin := FixupStub(hWinSockDll, 'WSALookupServiceBeginW'); {Do not Localize} + {$ELSE} + @WSALookupServiceBegin := FixupStub(hWinSockDll, 'WSALookupServiceBeginA'); {Do not Localize} + {$ENDIF} + Result := WSALookupServiceBegin(qsRestrictions, dwControlFlags, hLookup); +end; + +function Stub_WSALookupServiceNextA(const hLookup: THandle; const dwControlFlags: DWORD; var dwBufferLength: DWORD; lpqsResults: LPWSAQUERYSETA): Integer; stdcall; +begin + @WSALookupServiceNextA := FixupStub(hWinSockDll, 'WSALookupServiceNextA'); {Do not Localize} + Result := WSALookupServiceNextA(hLookup, dwControlFlags, dwBufferLength, lpqsResults); +end; + +function Stub_WSALookupServiceNextW(const hLookup: THandle; const dwControlFlags: DWORD; var dwBufferLength: DWORD; lpqsResults: LPWSAQUERYSETW): Integer; stdcall; +begin + @WSALookupServiceNextW := FixupStub(hWinSockDll, 'WSALookupServiceNextW'); {Do not Localize} + Result := WSALookupServiceNextW(hLookup, dwControlFlags, dwBufferLength, lpqsResults); +end; + +function Stub_WSALookupServiceNext(const hLookup: THandle; const dwControlFlags: DWORD; var dwBufferLength: DWORD; lpqsResults: LPWSAQUERYSET): Integer; stdcall; +begin + {$IFDEF UNICODE} + @WSALookupServiceNext := FixupStub(hWinSockDll, 'WSALookupServiceNextW'); {Do not Localize} + {$ELSE} + @WSALookupServiceNext := FixupStub(hWinSockDll, 'WSALookupServiceNextA'); {Do not Localize} + {$ENDIF} + Result := WSALookupServiceNext(hLookup, dwControlFlags, dwBufferLength, lpqsResults); +end; + +function Stub_WSALookupServiceEnd(const hLookup: THandle): Integer; stdcall; +begin + @WSALookupServiceEnd := FixupStub(hWinSockDll, 'WSALookupServiceEnd'); {Do not Localize} + Result := WSALookupServiceEnd(hLookup); +end; + + +function Stub_WSANSPIoctl(const hLookup : THANDLE; const dwControlCode : DWORD; + lpvInBuffer : Pointer; var cbInBuffer : DWORD; lpvOutBuffer : Pointer; + var cbOutBuffer : DWORD; var lpcbBytesReturned : DWORD; + lpCompletion : LPWSACOMPLETION) : Integer; stdcall; +begin + @WSANSPIoctl := FixupStub(hWinSockDLL, 'WSANSPIoctl'); {Do not Localize} + Result := WSANSPIoctl(hLookup,dwControlCode,lpvInBuffer,cbInBuffer,lpvOutBuffer, + cbOutBuffer, lpcbBytesReturned,lpCompletion); +end; + +function Stub_WSAInstallServiceClassA(const lpServiceClassInfo: LPWSASERVICECLASSINFOA): Integer; stdcall; +begin + @WSAInstallServiceClassA := FixupStub(hWinSockDll, 'WSAInstallServiceClassA'); {Do not Localize} + Result := WSAInstallServiceClassA(lpServiceClassInfo); +end; + +function Stub_WSAInstallServiceClassW(const lpServiceClassInfo: LPWSASERVICECLASSINFOW): Integer; stdcall; +begin + @WSAInstallServiceClassW := FixupStub(hWinSockDll, 'WSAInstallServiceClassW'); {Do not Localize} + Result := WSAInstallServiceClassW(lpServiceClassInfo); +end; + +function Stub_WSAInstallServiceClass(const lpServiceClassInfo: LPWSASERVICECLASSINFO): Integer; stdcall; +begin + {$IFDEF UNICODE} + @WSAInstallServiceClass := FixupStub(hWinSockDll, 'WSAInstallServiceClassW'); {Do not Localize} + {$ELSE} + @WSAInstallServiceClass := FixupStub(hWinSockDll, 'WSAInstallServiceClassA'); {Do not Localize} + {$ENDIF} + Result := WSAInstallServiceClass(lpServiceClassInfo); +end; + +function Stub_WSARemoveServiceClass(const lpServiceClassId: PGUID): Integer; stdcall; +begin + @WSARemoveServiceClass := FixupStub(hWinSockDll, 'WSARemoveServiceClass'); {Do not Localize} + Result := WSARemoveServiceClass(lpServiceClassId); +end; + +function Stub_WSAGetServiceClassInfoA(const lpProviderId: PGUID; const lpServiceClassId: PGUID; var lpdwBufSize: DWORD; lpServiceClassInfo: LPWSASERVICECLASSINFOA): Integer; stdcall; +begin + @WSAGetServiceClassInfoA := FixupStub(hWinSockDll, 'WSAGetServiceClassInfoA'); {Do not Localize} + Result := WSAGetServiceClassInfoA(lpProviderId, lpServiceClassId, lpdwBufSize, lpServiceClassInfo); +end; + +function Stub_WSAGetServiceClassInfoW(const lpProviderId: PGUID; const lpServiceClassId: PGUID; var lpdwBufSize: DWORD; lpServiceClassInfo: LPWSASERVICECLASSINFOW): Integer; stdcall; +begin + @WSAGetServiceClassInfoW := FixupStub(hWinSockDll, 'WSAGetServiceClassInfoW'); {Do not Localize} + Result := WSAGetServiceClassInfoW(lpProviderId, lpServiceClassId, lpdwBufSize, lpServiceClassInfo); +end; + +function Stub_WSAGetServiceClassInfo(const lpProviderId: PGUID; const lpServiceClassId: PGUID; var lpdwBufSize: DWORD; lpServiceClassInfo: LPWSASERVICECLASSINFO): Integer; stdcall; +begin + {$IFDEF UNICODE} + @WSAGetServiceClassInfo := FixupStub(hWinSockDll, 'WSAGetServiceClassInfoW'); {Do not Localize} + {$ELSE} + @WSAGetServiceClassInfo := FixupStub(hWinSockDll, 'WSAGetServiceClassInfoA'); {Do not Localize} + {$ENDIF} + Result := WSAGetServiceClassInfo(lpProviderId, lpServiceClassId, lpdwBufSize, lpServiceClassInfo); +end; + +function Stub_WSAEnumNameSpaceProvidersA(var lpdwBufferLength: DWORD; const lpnspBuffer: LPWSANAMESPACE_INFOA): Integer; stdcall; +begin + @WSAEnumNameSpaceProvidersA := FixupStub(hWinSockDll, 'WSAEnumNameSpaceProvidersA'); {Do not Localize} + Result := WSAEnumNameSpaceProvidersA(lpdwBufferLength, lpnspBuffer); +end; + +function Stub_WSAEnumNameSpaceProvidersW(var lpdwBufferLength: DWORD; const lpnspBuffer: LPWSANAMESPACE_INFOW): Integer; stdcall; +begin + @WSAEnumNameSpaceProvidersW := FixupStub(hWinSockDll, 'WSAEnumNameSpaceProvidersW'); {Do not Localize} + Result := WSAEnumNameSpaceProvidersW(lpdwBufferLength, lpnspBuffer); +end; + +function Stub_WSAEnumNameSpaceProviders(var lpdwBufferLength: DWORD; const lpnspBuffer: LPWSANAMESPACE_INFO): Integer; stdcall; +begin + {$IFDEF UNICODE} + @WSAEnumNameSpaceProviders := FixupStub(hWinSockDll, 'WSAEnumNameSpaceProvidersW'); {Do not Localize} + {$ELSE} + @WSAEnumNameSpaceProviders := FixupStub(hWinSockDll, 'WSAEnumNameSpaceProvidersA'); {Do not Localize} + {$ENDIF} + Result := WSAEnumNameSpaceProviders(lpdwBufferLength, lpnspBuffer); +end; + +function Stub_WSAGetServiceClassNameByClassIdA(const lpServiceClassId: PGUID; lpszServiceClassName: PIdAnsiChar; var lpdwBufferLength: DWORD): Integer; stdcall; +begin + @WSAGetServiceClassNameByClassIdA := FixupStub(hWinSockDll, 'WSAGetServiceClassNameByClassIdA'); {Do not Localize} + Result := WSAGetServiceClassNameByClassIdA(lpServiceClassId, lpszServiceClassName, lpdwBufferLength); +end; + +function Stub_WSAGetServiceClassNameByClassIdW(const lpServiceClassId: PGUID; lpszServiceClassName: PWideChar; var lpdwBufferLength: DWORD): Integer; stdcall; +begin + @WSAGetServiceClassNameByClassIdW := FixupStub(hWinSockDll, 'WSAGetServiceClassNameByClassIdW'); {Do not Localize} + Result := WSAGetServiceClassNameByClassIdW(lpServiceClassId, lpszServiceClassName, lpdwBufferLength); +end; + +function Stub_WSAGetServiceClassNameByClassId(const lpServiceClassId: PGUID; + lpszServiceClassName: PIdPlatformChar; var lpdwBufferLength: DWORD): Integer; stdcall; +begin + {$IFDEF UNICODE} + @WSAGetServiceClassNameByClassId := FixupStub(hWinSockDll, 'WSAGetServiceClassNameByClassIdW'); {Do not Localize} + {$ELSE} + @WSAGetServiceClassNameByClassId := FixupStub(hWinSockDll, 'WSAGetServiceClassNameByClassIdA'); {Do not Localize} + {$ENDIF} + Result := WSAGetServiceClassNameByClassId(lpServiceClassId, lpszServiceClassName, lpdwBufferLength); +end; + +function Stub_WSASetServiceA(const lpqsRegInfo: LPWSAQUERYSETA; const essoperation: WSAESETSERVICEOP; const dwControlFlags: DWORD): Integer; stdcall; +begin + @WSASetServiceA := FixupStub(hWinSockDll, 'WSASetServiceA'); {Do not Localize} + Result := WSASetServiceA(lpqsRegInfo, essoperation, dwControlFlags); +end; + +function Stub_WSASetServiceW(const lpqsRegInfo: LPWSAQUERYSETW; const essoperation: WSAESETSERVICEOP; const dwControlFlags: DWORD): Integer; stdcall; +begin + @WSASetServiceW := FixupStub(hWinSockDll, 'WSASetServiceW'); {Do not Localize} + Result := WSASetServiceW(lpqsRegInfo, essoperation, dwControlFlags); +end; + +function Stub_WSASetService(const lpqsRegInfo: LPWSAQUERYSET; const essoperation: WSAESETSERVICEOP; const dwControlFlags: DWORD): Integer; stdcall; +begin + {$IFDEF UNICODE} + @WSASetService := FixupStub(hWinSockDll, 'WSASetServiceW'); {Do not Localize} + {$ELSE} + @WSASetService := FixupStub(hWinSockDll, 'WSASetServiceA'); {Do not Localize} + {$ENDIF} + Result := WSASetService(lpqsRegInfo, essoperation, dwControlFlags); +end; + +function Stub_WSAProviderConfigChange(var lpNotificationHandle: THandle; AOverlapped: LPWSAOVERLAPPED; lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; +begin + @WSAProviderConfigChange := FixupStub(hWinSockDll, 'WSAProviderConfigChange'); {Do not Localize} + Result := WSAProviderConfigChange(lpNotificationHandle, AOverlapped, lpCompletionRoutine); +end; + +function Stub_TransmitFile(hSocket: TSocket; hFile: THandle; nNumberOfBytesToWrite: DWORD; + nNumberOfBytesPerSend: DWORD; lpOverlapped: POverlapped; + lpTransmitBuffers: LPTRANSMIT_FILE_BUFFERS; dwReserved: DWORD): BOOL; stdcall; +begin + @TransmitFile := FixupStubEx(hSocket, 'TransmitFile', WSAID_TRANSMITFILE); {Do not localize} + Result := TransmitFile(hSocket, hFile, nNumberOfBytesToWrite, nNumberOfBytesPerSend, lpOverlapped, lpTransmitBuffers, dwReserved); +end; + +{RLebeau 1/26/2006 - loading GetAcceptExSockaddrs() at the same time as AcceptEx(). +This is because GetAcceptExSockaddrs() is not passed a SOCKET that can be passed to +WSAIoCtrl() to get the function pointer. Also, GetAcceptExSockaddrs() is needed to +parse AcceptEx()'s return data, so there is no point in calling AcceptEx() unless +its data can be parsed afterwards.} +function Stub_AcceptEx(sListenSocket, sAcceptSocket: TSocket; + lpOutputBuffer: Pointer; dwReceiveDataLength, dwLocalAddressLength, + dwRemoteAddressLength: DWORD; var lpdwBytesReceived: DWORD; + lpOverlapped: POverlapped): BOOL; stdcall; +begin + {RLebeau - loading GetAcceptExSockaddrs() first in case it fails} + @GetAcceptExSockaddrs := FixupStubEx(sListenSocket, 'GetAcceptExSockaddrs', WSAID_GETACCEPTEXSOCKADDRS); {Do not localize} + @AcceptEx := FixupStubEx(sListenSocket, 'AcceptEx', WSAID_ACCEPTEX); {Do not localize} + Result := AcceptEx(sListenSocket, sAcceptSocket, lpOutputBuffer, dwReceiveDataLength, + dwLocalAddressLength, dwRemoteAddressLength, lpdwBytesReceived, lpOverlapped); +end; + +{$IFNDEF WINCE} +function Stub_WSARecvEx(s: TSocket; var buf; len: Integer; var flags: Integer): Integer; stdcall; +begin + LoadMSWSock; + @WSARecvEx := FixupStub(hMSWSockDll, 'WSARecvEx'); {Do not localize} + Result := WSARecvEx(s, buf, len, flags); +end; +{$ENDIF} + +function Stub_ConnectEx(const s : TSocket; const name: PSockAddr; const namelen: Integer; lpSendBuffer : Pointer; + dwSendDataLength : DWORD; var lpdwBytesSent : DWORD; lpOverlapped : LPWSAOVERLAPPED) : BOOL; stdcall; +begin + @ConnectEx := FixupStubEx(s, 'ConnectEx', WSAID_CONNECTEX); {Do not localize} + Result := ConnectEx(s, name, namelen, lpSendBuffer, dwSendDataLength, lpdwBytesSent, lpOverlapped); +end; + +function Stub_DisconnectEx(const s : TSocket; AOverlapped: Pointer; const dwFlags : DWord; const dwReserved : DWORD) : BOOL; stdcall; +begin + @DisconnectEx := FixupStubEx(s, 'DisconnectEx', WSAID_DISCONNECTEX); {Do not localize} + Result := DisconnectEx(s, AOverlapped, dwFlags, dwReserved); +end; + +function Stub_WSARecvMsg(const s : TSocket; lpMsg : LPWSAMSG; var lpNumberOfBytesRecvd : DWORD; AOverlapped: Pointer; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; +begin + @WSARecvMsg := FixupStubEx(s, 'WSARecvMsg', WSAID_WSARECVMSG); {Do not localize} + Result := WSARecvMsg(s, lpMsg, lpNumberOfBytesRecvd, AOverlapped, lpCompletionRoutine); +end; + +function Stub_TransmitPackets(s: TSocket; lpPacketArray: LPTRANSMIT_PACKETS_ELEMENT; + nElementCount: DWORD; nSendSize: DWORD; lpOverlapped: LPWSAOVERLAPPED; dwFlags: DWORD): BOOL; stdcall; +begin + @TransmitPackets := FixupStubEx(s, 'TransmitPackets', WSAID_TRANSMITPACKETS); {Do not localize} + Result := TransmitPackets(s, lpPacketArray, nElementCount, nSendSize, lpOverlapped, dwFlags); +end; + +{$IFNDEF WINCE} +function Stub_WSASendMsg(const s : TSocket; lpMsg : LPWSAMSG; const dwFlags : DWORD; var lpNumberOfBytesSent : DWORD; lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; +begin + @WSASendMsg := FixupStubEx(s, 'WSASendMsg', WSAID_WSASENDMSG); {Do not localize} + Result := WSASendMsg(s, lpMsg, dwFlags, lpNumberOfBytesSent, lpOverlapped, lpCompletionRoutine); +end; + +function Stub_WSAPoll(fdarray : LPWSAPOLLFD; const nfds : u_long; const timeout : Integer) : Integer; stdcall; +begin + @WSAPoll := FixupStubEx(fdarray.fd, 'WSAPoll', WSAID_WSAPOLL); {Do not localize} + Result := WSAPoll(fdarray, nfds, timeout); +end; +{$ENDIF} + +procedure InitializeStubs; +{Alphabetize these so we can more easily determine what's available on a platform. +by section in Winsock SDK reference} +begin + accept := Stub_accept; + bind := Stub_bind; + closesocket := Stub_closesocket; + connect := Stub_connect; + ioctlsocket := Stub_ioctlsocket; + getpeername := Stub_getpeername; + getsockname := Stub_getsockname; + getsockopt := Stub_getsockopt; + htonl := Stub_htonl; + htons := Stub_htons; + inet_addr := Stub_inet_addr; + inet_ntoa := Stub_inet_ntoa; + listen := Stub_listen; + ntohl := Stub_ntohl; + ntohs := Stub_ntohs; + recv := Stub_recv; + recvfrom := Stub_recvfrom; + select := Stub_select; + send := Stub_send; + sendto := Stub_sendto; + {$IFDEF WINCE} + sethostname := Stub_sethostname; + {$ENDIF} + setsockopt := Stub_setsockopt; + shutdown := Stub_shutdown; + socket := Stub_socket; + gethostbyaddr := Stub_gethostbyaddr; + gethostbyname := Stub_gethostbyname; + gethostname := Stub_gethostname; + getservbyport := Stub_getservbyport; + getservbyname := Stub_getservbyname; + getprotobynumber := Stub_getprotobynumber; + getprotobyname := Stub_getprotobyname; + //extensions + __WSAFDIsSet := Stub___WSAFDIsSet; + {$IFNDEF WINCE} + AcceptEx := Stub_AcceptEx; + //GetAcceptExSockaddrs is loaded by Stub_AcceptEx + ConnectEx := Stub_ConnectEx; + DisconnectEx := Stub_DisconnectEx; + TransmitFile := Stub_TransmitFile; + TransmitPackets := Stub_TransmitPackets; + {$ENDIF} + WSAAccept := Stub_WSAAccept; + {$IFNDEF WINCE} + WSACancelAsyncRequest := Stub_WSACancelAsyncRequest; + WSAAsyncGetHostByAddr := Stub_WSAAsyncGetHostByAddr; + WSAAsyncGetHostByName := Stub_WSAAsyncGetHostByName; + WSAAsyncGetProtoByName := Stub_WSAAsyncGetProtoByName; + WSAAsyncGetProtoByNumber := Stub_WSAAsyncGetProtoByNumber; + WSAAsyncGetServByName := Stub_WSAAsyncGetServByName; + WSAAsyncGetServByPort := Stub_WSAAsyncGetServByPort; + WSAAsyncSelect := Stub_WSAAsyncSelect; + {$ENDIF} + WSAAddressToStringA := Stub_WSAAddressToStringA; + WSAAddressToStringW := Stub_WSAAddressToStringW; + WSAAddressToString := Stub_WSAAddressToString; + {$IFNDEF WINCE} + WSACancelBlockingCall := Stub_WSACancelBlockingCall; + {$ENDIF} + WSACleanup := Stub_WSACleanup; + WSACloseEvent := Stub_WSACloseEvent; + WSAConnect := Stub_WSAConnect; + WSACreateEvent := Stub_WSACreateEvent; + {$IFNDEF WINCE} + WSADuplicateSocketA := Stub_WSADuplicateSocketA; + WSADuplicateSocketW := Stub_WSADuplicateSocketW; + WSADuplicateSocket := Stub_WSADuplicateSocket; + {$ENDIF} + WSAEnumNameSpaceProvidersA := Stub_WSAEnumNameSpaceProvidersA; + WSAEnumNameSpaceProvidersW := Stub_WSAEnumNameSpaceProvidersW; + WSAEnumNameSpaceProviders := Stub_WSAEnumNameSpaceProviders; + WSAEnumNetworkEvents := Stub_WSAEnumNetworkEvents; + WSAEnumProtocolsA := Stub_WSAEnumProtocolsA; + WSAEnumProtocolsW := Stub_WSAEnumProtocolsW; + WSAEnumProtocols := Stub_WSAEnumProtocols; + WSAEventSelect := Stub_WSAEventSelect; + WSAGetLastError := Stub_WSAGetLastError; + WSAGetOverlappedResult := Stub_WSAGetOverlappedResult; + {$IFNDEF WINCE} + WSAGetQOSByName := Stub_WSAGetQOSByName; + WSAGetServiceClassInfoA := Stub_WSAGetServiceClassInfoA; + WSAGetServiceClassInfoW := Stub_WSAGetServiceClassInfoW; + WSAGetServiceClassInfo := Stub_WSAGetServiceClassInfo; + WSAGetServiceClassNameByClassIdA := Stub_WSAGetServiceClassNameByClassIdA; + WSAGetServiceClassNameByClassIdW := Stub_WSAGetServiceClassNameByClassIdW; + WSAGetServiceClassNameByClassId := Stub_WSAGetServiceClassNameByClassId; + {$ENDIF} + WSAHtonl := Stub_WSAHtonl; + WSAHtons := Stub_WSAHtons; + {$IFNDEF WINCE} + WSAInstallServiceClassA := Stub_WSAInstallServiceClassA; + WSAInstallServiceClassW := Stub_WSAInstallServiceClassW; + WSAInstallServiceClass := Stub_WSAInstallServiceClass; + {$ENDIF} + WSAIoctl := Stub_WSAIoctl; + {$IFNDEF WINCE} + WSAIsBlocking := Stub_WSAIsBlocking; + {$ENDIF} + WSAJoinLeaf := Stub_WSAJoinLeaf; + WSALookupServiceBeginA := Stub_WSALookupServiceBeginA; + WSALookupServiceBeginW := Stub_WSALookupServiceBeginW; + WSALookupServiceBegin := Stub_WSALookupServiceBegin; + WSALookupServiceEnd := Stub_WSALookupServiceEnd; + WSALookupServiceNextA := Stub_WSALookupServiceNextA; + WSALookupServiceNextW := Stub_WSALookupServiceNextW; + WSALookupServiceNext := Stub_WSALookupServiceNext; + + // WSANSPIoctl is not supported in WinCE 4.20 but is in later versions. + WSANSPIoctl := Stub_WSANSPIoctl; + + WSANtohl := Stub_WSANtohl; + WSANtohs := Stub_WSANtohs; + {$IFNDEF WINCE} + WSAPoll := Stub_WSAPoll; + WSAProviderConfigChange := Stub_WSAProviderConfigChange; + {$ENDIF} + WSARecv := Stub_WSARecv; + {$IFNDEF WINCE} + WSARecvDisconnect := Stub_WSARecvDisconnect; + WSARecvEx := Stub_WSARecvEx; + {$ENDIF} + WSARecvFrom := Stub_WSARecvFrom; + WSARecvMsg := Stub_WSARecvMsg; + WSARemoveServiceClass := Stub_WSARemoveServiceClass; + WSAResetEvent := Stub_WSAResetEvent; + WSASend := Stub_WSASend; + {$IFNDEF WINCE} + WSASendDisconnect := Stub_WSASendDisconnect; + WSASendMsg := Stub_WSASendMsg; + {$ENDIF} + WSASendTo := Stub_WSASendTo; + {$IFNDEF WINCE} + WSASetBlockingHook := Stub_WSASetBlockingHook; + {$ENDIF} + WSASetEvent := Stub_WSASetEvent; + WSASetLastError := Stub_WSASetLastError; + WSASetServiceA := Stub_WSASetServiceA; + WSASetServiceW := Stub_WSASetServiceW; + WSASetService := Stub_WSASetService; + WSASocketA := Stub_WSASocketA; + WSASocketW := Stub_WSASocketW; + WSASocket := Stub_WSASocket; + WSAStartup := Stub_WSAStartup; + WSAStringToAddressA := Stub_WSAStringToAddressA; + WSAStringToAddressW := Stub_WSAStringToAddressW; + WSAStringToAddress := Stub_WSAStringToAddress; + {$IFNDEF WINCE} + WSAUnhookBlockingHook := Stub_WSAUnhookBlockingHook; + {$ENDIF} + WSAWaitForMultipleEvents := Stub_WSAWaitForMultipleEvents; +end; + +function WSAMakeSyncReply(Buflen, AError: Word): Longint; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := MakeLong(Buflen, AError); +end; + +function WSAMakeSelectReply(Event, AError: Word): Longint; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := MakeLong(Event, AError); +end; + +function WSAGetAsyncBuflen(Param: LPARAM): Word; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := LOWORD(Param); +end; + +function WSAGetAsyncError(Param: LPARAM): Word; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := HIWORD(Param); +end; + +function WSAGetSelectEvent(Param: LPARAM): Word; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := LOWORD(Param); +end; + +function WSAGetSelectError(Param: LPARAM): Word; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + WSAGetSelectError := HIWORD(Param); +end; + +procedure FD_CLR(ASocket: TSocket; var FDSet: TFDSet); +var + i: u_int; +begin + i := 0; + while i < FDSet.fd_count do + begin + if FDSet.fd_array[i] = ASocket then + begin + while i < FDSet.fd_count - 1 do + begin + FDSet.fd_array[i] := FDSet.fd_array[i+1]; + Inc(i); + end; + Dec(FDSet.fd_count); + Break; + end; + Inc(i); + end; +end; + +function FD_ISSET(ASocket: TSocket; var FDSet: TFDSet): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := __WSAFDIsSet(ASocket, FDSet); +end; + +procedure FD_SET(ASocket: TSocket; var FDSet: TFDSet); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if FDSet.fd_count < fd_setsize then + begin + FDSet.fd_array[FDSet.fd_count] := ASocket; + Inc(FDSet.fd_count); + end; +end; + +procedure FD_ZERO(var FDSet: TFDSet); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + FDSet.fd_count := 0; +end; + +{$IFNDEF WINCE} + +//Posix aliases +// #define CMSGHDR_ALIGN WSA_CMSGHDR_ALIGN +function CMSGHDR_ALIGN(const Alength: SIZE_T): SIZE_T; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := WSA_CMSGHDR_ALIGN(Alength); +end; + +// #define CMSGDATA_ALIGN WSA_CMSGDATA_ALIGN +function CMSGDATA_ALIGN(const Alength: PtrUInt): PtrUInt; + {$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := WSA_CMSGDATA_ALIGN(Alength); +end; + +//#define CMSG_FIRSTHDR WSA_CMSG_FIRSTHDR +function CMSG_FIRSTHDR(const msg: LPWSAMSG): LPWSACMSGHDR; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := WSA_CMSG_FIRSTHDR(msg); +end; + +// #define CMSG_NXTHDR WSA_CMSG_NXTHDR +function CMSG_NXTHDR(const msg: LPWSAMSG; const cmsg: LPWSACMSGHDR): LPWSACMSGHDR; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := WSA_CMSG_NXTHDR(msg, cmsg); +end; + +// #define CMSG_SPACE WSA_CMSG_SPACE +function CMSG_SPACE(const Alength: PtrUInt): PtrUInt; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := WSA_CMSG_SPACE(ALength); +end; + +// #define CMSG_LEN WSA_CMSG_LEN +function CMSG_LEN(const Alength: SIZE_T): SIZE_T; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := WSA_CMSG_LEN(ALength); +end; + +// +function WSA_CMSGHDR_ALIGN(const Alength: SIZE_T): SIZE_T; +type + {$IFDEF WIN32} + {$ALIGN ON} + TempRec = record + x: TIdAnsiChar; + test: WSACMSGHDR; + end; + {$ALIGN OFF} + {$ELSE} + //Win64 and WinCE seem to require alignment for API records + TempRec = record + x: TIdAnsiChar; + test: WSACMSGHDR; + end; + {$ENDIF} +var + Alignment: SIZE_T; + Tmp: ^TempRec; +begin + Tmp := nil; + Alignment := PtrUInt(@(Tmp^.test)); + Result := (Alength + (Alignment-1)) and not (Alignment-1); +end; + +function WSA_CMSGDATA_ALIGN(const Alength: PtrUInt): PtrUInt; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := (Alength + MAX_NATURAL_ALIGNMENT_SUB_1) and not (MAX_NATURAL_ALIGNMENT_SUB_1); +end; + +function WSA_CMSG_FIRSTHDR(const msg: LPWSAMSG): LPWSACMSGHDR; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (msg <> nil) and (msg^.Control.len >= SIZE_WSACMSGHDR) then begin + Result := LPWSACMSGHDR(msg^.Control.buf); + end else begin + Result := nil; + end; +end; + +function WSA_CMSG_NXTHDR(const msg: LPWSAMSG; const cmsg: LPWSACMSGHDR): LPWSACMSGHDR; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if cmsg = nil then begin + Result := WSA_CMSG_FIRSTHDR(msg); + end else begin + if (PtrUInt(cmsg) + WSA_CMSGHDR_ALIGN(cmsg^.cmsg_len) + SIZE_WSACMSGHDR) > (PtrUInt(msg^.Control.buf) + msg^.Control.len) then begin + Result := nil; + end else begin + Result := LPWSACMSGHDR(PtrUInt(cmsg) + WSA_CMSGHDR_ALIGN(cmsg^.cmsg_len)); + end; + end; +end; + +function WSA_CMSG_DATA(const cmsg: LPWSACMSGHDR): PByte; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := PByte(PtrUInt(cmsg) + WSA_CMSGDATA_ALIGN(SIZE_WSACMSGHDR)); +end; + +function WSA_CMSG_SPACE(const Alength: PtrUInt): PtrUInt; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := WSA_CMSGDATA_ALIGN(PtrUInt(SIZE_WSACMSGHDR + WSA_CMSGHDR_ALIGN(Alength))); +end; + +function WSA_CMSG_LEN(const Alength: SIZE_T): SIZE_T; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := (WSA_CMSGDATA_ALIGN(SizeOf(WSACMSGHDR)) + Alength); +end; + +function RIO_CMSG_BASE_SIZE : SIZE_T; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := WSA_CMSGHDR_ALIGN(sizeof(RIO_CMSG_BUFFER)); +end; + +function RIO_CMSG_FIRSTHDR(buffer : PRIO_CMSG_BUFFER) : PWSACMSGHDR; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if ((buffer)^.TotalLength >= RIO_CMSG_BASE_SIZE) then + begin + if (((buffer)^.TotalLength - RIO_CMSG_BASE_SIZE) >= sizeof(WSACMSGHDR)) then begin + Result := PWSACMSGHDR((PIdAnsiChar(buffer)) + RIO_CMSG_BASE_SIZE); + end else begin + Result := PWSACMSGHDR(nil); + end; + end else begin + Result := PWSACMSGHDR(nil); + end; +end; + +function RIO_CMSG_NEXTHDR(buffer : PRIO_CMSG_BUFFER; cmsg : PWSACMSGHDR) : PWSACMSGHDR; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if ((cmsg) = nil) then begin + Result := RIO_CMSG_FIRSTHDR(buffer); + end else begin + if (PIdAnsiChar(cmsg) + WSA_CMSGHDR_ALIGN((cmsg^.cmsg_len) + sizeof(WSACMSGHDR)) > (PIdAnsiChar(buffer) + (buffer)^.TotalLength)) then begin + Result := (PWSACMSGHDR(nil)); + end else begin + Result :=(PWSACMSGHDR(PIdAnsiChar(cmsg) + WSA_CMSGHDR_ALIGN(cmsg^.cmsg_len))); + end; + end; +end; + +{$ENDIF} // {$IFNDEF WINCE} + +function IP_MSFILTER_SIZE(const numsrc: DWORD): PtrUInt; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := SIZE_IP_MSFILTER - SIZE_TINADDR + (numsrc*SIZE_TINADDR); +end; + +function SS_PORT(ssp: PSockAddrIn): u_short; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if ssp <> nil then begin + Result := ssp^.sin_port; + end else begin + Result := 0; + end; +end; + +// +// Microsoft-specific IPv4 definitions. +// +function IN4_CLASSA(const i : UInt32) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := ((i and $00000080) = 0); +end; + +function IN4_CLASSB(const i : UInt32) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := ((i and $000000c0) = $00000080); +end; + +function IN4_CLASSC(const i : UInt32) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := ((i and $000000e0) = $000000c0); +end; + +function IN4_CLASSD(const i : UInt32) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := ((i and $000000f0) = $000000e0); +end; + +function IN4_MULTICAST(const i : UInt32) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := IN4_CLASSD(i); +end; + +function IN4_ADDR_EQUAL(const a, b : PInAddr ) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := a^.S_addr = b^.S_addr; +end; + +function IN4_UNALIGNED_ADDR_EQUAL(const a, b : PInAddr ) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := a^.S_addr = b^.S_addr +end; + +function IN4_IS_ADDR_UNSPECIFIED(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := a^.S_addr = IN4ADDR_ANY; +end; + +function IN4_IS_UNALIGNED_ADDR_UNSPECIFIED(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := a^.S_addr = IN4ADDR_ANY; +end; + +function IN4_IS_ADDR_LOOPBACK(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := PByte(a)^ = $7f; // 127/8 +end; + +function IN4_IS_UNALIGNED_ADDR_LOOPBACK(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := PByte(a)^ = $7f; // 127/8 +end; + +function IN4_IS_ADDR_BROADCAST(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := a^.S_addr = IN4ADDR_BROADCAST; +end; + +function IN4_IS_UNALIGNED_ADDR_BROADCAST(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := a^.S_addr = IN4ADDR_BROADCAST; +end; + +function IN4_IS_ADDR_MULTICAST(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := IN4_MULTICAST(a^.S_addr); +end; + +function IN4_IS_UNALIGNED_ADDR_MULTICAST(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := IN4_MULTICAST(a^.S_addr); +end; + +function IN4_IS_ADDR_LINKLOCAL(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := ((a^.s_addr and $ffff) = $fea9); // 169.254/16 +end; + +function IN4_IS_UNALIGNED_ADDR_LINKLOCAL(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := ((a^.s_addr and $ffff) = $fea9); // 169.254/16 +end; + +function IN4_IS_ADDR_SITELOCAL(const a :PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + //UNREFERENCED_PARAMETER(a); + // + // For existing scenarios (e.g. ICS) to work as expected, RFC-1918 prefixes + // are deemed to be global scoped. When appropriate, site border routers + // must explicitly filter packets with these addresses. + // + Result := False; +end; + +function IN4_IS_UNALIGNED_ADDR_SITELOCAL(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := IN4_IS_ADDR_SITELOCAL(a); +end; + +function IN4_IS_ADDR_RFC1918(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := (((a^.s_addr and $00ff) = $0a) or // 10/8 + ((a^.s_addr and $f0ff) = $10ac) or // 172.16/12 + ((a^.s_addr and $ffff) = $a8c0)); // 192.168/16 +end; + +function IN4_IS_UNALIGNED_ADDR_RFC1918(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +var + Ipv4Address : IN_ADDR; +begin + //JPM Notes: Done this way because pointers may not be aligned at all. + Ipv4Address := a^; + Result := IN4_IS_ADDR_RFC1918( @Ipv4Address ); +end; + +function IN4_IS_ADDR_MC_LINKLOCAL(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := ((a^.s_addr and $ffffff) = $e0); // 224.0.0/24 +end; + +function IN4_IS_ADDR_MC_ADMINLOCAL(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := ((a^.s_addr and $ffff) = $ffef); // 239.255/16 +end; + +function IN4_IS_ADDR_MC_SITELOCAL(const a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := ((a^.s_addr and $ff) = $ef) and + (not IN4_IS_ADDR_MC_ADMINLOCAL(a)); +end; + +function SCOPEID_UNSPECIFIED_INIT: {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result{$IFNDEF WINCE}.Value{$ENDIF} := 0; +end; + +function IN4ADDR_ANY_INIT: TInAddr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result.S_addr := 0; +end; + +function IN4ADDR_LOOPBACK_INIT: TInAddr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result.S_un_b.s_b1 := $7f; + Result.S_un_b.s_b2 := $00; + Result.S_un_b.s_b3 := $00; + Result.S_un_b.s_b4 := $01; +end; + +function IN4ADDR_BROADCAST_INIT: TInAddr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result.S_un_b.s_b1 := $ff; + Result.S_un_b.s_b2 := $ff; + Result.S_un_b.s_b3 := $ff; + Result.S_un_b.s_b4 := $ff; +end; + +function IN4ADDR_ALLNODESONLINK_INIT: TInAddr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result.S_un_b.s_b1 := $e0; + Result.S_un_b.s_b2 := $00; + Result.S_un_b.s_b3 := $00; + Result.S_un_b.s_b4 := $01; +end; + +function IN4ADDR_ALLROUTERSONLINK_INIT: TInAddr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result.S_un_b.s_b1 := $e0; + Result.S_un_b.s_b2 := $00; + Result.S_un_b.s_b3 := $00; + Result.S_un_b.s_b4 := $02; +end; + +function IN4ADDR_ALLIGMPV3ROUTERSONLINK_INIT: TInAddr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result.S_un_b.s_b1 := $e0; + Result.S_un_b.s_b2 := $00; + Result.S_un_b.s_b3 := $00; + Result.S_un_b.s_b4 := $16; +end; + +function IN4ADDR_ALLTEREDONODESONLINK_INIT: TInAddr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result.S_un_b.s_b1 := $e0; + Result.S_un_b.s_b2 := $00; + Result.S_un_b.s_b3 := $00; + Result.S_un_b.s_b4 := $fd; +end; + +function IN4ADDR_LINKLOCALPREFIX_INIT: TInAddr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result.S_un_b.s_b1 := $a9; + Result.S_un_b.s_b2 := $fe; + Result.S_un_b.s_b3 := $00; + Result.S_un_b.s_b4 := $00; +end; + +function IN4ADDR_MULTICASTPREFIX_INIT: TInAddr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result.S_un_b.s_b1 := $e0; + Result.S_un_b.s_b2 := $00; + Result.S_un_b.s_b3 := $00; + Result.S_un_b.s_b4 := $00; +end; + +procedure IN4ADDR_SETSOCKADDR(a : PSockAddrIn; const addr : PInAddr; const port : USHORT); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + a^.sin_family := AF_INET; + a^.sin_port := port; + a^.sin_addr.S_addr := addr^.S_addr; + FillChar(a^.sin_zero,SizeOf(a^.sin_zero),0); +end; + +procedure IN4ADDR_SETANY(a : PSockAddrIn); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + a^.sin_family := AF_INET; + a^.sin_port := 0; + a^.sin_addr.S_addr := IN4ADDR_ANY; + FillChar(a^.sin_zero,SizeOf(a^.sin_zero),0); +end; + +procedure IN4ADDR_SETLOOPBACK(a : PSockAddrIn); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + a^.sin_family := AF_INET; + a^.sin_port := 0; + a^.sin_addr.S_addr := IN4ADDR_LOOPBACK; + FillChar(a^.sin_zero,SizeOf(a^.sin_zero),0); +end; + +function IN4ADDR_ISANY(const a : PSockAddrIn) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + ASSERT(a^.sin_family = AF_INET); + Result := IN4_IS_ADDR_UNSPECIFIED(@a^.sin_addr ); +end; + +function IN4ADDR_ISLOOPBACK(const a : PSockAddrIn) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + ASSERT(a^.sin_family = AF_INET); + Result := IN4_IS_ADDR_LOOPBACK(@a^.sin_addr); +end; + +function IN4ADDR_SCOPE_ID(const a : PSockAddrIn) : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + //SCOPE_ID UnspecifiedScopeId = {0}; + //UNREFERENCED_PARAMETER(a); + //return UnspecifiedScopeId; + Result{$IFNDEF WINCE}.Value{$ENDIF} := 0; +end; + +function IN4ADDR_ISEQUAL(a, b : PSockAddrIn) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + ASSERT(a^.sin_family = AF_INET); + Result := (IN4ADDR_SCOPE_ID(a){$IFNDEF WINCE}.Value{$ENDIF} = IN4ADDR_SCOPE_ID(b){$IFNDEF WINCE}.Value{$ENDIF}) and + IN4_ADDR_EQUAL(@a^.sin_addr , @b^.sin_addr); +end; + +function IN4ADDR_ISUNSPECIFIED(a : PSockAddrIn) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + ASSERT(a^.sin_family = AF_INET); + Result := (IN4ADDR_SCOPE_ID(a){$IFNDEF WINCE}.Value{$ENDIF} = 0) and + IN4_IS_ADDR_UNSPECIFIED(@a^.sin_addr); +end; + +{Important!!! INET_IS_ALIGNED doesn't seem to translate well to +Delphi. The best I could think of is to make a function +for testing with specific types. I wish Pascal had an AlignOf function} + +//#define INET_IS_ALIGNED(Pointer, Type) \ +// (((ULONG_PTR)Pointer & (__builtin_alignof(Type)-1)) == 0) + + +function INET_IS_ALIGNED_IN_ADDR(Ptr : Pointer) : Boolean; +type + {$IFDEF WIN32} + {$ALIGN ON} + TempRec = record + test: IN_ADDR; + end; + {$ALIGN OFF} + {$ELSE} + //Win64 and WinCE seem to require alignment for API records + TempRec = record + test: IN_ADDR; + end; + {$ENDIF} +var + Alignment : SIZE_T; +begin + Alignment := SizeOf(TempRec); + Result := ((ULONG_PTR(Ptr) and (Alignment - 1)) = 0); +end; + + +function INET_IS_ALIGNED_IN6_ADDR(Ptr : Pointer) : Boolean; +type + {$IFDEF WIN32} + {$ALIGN ON} + TempRec = record + test: IN6_ADDR; + end; + {$ALIGN OFF} + {$ELSE} + //Win64 and WinCE seem to require alignment for API records + TempRec = record + test: IN6_ADDR; + end; + {$ENDIF} +var + Alignment : SIZE_T; +begin + Alignment := SizeOf(TempRec); + Result := ((ULONG_PTR(Ptr) and (Alignment - 1)) = 0); +end; + +{ + +Routine Description: + + Determines the scope of an IPv4 unicast address. + + For existing scenarios (e.g. ICS) to work as expected, RFC-1918 prefixes + are deemed to be global scoped. When appropriate, site border routers + must explicitly filter packets with these addresses. + +Arguments: + + Address - Supplies the IPv4 unicast address. + +Return Value: + + Returns the scope level of the address. + +Caller IRQL: + + May be called at PASSIVE through DISPATCH level. + +--*/ +} + +function Ipv4UnicastAddressScope(const Address : PUChar) : SCOPE_LEVEL; +{$IFDEF USE_INLINE}inline;{$ENDIF} +var + Ipv4Address : IN_ADDR; + AddrPtr: PInAddr; +begin + if not INET_IS_ALIGNED_IN_ADDR(Address) then begin + Ipv4Address := PInAddr(Address)^; + AddrPtr := @Ipv4Address; + end else begin + AddrPtr := PInAddr(Address); + end; + if IN4_IS_ADDR_LINKLOCAL(AddrPtr) or + IN4_IS_ADDR_LOOPBACK(AddrPtr) then + begin + Result := ScopeLevelLink; + end else begin + Result := ScopeLevelGlobal; + end; +end; + +{ +/*++ + +Routine Description: + + Determines the scope of an IPv4 multicast address. + See RFC 2365. + +Arguments: + + Address - Supplies the IPv4 multicast address. + +Return Value: + + Returns the scope level of the multicast address. + +Caller IRQL: + + May be called at PASSIVE through DISPATCH level. + +--*/ +} +function Ipv4MulticastAddressScope(const Address : PUCHAR) : SCOPE_LEVEL; +var + Ipv4Address : IN_ADDR; + AddrPtr : PInAddr; +begin + if not INET_IS_ALIGNED_IN_ADDR(Address) then begin + Ipv4Address := PInAddr(Address)^; + AddrPtr := @Ipv4Address; + end else begin + AddrPtr := PInAddr(Address); + end; + if IN4_IS_ADDR_MC_LINKLOCAL(AddrPtr) then begin + Result := ScopeLevelLink; + end + else if IN4_IS_ADDR_MC_ADMINLOCAL(AddrPtr) then begin + Result := ScopeLevelAdmin; + end + else if IN4_IS_ADDR_MC_SITELOCAL(AddrPtr) then begin + Result := ScopeLevelSite; + end else begin + Result := ScopeLevelGlobal; + end; +end; + +{ +/*++ + +Routine Description: + + Examines an IPv4 address and determines its scope. + +Arguments: + + Address - Supplies the address to test. + +Return Value: + + Returns the scope level of the address. + +Caller IRQL: + + May be called at PASSIVE through DISPATCH level. + +--*/ +} +function Ipv4AddressScope(Address : PUChar) : SCOPE_LEVEL; +{$IFDEF USE_INLINE}inline;{$ENDIF} +var + Ipv4Address : IN_ADDR; +begin + Ipv4Address := PInAddr(Address)^; + if IN4_IS_ADDR_BROADCAST(@Ipv4Address) then begin + Result := ScopeLevelLink; + end + else if IN4_IS_ADDR_MULTICAST(@Ipv4Address) then begin + Result := Ipv4MulticastAddressScope(PUCHAR(@Ipv4Address)); + end else begin + Result := Ipv4UnicastAddressScope(PUCHAR(@Ipv4Address)); + end; +end; + +function Ipv4AddressType(Address : PUChar) : NL_ADDRESS_TYPE; +{$IFDEF USE_INLINE}inline;{$ENDIF} +var + Ipv4Address : TInAddr; +begin + Ipv4Address := PInAddr(Address)^; + if IN4_IS_ADDR_MULTICAST(@Ipv4Address) then begin + Result := NlatMulticast; + Exit; + end; + if IN4_IS_ADDR_BROADCAST(@Ipv4Address) then begin + Result := NlatBroadcast; + Exit; + end; + if IN4_IS_ADDR_UNSPECIFIED(@Ipv4Address) then begin + Result := NlatUnspecified; + Exit; + end; + // + // Following prefixes are invalid: + // 1. 0.0.0.0/8 (except 0.0.0.0/32). + // 2. 240.0.0.0/4 (except 255.255.255.255/32). + // + if ((Ipv4Address.s_addr and $000000ff) = 0) or + ((Ipv4Address.s_addr and $000000f0) = 240) then + begin + Result := NlatInvalid; + Exit; + end; + // + // Loopback and anycast addresses are treated as unicast. + // + Result := NlatUnicast; +end; + +{$IFNDEF WINCE} +// SCOPE_ID = record +// union { +// struct { +// ULONG Zone : 28; +// ULONG Level : 4; +// }; +// ULONG Value; +// }; +// Value : ULONG; +// end; + +function SCOPE_ID_GetZone(const ScopeId : SCOPE_ID) : ULONG; +begin + Result := (ScopeId.Value and $FFFFFFF0) shr 4; +end; + +procedure SCOPE_ID_SetZone(var ScopeId : SCOPE_ID; Value: ULONG); +begin + ScopeId.Value := ((Value and $0FFFFFFF) shl 4) or (ScopeId.Value and $F); +end; + +function SCOPE_ID_GetLevel(const ScopeId : SCOPE_ID) : SCOPE_LEVEL; +begin + Result := SCOPE_LEVEL(ScopeId.Value and $F); +end; + +procedure SCOPE_ID_SetLevel(var ScopeId : SCOPE_ID; Value: ULONG); +begin + ScopeId.Value := (ScopeId.Value and $FFFFFFF0) or (Value and $F); +end; + +procedure IN4_UNCANONICALIZE_SCOPE_ID(Address : PInAddr; ScopeId : PSCOPE_ID); +{$IFDEF USE_INLINE}inline;{$ENDIF} +var + ScopeLevel : SCOPE_LEVEL; +begin + ScopeLevel := Ipv4AddressScope(PUCHAR(Address)); + if IN4_IS_ADDR_LOOPBACK(Address) or (ScopeLevel = ScopeLevelGlobal) then begin + ScopeId^.Value := 0; + end; + if SCOPE_ID_GetLevel(ScopeId^) = ScopeLevel then begin + SCOPE_ID_SetLevel(ScopeId^, 0); + end; +end; +{$ENDIF} + +function IN4_IS_ADDR_6TO4ELIGIBLE(a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := (Ipv4AddressType(PUChar(a)) = NlatUnicast) and + (not (IN4_IS_ADDR_LOOPBACK(a) or + IN4_IS_ADDR_LINKLOCAL(a) or + IN4_IS_ADDR_SITELOCAL(a) or + IN4_IS_ADDR_RFC1918(a))); +end; + +function IN4_IS_UNALIGNED_ADDR_6TO4ELIGIBLE(a : PInAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +var + Ipv4Address : TInAddr; +begin + Ipv4Address := a^; + Result := IN4_IS_ADDR_6TO4ELIGIBLE(@Ipv4Address); +end; + +// +// Microsoft-specific IPv6 definitions. +// + +function IN6_PREFIX_EQUAL(const a, b : PIN6_ADDR; const len : UINT8) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +var + Bytes : UINT8; + Bits : UINT8; + Mask : UINT8; +begin + Bytes := len div 8; + Bits := len mod 8; + Mask := $ff shl (8 - Bits); + ASSERT(len <= (SizeOf(IN6_ADDR) * 8)); + Result := CompareMem(a,b,len) and ((Bits = 0) or ((a^.s6_bytes[Bytes] or Mask) = (b^.s6_bytes[Bytes] or Mask))); +end; + +function IN6_IS_ADDR_ALLNODESONNODE(a : PIN6_ADDR) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := IN6_ADDR_EQUAL(a, @in6addr_allnodesonnode); +end; + +function IN6_IS_ADDR_ALLNODESONLINK(a : PIN6_ADDR) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := IN6_ADDR_EQUAL(a, @in6addr_allnodesonlink); +end; + +function IN6_IS_ADDR_ALLROUTERSONLINK(a : PIN6_ADDR) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := IN6_ADDR_EQUAL(a, @in6addr_allroutersonlink); +end; + +function IN6_IS_ADDR_SOLICITEDNODE(a : PIN6_ADDR) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := IN6_PREFIX_EQUAL( + a, + @in6addr_solicitednodemulticastprefix, + IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH); +end; + +function IN6_IS_ADDR_ISATAP(a : PIN6_ADDR) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + // + // Disregard the u/g bit and compare the first byte of the interface id. + // + Result := ((a^.s6_words[4] and $fffd) = $0000) and (a^.s6_words[5] = $fe5e); +end; + +function IN6_IS_ADDR_6TO4(a : PIN6_ADDR) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + //C_ASSERT(IN6ADDR_6TO4PREFIX_LENGTH = RTL_BITS_OF(USHORT)); + Result := (a^.s6_words[0] = in6addr_6to4prefix.s6_words[0]); +end; + +function IN6_IS_ADDR_TEREDO(a : PIN6_ADDR) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + //C_ASSERT(IN6ADDR_TEREDOPREFIX_LENGTH == 2 * RTL_BITS_OF(USHORT)); + Result := (a^.s6_words[0] = in6addr_teredoprefix.s6_words[0]) and + (a^.s6_words[1] = in6addr_teredoprefix.s6_words[1]); +end; + +function IN6ADDR_ISV4MAPPED(a : PSOCKADDR_IN6) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + ASSERT(a^.sin6_family = AF_INET6); + Result := IN6_IS_ADDR_V4MAPPED(@a^.sin6_addr); +end; + +function IN6ADDR_ISISATAP(a : PSOCKADDR_IN6) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + ASSERT(a^.sin6_family = AF_INET6); + Result := IN6_IS_ADDR_ISATAP(@a^.sin6_addr);; +end; + +function IN6ADDR_IS6TO4(a : PSOCKADDR_IN6) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + ASSERT(a^.sin6_family = AF_INET6); + Result := IN6_IS_ADDR_6TO4(@a^.sin6_addr); +end; + +function IN6ADDR_ISTEREDO(a : PSOCKADDR_IN6) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + ASSERT(a^.sin6_family = AF_INET6); + Result := IN6_IS_ADDR_TEREDO(@a^.sin6_addr); +end; + +function IN6_GET_ADDR_V4MAPPED(Ipv6Address : PIN6_ADDR) : PUCHAR; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := PUChar(@Ipv6Address^.s6_words[6]); +end; + +function IN6_GET_ADDR_V4COMPAT(Ipv6Address : PIN6_ADDR) : PUCHAR; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := PUChar(@Ipv6Address^.s6_words[6]); +end; + +function IN6_EXTRACT_V4ADDR_FROM_ISATAP(Ipv6Address : PIN6_ADDR) : PUCHAR; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := PUChar(@Ipv6Address^.s6_words[6]); +end; + +function IN6_EXTRACT_V4ADDR_FROM_6TO4(Ipv6Address : PIN6_ADDR) : PUCHAR; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := PUChar(@Ipv6Address^.s6_words[1]); +end; + +procedure IN6_SET_ADDR_V4MAPPED(out a6 : IN6_ADDR; a4 : PInAddr ); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + a6 := in6addr_v4mappedprefix; + a6.s6_bytes[12] := a4^.S_un_b.s_b1; + a6.s6_bytes[13] := a4^.S_un_b.s_b2; + a6.s6_bytes[14] := a4^.S_un_b.s_b3; + a6.s6_bytes[15] := a4^.S_un_b.s_b4; +end; + +procedure IN6_SET_ADDR_V4COMPAT(out a6 : IN6_ADDR; a4 : PInAddr ); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + a6 := in6addr_any; + a6.s6_bytes[12] := a4^.S_un_b.s_b1; + a6.s6_bytes[13] := a4^.S_un_b.s_b2; + a6.s6_bytes[14] := a4^.S_un_b.s_b3; + a6.s6_bytes[15] := a4^.S_un_b.s_b4; +end; + +procedure IN6_SET_ADDR_SOLICITEDNODE(out Multicast : IN6_ADDR; Unicast : PIN6_ADDR); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Multicast := in6addr_solicitednodemulticastprefix; + Multicast.s6_bytes[13] := Unicast^.s6_bytes[13]; + Multicast.s6_bytes[14] := Unicast^.s6_bytes[14]; + Multicast.s6_bytes[15] := Unicast^.s6_bytes[15]; +end; + +procedure IN6_SET_ISATAP_IDENTIFIER(Ipv6Address : PIN6_ADDR; Ipv4Address : PInAddr); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if IN4_IS_ADDR_6TO4ELIGIBLE(Ipv4Address) then begin + Ipv6Address^.s6_words[4] := $0002; + end else begin + Ipv6Address^.s6_words[4] := $0000; + end; + // + // 24-bit IANA OUI 00-00-5E and the 8-bit hex value 0xFE. + // See section 6.1 of RFC 4214. + // + Ipv6Address^.s6_words[5] := $FE5E; + PInAddr(@Ipv6Address^.s6_words[6])^ := Ipv4Address^; +end; + +procedure IN6_SET_6TO4_PREFIX(Ipv6Address : PIN6_ADDR; Ipv4Address : PInAddr); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Ipv6Address^.s6_words[0] := $0220; + PInAddr(@Ipv6Address^.s6_words[1])^ := Ipv4Address^; + Ipv6Address^.s6_words[3] := $0000; +end; + +function Ipv6UnicastAddressScope(const Address : PUChar) : SCOPE_LEVEL; +{$IFDEF USE_INLINE}inline;{$ENDIF} +{*++ + +Routine Description: + + Examines a unicast address and determines its scope. + + Note that v4-compatible and 6to4 addresses are deemed to have global scope; + it is not legal to derive them from non IN4_IS_ADDR_6TO4ELIGIBLE addresses + (IPv4 loopback, link-local, site-local, and RFC-1918 addresses). + +Arguments: + + Address - Supplies an IPv6 unicast address. + +Return Value: + + Returns the scope level of the address. + +Caller IRQL: + + May be called at PASSIVE through DISPATCH level. + +--*} +var + Ipv6Address : TIn6Addr; + AddrPtr : PIn6Addr; +begin + if not INET_IS_ALIGNED_IN6_ADDR(Address) then begin + Ipv6Address := PIn6Addr(Address)^; + AddrPtr := @Ipv6Address; + end else begin + AddrPtr := PIn6Addr(Address); + end; + if IN6_IS_ADDR_LINKLOCAL(AddrPtr) or + IN6_IS_ADDR_LOOPBACK(AddrPtr) then + begin + Result := ScopeLevelLink; + end + else if IN6_IS_ADDR_SITELOCAL(AddrPtr) then begin + Result := ScopeLevelSite; + end else begin + Result := ScopeLevelGlobal; + end; +end; + +function IN6_MULTICAST_SCOPE(Address : PUCHAR ) : SCOPE_LEVEL; +{$IFDEF USE_INLINE}inline;{$ENDIF} +var + Ipv6Address : PIN6_ADDR; +begin + Ipv6Address := PIN6_ADDR(Address); + Result := SCOPE_LEVEL(Ipv6Address^.s6_bytes[1] and $f); +end; + +function Ipv6AddressScope(Address : PUCHAR ) : SCOPE_LEVEL; +{$IFDEF USE_INLINE}inline;{$ENDIF} +{*++ + +Routine Description: + + Examines an IPv6 address and determines its scope. + +Arguments: + + Address - Supplies an IPv6 address. + +Return Value: + + Returns the scope level of the address. + +Caller IRQL: + + May be called at PASSIVE through DISPATCH level. + +--*} +begin + if IN6_IS_ADDR_MULTICAST(PIn6Addr(Address)) then begin + Result := IN6_MULTICAST_SCOPE(Address); + end else begin + Result := Ipv6UnicastAddressScope(Address); + end; +end; + +function Ipv6AddressType( Address : PUCHAR) : NL_ADDRESS_TYPE; +{$IFDEF USE_INLINE}inline;{$ENDIF} +var + Ipv6Address : PIN6_ADDR; + Ipv4Address : PUCHAR; +begin + Ipv6Address := PIN6_ADDR(Address); + if IN6_IS_ADDR_MULTICAST(Ipv6Address) then begin + Result := NlatMulticast; + Exit; + end; + if IN6_IS_ADDR_UNSPECIFIED(Ipv6Address) then begin + Result := NlatUnspecified; + Exit; + end; + + // + // Extract embedded IPv4 address, if any. + // + if IN6_IS_ADDR_ISATAP(Ipv6Address) or + IN6_IS_ADDR_V4COMPAT(Ipv6Address) or + IN6_IS_ADDR_V4MAPPED(Ipv6Address) or + IN6_IS_ADDR_V4TRANSLATED(Ipv6Address) then + begin + Ipv4Address := IN6_EXTRACT_V4ADDR_FROM_ISATAP(Ipv6Address); + end + else if IN6_IS_ADDR_6TO4(Ipv6Address) then begin + Ipv4Address := IN6_EXTRACT_V4ADDR_FROM_6TO4(Ipv6Address); + end else begin + // + // Anycast and loopback addresses are treated unicast address. + // + Result := NlatUnicast; + Exit; + end; + // + // Ensure that the embedded IPv4 address is unicast. + // + if Ipv4AddressType(Ipv4Address) <> NlatUnicast then begin + Result := NlatInvalid; + Exit; + end; + Result := NlatUnicast; +end; + +{$IFNDEF WINCE} +procedure IN6_UNCANONICALIZE_SCOPE_ID(Address : PIN6_ADDR; ScopeId : PSCOPE_ID); +{$IFDEF USE_INLINE}inline;{$ENDIF} +var + ScopeLevel : SCOPE_LEVEL; +begin + ScopeLevel := Ipv6AddressScope(PUCHAR(Address)); + if IN6_IS_ADDR_LOOPBACK(Address) or (ScopeLevel = ScopeLevelGlobal) then begin + ScopeId^.Value := 0; + end; + if (SCOPE_LEVEL(ScopeId^.Value shr 28) = ScopeLevel) then begin + SCOPE_ID_SetLevel(ScopeId^, 0); + end; +end; +{$ENDIF} + +procedure IN6ADDR_SETSOCKADDR(a : PSOCKADDR_IN6; addr : PIN6_ADDR; + const scope : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; const port : USHORT ); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + a^.sin6_family := AF_INET6; + a^.sin6_port := port; + a^.sin6_flowinfo := 0; + a^.sin6_addr := addr^; + {$IFDEF WINCE} + a^.sin6_scope_id := scope; + {$ELSE} + a^.a.sin6_scope_struct := scope; + IN6_UNCANONICALIZE_SCOPE_ID(@a^.sin6_addr, @a^.a.sin6_scope_struct); + {$ENDIF} +end; + +procedure IN6ADDR_SETV4MAPPED(a6 : PSOCKADDR_IN6; a4 : PInAddr; + const scope : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; const port : USHORT ); +begin + a6^.sin6_family := AF_INET6; + a6^.sin6_port := port; + a6^.sin6_flowinfo := 0; + IN6_SET_ADDR_V4MAPPED(a6^.sin6_addr, a4); + {$IFDEF WINCE} + a6^.sin6_scope_id := scope; + {$ELSE} + a6^.a.sin6_scope_struct := scope; + IN4_UNCANONICALIZE_SCOPE_ID(a4, @a6^.a.sin6_scope_struct); + {$ENDIF} +end; + +// +// Define address-family-independent routines. +// +function INET_ADDR_EQUAL(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; + const a, b : Pointer) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (af = AF_INET6) then begin + Result := IN6_ADDR_EQUAL(PIN6_ADDR(a), PIN6_ADDR(b)); + end else begin + ASSERT(af = AF_INET); + Result := IN4_ADDR_EQUAL(PInAddr(a), PInAddr(b)); + end; +end; + +function INET_UNALIGNED_ADDR_EQUAL(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; + const a, b : Pointer ) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (af = AF_INET6) then begin + Result := IN6_ADDR_EQUAL(PIN6_ADDR(a), PIN6_ADDR(b)); + end else begin + ASSERT(af = AF_INET); + Result := IN4_UNALIGNED_ADDR_EQUAL(PInAddr(a), PInAddr(b)); + end; +end; + +function INET_IS_ADDR_UNSPECIFIED(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; + const a : Pointer) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (af = AF_INET6) then begin + Result := IN6_IS_ADDR_UNSPECIFIED(PIN6_ADDR(a)); + end else begin + ASSERT(af = AF_INET); + Result := IN4_IS_ADDR_UNSPECIFIED(PInAddr(a)); + end; +end; + +function INET_IS_UNALIGNED_ADDR_UNSPECIFIED(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; + const a : Pointer) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (af = AF_INET6) then begin + Result := IN6_IS_ADDR_LOOPBACK(PIN6_ADDR(a)); + end else begin + ASSERT(af = AF_INET); + Result := IN4_IS_ADDR_LOOPBACK(PInAddr(a)); + end; +end; + +function INET_IS_ADDR_LOOPBACK(const af: {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; + const a: Pointer): Boolean; +begin + if (af = AF_INET6) then begin + Result := IN6_IS_ADDR_LOOPBACK(PIn6Addr(a)); + end else begin + ASSERT(af = AF_INET); + Result := IN4_IS_ADDR_LOOPBACK(PInAddr(a)); + end; +end; + +function INET_IS_ADDR_BROADCAST(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; + const a : Pointer) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (af = AF_INET6) then begin + Result := False; + end else begin + ASSERT(af = AF_INET); + Result := IN4_IS_ADDR_BROADCAST(PInAddr(a)); + end; +end; + +function INET_IS_ADDR_MULTICAST(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; + const a : Pointer) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (af = AF_INET6) then begin + Result := IN6_IS_ADDR_MULTICAST(PIN6_ADDR(a)); + end else begin + ASSERT(af = AF_INET); + Result := IN4_IS_ADDR_MULTICAST(PInAddr(a)); + end; +end; + +function INET_ADDR_UNSPECIFIED(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}) : PUCHAR; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (af = AF_INET6) then begin + Result := PUCHAR(@in6addr_any); + end else begin + ASSERT(af = AF_INET); + Result := PUCHAR(@_in4addr_any); + end; +end; + +procedure INET_SET_ADDRESS( Family : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; + Address : PUCHAR; Value : PUCHAR); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (Family = AF_INET6) then begin + PIn6Addr(Address)^ := PIn6Addr(Value)^; + end else begin + ASSERT(Family = AF_INET); + PInAddr(Address)^ := PInAddr(Value)^; + end; +end; + +function INET_ADDR_LENGTH(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF} ) : Size_t; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (af = AF_INET6) then begin + Result := SizeOf(IN6_ADDR); + end else begin + ASSERT(af = AF_INET); + Result := SizeOf(IN_ADDR); + end; +end; + +function INET_SOCKADDR_LENGTH(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}) : Size_t; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (af = AF_INET6) then begin + Result := SizeOf(SOCKADDR_IN6); + end else begin + ASSERT(af = AF_INET); + Result := SizeOf(SOCKADDR_IN); + end; +end; +// +function IN6ADDR_ANY_INIT: TIn6Addr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} +end; + +function IN6ADDR_LOOPBACK_INIT: TIn6Addr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} + Result.s6_bytes[15] := 1; +end; + +function IN6ADDR_ALLNODESONNODE_INIT : TIn6Addr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} + + Result.s6_bytes[0] := $ff; + Result.s6_bytes[1] := $01; + Result.s6_bytes[15] := $01; +end; + +function IN6ADDR_ALLNODESONLINK_INIT : TIn6Addr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} + + Result.s6_bytes[0] := $ff; + Result.s6_bytes[1] := $02; + Result.s6_bytes[15] := $01; +end; + +function IN6ADDR_ALLROUTERSONLINK_INIT : TIn6Addr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} + + Result.s6_bytes[0] := $ff; + Result.s6_bytes[1] := $02; + Result.s6_bytes[15] := $02; +end; + +function IN6ADDR_ALLMLDV2ROUTERSONLINK_INIT : TIn6Addr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} + + Result.s6_bytes[0] := $ff; + Result.s6_bytes[1] := $02; + Result.s6_bytes[15] := $16; +end; + +function IN6ADDR_TEREDOINITIALLINKLOCALADDRESS_INIT : TIn6Addr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} + + Result.s6_bytes[0] := $fe; + Result.s6_bytes[1] := $80; + + Result.s6_bytes[10] := $ff; + Result.s6_bytes[11] := $ff; + Result.s6_bytes[12] := $ff; + Result.s6_bytes[13] := $ff; + Result.s6_bytes[14] := $ff; + Result.s6_bytes[15] := $fe; +end; + +// +// The old link local address for XP-SP2/Win2K3 machines. +// +function IN6ADDR_TEREDOOLDLINKLOCALADDRESSXP_INIT : TIn6Addr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} + + Result.s6_bytes[0] := $fe; + Result.s6_bytes[1] := $80; + + Result.s6_bytes[10] := Ord('T'); + Result.s6_bytes[11] := Ord('E'); + Result.s6_bytes[12] := Ord('R'); + Result.s6_bytes[13] := Ord('E'); + Result.s6_bytes[14] := Ord('D'); + Result.s6_bytes[15] := Ord('O'); +end; + +// +// The old link local address for Vista Beta-2 and earlier machines. +// +function IN6ADDR_TEREDOOLDLINKLOCALADDRESSVISTA_INIT : TIn6Addr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} + + Result.s6_bytes[0] := $fe; + Result.s6_bytes[1] := $80; + + Result.s6_bytes[10] := $ff; + Result.s6_bytes[11] := $ff; + Result.s6_bytes[12] := $ff; + Result.s6_bytes[13] := $ff; + Result.s6_bytes[14] := $ff; + Result.s6_bytes[15] := $ff; +end; + +function IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_INIT : IN6_ADDR; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} + Result.s6_bytes[0] := $FF; + Result.s6_bytes[1] := $02; + Result.s6_bytes[11] := $01; + Result.s6_bytes[12] := $ff; +end; + +function IN6ADDR_V4MAPPEDPREFIX_INIT : TIn6Addr; +begin + System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} + Result.s6_bytes[10] := $ff; + Result.s6_bytes[11] := $ff; +end; + +function IN6ADDR_6TO4PREFIX_INIT : TIn6Addr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} + Result.s6_bytes[0] := $20; + Result.s6_bytes[1] := $02; +end; + +function IN6ADDR_TEREDOPREFIX_INIT : TIn6Addr; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(Result.s6_bytes, SIZE_TIN6ADDR, 0); {Do not Localize} + Result.s6_bytes[0] := $20; + Result.s6_bytes[1] := $01; +end; + +procedure IN6ADDR_SETANY(sa: PSockAddrIn6); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if sa <> nil then begin + sa^.sin6_family := AF_INET6; + sa^.sin6_port := 0; + sa^.sin6_flowinfo := 0; + PULONG(@sa^.sin6_addr.s6_bytes[0])^ := 0; + PULONG(@sa^.sin6_addr.s6_bytes[4])^ := 0; + PULONG(@sa^.sin6_addr.s6_bytes[8])^ := 0; + PULONG(@sa^.sin6_addr.s6_bytes[12])^ := 0; + end; +end; + +procedure IN6ADDR_SETLOOPBACK(sa: PSockAddrIn6); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if sa <> nil then begin + sa^.sin6_family := AF_INET6; + sa^.sin6_port := 0; + sa^.sin6_flowinfo := 0; + PULONG(@sa^.sin6_addr.s6_bytes[0])^ := 0; + PULONG(@sa^.sin6_addr.s6_bytes[4])^ := 0; + PULONG(@sa^.sin6_addr.s6_bytes[8])^ := 0; + PULONG(@sa^.sin6_addr.s6_bytes[12])^ := 1; + end; +end; + +function IN6ADDR_ISANY(sa: PSockAddrIn6): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if sa <> nil then begin + Result := (sa^.sin6_family = AF_INET6) and + (PULONG(@sa^.sin6_addr.s6_bytes[0])^ = 0) and + (PULONG(@sa^.sin6_addr.s6_bytes[4])^ = 0) and + (PULONG(@sa^.sin6_addr.s6_bytes[8])^ = 0) and + (PULONG(@sa^.sin6_addr.s6_bytes[12])^ = 0); + end else begin + Result := False; + end; +end; + +function IN6ADDR_ISLOOPBACK(sa: PSockAddrIn6): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if sa <> nil then begin + Result := (sa^.sin6_family = AF_INET6) and + (PULONG(@sa^.sin6_addr.s6_bytes[0])^ = 0) and + (PULONG(@sa^.sin6_addr.s6_bytes[4])^ = 0) and + (PULONG(@sa^.sin6_addr.s6_bytes[8])^ = 0) and + (PULONG(@sa^.sin6_addr.s6_bytes[12])^ = 1); + end else begin + Result := False; + end; +end; + +function IN6_ADDR_EQUAL(const a: PIn6Addr; const b: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := SysUtils.CompareMem(a, b, SIZE_TIN6ADDR); +end; + +function IN6_IS_ADDR_UNSPECIFIED(const a: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := IN6_ADDR_EQUAL(a, @in6addr_any); +end; + +function IN6_IS_ADDR_LOOPBACK(const a: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := IN6_ADDR_EQUAL(a, @in6addr_loopback); +end; + +function IN6_IS_ADDR_MULTICAST(const a: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if a <> nil then begin + Result := (a^.s6_bytes[0] = $FF); + end else begin + Result := False; + end; +end; + +function IN6_IS_ADDR_EUI64(const a : PIn6Addr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} + // + // Format prefixes 001 through 111, except for multicast. + // +begin + if a <> nil then begin + Result := ((a^.s6_bytes[0] and $e0) <> 0 ) and (not IN6_IS_ADDR_MULTICAST(a)); + end else begin + Result := False; + end; +end; + +function IN6_IS_ADDR_SUBNET_ROUTER_ANYCAST(const a : PIn6Addr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +// +// Is this the subnet router anycast address? +// See RFC 2373. +// +begin + if a <> nil then begin + Result := IN6_IS_ADDR_EUI64(a) and (a^.s6_words[4] = 0) and + (a^.s6_words[5] = 0) and (a^.s6_words[6]=0) and (a^.s6_words[7]=0); + end else begin + Result := False; + end; +end; + +function IN6_IS_ADDR_SUBNET_RESERVED_ANYCAST(const a: PIn6Addr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if a <> nil then begin + Result := IN6_IS_ADDR_EUI64(a) and (a^.s6_words[4] = $fffd) and + (a^.s6_words[5] = $ffff) and (a^.s6_words[6] = $ffff) and + ((a^.s6_words[7] and $80ff) = $80ff); + end else begin + Result := False; + end; +end; + +function IN6_IS_ADDR_ANYCAST(const a: PIn6Addr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if a <> nil then begin + Result := IN6_IS_ADDR_SUBNET_RESERVED_ANYCAST(a) or IN6_IS_ADDR_SUBNET_ROUTER_ANYCAST(a); + end else begin + Result := False; + end; +end; + +function IN6_IS_ADDR_LINKLOCAL(const a: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if a <> nil then begin + Result := (a^.s6_bytes[0] = $FE) and ((a^.s6_bytes[1] and $C0) = $80); + end else begin + Result := False; + end; +end; + +function IN6_IS_ADDR_SITELOCAL(const a: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if a <> nil then begin + Result := (a^.s6_bytes[0] = $FE) and ((a^.s6_bytes[1] and $C0) = $C0); + end else begin + Result := False; + end; +end; + +function IN6_IS_ADDR_V4MAPPED(const a: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if a <> nil then begin + Result := (a^.s6_words[0] = 0) and + (a^.s6_words[1] = 0) and + (a^.s6_words[2] = 0) and + (a^.s6_words[3] = 0) and + (a^.s6_words[4] = 0) and + (a^.s6_words[5] = $FFFF); + end else begin + Result := False; + end; +end; + +function IN6_IS_ADDR_V4COMPAT(const a: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if a <> nil then begin + Result := (a^.s6_words[0] = 0) and + (a^.s6_words[1] = 0) and + (a^.s6_words[2] = 0) and + (a^.s6_words[3] = 0) and + (a^.s6_words[4] = 0) and + (a^.s6_words[5] = 0) and + not ((a^.s6_words[6] = 0) and (a^.s6_bytes[14] = 0) and + ((a^.s6_bytes[15] = 0) or (a^.s6_bytes[15] = 1))); + end else begin + Result := False; + end; +end; + +function IN6_IS_ADDR_V4TRANSLATED(const a: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := ((a^.s6_words[0] = 0) and + (a^.s6_words[1] = 0) and + (a^.s6_words[2] = 0) and + (a^.s6_words[3] = 0) and + (a^.s6_words[4] = $ffff) and + (a^.s6_words[5] = 0)); +end; + +procedure INETADDR_SETSOCKADDR(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; + a : PSOCKADDR; addr : Pointer; const scope : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; const port : USHORT); +{$IFDEF USE_INLINE}inline;{$ENDIF} +var + addr4 : IN_ADDR; +begin + if (af = AF_INET6) then begin + IN6ADDR_SETSOCKADDR(PSOCKADDR_IN6( a), PIN6_ADDR( addr ), scope, port); + end else begin + addr4 := PInAddr(addr)^; + ASSERT(af = AF_INET); + IN4ADDR_SETSOCKADDR(PSockAddrIn(a),PInAddr( @addr4), port); + end; +end; + +procedure INETADDR_SETANY(a : PSOCKADDR); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (a^.sa_family = AF_INET6) then begin + IN6ADDR_SETANY(PSOCKADDR_IN6(a)); + end else begin + ASSERT(a^.sa_family = AF_INET); + IN4ADDR_SETANY(PSockAddrIn(a)); + end; +end; + +procedure INETADDR_SETLOOPBACK(a : PSOCKADDR); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (a^.sa_family = AF_INET6) then begin + IN6ADDR_SETLOOPBACK(PSOCKADDR_IN6(a)); + end else begin + ASSERT(a^.sa_family = AF_INET); + IN4ADDR_SETLOOPBACK(PSockAddrIn(a)); + end; +end; + +function INETADDR_ISANY(const a : PSOCKADDR) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (a^.sa_family = AF_INET6) then begin + Result := IN6ADDR_ISANY(PSOCKADDR_IN6(a)); + end else begin + ASSERT(a^.sa_family = AF_INET); + Result := IN4ADDR_ISANY(PSockAddrIn(a)); + end; +end; + +function INETADDR_ISLOOPBACK(const a : PSockAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (a^.sa_family = AF_INET6) then begin + Result := IN6ADDR_ISLOOPBACK(PSOCKADDR_IN6(a)); + end else begin + ASSERT(a^.sa_family = AF_INET); + Result := IN4ADDR_ISLOOPBACK(PSockAddrIn(a)); + end; +end; + +function INETADDR_ISV4MAPPED(const a : PSockAddr) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (a^.sa_family = AF_INET6) then begin + Result := IN6ADDR_ISV4MAPPED(PSOCKADDR_IN6(a)); + end else begin + Result := False; + end; +end; + +function NL_ADDR_EQUAL(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; + const sa : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; + const aa : PUCHAR; + const sb : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; + const ab : PUCHAR) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := ((sa{$IFNDEF WINCE}.Value{$ENDIF} = sb{$IFNDEF WINCE}.Value{$ENDIF}) and + INET_ADDR_EQUAL(af, aa, ab)); +end; + +function NL_IS_ADDR_UNSPECIFIED(const af : {$IFDEF WINCE}Int16{$ELSE}ADDRESS_FAMILY{$ENDIF}; + const s : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; + const a : PUCHAR) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := ((s{$IFNDEF WINCE}.Value{$ENDIF} = 0) and INET_IS_ADDR_UNSPECIFIED(af, a)); +end; + +function IN6ADDR_ISEQUAL(const a,b : PSOCKADDR_IN6 ) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + ASSERT(a^.sin6_family = AF_INET6); + Result := (a^.{$IFNDEF WINCE}a.{$ENDIF}sin6_scope_id = b^.{$IFNDEF WINCE}a.{$ENDIF}sin6_scope_id) and + IN6_ADDR_EQUAL(@a^.sin6_addr, @b^.sin6_addr); +end; + +function INETADDR_ISEQUAL(const a,b : PSOCKADDR) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (a^.sa_family = AF_INET6) then begin + Result := (b^.sa_family = AF_INET6) and + IN6ADDR_ISEQUAL(PSOCKADDR_IN6(a), PSOCKADDR_IN6(b)); + end else begin + ASSERT(a^.sa_family = AF_INET); + Result := (b^.sa_family = AF_INET) and + IN4ADDR_ISEQUAL(PSOCKADDR_IN(a), PSOCKADDR_IN(b)); + end; +end; + +function IN6ADDR_ISUNSPECIFIED(a : PSOCKADDR_IN6) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + ASSERT(a^.sin6_family = AF_INET6); + Result := (a^.{$IFNDEF WINCE}a.{$ENDIF}sin6_scope_id = 0) and + IN6_IS_ADDR_UNSPECIFIED(@a^.sin6_addr); +end; + +function INETADDR_ISUNSPECIFIED(const a : PSOCKADDR) : Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (a^.sa_family = AF_INET6) then begin + Result := IN6ADDR_ISUNSPECIFIED( PSOCKADDR_IN6(a)); + end else begin + ASSERT(a^.sa_family = AF_INET); + Result := IN4ADDR_ISUNSPECIFIED(PSOCKADDR_IN(a)); + end; +end; + +function INETADDR_SCOPE_ID(const a : PSOCKADDR) : {$IFDEF WINCE}u_long{$ELSE}SCOPE_ID{$ENDIF}; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (a^.sa_family = AF_INET6) then begin + Result := PSOCKADDR_IN6(a)^.{$IFDEF WINCE}sin6_scope_id{$ELSE}a.sin6_scope_struct{$ENDIF}; + end else begin + ASSERT(a^.sa_family = AF_INET); + Result := IN4ADDR_SCOPE_ID(PSOCKADDR_IN(a)); + end; +end; + +function INETADDR_PORT(const a : PSOCKADDR) : USHORT; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (a^.sa_family = AF_INET6) then begin + Result := PSOCKADDR_IN6(a)^.sin6_port; + end else begin + ASSERT(a^.sa_family = AF_INET); + Result := PSOCKADDR_IN(a)^.sin_port; + end; +end; + +function INETADDR_ADDRESS(const a : PSOCKADDR) : PUCHAR; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (a^.sa_family = AF_INET6) then begin + Result := PUCHAR(@(PSOCKADDR_IN6(a))^.sin6_addr); + end else begin + ASSERT(a^.sa_family = AF_INET); + Result := PUCHAR(@(PSOCKADDR_IN(a))^.sin_addr); + end; +end; + +procedure INETADDR_SET_PORT(const a : PSOCKADDR; Port : USHORT); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + a^.sin_port := Port; +end; + +procedure INETADDR_SET_ADDRESS(const a : PSOCKADDR; Address : PUCHAR); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (a^.sa_family = AF_INET6) then begin + PSOCKADDR_IN6(a)^.sin6_addr := PIN6_ADDR(Address)^; + end else begin + ASSERT(PSOCKADDR_IN(a)^.sa_family = AF_INET); + PSOCKADDR_IN(a)^.sin_addr := PInAddr(Address)^; + end; +end; + +{$IFNDEF WINCE} +procedure INET_UNCANONICALIZE_SCOPE_ID( AddressFamily : ADDRESS_FAMILY; + Address : PUCHAR; ScopeId : PSCOPE_ID); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if (AddressFamily = AF_INET6) then begin + IN6_UNCANONICALIZE_SCOPE_ID(PIn6Addr( Address), ScopeId); + end else begin + IN4_UNCANONICALIZE_SCOPE_ID(PInAddr( Address), ScopeId); + end; +end; +{$ENDIF} + +function IN6_IS_ADDR_MC_NODELOCAL(const a: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if a <> nil then begin + Result := IN6_IS_ADDR_MULTICAST(a) and ((a^.s6_bytes[1] and $F) = 1); + end else begin + Result := False; + end; +end; + +function IN6_IS_ADDR_MC_LINKLOCAL(const a: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if a <> nil then begin + Result := IN6_IS_ADDR_MULTICAST(a) and ((a^.s6_bytes[1] and $F) = 2); + end else begin + Result := False; + end; +end; + +function IN6_IS_ADDR_MC_SITELOCAL(const a: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if a <> nil then begin + Result := IN6_IS_ADDR_MULTICAST(a) and ((a^.s6_bytes[1] and $F) = 5); + end else begin + Result := False; + end; +end; + +function IN6_IS_ADDR_MC_ORGLOCAL(const a: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if a <> nil then begin + Result := IN6_IS_ADDR_MULTICAST(a) and ((a^.s6_bytes[1] and $F) = 8); + end else begin + Result := False; + end; +end; + +function IN6_IS_ADDR_MC_GLOBAL(const a: PIn6Addr): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if a <> nil then begin + Result := IN6_IS_ADDR_MULTICAST(a) and ((a^.s6_bytes[1] and $F) = $E); + end else begin + Result := False; + end; +end; + +procedure IN6_SET_ADDR_UNSPECIFIED(a : PIN6_ADDR); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(a^.s6_bytes, SizeOf(IN6_ADDR), 0 ); +end; + +procedure IN6_SET_ADDR_LOOPBACK(a : PIN6_ADDR); +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + System.FillChar(a^.s6_bytes, SizeOf(IN6_ADDR), 0 ); + a^.s6_bytes[15] := 1; +end; + +// A macro convenient for setting up NETBIOS SOCKADDRs. +procedure SET_NETBIOS_SOCKADDR(snb : PSockAddrNB; const SnbType : Word; const Name : PIdAnsiChar; const Port : TIdAnsiChar); +var + len : {$IFDEF FPC}sizeint{$ELSE}DWord{$ENDIF}; +begin + if snb <> nil then begin + snb^.snb_family := AF_NETBIOS; + snb^.snb_type := SnbType; + {$IFDEF NEXTGEN} + len := Length(Name); + {$ELSE} + len := {$IFDEF HAS_AnsiStrings_StrLen}AnsiStrings.{$ENDIF}StrLen(Name); + {$ENDIF} + if len >= NETBIOS_NAME_LENGTH-1 then begin + System.Move(Name^, snb^.snb_name, NETBIOS_NAME_LENGTH-1); + end else begin + if len > 0 then begin + System.Move(Name^, snb^.snb_name, LongInt(len)); + end; + System.FillChar((PIdAnsiChar(@snb^.snb_name)+len)^, NETBIOS_NAME_LENGTH-1-len, ' '); {Do not Localize} + end; + snb^.snb_name[NETBIOS_NAME_LENGTH-1] := Port; + end; +end; + +function GROUP_FILTER_SIZE(const numsrc : DWord) : PtrUInt; +{$IFDEF USE_INLINE}inline;{$ENDIF} +begin + Result := (SIZE_GROUP_FILTER - SIZE_SOCKADDR_STORAGE) + (numsrc * SIZE_SOCKADDR_STORAGE); +end; + +initialization + scopeid_unspecified := SCOPEID_UNSPECIFIED_INIT; + + _in4addr_any := IN4ADDR_ANY_INIT; + _in4addr_loopback := IN4ADDR_LOOPBACK_INIT; + _in4addr_broadcast := IN4ADDR_BROADCAST_INIT; + in4addr_allnodesonlink := IN4ADDR_ALLNODESONLINK_INIT; + in4addr_allroutersonlink := IN4ADDR_ALLROUTERSONLINK_INIT; + in4addr_alligmpv3routersonlink := IN4ADDR_ALLIGMPV3ROUTERSONLINK_INIT; + in4addr_allteredohostsonlink := IN4ADDR_ALLTEREDONODESONLINK_INIT; + in4addr_linklocalprefix := IN4ADDR_LINKLOCALPREFIX_INIT; + in4addr_multicastprefix := IN4ADDR_MULTICASTPREFIX_INIT; + + in6addr_any := IN6ADDR_ANY_INIT; + in6addr_loopback := IN6ADDR_LOOPBACK_INIT; + in6addr_allnodesonnode := IN6ADDR_ALLNODESONNODE_INIT; + in6addr_allnodesonlink := IN6ADDR_ALLNODESONLINK_INIT; + in6addr_allroutersonlink := IN6ADDR_ALLROUTERSONLINK_INIT; + in6addr_solicitednodemulticastprefix := IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_INIT; + in6addr_v4mappedprefix := IN6ADDR_V4MAPPEDPREFIX_INIT; + in6addr_6to4prefix := IN6ADDR_6TO4PREFIX_INIT; + in6addr_teredoprefix := IN6ADDR_TEREDOPREFIX_INIT; + + InitializeStubs; + +{$ENDIF} + +end. + diff --git a/Lib/System/IdWship6.pas b/Lib/System/IdWship6.pas index d6f93b48d..1ce77d2fe 100644 --- a/Lib/System/IdWship6.pas +++ b/Lib/System/IdWship6.pas @@ -1,1548 +1,1548 @@ -{ - $Project$ - $Workfile$ - $Revision$ - $DateUTC$ - $Id$ - - This file is part of the Indy (Internet Direct) project, and is offered - under the dual-licensing agreement described on the Indy website. - (http://www.indyproject.org/) - - Copyright: - (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. -} -{ - $Log$ -} -{ - Rev 1.0 2004.02.03 3:14:52 PM czhower - Move and updates - - Rev 1.2 10/15/2003 9:43:20 PM DSiders - Added localization comments. - - Rev 1.1 1-10-2003 19:44:28 BGooijen - fixed leak in CloseLibrary() - - Rev 1.0 11/13/2002 09:03:24 AM JPMugaas -} - -unit IdWship6; - -interface - -{$I IdCompilerDefines.inc} - -{$IFDEF WINDOWS} -{$IFDEF FPC} - {$IFDEF WIN32} - {$ALIGN OFF} - {$ELSE} - //It turns out that Win64 and WinCE require record alignment - {$PACKRECORDS C} - {$ENDIF} -{$ELSE} - {$IFDEF WIN64} - {$ALIGN ON} - {$MINENUMSIZE 4} - {$ELSE} - {$MINENUMSIZE 4} - {$IFDEF REQUIRES_PROPER_ALIGNMENT} - {$ALIGN ON} - {$ELSE} - {$ALIGN OFF} - {$WRITEABLECONST OFF} - {$ENDIF} - {$ENDIF} -{$ENDIF} - -uses - {$IFDEF HAS_TInterlocked} - syncobjs, //here to facilitate inlining with Delphi - {$ENDIF} - IdGlobal, - Windows, - IdWinsock2; - -const - Wship6_dll = 'Wship6.dll'; {do not localize} - iphlpapi_dll = 'iphlpapi.dll'; {do not localize} - fwpuclnt_dll = 'Fwpuclnt.dll'; {Do not localize} - - // Error codes from getaddrinfo(). - - //JPM - //Note that I am adding a GIA_ prefix on my own because - //some names here share some names defined in IdWinsock2 causing - //an unpredictible problem. The values are not defined the same in IdWinsock2 - {$EXTERNALSYM GIA_EAI_ADDRFAMILY} - GIA_EAI_ADDRFAMILY = 1 ; // Address family for nodename not supported. - {$EXTERNALSYM GIA_EAI_AGAIN} - GIA_EAI_AGAIN = 2 ; // Temporary failure in name resolution. - {$EXTERNALSYM GIA_EAI_BADFLAGS} - GIA_EAI_BADFLAGS = 3 ; // Invalid value for ai_flags. - {$EXTERNALSYM GIA_EAI_FAIL} - GIA_EAI_FAIL = 4 ; // Non-recoverable failure in name resolution. - {$EXTERNALSYM GIA_EAI_FAMILY} - GIA_EAI_FAMILY = 5 ; // Address family ai_family not supported. - {$EXTERNALSYM GIA_EAI_MEMORY} - GIA_EAI_MEMORY = 6 ; // Memory allocation failure. - {$EXTERNALSYM GIA_EAI_NODATA} - GIA_EAI_NODATA = 7 ; // No address associated with nodename. - {$EXTERNALSYM GIA_EAI_NONAME} - GIA_EAI_NONAME = 8 ; // Nodename nor servname provided, or not known. - {$EXTERNALSYM GIA_EAI_SERVICE} - GIA_EAI_SERVICE = 9 ; // Servname not supported for ai_socktype. - {$EXTERNALSYM GIA_EAI_SOCKTYPE} - GIA_EAI_SOCKTYPE = 10 ; // Socket type ai_socktype not supported. - {$EXTERNALSYM GIA_EAI_SYSTEM} - GIA_EAI_SYSTEM = 11 ; // System error returned in errno. - - {$EXTERNALSYM NI_MAXHOST} - NI_MAXHOST = 1025; // Max size of a fully-qualified domain name. - {$EXTERNALSYM NI_MAXSERV} - NI_MAXSERV = 32; // Max size of a service name. - - // Flags for getnameinfo(). - - {$EXTERNALSYM NI_NOFQDN} - NI_NOFQDN = $1 ; // Only return nodename portion for local hosts. - {$EXTERNALSYM NI_NUMERICHOST} - NI_NUMERICHOST = $2 ; // Return numeric form of the host's address. - {$EXTERNALSYM NI_NAMEREQD} - NI_NAMEREQD = $4 ; // Error if the host's name not in DNS. - {$EXTERNALSYM NI_NUMERICSERV} - NI_NUMERICSERV = $8 ; // Return numeric form of the service (port #). - {$EXTERNALSYM NI_DGRAM} - NI_DGRAM = $10 ; // Service is a datagram service. - - //JPM - These may not be supported in WinCE 4.2 - {$EXTERNALSYM PROTECTION_LEVEL_RESTRICTED} - PROTECTION_LEVEL_RESTRICTED = 30; //* for Intranet apps /* - {$EXTERNALSYM PROTECTION_LEVEL_DEFAULT} - PROTECTION_LEVEL_DEFAULT = 20; //* default level /* - {$EXTERNALSYM PROTECTION_LEVEL_UNRESTRICTED} - PROTECTION_LEVEL_UNRESTRICTED = 10; //* for peer-to-peer apps /* - - {$EXTERNALSYM SOCKET_SETTINGS_GUARANTEE_ENCRYPTION} - SOCKET_SETTINGS_GUARANTEE_ENCRYPTION = $00000001; - {$EXTERNALSYM SOCKET_SETTINGS_ALLOW_INSECURE} - SOCKET_SETTINGS_ALLOW_INSECURE = $00000002; - - {$EXTERNALSYM SOCKET_INFO_CONNECTION_SECURED} - SOCKET_INFO_CONNECTION_SECURED = $00000001; - {$EXTERNALSYM SOCKET_INFO_CONNECTION_ENCRYPTED} - SOCKET_INFO_CONNECTION_ENCRYPTED = $00000002; - -type - // RLebeau: find a better place for this - {$IFNDEF HAS_UInt64} - {$EXTERNALSYM UINT64} - UINT64 = {$IFDEF HAS_QWord}QWord{$ELSE}Int64{$ENDIF}; - {$ENDIF} - - {$NODEFINE PPaddrinfo} - PPaddrinfo = ^PAddrInfo; - {$NODEFINE PPaddrinfoW} - PPaddrinfoW = ^PAddrInfoW; - - {$IFNDEF WINCE} - {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL} - {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL_DEFAULT} - {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL_IPSEC} - {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL_INVALID} - SOCKET_SECURITY_PROTOCOL = ( - SOCKET_SECURITY_PROTOCOL_DEFAULT, SOCKET_SECURITY_PROTOCOL_IPSEC, SOCKET_SECURITY_PROTOCOL_INVALID - ); - - {$EXTERNALSYM SOCKET_SECURITY_SETTINGS_IPSEC} - SOCKET_SECURITY_SETTINGS_IPSEC = record - SecurityProtocol : SOCKET_SECURITY_PROTOCOL; - SecurityFlags : ULONG; - IpsecFlags : ULONG; - AuthipMMPolicyKey : TGUID; - AuthipQMPolicyKey : TGUID; - Reserved : TGUID; - Reserved2 : UINT64; - UserNameStringLen : ULONG; - DomainNameStringLen : ULONG; - PasswordStringLen : ULONG; - // wchar_t AllStrings[0]; - end; - {$EXTERNALSYM PSOCKET_SECURITY_SETTINGS_IPSEC} - PSOCKET_SECURITY_SETTINGS_IPSEC = ^SOCKET_SECURITY_SETTINGS_IPSEC; - {$EXTERNALSYM SOCKET_SECURITY_SETTINGS} - SOCKET_SECURITY_SETTINGS = record - SecurityProtocol : SOCKET_SECURITY_PROTOCOL; - SecurityFlags : ULONG; - end; - {$EXTERNALSYM PSOCKET_SECURITY_SETTINGS} - PSOCKET_SECURITY_SETTINGS = ^SOCKET_SECURITY_SETTINGS; - {$EXTERNALSYM SOCKET_PEER_TARGET_NAME} - SOCKET_PEER_TARGET_NAME = record - SecurityProtocol : SOCKET_SECURITY_PROTOCOL; - PeerAddress : SOCKADDR_STORAGE; - PeerTargetNameStringLen : ULONG; - //wchar_t AllStrings[0]; - end; - {$EXTERNALSYM PSOCKET_PEER_TARGET_NAME} - PSOCKET_PEER_TARGET_NAME = ^SOCKET_PEER_TARGET_NAME; - - {$EXTERNALSYM SOCKET_SECURITY_QUERY_INFO} - SOCKET_SECURITY_QUERY_INFO = record - SecurityProtocol : SOCKET_SECURITY_PROTOCOL; - Flags : ULONG; - PeerApplicationAccessTokenHandle : UINT64; - PeerMachineAccessTokenHandle : UINT64; - end; - {$EXTERNALSYM PSOCKET_SECURITY_QUERY_INFO} - PSOCKET_SECURITY_QUERY_INFO = ^SOCKET_SECURITY_QUERY_INFO; - {$EXTERNALSYM SOCKET_SECURITY_QUERY_TEMPLATE} - SOCKET_SECURITY_QUERY_TEMPLATE = record - SecurityProtocol : SOCKET_SECURITY_PROTOCOL; - PeerAddress : SOCKADDR_STORAGE; - PeerTokenAccessMask : ULONG; - end; - {$EXTERNALSYM PSOCKET_SECURITY_QUERY_TEMPLATE} - PSOCKET_SECURITY_QUERY_TEMPLATE = ^SOCKET_SECURITY_QUERY_TEMPLATE; - -//callback defs -type - {$EXTERNALSYM LPLOOKUPSERVICE_COMPLETION_ROUTINE} - LPLOOKUPSERVICE_COMPLETION_ROUTINE = procedure (const dwError, dwBytes : DWORD; lpOverlapped : LPWSAOVERLAPPED); stdcall; -{$ENDIF} - -type - {$EXTERNALSYM LPFN_GETADDRINFO} - LPFN_GETADDRINFO = function(NodeName: PIdAnsiChar; ServiceName: PIdAnsiChar; Hints: Paddrinfo; ppResult: PPaddrinfo): Integer; stdcall; - {$EXTERNALSYM LPFN_GETADDRINFOW} - LPFN_GETADDRINFOW = function(NodeName: PWideChar; ServiceName: PWideChar; Hints: PaddrinfoW; ppResult: PPaddrinfoW): Integer; stdcall; - {$EXTERNALSYM LPFN_GETNAMEINFO} - //The IPv6 preview for Win2K defines hostlen and servelen as size_t but do not use them - //for these definitions as the newer SDK's define those as DWORD. - LPFN_GETNAMEINFO = function(sa: psockaddr; salen: u_int; host: PIdAnsiChar; hostlen: u_int; serv: PIdAnsiChar; servlen: u_int; flags: Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_GETNAMEINFOW} - LPFN_GETNAMEINFOW = function(sa: psockaddr; salen: u_int; host: PWideChar; hostlen: u_int; serv: PWideChar; servlen: u_int; flags: Integer): Integer; stdcall; - {$EXTERNALSYM LPFN_FREEADDRINFO} - LPFN_FREEADDRINFO = procedure(ai: Paddrinfo); stdcall; - {$EXTERNALSYM LPFN_FREEADDRINFOW} - LPFN_FREEADDRINFOW = procedure(ai: PaddrinfoW); stdcall; - -//function GetAdaptersAddresses( Family:ULONG; Flags:ULONG; Reserved:Pointer; pAdapterAddresses: PIP_ADAPTER_ADDRESSES; pOutBufLen:PULONG):ULONG;stdcall; external iphlpapi_dll; - -{ the following are not used, nor tested} -{function getipnodebyaddr(const src:pointer; len:integer; af:integer;var error_num:integer) :phostent;stdcall; external Wship6_dll; -procedure freehostent(ptr:phostent);stdcall; external Wship6_dll; -function inet_pton(af:integer; const src:pchar; dst:pointer):integer;stdcall; external Wship6_dll; -function inet_ntop(af:integer; const src:pointer; dst:pchar;size:integer):pchar;stdcall; external Wship6_dll; -} - {$IFNDEF WINCE} - {$EXTERNALSYM LPFN_INET_PTON} - LPFN_INET_PTON = function (af: Integer; const src: PIdAnsiChar; dst: Pointer): Integer; stdcall; - {$EXTERNALSYM LPFN_INET_PTONW} - LPFN_INET_PTONW = function (af: Integer; const src: PWideChar; dst: Pointer): Integer; stdcall; - {$EXTERNALSYM LPFN_INET_NTOP} - LPFN_INET_NTOP = function (af: Integer; const src: Pointer; dst: PIdAnsiChar; size: size_t): PIdAnsiChar; stdcall; - {$EXTERNALSYM LPFN_INET_NTOPW} - LPFN_INET_NTOPW = function (af: Integer; const src: Pointer; dst: PWideChar; size: size_t): PIdAnsiChar; stdcall; - -{ end the following are not used, nor tested} -//These are provided in case we need them later -//Windows Vista - {$EXTERNALSYM LPFN_GETADDRINFOEXA} - LPFN_GETADDRINFOEXA = function(pName : PIdAnsiChar; pServiceName : PIdAnsiChar; - const dwNameSpace: DWord; lpNspId : LPGUID; hints : PADDRINFOEXA; - var ppResult : PADDRINFOEXA; timeout : Ptimeval; lpOverlapped : LPWSAOVERLAPPED; - lpCompletionRoutine : LPLOOKUPSERVICE_COMPLETION_ROUTINE; - lpNameHandle : PHandle) : Integer; stdcall; - {$EXTERNALSYM LPFN_GETADDRINFOEXW} - LPFN_GETADDRINFOEXW = function(pName : PWideChar; pServiceName : PWideChar; - const dwNameSpace: DWord; lpNspId : LPGUID;hints : PADDRINFOEXW; - var ppResult : PADDRINFOEXW; timeout : Ptimeval; lpOverlapped : LPWSAOVERLAPPED; - lpCompletionRoutine : LPLOOKUPSERVICE_COMPLETION_ROUTINE; - lpNameHandle : PHandle) : Integer; stdcall; - {$EXTERNALSYM LPFN_SETADDRINFOEXA} - LPFN_SETADDRINFOEXA= function(pName : PIdAnsiChar; pServiceName : PIdAnsiChar; - pAddresses : PSOCKET_ADDRESS; const dwAddressCount : DWord; lpBlob : LPBLOB; - const dwFlags : DWord; const dwNameSpace : DWord; lpNspId : LPGUID; - timeout : Ptimeval; - lpOverlapped : LPWSAOVERLAPPED; - lpCompletionRoutine : LPLOOKUPSERVICE_COMPLETION_ROUTINE; lpNameHandle : PHandle) : Integer; stdcall; - {$EXTERNALSYM LPFN_SETADDRINFOEXW} - LPFN_SETADDRINFOEXW= function(pName : PWideChar; pServiceName : PWideChar; - pAddresses : PSOCKET_ADDRESS; const dwAddressCount : DWord; lpBlob : LPBLOB; - const dwFlags : DWord; const dwNameSpace : DWord; lpNspId : LPGUID; - timeout : Ptimeval; - lpOverlapped : LPWSAOVERLAPPED; - lpCompletionRoutine : LPLOOKUPSERVICE_COMPLETION_ROUTINE; lpNameHandle : PHandle) : Integer; stdcall; - - {$EXTERNALSYM LPFN_FREEADDRINFOEX} - LPFN_FREEADDRINFOEX = procedure(pAddrInfoEx : PADDRINFOEXA) ; stdcall; - {$EXTERNALSYM LPFN_FREEADDRINFOEXW} - LPFN_FREEADDRINFOEXW = procedure(pAddrInfoEx : PADDRINFOEXW) ; stdcall; - - {$EXTERNALSYM LPFN_GETADDRINFOEX} - {$EXTERNALSYM LPFN_SETADDRINFOEX} - {$IFDEF UNICODE} - LPFN_GETADDRINFOEX = LPFN_GETADDRINFOEXW; - LPFN_SETADDRINFOEX = LPFN_SETADDRINFOEXW; - {$ELSE} - LPFN_GETADDRINFOEX = LPFN_GETADDRINFOEXA; - LPFN_SETADDRINFOEX = LPFN_SETADDRINFOEXA; - {$ENDIF} - - // Fwpuclnt.dll - API - {$EXTERNALSYM LPFN_WSASetSocketSecurity} - LPFN_WSASetSocketSecurity = function (socket : TSocket; - SecuritySettings : PSOCKET_SECURITY_SETTINGS; const SecuritySettingsLen : ULONG; - OVERLAPPED : LPWSAOVERLAPPED; CompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSADELETESOCKETPEERTARGETNAME} - LPFN_WSADELETESOCKETPEERTARGETNAME = function (Socket : TSocket; - PeerAddr : Psockaddr; PeerAddrLen : ULONG; - Overlapped : LPWSAOVERLAPPED; CompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; - {$EXTERNALSYM LPFN_WSASETSOCKETPEERTARGETNAME} - LPFN_WSASETSOCKETPEERTARGETNAME = function (Socket : TSocket; - PeerTargetName : PSOCKET_PEER_TARGET_NAME; PeerTargetNameLen : ULONG; - Overlapped : LPWSAOVERLAPPED; CompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSAIMPERSONATESOCKETPEER} - LPFN_WSAIMPERSONATESOCKETPEER = function (Socket : TSocket; - PeerAddress : Psockaddr; peerAddressLen : ULONG) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSAQUERYSOCKETSECURITY} - LPFN_WSAQUERYSOCKETSECURITY = function (Socket : TSocket; - SecurityQueryTemplate : PSOCKET_SECURITY_QUERY_TEMPLATE; const SecurityQueryTemplateLen : ULONG; - SecurityQueryInfo : PSOCKET_SECURITY_QUERY_INFO; var SecurityQueryInfoLen : ULONG; - Overlapped : LPWSAOVERLAPPED; CompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; - {$EXTERNALSYM LPFN_WSAREVERTIMPERSONATION} - LPFN_WSAREVERTIMPERSONATION = function : Integer; stdcall; -{$ENDIF} - -const - {$NODEFINE fn_GetAddrInfo} - {$NODEFINE fn_getnameinfo} - {$NODEFINE fn_freeaddrinfo} - {$IFNDEF WINCE} - {$NODEFINE fn_GetAddrInfoEx} - {$NODEFINE fn_SetAddrInfoEx} - {$NODEFINE fn_FreeAddrInfoEx} - {$NODEFINE fn_inet_pton} - {$NODEFINE fn_inet_ntop} - {$ENDIF} - {$IFDEF UNICODE} - // WinCE does not support GetAddrInfoW(), GetNameInfoW(), or FreeAddrInfoW(). - // To support IPv6 on WinCE when UNICODE is defined, we will use our own - // wrappers that internally call WinCE's functions... - fn_GetAddrInfo = {$IFDEF WINCE}'getaddrinfo'{$ELSE}'GetAddrInfoW'{$ENDIF}; - fn_getnameinfo = {$IFDEF WINCE}'getnameinfo'{$ELSE}'GetNameInfoW'{$ENDIF}; - fn_freeaddrinfo = {$IFDEF WINCE}'freeaddrinfo'{$ELSE}'FreeAddrInfoW'{$ENDIF}; - {$IFNDEF WINCE} - fn_GetAddrInfoEx = 'GetAddrInfoExW'; - fn_SetAddrInfoEx = 'SetAddrInfoExW'; - fn_FreeAddrInfoEx = 'FreeAddrInfoExW'; - fn_inet_pton = 'InetPtonW'; - fn_inet_ntop = 'InetNtopW'; - {$ENDIF} - {$ELSE} - fn_GetAddrInfo = 'getaddrinfo'; - fn_getnameinfo = 'getnameinfo'; - fn_freeaddrinfo = 'freeaddrinfo'; - {$IFNDEF WINCE} - fn_GetAddrInfoEx = 'GetAddrInfoExA'; - fn_SetAddrInfoEx = 'SetAddrInfoExA'; - fn_FreeAddrInfoEx = 'FreeAddrInfoEx'; - fn_inet_pton = 'inet_pton'; - fn_inet_ntop = 'inet_ntop'; - {$ENDIF} - {$ENDIF} - -{$UNDEF WINCE_UNICODE} -{$IFDEF WINCE} - {$IFDEF UNICODE} - {$DEFINE WINCE_UNICODE} - {$ENDIF} -{$ENDIF} - -var - {$EXTERNALSYM getaddrinfo} - {$EXTERNALSYM getnameinfo} - {$EXTERNALSYM freeaddrinfo} - {$IFNDEF WINCE} - {$EXTERNALSYM inet_pton} - {$EXTERNALSYM inet_ntop} - {$ENDIF} - {$IFDEF UNICODE} - {$IFDEF WINCE} - getaddrinfoCE: LPFN_GETADDRINFO = nil; - getnameinfoCE: LPFN_GETNAMEINFO = nil; - freeaddrinfoCE: LPFN_FREEADDRINFO = nil; - {$ENDIF} - getaddrinfo: LPFN_GETADDRINFOW = nil; - getnameinfo: LPFN_GETNAMEINFOW = nil; - freeaddrinfo: LPFN_FREEADDRINFOW = nil; - {$IFNDEF WINCE} - //These are here for completeness - inet_pton : LPFN_inet_ptonW = nil; - inet_ntop : LPFN_inet_ntopW = nil; - {$ENDIF} - {$ELSE} - getaddrinfo: LPFN_GETADDRINFO = nil; - getnameinfo: LPFN_GETNAMEINFO = nil; - freeaddrinfo: LPFN_FREEADDRINFO = nil; - {$IFNDEF WINCE} - //These are here for completeness - inet_pton : LPFN_inet_pton = nil; - inet_ntop : LPFN_inet_ntop = nil; - {$ENDIF} - {$ENDIF} - {$IFNDEF WINCE} - { - IMPORTANT!!! - - These are Windows Vista functions and there's no guarantee that you will have - them so ALWAYS check the function pointer before calling them. - } - {$EXTERNALSYM GetAddrInfoEx} - GetAddrInfoEx : LPFN_GETADDRINFOEX = nil; - {$EXTERNALSYM SetAddrInfoEx} - SetAddrInfoEx : LPFN_SETADDRINFOEX = nil; - {$EXTERNALSYM FreeAddrInfoEx} - //You can't alias the LPFN for this because the ASCII version of this - //does not end with an "a" - {$IFDEF UNICODE} - FreeAddrInfoEx : LPFN_FREEADDRINFOEXW = nil; - {$ELSE} - FreeAddrInfoEx : LPFN_FREEADDRINFOEX = nil; - {$ENDIF} - - //Fwpuclnt.dll available for Windows Vista and later - {$EXTERNALSYM WSASetSocketSecurity} - WSASetSocketSecurity : LPFN_WSASetSocketSecurity = nil; - {$EXTERNALSYM WSASETSOCKETPEERTARGETNAME} - WSASetSocketPeerTargetName : LPFN_WSASETSOCKETPEERTARGETNAME = nil; - {$EXTERNALSYM WSADELETESOCKETPEERTARGETNAME} - WSADeleteSocketPeerTargetName : LPFN_WSADELETESOCKETPEERTARGETNAME = nil; - {$EXTERNALSYM WSAImpersonateSocketPeer} - WSAImpersonateSocketPeer : LPFN_WSAIMPERSONATESOCKETPEER = nil; - {$EXTERNALSYM WSAQUERYSOCKETSECURITY} - WSAQUERYSOCKETSECURITY : LPFN_WSAQUERYSOCKETSECURITY = nil; - {$EXTERNALSYM WSAREVERTIMPERSONATION} - WSARevertImpersonation : LPFN_WSAREVERTIMPERSONATION = nil; - {$ENDIF} - -var - GIdIPv6FuncsAvailable: Boolean = False{$IFDEF HAS_DEPRECATED}{$IFDEF USE_SEMICOLON_BEFORE_DEPRECATED};{$ENDIF} deprecated{$ENDIF}; - -function gaiErrorToWsaError(const gaiError: Integer): Integer; - -//We want to load this library only after loading Winsock and unload immediately -//before unloading Winsock. -procedure InitLibrary; -procedure CloseLibrary; - -{$ENDIF} -implementation -{$IFDEF WINDOWS} - -uses - SysUtils; - -var - hWship6Dll : TIdLibHandle = IdNilHandle; // Wship6.dll handle - //Use this instead of hWship6Dll because this will point to the correct lib. - hProcHandle : TIdLibHandle = IdNilHandle; - {$IFNDEF WINCE} - hfwpuclntDll : TIdLibHandle = IdNilHandle; - {$ENDIF} - -function gaiErrorToWsaError(const gaiError: Integer): Integer; -begin - case gaiError of - GIA_EAI_ADDRFAMILY: Result := 0; // TODO: find a decent error for here - GIA_EAI_AGAIN: Result := WSATRY_AGAIN; - GIA_EAI_BADFLAGS: Result := WSAEINVAL; - GIA_EAI_FAIL: Result := WSANO_RECOVERY; - GIA_EAI_FAMILY: Result := WSAEAFNOSUPPORT; - GIA_EAI_MEMORY: Result := WSA_NOT_ENOUGH_MEMORY; - GIA_EAI_NODATA: Result := WSANO_DATA; - GIA_EAI_NONAME: Result := WSAHOST_NOT_FOUND; - GIA_EAI_SERVICE: Result := WSATYPE_NOT_FOUND; - GIA_EAI_SOCKTYPE: Result := WSAESOCKTNOSUPPORT; - GIA_EAI_SYSTEM: - begin - Result := 0; // avoid warning - IndyRaiseLastError; - end; - else - Result := gaiError; - end; -end; - -procedure CloseLibrary; -var - h : TIdLibHandle; -begin - h := InterlockedExchangeTLibHandle(hWship6Dll, IdNilHandle); - if h <> IdNilHandle then begin - FreeLibrary(h); - end; - {$IFNDEF WINCE} - h := InterlockedExchangeTLibHandle(hfwpuclntDll, IdNilHandle); - if h <> IdNilHandle then begin - FreeLibrary(h); - end; - {$ENDIF} - - {$I IdSymbolDeprecatedOff.inc} - GIdIPv6FuncsAvailable := False; - {$I IdSymbolDeprecatedOn.inc} - - {$IFDEF WINCE_UNICODE} - getaddrinfoCE := nil; - getnameinfoCE := nil; - freeaddrinfoCE := nil; - {$ENDIF} - getaddrinfo := nil; - getnameinfo := nil; - freeaddrinfo := nil; - {$IFNDEF WINCE} - inet_pton := nil; - inet_ntop := nil; - GetAddrInfoEx := nil; - SetAddrInfoEx := nil; - FreeAddrInfoEx := nil; - WSASetSocketPeerTargetName := nil; - WSADeleteSocketPeerTargetName := nil; - WSAImpersonateSocketPeer := nil; - WSAQuerySocketSecurity := nil; - WSARevertImpersonation := nil; - {$ENDIF} -end; - -{$IFDEF FPC} //{$IFDEF STRING_IS_ANSI} - {$IFDEF UNICODE} - -// FreePascal does not have PWideChar overloads of these functions - -function StrComp(const Str1, Str2: PWideChar): Integer; overload; -var - P1, P2: PWideChar; -begin - P1 := Str1; - P2 := Str2; - while True do - begin - if (P1^ <> P2^) or (P1^ = #0) then - begin - Result := Ord(P1^) - Ord(P2^); - Exit; - end; - Inc(P1); - Inc(P2); - end; - Result := 0; -end; - -function StrScan(const Str: PWideChar; Chr: WideChar): PWideChar; overload; -begin - Result := Str; - while Result^ <> #0 do - begin - if Result^ = Chr then begin - Exit; - end; - Inc(Result); - end; - if Chr <> #0 then begin - Result := nil; - end; -end; - - {$ENDIF} -{$ENDIF} - -// The IPv6 functions were added to the Ws2_32.dll on Windows XP and later. -// To execute an application that uses these functions on earlier versions of -// Windows, the functions are defined as inline functions in the Wspiapi.h file. -// At runtime, the functions are implemented in such a way that if the Ws2_32.dll -// or the Wship6.dll (the file containing the functions in the IPv6 Technology -// Preview for Windows 2000) does not include them, then versions are implemented -// inline based on code in the Wspiapi.h header file. This inline code will be -// used on older Windows platforms that do not natively support the functions. - -// RLebeau: Wspiapi.h only defines Ansi versions of the legacy functions, but we -// need to handle Unicode as well... - -function WspiapiMalloc(tSize: size_t): Pointer; -begin - try - GetMem(Result, tSize); - ZeroMemory(Result, tSize); - except - Result := nil; - end; -end; - -procedure WspiapiFree(p: Pointer); -begin - FreeMem(p); -end; - -procedure WspiapiSwap(var a, b, c: PIdPlatformChar); - {$IFDEF USE_INLINE}inline;{$ENDIF} -begin - c := a; - a := b; - b := c; -end; - -function WspiapiStrdup(const pszString: PIdPlatformChar): PIdPlatformChar; stdcall; -var - pszMemory: PIdPlatformChar; - cchMemory: size_t; -begin - if pszString = nil then begin - Result := nil; - Exit; - end; - - cchMemory := StrLen(pszString) + 1; - pszMemory := PIdPlatformChar(WspiapiMalloc(cchMemory * SizeOf(TIdPlatformChar))); - if pszMemory = nil then begin - Result := nil; - Exit; - end; - - StrLCopy(pszMemory, pszString, cchMemory); - Result := pszMemory; -end; - -function WspiapiParseV4Address(const pszAddress: PIdPlatformChar; var pdwAddress: DWORD): BOOL; stdcall; -var - dwAddress: DWORD; - pcNext: PIdPlatformChar; - iCount: Integer; - {$IFDEF USE_MARSHALLED_PTRS} - M: TMarshaller; - {$ENDIF} -begin - iCount := 0; - - // ensure there are 3 '.' (periods) - pcNext := pszAddress; - while pcNext^ <> TIdPlatformChar(0) do begin - if pcNext^ = '.' then begin - Inc(iCount); - end; - Inc(pcNext); - end; - if iCount <> 3 then begin - Result := FALSE; - Exit; - end; - - // return an error if dwAddress is INADDR_NONE (255.255.255.255) - // since this is never a valid argument to getaddrinfo. - dwAddress := inet_addr( - {$IFDEF USE_MARSHALLED_PTRS} - M.AsAnsi(pszAddress).ToPointer - {$ELSE} - {$IFDEF UNICODE} - PIdAnsiChar(AnsiString(pszAddress)) // explicit convert to Ansi - {$ELSE} - pszAddress - {$ENDIF} - {$ENDIF} - ); - if dwAddress = INADDR_NONE then begin - Result := FALSE; - Exit; - end; - - pdwAddress := dwAddress; - Result := TRUE; -end; - -function WspiapiNewAddrInfo(iSocketType, iProtocol: Integer; wPort: WORD; dwAddress: DWORD): {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}; stdcall; -var - ptNew: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}; - ptAddress: PSockAddrIn; -begin - // allocate a new addrinfo structure. - {$IFDEF UNICODE} - ptNew := PaddrinfoW(WspiapiMalloc(SizeOf(addrinfoW))); - {$ELSE} - ptNew := Paddrinfo(WspiapiMalloc(SizeOf(addrinfo))); - {$ENDIF} - if ptNew = nil then begin - Result := nil; - Exit; - end; - - ptAddress := PSockAddrIn(WspiapiMalloc(SizeOf(sockaddr_in))); - if ptAddress = nil then begin - WspiapiFree(ptNew); - Result := nil; - Exit; - end; - ptAddress^.sin_family := AF_INET; - ptAddress^.sin_port := wPort; - ptAddress^.sin_addr.s_addr := dwAddress; - - // fill in the fields... - ptNew^.ai_family := PF_INET; - ptNew^.ai_socktype := iSocketType; - ptNew^.ai_protocol := iProtocol; - ptNew^.ai_addrlen := SizeOf(sockaddr_in); - ptNew^.ai_addr := Psockaddr(ptAddress); - - Result := ptNew; -end; - -function WspiapiQueryDNS(const pszNodeName: PIdPlatformChar; iSocketType, iProtocol: Integer; - wPort: WORD; pszAlias: PIdPlatformChar; var pptResult: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}): Integer; stdcall; -var - pptNext: {$IFDEF UNICODE}PPaddrinfoW{$ELSE}PPaddrinfo{$ENDIF}; - ptHost: Phostent; - ppAddresses: ^PInAddr; - {$IFDEF USE_MARSHALLED_PTRS} - M: TMarshaller; - {$ENDIF} -begin - pptNext := @pptResult; - - pptNext^ := nil; - pszAlias^ := TIdPlatformChar(0); - - ptHost := gethostbyname( - {$IFDEF USE_MARSHALLED_PTRS} - M.AsAnsi(pszNodeName).ToPointer - {$ELSE} - {$IFDEF UNICODE} - PIdAnsiChar(AnsiString(pszNodeName)) // explicit convert to Ansi - {$ELSE} - pszNodeName - {$ENDIF} - {$ENDIF} - ); - if ptHost <> nil then begin - if (ptHost^.h_addrtype = AF_INET) and (ptHost^.h_length = SizeOf(in_addr)) then begin - ppAddresses := Pointer(ptHost^.h_address_list); - while ppAddresses^ <> nil do begin - // create an addrinfo structure... - pptNext^ := WspiapiNewAddrInfo(iSocketType, iProtocol, wPort, ppAddresses^^.s_addr); - if pptNext^ = nil then begin - Result := EAI_MEMORY; - Exit; - end; - - pptNext := @((pptNext^)^.ai_next); - Inc(ppAddresses); - end; - end; - - // pick up the canonical name. - StrLCopy(pszAlias, - {$IFNDEF UNICODE} - ptHost^.h_name - {$ELSE} - PIdPlatformChar(TIdPlatformString(ptHost^.h_name)) - {$ENDIF} - , NI_MAXHOST); - - Result := 0; - Exit; - end; - - case WSAGetLastError() of - WSAHOST_NOT_FOUND: Result := EAI_NONAME; - WSATRY_AGAIN: Result := EAI_AGAIN; - WSANO_RECOVERY: Result := EAI_FAIL; - WSANO_DATA: Result := EAI_NODATA; - else - Result := EAI_NONAME; - end; -end; - -function WspiapiLookupNode(const pszNodeName: PIdPlatformChar; iSocketType: Integer; - iProtocol: Integer; wPort: WORD; bAI_CANONNAME: BOOL; var pptResult: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}): Integer; stdcall; -var - iError: Integer; - iAliasCount: Integer; - szFQDN1: array[0..NI_MAXHOST-1] of TIdPlatformChar; - szFQDN2: array[0..NI_MAXHOST-1] of TIdPlatformChar; - pszName: PIdPlatformChar; - pszAlias: PIdPlatformChar; - pszScratch: PIdPlatformChar; -begin - iAliasCount := 0; - - ZeroMemory(@szFQDN1, SizeOf(szFQDN1)); - ZeroMemory(@szFQDN2, SizeOf(szFQDN2)); - pszName := @szFQDN1[0]; - pszAlias := @szFQDN2[0]; - pszScratch := nil; - StrLCopy(pszName, pszNodeName, NI_MAXHOST); - - repeat - iError := WspiapiQueryDNS(pszNodeName, iSocketType, iProtocol, wPort, pszAlias, pptResult); - if iError <> 0 then begin - Break; - end; - - // if we found addresses, then we are done. - if pptResult <> nil then begin - Break; - end; - - // stop infinite loops due to DNS misconfiguration. there appears - // to be no particular recommended limit in RFCs 1034 and 1035. - if (StrLen(pszAlias) = 0) or (StrComp(pszName, pszAlias) = 0) then begin - iError := EAI_FAIL; - Break; - end; - Inc(iAliasCount); - if iAliasCount = 16 then begin - iError := EAI_FAIL; - Break; - end; - - // there was a new CNAME, look again. - WspiapiSwap(pszName, pszAlias, pszScratch); - until False; - - if (iError = 0) and bAI_CANONNAME then begin - pptResult^.ai_canonname := WspiapiStrdup(pszAlias); - if pptResult^.ai_canonname = nil then begin - iError := EAI_MEMORY; - end; - end; - - Result := iError; -end; - -function WspiapiClone(wPort: WORD; ptResult: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}): Integer; stdcall; -var - ptNext, ptNew: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}; -begin - ptNext := ptResult; - while ptNext <> nil do begin - // create an addrinfo structure... - ptNew := WspiapiNewAddrInfo(SOCK_DGRAM, ptNext^.ai_protocol, wPort, PSockAddrIn(ptNext^.ai_addr)^.sin_addr.s_addr); - if ptNew = nil then begin - Break; - end; - - // link the cloned addrinfo - ptNew^.ai_next := ptNext^.ai_next; - ptNext^.ai_next := ptNew; - ptNext := ptNew^.ai_next; - end; - - if ptNext <> nil then begin - Result := EAI_MEMORY; - Exit; - end; - - Result := 0; -end; - -procedure WspiapiLegacyFreeAddrInfo(ptHead: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}); stdcall; -var - ptNext: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}; -begin - ptNext := ptHead; - while ptNext <> nil do - begin - if ptNext^.ai_canonname <> nil then begin - WspiapiFree(ptNext^.ai_canonname); - end; - if ptNext^.ai_addr <> nil then begin - WspiapiFree(ptNext^.ai_addr); - end; - ptHead := ptNext^.ai_next; - WspiapiFree(ptNext); - ptNext := ptHead; - end; -end; - -{$IFNDEF HAS_TryStrToInt} -// TODO: use the implementation already in IdGlobalProtocols... -function TryStrToInt(const S: string; out Value: Integer): Boolean; -{$IFDEF USE_INLINE}inline;{$ENDIF} -var - E: Integer; -begin - Val(S, Value, E); - Result := E = 0; -end; -{$ENDIF} - -function WspiapiLegacyGetAddrInfo(const pszNodeName: PIdPlatformChar; const pszServiceName: PIdPlatformChar; - const ptHints: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}; - var pptResult: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}): Integer; stdcall; -var - iError: Integer; - iFlags: Integer; - iSocketType: Integer; - iProtocol: Integer; - wPort: WORD; - iTmp: Integer; - dwAddress: DWORD; - ptService: Pservent; - bClone: BOOL; - wTcpPort: WORD; - wUdpPort: WORD; - {$IFDEF USE_MARSHALLED_PTRS} - M: TMarshaller; - {$ENDIF} -begin - iError := 0; - iFlags := 0; - iSocketType := 0; - iProtocol := 0; - wPort := 0; - dwAddress := 0; - bClone := FALSE; - wTcpPort := 0; - wUdpPort := 0; - - // initialize pptResult with default return value. - pptResult := nil; - - //////////////////////////////////////// - // validate arguments... - // - - // both the node name and the service name can't be NULL. - if (pszNodeName = nil) and (pszServiceName = nil) then begin - Result := EAI_NONAME; - Exit; - end; - - // validate hints. - if ptHints <> nil then - begin - // all members other than ai_flags, ai_family, ai_socktype - // and ai_protocol must be zero or a null pointer. - if (ptHints^.ai_addrlen <> 0) or - (ptHints^.ai_canonname <> nil) or - (ptHints^.ai_addr <> nil) or - (ptHints^.ai_next <> nil) then - begin - Result := EAI_FAIL; - Exit; - end; - - // the spec has the "bad flags" error code, so presumably we - // should check something here. insisting that there aren't - // any unspecified flags set would break forward compatibility, - // however. so we just check for non-sensical combinations. - // - // we cannot come up with a canonical name given a null node name. - iFlags := ptHints^.ai_flags; - if ((iFlags and AI_CANONNAME) <> 0) and (pszNodeName = nil) then begin - Result := EAI_BADFLAGS; - Exit; - end; - - // we only support a limited number of protocol families. - if (ptHints^.ai_family <> PF_UNSPEC) and (ptHints^.ai_family <> PF_INET) then begin - Result := EAI_FAMILY; - Exit; - end; - - // we only support only these socket types. - iSocketType := ptHints^.ai_socktype; - if (iSocketType <> 0) and - (iSocketType <> SOCK_STREAM) and - (iSocketType <> SOCK_DGRAM) and - (iSocketType <> SOCK_RAW) then - begin - Result := EAI_SOCKTYPE; - Exit; - end; - - // REVIEW: What if ai_socktype and ai_protocol are at odds? - iProtocol := ptHints^.ai_protocol; - end; - - //////////////////////////////////////// - // do service lookup... - - if pszServiceName <> nil then begin - if TryStrToInt(pszServiceName, iTmp) and (iTmp >= 0) then begin - wPort := htons(WORD(iTmp)); - //wTcpPort := wPort; // never used - wUdpPort := wPort; - if iSocketType = 0 then begin - bClone := TRUE; - iSocketType := SOCK_STREAM; - end; - end else - begin - if (iSocketType = 0) or (iSocketType = SOCK_DGRAM) then begin - ptService := getservbyname( - {$IFDEF USE_MARSHALLED_PTRS} - M.AsAnsi(pszServiceName).ToPointer - {$ELSE} - {$IFDEF UNICODE} - PIdAnsiChar(AnsiString(pszServiceName)) // explicit convert to Ansi - {$ELSE} - pszServiceName - {$ENDIF} - {$ENDIF} - , 'udp'); {do not localize} - if ptService <> nil then begin - wPort := ptService^.s_port; - wUdpPort := wPort; - end; - end; - - if (iSocketType = 0) or (iSocketType = SOCK_STREAM) then begin - ptService := getservbyname( - {$IFDEF USE_MARSHALLED_PTRS} - M.AsAnsi(pszServiceName).ToPointer - {$ELSE} - {$IFDEF UNICODE} - PIdAnsiChar(AnsiString(pszServiceName)) // explicit convert to Ansi - {$ELSE} - pszServiceName - {$ENDIF} - {$ENDIF} - , 'tcp'); {do not localize} - if ptService <> nil then begin - wPort := ptService^.s_port; - wTcpPort := wPort; - end; - end; - - // assumes 0 is an invalid service port... - if wPort = 0 then begin - Result := iif(iSocketType <> 0, EAI_SERVICE, EAI_NONAME); - Exit; - end; - - if iSocketType = 0 then begin - // if both tcp and udp, process tcp now & clone udp later. - iSocketType := iif(wTcpPort <> 0, SOCK_STREAM, SOCK_DGRAM); - bClone := (wTcpPort <> 0) and (wUdpPort <> 0); - end; - end; - end; - - //////////////////////////////////////// - // do node name lookup... - - // if we weren't given a node name, - // return the wildcard or loopback address (depending on AI_PASSIVE). - // - // if we have a numeric host address string, - // return the binary address. - // - if ((pszNodeName = nil) or WspiapiParseV4Address(pszNodeName, dwAddress)) then begin - if pszNodeName = nil then begin - dwAddress := htonl(iif((iFlags and AI_PASSIVE) <> 0, INADDR_ANY, INADDR_LOOPBACK)); - end; - - // create an addrinfo structure... - pptResult := WspiapiNewAddrInfo(iSocketType, iProtocol, wPort, dwAddress); - if pptResult = nil then begin - iError := EAI_MEMORY; - end; - - if (iError = 0) and (pszNodeName <> nil) then begin - // implementation specific behavior: set AI_NUMERICHOST - // to indicate that we got a numeric host address string. - pptResult^.ai_flags := pptResult^.ai_flags or AI_NUMERICHOST; - // return the numeric address string as the canonical name - if (iFlags and AI_CANONNAME) <> 0 then begin - pptResult^.ai_canonname := WspiapiStrdup( - {$IFNDEF UNICODE} - inet_ntoa(PInAddr(@dwAddress)^) - {$ELSE} - PWideChar(TIdUnicodeString(inet_ntoa(PInAddr(@dwAddress)^))) - {$ENDIF} - ); - if pptResult^.ai_canonname = nil then begin - iError := EAI_MEMORY; - end; - end; - end; - end - - // if we do not have a numeric host address string and - // AI_NUMERICHOST flag is set, return an error! - else if ((iFlags and AI_NUMERICHOST) <> 0) then begin - iError := EAI_NONAME; - end - - // since we have a non-numeric node name, - // we have to do a regular node name lookup. - else begin - iError := WspiapiLookupNode(pszNodeName, iSocketType, iProtocol, wPort, (iFlags and AI_CANONNAME) <> 0, pptResult); - end; - - if (iError = 0) and bClone then begin - iError := WspiapiClone(wUdpPort, pptResult); - end; - - if iError <> 0 then begin - WspiapiLegacyFreeAddrInfo(pptResult); - pptResult := nil; - end; - - Result := iError; -end; - -function iif(ATest: Boolean; const ATrue, AFalse: PIdAnsiChar): PIdAnsiChar; - {$IFDEF USE_INLINE}inline;{$ENDIF} -begin - if ATest then begin - Result := ATrue; - end else begin - Result := AFalse; - end; -end; - -function WspiapiLegacyGetNameInfo(ptSocketAddress: Psockaddr; - tSocketLength: u_int; pszNodeName: PIdPlatformChar; tNodeLength: size_t; - pszServiceName: PIdPlatformChar; tServiceLength: size_t; iFlags: Integer): Integer; stdcall; -var - ptService: Pservent; - wPort: WORD; - szBuffer: array[0..5] of TIdPlatformChar; - pszService: PIdPlatformChar; - ptHost: Phostent; - tAddress: in_addr; - pszNode: PIdPlatformChar; - pc: PIdPlatformChar; - {$IFDEF UNICODE} - tmpService: TIdUnicodeString; - tmpNode: TIdUnicodeString; - {$ENDIF} -begin - StrCopy(szBuffer, '65535'); - pszService := szBuffer; - - // sanity check ptSocketAddress and tSocketLength. - if (ptSocketAddress = nil) or (tSocketLength < SizeOf(sockaddr)) then begin - Result := EAI_FAIL; - Exit; - end; - - if ptSocketAddress^.sa_family <> AF_INET then begin - Result := EAI_FAMILY; - Exit; - end; - - if tSocketLength < SizeOf(sockaddr_in) then begin - Result := EAI_FAIL; - Exit; - end; - - if (not ((pszNodeName <> nil) and (tNodeLength > 0))) and (not ((pszServiceName <> nil) and (tServiceLength > 0))) then begin - Result := EAI_NONAME; - Exit; - end; - - // the draft has the "bad flags" error code, so presumably we - // should check something here. insisting that there aren't - // any unspecified flags set would break forward compatibility, - // however. so we just check for non-sensical combinations. - if ((iFlags and NI_NUMERICHOST) <> 0) and ((iFlags and NI_NAMEREQD) <> 0) then begin - Result := EAI_BADFLAGS; - Exit; - end; - - // translate the port to a service name (if requested). - if (pszServiceName <> nil) and (tServiceLength > 0) then begin - wPort := PSockAddrIn(ptSocketAddress)^.sin_port; - - if (iFlags and NI_NUMERICSERV) <> 0 then begin - // return numeric form of the address. - StrPLCopy(szBuffer, IntToStr(ntohs(wPort)), Length(szBuffer)); - end else - begin - // return service name corresponding to port. - ptService := getservbyport(wPort, iif((iFlags and NI_DGRAM) <> 0, 'udp', nil)); - if (ptService <> nil) and (ptService^.s_name <> nil) then begin - // lookup successful. - {$IFNDEF UNICODE} - pszService := ptService^.s_name; - {$ELSE} - tmpService := TIdUnicodeString(ptService^.s_name); - pszService := PWideChar(tmpService); - {$ENDIF} - end else begin - // DRAFT: return numeric form of the port! - StrPLCopy(szBuffer, IntToStr(ntohs(wPort)), Length(szBuffer)); - end; - end; - - if tServiceLength > size_t(StrLen(pszService)) then begin - StrLCopy(pszServiceName, pszService, tServiceLength); - end else begin - Result := EAI_FAIL; - Exit; - end; - end; - - // translate the address to a node name (if requested). - if (pszNodeName <> nil) and (tNodeLength > 0) then begin - // this is the IPv4-only version, so we have an IPv4 address. - tAddress := PSockAddrIn(ptSocketAddress)^.sin_addr; - - if (iFlags and NI_NUMERICHOST) <> 0 then begin - // return numeric form of the address. - {$IFNDEF UNICODE} - pszNode := inet_ntoa(tAddress); - {$ELSE} - tmpNode := TIdUnicodeString(inet_ntoa(tAddress)); - pszNode := PWideChar(tmpNode); - {$ENDIF} - end else - begin - // return node name corresponding to address. - ptHost := gethostbyaddr(PIdAnsiChar(@tAddress), SizeOf(in_addr), AF_INET); - if (ptHost <> nil) and (ptHost^.h_name <> nil) then begin - // DNS lookup successful. - // stop copying at a "." if NI_NOFQDN is specified. - {$IFNDEF UNICODE} - pszNode := ptHost^.h_name; - {$ELSE} - tmpNode := TIdUnicodeString(ptHost^.h_name); - pszNode := PWideChar(tmpNode); - {$ENDIF} - if (iFlags and NI_NOFQDN) <> 0 then begin - pc := StrScan(pszNode, '.'); - if pc <> nil then begin - pc^ := TIdPlatformChar(0); - end; - end; - end else - begin - // DNS lookup failed. return numeric form of the address. - if (iFlags and NI_NAMEREQD) <> 0 then begin - case WSAGetLastError() of - WSAHOST_NOT_FOUND: Result := EAI_NONAME; - WSATRY_AGAIN: Result := EAI_AGAIN; - WSANO_RECOVERY: Result := EAI_FAIL; - else - Result := EAI_NONAME; - end; - Exit; - end else begin - {$IFNDEF UNICODE} - pszNode := inet_ntoa(tAddress); - {$ELSE} - tmpNode := TIdUnicodeString(inet_ntoa(tAddress)); - pszNode := PWideChar(tmpNode); - {$ENDIF} - end; - end; - end; - - if tNodeLength > size_t(StrLen(pszNode)) then begin - StrLCopy(pszNodeName, pszNode, tNodeLength); - end else begin - Result := EAI_FAIL; - Exit; - end; - end; - - Result := 0; -end; - -{$IFDEF WINCE_UNICODE} - -function IndyStrdupAToW(const pszString: PIdAnsiChar): PWideChar; -var - szStr: TIdUnicodeString; - pszMemory: PWideChar; - cchMemory: size_t; -begin - if pszString = nil then begin - Result := nil; - Exit; - end; - - szStr := TIdUnicodeString(pszString); - cchMemory := Length(szStr) + 1; - - pszMemory := PWideChar(WspiapiMalloc(cchMemory * SizeOf(WideChar))); - if pszMemory = nil then begin - Result := nil; - Exit; - end; - - StrLCopy(pszMemory, PWideChar(szStr), cchMemory); - Result := pszMemory; -end; - -procedure IndyFreeAddrInfoW(ptHead: PaddrinfoW); stdcall; -var - ptNext: PaddrinfoW; -begin - ptNext := ptHead; - while ptNext <> nil do - begin - if ptNext^.ai_canonname <> nil then begin - WspiapiFree(ptNext^.ai_canonname); - end; - if ptNext^.ai_addr <> nil then begin - WspiapiFree(ptNext^.ai_addr); - end; - ptHead := ptNext^.ai_next; - WspiapiFree(ptNext); - ptNext := ptHead; - end; -end; - -function IndyAddrInfoConvert(AddrInfo: Paddrinfo): PaddrinfoW; -var - ptNew: PaddrinfoW; - ptAddress: Pointer; -begin - Result := nil; - - if AddrInfo = nil then begin - Exit; - end; - - // allocate a new addrinfo structure. - ptNew := PaddrinfoW(WspiapiMalloc(SizeOf(addrinfoW))); - if ptNew = nil then begin - WspiapiFree(ptNew); - Exit; - end; - - ptAddress := WspiapiMalloc(AddrInfo^.ai_addrlen); - if ptAddress = nil then begin - WspiapiFree(ptNew); - Exit; - end; - Move(AddrInfo^.ai_addr^, ptAddress^, AddrInfo^.ai_addrlen); - - // fill in the fields... - ptNew^.ai_flags := AddrInfo^.ai_flags; - ptNew^.ai_family := AddrInfo^.ai_family; - ptNew^.ai_socktype := AddrInfo^.ai_socktype; - ptNew^.ai_protocol := AddrInfo^.ai_protocol; - ptNew^.ai_addrlen := AddrInfo^.ai_addrlen; - ptNew^.ai_canonname := nil; - ptNew^.ai_addr := Psockaddr(ptAddress); - ptNew^.ai_next := nil; - - if AddrInfo^.ai_canonname <> nil then begin - ptNew^.ai_canonname := IndyStrdupAToW(AddrInfo^.ai_canonname); - if ptNew^.ai_canonname = nil then begin - IndyFreeAddrInfoW(ptNew); - Exit; - end; - end; - - if AddrInfo^.ai_next <> nil then begin - ptNew^.ai_next := IndyAddrInfoConvert(AddrInfo^.ai_next); - if ptNew^.ai_next = nil then begin - IndyFreeAddrInfoW(ptNew); - Exit; - end; - end; - - Result := ptNew; -end; - -function IndyGetAddrInfoW(const pszNodeName: PWideChar; const pszServiceName: PWideChar; - const ptHints: PaddrinfoW; var pptResult: PaddrinfoW): Integer; stdcall; -var - LNodeName: AnsiString; - LPNodeName: PIdAnsiChar; - LServiceName: AnsiString; - LPServiceName: PIdAnsiChar; - LHints: addrinfo; - LPHints: Paddrinfo; - LResult: Paddrinfo; -begin - // initialize pptResult with default return value. - pptResult := nil; - - if pszNodeName <> nil then begin - LNodeName := AnsiString(pszNodeName); - LPNodeName := PIdAnsiChar(LNodeName); - end else begin - LPNodeName := nil; - end; - - if pszServiceName <> nil then begin - LServiceName := AnsiString(pszServiceName); - LPServiceName := PIdAnsiChar(LServiceName); - end else begin - LPServiceName := nil; - end; - - if ptHints <> nil then begin - ZeroMemory(@LHints, SizeOf(LHints)); - LHints.ai_flags := ptHints^.ai_flags; - LHints.ai_family := ptHints^.ai_family; - LHints.ai_socktype := ptHints^.ai_socktype; - LHints.ai_protocol := ptHints^.ai_protocol; - LPHints := @LHints; - end else begin - LPHints := nil; - end; - - Result := getaddrinfoCE(LPNodeName, LPServiceName, LPHints, @LResult); - if Result = 0 then begin - try - pptResult := IndyAddrInfoConvert(LResult); - finally - freeaddrinfoCE(LResult); - end; - if pptResult = nil then begin - Result := EAI_MEMORY; - end; - end; -end; - -function IndyGetNameInfoW(ptSocketAddress: Psockaddr; tSocketLength: u_int; - pszNodeName: PWideChar; tNodeLength: size_t; pszServiceName: PWideChar; - tServiceLength: size_t; iFlags: Integer): Integer; stdcall; -var - LHost: array[0..NI_MAXHOST-1] of TIdAnsiChar; - LPHost: PIdAnsiChar; - LHostLen: u_int; - LServ: array[0..NI_MAXSERV-1] of TIdAnsiChar; - LPServ: PIdAnsiChar; - LServLen: u_int; -begin - if pszNodeName <> nil then - begin - LPHost := @LHost[0]; - LHostLen := Length(LHost); - end else begin - LPHost := nil; - LHostLen := 0; - end; - - if pszServiceName <> nil then - begin - LPServ := @LServ[0]; - LServLen := Length(LServ); - end else begin - LPServ := nil; - LServLen := 0; - end; - - Result := getnameinfoCE(ptSocketAddress, tSocketLength, LPHost, LHostLen, LPServ, LServLen, iFlags); - if Result = 0 then begin - if pszNodeName <> nil then begin - StrPLCopy(pszNodeName, TIdUnicodeString(LPHost), tNodeLength); - end; - if pszServiceName <> nil then begin - StrPLCopy(pszServiceName, TIdUnicodeString(LPServ), tServiceLength); - end; - end; -end; - -{$ENDIF} - -procedure InitLibrary; -var - {$IFDEF WINCE_UNICODE} - gai: LPFN_GETADDRINFO; - gni: LPFN_GETNAMEINFO; - fai: LPFN_FREEADDRINFO; - {$ELSE} - gai: {$IFDEF UNICODE}LPFN_GETADDRINFOW{$ELSE}LPFN_GETADDRINFO{$ENDIF}; - gni: {$IFDEF UNICODE}LPFN_GETNAMEINFOW{$ELSE}LPFN_GETNAMEINFO{$ENDIF}; - fai: {$IFDEF UNICODE}LPFN_FREEADDRINFOW{$ELSE}LPFN_FREEADDRINFO{$ENDIF}; - {$ENDIF} -begin -{ -IMPORTANT!!! - -I am doing things this way because the functions we want are probably in -the Winsock2 dll. If they are not there, only then do you actually want -to try the Wship6.dll. I know it's a mess but I found that the functions -may not load if they aren't in Wship6.dll (and they aren't there in some -versions of Windows). - -hProcHandle provides a transparant way of managing the two possible library -locations. hWship6Dll is kept so we can unload the Wship6.dll if necessary. -} - //Winsock2 has to be loaded by IdWinsock first. - if not IdWinsock2.Winsock2Loaded then - begin - IdWinsock2.InitializeWinSock; - end; - hProcHandle := IdWinsock2.WinsockHandle; - - gai := LoadLibFunction(hProcHandle, fn_getaddrinfo); - if not Assigned(gai) then - begin - hWship6Dll := SafeLoadLibrary(Wship6_dll); - hProcHandle := hWship6Dll; - gai := LoadLibFunction(hProcHandle, fn_getaddrinfo); - end; - - if Assigned(gai) then - begin - gni := LoadLibFunction(hProcHandle, fn_getnameinfo); - if Assigned(gni) then - begin - fai := LoadLibFunction(hProcHandle, fn_freeaddrinfo); - if Assigned(fai) then - begin - {$IFDEF WINCE_UNICODE} - getaddrinfoCE := gai; - getnameinfoCE := gni; - freeaddrinfoCE := fai; - getaddrinfo := @IndyGetAddrInfoW; - getnameinfo := @IndyGetNameInfoW; - freeaddrinfo := @IndyFreeAddrInfoW; - {$ELSE} - getaddrinfo := gai; - getnameinfo := gni; - freeaddrinfo := fai; - {$ENDIF} - - //Additional functions should be initialized here. - {$IFNDEF WINCE} - inet_pton := LoadLibFunction(hProcHandle, fn_inet_pton); - inet_ntop := LoadLibFunction(hProcHandle, fn_inet_ntop); - GetAddrInfoEx := LoadLibFunction(hProcHandle, fn_GetAddrInfoEx); - SetAddrInfoEx := LoadLibFunction(hProcHandle, fn_SetAddrInfoEx); - FreeAddrInfoEx := LoadLibFunction(hProcHandle, fn_FreeAddrInfoEx); - hfwpuclntDll := SafeLoadLibrary(fwpuclnt_dll); - if hfwpuclntDll <> IdNilHandle then - begin - WSASetSocketSecurity := LoadLibFunction(hfwpuclntDll, 'WSASetSocketSecurity'); {Do not localize} - WSAQuerySocketSecurity := LoadLibFunction(hfwpuclntDll, 'WSAQuerySocketSecurity'); {Do not localize} - WSASetSocketPeerTargetName := LoadLibFunction(hfwpuclntDll, 'WSASetSocketPeerTargetName'); {Do not localize} - WSADeleteSocketPeerTargetName := LoadLibFunction(hfwpuclntDll, 'WSADeleteSocketPeerTargetName'); {Do not localize} - WSAImpersonateSocketPeer := LoadLibFunction(hfwpuclntDll, 'WSAImpersonateSocketPeer'); {Do not localize} - WSARevertImpersonation := LoadLibFunction(hfwpuclntDll, 'WSARevertImpersonation'); {Do not localize} - end; - {$ENDIF} - - Exit; - end; - end; - end; - - CloseLibrary; - - getaddrinfo := Addr(WspiapiLegacyGetAddrInfo); - getnameinfo := Addr(WspiapiLegacyGetNameInfo); - freeaddrinfo := Addr(WspiapiLegacyFreeAddrInfo); - - {$I IdSymbolDeprecatedOff.inc} - GIdIPv6FuncsAvailable := True; - {$I IdSymbolDeprecatedOn.inc} -end; - -initialization -finalization - CloseLibrary; -{$ENDIF} -end. +{ + $Project$ + $Workfile$ + $Revision$ + $DateUTC$ + $Id$ + + This file is part of the Indy (Internet Direct) project, and is offered + under the dual-licensing agreement described on the Indy website. + (http://www.indyproject.org/) + + Copyright: + (c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved. +} +{ + $Log$ +} +{ + Rev 1.0 2004.02.03 3:14:52 PM czhower + Move and updates + + Rev 1.2 10/15/2003 9:43:20 PM DSiders + Added localization comments. + + Rev 1.1 1-10-2003 19:44:28 BGooijen + fixed leak in CloseLibrary() + + Rev 1.0 11/13/2002 09:03:24 AM JPMugaas +} + +unit IdWship6; + +interface + +{$I IdCompilerDefines.inc} + +{$IFDEF WINDOWS} +{$IFDEF FPC} + {$IFDEF WIN32} + {$ALIGN OFF} + {$ELSE} + //It turns out that Win64 and WinCE require record alignment + {$PACKRECORDS C} + {$ENDIF} +{$ELSE} + {$IFDEF WIN64} + {$ALIGN ON} + {$MINENUMSIZE 4} + {$ELSE} + {$MINENUMSIZE 4} + {$IFDEF REQUIRES_PROPER_ALIGNMENT} + {$ALIGN ON} + {$ELSE} + {$ALIGN OFF} + {$WRITEABLECONST OFF} + {$ENDIF} + {$ENDIF} +{$ENDIF} + +uses + {$IFDEF HAS_TInterlocked} + syncobjs, //here to facilitate inlining with Delphi + {$ENDIF} + IdGlobal, + Windows, + IdWinsock2; + +const + Wship6_dll = 'Wship6.dll'; {do not localize} + iphlpapi_dll = 'iphlpapi.dll'; {do not localize} + fwpuclnt_dll = 'Fwpuclnt.dll'; {Do not localize} + + // Error codes from getaddrinfo(). + + //JPM + //Note that I am adding a GIA_ prefix on my own because + //some names here share some names defined in IdWinsock2 causing + //an unpredictible problem. The values are not defined the same in IdWinsock2 + {$EXTERNALSYM GIA_EAI_ADDRFAMILY} + GIA_EAI_ADDRFAMILY = 1 ; // Address family for nodename not supported. + {$EXTERNALSYM GIA_EAI_AGAIN} + GIA_EAI_AGAIN = 2 ; // Temporary failure in name resolution. + {$EXTERNALSYM GIA_EAI_BADFLAGS} + GIA_EAI_BADFLAGS = 3 ; // Invalid value for ai_flags. + {$EXTERNALSYM GIA_EAI_FAIL} + GIA_EAI_FAIL = 4 ; // Non-recoverable failure in name resolution. + {$EXTERNALSYM GIA_EAI_FAMILY} + GIA_EAI_FAMILY = 5 ; // Address family ai_family not supported. + {$EXTERNALSYM GIA_EAI_MEMORY} + GIA_EAI_MEMORY = 6 ; // Memory allocation failure. + {$EXTERNALSYM GIA_EAI_NODATA} + GIA_EAI_NODATA = 7 ; // No address associated with nodename. + {$EXTERNALSYM GIA_EAI_NONAME} + GIA_EAI_NONAME = 8 ; // Nodename nor servname provided, or not known. + {$EXTERNALSYM GIA_EAI_SERVICE} + GIA_EAI_SERVICE = 9 ; // Servname not supported for ai_socktype. + {$EXTERNALSYM GIA_EAI_SOCKTYPE} + GIA_EAI_SOCKTYPE = 10 ; // Socket type ai_socktype not supported. + {$EXTERNALSYM GIA_EAI_SYSTEM} + GIA_EAI_SYSTEM = 11 ; // System error returned in errno. + + {$EXTERNALSYM NI_MAXHOST} + NI_MAXHOST = 1025; // Max size of a fully-qualified domain name. + {$EXTERNALSYM NI_MAXSERV} + NI_MAXSERV = 32; // Max size of a service name. + + // Flags for getnameinfo(). + + {$EXTERNALSYM NI_NOFQDN} + NI_NOFQDN = $1 ; // Only return nodename portion for local hosts. + {$EXTERNALSYM NI_NUMERICHOST} + NI_NUMERICHOST = $2 ; // Return numeric form of the host's address. + {$EXTERNALSYM NI_NAMEREQD} + NI_NAMEREQD = $4 ; // Error if the host's name not in DNS. + {$EXTERNALSYM NI_NUMERICSERV} + NI_NUMERICSERV = $8 ; // Return numeric form of the service (port #). + {$EXTERNALSYM NI_DGRAM} + NI_DGRAM = $10 ; // Service is a datagram service. + + //JPM - These may not be supported in WinCE 4.2 + {$EXTERNALSYM PROTECTION_LEVEL_RESTRICTED} + PROTECTION_LEVEL_RESTRICTED = 30; //* for Intranet apps /* + {$EXTERNALSYM PROTECTION_LEVEL_DEFAULT} + PROTECTION_LEVEL_DEFAULT = 20; //* default level /* + {$EXTERNALSYM PROTECTION_LEVEL_UNRESTRICTED} + PROTECTION_LEVEL_UNRESTRICTED = 10; //* for peer-to-peer apps /* + + {$EXTERNALSYM SOCKET_SETTINGS_GUARANTEE_ENCRYPTION} + SOCKET_SETTINGS_GUARANTEE_ENCRYPTION = $00000001; + {$EXTERNALSYM SOCKET_SETTINGS_ALLOW_INSECURE} + SOCKET_SETTINGS_ALLOW_INSECURE = $00000002; + + {$EXTERNALSYM SOCKET_INFO_CONNECTION_SECURED} + SOCKET_INFO_CONNECTION_SECURED = $00000001; + {$EXTERNALSYM SOCKET_INFO_CONNECTION_ENCRYPTED} + SOCKET_INFO_CONNECTION_ENCRYPTED = $00000002; + +type + // RLebeau: find a better place for this + {$IFNDEF HAS_UInt64} + {$EXTERNALSYM UINT64} + UINT64 = {$IFDEF HAS_QWord}QWord{$ELSE}Int64{$ENDIF}; + {$ENDIF} + + {$NODEFINE PPaddrinfo} + PPaddrinfo = ^PAddrInfo; + {$NODEFINE PPaddrinfoW} + PPaddrinfoW = ^PAddrInfoW; + + {$IFNDEF WINCE} + {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL} + {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL_DEFAULT} + {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL_IPSEC} + {$EXTERNALSYM SOCKET_SECURITY_PROTOCOL_INVALID} + SOCKET_SECURITY_PROTOCOL = ( + SOCKET_SECURITY_PROTOCOL_DEFAULT, SOCKET_SECURITY_PROTOCOL_IPSEC, SOCKET_SECURITY_PROTOCOL_INVALID + ); + + {$EXTERNALSYM SOCKET_SECURITY_SETTINGS_IPSEC} + SOCKET_SECURITY_SETTINGS_IPSEC = record + SecurityProtocol : SOCKET_SECURITY_PROTOCOL; + SecurityFlags : ULONG; + IpsecFlags : ULONG; + AuthipMMPolicyKey : TGUID; + AuthipQMPolicyKey : TGUID; + Reserved : TGUID; + Reserved2 : UINT64; + UserNameStringLen : ULONG; + DomainNameStringLen : ULONG; + PasswordStringLen : ULONG; + // wchar_t AllStrings[0]; + end; + {$EXTERNALSYM PSOCKET_SECURITY_SETTINGS_IPSEC} + PSOCKET_SECURITY_SETTINGS_IPSEC = ^SOCKET_SECURITY_SETTINGS_IPSEC; + {$EXTERNALSYM SOCKET_SECURITY_SETTINGS} + SOCKET_SECURITY_SETTINGS = record + SecurityProtocol : SOCKET_SECURITY_PROTOCOL; + SecurityFlags : ULONG; + end; + {$EXTERNALSYM PSOCKET_SECURITY_SETTINGS} + PSOCKET_SECURITY_SETTINGS = ^SOCKET_SECURITY_SETTINGS; + {$EXTERNALSYM SOCKET_PEER_TARGET_NAME} + SOCKET_PEER_TARGET_NAME = record + SecurityProtocol : SOCKET_SECURITY_PROTOCOL; + PeerAddress : SOCKADDR_STORAGE; + PeerTargetNameStringLen : ULONG; + //wchar_t AllStrings[0]; + end; + {$EXTERNALSYM PSOCKET_PEER_TARGET_NAME} + PSOCKET_PEER_TARGET_NAME = ^SOCKET_PEER_TARGET_NAME; + + {$EXTERNALSYM SOCKET_SECURITY_QUERY_INFO} + SOCKET_SECURITY_QUERY_INFO = record + SecurityProtocol : SOCKET_SECURITY_PROTOCOL; + Flags : ULONG; + PeerApplicationAccessTokenHandle : UINT64; + PeerMachineAccessTokenHandle : UINT64; + end; + {$EXTERNALSYM PSOCKET_SECURITY_QUERY_INFO} + PSOCKET_SECURITY_QUERY_INFO = ^SOCKET_SECURITY_QUERY_INFO; + {$EXTERNALSYM SOCKET_SECURITY_QUERY_TEMPLATE} + SOCKET_SECURITY_QUERY_TEMPLATE = record + SecurityProtocol : SOCKET_SECURITY_PROTOCOL; + PeerAddress : SOCKADDR_STORAGE; + PeerTokenAccessMask : ULONG; + end; + {$EXTERNALSYM PSOCKET_SECURITY_QUERY_TEMPLATE} + PSOCKET_SECURITY_QUERY_TEMPLATE = ^SOCKET_SECURITY_QUERY_TEMPLATE; + +//callback defs +type + {$EXTERNALSYM LPLOOKUPSERVICE_COMPLETION_ROUTINE} + LPLOOKUPSERVICE_COMPLETION_ROUTINE = procedure (const dwError, dwBytes : DWORD; lpOverlapped : LPWSAOVERLAPPED); stdcall; +{$ENDIF} + +type + {$EXTERNALSYM LPFN_GETADDRINFO} + LPFN_GETADDRINFO = function(NodeName: PIdAnsiChar; ServiceName: PIdAnsiChar; Hints: Paddrinfo; ppResult: PPaddrinfo): Integer; stdcall; + {$EXTERNALSYM LPFN_GETADDRINFOW} + LPFN_GETADDRINFOW = function(NodeName: PWideChar; ServiceName: PWideChar; Hints: PaddrinfoW; ppResult: PPaddrinfoW): Integer; stdcall; + {$EXTERNALSYM LPFN_GETNAMEINFO} + //The IPv6 preview for Win2K defines hostlen and servelen as size_t but do not use them + //for these definitions as the newer SDK's define those as DWORD. + LPFN_GETNAMEINFO = function(sa: psockaddr; salen: u_int; host: PIdAnsiChar; hostlen: u_int; serv: PIdAnsiChar; servlen: u_int; flags: Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_GETNAMEINFOW} + LPFN_GETNAMEINFOW = function(sa: psockaddr; salen: u_int; host: PWideChar; hostlen: u_int; serv: PWideChar; servlen: u_int; flags: Integer): Integer; stdcall; + {$EXTERNALSYM LPFN_FREEADDRINFO} + LPFN_FREEADDRINFO = procedure(ai: Paddrinfo); stdcall; + {$EXTERNALSYM LPFN_FREEADDRINFOW} + LPFN_FREEADDRINFOW = procedure(ai: PaddrinfoW); stdcall; + +//function GetAdaptersAddresses( Family:ULONG; Flags:ULONG; Reserved:Pointer; pAdapterAddresses: PIP_ADAPTER_ADDRESSES; pOutBufLen:PULONG):ULONG;stdcall; external iphlpapi_dll; + +{ the following are not used, nor tested} +{function getipnodebyaddr(const src:pointer; len:integer; af:integer;var error_num:integer) :phostent;stdcall; external Wship6_dll; +procedure freehostent(ptr:phostent);stdcall; external Wship6_dll; +function inet_pton(af:integer; const src:pchar; dst:pointer):integer;stdcall; external Wship6_dll; +function inet_ntop(af:integer; const src:pointer; dst:pchar;size:integer):pchar;stdcall; external Wship6_dll; +} + {$IFNDEF WINCE} + {$EXTERNALSYM LPFN_INET_PTON} + LPFN_INET_PTON = function (af: Integer; const src: PIdAnsiChar; dst: Pointer): Integer; stdcall; + {$EXTERNALSYM LPFN_INET_PTONW} + LPFN_INET_PTONW = function (af: Integer; const src: PWideChar; dst: Pointer): Integer; stdcall; + {$EXTERNALSYM LPFN_INET_NTOP} + LPFN_INET_NTOP = function (af: Integer; const src: Pointer; dst: PIdAnsiChar; size: size_t): PIdAnsiChar; stdcall; + {$EXTERNALSYM LPFN_INET_NTOPW} + LPFN_INET_NTOPW = function (af: Integer; const src: Pointer; dst: PWideChar; size: size_t): PIdAnsiChar; stdcall; + +{ end the following are not used, nor tested} +//These are provided in case we need them later +//Windows Vista + {$EXTERNALSYM LPFN_GETADDRINFOEXA} + LPFN_GETADDRINFOEXA = function(pName : PIdAnsiChar; pServiceName : PIdAnsiChar; + const dwNameSpace: DWord; lpNspId : LPGUID; hints : PADDRINFOEXA; + var ppResult : PADDRINFOEXA; timeout : Ptimeval; lpOverlapped : LPWSAOVERLAPPED; + lpCompletionRoutine : LPLOOKUPSERVICE_COMPLETION_ROUTINE; + lpNameHandle : PHandle) : Integer; stdcall; + {$EXTERNALSYM LPFN_GETADDRINFOEXW} + LPFN_GETADDRINFOEXW = function(pName : PWideChar; pServiceName : PWideChar; + const dwNameSpace: DWord; lpNspId : LPGUID;hints : PADDRINFOEXW; + var ppResult : PADDRINFOEXW; timeout : Ptimeval; lpOverlapped : LPWSAOVERLAPPED; + lpCompletionRoutine : LPLOOKUPSERVICE_COMPLETION_ROUTINE; + lpNameHandle : PHandle) : Integer; stdcall; + {$EXTERNALSYM LPFN_SETADDRINFOEXA} + LPFN_SETADDRINFOEXA= function(pName : PIdAnsiChar; pServiceName : PIdAnsiChar; + pAddresses : PSOCKET_ADDRESS; const dwAddressCount : DWord; lpBlob : LPBLOB; + const dwFlags : DWord; const dwNameSpace : DWord; lpNspId : LPGUID; + timeout : Ptimeval; + lpOverlapped : LPWSAOVERLAPPED; + lpCompletionRoutine : LPLOOKUPSERVICE_COMPLETION_ROUTINE; lpNameHandle : PHandle) : Integer; stdcall; + {$EXTERNALSYM LPFN_SETADDRINFOEXW} + LPFN_SETADDRINFOEXW= function(pName : PWideChar; pServiceName : PWideChar; + pAddresses : PSOCKET_ADDRESS; const dwAddressCount : DWord; lpBlob : LPBLOB; + const dwFlags : DWord; const dwNameSpace : DWord; lpNspId : LPGUID; + timeout : Ptimeval; + lpOverlapped : LPWSAOVERLAPPED; + lpCompletionRoutine : LPLOOKUPSERVICE_COMPLETION_ROUTINE; lpNameHandle : PHandle) : Integer; stdcall; + + {$EXTERNALSYM LPFN_FREEADDRINFOEX} + LPFN_FREEADDRINFOEX = procedure(pAddrInfoEx : PADDRINFOEXA) ; stdcall; + {$EXTERNALSYM LPFN_FREEADDRINFOEXW} + LPFN_FREEADDRINFOEXW = procedure(pAddrInfoEx : PADDRINFOEXW) ; stdcall; + + {$EXTERNALSYM LPFN_GETADDRINFOEX} + {$EXTERNALSYM LPFN_SETADDRINFOEX} + {$IFDEF UNICODE} + LPFN_GETADDRINFOEX = LPFN_GETADDRINFOEXW; + LPFN_SETADDRINFOEX = LPFN_SETADDRINFOEXW; + {$ELSE} + LPFN_GETADDRINFOEX = LPFN_GETADDRINFOEXA; + LPFN_SETADDRINFOEX = LPFN_SETADDRINFOEXA; + {$ENDIF} + + // Fwpuclnt.dll - API + {$EXTERNALSYM LPFN_WSASetSocketSecurity} + LPFN_WSASetSocketSecurity = function (socket : TSocket; + SecuritySettings : PSOCKET_SECURITY_SETTINGS; const SecuritySettingsLen : ULONG; + OVERLAPPED : LPWSAOVERLAPPED; CompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSADELETESOCKETPEERTARGETNAME} + LPFN_WSADELETESOCKETPEERTARGETNAME = function (Socket : TSocket; + PeerAddr : Psockaddr; PeerAddrLen : ULONG; + Overlapped : LPWSAOVERLAPPED; CompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE): Integer; stdcall; + {$EXTERNALSYM LPFN_WSASETSOCKETPEERTARGETNAME} + LPFN_WSASETSOCKETPEERTARGETNAME = function (Socket : TSocket; + PeerTargetName : PSOCKET_PEER_TARGET_NAME; PeerTargetNameLen : ULONG; + Overlapped : LPWSAOVERLAPPED; CompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSAIMPERSONATESOCKETPEER} + LPFN_WSAIMPERSONATESOCKETPEER = function (Socket : TSocket; + PeerAddress : Psockaddr; peerAddressLen : ULONG) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSAQUERYSOCKETSECURITY} + LPFN_WSAQUERYSOCKETSECURITY = function (Socket : TSocket; + SecurityQueryTemplate : PSOCKET_SECURITY_QUERY_TEMPLATE; const SecurityQueryTemplateLen : ULONG; + SecurityQueryInfo : PSOCKET_SECURITY_QUERY_INFO; var SecurityQueryInfoLen : ULONG; + Overlapped : LPWSAOVERLAPPED; CompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE) : Integer; stdcall; + {$EXTERNALSYM LPFN_WSAREVERTIMPERSONATION} + LPFN_WSAREVERTIMPERSONATION = function : Integer; stdcall; +{$ENDIF} + +const + {$NODEFINE fn_GetAddrInfo} + {$NODEFINE fn_getnameinfo} + {$NODEFINE fn_freeaddrinfo} + {$IFNDEF WINCE} + {$NODEFINE fn_GetAddrInfoEx} + {$NODEFINE fn_SetAddrInfoEx} + {$NODEFINE fn_FreeAddrInfoEx} + {$NODEFINE fn_inet_pton} + {$NODEFINE fn_inet_ntop} + {$ENDIF} + {$IFDEF UNICODE} + // WinCE does not support GetAddrInfoW(), GetNameInfoW(), or FreeAddrInfoW(). + // To support IPv6 on WinCE when UNICODE is defined, we will use our own + // wrappers that internally call WinCE's functions... + fn_GetAddrInfo = {$IFDEF WINCE}'getaddrinfo'{$ELSE}'GetAddrInfoW'{$ENDIF}; + fn_getnameinfo = {$IFDEF WINCE}'getnameinfo'{$ELSE}'GetNameInfoW'{$ENDIF}; + fn_freeaddrinfo = {$IFDEF WINCE}'freeaddrinfo'{$ELSE}'FreeAddrInfoW'{$ENDIF}; + {$IFNDEF WINCE} + fn_GetAddrInfoEx = 'GetAddrInfoExW'; + fn_SetAddrInfoEx = 'SetAddrInfoExW'; + fn_FreeAddrInfoEx = 'FreeAddrInfoExW'; + fn_inet_pton = 'InetPtonW'; + fn_inet_ntop = 'InetNtopW'; + {$ENDIF} + {$ELSE} + fn_GetAddrInfo = 'getaddrinfo'; + fn_getnameinfo = 'getnameinfo'; + fn_freeaddrinfo = 'freeaddrinfo'; + {$IFNDEF WINCE} + fn_GetAddrInfoEx = 'GetAddrInfoExA'; + fn_SetAddrInfoEx = 'SetAddrInfoExA'; + fn_FreeAddrInfoEx = 'FreeAddrInfoEx'; + fn_inet_pton = 'inet_pton'; + fn_inet_ntop = 'inet_ntop'; + {$ENDIF} + {$ENDIF} + +{$UNDEF WINCE_UNICODE} +{$IFDEF WINCE} + {$IFDEF UNICODE} + {$DEFINE WINCE_UNICODE} + {$ENDIF} +{$ENDIF} + +var + {$EXTERNALSYM getaddrinfo} + {$EXTERNALSYM getnameinfo} + {$EXTERNALSYM freeaddrinfo} + {$IFNDEF WINCE} + {$EXTERNALSYM inet_pton} + {$EXTERNALSYM inet_ntop} + {$ENDIF} + {$IFDEF UNICODE} + {$IFDEF WINCE} + getaddrinfoCE: LPFN_GETADDRINFO = nil; + getnameinfoCE: LPFN_GETNAMEINFO = nil; + freeaddrinfoCE: LPFN_FREEADDRINFO = nil; + {$ENDIF} + getaddrinfo: LPFN_GETADDRINFOW = nil; + getnameinfo: LPFN_GETNAMEINFOW = nil; + freeaddrinfo: LPFN_FREEADDRINFOW = nil; + {$IFNDEF WINCE} + //These are here for completeness + inet_pton : LPFN_inet_ptonW = nil; + inet_ntop : LPFN_inet_ntopW = nil; + {$ENDIF} + {$ELSE} + getaddrinfo: LPFN_GETADDRINFO = nil; + getnameinfo: LPFN_GETNAMEINFO = nil; + freeaddrinfo: LPFN_FREEADDRINFO = nil; + {$IFNDEF WINCE} + //These are here for completeness + inet_pton : LPFN_inet_pton = nil; + inet_ntop : LPFN_inet_ntop = nil; + {$ENDIF} + {$ENDIF} + {$IFNDEF WINCE} + { + IMPORTANT!!! + + These are Windows Vista functions and there's no guarantee that you will have + them so ALWAYS check the function pointer before calling them. + } + {$EXTERNALSYM GetAddrInfoEx} + GetAddrInfoEx : LPFN_GETADDRINFOEX = nil; + {$EXTERNALSYM SetAddrInfoEx} + SetAddrInfoEx : LPFN_SETADDRINFOEX = nil; + {$EXTERNALSYM FreeAddrInfoEx} + //You can't alias the LPFN for this because the ASCII version of this + //does not end with an "a" + {$IFDEF UNICODE} + FreeAddrInfoEx : LPFN_FREEADDRINFOEXW = nil; + {$ELSE} + FreeAddrInfoEx : LPFN_FREEADDRINFOEX = nil; + {$ENDIF} + + //Fwpuclnt.dll available for Windows Vista and later + {$EXTERNALSYM WSASetSocketSecurity} + WSASetSocketSecurity : LPFN_WSASetSocketSecurity = nil; + {$EXTERNALSYM WSASETSOCKETPEERTARGETNAME} + WSASetSocketPeerTargetName : LPFN_WSASETSOCKETPEERTARGETNAME = nil; + {$EXTERNALSYM WSADELETESOCKETPEERTARGETNAME} + WSADeleteSocketPeerTargetName : LPFN_WSADELETESOCKETPEERTARGETNAME = nil; + {$EXTERNALSYM WSAImpersonateSocketPeer} + WSAImpersonateSocketPeer : LPFN_WSAIMPERSONATESOCKETPEER = nil; + {$EXTERNALSYM WSAQUERYSOCKETSECURITY} + WSAQUERYSOCKETSECURITY : LPFN_WSAQUERYSOCKETSECURITY = nil; + {$EXTERNALSYM WSAREVERTIMPERSONATION} + WSARevertImpersonation : LPFN_WSAREVERTIMPERSONATION = nil; + {$ENDIF} + +var + GIdIPv6FuncsAvailable: Boolean = False{$IFDEF HAS_DEPRECATED}{$IFDEF USE_SEMICOLON_BEFORE_DEPRECATED};{$ENDIF} deprecated{$ENDIF}; + +function gaiErrorToWsaError(const gaiError: Integer): Integer; + +//We want to load this library only after loading Winsock and unload immediately +//before unloading Winsock. +procedure InitLibrary; +procedure CloseLibrary; + +{$ENDIF} +implementation +{$IFDEF WINDOWS} + +uses + SysUtils; + +var + hWship6Dll : TIdLibHandle = IdNilHandle; // Wship6.dll handle + //Use this instead of hWship6Dll because this will point to the correct lib. + hProcHandle : TIdLibHandle = IdNilHandle; + {$IFNDEF WINCE} + hfwpuclntDll : TIdLibHandle = IdNilHandle; + {$ENDIF} + +function gaiErrorToWsaError(const gaiError: Integer): Integer; +begin + case gaiError of + GIA_EAI_ADDRFAMILY: Result := 0; // TODO: find a decent error for here + GIA_EAI_AGAIN: Result := WSATRY_AGAIN; + GIA_EAI_BADFLAGS: Result := WSAEINVAL; + GIA_EAI_FAIL: Result := WSANO_RECOVERY; + GIA_EAI_FAMILY: Result := WSAEAFNOSUPPORT; + GIA_EAI_MEMORY: Result := WSA_NOT_ENOUGH_MEMORY; + GIA_EAI_NODATA: Result := WSANO_DATA; + GIA_EAI_NONAME: Result := WSAHOST_NOT_FOUND; + GIA_EAI_SERVICE: Result := WSATYPE_NOT_FOUND; + GIA_EAI_SOCKTYPE: Result := WSAESOCKTNOSUPPORT; + GIA_EAI_SYSTEM: + begin + Result := 0; // avoid warning + IndyRaiseLastError; + end; + else + Result := gaiError; + end; +end; + +procedure CloseLibrary; +var + h : TIdLibHandle; +begin + h := InterlockedExchangeTLibHandle(hWship6Dll, IdNilHandle); + if h <> IdNilHandle then begin + FreeLibrary(h); + end; + {$IFNDEF WINCE} + h := InterlockedExchangeTLibHandle(hfwpuclntDll, IdNilHandle); + if h <> IdNilHandle then begin + FreeLibrary(h); + end; + {$ENDIF} + + {$I IdSymbolDeprecatedOff.inc} + GIdIPv6FuncsAvailable := False; + {$I IdSymbolDeprecatedOn.inc} + + {$IFDEF WINCE_UNICODE} + getaddrinfoCE := nil; + getnameinfoCE := nil; + freeaddrinfoCE := nil; + {$ENDIF} + getaddrinfo := nil; + getnameinfo := nil; + freeaddrinfo := nil; + {$IFNDEF WINCE} + inet_pton := nil; + inet_ntop := nil; + GetAddrInfoEx := nil; + SetAddrInfoEx := nil; + FreeAddrInfoEx := nil; + WSASetSocketPeerTargetName := nil; + WSADeleteSocketPeerTargetName := nil; + WSAImpersonateSocketPeer := nil; + WSAQuerySocketSecurity := nil; + WSARevertImpersonation := nil; + {$ENDIF} +end; + +{$IFDEF FPC} //{$IFDEF STRING_IS_ANSI} + {$IFDEF UNICODE} + +// FreePascal does not have PWideChar overloads of these functions + +function StrComp(const Str1, Str2: PWideChar): Integer; overload; +var + P1, P2: PWideChar; +begin + P1 := Str1; + P2 := Str2; + while True do + begin + if (P1^ <> P2^) or (P1^ = #0) then + begin + Result := Ord(P1^) - Ord(P2^); + Exit; + end; + Inc(P1); + Inc(P2); + end; + Result := 0; +end; + +function StrScan(const Str: PWideChar; Chr: WideChar): PWideChar; overload; +begin + Result := Str; + while Result^ <> #0 do + begin + if Result^ = Chr then begin + Exit; + end; + Inc(Result); + end; + if Chr <> #0 then begin + Result := nil; + end; +end; + + {$ENDIF} +{$ENDIF} + +// The IPv6 functions were added to the Ws2_32.dll on Windows XP and later. +// To execute an application that uses these functions on earlier versions of +// Windows, the functions are defined as inline functions in the Wspiapi.h file. +// At runtime, the functions are implemented in such a way that if the Ws2_32.dll +// or the Wship6.dll (the file containing the functions in the IPv6 Technology +// Preview for Windows 2000) does not include them, then versions are implemented +// inline based on code in the Wspiapi.h header file. This inline code will be +// used on older Windows platforms that do not natively support the functions. + +// RLebeau: Wspiapi.h only defines Ansi versions of the legacy functions, but we +// need to handle Unicode as well... + +function WspiapiMalloc(tSize: size_t): Pointer; +begin + try + GetMem(Result, tSize); + ZeroMemory(Result, tSize); + except + Result := nil; + end; +end; + +procedure WspiapiFree(p: Pointer); +begin + FreeMem(p); +end; + +procedure WspiapiSwap(var a, b, c: PIdPlatformChar); + {$IFDEF USE_INLINE}inline;{$ENDIF} +begin + c := a; + a := b; + b := c; +end; + +function WspiapiStrdup(const pszString: PIdPlatformChar): PIdPlatformChar; stdcall; +var + pszMemory: PIdPlatformChar; + cchMemory: size_t; +begin + if pszString = nil then begin + Result := nil; + Exit; + end; + + cchMemory := StrLen(pszString) + 1; + pszMemory := PIdPlatformChar(WspiapiMalloc(cchMemory * SizeOf(TIdPlatformChar))); + if pszMemory = nil then begin + Result := nil; + Exit; + end; + + StrLCopy(pszMemory, pszString, cchMemory); + Result := pszMemory; +end; + +function WspiapiParseV4Address(const pszAddress: PIdPlatformChar; var pdwAddress: DWORD): BOOL; stdcall; +var + dwAddress: DWORD; + pcNext: PIdPlatformChar; + iCount: Integer; + {$IFDEF USE_MARSHALLED_PTRS} + M: TMarshaller; + {$ENDIF} +begin + iCount := 0; + + // ensure there are 3 '.' (periods) + pcNext := pszAddress; + while pcNext^ <> TIdPlatformChar(0) do begin + if pcNext^ = '.' then begin + Inc(iCount); + end; + Inc(pcNext); + end; + if iCount <> 3 then begin + Result := FALSE; + Exit; + end; + + // return an error if dwAddress is INADDR_NONE (255.255.255.255) + // since this is never a valid argument to getaddrinfo. + dwAddress := inet_addr( + {$IFDEF USE_MARSHALLED_PTRS} + M.AsAnsi(pszAddress).ToPointer + {$ELSE} + {$IFDEF UNICODE} + PIdAnsiChar(AnsiString(pszAddress)) // explicit convert to Ansi + {$ELSE} + pszAddress + {$ENDIF} + {$ENDIF} + ); + if dwAddress = INADDR_NONE then begin + Result := FALSE; + Exit; + end; + + pdwAddress := dwAddress; + Result := TRUE; +end; + +function WspiapiNewAddrInfo(iSocketType, iProtocol: Integer; wPort: WORD; dwAddress: DWORD): {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}; stdcall; +var + ptNew: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}; + ptAddress: PSockAddrIn; +begin + // allocate a new addrinfo structure. + {$IFDEF UNICODE} + ptNew := PaddrinfoW(WspiapiMalloc(SizeOf(addrinfoW))); + {$ELSE} + ptNew := Paddrinfo(WspiapiMalloc(SizeOf(addrinfo))); + {$ENDIF} + if ptNew = nil then begin + Result := nil; + Exit; + end; + + ptAddress := PSockAddrIn(WspiapiMalloc(SizeOf(sockaddr_in))); + if ptAddress = nil then begin + WspiapiFree(ptNew); + Result := nil; + Exit; + end; + ptAddress^.sin_family := AF_INET; + ptAddress^.sin_port := wPort; + ptAddress^.sin_addr.s_addr := dwAddress; + + // fill in the fields... + ptNew^.ai_family := PF_INET; + ptNew^.ai_socktype := iSocketType; + ptNew^.ai_protocol := iProtocol; + ptNew^.ai_addrlen := SizeOf(sockaddr_in); + ptNew^.ai_addr := Psockaddr(ptAddress); + + Result := ptNew; +end; + +function WspiapiQueryDNS(const pszNodeName: PIdPlatformChar; iSocketType, iProtocol: Integer; + wPort: WORD; pszAlias: PIdPlatformChar; var pptResult: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}): Integer; stdcall; +var + pptNext: {$IFDEF UNICODE}PPaddrinfoW{$ELSE}PPaddrinfo{$ENDIF}; + ptHost: Phostent; + ppAddresses: ^PInAddr; + {$IFDEF USE_MARSHALLED_PTRS} + M: TMarshaller; + {$ENDIF} +begin + pptNext := @pptResult; + + pptNext^ := nil; + pszAlias^ := TIdPlatformChar(0); + + ptHost := gethostbyname( + {$IFDEF USE_MARSHALLED_PTRS} + M.AsAnsi(pszNodeName).ToPointer + {$ELSE} + {$IFDEF UNICODE} + PIdAnsiChar(AnsiString(pszNodeName)) // explicit convert to Ansi + {$ELSE} + pszNodeName + {$ENDIF} + {$ENDIF} + ); + if ptHost <> nil then begin + if (ptHost^.h_addrtype = AF_INET) and (ptHost^.h_length = SizeOf(in_addr)) then begin + ppAddresses := Pointer(ptHost^.h_address_list); + while ppAddresses^ <> nil do begin + // create an addrinfo structure... + pptNext^ := WspiapiNewAddrInfo(iSocketType, iProtocol, wPort, ppAddresses^^.s_addr); + if pptNext^ = nil then begin + Result := EAI_MEMORY; + Exit; + end; + + pptNext := @((pptNext^)^.ai_next); + Inc(ppAddresses); + end; + end; + + // pick up the canonical name. + StrLCopy(pszAlias, + {$IFNDEF UNICODE} + ptHost^.h_name + {$ELSE} + PIdPlatformChar(TIdPlatformString(ptHost^.h_name)) + {$ENDIF} + , NI_MAXHOST); + + Result := 0; + Exit; + end; + + case WSAGetLastError() of + WSAHOST_NOT_FOUND: Result := EAI_NONAME; + WSATRY_AGAIN: Result := EAI_AGAIN; + WSANO_RECOVERY: Result := EAI_FAIL; + WSANO_DATA: Result := EAI_NODATA; + else + Result := EAI_NONAME; + end; +end; + +function WspiapiLookupNode(const pszNodeName: PIdPlatformChar; iSocketType: Integer; + iProtocol: Integer; wPort: WORD; bAI_CANONNAME: BOOL; var pptResult: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}): Integer; stdcall; +var + iError: Integer; + iAliasCount: Integer; + szFQDN1: array[0..NI_MAXHOST-1] of TIdPlatformChar; + szFQDN2: array[0..NI_MAXHOST-1] of TIdPlatformChar; + pszName: PIdPlatformChar; + pszAlias: PIdPlatformChar; + pszScratch: PIdPlatformChar; +begin + iAliasCount := 0; + + ZeroMemory(@szFQDN1, SizeOf(szFQDN1)); + ZeroMemory(@szFQDN2, SizeOf(szFQDN2)); + pszName := @szFQDN1[0]; + pszAlias := @szFQDN2[0]; + pszScratch := nil; + StrLCopy(pszName, pszNodeName, NI_MAXHOST); + + repeat + iError := WspiapiQueryDNS(pszNodeName, iSocketType, iProtocol, wPort, pszAlias, pptResult); + if iError <> 0 then begin + Break; + end; + + // if we found addresses, then we are done. + if pptResult <> nil then begin + Break; + end; + + // stop infinite loops due to DNS misconfiguration. there appears + // to be no particular recommended limit in RFCs 1034 and 1035. + if (StrLen(pszAlias) = 0) or (StrComp(pszName, pszAlias) = 0) then begin + iError := EAI_FAIL; + Break; + end; + Inc(iAliasCount); + if iAliasCount = 16 then begin + iError := EAI_FAIL; + Break; + end; + + // there was a new CNAME, look again. + WspiapiSwap(pszName, pszAlias, pszScratch); + until False; + + if (iError = 0) and bAI_CANONNAME then begin + pptResult^.ai_canonname := WspiapiStrdup(pszAlias); + if pptResult^.ai_canonname = nil then begin + iError := EAI_MEMORY; + end; + end; + + Result := iError; +end; + +function WspiapiClone(wPort: WORD; ptResult: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}): Integer; stdcall; +var + ptNext, ptNew: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}; +begin + ptNext := ptResult; + while ptNext <> nil do begin + // create an addrinfo structure... + ptNew := WspiapiNewAddrInfo(SOCK_DGRAM, ptNext^.ai_protocol, wPort, PSockAddrIn(ptNext^.ai_addr)^.sin_addr.s_addr); + if ptNew = nil then begin + Break; + end; + + // link the cloned addrinfo + ptNew^.ai_next := ptNext^.ai_next; + ptNext^.ai_next := ptNew; + ptNext := ptNew^.ai_next; + end; + + if ptNext <> nil then begin + Result := EAI_MEMORY; + Exit; + end; + + Result := 0; +end; + +procedure WspiapiLegacyFreeAddrInfo(ptHead: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}); stdcall; +var + ptNext: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}; +begin + ptNext := ptHead; + while ptNext <> nil do + begin + if ptNext^.ai_canonname <> nil then begin + WspiapiFree(ptNext^.ai_canonname); + end; + if ptNext^.ai_addr <> nil then begin + WspiapiFree(ptNext^.ai_addr); + end; + ptHead := ptNext^.ai_next; + WspiapiFree(ptNext); + ptNext := ptHead; + end; +end; + +{$IFNDEF HAS_TryStrToInt} +// TODO: use the implementation already in IdGlobalProtocols... +function TryStrToInt(const S: string; out Value: Integer): Boolean; +{$IFDEF USE_INLINE}inline;{$ENDIF} +var + E: Integer; +begin + Val(S, Value, E); + Result := E = 0; +end; +{$ENDIF} + +function WspiapiLegacyGetAddrInfo(const pszNodeName: PIdPlatformChar; const pszServiceName: PIdPlatformChar; + const ptHints: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}; + var pptResult: {$IFDEF UNICODE}PaddrinfoW{$ELSE}Paddrinfo{$ENDIF}): Integer; stdcall; +var + iError: Integer; + iFlags: Integer; + iSocketType: Integer; + iProtocol: Integer; + wPort: WORD; + iTmp: Integer; + dwAddress: DWORD; + ptService: Pservent; + bClone: BOOL; + wTcpPort: WORD; + wUdpPort: WORD; + {$IFDEF USE_MARSHALLED_PTRS} + M: TMarshaller; + {$ENDIF} +begin + iError := 0; + iFlags := 0; + iSocketType := 0; + iProtocol := 0; + wPort := 0; + dwAddress := 0; + bClone := FALSE; + wTcpPort := 0; + wUdpPort := 0; + + // initialize pptResult with default return value. + pptResult := nil; + + //////////////////////////////////////// + // validate arguments... + // + + // both the node name and the service name can't be NULL. + if (pszNodeName = nil) and (pszServiceName = nil) then begin + Result := EAI_NONAME; + Exit; + end; + + // validate hints. + if ptHints <> nil then + begin + // all members other than ai_flags, ai_family, ai_socktype + // and ai_protocol must be zero or a null pointer. + if (ptHints^.ai_addrlen <> 0) or + (ptHints^.ai_canonname <> nil) or + (ptHints^.ai_addr <> nil) or + (ptHints^.ai_next <> nil) then + begin + Result := EAI_FAIL; + Exit; + end; + + // the spec has the "bad flags" error code, so presumably we + // should check something here. insisting that there aren't + // any unspecified flags set would break forward compatibility, + // however. so we just check for non-sensical combinations. + // + // we cannot come up with a canonical name given a null node name. + iFlags := ptHints^.ai_flags; + if ((iFlags and AI_CANONNAME) <> 0) and (pszNodeName = nil) then begin + Result := EAI_BADFLAGS; + Exit; + end; + + // we only support a limited number of protocol families. + if (ptHints^.ai_family <> PF_UNSPEC) and (ptHints^.ai_family <> PF_INET) then begin + Result := EAI_FAMILY; + Exit; + end; + + // we only support only these socket types. + iSocketType := ptHints^.ai_socktype; + if (iSocketType <> 0) and + (iSocketType <> SOCK_STREAM) and + (iSocketType <> SOCK_DGRAM) and + (iSocketType <> SOCK_RAW) then + begin + Result := EAI_SOCKTYPE; + Exit; + end; + + // REVIEW: What if ai_socktype and ai_protocol are at odds? + iProtocol := ptHints^.ai_protocol; + end; + + //////////////////////////////////////// + // do service lookup... + + if pszServiceName <> nil then begin + if TryStrToInt(pszServiceName, iTmp) and (iTmp >= 0) then begin + wPort := htons(WORD(iTmp)); + //wTcpPort := wPort; // never used + wUdpPort := wPort; + if iSocketType = 0 then begin + bClone := TRUE; + iSocketType := SOCK_STREAM; + end; + end else + begin + if (iSocketType = 0) or (iSocketType = SOCK_DGRAM) then begin + ptService := getservbyname( + {$IFDEF USE_MARSHALLED_PTRS} + M.AsAnsi(pszServiceName).ToPointer + {$ELSE} + {$IFDEF UNICODE} + PIdAnsiChar(AnsiString(pszServiceName)) // explicit convert to Ansi + {$ELSE} + pszServiceName + {$ENDIF} + {$ENDIF} + , 'udp'); {do not localize} + if ptService <> nil then begin + wPort := ptService^.s_port; + wUdpPort := wPort; + end; + end; + + if (iSocketType = 0) or (iSocketType = SOCK_STREAM) then begin + ptService := getservbyname( + {$IFDEF USE_MARSHALLED_PTRS} + M.AsAnsi(pszServiceName).ToPointer + {$ELSE} + {$IFDEF UNICODE} + PIdAnsiChar(AnsiString(pszServiceName)) // explicit convert to Ansi + {$ELSE} + pszServiceName + {$ENDIF} + {$ENDIF} + , 'tcp'); {do not localize} + if ptService <> nil then begin + wPort := ptService^.s_port; + wTcpPort := wPort; + end; + end; + + // assumes 0 is an invalid service port... + if wPort = 0 then begin + Result := iif(iSocketType <> 0, EAI_SERVICE, EAI_NONAME); + Exit; + end; + + if iSocketType = 0 then begin + // if both tcp and udp, process tcp now & clone udp later. + iSocketType := iif(wTcpPort <> 0, SOCK_STREAM, SOCK_DGRAM); + bClone := (wTcpPort <> 0) and (wUdpPort <> 0); + end; + end; + end; + + //////////////////////////////////////// + // do node name lookup... + + // if we weren't given a node name, + // return the wildcard or loopback address (depending on AI_PASSIVE). + // + // if we have a numeric host address string, + // return the binary address. + // + if ((pszNodeName = nil) or WspiapiParseV4Address(pszNodeName, dwAddress)) then begin + if pszNodeName = nil then begin + dwAddress := htonl(iif((iFlags and AI_PASSIVE) <> 0, INADDR_ANY, INADDR_LOOPBACK)); + end; + + // create an addrinfo structure... + pptResult := WspiapiNewAddrInfo(iSocketType, iProtocol, wPort, dwAddress); + if pptResult = nil then begin + iError := EAI_MEMORY; + end; + + if (iError = 0) and (pszNodeName <> nil) then begin + // implementation specific behavior: set AI_NUMERICHOST + // to indicate that we got a numeric host address string. + pptResult^.ai_flags := pptResult^.ai_flags or AI_NUMERICHOST; + // return the numeric address string as the canonical name + if (iFlags and AI_CANONNAME) <> 0 then begin + pptResult^.ai_canonname := WspiapiStrdup( + {$IFNDEF UNICODE} + inet_ntoa(PInAddr(@dwAddress)^) + {$ELSE} + PWideChar(TIdUnicodeString(inet_ntoa(PInAddr(@dwAddress)^))) + {$ENDIF} + ); + if pptResult^.ai_canonname = nil then begin + iError := EAI_MEMORY; + end; + end; + end; + end + + // if we do not have a numeric host address string and + // AI_NUMERICHOST flag is set, return an error! + else if ((iFlags and AI_NUMERICHOST) <> 0) then begin + iError := EAI_NONAME; + end + + // since we have a non-numeric node name, + // we have to do a regular node name lookup. + else begin + iError := WspiapiLookupNode(pszNodeName, iSocketType, iProtocol, wPort, (iFlags and AI_CANONNAME) <> 0, pptResult); + end; + + if (iError = 0) and bClone then begin + iError := WspiapiClone(wUdpPort, pptResult); + end; + + if iError <> 0 then begin + WspiapiLegacyFreeAddrInfo(pptResult); + pptResult := nil; + end; + + Result := iError; +end; + +function iif(ATest: Boolean; const ATrue, AFalse: PIdAnsiChar): PIdAnsiChar; + {$IFDEF USE_INLINE}inline;{$ENDIF} +begin + if ATest then begin + Result := ATrue; + end else begin + Result := AFalse; + end; +end; + +function WspiapiLegacyGetNameInfo(ptSocketAddress: Psockaddr; + tSocketLength: u_int; pszNodeName: PIdPlatformChar; tNodeLength: size_t; + pszServiceName: PIdPlatformChar; tServiceLength: size_t; iFlags: Integer): Integer; stdcall; +var + ptService: Pservent; + wPort: WORD; + szBuffer: array[0..5] of TIdPlatformChar; + pszService: PIdPlatformChar; + ptHost: Phostent; + tAddress: in_addr; + pszNode: PIdPlatformChar; + pc: PIdPlatformChar; + {$IFDEF UNICODE} + tmpService: TIdUnicodeString; + tmpNode: TIdUnicodeString; + {$ENDIF} +begin + StrCopy(szBuffer, '65535'); + pszService := szBuffer; + + // sanity check ptSocketAddress and tSocketLength. + if (ptSocketAddress = nil) or (tSocketLength < SizeOf(sockaddr)) then begin + Result := EAI_FAIL; + Exit; + end; + + if ptSocketAddress^.sa_family <> AF_INET then begin + Result := EAI_FAMILY; + Exit; + end; + + if tSocketLength < SizeOf(sockaddr_in) then begin + Result := EAI_FAIL; + Exit; + end; + + if (not ((pszNodeName <> nil) and (tNodeLength > 0))) and (not ((pszServiceName <> nil) and (tServiceLength > 0))) then begin + Result := EAI_NONAME; + Exit; + end; + + // the draft has the "bad flags" error code, so presumably we + // should check something here. insisting that there aren't + // any unspecified flags set would break forward compatibility, + // however. so we just check for non-sensical combinations. + if ((iFlags and NI_NUMERICHOST) <> 0) and ((iFlags and NI_NAMEREQD) <> 0) then begin + Result := EAI_BADFLAGS; + Exit; + end; + + // translate the port to a service name (if requested). + if (pszServiceName <> nil) and (tServiceLength > 0) then begin + wPort := PSockAddrIn(ptSocketAddress)^.sin_port; + + if (iFlags and NI_NUMERICSERV) <> 0 then begin + // return numeric form of the address. + StrPLCopy(szBuffer, IntToStr(ntohs(wPort)), Length(szBuffer)); + end else + begin + // return service name corresponding to port. + ptService := getservbyport(wPort, iif((iFlags and NI_DGRAM) <> 0, 'udp', nil)); + if (ptService <> nil) and (ptService^.s_name <> nil) then begin + // lookup successful. + {$IFNDEF UNICODE} + pszService := ptService^.s_name; + {$ELSE} + tmpService := TIdUnicodeString(ptService^.s_name); + pszService := PWideChar(tmpService); + {$ENDIF} + end else begin + // DRAFT: return numeric form of the port! + StrPLCopy(szBuffer, IntToStr(ntohs(wPort)), Length(szBuffer)); + end; + end; + + if tServiceLength > size_t(StrLen(pszService)) then begin + StrLCopy(pszServiceName, pszService, tServiceLength); + end else begin + Result := EAI_FAIL; + Exit; + end; + end; + + // translate the address to a node name (if requested). + if (pszNodeName <> nil) and (tNodeLength > 0) then begin + // this is the IPv4-only version, so we have an IPv4 address. + tAddress := PSockAddrIn(ptSocketAddress)^.sin_addr; + + if (iFlags and NI_NUMERICHOST) <> 0 then begin + // return numeric form of the address. + {$IFNDEF UNICODE} + pszNode := inet_ntoa(tAddress); + {$ELSE} + tmpNode := TIdUnicodeString(inet_ntoa(tAddress)); + pszNode := PWideChar(tmpNode); + {$ENDIF} + end else + begin + // return node name corresponding to address. + ptHost := gethostbyaddr(PIdAnsiChar(@tAddress), SizeOf(in_addr), AF_INET); + if (ptHost <> nil) and (ptHost^.h_name <> nil) then begin + // DNS lookup successful. + // stop copying at a "." if NI_NOFQDN is specified. + {$IFNDEF UNICODE} + pszNode := ptHost^.h_name; + {$ELSE} + tmpNode := TIdUnicodeString(ptHost^.h_name); + pszNode := PWideChar(tmpNode); + {$ENDIF} + if (iFlags and NI_NOFQDN) <> 0 then begin + pc := StrScan(pszNode, '.'); + if pc <> nil then begin + pc^ := TIdPlatformChar(0); + end; + end; + end else + begin + // DNS lookup failed. return numeric form of the address. + if (iFlags and NI_NAMEREQD) <> 0 then begin + case WSAGetLastError() of + WSAHOST_NOT_FOUND: Result := EAI_NONAME; + WSATRY_AGAIN: Result := EAI_AGAIN; + WSANO_RECOVERY: Result := EAI_FAIL; + else + Result := EAI_NONAME; + end; + Exit; + end else begin + {$IFNDEF UNICODE} + pszNode := inet_ntoa(tAddress); + {$ELSE} + tmpNode := TIdUnicodeString(inet_ntoa(tAddress)); + pszNode := PWideChar(tmpNode); + {$ENDIF} + end; + end; + end; + + if tNodeLength > size_t(StrLen(pszNode)) then begin + StrLCopy(pszNodeName, pszNode, tNodeLength); + end else begin + Result := EAI_FAIL; + Exit; + end; + end; + + Result := 0; +end; + +{$IFDEF WINCE_UNICODE} + +function IndyStrdupAToW(const pszString: PIdAnsiChar): PWideChar; +var + szStr: TIdUnicodeString; + pszMemory: PWideChar; + cchMemory: size_t; +begin + if pszString = nil then begin + Result := nil; + Exit; + end; + + szStr := TIdUnicodeString(pszString); + cchMemory := Length(szStr) + 1; + + pszMemory := PWideChar(WspiapiMalloc(cchMemory * SizeOf(WideChar))); + if pszMemory = nil then begin + Result := nil; + Exit; + end; + + StrLCopy(pszMemory, PWideChar(szStr), cchMemory); + Result := pszMemory; +end; + +procedure IndyFreeAddrInfoW(ptHead: PaddrinfoW); stdcall; +var + ptNext: PaddrinfoW; +begin + ptNext := ptHead; + while ptNext <> nil do + begin + if ptNext^.ai_canonname <> nil then begin + WspiapiFree(ptNext^.ai_canonname); + end; + if ptNext^.ai_addr <> nil then begin + WspiapiFree(ptNext^.ai_addr); + end; + ptHead := ptNext^.ai_next; + WspiapiFree(ptNext); + ptNext := ptHead; + end; +end; + +function IndyAddrInfoConvert(AddrInfo: Paddrinfo): PaddrinfoW; +var + ptNew: PaddrinfoW; + ptAddress: Pointer; +begin + Result := nil; + + if AddrInfo = nil then begin + Exit; + end; + + // allocate a new addrinfo structure. + ptNew := PaddrinfoW(WspiapiMalloc(SizeOf(addrinfoW))); + if ptNew = nil then begin + WspiapiFree(ptNew); + Exit; + end; + + ptAddress := WspiapiMalloc(AddrInfo^.ai_addrlen); + if ptAddress = nil then begin + WspiapiFree(ptNew); + Exit; + end; + Move(AddrInfo^.ai_addr^, ptAddress^, AddrInfo^.ai_addrlen); + + // fill in the fields... + ptNew^.ai_flags := AddrInfo^.ai_flags; + ptNew^.ai_family := AddrInfo^.ai_family; + ptNew^.ai_socktype := AddrInfo^.ai_socktype; + ptNew^.ai_protocol := AddrInfo^.ai_protocol; + ptNew^.ai_addrlen := AddrInfo^.ai_addrlen; + ptNew^.ai_canonname := nil; + ptNew^.ai_addr := Psockaddr(ptAddress); + ptNew^.ai_next := nil; + + if AddrInfo^.ai_canonname <> nil then begin + ptNew^.ai_canonname := IndyStrdupAToW(AddrInfo^.ai_canonname); + if ptNew^.ai_canonname = nil then begin + IndyFreeAddrInfoW(ptNew); + Exit; + end; + end; + + if AddrInfo^.ai_next <> nil then begin + ptNew^.ai_next := IndyAddrInfoConvert(AddrInfo^.ai_next); + if ptNew^.ai_next = nil then begin + IndyFreeAddrInfoW(ptNew); + Exit; + end; + end; + + Result := ptNew; +end; + +function IndyGetAddrInfoW(const pszNodeName: PWideChar; const pszServiceName: PWideChar; + const ptHints: PaddrinfoW; var pptResult: PaddrinfoW): Integer; stdcall; +var + LNodeName: AnsiString; + LPNodeName: PIdAnsiChar; + LServiceName: AnsiString; + LPServiceName: PIdAnsiChar; + LHints: addrinfo; + LPHints: Paddrinfo; + LResult: Paddrinfo; +begin + // initialize pptResult with default return value. + pptResult := nil; + + if pszNodeName <> nil then begin + LNodeName := AnsiString(pszNodeName); + LPNodeName := PIdAnsiChar(LNodeName); + end else begin + LPNodeName := nil; + end; + + if pszServiceName <> nil then begin + LServiceName := AnsiString(pszServiceName); + LPServiceName := PIdAnsiChar(LServiceName); + end else begin + LPServiceName := nil; + end; + + if ptHints <> nil then begin + ZeroMemory(@LHints, SizeOf(LHints)); + LHints.ai_flags := ptHints^.ai_flags; + LHints.ai_family := ptHints^.ai_family; + LHints.ai_socktype := ptHints^.ai_socktype; + LHints.ai_protocol := ptHints^.ai_protocol; + LPHints := @LHints; + end else begin + LPHints := nil; + end; + + Result := getaddrinfoCE(LPNodeName, LPServiceName, LPHints, @LResult); + if Result = 0 then begin + try + pptResult := IndyAddrInfoConvert(LResult); + finally + freeaddrinfoCE(LResult); + end; + if pptResult = nil then begin + Result := EAI_MEMORY; + end; + end; +end; + +function IndyGetNameInfoW(ptSocketAddress: Psockaddr; tSocketLength: u_int; + pszNodeName: PWideChar; tNodeLength: size_t; pszServiceName: PWideChar; + tServiceLength: size_t; iFlags: Integer): Integer; stdcall; +var + LHost: array[0..NI_MAXHOST-1] of TIdAnsiChar; + LPHost: PIdAnsiChar; + LHostLen: u_int; + LServ: array[0..NI_MAXSERV-1] of TIdAnsiChar; + LPServ: PIdAnsiChar; + LServLen: u_int; +begin + if pszNodeName <> nil then + begin + LPHost := @LHost[0]; + LHostLen := Length(LHost); + end else begin + LPHost := nil; + LHostLen := 0; + end; + + if pszServiceName <> nil then + begin + LPServ := @LServ[0]; + LServLen := Length(LServ); + end else begin + LPServ := nil; + LServLen := 0; + end; + + Result := getnameinfoCE(ptSocketAddress, tSocketLength, LPHost, LHostLen, LPServ, LServLen, iFlags); + if Result = 0 then begin + if pszNodeName <> nil then begin + StrPLCopy(pszNodeName, TIdUnicodeString(LPHost), tNodeLength); + end; + if pszServiceName <> nil then begin + StrPLCopy(pszServiceName, TIdUnicodeString(LPServ), tServiceLength); + end; + end; +end; + +{$ENDIF} + +procedure InitLibrary; +var + {$IFDEF WINCE_UNICODE} + gai: LPFN_GETADDRINFO; + gni: LPFN_GETNAMEINFO; + fai: LPFN_FREEADDRINFO; + {$ELSE} + gai: {$IFDEF UNICODE}LPFN_GETADDRINFOW{$ELSE}LPFN_GETADDRINFO{$ENDIF}; + gni: {$IFDEF UNICODE}LPFN_GETNAMEINFOW{$ELSE}LPFN_GETNAMEINFO{$ENDIF}; + fai: {$IFDEF UNICODE}LPFN_FREEADDRINFOW{$ELSE}LPFN_FREEADDRINFO{$ENDIF}; + {$ENDIF} +begin +{ +IMPORTANT!!! + +I am doing things this way because the functions we want are probably in +the Winsock2 dll. If they are not there, only then do you actually want +to try the Wship6.dll. I know it's a mess but I found that the functions +may not load if they aren't in Wship6.dll (and they aren't there in some +versions of Windows). + +hProcHandle provides a transparant way of managing the two possible library +locations. hWship6Dll is kept so we can unload the Wship6.dll if necessary. +} + //Winsock2 has to be loaded by IdWinsock first. + if not IdWinsock2.Winsock2Loaded then + begin + IdWinsock2.InitializeWinSock; + end; + hProcHandle := IdWinsock2.WinsockHandle; + + gai := LoadLibFunction(hProcHandle, fn_getaddrinfo); + if not Assigned(gai) then + begin + hWship6Dll := SafeLoadLibrary(Wship6_dll); + hProcHandle := hWship6Dll; + gai := LoadLibFunction(hProcHandle, fn_getaddrinfo); + end; + + if Assigned(gai) then + begin + gni := LoadLibFunction(hProcHandle, fn_getnameinfo); + if Assigned(gni) then + begin + fai := LoadLibFunction(hProcHandle, fn_freeaddrinfo); + if Assigned(fai) then + begin + {$IFDEF WINCE_UNICODE} + getaddrinfoCE := gai; + getnameinfoCE := gni; + freeaddrinfoCE := fai; + getaddrinfo := @IndyGetAddrInfoW; + getnameinfo := @IndyGetNameInfoW; + freeaddrinfo := @IndyFreeAddrInfoW; + {$ELSE} + getaddrinfo := gai; + getnameinfo := gni; + freeaddrinfo := fai; + {$ENDIF} + + //Additional functions should be initialized here. + {$IFNDEF WINCE} + inet_pton := LoadLibFunction(hProcHandle, fn_inet_pton); + inet_ntop := LoadLibFunction(hProcHandle, fn_inet_ntop); + GetAddrInfoEx := LoadLibFunction(hProcHandle, fn_GetAddrInfoEx); + SetAddrInfoEx := LoadLibFunction(hProcHandle, fn_SetAddrInfoEx); + FreeAddrInfoEx := LoadLibFunction(hProcHandle, fn_FreeAddrInfoEx); + hfwpuclntDll := SafeLoadLibrary(fwpuclnt_dll); + if hfwpuclntDll <> IdNilHandle then + begin + WSASetSocketSecurity := LoadLibFunction(hfwpuclntDll, 'WSASetSocketSecurity'); {Do not localize} + WSAQuerySocketSecurity := LoadLibFunction(hfwpuclntDll, 'WSAQuerySocketSecurity'); {Do not localize} + WSASetSocketPeerTargetName := LoadLibFunction(hfwpuclntDll, 'WSASetSocketPeerTargetName'); {Do not localize} + WSADeleteSocketPeerTargetName := LoadLibFunction(hfwpuclntDll, 'WSADeleteSocketPeerTargetName'); {Do not localize} + WSAImpersonateSocketPeer := LoadLibFunction(hfwpuclntDll, 'WSAImpersonateSocketPeer'); {Do not localize} + WSARevertImpersonation := LoadLibFunction(hfwpuclntDll, 'WSARevertImpersonation'); {Do not localize} + end; + {$ENDIF} + + Exit; + end; + end; + end; + + CloseLibrary; + + getaddrinfo := Addr(WspiapiLegacyGetAddrInfo); + getnameinfo := Addr(WspiapiLegacyGetNameInfo); + freeaddrinfo := Addr(WspiapiLegacyFreeAddrInfo); + + {$I IdSymbolDeprecatedOff.inc} + GIdIPv6FuncsAvailable := True; + {$I IdSymbolDeprecatedOn.inc} +end; + +initialization +finalization + CloseLibrary; +{$ENDIF} +end.