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

📄 locplgmgr.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            continue;
        }

        if (pRC->HasRegisteredAppsOrResolvers()) {
            // If the report type has other clients, we can't deregister it.
            continue; 
        }

        // Stop since this was the last client associated with the report
        StopPlugins(&supportedReports[i],&pluginsToStop,0);
    }
}


// When a provider becomes unavailable, it is possible that it had 
// resolvers depending on it to generate reports.  In this function,
// we will see if no other running providers generate this report and if they
// do not then we will try to start one.

// If it is not possible to start another plugin and hence a given resolver
// has no possibility of having a provider generate reports for it,
// then indicate to the resolver that is de facto unavailable (even
// if resolver could still in theory operate).

// For instance, suppose an Active Directory resolver relies on 802.11
// reports that the 802.11 provider generates.  If the 802.11 provider
// becomes unavailable, then we should mark the AD Resolver as unavailable
// if and only if there are no other providers that could generate a report 
// the AD supports. 
void pluginMgr_t::ProcessProviderFailureOnResolvers(provider_t *pProv) {
    DEBUGCHK(g_pLocLock->IsLocked());
    DEBUGCHK((pProv->GetState() == PLUGIN_STATE_UNAVAILABLE) ||
             (pProv->GetState() == PLUGIN_STATE_ERROR));

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

    DEBUGMSG(ZONE_PLUGIN,(L"LOC: Determining which resolvers depended on unavailable provider <%s> and trying to restart\r\n",
             pProv->GetName()));

    // Iterate through each resolver, detecting if this provider was the last
    // one that could generate reports.

    for (; it != itEnd; ++it) {
        if ((*it)->IsAProvider()) {
            // Providers generate reports independent of one another.  If 
            // one provider is unavailable it has no effect on other providers.
            continue;
        }

        if ((*it)->GetState() < PLUGIN_STATE_UNAVAILABLE) {
            // The resolver was not actively trying to determine new 
            // reports, so continue.
            continue;
        }

        resolver_t *pRes = (resolver_t*)((plugin_t*)(*it));
        BOOL        noProvsAvailable = TRUE;

        if (! pRes->HasProvidersAvailable()) {
            // Resolver is already in state where nothing is available.
            // Don't bother recomputing all this.
            continue;
        }

        DWORD numSupportedReports;
        GUID  supportedReports[MAX_PLUGIN_REPORT_TYPES];
        pRes->GetSupportedReportInfo(supportedReports,&numSupportedReports);

        // For each report type that the resolver can support, determine
        // if there is any *provider* that can generate the given type.
        // Even one match is enough to indicate that the resolver is still valid.
        for (DWORD i = 0; i < numSupportedReports; i++) {
            PLUGIN_STATE repState = GetPluginInfoForReport(&supportedReports[i],NULL,TRUE);
            if (repState >= PLUGIN_STATE_STARTING_UP) {
                noProvsAvailable = FALSE;
                break;
            }
        }

        if (noProvsAvailable) {
            // First, try to startup a new provider to do this work.
            if (! StartDependentProviderIfNeeded(NULL,pRes)) {
                // No providers can support this resolver even after this attempt.
                // Indicate this to the resolver so it can take appropriate action.
                pRes->NoProvidersAvailable();
                // Try to startup next plugin for any reports that were registered
                // for this resolver.  Even if resolver would've been available
                // otherwise, it's dead in the water without a provider.
                StartNextPluginsOnFailure(pRes);
            }
        }
    }
}


//*****************************************************************************
//  Callback implementations
//*****************************************************************************

// A new provider report is available via NewProviderReport.  Alert
// registered apps & resolvers, possibly stop lower priority plugins that 
// were started up if this plugin was previously unavailable.
DWORD pluginMgr_t::NewProviderReportInd(HANDLE provContext, LOCATION_REPORT *pNewReport) {
    DEBUGMSG(ZONE_PROVIDER,(L"LOC: Received NewProviderReport callback.  Context=<0x%08x>, report=<0x%08x>\r\n",
                          provContext,pNewReport));

    if (pNewReport == NULL) {
        DEBUGMSG(ZONE_ERROR,(L"LOC: NewProviderReportInd passed NULL report, invalid\r\n"));
        return ERROR_INVALID_PARAMETER;
    }

    provider_t *pProv;
    reportCol_t *pRC;
    LOCATION_REPORT_BASE *pNewReportBase = (LOCATION_REPORT_BASE *)pNewReport;
    GUID                 *pNewReportType = &pNewReportBase->type;

    DWORD err;

    if (pNewReportBase->size < sizeof(LOCATION_REPORT_BASE)) {
        DEBUGMSG(ZONE_ERROR,(L"LOC: NewProviderReportInd passed in report that is too small\r\n"));
        return ERROR_INVALID_PARAMETER;
    }

    g_pLocLock->Lock();

    if (g_serviceState != SERVICE_STATE_ON) {
        // This indicates that the location service is shutting down.  The last
        // thing we want to do is start stopping & starting plugins, because
        // otherwise the shutdown logic becomes much harder.
        DEBUGMSG(ZONE_RESOLVER,(L"LOC: Ignoring NewProviderReport since loc service is not on\r\n"));
        err = ERROR_SERVICE_NOT_ACTIVE;
        goto done;
    }

    pProv = FindProvider(provContext);
    if (!pProv) {
        err = ERROR_INVALID_PARAMETER;
        goto done;
    }

    PLUGIN_STATE oldState = pProv->GetState();
    if (oldState < PLUGIN_STATE_UNAVAILABLE) {
        // In this case, plugin isn't registered anymore so throw out
        // any reports it may still be generating.
        DEBUGMSG(ZONE_PROVIDER,(L"LOC: Ignoring Provider Report for <%s> because state is off/error\r\n",
                                  pProv->GetName()));
        err = ERROR_SERVICE_NOT_ACTIVE;
        goto done;
    }

    // Indicate to reports collector monitoring this report type
    if (! pProv->CanGenerateReportType(pNewReportType)) {
        // For instance, if a lat/long only provider generates an 802.11 address or
        // if we're not currently registered for the report, then ignore.
        DEBUGMSG(ZONE_PROVIDER,(L"LOC: Provider report for <%s> is not a report the provider is configured to generate\r\n",
                                  pProv->GetName()));
        err = ERROR_INVALID_PARAMETER;
        goto done;
    }

    pRC = FindRC(pNewReportType);
    
    pProv->ReportsAvailable();
    if (pRC->NewReport(pProv,pNewReport)) {
        // NewReport returns TRUE if the RC will use this report 
        // (i.e. not a higher prio plugin available).
        if (! pProv->HasReceivedReport(pNewReportType)) {
            // This is the first time on this ProviderGetLocation cycle 
            // that this report has been generated OR it's coming back
            // from unavailable state.  Indicate this state change to applications
            // only the first time we transition to ON.
            pRC->PluginStateChange();
        }
    }

    pProv->IndicateReceivedReport(pNewReportType);

    if ((oldState == PLUGIN_STATE_UNAVAILABLE) || (oldState == PLUGIN_STATE_STARTING_UP)) {
        // In this case, the plugin was temporarily unavailable and
        // lower priority plugins may have been started.  Stop them.
        StopPluginsOnProviderAvailable(pProv);
    }

    err = ERROR_SUCCESS;
done:
    g_pLocLock->Unlock();
    return err;
}

// Provider calls ProviderUnavailable callback.  Move provider to 
// the unavailable state.
DWORD pluginMgr_t::ProviderUnavailableInd(HANDLE provContext) {
    DEBUGMSG(ZONE_PROVIDER,(L"LOC: Received ProviderUnavailable callback.  Context=<0x%08x>\r\n",
                             provContext));

    provider_t *pProv;
    DWORD err;

    g_pLocLock->Lock();

    if (g_serviceState != SERVICE_STATE_ON) {
        DEBUGMSG(ZONE_RESOLVER,(L"LOC: Ignoring ProviderUnavailable since loc service is not on\r\n"));
        err = ERROR_SERVICE_NOT_ACTIVE;
        goto done;
    }

    pProv = FindProvider(provContext);
    if (!pProv) {
        err = ERROR_INVALID_PARAMETER;
        goto done;
    }

    PLUGIN_STATE oldState = pProv->GetState();
    if (oldState <= PLUGIN_STATE_UNAVAILABLE) {
        // In this case, provider has already been put into the unavailable
        // state.  The provider is basically calling unavaibale a 2nd time
        // (before giving new data) and hence we ignore this report.
        DEBUGMSG(ZONE_PROVIDER,(L"LOC: Ignoring Provider Unavialable for <%s> because state is off/error/unavail\r\n",
                                  pProv->GetName()));
        err = ERROR_SERVICE_NOT_ACTIVE;
        goto done;
    }

    pProv->ReportsUnavailable();

    DEBUGMSG(ZONE_PROVIDER,(L"LOC: Marking provider <%s> as unavailable\r\n",pProv->GetName()));

    // It doesn't matter if plugin was on or just starting up at this point -
    // either way we need to try to start next plugin in line.  
    StartNextPluginsOnFailure(pProv);
    // If there were resolvers that were relying on this provider to 
    // generate reports for them, need to either startup new providers
    // or if that fails, disable the resolvers.
    ProcessProviderFailureOnResolvers(pProv);

    err = ERROR_SUCCESS;
done:
    g_pLocLock->Unlock();
    return err;
}

// Resolver cannot resolve a particular report.
DWORD pluginMgr_t::NewResolverReportInd(HANDLE resContext, LOCATION_REPORT *pNewReport) {
    DEBUGMSG(ZONE_RESOLVER,(L"LOC: Received NewResolverReport callback.  Context=<0x%08x>, report=<0x%08x>\r\n",
                             resContext,pNewReport));

    DWORD err;

    if (pNewReport == NULL) {
        DEBUGMSG(ZONE_ERROR,(L"LOC: NewResolverReport passed NULL report, invalid\r\n"));
        return ERROR_SUCCESS;
    }

    LOCATION_REPORT_BASE *pNewReportBase = (LOCATION_REPORT_BASE*)pNewReport;

    if (pNewReportBase->size < sizeof(LOCATION_REPORT_BASE)) {
        DEBUGMSG(ZONE_ERROR,(L"LOC: NewResolverReport passed in report that is too small\r\n"));
        return ERROR_INVALID_PARAMETER;
    }

    g_pLocLock->Lock();

    if (g_serviceState != SERVICE_STATE_ON) {
        DEBUGMSG(ZONE_RESOLVER,(L"LOC: Ignoring NewResolverReport since loc service is not on\r\n"));
        err = ERROR_SERVICE_NOT_ACTIVE;
        goto done;
    }

    resolver_t *pRes;
    reportCol_t *pRC;
    GUID                 *pNewReportType = &pNewReportBase->type;

    pRes = FindResolver(resContext);
    if (!pRes) {
        err = ERROR_INVALID_PARAMETER;
        goto done;
    }

    if (! pRes->CanGenerateReportType(pNewReportType)) {
        DEBUGMSG(ZONE_RESOLVER,(L"LOC: Resolver report for <%s> is not a report the resolver is requested to generate\r\n",
                 pRes->GetName()));
        err = ERROR_INVALID_PARAMETER;
        goto done;
    }

    PLUGIN_STATE oldStatePlugin = pRes->GetState();
    PLUGIN_STATE oldStateReport = pRes->GetReportTypeState(pNewReportType);

    if (oldStateReport < PLUGIN_STATE_UNAVAILABLE) {
        DEBUGMSG(ZONE_RESOLVER,(L"LOC: Resolver <%s> is not requested to generate this report type, ignoring report\r\n",
                 pRes->GetName()));
        err = ERROR_SERVICE_NOT_ACTIVE;
        goto done;
    }

    if (! pRes->HasProvidersAvailable()) {
        // If the resolver has all plugins inactive during its ResolverGetLocation
        // call, then just throw out reports the resolver generates in the interim
        // In theory we could still push these up to the app but it would greatly
        // complicate the state maintenence for little gain.
        DEBUGMSG(ZONE_RESOLVER,(L"LOC: Resolver <%s> does not have providers available, ignoring report\r\n",
                 pRes->GetName()));
        err = ERROR_SERVICE_NOT_ACTIVE;
        goto done;
    }

    // Indicate to reports collector monitoring this report type
    pRC = FindRC(pNewReportType);

    // Regardless of how we process report, always have resolver
    // remember the fact it has received it so that when ResolverGetLocation
    // callback returns resolver will not mark it as unavailable.
    pRes->IndicateReceivedReport(pNewReportType);

    if (oldStateReport == PLUGIN_STATE_ON) {
        // If the plugin for this type is already in the ON state, then 
        // no further action is required.
        pRC->NewReport(pRes,pNewReport);
        err = ERROR_SUCCESS;
        goto done;
    }

    if (oldStatePlugin == PLUGIN_STATE_UNAVAILABLE) {
        // When the resolver entered the unavailable state, it stopped 
        // all the plugins that could register reports for it in order
        // to save them from generating reports for nothing.  Now that
        // the resolver has returned, we need to start at least 1 up again.
        if (! StartDependentProviderIfNeeded(pNewReportType,pRes)) {
            // If we were unable to start providers, then we're dead in the water
            // again.  Take no further action
            err = ERROR_SERVICE_NOT_ACTIVE;
            goto done;
        }
    }

⌨️ 快捷键说明

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