windows-nt/Source/XPSP1/NT/base/fs/dfs/h/dfsmrshl.h
2020-09-26 16:20:57 +08:00

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_