HANDLE CreateFileDescriptorEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, int FileDescriptor) { #ifndef _WIN32 WINPR_EVENT* event; HANDLE handle = NULL; event = (WINPR_EVENT*) malloc(sizeof(WINPR_EVENT)); if (event) { event->bAttached = TRUE; event->bManualReset = bManualReset; event->pipe_fd[0] = FileDescriptor; event->pipe_fd[1] = -1; WINPR_HANDLE_SET_TYPE(event, HANDLE_TYPE_EVENT); handle = (HANDLE) event; } return handle; #else return NULL; #endif }
HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { char* name; int status; HANDLE hNamedPipe; struct sockaddr_un s; WINPR_NAMED_PIPE* pNamedPipe; if (!lpFileName) return INVALID_HANDLE_VALUE; name = GetNamedPipeNameWithoutPrefixA(lpFileName); if (!name) return INVALID_HANDLE_VALUE; free(name); pNamedPipe = (WINPR_NAMED_PIPE*) malloc(sizeof(WINPR_NAMED_PIPE)); hNamedPipe = (HANDLE) pNamedPipe; WINPR_HANDLE_SET_TYPE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE); pNamedPipe->name = _strdup(lpFileName); pNamedPipe->dwOpenMode = 0; pNamedPipe->dwPipeMode = 0; pNamedPipe->nMaxInstances = 0; pNamedPipe->nOutBufferSize = 0; pNamedPipe->nInBufferSize = 0; pNamedPipe->nDefaultTimeOut = 0; pNamedPipe->dwFlagsAndAttributes = dwFlagsAndAttributes; pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpFileName); pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpFileName); pNamedPipe->clientfd = socket(PF_LOCAL, SOCK_STREAM, 0); pNamedPipe->serverfd = -1; pNamedPipe->ServerMode = FALSE; ZeroMemory(&s, sizeof(struct sockaddr_un)); s.sun_family = AF_UNIX; strcpy(s.sun_path, pNamedPipe->lpFilePath); status = connect(pNamedPipe->clientfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un)); if (status != 0) { close(pNamedPipe->clientfd); free((char *)pNamedPipe->name); free((char *)pNamedPipe->lpFileName); free((char *)pNamedPipe->lpFilePath); free(pNamedPipe); return INVALID_HANDLE_VALUE; } return hNamedPipe; }
HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName) { WINPR_EVENT* event; event = (WINPR_EVENT*) calloc(1, sizeof(WINPR_EVENT)); if (!event) return NULL; event->bAttached = FALSE; event->bManualReset = bManualReset; event->ops = &ops; WINPR_HANDLE_SET_TYPE(event, HANDLE_TYPE_EVENT); if (!event->bManualReset) { WLog_ERR(TAG, "auto-reset events not yet implemented"); } event->pipe_fd[0] = -1; event->pipe_fd[1] = -1; #ifdef HAVE_EVENTFD_H event->pipe_fd[0] = eventfd(0, EFD_NONBLOCK); if (event->pipe_fd[0] < 0) { WLog_ERR(TAG, "failed to create event"); free(event); return NULL; } #else if (pipe(event->pipe_fd) < 0) { WLog_ERR(TAG, "failed to create event"); free(event); return NULL; } #endif if (bInitialState) SetEvent(event); if (!cs.LockSemaphore && !InitializeCriticalSectionEx(&cs, 0, 0)) { if (event->pipe_fd[0] != -1) close(event->pipe_fd[0]); if (event->pipe_fd[1] != -1) close(event->pipe_fd[1]); free(event); return NULL; } return (HANDLE)event; }
HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName) { HANDLE handle; WINPR_SEMAPHORE* semaphore; semaphore = (WINPR_SEMAPHORE*) calloc(1, sizeof(WINPR_SEMAPHORE)); if (!semaphore) return NULL; semaphore->pipe_fd[0] = -1; semaphore->pipe_fd[0] = -1; semaphore->sem = (winpr_sem_t*) NULL; semaphore->ops = &ops; if (semaphore) { #ifdef WINPR_PIPE_SEMAPHORE if (pipe(semaphore->pipe_fd) < 0) { WLog_ERR(TAG, "failed to create semaphore"); free(semaphore); return NULL; } while (lInitialCount > 0) { if (write(semaphore->pipe_fd[1], "-", 1) != 1) { close(semaphore->pipe_fd[0]); close(semaphore->pipe_fd[1]); free(semaphore); return NULL; } lInitialCount--; } #else semaphore->sem = (winpr_sem_t*) malloc(sizeof(winpr_sem_t)); #if defined __APPLE__ semaphore_create(mach_task_self(), semaphore->sem, SYNC_POLICY_FIFO, lMaximumCount); #else sem_init(semaphore->sem, 0, lMaximumCount); #endif #endif } WINPR_HANDLE_SET_TYPE(semaphore, HANDLE_TYPE_SEMAPHORE); handle = (HANDLE) semaphore; return handle; }
BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize) { int pipe_fd[2]; WINPR_PIPE* pReadPipe; WINPR_PIPE* pWritePipe; pipe_fd[0] = -1; pipe_fd[1] = -1; if (pipe(pipe_fd) < 0) { printf("CreatePipe: failed to create pipe\n"); return FALSE; } pReadPipe = (WINPR_PIPE*) malloc(sizeof(WINPR_PIPE)); pWritePipe = (WINPR_PIPE*) malloc(sizeof(WINPR_PIPE)); if (!pReadPipe || !pWritePipe) { if (pReadPipe) free(pReadPipe); if (pWritePipe) free(pWritePipe); return FALSE; } pReadPipe->fd = pipe_fd[0]; pWritePipe->fd = pipe_fd[1]; WINPR_HANDLE_SET_TYPE(pReadPipe, HANDLE_TYPE_ANONYMOUS_PIPE); *((ULONG_PTR*) hReadPipe) = (ULONG_PTR) pReadPipe; WINPR_HANDLE_SET_TYPE(pWritePipe, HANDLE_TYPE_ANONYMOUS_PIPE); *((ULONG_PTR*) hWritePipe) = (ULONG_PTR) pWritePipe; return TRUE; }
HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName) { WINPR_EVENT* event; HANDLE handle = NULL; event = (WINPR_EVENT*) malloc(sizeof(WINPR_EVENT)); if (event) { event->bAttached = FALSE; event->bManualReset = bManualReset; if (!event->bManualReset) { fprintf(stderr, "CreateEventW: auto-reset events not yet implemented\n"); } event->pipe_fd[0] = -1; event->pipe_fd[1] = -1; #ifdef HAVE_EVENTFD_H event->pipe_fd[0] = eventfd(0, EFD_NONBLOCK); if (event->pipe_fd[0] < 0) { fprintf(stderr, "CreateEventW: failed to create event\n"); free(event); return NULL; } #else if (pipe(event->pipe_fd) < 0) { fprintf(stderr, "CreateEventW: failed to create event\n"); free(event); return NULL; } #endif WINPR_HANDLE_SET_TYPE(event, HANDLE_TYPE_EVENT); handle = (HANDLE) event; if (bInitialState) SetEvent(handle); } if (!cs.LockSemaphore) InitializeCriticalSection(&cs); return handle; }
HANDLE CreateTimerQueue(void) { HANDLE handle = NULL; WINPR_TIMER_QUEUE* timerQueue; timerQueue = (WINPR_TIMER_QUEUE*) calloc(1, sizeof(WINPR_TIMER_QUEUE)); if (timerQueue) { WINPR_HANDLE_SET_TYPE(timerQueue, HANDLE_TYPE_TIMER_QUEUE); handle = (HANDLE) timerQueue; timerQueue->activeHead = NULL; timerQueue->inactiveHead = NULL; timerQueue->bCancelled = FALSE; StartTimerQueueThread(timerQueue); } return handle; }
HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName) { HANDLE handle = NULL; WINPR_MUTEX* mutex; mutex = (WINPR_MUTEX*) malloc(sizeof(WINPR_MUTEX)); if (mutex) { pthread_mutex_init(&mutex->mutex, 0); WINPR_HANDLE_SET_TYPE(mutex, HANDLE_TYPE_MUTEX); handle = (HANDLE) mutex; if (bInitialOwner) pthread_mutex_lock(&mutex->mutex); } return handle; }
HANDLE CreateWaitableTimerA(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset, LPCSTR lpTimerName) { HANDLE handle = NULL; WINPR_TIMER* timer; timer = (WINPR_TIMER*) calloc(1, sizeof(WINPR_TIMER)); if (timer) { WINPR_HANDLE_SET_TYPE(timer, HANDLE_TYPE_TIMER); handle = (HANDLE) timer; timer->fd = -1; timer->lPeriod = 0; timer->bManualReset = bManualReset; timer->pfnCompletionRoutine = NULL; timer->lpArgToCompletionRoutine = NULL; timer->bInit = FALSE; timer->ops = &ops; } return handle; }
BOOL CreateTimerQueueTimer(PHANDLE phNewTimer, HANDLE TimerQueue, WAITORTIMERCALLBACK Callback, PVOID Parameter, DWORD DueTime, DWORD Period, ULONG Flags) { struct timespec CurrentTime; WINPR_TIMER_QUEUE* timerQueue; WINPR_TIMER_QUEUE_TIMER* timer; if (!TimerQueue) return FALSE; timespec_gettimeofday(&CurrentTime); timerQueue = (WINPR_TIMER_QUEUE*) TimerQueue; timer = (WINPR_TIMER_QUEUE_TIMER*) malloc(sizeof(WINPR_TIMER_QUEUE_TIMER)); if (!timer) return FALSE; WINPR_HANDLE_SET_TYPE(timer, HANDLE_TYPE_TIMER_QUEUE_TIMER); *((UINT_PTR*) phNewTimer) = (UINT_PTR)(HANDLE) timer; timespec_copy(&(timer->StartTime), &CurrentTime); timespec_add_ms(&(timer->StartTime), DueTime); timespec_copy(&(timer->ExpirationTime), &(timer->StartTime)); timer->Flags = Flags; timer->DueTime = DueTime; timer->Period = Period; timer->Callback = Callback; timer->Parameter = Parameter; timer->timerQueue = (WINPR_TIMER_QUEUE*) TimerQueue; timer->FireCount = 0; timer->next = NULL; pthread_mutex_lock(&(timerQueue->cond_mutex)); InsertTimerQueueTimer(&(timerQueue->activeHead), timer); pthread_cond_signal(&(timerQueue->cond)); pthread_mutex_unlock(&(timerQueue->cond_mutex)); return TRUE; }
HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes) { int index; HANDLE hNamedPipe = INVALID_HANDLE_VALUE; char* lpPipePath; struct sockaddr_un s; WINPR_NAMED_PIPE* pNamedPipe = NULL; int serverfd = -1; NamedPipeServerSocketEntry* baseSocket = NULL; if (!lpName) return INVALID_HANDLE_VALUE; InitWinPRPipeModule(); pNamedPipe = (WINPR_NAMED_PIPE*) calloc(1, sizeof(WINPR_NAMED_PIPE)); if (!pNamedPipe) return INVALID_HANDLE_VALUE; WINPR_HANDLE_SET_TYPE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE); if (!(pNamedPipe->name = _strdup(lpName))) goto out; if (!(pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpName))) goto out; if (!(pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpName))) goto out; pNamedPipe->dwOpenMode = dwOpenMode; pNamedPipe->dwPipeMode = dwPipeMode; pNamedPipe->nMaxInstances = nMaxInstances; pNamedPipe->nOutBufferSize = nOutBufferSize; pNamedPipe->nInBufferSize = nInBufferSize; pNamedPipe->nDefaultTimeOut = nDefaultTimeOut; pNamedPipe->dwFlagsAndAttributes = dwOpenMode; pNamedPipe->clientfd = -1; pNamedPipe->ServerMode = TRUE; ArrayList_Lock(g_NamedPipeServerSockets); for (index = 0; index < ArrayList_Count(g_NamedPipeServerSockets); index++) { baseSocket = (NamedPipeServerSocketEntry*) ArrayList_GetItem( g_NamedPipeServerSockets, index); if (!strcmp(baseSocket->name, lpName)) { serverfd = baseSocket->serverfd; //WLog_DBG(TAG, "using shared socked resource for pipe %p (%s)", pNamedPipe, lpName); break; } } /* If this is the first instance of the named pipe... */ if (serverfd == -1) { /* Create the UNIX domain socket and start listening. */ if (!(lpPipePath = GetNamedPipeUnixDomainSocketBaseFilePathA())) goto out; if (!PathFileExistsA(lpPipePath)) { CreateDirectoryA(lpPipePath, 0); UnixChangeFileMode(lpPipePath, 0xFFFF); } free(lpPipePath); if (PathFileExistsA(pNamedPipe->lpFilePath)) { DeleteFileA(pNamedPipe->lpFilePath); } if ((serverfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { WLog_ERR(TAG, "CreateNamedPipeA: socket error, %s", strerror(errno)); goto out; } ZeroMemory(&s, sizeof(struct sockaddr_un)); s.sun_family = AF_UNIX; strcpy(s.sun_path, pNamedPipe->lpFilePath); if (bind(serverfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un)) == -1) { WLog_ERR(TAG, "CreateNamedPipeA: bind error, %s", strerror(errno)); goto out; } if (listen(serverfd, 2) == -1) { WLog_ERR(TAG, "CreateNamedPipeA: listen error, %s", strerror(errno)); goto out; } UnixChangeFileMode(pNamedPipe->lpFilePath, 0xFFFF); if (!(baseSocket = (NamedPipeServerSocketEntry*) malloc(sizeof(NamedPipeServerSocketEntry)))) goto out; if (!(baseSocket->name = _strdup(lpName))) { free(baseSocket); goto out; } baseSocket->serverfd = serverfd; baseSocket->references = 0; ArrayList_Add(g_NamedPipeServerSockets, baseSocket); //WLog_DBG(TAG, "created shared socked resource for pipe %p (%s). base serverfd = %d", pNamedPipe, lpName, serverfd); } pNamedPipe->serverfd = dup(baseSocket->serverfd); //WLog_DBG(TAG, "using serverfd %d (duplicated from %d)", pNamedPipe->serverfd, baseSocket->serverfd); pNamedPipe->pfnUnrefNamedPipe = winpr_unref_named_pipe; baseSocket->references++; if (dwOpenMode & FILE_FLAG_OVERLAPPED) { #if 0 int flags = fcntl(pNamedPipe->serverfd, F_GETFL); if (flags != -1) fcntl(pNamedPipe->serverfd, F_SETFL, flags | O_NONBLOCK); #endif } hNamedPipe = (HANDLE) pNamedPipe; out: if (hNamedPipe == INVALID_HANDLE_VALUE) { if (pNamedPipe) { free((void*)pNamedPipe->name); free((void*)pNamedPipe->lpFileName); free((void*)pNamedPipe->lpFilePath); free(pNamedPipe); } if (serverfd != -1) close(serverfd); } ArrayList_Unlock(g_NamedPipeServerSockets); return hNamedPipe; }
HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes) { int status; HANDLE hNamedPipe; char* lpPipePath; unsigned long flags; struct sockaddr_un s; WINPR_NAMED_PIPE* pNamedPipe; if (!lpName) return INVALID_HANDLE_VALUE; pNamedPipe = (WINPR_NAMED_PIPE*) malloc(sizeof(WINPR_NAMED_PIPE)); hNamedPipe = (HANDLE) pNamedPipe; WINPR_HANDLE_SET_TYPE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE); pNamedPipe->name = _strdup(lpName); pNamedPipe->dwOpenMode = dwOpenMode; pNamedPipe->dwPipeMode = dwPipeMode; pNamedPipe->nMaxInstances = nMaxInstances; pNamedPipe->nOutBufferSize = nOutBufferSize; pNamedPipe->nInBufferSize = nInBufferSize; pNamedPipe->nDefaultTimeOut = nDefaultTimeOut; pNamedPipe->dwFlagsAndAttributes = dwOpenMode; pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpName); pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpName); lpPipePath = GetNamedPipeUnixDomainSocketBaseFilePathA(); if (!PathFileExistsA(lpPipePath)) CreateDirectoryA(lpPipePath, 0); free(lpPipePath); pNamedPipe->clientfd = -1; pNamedPipe->serverfd = socket(PF_LOCAL, SOCK_STREAM, 0); if (0) { flags = fcntl(pNamedPipe->serverfd, F_GETFL); flags = flags | O_NONBLOCK; fcntl(pNamedPipe->serverfd, F_SETFL, flags); } ZeroMemory(&s, sizeof(struct sockaddr_un)); s.sun_family = AF_UNIX; strcpy(s.sun_path, pNamedPipe->lpFilePath); unlink(s.sun_path); status = bind(pNamedPipe->serverfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un)); if (status == 0) { status = listen(pNamedPipe->serverfd, 2); if (status == 0) { UnixChangeFileMode(pNamedPipe->lpFilePath, 0xFFFF); } } return hNamedPipe; }
/** * http://msdn.microsoft.com/en-us/library/windows/desktop/aa363198%28v=vs.85%29.aspx * * @param lpDeviceName e.g. COM1, \\.\COM1, ... * * @param dwDesiredAccess expects GENERIC_READ | GENERIC_WRITE, a * warning message is printed otherwise. TODO: better support. * * @param dwShareMode must be zero, INVALID_HANDLE_VALUE is returned * otherwise and GetLastError() should return ERROR_SHARING_VIOLATION. * * @param lpSecurityAttributes NULL expected, a warning message is printed * otherwise. TODO: better support. * * @param dwCreationDisposition must be OPEN_EXISTING. If the * communication device doesn't exist INVALID_HANDLE_VALUE is returned * and GetLastError() returns ERROR_FILE_NOT_FOUND. * * @param dwFlagsAndAttributes zero expected, a warning message is * printed otherwise. * * @param hTemplateFile must be NULL. * * @return INVALID_HANDLE_VALUE on error. */ HANDLE CommCreateFileA(LPCSTR lpDeviceName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { CHAR devicePath[MAX_PATH]; struct stat deviceStat; WINPR_COMM* pComm = NULL; struct termios upcomingTermios; if (!CommInitialized()) return INVALID_HANDLE_VALUE; if (dwDesiredAccess != (GENERIC_READ | GENERIC_WRITE)) { CommLog_Print(WLOG_WARN, "unexpected access to the device: 0x%lX", dwDesiredAccess); } if (dwShareMode != 0) { SetLastError(ERROR_SHARING_VIOLATION); return INVALID_HANDLE_VALUE; } /* TODO: Prevents other processes from opening a file or * device if they request delete, read, or write access. */ if (lpSecurityAttributes != NULL) { CommLog_Print(WLOG_WARN, "unexpected security attributes, nLength=%lu", lpSecurityAttributes->nLength); } if (dwCreationDisposition != OPEN_EXISTING) { SetLastError(ERROR_FILE_NOT_FOUND); /* FIXME: ERROR_NOT_SUPPORTED better? */ return INVALID_HANDLE_VALUE; } if (QueryCommDevice(lpDeviceName, devicePath, MAX_PATH) <= 0) { /* SetLastError(GetLastError()); */ return INVALID_HANDLE_VALUE; } if (stat(devicePath, &deviceStat) < 0) { CommLog_Print(WLOG_WARN, "device not found %s", devicePath); SetLastError(ERROR_FILE_NOT_FOUND); return INVALID_HANDLE_VALUE; } if (!S_ISCHR(deviceStat.st_mode)) { CommLog_Print(WLOG_WARN, "bad device %s", devicePath); SetLastError(ERROR_BAD_DEVICE); return INVALID_HANDLE_VALUE; } if (dwFlagsAndAttributes != 0) { CommLog_Print(WLOG_WARN, "unexpected flags and attributes: 0x%lX", dwFlagsAndAttributes); } if (hTemplateFile != NULL) { SetLastError(ERROR_NOT_SUPPORTED); /* FIXME: other proper error? */ return INVALID_HANDLE_VALUE; } pComm = (WINPR_COMM*) calloc(1, sizeof(WINPR_COMM)); if (pComm == NULL) { SetLastError(ERROR_OUTOFMEMORY); return INVALID_HANDLE_VALUE; } WINPR_HANDLE_SET_TYPE(pComm, HANDLE_TYPE_COMM); pComm->ops = &ops; /* error_handle */ pComm->fd = open(devicePath, O_RDWR | O_NOCTTY | O_NONBLOCK); if (pComm->fd < 0) { CommLog_Print(WLOG_WARN, "failed to open device %s", devicePath); SetLastError(ERROR_BAD_DEVICE); goto error_handle; } pComm->fd_read = open(devicePath, O_RDONLY | O_NOCTTY | O_NONBLOCK); if (pComm->fd_read < 0) { CommLog_Print(WLOG_WARN, "failed to open fd_read, device: %s", devicePath); SetLastError(ERROR_BAD_DEVICE); goto error_handle; } pComm->fd_read_event = eventfd(0, EFD_NONBLOCK); /* EFD_NONBLOCK required because a read() is not always expected */ if (pComm->fd_read_event < 0) { CommLog_Print(WLOG_WARN, "failed to open fd_read_event, device: %s", devicePath); SetLastError(ERROR_BAD_DEVICE); goto error_handle; } InitializeCriticalSection(&pComm->ReadLock); pComm->fd_write = open(devicePath, O_WRONLY | O_NOCTTY | O_NONBLOCK); if (pComm->fd_write < 0) { CommLog_Print(WLOG_WARN, "failed to open fd_write, device: %s", devicePath); SetLastError(ERROR_BAD_DEVICE); goto error_handle; } pComm->fd_write_event = eventfd(0, EFD_NONBLOCK); /* EFD_NONBLOCK required because a read() is not always expected */ if (pComm->fd_write_event < 0) { CommLog_Print(WLOG_WARN, "failed to open fd_write_event, device: %s", devicePath); SetLastError(ERROR_BAD_DEVICE); goto error_handle; } InitializeCriticalSection(&pComm->WriteLock); /* can also be setup later on with _comm_setServerSerialDriver() */ pComm->serverSerialDriverId = SerialDriverUnknown; InitializeCriticalSection(&pComm->EventsLock); if (ioctl(pComm->fd, TIOCGICOUNT, &(pComm->counters)) < 0) { CommLog_Print(WLOG_WARN, "TIOCGICOUNT ioctl failed, errno=[%d] %s.", errno, strerror(errno)); CommLog_Print(WLOG_WARN, "could not read counters."); /* could not initialize counters but keep on. * * Not all drivers, especially for USB to serial * adapters (e.g. those based on pl2303), does support * this call. */ ZeroMemory(&(pComm->counters), sizeof(struct serial_icounter_struct)); } /* The binary/raw mode is required for the redirection but * only flags that are not handle somewhere-else, except * ICANON, are forced here. */ ZeroMemory(&upcomingTermios, sizeof(struct termios)); if (tcgetattr(pComm->fd, &upcomingTermios) < 0) { SetLastError(ERROR_IO_DEVICE); goto error_handle; } upcomingTermios.c_iflag &= ~(/*IGNBRK |*/ BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL /*| IXON*/); upcomingTermios.c_oflag = 0; /* <=> &= ~OPOST */ upcomingTermios.c_lflag = 0; /* <=> &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); */ /* upcomingTermios.c_cflag &= ~(CSIZE | PARENB); */ /* upcomingTermios.c_cflag |= CS8; */ /* About missing flags recommended by termios(3): * * IGNBRK and IXON, see: IOCTL_SERIAL_SET_HANDFLOW * CSIZE, PARENB and CS8, see: IOCTL_SERIAL_SET_LINE_CONTROL */ /* a few more settings required for the redirection */ upcomingTermios.c_cflag |= CLOCAL | CREAD; if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &upcomingTermios) < 0) { SetLastError(ERROR_IO_DEVICE); goto error_handle; } return (HANDLE)pComm; error_handle: if (pComm != NULL) { CloseHandle(pComm); } return INVALID_HANDLE_VALUE; }
HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { int i; char* name; int status; HANDLE hNamedPipe; struct sockaddr_un s; WINPR_NAMED_PIPE* pNamedPipe; if (!lpFileName) return INVALID_HANDLE_VALUE; if (pthread_once(&_HandleCreatorsInitialized, _HandleCreatorsInit) != 0) { SetLastError(ERROR_DLL_INIT_FAILED); return INVALID_HANDLE_VALUE; } if (_HandleCreators == NULL) { SetLastError(ERROR_DLL_INIT_FAILED); return INVALID_HANDLE_VALUE; } EnterCriticalSection(&_HandleCreatorsLock); for (i=0; _HandleCreators[i] != NULL; i++) { HANDLE_CREATOR* creator = (HANDLE_CREATOR*)_HandleCreators[i]; if (creator && creator->IsHandled(lpFileName)) { HANDLE newHandle = creator->CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); LeaveCriticalSection(&_HandleCreatorsLock); return newHandle; } } LeaveCriticalSection(&_HandleCreatorsLock); /* TODO: use of a HANDLE_CREATOR for named pipes as well */ if (!IsNamedPipeFileNameA(lpFileName)) return INVALID_HANDLE_VALUE; name = GetNamedPipeNameWithoutPrefixA(lpFileName); if (!name) return INVALID_HANDLE_VALUE; free(name); pNamedPipe = (WINPR_NAMED_PIPE*) calloc(1, sizeof(WINPR_NAMED_PIPE)); if (!pNamedPipe) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return INVALID_HANDLE_VALUE; } hNamedPipe = (HANDLE) pNamedPipe; WINPR_HANDLE_SET_TYPE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE); pNamedPipe->name = _strdup(lpFileName); if (!pNamedPipe->name) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); free(pNamedPipe); return INVALID_HANDLE_VALUE; } pNamedPipe->dwOpenMode = 0; pNamedPipe->dwPipeMode = 0; pNamedPipe->nMaxInstances = 0; pNamedPipe->nOutBufferSize = 0; pNamedPipe->nInBufferSize = 0; pNamedPipe->nDefaultTimeOut = 0; pNamedPipe->dwFlagsAndAttributes = dwFlagsAndAttributes; pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpFileName); if (!pNamedPipe->lpFileName) { free((void *)pNamedPipe->name); free(pNamedPipe); return INVALID_HANDLE_VALUE; } pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpFileName); if (!pNamedPipe->lpFilePath) { free((void *)pNamedPipe->lpFileName); free((void *)pNamedPipe->name); free(pNamedPipe); return INVALID_HANDLE_VALUE; } pNamedPipe->clientfd = socket(PF_LOCAL, SOCK_STREAM, 0); pNamedPipe->serverfd = -1; pNamedPipe->ServerMode = FALSE; ZeroMemory(&s, sizeof(struct sockaddr_un)); s.sun_family = AF_UNIX; strcpy(s.sun_path, pNamedPipe->lpFilePath); status = connect(pNamedPipe->clientfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un)); pNamedPipe->ops = &ops; if (status != 0) { close(pNamedPipe->clientfd); free((char*) pNamedPipe->name); free((char*) pNamedPipe->lpFileName); free((char*) pNamedPipe->lpFilePath); free(pNamedPipe); return INVALID_HANDLE_VALUE; } if (dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED) { #if 0 int flags = fcntl(pNamedPipe->clientfd, F_GETFL); if (flags != -1) fcntl(pNamedPipe->clientfd, F_SETFL, flags | O_NONBLOCK); #endif } return hNamedPipe; }
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) { HANDLE handle; WINPR_THREAD* thread; thread = (WINPR_THREAD*) calloc(1, sizeof(WINPR_THREAD)); if (!thread) return NULL; thread->dwStackSize = dwStackSize; thread->lpParameter = lpParameter; thread->lpStartAddress = lpStartAddress; thread->lpThreadAttributes = lpThreadAttributes; thread->ops = &ops; #if defined(WITH_DEBUG_THREADS) thread->create_stack = winpr_backtrace(20); dump_thread(thread); #endif thread->pipe_fd[0] = -1; thread->pipe_fd[1] = -1; #ifdef HAVE_EVENTFD_H thread->pipe_fd[0] = eventfd(0, EFD_NONBLOCK); if (thread->pipe_fd[0] < 0) { WLog_ERR(TAG, "failed to create thread pipe fd 0"); goto error_pipefd0; } #else if (pipe(thread->pipe_fd) < 0) { WLog_ERR(TAG, "failed to create thread pipe"); goto error_pipefd0; } { int flags = fcntl(thread->pipe_fd[0], F_GETFL); fcntl(thread->pipe_fd[0], F_SETFL, flags | O_NONBLOCK); } #endif if(pthread_mutex_init(&thread->mutex, 0) != 0) { WLog_ERR(TAG, "failed to initialize thread mutex"); goto error_mutex; } WINPR_HANDLE_SET_TYPE(thread, HANDLE_TYPE_THREAD); handle = (HANDLE) thread; if (!thread_list) { thread_list = ListDictionary_New(TRUE); if (!thread_list) { WLog_ERR(TAG, "Couldn't create global thread list"); goto error_thread_list; } thread_list->objectKey.fnObjectEquals = thread_compare; } if (!(dwCreationFlags & CREATE_SUSPENDED)) { if (!winpr_StartThread(thread)) goto error_thread_list; } else { if (!set_event(thread)) goto error_thread_list; } return handle; error_thread_list: pthread_mutex_destroy(&thread->mutex); error_mutex: if (thread->pipe_fd[1] >= 0) close(thread->pipe_fd[1]); if (thread->pipe_fd[0] >= 0) close(thread->pipe_fd[0]); error_pipefd0: free(thread); return NULL; }
BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation) { pid_t pid; int flags; int numArgs; LPSTR* pArgs; char** envp; char* filename = NULL; WINPR_THREAD* thread; WINPR_PROCESS* process; WINPR_ACCESS_TOKEN* token; LPTCH lpszEnvironmentBlock; pid = 0; envp = NULL; numArgs = 0; lpszEnvironmentBlock = NULL; pArgs = CommandLineToArgvA(lpCommandLine, &numArgs); flags = 0; token = (WINPR_ACCESS_TOKEN*) hToken; if (lpEnvironment) { envp = EnvironmentBlockToEnvpA(lpEnvironment); } else { lpszEnvironmentBlock = GetEnvironmentStrings(); envp = EnvironmentBlockToEnvpA(lpszEnvironmentBlock); } filename = FindApplicationPath(pArgs[0]); /* fork and exec */ pid = fork(); if (pid < 0) { /* fork failure */ return FALSE; } if (pid == 0) { /* child process */ #ifdef __sun closefrom(3); #else int maxfd; #ifdef F_MAXFD // on some BSD derivates maxfd = fcntl(0, F_MAXFD); #else maxfd = sysconf(_SC_OPEN_MAX); #endif int fd; for(fd=3; fd<maxfd; fd++) close(fd); #endif // __sun if (token) { if (token->GroupId) { setgid((gid_t) token->GroupId); initgroups(token->Username, (gid_t) token->GroupId); } if (token->UserId) setuid((uid_t) token->UserId); } if (execve(filename, pArgs, envp) < 0) { return FALSE; } } else { /* parent process */ } process = (WINPR_PROCESS*) malloc(sizeof(WINPR_PROCESS)); if (!process) return FALSE; ZeroMemory(process, sizeof(WINPR_PROCESS)); WINPR_HANDLE_SET_TYPE(process, HANDLE_TYPE_PROCESS); process->pid = pid; process->status = 0; process->dwExitCode = 0; thread = (WINPR_THREAD*) malloc(sizeof(WINPR_THREAD)); ZeroMemory(thread, sizeof(WINPR_THREAD)); if (!thread) return FALSE; WINPR_HANDLE_SET_TYPE(thread, HANDLE_TYPE_THREAD); thread->mainProcess = TRUE; lpProcessInformation->hProcess = (HANDLE) process; lpProcessInformation->hThread = (HANDLE) thread; lpProcessInformation->dwProcessId = (DWORD) pid; lpProcessInformation->dwThreadId = (DWORD) pid; free(filename); if (pArgs) { HeapFree(GetProcessHeap(), 0, pArgs); } if (lpszEnvironmentBlock) FreeEnvironmentStrings(lpszEnvironmentBlock); if (envp) { int i = 0; while (envp[i]) { free(envp[i]); i++; } free(envp); } return TRUE; }