[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] Refactor Wmi.c
* 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 **)®info, - WMI_BUFFER, entries * sizeof(WMIREGGUID), (UCHAR **)&guiddata, - WMI_STRING, mofnamesz, &mofnameptr, - WMI_STRING, DriverParameters.RegistryPath.Length+sizeof(USHORT), - ®path, - WMI_DONE)){ + + if (!AccessWmiBuffer(Stack->Parameters.WMI.Buffer, FALSE, + &RequiredSize, + Stack->Parameters.WMI.BufferSize, + WMI_BUFFER, sizeof(WMIREGINFO), (UCHAR **)®info, + WMI_BUFFER, entries * sizeof(WMIREGGUID), (UCHAR **)&guiddata, + WMI_STRING, mofnamesz, &mofnameptr, + WMI_STRING, DriverParameters.RegistryPath.Length + sizeof(USHORT), ®path, + 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 = ®info->WmiRegGuid[1]; guid->Guid = OBJECT_GUID(XenStoreSession); - guid->Flags =0; + guid->Flags = 0; guid = ®info->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 = ®info->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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |