SMBLibrary/SMBLibrary/NTFileStore/Adapter/NTFileSystemAdapter.Query.cs

211 lines
9.6 KiB
C#

/* Copyright (C) 2014-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 Utilities;
namespace SMBLibrary
{
public partial class NTFileSystemAdapter
{
public NTStatus GetFileInformation(out FileInformation result, object handle, FileInformationClass informationClass)
{
FileHandle fileHandle = (FileHandle)handle;
string path = fileHandle.Path;
FileSystemEntry entry;
try
{
entry = m_fileSystem.GetEntry(path);
}
catch (Exception ex)
{
NTStatus status = ToNTStatus(ex);
Log(Severity.Debug, "GetFileInformation on '{0}' failed. {1}", path, status);
result = null;
return status;
}
if (entry == null)
{
result = null;
return NTStatus.STATUS_NO_SUCH_FILE;
}
switch (informationClass)
{
case FileInformationClass.FileBasicInformation:
{
FileBasicInformation information = new FileBasicInformation();
information.CreationTime = entry.CreationTime;
information.LastAccessTime = entry.LastAccessTime;
information.LastWriteTime = entry.LastWriteTime;
information.ChangeTime = entry.LastWriteTime;
information.FileAttributes = GetFileAttributes(entry);
result = information;
return NTStatus.STATUS_SUCCESS;
}
case FileInformationClass.FileStandardInformation:
{
FileStandardInformation information = new FileStandardInformation();
information.AllocationSize = (long)GetAllocationSize(entry.Size);
information.EndOfFile = (long)entry.Size;
information.Directory = entry.IsDirectory;
information.DeletePending = fileHandle.DeleteOnClose;
result = information;
return NTStatus.STATUS_SUCCESS;
}
case FileInformationClass.FileInternalInformation:
{
FileInternalInformation information = new FileInternalInformation();
result = information;
return NTStatus.STATUS_SUCCESS;
}
case FileInformationClass.FileEaInformation:
{
FileEaInformation information = new FileEaInformation();
information.EaSize = 0;
result = information;
return NTStatus.STATUS_SUCCESS;
}
case FileInformationClass.FileAccessInformation:
{
result = null;
return NTStatus.STATUS_NOT_IMPLEMENTED;
}
case FileInformationClass.FileNameInformation:
{
FileNameInformation information = new FileNameInformation();
information.FileName = entry.Name;
result = information;
return NTStatus.STATUS_SUCCESS;
}
case FileInformationClass.FilePositionInformation:
{
result = null;
return NTStatus.STATUS_NOT_IMPLEMENTED;
}
case FileInformationClass.FileFullEaInformation:
{
result = null;
return NTStatus.STATUS_NOT_IMPLEMENTED;
}
case FileInformationClass.FileModeInformation:
{
result = null;
return NTStatus.STATUS_NOT_IMPLEMENTED;
}
case FileInformationClass.FileAlignmentInformation:
{
result = null;
return NTStatus.STATUS_NOT_IMPLEMENTED;
}
case FileInformationClass.FileAllInformation:
{
FileAllInformation information = new FileAllInformation();
information.BasicInformation.CreationTime = entry.CreationTime;
information.BasicInformation.LastAccessTime = entry.LastAccessTime;
information.BasicInformation.LastWriteTime = entry.LastWriteTime;
information.BasicInformation.ChangeTime = entry.LastWriteTime;
information.BasicInformation.FileAttributes = GetFileAttributes(entry);
information.StandardInformation.AllocationSize = (long)GetAllocationSize(entry.Size);
information.StandardInformation.EndOfFile = (long)entry.Size;
information.StandardInformation.Directory = entry.IsDirectory;
information.StandardInformation.DeletePending = fileHandle.DeleteOnClose;
information.NameInformation.FileName = entry.Name;
result = information;
return NTStatus.STATUS_SUCCESS;
}
case FileInformationClass.FileAlternateNameInformation:
{
result = null;
return NTStatus.STATUS_NOT_IMPLEMENTED;
}
case FileInformationClass.FileStreamInformation:
{
// This information class is used to enumerate the data streams of a file or a directory.
// A buffer of FileStreamInformation data elements is returned by the server.
FileStreamInformation information = new FileStreamInformation();
information.StreamSize = (long)entry.Size;
information.StreamAllocationSize = (long)GetAllocationSize(entry.Size);
information.StreamName = "::$DATA";
result = information;
return NTStatus.STATUS_SUCCESS;
}
case FileInformationClass.FilePipeInformation:
{
result = null;
return NTStatus.STATUS_NOT_IMPLEMENTED;
}
case FileInformationClass.FilePipeLocalInformation:
{
result = null;
return NTStatus.STATUS_NOT_IMPLEMENTED;
}
case FileInformationClass.FilePipeRemoteInformation:
{
result = null;
return NTStatus.STATUS_NOT_IMPLEMENTED;
}
case FileInformationClass.FileCompressionInformation:
{
result = null;
return NTStatus.STATUS_NOT_IMPLEMENTED;
}
case FileInformationClass.FileNetworkOpenInformation:
{
FileNetworkOpenInformation information = new FileNetworkOpenInformation();
information.CreationTime = entry.CreationTime;
information.LastAccessTime = entry.LastAccessTime;
information.LastWriteTime = entry.LastWriteTime;
information.ChangeTime = entry.LastWriteTime;
information.AllocationSize = (long)GetAllocationSize(entry.Size);
information.EndOfFile = (long)entry.Size;
information.FileAttributes = GetFileAttributes(entry);
result = information;
return NTStatus.STATUS_SUCCESS;
}
case FileInformationClass.FileAttributeTagInformation:
{
result = null;
return NTStatus.STATUS_NOT_IMPLEMENTED;
}
default:
result = null;
return NTStatus.STATUS_INVALID_INFO_CLASS;
}
}
public static FileAttributes GetFileAttributes(FileSystemEntry entry)
{
FileAttributes attributes = 0;
if (entry.IsHidden)
{
attributes |= FileAttributes.Hidden;
}
if (entry.IsReadonly)
{
attributes |= FileAttributes.ReadOnly;
}
if (entry.IsArchived)
{
attributes |= FileAttributes.Archive;
}
if (entry.IsDirectory)
{
attributes |= FileAttributes.Directory;
}
if (attributes == 0)
{
attributes = FileAttributes.Normal;
}
return attributes;
}
}
}