Merge pull request #2244 from MartinHaimberger/mh-improveHandleHandling

improve handle handling and fix memory leak
This commit is contained in:
Martin Fleisz 2014-12-02 14:18:04 +01:00
commit 586170f38d
6 changed files with 177 additions and 29 deletions

View File

@ -2,6 +2,7 @@
# libwinpr-handle cmake build script # libwinpr-handle cmake build script
# #
# Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> # Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
# Copyright 2014 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with 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 # See the License for the specific language governing permissions and
# limitations under the License. # 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) if(${CMAKE_SYSTEM_NAME} MATCHES SunOS)
winpr_library_add(rt) winpr_library_add(rt)

View File

@ -3,6 +3,7 @@
* Handle Management * Handle Management
* *
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2014 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -127,14 +128,7 @@ BOOL CloseHandle(HANDLE hObject)
LeaveCriticalSection(&_HandleCloseCbsLock); LeaveCriticalSection(&_HandleCloseCbsLock);
if (Type == HANDLE_TYPE_PROCESS) if (Type == HANDLE_TYPE_MUTEX)
{
WINPR_PROCESS* process;
process = (WINPR_PROCESS*) Object;
free(process);
return TRUE;
}
else if (Type == HANDLE_TYPE_MUTEX)
{ {
WINPR_MUTEX* mutex; WINPR_MUTEX* mutex;
mutex = (WINPR_MUTEX*) Object; mutex = (WINPR_MUTEX*) Object;

View File

@ -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 <martin.haimberger@thincast.com>
*
* 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 <pthread.h>
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

View File

@ -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 <martin.haimberger@thincast.com>
*
* 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 <winpr/handle.h>
#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 */

View File

@ -3,6 +3,7 @@
* Process Thread Functions * Process Thread Functions
* *
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2014 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,6 +23,7 @@
#endif #endif
#include <winpr/handle.h> #include <winpr/handle.h>
#include "../handle/nonehandle.h"
#include <winpr/thread.h> #include <winpr/thread.h>
#include <fcntl.h> #include <fcntl.h>
@ -78,6 +80,9 @@
#include "../handle/handle.h" #include "../handle/handle.h"
#include "../security/security.h" #include "../security/security.h"
static HANDLE_CLOSE_CB _ProcessHandleCloseCb;
static pthread_once_t process_initialized = PTHREAD_ONCE_INIT;
char** EnvironmentBlockToEnvpA(LPCH lpszEnvironmentBlock) char** EnvironmentBlockToEnvpA(LPCH lpszEnvironmentBlock)
{ {
char* p; char* p;
@ -172,6 +177,8 @@ char* FindApplicationPath(char* application)
return filename; return filename;
} }
HANDLE CreateProcessHandle(pid_t pid);
BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags,
LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment,
@ -183,8 +190,8 @@ BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags,
LPSTR* pArgs = NULL; LPSTR* pArgs = NULL;
char** envp = NULL; char** envp = NULL;
char* filename = NULL; char* filename = NULL;
WINPR_THREAD* thread; HANDLE thread;
WINPR_PROCESS* process; HANDLE process;
WINPR_ACCESS_TOKEN* token; WINPR_ACCESS_TOKEN* token;
LPTCH lpszEnvironmentBlock; LPTCH lpszEnvironmentBlock;
BOOL ret = FALSE; BOOL ret = FALSE;
@ -273,36 +280,22 @@ BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags,
/* parent process */ /* parent process */
} }
process = (WINPR_PROCESS*) malloc(sizeof(WINPR_PROCESS)); process = CreateProcessHandle(pid);
if (!process) if (!process)
{ {
goto finish; goto finish;
} }
ZeroMemory(process, sizeof(WINPR_PROCESS)); thread = CreateNoneHandle();
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) if (!thread)
{ {
goto finish; goto finish;
} }
WINPR_HANDLE_SET_TYPE(thread, HANDLE_TYPE_THREAD); lpProcessInformation->hProcess = process;
lpProcessInformation->hThread = thread;
thread->mainProcess = TRUE;
lpProcessInformation->hProcess = (HANDLE) process;
lpProcessInformation->hThread = (HANDLE) thread;
lpProcessInformation->dwProcessId = (DWORD) pid; lpProcessInformation->dwProcessId = (DWORD) pid;
lpProcessInformation->dwThreadId = (DWORD) pid; lpProcessInformation->dwThreadId = (DWORD) pid;
@ -462,5 +455,49 @@ BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode)
return TRUE; 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 #endif

View File

@ -296,7 +296,9 @@ static void winpr_StartThread(WINPR_THREAD *thread)
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
{ {
#ifndef HAVE_EVENTFD_H
int flags; int flags;
#endif
HANDLE handle; HANDLE handle;
WINPR_THREAD* thread; WINPR_THREAD* thread;
thread = (WINPR_THREAD*) calloc(1, sizeof(WINPR_THREAD)); thread = (WINPR_THREAD*) calloc(1, sizeof(WINPR_THREAD));