summaryrefslogtreecommitdiffstats
path: root/server/shadow
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--server/shadow/CMakeLists.txt88
-rw-r--r--server/shadow/X11/x11_shadow.c34
-rw-r--r--server/shadow/X11/x11_shadow.h1
-rw-r--r--server/shadow/freerdp-shadow-cli.1.in8
-rw-r--r--server/shadow/shadow_capture.c214
-rw-r--r--server/shadow/shadow_client.c8
-rw-r--r--server/shadow/shadow_lobby.c25
-rw-r--r--server/shadow/shadow_server.c8
-rw-r--r--server/shadow/shadow_subsystem.c36
9 files changed, 213 insertions, 209 deletions
diff --git a/server/shadow/CMakeLists.txt b/server/shadow/CMakeLists.txt
index 72adcca..159b6b6 100644
--- a/server/shadow/CMakeLists.txt
+++ b/server/shadow/CMakeLists.txt
@@ -64,24 +64,7 @@ else()
include_directories(${PROJECT_BINARY_DIR}/rdtk/include)
endif()
-# On windows create dll version information.
-# Vendor, product and year are already set in top level CMakeLists.txt
-if (WIN32)
- set (RC_VERSION_MAJOR ${FREERDP_VERSION_MAJOR})
- set (RC_VERSION_MINOR ${FREERDP_VERSION_MINOR})
- set (RC_VERSION_BUILD ${FREERDP_VERSION_REVISION})
- set (RC_VERSION_PATCH 0)
- set (RC_VERSION_FILE "${CMAKE_SHARED_LIBRARY_PREFIX}${MODULE_NAME}${FREERDP_API_VERSION}${CMAKE_SHARED_LIBRARY_SUFFIX}" )
-
- configure_file(
- ${PROJECT_SOURCE_DIR}/cmake/WindowsDLLVersion.rc.in
- ${CMAKE_CURRENT_BINARY_DIR}/version.rc
- @ONLY)
-
-list (APPEND SRCS ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
-endif()
-
-add_library(${MODULE_NAME} ${SRCS})
+AddTargetWithResourceFile(${MODULE_NAME} "FALSE" "${FREERDP_VERSION}" SRCS)
list(APPEND LIBS
freerdp
@@ -94,21 +77,11 @@ list(APPEND LIBS
target_include_directories(${MODULE_NAME} INTERFACE $<INSTALL_INTERFACE:include>)
target_link_libraries(${MODULE_NAME} PRIVATE ${LIBS})
-set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_NAME}${FREERDP_VERSION_MAJOR})
-if (WITH_LIBRARY_VERSIONING)
- set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION})
-endif()
-
install(TARGETS ${MODULE_NAME} COMPONENT server EXPORT FreeRDP-ShadowTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
-if (WITH_DEBUG_SYMBOLS AND MSVC)
- get_target_property(OUTPUT_FILENAME ${MODULE_NAME} OUTPUT_NAME)
- install(FILES ${PROJECT_BINARY_DIR}/${OUTPUT_FILENAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT symbols)
-endif()
-
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/shadow")
# subsystem library
@@ -126,21 +99,7 @@ elseif(APPLE AND NOT IOS)
add_subdirectory(Mac)
endif()
-if (WIN32)
- set (RC_VERSION_MAJOR ${FREERDP_VERSION_MAJOR})
- set (RC_VERSION_MINOR ${FREERDP_VERSION_MINOR})
- set (RC_VERSION_BUILD ${FREERDP_VERSION_REVISION})
- set (RC_VERSION_FILE "${MODULE_NAME}${CMAKE_EXECUTABLE_SUFFIX}" )
-
- configure_file(
- ${PROJECT_SOURCE_DIR}/cmake/WindowsDLLVersion.rc.in
- ${CMAKE_CURRENT_BINARY_DIR}/version.rc
- @ONLY)
-
- set ( SRCS ${SRCS} ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
-endif()
-
-add_library(${MODULE_NAME} ${SRCS})
+AddTargetWithResourceFile(${MODULE_NAME} FALSE "${FREERDP_VERSION}" SRCS)
list(APPEND LIBS
freerdp-shadow-subsystem-impl
@@ -152,11 +111,6 @@ list(APPEND LIBS
target_include_directories(${MODULE_NAME} INTERFACE $<INSTALL_INTERFACE:include>)
target_link_libraries(${MODULE_NAME} PRIVATE ${LIBS})
-set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_NAME}${FREERDP_API_VERSION})
-if (WITH_LIBRARY_VERSIONING)
- set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${FREERDP_VERSION} SOVERSION ${FREERDP_API_VERSION})
-endif()
-
if (NOT BUILD_SHARED_LIBS)
install(TARGETS freerdp-shadow-subsystem-impl
DESTINATION ${CMAKE_INSTALL_LIBDIR}
@@ -169,12 +123,6 @@ install(TARGETS ${MODULE_NAME} COMPONENT server EXPORT FreeRDP-ShadowTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
-if (WITH_DEBUG_SYMBOLS AND MSVC)
- get_target_property(OUTPUT_FILENAME ${MODULE_NAME} OUTPUT_NAME)
- install(FILES ${PROJECT_BINARY_DIR}/${OUTPUT_FILENAME}.pdb DESTINATION ${CMAKE_INSTALL_LIBDIR}
- COMPONENT symbols)
-endif()
-
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/shadow")
# command-line executable
@@ -184,46 +132,20 @@ set(MODULE_NAME "freerdp-shadow-cli")
set(SRCS
shadow.c)
-# On windows create dll version information.
-# Vendor, product and year are already set in top level CMakeLists.txt
-if (WIN32)
- set (RC_VERSION_MAJOR ${FREERDP_VERSION_MAJOR})
- set (RC_VERSION_MINOR ${FREERDP_VERSION_MINOR})
- set (RC_VERSION_BUILD ${FREERDP_VERSION_REVISION})
- set (RC_VERSION_FILE "${MODULE_NAME}${CMAKE_EXECUTABLE_SUFFIX}" )
-
- configure_file(
- ${PROJECT_SOURCE_DIR}/cmake/WindowsDLLVersion.rc.in
- ${CMAKE_CURRENT_BINARY_DIR}/version.rc
- @ONLY)
-
- set ( SRCS ${SRCS} ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
-endif()
-
-add_executable(${MODULE_NAME} ${SRCS})
-
-set(MANPAGE_NAME "${MODULE_NAME}")
-if (WITH_BINARY_VERSIONING)
- set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "${MODULE_NAME}${FREERDP_API_VERSION}")
- set(MANPAGE_NAME "${MODULE_NAME}${FREERDP_API_VERSION}")
-endif()
+AddTargetWithResourceFile(${MODULE_NAME} TRUE "${FREERDP_VERSION}" SRCS)
list(APPEND LIBS freerdp-shadow-subsystem freerdp-shadow freerdp winpr)
target_link_libraries(${MODULE_NAME} PRIVATE ${LIBS})
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT server)
-if (WITH_DEBUG_SYMBOLS AND MSVC)
- install(FILES ${PROJECT_BINARY_DIR}/${MODULE_NAME}.pdb DESTINATION ${CMAKE_INSTALL_BINDIR}
- COMPONENT symbols)
-endif()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "Server/shadow")
include(pkg-config-install-prefix)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/freerdp-shadow.pc.in ${CMAKE_CURRENT_BINARY_DIR}/freerdp-shadow${FREERDP_VERSION_MAJOR}.pc @ONLY)
-configure_file(freerdp-shadow-cli.1.in ${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE_NAME}.1)
-install_freerdp_man(${CMAKE_CURRENT_BINARY_DIR}/${MANPAGE_NAME}.1 1)
+
+generate_and_install_freerdp_man_from_template(${MODULE_NAME} "1" "${FREERDP_API_VERSION}")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freerdp-shadow${FREERDP_VERSION_MAJOR}.pc DESTINATION ${PKG_CONFIG_PC_INSTALL_DIR})
diff --git a/server/shadow/X11/x11_shadow.c b/server/shadow/X11/x11_shadow.c
index 5c1fab1..1e4f945 100644
--- a/server/shadow/X11/x11_shadow.c
+++ b/server/shadow/X11/x11_shadow.c
@@ -409,7 +409,7 @@ static int x11_shadow_pointer_position_update(x11ShadowSubsystem* subsystem)
{
UINT32 msgId = SHADOW_MSG_OUT_POINTER_POSITION_UPDATE_ID;
rdpShadowServer* server = NULL;
- SHADOW_MSG_OUT_POINTER_POSITION_UPDATE templateMsg;
+ SHADOW_MSG_OUT_POINTER_POSITION_UPDATE templateMsg = { 0 };
int count = 0;
if (!subsystem || !subsystem->common.server || !subsystem->common.server->clients)
@@ -463,8 +463,8 @@ static int x11_shadow_pointer_alpha_update(x11ShadowSubsystem* subsystem)
msg->width = subsystem->cursorWidth;
msg->height = subsystem->cursorHeight;
- if (shadow_subsystem_pointer_convert_alpha_pointer_data(subsystem->cursorPixels, TRUE,
- msg->width, msg->height, msg) < 0)
+ if (shadow_subsystem_pointer_convert_alpha_pointer_data_to_format(
+ subsystem->cursorPixels, subsystem->format, TRUE, msg->width, msg->height, msg) < 0)
{
free(msg);
return -1;
@@ -796,9 +796,10 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
subsystem->xshm_gc, 0, 0, subsystem->width, subsystem->height, 0, 0);
EnterCriticalSection(&surface->lock);
- status = shadow_capture_compare(surface->data, surface->scanline, surface->width,
- surface->height, (BYTE*)&(image->data[surface->width * 4]),
- image->bytes_per_line, &invalidRect);
+ status = shadow_capture_compare_with_format(
+ surface->data, surface->format, surface->scanline, surface->width, surface->height,
+ (BYTE*)&(image->data[surface->width * 4ull]), subsystem->format, image->bytes_per_line,
+ &invalidRect);
LeaveCriticalSection(&surface->lock);
}
else
@@ -810,9 +811,9 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
if (image)
{
- status = shadow_capture_compare(surface->data, surface->scanline, surface->width,
- surface->height, (BYTE*)image->data,
- image->bytes_per_line, &invalidRect);
+ status = shadow_capture_compare_with_format(
+ surface->data, surface->format, surface->scanline, surface->width, surface->height,
+ (BYTE*)image->data, subsystem->format, image->bytes_per_line, &invalidRect);
}
LeaveCriticalSection(&surface->lock);
if (!image)
@@ -854,7 +855,7 @@ static int x11_shadow_screen_grab(x11ShadowSubsystem* subsystem)
WINPR_ASSERT(height >= 0);
success = freerdp_image_copy(surface->data, surface->format, surface->scanline, x, y,
(UINT32)width, (UINT32)height, (BYTE*)image->data,
- PIXEL_FORMAT_BGRX32, (UINT32)image->bytes_per_line, x, y,
+ subsystem->format, (UINT32)image->bytes_per_line, x, y,
NULL, FREERDP_FLIP_NONE);
LeaveCriticalSection(&surface->lock);
if (!success)
@@ -1036,7 +1037,10 @@ static int x11_shadow_xinerama_init(x11ShadowSubsystem* subsystem)
#ifdef WITH_XINERAMA
int xinerama_event = 0;
int xinerama_error = 0;
- x11_shadow_subsystem_base_init(subsystem);
+
+ const int rc = x11_shadow_subsystem_base_init(subsystem);
+ if (rc < 0)
+ return rc;
if (!XineramaQueryExtension(subsystem->display, &xinerama_event, &xinerama_error))
return -1;
@@ -1270,7 +1274,12 @@ static int x11_shadow_subsystem_init(rdpShadowSubsystem* sub)
return -1;
subsystem->common.numMonitors = x11_shadow_enum_monitors(subsystem->common.monitors, 16);
- x11_shadow_subsystem_base_init(subsystem);
+ const int rc = x11_shadow_subsystem_base_init(subsystem);
+ if (rc < 0)
+ return rc;
+
+ subsystem->format = (ImageByteOrder(subsystem->display) == LSBFirst) ? PIXEL_FORMAT_BGRA32
+ : PIXEL_FORMAT_ARGB32;
if ((subsystem->depth != 24) && (subsystem->depth != 32))
{
@@ -1392,6 +1401,7 @@ static int x11_shadow_subsystem_init(rdpShadowSubsystem* sub)
subsystem->use_xfixes, subsystem->use_xinerama, subsystem->use_xdamage,
subsystem->use_xshm);
}
+
return 1;
}
diff --git a/server/shadow/X11/x11_shadow.h b/server/shadow/X11/x11_shadow.h
index aca2d63..5ab8beb 100644
--- a/server/shadow/X11/x11_shadow.h
+++ b/server/shadow/X11/x11_shadow.h
@@ -100,6 +100,7 @@ struct x11_shadow_subsystem
#ifdef WITH_XFIXES
int xfixes_cursor_notify_event;
#endif
+ UINT32 format;
};
#ifdef __cplusplus
diff --git a/server/shadow/freerdp-shadow-cli.1.in b/server/shadow/freerdp-shadow-cli.1.in
index 890fb7a..ddea924 100644
--- a/server/shadow/freerdp-shadow-cli.1.in
+++ b/server/shadow/freerdp-shadow-cli.1.in
@@ -64,6 +64,14 @@ Print the version and exit.
.IP /help
Print the help and exit.
+.SH USAGE
+
+#MANPAGE_NAME@ - start the shadow server on port 3389 with NLA security, SAM database at /etc/winpr/SAM
+.br
+@MANPAGE_NAME@ /sam-file:SAM.db - same as above, but a custom SAM database provided as argument
+.br
+@MANPAGE_NAME@ -sec-nla - start the shadow server on port 3380 with TLS/NLA security. This allows authenticating against PAM with unix users. Be aware that the password is transmitted plain text like with basic HTTP auth
+
.SH EXAMPLES
@MANPAGE_NAME@ /port:12345
diff --git a/server/shadow/shadow_capture.c b/server/shadow/shadow_capture.c
index 4711ded..887f229 100644
--- a/server/shadow/shadow_capture.c
+++ b/server/shadow/shadow_capture.c
@@ -29,7 +29,7 @@
#define TAG SERVER_TAG("shadow")
-int shadow_capture_align_clip_rect(RECTANGLE_16* rect, RECTANGLE_16* clip)
+int shadow_capture_align_clip_rect(RECTANGLE_16* rect, const RECTANGLE_16* clip)
{
int dx = 0;
int dy = 0;
@@ -78,59 +78,151 @@ int shadow_capture_align_clip_rect(RECTANGLE_16* rect, RECTANGLE_16* clip)
return 1;
}
-int shadow_capture_compare(BYTE* pData1, UINT32 nStep1, UINT32 nWidth, UINT32 nHeight, BYTE* pData2,
- UINT32 nStep2, RECTANGLE_16* rect)
+int shadow_capture_compare(const BYTE* WINPR_RESTRICT pData1, UINT32 nStep1, UINT32 nWidth,
+ UINT32 nHeight, const BYTE* WINPR_RESTRICT pData2, UINT32 nStep2,
+ RECTANGLE_16* WINPR_RESTRICT rect)
{
- BOOL equal = 0;
- BOOL allEqual = 0;
+ return shadow_capture_compare_with_format(pData1, PIXEL_FORMAT_BGRX32, nStep1, nWidth, nHeight,
+ pData2, PIXEL_FORMAT_BGRX32, nStep2, rect);
+}
+
+static BOOL color_equal(UINT32 colorA, UINT32 formatA, UINT32 colorB, UINT32 formatB)
+{
+ BYTE ar = 0;
+ BYTE ag = 0;
+ BYTE ab = 0;
+ BYTE aa = 0;
+ BYTE br = 0;
+ BYTE bg = 0;
+ BYTE bb = 0;
+ BYTE ba = 0;
+ FreeRDPSplitColor(colorA, formatA, &ar, &ag, &ab, &aa, NULL);
+ FreeRDPSplitColor(colorB, formatB, &br, &bg, &bb, &ba, NULL);
+
+ if (ar != br)
+ return FALSE;
+ if (ag != bg)
+ return FALSE;
+ if (ab != bb)
+ return FALSE;
+ if (aa != ba)
+ return FALSE;
+ return TRUE;
+}
+
+static BOOL pixel_equal(const BYTE* WINPR_RESTRICT a, UINT32 formatA, const BYTE* WINPR_RESTRICT b,
+ UINT32 formatB, size_t count)
+{
+ const size_t bppA = FreeRDPGetBytesPerPixel(formatA);
+ const size_t bppB = FreeRDPGetBytesPerPixel(formatB);
+
+ for (size_t x = 0; x < count; x++)
+ {
+ const UINT32 colorA = FreeRDPReadColor(&a[bppA * x], formatA);
+ const UINT32 colorB = FreeRDPReadColor(&b[bppB * x], formatB);
+ if (!color_equal(colorA, formatA, colorB, formatB))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL color_equal_no_alpha(UINT32 colorA, UINT32 formatA, UINT32 colorB, UINT32 formatB)
+{
+ BYTE ar = 0;
+ BYTE ag = 0;
+ BYTE ab = 0;
+ BYTE br = 0;
+ BYTE bg = 0;
+ BYTE bb = 0;
+ FreeRDPSplitColor(colorA, formatA, &ar, &ag, &ab, NULL, NULL);
+ FreeRDPSplitColor(colorB, formatB, &br, &bg, &bb, NULL, NULL);
+
+ if (ar != br)
+ return FALSE;
+ if (ag != bg)
+ return FALSE;
+ if (ab != bb)
+ return FALSE;
+ return TRUE;
+}
+
+static BOOL pixel_equal_no_alpha(const BYTE* WINPR_RESTRICT a, UINT32 formatA,
+ const BYTE* WINPR_RESTRICT b, UINT32 formatB, size_t count)
+{
+ const size_t bppA = FreeRDPGetBytesPerPixel(formatA);
+ const size_t bppB = FreeRDPGetBytesPerPixel(formatB);
+
+ for (size_t x = 0; x < count; x++)
+ {
+ const UINT32 colorA = FreeRDPReadColor(&a[bppA * x], formatA);
+ const UINT32 colorB = FreeRDPReadColor(&b[bppB * x], formatB);
+ if (!color_equal_no_alpha(colorA, formatA, colorB, formatB))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL pixel_equal_same_format(const BYTE* WINPR_RESTRICT a, UINT32 formatA,
+ const BYTE* WINPR_RESTRICT b, UINT32 formatB, size_t count)
+{
+ if (formatA != formatB)
+ return FALSE;
+ const size_t bppA = FreeRDPGetBytesPerPixel(formatA);
+ return memcmp(a, b, count * bppA) == 0;
+}
+
+int shadow_capture_compare_with_format(const BYTE* WINPR_RESTRICT pData1, UINT32 format1,
+ UINT32 nStep1, UINT32 nWidth, UINT32 nHeight,
+ const BYTE* WINPR_RESTRICT pData2, UINT32 format2,
+ UINT32 nStep2, RECTANGLE_16* WINPR_RESTRICT rect)
+{
+ BOOL(*pixel_equal_fn)
+ (const BYTE* a, UINT32 formatA, const BYTE* b, UINT32 formatB, size_t count) = pixel_equal;
+
+ if (format1 == format2)
+ pixel_equal_fn = pixel_equal_same_format;
+ else if (!FreeRDPColorHasAlpha(format1) || !FreeRDPColorHasAlpha(format2))
+ pixel_equal_fn = pixel_equal_no_alpha;
+
+ BOOL allEqual = TRUE;
UINT32 tw = 0;
- UINT32 th = 0;
- UINT32 nrow = 0;
- UINT32 ncol = 0;
- UINT32 l = 0;
- UINT32 t = 0;
+ const UINT32 nrow = (nHeight + 15) / 16;
+ const UINT32 ncol = (nWidth + 15) / 16;
+ UINT32 l = ncol + 1;
+ UINT32 t = nrow + 1;
UINT32 r = 0;
UINT32 b = 0;
- BYTE* p1 = NULL;
- BYTE* p2 = NULL;
- BOOL rows[1024];
-#ifdef WITH_DEBUG_SHADOW_CAPTURE
- BOOL cols[1024] = { FALSE };
-#endif
- allEqual = TRUE;
- ZeroMemory(rect, sizeof(RECTANGLE_16));
- FillMemory(rows, sizeof(rows), 0xFF);
-#ifdef WITH_DEBUG_SHADOW_CAPTURE
- FillMemory(cols, sizeof(cols), 0xFF);
-#endif
- nrow = (nHeight + 15) / 16;
- ncol = (nWidth + 15) / 16;
- l = ncol + 1;
- r = 0;
- t = nrow + 1;
- b = 0;
-
- for (UINT32 ty = 0; ty < nrow; ty++)
+ const size_t bppA = FreeRDPGetBytesPerPixel(format1);
+ const size_t bppB = FreeRDPGetBytesPerPixel(format2);
+ const RECTANGLE_16 empty = { 0 };
+ WINPR_ASSERT(rect);
+
+ *rect = empty;
+
+ for (size_t ty = 0; ty < nrow; ty++)
{
- th = ((ty + 1) == nrow) ? (nHeight % 16) : 16;
+ BOOL rowEqual = TRUE;
+ size_t th = ((ty + 1) == nrow) ? (nHeight % 16) : 16;
if (!th)
th = 16;
- for (UINT32 tx = 0; tx < ncol; tx++)
+ for (size_t tx = 0; tx < ncol; tx++)
{
- equal = TRUE;
+ BOOL equal = TRUE;
tw = ((tx + 1) == ncol) ? (nWidth % 16) : 16;
if (!tw)
tw = 16;
- p1 = &pData1[(ty * 16 * nStep1) + (tx * 16 * 4)];
- p2 = &pData2[(ty * 16 * nStep2) + (tx * 16 * 4)];
+ const BYTE* p1 = &pData1[(ty * 16 * nStep1) + (tx * 16ull * bppA)];
+ const BYTE* p2 = &pData2[(ty * 16 * nStep2) + (tx * 16ull * bppB)];
- for (UINT32 k = 0; k < th; k++)
+ for (size_t k = 0; k < th; k++)
{
- if (memcmp(p1, p2, tw * 4) != 0)
+ if (!pixel_equal_fn(p1, format1, p2, format2, tw))
{
equal = FALSE;
break;
@@ -142,11 +234,7 @@ int shadow_capture_compare(BYTE* pData1, UINT32 nStep1, UINT32 nWidth, UINT32 nH
if (!equal)
{
- rows[ty] = FALSE;
-#ifdef WITH_DEBUG_SHADOW_CAPTURE
- cols[tx] = FALSE;
-#endif
-
+ rowEqual = FALSE;
if (l > tx)
l = tx;
@@ -155,7 +243,7 @@ int shadow_capture_compare(BYTE* pData1, UINT32 nStep1, UINT32 nWidth, UINT32 nH
}
}
- if (!rows[ty])
+ if (!rowEqual)
{
allEqual = FALSE;
@@ -187,46 +275,6 @@ int shadow_capture_compare(BYTE* pData1, UINT32 nStep1, UINT32 nWidth, UINT32 nH
if (rect->bottom > nHeight)
rect->bottom = (UINT16)nHeight;
-#ifdef WITH_DEBUG_SHADOW_CAPTURE
- size_t size = ncol + 1;
- char* col_str = calloc(size, sizeof(char));
-
- if (!col_str)
- {
- WLog_ERR(TAG, "calloc failed!");
- return 1;
- }
-
- for (UINT32 tx = 0; tx < ncol; tx++)
- sprintf_s(&col_str[tx], size - tx, "-");
-
- WLog_INFO(TAG, "%s", col_str);
-
- for (UINT32 tx = 0; tx < ncol; tx++)
- sprintf_s(&col_str[tx], size - tx, "%c", cols[tx] ? 'O' : 'X');
-
- WLog_INFO(TAG, "%s", col_str);
-
- for (UINT32 tx = 0; tx < ncol; tx++)
- sprintf_s(&col_str[tx], size - tx, "-");
-
- WLog_INFO(TAG, "%s", col_str);
-
- for (UINT32 ty = 0; ty < nrow; ty++)
- {
- for (UINT32 tx = 0; tx < ncol; tx++)
- sprintf_s(&col_str[tx], size - tx, "%c", cols[tx] ? 'O' : 'X');
-
- WLog_INFO(TAG, "%s", col_str);
- WLog_INFO(TAG, "|%s|", rows[ty] ? "O" : "X");
- }
-
- WLog_INFO(TAG,
- "left: %" PRIu32 " top: %" PRIu32 " right: %" PRIu32 " bottom: %" PRIu32
- " ncol: %" PRIu32 " nrow: %" PRIu32,
- l, t, r, b, ncol, nrow);
- free(col_str);
-#endif
return 1;
}
diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c
index 0fd5236..f0b4dc4 100644
--- a/server/shadow/shadow_client.c
+++ b/server/shadow/shadow_client.c
@@ -252,7 +252,7 @@ static BOOL shadow_client_context_new(freerdp_peer* peer, rdpContext* context)
goto fail;
region16_init(&(client->invalidRegion));
- client->vcm = WTSOpenServerA(peer->context);
+ client->vcm = WTSOpenServerA((LPSTR)peer->context);
if (!client->vcm || client->vcm == INVALID_HANDLE_VALUE)
goto fail;
@@ -1444,7 +1444,6 @@ static BOOL shadow_client_send_surface_bits(rdpShadowClient* client, BYTE* pSrcD
const RFX_MESSAGE* msg = rfx_message_list_get(messages, i);
if (!rfx_write_message(encoder->rfx, s, msg))
{
- rfx_message_list_free(messages);
WLog_ERR(TAG, "rfx_write_message failed");
ret = FALSE;
break;
@@ -1982,7 +1981,10 @@ static INLINE BOOL shadow_client_no_surface_update(rdpShadowClient* client,
server = client->server;
WINPR_ASSERT(server);
surface = client->inLobby ? server->lobby : server->surface;
- return shadow_client_surface_update(client, &(surface->invalidRegion));
+ EnterCriticalSection(&surface->lock);
+ const BOOL rc = shadow_client_surface_update(client, &(surface->invalidRegion));
+ LeaveCriticalSection(&surface->lock);
+ return rc;
}
static int shadow_client_subsystem_process_message(rdpShadowClient* client, wMessage* message)
diff --git a/server/shadow/shadow_lobby.c b/server/shadow/shadow_lobby.c
index 8a9fade..f28408d 100644
--- a/server/shadow/shadow_lobby.c
+++ b/server/shadow/shadow_lobby.c
@@ -27,9 +27,9 @@
BOOL shadow_client_init_lobby(rdpShadowServer* server)
{
+ BOOL rc = FALSE;
int width = 0;
int height = 0;
- rdtkEngine* engine = NULL;
rdtkSurface* surface = NULL;
RECTANGLE_16 invalidRect;
rdpShadowSurface* lobby = server->lobby;
@@ -37,17 +37,14 @@ BOOL shadow_client_init_lobby(rdpShadowServer* server)
if (!lobby)
return FALSE;
- if (!(engine = rdtk_engine_new()))
- {
+ rdtkEngine* engine = rdtk_engine_new();
+ if (!engine)
return FALSE;
- }
- if (!(surface =
- rdtk_surface_new(engine, lobby->data, lobby->width, lobby->height, lobby->scanline)))
- {
- rdtk_engine_free(engine);
- return FALSE;
- }
+ EnterCriticalSection(&lobby->lock);
+ surface = rdtk_surface_new(engine, lobby->data, lobby->width, lobby->height, lobby->scanline);
+ if (!surface)
+ goto fail;
invalidRect.left = 0;
invalidRect.top = 0;
@@ -77,9 +74,11 @@ BOOL shadow_client_init_lobby(rdpShadowServer* server)
rdtk_surface_free(surface);
- rdtk_engine_free(engine);
-
region16_union_rect(&(lobby->invalidRegion), &(lobby->invalidRegion), &invalidRect);
- return TRUE;
+ rc = TRUE;
+fail:
+ LeaveCriticalSection(&lobby->lock);
+ rdtk_engine_free(engine);
+ return rc;
}
diff --git a/server/shadow/shadow_server.c b/server/shadow/shadow_server.c
index 067dcc6..751f460 100644
--- a/server/shadow/shadow_server.c
+++ b/server/shadow/shadow_server.c
@@ -55,6 +55,14 @@ static int shadow_server_print_command_line_help(int argc, char** argv,
printf("Usage: %s [options]\n", argv[0]);
printf("\n");
+ printf("Notes: By default NLA security is active.\n");
+ printf("\tIn this mode a SAM database is required.\n");
+ printf("\tProvide one with /sam-file:<file with path>\n");
+ printf("\telse the default path /etc/winpr/SAM is used.\n");
+ printf("\tIf there is no existing SAM file authentication for all users will fail.\n");
+ printf(
+ "\n\tIf authentication against PAM is desired, start with -sec-nla (requires compiled in "
+ "support for PAM)\n\n");
printf("Syntax:\n");
printf(" /flag (enables flag)\n");
printf(" /option:<value> (specifies option with value)\n");
diff --git a/server/shadow/shadow_subsystem.c b/server/shadow/shadow_subsystem.c
index ca73c72..bbdb568 100644
--- a/server/shadow/shadow_subsystem.c
+++ b/server/shadow/shadow_subsystem.c
@@ -190,20 +190,23 @@ UINT32 shadow_enum_monitors(MONITOR_DEF* monitors, UINT32 maxMonitors)
* Caller should free the andMaskData and xorMaskData later.
*/
int shadow_subsystem_pointer_convert_alpha_pointer_data(
- BYTE* pixels, BOOL premultiplied, UINT32 width, UINT32 height,
+ const BYTE* WINPR_RESTRICT pixels, BOOL premultiplied, UINT32 width, UINT32 height,
+ SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE* WINPR_RESTRICT pointerColor)
+{
+ return shadow_subsystem_pointer_convert_alpha_pointer_data_to_format(
+ pixels, PIXEL_FORMAT_BGRX32, premultiplied, width, height, pointerColor);
+}
+
+int shadow_subsystem_pointer_convert_alpha_pointer_data_to_format(
+ const BYTE* pixels, UINT32 format, BOOL premultiplied, UINT32 width, UINT32 height,
SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE* pointerColor)
{
- BYTE* pSrc8 = NULL;
- BYTE* pDst8 = NULL;
UINT32 xorStep = 0;
UINT32 andStep = 0;
UINT32 andBit = 0;
BYTE* andBits = NULL;
UINT32 andPixel = 0;
- BYTE A = 0;
- BYTE R = 0;
- BYTE G = 0;
- BYTE B = 0;
+ const size_t bpp = FreeRDPGetBytesPerPixel(format);
xorStep = (width * 3);
xorStep += (xorStep % 2);
@@ -227,20 +230,23 @@ int shadow_subsystem_pointer_convert_alpha_pointer_data(
return -1;
}
- for (UINT32 y = 0; y < height; y++)
+ for (size_t y = 0; y < height; y++)
{
- pSrc8 = &pixels[(width * 4) * (height - 1 - y)];
- pDst8 = &(pointerColor->xorMaskData[y * xorStep]);
+ const BYTE* pSrc8 = &pixels[(width * bpp) * (height - 1 - y)];
+ BYTE* pDst8 = &(pointerColor->xorMaskData[y * xorStep]);
andBit = 0x80;
andBits = &(pointerColor->andMaskData[andStep * y]);
- for (UINT32 x = 0; x < width; x++)
+ for (size_t x = 0; x < width; x++)
{
- B = *pSrc8++;
- G = *pSrc8++;
- R = *pSrc8++;
- A = *pSrc8++;
+ BYTE B = 0;
+ BYTE G = 0;
+ BYTE R = 0;
+ BYTE A = 0;
+
+ const UINT32 color = FreeRDPReadColor(&pSrc8[x * bpp], format);
+ FreeRDPSplitColor(color, format, &R, &G, &B, &A, NULL);
andPixel = 0;