Merge pull request #4236 from akallabeth/scan_fix_remastered
Scanbuild warning fixes
This commit is contained in:
commit
4ff1251488
@ -149,7 +149,6 @@ static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext*
|
||||
Stream_Read_UINT32(s, UnicodeFlag); /* UnicodeFlag (4 bytes) */
|
||||
Stream_Seek_UINT32(s); /* CodePage (4 bytes), MUST be set to zero */
|
||||
Stream_Read_UINT32(s, ComputerNameLen); /* ComputerNameLen (4 bytes) */
|
||||
|
||||
/* UnicodeFlag is either 0 or 1, the other 31 bits must be ignored.
|
||||
*/
|
||||
UnicodeFlag = UnicodeFlag & 0x00000001;
|
||||
@ -766,7 +765,6 @@ static UINT rdpdr_server_receive_device_list_announce_request(
|
||||
UINT32 DeviceId;
|
||||
char PreferredDosName[9];
|
||||
UINT32 DeviceDataLength;
|
||||
BYTE* DeviceData;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
{
|
||||
@ -798,7 +796,6 @@ static UINT rdpdr_server_receive_device_list_announce_request(
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
DeviceData = Stream_Pointer(s);
|
||||
WLog_DBG(TAG, "Device %d Name: %s Id: 0x%08"PRIX32" DataLength: %"PRIu32"",
|
||||
i, PreferredDosName, DeviceId, DeviceDataLength);
|
||||
|
||||
@ -1148,7 +1145,6 @@ static void* rdpdr_server_thread(void* arg)
|
||||
buffer = NULL;
|
||||
BytesReturned = 0;
|
||||
ChannelEvent = NULL;
|
||||
|
||||
s = Stream_New(NULL, 4096);
|
||||
|
||||
if (!s)
|
||||
|
@ -67,7 +67,7 @@ struct _SSHAGENT_LISTENER_CALLBACK
|
||||
IWTSVirtualChannelManager* channel_mgr;
|
||||
|
||||
rdpContext* rdpcontext;
|
||||
const char *agent_uds_path;
|
||||
const char* agent_uds_path;
|
||||
};
|
||||
|
||||
typedef struct _SSHAGENT_CHANNEL_CALLBACK SSHAGENT_CHANNEL_CALLBACK;
|
||||
@ -80,7 +80,7 @@ struct _SSHAGENT_CHANNEL_CALLBACK
|
||||
IWTSVirtualChannel* channel;
|
||||
|
||||
rdpContext* rdpcontext;
|
||||
int agent_fd;
|
||||
int agent_fd;
|
||||
HANDLE thread;
|
||||
CRITICAL_SECTION lock;
|
||||
};
|
||||
@ -101,29 +101,35 @@ struct _SSHAGENT_PLUGIN
|
||||
*
|
||||
* @return The fd on success, otherwise -1
|
||||
*/
|
||||
static int connect_to_sshagent(const char *udspath)
|
||||
static int connect_to_sshagent(const char* udspath)
|
||||
{
|
||||
int agent_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (agent_fd == -1)
|
||||
{
|
||||
WLog_ERR(TAG, "Can't open Unix domain socket!");
|
||||
return -1;
|
||||
}
|
||||
int agent_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
struct sockaddr_un addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, udspath, sizeof(addr.sun_path) - 1);
|
||||
int rc = connect(agent_fd, (struct sockaddr*)&addr, sizeof(addr));
|
||||
if (rc != 0)
|
||||
{
|
||||
WLog_ERR(TAG, "Can't connect to Unix domain socket \"%s\"!",
|
||||
udspath);
|
||||
close(agent_fd);
|
||||
return -1;
|
||||
}
|
||||
if (agent_fd == -1)
|
||||
{
|
||||
WLog_ERR(TAG, "Can't open Unix domain socket!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return agent_fd;
|
||||
struct sockaddr_un addr;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
addr.sun_family = AF_UNIX;
|
||||
|
||||
strncpy(addr.sun_path, udspath, sizeof(addr.sun_path) - 1);
|
||||
|
||||
int rc = connect(agent_fd, (struct sockaddr*)&addr, sizeof(addr));
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
WLog_ERR(TAG, "Can't connect to Unix domain socket \"%s\"!",
|
||||
udspath);
|
||||
close(agent_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return agent_fd;
|
||||
}
|
||||
|
||||
|
||||
@ -133,57 +139,58 @@ static int connect_to_sshagent(const char *udspath)
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
static void *sshagent_read_thread(void *data)
|
||||
static void* sshagent_read_thread(void* data)
|
||||
{
|
||||
SSHAGENT_CHANNEL_CALLBACK *callback = (SSHAGENT_CHANNEL_CALLBACK *)data;
|
||||
BYTE buffer[4096];
|
||||
int going = 1;
|
||||
UINT status = CHANNEL_RC_OK;
|
||||
SSHAGENT_CHANNEL_CALLBACK* callback = (SSHAGENT_CHANNEL_CALLBACK*)data;
|
||||
BYTE buffer[4096];
|
||||
int going = 1;
|
||||
UINT status = CHANNEL_RC_OK;
|
||||
|
||||
while (going)
|
||||
{
|
||||
int bytes_read = read(callback->agent_fd,
|
||||
buffer,
|
||||
sizeof(buffer));
|
||||
while (going)
|
||||
{
|
||||
int bytes_read = read(callback->agent_fd,
|
||||
buffer,
|
||||
sizeof(buffer));
|
||||
|
||||
if (bytes_read == 0)
|
||||
{
|
||||
/* Socket closed cleanly at other end */
|
||||
going = 0;
|
||||
}
|
||||
else if (bytes_read < 0)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"Error reading from sshagent, errno=%d",
|
||||
errno);
|
||||
status = ERROR_READ_FAULT;
|
||||
going = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Something read: forward to virtual channel */
|
||||
status = callback->channel->Write(callback->channel,
|
||||
bytes_read,
|
||||
buffer,
|
||||
NULL);
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
going = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bytes_read == 0)
|
||||
{
|
||||
/* Socket closed cleanly at other end */
|
||||
going = 0;
|
||||
}
|
||||
else if (bytes_read < 0)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"Error reading from sshagent, errno=%d",
|
||||
errno);
|
||||
status = ERROR_READ_FAULT;
|
||||
going = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Something read: forward to virtual channel */
|
||||
status = callback->channel->Write(callback->channel,
|
||||
bytes_read,
|
||||
buffer,
|
||||
NULL);
|
||||
|
||||
close(callback->agent_fd);
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
going = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
setChannelError(callback->rdpcontext, status,
|
||||
"sshagent_read_thread reported an error");
|
||||
close(callback->agent_fd);
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
setChannelError(callback->rdpcontext, status,
|
||||
"sshagent_read_thread reported an error");
|
||||
|
||||
ExitThread(0);
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,41 +198,41 @@ static void *sshagent_read_thread(void *data)
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT sshagent_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream *data)
|
||||
static UINT sshagent_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream* data)
|
||||
{
|
||||
SSHAGENT_CHANNEL_CALLBACK* callback = (SSHAGENT_CHANNEL_CALLBACK*) pChannelCallback;
|
||||
BYTE* pBuffer = Stream_Pointer(data);
|
||||
UINT32 cbSize = Stream_GetRemainingLength(data);
|
||||
BYTE *pos = pBuffer;
|
||||
BYTE* pos = pBuffer;
|
||||
/* Forward what we have received to the ssh agent */
|
||||
UINT32 bytes_to_write = cbSize;
|
||||
errno = 0;
|
||||
|
||||
/* Forward what we have received to the ssh agent */
|
||||
UINT32 bytes_to_write = cbSize;
|
||||
errno = 0;
|
||||
while (bytes_to_write > 0)
|
||||
{
|
||||
int bytes_written = write(callback->agent_fd, pos,
|
||||
bytes_to_write);
|
||||
if (bytes_written < 0)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"Error writing to sshagent, errno=%d",
|
||||
errno);
|
||||
return ERROR_WRITE_FAULT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_to_write -= bytes_written;
|
||||
pos += bytes_written;
|
||||
}
|
||||
}
|
||||
while (bytes_to_write > 0)
|
||||
{
|
||||
int bytes_written = write(callback->agent_fd, pos,
|
||||
bytes_to_write);
|
||||
|
||||
/* Consume stream */
|
||||
Stream_Seek(data, cbSize);
|
||||
if (bytes_written < 0)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"Error writing to sshagent, errno=%d",
|
||||
errno);
|
||||
return ERROR_WRITE_FAULT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_to_write -= bytes_written;
|
||||
pos += bytes_written;
|
||||
}
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
/* Consume stream */
|
||||
Stream_Seek(data, cbSize);
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -236,11 +243,10 @@ static UINT sshagent_on_data_received(IWTSVirtualChannelCallback* pChannelCallba
|
||||
static UINT sshagent_on_close(IWTSVirtualChannelCallback* pChannelCallback)
|
||||
{
|
||||
SSHAGENT_CHANNEL_CALLBACK* callback = (SSHAGENT_CHANNEL_CALLBACK*) pChannelCallback;
|
||||
|
||||
/* Call shutdown() to wake up the read() in sshagent_read_thread(). */
|
||||
shutdown(callback->agent_fd, SHUT_RDWR);
|
||||
|
||||
/* Call shutdown() to wake up the read() in sshagent_read_thread(). */
|
||||
shutdown(callback->agent_fd, SHUT_RDWR);
|
||||
EnterCriticalSection(&callback->lock);
|
||||
|
||||
if (WaitForSingleObject(callback->thread, INFINITE) == WAIT_FAILED)
|
||||
{
|
||||
UINT error = GetLastError();
|
||||
@ -248,11 +254,10 @@ static UINT sshagent_on_close(IWTSVirtualChannelCallback* pChannelCallback)
|
||||
return error;
|
||||
}
|
||||
|
||||
CloseHandle(callback->thread);
|
||||
CloseHandle(callback->thread);
|
||||
LeaveCriticalSection(&callback->lock);
|
||||
DeleteCriticalSection(&callback->lock);
|
||||
|
||||
free(callback);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
@ -263,12 +268,11 @@ static UINT sshagent_on_close(IWTSVirtualChannelCallback* pChannelCallback)
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT sshagent_on_new_channel_connection(IWTSListenerCallback* pListenerCallback,
|
||||
IWTSVirtualChannel* pChannel, BYTE* Data, BOOL* pbAccept,
|
||||
IWTSVirtualChannelCallback** ppCallback)
|
||||
IWTSVirtualChannel* pChannel, BYTE* Data, BOOL* pbAccept,
|
||||
IWTSVirtualChannelCallback** ppCallback)
|
||||
{
|
||||
SSHAGENT_CHANNEL_CALLBACK* callback;
|
||||
SSHAGENT_LISTENER_CALLBACK* listener_callback = (SSHAGENT_LISTENER_CALLBACK*) pListenerCallback;
|
||||
|
||||
callback = (SSHAGENT_CHANNEL_CALLBACK*) calloc(1, sizeof(SSHAGENT_CHANNEL_CALLBACK));
|
||||
|
||||
if (!callback)
|
||||
@ -277,39 +281,41 @@ static UINT sshagent_on_new_channel_connection(IWTSListenerCallback* pListenerCa
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Now open a connection to the local ssh-agent. Do this for each
|
||||
* connection to the plugin in case we mess up the agent session. */
|
||||
callback->agent_fd
|
||||
= connect_to_sshagent(listener_callback->agent_uds_path);
|
||||
if (callback->agent_fd == -1)
|
||||
{
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
}
|
||||
/* Now open a connection to the local ssh-agent. Do this for each
|
||||
* connection to the plugin in case we mess up the agent session. */
|
||||
callback->agent_fd
|
||||
= connect_to_sshagent(listener_callback->agent_uds_path);
|
||||
|
||||
if (callback->agent_fd == -1)
|
||||
{
|
||||
free(callback);
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
}
|
||||
|
||||
InitializeCriticalSection(&callback->lock);
|
||||
|
||||
callback->iface.OnDataReceived = sshagent_on_data_received;
|
||||
callback->iface.OnClose = sshagent_on_close;
|
||||
callback->plugin = listener_callback->plugin;
|
||||
callback->channel_mgr = listener_callback->channel_mgr;
|
||||
callback->channel = pChannel;
|
||||
callback->rdpcontext = listener_callback->rdpcontext;
|
||||
|
||||
callback->thread
|
||||
= CreateThread(NULL,
|
||||
0,
|
||||
(LPTHREAD_START_ROUTINE) sshagent_read_thread,
|
||||
(void*) callback,
|
||||
0,
|
||||
NULL);
|
||||
= CreateThread(NULL,
|
||||
0,
|
||||
(LPTHREAD_START_ROUTINE) sshagent_read_thread,
|
||||
(void*) callback,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (!callback->thread)
|
||||
{
|
||||
WLog_ERR(TAG, "CreateThread failed!");
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
DeleteCriticalSection(&callback->lock);
|
||||
free(callback);
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
}
|
||||
|
||||
*ppCallback = (IWTSVirtualChannelCallback*) callback;
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
@ -321,8 +327,8 @@ static UINT sshagent_on_new_channel_connection(IWTSListenerCallback* pListenerCa
|
||||
static UINT sshagent_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
|
||||
{
|
||||
SSHAGENT_PLUGIN* sshagent = (SSHAGENT_PLUGIN*) pPlugin;
|
||||
|
||||
sshagent->listener_callback = (SSHAGENT_LISTENER_CALLBACK*) calloc(1, sizeof(SSHAGENT_LISTENER_CALLBACK));
|
||||
sshagent->listener_callback = (SSHAGENT_LISTENER_CALLBACK*) calloc(1,
|
||||
sizeof(SSHAGENT_LISTENER_CALLBACK));
|
||||
|
||||
if (!sshagent->listener_callback)
|
||||
{
|
||||
@ -334,16 +340,18 @@ static UINT sshagent_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMa
|
||||
sshagent->listener_callback->iface.OnNewChannelConnection = sshagent_on_new_channel_connection;
|
||||
sshagent->listener_callback->plugin = pPlugin;
|
||||
sshagent->listener_callback->channel_mgr = pChannelMgr;
|
||||
sshagent->listener_callback->agent_uds_path = getenv("SSH_AUTH_SOCK");
|
||||
|
||||
sshagent->listener_callback->agent_uds_path = getenv("SSH_AUTH_SOCK");
|
||||
if (sshagent->listener_callback->agent_uds_path == NULL)
|
||||
{
|
||||
if (sshagent->listener_callback->agent_uds_path == NULL)
|
||||
{
|
||||
WLog_ERR(TAG, "Environment variable $SSH_AUTH_SOCK undefined!");
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
}
|
||||
free(sshagent->listener_callback);
|
||||
sshagent->listener_callback = NULL;
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
}
|
||||
|
||||
return pChannelMgr->CreateListener(pChannelMgr, "SSHAGENT", 0,
|
||||
(IWTSListenerCallback*) sshagent->listener_callback, NULL);
|
||||
(IWTSListenerCallback*) sshagent->listener_callback, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -354,9 +362,7 @@ static UINT sshagent_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelMa
|
||||
static UINT sshagent_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
{
|
||||
SSHAGENT_PLUGIN* sshagent = (SSHAGENT_PLUGIN*) pPlugin;
|
||||
|
||||
free(sshagent);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
@ -375,7 +381,6 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
{
|
||||
UINT status = CHANNEL_RC_OK;
|
||||
SSHAGENT_PLUGIN* sshagent;
|
||||
|
||||
sshagent = (SSHAGENT_PLUGIN*) pEntryPoints->GetPlugin(pEntryPoints, "sshagent");
|
||||
|
||||
if (!sshagent)
|
||||
@ -392,9 +397,8 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||
sshagent->iface.Connected = NULL;
|
||||
sshagent->iface.Disconnected = NULL;
|
||||
sshagent->iface.Terminated = sshagent_plugin_terminated;
|
||||
sshagent->rdpcontext = ((freerdp*)((rdpSettings*) pEntryPoints->GetRdpSettings(
|
||||
pEntryPoints))->instance)->context;
|
||||
|
||||
sshagent->rdpcontext = ((freerdp*)((rdpSettings*) pEntryPoints->GetRdpSettings(
|
||||
pEntryPoints))->instance)->context;
|
||||
status = pEntryPoints->RegisterPlugin(pEntryPoints, "sshagent", (IWTSPlugin*) sshagent);
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Portions are from OpenSSH, under the following license:
|
||||
*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@ -60,7 +60,7 @@
|
||||
* xrdp-ssh-agent.c: program to forward ssh-agent protocol from xrdp session
|
||||
*
|
||||
* This performs the equivalent function of ssh-agent on a server you connect
|
||||
* to via ssh, but the ssh-agent protocol is over an RDP dynamic virtual
|
||||
* to via ssh, but the ssh-agent protocol is over an RDP dynamic virtual
|
||||
* channel and not an SSH channel.
|
||||
*
|
||||
* This will print out variables to set in your environment (specifically,
|
||||
@ -120,283 +120,304 @@ static int is_going = 1;
|
||||
/* Make a template filename for mk[sd]temp() */
|
||||
/* This is from mktemp_proto() in misc.c from openssh */
|
||||
void
|
||||
mktemp_proto(char *s, size_t len)
|
||||
mktemp_proto(char* s, size_t len)
|
||||
{
|
||||
const char *tmpdir;
|
||||
const char* tmpdir;
|
||||
int r;
|
||||
|
||||
if ((tmpdir = getenv("TMPDIR")) != NULL) {
|
||||
if ((tmpdir = getenv("TMPDIR")) != NULL)
|
||||
{
|
||||
r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir);
|
||||
|
||||
if (r > 0 && (size_t)r < len)
|
||||
return;
|
||||
}
|
||||
|
||||
r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX");
|
||||
|
||||
if (r < 0 || (size_t)r >= len)
|
||||
{
|
||||
fprintf(stderr, "%s: template string too short", __func__);
|
||||
exit(1);
|
||||
}
|
||||
{
|
||||
fprintf(stderr, "%s: template string too short", __func__);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This uses parts of main() in ssh-agent.c from openssh */
|
||||
static void
|
||||
setup_ssh_agent(struct sockaddr_un *addr)
|
||||
setup_ssh_agent(struct sockaddr_un* addr)
|
||||
{
|
||||
int rc;
|
||||
int rc;
|
||||
/* Create private directory for agent socket */
|
||||
mktemp_proto(socket_dir, sizeof(socket_dir));
|
||||
|
||||
/* Create private directory for agent socket */
|
||||
mktemp_proto(socket_dir, sizeof(socket_dir));
|
||||
if (mkdtemp(socket_dir) == NULL) {
|
||||
perror("mkdtemp: private socket dir");
|
||||
exit(1);
|
||||
}
|
||||
snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir,
|
||||
(long)getpid());
|
||||
if (mkdtemp(socket_dir) == NULL)
|
||||
{
|
||||
perror("mkdtemp: private socket dir");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Create unix domain socket */
|
||||
unlink(socket_name);
|
||||
snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir,
|
||||
(long)getpid());
|
||||
/* Create unix domain socket */
|
||||
unlink(socket_name);
|
||||
sa_uds_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
sa_uds_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sa_uds_fd == -1)
|
||||
{
|
||||
fprintf(stderr, "sshagent: socket creation failed");
|
||||
exit(2);
|
||||
}
|
||||
if (sa_uds_fd == -1)
|
||||
{
|
||||
fprintf(stderr, "sshagent: socket creation failed");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
memset(addr, 0, sizeof(struct sockaddr_un));
|
||||
addr->sun_family = AF_UNIX;
|
||||
strncpy(addr->sun_path, socket_name, sizeof(addr->sun_path));
|
||||
addr->sun_path[sizeof(addr->sun_path) - 1] = 0;
|
||||
memset(addr, 0, sizeof(struct sockaddr_un));
|
||||
addr->sun_family = AF_UNIX;
|
||||
strncpy(addr->sun_path, socket_name, sizeof(addr->sun_path));
|
||||
addr->sun_path[sizeof(addr->sun_path) - 1] = 0;
|
||||
/* Create with privileges rw------- so other users can't access the UDS */
|
||||
mode_t umask_sav = umask(0177);
|
||||
rc = bind(sa_uds_fd, (struct sockaddr*)addr, sizeof(struct sockaddr_un));
|
||||
|
||||
/* Create with privileges rw------- so other users can't access the UDS */
|
||||
mode_t umask_sav = umask(0177);
|
||||
rc = bind(sa_uds_fd, (struct sockaddr *)addr, sizeof(struct sockaddr_un));
|
||||
if (rc != 0)
|
||||
{
|
||||
fprintf(stderr, "sshagent: bind failed");
|
||||
close(sa_uds_fd);
|
||||
unlink(socket_name);
|
||||
exit(3);
|
||||
}
|
||||
umask(umask_sav);
|
||||
if (rc != 0)
|
||||
{
|
||||
fprintf(stderr, "sshagent: bind failed");
|
||||
close(sa_uds_fd);
|
||||
unlink(socket_name);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
rc = listen(sa_uds_fd, /* backlog = */ 5);
|
||||
if (rc != 0)
|
||||
{
|
||||
fprintf(stderr, "listen failed\n");
|
||||
close(sa_uds_fd);
|
||||
unlink(socket_name);
|
||||
exit(1);
|
||||
}
|
||||
umask(umask_sav);
|
||||
rc = listen(sa_uds_fd, /* backlog = */ 5);
|
||||
|
||||
/* Now fork: the child becomes the ssh-agent daemon and the parent prints
|
||||
* out the pid and socket name. */
|
||||
pid_t pid = fork();
|
||||
if (pid == -1)
|
||||
{
|
||||
perror("fork");
|
||||
exit(1);
|
||||
}
|
||||
else if (pid != 0)
|
||||
{
|
||||
/* Parent */
|
||||
close(sa_uds_fd);
|
||||
printf("SSH_AUTH_SOCK=%s; export SSH_AUTH_SOCK;\n", socket_name);
|
||||
printf("SSH_AGENT_PID=%d; export SSH_AGENT_PID;\n", pid);
|
||||
printf("echo Agent pid %d;\n", pid);
|
||||
exit(0);
|
||||
}
|
||||
if (rc != 0)
|
||||
{
|
||||
fprintf(stderr, "listen failed\n");
|
||||
close(sa_uds_fd);
|
||||
unlink(socket_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Child */
|
||||
/* Now fork: the child becomes the ssh-agent daemon and the parent prints
|
||||
* out the pid and socket name. */
|
||||
pid_t pid = fork();
|
||||
|
||||
if (setsid() == -1)
|
||||
{
|
||||
fprintf(stderr, "setsid failed");
|
||||
exit(1);
|
||||
}
|
||||
if (pid == -1)
|
||||
{
|
||||
perror("fork");
|
||||
exit(1);
|
||||
}
|
||||
else if (pid != 0)
|
||||
{
|
||||
/* Parent */
|
||||
close(sa_uds_fd);
|
||||
printf("SSH_AUTH_SOCK=%s; export SSH_AUTH_SOCK;\n", socket_name);
|
||||
printf("SSH_AGENT_PID=%d; export SSH_AGENT_PID;\n", pid);
|
||||
printf("echo Agent pid %d;\n", pid);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
(void)chdir("/");
|
||||
int devnullfd;
|
||||
if ((devnullfd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
|
||||
/* XXX might close listen socket */
|
||||
(void)dup2(devnullfd, STDIN_FILENO);
|
||||
(void)dup2(devnullfd, STDOUT_FILENO);
|
||||
(void)dup2(devnullfd, STDERR_FILENO);
|
||||
if (devnullfd > 2)
|
||||
close(devnullfd);
|
||||
}
|
||||
/* Child */
|
||||
|
||||
/* deny core dumps, since memory contains unencrypted private keys */
|
||||
struct rlimit rlim;
|
||||
rlim.rlim_cur = rlim.rlim_max = 0;
|
||||
if (setrlimit(RLIMIT_CORE, &rlim) < 0) {
|
||||
fprintf(stderr, "setrlimit RLIMIT_CORE: %s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (setsid() == -1)
|
||||
{
|
||||
fprintf(stderr, "setsid failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
(void)chdir("/");
|
||||
int devnullfd;
|
||||
|
||||
if ((devnullfd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1)
|
||||
{
|
||||
/* XXX might close listen socket */
|
||||
(void)dup2(devnullfd, STDIN_FILENO);
|
||||
(void)dup2(devnullfd, STDOUT_FILENO);
|
||||
(void)dup2(devnullfd, STDERR_FILENO);
|
||||
|
||||
if (devnullfd > 2)
|
||||
close(devnullfd);
|
||||
}
|
||||
|
||||
/* deny core dumps, since memory contains unencrypted private keys */
|
||||
struct rlimit rlim;
|
||||
rlim.rlim_cur = rlim.rlim_max = 0;
|
||||
|
||||
if (setrlimit(RLIMIT_CORE, &rlim) < 0)
|
||||
{
|
||||
fprintf(stderr, "setrlimit RLIMIT_CORE: %s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
handle_connection(int client_fd)
|
||||
{
|
||||
int rdp_fd = -1;
|
||||
int rc;
|
||||
void *channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION,
|
||||
"SSHAGENT",
|
||||
WTS_CHANNEL_OPTION_DYNAMIC_PRI_MED);
|
||||
if (channel == NULL)
|
||||
{
|
||||
fprintf(stderr, "WTSVirtualChannelOpenEx() failed\n");
|
||||
}
|
||||
int rdp_fd = -1;
|
||||
int rc;
|
||||
void* channel = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION,
|
||||
"SSHAGENT",
|
||||
WTS_CHANNEL_OPTION_DYNAMIC_PRI_MED);
|
||||
|
||||
unsigned int retlen;
|
||||
int *retdata;
|
||||
rc = WTSVirtualChannelQuery(channel,
|
||||
WTSVirtualFileHandle,
|
||||
(void **)&retdata,
|
||||
&retlen);
|
||||
if (!rc)
|
||||
{
|
||||
fprintf(stderr, "WTSVirtualChannelQuery() failed\n");
|
||||
}
|
||||
if (retlen != sizeof(rdp_fd))
|
||||
{
|
||||
fprintf(stderr, "WTSVirtualChannelQuery() returned wrong length %d\n",
|
||||
retlen);
|
||||
}
|
||||
rdp_fd = *retdata;
|
||||
if (channel == NULL)
|
||||
{
|
||||
fprintf(stderr, "WTSVirtualChannelOpenEx() failed\n");
|
||||
}
|
||||
|
||||
int client_going = 1;
|
||||
while (client_going)
|
||||
{
|
||||
/* Wait for data from RDP or the client */
|
||||
fd_set readfds;
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(client_fd, &readfds);
|
||||
FD_SET(rdp_fd, &readfds);
|
||||
select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
|
||||
unsigned int retlen;
|
||||
int* retdata;
|
||||
rc = WTSVirtualChannelQuery(channel,
|
||||
WTSVirtualFileHandle,
|
||||
(void**)&retdata,
|
||||
&retlen);
|
||||
|
||||
if (FD_ISSET(rdp_fd, &readfds))
|
||||
{
|
||||
/* Read from RDP and write to the client */
|
||||
char buffer[4096];
|
||||
unsigned int bytes_to_write;
|
||||
rc = WTSVirtualChannelRead(channel,
|
||||
/* TimeOut = */ 5000,
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
&bytes_to_write);
|
||||
if (rc == 1)
|
||||
{
|
||||
char *pos = buffer;
|
||||
errno = 0;
|
||||
while (bytes_to_write > 0)
|
||||
{
|
||||
int bytes_written = send(client_fd, pos, bytes_to_write, 0);
|
||||
if (!rc)
|
||||
{
|
||||
fprintf(stderr, "WTSVirtualChannelQuery() failed\n");
|
||||
}
|
||||
|
||||
if (bytes_written > 0)
|
||||
{
|
||||
bytes_to_write -= bytes_written;
|
||||
pos += bytes_written;
|
||||
}
|
||||
else if (bytes_written == 0)
|
||||
{
|
||||
fprintf(stderr, "send() returned 0!\n");
|
||||
}
|
||||
else if (errno != EINTR)
|
||||
{
|
||||
/* Error */
|
||||
fprintf(stderr, "Error %d on recv\n", errno);
|
||||
client_going = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error */
|
||||
fprintf(stderr, "WTSVirtualChannelRead() failed: %d\n", errno);
|
||||
client_going = 0;
|
||||
}
|
||||
}
|
||||
if (retlen != sizeof(rdp_fd))
|
||||
{
|
||||
fprintf(stderr, "WTSVirtualChannelQuery() returned wrong length %d\n",
|
||||
retlen);
|
||||
}
|
||||
|
||||
if (FD_ISSET(client_fd, &readfds))
|
||||
{
|
||||
/* Read from the client and write to RDP */
|
||||
char buffer[4096];
|
||||
ssize_t bytes_to_write = recv(client_fd, buffer, sizeof(buffer), 0);
|
||||
if (bytes_to_write > 0)
|
||||
{
|
||||
char *pos = buffer;
|
||||
while (bytes_to_write > 0)
|
||||
{
|
||||
unsigned int bytes_written;
|
||||
int rc = WTSVirtualChannelWrite(channel,
|
||||
pos,
|
||||
bytes_to_write,
|
||||
&bytes_written);
|
||||
if (rc == 0)
|
||||
{
|
||||
fprintf(stderr, "WTSVirtualChannelWrite() failed: %d\n",
|
||||
errno);
|
||||
client_going = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_to_write -= bytes_written;
|
||||
pos += bytes_written;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bytes_to_write == 0)
|
||||
{
|
||||
/* Client has closed connection */
|
||||
client_going = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error */
|
||||
fprintf(stderr, "Error %d on recv\n", errno);
|
||||
client_going = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
WTSVirtualChannelClose(channel);
|
||||
rdp_fd = *retdata;
|
||||
int client_going = 1;
|
||||
|
||||
while (client_going)
|
||||
{
|
||||
/* Wait for data from RDP or the client */
|
||||
fd_set readfds;
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(client_fd, &readfds);
|
||||
FD_SET(rdp_fd, &readfds);
|
||||
select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
|
||||
|
||||
if (FD_ISSET(rdp_fd, &readfds))
|
||||
{
|
||||
/* Read from RDP and write to the client */
|
||||
char buffer[4096];
|
||||
unsigned int bytes_to_write;
|
||||
rc = WTSVirtualChannelRead(channel,
|
||||
/* TimeOut = */ 5000,
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
&bytes_to_write);
|
||||
|
||||
if (rc == 1)
|
||||
{
|
||||
char* pos = buffer;
|
||||
errno = 0;
|
||||
|
||||
while (bytes_to_write > 0)
|
||||
{
|
||||
int bytes_written = send(client_fd, pos, bytes_to_write, 0);
|
||||
|
||||
if (bytes_written > 0)
|
||||
{
|
||||
bytes_to_write -= bytes_written;
|
||||
pos += bytes_written;
|
||||
}
|
||||
else if (bytes_written == 0)
|
||||
{
|
||||
fprintf(stderr, "send() returned 0!\n");
|
||||
}
|
||||
else if (errno != EINTR)
|
||||
{
|
||||
/* Error */
|
||||
fprintf(stderr, "Error %d on recv\n", errno);
|
||||
client_going = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error */
|
||||
fprintf(stderr, "WTSVirtualChannelRead() failed: %d\n", errno);
|
||||
client_going = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(client_fd, &readfds))
|
||||
{
|
||||
/* Read from the client and write to RDP */
|
||||
char buffer[4096];
|
||||
ssize_t bytes_to_write = recv(client_fd, buffer, sizeof(buffer), 0);
|
||||
|
||||
if (bytes_to_write > 0)
|
||||
{
|
||||
char* pos = buffer;
|
||||
|
||||
while (bytes_to_write > 0)
|
||||
{
|
||||
unsigned int bytes_written;
|
||||
int rc = WTSVirtualChannelWrite(channel,
|
||||
pos,
|
||||
bytes_to_write,
|
||||
&bytes_written);
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
fprintf(stderr, "WTSVirtualChannelWrite() failed: %d\n",
|
||||
errno);
|
||||
client_going = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_to_write -= bytes_written;
|
||||
pos += bytes_written;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (bytes_to_write == 0)
|
||||
{
|
||||
/* Client has closed connection */
|
||||
client_going = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error */
|
||||
fprintf(stderr, "Error %d on recv\n", errno);
|
||||
client_going = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WTSVirtualChannelClose(channel);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
/* Setup the Unix domain socket and daemon process */
|
||||
struct sockaddr_un addr;
|
||||
setup_ssh_agent(&addr);
|
||||
/* Setup the Unix domain socket and daemon process */
|
||||
struct sockaddr_un addr;
|
||||
setup_ssh_agent(&addr);
|
||||
|
||||
/* Wait for a client to connect to the socket */
|
||||
while (is_going)
|
||||
{
|
||||
fd_set readfds;
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(sa_uds_fd, &readfds);
|
||||
select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
|
||||
/* Wait for a client to connect to the socket */
|
||||
while (is_going)
|
||||
{
|
||||
fd_set readfds;
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(sa_uds_fd, &readfds);
|
||||
select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
|
||||
|
||||
/* If something connected then get it...
|
||||
* (You can test this using "socat - UNIX-CONNECT:<udspath>".) */
|
||||
if (FD_ISSET(sa_uds_fd, &readfds))
|
||||
{
|
||||
socklen_t addrsize = sizeof(addr);
|
||||
int client_fd = accept(sa_uds_fd,
|
||||
(struct sockaddr*)&addr,
|
||||
&addrsize);
|
||||
handle_connection(client_fd);
|
||||
close(client_fd);
|
||||
}
|
||||
}
|
||||
/* If something connected then get it...
|
||||
* (You can test this using "socat - UNIX-CONNECT:<udspath>".) */
|
||||
if (FD_ISSET(sa_uds_fd, &readfds))
|
||||
{
|
||||
socklen_t addrsize = sizeof(addr);
|
||||
int client_fd = accept(sa_uds_fd,
|
||||
(struct sockaddr*)&addr,
|
||||
&addrsize);
|
||||
handle_connection(client_fd);
|
||||
close(client_fd);
|
||||
}
|
||||
}
|
||||
|
||||
close(sa_uds_fd);
|
||||
unlink(socket_name);
|
||||
|
||||
return 0;
|
||||
close(sa_uds_fd);
|
||||
unlink(socket_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vim: set sw=4:ts=4:et: */
|
||||
|
@ -320,7 +320,10 @@ static wStream* xf_cliprdr_serialize_server_format_list(xfClipboard* clipboard)
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(s, format->formatId);
|
||||
Stream_Write(s, format->formatName, name_length);
|
||||
|
||||
if (format->formatName)
|
||||
Stream_Write(s, format->formatName, name_length);
|
||||
|
||||
Stream_Write_UINT8(s, '\0');
|
||||
}
|
||||
|
||||
@ -436,7 +439,8 @@ static CLIPRDR_FORMAT* xf_cliprdr_get_raw_server_formats(xfClipboard* clipboard,
|
||||
{
|
||||
WLog_ERR(TAG,
|
||||
"failed to retrieve raw format list: data=%p, length=%lu, format=%d, type=%lu (expected=%lu)",
|
||||
(void*) data, length, format, (unsigned long) type, (unsigned long) clipboard->raw_format_list_atom);
|
||||
(void*) data, length, format, (unsigned long) type,
|
||||
(unsigned long) clipboard->raw_format_list_atom);
|
||||
}
|
||||
|
||||
if (data)
|
||||
@ -630,15 +634,13 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard,
|
||||
* to not process CF_RAW as a file list in case WinPR does not support file transfers.
|
||||
*/
|
||||
if (dstFormatId &&
|
||||
(dstFormatId == ClipboardGetFormatId(clipboard->system, "FileGroupDescriptorW")))
|
||||
(dstFormatId == ClipboardGetFormatId(clipboard->system, "FileGroupDescriptorW")))
|
||||
{
|
||||
UINT error = NO_ERROR;
|
||||
FILEDESCRIPTOR* file_array = (FILEDESCRIPTOR*) pDstData;
|
||||
UINT32 file_count = DstSize / sizeof(FILEDESCRIPTOR);
|
||||
|
||||
pDstData = NULL;
|
||||
DstSize = 0;
|
||||
|
||||
error = cliprdr_serialize_file_list(file_array, file_count, &pDstData, &DstSize);
|
||||
|
||||
if (error)
|
||||
@ -817,6 +819,7 @@ static void xf_cliprdr_clear_cached_data(xfClipboard* clipboard)
|
||||
free(clipboard->data);
|
||||
clipboard->data = NULL;
|
||||
}
|
||||
|
||||
clipboard->data_length = 0;
|
||||
|
||||
if (clipboard->data_raw)
|
||||
@ -824,6 +827,7 @@ static void xf_cliprdr_clear_cached_data(xfClipboard* clipboard)
|
||||
free(clipboard->data_raw);
|
||||
clipboard->data_raw = NULL;
|
||||
}
|
||||
|
||||
clipboard->data_raw_length = 0;
|
||||
}
|
||||
|
||||
@ -904,7 +908,7 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard,
|
||||
/* We can compare format names by pointer value here as they are both
|
||||
* taken from the same clipboard->serverFormats array */
|
||||
matchingFormat = (formatId == clipboard->data_format_id)
|
||||
&& (formatName == clipboard->data_format_name);
|
||||
&& (formatName == clipboard->data_format_name);
|
||||
|
||||
if (matchingFormat && (clipboard->data != 0) && !rawTransfer)
|
||||
{
|
||||
@ -930,7 +934,6 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard,
|
||||
* Response will be postponed after receiving the data
|
||||
*/
|
||||
xf_cliprdr_clear_cached_data(clipboard);
|
||||
|
||||
respond->xselection.property = xevent->xselectionrequest.property;
|
||||
clipboard->respond = respond;
|
||||
clipboard->data_format_id = formatId;
|
||||
@ -1078,7 +1081,7 @@ static UINT xf_cliprdr_send_client_capabilities(xfClipboard* clipboard)
|
||||
|
||||
if (clipboard->streams_supported && clipboard->file_formats_registered)
|
||||
generalCapabilitySet.generalFlags |=
|
||||
CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS;
|
||||
CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS;
|
||||
|
||||
return clipboard->context->ClientCapabilities(clipboard->context,
|
||||
&capabilities);
|
||||
@ -1180,7 +1183,6 @@ static UINT xf_cliprdr_server_capabilities(CliprdrClientContext* context,
|
||||
const CLIPRDR_GENERAL_CAPABILITY_SET* generalCaps;
|
||||
const BYTE* capsPtr = (const BYTE*) capabilities->capabilitySets;
|
||||
xfClipboard* clipboard = (xfClipboard*) context->custom;
|
||||
|
||||
clipboard->streams_supported = FALSE;
|
||||
|
||||
for (i = 0; i < capabilities->cCapabilitiesSets; i++)
|
||||
@ -1211,21 +1213,19 @@ static UINT xf_cliprdr_server_capabilities(CliprdrClientContext* context,
|
||||
static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context,
|
||||
CLIPRDR_FORMAT_LIST* formatList)
|
||||
{
|
||||
int i, j;
|
||||
CLIPRDR_FORMAT* format;
|
||||
UINT32 i;
|
||||
int j;
|
||||
xfClipboard* clipboard = (xfClipboard*) context->custom;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
UINT ret;
|
||||
|
||||
xf_cliprdr_clear_cached_data(clipboard);
|
||||
|
||||
clipboard->data_format_id = -1;
|
||||
clipboard->data_format_name = NULL;
|
||||
|
||||
if (clipboard->serverFormats)
|
||||
{
|
||||
for (i = 0; i < clipboard->numServerFormats; i++)
|
||||
free(clipboard->serverFormats[i].formatName);
|
||||
for (j = 0; j < clipboard->numServerFormats; j++)
|
||||
free(clipboard->serverFormats[j].formatName);
|
||||
|
||||
free(clipboard->serverFormats);
|
||||
clipboard->serverFormats = NULL;
|
||||
@ -1244,7 +1244,7 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context,
|
||||
|
||||
for (i = 0; i < formatList->numFormats; i++)
|
||||
{
|
||||
format = &formatList->formats[i];
|
||||
CLIPRDR_FORMAT* format = &formatList->formats[i];
|
||||
clipboard->serverFormats[i].formatId = format->formatId;
|
||||
|
||||
if (format->formatName)
|
||||
@ -1253,8 +1253,10 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context,
|
||||
|
||||
if (!clipboard->serverFormats[i].formatName)
|
||||
{
|
||||
for (--i; i >= 0; --i)
|
||||
free(clipboard->serverFormats[i].formatName);
|
||||
UINT32 k;
|
||||
|
||||
for (k = 0; k < i; k++)
|
||||
free(clipboard->serverFormats[k].formatName);
|
||||
|
||||
clipboard->numServerFormats = 0;
|
||||
free(clipboard->serverFormats);
|
||||
@ -1265,15 +1267,17 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context,
|
||||
}
|
||||
|
||||
/* CF_RAW is always implicitly supported by the server */
|
||||
format = &clipboard->serverFormats[formatList->numFormats];
|
||||
format->formatId = CF_RAW;
|
||||
format->formatName = NULL;
|
||||
{
|
||||
CLIPRDR_FORMAT* format = &clipboard->serverFormats[formatList->numFormats];
|
||||
format->formatId = CF_RAW;
|
||||
format->formatName = NULL;
|
||||
}
|
||||
xf_cliprdr_provide_server_format_list(clipboard);
|
||||
clipboard->numTargets = 2;
|
||||
|
||||
for (i = 0; i < formatList->numFormats; i++)
|
||||
{
|
||||
format = &formatList->formats[i];
|
||||
CLIPRDR_FORMAT* format = &formatList->formats[i];
|
||||
|
||||
for (j = 0; j < clipboard->numClientFormats; j++)
|
||||
{
|
||||
@ -1362,7 +1366,6 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext*
|
||||
return CHANNEL_RC_OK;
|
||||
|
||||
xf_cliprdr_clear_cached_data(clipboard);
|
||||
|
||||
pDstData = NULL;
|
||||
DstSize = 0;
|
||||
srcFormatId = 0;
|
||||
@ -1430,11 +1433,11 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext*
|
||||
* conversion again on subsequent requests */
|
||||
clipboard->data = pDstData;
|
||||
clipboard->data_length = DstSize;
|
||||
|
||||
/* We have to copy the original data again, as pSrcData is now owned
|
||||
* by clipboard->system. Memory allocation failure is not fatal here
|
||||
* as this is only a cached value. */
|
||||
clipboard->data_raw = (BYTE*) malloc(size);
|
||||
|
||||
if (clipboard->data_raw)
|
||||
{
|
||||
CopyMemory(clipboard->data_raw, data, size);
|
||||
@ -1455,56 +1458,48 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext*
|
||||
}
|
||||
|
||||
static UINT xf_cliprdr_server_file_size_request(xfClipboard* clipboard,
|
||||
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
|
||||
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
|
||||
{
|
||||
wClipboardFileSizeRequest request;
|
||||
|
||||
ZeroMemory(&request, sizeof(request));
|
||||
|
||||
request.streamId = fileContentsRequest->streamId;
|
||||
request.listIndex = fileContentsRequest->listIndex;
|
||||
|
||||
if (fileContentsRequest->cbRequested != sizeof(UINT64))
|
||||
{
|
||||
WLog_WARN(TAG, "unexpected FILECONTENTS_SIZE request: %"PRIu32" bytes",
|
||||
fileContentsRequest->cbRequested);
|
||||
fileContentsRequest->cbRequested);
|
||||
}
|
||||
|
||||
return clipboard->delegate->ClientRequestFileSize(clipboard->delegate, &request);
|
||||
}
|
||||
|
||||
static UINT xf_cliprdr_server_file_range_request(xfClipboard* clipboard,
|
||||
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
|
||||
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
|
||||
{
|
||||
wClipboardFileRangeRequest request;
|
||||
|
||||
ZeroMemory(&request, sizeof(request));
|
||||
|
||||
request.streamId = fileContentsRequest->streamId;
|
||||
request.listIndex = fileContentsRequest->listIndex;
|
||||
request.nPositionLow = fileContentsRequest->nPositionLow;
|
||||
request.nPositionHigh = fileContentsRequest->nPositionHigh;
|
||||
request.cbRequested = fileContentsRequest->cbRequested;
|
||||
|
||||
return clipboard->delegate->ClientRequestFileRange(clipboard->delegate, &request);
|
||||
}
|
||||
|
||||
static UINT xf_cliprdr_send_file_contents_failure(CliprdrClientContext* context,
|
||||
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
|
||||
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
|
||||
{
|
||||
CLIPRDR_FILE_CONTENTS_RESPONSE response;
|
||||
|
||||
ZeroMemory(&response, sizeof(response));
|
||||
|
||||
response.msgFlags = CB_RESPONSE_FAIL;
|
||||
response.streamId = fileContentsRequest->streamId;
|
||||
response.dwFlags = fileContentsRequest->dwFlags;
|
||||
|
||||
return context->ClientFileContentsResponse(context, &response);
|
||||
}
|
||||
|
||||
static UINT xf_cliprdr_server_file_contents_request(CliprdrClientContext* context,
|
||||
CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
|
||||
CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
|
||||
{
|
||||
UINT error = NO_ERROR;
|
||||
xfClipboard* clipboard = context->custom;
|
||||
@ -1514,10 +1509,9 @@ static UINT xf_cliprdr_server_file_contents_request(CliprdrClientContext* contex
|
||||
* The FILECONTENTS_SIZE and FILECONTENTS_RANGE flags MUST NOT be set at the same time.
|
||||
*/
|
||||
if ((fileContentsRequest->dwFlags & (FILECONTENTS_SIZE | FILECONTENTS_RANGE)) ==
|
||||
(FILECONTENTS_SIZE | FILECONTENTS_RANGE))
|
||||
(FILECONTENTS_SIZE | FILECONTENTS_RANGE))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid CLIPRDR_FILECONTENTS_REQUEST.dwFlags");
|
||||
|
||||
return xf_cliprdr_send_file_contents_failure(context, fileContentsRequest);
|
||||
}
|
||||
|
||||
@ -1530,7 +1524,6 @@ static UINT xf_cliprdr_server_file_contents_request(CliprdrClientContext* contex
|
||||
if (error)
|
||||
{
|
||||
WLog_ERR(TAG, "failed to handle CLIPRDR_FILECONTENTS_REQUEST: 0x%08X", error);
|
||||
|
||||
return xf_cliprdr_send_file_contents_failure(context, fileContentsRequest);
|
||||
}
|
||||
|
||||
@ -1538,66 +1531,54 @@ static UINT xf_cliprdr_server_file_contents_request(CliprdrClientContext* contex
|
||||
}
|
||||
|
||||
static UINT xf_cliprdr_clipboard_file_size_success(wClipboardDelegate* delegate,
|
||||
const wClipboardFileSizeRequest* request, UINT64 fileSize)
|
||||
const wClipboardFileSizeRequest* request, UINT64 fileSize)
|
||||
{
|
||||
CLIPRDR_FILE_CONTENTS_RESPONSE response;
|
||||
xfClipboard* clipboard = delegate->custom;
|
||||
|
||||
ZeroMemory(&response, sizeof(response));
|
||||
|
||||
response.msgFlags = CB_RESPONSE_OK;
|
||||
response.streamId = request->streamId;
|
||||
response.dwFlags = FILECONTENTS_SIZE;
|
||||
response.cbRequested = sizeof(UINT64);
|
||||
response.requestedData = (BYTE*) &fileSize;
|
||||
|
||||
return clipboard->context->ClientFileContentsResponse(clipboard->context, &response);
|
||||
}
|
||||
|
||||
static UINT xf_cliprdr_clipboard_file_size_failure(wClipboardDelegate* delegate,
|
||||
const wClipboardFileSizeRequest* request, UINT errorCode)
|
||||
const wClipboardFileSizeRequest* request, UINT errorCode)
|
||||
{
|
||||
CLIPRDR_FILE_CONTENTS_RESPONSE response;
|
||||
xfClipboard* clipboard = delegate->custom;
|
||||
|
||||
ZeroMemory(&response, sizeof(response));
|
||||
|
||||
response.msgFlags = CB_RESPONSE_FAIL;
|
||||
response.streamId = request->streamId;
|
||||
response.dwFlags = FILECONTENTS_SIZE;
|
||||
|
||||
return clipboard->context->ClientFileContentsResponse(clipboard->context, &response);
|
||||
}
|
||||
|
||||
static UINT xf_cliprdr_clipboard_file_range_success(wClipboardDelegate* delegate,
|
||||
const wClipboardFileRangeRequest* request, const BYTE* data, UINT32 size)
|
||||
const wClipboardFileRangeRequest* request, const BYTE* data, UINT32 size)
|
||||
{
|
||||
CLIPRDR_FILE_CONTENTS_RESPONSE response;
|
||||
xfClipboard* clipboard = delegate->custom;
|
||||
|
||||
ZeroMemory(&response, sizeof(response));
|
||||
|
||||
response.msgFlags = CB_RESPONSE_OK;
|
||||
response.streamId = request->streamId;
|
||||
response.dwFlags = FILECONTENTS_RANGE;
|
||||
response.cbRequested = size;
|
||||
response.requestedData = (BYTE*) data;
|
||||
|
||||
return clipboard->context->ClientFileContentsResponse(clipboard->context, &response);
|
||||
}
|
||||
|
||||
static UINT xf_cliprdr_clipboard_file_range_failure(wClipboardDelegate* delegate,
|
||||
const wClipboardFileRangeRequest* request, UINT errorCode)
|
||||
const wClipboardFileRangeRequest* request, UINT errorCode)
|
||||
{
|
||||
CLIPRDR_FILE_CONTENTS_RESPONSE response;
|
||||
xfClipboard* clipboard = delegate->custom;
|
||||
|
||||
ZeroMemory(&response, sizeof(response));
|
||||
|
||||
response.msgFlags = CB_RESPONSE_FAIL;
|
||||
response.streamId = request->streamId;
|
||||
response.dwFlags = FILECONTENTS_RANGE;
|
||||
|
||||
return clipboard->context->ClientFileContentsResponse(clipboard->context, &response);
|
||||
}
|
||||
|
||||
@ -1631,12 +1612,11 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
|
||||
clipboard->property_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR", FALSE);
|
||||
clipboard->raw_transfer_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR_RAW", FALSE);
|
||||
clipboard->raw_format_list_atom =
|
||||
XInternAtom(xfc->display, "_FREERDP_CLIPRDR_FORMATS", FALSE);
|
||||
XInternAtom(xfc->display, "_FREERDP_CLIPRDR_FORMATS", FALSE);
|
||||
xf_cliprdr_set_raw_transfer_enabled(clipboard, TRUE);
|
||||
|
||||
XSelectInput(xfc->display, clipboard->root_window, PropertyChangeMask);
|
||||
|
||||
#ifdef WITH_XFIXES
|
||||
|
||||
if (XFixesQueryExtension(xfc->display, &clipboard->xfixes_event_base,
|
||||
&clipboard->xfixes_error_base))
|
||||
{
|
||||
@ -1662,40 +1642,34 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
|
||||
WLog_ERR(TAG,
|
||||
"Warning: Using clipboard redirection without XFIXES extension is strongly discouraged!");
|
||||
#endif
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "_FREERDP_RAW", False);
|
||||
clipboard->clientFormats[n].formatId = CF_RAW;
|
||||
n++;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "UTF8_STRING", False);
|
||||
clipboard->clientFormats[n].formatId = CF_UNICODETEXT;
|
||||
n++;
|
||||
|
||||
clipboard->clientFormats[n].atom = XA_STRING;
|
||||
clipboard->clientFormats[n].formatId = CF_TEXT;
|
||||
n++;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/png", False);
|
||||
clipboard->clientFormats[n].formatId = CB_FORMAT_PNG;
|
||||
n++;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/jpeg", False);
|
||||
clipboard->clientFormats[n].formatId = CB_FORMAT_JPEG;
|
||||
n++;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/gif", False);
|
||||
clipboard->clientFormats[n].formatId = CB_FORMAT_GIF;
|
||||
n++;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "image/bmp", False);
|
||||
clipboard->clientFormats[n].formatId = CF_DIB;
|
||||
n++;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "text/html", False);
|
||||
clipboard->clientFormats[n].formatId = CB_FORMAT_HTML;
|
||||
clipboard->clientFormats[n].formatName = _strdup("HTML Format");
|
||||
|
||||
if (!clipboard->clientFormats[n].formatName)
|
||||
goto error;
|
||||
|
||||
n++;
|
||||
|
||||
/*
|
||||
@ -1710,8 +1684,10 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "text/uri-list", False);
|
||||
clipboard->clientFormats[n].formatId = CB_FORMAT_TEXTURILIST;
|
||||
clipboard->clientFormats[n].formatName = _strdup("FileGroupDescriptorW");
|
||||
|
||||
if (!clipboard->clientFormats[n].formatName)
|
||||
goto error;
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
@ -1720,24 +1696,20 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
|
||||
clipboard->targets[1] = XInternAtom(xfc->display, "TARGETS", FALSE);
|
||||
clipboard->numTargets = 2;
|
||||
clipboard->incr_atom = XInternAtom(xfc->display, "INCR", FALSE);
|
||||
|
||||
clipboard->delegate = ClipboardGetDelegate(clipboard->system);
|
||||
clipboard->delegate->custom = clipboard;
|
||||
clipboard->delegate->ClipboardFileSizeSuccess = xf_cliprdr_clipboard_file_size_success;
|
||||
clipboard->delegate->ClipboardFileSizeFailure = xf_cliprdr_clipboard_file_size_failure;
|
||||
clipboard->delegate->ClipboardFileRangeSuccess = xf_cliprdr_clipboard_file_range_success;
|
||||
clipboard->delegate->ClipboardFileRangeFailure = xf_cliprdr_clipboard_file_range_failure;
|
||||
|
||||
return clipboard;
|
||||
|
||||
error:
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
free(clipboard->clientFormats[i].formatName);
|
||||
|
||||
ClipboardDestroy(clipboard->system);
|
||||
|
||||
free(clipboard);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -384,9 +384,11 @@ BOOL interleaved_compress(BITMAP_INTERLEAVED_CONTEXT* interleaved,
|
||||
if (!DstFormat)
|
||||
return FALSE;
|
||||
|
||||
status = freerdp_image_copy(interleaved->TempBuffer, DstFormat, 0, 0, 0, nWidth,
|
||||
nHeight,
|
||||
pSrcData, SrcFormat, nSrcStep, nXSrc, nYSrc, palette, FREERDP_FLIP_NONE);
|
||||
if (!freerdp_image_copy(interleaved->TempBuffer, DstFormat, 0, 0, 0, nWidth,
|
||||
nHeight,
|
||||
pSrcData, SrcFormat, nSrcStep, nXSrc, nYSrc, palette, FREERDP_FLIP_NONE))
|
||||
return FALSE;
|
||||
|
||||
s = Stream_New(pDstData, maxSize);
|
||||
|
||||
if (!s)
|
||||
|
@ -309,7 +309,7 @@ static INLINE BOOL planar_decompress_planes_raw(const BYTE* pSrcData[4],
|
||||
for (y = beg; y != end; y += inc)
|
||||
{
|
||||
BYTE* pRGB = &pDstData[((nYDst + y) * nDstStep) + (nXDst * GetBytesPerPixel(
|
||||
DstFormat))];
|
||||
DstFormat))];
|
||||
|
||||
if (!writeLine(&pRGB, DstFormat, nWidth, &pR, &pG, &pB, &pA))
|
||||
return FALSE;
|
||||
@ -320,7 +320,7 @@ static INLINE BOOL planar_decompress_planes_raw(const BYTE* pSrcData[4],
|
||||
for (y = beg; y != end; y += inc)
|
||||
{
|
||||
BYTE* pRGB = &pDstData[((nYDst + y) * nDstStep) + (nXDst * GetBytesPerPixel(
|
||||
DstFormat))];
|
||||
DstFormat))];
|
||||
|
||||
if (!writeLine(&pRGB, DstFormat, nWidth, &pR, &pG, &pB, &pA))
|
||||
return FALSE;
|
||||
@ -998,7 +998,7 @@ BYTE* freerdp_bitmap_planar_compress_plane_rle(const BYTE* inPlane,
|
||||
return outPlane;
|
||||
}
|
||||
|
||||
static INLINE UINT32 freerdp_bitmap_planar_compress_planes_rle(
|
||||
static INLINE BOOL freerdp_bitmap_planar_compress_planes_rle(
|
||||
BYTE* inPlanes[4], UINT32 width, UINT32 height,
|
||||
BYTE* outPlanes, UINT32* dstSizes, BOOL skipAlpha)
|
||||
{
|
||||
@ -1015,7 +1015,7 @@ static INLINE UINT32 freerdp_bitmap_planar_compress_planes_rle(
|
||||
|
||||
if (!freerdp_bitmap_planar_compress_plane_rle(
|
||||
inPlanes[0], width, height, outPlanes, &dstSizes[0]))
|
||||
return 0;
|
||||
return FALSE;
|
||||
|
||||
outPlanes += dstSizes[0];
|
||||
outPlanesSize -= dstSizes[0];
|
||||
@ -1026,7 +1026,7 @@ static INLINE UINT32 freerdp_bitmap_planar_compress_planes_rle(
|
||||
|
||||
if (!freerdp_bitmap_planar_compress_plane_rle(inPlanes[1], width, height,
|
||||
outPlanes, &dstSizes[1]))
|
||||
return 0;
|
||||
return FALSE;
|
||||
|
||||
outPlanes += dstSizes[1];
|
||||
outPlanesSize -= dstSizes[1];
|
||||
@ -1035,7 +1035,7 @@ static INLINE UINT32 freerdp_bitmap_planar_compress_planes_rle(
|
||||
|
||||
if (!freerdp_bitmap_planar_compress_plane_rle(inPlanes[2], width, height,
|
||||
outPlanes, &dstSizes[2]))
|
||||
return 0;
|
||||
return FALSE;
|
||||
|
||||
outPlanes += dstSizes[2];
|
||||
outPlanesSize -= dstSizes[2];
|
||||
@ -1044,9 +1044,9 @@ static INLINE UINT32 freerdp_bitmap_planar_compress_planes_rle(
|
||||
|
||||
if (!freerdp_bitmap_planar_compress_plane_rle(inPlanes[3], width, height,
|
||||
outPlanes, &dstSizes[3]))
|
||||
return 0;
|
||||
return FALSE;
|
||||
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BYTE* freerdp_bitmap_planar_delta_encode_plane(const BYTE* inPlane,
|
||||
@ -1136,10 +1136,12 @@ BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context,
|
||||
context->deltaPlanes))
|
||||
return NULL;
|
||||
|
||||
if (freerdp_bitmap_planar_compress_planes_rle(
|
||||
if (!freerdp_bitmap_planar_compress_planes_rle(
|
||||
context->deltaPlanes, width, height,
|
||||
context->rlePlanesBuffer, dstSizes,
|
||||
context->AllowSkipAlpha) > 0)
|
||||
context->AllowSkipAlpha))
|
||||
return NULL;
|
||||
|
||||
{
|
||||
int offset = 0;
|
||||
FormatHeader |= PLANAR_FORMAT_HEADER_RLE;
|
||||
@ -1155,6 +1157,24 @@ BYTE* freerdp_bitmap_compress_planar(BITMAP_PLANAR_CONTEXT* context,
|
||||
}
|
||||
}
|
||||
|
||||
if (FormatHeader & PLANAR_FORMAT_HEADER_RLE)
|
||||
{
|
||||
if (!context->AllowRunLengthEncoding)
|
||||
return NULL;
|
||||
|
||||
if (context->rlePlanes[0] == NULL)
|
||||
return NULL;
|
||||
|
||||
if (context->rlePlanes[1] == NULL)
|
||||
return NULL;
|
||||
|
||||
if (context->rlePlanes[2] == NULL)
|
||||
return NULL;
|
||||
|
||||
if (context->rlePlanes[3] == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!dstData)
|
||||
{
|
||||
size = 1;
|
||||
|
@ -8,21 +8,21 @@
|
||||
|
||||
/* Sample from [MS-RDPEGFX] */
|
||||
static const BYTE TEST_FOX_DATA[] =
|
||||
"The quick brown "
|
||||
"fox jumps over t"
|
||||
"he lazy dog";
|
||||
"The quick brown "
|
||||
"fox jumps over t"
|
||||
"he lazy dog";
|
||||
|
||||
static const BYTE TEST_FOX_DATA_SINGLE[] =
|
||||
"\xE0\x04\x54\x68\x65\x20\x71\x75\x69\x63\x6B\x20\x62\x72\x6F\x77"
|
||||
"\x6E\x20\x66\x6F\x78\x20\x6A\x75\x6D\x70\x73\x20\x6F\x76\x65\x72"
|
||||
"\x20\x74\x68\x65\x20\x6C\x61\x7A\x79\x20\x64\x6F\x67";
|
||||
"\xE0\x04\x54\x68\x65\x20\x71\x75\x69\x63\x6B\x20\x62\x72\x6F\x77"
|
||||
"\x6E\x20\x66\x6F\x78\x20\x6A\x75\x6D\x70\x73\x20\x6F\x76\x65\x72"
|
||||
"\x20\x74\x68\x65\x20\x6C\x61\x7A\x79\x20\x64\x6F\x67";
|
||||
|
||||
static const BYTE TEST_FOX_DATA_MULTIPART[] =
|
||||
"\xE1\x03\x00\x2B\x00\x00\x00\x11\x00\x00\x00\x04\x54\x68\x65\x20"
|
||||
"\x71\x75\x69\x63\x6B\x20\x62\x72\x6F\x77\x6E\x20\x0E\x00\x00\x00"
|
||||
"\x04\x66\x6F\x78\x20\x6A\x75\x6D\x70\x73\x20\x6F\x76\x65\x10\x00"
|
||||
"\x00\x00\x24\x39\x08\x0E\x91\xF8\xD8\x61\x3D\x1E\x44\x06\x43\x79"
|
||||
"\x9C\x02";
|
||||
"\xE1\x03\x00\x2B\x00\x00\x00\x11\x00\x00\x00\x04\x54\x68\x65\x20"
|
||||
"\x71\x75\x69\x63\x6B\x20\x62\x72\x6F\x77\x6E\x20\x0E\x00\x00\x00"
|
||||
"\x04\x66\x6F\x78\x20\x6A\x75\x6D\x70\x73\x20\x6F\x76\x65\x10\x00"
|
||||
"\x00\x00\x24\x39\x08\x0E\x91\xF8\xD8\x61\x3D\x1E\x44\x06\x43\x79"
|
||||
"\x9C\x02";
|
||||
|
||||
static int test_ZGfxCompressFox(void)
|
||||
{
|
||||
@ -35,8 +35,8 @@ static int test_ZGfxCompressFox(void)
|
||||
BYTE* pDstData;
|
||||
ZGFX_CONTEXT* zgfx;
|
||||
UINT32 expectedSize;
|
||||
|
||||
zgfx = zgfx_context_new(TRUE);
|
||||
|
||||
if (!zgfx)
|
||||
return -1;
|
||||
|
||||
@ -45,6 +45,7 @@ static int test_ZGfxCompressFox(void)
|
||||
Flags = 0;
|
||||
expectedSize = sizeof(TEST_FOX_DATA_SINGLE) - 1;
|
||||
status = zgfx_compress(zgfx, pSrcData, SrcSize, &pDstData, &DstSize, &Flags);
|
||||
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
|
||||
@ -52,7 +53,8 @@ static int test_ZGfxCompressFox(void)
|
||||
|
||||
if (DstSize != expectedSize)
|
||||
{
|
||||
printf("test_ZGfxCompressFox: output size mismatch: Actual: %"PRIu32", Expected: %"PRIu32"\n", DstSize, expectedSize);
|
||||
printf("test_ZGfxCompressFox: output size mismatch: Actual: %"PRIu32", Expected: %"PRIu32"\n",
|
||||
DstSize, expectedSize);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -67,7 +69,6 @@ static int test_ZGfxCompressFox(void)
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
fail:
|
||||
zgfx_context_free(zgfx);
|
||||
return rc;
|
||||
@ -84,8 +85,8 @@ static int test_ZGfxDecompressFoxSingle(void)
|
||||
BYTE* pDstData;
|
||||
ZGFX_CONTEXT* zgfx;
|
||||
UINT32 expectedSize;
|
||||
|
||||
zgfx = zgfx_context_new(TRUE);
|
||||
|
||||
if (!zgfx)
|
||||
return -1;
|
||||
|
||||
@ -94,6 +95,7 @@ static int test_ZGfxDecompressFoxSingle(void)
|
||||
Flags = 0;
|
||||
expectedSize = sizeof(TEST_FOX_DATA) - 1;
|
||||
status = zgfx_decompress(zgfx, pSrcData, SrcSize, &pDstData, &DstSize, Flags);
|
||||
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
|
||||
@ -101,7 +103,8 @@ static int test_ZGfxDecompressFoxSingle(void)
|
||||
|
||||
if (DstSize != expectedSize)
|
||||
{
|
||||
printf("test_ZGfxDecompressFoxSingle: output size mismatch: Actual: %"PRIu32", Expected: %"PRIu32"\n", DstSize, expectedSize);
|
||||
printf("test_ZGfxDecompressFoxSingle: output size mismatch: Actual: %"PRIu32", Expected: %"PRIu32"\n",
|
||||
DstSize, expectedSize);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -116,7 +119,6 @@ static int test_ZGfxDecompressFoxSingle(void)
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
fail:
|
||||
zgfx_context_free(zgfx);
|
||||
return rc;
|
||||
@ -133,8 +135,8 @@ static int test_ZGfxDecompressFoxMultipart(void)
|
||||
BYTE* pDstData;
|
||||
ZGFX_CONTEXT* zgfx;
|
||||
UINT32 expectedSize;
|
||||
|
||||
zgfx = zgfx_context_new(TRUE);
|
||||
|
||||
if (!zgfx)
|
||||
return -1;
|
||||
|
||||
@ -143,6 +145,7 @@ static int test_ZGfxDecompressFoxMultipart(void)
|
||||
Flags = 0;
|
||||
expectedSize = sizeof(TEST_FOX_DATA) - 1;
|
||||
status = zgfx_decompress(zgfx, pSrcData, SrcSize, &pDstData, &DstSize, Flags);
|
||||
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
|
||||
@ -150,7 +153,8 @@ static int test_ZGfxDecompressFoxMultipart(void)
|
||||
|
||||
if (DstSize != expectedSize)
|
||||
{
|
||||
printf("test_ZGfxDecompressFoxSingle: output size mismatch: Actual: %"PRIu32", Expected: %"PRIu32"\n", DstSize, expectedSize);
|
||||
printf("test_ZGfxDecompressFoxSingle: output size mismatch: Actual: %"PRIu32", Expected: %"PRIu32"\n",
|
||||
DstSize, expectedSize);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -165,10 +169,9 @@ static int test_ZGfxDecompressFoxMultipart(void)
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
fail:
|
||||
zgfx_context_free(zgfx);
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_ZGfxCompressConsistent(void)
|
||||
@ -185,10 +188,10 @@ static int test_ZGfxCompressConsistent(void)
|
||||
ZGFX_CONTEXT* zgfx;
|
||||
UINT32 expectedSize;
|
||||
BYTE BigBuffer[65536];
|
||||
|
||||
memset(BigBuffer, 0xaa, sizeof(BigBuffer));
|
||||
memcpy(BigBuffer, TEST_FOX_DATA, sizeof(TEST_FOX_DATA) - 1);
|
||||
zgfx = zgfx_context_new(TRUE);
|
||||
|
||||
if (!zgfx)
|
||||
return -1;
|
||||
|
||||
@ -197,13 +200,14 @@ static int test_ZGfxCompressConsistent(void)
|
||||
pSrcData = (BYTE*) BigBuffer;
|
||||
Flags = 0;
|
||||
status = zgfx_compress(zgfx, pSrcData, SrcSize, &pDstData2, &DstSize2, &Flags);
|
||||
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
|
||||
printf("Compress: flags: 0x%08"PRIX32" size: %"PRIu32"\n", Flags, DstSize2);
|
||||
|
||||
/* Decompress */
|
||||
status = zgfx_decompress(zgfx, pDstData2, DstSize2, &pDstData, &DstSize, Flags);
|
||||
|
||||
if (status < 0)
|
||||
goto fail;
|
||||
|
||||
@ -211,7 +215,8 @@ static int test_ZGfxCompressConsistent(void)
|
||||
|
||||
if (DstSize != expectedSize)
|
||||
{
|
||||
printf("test_ZGfxDecompressFoxSingle: output size mismatch: Actual: %"PRIu32", Expected: %"PRIu32"\n", DstSize, expectedSize);
|
||||
printf("test_ZGfxDecompressFoxSingle: output size mismatch: Actual: %"PRIu32", Expected: %"PRIu32"\n",
|
||||
DstSize, expectedSize);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -837,13 +837,13 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength)
|
||||
RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU) ? TRUE : FALSE;
|
||||
|
||||
if (settings->SupportStatusInfoPdu)
|
||||
settings->SupportStatusInfoPdu = (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_STATUSINFO_PDU) ? TRUE : FALSE;
|
||||
settings->SupportStatusInfoPdu = (earlyCapabilityFlags &
|
||||
RNS_UD_CS_SUPPORT_STATUSINFO_PDU) ? TRUE : FALSE;
|
||||
|
||||
if (!(earlyCapabilityFlags & RNS_UD_CS_VALID_CONNECTION_TYPE))
|
||||
connectionType = 0;
|
||||
|
||||
settings->SupportErrorInfoPdu = earlyCapabilityFlags &
|
||||
RNS_UD_CS_SUPPORT_ERRINFO_PDU;
|
||||
settings->SupportErrorInfoPdu = earlyCapabilityFlags & RNS_UD_CS_SUPPORT_ERRINFO_PDU;
|
||||
settings->ConnectionType = connectionType;
|
||||
return TRUE;
|
||||
}
|
||||
@ -1221,15 +1221,15 @@ BOOL gcc_read_server_security_data(wStream* s, rdpMcs* mcs)
|
||||
|
||||
data = settings->ServerCertificate;
|
||||
length = settings->ServerCertificateLength;
|
||||
|
||||
if (!certificate_read_server_certificate(settings->RdpServerCertificate, data,
|
||||
length))
|
||||
goto fail;
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
free (settings->ServerRandom);
|
||||
free (settings->ServerCertificate);
|
||||
free(settings->ServerRandom);
|
||||
free(settings->ServerCertificate);
|
||||
settings->ServerRandom = NULL;
|
||||
settings->ServerCertificate = NULL;
|
||||
return FALSE;
|
||||
@ -1471,10 +1471,12 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs)
|
||||
Stream_Write_UINT32(s, serverCertLen); /* serverCertLen */
|
||||
settings->ServerRandomLength = serverRandomLen;
|
||||
settings->ServerRandom = (BYTE*) malloc(serverRandomLen);
|
||||
|
||||
if (!settings->ServerRandom)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
winpr_RAND(settings->ServerRandom, serverRandomLen);
|
||||
Stream_Write(s, settings->ServerRandom, serverRandomLen);
|
||||
sigData = Stream_Pointer(s);
|
||||
@ -1772,7 +1774,7 @@ void gcc_write_client_monitor_data(wStream* s, rdpMcs* mcs)
|
||||
int i;
|
||||
UINT16 length;
|
||||
UINT32 left, top, right, bottom, flags;
|
||||
INT32 baseX, baseY;
|
||||
INT32 baseX = 0, baseY = 0;
|
||||
rdpSettings* settings = mcs->settings;
|
||||
|
||||
if (settings->MonitorCount > 1)
|
||||
|
@ -196,13 +196,15 @@ static BOOL update_message_SetKeyboardIndicators(rdpContext* context, UINT16 led
|
||||
MakeMessageId(Update, SetKeyboardIndicators), (void*)(size_t)led_flags, NULL);
|
||||
}
|
||||
|
||||
static BOOL update_message_SetKeyboardImeStatus(rdpContext* context, UINT16 imeId, UINT32 imeState, UINT32 imeConvMode)
|
||||
static BOOL update_message_SetKeyboardImeStatus(rdpContext* context, UINT16 imeId, UINT32 imeState,
|
||||
UINT32 imeConvMode)
|
||||
{
|
||||
if (!context || !context->update)
|
||||
return FALSE;
|
||||
|
||||
return MessageQueue_Post(context->update->queue, (void*) context,
|
||||
MakeMessageId(Update, SetKeyboardImeStatus), (void*)(size_t)((imeId << 16UL) | imeState), (void*)(size_t) imeConvMode);
|
||||
MakeMessageId(Update, SetKeyboardImeStatus), (void*)(size_t)((imeId << 16UL) | imeState),
|
||||
(void*)(size_t) imeConvMode);
|
||||
}
|
||||
|
||||
static BOOL update_message_RefreshRect(rdpContext* context, BYTE count,
|
||||
@ -2632,7 +2634,7 @@ int update_message_queue_process_message(rdpUpdate* update, wMessage* message)
|
||||
update_message_free_class(message, msgClass, msgType);
|
||||
|
||||
if (status < 0)
|
||||
status = -1;
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -391,6 +391,7 @@ int nla_client_begin(rdpNla* nla)
|
||||
nla->packageName = nla->pPackageInfo->Name;
|
||||
}
|
||||
}
|
||||
|
||||
if ((nla->status == SEC_I_COMPLETE_AND_CONTINUE) || (nla->status == SEC_I_COMPLETE_NEEDED))
|
||||
{
|
||||
if (nla->table->CompleteAuthToken)
|
||||
@ -553,11 +554,13 @@ static int nla_client_recv(rdpNla* nla)
|
||||
}
|
||||
|
||||
nla_buffer_free(nla);
|
||||
|
||||
if (SecIsValidHandle(&nla->credentials))
|
||||
{
|
||||
nla->table->FreeCredentialsHandle(&nla->credentials);
|
||||
SecInvalidateHandle(&nla->credentials);
|
||||
}
|
||||
|
||||
if (nla->status != SEC_E_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "FreeCredentialsHandle status %s [0x%08"PRIX32"]",
|
||||
@ -781,6 +784,7 @@ static int nla_server_authenticate(rdpNla* nla)
|
||||
|
||||
status = nla->table->SetContextAttributes(&nla->context, SECPKG_ATTR_AUTH_NTLM_HASH_CB_DATA, peer,
|
||||
0);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "SetContextAttributesA(hash cb data) status %s [0x%08"PRIX32"]",
|
||||
@ -865,21 +869,21 @@ static int nla_server_authenticate(rdpNla* nla)
|
||||
*/
|
||||
switch (GetLastError())
|
||||
{
|
||||
case ERROR_PASSWORD_MUST_CHANGE:
|
||||
nla->errorCode = STATUS_PASSWORD_MUST_CHANGE;
|
||||
break;
|
||||
case ERROR_PASSWORD_MUST_CHANGE:
|
||||
nla->errorCode = STATUS_PASSWORD_MUST_CHANGE;
|
||||
break;
|
||||
|
||||
case ERROR_PASSWORD_EXPIRED:
|
||||
nla->errorCode = STATUS_PASSWORD_EXPIRED;
|
||||
break;
|
||||
case ERROR_PASSWORD_EXPIRED:
|
||||
nla->errorCode = STATUS_PASSWORD_EXPIRED;
|
||||
break;
|
||||
|
||||
case ERROR_ACCOUNT_DISABLED:
|
||||
nla->errorCode = STATUS_ACCOUNT_DISABLED;
|
||||
break;
|
||||
case ERROR_ACCOUNT_DISABLED:
|
||||
nla->errorCode = STATUS_ACCOUNT_DISABLED;
|
||||
break;
|
||||
|
||||
default:
|
||||
nla->errorCode = NTSTATUS_FROM_WIN32(GetLastError());
|
||||
break;
|
||||
default:
|
||||
nla->errorCode = NTSTATUS_FROM_WIN32(GetLastError());
|
||||
break;
|
||||
}
|
||||
|
||||
WLog_ERR(TAG, "AcceptSecurityContext status %s [0x%08"PRIX32"]",
|
||||
@ -1006,7 +1010,7 @@ static void ap_integer_decrement_le(BYTE* number, int size)
|
||||
|
||||
SECURITY_STATUS nla_encrypt_public_key_echo(rdpNla* nla)
|
||||
{
|
||||
SecBuffer Buffers[2];
|
||||
SecBuffer Buffers[2] = { 0 };
|
||||
SecBufferDesc Message;
|
||||
SECURITY_STATUS status;
|
||||
int public_key_length;
|
||||
@ -1060,8 +1064,8 @@ SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla)
|
||||
int length;
|
||||
BYTE* buffer;
|
||||
ULONG pfQOP = 0;
|
||||
BYTE* public_key1;
|
||||
BYTE* public_key2;
|
||||
BYTE* public_key1 = NULL;
|
||||
BYTE* public_key2 = NULL;
|
||||
int public_key_length = 0;
|
||||
int signature_length;
|
||||
SecBuffer Buffers[2] = { 0 };
|
||||
@ -1112,6 +1116,7 @@ SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla)
|
||||
Message.ulVersion = SECBUFFER_VERSION;
|
||||
Message.pBuffers = (PSecBuffer) &Buffers;
|
||||
}
|
||||
|
||||
status = nla->table->DecryptMessage(&nla->context, &Message, nla->recvSeqNum++, &pfQOP);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
@ -1140,7 +1145,7 @@ SECURITY_STATUS nla_decrypt_public_key_echo(rdpNla* nla)
|
||||
ap_integer_decrement_le(public_key2, public_key_length);
|
||||
}
|
||||
|
||||
if (memcmp(public_key1, public_key2, public_key_length) != 0)
|
||||
if (!public_key1 || !public_key2 || memcmp(public_key1, public_key2, public_key_length) != 0)
|
||||
{
|
||||
WLog_ERR(TAG, "Could not verify server's public key echo");
|
||||
WLog_ERR(TAG, "Expected (length = %d):", public_key_length);
|
||||
@ -1304,6 +1309,10 @@ static BOOL nla_read_ts_credentials(rdpNla* nla, PSecBuffer ts_credentials)
|
||||
int length;
|
||||
int ts_password_creds_length = 0;
|
||||
BOOL ret;
|
||||
|
||||
if (!ts_credentials || !ts_credentials->pvBuffer)
|
||||
return FALSE;
|
||||
|
||||
s = Stream_New(ts_credentials->pvBuffer, ts_credentials->cbBuffer);
|
||||
|
||||
if (!s)
|
||||
@ -1405,7 +1414,7 @@ static BOOL nla_encode_ts_credentials(rdpNla* nla)
|
||||
|
||||
static SECURITY_STATUS nla_encrypt_ts_credentials(rdpNla* nla)
|
||||
{
|
||||
SecBuffer Buffers[2];
|
||||
SecBuffer Buffers[2] = { 0 };
|
||||
SecBufferDesc Message;
|
||||
SECURITY_STATUS status;
|
||||
|
||||
@ -1441,6 +1450,7 @@ static SECURITY_STATUS nla_encrypt_ts_credentials(rdpNla* nla)
|
||||
Message.ulVersion = SECBUFFER_VERSION;
|
||||
Message.pBuffers = (PSecBuffer) &Buffers;
|
||||
}
|
||||
|
||||
status = nla->table->EncryptMessage(&nla->context, 0, &Message, nla->sendSeqNum++);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
@ -1458,7 +1468,7 @@ static SECURITY_STATUS nla_decrypt_ts_credentials(rdpNla* nla)
|
||||
int length;
|
||||
BYTE* buffer;
|
||||
ULONG pfQOP;
|
||||
SecBuffer Buffers[2];
|
||||
SecBuffer Buffers[2] = { 0 };
|
||||
SecBufferDesc Message;
|
||||
SECURITY_STATUS status;
|
||||
|
||||
@ -1498,6 +1508,7 @@ static SECURITY_STATUS nla_decrypt_ts_credentials(rdpNla* nla)
|
||||
Message.ulVersion = SECBUFFER_VERSION;
|
||||
Message.pBuffers = (PSecBuffer) &Buffers;
|
||||
}
|
||||
|
||||
status = nla->table->DecryptMessage(&nla->context, &Message, nla->recvSeqNum++, &pfQOP);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
@ -1729,53 +1740,55 @@ int nla_recv_pdu(rdpNla* nla, wStream* s)
|
||||
if (nla->errorCode)
|
||||
{
|
||||
UINT32 code;
|
||||
|
||||
switch (nla->errorCode)
|
||||
{
|
||||
case STATUS_PASSWORD_MUST_CHANGE:
|
||||
code = FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE;
|
||||
break;
|
||||
case STATUS_PASSWORD_MUST_CHANGE:
|
||||
code = FREERDP_ERROR_CONNECT_PASSWORD_MUST_CHANGE;
|
||||
break;
|
||||
|
||||
case STATUS_PASSWORD_EXPIRED:
|
||||
code = FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED;
|
||||
break;
|
||||
case STATUS_PASSWORD_EXPIRED:
|
||||
code = FREERDP_ERROR_CONNECT_PASSWORD_EXPIRED;
|
||||
break;
|
||||
|
||||
case STATUS_ACCOUNT_DISABLED:
|
||||
code = FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED;
|
||||
break;
|
||||
case STATUS_ACCOUNT_DISABLED:
|
||||
code = FREERDP_ERROR_CONNECT_ACCOUNT_DISABLED;
|
||||
break;
|
||||
|
||||
case STATUS_LOGON_FAILURE:
|
||||
code = FREERDP_ERROR_CONNECT_LOGON_FAILURE;
|
||||
break;
|
||||
case STATUS_LOGON_FAILURE:
|
||||
code = FREERDP_ERROR_CONNECT_LOGON_FAILURE;
|
||||
break;
|
||||
|
||||
case STATUS_WRONG_PASSWORD:
|
||||
code = FREERDP_ERROR_CONNECT_WRONG_PASSWORD;
|
||||
break;
|
||||
case STATUS_WRONG_PASSWORD:
|
||||
code = FREERDP_ERROR_CONNECT_WRONG_PASSWORD;
|
||||
break;
|
||||
|
||||
case STATUS_ACCESS_DENIED:
|
||||
code = FREERDP_ERROR_CONNECT_ACCESS_DENIED;
|
||||
break;
|
||||
case STATUS_ACCESS_DENIED:
|
||||
code = FREERDP_ERROR_CONNECT_ACCESS_DENIED;
|
||||
break;
|
||||
|
||||
case STATUS_ACCOUNT_RESTRICTION:
|
||||
code = FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION;
|
||||
break;
|
||||
case STATUS_ACCOUNT_RESTRICTION:
|
||||
code = FREERDP_ERROR_CONNECT_ACCOUNT_RESTRICTION;
|
||||
break;
|
||||
|
||||
case STATUS_ACCOUNT_LOCKED_OUT:
|
||||
code = FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT;
|
||||
break;
|
||||
case STATUS_ACCOUNT_LOCKED_OUT:
|
||||
code = FREERDP_ERROR_CONNECT_ACCOUNT_LOCKED_OUT;
|
||||
break;
|
||||
|
||||
case STATUS_ACCOUNT_EXPIRED:
|
||||
code = FREERDP_ERROR_CONNECT_ACCOUNT_EXPIRED;
|
||||
break;
|
||||
case STATUS_ACCOUNT_EXPIRED:
|
||||
code = FREERDP_ERROR_CONNECT_ACCOUNT_EXPIRED;
|
||||
break;
|
||||
|
||||
case STATUS_LOGON_TYPE_NOT_GRANTED:
|
||||
code = FREERDP_ERROR_CONNECT_LOGON_TYPE_NOT_GRANTED;
|
||||
break;
|
||||
case STATUS_LOGON_TYPE_NOT_GRANTED:
|
||||
code = FREERDP_ERROR_CONNECT_LOGON_TYPE_NOT_GRANTED;
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "SPNEGO failed with NTSTATUS: 0x%08"PRIX32"", nla->errorCode);
|
||||
default:
|
||||
WLog_ERR(TAG, "SPNEGO failed with NTSTATUS: 0x%08"PRIX32"", nla->errorCode);
|
||||
code = FREERDP_ERROR_AUTHENTICATION_FAILED;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
freerdp_set_last_error(nla->instance->context, code);
|
||||
return -1;
|
||||
}
|
||||
@ -1923,6 +1936,7 @@ rdpNla* nla_new(freerdp* instance, rdpTransport* transport, rdpSettings* setting
|
||||
return NULL;
|
||||
|
||||
nla->identity = calloc(1, sizeof(SEC_WINNT_AUTH_IDENTITY));
|
||||
|
||||
if (!nla->identity)
|
||||
{
|
||||
free(nla);
|
||||
@ -2008,9 +2022,17 @@ void nla_free(rdpNla* nla)
|
||||
if (nla->table)
|
||||
{
|
||||
SECURITY_STATUS status;
|
||||
|
||||
if (SecIsValidHandle(&nla->credentials))
|
||||
{
|
||||
status = nla->table->FreeCredentialsHandle(&nla->credentials);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
{
|
||||
WLog_WARN(TAG, "FreeCredentialsHandle status %s [0x%08"PRIX32"]",
|
||||
GetSecurityStatusString(status), status);
|
||||
}
|
||||
|
||||
SecInvalidateHandle(&nla->credentials);
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,6 @@ BOOL gdi_Rectangle(HGDI_DC hdc, UINT32 nXDst, UINT32 nYDst, UINT32 nWidth,
|
||||
return TRUE;
|
||||
|
||||
color = hdc->textColor;
|
||||
color = GetColor(hdc->format, 0, 0xFF, 0, 0xFF);
|
||||
|
||||
for (y = 0; y < nHeight; y++)
|
||||
{
|
||||
|
@ -61,14 +61,13 @@ static struct posix_file* make_posix_file(const char* local_name, const WCHAR* r
|
||||
{
|
||||
struct posix_file* file = NULL;
|
||||
struct stat statbuf;
|
||||
|
||||
file = calloc(1, sizeof(*file));
|
||||
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
file->fd = -1;
|
||||
file->offset = 0;
|
||||
|
||||
file->local_name = _strdup(local_name);
|
||||
file->remote_name = _wcsdup(remote_name);
|
||||
|
||||
@ -84,14 +83,11 @@ static struct posix_file* make_posix_file(const char* local_name, const WCHAR* r
|
||||
|
||||
file->is_directory = S_ISDIR(statbuf.st_mode);
|
||||
file->size = statbuf.st_size;
|
||||
|
||||
return file;
|
||||
|
||||
error:
|
||||
free(file->local_name);
|
||||
free(file->remote_name);
|
||||
free(file);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -142,7 +138,6 @@ static BOOL decode_percent_encoded_byte(const char* str, const char* end, char*
|
||||
*value |= hex_to_dec(str[1], &valid);
|
||||
*value <<= 4;
|
||||
*value |= hex_to_dec(str[2], &valid);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
@ -152,9 +147,9 @@ static char* decode_percent_encoded_string(const char* str, size_t len)
|
||||
char* next = NULL;
|
||||
const char* cur = str;
|
||||
const char* lim = str + len;
|
||||
|
||||
/* Percent decoding shrinks data length, so len bytes will be enough. */
|
||||
buffer = calloc(len + 1, sizeof(char));
|
||||
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
@ -180,10 +175,8 @@ static char* decode_percent_encoded_string(const char* str, size_t len)
|
||||
}
|
||||
|
||||
return buffer;
|
||||
|
||||
error:
|
||||
free(buffer);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -220,7 +213,6 @@ static WCHAR* convert_local_name_component_to_remote(const char* local_name)
|
||||
}
|
||||
|
||||
return remote_name;
|
||||
|
||||
error:
|
||||
free(remote_name);
|
||||
return NULL;
|
||||
@ -231,18 +223,16 @@ static char* concat_local_name(const char* dir, const char* file)
|
||||
size_t len_dir = 0;
|
||||
size_t len_file = 0;
|
||||
char* buffer = NULL;
|
||||
|
||||
len_dir = strlen(dir);
|
||||
len_file = strlen(file);
|
||||
|
||||
buffer = calloc(len_dir + 1 + len_file + 1, sizeof(char));
|
||||
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
memcpy(buffer, dir, len_dir * sizeof(char));
|
||||
buffer[len_dir] = '/';
|
||||
memcpy(buffer + len_dir + 1, file, len_file * sizeof(char));
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -251,25 +241,23 @@ static WCHAR* concat_remote_name(const WCHAR* dir, const WCHAR* file)
|
||||
size_t len_dir = 0;
|
||||
size_t len_file = 0;
|
||||
WCHAR* buffer = NULL;
|
||||
|
||||
len_dir = _wcslen(dir);
|
||||
len_file = _wcslen(file);
|
||||
|
||||
buffer = calloc(len_dir + 1 + len_file + 1, sizeof(WCHAR));
|
||||
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
memcpy(buffer, dir, len_dir * sizeof(WCHAR));
|
||||
buffer[len_dir] = L'\\';
|
||||
memcpy(buffer + len_dir + 1, file, len_file * sizeof(WCHAR));
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static BOOL add_file_to_list(const char* local_name, const WCHAR* remote_name, wArrayList* files);
|
||||
|
||||
static BOOL add_directory_entry_to_list(const char* local_dir_name, const WCHAR* remote_dir_name,
|
||||
const struct dirent* entry, wArrayList* files)
|
||||
const struct dirent* entry, wArrayList* files)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
char* local_name = NULL;
|
||||
@ -281,6 +269,7 @@ static BOOL add_directory_entry_to_list(const char* local_dir_name, const WCHAR*
|
||||
return TRUE;
|
||||
|
||||
remote_base_name = convert_local_name_component_to_remote(entry->d_name);
|
||||
|
||||
if (!remote_base_name)
|
||||
return FALSE;
|
||||
|
||||
@ -293,12 +282,11 @@ static BOOL add_directory_entry_to_list(const char* local_dir_name, const WCHAR*
|
||||
free(remote_base_name);
|
||||
free(remote_name);
|
||||
free(local_name);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static BOOL do_add_directory_contents_to_list(const char* local_name, const WCHAR* remote_name,
|
||||
DIR* dirp, wArrayList* files)
|
||||
DIR* dirp, wArrayList* files)
|
||||
{
|
||||
/*
|
||||
* For some reason POSIX does not require readdir() to be thread-safe.
|
||||
@ -313,16 +301,16 @@ static BOOL do_add_directory_contents_to_list(const char* local_name, const WCHA
|
||||
* musl). We should not be breaking people's builds because of that,
|
||||
* so we do nothing and proceed with fingers crossed.
|
||||
*/
|
||||
|
||||
for (;;)
|
||||
{
|
||||
struct dirent* entry = NULL;
|
||||
|
||||
errno = 0;
|
||||
entry = readdir(dirp);
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
int err = errno;
|
||||
|
||||
if (!err)
|
||||
break;
|
||||
|
||||
@ -338,14 +326,13 @@ static BOOL do_add_directory_contents_to_list(const char* local_name, const WCHA
|
||||
}
|
||||
|
||||
static BOOL add_directory_contents_to_list(const char* local_name, const WCHAR* remote_name,
|
||||
wArrayList* files)
|
||||
wArrayList* files)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
DIR* dirp = NULL;
|
||||
|
||||
WLog_VRB(TAG, "adding directory: %s", local_name);
|
||||
|
||||
dirp = opendir(local_name);
|
||||
|
||||
if (!dirp)
|
||||
{
|
||||
int err = errno;
|
||||
@ -360,6 +347,7 @@ static BOOL add_directory_contents_to_list(const char* local_name, const WCHAR*
|
||||
int err = errno;
|
||||
WLog_WARN(TAG, "failed to close directory: %s", strerror(err));
|
||||
}
|
||||
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
@ -367,17 +355,15 @@ out:
|
||||
static BOOL add_file_to_list(const char* local_name, const WCHAR* remote_name, wArrayList* files)
|
||||
{
|
||||
struct posix_file* file = NULL;
|
||||
|
||||
WLog_VRB(TAG, "adding file: %s", local_name);
|
||||
|
||||
file = make_posix_file(local_name, remote_name);
|
||||
|
||||
if (!file)
|
||||
return FALSE;
|
||||
|
||||
if (ArrayList_Add(files, file) < 0)
|
||||
{
|
||||
free_posix_file(file);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -413,22 +399,19 @@ static BOOL process_file_name(const char* local_name, wArrayList* files)
|
||||
BOOL result = FALSE;
|
||||
const char* base_name = NULL;
|
||||
WCHAR* remote_name = NULL;
|
||||
|
||||
/*
|
||||
* Start with the base name of the file. text/uri-list contains the
|
||||
* exact files selected by the user, and we want the remote files
|
||||
* to have names relative to that selection.
|
||||
*/
|
||||
base_name = get_basename(local_name);
|
||||
|
||||
remote_name = convert_local_name_component_to_remote(base_name);
|
||||
|
||||
if (!remote_name)
|
||||
return FALSE;
|
||||
|
||||
result = add_file_to_list(local_name, remote_name, files);
|
||||
|
||||
free(remote_name);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -436,7 +419,6 @@ static BOOL process_uri(const char* uri, size_t uri_len, wArrayList* files)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
char* name = NULL;
|
||||
|
||||
WLog_VRB(TAG, "processing URI: %.*s", uri_len, uri);
|
||||
|
||||
if ((uri_len < strlen("file://")) || strncmp(uri, "file://", strlen("file://")))
|
||||
@ -446,13 +428,13 @@ static BOOL process_uri(const char* uri, size_t uri_len, wArrayList* files)
|
||||
}
|
||||
|
||||
name = decode_percent_encoded_string(uri + strlen("file://"), uri_len - strlen("file://"));
|
||||
|
||||
if (!name)
|
||||
goto out;
|
||||
|
||||
result = process_file_name(name, files);
|
||||
out:
|
||||
free(name);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -462,9 +444,7 @@ static BOOL process_uri_list(const char* data, size_t length, wArrayList* files)
|
||||
const char* lim = data + length;
|
||||
const char* start = NULL;
|
||||
const char* stop = NULL;
|
||||
|
||||
WLog_VRB(TAG, "processing URI list:\n%.*s", length, data);
|
||||
|
||||
ArrayList_Clear(files);
|
||||
|
||||
/*
|
||||
@ -478,9 +458,7 @@ static BOOL process_uri_list(const char* data, size_t length, wArrayList* files)
|
||||
while (cur < lim)
|
||||
{
|
||||
BOOL comment = (*cur == '#');
|
||||
|
||||
start = cur;
|
||||
stop = cur;
|
||||
|
||||
for (stop = cur; stop < lim; stop++)
|
||||
{
|
||||
@ -490,14 +468,17 @@ static BOOL process_uri_list(const char* data, size_t length, wArrayList* files)
|
||||
cur = stop + 2;
|
||||
else
|
||||
cur = stop + 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (*stop == '\n')
|
||||
{
|
||||
cur = stop + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stop == lim)
|
||||
cur = lim;
|
||||
|
||||
@ -512,10 +493,9 @@ static BOOL process_uri_list(const char* data, size_t length, wArrayList* files)
|
||||
}
|
||||
|
||||
static BOOL convert_local_file_to_filedescriptor(const struct posix_file* file,
|
||||
FILEDESCRIPTOR* descriptor)
|
||||
FILEDESCRIPTOR* descriptor)
|
||||
{
|
||||
size_t remote_len = 0;
|
||||
|
||||
descriptor->dwFlags = FD_ATTRIBUTES | FD_FILESIZE | FD_SHOWPROGRESSUI;
|
||||
|
||||
if (file->is_directory)
|
||||
@ -532,6 +512,7 @@ static BOOL convert_local_file_to_filedescriptor(const struct posix_file* file,
|
||||
}
|
||||
|
||||
remote_len = _wcslen(file->remote_name);
|
||||
|
||||
if (remote_len + 1 > ARRAYSIZE(descriptor->cFileName))
|
||||
{
|
||||
WLog_ERR(TAG, "file name too long (%"PRIuz" characters)", remote_len);
|
||||
@ -539,7 +520,6 @@ static BOOL convert_local_file_to_filedescriptor(const struct posix_file* file,
|
||||
}
|
||||
|
||||
memcpy(descriptor->cFileName, file->remote_name, remote_len * sizeof(WCHAR));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -548,10 +528,9 @@ static FILEDESCRIPTOR* convert_local_file_list_to_filedescriptors(wArrayList* fi
|
||||
int i;
|
||||
int count = 0;
|
||||
FILEDESCRIPTOR* descriptors = NULL;
|
||||
|
||||
count = ArrayList_Count(files);
|
||||
|
||||
descriptors = calloc(count, sizeof(descriptors[0]));
|
||||
|
||||
if (!descriptors)
|
||||
goto error;
|
||||
|
||||
@ -564,15 +543,13 @@ static FILEDESCRIPTOR* convert_local_file_list_to_filedescriptors(wArrayList* fi
|
||||
}
|
||||
|
||||
return descriptors;
|
||||
|
||||
error:
|
||||
free(descriptors);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* convert_uri_list_to_filedescriptors(wClipboard* clipboard, UINT32 formatId,
|
||||
const void* data, UINT32* pSize)
|
||||
const void* data, UINT32* pSize)
|
||||
{
|
||||
FILEDESCRIPTOR* descriptors = NULL;
|
||||
|
||||
@ -586,13 +563,12 @@ static void* convert_uri_list_to_filedescriptors(wClipboard* clipboard, UINT32 f
|
||||
return NULL;
|
||||
|
||||
descriptors = convert_local_file_list_to_filedescriptors(clipboard->localFiles);
|
||||
|
||||
if (!descriptors)
|
||||
return NULL;
|
||||
|
||||
*pSize = ArrayList_Count(clipboard->localFiles) * sizeof(FILEDESCRIPTOR);
|
||||
|
||||
clipboard->fileListSequenceNumber = clipboard->sequenceNumber;
|
||||
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
@ -600,25 +576,25 @@ static BOOL register_file_formats_and_synthesizers(wClipboard* clipboard)
|
||||
{
|
||||
UINT32 file_group_format_id;
|
||||
UINT32 local_file_format_id;
|
||||
|
||||
file_group_format_id = ClipboardRegisterFormat(clipboard, "FileGroupDescriptorW");
|
||||
local_file_format_id = ClipboardRegisterFormat(clipboard, "text/uri-list");
|
||||
|
||||
if (!file_group_format_id || !local_file_format_id)
|
||||
goto error;
|
||||
|
||||
clipboard->localFiles = ArrayList_New(FALSE);
|
||||
|
||||
if (!clipboard->localFiles)
|
||||
goto error;
|
||||
|
||||
ArrayList_Object(clipboard->localFiles)->fnObjectFree = free_posix_file;
|
||||
|
||||
if (!ClipboardRegisterSynthesizer(clipboard,
|
||||
local_file_format_id, file_group_format_id,
|
||||
convert_uri_list_to_filedescriptors))
|
||||
local_file_format_id, file_group_format_id,
|
||||
convert_uri_list_to_filedescriptors))
|
||||
goto error_free_local_files;
|
||||
|
||||
return TRUE;
|
||||
|
||||
error_free_local_files:
|
||||
ArrayList_Free(clipboard->localFiles);
|
||||
clipboard->localFiles = NULL;
|
||||
@ -638,12 +614,11 @@ static UINT posix_file_get_size(const struct posix_file* file, INT64* size)
|
||||
}
|
||||
|
||||
*size = statbuf.st_size;
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
static UINT posix_file_request_size(wClipboardDelegate* delegate,
|
||||
const wClipboardFileSizeRequest* request)
|
||||
const wClipboardFileSizeRequest* request)
|
||||
{
|
||||
UINT error = NO_ERROR;
|
||||
INT64 size = 0;
|
||||
@ -656,6 +631,7 @@ static UINT posix_file_request_size(wClipboardDelegate* delegate,
|
||||
return ERROR_INVALID_STATE;
|
||||
|
||||
file = ArrayList_GetItem(delegate->clipboard->localFiles, request->listIndex);
|
||||
|
||||
if (!file)
|
||||
return ERROR_INDEX_ABSENT;
|
||||
|
||||
@ -680,6 +656,7 @@ static UINT posix_file_read_open(struct posix_file* file)
|
||||
return NO_ERROR;
|
||||
|
||||
file->fd = open(file->local_name, O_RDONLY);
|
||||
|
||||
if (file->fd < 0)
|
||||
{
|
||||
int err = errno;
|
||||
@ -696,10 +673,8 @@ static UINT posix_file_read_open(struct posix_file* file)
|
||||
|
||||
file->offset = 0;
|
||||
file->size = statbuf.st_size;
|
||||
|
||||
WLog_VRB(TAG, "open file %d -> %s", file->fd, file->local_name);
|
||||
WLog_VRB(TAG, "file %d size: %"PRIu64" bytes", file->fd, file->size);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@ -715,7 +690,7 @@ static UINT posix_file_read_seek(struct posix_file* file, UINT64 offset)
|
||||
return NO_ERROR;
|
||||
|
||||
WLog_VRB(TAG, "file %d force seeking to %"PRIu64", current %"PRIu64, file->fd,
|
||||
offset, file->offset);
|
||||
offset, file->offset);
|
||||
|
||||
if (lseek(file->fd, offset, SEEK_SET) < 0)
|
||||
{
|
||||
@ -728,14 +703,13 @@ static UINT posix_file_read_seek(struct posix_file* file, UINT64 offset)
|
||||
}
|
||||
|
||||
static UINT posix_file_read_perform(struct posix_file* file, UINT32 size,
|
||||
BYTE** actual_data, UINT32* actual_size)
|
||||
BYTE** actual_data, UINT32* actual_size)
|
||||
{
|
||||
BYTE* buffer = NULL;
|
||||
ssize_t amount = 0;
|
||||
|
||||
WLog_VRB(TAG, "file %d request read %"PRIu32" bytes", file->fd, size);
|
||||
|
||||
buffer = malloc(size);
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
WLog_ERR(TAG, "failed to allocate %"PRIu32" buffer bytes", size);
|
||||
@ -743,6 +717,7 @@ static UINT posix_file_read_perform(struct posix_file* file, UINT32 size,
|
||||
}
|
||||
|
||||
amount = read(file->fd, buffer, size);
|
||||
|
||||
if (amount < 0)
|
||||
{
|
||||
int err = errno;
|
||||
@ -753,15 +728,11 @@ static UINT posix_file_read_perform(struct posix_file* file, UINT32 size,
|
||||
*actual_data = buffer;
|
||||
*actual_size = amount;
|
||||
file->offset += amount;
|
||||
|
||||
WLog_VRB(TAG, "file %d actual read %"PRIu32" bytes (offset %"PRIu64")", file->fd,
|
||||
amount, file->offset);
|
||||
|
||||
amount, file->offset);
|
||||
return NO_ERROR;
|
||||
|
||||
error:
|
||||
free(buffer);
|
||||
|
||||
return ERROR_READ_FAULT;
|
||||
}
|
||||
|
||||
@ -779,6 +750,7 @@ static UINT posix_file_read_close(struct posix_file* file)
|
||||
int err = errno;
|
||||
WLog_WARN(TAG, "failed to close fd %d: %s", file->fd, strerror(err));
|
||||
}
|
||||
|
||||
file->fd = -1;
|
||||
}
|
||||
|
||||
@ -786,31 +758,35 @@ static UINT posix_file_read_close(struct posix_file* file)
|
||||
}
|
||||
|
||||
static UINT posix_file_get_range(struct posix_file* file, UINT64 offset, UINT32 size,
|
||||
BYTE** actual_data, UINT32* actual_size)
|
||||
BYTE** actual_data, UINT32* actual_size)
|
||||
{
|
||||
UINT error = NO_ERROR;
|
||||
|
||||
error = posix_file_read_open(file);
|
||||
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
error = posix_file_read_seek(file, offset);
|
||||
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
error = posix_file_read_perform(file, size, actual_data, actual_size);
|
||||
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
error = posix_file_read_close(file);
|
||||
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
static UINT posix_file_request_range(wClipboardDelegate* delegate,
|
||||
const wClipboardFileRangeRequest* request)
|
||||
const wClipboardFileRangeRequest* request)
|
||||
{
|
||||
UINT error = 0;
|
||||
BYTE* data = NULL;
|
||||
@ -825,6 +801,7 @@ static UINT posix_file_request_range(wClipboardDelegate* delegate,
|
||||
return ERROR_INVALID_STATE;
|
||||
|
||||
file = ArrayList_GetItem(delegate->clipboard->localFiles, request->listIndex);
|
||||
|
||||
if (!file)
|
||||
return ERROR_INDEX_ABSENT;
|
||||
|
||||
@ -840,26 +817,29 @@ static UINT posix_file_request_range(wClipboardDelegate* delegate,
|
||||
WLog_WARN(TAG, "failed to report file range result: 0x%08X", error);
|
||||
|
||||
free(data);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
static UINT dummy_file_size_success(wClipboardDelegate* delegate, const wClipboardFileSizeRequest* request, UINT64 fileSize)
|
||||
static UINT dummy_file_size_success(wClipboardDelegate* delegate,
|
||||
const wClipboardFileSizeRequest* request, UINT64 fileSize)
|
||||
{
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static UINT dummy_file_size_failure(wClipboardDelegate* delegate, const wClipboardFileSizeRequest* request, UINT errorCode)
|
||||
static UINT dummy_file_size_failure(wClipboardDelegate* delegate,
|
||||
const wClipboardFileSizeRequest* request, UINT errorCode)
|
||||
{
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static UINT dummy_file_range_success(wClipboardDelegate* delegate, const wClipboardFileRangeRequest* request, const BYTE* data, UINT32 size)
|
||||
static UINT dummy_file_range_success(wClipboardDelegate* delegate,
|
||||
const wClipboardFileRangeRequest* request, const BYTE* data, UINT32 size)
|
||||
{
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static UINT dummy_file_range_failure(wClipboardDelegate* delegate, const wClipboardFileRangeRequest* request, UINT errorCode)
|
||||
static UINT dummy_file_range_failure(wClipboardDelegate* delegate,
|
||||
const wClipboardFileRangeRequest* request, UINT errorCode)
|
||||
{
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
@ -869,7 +849,6 @@ static void setup_delegate(wClipboardDelegate* delegate)
|
||||
delegate->ClientRequestFileSize = posix_file_request_size;
|
||||
delegate->ClipboardFileSizeSuccess = dummy_file_size_success;
|
||||
delegate->ClipboardFileSizeFailure = dummy_file_size_failure;
|
||||
|
||||
delegate->ClientRequestFileRange = posix_file_request_range;
|
||||
delegate->ClipboardFileRangeSuccess = dummy_file_range_success;
|
||||
delegate->ClipboardFileRangeFailure = dummy_file_range_failure;
|
||||
@ -884,6 +863,5 @@ BOOL ClipboardInitPosixFileSubsystem(wClipboard* clipboard)
|
||||
return FALSE;
|
||||
|
||||
setup_delegate(&clipboard->delegate);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -28,24 +28,25 @@
|
||||
|
||||
#include "../sspi.h"
|
||||
|
||||
char* CREDSSP_PACKAGE_NAME = "CredSSP";
|
||||
static const char* CREDSSP_PACKAGE_NAME = "CredSSP";
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY credssp_InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext,
|
||||
SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
|
||||
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
|
||||
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
|
||||
static SECURITY_STATUS SEC_ENTRY credssp_InitializeSecurityContextW(PCredHandle phCredential,
|
||||
PCtxtHandle phContext,
|
||||
SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
|
||||
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
|
||||
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
|
||||
{
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY credssp_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext,
|
||||
SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
|
||||
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
|
||||
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
|
||||
static SECURITY_STATUS SEC_ENTRY credssp_InitializeSecurityContextA(PCredHandle phCredential,
|
||||
PCtxtHandle phContext,
|
||||
SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
|
||||
PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
|
||||
PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
|
||||
{
|
||||
CREDSSP_CONTEXT* context;
|
||||
SSPI_CREDENTIALS* credentials;
|
||||
|
||||
context = (CREDSSP_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (!context)
|
||||
@ -57,6 +58,12 @@ SECURITY_STATUS SEC_ENTRY credssp_InitializeSecurityContextA(PCredHandle phCrede
|
||||
|
||||
credentials = (SSPI_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
|
||||
|
||||
if (!credentials)
|
||||
{
|
||||
credssp_ContextFree(context);
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
sspi_SecureHandleSetLowerPointer(phNewContext, context);
|
||||
sspi_SecureHandleSetUpperPointer(phNewContext, (void*) CREDSSP_PACKAGE_NAME);
|
||||
}
|
||||
@ -64,10 +71,9 @@ SECURITY_STATUS SEC_ENTRY credssp_InitializeSecurityContextA(PCredHandle phCrede
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
CREDSSP_CONTEXT* credssp_ContextNew()
|
||||
CREDSSP_CONTEXT* credssp_ContextNew(void)
|
||||
{
|
||||
CREDSSP_CONTEXT* context;
|
||||
|
||||
context = (CREDSSP_CONTEXT*) calloc(1, sizeof(CREDSSP_CONTEXT));
|
||||
|
||||
if (!context)
|
||||
@ -81,7 +87,9 @@ void credssp_ContextFree(CREDSSP_CONTEXT* context)
|
||||
free(context);
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY credssp_QueryContextAttributes(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer)
|
||||
static SECURITY_STATUS SEC_ENTRY credssp_QueryContextAttributes(PCtxtHandle phContext,
|
||||
ULONG ulAttribute,
|
||||
void* pBuffer)
|
||||
{
|
||||
if (!phContext)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
@ -92,16 +100,18 @@ SECURITY_STATUS SEC_ENTRY credssp_QueryContextAttributes(PCtxtHandle phContext,
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY credssp_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage,
|
||||
ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
|
||||
void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
|
||||
SECURITY_STATUS SEC_ENTRY credssp_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal,
|
||||
SEC_WCHAR* pszPackage,
|
||||
ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
|
||||
void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
|
||||
{
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY credssp_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage,
|
||||
ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
|
||||
void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
|
||||
static SECURITY_STATUS SEC_ENTRY credssp_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal,
|
||||
SEC_CHAR* pszPackage,
|
||||
ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
|
||||
void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
|
||||
{
|
||||
SSPI_CREDENTIALS* credentials;
|
||||
SEC_WINNT_AUTH_IDENTITY* identity;
|
||||
@ -114,30 +124,30 @@ SECURITY_STATUS SEC_ENTRY credssp_AcquireCredentialsHandleA(SEC_CHAR* pszPrincip
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData;
|
||||
|
||||
CopyMemory(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY));
|
||||
|
||||
sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials);
|
||||
sspi_SecureHandleSetUpperPointer(phCredential, (void*) CREDSSP_PACKAGE_NAME);
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY credssp_QueryCredentialsAttributesW(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer)
|
||||
static SECURITY_STATUS SEC_ENTRY credssp_QueryCredentialsAttributesW(PCredHandle phCredential,
|
||||
ULONG ulAttribute, void* pBuffer)
|
||||
{
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY credssp_QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer)
|
||||
static SECURITY_STATUS SEC_ENTRY credssp_QueryCredentialsAttributesA(PCredHandle phCredential,
|
||||
ULONG ulAttribute, void* pBuffer)
|
||||
{
|
||||
if (ulAttribute == SECPKG_CRED_ATTR_NAMES)
|
||||
{
|
||||
SSPI_CREDENTIALS* credentials;
|
||||
SSPI_CREDENTIALS* credentials = (SSPI_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
|
||||
|
||||
credentials = (SSPI_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential);
|
||||
if (!credentials)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
@ -145,7 +155,7 @@ SECURITY_STATUS SEC_ENTRY credssp_QueryCredentialsAttributesA(PCredHandle phCred
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY credssp_FreeCredentialsHandle(PCredHandle phCredential)
|
||||
static SECURITY_STATUS SEC_ENTRY credssp_FreeCredentialsHandle(PCredHandle phCredential)
|
||||
{
|
||||
SSPI_CREDENTIALS* credentials;
|
||||
|
||||
@ -158,26 +168,31 @@ SECURITY_STATUS SEC_ENTRY credssp_FreeCredentialsHandle(PCredHandle phCredential
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
sspi_CredentialsFree(credentials);
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY credssp_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
|
||||
static SECURITY_STATUS SEC_ENTRY credssp_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
|
||||
PSecBufferDesc pMessage, ULONG MessageSeqNo)
|
||||
{
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY credssp_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, ULONG* pfQOP)
|
||||
static SECURITY_STATUS SEC_ENTRY credssp_DecryptMessage(PCtxtHandle phContext,
|
||||
PSecBufferDesc pMessage,
|
||||
ULONG MessageSeqNo, ULONG* pfQOP)
|
||||
{
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY credssp_MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
|
||||
static SECURITY_STATUS SEC_ENTRY credssp_MakeSignature(PCtxtHandle phContext, ULONG fQOP,
|
||||
PSecBufferDesc pMessage, ULONG MessageSeqNo)
|
||||
{
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY credssp_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, ULONG* pfQOP)
|
||||
static SECURITY_STATUS SEC_ENTRY credssp_VerifySignature(PCtxtHandle phContext,
|
||||
PSecBufferDesc pMessage,
|
||||
ULONG MessageSeqNo, ULONG* pfQOP)
|
||||
{
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
@ -256,14 +271,14 @@ const SecPkgInfoA CREDSSP_SecPkgInfoA =
|
||||
"Microsoft CredSSP Security Provider" /* Comment */
|
||||
};
|
||||
|
||||
WCHAR CREDSSP_SecPkgInfoW_Name[] = { 'C','R','E','D','S','S','P','\0' };
|
||||
static WCHAR CREDSSP_SecPkgInfoW_Name[] = { 'C', 'R', 'E', 'D', 'S', 'S', 'P', '\0' };
|
||||
|
||||
WCHAR CREDSSP_SecPkgInfoW_Comment[] =
|
||||
static WCHAR CREDSSP_SecPkgInfoW_Comment[] =
|
||||
{
|
||||
'M','i','c','r','o','s','o','f','t',' ',
|
||||
'C','r','e','d','S','S','P',' ',
|
||||
'S','e','c','u','r','i','t','y',' ',
|
||||
'P','r','o','v','i','d','e','r','\0'
|
||||
'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', ' ',
|
||||
'C', 'r', 'e', 'd', 'S', 'S', 'P', ' ',
|
||||
'S', 'e', 'c', 'u', 'r', 'i', 't', 'y', ' ',
|
||||
'P', 'r', 'o', 'v', 'i', 'd', 'e', 'r', '\0'
|
||||
};
|
||||
|
||||
const SecPkgInfoW CREDSSP_SecPkgInfoW =
|
||||
|
@ -60,7 +60,7 @@ static BOOL TimerIsHandled(HANDLE handle)
|
||||
|
||||
static int TimerGetFd(HANDLE handle)
|
||||
{
|
||||
WINPR_TIMER *timer = (WINPR_TIMER *)handle;
|
||||
WINPR_TIMER* timer = (WINPR_TIMER*)handle;
|
||||
|
||||
if (!TimerIsHandled(handle))
|
||||
return -1;
|
||||
@ -72,12 +72,12 @@ static DWORD TimerCleanupHandle(HANDLE handle)
|
||||
{
|
||||
int length;
|
||||
UINT64 expirations;
|
||||
WINPR_TIMER *timer = (WINPR_TIMER *)handle;
|
||||
WINPR_TIMER* timer = (WINPR_TIMER*)handle;
|
||||
|
||||
if (!TimerIsHandled(handle))
|
||||
return WAIT_FAILED;
|
||||
|
||||
length = read(timer->fd, (void *) &expirations, sizeof(UINT64));
|
||||
length = read(timer->fd, (void*) &expirations, sizeof(UINT64));
|
||||
|
||||
if (length != 8)
|
||||
{
|
||||
@ -99,22 +99,22 @@ static DWORD TimerCleanupHandle(HANDLE handle)
|
||||
return WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
BOOL TimerCloseHandle(HANDLE handle) {
|
||||
BOOL TimerCloseHandle(HANDLE handle)
|
||||
{
|
||||
WINPR_TIMER* timer;
|
||||
timer = (WINPR_TIMER*) handle;
|
||||
|
||||
if (!TimerIsHandled(handle))
|
||||
return FALSE;
|
||||
if (!TimerIsHandled(handle))
|
||||
return FALSE;
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
if (timer->fd != -1)
|
||||
if (timer->fd != -1)
|
||||
close(timer->fd);
|
||||
|
||||
#endif
|
||||
free(timer);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef WITH_POSIX_TIMER
|
||||
@ -139,7 +139,7 @@ static void WaitableTimerSignalHandler(int signum, siginfo_t* siginfo, void* arg
|
||||
|
||||
if ((timer_settime(timer->tid, 0, &(timer->timeout), NULL)) != 0)
|
||||
{
|
||||
WLog_ERR(TAG,"timer_settime");
|
||||
WLog_ERR(TAG, "timer_settime");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -186,6 +186,7 @@ int InitializeWaitableTimer(WINPR_TIMER* timer)
|
||||
close(timer->fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
WLog_ERR(TAG, "%s: os specific implementation is missing", __FUNCTION__);
|
||||
result = -1;
|
||||
@ -203,9 +204,10 @@ int InitializeWaitableTimer(WINPR_TIMER* timer)
|
||||
|
||||
if ((timer_create(CLOCK_MONOTONIC, &sigev, &(timer->tid))) != 0)
|
||||
{
|
||||
WLog_ERR(TAG,"timer_create");
|
||||
WLog_ERR(TAG, "timer_create");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
WLog_ERR(TAG, "%s: os specific implementation is missing", __FUNCTION__);
|
||||
result = -1;
|
||||
@ -217,23 +219,25 @@ int InitializeWaitableTimer(WINPR_TIMER* timer)
|
||||
}
|
||||
|
||||
|
||||
static HANDLE_OPS ops = {
|
||||
TimerIsHandled,
|
||||
TimerCloseHandle,
|
||||
TimerGetFd,
|
||||
TimerCleanupHandle
|
||||
static HANDLE_OPS ops =
|
||||
{
|
||||
TimerIsHandled,
|
||||
TimerCloseHandle,
|
||||
TimerGetFd,
|
||||
TimerCleanupHandle
|
||||
};
|
||||
|
||||
/**
|
||||
* Waitable Timer
|
||||
*/
|
||||
|
||||
HANDLE CreateWaitableTimerA(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset, LPCSTR lpTimerName)
|
||||
HANDLE CreateWaitableTimerA(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset,
|
||||
LPCSTR lpTimerName)
|
||||
{
|
||||
HANDLE handle = NULL;
|
||||
WINPR_TIMER* timer;
|
||||
|
||||
timer = (WINPR_TIMER*) calloc(1, sizeof(WINPR_TIMER));
|
||||
|
||||
if (timer)
|
||||
{
|
||||
WINPR_HANDLE_SET_TYPE_AND_MODE(timer, HANDLE_TYPE_TIMER, WINPR_FD_READ);
|
||||
@ -250,25 +254,28 @@ HANDLE CreateWaitableTimerA(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManua
|
||||
return handle;
|
||||
}
|
||||
|
||||
HANDLE CreateWaitableTimerW(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset, LPCWSTR lpTimerName)
|
||||
HANDLE CreateWaitableTimerW(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset,
|
||||
LPCWSTR lpTimerName)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HANDLE CreateWaitableTimerExA(LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCSTR lpTimerName, DWORD dwFlags, DWORD dwDesiredAccess)
|
||||
HANDLE CreateWaitableTimerExA(LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCSTR lpTimerName,
|
||||
DWORD dwFlags, DWORD dwDesiredAccess)
|
||||
{
|
||||
BOOL bManualReset;
|
||||
bManualReset = (dwFlags & CREATE_WAITABLE_TIMER_MANUAL_RESET) ? TRUE : FALSE;
|
||||
return CreateWaitableTimerA(lpTimerAttributes, bManualReset, lpTimerName);
|
||||
}
|
||||
|
||||
HANDLE CreateWaitableTimerExW(LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCWSTR lpTimerName, DWORD dwFlags, DWORD dwDesiredAccess)
|
||||
HANDLE CreateWaitableTimerExW(LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCWSTR lpTimerName,
|
||||
DWORD dwFlags, DWORD dwDesiredAccess)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL SetWaitableTimer(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPeriod,
|
||||
PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, BOOL fResume)
|
||||
PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, BOOL fResume)
|
||||
{
|
||||
ULONG Type;
|
||||
WINPR_HANDLE* Object;
|
||||
@ -358,7 +365,7 @@ BOOL SetWaitableTimer(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPerio
|
||||
{
|
||||
if ((timer_settime(timer->tid, 0, &(timer->timeout), NULL)) != 0)
|
||||
{
|
||||
WLog_ERR(TAG,"timer_settime");
|
||||
WLog_ERR(TAG, "timer_settime");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -368,20 +375,19 @@ BOOL SetWaitableTimer(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPerio
|
||||
}
|
||||
|
||||
BOOL SetWaitableTimerEx(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPeriod,
|
||||
PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext, ULONG TolerableDelay)
|
||||
PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext,
|
||||
ULONG TolerableDelay)
|
||||
{
|
||||
ULONG Type;
|
||||
WINPR_HANDLE* Object;
|
||||
WINPR_TIMER* timer;
|
||||
|
||||
if (!winpr_Handle_GetInfo(hTimer, &Type, &Object))
|
||||
return FALSE;
|
||||
|
||||
(void)Object;
|
||||
|
||||
if (Type == HANDLE_TYPE_TIMER)
|
||||
{
|
||||
timer = (WINPR_TIMER*) Object;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -590,6 +596,9 @@ static void* TimerQueueThread(void* arg)
|
||||
FireExpiredTimerQueueTimers(timerQueue);
|
||||
pthread_mutex_unlock(&(timerQueue->cond_mutex));
|
||||
|
||||
if ((status != ETIMEDOUT) && (status != 0))
|
||||
break;
|
||||
|
||||
if (timerQueue->bCancelled)
|
||||
break;
|
||||
}
|
||||
@ -646,7 +655,6 @@ BOOL DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
|
||||
pthread_cond_signal(&(timerQueue->cond));
|
||||
pthread_mutex_unlock(&(timerQueue->cond_mutex));
|
||||
pthread_join(timerQueue->thread, &rvalue);
|
||||
|
||||
/**
|
||||
* Quote from MSDN regarding CompletionEvent:
|
||||
* If this parameter is INVALID_HANDLE_VALUE, the function waits for
|
||||
@ -657,7 +665,6 @@ BOOL DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
|
||||
* Note: The current WinPR implementation implicitly waits for any
|
||||
* callback functions to complete (see pthread_join above)
|
||||
*/
|
||||
|
||||
{
|
||||
/* Move all active timers to the inactive timer list */
|
||||
node = timerQueue->activeHead;
|
||||
@ -681,7 +688,6 @@ BOOL DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent)
|
||||
|
||||
timerQueue->inactiveHead = NULL;
|
||||
}
|
||||
|
||||
/* Delete timer queue */
|
||||
pthread_cond_destroy(&(timerQueue->cond));
|
||||
pthread_mutex_destroy(&(timerQueue->cond_mutex));
|
||||
@ -701,7 +707,7 @@ BOOL DeleteTimerQueue(HANDLE TimerQueue)
|
||||
}
|
||||
|
||||
BOOL CreateTimerQueueTimer(PHANDLE phNewTimer, HANDLE TimerQueue,
|
||||
WAITORTIMERCALLBACK Callback, PVOID Parameter, DWORD DueTime, DWORD Period, ULONG Flags)
|
||||
WAITORTIMERCALLBACK Callback, PVOID Parameter, DWORD DueTime, DWORD Period, ULONG Flags)
|
||||
{
|
||||
struct timespec CurrentTime;
|
||||
WINPR_TIMER_QUEUE* timerQueue;
|
||||
@ -775,7 +781,6 @@ BOOL DeleteTimerQueueTimer(HANDLE TimerQueue, HANDLE Timer, HANDLE CompletionEve
|
||||
timerQueue = (WINPR_TIMER_QUEUE*) TimerQueue;
|
||||
timer = (WINPR_TIMER_QUEUE_TIMER*) Timer;
|
||||
pthread_mutex_lock(&(timerQueue->cond_mutex));
|
||||
|
||||
/**
|
||||
* Quote from MSDN regarding CompletionEvent:
|
||||
* If this parameter is INVALID_HANDLE_VALUE, the function waits for
|
||||
@ -786,9 +791,7 @@ BOOL DeleteTimerQueueTimer(HANDLE TimerQueue, HANDLE Timer, HANDLE CompletionEve
|
||||
* Note: The current WinPR implementation implicitly waits for any
|
||||
* callback functions to complete (see cond_mutex usage)
|
||||
*/
|
||||
|
||||
RemoveTimerQueueTimer(&(timerQueue->activeHead), timer);
|
||||
|
||||
pthread_cond_signal(&(timerQueue->cond));
|
||||
pthread_mutex_unlock(&(timerQueue->cond_mutex));
|
||||
free(timer);
|
||||
|
@ -96,7 +96,7 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
||||
char* pEnd;
|
||||
char* buffer;
|
||||
char* pOutput;
|
||||
int numArgs;
|
||||
int numArgs = 0;
|
||||
LPSTR* pArgs;
|
||||
int maxNumArgs;
|
||||
int maxBufferSize;
|
||||
@ -111,7 +111,6 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
||||
return NULL;
|
||||
|
||||
pArgs = NULL;
|
||||
numArgs = 0;
|
||||
lpEscapedCmdLine = NULL;
|
||||
cmdLineLength = (int) strlen(lpCmdLine);
|
||||
lpEscapedChars = (BOOL*) calloc(cmdLineLength + 1, sizeof(BOOL));
|
||||
@ -204,7 +203,6 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
||||
|
||||
pArgs = (LPSTR*) buffer;
|
||||
pOutput = (char*) &buffer[maxNumArgs * (sizeof(char*))];
|
||||
numArgs = 0;
|
||||
p = (char*) lpCmdLine;
|
||||
|
||||
while (p < lpCmdLine + cmdLineLength)
|
||||
|
@ -282,7 +282,6 @@ static BOOL thread_compare(void* a, void* b)
|
||||
* in thread function. */
|
||||
static void* thread_launcher(void* arg)
|
||||
{
|
||||
DWORD res = 1;
|
||||
void* rc = NULL;
|
||||
WINPR_THREAD* thread = (WINPR_THREAD*) arg;
|
||||
typedef void* (*fkt_t)(void*);
|
||||
@ -296,7 +295,7 @@ static void* thread_launcher(void* arg)
|
||||
|
||||
if (!(fkt = (fkt_t)thread->lpStartAddress))
|
||||
{
|
||||
WLog_ERR(TAG, "Thread function argument is %p", (void *)fkt);
|
||||
WLog_ERR(TAG, "Thread function argument is %p", (void*)fkt);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -326,7 +325,6 @@ exit:
|
||||
thread->dwExitCode = (DWORD)(size_t)rc;
|
||||
|
||||
set_event(thread);
|
||||
res = thread->dwExitCode;
|
||||
|
||||
if (thread->detached || !thread->started)
|
||||
cleanup_handle(thread);
|
||||
|
@ -52,31 +52,19 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
|
||||
int i, j;
|
||||
int status;
|
||||
int count;
|
||||
int length;
|
||||
int index;
|
||||
BOOL match;
|
||||
BOOL found;
|
||||
BOOL argument;
|
||||
BOOL escaped;
|
||||
size_t length;
|
||||
BOOL notescaped;
|
||||
char* sigil;
|
||||
int sigil_length;
|
||||
int sigil_index;
|
||||
size_t sigil_length;
|
||||
char* keyword;
|
||||
int keyword_length;
|
||||
int keyword_index;
|
||||
SSIZE_T keyword_length;
|
||||
SSIZE_T keyword_index;
|
||||
char* separator;
|
||||
int separator_length;
|
||||
int separator_index;
|
||||
char* value;
|
||||
int value_length;
|
||||
int value_index;
|
||||
int toggle;
|
||||
|
||||
status = 0;
|
||||
match = FALSE;
|
||||
found = FALSE;
|
||||
argument = FALSE;
|
||||
escaped = TRUE;
|
||||
|
||||
notescaped = FALSE;
|
||||
|
||||
if (!argv)
|
||||
@ -93,8 +81,8 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
index = i;
|
||||
escaped = TRUE;
|
||||
BOOL found = FALSE;
|
||||
BOOL escaped = TRUE;
|
||||
|
||||
if (preFilter)
|
||||
{
|
||||
@ -113,10 +101,8 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
|
||||
}
|
||||
}
|
||||
|
||||
sigil_index = 0;
|
||||
sigil_length = 0;
|
||||
sigil = (char*) &argv[i][sigil_index];
|
||||
length = (int) strlen(argv[i]);
|
||||
sigil = (char*) argv[i];
|
||||
length = strlen(argv[i]);
|
||||
|
||||
if ((sigil[0] == '/') && (flags & COMMAND_LINE_SIGIL_SLASH))
|
||||
{
|
||||
@ -165,12 +151,12 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
|
||||
{
|
||||
if ((flags & COMMAND_LINE_IGN_UNKNOWN_KEYWORD))
|
||||
continue;
|
||||
|
||||
return COMMAND_LINE_ERROR_NO_KEYWORD;
|
||||
}
|
||||
|
||||
keyword_index = sigil_index + sigil_length;
|
||||
keyword_index = sigil_length;
|
||||
keyword = (char*) &argv[i][keyword_index];
|
||||
|
||||
toggle = -1;
|
||||
|
||||
if (flags & COMMAND_LINE_SIGIL_ENABLE_DISABLE)
|
||||
@ -199,31 +185,24 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
|
||||
|
||||
if (separator)
|
||||
{
|
||||
separator_length = 1;
|
||||
separator_index = (int)(separator - argv[i]);
|
||||
keyword_length = (int)(separator - keyword);
|
||||
value_index = separator_index + separator_length;
|
||||
SSIZE_T separator_index = (separator - argv[i]);
|
||||
SSIZE_T value_index = separator_index + 1;
|
||||
keyword_length = (separator - keyword);
|
||||
value = (char*) &argv[i][value_index];
|
||||
value_length = (length - value_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
separator_length = 0;
|
||||
separator_index = -1;
|
||||
keyword_length = (length - keyword_index);
|
||||
value_index = -1;
|
||||
|
||||
value = NULL;
|
||||
value_length = 0;
|
||||
}
|
||||
|
||||
if (!escaped)
|
||||
continue;
|
||||
|
||||
found = FALSE;
|
||||
|
||||
for (j = 0; options[j].Name != NULL; j++)
|
||||
{
|
||||
match = FALSE;
|
||||
BOOL match = FALSE;
|
||||
|
||||
if (strncmp(options[j].Name, keyword, keyword_length) == 0)
|
||||
{
|
||||
@ -244,10 +223,11 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
|
||||
continue;
|
||||
|
||||
found = match;
|
||||
options[j].Index = index;
|
||||
options[j].Index = i;
|
||||
|
||||
if ((flags & COMMAND_LINE_SEPARATOR_SPACE) && ((i + 1) < argc))
|
||||
{
|
||||
BOOL argument;
|
||||
int value_present = 1;
|
||||
|
||||
if (flags & COMMAND_LINE_SIGIL_DASH)
|
||||
@ -273,20 +253,14 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
|
||||
argument = TRUE;
|
||||
else
|
||||
argument = FALSE;
|
||||
|
||||
if (value_present && argument)
|
||||
{
|
||||
i++;
|
||||
value_index = 0;
|
||||
length = (int) strlen(argv[i]);
|
||||
value = (char*) &argv[i][value_index];
|
||||
value_length = (length - value_index);
|
||||
value = (char*) argv[i];
|
||||
}
|
||||
else if (!value_present && (options[j].Flags & COMMAND_LINE_VALUE_OPTIONAL))
|
||||
{
|
||||
value_index = 0;
|
||||
value = NULL;
|
||||
value_length = 0;
|
||||
}
|
||||
else if (!value_present && argument)
|
||||
return COMMAND_LINE_ERROR;
|
||||
@ -302,9 +276,7 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
|
||||
if (value && (options[j].Flags & COMMAND_LINE_VALUE_FLAG))
|
||||
{
|
||||
i--;
|
||||
value_index = -1;
|
||||
value = NULL;
|
||||
value_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -365,7 +337,6 @@ int CommandLineParseArgumentsA(int argc, LPCSTR* argv, COMMAND_LINE_ARGUMENT_A*
|
||||
else if (options[j].Flags & COMMAND_LINE_PRINT_BUILDCONFIG)
|
||||
return COMMAND_LINE_STATUS_PRINT_BUILDCONFIG;
|
||||
}
|
||||
|
||||
if (!found && (flags & COMMAND_LINE_IGN_UNKNOWN_KEYWORD) == 0)
|
||||
return COMMAND_LINE_ERROR_NO_KEYWORD;
|
||||
}
|
||||
@ -409,7 +380,7 @@ int CommandLineClearArgumentsW(COMMAND_LINE_ARGUMENT_W* options)
|
||||
|
||||
COMMAND_LINE_ARGUMENT_A* CommandLineFindArgumentA(COMMAND_LINE_ARGUMENT_A* options, LPCSTR Name)
|
||||
{
|
||||
size_t i;
|
||||
int i;
|
||||
|
||||
for (i = 0; options[i].Name != NULL; i++)
|
||||
{
|
||||
@ -428,7 +399,7 @@ COMMAND_LINE_ARGUMENT_A* CommandLineFindArgumentA(COMMAND_LINE_ARGUMENT_A* optio
|
||||
|
||||
COMMAND_LINE_ARGUMENT_W* CommandLineFindArgumentW(COMMAND_LINE_ARGUMENT_W* options, LPCWSTR Name)
|
||||
{
|
||||
size_t i;
|
||||
int i;
|
||||
|
||||
for (i = 0; options[i].Name != NULL; i++)
|
||||
{
|
||||
@ -449,9 +420,6 @@ COMMAND_LINE_ARGUMENT_A* CommandLineFindNextArgumentA(COMMAND_LINE_ARGUMENT_A* a
|
||||
{
|
||||
COMMAND_LINE_ARGUMENT_A* nextArgument;
|
||||
|
||||
if (!argument)
|
||||
return NULL;
|
||||
|
||||
nextArgument = &argument[1];
|
||||
|
||||
if (nextArgument->Name == NULL)
|
||||
|
@ -93,7 +93,8 @@ static struct CRYPTO_dynlock_value* _winpr_openssl_dynlock_create(const char* fi
|
||||
return dynlock;
|
||||
}
|
||||
|
||||
static void _winpr_openssl_dynlock_lock(int mode, struct CRYPTO_dynlock_value* dynlock, const char* file, int line)
|
||||
static void _winpr_openssl_dynlock_lock(int mode, struct CRYPTO_dynlock_value* dynlock,
|
||||
const char* file, int line)
|
||||
{
|
||||
if (mode & CRYPTO_LOCK)
|
||||
{
|
||||
@ -105,7 +106,8 @@ static void _winpr_openssl_dynlock_lock(int mode, struct CRYPTO_dynlock_value* d
|
||||
}
|
||||
}
|
||||
|
||||
static void _winpr_openssl_dynlock_destroy(struct CRYPTO_dynlock_value* dynlock, const char* file, int line)
|
||||
static void _winpr_openssl_dynlock_destroy(struct CRYPTO_dynlock_value* dynlock, const char* file,
|
||||
int line)
|
||||
{
|
||||
CloseHandle(dynlock->mutex);
|
||||
free(dynlock);
|
||||
@ -159,8 +161,8 @@ static BOOL _winpr_openssl_initialize_locking(void)
|
||||
/* OpenSSL dynamic locking */
|
||||
|
||||
if (CRYPTO_get_dynlock_create_callback() ||
|
||||
CRYPTO_get_dynlock_lock_callback() ||
|
||||
CRYPTO_get_dynlock_destroy_callback())
|
||||
CRYPTO_get_dynlock_lock_callback() ||
|
||||
CRYPTO_get_dynlock_destroy_callback())
|
||||
{
|
||||
WLog_WARN(TAG, "dynamic locking callbacks are already set");
|
||||
}
|
||||
@ -246,6 +248,7 @@ static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVO
|
||||
}
|
||||
|
||||
#ifdef WINPR_OPENSSL_LOCKING_REQUIRED
|
||||
|
||||
if (flags & WINPR_SSL_INIT_ENABLE_LOCKING)
|
||||
{
|
||||
if (!_winpr_openssl_initialize_locking())
|
||||
@ -253,6 +256,7 @@ static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVO
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
/* SSL_load_error_strings() is void */
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
|
||||
@ -262,12 +266,14 @@ static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVO
|
||||
OpenSSL_add_all_digests();
|
||||
OpenSSL_add_all_ciphers();
|
||||
#else
|
||||
|
||||
if (OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS |
|
||||
OPENSSL_INIT_LOAD_CRYPTO_STRINGS |
|
||||
OPENSSL_INIT_ADD_ALL_CIPHERS |
|
||||
OPENSSL_INIT_ADD_ALL_DIGESTS |
|
||||
OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL) != 1)
|
||||
OPENSSL_INIT_LOAD_CRYPTO_STRINGS |
|
||||
OPENSSL_INIT_ADD_ALL_CIPHERS |
|
||||
OPENSSL_INIT_ADD_ALL_DIGESTS |
|
||||
OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL) != 1)
|
||||
return FALSE;
|
||||
|
||||
#endif
|
||||
g_winpr_openssl_initialized_by_winpr = TRUE;
|
||||
return TRUE;
|
||||
@ -301,10 +307,13 @@ BOOL winpr_CleanupSSL(DWORD flags)
|
||||
ERR_free_strings();
|
||||
EVP_cleanup();
|
||||
#endif
|
||||
#ifdef WINPR_OPENSSL_LOCKING_REQUIRED
|
||||
flags |= WINPR_SSL_CLEANUP_THREAD;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WINPR_OPENSSL_LOCKING_REQUIRED
|
||||
|
||||
if (flags & WINPR_SSL_CLEANUP_THREAD)
|
||||
{
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000L) || defined(LIBRESSL_VERSION_NUMBER)
|
||||
@ -313,6 +322,7 @@ BOOL winpr_CleanupSSL(DWORD flags)
|
||||
ERR_remove_thread_state(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -5,8 +5,8 @@
|
||||
int TestBipBuffer(int argc, char* argv[])
|
||||
{
|
||||
BYTE* data;
|
||||
int rc = -1;
|
||||
wBipBuffer* bb;
|
||||
|
||||
bb = BipBuffer_New(1024);
|
||||
|
||||
if (!bb)
|
||||
@ -14,9 +14,10 @@ int TestBipBuffer(int argc, char* argv[])
|
||||
|
||||
data = BipBuffer_WriteReserve(bb, 1024 * 2);
|
||||
|
||||
if (data)
|
||||
rc = 0;
|
||||
|
||||
fprintf(stderr, "BipBuffer_BufferSize: %"PRIuz"\n", BipBuffer_BufferSize(bb));
|
||||
|
||||
BipBuffer_Free(bb);
|
||||
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user