'Decodes the SMB message in buf.
All fields of the SMB2Message object will be reset to default values before decoding.
On errors, do not assume that the fields will be reinstated back to what they are before
this method is invoked.
References
- [MS-SMB2]: 2.2.1
@param buf: data containing one complete SMB2 message
@type buf: string
@return: a positive integer indicating the number of bytes used in buf to decode this SMB message
@raise ProtocolError: raised when decoding fails'

def decode(self, buf):

    buf_len = len(buf)
    if (buf_len < 64):
        raise ProtocolError('Not    enough    data    to    decode    SMB2    header', buf)
    self.reset()
    (protocol, struct_size, self.credit_charge, self.status, self.command, self.credit_re, self.flags) = struct.unpack(self.HEADER_STRUCT_FORMAT, buf[:self.HEADER_STRUCT_SIZE])
    if (protocol != '\xfeSMB'):
        raise ProtocolError('Invalid    4-byte    SMB2    protocol    field', buf)
    if (struct_size != self.HEADER_SIZE):
        raise ProtocolError('Invalid    SMB2    header    structure    size')
    if self.isAsync:
        if (buf_len < (self.HEADER_STRUCT_SIZE + self.ASYNC_HEADER_STRUCT_SIZE)):
            raise ProtocolError('Not    enough    data    to    decode    SMB2    header', buf)
        (self.next_command_offset, self.mid, self.async_id, self.session_id, self.signature) = struct.unpack(self.ASYNC_HEADER_STRUCT_FORMAT, buf[self.HEADER_STRUCT_SIZE:(self.HEADER_STRUCT_SIZE + self.ASYNC_HEADER_STRUCT_SIZE)])
    else:
        if (buf_len < (self.HEADER_STRUCT_SIZE + self.SYNC_HEADER_STRUCT_SIZE)):
            raise ProtocolError('Not    enough    data    to    decode    SMB2    header', buf)
        (self.next_command_offset, self.mid, self.pid, self.tid, self.session_id, self.signature) = struct.unpack(self.SYNC_HEADER_STRUCT_FORMAT, buf[self.HEADER_STRUCT_SIZE:(self.HEADER_STRUCT_SIZE + self.SYNC_HEADER_STRUCT_SIZE)])
    if (self.next_command_offset > 0):
        self.raw_data = buf[:self.next_command_offset]
        self.data = buf[self.HEADER_SIZE:self.next_command_offset]
    else:
        self.raw_data = buf
        self.data = buf[self.HEADER_SIZE:]
    self._decodeCommand()
    if self.payload:
        self.payload.decode(self)
    return len(self.raw_data)
