{
   $Id:$

   @file eautil.pas

   @brief

   (c) osFree Project 2003, <http://www.osFree.org>
   for licence see licence.txt in root directory, or project website

   @author Yuri Prokushev <prokushev@freemail.ru>
}

constructor tEAList.Create( const name : string );
var
  PathZ     : Array [ 0..cchMaxPathComp ] of Char;
  FullPathZ : Array [ 0..cchMaxPathComp ] of Char;
  FullNameZ : Array [ 0..cchMaxPathComp ] of Char;
  sr        : FileFindBuf4;
  HDir      : Longint;
  buffer    : Pointer;
  Count     : Longint;
  rc        : ApiRet;
  pEA       : PFea2;
  pEAOP     : pEAop2;
  pFEA      : pFEA2;
  pGEA      : pGEA2;
  offset    : Longint;
  Length    : Longint;
  pEABase   : Pointer;
  EAClass   : tCollectionItemClass;

begin
  inherited Create( tEA );

  // Verify that file exists
  StrPCopy( PathZ, Name );
  DosQueryPathInfo ( PathZ, fil_QueryFullName, FullPathZ, cchMaxPathComp );

  StrECopy( FullNameZ, FullPathZ );
  Count := 1;
  HDir := hdir_System;
  rc := DosFindFirst( PathZ, HDir, file_Directory, sr, SizeOf( sr ), Count, fil_QueryEASize );
  DosFindClose( HDir );
  if rc <> no_Error then
    raise EEAError.CreateFmt( 'File %s not found; rc = %d ', [ Name, rc ] );

  // Set up buffer for list of EA name query
  GetMem( Buffer, sr.cbList );
  Count := -1;
  try
    // Get list of EA names from OS/2
    rc := DosEnumAttribute( enumea_RefType_Path, @FullNameZ, 1, Buffer^, sr.cbList, Count, enumea_Level_No_Value );

    // Reorganize and set up to enumerate values
    pEA := PFEa2( Buffer );
    GetMem( pEAOP, eaopsize );
    try
      pEAOP^.fpGEA2List := Ptr(Longint(pEAOP)+sizeof(EAOP2));
      pGEA := @pEAOP^.fpGEA2List^.List[0];
      offset := 0;

      // Move all EA's to structure for DosQueryPathInfo
      If count <> 0 then
        Repeat
          Inc( ULong( pEA ), offset );
          StrCopy( @pGEA^.szName, @pEA^.szName );
          pGEA^.cbName := pEA^.cbName;
          Offset := pEA^.oNextEntryOffset;
          Length := pGEA^.cbName + Sizeof( pGEA^.cbName ) +
                    sizeof( pGEA^.oNextEntryOffset );
          If length mod 4 <> 0 then
            inc( length, 4-length mod 4 );      // Double word aligned
          If Offset <> 0 then
            pGEA^.oNextEntryOffset := Length
          else
            pGEA^.oNextEntryOffset := 0;

          Inc( ULong( pGEA ), Length );
        Until pEA^.oNextEntryOffset = 0;
      with PEAOP^, PEAOP^.fpGEA2List^ do
        begin
          cbList := pChar(pGEA) - pChar(fpGEA2List);
          fpFEA2List := Ptr( Longint(fpGEA2List) + cbList );
          fpFEA2List^.cbList := eaopsize - (pChar(fpFEA2List) - pChar(pEAOP));
        end;
      // Get list of EA values from OS/2
      rc := DosQueryPathInfo( FullNameZ, fil_QueryEAsFromList, pEAOP^, sizeof( EAOP2 ));

      // Insert data into tEAList class structure
      if ( rc = 0 ) and ( pEAOP^.fpFEA2List^.cbList > 0 ) then
        begin
          Offset := 0;
          pFEA := @pEAOP^.fpFEA2List^.List;
          Repeat
            Inc( ULong( pFEA ), offset );       // Base of this EA
            pEABase := pChar(@pFEA^.szName) + pFEA^.cbName + 1;

            if smallWord( pEABase^ ) = eat_Ascii then
              EAClass := tEA_Ascii              // Create Ascii EA
            else
              EAClass := tEA;                   // Create standard EA
            With Add(EAClass) as tEA do         // Create and add
              SetNameValue( @pFEA^.szName, pFEA^.cbValue, pEABase );
            Offset := pFEA^.oNextEntryOffset;   // Go to next EA in list
          Until Offset = 0;
        end;
        FileName := StrPNew( name );
    finally  // Free memory
      FreeMem( pEAOP, eaopsize );
    end;
  finally
    FreeMem( Buffer, sr.cbList );
  end;
end;
