#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>
#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
__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.
static NTSTATUS
GetInstanceName(
OUT PUNICODE_STRING dest,
- IN PXENIFACE_FDO FdoData,
+ IN PXENIFACE_FDO Fdo,
IN const CHAR* string
)
{
if (!NT_SUCCESS(status))
goto fail1;
- destsz = FdoData->SuggestedInstanceName.Length +
+ destsz = Fdo->SuggestedInstanceName.Length +
sizeof(WCHAR) +
unicode.Length;
status = RtlUnicodeStringPrintf(dest,
L"%s\\%s",
- FdoData->SuggestedInstanceName.Buffer,
+ Fdo->SuggestedInstanceName.Buffer,
unicode.Buffer);
if (!NT_SUCCESS(status))
goto fail3;
static NTSTATUS
WriteInstanceName(
- IN PXENIFACE_FDO FdoData,
+ IN PXENIFACE_FDO Fdo,
IN const CHAR* string,
IN PUCHAR location
)
UNICODE_STRING destination;
NTSTATUS status;
- status = GetInstanceName(&destination, FdoData, string);
+ status = GetInstanceName(&destination, Fdo, string);
if (!NT_SUCCESS(status))
return status;
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)
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)) {
}
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) {
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 {
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;
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;
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);
}
*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);
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);
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
}
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:
}
}
-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