Пример #1
0
//
// ReadDirectory
//
static void ReadDirectory(void)
{
  int i;
  int total_entries = wad.num_entries;
  lump_t *prev_list;

  fseek(in_file, wad.dir_start, SEEK_SET);

  for (i=0; i < total_entries; i++)
  {
    ReadDirEntry();
  }

  DetermineLevelNames();

  // finally, unlink all lumps and process each one in turn
  
  prev_list = wad.dir_head;
  wad.dir_head = wad.dir_tail = NULL;
  
  while (prev_list)
  {
    lump_t *cur = prev_list;
    prev_list = cur->next;

    ProcessDirEntry(cur);
  }
}
Пример #2
0
long UFSGetDirEntry( CICell ih, char * dirPath, long long * dirIndex,
                     char ** name, long * flags, long * time,
                     FinderInfo * finderInfo, long * infoValid)
{
    long  ret, fileInodeNum, dirFlags;
    Inode tmpInode;

    if (UFSInitPartition(ih) == -1) return -1;

    if (infoValid) *infoValid = 0;

    // Skip a leading '/' if present
    if (*dirPath == '/') dirPath++;
    if (*dirPath == '/') dirPath++;

    ret = ResolvePathToInode(dirPath, &dirFlags, gFileInodePtr, gRootInodePtr);
    if ((ret == -1) || ((dirFlags & kFileTypeMask) != kFileTypeDirectory))
        return -1;

    ret = ReadDirEntry(gFileInodePtr, &fileInodeNum, dirIndex, name);
    if (ret != 0) return ret;

    ReadInode(fileInodeNum, &tmpInode, flags, time);

    return 0;
}
Пример #3
0
static long FindFileInDir( char * fileName, long * flags,
                           InodePtr fileInode, InodePtr dirInode )
{
    long ret, inodeNum, index = 0;
    char *name;

    while (1) {
        ret = ReadDirEntry(dirInode, &inodeNum, &index, &name);
        if (ret == -1) return -1;

        if (strcmp(fileName, name) == 0) break;
    }

    ReadInode(inodeNum, fileInode, flags, 0);

    return 0;
}
Пример #4
0
// ---------------------------------------------------------------------------
// Scans a list of drives for files
// ---------------------------------------------------------------------------
//
void CMPXFolderScanner::ScanL( RArray<TPath>& aDrives )
    {
    MPX_DEBUG1("CMPXFolderScanner::ScanL <---");
    
    // Copy all the other drives we want to scan
    //
    TInt count( aDrives.Count() );
    MPX_DEBUG2("CMPXFolderScanner::ScanL aDrives %d",count);
    for( TInt i=0; i<count; ++i )
        {
        // Check if we are already scanning this drive
        TInt found( iDrivesToScan.FindInOrder( aDrives[i], CompareString ) ); 
        if( found == KErrNotFound )
            {
            iDrivesToScan.Append( aDrives[i] );
            }
        }
    
    // If we were already scanning, don't do it again
    //
    if( !iScanning )
        {
        // Setup the next drive to scan
        //
        if( !SetupNextDriveToScanL() )
            {
            // Kick off the scanning
            iCurDirQueueEntry = iDirQueue[ 0 ];
            iCurFullPath = iCurDirQueueEntry->iFullPath;
            ReadDirEntry();

            // We've started scanning
            iScanning = ETrue;
            }
        else
            {
            // Nothing to scan
            DoScanCompleteL(KErrNone);    
            }        
        }
    MPX_DEBUG1("CMPXFolderScanner::ScanL --->");
    }
Пример #5
0
long Ext2GetDirEntry(CICell ih, char *dirPath, long *dirIndex,
		     char **name, long *flags, long *time)
{
  long  ret, fileInodeNum, dirFlags;
  Inode tmpInode;
  
  if (Ext2InitPartition(ih) == -1) return -1;
  
  // Skip a leading '\' if present
  if (dirPath[0] == '\\') dirPath++;
  ret = ResolvePathToInode(dirPath, &dirFlags, &gFileInode, &gRootInode);
  if ((ret == -1) || ((dirFlags & kFileTypeMask) != kFileTypeDirectory))
    return -1;
  
  ret = ReadDirEntry(&gFileInode, &fileInodeNum, dirIndex, name);
  if (ret != 0) return ret;
  
  ReadInode(fileInodeNum, &tmpInode, flags, time);
  
  return 0;
}
Пример #6
0
static long CountEntriesInRootDirectory(RDWRHandle handle, char attribute)
{
    long count = 0, i;
    struct DirectoryEntry* entry;

    long rootcount = GetNumberOfRootEntries(handle);
    if (!rootcount) return FAIL;

    entry = AllocateDirectoryEntry();
    if (!entry) return FAIL;

    for (i = 0; i < rootcount; i++)
    {
	if (!ReadDirEntry(handle, i, entry))
	{
	   FreeDirectoryEntry(entry);
	   return FAIL;
        }
	if (IsLastLabel(*entry))
	{
	   FreeDirectoryEntry(entry);
	   return count;
	}
        
        if (entry->attribute == LFN_ATTRIBUTES)
        {
           if (IsLFNEntry(entry))
              count++;
        }
        else if ((entry->attribute & attribute) ||
	         (attribute == -1))
        {
	   count++;
        }
    }
    FreeDirectoryEntry(entry);
    return rootcount;
}
Пример #7
0
HRESULT CInArchive::OpenHelp2(IInStream *inStream, CDatabase &database)
{
  if (ReadUInt32() != 1) // version
    return S_FALSE;
  if (ReadUInt32() != 0x28) // Location of header section table
    return S_FALSE;
  UInt32 numHeaderSections = ReadUInt32();
  const unsigned kNumHeaderSectionsMax = 5;
  if (numHeaderSections != kNumHeaderSectionsMax)
    return S_FALSE;

  IsArc = true;

  ReadUInt32(); // Len of post-header table
  Byte g[16];
  ReadGUID(g);  // {0A9007C1-4076-11D3-8789-0000F8105754}

  // header section table
  UInt64 sectionOffsets[kNumHeaderSectionsMax];
  UInt64 sectionSizes[kNumHeaderSectionsMax];
  UInt32 i;
  for (i = 0; i < numHeaderSections; i++)
  {
    sectionOffsets[i] = ReadUInt64();
    sectionSizes[i] = ReadUInt64();
    UInt64 end = sectionOffsets[i] + sectionSizes[i];
    database.UpdatePhySize(end);
  }
  
  // Post-Header
  ReadUInt32(); // 2
  ReadUInt32(); // 0x98: offset to CAOL from beginning of post-header)
  // ----- Directory information
  ReadUInt64(); // Chunk number of top-level AOLI chunk in directory, or -1
  ReadUInt64(); // Chunk number of first AOLL chunk in directory
  ReadUInt64(); // Chunk number of last AOLL chunk in directory
  ReadUInt64(); // 0 (unknown)
  ReadUInt32(); // $2000 (Directory chunk size of directory)
  ReadUInt32(); // Quickref density for main directory, usually 2
  ReadUInt32(); // 0 (unknown)
  ReadUInt32(); // Depth of main directory index tree
                // 1 there is no index, 2 if there is one level of AOLI chunks.
  ReadUInt64(); // 0 (unknown)
  UInt64 numDirEntries = ReadUInt64(); // Number of directory entries
  // ----- Directory Index Information
  ReadUInt64(); // -1 (unknown, probably chunk number of top-level AOLI in directory index)
  ReadUInt64(); // Chunk number of first AOLL chunk in directory index
  ReadUInt64(); // Chunk number of last AOLL chunk in directory index
  ReadUInt64(); // 0 (unknown)
  ReadUInt32(); // $200 (Directory chunk size of directory index)
  ReadUInt32(); // Quickref density for directory index, usually 2
  ReadUInt32(); // 0 (unknown)
  ReadUInt32(); // Depth of directory index index tree.
  ReadUInt64(); // Possibly flags -- sometimes 1, sometimes 0.
  ReadUInt64(); // Number of directory index entries (same as number of AOLL
               // chunks in main directory)
  
  // (The obvious guess for the following two fields, which recur in a number
  // of places, is they are maximum sizes for the directory and directory index.
  // However, I have seen no direct evidence that this is the case.)

  ReadUInt32(); // $100000 (Same as field following chunk size in directory)
  ReadUInt32(); // $20000 (Same as field following chunk size in directory index)

  ReadUInt64(); // 0 (unknown)
  if (ReadUInt32() != kSignature_CAOL)
    return S_FALSE;
  if (ReadUInt32() != 2) // (Most likely a version number)
    return S_FALSE;
  UInt32 caolLength = ReadUInt32(); // $50 (Len of the CAOL section, which includes the ITSF section)
  if (caolLength >= 0x2C)
  {
    /* UInt32 c7 = */ ReadUInt16(); // Unknown.  Remains the same when identical files are built.
              // Does not appear to be a checksum.  Many files have
              // 'HH' (HTML Help?) here, indicating this may be a compiler ID
              //  field.  But at least one ITOL/ITLS compiler does not set this
              // field to a constant value.
    ReadUInt16(); // 0 (Unknown.  Possibly part of 00A4 field)
    ReadUInt32(); // Unknown.  Two values have been seen -- $43ED, and 0.
    ReadUInt32(); // $2000 (Directory chunk size of directory)
    ReadUInt32(); // $200 (Directory chunk size of directory index)
    ReadUInt32(); // $100000 (Same as field following chunk size in directory)
    ReadUInt32(); // $20000 (Same as field following chunk size in directory index)
    ReadUInt32(); // 0 (unknown)
    ReadUInt32(); // 0 (Unknown)
    if (caolLength == 0x2C)
    {
      // fprintf(stdout, "\n !!!NewFormat\n");
      // fflush(stdout);
      database.ContentOffset = 0; // maybe we must add database.StartPosition here?
      database.NewFormat = true;
    }
    else if (caolLength == 0x50)
    {
      ReadUInt32(); // 0 (Unknown)
      if (ReadUInt32() != kSignature_ITSF)
        return S_FALSE;
      if (ReadUInt32() != 4) // $4 (Version number -- CHM uses 3)
        return S_FALSE;
      if (ReadUInt32() != 0x20) // $20 (length of ITSF)
        return S_FALSE;
      UInt32 unknown = ReadUInt32();
      if (unknown != 0 && unknown != 1) // = 0 for some HxW files, 1 in other cases;
        return S_FALSE;
      database.ContentOffset = database.StartPosition + ReadUInt64();
      /* UInt32 timeStamp = */ ReadUInt32();
          // A timestamp of some sort.
          // Considered as a big-endian DWORD, it appears to contain
          // seconds (MSB) and fractional seconds (second byte).
          // The third and fourth bytes may contain even more fractional
          // bits.  The 4 least significant bits in the last byte are constant.
      /* UInt32 lang = */ ReadUInt32(); // BE?
    }
    else
      return S_FALSE;
  }

  // Section 0
  ReadChunk(inStream, database.StartPosition + sectionOffsets[0], sectionSizes[0]);
  if (sectionSizes[0] < 0x18)
    return S_FALSE;
  if (ReadUInt32() != 0x01FE)
    return S_FALSE;
  ReadUInt32(); // unknown:  0
  UInt64 fileSize = ReadUInt64();
  database.UpdatePhySize(fileSize);
  ReadUInt32(); // unknown:  0
  ReadUInt32(); // unknown:  0

  // Section 1: The Directory Listing
  ReadChunk(inStream, database.StartPosition + sectionOffsets[1], sectionSizes[1]);
  if (ReadUInt32() != kSignature_IFCM)
    return S_FALSE;
  if (ReadUInt32() != 1) // (probably a version number)
    return S_FALSE;
  UInt32 dirChunkSize = ReadUInt32(); // $2000
  if (dirChunkSize < 64)
    return S_FALSE;
  ReadUInt32(); // $100000  (unknown)
  ReadUInt32(); // -1 (unknown)
  ReadUInt32(); // -1 (unknown)
  UInt32 numDirChunks = ReadUInt32();
  ReadUInt32(); // 0 (unknown, probably high word of above)

  for (UInt32 ci = 0; ci < numDirChunks; ci++)
  {
    UInt64 chunkPos = _inBuffer.GetProcessedSize();
    if (ReadUInt32() == kSignature_AOLL)
    {
      UInt32 quickrefLength = ReadUInt32(); // Len of quickref area at end of directory chunk
      if (quickrefLength > dirChunkSize || quickrefLength < 2)
        return S_FALSE;
      ReadUInt64(); // Directory chunk number
            // This must match physical position in file, that is
            // the chunk size times the chunk number must be the
            // offset from the end of the directory header.
      ReadUInt64(); // Chunk number of previous listing chunk when reading
                    // directory in sequence (-1 if first listing chunk)
      ReadUInt64(); // Chunk number of next listing chunk when reading
                    // directory in sequence (-1 if last listing chunk)
      ReadUInt64(); // Number of first listing entry in this chunk
      ReadUInt32(); // 1 (unknown -- other values have also been seen here)
      ReadUInt32(); // 0 (unknown)
      
      unsigned numItems = 0;
      for (;;)
      {
        UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos;
        UInt32 offsetLimit = dirChunkSize - quickrefLength;
        if (offset > offsetLimit)
          return S_FALSE;
        if (offset == offsetLimit)
          break;
        if (database.NewFormat)
        {
          UInt16 nameLen = ReadUInt16();
          if (nameLen == 0)
            return S_FALSE;
          UString name;
          ReadUString((unsigned)nameLen, name);
          AString s;
          ConvertUnicodeToUTF8(name, s);
          Byte b = ReadByte();
          s.Add_Space();
          PrintByte(b, s);
          s.Add_Space();
          UInt64 len = ReadEncInt();
          // then number of items ?
          // then length ?
          // then some data (binary encoding?)
          while (len-- != 0)
          {
            b = ReadByte();
            PrintByte(b, s);
          }
          database.NewFormatString += s;
          database.NewFormatString += "\r\n";
        }
        else
        {
          RINOK(ReadDirEntry(database));
        }
        numItems++;
      }
      Skip(quickrefLength - 2);
      if (ReadUInt16() != numItems)
        return S_FALSE;
      if (numItems > numDirEntries)
        return S_FALSE;
      numDirEntries -= numItems;
    }
    else
      Skip(dirChunkSize - 4);
  }
  return numDirEntries == 0 ? S_OK : S_FALSE;
}
Пример #8
0
HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database)
{
  UInt32 headerSize = ReadUInt32();
  if (headerSize != 0x60)
    return S_FALSE;
  database.PhySize = headerSize;

  UInt32 unknown1 = ReadUInt32();
  if (unknown1 != 0 && unknown1 != 1) // it's 0 in one .sll file
    return S_FALSE;

  IsArc = true;

  /* UInt32 timeStamp = */ ReadUInt32();
      // Considered as a big-endian DWORD, it appears to contain seconds (MSB) and
      // fractional seconds (second byte).
      // The third and fourth bytes may contain even more fractional bits.
      // The 4 least significant bits in the last byte are constant.
  /* UInt32 lang = */ ReadUInt32();
  Byte g[16];
  ReadGUID(g); // {7C01FD10-7BAA-11D0-9E0C-00A0-C922-E6EC}
  ReadGUID(g); // {7C01FD11-7BAA-11D0-9E0C-00A0-C922-E6EC}
  const unsigned kNumSections = 2;
  UInt64 sectionOffsets[kNumSections];
  UInt64 sectionSizes[kNumSections];
  unsigned i;
  for (i = 0; i < kNumSections; i++)
  {
    sectionOffsets[i] = ReadUInt64();
    sectionSizes[i] = ReadUInt64();
    UInt64 end = sectionOffsets[i] + sectionSizes[i];
    database.UpdatePhySize(end);
  }
  // if (chmVersion == 3)
    database.ContentOffset = ReadUInt64();
  /*
  else
    database.ContentOffset = database.StartPosition + 0x58
  */

  // Section 0
  ReadChunk(inStream, sectionOffsets[0], sectionSizes[0]);
  if (sectionSizes[0] < 0x18)
    return S_FALSE;
  if (ReadUInt32() != 0x01FE)
    return S_FALSE;
  ReadUInt32(); // unknown:  0
  UInt64 fileSize = ReadUInt64();
  database.UpdatePhySize(fileSize);
  ReadUInt32(); // unknown:  0
  ReadUInt32(); // unknown:  0

  // Section 1: The Directory Listing
  ReadChunk(inStream, sectionOffsets[1], sectionSizes[1]);
  if (ReadUInt32() != kSignature_ITSP)
    return S_FALSE;
  if (ReadUInt32() != 1) // version
    return S_FALSE;
  /* UInt32 dirHeaderSize = */ ReadUInt32();
  ReadUInt32(); // 0x0A (unknown)
  UInt32 dirChunkSize = ReadUInt32(); // $1000
  if (dirChunkSize < 32)
    return S_FALSE;
  /* UInt32 density = */ ReadUInt32(); //  "Density" of quickref section, usually 2.
  /* UInt32 depth = */ ReadUInt32(); //  Depth of the index tree: 1 there is no index,
                               // 2 if there is one level of PMGI chunks.

  /* UInt32 chunkNumber = */ ReadUInt32(); //  Chunk number of root index chunk, -1 if there is none
                                     // (though at least one file has 0 despite there being no
                                     // index chunk, probably a bug.)
  /* UInt32 firstPmglChunkNumber = */ ReadUInt32(); // Chunk number of first PMGL (listing) chunk
  /* UInt32 lastPmglChunkNumber = */ ReadUInt32();  // Chunk number of last PMGL (listing) chunk
  ReadUInt32(); // -1 (unknown)
  UInt32 numDirChunks = ReadUInt32(); // Number of directory chunks (total)
  /* UInt32 windowsLangId = */ ReadUInt32();
  ReadGUID(g);  // {5D02926A-212E-11D0-9DF9-00A0C922E6EC}
  ReadUInt32(); // 0x54 (This is the length again)
  ReadUInt32(); // -1 (unknown)
  ReadUInt32(); // -1 (unknown)
  ReadUInt32(); // -1 (unknown)

  for (UInt32 ci = 0; ci < numDirChunks; ci++)
  {
    UInt64 chunkPos = _inBuffer.GetProcessedSize();
    if (ReadUInt32() == kSignature_PMGL)
    {
      // The quickref area is written backwards from the end of the chunk.
      // One quickref entry exists for every n entries in the file, where n
      // is calculated as 1 + (1 << quickref density). So for density = 2, n = 5.

      UInt32 quickrefLength = ReadUInt32(); // Len of free space and/or quickref area at end of directory chunk
      if (quickrefLength > dirChunkSize || quickrefLength < 2)
        return S_FALSE;
      ReadUInt32(); // Always 0
      ReadUInt32(); // Chunk number of previous listing chunk when reading
                    // directory in sequence (-1 if this is the first listing chunk)
      ReadUInt32(); // Chunk number of next  listing chunk when reading
                    // directory in sequence (-1 if this is the last listing chunk)
      unsigned numItems = 0;
      
      for (;;)
      {
        UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos;
        UInt32 offsetLimit = dirChunkSize - quickrefLength;
        if (offset > offsetLimit)
          return S_FALSE;
        if (offset == offsetLimit)
          break;
        RINOK(ReadDirEntry(database));
        numItems++;
      }
      
      Skip(quickrefLength - 2);
      
      unsigned rrr = ReadUInt16();
      if (rrr != numItems)
      {
        // Lazarus 9-26-2 chm contains 0 here.
        if (rrr != 0)
          return S_FALSE;
      }
    }
    else
      Skip(dirChunkSize - 4);
  }
  return S_OK;
}
Пример #9
0
// ---------------------------------------------------------------------------
// Continue Scanning for more files
// ---------------------------------------------------------------------------
//
TBool CMPXFolderScanner::DoScanL()
    {
    MPX_DEBUG1("CMPXFolderScanner::DoScanL <---");
    TBool done (EFalse);
    TBool blocked ( EFalse );

    // read successfully
    if ( iStatus == KErrNone || iStatus == KErrEof )
        {
        TBuf<KMaxFileName> buffer;
        const TEntry* entry = NULL;
        TInt numEntries( iCurDirQueueEntry->iEntryArray.Count() );

        // process the entry one by one
        while ( iCurDirQueueEntry->iPos < numEntries )
            {
            entry = iCurDirQueueEntry->NextEntry();
            buffer.Zero();

            // Generates the full name of the entry
            buffer.Append( *iCurFullPath );
            buffer.Append( entry->iName );

            if ( entry->IsDir() ) // entry is a directory
                {
                buffer.Append( KTxtBackSlash );

                blocked = iObserver.IsPathBlockedL( buffer );

                if ( !blocked )
                    {
                    CDirQueueEntry* newEntry = CDirQueueEntry::NewL( buffer );
                    TInt err = newEntry->iDir.Open( iFs,
                                                    buffer,
                                             KEntryAttNormal | KEntryAttDir );
                    if ( err == KErrNone )
                        {
                        CDirQueueEntry::PushL( iDirQueue, newEntry );
                        }
                    else
                        {
                        delete newEntry;
                        }
                    }
                }
            else // entry is a file
                {
                TInt index = iObserver.IsMediaFileL( buffer );
                if( KErrNotFound != index )
                    {
                    iObserver.HandleFileAdditionL( buffer, index );
                    }
                }
            if ( iCurDirQueueEntry->iPos % KFileNumBreakCount == 0 )
                {
                return done;
                }
            }
        }

    // this dir has other entries to read
    if ( iStatus == KErrNone )
        {
        iCurDirQueueEntry->ResetPosition();
        ReadDirEntry();
        }

    // there is nothing to read or some error has occured during reading,
    // try to move to next dir
    else
        {
        CDirQueueEntry::PopAndDestroy( iDirQueue );
        if ( iDirQueue.Count() || !SetupNextDriveToScanL() )
            {
            iCurDirQueueEntry = iDirQueue[ 0 ];
            iCurFullPath = iCurDirQueueEntry->iFullPath;
            ReadDirEntry();
            }
        else // there is nothing to scan
            {
            done = ETrue;
            }
        }
        
    MPX_DEBUG1("CMPXFolderScanner::DoScanL --->");
    return done;
    }
Пример #10
0
/**
Reads a directory entry from the specified position in the core image file.
This method moves the position of the file to the specified value and then
uses the other ReadDirEntry method to read the directory entry

@param aDir memory where the directory entry is read from the file. This is only valid if KErrNone is returned.
@param aFilePos position in the core image file where the directory
entry is located
@return KErrNone for successful read or error number if failed 
@see RCoreImageReader::ReadDirEntry(TRofsDir* aDir)
*/
TInt RCoreImageReader::ReadDirEntry(TRofsDir& aDir, long aFilePos)
	{
	SetFilePosition(aFilePos);
	return ReadDirEntry(aDir);
	}