static NTSTATUS LwIoThreadInit( void ) { NTSTATUS Status = 0; BOOL bInLock = FALSE; LWIO_LOCK_MUTEX(bInLock, &gLock); if (!gpLwIoProtocol) { LwIoInitialize(); } if (!gbStateKeyInit) { Status = LwErrnoToNtStatus(pthread_key_create(&gStateKey, LwIoThreadStateDestruct)); BAIL_ON_NT_STATUS(Status); gbStateKeyInit = TRUE; } if (!gpProcessCreds) { Status = LwIoInitProcessCreds(); BAIL_ON_NT_STATUS(Status); } if (!gpClient) { Status = NtIpcLWMsgStatusToNtStatus(lwmsg_peer_new(NULL, gpLwIoProtocol, &gpClient)); BAIL_ON_NT_STATUS(Status); Status = NtIpcLWMsgStatusToNtStatus(lwmsg_peer_add_connect_endpoint( gpClient, LWMSG_ENDPOINT_DIRECT, "lwio")); Status = NtIpcLWMsgStatusToNtStatus(lwmsg_peer_add_connect_endpoint( gpClient, LWMSG_ENDPOINT_LOCAL, LWIO_SERVER_FILENAME)); BAIL_ON_NT_STATUS(Status); } if (!gpSession) { Status = NtIpcLWMsgStatusToNtStatus(lwmsg_peer_connect( gpClient, &gpSession)); BAIL_ON_NT_STATUS(Status); } error: LWIO_UNLOCK_MUTEX(bInLock, &gLock); return Status; }
NTSTATUS LwIoDaemonIpcAddProtocolSpec( IN OUT LWMsgProtocol* pProtocol ) { NTSTATUS status = 0; int EE = 0; LWMsgStatus msgStatus = 0; msgStatus = lwmsg_protocol_add_protocol_spec(pProtocol, gLwIoDaemonProtocolSpec); status = NtIpcLWMsgStatusToNtStatus(msgStatus); GOTO_CLEANUP_ON_STATUS_EE(status, EE); cleanup: LOG_LEAVE_IF_STATUS_EE(status, EE); return status; }
static NTSTATUS NtpCtxCall( IN LWMsgCall* pCall, IN LWMsgTag RequestType, IN PVOID pRequest, IN LWMsgTag ResponseType, OUT PVOID* ppResponse ) { NTSTATUS status = 0; LWMsgParams in = LWMSG_PARAMS_INITIALIZER; LWMsgParams out = LWMSG_PARAMS_INITIALIZER; in.tag = RequestType; in.data = pRequest; status = NtIpcLWMsgStatusToNtStatus(lwmsg_call_dispatch(pCall, &in, &out, NULL, NULL)); BAIL_ON_NT_STATUS(status); if (out.tag != ResponseType) { status = STATUS_INTERNAL_ERROR; BAIL_ON_NT_STATUS(status); } *ppResponse = out.data; cleanup: return status; error: *ppResponse = NULL; NtpCtxFreeResponse(pCall, out.tag, out.data); goto cleanup; }
static void NtpCtxCallComplete( LWMsgCall* pCall, LWMsgStatus callStatus, void* data ) { PIO_CLIENT_ASYNC_CONTEXT pContext = data; NTSTATUS status = NtIpcLWMsgStatusToNtStatus(callStatus); if (status == STATUS_SUCCESS && pContext->out.tag != pContext->responseType) { status = STATUS_INTERNAL_ERROR; } pContext->pfnComplete( pContext, status); pContext->pControl->Callback(pContext->pControl->CallbackContext); LwNtDereferenceAsyncCancelContext(&pContext); }
static NTSTATUS NtpCtxCallAsync( IN PIO_CLIENT_ASYNC_CONTEXT pContext, IN LWMsgTag RequestType, IN PVOID pRequest, IN LWMsgTag ResponseType, IN OUT OPTIONAL PIO_ASYNC_CONTROL_BLOCK pControl, IN IO_CLIENT_ASYNC_COMPLETE_FUNCTION pfnComplete ) { NTSTATUS status = STATUS_SUCCESS; pContext->in.tag = RequestType; pContext->in.data = pRequest; status = LwIoConnectionAcquireCall(&pContext->pCall); BAIL_ON_NT_STATUS(status); if (pControl) { pContext->lRefcount = 2; pContext->pfnComplete = pfnComplete; pContext->pControl = pControl; pContext->responseType = ResponseType; status = NtIpcLWMsgStatusToNtStatus(lwmsg_call_dispatch( pContext->pCall, &pContext->in, &pContext->out, NtpCtxCallComplete, pContext)); } else { status = NtIpcLWMsgStatusToNtStatus(lwmsg_call_dispatch( pContext->pCall, &pContext->in, &pContext->out, NULL, NULL)); } switch (status) { case STATUS_PENDING: /* We should only get STATUS_PENDING from async calls */ assert(pControl); pControl->AsyncCancelContext = pContext; BAIL_ON_NT_STATUS(status); case STATUS_SUCCESS: if (pContext->out.tag != ResponseType) { status = STATUS_INTERNAL_ERROR; BAIL_ON_NT_STATUS(status); } break; default: BAIL_ON_NT_STATUS(status); } cleanup: return status; error: goto cleanup; }