mirror of https://github.com/FreeRDP/FreeRDP
channels/rdpdr/disk: replace thread utils by WinPR thread API
This commit is contained in:
parent
90ffa6ea86
commit
a11a69c70f
|
@ -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})
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue