Explorar o código

SMB2: Honor SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB flag

Tal Aloni %!s(int64=8) %!d(string=hai) anos
pai
achega
88204faf9b

+ 8 - 0
SMBLibrary/SMB2/Commands/CloseRequest.cs

@@ -43,6 +43,14 @@ namespace SMBLibrary.SMB2
             FileId.WriteBytes(buffer, offset + 8);
         }
 
+        public bool PostQueryAttributes
+        {
+            get
+            {
+                return ((this.Flags & CloseFlags.PostQueryAttributes) > 0);
+            }
+        }
+
         public override int CommandLength
         {
             get

+ 1 - 1
SMBLibrary/SMB2/Enums/Close/CloseFlags.cs

@@ -5,6 +5,6 @@ namespace SMBLibrary.SMB2
     [Flags]
     public enum CloseFlags : byte
     {
-        PostQueryAttribute = 0x0001, // SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB
+        PostQueryAttributes = 0x0001, // SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB
     }
 }

+ 1 - 0
SMBLibrary/SMBLibrary.csproj

@@ -153,6 +153,7 @@
     <Compile Include="Server\SMB1\TransactionHelper.cs" />
     <Compile Include="Server\SMB1\TransactionSubcommandHelper.cs" />
     <Compile Include="Server\SMB1\TreeConnectHelper.cs" />
+    <Compile Include="Server\SMB2\CloseHelper.cs" />
     <Compile Include="Server\SMB2\CreateHelper.cs" />
     <Compile Include="Server\SMB2\IOCtlHelper.cs" />
     <Compile Include="Server\SMB2\NegotiateHelper.cs" />

+ 53 - 0
SMBLibrary/Server/SMB2/CloseHelper.cs

@@ -0,0 +1,53 @@
+/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
+ * 
+ * You can redistribute this program and/or modify it under the terms of
+ * the GNU Lesser Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ */
+using System;
+using System.Collections.Generic;
+using System.IO;
+using SMBLibrary.SMB2;
+using Utilities;
+
+namespace SMBLibrary.Server.SMB2
+{
+    public class CloseHelper
+    {
+        internal static SMB2Command GetCloseResponse(CloseRequest request, ISMBShare share, SMB2ConnectionState state)
+        {
+            SMB2Session session = state.GetSession(request.Header.SessionID);
+            OpenFileObject openFile = session.GetOpenFileObject(request.FileId.Persistent);
+            if (openFile == null)
+            {
+                return new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED);
+            }
+            string path = openFile.Path;
+            session.RemoveOpenFile(request.FileId.Persistent);
+            CloseResponse response = new CloseResponse();
+            if (request.PostQueryAttributes)
+            {
+                if (share is NamedPipeShare)
+                {
+                    response.FileAttributes = FileAttributes.Temporary;
+                }
+                else // FileSystemShare
+                {
+                    IFileSystem fileSystem = ((FileSystemShare)share).FileSystem;
+                    FileSystemEntry entry = fileSystem.GetEntry(path);
+                    if (entry != null)
+                    {
+                        response.CreationTime = entry.CreationTime;
+                        response.LastAccessTime = entry.LastAccessTime;
+                        response.LastWriteTime = entry.LastWriteTime;
+                        response.ChangeTime = entry.LastWriteTime;
+                        response.AllocationSize = NTFileSystemHelper.GetAllocationSize(entry.Size);
+                        response.EndofFile = entry.Size;
+                        response.FileAttributes = NTFileSystemHelper.GetFileAttributes(entry);
+                    }
+                }
+            }
+            return response;
+        }
+    }
+}

+ 1 - 8
SMBLibrary/Server/SMBServer.SMB2.cs

@@ -155,14 +155,7 @@ namespace SMBLibrary.Server
                     }
                     else if (command is CloseRequest)
                     {
-                        CloseRequest request = (CloseRequest)command;
-                        OpenFileObject openFile = session.GetOpenFileObject(request.FileId.Persistent);
-                        if (openFile == null)
-                        {
-                            return new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED);
-                        }
-                        session.RemoveOpenFile(request.FileId.Persistent);
-                        return new CloseResponse();
+                        return CloseHelper.GetCloseResponse((CloseRequest)command, share, state);
                     }
                     else if (command is IOCtlRequest)
                     {