<div dir="ltr"><div><div class="gmail_extra"><div class="gmail_quote">Hi<br>On Thu, Sep 17, 2015 at 2:47 PM, Marc-André Lureau <span dir="ltr"><<a href="mailto:mlureau@redhat.com" target="_blank">mlureau@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi<br>
<span class=""><br>
----- Original Message -----</span> </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
> How do you prevent from having multiple drive pointing to the spice folder?<br>
><br>
><br>
> Currently, I don't.<br>
><br>
> Only way to connect multiple drives, is if you restart the service,<br>
> because the drives will disconnect, after restarting guest.<br>
><br>
> I will add a disconnect function to the quit function in the service,<br>
> so that if uou disable, or restart teh service, the drive will be unmapped<br>
><br>
<br>
</span>Can't you enumerate existing mappings and only add one if it's necessary?<br>
<div><div class="h5"><br></div></div></blockquote><div><br></div><div>Yes there seems to be API for that, so I can try to implement it.<br><br></div><div>Still I'll make a disconnect function anyway, because it doesn't make sense<br>to have a drive mapped, when the webdavd service is not even running<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div class="h5">
> > ---<br>
> > Changes since RFC:<br>
> > - Calling WNetAddConnection2() blindly was slow and caause many threads to<br>
> > spawn.<br>
> > - Now only call it once, when it is sure, that it will connect.<br>
> > - Now connects to a * drive, instead of always Z:<br>
> > - Thread is now spawned and joined every time run_service() is called.<br>
> > ---<br>
> > Makefile.am | 4 +++<br>
> > spice/spice-webdavd.c | 76<br>
> > +++++++++++++++++++++++++++++++++++++++++++++++++++<br>
> > 2 files changed, 80 insertions(+)<br>
> ><br>
> > diff --git a/Makefile.am b/Makefile.am<br>
> > index 485417b..df9a73e 100644<br>
> > --- a/Makefile.am<br>
> > +++ b/Makefile.am<br>
> > @@ -87,6 +87,10 @@ spice_webdavd_LDADD = \<br>
> > $(PIE_LDFLAGS) \<br>
> > $(NULL)<br>
> ><br>
> > +if OS_WIN32<br>
> > +spice_webdavd_LDADD += -lnetapi32 -lmpr<br>
> > +endif<br>
> > +<br>
> > deps.txt:<br>
> > $(AM_V_GEN)rpm -qa | grep $(host_os) | sort | unix2dos > $@<br>
> ><br>
> > diff --git a/spice/spice-webdavd.c b/spice/spice-webdavd.c<br>
> > index f9c5cf1..3940f1c 100644<br>
> > --- a/spice/spice-webdavd.c<br>
> > +++ b/spice/spice-webdavd.c<br>
> > @@ -737,11 +737,81 @@ open_mux_path (const char *path)<br>
> > mux_queue = output_queue_new (G_OUTPUT_STREAM (mux_ostream));<br>
> > }<br>
> ><br>
> > +#ifdef G_OS_WIN32<br>
> > +static gchar<br>
> > +get_free_drive_letter(void)<br>
> > +{<br>
> > + const guint32 max_mask = 1 << 25;<br>
> > + guint32 drives;<br>
> > + guint32 mask;<br>
> > + gint i;<br>
> > +<br>
> > + drives = GetLogicalDrives ();<br>
> > +<br>
> > + for (i = 0; i < 26; i++)<br>
> > + {<br>
> > + mask = max_mask >> i;<br>
> > + if ((drives & mask) == 0)<br>
> > + return 'Z' - i;<br>
> > + }<br>
> > +<br>
> > + return 0;<br>
> > +}<br>
> > +<br>
> > +static gpointer<br>
> > +map_drive(gpointer user_data)<br>
> > +{<br>
> > + GCancellable * cancel_map = user_data;<br>
> > + gchar drive_letter;<br>
> > + gchar local_name[3];<br>
> > + gchar remote_name[] = " <a href="http://localhost:9843/" rel="noreferrer" target="_blank">http://localhost:9843/</a> ";<br>
> > + NETRESOURCE net_resource;<br>
> > + guint32 retval;<br>
> > + gint i;<br>
> > +<br>
> > + for (i = 0; i < 5; ++i)<br>
> > + {<br>
> > + if (g_cancellable_is_cancelled (cancel_map))<br>
> > + return NULL;<br>
> > + else<br>
> > + g_usleep (G_USEC_PER_SEC);<br>
> > + }<br>
><br>
> It looks like this would fail if the guest is started without client<br>
> connected (or not sharing folder).<br>
><br>
> I'm not sure I follow.<br>
> This is supposed to return NULL precisely, if the client is not connected,<br>
> or not sharing folder. Windows webdavd will loop and call run_service(),<br>
> until sharing is enabled, which will then NOT cancel this function,<br>
> and we map the drive.<br>
<br>
</div></div>ah so the service keeps running and next time the client connects, then the thread will be started again?<br></blockquote><div><br></div><div>No, the thread starts only after the service is started for the first time. When user disconnects, the service<br>currently doesn't notice on Windows (read_thread is still blocked), so when a different user connects,<br>the drive is still mapped, but when the new user enables sharing, the original drive will work, as it connects<br>to the same remote name (<a href="http://localhost:9843/">http://localhost:9843/</a>).<br><br></div><div>This is still an issue, because if the new user doesn't enable sharing, the drive will still be there, but won't<br>be accessible. But that is issue for another patch (and bug).<br></div></div><br>...<br><br>> Sorry I didn't mean what the thread was doing, but rather why we need a thread for this task.<br><br></div><div class="gmail_extra">Well I could use a g_task or g_idle, or something like that, but g_idle isn't cancellable, and g_task<br>seemed too complicated for this. When I tried to do this in the main_thread (as it just has to be a<br>different thread then read_thread), I ran into race conditions between the read_thread and map_drive,<br>especially, when using sleep between polling for cancellable.<br></div><div class="gmail_extra">Spawning a thread for a few seconds just seemed to be less complicated.<br><br></div><div class="gmail_extra">As for why this has to be in a different thread, then read_thread, is because if I call map_drive before<br>read actually blocks, it returns error, as if it's not connected. I think this is because when we try to map<br>the drive, client sends a message to the guest, and the read has to be ready to receive it, which in turn<br>lets the map_drive to actually map the drive.<br><br></div><div class="gmail_extra">I tryed using every possible way I could think of, even windows specific polling, but I couldn't make<br>anything work, except just plain spawning another thread.<br><br></div><div class="gmail_extra">Lukas Venhoda<br></div></div></div>