123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- /* 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.RPC;
- using SMBLibrary.Services;
- using Utilities;
- namespace SMBLibrary
- {
- public class NamedPipeStore : INTFileStore
- {
- private List<RemoteService> m_services;
- public NamedPipeStore(List<RemoteService> services)
- {
- m_services = services;
- }
- public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext)
- {
- fileStatus = FileStatus.FILE_DOES_NOT_EXIST;
- // It is possible to have a named pipe that does not use RPC (e.g. MS-WSP),
- // However this is not currently needed by our implementation.
- RemoteService service = GetService(path);
- if (service != null)
- {
- // All instances of a named pipe share the same pipe name, but each instance has its own buffers and handles,
- // and provides a separate conduit for client/server communication.
- RPCPipeStream stream = new RPCPipeStream(service);
- handle = new FileHandle(path, false, stream, false);
- fileStatus = FileStatus.FILE_OPENED;
- return NTStatus.STATUS_SUCCESS;
- }
- handle = null;
- return NTStatus.STATUS_OBJECT_PATH_NOT_FOUND;
- }
- public NTStatus CloseFile(object handle)
- {
- FileHandle fileHandle = (FileHandle)handle;
- if (fileHandle.Stream != null)
- {
- fileHandle.Stream.Close();
- }
- return NTStatus.STATUS_SUCCESS;
- }
- private RemoteService GetService(string path)
- {
- if (path.StartsWith(@"\"))
- {
- path = path.Substring(1);
- }
- foreach (RemoteService service in m_services)
- {
- if (String.Equals(path, service.PipeName, StringComparison.InvariantCultureIgnoreCase))
- {
- return service;
- }
- }
- return null;
- }
- public NTStatus ReadFile(out byte[] data, object handle, long offset, int maxCount)
- {
- Stream stream = ((FileHandle)handle).Stream;
- data = new byte[maxCount];
- int bytesRead = stream.Read(data, 0, maxCount);
- if (bytesRead < maxCount)
- {
- // EOF, we must trim the response data array
- data = ByteReader.ReadBytes(data, 0, bytesRead);
- }
- return NTStatus.STATUS_SUCCESS;
- }
- public NTStatus WriteFile(out int numberOfBytesWritten, object handle, long offset, byte[] data)
- {
- Stream stream = ((FileHandle)handle).Stream;
- stream.Write(data, 0, data.Length);
- numberOfBytesWritten = data.Length;
- return NTStatus.STATUS_SUCCESS;
- }
- public NTStatus FlushFileBuffers(object handle)
- {
- FileHandle fileHandle = (FileHandle)handle;
- if (fileHandle.Stream != null)
- {
- fileHandle.Stream.Flush();
- }
- return NTStatus.STATUS_SUCCESS;
- }
- public NTStatus DeviceIOControl(object handle, uint ctlCode, byte[] input, out byte[] output, int maxOutputLength)
- {
- output = null;
- if (ctlCode == (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE)
- {
- int numberOfBytesWritten;
- NTStatus writeStatus = WriteFile(out numberOfBytesWritten, handle, 0, input);
- if (writeStatus != NTStatus.STATUS_SUCCESS)
- {
- return writeStatus;
- }
- NTStatus readStatus = ReadFile(out output, handle, 0, maxOutputLength);
- if (readStatus != NTStatus.STATUS_SUCCESS)
- {
- return readStatus;
- }
- return NTStatus.STATUS_SUCCESS;
- }
- return NTStatus.STATUS_NOT_SUPPORTED;
- }
- public NTStatus QueryDirectory(out List<QueryDirectoryFileInformation> result, object directoryHandle, string fileName, FileInformationClass informationClass)
- {
- result = null;
- return NTStatus.STATUS_NOT_SUPPORTED;
- }
- public NTStatus GetFileInformation(out FileInformation result, object handle, FileInformationClass informationClass)
- {
- switch (informationClass)
- {
- case FileInformationClass.FileBasicInformation:
- {
- FileBasicInformation information = new FileBasicInformation();
- information.FileAttributes = FileAttributes.Temporary;
- result = information;
- return NTStatus.STATUS_SUCCESS;
- }
- case FileInformationClass.FileStandardInformation:
- {
- FileStandardInformation information = new FileStandardInformation();
- information.DeletePending = false;
- result = information;
- return NTStatus.STATUS_SUCCESS;
- }
- case FileInformationClass.FileNetworkOpenInformation:
- {
- FileNetworkOpenInformation information = new FileNetworkOpenInformation();
- information.FileAttributes = FileAttributes.Temporary;
- result = information;
- return NTStatus.STATUS_SUCCESS;
- }
- default:
- result = null;
- return NTStatus.STATUS_INVALID_INFO_CLASS;
- }
- }
- public NTStatus SetFileInformation(object handle, FileInformation information)
- {
- return NTStatus.STATUS_NOT_SUPPORTED;
- }
- public NTStatus GetFileSystemInformation(out FileSystemInformation result, FileSystemInformationClass informationClass)
- {
- result = null;
- return NTStatus.STATUS_NOT_SUPPORTED;
- }
- }
- }
|