⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scapi.cxx

📁 Windows CE 6.0 Server 源码
💻 CXX
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++


Module Name:

    scapi.cxx

Abstract:

    Small client driver


--*/
#include <sc.hxx>
#include <scqman.hxx>
#include <scqueue.hxx>
#include <scpacket.hxx>
#include <scfile.hxx>

#include <mq.h>
#include <mqformat.h>

#include <scapi.h>

#include <scoverio.hxx>
#include <sccomp.hxx>

#include <scsrmp.hxx>
#include <scsman.hxx>
#include <psl_marshaler.hxx>

//
//	Service code section
//
void *scapi_GetOwnerProcId (void) {
	return GetCallerProcess();
}

ULONG CalcFwdRevViaSectionSize(CAPROPVARIANT *pEntry);
ULONG CalcFwdRevViaSectionSize(CDataHeader *pFwdRevEntry, DWORD *pdwElements);
BOOL  SetFwdRevViaSection(CDataHeader *pFwdRevEntry, CAPROPVARIANT *pPropVar, DWORD dwElements, 
	                      DWORD cbBufferSize, HANDLE hCallerProc, HRESULT *pHR);

static HRESULT scapi_FillQueueInfo (int iQueueLenNdx, int iQueueNdx, SCPROPVAR *pMsgProps, QUEUE_FORMAT *pqft, HANDLE hCallerProc) {
	HRESULT hRes = MQ_OK;

    CMarshallDataToProcess copyData(hCallerProc);

	if (iQueueLenNdx >= 0) {
		int ccLen = pMsgProps->aPropVar[iQueueLenNdx].ulVal;
		WCHAR *lpszQueueName = scutil_QFtoString (pqft);

		if (! lpszQueueName) {
			hRes = MQ_ERROR_INSUFFICIENT_RESOURCES;
			pMsgProps->aPropVar[iQueueLenNdx].ulVal = 0;
		} else {
			int ccLenReal = wcslen (lpszQueueName) + 1;

			pMsgProps->aPropVar[iQueueLenNdx].ulVal = ccLenReal;

			if (ccLenReal > ccLen)
				return MQ_ERROR_BUFFER_OVERFLOW;

			if ((iQueueNdx >= 0) && (ccLenReal > 0)) {
				copyData.WriteStrToProc(pMsgProps->aPropVar[iQueueNdx].pwszVal,
                                              lpszQueueName,ccLenReal,&hRes);
			}

			g_funcFree (lpszQueueName, g_pvFreeData);
		}
	} else if (iQueueNdx >= 0)
		hRes = MQ_ERROR_PROPERTY;

	if ((iQueueNdx >= 0) && (pMsgProps->aStatus))
		pMsgProps->aStatus[iQueueNdx] = hRes;

	return hRes;
}

// Fills in PROPVARIANT related to array (VT_UI | VT_VECTOR) types on  
// retrieving message.
static HRESULT scapi_FillArrayInfo(int iDataLenNdx, int iDataNdx, SCPROPVAR *pMsgProps,
                                  const UCHAR *pData, DWORD cbActualDataLen, HANDLE hCallerProc)
{
    // Fill in the length of this data, i.e. in the PROPID_M_FIELD_SIZE
	if (iDataLenNdx >= 0) {
        SVSUTIL_ASSERT(pMsgProps->aPropVar[iDataLenNdx].vt == VT_UI4);
		pMsgProps->aPropVar[iDataLenNdx].ulVal = cbActualDataLen;
	}

    // Fill out the data itself, i.e. the PROPID_M_FIELD
	if (iDataNdx >= 0) {
        DWORD cbAppDataLen = pMsgProps->aPropVar[iDataNdx].caub.cElems;
        if (cbAppDataLen < cbActualDataLen)
			return MQ_ERROR_BUFFER_OVERFLOW;

        HRESULT hRes = MQ_OK;

        if (cbActualDataLen > 0) {
            CMarshallDataToProcess copyData(hCallerProc);
            copyData.WriteBufToProc(pMsgProps->aPropVar[iDataNdx].caub.pElems,
                                    pData,cbActualDataLen,&hRes);
        }
        return hRes;
	}

    return MQ_OK;
}

// Fills in PROPVARIANT info related to a LPWSTR type
static HRESULT scapi_FillStringInfo(int iDataLenNdx, int iDataNdx, SCPROPVAR *pMsgProps,
                                    const WCHAR *szData, DWORD ccActualDataLen, HANDLE hCallerProc)
{
	ULONG ccAppDataLen = (iDataLenNdx < 0) ? 0 : pMsgProps->aPropVar[iDataLenNdx].ulVal;
	if (iDataLenNdx >= 0) {
		SVSUTIL_ASSERT(pMsgProps->aPropVar[iDataLenNdx].vt == VT_UI4);
		pMsgProps->aPropVar[iDataLenNdx].ulVal = ccActualDataLen;
	}

	if (iDataNdx >= 0 && szData) {
		if (ccAppDataLen < ccActualDataLen)
			return MQ_ERROR_BUFFER_OVERFLOW;

        HRESULT hRes = MQ_OK;

        if (ccActualDataLen > 0) {
    		CMarshallDataToProcess copyData(hCallerProc);
		    copyData.WriteStrToProc(pMsgProps->aPropVar[iDataNdx].pwszVal,
		                        szData,ccActualDataLen,&hRes);
        }
		return hRes;
	}

    return MQ_OK;
}

static HRESULT scapi_GetPacket
(
SCHANDLE			hQueue,
SCHANDLE			hCursor,
DWORD				dwAction,
ScPacket			*&pPacket,
ScQueue				*&pQueue,
ScHandleInfo		*&pHInfo
) {
	SVSUTIL_ASSERT (gMem->IsLocked ());

	pPacket = NULL;
	pQueue  = NULL;
	pHInfo  = NULL;

	int	fDefaultCursor = ((SVSHandle)hCursor == SVSUTIL_HANDLE_INVALID);

	ScHandleInfo *pQueueHInfo = gQueueMan->QueryHandle ((SVSHandle)hQueue);

	if ((! pQueueHInfo) || (pQueueHInfo->uiHandleType != SCQMAN_HANDLE_QUEUE))
		return MQ_ERROR_INVALID_HANDLE;

	if (((pQueueHInfo->q.uiAccess != MQ_RECEIVE_ACCESS) && (pQueueHInfo->q.uiAccess != MQ_PEEK_ACCESS)) ||
		((pQueueHInfo->q.uiAccess != MQ_RECEIVE_ACCESS) && (dwAction == MQ_ACTION_RECEIVE)))
		return MQ_ERROR_ACCESS_DENIED;

	pQueue = pQueueHInfo->pQueue;

	if  (fDefaultCursor)
		hCursor = (SCHANDLE)pQueueHInfo->q.hDefaultCursor;

	pHInfo = gQueueMan->QueryHandle ((SVSHandle)hCursor);

	if ((! pHInfo) || (pHInfo->uiHandleType != SCQMAN_HANDLE_CURSOR) || (pHInfo->pQueue != pQueue)) {
		pHInfo = NULL;
		pQueue = NULL;

		return MQ_ERROR_INVALID_HANDLE;
	}

	if (! pHInfo->c.fPosValid) {
		if ((dwAction == MQ_ACTION_PEEK_NEXT) || (dwAction == MQ_ACTION_PEEK_PREV)) {
			pQueue = NULL;
			pHInfo = NULL;

			return MQ_ERROR_ILLEGAL_CURSOR_ACTION;
		}

		if (fDefaultCursor)
			pQueue->Reset (pHInfo);

		if (! pQueue->Advance (pHInfo)) {
			pHInfo = NULL;

			return MQ_OK;
		}

		pHInfo->c.fPosValid = TRUE;
	} else {
		int fSuccess = TRUE;
		if ((dwAction == MQ_ACTION_RECEIVE) || (dwAction == MQ_ACTION_PEEK_CURRENT)) {
			if (fDefaultCursor) {
				pQueue->Reset (pHInfo);

				if (! pQueue->Advance (pHInfo)) {
					pHInfo = NULL;

					return MQ_OK;
				}
			}

			ScPacket *pCandidate = (ScPacket *)SVSTree::GetData(pHInfo->c.pNode);
			if (! ((pCandidate->uiPacketState == SCPACKET_STATE_ALIVE) && did_not_expire (pCandidate->tExpirationTime, scutil_now ()))) {
				pQueue = NULL;
				pHInfo = NULL;

				return MQ_ERROR_MESSAGE_ALREADY_RECEIVED;
			}
		} else if (fDefaultCursor) {
			pQueue = NULL;
			pHInfo = NULL;

			return MQ_ERROR_ILLEGAL_CURSOR_ACTION;
		} else if (dwAction == MQ_ACTION_PEEK_NEXT)
			fSuccess = pQueue->Advance (pHInfo);
		else if (dwAction == MQ_ACTION_PEEK_PREV)
			fSuccess = pQueue->Backup (pHInfo);

		if (! fSuccess) {
			pHInfo = NULL;
			return MQ_OK;
		}
	}

	SVSUTIL_ASSERT (pHInfo->c.pNode);

	pPacket = (ScPacket *)SVSTree::GetData(pHInfo->c.pNode);

	return MQ_OK;
}

// Helpers to set PROPVARIANT simple types

inline BOOL SetUI1(PROPVARIANT *pProp, BYTE valueToSet)  {
    if (pProp->vt != VT_UI1)
        return FALSE;

    pProp->bVal = valueToSet;
    return TRUE;
}

inline BOOL SetUI2(PROPVARIANT *pProp, USHORT valueToSet)  {
    if (pProp->vt != VT_UI2)
        return FALSE;

    pProp->uiVal = valueToSet;
    return TRUE;
}

inline BOOL SetUI4(PROPVARIANT *pProp, ULONG valueToSet) {
    if (pProp->vt != VT_UI4)
        return FALSE;

    pProp->ulVal = valueToSet;
    return TRUE;
}

inline BOOL VerifyString(PROPVARIANT *pProp) {
    if ((pProp->vt != VT_LPWSTR) || (! pProp->pwszVal))
        return FALSE;

    return TRUE;
}

inline BOOL SetStringIndex(PROPVARIANT *pProp, int iIndexToSet, int *piIndex) {
    if (! VerifyString(pProp))
        return FALSE;

    *piIndex = iIndexToSet;
    return TRUE;
}

inline BOOL VerifyGuid(PROPVARIANT *pProp) {
    if ((pProp->vt != VT_CLSID) || (pProp->puuid == NULL))
        return FALSE;

    return TRUE;
}

inline BOOL SetLengthIndex(PROPVARIANT *pProp, int iIndexToSet, int *piIndex) {
    if (pProp->vt != VT_UI4)
        return FALSE;

    *piIndex = iIndexToSet;
    return TRUE;
}

inline BOOL SetArrayPtrIndex(PROPVARIANT *pProp, int iIndexToSet, int *piIndex) {
    if ((pProp->vt != (VT_VECTOR | VT_UI1)) ||
        (pProp->caub.cElems <= 0))
        return FALSE;

    *piIndex = iIndexToSet;
    return TRUE;
}

inline BOOL VerifyArrayPtr(PROPVARIANT *pProp, DWORD sizeRequired) {
    if ((pProp->vt != (VT_VECTOR | VT_UI1)) ||
        (pProp->caub.cElems != sizeRequired) ||
        (pProp->caub.pElems == NULL))
        return FALSE;

    return TRUE;

}

inline BOOL SetVariantArrayPtrIndex(PROPVARIANT *pProp, int iIndexToSet, int *piIndex) {
    if (pProp->vt != (VT_VECTOR | VT_VARIANT))
        return FALSE;

    *piIndex = iIndexToSet;
    return TRUE;
}

// Note: This function is called with the global lock held and in a __try/_except block.
static HRESULT scapi_RetrievePacketInfo
(
ScPacket		*pPacket,
ScQueue			*pQueue,
ScHandleInfo	*pHInfo,
DWORD			dwAction,
ce::copy_in<SCPROPVAR*> *pMsgPropsA,
HANDLE			hCallerProc
) {
	SVSUTIL_ASSERT (pPacket && pHInfo);
	SVSUTIL_ASSERT (gMem->IsLocked ());

	SCPROPVAR* pMsgProps = *pMsgPropsA;

    CMarshallDataToProcess copyData(hCallerProc);

    static const WCHAR szEmpty[] = L"";

#if defined (SC_VERBOSE)
	scerror_DebugOut (VERBOSE_MASK_IO, L"Got a message!\n");
#endif
	//
	//	pPacket is here, the queue is locked and the cursor handle pointer is in pHInfo...
	//
	HRESULT hRes = MQ_OK;

	//
	//	Restore packet's image if necessary
	//
	if (! pQueue->BringToMemory (pPacket))
		return MQ_ERROR;

	SVSUTIL_ASSERT (pPacket->pImage && pPacket->pImage->sect.pBaseHeader && pPacket->pImage->sect.pUserHeader && pPacket->pImage->sect.pPropHeader);

	SVSUTIL_ASSERT (pPacket->uiAuditType == pPacket->pImage->sect.pUserHeader->GetAuditing ());
	SVSUTIL_ASSERT (pPacket->uiPacketState == SCPACKET_STATE_ALIVE);
	SVSUTIL_ASSERT (pPacket->uiAckType == pPacket->pImage->sect.pPropHeader->GetAckType ());

	if (pMsgProps->aStatus && pMsgProps->cProp > 0)
		memset (pMsgProps->aStatus, 0, sizeof (HRESULT) * pMsgProps->cProp);

	int iAdminQueueNdx     = -1;
	int iAdminQueueLenNdx  = -1;
	int iBodyNdx		   = -1;
	int iBodySizeNdx	   = -1;
	int iDestQueueNdx      = -1;
	int iDestQueueLenNdx   = -1;
	int iExtNdx			   = -1;
	int iExtSizeNdx        = -1;
	int iLabelNdx		   = -1;
	int iLabelLenNdx       = -1;
	int iRespQueueNdx      = -1;
	int iRespQueueLenNdx   = -1;
	int iSoapEnvNdx        = -1;
	int iSoapEnvLenNdx     = -1;
	int iCompoundMsgNdx    = -1;
	int iCompoundMsgLenNdx = -1;
	int iSoapFwdViaNdx     = -1;
	int iSoapFwdViaLenNdx  = -1;
	int iSoapRevViaNdx     = -1;
	int iSoapRevViaLenNdx  = -1;
	int iSoapFromNdx       = -1;
	int iSoapFromLenNdx    = -1;
	int iSoapRelatesToNdx    = -1;
	int iSoapRelatesToLenNdx = -1;

	CCompoundMessageHeader *pCompoundMessage = pPacket->pImage->sect.pUserHeader->SrmpIsIncluded() ? pPacket->pImage->sect.pCompoundMessageHeader : NULL;

    // Validate that parameters are legal.
	for (int i = 0 ; (! FAILED (hRes)) && (i < (int)pMsgProps->cProp) ; ++i) {
		hRes = MQ_OK;
        PROPVARIANT *pProp = &pMsgProps->aPropVar[i];

		switch (pMsgProps->aPropID[i]) {
		case PROPID_M_ACKNOWLEDGE:
            if (! SetUI1(pProp,pPacket->pImage->sect.pPropHeader->GetAckType()))
				hRes = MQ_ERROR_ILLEGAL_PROPERTY_VALUE;
			break;

		case PROPID_M_ADMIN_QUEUE:
            if (! SetStringIndex(pProp,i,&iAdminQueueNdx))
				hRes = MQ_ERROR_ILLEGAL_PROPERTY_VT;
			break;

		case PROPID_M_ADMIN_QUEUE_LEN:
            if (! SetLengthIndex(pProp,i,&iAdminQueueLenNdx))
				hRes = MQ_ERROR_ILLEGAL_PROPERTY_VALUE;
			break;

		case PROPID_M_APPSPECIFIC:
			if (! SetUI4(pProp,pPacket->pImage->sect.pPropHeader->GetApplicationTag()))
				hRes = MQ_ERROR_ILLEGAL_PROPERTY_VT;
			break;

		case PROPID_M_AUTH_LEVEL:
            if (! SetUI4(pProp,MQMSG_AUTH_LEVEL_NONE))
				hRes = MQ_ERROR_ILLEGAL_PROPERTY_VT;
			break;

		case PROPID_M_BODY:
            if (! SetArrayPtrIndex(pProp, i, &iBodyNdx))
				hRes = MQ_ERROR_ILLEGAL_PROPERTY_VALUE;
			break;

		case PROPID_M_BODY_SIZE:
            if (! SetLengthIndex(pProp,i,&iBodySizeNdx))
				hRes = MQ_ERROR_ILLEGAL_PROPERTY_VALUE;
			break;

		case PROPID_M_BODY_TYPE:
            if (! SetUI4(pProp,pPacket->pImage->sect.pPropHeader->GetBodyType ()))
				hRes = MQ_ERROR_ILLEGAL_PROPERTY_VT;
			break;

		case PROPID_M_CLASS:
            if (! SetUI2(pProp,pPacket->pImage->sect.pPropHeader->GetClass ()))
				hRes = MQ_ERROR_ILLEGAL_PROPERTY_VALUE;
			break;

		case PROPID_M_CORRELATIONID:
            if (! VerifyArrayPtr(pProp,PROPID_M_CORRELATIONID_SIZE))
				hRes = MQ_ERROR_ILLEGAL_PROPERTY_VALUE;

            copyData.WriteBufToProc(pProp->caub.pElems, 
                    pPacket->pImage->sect.pPropHeader->GetCorrelationID(), 
                    PROPID_M_CORRELATIONID_SIZE,&hRes);

			break;

		case PROPID_M_DELIVERY:
            if (! SetUI1(pProp,pPacket->pImage->sect.pUserHeader->GetDelivery ()))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -