diff --git a/winpr/libwinpr/handle/CMakeLists.txt b/winpr/libwinpr/handle/CMakeLists.txt index d58ff5a37..09ea2f13d 100644 --- a/winpr/libwinpr/handle/CMakeLists.txt +++ b/winpr/libwinpr/handle/CMakeLists.txt @@ -2,6 +2,7 @@ # libwinpr-handle cmake build script # # Copyright 2012 Marc-Andre Moreau +# Copyright 2014 DI (FH) Martin Haimberger # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,7 +16,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -winpr_module_add(handle.c handle.h) +winpr_module_add(handle.c handle.h nonehandle.c nonehandle.h) if(${CMAKE_SYSTEM_NAME} MATCHES SunOS) winpr_library_add(rt) diff --git a/winpr/libwinpr/handle/handle.c b/winpr/libwinpr/handle/handle.c index ff02aea9b..5f236ca17 100644 --- a/winpr/libwinpr/handle/handle.c +++ b/winpr/libwinpr/handle/handle.c @@ -3,6 +3,7 @@ * Handle Management * * Copyright 2012 Marc-Andre Moreau + * Copyright 2014 DI (FH) Martin Haimberger * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -127,14 +128,7 @@ BOOL CloseHandle(HANDLE hObject) LeaveCriticalSection(&_HandleCloseCbsLock); - if (Type == HANDLE_TYPE_PROCESS) - { - WINPR_PROCESS* process; - process = (WINPR_PROCESS*) Object; - free(process); - return TRUE; - } - else if (Type == HANDLE_TYPE_MUTEX) + if (Type == HANDLE_TYPE_MUTEX) { WINPR_MUTEX* mutex; mutex = (WINPR_MUTEX*) Object; diff --git a/winpr/libwinpr/handle/nonehandle.c b/winpr/libwinpr/handle/nonehandle.c new file mode 100644 index 000000000..5a8b2be11 --- /dev/null +++ b/winpr/libwinpr/handle/nonehandle.c @@ -0,0 +1,74 @@ +/** + * WinPR: Windows Portable Runtime + * NoneHandle a.k.a. brathandle should be used where a handle is needed, but + * functionality is not implemented yet or not implementable. + * + * Copyright 2014 DI (FH) Martin Haimberger + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "nonehandle.h" + +#ifndef _WIN32 + +#include + +static HANDLE_CLOSE_CB _NoneHandleCloseCb; +static pthread_once_t none_initialized = PTHREAD_ONCE_INIT; + +static BOOL NoneHandleCloseHandle(HANDLE handle) +{ + WINPR_NONE_HANDLE* none = (WINPR_NONE_HANDLE*) handle; + free(none); + return TRUE; +} + +static BOOL NoneHandleIsHandle(HANDLE handle) +{ + WINPR_NONE_HANDLE* none = (WINPR_NONE_HANDLE*) handle; + + if (!none || none->Type != HANDLE_TYPE_NONE) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + return TRUE; +} + +static void NoneHandleInitialize(void) +{ + _NoneHandleCloseCb.IsHandled = NoneHandleIsHandle; + _NoneHandleCloseCb.CloseHandle = NoneHandleCloseHandle; + RegisterHandleCloseCb(&_NoneHandleCloseCb); +} + +HANDLE CreateNoneHandle() +{ + WINPR_NONE_HANDLE* none; + none = (WINPR_NONE_HANDLE*) calloc(1, sizeof(WINPR_NONE_HANDLE)); + + if (!none) + return NULL; + + pthread_once(&none_initialized, NoneHandleInitialize); + + return (HANDLE)none; +} + +#endif diff --git a/winpr/libwinpr/handle/nonehandle.h b/winpr/libwinpr/handle/nonehandle.h new file mode 100644 index 000000000..1aa509888 --- /dev/null +++ b/winpr/libwinpr/handle/nonehandle.h @@ -0,0 +1,40 @@ +/** + * WinPR: Windows Portable Runtime + * NoneHandle a.k.a. brathandle should be used where a handle is needed, but + * functionality is not implemented yet or not implementable. + * + * Copyright 2014 DI (FH) Martin Haimberger + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_NONE_HANDLE_PRIVATE_H +#define WINPR_NONE_HANDLE_PRIVATE_H + +#ifndef _WIN32 + +#include +#include "handle.h" + +struct winpr_none_handle +{ + WINPR_HANDLE_DEF(); +}; + +typedef struct winpr_none_handle WINPR_NONE_HANDLE; + +HANDLE CreateNoneHandle(); + +#endif /*_WIN32*/ + +#endif /* WINPR_NONE_HANDLE_PRIVATE_H */ diff --git a/winpr/libwinpr/thread/process.c b/winpr/libwinpr/thread/process.c index 4f5adc026..624904ab7 100644 --- a/winpr/libwinpr/thread/process.c +++ b/winpr/libwinpr/thread/process.c @@ -3,6 +3,7 @@ * Process Thread Functions * * Copyright 2012 Marc-Andre Moreau + * Copyright 2014 DI (FH) Martin Haimberger * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +23,7 @@ #endif #include +#include "../handle/nonehandle.h" #include #include @@ -78,6 +80,9 @@ #include "../handle/handle.h" #include "../security/security.h" +static HANDLE_CLOSE_CB _ProcessHandleCloseCb; +static pthread_once_t process_initialized = PTHREAD_ONCE_INIT; + char** EnvironmentBlockToEnvpA(LPCH lpszEnvironmentBlock) { char* p; @@ -172,6 +177,8 @@ char* FindApplicationPath(char* application) return filename; } +HANDLE CreateProcessHandle(pid_t pid); + BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, @@ -183,8 +190,8 @@ BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, LPSTR* pArgs = NULL; char** envp = NULL; char* filename = NULL; - WINPR_THREAD* thread; - WINPR_PROCESS* process; + HANDLE thread; + HANDLE process; WINPR_ACCESS_TOKEN* token; LPTCH lpszEnvironmentBlock; BOOL ret = FALSE; @@ -273,36 +280,22 @@ BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, /* parent process */ } - process = (WINPR_PROCESS*) malloc(sizeof(WINPR_PROCESS)); + process = CreateProcessHandle(pid); if (!process) { goto finish; } - 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)); + thread = CreateNoneHandle(); if (!thread) { goto finish; } - WINPR_HANDLE_SET_TYPE(thread, HANDLE_TYPE_THREAD); - - thread->mainProcess = TRUE; - - lpProcessInformation->hProcess = (HANDLE) process; - lpProcessInformation->hThread = (HANDLE) thread; + lpProcessInformation->hProcess = process; + lpProcessInformation->hThread = thread; lpProcessInformation->dwProcessId = (DWORD) pid; lpProcessInformation->dwThreadId = (DWORD) pid; @@ -462,5 +455,49 @@ BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode) return TRUE; } + +static BOOL ProcessHandleCloseHandle(HANDLE handle) +{ + WINPR_PROCESS* process = (WINPR_PROCESS*) handle; + free(process); + return TRUE; +} + +static BOOL ProcessHandleIsHandle(HANDLE handle) +{ + WINPR_PROCESS* process = (WINPR_PROCESS*) handle; + + if (!process || process->Type != HANDLE_TYPE_PROCESS) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + return TRUE; +} + +static void ProcessHandleInitialize(void) +{ + _ProcessHandleCloseCb.IsHandled = ProcessHandleIsHandle; + _ProcessHandleCloseCb.CloseHandle = ProcessHandleCloseHandle; + RegisterHandleCloseCb(&_ProcessHandleCloseCb); +} + +HANDLE CreateProcessHandle(pid_t pid) +{ + WINPR_PROCESS* process; + process = (WINPR_PROCESS*) calloc(1, sizeof(WINPR_PROCESS)); + + if (!process) + return NULL; + + pthread_once(&process_initialized, ProcessHandleInitialize); + process->pid = pid; + process->Type = HANDLE_TYPE_PROCESS; + + return (HANDLE)process; +} + + #endif diff --git a/winpr/libwinpr/thread/thread.c b/winpr/libwinpr/thread/thread.c index 7ff53214d..30d8580e4 100644 --- a/winpr/libwinpr/thread/thread.c +++ b/winpr/libwinpr/thread/thread.c @@ -296,7 +296,9 @@ static void winpr_StartThread(WINPR_THREAD *thread) HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) { + #ifndef HAVE_EVENTFD_H int flags; + #endif HANDLE handle; WINPR_THREAD* thread; thread = (WINPR_THREAD*) calloc(1, sizeof(WINPR_THREAD));