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/thread/process.c b/winpr/libwinpr/thread/process.c index b7b8bef11..624904ab7 100644 --- a/winpr/libwinpr/thread/process.c +++ b/winpr/libwinpr/thread/process.c @@ -80,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; @@ -174,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, @@ -186,7 +191,7 @@ BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, char** envp = NULL; char* filename = NULL; HANDLE thread; - WINPR_PROCESS* process; + HANDLE process; WINPR_ACCESS_TOKEN* token; LPTCH lpszEnvironmentBlock; BOOL ret = FALSE; @@ -275,21 +280,13 @@ 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 = CreateNoneHandle(); if (!thread) @@ -297,7 +294,7 @@ BOOL _CreateProcessExA(HANDLE hToken, DWORD dwLogonFlags, goto finish; } - lpProcessInformation->hProcess = (HANDLE) process; + lpProcessInformation->hProcess = process; lpProcessInformation->hThread = thread; lpProcessInformation->dwProcessId = (DWORD) pid; lpProcessInformation->dwThreadId = (DWORD) pid; @@ -458,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