import mingw-spice-vdagent-0.9.0-3.el8

This commit is contained in:
CentOS Sources 2019-05-07 08:01:10 -04:00 committed by Andrew Lukoshko
commit 36a6641c43
44 changed files with 2972 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
SOURCES/vdagent-win-0.9.0.tar.xz

View File

@ -0,0 +1 @@
e053d42313e9a201313052af0694c5489b643bc4 SOURCES/vdagent-win-0.9.0.tar.xz

View File

@ -0,0 +1,56 @@
From aaeecf129424752b13373a9242bcede58337e047 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Tue, 22 Aug 2017 12:51:45 +0100
Subject: [PATCH 01/43] Make BitmapCoder::from_bitmap return a BMP file format
The network expect the format of the data to match a file
format so prepending DIB data with BITMAPFILEHEADER change
the format from DIB to BMP file.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Uri Lublin <uril@redhat.com>
---
vdagent/image.cpp | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/vdagent/image.cpp b/vdagent/image.cpp
index 82cfb0e..15bd4fa 100644
--- a/vdagent/image.cpp
+++ b/vdagent/image.cpp
@@ -150,6 +150,8 @@ void BitmapCoder::get_dib_data(uint8_t *dib, const uint8_t *data, size_t size)
uint8_t *BitmapCoder::from_bitmap(const BITMAPINFO& info, const void *bits, long &size)
{
+ BITMAPFILEHEADER file_hdr;
+
const BITMAPINFOHEADER& head(info.bmiHeader);
const DWORD max_palette_colors = head.biBitCount <= 8 ? 1 << head.biBitCount : 0;
@@ -157,14 +159,21 @@ uint8_t *BitmapCoder::from_bitmap(const BITMAPINFO& info, const void *bits, long
const size_t stride = compute_dib_stride(head.biWidth, head.biBitCount);
const size_t image_size = stride * head.biHeight;
- size = sizeof(head) + palette_size + image_size;
+ size = sizeof(file_hdr) + sizeof(head) + palette_size + image_size;
+
+ file_hdr.bfType = 'B' + 'M'*256u;
+ file_hdr.bfSize = size;
+ file_hdr.bfReserved1 = 0;
+ file_hdr.bfReserved2 = 0;
+ file_hdr.bfOffBits = sizeof(file_hdr) + sizeof(head) + palette_size;
uint8_t *data = (uint8_t *) malloc(size);
if (!data) {
return NULL;
}
- memcpy(data, &info, sizeof(head) + palette_size);
- memcpy(data + sizeof(head) + palette_size, bits, image_size);
+ memcpy(data, &file_hdr, sizeof(file_hdr));
+ memcpy(data + sizeof(file_hdr), &info, sizeof(head) + palette_size);
+ memcpy(data + sizeof(file_hdr) + sizeof(head) + palette_size, bits, image_size);
return data;
}
--
2.17.1

View File

@ -0,0 +1,62 @@
From 9c85f8d3caf826099d8a1db562e23e5cf4e8b243 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Tue, 22 Aug 2017 12:57:16 +0100
Subject: [PATCH 02/43] imagetest: Save PNG file using a helper function
This allows to reuse the code to save a DIB to a file.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Uri Lublin <uril@redhat.com>
---
vdagent/imagetest.cpp | 28 ++++++++++++++++++----------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/vdagent/imagetest.cpp b/vdagent/imagetest.cpp
index 319b188..3a553a9 100644
--- a/vdagent/imagetest.cpp
+++ b/vdagent/imagetest.cpp
@@ -23,6 +23,23 @@
#include "image.h"
#include "imagepng.h"
+static void
+save_dib_to_file(ImageCoder& coder, const uint8_t *raw_dib, const char *filename)
+{
+ const BITMAPINFO& info(*(BITMAPINFO*) raw_dib);
+ const uint8_t *raw_bits = &raw_dib[sizeof(BITMAPINFOHEADER) + 4 * info.bmiHeader.biClrUsed];
+
+ long size = 0;
+ uint8_t *raw_file = coder.from_bitmap(info, raw_bits, size);
+ assert(raw_file && size > 0);
+
+ FILE *f = fopen(filename, "wb");
+ assert(f);
+ assert(fwrite(raw_file, 1, size, f) == (unsigned long) size);
+ fclose(f);
+ free(raw_file);
+}
+
int main(int argc, char **argv)
{
ImageCoder *coder = create_png_coder();
@@ -66,16 +83,7 @@ int main(int argc, char **argv)
fclose(f);
// convert back to PNG
- long png_size = 0;
- uint8_t *png = coder->from_bitmap(*((BITMAPINFO*)&out[0]), &out[sizeof(BITMAPINFOHEADER) + 4 * info.biClrUsed], png_size);
- assert(png && png_size > 0);
-
- f = fopen(argc > 3 ? argv[3] : "out.png", "wb");
- assert(f);
- assert(fwrite(png, 1, png_size, f) == (unsigned long) png_size);
- fclose(f);
- free(png);
- png = NULL;
+ save_dib_to_file(*coder, &out[0], argc > 3 ? argv[3] : "out.png");
return 0;
}
--
2.17.1

View File

@ -0,0 +1,89 @@
From 16aee83802ee436cc5216bd55cb8f7760c30f50a Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Tue, 22 Aug 2017 12:58:25 +0100
Subject: [PATCH 03/43] imagetest: Save BMP file using BitmapCoder
This allows to test BitmapCoder::from_bitmap.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Uri Lublin <uril@redhat.com>
---
vdagent/image.cpp | 2 --
vdagent/image.h | 2 ++
vdagent/imagetest.cpp | 20 ++++++--------------
3 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/vdagent/image.cpp b/vdagent/image.cpp
index 15bd4fa..1b21b53 100644
--- a/vdagent/image.cpp
+++ b/vdagent/image.cpp
@@ -23,8 +23,6 @@
#include "image.h"
#include "imagepng.h"
-ImageCoder *create_bitmap_coder();
-
static ImageCoder *get_coder(uint32_t vdagent_type)
{
switch (vdagent_type) {
diff --git a/vdagent/image.h b/vdagent/image.h
index da549d3..326d7f9 100644
--- a/vdagent/image.h
+++ b/vdagent/image.h
@@ -39,6 +39,8 @@ static inline size_t compute_dib_stride(unsigned int width, unsigned int bit_cou
return ((width * bit_count + 31u) & ~31u) / 8u;
}
+ImageCoder *create_bitmap_coder();
+
/**
* Returns image to put in the clipboard.
*
diff --git a/vdagent/imagetest.cpp b/vdagent/imagetest.cpp
index 3a553a9..36b8f6c 100644
--- a/vdagent/imagetest.cpp
+++ b/vdagent/imagetest.cpp
@@ -18,6 +18,7 @@
#undef NDEBUG
#include <assert.h>
#include <vector>
+#include <memory>
#include "vdcommon.h"
#include "image.h"
@@ -42,7 +43,7 @@ save_dib_to_file(ImageCoder& coder, const uint8_t *raw_dib, const char *filename
int main(int argc, char **argv)
{
- ImageCoder *coder = create_png_coder();
+ std::unique_ptr<ImageCoder> coder(create_png_coder());
assert(coder);
if (argc < 2) {
@@ -68,19 +69,10 @@ int main(int argc, char **argv)
memset(&out[0], 0xcc, dib_size);
coder->get_dib_data(&out[0], &data[0], len);
- // looks like many tools wants this header so craft it
- BITMAPFILEHEADER head;
- memset(&head, 0, sizeof(head));
- head.bfType = 'B'+'M'*256u;
- head.bfSize = sizeof(head) + dib_size;
- BITMAPINFOHEADER& info(*(BITMAPINFOHEADER*)&out[0]);
- head.bfOffBits = sizeof(head) + sizeof(BITMAPINFOHEADER) + 4 * info.biClrUsed;
-
- f = fopen(argc > 2 ? argv[2] : "out.bmp", "wb");
- assert(f);
- assert(fwrite(&head, 1, sizeof(head), f) == sizeof(head));
- assert(fwrite(&out[0], 1, dib_size, f) == dib_size);
- fclose(f);
+ // write BMP file
+ std::unique_ptr<ImageCoder> bmp_coder(create_bitmap_coder());
+ assert(bmp_coder);
+ save_dib_to_file(*bmp_coder, &out[0], argc > 2 ? argv[2] : "out.bmp");
// convert back to PNG
save_dib_to_file(*coder, &out[0], argc > 3 ? argv[3] : "out.png");
--
2.17.1

View File

@ -0,0 +1,26 @@
From 2aa6f16af4ad2d50ab614dd87b10baae1729c461 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Thu, 24 May 2018 14:01:53 +0100
Subject: [PATCH 04/43] vdagent: Removed unused declaration
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/vdagent.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index f00fbf5..0a364df 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -99,7 +99,6 @@ private:
void dispatch_message(VDAgentMessage* msg, uint32_t port);
uint32_t get_clipboard_format(uint32_t type) const;
uint32_t get_clipboard_type(uint32_t format) const;
- DWORD get_cximage_format(uint32_t type) const;
enum { owner_none, owner_guest, owner_client };
void set_clipboard_owner(int new_owner);
enum { CONTROL_STOP, CONTROL_RESET, CONTROL_DESKTOP_SWITCH, CONTROL_LOGON, CONTROL_CLIPBOARD };
--
2.17.1

View File

@ -0,0 +1,63 @@
From e2ced9f094bf676856ae78779f4a791936eb535f Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Mon, 5 Sep 2016 14:51:56 +0100
Subject: [PATCH 05/43] Avoid to use names with reserved characters.
Some characters are reserved and should not be used in Windows
independently by the file system used.
This avoid to use paths in the filename which could lead to some
nasty hacks (like names like "..\hack.txt").
The return statement cause the file transfer to be aborted with
VD_AGENT_FILE_XFER_STATUS_ERROR as status.
":" is used to separate filenames from stream names and can be used
to create hidden streams. Also is used for drive separator (A:)
or device names (NUL:).
"/" and "\" are reserved for components (directory, filename, drive,
share, server) separators.
"*" and "?" are wildcards (which on Windows are supported by
different APIs too).
"<", ">", """ and "|" are reserved for shell usage.
More information on "Naming Files, Paths, and Namespaces" page at
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
This fixes also https://bugzilla.redhat.com/show_bug.cgi?id=1520393.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/file_xfer.cpp | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/vdagent/file_xfer.cpp b/vdagent/file_xfer.cpp
index e877cca..8203b99 100644
--- a/vdagent/file_xfer.cpp
+++ b/vdagent/file_xfer.cpp
@@ -33,6 +33,12 @@
#include "file_xfer.h"
#include "as_user.h"
+#define FILENAME_RESERVED_CHAR_LIST \
+ ":" /* streams and devices */ \
+ "/\\" /* components separator */ \
+ "?*" /* wildcards */ \
+ "<>\"|" /* reserved to shell */
+
void FileXfer::reset()
{
FileXferTasks::iterator iter;
@@ -72,6 +78,10 @@ void FileXfer::handle_start(VDAgentFileXferStartMessage* start,
return;
}
vd_printf("%u %s (%" PRIu64 ")", start->id, file_name, file_size);
+ if (strcspn(file_name, FILENAME_RESERVED_CHAR_LIST) != strlen(file_name)) {
+ vd_printf("filename contains invalid characters");
+ return;
+ }
if (!as_user.begin()) {
vd_printf("as_user failed");
return;
--
2.17.1

View File

@ -0,0 +1,92 @@
From 9a929bd24ade5e25b33afd43509ff04acf4352a0 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Fri, 25 May 2018 19:47:20 +0100
Subject: [PATCH 08/43] vcproj: Remove reference to CxImage
Not used anymore.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/vdagent.vcproj | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/vdagent/vdagent.vcproj b/vdagent/vdagent.vcproj
index f9f4228..f830b0f 100644
--- a/vdagent/vdagent.vcproj
+++ b/vdagent/vdagent.vcproj
@@ -44,7 +44,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\common;$(SPICE_PROTOCOL_DIR);$(SPICE_LIBS)\include\CxImage"
+ AdditionalIncludeDirectories="..\common;$(SPICE_PROTOCOL_DIR)"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS,_WIN32_WINNT=0x0501"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -65,7 +65,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="Version.lib zlibwapiD.lib png_d.lib cximage_d.lib wtsapi32.lib"
+ AdditionalDependencies="Version.lib zlibwapiD.lib png_d.lib wtsapi32.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;$(SPICE_LIBS)\lib&quot;"
GenerateDebugInformation="true"
@@ -122,7 +122,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\common;$(SPICE_PROTOCOL_DIR);$(SPICE_LIBS)\include\CxImage"
+ AdditionalIncludeDirectories="..\common;$(SPICE_PROTOCOL_DIR)"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS,_WIN32_WINNT=0x0501"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -143,7 +143,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="Version.lib zlibwapiD.lib png_d.lib cximage_d.lib wtsapi32.lib"
+ AdditionalDependencies="Version.lib zlibwapiD.lib png_d.lib wtsapi32.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="&quot;$(SPICE_LIBS)\lib64&quot;"
IgnoreDefaultLibraryNames=""
@@ -200,7 +200,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\common;$(SPICE_PROTOCOL_DIR);$(SPICE_LIBS)\include\CxImage"
+ AdditionalIncludeDirectories="..\common;$(SPICE_PROTOCOL_DIR)"
AdditionalUsingDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS,_WIN32_WINNT=0x0501"
RuntimeLibrary="0"
@@ -220,7 +220,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="Version.lib zlibwapi.lib png.lib cximage.lib wtsapi32.lib"
+ AdditionalDependencies="Version.lib zlibwapi.lib png.lib wtsapi32.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;$(SPICE_LIBS)\lib&quot;"
GenerateDebugInformation="true"
@@ -279,7 +279,7 @@
/>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="..\common;$(SPICE_PROTOCOL_DIR);$(SPICE_LIBS)\include\CxImage"
+ AdditionalIncludeDirectories="..\common;$(SPICE_PROTOCOL_DIR)"
AdditionalUsingDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS,_WIN32_WINNT=0x0501"
RuntimeLibrary="0"
@@ -299,7 +299,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="Version.lib zlibwapi.lib png.lib cximage.lib wtsapi32.lib"
+ AdditionalDependencies="Version.lib zlibwapi.lib png.lib wtsapi32.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="&quot;$(SPICE_LIBS)\lib64&quot;"
GenerateDebugInformation="true"
--
2.17.1

View File

@ -0,0 +1,44 @@
From b15a8806390153748594937f321c192181f9000f Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Fri, 25 May 2018 19:47:32 +0100
Subject: [PATCH 09/43] vcproj: Add some missing files
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/vdagent.vcproj | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/vdagent/vdagent.vcproj b/vdagent/vdagent.vcproj
index f830b0f..376ddd4 100644
--- a/vdagent/vdagent.vcproj
+++ b/vdagent/vdagent.vcproj
@@ -349,6 +349,10 @@
RelativePath=".\desktop_layout.cpp"
>
</File>
+ <File
+ RelativePath=".\display_configuration.cpp"
+ >
+ </File>
<File
RelativePath=".\display_setting.cpp"
>
@@ -357,6 +361,14 @@
RelativePath=".\file_xfer.cpp"
>
</File>
+ <File
+ RelativePath=".\image.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\imagepng.cpp"
+ >
+ </File>
<File
RelativePath=".\vdagent.cpp"
>
--
2.17.1

View File

@ -0,0 +1,38 @@
From 1982d50375e4f3fdf5d5ca5e497328743af4e559 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sat, 26 May 2018 07:51:59 +0100
Subject: [PATCH 10/43] Fix minor compiler compatibility
Ensure std::min is declared including directly algorithm header.
Undefine possible min and max macros, some Windows headers define them.
Currently happens using Visual Studio 2015.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/image.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/vdagent/image.cpp b/vdagent/image.cpp
index 1b21b53..c0bcdb5 100644
--- a/vdagent/image.cpp
+++ b/vdagent/image.cpp
@@ -18,11 +18,15 @@
#include <spice/macros.h>
#include <memory>
#include <vector>
+#include <algorithm>
#include "vdcommon.h"
#include "image.h"
#include "imagepng.h"
+#undef max
+#undef min
+
static ImageCoder *get_coder(uint32_t vdagent_type)
{
switch (vdagent_type) {
--
2.17.1

View File

@ -0,0 +1,29 @@
From 022c56ac6ae2f7f9a082b81e44872d48aace35b2 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sat, 26 May 2018 07:50:53 +0100
Subject: [PATCH 11/43] Avoid unused variable warning
Currently happens using Visual Studio 2015.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/display_configuration.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/vdagent/display_configuration.cpp b/vdagent/display_configuration.cpp
index 6e7624b..cdbbe23 100644
--- a/vdagent/display_configuration.cpp
+++ b/vdagent/display_configuration.cpp
@@ -259,7 +259,7 @@ DisplayConfig* DisplayConfig::create_config()
try {
new_interface = new WDDMInterface();
}
- catch (std::exception& e) {
+ catch (std::exception&) {
new_interface = new XPDMInterface();
}
return new_interface;
--
2.17.1

View File

@ -0,0 +1,61 @@
From d4a4fb28ea0c057428ef1f28bc689b8d0f085dc6 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Mon, 28 May 2018 09:20:41 +0100
Subject: [PATCH 12/43] msi: Do not generate deps.txt
There's no reason to tell the package installed on the build system
used.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
Makefile.am | 5 +----
spice-vdagent.wxs.in | 4 ----
2 files changed, 1 insertion(+), 8 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 62640f2..3020824 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -100,15 +100,12 @@ test_log_win_SOURCES = \
common/test-log.cpp \
$(NULL)
-deps.txt:
- $(AM_V_GEN)rpm -qa | grep $(host_os) | sort | unix2dos > $@
-
MANUFACTURER = The Spice Project
EXTRA_DIST += spice-vdagent.wxs.in
CONFIG_STATUS_DEPENDENCIES = spice-vdagent.wxs.in
-spice-vdagent-$(WIXL_ARCH)-$(VERSION)$(BUILDID).msi: spice-vdagent.wxs deps.txt all
+spice-vdagent-$(WIXL_ARCH)-$(VERSION)$(BUILDID).msi: spice-vdagent.wxs all
$(AM_V_GEN)DESTDIR=`mktemp -d`&& \
make -C $(top_builddir) install DESTDIR=$$DESTDIR >/dev/null && \
MANUFACTURER="$(MANUFACTURER)" wixl -D SourceDir=$(prefix) \
diff --git a/spice-vdagent.wxs.in b/spice-vdagent.wxs.in
index 452f995..7432ca9 100644
--- a/spice-vdagent.wxs.in
+++ b/spice-vdagent.wxs.in
@@ -61,9 +61,6 @@
Wait="yes"/>
</Component>
</Directory>
- <Component Id="CDepsTxt" Guid="*">
- <File Id='depstxt' Name='deps.txt' DiskId='1' Source='deps.txt' KeyPath='yes'/>
- </Component>
</Directory>
</Directory>
</Directory>
@@ -71,7 +68,6 @@
<Feature Id="Complete" Level="1">
<ComponentRef Id="CSpiceAgent"/>
<ComponentRef Id="CSpiceService"/>
- <ComponentRef Id="CDepsTxt"/>
</Feature>
</Product>
--
2.17.1

View File

@ -0,0 +1,39 @@
From 0de788aa6175fa6035b9f79a7dcfda8b98cd1e6f Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Fri, 25 May 2018 19:41:26 +0100
Subject: [PATCH 13/43] file_xfer: Remove FileXferTask structure alignment
There's no reason beside losing performances to align
that structure, is not passed as binary data.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/file_xfer.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/vdagent/file_xfer.h b/vdagent/file_xfer.h
index 25cd5c2..029d0e7 100644
--- a/vdagent/file_xfer.h
+++ b/vdagent/file_xfer.h
@@ -21,7 +21,7 @@
#include <map>
#include "vdcommon.h"
-typedef struct ALIGN_VC FileXferTask {
+typedef struct FileXferTask {
FileXferTask(HANDLE _handle, uint64_t _size, const TCHAR* _name):
handle(_handle), size(_size), pos(0) {
// FIXME: should raise an error if name is too long..
@@ -36,7 +36,7 @@ typedef struct ALIGN_VC FileXferTask {
TCHAR name[MAX_PATH];
void cancel();
-} ALIGN_GCC FileXferTask;
+} FileXferTask;
typedef std::map<uint32_t, FileXferTask*> FileXferTasks;
--
2.17.1

View File

@ -0,0 +1,39 @@
From e8ab5856a116f6b7b9bd28781fcf2f685cc6645f Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Fri, 25 May 2018 19:46:34 +0100
Subject: [PATCH 14/43] file_xfer: Remove too C syntax for C++
In C++ simply declaring the struct add the structure name to the global
namespace, no needs for additional typedef.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/file_xfer.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/vdagent/file_xfer.h b/vdagent/file_xfer.h
index 029d0e7..747c29c 100644
--- a/vdagent/file_xfer.h
+++ b/vdagent/file_xfer.h
@@ -21,7 +21,7 @@
#include <map>
#include "vdcommon.h"
-typedef struct FileXferTask {
+struct FileXferTask {
FileXferTask(HANDLE _handle, uint64_t _size, const TCHAR* _name):
handle(_handle), size(_size), pos(0) {
// FIXME: should raise an error if name is too long..
@@ -36,7 +36,7 @@ typedef struct FileXferTask {
TCHAR name[MAX_PATH];
void cancel();
-} FileXferTask;
+};
typedef std::map<uint32_t, FileXferTask*> FileXferTasks;
--
2.17.1

View File

@ -0,0 +1,99 @@
From aefc220c027c98c0877cbb6dc7140e72f119262b Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Fri, 25 May 2018 20:01:11 +0100
Subject: [PATCH 15/43] file_xfer: Use destructor for FileXferTask
Limit too much manual work.
By default delete the file, unless success() is called.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/file_xfer.cpp | 24 +++++++++++++++---------
vdagent/file_xfer.h | 4 +++-
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/vdagent/file_xfer.cpp b/vdagent/file_xfer.cpp
index 8203b99..ff4c0b9 100644
--- a/vdagent/file_xfer.cpp
+++ b/vdagent/file_xfer.cpp
@@ -46,7 +46,6 @@ void FileXfer::reset()
for (iter = _tasks.begin(); iter != _tasks.end(); iter++) {
task = iter->second;
- task->cancel();
delete task;
}
_tasks.clear();
@@ -181,14 +180,11 @@ bool FileXfer::handle_data(VDAgentFileXferDataMessage* data,
return false;
}
vd_printf("%u completed", iter->first);
+ task->success();
status->result = VD_AGENT_FILE_XFER_STATUS_SUCCESS;
fin:
if (task) {
- CloseHandle(task->handle);
- if (status->result != VD_AGENT_FILE_XFER_STATUS_SUCCESS) {
- DeleteFile(task->name);
- }
_tasks.erase(iter);
delete task;
}
@@ -196,10 +192,21 @@ fin:
return true;
}
-void FileXferTask::cancel()
+FileXferTask::~FileXferTask()
{
- CloseHandle(handle);
- DeleteFile(name);
+ if (handle != INVALID_HANDLE_VALUE) {
+ CloseHandle(handle);
+ DeleteFile(name);
+ }
+}
+
+void FileXferTask::success()
+{
+ // close the handle so the destructor won't delete the file
+ if (handle != INVALID_HANDLE_VALUE) {
+ CloseHandle(handle);
+ handle = INVALID_HANDLE_VALUE;
+ }
}
void FileXfer::handle_status(VDAgentFileXferStatusMessage* status)
@@ -218,7 +225,6 @@ void FileXfer::handle_status(VDAgentFileXferStatusMessage* status)
return;
}
task = iter->second;
- task->cancel();
_tasks.erase(iter);
delete task;
}
diff --git a/vdagent/file_xfer.h b/vdagent/file_xfer.h
index 747c29c..41f677a 100644
--- a/vdagent/file_xfer.h
+++ b/vdagent/file_xfer.h
@@ -30,12 +30,14 @@ struct FileXferTask {
lstrcpyn(name, _name, ARRAYSIZE(name));
name[ARRAYSIZE(name)-1] = 0;
}
+ ~FileXferTask();
+
HANDLE handle;
uint64_t size;
uint64_t pos;
TCHAR name[MAX_PATH];
- void cancel();
+ void success();
};
typedef std::map<uint32_t, FileXferTask*> FileXferTasks;
--
2.17.1

View File

@ -0,0 +1,130 @@
From 7b0c48b15bfe3c02c4158c7cb213403739d078b5 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Fri, 25 May 2018 23:03:18 +0100
Subject: [PATCH 16/43] file_xfer: Use shared_ptr to simplify memory management
Clear automatically tasks items.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/file_xfer.cpp | 25 ++++---------------------
vdagent/file_xfer.h | 3 ++-
2 files changed, 6 insertions(+), 22 deletions(-)
diff --git a/vdagent/file_xfer.cpp b/vdagent/file_xfer.cpp
index ff4c0b9..ada3b47 100644
--- a/vdagent/file_xfer.cpp
+++ b/vdagent/file_xfer.cpp
@@ -41,19 +41,11 @@
void FileXfer::reset()
{
- FileXferTasks::iterator iter;
- FileXferTask* task;
-
- for (iter = _tasks.begin(); iter != _tasks.end(); iter++) {
- task = iter->second;
- delete task;
- }
_tasks.clear();
}
FileXfer::~FileXfer()
{
- reset();
}
void FileXfer::handle_start(VDAgentFileXferStartMessage* start,
@@ -63,7 +55,6 @@ void FileXfer::handle_start(VDAgentFileXferStartMessage* start,
TCHAR file_path[MAX_PATH];
char file_name[MAX_PATH];
ULARGE_INTEGER free_bytes;
- FileXferTask* task;
uint64_t file_size;
HANDLE handle;
AsUser as_user;
@@ -146,7 +137,7 @@ void FileXfer::handle_start(VDAgentFileXferStartMessage* start,
vd_printf("Failed creating %ls. More than 63 copies exist?", file_path);
return;
}
- task = new FileXferTask(handle, file_size, file_path);
+ auto task = std::make_shared<FileXferTask>(handle, file_size, file_path);
_tasks[start->id] = task;
status->result = VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA;
}
@@ -155,7 +146,6 @@ bool FileXfer::handle_data(VDAgentFileXferDataMessage* data,
VDAgentFileXferStatusMessage* status)
{
FileXferTasks::iterator iter;
- FileXferTask* task = NULL;
DWORD written;
status->id = data->id;
@@ -163,9 +153,9 @@ bool FileXfer::handle_data(VDAgentFileXferDataMessage* data,
iter = _tasks.find(data->id);
if (iter == _tasks.end()) {
vd_printf("file id %u not found", data->id);
- goto fin;
+ return true;
}
- task = iter->second;
+ auto task = iter->second;
task->pos += data->size;
if (task->pos > task->size) {
vd_printf("file xfer is longer than expected");
@@ -184,11 +174,7 @@ bool FileXfer::handle_data(VDAgentFileXferDataMessage* data,
status->result = VD_AGENT_FILE_XFER_STATUS_SUCCESS;
fin:
- if (task) {
- _tasks.erase(iter);
- delete task;
- }
-
+ _tasks.erase(iter);
return true;
}
@@ -212,7 +198,6 @@ void FileXferTask::success()
void FileXfer::handle_status(VDAgentFileXferStatusMessage* status)
{
FileXferTasks::iterator iter;
- FileXferTask* task;
vd_printf("id %u result %u", status->id, status->result);
if (status->result != VD_AGENT_FILE_XFER_STATUS_CANCELLED) {
@@ -224,9 +209,7 @@ void FileXfer::handle_status(VDAgentFileXferStatusMessage* status)
vd_printf("file id %u not found", status->id);
return;
}
- task = iter->second;
_tasks.erase(iter);
- delete task;
}
bool FileXfer::dispatch(VDAgentMessage* msg, VDAgentFileXferStatusMessage* status)
diff --git a/vdagent/file_xfer.h b/vdagent/file_xfer.h
index 41f677a..b138019 100644
--- a/vdagent/file_xfer.h
+++ b/vdagent/file_xfer.h
@@ -19,6 +19,7 @@
#define _H_FILE_XFER
#include <map>
+#include <memory>
#include "vdcommon.h"
struct FileXferTask {
@@ -40,7 +41,7 @@ struct FileXferTask {
void success();
};
-typedef std::map<uint32_t, FileXferTask*> FileXferTasks;
+typedef std::map<uint32_t, std::shared_ptr<FileXferTask> > FileXferTasks;
class FileXfer {
public:
--
2.17.1

View File

@ -0,0 +1,257 @@
From b291e4ca14b611ad20cb93d90dc98c8a715b91f9 Mon Sep 17 00:00:00 2001
From: "free.user.name" <free.user.name@ya.ru>
Date: Fri, 16 Feb 2018 15:05:39 +0300
Subject: [PATCH 17/43] vdagent: Fix loss of mouse movement events
send_input() may not be immediately called from handle_mouse_event() on
movement. INPUT structure is generated and stored and a timer may be set
instead. If subsequent call to handle_mouse_event() occurs before timer
expires, prepared INPUT structure gets overwritten and MOUSEEVENTF_MOVE
bit is lost. Windows doesn't see updated mouse position as the result.
Make handle_mouse_event() merely store the new mouse state, and move
INPUT structure generation to send_input(). Shuffle new mouse state to
previous only after mouse events are submitted to SendInput() Windows
API function.
This patch was sent to the mailing list by an anonymous contributor
with minimal style changes.
You can easily test increasing VD_INPUT_INTERVAL_MS (like 1000).
For instance you can try in a word processor to move the cursor
clicking the mouse on different positions.
Acked-by: Victor Toso <victortoso@redhat.com>
---
vdagent/vdagent.cpp | 145 +++++++++++++++++++++-----------------------
1 file changed, 70 insertions(+), 75 deletions(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 0a364df..ca1f8fa 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -89,8 +89,7 @@ private:
void on_clipboard_grab();
void on_clipboard_request(UINT format);
void on_clipboard_release();
- DWORD get_buttons_change(DWORD last_buttons_state, DWORD new_buttons_state,
- DWORD mask, DWORD down_flag, DWORD up_flag);
+ DWORD get_buttons_change(DWORD mask, DWORD down_flag, DWORD up_flag);
static HGLOBAL utf8_alloc(LPCSTR data, int size);
static LRESULT CALLBACK wnd_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
static DWORD WINAPI event_thread_proc(LPVOID param);
@@ -130,10 +129,8 @@ private:
int _system_version;
int _clipboard_owner;
DWORD _clipboard_tick;
- DWORD _buttons_state;
- ULONG _mouse_x;
- ULONG _mouse_y;
- INPUT _input;
+ VDAgentMouseState _new_mouse = {};
+ VDAgentMouseState _last_mouse = {};
DWORD _input_time;
HANDLE _control_event;
HANDLE _stop_event;
@@ -190,9 +187,6 @@ VDAgent::VDAgent()
, _remove_clipboard_listener (NULL)
, _clipboard_owner (owner_none)
, _clipboard_tick (0)
- , _buttons_state (0)
- , _mouse_x (0)
- , _mouse_y (0)
, _input_time (0)
, _control_event (NULL)
, _stop_event (NULL)
@@ -220,7 +214,6 @@ VDAgent::VDAgent()
swprintf_s(log_path, MAX_PATH, VD_AGENT_LOG_PATH, temp_path);
_log = VDLog::get(log_path);
}
- ZeroMemory(&_input, sizeof(_input));
ZeroMemory(&_read_overlapped, sizeof(_read_overlapped));
ZeroMemory(&_write_overlapped, sizeof(_write_overlapped));
ZeroMemory(_read_buf, sizeof(_read_buf));
@@ -521,113 +514,115 @@ void VDAgent::event_dispatcher(DWORD timeout, DWORD wake_mask)
}
}
-DWORD VDAgent::get_buttons_change(DWORD last_buttons_state, DWORD new_buttons_state,
- DWORD mask, DWORD down_flag, DWORD up_flag)
+DWORD VDAgent::get_buttons_change(DWORD mask, DWORD down_flag, DWORD up_flag)
{
DWORD ret = 0;
- if (!(last_buttons_state & mask) && (new_buttons_state & mask)) {
+ if (!(_last_mouse.buttons & mask) && (_new_mouse.buttons & mask)) {
ret = down_flag;
- } else if ((last_buttons_state & mask) && !(new_buttons_state & mask)) {
+ } else if ((_last_mouse.buttons & mask) && !(_new_mouse.buttons & mask)) {
ret = up_flag;
}
return ret;
}
bool VDAgent::send_input()
-{
- bool ret = true;
- _desktop_layout->lock();
- if (_pending_input) {
- if (KillTimer(_hwnd, VD_TIMER_ID)) {
- _pending_input = false;
- } else {
- vd_printf("KillTimer failed: %lu", GetLastError());
- _running = false;
- _desktop_layout->unlock();
- return false;
- }
- }
- if (!SendInput(1, &_input, sizeof(INPUT))) {
- DWORD err = GetLastError();
- // Don't stop agent due to UIPI blocking, which is usually only for specific windows
- // of system security applications (anti-viruses etc.)
- if (err != ERROR_SUCCESS && err != ERROR_ACCESS_DENIED) {
- vd_printf("SendInput failed: %lu", err);
- ret = _running = false;
- }
- }
- _input_time = GetTickCount();
- _desktop_layout->unlock();
- return ret;
-}
-
-bool VDAgent::handle_mouse_event(VDAgentMouseState* state)
{
DisplayMode* mode = NULL;
DWORD mouse_move = 0;
DWORD buttons_change = 0;
DWORD mouse_wheel = 0;
bool ret = true;
+ INPUT input;
+
+ if (_pending_input) {
+ if (KillTimer(_hwnd, VD_TIMER_ID)) {
+ _pending_input = false;
+ } else {
+ vd_printf("KillTimer failed: %lu", GetLastError());
+ _running = false;
+ return false;
+ }
+ }
ASSERT(_desktop_layout);
_desktop_layout->lock();
- if (state->display_id < _desktop_layout->get_display_count()) {
- mode = _desktop_layout->get_display(state->display_id);
+ if (_new_mouse.display_id < _desktop_layout->get_display_count()) {
+ mode = _desktop_layout->get_display(_new_mouse.display_id);
}
if (!mode || !mode->get_attached()) {
_desktop_layout->unlock();
return true;
}
- ZeroMemory(&_input, sizeof(INPUT));
- _input.type = INPUT_MOUSE;
- if (state->x != _mouse_x || state->y != _mouse_y) {
+ ZeroMemory(&input, sizeof(INPUT));
+ input.type = INPUT_MOUSE;
+ if (_new_mouse.x != _last_mouse.x || _new_mouse.y != _last_mouse.y) {
DWORD w = _desktop_layout->get_total_width();
DWORD h = _desktop_layout->get_total_height();
w = (w > 1) ? w-1 : 1; /* coordinates are 0..w-1, protect w==0 */
h = (h > 1) ? h-1 : 1; /* coordinates are 0..h-1, protect h==0 */
- _mouse_x = state->x;
- _mouse_y = state->y;
mouse_move = MOUSEEVENTF_MOVE;
- _input.mi.dx = (mode->get_pos_x() + _mouse_x) * 0xffff / w;
- _input.mi.dy = (mode->get_pos_y() + _mouse_y) * 0xffff / h;
+ input.mi.dx = (mode->get_pos_x() + _new_mouse.x) * 0xffff / w;
+ input.mi.dy = (mode->get_pos_y() + _new_mouse.y) * 0xffff / h;
}
- if (state->buttons != _buttons_state) {
- buttons_change = get_buttons_change(_buttons_state, state->buttons, VD_AGENT_LBUTTON_MASK,
+ if (_new_mouse.buttons != _last_mouse.buttons) {
+ buttons_change = get_buttons_change(VD_AGENT_LBUTTON_MASK,
MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP) |
- get_buttons_change(_buttons_state, state->buttons, VD_AGENT_MBUTTON_MASK,
+ get_buttons_change(VD_AGENT_MBUTTON_MASK,
MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP) |
- get_buttons_change(_buttons_state, state->buttons, VD_AGENT_RBUTTON_MASK,
+ get_buttons_change(VD_AGENT_RBUTTON_MASK,
MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP);
- mouse_wheel = get_buttons_change(_buttons_state, state->buttons,
- VD_AGENT_UBUTTON_MASK | VD_AGENT_DBUTTON_MASK,
+ mouse_wheel = get_buttons_change(VD_AGENT_UBUTTON_MASK | VD_AGENT_DBUTTON_MASK,
MOUSEEVENTF_WHEEL, 0);
if (mouse_wheel) {
- if (state->buttons & VD_AGENT_UBUTTON_MASK) {
- _input.mi.mouseData = WHEEL_DELTA;
- } else if (state->buttons & VD_AGENT_DBUTTON_MASK) {
- _input.mi.mouseData = (DWORD)(-WHEEL_DELTA);
+ if (_new_mouse.buttons & VD_AGENT_UBUTTON_MASK) {
+ input.mi.mouseData = WHEEL_DELTA;
+ } else if (_new_mouse.buttons & VD_AGENT_DBUTTON_MASK) {
+ input.mi.mouseData = (DWORD)(-WHEEL_DELTA);
}
}
- _buttons_state = state->buttons;
}
- _input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK | mouse_move |
- mouse_wheel | buttons_change;
+ input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK | mouse_move |
+ mouse_wheel | buttons_change;
- if ((mouse_move && GetTickCount() - _input_time > VD_INPUT_INTERVAL_MS) || buttons_change ||
- mouse_wheel) {
- ret = send_input();
- } else if (!_pending_input) {
- if (SetTimer(_hwnd, VD_TIMER_ID, VD_INPUT_INTERVAL_MS, NULL)) {
+ if (!SendInput(1, &input, sizeof(INPUT))) {
+ DWORD err = GetLastError();
+ // Don't stop agent due to UIPI blocking, which is usually only for specific windows
+ // of system security applications (anti-viruses etc.)
+ if (err != ERROR_SUCCESS && err != ERROR_ACCESS_DENIED) {
+ vd_printf("SendInput failed: %lu", err);
+ ret = _running = false;
+ }
+ } else {
+ _last_mouse = _new_mouse;
+ }
+ _input_time = GetTickCount();
+ _desktop_layout->unlock();
+ return ret;
+}
+
+bool VDAgent::handle_mouse_event(VDAgentMouseState* state)
+{
+ _new_mouse = *state;
+ if (_new_mouse.buttons != _last_mouse.buttons) {
+ return send_input();
+ }
+
+ if (_new_mouse.x != _last_mouse.x || _new_mouse.y != _last_mouse.y) {
+ if (GetTickCount() - _input_time > VD_INPUT_INTERVAL_MS) {
+ return send_input();
+ }
+
+ if (!_pending_input) {
+ if (!SetTimer(_hwnd, VD_TIMER_ID, VD_INPUT_INTERVAL_MS, NULL)) {
+ vd_printf("SetTimer failed: %lu", GetLastError());
+ _running = false;
+ return false;
+ }
_pending_input = true;
- } else {
- vd_printf("SetTimer failed: %lu", GetLastError());
- _running = false;
- ret = false;
}
}
- _desktop_layout->unlock();
- return ret;
+ return true;
}
bool VDAgent::handle_mon_config(VDAgentMonitorsConfig* mon_config, uint32_t port)
--
2.17.1

View File

@ -0,0 +1,54 @@
From 531dd85f60e3de8fd6deddc820f3f6a92d83186c Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Mon, 28 May 2018 10:50:14 +0100
Subject: [PATCH 18/43] Reuse spice-protocol macros instead of defining new
ones for alignment
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
common/vdcommon.h | 8 --------
vdagent/vdagent.cpp | 6 ++++--
2 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/common/vdcommon.h b/common/vdcommon.h
index c1920e9..ac58efe 100644
--- a/common/vdcommon.h
+++ b/common/vdcommon.h
@@ -67,14 +67,6 @@ typedef Mutex mutex_t;
#define VD_AGENT_REGISTRY_KEY "SOFTWARE\\Red Hat\\Spice\\vdagent\\"
#define VD_AGENT_STOP_EVENT TEXT("Global\\vdagent_stop_event")
-#if defined __GNUC__
-#define ALIGN_GCC __attribute__ ((packed))
-#define ALIGN_VC
-#else
-#define ALIGN_GCC
-#define ALIGN_VC __declspec (align(1))
-#endif
-
/*
* Note: OLDMSVCRT, which is defined (in the Makefile) for mingw builds, and
* is not defined for Visual Studio builds.
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index ca1f8fa..e22687c 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -55,10 +55,12 @@ static const VDClipboardFormat clipboard_formats[] = {
#define clipboard_formats_count SPICE_N_ELEMENTS(clipboard_formats)
-typedef struct ALIGN_VC VDIChunk {
+#include <spice/start-packed.h>
+typedef struct SPICE_ATTR_PACKED VDIChunk {
VDIChunkHeader hdr;
uint8_t data[0];
-} ALIGN_GCC VDIChunk;
+} VDIChunk;
+#include <spice/end-packed.h>
#define VD_MESSAGE_HEADER_SIZE (sizeof(VDIChunk) + sizeof(VDAgentMessage))
#define VD_READ_BUF_SIZE (sizeof(VDIChunk) + VD_AGENT_MAX_DATA_SIZE)
--
2.17.1

View File

@ -0,0 +1,29 @@
From 14769f88c923945aba4aa257f9a8632a5b685210 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Tue, 29 May 2018 10:29:52 +0100
Subject: [PATCH 19/43] vdservice: Do not append line terminator to log
vd_printf already add a line terminator
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdservice/vdservice.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp
index ec6243e..7564fbb 100644
--- a/vdservice/vdservice.cpp
+++ b/vdservice/vdservice.cpp
@@ -337,7 +337,7 @@ VOID WINAPI VDService::main(DWORD argc, TCHAR* argv[])
s->_status_handle = RegisterServiceCtrlHandlerEx(VD_SERVICE_NAME, &VDService::control_handler,
s);
if (!s->_status_handle) {
- vd_printf("RegisterServiceCtrlHandler failed\n");
+ vd_printf("RegisterServiceCtrlHandler failed");
return;
}
--
2.17.1

View File

@ -0,0 +1,80 @@
From 13fb63e328f799a4e87dc62f81f3d58faab6987c Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Fri, 25 May 2018 21:50:57 +0100
Subject: [PATCH 20/43] Fix some minor buffer overflows reading registry
informations
Strings in the registry can be not NUL-terminated.
Current code to make sure they are NUL-terminated can add an extra
NUL character at the end of the buffer.
Also RegQueryValueEx returns the number of bytes read, not the number
of characters so the value must be fixed to avoid overflows.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdagent/display_setting.cpp | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/vdagent/display_setting.cpp b/vdagent/display_setting.cpp
index 25a248e..2b22144 100644
--- a/vdagent/display_setting.cpp
+++ b/vdagent/display_setting.cpp
@@ -285,7 +285,7 @@ bool DisplaySetting::disable_wallpaper()
bool DisplaySetting::reload_wallpaper(HKEY desktop_reg_key)
{
TCHAR wallpaper_path[MAX_PATH + 1];
- DWORD value_size = sizeof(wallpaper_path);
+ DWORD value_size = sizeof(wallpaper_path) - sizeof(wallpaper_path[0]);
DWORD value_type;
LONG status;
TCHAR cur_wallpaper[MAX_PATH + 1];
@@ -303,7 +303,8 @@ bool DisplaySetting::reload_wallpaper(HKEY desktop_reg_key)
return false;
}
- if (wallpaper_path[value_size - 1] != '\0') {
+ value_size /= sizeof(wallpaper_path[0]);
+ if (!value_size || wallpaper_path[value_size - 1] != '\0') {
wallpaper_path[value_size] = '\0';
}
@@ -339,7 +340,7 @@ bool DisplaySetting::disable_font_smoothing()
bool DisplaySetting::reload_font_smoothing(HKEY desktop_reg_key)
{
CHAR smooth_value[4];
- DWORD value_size = sizeof(smooth_value);
+ DWORD value_size = sizeof(smooth_value)-1;
DWORD value_type;
LONG status;
BOOL cur_font_smooth;
@@ -357,7 +358,7 @@ bool DisplaySetting::reload_font_smoothing(HKEY desktop_reg_key)
return false;
}
- if (smooth_value[value_size - 1] != '\0') {
+ if (!value_size || smooth_value[value_size - 1] != '\0') {
smooth_value[value_size] = '\0';
}
@@ -412,7 +413,7 @@ bool DisplaySetting::reload_win_animation(HKEY desktop_reg_key)
{
HKEY win_metrics_hkey;
CHAR win_anim_value[4];
- DWORD value_size = sizeof(win_anim_value);
+ DWORD value_size = sizeof(win_anim_value)-1;
DWORD value_type;
LONG status;
ANIMATIONINFO active_win_animation;
@@ -441,7 +442,7 @@ bool DisplaySetting::reload_win_animation(HKEY desktop_reg_key)
return false;
}
- if (win_anim_value[value_size - 1] != '\0') {
+ if (!value_size || win_anim_value[value_size - 1] != '\0') {
win_anim_value[value_size] = '\0';
}
--
2.17.1

View File

@ -0,0 +1,62 @@
From ae94c50ee912ab8925cda61449235a8027d49c77 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Wed, 30 May 2018 14:21:00 +0100
Subject: [PATCH 21/43] Use enumeration types
No reasons to allow any possible number.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdagent/vdagent.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index e22687c..551f326 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -100,10 +100,10 @@ private:
void dispatch_message(VDAgentMessage* msg, uint32_t port);
uint32_t get_clipboard_format(uint32_t type) const;
uint32_t get_clipboard_type(uint32_t format) const;
- enum { owner_none, owner_guest, owner_client };
- void set_clipboard_owner(int new_owner);
- enum { CONTROL_STOP, CONTROL_RESET, CONTROL_DESKTOP_SWITCH, CONTROL_LOGON, CONTROL_CLIPBOARD };
- void set_control_event(int control_command);
+ enum clipboard_owner_t { owner_none, owner_guest, owner_client };
+ void set_clipboard_owner(clipboard_owner_t new_owner);
+ enum control_command_t { CONTROL_STOP, CONTROL_RESET, CONTROL_DESKTOP_SWITCH, CONTROL_LOGON, CONTROL_CLIPBOARD };
+ void set_control_event(control_command_t control_command);
void handle_control_event();
VDIChunk* new_chunk(DWORD bytes = 0);
void enqueue_chunk(VDIChunk* msg);
@@ -346,7 +346,7 @@ void VDAgent::cleanup()
delete _desktop_layout;
}
-void VDAgent::set_control_event(int control_command)
+void VDAgent::set_control_event(control_command_t control_command)
{
MutexLocker lock(_control_mutex);
_control_queue.push(control_command);
@@ -1207,7 +1207,7 @@ uint32_t VDAgent::get_clipboard_type(uint32_t format) const
return 0;
}
-void VDAgent::set_clipboard_owner(int new_owner)
+void VDAgent::set_clipboard_owner(clipboard_owner_t new_owner)
{
// FIXME: Clear requests, clipboard data and state
if (new_owner == owner_none) {
@@ -1455,7 +1455,7 @@ LRESULT CALLBACK VDAgent::wnd_proc(HWND hwnd, UINT message, WPARAM wparam, LPARA
case WM_CLIPBOARDUPDATE:
case WM_DRAWCLIPBOARD:
if (a->_hwnd != GetClipboardOwner()) {
- a->set_clipboard_owner(a->owner_none);
+ a->set_clipboard_owner(owner_none);
a->on_clipboard_grab();
}
if (a->_hwnd_next_viewer) {
--
2.17.1

View File

@ -0,0 +1,80 @@
From 8251fa25ac0c0a9a8055a6eb7299d7d379341b94 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Wed, 30 May 2018 14:32:10 +0100
Subject: [PATCH 22/43] Minimal message size check
Avoid some possible integer overflows.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
---
vdagent/vdagent.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 551f326..1e8f27c 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -1231,6 +1231,60 @@ void VDAgent::dispatch_message(VDAgentMessage* msg, uint32_t port)
{
bool res = true;
+ // check minimal message size
+ int min_size = -1;
+ switch (msg->type) {
+ case VD_AGENT_MOUSE_STATE:
+ min_size = sizeof(VDAgentMouseState);
+ break;
+ case VD_AGENT_MONITORS_CONFIG:
+ min_size = sizeof(VDAgentMonitorsConfig);
+ break;
+ case VD_AGENT_CLIPBOARD:
+ min_size = sizeof(VDAgentClipboard);
+ break;
+ case VD_AGENT_CLIPBOARD_GRAB:
+ min_size = sizeof(VDAgentClipboardGrab);
+ break;
+ case VD_AGENT_CLIPBOARD_REQUEST:
+ min_size = sizeof(VDAgentClipboardRequest);
+ break;
+ case VD_AGENT_CLIPBOARD_RELEASE:
+ min_size = sizeof(VDAgentClipboardRelease);
+ break;
+ case VD_AGENT_DISPLAY_CONFIG:
+ min_size = sizeof(VDAgentDisplayConfig);
+ break;
+ case VD_AGENT_ANNOUNCE_CAPABILITIES:
+ min_size = sizeof(VDAgentAnnounceCapabilities);
+ break;
+ case VD_AGENT_FILE_XFER_START:
+ min_size = sizeof(VDAgentFileXferStatusMessage);
+ break;
+ case VD_AGENT_FILE_XFER_STATUS:
+ min_size = sizeof(VDAgentFileXferStatusMessage);
+ break;
+ case VD_AGENT_FILE_XFER_DATA:
+ min_size = sizeof(VDAgentFileXferDataMessage);
+ break;
+ case VD_AGENT_CLIENT_DISCONNECTED:
+ min_size = 0;
+ break;
+ case VD_AGENT_MAX_CLIPBOARD:
+ min_size = sizeof(VDAgentMaxClipboard);
+ break;
+ }
+ if (min_size < 0) {
+ vd_printf("Unsupported message type %u size %u", msg->type, msg->size);
+ _running = false;
+ return;
+ }
+ if (msg->size < (unsigned) min_size) {
+ vd_printf("Unexpected msg size %u for message type %u", msg->size, msg->type);
+ _running = false;
+ return;
+ }
+
switch (msg->type) {
case VD_AGENT_MOUSE_STATE:
res = handle_mouse_event((VDAgentMouseState*)msg->data);
--
2.17.1

View File

@ -0,0 +1,27 @@
From bc3384f359765fe84aa8e53e0330886d5b6e42f3 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sat, 30 Jun 2018 06:02:27 +0100
Subject: [PATCH 23/43] Use proper type for _clipboard_owner
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe de Dinechin <dinechin@redhat.com>
---
vdagent/vdagent.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 1e8f27c..78c42d1 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -129,7 +129,7 @@ private:
PCLIPBOARD_OP _add_clipboard_listener;
PCLIPBOARD_OP _remove_clipboard_listener;
int _system_version;
- int _clipboard_owner;
+ clipboard_owner_t _clipboard_owner;
DWORD _clipboard_tick;
VDAgentMouseState _new_mouse = {};
VDAgentMouseState _last_mouse = {};
--
2.17.1

View File

@ -0,0 +1,82 @@
From 873464cecceb1895a620ca3606004f7c856cfd79 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Fri, 29 Jun 2018 07:50:44 +0100
Subject: [PATCH 24/43] Reduce indentation returning earlier
Also add some comments.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdagent/vdagent.cpp | 45 ++++++++++++++++++++++++++-------------------
2 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 78c42d1..cf492cc 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -1393,6 +1393,7 @@ void VDAgent::handle_chunk(VDIChunk* chunk)
{
//FIXME: currently assumes that multi-part msg arrives only from client port
if (_in_msg_pos == 0 || chunk->hdr.port == VDP_SERVER_PORT) {
+ // ignore the chunk if too short
if (chunk->hdr.size < sizeof(VDAgentMessage)) {
return;
}
@@ -1404,28 +1405,34 @@ void VDAgent::handle_chunk(VDIChunk* chunk)
}
uint32_t msg_size = sizeof(VDAgentMessage) + msg->size;
if (chunk->hdr.size == msg_size) {
+ // we got an entire message, handle it
dispatch_message(msg, chunk->hdr.port);
+ return;
+ }
+
+ // got just the start, start to collapse all chunks into a
+ // single buffer
+ ASSERT(chunk->hdr.size < msg_size);
+ _in_msg = (VDAgentMessage*)new uint8_t[msg_size];
+ memcpy(_in_msg, chunk->data, chunk->hdr.size);
+ _in_msg_pos = chunk->hdr.size;
+ return;
+ }
+
+ // the previous chunk was a partial message, so append this chunk to the previous chunk
+ memcpy((uint8_t*)_in_msg + _in_msg_pos, chunk->data, chunk->hdr.size);
+ _in_msg_pos += chunk->hdr.size;
+ // update clipboard tick on each clipboard chunk for timeout setting
+ if (_in_msg->type == VD_AGENT_CLIPBOARD && _clipboard_tick) {
+ _clipboard_tick = GetTickCount();
+ }
+ if (_in_msg_pos == sizeof(VDAgentMessage) + _in_msg->size) {
+ if (_in_msg->type == VD_AGENT_CLIPBOARD && !_clipboard_tick) {
+ vd_printf("Clipboard received but dropped due to timeout");
} else {
- ASSERT(chunk->hdr.size < msg_size);
- _in_msg = (VDAgentMessage*)new uint8_t[msg_size];
- memcpy(_in_msg, chunk->data, chunk->hdr.size);
- _in_msg_pos = chunk->hdr.size;
- }
- } else {
- memcpy((uint8_t*)_in_msg + _in_msg_pos, chunk->data, chunk->hdr.size);
- _in_msg_pos += chunk->hdr.size;
- // update clipboard tick on each clipboard chunk for timeout setting
- if (_in_msg->type == VD_AGENT_CLIPBOARD && _clipboard_tick) {
- _clipboard_tick = GetTickCount();
- }
- if (_in_msg_pos == sizeof(VDAgentMessage) + _in_msg->size) {
- if (_in_msg->type == VD_AGENT_CLIPBOARD && !_clipboard_tick) {
- vd_printf("Clipboard received but dropped due to timeout");
- } else {
- dispatch_message(_in_msg, 0);
- }
- cleanup_in_msg();
+ dispatch_message(_in_msg, 0);
}
+ cleanup_in_msg();
}
}
--
2.17.1

View File

@ -0,0 +1,43 @@
From 3e8cab6da1a1572db9a91ee21687ab5dca7671b1 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sat, 26 May 2018 07:53:51 +0100
Subject: [PATCH 25/43] Minor overflow checks improvements
Although source of these data should be safe, improve data checks
to avoid some overflows and make the code more robust.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdagent/vdagent.cpp | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index cf492cc..9fbff3d 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -1368,7 +1368,7 @@ VOID VDAgent::read_completion(DWORD err, DWORD bytes, LPOVERLAPPED overlapped)
count = sizeof(VDIChunk) - a->_read_pos;
} else if (a->_read_pos == sizeof(VDIChunk)) {
count = chunk->hdr.size;
- if (a->_read_pos + count > sizeof(a->_read_buf)) {
+ if (count > sizeof(a->_read_buf) - a->_read_pos) {
vd_printf("chunk is too large, size %u port %u", chunk->hdr.size, chunk->hdr.port);
a->_running = false;
return;
@@ -1420,6 +1420,12 @@ void VDAgent::handle_chunk(VDIChunk* chunk)
}
// the previous chunk was a partial message, so append this chunk to the previous chunk
+ if (chunk->hdr.size > sizeof(VDAgentMessage) + _in_msg->size - _in_msg_pos) {
+ vd_printf("Invalid VDAgentMessage message");
+ _running = false;
+ return;
+ }
+
memcpy((uint8_t*)_in_msg + _in_msg_pos, chunk->data, chunk->hdr.size);
_in_msg_pos += chunk->hdr.size;
// update clipboard tick on each clipboard chunk for timeout setting
--
2.17.1

View File

@ -0,0 +1,33 @@
From 18cbe9f306f6dcfeeb4952e278dd88e2520d87f6 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Fri, 29 Jun 2018 08:02:02 +0100
Subject: [PATCH 26/43] Replace an assert with proper handling code
Make sure the condition is handled properly.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdagent/vdagent.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 9fbff3d..7b3720d 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -1412,7 +1412,11 @@ void VDAgent::handle_chunk(VDIChunk* chunk)
// got just the start, start to collapse all chunks into a
// single buffer
- ASSERT(chunk->hdr.size < msg_size);
+ if (chunk->hdr.size >= msg_size) {
+ vd_printf("Invalid VDAgentMessage message");
+ _running = false;
+ return;
+ }
_in_msg = (VDAgentMessage*)new uint8_t[msg_size];
memcpy(_in_msg, chunk->data, chunk->hdr.size);
_in_msg_pos = chunk->hdr.size;
--
2.17.1

View File

@ -0,0 +1,55 @@
From 0984079e08c252b0baf5ccab50f8196edd714904 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Fri, 29 Jun 2018 19:33:25 +0100
Subject: [PATCH 27/43] Use std::unique_ptr for _desktop_layout
Make automatic the release of this pointer.
Also avoids having a leak if VDAgent::run is called twice.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdagent/vdagent.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 7b3720d..1a68e0c 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -142,7 +142,7 @@ private:
bool _running;
bool _session_is_locked;
bool _desktop_switch;
- DesktopLayout* _desktop_layout;
+ std::unique_ptr<DesktopLayout> _desktop_layout;
bool _updating_display_config;
DisplaySetting _display_setting;
FileXfer _file_xfer;
@@ -198,7 +198,6 @@ VDAgent::VDAgent()
, _running (false)
, _session_is_locked (false)
, _desktop_switch (false)
- , _desktop_layout (NULL)
, _display_setting (VD_AGENT_REGISTRY_KEY)
, _vio_serial (NULL)
, _read_pos (0)
@@ -301,7 +300,7 @@ bool VDAgent::run()
cleanup();
return false;
}
- _desktop_layout = new DesktopLayout();
+ _desktop_layout.reset(new DesktopLayout());
if (_desktop_layout->get_display_count() == 0) {
vd_printf("No QXL devices!");
}
@@ -343,7 +342,6 @@ void VDAgent::cleanup()
CloseHandle(_stop_event);
CloseHandle(_control_event);
CloseHandle(_vio_serial);
- delete _desktop_layout;
}
void VDAgent::set_control_event(control_command_t control_command)
--
2.17.1

View File

@ -0,0 +1,103 @@
From 97ef38dc6d69a14365b1245e9a6406105a033a8a Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Mon, 28 May 2018 16:04:34 +0100
Subject: [PATCH 28/43] Use always TCHAR to read string from registry
This is a preparation patch in order to factor out code to read
a string from registry.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdagent/display_setting.cpp | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/vdagent/display_setting.cpp b/vdagent/display_setting.cpp
index 2b22144..cef3401 100644
--- a/vdagent/display_setting.cpp
+++ b/vdagent/display_setting.cpp
@@ -339,15 +339,15 @@ bool DisplaySetting::disable_font_smoothing()
bool DisplaySetting::reload_font_smoothing(HKEY desktop_reg_key)
{
- CHAR smooth_value[4];
- DWORD value_size = sizeof(smooth_value)-1;
+ TCHAR smooth_value[4];
+ DWORD value_size = sizeof(smooth_value)-sizeof(smooth_value[0]);
DWORD value_type;
LONG status;
BOOL cur_font_smooth;
vd_printf("");
- status = RegQueryValueExA(desktop_reg_key, "FontSmoothing", NULL,
- &value_type, (LPBYTE)smooth_value, &value_size);
+ status = RegQueryValueEx(desktop_reg_key, TEXT("FontSmoothing"), NULL,
+ &value_type, (LPBYTE)smooth_value, &value_size);
if (status != ERROR_SUCCESS) {
vd_printf("RegQueryValueEx(FontSmoothing) : fail %ld", status);
return false;
@@ -358,15 +358,16 @@ bool DisplaySetting::reload_font_smoothing(HKEY desktop_reg_key)
return false;
}
+ value_size /= sizeof(smooth_value[0]);
if (!value_size || smooth_value[value_size - 1] != '\0') {
smooth_value[value_size] = '\0';
}
- if (strcmp(smooth_value, "0") == 0) {
+ if (_tcscmp(smooth_value, TEXT("0")) == 0) {
vd_printf("font smoothing is disabled in registry. do nothing");
return true;
- } else if (strcmp(smooth_value, "2") != 0) {
- vd_printf("unexpectd font smoothing value %s", smooth_value);
+ } else if (_tcscmp(smooth_value, TEXT("2")) != 0) {
+ vd_printf("unexpectd font smoothing value %ls", smooth_value);
return false;
}
@@ -412,8 +413,8 @@ bool DisplaySetting::disable_animation()
bool DisplaySetting::reload_win_animation(HKEY desktop_reg_key)
{
HKEY win_metrics_hkey;
- CHAR win_anim_value[4];
- DWORD value_size = sizeof(win_anim_value)-1;
+ TCHAR win_anim_value[4];
+ DWORD value_size = sizeof(win_anim_value)-sizeof(win_anim_value[0]);
DWORD value_type;
LONG status;
ANIMATIONINFO active_win_animation;
@@ -427,8 +428,8 @@ bool DisplaySetting::reload_win_animation(HKEY desktop_reg_key)
return false;
}
- status = RegQueryValueExA(win_metrics_hkey, "MinAnimate", NULL,
- &value_type, (LPBYTE)win_anim_value, &value_size);
+ status = RegQueryValueEx(win_metrics_hkey, TEXT("MinAnimate"), NULL,
+ &value_type, (LPBYTE)win_anim_value, &value_size);
if (status != ERROR_SUCCESS) {
vd_printf("RegQueryValueEx(MinAnimate) : fail %ld", status);
RegCloseKey(win_metrics_hkey);
@@ -442,15 +443,16 @@ bool DisplaySetting::reload_win_animation(HKEY desktop_reg_key)
return false;
}
+ value_size /= sizeof(win_anim_value[0]);
if (!value_size || win_anim_value[value_size - 1] != '\0') {
win_anim_value[value_size] = '\0';
}
- if (!strcmp(win_anim_value, "0")) {
+ if (!_tcscmp(win_anim_value, TEXT("0"))) {
vd_printf("window animation is disabled in registry. do nothing");
return true;
- } else if (strcmp(win_anim_value, "1") != 0) {
- vd_printf("unexpectd window animation value %s", win_anim_value);
+ } else if (_tcscmp(win_anim_value, TEXT("1")) != 0) {
+ vd_printf("unexpectd window animation value %ls", win_anim_value);
return false;
}
active_win_animation.cbSize = sizeof(ANIMATIONINFO);
--
2.17.1

View File

@ -0,0 +1,159 @@
From 1a2e2d1411c131c63703be04a82522462c89918a Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sat, 26 May 2018 07:55:12 +0100
Subject: [PATCH 29/43] Factor out an utility function to read strings from
registry
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdagent/display_setting.cpp | 91 +++++++++++++++++--------------------
1 file changed, 41 insertions(+), 50 deletions(-)
diff --git a/vdagent/display_setting.cpp b/vdagent/display_setting.cpp
index cef3401..78c67d6 100644
--- a/vdagent/display_setting.cpp
+++ b/vdagent/display_setting.cpp
@@ -282,32 +282,54 @@ bool DisplaySetting::disable_wallpaper()
}
}
+#if defined(UNICODE) || defined(_UNICODE)
+#define PRIsTSTR "ls"
+#else
+#define PRIsTSTR "s"
+#endif
+
+static bool RegReadString(HKEY key, const TCHAR *name, TCHAR *buffer, size_t buffer_len)
+{
+ DWORD value_size = (buffer_len - 1) * sizeof(buffer[0]);
+ DWORD value_type;
+ LONG status;
+
+ status = RegQueryValueEx(key, name, NULL, &value_type, (LPBYTE)buffer, &value_size);
+ if (status != ERROR_SUCCESS) {
+ vd_printf("RegQueryValueEx(%" PRIsTSTR ") : fail %ld", name, status);
+ return false;
+ }
+
+ if (value_type != REG_SZ) {
+ vd_printf("bad %" PRIsTSTR " value type %lu (expected REG_SZ)", name, value_type);
+ return false;
+ }
+
+ // assure NUL-terminated
+ value_size /= sizeof(buffer[0]);
+ if (!value_size || buffer[value_size - 1] != '\0') {
+ buffer[value_size] = '\0';
+ }
+
+ return true;
+}
+
+template <size_t N>
+static inline bool RegReadString(HKEY key, const TCHAR *name, TCHAR (&buffer)[N])
+{
+ return RegReadString(key, name, buffer, N);
+}
+
bool DisplaySetting::reload_wallpaper(HKEY desktop_reg_key)
{
TCHAR wallpaper_path[MAX_PATH + 1];
- DWORD value_size = sizeof(wallpaper_path) - sizeof(wallpaper_path[0]);
- DWORD value_type;
- LONG status;
TCHAR cur_wallpaper[MAX_PATH + 1];
vd_printf("");
- status = RegQueryValueEx(desktop_reg_key, TEXT("Wallpaper"), NULL,
- &value_type, (LPBYTE)wallpaper_path, &value_size);
- if (status != ERROR_SUCCESS) {
- vd_printf("RegQueryValueEx(Wallpaper) : fail %ld", status);
+ if (!RegReadString(desktop_reg_key, TEXT("Wallpaper"), wallpaper_path)) {
return false;
}
- if (value_type != REG_SZ) {
- vd_printf("bad wallpaper value type %lu (expected REG_SZ)", value_type);
- return false;
- }
-
- value_size /= sizeof(wallpaper_path[0]);
- if (!value_size || wallpaper_path[value_size - 1] != '\0') {
- wallpaper_path[value_size] = '\0';
- }
-
if (SystemParametersInfo(SPI_GETDESKWALLPAPER, SPICE_N_ELEMENTS(cur_wallpaper), cur_wallpaper, 0)) {
if (_tcscmp(cur_wallpaper, TEXT("")) != 0) {
vd_printf("wallpaper wasn't disabled");
@@ -340,29 +362,13 @@ bool DisplaySetting::disable_font_smoothing()
bool DisplaySetting::reload_font_smoothing(HKEY desktop_reg_key)
{
TCHAR smooth_value[4];
- DWORD value_size = sizeof(smooth_value)-sizeof(smooth_value[0]);
- DWORD value_type;
- LONG status;
BOOL cur_font_smooth;
vd_printf("");
- status = RegQueryValueEx(desktop_reg_key, TEXT("FontSmoothing"), NULL,
- &value_type, (LPBYTE)smooth_value, &value_size);
- if (status != ERROR_SUCCESS) {
- vd_printf("RegQueryValueEx(FontSmoothing) : fail %ld", status);
+ if (!RegReadString(desktop_reg_key, TEXT("FontSmoothing"), smooth_value)) {
return false;
}
- if (value_type != REG_SZ) {
- vd_printf("bad font smoothing value type %lu (expected REG_SZ)", value_type);
- return false;
- }
-
- value_size /= sizeof(smooth_value[0]);
- if (!value_size || smooth_value[value_size - 1] != '\0') {
- smooth_value[value_size] = '\0';
- }
-
if (_tcscmp(smooth_value, TEXT("0")) == 0) {
vd_printf("font smoothing is disabled in registry. do nothing");
return true;
@@ -414,8 +420,6 @@ bool DisplaySetting::reload_win_animation(HKEY desktop_reg_key)
{
HKEY win_metrics_hkey;
TCHAR win_anim_value[4];
- DWORD value_size = sizeof(win_anim_value)-sizeof(win_anim_value[0]);
- DWORD value_type;
LONG status;
ANIMATIONINFO active_win_animation;
@@ -428,26 +432,13 @@ bool DisplaySetting::reload_win_animation(HKEY desktop_reg_key)
return false;
}
- status = RegQueryValueEx(win_metrics_hkey, TEXT("MinAnimate"), NULL,
- &value_type, (LPBYTE)win_anim_value, &value_size);
- if (status != ERROR_SUCCESS) {
- vd_printf("RegQueryValueEx(MinAnimate) : fail %ld", status);
+ if (!RegReadString(win_metrics_hkey, TEXT("MinAnimate"), win_anim_value)) {
RegCloseKey(win_metrics_hkey);
return false;
}
RegCloseKey(win_metrics_hkey);
- if (value_type != REG_SZ) {
- vd_printf("bad MinAnimate value type %lu (expected REG_SZ)", value_type);
- return false;
- }
-
- value_size /= sizeof(win_anim_value[0]);
- if (!value_size || win_anim_value[value_size - 1] != '\0') {
- win_anim_value[value_size] = '\0';
- }
-
if (!_tcscmp(win_anim_value, TEXT("0"))) {
vd_printf("window animation is disabled in registry. do nothing");
return true;
--
2.17.1

View File

@ -0,0 +1,67 @@
From 7b368a134fac63f4e603969694b83c916df04e17 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sat, 26 May 2018 07:55:12 +0100
Subject: [PATCH 30/43] Allow one more character reading strings from registry
The strings in the registry are usually NUL-terminated but this
is not a requirement.
Handle the case when the string, considering the terminator, fit
into the reading buffer. In this case accept the string. In the
case the string fit into the buffer but is not terminated
returns ERROR_MORE_DATA (the error that would be returned if the
string didn't fit in the buffer as there is no place to add the
terminator).
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdagent/display_setting.cpp | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/vdagent/display_setting.cpp b/vdagent/display_setting.cpp
index 78c67d6..b6711d7 100644
--- a/vdagent/display_setting.cpp
+++ b/vdagent/display_setting.cpp
@@ -290,11 +290,25 @@ bool DisplaySetting::disable_wallpaper()
static bool RegReadString(HKEY key, const TCHAR *name, TCHAR *buffer, size_t buffer_len)
{
- DWORD value_size = (buffer_len - 1) * sizeof(buffer[0]);
+ DWORD value_size = buffer_len * sizeof(buffer[0]);
DWORD value_type;
LONG status;
status = RegQueryValueEx(key, name, NULL, &value_type, (LPBYTE)buffer, &value_size);
+ if (status == ERROR_SUCCESS && value_type == REG_SZ) {
+ // ensure NUL-terminated
+ value_size /= sizeof(buffer[0]);
+ if (value_size == buffer_len) {
+ // full buffer but not terminated?
+ if (buffer[value_size-1] != '\0') {
+ status = ERROR_MORE_DATA;
+ }
+ } else {
+ // append a NUL. If there's already a NUL character this
+ // new one will be ignored
+ buffer[value_size] = '\0';
+ }
+ }
if (status != ERROR_SUCCESS) {
vd_printf("RegQueryValueEx(%" PRIsTSTR ") : fail %ld", name, status);
return false;
@@ -305,12 +319,6 @@ static bool RegReadString(HKEY key, const TCHAR *name, TCHAR *buffer, size_t buf
return false;
}
- // assure NUL-terminated
- value_size /= sizeof(buffer[0]);
- if (!value_size || buffer[value_size - 1] != '\0') {
- buffer[value_size] = '\0';
- }
-
return true;
}
--
2.17.1

View File

@ -0,0 +1,60 @@
From 6a0683707f3fcebcca3d3e5aced46ec3024f3784 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sat, 30 Jun 2018 05:31:13 +0100
Subject: [PATCH 31/43] Allocate _control_event and _stop_event just once
Handle _control_event and _stop_event destruction in destructor.
Allows to call VDAgent::run multiple time if needed.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdagent/vdagent.cpp | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 1a68e0c..64055c4 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -224,6 +224,8 @@ VDAgent::VDAgent()
VDAgent::~VDAgent()
{
+ CloseHandle(_stop_event);
+ CloseHandle(_control_event);
delete _log;
}
@@ -285,13 +287,18 @@ bool VDAgent::run()
return false;
}
}
- _control_event = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (!_control_event)
+ _control_event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!_control_event) {
vd_printf("CreateEvent() failed: %lu", GetLastError());
cleanup();
return false;
}
- _stop_event = OpenEvent(SYNCHRONIZE, FALSE, VD_AGENT_STOP_EVENT);
+ ResetEvent(_control_event);
+
+ if (!_stop_event)
+ _stop_event = OpenEvent(SYNCHRONIZE, FALSE, VD_AGENT_STOP_EVENT);
+
memset(&wcls, 0, sizeof(wcls));
wcls.lpfnWndProc = &VDAgent::wnd_proc;
wcls.lpszClassName = VD_AGENT_WINCLASS_NAME;
@@ -339,8 +346,6 @@ bool VDAgent::run()
void VDAgent::cleanup()
{
FreeLibrary(_user_lib);
- CloseHandle(_stop_event);
- CloseHandle(_control_event);
CloseHandle(_vio_serial);
}
--
2.17.1

View File

@ -0,0 +1,37 @@
From c0a6e42e809a5d177c4863ae24e43cf523ab0b4b Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sat, 30 Jun 2018 09:05:08 +0100
Subject: [PATCH 32/43] Avoid declaring event_thread_id
As the value is never used we can pass NULL in CreateThread.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdagent/vdagent.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 64055c4..fc8e727 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -255,7 +255,6 @@ DWORD WINAPI VDAgent::event_thread_proc(LPVOID param)
bool VDAgent::run()
{
DWORD session_id;
- DWORD event_thread_id;
HANDLE event_thread;
WNDCLASS wcls;
@@ -322,7 +321,7 @@ bool VDAgent::run()
return false;
}
_running = true;
- event_thread = CreateThread(NULL, 0, event_thread_proc, this, 0, &event_thread_id);
+ event_thread = CreateThread(NULL, 0, event_thread_proc, this, 0, NULL);
if (!event_thread) {
vd_printf("CreateThread() failed: %lu", GetLastError());
cleanup();
--
2.17.1

View File

@ -0,0 +1,64 @@
From e9421d09b82c7c1ff284175d335b23303ac80e69 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sat, 30 Jun 2018 09:05:40 +0100
Subject: [PATCH 33/43] Avoid declaring _system_version member
The check can be done a single time, no reason to cache
supported_system_version() value.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdagent/vdagent.cpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index fc8e727..95783c1 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -128,7 +128,6 @@ private:
HMODULE _user_lib;
PCLIPBOARD_OP _add_clipboard_listener;
PCLIPBOARD_OP _remove_clipboard_listener;
- int _system_version;
clipboard_owner_t _clipboard_owner;
DWORD _clipboard_tick;
VDAgentMouseState _new_mouse = {};
@@ -210,7 +209,6 @@ VDAgent::VDAgent()
TCHAR log_path[MAX_PATH];
TCHAR temp_path[MAX_PATH];
- _system_version = supported_system_version();
if (GetTempPath(MAX_PATH, temp_path)) {
swprintf_s(log_path, MAX_PATH, VD_AGENT_LOG_PATH, temp_path);
_log = VDLog::get(log_path);
@@ -270,7 +268,7 @@ bool VDAgent::run()
if (!SetProcessShutdownParameters(0x100, 0)) {
vd_printf("SetProcessShutdownParameters failed %lu", GetLastError());
}
- if (_system_version == SYS_VER_WIN_7_CLASS) {
+ if (supported_system_version() == SYS_VER_WIN_7_CLASS) {
_user_lib = LoadLibrary(L"User32.dll");
if (!_user_lib) {
vd_printf("LoadLibrary failed %lu", GetLastError());
@@ -447,7 +445,7 @@ void VDAgent::input_desktop_message_loop()
if (!WTSRegisterSessionNotification(_hwnd, NOTIFY_FOR_ALL_SESSIONS)) {
vd_printf("WTSRegisterSessionNotification() failed: %lu", GetLastError());
}
- if (_system_version == SYS_VER_WIN_7_CLASS) {
+ if (_add_clipboard_listener) {
_add_clipboard_listener(_hwnd);
} else {
_hwnd_next_viewer = SetClipboardViewer(_hwnd);
@@ -460,7 +458,7 @@ void VDAgent::input_desktop_message_loop()
KillTimer(_hwnd, VD_TIMER_ID);
_pending_input = false;
}
- if (_system_version == SYS_VER_WIN_7_CLASS) {
+ if (_remove_clipboard_listener) {
_remove_clipboard_listener(_hwnd);
} else {
ChangeClipboardChain(_hwnd, _hwnd_next_viewer);
--
2.17.1

View File

@ -0,0 +1,61 @@
From 55290d17666d2237896ba0c8cd9c028ddc29f5c9 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sat, 30 Jun 2018 09:14:08 +0100
Subject: [PATCH 34/43] Avoids to call supported_system_version()
The only reason we call this function is to check if the
system should support some APIs.
Instead just check directly if these APIs are supported
calling GetProcAddress directly.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
vdagent/vdagent.cpp | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 95783c1..423c3ee 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -268,22 +268,22 @@ bool VDAgent::run()
if (!SetProcessShutdownParameters(0x100, 0)) {
vd_printf("SetProcessShutdownParameters failed %lu", GetLastError());
}
- if (supported_system_version() == SYS_VER_WIN_7_CLASS) {
- _user_lib = LoadLibrary(L"User32.dll");
- if (!_user_lib) {
- vd_printf("LoadLibrary failed %lu", GetLastError());
- return false;
- }
- _add_clipboard_listener =
- (PCLIPBOARD_OP)GetProcAddress(_user_lib, "AddClipboardFormatListener");
- _remove_clipboard_listener =
- (PCLIPBOARD_OP)GetProcAddress(_user_lib, "RemoveClipboardFormatListener");
- if (!_add_clipboard_listener || !_remove_clipboard_listener) {
- vd_printf("GetProcAddress failed %lu", GetLastError());
- cleanup();
- return false;
- }
+
+ _user_lib = LoadLibrary(L"User32.dll");
+ if (!_user_lib) {
+ vd_printf("LoadLibrary failed %lu", GetLastError());
+ return false;
}
+ _add_clipboard_listener =
+ (PCLIPBOARD_OP)GetProcAddress(_user_lib, "AddClipboardFormatListener");
+ _remove_clipboard_listener =
+ (PCLIPBOARD_OP)GetProcAddress(_user_lib, "RemoveClipboardFormatListener");
+ // do not use FormatListener APIs if not available
+ if (!_add_clipboard_listener || !_remove_clipboard_listener) {
+ _add_clipboard_listener = nullptr;
+ _remove_clipboard_listener = nullptr;
+ }
+
if (!_control_event)
_control_event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!_control_event) {
--
2.17.1

View File

@ -0,0 +1,62 @@
From c4b8c5349e3870cde0101e890e6aeb7f78bc89e2 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sun, 1 Jul 2018 06:50:58 +0100
Subject: [PATCH 35/43] vdlog: Remove the lookup table for log types
As log type is passed as constant in some macros and the lockup
is basically using this name without the prefix pass to the macro
the name without the prefix.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
common/vdlog.h | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/common/vdlog.h b/common/vdlog.h
index 9f08fc4..d017ac3 100644
--- a/common/vdlog.h
+++ b/common/vdlog.h
@@ -59,8 +59,7 @@ static const VDLogLevel log_level = LOG_INFO;
#endif
#define LOG(type, format, ...) do { \
- if (type >= log_level && type <= LOG_FATAL) { \
- const char *type_as_char[] = { "DEBUG", "INFO", "WARN", "ERROR", "FATAL" }; \
+ if (LOG_ ## type >= log_level && LOG_ ## type <= LOG_FATAL) { \
struct _timeb now; \
struct tm today; \
char datetime_str[20]; \
@@ -68,23 +67,23 @@ static const VDLogLevel log_level = LOG_INFO;
localtime_s(&today, &now.time); \
strftime(datetime_str, 20, "%Y-%m-%d %H:%M:%S", &today); \
VDLog::printf("%lu::%s::%s,%.3d::%s::" format "\n", \
- GetCurrentThreadId(), type_as_char[type], \
+ GetCurrentThreadId(), #type, \
datetime_str, now.millitm, \
__FUNCTION__, ## __VA_ARGS__); \
} \
} while(0)
-#define vd_printf(format, ...) LOG(LOG_INFO, format, ## __VA_ARGS__)
-#define LOG_INFO(format, ...) LOG(LOG_INFO, format, ## __VA_ARGS__)
-#define LOG_WARN(format, ...) LOG(LOG_WARN, format, ## __VA_ARGS__)
-#define LOG_ERROR(format, ...) LOG(LOG_ERROR, format, ## __VA_ARGS__)
+#define vd_printf(format, ...) LOG(INFO, format, ## __VA_ARGS__)
+#define LOG_INFO(format, ...) LOG(INFO, format, ## __VA_ARGS__)
+#define LOG_WARN(format, ...) LOG(WARN, format, ## __VA_ARGS__)
+#define LOG_ERROR(format, ...) LOG(ERROR, format, ## __VA_ARGS__)
#define DBGLEVEL 1000
#define DBG(level, format, ...) do { \
if (level <= DBGLEVEL) { \
- LOG(LOG_DEBUG, format, ## __VA_ARGS__); \
+ LOG(DEBUG, format, ## __VA_ARGS__); \
} \
} while(0)
--
2.17.1

View File

@ -0,0 +1,86 @@
From df20de186c5a014c4064a4f6e57bd53493c37348 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Tue, 29 May 2018 01:01:23 +0100
Subject: [PATCH 36/43] vdlog: Factor our a "logf" function to avoid long "LOG"
macro
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
common/vdlog.cpp | 26 ++++++++++++++++++++++++++
common/vdlog.h | 15 +++++----------
2 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/common/vdlog.cpp b/common/vdlog.cpp
index 8af6dcc..8c11d33 100644
--- a/common/vdlog.cpp
+++ b/common/vdlog.cpp
@@ -79,6 +79,32 @@ void VDLog::printf(const char* format, ...)
fflush(fh);
}
+void VDLog::logf(const char *type, const char *function, const char* format, ...)
+{
+ FILE *fh = _log ? _log->_handle : stdout;
+ va_list args;
+
+ struct _timeb now;
+ struct tm today;
+ char datetime_str[20];
+ _ftime_s(&now);
+ localtime_s(&today, &now.time);
+ strftime(datetime_str, 20, "%Y-%m-%d %H:%M:%S", &today);
+
+ _lock_file(fh);
+ fprintf(fh, "%lu::%s::%s,%.3d::%s::",
+ GetCurrentThreadId(), type,
+ datetime_str,
+ now.millitm,
+ function);
+
+ va_start(args, format);
+ vfprintf(fh, format, args);
+ va_end(args);
+ _unlock_file(fh);
+ fflush(fh);
+}
+
void log_version()
{
// print same version as resource one
diff --git a/common/vdlog.h b/common/vdlog.h
index d017ac3..c80a199 100644
--- a/common/vdlog.h
+++ b/common/vdlog.h
@@ -35,6 +35,10 @@ public:
__attribute__((__format__ (gnu_printf, 1, 2)))
#endif
static void printf(const char* format, ...);
+#ifdef __GNUC__
+ __attribute__((__format__ (gnu_printf, 3, 4)))
+#endif
+ static void logf(const char *type, const char *function, const char* format, ...);
private:
VDLog(FILE* handle);
@@ -60,16 +64,7 @@ static const VDLogLevel log_level = LOG_INFO;
#define LOG(type, format, ...) do { \
if (LOG_ ## type >= log_level && LOG_ ## type <= LOG_FATAL) { \
- struct _timeb now; \
- struct tm today; \
- char datetime_str[20]; \
- _ftime_s(&now); \
- localtime_s(&today, &now.time); \
- strftime(datetime_str, 20, "%Y-%m-%d %H:%M:%S", &today); \
- VDLog::printf("%lu::%s::%s,%.3d::%s::" format "\n", \
- GetCurrentThreadId(), #type, \
- datetime_str, now.millitm, \
- __FUNCTION__, ## __VA_ARGS__); \
+ VDLog::logf(#type, __FUNCTION__, format "\n", ## __VA_ARGS__); \
} \
} while(0)
--
2.17.1

View File

@ -0,0 +1,46 @@
From 9ddddf205f61b3451f37867a3bf7db455c773e53 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Tue, 29 May 2018 01:01:23 +0100
Subject: [PATCH 37/43] vdlog: Use GetLocalTime instead of multiple C functions
The GetLocalTime function already returns all information we
need for the log, no needs to call multiple C functions.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
---
common/vdlog.cpp | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/common/vdlog.cpp b/common/vdlog.cpp
index 8c11d33..e2561e2 100644
--- a/common/vdlog.cpp
+++ b/common/vdlog.cpp
@@ -84,18 +84,15 @@ void VDLog::logf(const char *type, const char *function, const char* format, ...
FILE *fh = _log ? _log->_handle : stdout;
va_list args;
- struct _timeb now;
- struct tm today;
- char datetime_str[20];
- _ftime_s(&now);
- localtime_s(&today, &now.time);
- strftime(datetime_str, 20, "%Y-%m-%d %H:%M:%S", &today);
+ SYSTEMTIME st;
+ GetLocalTime(&st);
_lock_file(fh);
- fprintf(fh, "%lu::%s::%s,%.3d::%s::",
+ fprintf(fh, "%lu::%s::%.4u-%.2u-%.2u %.2u:%.2u:%.2u,%.3u::%s::",
GetCurrentThreadId(), type,
- datetime_str,
- now.millitm,
+ st.wYear, st.wMonth, st.wDay,
+ st.wHour, st.wMinute, st.wSecond,
+ st.wMilliseconds,
function);
va_start(args, format);
--
2.17.1

View File

@ -0,0 +1,32 @@
From 6d1d4241ac9abc59970c4839845a2d174db58854 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sat, 30 Jun 2018 05:46:19 +0100
Subject: [PATCH 38/43] Use proper invalid value for _vio_serial
For some reason kernel handles in Windows have 2 invalid values
depending on the type. Files/devices use INVALID_HANDLE_VALUE (-1),
while others use NULL (0). As _vio_serial is a file, created
with CreateFile, use INVALID_HANDLE_VALUE for consistency.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/vdagent.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 423c3ee..eed3103 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -198,7 +198,7 @@ VDAgent::VDAgent()
, _session_is_locked (false)
, _desktop_switch (false)
, _display_setting (VD_AGENT_REGISTRY_KEY)
- , _vio_serial (NULL)
+ , _vio_serial (INVALID_HANDLE_VALUE)
, _read_pos (0)
, _write_pos (0)
, _logon_desktop (false)
--
2.17.1

View File

@ -0,0 +1,54 @@
From 0ac9d687e92165f6274786e5f5485cc65ae5c34a Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sat, 30 Jun 2018 05:48:02 +0100
Subject: [PATCH 39/43] Introduce an helper to close VirtIo device
Do not assume we allocated the handle doing the cleanup.
This utility will be reused in next patch.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe de Dinechin <dinechin@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/vdagent.cpp | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index eed3103..69d61da 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -110,6 +110,7 @@ private:
bool write_message(uint32_t type, uint32_t size, void* data);
bool write_clipboard(VDAgentMessage* msg, uint32_t size);
bool init_vio_serial();
+ void close_vio_serial();
bool send_input();
void set_display_depth(uint32_t depth);
void load_display_setting();
@@ -343,7 +344,7 @@ bool VDAgent::run()
void VDAgent::cleanup()
{
FreeLibrary(_user_lib);
- CloseHandle(_vio_serial);
+ close_vio_serial();
}
void VDAgent::set_control_event(control_command_t control_command)
@@ -1227,6 +1228,14 @@ bool VDAgent::init_vio_serial()
return true;
}
+void VDAgent::close_vio_serial()
+{
+ if (_vio_serial != INVALID_HANDLE_VALUE) {
+ CloseHandle(_vio_serial);
+ _vio_serial = INVALID_HANDLE_VALUE;
+ }
+}
+
void VDAgent::dispatch_message(VDAgentMessage* msg, uint32_t port)
{
bool res = true;
--
2.17.1

View File

@ -0,0 +1,102 @@
From 2ae3bd5b9c9548c096e13f5de42855680a63b692 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sun, 1 Jul 2018 06:40:48 +0100
Subject: [PATCH 40/43] Use destructor instead of cleanup function
More C++ style.
Also avoids missing cleanup calls.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/vdagent.cpp | 17 ++++-------------
1 file changed, 4 insertions(+), 13 deletions(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 69d61da..306bfbd 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -116,7 +116,6 @@ private:
void load_display_setting();
bool send_announce_capabilities(bool request);
void cleanup_in_msg();
- void cleanup();
bool has_capability(unsigned int capability) const {
return VD_AGENT_HAS_CAPABILITY(_client_caps.begin(), _client_caps.size(),
capability);
@@ -223,6 +222,8 @@ VDAgent::VDAgent()
VDAgent::~VDAgent()
{
+ FreeLibrary(_user_lib);
+ close_vio_serial();
CloseHandle(_stop_event);
CloseHandle(_control_event);
delete _log;
@@ -257,6 +258,8 @@ bool VDAgent::run()
HANDLE event_thread;
WNDCLASS wcls;
+ close_vio_serial();
+
if (!ProcessIdToSessionId(GetCurrentProcessId(), &session_id)) {
vd_printf("ProcessIdToSessionId failed %lu", GetLastError());
return false;
@@ -289,7 +292,6 @@ bool VDAgent::run()
_control_event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!_control_event) {
vd_printf("CreateEvent() failed: %lu", GetLastError());
- cleanup();
return false;
}
ResetEvent(_control_event);
@@ -302,7 +304,6 @@ bool VDAgent::run()
wcls.lpszClassName = VD_AGENT_WINCLASS_NAME;
if (!RegisterClass(&wcls)) {
vd_printf("RegisterClass() failed: %lu", GetLastError());
- cleanup();
return false;
}
_desktop_layout.reset(new DesktopLayout());
@@ -310,20 +311,17 @@ bool VDAgent::run()
vd_printf("No QXL devices!");
}
if (!init_vio_serial()) {
- cleanup();
return false;
}
if (!ReadFileEx(_vio_serial, _read_buf, sizeof(VDIChunk), &_read_overlapped, read_completion) &&
GetLastError() != ERROR_IO_PENDING) {
vd_printf("vio_serial read error %lu", GetLastError());
- cleanup();
return false;
}
_running = true;
event_thread = CreateThread(NULL, 0, event_thread_proc, this, 0, NULL);
if (!event_thread) {
vd_printf("CreateThread() failed: %lu", GetLastError());
- cleanup();
return false;
}
send_announce_capabilities(true);
@@ -337,16 +335,9 @@ bool VDAgent::run()
}
vd_printf("Agent stopped");
CloseHandle(event_thread);
- cleanup();
return true;
}
-void VDAgent::cleanup()
-{
- FreeLibrary(_user_lib);
- close_vio_serial();
-}
-
void VDAgent::set_control_event(control_command_t control_command)
{
MutexLocker lock(_control_mutex);
--
2.17.1

View File

@ -0,0 +1,67 @@
From 7038aa83b393146ceaaa5ada74fdd76beef150ac Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sun, 8 Jul 2018 20:48:56 +0100
Subject: [PATCH 41/43] vdagent: Stop correctly helper thread
The thread launched to detect desktop switches events is not stopped
correctly causing potentially dandling pointers.
Queue a APC to make the loop exit and wait for thread termination
from the main thread.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/vdagent.cpp | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index 306bfbd..e577679 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -238,20 +238,27 @@ DWORD WINAPI VDAgent::event_thread_proc(LPVOID param)
return 1;
}
while (agent->_running) {
- DWORD wait_ret = WaitForSingleObject(desktop_event, INFINITE);
+ DWORD wait_ret = WaitForSingleObjectEx(desktop_event, INFINITE, TRUE);
switch (wait_ret) {
case WAIT_OBJECT_0:
agent->set_control_event(CONTROL_DESKTOP_SWITCH);
break;
+ case WAIT_IO_COMPLETION:
+ // handle APC events
+ break;
case WAIT_TIMEOUT:
default:
- vd_printf("WaitForSingleObject(): %lu", wait_ret);
+ vd_printf("WaitForSingleObjectEx(): %lu", wait_ret);
}
}
CloseHandle(desktop_event);
return 0;
}
+static VOID CALLBACK event_thread_stop_proc(ULONG_PTR)
+{
+}
+
bool VDAgent::run()
{
DWORD session_id;
@@ -333,8 +340,12 @@ bool VDAgent::run()
set_clipboard_owner(owner_none);
}
}
- vd_printf("Agent stopped");
+ if (!QueueUserAPC(event_thread_stop_proc, event_thread, 0)) {
+ TerminateThread(event_thread, 0);
+ }
+ WaitForSingleObject(event_thread, INFINITE);
CloseHandle(event_thread);
+ vd_printf("Agent stopped");
return true;
}
--
2.17.1

View File

@ -0,0 +1,36 @@
From 9264c7f367e44ce2d4e773add80b63e1777e3e0f Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Thu, 5 Jul 2018 16:13:00 +0100
Subject: [PATCH 42/43] vdagent: Add a comment around WinSta0_DesktopSwitch
event usage
Multiple times while I was reading this code was not clear why the
synchronization of this event was not done in the main event loop.
Also document why we want to use it not relying just on
WTSRegisterSessionNotification and WM_WTSSESSION_CHANGE.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/vdagent.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index e577679..be17ddc 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -232,6 +232,11 @@ VDAgent::~VDAgent()
DWORD WINAPI VDAgent::event_thread_proc(LPVOID param)
{
VDAgent *agent = static_cast<VDAgent *>(param);
+ // This event is monitored in a separate thread to avoid losing
+ // events as the event is signaled with PulseEvent to wake up all
+ // thread waiting for it.
+ // This event allows to detect desktop switches which do not
+ // change sessions like pressing Ctrl-Alt-Delete.
HANDLE desktop_event = OpenEvent(SYNCHRONIZE, FALSE, L"WinSta0_DesktopSwitch");
if (!desktop_event) {
vd_printf("OpenEvent() failed: %lu", GetLastError());
--
2.17.1

View File

@ -0,0 +1,61 @@
From 348f7ed0cd355451408b5206f8fa423d406bc440 Mon Sep 17 00:00:00 2001
From: Frediano Ziglio <fziglio@redhat.com>
Date: Sat, 30 Jun 2018 05:13:07 +0100
Subject: [PATCH 43/43] Use GetModuleHandle to get some functions from user32
library
The library is surely already loaded as providing clipboard and
other utilities we need.
user32 is one of the main win32 libraries.
Avoid using LoadLibrary that increment the reference so we don't
need to call FreeLibrary to cleanly decrement the reference.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Acked-by: Christophe Fergeau <cfergeau@redhat.com>
---
vdagent/vdagent.cpp | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/vdagent/vdagent.cpp b/vdagent/vdagent.cpp
index be17ddc..89019bb 100644
--- a/vdagent/vdagent.cpp
+++ b/vdagent/vdagent.cpp
@@ -125,7 +125,6 @@ private:
static VDAgent* _singleton;
HWND _hwnd;
HWND _hwnd_next_viewer;
- HMODULE _user_lib;
PCLIPBOARD_OP _add_clipboard_listener;
PCLIPBOARD_OP _remove_clipboard_listener;
clipboard_owner_t _clipboard_owner;
@@ -183,7 +182,6 @@ VDAgent* VDAgent::get()
VDAgent::VDAgent()
: _hwnd (NULL)
, _hwnd_next_viewer (NULL)
- , _user_lib (NULL)
, _add_clipboard_listener (NULL)
, _remove_clipboard_listener (NULL)
, _clipboard_owner (owner_none)
@@ -222,7 +220,6 @@ VDAgent::VDAgent()
VDAgent::~VDAgent()
{
- FreeLibrary(_user_lib);
close_vio_serial();
CloseHandle(_stop_event);
CloseHandle(_control_event);
@@ -285,9 +282,9 @@ bool VDAgent::run()
vd_printf("SetProcessShutdownParameters failed %lu", GetLastError());
}
- _user_lib = LoadLibrary(L"User32.dll");
+ HMODULE _user_lib = GetModuleHandle(L"User32");
if (!_user_lib) {
- vd_printf("LoadLibrary failed %lu", GetLastError());
+ vd_printf("GetModuleHandle failed %lu", GetLastError());
return false;
}
_add_clipboard_listener =
--
2.17.1

View File

@ -0,0 +1,204 @@
%{?mingw_package_header}
%global _hardened_build 1
#define _version_suffix -348f
Name: mingw-spice-vdagent
Version: 0.9.0
Release: 3%{?dist}
Summary: MinGW Windows SPICE guest agent
License: GPLv2+
URL: http://spice-space.org/
Source0: vdagent-win-%{version}%{?_version_suffix}.tar.xz
Patch1:0001-Make-BitmapCoder-from_bitmap-return-a-BMP-file-forma.patch
Patch2:0002-imagetest-Save-PNG-file-using-a-helper-function.patch
Patch3:0003-imagetest-Save-BMP-file-using-BitmapCoder.patch
Patch4:0004-vdagent-Removed-unused-declaration.patch
Patch5:0005-Avoid-to-use-names-with-reserved-characters.patch
# do not apply patch6 + its revert -- do not touch Makefile.am
#Patch6:0006-Enable-some-security-options-on-output-executables.patch
#Patch7:0007-Revert-Enable-some-security-options-on-output-execut.patch
Patch8:0008-vcproj-Remove-reference-to-CxImage.patch
Patch9:0009-vcproj-Add-some-missing-files.patch
Patch10:0010-Fix-minor-compiler-compatibility.patch
Patch11:0011-Avoid-unused-variable-warning.patch
Patch12:0012-msi-Do-not-generate-deps.txt.patch
Patch13:0013-file_xfer-Remove-FileXferTask-structure-alignment.patch
Patch14:0014-file_xfer-Remove-too-C-syntax-for-C.patch
Patch15:0015-file_xfer-Use-destructor-for-FileXferTask.patch
Patch16:0016-file_xfer-Use-shared_ptr-to-simplify-memory-manageme.patch
Patch17:0017-vdagent-Fix-loss-of-mouse-movement-events.patch
Patch18:0018-Reuse-spice-protocol-macros-instead-of-defining-new-.patch
Patch19:0019-vdservice-Do-not-append-line-terminator-to-log.patch
Patch20:0020-Fix-some-minor-buffer-overflows-reading-registry-inf.patch
Patch21:0021-Use-enumeration-types.patch
Patch22:0022-Minimal-message-size-check.patch
Patch23:0023-Use-proper-type-for-_clipboard_owner.patch
Patch24:0024-Reduce-indentation-returning-earlier.patch
Patch25:0025-Minor-overflow-checks-improvements.patch
Patch26:0026-Replace-an-assert-with-proper-handling-code.patch
Patch27:0027-Use-std-unique_ptr-for-_desktop_layout.patch
Patch28:0028-Use-always-TCHAR-to-read-string-from-registry.patch
Patch29:0029-Factor-out-an-utility-function-to-read-strings-from-.patch
Patch30:0030-Allow-one-more-character-reading-strings-from-regist.patch
Patch31:0031-Allocate-_control_event-and-_stop_event-just-once.patch
Patch32:0032-Avoid-declaring-event_thread_id.patch
Patch33:0033-Avoid-declaring-_system_version-member.patch
Patch34:0034-Avoids-to-call-supported_system_version.patch
Patch35:0035-vdlog-Remove-the-lookup-table-for-log-types.patch
Patch36:0036-vdlog-Factor-our-a-logf-function-to-avoid-long-LOG-m.patch
Patch37:0037-vdlog-Use-GetLocalTime-instead-of-multiple-C-functio.patch
Patch38:0038-Use-proper-invalid-value-for-_vio_serial.patch
Patch39:0039-Introduce-an-helper-to-close-VirtIo-device.patch
Patch40:0040-Use-destructor-instead-of-cleanup-function.patch
Patch41:0041-vdagent-Stop-correctly-helper-thread.patch
Patch42:0042-vdagent-Add-a-comment-around-WinSta0_DesktopSwitch-e.patch
Patch43:0043-Use-GetModuleHandle-to-get-some-functions-from-user3.patch
BuildRequires: mingw32-filesystem >= 23
BuildRequires: mingw64-filesystem >= 23
BuildRequires: mingw32-gcc-c++
BuildRequires: mingw64-gcc-c++
BuildRequires: mingw32-libpng-static
BuildRequires: mingw64-libpng-static
BuildRequires: mingw32-winpthreads-static
BuildRequires: mingw64-winpthreads-static
BuildRequires: mingw32-zlib-static
BuildRequires: mingw64-zlib-static
BuildRequires: pkgconfig
BuildRequires: mingw32-pkg-config
BuildRequires: mingw64-pkg-config
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: autoconf-archive
BuildArch: noarch
ExclusiveArch: %{ix86} x86_64
%package -n mingw32-spice-vdagent
Summary: MinGW Windows SPICE guest agent
%package -n mingw64-spice-vdagent
Summary: MinGW Windows SPICE guest agent
%description
Spice agent for Windows guests offering the following features:
Features:
* Client mouse mode (no need to grab mouse by client, no mouse lag)
this is handled by the daemon by feeding mouse events into the kernel
via uinput.
* Automatic adjustment of the Windows desktop resolution to the client resolution
* Support of copy and paste (text and images) between the active Windows
session and the client
%description -n mingw32-spice-vdagent
Spice agent for Windows guests offering the following features:
Features:
* Client mouse mode (no need to grab mouse by client, no mouse lag)
this is handled by the daemon by feeding mouse events into the kernel
via uinput.
* Automatic adjustment of the Windows desktop resolution to the client resolution
* Support of copy and paste (text and images) between the active Windows
session and the client
%description -n mingw64-spice-vdagent
Spice agent for Windows guests offering the following features:
Features:
* Client mouse mode (no need to grab mouse by client, no mouse lag)
this is handled by the daemon by feeding mouse events into the kernel
via uinput.
* Automatic adjustment of the Windows desktop resolution to the client resolution
* Support of copy and paste (text and images) between the active Windows
session and the client
%{mingw_debug_package}
%prep
%setup -q -n vdagent-win-%{version}%{?_version_suffix}
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
#%patch6 -p1
#%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
%patch28 -p1
%patch29 -p1
%patch30 -p1
%patch31 -p1
%patch32 -p1
%patch33 -p1
%patch34 -p1
%patch35 -p1
%patch36 -p1
%patch37 -p1
%patch38 -p1
%patch39 -p1
%patch40 -p1
%patch41 -p1
%patch42 -p1
%patch43 -p1
# --- autoreconf ---
# Without autoreconf it fails.
# Update configure.ac with the version and run autoreconf.
# build-aux/git-version-gen is currently not available in the tarball
# so use sed instead.
sed -i "s/^AC_INIT.*/AC_INIT(vdagent-win, [%{version}])/" configure.ac
sed -i "/m4_esyscmd.*build-aux.git-version-gen .tarball-version/d" configure.ac
autoreconf -fi
# --- autoreconf --- done
%build
%mingw_configure --verbose --enable-debug
%mingw_make %{?_smp_mflags} V=1
%install
%mingw_make_install DESTDIR=$RPM_BUILD_ROOT
%files -n mingw32-spice-vdagent
%defattr(-,root,root)
%{mingw32_bindir}/vdagent.exe
%{mingw32_bindir}/vdservice.exe
%files -n mingw64-spice-vdagent
%defattr(-,root,root)
%{mingw64_bindir}/vdagent.exe
%{mingw64_bindir}/vdservice.exe
%changelog
* Tue Aug 22 2017 Uri Lublin <uril@redhat.com> - 0.9.0-3
- First build for RHEL-8.0
Related: rhbz#1557012