/*++ Copyright (c) 2000-2000 Microsoft Corporation Module Name: flatbuf.c Abstract: Domain Name System (DNS) Library Flat buffer sizing routines. Author: Jim Gilroy (jamesg) December 22, 2000 Revision History: --*/ #include "local.h" // // Flat buffer routines -- argument versions // // These versions have the actual code so that we can // easily use this stuff with existing code that has // independent pCurrent and BytesLeft variables. // // FLATBUF structure versions just call these inline. // PBYTE FlatBuf_Arg_Reserve( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN DWORD Size, IN DWORD Alignment ) /*++ Routine Description: Reserve space in a flat buffer -- properly aligned. Arguments: ppCurrent -- address of buffer current pointer updated with buf pointer after reservation pBytesLeft -- address of buf bytes left updated with bytes left after reservation Size -- size required Alignment -- alignment (size in bytes) required Return Value: Ptr to aligned spot in buffer reserved for write. NULL on error. --*/ { register PBYTE pb = *ppCurrent; register INT bytesLeft = *pBytesLeft; register PBYTE pstart; register PBYTE palign; // // align pointer // pstart = pb; if ( Alignment ) { Alignment--; pb = (PBYTE) ( (UINT_PTR)(pb + Alignment) & ~(UINT_PTR)Alignment ); } palign = pb; // // reserve space // pb += Size; bytesLeft -= (INT) (pb - pstart); *pBytesLeft = bytesLeft; *ppCurrent = pb; // // indicate space adequate\not // if ( bytesLeft < 0 ) { palign = NULL; } return palign; } PBYTE FlatBuf_Arg_WriteString( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN PSTR pString, IN BOOL fUnicode ) /*++ Routine Description: Write string to flat buffer. Arguments: ppCurrent -- address of buffer current pointer updated with buf pointer after reservation pBytesLeft -- address of buf bytes left updated with bytes left after reservation pString -- ptr to string to write fUnicode -- TRUE for unicode string Return Value: Ptr to location string was written in buffer. NULL on error. --*/ { register PBYTE pwrite; register DWORD length; register DWORD align; // // determine length // if ( fUnicode ) { length = (wcslen( (PWSTR)pString ) + 1) * sizeof(WCHAR); align = sizeof(WCHAR); } else { length = strlen( pString ) + 1; align = 0; } // // reserve space and copy string // pwrite = FlatBuf_Arg_Reserve( ppCurrent, pBytesLeft, length, align ); if ( pwrite ) { RtlCopyMemory( pwrite, pString, length ); } return pwrite; } PBYTE FlatBuf_Arg_CopyMemory( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN PVOID pMemory, IN DWORD Length, IN DWORD Alignment ) /*++ Routine Description: Write memory to flat buffer. Arguments: ppCurrent -- address of buffer current pointer updated with buf pointer after reservation pBytesLeft -- address of buf bytes left updated with bytes left after reservation pMemory -- memory to copy Length -- length to copy Alignment -- alignment (size in bytes) required Return Value: Ptr to location string was written in buffer. NULL on error. --*/ { register PBYTE pwrite; // // reserve space and copy memory // pwrite = FlatBuf_Arg_Reserve( ppCurrent, pBytesLeft, Length, Alignment ); if ( pwrite ) { RtlCopyMemory( pwrite, pMemory, Length ); } return pwrite; } #if 0 // // Flatbuf inline functions -- defined in dnslib.h // __inline PBYTE FlatBuf_Arg_ReserveAlignPointer( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN DWORD Size ) { return FlatBuf_Arg_Reserve( ppCurrent, pBytesLeft, Size, sizeof(PVOID) ); } __inline PBYTE FlatBuf_Arg_ReserveAlignQword( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN DWORD Size ) { return FlatBuf_Arg_Reserve( ppCurrent, pBytesLeft, Size, sizeof(QWORD) ); } __inline PBYTE FlatBuf_Arg_ReserveAlignDword( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN DWORD Size ) { return FlatBuf_Arg_Reserve( ppCurrent, pBytesLeft, Size, sizeof(DWORD) ); } __inline PBYTE FlatBuf_Arg_ReserveAlignWord( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN DWORD Size ) { return FlatBuf_Arg_Reserve( ppCurrent, pBytesLeft, Size, sizeof(WORD) ); } __inline PBYTE FlatBuf_Arg_ReserveAlignByte( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN DWORD Size ) { return FlatBuf_Arg_Reserve( ppCurrent, pBytesLeft, Size, 0 ); } PBYTE __inline FlatBuf_Arg_WriteString_A( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN PSTR pString ) { return FlatBuf_Arg_WriteString( ppCurrent, pBytesLeft, pString, FALSE // not unicode ); } PBYTE __inline FlatBuf_Arg_WriteString_W( IN OUT PBYTE * ppCurrent, IN OUT PINT pBytesLeft, IN PWSTR pString ) { return FlatBuf_Arg_WriteString( ppCurrent, pBytesLeft, (PSTR) pString, TRUE // unicode ); } #endif // // Flat buffer routines -- structure versions // VOID FlatBuf_Init( IN OUT PFLATBUF pFlatBuf, IN PBYTE pBuffer, IN INT Size ) /*++ Routine Description: Init a FLATBUF struct with given buffer and size. Note, ok to init to zero for size determination. Arguments: pFlatBuf -- ptr to FLATBUF to init pBuffer -- buffer ptr Size -- size required Return Value: None --*/ { pFlatBuf->pBuffer = pBuffer; pFlatBuf->pCurrent = pBuffer; pFlatBuf->pEnd = pBuffer + Size; pFlatBuf->Size = Size; pFlatBuf->BytesLeft = Size; } #if 0 // // Flatbuf inline functions -- defined in dnslib.h // __inline PBYTE FlatBuf_Reserve( IN OUT PFLATBUF pBuf, IN DWORD Size, IN DWORD Alignment ) { return FlatBuf_Arg_Reserve( & pBuf->pCurrent, & pBuf->BytesLeft, Size, Alignment ); } __inline PBYTE FlatBuf_ReserveAlignPointer( IN OUT PFLATBUF pBuf, IN DWORD Size ) { return FlatBuf_Arg_Reserve( & pBuf->pCurrent, & pBuf->BytesLeft, Size, sizeof(PVOID) ); } __inline PBYTE FlatBuf_ReserveAlignQword( IN OUT PFLATBUF pBuf, IN DWORD Size ) { return FlatBuf_Arg_Reserve( & pBuf->pCurrent, & pBuf->BytesLeft, Size, sizeof(QWORD) ); } __inline PBYTE FlatBuf_ReserveAlignDword( IN OUT PFLATBUF pBuf, IN DWORD Size ) { return FlatBuf_Arg_Reserve( & pBuf->pCurrent, & pBuf->BytesLeft, Size, sizeof(DWORD) ); } __inline PBYTE FlatBuf_ReserveAlignWord( IN OUT PFLATBUF pBuf, IN DWORD Size ) { return FlatBuf_Arg_Reserve( & pBuf->pCurrent, & pBuf->BytesLeft, Size, sizeof(WORD) ); } __inline PBYTE FlatBuf_ReserveAlignByte( IN OUT PFLATBUF pBuf, IN DWORD Size ) { return FlatBuf_Arg_Reserve( & pBuf->pCurrent, & pBuf->BytesLeft, Size, 0 ); } PBYTE __inline FlatBuf_WriteString( IN OUT PFLATBUF pBuf, IN PSTR pString, IN BOOL fUnicode ) { return FlatBuf_Arg_WriteString( & pBuf->pCurrent, & pBuf->BytesLeft, pString, fUnicode ); } PBYTE __inline FlatBuf_WriteString_A( IN OUT PFLATBUF pBuf, IN PSTR pString ) { return FlatBuf_Arg_WriteString( & pBuf->pCurrent, & pBuf->BytesLeft, pString, FALSE // not unicode ); } PBYTE __inline FlatBuf_WriteString_W( IN OUT PFLATBUF pBuf, IN PWSTR pString ) { return FlatBuf_Arg_WriteString( & pBuf->pCurrent, & pBuf->BytesLeft, (PSTR) pString, TRUE // unicode ); } PBYTE __inline FlatBuf_CopyMemory( IN OUT PFLATBUF pBuf, IN PVOID pMemory, IN DWORD Length, IN DWORD Alignment ) { return FlatBuf_Arg_CopyMemory( & pBuf->pCurrent, & pBuf->BytesLeft, pMemory, Length, Alignment ); } #endif // // End flatbuf.c //