[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