<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Veridium Software</title>
	<atom:link href="http://veridium.net/feed/" rel="self" type="application/rss+xml" />
	<link>https://veridium.net</link>
	<description>Veridium Software, HomeGuard activity monitoring and parental control tools: content based porn filtering, website blocker, keylogger, activity based screenshots, gaming and Internet time restrictions and more.</description>
	<lastBuildDate>Wed, 08 Aug 2018 20:17:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Scalable IPC Using Asynchronous Named Pipes and IO Completion Ports</title>
		<link>https://veridium.net/programming-tutorials/scalable-ipc-using-asynchronous-named-pipes-and-io-completion-ports/</link>
		<comments>https://veridium.net/programming-tutorials/scalable-ipc-using-asynchronous-named-pipes-and-io-completion-ports/#comments</comments>
		<pubDate>Sat, 04 Jun 2011 22:12:54 +0000</pubDate>
		<dc:creator>hseldon</dc:creator>
				<category><![CDATA[cpp]]></category>
		<category><![CDATA[programming-tutorials]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[client]]></category>
		<category><![CDATA[io completion ports]]></category>
		<category><![CDATA[IPC]]></category>
		<category><![CDATA[pipes]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[win32]]></category>

		<guid isPermaLink="false">http://veridium.net/?p=145</guid>
		<description><![CDATA[This is a client/server implementation of Inter Process Communication using Asynchronous Named Pipes with IO completion ports to achieve scalability in situations where several applications need to send and receive large chunks of data to each other or to a central (server) application.
]]></description>
			<content:encoded><![CDATA[<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style ">
<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
<a class="addthis_button_tweet"></a>
<a class="addthis_counter addthis_pill_style"></a>
</div>
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="https://s7.addthis.com/js/250/addthis_widget.js#username=hseldon"></script>
<!-- AddThis Button END -->


<div style="margin-bottom: 30px;"><span style="display: none;">.</span></div>


<ul>
<li><a href="/files_u/blog/code/async_named_pipes_src.zip"><span style="font-size:13px;"><strong>Download Source Code</strong></span></a></li>
<li><a href="/files_u/blog/code/async_named_pipes_demo.zip"><span style="font-size:13px;"><strong>Download Demo Project</strong></span></a></li>
</ul>

<img src="/files_u/blog/img/async_named_pipes.png" alt="XML parsing using SAX" />
<br />
<br />
<br />
<h2>Introduction</h2>
This is a client/server implementation of <a href="
https://en.wikipedia.org/wiki/Inter-process_communication">Inter Process Communication</a> using Asynchronous Named Pipes with IO completion ports to achieve scalability in situations where several applications need to send and receive large chunks of data to each other or to a central (server) application.<br />
Named pipes provide a flexible and rather easy to implement IPC model which has a message read communication mode where a "client" process can send a message to a "server" process and get an answer to that message.<br />
IO Completion ports, though more known for their use with sockets in server applications,  can also be used with files, directories and pipes and they provide an efficient way for handling concurrent asynchronous IO requests.

<br /><br />
<h2>Using the Code</h2>

Creating the server:

<pre class="brush: cpp; title: ;">

//this function will be called when a message is received
//and can be given an answer in pAnswerBuf to pass to the sender
VOID WINAPI Callback(
  LPCVOID	pMessage,
  DWORD		dwMessageLen,
  LPVOID	pAns,
  DWORD*	pdwAnsLen)
{

}

CAsyncPipesServer2 myPipeServer;
myPipeServer.Create(_T(&quot;SAMPLEIPC1&quot;), Callback);

</pre>

<br /><br />
Sending a message to server:

<pre class="brush: cpp; title: ;">

	CAsyncPipesClient2 myPipe;

	if (!myPipe.SendMsg(_T(&quot;SAMPLEIPC1&quot;),
                  (PVOID)pBuff,
                  nLenBuff,
                  szAns,
                  nAnsLen,
                  INFINITE))
	{ .... }
</pre>

<br /><br />
<h2>How Does It Work</h2>
<h3>Server Side</h3>
After creating a completion port we create a separate thread for creating pipe instances that will wait for new connections from clients. This thread will create a predefined number of instances and then wait for a signal from the main thread. When new clients connect to the server, using up pending pipe instances, main thread signals the pipe instances thread to create more. This way we don't hold up the main queue polling thread too much and replace the used up pending pipe instances as soon as possible.
After that we issue a <span style="color: #800000;">ReadFile</span> call to read data a newly connected client has sent.
<br />
<pre class="brush: cpp; title: ;">
		case OP_CONNECT:
			{
				////////////////////////////////////////////////////////////

				{
					CXCritSec::CLocker (p-&gt;m_csOlp);
					--p-&gt;m_nPendingConnects;
				}

				p-&gt;m_eventMoreConnects.Set();


				///////////////////////////////////////////////////////////

				pOverlapPlus-&gt;nOpCode = OP_READ;
				if (!(pOverlapPlus-&gt;pBuff = new CBuffer))
				{
					_ASSERT(NULL);
					p-&gt;RemoveOverlapped(pOverlapPlus);
					break;
				}

				DWORD dwBytesRead = 0;

				if (!ReadFile(pOverlapPlus-&gt;hPipe,
						pOverlapPlus-&gt;pBuff-&gt;GetPTR(),
						pOverlapPlus-&gt;pBuff-&gt;GetSize(),
						&amp;dwBytesRead,
						&amp;pOverlapPlus-&gt;ol))
				{
					DWORD dwErr;
					if ((dwErr = GetLastError()) != ERROR_IO_PENDING
						&amp;&amp; dwErr != ERROR_PIPE_LISTENING)
					{
						_ASSERT(NULL);
						p-&gt;RemoveOverlapped(pOverlapPlus);
						break;
					}

				}
				else //completed immediately
				{
					pOverlapPlus-&gt;pBuff-&gt;SetCurrLen(dwBytesRead);

					PostQueuedCompletionStatus(p-&gt;m_hIOCP,
						dwBytesRead,
						(ULONG_PTR)pOverlapPlus-&gt;hPipe,
						&amp;pOverlapPlus-&gt;ol);
				}

			}
			break;


</pre>

<br /><br />

Once read is complete we create a new thread in which we will call the callback function supplied during creation of the server this is because we want to return to <span style="color: #800000;">GetQueuedCompletionStatus</span> as soon as possible otherwise we unnecessarily delay both new connections and pending read/write requests this also allows the callback function to safely do any lengthy operations if needed.
After that we write any (answer) data the callback function wish to pass on to the client onto the pipe.

<pre class="brush: cpp; title: ;">
//called from a separate thread upon read completion
void CAsyncPipesServer2::OnRead(SOverlapped* pOlp)
{
	CBuffer myBuffAns;
	DWORD dwAns = myBuffAns.GetSize();

	m_pCallback(pOlp-&gt;pBuff-&gt;GetPTR(),
				pOlp-&gt;pBuff-&gt;GetCurrLen(),
				myBuffAns.GetPTR(),
				&amp;dwAns);


	myBuffAns.SetCurrLen(dwAns);
	pOlp-&gt;pBuff-&gt;Assign(myBuffAns);


	DWORD dwWritten = 0;

	if (WriteFile(pOlp-&gt;hPipe,
			pOlp-&gt;pBuff-&gt;GetPTR(),
			pOlp-&gt;pBuff-&gt;GetCurrLen(),
			&amp;dwWritten,
			&amp;pOlp-&gt;ol))
	{
		PostQueuedCompletionStatus(m_hIOCP,
						dwWritten,
						(ULONG_PTR)pOlp-&gt;hPipe,
						&amp;pOlp-&gt;ol);
	}
	else if (GetLastError() != ERROR_IO_PENDING)
	{
		//probably pipe is being closed, or pipe not connected
		RemoveOverlapped(pOlp, true);
	}


}
</pre>

<br /><br />

<h3>Client Side</h3>

There are a couple of ways to send a message to the pipes server, depending on the level of control you want. I wanted to control the timeout for connection establishment and message transfer individually so I am using the second easiest method <span style="color: #800000;">CreateFile</span> + <span style="color: #800000;">WaitNamedPipe</span> + <span style="color: #800000;">TransactNamedPipe</span>. Easiest method being <span style="color: #800000;">CallNamedPipe</span> which is equivalent to calling <span style="color: #800000;">CreateFile</span>, <span style="color: #800000;">WaitNamedPipe</span>, <span style="color: #800000;">WriteFile</span>, <span style="color: #800000;">ReadFile</span> and <span style="color: #800000;">CloseHandle</span>.

<br />
<pre class="brush: cpp; title: ;">
BOOL CAsyncPipesClient2::SendMsg(LPCTSTR  pIpc,
		PVOID   pMessage,
		DWORD   dwMessageLen,
		PVOID   pAns,
		DWORD   dwAnsLen,
		DWORD   dwAnsTimeOut)
{
	tstring strPipeName = _T(&quot;\\\\.\\pipe\\&quot;);
	strPipeName += pIpc;

	HANDLE hPipe;


_BEGIN:

	if ((hPipe = CreateFile(strPipeName.c_str(),
				GENERIC_READ |
				GENERIC_WRITE,
				FILE_SHARE_READ | FILE_SHARE_WRITE,
				NULL,
				OPEN_EXISTING,
				FILE_FLAG_OVERLAPPED,
				NULL)) == INVALID_HANDLE_VALUE)
	{
		if (GetLastError() == ERROR_PIPE_BUSY)
		{
			if (WaitNamedPipe(strPipeName.c_str(), MAX_WAIT_CONNECT))
				goto _BEGIN;
		}
		else
			return FALSE;

		
		//_ASSERT(NULL);

		return FALSE;
	}


	// Pipe connected; change to message-read mode. 
	DWORD dwMode = PIPE_READMODE_MESSAGE; 
	if (!SetNamedPipeHandleState( 
					hPipe,    // pipe handle 
					&amp;dwMode,  // new pipe mode 
					NULL,
					NULL))
	{
		_ASSERT(NULL);
		CloseHandle(hPipe);
		return FALSE;
	}


	OVERLAPPED olp;
	CXEvent eventTransact;

	memset(&amp;olp, 0, sizeof(olp));
	olp.hEvent = eventTransact.GetEvent();

	DWORD dwBytesRead = 0;
	if (!TransactNamedPipe( 
					hPipe,
					pMessage,
					dwMessageLen,
					pAns,
					dwAnsLen,
					&amp;dwBytesRead,
					&amp;olp))
	{
		DWORD dwLastErr = GetLastError();
		if (dwLastErr == ERROR_MORE_DATA) 
		{
			//ReadFile..
		}
		else if (dwLastErr == ERROR_IO_PENDING)
		{
			if (pAns)
				eventTransact.Wait(dwAnsTimeOut);
		}
		else
		{
			CloseHandle(hPipe);
			return FALSE;
		}
	}


	CloseHandle(hPipe); 


	return TRUE;
}

</pre>

<div style="margin-bottom: 50px;"><span style="display: none;">.</span></div>

<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style addthis_32x32_style">
<a class="addthis_button_preferred_1"></a>
<a class="addthis_button_preferred_2"></a>
<a class="addthis_button_preferred_3"></a>
<a class="addthis_button_preferred_4"></a>
<a class="addthis_button_compact"></a>
</div>
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=hseldon"></script>
<!-- AddThis Button END -->

<div style="margin-bottom: 20px;"><span style="display: none;">.</span></div>
]]></content:encoded>
			<wfw:commentRss>https://veridium.net/programming-tutorials/scalable-ipc-using-asynchronous-named-pipes-and-io-completion-ports/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fast XML parsing using SAX (Simple API for XML)</title>
		<link>https://veridium.net/programming-tutorials/fast-xml-parsing-using-sax-simple-api-for-xml/</link>
		<comments>https://veridium.net/programming-tutorials/fast-xml-parsing-using-sax-simple-api-for-xml/#comments</comments>
		<pubDate>Sat, 16 Apr 2011 15:58:22 +0000</pubDate>
		<dc:creator>hseldon</dc:creator>
				<category><![CDATA[cpp]]></category>
		<category><![CDATA[programming-tutorials]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[SAX]]></category>
		<category><![CDATA[Win32 API]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://veridium.net/?p=142</guid>
		<description><![CDATA[Parsing XML files using the SAX (Simple API for XML) event based interface with demo project and source code.]]></description>
			<content:encoded><![CDATA[<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style ">
<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
<a class="addthis_button_tweet"></a>
<a class="addthis_counter addthis_pill_style"></a>
</div>
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="https://s7.addthis.com/js/250/addthis_widget.js#username=hseldon"></script>
<!-- AddThis Button END -->

<div style="margin-bottom: 30px;"><span style="display: none;">.</span></div>


<ul>
<li><a href="/files_u/blog/code/sax-xml-parser-src.zip"><span style="font-size:13px;"><strong>Download Source Code</strong></span></a></li>
<li><a href="/files_u/blog/code/sax-xml-parser-demo.zip"><span style="font-size:13px;"><strong>Download Demo Project</strong></span></a></li>
</ul>

<img src="/files_u/blog/img/xml-parsing-sax.png" alt="XML parsing using SAX" />
<br />
<br />
<br />
<h2>Introduction</h2>

SAX (Simple API for XML) is a fast event based interface for parsing XML files sequentially through a set of callback methods. Unlike <a href="https://en.wikipedia.org/wiki/Document_Object_Model">DOM</a> (Document Object Model) SAX doesn't require memory for in-memory representation of the XML document thus it facilitates handling of large XML files and is best used for extracting small quantities of data from a large XML file.
<br /><br />
<strong>Main Benefits:</strong>
<br />
<br />

<ul>
<li>Supports local or web based XML files.</li>
<li>Parsing can be aborted at any point (before the whole document is parsed).</li>
<li>Includes methods for completing transformations and validation.</li>
<li>Lightweight.</li>
</ul>

<br />
<h3>Using SAX</h3>
It is rather simple to implement SAX. First we implement an abstract COM interface <span style="color: #800000;">ISAXContentHandler</span> which has members to be called to notify us of different elements of the XML document being parsed. Then we create <span style="color: #800000;">SAXXMLReader</span> as we would any COM object (using <span style="color: #800000;">CoCreateInstance</span>) and we set the content handler of the reader (using our aforementioned implementation).
<br />
<pre class="brush: cpp; title: ;">
	CoInitialize(NULL);


	ISAXXMLReader* pRdr = NULL;

	HRESULT hr = CoCreateInstance(
					__uuidof(SAXXMLReader), 
					NULL, 
					CLSCTX_ALL, 
					__uuidof(ISAXXMLReader), 
					(void **)&amp;pRdr);

	if (!FAILED(hr)) 
	{
		ISAXContentHandler* pContentHandler = new CSaxContentHandlerImp;
		hr = pRdr-&gt;putContentHandler(pContentHandler);

		//SAXErrorHandlerImpl * pEc = new SAXErrorHandlerImpl();
		//hr = pRdr-&gt;putErrorHandler(pEc);

		// SAXDTDHandlerImpl * pDc = new SAXDTDHandlerImpl();
		// hr = pRdr-&gt;putDTDHandler(pDc);

		if (FAILED((hr = pRdr-&gt;parseURL((unsigned short*)pPath))))
			wprintf(L&quot;\nError parsing file, code: %08X\n\n&quot;, hr);
		else
			wprintf(L&quot;\n\nSucess\n\n&quot;);

		pRdr-&gt;Release();
		delete pContentHandler;

	}
	else
	{
		wprintf(L&quot;\nError creating COM object, code: %08X\n\n&quot;, hr);
	}

	CoUninitialize();

</pre>

<br />
<br />

Now with each new element found a content handler member will be called to tell us about it, for example the following method will be called when a new element is found:

<br />
<pre class="brush: cpp; title: ;">
HRESULT STDMETHODCALLTYPE CSaxContentHandlerImp::startElement( 
			/* [in] */ unsigned short __RPC_FAR *pwchNamespaceUri,
			/* [in] */ int cchNamespaceUri,
			/* [in] */ unsigned short __RPC_FAR *pwchLocalName,
			/* [in] */ int cchLocalName,
			/* [in] */ unsigned short __RPC_FAR *pwchRawName,
			/* [in] */ int cchRawName,
			/* [in] */ ISAXAttributes __RPC_FAR *pAttributes)
{
	int nAttrCount = 0;
	pAttributes-&gt;getLength(&amp;nAttrCount);


	unsigned short *pAttr = NULL, *pValue = NULL;
	int nAttrLen = 0, nValueLen = 0;


	wprintf(L&quot;Local Name: %s\n&quot;, pwchLocalName);


	wstring str;

	for (int i = 0; i &lt; nAttrCount; ++i)
	{
		pAttributes-&gt;getLocalName(i, &amp;pAttr, &amp;nAttrLen);
		str.assign((wchar_t*)pAttr, nAttrLen);
		wprintf(L&quot;Attribute Name: %s\n&quot;, str.c_str());

		pAttributes-&gt;getValue(i, &amp;pValue, &amp;nValueLen);
		str.assign((wchar_t*)pValue, nValueLen);
		wprintf(L&quot;Attribute Value: %s\n&quot;, str.c_str());
	}


	return S_OK;
}

</pre>

<br />
<br />

<h3>References</h3>
<ul>
<li>
<a href="http://msdn.microsoft.com/en-us/library/ms757049%28v=vs.85%29.aspx">Frequently Asked Questions about SAX2 </a>
</li>
<li>
<a href="http://en.wikipedia.org/wiki/Simple_API_for_XML">Simple API for XML</a>
</li>
</ul>



<div style="margin-bottom: 50px;"><span style="display: none;">.</span></div>

<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style addthis_32x32_style">
<a class="addthis_button_preferred_1"></a>
<a class="addthis_button_preferred_2"></a>
<a class="addthis_button_preferred_3"></a>
<a class="addthis_button_preferred_4"></a>
<a class="addthis_button_compact"></a>
</div>
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=hseldon"></script>
<!-- AddThis Button END -->

<div style="margin-bottom: 20px;"><span style="display: none;">.</span></div>

]]></content:encoded>
			<wfw:commentRss>https://veridium.net/programming-tutorials/fast-xml-parsing-using-sax-simple-api-for-xml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTTP Client Using WININET Asynchronously</title>
		<link>https://veridium.net/programming-tutorials/http-client-async-wininet/</link>
		<comments>https://veridium.net/programming-tutorials/http-client-async-wininet/#comments</comments>
		<pubDate>Sun, 20 Mar 2011 11:46:02 +0000</pubDate>
		<dc:creator>hseldon</dc:creator>
				<category><![CDATA[cpp]]></category>
		<category><![CDATA[programming-tutorials]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Win32 API]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[WININET]]></category>

		<guid isPermaLink="false">http://veridium.net/?p=135</guid>
		<description><![CDATA[HTTP requests Using WININET API asynchronously. Full source code + demo project.]]></description>
			<content:encoded><![CDATA[<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style ">
<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
<a class="addthis_button_tweet"></a>
<a class="addthis_counter addthis_pill_style"></a>
</div>
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="https://s7.addthis.com/js/250/addthis_widget.js#username=hseldon"></script>
<!-- AddThis Button END -->

<div style="margin-bottom: 30px;"><span style="display: none;">.</span></div>


<ul>
<li><a href="/files_u/blog/code/asynchronous-wininet-src.zip"><span style="font-size:13px;"><strong>Download Source Code</strong></span></a></li>
<li><a href="/files_u/blog/code/asynchronous-wininet-demo.zip"><span style="font-size:13px;"><strong>Download Demo Project</strong></span></a></li>
</ul>

<img src="/files_u/blog/img/asynchronous-wininet.png" alt="async wininet" />
<br />
<br />
<br />
<h2>Introduction</h2>


WININET is a set of easy to use APIs that enable you to interact with the FTP and HTTP protocols without having to worry about protocol specifications or even Winsock calls. Other <a href="https://msdn.microsoft.com/en-us/library/aa383630%28v=vs.85%29.aspx">WININET</a> benefits include:
<br />
<br />
<ul>
<li>Built in caching support</li>
<li>Supports proxy servers</li>
<li>Supports IPv6</a>
</ul>

<h3>Using The Code</h3>

Attached with this post is a wrapper class around the WININET API demonstrating how to use it asynchronously, this is how to use the class:

<br />
<pre class="brush: cpp; title: ;">

#include &quot;wininet.h&quot;

....

	CWininet myWininet;
	if (myWininet.Connect(&quot;http://veridium.net&quot;), 80, _T(&quot;AsyncWininet&quot;), 20000)  //timeout
	{
		if (myWininet.SendRequest(&quot;/&quot;, _T(&quot;&quot;), 20000)) //timeout
		//index page, no referer
		{
			char szBuff[1024];

			while ((nLen = myWininet.Read((PBYTE)szBuff, 1024, 20000)) &gt; 0)
			{
				szBuff[nLen] = 0;
				.....
			}
		}
	}
</pre>

<br />
<br />

<h3>How Does It Work</h3>

First we call <span style="color: #800000;">InternetOpen</span> using <span style="color: #800000;">INTERNET_FLAG_ASYNC</span>:
<br />
<pre class="brush: cpp; title: ;">
	if (!(m_hInstance = InternetOpen(lpszAgent, 
					INTERNET_OPEN_TYPE_PRECONFIG,
					NULL,
					NULL,
					INTERNET_FLAG_ASYNC)))
	{
               return FALSE;
	}
</pre>

<br />
<br />

Then we set a callback function that would be called by the system when an asynchronous operation complets:

<br />
<pre class="brush: cpp; title: ;">

	if (InternetSetStatusCallback(m_hInstance,
				(INTERNET_STATUS_CALLBACK)&amp;Callback)
				== INTERNET_INVALID_STATUS_CALLBACK)
	{
		return FALSE;
	}

</pre>

<br />
<br />

Now in subsequent API calls we pass a predefined flag so that we recognize this operation and this object from inside the callback function:

<br />
<pre class="brush: cpp; title: ;">

	m_context.dwContext	= CONTEXT_CONNECT;
	m_context.pObj		= this;

	m_hConnect = InternetConnect(m_hInstance, 
					lpszAddr,
					uPort,
					NULL,
					NULL,
					INTERNET_SERVICE_HTTP,
					INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_CACHE_WRITE,
					(DWORD)&amp;m_context);
</pre>

<br />
<br />

And inside the callback we signal an event for each completed operation to notifiy the waiting thread:

<br />
<pre class="brush: cpp; title: ;">
	switch(pContext-&gt;dwContext)
	{
	case CONTEXT_CONNECT:
		if (dwInternetStatus == INTERNET_STATUS_HANDLE_CREATED)
		{
			INTERNET_ASYNC_RESULT *pRes = (INTERNET_ASYNC_RESULT *)lpStatusInfo;
			pContext-&gt;pObj-&gt;m_hConnect = (HINTERNET)pRes-&gt;dwResult;
			SetEvent(pContext-&gt;pObj-&gt;m_hConnectedEvent);
		}
		break;
	......

	}
</pre>



<br />
<br />
<h2>History</h2>

<p>20 MAR 11: first release.</p>



<div style="margin-bottom: 50px;"><span style="display: none;">.</span></div>

<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style addthis_32x32_style">
<a class="addthis_button_preferred_1"></a>
<a class="addthis_button_preferred_2"></a>
<a class="addthis_button_preferred_3"></a>
<a class="addthis_button_preferred_4"></a>
<a class="addthis_button_compact"></a>
</div>
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="https://s7.addthis.com/js/250/addthis_widget.js#username=hseldon"></script>
<!-- AddThis Button END -->

<div style="margin-bottom: 20px;"><span style="display: none;">.</span></div>

]]></content:encoded>
			<wfw:commentRss>https://veridium.net/programming-tutorials/http-client-async-wininet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>(GDI) Scheduler Control</title>
		<link>https://veridium.net/programming-tutorials/gdi-scheduler-control/</link>
		<comments>https://veridium.net/programming-tutorials/gdi-scheduler-control/#comments</comments>
		<pubDate>Sat, 19 Feb 2011 21:10:16 +0000</pubDate>
		<dc:creator>hseldon</dc:creator>
				<category><![CDATA[cpp]]></category>
		<category><![CDATA[programming-tutorials]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[control]]></category>
		<category><![CDATA[GDI]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://veridium.net/?p=130</guid>
		<description><![CDATA[This is a simple scheduler control created using plain GDI API. Full source code + demo project.
]]></description>
			<content:encoded><![CDATA[<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style ">
<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
<a class="addthis_button_tweet"></a>
<a class="addthis_counter addthis_pill_style"></a>
</div>
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="https://s7.addthis.com/js/250/addthis_widget.js#username=hseldon"></script>
<!-- AddThis Button END -->

<div style="margin-bottom: 30px;"><span style="display: none;">.</span></div>


<ul>
<li><a href="/files_u/blog/code/scheduler-control-src.zip"><span style="font-size:13px;"><strong>Download Source Code</strong></span></a></li>
<li><a href="/files_u/blog/code/scheduler-control-demo.zip"><span style="font-size:13px;"><strong>Download Demo Project</strong></span></a></li>
</ul>

<img src="/files_u/blog/img/scheduler-control.png" alt="Scheduler Control" />
<br />
<br />
<br />
<h2>Introduction</h2>
This is a simple scheduler control created using plain GDI API. Lines drawing done using <span style="color: #800000;">MoveToEx</span> and <span style="color: #800000;">LineTo</span>. Coloring done using <span style="color: #800000;">FillRect</span>. All wrapped up in one class <span style="color: #800000;">CScheculerCtrl</span> without any MFC (though the demo project is in MFC).

<br />
<br />
<br />

<h2>How to Use</h2>

Initialization: (e.g.: in <span style="color: #800000;">OnInitDialog</span>)

<pre class="brush: cpp; title: ;">

//left margin: 40px, top margin: 25px
m_mySchedulerCtrl.Init(40, 25);


</pre>

<br />
<br />

Painting: (e.g.: in <span style="color: #800000;">OnPaint</span>)

<pre class="brush: cpp; title: ;">
m_mySchedulerCtrl.Paint(dc.GetSafeHdc());
</pre>

<br />
<br />

On mouse hover handling (e.g.: in <span style="color: #800000;">OnMouseMove</span> )

<pre class="brush: cpp; title: ;">
	CDC* pDC = GetDC();

    //rect structs that will hold changed regions coordinates
    //in case you are using a memroy DC and want to only paint updated regions only
    //to the final DC
	RECT rc1, rc2;
	memset(&amp;rc1, 0, sizeof(rc1));
	memset(&amp;rc2, 0, sizeof(rc2));

	m_mySchedulerCtrl.OnMouseMove(pDC-&gt;GetSafeHdc(), point.x, point.y, &amp;rc1, &amp;rc2);
	ReleaseDC(pDC);

</pre>

<br />

Mouse click handling, in <span style="color: #800000;">OnLButtonDown</span>:
<br />

<pre class="brush: cpp; title: ;">
	CDC* pDC = GetDC();

	RECT rc;
	memset(&amp;rc, 0, sizeof(rc));

	m_mySchedulerCtrl.OnMouseLClick(pDC-&gt;GetSafeHdc(), point.x, point.y, &amp;rc);
	ReleaseDC(pDC);
</pre>

<br />
<br />
<h2>History</h2>

<p>19 FEB 11: first release.</p>



<div style="margin-bottom: 50px;"><span style="display: none;">.</span></div>

<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style addthis_32x32_style">
<a class="addthis_button_preferred_1"></a>
<a class="addthis_button_preferred_2"></a>
<a class="addthis_button_preferred_3"></a>
<a class="addthis_button_preferred_4"></a>
<a class="addthis_button_compact"></a>
</div>
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=hseldon"></script>
<!-- AddThis Button END -->

<div style="margin-bottom: 20px;"><span style="display: none;">.</span></div>

]]></content:encoded>
			<wfw:commentRss>https://veridium.net/programming-tutorials/gdi-scheduler-control/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous File System Monitoring</title>
		<link>https://veridium.net/programming-tutorials/asynchronous-file-system-monitor/</link>
		<comments>https://veridium.net/programming-tutorials/asynchronous-file-system-monitor/#comments</comments>
		<pubDate>Thu, 13 Jan 2011 15:19:49 +0000</pubDate>
		<dc:creator>hseldon</dc:creator>
				<category><![CDATA[cpp]]></category>
		<category><![CDATA[programming-tutorials]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[file monitor]]></category>
		<category><![CDATA[Filesystem]]></category>
		<category><![CDATA[folder monitor]]></category>
		<category><![CDATA[Win32 API]]></category>

		<guid isPermaLink="false">http://veridium.net/?p=127</guid>
		<description><![CDATA[Asynchronous file system monitoring using ReadDirectoryChangesW and IO completion ports in C++.
Full Source code + demonstration project.]]></description>
			<content:encoded><![CDATA[<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style ">
<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
<a class="addthis_button_tweet"></a>
<a class="addthis_counter addthis_pill_style"></a>
</div>
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="https://s7.addthis.com/js/250/addthis_widget.js#username=hseldon"></script>
<!-- AddThis Button END -->

<div style="margin-bottom: 30px;"><span style="display: none;">.</span></div>


<ul>
<li><a href="/files_u/blog/code/file-sys-monitor-src.zip"><span style="font-size:13px;"><strong>Download Source Code</strong></span></a></li>
<li><a href="/files_u/blog/code/file-sys-monitor-demo.zip"><span style="font-size:13px;"><strong>Download Demo Project</strong></span></a></li>
</ul>

<img src="/files_u/blog/img/folder-monitor.png" alt="Asynchronous file monitoring" />
<br />
<br />
<br />
<h2>Introduction</h2>
There are 3 main methods for monitoring the file system on a Windows machine. Kernel mode filesystem drivers, the <span style="color: #800000;">FindFirstChangeNotification</span> API and the <span style="color: #800000;">ReadDirectoryChangesW</span> API. If the main purpose of your application is not monitoring the file system or bypassing/overriding file system IO operations then Kernel mode file system drivers would be too much unnecessary work. <span style="color: #800000;">FindFirstChangeNotification</span> is a good alternative but it tells you that a change took place but not which file was changed or how (added, modified, removed..etc.)
<span style="color: #800000;">ReadDirectoryChangesW</span> on the other hand, when called asynchronously, is reasonably efficient and provides detailed info on which file changed and how.
<br /><br />
There are also 3 approaches to using <span style="color: #800000;">ReadDirectoryChangesW</span> asynchronously: 
<br /><br />
<ul>
 <li><strong>GetOverlappedResult:</strong> this requires an event object for each directory you'd like to monitor.
<div style="margin-bottom: 15px;"><span style="display: none;">.</span></div></li>


 <li><strong>Using a completion routine:</strong> this requires that you provide a completion function (completion routine) that would be called by the system whenever a change occurs. 
<div style="margin-bottom: 15px;"><span style="display: none;">.</span></div></li>

 <li><strong>Using IO completion ports:</strong> in this method we associate handles of directories to be monitored with a completion port much like we associate it with sockets. This I think is more scalable/efficient than the two other methods and that's what we are implementing here.</li>
</ul>

<br />
<h2>Using the Code</h2>

<pre class="brush: cpp; title: ;">

#include &quot;FileSysMon.h&quot;

.....

	CFileSysMon myFileSysMon;
	if (!myFileSysMon.Init())
	{
		MessageBox(0, _T(&quot;Initialization Error&quot;), NULL, MB_ICONERROR);
		return 0;
	}


	if (myFileSysMon.AddPath(_T(&quot;c:\\FolderToMonitor&quot;)) != E_FILESYSMON_SUCCESS)
		MessageBox(hWnd, _T(&quot;Error adding file to monitoring list&quot;), NULL, MB_ICONERROR);


	VECCHANGES vecChanges;
	while (myFileSysMon.GetQueuedStatus(vecChanges, INFINITE) == E_FILESYSMON_SUCCESS) //INFINITE or a timeout value in milliseconds
	{
		//vecChanges.at(i).strFilePath
		//if ((vecChanges.at(i).dwAction &amp; FILE_ACTION_ADDED) == FILE_ACTION_ADDED)
		//if ((vecChanges.at(i).dwAction &amp; FILE_ACTION_REMOVED) == FILE_ACTION_REMOVED)
		//if ((vecChanges.at(i).dwAction &amp; FILE_ACTION_MODIFIED) == FILE_ACTION_MODIFIED)
		//if ((vecChanges.at(i).dwAction &amp; FILE_ACTION_RENAMED_OLD_NAME) == FILE_ACTION_RENAMED_OLD_NAME)
		//if ((vecChanges.at(i).dwAction &amp; FILE_ACTION_RENAMED_NEW_NAME) == FILE_ACTION_RENAMED_NEW_NAME)

		.....
	}

</pre>

<br />
<br />
<h2>How Does It Work</h2>

 First we create a completion port using <span style="color: #800000;">CreateIOCompletionPort</span>:

<pre class="brush: cpp; title: ;">
	if (!(m_hIOCP = CreateIoCompletionPort(
							(HANDLE)INVALID_HANDLE_VALUE,
							NULL,
							0,
							nThreads)))
	{
		m_nLastError = GetLastError();
		return false;
	}

</pre>

<br />
<br />

Then we associate each directory we would like to monitor with that completion port also using <span style="color: #800000;">CreateIOCompletionPort</span>:

<pre class="brush: cpp; title: ;">
	if (CreateIoCompletionPort(pDir-&gt;hFile, m_hIOCP, (ULONG_PTR) pDir-&gt;hFile, 0) == NULL)
	{
		m_nLastError = GetLastError();
		CloseHandle(pDir-&gt;hFile);
		delete pDir;

		return E_FILESYSMON_ERRORADDTOIOCP;
	}

</pre>

<br />
<br />

And we call <span style="color: #800000;">ReadDirectoryChangesW</span> on the directory handle:

<pre class="brush: cpp; title: ;">
	if (!ReadDirectoryChangesW(pDir-&gt;hFile,
					pDir-&gt;pBuff,
					MAX_BUFF_SIZE * sizeof(FILE_NOTIFY_INFORMATION),
					bSubTree,
					dwNotifyFilters, 
					&amp;dwBytesReturned,
					&amp;pDir-&gt;ol,
					NULL))
	{
		m_nLastError = GetLastError();
		CloseHandle(pDir-&gt;hFile);
		delete pDir;
	
		return E_FILESYSMON_ERRORREADDIR;
	}


</pre>

<br />
<br />
 Then we query the completion port for status messages:

<pre class="brush: cpp; title: ;">
	if (!GetQueuedCompletionStatus(m_hIOCP, &amp;dwBytesXFered, &amp;ulKey, &amp;pOl, dwTimeOut))
	{
		if ((m_nLastError = GetLastError()) == WAIT_TIMEOUT)
			return E_FILESYSMON_NOCHANGE;
		return E_FILESYSMON_ERRORDEQUE;
	}

</pre>


<br />
<h2>History</h2>

<p>13 JAN 11: first release.</p>



<div style="margin-bottom: 50px;"><span style="display: none;">.</span></div>

<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style addthis_32x32_style">
<a class="addthis_button_preferred_1"></a>
<a class="addthis_button_preferred_2"></a>
<a class="addthis_button_preferred_3"></a>
<a class="addthis_button_preferred_4"></a>
<a class="addthis_button_compact"></a>
</div>
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=hseldon"></script>
<!-- AddThis Button END -->

<div style="margin-bottom: 20px;"><span style="display: none;">.</span></div>
]]></content:encoded>
			<wfw:commentRss>https://veridium.net/programming-tutorials/asynchronous-file-system-monitor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous Client Socket Class Without MFC</title>
		<link>https://veridium.net/programming-tutorials/asynchronous-client-socket-class/</link>
		<comments>https://veridium.net/programming-tutorials/asynchronous-client-socket-class/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 21:48:28 +0000</pubDate>
		<dc:creator>hseldon</dc:creator>
				<category><![CDATA[cpp]]></category>
		<category><![CDATA[programming-tutorials]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Win32 API]]></category>
		<category><![CDATA[Windows Sockets]]></category>

		<guid isPermaLink="false">http://veridium.net/?p=115</guid>
		<description><![CDATA[Asynchronous (nonblocking) client socket wrapper class in C++ without using MFC.<br /> Full Source code + demonstration project.]]></description>
			<content:encoded><![CDATA[<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style ">
<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>
<a class="addthis_button_tweet"></a>
<a class="addthis_counter addthis_pill_style"></a>
</div>
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="https://s7.addthis.com/js/250/addthis_widget.js#username=hseldon"></script>
<!-- AddThis Button END -->

<div style="margin-bottom: 30px;"><span style="display: none;">.</span></div>

<ul>
<li><a href="/files_u/blog/code/async-socket-win32-src.zip"><span style="font-size:13px;"><strong>Download Source Code</strong></span></a></li>
<li><a href="http://veridium.net/files_u/blog/code/async-socket-win32-demo.zip"><span style="font-size:13px;"><strong>Download Demo Project</strong></span></a></li>
</ul>

<img src="/files_u/blog/img/async-socket-win32.png", alt="Asynchronous socket class" />
<br />
<br />
<br />
<h2>Introduction</h2>

<p>I created this class while trying to avoid having <span style="color: #800000;">recv</span> hang/block indefinitely in a simple client application I was working on, without using MFC. 
<span style="color: #800000;">recv</span> can hang for a variety of reasons most common is untimely calling of <span style="color: #800000;">recv</span> or calling it when the remote server doesn't send data it was supposed to send, e.g.: because of a malformed request.
 </p>


<h2>Using the code</h2>

    <pre class="brush: cpp; title: ;">
    
    #include &quot;XSocket.h&quot;
    
    ....
    
	CXSocket mySock;

	if (!mySock.Init()) //initalize winsocks
	    return false; //failed
	    
	//////////////////////////////////////////////////////////////////////////
		
	if (!mySock.Connect(pHostName, nPort))
	{
	    int nError = mySock.GetLastError();
	    return false; //failed to connect
	}
	
	/////////////////////////////////////////////////////////////////////////
	
	// Send a buffer, 5 seconds timeout
	// further error checking omitted for previty
	
	int nLen = 0;
	if (mySock.Send(szBuff, strlen(szBuff), nLen, 5000) != E_XSOCKET_SUCCESS)
	    return false;
	   
 
	/////////////////////////////////////////////////////////////////////////
	
	// Receive server's response, 5 seconds time out
	// last argument is optional, if not used Rec will return immediately
	
	do
	{
	    if (mySock.Recv(szBuff, sizeof(szBuff) - 1, nLen, 5000) 
			!= E_XSOCKET_SUCCESS)
		{
			break;
		}
	}
    while (nLen == sizeof(szBuff));	
    
    
    //////////////////////////////////////////////////////////////////////////
    
    // Optional: explicitly close the socket, if not called socket will be closed
    // auto on destruction
    
    mySock.Close();

	</pre>

<p />

<p>Canceling a request, regardless of timeout:</p>

<pre class="brush: cpp; title: ;">
    mySock.Abort();
</pre>

<br />
<p>Checking if there is data available for reading, this can be called at any time after a successful <span style="color: #800000;">Connect</span>:</p>
<pre class="brush: cpp; title: ;">long lLen = mySocket.GetLenDataAvail();</pre>

<br />
<br />

<h2>Points of Interest</h2>

<p>We turn on nonblocking mode for a socket and at the same time attach an event object by calling:</p>

<pre class="brush: cpp; title: ;">WSAEventSelect(hSocket, hEvent, FD_READ | FD_WRITE | FD_CLOSE)</pre>

This will attach <span style="color: #800000;">hEvent</span> to <span style="color: #800000;">hSocket</span> so that when there is a new read, write and close event
<span style="color: #800000;">hEvent</span> will be signaled. Also<span style="color: #800000;">WSAEventSelect</span> automatically turns on nonblocking mode for <span style="color: #800000;">hSocket</span> as well.

<div style="margin-bottom: 30px;"><span style="display: none;">.</span></div>

<h3>Sending Data</h3>

<div style="margin-bottom: 5px;"><span style="display: none;">.</span></div>

<p>Data sending code looks like this:</p>
    <pre class="brush: cpp; title: ;">
int CXSocket::Send(const char* pBuff, int nLen, int&amp; nLenSent, DWORD dwTimeOut)
{	

_BEGIN:

	int nRet = 0;
	m_nLastError = 0;

	if ((nRet = send(m_hSocket, pBuff, nLen, 0)) &gt; 0 || (m_nLastError = WSAGetLastError()) != WSAEWOULDBLOCK)
		return E_XSOCKET_SUCCESS;


	///////////////////////////////////////////////////////////////////////////////////

	HANDLE arrHandles[2];

	arrHandles[0] = m_eventNet.GetEvent();
	arrHandles[1] = m_eventStop.GetEvent();

	DWORD dwWaitRes = WaitForMultipleObjects(2, arrHandles, FALSE, dwTimeOut); 
	
	if (dwWaitRes == WAIT_OBJECT_0 + 1)
		return E_XSOCKET_ABORTED;
	else if (dwWaitRes != WAIT_OBJECT_0)
		return E_XSOCKET_TIMEDOUT;


	//////////////////////////////////////////////////////////////////////////////////

	WSANETWORKEVENTS myNetEvents;

	if (WSAEnumNetworkEvents(m_hSocket, m_eventNet.GetEvent(), &amp;myNetEvents) != 0)
	{
		m_nLastError = WSAGetLastError();
		return E_XSOCKET_SOCKERR;
	}

	if ((myNetEvents.lNetworkEvents &amp; FD_WRITE) != FD_WRITE)
	{
		goto _BEGIN;
	}

	if (myNetEvents.iErrorCode[FD_WRITE_BIT] != 0)
		return E_XSOCKET_SOCKERR;


	/////////////////////////////////////////////////////////////////////////////////////

	nLenSent = send(m_hSocket, pBuff, nLen, 0);


	return E_XSOCKET_SUCCESS;
}
    </pre>

<p>What we do here is first issue a <span style="color: #800000;">Send</span> request, if our request can be fulfilled data will be sent immediately and return value of <span style="color: #800000;">Send</span> will be the length of data actually sent. Otherwise
our request will be queued and <span style="color: #800000;">Send</span> will return <span style="color: #800000;">WSAEWOULDBLOCK</span>. The Winsock subsystem will then notify us when it is possible to send our data by signaling the event we attached to
the socket earlier. At that point we call <span style="color: #800000;">WSAEnumNetworkEvents</span> to make sure the event is an FD_WRITE if it is not we continue waiting for FD_WRITE (if <span style="color: #800000;">dwTimeOut</span> is greater than zero).</p>

<div style="margin-bottom: 30px;"><span style="display: none;">.</span></div>


<h3>Receiving Data</h3>

<div style="margin-bottom: 5px;"><span style="display: none;">.</span></div>


<p>Data receiving code looks like this:</p>

<pre class="brush: cpp; title: ;">
int CXSocket::Recv(char* pBuff, int nLen, int&amp; nLenReceived, DWORD dwTimeOut)
{

_BEGIN:

	///////////////////////////////////////////////////////////////////////////////////

	HANDLE arrHandles[2];

	arrHandles[0] = m_eventNet.GetEvent();
	arrHandles[1] = m_eventStop.GetEvent();

	DWORD dwWaitRes = WaitForMultipleObjects(2, arrHandles, FALSE, dwTimeOut); 
	
	if (dwWaitRes == WAIT_OBJECT_0 + 1)
		return E_XSOCKET_ABORTED;
	else if (dwWaitRes != WAIT_OBJECT_0)
		return E_XSOCKET_TIMEDOUT;


	////////////////////////////////////////////////////////////////////////////////////

	WSANETWORKEVENTS myNetEvents;

	if (WSAEnumNetworkEvents(m_hSocket, m_eventNet.GetEvent(), &amp;myNetEvents) != 0)
	{
		m_nLastError = WSAGetLastError();
		return E_XSOCKET_SOCKERR;
	}

	if ((myNetEvents.lNetworkEvents &amp; FD_READ) != FD_READ)
		goto _BEGIN;

	if (myNetEvents.iErrorCode[FD_READ_BIT] != 0)
		return E_XSOCKET_SOCKERR;


	/////////////////////////////////////////////////////////////////////////////////////

	if ((nLenReceived = recv(m_hSocket, pBuff, nLen, 0)) == WSAEWOULDBLOCK)
	{
		nLenReceived = 0;
		return E_XSOCKET_NOMOREDATA;
	}


	return E_XSOCKET_SUCCESS;
}
</pre>

<p>What we do is wait for an FD_READ event. If we get it we call <span style="color: #800000;">recv</span> to read the data available.</p>

<br />
<h2>History</h2>

<p>03 DEC 10 first release.</p>


<div style="margin-bottom: 50px;"><span style="display: none;">.</span></div>

<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style addthis_32x32_style">
<a class="addthis_button_preferred_1"></a>
<a class="addthis_button_preferred_2"></a>
<a class="addthis_button_preferred_3"></a>
<a class="addthis_button_preferred_4"></a>
<a class="addthis_button_compact"></a>
</div>
<script type="text/javascript">var addthis_config = {"data_track_clickback":true};</script>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=hseldon"></script>
<!-- AddThis Button END -->

<div style="margin-bottom: 20px;"><span style="display: none;">.</span></div>
]]></content:encoded>
			<wfw:commentRss>https://veridium.net/programming-tutorials/asynchronous-client-socket-class/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Home Tab</title>
		<link>https://veridium.net/homeguard-screenshots/home-tab/</link>
		<comments>https://veridium.net/homeguard-screenshots/home-tab/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 15:08:33 +0000</pubDate>
		<dc:creator>webadmin</dc:creator>
				<category><![CDATA[HomeGuard Screenshots]]></category>
		<category><![CDATA[Activity Monitor]]></category>
		<category><![CDATA[addictive gaming]]></category>
		<category><![CDATA[internet addiction]]></category>
		<category><![CDATA[parental control]]></category>
		<category><![CDATA[porn filter]]></category>
		<category><![CDATA[Website filtering]]></category>

		<guid isPermaLink="false">http://veridium.net/?p=20</guid>
		<description><![CDATA[The Home tab shows total monitoring records counts and buttons for stopping/starting monitoring (HomeGuard starts automatically at Windows startup), changing monitoring settings, changing the administrative password, uninstalling HomeGuard and online help.]]></description>
			<content:encoded><![CDATA[The Home tab shows total monitoring records counts and buttons for stopping/starting monitoring (HomeGuard starts automatically at Windows startup), changing monitoring settings, changing the administrative password, uninstalling HomeGuard and online help.

<div style="margin-bottom: 40px;"><span style="display: none;">.</span></div>

<a href="http://veridium.net/homeguard-activity-monitor"><strong><span style="text-decoration: underline;">Features</span></strong></a>&nbsp; &nbsp;

<span style="text-decoration: underline;"><a href="http://veridium.net/homeguard-activity-monitor/screenshots"><strong>Screenshots</strong></a></span>&nbsp; &nbsp;

<a href="http://veridium.net/homeguard-activity-monitor/buy-now"><strong><span style="text-decoration: underline;">Buy Now</span></strong></a>&nbsp; &nbsp;

<a href="http://veridium.net/homeguard-activity-monitor/help"><strong><span style="text-decoration: underline;">Help And FAQ</span></strong></a>&nbsp; &nbsp;


<div style="margin-bottom: 40px;"><span style="display: none;">.</span></div>

]]></content:encoded>
			<wfw:commentRss>https://veridium.net/homeguard-screenshots/home-tab/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web Filter</title>
		<link>https://veridium.net/homeguard-screenshots/web-filter/</link>
		<comments>https://veridium.net/homeguard-screenshots/web-filter/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 15:07:17 +0000</pubDate>
		<dc:creator>webadmin</dc:creator>
				<category><![CDATA[HomeGuard Screenshots]]></category>
		<category><![CDATA[HomeGuard]]></category>
		<category><![CDATA[Website filtering]]></category>

		<guid isPermaLink="false">http://veridium.net/?p=65</guid>
		<description><![CDATA[Web filter blocks porn websites and records details of visited websites including time spent on each website and program used to access it.]]></description>
			<content:encoded><![CDATA[This tab shows total time spent on each site visit and program used to access the site. You can view individual pages visited from each site by right clicking the title box and selecting 'View All Files'.
<div style="margin-bottom: 40px;"><span style="display: none;">.</span></div>

<a href="http://veridium.net/homeguard-activity-monitor"><strong><span style="text-decoration: underline;">Features</span></strong></a>&nbsp; &nbsp;

<span style="text-decoration: underline;"><a href="http://veridium.net/homeguard-activity-monitor/screenshots"><strong>Screenshots</strong></a></span>&nbsp; &nbsp;

<a href="http://veridium.net/homeguard-activity-monitor/buy-now"><strong><span style="text-decoration: underline;">Buy Now</span></strong></a>&nbsp; &nbsp;

<a href="http://veridium.net/homeguard-activity-monitor/help"><strong><span style="text-decoration: underline;">Help And FAQ</span></strong></a>&nbsp; &nbsp;


<div style="margin-bottom: 40px;"><span style="display: none;">.</span></div>]]></content:encoded>
			<wfw:commentRss>https://veridium.net/homeguard-screenshots/web-filter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Screen Capture</title>
		<link>https://veridium.net/homeguard-screenshots/screen-capture/</link>
		<comments>https://veridium.net/homeguard-screenshots/screen-capture/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 15:06:44 +0000</pubDate>
		<dc:creator>webadmin</dc:creator>
				<category><![CDATA[HomeGuard Screenshots]]></category>
		<category><![CDATA[HomeGuard]]></category>

		<guid isPermaLink="false">http://veridium.net/?p=63</guid>
		<description><![CDATA[Thumbnail view for quickly flipping through many shots and full size view for closer observation. Screen shots can be taken at specific intervals and at specific times of day or days of week (default is all day everyday). HomeGuard can also take shots when an event occurs, e.g.: website visits, keywords...
]]></description>
			<content:encoded><![CDATA[Thumbnail view for quickly flipping through many shots and full size view for closer observation. Screen shots can be taken at specific intervals and at specific times of day or days of week (default is all day everyday). HomeGuard can also take shots when an event occurs, e.g.: website visits, keywords...

<div style="margin-bottom: 40px;"><span style="display: none;">.</span></div>

<a href="http://veridium.net/homeguard-activity-monitor"><strong><span style="text-decoration: underline;">Features</span></strong></a>&nbsp; &nbsp;

<span style="text-decoration: underline;"><a href="http://veridium.net/homeguard-activity-monitor/screenshots"><strong>Screenshots</strong></a></span>&nbsp; &nbsp;

<a href="http://veridium.net/homeguard-activity-monitor/buy-now"><strong><span style="text-decoration: underline;">Buy Now</span></strong></a>&nbsp; &nbsp;

<a href="http://veridium.net/homeguard-activity-monitor/help"><strong><span style="text-decoration: underline;">Help And FAQ</span></strong></a>&nbsp; &nbsp;


<div style="margin-bottom: 40px;"><span style="display: none;">.</span></div>]]></content:encoded>
			<wfw:commentRss>https://veridium.net/homeguard-screenshots/screen-capture/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Keylogger</title>
		<link>https://veridium.net/homeguard-screenshots/keylogger/</link>
		<comments>https://veridium.net/homeguard-screenshots/keylogger/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 15:04:39 +0000</pubDate>
		<dc:creator>webadmin</dc:creator>
				<category><![CDATA[HomeGuard Screenshots]]></category>
		<category><![CDATA[HomeGuard]]></category>
		<category><![CDATA[keylogger]]></category>

		<guid isPermaLink="false">http://veridium.net/?p=59</guid>
		<description><![CDATA[Keylogger records show which programs were typed in and program titles at the time of typing.]]></description>
			<content:encoded><![CDATA[Keylogger records show which programs were typed in and program titles at the time of typing.

<div style="margin-bottom: 40px;"><span style="display: none;">.</span></div>

<a href="http://veridium.net/homeguard-activity-monitor"><strong><span style="text-decoration: underline;">Features</span></strong></a>&nbsp; &nbsp;

<span style="text-decoration: underline;"><a href="http://veridium.net/homeguard-activity-monitor/screenshots"><strong>Screenshots</strong></a></span>&nbsp; &nbsp;

<a href="http://veridium.net/homeguard-activity-monitor/buy-now"><strong><span style="text-decoration: underline;">Buy Now</span></strong></a>&nbsp; &nbsp;

<a href="http://veridium.net/homeguard-activity-monitor/help"><strong><span style="text-decoration: underline;">Help And FAQ</span></strong></a>&nbsp; &nbsp;


<div style="margin-bottom: 40px;"><span style="display: none;">.</span></div>]]></content:encoded>
			<wfw:commentRss>https://veridium.net/homeguard-screenshots/keylogger/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
