📄 scutil.cxx
字号:
a_pqp->bIsIncoming = bIsIncoming;
a_pqp->bIsPublic = bIsPublic;
return TRUE;
}
WCHAR *scutil_MakePathName (WCHAR *a_lpszHostName, WCHAR *a_lpszQueueName, ScQueueParms *a_pqp) {
SVSUTIL_ASSERT (a_lpszHostName && a_lpszQueueName && a_pqp);
int ccHostLen = wcslen(a_lpszHostName);
int ccQueueLen = wcslen (a_lpszQueueName);
int ccPrivateTag = a_pqp->bIsPublic ? 0 : SVSUTIL_CONSTSTRLEN(MSMQ_SC_PATHNAME_PRIVATE) + 1;
int iSz = (ccHostLen + ccQueueLen + 2 + ccPrivateTag) * sizeof(WCHAR);
WCHAR chPathSeparator = ((a_pqp->bFormatType == SCFILE_QP_FORMAT_HTTP) || (a_pqp->bFormatType == SCFILE_QP_FORMAT_HTTPS)) ? L'/' : L'\\';
WCHAR *lpszPathName = (WCHAR *)g_funcAlloc (iSz, g_pvAllocData);
memcpy (lpszPathName, a_lpszHostName, sizeof(WCHAR) * ccHostLen);
lpszPathName[ccHostLen] = chPathSeparator;
if (ccPrivateTag) {
memcpy (&lpszPathName[ccHostLen+1], MSMQ_SC_PATHNAME_PRIVATE, sizeof (WCHAR) * SVSUTIL_CONSTSTRLEN(MSMQ_SC_PATHNAME_PRIVATE));
lpszPathName[ccHostLen + 1 + SVSUTIL_CONSTSTRLEN(MSMQ_SC_PATHNAME_PRIVATE)] = chPathSeparator;
}
memcpy (&lpszPathName[ccHostLen + 1 + ccPrivateTag], a_lpszQueueName, sizeof(WCHAR) * (ccQueueLen + 1));
return lpszPathName;
}
WCHAR *scutil_MakeFileName (WCHAR *a_lpszQueueHost, WCHAR *a_lpszQueueName, ScQueueParms *a_pqp) {
SVSUTIL_ASSERT (a_lpszQueueHost && a_lpszQueueName && a_pqp);
if (a_pqp->bIsIncoming)
a_lpszQueueHost = MSMQ_SC_LOCALHOST;
WCHAR *lpszFileExt = (! a_pqp->bIsIncoming) ? MSMQ_SC_EXT_OQ :
(a_pqp->bIsJournal ? MSMQ_SC_EXT_JQ :
(a_pqp->bIsMachineJournal ? MSMQ_SC_EXT_MJ : MSMQ_SC_EXT_IQ));
int ccDirLen = wcslen(gMachine->lpszDirName);
int ccQueueLen = wcslen(a_lpszQueueName);
int ccHostLen = wcslen(a_lpszQueueHost);
int ccPublicToken = a_pqp->bIsPublic ? SVSUTIL_CONSTSTRLEN (MSMQ_SC_FILENAME_PUBLIC) : 0;
int ccHttpToken = 0;
if (a_pqp->bFormatType == SCFILE_QP_FORMAT_HTTP)
ccHttpToken = SVSUTIL_CONSTSTRLEN(MSMQ_SC_FILENAME_HTTP);
else if (a_pqp->bFormatType == SCFILE_QP_FORMAT_HTTPS)
ccHttpToken = SVSUTIL_CONSTSTRLEN(MSMQ_SC_FILENAME_HTTPS);
int ccFileName = ccDirLen + ccHostLen + ccQueueLen + ccPublicToken + ccHttpToken + wcslen(lpszFileExt) + 2 + 3;
WCHAR *lpszFileName = (WCHAR *)g_funcAlloc (ccFileName * sizeof(WCHAR), g_pvAllocData);
if (lpszFileName==NULL)
return NULL;
memcpy (lpszFileName, gMachine->lpszDirName, sizeof(WCHAR) * ccDirLen);
lpszFileName[ccDirLen] = L'\\';
memcpy (lpszFileName + ccDirLen + 1, a_lpszQueueHost, sizeof(WCHAR) * ccHostLen);
lpszFileName[ccDirLen + ccHostLen + 1] = L' ';
lpszFileName[ccDirLen + ccHostLen + 2] = L'-';
lpszFileName[ccDirLen + ccHostLen + 3] = L' ';
if (ccPublicToken)
memcpy (lpszFileName + ccDirLen + ccHostLen + 4, MSMQ_SC_FILENAME_PUBLIC, sizeof(MSMQ_SC_FILENAME_PUBLIC));
if (a_pqp->bFormatType == SCFILE_QP_FORMAT_HTTP)
memcpy (lpszFileName + ccDirLen + ccPublicToken + ccHostLen + 4, MSMQ_SC_FILENAME_HTTP, sizeof(WCHAR) * ccHttpToken);
else if (a_pqp->bFormatType == SCFILE_QP_FORMAT_HTTPS)
memcpy (lpszFileName + ccDirLen + ccPublicToken + ccHostLen + 4, MSMQ_SC_FILENAME_HTTPS, sizeof(WCHAR) * ccHttpToken);
memcpy (lpszFileName + ccDirLen + ccPublicToken + ccHttpToken + ccHostLen + 4, a_lpszQueueName, sizeof(WCHAR) * ccQueueLen);
wcscpy (lpszFileName + ccDirLen + ccPublicToken + ccHttpToken + ccHostLen + ccQueueLen + 4, lpszFileExt);
WCHAR *p = lpszFileName + ccDirLen + ccPublicToken + ccHttpToken + ccHostLen + 4;
while (*p) {
if ((*p == '\\') || (*p == '/'))
*p = '_';
++p;
}
return lpszFileName;
}
WCHAR *scutil_QFtoString (QUEUE_FORMAT *pqft) {
WCHAR szBuffer[_MAX_PATH];
ULONG ulSize = 0;
NTSTATUS nts = MQpQueueFormatToFormatName(pqft, szBuffer, _MAX_PATH, &ulSize);
if (nts == MQ_OK)
return svsutil_wcsdup (szBuffer);
if (nts == MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL) {
WCHAR *lpRes = (WCHAR *)g_funcAlloc (ulSize * sizeof (WCHAR), g_pvAllocData);
if (! lpRes)
return NULL;
if (MQ_OK == MQpQueueFormatToFormatName(pqft, lpRes, ulSize, &ulSize))
return lpRes;
g_funcFree (lpRes, g_pvFreeData);
}
return NULL;
}
/*++
Abstract:
Format Name parsing.
QUEUE_FORMAT <--> Format Name String conversion routines
--*/
//=========================================================
//
// Format Name String -> QUEUE_FORMAT conversion routines
//
//=========================================================
//---------------------------------------------------------
//
// Skip white space characters, return next non ws char
//
// N.B. if no white space is needed uncomment next line
//#define skip_ws(p) (p)
inline LPCWSTR skip_ws(LPCWSTR p)
{
//
// Don't skip first non white space
//
while(iswspace(*p))
{
++p;
}
return p;
}
//---------------------------------------------------------
//
// Skip white space characters, return next non ws char
//
inline LPCWSTR FindPathNameDelimiter(LPCWSTR p)
{
return wcschr(p, PN_DELIMITER_C);
}
//---------------------------------------------------------
//
// Parse Format Name Type prefix string.
// Return next char to parse on success, 0 on failure.
//
static LPCWSTR ParsePrefixString(LPCWSTR p, QUEUE_FORMAT_TYPE& qft)
{
const int unique = 1;
//----------------0v-------------------------
ASSERT(L'U' == FN_PUBLIC_TOKEN [unique]);
ASSERT(L'R' == FN_PRIVATE_TOKEN [unique]);
ASSERT(L'O' == FN_CONNECTOR_TOKEN [unique]);
ASSERT(L'A' == FN_MACHINE_TOKEN [unique]);
ASSERT(L'I' == FN_DIRECT_TOKEN [unique]);
//----------------0^-------------------------
//
// accelarate token recognition by checking 3rd character
//
switch(towupper(p[unique]))
{
// pUblic
case L'U':
qft = QUEUE_FORMAT_TYPE_PUBLIC;
if(_wcsnicmp(p, FN_PUBLIC_TOKEN, FN_PUBLIC_TOKEN_LEN) == 0)
return (p + FN_PUBLIC_TOKEN_LEN);
break;
// pRivate
case L'R':
qft = QUEUE_FORMAT_TYPE_PRIVATE;
if(_wcsnicmp(p, FN_PRIVATE_TOKEN, FN_PRIVATE_TOKEN_LEN) == 0)
return (p + FN_PRIVATE_TOKEN_LEN);
break;
// cOnnector
case L'O':
qft = QUEUE_FORMAT_TYPE_CONNECTOR;
if(_wcsnicmp(p, FN_CONNECTOR_TOKEN, FN_CONNECTOR_TOKEN_LEN) == 0)
return (p + FN_CONNECTOR_TOKEN_LEN);
break;
// mAchine
case L'A':
qft = QUEUE_FORMAT_TYPE_MACHINE;
if(_wcsnicmp(p, FN_MACHINE_TOKEN, FN_MACHINE_TOKEN_LEN) == 0)
return (p + FN_MACHINE_TOKEN_LEN);
break;
// dIrect
case L'I':
qft = QUEUE_FORMAT_TYPE_DIRECT;
if(_wcsnicmp(p, FN_DIRECT_TOKEN, FN_DIRECT_TOKEN_LEN) == 0)
return (p + FN_DIRECT_TOKEN_LEN);
break;
}
return 0;
}
//---------------------------------------------------------
//
// Parse a guid string, into guid.
// Return next char to parse on success, 0 on failure.
//
LPCWSTR scutil_ParseGuidString(LPCWSTR p, GUID* pg)
{
//
// N.B. scanf stores the results in an int, no matter what the field size
// is. Thus we store the result in tmp variabes.
//
int n;
UINT w2, w3, d[8];
if(swscanf(
p,
GUID_FORMAT L"%n",
&pg->Data1,
&w2, &w3, // Data2, Data3
&d[0], &d[1], &d[2], &d[3], // Data4[0..3]
&d[4], &d[5], &d[6], &d[7], // Data4[4..7]
&n // number of characters scaned
) != 11)
{
//
// not all 11 fields where not found.
//
return 0;
}
pg->Data2 = (WORD)w2;
pg->Data3 = (WORD)w3;
for(int i = 0; i < 8; i++)
{
pg->Data4[i] = (BYTE)d[i];
}
return (p + n);
}
// called on scapi_MQSendMessage on determining how big a buffer to allocate for packet.
ULONG CalcFwdRevViaSectionSize(CAPROPVARIANT *pEntry) {
ULONG ulNeeded = sizeof(CDataHeader);
for (unsigned int i =0; i < pEntry->cElems; i++) {
PROPVARIANT *pVar = &pEntry->pElems[i];
if (! pVar || pVar->vt != VT_LPWSTR)
return 0;
ulNeeded += ((wcslen(pVar->pwszVal)+1) * sizeof(WCHAR));
}
SVSUTIL_ASSERT(ulNeeded > sizeof(CDataHeader));
return ALIGNUP4(ulNeeded);
}
// called on scapi_RetrievePacketInfo to determine how space required by calling app.
ULONG CalcFwdRevViaSectionSize(CDataHeader *pFwdRevEntry, DWORD *pdwElements) {
SVSUTIL_ASSERT(*pdwElements == 0);
if (!pFwdRevEntry)
return 0;
ULONG ulNeeded = 0;
int iLen = pFwdRevEntry->GetDataLengthInWCHARs();
WCHAR *szStart = (WCHAR*) pFwdRevEntry->GetData();
WCHAR *pszTrav = szStart;
// VIA list is stored as a NULL separated multi-string. Elements
// may be set to \0 to indicate an empty tag.
while (pszTrav - szStart < iLen) {
int iElementLen = wcslen(pszTrav)+1;
ulNeeded += (iElementLen*sizeof(WCHAR) + sizeof(PROPVARIANT));
pszTrav += iElementLen;
(*pdwElements)++;
}
SVSUTIL_ASSERT(pszTrav-szStart == iLen);
return ulNeeded;
}
// Copy the (VT_VARIAT | VT_VECTOR) data associated with SOAP VIA elements
// into the user process space. To do this, we build the buffer up in
// servicesd.exe process space and then copy it all at once into app-space.
BOOL SetFwdRevViaSection(CDataHeader *pFwdRevEntry, CAPROPVARIANT *pPropVar, DWORD dwElements,
DWORD cbBufferSize, HANDLE hCallerProc, HRESULT *pHR) {
int iStringLen = pFwdRevEntry->GetDataLengthInWCHARs();
WCHAR *szStart = (WCHAR*) pFwdRevEntry->GetData();
WCHAR *pszTrav = szStart;
// Data in servicesd.exe to write to
WCHAR *szWrite;
// Data client will access (in its process space). This is not
// safe to dereference in servicesd.exe.
WCHAR *szWriteClient;
// Makep copy in servicesd.exe space that we write to temporarily
PROPVARIANT *pPropWriteBase = (PROPVARIANT *)LocalAlloc(0,cbBufferSize);
PROPVARIANT *pPropWrite = pPropWriteBase;
// Helper to actually write data to process. We can't use MarshalBuffer_t
// since we're not necesarrily running on PSL caller thread.
CMarshallDataToProcess copyData(hCallerProc);
if (! pPropWriteBase) {
*pHR = MQ_ERROR_INSUFFICIENT_RESOURCES;
return FALSE;
}
pPropVar->cElems = dwElements;
szWrite = (WCHAR*) ((CHAR*)pPropWriteBase+ sizeof(PROPVARIANT)*dwElements);
memset(pPropWriteBase,0,dwElements*sizeof(PROPVARIANT));
szWriteClient = (WCHAR*) ((CHAR*)pPropVar->pElems+ sizeof(PROPVARIANT)*dwElements);
// VIA list is stored as a NULL separated multi-string. Elements
// may be set to \0 to indicate an empty tag.
while (pszTrav - szStart < iStringLen) {
int iElementLen = wcslen(pszTrav)+1;
memcpy(szWrite,pszTrav,iElementLen*sizeof(WCHAR));
pPropWrite->vt = VT_LPWSTR;
// This is the pointer that the user mode process will use to access
// the written out data, not the actual memory MSMQ is writing out for
// this particular value.
pPropWrite->pwszVal = szWriteClient;
pPropWrite++;
szWrite += iElementLen;
pszTrav += iElementLen;
szWriteClient += iElementLen;
}
// Check we wrote out the number of bytes we thought we would.
SVSUTIL_ASSERT(pszTrav-szStart == iStringLen);
copyData.WriteBufToProc((UCHAR*)pPropVar->pElems, (UCHAR*)pPropWriteBase, cbBufferSize, pHR);
LocalFree(pPropWriteBase);
return (*pHR == MQ_OK);
}
WCHAR * GetNextHopOnFwdList(ScPacketImage *pImage) {
// If we're receiving a message off wire (fSRMPGenerated=TRUE), then the 1st entry in pFwdVia header
// is the current machine name's <fwd><via> entry, skip it because we want to route
// to the next queue in line. When we're generating the message locally (fSRMPGenerated=FALSE) then
// 1st element in pFwdViaHeader is queue to route to.
if (! pImage->flags.fSRMPGenerated)
return (WCHAR*) pImage->sect.pFwdViaHeader->GetData();
WCHAR *szFirstElement = (WCHAR*) pImage->sect.pFwdViaHeader->GetData();
int ccElementList = pImage->sect.pFwdViaHeader->GetDataLengthInWCHARs();
int ccFirstElement = wcslen(szFirstElement) + 1;
// only one entry is in <fwd> list.
if (ccElementList == ccFirstElement)
return NULL;
return (szFirstElement+ccFirstElement);
}
//---------------------------------------------------------
//
// Parse private id uniquifier, into guid.
// Return next char to parse on success, 0 on failure.
//
static LPCWSTR ParsePrivateIDString(LPCWSTR p, ULONG* pUniquifier)
{
int n;
if(swscanf(
p,
PRIVATE_ID_FORMAT L"%n",
pUniquifier,
&n // number of characters scaned
) != 1)
{
//
// private id field was not found.
//
return 0;
}
return (p + n);
}
extern const WCHAR cszHttpPrefix[] = L"HTTP://";
extern const WCHAR cszHttpsPrefix[] = L"HTTPS://";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -