static inline void HandleListInsertBefore(struct PVRSRV_HANDLE_BASE *psBase, u32 ui32InsIndex, struct sHandleList *psIns, size_t uiParentOffset, u32 ui32EntryIndex, struct sHandleList *psEntry, size_t uiEntryOffset, u32 ui32ParentIndex) { struct sHandleList *psPrevIns = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psIns->ui32Prev, ui32ParentIndex, uiParentOffset, uiEntryOffset); PVR_ASSERT(psEntry->hParent == NULL); PVR_ASSERT(ui32InsIndex == psPrevIns->ui32Next); PVR_ASSERT(LIST_PTR_FROM_INDEX_AND_OFFSET (psBase, ui32ParentIndex, ui32ParentIndex, uiParentOffset, uiParentOffset)->hParent == INDEX_TO_HANDLE(psBase, ui32ParentIndex)); psEntry->ui32Prev = psIns->ui32Prev; psIns->ui32Prev = ui32EntryIndex; psEntry->ui32Next = ui32InsIndex; psPrevIns->ui32Next = ui32EntryIndex; psEntry->hParent = INDEX_TO_HANDLE(psBase, ui32ParentIndex); }
static INLINE IMG_VOID InitParentList(PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle) { IMG_UINT32 ui32Parent = HANDLE_PTR_TO_INDEX(psBase, psHandle); HandleListInit(ui32Parent, &psHandle->sChildren, INDEX_TO_HANDLE(psBase, ui32Parent)); }
static inline void InitParentList(struct PVRSRV_HANDLE_BASE *psBase, struct sHandle *psHandle) { u32 ui32Parent = HANDLE_PTR_TO_INDEX(psBase, psHandle); HandleListInit(ui32Parent, &psHandle->sChildren, INDEX_TO_HANDLE(psBase, ui32Parent)); }
static int nbd_co_send_request(BlockDriverState *bs, struct nbd_request *request, QEMUIOVector *qiov, int offset) { NbdClientSession *s = nbd_get_client_session(bs); AioContext *aio_context; int rc, ret, i; qemu_co_mutex_lock(&s->send_mutex); for (i = 0; i < MAX_NBD_REQUESTS; i++) { if (s->recv_coroutine[i] == NULL) { s->recv_coroutine[i] = qemu_coroutine_self(); break; } } g_assert(qemu_in_coroutine()); assert(i < MAX_NBD_REQUESTS); request->handle = INDEX_TO_HANDLE(s, i); if (!s->ioc) { qemu_co_mutex_unlock(&s->send_mutex); return -EPIPE; } s->send_coroutine = qemu_coroutine_self(); aio_context = bdrv_get_aio_context(bs); aio_set_fd_handler(aio_context, s->sioc->fd, false, nbd_reply_ready, nbd_restart_write, bs); if (qiov) { qio_channel_set_cork(s->ioc, true); rc = nbd_send_request(s->ioc, request); if (rc >= 0) { ret = nbd_wr_syncv(s->ioc, qiov->iov, qiov->niov, offset, request->len, 0); if (ret != request->len) { rc = -EIO; } } qio_channel_set_cork(s->ioc, false); } else { rc = nbd_send_request(s->ioc, request); } aio_set_fd_handler(aio_context, s->sioc->fd, false, nbd_reply_ready, NULL, bs); s->send_coroutine = NULL; qemu_co_mutex_unlock(&s->send_mutex); return rc; }
static int nbd_co_send_request(BlockDriverState *bs, struct nbd_request *request, QEMUIOVector *qiov, int offset) { NbdClientSession *s = nbd_get_client_session(bs); AioContext *aio_context; int rc, ret, i; qemu_co_mutex_lock(&s->send_mutex); for (i = 0; i < MAX_NBD_REQUESTS; i++) { if (s->recv_coroutine[i] == NULL) { s->recv_coroutine[i] = qemu_coroutine_self(); break; } } assert(i < MAX_NBD_REQUESTS); request->handle = INDEX_TO_HANDLE(s, i); s->send_coroutine = qemu_coroutine_self(); aio_context = bdrv_get_aio_context(bs); aio_set_fd_handler(aio_context, s->sock, AIO_CLIENT_PROTOCOL, nbd_reply_ready, nbd_restart_write, bs); if (qiov) { if (!s->is_unix) { socket_set_cork(s->sock, 1); } rc = nbd_send_request(s->sock, request); if (rc >= 0) { ret = qemu_co_sendv(s->sock, qiov->iov, qiov->niov, offset, request->len); if (ret != request->len) { rc = -EIO; } } if (!s->is_unix) { socket_set_cork(s->sock, 0); } } else { rc = nbd_send_request(s->sock, request); } aio_set_fd_handler(aio_context, s->sock, AIO_CLIENT_PROTOCOL, nbd_reply_ready, NULL, bs); s->send_coroutine = NULL; qemu_co_mutex_unlock(&s->send_mutex); return rc; }
static INLINE IMG_VOID HandleListInsertBefore(PVRSRV_HANDLE_BASE *psBase, IMG_UINT32 ui32InsIndex, struct sHandleList *psIns, IMG_SIZE_T uiParentOffset, IMG_UINT32 ui32EntryIndex, struct sHandleList *psEntry, IMG_SIZE_T uiEntryOffset, IMG_UINT32 ui32ParentIndex) { struct sHandleList *psPrevIns = LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, psIns->ui32Prev, ui32ParentIndex, uiParentOffset, uiEntryOffset); PVR_ASSERT(psEntry->hParent == IMG_NULL); PVR_ASSERT(ui32InsIndex == psPrevIns->ui32Next); PVR_ASSERT(LIST_PTR_FROM_INDEX_AND_OFFSET(psBase, ui32ParentIndex, ui32ParentIndex, uiParentOffset, uiParentOffset)->hParent == INDEX_TO_HANDLE(psBase, ui32ParentIndex)); psEntry->ui32Prev = psIns->ui32Prev; psIns->ui32Prev = ui32EntryIndex; psEntry->ui32Next = ui32InsIndex; psPrevIns->ui32Next = ui32EntryIndex; psEntry->hParent = INDEX_TO_HANDLE(psBase, ui32ParentIndex); }
static int nbd_co_send_request(BlockDriverState *bs, NBDRequest *request, QEMUIOVector *qiov) { NBDClientSession *s = nbd_get_client_session(bs); int rc, ret, i; qemu_co_mutex_lock(&s->send_mutex); while (s->in_flight == MAX_NBD_REQUESTS) { qemu_co_queue_wait(&s->free_sema, &s->send_mutex); } s->in_flight++; for (i = 0; i < MAX_NBD_REQUESTS; i++) { if (s->recv_coroutine[i] == NULL) { s->recv_coroutine[i] = qemu_coroutine_self(); break; } } g_assert(qemu_in_coroutine()); assert(i < MAX_NBD_REQUESTS); request->handle = INDEX_TO_HANDLE(s, i); if (!s->ioc) { qemu_co_mutex_unlock(&s->send_mutex); return -EPIPE; } if (qiov) { qio_channel_set_cork(s->ioc, true); rc = nbd_send_request(s->ioc, request); if (rc >= 0) { ret = nbd_rwv(s->ioc, qiov->iov, qiov->niov, request->len, false, NULL); if (ret != request->len) { rc = -EIO; } } qio_channel_set_cork(s->ioc, false); } else { rc = nbd_send_request(s->ioc, request); } qemu_co_mutex_unlock(&s->send_mutex); return rc; }
static void nbd_coroutine_start(BDRVNBDState *s, struct nbd_request *request) { int i; /* Poor man semaphore. The free_sema is locked when no other request * can be accepted, and unlocked after receiving one reply. */ if (s->in_flight >= MAX_NBD_REQUESTS - 1) { qemu_co_mutex_lock(&s->free_sema); assert(s->in_flight < MAX_NBD_REQUESTS); } s->in_flight++; for (i = 0; i < MAX_NBD_REQUESTS; i++) { if (s->recv_coroutine[i] == NULL) { s->recv_coroutine[i] = qemu_coroutine_self(); break; } } assert(i < MAX_NBD_REQUESTS); request->handle = INDEX_TO_HANDLE(s, i); }
static int nbd_co_send_request(BlockDriverState *bs, NBDRequest *request, QEMUIOVector *qiov) { NBDClientSession *s = nbd_get_client_session(bs); int rc, i; qemu_co_mutex_lock(&s->send_mutex); while (s->in_flight == MAX_NBD_REQUESTS) { qemu_co_queue_wait(&s->free_sema, &s->send_mutex); } s->in_flight++; for (i = 0; i < MAX_NBD_REQUESTS; i++) { if (s->requests[i].coroutine == NULL) { break; } } g_assert(qemu_in_coroutine()); assert(i < MAX_NBD_REQUESTS); s->requests[i].coroutine = qemu_coroutine_self(); s->requests[i].receiving = false; request->handle = INDEX_TO_HANDLE(s, i); if (s->quit) { rc = -EIO; goto err; } if (!s->ioc) { rc = -EPIPE; goto err; } if (qiov) { qio_channel_set_cork(s->ioc, true); rc = nbd_send_request(s->ioc, request); if (rc >= 0 && !s->quit) { assert(request->len == iov_size(qiov->iov, qiov->niov)); if (qio_channel_writev_all(s->ioc, qiov->iov, qiov->niov, NULL) < 0) { rc = -EIO; } } qio_channel_set_cork(s->ioc, false); } else { rc = nbd_send_request(s->ioc, request); } err: if (rc < 0) { s->quit = true; s->requests[i].coroutine = NULL; s->in_flight--; qemu_co_queue_next(&s->free_sema); } qemu_co_mutex_unlock(&s->send_mutex); return rc; }
/*! ****************************************************************************** @Function AcquireHandle @Description Acquire a new handle @Input psBase - Pointer to handle base structure phHandle - Points to a handle pointer pvData - Pointer to resource to be associated with the handle @Output phHandle - Points to a handle pointer @Return Error code or PVRSRV_OK ******************************************************************************/ static PVRSRV_ERROR AcquireHandle(HANDLE_IMPL_BASE *psBase, IMG_HANDLE *phHandle, IMG_VOID *pvData) { IMG_UINT32 ui32NewIndex = BASE_TO_TOTAL_INDICES(psBase); HANDLE_IMPL_DATA *psNewHandleData = IMG_NULL; PVRSRV_ERROR eError; PVR_ASSERT(psBase != IMG_NULL); PVR_ASSERT(phHandle != IMG_NULL); PVR_ASSERT(pvData != IMG_NULL); /* Ensure there is a free handle */ eError = EnsureFreeHandles(psBase, 1); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "%s: EnsureFreeHandles failed (%s)", __FUNCTION__, PVRSRVGetErrorStringKM(eError))); return eError; } PVR_ASSERT(psBase->ui32TotalFreeHandCount != 0); if (!psBase->bPurgingEnabled) { /* Array index of first free handle */ ui32NewIndex = psBase->ui32FirstFreeIndex; /* Get handle array entry */ psNewHandleData = INDEX_TO_HANDLE_DATA(psBase, ui32NewIndex); } else { IMG_UINT32 ui32BlockedIndex; /* * If purging is enabled, we always try to allocate handles * at the front of the array, to increase the chances that * the size of the handle array can be reduced by a purge. * No linked list of free handles is kept; we search for * free handles as required. */ /* * ui32FirstFreeIndex should only be set when a new batch of * handle structures is allocated, and should always be a * multiple of the block size. */ PVR_ASSERT((psBase->ui32FirstFreeIndex % HANDLE_BLOCK_SIZE) == 0); for (ui32BlockedIndex = ROUND_DOWN_TO_MULTIPLE_OF_BLOCK_SIZE(psBase->ui32FirstFreeIndex); ui32BlockedIndex < psBase->ui32TotalHandCount; ui32BlockedIndex += HANDLE_BLOCK_SIZE) { HANDLE_BLOCK *psHandleBlock = BASE_AND_INDEX_TO_HANDLE_BLOCK(psBase, ui32BlockedIndex); if (psHandleBlock->ui32FreeHandCount == 0) { continue; } for (ui32NewIndex = ui32BlockedIndex; ui32NewIndex < ui32BlockedIndex + HANDLE_BLOCK_SIZE; ui32NewIndex++) { psNewHandleData = INDEX_TO_HANDLE_DATA(psBase, ui32NewIndex); if (psNewHandleData->pvData == IMG_NULL) { break; } } } psBase->ui32FirstFreeIndex = 0; PVR_ASSERT(INDEX_IS_VALID(psBase, ui32NewIndex)); } PVR_ASSERT(psNewHandleData != IMG_NULL); psBase->ui32TotalFreeHandCount--; PVR_ASSERT(INDEX_TO_BLOCK_FREE_HAND_COUNT(psBase, ui32NewIndex) <= HANDLE_BLOCK_SIZE); PVR_ASSERT(INDEX_TO_BLOCK_FREE_HAND_COUNT(psBase, ui32NewIndex) > 0); INDEX_TO_BLOCK_FREE_HAND_COUNT(psBase, ui32NewIndex)--; /* No free list management if purging is enabled */ if (!psBase->bPurgingEnabled) { /* Check whether the last free handle has been allocated */ if (psBase->ui32TotalFreeHandCount == 0) { PVR_ASSERT(psBase->ui32FirstFreeIndex == ui32NewIndex); PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == (ui32NewIndex + 1)); psBase->ui32LastFreeIndexPlusOne = 0; psBase->ui32FirstFreeIndex = 0; } else { /* * Update the first free handle index. * If the "next free index plus one" field in the new * handle structure is zero, the next free index is * the index of the new handle plus one. This * convention has been adopted to simplify the * initialisation of freshly allocated handle * space. */ if (psNewHandleData->ui32NextIndexPlusOne == 0) { psBase->ui32FirstFreeIndex = ui32NewIndex + 1; } else { psBase->ui32FirstFreeIndex = psNewHandleData->ui32NextIndexPlusOne - 1; } } } PVR_ASSERT(HANDLE_DATA_TO_HANDLE(psNewHandleData) == INDEX_TO_HANDLE(ui32NewIndex)); psNewHandleData->pvData = pvData; psNewHandleData->ui32NextIndexPlusOne = 0; /* Return the new handle to the client */ *phHandle = INDEX_TO_HANDLE(ui32NewIndex); #if defined(DEBUG_HANDLEALLOC_KM) PVR_DPF((PVR_DBG_MESSAGE, "Handle acquire base %p hdl %p", psBase, *phHandle)); #endif return PVRSRV_OK; }
/*! ****************************************************************************** @Function ReallocHandleBlockArray @Description Reallocate the handle block array @Input psBase - Pointer to handle base structure ui32NewCount - The new total number of handles @Return Error code or PVRSRV_OK ******************************************************************************/ static PVRSRV_ERROR ReallocHandleBlockArray(HANDLE_IMPL_BASE *psBase, IMG_UINT32 ui32NewCount) { HANDLE_BLOCK *psOldArray = psBase->psHandleBlockArray; IMG_UINT32 ui32OldCount = psBase->ui32TotalHandCount; HANDLE_BLOCK *psNewArray = IMG_NULL; PVRSRV_ERROR eError = PVRSRV_OK; IMG_UINT32 ui32Index; if (ui32NewCount == ui32OldCount) { return PVRSRV_OK; } if (ui32NewCount != 0 && !psBase->bPurgingEnabled && ui32NewCount < ui32OldCount) { return PVRSRV_ERROR_INVALID_PARAMS; } if (((ui32OldCount % HANDLE_BLOCK_SIZE) != 0) || ((ui32NewCount % HANDLE_BLOCK_SIZE) != 0)) { PVR_ASSERT((ui32OldCount % HANDLE_BLOCK_SIZE) == 0); PVR_ASSERT((ui32NewCount % HANDLE_BLOCK_SIZE) == 0); return PVRSRV_ERROR_INVALID_PARAMS; } if (ui32NewCount != 0) { /* Allocate new handle array */ psNewArray = OSAllocMem(HANDLE_BLOCK_ARRAY_SIZE(ui32NewCount) * sizeof(HANDLE_BLOCK)); if (psNewArray == IMG_NULL) { PVR_DPF((PVR_DBG_ERROR, "%s: Couldn't allocate new handle array", __FUNCTION__)); eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto error; } if (ui32OldCount != 0) { OSMemCopy(psNewArray, psOldArray, HANDLE_BLOCK_ARRAY_SIZE(MIN(ui32NewCount, ui32OldCount)) * sizeof(HANDLE_BLOCK)); } } /* * If the new handle array is smaller than the old one, free * unused handle data structure arrays */ for (ui32Index = ui32NewCount; ui32Index < ui32OldCount; ui32Index += HANDLE_BLOCK_SIZE) { HANDLE_BLOCK *psHandleBlock = BLOCK_ARRAY_AND_INDEX_TO_HANDLE_BLOCK(psOldArray, ui32Index); OSFreeMem(psHandleBlock->psHandleDataArray); } /* * If the new handle array is bigger than the old one, allocate * new handle data structure arrays */ for (ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE) { /* PRQA S 0505 1 */ /* psNewArray is never NULL, see assert earlier */ HANDLE_BLOCK *psHandleBlock = BLOCK_ARRAY_AND_INDEX_TO_HANDLE_BLOCK(psNewArray, ui32Index); psHandleBlock->psHandleDataArray = OSAllocMem(sizeof(HANDLE_IMPL_DATA) * HANDLE_BLOCK_SIZE); if (psHandleBlock->psHandleDataArray != IMG_NULL) { IMG_UINT32 ui32SubIndex; psHandleBlock->ui32FreeHandCount = HANDLE_BLOCK_SIZE; for (ui32SubIndex = 0; ui32SubIndex < HANDLE_BLOCK_SIZE; ui32SubIndex++) { HANDLE_IMPL_DATA *psHandleData = psHandleBlock->psHandleDataArray + ui32SubIndex; psHandleData->hHandle = INDEX_TO_HANDLE(ui32SubIndex + ui32Index); psHandleData->pvData = IMG_NULL; psHandleData->ui32NextIndexPlusOne = 0; } } else { PVR_DPF((PVR_DBG_ERROR, "%s: Couldn't allocate handle structures", __FUNCTION__)); eError = PVRSRV_ERROR_OUT_OF_MEMORY; } } if (eError != PVRSRV_OK) { goto error; } #if defined(DEBUG_MAX_HANDLE_COUNT) /* Force handle failure to test error exit code */ if (ui32NewCount > DEBUG_MAX_HANDLE_COUNT) { PVR_DPF((PVR_DBG_ERROR, "%s: Max handle count (%u) reached", __FUNCTION__, DEBUG_MAX_HANDLE_COUNT)); eError = PVRSRV_ERROR_OUT_OF_MEMORY; goto error; } #endif /* defined(DEBUG_MAX_HANDLE_COUNT) */ if (psOldArray != IMG_NULL) { /* Free old handle array */ OSFreeMem(psOldArray); } psBase->psHandleBlockArray = psNewArray; psBase->ui32TotalHandCount = ui32NewCount; if (ui32NewCount > ui32OldCount) { /* Check for wraparound */ PVR_ASSERT(psBase->ui32TotalFreeHandCount + (ui32NewCount - ui32OldCount) > psBase->ui32TotalFreeHandCount); /* PRQA S 3382 1 */ /* ui32NewCount always > ui32OldCount */ psBase->ui32TotalFreeHandCount += (ui32NewCount - ui32OldCount); /* * If purging is enabled, there is no free handle list * management, but as an optimization, when allocating * new handles, we use ui32FirstFreeIndex to point to * the first handle in a newly allocated block. */ if (psBase->ui32FirstFreeIndex == 0) { PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne == 0); psBase->ui32FirstFreeIndex = ui32OldCount; } else { if (!psBase->bPurgingEnabled) { PVR_ASSERT(psBase->ui32LastFreeIndexPlusOne != 0); PVR_ASSERT(INDEX_TO_HANDLE_DATA(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne == 0); INDEX_TO_HANDLE_DATA(psBase, psBase->ui32LastFreeIndexPlusOne - 1)->ui32NextIndexPlusOne = ui32OldCount + 1; } } if (!psBase->bPurgingEnabled) { psBase->ui32LastFreeIndexPlusOne = ui32NewCount; } } else { if (ui32NewCount == 0) { psBase->ui32TotalFreeHandCount = 0; psBase->ui32FirstFreeIndex = 0; psBase->ui32LastFreeIndexPlusOne = 0; } else { PVR_ASSERT(psBase->bPurgingEnabled); PVR_ASSERT(psBase->ui32FirstFreeIndex <= ui32NewCount); PVR_ASSERT(psBase->ui32TotalFreeHandCount - (ui32OldCount - ui32NewCount) < psBase->ui32TotalFreeHandCount); /* PRQA S 3382 1 */ /* ui32OldCount always >= ui32NewCount */ psBase->ui32TotalFreeHandCount -= (ui32OldCount - ui32NewCount); } } PVR_ASSERT(psBase->ui32FirstFreeIndex <= psBase->ui32TotalHandCount); return PVRSRV_OK; error: PVR_ASSERT(eError != PVRSRV_OK); if (psNewArray != IMG_NULL) { /* Free any new handle structures that were allocated */ for (ui32Index = ui32OldCount; ui32Index < ui32NewCount; ui32Index += HANDLE_BLOCK_SIZE) { HANDLE_BLOCK *psHandleBlock = BLOCK_ARRAY_AND_INDEX_TO_HANDLE_BLOCK(psNewArray, ui32Index); if (psHandleBlock->psHandleDataArray != IMG_NULL) { OSFreeMem(psHandleBlock->psHandleDataArray); } } /* Free new handle array */ OSFreeMem(psNewArray); } return eError; }
NTSTATUS InitializeIoHandleTable( IN OUT PCONSOLE_INFORMATION Console, OUT PCONSOLE_PER_PROCESS_DATA ProcessData, OUT PHANDLE StdIn, OUT PHANDLE StdOut, OUT PHANDLE StdErr ) /*++ Routine Description: This routine initializes a process's handle table for the first time (there is no parent process). It also sets up stdin, stdout, and stderr. Arguments: Console - Pointer to console information structure. ProcessData - Pointer to per process data structure. Stdin - Pointer in which to return StdIn handle. StdOut - Pointer in which to return StdOut handle. StdErr - Pointer in which to return StdErr handle. Return Value: --*/ { ULONG i; HANDLE Handle; NTSTATUS Status; PHANDLE_DATA HandleData; // HandleTablePtr gets set up by ConsoleAddProcessRoutine. // it will be != to HandleTable if the new process was created // using "start xxx" at the command line and cmd.exe has > // CONSOLE_INITIAL_IO_HANDLES. if (ProcessData->HandleTablePtr != ProcessData->HandleTable) { ASSERT(ProcessData->HandleTableSize != CONSOLE_INITIAL_IO_HANDLES); HeapFree(pConHeap,0,ProcessData->HandleTablePtr); ProcessData->HandleTablePtr = ProcessData->HandleTable; } for (i=0; i<CONSOLE_INITIAL_IO_HANDLES; i++) { ProcessData->HandleTable[i].HandleType = CONSOLE_FREE_HANDLE; } ProcessData->HandleTableSize = CONSOLE_INITIAL_IO_HANDLES; ProcessData->Foo = 0xF00; // // set up stdin, stdout, stderr. we don't do any cleanup in case // of errors because we're going to fail the console creation. // // stdin // Status = AllocateIoHandle(ProcessData, CONSOLE_INPUT_HANDLE, &Handle ); if (!NT_SUCCESS(Status)) { return((ULONG) Status); } Status = DereferenceIoHandleNoCheck(ProcessData, Handle, &HandleData ); ASSERT (NT_SUCCESS(Status)); if (!NT_SUCCESS(Status)) { return((ULONG) Status); } if (!InitializeInputHandle(HandleData, &Console->InputBuffer)) { return STATUS_NO_MEMORY; } HandleData->HandleType |= CONSOLE_INHERITABLE; Status = ConsoleAddShare(GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &Console->InputBuffer.ShareAccess, HandleData ); ASSERT(NT_SUCCESS(Status)); if (!NT_SUCCESS(Status)) { return((ULONG) Status); } *StdIn = INDEX_TO_HANDLE(Handle); // // stdout // Status = AllocateIoHandle(ProcessData, CONSOLE_OUTPUT_HANDLE, &Handle ); if (!NT_SUCCESS(Status)) { return((ULONG) Status); } Status = DereferenceIoHandleNoCheck(ProcessData, Handle, &HandleData ); ASSERT (NT_SUCCESS(Status)); if (!NT_SUCCESS(Status)) { return((ULONG) Status); } InitializeOutputHandle(HandleData,Console->CurrentScreenBuffer); HandleData->HandleType |= CONSOLE_INHERITABLE; Status = ConsoleAddShare(GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &Console->ScreenBuffers->ShareAccess, HandleData ); ASSERT(NT_SUCCESS(Status)); if (!NT_SUCCESS(Status)) { return((ULONG) Status); } *StdOut = INDEX_TO_HANDLE(Handle); // // stderr // Status = AllocateIoHandle(ProcessData, CONSOLE_OUTPUT_HANDLE, &Handle ); if (!NT_SUCCESS(Status)) { return((ULONG) Status); } Status = DereferenceIoHandleNoCheck(ProcessData, Handle, &HandleData ); ASSERT (NT_SUCCESS(Status)); if (!NT_SUCCESS(Status)) { return((ULONG) Status); } InitializeOutputHandle(HandleData,Console->CurrentScreenBuffer); HandleData->HandleType |= CONSOLE_INHERITABLE; Status = ConsoleAddShare(GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &Console->ScreenBuffers->ShareAccess, HandleData ); ASSERT(NT_SUCCESS(Status)); if (!NT_SUCCESS(Status)) { return((ULONG) Status); } *StdErr = INDEX_TO_HANDLE(Handle); return STATUS_SUCCESS; }