module cifs

#define BOOL uint32
#define UCHAR uint8
#define USHORT uint16
#define LONG uint32
#define ULONG uint32
#define DWORD uint32
#define SMB_TIME uint16
#define SMB_DATE uint16

typedef struct {
	ULONG low;
	LONG high;
} TIME;

typedef struct {
	ULONG low;
	ULONG high;
} hyper;

typedef struct {
	uint8 cmd;
	uint8 reserved;
	uint16 offset;
} ANDX_INFO;


typedef struct {
	uint8 tag2;
	string protocol;
} BUF2;

typedef struct {
	uint16 bcount;
	BUF2 protocol[*];
} Q_NEGPROT_0;

typedef struct {
	uint8 wcount;
	union ctr[wcount] {
		case 0 Q_NEGPROT_0 q0;
	}
} Q_NEGPROT;

typedef struct {
	USHORT  DialectIndex;         /* Index of selected dialect */
	USHORT  SecurityMode;         /* Security mode: */
				      /* bit 0: 0 = share, 1 = user */
				      /* bit 1: 1 = use challenge/response */
				      /* authentication */
	USHORT  MaxBufferSize;        /* Max transmit buffer size (>= 1024) */
	USHORT  MaxMpxCount;          /* Max pending multiplexed requests */
	USHORT  MaxNumberVcs;         /* Max VCs between client and server */
	USHORT  RawMode;              /* Raw modes supported: */
				      /*  bit 0: 1 = Read Raw supported */
				      /*  bit 1: 1 = Write Raw supported */
	ULONG SessionKey;             /* Unique token identifying this session */
	SMB_TIME ServerTime;          /* Current time at server */
	SMB_DATE ServerDate;          /* Current date at server */
	USHORT ServerTimeZone;        /* Current time zone at server */
	USHORT  ChallengeLength;      /* Length of Challenge; MBZ if not LM2.1
				      /* dialect or later */
	USHORT  Reserved;             /* MBZ */
	USHORT  ByteCount;             /* Count of data bytes */
	UCHAR Challenge[ChallengeLength];            /* The challenge */
	string PrimaryDomain;       /* The server's primary domain */

	uint16 bcount;
	uint8 chal[8];
	string domain;
} R_NEGPROT_12;

typedef struct {
	USHORT DialectIndex;  /*Index of selected dialect */
	UCHAR SecurityMode;   /*Security mode: */
			      /*  bit 0: 0 = share, 1 = user */
			      /*  bit 1: 1 = use challenge/response */
			      /*  authentication */
			      /*  bit 2: 1 = Security Signatures (SMB integrity */
			      /*  check) enabled */
			      /*  bit 3: 1 = Security Signatures (SMB integrity */
			      /*  check) required */
	USHORT MaxMpxCount;   /*Max pending outstanding requests */
	USHORT MaxNumberVcs;  /*Max VCs between client and server */
	ULONG MaxBufferSize;  /*Max transmit buffer size */
	ULONG MaxRawSize;     /*Maximum raw buffer size */
	ULONG SessionKey;     /*Unique token identifying this session */
	ULONG Capabilities;   /*Server capabilities */
	ULONG SystemTimeLow;  /*System (UTC) time of the server (low). */
	ULONG SystemTimeHigh; /*System (UTC) time of the server (high). */
	USHORT ServerTimeZone;/*Time zone of server (minutes from UTC) */
	UCHAR SecurityBlobLength;/*Length of SecurityBlob */

	USHORT bcount;     /*Count of data bytes */
	/*UCHAR GUID[16];       A globally unique identifier assigned to the */
			      /*  server; present only when */
			      /*  CAP_EXTENDED_SECURITY is on in the */
			      /*  Capabilities field. */
	UCHAR SecurityBlob[SecurityBlobLength];  /*Opaque Security Blob associated with the */
			      /*  security package if CAP_EXTENDED_SECURITY is */
			      /*  on in the Capabilities field; else challenge */
			      /*  for CIFS challenge/response authentication. */
	string OemDomainName[+]; /*The name of the domain (in OEM chars); not */
	                      /*  present  if CAP_EXTENDED_SECURITY is on in the */
			      /*  Capabilities field */
} R_NEGPROT_17;


typedef struct {
	uint8 wcount;
	union ctr[wcount] {
		case 17 R_NEGPROT_17 r17;
	}
} R_NEGPROT;

typedef struct {
	uint8 wcount;
	uint16 vwv[wcount];
	uint16 bcount;
	uint8 none[bcount];
} Q_TDIS;

typedef struct {
	uint8 wcount;
	uint16 vwv[wcount];
	uint16 bcount;
	uint8 none[bcount];
} R_TDIS;

typedef struct {
	ANDX_INFO andx;
	uint16 bcount;
	uint8 none[bcount];
} R_ULOGOFF_ANDX_2;

typedef struct {
	uint8 wcount;
	union ctr[wcount] {
		case 2 R_ULOGOFF_ANDX_2 q2;
	}
} R_ULOGOFF_ANDX;

typedef struct {
	ANDX_INFO andx;
	uint16 bcount;
	uint8 none[bcount];
} Q_ULOGOFF_ANDX_2;

typedef struct {
	uint8 wcount;
	union ctr[wcount] {
		case 2 Q_ULOGOFF_ANDX_2 q2;
	}
} Q_ULOGOFF_ANDX;

typedef struct {
	ANDX_INFO andx;
	uint16 bufsize;
	uint16 max_mpx;
	uint16 vc;
	ULONG sess_key;
	uint16 pwlen;
	ULONG reserved;

	uint16 bcount;
	uint8 password[pwlen];
	string domain;
	string os;
	string server;

} Q_SESSION_SETUP_ANDX_10;

typedef struct {
	ANDX_INFO andx;
	uint16 bufsize;
	uint16 max_mpx;
	uint16 vc;
	ULONG sess_key;
	uint16 pwlen;
	uint16 upwlen;
	ULONG capabilities;
	ULONG reserved;

	uint16 bcount;
	uint8 password[pwlen];
	uint8 upassword[upwlen];
	string user;
	string domain;
	string os;
	string server;

} Q_SESSION_SETUP_ANDX_13;

typedef struct _Q_SESSION_SETUP_ANDX {
	uint8 wcount;
	union ctr[wcount] {
		case 10 Q_SESSION_SETUP_ANDX_10 q10;
		case 13 Q_SESSION_SETUP_ANDX_13 q13;
	}
} Q_SESSION_SETUP_ANDX;

typedef struct {
	ANDX_INFO andx;
	uint16 vwv2;
	uint16 passlen;
	uint16 bcount;
	uint8 password[passlen];
	string path;
	string device;
} Q_TCON_ANDX_4;

typedef struct _Q_TCON_ANDX {
	uint8 wcount;
	union ctr[wcount] {
		case 4 Q_TCON_ANDX_4 q4;
	}
} Q_TCON_ANDX;

typedef struct {
	ANDX_INFO andx;
	uint16 vwv2;
	uint16 bcount;
	string share;
} R_TCON_ANDX_3;

typedef struct _R_TCON_ANDX {
	uint8 wcount;
	union ctr[wcount] {
		case 3 R_TCON_ANDX_3 q3;
	}
} R_TCON_ANDX;

typedef struct {
	ANDX_INFO andx;
	uint16 action;

	uint16 count;
	string os;
	string server;
	string domain;
} R_SESSION_SETUP_ANDX_10;

typedef struct _R_SESSION_SETUP_ANDX {
	uint8 wcount;
	union ctr[wcount] {
		case 3 R_SESSION_SETUP_ANDX_10 r3;
	}
} R_SESSION_SETUP_ANDX;


typedef struct _R_CLOSE {
	uint8 wcount;
	uint16 count;
	uint8 none[count];

} R_CLOSE;

typedef struct _Q_CLOSE {
	uint8 wcount;
	uint16 fnum;
	uint32 vwv1;

	uint16 count;
	uint8 none[count];

} Q_CLOSE;

typedef struct {
	uint16 dsize;
	uint16 bsizehi;
	uint16 bsizelo;
	uint16 avail;
	uint16 vwv4;

	uint16 bcount;
	uint8 none[bcount];

} R_DSKATTR_5;

typedef struct {
	uint8 wcount;
	union ctr[wcount] {
		case 5 R_DSKATTR_5 r5;
	}
} R_DSKATTR;

typedef struct {
	uint16 count;
	uint8 none[count];

} Q_DSKATTR_0;

typedef struct _Q_DSKATTR {
	uint8 wcount;
	union ctr[wcount] {
		case 0 Q_DSKATTR_0 q1;
	}

} Q_DSKATTR;

typedef struct {
	ANDX_INFO andx;

	uint16 bcount;
	uint8 none[bcount];

} R_LOCKING_2;

typedef struct {
	uint8 wcount;
	union ctr[wcount] {
		case 2 R_LOCKING_2 r2;
	}
} R_LOCKING_ANDX;

/* XXXX must do a switch on bit 0x10 to do large locks XXXX */
/*      LockType Flag Name            Value Description */

#define LOCKING_ANDX_SHARED_LOCK      0x01  /* Read-only lock */
#define LOCKING_ANDX_OPLOCK_RELEASE   0x02  /* Oplock break notification */
#define LOCKING_ANDX_CHANGE_LOCKTYPE  0x04  /* Change lock type */
#define LOCKING_ANDX_CANCEL_LOCK      0x08  /* Cancel outstanding request */
#define LOCKING_ANDX_LARGE_FILES      0x10  /* Large file locking format */

typedef struct {
	USHORT Pid;      /* PID of process "owning" lock */
	ULONG Offset;    /* Offset to bytes to [un]lock */
	ULONG Length;    /* Number of bytes to [un]lock */
} LOCKING_ANDX_RANGE_SHORT;

typedef struct {
	USHORT Pid;       /* PID of process "owning" lock */
	USHORT Pad;       /* Pad to DWORD align (mbz) */
	ULONG OffsetHigh; /* Offset to bytes to [un]lock (high) */
	ULONG OffsetLow;  /* Offset to bytes to [un]lock (low) */
	ULONG LengthHigh; /* Number of bytes to [un]lock (high) */
	ULONG LengthLow;  /* Number of bytes to [un]lock (low) */

} LOCKING_ANDX_RANGE_LARGE;

/* typedef struct { */
	/* union ctr[LockType&0x10] { */
		/* case 0    LOCKING_ANDX_RANGE_SHORT ls; */
		/* case 0x10 LOCKING_ANDX_RANGE_LARGE ll; */
	/* } */
/* } LOCKING_ANDX_RANGE; */

typedef struct {
	ANDX_INFO andx;

	USHORT Fid;             /* File handle */
	UCHAR LockType;         /* See LockType table below */
	UCHAR OplockLevel;      /* The new oplock level */
	ULONG Timeout;          /* Milliseconds to wait for unlock */
	USHORT NumberOfUnlocks; /* Num. unlock range structs following */
	USHORT NumberOfLocks;   /* Num. lock range structs following */

	USHORT ByteCount;       /* Count of data bytes */
	LOCKING_ANDX_RANGE_SHORT Unlocks[NumberOfUnlocks]; /* Unlock ranges */
	LOCKING_ANDX_RANGE_SHORT Locks[NumberOfLocks];     /* Lock ranges */

} Q_LOCKING_8;

typedef struct _Q_LOCKING {
	uint8 wcount;
	union ctr[wcount] {
		case 8 Q_LOCKING_8 q8;
	}

} Q_LOCKING_ANDX;


typedef struct {
	uint16 bcount;
	uint8 protocols[bcount];

} R_UNLINK_0;

typedef struct {
	uint8 wcount;
	union ctr[wcount] {
		case 0 R_UNLINK_0 r0;
	}
} R_UNLINK;

typedef struct {
	uint16 dirtype;

	uint16 count;
	uint8 fname[count];

} Q_UNLINK_1;

typedef struct _Q_UNLINK {
	uint8 wcount;
	union ctr[wcount] {
		case 1 Q_UNLINK_1 q1;
	}

} Q_UNLINK;

typedef struct _R_OPEN_ANDX{
	uint8 wcount;
	ANDX_INFO andx;
	uint16 fnum;
	uint16 fmode;
	uint32 mtime;
	uint32 size;
	uint16 rmode;
	uint16 vwv9;
	uint16 vwv10;
	uint16 smb_action;
	uint16 vwv12;
	uint16 vwv13;
	uint16 vwv14;

	uint16 count;
	uint8 none[count];

} R_OPEN_ANDX;

typedef struct _Q_OPEN_ANDX{
	uint8 wcount;
	ANDX_INFO andx;
	uint16 fnum;
	uint16 fmode;
	uint32 mtime;
	uint32 size;
	uint16 rmode;
	uint16 vwv9;
	uint16 vwv10;
	uint16 smb_action;
	uint16 vwv12;
	uint16 vwv13;
	uint16 vwv14;

	uint16 count;
	uint8 fname[count];

} Q_OPEN_ANDX;

typedef struct _R_READ_ANDX {
	uint8 wcount;
	ANDX_INFO andx;
	uint16 vwv2;
	uint16 vwv3;
	uint16 vwv4;
	uint16 nread;
	uint16 offset;
	uint16 vwv7;
	uint16 vwv8;
	uint16 vwv9;
	uint16 vwv10;
	uint16 vwv11;

	uint16 count;
	uint8 data[count];

} R_READ_ANDX;

typedef struct _Q_READ_ANDX_10 {
	ANDX_INFO andx;
	uint16 fnum;
	uint32 startpos;
	uint16 smb_maxcnt;
	uint16 smb_mincnt;
	uint16 vwv7;
	uint16 vwv8;
	uint16 vwv9;

	uint16 count;
	uint8 none[count];

} Q_READ_ANDX_10;

typedef struct _Q_READ_ANDX_12 {
	ANDX_INFO andx;
	uint16 fnum;
	uint32 startpos;
	uint16 smb_maxcnt;
	uint16 smb_mincnt;
	uint16 vwv7;
	uint16 vwv8;
	uint16 vwv9;
	uint32 startposhi;

	uint16 count;
	uint8 none[count];

} Q_READ_ANDX_12;

typedef struct _Q_READ_ANDX {
	uint8 wcount;
	union ctr[wcount] {
		case 10 Q_READ_ANDX_10 q10;
		case 12 Q_READ_ANDX_12 q12;
	}
} Q_READ_ANDX;

typedef struct _R_WRITE_ANDX {
	uint8 wcount;
	ANDX_INFO andx;
	uint16 nwritten;
	uint16 vwv3;
	uint16 vwv4;
	uint16 vwv5;

	uint16 count;
	uint8 none[count];

} R_WRITE_ANDX;

typedef struct _Q_WRITE_ANDX_12 {
	ANDX_INFO andx;
	uint16 fnum;
	uint32 startpos;
	uint16 vwv5;
	uint16 vwv6;
	uint16 write_through;
	uint16 vwv8;
	uint16 vwv9;
	uint16 numtowrite;
	uint16 smb_doff;

	uint16 count;
	uint8 data[count];

} Q_WRITE_ANDX_12;

typedef struct _Q_WRITE_ANDX_14 {
	ANDX_INFO andx;
	uint16 fnum;
	uint32 startpos;
	uint16 vwv5;
	uint16 vwv6;
	uint16 write_through;
	uint16 vwv8;
	uint16 vwv9;
	uint16 numtowrite;
	uint16 smb_doff;
	uint32 startposhi;

	uint16 count;
	uint8 data[count];

} Q_WRITE_ANDX_14;

typedef struct _Q_WRITE_ANDX {
	uint8 wcount;
	union ctr[wcount] {
		case 12 Q_WRITE_ANDX_12 q12;
		case 14 Q_WRITE_ANDX_14 q14;
	}
} Q_WRITE_ANDX;



typedef struct _Q_NTTRANS_19 {
	UCHAR MaxSetupCount;          /* Max setup words to return */
	USHORT Reserved;
	ULONG TotalParameterCount;    /* Total parameter bytes being sent */
	ULONG TotalDataCount;         /* Total data bytes being sent */
	ULONG MaxParameterCount;      /* Max parameter bytes to return */
	ULONG MaxDataCount;           /* Max data bytes to return */
	ULONG ParameterCount;         /* Parameter bytes sent this buffer */
	ULONG ParameterOffset;        /* Offset (from header start) to */
					 /* Parameters */
	ULONG DataCount;              /* Data bytes sent this buffer */
	ULONG DataOffset;             /* Offset (from header start) to data */
	UCHAR SetupCount;             /* Count of setup words */
	USHORT Function;              /* The transaction function code */
	UCHAR Buffer[1];
	USHORT Setup[SetupCount];     /* Setup words */
	USHORT ByteCount;             /* Count of data bytes */
	UCHAR Pad1;                   /* Pad to LONG */
	UCHAR Parameters[ParameterCount];/* Parameter bytes */
	UCHAR Pad2;                   /* Pad to LONG */
	UCHAR Data[DataCount];        /* Data bytes */

} Q_NTTRANS_19;

typedef struct _Q_NTTRANS {
	uint8 wcount;
	union ctr[wcount] {
		case 19 Q_NTTRANS_19 q19;
	}
} Q_NTTRANS;

typedef struct _R_NTTRANS_18 {
	UCHAR Reserved[3];
	ULONG TotalParameterCount;   /* Total parameter bytes being sent */
	ULONG TotalDataCount;        /* Total data bytes being sent */
	ULONG ParameterCount;        /* Parameter bytes sent this buffer */
	ULONG ParameterOffset;       /* Offset (from header start) to */
					  /* Parameters */
	ULONG ParameterDisplacement; /* Specifies the offset from the start */
				/* of the overall parameter block to */
				/* the parameter bytes that are */
				/* contained in this message */
	ULONG DataCount;        /* Data bytes sent this buffer */
	ULONG DataOffset;       /* Offset (from header start) to data */
	ULONG DataDisplacement; /* Specifies the offset from the start */
				/* of the overall data block to the */
				/* data bytes that are contained in */
				/* this message. */
	UCHAR SetupCount;       /* Count of setup words */
	USHORT Setup[SetupCount]; /* Setup words */
	USHORT ByteCount;       /* Count of data bytes */
	UCHAR Pad1;           /* Pad to LONG */
	UCHAR Parameters[ParameterCount]; /* Parameter bytes */
	UCHAR Pad2;           /* Pad to SHORT or LONG */
	UCHAR Data[DataCount];  /* Data bytes */
} R_NTTRANS_18;

typedef struct _R_NTTRANS {
	uint8 wcount;
	union ctr[wcount] {
		case 18 R_NTTRANS_18 q18;
	}
} R_NTTRANS;

typedef struct _Q_TRANS2_15 {
	USHORT TotalParameterCount;      /* Total parameter bytes being sent */
	USHORT TotalDataCount;           /* Total data bytes being sent */
	USHORT MaxParameterCount;        /* Max parameter bytes to return */
	USHORT MaxDataCount;             /* Max data bytes to return */
	UCHAR MaxSetupCount;             /* Max setup words to return */
	UCHAR Reserved;
	USHORT Flags;                    /* Additional information: */
				  /* bit 0 - also disconnect TID in TID */
	ULONG Timeout;
	USHORT Reserved2;
	USHORT ParameterCount;           /* Parameter bytes sent this buffer */
	USHORT ParameterOffset;          /* Offset (from header start) to */
				  /* Parameters */
	USHORT DataCount;                /* Data bytes sent this buffer */
	USHORT DataOffset;               /* Offset (from header start) to data */
	UCHAR SetupCount;                /* Count of setup words */
	UCHAR Reserved3;                 /* Reserved (pad above to word) */
	USHORT Setup[SetupCount];        /* Setup words (# = SetupWordCount) */
	USHORT ByteCount;                /* Count of data bytes */
	string Name;                    /* Must be NULL */
	UCHAR Pad[];                     /* Pad to SHORT or LONG */
	UCHAR Parameters[ParameterCount];/* Parameter bytes (# = ParameterCount) */ 
	UCHAR Pad1[];                    /* Pad to SHORT or LONG */
	UCHAR Data[DataCount];           /* Data bytes (# = DataCount) */

} Q_TRANS2_15;

typedef struct _Q_TRANS2 {
	uint8 wcount;
	union ctr[wcount] {
		case 15 Q_TRANS2_15 q15;
	}
} Q_TRANS2;

typedef struct _Q_TRANS_16 {
	USHORT TotalParameterCount;      /* Total parameter bytes being sent */
	USHORT TotalDataCount;           /* Total data bytes being sent */
	USHORT MaxParameterCount;        /* Max parameter bytes to return */
	USHORT MaxDataCount;             /* Max data bytes to return */
	UCHAR MaxSetupCount;             /* Max setup words to return */
	UCHAR Reserved;
	USHORT Flags;                    /* Additional information: */
				  /* bit 0 - also disconnect TID in TID */
	ULONG Timeout;
	USHORT Reserved2;
	USHORT ParameterCount;           /* Parameter bytes sent this buffer */
	USHORT ParameterOffset;          /* Offset (from header start) to */
				  /* Parameters */
	USHORT DataCount;                /* Data bytes sent this buffer */
	USHORT DataOffset;               /* Offset (from header start) to data */
	UCHAR SetupCount;                /* Count of setup words */
	UCHAR Reserved3;                 /* Reserved (pad above to word) */
	USHORT Setup[SetupCount];        /* Setup words (# = SetupWordCount) */
	USHORT ByteCount;                /* Count of data bytes */
	string Name;                    /* Must be NULL */
	UCHAR Pad[];                     /* Pad to SHORT or LONG */
	UCHAR Parameters[ParameterCount];/* Parameter bytes (# = ParameterCount) */ 
	UCHAR Pad1[];                    /* Pad to SHORT or LONG */
	UCHAR Data[DataCount];           /* Data bytes (# = DataCount) */

} Q_TRANS_16;

typedef struct _Q_TRANS {
	uint8 wcount;
	union ctr[wcount] {
		case 16 Q_TRANS_16 q16;
	}
} Q_TRANS;

typedef struct _R_TRANS_10 {
	USHORT TotalParameterCount;/* Total parameter bytes being sent */
	USHORT TotalDataCount;     /* Total data bytes being sent */
	USHORT Reserved2;
	USHORT ParameterCount;     /* Parameter bytes sent this buffer */
	USHORT ParameterOffset;    /* Offset (from header start) to */
				  /* Parameters */
	USHORT ParameterDisplacement; /* Specifies the offset from the start */
				  /* of the overall parameter block to */
				  /* the parameter bytes that are */
				  /* contained in this message */
	USHORT DataCount;          /* Data bytes sent this buffer */
	USHORT DataOffset;         /* Offset (from header start) to data */
	USHORT DataDisplacement;   /* Specifies the offset from the start */
				  /* of the overall data block to the */
				  /* data bytes that are contained in */
				  /* this message. */
	UCHAR SetupCount;         /* Count of setup words */
	UCHAR Reserved3;                 /* Reserved (pad above to word) */
	USHORT Setup[SetupCount]; /* Setup words */
	USHORT ByteCount;         /* Count of data bytes */
	UCHAR Pad1;               /* Pad to LONG */
	UCHAR Parameters[ParameterCount];/* Parameter bytes */
	/*UCHAR Pad2;               Pad to SHORT or LONG */
	UCHAR Data[DataCount];    /* Data bytes */
} R_TRANS_10;

typedef struct _R_TRANS {
	uint8 wcount;
	union ctr[wcount] {
		case 10 R_TRANS_10 q10;
	}
} R_TRANS;

typedef struct _Q_NT_CREATE_ANDX_24 {
	ANDX_INFO andx;
	uint8 reserved;
	uint16 name_len;
	ULONG flags;
	ULONG rootfid;
	ULONG access;
	hyper allocsize;
	ULONG attribs;
	ULONG sharing;
	ULONG creat_disp;
	ULONG creat_options;
	ULONG impersonation;
	uint8 sec_flags;

	uint16 count;
	uint8 name[name_len];

} Q_NTCREATE_ANDX_24;

typedef struct _Q_NTCREATE_ANDX{
	uint8 wcount;
	union ctr[wcount] {
		case 24 Q_NTCREATE_ANDX_24 q24;
	}
} Q_NTCREATE_ANDX;

typedef struct {
	ANDX_INFO andx;
	uint8 oplock_level;
	uint16 fid;
	ULONG action;
	TIME create_time;
	TIME access_time;
	TIME write_time;
	TIME change_time;
	ULONG ext_attribs;
	hyper allocsize;
	hyper size;
	uint16 type;
	uint16 state;
	uint8 directory;

	uint16 count;
	uint8 none[count];

} R_NTCREATE_ANDX_34;

typedef struct _R_NTCREATE_ANDX{
	uint8 wcount;
	union ctr[wcount] {
		case 34 R_NTCREATE_ANDX_34 q34;
	}
} R_NTCREATE_ANDX;

typedef struct {
	ULONG smbhdr;
	uint8 com;
	uint8 rcls;
	uint8 reh;
	uint16 err;
	uint8 flg;
	uint16 flg2;
	uint16 reserved;
	uint8 SecuritySignature[8]; 
	uint16 pad;
	uint16 tid;
	uint16 pid;
	uint16 uid;
	uint16 mid;
} SMB_HDR;

typedef struct _R_SMB {
	ULONG nbhdr;
	SMB_HDR hdr;
	union ctr[hdr.com] {
		case 4   R_CLOSE      r4;
		case 6   R_UNLINK     r6;
		case 36  R_LOCKING_ANDX r36;
		case 37  R_TRANS r37;
		case 45  R_OPEN_ANDX r45;
		case 46  R_READ_ANDX r46;
		case 47  R_WRITE_ANDX r47;
		case 113 R_TDIS    r113;
		case 114 R_NEGPROT r114;
		case 115 R_SESSION_SETUP_ANDX r115;
		case 117 R_TCON_ANDX r117;
		case 128 R_DSKATTR    r128;
		case 160 R_NTTRANS r160;
		case 162 R_NTCREATE_ANDX r162;
	}
} R_SMB;

typedef struct _Q_SMB {
	ULONG nbhdr;
	SMB_HDR hdr;
	union ctr[hdr.com] {
		case 4   Q_CLOSE      q4;
		case 6   Q_UNLINK     q6;
		case 36  Q_LOCKING_ANDX q36;
		case 37  Q_TRANS q37;
		case 45  Q_OPEN_ANDX q45;
		case 46  Q_READ_ANDX q46;
		case 47  Q_WRITE_ANDX q47;
		case 50  Q_TRANS2 q50;
		case 113 Q_TDIS    q113;
		case 114 Q_NEGPROT q114;
		case 115 Q_SESSION_SETUP_ANDX q115;
		case 117 Q_TCON_ANDX q117;
		case 128 Q_DSKATTR    q128;
		case 160 Q_NTTRANS q160;
		case 162 Q_NTCREATE_ANDX q162;
	}
} Q_SMB;