----- Original Message ----- > Hey, > > On Thu, Sep 17, 2015 at 02:29:21PM +0200, Lukas Venhoda wrote: > > Hi > > > > On Thu, Sep 17, 2015 at 12:23 PM, Marc-André Lureau < > > marcandre.lureau@xxxxxxxxx> wrote: > > > > > Hi > > > > > > On Thu, Aug 27, 2015 at 6:25 PM, Lukas Venhoda <lvenhoda@xxxxxxxxxx> > > > wrote: > > > > Try to connect to shared folder automatically on Windows. > > > > > > > > On each loop of run_service(), spawn a thread, that waits for 5 > > > > seconds. > > > > If read_thread() returns, it means, that sharing is not yet connected, > > > > and the map_drive thread is cancelled, and joined back to main thread. > > > > > > > > If the map_drive thread is NOT cancelled, it enumerates free drive > > > > letters, and maps shared folder to highest possible (from Z: to A:). > > > > > > > > If all drive letters are already assigned, stop the service. > > > > > > Could you explain in the commit message why you need the thread ? > > > > > > > How about this commit message? > > > > "Try to connect to shared folder automatically on Windows. > > > > When client is connected, and sharing is enabled, map_drive is called. > > It enumerates free drive letters, and maps shared folder to highest > > possible, > > from (Z:) to (A:). If all drive letters are already assigned, stops the > > service. > > > > map_drive needs to be called only after, the read_thread blocks. > > If it is called before, the mapping fails. > > > > In order to call it only after read_thread blocks, we spawn a thread, > > that waits for 5 seconds, before actually calling map_drive. > > If read_thread() returns, it means, that sharing is not yet connected, > > and the map_drive thread is cancelled. > > > > We spawn this thread on each loop of run_service(), and join it back > > into main_thread, after main loop ends." > > Sorry I didn't mean what the thread was doing, but rather why we need a thread for this task. > > I would also include that this patch resolves > https://bugs.freedesktop.org/show_bug.cgi?id=90477 > > - toso > > > > > > > > How do you prevent from having multiple drive pointing to the spice > > > folder? > > > > > > > > Currently, I don't. > > > > Only way to connect multiple drives, is if you restart the service, > > because the drives will disconnect, after restarting guest. > > > > I will add a disconnect function to the quit function in the service, > > so that if uou disable, or restart teh service, the drive will be unmapped > > > > > > > > > > > --- > > > > Changes since RFC: > > > > - Calling WNetAddConnection2() blindly was slow and caause many > > > > threads > > > to spawn. > > > > - Now only call it once, when it is sure, that it will connect. > > > > - Now connects to a * drive, instead of always Z: > > > > - Thread is now spawned and joined every time run_service() is called. > > > > --- > > > > Makefile.am | 4 +++ > > > > spice/spice-webdavd.c | 76 > > > +++++++++++++++++++++++++++++++++++++++++++++++++++ > > > > 2 files changed, 80 insertions(+) > > > > > > > > diff --git a/Makefile.am b/Makefile.am > > > > index 485417b..df9a73e 100644 > > > > --- a/Makefile.am > > > > +++ b/Makefile.am > > > > @@ -87,6 +87,10 @@ spice_webdavd_LDADD = \ > > > > $(PIE_LDFLAGS) \ > > > > $(NULL) > > > > > > > > +if OS_WIN32 > > > > +spice_webdavd_LDADD += -lnetapi32 -lmpr > > > > +endif > > > > + > > > > deps.txt: > > > > $(AM_V_GEN)rpm -qa | grep $(host_os) | sort | unix2dos > $@ > > > > > > > > diff --git a/spice/spice-webdavd.c b/spice/spice-webdavd.c > > > > index f9c5cf1..3940f1c 100644 > > > > --- a/spice/spice-webdavd.c > > > > +++ b/spice/spice-webdavd.c > > > > @@ -737,11 +737,81 @@ open_mux_path (const char *path) > > > > mux_queue = output_queue_new (G_OUTPUT_STREAM (mux_ostream)); > > > > } > > > > > > > > +#ifdef G_OS_WIN32 > > > > +static gchar > > > > +get_free_drive_letter(void) > > > > +{ > > > > + const guint32 max_mask = 1 << 25; > > > > + guint32 drives; > > > > + guint32 mask; > > > > + gint i; > > > > + > > > > + drives = GetLogicalDrives (); > > > > + > > > > + for (i = 0; i < 26; i++) > > > > + { > > > > + mask = max_mask >> i; > > > > + if ((drives & mask) == 0) > > > > + return 'Z' - i; > > > > + } > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static gpointer > > > > +map_drive(gpointer user_data) > > > > +{ > > > > + GCancellable * cancel_map = user_data; > > > > + gchar drive_letter; > > > > + gchar local_name[3]; > > > > + gchar remote_name[] = "http://localhost:9843/"; > > > > + NETRESOURCE net_resource; > > > > + guint32 retval; > > > > + gint i; > > > > + > > > > + for (i = 0; i < 5; ++i) > > > > + { > > > > + if (g_cancellable_is_cancelled (cancel_map)) > > > > + return NULL; > > > > + else > > > > + g_usleep (G_USEC_PER_SEC); > > > > + } > > > > > > It looks like this would fail if the guest is started without client > > > connected (or not sharing folder). > > > > > > > I'm not sure I follow. > > This is supposed to return NULL precisely, if the client is not connected, > > or not sharing folder. Windows webdavd will loop and call run_service(), > > until sharing is enabled, which will then NOT cancel this function, > > and we map the drive. > > > > > > > > > > > + > > > > + if ((drive_letter = get_free_drive_letter ()) == 0) > > > > + g_error ("all drive letters already assigned."); > > > > + > > > > + local_name[0] = drive_letter; > > > > + local_name[1] = ':'; > > > > + local_name[2] = 0; > > > > + > > > > + net_resource.dwType = RESOURCETYPE_DISK; > > > > + net_resource.lpLocalName = local_name; > > > > + net_resource.lpRemoteName = remote_name; > > > > + net_resource.lpProvider = NULL; > > > > + > > > > + retval = WNetAddConnection2 (&net_resource, NULL, NULL, > > > CONNECT_TEMPORARY); > > > > + > > > > + if (retval == NO_ERROR) > > > > + g_debug ("map_drive ok"); > > > > + else if (retval == ERROR_ALREADY_ASSIGNED) > > > > + g_debug ("map_drive already asigned"); > > > > + else > > > > + g_error ("map_drive error %d", retval); > > > > + > > > > + return NULL; > > > > +} > > > > +#endif > > > > + > > > > static void > > > > run_service (void) > > > > { > > > > g_debug ("Run service"); > > > > > > > > +#ifdef G_OS_WIN32 > > > > + GCancellable * cancel_map = g_cancellable_new (); > > > > + GThread * map_drive_thread = g_thread_new ("map-drive-thread", > > > map_drive, cancel_map); > > > > +#endif > > > > + > > > > g_socket_service_start (socket_service); > > > > > > > > cancel = g_cancellable_new (); > > > > @@ -775,6 +845,12 @@ run_service (void) > > > > g_main_loop_run (loop); > > > > g_main_loop_unref (loop); > > > > > > > > +#ifdef G_OS_WIN32 > > > > + g_cancellable_cancel (cancel_map); > > > > + g_thread_join(map_drive_thread); > > > > + g_print ("map-drive-thread joined\n"); > > > > +#endif > > > > + > > > > g_cancellable_cancel (cancel); > > > > > > > > g_clear_object (&mux_istream); > > > > -- > > > > 2.4.3 > > > > > > > > _______________________________________________ > > > > Spice-devel mailing list > > > > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > > > > http://lists.freedesktop.org/mailman/listinfo/spice-devel > > > > > > > > > > > > -- > > > Marc-André Lureau > > > > > > > Lukas Venhoda > > > _______________________________________________ > > Spice-devel mailing list > > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > > http://lists.freedesktop.org/mailman/listinfo/spice-devel > > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/spice-devel > _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel