⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 locplgmgr.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//

// Abstract: Location framework plugin manager

#include <locCore.hpp>

// Global plugin  manager
pluginMgr_t * g_pPluginMgr;

//*****************************************************************************
//  Init and deinit routines for the location framework
//*****************************************************************************

// Main initialization for the plugin manager.
pluginMgr_t::pluginMgr_t() {
    DEBUGCHK(g_pLocLock->IsLocked());
    DEBUGCHK(g_serviceState == SERVICE_STATE_STARTING_UP);

    m_initSuccess = FALSE;

    CReg reg(HKEY_LOCAL_MACHINE,g_rkLocBase);
    if (!reg.IsOK()) {
        DEBUGMSG(ZONE_ERROR,(L"LOC: ERROR: Unable to start because base reg key <%s> is not present\r\n",g_rkLocBase));
        return;
    }

    if (! InitProviders(&reg) ||
        ! InitResolvers(&reg) ||
        ! AssignPluginOrder() ||
        ! InitReportCollectors())
    {
        return;
    }

    m_initSuccess = TRUE;
}

// All pointers are smart pointers and auto-freed, so no work in destructor
pluginMgr_t::~pluginMgr_t() {
    DEBUGCHK(g_pLocLock->IsLocked());
    DEBUGCHK((g_serviceState != SERVICE_STATE_ON) && (g_serviceState != SERVICE_STATE_STARTING_UP));
}

BOOL pluginMgr_t::IsPlgMgrInited(void) {
    return m_initSuccess;
}

// Inserts plugin into the list based on its order.  Simple insert algorithm
// since # of plugins will be small.
BOOL pluginMgr_t::InsertPluginOrdered(pluginSmartPtr_t pPlugin) {
    pluginListIter_t it     = m_pluginList.begin();
    pluginListIter_t itEnd  = m_pluginList.end();

    DWORD newPref = pPlugin->GetPreference();

    for (; it != itEnd; ++it) {
        if ((*it)->GetPreference() > newPref) {
            if (! m_pluginList.insert(it,pPlugin)) {
                DEBUGMSG_OOM();
                return FALSE;
            }
            return TRUE;
        }
    }

    if (! m_pluginList.push_back(pPlugin)) {
        DEBUGMSG_OOM();
        return FALSE;
    }
    return TRUE;
}

// Now that plugins have been loaded in a sorted list, indicate to 
// each one what its load order was.  This order will be used later
// when determining when to stop & start plugins after failures.
BOOL pluginMgr_t::AssignPluginOrder(void) {
    pluginListIter_t it    = m_pluginList.begin();
    pluginListIter_t itEnd = m_pluginList.end();

    DWORD index = 0;

    for (; it != itEnd; ++it) {
        (*it)->SetStartOrder(index);
        index++;
    }

    return TRUE;
}

// Read all provider DLL config options, load the DLLs, and get required exports.
BOOL pluginMgr_t::InitProviders(CReg *pBaseReg) {
    CReg providersReg(*pBaseReg,g_rkProviders);
    WCHAR providerName[MAX_PATH];

    DEBUGMSG(ZONE_INIT,(L"LOC: Begin initializing providers...\r\n"));

    // Each provider is represented by a reg subkey under ...\Providers
    while (providersReg.EnumKey(providerName,SVSUTIL_ARRLEN(providerName))) {
        CReg providerReg(providersReg, providerName);

        pluginSmartPtr_t pProv = new provider_t(&providerReg,providerName);
        if (! pProv.valid()) {
            DEBUGMSG_OOM();
            return FALSE;
        }

        if (pProv->GetState() == PLUGIN_STATE_ERROR) {
            // This usually indicates plugin misconfiguration (not a fatal OOM)
            // Don't put plugin into m_pluginList (so it will be deleted
            // automatically) and move on to initialize next plugin.
            continue;
        }

        if (! InsertPluginOrdered(pProv))
            return FALSE;
    }

    DEBUGMSG(ZONE_INIT,(L"LOC: Completed initializing providers...\r\n"));
    return TRUE;
}

// Read all resolver DLL config options, load the DLLs, and get required exports.
BOOL pluginMgr_t::InitResolvers(CReg *pBaseReg) {
    CReg resolversReg(*pBaseReg,g_rkResolvers);
    WCHAR resolverName[MAX_PATH];

    DEBUGMSG(ZONE_INIT,(L"LOC: Begin initializing resolvers...\r\n"));

    // Each resolver is represented by a reg subkey under ...\resolver
    while (resolversReg.EnumKey(resolverName,SVSUTIL_ARRLEN(resolverName))) {
        CReg resolverReg(resolversReg, resolverName);

        pluginSmartPtr_t pRes = new resolver_t(&resolverReg,resolverName);
        if (! pRes.valid()) {
            DEBUGMSG_OOM();
            return FALSE;
        }

        if (pRes->GetState() == PLUGIN_STATE_ERROR) {
            // This usually indicates plugin misconfiguration (not a fatal OOM)
            // Don't put plugin into m_pluginList (so it will be deleted
            // automatically) and move on to initialize next plugin.
            continue;
        }

        if (! InsertPluginOrdered(pRes))
            return FALSE;
    }

    DEBUGMSG(ZONE_INIT,(L"LOC: Completed initializing resolver...\r\n"));
    return TRUE;
}


// Determines what report types each plugin on the system can generate
// and create a report collector for each unique type.
BOOL pluginMgr_t::InitReportCollectors(void) {
    DEBUGMSG(ZONE_REPCOL,(L"LOC: Beginning to initialize reports collectors...\r\n"));

    DEBUGCHK(g_pLocLock->IsLocked());

    pluginListIter_t it    = m_pluginList.begin();
    pluginListIter_t itEnd = m_pluginList.end();

    //
    // Iterate through each plugin on the system.  
    // For each plugin, create an RC for each report type it 
    // generates (assuming one hasn't been created already)
    //
    for (; it != itEnd; ++it) {
        GUID generatedReports[MAX_PLUGIN_REPORT_TYPES];
        DWORD numRepTypes;
        (*it)->GetGeneratedReportInfo(generatedReports,&numRepTypes);

        // Iterate through each report type plugin generates
        for (DWORD i = 0; i < numRepTypes; i++) {
            if (FindRC(&generatedReports[i])) {
                // A report collector for this type has already been 
                // created because another plugin also generates it.
                continue; 
            }

            reportColSmartPtr_t pNewReport = new reportCol_t(&generatedReports[i]);
            if (! pNewReport.valid()) {
                DEBUGMSG_OOM();
                return FALSE;
            }

            if (! m_reportColList.push_back(pNewReport)) {
                DEBUGMSG_OOM();
                // Auto-deleted because it's a smart pointer going out of scope.
                return FALSE;
            }

            DEBUGMSG(ZONE_REPCOL,(L"LOC: Created report collector for report type <" SVSUTIL_GUID_FORMAT_W L">\r\n",
                     SVSUTIL_RGUID_ELEMENTS(generatedReports[i])));
        }
    }


    //
    // For each resolver on the system, for each report type that it supports
    // add it to the appropriate RC's resolver list.
    //

    for (it = m_pluginList.begin(); it != itEnd; ++it) {
        if ((*it)->IsAProvider()) {
            // We only care about resolvers.
            continue;
        }

        resolver_t *pRes = (resolver_t*)((plugin_t*)(*it));
        GUID  supportedReports[MAX_PLUGIN_REPORT_TYPES];
        DWORD numSupportedReports;
        pRes->GetSupportedReportInfo(supportedReports,&numSupportedReports);

        // For each supported report each resolver accepts, find RC (if exists)
        // and associate with it.
        for (DWORD i = 0; i < numSupportedReports; i++) {
            reportCol_t *pRC = FindRC(&supportedReports[i]);
            if (NULL == pRC) {
                // Just because a resolver supports a report doesn't mean anything 
                // on the system generates it (and hence no reports collector)
                continue; 
            }

            if (ERROR_SUCCESS != pRC->AddToResolversList(pRes))
                return FALSE;
        }
    }

    DEBUGMSG(ZONE_REPCOL,(L"LOC: Done initializing reports collectors...\r\n"));
    return TRUE;
}


//*****************************************************************************
//  Misc plugin manager helper functions
//*****************************************************************************

// Finds reports collector associated with a given GUID
reportCol_t * pluginMgr_t::FindRC(const GUID *pGUID) {
    reportColListIter_t it    = m_reportColList.begin();
    reportColListIter_t itEnd = m_reportColList.end();

    for (; it != itEnd; ++it) {
        if (0 == memcmp(pGUID,(*it)->GetReportType(),sizeof(GUID)))
            return (*it);
    }

    return NULL;
}

// Helper to find a plugin based on context passed in from a callback
plugin_t *pluginMgr_t::FindPlugin(HANDLE pluginContext) {
    pluginListIter_t it    = m_pluginList.begin();
    pluginListIter_t itEnd = m_pluginList.end();

    for (; it != itEnd; ++it) {
        if ((*it) == (plugin_t*)pluginContext)
            return (*it);
    }

    DEBUGMSG(ZONE_ERROR,(L"LOC: ERROR: Callback Context <0x%08x> is invalid\r\n",pluginContext));
    return NULL;
}


// Returns the plugin that has the specified plugin guid
plugin_t *pluginMgr_t::FindPlugin(const GUID *pPluginGuid) {
    pluginListIter_t it    = m_pluginList.begin();
    pluginListIter_t itEnd = m_pluginList.end();

    for (; it != itEnd; ++it) {
        if ((*it)->IsGuid(pPluginGuid))
            return (*it);
    }

    return NULL;
}

// This function is called when a plugin has had some fatal error,
// such as throwing an exception.  This will call into the plugin itself
// telling it to change its state to PLUGIN_STATE_ERROR and will
// try to load the next plugins for reports this plugin can't generate anymore.

// Once a plugin enters PLUGIN_STATE_ERROR, nothing short of refreshing the LFSVC
// will ever get it out of that state.
void pluginMgr_t::FatalPluginError(plugin_t *pPlugin) {
    DEBUGCHK(g_pLocLock->IsLocked());

    if (pPlugin->GetState() == PLUGIN_STATE_ERROR) {
        // It is possible for this to be called multiple times (i.e. for
        // a plugin that throws multiple exceptions).  Only take action
        // first time plugin gets into this state.
        return;
    }

    DEBUGMSG(ZONE_ERROR,(L"LOC: Plugin <%s> has entered PLUGIN_ERROR_STATE.  Trying to start next available plugins\r\n",
                           pPlugin->GetName()));

    pPlugin->SetFatalError();

    if (g_serviceState == SERVICE_STATE_ON) {
        // If service is on still, then start up next plugins in line.
        StartNextPluginsOnFailure(pPlugin);
    }

    if (pPlugin->IsAResolver()) {
        // A failed resolver may have loaded up providers to do work for it.
        // Stop any providers that are no longer needed
        StopDependentProvidersForResolver((resolver_t*)pPlugin);
    }
    else {
        // If this is last plugin that generated reports for a given resolver,
        // indicate the resolver as unavailable now.
        ProcessProviderFailureOnResolvers((provider_t*)pPlugin);
    }
}


// When an application closes its LocationOpen handle (either via LocationClose call
// or by process shutting-down cleanup), unregister any reports it may have
// forgot to unregister manually.
void pluginMgr_t::UnRegisterEventsFromHandle(locOpenHandle_t *pLocHandle) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -