summaryrefslogtreecommitdiff
path: root/general/echo/umdfSocketEcho
diff options
context:
space:
mode:
Diffstat (limited to 'general/echo/umdfSocketEcho')
-rw-r--r--general/echo/umdfSocketEcho/Driver/Connection.cpp263
-rw-r--r--general/echo/umdfSocketEcho/Driver/FileContext.h30
-rw-r--r--general/echo/umdfSocketEcho/Driver/Queue.cpp580
-rw-r--r--general/echo/umdfSocketEcho/Driver/Queue.h83
-rw-r--r--general/echo/umdfSocketEcho/Driver/SocketEcho.inx89
-rw-r--r--general/echo/umdfSocketEcho/Driver/SocketEcho.rc21
-rw-r--r--general/echo/umdfSocketEcho/Driver/SocketEcho.vcxproj245
-rw-r--r--general/echo/umdfSocketEcho/Driver/SocketEcho.vcxproj.Filters54
-rw-r--r--general/echo/umdfSocketEcho/Driver/connection.h32
-rw-r--r--general/echo/umdfSocketEcho/Driver/device.cpp469
-rw-r--r--general/echo/umdfSocketEcho/Driver/device.h70
-rw-r--r--general/echo/umdfSocketEcho/Driver/devicecontext.h32
-rw-r--r--general/echo/umdfSocketEcho/Driver/dllsup.cpp111
-rw-r--r--general/echo/umdfSocketEcho/Driver/driver.cpp174
-rw-r--r--general/echo/umdfSocketEcho/Driver/driver.h53
-rw-r--r--general/echo/umdfSocketEcho/Driver/exports.def6
-rw-r--r--general/echo/umdfSocketEcho/Driver/internal.h117
-rw-r--r--general/echo/umdfSocketEcho/Exe/internal.h18
-rw-r--r--general/echo/umdfSocketEcho/Exe/socketechoserver.cpp512
-rw-r--r--general/echo/umdfSocketEcho/Exe/socketechoserver.h48
-rw-r--r--general/echo/umdfSocketEcho/Exe/socketechoserver.vcxproj179
-rw-r--r--general/echo/umdfSocketEcho/Exe/socketechoserver.vcxproj.Filters22
-rw-r--r--general/echo/umdfSocketEcho/ReadMe.md184
-rw-r--r--general/echo/umdfSocketEcho/umdfsocketecho.sln46
24 files changed, 3438 insertions, 0 deletions
diff --git a/general/echo/umdfSocketEcho/Driver/Connection.cpp b/general/echo/umdfSocketEcho/Driver/Connection.cpp
new file mode 100644
index 00000000..e28d0c56
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/Connection.cpp
@@ -0,0 +1,263 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ Connection.cpp
+
+Abstract:
+
+ Module for the socket connection specfic routines in the driver.
+ Makes Connection to the server given server host and port address.
+
+Environment:
+
+ User mode only
+
+
+--*/
+
+#include "internal.h"
+#include "connection.tmh"
+
+
+CConnection::CConnection()
+/*++
+
+Routine Description:
+
+ Constructor for connection object
+
+Arguments:
+
+ None
+
+Return Value:
+
+ VOID
+
+--*/
+{
+
+ // Initialize the socket member as Invalid
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+ m_socket = INVALID_SOCKET;
+}
+
+HRESULT
+CConnection::Connect(
+ IN IWDFDevice *pDevice
+ )
+/*++
+
+Routine Description:
+
+ This routine is for the initialization of the connection object associated with
+ the File Object . It is invoked from the dispatch OnCreateFile on the default
+ queue callback of the driver. It socket connection to the client.
+
+Arguments:
+
+ pDevice = Wdf Device Object
+
+Return Value:
+
+ S_OK if success , error HRESULT otherwise
+
+--*/
+{
+
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+
+ HRESULT hr = S_OK;
+
+ addrinfoW* info = NULL ;
+
+ PWSTR hostStr = NULL;
+
+ PWSTR portStr = NULL;
+
+ //
+ // Reads the host and port strings stored in the device context.
+ //
+
+ DeviceContext *pContext = NULL;
+
+ hr = pDevice->RetrieveContext((void**)&pContext);
+
+ if ( FAILED(hr) )
+ {
+
+ Trace(
+ TRACE_LEVEL_ERROR,
+ L"ERROR: unable to retrieve context from wdf device object %!hresult!",
+ hr
+ );
+ goto Clean0;
+
+ }
+
+ hostStr = pContext->hostStr;
+
+ portStr = pContext->portStr;
+
+ //
+ // lookup hostname with addrinfo hints;
+ //
+
+ addrinfoW hints;
+
+ ZeroMemory(&hints,sizeof(hints));
+
+ hints.ai_family = AF_INET;
+
+ hints.ai_socktype = SOCK_STREAM;
+
+ hints.ai_protocol = IPPROTO_TCP;
+
+ int n = GetAddrInfoW(hostStr, portStr, &hints, &info);
+
+ if (n != 0)
+ {
+ DWORD err = WSAGetLastError();
+ Trace(
+ TRACE_LEVEL_ERROR,
+ L"ERROR: Unable to find address/port of host %!winerr!",
+ err
+ );
+ hr = HRESULT_FROM_WIN32(err);
+ goto Clean0;
+ }
+
+ //
+ // Create a socket with this infomation recvd in getaddrinfo
+ //
+ m_socket = socket(info->ai_family,info->ai_socktype,info->ai_protocol);
+
+ if (m_socket == INVALID_SOCKET)
+ {
+ DWORD err = WSAGetLastError();
+
+ Trace(
+ TRACE_LEVEL_ERROR,
+ L"ERROR: Unable to create socket %!winerr!",
+ err
+ );
+
+ hr = HRESULT_FROM_WIN32(err);
+
+ goto Clean0;
+ }
+
+ //
+ // If that succeeds , proceed to connect to the socket
+ //
+
+
+ ATLASSERT(info->ai_addrlen <= 0x7fffffff);
+
+ int nret = connect(m_socket,info->ai_addr,(int)info->ai_addrlen);
+
+ if (nret == SOCKET_ERROR)
+ {
+ DWORD err = WSAGetLastError();
+ Trace(
+ TRACE_LEVEL_ERROR,
+ L"ERROR: Unable to connect to host %!winerr!",
+ err
+ );
+ hr = HRESULT_FROM_WIN32(err);
+
+ goto Clean0;
+ }
+
+
+Clean0:
+
+ if (info != NULL)
+ {
+ FreeAddrInfoW(info);
+
+ }
+
+ if (FAILED(hr) && m_socket != INVALID_SOCKET)
+ {
+ closesocket(m_socket);
+ m_socket = INVALID_SOCKET;
+ }
+
+ return hr;
+
+}
+
+HANDLE
+CConnection::GetSocketHandle(
+ )
+/*++
+
+Routine Description:
+
+ Function returns the socket handle associated with this connection object
+
+Arguments:
+
+ None
+
+Return Value:
+
+ Socket handle if valid socket
+ INVALID_HANDLE_VALUE otherwise
+
+--*/
+{
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+ if ( INVALID_SOCKET != m_socket )
+ {
+ return (HANDLE)m_socket ;
+ }
+ else
+ {
+ return INVALID_HANDLE_VALUE;
+ }
+
+}
+
+
+VOID
+CConnection::Close()
+/*++
+
+Routine Description:
+
+ Closes the socket connection to the server associated with this connection object
+
+Arguments:
+
+ None
+
+Return Value:
+
+ None
+--*/
+{
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+ if (m_socket != INVALID_SOCKET)
+ {
+ closesocket(m_socket);
+ m_socket = INVALID_SOCKET;
+ }
+
+}
diff --git a/general/echo/umdfSocketEcho/Driver/FileContext.h b/general/echo/umdfSocketEcho/Driver/FileContext.h
new file mode 100644
index 00000000..dbdda2e4
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/FileContext.h
@@ -0,0 +1,30 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved
+
+Module Name:
+
+ filecontext.h
+
+Abstract:
+
+ This header file defines the structure type for file context associated with the file object
+
+Environment:
+
+ user mode only
+
+Revision History:
+
+--*/
+
+
+#pragma once
+
+typedef struct _FileContext
+{
+ CConnection *pConnection ;
+
+ CComPtr<IWDFIoTarget> pFileTarget;
+
+}FileContext;
diff --git a/general/echo/umdfSocketEcho/Driver/Queue.cpp b/general/echo/umdfSocketEcho/Driver/Queue.cpp
new file mode 100644
index 00000000..242925d4
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/Queue.cpp
@@ -0,0 +1,580 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ queue.cpp
+
+Abstract:
+
+ This file implements the I/O queue interface and performs
+ the read/write/ioctl operations.
+
+Environment:
+
+ user mode only
+
+Revision History:
+
+--*/
+
+#include "internal.h"
+
+#include "queue.tmh"
+
+CMyQueue::CMyQueue(
+ ) :
+ m_FxQueue(NULL),
+ m_Device(NULL)
+{
+}
+
+//
+// Queue destructor.
+//
+
+CMyQueue::~CMyQueue(
+ VOID
+ )
+{
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+}
+
+//
+// Initialize
+//
+
+HRESULT
+CMyQueue::Initialize(
+ _In_ CMyDevice * Device
+ )
+/*++
+
+Routine Description:
+
+ Queue Initialize helper routine.
+ This routine will Create a default parallel queue associated with the Fx device object
+ and pass the IUnknown for this queue
+
+Aruments:
+ Device - Device object pointer
+
+Return Value:
+
+ S_OK if Initialize succeeds
+
+--*/
+{
+
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+
+ CComPtr<IWDFIoQueue> fxQueue;
+
+ HRESULT hr;
+
+ m_Device = Device;
+
+ //
+ // Create the I/O Queue object.
+ //
+
+ {
+ CComPtr<IUnknown> pUnk;
+
+ HRESULT hrQI = this->QueryInterface(__uuidof(IUnknown),(void**)&pUnk);
+
+ WUDF_SAMPLE_DRIVER_ASSERT(SUCCEEDED(hrQI));
+
+ hr = m_Device->GetFxDevice()->CreateIoQueue(
+ pUnk,
+ TRUE,
+ WdfIoQueueDispatchParallel,
+ TRUE,
+ FALSE,
+ &fxQueue
+ );
+ }
+
+ if (FAILED(hr))
+ {
+ Trace(
+ TRACE_LEVEL_ERROR,
+ "Failed to initialize driver queue %!hresult!",
+ hr
+ );
+ goto Exit;
+ }
+
+ m_FxQueue = fxQueue;
+
+
+Exit:
+
+ return hr;
+}
+
+HRESULT
+CMyQueue::Configure(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Queue configuration function .
+ It is called after queue object has been succesfully initialized.
+
+Aruments:
+
+ NONE
+
+ Return Value:
+
+ S_OK if succeeds.
+
+--*/
+{
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+
+ HRESULT hr = S_OK;
+
+ return hr;
+}
+
+
+STDMETHODIMP_(void)
+CMyQueue::OnCreateFile(
+ _In_ IWDFIoQueue* pWdfQueue,
+ _In_ IWDFIoRequest* pWdfRequest,
+ _In_ IWDFFile* pWdfFileObject
+ )
+
+/*++
+
+Routine Description:
+
+ Create callback from the framework for this default parallel queue
+
+ The create request will create a socket connection , create a file i/o target associated
+ with the socket handle for this connection and store in the file object context.
+
+Aruments:
+
+ pWdfQueue - Framework Queue instance
+ pWdfRequest - Framework Request instance
+ pWdfFileObject - WDF file object for this create
+
+ Return Value:
+
+ VOID
+
+--*/
+{
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+
+ HRESULT hr = S_OK;
+
+ CComPtr<IWDFFileHandleTargetFactory> spFileHandleTargetFactory;
+
+ CComPtr<IWDFIoTarget> pFileTarget;
+
+ CComPtr<IWDFDevice> pDevice;
+
+ HANDLE SocketHandle = NULL;
+
+ pWdfQueue->GetDevice(&pDevice);
+
+ FileContext *pContext = NULL;
+
+ //
+ // Create new connection object
+ //
+
+ CConnection *pConnection = new CConnection();
+
+ if (NULL == pConnection )
+ {
+ hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
+ Trace(
+ TRACE_LEVEL_ERROR,
+ L"ERROR: Could not create connection object %!hresult!",
+ hr
+ );
+ goto Exit;
+ }
+
+ //
+ // Connect to the socket server
+ //
+
+ hr = pConnection->Connect(pDevice);
+
+ if (FAILED(hr))
+ {
+ Trace(
+ TRACE_LEVEL_ERROR,
+ L"ERROR: Could not connect %!hresult!",
+ hr
+ );
+
+ goto Exit;
+
+ }
+
+ //
+ // If that succeeds, get socket handle for the connection
+ //
+
+ if ( NULL == (SocketHandle = pConnection->GetSocketHandle()) )
+ {
+ hr = E_FAIL;
+ Trace(
+ TRACE_LEVEL_ERROR,
+ L"ERROR: Unable to obtain valid Socket Handle %!hresult!",
+ hr
+ );
+ goto Exit;
+ }
+
+ //
+ // Create file context for this file object
+ //
+
+ pContext = new FileContext;
+
+ if (NULL == pContext)
+ {
+ hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
+ Trace(
+ TRACE_LEVEL_ERROR,
+ L"ERROR: Could not create file context %!hresult!",
+ hr
+ );
+ goto Exit;
+
+ }
+
+ //
+ // QI for IWDFFileHandleTargetFactory from the framework device object.
+ // Note UmdfDispatcher in Wdf Section in the Inf
+ //
+
+ hr = pDevice->QueryInterface(IID_PPV_ARGS(&spFileHandleTargetFactory));
+
+ if (FAILED(hr))
+ {
+ Trace(
+ TRACE_LEVEL_ERROR,
+ L"ERROR: Unable to obtain target factory for creating FileHandle based I/O target %!hresult!",
+ hr
+ );
+ goto Exit;
+ }
+
+ //
+ // If that succeeds, Create a File Handle I/O Target and associate the socket handle with this target
+ //
+
+ hr = spFileHandleTargetFactory->CreateFileHandleTarget(SocketHandle ,&pFileTarget);
+
+ if (FAILED(hr))
+ {
+ Trace(
+ TRACE_LEVEL_ERROR,
+ L"ERROR: Unable to create framework I/O target %!hresult!",
+ hr
+ );
+ goto Exit;
+ }
+
+
+ pContext->pFileTarget = pFileTarget;
+
+ pContext->pConnection = pConnection;
+
+ hr = pWdfFileObject->AssignContext(NULL,(void*)pContext);
+
+ if (FAILED(hr))
+ {
+ Trace(
+ TRACE_LEVEL_ERROR,
+ L"ERROR: Unable to Assign Context to this File Object %!hresult!",
+ hr
+ );
+ goto Exit;
+ }
+
+
+
+Exit:
+
+ if (FAILED(hr))
+ {
+
+ if ( pFileTarget )
+ {
+ pFileTarget->DeleteWdfObject();
+ }
+
+ if (pConnection != NULL)
+ {
+ delete pConnection;
+ pConnection = NULL;
+ }
+
+ if (pContext != NULL)
+ {
+ delete pContext;
+ pContext = NULL;
+ }
+
+ }
+
+ pWdfRequest->Complete(hr);
+
+}
+
+
+STDMETHODIMP_ (void)
+CMyQueue::OnWrite(
+ _In_ IWDFIoQueue *pWdfQueue,
+ _In_ IWDFIoRequest *pWdfRequest,
+ _In_ SIZE_T BytesToWrite
+ )
+/*++
+
+Routine Description:
+
+ Write callback from the framework for this default parallel queue
+
+ The write request needs to be sent to the file handle i/o target associated with this fileobject
+
+Aruments:
+
+ pWdfQueue - Framework Queue instance
+ pWdfRequest - Framework Request instance
+ BytesToWrite - Lenth of bytes in the write buffer
+
+ Return Value:
+
+ VOID
+
+--*/
+{
+ UNREFERENCED_PARAMETER(pWdfQueue);
+ UNREFERENCED_PARAMETER(BytesToWrite);
+
+ // Call helper function to send request to i/o target
+
+ SendRequestToFileTarget(pWdfRequest);
+
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+
+ return;
+}
+
+STDMETHODIMP_ (void)
+CMyQueue::OnRead(
+ _In_ IWDFIoQueue *pWdfQueue,
+ _In_ IWDFIoRequest *pWdfRequest,
+ _In_ SIZE_T BytesToRead
+ )
+/*++
+
+Routine Description:
+
+ Read callback from the framework for this default parallel queue
+
+ The read request needs to be sent to the file handle i/o target associated with this fileobject
+
+Aruments:
+
+ pWdfQueue - Framework Queue instance
+ pWdfRequest - Framework Request instance
+ BytesToRead - Lenth of bytes in the read buffer
+
+
+Return Value:
+
+ VOID
+
+--*/
+{
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+
+ UNREFERENCED_PARAMETER(pWdfQueue);
+ UNREFERENCED_PARAMETER(BytesToRead);
+
+ //
+ // Call helper function to send request to i/o target
+ //
+
+ SendRequestToFileTarget(pWdfRequest);
+
+ return;
+}
+
+STDMETHODIMP_(void)
+CMyQueue::OnCompletion(
+ _In_ IWDFIoRequest* pWdfRequest,
+ _In_ IWDFIoTarget* pTarget,
+ _In_ IWDFRequestCompletionParams* pCompletionParams,
+ _In_ void* pContext
+)
+/*++
+
+Routine Description:
+
+ This routine is invoked when the request is completed by the lower stack location,
+ in this case the win32 i/o target associated with the file object of this request
+
+
+ Arguments:
+
+ pWdfRequest - wdf request
+ pTarget - wdf target to which request was earlier sent
+ pCompletionParams - wdf request completion parameters
+ pContext - Context information , if any
+
+
+Return Value:
+
+ None
+--*/
+{
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+
+ UNREFERENCED_PARAMETER(pTarget);
+ UNREFERENCED_PARAMETER(pContext);
+
+ // Complete request from the driver
+ pWdfRequest->CompleteWithInformation(
+ pCompletionParams->GetCompletionStatus(),
+ pCompletionParams->GetInformation());
+}
+
+VOID
+CMyQueue::SendRequestToFileTarget(
+ _In_ IWDFIoRequest* pWdfRequest
+)
+/*++
+
+Routine Description:
+
+ This is a helper functiom to send R/W requests to the win32 file i/o target
+ associated with the socket connection for this request.
+ First, filecontext is retrieved which has the file i/o target where this request needs to be sent.
+
+
+Arguments:
+
+ pWdfRequest - wdf request
+
+Return Value:
+
+ None
+
+--*/
+{
+
+ HRESULT hr;
+
+ FileContext *pContext = NULL;
+ CComPtr<IWDFFile> pWdfFile = NULL;
+
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+
+ //
+ // Get the file object for this request
+ //
+
+ pWdfRequest->GetFileObject(&pWdfFile);
+
+ //
+ // Retrieve Context from file object
+ //
+
+ hr = pWdfFile->RetrieveContext((void**)&pContext);
+
+ if (pContext == NULL)
+ {
+ if ( SUCCEEDED(hr) )
+ {
+ hr = E_FAIL;
+ Trace(TRACE_LEVEL_ERROR,
+ " No Context associated with this file object %!hresult!",
+ hr);
+ }
+ goto Exit;
+ }
+
+ //
+ // If that succeeds, set completion callback for the request
+ //
+ pWdfRequest->SetCompletionCallback(CComQIPtr<IRequestCallbackRequestCompletion>(this),
+ NULL);
+
+ //
+ // Do not modify the request, format using current type
+ //
+
+ pWdfRequest->FormatUsingCurrentType();
+
+ //
+ // Send the request to the win32 i/o target . This was created in OnCreateFile
+ //
+
+ hr = pWdfRequest->Send(pContext->pFileTarget,
+ 0,
+ 0);
+Exit:
+
+ if (FAILED(hr))
+ {
+ Trace(TRACE_LEVEL_ERROR,
+ "Could not send request to i/o target %!hresult!",
+ hr);
+ pWdfRequest->Complete(hr);
+ }
+
+ return ;
+}
+
+STDMETHODIMP_(void)
+CMyQueue::OnCleanup(
+ _In_ IWDFObject* /*pWdfObject*/
+ )
+{
+ //
+ // CMyQueue has a reference to framework device object via m_FxQueue.
+ // Framework queue object has a reference to CMyQueue object via the callbacks.
+ // This leads to circular reference and both the objects can't be destroyed until this circular reference is broken.
+ // To break the circular reference we release the reference to the framework queue object here in OnCleanup.
+ //
+ m_FxQueue = NULL;
+}
diff --git a/general/echo/umdfSocketEcho/Driver/Queue.h b/general/echo/umdfSocketEcho/Driver/Queue.h
new file mode 100644
index 00000000..952e1e0d
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/Queue.h
@@ -0,0 +1,83 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ queue.h
+
+Abstract:
+
+ This file defines the queue callback interface.
+
+Environment:
+
+ user mode only
+
+Revision History:
+
+--*/
+
+#pragma once
+
+//
+// Queue Callback Object.
+//
+
+class ATL_NO_VTABLE CMyQueue :
+ public CComObjectRootEx<CComMultiThreadModel>,
+ public IQueueCallbackCreate,
+ public IQueueCallbackRead,
+ public IQueueCallbackWrite,
+ public IRequestCallbackRequestCompletion,
+ public IObjectCleanup
+{
+public:
+
+DECLARE_NOT_AGGREGATABLE(CMyQueue)
+
+BEGIN_COM_MAP(CMyQueue)
+ COM_INTERFACE_ENTRY(IQueueCallbackCreate)
+ COM_INTERFACE_ENTRY(IQueueCallbackRead)
+ COM_INTERFACE_ENTRY(IQueueCallbackWrite)
+ COM_INTERFACE_ENTRY(IRequestCallbackRequestCompletion)
+ COM_INTERFACE_ENTRY(IObjectCleanup)
+END_COM_MAP()
+
+public:
+ //IQueueCallbackRead
+ STDMETHOD_(void,OnRead)(_In_ IWDFIoQueue* pWdfQueue,_In_ IWDFIoRequest* pWdfRequest,_In_ SIZE_T NumOfBytesToRead);
+
+ //IQueueCallbackWrite
+ STDMETHOD_(void,OnWrite)(_In_ IWDFIoQueue* pWdfQueue,_In_ IWDFIoRequest* pWdfRequest,_In_ SIZE_T NumOfBytesToWrite);
+
+ //IQueueCallbackCreate
+ STDMETHOD_(void,OnCreateFile)(_In_ IWDFIoQueue* pWdfQueue,_In_ IWDFIoRequest* pWDFRequest,_In_ IWDFFile* pWdfFileObject);
+
+ // IRequestCallbackRequestCompletion
+ STDMETHOD_(void,OnCompletion)(_In_ IWDFIoRequest* pWdfRequest,_In_ IWDFIoTarget* pTarget,_In_ IWDFRequestCompletionParams* pCompletionParams,_In_ void* pContext);
+
+ //IObjectCleanup
+ STDMETHOD_(void,OnCleanup)(_In_ IWDFObject* pWdfObject);
+
+public:
+ CMyQueue();
+ ~CMyQueue();
+
+ STDMETHOD(Initialize)(_In_ CMyDevice * Device);
+
+ HRESULT
+ Configure(
+ );
+
+private:
+ CComPtr<IWDFIoQueue> m_FxQueue;
+
+ //
+ // Unreferenced pointer to the parent device.
+ //
+
+ CMyDevice * m_Device;
+
+ VOID SendRequestToFileTarget( _In_ IWDFIoRequest* pWdfRequest);
+};
diff --git a/general/echo/umdfSocketEcho/Driver/SocketEcho.inx b/general/echo/umdfSocketEcho/Driver/SocketEcho.inx
new file mode 100644
index 00000000..d9ed27ea
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/SocketEcho.inx
@@ -0,0 +1,89 @@
+;
+; SocketEcho.inf
+;
+
+[Version]
+Signature="$WINDOWS NT$"
+Class=Sample
+ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171}
+Provider=%MSFT%
+CatalogFile=wudf.cat
+DriverVer=03/20/2003,5.00.3788
+
+[Manufacturer]
+%MSFTWUDF%=Microsoft,NT$ARCH$
+
+[Microsoft.NT$ARCH$]
+%SocketEchoName%=SocketEcho_Install,WUDF\SocketEcho
+
+[ClassInstall32]
+AddReg=SampleClass_RegistryAdd
+
+[SampleClass_RegistryAdd]
+HKR,,,,%ClassName%
+HKR,,Icon,,"-10"
+
+[SourceDisksFiles]
+WudfUpdate_$UMDFCOINSTALLERVERSION$.dll=1
+SocketEcho.dll=1
+
+[SourceDisksNames]
+1 = %MediaDescription%
+
+; =================== WUDF SocketEcho Test Driver ==================================
+
+[SocketEcho_Install]
+CopyFiles=UMDFDriverCopy
+
+[SocketEcho_Install.hw]
+AddReg=SocketEcho_AddReg
+
+[SocketEcho_Install.Services]
+AddService=WUDFRd,0x000001fa,WUDFRD_ServiceInstall
+
+[SocketEcho_Install.CoInstallers]
+AddReg = SocketEcho_Install.CoInstallers_AddReg
+CopyFiles = CoInstallers_CopyFiles
+
+[SocketEcho_Install.CoInstallers_AddReg]
+HKR,,CoInstallers32,0x00010000,"WudfUpdate_$UMDFCOINSTALLERVERSION$.dll"
+
+
+
+[CoInstallers_CopyFiles]
+WudfUpdate_$UMDFCOINSTALLERVERSION$.dll
+
+[SocketEcho_Install.Wdf]
+UmdfService=SocketEcho, SocketEcho_Driver_Install
+UmdfServiceOrder=SocketEcho
+UmdfDispatcher=FileHandle
+
+[SocketEcho_AddReg]
+HKR,"SocketEcho","Host",0x00000000,"localhost"
+HKR,"SocketEcho","Port",0x00000000,"6000"
+
+[WUDFRD_ServiceInstall]
+ServiceType=1
+StartType=3
+ErrorControl=1
+ServiceBinary=%12%\WUDFRd.sys
+
+[SocketEcho_Driver_Install]
+UmdfLibraryVersion=$UMDFVERSION$
+DriverCLSID="{83B87D35-76B8-4920-B43C-3BDE6B0EC5B8}"
+ServiceBinary="%12%\UMDF\SocketEcho.dll"
+
+[DestinationDirs]
+UMDFDriverCopy=12,UMDF
+
+[UMDFDriverCopy]
+SocketEcho.dll,,,0x00004000 ; COPYFLG_IN_USE_RENAME
+
+; =================== Generic ==================================
+
+[Strings]
+MSFT="Microsoft"
+MSFTWUDF="Microsoft Internal (WUDF)"
+MediaDescription="Microsoft WUDF Sample Driver Installation Media"
+ClassName="Sample Device"
+SocketEchoName="Sample WUDF SocketEcho Driver"
diff --git a/general/echo/umdfSocketEcho/Driver/SocketEcho.rc b/general/echo/umdfSocketEcho/Driver/SocketEcho.rc
new file mode 100644
index 00000000..cc27b15f
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/SocketEcho.rc
@@ -0,0 +1,21 @@
+//---------------------------------------------------------------------------
+// Skeleton.rc
+//
+// Copyright (c) Microsoft Corporation, All Rights Reserved
+//---------------------------------------------------------------------------
+
+
+#include <windows.h>
+#include <ntverp.h>
+
+//
+// TODO: Change the file description and file names to match your binary.
+//
+
+#define VER_FILETYPE VFT_DLL
+#define VER_FILESUBTYPE VFT_UNKNOWN
+#define VER_FILEDESCRIPTION_STR "WDF:UMDF Sample WUDF SocketEcho Driver"
+#define VER_INTERNALNAME_STR "SocketEcho"
+#define VER_ORIGINALFILENAME_STR "SocketEcho.dll"
+
+#include "common.ver"
diff --git a/general/echo/umdfSocketEcho/Driver/SocketEcho.vcxproj b/general/echo/umdfSocketEcho/Driver/SocketEcho.vcxproj
new file mode 100644
index 00000000..d9930170
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/SocketEcho.vcxproj
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{ABEFFAA1-36CF-4F78-9A6B-10EAEC11B3E3}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR>
+ <KMDF_VERSION_MAJOR>1</KMDF_VERSION_MAJOR>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{DA04694B-6179-416F-83FF-53A671E51B26}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems">
+ <ClCompile Include="dllsup.cpp; driver.cpp; device.cpp; queue.cpp; connection.cpp">
+ <WppEnabled>true</WppEnabled>
+ <WppDllMacro>true</WppDllMacro>
+ <WppScanConfigurationData>internal.h</WppScanConfigurationData>
+ </ClCompile>
+ <Inf Include="SocketEcho.inx">
+ <Architecture>$(InfArch)</Architecture>
+ <SpecifyArchitecture>true</SpecifyArchitecture>
+ <CopyOutput>.\$(IntDir)\SocketEcho.inf</CopyOutput>
+ </Inf>
+ <OtherWpp Include="SocketEcho.rc">
+ <WppEnabled>true</WppEnabled>
+ <WppDllMacro>true</WppDllMacro>
+ <WppScanConfigurationData>internal.h</WppScanConfigurationData>
+ </OtherWpp>
+ </ItemGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>SocketEcho</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>SocketEcho</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>SocketEcho</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>SocketEcho</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
+ <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
+ <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
+ <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);_UNICODE;UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
+ <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ </Link>
+ </ItemDefinitionGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <UseOfAtl>Dynamic</UseOfAtl>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <UseOfAtl>Dynamic</UseOfAtl>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <UseOfAtl>Dynamic</UseOfAtl>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <UseOfAtl>Dynamic</UseOfAtl>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\user32.lib;$(SDK_LIB_PATH)\ole32.lib;$(SDK_LIB_PATH)\oleaut32.lib;$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\shlwapi.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\Ws2_32.lib</AdditionalDependencies>
+ <ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\user32.lib;$(SDK_LIB_PATH)\ole32.lib;$(SDK_LIB_PATH)\oleaut32.lib;$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\shlwapi.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\Ws2_32.lib</AdditionalDependencies>
+ <ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\user32.lib;$(SDK_LIB_PATH)\ole32.lib;$(SDK_LIB_PATH)\oleaut32.lib;$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\shlwapi.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\Ws2_32.lib</AdditionalDependencies>
+ <ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\user32.lib;$(SDK_LIB_PATH)\ole32.lib;$(SDK_LIB_PATH)\oleaut32.lib;$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\shlwapi.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\Ws2_32.lib</AdditionalDependencies>
+ <ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ResourceCompile Include="SocketEcho.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/general/echo/umdfSocketEcho/Driver/SocketEcho.vcxproj.Filters b/general/echo/umdfSocketEcho/Driver/SocketEcho.vcxproj.Filters
new file mode 100644
index 00000000..539cbe3b
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/SocketEcho.vcxproj.Filters
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{BEDB1CCE-4E58-4AE0-B5B6-C54C6159232D}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{07B8152F-B3FA-4EA1-BBCD-EABDD1B7FCAB}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{61C11142-602D-496E-B9EB-516ED5D7685B}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Driver Files">
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ <UniqueIdentifier>{2BB65E51-CB92-4484-AD29-5ED2A6007684}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="connection.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="device.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="dllsup.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="driver.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="queue.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <None Include="exports.def">
+ <Filter>Source Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <FilesToPackage Include=".\Debug\\SocketEcho.inf">
+ <Filter>Driver Files</Filter>
+ </FilesToPackage>
+ <Inf Include="SocketEcho.inx">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="SocketEcho.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/echo/umdfSocketEcho/Driver/connection.h b/general/echo/umdfSocketEcho/Driver/connection.h
new file mode 100644
index 00000000..2b7e23c6
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/connection.h
@@ -0,0 +1,32 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ Connection.h
+
+Abstract:
+
+ Header file for the socketecho connection class
+
+Environment:
+
+ User mode only
+
+
+--*/
+#pragma once
+
+class CConnection
+{
+public:
+ CConnection();
+ HRESULT Connect(IN IWDFDevice *pDevice);
+ VOID Close();
+ HANDLE GetSocketHandle( );
+
+private:
+ SOCKET m_socket;
+};
+
diff --git a/general/echo/umdfSocketEcho/Driver/device.cpp b/general/echo/umdfSocketEcho/Driver/device.cpp
new file mode 100644
index 00000000..9c3e4db1
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/device.cpp
@@ -0,0 +1,469 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved.
+
+Module Name:
+
+ Device.cpp
+
+Abstract:
+
+ This module contains the implementation of the UMDF socketecho sample
+ driver's device callback object.
+
+ It does not implement either of the PNP interfaces so once the device
+ is setup, it won't ever get any callbacks until the device is removed.
+
+Environment:
+
+ Windows User-Mode Driver Framework (WUDF)
+
+--*/
+
+#include "internal.h"
+#include "device.tmh"
+
+const GUID GUID_DEVINTERFACE_SOCKETECHO =
+ {0xcdc35b6e, 0xbe4, 0x4936, { 0xbf, 0x5f, 0x55, 0x37, 0x38, 0xa, 0x7c, 0x1a }};
+
+
+HRESULT
+CMyDevice::Initialize(
+ _In_ IWDFDriver* FxDriver,
+ _In_ IWDFDeviceInitialize* FxDeviceInit
+ )
+/*++
+
+ Routine Description:
+
+ This method initializes the device callback object and creates the
+ partner device object.
+
+ The method should perform any device-specific configuration that:
+ * could fail (these can't be done in the constructor)
+ * must be done before the partner object is created -or-
+ * can be done after the partner object is created and which aren't
+ influenced by any device-level parameters the parent (the driver
+ in this case) might set.
+
+ Arguments:
+
+ FxDeviceInit - the settings for this device.
+ FxDriver - IWDF Driver for this device.
+
+ Return Value:
+
+ status.
+
+--*/
+{
+ Trace(TRACE_LEVEL_INFORMATION, "%!FUNC!");
+
+ CComPtr<IWDFDevice> fxDevice;
+ HRESULT hr;
+ BOOL bFilter = FALSE;
+
+ //
+ // Configure things like the locking model before we go to create our
+ // partner device.
+ //
+
+ //
+ // Set the locking model
+ //
+
+ FxDeviceInit->SetLockingConstraint(None);
+
+ //
+ // Mark filter if we are a filter
+ //
+
+ if (bFilter)
+ {
+ FxDeviceInit->SetFilter();
+ }
+
+ //
+ // TODO: Any per-device initialization which must be done before
+ // creating the partner object.
+ //
+
+ //
+ // Create a new FX device object and assign the new callback object to
+ // handle any device level events that occur.
+ //
+
+ //
+ // QueryIUnknown references the IUnknown interface that it returns
+ // (which is the same as referencing the device). We pass that to
+ // CreateDevice, which takes its own reference if everything works.
+ //
+
+ CComPtr<IUnknown> pUnk;
+ HRESULT hrQI = this->QueryInterface(__uuidof(IUnknown),(void**)&pUnk);
+ WUDF_SAMPLE_DRIVER_ASSERT(SUCCEEDED(hrQI));
+
+ hr = FxDriver->CreateDevice(FxDeviceInit, pUnk, &fxDevice);
+
+ //
+ // If that succeeded then set our FxDevice member variable.
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ m_FxDevice = fxDevice;
+ }
+
+ return hr;
+}
+
+HRESULT
+CMyDevice::Configure(
+ VOID
+ )
+/*++
+
+ Routine Description:
+
+ This method is called after the device callback object has been initialized
+ and returned to the driver. It would setup the device's queues and their
+ corresponding callback objects.
+
+ Arguments:
+
+ None
+
+ Return Value:
+
+ status
+
+--*/
+{
+ Trace(TRACE_LEVEL_INFORMATION, "%!FUNC!");
+
+ HRESULT hr;
+ CComObject<CMyQueue> * defaultQueue = NULL;
+
+ //
+ // Create a new instance of our queue callback object
+ //
+ hr = CComObject<CMyQueue>::CreateInstance(&defaultQueue);
+
+ if (SUCCEEDED(hr))
+ {
+ defaultQueue->AddRef();
+ hr = defaultQueue->Initialize(this);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = defaultQueue->Configure();
+ }
+
+ //
+ // Create and Enable Device Interface for this device.
+ //
+ if (SUCCEEDED(hr))
+ {
+ hr = m_FxDevice->CreateDeviceInterface(&GUID_DEVINTERFACE_SOCKETECHO,
+ NULL);
+ }
+ if (SUCCEEDED(hr))
+ {
+ hr = m_FxDevice->AssignDeviceInterfaceState(&GUID_DEVINTERFACE_SOCKETECHO,
+ NULL,
+ TRUE);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = ReadAndAssignPropertyStoreValue();
+ }
+
+ //
+ // Release the reference we took on the queue callback object.
+ // The framework took its own references on the object's callback interfaces
+ // when we called m_FxDevice->CreateIoQueue, and will manage the object's lifetime.
+ //
+ SAFE_RELEASE(defaultQueue);
+
+ return hr;
+}
+
+STDMETHODIMP_(void)
+CMyDevice::OnCloseFile(
+ _In_ IWDFFile* pWdfFileObject
+ )
+/*++
+
+ Routine Description:
+
+ This method is called when an app closes the file handle to this device.
+ This will free the context memory associated with this file object, close
+ the connection object associated with this file object and delete the file
+ handle i/o target object associated with this file object.
+
+ Arguments:
+
+ pWdfFileObject - the framework file object for which close is handled.
+
+ Return Value:
+
+ None
+
+--*/
+{
+ Trace(TRACE_LEVEL_INFORMATION, "%!FUNC!");
+
+ HRESULT hr = S_OK ;
+ FileContext *pContext = NULL;
+
+ hr = pWdfFileObject->RetrieveContext((void**)&pContext);
+
+ if (SUCCEEDED(hr) && (pContext != NULL ) )
+ {
+ pContext->pConnection->Close();
+ pContext->pFileTarget->DeleteWdfObject();
+
+ delete pContext->pConnection;
+ delete pContext;
+ }
+
+ return ;
+}
+
+
+STDMETHODIMP_(void)
+CMyDevice::OnCleanupFile(
+ _In_ IWDFFile* pWdfFileObject
+ )
+/*++
+
+ Routine Description:
+
+ This method is when app with open handle device terminates.
+
+ Arguments:
+
+ pWdfFileObject - the framework file object for which close is handled.
+
+ Return Value:
+
+ None
+
+--*/
+{
+ UNREFERENCED_PARAMETER(pWdfFileObject);
+}
+
+STDMETHODIMP_(void)
+CMyDevice::OnCleanup(
+ _In_ IWDFObject* pWdfObject
+ )
+/*++
+
+ Routine Description:
+
+ This device callback method is invoked by the framework when the WdfObject
+ is about to be released by the framework. This will free the context memory
+ associated with the device object.
+
+ Arguments:
+
+ pWdfObject - the framework device object for which OnCleanup.
+
+ Return Value:
+
+ None
+
+--*/
+{
+ Trace(TRACE_LEVEL_INFORMATION, "%!FUNC!");
+
+ HRESULT hr ;
+ DeviceContext *pContext = NULL;
+
+ WUDF_SAMPLE_DRIVER_ASSERT(pWdfObject == m_FxDevice);
+
+ hr = pWdfObject->RetrieveContext((void**)&pContext);
+
+ if (SUCCEEDED(hr) && (pContext != NULL))
+ {
+ // hostStr is allocated through StrDup, and thus need be freed through LocalFree
+ //
+ if (pContext->hostStr != NULL)
+ {
+ LocalFree( pContext->hostStr );
+ }
+
+ if (pContext->portStr != NULL)
+ {
+ LocalFree( pContext->portStr );
+ }
+
+ delete pContext;
+ }
+//
+//CMyDevice has a reference to framework device object via m_Device.
+//Framework device object has a reference to CMyDevice object via the callbacks.
+//This leads to circular reference and both the objects can't be destroyed until this circular reference is broken.
+//To break the circular reference we release the reference to the framework device object here in OnCleanup.
+
+ m_FxDevice = NULL;
+}
+
+HRESULT
+CMyDevice::ReadAndAssignPropertyStoreValue(
+ VOID
+ )
+/*++
+
+ Routine Description:
+ Helper function for reading property store values and storing them in the
+ device level context.
+
+ Arguments:
+
+ pWdfFileObject - the framework file object for which close is handled.
+
+ Return Value:
+
+ None
+
+--*/
+{
+ Trace(TRACE_LEVEL_INFORMATION, "%!FUNC!");
+
+ CComPtr<IWDFNamedPropertyStore> pPropStore;
+ WDF_PROPERTY_STORE_DISPOSITION disposition;
+ PROPVARIANT val;
+ HRESULT hr ;
+
+ PropVariantInit(&val);
+
+ DeviceContext *pContext = new DeviceContext;
+ if (pContext == NULL)
+ {
+ hr = E_OUTOFMEMORY;
+ Trace(TRACE_LEVEL_ERROR,
+ L"ERROR: Could not create device context object %!hresult!",
+ hr);
+
+ goto CleanUp;
+ }
+
+ pContext->hostStr = NULL;
+ pContext->portStr = NULL;
+
+ //
+ // Retreive property store for reading drivers custom settings as specified
+ // in the INF
+ //
+ hr = m_FxDevice->RetrieveDevicePropertyStore(L"SocketEcho",
+ WdfPropertyStoreNormal,
+ &pPropStore,
+ &disposition);
+ if (FAILED(hr))
+ {
+ Trace(TRACE_LEVEL_ERROR,
+ "Failed to retrieve device property store for reading custom "
+ "settings as specified in the INF %!hresult!",
+ hr);
+
+ goto CleanUp;
+ }
+
+ //
+ // Get the key for this device with Named value "host"
+ //
+ hr = pPropStore->GetNamedValue(L"Host", &val);
+ if (FAILED(hr))
+ {
+ Trace(TRACE_LEVEL_ERROR,
+ "Failed to get \"Host\" key value %!hresult!",
+ hr);
+
+ goto CleanUp;
+ }
+
+ if (val.vt != VT_LPWSTR)
+ {
+ hr = HRESULT_FROM_WIN32(ERROR_BAD_CONFIGURATION);
+ Trace(TRACE_LEVEL_ERROR,
+ "Unexpected string format for value in \"Host\" key %!hresult!",
+ hr);
+
+ goto CleanUp;
+ }
+
+ pContext->hostStr = StrDup(val.pwszVal);
+
+ //
+ // Clear property variant for reading next key
+ //
+ PropVariantClear(&val);
+
+ //
+ // Get the key for this device with Named value "Port"
+ //
+ hr = pPropStore->GetNamedValue(L"Port", &val);
+ if (FAILED(hr))
+ {
+ Trace(TRACE_LEVEL_ERROR,
+ "Failed to get \"Port\" key value %!hresult!",
+ hr);
+
+ goto CleanUp;
+ }
+
+ if (val.vt != VT_LPWSTR)
+ {
+ hr = HRESULT_FROM_WIN32(ERROR_BAD_CONFIGURATION);
+ Trace(TRACE_LEVEL_ERROR,
+ "Unexpected string format for value in \"Port\" key %!hresult!",
+ hr);
+
+ goto CleanUp;
+ }
+
+ pContext->portStr = StrDup(val.pwszVal);
+
+ hr = m_FxDevice->AssignContext(NULL, (void*)pContext);
+ if (FAILED(hr))
+ {
+ Trace(TRACE_LEVEL_ERROR,
+ "Failed to assign property store value to device %!hresult!",
+ hr);
+
+ //
+ // Fall through to clean up and exit ...
+ //
+ }
+
+CleanUp:
+
+ PropVariantClear(&val);
+
+ if (FAILED(hr))
+ {
+ if (pContext != NULL)
+ {
+ // hostStr is allocated through StrDup, and thus need be freed through LocalFree
+ //
+ if (pContext->hostStr != NULL)
+ {
+ LocalFree( pContext->hostStr );
+ }
+
+ if (pContext->portStr != NULL)
+ {
+ LocalFree( pContext->portStr );
+ }
+
+ delete pContext;
+ }
+ }
+
+ return hr;
+}
+
diff --git a/general/echo/umdfSocketEcho/Driver/device.h b/general/echo/umdfSocketEcho/Driver/device.h
new file mode 100644
index 00000000..176f10e6
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/device.h
@@ -0,0 +1,70 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved
+
+Module Name:
+
+ Device.h
+
+Abstract:
+
+ This module contains the type definitions for the UMDF Skeleton sample
+ driver's device callback class.
+
+Environment:
+
+ Windows User-Mode Driver Framework (WUDF)
+
+--*/
+
+#pragma once
+
+//
+// Class for the iotrace driver.
+//
+
+class ATL_NO_VTABLE CMyDevice :
+ public CComObjectRootEx<CComMultiThreadModel>,
+ public IFileCallbackCleanup,
+ public IFileCallbackClose,
+ public IObjectCleanup
+{
+public:
+
+DECLARE_NOT_AGGREGATABLE(CMyDevice)
+
+BEGIN_COM_MAP(CMyDevice)
+ COM_INTERFACE_ENTRY(IFileCallbackCleanup)
+ COM_INTERFACE_ENTRY(IFileCallbackClose)
+ COM_INTERFACE_ENTRY(IObjectCleanup)
+END_COM_MAP()
+
+public:
+
+ //IFileCallbackCleanup
+ STDMETHOD_(void,OnCleanupFile)(_In_ IWDFFile* pWdfFileObject);
+ //IFileCallbackClose
+ STDMETHOD_(void,OnCloseFile)(_In_ IWDFFile* pWdfFileObject);
+ //IObjectCleanup
+ STDMETHOD_(void,OnCleanup)(_In_ IWDFObject* pWdfObject);
+
+public:
+
+ STDMETHOD(Initialize)(_In_ IWDFDriver* pWdfDriver, _In_ IWDFDeviceInitialize* pWdfDeviceInit);
+
+ HRESULT
+ Configure(
+ );
+
+ IWDFDevice *
+ GetFxDevice(
+ )
+ {
+ return m_FxDevice;
+ }
+
+private:
+ CComPtr<IWDFDevice> m_FxDevice;
+ HRESULT ReadAndAssignPropertyStoreValue();
+
+};
diff --git a/general/echo/umdfSocketEcho/Driver/devicecontext.h b/general/echo/umdfSocketEcho/Driver/devicecontext.h
new file mode 100644
index 00000000..2bf10d2e
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/devicecontext.h
@@ -0,0 +1,32 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ devicecontext.h
+
+Abstract:
+
+ This header file defines the structure type for device context associated with the device object
+
+Environment:
+
+ user mode only
+
+Revision History:
+
+--*/
+
+
+#pragma once
+
+
+typedef struct _DeviceContext
+{
+ PWSTR hostStr;
+
+ PWSTR portStr;
+
+}DeviceContext;
+
diff --git a/general/echo/umdfSocketEcho/Driver/dllsup.cpp b/general/echo/umdfSocketEcho/Driver/dllsup.cpp
new file mode 100644
index 00000000..5ec3eb33
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/dllsup.cpp
@@ -0,0 +1,111 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved.
+
+Module Name:
+
+ dllsup.cpp
+
+Abstract:
+
+ This module contains the implementation of the UMDF Socktecho Sample
+ Driver's entry point and its exported functions for providing COM support.
+
+ This module can be copied without modification to a new UMDF driver. It
+ depends on some of the code in comsup.cpp & comsup.h to handle DLL
+ registration and creating the first class factory.
+
+ This module is dependent on the following defines:
+
+ MYDRIVER_TRACING_ID - A wide string passed to WPP when initializing
+ tracing. For example the socktecho uses
+ L"Microsoft\\UMDF\\Socketecho"
+
+ MYDRIVER_CLASS_ID - A GUID encoded in struct format used to
+ initialize the driver's ClassID.
+
+ These are defined in internal.h for the sample. If you choose
+ to use a different primary include file, you should ensure they are
+ defined there as well.
+
+Environment:
+
+ WDF User-Mode Driver Framework (WDF:UMDF)
+
+--*/
+
+#include "internal.h"
+#include "dllsup.tmh"
+
+const GUID CLSID_MyDriverCoClass = MYDRIVER_CLASS_ID;
+
+class CSocketEchoModule : public CAtlDllModuleT< CSocketEchoModule >
+{
+};
+
+
+OBJECT_ENTRY_AUTO(CLSID_MyDriverCoClass, CMyDriver)
+
+
+CSocketEchoModule _AtlModule;
+
+BOOL
+WINAPI
+DllMain(
+ HINSTANCE ModuleHandle,
+ DWORD Reason,
+ PVOID Reserved
+ )
+/*++
+
+ Routine Description:
+
+ This is the entry point and exit point for the I/O trace driver. This
+ does very little as the I/O trace driver has minimal global data.
+
+ This method initializes tracing.
+
+ Arguments:
+
+ ModuleHandle - the DLL handle for this module.
+
+ Reason - the reason this entry point was called.
+
+ Reserved - unused
+
+ Return Value:
+
+ TRUE
+
+--*/
+{
+
+ UNREFERENCED_PARAMETER( ModuleHandle );
+
+ if (DLL_PROCESS_ATTACH == Reason)
+ {
+ //
+ // Initialize tracing.
+ //
+
+ WPP_INIT_TRACING(MYDRIVER_TRACING_ID);
+
+ }
+ else if (DLL_PROCESS_DETACH == Reason)
+ {
+ //
+ // Cleanup tracing.
+ //
+
+ WPP_CLEANUP();
+ }
+
+ return _AtlModule.DllMain(Reason, Reserved);
+;
+}
+
+_Check_return_
+STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID* ppv)
+{
+ return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
+}
diff --git a/general/echo/umdfSocketEcho/Driver/driver.cpp b/general/echo/umdfSocketEcho/Driver/driver.cpp
new file mode 100644
index 00000000..4f93691c
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/driver.cpp
@@ -0,0 +1,174 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved.
+
+Module Name:
+
+ Driver.cpp
+
+Abstract:
+
+ This module contains the implementation of the UMDF Socketecho Sample's
+ core driver callback object.
+
+Environment:
+
+ Windows User-Mode Driver Framework (WUDF)
+
+--*/
+
+#include "internal.h"
+#include "driver.tmh"
+
+STDMETHODIMP
+CMyDriver::OnInitialize(
+ _In_ IWDFDriver* pWdfDriver
+ )
+
+
+/*++
+
+ Routine Description:
+
+ This routine is invoked by the framework at driver load .
+ This method will invoke the Winsock Library for using
+ Winsock API in this driver.
+
+ Arguments:
+
+ pWdfDriver - Framework driver object
+
+ Return Value:
+
+ S_OK if successful, or error otherwise.
+
+--*/
+
+{
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+ UNREFERENCED_PARAMETER(pWdfDriver);
+
+ WORD sockVersion;
+ WSADATA wsaData;
+
+ sockVersion = MAKEWORD(2, 0);
+
+ int result = WSAStartup(sockVersion, &wsaData);
+
+ if (result != 0)
+ {
+ DWORD err = WSAGetLastError();
+ Trace(
+ TRACE_LEVEL_ERROR,
+ L"ERROR: Failed to initialize Winsock 2.0 %!winerr!",
+ err
+ );
+ return HRESULT_FROM_WIN32(err);
+ }
+
+ return S_OK;
+}
+
+STDMETHODIMP_(void)
+CMyDriver::OnDeinitialize(
+ _In_ IWDFDriver* pWdfDriver
+ )
+
+/*++
+ Routine Description:
+
+ The FX invokes this method when it unloads the driver.
+ This routine will Cleanup Winsock library
+
+ Arguments:
+
+ pWdfDriver - the Fx driver object.
+
+ Return Value:
+
+ None
+
+
+ --*/
+
+{
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+
+ UNREFERENCED_PARAMETER(pWdfDriver);
+
+ WSACleanup();
+}
+
+STDMETHODIMP
+CMyDriver::OnDeviceAdd(
+ _In_ IWDFDriver *FxWdfDriver,
+ _In_ IWDFDeviceInitialize *FxDeviceInit
+ )
+/*++
+
+ Routine Description:
+
+ The FX invokes this method when it wants to install our driver on a device
+ stack. This method creates a device callback object, then calls the Fx
+ to create an Fx device object and associate the new callback object with
+ it.
+
+ Arguments:
+
+ FxWdfDriver - the Fx driver object.
+
+ FxDeviceInit - the initialization information for the device.
+
+ Return Value:
+
+ status
+
+--*/
+{
+ Trace(
+ TRACE_LEVEL_INFORMATION,
+ "%!FUNC!"
+ );
+
+ HRESULT hr;
+
+ CComObject<CMyDevice> * device = NULL;
+
+ //
+ // Create a new instance of our device callback object
+ //
+
+ hr = CComObject<CMyDevice>::CreateInstance(&device);
+
+ if (SUCCEEDED(hr))
+ {
+ device->AddRef();
+ hr = device->Initialize(FxWdfDriver, FxDeviceInit);
+ }
+
+ //
+ // If that succeeded then call the device's configure method. This
+ // allows the device to create any queues or other structures that it
+ // needs now that the corresponding fx device object has been created.
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ hr = device->Configure();
+ }
+
+ //
+ // Release the reference we took on the device callback object.
+ // The framework took its own references on the object's callback interfaces
+ // when we called FxWdfDriver->CreateDevice, and will manage the object's lifetime.
+ //
+ SAFE_RELEASE(device);
+
+ return hr;
+}
diff --git a/general/echo/umdfSocketEcho/Driver/driver.h b/general/echo/umdfSocketEcho/Driver/driver.h
new file mode 100644
index 00000000..6affa20f
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/driver.h
@@ -0,0 +1,53 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved
+
+Module Name:
+
+ Driver.h
+
+Abstract:
+
+ This module contains the type definitions for the UMDF Socketecho sample's
+ driver callback class.
+
+Environment:
+
+ Windows User-Mode Driver Framework (WUDF)
+
+--*/
+
+#pragma once
+
+//
+// This class handles driver events for the socktecho sample. In particular
+// it supports the OnDeviceAdd event, which occurs when the driver is called
+// to setup per-device handlers for a new device stack.
+//
+
+extern const GUID CLSID_MyDriverCoClass;
+
+class ATL_NO_VTABLE CMyDriver :
+ public CComObjectRootEx<CComMultiThreadModel>,
+ public CComCoClass<CMyDriver, &CLSID_MyDriverCoClass>,
+ public IDriverEntry
+{
+public:
+
+DECLARE_NOT_AGGREGATABLE(CMyDriver)
+
+DECLARE_CLASSFACTORY();
+
+DECLARE_NO_REGISTRY();
+
+BEGIN_COM_MAP(CMyDriver)
+ COM_INTERFACE_ENTRY(IDriverEntry)
+END_COM_MAP()
+
+public:
+ // IDriverEntry
+ STDMETHOD(OnInitialize)(_In_ IWDFDriver* pWdfDriver);
+ STDMETHOD(OnDeviceAdd)(_In_ IWDFDriver* pWdfDriver, _In_ IWDFDeviceInitialize* pWdfDeviceInit);
+ STDMETHOD_(void,OnDeinitialize)(_In_ IWDFDriver* pWdfDriver);
+};
+
diff --git a/general/echo/umdfSocketEcho/Driver/exports.def b/general/echo/umdfSocketEcho/Driver/exports.def
new file mode 100644
index 00000000..2c0b7d49
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/exports.def
@@ -0,0 +1,6 @@
+; Socketecho.def : Declares the module parameters.
+
+LIBRARY "SocketEcho"
+
+EXPORTS
+ DllGetClassObject PRIVATE
diff --git a/general/echo/umdfSocketEcho/Driver/internal.h b/general/echo/umdfSocketEcho/Driver/internal.h
new file mode 100644
index 00000000..a7875468
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Driver/internal.h
@@ -0,0 +1,117 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved
+
+Module Name:
+
+ Internal.h
+
+Abstract:
+
+ This module contains the local type definitions for the UMDF Socketecho sample
+ driver sample.
+
+Environment:
+
+ Windows User-Mode Driver Framework (WUDF)
+
+--*/
+
+#pragma once
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+//
+// Include the winsock headers before any other windows headers.
+//
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+//
+// Include the WUDF DDI
+//
+
+#include "wudfddi.h"
+
+//
+// Use specstrings for in/out annotation of function parameters.
+//
+
+#include "specstrings.h"
+
+//
+// Define the tracing flags.
+//
+
+#define WPP_CONTROL_GUIDS \
+ WPP_DEFINE_CONTROL_GUID( \
+ MyDriverTraceControl, (64316518,DFE2,42B6,8786,4995E5EC435), \
+ \
+ WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \
+ )
+
+#define WPP_FLAG_LEVEL_LOGGER(flag, level) \
+ WPP_LEVEL_LOGGER(flag)
+
+#define WPP_FLAG_LEVEL_ENABLED(flag, level) \
+ (WPP_LEVEL_ENABLED(flag) && \
+ WPP_CONTROL(WPP_BIT_ ## flag).Level >= level)
+
+//
+// This comment block is scanned by the trace preprocessor to define our
+// Trace function.
+//
+// begin_wpp config
+// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...);
+// end_wpp
+//
+
+//
+// Driver specific #defines
+//
+
+#define MYDRIVER_TRACING_ID L"Microsoft\\UMDF\\SocketEcho"
+#define MYDRIVER_CLASS_ID { 0x83B87D35, 0x76B8, 0x4920, {0xB4, 0x3C, 0x3B, 0xDE, 0x6B, 0x0E, 0xC5, 0xB8} }
+
+#ifndef SAFE_RELEASE
+#define SAFE_RELEASE(p) {if ((p)) { (p)->Release(); (p) = NULL; }}
+#endif
+
+__forceinline
+#ifdef _PREFAST_
+__declspec(noreturn)
+#endif
+VOID
+WdfTestNoReturn(
+ VOID
+ )
+{
+ // do nothing.
+}
+
+#define WUDF_SAMPLE_DRIVER_ASSERT(p) \
+{ \
+ if ( !(p) ) \
+ { \
+ DebugBreak(); \
+ WdfTestNoReturn(); \
+ } \
+}
+
+//
+// Include the type specific headers.
+//
+#include <atlbase.h>
+#include <atlcom.h>
+
+#include "connection.h"
+#include "filecontext.h"
+#include "devicecontext.h"
+#include "driver.h"
+#include "device.h"
+#include "queue.h"
+
+_Analysis_mode_(_Analysis_operator_new_null_)
+
diff --git a/general/echo/umdfSocketEcho/Exe/internal.h b/general/echo/umdfSocketEcho/Exe/internal.h
new file mode 100644
index 00000000..ff1cd863
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Exe/internal.h
@@ -0,0 +1,18 @@
+// internal.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include <driverspecs.h>
+_Analysis_mode_(_Analysis_code_type_user_code_);
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strsafe.h>
+#include <setupapi.h>
+
+#include "socketechoserver.h"
diff --git a/general/echo/umdfSocketEcho/Exe/socketechoserver.cpp b/general/echo/umdfSocketEcho/Exe/socketechoserver.cpp
new file mode 100644
index 00000000..bfe5f546
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Exe/socketechoserver.cpp
@@ -0,0 +1,512 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ socketserver.cpp
+
+Abstract:
+
+ A simple socket server application that listens on a specified port and echoes back data
+ received.
+
+Environment:
+
+ User Mode
+
+--*/
+
+#include "internal.h"
+
+
+DWORD
+Run(
+ LPVOID lpThreadParameter
+ )
+ /*++
+
+Routine Description:
+
+ This routine is invoked for each thread created for a new connection accepted by the server.
+ The rcv and send to socket happen in this thread routine.
+
+
+Arguments:
+
+ lpThreadParameter , The Thread parameter which contains socket information
+
+Return Value:
+
+ Thread Exit Code
+
+
+--*/
+{
+ #define DeleteBufferExitThread(dwExitCode) \
+ delete[] buffer; \
+ buffer = NULL; \
+ ExitThread(dwExitCode);
+
+ #define DeleteBufferReturn(dwExitCode) \
+ delete[] buffer; \
+ buffer = NULL; \
+ return dwExitCode;
+
+ int count =0;
+
+ char *buffer = new char[DATA_LENGTH];
+ if (NULL == buffer)
+ {
+ ExitThread(1);
+ }
+
+ DWORD Event;
+
+ //
+ // Look at socket information from thread arg.
+ //
+
+
+ CEchoServer *pThreadData = (CEchoServer*)lpThreadParameter;
+ if (pThreadData==NULL)
+ {
+ DeleteBufferExitThread(1);
+ }
+
+ SOCKET sClient = pThreadData->m_socket;
+ HANDLE NetworkEvent = pThreadData->m_NetworkEvent;
+ WSANETWORKEVENTS NetworkEvents;
+ printf("Client Start: 0x%Ix\n", sClient);
+ int actual = 0;
+ for(;;)
+ {
+ if ((Event = WSAWaitForMultipleEvents(
+ 1,
+ &NetworkEvent,
+ FALSE,
+ WSA_INFINITE,
+ FALSE)) == WSA_WAIT_FAILED)
+ {
+ printf("WSAWaitForMultipleEvents failed with error %d\n", WSAGetLastError());
+ DeleteBufferReturn(0);
+ }
+
+ if (WSAEnumNetworkEvents(sClient ,NetworkEvent, &NetworkEvents) == SOCKET_ERROR)
+ {
+ printf("WSAEnumNetworkEvents failed with error %d\n", WSAGetLastError());
+ DeleteBufferReturn(0);
+ }
+
+ if (NetworkEvents.lNetworkEvents & FD_READ)
+ {
+ if (NetworkEvents.lNetworkEvents & FD_READ && NetworkEvents.iErrorCode[FD_READ_BIT] != 0)
+ {
+ printf("FD_READ failed with error %d\n", NetworkEvents.iErrorCode[FD_READ_BIT]);
+ }
+ else
+ {
+
+ actual = recv(sClient,buffer,DATA_LENGTH*sizeof(char),0);
+ //
+ // socket connection has been reset ,so bail out .
+ //
+ if (actual == 0 || actual == WSAECONNRESET )
+ {
+ printf(" Could not get data , Error : 0x%lx \n",WSAGetLastError());
+ break; // socket shut-down
+
+ }
+ printf("FD_READ read buffer on client 0x%Ix with length %d \n",sClient,actual);
+ count = send(sClient, (const char*)buffer,actual,0);
+ if ( count == SOCKET_ERROR )
+ {
+ if ( WSAGetLastError()== WSAEWOULDBLOCK )
+ {
+ printf(" Could not send data as resource is unavaliable , do not retry until next Write event \n");
+ }
+ else
+ {
+ printf(" Could not send data , Error : 0x%lx \n",WSAGetLastError());
+ break;
+ }
+ }
+ else
+ {
+ printf("FD_WRITE write buffer on client 0x%Ix with length %d \n",sClient,count);
+ }
+ }
+ }
+ //
+ // if there is a write network event and there is data to write , write that
+ //
+ if (NetworkEvents.lNetworkEvents & FD_WRITE)
+ {
+ if (NetworkEvents.lNetworkEvents & FD_WRITE && NetworkEvents.iErrorCode[FD_WRITE_BIT] != 0)
+ {
+ printf("FD_WRITE failed with error %d\n", NetworkEvents.iErrorCode[FD_WRITE_BIT]);
+ }
+ else
+ {
+ count = send(sClient, (const char*)buffer,actual,0);
+ if ( count == SOCKET_ERROR )
+ {
+ if ( WSAGetLastError()== WSAEWOULDBLOCK )
+ {
+ printf(" Could not send data as resource is unavaliable , do not retry until next Write event ");
+ }
+ else
+ {
+ printf(" Could not send data , Error : 0x%lx \n",WSAGetLastError());
+ break;
+ }
+ }
+ else
+ {
+ printf("FD_WRITE write buffer on client 0x%Ix with length %d \n",sClient,count);
+ }
+ actual = 0;
+ }
+ }
+ if (NetworkEvents.lNetworkEvents & FD_CLOSE)
+ {
+ shutdown(sClient,FD_READ|FD_WRITE);
+ printf(" recived a close from client : 0x%Ix \n",sClient);
+ closesocket(sClient);
+ DeleteBufferExitThread(0);
+ }
+ }
+
+ DeleteBufferReturn(1);
+
+}
+
+CEchoServer::CEchoServer(
+ SOCKET socketclient
+ )
+/*++
+
+Routine Description:
+
+ This is the constructor routine for CEchoServer class. This is called for each instance of new
+ connection accepted by the server .
+
+Arguments:
+
+ Socket received from the accept
+
+Return Value:
+
+ None .
+
+--*/
+{
+ m_socket = socketclient;
+ m_NetworkEvent = WSACreateEvent();
+ printf("socket created : 0x%Ix \n", m_socket);
+
+}
+
+void
+CEchoServer::Start()
+/*++
+
+Routine Description:
+
+ This routine is to Start the thread which will rcv and send the data recieved on this instance of socket connection.
+
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+--*/
+{
+
+
+ if(WSAEventSelect(
+ m_socket,
+ m_NetworkEvent,
+ FD_READ|FD_WRITE|FD_CLOSE)== SOCKET_ERROR)
+ {
+ printf("Error in Event Select,Cannot start Server thread for this socket \n");
+ closesocket(m_socket);
+ goto Exit;
+ }
+//
+// Create thread to read/write data to this socket
+//
+
+ HANDLE hRunThread = CreateThread(
+ NULL, // Default Security Attrib.
+ 0, // Initial Stack Size,
+ (LPTHREAD_START_ROUTINE) Run, // Thread Func
+ this, // Arg to Thread Func.
+ 0, // Creation Flags
+ NULL // Don't need the Thread Id.
+ );
+ if (NULL == hRunThread)
+ {
+ printf(" Could not create socket server run thread : 0x%lx \n", GetLastError());
+ closesocket(m_socket);
+ goto Exit;
+ }
+
+Exit:
+
+ return ;
+ }
+
+void
+SocketServerMain(
+ _In_ unsigned short uPort
+ )
+/*++
+
+Routine Description:
+
+ This routine is the main entry for the app when the app is configured to
+ be a socket server.
+ It creates a a listening socket for incoming conenctions.
+
+
+Arguments:
+
+ uPort - Port Number that the socket server binds to
+
+Return Value:
+
+ None.
+--*/
+{
+
+
+ SOCKET ListenSocket;
+ int iResult;
+ #pragma warning( suppress: 24002 ) // suppress warning for IPv6 ,currently IPv4 specific
+ sockaddr_in service ;
+
+ // Initialize Winsock 2.2
+ WSADATA wsaData;
+ iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
+ if ( NO_ERROR != iResult )
+ {
+ printf("Error at WSAStartup() \n");
+ goto Exit;
+ }
+ //
+ // Create a SOCKET for listening for incoming connection requests.
+ //
+ ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if ( INVALID_SOCKET == ListenSocket)
+ {
+ printf("Error at socket(): %ld\n ", WSAGetLastError());
+ goto Cleanup;
+ }
+ // The sockaddr_in structure specifies the address family,
+ // IP address, and port for the socket that is being bound.
+ service.sin_family = AF_INET;
+ //
+ // Suppress overflow warning.
+ // inet_pton is annotated to write sizeof(IN6_ADDR) bytes to pAddrBuf,
+ // but it only writes sizeof(IN_ADDR) bytes when Family is AF_INET (IPv4).
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/cc805844(v=vs.85).aspx
+ //
+ #pragma warning( suppress: 26000 )
+ iResult = inet_pton(AF_INET, "127.0.0.1", &service.sin_addr);
+ if (iResult != 1)
+ {
+ printf("Error at inet_pton(): %ld\n ", WSAGetLastError());
+ closesocket(ListenSocket);
+ goto Cleanup;
+ }
+ service.sin_port = htons(uPort);
+ if (SOCKET_ERROR == bind(
+ ListenSocket,
+ (SOCKADDR*) &service,
+ sizeof(service) ) )
+ {
+ printf("bind() failed. \n");
+ closesocket(ListenSocket);
+ goto Cleanup;
+ }
+
+ //
+ // Listen for incoming connection requests
+ // on the created socket upto MAX_CONNECTIONS
+ //
+ if ( SOCKET_ERROR == listen(
+ ListenSocket,
+ MAX_CONNECTIONS ) )
+ {
+ printf("Error listening on socket.\n");
+ }
+ printf("Listening on socket...\n");
+
+ //
+ // Set Socket RCVBUF and SNDBUF size to DATA_LENGTH , so large requests are not fragmented .
+ //
+ int iOptVal;
+ int iOptLen = sizeof(int);
+
+ if (getsockopt(ListenSocket, SOL_SOCKET, SO_RCVBUF, (char*)&iOptVal, &iOptLen) != SOCKET_ERROR)
+ {
+ printf("SO_RCVBUF value: %ld\n", iOptVal);
+ }
+ iOptVal = DATA_LENGTH;
+ iOptLen = sizeof(int);
+ if (setsockopt(ListenSocket, SOL_SOCKET, SO_RCVBUF, (char*)&iOptVal, iOptLen) != SOCKET_ERROR)
+ {
+ printf("Set SO_RCVBUF: ON\n");
+ }
+ iOptLen = sizeof(int);
+ if (getsockopt(ListenSocket, SOL_SOCKET, SO_RCVBUF, (char*)&iOptVal, &iOptLen) != SOCKET_ERROR)
+ {
+ printf("SO_RCVBUF Value: %ld\n", iOptVal);
+ }
+ iOptLen = sizeof(int);
+ if (getsockopt(ListenSocket, SOL_SOCKET, SO_SNDBUF, (char*)&iOptVal, &iOptLen) != SOCKET_ERROR)
+ {
+ printf("SO_SNDBUF value: %ld\n", iOptVal);
+ }
+ iOptVal = DATA_LENGTH;
+ iOptLen = sizeof(int);
+ if (setsockopt(ListenSocket, SOL_SOCKET, SO_SNDBUF, (char*)&iOptVal, iOptLen) != SOCKET_ERROR)
+ {
+ printf("Set SO_SNDBUF: ON\n");
+ }
+ iOptLen = sizeof(int);
+ if (getsockopt(ListenSocket, SOL_SOCKET, SO_SNDBUF, (char*)&iOptVal, &iOptLen) != SOCKET_ERROR)
+ {
+ printf("SO_SNDBUF Value: %ld\n", iOptVal);
+ }
+
+//
+// Loop the server to start accepting connections from clients on this socket
+//
+
+ for(;;)
+ {
+ CEchoServer *client = new CEchoServer(accept(ListenSocket,NULL,NULL));
+
+ if (client)
+ {
+ printf("Client connected.\n");
+ client->Start(); // Start receiving/sending data on the socket
+ }
+ }
+
+Cleanup:
+ //
+ // Invoke Winsock Cleanup
+ //
+
+ WSACleanup();
+
+ Exit:
+ return;
+
+}
+void
+Usage()
+
+/*++
+
+Routine Description:
+
+ This routine is invoked to display the usage of this application
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None .
+--*/
+
+{
+ printf("\n\n Usage: \n");
+ printf(" ------ \n\n");
+ printf(" socketechoapp Display Usage \n");
+ printf(" socketechoapp -h Display Usage\n");
+ printf(" socketechoapp -p Start the app as server listening on default port\n");
+ printf(" socketechoapp -p [port#] Start the app as server listening on this port \n");
+
+
+
+}
+
+
+/* */
+void __cdecl
+main(
+ _In_ int argc,
+ _In_reads_(argc) char* argv[]
+ )
+
+/*++
+
+Routine Description:
+
+
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+--*/
+{
+ unsigned short argIndex = 1 ;
+ unsigned short uPort = DEFAULT_PORT_ADDRESS ;
+
+
+ if (argc < 2)
+ {
+ Usage();
+ goto Exit;
+ }
+
+//
+// look at second arg and check for either -h which indicates user asked for help in Usage
+// of this commandline
+//
+
+ if (!strcmp(*(argv+argIndex),"-h"))
+ {
+ Usage();
+ goto Exit;
+ }
+//
+// check if its -p and proceed with otherwise show usage
+//
+ else if (!strcmp(*(argv+argIndex),"-p"))
+ {
+ //
+ // look at third arg, which should be the port#
+ //
+ if ( ++argIndex < argc )
+ {
+ uPort = (unsigned short)atoi(*(argv+(argIndex)));
+ }
+ SocketServerMain(uPort);
+
+ }
+ else
+ {
+ Usage();
+ goto Exit;
+ }
+
+Exit:
+ return;
+
+}
+
+
diff --git a/general/echo/umdfSocketEcho/Exe/socketechoserver.h b/general/echo/umdfSocketEcho/Exe/socketechoserver.h
new file mode 100644
index 00000000..f71bc48b
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Exe/socketechoserver.h
@@ -0,0 +1,48 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Module Name:
+
+ sockechoserver.h
+
+Abstract:
+
+ Header file for the socket server module of the socketecho application
+
+Environment:
+
+ User mode only
+
+--*/
+
+#pragma once
+
+
+#define MAX_CONNECTIONS 5
+#define DEFAULT_PORT_ADDRESS 6000
+#define DATA_LENGTH 1024*40
+
+void
+SocketServerMain(
+ _In_ unsigned short uPort
+ );
+
+ //
+ // Class definition for CEchoServer Class
+ //
+class CEchoServer
+{
+
+ public:
+
+ SOCKET m_socket;
+ HANDLE m_NetworkEvent;
+
+
+
+ CEchoServer(SOCKET socketclient);
+ void Start();
+
+};
+
diff --git a/general/echo/umdfSocketEcho/Exe/socketechoserver.vcxproj b/general/echo/umdfSocketEcho/Exe/socketechoserver.vcxproj
new file mode 100644
index 00000000..ea299161
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Exe/socketechoserver.vcxproj
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4237BF5F-1426-45DD-96E0-74DEADFA24C6}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{13151EE8-4C58-4284-BA01-C4B9431C6B06}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>socketechoserver</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>socketechoserver</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>socketechoserver</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>socketechoserver</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);user32.lib;Ws2_32.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);user32.lib;Ws2_32.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);user32.lib;Ws2_32.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);user32.lib;Ws2_32.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(DDK_INC_PATH)</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="socketechoserver.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/general/echo/umdfSocketEcho/Exe/socketechoserver.vcxproj.Filters b/general/echo/umdfSocketEcho/Exe/socketechoserver.vcxproj.Filters
new file mode 100644
index 00000000..035fba1a
--- /dev/null
+++ b/general/echo/umdfSocketEcho/Exe/socketechoserver.vcxproj.Filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{1BEC8228-FE60-4512-B036-885F56208A4B}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{E4060FEA-373E-4AE6-94B7-FF878D406EAE}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{181042B8-D282-46BA-B9D7-BDEE33402D00}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="socketechoserver.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/echo/umdfSocketEcho/ReadMe.md b/general/echo/umdfSocketEcho/ReadMe.md
new file mode 100644
index 00000000..12515365
--- /dev/null
+++ b/general/echo/umdfSocketEcho/ReadMe.md
@@ -0,0 +1,184 @@
+UMDF SocketEcho Sample (UMDF Version 1)
+=======================================
+
+The UMDF SocketEcho sample demonstrates how to use the User-Mode Driver Framework (UMDF) to write a driver and demonstrates best practices.
+
+This sample also demonstrates how to use a default parallel dispatch I/O queue, use a Microsoft Win32 dispatcher, and handle a socket handle by using a Win32 file I/O target.
+
+Related technologies
+--------------------
+
+[User-Mode Driver Framework](http://msdn.microsoft.com/en-us/library/windows/hardware/ff560456)
+
+Code Tour
+---------
+
+Parts of this code sample are generated from the ATL Project Wizard in Microsoft Visual Studio 2005. This sample driver is a minimal driver that is intended to demonstrate how to use UMDF. It is not intended for use in a production environment.
+
+CMyDriver::OnInitialize in driver.cpp is called by the framework when the driver loads. This method initiates use of the Winsock Library. CMyDriver::OnDeviceAdd in driver.cpp is called by the framework to install the driver on a device stack. OnDeviceAdd creates a device callback object, and then calls IWDFDriver::CreateDevice to create an framework device object and to associate the device callback object with the framework device object.
+
+CMyQueue::OnCreateFile in queue.cpp is called by the framework to create a socket connection, create a file i/o target that is associated with the socket handle for this connection, and store the socket handle in the file object context.
+
+Installation
+------------
+
+In Visual Studio, you can press F5 to build the sample and then deploy it to a target machine. For more information, see [Deploying a Driver to a Test Computer](http://msdn.microsoft.com/en-us/library/windows/hardware/hh454834). Alternatively, you can install the sample from the command line.
+
+To test this sample, you must have a test computer that is running Windows Vista or later. This test computer can be a second computer or, if necessary, your development computer.
+
+To install the UMDF Echo sample driver from the command line, do the following:
+
+1. Copy the driver binary and the socketecho.inf file to a directory on your test computer (for example, C:\\ socketechoSample.)
+
+2. Copy the UMDF coinstaller, WUDFUpdate\_*MMmmmm*.dll, from the \\redist\\wdf\\\<architecture\> directory to the same directory (for example, C:\\socketechoSample).
+
+ **Note**  
+
+ You can obtain redistributable framework updates by downloading the *wdfcoinstaller.msi* package from [WDK 8 Redistributable Components](http://go.microsoft.com/fwlink/p/?LinkID=226396). This package performs a silent install into the directory of your Windows Driver Kit (WDK) installation. You will see no confirmation that the installation has completed. You can verify that the redistributables have been installed on top of the WDK by ensuring there is a redist\\wdf directory under the root directory of the WDK, %ProgramFiles(x86)%\\Windows Kits\\8.0.
+
+3.
+
+ Navigate to the directory that contains the INF file and binaries (for example, cd /d c:\\socketechoSample), and run DevCon.exe as follows:
+
+ **devcon.exe install socketecho.inf WUDF\\socketecho**
+
+ You can find DevCon.exe in the \\tools directory of the WDK (for example, \\tools\\devcon\\i386\\devcon.exe).
+
+To update the socketecho driver after you make any changes, do the following:
+
+1. Increment the version number in the INF file. This change is not necessary, but it will help ensure that Plug and Play (PnP) selects your new driver as a better match for the device.
+
+2. Copy the updated driver binary and the socketecho.inf file to a directory on your test computer (for example, C:\\ socketechoSample.)
+
+3. Navigate to the directory that contains the INF file and binaries (for example, cd /d c:\\ socketechoSample), and run devcon.exe as follows:
+
+ devcon.exe update socketecho.inf WUDF\\socketecho
+
+To test this sample drivers on a checked operating system that you have installed (in contrast to the standard retail installations), you must modify the INF file to use the checked version of the UMDF co-installer. That is, you must do the following:
+
+1. In the INX file, replace all occurrences of WudfUpdate\_*MMmmmm*.dll with WudfUpdate\_*MMmmmm*\_chk.dll.
+
+2. Copy the WudfUpdate\_*MMmmmm*\_chk.dll file from the \\redist\\wdf\\\<architecture\> directory to your driver package instead of WudfUpdate\_*MMmmmm*.dll.
+
+3. If WdfCoinstaller*MMmmmm*.dll or WinUsbCoinstaller.dll is included in your driver package, repeat step 1 and step 2 for them.
+
+Testing
+-------
+
+To test the SocketEcho driver, you can run socketechoserver.exe, which is built from the src\\general\\echo\\umdfSocketEcho\\Exe directory, and echoapp.exe, which is built from the Kernel-Mode Driver Framework (KMDF) samples in the src\\general\\echo\\kmdf directory.
+
+First, you must install the device as described earlier. Then, run socketechoserver.exe from a Command Prompt window.
+
+D:\\\>socketechoserver -h
+
+Usage:
+
+------
+
+socketechoserver Display Usage
+
+socketechoserver -h Display Usage
+
+socketechoserver -p Start the app as server listening on default port
+
+socketechoserver -p [port\#] Start the app as server listening on this port
+
+D:\\\>socketechoserver -p
+
+Listening on socket...
+
+In another Command Prompt window, run echoapp.exe.
+
+D:\\\>echoapp
+
+DevicePath: \\\\?\\root\#sample\#0000\#{ e5e65b0c-82c8-4689-96d4-f77837971990}
+
+Opened device successfully
+
+512 Pattern Bytes Written successfully
+
+512 Pattern Bytes Read successfully
+
+Pattern Verified successfully
+
+D:\\\>echoapp -Async
+
+DevicePath: \\\\?\\root\#sample\#0000\#{cdc35b6e-0be4-4936-bf5f-5537380a7c1a}
+
+Opened device successfully
+
+Starting AsyncIo
+
+Number of bytes written by request number 0 is 1024
+
+Number of bytes read by request number 0 is 1024
+
+Number of bytes read by request number 1 is 1024
+
+Number of bytes written by request number 2 is 1024
+
+Number of bytes read by request number 2 is 1024
+
+Number of bytes written by request number 3 is 1024
+
+Number of bytes read by request number 3 is 1024
+
+Number of bytes written by request number 4 is 1024
+
+Number of bytes read by request number 4 is 1024
+
+Number of bytes written by request number 5 is 1024
+
+Number of bytes read by request number 5 is 1024
+
+Number of bytes written by request number 6 is 1024
+
+Number of bytes read by request number 6 is 1024
+
+Number of bytes written by request number 7 is 1024
+
+Number of bytes read by request number 7 is 1024
+
+Number of bytes written by request number 8 is 1024
+
+Number of bytes read by request number 8 is 1024
+
+Number of bytes written by request number 9 is 1024
+
+Number of bytes read by request number 9 is 1024
+
+Number of bytes written by request number 10 is 1024
+
+Number of bytes read by request number 10 is 1024
+
+Number of bytes written by request number 11 is 1024
+
+...
+
+Note that independent threads perform the reads and writes in the echo test application. As a result, the order of the output might not exactly match what you see in the preceding output.
+
+File Manifest
+-------------
+
+<table>
+<colgroup>
+<col width="50%" />
+<col width="50%" />
+</colgroup>
+<thead>
+<tr class="header">
+<th align="left">File
+Description</th>
+</tr>
+</thead>
+<tbody>
+<tr class="odd">
+<td align="left"><p>Socketecho.htm</p>
+<p>The documentation for this sample.</p></td>
+<td align="left"><p>Dllsup.cpp</p>
+<p>The DLL support code that provides the DLL's entry point and the single required export (DllGetClassObject).</p></td>
+</tr>
+</tbody>
+</table>
+
+
diff --git a/general/echo/umdfSocketEcho/umdfsocketecho.sln b/general/echo/umdfSocketEcho/umdfsocketecho.sln
new file mode 100644
index 00000000..9cd8f76d
--- /dev/null
+++ b/general/echo/umdfSocketEcho/umdfsocketecho.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0
+MinimumVisualStudioVersion = 12.0
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Driver", "Driver", "{C4B24CED-B58F-47D1-8FC0-778610EF84CF}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{AFCDA28A-1D07-410D-BA77-47E637336CA6}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SocketEcho", "Driver\SocketEcho.vcxproj", "{ABEFFAA1-36CF-4F78-9A6B-10EAEC11B3E3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "socketechoserver", "Exe\socketechoserver.vcxproj", "{4237BF5F-1426-45DD-96E0-74DEADFA24C6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {ABEFFAA1-36CF-4F78-9A6B-10EAEC11B3E3}.Debug|Win32.ActiveCfg = Debug|Win32
+ {ABEFFAA1-36CF-4F78-9A6B-10EAEC11B3E3}.Debug|Win32.Build.0 = Debug|Win32
+ {ABEFFAA1-36CF-4F78-9A6B-10EAEC11B3E3}.Release|Win32.ActiveCfg = Release|Win32
+ {ABEFFAA1-36CF-4F78-9A6B-10EAEC11B3E3}.Release|Win32.Build.0 = Release|Win32
+ {ABEFFAA1-36CF-4F78-9A6B-10EAEC11B3E3}.Debug|x64.ActiveCfg = Debug|x64
+ {ABEFFAA1-36CF-4F78-9A6B-10EAEC11B3E3}.Debug|x64.Build.0 = Debug|x64
+ {ABEFFAA1-36CF-4F78-9A6B-10EAEC11B3E3}.Release|x64.ActiveCfg = Release|x64
+ {ABEFFAA1-36CF-4F78-9A6B-10EAEC11B3E3}.Release|x64.Build.0 = Release|x64
+ {4237BF5F-1426-45DD-96E0-74DEADFA24C6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4237BF5F-1426-45DD-96E0-74DEADFA24C6}.Debug|Win32.Build.0 = Debug|Win32
+ {4237BF5F-1426-45DD-96E0-74DEADFA24C6}.Release|Win32.ActiveCfg = Release|Win32
+ {4237BF5F-1426-45DD-96E0-74DEADFA24C6}.Release|Win32.Build.0 = Release|Win32
+ {4237BF5F-1426-45DD-96E0-74DEADFA24C6}.Debug|x64.ActiveCfg = Debug|x64
+ {4237BF5F-1426-45DD-96E0-74DEADFA24C6}.Debug|x64.Build.0 = Debug|x64
+ {4237BF5F-1426-45DD-96E0-74DEADFA24C6}.Release|x64.ActiveCfg = Release|x64
+ {4237BF5F-1426-45DD-96E0-74DEADFA24C6}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {ABEFFAA1-36CF-4F78-9A6B-10EAEC11B3E3} = {C4B24CED-B58F-47D1-8FC0-778610EF84CF}
+ {4237BF5F-1426-45DD-96E0-74DEADFA24C6} = {AFCDA28A-1D07-410D-BA77-47E637336CA6}
+ EndGlobalSection
+EndGlobal