LW_NTSTATUS LwRtlSetTaskFd( PLW_TASK pTask, int Fd, LW_TASK_EVENT_MASK Mask ) { NTSTATUS status = STATUS_SUCCESS; struct epoll_event event; memset(&event, 0, sizeof(event)); if (Fd < 0) { status = STATUS_INVALID_HANDLE; GOTO_ERROR_ON_STATUS(status); } if (Fd == pTask->Fd) { if (Mask == 0) { pTask->Fd = -1; if (epoll_ctl(pTask->pThread->EpollFd, EPOLL_CTL_DEL, Fd, &event) < 0) { ABORT_ON_FATAL_ERRNO(errno); status = LwErrnoToNtStatus(errno); GOTO_ERROR_ON_STATUS(status); } } } else if (Mask) { if (pTask->Fd >= 0) { /* Only one fd is supported */ status = STATUS_INSUFFICIENT_RESOURCES; GOTO_ERROR_ON_STATUS(status); } if (epoll_ctl(pTask->pThread->EpollFd, EPOLL_CTL_ADD, Fd, &event) < 0) { ABORT_ON_FATAL_ERRNO(errno); status = LwErrnoToNtStatus(errno); GOTO_ERROR_ON_STATUS(status); } pTask->Fd = Fd; pTask->EventLastWait = 0; } error: return status; }
NTSTATUS InitWorkThreads( PLW_WORK_THREADS pThreads, PLW_THREAD_POOL_ATTRIBUTES pAttrs, int numCpus ) { NTSTATUS status = STATUS_SUCCESS; size_t i = 0; RingInit(&pThreads->WorkItems); status = LwErrnoToNtStatus(pthread_mutex_init(&pThreads->Lock, NULL)); GOTO_ERROR_ON_STATUS(status); pThreads->bDestroyLock = TRUE; status = LwErrnoToNtStatus(pthread_cond_init(&pThreads->Event, NULL)); GOTO_ERROR_ON_STATUS(status); pThreads->bDestroyEvent = TRUE; pThreads->ulWorkThreadCount = GetWorkThreadsAttr(pAttrs, numCpus); pThreads->ulWorkThreadStackSize = pAttrs ? pAttrs->ulWorkThreadStackSize : 0; pThreads->ulWorkThreadTimeout = GetWorkThreadTimeoutAttr(pAttrs); if (pThreads->ulWorkThreadCount) { status = LW_RTL_ALLOCATE_ARRAY_AUTO( &pThreads->pWorkThreads, pThreads->ulWorkThreadCount); GOTO_ERROR_ON_STATUS(status); for (i = 0; i < pThreads->ulWorkThreadCount; i++) { pThreads->pWorkThreads[i].Thread = INVALID_THREAD_HANDLE; } } if (pThreads->ulWorkThreadTimeout == 0) { for (i = 0; i < pThreads->ulWorkThreadCount; i++) { status = StartWorkThread(pThreads, &pThreads->pWorkThreads[i]); GOTO_ERROR_ON_STATUS(status); } } error: return status; }
/* * Called with pThreads->Lock held */ static NTSTATUS StartWorkThread( PLW_WORK_THREADS pThreads, PLW_WORK_THREAD pThread ) { NTSTATUS status = STATUS_SUCCESS; pthread_attr_t threadAttr; pthread_attr_t* pThreadAttr = NULL; pThread->pThreads = pThreads; if (pThreads->ulWorkThreadStackSize) { status = LwErrnoToNtStatus(pthread_attr_init(&threadAttr)); GOTO_ERROR_ON_STATUS(status); pThreadAttr = &threadAttr; status = LwErrnoToNtStatus( pthread_attr_setstacksize(pThreadAttr, pThreads->ulWorkThreadStackSize)); GOTO_ERROR_ON_STATUS(status); status = LwRtlResetAffinityThreadAttribute(pThreadAttr); GOTO_ERROR_ON_STATUS(status); } status = LwErrnoToNtStatus( pthread_create( &pThread->Thread, pThreadAttr, WorkThread, pThread)); GOTO_ERROR_ON_STATUS(status); pThread->bStarted = TRUE; pThreads->ulStarted++; error: if (pThreadAttr) { pthread_attr_destroy(pThreadAttr); } return status; }
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 LwioLocalOpenFile( IN PCSTR pszFileName, IN INT dwMode, IN INT dwPerms, OUT INT *dwHandle ) { NTSTATUS status = STATUS_SUCCESS; int fd = -1; BAIL_ON_NULL_POINTER(pszFileName); if ((fd = open(pszFileName, dwMode, dwPerms)) == -1) { status = LwErrnoToNtStatus(errno); BAIL_ON_NT_STATUS(status); } error: *dwHandle = fd; return status; }
NTSTATUS WireGetCurrentNTTime( PLONG64 pllCurTime ) { NTSTATUS ntStatus = STATUS_SUCCESS; struct timeval tv = {0}; if (gettimeofday(&tv, NULL) < 0) { ntStatus = LwErrnoToNtStatus(errno); BAIL_ON_NT_STATUS(ntStatus); } *pllCurTime = ((tv.tv_sec + WIRE_NTTIME_EPOCH_DIFFERENCE_SECS) * WIRE_FACTOR_SECS_TO_HUNDREDS_OF_NANOSECS) + tv.tv_usec * WIRE_FACTOR_MICROSECS_TO_HUNDREDS_OF_NANOSECS; cleanup: return ntStatus; error: *pllCurTime = 0LL; goto cleanup; }
static NTSTATUS GetFdLimit( PULONG pulLimit ) { NTSTATUS status = STATUS_SUCCESS; struct rlimit limit = {0}; if (getrlimit(RLIMIT_NOFILE, &limit) != 0) { status = LwErrnoToNtStatus(errno); GOTO_ERROR_ON_STATUS(status); } if (limit.rlim_cur == RLIM_INFINITY) { *pulLimit = (ULONG) 0xFFFFFFFF; } else { *pulLimit = (ULONG) limit.rlim_cur; } error: return status; }
NTSTATUS LwRtlResetAffinityThreadAttribute( pthread_attr_t* pAttr ) { NTSTATUS status = STATUS_SUCCESS; CPU_SET_TYPE cpuSet; ULONG numCpus = 0; int i = 0; CPU_ZERO(&cpuSet); numCpus = LwRtlGetCpuCount(); for (i = 0; i < numCpus; i++) { (void) CPU_SET(i, &cpuSet); } status = LwErrnoToNtStatus( pthread_attr_setaffinity_np(pAttr, sizeof(cpuSet), &cpuSet)); GOTO_ERROR_ON_STATUS(status); error: return status; }
NTSTATUS LwioChangeLocalFileOwner( IN PCSTR pszPath, IN uid_t uid, IN gid_t gid ) { NTSTATUS status = STATUS_SUCCESS; while (1) { if (chown(pszPath, uid, gid) < 0) { if (errno == EINTR) { continue; } status = LwErrnoToNtStatus(errno); BAIL_ON_NT_STATUS(status); } else { break; } } error: return status; }
NTSTATUS LwioChangeLocalFilePerms( IN PCSTR pszPath, IN mode_t dwFileMode ) { NTSTATUS status = STATUS_SUCCESS; while (1) { if (chmod(pszPath, dwFileMode) < 0) { if (errno == EINTR) { continue; } status = LwErrnoToNtStatus(errno); BAIL_ON_NT_STATUS(status); } else { break; } } error: return status; }
static NTSTATUS LwioGetSystemTime( struct timespec* pTimeSpec /* IN OUT */ ) { NTSTATUS status = STATUS_SUCCESS; struct timespec ts = {0}; #ifdef LW_SUPPORT_NANOSECOND_TIMESTAMP #if defined(HAVE_CLOCK_GETTIME) if (gbLwioLogDoNanoSecondTime) { if (clock_gettime(CLOCK_REALTIME, &ts) < 0) { status = LwErrnoToNtStatus(errno); } } else #endif /* defined(HAVE_CLOCK_GETRES) && defined(HAVE_CLOCK_GETTIME) */ #endif /* LW_SUPPORT_NANOSECOND_TIMESTAMP */ { ts.tv_sec = time(NULL); ts.tv_nsec = 0; } *pTimeSpec = ts; return status; }
NTSTATUS LwioLocalRemoveFile( IN PCSTR pszPath ) { NTSTATUS status = STATUS_SUCCESS; BAIL_ON_NULL_POINTER(pszPath); while (1) { if (unlink(pszPath) < 0) { if (errno == EINTR) { continue; } status = LwErrnoToNtStatus(errno); BAIL_ON_NT_STATUS(status); } else { break; } } error: return status; }
NTSTATUS LwioGetLocalFileOwnerAndPerms( IN PCSTR pszSrcPath, OUT uid_t * uid, OUT gid_t * gid, OUT mode_t * mode ) { NTSTATUS status = STATUS_SUCCESS; struct stat statbuf; memset(&statbuf, 0, sizeof(struct stat)); if (stat(pszSrcPath, &statbuf) < 0) { status = LwErrnoToNtStatus(errno); BAIL_ON_NT_STATUS(status); } *uid = statbuf.st_uid; *gid = statbuf.st_gid; *mode = statbuf.st_mode; error: return status; }
static NTSTATUS WorkWait( PLW_WORK_THREAD pThread ) { NTSTATUS status = STATUS_SUCCESS; struct timespec ts = {0}; LONG64 llDeadline = 0; int err = 0; BOOLEAN bLastThread = FALSE; PLW_WORK_THREADS pThreads = pThread->pThreads; while (pThreads->ulQueued == 0) { if (pThreads->bShutdown) { status = STATUS_CANCELLED; GOTO_ERROR_ON_STATUS(status); } if (pThread->pThreads->ulWorkThreadTimeout && !bLastThread) { status = TimeNow(&llDeadline); GOTO_ERROR_ON_STATUS(status); llDeadline += (LONG64) 1000000000ll * pThread->pThreads->ulWorkThreadTimeout; ts.tv_sec = llDeadline / 1000000000ll; ts.tv_nsec = llDeadline % 1000000000ll; err = pthread_cond_timedwait(&pThread->pThreads->Event, &pThread->pThreads->Lock, &ts); } else { err = pthread_cond_wait(&pThread->pThreads->Event, &pThread->pThreads->Lock); } bLastThread = pThreads->ulWorkItemCount && pThreads->ulStarted == 1; switch(err) { case ETIMEDOUT: if (!bLastThread) { status = STATUS_TIMEOUT; GOTO_ERROR_ON_STATUS(status); } break; default: status = LwErrnoToNtStatus(err); GOTO_ERROR_ON_STATUS(status); } } error: return status; }
static NTSTATUS Poll( IN PCLOCK pClock, IN OUT PLONG64 pllNow, IN int EpollFd, OUT struct epoll_event* pEvents, IN int maxEvents, IN LONG64 llNextDeadline, OUT int* pReady ) { NTSTATUS status = STATUS_SUCCESS; int ready = 0; int timeout = 0; do { if (llNextDeadline >= 0) { /* Convert to timeout in milliseconds */ timeout = (llNextDeadline - *pllNow) / 1000000ll; if (timeout < 0) { timeout = 0; } } else { timeout = -1; } ready = epoll_wait(EpollFd, pEvents, maxEvents, timeout); if (ready < 0 && errno == EINTR) { /* Update current time so the next timeout calculation is correct */ status = ClockGetMonotonicTime(pClock, pllNow); GOTO_ERROR_ON_STATUS(status); } } while (ready < 0 && errno == EINTR); if (ready < 0) { ABORT_ON_FATAL_ERRNO(errno); status = LwErrnoToNtStatus(errno); GOTO_ERROR_ON_STATUS(status); } *pReady = ready; error: return status; }
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; }
NTSTATUS LwioCheckLocalFileExists( IN PCSTR pszPath, OUT PBOOLEAN pbFileExists ) { NTSTATUS status = STATUS_SUCCESS; struct stat statbuf; BAIL_ON_NULL_POINTER(pszPath); memset(&statbuf, 0, sizeof(struct stat)); while (1) { if (stat(pszPath, &statbuf) < 0) { if (errno == EINTR) { continue; } else if (errno == ENOENT || errno == ENOTDIR) { *pbFileExists = FALSE; break; } status = LwErrnoToNtStatus(errno); BAIL_ON_NT_STATUS(status); } else { *pbFileExists = (((statbuf.st_mode & S_IFMT) == S_IFREG) ? TRUE : FALSE); break; } } cleanup: return status; error: *pbFileExists = FALSE; goto cleanup; }
NTSTATUS SrvSocketAddressToString( const struct sockaddr* pSocketAddress, /* IN */ PSTR pszAddress, /* OUT */ ULONG ulAddressLength /* IN */ ) { NTSTATUS ntStatus = STATUS_SUCCESS; PVOID pAddressPart = NULL; switch (pSocketAddress->sa_family) { case AF_INET: pAddressPart = &((struct sockaddr_in*)pSocketAddress)->sin_addr; break; #ifdef AF_INET6 case AF_INET6: pAddressPart = &((struct sockaddr_in6*)pSocketAddress)->sin6_addr; break; #endif default: ntStatus = STATUS_NOT_SUPPORTED; BAIL_ON_NT_STATUS(ntStatus); } if (!inet_ntop( pSocketAddress->sa_family, pAddressPart, pszAddress, ulAddressLength)) { ntStatus = LwErrnoToNtStatus(errno); BAIL_ON_NT_STATUS(ntStatus); } cleanup: return ntStatus; error: // Terminate output buffer if (ulAddressLength > 0) { pszAddress[0] = 0; } goto cleanup; }
/* * Updates the epoll set with the events a task is waiting on. */ static NTSTATUS UpdateEventWait( PEPOLL_TASK pTask, int EpollFd ) { NTSTATUS status = STATUS_SUCCESS; __uint32_t events = 0; struct epoll_event event; if ((pTask->EventWait & FD_EVENTS) != (pTask->EventLastWait & FD_EVENTS) && pTask->Fd >= 0) { if (pTask->EventWait & LW_TASK_EVENT_FD_READABLE) { events |= EPOLLIN; } if (pTask->EventWait & LW_TASK_EVENT_FD_WRITABLE) { events |= EPOLLOUT; } if (pTask->EventWait & LW_TASK_EVENT_FD_EXCEPTION) { events |= EPOLLERR; } memset(&event, 0, sizeof(event)); event.events = events | EPOLLET; event.data.ptr = pTask; if (epoll_ctl(EpollFd, EPOLL_CTL_MOD, pTask->Fd, &event) < 0) { ABORT_ON_FATAL_ERRNO(errno); status = LwErrnoToNtStatus(errno); GOTO_ERROR_ON_STATUS(status); } } pTask->EventLastWait = pTask->EventWait; error: return status; }
LW_NTSTATUS LwRtlWC16StringAllocatePrintfV( LW_OUT LW_PWSTR* ppszString, LW_IN LW_PCSTR pszFormat, LW_IN va_list Args ) { size_t writtenCount = 0; return LwErrnoToNtStatus( LwPrintfW16AllocateStringV( ppszString, &writtenCount, pszFormat, Args)); }
LW_NTSTATUS LwRtlWC16StringAllocatePrintfWV( LW_OUT LW_PWSTR* ppszString, LW_IN const wchar_t* pszFormat, LW_IN va_list Args ) { size_t charsWritten = 0; return LwErrnoToNtStatus( LwPrintfW16AllocateStringWV( ppszString, &charsWritten, pszFormat, Args)); }
NTSTATUS SrvSocketGetAddrInfoA( PCSTR pszClientname, struct addrinfo** ppAddrInfo ) { NTSTATUS ntStatus = STATUS_SUCCESS; struct addrinfo hints = {0}; struct addrinfo* pAddrInfo = NULL; if (IsNullOrEmptyString(pszClientname)) { ntStatus = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntStatus); } hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; hints.ai_protocol = 0; hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; if (getaddrinfo(pszClientname, NULL, &hints, &pAddrInfo) != 0) { ntStatus = LwErrnoToNtStatus(errno); BAIL_ON_NT_STATUS(ntStatus); } *ppAddrInfo = pAddrInfo; cleanup: return ntStatus; error: *ppAddrInfo = NULL; if (pAddrInfo) { freeaddrinfo(pAddrInfo); } goto cleanup; }
NTSTATUS PvfsMapUnixErrnoToNtStatus( int err ) { NTSTATUS ntError = LwErrnoToNtStatus(err); if (ntError == (NTSTATUS)-1) { LWIO_LOG_ERROR( "%s: Unable to map Unix errno (%d) to an NTSTATUS error.\n", PVFS_LOG_HEADER, err); } return ntError; }
static NTSTATUS SelectThreadInit( PLW_THREAD_POOL_ATTRIBUTES pAttrs, PSELECT_THREAD pThread ) { NTSTATUS status = STATUS_SUCCESS; pthread_attr_t pthreadAttr; BOOLEAN bAttrInit = FALSE; status = LwErrnoToNtStatus(pthread_attr_init(&pthreadAttr)); GOTO_ERROR_ON_STATUS(status); bAttrInit = TRUE; GOTO_ERROR_ON_STATUS(status = LwErrnoToNtStatus(pthread_mutex_init(&pThread->Lock, NULL))); GOTO_ERROR_ON_STATUS(status = LwErrnoToNtStatus(pthread_cond_init(&pThread->Event, NULL))); if (pipe(pThread->SignalFds) < 0) { GOTO_ERROR_ON_STATUS(status = LwErrnoToNtStatus(errno)); } SetCloseOnExec(pThread->SignalFds[0]); SetCloseOnExec(pThread->SignalFds[1]); RingInit(&pThread->Tasks); if (pAttrs && pAttrs->ulTaskThreadStackSize) { GOTO_ERROR_ON_STATUS(status = LwErrnoToNtStatus( pthread_attr_setstacksize(&pthreadAttr, pAttrs->ulTaskThreadStackSize))); } GOTO_ERROR_ON_STATUS(status = LwErrnoToNtStatus( pthread_create( &pThread->Thread, &pthreadAttr, EventThread, pThread))); error: if (bAttrInit) { pthread_attr_destroy(&pthreadAttr); } return status; }
/** * @brief Set the thread cpu affinity attribute to the * supplied cpu number. * Specifying a cpu number that does not exist, or is * offline will cause pthread_create() to fail with * EINVAL. * * @param pAttr pointer to the pthread_att_t * @param CpuNumber the cpu number */ NTSTATUS LwRtlSetAffinityThreadAttribute( pthread_attr_t* pAttr, ULONG CpuNumber ) { NTSTATUS status = STATUS_SUCCESS; CPU_SET_TYPE cpuSet; CPU_ZERO(&cpuSet); (void) CPU_SET(CpuNumber, &cpuSet); status = LwErrnoToNtStatus( pthread_attr_setaffinity_np(pAttr, sizeof(cpuSet), &cpuSet)); GOTO_ERROR_ON_STATUS(status); error: return status; }
NTSTATUS PvfsSysReadDir( DIR *pDir, struct dirent *pDirEntry, struct dirent **ppDirEntry ) { NTSTATUS ntError = STATUS_SUCCESS; int unixerr = 0; unixerr = readdir_r(pDir, pDirEntry, ppDirEntry); if (unixerr != 0) { ntError = LwErrnoToNtStatus(unixerr); } BAIL_ON_NT_STATUS(ntError); error: return ntError; }
static inline NTSTATUS TimeNow( PLONG64 pllNow ) { struct timeval tv; if (gettimeofday(&tv, NULL)) { return LwErrnoToNtStatus(errno); } else { *pllNow = tv.tv_sec * 1000000000ll + tv.tv_usec * 1000ll; return STATUS_SUCCESS; } }
NTSTATUS LwioLocalCheckDirExists( IN PCSTR pszPath, IN PBOOLEAN pbDirExists ) { NTSTATUS status = STATUS_SUCCESS; struct stat statbuf; BAIL_ON_NULL_POINTER(pszPath); while (1) { memset(&statbuf, 0, sizeof(struct stat)); if (stat(pszPath, &statbuf) < 0) { if (errno == EINTR) { continue; } else if (errno == ENOENT || errno == ENOTDIR) { *pbDirExists = FALSE; break; } status = LwErrnoToNtStatus(errno); BAIL_ON_NT_STATUS(status); } *pbDirExists = (((statbuf.st_mode & S_IFMT) == S_IFDIR) ? TRUE : FALSE); break; } error: return status; }
LW_NTSTATUS LwRtlBlockSignals( VOID ) { NTSTATUS status = STATUS_SUCCESS; sigset_t blockSet; size_t i = 0; sigfillset(&blockSet); /* Don't block blacklisted signals */ for (i = 0; SignalBlacklist[i]; i++) { sigdelset(&blockSet, SignalBlacklist[i]); } status = LwErrnoToNtStatus(pthread_sigmask(SIG_SETMASK, &blockSet, NULL)); GOTO_ERROR_ON_STATUS(status); error: return status; }
NTSTATUS RegMapLwmsgStatus( LWMsgStatus status ) { switch (status) { case LWMSG_STATUS_SUCCESS: return STATUS_SUCCESS; case LWMSG_STATUS_ERROR: case LWMSG_STATUS_SYSTEM: return STATUS_INTERNAL_ERROR; case LWMSG_STATUS_MEMORY: return STATUS_NO_MEMORY; case LWMSG_STATUS_MALFORMED: case LWMSG_STATUS_OVERFLOW: case LWMSG_STATUS_UNDERFLOW: case LWMSG_STATUS_EOF: return STATUS_INVALID_NETWORK_RESPONSE; case LWMSG_STATUS_INVALID_PARAMETER: case LWMSG_STATUS_INVALID_STATE: return STATUS_INVALID_PARAMETER; case LWMSG_STATUS_UNIMPLEMENTED: return STATUS_NOT_IMPLEMENTED; case LWMSG_STATUS_SECURITY: return STATUS_ACCESS_DENIED; case LWMSG_STATUS_CANCELLED: return STATUS_MORE_PROCESSING_REQUIRED; case LWMSG_STATUS_FILE_NOT_FOUND: return LwErrnoToNtStatus(ENOENT); case LWMSG_STATUS_CONNECTION_REFUSED: return LwErrnoToNtStatus(ECONNREFUSED); case LWMSG_STATUS_PEER_RESET: return LwErrnoToNtStatus(ECONNRESET); case LWMSG_STATUS_PEER_ABORT: return LwErrnoToNtStatus(ECONNABORTED); case LWMSG_STATUS_PEER_CLOSE: return LwErrnoToNtStatus(EPIPE); case LWMSG_STATUS_SESSION_LOST: return LwErrnoToNtStatus(EPIPE); case LWMSG_STATUS_NOT_FOUND: return STATUS_NOT_FOUND; default: return STATUS_INTERNAL_ERROR; } }