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

📄 scutil.cxx

📁 Windows CE 6.0 Server 源码
💻 CXX
📖 第 1 页 / 共 4 页
字号:
//  Function:
//      RTpFormatNameToQueueFormat
//
//  Description:
//      Convert a format name string to a QUEUE_FORMAT union.
//
//---------------------------------------------------------
static BOOL
RTpFormatNameToQueueFormat(
    LPCWSTR pfn,            // pointer to format name string
    QUEUE_FORMAT* pqf,      // pointer to QUEUE_FORMAT
    LPWSTR* ppStringToFree  // pointer to allocated string need to free at end of use
    )                       // if null, format name will not get expanded
{
    LPCWSTR p = pfn;
    QUEUE_FORMAT_TYPE qft;

    if((p = ParsePrefixString(p, qft)) == 0)
        return FALSE;

    p = skip_ws(p);

    if(*p++ != FN_EQUAL_SIGN_C)
        return FALSE;

    p = skip_ws(p);

    GUID guid;
    switch(qft)
    {
        //
        //  "PUBLIC=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\0"
        //
        case QUEUE_FORMAT_TYPE_PUBLIC:
            if((p = scutil_ParseGuidString(p, &guid)) == 0)
                return FALSE;

            pqf->PublicID(guid);
            break;

        //
        //  "PRIVATE=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\\xxxxxxxx\0"
        //
        case QUEUE_FORMAT_TYPE_PRIVATE:
            if((p = scutil_ParseGuidString(p, &guid)) == 0)
                return FALSE;

            p = skip_ws(p);

            if(*p++ != FN_PRIVATE_SEPERATOR_C)
                return FALSE;

            p = skip_ws(p);

            ULONG uniquifier;
            if((p = ParsePrivateIDString(p, &uniquifier)) == 0)
                return FALSE;

            pqf->PrivateID(guid, uniquifier);
            break;

        //
        //  "DIRECT=OS:bla-bla\0"
        //
        case QUEUE_FORMAT_TYPE_DIRECT:
            LPCWSTR pExpandedDirectFormat;
            if((p = ParseDirectString(p, &pExpandedDirectFormat, ppStringToFree)) == 0)
                return FALSE;

            pqf->DirectID(const_cast<LPWSTR>(pExpandedDirectFormat));
            break;

        //
        //  "MACHINE=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\0"
        //
        case QUEUE_FORMAT_TYPE_MACHINE:
           if((p = scutil_ParseGuidString(p, &guid)) == 0)
                return FALSE;

            pqf->MachineID(guid);
            break;

        //
        //  "CONNECTOR=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\0"
        //
        case QUEUE_FORMAT_TYPE_CONNECTOR:
           if((p = scutil_ParseGuidString(p, &guid)) == 0)
                return FALSE;

            pqf->ConnectorID(guid);
            break;

        default:
            ASSERT(0);
    }

    p = skip_ws(p);

    //
    //  We're at end of string, return now.
    //  N.B. Machine format name *must* have a suffix
    //
    if(*p == L'\0')
        return (qft != QUEUE_FORMAT_TYPE_MACHINE);

    if(*p != FN_SUFFIX_DELIMITER_C)
        return FALSE;

    QUEUE_SUFFIX_TYPE qst;
    if((p = ParseSuffixString(p, qst)) == 0)
        return FALSE;

    p = skip_ws(p);

    //
    //  Only white space padding is allowed.
    //
    if(*p != L'\0')
        return FALSE;

    pqf->Suffix(qst);

    return pqf->Leagal();
}

int scutil_StringToQF (QUEUE_FORMAT *pqf, WCHAR *lpszName) {
	return RTpFormatNameToQueueFormat (lpszName, pqf, NULL);
}

int scutil_GetLanNum (void) {
	char name[MSMQ_SC_REGBUFFER];

	if (gethostname (name, sizeof(name)))
		return 0;

	HOSTENT *phe = gethostbyname (name);
	if (NULL == phe) {
		scerror_DebugOutM (VERBOSE_MASK_FATAL, (L"gethostbyname(%S) fails.  WSAGetLastError returns 0x%08x\n",name,WSAGetLastError()));
		SVSUTIL_ASSERT(0);
		return 0;
	}
	
	if ((phe->h_addrtype != AF_INET) || (phe->h_length != sizeof (IN_ADDR)) || (*phe->h_addr_list == NULL))
		return 0;

	int iRes = 0;

	IN_ADDR **ppia = (IN_ADDR **)phe->h_addr_list;

	while (*ppia != NULL) {
		if (ntohl((**ppia).S_un.S_addr) != INADDR_LOOPBACK)
			++iRes;

		++ppia;
	}

	return iRes;
}

int scutil_IsLocalTCP (WCHAR *szHostName) {
	static int iTcpAddresses = 0;
	static unsigned long aulTcpAddresses[MSMQ_SC_MAX_IP_INTERFACES];

	if (! szHostName) {
		iTcpAddresses = 0;

		char name[MSMQ_SC_REGBUFFER];

		if (gethostname (name, sizeof(name)))
			return 0;

		HOSTENT *phe = gethostbyname (name);
		if (NULL == phe) {
			scerror_DebugOutM (VERBOSE_MASK_FATAL, (L"gethostbyname(%S) fails.  WSAGetLastError returns 0x%08x\n",name,WSAGetLastError()));
			SVSUTIL_ASSERT(0);
			return 0;
		}
	
		if ((phe->h_addrtype != AF_INET) || (phe->h_length != sizeof (IN_ADDR)) || (*phe->h_addr_list == NULL))
			return FALSE;

		IN_ADDR **ppia = (IN_ADDR **)phe->h_addr_list;

		while ((*ppia != NULL) && (iTcpAddresses < MSMQ_SC_MAX_IP_INTERFACES)) {
			unsigned long ulInterfaceAddress = (**ppia).S_un.S_addr;
			if (ulInterfaceAddress != INADDR_LOOPBACK)
				aulTcpAddresses[iTcpAddresses++] = ulInterfaceAddress;

			++ppia;
		}

		return iTcpAddresses;
	}

	char szaddr[MSMQ_SC_IPBUFFER];

	if (! WideCharToMultiByte (CP_ACP, 0, szHostName, -1, szaddr, sizeof(szaddr), NULL, NULL)) 
		return FALSE;

	unsigned long ul_addr = inet_addr (szaddr);

	if (ul_addr == INADDR_NONE)
		return FALSE;

	for (int i = 0 ; i < iTcpAddresses ; ++i) {
		if (ul_addr == aulTcpAddresses[i])
			return TRUE;
	}

	return FALSE;
}

WCHAR* scutil_StrStrWI(const WCHAR * str1, const WCHAR * str2) {
	WCHAR *cp = (WCHAR *) str1;
	WCHAR *s1, *s2;
	while (*cp) {
		s1 = cp;
		s2 = (WCHAR *) str2;
		while ( *s1 && *s2 && (towlower(*s1) == towlower(*s2)) )
			s1++, s2++;
		if (!*s2)
			return(cp);
		cp++;
	}
	return(NULL);
}

void scutil_ReplaceBackSlashesWithSlashes(WCHAR *a_lpszName) {
	for (WCHAR *p = a_lpszName; *p; p++) {
		if (*p == '\\')
			*p = '/';
	}
}

//
// CRemoteAllocMgr implementation
// Handles cases when we need to remotely alloc / dealloc memory in the 
// caller process.  Note this MUST be done on the PSL thread, and not 
// on a servicesd.exe worker.
//
//

// Destroys a remote heap.
void DeleteRemoteHeapInfo(void *pvData) {
	SVSUTIL_ASSERT((glServiceState == SERVICE_STATE_OFF) || gMem->IsLocked());
	REMOTE_HEAP_INFO *pRemoteInfo = (REMOTE_HEAP_INFO*)pvData;
	if (pRemoteInfo->hHeap)
		HeapDestroy(pRemoteInfo->hHeap);
}

// Checks current caller process and determines if heap is associated with it.
BOOL DoesHeapInfoBelongToCaller(void *pvContext, void *pvData) {
	SVSUTIL_ASSERT(gMem->IsLocked());
	REMOTE_HEAP_INFO *pRemoteInfo = (REMOTE_HEAP_INFO*)pvContext;

	// Passed in pvData, via SVSLinkManager filter mechanism, is the
	// result of GetCallerVMProcessId().  Don't call it in each call to
	// this fcn to avoid extra PSL calls.
	return (pRemoteInfo->hProcess == (HANDLE)pvData);
}

// Finds heap caller process owns, and dereferences its usage count, deleting once 0
BOOL DeRefHeapOnProcessDeInit(void *pvContext, void *pvData) {
	SVSUTIL_ASSERT(gMem->IsLocked());
	REMOTE_HEAP_INFO *pRemoteInfo = (REMOTE_HEAP_INFO*)pvContext;

	// pvData is result of GetCallerVMProcessId() by caller
	if (pRemoteInfo->hProcess != (HANDLE)pvData)
		return FALSE;

	pRemoteInfo->dwRefs--;
	if (pRemoteInfo->dwRefs == 0)
		return TRUE; // indicate to SVSLinkManager delete this node now

	return FALSE; // don't delete this node
}

// Creates a new entry in m_remoteHeaps for process tying into MSMQ (if it wasn't present already)
BOOL CRemoteAllocMgr::InitForProcess(void) {
	if (IsCallerProcSameAsCurrent())
		return TRUE;

	SVSUTIL_ASSERT(gMem->IsLocked());
	REMOTE_HEAP_INFO *pRemoteInfo = FindRemoteHeapOfCaller();

	if (pRemoteInfo) {
		// Process already has a remote heap structure allocated; just increment ref count.
		SVSUTIL_ASSERT(pRemoteInfo->dwRefs >= 1);
		pRemoteInfo->dwRefs++;
		return TRUE;
	}
	
	pRemoteInfo = (REMOTE_HEAP_INFO *)m_remoteHeaps.AllocEntry();
	if (! pRemoteInfo)
		return FALSE;

	pRemoteInfo->dwRefs   = 1;
	pRemoteInfo->hProcess = (HANDLE)GetCallerVMProcessId();
	pRemoteInfo->hHeap    = CeRemoteHeapCreate((DWORD)pRemoteInfo->hProcess,0);
	if (!pRemoteInfo->hHeap) {
		scerror_DebugOutM(VERBOSE_MASK_FATAL,(L"MSMQ: CeRemoteHeapCreate(callerVM=0x%08x) fails, GLE = 0x%08x\r\n",pRemoteInfo->hProcess,GetLastError()));
		m_remoteHeaps.RemoveEntry(pRemoteInfo);
		return FALSE;
	}

	return TRUE;
}

// Destroys associated entry in m_remoteHeaps (if ref count is at 0)
BOOL CRemoteAllocMgr::DeInitForProcess(void) {
	SVSUTIL_ASSERT(gMem->IsLocked());
	m_remoteHeaps.RemoveEntriesFiltered(DeRefHeapOnProcessDeInit, (void*)GetCallerVMProcessId());
	return TRUE;
}

// Duplicates a buffer and translates to appropriate address space
BYTE *CRemoteAllocMgr::DuplicateBufferAndTranslate(const BYTE *pbData, DWORD cbData) {
	SVSUTIL_ASSERT(gMem->IsLocked());

	BYTE *pbCopy;
	if (IsCallerProcSameAsCurrent()) {
		pbCopy = (BYTE*)LocalAlloc(0,cbData);
		if (! pbCopy)
			return NULL;

		memcpy(pbCopy,pbData,cbData);
		return pbCopy;
	}

	REMOTE_HEAP_INFO *pRemoteInfo = FindRemoteHeapOfCaller();
	if (! pRemoteInfo)
		return NULL;

	pbCopy = (BYTE*)HeapAlloc(pRemoteInfo->hHeap,0,cbData);
	if (! pbCopy)
		return NULL;

	memcpy(pbCopy,pbData,cbData);
	return (BYTE*)CeRemoteHeapTranslatePointer(pRemoteInfo->hHeap,0,pbCopy);

};

// Duplicates a string and translates to appropriate address space
WCHAR *CRemoteAllocMgr::DuplicateStringAndTranslate(const WCHAR *szData) {
	return (WCHAR*)DuplicateBufferAndTranslate((BYTE*)szData,sizeof(WCHAR)*(wcslen(szData)+1));
}

// Allocates data on the caller's heap.
BYTE *CRemoteAllocMgr::AllocOnCallerHeap(DWORD dwData) {
	SVSUTIL_ASSERT(gMem->IsLocked());

	if (IsCallerProcSameAsCurrent())
		return (BYTE*)LocalAlloc(0,dwData);

	REMOTE_HEAP_INFO *pRemoteInfo = FindRemoteHeapOfCaller();
	if (! pRemoteInfo)
		return NULL;

	return (BYTE*)HeapAlloc(pRemoteInfo->hHeap,0,dwData);
}

// Translates the data to caller process address space
BYTE *CRemoteAllocMgr::TranslateData(BYTE *pbData) {
	if (IsCallerProcSameAsCurrent())
		return pbData;

	SVSUTIL_ASSERT(gMem->IsLocked());
	REMOTE_HEAP_INFO *pRemoteInfo = FindRemoteHeapOfCaller();
	if (! pRemoteInfo)
		return NULL;

	return (BYTE*)CeRemoteHeapTranslatePointer(pRemoteInfo->hHeap,0,pbData);
}

// Frees data allocated on remote heap (HeapFree wrapper)
void CRemoteAllocMgr::FreeData(BYTE *pbData) {
	if (IsCallerProcSameAsCurrent()) {
		LocalFree(pbData);
		return;
	}

	SVSUTIL_ASSERT(gMem->IsLocked());
	REMOTE_HEAP_INFO *pRemoteInfo = FindRemoteHeapOfCaller();
	if (! pRemoteInfo)
		return;

	HeapFree(pRemoteInfo->hHeap,0,pbData);
}

⌨️ 快捷键说明

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