sdk: const correctness
[sdk] / ecere / src / sys / EARArchive.ec
index bff43f4..f97f45e 100644 (file)
@@ -7,7 +7,7 @@ namespace sys;
 import "System"
 import "BufferedFile"
 
-#define OFFSET(s, m) ((uint) (&((s *) 0)->m))
+#define OFFSET(s, m) ((uint)(uintptr) (&((s *) 0)->m))
 #define MDWORD(a,b) ((((uint32)((uint16)(b)))<<16)+((uint16)(a)))
 
 #define EAR_RECOGNITION { 'e', 'A', 'R', 228, 11, 12, 3, 0 }
@@ -21,10 +21,10 @@ static class FreeBlock : struct
 };
 
 static struct EARHeader
-{                                               
-   byte recognition[sizeof(earRecognition)] __attribute__((packed));
-   uint version                            __attribute__((packed));
-   FileSize totalSize                      __attribute__((packed));
+{
+   byte recognition[sizeof(earRecognition)];
+   uint version                             __attribute__((packed));
+   FileSize totalSize                       __attribute__((packed));
 };
 
 static enum EAREntryType { ENTRY_FILE = 1, ENTRY_FOLDER = 2 };
@@ -39,13 +39,19 @@ static struct EAREntry
    // null terminated file name follows
 };
 
-static File EAROpenArchive(char * archive, EARHeader header)
+static File EAROpenArchive(const char * archive, EARHeader header)
 {
    File f = null;
    if(archive[0] == ':')
    {
       char moduleName[MAX_LOCATION];
-      if(LocateModule(archive + 1, moduleName))
+      const char * name = archive + 1;
+#if defined(__ANDROID__)
+      if(!name[0])
+         name = ((SubModule)__thisModule.application.modules.first).next.module.name;
+#endif
+
+      if(LocateModule(name, moduleName))
          f = FileOpen(moduleName, read);
    }
    else
@@ -56,7 +62,7 @@ static File EAROpenArchive(char * archive, EARHeader header)
 
       // First attempt to treat this as an archive file
       if(f.Read(header, sizeof(EARHeader), 1) == 1 &&
-         !strncmp(header.recognition, earRecognition, sizeof(earRecognition)))
+         !memcmp(header.recognition, earRecognition, sizeof(earRecognition)))
          return f;
 
       // Then try to see if an archive is at the end of the file
@@ -64,7 +70,7 @@ static File EAROpenArchive(char * archive, EARHeader header)
       f.Read(&archiveSize, sizeof(uint), 1);
       f.Seek(-(int)archiveSize, end);
       if(f.Read(header, sizeof(EARHeader), 1) == 1 &&
-         !strncmp(header.recognition, earRecognition, sizeof(earRecognition)))
+         !memcmp(header.recognition, earRecognition, sizeof(earRecognition)))
          return f;
 
       delete f;
@@ -72,7 +78,7 @@ static File EAROpenArchive(char * archive, EARHeader header)
    return null;
 }
 
-static FileAttribs EARGetEntry(File f, EAREntry entry, char * name, char * path)
+static FileAttribs EARGetEntry(File f, EAREntry entry, const char * name, char * path)
 {
    uint first = 0, last = 0;
    if(!name[0])
@@ -92,7 +98,7 @@ static FileAttribs EARGetEntry(File f, EAREntry entry, char * name, char * path)
       for(;;)
       {
          char fileName[MAX_FILENAME];
-         
+
          f.Read(entry, sizeof(EAREntry), 1);
          f.Read(fileName, 1, entry.nameLen);
          fileName[entry.nameLen] = '\0';
@@ -153,6 +159,7 @@ class EARArchive : Archive
 
          return end;
       }
+      return 0;
    }
 
    ~EARArchive()
@@ -163,7 +170,11 @@ class EARArchive : Archive
          Defrag(rootDir);
          archiveStart += Update();
       }
-
+      if(f && writeAccess)
+      {
+         f.Flush();
+         f.Unlock(0, 0, true);
+      }
       delete f;
 
       /*if(rootDir && writeAccess)
@@ -171,7 +182,7 @@ class EARArchive : Archive
          // Fix the size of the archive
          FileTruncate(path, archiveStart);
       }*/
-      
+
       freeBlocks.Free(null);
    }
 
@@ -181,14 +192,13 @@ class EARArchive : Archive
       return true;
    }
 
-   ArchiveDir OpenDirectory(char * name, FileStats stats, ArchiveAddMode addMode)
+   ArchiveDir OpenDirectory(const char * name, FileStats stats, ArchiveAddMode addMode)
    {
       ArchiveDir result = null;
       EARArchiveDir dir { readOnly = addMode == readOnlyDir };
       if(dir)
       {
          char namePart[MAX_LOCATION] = "", nameRest[MAX_LOCATION];
-         uint position;
 
          dir.archive = this;
 
@@ -219,7 +229,7 @@ class EARArchive : Archive
             rootDir = Position(2*sizeof(uint));
             dir.position = rootDir;
          }
-         
+
          result = dir;
 
          // Open rest of directory...
@@ -293,7 +303,7 @@ class EARArchive : Archive
          if(f.Seek(dirPosition + sizeof(uint), start))
             f.Write(&last, sizeof(uint), 1);
       }
-      
+
       for(; position; position = next)
       {
          EAREntry entry { };
@@ -317,7 +327,7 @@ class EARArchive : Archive
                Defrag(position + sizeof(EAREntry) + entry.nameLen);
          }
          else
-            return 0;
+            return;
       }
 
       // Move all the blocks
@@ -360,13 +370,13 @@ class EARArchive : Archive
       }
    }
 
-   uint Find(EARArchiveDir directory, char * namePart, EAREntry entry)
+   uint Find(EARArchiveDir directory, const char * namePart, EAREntry entry)
    {
       uint position;
       for(position = directory.first; position; position = entry.next)
       {
          char fileName[MAX_FILENAME];
-      
+
          if(f.Seek(position, start) && f.Read(entry, sizeof(EAREntry), 1))
          {
             if(entry.nameLen > MAX_FILENAME)
@@ -389,12 +399,12 @@ class EARArchive : Archive
    void AddFreeBlock(uint position, uint size)
    {
       FreeBlock block, prevBlock, nextBlock = null;
-      
+
       // Find the previous and next free block
       prevBlock = null;
       for(block = freeBlocks.first; block; block = block.next)
          if(block.end < position)
-            prevBlock = block; 
+            prevBlock = block;
          else
          {
             nextBlock = block;
@@ -483,12 +493,12 @@ class EARArchive : Archive
          size = sizeof(EAREntry) + entry.nameLen + (entry.cSize ? entry.cSize : entry.size);
 
       // Unlink this file
-      if(entry.prev) 
+      if(entry.prev)
       {
          f.Seek(entry.prev + OFFSET(EAREntry, next), start);
          f.Write(&entry.next, sizeof(uint), 1);
       }
-      if(entry.next) 
+      if(entry.next)
       {
          f.Seek(entry.next + OFFSET(EAREntry, prev), start);
          f.Write(&entry.prev, sizeof(uint), 1);
@@ -503,13 +513,12 @@ class EARArchive : Archive
       // bf.handle = f;
    }
 
-   File FileOpen(char * name)
+   File FileOpen(const char * name)
    {
       File result = null;
       EARFile file {};
       if(file)
       {
-         char fileName[MAX_LOCATION];
          EAREntry entry { };
 
          f.Seek(archiveStart + sizeof(EARHeader), start);
@@ -524,7 +533,11 @@ class EARArchive : Archive
                   if(compressed)
                   {
                      if(f.Read(compressed, 1, entry.cSize) == entry.cSize)
-                        uncompress(uncompressed, (uint *)&entry.size, compressed, entry.cSize);
+                     {
+                        unsigned long destLen = entry.size;
+                        uncompress(uncompressed, &destLen, compressed, entry.cSize);
+                        entry.size = (FileSize)destLen;  // TODO: Support 64 bit file sizes
+                     }
                      delete compressed;
                   }
 
@@ -571,7 +584,11 @@ class EARArchive : Archive
             if(compressed)
             {
                if(f.Read(compressed, 1, entry.cSize) == entry.cSize)
-                  uncompress(uncompressed, (uint *)&entry.size, compressed, entry.cSize);
+               {
+                  unsigned long destLen = entry.size;
+                  uncompress(uncompressed, &destLen, compressed, entry.cSize);
+                  entry.size = (FileSize)destLen;
+               }
                delete compressed;
             }
 
@@ -592,7 +609,7 @@ class EARArchive : Archive
       return file;
    }
 
-   FileAttribs FileExists(char * fileName)
+   FileAttribs FileExists(const char * fileName)
    {
       FileAttribs result;
       EAREntry entry { };
@@ -605,7 +622,7 @@ class EARArchive : Archive
    {
       uint first, last;
       if(!f.Read(&first, sizeof(uint), 1))
-         return 0;
+         return;
 #ifdef _DEBUG
       if(first > f.GetSize())
       {
@@ -681,13 +698,12 @@ class EARArchiveDir : ArchiveDir
       }
    }
 
-   File FileOpen(char * name)
+   File FileOpen(const char * name)
    {
       File result = null;
       EARFile file {};
       if(file)
       {
-         char fileName[MAX_LOCATION];
          EAREntry entry { };
 
          archive.f.Seek(position, start);
@@ -702,7 +718,11 @@ class EARArchiveDir : ArchiveDir
                   if(compressed)
                   {
                      if(archive.f.Read(compressed, 1, entry.cSize) == entry.cSize)
-                        uncompress(uncompressed, (uint *)&entry.size, compressed, entry.cSize);
+                     {
+                        unsigned long destLen = entry.size;
+                        uncompress(uncompressed, &destLen, compressed, entry.cSize);
+                        entry.size = (FileSize)destLen;
+                     }
                      delete compressed;
                   }
 
@@ -730,7 +750,7 @@ class EARArchiveDir : ArchiveDir
       return result;
    }
 
-   FileAttribs FileExists(char * fileName)
+   FileAttribs FileExists(const char * fileName)
    {
       FileAttribs result;
       EAREntry entry { };
@@ -739,7 +759,7 @@ class EARArchiveDir : ArchiveDir
       return result;
    }
 
-   ArchiveDir OpenDirectory(char * name, FileStats stats, ArchiveAddMode addMode)
+   ArchiveDir OpenDirectory(const char * name, FileStats stats, ArchiveAddMode addMode)
    {
       ArchiveDir result = null;
       EARArchiveDir dir { readOnly = addMode == readOnlyDir };
@@ -757,7 +777,7 @@ class EARArchiveDir : ArchiveDir
             strcpy(namePart, DIR_SEPS);
 
          // Search for directory
-         
+
          position = archive.Find(this, namePart, entry);
          if(position)
          {
@@ -772,9 +792,9 @@ class EARArchiveDir : ArchiveDir
 
                archive.f.Read(&dir.first, sizeof(uint), 1);
                archive.f.Read(&dir.last, sizeof(uint), 1);
-               
+
                result = dir;
-            }               
+            }
          }
 
          // If directory doesn't exist already
@@ -832,7 +852,7 @@ class EARArchiveDir : ArchiveDir
       return result;
    }
 
-   bool Delete(char * name)
+   bool Delete(const char * name)
    {
       EAREntry entry { };
       uint position;
@@ -841,7 +861,7 @@ class EARArchiveDir : ArchiveDir
       strcpy(namePart, name);
       if(!strcmp(namePart, "/") || !strcmp(namePart, "\\"))
          strcpy(namePart, DIR_SEPS);
-  
+
       position = archive.Find(this, namePart, entry);
       if(position)
       {
@@ -851,7 +871,7 @@ class EARArchiveDir : ArchiveDir
       return false;
    }
 
-   bool Move(char * name, EARArchiveDir to)
+   bool Move(const char * name, EARArchiveDir to)
    {
       bool result = false;
       if(position != to.position)
@@ -873,7 +893,7 @@ class EARArchiveDir : ArchiveDir
                archive.f.Seek(entry.prev + OFFSET(EAREntry, next), start);
                archive.f.Write(&entry.next, sizeof(uint), 1);
             }
-            if(entry.next) 
+            if(entry.next)
             {
                archive.f.Seek(entry.next + OFFSET(EAREntry, prev), start);
                archive.f.Write(&entry.prev, sizeof(uint), 1);
@@ -904,7 +924,7 @@ class EARArchiveDir : ArchiveDir
       return result;
    }
 
-   bool Rename(char * name, char * newName)
+   bool Rename(const char * name, const char * newName)
    {
       bool result = false;
       EAREntry entry { };
@@ -926,7 +946,7 @@ class EARArchiveDir : ArchiveDir
             dataSize = 2 * sizeof(uint);
          else
             dataSize = entry.cSize ? entry.cSize : entry.size;
-      
+
          newEntry.nameLen = strlen(newName);
          if(newEntry.nameLen > entry.nameLen)
          {
@@ -938,12 +958,12 @@ class EARArchiveDir : ArchiveDir
             archive.f.Write(newName, sizeof(char), newEntry.nameLen);
 
             // Fix the links
-            if(entry.prev) 
+            if(entry.prev)
             {
                archive.f.Seek(entry.prev + OFFSET(EAREntry, next), start);
                archive.f.Write(&newPosition, sizeof(uint), 1);
             }
-            if(entry.next) 
+            if(entry.next)
             {
                archive.f.Seek(entry.next + OFFSET(EAREntry, prev), start);
                archive.f.Write(&newPosition, sizeof(uint), 1);
@@ -961,7 +981,7 @@ class EARArchiveDir : ArchiveDir
 
             // There will be free space at the end of an entry with a shorter new name
             if(newEntry.nameLen < entry.nameLen)
-               archive.AddFreeBlock(position + sizeof(EAREntry) + newEntry.nameLen + dataSize, entry.nameLen - newEntry.nameLen);            
+               archive.AddFreeBlock(position + sizeof(EAREntry) + newEntry.nameLen + dataSize, entry.nameLen - newEntry.nameLen);
          }
          if(entry.nameLen != newEntry.nameLen)
          {
@@ -1009,7 +1029,7 @@ class EARArchiveDir : ArchiveDir
       return result;
    }
 
-   bool AddFromFile(char * name, File input, FileStats stats, ArchiveAddMode addMode, int compression, int * ratio, uint * newPosition)
+   bool AddFromFile(const char * name, File input, FileStats stats, ArchiveAddMode addMode, int compression, int * ratio, uint * newPosition)
    {
       // Search for identical entry
       EAREntry oldEntry;
@@ -1017,7 +1037,7 @@ class EARArchiveDir : ArchiveDir
       return _AddFromFileAtPosition(oldEntry, oldPosition, name, input, stats, addMode, compression, ratio, newPosition);
    }
 
-   bool AddFromFileAtPosition(uint oldPosition, char * name, File input, FileStats stats, ArchiveAddMode addMode, int compression, int * ratio, uint * newPosition)
+   bool AddFromFileAtPosition(uint oldPosition, const char * name, File input, FileStats stats, ArchiveAddMode addMode, int compression, int * ratio, uint * newPosition)
    {
       EAREntry oldEntry;
       if(oldPosition)
@@ -1028,9 +1048,8 @@ class EARArchiveDir : ArchiveDir
       return _AddFromFileAtPosition(oldEntry, oldPosition, name, input, stats, addMode, compression, ratio, newPosition);
    }
 
-   bool _AddFromFileAtPosition(EAREntry oldEntry, uint oldPosition, char * name, File input, FileStats stats, ArchiveAddMode addMode, int compression, int * ratio, uint * newPosition)
+   bool _AddFromFileAtPosition(EAREntry oldEntry, uint oldPosition, const char * name, File input, FileStats stats, ArchiveAddMode addMode, int compression, int * ratio, uint * newPosition)
    {
-      bool result = false;
       bool skip = false;
       FileStats oldStats { };
 
@@ -1054,9 +1073,9 @@ class EARArchiveDir : ArchiveDir
             break;
          // Only updates changed files
          case refresh:
-            if(oldPosition && 
-                 (oldEntry.size != stats.size || 
-                  oldEntry.modified != (TimeStamp32)stats.modified || 
+            if(oldPosition &&
+                 (oldEntry.size != stats.size ||
+                  oldEntry.modified != (TimeStamp32)stats.modified ||
                   oldEntry.created != (TimeStamp32)stats.created))
                   archive.Delete(this, oldPosition, oldEntry);
             else
@@ -1066,8 +1085,8 @@ class EARArchiveDir : ArchiveDir
          case update:
             if(oldPosition)
             {
-               if(oldEntry.size != stats.size || 
-                  oldEntry.modified != (TimeStamp32)stats.modified || 
+               if(oldEntry.size != stats.size ||
+                  oldEntry.modified != (TimeStamp32)stats.modified ||
                   oldEntry.created != (TimeStamp32)stats.created)
                   archive.Delete(this, oldPosition, oldEntry);
                else
@@ -1087,11 +1106,11 @@ class EARArchiveDir : ArchiveDir
          entry.prev = last;
          entry.next = 0;
          entry.type = ENTRY_FILE;
-         
+
          entry.size = stats.size;
          entry.created = (TimeStamp32)stats.created;
          entry.modified = (TimeStamp32)stats.modified;
-      
+
          if(compression)
          {
             byte * uncompressed = new byte[entry.size];
@@ -1099,11 +1118,14 @@ class EARArchiveDir : ArchiveDir
             {
                if(input.Read(uncompressed, 1, entry.size) == entry.size)
                {
-                  entry.cSize = entry.size + entry.size / 1000 + 12;
+                  unsigned long destLen = entry.size + entry.size / 1000 + 12;
 
-                  compressed = new byte[entry.cSize];
+                  compressed = new byte[destLen];
                   if(compressed)
-                     compress2(compressed, (uint *)&entry.cSize, uncompressed, entry.size, compression);
+                  {
+                     compress2(compressed, &destLen, uncompressed, entry.size, compression);
+                     entry.cSize = (FileSize)destLen;
+                  }
                }
                delete uncompressed;
             }
@@ -1166,13 +1188,13 @@ class EARArchiveDir : ArchiveDir
 
          last = position;
          if(!first) first = position;
-         if(newPosition) *newPosition = (bool)position;
+         if(newPosition) *newPosition = position;
       }
       else
       {
          if(newPosition) *newPosition = 0;
       }
-               
+
       // archive.f.handle = archive.f;
       return true;
    }
@@ -1231,7 +1253,7 @@ class EARFile : File
       return read;
    }
 
-   int Write(byte * buffer, uint size, uint count)
+   int Write(const byte * buffer, uint size, uint count)
    {
       return 0;
    }
@@ -1261,7 +1283,7 @@ class EARFile : File
       return false;
    }
 
-   bool Puts(char * string)
+   bool Puts(const char * string)
    {
       return false;
    }
@@ -1271,7 +1293,7 @@ class EARFile : File
       bool result = false;
       switch(mode)
       {
-         case start:   
+         case start:
             if(pos <= (int)size)
             {
                position = pos;
@@ -1302,7 +1324,7 @@ class EARFile : File
             }
             break;
       }
-      return result;   
+      return result;
    }
 
    uint Tell()
@@ -1315,7 +1337,7 @@ class EARFile : File
       return position >= size || (f && f.Eof());
    }
 
-   bool GetSize()
+   uint GetSize()
    {
       return size;
    }
@@ -1323,7 +1345,7 @@ class EARFile : File
 
 class EARFileSystem : FileSystem
 {
-   File ::Open(char * archive, char * name, FileOpenMode mode)
+   File ::Open(const char * archive, const char * name, FileOpenMode mode)
    {
       File result = null;
       if(mode == read)
@@ -1360,7 +1382,11 @@ class EARFileSystem : FileSystem
                         if(compressed)
                         {
                            if(f.Read(compressed, 1, entry.cSize) == entry.cSize)
-                              uncompress(uncompressed, (uint *)&entry.size, compressed, entry.cSize);
+                           {
+                              unsigned long destLen = entry.size;
+                              uncompress(uncompressed, &destLen, compressed, entry.cSize);
+                              entry.size = (FileSize)destLen;
+                           }
                            delete compressed;
                         }
 
@@ -1391,7 +1417,7 @@ class EARFileSystem : FileSystem
       return result;
    }
 
-   FileAttribs ::Exists(char * archive, char * fileName)
+   FileAttribs ::Exists(const char * archive, const char * fileName)
    {
       uint result = 0;
       EARHeader header;
@@ -1405,7 +1431,7 @@ class EARFileSystem : FileSystem
       return result;
    }
 
-   bool ::GetSize(char * archive, char * fileName, FileSize * size)
+   bool ::GetSize(const char * archive, const char * fileName, FileSize * size)
    {
       bool result = false;
       EARHeader header;
@@ -1421,7 +1447,7 @@ class EARFileSystem : FileSystem
       return result;
    }
 
-   bool ::Stats(char * archive, char * fileName, FileStats stats)
+   bool ::Stats(const char * archive, const char * fileName, FileStats stats)
    {
       bool result = false;
       EARHeader header;
@@ -1442,7 +1468,7 @@ class EARFileSystem : FileSystem
       return result;
    }
 
-   void ::FixCase(char * archive, char * name)
+   void ::FixCase(const char * archive, char * name)
    {
    #ifdef __WIN32__
       EARHeader header;
@@ -1458,7 +1484,7 @@ class EARFileSystem : FileSystem
    #endif
    }
 
-   bool ::Find(FileDesc file, char * archive, char * name)
+   bool ::Find(FileDesc file, const char * archive, const char * name)
    {
       bool result = false;
       EARDir d {};
@@ -1485,11 +1511,11 @@ class EARFileSystem : FileSystem
                   d.f.Read(entry, sizeof(EAREntry), 1);
                   d.f.Read(file.name, 1, entry.nameLen);
                   file.name[entry.nameLen] = '\0';
-                  file.stats.attribs = { isDirectory = (entry.type == ENTRY_FOLDER) };
+                  file.stats.attribs = { isDirectory = (entry.type == ENTRY_FOLDER), isFile = (entry.type != ENTRY_FOLDER) };
                   file.stats.accessed = file.stats.modified = (TimeStamp)entry.modified;
                   file.stats.created = (TimeStamp)entry.created;
                   file.stats.size = entry.size;
-                  
+
                   strcpy(file.path, d.path);
                   PathCat(file.path, file.name);
                   d.next = entry.next;
@@ -1519,7 +1545,7 @@ class EARFileSystem : FileSystem
          d.f.Read(entry, sizeof(EAREntry), 1);
          d.f.Read(file.name, 1, entry.nameLen);
          file.name[entry.nameLen] = '\0';
-         file.stats.attribs = FileAttribs { isDirectory = (entry.type == ENTRY_FOLDER) };
+         file.stats.attribs = FileAttribs { isDirectory = (entry.type == ENTRY_FOLDER), isFile = (entry.type != ENTRY_FOLDER) };
          file.stats.accessed = file.stats.modified = (TimeStamp)entry.modified;
          file.stats.created = (TimeStamp)entry.created;
          file.stats.size = entry.size;
@@ -1543,67 +1569,74 @@ class EARFileSystem : FileSystem
    }
 
 #if !defined(ECERE_NOARCHIVE) && !defined(ECERE_VANILLA)
-   Archive ::OpenArchive(char * fileName, ArchiveOpenFlags flags)
+   Archive ::OpenArchive(const char * fileName, ArchiveOpenFlags flags)
    {
       Archive result = null;
       EARArchive archive { writeAccess = flags.writeAccess };
       if(archive)
       {
-         // Check for existing Archive
-         if((archive.f = fileName ? (flags.buffered ? FileOpenBuffered : FileOpen)(fileName, flags.writeAccess ? readWrite : read) : TempFile { openMode = readWrite } ))
+         int try = flags.waitLock ? 10 : 0;
+         for(; try >= 0; try--)
          {
-            EARHeader header;
-            bool opened = false;
-            uint archiveSize = 0;
-            archive.f.Seek(-(int)sizeof(uint), end);
-            archive.f.Read(&archiveSize, sizeof(uint), 1);
-            archive.f.Seek(-(int)archiveSize, end);
-
-            archive.archiveStart = archive.f.Tell();
-            if(archive.f.Read(&header, sizeof(EARHeader), 1) == 1 &&
-               !strncmp(header.recognition, earRecognition, sizeof(earRecognition)))
-               opened = true;
-
-            if(!opened)
+            // Check for existing Archive
+            if((archive.f = fileName ? (flags.buffered ? FileOpenBuffered : FileOpen)(fileName, flags.writeAccess ? readWrite : read) : TempFile { openMode = readWrite } ))
             {
-               archive.f.Seek(0, start);
+               EARHeader header;
+               bool opened = false;
+               uint archiveSize = 0;
+               archive.f.Seek(-(int)sizeof(uint), end);
+               archive.f.Read(&archiveSize, sizeof(uint), 1);
+               archive.f.Seek(-(int)archiveSize, end);
+
                archive.archiveStart = archive.f.Tell();
-               archiveSize = archive.f.GetSize();
                if(archive.f.Read(&header, sizeof(EARHeader), 1) == 1 &&
-                  !strncmp(header.recognition, earRecognition, sizeof(earRecognition)))
+                  !memcmp(header.recognition, earRecognition, sizeof(earRecognition)))
                   opened = true;
-            }
-
-            if(opened)
-            {
-               // At this point we recognized the file as a valid eAR archive
-               archive.rootDir = archive.archiveStart + sizeof(EARHeader);
-               archive.totalSize = header.totalSize;
 
-               archive.f.Seek(archive.rootDir, start);
-               if(flags.buffered)
+               if(!opened)
                {
-                  archive.freeBlocks.Add(FreeBlock { start = archive.rootDir + 2 * sizeof(uint), end = MAXDWORD });
-                  archive.SubtractUsedBlocks();
-               }
-               else
-               {
-                  archive.freeBlocks.Add(FreeBlock { start = archive.archiveStart + (archiveSize - sizeof(uint)), end = MAXDWORD });
+                  archive.f.Seek(0, start);
+                  archive.archiveStart = archive.f.Tell();
+                  archiveSize = archive.f.GetSize();
+                  if(archive.f.Read(&header, sizeof(EARHeader), 1) == 1 &&
+                     !memcmp(header.recognition, earRecognition, sizeof(earRecognition)))
+                     opened = true;
                }
 
-               /*
-               if(!flags.writeAccess)
-               {
-                  delete archive.f;
-                  archive.f = FileOpen(fileName, readWrite);
-               }
-               */
-               if(archive.f)
+               if(opened)
                {
-                  incref archive.f;
-                  result = archive;
+                  // At this point we recognized the file as a valid eAR archive
+                  archive.rootDir = archive.archiveStart + sizeof(EARHeader);
+                  archive.totalSize = header.totalSize;
+
+                  archive.f.Seek(archive.rootDir, start);
+                  if(flags.buffered)
+                  {
+                     archive.freeBlocks.Add(FreeBlock { start = archive.rootDir + 2 * sizeof(uint), end = MAXDWORD });
+                     archive.SubtractUsedBlocks();
+                  }
+                  else
+                  {
+                     archive.freeBlocks.Add(FreeBlock { start = archive.archiveStart + (archiveSize - sizeof(uint)), end = MAXDWORD });
+                  }
+
+                  /*
+                  if(!flags.writeAccess)
+                  {
+                     delete archive.f;
+                     archive.f = FileOpen(fileName, readWrite);
+                  }
+                  */
+                  if(archive.f)
+                  {
+                     incref archive.f;
+                     result = archive;
+                  }
                }
+               break;
             }
+            else if(try > 0)
+               Sleep(0.01);
          }
 
          // This piece of code will create a new archive as a new file or at the footer
@@ -1624,9 +1657,9 @@ class EARFileSystem : FileSystem
                   EAR_RECOGNITION,
                   MDWORD(0, 1)
                };
-                    
+
                archive.f.Seek(0, end);
-         
+
                archive.archiveStart = archive.f.Tell();
                archive.freeBlocks.Add(FreeBlock { start = archive.archiveStart + sizeof(EARHeader), end = MAXDWORD });
 
@@ -1643,7 +1676,7 @@ class EARFileSystem : FileSystem
                result = archive;
             }
          }
-         if(archive.f && flags.writeAccess && flags.exclusive && !archive.f.Lock(flags.exclusive ? exclusive : shared, 0, 0, false))
+         if(archive.f && flags.writeAccess && flags.exclusive && !archive.f.Lock(flags.exclusive ? exclusive : shared, 0, 0, flags.waitLock))
             result = null;
          if(!result)
          {
@@ -1658,7 +1691,7 @@ class EARFileSystem : FileSystem
       return result;
    }
 #endif
-   bool ::QuerySize(char * archive, FileSize * size)
+   bool ::QuerySize(const char * archive, FileSize * size)
    {
       bool result = false;
       EARHeader header;