/* * @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; }
/* * @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; }