mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-07-25 02:18:16 +02:00
Merge remote-tracking branch 'TalAloni/master' into feat/LAN-13040
This commit is contained in:
commit
c352e85065
22 changed files with 164 additions and 66 deletions
|
@ -11,6 +11,7 @@ if (isConnected)
|
|||
List<string> shares = client.ListShares(out status);
|
||||
client.Logoff();
|
||||
}
|
||||
client.Disconnect();
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -93,7 +94,7 @@ status = fileStore.Disconnect();
|
|||
Create a file and write to it:
|
||||
==============================
|
||||
```
|
||||
ISMBFileStore fileStore = client.TreeConnect("Shared", out status);
|
||||
ISMBFileStore fileStore = client.TreeConnect("Shared", out status);
|
||||
string filePath = "NewFile.txt";
|
||||
if (fileStore is SMB1FileStore)
|
||||
{
|
||||
|
@ -116,10 +117,52 @@ if (status == NTStatus.STATUS_SUCCESS)
|
|||
status = fileStore.Disconnect();
|
||||
```
|
||||
|
||||
Write a large file:
|
||||
===================
|
||||
```
|
||||
ISMBFileStore fileStore = client.TreeConnect("Shared", out status);
|
||||
if (status != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
throw new Exception("Failed to connect to share");
|
||||
}
|
||||
string localFilePath = @"C:\Image.jpg";
|
||||
string remoteFilePath = "NewFile.jpg";
|
||||
if (fileStore is SMB1FileStore)
|
||||
{
|
||||
remoteFilePath = @"\\" + remoteFilePath;
|
||||
}
|
||||
FileStream localFileStream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read);
|
||||
object fileHandle;
|
||||
FileStatus fileStatus;
|
||||
status = fileStore.CreateFile(out fileHandle, out fileStatus, remoteFilePath, AccessMask.GENERIC_WRITE | AccessMask.SYNCHRONIZE, FileAttributes.Normal, ShareAccess.None, CreateDisposition.FILE_CREATE, CreateOptions.FILE_NON_DIRECTORY_FILE | CreateOptions.FILE_SYNCHRONOUS_IO_ALERT, null);
|
||||
if (status == NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
int writeOffset = 0;
|
||||
while (localFileStream.Position < localFileStream.Length)
|
||||
{
|
||||
byte[] buffer = new byte[(int)client.MaxWriteSize];
|
||||
int bytesRead = localFileStream.Read(buffer, 0, buffer.Length);
|
||||
if (bytesRead < (int)client.MaxWriteSize)
|
||||
{
|
||||
Array.Resize<byte>(ref buffer, bytesRead);
|
||||
}
|
||||
int numberOfBytesWritten;
|
||||
status = fileStore.WriteFile(out numberOfBytesWritten, fileHandle, writeOffset, buffer);
|
||||
if (status != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
throw new Exception("Failed to write to file");
|
||||
}
|
||||
writeOffset += bytesRead;
|
||||
}
|
||||
status = fileStore.CloseFile(fileHandle);
|
||||
}
|
||||
status = fileStore.Disconnect();
|
||||
```
|
||||
|
||||
Delete file:
|
||||
============
|
||||
```
|
||||
ISMBFileStore fileStore = client.TreeConnect("Shared", out status);
|
||||
ISMBFileStore fileStore = client.TreeConnect("Shared", out status);
|
||||
string filePath = "DeleteMe.txt";
|
||||
if (fileStore is SMB1FileStore)
|
||||
{
|
||||
|
|
|
@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.4.6.0")]
|
||||
[assembly: AssemblyFileVersion("1.4.6.0")]
|
||||
[assembly: AssemblyVersion("1.4.8.0")]
|
||||
[assembly: AssemblyFileVersion("1.4.8.0")]
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFrameworks>net20;net40;netstandard2.0</TargetFrameworks>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AssemblyName>SMBLibrary.Adapters</AssemblyName>
|
||||
<Version>1.4.6</Version>
|
||||
<Version>1.4.8</Version>
|
||||
<NoWarn>1573;1591</NoWarn>
|
||||
<RootNamespace>SMBLibrary.Adapters</RootNamespace>
|
||||
<Authors>Tal Aloni</Authors>
|
||||
|
|
|
@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.4.6.0")]
|
||||
[assembly: AssemblyFileVersion("1.4.6.0")]
|
||||
[assembly: AssemblyVersion("1.4.8.0")]
|
||||
[assembly: AssemblyFileVersion("1.4.8.0")]
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFrameworks>net20;net40;netstandard2.0</TargetFrameworks>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AssemblyName>SMBLibrary.Win32</AssemblyName>
|
||||
<Version>1.4.6</Version>
|
||||
<Version>1.4.8</Version>
|
||||
<NoWarn>1573;1591</NoWarn>
|
||||
<RootNamespace>SMBLibrary.Win32</RootNamespace>
|
||||
<Authors>Tal Aloni</Authors>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2014-2020 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
/* Copyright (C) 2014-2021 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,
|
||||
|
@ -15,6 +15,15 @@ namespace SMBLibrary.Client
|
|||
public class ServerServiceHelper
|
||||
{
|
||||
public static List<string> ListShares(INTFileStore namedPipeShare, ShareType? shareType, out NTStatus status)
|
||||
{
|
||||
return ListShares(namedPipeShare, "*", shareType, out status);
|
||||
}
|
||||
|
||||
/// <param name="serverName">
|
||||
/// When a Windows Server host is using Failover Cluster and Cluster Shared Volumes, each of those CSV file shares is associated
|
||||
/// with a specific host name associated with the cluster and is not accessible using the node IP address or node host name.
|
||||
/// </param>
|
||||
public static List<string> ListShares(INTFileStore namedPipeShare, string serverName, ShareType? shareType, out NTStatus status)
|
||||
{
|
||||
object pipeHandle;
|
||||
int maxTransmitFragmentSize;
|
||||
|
@ -29,7 +38,7 @@ namespace SMBLibrary.Client
|
|||
shareEnumRequest.InfoStruct.Level = 1;
|
||||
shareEnumRequest.InfoStruct.Info = new ShareInfo1Container();
|
||||
shareEnumRequest.PreferedMaximumLength = UInt32.MaxValue;
|
||||
shareEnumRequest.ServerName = "*";
|
||||
shareEnumRequest.ServerName = @"\\" + serverName;
|
||||
RequestPDU requestPDU = new RequestPDU();
|
||||
requestPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment;
|
||||
requestPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
/* Copyright (C) 2017-2021 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,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2014-2020 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
/* Copyright (C) 2014-2021 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,
|
||||
|
@ -29,6 +29,7 @@ namespace SMBLibrary.Client
|
|||
|
||||
private static readonly ushort ClientMaxBufferSize = 65535; // Valid range: 512 - 65535
|
||||
private static readonly ushort ClientMaxMpxCount = 1;
|
||||
private static readonly int ResponseTimeoutInMilliseconds = 5000;
|
||||
|
||||
private SMBTransportType m_transport;
|
||||
private bool m_isConnected;
|
||||
|
@ -81,8 +82,7 @@ namespace SMBLibrary.Client
|
|||
if (!m_isConnected)
|
||||
{
|
||||
m_forceExtendedSecurity = forceExtendedSecurity;
|
||||
int port;
|
||||
port = transport == SMBTransportType.NetBiosOverTCP ? NetBiosOverTCPPort : DirectTCPPort;
|
||||
var port = transport == SMBTransportType.NetBiosOverTCP ? NetBiosOverTCPPort : DirectTCPPort;
|
||||
|
||||
if (!await ConnectSocketAsync(serverAddress, port))
|
||||
{
|
||||
|
@ -749,10 +749,9 @@ namespace SMBLibrary.Client
|
|||
|
||||
internal SMB1Message WaitForMessage(CommandName commandName)
|
||||
{
|
||||
const int TimeOut = 5000;
|
||||
Stopwatch stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
while (stopwatch.ElapsedMilliseconds < TimeOut)
|
||||
while (stopwatch.ElapsedMilliseconds < ResponseTimeoutInMilliseconds)
|
||||
{
|
||||
lock (m_incomingQueueLock)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2017-2020 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
/* Copyright (C) 2017-2021 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,
|
||||
|
@ -9,12 +9,9 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SMBLibrary.Authentication.NTLM;
|
||||
using SMBLibrary.NetBios;
|
||||
using SMBLibrary.Services;
|
||||
using SMBLibrary.SMB2;
|
||||
using Utilities;
|
||||
|
||||
|
@ -28,8 +25,10 @@ namespace SMBLibrary.Client
|
|||
public static readonly uint ClientMaxTransactSize = 1048576;
|
||||
public static readonly uint ClientMaxReadSize = 1048576;
|
||||
public static readonly uint ClientMaxWriteSize = 1048576;
|
||||
private static readonly ushort DesiredCredits = 16;
|
||||
private static readonly ushort DesiredCredits = 16;
|
||||
public static readonly int ResponseTimeoutInMilliseconds = 5000;
|
||||
|
||||
private string m_serverName;
|
||||
private SMBTransportType m_transport;
|
||||
private bool m_isConnected;
|
||||
private bool m_isLoggedIn;
|
||||
|
@ -63,11 +62,15 @@ namespace SMBLibrary.Client
|
|||
|
||||
public bool Connect(IPAddress serverAddress, SMBTransportType transport, string serverName = null)
|
||||
{
|
||||
if (m_serverName == null)
|
||||
{
|
||||
m_serverName = serverAddress.ToString();
|
||||
}
|
||||
|
||||
m_transport = transport;
|
||||
if (!m_isConnected)
|
||||
{
|
||||
int port;
|
||||
port = transport == SMBTransportType.NetBiosOverTCP ? NetBiosOverTCPPort : DirectTCPPort;
|
||||
var port = transport == SMBTransportType.NetBiosOverTCP ? NetBiosOverTCPPort : DirectTCPPort;
|
||||
|
||||
if (!ConnectSocket(serverAddress, port))
|
||||
{
|
||||
|
@ -294,7 +297,7 @@ namespace SMBLibrary.Client
|
|||
request.Dialects.Add(SMB2Dialect.SMB300);
|
||||
|
||||
TrySendCommand(request);
|
||||
NegotiateResponse response = WaitForCommand(SMB2CommandName.Negotiate) as NegotiateResponse;
|
||||
NegotiateResponse response = WaitForCommand(request.MessageID) as NegotiateResponse;
|
||||
if (response != null && response.Header.Status == NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
m_dialect = response.DialectRevision;
|
||||
|
@ -327,7 +330,7 @@ namespace SMBLibrary.Client
|
|||
SecurityBuffer = negotiateMessage
|
||||
};
|
||||
TrySendCommand(request);
|
||||
var response = WaitForCommand(SMB2CommandName.SessionSetup);
|
||||
var response = WaitForCommand(request.MessageID);
|
||||
if (response != null
|
||||
&& response.Header.Status == NTStatus.STATUS_MORE_PROCESSING_REQUIRED
|
||||
&& response is SessionSetupResponse ssr)
|
||||
|
@ -359,7 +362,7 @@ namespace SMBLibrary.Client
|
|||
request.SecurityMode = SecurityMode.SigningEnabled;
|
||||
request.SecurityBuffer = negotiateMessage;
|
||||
TrySendCommand(request);
|
||||
SMB2Command response = WaitForCommand(SMB2CommandName.SessionSetup);
|
||||
SMB2Command response = WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
if (response.Header.Status == NTStatus.STATUS_MORE_PROCESSING_REQUIRED && response is SessionSetupResponse)
|
||||
|
@ -375,7 +378,7 @@ namespace SMBLibrary.Client
|
|||
request.SecurityMode = SecurityMode.SigningEnabled;
|
||||
request.SecurityBuffer = authenticateMessage;
|
||||
TrySendCommand(request);
|
||||
response = WaitForCommand(SMB2CommandName.SessionSetup);
|
||||
response = WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
m_isLoggedIn = (response.Header.Status == NTStatus.STATUS_SUCCESS);
|
||||
|
@ -410,7 +413,7 @@ namespace SMBLibrary.Client
|
|||
LogoffRequest request = new LogoffRequest();
|
||||
TrySendCommand(request);
|
||||
|
||||
SMB2Command response = WaitForCommand(SMB2CommandName.Logoff);
|
||||
SMB2Command response = WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
m_isLoggedIn = (response.Header.Status != NTStatus.STATUS_SUCCESS);
|
||||
|
@ -432,7 +435,7 @@ namespace SMBLibrary.Client
|
|||
return null;
|
||||
}
|
||||
|
||||
List<string> shares = ServerServiceHelper.ListShares(namedPipeShare, SMBLibrary.Services.ShareType.DiskDrive, out status);
|
||||
List<string> shares = ServerServiceHelper.ListShares(namedPipeShare, m_serverName, SMBLibrary.Services.ShareType.DiskDrive, out status);
|
||||
namedPipeShare.Disconnect();
|
||||
return shares;
|
||||
}
|
||||
|
@ -444,12 +447,11 @@ namespace SMBLibrary.Client
|
|||
throw new InvalidOperationException("A login session must be successfully established before connecting to a share");
|
||||
}
|
||||
|
||||
IPAddress serverIPAddress = ((IPEndPoint)m_clientSocket.RemoteEndPoint).Address;
|
||||
string sharePath = String.Format(@"\\{0}\{1}", serverIPAddress.ToString(), shareName);
|
||||
string sharePath = String.Format(@"\\{0}\{1}", m_serverName, shareName);
|
||||
TreeConnectRequest request = new TreeConnectRequest();
|
||||
request.Path = sharePath;
|
||||
TrySendCommand(request);
|
||||
SMB2Command response = WaitForCommand(SMB2CommandName.TreeConnect);
|
||||
SMB2Command response = WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
status = response.Header.Status;
|
||||
|
@ -621,12 +623,11 @@ namespace SMBLibrary.Client
|
|||
}
|
||||
}
|
||||
|
||||
internal SMB2Command WaitForCommand(SMB2CommandName commandName)
|
||||
internal SMB2Command WaitForCommand(ulong messageID)
|
||||
{
|
||||
const int TimeOut = 5000;
|
||||
Stopwatch stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
while (stopwatch.ElapsedMilliseconds < TimeOut)
|
||||
while (stopwatch.ElapsedMilliseconds < ResponseTimeoutInMilliseconds)
|
||||
{
|
||||
lock (m_incomingQueueLock)
|
||||
{
|
||||
|
@ -634,9 +635,14 @@ namespace SMBLibrary.Client
|
|||
{
|
||||
SMB2Command command = m_incomingQueue[index];
|
||||
|
||||
if (command.CommandName == commandName)
|
||||
if (command.Header.MessageID == messageID)
|
||||
{
|
||||
m_incomingQueue.RemoveAt(index);
|
||||
if (command.Header.IsAsync && command.Header.Status == NTStatus.STATUS_PENDING)
|
||||
{
|
||||
index--;
|
||||
continue;
|
||||
}
|
||||
return command;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2017-2020 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
/* Copyright (C) 2017-2021 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,
|
||||
|
@ -40,7 +40,7 @@ namespace SMBLibrary.Client
|
|||
request.ImpersonationLevel = ImpersonationLevel.Impersonation;
|
||||
TrySendCommand(request);
|
||||
|
||||
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.Create);
|
||||
SMB2Command response = m_client.WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is CreateResponse)
|
||||
|
@ -60,7 +60,7 @@ namespace SMBLibrary.Client
|
|||
CloseRequest request = new CloseRequest();
|
||||
request.FileId = (FileID)handle;
|
||||
TrySendCommand(request);
|
||||
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.Close);
|
||||
SMB2Command response = m_client.WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
return response.Header.Status;
|
||||
|
@ -79,7 +79,7 @@ namespace SMBLibrary.Client
|
|||
request.ReadLength = (uint)maxCount;
|
||||
|
||||
TrySendCommand(request);
|
||||
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.Read);
|
||||
SMB2Command response = m_client.WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is ReadResponse)
|
||||
|
@ -102,7 +102,7 @@ namespace SMBLibrary.Client
|
|||
request.Data = data;
|
||||
|
||||
TrySendCommand(request);
|
||||
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.Write);
|
||||
SMB2Command response = m_client.WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is WriteResponse)
|
||||
|
@ -117,7 +117,20 @@ namespace SMBLibrary.Client
|
|||
|
||||
public NTStatus FlushFileBuffers(object handle)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
FlushRequest request = new FlushRequest();
|
||||
request.FileId = (FileID) handle;
|
||||
|
||||
TrySendCommand(request);
|
||||
SMB2Command response = m_client.WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is FlushResponse)
|
||||
{
|
||||
return response.Header.Status;
|
||||
}
|
||||
}
|
||||
|
||||
return NTStatus.STATUS_INVALID_SMB;
|
||||
}
|
||||
|
||||
public NTStatus LockFile(object handle, long byteOffset, long length, bool exclusiveLock)
|
||||
|
@ -142,7 +155,7 @@ namespace SMBLibrary.Client
|
|||
request.FileName = fileName;
|
||||
|
||||
TrySendCommand(request);
|
||||
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.QueryDirectory);
|
||||
SMB2Command response = m_client.WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
while (response.Header.Status == NTStatus.STATUS_SUCCESS && response is QueryDirectoryResponse)
|
||||
|
@ -151,7 +164,7 @@ namespace SMBLibrary.Client
|
|||
result.AddRange(page);
|
||||
request.Reopen = false;
|
||||
TrySendCommand(request);
|
||||
response = m_client.WaitForCommand(SMB2CommandName.QueryDirectory);
|
||||
response = m_client.WaitForCommand(request.MessageID);
|
||||
}
|
||||
return response.Header.Status;
|
||||
}
|
||||
|
@ -169,7 +182,7 @@ namespace SMBLibrary.Client
|
|||
request.FileId = (FileID)handle;
|
||||
|
||||
TrySendCommand(request);
|
||||
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.QueryInfo);
|
||||
SMB2Command response = m_client.WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is QueryInfoResponse)
|
||||
|
@ -191,7 +204,7 @@ namespace SMBLibrary.Client
|
|||
request.SetFileInformation(information);
|
||||
|
||||
TrySendCommand(request);
|
||||
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.SetInfo);
|
||||
SMB2Command response = m_client.WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
return response.Header.Status;
|
||||
|
@ -226,7 +239,7 @@ namespace SMBLibrary.Client
|
|||
request.FileId = (FileID)handle;
|
||||
|
||||
TrySendCommand(request);
|
||||
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.QueryInfo);
|
||||
SMB2Command response = m_client.WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is QueryInfoResponse)
|
||||
|
@ -254,7 +267,7 @@ namespace SMBLibrary.Client
|
|||
request.FileId = (FileID)handle;
|
||||
|
||||
TrySendCommand(request);
|
||||
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.QueryInfo);
|
||||
SMB2Command response = m_client.WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is QueryInfoResponse)
|
||||
|
@ -293,7 +306,7 @@ namespace SMBLibrary.Client
|
|||
request.Input = input;
|
||||
request.MaxOutputResponse = (uint)maxOutputLength;
|
||||
TrySendCommand(request);
|
||||
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.IOCtl);
|
||||
SMB2Command response = m_client.WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
if ((response.Header.Status == NTStatus.STATUS_SUCCESS || response.Header.Status == NTStatus.STATUS_BUFFER_OVERFLOW) && response is IOCtlResponse)
|
||||
|
@ -310,7 +323,7 @@ namespace SMBLibrary.Client
|
|||
{
|
||||
TreeDisconnectRequest request = new TreeDisconnectRequest();
|
||||
TrySendCommand(request);
|
||||
SMB2Command response = m_client.WaitForCommand(SMB2CommandName.TreeDisconnect);
|
||||
SMB2Command response = m_client.WaitForCommand(request.MessageID);
|
||||
if (response != null)
|
||||
{
|
||||
return response.Header.Status;
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace SMBLibrary
|
|||
STATUS_LOCK_NOT_GRANTED = 0xC0000055,
|
||||
STATUS_DELETE_PENDING = 0xC0000056,
|
||||
STATUS_PRIVILEGE_NOT_HELD = 0xC0000061,
|
||||
STATUS_WRONG_PASSWORD = 0xC000006A,
|
||||
STATUS_LOGON_FAILURE = 0xC000006D, // Authentication failure.
|
||||
STATUS_ACCOUNT_RESTRICTION = 0xC000006E, // The user has an empty password, which is not allowed
|
||||
STATUS_INVALID_LOGON_HOURS = 0xC000006F,
|
||||
|
@ -64,9 +65,10 @@ namespace SMBLibrary
|
|||
STATUS_FS_DRIVER_REQUIRED = 0xC000019C,
|
||||
STATUS_USER_SESSION_DELETED = 0xC0000203,
|
||||
STATUS_INSUFF_SERVER_RESOURCES = 0xC0000205,
|
||||
STATUS_PASSWORD_MUST_CHANGE = 0xC0000224,
|
||||
STATUS_NOT_FOUND = 0xC0000225,
|
||||
STATUS_ACCOUNT_LOCKED_OUT = 0xC0000234,
|
||||
STATUS_PASSWORD_MUST_CHANGE = 0xC0000244,
|
||||
STATUS_PATH_NOT_COVERED = 0xC0000257,
|
||||
STATUS_NOT_A_REPARSE_POINT = 0xC0000275,
|
||||
|
||||
STATUS_INVALID_SMB = 0x00010002, // SMB1/CIFS: A corrupt or invalid SMB request was received
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/// Adapted from https://referencesource.microsoft.com/#system.web/Security/Cryptography/SP800_108.cs
|
||||
// Adapted from https://referencesource.microsoft.com/#system.web/Security/Cryptography/SP800_108.cs
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using Utilities;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
/* Copyright (C) 2017-2021 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,
|
||||
|
@ -88,7 +88,7 @@ namespace SMBLibrary
|
|||
case FileInformationClass.FileShortNameInformation:
|
||||
throw new NotImplementedException();
|
||||
default:
|
||||
throw new UnsupportedInformationLevelException();
|
||||
throw new UnsupportedInformationLevelException(String.Format("Unsupported information class: {0}", informationClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace SMBLibrary.NetBios
|
|||
return EncodeName(netBiosName, scopeID);
|
||||
}
|
||||
|
||||
/// <param name="name">NetBIOS name</param>
|
||||
/// <param name="netBiosName">NetBIOS name</param>
|
||||
/// <param name="scopeID">dot-separated labels, formatted per DNS naming rules</param>
|
||||
public static byte[] EncodeName(string netBiosName, string scopeID)
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ namespace SMBLibrary.NetBios
|
|||
// into two nibbles and then adding the value of 'A' (0x41).
|
||||
// Thus, the '&' character (0x26) would be encoded as "CG".
|
||||
// NetBIOS names are usually padded with spaces before being encoded.
|
||||
/// <param name="name">NetBIOS name</param>
|
||||
/// <param name="netBiosName">NetBIOS name</param>
|
||||
/// <param name="scopeID">dot-separated labels, formatted per DNS naming rules</param>
|
||||
public static string FirstLevelEncoding(string netBiosName, string scopeID)
|
||||
{
|
||||
|
|
|
@ -31,6 +31,6 @@ using System.Runtime.InteropServices;
|
|||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.4.6.0")]
|
||||
[assembly: AssemblyFileVersion("1.4.6.0")]
|
||||
[assembly: AssemblyVersion("1.4.8.0")]
|
||||
[assembly: AssemblyFileVersion("1.4.8.0")]
|
||||
[assembly: InternalsVisibleTo("SMBLibrary.Tests")]
|
|
@ -459,3 +459,15 @@ Revision History:
|
|||
NTLM: Bugfix: IndependentNTLMAuthenticationProvider login failed to to modification of message byte arrays.
|
||||
|
||||
1.4.6 - SMB2Client: Fixed InvalidCastException on failed login to SMB 3.0 server.
|
||||
|
||||
1.4.7 - SMBServer: Added private Start overload allowing to specify the listening port.
|
||||
Client: Added private Connect overload allowing to specify the server port.
|
||||
SMB2Client: Correctly handle async responses.
|
||||
SMB2Client: WaitForCommand: Compare MessageID instead of CommandName.
|
||||
Client: SMB2FileStore: Implement Flush.
|
||||
Client: Added support for accessing Cluster Shared Volumes file shares.
|
||||
SMB2Command: Add MessageID property.
|
||||
NTStatus: Added STATUS_WRONG_PASSWORD.
|
||||
NTStatus: Correct STATUS_PASSWORD_MUST_CHANGE value.
|
||||
|
||||
1.4.8 - SMBServer - Start method bugfix.
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace SMBLibrary.SMB1
|
|||
{
|
||||
/// <summary>
|
||||
/// TRANS2_QUERY_FILE_INFORMATION Response
|
||||
/// </summary
|
||||
/// </summary>
|
||||
public class Transaction2QueryFileInformationResponse : Transaction2Subcommand
|
||||
{
|
||||
public const int ParametersLength = 2;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2017-2020 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
/* Copyright (C) 2017-2021 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,
|
||||
|
@ -49,6 +49,14 @@ namespace SMBLibrary.SMB2
|
|||
}
|
||||
}
|
||||
|
||||
public ulong MessageID
|
||||
{
|
||||
get
|
||||
{
|
||||
return Header.MessageID;
|
||||
}
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get
|
||||
|
@ -127,7 +135,7 @@ namespace SMBLibrary.SMB2
|
|||
return GetCommandChainBytes(commands, null, SMB2Dialect.SMB2xx);
|
||||
}
|
||||
|
||||
/// <param name="sessionKey">
|
||||
/// <param name="signingKey">
|
||||
/// Message will be signed using this key if (not null and) SMB2_FLAGS_SIGNED is set.
|
||||
/// </param>
|
||||
/// <param name="dialect">
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AssemblyName>SMBLibrary</AssemblyName>
|
||||
<Version>1.6.0</Version>
|
||||
<Version>1.4.8</Version>
|
||||
<NoWarn>1573;1591</NoWarn>
|
||||
<RootNamespace>SMBLibrary</RootNamespace>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2014-2020 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
|
||||
/* Copyright (C) 2014-2021 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,
|
||||
|
@ -77,6 +77,12 @@ namespace SMBLibrary.Server
|
|||
/// </param>
|
||||
/// <exception cref="System.Net.Sockets.SocketException"></exception>
|
||||
public void Start(IPAddress serverAddress, SMBTransportType transport, bool enableSMB1, bool enableSMB2, bool enableSMB3, TimeSpan? connectionInactivityTimeout)
|
||||
{
|
||||
int port = (transport == SMBTransportType.DirectTCPTransport ? DirectTCPPort : NetBiosOverTCPPort);
|
||||
Start(serverAddress, transport, port, enableSMB1, enableSMB2, enableSMB3, connectionInactivityTimeout);
|
||||
}
|
||||
|
||||
private void Start(IPAddress serverAddress, SMBTransportType transport, int port, bool enableSMB1, bool enableSMB2, bool enableSMB3, TimeSpan? connectionInactivityTimeout)
|
||||
{
|
||||
if (!m_listening)
|
||||
{
|
||||
|
@ -95,7 +101,6 @@ namespace SMBLibrary.Server
|
|||
m_serverStartTime = DateTime.Now;
|
||||
|
||||
m_listenerSocket = new Socket(m_serverAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||
int port = (m_transport == SMBTransportType.DirectTCPTransport ? DirectTCPPort : NetBiosOverTCPPort);
|
||||
m_listenerSocket.Bind(new IPEndPoint(m_serverAddress, port));
|
||||
m_listenerSocket.Listen((int)SocketOptionName.MaxConnections);
|
||||
m_listenerSocket.BeginAccept(ConnectRequestCallback, m_listenerSocket);
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace SMBLibrary.Server
|
|||
return result;
|
||||
}
|
||||
|
||||
/// <param name="relativePath">e.g. \Shared</param>
|
||||
/// <param name="shareName">e.g. \Shared</param>
|
||||
public FileSystemShare GetShareFromName(string shareName)
|
||||
{
|
||||
int index = IndexOf(shareName, StringComparison.OrdinalIgnoreCase);
|
||||
|
|
|
@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
|||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("1.4.6.0")]
|
||||
[assembly: AssemblyFileVersion("1.4.6.0")]
|
||||
[assembly: AssemblyVersion("1.4.8.0")]
|
||||
[assembly: AssemblyFileVersion("1.4.8.0")]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue