2008-11-17 18:29:00 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-03-05 09:52:00 -05:00
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
//
|
2008-11-17 18:29:00 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
using System;
|
|
|
|
using System.Text;
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
using Smb.Shared;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Smb.Protocol
|
|
|
|
{
|
|
|
|
[StructLayout(LayoutKind.Explicit, Pack=1, Size=37)]
|
|
|
|
pointerfree struct SmbHeader
|
|
|
|
{
|
|
|
|
[FieldOffset(0)] public byte FrameLength0;
|
|
|
|
[FieldOffset(1)] public byte FrameLength1;
|
|
|
|
[FieldOffset(2)] public byte FrameLength2;
|
|
|
|
[FieldOffset(3)] public byte FrameLength3;
|
|
|
|
[FieldOffset(4)] public byte Signature0;
|
|
|
|
[FieldOffset(5)] public byte Signature1;
|
|
|
|
[FieldOffset(6)] public byte Signature2;
|
|
|
|
[FieldOffset(7)] public byte Signature3;
|
|
|
|
[FieldOffset(8)] public byte Command;
|
|
|
|
[FieldOffset(9)] public byte ErrorClass;
|
|
|
|
[FieldOffset(10)] public byte Error1;
|
|
|
|
[FieldOffset(11)] public byte Error2;
|
|
|
|
[FieldOffset(12)] public byte Error3;
|
|
|
|
[FieldOffset(13)] public byte Flags1;
|
|
|
|
[FieldOffset(14)] public ushort Flags2;
|
|
|
|
[FieldOffset(16)] public ushort PidHigh;
|
|
|
|
[FieldOffset(18)] public uint Extra0;
|
|
|
|
[FieldOffset(22)] public uint Extra1;
|
|
|
|
[FieldOffset(26)] public ushort ExtraReserved;
|
|
|
|
[FieldOffset(28)] public ushort TreeId;
|
|
|
|
[FieldOffset(30)] public ushort ProcessId;
|
|
|
|
[FieldOffset(32)] public ushort UserId;
|
|
|
|
[FieldOffset(34)] public ushort MuxId;
|
|
|
|
[FieldOffset(36)] public byte ParameterCount;
|
|
|
|
|
|
|
|
// I can't believe it, but the length of this structure is 37! THIRTY SEVEN!
|
|
|
|
// Not only is it not aligned to any sane boundary, like 4 or 8 bytes, but it's
|
|
|
|
// a freakin PRIME NUMBER!
|
|
|
|
public const int SizeOf = 37;
|
|
|
|
|
|
|
|
public void SetSignature()
|
|
|
|
{
|
|
|
|
Signature0 = SmbSignature0;
|
|
|
|
Signature1 = SmbSignature1;
|
|
|
|
Signature2 = SmbSignature2;
|
|
|
|
Signature3 = SmbSignature3;
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool IsSignatureValid()
|
|
|
|
{
|
|
|
|
return Signature0 == SmbSignature0
|
|
|
|
&& Signature1 == SmbSignature1
|
|
|
|
&& Signature2 == SmbSignature2
|
|
|
|
&& Signature3 == SmbSignature3;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public const byte SmbSignature0 = 0xff;
|
|
|
|
public const byte SmbSignature1 = (byte)'S';
|
|
|
|
public const byte SmbSignature2 = (byte)'M';
|
|
|
|
public const byte SmbSignature3 = (byte)'B';
|
|
|
|
|
|
|
|
public bool IsError
|
|
|
|
{
|
|
|
|
get {
|
|
|
|
return Error1 != 0 || Error2 != 0 || Error3 != 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public NtStatus GetNtStatus()
|
|
|
|
{
|
|
|
|
if ((((SmbFlag2)Flags2) & SmbFlag2.UsingNtStatus) != 0) {
|
|
|
|
uint code = ((uint)ErrorClass)
|
|
|
|
| (((uint)Error1) << 8)
|
|
|
|
| (((uint)Error2) << 16)
|
|
|
|
| (((uint)Error3) << 24);
|
|
|
|
return (NtStatus)unchecked((int)code);
|
2008-11-17 18:29:00 -05:00
|
|
|
}
|
|
|
|
else {
|
2008-03-05 09:52:00 -05:00
|
|
|
return NtStatus.CodeNotMapped;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public string! GetErrorText()
|
|
|
|
{
|
|
|
|
return SmbProtocol.GetErrorText(this.ErrorClass, this.Error1 | ((ushort)Error2 << 8));
|
|
|
|
}
|
|
|
|
|
|
|
|
public int SmbMessageLength
|
|
|
|
{
|
|
|
|
get ensures result >= 0;
|
|
|
|
{
|
|
|
|
return (((int)this.FrameLength1) << 16)
|
|
|
|
| (((int)this.FrameLength2) << 8)
|
|
|
|
| ((int)this.FrameLength3);
|
|
|
|
}
|
|
|
|
|
|
|
|
set requires value >= 0;
|
|
|
|
{
|
|
|
|
this.FrameLength0 = 0;
|
|
|
|
this.FrameLength1 = (byte)((value >> 16) & 0xff);
|
|
|
|
this.FrameLength2 = (byte)((value >> 8) & 0xff);
|
|
|
|
this.FrameLength3 = (byte)(value & 0xff);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool IsRequest
|
|
|
|
{
|
|
|
|
get { return (this.Flags1 & (byte)SmbFlag1.IsResponse) == 0; }
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool IsResponse
|
|
|
|
{
|
|
|
|
get { return (this.Flags1 & (byte)SmbFlag1.IsResponse) != 0; }
|
|
|
|
}
|
|
|
|
|
|
|
|
public int TotalMessageLength
|
|
|
|
{
|
|
|
|
get { return this.SmbMessageLength + 4; }
|
|
|
|
|
|
|
|
set
|
|
|
|
requires value >= 4;
|
|
|
|
{ this.SmbMessageLength = value - 4; }
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Prepare(SmbCommand command, int parameterCount)
|
|
|
|
requires parameterCount >= 0;
|
|
|
|
requires parameterCount < 256;
|
|
|
|
{
|
|
|
|
this.SetSignature();
|
|
|
|
this.Command = (byte)command;
|
|
|
|
this.ParameterCount = (byte)parameterCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
public const int FramingHeaderLength = 4;
|
|
|
|
}
|
|
|
|
}
|