416 lines
15 KiB
C
416 lines
15 KiB
C
//+----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 1992, Microsoft Corporation
|
|
//
|
|
// File: DfsMrshl.h
|
|
//
|
|
// Contents: Defines for Dfs marshalling routines
|
|
//
|
|
// Classes:
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: March 29, 1994 Milans Created from Peterco's dfsrtl.h
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef _DFSMRSHL_
|
|
#define _DFSMRSHL_
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stddef.h>
|
|
#include <guiddef.h>
|
|
//
|
|
// MARSHALLING AND UNMARSHALLING SUPPORT
|
|
//
|
|
|
|
#ifdef KERNEL_MODE
|
|
#define MarshalBufferAllocate(x) ExAllocatePool(PagedPool, x)
|
|
#define MarshalBufferFree(x) ExFreePool(x)
|
|
#else
|
|
#include <stdlib.h>
|
|
#define MarshalBufferAllocate(x) malloc(x)
|
|
#define MarshalBufferFree(x) free(x)
|
|
#endif // KERNEL_MODE
|
|
|
|
#define DfsAllocate MarshalBufferAllocate
|
|
#define DfsFree MarshalBufferFree
|
|
|
|
//
|
|
// Structure used when marshalling and unmarhalling
|
|
//
|
|
typedef struct _MARSHAL_BUFFER {
|
|
|
|
PUCHAR First;
|
|
PUCHAR Current;
|
|
PUCHAR Last;
|
|
|
|
} MARSHAL_BUFFER, *PMARSHAL_BUFFER;
|
|
|
|
|
|
typedef struct _MARSHAL_TYPE_INFO {
|
|
|
|
ULONG _type; // the type of item to be marshalled
|
|
ULONG _off; // offset of item (in the struct)
|
|
ULONG _cntsize; // size of counter for counted array
|
|
ULONG _cntoff; // else, offset count item (in the struct)
|
|
struct _MARSHAL_INFO * _subinfo;// if compound type, need info
|
|
|
|
} MARSHAL_TYPE_INFO, *PMARSHAL_TYPE_INFO;
|
|
|
|
|
|
typedef struct _MARSHAL_INFO {
|
|
|
|
ULONG _size; // size of item
|
|
ULONG _typecnt; // number of type infos
|
|
PMARSHAL_TYPE_INFO _typeInfo; // type infos
|
|
|
|
} MARSHAL_INFO, *PMARSHAL_INFO;
|
|
|
|
#define _mkMarshalInfo(s, i)\
|
|
{(ULONG)sizeof(s),(ULONG)(sizeof(i)/sizeof(MARSHAL_TYPE_INFO)),i}
|
|
|
|
|
|
#define MTYPE_BASE_TYPE (0x0000ffffL)
|
|
|
|
#define MTYPE_COMPOUND (0x00000001L)
|
|
#define MTYPE_GUID (0x00000002L)
|
|
#define MTYPE_STRING (0x00000003L)
|
|
#define MTYPE_UNICODE_STRING (0x00000004L)
|
|
#define MTYPE_ULONG (0x00000005L)
|
|
#define MTYPE_USHORT (0x00000006L)
|
|
#define MTYPE_PWSTR (0x00000007L)
|
|
#define MTYPE_UCHAR (0x00000008L)
|
|
#define MTYPE_CONFORMANT_CNT (0x00000009L)
|
|
|
|
#define MTYPE_INDIRECT (0x80000000L)
|
|
|
|
#define MTYPE_COMPLEX_TYPE (0x7fff0000L)
|
|
|
|
#define MTYPE_STATIC_ARRAY (0x00010000L)
|
|
#define MTYPE_COUNTED_ARRAY (0x00020000L)
|
|
|
|
|
|
#define _MCode_conformant(s,m,c)\
|
|
{MTYPE_CONFORMANT_CNT, sizeof(((s *) 0)->m[0]), sizeof(((s *) 0)->c), offsetof(s,c), 0L}
|
|
|
|
#define _MCode_Base(t,s,m,i)\
|
|
{t,offsetof(s,m),0L,0L,i}
|
|
|
|
#define _MCode_struct(s,m,i)\
|
|
_MCode_Base(MTYPE_COMPOUND,s,m,i)
|
|
#define _MCode_guid(s,m)\
|
|
_MCode_Base(MTYPE_GUID,s,m,NULL)
|
|
#define _MCode_str(s,m)\
|
|
_MCode_Base(MTYPE_STRING,s,m,NULL)
|
|
#define _MCode_ustr(s,m)\
|
|
_MCode_Base(MTYPE_UNICODE_STRING,s,m,NULL)
|
|
#define _MCode_pwstr(s,m)\
|
|
_MCode_Base(MTYPE_PWSTR,s,m,NULL)
|
|
#define _MCode_ul(s,m)\
|
|
_MCode_Base(MTYPE_ULONG,s,m,NULL)
|
|
#define _MCode_ush(s,m)\
|
|
_MCode_Base(MTYPE_USHORT,s,m,NULL)
|
|
#define _MCode_uch(s,m)\
|
|
_MCode_Base(MTYPE_UCHAR,s,m,NULL)
|
|
|
|
#define _MCode_pstruct(s,m,i)\
|
|
_MCode_Base(MTYPE_COMPOUND|MTYPE_INDIRECT,s,m,i)
|
|
#define _MCode_pguid(s,m)\
|
|
_MCode_Base(MTYPE_GUID|MTYPE_INDIRECT,s,m,NULL)
|
|
#define _MCode_pstr(s,m)\
|
|
_MCode_Base(MTYPE_STRING|MTYPE_INDIRECT,s,m,NULL)
|
|
#define _MCode_pustr(s,m)\
|
|
_MCode_Base(MTYPE_UNICODE_STRING|MTYPE_INDIRECT,s,m,NULL)
|
|
#define _MCode_pul(s,m)\
|
|
_MCode_Base(MTYPE_ULONG|MTYPE_INDIRECT,s,m,NULL)
|
|
#define _MCode_push(s,m)\
|
|
_MCode_Base(MTYPE_USHORT|MTYPE_INDIRECT,s,m,NULL)
|
|
#define _MCode_puch(s,m)\
|
|
_MCode_Base(MTYPE_UCHAR|MTYPE_INDIRECT,s,m,NULL)
|
|
|
|
#define _MCode_aStatic(t,s,m,c,i)\
|
|
{t|MTYPE_STATIC_ARRAY,offsetof(s,m),0L,c,i}
|
|
|
|
#define _MCode_astruct(s,m,c,i)\
|
|
_MCode_aStatic(MTYPE_COMPOUND,s,m,c,i)
|
|
#define _MCode_aguid(s,m,c)\
|
|
_MCode_aStatic(MTYPE_GUID,s,m,c,NULL)
|
|
#define _MCode_astr(s,m,c)\
|
|
_MCode_aStatic(MTYPE_STRING,s,m,c,NULL)
|
|
#define _MCode_austr(s,m,c)\
|
|
_MCode_aStatic(MTYPE_UNICODE_STRING,s,m,c,NULL)
|
|
#define _MCode_aul(s,m,c)\
|
|
_MCode_aStatic(MTYPE_ULONG,s,m,c,NULL)
|
|
#define _MCode_aush(s,m,c)\
|
|
_MCode_aStatic(MTYPE_USHORT,s,m,c,NULL)
|
|
#define _MCode_auch(s,m,c)\
|
|
_MCode_aStatic(MTYPE_UCHAR,s,m,c,NULL)
|
|
|
|
#define _MCode_pastruct(s,m,c,i)\
|
|
_MCode_aStatic(MTYPE_COMPOUND|MTYPE_INDIRECT,s,m,c,i)
|
|
#define _MCode_paguid(s,m,c)\
|
|
_MCode_aStatic(MTYPE_GUID|MTYPE_INDIRECT,s,m,c,NULL)
|
|
#define _MCode_pastr(s,m,c)\
|
|
_MCode_aStatic(MTYPE_STRING|MTYPE_INDIRECT,s,m,c,NULL)
|
|
#define _MCode_paustr(s,m,c)\
|
|
_MCode_aStatic(MTYPE_UNICODE_STRING|MTYPE_INDIRECT,s,m,c,NULL)
|
|
#define _MCode_paul(s,m,c)\
|
|
_MCode_aStatic(MTYPE_ULONG|MTYPE_INDIRECT,s,m,c,NULL)
|
|
#define _MCode_paush(s,m,c)\
|
|
_MCode_aStatic(MTYPE_USHORT|MTYPE_INDIRECT,s,m,c,NULL)
|
|
#define _MCode_pauch(s,m,c)\
|
|
_MCode_aStatic(MTYPE_UCHAR|MTYPE_INDIRECT,s,m,c,NULL)
|
|
|
|
#define _MCode_aCounted(t,s,m,c,i) {\
|
|
t|MTYPE_COUNTED_ARRAY,\
|
|
offsetof(s,m),\
|
|
sizeof(((s *)0)->c),\
|
|
offsetof(s,c),\
|
|
i\
|
|
}
|
|
|
|
#define _MCode_castruct(s,m,c,i)\
|
|
_MCode_aCounted(MTYPE_COMPOUND,s,m,c,i)
|
|
#define _MCode_caguid(s,m,c)\
|
|
_MCode_aCounted(MTYPE_GUID,s,m,c,NULL)
|
|
#define _MCode_capwstr(s,m,c)\
|
|
_MCode_aCounted(MTYPE_PWSTR,s,m,c,NULL)
|
|
#define _MCode_castr(s,m,c)\
|
|
_MCode_aCounted(MTYPE_STRING,s,m,c,NULL)
|
|
#define _MCode_caustr(s,m,c)\
|
|
_MCode_aCounted(MTYPE_UNICODE_STRING,s,m,c,NULL)
|
|
#define _MCode_caul(s,m,c)\
|
|
_MCode_aCounted(MTYPE_ULONG,s,m,c,NULL)
|
|
#define _MCode_caush(s,m,c)\
|
|
_MCode_aCounted(MTYPE_USHORT,s,m,c,NULL)
|
|
#define _MCode_cauch(s,m,c)\
|
|
_MCode_aCounted(MTYPE_UCHAR,s,m,c,NULL)
|
|
|
|
#define _MCode_pcastruct(s,m,c,i)\
|
|
_MCode_aCounted(MTYPE_COMPOUND|MTYPE_INDIRECT,s,m,c,i)
|
|
#define _MCode_pcaguid(s,m,c)\
|
|
_MCode_aCounted(MTYPE_GUID|MTYPE_INDIRECT,s,m,c,NULL)
|
|
#define _MCode_pcapwstr(s,m,c)\
|
|
_MCode_aCounted(MTYPE_PWSTR|MTYPE_INDIRECT,s,m,c,NULL)
|
|
#define _MCode_pcastr(s,m,c)\
|
|
_MCode_aCounted(MTYPE_STRING|MTYPE_INDIRECT,s,m,c,NULL)
|
|
#define _MCode_pcaustr(s,m,c)\
|
|
_MCode_aCounted(MTYPE_UNICODE_STRING|MTYPE_INDIRECT,s,m,c,NULL)
|
|
#define _MCode_pcaul(s,m,c)\
|
|
_MCode_aCounted(MTYPE_ULONG|MTYPE_INDIRECT,s,m,c,NULL)
|
|
#define _MCode_pcaush(s,m,c)\
|
|
_MCode_aCounted(MTYPE_USHORT|MTYPE_INDIRECT,s,m,c,NULL)
|
|
#define _MCode_pcauch(s,m,c)\
|
|
_MCode_aCounted(MTYPE_UCHAR|MTYPE_INDIRECT,s,m,c,NULL)
|
|
|
|
|
|
|
|
#define MarshalBufferInitialize( MarshalBuffer, BufferLength, Buffer ) {\
|
|
(MarshalBuffer)->First = (PUCHAR)(Buffer); \
|
|
(MarshalBuffer)->Current = (PUCHAR)(Buffer); \
|
|
(MarshalBuffer)->Last = &(MarshalBuffer)->Current[(BufferLength)]; \
|
|
}
|
|
|
|
|
|
//
|
|
// Defines and functions for unmarshalling base types.
|
|
// The BYTE masks are perfectly fine and they dont care if
|
|
// we are on working on LITTLE_ENDIAN or BIG_ENDIAN etc.
|
|
//
|
|
|
|
#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)
|
|
|
|
|
|
#define DfsRtlGetUshort(MarshalBuffer, pValue) ( \
|
|
((MarshalBuffer)->Current + sizeof(USHORT) <= (MarshalBuffer)->Last) ? \
|
|
*(pValue) = (USHORT)((MarshalBuffer)->Current[0] ) | \
|
|
((MarshalBuffer)->Current[1] << 8), \
|
|
(MarshalBuffer)->Current += 2, \
|
|
STATUS_SUCCESS \
|
|
: STATUS_DATA_ERROR \
|
|
)
|
|
|
|
#define DfsRtlPutUshort(MarshalBuffer, pValue) ( \
|
|
((MarshalBuffer)->Current + sizeof(USHORT) <= (MarshalBuffer)->Last) ? \
|
|
(MarshalBuffer)->Current[0] = BYTE_0(*pValue), \
|
|
(MarshalBuffer)->Current[1] = BYTE_1(*pValue), \
|
|
(MarshalBuffer)->Current += 2, \
|
|
STATUS_SUCCESS \
|
|
: STATUS_BUFFER_TOO_SMALL \
|
|
)
|
|
|
|
#define DfsRtlGetUlong(MarshalBuffer, pValue) ( \
|
|
((MarshalBuffer)->Current + sizeof(ULONG) <= (MarshalBuffer)->Last) ? \
|
|
*(pValue) = (ULONG) ((MarshalBuffer)->Current[0] ) | \
|
|
((MarshalBuffer)->Current[1] << 8) | \
|
|
((MarshalBuffer)->Current[2] << 16) | \
|
|
((MarshalBuffer)->Current[3] << 24), \
|
|
(MarshalBuffer)->Current += 4, \
|
|
STATUS_SUCCESS \
|
|
: STATUS_DATA_ERROR \
|
|
)
|
|
|
|
#define DfsRtlPutUlong(MarshalBuffer, pValue) ( \
|
|
((MarshalBuffer)->Current + sizeof(ULONG) <= (MarshalBuffer)->Last) ? \
|
|
(MarshalBuffer)->Current[0] = BYTE_0(*pValue), \
|
|
(MarshalBuffer)->Current[1] = BYTE_1(*pValue), \
|
|
(MarshalBuffer)->Current[2] = BYTE_2(*pValue), \
|
|
(MarshalBuffer)->Current[3] = BYTE_3(*pValue), \
|
|
(MarshalBuffer)->Current += 4, \
|
|
STATUS_SUCCESS \
|
|
: STATUS_BUFFER_TOO_SMALL \
|
|
)
|
|
|
|
#define DfsRtlGetGuid(MarshalBuffer, pValue) ( \
|
|
((MarshalBuffer)->Current + 16 <= (MarshalBuffer)->Last) ? \
|
|
(pValue)->Data1 = (ULONG) ((MarshalBuffer)->Current[0] ) | \
|
|
((MarshalBuffer)->Current[1] << 8) | \
|
|
((MarshalBuffer)->Current[2] << 16) | \
|
|
((MarshalBuffer)->Current[3] << 24) , \
|
|
(pValue)->Data2 = (USHORT)((MarshalBuffer)->Current[4] ) | \
|
|
((MarshalBuffer)->Current[5] << 8) , \
|
|
(pValue)->Data3 = (USHORT)((MarshalBuffer)->Current[6] ) | \
|
|
((MarshalBuffer)->Current[7] << 8) , \
|
|
memcpy((pValue)->Data4, &(MarshalBuffer)->Current[8], 8), \
|
|
(MarshalBuffer)->Current += 16, \
|
|
STATUS_SUCCESS \
|
|
: STATUS_DATA_ERROR \
|
|
)
|
|
|
|
|
|
//
|
|
// This routine is being used for DFS_UPD_REFERRAL_BUFFER. These
|
|
// routines will continue to be used in the future as well since
|
|
// we want to keep the structure of DFS_UPD_REFERRAL_BUFFER well
|
|
// defined rather than using the Marshalling routines provided here.
|
|
//
|
|
#define _PutGuid(cp, pguid) \
|
|
cp[0] = BYTE_0((pguid)->Data1), \
|
|
cp[1] = BYTE_1((pguid)->Data1), \
|
|
cp[2] = BYTE_2((pguid)->Data1), \
|
|
cp[3] = BYTE_3((pguid)->Data1), \
|
|
cp[4] = BYTE_0((pguid)->Data2), \
|
|
cp[5] = BYTE_1((pguid)->Data2), \
|
|
cp[6] = BYTE_0((pguid)->Data3), \
|
|
cp[7] = BYTE_1((pguid)->Data3), \
|
|
memcpy(&cp[8], (pguid)->Data4, 8)
|
|
|
|
|
|
#define _PutULong(cp, ularg) \
|
|
cp[0] = BYTE_0(ularg), \
|
|
cp[1] = BYTE_1(ularg), \
|
|
cp[2] = BYTE_2(ularg), \
|
|
cp[3] = BYTE_3(ularg)
|
|
|
|
|
|
#define _GetULong(cp, ularg) \
|
|
ularg = (ULONG) (cp[0]) | \
|
|
(cp[1] << 8) | \
|
|
(cp[2] << 16) | \
|
|
(cp[3] << 24)
|
|
|
|
|
|
#define DfsRtlPutGuid(MarshalBuffer, pValue) ( \
|
|
((MarshalBuffer)->Current + 16 <= (MarshalBuffer)->Last) ? \
|
|
(MarshalBuffer)->Current[0] = BYTE_0((pValue)->Data1), \
|
|
(MarshalBuffer)->Current[1] = BYTE_1((pValue)->Data1), \
|
|
(MarshalBuffer)->Current[2] = BYTE_2((pValue)->Data1), \
|
|
(MarshalBuffer)->Current[3] = BYTE_3((pValue)->Data1), \
|
|
(MarshalBuffer)->Current[4] = BYTE_0((pValue)->Data2), \
|
|
(MarshalBuffer)->Current[5] = BYTE_1((pValue)->Data2), \
|
|
(MarshalBuffer)->Current[6] = BYTE_0((pValue)->Data3), \
|
|
(MarshalBuffer)->Current[7] = BYTE_1((pValue)->Data3), \
|
|
memcpy(&(MarshalBuffer)->Current[8], (pValue)->Data4, 8), \
|
|
(MarshalBuffer)->Current += 16, \
|
|
STATUS_SUCCESS \
|
|
: STATUS_BUFFER_TOO_SMALL \
|
|
)
|
|
|
|
|
|
|
|
#define DfsRtlSizeString(pString, pSize) ( \
|
|
((pString)->Length > 0) ? ( \
|
|
((pString)->Buffer != NULL) ? \
|
|
(*(pSize)) += (2 + (pString)->Length), \
|
|
STATUS_SUCCESS \
|
|
: STATUS_DATA_ERROR \
|
|
) \
|
|
: ((*(pSize)) += 2, \
|
|
STATUS_SUCCESS) \
|
|
)
|
|
|
|
#define DfsRtlSizepwString(pString, pSize) ( \
|
|
(*pString != NULL) ? \
|
|
(*(pSize)) += ((1 + wcslen(*pString))*sizeof(WCHAR)), \
|
|
STATUS_SUCCESS \
|
|
: ((*(pSize)) += 2, \
|
|
STATUS_SUCCESS) \
|
|
)
|
|
|
|
#define DfsRtlSizeUnicodeString(pUnicodeString, pSize) \
|
|
DfsRtlSizeString(pUnicodeString, pSize)
|
|
|
|
|
|
NTSTATUS
|
|
DfsRtlGet(
|
|
IN OUT PMARSHAL_BUFFER MarshalBuffer,
|
|
IN PMARSHAL_INFO MarshalInfo,
|
|
OUT PVOID Item
|
|
);
|
|
|
|
|
|
NTSTATUS
|
|
DfsRtlPut(
|
|
IN OUT PMARSHAL_BUFFER MarshalBuffer,
|
|
IN PMARSHAL_INFO MarshalInfo,
|
|
OUT PVOID Item
|
|
);
|
|
|
|
|
|
NTSTATUS
|
|
DfsRtlSize(
|
|
IN PMARSHAL_INFO MarshalInfo,
|
|
IN PVOID Item,
|
|
OUT PULONG Size
|
|
);
|
|
|
|
VOID
|
|
DfsRtlUnwindGet(
|
|
IN PMARSHAL_INFO MarshalInfo,
|
|
IN PMARSHAL_TYPE_INFO LastTypeInfo,
|
|
IN PVOID Item
|
|
);
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Macro: POINTER_TO_OFFSET
|
|
//
|
|
// Synopsis: Some fsctls communicate via buffers that contain "pointers"
|
|
// which are really offsets from the beginning of the buffer.
|
|
// This macro converts the pointers to buffer offsets
|
|
//
|
|
// Arguments: [field] -- The field to fix up.
|
|
// [buffer] -- The beginning of the buffer.
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define POINTER_TO_OFFSET(field, buffer) \
|
|
( ((PCHAR)field) -= ((ULONG_PTR)buffer) )
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif // _DFSMRSHL_
|