|
|
//
// Copyright (C) 2000, Microsoft Corporation
//
// File: PackMisc.c
//
// Contents: packing routines used by DFS
//
// History: Dec. 8 2000, Author: udayh
//
//-----------------------------------------------------------------------------
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include "dfsheader.h"
#include "dfsmisc.h"
#define BYTE_0_MASK 0xFF
#define BYTE_0(Value) (UCHAR)( (Value) & BYTE_0_MASK)
#define BYTE_1(Value) (UCHAR)( ((Value) >> 8) & BYTE_0_MASK)
#define BYTE_2(Value) (UCHAR)( ((Value) >> 16) & BYTE_0_MASK)
#define BYTE_3(Value) (UCHAR)( ((Value) >> 24) & BYTE_0_MASK)
//+-------------------------------------------------------------------------
//
// Function PackGetULong
//
// Arguments: pValue - pointer to return info
// ppBuffer - pointer to buffer that holds the binary
// stream.
// pSizeRemaining - pointer to size of above buffer
//
// Returns: Status
// ERROR_SUCCESS if we could unpack the name info
// ERROR_INVALID_DATA otherwise
//
//
// Description: This routine reads one ulong value from the binary
// stream, and returns that value. It adjusts the buffer
// pointer and remaining size appropriately to point
// to the next value in the binary stream.
//
//--------------------------------------------------------------------------
DFSSTATUS PackGetULong( PULONG pValue, PVOID *ppBuffer, PULONG pSizeRemaining ) { DFSSTATUS Status = ERROR_INVALID_DATA; ULONG SizeNeeded = sizeof(ULONG); PUCHAR pBinaryStream = (PUCHAR)(*ppBuffer);
if ( *pSizeRemaining >= SizeNeeded ) { *pValue = (ULONG) ( (ULONG) pBinaryStream[0] | (ULONG) pBinaryStream[1] << 8 | (ULONG) pBinaryStream[2] << 16 | (ULONG) pBinaryStream[3] << 24);
*ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + SizeNeeded); *pSizeRemaining -= SizeNeeded;
Status = ERROR_SUCCESS; }
return Status; }
//+-------------------------------------------------------------------------
//
// Function: PackSetULong - store one Ulong in the binary stream
//
// Arguments: Value - Ulong to add
// ppBuffer - pointer to buffer that holds the binary stream.
// pSizeRemaining - pointer to size remaining in buffer
//
// Returns: Status
// ERROR_SUCCESS if we could unpack the name info
// ERROR_INVALID_DATA otherwise
//
//
// Description: This routine stores one ulong value in the binary stream,
// It adjusts the buffer pointer and remaining size
// appropriately to point to the next value
// in the binary stream.
//
//--------------------------------------------------------------------------
DFSSTATUS PackSetULong( ULONG Value, PVOID *ppBuffer, PULONG pSizeRemaining ) { DFSSTATUS Status = ERROR_INVALID_DATA; ULONG SizeNeeded = sizeof(ULONG); PUCHAR pBinaryStream = (PUCHAR)(*ppBuffer);
if ( *pSizeRemaining >= SizeNeeded ) { pBinaryStream[0] = BYTE_0( Value ); pBinaryStream[1] = BYTE_1( Value ); pBinaryStream[2] = BYTE_2( Value ); pBinaryStream[3] = BYTE_3( Value ); *ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + SizeNeeded); *pSizeRemaining -= SizeNeeded;
Status = ERROR_SUCCESS; }
return Status; }
//
// Function: PackSizeULong, return size of ulong
//
ULONG PackSizeULong() { return sizeof(ULONG); }
//+-------------------------------------------------------------------------
//
// Function: PackGetUShort - get one UShort from the binary stream
//
// Arguments: pValue - pointer to return info
// ppBuffer - pointer to buffer that holds the binary
// stream.
// pSizeRemaining - pointer to size of above buffer
//
// Returns: Status
// ERROR_SUCCESS if we could unpack the name info
// ERROR_INVALID_DATA otherwise
//
//
// Description: This routine reads one uShort value from the binary
// stream, and returns that value. It adjusts the
// buffer pointer and remaining size appropriately to
// point to the next value in the binary stream.
//
//--------------------------------------------------------------------------
DFSSTATUS PackGetUShort( PUSHORT pValue, PVOID *ppBuffer, PULONG pSizeRemaining ) { DFSSTATUS Status = ERROR_INVALID_DATA; ULONG SizeNeeded = sizeof(USHORT); PUCHAR pBinaryStream = (PUCHAR)(*ppBuffer);
if ( *pSizeRemaining >= SizeNeeded ) { *pValue = (USHORT)( (USHORT) pBinaryStream[0] | (USHORT) pBinaryStream[1] << 8 );
*ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + SizeNeeded);
*pSizeRemaining -= SizeNeeded;
Status = ERROR_SUCCESS; }
return Status; }
//+-------------------------------------------------------------------------
//
// Function: PackSetUShort - puts one UShort in the binary stream
//
// Arguments: Value - Ushort value
// ppBuffer - pointer to buffer that holds the binary stream.
// pSizeRemaining - pointer to size of above buffer
//
// Returns: Status
// ERROR_SUCCESS if we could pack
// ERROR_INVALID_DATA otherwise
//
//
// Description: This routine puts one uShort value in the binary stream,
// It adjusts the buffer pointer and
// remaining size appropriately to point to the next value
// in the binary stream.
//
//--------------------------------------------------------------------------
DFSSTATUS PackSetUShort( USHORT Value, PVOID *ppBuffer, PULONG pSizeRemaining ) { DFSSTATUS Status = ERROR_INVALID_DATA; ULONG SizeNeeded = sizeof(USHORT); PUCHAR pBinaryStream = (PUCHAR)(*ppBuffer);
if ( *pSizeRemaining >= SizeNeeded ) { pBinaryStream[0] = BYTE_0(Value); pBinaryStream[1] = BYTE_1(Value);
*ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + SizeNeeded);
*pSizeRemaining -= SizeNeeded;
Status = ERROR_SUCCESS; } return Status; }
//
// Function: PackSizeUShort, return size of ushort
//
ULONG PackSizeUShort() { return sizeof(USHORT); }
//+-------------------------------------------------------------------------
//
// Function: PackGetString - gets a string from a binary stream.
//
// Arguments: pString - pointer to returned unicode string
// ppBuffer - pointer to buffer that holds the binary stream.
// pSizeRemaining - pointer to size of above buffer
//
// Returns: Status
// ERROR_SUCCESS if we could unpack the name info
// ERROR_INVALID_DATA otherwise
//
//
// Description: This routine reads one ulong value from the binary stream,
// and determines that to be the length of the string.
// It then sets up a unicode string, whose buffer points
// to the appropriate place within the binary stream, and
// whose length is set to the ulong value that was read.
// It returns the buffer and size remaining adjusted appropriately.
//
//--------------------------------------------------------------------------
DFSSTATUS PackGetString( PUNICODE_STRING pString, PVOID *ppBuffer, PULONG pSizeRemaining ) { DFSSTATUS ReturnStatus = ERROR_INVALID_DATA; DFSSTATUS Status;
//
// We first get the length of the string.
//
Status = PackGetUShort(&pString->Length, ppBuffer, pSizeRemaining );
if ( Status == ERROR_SUCCESS ) { //
// If the length exceeds the remaining binary stream or the length
// is odd, we dont have a valid string.
// Otherwise, set the pointer in the unicode string to the binary
// stream representing the string, and update the buffer to point
// to beyond the string.
//
if ( *pSizeRemaining >= pString->Length && (pString->Length & 0x1) == 0 ) {
pString->Buffer = (LPWSTR)(*ppBuffer); *ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + pString->Length); *pSizeRemaining -= pString->Length; pString->MaximumLength = pString->Length;
ReturnStatus = ERROR_SUCCESS; } }
return ReturnStatus; }
//+-------------------------------------------------------------------------
//
// Function: PackSetString - puts a string in the binary stream.
//
// Arguments: pString - pointer to unicode string to pack
// ppBuffer - pointer to buffer that holds the binary stream.
// pSizeRemaining - pointer to size of above buffer
//
// Returns: Status
// ERROR_SUCCESS if we could pack
// ERROR_INVALID_DATA otherwise
//
//
// Description: This routine puts one ulong value in the binary stream
// to represent length of string. It then copies the string
// itself into the buffer.
//
//--------------------------------------------------------------------------
DFSSTATUS PackSetString( PUNICODE_STRING pString, PVOID *ppBuffer, PULONG pSizeRemaining ) { DFSSTATUS ReturnStatus = ERROR_INVALID_DATA; DFSSTATUS Status;
//
// We first set the length of the string.
//
Status = PackSetUShort( pString->Length, ppBuffer, pSizeRemaining );
if ( Status == ERROR_SUCCESS ) { //
// If the length exceeds the remaining binary stream
// we dont have a valid string.
// Otherwise, we copy the unicode string to the binary
// stream representing the string, and update the buffer to point
// to beyond the string.
//
if ( *pSizeRemaining >= pString->Length ) { memcpy((LPWSTR)(*ppBuffer), pString->Buffer, pString->Length);
*ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + pString->Length); *pSizeRemaining -= pString->Length;
ReturnStatus = ERROR_SUCCESS; } }
return ReturnStatus; }
//
// Function: PackSizeString - return size of string
//
ULONG PackSizeString( PUNICODE_STRING pString) { return (ULONG)(sizeof(USHORT) + pString->Length); }
//+-------------------------------------------------------------------------
//
// Function: PackGetGuid - Unpacks the guid from a binary stream
//
// Arguments: pGuid - pointer to a guid structure
// ppBuffer - pointer to buffer that holds the binary stream.
// pSizeRemaining - pointer to size of above buffer
//
// Returns: Status
// ERROR_SUCCESS if we could unpack the info
// ERROR_INVALID_DATA otherwise
//
//
// Description: This routine expects the binary stream to hold a guid.
// It reads the guid information into the guid structure in
// the format prescribed for guids.
// The ppbuffer and size are adjusted to point to the next
// information in the binary stream.
//
//--------------------------------------------------------------------------
DFSSTATUS PackGetGuid( GUID *pGuid, PVOID *ppBuffer, PULONG pSizeRemaining ) { DFSSTATUS Status = ERROR_INVALID_DATA; ULONG SizeNeeded = sizeof(GUID); PUCHAR pGuidInfo = (PUCHAR)(*ppBuffer);
if ( *pSizeRemaining >= SizeNeeded ) { pGuid->Data1 = (ULONG) ((ULONG) pGuidInfo[0] | (ULONG) pGuidInfo[1] << 8 | (ULONG) pGuidInfo[2] << 16 | (ULONG) pGuidInfo[3] << 24 );
pGuid->Data2 = (USHORT) ((USHORT) pGuidInfo[4] | (USHORT) pGuidInfo[5] << 8 );
pGuid->Data3 = (USHORT) ((USHORT) pGuidInfo[6] | (USHORT) pGuidInfo[7] << 8 );
memcpy(pGuid->Data4, &pGuidInfo[8], 8);
*ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + SizeNeeded); *pSizeRemaining -= SizeNeeded;
Status = ERROR_SUCCESS; }
return Status; }
//+-------------------------------------------------------------------------
//
// Function: PackSetGuid - Packs the guid from a binary stream
//
// Arguments: pGuid - pointer to a guid structure
// ppBuffer - pointer to buffer that holds the binary stream.
// pSizeRemaining - pointer to size of above buffer
//
// Returns: Status
// ERROR_SUCCESS if we could pack the info
// ERROR_INVALID_DATA otherwise
//
//
// Description: This routine stores the guid into the binary stream.
// The ppbuffer and size are adjusted to point to the next
// information in the binary stream.
//
//--------------------------------------------------------------------------
DFSSTATUS PackSetGuid( GUID *pGuid, PVOID *ppBuffer, PULONG pSizeRemaining ) { DFSSTATUS Status = ERROR_INVALID_DATA; ULONG SizeNeeded = sizeof(GUID); PUCHAR pGuidInfo = (PUCHAR)(*ppBuffer);
if ( *pSizeRemaining >= SizeNeeded ) { pGuidInfo[0] = BYTE_0(pGuid->Data1); pGuidInfo[1] = BYTE_1(pGuid->Data1); pGuidInfo[2] = BYTE_2(pGuid->Data1); pGuidInfo[3] = BYTE_3(pGuid->Data1);
pGuidInfo[4] = BYTE_0(pGuid->Data2); pGuidInfo[5] = BYTE_1(pGuid->Data2); pGuidInfo[6] = BYTE_0(pGuid->Data3); pGuidInfo[7] = BYTE_1(pGuid->Data3);
memcpy(&pGuidInfo[8], pGuid->Data4, 8);
*ppBuffer = (PVOID)((ULONG_PTR)*ppBuffer + SizeNeeded); *pSizeRemaining -= SizeNeeded;
Status = ERROR_SUCCESS; } return Status; }
//
// Function: PackSizeGuid - return size of Guid
//
ULONG PackSizeGuid() { return sizeof(GUID); }
|