/* **============================================================================== ** ** Open Management Infrastructure (OMI) ** ** Copyright (c) Microsoft Corporation ** ** Licensed under the Apache License, Version 2.0 (the "License"); you may not ** use this file except in compliance with the License. You may obtain a copy ** of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABLITY OR NON-INFRINGEMENT. ** ** See the Apache 2 License for the specific language governing permissions ** and limitations under the License. ** **============================================================================== */ #include "messages.h" #include "packing.h" #include #include "result.h" #include "io.h" /* **============================================================================== ** ** Local definitions ** **============================================================================== */ typedef enum _FieldType { FT_BOOLEAN = MI_BOOLEAN, FT_UINT8 = MI_UINT8, FT_SINT8 = MI_SINT8, FT_UINT16 = MI_UINT16, FT_SINT16 = MI_SINT16, FT_UINT32 = MI_UINT32, FT_SINT32 = MI_SINT32, FT_UINT64 = MI_UINT64, FT_SINT64 = MI_SINT64, FT_REAL32 = MI_REAL32, FT_REAL64 = MI_REAL64, FT_CHAR16 = MI_CHAR16, FT_DATETIME = MI_DATETIME, FT_STRING = MI_STRING, FT_REFERENCE = MI_REFERENCE, FT_INSTANCE = MI_INSTANCE, FT_BOOLEANA = MI_BOOLEANA, FT_UINT8A = MI_UINT8A, FT_SINT8A = MI_SINT8A, FT_UINT16A = MI_UINT16A, FT_SINT16A = MI_SINT16A, FT_UINT32A = MI_UINT32A, FT_SINT32A = MI_SINT32A, FT_UINT64A = MI_UINT64A, FT_SINT64A = MI_SINT64A, FT_REAL32A = MI_REAL32A, FT_REAL64A = MI_REAL64A, FT_CHAR16A = MI_CHAR16A, FT_DATETIMEA = MI_DATETIMEA, FT_STRINGA = MI_STRINGA, FT_REFERENCEA = MI_REFERENCEA, FT_INSTANCEA = MI_INSTANCEA, FT_RESULT, FT_ATOMIC } FieldType; /* Defines meta data for message field (to support printing) */ typedef struct Field { /* Name of field */ const char* name; /* (T=Tag, S=String, B=Boolean, A=StringArray, O=Object) */ FieldType type; /* Byte off within structure to this field */ size_t off; } Field; typedef enum _MessageFieldType { MFT_END_OF_LIST, /* special type to terminate list of fields */ MFT_POINTER, /* Pointer that has to be converted */ MFT_POINTER_OPT, /* Pointer that has to be converted (may be null) */ MFT_POINTER_SET_NULL, /* Pointer that has to be nullified instead of converting */ MFT_INSTANCE, /* instance */ MFT_INSTANCE_OPT /* instance (maybe NULL) */ } MessageFieldType; /* Defines meta data for message field (to support packing/unpacking) */ typedef struct _MessageField { /* (T=Tag, S=String, B=Boolean, A=StringArray, O=Object) */ MessageFieldType type; /* Byte off within structure to this field and (for instance) to packed pointer/size */ size_t off; size_t offPackedPtr; size_t offPackedSize; } MessageField; static const MessageField baseMessageFields[] = { {MFT_POINTER_SET_NULL,offsetof(Message, next),0,0}, {MFT_POINTER_SET_NULL,offsetof(Message, prev),0,0}, {MFT_POINTER_SET_NULL,offsetof(Message, request),0,0}, {MFT_POINTER_SET_NULL,offsetof(Message, callback),0,0}, {MFT_POINTER_SET_NULL,offsetof(Message, callbackData),0,0}, {MFT_POINTER_SET_NULL,offsetof(Message, dtor),0,0}, {MFT_POINTER_SET_NULL,offsetof(Message, dtorData),0,0}, {MFT_POINTER_OPT,offsetof(Message, libraryName),0,0}, {MFT_END_OF_LIST, 0, 0, 0} }; static const MessageField emptyMessageFields[] = { {MFT_END_OF_LIST, 0, 0, 0} }; static const MessageField getInstanceMessageFields[] = { {MFT_POINTER,offsetof(GetInstanceReq, nameSpace),0,0}, {MFT_INSTANCE,offsetof(GetInstanceReq, instanceName),offsetof(GetInstanceReq, packedInstanceNamePtr),offsetof(GetInstanceReq, packedInstanceNameSize)}, {MFT_END_OF_LIST, 0, 0, 0} }; static const MessageField postInstanceMessageFields[] = { {MFT_INSTANCE,offsetof(PostInstanceMsg, instance),offsetof(PostInstanceMsg, packedInstancePtr),offsetof(PostInstanceMsg, packedInstanceSize)}, {MFT_END_OF_LIST, 0, 0, 0} }; static const MessageField enumerateInstancesMessageFields[] = { {MFT_POINTER,offsetof(EnumerateInstancesReq, nameSpace),0,0}, {MFT_POINTER,offsetof(EnumerateInstancesReq, className),0,0}, {MFT_POINTER_OPT,offsetof(EnumerateInstancesReq, requestClassName),0,0}, {MFT_POINTER_OPT,offsetof(EnumerateInstancesReq, queryLanguage),0,0}, {MFT_POINTER_OPT,offsetof(EnumerateInstancesReq, queryExpression),0,0}, {MFT_END_OF_LIST, 0, 0, 0} }; static const MessageField invokeMessageFields[] = { {MFT_POINTER,offsetof(InvokeReq, nameSpace),0,0}, {MFT_POINTER,offsetof(InvokeReq, function),0,0}, {MFT_POINTER_OPT,offsetof(InvokeReq, className),0,0}, {MFT_INSTANCE_OPT,offsetof(InvokeReq, instance),offsetof(InvokeReq, packedInstancePtr),offsetof(InvokeReq, packedInstanceSize)}, {MFT_INSTANCE_OPT,offsetof(InvokeReq, instanceParams),offsetof(InvokeReq, packedInstanceParamsPtr),offsetof(InvokeReq, packedInstanceParamsSize)}, {MFT_END_OF_LIST, 0, 0, 0} }; static const MessageField associatorsOfMessageFields[] = { {MFT_POINTER,offsetof(AssociatorsOfReq, nameSpace),0,0}, {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, className),0,0}, {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, assocClass),0,0}, {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, resultClass),0,0}, {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, role),0,0}, {MFT_POINTER_OPT,offsetof(AssociatorsOfReq, resultRole),0,0}, {MFT_INSTANCE,offsetof(AssociatorsOfReq, instance),offsetof(AssociatorsOfReq, packedInstancePtr),offsetof(AssociatorsOfReq, packedInstanceSize)}, {MFT_END_OF_LIST, 0, 0, 0} }; static const MessageField referencesOfMessageFields[] = { {MFT_POINTER,offsetof(ReferencesOfReq, nameSpace),0,0}, {MFT_POINTER_OPT,offsetof(ReferencesOfReq, className),0,0}, {MFT_POINTER_OPT,offsetof(ReferencesOfReq, assocClass),0,0}, {MFT_POINTER_OPT,offsetof(ReferencesOfReq, role),0,0}, {MFT_INSTANCE,offsetof(ReferencesOfReq, instance),offsetof(ReferencesOfReq, packedInstancePtr),offsetof(ReferencesOfReq, packedInstanceSize)}, {MFT_END_OF_LIST, 0, 0, 0} }; static const MessageField subscribeRequestMessageFields[] = { {MFT_POINTER,offsetof(SubscribeReq, nameSpace),0,0}, {MFT_POINTER,offsetof(SubscribeReq, className),0,0}, {MFT_POINTER,offsetof(SubscribeReq, filter),0,0}, {MFT_POINTER,offsetof(SubscribeReq, language),0,0}, {MFT_END_OF_LIST, 0, 0, 0} }; static const MessageField subscribeResponseMessageFields[] = { {MFT_POINTER,offsetof(SubscribeRes, subscriptionID),0,0}, {MFT_END_OF_LIST, 0, 0, 0} }; static const MessageField deleteInstanceMessageFields[] = { {MFT_POINTER,offsetof(DeleteInstanceReq, nameSpace),0,0}, {MFT_INSTANCE,offsetof(DeleteInstanceReq, instanceName),offsetof(DeleteInstanceReq, packedInstanceNamePtr),offsetof(DeleteInstanceReq, packedInstanceNameSize)}, {MFT_END_OF_LIST, 0, 0, 0} }; static const MessageField createInstanceMessageFields[] = { {MFT_POINTER,offsetof(CreateInstanceReq, nameSpace),0,0}, {MFT_INSTANCE,offsetof(CreateInstanceReq, instance),offsetof(CreateInstanceReq, packedInstancePtr),offsetof(CreateInstanceReq, packedInstanceSize)}, {MFT_END_OF_LIST, 0, 0, 0} }; static const MessageField modifyInstanceMessageFields[] = { {MFT_POINTER,offsetof(ModifyInstanceReq, nameSpace),0,0}, {MFT_INSTANCE,offsetof(ModifyInstanceReq, instance),offsetof(ModifyInstanceReq, packedInstancePtr),offsetof(ModifyInstanceReq, packedInstanceSize)}, {MFT_END_OF_LIST, 0, 0, 0} }; static const MessageField binProtocolNotificationFields[] = { {MFT_POINTER_OPT,offsetof(BinProtocolNotification, user),0,0}, {MFT_POINTER_OPT,offsetof(BinProtocolNotification, password),0,0}, {MFT_POINTER_OPT,offsetof(BinProtocolNotification, authFile),0,0}, {MFT_END_OF_LIST, 0, 0, 0} }; /* Entries in this array corresponds to MessageTag values: GetInstanceReqTag = 1, PostInstanceMsgTag = 2, EnumerateInstancesReqTag = 3, PostResultMsgTag = 4, NoOpReqTag = 5, NoOpRspTag = 6, DispResultMsgTag = 7, InvokeReqTag = 8, AssociatorsOfReqTag = 9, ReferencesOfReqTag = 10, SubscribeReqTag = 11, SubscribeResTag = 12, DeleteInstanceReqTag = 13, CreateInstanceReqTag = 14, ModifyInstanceReqTag = 15, BinProtocolNotificationTag = 16 */ typedef struct _MessageDeclaration { const MessageField* fields; size_t size; MI_Boolean cloneRequired; } MessageDeclaration; static const MessageDeclaration allMessages[] = { {baseMessageFields, 0, MI_FALSE}, {getInstanceMessageFields, sizeof(GetInstanceReq), MI_TRUE}, {postInstanceMessageFields, sizeof(PostInstanceMsg), MI_TRUE}, {enumerateInstancesMessageFields, sizeof(EnumerateInstancesReq), MI_FALSE}, {emptyMessageFields, sizeof(PostResultMsg), MI_FALSE}, {emptyMessageFields, sizeof(NoOpReq), MI_FALSE}, {emptyMessageFields, sizeof(NoOpRsp), MI_FALSE}, {emptyMessageFields, sizeof(DispResultMsg), MI_FALSE}, {invokeMessageFields, sizeof(InvokeReq), MI_TRUE}, {associatorsOfMessageFields, sizeof(AssociatorsOfReq), MI_TRUE}, {referencesOfMessageFields, sizeof(ReferencesOfReq), MI_TRUE}, {subscribeRequestMessageFields, sizeof(SubscribeReq), MI_FALSE}, {subscribeResponseMessageFields, sizeof(SubscribeRes), MI_FALSE}, {deleteInstanceMessageFields, sizeof(DeleteInstanceReq), MI_TRUE}, {createInstanceMessageFields, sizeof(CreateInstanceReq), MI_TRUE}, {modifyInstanceMessageFields, sizeof(ModifyInstanceReq), MI_TRUE}, {binProtocolNotificationFields, sizeof(BinProtocolNotification),MI_FALSE} }; /* **============================================================================== ** ** Public definitions ** **============================================================================== */ Message* __Message_New( MessageTag tag, size_t structSize, MI_Uint64 msgID, MI_Uint32 flags) { Batch *batch; Message* self; batch = Batch_New(BATCH_MAX_PAGES); if (!batch) return NULL; /* Allocate heap space for message */ self = Batch_Get(batch, structSize); if (!self) return NULL; /* Clear all fields */ memset(self, 0, structSize); /* Set the tag */ self->tag = tag; /* Set the message id and flags */ self->msgID = msgID; self->flags = flags; /* ref-counter is set to 1, to balance NewMessage/Release Message pair*/ self->refCounter = 1; /* Copy batch onto message (released by delete method) */ self->batch = batch; return self; } /* Decrements message's ref-counter and destroys mesage if last reference was released Parameters: self - message to decref/release */ void Message_Release( Message* self) { if (AtomicDec(&self->refCounter)) { /* Call destructor */ if (self->dtor) (*self->dtor)(self, self->dtorData); /* Release linked request */ if (self->request) Message_Release(self->request); Batch_Destroy(self->batch); } } static void _Message_Print( const void* msg, FILE* os, const char* structName, const Field fields[]) { size_t i; fprintf(os, "%s\n", structName); fprintf(os, "{\n"); for (i = 0; fields[i].name; i++) { const Field* f = &fields[i]; /* Print name */ fprintf(os, " %s=", f->name); /* Print value */ switch (f->type) { case FT_UINT32: { MessageTag* p = (MessageTag*)((char*)msg + f->off); fprintf(os, "%u", *p); break; } case FT_RESULT: { MI_Result* p = (MI_Result*)((char*)msg + f->off); Fzprintf(os, MI_T("%u [%s]"),*p, Result_ToString(*p)); break; } case FT_ATOMIC: { AtomicInt* p = (AtomicInt*)((char*)msg + f->off); Fzprintf(os, MI_T("%d"),(int)(*p)); break; } case FT_UINT64: { MI_Uint64* p = (MI_Uint64*)((char*)msg + f->off); fprintf(os, UINT64_FMT, *p); break; } case FT_BOOLEAN: { MI_Boolean* p = (MI_Boolean*)((char*)msg + f->off); fprintf(os, "%s", *p ? "TRUE" : "FALSE"); break; } case FT_STRING: { MI_Char** p = (MI_Char**)((char*)msg + f->off); if (*p) Fzprintf(os, MI_T("\"%s\""), *p); else fprintf(os, "NULL"); break; } case FT_STRINGA: { StringArray** p = (StringArray**)((char*)msg + f->off); if (*p) StringArray_Print(*p, os); else fprintf(os, "NULL"); break; } case FT_INSTANCE: { MI_Instance** p = (MI_Instance**)((char*)msg + f->off); if (*p) { fputc('\n', os); MI_Instance_Print(*p, os, 1); } else fprintf(os, "NULL\n"); break; } default: break; } if (f->type != FT_INSTANCE) fputc('\n', os); } fprintf(os, "}\n"); } void MessagePrint(const Message* msg, FILE* os) { switch ( msg->tag ) { case GetInstanceReqTag: { const GetInstanceReq* m = (const GetInstanceReq*)msg; GetInstanceReq_Print(m, os); } break; case PostInstanceMsgTag: { const PostInstanceMsg* m = (const PostInstanceMsg*)msg; PostInstanceMsg_Print(m, os); } break; case EnumerateInstancesReqTag: { const EnumerateInstancesReq* m = (const EnumerateInstancesReq*)msg; EnumerateInstancesReq_Print(m, os); } break; case PostResultMsgTag: { const PostResultMsg* m = (const PostResultMsg*)msg; PostResultMsg_Print(m, os); } break; case NoOpReqTag: { const NoOpReq* m = (const NoOpReq*)msg; NoOpReq_Print(m, os); } break; case NoOpRspTag: { const NoOpRsp* m = (const NoOpRsp*)msg; NoOpRsp_Print(m, os); } break; case DispResultMsgTag: { const DispResultMsg* m = (const DispResultMsg*)msg; DispResultMsg_Print(m, os); } break; case InvokeReqTag: { const InvokeReq* m = (const InvokeReq*)msg; InvokeReq_Print(m, os); } break; case AssociatorsOfReqTag: { const AssociatorsOfReq* m = (const AssociatorsOfReq*)msg; AssociatorsOfReq_Print(m, os); } break; case ReferencesOfReqTag: { const ReferencesOfReq* m = (const ReferencesOfReq*)msg; ReferencesOfReq_Print(m, os); } break; case SubscribeReqTag: { const SubscribeReq* m = (const SubscribeReq*)msg; SubscribeReq_Print(m, os); } break; case SubscribeResTag: { const SubscribeRes* m = (const SubscribeRes*)msg; SubscribeRes_Print(m, os); } break; case DeleteInstanceReqTag: { const DeleteInstanceReq* m = (const DeleteInstanceReq*)msg; DeleteInstanceReq_Print(m, os); } break; case CreateInstanceReqTag: { const CreateInstanceReq* m = (const CreateInstanceReq*)msg; CreateInstanceReq_Print(m, os); } break; case ModifyInstanceReqTag: { const ModifyInstanceReq* m = (const ModifyInstanceReq*)msg; ModifyInstanceReq_Print(m, os); } break; case BinProtocolNotificationTag: { const BinProtocolNotification* m = (const BinProtocolNotification*)msg; BinProtocolNotification_Print(m, os); } break; default: fprintf(os, "unknown message tag %d\n", msg->tag); break; } } /* **============================================================================== ** ** Field information. ** **============================================================================== */ void GetInstanceReq_Print(const GetInstanceReq* msg, FILE* os) { typedef GetInstanceReq Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {"instanceName", FT_INSTANCE, offsetof(Self, instanceName)}, {"includeClassOrigin", FT_BOOLEAN, offsetof(Self, includeClassOrigin)}, {"propertySet", FT_STRINGA, offsetof(Self, propertySet)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "GetInstanceReq", fields); } void CreateInstanceReq_Print(const CreateInstanceReq* msg, FILE* os) { typedef CreateInstanceReq Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {"instanceName", FT_INSTANCE, offsetof(Self, instance)}, {"propertySet", FT_STRINGA, offsetof(Self, propertySet)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "CreateInstanceReq", fields); } void ModifyInstanceReq_Print(const ModifyInstanceReq* msg, FILE* os) { typedef ModifyInstanceReq Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {"instanceName", FT_INSTANCE, offsetof(Self, instance)}, {"propertySet", FT_STRINGA, offsetof(Self, propertySet)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "ModifyInstanceReq", fields); } void DeleteInstanceReq_Print(const DeleteInstanceReq* msg, FILE* os) { typedef DeleteInstanceReq Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {"instanceName", FT_INSTANCE, offsetof(Self, instanceName)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "DeleteInstanceReq", fields); } void InvokeReq_Print(const InvokeReq* msg, FILE* os) { typedef InvokeReq Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {"nameSpace", FT_STRING, offsetof(Self, nameSpace)}, {"className", FT_STRING, offsetof(Self, className)}, {"function", FT_STRING, offsetof(Self, function)}, {"instance", FT_INSTANCE, offsetof(Self, instance)}, {"instanceParams", FT_INSTANCE, offsetof(Self, instanceParams)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "InvokeReq", fields); } void AssociatorsOfReq_Print(const AssociatorsOfReq* msg, FILE* os) { typedef AssociatorsOfReq Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {"nameSpace", FT_STRING, offsetof(Self, nameSpace)}, {"assocClass", FT_STRING, offsetof(Self, assocClass)}, {"resultClass", FT_STRING, offsetof(Self, resultClass)}, {"role", FT_STRING, offsetof(Self, role)}, {"resultRole", FT_STRING, offsetof(Self, resultRole)}, {"instance", FT_INSTANCE, offsetof(Self, instance)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "AssociatorsOfReq", fields); } void ReferencesOfReq_Print(const ReferencesOfReq* msg, FILE* os) { typedef ReferencesOfReq Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {"nameSpace", FT_STRING, offsetof(Self, nameSpace)}, {"assocClass", FT_STRING, offsetof(Self, assocClass)}, {"role", FT_STRING, offsetof(Self, role)}, {"instance", FT_INSTANCE, offsetof(Self, instance)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "ReferencesOfReq", fields); } void PostInstanceMsg_Print(const PostInstanceMsg* msg, FILE* os) { typedef PostInstanceMsg Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {"instance", FT_INSTANCE, offsetof(Self, instance)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "PostInstanceMsg", fields); } void PostResultMsg_Print(const PostResultMsg* msg, FILE* os) { typedef PostResultMsg Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {"result", FT_RESULT, offsetof(Self, result)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "PostResultMsg", fields); } void DispResultMsg_Print(const DispResultMsg* msg, FILE* os) { typedef DispResultMsg Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {"result", FT_RESULT, offsetof(Self, result)}, {"requestCounter", FT_ATOMIC, offsetof(Self, requestCounter)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "DispResultMsg", fields); } void EnumerateInstancesReq_Print( const EnumerateInstancesReq* msg, FILE* os) { typedef EnumerateInstancesReq Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {"nameSpace", FT_STRING, offsetof(Self, nameSpace)}, {"className", FT_STRING, offsetof(Self, className)}, {"requestClassName", FT_STRING, offsetof(Self, requestClassName)}, {"deepInheritance", FT_BOOLEAN, offsetof(Self, deepInheritance)}, {"includeClassOrigin", FT_BOOLEAN, offsetof(Self, includeClassOrigin)}, {"propertySet", FT_STRINGA, offsetof(Self, propertySet)}, {"queryLanguage", FT_STRING, offsetof(Self, queryLanguage)}, {"queryExpression", FT_STRING, offsetof(Self, queryExpression)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "EnumerateInstancesReq", fields); } void SubscribeReq_Print(const SubscribeReq* msg, FILE* os) { typedef SubscribeReq Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {"nameSpace", FT_STRING, offsetof(Self, nameSpace)}, {"className", FT_STRING, offsetof(Self, className)}, {"filter", FT_STRING, offsetof(Self, filter)}, {"language", FT_STRING, offsetof(Self, language)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "SubscribeReq", fields); } void SubscribeRes_Print(const SubscribeRes* msg, FILE* os) { typedef SubscribeRes Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {"subscriptionID", FT_STRING, offsetof(Self, subscriptionID)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "SubscribeRes", fields); } void NoOpReq_Print(const NoOpReq* msg, FILE* os) { typedef NoOpReq Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "NoOpReq", fields); } void NoOpRsp_Print(const NoOpRsp* msg, FILE* os) { typedef NoOpRsp Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "NoOpRsp", fields); } void BinProtocolNotification_Print(const BinProtocolNotification* msg, FILE* os) { typedef BinProtocolNotification Self; static const Field fields[] = { {"tag", FT_UINT32, offsetof(Self, base.tag)}, {"msgID", FT_UINT64, offsetof(Self, base.msgID)}, {"clientID", FT_UINT64, offsetof(Self, base.clientID)}, {NULL, 0, 0}, }; _Message_Print(msg, os, "BinProtocolNotification", fields); } static MI_Boolean _UnpackInstance( Batch* batch, void* ptr, MI_Uint32 size, MI_Instance** instanceOut) { MI_Result r; Buf buf = BUF_INITIALIZER; /* borrow pointer for unpacking, leaving it in the batch */ buf.data = ptr; buf.size = size; r = Instance_Unpack(instanceOut, &buf, batch, MI_FALSE); return r == MI_RESULT_OK; } static MI_Result _RestoreMessage( Message* msg, const Header_BatchInfoItem* ptrAdjustmentInfo, size_t ptrAdjustmentInfoCount, MI_Boolean skipInstanceUnpack, const MessageField* messageFields) { char* chunk = (char*)msg; Batch* batch = msg->batch; while (messageFields->type != MFT_END_OF_LIST) { void** ptr = (void**)(chunk + messageFields->off); switch (messageFields->type) { case MFT_POINTER_SET_NULL: *ptr = 0; break; case MFT_POINTER_OPT: case MFT_POINTER: if (*ptr) { if (!Batch_FixPointer( batch, ptrAdjustmentInfo, ptrAdjustmentInfoCount, ptr)) return MI_RESULT_INVALID_PARAMETER; } else if (messageFields->type == MFT_POINTER) return MI_RESULT_INVALID_PARAMETER; break; case MFT_INSTANCE: case MFT_INSTANCE_OPT: { void** ptrPacked = (void**)(chunk + messageFields->offPackedPtr); MI_Uint32 packedSize = * (const MI_Uint32*)(chunk + messageFields->offPackedSize); *ptr = 0; if (*ptrPacked) { if (!Batch_FixPointer( batch, ptrAdjustmentInfo, ptrAdjustmentInfoCount, ptrPacked)) return MI_RESULT_INVALID_PARAMETER; if (!skipInstanceUnpack && !_UnpackInstance( batch, *ptrPacked, packedSize, (MI_Instance**)ptr)) return MI_RESULT_INVALID_PARAMETER; } else if (messageFields->type == MFT_INSTANCE) return MI_RESULT_INVALID_PARAMETER; } break; default: break; } messageFields++; } return MI_RESULT_OK; } static MI_Result _Clone( const Message* msgSrc, Message* msg, const MessageField* messageFields, size_t size) { char* chunk = (char*)msg; Batch* batch = msg->batch; const char* chunkSrc = (const char*)msgSrc; /* copy all primitve data first */ memcpy(chunk + sizeof(Message), chunkSrc + sizeof(Message), size - sizeof(Message)); while (messageFields->type != MFT_END_OF_LIST) { void** ptr = (void**)(chunk + messageFields->off); void** ptrSrc = (void**)(chunkSrc + messageFields->off); switch (messageFields->type) { case MFT_POINTER_SET_NULL: default: break; case MFT_POINTER_OPT: case MFT_POINTER: if (*ptrSrc) { *ptr = Batch_Strdup2(batch, (const char*)*ptrSrc); if (!*ptr) return MI_RESULT_FAILED; } else if (messageFields->type == MFT_POINTER) return MI_RESULT_INVALID_PARAMETER; break; case MFT_INSTANCE: case MFT_INSTANCE_OPT: { void** ptrPacked = (void**)(chunk + messageFields->offPackedPtr); MI_Uint32* packedSize = (MI_Uint32*)(chunk + messageFields->offPackedSize); const void* ptrPackedSrc = *(void**)(chunkSrc + messageFields->offPackedPtr); MI_Uint32 packedSizeSrc = *(MI_Uint32*)(chunkSrc + messageFields->offPackedSize); *ptr = 0; if (ptrPackedSrc) { /* Take existing packed instance if exist (received from binary protocol */ *packedSize = packedSizeSrc; *ptrPacked = Batch_Get(batch, packedSizeSrc); if (!*ptrPacked) return MI_RESULT_FAILED; memcpy(*ptrPacked, ptrPackedSrc, packedSizeSrc); } else if (*ptrSrc) { /* Pack instance in binary buffer (received form wsman) */ if (MI_RESULT_OK != InstanceToBatch( (const MI_Instance*)(*ptrSrc), NULL, /* filterProperties */ NULL, /* filterPropertiesData */ batch, ptrPacked, packedSize)) return MI_RESULT_FAILED; } else if (messageFields->type == MFT_INSTANCE) /* Return error if non-optional parameter is missing */ return MI_RESULT_INVALID_PARAMETER; } break; } messageFields++; } return MI_RESULT_OK; } MI_Result MessageFromBatch( Batch* batch, void* originalMsgPtr, const Header_BatchInfoItem* ptrAdjustmentInfo, size_t ptrAdjustmentInfoCount, MI_Boolean skipInstanceUnpack, Message** msgOut) { Message* msg = originalMsgPtr; MI_Uint32 index; if (!Batch_FixPointer( batch, ptrAdjustmentInfo, ptrAdjustmentInfoCount, (void*)&msg)) return MI_RESULT_INVALID_PARAMETER; /* fix base part of message */ msg->batch = batch; msg->refCounter = 1; if (MI_RESULT_OK != _RestoreMessage( msg, ptrAdjustmentInfo, ptrAdjustmentInfoCount, skipInstanceUnpack, baseMessageFields)) return MI_RESULT_INVALID_PARAMETER; index = (MI_Uint32)msg->tag; if (index >= MI_COUNT(allMessages)) return MI_RESULT_INVALID_PARAMETER; if (MI_RESULT_OK != _RestoreMessage( msg, ptrAdjustmentInfo, ptrAdjustmentInfoCount, skipInstanceUnpack, allMessages[index].fields)) return MI_RESULT_INVALID_PARAMETER; *msgOut = msg; return MI_RESULT_OK; } MI_Result MessagePackCloneForBinarySending( Message* msgSrc, Message** msgOut) { Message* msg = msgSrc; MI_Uint32 index; index = (MI_Uint32)msg->tag; if (index >= MI_COUNT(allMessages)) return MI_RESULT_INVALID_PARAMETER; if (!allMessages[index].cloneRequired) { *msgOut = msg; Message_AddRef(msg); return MI_RESULT_OK; } /* create a copy */ msg = __Message_New(msgSrc->tag, allMessages[index].size, msgSrc->msgID, msgSrc->flags); if (!msg) return MI_RESULT_FAILED; msg->clientID = msgSrc->clientID; if (MI_RESULT_OK != _Clone(msgSrc, msg, allMessages[index].fields, allMessages[index].size)) { Message_Release(msg); return MI_RESULT_FAILED; } *msgOut = msg; return MI_RESULT_OK; }