Skip to content

Commit 4d3558c

Browse files
mamoreau-devolutionsawakecoding
authored andcommitted
add recording streaming to named pipe
1 parent f6150a5 commit 4d3558c

File tree

10 files changed

+487
-94
lines changed

10 files changed

+487
-94
lines changed

dll/ApiHooks.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,12 @@ bool WINAPI MsRdpEx_CaptureBlt(
457457
free(recordingPath);
458458
}
459459

460+
char* recordingPipeName = pExtendedSettings->GetRecordingPipeName();
461+
if (recordingPipeName) {
462+
MsRdpEx_OutputMirror_SetRecordingPipeName(outputMirror, recordingPipeName);
463+
free(recordingPipeName);
464+
}
465+
460466
const char* sessionId = pExtendedSettings->GetSessionId();
461467
MsRdpEx_OutputMirror_SetSessionId(outputMirror, sessionId);
462468

dll/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ set(MSRDPEX_HEADERS
3434
"${MSRDPEX_INCLUDE_DIR}/OutputMirror.h"
3535
"${MSRDPEX_INCLUDE_DIR}/VideoRecorder.h"
3636
"${MSRDPEX_INCLUDE_DIR}/RecordingManifest.h"
37+
"${MSRDPEX_INCLUDE_DIR}/NamedPipe.h"
3738
"${MSRDPEX_INCLUDE_DIR}/MsRdpEx.h")
3839

3940
set(MSRDPEX_SOURCES
@@ -59,6 +60,7 @@ set(MSRDPEX_SOURCES
5960
OutputMirror.c
6061
VideoRecorder.c
6162
RecordingManifest.c
63+
NamedPipe.c
6264
Pcap.cpp
6365
Bitmap.c
6466
WinMsg.c

dll/NamedPipe.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
2+
#include "MsRdpEx.h"
3+
4+
#include <MsRdpEx/NamedPipe.h>
5+
6+
#include <fcntl.h>
7+
#include <errno.h>
8+
9+
#define XMF_NAMED_PIPE_BUFFER_SIZE 8192
10+
11+
int MsRdpEx_NamedPipe_Read(HANDLE np_handle, uint8_t* data, size_t size)
12+
{
13+
DWORD cb_read = 0;
14+
15+
if (!ReadFile(np_handle, data, size, &cb_read, NULL)) {
16+
return -1;
17+
}
18+
19+
return (int) cb_read;
20+
}
21+
22+
int MsRdpEx_NamedPipe_Write(HANDLE np_handle, const uint8_t* data, size_t size)
23+
{
24+
DWORD cb_write = 0;
25+
26+
if (!WriteFile(np_handle, (void*)data, (DWORD)size, &cb_write, NULL)) {
27+
return -1;
28+
}
29+
30+
return (int) cb_write;
31+
}
32+
33+
HANDLE MsRdpEx_NamedPipe_Open(const char* np_name)
34+
{
35+
HANDLE np_handle;
36+
char filename[MSRDPEX_MAX_PATH];
37+
38+
if (!np_name)
39+
return NULL;
40+
41+
sprintf_s(filename, sizeof(filename) - 1, "\\\\.\\pipe\\%s", np_name);
42+
43+
np_handle = CreateFileA(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
44+
45+
if (np_handle == INVALID_HANDLE_VALUE) {
46+
return NULL;
47+
}
48+
49+
return np_handle;
50+
}
51+
52+
HANDLE MsRdpEx_NamedPipe_Create(const char* np_name, int max_clients)
53+
{
54+
HANDLE np_handle;
55+
char filename[MSRDPEX_MAX_PATH];
56+
57+
if (!np_name)
58+
return NULL;
59+
60+
sprintf_s(filename, sizeof(filename) - 1, "\\\\.\\pipe\\%s", np_name);
61+
62+
np_handle = CreateNamedPipeA(filename,
63+
PIPE_ACCESS_DUPLEX,
64+
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
65+
max_clients,
66+
XMF_NAMED_PIPE_BUFFER_SIZE,
67+
XMF_NAMED_PIPE_BUFFER_SIZE,
68+
0, NULL);
69+
70+
if (np_handle == INVALID_HANDLE_VALUE) {
71+
return NULL;
72+
}
73+
74+
return np_handle;
75+
}
76+
77+
HANDLE MsRdpEx_NamedPipe_Accept(HANDLE np_handle)
78+
{
79+
if (!ConnectNamedPipe(np_handle, NULL)) {
80+
return NULL;
81+
}
82+
return np_handle;
83+
}
84+
85+
86+
void MsRdpEx_NamedPipe_Close(HANDLE np_handle)
87+
{
88+
CloseHandle(np_handle);
89+
}

dll/OutputMirror.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct _MsRdpEx_OutputMirror
2727
bool videoRecordingEnabled;
2828
uint32_t videoQualityLevel;
2929
char recordingPath[MSRDPEX_MAX_PATH];
30+
char recordingPipeName[MSRDPEX_MAX_PATH];
3031
char outputPath[MSRDPEX_MAX_PATH];
3132
char sessionId[MSRDPEX_GUID_STRING_SIZE];
3233
MsRdpEx_VideoRecorder* videoRecorder;
@@ -125,6 +126,11 @@ void MsRdpEx_OutputMirror_SetRecordingPath(MsRdpEx_OutputMirror* ctx, const char
125126
strcpy_s(ctx->recordingPath, MSRDPEX_MAX_PATH, recordingPath);
126127
}
127128

129+
void MsRdpEx_OutputMirror_SetRecordingPipeName(MsRdpEx_OutputMirror* ctx, const char* recordingPipeName)
130+
{
131+
strcpy_s(ctx->recordingPipeName, MSRDPEX_MAX_PATH, recordingPipeName);
132+
}
133+
128134
void MsRdpEx_OutputMirror_SetSessionId(MsRdpEx_OutputMirror* ctx, const char* sessionId)
129135
{
130136
strcpy_s(ctx->sessionId, MSRDPEX_GUID_STRING_SIZE, sessionId);
@@ -207,6 +213,11 @@ bool MsRdpEx_OutputMirror_Init(MsRdpEx_OutputMirror* ctx)
207213
MsRdpEx_VideoRecorder_SetFrameSize(ctx->videoRecorder, ctx->bitmapWidth, ctx->bitmapHeight);
208214
MsRdpEx_VideoRecorder_SetFileName(ctx->videoRecorder, filename);
209215
MsRdpEx_VideoRecorder_SetVideoQuality(ctx->videoRecorder, ctx->videoQualityLevel);
216+
217+
if (!MsRdpEx_StringIsNullOrEmpty(ctx->recordingPipeName)) {
218+
MsRdpEx_VideoRecorder_SetPipeName(ctx->videoRecorder, ctx->recordingPipeName);
219+
}
220+
210221
MsRdpEx_VideoRecorder_Init(ctx->videoRecorder);
211222
}
212223

@@ -293,7 +304,9 @@ void MsRdpEx_OutputMirror_Free(MsRdpEx_OutputMirror* ctx)
293304
if (!ctx)
294305
return;
295306

296-
MsRdpEx_OutputMirror_WriteManifestFile(ctx);
307+
if (MsRdpEx_StringIsNullOrEmpty(ctx->recordingPipeName)) {
308+
MsRdpEx_OutputMirror_WriteManifestFile(ctx);
309+
}
297310

298311
MsRdpEx_OutputMirror_Uninit(ctx);
299312

dll/RdpSettings.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ CMsRdpExtendedSettings::~CMsRdpExtendedSettings()
482482
{
483483
this->SetKdcProxyUrl(NULL);
484484
this->SetRecordingPath(NULL);
485+
this->SetRecordingPipeName(NULL);
485486

486487
if (m_pMsRdpExtendedSettings)
487488
m_pMsRdpExtendedSettings->Release();
@@ -658,6 +659,20 @@ HRESULT __stdcall CMsRdpExtendedSettings::put_Property(BSTR bstrPropertyName, VA
658659
free(propValue);
659660
hr = S_OK;
660661
}
662+
else if (MsRdpEx_StringEquals(propName, "RecordingPipeName"))
663+
{
664+
if (pValue->vt != VT_BSTR)
665+
goto end;
666+
667+
char* propValue = _com_util::ConvertBSTRToString(pValue->bstrVal);
668+
669+
if (propValue) {
670+
hr = this->SetRecordingPipeName(propValue);
671+
}
672+
673+
free(propValue);
674+
hr = S_OK;
675+
}
661676
else if (MsRdpEx_StringEquals(propName, "DumpBitmapUpdates"))
662677
{
663678
if (pValue->vt != VT_BOOL)
@@ -779,6 +794,12 @@ HRESULT __stdcall CMsRdpExtendedSettings::get_Property(BSTR bstrPropertyName, VA
779794
pValue->bstrVal = _com_util::ConvertStringToBSTR(recordingPath);
780795
hr = S_OK;
781796
}
797+
else if (MsRdpEx_StringEquals(propName, "RecordingPipeName")) {
798+
pValue->vt = VT_BSTR;
799+
const char* recordingPipeName = m_RecordingPipeName ? m_RecordingPipeName : "";
800+
pValue->bstrVal = _com_util::ConvertStringToBSTR(recordingPipeName);
801+
hr = S_OK;
802+
}
782803
else if (MsRdpEx_StringEquals(propName, "MsRdpEx_SessionId")) {
783804
pValue->vt = VT_BSTR;
784805
char sessionId[MSRDPEX_GUID_STRING_SIZE];
@@ -883,6 +904,16 @@ HRESULT __stdcall CMsRdpExtendedSettings::SetRecordingPath(const char* recording
883904
return S_OK;
884905
}
885906

907+
HRESULT __stdcall CMsRdpExtendedSettings::SetRecordingPipeName(const char* recordingPipeName) {
908+
free(m_RecordingPipeName);
909+
m_RecordingPipeName = NULL;
910+
911+
if (recordingPipeName) {
912+
m_RecordingPipeName = _strdup(recordingPipeName);
913+
}
914+
return S_OK;
915+
}
916+
886917
HRESULT CMsRdpExtendedSettings::AttachRdpClient(IMsTscAx* pMsTscAx)
887918
{
888919
HRESULT hr;
@@ -1169,6 +1200,13 @@ HRESULT CMsRdpExtendedSettings::ApplyRdpFile(void* rdpFilePtr)
11691200
value.vt = VT_BSTR;
11701201
pMsRdpExtendedSettings->put_Property(propName, &value);
11711202
}
1203+
else if (MsRdpEx_RdpFileEntry_IsMatch(entry, 's', "RecordingPipeName")) {
1204+
bstr_t propName = _com_util::ConvertStringToBSTR(entry->name);
1205+
bstr_t propValue = _com_util::ConvertStringToBSTR(entry->value);
1206+
value.bstrVal = propValue;
1207+
value.vt = VT_BSTR;
1208+
pMsRdpExtendedSettings->put_Property(propName, &value);
1209+
}
11721210
else if (MsRdpEx_RdpFileEntry_IsMatch(entry, 'i', "DumpBitmapUpdates")) {
11731211
if (MsRdpEx_RdpFileEntry_GetVBoolValue(entry, &value)) {
11741212
bstr_t propName = _com_util::ConvertStringToBSTR(entry->name);
@@ -1407,6 +1445,14 @@ char* CMsRdpExtendedSettings::GetRecordingPath()
14071445
return NULL;
14081446
}
14091447

1448+
char* CMsRdpExtendedSettings::GetRecordingPipeName()
1449+
{
1450+
if (m_RecordingPipeName)
1451+
return _strdup(m_RecordingPipeName);
1452+
1453+
return NULL;
1454+
}
1455+
14101456
bool CMsRdpExtendedSettings::GetDumpBitmapUpdates()
14111457
{
14121458
return m_DumpBitmapUpdates;

0 commit comments

Comments
 (0)