Blame winpr/libwinpr/rpc/ndr_structure.c

Packit Service fa4841
/**
Packit Service fa4841
 * WinPR: Windows Portable Runtime
Packit Service fa4841
 * Microsoft Remote Procedure Call (MSRPC)
Packit Service fa4841
 *
Packit Service fa4841
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit Service fa4841
 *
Packit Service fa4841
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit Service fa4841
 * you may not use this file except in compliance with the License.
Packit Service fa4841
 * You may obtain a copy of the License at
Packit Service fa4841
 *
Packit Service fa4841
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit Service fa4841
 *
Packit Service fa4841
 * Unless required by applicable law or agreed to in writing, software
Packit Service fa4841
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit Service fa4841
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit Service fa4841
 * See the License for the specific language governing permissions and
Packit Service fa4841
 * limitations under the License.
Packit Service fa4841
 */
Packit Service fa4841
Packit Service fa4841
#ifdef HAVE_CONFIG_H
Packit Service fa4841
#include "config.h"
Packit Service fa4841
#endif
Packit Service fa4841
Packit Service fa4841
#include <stdio.h>
Packit Service fa4841
#include <stdlib.h>
Packit Service fa4841
Packit Service fa4841
#include <winpr/rpc.h>
Packit Service fa4841
Packit Service fa4841
#ifndef _WIN32
Packit Service fa4841
Packit Service fa4841
#include "ndr_private.h"
Packit Service fa4841
#include "ndr_pointer.h"
Packit Service fa4841
#include "ndr_structure.h"
Packit Service fa4841
Packit Service fa4841
/* Structures: http://msdn.microsoft.com/en-us/library/windows/desktop/aa378695/ */
Packit Service fa4841
Packit Service fa4841
void NdrSimpleStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
Packit Service fa4841
                               PFORMAT_STRING pFormat)
Packit Service fa4841
{
Packit Service fa4841
	/**
Packit Service fa4841
	 * FC_STRUCT
Packit Service fa4841
	 * alignment<1>
Packit Service fa4841
	 * memory_size<2>
Packit Service fa4841
	 * member_layout<>
Packit Service fa4841
	 * FC_END
Packit Service fa4841
	 */
Packit Service fa4841
	/**
Packit Service fa4841
	 * FC_PSTRUCT
Packit Service fa4841
	 * alignment<1>
Packit Service fa4841
	 * memory_size<2>
Packit Service fa4841
	 * pointer_layout<>
Packit Service fa4841
	 * member_layout<>
Packit Service fa4841
	 * FC_END
Packit Service fa4841
	 */
Packit Service fa4841
	unsigned char type;
Packit Service fa4841
	unsigned char alignment;
Packit Service fa4841
	unsigned short memory_size;
Packit Service fa4841
	type = pFormat[0];
Packit Service fa4841
	alignment = pFormat[1] + 1;
Packit Service fa4841
	memory_size = *(unsigned short*)&pFormat[2];
Packit Service fa4841
	NdrpAlignLength(&(pStubMsg->BufferLength), alignment);
Packit Service fa4841
	NdrpIncrementLength(&(pStubMsg->BufferLength), memory_size);
Packit Service fa4841
	pFormat += 4;
Packit Service fa4841
Packit Service fa4841
	if (*pFormat == FC_PSTRUCT)
Packit Service fa4841
		NdrpEmbeddedPointerBufferSize(pStubMsg, pMemory, pFormat);
Packit Service fa4841
Packit Service fa4841
	WLog_ERR(TAG, "warning: NdrSimpleStructBufferSize unimplemented");
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
void NdrConformantStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
Packit Service fa4841
                                   PFORMAT_STRING pFormat)
Packit Service fa4841
{
Packit Service fa4841
	/**
Packit Service fa4841
	 * FC_CSTRUCT alignment<1>
Packit Service fa4841
	 * memory_size<2>
Packit Service fa4841
	 * offset_to_array_description<2>
Packit Service fa4841
	 * member_layout<>
Packit Service fa4841
	 * FC_END
Packit Service fa4841
	 */
Packit Service fa4841
	/**
Packit Service fa4841
	 * FC_CPSTRUCT alignment<1>
Packit Service fa4841
	 * memory_size<2>
Packit Service fa4841
	 * offset_to_array_description<2>
Packit Service fa4841
	 * pointer_layout<>
Packit Service fa4841
	 * member_layout<> FC_END
Packit Service fa4841
	 */
Packit Service fa4841
	WLog_ERR(TAG, "warning: NdrConformantStructBufferSize unimplemented");
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
void NdrConformantVaryingStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
Packit Service fa4841
                                          PFORMAT_STRING pFormat)
Packit Service fa4841
{
Packit Service fa4841
	/**
Packit Service fa4841
	 * FC_CVSTRUCT alignment<1>
Packit Service fa4841
	 * memory_size<2>
Packit Service fa4841
	 * offset_to_array_description<2>
Packit Service fa4841
	 * [pointer_layout<>]
Packit Service fa4841
	 * layout<>
Packit Service fa4841
	 * FC_END
Packit Service fa4841
	 */
Packit Service fa4841
	WLog_ERR(TAG, "warning: NdrConformantVaryingStructBufferSize unimplemented");
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
static ULONG NdrComplexStructMemberSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat)
Packit Service fa4841
{
Packit Service fa4841
	ULONG size = 0;
Packit Service fa4841
Packit Service fa4841
	while (*pFormat != FC_END)
Packit Service fa4841
	{
Packit Service fa4841
		switch (*pFormat)
Packit Service fa4841
		{
Packit Service fa4841
			case FC_BYTE:
Packit Service fa4841
			case FC_CHAR:
Packit Service fa4841
			case FC_SMALL:
Packit Service fa4841
			case FC_USMALL:
Packit Service fa4841
				size += sizeof(BYTE);
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_WCHAR:
Packit Service fa4841
			case FC_SHORT:
Packit Service fa4841
			case FC_USHORT:
Packit Service fa4841
			case FC_ENUM16:
Packit Service fa4841
				size += sizeof(USHORT);
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_LONG:
Packit Service fa4841
			case FC_ULONG:
Packit Service fa4841
			case FC_ENUM32:
Packit Service fa4841
				size += sizeof(ULONG);
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_INT3264:
Packit Service fa4841
			case FC_UINT3264:
Packit Service fa4841
				size += sizeof(INT_PTR);
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_FLOAT:
Packit Service fa4841
				size += sizeof(FLOAT);
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_DOUBLE:
Packit Service fa4841
				size += sizeof(DOUBLE);
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_HYPER:
Packit Service fa4841
				size += sizeof(ULONGLONG);
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_ERROR_STATUS_T:
Packit Service fa4841
				size += sizeof(error_status_t);
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_IGNORE:
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_RP:
Packit Service fa4841
			case FC_UP:
Packit Service fa4841
			case FC_OP:
Packit Service fa4841
			case FC_FP:
Packit Service fa4841
			case FC_POINTER:
Packit Service fa4841
				size += sizeof(void*);
Packit Service fa4841
Packit Service fa4841
				if (*pFormat != FC_POINTER)
Packit Service fa4841
					pFormat += 4;
Packit Service fa4841
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_ALIGNM2:
Packit Service fa4841
				NdrpAlignLength(&size, 2);
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_ALIGNM4:
Packit Service fa4841
				NdrpAlignLength(&size, 4);
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_ALIGNM8:
Packit Service fa4841
				NdrpAlignLength(&size, 8);
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_STRUCTPAD1:
Packit Service fa4841
			case FC_STRUCTPAD2:
Packit Service fa4841
			case FC_STRUCTPAD3:
Packit Service fa4841
			case FC_STRUCTPAD4:
Packit Service fa4841
			case FC_STRUCTPAD5:
Packit Service fa4841
			case FC_STRUCTPAD6:
Packit Service fa4841
			case FC_STRUCTPAD7:
Packit Service fa4841
				size += *pFormat - FC_STRUCTPAD1 + 1;
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_PAD:
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			case FC_EMBEDDED_COMPLEX:
Packit Service fa4841
				WLog_ERR(TAG,
Packit Service fa4841
				         "warning: NdrComplexStructMemberSize FC_EMBEDDED_COMPLEX unimplemented");
Packit Service fa4841
				break;
Packit Service fa4841
Packit Service fa4841
			default:
Packit Service fa4841
				WLog_ERR(TAG, "warning: NdrComplexStructMemberSize 0x%02X unimplemented", *pFormat);
Packit Service fa4841
				break;
Packit Service fa4841
		}
Packit Service fa4841
Packit Service fa4841
		pFormat++;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	return size;
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
void NdrComplexStructBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory,
Packit Service fa4841
                                PFORMAT_STRING pFormat)
Packit Service fa4841
{
Packit Service fa4841
	/**
Packit Service fa4841
	 * FC_BOGUS_STRUCT
Packit Service fa4841
	 * alignment<1>
Packit Service fa4841
	 * memory_size<2>
Packit Service fa4841
	 * offset_to_conformant_array_description<2>
Packit Service fa4841
	 * offset_to_pointer_layout<2>
Packit Service fa4841
	 * member_layout<>
Packit Service fa4841
	 * FC_END
Packit Service fa4841
	 * [pointer_layout<>]
Packit Service fa4841
	 */
Packit Service fa4841
	ULONG_PTR MaxCount;
Packit Service fa4841
	unsigned long Offset;
Packit Service fa4841
	unsigned long ActualCount;
Packit Service fa4841
	unsigned char* pMemoryCopy;
Packit Service fa4841
	unsigned char type;
Packit Service fa4841
	unsigned char alignment;
Packit Service fa4841
	unsigned short memory_size;
Packit Service fa4841
	unsigned char* pointer_layout;
Packit Service fa4841
	unsigned char* conformant_array_description;
Packit Service fa4841
	unsigned short offset_to_pointer_layout;
Packit Service fa4841
	unsigned short offset_to_conformant_array_description;
Packit Service fa4841
	type = pFormat[0];
Packit Service fa4841
	pMemoryCopy = pMemory;
Packit Service fa4841
	pointer_layout = conformant_array_description = NULL;
Packit Service fa4841
Packit Service fa4841
	if (type != FC_BOGUS_STRUCT)
Packit Service fa4841
	{
Packit Service fa4841
		WLog_ERR(TAG, "error: expected FC_BOGUS_STRUCT, got 0x%02X", type);
Packit Service fa4841
		return;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	alignment = pFormat[1] + 1;
Packit Service fa4841
	memory_size = *(unsigned short*)&pFormat[2];
Packit Service fa4841
	NdrpAlignLength(&(pStubMsg->BufferLength), alignment);
Packit Service fa4841
Packit Service fa4841
	if (!pStubMsg->IgnoreEmbeddedPointers && !pStubMsg->PointerLength)
Packit Service fa4841
	{
Packit Service fa4841
		unsigned long BufferLengthCopy = pStubMsg->BufferLength;
Packit Service fa4841
		int IgnoreEmbeddedPointersCopy = pStubMsg->IgnoreEmbeddedPointers;
Packit Service fa4841
		pStubMsg->IgnoreEmbeddedPointers = 1;
Packit Service fa4841
		NdrComplexStructBufferSize(pStubMsg, pMemory, pFormat);
Packit Service fa4841
		pStubMsg->IgnoreEmbeddedPointers = IgnoreEmbeddedPointersCopy;
Packit Service fa4841
		pStubMsg->PointerLength = pStubMsg->BufferLength;
Packit Service fa4841
		pStubMsg->BufferLength = BufferLengthCopy;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	pFormat += 4;
Packit Service fa4841
	offset_to_conformant_array_description = *(unsigned short*)&pFormat[0];
Packit Service fa4841
Packit Service fa4841
	if (offset_to_conformant_array_description)
Packit Service fa4841
		conformant_array_description =
Packit Service fa4841
		    (unsigned char*)pFormat + offset_to_conformant_array_description;
Packit Service fa4841
Packit Service fa4841
	pFormat += 2;
Packit Service fa4841
	offset_to_pointer_layout = *(unsigned short*)&pFormat[0];
Packit Service fa4841
Packit Service fa4841
	if (offset_to_pointer_layout)
Packit Service fa4841
		pointer_layout = (unsigned char*)pFormat + offset_to_pointer_layout;
Packit Service fa4841
Packit Service fa4841
	pFormat += 2;
Packit Service fa4841
	pStubMsg->Memory = pMemory;
Packit Service fa4841
Packit Service fa4841
	if (conformant_array_description)
Packit Service fa4841
	{
Packit Service fa4841
		ULONG size;
Packit Service fa4841
		unsigned char array_type;
Packit Service fa4841
		array_type = conformant_array_description[0];
Packit Service fa4841
		size = NdrComplexStructMemberSize(pStubMsg, pFormat);
Packit Service fa4841
		WLog_ERR(TAG, "warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented",
Packit Service fa4841
		         array_type);
Packit Service fa4841
		NdrpComputeConformance(pStubMsg, pMemory + size, conformant_array_description);
Packit Service fa4841
		NdrpComputeVariance(pStubMsg, pMemory + size, conformant_array_description);
Packit Service fa4841
		MaxCount = pStubMsg->MaxCount;
Packit Service fa4841
		ActualCount = pStubMsg->ActualCount;
Packit Service fa4841
		Offset = pStubMsg->Offset;
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	if (conformant_array_description)
Packit Service fa4841
	{
Packit Service fa4841
		unsigned char array_type;
Packit Service fa4841
		array_type = conformant_array_description[0];
Packit Service fa4841
		pStubMsg->MaxCount = MaxCount;
Packit Service fa4841
		pStubMsg->ActualCount = ActualCount;
Packit Service fa4841
		pStubMsg->Offset = Offset;
Packit Service fa4841
		WLog_ERR(TAG, "warning: NdrComplexStructBufferSize array_type: 0x%02X unimplemented",
Packit Service fa4841
		         array_type);
Packit Service fa4841
	}
Packit Service fa4841
Packit Service fa4841
	pStubMsg->Memory = pMemoryCopy;
Packit Service fa4841
Packit Service fa4841
	if (pStubMsg->PointerLength > 0)
Packit Service fa4841
	{
Packit Service fa4841
		pStubMsg->BufferLength = pStubMsg->PointerLength;
Packit Service fa4841
		pStubMsg->PointerLength = 0;
Packit Service fa4841
	}
Packit Service fa4841
}
Packit Service fa4841
Packit Service fa4841
#endif