[ros-diffs] [cfinck] 32165: - Cast the OutputBuffer to a byte (UCHAR) array, not a ULONG array, so adding a byte offset to its address works as expected. This fixes the extraction of any file, which is not the first file in the cabinet. - I don't see a reason for reading the file name in 32 byte chunks in ReadString() instead of reading it completely in one call. As the previous algorithm was buggy for files longer than 32 characters, I read the file name string completely now. Cabman is now able to extract the "reactos.cab" it created itself without any problems :-) - Simplify CreateSimpleCabinet() a bit

cfinck at svn.reactos.org cfinck at svn.reactos.org
Wed Feb 6 19:30:16 CET 2008


Author: cfinck
Date: Wed Feb  6 21:30:15 2008
New Revision: 32165

URL: http://svn.reactos.org/svn/reactos?rev=32165&view=rev
Log:
- Cast the OutputBuffer to a byte (UCHAR) array, not a ULONG array, so adding a byte offset to its address works as expected.
  This fixes the extraction of any file, which is not the first file in the cabinet.
- I don't see a reason for reading the file name in 32 byte chunks in ReadString() instead of reading it completely in one call.
  As the previous algorithm was buggy for files longer than 32 characters, I read the file name string completely now.
  Cabman is now able to extract the "reactos.cab" it created itself without any problems :-)
- Simplify CreateSimpleCabinet() a bit

Modified:
    trunk/reactos/tools/cabman/cabinet.cxx
    trunk/reactos/tools/cabman/cabinet.h

Modified: trunk/reactos/tools/cabman/cabinet.cxx
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/cabman/cabinet.cxx?rev=32165&r1=32164&r2=32165&view=diff
==============================================================================
--- trunk/reactos/tools/cabman/cabinet.cxx (original)
+++ trunk/reactos/tools/cabman/cabinet.cxx Wed Feb  6 21:30:15 2008
@@ -1021,8 +1021,8 @@
     ULONG BytesToWrite;
     ULONG TotalBytesRead;
     ULONG CurrentOffset;
-    unsigned char* Buffer;
-    unsigned char* CurrentBuffer;
+    PUCHAR Buffer;
+    PUCHAR CurrentBuffer;
     FILEHANDLE DestFile;
     PCFFILE_NODE File;
     CFDATA CFData;
@@ -1031,8 +1031,8 @@
 #if defined(WIN32)
     FILETIME FileTime;
 #endif
-    char DestName[MAX_PATH];
-    char TempName[MAX_PATH];
+    CHAR DestName[MAX_PATH];
+    CHAR TempName[MAX_PATH];
 
     Status = LocateFile(FileName, &File);
     if (Status != CAB_STATUS_SUCCESS)
@@ -1136,7 +1136,7 @@
 #endif
     SetAttributesOnFile(DestName, File->File.Attributes);
 
-    Buffer = (unsigned char*)AllocateMemory(CAB_BLOCKSIZE + 12); // This should be enough
+    Buffer = (PUCHAR)AllocateMemory(CAB_BLOCKSIZE + 12); // This should be enough
     if (!Buffer)
     {
         CloseFile(DestFile);
@@ -1388,14 +1388,14 @@
                 (UINT)Size));
 
 #if defined(WIN32)
-            if (!WriteFile(DestFile, (void*)((unsigned long *)OutputBuffer + BytesSkipped),
+            if (!WriteFile(DestFile, (void*)((PUCHAR)OutputBuffer + BytesSkipped),
                 BytesToWrite, (LPDWORD)&BytesWritten, NULL) ||
                 (BytesToWrite != BytesWritten))
             {
                         DPRINT(MIN_TRACE, ("Status 0x%X.\n", (UINT)GetLastError()));
 #else
             BytesWritten = BytesToWrite;
-            if (fwrite((void*)((unsigned long *)OutputBuffer + BytesSkipped),
+            if (fwrite((void*)((PUCHAR)OutputBuffer + BytesSkipped),
                 BytesToWrite, 1, DestFile) < 1)
             {
 #endif
@@ -2101,12 +2101,7 @@
     {
         // Store the file path with a trailing slash in szFilePath
         ConvertPath(Criteria->Search, false);
-
-#if defined(WIN32)
-        pszFile = strrchr(Criteria->Search, '\\');
-#else
-        pszFile = strrchr(Criteria->Search, '/');
-#endif
+        pszFile = strrchr(Criteria->Search, DIR_SEPARATOR_CHAR);
 
         if(pszFile)
         {
@@ -2387,7 +2382,7 @@
 
 
 ULONG CCabinet::LocateFile(char* FileName,
-                              PCFFILE_NODE *File)
+                           PCFFILE_NODE *File)
 /*
  * FUNCTION: Locates a file in the cabinet
  * ARGUMENTS:
@@ -2431,7 +2426,7 @@
 }
 
 
-ULONG CCabinet::ReadString(char* String, ULONG MaxLength)
+ULONG CCabinet::ReadString(char* String, LONG MaxLength)
 /*
  * FUNCTION: Reads a NULL-terminated string from the cabinet
  * ARGUMENTS:
@@ -2442,48 +2437,43 @@
  */
 {
     ULONG BytesRead;
-    ULONG Offset;
     ULONG Status;
-    ULONG Size;
+    LONG Size;
     bool Found;
 
-    Offset = 0;
     Found  = false;
-    do
-    {
-        Size = ((Offset + 32) <= MaxLength)? 32 : MaxLength - Offset;
-
-        if (Size == 0)
-        {
-            DPRINT(MIN_TRACE, ("Too long a filename.\n"));
-            return CAB_STATUS_INVALID_CAB;
-        }
-
-        Status = ReadBlock(&String[Offset], Size, &BytesRead);
-        if ((Status != CAB_STATUS_SUCCESS) || (BytesRead != Size))
-        {
-            DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
-            return CAB_STATUS_INVALID_CAB;
-        }
-
-        for (Size = Offset; Size < Offset + BytesRead; Size++)
-        {
-            if (String[Size] == '\0')
-            {
-                Found = true;
-                break;
-            }
-        }
-
-        Offset += BytesRead;
-
-    } while (!Found);
-
-    /* Back up some bytes */
-    Size = (BytesRead - Size) - 1;
+
+    Status = ReadBlock(String, MaxLength, &BytesRead);
+    if (Status != CAB_STATUS_SUCCESS)
+    {
+        DPRINT(MIN_TRACE, ("Cannot read from file (%u).\n", (UINT)Status));
+        return CAB_STATUS_INVALID_CAB;
+    }
+
+    // Find the terminating NULL character
+    for (Size = 0; Size < MaxLength; Size++)
+    {
+        if (String[Size] == '\0')
+        {
+            Found = true;
+            break;
+        }
+    }
+
+    if (!Found)
+    {
+        DPRINT(MIN_TRACE, ("Filename in the cabinet file is too long.\n"));
+        return CAB_STATUS_INVALID_CAB;
+    }
+
+    // Compute the offset of the next CFFILE.
+    // We have to subtract from the current offset here, because we read MaxLength characters above and most-probably the file name isn't MaxLength characters long.
+    // + 1 to skip the terminating NULL character as well.
+    Size = -(MaxLength - Size) + 1;
+
 #if defined(WIN32)
     if( SetFilePointer(FileHandle,
-                       -(LONG)Size,
+                       (LONG)Size,
                        NULL,
                        FILE_CURRENT) == INVALID_SET_FILE_POINTER )
     {
@@ -2491,7 +2481,7 @@
         return CAB_STATUS_INVALID_CAB;
     }
 #else
-    if (fseek(FileHandle, (off_t)(-(LONG)Size), SEEK_CUR) != 0)
+    if (fseek(FileHandle, (off_t)Size, SEEK_CUR) != 0)
     {
         DPRINT(MIN_TRACE, ("fseek() failed.\n"));
         return CAB_STATUS_INVALID_CAB;

Modified: trunk/reactos/tools/cabman/cabinet.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/cabman/cabinet.h?rev=32165&r1=32164&r2=32165&view=diff
==============================================================================
--- trunk/reactos/tools/cabman/cabinet.h (original)
+++ trunk/reactos/tools/cabman/cabinet.h Wed Feb  6 21:30:15 2008
@@ -413,7 +413,7 @@
     PCFFOLDER_NODE LocateFolderNode(ULONG Index);
     ULONG GetAbsoluteOffset(PCFFILE_NODE File);
     ULONG LocateFile(char* FileName, PCFFILE_NODE *File);
-    ULONG ReadString(char* String, ULONG MaxLength);
+    ULONG ReadString(char* String, LONG MaxLength);
     ULONG ReadFileTable();
     ULONG ReadDataBlocks(PCFFOLDER_NODE FolderNode);
     PCFFOLDER_NODE NewFolderNode();




More information about the Ros-diffs mailing list