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

📄 cping.cpp

📁 微软提供的截取Win32 API函数的开发包和例子detours-src-1.2.rar
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	return E_FAIL;
}

///////////////////////////////////////////////////////// CNetPingFactory.
//
LONG	CNetPingFactory::s_nObjects = 0;
LONG	CNetPingFactory::s_nLocks = 0;
HANDLE	CNetPingFactory::s_hevtDone = NULL;

CNetPingFactory::CNetPingFactory()
{
	m_cRef = 1;
}


CNetPingFactory::~CNetPingFactory()
{
	m_cRef = 0;
}

ULONG CNetPingFactory::AddRef(void)
{
	return InterlockedIncrement(&m_cRef);
}

ULONG CNetPingFactory::Release(void)
{
	if (InterlockedDecrement(&m_cRef) == 0) {
		delete this;
		return 0;
	}
	return 1;
}

HRESULT CNetPingFactory::InitSystem(VOID)
{
	s_nObjects = 0;
	s_nLocks = 0;

	s_hevtDone = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (s_hevtDone == NULL) {
		HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
		CheckResult(hr, "Server: CreateEvent");
		exit(hr);
	}
	
	return S_OK;
}

HRESULT CNetPingFactory::FiniSystem(VOID)
{
	if (s_hevtDone != NULL) {
		CloseHandle(s_hevtDone);
		s_hevtDone = NULL;
	}
	return S_OK;
}


HRESULT CNetPingFactory::InitObject(VOID)
{
	InterlockedIncrement(&s_nObjects);
	return S_OK;
}

HRESULT CNetPingFactory::FiniObject(VOID)
{
	if (InterlockedDecrement(&s_nObjects) == 0 && s_nLocks == 0)
		SetEvent(s_hevtDone);
	return S_OK;
}

HRESULT CNetPingFactory::Lock(BOOL fLock)
{
	if (fLock) {
		InterlockedIncrement(&s_nLocks);
	}
	
	else {
		if (InterlockedDecrement(&s_nLocks) == 0 && s_nObjects == 0)
			SetEvent(s_hevtDone);
	}
	return S_OK;
}

HRESULT CNetPingFactory::Wait(VOID)
{
	DWORD dwWaitResult;
	MSG msg;

	for (;;) {
		dwWaitResult = MsgWaitForMultipleObjects(1, &s_hevtDone,
												 FALSE, INFINITE,
												 QS_ALLINPUT);
		
		if (dwWaitResult == WAIT_OBJECT_0) {
			ResetEvent(s_hevtDone);
			return S_OK;
		}
		
		while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
			TranslateMessage(&msg);			
			DispatchMessage(&msg);
		}
	}
	return E_FAIL;
}
	
STDMETHODIMP CNetPingFactory::QueryInterface(REFIID riid, void** ppv)
{
    if (ppv == NULL)
        return E_INVALIDARG;
    if (riid == IID_IClassFactory || riid == IID_IUnknown) {
        *ppv = (IClassFactory *) this;
        AddRef();
        return S_OK;
	}
    *ppv = NULL;
    return E_NOINTERFACE;
}

HRESULT CNetPingFactory::LockServer (BOOL fLock)
{
	return Lock(fLock);
}

STDMETHODIMP CNetPingFactory::CreateInstance(LPUNKNOWN punkOuter,
											 REFIID riid, void** ppv)
{
    LPUNKNOWN   punk;
    HRESULT     hr;

    *ppv = NULL;

    if (punkOuter != NULL)
        return CLASS_E_NOAGGREGATION;

	printf("  Server: IClassFactory:CreateInstance\n");

    punk = new CNetPingObject;
    if (punk == NULL)
        return E_OUTOFMEMORY;

    hr = punk->QueryInterface(riid, ppv);
    punk->Release();
    return hr;
}	

/////////////////////////////////////////////////////////////// CNetPingObject.
//
CNetPingObject::CNetPingObject()
{
	m_cRef = 1;
	m_cbLast = ~0u;
	m_cbOut = 2;
	CNetPingFactory::InitObject();
}

CNetPingObject::~CNetPingObject()
{
	CNetPingFactory::FiniObject();
}

STDMETHODIMP CNetPingObject::QueryInterface(REFIID riid, void** ppv)
{
    if (ppv == NULL)
        return E_INVALIDARG;
    if (riid == IID_IUnknown || riid == IID_IPing) {
        *ppv = (IPing *) this;
        AddRef();
        return S_OK;
	}
    *ppv = NULL;
    return E_NOINTERFACE;
}

STDMETHODIMP_(ULONG) CNetPingObject::AddRef(void)
{
	return InterlockedIncrement(&m_cRef);
}

STDMETHODIMP_(ULONG) CNetPingObject::Release(void)
{
	if (InterlockedDecrement(&m_cRef) == 0) {
		delete this;
		return 0;
	}
	return 1;
}

STDMETHODIMP CNetPingObject::Ping()
{
	return S_OK;
}

STDMETHODIMP CNetPingObject::PingToServer(LPSTR pszString)
{
	return S_OK;
}

STDMETHODIMP CNetPingObject::PingToClient(LPSTR *ppszString)
{
	LPSTR pszString = (LPSTR)CoTaskMemAlloc(m_cbOut);
	if (pszString == NULL)
		return E_OUTOFMEMORY;

	CopyMemory(pszString, g_pBuffer, m_cbOut);
	*ppszString = pszString;

	return S_OK;
}

STDMETHODIMP CNetPingObject::PingToClientSize(ULONG cbOut)
{
	if (cbOut < 1) {
		return E_INVALIDARG;
	}
	
	InitializeString((LPSTR)g_pBuffer, cbOut);
	m_cbOut = cbOut;
	return S_OK;
}

//////////////////////////////////////////////////////////////////////////////
//
class CSampleRecord
{
public:
	DOUBLE		m_dTime;
	FILETIME	m_nWhen;
	LONG		m_cbToClient;
	LONG		m_cbToServer;
	DOUBLE		m_dDcom;
	DOUBLE		m_dRpc;
	DOUBLE		m_dUdp;
	DOUBLE		m_dNet;

protected:
	static LONG	s_cbToClient;
	static LONG	s_cbToServer;

public:
	CSampleRecord();
	CSampleRecord(IPing *pIPing, LONG cbToClient, LONG cbToServer);

	HRESULT		Measure(IPing *pIPing, LONG cbToClient, LONG cbToServer);
	HRESULT		Write(FILE *fp);

	double		GetTime() 			{ return m_dTime; }
	FILETIME	GetWhen() 			{ return m_nWhen; }
	LONG		GetToClient() 		{ return m_cbToClient; }
	LONG		GetToServer() 		{ return m_cbToServer; }

};

//////////////////////////////////////////////////////////////////////////////
//
LONG CSampleRecord::s_cbToClient = 0;
LONG CSampleRecord::s_cbToServer = 0;

//////////////////////////////////////////////////////////////////////////////
//
CSampleRecord::CSampleRecord()
{
	m_dTime = 0;
	m_dDcom = 0;
	m_dRpc = 0;
	m_dUdp = 0;
	m_dNet = 0;
}

CSampleRecord::CSampleRecord(IPing *pIPing, LONG cbToClient, LONG cbToServer)
{
	Measure(pIPing, cbToClient, cbToServer);
}

HRESULT CSampleRecord::Measure(IPing *pIPing, LONG cbToClient, LONG cbToServer)
{
	HRESULT hr;
	LONGLONG llBeg;
	LONGLONG llEnd;

	GetSystemTimeAsFileTime(&m_nWhen);
	m_cbToClient = cbToClient;
	m_cbToServer = cbToServer;
	
	if (cbToClient == 0 && cbToServer == 0) {
		PingLoadCycleCount(llBeg);
		hr = Detour_IPing_Ping(pIPing);
		PingLoadCycleCount(llEnd);
	}
	else if (cbToClient) {
		if (s_cbToClient != cbToClient) {
			hr = pIPing->PingToClientSize(cbToClient);
			s_cbToClient = cbToClient;
		}
		
		LPSTR pszString = NULL;
		
		PingLoadCycleCount(llBeg);
		hr = Detour_IPing_PingToClient(pIPing, &pszString);
		PingLoadCycleCount(llEnd);
		
		LONG cb = strlen(pszString) + 1;
		ASSERT(cb == cbToClient);
		
		if (pszString) {
			CoTaskMemFree(pszString);
			pszString = NULL;
		}
	}
	else {
		if (s_cbToServer != cbToServer) {
			InitializeString((LPSTR)g_pBuffer, cbToServer);
			s_cbToServer = cbToServer;
		}
		
		PingLoadCycleCount(llBeg);
		hr = Detour_IPing_PingToServer(pIPing, (LPSTR)g_pBuffer);
		PingLoadCycleCount(llEnd);
	}

	if (FAILED(hr)) {
		fprintf(g_fpLog, ";; Operation failed: %08lx\n", hr);
		fflush(g_fpLog);
		exit(999);
		
		m_dTime = -1.0;
		return hr;
	}

	if (g_fSummarize) {
		SummarizeCycles();
		m_dDcom = (double)s_rgCycles[E_DCOM] * g_dMsPerCycle;
		m_dRpc = (double)s_rgCycles[E_RPC] * g_dMsPerCycle;
		m_dUdp = (double)s_rgCycles[E_UDP] * g_dMsPerCycle;
		m_dNet = (double)s_rgCycles[E_NET] * g_dMsPerCycle;
	}
	
	m_dTime = (double)(llEnd - llBeg) * g_dMsPerCycle;
	
	return S_OK;
}

HRESULT CSampleRecord::Write(FILE *fp)
{
	SYSTEMTIME	st;
	FILETIME ft;

	FileTimeToLocalFileTime(&m_nWhen, &ft);
	FileTimeToSystemTime(&ft, &st);
	
	fprintf(fp, "%02d/%02d %2d:%02d:%02d %6d %d %6.3f [ %6.3f %6.3f %6.3f %6.3f ]\n",
			st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond,
			m_cbToClient, m_cbToServer, m_dTime,
			m_dDcom, m_dRpc, m_dUdp, m_dNet);

	return S_OK;
}

//////////////////////////////////////////////////////////////////////////////
//
double NetTest(HKEY hNetwork, IPing *pIPing,
			   BOOLEAN fToClient, LONG cbPacket, LONG nCount)
{
	//////////////////////////////////////////////////////////////////// ToClient.
	//
	double msAvg = 0.0;
	double msMin = 1.0e12;
	double msMax = 0.0;
	ULONG nMax = 999;
	ULONG nMin = 999;

	if (fToClient)
		printf(">Client %6d %6d ", cbPacket, nCount);
	else
		printf(">Server %6d %6d ", cbPacket, nCount);

	for (LONG n = 0; n < nCount; n++) {
		double ms;
		
		if (fToClient) {
			ms = CSampleRecord(pIPing, cbPacket, 0).GetTime();
		}
		else {
			ms = CSampleRecord(pIPing, 0, cbPacket).GetTime();
		}

		if (ms < 0)
			break;

		if (msMin > ms) {
			msMin = ms;
			nMin = n;
		}
		if (msMax < ms) {
			msMax = ms;
			nMax = n;
		}
		msAvg += ms;
	}
	
	if (nCount)
		msAvg /= nCount;

	if (cbPacket == 0)
		g_dLatency = msMin;

	double mbps = (double)cbPacket / msMin;
	mbps *= 8.0 * 1000.0 / 1024.0 / 1024.0;
	
	double mbps2 = (double)cbPacket / (msMin - g_dLatency);
	mbps2 *= 8.0 * 1000.0 / 1024.0 / 1024.0;
	if (cbPacket == 0)
		mbps2 = 0;

	if (hNetwork != NULL) {
		WCHAR wzKey[64];
		WCHAR wzLatency[64];
		
		if (fToClient)
			swprintf(wzKey, L"ToClient\\%d", cbPacket);
		else
			swprintf(wzKey, L"ToServer\\%d", cbPacket);
		
		swprintf(wzLatency, L"%I64d", msAvg);
		
		RegSetValue(hNetwork, wzKey, REG_SZ, wzLatency, wcssize(wzLatency));
	}
	
	printf("%8.3f %8.3f %8.3f %9.4f %8.3f %9.4f%3d\n",
		   msMin, 
		   msAvg, 
		   msMax,
		   mbps,
		   msMin - g_dLatency,
		   mbps2,
		   nMax);
	return mbps;
}

//////////////////////////////////////////////////////////////////////// main.

static WCHAR 	wzServers[32][64];
static int		nServers = 0;

void Sample_Fixed(IPing *pIPing)
{
	CSampleRecord csrRecords[512];
	LONG nRecords = 0;
	HRESULT hr;

	double dAvg = 0;
	double dMin = 500000.0;
	double dMax = 0.0;
	double dMinDcom = dMin;
	double dMinRpc = dMin;
	double dMinUdp = dMin;
	double dMinNet = dMin;
	
	for (int i = 0; i < 512; i++) {
		CSampleRecord& csr = csrRecords[nRecords++];
		
		hr = csr.Measure(pIPing, g_nFixedToClient, g_nFixedToServer);
		double d = csr.GetTime();
		if (dMin > d)
			dMin = d;
		if (dMax < d)
			dMax = d;
		if (dMinDcom > csr.m_dDcom)
			dMinDcom = csr.m_dDcom;
		if (dMinRpc > csr.m_dRpc)
			dMinRpc = csr.m_dRpc;
		if (dMinUdp > csr.m_dUdp)
			dMinUdp = csr.m_dUdp;
		if (dMinNet > csr.m_dNet)
			dMinNet = csr.m_dNet;
		dAvg += d;
	}
	
	dAvg /= 512;
	printf("size: %d, min: %.3f, max: %.3f avg: %.3f [ %8.3f %8.3f %8.3f %8.3f ]\n",
		   g_nFixedToClient, dMin, dMax, dAvg, dMinDcom, dMinRpc, dMinUdp, dMinNet);
	for (int n = 0; n < nRecords; n++)
		csrRecords[n].Write(g_fpLog);
}

void Sample_Simple(IPing *pIPing)
{
	CSampleRecord csrRecords[512];
	LONG nRecords = 0;
	HRESULT hr;
					
	for (int cb = 0; cb < 64000; cb = cb ? cb << 1 : 32) {
		double n[5];
					
		for (int i = 0; i < 5; i++) {
			CSampleRecord& csr = csrRecords[nRecords++];
						
			hr = csr.Measure(pIPing, cb, 0);
			n[i] = csr.GetTime();
		}
		
		double nAvg = 0;
		double nApx = 0;
		double nMin = n[0];
		double nMax = n[0];
					
		for (i = 0; i < 5; i++) {
			if (nMin > n[i])
				nMin = n[i];
			if (nMax < n[i])
				nMax = n[i];
			nAvg += n[i];
		}
		nApx = nAvg - nMax;
		nAvg /= 5;
		nApx /= 4;
		printf("min: %8.3f ms (%6d) %7.3f%7.3f%7.3f%7.3f%7.3f:%8.3f%8.3f\n",
			   nMin, cb, n[0], n[1], n[2], n[3], n[4], nAvg, nApx);
#ifdef INCLUDE_THIS		
		if (nMin > 300)
			break;
#endif		
	}
	for (int n = 0; n < nRecords; n++)
		csrRecords[n].Write(g_fpLog);
}

void Sample_More(IPing *pIPing)
{
	CSampleRecord csrRecords[64];
	LONG nRecords = 0;
					
	for (int cb = 0; cb < 64000; cb = cb ? cb << 1 : 32) {
		for (int i = 0; i < 64; i++) {
			CSampleRecord& csr = csrRecords[nRecords++];
						
			csr.Measure(pIPing, cb, 0);
		}
					
		double nAvg = 0;
		double nMin = csrRecords[0].GetTime();
		double nMax = csrRecords[0].GetTime();
					
		for (i = 0; i < 64; i++) {
			double n = csrRecords[i].GetTime();
			
			if (nMin > n)
				nMin = n;
			if (nMax < n)
				nMax = n;
			nAvg += n;
		}
		nAvg /= i;
		printf("min: %8.3f ms (%6d) : %8.3f %8.3f\n",

⌨️ 快捷键说明

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