[Spice-devel] [vdagent-win v4] Use wide characters in drap&drop code

Frediano Ziglio fziglio at redhat.com
Fri Apr 24 02:12:52 PDT 2015


This allow username to contain any extended characters (username is
embedded in the directory name).

Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 vdagent/file_xfer.cpp | 39 ++++++++++++++++++---------------------
 vdagent/file_xfer.h   |  9 +++++----
 2 files changed, 23 insertions(+), 25 deletions(-)

Changes since v4:
- fixed debugging format string

diff --git a/vdagent/file_xfer.cpp b/vdagent/file_xfer.cpp
index 2dc138b..b538faa 100644
--- a/vdagent/file_xfer.cpp
+++ b/vdagent/file_xfer.cpp
@@ -39,7 +39,7 @@ FileXfer::~FileXfer()
     for (iter = _tasks.begin(); iter != _tasks.end(); iter++) {
         task = iter->second;
         CloseHandle(task->handle);
-        DeleteFileA(task->name);
+        DeleteFile(task->name);
         delete task;
     }
 }
@@ -48,7 +48,8 @@ void FileXfer::handle_start(VDAgentFileXferStartMessage* start,
                             VDAgentFileXferStatusMessage* status)
 {
     char* file_meta = (char*)start->data;
-    char file_path[MAX_PATH], file_name[MAX_PATH];
+    TCHAR file_path[MAX_PATH];
+    char file_name[MAX_PATH];
     ULARGE_INTEGER free_bytes;
     FileXferTask* task;
     uint64_t file_size;
@@ -73,12 +74,12 @@ void FileXfer::handle_start(VDAgentFileXferStartMessage* start,
         return;
     }
 
-    if (FAILED(SHGetFolderPathA(NULL, CSIDL_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE, NULL,
+    if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE, NULL,
             SHGFP_TYPE_CURRENT, file_path))) {
         vd_printf("failed getting desktop path");
         return;
     }
-    if (!GetDiskFreeSpaceExA(file_path, &free_bytes, NULL, NULL)) {
+    if (!GetDiskFreeSpaceEx(file_path, &free_bytes, NULL, NULL)) {
         vd_printf("failed getting disk free space %lu", GetLastError());
         return;
     }
@@ -87,27 +88,23 @@ void FileXfer::handle_start(VDAgentFileXferStartMessage* start,
         return;
     }
 
-    if (strlen(file_path) + strlen(file_name) + 1 >= MAX_PATH) {
-        vd_printf("error: file too long %s\\%s", file_path, file_name);
+    wlen = _tcslen(file_path);
+    // assure we have a minimim of space
+    // (1 char for separator, 1 char for filename and 1 char for NUL terminator)
+    if (wlen + 3 >= MAX_PATH) {
+        vd_printf("error: file too long %ls\\%s", file_path, file_name);
         return;
     }
 
-    vdagent_strcat_s(file_path, sizeof(file_path), "\\");
-    vdagent_strcat_s(file_path, sizeof(file_path), file_name);
-    if((wlen = MultiByteToWideChar(CP_UTF8, 0, file_path, -1, NULL, 0)) == 0){
-        vd_printf("failed getting WideChar length of %s", file_path);
+    file_path[wlen++] = TEXT('\\');
+    file_path[wlen] = TEXT('\0');
+    if((wlen = MultiByteToWideChar(CP_UTF8, 0, file_name, -1, file_path + wlen, MAX_PATH - wlen)) == 0){
+        vd_printf("failed converting file_name:%s to WideChar", file_name);
         return;
     }
-    TCHAR *wfile_path = new TCHAR[wlen];
-    if (MultiByteToWideChar(CP_UTF8, 0, file_path, -1, wfile_path, wlen) == 0){
-        vd_printf("failed converting file_path:%s to WindChar", file_path);
-        delete[] wfile_path;
-        return;
-    }
-    handle = CreateFile(wfile_path, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
-    delete[] wfile_path;
+    handle = CreateFile(file_path, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
     if (handle == INVALID_HANDLE_VALUE) {
-        vd_printf("failed creating %s %lu", file_path, GetLastError());
+        vd_printf("failed creating %ls %lu", file_path, GetLastError());
         return;
     }
     task = new FileXferTask(handle, file_size, file_path);
@@ -150,7 +147,7 @@ fin:
     if (task) {
         CloseHandle(task->handle);
         if (status->result != VD_AGENT_FILE_XFER_STATUS_SUCCESS) {
-            DeleteFileA(task->name);
+            DeleteFile(task->name);
         }
         _tasks.erase(iter);
         delete task;
@@ -176,7 +173,7 @@ void FileXfer::handle_status(VDAgentFileXferStatusMessage* status)
     }
     task = iter->second;
     CloseHandle(task->handle);
-    DeleteFileA(task->name);
+    DeleteFile(task->name);
     _tasks.erase(iter);
     delete task;
 }
diff --git a/vdagent/file_xfer.h b/vdagent/file_xfer.h
index 7ac911e..d9c65f3 100644
--- a/vdagent/file_xfer.h
+++ b/vdagent/file_xfer.h
@@ -22,17 +22,18 @@
 #include "vdcommon.h"
 
 typedef struct ALIGN_VC FileXferTask {
-    FileXferTask(HANDLE _handle, uint64_t _size, char* _name):
+    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..
         //        currently the only user is FileXfer::handle_start
-        //        which verifies that strlen(_name) < MAX_PATH
-        vdagent_strcpy_s(name, sizeof(name), _name);
+        //        which verifies that _tcslen(_name) < MAX_PATH
+        lstrcpyn(name, _name, ARRAYSIZE(name));
+        name[ARRAYSIZE(name)-1] = 0;
     }
     HANDLE handle;
     uint64_t size;
     uint64_t pos;
-    char name[MAX_PATH];
+    TCHAR name[MAX_PATH];
 } ALIGN_GCC FileXferTask;
 
 typedef std::map<uint32_t, FileXferTask*> FileXferTasks;
-- 
2.1.0


More information about the Spice-devel mailing list