瀏覽代碼

SMB1: Improved FindInformation implementation and corrected reading of FindInformation entries from buffer

Tal Aloni 7 年之前
父節點
當前提交
6a1c68faf7

+ 3 - 3
SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileBothDirectoryInfo.cs

@@ -18,7 +18,7 @@ namespace SMBLibrary.SMB1
     {
         public const int FixedLength = 94;
 
-        public uint NextEntryOffset;
+        // uint NextEntryOffset;
         public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client
         public DateTime? CreationTime;
         public DateTime? LastAccessTime;
@@ -38,11 +38,11 @@ namespace SMBLibrary.SMB1
         // Will, in some rare but repeatable cases, cause issues with Windows XP SP3 as a client
         // (the client will display an error message that the folder "refers to a location that is unavailable"...)
 
-        public FindFileBothDirectoryInfo() : base(false)
+        public FindFileBothDirectoryInfo() : base()
         {
         }
 
-        public FindFileBothDirectoryInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false)
+        public FindFileBothDirectoryInfo(byte[] buffer, int offset, bool isUnicode) : base()
         {
             NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset);
             FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset);

+ 3 - 3
SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileDirectoryInfo.cs

@@ -18,7 +18,7 @@ namespace SMBLibrary.SMB1
     {
         public const int FixedLength = 64;
 
-        public uint NextEntryOffset;
+        // uint NextEntryOffset;
         public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client
         public DateTime? CreationTime;
         public DateTime? LastAccessTime;
@@ -30,11 +30,11 @@ namespace SMBLibrary.SMB1
         //uint FileNameLength; // In bytes, MUST exclude the null termination.
         public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string.
 
-        public FindFileDirectoryInfo() : base(false)
+        public FindFileDirectoryInfo() : base()
         {
         }
 
-        public FindFileDirectoryInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false)
+        public FindFileDirectoryInfo(byte[] buffer, int offset, bool isUnicode) : base()
         {
             NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset);
             FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset);

+ 3 - 3
SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileFullDirectoryInfo.cs

@@ -18,7 +18,7 @@ namespace SMBLibrary.SMB1
     {
         public const int FixedLength = 68;
 
-        public uint NextEntryOffset;
+        // uint NextEntryOffset;
         public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client
         public DateTime? CreationTime;
         public DateTime? LastAccessTime;
@@ -31,11 +31,11 @@ namespace SMBLibrary.SMB1
         public uint EASize;
         public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string.
 
-        public FindFileFullDirectoryInfo() : base(false)
+        public FindFileFullDirectoryInfo() : base()
         {
         }
 
-        public FindFileFullDirectoryInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false)
+        public FindFileFullDirectoryInfo(byte[] buffer, int offset, bool isUnicode) : base()
         {
             NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset);
             FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset);

+ 3 - 3
SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileIDBothDirectoryInfo.cs

@@ -18,7 +18,7 @@ namespace SMBLibrary.SMB1
     {
         public const int FixedLength = 104;
 
-        public uint NextEntryOffset;
+        // uint NextEntryOffset;
         public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client
         public DateTime? CreationTime;
         public DateTime? LastAccessTime;
@@ -40,11 +40,11 @@ namespace SMBLibrary.SMB1
         // Will, in some rare but repeatable cases, cause issues with Windows XP SP3 as a client
         // (the client will display an error message that the folder "refers to a location that is unavailable"...)
 
-        public FindFileIDBothDirectoryInfo() : base(false)
+        public FindFileIDBothDirectoryInfo() : base()
         {
         }
 
-        public FindFileIDBothDirectoryInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false)
+        public FindFileIDBothDirectoryInfo(byte[] buffer, int offset, bool isUnicode) : base()
         {
             NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset);
             FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset);

+ 3 - 3
SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileIDFullDirectoryInfo.cs

@@ -18,7 +18,7 @@ namespace SMBLibrary.SMB1
     {
         public const int FixedLength = 80;
 
-        public uint NextEntryOffset;
+        // uint NextEntryOffset;
         public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client
         public DateTime? CreationTime;
         public DateTime? LastAccessTime;
@@ -33,11 +33,11 @@ namespace SMBLibrary.SMB1
         public ulong FileID;
         public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string.
 
-        public FindFileIDFullDirectoryInfo() : base(false)
+        public FindFileIDFullDirectoryInfo() : base()
         {
         }
 
-        public FindFileIDFullDirectoryInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false)
+        public FindFileIDFullDirectoryInfo(byte[] buffer, int offset, bool isUnicode) : base()
         {
             NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset);
             FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset);

+ 3 - 3
SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileNamesInfo.cs

@@ -18,16 +18,16 @@ namespace SMBLibrary.SMB1
     {
         public const int FixedLength = 12;
 
-        public uint NextEntryOffset;
+        // uint NextEntryOffset;
         public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client
         //uint FileNameLength; // In bytes, MUST exclude the null termination.
         public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string.
 
-        public FindFileNamesInfo() : base(false)
+        public FindFileNamesInfo() : base()
         {
         }
 
-        public FindFileNamesInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false)
+        public FindFileNamesInfo(byte[] buffer, int offset, bool isUnicode) : base()
         {
             NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset);
             FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset);

+ 11 - 16
SMBLibrary/SMB1FileStore/Structures/FindInformation/FindInformation.cs

@@ -12,42 +12,37 @@ namespace SMBLibrary.SMB1
 {
     public abstract class FindInformation
     {
-        private bool m_returnResumeKeys;
+        public uint NextEntryOffset;
 
-        public FindInformation(bool returnResumeKeys)
+        public FindInformation()
         {
-            m_returnResumeKeys = returnResumeKeys;
         }
 
         public abstract void WriteBytes(byte[] buffer, ref int offset, bool isUnicode);
         
         public abstract int GetLength(bool isUnicode);
 
-        public bool ReturnResumeKeys
-        {
-            get
-            {
-                return m_returnResumeKeys;
-            }
-        }
-
         public abstract FindInformationLevel InformationLevel
         {
             get;
         }
 
-        public static FindInformation ReadEntry(byte[] buffer, ref int offset, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys)
+        public static FindInformation ReadEntry(byte[] buffer, int offset, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys)
         {
             switch (informationLevel)
             {
                 case FindInformationLevel.SMB_FIND_FILE_DIRECTORY_INFO:
-                    return new FindFileDirectoryInfo(buffer, ref offset, isUnicode);
+                    return new FindFileDirectoryInfo(buffer, offset, isUnicode);
                 case FindInformationLevel.SMB_FIND_FILE_FULL_DIRECTORY_INFO:
-                    return new FindFileFullDirectoryInfo(buffer, ref offset, isUnicode);
+                    return new FindFileFullDirectoryInfo(buffer, offset, isUnicode);
                 case FindInformationLevel.SMB_FIND_FILE_NAMES_INFO:
-                    return new FindFileNamesInfo(buffer, ref offset, isUnicode);
+                    return new FindFileNamesInfo(buffer, offset, isUnicode);
                 case FindInformationLevel.SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
-                    return new FindFileBothDirectoryInfo(buffer, ref offset, isUnicode);
+                    return new FindFileBothDirectoryInfo(buffer, offset, isUnicode);
+                case FindInformationLevel.SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO:
+                    return new FindFileIDFullDirectoryInfo(buffer, offset, isUnicode);
+                case FindInformationLevel.SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO:
+                    return new FindFileIDBothDirectoryInfo(buffer, offset, isUnicode);
                 default:
                     throw new UnsupportedInformationLevelException();
             }

+ 7 - 23
SMBLibrary/SMB1FileStore/Structures/FindInformation/FindInformationList.cs

@@ -22,36 +22,20 @@ namespace SMBLibrary.SMB1
             int offset = 0;
             while (offset < buffer.Length)
             {
-                FindInformation entry = FindInformation.ReadEntry(buffer, ref offset, informationLevel, isUnicode, returnResumeKeys);
+                FindInformation entry = FindInformation.ReadEntry(buffer, offset, informationLevel, isUnicode, returnResumeKeys);
                 this.Add(entry);
+                offset += (int)entry.NextEntryOffset;
             }
         }
 
         public byte[] GetBytes(bool isUnicode)
         {
-            for(int index = 0; index < this.Count; index++)
+            for(int index = 0; index < this.Count - 1; index++)
             {
-                if (index < this.Count - 1)
-                {
-                    FindInformation entry = this[index];
-                    int entryLength = entry.GetLength(isUnicode);
-                    if (entry is FindFileBothDirectoryInfo)
-                    {
-                        ((FindFileBothDirectoryInfo)entry).NextEntryOffset = (uint)entryLength;
-                    }
-                    else if (entry is FindFileDirectoryInfo)
-                    {
-                        ((FindFileDirectoryInfo)entry).NextEntryOffset = (uint)entryLength;
-                    }
-                    else if (entry is FindFileFullDirectoryInfo)
-                    {
-                        ((FindFileFullDirectoryInfo)entry).NextEntryOffset = (uint)entryLength;
-                    }
-                    else if (entry is FindFileNamesInfo)
-                    {
-                        ((FindFileNamesInfo)entry).NextEntryOffset = (uint)entryLength;
-                    }
-                }
+                FindInformation entry = this[index];
+                int entryLength = entry.GetLength(isUnicode);
+                entry.NextEntryOffset = (uint)entryLength;
+
             }
             int length = GetLength(isUnicode);
             byte[] buffer = new byte[length];