Merge pull request #5139 from akallabeth/drive_hotplug_shutdown_crash_fix

Fixed crash on drive hotplug shutdown.
This commit is contained in:
Bernhard Miklautz 2019-02-07 10:08:41 +01:00 committed by GitHub
commit 162a69b0f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 43 deletions

View File

@ -593,33 +593,6 @@ static DWORD WINAPI drive_hotplug_thread_func(LPVOID arg)
return CHANNEL_RC_OK; return CHANNEL_RC_OK;
} }
/**
* Function description
*
* @return 0 on success, otherwise a Win32 error code
*/
static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr)
{
UINT error;
if (rdpdr->hotplugThread)
{
CFRunLoopStop(rdpdr->runLoop);
if (WaitForSingleObject(rdpdr->hotplugThread, INFINITE) == WAIT_FAILED)
{
error = GetLastError();
WLog_ERR(TAG, "WaitForSingleObject failed with error %"PRIu32"!", error);
return error;
}
rdpdr->hotplugThread = NULL;
}
return CHANNEL_RC_OK;
}
#else #else
#define MAX_USB_DEVICES 100 #define MAX_USB_DEVICES 100
@ -949,14 +922,6 @@ static DWORD WINAPI drive_hotplug_thread_func(LPVOID arg)
UINT error = 0; UINT error = 0;
DWORD status; DWORD status;
rdpdr = (rdpdrPlugin*) arg; rdpdr = (rdpdrPlugin*) arg;
if (!(rdpdr->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
{
WLog_ERR(TAG, "CreateEvent failed!");
error = ERROR_INTERNAL_ERROR;
goto out;
}
mfd = open("/proc/mounts", O_RDONLY, 0); mfd = open("/proc/mounts", O_RDONLY, 0);
if (mfd < 0) if (mfd < 0)
@ -1009,11 +974,13 @@ out:
setChannelError(rdpdr->rdpcontext, error, setChannelError(rdpdr->rdpcontext, error,
"drive_hotplug_thread_func reported an error"); "drive_hotplug_thread_func reported an error");
CloseHandle(rdpdr->stopEvent);
ExitThread(error); ExitThread(error);
return error; return error;
} }
#endif
#ifndef _WIN32
/** /**
* Function description * Function description
* *
@ -1025,8 +992,10 @@ static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr)
if (rdpdr->hotplugThread) if (rdpdr->hotplugThread)
{ {
if (rdpdr->stopEvent)
SetEvent(rdpdr->stopEvent); SetEvent(rdpdr->stopEvent);
#ifdef __MACOSX__
CFRunLoopStop(rdpdr->runLoop);
#endif
if (WaitForSingleObject(rdpdr->hotplugThread, INFINITE) == WAIT_FAILED) if (WaitForSingleObject(rdpdr->hotplugThread, INFINITE) == WAIT_FAILED)
{ {
@ -1035,6 +1004,9 @@ static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr)
return error; return error;
} }
CloseHandle(rdpdr->hotplugThread);
CloseHandle(rdpdr->stopEvent);
rdpdr->stopEvent = NULL;
rdpdr->hotplugThread = NULL; rdpdr->hotplugThread = NULL;
} }
@ -1083,11 +1055,24 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr)
if (drive->Path && (strcmp(drive->Path, "*") == 0)) if (drive->Path && (strcmp(drive->Path, "*") == 0))
{ {
first_hotplug(rdpdr); first_hotplug(rdpdr);
#ifndef _WIN32
if (!(rdpdr->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
{
WLog_ERR(TAG, "CreateEvent failed!");
return ERROR_INTERNAL_ERROR;
}
#endif
if (!(rdpdr->hotplugThread = CreateThread(NULL, 0, if (!(rdpdr->hotplugThread = CreateThread(NULL, 0,
drive_hotplug_thread_func, rdpdr, 0, NULL))) drive_hotplug_thread_func, rdpdr, 0, NULL)))
{ {
WLog_ERR(TAG, "CreateThread failed!"); WLog_ERR(TAG, "CreateThread failed!");
#ifndef _WIN32
CloseHandle(rdpdr->stopEvent);
rdpdr->stopEvent = NULL;
#endif
return ERROR_INTERNAL_ERROR; return ERROR_INTERNAL_ERROR;
} }

View File

@ -70,9 +70,11 @@ struct rdpdr_plugin
HANDLE hotplugThread; HANDLE hotplugThread;
#ifdef _WIN32 #ifdef _WIN32
HWND hotplug_wnd; HWND hotplug_wnd;
#elif __MACOSX__ #endif
#ifdef __MACOSX__
CFRunLoopRef runLoop; CFRunLoopRef runLoop;
#else #endif
#ifndef _WIN32
HANDLE stopEvent; HANDLE stopEvent;
#endif #endif
rdpContext* rdpcontext; rdpContext* rdpcontext;

View File

@ -1080,9 +1080,12 @@ BOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
} }
memcpy(fullpath, pFileSearch->lpPath, pathlen); memcpy(fullpath, pFileSearch->lpPath, pathlen);
fullpath[pathlen] = '/'; /* Ensure path is terminated with a separator, but prevent
memcpy(fullpath + pathlen + 1, pFileSearch->pDirent->d_name, namelen); * duplicate separators */
fullpath[pathlen + namelen + 1] = 0; if (fullpath[pathlen-1] != '/')
fullpath[pathlen++] = '/';
memcpy(fullpath + pathlen, pFileSearch->pDirent->d_name, namelen);
fullpath[pathlen + namelen] = 0;
if (stat(fullpath, &fileStat) != 0) if (stat(fullpath, &fileStat) != 0)
{ {