Esempio n. 1
0
DWORD
LwSmSrvAcquireServiceHandle(
    PCWSTR pwszName,
    PLW_SERVICE_HANDLE phHandle
    )
{
    DWORD dwError = 0;
    PSM_TABLE_ENTRY pEntry = NULL;
    LW_SERVICE_HANDLE hHandle = NULL;

    dwError = LwSmTableGetEntry(pwszName, &pEntry);
    BAIL_ON_ERROR(dwError);

    dwError = LwAllocateMemory(sizeof(*hHandle), OUT_PPVOID(&hHandle));
    BAIL_ON_ERROR(dwError);

    hHandle->pEntry = pEntry;
    *phHandle = hHandle;
    
cleanup:
    
    return dwError;
    
error:
    
    *phHandle = NULL;
    
    if (pEntry)
    {
        LwSmTableReleaseEntry(pEntry);
    }
    
    goto cleanup;
}
Esempio n. 2
0
static
VOID
LwSmTableWatchdog(
    PVOID pContext
    )
{
    DWORD error = 0;
    PSM_TABLE_ENTRY pEntry = pContext;
    PSM_TABLE_ENTRY pOtherEntry = NULL;
    LW_SERVICE_STATUS status = {0};
    PWSTR* ppServices = NULL;
    DWORD index = 0;

    error = LwSmTableStartRecursive(pEntry);
    BAIL_ON_ERROR(error);

    /* See if any reverse dependencies changed state without announcing it */
    error = LwSmTableGetEntryReverseDependencyClosure(pEntry, &ppServices);
    BAIL_ON_ERROR(error);

    for (index = 0; ppServices[index]; index++)
    {
        error = LwSmTableGetEntry(ppServices[index], &pOtherEntry);
        BAIL_ON_ERROR(error);

        error = LwSmTableGetEntryStatus(pOtherEntry, &status);
        BAIL_ON_ERROR(error);

        if (status.state == LW_SERVICE_STATE_DEAD)
        {
            (void) LwSmTableStartRecursive(pOtherEntry);
        }

        LwSmTableReleaseEntry(pOtherEntry);
        pOtherEntry = NULL;
    }

error:

    if (ppServices)
    {
        LwSmFreeStringList(ppServices);
    }

    if (pOtherEntry)
    {
        LwSmTableReleaseEntry(pOtherEntry);
    }

    LwSmTableReleaseEntry(pEntry);

    return;
}
Esempio n. 3
0
static
DWORD
LwSmShutdownServices(
    VOID
    )
{
    DWORD dwError = 0;
    PWSTR* ppwszServiceNames = NULL;
    size_t i = 0;
    PSM_TABLE_ENTRY pEntry = NULL;

    SM_LOG_INFO("Shutting down running services");

    dwError = LwSmTableEnumerateEntries(&ppwszServiceNames);
    BAIL_ON_ERROR(dwError);
    
    for (i = 0; ppwszServiceNames[i]; i++)
    {
        dwError = LwSmTableGetEntry(ppwszServiceNames[i], &pEntry);
        BAIL_ON_ERROR(dwError);

        dwError = LwSmShutdownService(pEntry);
        if (dwError)
        {
            /* Ignore errors and try to shut down everything we can */
            SM_LOG_WARNING("Could not shut down service: %u\n", (unsigned int) dwError);
            dwError = 0;
        }

        LwSmTableReleaseEntry(pEntry);
        pEntry = NULL;
    }

cleanup:

    if (ppwszServiceNames)
    {
        LwSmFreeStringList(ppwszServiceNames);
    }

    if (pEntry)
    {
        LwSmTableReleaseEntry(pEntry);
    }

    return dwError;

error:

    goto cleanup;
}
Esempio n. 4
0
static
DWORD
LwSmShutdownService(
    PSM_TABLE_ENTRY pEntry
    )
{
    DWORD dwError = 0;
    PSM_TABLE_ENTRY pDep = NULL;
    PWSTR* ppwszDeps = NULL;
    size_t i = 0;

    dwError = LwSmTableGetEntryReverseDependencyClosure(pEntry, &ppwszDeps);
    BAIL_ON_ERROR(dwError);

    for (i = 0; ppwszDeps[i]; i++)
    {
        dwError = LwSmTableGetEntry(ppwszDeps[i], &pDep);
        BAIL_ON_ERROR(dwError);

        dwError = LwSmTableStopEntry(pDep);
        BAIL_ON_ERROR(dwError);

        LwSmTableReleaseEntry(pDep);
        pDep = NULL;
    }

    dwError = LwSmTableStopEntry(pEntry);
    BAIL_ON_ERROR(dwError);

cleanup:

    if (pDep)
    {
        LwSmTableReleaseEntry(pDep);
    }

    if (ppwszDeps)
    {
        LwSmFreeStringList(ppwszDeps);
    }

    return dwError;

error:

    goto cleanup;
}
Esempio n. 5
0
static
DWORD
LwSmTableStartRecursive(
    PSM_TABLE_ENTRY pEntry
    )
{
    DWORD error = 0;
    PSM_TABLE_ENTRY pOtherEntry = NULL;
    PWSTR* ppServices = NULL;
    DWORD index = 0;

    /* Start all dependencies */
    error = LwSmTableGetEntryDependencyClosure(pEntry, &ppServices);
    BAIL_ON_ERROR(error);

    for (index = 0; ppServices[index]; index++)
    {
        error = LwSmTableGetEntry(ppServices[index], &pOtherEntry);
        BAIL_ON_ERROR(error);

        error = LwSmTableStartEntry(pOtherEntry);
        BAIL_ON_ERROR(error);

        LwSmTableReleaseEntry(pOtherEntry);
        pOtherEntry = NULL;
    }

    error = LwSmTableStartEntry(pEntry);
    BAIL_ON_ERROR(error);

error:

    if (ppServices)
    {
        LwSmFreeStringList(ppServices);
    }

    if (pOtherEntry)
    {
        LwSmTableReleaseEntry(pOtherEntry);
    }

    return error;
}
Esempio n. 6
0
static
DWORD
LwSmTableGetEntryReverseDependencyClosureHelper(
    PSM_TABLE_ENTRY pEntry,
    PWSTR* ppwszAllServices,
    PWSTR** pppwszServiceList
    )
{
    DWORD dwError = 0;
    PLW_SERVICE_INFO pInfo = NULL;
    PLW_SERVICE_INFO pDepInfo = NULL;
    size_t i = 0;
    PSM_TABLE_ENTRY pDepEntry = NULL;
    PWSTR pwszDepName = NULL;
    BOOLEAN bLocked = FALSE;

    LOCK(bLocked, pEntry->pLock);
    dwError = LwSmCopyServiceInfo(pEntry->pInfo, &pInfo);
    UNLOCK(bLocked, pEntry->pLock);
    BAIL_ON_ERROR(dwError);

    for (i = 0; ppwszAllServices[i]; i++)
    {
        dwError = LwSmTableGetEntry(ppwszAllServices[i], &pDepEntry);
        BAIL_ON_ERROR(dwError);

        LOCK(bLocked, pEntry->pLock);
        dwError = LwSmCopyServiceInfo(pDepEntry->pInfo, &pDepInfo);
        UNLOCK(bLocked, pEntry->pLock);
        BAIL_ON_ERROR(dwError);

        if (LwSmStringListContains(pDepInfo->ppwszDependencies, pInfo->pwszName))
        {
            dwError = LwSmTableGetEntryReverseDependencyClosureHelper(
                pDepEntry,
                ppwszAllServices,
                pppwszServiceList);
            BAIL_ON_ERROR(dwError);
            
            dwError = LwAllocateWc16String(&pwszDepName, pDepInfo->pwszName);
            BAIL_ON_ERROR(dwError);

            dwError = LwSmStringListAppend(pppwszServiceList, pwszDepName);
            BAIL_ON_ERROR(dwError);

            pwszDepName = NULL;
        }

        LwSmCommonFreeServiceInfo(pDepInfo);
        pDepInfo = NULL;

        LwSmTableReleaseEntry(pDepEntry);
        pDepEntry = NULL;
    }

cleanup:

    LW_SAFE_FREE_MEMORY(pwszDepName);

    if (pInfo)
    {
        LwSmCommonFreeServiceInfo(pInfo);
    }

    if (pDepInfo)
    {
        LwSmCommonFreeServiceInfo(pDepInfo);
    }

    if (pDepEntry)
    {
        LwSmTableReleaseEntry(pDepEntry);
    }

    return dwError;

error:

    goto cleanup;
}
Esempio n. 7
0
DWORD
LwSmPopulateTable(
    VOID
    )
{
    DWORD dwError = 0;
    HANDLE hReg = NULL;
    PWSTR* ppwszNames = NULL;
    PWSTR pwszName = NULL;
    PLW_SERVICE_INFO pInfo = NULL;
    PSM_TABLE_ENTRY pEntry = NULL;
    size_t i = 0;

    SM_LOG_VERBOSE("Populating service table");

    dwError = RegOpenServer(&hReg);
    BAIL_ON_ERROR(dwError);

    dwError = LwSmRegistryEnumServices(hReg, &ppwszNames);
    switch (dwError)
    {
    case LWREG_ERROR_NO_SUCH_KEY_OR_VALUE:
        /* No services in registry */
        dwError = 0;
        goto cleanup;
    }
    BAIL_ON_ERROR(dwError);

    for (i = 0; ppwszNames[i]; i++)
    {
        pwszName = ppwszNames[i];

        LwSmCommonFreeServiceInfo(pInfo);
        pInfo = NULL;

        dwError = LwSmRegistryReadServiceInfo(hReg, pwszName, &pInfo);
        switch (dwError)
        {
        case LWREG_ERROR_NO_SUCH_KEY_OR_VALUE:
            dwError = 0;
            continue;
        default:
            break;
        }
        BAIL_ON_ERROR(dwError);

        dwError = LwSmTableGetEntry(pwszName, &pEntry);
        if (!dwError)
        {
            dwError = LwSmTableUpdateEntry(pEntry, pInfo, LW_SERVICE_INFO_MASK_ALL);
            BAIL_ON_ERROR(dwError);
        }
        else if (dwError == LW_ERROR_NO_SUCH_SERVICE)
        {
            dwError = LwSmTableAddEntry(pInfo, &pEntry);
            BAIL_ON_ERROR(dwError);
        }
        else
        {
            BAIL_ON_ERROR(dwError);
        }

        LwSmTableReleaseEntry(pEntry);
        pEntry = NULL;
    }

cleanup:

    LwSmFreeStringList(ppwszNames);
    LwSmCommonFreeServiceInfo(pInfo);

    if (hReg)
    {
        RegCloseServer(hReg);
    }

    return dwError;

error:

    goto cleanup;
}