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 8ce7d254c..ccfd332fe 100644 --- a/Lib/Core/IdCompilerDefines.inc +++ b/Lib/Core/IdCompilerDefines.inc @@ -1,2091 +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 -{.$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 +{$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/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/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 dd9e2b6f5..4293b3840 100644 --- a/Lib/Protocols/IdAuthenticationSSPI.pas +++ b/Lib/Protocols/IdAuthenticationSSPI.pas @@ -1,1322 +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} - -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} - -implementation - -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); - -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 8ce7d254c..ccfd332fe 100644 --- a/Lib/Protocols/IdCompilerDefines.inc +++ b/Lib/Protocols/IdCompilerDefines.inc @@ -1,2091 +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 -{.$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 +{$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 158b3d833..55542179f 100644 --- a/Lib/Protocols/IdSSH.pas +++ b/Lib/Protocols/IdSSH.pas @@ -1,178 +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, - 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:TIdThreadHandle ): 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:TIdThreadHandle ): 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 7160051fb..38ade4c1b 100644 --- a/Lib/Protocols/IdSSPI.pas +++ b/Lib/Protocols/IdSSPI.pas @@ -1,2896 +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} - -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 - -*) - -implementation - -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; - -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/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/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 8ce7d254c..ccfd332fe 100644 --- a/Lib/System/IdCompilerDefines.inc +++ b/Lib/System/IdCompilerDefines.inc @@ -1,2091 +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 -{.$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 +{$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 2651f1715..5038e7abc 100644 --- a/Lib/System/IdTransactedFileStream.pas +++ b/Lib/System/IdTransactedFileStream.pas @@ -1,360 +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. - FHandle := INVALID_HANDLE_VALUE; - 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 4f7df261f..ab842c652 100644 --- a/Lib/System/IdWinsock2.pas +++ b/Lib/System/IdWinsock2.pas @@ -1,9023 +1,9023 @@ -{ - $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. - -} - -{$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; - - -//============================================================= -implementation -//============================================================= - -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; - -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. + +} + +{$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; + + +//============================================================= +implementation +//============================================================= + +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; + +end. + diff --git a/Lib/System/IdWship6.pas b/Lib/System/IdWship6.pas index 4699f35b5..c584e1d96 100644 --- a/Lib/System/IdWship6.pas +++ b/Lib/System/IdWship6.pas @@ -1,1545 +1,1545 @@ -{ - $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 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; - -implementation - -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; - -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 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; + +implementation + +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; + +end. 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/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 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/- + + + + 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. 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..d16bb0bd7 --- /dev/null +++ b/lazarus-fpc/indysystem.lpk @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lazarus-fpc/indysystem.pas b/lazarus-fpc/indysystem.pas new file mode 100644 index 000000000..5cfd20cfa --- /dev/null +++ b/lazarus-fpc/indysystem.pas @@ -0,0 +1,25 @@ +{ 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, IdResourceStringsIconv, IdResourceStringsKylixCompat, + IdResourceStringsTextEncoding, IdResourceStringsUnix, IdStack, + IdStackBSDBase, IdStackConsts, IdStream, IdStruct, IdTransactedFileStream, + IdAntiFreezeBase, LazarusPackageIntf; + +implementation + +procedure Register; +begin +end; + +initialization + RegisterPackage('indysystem', @Register); +end.