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

📄 locplgmgr.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    pRes->ReportTypeAvailable(pNewReportType);
    if (pRC->NewReport(pRes,pNewReport))
        pRC->PluginStateChange();

    if (oldStateReport == PLUGIN_STATE_UNAVAILABLE) {
        // In this case, the plugin was temporarily unavailable for this 
        // report type (not necessarily others) and lower priority plugins may have 
        // been started for this type.  Stop them.
        StopPluginsForReportType(pNewReportType, pRes->GetStartOrder() + 1);
    }

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

// Called when a resolver cannot generate the resolved report.  Note
// that resolvers do not call this function directly, but instead the LF
// will have it called when a resolver returns from a resolution without
// resolving a particular report type
DWORD pluginMgr_t::ResolverReportTypeUnavailable(resolver_t *pRes, const GUID *pReportType) {
    DEBUGMSG(ZONE_RESOLVER,(L"LOC: ResolverUnavailable for resolver DLL <%s>",
                            pRes->GetName()));

    // LF itself (not a 3rd party plugin) is calling this, so we can assume
    // that reportType is reasonably well formatted.
    DEBUGCHK(g_pLocLock->IsLocked());
    DEBUGCHK(pReportType);
    DEBUGCHK(g_serviceState == SERVICE_STATE_ON);
    DEBUGCHK(FindResolver(pRes));

    DWORD err;

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

    pRes->ReportTypeUnavailable(pReportType);

    // Determines whether any report type in resolver is still active
    PLUGIN_STATE currentState = pRes->GetState(); 

    // Current state goes to unavilable if NO reports this resolver generates
    // can be resolved at this point
    if (currentState == PLUGIN_STATE_UNAVAILABLE) {
        // 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(pRes);

        // Stop providers if they were only spun up for this report
        StopDependentProvidersForResolver(pRes);
    }

    err = ERROR_SUCCESS;
done:
    return err;
}

//*****************************************************************************
//  Routines that process Location Framework API calls.
//*****************************************************************************


// An application has indicated via LocationRegisterForReport that it wants
// plugin(s) needed to generate this report started.
DWORD pluginMgr_t::RegisterAppForReport(const GUID *pReportType, locOpenHandle_t *pLocHandle,  
                                        HANDLE hNewLocationReport, HANDLE hStateChangeEvent)
{
    DEBUGCHK(g_pLocLock->IsLocked());

    reportCol_t *pRC = FindRC(pReportType);
    if (! pRC) {
        DEBUGMSG(ZONE_ERROR,(L"LOC: ERROR: No plugin supports report type <" SVSUTIL_GUID_FORMAT_W L">\r\n",
                             SVSUTIL_PGUID_ELEMENTS(pReportType)));
        return ERROR_DEV_NOT_EXIST;
    }

    PLUGIN_STATE reportState = GetPluginInfoForReport(pReportType, NULL,FALSE);
    if (reportState == PLUGIN_STATE_ERROR) {
        DEBUGMSG(ZONE_ERROR,(L"LOC: ERROR: All plugins that support report type <" SVSUTIL_GUID_FORMAT_W L"> are in PLUGIN_ERROR state\r\n",
                             SVSUTIL_PGUID_ELEMENTS(pReportType)));
        return ERROR_DEV_NOT_EXIST;
    }

    if (pRC->HasRegisteredAppsOrResolvers()) {
        // Another application has already registered for this report type
        // The plugin manager has already started appropriate plugins to process
        // this, so just note that there's a new client requesting reports.
        return pRC->RegisterAppForReport(pLocHandle, hNewLocationReport, hStateChangeEvent);
    }

    // Otherwise, this is first instance of anything registering for this report type.

    // Register now, even though we don't know if we'll succeed, so that if we hit
    // an OOM here we don't bother starting up plugin manager
    DWORD err = pRC->RegisterAppForReport(pLocHandle, hNewLocationReport, hStateChangeEvent);
    if (err != ERROR_SUCCESS)
        return err;

    err = StartPluginForReportType(pReportType,0);
    if (err == ERROR_SUCCESS)
        return ERROR_SUCCESS;

    // StartPluginForReportType could fail if for instance a resolver 
    // was only plugin that supported this type, but the resolver
    // couldn't startup any providers that it required.

    DEBUGMSG(ZONE_ERROR,(L"LOC: No plugins were available to service report type <" SVSUTIL_GUID_FORMAT_W L">",
             SVSUTIL_PGUID_ELEMENTS(pReportType)));

    // Cleanup
    pRC->UnRegisterAppForReport(pLocHandle);
    return ERROR_DEV_NOT_EXIST;
}


// An application no longer wishes to the particular report type to be
// active.  Deregister and potentially close plugins that were generating 
// the report.
DWORD pluginMgr_t::UnRegisterAppForReport(locOpenHandle_t *pLocHandle, const GUID *pReportType) {
    reportCol_t *pRC = FindRC(pReportType);
    if (! pRC) {
        DEBUGMSG(ZONE_ERROR,(L"LOC: ERROR: No plugin supports report type <" SVSUTIL_GUID_FORMAT_W L">\r\n",
                                SVSUTIL_PGUID_ELEMENTS(pReportType)));
        return ERROR_DEV_NOT_EXIST;
    }

    DWORD err = pRC->UnRegisterAppForReport(pLocHandle);
    if (err != ERROR_SUCCESS)
        return err;

    if (pRC->HasRegisteredAppsOrResolvers()) {
        // If this report has other applications or resolvers
        // registered on it, then we take no further action
        return ERROR_SUCCESS; 
    }

    // No longer require this report type, so tell plugins generating it to stop.
    StopPluginsForReportType(pReportType, 0);
    return ERROR_SUCCESS;
}


// Fill in fields of LOCATION_SERVICE_STATE
void pluginMgr_t::GetServiceState(LOCATION_SERVICE_STATE *pServiceState) {
    DEBUGCHK(g_pLocLock->IsLocked());

    pServiceState->serviceState       = g_serviceState;
    pServiceState->numLoadedProviders = pServiceState->numLoadedResolvers =
    pServiceState->numActiveProviders = pServiceState->numActiveResolvers = 0;

    // Iterate through each plugin, incrementing count and examining state.
    pluginListIter_t it    = m_pluginList.begin();
    pluginListIter_t itEnd = m_pluginList.end();
        
    for (; it != itEnd; ++it) {
        PLUGIN_STATE pluginState = (*it)->GetState();
        BOOL isActive = (pluginState >= PLUGIN_STATE_STARTING_UP);
        if ((*it)->IsAProvider()) {
            pServiceState->numLoadedProviders++;
            if (isActive)
                pServiceState->numActiveProviders++;
        }
        else {
            DEBUGCHK((*it)->IsAResolver());
            pServiceState->numLoadedResolvers++;
            if (isActive)
                pServiceState->numActiveResolvers++;
        }
    }
}


// Retrieves information about all providers loaded on the system,
// as the result of LocationGetProvidersInfo call
DWORD pluginMgr_t::GetProvidersInfo(PROVIDER_INFORMATION *pProviders, DWORD *pcbBuffer) {
    DEBUGCHK(g_pLocLock->IsLocked());

    //
    // Determine if passed buffer is big enough
    //
    LOCATION_SERVICE_STATE locServiceState;
    GetServiceState(&locServiceState);

    DWORD numBytesToWrite = locServiceState.numLoadedProviders*sizeof(PROVIDER_INFORMATION);

    if ((*pcbBuffer) < numBytesToWrite) {
#ifdef DEBUG
        if ((*pcbBuffer) != 0) { 
            // if app passed 0 bytes, they're expecting an error so don't DEBUGMSG
            DEBUGMSG(ZONE_ERROR,(L"LOC: LocationGetProvidersInfo passed <%d> byte buffer size but needs <%d> bytes\r\n",
                     *pcbBuffer,numBytesToWrite));
        }
#endif
        *pcbBuffer = numBytesToWrite;
        return ERROR_INSUFFICIENT_BUFFER;
    }
    *pcbBuffer = numBytesToWrite;

    //
    // Actually retrieve the data into the buffer
    //
    pluginListIter_t it    = m_pluginList.begin();
    pluginListIter_t itEnd = m_pluginList.end();

    for (; it != itEnd; ++it) {
        if ((*it)->IsAResolver())
            continue;

        provider_t *pProv = (provider_t*)((plugin_t*)(*it));

        pProv->GetProviderInfo(pProviders);
        pProviders++;
    }

    return ERROR_SUCCESS;
}

// Retrieves information about all resolvers loaded on the system,
// as the result of LocationGetResolversInfo call
DWORD pluginMgr_t::GetResolversInfo(RESOLVER_INFORMATION *pResolvers, DWORD *pcbBuffer) {
    DEBUGCHK(g_pLocLock->IsLocked());

    //
    // Determine if passed buffer is big enough
    //
    LOCATION_SERVICE_STATE locServiceState;
    GetServiceState(&locServiceState);

    DWORD numBytesToWrite = locServiceState.numLoadedResolvers*sizeof(RESOLVER_INFORMATION);

    if ((*pcbBuffer) < numBytesToWrite) {
#ifdef DEBUG
        if ((*pcbBuffer) != 0) { 
            // if app passed 0 bytes, they're expecting an error so don't DEBUGMSG
            DEBUGMSG(ZONE_ERROR,(L"LOC: LocationGetResolversInfo passed <%d> byte buffer size but needs <%d> bytes\r\n",
                     *pcbBuffer,numBytesToWrite));
        }
#endif
        *pcbBuffer = numBytesToWrite;
        return ERROR_INSUFFICIENT_BUFFER;
    }
    *pcbBuffer = numBytesToWrite;

    //
    // Actually retrieve the data into the buffer
    //
    pluginListIter_t it    = m_pluginList.begin();
    pluginListIter_t itEnd = m_pluginList.end();

    for (; it != itEnd; ++it) {
        if ((*it)->IsAProvider())
            continue;

        resolver_t *pRes = (resolver_t*)((plugin_t*)(*it));

        pRes->GetResolverInfo(pResolvers);
        pResolvers++;
    }

    return ERROR_SUCCESS;
}

// Determines state of the plugin that can generate the given report,
// if the system supports it.  Since multiple plugins may be able to support
// the same report type, we return the "highest" state (based on int value
// of the PLUGIN_STATE enum).  This means if highest prio plugin is in ERROR
// state, next is UNAVAILABLE, 3rd is starting up, and 4th is OFF, we 
// chose the starting up.
PLUGIN_STATE pluginMgr_t::GetPluginInfoForReport(const GUID *pReportType, GUID *pPluginGuid, BOOL providersOnly) {
    DEBUGCHK(g_pLocLock->IsLocked());

    PLUGIN_STATE retState = PLUGIN_STATE_NOT_SUPPORTED;
    const GUID  *pCurPlugin = NULL;

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

    for (; it != itEnd; ++it) {
        if (! (*it)->CanGenerateReportType(pReportType))
            continue;

        if (providersOnly && (*it)->IsAResolver())
            continue;

        PLUGIN_STATE pluginState = (*it)->GetReportTypeState(pReportType);
        if (pluginState > retState) {
            pCurPlugin = (*it)->GetGuid();
            retState = pluginState;
        }
    }

    if (pPluginGuid) {
        if (pCurPlugin)
            memcpy(pPluginGuid,pCurPlugin,sizeof(GUID));
        else
            memset(pPluginGuid,0,sizeof(GUID));
    }

    return retState;
}



#ifdef DEBUG
// Verify that every item on the pluginList is unique.  At various
// times LF creates such lists and assumes that the list has only 
// unique items on it.  Failing this check indicates a serious bug in the LF
// that could cause plugins to be called multiple times for the same event.
void DbgVerifyPluginListItemsUnique(pluginList_t *pPluginList) {
    pluginListIter_t it    = pPluginList->begin();
    pluginListIter_t itEnd = pPluginList->end();

    for (; it != itEnd; ++it) {
        // For each item in list, run through list again and verify
        // that it is not present
        pluginListIter_t itTrav = it;
        ++itTrav;
        for (; itTrav != itEnd; ++itTrav)
            DEBUGCHK(itTrav != it);
    }
}
#endif

⌨️ 快捷键说明

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