Skip to content
11 changes: 11 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ module_LTLIBRARIES = \
libulalaca.la

libulalaca_la_SOURCES = \
Utility.hpp \
Utility.cpp \
UnixSocket.cpp \
UnixSocket.hpp \
SocketStream.cpp \
Expand All @@ -24,6 +26,15 @@ libulalaca_la_SOURCES = \
XrdpTransport.cpp \
XrdpStream.hpp \
XrdpStream.cpp \
XrdpStream.template.cpp \
channels/XrdpChannelBase.hpp \
channels/XrdpChannelBase.cpp \
channels/XrdpChannelEvent.hpp \
channels/XrdpChannelEvent.cpp \
channels/clipboard/ClipboardEntry.hpp \
channels/clipboard/ClipboardEntry.cpp \
channels/clipboard/ClipboardChannel.hpp \
channels/clipboard/ClipboardChannel.cpp \
UlalacaMessages.hpp \
IPCConnection.hpp \
IPCConnection.cpp \
Expand Down
6 changes: 6 additions & 0 deletions ProjectionTarget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ class ProjectionTarget {
int32_t width, int32_t height
) = 0;

virtual void streamWillStart(uint8_t type, uint64_t resourceId) = 0;
virtual void streamDataReceived(uint8_t type, uint64_t resourceId, const uint8_t *data, size_t size) = 0;
virtual void streamWillEnd(uint8_t type, uint64_t resourceId) = 0;

virtual void ipcConnected() = 0;
virtual void ipcDisconnected() = 0;
virtual void ipcError(int reason) = 0;
};

#endif //ULALACA_PROJECTIONCONTEXT_HPP
43 changes: 43 additions & 0 deletions Utility.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// Created by Gyuhwan Park on 1/19/24.
//

#include <CoreFoundation/CoreFoundation.h>

#include "Utility.hpp"

namespace ulalaca::utility {
std::string unix2dos(const std::string &unixText) {
std::string dosText;
dosText.reserve(unixText.size());

for (char it : unixText) {
if (it == '\n') {
dosText.push_back('\r');
}
dosText.push_back(it);
}

return std::move(dosText);
}

std::string ansi2unicode(const std::string &ansiText) {
// sorry, i'm too stupid to implement this function.
CFStringRef cfAnsiText
= CFStringCreateWithCString(kCFAllocatorDefault,
ansiText.c_str(),
kCFStringEncodingUTF8);

CFIndex length = CFStringGetLength(cfAnsiText);

std::unique_ptr<UniChar> utf16LEText(new UniChar[sizeof(UniChar) * length]);
CFStringGetCharacters(cfAnsiText,
CFRangeMake(0, length),
utf16LEText.get());

CFRelease(cfAnsiText);

return std::string(reinterpret_cast<char *>(utf16LEText.get()),
sizeof(UniChar) * length);
}
}
21 changes: 21 additions & 0 deletions Utility.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// Created by Gyuhwan Park on 1/19/24.
//

#ifndef XRDP_TUMOD_UTILITY_HPP
#define XRDP_TUMOD_UTILITY_HPP

#include <string>

namespace ulalaca::utility {
std::string unix2dos(const std::string &unixText);

/**
* @brief converts UTF-8 string to UTF-16LE string
* @FIXME bad name. actually, it converts UTF-8 to UTF-16LE
*/
std::string ansi2unicode(const std::string &ansiText);
}


#endif //XRDP_TUMOD_UTILITY_HPP
105 changes: 105 additions & 0 deletions XrdpStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#endif

#include "ulalaca.hpp"
#include "XrdpStream.hpp"


static inline XrdpStream::Stream *createXrdpStreamInternal(size_t size) {
XrdpStream::Stream *stream;
Expand All @@ -29,3 +31,106 @@ XrdpStream::XrdpStream(size_t size):
XrdpStream::operator Stream const *() const {
return _stream.get();
}

void XrdpStream::write(uint8_t value) {
out_uint8(_stream.get(), value);
}

void XrdpStream::write(uint16_t value) {
out_uint16_le(_stream.get(), value);
}

void XrdpStream::write(uint32_t value) {
out_uint32_le(_stream.get(), value);
}

void XrdpStream::write(uint64_t value) {
out_uint64_le(_stream.get(), value);
}

uint8_t XrdpStream::readUInt8() {
uint8_t value = 0;
in_uint8(_stream.get(), value);

return value;
}

uint16_t XrdpStream::readUInt16() {
uint16_t value = 0;
in_uint16_le(_stream.get(), value);

return value;
}

uint32_t XrdpStream::readUInt32() {
uint32_t value = 0;
in_uint32_le(_stream.get(), value);

return value;
}

uint64_t XrdpStream::readUInt64() {
uint64_t value = 0;
in_uint64_le(_stream.get(), value);

return value;
}

void XrdpStream::write(const uint8_t *data, size_t size) {
out_uint8a(_stream.get(), data, size);
}

ptrdiff_t XrdpStream::size() const {
return _stream->end - _stream->data;
}

ptrdiff_t XrdpStream::distance() const {
return _stream->end - _stream->p;
}

bool XrdpStream::checkDistance(int n) const {
return (_stream->p + n) <= _stream->end;
}

void XrdpStream::seekAbsolute(ptrdiff_t offset) {
if (offset < 0) {
_stream->p = _stream->data;
} else if (offset > size()) {
_stream->p = _stream->end;
} else {
_stream->p = _stream->data + offset;
}
}

void XrdpStream::seekRelative(ptrdiff_t offset) {
if (offset < 0) {
_stream->p = std::max(_stream->data, _stream->p - offset);
} else {
_stream->p = std::min(_stream->end, _stream->p + offset);
}
}

void XrdpStream::markChannelHeader(int offset) {
s_push_layer(_stream.get(), channel_hdr, offset);
}

void XrdpStream::seekToChannelHeader() {
s_pop_layer(_stream.get(), channel_hdr);
}

const char *XrdpStream::begin() const {
return _stream->data;
}

void XrdpStream::seekToBegin() {
_stream->p = _stream->data;
}

const char *XrdpStream::end() const {
return _stream->end;
}

void XrdpStream::markEnd() {
s_mark_end(_stream.get());
}

51 changes: 51 additions & 0 deletions XrdpStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ extern "C" {
#include "defines.h"
};

/**
* wrapper class for xrdp stream
*/
class XrdpStream {
public:
using Stream = stream;
Expand All @@ -27,8 +30,56 @@ class XrdpStream {
template<typename T>
XrdpStream &operator<< (T value);

void write(uint8_t value);
void write(uint16_t value);
void write(uint32_t value);
void write(uint64_t value);
void write(const uint8_t *data, size_t size);

uint8_t readUInt8();
uint16_t readUInt16();
uint32_t readUInt32();
uint64_t readUInt64();

/**
* @brief calculates size of the entire stream
*/
ptrdiff_t size() const;

/**
* @brief calculates distance between current position and the end of the stream
*/
ptrdiff_t distance() const;

bool checkDistance(int n) const;

const char *channelHeader() const;

void seekAbsolute(ptrdiff_t offset);
void seekRelative(ptrdiff_t offset);

/**
* equivalent to s_push_layer(s, channel_hdr, n)
*/
void markChannelHeader(int offset);
/**
* equivalent to s_pop_layer(s, channel_hdr)
*/
void seekToChannelHeader();

/**
* @brief returns pointer to the beginning of the stream
*/
const char *begin() const;
void seekToBegin();

const char *end() const;
void markEnd();

private:
std::unique_ptr<Stream, StreamDeleter> _stream;
};

#include "XrdpStream.template.cpp"

#endif //ULALACA_XRDPSTREAM_HPP
18 changes: 13 additions & 5 deletions XrdpStream.template.cpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
#ifndef __ULALACA_XRDPSTREAM_TEMPLATE_CPP__
#define __ULALACA_XRDPSTREAM_TEMPLATE_CPP__

#include "ulalaca.hpp"
#include "XrdpStream.hpp"

template <>
XrdpStream &XrdpStream::operator<<(uint8_t value) {
out_uint8(_stream, value);
write(value);

return *this;
}

template <>
XrdpStream &XrdpStream::operator<<(uint16_t value) {
out_uint16_le(_stream, value);
write(value);

return *this;
}

template <>
XrdpStream &XrdpStream::operator<<(uint32_t value) {
out_uint32_le(_stream, value);
write(value);

return *this;
}

template <>
XrdpStream &XrdpStream::operator<<(uint64_t value) {
out_uint64_le(_stream, value);
write(value);

return *this;
}

#endif
45 changes: 45 additions & 0 deletions channels/XrdpChannelBase.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// Created by Gyuhwan Park on 1/19/24.
//

#include "XrdpChannelBase.hpp"

namespace ulalaca::channel {
XrdpChannelBase::XrdpChannelBase(XrdpUlalaca *mod, const std::string &channelName):
_mod(mod),
_channelName(channelName),
_channelId(-1),
_isChannelOpen(false)
{
}

const std::string &XrdpChannelBase::channelName() const {
return _channelName;
}

int XrdpChannelBase::channelId() const {
return _channelId;
}

void XrdpChannelBase::setChannelId(int channelId) {
_channelId = channelId;
}

bool XrdpChannelBase::isChannelOpen() const {
return _isChannelOpen;
}

void XrdpChannelBase::setChannelOpen(bool isChannelOpen) {
_isChannelOpen = isChannelOpen;
}

XrdpUlalaca *XrdpChannelBase::mod() const {
return _mod;
}

bool XrdpChannelBase::canHandle(const XrdpChannelEvent &event) const {
return event.channelId() == channelId();
}


}
Loading