Пример #1
0
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)
	{
		WLog_ERR(TAG, "failed to create pipe");
		return FALSE;
	}

	pReadPipe = (WINPR_PIPE*) calloc(1, sizeof(WINPR_PIPE));
	pWritePipe = (WINPR_PIPE*) calloc(1, sizeof(WINPR_PIPE));

	if (!pReadPipe || !pWritePipe)
	{
		free(pReadPipe);
		free(pWritePipe);
		return FALSE;
	}

	pReadPipe->fd = pipe_fd[0];
	pWritePipe->fd = pipe_fd[1];
	WINPR_HANDLE_SET_TYPE_AND_MODE(pReadPipe, HANDLE_TYPE_ANONYMOUS_PIPE, WINPR_FD_READ);
	pReadPipe->ops = &ops;

	*((ULONG_PTR*) hReadPipe) = (ULONG_PTR) pReadPipe;
	WINPR_HANDLE_SET_TYPE_AND_MODE(pWritePipe, HANDLE_TYPE_ANONYMOUS_PIPE, WINPR_FD_READ);
	pWritePipe->ops = &ops;
	*((ULONG_PTR*) hWritePipe) = (ULONG_PTR) pWritePipe;
	return TRUE;
}
Пример #2
0
HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName)
{
	HANDLE handle = NULL;
	WINPR_MUTEX* mutex;

	mutex = (WINPR_MUTEX*) calloc(1, sizeof(WINPR_MUTEX));

	if (mutex)
	{
		pthread_mutexattr_t attr;
		pthread_mutexattr_init(&attr);
		pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
		pthread_mutex_init(&mutex->mutex, &attr);

		WINPR_HANDLE_SET_TYPE_AND_MODE(mutex, HANDLE_TYPE_MUTEX, WINPR_FD_READ);
		mutex->ops = &ops;

		handle = (HANDLE) mutex;

		if (bInitialOwner)
			pthread_mutex_lock(&mutex->mutex);
	}

	return handle;
}
Пример #3
0
HANDLE CreateFileDescriptorEventW(LPSECURITY_ATTRIBUTES lpEventAttributes,
                                  BOOL bManualReset, BOOL bInitialState,
                                  int FileDescriptor, ULONG mode)
{
#ifndef _WIN32
	WINPR_EVENT* event;
	HANDLE handle = NULL;
	event = (WINPR_EVENT*) calloc(1, sizeof(WINPR_EVENT));

	if (event)
	{
		event->bAttached = TRUE;
		event->bManualReset = bManualReset;
		event->pipe_fd[0] = FileDescriptor;
		event->pipe_fd[1] = -1;
		event->ops = &ops;
		WINPR_HANDLE_SET_TYPE_AND_MODE(event, HANDLE_TYPE_EVENT, mode);
		handle = (HANDLE) event;
	}

	return handle;
#else
	return NULL;
#endif
}
Пример #4
0
BOOL LogonUserA(LPCSTR lpszUsername, LPCSTR lpszDomain, LPCSTR lpszPassword,
                DWORD dwLogonType, DWORD dwLogonProvider, PHANDLE phToken)
{
    struct passwd* pw;
    WINPR_ACCESS_TOKEN* token;

    if (!lpszUsername)
        return FALSE;

    token = (WINPR_ACCESS_TOKEN*) calloc(1, sizeof(WINPR_ACCESS_TOKEN));

    if (!token)
        return FALSE;

    WINPR_HANDLE_SET_TYPE_AND_MODE(token, HANDLE_TYPE_ACCESS_TOKEN, FD_READ);

    token->ops = &ops;

    token->Username = _strdup(lpszUsername);
    if (!token->Username)
    {
        free(token);
        return FALSE;
    }

    if (lpszDomain)
    {
        token->Domain = _strdup(lpszDomain);
        if (!token->Domain)
        {
            free(token->Username);
            free(token);
            return FALSE;
        }
    }

    pw = getpwnam(lpszUsername);

    if (pw)
    {
        token->UserId = (DWORD) pw->pw_uid;
        token->GroupId = (DWORD) pw->pw_gid;
    }

    *((ULONG_PTR*) phToken) = (ULONG_PTR) token;

    return TRUE;
}
Пример #5
0
HANDLE CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState,
                    LPCSTR lpName)
{
	WINPR_EVENT* event = (WINPR_EVENT*) calloc(1, sizeof(WINPR_EVENT));

	if (lpEventAttributes)
		WLog_WARN(TAG, "%s [%s] does not support lpEventAttributes", __FUNCTION__, lpName);

	if (!event)
		return NULL;

	if (lpName)
		event->name = strdup(lpName);

	event->bAttached = FALSE;
	event->bManualReset = bManualReset;
	event->ops = &ops;
	WINPR_HANDLE_SET_TYPE_AND_MODE(event, HANDLE_TYPE_EVENT, FD_READ);

	if (!event->bManualReset)
		WLog_ERR(TAG, "auto-reset events not yet implemented");

	event->pipe_fd[0] = -1;
	event->pipe_fd[1] = -1;
#ifdef HAVE_SYS_EVENTFD_H
	event->pipe_fd[0] = eventfd(0, EFD_NONBLOCK);

	if (event->pipe_fd[0] < 0)
		goto fail;

#else

	if (pipe(event->pipe_fd) < 0)
		goto fail;

#endif

	if (bInitialState)
	{
		if (!SetEvent(event))
			goto fail;
	}

	return (HANDLE)event;
fail:
	EventCloseHandle_(event);
	return NULL;
}
Пример #6
0
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_AND_MODE(timerQueue, HANDLE_TYPE_TIMER_QUEUE, WINPR_FD_READ);
		handle = (HANDLE) timerQueue;
		timerQueue->activeHead = NULL;
		timerQueue->inactiveHead = NULL;
		timerQueue->bCancelled = FALSE;
		StartTimerQueueThread(timerQueue);
	}

	return handle;
}
Пример #7
0
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_AND_MODE(event, HANDLE_TYPE_EVENT, FD_READ);

	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);

	return (HANDLE)event;
}
Пример #8
0
static WINPR_FILE *FileHandle_New(FILE* fp)
{
	WINPR_FILE *pFile;
	char name[MAX_PATH];

	_snprintf(name, sizeof(name), "device_%d", fileno(fp));
	pFile = (WINPR_FILE*) calloc(1, sizeof(WINPR_FILE));
	if (!pFile)
	{
		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
		return NULL;
	}
	pFile->fp = fp;
	pFile->ops = &shmOps;
	pFile->lpFileName = _strdup(name);

	WINPR_HANDLE_SET_TYPE_AND_MODE(pFile, HANDLE_TYPE_FILE, WINPR_FD_READ);
	return pFile;
}
Пример #9
0
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_AND_MODE(timer, HANDLE_TYPE_TIMER, WINPR_FD_READ);
		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;
}
Пример #10
0
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_AND_MODE(timer, HANDLE_TYPE_TIMER_QUEUE_TIMER, WINPR_FD_READ);
	*((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;
}
Пример #11
0
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;

#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 (!semaphore->sem)
	{
		WLog_ERR(TAG, "failed to allocate semaphore memory");
		free(semaphore);
		return NULL;
	}
#if defined __APPLE__
	if (semaphore_create(mach_task_self(), semaphore->sem, SYNC_POLICY_FIFO, lMaximumCount) != KERN_SUCCESS)
#else
	if (sem_init(semaphore->sem, 0, lMaximumCount) == -1)
#endif
	{
		WLog_ERR(TAG, "failed to create semaphore");
		free(semaphore->sem);
		free(semaphore);
		return NULL;
	}
#endif

	WINPR_HANDLE_SET_TYPE_AND_MODE(semaphore, HANDLE_TYPE_SEMAPHORE, WINPR_FD_READ);
	handle = (HANDLE) semaphore;
	return handle;
}
Пример #12
0
static HANDLE NamedPipeClientCreateFileA(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;

	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_AND_MODE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE, WINPR_FD_READ);
	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;
}
Пример #13
0
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;

	if (!InitWinPRPipeModule())
		return INVALID_HANDLE_VALUE;

	pNamedPipe = (WINPR_NAMED_PIPE*) calloc(1, sizeof(WINPR_NAMED_PIPE));
	if (!pNamedPipe)
		return INVALID_HANDLE_VALUE;

	WINPR_HANDLE_SET_TYPE_AND_MODE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE, WINPR_FD_READ);

	pNamedPipe->serverfd = -1;
	pNamedPipe->clientfd = -1;
	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;
	pNamedPipe->ops = &namedOps;
	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))
		{
			if (!CreateDirectoryA(lpPipePath, 0))
			{
				free(lpPipePath);
				goto out;
			}
			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;

		if (ArrayList_Add(g_NamedPipeServerSockets, baseSocket) < 0)
		{
			free(baseSocket->name);
			goto out;
		}
		//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)
			NamedPipeCloseHandle(pNamedPipe);

		if (serverfd != -1)
			close(serverfd);
	}

	ArrayList_Unlock(g_NamedPipeServerSockets);
	return hNamedPipe;
}
Пример #14
0
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_AND_MODE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE, WINPR_FD_READ);
	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;
}
Пример #15
0
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;
	}

	if (pthread_mutex_init(&thread->threadIsReadyMutex, NULL) != 0)
	{
		WLog_ERR(TAG, "failed to initialize a mutex for a condition variable");
		goto error_thread_ready_mutex;
	}

	if (pthread_cond_init(&thread->threadIsReady, NULL) != 0)
	{
		WLog_ERR(TAG, "failed to initialize a condition variable");
		goto error_thread_ready;
	}

	WINPR_HANDLE_SET_TYPE_AND_MODE(thread, HANDLE_TYPE_THREAD, WINPR_FD_READ);
	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_cond_destroy(&thread->threadIsReady);
error_thread_ready:
	pthread_mutex_destroy(&thread->threadIsReadyMutex);
error_thread_ready_mutex:
	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;
}
Пример #16
0
/**
 * 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%08"PRIX32"",
		              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=%"PRIu32"",
		              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%08"PRIX32"",
		              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_AND_MODE(pComm, HANDLE_TYPE_COMM, WINPR_FD_READ);
	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;
}
Пример #17
0
static HANDLE FileCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
				  DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
	WINPR_FILE* pFile;
	BOOL create;
	const char* mode = FileGetMode(dwDesiredAccess, dwCreationDisposition, &create);
	int lock = 0;
	FILE* fp = NULL;

	pFile = (WINPR_FILE*) calloc(1, sizeof(WINPR_FILE));
	if (!pFile)
	{
		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
		return INVALID_HANDLE_VALUE;
	}

	WINPR_HANDLE_SET_TYPE_AND_MODE(pFile, HANDLE_TYPE_FILE, WINPR_FD_READ);
	pFile->ops = &fileOps;

	pFile->lpFileName = _strdup(lpFileName);
	if (!pFile->lpFileName)
	{
		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
		free(pFile);
		return INVALID_HANDLE_VALUE;
	}

	pFile->dwOpenMode = dwDesiredAccess;
	pFile->dwShareMode = dwShareMode;
	pFile->dwFlagsAndAttributes = dwFlagsAndAttributes;
	pFile->lpSecurityAttributes = lpSecurityAttributes;
	pFile->dwCreationDisposition = dwCreationDisposition;
	pFile->hTemplateFile = hTemplateFile;

	if (create)
	{
		fp = fopen(pFile->lpFileName, "ab");
		if (!fp)
		{
			free(pFile->lpFileName);
			free(pFile);
			return INVALID_HANDLE_VALUE;
		}

		fp = freopen(pFile->lpFileName, mode, fp);
	}

	if (NULL == fp)
		fp = fopen(pFile->lpFileName, mode);

	pFile->fp = fp;
	if (!pFile->fp)
	{
		/* This case can occur when trying to open a
		 * not existing file without create flag. */
		free(pFile->lpFileName);
		free(pFile);
		return INVALID_HANDLE_VALUE;
	}

	setvbuf(fp, NULL, _IONBF, 0);

	if (dwShareMode & FILE_SHARE_READ)
		lock = LOCK_SH;
	if (dwShareMode & FILE_SHARE_WRITE)
		lock = LOCK_EX;

	if (dwShareMode & (FILE_SHARE_READ | FILE_SHARE_WRITE))
	{
		if (flock(fileno(pFile->fp), lock) < 0)
		{
			WLog_ERR(TAG, "flock failed with %s [%08X]",
				 strerror(errno), errno);
			FileCloseHandle(pFile);
			return INVALID_HANDLE_VALUE;
		}

		pFile->bLocked = TRUE;
	}

	return pFile;
}