'Decodes the SMB message in buf.
All fields of the SMBMessage 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.
@param buf: data containing one complete SMB 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 < self.HEADER_STRUCT_SIZE):
        raise ProtocolError('Not    enough    data    to    decode    SMB    header', buf)
    self.reset()
    (protocol, self.command, status, self.flags, self.flags2, pid_high, self.security, self.tid, pid_low, self.uid, self.mid, params_count) = struct.unpack(self.HEADER_STRUCT_FORMAT, buf[:self.HEADER_STRUCT_SIZE])
    if (protocol == '\xfeSMB'):
        raise SMB2ProtocolHeaderError()
    if (protocol != '\xffSMB'):
        raise ProtocolError('Invalid    4-byte    protocol    field', buf)
    self.pid = ((pid_high << 16) | pid_low)
    self.status.internal_value = status
    self.status.is_ntstatus = bool((self.flags2 & SMB_FLAGS2_NT_STATUS))
    offset = self.HEADER_STRUCT_SIZE
    if (buf_len < ((params_count * 2) + 2)):
        raise ProtocolError('Not    enough    data.    Parameters    list    decoding    failed', buf)
    datalen_offset = (offset + (params_count * 2))
    body_len = struct.unpack('<H', buf[datalen_offset:(datalen_offset + 2)])[0]
    if ((body_len > 0) and (buf_len < ((datalen_offset + 2) + body_len))):
        raise ProtocolError('Not    enough    data.    Body    decoding    failed', buf)
    self.parameters_data = buf[offset:datalen_offset]
    if (body_len > 0):
        self.data = buf[(datalen_offset + 2):((datalen_offset + 2) + body_len)]
    self.raw_data = buf
    self._decodePayload()
    return (((self.HEADER_STRUCT_SIZE + (params_count * 2)) + 2) + body_len)
