[ofw] [RFC] [PATCH 4/12] winverbs: implement IWVProvider

Sean Hefty sean.hefty at intel.com
Fri Mar 14 23:00:11 PDT 2008


Userspace WinVerb implementation for the winverb provider.

The provider class is responsible for opening the file to communicate
with the winverb driver.  A simple Open() stub has been created for
this, which will need to be coordinated with the driver implementation,
once it's ready.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---

Index: core/winverbs/user/wv_provider.cpp
===================================================================
--- core/winverbs/user/wv_provider.cpp	(revision 981)
+++ core/winverbs/user/wv_provider.cpp	(working copy)
@@ -27,21 +27,48 @@
  * SOFTWARE.
  */
 
+#include <iba\ib_al.h>
+
 #include "wv_base.h"
 #include "wv_provider.h"
 #include "wv_device.h"
+#include "wv_ep.h"
+#include "wv_listen.h"
 
+CWVProvider::CWVProvider()
+{
+	m_nRef = 1;
+	InterlockedIncrement(&WvRef);
+
+	m_hFile = INVALID_HANDLE_VALUE;
+}
+
 STDMETHODIMP CWVProvider::
+Open(void)
+{
+	m_hFile = CreateFileW(L"\\\\.\\WinVerbs", GENERIC_READ | GENERIC_WRITE,
+						  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+						  FILE_FLAG_OVERLAPPED, NULL);
+
+	return (m_hFile == INVALID_HANDLE_VALUE) ? WV_UNSUCCESSFUL : WV_SUCCESS;
+}
+
+CWVProvider::~CWVProvider()
+{
+	CloseHandle(m_hFile);
+	InterlockedDecrement(&WvRef);
+}
+
+STDMETHODIMP CWVProvider::
 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
 {
-	if (riid != IID_IUnknown && riid != IID_IWVProvider)
-	{
+	if (riid != IID_IUnknown && riid != IID_IWVProvider) {
 		*ppvObj = NULL;
 		return E_NOINTERFACE;
 	}
 
 	*ppvObj = this;
-	InterlockedIncrement(&m_nRef);
+	AddRef();
 	return WV_SUCCESS;
 }
 
@@ -57,18 +84,44 @@
 	ULONG ref;
 
 	ref = (ULONG) InterlockedDecrement(&m_nRef);
-	if (ref == 0)
+	if (ref == 0) {
 		delete this;
+	}
 	return ref;
 }
 
 STDMETHODIMP CWVProvider::
 QueryDeviceList(UINT64* pGuidList, SIZE_T* pBufferSize)
 {
-	UNREFERENCED_PARAMETER(pGuidList);
-	UNREFERENCED_PARAMETER(pBufferSize);
+	CWVBuffer		buf;
+	WV_IO_GUID_LIST	*list;
+	DWORD			bytes;
+	HRESULT			hr;
 
-	return E_NOTIMPL;
+	bytes = sizeof(WV_IO_GUID_LIST) + *pBufferSize;
+	list = (WV_IO_GUID_LIST *) buf.Get(bytes);
+	if (list == NULL) {
+		return WV_NO_MEMORY;
+	}
+
+	if (!DeviceIoControl(m_hFile, WV_IOCTL_GUID_QUERY, NULL, 0,
+						 list, bytes, &bytes, NULL)) {
+		hr = HRESULT_FROM_WIN32(GetLastError());
+		goto out;
+	}
+
+	if (*pBufferSize >= list->Count * sizeof UINT64) {
+		RtlCopyMemory(pGuidList, list->Guid, list->Count * sizeof UINT64);
+	} else if (*pBufferSize > 0) {
+		RtlCopyMemory(pGuidList, list->Guid, *pBufferSize);
+	}
+
+	*pBufferSize = list->Count * sizeof UINT64;
+	hr = WV_SUCCESS;
+
+out:
+	buf.Put();
+	return hr;
 }
 
 STDMETHODIMP CWVProvider::
@@ -78,8 +131,9 @@
 	HRESULT hr;
 
 	hr = OpenDevice(Guid, &dev);
-	if (hr != WV_SUCCESS)
+	if (FAILED(hr)) {
 		goto out;
+	}
 	
 	hr = dev->Query(pAttributes);
 	dev->Release();
@@ -103,17 +157,18 @@
 	CWVDevice *dev;
 
 	dev = new CWVDevice(this);
-	if (!dev)
-	{
+	if (dev == NULL) {
 		hr = WV_NO_MEMORY;
 		goto err1;
 	}
 
 	dev->QueryInterface(IID_IWVDevice, (LPVOID*) ppDevice);
+	dev->Release();
 
 	hr = dev->Open(Guid);
-	if (hr != WV_SUCCESS)
+	if (FAILED(hr)) {
 		goto err2;
+	}
 
 	return WV_SUCCESS;
 
@@ -127,25 +182,70 @@
 STDMETHODIMP CWVProvider::
 CreateConnectEndpoint(IWVConnectEndpoint** ppConnectEndpoint)
 {
-	UNREFERENCED_PARAMETER(ppConnectEndpoint);
+	HRESULT hr;
+	CWVConnectEndpoint *ep;
 
-	return E_NOTIMPL;
+	ep = new CWVConnectEndpoint(this);
+	if (ep == NULL) {
+		hr = WV_NO_MEMORY;
+		goto err1;
+	}
+
+	ep->QueryInterface(IID_IWVConnectEndpoint, (LPVOID*) ppConnectEndpoint);
+	ep->Release();
+	return WV_SUCCESS;
+
+err1:
+	*ppConnectEndpoint = NULL;
+	return hr;
 }
 
 STDMETHODIMP CWVProvider::
 CreateDatagramEndpoint(IWVDatagramEndpoint** ppDatagramEndpoint)
 {
-	UNREFERENCED_PARAMETER(ppDatagramEndpoint);
+	HRESULT hr;
+	CWVDatagramEndpoint *ep;
 
-	return E_NOTIMPL;
+	ep = new CWVDatagramEndpoint(this);
+	if (ep == NULL) {
+		hr = WV_NO_MEMORY;
+		goto err1;
+	}
+
+	ep->QueryInterface(IID_IWVDatagramEndpoint, (LPVOID*) ppDatagramEndpoint);
+	ep->Release();
+	return WV_SUCCESS;
+
+err1:
+	*ppDatagramEndpoint = NULL;
+	return hr;
 }
 
 STDMETHODIMP CWVProvider::
 CreateListen(const struct sockaddr* pAddress, SIZE_T Backlog, IWVListen** ppListen)
 {
-	UNREFERENCED_PARAMETER(pAddress);
-	UNREFERENCED_PARAMETER(Backlog);
-	UNREFERENCED_PARAMETER(ppListen);
+	HRESULT hr;
+	CWVListen *listener;
 
-	return E_NOTIMPL;
+	listener = new CWVListen(this);
+	if (listener == NULL) {
+		hr = WV_NO_MEMORY;
+		goto err1;
+	}
+
+	listener->QueryInterface(IID_IWVListen, (LPVOID*) ppListen);
+	listener->Release();
+
+	hr = listener->Listen(pAddress, Backlog);
+	if (FAILED(hr)) {
+		goto err2;
+	}
+
+	return WV_SUCCESS;
+
+err2:
+	listener->Release();
+err1:
+	*ppListen = NULL;
+	return hr;
 }
Index: core/winverbs/user/wv_provider.h
===================================================================
--- core/winverbs/user/wv_provider.h	(revision 986)
+++ core/winverbs/user/wv_provider.h	(working copy)
@@ -56,16 +56,13 @@
 	STDMETHODIMP CreateListen(const struct sockaddr* pAddress,
 							  SIZE_T backlog, IWVListen** ppListen);
 
-	CWVProvider()
-	{
-		m_nRef = 0;
-		InterlockedIncrement(&WvRef);
-	}
-	~CWVProvider()
-	{
-		InterlockedDecrement(&WvRef);
-	}
-private:
+	CWVProvider();
+	~CWVProvider();
+	STDMETHODIMP Open();
+
+	HANDLE			m_hFile;
+
+protected:
 	volatile LONG m_nRef;
 };
 





More information about the ofw mailing list