/**
       Returns the architecture of the platform, e.g. PA-Risc, x86 or SPARC
    
       \returns   String with the architecture of the platform
    
    */
    std::wstring SCXOSTypeInfo::GetArchitectureString() const
    {
#if defined(hpux)
#if defined(hppa)
        return L"PA-Risc";
#else
        return L"IA64";
#endif // defined(hpux)

#elif defined(linux)

        unsigned short bitSize = 0;
        try
        {
            SystemInfo sysInfo;
            sysInfo.GetNativeBitSize(bitSize);
        }
        catch (SCXCoreLib::SCXException &e)
        {
            SCX_LOGERROR(m_log, StrAppend( StrAppend(L"Failure in SystemInstance::GetNativeBitSize: ", e.What()), e.Where()));
        }

        if (32 == bitSize)
        {
            return L"x86";
        }
        else if (64 == bitSize) 
        {
            return L"x64";
        }
        else 
        {
            assert(!"Unknown architecture");
            return L"Unknown";
        }

#elif defined(sun)
            
#if defined(sparc)
        return L"SPARC";
#else
        return L"x86";
#endif
        
#elif defined(aix)
        return L"powerpc";     // This is what uname -p says
        
#elif defined(macos)

        // On MacOS Intel platforms, the architecture appears to always be i386,
        // regardless of 32-bit vs. 64-bit capabilities.  However, since we may
        // (some day) run on something else, we'll implement this properly.
        //
        // Intel (i386) on Mac is a special case: we return 'x86' or 'x64' based
        // on 64-bit capabilities of the CPU.

        // First get the machine architecture dynamically

        int mib[2];
        char hwMachine[64];
        size_t len_hwMachine = sizeof(hwMachine);

        mib[0] = CTL_HW;
        mib[1] = HW_MACHINE;

        if (0 != sysctl(mib, 2, hwMachine, &len_hwMachine, NULL, 0))
        {
            wostringstream sout;
            sout << L"Failure calling sysctl(): Errno=" << errno;
            SCX_LOGERROR(m_log, sout.str());

            return L"";
        }

        // Now figure out our bit size (if Intel, handle the special case)

        if (0 == strncmp("i386", hwMachine, sizeof(hwMachine)))
        {
            unsigned short bitSize = 0;
            try
            {
                SystemInfo sysInfo;
                sysInfo.GetNativeBitSize(bitSize);
            }
            catch (SCXCoreLib::SCXException &e)
            {
                SCX_LOGERROR(m_log, StrAppend( StrAppend(L"Failure in SystemInstance::GetNativeBitSize: ", e.What()), e.Where()));
            }

            if (32 == bitSize)
            {
                return L"x86";
            }
            else if (64 == bitSize) 
            {
                return L"x64";
            }
        }

        // Return the actual architecture, whatever it is

        return StrFromMultibyte(hwMachine);

#else
#error "Platform not supported"
#endif
    }
static void EnumerateOneInstance(
    Context& context,
    SCX_OperatingSystem_Class& inst,
    bool keysOnly,
    SCXHandle<OSInstance> osinst,
    SCXHandle<MemoryInstance> meminst)
{
    // Get some handles
    SCXHandle<SCXOSTypeInfo> osTypeInfo = SCXCore::g_OSProvider.GetOSTypeInfo();
    SCXLogHandle& log = SCXCore::g_OSProvider.GetLogHandle();

    SCX_LOGTRACE(log, L"OSProvider EnumerateOneInstance()");

    // Fill in the keys
    inst.Name_value( StrToMultibyte(osTypeInfo->GetOSName(true)).c_str() );
    inst.CSCreationClassName_value( "SCX_ComputerSystem" );

    try {
        NameResolver mi;
        inst.CSName_value( StrToMultibyte(mi.GetHostDomainname()).c_str() );
    } catch (SCXException& e) {
        SCX_LOGWARNING(log, StrAppend(
                              StrAppend(L"Can't read host/domainname because ", e.What()),
                              e.Where()));
    }

    inst.CreationClassName_value( "SCX_OperatingSystem" );

    if ( !keysOnly )
    {
        SCXCalendarTime ASCXCalendarTime;
        scxulong Ascxulong, Ascxulong1;
        unsigned short Aunsignedshort;
        vector<string> Avector;
        vector<unsigned short> Aushortvector;
        wstring Awstring;
        signed short Ashort;
        unsigned int Auint;

        /*===================================================================================*/
        /* Defaulted Values (from MOF)                                                       */
        /*===================================================================================*/

        inst.EnabledDefault_value( 2 );
        inst.EnabledState_value( 5 );
        inst.RequestedState_value( 12 );

        /*===================================================================================*/
        /* Properties of CIM_ManagedElement                                                  */
        /*===================================================================================*/

        inst.Caption_value( StrToMultibyte(osTypeInfo->GetCaption()).c_str() );
        inst.Description_value( StrToMultibyte(osTypeInfo->GetDescription()).c_str() );

        /*===================================================================================*/
        /* Properties of CIM_ManagedSystemElement                                            */
        /*===================================================================================*/

        // We don't support the following because there's no way to retrieve on any platforms:
        //      InstallDate
        //      Status
        //      OperationalStatus
        //      StatusDescriptions
        //      HealthState

        /*===================================================================================*/
        /* Properties of CIM_OperatingSystem                                                 */
        /*===================================================================================*/

        // We don't support the following because there's no way to retrieve on any platforms:
        //      EnabledState
        //      OtherEnabledState
        //      RequestedState
        //      EnabledDefault
        //      TimeOfLastStateChange
        //      OverwritePolicy
        //      Distributed

        /* CSCreationClassName is a key property and thus set in AddKeys */
        /* CSName is a key property and thus set in AddKeys */
        /* CreationClassName is a key property and thus set in AddKeys */

        if (osinst->GetOSType(Aunsignedshort))
            inst.OSType_value( Aunsignedshort );

        if (osinst->GetOtherTypeDescription(Awstring))
            inst.OtherTypeDescription_value( StrToMultibyte(Awstring).c_str() );

        if (osinst->GetVersion(Awstring))
            inst.Version_value( StrToMultibyte(Awstring).c_str() );

        if (osinst->GetLastBootUpTime(ASCXCalendarTime))
        {
            MI_Datetime bootTime;
            CIMUtils::ConvertToCIMDatetime( bootTime, ASCXCalendarTime );
            inst.LastBootUpTime_value( bootTime );
        }

        if (osinst->GetLocalDateTime(ASCXCalendarTime))
        {
            MI_Datetime localTime;
            CIMUtils::ConvertToCIMDatetime( localTime, ASCXCalendarTime );
            inst.LocalDateTime_value( localTime );
        }

        if (osinst->GetCurrentTimeZone(Ashort))
            inst.CurrentTimeZone_value( Ashort );

        if (osinst->GetNumberOfLicensedUsers(Auint))
            inst.NumberOfLicensedUsers_value( Auint );

        if (osinst->GetNumberOfUsers(Auint))
            inst.NumberOfUsers_value( Auint );

        if (ProcessEnumeration::GetNumberOfProcesses(Auint))
            inst.NumberOfProcesses_value( Auint );

        if (osinst->GetMaxNumberOfProcesses(Auint))
            inst.MaxNumberOfProcesses_value( Auint );

        if (meminst->GetTotalSwap(Ascxulong))
        {
            inst.TotalSwapSpaceSize_value( BytesToKiloBytes(Ascxulong) );
        }

        if (meminst->GetTotalPhysicalMemory(Ascxulong) && meminst->GetTotalSwap(Ascxulong1))
        {
            inst.TotalVirtualMemorySize_value( BytesToKiloBytes(Ascxulong) + BytesToKiloBytes(Ascxulong1) );
        }

        if (meminst->GetAvailableMemory(Ascxulong))
        {
            Ascxulong = BytesToKiloBytes(Ascxulong);

            if (meminst->GetAvailableSwap(Ascxulong1)) {
                inst.FreeVirtualMemory_value( Ascxulong + BytesToKiloBytes(Ascxulong1) );
            }

            inst.FreePhysicalMemory_value( Ascxulong );
        }

        if (meminst->GetTotalPhysicalMemory(Ascxulong))
            inst.TotalVisibleMemorySize_value( BytesToKiloBytes(Ascxulong) );

        if (meminst->GetTotalSwap(Ascxulong))
            inst.SizeStoredInPagingFiles_value( BytesToKiloBytes(Ascxulong) );

        if (meminst->GetAvailableSwap(Ascxulong))
            inst.FreeSpaceInPagingFiles_value( BytesToKiloBytes(Ascxulong) );

        if (osinst->GetMaxProcessMemorySize(Ascxulong))
            inst.MaxProcessMemorySize_value( Ascxulong );

        if (osinst->GetMaxProcessesPerUser(Auint))
            inst.MaxProcessesPerUser_value( Auint );

        /*===================================================================================*/
        /* Properties of SCX_OperatingSystem (Taken from PG_OperatingSystem)                 */
        /*===================================================================================*/

        SystemInfo sysInfo;
        if (sysInfo.GetNativeBitSize(Aunsignedshort))
        {
            std::ostringstream bitText;
            bitText << Aunsignedshort << " bit";

            inst.OperatingSystemCapability_value( bitText.str().c_str() );
        }

        if (osinst->GetSystemUpTime(Ascxulong))
            inst.SystemUpTime_value( Ascxulong );
    }

    context.Post(inst);
}