예제 #1
0
파일: fiber.c 프로젝트: farp90/nativecmd
/*
 * @implemented
 */
LPVOID
WINAPI
CreateFiberEx(SIZE_T dwStackCommitSize,
              SIZE_T dwStackReserveSize,
              DWORD dwFlags,
              LPFIBER_START_ROUTINE lpStartAddress,
              LPVOID lpParameter)
{
    PFIBER pfCurFiber;
    NTSTATUS nErrCode;
    INITIAL_TEB usFiberInitialTeb;
    PVOID ActivationContextStack = NULL;
    DPRINT("Creating Fiber\n");

#ifdef SXS_SUPPORT_ENABLED
    /* Allocate the Activation Context Stack */
    nErrCode = RtlAllocateActivationContextStack(&ActivationContextStack);
#endif

    /* Allocate the fiber */
    pfCurFiber = (PFIBER)RtlAllocateHeap(GetProcessHeap(),
                                         0,
                                         sizeof(FIBER));
    /* Failure */
    if (pfCurFiber == NULL)
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return NULL;
    }

    /* Create the stack for the fiber */
    nErrCode = BasepCreateStack(NtCurrentProcess(),
                                dwStackCommitSize,
                                dwStackReserveSize,
                                &usFiberInitialTeb);
    /* Failure */
    if(!NT_SUCCESS(nErrCode))
    {
        /* Free the fiber */
        RtlFreeHeap(GetProcessHeap(), 0, pfCurFiber);

        /* Failure */
        SetLastErrorByStatus(nErrCode);
        return NULL;
    }

    /* Clear the context */
    RtlZeroMemory(&pfCurFiber->Context, sizeof(CONTEXT));

    /* copy the data into the fiber */
    pfCurFiber->StackBase = usFiberInitialTeb.StackBase;
    pfCurFiber->StackLimit = usFiberInitialTeb.StackLimit;
    pfCurFiber->DeallocationStack = usFiberInitialTeb.AllocatedStackBase;
    pfCurFiber->Parameter = lpParameter;
    pfCurFiber->ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)-1;
    pfCurFiber->GuaranteedStackBytes = 0;
    pfCurFiber->FlsData = NULL;
    pfCurFiber->ActivationContextStack = ActivationContextStack;
    pfCurFiber->Context.ContextFlags = CONTEXT_FULL;

    /* Save FPU State if requsted */
    if (dwFlags & FIBER_FLAG_FLOAT_SWITCH)
    {
        pfCurFiber->Context.ContextFlags |= CONTEXT_FLOATING_POINT;
    }

    /* initialize the context for the fiber */
    BasepInitializeContext(&pfCurFiber->Context,
                           lpParameter,
                           lpStartAddress,
                           usFiberInitialTeb.StackBase,
                           2);

    /* Return the Fiber */
    return pfCurFiber;
}
예제 #2
0
/*
 * @implemented
 */
LPVOID
WINAPI
CreateFiberEx(SIZE_T dwStackCommitSize,
              SIZE_T dwStackReserveSize,
              DWORD dwFlags,
              LPFIBER_START_ROUTINE lpStartAddress,
              LPVOID lpParameter)
{
    PFIBER Fiber;
    NTSTATUS Status;
    INITIAL_TEB InitialTeb;
    PVOID ActivationContextStack = NULL;
    DPRINT("Creating Fiber\n");

    /* Check for invalid flags */
    if (dwFlags &~ FIBER_FLAG_FLOAT_SWITCH)
    {
        /* Fail */
        SetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }

    /* Allocate the Activation Context Stack */
    Status = RtlAllocateActivationContextStack(&ActivationContextStack);
    if (!NT_SUCCESS(Status))
    {
        /* Fail */
        BaseSetLastNTError(Status);
        return NULL;
    }

    /* Allocate the fiber */
    Fiber = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(FIBER));
    if (!Fiber)
    {
        /* Fail */
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return NULL;
    }

    /* Create the stack for the fiber */
    Status = BasepCreateStack(NtCurrentProcess(),
                              dwStackCommitSize,
                              dwStackReserveSize,
                              &InitialTeb);
    if (!NT_SUCCESS(Status))
    {
        /* Free the fiber */
        RtlFreeHeap(GetProcessHeap(), 0, Fiber);

        /* Free the activation context */
        DPRINT1("Leaking activation stack because nobody implemented free");
        //RtlFreeActivationContextStack(&ActivationContextStack);

        /* Failure */
        BaseSetLastNTError(Status);
        return NULL;
    }

    /* Clear the context */
    RtlZeroMemory(&Fiber->Context, sizeof(CONTEXT));

    /* Copy the data into the fiber */
    Fiber->StackBase = InitialTeb.StackBase;
    Fiber->StackLimit = InitialTeb.StackLimit;
    Fiber->DeallocationStack = InitialTeb.AllocatedStackBase;
    Fiber->Parameter = lpParameter;
    Fiber->ExceptionList = EXCEPTION_CHAIN_END;
    Fiber->GuaranteedStackBytes = 0;
    Fiber->FlsData = NULL;
    Fiber->ActivationContextStack = ActivationContextStack;
    Fiber->Context.ContextFlags = CONTEXT_FULL;

    /* Save FPU State if requested */
    Fiber->Context.ContextFlags = (dwFlags & FIBER_FLAG_FLOAT_SWITCH) ? CONTEXT_FLOATING_POINT : 0;

    /* initialize the context for the fiber */
    BasepInitializeContext(&Fiber->Context,
                           lpParameter,
                           lpStartAddress,
                           InitialTeb.StackBase,
                           2);

    /* Return the Fiber */
    return Fiber;
}