/*============================================================================ * Copyright (C) Microsoft Corporation, All rights reserved. *============================================================================ */ #include #include #include #include #include #include #include #include #include #include #include "xmlserializer.h" //******************************************XMLSERIALIZER Creation/Deletion************************ /* Create serializer object */ MI_Result MI_CALL XmlSerializer_Create( _In_ MI_Application *application, MI_Uint32 flags, _In_z_ MI_Char *format, _Out_ MI_Serializer *serializer) { if ((application == NULL) || (flags != 0) || (format == NULL) || (serializer == NULL)) { return MI_RESULT_INVALID_PARAMETER; } if (Tcscmp(format, PAL_T("MI_XML")) != 0) //TODO: Case sensitive? { return MI_RESULT_NOT_SUPPORTED; } memset(serializer, 0, sizeof(*serializer)); return MI_RESULT_OK; } /* Close serializer object */ MI_Result MI_CALL XmlSerializer_Close( _Inout_ MI_Serializer *serializer) { return MI_RESULT_OK; } //******************************************Class Serialization logic************************ #define IsOptionTrue(flags, option) ((flags & (option)) != 0) #define SERIALIZE_NO_ESCAPE 0 //Length of string literal #define WCSLEN(string) ((sizeof(string)/sizeof(string[0]))-1) /* Preferred write mechanism for string literal to the buffer. We do sizeof string which is a compile-time calculation. */ #define WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferUsed, bufferToWrite, escapingDepth, result) WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferUsed, bufferToWrite, WCSLEN(bufferToWrite), escapingDepth, result) /* Preferred write mechanism as we don't need to Tcslen the buffer to write */ static void WriteBuffer_StringWithLength(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_reads_z_(bufferToWriteLength) const MI_Char *bufferToWrite, MI_Uint32 bufferToWriteLength, MI_Uint32 escapingDepth, _Inout_ MI_Result *result); /* Don't use unless we really don't know the length as we will Tcslen the buffer to write */ #define WriteBuffer_String(clientBuffer, clientBufferLength, clientBufferUsed, bufferToWrite, escapingDepth, result) WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferUsed, bufferToWrite, Tcslen(bufferToWrite), escapingDepth, result) /* writes the textual version of MI_Type */ static void WriteBuffer_MiType(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferUsed, MI_Type type, MI_Uint32 escapingDepth, _Inout_ MI_Result *result); /* writes the textual version of MI_Array based on MI_Type. */ static void WriteBuffer_MiValueArray(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferUsed, MI_Type type, _In_ const MI_Array *value, MI_Uint32 escapingDepth, _Inout_ MI_Result *result); /* writes the textual version of MI_Value based on MI_Type. */ static void WriteBuffer_MiValue(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferUsed, MI_Type type, _In_opt_ const MI_Value *value, MI_Boolean includeTags, MI_Uint32 escapingDepth, _Inout_ MI_Result *result); /* writes the textual version of MI_Qualifier array. */ static void WriteBuffer_MiQualifierSet(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferUsed, _In_ const MI_QualifierSet *qualifierSet, MI_Uint32 flagsToSerializeAsQualifiers, MI_Boolean isQualOnInheritedElement, _Inout_ MI_Result *result); static void WriteBuffer_MiParamPropertyQualifierSet(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferUsed, _In_ const MI_QualifierSet *qualifierSet, MI_Uint32 flagsToSerializeAsQualifiers, MI_Boolean isQualOnInheritedElement, MI_Boolean isEmbeddedProperty, _In_opt_ const MI_Char *referenceClassForEmbeddedProperty, _Inout_ MI_Result *result); static void WriteBuffer_EmbeddedPropertyQualifier(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_opt_ const MI_Char *referenceClassForEmbeddedProperty, _Inout_ MI_Result *result); static void WriteBuffer_MiFlagQualifiers(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer,MI_Uint32 clientBufferLength,_Inout_ MI_Uint32 *clientBufferNeeded,MI_Uint32 flagsToSerializeAsQualifiers,_Inout_ MI_Result *result); /* writes the textual version of %CIMName. (name="name") */ static void WriteBuffer_CimName(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferUsed, _In_z_ const MI_Char* name, MI_Uint32 escapingDepth, _Inout_ MI_Result *result); static void WriteBuffer_Uint32(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, MI_Uint32 number, _Inout_ MI_Result *result); static void WriteBuffer_SerializeClass(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, MI_Uint32 flags, _In_ const MI_Class *miClass, _In_opt_z_ const MI_Char *namespaceName,_In_opt_z_ const MI_Char *serverName,_Out_ MI_Result *result); static void WriteBuffer_Instance(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer,MI_Uint32 clientBufferLength,_Inout_ MI_Uint32 *clientBufferNeeded,_In_ const MI_Instance *instance,MI_Uint32 escapingDepth, _Out_ MI_Result *result); static void WriteBuffer_InstanceReference(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer,MI_Uint32 clientBufferLength,_Inout_ MI_Uint32 *clientBufferNeeded,_In_opt_z_ const MI_Char *namespaceName, _In_opt_z_ const MI_Char *serverName, _In_ const MI_Instance *refValue, MI_Uint32 escapingDepth, _Inout_ MI_Result *result); static void WriteBuffer_MiPropertyDecls(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_ const MI_Class *miClass, MI_Uint32 flags, _In_z_ const MI_Char *className,_In_opt_z_ const MI_Char *namespaceName, _In_opt_z_ const MI_Char *serverName , _In_opt_ const char *instanceStart, MI_Uint32 escapingDepth, _Inout_ MI_Result *result); //Write an instance parameter MI_Field static void WriteBuffer_MiTypeField(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer,MI_Uint32 clientBufferLength,_Inout_ MI_Uint32 *clientBufferNeeded,MI_Type type,_In_ const char *fieldValue, MI_Uint32 escapingDepth, _Inout_ MI_Result *result); //Write an instance array parameter MI_ArrayField static void WriteBuffer_MiArrayField(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer,MI_Uint32 clientBufferLength,_Inout_ MI_Uint32 *clientBufferNeeded,MI_Type type,_In_ MI_ArrayField *arrayField, MI_Uint32 escapingDepth, _Inout_ MI_Result *result); static void WriteBuffer_NAMESPACEPATH(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer,MI_Uint32 clientBufferLength,_Inout_ MI_Uint32 *clientBufferNeeded,_In_z_ const MI_Char *namespaceName, _In_z_ const MI_Char *serverName, MI_Uint32 escapingDepth, _Inout_ MI_Result *result); static void WriteBuffer_LOCALNAMESPACEPATH(_Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer,MI_Uint32 clientBufferLength,_Inout_ MI_Uint32 *clientBufferNeeded,_In_z_ const MI_Char *namespaceName, MI_Uint32 escapingDepth, _Inout_ MI_Result *result); static void WriteBuffer_Instance( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_ const MI_Instance *instance_, MI_Uint32 escapingDepth, _Out_ MI_Result *result) { // No one is using OSC_Instance structure inside OMI; // so I am assuming all instances here are going to be MI_Instances // so getting rid of this OSC_Instance from the reused code and replacing it with MI_Instance // in the future if someone adds OSC_Instance in OMI then add this back // MI_Instance *instance = (MI_Instance*)((OSC_Instance*)instance_)->self; //In case this is dynamic instance point to the real one, otherwise it points to ourself! const MI_Instance *instance = instance_; MI_Class classOfInstance = MI_CLASS_NULL; const MI_Char *classNameOfInstance = NULL; *result = MI_RESULT_OK; *result = MI_Instance_GetClassExt(instance, &classOfInstance); *result = GetClassExtendedFt(&classOfInstance)->GetClassName(&classOfInstance, &classNameOfInstance); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); /* PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE */ // casting done since it does not compile on non-windows WriteBuffer_MiPropertyDecls(clientBuffer, clientBufferLength, clientBufferNeeded, &classOfInstance, MI_TRUE, classNameOfInstance, instance->nameSpace, instance->serverName, (char*)instance, escapingDepth, result); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } static void WriteBuffer_SerializeClass( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, MI_Uint32 flags, _In_ const MI_Class *miClass, _In_opt_z_ const MI_Char *namespaceName, _In_opt_z_ const MI_Char *serverName, _Out_ MI_Result *result) { const MI_Char *miClassName = NULL; const MI_Char *miParentClassName = NULL; MI_QualifierSet qualifierSet; MI_Uint32 numQualifiers = 0; *result = MI_RESULT_OK; WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T("GetClassName(miClass, &miClassName); if(miClassName) { WriteBuffer_CimName(clientBuffer, clientBufferLength, clientBufferNeeded, miClassName, SERIALIZE_NO_ESCAPE, result); } /* %SuperClass; */ GetClassExtendedFt(miClass)->GetParentClassName(miClass, &miParentClassName); if (miParentClassName) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(" SUPERCLASS=\""), SERIALIZE_NO_ESCAPE, result); WriteBuffer_String(clientBuffer, clientBufferLength, clientBufferNeeded, miParentClassName, SERIALIZE_NO_ESCAPE, result); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T("\""), SERIALIZE_NO_ESCAPE, result); } /* %DERIVATION; */ if(IsOptionTrue(flags, MI_SERIALIZER_FLAGS_INCLUDE_INHERITANCE_HIERARCHY)) { const MI_Class *currentClass = miClass; MI_Class currentSuperClass; MI_Uint32 countOfClasses = 0; GetClassExtendedFt(currentClass)->GetParentClassExt(currentClass, ¤tSuperClass); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(" DERIVATION=\""), SERIALIZE_NO_ESCAPE, result); while(miParentClassName) { trace_XmlSerializer_CurrentParent(tcs(miParentClassName)); // before writing first superclassname; you would not need a separator otherwise you will if(countOfClasses != 0) { // preventing infinite loop if(countOfClasses == 0xFFFFFFFF) { *result = MI_RESULT_FAILED; return; } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(","), SERIALIZE_NO_ESCAPE, result); } #ifdef _MSC_VER #pragma prefast(push) #pragma prefast (disable: 26018) #endif // write the super class name in the list WriteBuffer_String(clientBuffer, clientBufferLength, clientBufferNeeded, miParentClassName, SERIALIZE_NO_ESCAPE, result); #ifdef _MSC_VER #pragma prefast(pop) #endif // clear out the classname we just wrote miParentClassName = NULL; // go up one level in the parent chain currentClass = ¤tSuperClass; // if there is still a superclass, get its name if(GetClassExtendedFt(currentClass)->GetParentClassExt(currentClass, ¤tSuperClass) == MI_RESULT_OK) { *result = GetClassExtendedFt(¤tSuperClass)->GetClassName(¤tSuperClass, &miParentClassName); } countOfClasses++; } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T("\""), SERIALIZE_NO_ESCAPE, result); } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(">"), SERIALIZE_NO_ESCAPE, result); /* QUALIFIERS */ if(IsOptionTrue(flags, MI_SERIALIZER_FLAGS_INCLUDE_QUALIFIERS)) { MI_Uint32 classFlags = 0; GetClassExtendedFt(miClass)->GetClassQualifierSet(miClass, &qualifierSet); GetQualifierSetFt(&qualifierSet)->GetQualifierCount(&qualifierSet, &numQualifiers); GetClassExtendedFt(miClass)->GetClassFlagsExt(miClass, &classFlags); WriteBuffer_MiQualifierSet(clientBuffer, clientBufferLength, clientBufferNeeded, &qualifierSet, classFlags, MI_FALSE, result); } /* PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE */ WriteBuffer_MiPropertyDecls(clientBuffer, clientBufferLength, clientBufferNeeded, miClass, flags, miClassName, namespaceName, serverName, NULL, SERIALIZE_NO_ESCAPE, result); /* METHOD */ { MI_Uint32 methodCount; MI_Uint32 totalMethodCount; MI_Uint32 parameterCount; const MI_Char *methodName = NULL; MI_QualifierSet methodQualifierSet; MI_ParameterSet parameterSet; MI_Uint32 methodParameterCount; const MI_Char *parameterName = NULL; MI_Type parameterType; MI_Uint32 parameterSubscript; MI_Char *referenceClass = NULL; MI_Char *methodOriginClass = NULL; MI_Char *methodPropagatorClass = NULL; MI_QualifierSet parameterQualifierSet; MI_Uint32 methodFlags = 0; MI_Uint32 parameterFlags = 0; GetClassExtendedFt(miClass)->GetMethodCount(miClass, &totalMethodCount); for (methodCount = 0; methodCount != totalMethodCount; methodCount++) { MI_Boolean isInheritedElement = MI_FALSE; GetClassExtendedFt(miClass)->GetMethodAtExt(miClass, methodCount, &methodName, &methodOriginClass, &methodPropagatorClass, &methodQualifierSet, ¶meterSet, &methodFlags); /* If not serializing deep and we are not the propagator of the property then we need to skip this one */ if (!IsOptionTrue(flags, MI_SERIALIZER_FLAGS_CLASS_DEEP | MI_SERIALIZER_FLAGS_INCLUDE_INHERITED_ELEMENTS) && methodPropagatorClass && Tcscmp(methodPropagatorClass, miClassName)!=0) { continue; } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T("GetParameterCount(¶meterSet, &methodParameterCount); GetParameterSetExtendedFt(¶meterSet)->GetMethodReturnType(¶meterSet, ¶meterType, ¶meterQualifierSet); /* %CIMType; */ WriteBuffer_MiType(clientBuffer, clientBufferLength, clientBufferNeeded, (MI_Type)(parameterType&~MI_ARRAY), SERIALIZE_NO_ESCAPE, result); /* %ClassOrigin; */ if (IsOptionTrue(flags, MI_SERIALIZER_FLAGS_INCLUDE_CLASS_ORIGIN) && methodOriginClass) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(" CLASSORIGIN=\""), SERIALIZE_NO_ESCAPE, result); WriteBuffer_String(clientBuffer, clientBufferLength, clientBufferNeeded, methodOriginClass, SERIALIZE_NO_ESCAPE, result); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T("\""), SERIALIZE_NO_ESCAPE, result); } /* %Propagated; */ if (methodPropagatorClass && (Tcscasecmp(methodPropagatorClass, miClassName) != 0)) { isInheritedElement = MI_TRUE; WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(" PROPAGATED=\"true\""), SERIALIZE_NO_ESCAPE, result); } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(">"), SERIALIZE_NO_ESCAPE, result); /* QUALIFIERS */ if(IsOptionTrue(flags, MI_SERIALIZER_FLAGS_INCLUDE_QUALIFIERS)) { WriteBuffer_MiQualifierSet(clientBuffer, clientBufferLength, clientBufferNeeded, &methodQualifierSet, methodFlags, isInheritedElement, result); } /* even though this loop starts from 0, the GetParameterAt method increments the index passed to it so we will get the parameters from the index 1 */ for (parameterCount = 0; parameterCount < methodParameterCount; parameterCount++) { GetParameterSetExtendedFt(¶meterSet)->GetParameterAtExt(¶meterSet, parameterCount, ¶meterName, ¶meterType, ¶meterSubscript, &referenceClass, ¶meterQualifierSet, ¶meterFlags); /* Start of PARAMETER | PARAMETER.REFERENCE | PARAMETER_ARRAY | PARAMETER.REFARRAY */ if (parameterType == MI_REFERENCE) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), SERIALIZE_NO_ESCAPE, result); /* QUALIFIERS */ if(IsOptionTrue(flags, MI_SERIALIZER_FLAGS_INCLUDE_QUALIFIERS)) { WriteBuffer_MiParamPropertyQualifierSet(clientBuffer, clientBufferLength, clientBufferNeeded, ¶meterQualifierSet, parameterFlags, MI_FALSE, ((parameterType&~MI_ARRAY) == MI_INSTANCE), referenceClass, result); } /* End of PARAMETER | PARAMETER.REFERENCE | PARAMETER_ARRAY | PARAMETER.REFARRAY */ if (parameterType == MI_REFERENCE) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), SERIALIZE_NO_ESCAPE, result); } else if (parameterType == MI_REFERENCEA) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), SERIALIZE_NO_ESCAPE, result); } else if (parameterType & MI_ARRAY) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), SERIALIZE_NO_ESCAPE, result); } else { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), SERIALIZE_NO_ESCAPE, result); } } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), SERIALIZE_NO_ESCAPE, result); } } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), SERIALIZE_NO_ESCAPE, result); } static void WriteBuffer_MiPropertyDecls( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_ const MI_Class *miClass, MI_Uint32 flags, _In_z_ const MI_Char *className, _In_opt_z_ const MI_Char *namespaceName, _In_opt_z_ const MI_Char *serverName, _In_opt_ const char *instanceStart, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { MI_Uint32 propertyCount; MI_Uint32 totalPropertyCount; MI_Value propertyValue; MI_Type propertyType; MI_Uint32 propertyFlags; MI_Uint32 propertySubscript; MI_Uint32 propertyOffset; MI_QualifierSet propertyQualifierSet; const MI_Char *propertyName = NULL; MI_Char *propertyReferenceClass = NULL; MI_Char *propertyOriginClass = NULL; MI_Char *propertyPropagatorClass = NULL; GetClassExtendedFt(miClass)->GetElementCount(miClass, &totalPropertyCount); /* PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE */ for (propertyCount = 0; propertyCount != totalPropertyCount; propertyCount++) { MI_Boolean propertyValueExists = MI_TRUE; MI_Boolean isInheritedElement = MI_FALSE; GetClassExtendedFt(miClass)->GetElementAtExt(miClass, propertyCount, &propertyName, &propertyValue, &propertyValueExists, &propertyType, &propertySubscript, &propertyOffset , &propertyReferenceClass, &propertyOriginClass, &propertyPropagatorClass, &propertyQualifierSet, &propertyFlags); /* If not serializing deep and we are not the propagator of the property then we need to skip this one */ //MI_SERIALIZER_FLAGS_CLASS_DEEP if (!IsOptionTrue(flags, MI_SERIALIZER_FLAGS_CLASS_DEEP | MI_SERIALIZER_FLAGS_INCLUDE_INHERITED_ELEMENTS) && propertyPropagatorClass && Tcscmp(propertyPropagatorClass, className)!=0) { continue; } else { trace_XmlSerializer_WriteBuffer_MiPropertyDecls(tcs(className), tcs(propertyPropagatorClass), tcs(propertyName)); } if (propertyType & MI_ARRAY) { if (propertyType == MI_REFERENCEA) { //Properties of type referenceArray cannot be supported. It is not CIM compliant //Overwrite error as this is a hard error. *result = MI_RESULT_NOT_SUPPORTED; return; } else { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); /* QUALIFIERS -- class only*/ if (!instanceStart && IsOptionTrue(flags, MI_SERIALIZER_FLAGS_INCLUDE_QUALIFIERS)) { if ((propertyFlags & MI_FLAG_PROPERTY) == 0) { //Dynamic classes do not have qualifiers, only flags. They don't even mark a property as being a property! //If this is a dynanic instance and this is property is an embedded instance then we need to fabricate a EmbeddedObject qualifier otherwise //deserialization will think it is a string if ((propertyType&~MI_ARRAY) == MI_INSTANCE) { WriteBuffer_EmbeddedPropertyQualifier(clientBuffer, clientBufferLength, clientBufferNeeded, propertyReferenceClass, result); } WriteBuffer_MiFlagQualifiers(clientBuffer, clientBufferLength, clientBufferNeeded, propertyFlags, result); } else { WriteBuffer_MiParamPropertyQualifierSet(clientBuffer, clientBufferLength, clientBufferNeeded, &propertyQualifierSet, propertyFlags, isInheritedElement, ((propertyType&~MI_ARRAY) == MI_INSTANCE), propertyReferenceClass, result); } } /* Values and closing element */ if (propertyType & MI_ARRAY) { if (propertyType == MI_REFERENCEA) { //Property arrays are not supported in CIM or in serialization. //This is a hard error overwriting any other error that may be there. *result = MI_RESULT_NOT_SUPPORTED; return; } else { /* VALUE.ARRAY*/ if (instanceStart) { #ifdef _MSC_VER #pragma prefast(push) #pragma prefast (disable: 26007) #endif if (propertyValueExists) WriteBuffer_MiArrayField(clientBuffer, clientBufferLength, clientBufferNeeded, propertyType, (MI_ArrayField*)(instanceStart+propertyOffset), escapingDepth, result); #ifdef _MSC_VER #pragma prefast(pop) #endif } else { if (propertyValueExists && ((propertyType & MI_FLAG_NULL) == 0)) WriteBuffer_MiValueArray(clientBuffer, clientBufferLength, clientBufferNeeded, propertyType, (MI_Array*)(&propertyValue), SERIALIZE_NO_ESCAPE, result); } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } } else if (propertyType == MI_REFERENCE) { MI_Instance *refValue = NULL; if (instanceStart) { MI_ReferenceField *field = (MI_ReferenceField *)(instanceStart+propertyOffset); refValue = field->value; } else { if (propertyValueExists) { refValue = propertyValue.instance; } } if (refValue) { WriteBuffer_InstanceReference(clientBuffer, clientBufferLength, clientBufferNeeded, namespaceName, serverName, refValue, escapingDepth, result); } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } else { /* VALUE */ if (instanceStart) { WriteBuffer_MiTypeField(clientBuffer, clientBufferLength, clientBufferNeeded, propertyType, instanceStart+propertyOffset, escapingDepth, result); } else { if(propertyValueExists) WriteBuffer_MiValue(clientBuffer, clientBufferLength, clientBufferNeeded, propertyType, (MI_Value*)(&propertyValue), MI_TRUE, SERIALIZE_NO_ESCAPE, result); } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } } } MI_INLINE void WriteBuffer_NoneEscapedChar( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_ const MI_Char charToWrite, _Inout_ MI_Result *result) { MI_Uint32 origBufferNeeded = *clientBufferNeeded; (*clientBufferNeeded)+=sizeof(MI_Char); if ((*result==MI_RESULT_OK) && (*clientBufferNeeded <= clientBufferLength)) { ((MI_Char*)clientBuffer)[origBufferNeeded/sizeof(MI_Char)] = charToWrite; } else if (*result == MI_RESULT_OK) { //If error has not already been set then set it now *result = MI_RESULT_FAILED; } } static void WriteBuffer_Char( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_ const MI_Char charToWrite, MI_Uint32 escapingDepth, //0 means no escaping _Inout_ MI_Result *result) { static const struct { const MI_Char* str; size_t len; } _encode[] = { { PAL_T("�"), 4 }, { PAL_T(""), 4 }, { PAL_T(""), 4 }, { PAL_T(""), 4 }, { PAL_T(""), 4 }, { PAL_T(""), 4 }, { PAL_T(""), 4 }, { PAL_T(""), 4 }, { PAL_T(""), 4 }, { PAL_T(" "), 4 }, { PAL_T(" "), 5 }, { PAL_T(" "), 5 }, { PAL_T(" "), 5 }, { PAL_T(" "), 5}, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { PAL_T(""), 5 }, { NULL, 0 }, { NULL, 0 }, { PAL_T("""), 6 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { PAL_T("&"), 5 }, { PAL_T("'"), 6 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { NULL, 0 }, { PAL_T("<"), 4 }, { NULL, 0 }, { PAL_T(">"), 4 } }; if ((escapingDepth == 0) || (charToWrite > L'>') || (_encode[(unsigned int)charToWrite].str == NULL)) { WriteBuffer_NoneEscapedChar(clientBuffer, clientBufferLength, clientBufferNeeded, charToWrite, result); } else { WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, _encode[(unsigned int)charToWrite].str, _encode[(unsigned int)charToWrite].len, escapingDepth-1, result); } } /* Preferred write mechanism as we don't need to Tcslen the buffer to write */ static void WriteBuffer_StringWithLength( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_reads_z_(bufferToWriteLength) const MI_Char *bufferToWrite, MI_Uint32 bufferToWriteLength, MI_Uint32 escapingDepth, //0 or SERIALIZE_NO_ESCAPE means no escaping _Inout_ MI_Result *result) { if (escapingDepth == 0) { MI_Uint32 origBufferNeeded = *clientBufferNeeded; (*clientBufferNeeded) += (bufferToWriteLength * sizeof(MI_Char)); if ((*result==MI_RESULT_OK) && (*clientBufferNeeded <= clientBufferLength)) { memcpy(clientBuffer + origBufferNeeded, bufferToWrite, bufferToWriteLength * sizeof(MI_Char)); } else if (*result == MI_RESULT_OK) { //If error has not already been set then set it now *result = MI_RESULT_FAILED; } } else { MI_Uint32 loop; for (loop = 0; loop != bufferToWriteLength; loop++) { WriteBuffer_Char(clientBuffer, clientBufferLength, clientBufferNeeded, bufferToWrite[loop], escapingDepth, result); } } } /* writes the textual version of MI_Type */ static void WriteBuffer_MiType( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, MI_Type type, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { static struct _mapping { const MI_Char *typeString; MI_Uint32 typeStringLength; } mapping[] = { {PAL_T("boolean"), WCSLEN(PAL_T("boolean")) }, {PAL_T("uint8"), WCSLEN(PAL_T("uint8")) }, {PAL_T("sint8"), WCSLEN(PAL_T("sint8")) }, {PAL_T("uint16"), WCSLEN(PAL_T("uint16")) }, {PAL_T("sint16"), WCSLEN(PAL_T("sint16")) }, {PAL_T("uint32"), WCSLEN(PAL_T("uint32")) }, {PAL_T("sint32"), WCSLEN(PAL_T("sint32")) }, {PAL_T("uint64"), WCSLEN(PAL_T("uint64")) }, {PAL_T("sint64"), WCSLEN(PAL_T("sint64")) }, {PAL_T("real32"), WCSLEN(PAL_T("real32")) }, {PAL_T("real64"), WCSLEN(PAL_T("real64")) }, {PAL_T("char16"), WCSLEN(PAL_T("char16")) }, {PAL_T("datetime"), WCSLEN(PAL_T("datetime")) }, {PAL_T("string"), WCSLEN(PAL_T("string")) }, {PAL_T("unused"), WCSLEN(PAL_T("unused")) }, /* Reference, not used */ {PAL_T("string"), WCSLEN(PAL_T("string")) } /* Instance is encoded as a string */ }; WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(" TYPE=\""), escapingDepth, result); if ((type&~MI_ARRAY) >= sizeof(mapping)/sizeof(mapping[0])) { WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T("unknown"), WCSLEN(PAL_T("unknown")), SERIALIZE_NO_ESCAPE, result); } else { WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, mapping[type&~MI_ARRAY].typeString, mapping[type&~MI_ARRAY].typeStringLength, SERIALIZE_NO_ESCAPE, result); } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T("\""), escapingDepth, result); } /* writes the textual version of MI_Array based on MI_Type. */ static void WriteBuffer_MiValueArray( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, MI_Type type, _In_ const MI_Array *arrayValue, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { MI_Uint32 index; MI_Type scalarType = (MI_Type)(type&~MI_ARRAY); char* ptr; if (arrayValue == NULL) return; ptr = (char*)arrayValue->data; WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""),escapingDepth, result); for(index = 0; index != arrayValue->size; index++) { WriteBuffer_MiValue(clientBuffer, clientBufferLength, clientBufferNeeded, scalarType, (MI_Value*)ptr, MI_TRUE, escapingDepth, result); ptr += Type_SizeOf(scalarType); } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""),escapingDepth, result); } /* writes the textual version of MI_Value based on MI_Type. */ static void WriteBuffer_MiValue( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, MI_Type type, _In_opt_ const MI_Value *value, MI_Boolean includeTags, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { // MI_Char stringbuffer[_CVTBUFSIZE]; TChar strBufForUnsignedConversion[21]; TChar strBufForSignedConversion[64]; const TChar *convertedBuffer = NULL; TChar strBufForDatetimeConversion[26]; size_t convertedSize = 0; if (value == NULL) return; strBufForSignedConversion[0] = PAL_T('\0'); if (includeTags) WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); switch(type) { case MI_BOOLEAN: { MI_Boolean boolValue = value->boolean; if (boolValue) WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T("true"), SERIALIZE_NO_ESCAPE, result); else WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T("false"), SERIALIZE_NO_ESCAPE, result); break; } case MI_UINT8: Uint64ToZStr(strBufForUnsignedConversion, value->uint8, &convertedBuffer, &convertedSize); WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, convertedBuffer, convertedSize, SERIALIZE_NO_ESCAPE, result); break; case MI_SINT8: Sint64ToZStr(strBufForSignedConversion, value->sint8, &convertedBuffer, &convertedSize); WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, convertedBuffer, convertedSize, SERIALIZE_NO_ESCAPE, result); break; case MI_UINT16: Uint64ToZStr(strBufForUnsignedConversion, value->uint16, &convertedBuffer, &convertedSize); WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, convertedBuffer, convertedSize, SERIALIZE_NO_ESCAPE, result); break; case MI_SINT16: Sint64ToZStr(strBufForSignedConversion, value->sint16, &convertedBuffer, &convertedSize); WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, convertedBuffer, convertedSize, SERIALIZE_NO_ESCAPE, result); break; case MI_UINT32: Uint64ToZStr(strBufForUnsignedConversion, value->uint32, &convertedBuffer, &convertedSize); WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, convertedBuffer, convertedSize, SERIALIZE_NO_ESCAPE, result); break; case MI_SINT32: Sint64ToZStr(strBufForSignedConversion, value->sint32, &convertedBuffer, &convertedSize); WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, convertedBuffer, convertedSize, SERIALIZE_NO_ESCAPE, result); break; case MI_UINT64: Uint64ToZStr(strBufForUnsignedConversion, value->uint64, &convertedBuffer, &convertedSize); WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, convertedBuffer, convertedSize, SERIALIZE_NO_ESCAPE, result); break; case MI_SINT64: Sint64ToZStr(strBufForSignedConversion, value->sint64, &convertedBuffer, &convertedSize); WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, convertedBuffer, convertedSize, SERIALIZE_NO_ESCAPE, result); break; case MI_REAL32: { #if defined(_MSC_VER) unsigned int old_exponent_format = _set_output_format(_TWO_DIGIT_EXPONENT); #endif Stprintf(strBufForSignedConversion, MI_COUNT(strBufForSignedConversion), PAL_T("%.7e"), (double)value->real32); #if defined(_MSC_VER) _set_output_format(old_exponent_format); #endif WriteBuffer_String(clientBuffer, clientBufferLength, clientBufferNeeded, strBufForSignedConversion, SERIALIZE_NO_ESCAPE, result); break; } case MI_REAL64: { #if defined(_MSC_VER) unsigned int old_exponent_format = _set_output_format(_TWO_DIGIT_EXPONENT); #endif Stprintf(strBufForSignedConversion, MI_COUNT(strBufForSignedConversion), PAL_T("%.16e"), (double)value->real64); #if defined(_MSC_VER) _set_output_format(old_exponent_format); #endif WriteBuffer_String(clientBuffer, clientBufferLength, clientBufferNeeded, strBufForSignedConversion, SERIALIZE_NO_ESCAPE, result); break; } case MI_CHAR16: // We decided to encode the MI_Char16 as number itself since if we do not then we have to encode this differently when the MI_Char is char as opposed to when it is wchar_t // OMI instance serialization also uses the same logic so this makes it consistent with that // WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, (const MI_Char *)&value->char16, 1, escapingDepth+1, result); Uint64ToZStr(strBufForUnsignedConversion, value->char16, &convertedBuffer, &convertedSize); WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, convertedBuffer, convertedSize, SERIALIZE_NO_ESCAPE, result); break; case MI_DATETIME: { const MI_Datetime* p = (const MI_Datetime*)value; DatetimeToStr(p, strBufForDatetimeConversion); WriteBuffer_String(clientBuffer, clientBufferLength, clientBufferNeeded, strBufForDatetimeConversion, SERIALIZE_NO_ESCAPE, result); break; } case MI_STRING: WriteBuffer_String(clientBuffer, clientBufferLength, clientBufferNeeded, value->string, escapingDepth+1, result); break; //case MI_REFERENCE: /* Other code paths handle this */ // break; case MI_INSTANCE: WriteBuffer_Instance(clientBuffer, clientBufferLength, clientBufferNeeded, (MI_Instance*)value->instance, escapingDepth+1, result); break; default: *result = MI_RESULT_FAILED; } if (includeTags) WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } static struct _FlagQualifiers { MI_Uint32 flag; const MI_Char *name; } sFlagQualifiers[] = { { MI_FLAG_KEY, PAL_T("key") }, { MI_FLAG_REQUIRED, PAL_T("required") }, { MI_FLAG_STATIC, PAL_T("static") }, { MI_FLAG_EXPENSIVE, PAL_T("expensive") }, { MI_FLAG_READONLY, PAL_T("read") }, { MI_FLAG_IN, PAL_T("in") }, { MI_FLAG_OUT, PAL_T("out") }, { MI_FLAG_ABSTRACT, PAL_T("abstract") }, { MI_FLAG_TERMINAL, PAL_T("terminal") }, { MI_FLAG_ASSOCIATION, PAL_T("association") }, { MI_FLAG_INDICATION, PAL_T("indication") }, // { MI_FLAG_STREAM, PAL_T("stream") }, }; static MI_Uint32 sFlagQualifierCount = sizeof(sFlagQualifiers)/sizeof(sFlagQualifiers[0]); /* writes the textual version of MI_Qualifier flags. */ static void WriteBuffer_MiFlagQualifiers( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, MI_Uint32 flagsToSerializeAsQualifiers, _Inout_ MI_Result *result) { MI_Value value; MI_Uint32 index; value.boolean = MI_TRUE; for (index = 0; index != sFlagQualifierCount; index++) { if (flagsToSerializeAsQualifiers & sFlagQualifiers[index].flag) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), SERIALIZE_NO_ESCAPE, result); /* VALUE */ WriteBuffer_MiValue(clientBuffer, clientBufferLength, clientBufferNeeded, MI_BOOLEAN, &value, MI_TRUE, SERIALIZE_NO_ESCAPE, result); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), SERIALIZE_NO_ESCAPE, result); } } } // this function looks up the qualifiername in the sQualifierFlags list and // resets the corresponding flag from the given flags bitmask. // this could use a hash table lookup but not adding complexity // since it is a very small table so the lookup will be constant time static void ResetFlagForQualifier(_Inout_ MI_Uint32 *flags, const MI_Char *qualifierName) { MI_Uint32 index; // assumption is that flags has to be non-null if(flags == NULL) { return; } for (index = 0; index != sFlagQualifierCount; index++) { if(Tcscasecmp(qualifierName, sFlagQualifiers[index].name) == 0) { *flags = *flags & (~(sFlagQualifiers[index].flag)); break; } } } static void WriteBuffer_EmbeddedPropertyQualifier( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_opt_ const MI_Char *referenceClassForEmbeddedProperty, _Inout_ MI_Result *result) { MI_Type type; MI_Value value; const MI_Char *qualifierName = NULL; if(referenceClassForEmbeddedProperty == NULL) { type = MI_BOOLEAN; value.boolean = MI_TRUE; qualifierName = PAL_T("EmbeddedObject"); } else { type = MI_STRING; value.string = (MI_Char *)referenceClassForEmbeddedProperty; qualifierName = PAL_T("EmbeddedInstance"); } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), SERIALIZE_NO_ESCAPE, result); /* VALUE -- embedded instance class name or true for embedded object */ WriteBuffer_MiValue(clientBuffer, clientBufferLength, clientBufferNeeded, type, &value, MI_TRUE, SERIALIZE_NO_ESCAPE, result); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), SERIALIZE_NO_ESCAPE, result); } static void WriteBuffer_MiQualifierSet( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_ const MI_QualifierSet *qualifierSet, MI_Uint32 flagsToSerializeAsQualifiers, MI_Boolean isQualOnInheritedElement, _Inout_ MI_Result *result) { WriteBuffer_MiParamPropertyQualifierSet(clientBuffer, clientBufferLength, clientBufferNeeded, qualifierSet, flagsToSerializeAsQualifiers, isQualOnInheritedElement, MI_FALSE, NULL, result); } static void WriteBuffer_MiParamPropertyQualifierSet( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_ const MI_QualifierSet *qualifierSet, MI_Uint32 flagsToSerializeAsQualifiers, MI_Boolean isQualOnInheritedElement, MI_Boolean isEmbeddedProperty, _In_opt_ const MI_Char *referenceClassForEmbeddedProperty, _Inout_ MI_Result *result) { MI_Uint32 index; MI_Uint32 qualifierCount = 0; const MI_Char *qualifierName = NULL; MI_Type qualifierType; MI_Uint32 qualifierFlags; MI_Value qualifierValue; MI_Boolean embeddedPropertyQualifierSpecified = 0; if(qualifierSet) { GetQualifierSetFt(qualifierSet)->GetQualifierCount(qualifierSet, &qualifierCount); } for (index = 0; index != qualifierCount; index++) { GetQualifierSetFt(qualifierSet)->GetQualifierAt(qualifierSet, index, &qualifierName, &qualifierType, &qualifierFlags, &qualifierValue); // Restricted qualifier should not be sent on inherited elements if (isQualOnInheritedElement && (qualifierFlags & MI_FLAG_RESTRICTED)) continue; WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), SERIALIZE_NO_ESCAPE, result); /* VALUE | VALUE.ARRAY */ if (qualifierType & MI_ARRAY) { WriteBuffer_MiValueArray(clientBuffer, clientBufferLength, clientBufferNeeded, (MI_Type)qualifierType, (MI_Array*)(&qualifierValue), SERIALIZE_NO_ESCAPE, result); } else { WriteBuffer_MiValue(clientBuffer, clientBufferLength, clientBufferNeeded, (MI_Type)qualifierType, &qualifierValue, MI_TRUE, SERIALIZE_NO_ESCAPE, result); } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), SERIALIZE_NO_ESCAPE, result); } // code to fabricate embedded qualifier if(isEmbeddedProperty && !embeddedPropertyQualifierSpecified) { WriteBuffer_EmbeddedPropertyQualifier(clientBuffer, clientBufferLength, clientBufferNeeded, referenceClassForEmbeddedProperty, result); } WriteBuffer_MiFlagQualifiers(clientBuffer, clientBufferLength, clientBufferNeeded, flagsToSerializeAsQualifiers, result); } /* writes the textual version of %CIMName. (name="name") */ static void WriteBuffer_CimName( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_z_ const MI_Char* name, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(" NAME=\""), escapingDepth, result); WriteBuffer_String(clientBuffer, clientBufferLength, clientBufferNeeded, name, escapingDepth, result); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T("\""), escapingDepth, result); } static void WriteBuffer_Uint32( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, MI_Uint32 number, _Inout_ MI_Result *result) { // MI_Char stringbuffer[_CVTBUFSIZE]; TChar strBufForUnsignedConversion[21]; size_t convertedSize = 0; const TChar *convertedBuffer = NULL; Uint64ToZStr(strBufForUnsignedConversion, number, &convertedBuffer, &convertedSize); WriteBuffer_StringWithLength(clientBuffer, clientBufferLength, clientBufferNeeded, convertedBuffer, convertedSize, SERIALIZE_NO_ESCAPE, result); } MI_INLINE MI_Boolean _Exists(MI_Type type, const void* field) { return *((MI_Boolean*)((char*)field + Type_SizeOf(type))); } static void WriteBuffer_MiTypeField( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, MI_Type type, _In_ const char *fieldValue, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { if (_Exists(type, fieldValue)) { #ifdef _MSC_VER #pragma prefast(push) #pragma prefast (disable: 26007) #endif WriteBuffer_MiValue(clientBuffer, clientBufferLength, clientBufferNeeded, type, (MI_Value*)fieldValue, MI_TRUE, escapingDepth, result); #ifdef _MSC_VER #pragma prefast(pop) #endif } } static void WriteBuffer_MiArrayField( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, MI_Type type, _In_ MI_ArrayField *arrayField, MI_Uint32 escapingDepth, _Inout_ MI_Result *result ) { MI_Uint32 index; MI_Type scalarType = (MI_Type)(type&~MI_ARRAY); char* ptr = (char*)arrayField->value.data; if (_Exists(type, arrayField)) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); if (ptr) { for(index = 0; index != arrayField->value.size; index++) { WriteBuffer_MiValue(clientBuffer, clientBufferLength, clientBufferNeeded, scalarType, (MI_Value*)ptr, MI_TRUE, escapingDepth, result); ptr += Type_SizeOf(scalarType); } } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } } static void WriteBuffer_LOCALNAMESPACEPATH_Internal( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_z_ const MI_Char *namespaceName, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } static void WriteBuffer_LOCALNAMESPACEPATH( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_z_ const MI_Char *namespaceName, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); { MI_Uint32 uNamespaceLength = Tcslen(namespaceName) + 1; // add fault sim shim for all malloc calls in omi MI_Char * tNamespace = (MI_Char *)PAL_Malloc(sizeof(MI_Char)*uNamespaceLength); MI_Char * pCurrentNamespace; const MI_Char * pSearch; if (tNamespace == NULL) { *result = MI_RESULT_SERVER_LIMITS_EXCEEDED; return; } pCurrentNamespace = tNamespace; pSearch = namespaceName; // suppose namespaceName could be "a\\b/c\\d//e" while(*pSearch != L'\0') { if (*pSearch == L'/' || *pSearch == L'\\') { if (pCurrentNamespace != tNamespace) { #ifdef _MSC_VER #pragma prefast(push) #pragma prefast (disable: 26001) #endif // write terminator *pCurrentNamespace = L'\0'; #ifdef _MSC_VER #pragma prefast(pop) #endif // the namespace part is not empty, write this part to local NAMESPACE WriteBuffer_LOCALNAMESPACEPATH_Internal(clientBuffer, clientBufferLength, clientBufferNeeded, tNamespace, escapingDepth, result); // reset pCurrentNamespace pCurrentNamespace = tNamespace; } } else { *pCurrentNamespace = *pSearch; pCurrentNamespace++; } pSearch ++; } if (pCurrentNamespace != tNamespace) { // write terminator *pCurrentNamespace = L'\0'; // the namespace part is not empty, write this part to local NAMESPACE WriteBuffer_LOCALNAMESPACEPATH_Internal(clientBuffer, clientBufferLength, clientBufferNeeded, tNamespace, escapingDepth, result); } PAL_Free(tNamespace); } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } static void WriteBuffer_NAMESPACEPATH( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_z_ const MI_Char *namespaceName, _In_z_ const MI_Char *serverName, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); WriteBuffer_String(clientBuffer, clientBufferLength, clientBufferNeeded, serverName, escapingDepth, result); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); WriteBuffer_LOCALNAMESPACEPATH(clientBuffer, clientBufferLength, clientBufferNeeded, namespaceName, escapingDepth, result); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } static void WriteBuffer_INSTANCENAME_single( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_ const MI_Instance *refValue, MI_Type type, _In_ MI_Value *value, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { if (type == MI_REFERENCE) { const MI_Char *namespaceName = NULL; const MI_Char *serverName = NULL; if ((value->instance->nameSpace && (refValue->nameSpace == NULL)) || (refValue->nameSpace && value->instance->nameSpace && (Tcscasecmp(refValue->nameSpace, value->instance->nameSpace) != 0))) { namespaceName = value->instance->nameSpace; } if ((value->instance->serverName && (refValue->serverName == NULL)) || (refValue->serverName && value->instance->serverName && (Tcscasecmp(refValue->serverName, value->instance->serverName) != 0))) { serverName = value->instance->serverName; } WriteBuffer_InstanceReference(clientBuffer, clientBufferLength, clientBufferNeeded, namespaceName, serverName, value->reference, escapingDepth, result); } else { switch(type) { case MI_BOOLEAN: WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); WriteBuffer_MiValue(clientBuffer, clientBufferLength, clientBufferNeeded, type, value, MI_FALSE, escapingDepth, result); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } } static void WriteBuffer_INSTANCENAME( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_ const MI_Instance *refValue, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { /* Need to count keys to determine if we need to use KEYBINDING [more than 1 key] or (KEYVALUE|VALUE.REFERENCE) [only 1 key] */ MI_Uint32 keyCount = 0; MI_Uint32 propertyIndex; MI_Uint32 totalPropertyCount = 0; MI_Class classOfRefValue = MI_CLASS_NULL; const MI_Char *classNameOfRefValue = NULL; MI_Uint32 propertyFlags; *result = MI_Instance_GetClassExt(refValue, &classOfRefValue); *result = GetClassExtendedFt(&classOfRefValue)->GetClassName(&classOfRefValue, &classNameOfRefValue); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); GetClassExtendedFt(&classOfRefValue)->GetElementCount(&classOfRefValue, &totalPropertyCount); for (propertyIndex = 0;propertyIndex != totalPropertyCount; propertyIndex++) { GetClassExtendedFt(&classOfRefValue)->GetElementAtExt(&classOfRefValue, propertyIndex, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &propertyFlags); if (propertyFlags & MI_FLAG_KEY) { keyCount++; } } for (propertyIndex = 0;propertyIndex != totalPropertyCount; propertyIndex++) { GetClassExtendedFt(&classOfRefValue)->GetElementAtExt(&classOfRefValue, propertyIndex, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &propertyFlags); if (propertyFlags & MI_FLAG_KEY) { const MI_Char *name; MI_Value value; MI_Type type; MI_Uint32 flags; MI_Result tmpResult = MI_Instance_GetElementAt(refValue, propertyIndex, &name, &value, &type, &flags); if (tmpResult != MI_RESULT_OK) { *result = tmpResult; return; } if (keyCount == 1) { WriteBuffer_INSTANCENAME_single(clientBuffer, clientBufferLength, clientBufferNeeded, refValue, type, &value, escapingDepth, result); } else { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); WriteBuffer_INSTANCENAME_single(clientBuffer, clientBufferLength, clientBufferNeeded, refValue, type, &value, escapingDepth, result); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } } } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } static void WriteBuffer_LOCALINSTANCEPATH( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_z_ const MI_Char *namespaceName, _In_ const MI_Instance *refValue, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); WriteBuffer_LOCALNAMESPACEPATH(clientBuffer, clientBufferLength, clientBufferNeeded, namespaceName, escapingDepth, result); WriteBuffer_INSTANCENAME(clientBuffer, clientBufferLength, clientBufferNeeded, refValue, escapingDepth, result); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } static void WriteBuffer_INSTANCEPATH( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_z_ const MI_Char *namespaceName, _In_z_ const MI_Char *serverName, _In_ const MI_Instance *refValue, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); WriteBuffer_NAMESPACEPATH(clientBuffer, clientBufferLength, clientBufferNeeded, namespaceName, serverName, escapingDepth, result); WriteBuffer_INSTANCENAME(clientBuffer, clientBufferLength, clientBufferNeeded, refValue, escapingDepth, result); WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } static void WriteBuffer_InstanceReference( _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded, _In_opt_z_ const MI_Char *_namespaceName, _In_opt_z_ const MI_Char *_serverName, _In_ const MI_Instance *refInstance_, MI_Uint32 escapingDepth, _Inout_ MI_Result *result) { const MI_Char *namespaceName = NULL; const MI_Char *serverName = NULL; // No one is using OSC_Instance structure inside OMI; // so I am assuming all instances here are going to be MI_Instances // so getting rid of this OSC_Instance from the reused code and replacing it with MI_Instance // in the future if someone adds OSC_Instance in OMI then add this back // MI_Instance *refInstance = (MI_Instance*)(((OSC_Instance*)refInstance_)->self); //In case this is dynamic instance point to the real one, otherwise it points to ourself! const MI_Instance *refInstance = refInstance_; if ((_namespaceName && refInstance->nameSpace && (Tcscasecmp(_namespaceName, refInstance->nameSpace)!=0)) || (!_namespaceName && refInstance->nameSpace)) { namespaceName = refInstance->nameSpace; } if ((_serverName && refInstance->serverName && (Tcscasecmp(_serverName, refInstance->serverName)!=0)) || (!_serverName && refInstance->serverName)) { serverName = refInstance->serverName; } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); if (serverName && namespaceName) { WriteBuffer_INSTANCEPATH(clientBuffer, clientBufferLength, clientBufferNeeded, namespaceName, serverName, refInstance, escapingDepth, result); } else if (namespaceName) { WriteBuffer_LOCALINSTANCEPATH(clientBuffer, clientBufferLength, clientBufferNeeded, namespaceName, refInstance, escapingDepth, result); } else { WriteBuffer_INSTANCENAME(clientBuffer, clientBufferLength, clientBufferNeeded, refInstance, escapingDepth, result); } WriteBuffer_StringLiteral(clientBuffer, clientBufferLength, clientBufferNeeded, PAL_T(""), escapingDepth, result); } /* Serialize class api; assumes the MI_Class is setup with right function table using Class_Construct*/ MI_Result MI_CALL XmlSerializer_SerializeClass( _Inout_ MI_Serializer *serializer, MI_Uint32 flags, _In_ const MI_Class *classObject, _Out_writes_bytes_(clientBufferLength) MI_Uint8 *clientBuffer, MI_Uint32 clientBufferLength, _Inout_ MI_Uint32 *clientBufferNeeded) { MI_Result result = MI_RESULT_OK; MI_Uint32 validFlags = MI_SERIALIZER_FLAGS_CLASS_DEEP | MI_SERIALIZER_FLAGS_INCLUDE_CLASS_ORIGIN | MI_SERIALIZER_FLAGS_INCLUDE_INHERITANCE_HIERARCHY | MI_SERIALIZER_FLAGS_INCLUDE_INHERITED_ELEMENTS | MI_SERIALIZER_FLAGS_INCLUDE_QUALIFIERS; if (((flags != 0) && (flags & ~validFlags)) || (classObject == NULL) || (clientBufferNeeded == NULL)) { return MI_RESULT_INVALID_PARAMETER; } *clientBufferNeeded = 0; WriteBuffer_SerializeClass(clientBuffer, clientBufferLength, clientBufferNeeded, flags, classObject, classObject->namespaceName, classObject->serverName, &result); return result; }