[Spice-devel] [phodav PATCH 3/3 v6] spice-webdavd-windows: Dismount shared folder on service stop
Lukáš Venhoda
lvenhoda at redhat.com
Thu Apr 21 15:28:09 UTC 2016
From: Lukas Venhoda <lvenhoda at redhat.com>
When stopping the service, automatically disconnect shared folder on
windows. Not dismounting could lead to multiple shared folders.
---
Changes since v5:
- fixed indentation
- fixed * indentaion
- removed return from void functions
- changed ServiceData * to gpointer, so that it compiles on linux
Changes since v4:
- Dont lookup drive letter when unmapping
- Uses a service_data structure and map_drive_data structure to store
the drive_letter for later use while unmapping
- Better debug messages
Changes since v3:
- Better handeling of string names
- Syntax cleanup
- Remove global variable drive_letter
- Now scans for mapped drive and unmaps it
Changes since v2:
- None
Changes since v1:
- New patch
---
spice/spice-webdavd.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 52 insertions(+), 4 deletions(-)
diff --git a/spice/spice-webdavd.c b/spice/spice-webdavd.c
index bac8dbd..b9f4c44 100644
--- a/spice/spice-webdavd.c
+++ b/spice/spice-webdavd.c
@@ -749,6 +749,7 @@ typedef enum _MapDriveEnum
typedef struct _MapDriveData
{
+ gchar *drive_letter;
GCancellable *cancel_map;
} MapDriveData;
@@ -855,6 +856,31 @@ map_drive(const gchar drive_letter)
}
static void
+unmap_drive(const gchar drive_letter)
+{
+ gchar local_name[MAX_DRIVE_LETTER_SIZE];
+ guint32 errn;
+
+ g_snprintf(local_name, MAX_DRIVE_LETTER_SIZE, "%c:", drive_letter);
+ errn = WNetCancelConnection2(local_name, CONNECT_UPDATE_PROFILE, TRUE);
+
+ if (errn == NO_ERROR)
+ {
+ g_debug ("Shared folder unmapped succesfully");
+ }
+ else if (errn == ERROR_NOT_CONNECTED)
+ {
+ g_debug ("Drive %c is not connected", drive_letter);
+ }
+ else
+ {
+ g_warning ("map_drive error %d", errn);
+ }
+
+ return;
+}
+
+static void
map_drive_cb(GTask *task,
gpointer source_object,
gpointer task_data,
@@ -899,10 +925,17 @@ map_drive_cb(GTask *task,
*(map_drive_data->drive_letter) = drive_letter;
}
+
+typedef struct _ServiceData
+{
+ gchar drive_letter;
+} ServiceData;
+
#endif
+//Parameter service_data is only used on windows when started as a service
static void
-run_service (void)
+run_service (ServiceData *service_data G_GNUC_UNUSED)
{
g_debug ("Run service");
@@ -912,6 +945,16 @@ run_service (void)
gchar drive_letter = get_spice_folder_letter ();
+ if (service_data != NULL)
+ {
+ service_data->drive_letter = drive_letter;
+ map_drive_data.drive_letter = &(service_data->drive_letter);
+ }
+ else
+ {
+ map_drive_data.drive_letter = &(drive_letter);
+ }
+
if (drive_letter == 0)
{
GTask *map_drive_task = g_task_new (NULL, NULL, NULL, NULL);
@@ -993,10 +1036,13 @@ service_ctrl_handler (DWORD ctrl, DWORD type, LPVOID data, LPVOID ctx)
{
DWORD ret = NO_ERROR;
+ ServiceData *service_data = ctx;
+
switch (ctrl)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
+ unmap_drive (service_data->drive_letter);
quit (SIGTERM);
service_status.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus (service_status_handle, &service_status);
@@ -1012,8 +1058,10 @@ service_ctrl_handler (DWORD ctrl, DWORD type, LPVOID data, LPVOID ctx)
VOID WINAPI
service_main (DWORD argc, TCHAR *argv[])
{
+ ServiceData service_data;
+
service_status_handle =
- RegisterServiceCtrlHandlerEx ("spice-webdavd", service_ctrl_handler, NULL);
+ RegisterServiceCtrlHandlerEx ("spice-webdavd", service_ctrl_handler, &service_data);
g_return_if_fail (service_status_handle != 0);
@@ -1027,7 +1075,7 @@ service_main (DWORD argc, TCHAR *argv[])
SetServiceStatus (service_status_handle, &service_status);
while (!quit_service) {
- run_service ();
+ run_service (&service_data);
g_usleep (G_USEC_PER_SEC);
}
@@ -1113,7 +1161,7 @@ main (int argc, char *argv[])
} else
#endif
while (!quit_service) {
- run_service ();
+ run_service (NULL);
g_usleep (G_USEC_PER_SEC);
}
--
2.5.5
More information about the Spice-devel
mailing list