summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2012-08-02 14:39:35 -0700
committerJay Sorg <jay.sorg@gmail.com>2012-08-02 14:39:35 -0700
commit97ec29f9fff14aa28d1a0e22c3fcfea00a9dd4df (patch)
tree196a13f5d9b32a1bf797b688adc3fd0065b3a8eb
parente9aa5df42086b32f9bce915c063464f25b388e3b (diff)
downloadxrdp-proprietary-97ec29f9fff14aa28d1a0e22c3fcfea00a9dd4df.tar.gz
xrdp-proprietary-97ec29f9fff14aa28d1a0e22c3fcfea00a9dd4df.zip
xrdpapi: complete basic WTSVirtual* functions
-rw-r--r--xrdpapi/xrdpapi.c308
-rw-r--r--xrdpapi/xrdpapi.h18
2 files changed, 318 insertions, 8 deletions
diff --git a/xrdpapi/xrdpapi.c b/xrdpapi/xrdpapi.c
index 3afc8594..3190cd39 100644
--- a/xrdpapi/xrdpapi.c
+++ b/xrdpapi/xrdpapi.c
@@ -17,16 +17,148 @@
* limitations under the License.
*/
+/* do not use os_calls in here */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
#include "xrdpapi.h"
+struct wts_obj
+{
+ int fd;
+ int status;
+ char name[8];
+ char dname[128];
+ int display_num;
+};
+
+/*****************************************************************************/
+static int
+get_display_num_from_display(char* display_text)
+{
+ int index;
+ int mode;
+ int host_index;
+ int disp_index;
+ int scre_index;
+ char host[256];
+ char disp[256];
+ char scre[256];
+
+ index = 0;
+ host_index = 0;
+ disp_index = 0;
+ scre_index = 0;
+ mode = 0;
+ while (display_text[index] != 0)
+ {
+ if (display_text[index] == ':')
+ {
+ mode = 1;
+ }
+ else if (display_text[index] == '.')
+ {
+ mode = 2;
+ }
+ else if (mode == 0)
+ {
+ host[host_index] = display_text[index];
+ host_index++;
+ }
+ else if (mode == 1)
+ {
+ disp[disp_index] = display_text[index];
+ disp_index++;
+ }
+ else if (mode == 2)
+ {
+ scre[scre_index] = display_text[index];
+ scre_index++;
+ }
+ index++;
+ }
+ host[host_index] = 0;
+ disp[disp_index] = 0;
+ scre[scre_index] = 0;
+ return atoi(disp);
+}
+
/*****************************************************************************/
void*
WTSVirtualChannelOpen(void* hServer, unsigned int SessionId,
const char* pVirtualName)
{
+ if (hServer != WTS_CURRENT_SERVER_HANDLE)
+ {
+ return 0;
+ }
+ return WTSVirtualChannelOpenEx(SessionId, pVirtualName, 0);
+}
+
+/*****************************************************************************/
+static int
+can_send(int sck, int millis)
+{
+ struct timeval time;
+ fd_set wfds;
+ int select_rv;
+
+ FD_ZERO(&wfds);
+ FD_SET(sck, &wfds);
+ time.tv_sec = millis / 1000;
+ time.tv_usec = (millis * 1000) % 1000000;
+ select_rv = select(sck + 1, 0, &wfds, 0, &time);
+ if (select_rv > 0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+can_recv(int sck, int millis)
+{
+ struct timeval time;
+ fd_set rfds;
+ int select_rv;
+
+ FD_ZERO(&rfds);
+ FD_SET(sck, &rfds);
+ time.tv_sec = millis / 1000;
+ time.tv_usec = (millis * 1000) % 1000000;
+ select_rv = select(sck + 1, &rfds, 0, 0, &time);
+ if (select_rv > 0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+static int
+send_init(struct wts_obj* wts)
+{
+ char initmsg[64];
+
+ memset(initmsg, 0, 64);
+ if (!can_send(wts->fd, 500))
+ {
+ return 1;
+ }
+ if (send(wts->fd, initmsg, 64, 0) != 64)
+ {
+ return 1;
+ }
return 0;
}
@@ -36,7 +168,50 @@ WTSVirtualChannelOpenEx(unsigned int SessionId,
const char* pVirtualName,
unsigned int flags)
{
- return 0;
+ struct wts_obj* wts;
+ char* display_text;
+ struct sockaddr_un s;
+ int bytes;
+ unsigned long llong;
+
+ if (SessionId != WTS_CURRENT_SESSION)
+ {
+ return 0;
+ }
+ wts = (struct wts_obj*)malloc(sizeof(struct wts_obj));
+ memset(wts, 0, sizeof(struct wts_obj));
+ wts->fd = -1;
+ display_text = getenv("DISPLAY");
+ if (display_text != 0)
+ {
+ wts->display_num = get_display_num_from_display(display_text);
+ }
+ if (wts->display_num > 0)
+ {
+ wts->fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ /* set non blocking */
+ llong = fcntl(wts->fd, F_GETFL);
+ llong = llong | O_NONBLOCK;
+ fcntl(wts->fd, F_SETFL, llong);
+ /* connect to session chansrv */
+ memset(&s, 0, sizeof(struct sockaddr_un));
+ s.sun_family = AF_UNIX;
+ bytes = sizeof(s.sun_path);
+ snprintf(s.sun_path, bytes - 1, "/tmp/.xrdp/xrdpapi_%d", wts->display_num);
+ s.sun_path[bytes - 1] = 0;
+ bytes = sizeof(struct sockaddr_un);
+ if (connect(wts->fd, (struct sockaddr*)&s, bytes) == 0)
+ {
+ strncpy(wts->name, pVirtualName, 8);
+ /* wait for connection to complete and send init */
+ if (send_init(wts) == 0)
+ {
+ /* all ok */
+ wts->status = 1;
+ }
+ }
+ }
+ return wts;
}
/*****************************************************************************/
@@ -44,21 +219,144 @@ int
WTSVirtualChannelWrite(void* hChannelHandle, const char* Buffer,
unsigned int Length, unsigned int* pBytesWritten)
{
- return 0;
+ struct wts_obj* wts;
+ int error;
+ int lerrno;
+
+ wts = (struct wts_obj*)hChannelHandle;
+ if (wts == 0)
+ {
+ return 0;
+ }
+ if (wts->status != 1)
+ {
+ return 0;
+ }
+ if (can_send(wts->fd, 0))
+ {
+ error = send(wts->fd, Buffer, Length, 0);
+ if (error == -1)
+ {
+ lerrno = errno;
+ if ((lerrno == EWOULDBLOCK) || (lerrno == EAGAIN) ||
+ (lerrno == EINPROGRESS))
+ {
+ *pBytesWritten = 0;
+ return 1;
+ }
+ return 0;
+ }
+ else if (error == 0)
+ {
+ return 0;
+ }
+ else if (error > 0)
+ {
+ *pBytesWritten = error;
+ return 1;
+ }
+ }
+ *pBytesWritten = 0;
+ return 1;
}
/*****************************************************************************/
int
-WTSVirtualChannelRead(void* nChannelHandle, unsigned int TimeOut,
+WTSVirtualChannelRead(void* hChannelHandle, unsigned int TimeOut,
char* Buffer, unsigned int BufferSize,
unsigned int* pBytesRead)
{
- return 0;
+ struct wts_obj* wts;
+ int error;
+ int lerrno;
+
+ wts = (struct wts_obj*)hChannelHandle;
+ if (wts == 0)
+ {
+ return 0;
+ }
+ if (wts->status != 1)
+ {
+ return 0;
+ }
+ if (can_recv(wts->fd, TimeOut))
+ {
+ error = recv(wts->fd, Buffer, BufferSize, 0);
+ if (error == -1)
+ {
+ lerrno = errno;
+ if ((lerrno == EWOULDBLOCK) || (lerrno == EAGAIN) ||
+ (lerrno == EINPROGRESS))
+ {
+ *pBytesRead = 0;
+ return 1;
+ }
+ return 0;
+ }
+ else if (error == 0)
+ {
+ return 0;
+ }
+ else if (error > 0)
+ {
+ *pBytesRead = error;
+ return 1;
+ }
+ }
+ *pBytesRead = 0;
+ return 1;
}
/*****************************************************************************/
int
-WTSVirtualChannelClose(void* openHandle)
+WTSVirtualChannelClose(void* hChannelHandle)
{
+ struct wts_obj* wts;
+
+ wts = (struct wts_obj*)hChannelHandle;
+ if (wts == 0)
+ {
+ return 0;
+ }
+ if (wts->fd != -1)
+ {
+ close(wts->fd);
+ }
+ free(wts);
+ return 1;
+}
+
+/*****************************************************************************/
+int
+WTSVirtualChannelQuery(void* hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass,
+ void** ppBuffer, unsigned int* pBytesReturned)
+{
+ struct wts_obj* wts;
+
+ wts = (struct wts_obj*)hChannelHandle;
+ if (wts == 0)
+ {
+ return 0;
+ }
+ if (wts->status != 1)
+ {
+ return 0;
+ }
+ if (WtsVirtualClass == WTSVirtualFileHandle)
+ {
+ *pBytesReturned = 4;
+ *ppBuffer = malloc(4);
+ memcpy(*ppBuffer, &(wts->fd), 4);
+ }
return 0;
}
+
+/*****************************************************************************/
+void
+WTSFreeMemory(void* pMemory)
+{
+ if (pMemory != 0)
+ {
+ free(pMemory);
+ }
+}
diff --git a/xrdpapi/xrdpapi.h b/xrdpapi/xrdpapi.h
index c4571e46..cb451559 100644
--- a/xrdpapi/xrdpapi.h
+++ b/xrdpapi/xrdpapi.h
@@ -17,7 +17,8 @@
* limitations under the License.
*/
/*
- xrdpapi header
+ xrdpapi header, do not use os_calls.h, arch.h or any xrdp internal headers
+ this file is included in 3rd party apps
*/
#if !defined(XRDPAPI_H_)
@@ -26,6 +27,12 @@
#define WTS_CURRENT_SERVER_HANDLE 0
#define WTS_CURRENT_SESSION 0xffffffff
+typedef enum _WTS_VIRTUAL_CLASS
+{
+ WTSVirtualClientData,
+ WTSVirtualFileHandle
+} WTS_VIRTUAL_CLASS;
+
/*
Reference:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa383464(v=vs.85).aspx
@@ -41,10 +48,15 @@ int
WTSVirtualChannelWrite(void* hChannelHandle, const char* Buffer,
unsigned int Length, unsigned int* pBytesWritten);
int
-WTSVirtualChannelRead(void* nChannelHandle, unsigned int TimeOut,
+WTSVirtualChannelRead(void* hChannelHandle, unsigned int TimeOut,
char* Buffer, unsigned int BufferSize,
unsigned int* pBytesRead);
int
-WTSVirtualChannelClose(void* openHandle);
+WTSVirtualChannelClose(void* hChannelHandle);
+int
+WTSVirtualChannelQuery(void* hChannelHandle, WTS_VIRTUAL_CLASS WtsVirtualClass,
+ void** ppBuffer, unsigned int* pBytesReturned);
+void
+WTSFreeMemory(void* pMemory);
#endif /* XRDPAPI_H_ */