/* **============================================================================== ** ** 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. ** **============================================================================== */ #ifndef _omi_messages_h #define _omi_messages_h #include "config.h" #include #include #include "batch.h" #include "instance.h" #include "stringarray.h" #include "atomic.h" #include "user.h" BEGIN_EXTERNC /* **============================================================================== ** ** MessageTag ** ** Enumeration of all message tags. ** **============================================================================== */ typedef enum _MessageTag { 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 } MessageTag; /* **============================================================================== ** ** MessageFlag ** ** Supported flags for message. ** **============================================================================== */ typedef enum _MessageFlag { /* Instance encoding type (only one can be set at a time) */ BinaryProtocolFlag = 0x0001, WSMANFlag = 0x0002, CIMXMLFlag = 0x0004, /* WSMAN-specific encoding options */ WSMAN_ObjectAndEPRFlag =0x0018, WSMAN_EPRFlag = 0x0008, WSMAN_ObjectFlag = 0x0010, WSMAN_CreatedEPRFlag = 0x0020 } MessageFlag; /* **============================================================================== ** ** Message ** ** Base type for all messages. ** **============================================================================== */ typedef struct _Message Message; struct _Message { /* Links for inserting messages onto linked-lists */ struct _Message* next; struct _Message* prev; /* The batch this message was allocated from */ Batch *batch; /* original request (can be NULL); lifetime controlled by ref-counter */ struct _Message* request; /* The message tag (see MessageTag enum above) */ MI_Uint32 tag; /* Flags for message processing - like instance encoding type (see MessageFlag enum above) */ MI_Uint32 flags; /* ref counter */ AtomicInt refCounter; /* Message identifier derived from the original request */ MI_Uint64 msgID; /* Client identifier derived from requestor */ MI_Uint64 clientID; /* Callback used to deliver response to this message */ void (*callback)(Message* message, void* callbackData); /* Data passed as 2nd argument of 'callback' */ void* callbackData; /* Message's destructor [opt] 'Release' will call dtor (if set) right before destroying the message */ void (*dtor)(Message* message, void* callbackData); /* Data passed as 2nd argument of 'dtor' */ void* dtorData; /* Server -> agent IPC specific */ const char* libraryName; /* Requestor information */ uid_t uid; gid_t gid; }; Message* __Message_New( MessageTag tag, size_t structSize, MI_Uint64 msgID, MI_Uint32 flags); void Message_Release( Message* self); MI_INLINE void Message_AddRef( Message* self) { AtomicInc(&self->refCounter); } MI_INLINE void Message_SetRequest( Message* self, Message* request) { if (self->request) Message_Release(self->request); self->request = request; if (self->request) Message_AddRef(self->request); } /* Verifies if message is final reposne to the initial request */ MI_INLINE MI_Boolean Message_IsFinalRepsonse( const Message* msg) { if (PostResultMsgTag == msg->tag || NoOpRspTag == msg->tag || SubscribeResTag == msg->tag) return MI_TRUE; return MI_FALSE; } /* **============================================================================== ** ** PostResultMsg ** ** generic error response ** **============================================================================== */ typedef struct _PostResultMsg { Message base; MI_Result result; } PostResultMsg; MI_INLINE PostResultMsg* PostResultMsg_New( MI_Uint64 msgID) { return (PostResultMsg*)__Message_New( PostResultMsgTag, sizeof(PostResultMsg), msgID, 0); } MI_INLINE void PostResultMsg_Release( PostResultMsg* self) { Message_Release(&self->base); } void PostResultMsg_Print(const PostResultMsg* msg, FILE* os); /* **============================================================================== ** ** DispResultMsg ** ** interanl strucutre for dispatcher ** dispatcher keeps track of multiple 'enumerate' responses ** **============================================================================== */ typedef struct _DispResultMsg { Message base; /* number of outstanding requests */ AtomicInt requestCounter; /* current result */ MI_Result result; } DispResultMsg; MI_INLINE DispResultMsg* DispResultMsg_New( MI_Uint64 msgID) { return (DispResultMsg*)__Message_New( DispResultMsgTag, sizeof(DispResultMsg), msgID, 0); } MI_INLINE void DispResultMsg_Release( DispResultMsg* self) { Message_Release(&self->base); } void DispResultMsg_Print(const DispResultMsg* msg, FILE* os); /* **============================================================================== ** ** GetInstanceReq ** ** A CIM GetInstance request (see DSP0200). ** **============================================================================== */ typedef struct _GetInstanceReq { Message base; MI_ConstString nameSpace; /* un-packed version of instance */ MI_Instance* instanceName; /* packed version of instance */ void* packedInstanceNamePtr; MI_Uint32 packedInstanceNameSize; MI_Boolean includeClassOrigin; StringArray* propertySet; } GetInstanceReq; MI_INLINE GetInstanceReq* GetInstanceReq_New( MI_Uint64 msgID, MI_Uint32 flags) { return (GetInstanceReq*)__Message_New( GetInstanceReqTag, sizeof(GetInstanceReq), msgID, flags); } MI_INLINE void GetInstanceReq_Release( GetInstanceReq* self) { Message_Release(&self->base); } void GetInstanceReq_Print(const GetInstanceReq* msg, FILE* os); /* **============================================================================== ** ** CreateInstanceReq ** ** A CIM CreateInstance request (see DSP0200). ** **============================================================================== */ typedef struct _CreateInstanceReq { Message base; MI_ConstString nameSpace; MI_Instance* instance; void* packedInstancePtr; MI_Uint32 packedInstanceSize; StringArray* propertySet; } CreateInstanceReq; MI_INLINE CreateInstanceReq* CreateInstanceReq_New( MI_Uint64 msgID, MI_Uint32 flags) { return (CreateInstanceReq*)__Message_New( CreateInstanceReqTag, sizeof(CreateInstanceReq), msgID, flags); } MI_INLINE void CreateInstanceReq_Release( CreateInstanceReq* self) { Message_Release(&self->base); } void CreateInstanceReq_Print(const CreateInstanceReq* msg, FILE* os); /* **============================================================================== ** ** ModifyInstanceReq ** ** A CIM ModifyInstance request (see DSP0200). ** **============================================================================== */ typedef struct _ModifyInstanceReq { Message base; MI_ConstString nameSpace; MI_Instance* instance; void* packedInstancePtr; MI_Uint32 packedInstanceSize; StringArray* propertySet; } ModifyInstanceReq; MI_INLINE ModifyInstanceReq* ModifyInstanceReq_New( MI_Uint64 msgID, MI_Uint32 flags) { return (ModifyInstanceReq*)__Message_New( ModifyInstanceReqTag, sizeof(ModifyInstanceReq), msgID, flags); } MI_INLINE void ModifyInstanceReq_Release( ModifyInstanceReq* self) { Message_Release(&self->base); } void ModifyInstanceReq_Print(const ModifyInstanceReq* msg, FILE* os); /* **============================================================================== ** ** DeleteInstanceReq ** ** A CIM DeleteInstance request (see DSP0200). ** **============================================================================== */ typedef struct _DeleteInstanceReq { Message base; MI_ConstString nameSpace; MI_Instance* instanceName; void* packedInstanceNamePtr; MI_Uint32 packedInstanceNameSize; } DeleteInstanceReq; MI_INLINE DeleteInstanceReq* DeleteInstanceReq_New( MI_Uint64 msgID, MI_Uint32 flags) { return (DeleteInstanceReq*)__Message_New( DeleteInstanceReqTag, sizeof(DeleteInstanceReq), msgID, flags); } MI_INLINE void DeleteInstanceReq_Release( DeleteInstanceReq* self) { Message_Release(&self->base); } void DeleteInstanceReq_Print( const DeleteInstanceReq* msg, FILE* os); /* **============================================================================== ** ** InvokeReq ** ** A CIM Invoke request (see DSP0200). ** **============================================================================== */ typedef struct _InvokeReq { Message base; MI_ConstString nameSpace; MI_ConstString function; MI_ConstString className; /* for static functions only, otherwise null */ /* un-packed version of instance (for non-static functions) and parameters */ MI_Instance* instance; MI_Instance* instanceParams; /* packed version of instance */ void* packedInstancePtr; void* packedInstanceParamsPtr; MI_Uint32 packedInstanceSize; MI_Uint32 packedInstanceParamsSize; } InvokeReq; MI_INLINE InvokeReq* InvokeReq_New( MI_Uint64 msgID, MI_Uint32 flags) { return (InvokeReq*)__Message_New( InvokeReqTag, sizeof(InvokeReq), msgID, flags); } MI_INLINE void InvokeReq_Release( InvokeReq* self) { Message_Release(&self->base); } void InvokeReq_Print(const InvokeReq* msg, FILE* os); /* **============================================================================== ** ** AssociatorsOfReq ** ** A CIM "Associators of" request (see DSP0200). ** **============================================================================== */ typedef struct _AssociatorsOfReq { Message base; MI_ConstString nameSpace; MI_ConstString assocClass; MI_ConstString resultClass; MI_ConstString role; MI_ConstString resultRole; /* dispatcher to provider only */ MI_ConstString className; /* un-packed version of instance */ MI_Instance* instance; /* packed version of instance */ void* packedInstancePtr; MI_Uint32 packedInstanceSize; } AssociatorsOfReq; MI_INLINE AssociatorsOfReq* AssociatorsOfReq_New( MI_Uint64 msgID, MI_Uint32 flags) { return (AssociatorsOfReq*)__Message_New( AssociatorsOfReqTag, sizeof(AssociatorsOfReq), msgID, flags); } MI_INLINE void AssociatorsOfReq_Release( AssociatorsOfReq* self) { Message_Release(&self->base); } void AssociatorsOfReq_Print(const AssociatorsOfReq* msg, FILE* os); /* **============================================================================== ** ** ReferencesOfReq ** ** A CIM "References of" request (see DSP0200). ** **============================================================================== */ typedef struct _ReferencesOfReq { Message base; MI_ConstString nameSpace; MI_ConstString assocClass; MI_ConstString role; /* dispatcher to provider only */ MI_ConstString className; /* un-packed version of instance */ MI_Instance* instance; /* packed version of instance */ void* packedInstancePtr; MI_Uint32 packedInstanceSize; } ReferencesOfReq; MI_INLINE ReferencesOfReq* ReferencesOfReq_New( MI_Uint64 msgID, MI_Uint32 flags) { return (ReferencesOfReq*)__Message_New( ReferencesOfReqTag, sizeof(ReferencesOfReq), msgID, flags); } MI_INLINE void ReferencesOfReq_Release( ReferencesOfReq* self) { Message_Release(&self->base); } void ReferencesOfReq_Print(const ReferencesOfReq* msg, FILE* os); /* **============================================================================== ** ** PostInstanceMsg ** ** A CIM GetInstance response (see DSP0200). ** **============================================================================== */ typedef struct _PostInstanceMsg { Message base; /* un-packed version of instance */ MI_Instance* instance; /* packed version of instance */ void* packedInstancePtr; MI_Uint32 packedInstanceSize; } PostInstanceMsg; MI_INLINE PostInstanceMsg* PostInstanceMsg_New( MI_Uint64 msgID) { return (PostInstanceMsg*)__Message_New( PostInstanceMsgTag, sizeof(PostInstanceMsg), msgID, 0); } MI_INLINE void PostInstanceMsg_Release( PostInstanceMsg* self) { Message_Release(&self->base); } void PostInstanceMsg_Print(const PostInstanceMsg* msg, FILE* os); /* **============================================================================== ** ** EnumerateInstancesReq ** ** A CIM EnumerateInstances request (see DSP0200). ** **============================================================================== */ typedef struct _EnumerateInstancesReq { Message base; MI_ConstString nameSpace; MI_ConstString className; /* Used for 'base-properties-only' mode to transfer request's class-name */ MI_ConstString requestClassName; StringArray* propertySet; MI_Boolean deepInheritance; MI_Boolean includeClassOrigin; MI_Boolean basePropertiesOnly; /* Query language (or null none) */ const MI_Char* queryLanguage; /* Query expression (or null none) */ const MI_Char* queryExpression; /* Compiled WQL query */ struct _WQL* wql; } EnumerateInstancesReq; MI_INLINE EnumerateInstancesReq* EnumerateInstancesReq_New( MI_Uint64 msgID, MI_Uint32 flags) { return (EnumerateInstancesReq*)__Message_New( EnumerateInstancesReqTag, sizeof(EnumerateInstancesReq), msgID, flags); } MI_INLINE void EnumerateInstancesReq_Release( EnumerateInstancesReq* self) { Message_Release(&self->base); } void EnumerateInstancesReq_Print(const EnumerateInstancesReq* msg, FILE* os); /* **============================================================================== ** ** SubscribeReq ** ** Subscribe request (internal representation of it) ** **============================================================================== */ typedef struct _SubscribeReq { Message base; MI_ConstString nameSpace; MI_ConstString className; MI_ConstString filter; MI_ConstString language; /* used for disp -> provmgr */ MI_Uint64 ctxID; /* used for disp -> provider */ MI_Uint64 subscriptionID; } SubscribeReq; MI_INLINE SubscribeReq* SubscribeReq_New( MI_Uint64 msgID, MI_Uint32 flags) { return (SubscribeReq*)__Message_New( SubscribeReqTag, sizeof(SubscribeReq), msgID, flags); } MI_INLINE void SubscribeReq_Release( SubscribeReq* self) { Message_Release(&self->base); } void SubscribeReq_Print(const SubscribeReq* msg, FILE* os); /* **============================================================================== ** ** SubscribeRes ** ** Subscribe request (internal representation of it) ** **============================================================================== */ typedef struct _SubscribeRes { Message base; MI_ConstString subscriptionID; } SubscribeRes; MI_INLINE SubscribeRes* SubscribeRes_New( MI_Uint64 msgID) { return (SubscribeRes*)__Message_New( SubscribeResTag, sizeof(SubscribeRes), msgID, 0); } MI_INLINE void SubscribeRes_Release( SubscribeRes* self) { Message_Release(&self->base); } void SubscribeRes_Print(const SubscribeRes* msg, FILE* os); /* **============================================================================== ** ** NoOpReq ** ** A NoOp request. ** **============================================================================== */ typedef struct _NoOpReq { Message base; } NoOpReq; MI_INLINE NoOpReq* NoOpReq_New( MI_Uint64 msgID) { return (NoOpReq*)__Message_New( NoOpReqTag, sizeof(NoOpReq), msgID, BinaryProtocolFlag); } MI_INLINE void NoOpReq_Release( NoOpReq* self) { Message_Release(&self->base); } void NoOpReq_Print(const NoOpReq* msg, FILE* os); /* **============================================================================== ** ** NoOpRsp ** ** A NoOp request. ** **============================================================================== */ typedef struct _NoOpRsp { Message base; } NoOpRsp; MI_INLINE NoOpRsp* NoOpRsp_New( MI_Uint64 msgID) { return (NoOpRsp*)__Message_New( NoOpRspTag, sizeof(NoOpRsp), msgID, 0); } MI_INLINE void NoOpRsp_Release( NoOpRsp* self) { Message_Release(&self->base); } void NoOpRsp_Print(const NoOpRsp* msg, FILE* os); /* **============================================================================== ** ** BinProtocolNotification ** ** A internal notification transfered over bin protocol. ** **============================================================================== */ typedef enum _BinProtNotificationType { BinNotificationAgentIdle = 0, BinNotificationConnectRequest = 1, BinNotificationConnectResponse = 2 } BinProtNotificationType; #define AUTH_RANDOM_DATA_SIZE 64 typedef struct _BinProtocolNotification { Message base; /* see BinProtNotificationType for supported types */ MI_Uint32 type; /* **** Connect-request specific data **** */ /* explicit auth [opt] */ const char* user; const char* password; /* implicit auth - Requestor information */ uid_t uid; gid_t gid; /* File-based authentication - files's content */ unsigned char authData[AUTH_RANDOM_DATA_SIZE]; /* **** Connect-response specific data **** */ /* ok/access-denied */ MI_Result result; /* file name - client has to read it and send back content */ const char* authFile; } BinProtocolNotification; MI_INLINE BinProtocolNotification* BinProtocolNotification_New(BinProtNotificationType type) { BinProtocolNotification* res = (BinProtocolNotification*)__Message_New( BinProtocolNotificationTag, sizeof(BinProtocolNotification), 0, 0); if (res) res->type = type; return res; } MI_INLINE void BinProtocolNotification_Release( BinProtocolNotification* self) { Message_Release(&self->base); } void BinProtocolNotification_Print(const BinProtocolNotification* msg, FILE* os); /* **============================================================================== ** ** binary transport with batch support ** ** ** **============================================================================== */ MI_Result MessageFromBatch( Batch* batch, void* originalMsgPtr, const Header_BatchInfoItem* ptrAdjustmentInfo, size_t ptrAdjustmentInfoCount, MI_Boolean skipInstanceUnpack, Message** msgOut ); /* **============================================================================== ** ** Creates a clone of given message, ** suitable for sending with binary protocol ** This is needed to: ** - make batch smaller (no small blocks form instance's parts ** - all instances are packed ** ** Note: requests without instances (like Enum) don't need a copy - ** add-ref-ed original message is returned in that case ** **============================================================================== */ MI_Result MessagePackCloneForBinarySending( Message* msgSrc, Message** msgOut); /* **============================================================================== ** ** Print the message ** **============================================================================== */ void MessagePrint(const Message* msg, FILE* os); /* **============================================================================== ** ** Uint64ToPtr() ** PtrToUint64() ** **============================================================================== */ MI_INLINE void* Uint64ToPtr(MI_Uint64 x) { union U { void* ptr; MI_Uint64 x; }; union U u; u.x = x; return u.ptr; } MI_INLINE MI_Uint64 PtrToUint64(void* ptr) { union U { void* ptr; MI_Uint64 x; }; union U u; u.ptr = ptr; return u.x; } END_EXTERNC #endif /* _omi_messages_h */