[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Refactor Wmi.c


  • To: <win-pv-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Owen Smith <owen.smith@xxxxxxxxxx>
  • Date: Wed, 30 Mar 2022 10:32:23 +0100
  • Authentication-results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none
  • Cc: Owen Smith <owen.smith@xxxxxxxxxx>
  • Delivery-date: Wed, 30 Mar 2022 09:32:39 +0000
  • Ironport-data: A9a23:kRFWEqoKPC4jeecjhqm9mpX8rTxeBmJCZRIvgKrLsJaIsI4StFCzt garIBmGa6yJYGahc491aNzi9E9V6peDnNAwTgNqpSkxEXlE8ZuZCYyVIHmrMnLJJKUvbq7GA +byyDXkBJppJpMJjk71atANlVEliefQAOCU5NfsYkidfyc9IMsaoU8lyrZRbrJA24DjWVvW4 ouq+aUzBXf+s9JKGjNMg068gEsHUMTa4Fv0aXRnOJinFHeH/5UkJMp3yZOZdhMUcaENdgKOf M7RzanRw4/s10xF5uVJMFrMWhZirrb6ZWBig5fNMkSoqkAqSicais7XOBeAAKv+Zvrgc91Zk b1wWZKMpQgBGJ3QpeQBVB5kI3tMAIdb1ueALWq+rpnGp6HGWyOEL/RGCUg3OcsT+/ptAHEI/ vsdQNwPRknd3aTsmuv9E7QywJR4RCXoFNp3VnVIyi7UC7A9RJHfQ43B5MNC3Sd2jcdLdRrbT 5RGNWAxPUueC/FJEmoKKpY0ofasv3/mfjJkpVHWiId0zXeGmWSd15CyaYGIK7RmX/59gUee4 3rYumj0HBweHNie0iaetGKhgPfVmiH2U55UE6e3nsOGm3XKmDZVUkdPEwLm/7/p0SZSRu6zN WQyyjYTrbQ183CbFOvAdQCW+DmIrB8DDo84//IB1CmBza/d4gC8D2cCTyJcZNFOiPLaVQDGx XfSwYq3WGUHXKm9DCvEq+zK9W/a1T09dzdqWMMScecSDzAPSqkXhwmHcNtsGbXdYjbdSWCpm GDiQMTTatwuYS83O0eToAivb9GE/MGhousJCuP/BDjNAuRRPtPNWmBQwQKHhcus1a7AJrV7g FAKmtKF8McFBoyXmSqGTY0lRe/1t6vVamSG2QQ3Q/HNEghBHVb5J+i8BxkkeS9U3jssI2e1M Cc/RysPjHOsAJdaRfAuON/gYyjb5aPhCc7kRpjpgilmOfBMmPu81Hg2Pya4hjm1+GB1yP1XE crLIK6EUCdBYYw6nWXeegvo+eJyrszI7TiIHs6TItXO+ef2WUN5vp9YaQPXNbpotfnsTce82 483CvZmAi53CIXWChQ7O6ZKRbzWBRDX3azLlvE=
  • Ironport-hdrordr: A9a23:aW3sy69RnLXtEh126vBuk+DSI+orL9Y04lQ7vn2YSXRuHfBw8P re+cjztCWE7wr5N0tApTntAsS9qBDnhPxICOsqXYtKNTOO0ADDEGgL1/qH/9SKIUPDH4BmuZ uIC5IOa+HNMQ==
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

* Moves functions to be in related locations in file
* Formats code to appropriate code style
* Inlines some functions that are only called from 1 location
* Uses LIST_ENTRY macros to access linked lists

Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 src/xeniface/wmi.c | 3794 ++++++++++++++++++++++----------------------
 1 file changed, 1907 insertions(+), 1887 deletions(-)

diff --git a/src/xeniface/wmi.c b/src/xeniface/wmi.c
index 1b4c6c6..0d21b92 100644
--- a/src/xeniface/wmi.c
+++ b/src/xeniface/wmi.c
@@ -37,11 +37,11 @@
 #include <stdio.h>
 #include <guiddef.h>
 #define NTSTRSAFE_LIB
-#include<ntstrsafe.h>
+#include <ntstrsafe.h>
 #include "wmi.h"
 #include "driver.h"
-#include "..\..\include\store_interface.h"
-#include "..\..\include\suspend_interface.h"
+#include "store_interface.h"
+#include "suspend_interface.h"
 #include "log.h"
 #include "xeniface_ioctls.h"
 #include <version.h>
@@ -53,6 +53,54 @@
 #define UTF8MASK3 0x1FF800
 #define UTF8MASK4 0x1F0000
 
+typedef enum _WMI_TYPE {
+    WMI_DONE,
+    WMI_STRING,
+    WMI_BOOLEAN,
+    WMI_SINT8,
+    WMI_UINT8,
+    WMI_SINT16,
+    WMI_UINT16,
+    WMI_INT32,
+    WMI_UINT32,
+    WMI_SINT64,
+    WMI_UINT64,
+    WMI_DATETIME,
+    WMI_BUFFER,
+    WMI_OFFSET,
+    WMI_STRINGOFFSET
+} WMI_TYPE;
+
+#define MAX_WATCH_COUNT (MAXIMUM_WAIT_OBJECTS -1)
+
+typedef struct _XENSTORE_SESSION {
+    LIST_ENTRY                  ListEntry;
+    LONG                        SessionId;
+    UNICODE_STRING              StringId;
+    UNICODE_STRING              InstanceName;
+    PXENBUS_STORE_TRANSACTION   Transaction;
+    LIST_ENTRY                  WatchList;
+    int                         WatchCount;
+    PKEVENT                     WatchEvents[MAXIMUM_WAIT_OBJECTS];
+    KWAIT_BLOCK                 WatchWaitBlocks[MAXIMUM_WAIT_OBJECTS];
+    KEVENT                      SessionChangedEvent;
+    XENIFACE_MUTEX              WatchMapLock;
+    BOOLEAN                     Changed;
+    BOOLEAN                     Closing;
+    BOOLEAN                     Suspended;
+    PKTHREAD                    WatchThread;
+} XENSTORE_SESSION, *PXENSTORE_SESSION;
+
+typedef struct _XENSTORE_WATCH {
+    LIST_ENTRY                  ListEntry;
+    UNICODE_STRING              Path;
+    PXENIFACE_FDO               Fdo;
+    ULONG                       SuspendCount;
+    BOOLEAN                     Finished;
+    KEVENT                      WatchEvent;
+    PXENBUS_STORE_WATCH         WatchHandle;
+} XENSTORE_WATCH, *PXENSTORE_WATCH;
+
 static FORCEINLINE PVOID
 WmiAllocate(
     IN  ULONG   Length
@@ -70,19 +118,6 @@ WmiFree(
     __FreePoolWithTag(Buffer, WMI_POOL_TAG);
 }
 
-void LockSessions(
-        XENIFACE_FDO* fdoData)
-{
-    AcquireMutex(&fdoData->SessionLock);
-}
-
-
-void UnlockSessions(
-        XENIFACE_FDO* fdoData)
-{
-    ReleaseMutex(&fdoData->SessionLock);
-}
-
 // Rather inconveniently, xenstore needs UTF8 data, WMI works in UTF16
 // and windows doesn't provide conversion functions in any version
 // prior to Windows 7.
@@ -499,7 +534,7 @@ CloneUnicodeString(
 static NTSTATUS
 GetInstanceName(
     OUT PUNICODE_STRING dest,
-    IN  PXENIFACE_FDO   FdoData,
+    IN  PXENIFACE_FDO   Fdo,
     IN  const CHAR*     string
     )
 {
@@ -513,7 +548,7 @@ GetInstanceName(
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    destsz = FdoData->SuggestedInstanceName.Length +
+    destsz = Fdo->SuggestedInstanceName.Length +
              sizeof(WCHAR) +
              unicode.Length;
 
@@ -524,7 +559,7 @@ GetInstanceName(
 
     status = RtlUnicodeStringPrintf(dest,
                                     L"%s\\%s",
-                                    FdoData->SuggestedInstanceName.Buffer,
+                                    Fdo->SuggestedInstanceName.Buffer,
                                     unicode.Buffer);
     if (!NT_SUCCESS(status))
         goto fail3;
@@ -544,7 +579,7 @@ fail1:
 
 static NTSTATUS
 WriteInstanceName(
-    IN  PXENIFACE_FDO   FdoData,
+    IN  PXENIFACE_FDO   Fdo,
     IN  const CHAR*     string,
     IN  PUCHAR          location
     )
@@ -552,7 +587,7 @@ WriteInstanceName(
     UNICODE_STRING      destination;
     NTSTATUS            status;
 
-    status = GetInstanceName(&destination, FdoData, string);
+    status = GetInstanceName(&destination, Fdo, string);
     if (!NT_SUCCESS(status))
         return status;
 
@@ -561,169 +596,209 @@ WriteInstanceName(
     return STATUS_SUCCESS;
 }
 
-typedef enum {
-    WMI_DONE,
-    WMI_STRING,
-    WMI_BOOLEAN,
-    WMI_SINT8,
-    WMI_UINT8,
-    WMI_SINT16,
-    WMI_UINT16,
-    WMI_INT32,
-    WMI_UINT32,
-    WMI_SINT64,
-    WMI_UINT64,
-    WMI_DATETIME,
-    WMI_BUFFER,
-    WMI_OFFSET,
-    WMI_STRINGOFFSET
-} WMI_TYPE;
+static PSTR
+Xmasprintf(
+    IN  const char* fmt,
+    ...
+    )
+{
+    va_list         argv;
+    PSTR            out;
+    size_t          basesize = 128;
+    size_t          unused;
+    NTSTATUS        status;
+
+    va_start(argv, fmt);
+    do {
+        basesize = basesize * 2;
+        out =  WmiAllocate((ULONG)basesize);
+        if (out == NULL)
+            return NULL;
+
+        status = RtlStringCbVPrintfExA(out, basesize, NULL, &unused, 0, fmt, 
argv);
+
+        WmiFree(out);
+    } while (status != STATUS_SUCCESS);
+
+    out = WmiAllocate((ULONG)(basesize - unused + 1));
+    if (out == NULL)
+        return NULL;
+
+    RtlStringCbVPrintfA(out, basesize - unused + 1, fmt, argv);
+
+    va_end(argv);
+    return out;
+}
+
+static FORCEINLINE VOID
+UnicodeShallowCopy(
+    IN  PUNICODE_STRING     dest,
+    IN  PUNICODE_STRING     src
+    )
+{
+    dest->Buffer = src->Buffer;
+    dest->Length = src->Length;
+    dest->MaximumLength = src->MaximumLength;
+}
+
+static FORCEINLINE int
+CompareUnicodeStrings(
+    IN  PCUNICODE_STRING    string1,
+    IN  PCUNICODE_STRING    string2
+    )
+{
+    if (string1->Length == string2->Length)
+        return RtlCompareMemory(string1->Buffer,
+                                string2->Buffer,
+                                string1->Length) != string1->Length;
+    return 1;
+}
+
+static int
+AccessWmiBuffer(
+    IN  PUCHAR  Buffer,
+    IN  int     readbuffer,
+    OUT ULONG*  RequiredSize,
+    IN  size_t  BufferSize,
+    ...
+    )
+{
+    va_list     vl;
+    ULONG_PTR   offset;
+    ULONG_PTR   offby;
+    PUCHAR      position = Buffer;
+    PUCHAR      endbuffer = Buffer + BufferSize;
+    int         overflow = 0;
 
-int AccessWmiBuffer(PUCHAR Buffer, int readbuffer, ULONG * RequiredSize,
-                    size_t BufferSize, ...) {
-    va_list vl;
-    ULONG_PTR offset;
-    ULONG_PTR offby;
-    PUCHAR position = Buffer;
-    PUCHAR endbuffer = Buffer + BufferSize;
-    int overflow=0;
     va_start(vl, BufferSize);
-    for(;;) {
+    for (;;) {
         WMI_TYPE type = va_arg(vl, WMI_TYPE);
-        if (type != WMI_DONE) {
-#define WMITYPECASE(_wmitype, _type, _align) \
-            case _wmitype: {\
-                _type** val; \
-                offby = ((ULONG_PTR)position)%(_align); \
-                offset = ((_align)-offby)%(_align) ; \
-                position += offset;\
-                if (position + sizeof(_type) > endbuffer) \
-                    overflow = TRUE;\
-                val = va_arg(vl, _type**); \
-                *val = NULL; \
-                if (!overflow) \
-                    *val = (_type *)position; \
-                position += sizeof(_type); } \
-                break
-            switch (type) {
-                case WMI_STRING:
-                    {
-                        UCHAR **countstr;
-                        USHORT strsize;
-                        offset = (2-((ULONG_PTR)position%2))%2;
-                        position+=offset;
-                        if (position + sizeof(USHORT) > endbuffer)
-                            overflow = TRUE;
-                        if (readbuffer) {
-                            if (!overflow)
-                                strsize = *(USHORT*)position;
-                            else
-                                strsize = 0;
-                            strsize+=sizeof(USHORT);
-                        }
-                        else {
-                            strsize = va_arg(vl, USHORT);
-                        }
-                        if (position + strsize  >endbuffer)
-                            overflow = TRUE;
-                        countstr = va_arg(vl, UCHAR**);
-                        *countstr = NULL;
-                        if (!overflow)
-                            *countstr = position;
-                        position +=strsize;
-                    }
-                    break;
-                case WMI_BUFFER:
-                    {
-                        ULONG size = va_arg(vl, ULONG);
-                        UCHAR **buffer;
-                        if (position + size > endbuffer)
-                            overflow = TRUE;
-                        buffer = va_arg(vl, UCHAR**);
-                        *buffer = NULL;
-                        if (!overflow)
-                            *buffer = position;
-                        position += size;
-                    }
-                    break;
-                case WMI_OFFSET:
-                    {
-                        ULONG inpos = va_arg(vl, ULONG);
-                        UCHAR *bufferpos = Buffer + inpos;
-                        ULONG insize = va_arg(vl, ULONG);
-                        UCHAR **writebuf = va_arg(vl, UCHAR**);
-                        *writebuf = NULL;
-                        if (bufferpos+ insize > endbuffer) {;
-                            overflow = TRUE;
-                        }
-                        else {
-                            *writebuf = bufferpos;
-                        }
-                        // Only update position if it extends
-                        // the required size of the buffer
-                        if (bufferpos+insize > position)
-                            position = bufferpos+insize;
-                    }
-                    break;
-                    case WMI_STRINGOFFSET:
-                    {
-                        UCHAR **countstr;
-                        USHORT strsize;
-                        ULONG inpos = va_arg(vl, ULONG);
-                        UCHAR *bufferpos = Buffer + inpos;
-                        if (bufferpos + sizeof(USHORT) > endbuffer)
-                            overflow = TRUE;
-                        if (readbuffer) {
-                            if (!overflow)
-                                strsize = *(USHORT*)bufferpos;
-                            else
-                                strsize = 0;
-                            strsize+=sizeof(USHORT);
-                        }
-                        else {
-                            strsize = va_arg(vl, USHORT);
-                        }
-                        if (bufferpos + strsize  >endbuffer)
-                            overflow = TRUE;
-                        countstr = va_arg(vl, UCHAR**);
-                        *countstr = NULL;
-                        if (!overflow)
-                            *countstr = bufferpos;
-                        if (bufferpos+strsize > position)
-                            position =bufferpos+strsize;
-                    }
-                    break;
-                WMITYPECASE(WMI_BOOLEAN, UCHAR, 1);
-                WMITYPECASE(WMI_SINT8, CHAR, 1);
-                WMITYPECASE(WMI_UINT8, UCHAR, 1);
-                WMITYPECASE(WMI_SINT16, SHORT, 2);
-                WMITYPECASE(WMI_UINT16, USHORT, 2);
-                WMITYPECASE(WMI_INT32, LONG, 4);
-                WMITYPECASE(WMI_UINT32, ULONG, 4);
-                WMITYPECASE(WMI_SINT64, LONGLONG, 8);
-                WMITYPECASE(WMI_UINT64, ULONGLONG, 8);
-                case WMI_DATETIME:
-                    {
-                        LPWSTR *val;
-                        offset = (2-((ULONG_PTR)position%2))%2;
-                        position += offset;
-                        if (position + sizeof(WCHAR)*25 > endbuffer)
-                            overflow = TRUE;
-                        val = va_arg(vl, LPWSTR*);
-                        *val = NULL;
-                        if (!overflow)
-                            *val = (LPWSTR )position;
-                        position += sizeof(WCHAR)*25;
-                    }
-                    break;
-                default:
-                    return FALSE;
-            }
-        }
-        else {
+        if (type == WMI_DONE)
             break;
+
+#define WMITYPECASE(_wmitype, _type, _align)            \
+        case _wmitype: {                                \
+            _type** val;                                \
+            offby = ((ULONG_PTR)position) % (_align);   \
+            offset = ((_align) - offby) % (_align);     \
+            position += offset;                         \
+            if (position + sizeof(_type) > endbuffer)   \
+                overflow = TRUE;                        \
+            val = va_arg(vl, _type**);                  \
+            *val = NULL;                                \
+            if (!overflow)                              \
+                *val = (_type *)position;               \
+            position += sizeof(_type);                  \
+        } break
+
+        switch (type) {
+        WMITYPECASE(WMI_BOOLEAN, UCHAR, 1);
+        WMITYPECASE(WMI_SINT8, CHAR, 1);
+        WMITYPECASE(WMI_UINT8, UCHAR, 1);
+        WMITYPECASE(WMI_SINT16, SHORT, 2);
+        WMITYPECASE(WMI_UINT16, USHORT, 2);
+        WMITYPECASE(WMI_INT32, LONG, 4);
+        WMITYPECASE(WMI_UINT32, ULONG, 4);
+        WMITYPECASE(WMI_SINT64, LONGLONG, 8);
+        WMITYPECASE(WMI_UINT64, ULONGLONG, 8);
+
+        case WMI_STRING: {
+            UCHAR** countstr;
+            USHORT  strsize;
+            offset = (2 - ((ULONG_PTR)position % 2)) % 2;
+            position += offset;
+            if (position + sizeof(USHORT) > endbuffer)
+                overflow = TRUE;
+            if (readbuffer) {
+                if (!overflow)
+                    strsize = *(USHORT*)position;
+                else
+                    strsize = 0;
+                strsize += sizeof(USHORT);
+            } else {
+                strsize = va_arg(vl, USHORT);
+            }
+            if (position + strsize > endbuffer)
+                overflow = TRUE;
+            countstr = va_arg(vl, UCHAR**);
+            *countstr = NULL;
+            if (!overflow)
+                *countstr = position;
+            position += strsize;
+        } break;
+
+        case WMI_BUFFER: {
+            ULONG   size = va_arg(vl, ULONG);
+            UCHAR** buffer;
+            if (position + size > endbuffer)
+                overflow = TRUE;
+            buffer = va_arg(vl, UCHAR**);
+            *buffer = NULL;
+            if (!overflow)
+                *buffer = position;
+            position += size;
+        } break;
+
+        case WMI_OFFSET: {
+            ULONG   inpos = va_arg(vl, ULONG);
+            UCHAR*  bufferpos = Buffer + inpos;
+            ULONG   insize = va_arg(vl, ULONG);
+            UCHAR** writebuf = va_arg(vl, UCHAR**);
+            *writebuf = NULL;
+            if (bufferpos + insize > endbuffer)
+                overflow = TRUE;
+            else
+                *writebuf = bufferpos;
+            // Only update position if it extends
+            // the required size of the buffer
+            if (bufferpos + insize > position)
+                position = bufferpos + insize;
+        } break;
+
+        case WMI_STRINGOFFSET: {
+            UCHAR** countstr;
+            USHORT  strsize;
+            ULONG   inpos = va_arg(vl, ULONG);
+            UCHAR*  bufferpos = Buffer + inpos;
+            if (bufferpos + sizeof(USHORT) > endbuffer)
+                overflow = TRUE;
+            if (readbuffer) {
+                if (!overflow)
+                    strsize = *(USHORT*)bufferpos;
+                else
+                    strsize = 0;
+                strsize += sizeof(USHORT);
+            } else {
+                strsize = va_arg(vl, USHORT);
+            }
+            if (bufferpos + strsize > endbuffer)
+                overflow = TRUE;
+            countstr = va_arg(vl, UCHAR**);
+            *countstr = NULL;
+            if (!overflow)
+                *countstr = bufferpos;
+            if (bufferpos + strsize > position)
+                position = bufferpos + strsize;
+        } break;
+
+        case WMI_DATETIME: {
+            LPWSTR* val;
+            offset = (2 - ((ULONG_PTR)position % 2)) % 2;
+            position += offset;
+            if (position + sizeof(WCHAR) * 25 > endbuffer)
+                overflow = TRUE;
+            val = va_arg(vl, LPWSTR*);
+            *val = NULL;
+            if (!overflow)
+                *val = (LPWSTR)position;
+            position += sizeof(WCHAR) * 25;
+        } break;
+
+        default:
+            return FALSE;
         }
     }
+
     *RequiredSize = (ULONG)(position - Buffer);
     va_end(vl);
     if (overflow)
@@ -731,1086 +806,922 @@ int AccessWmiBuffer(PUCHAR Buffer, int readbuffer, 
ULONG * RequiredSize,
     return TRUE;
 }
 
-#define MAX_WATCH_COUNT (MAXIMUM_WAIT_OBJECTS -1)
+static FORCEINLINE PXENSTORE_SESSION
+FindSessionLocked(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  LONG            Id
+    )
+{
+    PLIST_ENTRY         ListEntry;
+    PXENSTORE_SESSION   Session;
 
-typedef struct _XenStoreSession {
-    LIST_ENTRY listentry;
-    LONG id;
-    UNICODE_STRING stringid;
-    UNICODE_STRING instancename;
-    PXENBUS_STORE_TRANSACTION transaction;
-    LIST_ENTRY watches;
-    int watchcount;
-    KEVENT* watchevents[MAXIMUM_WAIT_OBJECTS];
-    KWAIT_BLOCK watchwaitblockarray[MAXIMUM_WAIT_OBJECTS];
-    KEVENT SessionChangedEvent;
-    XENIFACE_MUTEX WatchMapLock;
-    BOOLEAN mapchanged;
-    BOOLEAN closing;
-    BOOLEAN suspended;
-    PKTHREAD WatchThread;
-} XenStoreSession;
-
-typedef struct _XenStoreWatch {
-    LIST_ENTRY listentry;
-    UNICODE_STRING path;
-    XENIFACE_FDO *fdoData;
-
-    ULONG   suspendcount;
-    BOOLEAN finished;
-    KEVENT watchevent;
-    PXENBUS_STORE_WATCH watchhandle;
-
-} XenStoreWatch;
-
-void UnicodeShallowCopy(UNICODE_STRING *dest, UNICODE_STRING *src) {
-    dest->Buffer = src->Buffer;
-    dest->Length = src->Length;
-    dest->MaximumLength = src->MaximumLength;
-}
+    ASSERT3P(Fdo->SessionLock.Owner, ==, KeGetCurrentThread());
 
+    for (ListEntry = Fdo->SessionHead.Flink;
+         ListEntry != &Fdo->SessionHead;
+         ListEntry = ListEntry->Flink) {
+        Session = CONTAINING_RECORD(ListEntry, XENSTORE_SESSION, ListEntry);
 
-XenStoreSession*
-FindSessionLocked(XENIFACE_FDO *fdoData,
-                                LONG id) {
-    XenStoreSession *session;
+        if (Session->SessionId != Id)
+            continue;
 
-    session = (XenStoreSession *)fdoData->SessionHead.Flink;
-    while (session != (XenStoreSession *)&fdoData->SessionHead){
-        if (session->id == id) {
-            if (session->suspended)
-                return NULL;
-            return session;
-        }
-        session = (XenStoreSession *)session->listentry.Flink;
+        return Session->Suspended ? NULL : Session;
     }
     return NULL;
 }
 
+static FORCEINLINE PXENSTORE_WATCH
+SessionFindWatchLocked(
+    IN  PXENSTORE_SESSION   Session,
+    IN  PUNICODE_STRING     Path
+    )
+{
+    PLIST_ENTRY             ListEntry;
+    PXENSTORE_WATCH         Watch;
 
-int CompareUnicodeStrings(PCUNICODE_STRING string1, PCUNICODE_STRING string2) {
-    if (string1->Length == string2->Length) {
-        return RtlCompareMemory(string1->Buffer,string2->Buffer, 
string1->Length) != string1->Length;
-    }
-    return 1;
-
-}
-
-XenStoreWatch *
-SessionFindWatchLocked(XenStoreSession *session,
-                        UNICODE_STRING *path) {
-    XenStoreWatch * watch;
+    ASSERT3P(Session->WatchMapLock.Owner, ==, KeGetCurrentThread());
 
-    Trace("Wait for session watch lock\n");
-    AcquireMutex(&session->WatchMapLock);
-    Trace("got session watch lock\n");
-    watch = (XenStoreWatch *)session->watches.Flink;
+    for (ListEntry = Session->WatchList.Flink;
+         ListEntry != &Session->WatchList;
+         ListEntry = ListEntry->Flink) {
+        Watch = CONTAINING_RECORD(ListEntry, XENSTORE_WATCH, ListEntry);
 
-    while (watch != (XenStoreWatch *)&session->watches){
-        if (CompareUnicodeStrings(path, &watch->path)==0) {
-            return watch;
-        }
-        watch = (XenStoreWatch *)watch->listentry.Flink;
+        if (CompareUnicodeStrings(Path, &Watch->Path) == 0)
+            return Watch;
     }
-
-    Warning("couldn't find watch\n");
     return NULL;
-
 }
 
-VOID
-WmiFireSuspendEvent(
-    IN  PXENIFACE_FDO   Fdo
+static VOID
+FireWatch(
+    IN  PXENSTORE_WATCH Watch
     )
 {
-    Info("Ready to unsuspend Event\n");
-    KeSetEvent(&Fdo->registryWriteEvent, IO_NO_INCREMENT, FALSE);
-
-    if (!Fdo->WmiReady)
-        return;
-
-    Trace("Fire Suspend Event\n");
-    WmiFireEvent(Fdo->Dx->DeviceObject,
-                 (LPGUID)&OBJECT_GUID(XenStoreUnsuspendedEvent),
-                 0,
-                 0,
-                 NULL);
-}
-
-void FireWatch(XenStoreWatch* watch) {
-    UCHAR * eventdata;
-    ULONG RequiredSize;
-    UCHAR *sesbuf;
+    UCHAR*              eventdata;
+    ULONG               RequiredSize;
+    UCHAR*              sesbuf;
 
-    (VOID) AccessWmiBuffer(0, FALSE, &RequiredSize, 0,
-            WMI_STRING, GetCountedUnicodeStringSize(&watch->path),
-                &sesbuf,
+    (VOID) AccessWmiBuffer(NULL, FALSE, &RequiredSize, 0,
+            WMI_STRING, GetCountedUnicodeStringSize(&Watch->Path), &sesbuf,
             WMI_DONE);
 
     eventdata = WmiAllocate(RequiredSize);
-    if (eventdata!=NULL) {
-        (VOID) AccessWmiBuffer(eventdata, FALSE, &RequiredSize, RequiredSize,
-            WMI_STRING, GetCountedUnicodeStringSize(&watch->path),
-                &sesbuf,
+    if (eventdata == NULL)
+        return;
+
+    (VOID) AccessWmiBuffer(eventdata, FALSE, &RequiredSize, RequiredSize,
+            WMI_STRING, GetCountedUnicodeStringSize(&Watch->Path), &sesbuf,
             WMI_DONE);
 
-        WriteCountedUnicodeString(&watch->path, sesbuf);
-    }
+    WriteCountedUnicodeString(&Watch->Path, sesbuf);
 
-    if (eventdata !=NULL) {
-        Trace("Fire Watch Event\n");
-        WmiFireEvent(watch->fdoData->Dx->DeviceObject,
-                     (LPGUID)&OBJECT_GUID(XenStoreWatchEvent),
-                     0,
-                     RequiredSize,
-                     eventdata);
-    }
+    Trace("Fire Watch Event\n");
+    WmiFireEvent(Watch->Fdo->Dx->DeviceObject,
+                 (LPGUID)&OBJECT_GUID(XenStoreWatchEvent),
+                 0,
+                 RequiredSize,
+                 eventdata);
 }
 
-
 KSTART_ROUTINE WatchCallbackThread;
-NTSTATUS
-StartWatch(XENIFACE_FDO *fdoData, XenStoreWatch *watch)
+
+static NTSTATUS
+StartWatch(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  PXENSTORE_WATCH Watch
+    )
 {
-    char *tmppath;
-    ANSI_STRING ansipath;
-    NTSTATUS status;
-    status = RtlUnicodeStringToAnsiString(&ansipath, &watch->path, TRUE);
-    if (!NT_SUCCESS(status)) {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
+    char*               tmppath;
+    ANSI_STRING         ansipath;
+    NTSTATUS            status;
+
+    status = RtlUnicodeStringToAnsiString(&ansipath, &Watch->Path, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
     tmppath = WmiAllocate(ansipath.Length + 1);
-    if (!tmppath) {
-        RtlFreeAnsiString(&ansipath);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (tmppath == NULL)
+        goto fail2;
 
-    RtlCopyBytes(tmppath,ansipath.Buffer, ansipath.Length);
+    RtlCopyBytes(tmppath, ansipath.Buffer, ansipath.Length);
 
-    status = XENBUS_STORE(WatchAdd, &fdoData->StoreInterface, NULL, tmppath, 
&watch->watchevent, &watch->watchhandle );
-    if (!NT_SUCCESS(status)) {
-        WmiFree(tmppath);
-        RtlFreeAnsiString(&ansipath);
-        return status;
-    }
+    status = XENBUS_STORE(WatchAdd,
+                          &Fdo->StoreInterface,
+                          NULL,
+                          tmppath,
+                          &Watch->WatchEvent,
+                          &Watch->WatchHandle);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
-    Info("Start Watch %p\n", watch->watchhandle);
+    Info("Start Watch %p\n", Watch->WatchHandle);
 
     WmiFree(tmppath);
     RtlFreeAnsiString(&ansipath);
 
     return STATUS_SUCCESS;
-}
-
 
-VOID WatchCallbackThread(__in PVOID StartContext) {
-    NTSTATUS status;
-    int i=0;
-    XenStoreSession * session = (XenStoreSession*) StartContext;
+fail3:
+    WmiFree(tmppath);
+fail2:
+    RtlFreeAnsiString(&ansipath);
+fail1:
+    return status;
+}
 
-    for(;;) {
-        AcquireMutex(&session->WatchMapLock);
-        if (session->mapchanged) {
+VOID
+WatchCallbackThread(
+    __in PVOID          StartContext
+    )
+{
+    NTSTATUS            status;
+    PLIST_ENTRY         ListEntry;
+    PXENSTORE_WATCH     Watch;
+    PXENSTORE_SESSION   Session = (PXENSTORE_SESSION)StartContext;
+    int                 Count = 0;
+
+    for (;;) {
+        AcquireMutex(&Session->WatchMapLock);
+        if (Session->Changed) {
             // Construct a new mapping
-            XenStoreWatch *watch;
             Trace("Construct a new mapping\n");
-            watch = (XenStoreWatch *)session->watches.Flink;
-            for (i=0; watch != (XenStoreWatch *)&session->watches; i++) {
-                session->watchevents[i] = &watch->watchevent;
-                watch = (XenStoreWatch *)watch->listentry.Flink;
+            for (Count = 0, ListEntry = Session->WatchList.Flink;
+                 ListEntry != &Session->WatchList;
+                 Count++, ListEntry = ListEntry->Flink) {
+                Watch = CONTAINING_RECORD(ListEntry, XENSTORE_WATCH, 
ListEntry);
+
+                Session->WatchEvents[Count] = &Watch->WatchEvent;
             }
-            session->mapchanged = FALSE;
-            session->watchevents[i] = &session->SessionChangedEvent;
+            Session->WatchEvents[Count] = &Session->SessionChangedEvent;
+            Session->Changed = FALSE;
         }
-        ReleaseMutex(&session->WatchMapLock);
+        ReleaseMutex(&Session->WatchMapLock);
+
         Trace("Wait for new event\n");
-        status = KeWaitForMultipleObjects(i+1, session->watchevents, WaitAny, 
Executive, KernelMode, TRUE, NULL, session->watchwaitblockarray);
+        status = KeWaitForMultipleObjects(Count + 1,
+                                          Session->WatchEvents,
+                                          WaitAny,
+                                          Executive,
+                                          KernelMode,
+                                          TRUE,
+                                          NULL,
+                                          Session->WatchWaitBlocks);
         Trace("got new event\n");
-        if ((status >= STATUS_WAIT_0) && (status < STATUS_WAIT_0 +i )) {
-            XenStoreWatch *watch;
+
+        if ((status >= STATUS_WAIT_0) && (status < STATUS_WAIT_0 + Count)) {
             Trace("watch or suspend\n");
-            watch = 
CONTAINING_RECORD(session->watchevents[status-STATUS_WAIT_0], XenStoreWatch, 
watchevent );
-            AcquireMutex(&session->WatchMapLock);
-            KeClearEvent(&watch->watchevent);
-
-
-            if (watch->finished) {
-                FreeUnicodeStringBuffer(&watch->path);
-                RemoveEntryList((LIST_ENTRY*)watch);
-                WmiFree(watch);
-                session->mapchanged = TRUE;
-                session->watchcount --;
-            } else if (!session->suspended &&
-                       watch->suspendcount != XENBUS_SUSPEND(GetCount, 
&watch->fdoData->SuspendInterface)) {
-                watch->suspendcount = XENBUS_SUSPEND(GetCount, 
&watch->fdoData->SuspendInterface);
-                Info("SessionSuspendResumeUnwatch %p\n", watch->watchhandle);
-
-                XENBUS_STORE(WatchRemove, &watch->fdoData->StoreInterface, 
watch->watchhandle);
-                watch->watchhandle = NULL;
-                StartWatch(watch->fdoData, watch);
+            Watch = CONTAINING_RECORD(Session->WatchEvents[status - 
STATUS_WAIT_0],
+                                      XENSTORE_WATCH,
+                                      WatchEvent);
+
+            AcquireMutex(&Session->WatchMapLock);
+            KeClearEvent(&Watch->WatchEvent);
+
+            if (Watch->Finished) {
+                FreeUnicodeStringBuffer(&Watch->Path);
+                RemoveEntryList(&Watch->ListEntry);
+                WmiFree(Watch);
+
+                Session->Changed = TRUE;
+                Session->WatchCount--;
+            } else if (!Session->Suspended &&
+                       Watch->SuspendCount != XENBUS_SUSPEND(GetCount, 
&Watch->Fdo->SuspendInterface)) {
+                Watch->SuspendCount = XENBUS_SUSPEND(GetCount, 
&Watch->Fdo->SuspendInterface);
+                Info("SessionSuspendResumeUnwatch %p\n", Watch->WatchHandle);
+
+                XENBUS_STORE(WatchRemove, &Watch->Fdo->StoreInterface, 
Watch->WatchHandle);
+                Watch->WatchHandle = NULL;
+                StartWatch(Watch->Fdo, Watch);
             } else {
-                FireWatch(watch);
+                FireWatch(Watch);
             }
-            ReleaseMutex(&session->WatchMapLock);
-        }
-        else if ( status == STATUS_WAIT_0 + i) {
-            AcquireMutex(&session->WatchMapLock);
-            KeClearEvent(&session->SessionChangedEvent);
-            if (session->closing==TRUE) {
+
+            ReleaseMutex(&Session->WatchMapLock);
+        } else if (status == STATUS_WAIT_0 + Count) {
+            AcquireMutex(&Session->WatchMapLock);
+            KeClearEvent(&Session->SessionChangedEvent);
+            if (Session->Closing) {
                 Trace("Trying to end session thread\n");
-                if (session->watchcount != 0) {
-                    XenStoreWatch *watch;
-                    for (watch = (XenStoreWatch *)session->watches.Flink;
-                        watch!=(XenStoreWatch *)&session->watches;
-                        watch=(XenStoreWatch *)session->watches.Flink) {
-                            FreeUnicodeStringBuffer(&watch->path);
-                            RemoveEntryList((LIST_ENTRY*)watch);
-                            WmiFree(watch);
-                            session->mapchanged = TRUE;
-                            session->watchcount --;
-                    }
+                while (!IsListEmpty(&Session->WatchList)) {
+                    ListEntry = RemoveHeadList(&Session->WatchList);
+                    ASSERT(ListEntry != &Session->WatchList);
+
+                    Session->WatchCount--;
+                    Session->Changed = TRUE;
+
+                    Watch = CONTAINING_RECORD(ListEntry, XENSTORE_WATCH, 
ListEntry);
+
+                    FreeUnicodeStringBuffer(&Watch->Path);
+                    WmiFree(Watch);
                 }
-                ReleaseMutex(&session->WatchMapLock);
+                ReleaseMutex(&Session->WatchMapLock);
+
                 Trace("Ending session thread\n");
                 PsTerminateSystemThread(STATUS_SUCCESS);
-                //ReleaseMutex(&session->WatchMapLock);
-            }
-            else {
-
-                ReleaseMutex(&session->WatchMapLock);
+            } else {
+                ReleaseMutex(&Session->WatchMapLock);
             }
         }
-
     }
 }
 
-NTSTATUS
-SessionAddWatchLocked(XenStoreSession *session,
-                        XENIFACE_FDO* fdoData,
-                        UNICODE_STRING *path,
-                        XenStoreWatch **watch) {
-
-
-    NTSTATUS status;
-    XenStoreWatch *pwatch;
-
-    if (session->watchcount >= MAX_WATCH_COUNT) {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    *watch = WmiAllocate(sizeof(XenStoreWatch));
-    if (*watch == NULL)
-        return STATUS_INSUFFICIENT_RESOURCES;
-
-    (*watch)->finished = FALSE;
-    (*watch)->fdoData = fdoData;
-    UnicodeShallowCopy(&(*watch)->path, path);
-
+static NTSTATUS
+SessionAddWatchLocked(
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PXENSTORE_SESSION   Session,
+    IN  PUNICODE_STRING     Path
+    )
+{
+    PXENSTORE_WATCH         Watch;
+    NTSTATUS                status;
 
+    ASSERT3P(Session->WatchMapLock.Owner, ==, KeGetCurrentThread());
 
-    (*watch)->suspendcount = XENBUS_SUSPEND(GetCount, 
&fdoData->SuspendInterface);
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (Session->WatchCount >= MAX_WATCH_COUNT)
+        goto fail1;
 
+    Watch = WmiAllocate(sizeof(XENSTORE_WATCH));
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (Watch == NULL)
+        goto fail2;
 
-    KeInitializeEvent(&(*watch)->watchevent, NotificationEvent, FALSE);
+    Watch->Finished = FALSE;
+    Watch->Fdo = Fdo;
+    Watch->SuspendCount = XENBUS_SUSPEND(GetCount, &Fdo->SuspendInterface);
 
+    UnicodeShallowCopy(&Watch->Path, Path);
+    KeInitializeEvent(&Watch->WatchEvent, NotificationEvent, FALSE);
 
-    status = StartWatch(fdoData, *watch);
-    if ((!NT_SUCCESS(status)) || ((*watch)->watchhandle == NULL)) {
-        WmiFree(*watch);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
+    status = StartWatch(Fdo, Watch);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
-    AcquireMutex(&session->WatchMapLock);
-    session->mapchanged = TRUE;
-    KeSetEvent(&session->SessionChangedEvent, IO_NO_INCREMENT,FALSE);
-    session->watchcount++;
-    InsertHeadList(&session->watches,(PLIST_ENTRY)(*watch));
+    ASSERT(Watch->WatchHandle != NULL);
 
-    Trace("WATCHLIST for session %p-----------\n", session);
-    pwatch = (XenStoreWatch *)session->watches.Flink;
+    Session->WatchCount++;
+    InsertHeadList(&Session->WatchList, &Watch->ListEntry);
 
-    while (pwatch != (XenStoreWatch *)&session->watches){
-        Trace("WATCHLIST %p\n", pwatch->watchhandle);
-        pwatch = (XenStoreWatch *)pwatch->listentry.Flink;
-    }
-    Trace("WATCHLIST-------------------\n");
+    Session->Changed = TRUE;
+    KeSetEvent(&Session->SessionChangedEvent, IO_NO_INCREMENT,FALSE);
 
-    ReleaseMutex(&session->WatchMapLock);
     return STATUS_SUCCESS;
 
+fail3:
+    WmiFree(Watch);
+fail2:
+fail1:
+    return status;
 }
 
-void SessionRemoveWatchLocked(XenStoreSession *session, XenStoreWatch *watch) {
-
-    XenStoreWatch *pwatch;
-    Trace("Remove watch locked\n");
-    Trace("watch %p\n", watch);
-    Trace("handle %p\n", watch->watchhandle);
+static VOID
+SessionRemoveWatchLocked(
+    IN  PXENSTORE_WATCH     Watch
+    )
+{
+    // ASSERT3P(Session->WatchMapLock.Owner, ==, KeGetCurrentThread());
 
-    if (watch->watchhandle) {
-        XENBUS_STORE(WatchRemove, &watch->fdoData->StoreInterface, 
watch->watchhandle);
-        watch->watchhandle=NULL;
-        watch->finished = TRUE;
-        Trace("WATCHLIST for session %p-----------\n", session);
-    pwatch = (XenStoreWatch *)session->watches.Flink;
+    if (Watch->WatchHandle)
+        XENBUS_STORE(WatchRemove, &Watch->Fdo->StoreInterface, 
Watch->WatchHandle);
+    Watch->WatchHandle = NULL;
 
-    while (pwatch != (XenStoreWatch *)&session->watches){
-        Trace("WATCHLIST %p\n", pwatch->watchhandle);
-        pwatch = (XenStoreWatch *)pwatch->listentry.Flink;
-    }
-    Trace("WATCHLIST-------------------\n");
-        KeSetEvent(&watch->watchevent, IO_NO_INCREMENT,FALSE);
-    }
+    Watch->Finished = TRUE;
 
+    KeSetEvent(&Watch->WatchEvent, IO_NO_INCREMENT,FALSE);
 }
 
-void SessionRemoveWatchesLocked(XenStoreSession *session) {
-    XenStoreWatch *watch;
-
-    Trace("wait remove mutex\n");
-    AcquireMutex(&session->WatchMapLock);
-    for (watch = (XenStoreWatch *)session->watches.Flink;
-         watch!=(XenStoreWatch *)&session->watches;
-         watch=(XenStoreWatch *)watch->listentry.Flink) {
+static PXENSTORE_SESSION
+FindSessionByInstanceLocked(
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PUNICODE_STRING     Instance
+    )
+{
+    PLIST_ENTRY             ListEntry;
+    PXENSTORE_SESSION       Session;
 
-        Trace("try remove %p\n", session->watches.Flink);
-        SessionRemoveWatchLocked(session, watch);
-    }
-    Trace("release remove mutex\n");
-    ReleaseMutex(&session->WatchMapLock);
-}
+    ASSERT3P(Fdo->SessionLock.Owner, ==, KeGetCurrentThread());
 
+    for (ListEntry = Fdo->SessionHead.Flink;
+         ListEntry != &Fdo->SessionHead;
+         ListEntry = ListEntry->Flink) {
+        Session = CONTAINING_RECORD(ListEntry, XENSTORE_SESSION, ListEntry);
 
-XenStoreSession*
-FindSessionByInstanceLocked(XENIFACE_FDO *fdoData,
-                            UNICODE_STRING *instance) {
-    XenStoreSession *session;
+        if (CompareUnicodeStrings(Instance, &Session->InstanceName) != 0)
+            continue;
 
-    session = (XenStoreSession *)fdoData->SessionHead.Flink;
-    while (session != (XenStoreSession *)&fdoData->SessionHead) {
-        if (CompareUnicodeStrings(instance, &session->instancename)==0) {
-            if (session->suspended)
-                return NULL;
-            return session;
-        }
-        session = (XenStoreSession *)session->listentry.Flink;
+        return Session->Suspended ? NULL : Session;
     }
     return NULL;
 }
 
-
 __checkReturn
-__success(return!=NULL)
-XenStoreSession *
-FindSessionByInstanceAndLock(XENIFACE_FDO *fdoData,
-                                UNICODE_STRING *instance) {
-    XenStoreSession *session;
-    LockSessions(fdoData);
-    session = FindSessionByInstanceLocked(fdoData, instance);
-    if (session == NULL) {
-         UnlockSessions(fdoData);
-    }
-    return session;
+__success(return != NULL)
+static PXENSTORE_SESSION
+FindSessionByInstanceAndLock(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  PUNICODE_STRING Instance
+    )
+{
+    PXENSTORE_SESSION   Session;
+
+    AcquireMutex(&Fdo->SessionLock);
+    Session = FindSessionByInstanceLocked(Fdo, Instance);
+    if (Session == NULL)
+         ReleaseMutex(&Fdo->SessionLock);
+    return Session;
 }
 
-PSTR Xmasprintf(const char *fmt, ...) {
-    va_list argv;
-    PSTR out;
-    size_t basesize = 128;
-    size_t unused;
-    NTSTATUS status;
-    va_start(argv, fmt);
-    do{
-        basesize = basesize * 2;
-        out =  WmiAllocate((ULONG)basesize);
-        if (out == NULL)
-            return NULL;
+static NTSTATUS
+SessionCreate(
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PUNICODE_STRING     StringId,
+    OUT ULONG*              SessionId
+    )
+{
+    PXENSTORE_SESSION       Session;
+    PSTR                    iname;
+    NTSTATUS                status;
+    ANSI_STRING             ansi;
+    HANDLE                  hthread;
+    OBJECT_ATTRIBUTES       oa;
+    int                     count = 0;
 
-        status = RtlStringCbVPrintfExA(out, basesize, NULL, &unused,0, fmt, 
argv);
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (Fdo->Sessions == MAX_SESSIONS)
+        goto fail1;
 
-        WmiFree(out);
-    }while (status != STATUS_SUCCESS);
+    Session = WmiAllocate(sizeof(XENSTORE_SESSION));
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (Session == NULL)
+        goto fail2;
 
-    out = WmiAllocate((ULONG)(basesize - unused + 1));
-    if (out == NULL)
-        return NULL;
+    status = RtlUnicodeStringToAnsiString(&ansi, StringId, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
-    RtlStringCbVPrintfA(out, basesize-unused+1, fmt, argv);
+    InitializeMutex(&Session->WatchMapLock);
+    Session->Changed = TRUE;
 
-    va_end(argv);
-    return out;
-}
-
-NTSTATUS
-CreateNewSession(XENIFACE_FDO *fdoData,
-                    UNICODE_STRING *stringid,
-                    ULONG *sessionid) {
-    XenStoreSession *session;
-    PSTR iname;
-    NTSTATUS status;
-    ANSI_STRING ansi;
-    HANDLE hthread;
-    int count = 0;
-    OBJECT_ATTRIBUTES oa;
-    if (fdoData->Sessions == MAX_SESSIONS) {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-    session = WmiAllocate(sizeof(XenStoreSession));
-    if (session == NULL)
-        return STATUS_INSUFFICIENT_RESOURCES;
-
-    InitializeMutex(&session->WatchMapLock);
-    session->mapchanged = TRUE;
-    status = RtlUnicodeStringToAnsiString(&ansi, stringid, TRUE);
-    if (!NT_SUCCESS(status)) {
-        WmiFree(session);
-        return status;
-    }
-    LockSessions(fdoData);
-    do {
-        FreeUnicodeStringBuffer(&session->instancename);
-        iname = Xmasprintf("Session_%s_%d", ansi.Buffer, count);
+    AcquireMutex(&Fdo->SessionLock);
+    do {
+        FreeUnicodeStringBuffer(&Session->InstanceName);
+        iname = Xmasprintf("Session_%s_%d", ansi.Buffer, count);
 
         status = STATUS_NO_MEMORY;
-        if (iname == NULL) {
-            UnlockSessions(fdoData);
-            RtlFreeAnsiString(&ansi);
-            WmiFree(session);
-            return status;
-        }
+        if (iname == NULL)
+            goto fail4;
 
-        status = GetInstanceName(&session->instancename ,fdoData,iname);
+        status = GetInstanceName(&Session->InstanceName, Fdo, iname);
         WmiFree(iname);
-        if (!NT_SUCCESS(status)) {
-            UnlockSessions(fdoData);
-            RtlFreeAnsiString(&ansi);
-            WmiFree(session);
-            return status;
-        }
-        count++;
-
-    } while (FindSessionByInstanceLocked(fdoData, &session->instancename) != 
NULL);
-
+        if (!NT_SUCCESS(status))
+            goto fail5;
 
+        count++;
+    } while (FindSessionByInstanceLocked(Fdo, &Session->InstanceName) != NULL);
 
+    if (IsListEmpty(&Fdo->SessionHead)) {
+        Session->SessionId = 0;
+    } else {
+        Session->SessionId = 
((PXENSTORE_SESSION)(Fdo->SessionHead.Flink))->SessionId + 1;
+        while (FindSessionLocked(Fdo, Session->SessionId))
+            Session->SessionId = (Session->SessionId + 1) % MAX_SESSIONS;
+    }
 
+    Session->Closing = FALSE;
+    Session->Transaction = NULL;
 
-    if (fdoData->SessionHead.Flink==&fdoData->SessionHead) {
-        session->id=0;
-    }
-    else {
-        session->id =((XenStoreSession*)(fdoData->SessionHead.Flink))->id+1;
-        while (FindSessionLocked(fdoData, session->id))
-            session->id = (session->id + 1) % MAX_SESSIONS;
-    }
-    session->transaction=NULL;
-    InsertHeadList((PLIST_ENTRY)&fdoData->SessionHead, (PLIST_ENTRY)session);
-    *sessionid = session->id;
-    UnicodeShallowCopy(&session->stringid, stringid);
+    *SessionId = Session->SessionId;
 
-    InitializeListHead((PLIST_ENTRY)&session->watches);
+    UnicodeShallowCopy(&Session->StringId, StringId);
+    InitializeListHead(&Session->WatchList);
+    KeInitializeEvent(&Session->SessionChangedEvent, NotificationEvent, FALSE);
 
-    KeInitializeEvent(&session->SessionChangedEvent, NotificationEvent, FALSE);
-    session->closing = FALSE;
-    if (fdoData->InterfacesAcquired){
+    if (Fdo->InterfacesAcquired){
         Trace("Add session unsuspended\n");
-        session->suspended=FALSE;
-    }
-    else {
+        Session->Suspended = FALSE;
+    } else {
         Trace("Add session suspended\n");
-        session->suspended=TRUE;
+        Session->Suspended = TRUE;
     }
-    fdoData->Sessions++;
+
+    InsertHeadList(&Fdo->SessionHead, &Session->ListEntry);
+    Fdo->Sessions++;
+
     InitializeObjectAttributes(&oa, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
 
-    status = PsCreateSystemThread(&hthread, THREAD_ALL_ACCESS, &oa, NULL, 
NULL, WatchCallbackThread, session);
-    if (!NT_SUCCESS(status)) {
-            RtlFreeAnsiString(&ansi);
-            WmiFree(session);
-            return status;
-    }
-    ObReferenceObjectByHandle(hthread, THREAD_ALL_ACCESS, NULL, KernelMode,  
&session->WatchThread, NULL);
-    UnlockSessions(fdoData);
-    RtlFreeAnsiString(&ansi);
-    return STATUS_SUCCESS;
-}
+    status = PsCreateSystemThread(&hthread, THREAD_ALL_ACCESS, &oa, NULL, 
NULL, WatchCallbackThread, Session);
+    if (!NT_SUCCESS(status))
+        goto fail6;
 
-void
-RemoveSessionLocked(XENIFACE_FDO *fdoData,
-                    XenStoreSession *session) {
+    ObReferenceObjectByHandle(hthread, THREAD_ALL_ACCESS, NULL, KernelMode,  
&Session->WatchThread, NULL);
+    ReleaseMutex(&Fdo->SessionLock);
 
-    Trace("RemoveSessionLocked\n");
-    RemoveEntryList((LIST_ENTRY*)session);
-    fdoData->Sessions--;
-    SessionRemoveWatchesLocked(session);
-    if (session->transaction != NULL) {
-        XENBUS_STORE(TransactionEnd, &fdoData->StoreInterface, 
session->transaction, FALSE);
-        session->transaction = NULL;
-    }
-    session->closing = TRUE;
-    KeSetEvent(&session->SessionChangedEvent, IO_NO_INCREMENT, FALSE);
-    KeWaitForSingleObject(session->WatchThread, Executive, KernelMode, FALSE, 
NULL);
-    ObDereferenceObject(session->WatchThread);
-    FreeUnicodeStringBuffer(&session->stringid);
-    FreeUnicodeStringBuffer(&session->instancename);
-    WmiFree(session);
-}
-
-void
-RemoveSession(XENIFACE_FDO *fdoData,
-                    XenStoreSession *session) {
-    Trace("RemoveSession\n");
-    LockSessions(fdoData);
-    RemoveSessionLocked(fdoData, session);
-    UnlockSessions(fdoData);
-}
-
-void SessionsRemoveAll(XENIFACE_FDO *fdoData) {
-    LockSessions(fdoData);
-    while (fdoData->SessionHead.Flink != &fdoData->SessionHead) {
-        RemoveSessionLocked(fdoData, (XenStoreSession 
*)fdoData->SessionHead.Flink);
-    }
-    UnlockSessions(fdoData);
-}
+    RtlFreeAnsiString(&ansi);
 
+    return STATUS_SUCCESS;
 
+fail6:
+    RemoveEntryList(&Session->ListEntry);
+    Fdo->Sessions--;
+fail5:
+fail4:
+    ReleaseMutex(&Fdo->SessionLock);
+    RtlFreeAnsiString(&ansi);
+fail3:
+    WmiFree(Session);
+fail2:
+fail1:
+    return status;
+}
 
-void SessionUnwatchWatchesLocked(XenStoreSession *session)
+static VOID
+SessionRemoveLocked(
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PXENSTORE_SESSION   Session
+    )
 {
-    int i;
-    XenStoreWatch *watch;
-    AcquireMutex(&session->WatchMapLock);
-    watch = (XenStoreWatch *)session->watches.Flink;
-    for (i=0; watch != (XenStoreWatch *)&session->watches; i++) {
-        Trace("Suspend unwatch %p\n", watch->watchhandle);
+    PLIST_ENTRY             ListEntry;
+    PXENSTORE_WATCH         Watch;
 
-        XENBUS_STORE(WatchRemove, &watch->fdoData->StoreInterface, 
watch->watchhandle);
-        watch->watchhandle = NULL;
-        watch = (XenStoreWatch *)watch->listentry.Flink;
-    }
-    Trace("WATCHLIST for session %p-----------\n",session);
-    watch = (XenStoreWatch *)session->watches.Flink;
+    ASSERT3P(Fdo->SessionLock.Owner, ==, KeGetCurrentThread());
 
-    while (watch != (XenStoreWatch *)&session->watches){
-        Trace("WATCHLIST %p\n",watch->watchhandle);
-        watch = (XenStoreWatch *)watch->listentry.Flink;
-    }
-    Trace("WATCHLIST-------------------\n");
-    session->suspended=1;
-    ReleaseMutex(&session->WatchMapLock);
-}
+    RemoveEntryList(&Session->ListEntry);
+    Fdo->Sessions--;
 
-void SuspendSessionLocked(XENIFACE_FDO *fdoData,
-                         XenStoreSession *session) {
-    SessionUnwatchWatchesLocked(session);
-    if (session->transaction != NULL) {
-        Trace("End transaction %p\n",session->transaction);
+    AcquireMutex(&Session->WatchMapLock);
+    for (ListEntry = Session->WatchList.Flink;
+         ListEntry != &Session->WatchList;
+         ListEntry = ListEntry->Flink) {
+        Watch = CONTAINING_RECORD(ListEntry, XENSTORE_WATCH, ListEntry);
 
-        XENBUS_STORE(TransactionEnd, &fdoData->StoreInterface, 
session->transaction, FALSE);
-        session->transaction = NULL;
+        SessionRemoveWatchLocked(Watch);
     }
-}
-
-VOID
-WmiSessionsSuspendAll(
-    IN  PXENIFACE_FDO   Fdo
-    )
-{
-    XenStoreSession *session;
+    ReleaseMutex(&Session->WatchMapLock);
 
-    LockSessions(Fdo);
-    Trace("Suspend all sessions\n");
-    session = (XenStoreSession *)Fdo->SessionHead.Flink;
-    while (session != (XenStoreSession *)&Fdo->SessionHead) {
-        SuspendSessionLocked(Fdo, session);
-        session = (XenStoreSession *)session->listentry.Flink;
-    }
-    UnlockSessions(Fdo);
-}
+    if (Session->Transaction != NULL)
+        XENBUS_STORE(TransactionEnd, &Fdo->StoreInterface, 
Session->Transaction, FALSE);
+    Session->Transaction = NULL;
 
-void SessionRenewWatchesLocked(XenStoreSession *session) {
-    int i;
-    XenStoreWatch *watch;
-    AcquireMutex(&session->WatchMapLock);
-    watch = (XenStoreWatch *)session->watches.Flink;
-    for (i=0; watch != (XenStoreWatch *)&session->watches; i++) {
-        if (!watch->finished) {
-            watch->suspendcount = XENBUS_SUSPEND(GetCount, 
&watch->fdoData->SuspendInterface);
-            StartWatch(watch->fdoData, watch);
-        }
-        watch = (XenStoreWatch *)watch->listentry.Flink;
-    }
-    Trace("WATCHLIST for session %p-----------\n",session);
-    watch = (XenStoreWatch *)session->watches.Flink;
+    Session->Closing = TRUE;
 
-    while (watch != (XenStoreWatch *)&session->watches){
-        Trace("WATCHLIST %p\n",watch->watchhandle);
-        watch = (XenStoreWatch *)watch->listentry.Flink;
-    }
-    Trace("WATCHLIST-------------------\n");
-    session->suspended=0;
-    session->mapchanged = TRUE;
-    KeSetEvent(&session->SessionChangedEvent, IO_NO_INCREMENT,FALSE);
-    ReleaseMutex(&session->WatchMapLock);
-}
+    KeSetEvent(&Session->SessionChangedEvent, IO_NO_INCREMENT, FALSE);
+    KeWaitForSingleObject(Session->WatchThread, Executive, KernelMode, FALSE, 
NULL);
 
-void ResumeSessionLocked(XENIFACE_FDO *fdoData,
-                         XenStoreSession *session) {
-    SessionRenewWatchesLocked(session);
+    ObDereferenceObject(Session->WatchThread);
+    FreeUnicodeStringBuffer(&Session->StringId);
+    FreeUnicodeStringBuffer(&Session->InstanceName);
+    WmiFree(Session);
 }
 
-VOID
-WmiSessionsResumeAll(
+static VOID
+SessionsRemoveAll(
     IN  PXENIFACE_FDO   Fdo
     )
 {
-    XenStoreSession *session;
+    PXENSTORE_SESSION   Session;
 
-    LockSessions(Fdo);
-    Trace("Resume all sessions\n");
-    session = (XenStoreSession *)Fdo->SessionHead.Flink;
-    while (session != (XenStoreSession *)&Fdo->SessionHead) {
-        ResumeSessionLocked(Fdo, session);
-        session = (XenStoreSession *)session->listentry.Flink;
+    AcquireMutex(&Fdo->SessionLock);
+    while (!IsListEmpty(&Fdo->SessionHead)) {
+        ASSERT(Fdo->SessionHead.Flink != &Fdo->SessionHead);
+
+        Session = CONTAINING_RECORD(Fdo->SessionHead.Flink,
+                                    XENSTORE_SESSION,
+                                    ListEntry);
+
+        SessionRemoveLocked(Fdo, Session);
     }
-    UnlockSessions(Fdo);
+    ReleaseMutex(&Fdo->SessionLock);
 }
 
-NTSTATUS
-WmiRegister(
-    IN  PXENIFACE_FDO   Fdo
+static VOID
+SessionsSuspendLocked(
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PXENSTORE_SESSION   Session
     )
 {
-    NTSTATUS            status;
+    PLIST_ENTRY             ListEntry;
+    PXENSTORE_WATCH         Watch;
 
-    if (Fdo->WmiReady)
-        return STATUS_SUCCESS;
+    ASSERT3P(Fdo->SessionLock.Owner, ==, KeGetCurrentThread());
 
-    Trace("%s\n",__FUNCTION__);
-    Info("DRV: XenIface WMI Initialisation\n");
+    AcquireMutex(&Session->WatchMapLock);
+    for (ListEntry = Session->WatchList.Flink;
+         ListEntry != &Session->WatchList;
+         ListEntry = ListEntry->Flink) {
+        Watch = CONTAINING_RECORD(ListEntry, XENSTORE_WATCH, ListEntry);
 
-    status = IoWMIRegistrationControl(Fdo->Dx->DeviceObject,
-                                      WMIREG_ACTION_REGISTER);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Fdo->WmiReady = 1;
-    return STATUS_SUCCESS;
+        if (Watch->WatchHandle != NULL)
+            XENBUS_STORE(WatchRemove, &Watch->Fdo->StoreInterface, 
Watch->WatchHandle);
+        Watch->WatchHandle = NULL;
+    }
+    Session->Suspended = TRUE;
+    ReleaseMutex(&Session->WatchMapLock);
 
-fail1:
-    Error("fail1 (%08x)\n", status);
-    return status;
+    if (Session->Transaction != NULL)
+        XENBUS_STORE(TransactionEnd, &Fdo->StoreInterface, 
Session->Transaction, FALSE);
+    Session->Transaction = NULL;
 }
 
-VOID
-WmiDeregister(
-    IN  PXENIFACE_FDO   Fdo
+static VOID
+SessionResumeLocked(
+    IN  PXENSTORE_SESSION   Session
     )
 {
-    if (!Fdo->WmiReady)
-        return;
-
-    Info("DRV: XenIface WMI Finalisation\n");
-    Trace("%s\n",__FUNCTION__);
+    PLIST_ENTRY             ListEntry;
+    PXENSTORE_WATCH         Watch;
 
-    SessionsRemoveAll(Fdo);
-    (VOID) IoWMIRegistrationControl(Fdo->Dx->DeviceObject,
-                                    WMIREG_ACTION_DEREGISTER);
-    Fdo->WmiReady = 0;
-}
+    // ASSERT3P(Fdo->SessionLock.Owner, ==, KeGetCurrentThread());
 
-NTSTATUS
-WmiChangeSingleInstance(
-    PXENIFACE_FDO Fdo,
-    PIO_STACK_LOCATION stack
-   )
-{
-    UNREFERENCED_PARAMETER(Fdo);
-    UNREFERENCED_PARAMETER(stack);
-    Trace("%s\n",__FUNCTION__);
-    return STATUS_NOT_SUPPORTED;
-}
+    AcquireMutex(&Session->WatchMapLock);
+    for (ListEntry = Session->WatchList.Flink;
+         ListEntry != &Session->WatchList;
+         ListEntry = ListEntry->Flink) {
+        Watch = CONTAINING_RECORD(ListEntry, XENSTORE_WATCH, ListEntry);
 
-NTSTATUS
-WmiChangeSingleItem(
-    IN PXENIFACE_FDO Fdo,
-    IN PIO_STACK_LOCATION stack
-   )
-{
-    UNREFERENCED_PARAMETER(Fdo);
-    UNREFERENCED_PARAMETER(stack);
-    Trace("%s\n",__FUNCTION__);
-    return STATUS_NOT_SUPPORTED;
-}
+        if (Watch->Finished)
+            continue;
 
-NTSTATUS
-WmiDisableCollection(
-    IN PXENIFACE_FDO Fdo,
-    IN PIO_STACK_LOCATION stack
-   )
-{
-    UNREFERENCED_PARAMETER(Fdo);
-    UNREFERENCED_PARAMETER(stack);
-    Trace("%s\n",__FUNCTION__);
-    return STATUS_NOT_SUPPORTED;
-}
-
-NTSTATUS
-WmiDisableEvents(
-    IN PXENIFACE_FDO Fdo,
-    IN PIO_STACK_LOCATION stack
-   )
-{
-    UNREFERENCED_PARAMETER(Fdo);
-    UNREFERENCED_PARAMETER(stack);
-    Trace("%s\n",__FUNCTION__);
-    return STATUS_NOT_SUPPORTED;
-}
+        Watch->SuspendCount = XENBUS_SUSPEND(GetCount, 
&Watch->Fdo->SuspendInterface);
+        StartWatch(Watch->Fdo, Watch);
+    }
+    Session->Suspended = FALSE;
 
-NTSTATUS
-WmiEnableCollection(
-    IN PXENIFACE_FDO Fdo,
-    IN PIO_STACK_LOCATION stack
-   )
-{
-    UNREFERENCED_PARAMETER(Fdo);
-    UNREFERENCED_PARAMETER(stack);
-    Trace("%s\n",__FUNCTION__);
-    return STATUS_NOT_SUPPORTED;
+    Session->Changed = TRUE;
+    KeSetEvent(&Session->SessionChangedEvent, IO_NO_INCREMENT,FALSE);
+    ReleaseMutex(&Session->WatchMapLock);
 }
 
-NTSTATUS
-WmiEnableEvents(
-    IN PXENIFACE_FDO Fdo,
-    IN PIO_STACK_LOCATION stack
-   )
+static NTSTATUS
+NodeTooSmall(
+    IN  UCHAR*      Buffer,
+    IN  ULONG       BufferSize,
+    IN  ULONG       Needed,
+    OUT ULONG_PTR*  BytesWritten
+    )
 {
-    UNREFERENCED_PARAMETER(Fdo);
-    UNREFERENCED_PARAMETER(stack);
-    Trace("%s\n",__FUNCTION__);
-    return STATUS_NOT_SUPPORTED;
-}
+    WNODE_TOO_SMALL*    node;
+    ULONG               RequiredSize;
 
-NTSTATUS NodeTooSmall(UCHAR *Buffer,
-                    ULONG BufferSize,
-                    ULONG Needed,
-                    ULONG_PTR *byteswritten) {
-    WNODE_TOO_SMALL *node;
-    ULONG RequiredSize;
     if (!AccessWmiBuffer(Buffer, FALSE, &RequiredSize, BufferSize,
-                            WMI_BUFFER, sizeof(WNODE_TOO_SMALL), &node,
-                            WMI_DONE))
-    {
-        *byteswritten = RequiredSize;
+                         WMI_BUFFER, sizeof(WNODE_TOO_SMALL), &node,
+                         WMI_DONE)) {
+        *BytesWritten = RequiredSize;
         return STATUS_BUFFER_TOO_SMALL;
     }
-    node->WnodeHeader.BufferSize=sizeof(WNODE_TOO_SMALL);
+
+    node->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL);
     KeQuerySystemTime(&node->WnodeHeader.TimeStamp);
     node->WnodeHeader.Flags = WNODE_FLAG_TOO_SMALL;
     node->SizeNeeded = Needed;
-    *byteswritten = sizeof(WNODE_TOO_SMALL);
+
+    *BytesWritten = sizeof(WNODE_TOO_SMALL);
     return STATUS_SUCCESS;
 }
 
-NTSTATUS
-SessionExecuteRemoveValue(UCHAR *InBuffer,
-                            ULONG InBufferSize,
-                            UCHAR *OutBuffer,
-                            ULONG OutBufferSize,
-                            XENIFACE_FDO* fdoData,
-                            UNICODE_STRING *instance,
-                            OUT ULONG_PTR *byteswritten) {
-    ULONG RequiredSize;
-    NTSTATUS status;
-    UCHAR* upathname;
-    OEM_STRING pathname;
-    XenStoreSession *session;
-    char *tmpbuffer;
-
-    *byteswritten=0;
+static NTSTATUS
+SessionExecuteRemoveValue(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  PUNICODE_STRING instance,
+    IN  UCHAR*          InBuffer,
+    IN  ULONG           InBufferSize,
+    IN  UCHAR*          OutBuffer,
+    IN  ULONG           OutBufferSize,
+    OUT ULONG_PTR*      BytesWritten
+    )
+{
+    ULONG               RequiredSize;
+    NTSTATUS            status;
+    UCHAR*              upathname;
+    OEM_STRING          pathname;
+    PXENSTORE_SESSION   session;
+    char*               tmpbuffer;
+
+    *BytesWritten = 0;
+    status = STATUS_INVALID_DEVICE_REQUEST;
     if (!AccessWmiBuffer(InBuffer, TRUE, &RequiredSize, InBufferSize,
-                            WMI_STRING, &upathname,
-                            WMI_DONE))
-        return STATUS_INVALID_DEVICE_REQUEST;
-    if (!fdoData->InterfacesAcquired) {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
+                         WMI_STRING, &upathname,
+                         WMI_DONE))
+        goto fail1;
+
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (!Fdo->InterfacesAcquired)
+        goto fail2;
 
     status = GetCountedUTF8String(&pathname, upathname);
     if (!NT_SUCCESS(status))
-        return status;
+        goto fail3;
 
     status = STATUS_INSUFFICIENT_RESOURCES;
     tmpbuffer = WmiAllocate(pathname.Length + 1);
-    if (!tmpbuffer) {
-        goto fail1;
-    }
+    if (tmpbuffer == NULL)
+        goto fail4;
 
     RtlCopyBytes(tmpbuffer, pathname.Buffer, pathname.Length);
 
     status = STATUS_WMI_INSTANCE_NOT_FOUND;
-    if ((session = FindSessionByInstanceAndLock(fdoData, instance)) ==
-            NULL){
-        goto fail2;
-    }
-    status = XENBUS_STORE(Remove, &fdoData->StoreInterface, 
session->transaction, NULL, tmpbuffer);
-    UnlockSessions(fdoData);
+    session = FindSessionByInstanceAndLock(Fdo, instance);
+    if (session == NULL)
+        goto fail5;
+
+    status = XENBUS_STORE(Remove, &Fdo->StoreInterface, session->Transaction, 
NULL, tmpbuffer);
+    ReleaseMutex(&Fdo->SessionLock);
+
+    if (!NT_SUCCESS(status))
+        goto fail6;
 
-fail2:
     WmiFree(tmpbuffer);
+    FreeUTF8String(&pathname);
 
-fail1:
+    return STATUS_SUCCESS;
+
+fail6:
+fail5:
+    WmiFree(tmpbuffer);
+fail4:
     FreeUTF8String(&pathname);
+fail3:
+fail2:
+fail1:
     return status;
-
 }
 
-NTSTATUS
-SessionExecuteRemoveWatch(UCHAR *InBuffer,
-                            ULONG InBufferSize,
-                            UCHAR *OutBuffer,
-                            ULONG OutBufferSize,
-                            XENIFACE_FDO* fdoData,
-                            UNICODE_STRING *instance,
-                            OUT ULONG_PTR *byteswritten) {
-    ULONG RequiredSize;
-    UCHAR* upathname;
-    XenStoreWatch* watch;
-    UNICODE_STRING unicpath_notbacked;
-    XenStoreSession *session;
-
+static NTSTATUS
+SessionExecuteRemoveWatch(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  PUNICODE_STRING instance,
+    IN  UCHAR*          InBuffer,
+    IN  ULONG           InBufferSize,
+    IN  UCHAR*          OutBuffer,
+    IN  ULONG           OutBufferSize,
+    OUT ULONG_PTR*      BytesWritten
+    )
+{
+    NTSTATUS            status;
+    ULONG               RequiredSize;
+    UCHAR*              upathname;
+    PXENSTORE_WATCH     watch;
+    UNICODE_STRING      unicpath_notbacked;
+    PXENSTORE_SESSION   session;
+
+    *BytesWritten = 0;
+    status = STATUS_INVALID_DEVICE_REQUEST;
     if (!AccessWmiBuffer(InBuffer, TRUE, &RequiredSize, InBufferSize,
-                            WMI_STRING, &upathname,
-                            WMI_DONE))
-        return STATUS_INVALID_DEVICE_REQUEST;
-
+                         WMI_STRING, &upathname,
+                         WMI_DONE))
+        goto fail1;
 
     GetCountedUnicodeString(&unicpath_notbacked, upathname);
 
-    if ((session = FindSessionByInstanceAndLock(fdoData, instance)) ==
-            NULL){
-        return STATUS_WMI_INSTANCE_NOT_FOUND;
-    }
-
-
-    Trace("Find Watch\n");
+    status = STATUS_WMI_INSTANCE_NOT_FOUND;
+    session = FindSessionByInstanceAndLock(Fdo, instance);
+    if (session == NULL)
+        goto fail2;
 
+    AcquireMutex(&session->WatchMapLock);
     watch = SessionFindWatchLocked(session, &unicpath_notbacked);
-
     if (watch) {
-
-        SessionRemoveWatchLocked(session, watch);
-    }
-    else {
+        SessionRemoveWatchLocked(watch);
+    } else {
         Warning("No Watch\n");
     }
-#pragma prefast (suppress:26110)
     ReleaseMutex(&session->WatchMapLock);
-    UnlockSessions(fdoData);
-
-    *byteswritten=0;
-
 
+    ReleaseMutex(&Fdo->SessionLock);
 
     return STATUS_SUCCESS;
 
+fail2:
+fail1:
+    return status;
 }
 
+static NTSTATUS
+SessionExecuteSetWatch(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  PUNICODE_STRING instance,
+    IN  UCHAR*          InBuffer,
+    IN  ULONG           InBufferSize,
+    IN  UCHAR*          OutBuffer,
+    IN  ULONG           OutBufferSize,
+    OUT ULONG_PTR*      BytesWritten
+    )
+{
+    ULONG               RequiredSize;
+    NTSTATUS            status;
+    UCHAR*              upathname;
+    PXENSTORE_SESSION   Session;
+    UNICODE_STRING      unicpath_notbacked;
+    UNICODE_STRING      unicpath_backed;
 
-NTSTATUS
-SessionExecuteSetWatch(UCHAR *InBuffer,
-                            ULONG InBufferSize,
-                            UCHAR *OutBuffer,
-                            ULONG OutBufferSize,
-                            XENIFACE_FDO* fdoData,
-                            UNICODE_STRING *instance,
-                            OUT ULONG_PTR *byteswritten) {
-    ULONG RequiredSize;
-    NTSTATUS status;
-    UCHAR* upathname;
-    XenStoreWatch* watch;
-    XenStoreSession *session;
-    UNICODE_STRING unicpath_notbacked;
-    UNICODE_STRING unicpath_backed;
+    *BytesWritten = 0;
+    status = STATUS_INVALID_DEVICE_REQUEST;
     if (!AccessWmiBuffer(InBuffer, TRUE, &RequiredSize, InBufferSize,
-                            WMI_STRING, &upathname,
-                            WMI_DONE))
-        return STATUS_INVALID_DEVICE_REQUEST;
-
+                         WMI_STRING, &upathname,
+                         WMI_DONE))
+        goto fail1;
 
     GetCountedUnicodeString(&unicpath_notbacked, upathname);
-    status = CloneUnicodeString(&unicpath_backed, &unicpath_notbacked);
-    if (!NT_SUCCESS(status)) return status;
-
-    if ((session = FindSessionByInstanceAndLock(fdoData, instance)) ==
-            NULL){
-        FreeUnicodeStringBuffer(&unicpath_backed);
-        return STATUS_WMI_INSTANCE_NOT_FOUND;
-    }
 
-    status = SessionAddWatchLocked(session, fdoData, &unicpath_backed, &watch);
+    status = CloneUnicodeString(&unicpath_backed, &unicpath_notbacked);
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
-    UnlockSessions(fdoData);
-    if (!NT_SUCCESS(status)) {
-        FreeUnicodeStringBuffer(&unicpath_backed);
-        return status;
-    }
+    status = STATUS_WMI_INSTANCE_NOT_FOUND;
+    Session = FindSessionByInstanceAndLock(Fdo, instance);
+    if (Session == NULL)
+        goto fail3;
 
+    AcquireMutex(&Session->WatchMapLock);
 
-    *byteswritten=0;
+    status = SessionAddWatchLocked(Fdo, Session, &unicpath_backed);
 
+    ReleaseMutex(&Session->WatchMapLock);
 
+    ReleaseMutex(&Fdo->SessionLock);
+    if (!NT_SUCCESS(status))
+        goto fail4;
 
     return STATUS_SUCCESS;
 
+fail4:
+fail3:
+    FreeUnicodeStringBuffer(&unicpath_backed);
+fail2:
+fail1:
+    return status;
 }
-NTSTATUS
-SessionExecuteEndSession(UCHAR *InBuffer,
-                            ULONG InBufferSize,
-                            UCHAR *OutBuffer,
-                            ULONG OutBufferSize,
-                            XENIFACE_FDO* fdoData,
-                            UNICODE_STRING *instance,
-                            OUT ULONG_PTR *byteswritten) {
-    XenStoreSession *session;
-    Trace("ExecuteEndSession\n");
-    *byteswritten = 0;
-    if ((session = FindSessionByInstanceAndLock(fdoData, instance)) ==
-            NULL){
-        return STATUS_WMI_INSTANCE_NOT_FOUND;
-    }
 
-    RemoveSessionLocked(fdoData, session);
-    UnlockSessions(fdoData);
+static NTSTATUS
+SessionExecuteEndSession(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  PUNICODE_STRING instance,
+    IN  UCHAR*          InBuffer,
+    IN  ULONG           InBufferSize,
+    IN  UCHAR*          OutBuffer,
+    IN  ULONG           OutBufferSize,
+    OUT ULONG_PTR*      BytesWritten
+    )
+{
+    PXENSTORE_SESSION   Session;
+    NTSTATUS            status;
+
+    *BytesWritten = 0;
+    status = STATUS_WMI_INSTANCE_NOT_FOUND;
+    Session = FindSessionByInstanceAndLock(Fdo, instance);
+    if (Session == NULL)
+        goto fail1;
+
+    SessionRemoveLocked(Fdo, Session);
+    ReleaseMutex(&Fdo->SessionLock);
+
     return STATUS_SUCCESS;
+
+fail1:
+    return status;
 }
-NTSTATUS
-SessionExecuteSetValue(UCHAR *InBuffer,
-                            ULONG InBufferSize,
-                            UCHAR *OutBuffer,
-                            ULONG OutBufferSize,
-                            XENIFACE_FDO* fdoData,
-                            UNICODE_STRING *instance,
-                            OUT ULONG_PTR *byteswritten) {
-    ULONG RequiredSize;
-    NTSTATUS status;
-    UCHAR* upathname;
-    UCHAR* uvalue;
-    OEM_STRING pathname;
-    OEM_STRING value;
-    XenStoreSession *session;
-    char *tmppath;
-    char* tmpvalue;
-
-    Trace(" Try to write\n");
+
+static NTSTATUS
+SessionExecuteSetValue(
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PUNICODE_STRING     instance,
+    IN  UCHAR*              InBuffer,
+    IN  ULONG               InBufferSize,
+    IN  UCHAR*              OutBuffer,
+    IN  ULONG               OutBufferSize,
+    OUT ULONG_PTR*          BytesWritten
+    )
+{
+    ULONG                   RequiredSize;
+    NTSTATUS                status;
+    UCHAR*                  upathname;
+    UCHAR*                  uvalue;
+    OEM_STRING              pathname;
+    OEM_STRING              value;
+    PXENSTORE_SESSION       session;
+    char*                   tmppath;
+    char*                   tmpvalue;
+
+    *BytesWritten = 0;
+    status = STATUS_INVALID_DEVICE_REQUEST;
     if (!AccessWmiBuffer(InBuffer, TRUE, &RequiredSize, InBufferSize,
-                            WMI_STRING, &upathname,
-                            WMI_STRING, &uvalue,
-                            WMI_DONE))
-        return STATUS_INVALID_DEVICE_REQUEST;
-    if (!fdoData->InterfacesAcquired) {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
+                         WMI_STRING, &upathname,
+                         WMI_STRING, &uvalue,
+                         WMI_DONE))
+        goto fail1;
+
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (!Fdo->InterfacesAcquired)
+        goto fail2;
+
     status = GetCountedUTF8String(&pathname, upathname);
     if (!NT_SUCCESS(status))
-        return status;
+        goto fail3;
 
     status = STATUS_INSUFFICIENT_RESOURCES;
     tmppath = WmiAllocate(pathname.Length + 1);
-    if (!tmppath) {
-        goto fail1;
-    }
+    if (tmppath == NULL)
+        goto fail4;
 
     RtlCopyBytes(tmppath, pathname.Buffer, pathname.Length);
 
     status = GetCountedUTF8String(&value, uvalue);
-    if (!NT_SUCCESS(status)){
-        goto fail2;
-    }
+    if (!NT_SUCCESS(status))
+        goto fail5;
+
     status = STATUS_INSUFFICIENT_RESOURCES;
     tmpvalue = WmiAllocate(value.Length + 1);
-    if (!tmpvalue) {
-        goto fail3;
-    }
+    if (tmpvalue == NULL)
+        goto fail6;
 
     RtlCopyBytes(tmpvalue, value.Buffer, value.Length);
 
     status = STATUS_WMI_INSTANCE_NOT_FOUND;
-    if ((session = FindSessionByInstanceAndLock(fdoData, instance)) ==
-            NULL){
-        goto fail4;
-    }
-    status = XENBUS_STORE(Printf, &fdoData->StoreInterface, 
session->transaction, NULL, tmppath, "%s", tmpvalue);
-    Trace(" Write %s to %s (%p)\n", tmpvalue, tmppath, status);
-    UnlockSessions(fdoData);
+    session = FindSessionByInstanceAndLock(Fdo, instance);
+    if (session == NULL)
+        goto fail7;
 
-fail4:
-    WmiFree(tmpvalue);
+    status = XENBUS_STORE(Printf, &Fdo->StoreInterface, session->Transaction, 
NULL, tmppath, "%s", tmpvalue);
+    ReleaseMutex(&Fdo->SessionLock);
 
-fail3:
-    FreeUTF8String(&value);
+    if (!NT_SUCCESS(status))
+        goto fail8;
 
-fail2:
+    WmiFree(tmpvalue);
+    FreeUTF8String(&value);
     WmiFree(tmppath);
-
-fail1:
     FreeUTF8String(&pathname);
 
-    *byteswritten = 0;
-    return status;
+    return STATUS_SUCCESS;
 
+fail8:
+fail7:
+    WmiFree(tmpvalue);
+fail6:
+    FreeUTF8String(&value);
+fail5:
+    WmiFree(tmppath);
+fail4:
+    FreeUTF8String(&pathname);
+fail3:
+fail2:
+fail1:
+    return status;
 }
-NTSTATUS
-SessionExecuteGetFirstChild(UCHAR *InBuffer,
-                            ULONG InBufferSize,
-                            UCHAR *OutBuffer,
-                            ULONG OutBufferSize,
-                            XENIFACE_FDO* fdoData,
-                            UNICODE_STRING *instance,
-                            OUT ULONG_PTR *byteswritten) {
-    ULONG RequiredSize;
-    UCHAR *uloc;
-    NTSTATUS status;
-    OEM_STRING path;
-    PCHAR listresults;
-    size_t stringarraysize;
-    UCHAR *valuepos;
-    XenStoreSession *session;
-    char *tmppath;
+
+static NTSTATUS
+SessionExecuteGetFirstChild(
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PUNICODE_STRING     instance,
+    IN  UCHAR*              InBuffer,
+    IN  ULONG               InBufferSize,
+    IN  UCHAR*              OutBuffer,
+    IN  ULONG               OutBufferSize,
+    OUT ULONG_PTR*          BytesWritten
+    )
+{
+    ULONG                   RequiredSize;
+    UCHAR*                  uloc;
+    NTSTATUS                status;
+    OEM_STRING              path;
+    PCHAR                   listresults;
+    size_t                  stringarraysize;
+    UCHAR*                  valuepos;
+    PXENSTORE_SESSION       session;
+    char*                   tmppath;
+
+    *BytesWritten = 0;
+    status = STATUS_INVALID_DEVICE_REQUEST;
     if (!AccessWmiBuffer(InBuffer, TRUE, &RequiredSize, InBufferSize,
-                            WMI_STRING, &uloc,
-                            WMI_DONE)){
-        return  STATUS_INVALID_DEVICE_REQUEST;
-    }
-    if (!fdoData->InterfacesAcquired) {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
+                         WMI_STRING, &uloc,
+                         WMI_DONE))
+        goto fail1;
 
-    status = GetCountedUTF8String(&path, uloc);
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (!Fdo->InterfacesAcquired)
+        goto fail2;
 
-    if (!NT_SUCCESS(status)) {
-        return status;
-    }
+    status = GetCountedUTF8String(&path, uloc);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
     status = STATUS_INSUFFICIENT_RESOURCES;
     tmppath = WmiAllocate(path.Length + 1);
-    if (!tmppath) {
-        goto fail1;
-    }
+    if (tmppath == NULL)
+        goto fail4;
 
     RtlCopyBytes(tmppath, path.Buffer, path.Length);
 
     status = STATUS_WMI_INSTANCE_NOT_FOUND;
-    if ((session = FindSessionByInstanceAndLock(fdoData, instance)) ==
-            NULL){
-        goto fail2;
-    }
-    status = XENBUS_STORE(Directory,&fdoData->StoreInterface, 
session->transaction, NULL, tmppath, &listresults);
-    UnlockSessions(fdoData);
+    session = FindSessionByInstanceAndLock(Fdo, instance);
+    if (session == NULL)
+        goto fail5;
 
-    if (!NT_SUCCESS(status)) {
-        goto fail2;
-    }
+    status = XENBUS_STORE(Directory, &Fdo->StoreInterface, 
session->Transaction, NULL, tmppath, &listresults);
+    ReleaseMutex(&Fdo->SessionLock);
+
+    if (!NT_SUCCESS(status))
+        goto fail6;
 
     stringarraysize = 0;
     if ((listresults != NULL) && (listresults[0] != 0)) {
@@ -1822,108 +1733,110 @@ SessionExecuteGetFirstChild(UCHAR *InBuffer,
         }
         stringarraysize += GetCountedUtf8Size(listresults);
     } else {
-        stringarraysize+=GetCountedUtf8Size("");
+        stringarraysize += GetCountedUtf8Size("");
     }
 
     status = STATUS_BUFFER_TOO_SMALL;
     if (!AccessWmiBuffer(InBuffer, FALSE, &RequiredSize, OutBufferSize,
-                            WMI_STRING, stringarraysize, &valuepos,
-                            WMI_DONE)){
-        goto fail3;
-    }
+                         WMI_STRING, stringarraysize, &valuepos,
+                         WMI_DONE))
+        goto fail7;
 
-    status = STATUS_SUCCESS;
     if ((listresults != NULL) && (listresults[0] != 0)) {
         PSTR fullpath;
-        if ((path.Length == 1) && (path.Buffer[0] == '/')) {
+        if ((path.Length == 1) && (path.Buffer[0] == '/'))
             fullpath = Xmasprintf("/%s", listresults);
-        } else {
+        else
             fullpath = Xmasprintf("%s/%s", path.Buffer, listresults);
-        }
 
-        if (fullpath == NULL) {
-            status = STATUS_NO_MEMORY;
-            goto fail4;
-        }
+        status = STATUS_NO_MEMORY;
+        if (fullpath == NULL)
+            goto fail8;
 
         WriteCountedUTF8String(fullpath, valuepos);
-        valuepos+=GetCountedUtf8Size(fullpath);
+        valuepos += GetCountedUtf8Size(fullpath);
         WmiFree(fullpath);
-    }
-    else {
+    } else {
         WriteCountedUTF8String("", valuepos);
     }
 
-fail4:
-fail3:
-    XENBUS_STORE(Free, &fdoData->StoreInterface, listresults);
-
-    *byteswritten = RequiredSize;
+    XENBUS_STORE(Free, &Fdo->StoreInterface, listresults);
 
-fail2:
     WmiFree(tmppath);
-
-fail1:
     FreeUTF8String(&path);
 
-    return status;
+    *BytesWritten = RequiredSize;
+    return STATUS_SUCCESS;
 
+fail8:
+fail7:
+    XENBUS_STORE(Free, &Fdo->StoreInterface, listresults);
+    *BytesWritten = RequiredSize;
+fail6:
+fail5:
+    WmiFree(tmppath);
+fail4:
+    FreeUTF8String(&path);
+fail3:
+fail2:
+fail1:
+    return status;
 }
 
-NTSTATUS
-SessionExecuteGetNextSibling(UCHAR *InBuffer,
-                            ULONG InBufferSize,
-                            UCHAR *OutBuffer,
-                            ULONG OutBufferSize,
-                            XENIFACE_FDO* fdoData,
-                            UNICODE_STRING *instance,
-                            OUT ULONG_PTR *byteswritten) {
-    ULONG RequiredSize;
-    UCHAR *uloc;
-    NTSTATUS status;
-    OEM_STRING path;
-    ANSI_STRING checkleaf;
-    PCHAR listresults;
-    PCHAR nextresult;
-    size_t stringarraysize;
-    UCHAR *valuepos;
-    XenStoreSession *session;
-    char *tmppath;
-    char *tmpleaf;
-    int leafoffset;
-    char *attemptstring;
+static NTSTATUS
+SessionExecuteGetNextSibling(
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PUNICODE_STRING     instance,
+    IN  UCHAR*              InBuffer,
+    IN  ULONG               InBufferSize,
+    IN  UCHAR*              OutBuffer,
+    IN  ULONG               OutBufferSize,
+    OUT ULONG_PTR*          BytesWritten
+    )
+{
+    ULONG                   RequiredSize;
+    UCHAR*                  uloc;
+    NTSTATUS                status;
+    OEM_STRING              path;
+    ANSI_STRING             checkleaf;
+    PCHAR                   listresults;
+    PCHAR                   nextresult;
+    size_t                  stringarraysize;
+    UCHAR*                  valuepos;
+    PXENSTORE_SESSION       session;
+    char*                   tmppath;
+    char*                   tmpleaf;
+    int                     leafoffset;
+    char*                   attemptstring;
+
+    *BytesWritten = 0;
+    status = STATUS_INVALID_DEVICE_REQUEST;
     if (!AccessWmiBuffer(InBuffer, TRUE, &RequiredSize, InBufferSize,
-                            WMI_STRING, &uloc,
-                            WMI_DONE)){
-        return  STATUS_INVALID_DEVICE_REQUEST;
-    }
-    if (!fdoData->InterfacesAcquired) {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
+                         WMI_STRING, &uloc,
+                         WMI_DONE))
+        goto fail1;
 
-    status = GetCountedUTF8String(&path, uloc);
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (!Fdo->InterfacesAcquired)
+        goto fail2;
 
-    if (!NT_SUCCESS(status)) {
-        return status;
-    }
+    status = GetCountedUTF8String(&path, uloc);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
     status = STATUS_INSUFFICIENT_RESOURCES;
     tmppath = WmiAllocate(path.Length + 1);
-
-    if (!tmppath) {
-        goto fail1;
-    }
+    if (tmppath == NULL)
+        goto fail4;
 
     tmpleaf = WmiAllocate(path.Length + 1);
-    if (!tmpleaf) {
-        goto fail2;
-    }
+    if (tmpleaf == NULL)
+        goto fail5;
 
     status = STATUS_WMI_INSTANCE_NOT_FOUND;
-    if ((session = FindSessionByInstanceAndLock(fdoData, instance)) ==
-            NULL){
-        goto fail3;
-    }
+    session = FindSessionByInstanceAndLock(Fdo, instance);
+    if (session == NULL)
+        goto fail6;
 
     leafoffset = 0;
     if (path.Length > 1) {
@@ -1936,7 +1849,7 @@ SessionExecuteGetNextSibling(UCHAR *InBuffer,
         RtlCopyBytes(tmppath, path.Buffer, leafoffset);
         RtlCopyBytes(tmpleaf, path.Buffer + leafoffset + 1, path.Length - 
leafoffset - 1);
     } else if (path.Buffer[0] == '/') {
-        if (path.Length>1)
+        if (path.Length > 1)
             RtlCopyBytes(tmpleaf, path.Buffer + 1, path.Length - 1);
         tmppath[0] = '/';
     } else {
@@ -1944,39 +1857,34 @@ SessionExecuteGetNextSibling(UCHAR *InBuffer,
         RtlCopyBytes(tmpleaf, path.Buffer, path.Length);
     }
 
-    status = XENBUS_STORE(Directory,&fdoData->StoreInterface, 
session->transaction, NULL, tmppath, &listresults);
-    UnlockSessions(fdoData);
+    status = XENBUS_STORE(Directory, &Fdo->StoreInterface, 
session->Transaction, NULL, tmppath, &listresults);
+    ReleaseMutex(&Fdo->SessionLock);
 
-    if (!NT_SUCCESS(status)) {
-        goto fail3;
-    }
+    if (!NT_SUCCESS(status))
+        goto fail7;
 
     stringarraysize = 0;
     RtlInitAnsiString(&checkleaf, tmpleaf);
 
     nextresult = listresults;
-
     while (*nextresult != 0) {
         ANSI_STRING checkstr;
         RtlInitAnsiString(&checkstr, nextresult);
-        if (RtlEqualString(&checkstr, &checkleaf, TRUE)) {
+        if (RtlEqualString(&checkstr, &checkleaf, TRUE))
             break;
-        }
-        while (*nextresult!=0) {
+
+        while (*nextresult != 0)
             nextresult++;
-        }
         nextresult++;
     }
 
-
     attemptstring = NULL;
-    while (*nextresult !=0) {
+    while (*nextresult != 0)
         nextresult++;
-    }
     nextresult++;
-    if (*nextresult!=0) {
+
+    if (*nextresult != 0)
         attemptstring = nextresult;
-    }
 
     if (attemptstring != NULL) {
         stringarraysize += CountBytesUtf16FromUtf8(tmppath); 
//sizeof(WCHAR)*leafoffset;
@@ -1992,105 +1900,109 @@ SessionExecuteGetNextSibling(UCHAR *InBuffer,
 
     status = STATUS_BUFFER_TOO_SMALL;
     if (!AccessWmiBuffer(InBuffer, FALSE, &RequiredSize, OutBufferSize,
-                            WMI_STRING, stringarraysize, &valuepos,
-                            WMI_DONE)){
-        goto fail4;
-    }
+                         WMI_STRING, stringarraysize, &valuepos,
+                         WMI_DONE))
+        goto fail8;
 
-    status = STATUS_SUCCESS;
     if (attemptstring != NULL) {
         PSTR fullpath;
-        if ((leafoffset == 1) && (path.Buffer[0] == '/')) {
+        if ((leafoffset == 1) && (path.Buffer[0] == '/'))
             fullpath = Xmasprintf("/%s", attemptstring);
-        } else {
+        else
             fullpath = Xmasprintf("%s/%s", tmppath, attemptstring);
-        }
 
-        if (fullpath == NULL) {
-            status = STATUS_NO_MEMORY;
-            goto fail5;
-        }
+        status = STATUS_NO_MEMORY;
+        if (fullpath == NULL)
+            goto fail9;
 
         WriteCountedUTF8String(fullpath, valuepos);
         WmiFree(fullpath);
-    }
-    else {
+    } else {
         WriteCountedUTF8String("", valuepos);
-        valuepos+=GetCountedUtf8Size("");
+        valuepos += GetCountedUtf8Size("");
     }
 
+    XENBUS_STORE(Free, &Fdo->StoreInterface, listresults);
+
+    WmiFree(tmpleaf);
+    WmiFree(tmppath);
+    FreeUTF8String(&path);
+
+    *BytesWritten = RequiredSize;
+    return STATUS_SUCCESS;
 
+fail9:
+fail8:
+    XENBUS_STORE(Free, &Fdo->StoreInterface, listresults);
+    *BytesWritten = RequiredSize;
+fail7:
+fail6:
+    WmiFree(tmpleaf);
 fail5:
+    WmiFree(tmppath);
 fail4:
-    XENBUS_STORE(Free, &fdoData->StoreInterface, listresults);
-
+    FreeUTF8String(&path);
 fail3:
-    WmiFree(tmpleaf);
-
 fail2:
-    WmiFree(tmppath);
-
 fail1:
-    FreeUTF8String(&path);
-    *byteswritten = RequiredSize;
     return status;
-
 }
 
-NTSTATUS
-SessionExecuteGetChildren(UCHAR *InBuffer,
-                            ULONG InBufferSize,
-                            UCHAR *OutBuffer,
-                            ULONG OutBufferSize,
-                            XENIFACE_FDO* fdoData,
-                            UNICODE_STRING *instance,
-                            OUT ULONG_PTR *byteswritten) {
-    int i;
-    ULONG RequiredSize;
-    UCHAR *uloc;
-    NTSTATUS status;
-    OEM_STRING path;
-    PCHAR listresults;
-    PCHAR nextresults;
-    ULONG *noofnodes;
-    size_t stringarraysize;
-    UCHAR *valuepos;
-    XenStoreSession *session;
-    char *tmppath;
+static NTSTATUS
+SessionExecuteGetChildren(
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PUNICODE_STRING     instance,
+    IN  UCHAR*              InBuffer,
+    IN  ULONG               InBufferSize,
+    IN  UCHAR*              OutBuffer,
+    IN  ULONG               OutBufferSize,
+    OUT ULONG_PTR*          BytesWritten
+    )
+{
+    int                     i;
+    ULONG                   RequiredSize;
+    UCHAR*                  uloc;
+    NTSTATUS                status;
+    OEM_STRING              path;
+    PCHAR                   listresults;
+    PCHAR                   nextresults;
+    ULONG*                  noofnodes;
+    size_t                  stringarraysize;
+    UCHAR*                  valuepos;
+    PXENSTORE_SESSION       session;
+    char*                   tmppath;
+
+    status = STATUS_INVALID_DEVICE_REQUEST;
     if (!AccessWmiBuffer(InBuffer, TRUE, &RequiredSize, InBufferSize,
-                            WMI_STRING, &uloc,
-                            WMI_DONE)){
-        return  STATUS_INVALID_DEVICE_REQUEST;
-    }
-    if (!fdoData->InterfacesAcquired) {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
+                         WMI_STRING, &uloc,
+                         WMI_DONE))
+        goto fail1;
 
-    status = GetCountedUTF8String(&path, uloc);
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (!Fdo->InterfacesAcquired)
+        goto fail2;
 
-    if (!NT_SUCCESS(status)) {
-        return status;
-    }
+    status = GetCountedUTF8String(&path, uloc);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
     status = STATUS_INSUFFICIENT_RESOURCES;
     tmppath = WmiAllocate(path.Length + 1);
-    if (!tmppath) {
-        goto fail1;
-    }
+    if (tmppath == NULL)
+        goto fail4;
 
     RtlCopyBytes(tmppath, path.Buffer, path.Length);
 
     status = STATUS_WMI_INSTANCE_NOT_FOUND;
-    if ((session = FindSessionByInstanceAndLock(fdoData, instance)) ==
-            NULL){
-        goto fail2;
-    }
-    status = 
XENBUS_STORE(Directory,&fdoData->StoreInterface,session->transaction,NULL, 
tmppath, &listresults);
-    UnlockSessions(fdoData);
+    session = FindSessionByInstanceAndLock(Fdo, instance);
+    if (session == NULL)
+        goto fail5;
 
-    if (!NT_SUCCESS(status)) {
-        goto fail2;
-    }
+    status = XENBUS_STORE(Directory, &Fdo->StoreInterface, 
session->Transaction, NULL, tmppath, &listresults);
+    ReleaseMutex(&Fdo->SessionLock);
+
+    if (!NT_SUCCESS(status))
+        goto fail6;
 
     stringarraysize = 0;
 
@@ -2111,27 +2023,23 @@ SessionExecuteGetChildren(UCHAR *InBuffer,
 
     status = STATUS_BUFFER_TOO_SMALL;
     if (!AccessWmiBuffer(InBuffer, FALSE, &RequiredSize, OutBufferSize,
-                            WMI_UINT32, &noofnodes,
-                            WMI_STRING, stringarraysize, &valuepos,
-                            WMI_DONE)){
-        goto fail3;
-    }
+                         WMI_UINT32, &noofnodes,
+                         WMI_STRING, stringarraysize, &valuepos,
+                         WMI_DONE))
+        goto fail7;
 
-    status = STATUS_SUCCESS;
     nextresults = listresults;
     i = 0;
     while (*nextresults != 0) {
         PSTR fullpath;
-        if ((path.Length == 1) && (path.Buffer[0] == '/')) {
+        if ((path.Length == 1) && (path.Buffer[0] == '/'))
             fullpath = Xmasprintf("/%s", nextresults);
-        } else {
+        else
             fullpath = Xmasprintf("%s/%s", path.Buffer, nextresults);
-        }
 
-        if (fullpath == NULL) {
-            status = STATUS_NO_MEMORY;
-            goto fail4;
-        }
+        status = STATUS_NO_MEMORY;
+        if (fullpath == NULL)
+            goto fail8;
 
         WriteCountedUTF8String(fullpath, valuepos);
         valuepos += GetCountedUtf8Size(fullpath);
@@ -2144,562 +2052,626 @@ SessionExecuteGetChildren(UCHAR *InBuffer,
     }
     *noofnodes = i;
 
+    XENBUS_STORE(Free, &Fdo->StoreInterface, listresults);
+    WmiFree(tmppath);
+    FreeUTF8String(&path);
+
+    *BytesWritten = RequiredSize;
+    return STATUS_SUCCESS;
+
+fail8:
+fail7:
+    XENBUS_STORE(Free, &Fdo->StoreInterface, listresults);
+    *BytesWritten = RequiredSize;
+fail6:
+fail5:
+    WmiFree(tmppath);
 fail4:
+    FreeUTF8String(&path);
 fail3:
-    XENBUS_STORE(Free, &fdoData->StoreInterface, listresults);
-
 fail2:
-    WmiFree(tmppath);
-
 fail1:
-    FreeUTF8String(&path);
-    *byteswritten = RequiredSize;
     return status;
 }
 
+static NTSTATUS
+SessionExecuteLog(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  PUNICODE_STRING instance,
+    IN  UCHAR*          InBuffer,
+    IN  ULONG           InBufferSize,
+    IN  UCHAR*          OutBuffer,
+    IN  ULONG           OutBufferSize,
+    OUT ULONG_PTR*      BytesWritten
+    )
+{
+    ULONG               RequiredSize;
+    UCHAR*              uloc;
+    NTSTATUS            status;
+    ANSI_STRING         message;
 
-NTSTATUS
-SessionExecuteLog(UCHAR *InBuffer,
-                        ULONG InBufferSize,
-                        UCHAR *OutBuffer,
-                        ULONG OutBufferSize,
-                        XENIFACE_FDO* fdoData,
-                        UNICODE_STRING *instance,
-                        OUT ULONG_PTR *byteswritten) {
-
-    ULONG RequiredSize;
-    UCHAR *uloc;
-    NTSTATUS status;
-    ANSI_STRING message;
+    *BytesWritten = 0;
+    status = STATUS_INVALID_DEVICE_REQUEST;
     if (!AccessWmiBuffer(InBuffer, TRUE, &RequiredSize, InBufferSize,
-                                            WMI_STRING, &uloc,
-                                            WMI_DONE))
-        return STATUS_INVALID_DEVICE_REQUEST;
+                         WMI_STRING, &uloc,
+                         WMI_DONE))
+        goto fail1;
 
     status = GetCountedAnsiString(&message, uloc);
-
     if (!NT_SUCCESS(status))
-        return status;
+        goto fail2;
 
     Info("USER: %s\n", message.Buffer);
 
     RtlFreeAnsiString(&message);
-    *byteswritten = 0;
+
     return STATUS_SUCCESS;
 
+fail2:
+fail1:
+    return status;
 }
 
-NTSTATUS
-SessionExecuteStartTransaction(UCHAR *InBuffer,
-                        ULONG InBufferSize,
-                        UCHAR *OutBuffer,
-                        ULONG OutBufferSize,
-                        XENIFACE_FDO* fdoData,
-                        UNICODE_STRING *instance,
-                        OUT ULONG_PTR *byteswritten) {
-
-    NTSTATUS status = STATUS_SUCCESS;
-    XenStoreSession *session;
-
-    if (!fdoData->InterfacesAcquired) {
-        status= STATUS_INSUFFICIENT_RESOURCES;
-        goto failnotinitialised;
-    }
-    if ((session = FindSessionByInstanceAndLock(fdoData, instance)) ==
-            NULL){
-        status= STATUS_WMI_INSTANCE_NOT_FOUND;
-        goto failsessionnotfound;
-    }
+static NTSTATUS
+SessionExecuteStartTransaction(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  PUNICODE_STRING instance,
+    IN  UCHAR*          InBuffer,
+    IN  ULONG           InBufferSize,
+    IN  UCHAR*          OutBuffer,
+    IN  ULONG           OutBufferSize,
+    OUT ULONG_PTR*      BytesWritten
+    )
+{
+    NTSTATUS            status;
+    PXENSTORE_SESSION   session;
 
-    if (session->transaction!=NULL) {
-        status = STATUS_REQUEST_OUT_OF_SEQUENCE;
-        goto failtransactionactive;
-    }
+    *BytesWritten = 0;
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (!Fdo->InterfacesAcquired)
+        goto fail1;
+
+    session = FindSessionByInstanceAndLock(Fdo, instance);
+    status = STATUS_WMI_INSTANCE_NOT_FOUND;
+    if (session == NULL)
+        goto fail2;
 
-    XENBUS_STORE(TransactionStart, &fdoData->StoreInterface, 
&session->transaction);
+    status = STATUS_REQUEST_OUT_OF_SEQUENCE;
+    if (session->Transaction != NULL)
+        goto fail3;
 
+    XENBUS_STORE(TransactionStart, &Fdo->StoreInterface, 
&session->Transaction);
 
-failtransactionactive:
-    UnlockSessions(fdoData);
-failsessionnotfound:
-failnotinitialised:
+    ReleaseMutex(&Fdo->SessionLock);
 
-    *byteswritten = 0;
-    return status;
+    return STATUS_SUCCESS;
 
+fail3:
+    ReleaseMutex(&Fdo->SessionLock);
+fail2:
+fail1:
+    return status;
 }
-NTSTATUS
-SessionExecuteCommitTransaction(UCHAR *InBuffer,
-                        ULONG InBufferSize,
-                        UCHAR *OutBuffer,
-                        ULONG OutBufferSize,
-                        XENIFACE_FDO* fdoData,
-                        UNICODE_STRING *instance,
-                        OUT ULONG_PTR *byteswritten) {
-
-    NTSTATUS status = STATUS_SUCCESS;
-    XenStoreSession *session;
-
-    if (!fdoData->InterfacesAcquired) {
-        status= STATUS_INSUFFICIENT_RESOURCES;
-        goto failnotinitialised;
-    }
-    if ((session = FindSessionByInstanceAndLock(fdoData, instance)) ==
-            NULL){
-        status= STATUS_WMI_INSTANCE_NOT_FOUND;
-        goto failsessionnotfound;
-    }
 
-    if (session->transaction==NULL) {
-        status = STATUS_REQUEST_OUT_OF_SEQUENCE;
-        goto failtransactionnotactive;
-    }
+static NTSTATUS
+SessionExecuteCommitTransaction(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  PUNICODE_STRING instance,
+    IN  UCHAR*          InBuffer,
+    IN  ULONG           InBufferSize,
+    IN  UCHAR*          OutBuffer,
+    IN  ULONG           OutBufferSize,
+    OUT ULONG_PTR*      BytesWritten
+    )
+{
+    NTSTATUS            status;
+    PXENSTORE_SESSION   session;
+
+    *BytesWritten = 0;
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (!Fdo->InterfacesAcquired)
+        goto fail1;
 
-    status = XENBUS_STORE(TransactionEnd,&fdoData->StoreInterface, 
session->transaction, TRUE);
+    session = FindSessionByInstanceAndLock(Fdo, instance);
+    status = STATUS_WMI_INSTANCE_NOT_FOUND;
+    if (session == NULL)
+        goto fail2;
+
+    status = STATUS_REQUEST_OUT_OF_SEQUENCE;
+    if (session->Transaction == NULL)
+        goto fail3;
 
-    session->transaction = NULL;
+    status = XENBUS_STORE(TransactionEnd, &Fdo->StoreInterface, 
session->Transaction, TRUE);
+    session->Transaction = NULL;
 
-failtransactionnotactive:
-    UnlockSessions(fdoData);
-failsessionnotfound:
-failnotinitialised:
+    if (!NT_SUCCESS(status))
+        goto fail4;
 
-    *byteswritten = 0;
-    return status;
+    ReleaseMutex(&Fdo->SessionLock);
 
+    return STATUS_SUCCESS;
+
+fail4:
+fail3:
+    ReleaseMutex(&Fdo->SessionLock);
+fail2:
+fail1:
+    return status;
 }
-NTSTATUS
-SessionExecuteAbortTransaction(UCHAR *InBuffer,
-                        ULONG InBufferSize,
-                        UCHAR *OutBuffer,
-                        ULONG OutBufferSize,
-                        XENIFACE_FDO* fdoData,
-                        UNICODE_STRING *instance,
-                        OUT ULONG_PTR *byteswritten) {
-
-    NTSTATUS status = STATUS_SUCCESS;
-    XenStoreSession *session;
-
-    if (!fdoData->InterfacesAcquired) {
-        status= STATUS_INSUFFICIENT_RESOURCES;
-        goto failnotinitialised;
-    }
-    if ((session = FindSessionByInstanceAndLock(fdoData, instance)) ==
-            NULL){
-        status= STATUS_WMI_INSTANCE_NOT_FOUND;
-        goto failsessionnotfound;
-    }
 
-    if (session->transaction==NULL) {
-        status = STATUS_REQUEST_OUT_OF_SEQUENCE;
-        goto failtransactionnotactive;
-    }
+static NTSTATUS
+SessionExecuteAbortTransaction(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  PUNICODE_STRING instance,
+    IN  UCHAR*          InBuffer,
+    IN  ULONG           InBufferSize,
+    IN  UCHAR*          OutBuffer,
+    IN  ULONG           OutBufferSize,
+    OUT ULONG_PTR*      BytesWritten
+    )
+{
+    NTSTATUS            status;
+    PXENSTORE_SESSION   session;
 
-    status = XENBUS_STORE(TransactionEnd, &fdoData->StoreInterface, 
session->transaction, FALSE);
+    *BytesWritten = 0;
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (!Fdo->InterfacesAcquired)
+        goto fail1;
+
+    session = FindSessionByInstanceAndLock(Fdo, instance);
+    status = STATUS_WMI_INSTANCE_NOT_FOUND;
+    if (session == NULL)
+        goto fail2;
 
-    session->transaction = NULL;
+    status = STATUS_REQUEST_OUT_OF_SEQUENCE;
+    if (session->Transaction == NULL)
+        goto fail3;
 
-failtransactionnotactive:
-    UnlockSessions(fdoData);
-failsessionnotfound:
-failnotinitialised:
+    status = XENBUS_STORE(TransactionEnd, &Fdo->StoreInterface, 
session->Transaction, FALSE);
+    session->Transaction = NULL;
 
-    *byteswritten = 0;
-    return status;
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    ReleaseMutex(&Fdo->SessionLock);
+
+    return STATUS_SUCCESS;
 
+fail4:
+fail3:
+    ReleaseMutex(&Fdo->SessionLock);
+fail2:
+fail1:
+    return status;
 }
 
-NTSTATUS
-SessionExecuteGetValue(UCHAR *InBuffer,
-                        ULONG InBufferSize,
-                        UCHAR *OutBuffer,
-                        ULONG OutBufferSize,
-                        XENIFACE_FDO* fdoData,
-                        UNICODE_STRING *instance,
-                        OUT ULONG_PTR *byteswritten) {
-    NTSTATUS status;
-    OEM_STRING path;
-    UCHAR *uloc;
-    char *value;
-    UCHAR *valuepos;
-    char *tmppath;
-    ULONG RequiredSize;
-    XenStoreSession *session;
-
-    *byteswritten = 0;
+static NTSTATUS
+SessionExecuteGetValue(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  PUNICODE_STRING instance,
+    IN  UCHAR*          InBuffer,
+    IN  ULONG           InBufferSize,
+    IN  UCHAR*          OutBuffer,
+    IN  ULONG           OutBufferSize,
+    OUT ULONG_PTR*      BytesWritten
+    )
+{
+    NTSTATUS            status;
+    OEM_STRING          path;
+    UCHAR*              uloc;
+    char*               value;
+    UCHAR*              valuepos;
+    char*               tmppath;
+    ULONG               RequiredSize;
+    PXENSTORE_SESSION   session;
+
+    *BytesWritten = 0;
+    status = STATUS_INVALID_DEVICE_REQUEST;
     if (!AccessWmiBuffer(InBuffer, TRUE, &RequiredSize, InBufferSize,
-                                            WMI_STRING, &uloc,
-                                            WMI_DONE))
-        return STATUS_INVALID_DEVICE_REQUEST;
-    if (!fdoData->InterfacesAcquired) {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
+                         WMI_STRING, &uloc,
+                         WMI_DONE))
+        goto fail1;
 
-    status = GetCountedUTF8String(&path, uloc);
+    status = STATUS_INSUFFICIENT_RESOURCES;
+    if (!Fdo->InterfacesAcquired)
+        goto fail2;
 
+    status = GetCountedUTF8String(&path, uloc);
     if (!NT_SUCCESS(status))
-        return status;;
+        goto fail3;
 
     status = STATUS_INSUFFICIENT_RESOURCES;
     tmppath = WmiAllocate(path.Length + 1);
-    if (!tmppath) {
-        goto fail1;
-    }
+    if (tmppath == NULL)
+        goto fail4;
 
     RtlCopyBytes(tmppath, path.Buffer, path.Length);
 
     status = STATUS_WMI_INSTANCE_NOT_FOUND;
-    if ((session = FindSessionByInstanceAndLock(fdoData, instance)) ==
-            NULL){
-        goto fail2;
-    }
-    status = XENBUS_STORE(Read, &fdoData->StoreInterface, 
session->transaction, NULL, tmppath, &value);
-    UnlockSessions(fdoData);
+    session = FindSessionByInstanceAndLock(Fdo, instance);
+    if (session == NULL)
+        goto fail5;
+
+    status = XENBUS_STORE(Read, &Fdo->StoreInterface, session->Transaction, 
NULL, tmppath, &value);
+    ReleaseMutex(&Fdo->SessionLock);
 
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail6;
 
     status = STATUS_BUFFER_TOO_SMALL;
     if (!AccessWmiBuffer(OutBuffer, FALSE, &RequiredSize, OutBufferSize,
-                            WMI_STRING, GetCountedUtf8Size(value), &valuepos,
-                            WMI_DONE)) {
-        goto fail3;
-    }
-    status = STATUS_SUCCESS;
-    WriteCountedUTF8String(value, valuepos);
+                         WMI_STRING, GetCountedUtf8Size(value), &valuepos,
+                         WMI_DONE))
+        goto fail7;
 
-fail3:
-    XENBUS_STORE(Free, &fdoData->StoreInterface, value);
-    *byteswritten = RequiredSize;
+    WriteCountedUTF8String(value, valuepos);
 
-fail2:
+    XENBUS_STORE(Free, &Fdo->StoreInterface, value);
     WmiFree(tmppath);
+    FreeUTF8String(&path);
 
-fail1:
+    *BytesWritten = RequiredSize;
+    return STATUS_SUCCESS;
+
+fail7:
+    XENBUS_STORE(Free, &Fdo->StoreInterface, value);
+    *BytesWritten = RequiredSize;
+fail6:
+fail5:
+    WmiFree(tmppath);
+fail4:
     FreeUTF8String(&path);
+fail3:
+fail2:
+fail1:
     return status;
 }
-NTSTATUS
-BaseExecuteAddSession(UCHAR *InBuffer,
-                        ULONG InBufferSize,
-                        UCHAR *OutBuffer,
-                        ULONG OutBufferSize,
-                        XENIFACE_FDO* fdoData,
-                        OUT ULONG_PTR *byteswritten) {
-    ULONG RequiredSize;
-    UNICODE_STRING ustring;
-    ULONG *id;
-    UCHAR* stringid;
-    NTSTATUS status;
-    *byteswritten = 0;
+
+static NTSTATUS
+BaseExecuteAddSession(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  UCHAR*          InBuffer,
+    IN  ULONG           InBufferSize,
+    IN  UCHAR*          OutBuffer,
+    IN  ULONG           OutBufferSize,
+    OUT ULONG_PTR*      BytesWritten
+    )
+{
+    ULONG               RequiredSize;
+    UNICODE_STRING      ustring;
+    ULONG*              id;
+    UCHAR*              StringId;
+    NTSTATUS            status;
+
+    *BytesWritten = 0;
+    status = STATUS_INVALID_DEVICE_REQUEST;
     if (!AccessWmiBuffer(InBuffer, TRUE, &RequiredSize, InBufferSize,
-                            WMI_STRING, &stringid,
-                            WMI_DONE)){
-        return STATUS_INVALID_DEVICE_REQUEST;
-    }
+                         WMI_STRING, &StringId,
+                         WMI_DONE))
+        goto fail1;
+
+    status = STATUS_BUFFER_TOO_SMALL;
     if (!AccessWmiBuffer(OutBuffer, FALSE, &RequiredSize, OutBufferSize,
-                            WMI_UINT32, &id,
-                            WMI_DONE)) {
-        *byteswritten = RequiredSize;
-        return STATUS_BUFFER_TOO_SMALL;
-    }
+                         WMI_UINT32, &id,
+                         WMI_DONE))
+        goto fail2;
 
-    AllocUnicodeStringBuffer(&ustring, *(USHORT*)(stringid));
+    AllocUnicodeStringBuffer(&ustring, *(USHORT*)(StringId));
+    status = STATUS_INSUFFICIENT_RESOURCES;
     if (ustring.Buffer == NULL)
-        return STATUS_INSUFFICIENT_RESOURCES;
+        goto fail3;
+
     status = RtlUnicodeStringCbCopyStringN(&ustring,
-                                            (LPCWSTR)(stringid+sizeof(USHORT)),
-                                            *(USHORT*)(stringid));
-    if (!NT_SUCCESS(status)) {
-        FreeUnicodeStringBuffer(&ustring);
-        return status;
-    }
-    status = CreateNewSession(fdoData, &ustring, id);
-    if (!NT_SUCCESS(status)) {
-        FreeUnicodeStringBuffer(&ustring);
-        return status;
-    }
+                                           (LPCWSTR)(StringId + 
sizeof(USHORT)),
+                                           *(USHORT*)(StringId));
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    status = SessionCreate(Fdo, &ustring, id);
+    if (!NT_SUCCESS(status))
+        goto fail5;
 
-    *byteswritten = RequiredSize;
+    *BytesWritten = RequiredSize;
     return STATUS_SUCCESS;
 
+fail5:
+fail4:
+    FreeUnicodeStringBuffer(&ustring);
+fail3:
+fail2:
+    *BytesWritten = RequiredSize;
+fail1:
+    return status;
 }
 
+static NTSTATUS
+SessionExecuteMethod(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  UCHAR*          Buffer,
+    IN  ULONG           BufferSize,
+    OUT ULONG_PTR*      BytesWritten
+    )
+{
+    ULONG               RequiredSize;
+    WNODE_METHOD_ITEM*  Method;
+    UCHAR*              InBuffer;
+    NTSTATUS            status;
+    UNICODE_STRING      instance;
+    UCHAR*              InstStr;
 
-NTSTATUS
-SessionExecuteMethod(UCHAR *Buffer,
-                    ULONG BufferSize,
-                    XENIFACE_FDO* fdoData,
-                    OUT ULONG_PTR *byteswritten) {
-    ULONG RequiredSize;
-    WNODE_METHOD_ITEM *Method;
-    UCHAR *InBuffer;
-    NTSTATUS status;
-    UNICODE_STRING instance;
-    UCHAR *InstStr;
-    Trace("%s\n",__FUNCTION__);
     if (!AccessWmiBuffer(Buffer, TRUE, &RequiredSize, BufferSize,
-                            WMI_BUFFER, sizeof(WNODE_METHOD_ITEM),
-                                &Method,
-                            WMI_DONE))
-    {
+                         WMI_BUFFER, sizeof(WNODE_METHOD_ITEM), &Method,
+                         WMI_DONE))
         return STATUS_INVALID_DEVICE_REQUEST;
-    }
+
     if (!AccessWmiBuffer(Buffer, TRUE, &RequiredSize, BufferSize,
-                            WMI_BUFFER, sizeof(WNODE_METHOD_ITEM),
-                                &Method,
-                            WMI_STRINGOFFSET, Method->OffsetInstanceName,
-                                &InstStr,
-                            WMI_DONE))
-    {
+                         WMI_BUFFER, sizeof(WNODE_METHOD_ITEM), &Method,
+                         WMI_STRINGOFFSET, Method->OffsetInstanceName, 
&InstStr,
+                         WMI_DONE))
         return STATUS_INVALID_DEVICE_REQUEST;
-    }
 
     InBuffer = Buffer + Method->DataBlockOffset;
 
     GetCountedUnicodeString(&instance, InstStr);
 
-
-    Trace("Method Id %d\n", Method->MethodId);
     switch (Method->MethodId) {
-        case GetValue:
-            status = SessionExecuteGetValue(InBuffer, Method->SizeDataBlock,
-                                              Buffer+Method->DataBlockOffset,
-                                              
BufferSize-Method->DataBlockOffset,
-                                              fdoData,
-                                              &instance,
-                                              byteswritten);
-            break;
-        case SetValue:
-            status = SessionExecuteSetValue(InBuffer, Method->SizeDataBlock,
-                                              Buffer+Method->DataBlockOffset,
-                                              
BufferSize-Method->DataBlockOffset,
-                                              fdoData,
-                                              &instance,
-                                              byteswritten);
-            break;
-        case GetChildren:
-            status = SessionExecuteGetChildren(InBuffer, Method->SizeDataBlock,
-                                              Buffer+Method->DataBlockOffset,
-                                              
BufferSize-Method->DataBlockOffset,
-                                              fdoData,
-                                              &instance,
-                                              byteswritten);
-            break;
-        case SetWatch:
-            status = SessionExecuteSetWatch(InBuffer, Method->SizeDataBlock,
-                                              Buffer+Method->DataBlockOffset,
-                                              
BufferSize-Method->DataBlockOffset,
-                                              fdoData,
-                                              &instance,
-                                              byteswritten);
-            break;
-        case EndSession:
-            status = SessionExecuteEndSession(InBuffer, Method->SizeDataBlock,
-                                              Buffer+Method->DataBlockOffset,
-                                              
BufferSize-Method->DataBlockOffset,
-                                              fdoData,
-                                              &instance,
-                                              byteswritten);
-            break;
-        case RemoveWatch:
-            status = SessionExecuteRemoveWatch(InBuffer, Method->SizeDataBlock,
-                                              Buffer+Method->DataBlockOffset,
-                                              
BufferSize-Method->DataBlockOffset,
-                                              fdoData,
+    case GetValue:
+        status = SessionExecuteGetValue(Fdo,
+                                        &instance,
+                                        InBuffer,
+                                        Method->SizeDataBlock,
+                                        Buffer + Method->DataBlockOffset,
+                                        BufferSize - Method->DataBlockOffset,
+                                        BytesWritten);
+        break;
+    case SetValue:
+        status = SessionExecuteSetValue(Fdo,
+                                        &instance,
+                                        InBuffer,
+                                        Method->SizeDataBlock,
+                                        Buffer + Method->DataBlockOffset,
+                                        BufferSize - Method->DataBlockOffset,
+                                        BytesWritten);
+        break;
+    case GetChildren:
+        status = SessionExecuteGetChildren(Fdo,
+                                           &instance,
+                                           InBuffer,
+                                           Method->SizeDataBlock,
+                                           Buffer + Method->DataBlockOffset,
+                                           BufferSize - 
Method->DataBlockOffset,
+                                           BytesWritten);
+        break;
+    case SetWatch:
+        status = SessionExecuteSetWatch(Fdo,
+                                        &instance,
+                                        InBuffer, Method->SizeDataBlock,
+                                        Buffer + Method->DataBlockOffset,
+                                        BufferSize - Method->DataBlockOffset,
+                                        BytesWritten);
+        break;
+    case EndSession:
+        status = SessionExecuteEndSession(Fdo,
+                                          &instance,
+                                          InBuffer,
+                                          Method->SizeDataBlock,
+                                          Buffer + Method->DataBlockOffset,
+                                          BufferSize - Method->DataBlockOffset,
+                                          BytesWritten);
+        break;
+    case RemoveWatch:
+        status = SessionExecuteRemoveWatch(Fdo,
+                                           &instance,
+                                           InBuffer,
+                                           Method->SizeDataBlock,
+                                           Buffer + Method->DataBlockOffset,
+                                           BufferSize - 
Method->DataBlockOffset,
+                                           BytesWritten);
+        break;
+    case RemoveValue:
+        status = SessionExecuteRemoveValue(Fdo,
+                                           &instance,
+                                           InBuffer,
+                                           Method->SizeDataBlock,
+                                           Buffer + Method->DataBlockOffset,
+                                           BufferSize - 
Method->DataBlockOffset,
+                                           BytesWritten);
+        break;
+    case Log:
+        status = SessionExecuteLog(Fdo,
+                                   &instance,
+                                   InBuffer,
+                                   Method->SizeDataBlock,
+                                   Buffer + Method->DataBlockOffset,
+                                   BufferSize - Method->DataBlockOffset,
+                                   BytesWritten);
+        break;
+    case StartTransaction:
+        status = SessionExecuteStartTransaction(Fdo,
+                                                &instance,
+                                                InBuffer,
+                                                Method->SizeDataBlock,
+                                                Buffer + 
Method->DataBlockOffset,
+                                                BufferSize - 
Method->DataBlockOffset,
+                                                BytesWritten);
+        break;
+    case CommitTransaction:
+        status = SessionExecuteCommitTransaction(Fdo,
+                                                 &instance,
+                                                 InBuffer,
+                                                 Method->SizeDataBlock,
+                                                 Buffer + 
Method->DataBlockOffset,
+                                                 BufferSize - 
Method->DataBlockOffset,
+                                                 BytesWritten);
+        break;
+    case AbortTransaction:
+        status = SessionExecuteAbortTransaction(Fdo,
+                                                &instance,
+                                                InBuffer,
+                                                Method->SizeDataBlock,
+                                                Buffer + 
Method->DataBlockOffset,
+                                                BufferSize - 
Method->DataBlockOffset,
+                                                BytesWritten);
+        break;
+    case GetFirstChild:
+        status = SessionExecuteGetFirstChild(Fdo,
+                                             &instance,
+                                             InBuffer,
+                                             Method->SizeDataBlock,
+                                             Buffer + Method->DataBlockOffset,
+                                             BufferSize - 
Method->DataBlockOffset,
+                                             BytesWritten);
+        break;
+    case GetNextSibling:
+        status = SessionExecuteGetNextSibling(Fdo,
                                               &instance,
-                                              byteswritten);
-            break;
-        case RemoveValue:
-            status = SessionExecuteRemoveValue(InBuffer, Method->SizeDataBlock,
-                                              Buffer+Method->DataBlockOffset,
-                                              
BufferSize-Method->DataBlockOffset,
-                                              fdoData,
-                                              &instance,
-                                              byteswritten);
-            break;
-        case Log:
-            status = SessionExecuteLog(InBuffer,  Method->SizeDataBlock,
-                                              Buffer+Method->DataBlockOffset,
-                                              
BufferSize-Method->DataBlockOffset,
-                                              fdoData,
-                                              &instance,
-                                              byteswritten);
-            break;
-        case StartTransaction:
-            status = SessionExecuteStartTransaction(InBuffer,  
Method->SizeDataBlock,
-                                              Buffer+Method->DataBlockOffset,
-                                              
BufferSize-Method->DataBlockOffset,
-                                              fdoData,
-                                              &instance,
-                                              byteswritten);
-            break;
-        case CommitTransaction:
-            status = SessionExecuteCommitTransaction(InBuffer,  
Method->SizeDataBlock,
-                                              Buffer+Method->DataBlockOffset,
-                                              
BufferSize-Method->DataBlockOffset,
-                                              fdoData,
-                                              &instance,
-                                              byteswritten);
-            break;
-        case AbortTransaction:
-            status = SessionExecuteAbortTransaction(InBuffer,  
Method->SizeDataBlock,
-                                              Buffer+Method->DataBlockOffset,
-                                              
BufferSize-Method->DataBlockOffset,
-                                              fdoData,
-                                              &instance,
-                                              byteswritten);
-            break;
-        case GetFirstChild:
-            status = SessionExecuteGetFirstChild(InBuffer,  
Method->SizeDataBlock,
-                                              Buffer+Method->DataBlockOffset,
-                                              
BufferSize-Method->DataBlockOffset,
-                                              fdoData,
-                                              &instance,
-                                              byteswritten);
-            break;
-        case GetNextSibling:
-            status = SessionExecuteGetNextSibling(InBuffer,  
Method->SizeDataBlock,
-                                              Buffer+Method->DataBlockOffset,
-                                              
BufferSize-Method->DataBlockOffset,
-                                              fdoData,
-                                              &instance,
-                                              byteswritten);
-            break;
-
-
-        default:
-            Info("DRV: Unknown WMI method %d\n", Method->MethodId);
-            return STATUS_WMI_ITEMID_NOT_FOUND;
-    }
-    Method->SizeDataBlock = (ULONG)*byteswritten;
-    *byteswritten+=Method->DataBlockOffset;
-    if (status == STATUS_BUFFER_TOO_SMALL) {
-        return NodeTooSmall(Buffer, BufferSize, (ULONG)*byteswritten, 
byteswritten);
+                                              InBuffer,
+                                              Method->SizeDataBlock,
+                                              Buffer + Method->DataBlockOffset,
+                                              BufferSize - 
Method->DataBlockOffset,
+                                              BytesWritten);
+        break;
+    default:
+        Info("DRV: Unknown WMI method %d\n", Method->MethodId);
+        return STATUS_WMI_ITEMID_NOT_FOUND;
     }
 
-    Method->WnodeHeader.BufferSize = (ULONG)*byteswritten;
-     return status;
+    Method->SizeDataBlock = (ULONG)*BytesWritten;
+    *BytesWritten += Method->DataBlockOffset;
+    if (status == STATUS_BUFFER_TOO_SMALL)
+        return NodeTooSmall(Buffer, BufferSize, (ULONG)*BytesWritten, 
BytesWritten);
+
+    Method->WnodeHeader.BufferSize = (ULONG)*BytesWritten;
+    return status;
 }
-NTSTATUS
-BaseExecuteMethod(UCHAR *Buffer,
-                    ULONG BufferSize,
-                    XENIFACE_FDO* fdoData,
-                    OUT ULONG_PTR *byteswritten) {
-    ULONG RequiredSize;
-    WNODE_METHOD_ITEM *Method;
-    UCHAR *InBuffer;
-    NTSTATUS status;
+
+static NTSTATUS
+BaseExecuteMethod(
+    IN  PXENIFACE_FDO       Fdo,
+    IN  UCHAR*              Buffer,
+    IN  ULONG               BufferSize,
+    OUT ULONG_PTR*          BytesWritten
+    )
+{
+    ULONG                   RequiredSize;
+    WNODE_METHOD_ITEM*      Method;
+    UCHAR*                  InBuffer;
+    NTSTATUS                status;
+
     if (!AccessWmiBuffer(Buffer, TRUE, &RequiredSize, BufferSize,
-                            WMI_BUFFER, sizeof(WNODE_METHOD_ITEM),
-                                &Method,
-                            WMI_DONE))
-    {
+                         WMI_BUFFER, sizeof(WNODE_METHOD_ITEM), &Method,
+                         WMI_DONE))
         return STATUS_INVALID_DEVICE_REQUEST;
-    }
 
     InBuffer = Buffer + Method->DataBlockOffset;
 
     switch (Method->MethodId) {
-        case AddSession:
-            status = BaseExecuteAddSession(InBuffer, Method->SizeDataBlock,
-                                             Buffer+Method->DataBlockOffset,
-                                             
BufferSize-Method->DataBlockOffset,
-                                             fdoData,
-                                             byteswritten);
-            Method->SizeDataBlock = (ULONG)*byteswritten;
-            *byteswritten+=Method->DataBlockOffset;
-            Method->WnodeHeader.BufferSize = (ULONG)*byteswritten;
-            return status;
+    case AddSession:
+        status = BaseExecuteAddSession(Fdo,
+                                       InBuffer,
+                                       Method->SizeDataBlock,
+                                       Buffer + Method->DataBlockOffset,
+                                       BufferSize - Method->DataBlockOffset,
+                                       BytesWritten);
+        break;
 
-        default:
-            return STATUS_WMI_ITEMID_NOT_FOUND;
+    default:
+        return STATUS_WMI_ITEMID_NOT_FOUND;
     }
+
+    Method->SizeDataBlock = (ULONG)*BytesWritten;
+    *BytesWritten += Method->DataBlockOffset;
+    Method->WnodeHeader.BufferSize = (ULONG)*BytesWritten;
+
+    return status;
 }
 
-NTSTATUS
+static NTSTATUS
 WmiExecuteMethod(
-    IN PXENIFACE_FDO fdoData,
-    IN PIO_STACK_LOCATION stack,
-    OUT ULONG_PTR *byteswritten
-   )
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PIO_STACK_LOCATION  Stack,
+    OUT ULONG_PTR*          BytesWritten
+    )
 {
-    if (IsEqualGUID(stack->Parameters.WMI.DataPath,
-                    &OBJECT_GUID(XenStoreBase))) {
-        return BaseExecuteMethod(stack->Parameters.WMI.Buffer,
-                                    stack->Parameters.WMI.BufferSize,
-                                    fdoData,  byteswritten);
-    }
-    else if (IsEqualGUID(stack->Parameters.WMI.DataPath,
-                         &OBJECT_GUID(XenStoreSession))) {
-        return SessionExecuteMethod(stack->Parameters.WMI.Buffer,
-                                    stack->Parameters.WMI.BufferSize,
-                                    fdoData,  byteswritten);
-    }
+    if (IsEqualGUID(Stack->Parameters.WMI.DataPath,
+                    &OBJECT_GUID(XenStoreBase)))
+        return BaseExecuteMethod(Fdo,
+                                 Stack->Parameters.WMI.Buffer,
+                                 Stack->Parameters.WMI.BufferSize,
+                                 BytesWritten);
+
+    if (IsEqualGUID(Stack->Parameters.WMI.DataPath,
+                    &OBJECT_GUID(XenStoreSession)))
+        return SessionExecuteMethod(Fdo,
+                                    Stack->Parameters.WMI.Buffer,
+                                    Stack->Parameters.WMI.BufferSize,
+                                    BytesWritten);
 
-    else
-        return STATUS_NOT_SUPPORTED;
+    return STATUS_NOT_SUPPORTED;
 }
 
-NTSTATUS
-GenerateSessionBlock(UCHAR *Buffer,
-                        ULONG BufferSize,
-                        PXENIFACE_FDO fdoData,
-                        ULONG_PTR *byteswritten) {
-    WNODE_ALL_DATA *node;
-    ULONG RequiredSize;
-    size_t nodesizerequired;
-    size_t namesizerequired;
-    int entries;
-    XenStoreSession *session;
+static NTSTATUS
+GenerateSessionBlock(
+    IN  PXENIFACE_FDO       Fdo,
+    IN  UCHAR*              Buffer,
+    IN  ULONG               BufferSize,
+    OUT ULONG_PTR*          BytesWritten
+    )
+{
+    PLIST_ENTRY             ListEntry;
+    PXENSTORE_SESSION       Session;
+    WNODE_ALL_DATA*         node;
+    ULONG                   RequiredSize;
+    size_t                  nodesizerequired;
+    size_t                  namesizerequired;
+    int                     entries;
     OFFSETINSTANCEDATAANDLENGTH* dataoffsets;
-    ULONG* nameoffsets;
-    UCHAR *data;
-    UCHAR *names;
+    ULONG*                  nameoffsets;
+    UCHAR*                  data;
+    UCHAR*                  names;
+    int                     entrynum = 0;
+    UCHAR*                  datapos;
+    UCHAR*                  namepos;
 
-
-    LockSessions(fdoData);
+    AcquireMutex(&Fdo->SessionLock);
 
     //work out how much space we need for each session structure
     nodesizerequired = 0;
     namesizerequired = 0;
     entries = 0;
-    session = (XenStoreSession *)fdoData->SessionHead.Flink;
-    //work out names for each session entry
-    while (session !=  (XenStoreSession *)&fdoData->SessionHead) {
+
+    for (ListEntry = Fdo->SessionHead.Flink;
+         ListEntry != &Fdo->SessionHead;
+         ListEntry = ListEntry->Flink) {
         ULONG *id;
         UCHAR *sesbuf;
         UCHAR *inamebuf;
 
+        Session = CONTAINING_RECORD(ListEntry, XENSTORE_SESSION, ListEntry);
+
         (VOID) AccessWmiBuffer((PUCHAR)nodesizerequired, FALSE, &RequiredSize, 
0,
                         WMI_UINT32, &id,
-                        WMI_STRING,
-                            GetCountedUnicodeStringSize(&session->stringid),
-                            &sesbuf,
+                        WMI_STRING, 
GetCountedUnicodeStringSize(&Session->StringId), &sesbuf,
                         WMI_DONE);
         nodesizerequired += RequiredSize;
 
         (VOID) AccessWmiBuffer((PUCHAR)namesizerequired, FALSE, &RequiredSize, 
0,
-                        WMI_STRING,
-                            
GetCountedUnicodeStringSize(&session->instancename),
-                            &inamebuf,
+                        WMI_STRING, 
GetCountedUnicodeStringSize(&Session->InstanceName), &inamebuf,
                         WMI_DONE);
         namesizerequired += RequiredSize;
         entries++;
-        session = (XenStoreSession *)session->listentry.Flink;
     }
 
-    //perform the access check
+    // perform the access check
     if (!AccessWmiBuffer(Buffer, FALSE, &RequiredSize, BufferSize,
-                            WMI_BUFFER, sizeof(WNODE_ALL_DATA), &node,
-                            WMI_BUFFER, sizeof(OFFSETINSTANCEDATAANDLENGTH)*
-                                            entries, &dataoffsets,
-                            WMI_BUFFER, sizeof(ULONG)*entries, &nameoffsets,
-                            WMI_BUFFER, nodesizerequired, &data,
-                            WMI_BUFFER, namesizerequired, &names,
-                            WMI_DONE)) {
-        UnlockSessions(fdoData);
-        return NodeTooSmall(Buffer, BufferSize, RequiredSize, byteswritten);
+                         WMI_BUFFER, sizeof(WNODE_ALL_DATA), &node,
+                         WMI_BUFFER, sizeof(OFFSETINSTANCEDATAANDLENGTH) * 
entries, &dataoffsets,
+                         WMI_BUFFER, sizeof(ULONG)*entries, &nameoffsets,
+                         WMI_BUFFER, nodesizerequired, &data,
+                         WMI_BUFFER, namesizerequired, &names,
+                         WMI_DONE)) {
+        ReleaseMutex(&Fdo->SessionLock);
+        return NodeTooSmall(Buffer, BufferSize, RequiredSize, BytesWritten);
     }
 
     node->DataBlockOffset = (ULONG)(data - Buffer);
@@ -2708,303 +2680,300 @@ GenerateSessionBlock(UCHAR *Buffer,
     KeQuerySystemTime(&node->WnodeHeader.TimeStamp);
     node->WnodeHeader.Flags = WNODE_FLAG_ALL_DATA;
     node->InstanceCount = entries;
-    *byteswritten = RequiredSize;
-
-    session = (XenStoreSession *)fdoData->SessionHead.Flink;
-    {
-        int entrynum = 0;
-        UCHAR *datapos = data;
-        UCHAR *namepos = names;
-        //work out names for each session entry
-        while (session !=  (XenStoreSession *)&fdoData->SessionHead){
-            ULONG *id;
-            UCHAR *sesbuf;
-            UCHAR *inamebuf;
-
-            (VOID) AccessWmiBuffer(datapos, FALSE, &RequiredSize, 
BufferSize+Buffer-datapos,
-                            WMI_UINT32, &id,
-                            WMI_STRING,
-                                
GetCountedUnicodeStringSize(&session->stringid),
-                                &sesbuf,
-                            WMI_DONE);
-
-            node->OffsetInstanceDataAndLength[entrynum].OffsetInstanceData =
-                (ULONG)((UCHAR *)id - Buffer);
-            node->OffsetInstanceDataAndLength[entrynum].LengthInstanceData =
-                RequiredSize;
-            *id = session->id;
-            WriteCountedUnicodeString(&session->stringid, sesbuf);
-            datapos+=RequiredSize;
-
-            (VOID) AccessWmiBuffer(namepos, FALSE, &RequiredSize, 
BufferSize+Buffer-namepos,
-                            WMI_STRING,
-                                
GetCountedUnicodeStringSize(&session->instancename),
-                                &inamebuf,
-                            WMI_DONE);
-
-            nameoffsets[entrynum] = (ULONG)(namepos-Buffer);
-            WriteCountedUnicodeString(&session->instancename, inamebuf);
-            namepos+=RequiredSize;
-
-            namesizerequired += RequiredSize;
-            entrynum++;
-            session = (XenStoreSession *)session->listentry.Flink;
-        }
 
+    *BytesWritten = RequiredSize;
+
+    datapos = data;
+    namepos = names;
+
+    //work out names for each session entry
+    for (ListEntry = Fdo->SessionHead.Flink;
+         ListEntry != &Fdo->SessionHead;
+         ListEntry = ListEntry->Flink) {
+        ULONG *id;
+        UCHAR *sesbuf;
+        UCHAR *inamebuf;
+
+        Session = CONTAINING_RECORD(ListEntry, XENSTORE_SESSION, ListEntry);
+
+        (VOID) AccessWmiBuffer(datapos, FALSE, &RequiredSize, 
BufferSize+Buffer-datapos,
+                        WMI_UINT32, &id,
+                        WMI_STRING, 
GetCountedUnicodeStringSize(&Session->StringId), &sesbuf,
+                        WMI_DONE);
+
+        node->OffsetInstanceDataAndLength[entrynum].OffsetInstanceData =
+            (ULONG)((UCHAR *)id - Buffer);
+        node->OffsetInstanceDataAndLength[entrynum].LengthInstanceData =
+            RequiredSize;
+        *id = Session->SessionId;
+        WriteCountedUnicodeString(&Session->StringId, sesbuf);
+        datapos += RequiredSize;
+
+        (VOID) AccessWmiBuffer(namepos, FALSE, &RequiredSize, 
BufferSize+Buffer-namepos,
+                        WMI_STRING, 
GetCountedUnicodeStringSize(&Session->InstanceName), &inamebuf,
+                        WMI_DONE);
+
+        nameoffsets[entrynum] = (ULONG)(namepos-Buffer);
+        WriteCountedUnicodeString(&Session->InstanceName, inamebuf);
+        namepos += RequiredSize;
+
+        namesizerequired += RequiredSize;
+        entrynum++;
     }
 
-    UnlockSessions(fdoData);
+    ReleaseMutex(&Fdo->SessionLock);
 
     return STATUS_SUCCESS;
-
 }
 
-NTSTATUS
-GenerateBaseBlock(  XENIFACE_FDO *fdoData,
-                    UCHAR *Buffer,
-                    ULONG BufferSize,
-                    ULONG_PTR *byteswritten) {
-    WNODE_ALL_DATA *node;
-    ULONG RequiredSize;
-    ULONGLONG *time;
+static NTSTATUS
+GenerateBaseBlock(
+    IN  PXENIFACE_FDO       Fdo,
+    IN  UCHAR*              Buffer,
+    IN  ULONG               BufferSize,
+    OUT ULONG_PTR*          BytesWritten
+    )
+{
+    WNODE_ALL_DATA*         node;
+    ULONG                   RequiredSize;
+    ULONGLONG*              time;
+
     if (!AccessWmiBuffer(Buffer, FALSE, &RequiredSize, BufferSize,
-                            WMI_BUFFER, sizeof(WNODE_ALL_DATA), &node,
-                            WMI_UINT64, &time,
-                            WMI_DONE))
-    {
-        return NodeTooSmall(Buffer, BufferSize, RequiredSize, byteswritten);
-    }
+                         WMI_BUFFER, sizeof(WNODE_ALL_DATA), &node,
+                         WMI_UINT64, &time,
+                         WMI_DONE))
+        return NodeTooSmall(Buffer, BufferSize, RequiredSize, BytesWritten);
 
-    node->DataBlockOffset =(ULONG)( ((UCHAR *)time)-Buffer);
+    node->DataBlockOffset = (ULONG)(((UCHAR *)time) - Buffer);
     node->WnodeHeader.BufferSize = RequiredSize;
     KeQuerySystemTime(&node->WnodeHeader.TimeStamp);
     node->WnodeHeader.Flags = WNODE_FLAG_ALL_DATA |
-                                WNODE_FLAG_FIXED_INSTANCE_SIZE |
-                                WNODE_FLAG_PDO_INSTANCE_NAMES;
-    if (fdoData->InterfacesAcquired) {
+                              WNODE_FLAG_FIXED_INSTANCE_SIZE |
+                              WNODE_FLAG_PDO_INSTANCE_NAMES;
+    if (Fdo->InterfacesAcquired) {
         LARGE_INTEGER info;
 
-        XENBUS_SHARED_INFO(GetTime, &fdoData->SharedInfoInterface, &info, 
NULL);
+        XENBUS_SHARED_INFO(GetTime, &Fdo->SharedInfoInterface, &info, NULL);
         *time = info.QuadPart;
-    }
-    else {
+    } else {
         *time = 0;
     }
+
     node->InstanceCount = 1;
     node->FixedInstanceSize = sizeof(ULONGLONG);
-    *byteswritten = RequiredSize;
+
+    *BytesWritten = RequiredSize;
     return STATUS_SUCCESS;
 }
-NTSTATUS
+
+static NTSTATUS
 GenerateBaseInstance(
-                    XENIFACE_FDO *fdoData,
-                    UCHAR *Buffer,
-                    ULONG BufferSize,
-                    ULONG_PTR *byteswritten) {
-    WNODE_SINGLE_INSTANCE *node;
-    ULONG RequiredSize;
-    ULONGLONG *time;
-    UCHAR * dbo;
-    if (!AccessWmiBuffer(Buffer, FALSE, &RequiredSize, BufferSize,
-                            WMI_BUFFER, sizeof(WNODE_SINGLE_INSTANCE), &node,
-                            WMI_DONE))
-    {
-        return NodeTooSmall(Buffer, BufferSize, RequiredSize, byteswritten);
-    }
+    IN  PXENIFACE_FDO       Fdo,
+    IN  UCHAR*              Buffer,
+    IN  ULONG               BufferSize,
+    OUT ULONG_PTR*          BytesWritten
+    )
+{
+    WNODE_SINGLE_INSTANCE*  node;
+    ULONG                   RequiredSize;
+    ULONGLONG*              time;
+    UCHAR*                  dbo;
+
     if (!AccessWmiBuffer(Buffer, FALSE, &RequiredSize, BufferSize,
-                            WMI_BUFFER, sizeof(WNODE_SINGLE_INSTANCE), &node,
-                            WMI_OFFSET, node->DataBlockOffset, 0 ,&dbo,
-                            WMI_DONE))
-    {
-        return NodeTooSmall(Buffer, BufferSize, RequiredSize, byteswritten);
-    }
-    if (!AccessWmiBuffer(dbo, FALSE, &RequiredSize, 
BufferSize-node->DataBlockOffset,
-                            WMI_UINT64, &time,
-                            WMI_DONE)){
-        return NodeTooSmall(Buffer, BufferSize, 
RequiredSize+node->DataBlockOffset,
-                            byteswritten);
-    }
+                         WMI_BUFFER, sizeof(WNODE_SINGLE_INSTANCE), &node,
+                         WMI_DONE))
+        return NodeTooSmall(Buffer, BufferSize, RequiredSize, BytesWritten);
 
-    if (node->InstanceIndex != 0) {
+    if (!AccessWmiBuffer(Buffer, FALSE, &RequiredSize, BufferSize,
+                         WMI_BUFFER, sizeof(WNODE_SINGLE_INSTANCE), &node,
+                         WMI_OFFSET, node->DataBlockOffset, 0 ,&dbo,
+                         WMI_DONE))
+        return NodeTooSmall(Buffer, BufferSize, RequiredSize, BytesWritten);
+
+    if (!AccessWmiBuffer(dbo, FALSE, &RequiredSize, BufferSize - 
node->DataBlockOffset,
+                         WMI_UINT64, &time,
+                         WMI_DONE))
+        return NodeTooSmall(Buffer,
+                            BufferSize,
+                            RequiredSize + node->DataBlockOffset,
+                            BytesWritten);
+
+    if (node->InstanceIndex != 0)
         return STATUS_WMI_ITEMID_NOT_FOUND;
-    }
-    if (fdoData->InterfacesAcquired) {
+
+    if (Fdo->InterfacesAcquired) {
         LARGE_INTEGER info;
 
-        XENBUS_SHARED_INFO(GetTime, &fdoData->SharedInfoInterface, &info, 
NULL);
+        XENBUS_SHARED_INFO(GetTime, &Fdo->SharedInfoInterface, &info, NULL);
         *time = info.QuadPart;
-    }
-    else {
+    } else {
         *time = 0;
     }
 
-
-    node->WnodeHeader.BufferSize = node->DataBlockOffset+RequiredSize;
+    node->WnodeHeader.BufferSize = node->DataBlockOffset + RequiredSize;
     node->SizeDataBlock = RequiredSize;
 
-    *byteswritten = node->DataBlockOffset+RequiredSize;
+    *BytesWritten = node->DataBlockOffset + RequiredSize;
 
     return STATUS_SUCCESS;
 }
 
-NTSTATUS
-GenerateSessionInstance(UCHAR *Buffer,
-                    ULONG BufferSize,
-                    XENIFACE_FDO *fdoData,
-                    ULONG_PTR *byteswritten) {
-    WNODE_SINGLE_INSTANCE *node;
-    ULONG RequiredSize;
-    UCHAR *dbo;
-    UCHAR *InstStr;
-    UNICODE_STRING instance;
-    ULONG* id;
-    XenStoreSession *session;
-    UCHAR *sesbuf;
+static NTSTATUS
+GenerateSessionInstance(
+    IN  PXENIFACE_FDO       Fdo,
+    IN  UCHAR*              Buffer,
+    IN  ULONG               BufferSize,
+    OUT ULONG_PTR*          BytesWritten
+    )
+{
+    WNODE_SINGLE_INSTANCE*  node;
+    ULONG                   RequiredSize;
+    UCHAR*                  dbo;
+    UCHAR*                  InstStr;
+    UNICODE_STRING          instance;
+    ULONG*                  id;
+    PXENSTORE_SESSION       session;
+    UCHAR*                  sesbuf;
+    NTSTATUS                status;
 
+    *BytesWritten = 0;
     if (!AccessWmiBuffer(Buffer, TRUE, &RequiredSize, BufferSize,
-                            WMI_BUFFER, sizeof(WNODE_SINGLE_INSTANCE), &node,
-                            WMI_DONE))
-    {
-        return NodeTooSmall(Buffer, BufferSize, RequiredSize, byteswritten);
-    }
+                         WMI_BUFFER, sizeof(WNODE_SINGLE_INSTANCE), &node,
+                         WMI_DONE))
+        goto fail1;
+
     if (!AccessWmiBuffer(Buffer, TRUE, &RequiredSize, BufferSize,
-                            WMI_BUFFER, sizeof(WNODE_SINGLE_INSTANCE), &node,
-                            WMI_STRINGOFFSET, node->OffsetInstanceName, 
&InstStr,
-                            WMI_OFFSET, node->DataBlockOffset, 0, &dbo,
-                            WMI_DONE))
-    {
-        return NodeTooSmall(Buffer, BufferSize, RequiredSize, byteswritten);
-    }
+                         WMI_BUFFER, sizeof(WNODE_SINGLE_INSTANCE), &node,
+                         WMI_STRINGOFFSET, node->OffsetInstanceName, &InstStr,
+                         WMI_OFFSET, node->DataBlockOffset, 0, &dbo,
+                         WMI_DONE))
+        goto fail2;
 
     GetCountedUnicodeString(&instance, InstStr);
-    LockSessions(fdoData);
-    if ((session = FindSessionByInstanceLocked(fdoData, &instance))==NULL){
-        UnlockSessions(fdoData);
-        return STATUS_WMI_INSTANCE_NOT_FOUND;
-    }
+
+    AcquireMutex(&Fdo->SessionLock);
+    status = STATUS_WMI_INSTANCE_NOT_FOUND;
+    session = FindSessionByInstanceLocked(Fdo, &instance);
+    if (session == NULL)
+        goto fail3;
 
     if (!AccessWmiBuffer(dbo, FALSE, &RequiredSize, 
BufferSize-node->DataBlockOffset,
-                            WMI_UINT32, &id,
-                            WMI_STRING,
-                                
GetCountedUnicodeStringSize(&session->stringid),
-                                &sesbuf,
-                            WMI_DONE)) {
-        UnlockSessions(fdoData);
-        return NodeTooSmall(Buffer, BufferSize, 
RequiredSize+node->DataBlockOffset,
-                            byteswritten);
-    }
+                         WMI_UINT32, &id,
+                         WMI_STRING, 
GetCountedUnicodeStringSize(&session->StringId), &sesbuf,
+                         WMI_DONE))
+        goto fail4;
+
+    *id = session->SessionId;
+    WriteCountedUnicodeString(&session->StringId, sesbuf);
+    ReleaseMutex(&Fdo->SessionLock);
 
-    *id = session->id;
-    WriteCountedUnicodeString(&session->stringid, sesbuf);
-    UnlockSessions(fdoData);
     node->SizeDataBlock = RequiredSize;
     node->WnodeHeader.BufferSize = node->DataBlockOffset + RequiredSize;
-    *byteswritten = node->DataBlockOffset + RequiredSize;
 
+    *BytesWritten = node->DataBlockOffset + RequiredSize;
+
+    return STATUS_SUCCESS;
 
+fail4:
+    ReleaseMutex(&Fdo->SessionLock);
+    return NodeTooSmall(Buffer, BufferSize, RequiredSize + 
node->DataBlockOffset, BytesWritten);
 
+fail3:
+    ReleaseMutex(&Fdo->SessionLock);
+    return status;
 
-    return STATUS_SUCCESS;
+fail2:
+fail1:
+    return NodeTooSmall(Buffer, BufferSize, RequiredSize, BytesWritten);
 }
 
-
 NTSTATUS
 WmiQueryAllData(
-    IN PXENIFACE_FDO fdoData,
-    IN PIO_STACK_LOCATION stack,
-    OUT ULONG_PTR *byteswritten
-   )
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PIO_STACK_LOCATION  Stack,
+    OUT ULONG_PTR*          BytesWritten
+    )
 {
+    if (IsEqualGUID(Stack->Parameters.WMI.DataPath,
+                    &OBJECT_GUID(XenStoreBase)))
+        return GenerateBaseBlock(Fdo,
+                                 Stack->Parameters.WMI.Buffer,
+                                 Stack->Parameters.WMI.BufferSize,
+                                 BytesWritten);
+
+    if (IsEqualGUID(Stack->Parameters.WMI.DataPath,
+                    &OBJECT_GUID(XenStoreSession)))
+        return GenerateSessionBlock(Fdo,
+                                    Stack->Parameters.WMI.Buffer,
+                                    Stack->Parameters.WMI.BufferSize,
+                                    BytesWritten);
 
-    if (IsEqualGUID(stack->Parameters.WMI.DataPath,
-                    &OBJECT_GUID(XenStoreBase))) {
-        return GenerateBaseBlock(   fdoData,
-                                    stack->Parameters.WMI.Buffer,
-                                    stack->Parameters.WMI.BufferSize,
-                                    byteswritten);
-    }
-    else if (IsEqualGUID(stack->Parameters.WMI.DataPath,
-                         &OBJECT_GUID(XenStoreSession))) {
-        return GenerateSessionBlock(stack->Parameters.WMI.Buffer,
-                                    stack->Parameters.WMI.BufferSize,
-                                    fdoData,
-                                    byteswritten);
-    }
-    else
-        return STATUS_NOT_SUPPORTED;
-
-
+    return STATUS_NOT_SUPPORTED;
 }
 
 NTSTATUS
 WmiQuerySingleInstance(
-    IN PXENIFACE_FDO fdoData,
-    IN PIO_STACK_LOCATION stack,
-    OUT ULONG_PTR *byteswritten
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PIO_STACK_LOCATION  Stack,
+    OUT ULONG_PTR*          BytesWritten
     )
 {
-    if (IsEqualGUID(stack->Parameters.WMI.DataPath,
-                    &OBJECT_GUID(XenStoreBase))) {
-        return GenerateBaseInstance(fdoData,
-                                    stack->Parameters.WMI.Buffer,
-                                    stack->Parameters.WMI.BufferSize,
-                                    byteswritten);
-    }
-    else if (IsEqualGUID(stack->Parameters.WMI.DataPath,
-                         &OBJECT_GUID(XenStoreSession))) {
-        return GenerateSessionInstance(stack->Parameters.WMI.Buffer,
-                                    stack->Parameters.WMI.BufferSize,
-                                    fdoData,
-                                    byteswritten);
-    }
-    else
-        return STATUS_NOT_SUPPORTED;
+    if (IsEqualGUID(Stack->Parameters.WMI.DataPath,
+                    &OBJECT_GUID(XenStoreBase)))
+        return GenerateBaseInstance(Fdo,
+                                    Stack->Parameters.WMI.Buffer,
+                                    Stack->Parameters.WMI.BufferSize,
+                                    BytesWritten);
+
+    if (IsEqualGUID(Stack->Parameters.WMI.DataPath,
+                    &OBJECT_GUID(XenStoreSession)))
+        return GenerateSessionInstance(Fdo,
+                                       Stack->Parameters.WMI.Buffer,
+                                       Stack->Parameters.WMI.BufferSize,
+                                       BytesWritten);
 
+    return STATUS_NOT_SUPPORTED;
 }
 
-
 NTSTATUS
 WmiRegInfo(
-    IN PXENIFACE_FDO fdoData,
-    IN PIO_STACK_LOCATION stack,
-    OUT ULONG_PTR *byteswritten
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PIO_STACK_LOCATION  Stack,
+    OUT ULONG_PTR*          BytesWritten
    )
 {
-    WMIREGINFO *reginfo;
-    WMIREGGUID *guiddata;
-    UCHAR *mofnameptr;
-    UCHAR *regpath;
-    ULONG RequiredSize;
-    int entries = 4;
+    size_t                  mofnamesz;
+    WMIREGGUID*             guid;
+    WMIREGINFO*             reginfo;
+    WMIREGGUID*             guiddata;
+    UCHAR*                  mofnameptr;
+    UCHAR*                  regpath;
+    ULONG                   RequiredSize;
+
+    const int entries = 4;
     const static UNICODE_STRING mofname = RTL_CONSTANT_STRING(L"XENIFACEMOF");
 
-    size_t mofnamesz;
-
-
-    WMIREGGUID * guid;
     Trace("%s\n",__FUNCTION__);
 
-    if  (stack->Parameters.WMI.DataPath == WMIREGISTER) {
+    if  (Stack->Parameters.WMI.DataPath == WMIREGISTER)
         mofnamesz = mofname.Length + sizeof(USHORT);
-    }
-    else {
+    else
         mofnamesz = 0;
-    }
-    if(!AccessWmiBuffer(stack->Parameters.WMI.Buffer, FALSE,
-                        &RequiredSize,
-                        stack->Parameters.WMI.BufferSize,
-                        WMI_BUFFER, sizeof(WMIREGINFO), (UCHAR **)&reginfo,
-                        WMI_BUFFER, entries * sizeof(WMIREGGUID), (UCHAR 
**)&guiddata,
-                        WMI_STRING, mofnamesz, &mofnameptr,
-                        WMI_STRING, 
DriverParameters.RegistryPath.Length+sizeof(USHORT),
-                                    &regpath,
-                        WMI_DONE)){
+
+    if (!AccessWmiBuffer(Stack->Parameters.WMI.Buffer, FALSE,
+                         &RequiredSize,
+                         Stack->Parameters.WMI.BufferSize,
+                         WMI_BUFFER, sizeof(WMIREGINFO), (UCHAR **)&reginfo,
+                         WMI_BUFFER, entries * sizeof(WMIREGGUID), (UCHAR 
**)&guiddata,
+                         WMI_STRING, mofnamesz, &mofnameptr,
+                         WMI_STRING, DriverParameters.RegistryPath.Length + 
sizeof(USHORT), &regpath,
+                         WMI_DONE)) {
         reginfo->BufferSize = RequiredSize;
-        *byteswritten = sizeof(ULONG);
+        *BytesWritten = sizeof(ULONG);
         return STATUS_BUFFER_TOO_SMALL;
-
     }
-    if (stack->Parameters.WMI.DataPath == WMIREGISTER) {
+
+    if (Stack->Parameters.WMI.DataPath == WMIREGISTER) {
         reginfo->MofResourceName = (ULONG)((ULONG_PTR)mofnameptr - 
(ULONG_PTR)reginfo);
         WriteCountedUnicodeString(&mofname, mofnameptr);
         reginfo->RegistryPath = (ULONG)((ULONG_PTR)regpath - 
(ULONG_PTR)reginfo);
@@ -3019,44 +2988,42 @@ WmiRegInfo(
     guid->InstanceCount = 1;
     guid->Guid = OBJECT_GUID(XenStoreBase);
     guid->Flags = WMIREG_FLAG_INSTANCE_PDO;
-    guid->Pdo = (ULONG_PTR)fdoData->PhysicalDeviceObject;
-    ObReferenceObject(fdoData->PhysicalDeviceObject);
+    guid->Pdo = (ULONG_PTR)Fdo->PhysicalDeviceObject;
+    ObReferenceObject(Fdo->PhysicalDeviceObject);
 
     guid = &reginfo->WmiRegGuid[1];
     guid->Guid = OBJECT_GUID(XenStoreSession);
-    guid->Flags =0;
+    guid->Flags = 0;
 
     guid = &reginfo->WmiRegGuid[2];
     guid->InstanceCount = 1;
     guid->Guid = OBJECT_GUID(XenStoreWatchEvent);
     guid->Flags = WMIREG_FLAG_INSTANCE_PDO |
-                WMIREG_FLAG_EVENT_ONLY_GUID ;
-    guid->Pdo = (ULONG_PTR)fdoData->PhysicalDeviceObject;
-    ObReferenceObject(fdoData->PhysicalDeviceObject);
+                  WMIREG_FLAG_EVENT_ONLY_GUID ;
+    guid->Pdo = (ULONG_PTR)Fdo->PhysicalDeviceObject;
+    ObReferenceObject(Fdo->PhysicalDeviceObject);
 
     guid = &reginfo->WmiRegGuid[3];
     guid->InstanceCount = 1;
     guid->Guid = OBJECT_GUID(XenStoreUnsuspendedEvent);
     guid->Flags = WMIREG_FLAG_INSTANCE_PDO |
-                WMIREG_FLAG_EVENT_ONLY_GUID ;
-    guid->Pdo = (ULONG_PTR)fdoData->PhysicalDeviceObject;
-    ObReferenceObject(fdoData->PhysicalDeviceObject);
+                  WMIREG_FLAG_EVENT_ONLY_GUID ;
+    guid->Pdo = (ULONG_PTR)Fdo->PhysicalDeviceObject;
+    ObReferenceObject(Fdo->PhysicalDeviceObject);
 
-
-    *byteswritten = RequiredSize;
+    *BytesWritten = RequiredSize;
     return STATUS_SUCCESS;
 }
 
 NTSTATUS
 WmiRegInfoEx(
-    IN PXENIFACE_FDO fdoData,
-    IN PIO_STACK_LOCATION stack,
-    OUT ULONG_PTR *byteswritten
-   )
+    IN  PXENIFACE_FDO       Fdo,
+    IN  PIO_STACK_LOCATION  Stack,
+    OUT ULONG_PTR*          BytesWritten
+    )
 {
-
     Trace("%s\n",__FUNCTION__);
-    return WmiRegInfo(fdoData, stack, byteswritten);
+    return WmiRegInfo(Fdo, Stack, BytesWritten);
 }
 
 NTSTATUS
@@ -3081,18 +3048,6 @@ WmiProcessMinorFunction(
     }
 
     switch (Stack->MinorFunction) {
-    case IRP_MN_CHANGE_SINGLE_INSTANCE:
-        return WmiChangeSingleInstance(Fdo, Stack);
-    case IRP_MN_CHANGE_SINGLE_ITEM:
-        return WmiChangeSingleItem(Fdo, Stack);
-    case IRP_MN_DISABLE_COLLECTION:
-        return WmiDisableCollection(Fdo, Stack);
-    case IRP_MN_DISABLE_EVENTS:
-        return WmiDisableEvents(Fdo, Stack);
-    case IRP_MN_ENABLE_COLLECTION:
-        return WmiEnableCollection(Fdo, Stack);
-    case IRP_MN_ENABLE_EVENTS:
-        return WmiEnableEvents(Fdo, Stack);
     case IRP_MN_EXECUTE_METHOD:
         return WmiExecuteMethod(Fdo, Stack,  &Irp->IoStatus.Information);
     case IRP_MN_QUERY_ALL_DATA:
@@ -3108,41 +3063,106 @@ WmiProcessMinorFunction(
     }
 }
 
-PCHAR
-WMIMinorFunctionString (
-    __in UCHAR MinorFunction
-)
-/*++
-
-Updated Routine Description:
-    WMIMinorFunctionString does not change in this stage of the function 
driver.
---*/
-{
-    switch (MinorFunction)
-    {
-    case IRP_MN_CHANGE_SINGLE_INSTANCE:
-        return "IRP_MN_CHANGE_SINGLE_INSTANCE";
-    case IRP_MN_CHANGE_SINGLE_ITEM:
-        return "IRP_MN_CHANGE_SINGLE_ITEM";
-    case IRP_MN_DISABLE_COLLECTION:
-        return "IRP_MN_DISABLE_COLLECTION";
-    case IRP_MN_DISABLE_EVENTS:
-        return "IRP_MN_DISABLE_EVENTS";
-    case IRP_MN_ENABLE_COLLECTION:
-        return "IRP_MN_ENABLE_COLLECTION";
-    case IRP_MN_ENABLE_EVENTS:
-        return "IRP_MN_ENABLE_EVENTS";
-    case IRP_MN_EXECUTE_METHOD:
-        return "IRP_MN_EXECUTE_METHOD";
-    case IRP_MN_QUERY_ALL_DATA:
-        return "IRP_MN_QUERY_ALL_DATA";
-    case IRP_MN_QUERY_SINGLE_INSTANCE:
-        return "IRP_MN_QUERY_SINGLE_INSTANCE";
-    case IRP_MN_REGINFO:
-        return "IRP_MN_REGINFO";
-    default:
-        return "unknown_syscontrol_irp";
+VOID
+WmiFireSuspendEvent(
+    IN  PXENIFACE_FDO   Fdo
+    )
+{
+    Info("Ready to unsuspend Event\n");
+    KeSetEvent(&Fdo->registryWriteEvent, IO_NO_INCREMENT, FALSE);
+
+    if (!Fdo->WmiReady)
+        return;
+
+    Trace("Fire Suspend Event\n");
+    WmiFireEvent(Fdo->Dx->DeviceObject,
+                 (LPGUID)&OBJECT_GUID(XenStoreUnsuspendedEvent),
+                 0,
+                 0,
+                 NULL);
+}
+
+VOID
+WmiSessionsSuspendAll(
+    IN  PXENIFACE_FDO   Fdo
+    )
+{
+    PLIST_ENTRY         ListEntry;
+    PXENSTORE_SESSION   Session;
+
+    AcquireMutex(&Fdo->SessionLock);
+    Trace("Suspend all sessions\n");
+    for (ListEntry = Fdo->SessionHead.Flink;
+         ListEntry != &Fdo->SessionHead;
+         ListEntry = ListEntry->Flink) {
+        Session = CONTAINING_RECORD(ListEntry, XENSTORE_SESSION, ListEntry);
+
+        SessionsSuspendLocked(Fdo, Session);
+    }
+    ReleaseMutex(&Fdo->SessionLock);
+}
+
+VOID
+WmiSessionsResumeAll(
+    IN  PXENIFACE_FDO   Fdo
+    )
+{
+    PLIST_ENTRY         ListEntry;
+    PXENSTORE_SESSION   Session;
+
+    AcquireMutex(&Fdo->SessionLock);
+    Trace("Resume all sessions\n");
+    for (ListEntry = Fdo->SessionHead.Flink;
+         ListEntry != &Fdo->SessionHead;
+         ListEntry = ListEntry->Flink) {
+        Session = CONTAINING_RECORD(ListEntry, XENSTORE_SESSION, ListEntry);
+
+        SessionResumeLocked(Session);
     }
+    ReleaseMutex(&Fdo->SessionLock);
+}
+
+NTSTATUS
+WmiRegister(
+    IN  PXENIFACE_FDO   Fdo
+    )
+{
+    NTSTATUS            status;
+
+    if (Fdo->WmiReady)
+        return STATUS_SUCCESS;
+
+    Trace("%s\n",__FUNCTION__);
+    Info("DRV: XenIface WMI Initialisation\n");
+
+    status = IoWMIRegistrationControl(Fdo->Dx->DeviceObject,
+                                      WMIREG_ACTION_REGISTER);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    Fdo->WmiReady = 1;
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+    return status;
+}
+
+VOID
+WmiDeregister(
+    IN  PXENIFACE_FDO   Fdo
+    )
+{
+    if (!Fdo->WmiReady)
+        return;
+
+    Info("DRV: XenIface WMI Finalisation\n");
+    Trace("%s\n",__FUNCTION__);
+
+    SessionsRemoveAll(Fdo);
+    (VOID) IoWMIRegistrationControl(Fdo->Dx->DeviceObject,
+                                    WMIREG_ACTION_DEREGISTER);
+    Fdo->WmiReady = 0;
 }
 
 NTSTATUS
-- 
2.32.0.windows.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.