channels/rdpdr/disk: replace thread utils by WinPR thread API

This commit is contained in:
Marc-André Moreau 2012-09-23 13:54:14 -04:00
parent 90ffa6ea86
commit a11a69c70f
11 changed files with 264 additions and 115 deletions

View File

@ -17,20 +17,24 @@
# See the License for the specific language governing permissions and
# limitations under the License.
set(DISK_SRCS
set(MODULE_NAME "disk")
set(MODULE_PREFIX "CHANNEL_DEVICE_DISK")
set(${MODULE_PREFIX}_SRCS
disk_file.c
disk_file.h
disk_main.c)
include_directories(..)
add_library(disk ${DISK_SRCS})
set_target_properties(disk PROPERTIES PREFIX "")
add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
if(WITH_MONOLITHIC_BUILD)
target_link_libraries(disk freerdp)
set(${MODULE_PREFIX}_LIBS freerdp winpr)
else()
target_link_libraries(disk freerdp-utils)
set(${MODULE_PREFIX}_LIBS freerdp-utils winpr-synch winpr-thread)
endif()
install(TARGETS disk DESTINATION ${FREERDP_PLUGIN_PATH})
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})

View File

@ -39,14 +39,17 @@
#include <freerdp/utils/stream.h>
#include <freerdp/utils/unicode.h>
#include <freerdp/utils/list.h>
#include <freerdp/utils/thread.h>
#include <freerdp/utils/svc_plugin.h>
#include <winpr/synch.h>
#include <winpr/thread.h>
#include "rdpdr_constants.h"
#include "rdpdr_types.h"
#include "disk_file.h"
typedef struct _DISK_DEVICE DISK_DEVICE;
struct _DISK_DEVICE
{
DEVICE device;
@ -54,15 +57,17 @@ struct _DISK_DEVICE
char* path;
LIST* files;
HANDLE mutex;
HANDLE thread;
LIST* irp_list;
freerdp_thread* thread;
HANDLE irpEvent;
HANDLE stopEvent;
DEVMAN* devman;
pcRegisterDevice UnregisterDevice;
};
static uint32
disk_map_posix_err(int fs_errno)
static uint32 disk_map_posix_err(int fs_errno)
{
uint32 rc;
@ -90,7 +95,9 @@ disk_map_posix_err(int fs_errno)
rc = STATUS_UNSUCCESSFUL;
break;
}
DEBUG_SVC("errno 0x%x mapped to 0x%x", fs_errno, rc);
return rc;
}
@ -101,7 +108,8 @@ static DISK_FILE* disk_get_file_by_id(DISK_DEVICE* disk, uint32 id)
for (item = disk->files->head; item; item = item->next)
{
file = (DISK_FILE*)item->data;
file = (DISK_FILE*) item->data;
if (file->id == id)
return file;
}
@ -238,7 +246,7 @@ static void disk_process_irp_read(DISK_DEVICE* disk, IRP* irp)
}
else
{
buffer = (uint8*)xmalloc(Length);
buffer = (uint8*) xmalloc(Length);
if (!disk_file_read(file, buffer, &Length))
{
irp->IoStatus = STATUS_UNSUCCESSFUL;
@ -255,11 +263,13 @@ static void disk_process_irp_read(DISK_DEVICE* disk, IRP* irp)
}
stream_write_uint32(irp->output, Length);
if (Length > 0)
{
stream_check_size(irp->output, Length);
stream_write(irp->output, buffer, Length);
}
xfree(buffer);
irp->Complete(irp);
@ -379,8 +389,8 @@ static void disk_process_irp_query_volume_information(DISK_DEVICE* disk, IRP* ir
struct STATVFS svfst;
struct STAT st;
UNICONV* uniconv;
char *volumeLabel = {"FREERDP"}; /* TODO:: Add sub routine to correctly pick up Volume Label name for each O/S supported*/
char *diskType = {"FAT32"};
char* volumeLabel = {"FREERDP"}; /* TODO: Add sub routine to correctly pick up Volume Label name for each O/S supported */
char* diskType = {"FAT32"};
char* outStr;
size_t len;
@ -581,12 +591,14 @@ static void disk_process_irp_list(DISK_DEVICE* disk)
while (1)
{
if (freerdp_thread_is_stopped(disk->thread))
if (WaitForSingleObject(disk->stopEvent, 0) == WAIT_OBJECT_0)
break;
freerdp_thread_lock(disk->thread);
irp = (IRP*)list_dequeue(disk->irp_list);
freerdp_thread_unlock(disk->thread);
WaitForSingleObject(disk->mutex, INFINITE);
irp = (IRP*) list_dequeue(disk->irp_list);
ReleaseMutex(disk->mutex);
if (irp == NULL)
break;
@ -597,63 +609,65 @@ static void disk_process_irp_list(DISK_DEVICE* disk)
static void* disk_thread_func(void* arg)
{
DISK_DEVICE* disk = (DISK_DEVICE*)arg;
DISK_DEVICE* disk = (DISK_DEVICE*) arg;
while (1)
{
freerdp_thread_wait(disk->thread);
WaitForSingleObject(disk->irpEvent, INFINITE);
if (freerdp_thread_is_stopped(disk->thread))
if (WaitForSingleObject(disk->stopEvent, 0) == WAIT_OBJECT_0)
break;
freerdp_thread_reset(disk->thread);
ResetEvent(disk->irpEvent);
disk_process_irp_list(disk);
}
freerdp_thread_quit(disk->thread);
return NULL;
}
static void disk_irp_request(DEVICE* device, IRP* irp)
{
DISK_DEVICE* disk = (DISK_DEVICE*)device;
DISK_DEVICE* disk = (DISK_DEVICE*) device;
freerdp_thread_lock(disk->thread);
WaitForSingleObject(disk->mutex, INFINITE);
list_enqueue(disk->irp_list, irp);
freerdp_thread_unlock(disk->thread);
ReleaseMutex(disk->mutex);
freerdp_thread_signal(disk->thread);
SetEvent(disk->irpEvent);
}
static void disk_free(DEVICE* device)
{
DISK_DEVICE* disk = (DISK_DEVICE*)device;
IRP* irp;
DISK_FILE* file;
DISK_DEVICE* disk = (DISK_DEVICE*) device;
freerdp_thread_stop(disk->thread);
freerdp_thread_free(disk->thread);
SetEvent(disk->stopEvent);
CloseHandle(disk->thread);
CloseHandle(disk->irpEvent);
CloseHandle(disk->mutex);
while ((irp = (IRP*)list_dequeue(disk->irp_list)) != NULL)
while ((irp = (IRP*) list_dequeue(disk->irp_list)) != NULL)
irp->Discard(irp);
list_free(disk->irp_list);
while ((file = (DISK_FILE*)list_dequeue(disk->files)) != NULL)
while ((file = (DISK_FILE*) list_dequeue(disk->files)) != NULL)
disk_file_free(file);
list_free(disk->files);
xfree(disk);
}
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
{
DISK_DEVICE* disk;
char* name;
char* path;
int i, len;
DISK_DEVICE* disk;
name = (char*)pEntryPoints->plugin_data->data[1];
path = (char*)pEntryPoints->plugin_data->data[2];
name = (char*) pEntryPoints->plugin_data->data[1];
path = (char*) pEntryPoints->plugin_data->data[2];
if (name[0] && path[0])
{
@ -666,6 +680,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
len = strlen(name);
disk->device.data = stream_new(len + 1);
for (i = 0; i <= len; i++)
stream_write_uint8(disk->device.data, name[i] < 0 ? '_' : name[i]);
@ -673,11 +688,14 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
disk->files = list_new();
disk->irp_list = list_new();
disk->thread = freerdp_thread_new();
disk->mutex = CreateMutex(NULL, FALSE, NULL);
disk->irpEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
disk->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
disk->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) disk_thread_func, disk, CREATE_SUSPENDED, NULL);
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)disk);
pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) disk);
freerdp_thread_start(disk->thread, disk_thread_func, disk);
ResumeThread(disk->thread);
}
return 0;

View File

@ -235,11 +235,11 @@ static boolean rdpdr_process_irp(rdpdrPlugin* rdpdr, STREAM* data_in)
static void rdpdr_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
{
rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin;
uint16 component;
uint16 packetID;
uint32 deviceID;
uint32 status;
rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin;
stream_read_uint16(data_in, component);
stream_read_uint16(data_in, packetID);

View File

@ -37,33 +37,34 @@
#include "scard_main.h"
static void
scard_free(DEVICE* dev)
static void scard_free(DEVICE* dev)
{
SCARD_DEVICE* scard = (SCARD_DEVICE*)dev;
IRP* irp;
COMPLETIONIDINFO* CompletionIdInfo;
SCARD_DEVICE* scard = (SCARD_DEVICE*) dev;
freerdp_thread_stop(scard->thread);
freerdp_thread_free(scard->thread);
while ((irp = (IRP*)list_dequeue(scard->irp_list)) != NULL)
while ((irp = (IRP*) list_dequeue(scard->irp_list)) != NULL)
irp->Discard(irp);
list_free(scard->irp_list);
/* Begin TS Client defect workaround. */
while ((CompletionIdInfo = (COMPLETIONIDINFO*)list_dequeue(scard->CompletionIds)) != NULL)
while ((CompletionIdInfo = (COMPLETIONIDINFO*) list_dequeue(scard->CompletionIds)) != NULL)
xfree(CompletionIdInfo);
list_free(scard->CompletionIds);
/* End TS Client defect workaround. */
xfree(dev);
return;
}
static void
scard_process_irp(SCARD_DEVICE* scard, IRP* irp)
static void scard_process_irp(SCARD_DEVICE* scard, IRP* irp)
{
switch (irp->MajorFunction)
{
@ -80,16 +81,14 @@ scard_process_irp(SCARD_DEVICE* scard, IRP* irp)
}
}
static void
scard_process_irp_list(SCARD_DEVICE* scard)
static void scard_process_irp_list(SCARD_DEVICE* scard)
{
IRP *irp;
IRP* irp;
while (!freerdp_thread_is_stopped(scard->thread))
{
freerdp_thread_lock(scard->thread);
irp = (IRP *) list_dequeue(scard->irp_list);
irp = (IRP*) list_dequeue(scard->irp_list);
freerdp_thread_unlock(scard->thread);
if (irp == NULL)
@ -99,16 +98,14 @@ scard_process_irp_list(SCARD_DEVICE* scard)
}
}
struct scard_irp_thread_args {
struct scard_irp_thread_args
{
SCARD_DEVICE* scard;
IRP* irp;
freerdp_thread* thread;
};
static void
scard_process_irp_thread_func(struct scard_irp_thread_args* args)
static void scard_process_irp_thread_func(struct scard_irp_thread_args* args)
{
scard_process_irp(args->scard, args->irp);
@ -116,9 +113,7 @@ scard_process_irp_thread_func(struct scard_irp_thread_args* args)
xfree(args);
}
static void *
scard_thread_func(void* arg)
static void* scard_thread_func(void* arg)
{
SCARD_DEVICE* scard = (SCARD_DEVICE*) arg;
@ -138,16 +133,14 @@ scard_thread_func(void* arg)
return NULL;
}
/* Begin TS Client defect workaround. */
static COMPLETIONIDINFO*
scard_mark_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
static COMPLETIONIDINFO* scard_mark_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
{
/*
* Search from the beginning of the LIST for one outstanding "CompletionID"
* that matches the one passed in. If there is one, mark it as a duplicate
* if it is not already marked.
*/
/*
* Search from the beginning of the LIST for one outstanding "CompletionID"
* that matches the one passed in. If there is one, mark it as a duplicate
* if it is not already marked.
*/
LIST_ITEM* item;
COMPLETIONIDINFO* CompletionIdInfo;
@ -164,18 +157,18 @@ scard_mark_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
return CompletionIdInfo;
}
}
return NULL; /* Either no items in the list or no match. */
}
static boolean
scard_check_for_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
static boolean scard_check_for_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
{
/*
* Search from the end of the LIST for one outstanding "CompletionID"
* that matches the one passed in. Remove it from the list and free the
* memory associated with it. Return whether or not it was marked
* as a duplicate.
*/
/*
* Search from the end of the LIST for one outstanding "CompletionID"
* that matches the one passed in. Remove it from the list and free the
* memory associated with it. Return whether or not it was marked
* as a duplicate.
*/
LIST_ITEM* item;
COMPLETIONIDINFO* CompletionIdInfo;
boolean duplicate;
@ -195,21 +188,22 @@ scard_check_for_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
return duplicate;
}
}
/* This function should only be called when there is
* at least one outstanding CompletionID item in the list.
*/
DEBUG_WARN("Error!!! No CompletionIDs (or no matching IDs) in the list!");
return false;
}
static void
scard_irp_complete(IRP* irp)
static void scard_irp_complete(IRP* irp)
{
/* This function is (mostly) a copy of the statically-declared "irp_complete()"
* function except that this function adds extra operations for the
* smart card's handling of duplicate "CompletionID"s. This function needs
* to be in this file so that "scard_irp_request()" can reference it.
*/
/* This function is (mostly) a copy of the statically-declared "irp_complete()"
* function except that this function adds extra operations for the
* smart card's handling of duplicate "CompletionID"s. This function needs
* to be in this file so that "scard_irp_request()" can reference it.
*/
int pos;
boolean duplicate;
SCARD_DEVICE* scard = (SCARD_DEVICE*)irp->device;
@ -247,13 +241,10 @@ scard_irp_complete(IRP* irp)
}
/* End TS Client defect workaround. */
static void
scard_irp_request(DEVICE* device, IRP* irp)
static void scard_irp_request(DEVICE* device, IRP* irp)
{
COMPLETIONIDINFO* CompletionIdInfo;
SCARD_DEVICE* scard = (SCARD_DEVICE*)device;
SCARD_DEVICE* scard = (SCARD_DEVICE*) device;
/* Begin TS Client defect workaround. */
CompletionIdInfo= xnew(COMPLETIONIDINFO);

View File

@ -110,9 +110,11 @@ static rdpSvcPlugin* svc_plugin_find_by_open_handle(uint32 open_handle)
rdpSvcPlugin * plugin;
WaitForSingleObject(g_mutex, INFINITE);
for (list = g_svc_plugin_list; list; list = list->next)
{
plugin = list->plugin;
if (plugin->priv->open_handle == open_handle)
{
ReleaseMutex(g_mutex);
@ -120,6 +122,7 @@ static rdpSvcPlugin* svc_plugin_find_by_open_handle(uint32 open_handle)
}
}
ReleaseMutex(g_mutex);
return NULL;
}
@ -215,22 +218,26 @@ static void svc_plugin_open_event(uint32 openHandle, uint32 event, void* pData,
DEBUG_SVC("openHandle %d event %d dataLength %d totalLength %d dataFlags %d",
openHandle, event, dataLength, totalLength, dataFlags);
plugin = (rdpSvcPlugin*)svc_plugin_find_by_open_handle(openHandle);
plugin = (rdpSvcPlugin*) svc_plugin_find_by_open_handle(openHandle);
if (plugin == NULL)
{
printf("svc_plugin_open_event: error no match\n");
return;
}
switch (event)
{
case CHANNEL_EVENT_DATA_RECEIVED:
svc_plugin_process_received(plugin, pData, dataLength, totalLength, dataFlags);
break;
case CHANNEL_EVENT_WRITE_COMPLETE:
stream_free((STREAM*)pData);
stream_free((STREAM*) pData);
break;
case CHANNEL_EVENT_USER:
svc_plugin_process_event(plugin, (RDP_EVENT*)pData);
svc_plugin_process_event(plugin, (RDP_EVENT*) pData);
break;
}
}
@ -347,19 +354,23 @@ static void svc_plugin_init_event(void* pInitHandle, uint32 event, void* pData,
DEBUG_SVC("event %d", event);
plugin = (rdpSvcPlugin*)svc_plugin_find_by_init_handle(pInitHandle);
if (plugin == NULL)
plugin = (rdpSvcPlugin*) svc_plugin_find_by_init_handle(pInitHandle);
if (!plugin)
{
printf("svc_plugin_init_event: error no match\n");
return;
}
switch (event)
{
case CHANNEL_EVENT_CONNECTED:
svc_plugin_process_connected(plugin, pData, dataLength);
break;
case CHANNEL_EVENT_DISCONNECTED:
break;
case CHANNEL_EVENT_TERMINATED:
svc_plugin_process_terminated(plugin);
break;
@ -402,6 +413,7 @@ int svc_plugin_send(rdpSvcPlugin* plugin, STREAM* data_out)
error = plugin->channel_entry_points.pVirtualChannelWrite(plugin->priv->open_handle,
stream_get_data(data_out), stream_get_length(data_out), data_out);
if (error != CHANNEL_RC_OK)
{
stream_free(data_out);

View File

@ -85,6 +85,16 @@ WINPR_API HANDLE OpenEventW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR
WINPR_API BOOL SetEvent(HANDLE hEvent);
WINPR_API BOOL ResetEvent(HANDLE hEvent);
#ifdef UNICODE
#define CreateEvent CreateEventW
#define CreateEventEx CreateEventExW
#define OpenEvent OpenEventW
#else
#define CreateEvent CreateEventA
#define CreateEventEx CreateEventExA
#define OpenEvent OpenEventA
#endif
/* One-Time Initialization */
typedef union _RTL_RUN_ONCE

View File

@ -114,12 +114,15 @@ WINPR_API BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode);
/* Thread */
WINPR_API HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);
#define CREATE_SUSPENDED 0x00000004
#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
WINPR_API HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
WINPR_API HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
WINPR_API VOID ExitThread(DWORD dwExitCode);
WINPR_API HANDLE GetCurrentThread(VOID);

View File

@ -26,6 +26,10 @@
#ifndef _WIN32
#include <pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
typedef struct _HANDLE_TABLE_ENTRY
{
ULONG Type;
@ -49,33 +53,49 @@ void winpr_HandleTable_New()
{
size_t size;
HandleTable.Count = 0;
HandleTable.MaxCount = 64;
pthread_mutex_lock(&mutex);
size = sizeof(HANDLE_TABLE_ENTRY) * HandleTable.MaxCount;
if (HandleTable.MaxCount < 1)
{
HandleTable.Count = 0;
HandleTable.MaxCount = 64;
HandleTable.Entries = (PHANDLE_TABLE_ENTRY) malloc(size);
ZeroMemory(HandleTable.Entries, size);
size = sizeof(HANDLE_TABLE_ENTRY) * HandleTable.MaxCount;
HandleTable.Entries = (PHANDLE_TABLE_ENTRY) malloc(size);
ZeroMemory(HandleTable.Entries, size);
}
pthread_mutex_unlock(&mutex);
}
void winpr_HandleTable_Grow()
{
size_t size;
pthread_mutex_lock(&mutex);
HandleTable.MaxCount *= 2;
size = sizeof(HANDLE_TABLE_ENTRY) * HandleTable.MaxCount;
HandleTable.Entries = (PHANDLE_TABLE_ENTRY) realloc(HandleTable.Entries, size);
ZeroMemory((void*) &HandleTable.Entries[HandleTable.MaxCount / 2], size / 2);
pthread_mutex_unlock(&mutex);
}
void winpr_HandleTable_Free()
{
pthread_mutex_lock(&mutex);
HandleTable.Count = 0;
HandleTable.MaxCount = 0;
free(HandleTable.Entries);
HandleTable.Entries = NULL;
pthread_mutex_unlock(&mutex);
}
HANDLE winpr_Handle_Insert(ULONG Type, PVOID Object)
@ -84,6 +104,8 @@ HANDLE winpr_Handle_Insert(ULONG Type, PVOID Object)
HandleTable_GetInstance();
pthread_mutex_lock(&mutex);
for (index = 0; index < (int) HandleTable.MaxCount; index++)
{
if (HandleTable.Entries[index].Object == NULL)
@ -93,10 +115,14 @@ HANDLE winpr_Handle_Insert(ULONG Type, PVOID Object)
HandleTable.Entries[index].Type = Type;
HandleTable.Entries[index].Object = Object;
pthread_mutex_unlock(&mutex);
return Object;
}
}
pthread_mutex_unlock(&mutex);
/* no available entry was found, the table needs to be grown */
winpr_HandleTable_Grow();
@ -112,6 +138,8 @@ BOOL winpr_Handle_Remove(HANDLE handle)
HandleTable_GetInstance();
pthread_mutex_lock(&mutex);
for (index = 0; index < (int) HandleTable.MaxCount; index++)
{
if (HandleTable.Entries[index].Object == handle)
@ -120,10 +148,14 @@ BOOL winpr_Handle_Remove(HANDLE handle)
HandleTable.Entries[index].Object = NULL;
HandleTable.Count--;
pthread_mutex_unlock(&mutex);
return TRUE;
}
}
pthread_mutex_unlock(&mutex);
return FALSE;
}
@ -133,12 +165,19 @@ ULONG winpr_Handle_GetType(HANDLE handle)
HandleTable_GetInstance();
pthread_mutex_lock(&mutex);
for (index = 0; index < (int) HandleTable.MaxCount; index++)
{
if (HandleTable.Entries[index].Object == handle)
{
pthread_mutex_unlock(&mutex);
return HandleTable.Entries[index].Type;
}
}
pthread_mutex_unlock(&mutex);
return HANDLE_TYPE_NONE;
}
@ -155,16 +194,23 @@ BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObject)
HandleTable_GetInstance();
pthread_mutex_lock(&mutex);
for (index = 0; index < (int) HandleTable.MaxCount; index++)
{
if (HandleTable.Entries[index].Object == handle)
{
*pType = HandleTable.Entries[index].Type;
*pObject = HandleTable.Entries[index].Object;
pthread_mutex_unlock(&mutex);
return TRUE;
}
}
pthread_mutex_unlock(&mutex);
return FALSE;
}

View File

@ -49,7 +49,7 @@ HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset,
event = (WINPR_EVENT*) malloc(sizeof(WINPR_EVENT));
if (!event)
if (event)
{
event->bManualReset = bManualReset;
@ -63,6 +63,7 @@ HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset,
if (pipe(event->pipe_fd) < 0)
{
printf("CreateEventW: failed to create event\n");
return NULL;
}

View File

@ -74,7 +74,7 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
FD_SET(event->pipe_fd[0], &rfds);
ZeroMemory(&timeout, sizeof(timeout));
if (dwMilliseconds != INFINITE)
if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0))
{
timeout.tv_usec = dwMilliseconds * 1000;
}

View File

@ -67,6 +67,8 @@
#ifndef _WIN32
#include <winpr/crt.h>
#include <pthread.h>
/**
@ -76,37 +78,68 @@
typedef void *(*pthread_start_routine)(void*);
HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId)
struct winpr_thread
{
return NULL;
BOOL started;
pthread_t thread;
SIZE_T dwStackSize;
LPVOID lpParameter;
pthread_mutex_t mutex;
LPTHREAD_START_ROUTINE lpStartAddress;
LPSECURITY_ATTRIBUTES lpThreadAttributes;
};
typedef struct winpr_thread WINPR_THREAD;
void winpr_StartThread(WINPR_THREAD* thread)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (thread->dwStackSize > 0)
pthread_attr_setstacksize(&attr, (size_t) thread->dwStackSize);
thread->started = TRUE;
pthread_create(&thread->thread, &attr, (pthread_start_routine) thread->lpStartAddress, thread->lpParameter);
pthread_attr_destroy(&attr);
}
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
{
HANDLE handle;
pthread_t thread;
pthread_attr_t attr;
WINPR_THREAD* thread;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
thread = (WINPR_THREAD*) malloc(sizeof(WINPR_THREAD));
ZeroMemory(thread, sizeof(WINPR_THREAD));
if (dwStackSize > 0)
pthread_attr_setstacksize(&attr, (size_t) dwStackSize);
thread->started = FALSE;
thread->dwStackSize = dwStackSize;
thread->lpParameter = lpParameter;
thread->lpStartAddress = lpStartAddress;
thread->lpThreadAttributes = lpThreadAttributes;
pthread_create(&thread, &attr, (pthread_start_routine) lpStartAddress, lpParameter);
pthread_mutex_init(&thread->mutex, 0);
handle = winpr_Handle_Insert(HANDLE_TYPE_THREAD, (void*) thread);
pthread_attr_destroy(&attr);
if (!(dwCreationFlags & CREATE_SUSPENDED))
winpr_StartThread(thread);
return handle;
}
HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
{
return NULL;
}
VOID ExitThread(DWORD dwExitCode)
{
pthread_exit((void*) dwExitCode);
}
HANDLE GetCurrentThread(VOID)
@ -121,6 +154,22 @@ DWORD GetCurrentThreadId(VOID)
DWORD ResumeThread(HANDLE hThread)
{
ULONG Type;
PVOID Object;
WINPR_THREAD* thread;
if (!winpr_Handle_GetInfo(hThread, &Type, &Object))
return 0;
thread = (WINPR_THREAD*) Object;
pthread_mutex_lock(&thread->mutex);
if (!thread->started)
winpr_StartThread(thread);
pthread_mutex_unlock(&thread->mutex);
return 0;
}
@ -136,6 +185,21 @@ BOOL SwitchToThread(VOID)
BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode)
{
ULONG Type;
PVOID Object;
WINPR_THREAD* thread;
if (!winpr_Handle_GetInfo(hThread, &Type, &Object))
return 0;
thread = (WINPR_THREAD*) Object;
pthread_mutex_lock(&thread->mutex);
pthread_cancel(thread->thread);
pthread_mutex_unlock(&thread->mutex);
return TRUE;
}