diff options
Diffstat (limited to 'source3/aparser')
56 files changed, 4009 insertions, 0 deletions
diff --git a/source3/aparser/Makefile b/source3/aparser/Makefile new file mode 100644 index 0000000000..953743b234 --- /dev/null +++ b/source3/aparser/Makefile @@ -0,0 +1,17 @@ +CFLAGS=-Wall -g +CC=gcc + +OBJ = vluke.o parser.o +AWKPROGS=dump.awk harness.awk header.awk parsefn.awk main.awk parsetree.awk template.awk util.awk + +all: test.h vluke + +test.h : $(AWKPROGS) + igawk -f main.awk srvsvc.struct + +vluke: test.h $(OBJ) + $(CC) $(CFLAGS) -o vluke $(OBJ) + +clean: + rm -f *.o test.h prs_*.[ch] + diff --git a/source3/aparser/build b/source3/aparser/build new file mode 100755 index 0000000000..4cdf2901f8 --- /dev/null +++ b/source3/aparser/build @@ -0,0 +1,13 @@ +#!/bin/sh + +file=$1 + +if ! igawk -f main.awk $file; then + echo parse failed; + exit 1; +fi + +echo compiling vluke +gcc -Wall -g -o vluke parser.c vluke.c util.c +echo done. + diff --git a/source3/aparser/cifs.struct b/source3/aparser/cifs.struct new file mode 100644 index 0000000000..202f0d7e61 --- /dev/null +++ b/source3/aparser/cifs.struct @@ -0,0 +1,1029 @@ +module cifs + +option autoalign False + + +#define BOOL uint32 +#define UCHAR uint8 +#define WCHAR uint16 +#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 */ + +} 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 */ + .align4 0; + 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 */ + .align4 0; + UCHAR Parameters[ParameterCount];/* Parameter bytes */ + .align4 0; + 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 */ + .align4 0; + UCHAR Parameters[ParameterCount]; /* Parameter bytes */ + .align4 0; + UCHAR Data[DataCount]; /* Data bytes */ +} R_NTTRANS_18; + +typedef struct _R_NTTRANS { + uint8 wcount; + union ctr[wcount] { + case 18 R_NTTRANS_18 q18; + } + .align4 2; +} R_NTTRANS; + +/*Setup[0] Transaction2 Value Description */ +/*Subcommand Code */ +/*=============================== ===== ============================= */ + +#define TRANS2_OPEN2 0x00 /* Create file with extended attributes */ +#define TRANS2_FIND_FIRST2 0x01 /* Begin search for files */ +#define TRANS2_FIND_NEXT2 0x02 /* Resume search for files */ +#define TRANS2_QUERY_FS_INFO 0x03 /* Get file system information +#define TRANS2_RESERVED4 0x04 /* Reserved */ +#define TRANS2_QUERY_PATH_INFO 0x05 /* Get information about a named file or directory */ +#define TRANS2_SET_PATH_INFO 0x06 /* Set information about a named file or directory */ +#define TRANS2_QUERY_FILE_INFO 0x07 /* Get information about a handle */ +#define TRANS2_SET_FILE_INFO 0x08 /* Set information by handle */ +#define TRANS2_FSCTL 0x09 /* Not implemented by NT server */ +#define TRANS2_IOCTL2 0x0A /* Not implemented by NT server */ +#define TRANS2_FIND_NOTIFY_FIRST 0x0B /* Not implemented by NT server */ +#define TRANS2_FIND_NOTIFY_NEXT 0x0C /* Not implemented by NT server */ +#define TRANS2_CREATE_DIRECTORY 0x0D /* Create directory with extended attributes */ +#define TRANS2_SESSION_SETUP 0x0E /* Session setup with extended security information */ +#define TRANS2_GET_DFS_REFERRAL 0x10 /* Get a DFS referral */ +#define TRANS2_REPORT_DFS_INCONSISTENCY 0x11 /* Report a DFS knowledge inconsistency */ + +typedef struct { + USHORT InformationLevel; /* Level of information requested */ +} TRANS2_QUERY_FS_INFO_STRUCT; + +#define SMB_INFO_STANDARD 1 +#define SMB_INFO_QUERY_EA_SIZE 2 +#define SMB_SET_FILE_BASIC_INFO 0x101 +#define SMB_SET_FILE_DISPOSITION_INFO 0x102 +#define SMB_SET_FILE_ALLOCATION_INFO 0x103 +#define SMB_SET_FILE_END_OF_FILE_INFO 0x104 + + +typedef struct { + hyper CreationTime; + hyper LastAccessTime; + hyper LastWriteTime; + hyper ChangeTime; + USHORT Attributes; + .align4 0; +} SMB_QUERY_FILE_BASIC_INFO_STRUCT; + + +typedef struct { + ULONG fs_atr; + LONG max_len_filename; + ULONG length; + uint8 fs[length]; + .align4 2; +} SMB_QUERY_FS_ATTRIBUTE_INFO_STRUCT; + +#define FILE_CASE_SENSITIVE_SEARCH 0x00000001 +#define FILE_CASE_PRESERVED_NAMES 0x00000002 +#define FILE_PRSISTENT_ACLS 0x00000004 +#define FILE_FILE_COMPRESSION 0x00000008 +#define FILE_VOLUME_QUOTAS 0x00000010 +#define FILE_DEVICE_IS_MOUNTED 0x00000020 +#define FILE_VOLUME_IS_COMPRESSED 0x00008000 + +typedef struct { + USHORT Fid; + USHORT InformationLevel; + USHORT Reserved; + .align4 0; + + union ctr[InformationLevel] { + case 0x101 SMB_QUERY_FILE_BASIC_INFO_STRUCT t101; + } + +} TRANS2_SET_FILE_INFO_STRUCT; + +typedef struct { + USHORT InformationLevel; /* Level of information requested */ + ULONG Reserved; /* Must be zero */ + STRING FileName; /* File or directory name */ +} TRANS2_QUERY_PATH_INFO_STRUCT; + +typedef struct { + USHORT SearchAttributes; + USHORT SearchCount; + USHORT Flags; + USHORT InformationLevel; + ULONG SearchStorageType; + STRING FileName; +} TRANS2_FIND_FIRST2_STRUCT; + +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 */ + .align4 0; + union ctr[Setup[0]] { + case 1 TRANS2_FIND_FIRST2_STRUCT t1; + case 3 TRANS2_QUERY_FS_INFO_STRUCT t3; + case 5 TRANS2_QUERY_PATH_INFO_STRUCT t5; + case 8 TRANS2_SET_FILE_INFO_STRUCT t8; + } + +} Q_TRANS2_15; + +typedef struct _Q_TRANS2 { + uint8 wcount; + union ctr[wcount] { + case 15 Q_TRANS2_15 q15; + } +} Q_TRANS2; + +typedef struct { + ULONG NextEntryOffset; + ULONG FileIndex; + hyper CreationTime; + hyper LastAccessTime; + hyper LastWriteTime; + hyper ChangeTime; + hyper EndOfFile; + hyper AllocationSize; + ULONG ExtFileAttributes; + ULONG FileNameLength; + ULONG EaSize; + UCHAR ShortNameLength; + UCHAR Reserved; + uint8 ShortName[24]; + UCHAR FileName[FileNameLength]; + .align4 2; +} SMB_FIND_FILE_BOTH_DIRECTORY_INFO; + +typedef struct { + .align2 0; +} R_TRANS2_D0; + +typedef struct { + .align4 2; +} R_TRANS2_P0; + +typedef struct { + USHORT Reserved; +} R_TRANS2_P2; + +typedef struct { + USHORT Sid; /* Search handle */ + USHORT SearchCount; /* Number of entries returned */ + USHORT EndOfSearch; /* Was last entry returned? */ + USHORT EaErrorOffset; /* Offset into EA list if EA error */ + USHORT LastNameOffset; /* Offset into data to file name of last */ + /* entry, if server needs it to resume */ + /* search; else 0 */ + .align4 2; + SMB_FIND_FILE_BOTH_DIRECTORY_INFO i104[SearchCount]; +} R_TRANS2_FIND_FIRST2_STRUCT; + +typedef struct { + SMB_QUERY_FILE_BASIC_INFO_STRUCT i101; + .align4 2; +} R_TRANS2_FILE_BASIC_STRUCT; + +typedef struct _R_TRANS2_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 */ + .align4 2; + union pctr[ParameterCount] { + case 0 R_TRANS2_P0 p0; + case 2 R_TRANS2_P2 p2; + case 10 R_TRANS2_FIND_FIRST2_STRUCT r10; + } + union dctr[DataCount] { + case 0 R_TRANS2_D0 d0; + case 0x24 R_TRANS2_FILE_BASIC_STRUCT r24; + case 0x14 SMB_QUERY_FS_ATTRIBUTE_INFO_STRUCT r14; + } +} R_TRANS2_10; + +typedef struct { + USHORT ByteCount; /* Count of data bytes */ +} R_TRANS2_0; + +typedef struct _R_TRANS2 { + uint8 wcount; + union ctr[wcount] { + case 0 R_TRANS2_0 q0; + case 10 R_TRANS2_10 q10; + } +} R_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 */ + .align4 0; + UCHAR Parameters[ParameterCount];/* Parameter bytes (# = ParameterCount) */ + .align4 0; + 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 */ + .align4 0; + UCHAR Parameters[ParameterCount];/* Parameter bytes */ + .align4 0; + 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 50 R_TRANS2 q50; + case 113 R_TDIS r113; + case 114 R_NEGPROT r114; + case 115 R_SESSION_SETUP_ANDX r115; + case 116 R_ULOGOFF_ANDX r116; + 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 116 Q_ULOGOFF_ANDX q116; + case 117 Q_TCON_ANDX q117; + case 128 Q_DSKATTR q128; + case 160 Q_NTTRANS q160; + case 162 Q_NTCREATE_ANDX q162; + } +} Q_SMB; + diff --git a/source3/aparser/dump.awk b/source3/aparser/dump.awk new file mode 100644 index 0000000000..11bfb107e4 --- /dev/null +++ b/source3/aparser/dump.awk @@ -0,0 +1,70 @@ +# dump the current parse tree + + +function element_string(elnum, + LOCAL, elem) +{ + elem = elements[elnum, "elem"]; + if (elements[elnum, "ptr"]=="1") elem="*"elem; + if (elements[elnum, "array_len"]!="") + elem=elem"["elements[elnum, "array_len"]"]"; + if (elements[elnum, "switch"]!="") + elem=elem"["elements[elnum, "switch"]"]"; + return elem; +} + +function dump_element(f, elnum, + LOCAL, elem, type) +{ + type = elements[elnum, "type"]; + case = elements[elnum, "case"]; + elem = element_string(elnum); + if (case != "") { + xprintf(f,"\t\tcase %d %s %s;\n", case, type, elem); + } else { + xprintf(f,"\t%s %s;\n", type, elem); + } +} + +function dump_union(f, elnum, + LOCAL, i) +{ + xprintf(f,"\tunion %s {\n", element_string(elnum)); + for (i=0;i<unions[elnum, "num_elems"];i++) { + dump_element(f, unions[elnum, i]); + } + xprintf(f,"\t}\n"); +} + +function dump_elem(f, struct_num, elem_num, + LOCAL, enum) +{ + elnum = structs[struct_num, elem_num]; + + if (elements[elnum, "type"] == "union") { + dump_union(f, elnum); + } else { + dump_element(f, elnum); + } +} + +function dump_structs(f, NIL, + LOCAL, i, j) +{ + xprintf(f,"/* dump of parsed structures */\n\n\n"); + + for (i=0;i < num_options;i++) { + xprintf(f,"option %s %s\n", options[i, "name"], options[i, "value"]); + } + xprintf(f,"\n\n"); + + for (i=0;i < num_structs;i++) { + xprintf(f,"/* structure %d */\n", i); + xprintf(f,"struct %s {\n", structs[i, "name"]); + for (j=0;j<structs[i, "num_elems"];j++) { + dump_elem(f, i, j); + } + xprintf(f,"};\n\n"); + } + xprintf(f,"/* end dump */\n\n"); +} diff --git a/source3/aparser/harness.awk b/source3/aparser/harness.awk new file mode 100644 index 0000000000..6c4c35c40f --- /dev/null +++ b/source3/aparser/harness.awk @@ -0,0 +1,17 @@ +function produce_harness(f, + LOCAL, v, struct_num, i) +{ + struct_num=structs[test]; + + v["MODULE"]=module; + + print_template(f, "harness_start.tpl", v); + + for (i=0;i<num_structs;i++) { + v["TEST"] = structs[i, "name"]; + print_template(f, "harness.tpl", v); + } + + print_template(f, "harness_end.tpl", v); +} + diff --git a/source3/aparser/header.awk b/source3/aparser/header.awk new file mode 100644 index 0000000000..ba7117436b --- /dev/null +++ b/source3/aparser/header.awk @@ -0,0 +1,80 @@ +# produce a header file for a parsed struct file + +function header_elstring(elnum, + LOCAL, elem) +{ + array_len = elements[elnum, "array_len"]; + elem=elements[elnum, "elem"]; + if (elements[elnum, "ptr"]=="1") elem="*"elem; + if (array_len!="") { + if (is_constant(array_len) == 1) { + elem=elem"["array_len"]"; + } else { + elem="*"elem; + } + } + return elem; +} + +function header_element(f, elnum, + LOCAL, type) +{ + type=elements[elnum, "type"]; + if (substr(type,1,1) == ".") return; + xprintf(f,"\t%s %s;\n", type, header_elstring(elnum)); +} + +function header_union(f, elnum, + LOCAL, i) +{ + xprintf(f,"\tunion {\n"); + for (i=0;i<unions[elnum, "num_elems"];i++) { + header_element(f, unions[elnum, i]); + } + xprintf(f,"\t} %s;\n", header_elstring(elnum)); +} + +function header_elem(f, elnum) +{ + + if (elements[elnum, "type"] == "union") { + header_union(f, elnum); + } else { + header_element(f, elnum); + } +} + +function header_struct(f, struct_num, + LOCAL, i) +{ + xprintf(f,"/* structure %s */\n", + structs[struct_num, "name"]); + xprintf(f,"typedef struct {\n"); + for (i=0;i < structs[struct_num, "num_elems"];i++) { + header_elem(f, structs[struct_num, i]); + } + xprintf(f,"} %s;\n\n\n", structs[struct_num, "name"]); +} + + +function produce_headers(f, NIL, + LOCAL, i) +{ + xprintf(f,"/* auto-generated headers for %s */\n\n\n", module); + xprintf(f,"#ifndef _%s_\n", module); + xprintf(f,"#define _%s_\n", module); + + xprintf(f,"\n\n"); + for (i=0;i < num_options;i++) { + xprintf(f,"#define OPTION_%s %s\n", + options[i, "name"], options[i, "value"]); + } + xprintf(f,"\n\n"); + + for (i=0;i < num_structs;i++) { + header_struct(f, i); + } + xprintf(f,"/* end auto-generated headers */\n\n"); + xprintf(f,"#endif /* _%s_ */\n", module); +} + diff --git a/source3/aparser/main.awk b/source3/aparser/main.awk new file mode 100644 index 0000000000..4969f2217a --- /dev/null +++ b/source3/aparser/main.awk @@ -0,0 +1,25 @@ +# the main program + +@include dump.awk +@include header.awk +@include util.awk +@include template.awk +#@include parsefn.awk +@include parserel.awk +@include harness.awk +@include parsetree.awk +@include token.awk + +END { + dump_structs("dump.out"); + printf("Producing headers...\n"); + produce_headers("prs_"module".h"); +# printf("Producing parsers...\n"); +# produce_parsers("prs_"module".c", "mod_"module".c"); + printf("Producing relative parsers...\n"); + produce_relative("prs_"module".c"); + printf("Producing harness...\n"); + produce_harness("test.h"); + printf("Done.\n"); + exit 0; +} diff --git a/source3/aparser/parsefn.awk b/source3/aparser/parsefn.awk new file mode 100644 index 0000000000..2bebd765e6 --- /dev/null +++ b/source3/aparser/parsefn.awk @@ -0,0 +1,271 @@ +# build parse functions for a parsed struct file + +function elem_name(v, elem) +{ + return v["UNION"]elem; +} + +function parse_array(f, v, elnum, flags, + LOCAL, type, elem, array_len) +{ + type = elements[elnum, "type"]; + elem = elements[elnum, "elem"]; + array_len = elements[elnum, "array_len"]; + v["ELEM"] = elem_name(v, elem); + v["TYPE"] = type; + v["FLAGS"] = flags; + v["ARRAY_LEN"] = array_len; + + if (array_len=="+") { + print_template(f,"prs_array_optional.tpl", v); + return; + } + + if (array_len=="*") { + print_template(f,"prs_array_remainder.tpl", v); + return; + } + + if (type == "wchar" || type == "uint16") { + if (match(array_len,"[0-9]") == 1) { + print_template(f, "prs_wstring_fixed.tpl", v); + } else { + print_template(f, "prs_wstring.tpl", v); + } + } else if (type == "uint8") { + if (match(array_len,"[0-9]") == 1) { + print_template(f, "prs_uint8s_fixed.tpl", v); + } else { + print_template(f, "prs_uint8s.tpl", v); + } + } else { + print_template(f, "prs_array.tpl", v); + } +} + + +function parse_element(f, v, elnum, flags, + LOCAL, type, elem) +{ + if (elements[elnum,"nowire"] != "") { + return; + } + type = elements[elnum, "type"]; + if (substr(type,1,1) == ".") return; + elem = elements[elnum, "elem"]; + if (elements[elnum,"ptr"] == "") { + v["PTR"] = "\\&"; + } else { + v["PTR"] = " "; + } + v["ELEM"] = elem_name(v, elem); + v["TYPE"] = type; + v["FLAGS"] = flags; + print_template(f, "prs_element.tpl", v); +} + +function parse_union(f, v, elnum, flags, + LOCAL, i) +{ + v["UNION"] = elements[elnum, "elem"]; + v["SWITCH"] = elements[elnum, "switch"]; + + if (elements[elnum, "ptr"] == "1") { + v["UNION"] = v["UNION"]"->"; + } else { + v["UNION"] = v["UNION"]"."; + } + + print_template(f, "union_start.tpl", v); + for (i=0;i<unions[elnum, "num_elems"];i++) { + v["CASE"] = elements[unions[elnum, i], "case"]; + print_template(f, "prs_case.tpl", v); + if (elements[elnum, "ptr"] == "1") { + parse_scalars(f, v, unions[elnum, i], "PARSE_SCALARS"); + parse_buffers(f, v, unions[elnum, i], "PARSE_BUFFERS"); + } else { + if (flags == "PARSE_SCALARS") { + parse_scalars(f, v, unions[elnum, i], flags); + } else { + parse_buffers(f, v, unions[elnum, i], flags); + } + } + print_template(f, "prs_break.tpl", v); + } + v["UNION"] = ""; + + print_template(f, "union_end.tpl", v); +} + +function parse_scalar(f, v, elnum, flags) +{ + if (elements[elnum, "type"] == "union") { + parse_union(f, v, elnum, flags); + } else if (elements[elnum, "array_len"]!="") { + parse_array(f, v, elnum, flags); + } else { + parse_element(f, v, elnum, flags); + } +} + +function parse_align2(f, v, elnum, flags, + LOCAL, elem) +{ + elem = elements[elnum, "elem"]; + v["OFFSET"] = elem_name(v, elem); + print_template(f, "prs_align2.tpl", v); +} + +function parse_align4(f, v, elnum, flags, + LOCAL, elem) +{ + elem = elements[elnum, "elem"]; + v["OFFSET"] = elem_name(v, elem); + print_template(f, "prs_align4.tpl", v); +} + +function parse_pointer(f, v, elnum, flags, + LOCAL, elem) +{ + elem = elements[elnum, "elem"]; + v["ELEM"] = elem_name(v, elem); + v["FLAGS"] = flags; + print_template(f, "prs_pointer.tpl", v); +} + +function parse_scalar_fn(m, v, elnum, + LOCAL, elem, type) +{ + elem = elements[elnum, "elem"]; + type = elements[elnum, "type"] + xprintf(m, "%s %s", type, elem_name(v, elem)); + if (type == "union") { + } else if (elements[elnum, "array_len"]!="") { + } else { + } +} + +function parse_pointer_fn(f, v, elnum, flags, + LOCAL, elem) +{ + elem = elements[elnum, "elem"]; + v["ELEM"] = elem_name(v, elem); + v["FLAGS"] = flags; + xprintf(m, "%s\n", v["ELEM"]); +} + +function parse_scalars_fn(m, v, elnum, flags) +{ + if (elements[elnum, "type"] == ".align2") { + } + else if (elements[elnum, "type"] == ".align4") { + } + else if (elements[elnum, "ptr"] == "1") { + parse_pointer_fn(m, v, elnum, flags); + } else { + parse_scalar_fn(m, v, elnum, flags); + } +} + +function parse_scalars(f, v, elnum, flags) +{ + if (elements[elnum, "type"] == ".align2") { + parse_align2(f, v, elnum, flags); + } + else if (elements[elnum, "type"] == ".align4") { + parse_align4(f, v, elnum, flags); + } + else if (elements[elnum, "ptr"] == "1") { + parse_pointer(f, v, elnum, flags); + } else { + parse_scalar(f, v, elnum, flags); + } +} + +function parse_buffers(f, v, elnum, flags, + LOCAL, elem, type) +{ + elem = elements[elnum, "elem"]; + type = elements[elnum, "type"]; + v["ELEM"] = elem_name(v, elem); + if (elements[elnum, "type"] == ".align2") { + } + else if (elements[elnum, "type"] == ".align4") { + } else if (elements[elnum, "ptr"] == "1") { + print_template(f, "ifptr_start.tpl", v); + parse_scalar(f, v, elnum, "PARSE_SCALARS|PARSE_BUFFERS"); + print_template(f, "ifptr_end.tpl", v); + } else { + parse_scalar(f, v, elnum, flags); + } +} + +function struct_parser(f, m, v, struct_num, + LOCAL, i, n1, f1, num_elems) +{ + f1 = -1; + num_elems = structs[struct_num, "num_elems"]; + v["STRUCTNAME"] = structs[struct_num, "name"]; + v["FUNCNAME"] = "io_" v["STRUCTNAME"]; + print_template(f, "fn_start.tpl", v); + + for (n1=0;n1<num_elems;n1++) { + if (elements[structs[struct_num, n1], "type"] == ".trailer") { + f1 = n1; + break; + } + } + + # first all the structure pointers, scalars and arrays + for (i=0;i<n1;i++) { + parse_scalars(f, v, structs[struct_num, i], "PARSE_SCALARS"); + } + + print_template(f, "fn_mid.tpl", v); + + # now the buffers + for (i=0;i<n1;i++) { + parse_buffers(f, v, structs[struct_num, i], "PARSE_BUFFERS"); + } + + # and any trailers + for (i=n1;i<num_elems;i++) { + parse_scalars(f, v, structs[struct_num, i], "PARSE_SCALARS"); + parse_buffers(f, v, structs[struct_num, i], "PARSE_BUFFERS"); + } + + if (i > 0) { + print_template(f, "fn_end.tpl", v); + } + else { + print_template(f, "fn_end0.tpl", v); + } + + if (f1 == -1) + return; + + xprintf(m, "void fn_%s(\n", v["STRUCTNAME"]); + + for (i=f1+1;i<num_elems;i++) { + parse_scalars_fn(m, v, structs[struct_num, i]); + if (i != num_elems-1) + xprintf(m, ", \n"); + + } + + xprintf(m, ")\n{\n}\n"); +} + +function produce_parsers(f, m, + LOCAL, v, i) +{ + v["MODULE"]=module; + + print_template(f, "module_start.tpl", v); + + for (i=0;i < num_structs;i++) { + struct_parser(f, m, v, i); + } + + print_template(f, "module_end.tpl", v); +} diff --git a/source3/aparser/parser.c b/source3/aparser/parser.c new file mode 100644 index 0000000000..0c7153e1fb --- /dev/null +++ b/source3/aparser/parser.c @@ -0,0 +1,471 @@ +#include "parser.h" + +/******************************************************************* + Attempt, if needed, to grow a data buffer. + Also depends on the data stream mode (io). + ********************************************************************/ + +BOOL io_grow(io_struct *ps, uint32 extra_space) +{ + uint32 new_size; + char *new_data; + + ps->grow_size = MAX(ps->grow_size, ps->data_offset + extra_space); + + if(ps->data_offset + extra_space <= ps->buffer_size) + return True; + + /* + * We cannot grow the buffer if we're not reading + * into the io_struct, or if we don't own the memory. + */ + + if(UNMARSHALLING(ps) || !ps->is_dynamic) { + DEBUG(0,("io_grow: Buffer overflow - unable to expand buffer by %u bytes.\n", + (unsigned int)extra_space)); + return False; + } + + /* + * Decide how much extra space we really need. + */ + + extra_space -= (ps->buffer_size - ps->data_offset); + if(ps->buffer_size == 0) { + new_size = extra_space; + + if((new_data = malloc(new_size)) == NULL) { + DEBUG(0,("io_grow: Malloc failure for size %u.\n", (unsigned int)new_size)); + return False; + } + memset(new_data, '\0', new_size ); + } else { + /* + * If the current buffer size is bigger than the space needed, just + * double it, else add extra_space. + */ + new_size = MAX(ps->buffer_size*2, ps->buffer_size + extra_space); + + if ((new_data = Realloc(ps->data_p, new_size)) == NULL) { + DEBUG(0,("io_grow: Realloc failure for size %u.\n", + (unsigned int)new_size)); + return False; + } + } + ps->buffer_size = new_size; + ps->data_p = new_data; + + return True; +} + + +/******************************************************************* + Ensure we can read/write to a given offset. + ********************************************************************/ + +char *io_mem_get(io_struct *ps, uint32 extra_size) +{ + if(UNMARSHALLING(ps)) { + /* + * If reading, ensure that we can read the requested size item. + */ + if (ps->data_offset + extra_size > ps->buffer_size) { + DEBUG(0,("io_mem_get: reading data of size %u would overrun buffer.\n", + (unsigned int)extra_size )); + return NULL; + } + } else { + /* + * Writing - grow the buffer if needed. + */ + if(!io_grow(ps, extra_size)) + return False; + } + return &ps->data_p[ps->data_offset]; +} + +/******************************************************************* + Initialise a parse structure - malloc the data if requested. + ********************************************************************/ + +BOOL io_init(io_struct *ps, uint32 size, BOOL io) +{ + ZERO_STRUCTP(ps); + ps->io = io; + ps->bigendian_data = False; + ps->is_dynamic = False; + ps->data_offset = 0; + ps->buffer_size = 0; + ps->data_p = NULL; + + if (size != 0) { + ps->buffer_size = size; + if((ps->data_p = (char *)malloc((size_t)size)) == NULL) { + DEBUG(0,("io_init: malloc fail for %u bytes.\n", (unsigned int)size)); + return False; + } + ps->is_dynamic = True; /* We own this memory. */ + } + + return True; +} + +/******************************************************************* + debug output for parsing info. + + XXXX side-effect of this function is to increase the debug depth XXXX + + ********************************************************************/ +void io_debug(io_struct *ps, int depth, char *desc, char *fn_name) +{ + DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->data_offset, fn_name, desc)); +} + +/******************************************************************* + Align a the data_len to a multiple of align bytes - filling with + zeros. + ********************************************************************/ + +BOOL io_align2(io_struct *ps, int offset) +{ + uint32 mod = (ps->data_offset + offset) & (2-1); + + if (mod != 0) { + uint32 extra_space = (2 - mod); + if(!io_grow(ps, extra_space)) + return False; + memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space); + ps->data_offset += extra_space; + } + + return True; +} + +BOOL io_align4(io_struct *ps, int offset) +{ + uint32 mod = (ps->data_offset + offset) & (4-1); + + if (mod != 0) { + uint32 extra_space = (4 - mod); + if(!io_grow(ps, extra_space)) + return False; + memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space); + ps->data_offset += extra_space; + } + + return True; +} + +/******************************************************************* + Align a the data_len to a multiple of align bytes - filling with + zeros. + ********************************************************************/ + +BOOL io_align(io_struct *ps, int align) +{ + uint32 mod; + + if (!ps->autoalign) return True; + + mod = ps->data_offset & (align-1); + + if (align != 0 && mod != 0) { + uint32 extra_space = (align - mod); + if(!io_grow(ps, extra_space)) + return False; + memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space); + ps->data_offset += extra_space; + } + + return True; +} + + +/******************************************************************* + read from a socket into memory. + ********************************************************************/ +BOOL io_read(io_struct *ps, int fd, size_t len, int timeout) +{ + BOOL ok; + size_t prev_size = ps->buffer_size; + if (!io_grow(ps, len)) + { + return False; + } + + if (timeout > 0) + { + ok = (read(fd, &ps->data_p[prev_size], len) == len); + } + else + { + ok = (read(fd, &ps->data_p[prev_size], len) == len); + } + return ok; +} + + +/******************************************************************* + do IO on a uint32. + ********************************************************************/ +BOOL io_uint32(char *name, io_struct *ps, int depth, uint32 *data32, unsigned flags) +{ + char *q; + + if (!(flags & PARSE_SCALARS)) return True; + + if (!io_align(ps, 4)) return False; + + q = io_mem_get(ps, sizeof(uint32)); + if (q == NULL) return False; + + DBG_RW_IVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data32) + ps->data_offset += sizeof(uint32); + + return True; +} + +/******************************************************************* + do IO on a uint16. + ********************************************************************/ +BOOL io_uint16(char *name, io_struct *ps, int depth, uint16 *data16, unsigned flags) +{ + char *q; + + if (!(flags & PARSE_SCALARS)) return True; + + if (!io_align(ps, 2)) return False; + + q = io_mem_get(ps, sizeof(uint16)); + if (q == NULL) return False; + + DBG_RW_SVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data16) + ps->data_offset += sizeof(uint16); + + return True; +} + +/******************************************************************* + do IO on a uint8. + ********************************************************************/ +BOOL io_uint8(char *name, io_struct *ps, int depth, uint8 *data8, unsigned flags) +{ + char *q; + + if (!(flags & PARSE_SCALARS)) return True; + + q = io_mem_get(ps, sizeof(uint8)); + if (q == NULL) return False; + + DBG_RW_IVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data8) + ps->data_offset += sizeof(uint8); + + return True; +} + +/******************************************************************* + do IO on a pointer + ********************************************************************/ +BOOL io_pointer(char *desc, io_struct *ps, int depth, void **p, unsigned flags) +{ + uint32 v; + + if (!(flags & PARSE_SCALARS)) return True; + + v = (*p) ? 0xdeadbeef : 0; + if (!io_uint32(desc, ps, depth, &v, flags)) return False; + *p = (void *) (v ? 0xdeadbeef : 0); + return True; +} + +/******************************************************************* + Stream a null-terminated string. + ********************************************************************/ +BOOL io_SMBSTR(char *name, io_struct *ps, int depth, char **str, unsigned flags) +{ + char *q; + uint8 *start; + int i; + size_t len; + int start_offset = ps->data_offset; + + if (!(flags & PARSE_SCALARS)) return True; + + if (UNMARSHALLING(ps)) { + *str = io_mem_get(ps, 0); + if (*str == NULL) + return False; + len = strlen(*str); + ps->data_offset += len + 1; + } + else + { + len = strlen(*str)+1; + start = (uint8*)q; + + for(i = 0; i < len; i++) { + q = io_mem_get(ps, 1); + if (q == NULL) + return False; + + RW_CVAL(ps->io, q, (*str)[i],0); + ps->data_offset++; + } + } + + DEBUG(5,("%s%04x %s: %s\n", tab_depth(depth), + start_offset, name, *str)); + return True; +} + +/****************************************************************** + do IO on a byte array + ********************************************************************/ +BOOL io_uint8s(char *name, io_struct *ps, int depth, uint8 **data8s, int len, unsigned flags) +{ + char *q; + size_t num_bytes = len * sizeof(uint8); + + if (!(flags & PARSE_SCALARS)) return True; + + q = io_mem_get(ps, num_bytes); + if (q == NULL) return False; + + if (MARSHALLING(ps)) + { + DBG_RW_PCVAL(True, name, depth, ps->data_offset, ps->io, q, *data8s, len) + } + else + { + *data8s = q; + dump_data(depth+5, *data8s, num_bytes); + } + ps->data_offset += num_bytes; + + return True; +} +/****************************************************************** + do IO on a fixed-size byte array + ********************************************************************/ +BOOL io_uint8s_fixed(char *name, io_struct *ps, int depth, uint8 *data8s, int len, unsigned flags) +{ + char *q; + size_t num_bytes = len * sizeof(uint8); + + if (!(flags & PARSE_SCALARS)) return True; + + q = io_mem_get(ps, num_bytes); + if (q == NULL) return False; + + DBG_RW_PCVAL(True, name, depth, ps->data_offset, ps->io, q, data8s, len) + ps->data_offset += num_bytes; + + return True; +} + + +/****************************************************************** + do IO on an io (eh?? :) + ********************************************************************/ +BOOL io_io_struct(char *name, io_struct *ps, int depth, io_struct *io, unsigned flags) +{ + char *q; + uint16 len; + + if (!(flags & PARSE_SCALARS)) return True; + + q = io_mem_get(ps, sizeof(uint16)); + if (q == NULL) return False; + + /* length first */ + if (MARSHALLING(ps)) + { + len = io->data_offset; + } + if (!io_uint16("len", ps, depth+1, &len, flags)) + { + return False; + } + if (UNMARSHALLING(ps)) + { + if (!io_init(io, len, UNMARSHALL)) + { + return False; + } + } + + /* now data */ + q = io_mem_get(ps, len * sizeof(uint8)); + if (q == NULL) return False; + + if (MARSHALLING(ps)) + { + DBG_RW_PCVAL(False, name, depth+1, ps->data_offset, ps->io, q, io->data_p, len) + } + else + { + io->data_p = q; + dump_data(depth+5, q, len); + } + ps->data_offset += len; + + return True; +} + +/****************************************************************** + do IO on a unicode array + ********************************************************************/ +BOOL io_wstring(char *name, io_struct *ps, int depth, uint16 *data16s, int len, unsigned flags) +{ + char *q; + + if (!(flags & PARSE_SCALARS)) return True; + + if (!io_align(ps, 2)) return False; + + q = io_mem_get(ps, len * sizeof(uint16)); + if (q == NULL) return False; + + DBG_RW_PSVAL(True, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data16s, len) + ps->data_offset += (len * sizeof(uint16)); + + return True; +} + + +/****************************************************************** +allocate some memory for a parse structure + ********************************************************************/ +void io_free(io_struct *ps) +{ + if (ps->is_dynamic && ps->data_p) + { + free(ps->data_p); + ps->data_p = NULL; + } +} + +/****************************************************************** +allocate some memory for a parse structure + ********************************************************************/ +BOOL io_alloc(char *name, io_struct *ps, void **ptr, unsigned size) +{ + (*ptr) = (void *)malloc(size); + if (*ptr) return True; + return False; +} + +/****************************************************************** +realloc some memory for a parse structure + ********************************************************************/ +BOOL io_realloc(char *name, io_struct *ps, void **ptr, unsigned size) +{ + BOOL ret = True; + void *tp; + + tp = (void *)Realloc(*ptr, size); + if (tp) *ptr = tp; + else ret = False; + return ret; +} + diff --git a/source3/aparser/parser.h b/source3/aparser/parser.h new file mode 100644 index 0000000000..319aeb5d13 --- /dev/null +++ b/source3/aparser/parser.h @@ -0,0 +1,103 @@ +#include <ctype.h> +#include <stdio.h> +#include <malloc.h> +#include <unistd.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "../include/byteorder.h" + +#define PARSE_SCALARS (1<<0) +#define PARSE_BUFFERS (1<<1) + +#ifndef MIN +#define MIN(a,b) ((a)<(b)?(a):(b)) +#endif + +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + +#define DEBUG(lvl, str) printf str; +#define DEBUGADD(lvl, str) printf str; + +#define MARSHALL 0 +#define UNMARSHALL 1 + +#define MARSHALLING(ps) (!(ps)->io) +#define UNMARSHALLING(ps) ((ps)->io) + +typedef int BOOL; +typedef unsigned char uint8; +typedef unsigned char uchar; +typedef unsigned short uint16; +typedef unsigned short wchar; +typedef unsigned uint32; +typedef char *SMBSTR; + +/* a null terminated unicode string */ +typedef uint16 ZUSTRING; + +#ifndef _PSTRING + +#define PSTRING_LEN 1024 +#define FSTRING_LEN 128 + +typedef char pstring[PSTRING_LEN]; +typedef char fstring[FSTRING_LEN]; + +#define _PSTRING + +#endif +#define False 0 +#define True 1 + +/* zero a structure given a pointer to the structure */ +#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) + +#define MAX_UNISTRLEN 256 +#define MAX_STRINGLEN 256 +#define MAX_BUFFERLEN 512 + +typedef struct _io_struct +{ + BOOL io; /* parsing in or out of data stream */ + /* + * If the (incoming) data is big-endian. On output we are + * always little-endian. + */ + BOOL bigendian_data; + BOOL is_dynamic; /* Do we own this memory or not ? */ + BOOL autoalign; /* should we auto-align all elements? */ + uint32 data_offset; /* Current working offset into data. */ + uint32 buffer_size; /* Current size of the buffer. */ + uint32 grow_size; /* size requested via io_grow() calls */ + char *data_p; /* The buffer itself. */ +} io_struct; + + +char *io_mem_get(io_struct *ps, uint32 extra_size); +BOOL io_init(io_struct *ps, uint32 size, BOOL io); +void io_debug(io_struct *ps, int depth, char *desc, char *fn_name); +BOOL io_align(io_struct *ps, int align); +BOOL io_align4(io_struct *ps, int align); +BOOL io_align2(io_struct *ps, int align); +BOOL io_read(io_struct *ps, int fd, size_t len, int timeout); +void dump_data(int level,char *buf1,int len); +BOOL io_alloc(char *name, io_struct *ps, void **ptr, unsigned size); +BOOL io_uint32(char *name, io_struct *ps, int depth, uint32 *data32, unsigned flags); +BOOL io_uint16(char *name, io_struct *ps, int depth, uint16 *data16, unsigned flags); +BOOL io_uint8(char *name, io_struct *ps, int depth, uint8 *data8, unsigned flags); +BOOL io_pointer(char *desc, io_struct *ps, int depth, void **p, unsigned flags); +BOOL io_SMBSTR(char *name, io_struct *ps, int depth, char **str, unsigned flags); +BOOL io_io_struct(char *name, io_struct *ps, int depth, io_struct *io, unsigned flags); +BOOL io_wstring(char *name, io_struct *ps, int depth, uint16 *data16s, int len, unsigned flags); +BOOL io_uint8s_fixed(char *name, io_struct *ps, int depth, uint8 *data8s, int len, unsigned flags); +BOOL io_uint8s(char *name, io_struct *ps, int depth, uint8 **data8s, int len, unsigned flags); + +char *tab_depth(int depth); +void *Realloc(void *p,size_t size); +void dump_data(int level,char *buf1,int len); +void print_asc(int level, uchar const *buf, int len); +BOOL io_ZUSTRING(char *name, io_struct *ps, int depth, uint16 **ustr, unsigned flags); +size_t strlen_w(void *src); + diff --git a/source3/aparser/parserel.awk b/source3/aparser/parserel.awk new file mode 100644 index 0000000000..6d80f0607e --- /dev/null +++ b/source3/aparser/parserel.awk @@ -0,0 +1,213 @@ +# build parse functions for a parsed struct file + +function elem_name(v, elem) +{ + return v["UNION"]elem; +} + +function parse_array(f, v, elnum, flags, + LOCAL, type, elem, array_len) +{ + type = elements[elnum, "type"]; + elem = elements[elnum, "elem"]; + array_len = elements[elnum, "array_len"]; + v["ELEM"] = elem_name(v, elem); + v["TYPE"] = type; + v["FLAGS"] = flags; + v["ARRAY_LEN"] = array_len; + + if (array_len=="+") { + print_template(f,"prs_array_optional.tpl", v); + return; + } + + if (array_len=="&") { + print_template(f,"prs_array_null.tpl", v); + return; + } + + if (array_len=="*") { + print_template(f,"prs_array_remainder.tpl", v); + return; + } + + if (type == "wchar" || type == "uint16") { + if (match(array_len,"[0-9]") == 1) { + print_template(f, "prs_wstring_fixed.tpl", v); + } else { + print_template(f, "prs_wstring.tpl", v); + } + } else if (type == "uint8") { + if (match(array_len,"[0-9]") == 1) { + print_template(f, "prs_uint8s_fixed.tpl", v); + } else { + print_template(f, "prs_uint8s.tpl", v); + } + } else { + print_template(f, "prs_array.tpl", v); + } +} + + +function parse_element(f, v, elnum, flags, + LOCAL, type, elem) +{ + if (elements[elnum,"nowire"] != "") { + return; + } + type = elements[elnum, "type"]; + if (substr(type,1,1) == ".") return; + elem = elements[elnum, "elem"]; + if (elements[elnum,"ptr"] == "") { + v["PTR"] = "\\&"; + } else { + v["PTR"] = " "; + } + v["ELEM"] = elem_name(v, elem); + v["TYPE"] = type; + v["FLAGS"] = flags; + print_template(f, "prs_element.tpl", v); +} + +function parse_union(f, v, elnum, flags, + LOCAL, i) +{ + v["UNION"] = elements[elnum, "elem"]; + v["SWITCH"] = elements[elnum, "switch"]; + + if (elements[elnum, "ptr"] == "1") { + v["UNION"] = v["UNION"]"->"; + } else { + v["UNION"] = v["UNION"]"."; + } + + print_template(f, "union_start.tpl", v); + for (i=0;i<unions[elnum, "num_elems"];i++) { + v["CASE"] = elements[unions[elnum, i], "case"]; + print_template(f, "prs_case.tpl", v); + if (elements[elnum, "ptr"] == "1") { + parse_scalars(f, v, unions[elnum, i], "PARSE_SCALARS"); + parse_buffers(f, v, unions[elnum, i], "PARSE_BUFFERS"); + } else { + if (flags == "PARSE_SCALARS") { + parse_scalars(f, v, unions[elnum, i], flags); + } else { + parse_buffers(f, v, unions[elnum, i], flags); + } + } + print_template(f, "prs_break.tpl", v); + } + v["UNION"] = ""; + + print_template(f, "union_end.tpl", v); +} + +function parse_scalar(f, v, elnum, flags) +{ + if (elements[elnum, "type"] == "union") { + parse_union(f, v, elnum, flags); + } else if (elements[elnum, "array_len"]!="") { + parse_array(f, v, elnum, flags); + } else { + parse_element(f, v, elnum, flags); + } +} + +function parse_pointer(f, v, elnum, flags, + LOCAL, elem) +{ + elem = elements[elnum, "elem"]; + v["ELEM"] = elem_name(v, elem); + v["FLAGS"] = flags; + print_template(f, "prs_pointer.tpl", v); +} + +function parse_scalars(f, v, elnum, flags) +{ + if (elements[elnum, "ptr"] == "1") { + parse_pointer(f, v, elnum, flags); + } else { + parse_scalar(f, v, elnum, flags); + } +} + +function parse_buffers(f, v, elnum, flags, + LOCAL, elem, type) +{ + elem = elements[elnum, "elem"]; + type = elements[elnum, "type"]; + v["ELEM"] = elem_name(v, elem); + if (elements[elnum, "ptr"] == "1") { + print_template(f, "ifptr_start.tpl", v); + parse_scalar(f, v, elnum, "PARSE_SCALARS|PARSE_BUFFERS"); + print_template(f, "ifptr_end.tpl", v); + } else { + parse_scalar(f, v, elnum, flags); + } +} + +function struct_immediate(f, v, struct_num, + LOCAL, i, n1, num_elems) +{ + num_elems = structs[struct_num, "num_elems"]; + v["STRUCTNAME"] = structs[struct_num, "name"]; + v["FUNCNAME"] = "io_" v["STRUCTNAME"]; + + print_template(f, "fn_i_start.tpl", v); + + for (i=0;i<num_elems;i++) { + parse_scalars(f, v, structs[struct_num, i], "PARSE_SCALARS"); + parse_buffers(f, v, structs[struct_num, i], "PARSE_BUFFERS"); + } + + print_template(f, "fn_i_end.tpl", v); +} + + +function struct_recursive(f, v, struct_num, + LOCAL, i, n1, num_elems) +{ + num_elems = structs[struct_num, "num_elems"]; + v["STRUCTNAME"] = structs[struct_num, "name"]; + v["FUNCNAME"] = "io_" v["STRUCTNAME"]; + + print_template(f, "fn_start.tpl", v); + +# first all the structure pointers, scalars and arrays + for (i=0;i<num_elems;i++) { + parse_scalars(f, v, structs[struct_num, i], "PARSE_SCALARS"); + } + + print_template(f, "fn_mid.tpl", v); + +# now the buffers + for (i=0;i<num_elems;i++) { + parse_buffers(f, v, structs[struct_num, i], "PARSE_BUFFERS"); + } + + print_template(f, "fn_end.tpl", v); +} + +function struct_parser(f, v, struct_num, + LOCAL, i, n1, num_elems) +{ + if (structs[struct_num, "recurse"] == "True") { + struct_recursive(f, v, struct_num); + } else { + struct_immediate(f, v, struct_num); + } +} + +function produce_relative(f, + LOCAL, v, i) +{ + v["MODULE"]=module; + + print_template(f, "module_start.tpl", v); + + for (i=0;i < num_structs;i++) { + struct_parser(f, v, i); + } + + print_template(f, "module_end.tpl", v); +} diff --git a/source3/aparser/parsetree.awk b/source3/aparser/parsetree.awk new file mode 100644 index 0000000000..80587a0111 --- /dev/null +++ b/source3/aparser/parsetree.awk @@ -0,0 +1,224 @@ +# build the parse tree for a struct file + +function find_structure(name, + LOCAL, i) +{ + for (i=0;i<num_structs;i++) { + if (structs[i, "name"] == name) return i; + } + return "-1"; +} + +function start_module(name) +{ + module=name; + num_structs=0; + num_elements=0; + num_unions=0; + num_tests=0; + num_options=0; +} + +function set_option(name, value) +{ + options[name] = value; + options[num_options, "name"] = name; + options[num_options, "value"] = value; + num_options++; +} + +function parse_define(def1, def2, + LOCAL, type, i) +{ + defines[def1]=def2; +} + +function start_struct(name) +{ + current_struct=num_structs; + structs[name]=current_struct; + structs[current_struct, "name"]=name; + structs[current_struct, "num_elems"]=0; + structs[current_struct, "num_unions"]=0; + structs[current_struct, "recurse"] = options["recurse"]; +} + +function end_struct(name) +{ + if (name!="") structs[num_structs, "name"]=name; + printf("struct %s with %d elements\n", + structs[num_structs, "name"], + structs[num_structs, "num_elems"]); + num_structs++; + current_struct=""; +} + +function add_element(type, elem, case, + LOCAL, elem_num, i, v) +{ + while (defines[type]!="") { + type=defines[type]; + } + elem_num=num_elements; + + if (substr(elem, 1, 1) == ".") { + elem=substr(elem, 2); + elements[elem_num, "nowire"]=1; + } + + if (substr(elem, 1, 1) == "*") { + elem=substr(elem, 2); + elements[elem_num, "ptr"]=1; + } + + i=match(elem,"[[]"); + if (i != 0) { + v = substr(elem, i+1, length(elem)-i-1); + elem=substr(elem, 1, i-1); + if (type=="union") { + elements[elem_num, "switch"] = v; + } else { + elements[elem_num, "array_len"] = v; + } + } + + elements[elem_num, "type"] = type; + elements[elem_num, "elem"] = elem; + elements[elem_num, "case"] = case; + + num_elements++; + return elem_num; +} + +function add_struct_elem(type, elem, case, + LOCAL, elem_num) +{ + elem_num=structs[current_struct, "num_elems"]; + structs[current_struct, elem_num] = add_element(type, elem, case); + structs[current_struct, "num_elems"]++; + return structs[current_struct, elem_num]; +} + +function start_union(elem) +{ + current_union = add_struct_elem("union", elem); + unions[current_union, "num_elems"] = 0; +} + +function start_union_notencap(switch) +{ + add_struct_elem("uint32", "switch_"switch); + start_union("UNKNOWN[switch_"switch"]"); +} + +function start_union_encap(struct, type, switch, union) +{ + start_struct(struct); + add_struct_elem(type, switch); + add_struct_elem(type, "switch_"switch); + start_union(union"[switch_"switch"]"); + encap_union="1"; +} + +function parse_case(case, type, elem, + LOCAL, elem_num) +{ + split(case, a, "[:]"); + case = a[1]; + elem_num = unions[current_union, "num_elems"]; + unions[current_union, elem_num] = add_element(type, elem, case); + unions[current_union, "num_elems"]++; +} + +function end_union(name) +{ + if (name!="") { + elements[current_union, "elem"] = name; + } + current_union=""; + if (encap_union=="1") { + end_struct(name); + encap_union="0"; + } +} + +function delete_element(struct, elnum, + LOCAL, i) +{ + for (i=elnum;i<structs[struct,"num_elems"]-1;i++) { + structs[struct, i] = structs[struct, i+1]; + } + structs[struct, "num_elems"]--; +} + +function copy_struct(from, to, + LOCAL, i) +{ + for (i=0;i<structs[from,"num_elems"];i++) { + structs[to, i] = structs[from, i]; + } + structs[to, "name"] = structs[from, "name"]; + structs[to, "num_elems"] = structs[from, "num_elems"]; + structs[to, "num_unions"] = structs[from, "num_unions"]; +} + +function add_sizeis_array(count, type, elem) +{ + copy_struct(current_struct, current_struct+1); + elem=substr(elem,2); + start_struct("array_"current_struct"_"elem); + add_struct_elem("uint32", count); + add_struct_elem(type, elem"["count"]"); + end_struct(""); + current_struct=num_structs; + add_struct_elem("array_"current_struct-1"_"elem, "*"elem"_ptr"); +} + + +function start_function(type, fname) +{ + start_struct(fname); + structs[current_struct, "recurse"] = "False"; +} + +function end_function(LOCAL, i) +{ + copy_struct(num_structs, num_structs+1); + structs[num_structs, "name"] = "Q_"structs[num_structs, "name"]; + for (i=0;i<structs[num_structs, "num_elems"];i++) { + if (match(elements[structs[num_structs, i], "properties"], "in") == 0) { + delete_element(num_structs, i); + i--; + } + } + end_struct(); + current_struct=num_structs; + structs[num_structs, "name"] = "R_"structs[num_structs, "name"]; + for (i=0;i<structs[num_structs, "num_elems"];i++) { + if (match(elements[structs[num_structs, i], "properties"], "out") == 0) { + delete_element(num_structs, i); + i--; + } + } + if (return_result!="void") + add_function_param("[out]", return_result, "status"); + end_struct(); +} + +function add_function_param(properties, type, elem, + LOCAL, elnum, len) +{ + len=length(type); + if (substr(type, len) == "*") { + type=substr(type, 1, len-1); + elem="*"elem; + } + if (substr(elem,1,1) == "*" && + (match(properties,"in") == 0 || + find_structure(type) != "-1")) { + elem=substr(elem, 2); + } + elnum = add_struct_elem(type, elem); + elements[elnum, "properties"] = properties; +} + diff --git a/source3/aparser/spool.struct b/source3/aparser/spool.struct new file mode 100644 index 0000000000..1563ba5be0 --- /dev/null +++ b/source3/aparser/spool.struct @@ -0,0 +1,90 @@ +module spool + +struct BUFFER5 { + uint32 buf_len; + uint16 buffer[buf_len]; +}; + +struct BUFFERP { + uint32 buf_len; + BUFFER5 *buf; +}; + +struct UNISTR2 { + uint32 max_len; + uint32 undoc; + uint32 str_len; + uint16 buffer[str_len]; +}; + +struct LPWSTR { + UNISTR2 *str; +}; + +struct VERSION { + uint32 version; + uint32 build; + uint32 osversion; +}; + +struct NTTIME { + uint32 low; + uint32 high; +}; + +struct DWORD { + uint32 x; +}; + +struct PRINTER_DRIVER_INFO_LEVEL_3 { + DWORD cversion; + LPWSTR name; + LPWSTR environment; + LPWSTR driverpath; + LPWSTR datafile; + LPWSTR configfile; + LPWSTR helpfile; + LPWSTR monitorname; + LPWSTR defaultdatatype; + BUFFERP dependentfiles; +}; + +struct PRINTER_DRIVER_INFO_LEVEL_6 { + DWORD dummy1; + DWORD version; + LPWSTR name; + LPWSTR environment; + LPWSTR driverpath; + LPWSTR datafile; + LPWSTR configfile; + LPWSTR helpfile; + LPWSTR monitorname; + LPWSTR defaultdatatype; + BUFFERP dependentfiles; + BUFFERP previousnames; + NTTIME driverdate; + VERSION driverversion; + LPWSTR mfgname; + LPWSTR oemurl; + LPWSTR hardwareid; + LPWSTR provider; +}; + + +struct PRINTER_DRIVER_INFO { + uint32 level; + union *info[level] { + case 3 PRINTER_DRIVER_INFO_LEVEL_3 info_3; + case 6 PRINTER_DRIVER_INFO_LEVEL_6 info_6; + } +}; + + +struct R_GETPRINTERDATA { + uint32 type; + uint32 size; + uint8 *data; + uint32 needed; + uint32 status; +}; + diff --git a/source3/aparser/spool_io_printer_driver_info_level_3.prs b/source3/aparser/spool_io_printer_driver_info_level_3.prs Binary files differnew file mode 100644 index 0000000000..baa32ef7c7 --- /dev/null +++ b/source3/aparser/spool_io_printer_driver_info_level_3.prs diff --git a/source3/aparser/spool_io_printer_driver_info_level_6.prs b/source3/aparser/spool_io_printer_driver_info_level_6.prs Binary files differnew file mode 100644 index 0000000000..3c5a47e7a3 --- /dev/null +++ b/source3/aparser/spool_io_printer_driver_info_level_6.prs diff --git a/source3/aparser/srvsvc.struct b/source3/aparser/srvsvc.struct new file mode 100644 index 0000000000..aa40c8f15e --- /dev/null +++ b/source3/aparser/srvsvc.struct @@ -0,0 +1,184 @@ +module srvsvc + +typedef uint32 LONG; +typedef uint32 *ENUM_HND; + +typedef struct _UNISTR2 { + uint32 max_len; + uint32 undoc; + uint32 str_len; + wchar buffer[str_len]; +} UNISTR2; + +typedef UNISTR2 *LPWSTR; + +/* function 8 */ +struct CONN_INFO_0 { + uint32 id; /* connection id. */ +}; + +struct CONN_INFO_1 { + uint32 id; + uint32 type; + uint32 num_opens; + uint32 num_users; + uint32 open_time; + LPWSTR usr_name; + LPWSTR net_name; +}; + +struct CONN_ENUM_CTR { + uint32 level; + uint32 level2; + uint32 num_entries; + uint32 num_entries2; + union *info[level] { + case 0 CONN_INFO_0 info0[num_entries]; + case 1 CONN_INFO_1 info1[num_entries]; + } +}; + +struct SRV_R_NET_CONN_ENUM { + .trailer; + CONN_ENUM_CTR ctr; + uint32 num_entries; + ENUM_HND handle; + uint32 status2; +}; + +struct SRV_Q_NET_CONN_ENUM { + .trailer; + LPWSTR dest_srv; + LPWSTR qual_srv; + uint32 level; + uint32 level2; + CONN_ENUM_CTR *ctr; + uint32 max_len; + ENUM_HND handle; +}; + +/* function 9 */ +struct FILE_INFO_3 { + uint32 id; /* file index */ + uint32 perms; /* file permissions. don't know what format */ + uint32 num_locks; /* file locks */ + LPWSTR path_name; /* file name */ + LPWSTR user_name; /* file owner */ +}; + +struct SRV_FILE_INFO_CTR { + uint32 level; + uint32 num_entries; + uint32 dummy; + union *file[level] { + case 3 FILE_INFO_3 info3[num_entries]; + } +}; + +struct SRV_Q_NET_FILE_ENUM { + .trailer; + LPWSTR srv_name; + LPWSTR qual_name; + uint32 dummy; + uint32 level; + SRV_FILE_INFO_CTR ctr; + uint32 *status; + uint32 preferred_len; + ENUM_HND enum_hnd; +}; + + +struct SRV_R_NET_FILE_ENUM { + .trailer; + uint32 level; + uint32 dummy; + SRV_FILE_INFO_CTR *ctr; + uint32 total_entries; /* total number of files */ + ENUM_HND enum_hnd; + uint32 status; /* return status */ +}; + + +/* function 15 */ +struct SRV_SHARE_INFO_1 { + LPWSTR uni_netname; + uint32 type; + LPWSTR uni_remark; +}; + +struct SRV_SHARE_INFO_2 { + LPWSTR uni_netname; + uint32 type; + LPWSTR uni_remark; + uint32 perms; + uint32 max_uses; + uint32 num_uses; + LPWSTR path; + LPWSTR passwd; +}; + +struct SRV_R_NET_SHARE_ENUM { + uint32 level; + uint32 level2; + uint32 *ret_count; + uint32 num_entries; + union *info[level] { + case 1 SRV_SHARE_INFO_1 info1[num_entries]; + case 2 SRV_SHARE_INFO_2 info2[num_entries]; + } + .trailer; + uint32 count; + ENUM_HND handle; + uint32 status; +}; + + + +/* function 21 */ +struct SERVER_INFO_100 { + uint32 dwPlatformID; + LPWSTR pszName; +}; + +struct SERVER_INFO_101 { + uint32 dwPlatformID; + LPWSTR pszName; + uint32 dwVerMajor; + uint32 dwVerMinor; + uint32 dwType; + LPWSTR pszComment; +}; + +struct SERVER_INFO_102 { + uint32 dwPlatformID; + LPWSTR pszName; + uint32 dwVerMajor; + uint32 dwVerMinor; + uint32 dwType; + LPWSTR pszComment; + uint32 dwUsers; + uint32 lDisc; + uint32 bHidden; + uint32 dwAnnounce; + uint32 dwAnnDelta; + uint32 dwLicenses; + LPWSTR pszUserPath; +}; + +struct SRV_R_NET_SERVER_INFO { + .trailer; + uint32 level; + union *info[level] { + case 100 SERVER_INFO_100 sv100; + case 101 SERVER_INFO_101 sv101; + case 102 SERVER_INFO_102 sv102; + } + uint32 status; +}; + +struct SRV_Q_NET_SERVER_INFO { + .trailer; + LPWSTR server; + uint32 level; +}; + diff --git a/source3/aparser/srvsvc2.struct b/source3/aparser/srvsvc2.struct new file mode 100644 index 0000000000..362d121e37 --- /dev/null +++ b/source3/aparser/srvsvc2.struct @@ -0,0 +1,655 @@ +module srvsvc + +option autoalign True +option relative False +option recurse True +option foo blah + +#define BOOL uint32 +#define LONG uint32 +#define DWORD uint32 +#define STATUS uint32 + +typedef struct _UNISTR2 { + uint32 max_len; + uint32 undoc; + uint32 str_len; + wchar buffer[str_len]; +} UNISTR2; + +struct LPWSTR { + UNISTR2 *str; +}; + + + + /* -- CHARACTER DEVICE INFORMATION -- */ + + typedef struct _CHARDEV_INFO_0 { + LPWSTR pszName; + } CHARDEV_INFO_0; + + typedef struct _CHARDEV_INFO_1 { + LPWSTR pszName; + DWORD dwStatus; + LPWSTR pszUser; + DWORD dwTime; + } CHARDEV_INFO_1; + + typedef union _CHARDEV_INFO switch (DWORD dwLevel) ctr { + case 1: CHARDEV_INFO_0 *ci0; + case 2: CHARDEV_INFO_1 *ci1; + } CHARDEV_INFO; + + typedef struct _CHARDEV_ENUM_0 { + DWORD dwEntries; + [size_is(dwEntries)] CHARDEV_INFO_0 *ci0; + } CHARDEV_ENUM_0; + + typedef struct _CHARDEV_ENUM_1 { + DWORD dwEntries; + [size_is(dwEntries)] CHARDEV_INFO_1 *ci1; + } CHARDEV_ENUM_1; + + typedef struct _CHARDEV_ENUM { + DWORD dwLevel; + [switch_is(dwLevel)] union { + [case(0)] CHARDEV_ENUM_0 *ce0; + [case(1)] CHARDEV_ENUM_1 *ce1; + } ctr; + } CHARDEV_ENUM; + + STATUS NetrCharDevEnum( /* Function 0x00 */ + [in,unique] LPWSTR pszServer, + [in,out] CHARDEV_ENUM* pCharDevEnum, + [in] DWORD dwMaxLen, + [out] DWORD* dwEntries, + [in,out] DWORD* hResume + ); + + STATUS NetrCharDevGetInfo( /* Function 0x01 */ + [in,unique] LPWSTR pszServer, + [in,ref] LPWSTR pszDevice, + [in] DWORD dwLevel, + [out] CHARDEV_INFO* pCharDevInfo + ); + + STATUS NetrCharDevControl( /* Function 0x02 */ + [in,unique] LPWSTR pszServer, + [in,ref] LPWSTR pszDevice, + [in] DWORD dwOpcode + ); + + /* -- CHARACTER DEVICE QUEUE INFORMATION -- */ + + typedef struct _CHARDEVQ_INFO_0 { + LPWSTR pszName; + } CHARDEVQ_INFO_0; + + typedef struct _CHARDEVQ_INFO_1 { + LPWSTR pszName; + DWORD dwPriority; + LPWSTR pszDevices; + DWORD dwNumUsers; + DWORD dwNumAhead; + } CHARDEVQ_INFO_1; + + typedef union _CHARDEVQ_INFO switch (DWORD dwLevel) ctr { + case 1: CHARDEVQ_INFO_0 *ci0; + case 2: CHARDEVQ_INFO_1 *ci1; + } CHARDEVQ_INFO; + + typedef struct _CHARDEVQ_ENUM_0 { + DWORD dwEntries; + [size_is(dwEntries)] CHARDEVQ_INFO_0 *ci0; + } CHARDEVQ_ENUM_0; + + typedef struct _CHARDEVQ_ENUM_1 { + DWORD dwEntries; + [size_is(dwEntries)] CHARDEVQ_INFO_1 *ci1; + } CHARDEVQ_ENUM_1; + + typedef struct _CHARDEVQ_ENUM { + DWORD dwLevel; + [switch_is(dwLevel)] union { + [case(0)] CHARDEVQ_ENUM_0 *ce0; + [case(1)] CHARDEVQ_ENUM_1 *ce1; + } ctr; + } CHARDEVQ_ENUM; + + STATUS NetrCharDevQEnum( /* Function 0x03 */ + [in,unique] LPWSTR pszServer, + [in,unique] LPWSTR pszUser, + [in,out] CHARDEVQ_ENUM* pCharDevQEnum, + [in] DWORD dwMaxLen, + [out] DWORD* dwEntries, + [in,out] DWORD* hResume + ); + + STATUS NetrCharDevQGetInfo( /* Function 0x04 */ + [in,unique] LPWSTR pszServer, + [in,ref] LPWSTR pszQueue, + [in,ref] LPWSTR pszUser, + [in] DWORD dwLevel, + [out] CHARDEVQ_INFO* pCharDevQInfo + ); + + STATUS NetrCharDevQSetInfo( /* Function 0x05 */ + [in,unique] LPWSTR pszServer, + [in,ref] LPWSTR pszQueue, + [in] DWORD dwLevel, + [in] CHARDEVQ_INFO* pCharDevQInfo, + [in,out] DWORD* dwParmError + ); + + STATUS NetrCharDevQPurge( /* Function 0x06 */ + [in,unique] LPWSTR pszServer, + [in,ref] LPWSTR pszQueue + ); + + STATUS NetrCharDevQPurgeSelf( /* Function 0x07 */ + [in,unique] LPWSTR pszServer, + [in,ref] LPWSTR pszQueue, + [in,ref] LPWSTR pszComputer + ); + + /* -- CONNECTION INFORMATION -- */ + + typedef struct _CONNECTION_INFO_0 { + DWORD dwConnID; + } CONNECTION_INFO_0; + + typedef struct _CONNECTION_INFO_1 { + DWORD dwConnID; + DWORD dwType; + DWORD dwNumOpens; + DWORD dwNumUsers; + DWORD dwTime; + LPWSTR pszUser; + LPWSTR pszShare; + } CONNECTION_INFO_1; + + typedef struct _CONNECTION_ENUM_0 { + DWORD dwEntries; + [size_is(dwEntries)] CONNECTION_INFO_0 *ci0; + } CONNECTION_ENUM_0; + + typedef struct _CONNECTION_ENUM_1 { + DWORD dwEntries; + [size_is(dwEntries)] CONNECTION_INFO_1 *ci1; + } CONNECTION_ENUM_1; + + typedef struct _CONNECTION_ENUM { + DWORD dwLevel; + [switch_is(dwLevel)] union { + [case(0)] CONNECTION_ENUM_0 *ce0; + [case(1)] CONNECTION_ENUM_1 *ce1; + } ctr; + } CONNECTION_ENUM; + + STATUS NetrConnectionEnum( /* Function 0x08 */ + [in,unique] LPWSTR pszServer, + [in,unique] LPWSTR pszClient, + [in,out] CONNECTION_ENUM* pConnectionEnum, + [in] DWORD dwMaxLen, + [out] DWORD* dwEntries, + [in,out] DWORD* hResume + ); + + /* -- FILE INFORMATION -- */ + + typedef struct _FILE_INFO_2 { + DWORD dwFileID; + } FILE_INFO_2; + + typedef struct _FILE_INFO_3 { + DWORD dwFileID; + DWORD dwPermissions; + DWORD dwNumLocks; + LPWSTR pszPath; + LPWSTR pszUser; + } FILE_INFO_3; + + typedef union _FILE_INFO switch (DWORD dwLevel) ctr { + case 2: FILE_INFO_2 *fi2; + case 3: FILE_INFO_3 *fi3; + } FILE_INFO; + + typedef struct _FILE_ENUM_2 { + DWORD dwEntries; + [size_is(dwEntries)] FILE_INFO_2 *fi2; + } FILE_ENUM_2; + + typedef struct _FILE_ENUM_3 { + DWORD dwEntries; + [size_is(dwEntries)] FILE_INFO_3 *fi3; + } FILE_ENUM_3; + + typedef struct _FILE_ENUM { + DWORD dwLevel; + [switch_is(dwLevel)] union { + [case(2)] FILE_ENUM_2 *fe2; + [case(3)] FILE_ENUM_3 *fe3; + } ctr; + } FILE_ENUM; + + STATUS NetrFileEnum( /* Function 0x09 */ + [in,unique] LPWSTR pszServer, + [in,unique] LPWSTR pszBasePath, + [in,unique] LPWSTR pszUser, + [in,out] FILE_ENUM* pFileEnum, + [in] DWORD dwMaxLen, + [out] DWORD* dwEntries, + [in,out] DWORD* hResume + ); + + STATUS NetrFileGetInfo( /* Function 0x0A */ + [in,unique] LPWSTR pszServer, + [in] DWORD dwFileID, + [in] DWORD dwLevel, + [out] FILE_INFO* pFileInfo + ); + + STATUS NetrFileClose( /* Function 0x0B */ + [in,unique] LPWSTR pszServer, + [in] DWORD dwFileID + ); + + /* -- SESSION INFORMATION -- */ + + typedef struct _SESSION_INFO_0 { + LPWSTR pszClient; + } SESSION_INFO_0; + + typedef struct _SESSION_INFO_1 { + LPWSTR pszClient; + LPWSTR pszUser; + DWORD dwOpens; + DWORD dwTime; + DWORD dwIdleTime; + DWORD dwUserFlags; + } SESSION_INFO_1; + + typedef struct _SESSION_INFO_2 { + LPWSTR pszClient; + LPWSTR pszUser; + DWORD dwOpens; + DWORD dwTime; + DWORD dwIdleTime; + DWORD dwUserFlags; + LPWSTR pszClientType; + } SESSION_INFO_2; + + typedef struct _SESSION_ENUM_0 { + DWORD dwEntries; + [size_is(dwEntries)] SESSION_INFO_0 *si0; + } SESSION_ENUM_0; + + typedef struct _SESSION_ENUM_1 { + DWORD dwEntries; + [size_is(dwEntries)] SESSION_INFO_1 *si1; + } SESSION_ENUM_1; + + typedef struct _SESSION_ENUM_2 { + DWORD dwEntries; + [size_is(dwEntries)] SESSION_INFO_2 *si2; + } SESSION_ENUM_2; + + typedef struct _SESSION_ENUM { + DWORD dwLevel; + [switch_is(dwLevel)] union { + [case(0)] SESSION_ENUM_0 *se0; + [case(1)] SESSION_ENUM_1 *se1; + [case(2)] SESSION_ENUM_2 *se2; + } ctr; + } SESSION_ENUM; + + STATUS NetrSessionEnum( /* Function 0x0C */ + [in,unique] LPWSTR pszServer, + [in,unique] LPWSTR pszClient, + [in,unique] LPWSTR pszUser, + [in,out] SESSION_ENUM* pFileEnum, + [in] DWORD dwMaxLen, + [out] DWORD* dwEntries, + [in,out] DWORD* hResume + ); + + STATUS NetrSessionDel( /* Function 0x0D */ + [in,unique] LPWSTR pszServer, + [in,ref] LPWSTR pszClient, + [in,ref] LPWSTR pszUser + ); + + /* -- SHARE INFORMATION -- */ + + typedef struct _SHARE_INFO_0 { + LPWSTR pszName; + } SHARE_INFO_0; + + typedef struct _SHARE_INFO_1 { + LPWSTR pszName; + DWORD dwType; + LPWSTR pszComment; + } SHARE_INFO_1; + + typedef struct _SHARE_INFO_2 { + LPWSTR pszName; + DWORD dwType; + LPWSTR pszComment; + DWORD dwPermissions; + DWORD dwMaxUses; + DWORD dwCurrentUses; + LPWSTR pszPath; + LPWSTR pszPasswd; + } SHARE_INFO_2; + + typedef union _SHARE_INFO switch (DWORD dwLevel) ctr { + case 0: SHARE_INFO_0 *si0; + case 1: SHARE_INFO_1 *si1; + case 2: SHARE_INFO_2 *si2; + } SHARE_INFO; + + typedef struct _SHARE_ENUM_0 { + DWORD dwEntries; + [size_is(dwEntries)] SHARE_INFO_0 *si0; + } SHARE_ENUM_0; + + typedef struct _SHARE_ENUM_1 { + DWORD dwEntries; + [size_is(dwEntries)] SHARE_INFO_1 *si1; + } SHARE_ENUM_1; + + typedef struct _SHARE_ENUM_2 { + DWORD dwEntries; + [size_is(dwEntries)] SHARE_INFO_2 *si2; + } SHARE_ENUM_2; + + typedef struct _SHARE_ENUM { + DWORD dwLevel; + [switch_is(dwLevel)] union { + [case(0)] SHARE_ENUM_0 *se0; + [case(1)] SHARE_ENUM_1 *se1; + [case(2)] SHARE_ENUM_2 *se2; + } ctr; + } SHARE_ENUM; + + STATUS NetrShareAdd( /* Function 0x0E */ + [in,unique] LPWSTR pszServer, + [in] DWORD dwLevel, + [out] SHARE_INFO* pShareInfo, + [in,out] DWORD* dwParmError + ); + + STATUS NetrShareEnum( /* Function 0x0F */ + [in,unique] LPWSTR pszServer, + [in,out] SHARE_ENUM* pShareEnum, + [in] DWORD dwMaxLen, + [out] DWORD* dwEntries, + [in,out] DWORD* hResume + ); + + STATUS NetrShareGetInfo( /* Function 0x10 */ + [in,unique] LPWSTR pszServer, + [in,ref] LPWSTR pszShare, + [in] DWORD dwLevel, + [out] SHARE_INFO* pShareInfo + ); + + STATUS NetrShareSetInfo( /* Function 0x11 */ + [in,unique] LPWSTR pszServer, + [in,ref] LPWSTR pszShare, + [in] DWORD dwLevel, + [in] SHARE_INFO* pShareInfo, + [in] DWORD dwReserved + ); + + STATUS NetrShareDel( /* Function 0x12 */ + [in,unique] LPWSTR pszServer, + [in,ref] LPWSTR pszShare, + [in] DWORD dwReserved + ); + + STATUS NetrShareDelSticky( /* Function 0x13 */ + [in,unique] LPWSTR pszServer, + [in,ref] LPWSTR pszShare, + [in] DWORD dwReserved + ); + + STATUS NetrShareCheck( /* Function 0x14 */ + [in,unique] LPWSTR pszServer, + [in,ref] LPWSTR pszDevice, + [out] DWORD* dwType + ); + + /* --- SERVER INFORMATION --- */ + + typedef struct _SERVER_INFO_100 { + DWORD dwPlatformID; + LPWSTR pszName; + } SERVER_INFO_100; + + typedef struct _SERVER_INFO_101 { + DWORD dwPlatformID; + LPWSTR pszName; + DWORD dwVerMajor; + DWORD dwVerMinor; + DWORD dwType; + LPWSTR pszComment; + } SERVER_INFO_101; + + typedef struct _SERVER_INFO_102 { + DWORD dwPlatformID; + LPWSTR pszName; + DWORD dwVerMajor; + DWORD dwVerMinor; + DWORD dwType; + LPWSTR pszComment; + DWORD dwUsers; + LONG lDisc; + BOOL bHidden; + DWORD dwAnnounce; + DWORD dwAnnDelta; + DWORD dwLicenses; + LPWSTR pszUserPath; + } SERVER_INFO_102; + + typedef union _SERVER_INFO switch (DWORD dwLevel) ctr { + case 100: SERVER_INFO_100 *sv100; + case 101: SERVER_INFO_101 *sv101; + case 102: SERVER_INFO_102 *sv102; + } SERVER_INFO; + + STATUS NetrServerGetInfo( /* Function 0x15 */ + [in,unique] LPWSTR pszServerName, + [in] DWORD dwLevel, + [out] SERVER_INFO* pServerInfo + ); + + STATUS NetrServerSetInfo( /* Function 0x16 */ + [in,unique] LPWSTR pszServerName, + [in] DWORD dwLevel, + [in] SERVER_INFO* pServerInfo, + [in] DWORD dwReserved + ); + + typedef struct _DISK_INFO { + LPWSTR pszName; + } DISK_INFO; + + typedef struct _DISK_ENUM { + DWORD dwEntries; + [size_is(dwEntries)] DISK_INFO *di; + } DISK_ENUM; + + STATUS NetrServerDiskEnum( /* Function 0x17 */ + [in,unique] LPWSTR pszServer, + [in] DWORD dwLevel, + [in,out] DISK_ENUM* pDiskEnum, + [in] DWORD dwMaxLen, + [out] DWORD* dwEntries, + [in,out] DWORD* hResume + ); + + typedef struct _STAT_SERVER { + DWORD dwStart; + DWORD dwFOpens; + DWORD dwDevOpens; + DWORD dwJobsQueued; + DWORD dwSOpens; + DWORD dwSTimedOut; + DWORD dwSErrors; + DWORD dwPWErrors; + DWORD dwPermErrors; + DWORD dwSysErrors; + DWORD dwBytesSentLow; + DWORD dwBytesSentHigh; + DWORD dwBytesRcvdLow; + DWORD dwBytesRcvdHigh; + DWORD dwAVResponse; + DWORD dwReqBufNeed; + DWORD dwBigBufNeed; + } STAT_SERVER; + + STATUS NetrServerStatisticsGet( /* Function 0x18 */ + [in,unique] LPWSTR pszServer, + [in] DWORD dwLevel, + [in] DWORD dwOptions, + [out] STAT_SERVER* pStatServer + ); + + typedef struct _TRANSPORT_INFO_0 { + LPWSTR pszName; + } TRANSPORT_INFO_0; + + typedef union _TRANSPORT_INFO switch (DWORD dwLevel) ctr { + case 0: TRANSPORT_INFO_0 *ti0; + } TRANSPORT_INFO; + + typedef struct _TRANSPORT_ENUM_0 { + DWORD dwEntries; + [size_is(dwEntries)] TRANSPORT_INFO_0 *ti0; + } TRANSPORT_ENUM_0; + + typedef struct _TRANSPORT_ENUM { + DWORD dwLevel; + [switch_is(dwLevel)] union { + [case(0)] TRANSPORT_ENUM_0 *te0; + } ctr; + } TRANSPORT_ENUM; + + STATUS NetrServerTransportAdd( /* Function 0x19 */ + [in,unique] LPWSTR pszServer, + [in] DWORD dwLevel, + [out] TRANSPORT_INFO* pTransportInfo + ); + + STATUS NetrServerTransportEnum( /* Function 0x1a */ + [in,unique] LPWSTR pszServer, + [in,out] TRANSPORT_ENUM* pTransportEnum, + [in] DWORD dwMaxLen, + [out] DWORD* dwEntries, + [in,out] DWORD* hResume + ); + + STATUS NetrServerTransportDel( /* Function 0x1b */ + [in,unique] LPWSTR pszServer, + [in] DWORD dwLevel, + [out] TRANSPORT_INFO* pTransportInfo + ); + + typedef struct _TIME_OF_DAY { + DWORD dwElapsedTime; + DWORD dwMsecs; + DWORD dwHours; + DWORD dwMins; + DWORD dwSecs; + DWORD dwHunds; + LONG lTimeZone; + DWORD dwInterval; + DWORD dwDay; + DWORD dwMonth; + DWORD dwYear; + DWORD dwWeekday; + } TIME_OF_DAY; + + STATUS NetrRemoteTOD( /* Function 0x1c */ + [in,unique] LPWSTR pszServer, + [out] TIME_OF_DAY* pTOD + ); + + STATUS NetrServerSetServiceBits( /* Function 0x1d */ + [in,unique] LPWSTR pszServer, + [in] DWORD hServiceStatus, /* ?? */ + [in] DWORD dwServiceBits, + [in] BOOL bSetBitsOn, + [in] BOOL bUpdateImmediately + ); + + /* --- PATH INFORMATION --- */ + + STATUS NetprPathType( /* Function 0x1e */ + void /* Not known */ + ); + + STATUS NetprPathCanonicalize( /* Function 0x1f */ + void /* Not known */ + ); + + STATUS NetprPathCompare( /* Function 0x20 */ + void /* Not known */ + ); + + STATUS NetprNameValidate( /* Function 0x21 */ + void /* Not known */ + ); + + STATUS NetprNameCanonicalize( /* Function 0x22 */ + void /* Not known */ + ); + + STATUS NetprNameCompare( /* Function 0x23 */ + void /* Not known */ + ); + + /* --- LATER ADDITIONS --- */ + + STATUS NetrShareEnumSticky( /* Function 0x24 */ + [in,unique] LPWSTR pszServer, + [in,out] SHARE_ENUM* pShareEnum, + [in] DWORD dwMaxLen, + [out] DWORD* dwEntries, + [in,out] DWORD* hResume + ); + + STATUS NetrShareDelStart( /* Function 0x25 */ + [in,unique] LPWSTR pszServer, + [in,ref] LPWSTR pszShare, + [in] DWORD dwReserved /* ? */ + ); + + STATUS NetrShareDelCommit( /* Function 0x26 */ + [in,unique] LPWSTR pszServer + ); + + STATUS NetrpGetFileSecurity( /* Function 0x27 */ + void /* Not known */ + ); + + STATUS NetrpSetFileSecurity( /* Function 0x28 */ + void /* Not known */ + ); + + STATUS NetrServerTransportAddEx( /* Function 0x29 */ + [in,unique] LPWSTR pszServer, + [in] DWORD dwLevel, + [out] TRANSPORT_INFO* pTransportInfo + ); + + STATUS NetrServerSetServiceBitsEx( /* Function 0x30 */ + [in,unique] LPWSTR pszServer, + [in] DWORD hServiceStatus, /* ?? */ + [in] DWORD dwServiceBits, + [in] BOOL bSetBitsOn, + [in] BOOL bUpdateImmediately + ); + diff --git a/source3/aparser/template.awk b/source3/aparser/template.awk new file mode 100644 index 0000000000..2015700835 --- /dev/null +++ b/source3/aparser/template.awk @@ -0,0 +1,18 @@ +# template file handling + +function print_template(f, tplname, v, + LOCAL, i, pat, line) +{ + tplname="templates/"tplname; + if (numlines(tplname) <= 0) fatal("no template "tplname); + while ((getline line < tplname) > 0) { + while ((i = match(line,"@[a-zA-Z_]*@")) != 0) { + pat=substr(line,i+1,RLENGTH-2); + if (v[pat] == "") fatal("no value for "pat" in "tplname); + gsub("@"pat"@", v[pat], line); + } + + xprintf(f, "%s\n", line); + } + close(tplname); +} diff --git a/source3/aparser/templates/fn_end.tpl b/source3/aparser/templates/fn_end.tpl new file mode 100644 index 0000000000..2275ec4e33 --- /dev/null +++ b/source3/aparser/templates/fn_end.tpl @@ -0,0 +1,13 @@ + +end: + /* the parse is OK */ + return True; + +fail: + if (UNMARSHALLING(ps)) { + ZERO_STRUCTP(il); + } + return False; +} /* @FUNCNAME@ */ + + diff --git a/source3/aparser/templates/fn_end0.tpl b/source3/aparser/templates/fn_end0.tpl new file mode 100644 index 0000000000..6e49a10f53 --- /dev/null +++ b/source3/aparser/templates/fn_end0.tpl @@ -0,0 +1,8 @@ + +end: + /* the parse is OK */ + return True; + +} /* @FUNCNAME@ */ + + diff --git a/source3/aparser/templates/fn_i_end.tpl b/source3/aparser/templates/fn_i_end.tpl new file mode 100644 index 0000000000..9de61decb3 --- /dev/null +++ b/source3/aparser/templates/fn_i_end.tpl @@ -0,0 +1,12 @@ + + /* the parse is OK */ + return True; + +fail: + if (UNMARSHALLING(ps)) { + ZERO_STRUCTP(il); + } + return False; +} /* @FUNCNAME@ */ + + diff --git a/source3/aparser/templates/fn_i_start.tpl b/source3/aparser/templates/fn_i_start.tpl new file mode 100644 index 0000000000..3979d78e7d --- /dev/null +++ b/source3/aparser/templates/fn_i_start.tpl @@ -0,0 +1,15 @@ +/******************************************************************* +parse a @STRUCTNAME@ structure +********************************************************************/ +BOOL @FUNCNAME@(char *desc, io_struct *ps, int depth, + @STRUCTNAME@ *il, unsigned flags) +{ + io_debug(ps, depth, desc, "@FUNCNAME@"); + depth++; + +#if 0 + if (UNMARSHALLING(ps)) { + ZERO_STRUCTP(il); + } +#endif + /* parse the scalars */ diff --git a/source3/aparser/templates/fn_mid.tpl b/source3/aparser/templates/fn_mid.tpl new file mode 100644 index 0000000000..b81de92a5b --- /dev/null +++ b/source3/aparser/templates/fn_mid.tpl @@ -0,0 +1,6 @@ + +buffers: + if (!(flags & PARSE_BUFFERS)) goto end; + + /* now parse the buffers */ + diff --git a/source3/aparser/templates/fn_start.tpl b/source3/aparser/templates/fn_start.tpl new file mode 100644 index 0000000000..a5d58767a6 --- /dev/null +++ b/source3/aparser/templates/fn_start.tpl @@ -0,0 +1,17 @@ +/******************************************************************* +parse a @STRUCTNAME@ structure +********************************************************************/ +BOOL @FUNCNAME@(char *desc, io_struct *ps, int depth, + @STRUCTNAME@ *il, unsigned flags) +{ + io_debug(ps, depth, desc, "@FUNCNAME@"); + depth++; + + if (!(flags & PARSE_SCALARS)) goto buffers; + +#if 0 + if (UNMARSHALLING(ps)) { + ZERO_STRUCTP(il); + } +#endif + /* parse the scalars */ diff --git a/source3/aparser/templates/harness.tpl b/source3/aparser/templates/harness.tpl new file mode 100644 index 0000000000..27c33c0adc --- /dev/null +++ b/source3/aparser/templates/harness.tpl @@ -0,0 +1,5 @@ + + if (strcmp(test,"@TEST@")==0) { + @TEST@ il; + ret = io_@TEST@("@TEST@", ps, 0, &il, flags); + } else diff --git a/source3/aparser/templates/harness_end.tpl b/source3/aparser/templates/harness_end.tpl new file mode 100644 index 0000000000..1e15faec16 --- /dev/null +++ b/source3/aparser/templates/harness_end.tpl @@ -0,0 +1,7 @@ + { + printf("structure %s not found\n", test); + ret = False; + } + + return ret; +} diff --git a/source3/aparser/templates/harness_start.tpl b/source3/aparser/templates/harness_start.tpl new file mode 100644 index 0000000000..beba6fc12d --- /dev/null +++ b/source3/aparser/templates/harness_start.tpl @@ -0,0 +1,7 @@ +#include "prs_@MODULE@.c" + +static BOOL run_test(char *test, io_struct *ps, int flags) +{ + BOOL ret; + + diff --git a/source3/aparser/templates/ifptr_end.tpl b/source3/aparser/templates/ifptr_end.tpl new file mode 100644 index 0000000000..990635cf45 --- /dev/null +++ b/source3/aparser/templates/ifptr_end.tpl @@ -0,0 +1 @@ + } diff --git a/source3/aparser/templates/ifptr_start.tpl b/source3/aparser/templates/ifptr_start.tpl new file mode 100644 index 0000000000..228b84bac9 --- /dev/null +++ b/source3/aparser/templates/ifptr_start.tpl @@ -0,0 +1,2 @@ + if (il->@ELEM@) { + if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@)))) goto fail; diff --git a/source3/aparser/templates/module_end.tpl b/source3/aparser/templates/module_end.tpl new file mode 100644 index 0000000000..661f7edb95 --- /dev/null +++ b/source3/aparser/templates/module_end.tpl @@ -0,0 +1,3 @@ + + +/* end auto-generated structure parsers for @MODULE@ */ diff --git a/source3/aparser/templates/module_start.tpl b/source3/aparser/templates/module_start.tpl new file mode 100644 index 0000000000..ac6a3c9d98 --- /dev/null +++ b/source3/aparser/templates/module_start.tpl @@ -0,0 +1,5 @@ +/* auto-generated structure parsers for @MODULE@ + generated by aparser +*/ +#include "prs_@MODULE@.h" + diff --git a/source3/aparser/templates/prs_.align.tpl b/source3/aparser/templates/prs_.align.tpl new file mode 100644 index 0000000000..25816a23b3 --- /dev/null +++ b/source3/aparser/templates/prs_.align.tpl @@ -0,0 +1 @@ + if(!io_align(ps)) goto fail; diff --git a/source3/aparser/templates/prs_align2.tpl b/source3/aparser/templates/prs_align2.tpl new file mode 100644 index 0000000000..54c569b547 --- /dev/null +++ b/source3/aparser/templates/prs_align2.tpl @@ -0,0 +1 @@ + if (!io_align2(ps, @OFFSET@)) goto fail; diff --git a/source3/aparser/templates/prs_align4.tpl b/source3/aparser/templates/prs_align4.tpl new file mode 100644 index 0000000000..702fab1324 --- /dev/null +++ b/source3/aparser/templates/prs_align4.tpl @@ -0,0 +1 @@ + if (!io_align4(ps, @OFFSET@)) goto fail; diff --git a/source3/aparser/templates/prs_array.tpl b/source3/aparser/templates/prs_array.tpl new file mode 100644 index 0000000000..4bd6a26c99 --- /dev/null +++ b/source3/aparser/templates/prs_array.tpl @@ -0,0 +1,8 @@ + if ((@FLAGS@ & PARSE_SCALARS) && + !io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@))*(il->@ARRAY_LEN@))) goto fail; + { + int i; + for (i=0;i<il->@ARRAY_LEN@;i++) { + if (!io_@TYPE@("@ELEM@...", ps, depth+1, &il->@ELEM@[i], @FLAGS@)) goto fail; + } + } diff --git a/source3/aparser/templates/prs_array_optional.tpl b/source3/aparser/templates/prs_array_optional.tpl new file mode 100644 index 0000000000..38bd32861f --- /dev/null +++ b/source3/aparser/templates/prs_array_optional.tpl @@ -0,0 +1,5 @@ + if ((MARSHALLING(ps) && il->@ELEM@) || + ps->data_offset < ps->buffer_size) { + if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@)))) goto fail; + if (!io_@TYPE@("@ELEM@...", ps, depth+1, il->@ELEM@, @FLAGS@)) goto fail; + } diff --git a/source3/aparser/templates/prs_array_remainder.tpl b/source3/aparser/templates/prs_array_remainder.tpl new file mode 100644 index 0000000000..c8b1e2ab5a --- /dev/null +++ b/source3/aparser/templates/prs_array_remainder.tpl @@ -0,0 +1,17 @@ + if (UNMARSHALLING(ps)) + { + int i; + for (i=0;ps->data_offset < ps->buffer_size;i++) { + if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@))*(i+1))) goto fail; + if (!io_@TYPE@("@ELEM@...", ps, depth+1, &il->@ELEM@[i], @FLAGS@)) goto fail; + } + } + else + { + int i = -1; + /* HACK ALERT! */ + do { + i++; + if (!io_@TYPE@("@ELEM@...", ps, depth+1, &il->@ELEM@[i], @FLAGS@)) goto fail; + } while (il->@ELEM@[i].tag2 != 0); + } diff --git a/source3/aparser/templates/prs_break.tpl b/source3/aparser/templates/prs_break.tpl new file mode 100644 index 0000000000..eb540f7be8 --- /dev/null +++ b/source3/aparser/templates/prs_break.tpl @@ -0,0 +1 @@ + break; diff --git a/source3/aparser/templates/prs_case.tpl b/source3/aparser/templates/prs_case.tpl new file mode 100644 index 0000000000..06c1bd3ae6 --- /dev/null +++ b/source3/aparser/templates/prs_case.tpl @@ -0,0 +1 @@ + case @CASE@: diff --git a/source3/aparser/templates/prs_case_end.tpl b/source3/aparser/templates/prs_case_end.tpl new file mode 100644 index 0000000000..eb540f7be8 --- /dev/null +++ b/source3/aparser/templates/prs_case_end.tpl @@ -0,0 +1 @@ + break; diff --git a/source3/aparser/templates/prs_element.tpl b/source3/aparser/templates/prs_element.tpl new file mode 100644 index 0000000000..e8bf5180ce --- /dev/null +++ b/source3/aparser/templates/prs_element.tpl @@ -0,0 +1 @@ + if (!io_@TYPE@("@ELEM@", ps, depth+1, @PTR@il->@ELEM@, @FLAGS@)) goto fail; diff --git a/source3/aparser/templates/prs_pointer.tpl b/source3/aparser/templates/prs_pointer.tpl new file mode 100644 index 0000000000..4ebcf19d83 --- /dev/null +++ b/source3/aparser/templates/prs_pointer.tpl @@ -0,0 +1,2 @@ + if (!io_pointer("@ELEM@_ptr", ps, depth+1, + (void **)&il->@ELEM@, @FLAGS@)) goto fail; diff --git a/source3/aparser/templates/prs_struct.tpl b/source3/aparser/templates/prs_struct.tpl new file mode 100644 index 0000000000..ab8246db8e --- /dev/null +++ b/source3/aparser/templates/prs_struct.tpl @@ -0,0 +1 @@ + if (!@MODULE@_io_@TYPE@("@ELEM@", &il->@ELEM@, ps, depth+1)) goto fail; diff --git a/source3/aparser/templates/prs_struct_alloc.tpl b/source3/aparser/templates/prs_struct_alloc.tpl new file mode 100644 index 0000000000..9eae5c92fc --- /dev/null +++ b/source3/aparser/templates/prs_struct_alloc.tpl @@ -0,0 +1 @@ + if (!@MODULE@_io_@TYPE@_alloc("@ELEM@", &il->@ELEM@, ps, depth+1)) goto fail; diff --git a/source3/aparser/templates/prs_uint16.tpl b/source3/aparser/templates/prs_uint16.tpl new file mode 100644 index 0000000000..b40d6d4216 --- /dev/null +++ b/source3/aparser/templates/prs_uint16.tpl @@ -0,0 +1 @@ + if (!io_uint16("@ELEM@", ps, depth+1, &il->@ELEM@)) goto fail; diff --git a/source3/aparser/templates/prs_uint32.tpl b/source3/aparser/templates/prs_uint32.tpl new file mode 100644 index 0000000000..eb76715d28 --- /dev/null +++ b/source3/aparser/templates/prs_uint32.tpl @@ -0,0 +1 @@ + if (!io_uint32("@ELEM@", ps, depth+1, &il->@ELEM@)) goto fail; diff --git a/source3/aparser/templates/prs_uint8s.tpl b/source3/aparser/templates/prs_uint8s.tpl new file mode 100644 index 0000000000..967162213f --- /dev/null +++ b/source3/aparser/templates/prs_uint8s.tpl @@ -0,0 +1,2 @@ + if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@))*(il->@ARRAY_LEN@))) goto fail; + if (!io_uint8s("@ELEM@", ps, depth+1, &il->@ELEM@, il->@ARRAY_LEN@, @FLAGS@)) goto fail; diff --git a/source3/aparser/templates/prs_uint8s_fixed.tpl b/source3/aparser/templates/prs_uint8s_fixed.tpl new file mode 100644 index 0000000000..26597f419f --- /dev/null +++ b/source3/aparser/templates/prs_uint8s_fixed.tpl @@ -0,0 +1 @@ + if (!io_uint8s_fixed("@ELEM@", ps, depth+1, il->@ELEM@, @ARRAY_LEN@, @FLAGS@)) goto fail; diff --git a/source3/aparser/templates/prs_wstring.tpl b/source3/aparser/templates/prs_wstring.tpl new file mode 100644 index 0000000000..4de46f093c --- /dev/null +++ b/source3/aparser/templates/prs_wstring.tpl @@ -0,0 +1,2 @@ + if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@))*(il->@ARRAY_LEN@))) goto fail; + if (!io_wstring("@ELEM@", ps, depth+1, il->@ELEM@, il->@ARRAY_LEN@, @FLAGS@)) goto fail; diff --git a/source3/aparser/templates/prs_wstring_fixed.tpl b/source3/aparser/templates/prs_wstring_fixed.tpl new file mode 100644 index 0000000000..e33f7c3d5d --- /dev/null +++ b/source3/aparser/templates/prs_wstring_fixed.tpl @@ -0,0 +1,2 @@ + if (!io_alloc("@ELEM@", ps, (void **)&il->@ELEM@, sizeof(*(il->@ELEM@))*(@ARRAY_LEN@))) goto fail; + if (!io_wstring("@ELEM@", ps, depth+1, il->@ELEM@, @ARRAY_LEN@, @FLAGS@)) goto fail; diff --git a/source3/aparser/templates/union_end.tpl b/source3/aparser/templates/union_end.tpl new file mode 100644 index 0000000000..511adbcf60 --- /dev/null +++ b/source3/aparser/templates/union_end.tpl @@ -0,0 +1,5 @@ + default: + DEBUG(5,("No handler for case %d in @FUNCNAME@\n", + (int)il->@SWITCH@)); + goto fail; + } diff --git a/source3/aparser/templates/union_start.tpl b/source3/aparser/templates/union_start.tpl new file mode 100644 index 0000000000..aa052be697 --- /dev/null +++ b/source3/aparser/templates/union_start.tpl @@ -0,0 +1 @@ + switch (il->@SWITCH@) { diff --git a/source3/aparser/token.awk b/source3/aparser/token.awk new file mode 100644 index 0000000000..fb2982f077 --- /dev/null +++ b/source3/aparser/token.awk @@ -0,0 +1,180 @@ +# tokenise the input file + +function parse_error(msg) { + printf("PARSE ERROR: %s\nLine "NR" : "$0"\n", msg); + exit 1; +} + +# ignore multi-line C comments. +{ + if (t = index($0, "/*")) { + if (t > 1) + tmp = substr($0, 1, t - 1) + else + tmp = "" + u = index(substr($0, t + 2), "*/") + while (u == 0) { + getline + t = -1 + u = index($0, "*/") + } + if (u <= length($0) - 2) + $0 = tmp substr($0, t + u + 3) + else + $0 = tmp + } +} + +# ignore blank lines +/^[ \t]*$/ { + next; +} + +/^\#define.*/ { + split($0,a,"[ \t;]*"); + parse_define(a[2], a[3]); + next; +} + +# ignore comments +/^[ \t]*\#/ { + next; +} + +/^[ \t]*module/ { + {if (module!="") parse_error("you can only specify one module name");} + start_module($2); + next; +} + +{if (module=="") parse_error("you must specify the module name first");} + +/^[ \t]*option/ { + set_option($2, $3); + next; +} + +/^[ \t]*typedef struct.*\{/ { + {if (current_struct!="") parse_error("you cannot have nested structures");} + start_struct($3); + next; +} + +/^[ \t]*struct.*\{/ { + {if (current_struct!="") parse_error("you cannot have nested structures");} + start_struct($2); + next; +} + +/^[ \t]*typedef union.*\{/ { + {if (current_struct!="") parse_error("this cannot appear inside a structure");} + split($0,a,"[ \t;()]*"); + start_union_encap(a[4], a[6], a[7], a[8]); + next; +} + +/^[ \t]*void.*\(/ { + {if (current_struct!="") parse_error("you cannot have nested structures");} + split($0,a,"[ \t;()]*"); + start_function(a[2], a[3]); + return_result="void"; + next; +} + +/^[ \t]*STATUS.*\(|^[ \t]*void.*\(/ { + {if (current_struct!="") parse_error("you cannot have nested structures");} + split($0,a,"[ \t;()]*"); + start_function(a[2], a[3]); + return_result="STATUS"; + next; +} + +{if (current_struct=="") parse_error("this must appear inside a structure");} + +/^[ \t]*union.*\{/ { + {if (current_union!="") parse_error("you cannot have nested unions");} + start_union($2); + next; +} + +/^[ \t]*\[switch_is.*union.*\{/ { + {if (current_union!="") parse_error("you cannot have nested unions");} + split($0,a,"[ \t;()]*"); + start_union_notencap(a[3]); + next; +} + +/^[ \t]*case.*;/ { + {if (current_union=="") parse_error("this must appear inide a union");} + split($0,a,"[ \t;]*"); + parse_case(a[3],a[4],a[5]); + next; +} + +/^[ \t]*\[case(.*)\].*;/ { + {if (current_union=="") parse_error("this must appear inide a union");} + split($0,a,"[ \t;()[\]]*"); + parse_case(a[6],a[8],a[9]); + next; +} + +/^[ \t]*\}$/ { + {if (current_union=="") parse_error("this must appear inside a union");} + end_union(""); + next; +} + +/^[ \t]*\} .*;/ { + if (current_union!="") { + split($2,a,"[ \t;]*"); + end_union(a[1]); + next; + } +} + +{if (current_union!="") parse_error("this cannot appear inside a union");} + +/^[ \t]*\};/ { + end_struct(""); + next; +} + +/^[ \t]*\} .*;/ { + split($2,a,"[ \t;]*"); + end_struct(a[1]); + next; +} + +/^[ \t]*\);/ { + end_function(); + return_result=""; + next; +} + +/^.*size_is.*\*.*;/ { + split($0,a,"[ \t;()]*"); + add_sizeis_array(a[3], a[5], a[6]); + next; +} + +/^.*;/ { + split($0,a,"[ \t;]*"); + add_struct_elem(a[2], a[3]); + next; +} + +/^[\t ]*void/ { + next; +} + +/^[ \t]*\[.*\].*/ { + split($0,a,"[ \t;]*"); + split(a[4], b, "[,]"); + add_function_param(a[2], a[3], b[1]); + next; +} + +{ + parse_error("Unknown construct."); +} + diff --git a/source3/aparser/util.awk b/source3/aparser/util.awk new file mode 100644 index 0000000000..6c5594da68 --- /dev/null +++ b/source3/aparser/util.awk @@ -0,0 +1,39 @@ +function isaptr(elem) +{ + if (substr(elem, 1, 1) == "*") { + return 1; + } + return 0; +} + +function noptr(elem) +{ + if (!isaptr(elem)) return elem; + return substr(elem, 2); +} + +function xprintf(f, fmt, v1, v2, v3, v4, v5, v6, v7) +{ + printf(fmt, v1, v2, v3, v4, v5, v6) > f; +} + +function fatal(why) +{ + printf("FATAL: %s\n", why); + exit 1; +} + +function numlines(fname, + LOCAL, line, count) +{ + count=0; + while ((getline line < fname) > 0) count++; + close(fname); + return count; +} + +# return 1 if the string is a constant +function is_constant(s) +{ + return match(s,"^[0-9]+$"); +} diff --git a/source3/aparser/util.c b/source3/aparser/util.c new file mode 100644 index 0000000000..ffa84dbfab --- /dev/null +++ b/source3/aparser/util.c @@ -0,0 +1,112 @@ +#include "parser.h" + + +/******************************************************************* + Count the number of characters (not bytes) in a unicode string. +********************************************************************/ +size_t strlen_w(void *src) +{ + size_t len; + + for (len = 0; SVAL(src, len*2); len++) ; + + return len; +} + +/**************************************************************************** +expand a pointer to be a particular size +****************************************************************************/ +void *Realloc(void *p,size_t size) +{ + void *ret=NULL; + + if (size == 0) { + if (p) free(p); + DEBUG(5,("Realloc asked for 0 bytes\n")); + return NULL; + } + + if (!p) + ret = (void *)malloc(size); + else + ret = (void *)realloc(p,size); + + if (!ret) + DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size)); + + return(ret); +} + + +char *tab_depth(int depth) +{ + static pstring spaces; + memset(spaces, ' ', depth * 4); + spaces[depth * 4] = 0; + return spaces; +} + +void print_asc(int level, uchar const *buf, int len) +{ + int i; + for (i = 0; i < len; i++) + { + DEBUGADD(level, ("%c", isprint(buf[i]) ? buf[i] : '.')); + } +} + +void dump_data(int level, char *buf1, int len) +{ + uchar const *buf = (uchar const *)buf1; + int i = 0; + if (buf == NULL) + { + DEBUG(level, ("dump_data: NULL, len=%d\n", len)); + return; + } + if (len < 0) + return; + if (len == 0) + { + DEBUG(level, ("\n")); + return; + } + + DEBUG(level, ("[%03X] ", i)); + for (i = 0; i < len;) + { + DEBUGADD(level, ("%02X ", (int)buf[i])); + i++; + if (i % 8 == 0) + DEBUGADD(level, (" ")); + if (i % 16 == 0) + { + print_asc(level, &buf[i - 16], 8); + DEBUGADD(level, (" ")); + print_asc(level, &buf[i - 8], 8); + DEBUGADD(level, ("\n")); + if (i < len) + DEBUGADD(level, ("[%03X] ", i)); + } + } + + if (i % 16 != 0) /* finish off a non-16-char-length row */ + { + int n; + + n = 16 - (i % 16); + DEBUGADD(level, (" ")); + if (n > 8) + DEBUGADD(level, (" ")); + while (n--) + DEBUGADD(level, (" ")); + + n = MIN(8, i % 16); + print_asc(level, &buf[i - (i % 16)], n); + DEBUGADD(level, (" ")); + n = (i % 16) - n; + if (n > 0) + print_asc(level, &buf[i - n], n); + DEBUGADD(level, ("\n")); + } +} diff --git a/source3/aparser/vluke.c b/source3/aparser/vluke.c new file mode 100644 index 0000000000..d3868f2753 --- /dev/null +++ b/source3/aparser/vluke.c @@ -0,0 +1,41 @@ +#include "parser.h" +#include "test.h" + +int main(int argc, char *argv[]) +{ + BOOL ret; + char *fname, *test; + int fd; + struct stat st; + io_struct ps; + + if (argc < 3) { + printf("usage: vluke <structure> <file>\n"); + exit(1); + } + + test = argv[1]; + fname = argv[2]; + + fd = open(fname,O_RDONLY); + if (fd == -1) { + perror(fname); + exit(1); + } + fstat(fd, &st); + + io_init(&ps, 0, MARSHALL); + ps.is_dynamic=True; + io_read(&ps, fd, st.st_size, 0); + ps.data_offset = 0; + ps.buffer_size = ps.grow_size; + ps.io = UNMARSHALL; + ps.autoalign = OPTION_autoalign; + ret = run_test(test, &ps, PARSE_SCALARS|PARSE_BUFFERS); + printf("\nret=%s\n", ret?"OK":"Bad"); + printf("Trailer is %d bytes\n\n", ps.grow_size - ps.data_offset); + if (ps.grow_size - ps.data_offset > 0) { + dump_data(0, ps.data_p + ps.data_offset, ps.grow_size - ps.data_offset); + } + return !ret; +} |