Blame winpr/libwinpr/rpc/ndr_correlation.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * WinPR: Windows Portable Runtime
Packit 1fb8d4
 * Microsoft Remote Procedure Call (MSRPC)
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <stdio.h>
Packit 1fb8d4
#include <stdlib.h>
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/rpc.h>
Packit 1fb8d4
Packit 1fb8d4
#ifndef _WIN32
Packit 1fb8d4
Packit 1fb8d4
#include "ndr_correlation.h"
Packit 1fb8d4
#include "ndr_private.h"
Packit 1fb8d4
Packit 1fb8d4
/*
Packit 1fb8d4
 * Correlation Descriptors: http://msdn.microsoft.com/en-us/library/windows/desktop/aa373607/
Packit 1fb8d4
 *
Packit 1fb8d4
 * correlation_type<1>
Packit 1fb8d4
 * correlation_operator<1>
Packit 1fb8d4
 * offset<2>
Packit 1fb8d4
 * [robust_flags<2>]
Packit 1fb8d4
 *
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
PFORMAT_STRING NdrpComputeCount(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat, ULONG_PTR* pCount)
Packit 1fb8d4
{
Packit 1fb8d4
	LPVOID ptr = NULL;
Packit 1fb8d4
	ULONG_PTR data = 0;
Packit 1fb8d4
	unsigned char type;
Packit 1fb8d4
	unsigned short offset;
Packit 1fb8d4
	unsigned char conformance;
Packit 1fb8d4
	unsigned char correlation_type;
Packit 1fb8d4
	unsigned char correlation_operator;
Packit 1fb8d4
	correlation_type = pFormat[0];
Packit 1fb8d4
	type = correlation_type & 0x0F;
Packit 1fb8d4
	conformance = correlation_type & 0xF0;
Packit 1fb8d4
	correlation_operator = pFormat[1];
Packit 1fb8d4
	offset = *(unsigned short*) & pFormat[2];
Packit 1fb8d4
Packit 1fb8d4
	if (conformance == FC_NORMAL_CONFORMANCE)
Packit 1fb8d4
	{
Packit 1fb8d4
		ptr = pMemory;
Packit 1fb8d4
	}
Packit 1fb8d4
	else if (conformance == FC_POINTER_CONFORMANCE)
Packit 1fb8d4
	{
Packit 1fb8d4
		ptr = pStubMsg->Memory;
Packit 1fb8d4
	}
Packit 1fb8d4
	else if (conformance == FC_TOP_LEVEL_CONFORMANCE)
Packit 1fb8d4
	{
Packit 1fb8d4
		ptr = pStubMsg->StackTop;
Packit 1fb8d4
	}
Packit 1fb8d4
	else if (conformance == FC_CONSTANT_CONFORMANCE)
Packit 1fb8d4
	{
Packit 1fb8d4
		data = offset | ((DWORD) pFormat[1] << 16);
Packit 1fb8d4
		*pCount = data;
Packit 1fb8d4
	}
Packit 1fb8d4
	else if (conformance == FC_TOP_LEVEL_MULTID_CONFORMANCE)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (pStubMsg->StackTop)
Packit 1fb8d4
			ptr = pStubMsg->StackTop;
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
		return pFormat;
Packit 1fb8d4
Packit 1fb8d4
	switch (correlation_operator)
Packit 1fb8d4
	{
Packit 1fb8d4
		case FC_DEREFERENCE:
Packit 1fb8d4
			ptr = *(LPVOID*)((char*) ptr + offset);
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_DIV_2:
Packit 1fb8d4
			ptr = (char*) ptr + offset;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_MULT_2:
Packit 1fb8d4
			ptr = (char*) ptr + offset;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_SUB_1:
Packit 1fb8d4
			ptr = (char*) ptr + offset;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_ADD_1:
Packit 1fb8d4
			ptr = (char*) ptr + offset;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_CALLBACK:
Packit 1fb8d4
			{
Packit 1fb8d4
				WLog_ERR(TAG, "warning: NdrpComputeConformance FC_CALLBACK unimplemented");
Packit 1fb8d4
			}
Packit 1fb8d4
			break;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (!ptr)
Packit 1fb8d4
		return pFormat;
Packit 1fb8d4
Packit 1fb8d4
	switch (type)
Packit 1fb8d4
	{
Packit 1fb8d4
		case FC_LONG:
Packit 1fb8d4
			data = *(LONG*) ptr;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_ULONG:
Packit 1fb8d4
			data = *(ULONG*) ptr;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_SHORT:
Packit 1fb8d4
			data = *(SHORT*) ptr;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_USHORT:
Packit 1fb8d4
			data = *(USHORT*) ptr;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_CHAR:
Packit 1fb8d4
		case FC_SMALL:
Packit 1fb8d4
			data = *(CHAR*) ptr;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_BYTE:
Packit 1fb8d4
		case FC_USMALL:
Packit 1fb8d4
			data = *(BYTE*) ptr;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_HYPER:
Packit 1fb8d4
			data = (ULONG_PTR) *(ULONGLONG*) ptr;
Packit 1fb8d4
			break;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	switch (correlation_operator)
Packit 1fb8d4
	{
Packit 1fb8d4
		case FC_ZERO:
Packit 1fb8d4
		case FC_DEREFERENCE:
Packit 1fb8d4
			*pCount = data;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_DIV_2:
Packit 1fb8d4
			*pCount = data / 1;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_MULT_2:
Packit 1fb8d4
			*pCount = data * 1;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_SUB_1:
Packit 1fb8d4
			*pCount = data - 1;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_ADD_1:
Packit 1fb8d4
			*pCount = data + 1;
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case FC_CALLBACK:
Packit 1fb8d4
			break;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (pStubMsg->fHasNewCorrDesc)
Packit 1fb8d4
		pFormat += 6;
Packit 1fb8d4
	else
Packit 1fb8d4
		pFormat += 4;
Packit 1fb8d4
Packit 1fb8d4
	return pFormat;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
PFORMAT_STRING NdrpComputeConformance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
Packit 1fb8d4
{
Packit 1fb8d4
	return NdrpComputeCount(pStubMsg, pMemory, pFormat, &pStubMsg->MaxCount);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
PFORMAT_STRING NdrpComputeVariance(PMIDL_STUB_MESSAGE pStubMsg, unsigned char* pMemory, PFORMAT_STRING pFormat)
Packit 1fb8d4
{
Packit 1fb8d4
	ULONG_PTR ActualCount = pStubMsg->ActualCount;
Packit 1fb8d4
	pFormat = NdrpComputeCount(pStubMsg, pMemory, pFormat, &ActualCount);
Packit 1fb8d4
	pStubMsg->ActualCount = (ULONG) ActualCount;
Packit 1fb8d4
	return pFormat;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif