Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

478 lines
16 KiB

//
// 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);
}