Esempio n. 1
0
LW_NTSTATUS
LwRtlSvcmLoadEmbedded(
    LW_IN LW_PCWSTR pServiceName,
    LW_IN LW_SVCM_MODULE_ENTRY_FUNCTION Entry,
    LW_OUT PLW_SVCM_INSTANCE* ppInstance
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PLW_SVCM_INSTANCE pInstance = NULL;

    status = InitPool();
    GCOS(status);

    status = LW_RTL_ALLOCATE_AUTO(&pInstance);
    GCOS(status);

    LW_RTL_LOG_DEBUG("Loading embedded service: %s", pServiceName);

    status = LwRtlSvcmInitializeInstance(pInstance, pServiceName, "<embedded>", Entry);
    GCOS(status);

cleanup:

    if (!NT_SUCCESS(status))
    {
        LwRtlSvcmUnload(pInstance);
        pInstance = NULL;
    }

    *ppInstance = pInstance;

    return status;
}
Esempio n. 2
0
NTSTATUS
RdrCreateContext(
    PIRP pIrp,
    PRDR_OP_CONTEXT* ppContext
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PRDR_OP_CONTEXT pContext = NULL;

    status = LW_RTL_ALLOCATE_AUTO(&pContext);
    BAIL_ON_NT_STATUS(status);

    LwListInit(&pContext->Link);

    pContext->pIrp = pIrp;
    
    if (pIrp)
    {
        LWIO_LOG_DEBUG("Created op context %p for IRP %p", pContext, pIrp);
    }
    else
    {
        LWIO_LOG_DEBUG("Created op context %p", pContext);
    }

    *ppContext = pContext;

error:

    return status;
}
Esempio n. 3
0
LW_NTSTATUS
LwRtlCreateThreadPoolAttributes(
    LW_OUT PLW_THREAD_POOL_ATTRIBUTES* ppAttrs
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PLW_THREAD_POOL_ATTRIBUTES pAttrs = NULL;

    status = LW_RTL_ALLOCATE_AUTO(&pAttrs);
    GOTO_ERROR_ON_STATUS(status);
    
    pAttrs->bDelegateTasks = TRUE;
    pAttrs->lTaskThreads = 0;
    pAttrs->lWorkThreads = 0;
    pAttrs->ulTaskThreadStackSize = (ULONG) _LW_TASK_THREAD_STACK_SIZE;
    pAttrs->ulWorkThreadStackSize = (ULONG) _LW_WORK_THREAD_STACK_SIZE;
    pAttrs->ulWorkThreadTimeout = DEFAULT_WORK_THREAD_TIMEOUT;

    *ppAttrs = pAttrs;

cleanup:

    return status;

error:

    *ppAttrs = NULL;

    goto cleanup;
}
Esempio n. 4
0
LW_NTSTATUS
LwRtlQueueWorkItem(
    LW_IN PLW_THREAD_POOL pPool,
    LW_IN LW_WORK_ITEM_FUNCTION_COMPAT pfnFunc,
    LW_IN LW_PVOID pContext,
    LW_IN LW_WORK_ITEM_FLAGS Flags
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PCOMPAT_WORK_ITEM pCompat = NULL;
    PLW_WORK_ITEM pItem = NULL;

    status = LW_RTL_ALLOCATE_AUTO(&pCompat);
    GOTO_ERROR_ON_STATUS(status);

    pCompat->pfnFunc = pfnFunc;
    pCompat->pContext = pContext;

    status = LwRtlCreateWorkItem(pPool, &pItem, CompatWorkItem, pCompat);
    GOTO_ERROR_ON_STATUS(status);
    pCompat = NULL;

    LwRtlScheduleWorkItem(pItem, Flags);
    pItem = NULL;

error:

    RTL_FREE(&pCompat);
    LwRtlFreeWorkItem(&pItem);

    return status;
}
Esempio n. 5
0
NTSTATUS
RdrAllocatePacket(
    ULONG ulSize,
    PSMB_PACKET* ppPacket
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PSMB_PACKET pPacket = NULL;

    status = LW_RTL_ALLOCATE_AUTO(&pPacket);
    BAIL_ON_NT_STATUS(status);

    pPacket->refCount = 1;

    status = RdrAllocatePacketBuffer(pPacket, ulSize);
    BAIL_ON_NT_STATUS(status);

    *ppPacket = pPacket;

cleanup:

    return status;

error:

    RdrFreePacket(pPacket);

    goto cleanup;
}
Esempio n. 6
0
LW_NTSTATUS
LwRtlSvcmRefresh(
    LW_IN PLW_SVCM_INSTANCE pInstance,
    LW_IN LW_SVCM_NOTIFY_FUNCTION Notify,
    LW_IN LW_PVOID pContext
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PSVCM_COMMAND_STATE pRefreshState = NULL;
    PLW_WORK_ITEM pRefreshItem = NULL;

    if (!pInstance)
    {
        status = STATUS_INVALID_PARAMETER;
        GCOS(status);
    }

    status = LW_RTL_ALLOCATE_AUTO(&pRefreshState);
    GCOS(status);

    status = LwRtlCreateWorkItem(
        gSvcmState.pPool,
        &pRefreshItem,
        RefreshWorkItem,
        pRefreshState);
    GCOS(status);

    pRefreshState->pInstance = pInstance;
    pRefreshState->Notify = Notify;
    pRefreshState->pNotifyContext = pContext;

    LwRtlScheduleWorkItem(pRefreshItem, 0);
    pRefreshItem = NULL;
    pRefreshState = NULL;

cleanup:

     LwRtlFreeWorkItem(&pRefreshItem);
     RTL_FREE(&pRefreshState);

     return status;
}
Esempio n. 7
0
NTSTATUS
LwRtlCreateTaskGroup(
    PLW_THREAD_POOL pPool,
    PLW_TASK_GROUP* ppGroup
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PLW_TASK_GROUP pGroup = NULL;

    if (pPool->pDelegate)
    {
        return LwRtlCreateTaskGroup(pPool->pDelegate, ppGroup);
    }

    status = LW_RTL_ALLOCATE_AUTO(&pGroup);
    GOTO_ERROR_ON_STATUS(status);

    pGroup->pPool = pPool;
    RingInit(&pGroup->Tasks);

    status = LwErrnoToNtStatus(pthread_mutex_init(&pGroup->Lock, NULL));
    GOTO_ERROR_ON_STATUS(status);
    pGroup->bLockInit = TRUE;

    status = LwErrnoToNtStatus(pthread_cond_init(&pGroup->Event, NULL));
    GOTO_ERROR_ON_STATUS(status);
    pGroup->bEventInit = TRUE;

    *ppGroup = pGroup;

cleanup:

    return status;

error:

    LwRtlFreeTaskGroup(&pGroup);
    *ppGroup = NULL;

    goto cleanup;
}
Esempio n. 8
0
LW_NTSTATUS
LwRtlSetTaskUnixSignal(
    LW_IN PLW_TASK pTask,
    LW_IN int Sig,
    LW_IN LW_BOOLEAN bSubscribe
    )
{
    NTSTATUS status = STATUS_SUCCESS;

    if (bSubscribe && !pTask->pUnixSignal)
    {
        status = LW_RTL_ALLOCATE_AUTO(&pTask->pUnixSignal);
        GOTO_ERROR_ON_STATUS(status);
    }

    status = RegisterTaskUnixSignal(pTask, Sig, bSubscribe);
    GOTO_ERROR_ON_STATUS(status);

error:

    return status;
}
Esempio n. 9
0
NTSTATUS
CreateWorkItem(
    LW_IN PLW_WORK_THREADS pThreads,
    LW_OUT PLW_WORK_ITEM* ppWorkItem,
    LW_WORK_ITEM_FUNCTION pfnFunc,
    PVOID pContext
    )
{
    PLW_WORK_ITEM pItem = NULL;
    NTSTATUS status = STATUS_SUCCESS;

    LOCK_THREADS(pThreads);

    if (pThreads->ulStarted == 0)
    {
        /* Make sure at least one thread is running */
        status = StartWorkThread(pThreads, &pThreads->pWorkThreads[0]);
        GOTO_ERROR_ON_STATUS(status);
    }

    status = LW_RTL_ALLOCATE_AUTO(&pItem);
    GOTO_ERROR_ON_STATUS(status);

    RingInit(&pItem->Ring);
    pItem->pThreads = pThreads;
    pItem->pfnFunc = pfnFunc;
    pItem->pContext = pContext;

    pThreads->ulWorkItemCount++;

error:

    UNLOCK_THREADS(pThreads);

    *ppWorkItem = pItem;

    return status;
}
Esempio n. 10
0
NTSTATUS
LwRtlCreateTask(
    PLW_THREAD_POOL pPool,
    PLW_TASK* ppTask,
    PLW_TASK_GROUP pGroup,
    LW_TASK_FUNCTION pfnFunc,
    PVOID pContext
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PEPOLL_TASK pTask = NULL;
    PEPOLL_THREAD pThread = NULL;
    ULONG ulMinLoad = 0xFFFFFFFF;
    ULONG ulIndex = 0;

    if (pPool->pDelegate)
    {
        return LwRtlCreateTask(pPool->pDelegate, ppTask, pGroup, pfnFunc, pContext);
    }

    status = LW_RTL_ALLOCATE_AUTO(&pTask);
    GOTO_ERROR_ON_STATUS(status);

    RingInit(&pTask->GroupRing);
    RingInit(&pTask->QueueRing);
    RingInit(&pTask->SignalRing);

    pTask->pGroup = pGroup;
    pTask->ulRefCount = 2;
    pTask->pfnFunc = pfnFunc;
    pTask->pFuncContext = pContext;
    pTask->Fd = -1;
    pTask->EventArgs = LW_TASK_EVENT_INIT;
    pTask->EventWait = LW_TASK_EVENT_EXPLICIT;
    pTask->llDeadline = 0;

    LOCK_POOL(pPool);

    for (ulIndex = 0; ulIndex < pPool->ulEventThreadCount; ulIndex++)
    {
        if (pPool->pEventThreads[ulIndex].ulLoad < ulMinLoad)
        {
            pThread = &pPool->pEventThreads[ulIndex];
            ulMinLoad = pThread->ulLoad;
        }
    }

    pTask->pThread = pThread;

    if (pGroup)
    {
        LOCK_GROUP(pGroup);
        if (pGroup->bCancelled)
        {
            UNLOCK_GROUP(pGroup);
            UNLOCK_POOL(pPool);
            status = STATUS_CANCELLED;
            GOTO_ERROR_ON_STATUS(status);
        }
        RingInsertBefore(&pGroup->Tasks, &pTask->GroupRing);
        UNLOCK_GROUP(pGroup);
    }

    pThread->ulLoad++;

    UNLOCK_POOL(pPool);

    *ppTask = pTask;

cleanup:

    return status;

error:

    if (pTask)
    {
        TaskDelete(pTask);
    }

    *ppTask = NULL;

    goto cleanup;
}
Esempio n. 11
0
NTSTATUS
LwRtlCreateThreadPool(
    PLW_THREAD_POOL* ppPool,
    PLW_THREAD_POOL_ATTRIBUTES pAttrs
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PLW_THREAD_POOL pPool = NULL;
    int i = 0;
    int numCpus = 0;

    status = LW_RTL_ALLOCATE_AUTO(&pPool);
    GOTO_ERROR_ON_STATUS(status);

    status = LwErrnoToNtStatus(pthread_mutex_init(&pPool->Lock, NULL));
    GOTO_ERROR_ON_STATUS(status);

    status = LwErrnoToNtStatus(pthread_cond_init(&pPool->Event, NULL));
    GOTO_ERROR_ON_STATUS(status);

    numCpus = LwRtlGetCpuCount();

    if (GetDelegateAttr(pAttrs))
    {
        status = AcquireDelegatePool(&pPool->pDelegate);
        GOTO_ERROR_ON_STATUS(status);
    }
    else
    {
        pPool->ulEventThreadCount = GetTaskThreadsAttr(pAttrs, numCpus);

        if (pPool->ulEventThreadCount)
        {
            status = LW_RTL_ALLOCATE_ARRAY_AUTO(
                &pPool->pEventThreads,
                pPool->ulEventThreadCount);
            GOTO_ERROR_ON_STATUS(status);

            for (i = 0; i < pPool->ulEventThreadCount; i++)
            {
                status = InitEventThread(pPool, pAttrs, &pPool->pEventThreads[i], i % numCpus);
                GOTO_ERROR_ON_STATUS(status);
            }
        }
    }

    status = InitWorkThreads(&pPool->WorkThreads, pAttrs, numCpus);
    GOTO_ERROR_ON_STATUS(status);

    *ppPool = pPool;

cleanup:

    return status;

error:

    LwRtlFreeThreadPool(&pPool);

    goto cleanup;
}
Esempio n. 12
0
NTSTATUS
LwRtlCreateTask(
    PLW_THREAD_POOL pPool,
    PLW_TASK* ppTask,
    PLW_TASK_GROUP pGroup,
    LW_TASK_FUNCTION pfnFunc,
    PVOID pContext
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PSELECT_TASK pTask = NULL;

    if (pPool->pDelegate)
    {
        return LwRtlCreateTask(pPool->pDelegate, ppTask, pGroup, pfnFunc, pContext);
    }

    GOTO_ERROR_ON_STATUS(status = LW_RTL_ALLOCATE_AUTO(&pTask));

    RingInit(&pTask->GroupRing);
    RingInit(&pTask->EventRing);
    pTask->pPool = pPool;
    pTask->pGroup = pGroup;
    pTask->ulRefCount = 2;
    pTask->pfnFunc = pfnFunc;
    pTask->pFuncContext = pContext;
    pTask->Fd = -1;
    pTask->TriggerSet = LW_TASK_EVENT_INIT;
    pTask->TriggerWait = LW_TASK_EVENT_EXPLICIT;
    pTask->llDeadline = 0;

    LOCK_POOL(pPool);
    if (pGroup)
    {
        LOCK_GROUP(pGroup);
        if (pGroup->bCancelled)
        {
            UNLOCK_GROUP(pGroup);
            UNLOCK_POOL(pPool);
            status = STATUS_CANCELLED;
            GOTO_ERROR_ON_STATUS(status);
        }
        RingInsertBefore(&pGroup->Tasks, &pTask->GroupRing);
    }

    pTask->pThread = &pPool->pEventThreads[pPool->ulNextEventThread];
    pPool->ulNextEventThread = (pPool->ulNextEventThread + 1) % pPool->ulEventThreadCount;
    UNLOCK_POOL(pPool);

    LOCK_THREAD(pTask->pThread);
    RingInsertBefore(&pTask->pThread->Tasks, &pTask->EventRing);
    /* It's not necessary to signal the thread about the new task here
       since it won't be run anyway */
    UNLOCK_THREAD(pTask->pThread);

    if (pGroup)
    {
        UNLOCK_GROUP(pGroup);
    }

    *ppTask = pTask;

error:

    return status;
}
Esempio n. 13
0
NTSTATUS
LwRtlCreateThreadPool(
    PLW_THREAD_POOL* ppPool,
    PLW_THREAD_POOL_ATTRIBUTES pAttrs
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PLW_THREAD_POOL pPool = NULL;
    int i = 0;
    int numCpus = 0;
    ULONG ulFdLimit = 0;

#if defined(_SC_NPROCESSORS_ONLN)
    numCpus = sysconf(_SC_NPROCESSORS_ONLN);

    if (numCpus < 0)
    {
        numCpus = 1;
    }
#else
    numCpus = 1;
#endif
   

    GOTO_ERROR_ON_STATUS(status = LW_RTL_ALLOCATE_AUTO(&pPool));
    
    GOTO_ERROR_ON_STATUS(status = LwErrnoToNtStatus(pthread_mutex_init(&pPool->Lock, NULL)));
    GOTO_ERROR_ON_STATUS(status = LwErrnoToNtStatus(pthread_cond_init(&pPool->Event, NULL)));

    if (GetDelegateAttr(pAttrs))
    {
        status = AcquireDelegatePool(&pPool->pDelegate);
        GOTO_ERROR_ON_STATUS(status);
    }
    else
    {
        pPool->ulEventThreadCount = GetTaskThreadsAttr(pAttrs, numCpus);
        pPool->ulNextEventThread = 0;

        status = GetFdLimit(&ulFdLimit);
        GOTO_ERROR_ON_STATUS(status);

        /*
         * Each thread needs 2 fds for the notification pipe.
         * This check will limit us to 1/4 of the process fd limit.
         * This is particularly important on Solaris which has a very
         * low default limit of 256.
         */
        if (pPool->ulEventThreadCount > ulFdLimit / 8)
        {
            pPool->ulEventThreadCount = ulFdLimit / 8;
        }

        if (pPool->ulEventThreadCount)
        {
            GOTO_ERROR_ON_STATUS(status = LW_RTL_ALLOCATE_ARRAY_AUTO(
                                     &pPool->pEventThreads,
                                     pPool->ulEventThreadCount));
            for (i = 0; i < pPool->ulEventThreadCount; i++)
            {
                GOTO_ERROR_ON_STATUS(status = SelectThreadInit(pAttrs, &pPool->pEventThreads[i]));
            }
        }
    }

    status = InitWorkThreads(&pPool->WorkThreads, pAttrs, numCpus);
    GOTO_ERROR_ON_STATUS(status);

    *ppPool = pPool;

error:

    return status;
}
Esempio n. 14
0
LW_NTSTATUS
LwRtlSvcmStart(
    LW_IN PLW_SVCM_INSTANCE pInstance,
    LW_IN LW_ULONG ArgCount,
    LW_IN LW_PWSTR* ppArgs,
    LW_IN LW_ULONG FdCount,
    LW_IN int* pFds,
    LW_IN LW_SVCM_NOTIFY_FUNCTION Notify,
    LW_IN LW_PVOID pContext
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PSVCM_START_STATE pStartState = NULL;
    PLW_WORK_ITEM pStartItem = NULL;

    if (!pInstance)
    {
        status = STATUS_INVALID_PARAMETER;
        GCOS(status);
    }

    status = LW_RTL_ALLOCATE_AUTO(&pStartState);
    GCOS(status);

    status = LW_RTL_ALLOCATE_AUTO(&pInstance->pStopState);
    GCOS(status);

    status = LwRtlCreateWorkItem(
        gSvcmState.pPool,
        &pStartItem,
        StartWorkItem,
        pStartState);
    GCOS(status);

    status = LwRtlCreateWorkItem(
        gSvcmState.pPool,
        &pInstance->pStopItem,
        StopWorkItem,
        pInstance->pStopState);
    GCOS(status);

    pStartState->pInstance = pInstance;
    pStartState->ArgCount = ArgCount;
    pStartState->ppArgs = ppArgs;
    pStartState->FdCount = FdCount;
    pStartState->pFds = pFds;
    pStartState->Notify = Notify;
    pStartState->pNotifyContext = pContext;

    LwRtlScheduleWorkItem(pStartItem, 0);
    pStartItem = NULL;
    pStartState = NULL;

cleanup:

    LwRtlFreeWorkItem(&pStartItem);
    RTL_FREE(&pStartState);

    if (status != STATUS_SUCCESS)
    {
        RTL_FREE(&pInstance->pStopState);
        LwRtlFreeWorkItem(&pInstance->pStopItem);
    }

    return status;
}
Esempio n. 15
0
NTSTATUS
RegisterTaskUnixSignal(
    LW_IN PLW_TASK pTask,
    LW_IN int Sig,
    LW_IN LW_BOOLEAN bSubscribe
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    size_t i = 0;
    PRING pBase = NULL;
    PRING pRing = NULL;
    PLW_SIGNAL_SUBSCRIPTION pExisting = NULL;
    PLW_SIGNAL_SUBSCRIPTION pSub = NULL;
    struct sigaction action;
#ifdef SIGRTMAX
    int maxSig = SIGRTMAX;
#else
    int maxSig = SIGUSR2;
#endif

    if (Sig == 0)
    {
        for (i = 1; i < maxSig + 1; i++)
        {
            status = RegisterTaskUnixSignal(pTask, (int) i, bSubscribe);
            if (status)
            {
                return status;
            }
        }

        return STATUS_SUCCESS;
    }

    LOCK_SIGNAL();

    if (Sig > maxSig || Sig < 0)
    {
        status = STATUS_INVALID_PARAMETER;
        GOTO_ERROR_ON_STATUS(status);
    }

    if (!gSignal.pSubscribers)
    {
        status = LW_RTL_ALLOCATE_ARRAY_AUTO(&gSignal.pSubscribers, maxSig + 1);
        GOTO_ERROR_ON_STATUS(status);

        for (i = 0; i < maxSig + 1; i++)
        {
            RingInit(&gSignal.pSubscribers[i]);
        }
        
        gSignal.maxSig = maxSig;
    }

    pBase = &gSignal.pSubscribers[Sig];
    for (pRing = pBase->pNext; pRing != pBase; pRing = pRing->pNext)
    {
        pSub = LW_STRUCT_FROM_FIELD(pRing, LW_SIGNAL_SUBSCRIPTION, Ring);
        if (pSub->pTask == pTask)
        {
            pExisting = pSub;
            break;
        }
    }

    if (bSubscribe && !pExisting)
    {
        if (Sig != SIGINT)
        {
            memset(&action, 0, sizeof(action));
            
            /* Make sure there is a dummy handler for the signal
               so it is actually delivered to the process */
            action.sa_handler = DummyHandler;
            action.sa_flags = 0;
            
            if (sigaction(Sig, &action, NULL) < 0)
            {
                status = LwErrnoToNtStatus(errno);
                GOTO_ERROR_ON_STATUS(status);
            }
        }

        status = LW_RTL_ALLOCATE_AUTO(&pSub);
        GOTO_ERROR_ON_STATUS(status);

        pSub->pTask = pTask;
        pSub->ucRefCount = 1;
        RingInit(&pSub->Ring);
        RingInit(&pSub->DispatchRing);

        RingEnqueue(pBase, &pSub->Ring);

        RetainTask(pTask);
    }
    else if (!bSubscribe && pExisting)
    {
        RingRemove(&pExisting->Ring);

        if (--pExisting->ucRefCount == 0)
        {
            LwRtlReleaseTask(&pExisting->pTask);
            LwRtlMemoryFree(pExisting);
        }
    }

error:

    UNLOCK_SIGNAL();

    return status;
}
Esempio n. 16
0
LW_NTSTATUS
LwRtlSvcmLoadModule(
    LW_IN LW_PCWSTR pServiceName,
    LW_IN LW_PCWSTR pModulePath,
    LW_OUT PLW_SVCM_INSTANCE* ppInstance
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PLW_SVCM_INSTANCE pInstance = NULL;
    PSTR pModulePathA = NULL;
    LW_SVCM_MODULE_ENTRY_FUNCTION Entry = NULL;
    PSTR pEntryName = NULL;
    PSTR pBareName = NULL;
    PSTR pFinalSlash = NULL;
    PSTR pFinalDot = NULL;

    status = InitPool();
    GCOS(status);

    status = LwRtlCStringAllocateFromWC16String(&pModulePathA, pModulePath);
    GCOS(status);

    pFinalSlash = strrchr(pModulePathA, '/');
    pFinalDot = strrchr(pModulePathA, '.');

    if (!pFinalSlash)
    {
        pFinalSlash = pModulePathA;
    }
    else
    {
        pFinalSlash++;
    }

    if (!pFinalDot)
    {
        pFinalDot = pModulePathA + strlen(pModulePathA);
    }

    status = LW_RTL_ALLOCATE(&pBareName, CHAR, (pFinalDot - pFinalSlash) + 1);
    GCOS(status);

    memcpy(pBareName, pFinalSlash, pFinalDot - pFinalSlash);

    status = LwRtlCStringAllocatePrintf(&pEntryName, "_LwSvcmEntry_%s", pBareName);
    GCOS(status);

    status = LW_RTL_ALLOCATE_AUTO(&pInstance);
    GCOS(status);

    LW_RTL_LOG_DEBUG("Loading service module: %s", pModulePathA);

    (void) dlerror();
    pInstance->pDlHandle = dlopen(pModulePathA, RTLD_LOCAL | RTLD_NOW);

    if (!pInstance->pDlHandle)
    {
        LW_RTL_LOG_ERROR(
            "Could not load service module '%s': %s",
            pModulePathA,
            dlerror());

        status = LwErrnoToNtStatus(errno);
        GCOS(status);
    }

    (void) dlerror();
    Entry = dlsym(pInstance->pDlHandle, pEntryName);

    if (!Entry)
    {
        LW_RTL_LOG_ERROR(
            "Could not load entry point from service module '%s': %s",
            pModulePathA,
            dlerror());

        status = LwErrnoToNtStatus(errno);
        if (!status)
        {
            status = STATUS_BAD_DLL_ENTRYPOINT;
        }
        GCOS(status);
    }

    status = LwRtlSvcmInitializeInstance(pInstance, pServiceName, pModulePathA, Entry);
    GCOS(status);

cleanup:

    RTL_FREE(&pModulePathA);
    RTL_FREE(&pBareName);
    RTL_FREE(&pEntryName);

    if (!NT_SUCCESS(status))
    {
        LwRtlSvcmUnload(pInstance);
        pInstance = NULL;
    }

    *ppInstance = pInstance;

    return status;
}
Esempio n. 17
0
static
NTSTATUS
CreateSocketPair(
    PLW_TASK_GROUP pGroup,
    PSOCKET* ppSocket1,
    PSOCKET* ppSocket2
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PSOCKET pSocket1 = NULL;
    PSOCKET pSocket2 = NULL;
    int socketFds[2] = {-1, -1};

    status = LW_RTL_ALLOCATE_AUTO(&pSocket1);
    GOTO_ERROR_ON_STATUS(status);

    status = LW_RTL_ALLOCATE_AUTO(&pSocket2);
    GOTO_ERROR_ON_STATUS(status);

    status = LW_RTL_ALLOCATE_ARRAY_AUTO(&pSocket1->pBuffer, gpSettings->ulBufferSize);
    GOTO_ERROR_ON_STATUS(status);

    status = LW_RTL_ALLOCATE_ARRAY_AUTO(&pSocket2->pBuffer, gpSettings->ulBufferSize);
    GOTO_ERROR_ON_STATUS(status);

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, socketFds) < 0)
    {
        status = LwErrnoToNtStatus(errno);
        GOTO_ERROR_ON_STATUS(status);
    }

    pSocket1->Fd = socketFds[0];
    pSocket2->Fd = socketFds[1];
    
    pSocket1->State = STATE_SEND;
    pSocket2->State = STATE_RECV;

    status = LwRtlCreateTask(
        gpPool,
        &pSocket1->pTask,
        pGroup,
        Transceiver,
        pSocket1);
    GOTO_ERROR_ON_STATUS(status);

    status = LwRtlCreateTask(
        gpPool,
        &pSocket2->pTask,
        pGroup,
        Transceiver,
        pSocket2);
    GOTO_ERROR_ON_STATUS(status);

    *ppSocket1 = pSocket1;
    *ppSocket2 = pSocket2;

cleanup:
    
    return status;

error:

    goto cleanup;
}