📄 scapi.cxx
字号:
//
// 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 + -