diff --git a/modules/access/unc.c b/modules/access/unc.c
index 159024d71474ecfdedec56ce7437e296c8782e73..75070c47f8e5fd229117a00408e4e96529bf9ac8 100644
--- a/modules/access/unc.c
+++ b/modules/access/unc.c
@@ -45,8 +45,8 @@
 
 typedef struct
 {
-    int i_smb;
-    uint64_t size;
+    HANDLE h;
+    LARGE_INTEGER size;
     vlc_url_t url;
 } access_sys_t;
 
@@ -120,15 +120,16 @@ static int Seek( stream_t *p_access, uint64_t i_pos )
     access_sys_t *p_sys = p_access->p_sys;
     int64_t      i_ret;
 
-    if( i_pos >= INT64_MAX )
+    if( i_pos >= LONG_LONG_MAX )
         return VLC_EGENERIC;
 
     msg_Dbg( p_access, "seeking to %"PRId64, i_pos );
 
-    i_ret = lseek( p_sys->i_smb, i_pos, SEEK_SET );
-    if( i_ret == -1 )
+    LARGE_INTEGER pos;
+    pos.QuadPart = i_pos;
+    if( !SetFilePointerEx( p_sys->h, pos, NULL, FILE_BEGIN) )
     {
-        msg_Err( p_access, "seek failed (%s)", vlc_strerror_c(errno) );
+        msg_Err( p_access, "seek failed (%lu)", GetLastError() );
         return VLC_EGENERIC;
     }
 
@@ -138,13 +139,12 @@ static int Seek( stream_t *p_access, uint64_t i_pos )
 static ssize_t Read( stream_t *p_access, void *p_buffer, size_t i_len )
 {
     access_sys_t *p_sys = p_access->p_sys;
-    int i_read;
+    DWORD i_read;
 
-    i_read = read( p_sys->i_smb, p_buffer, i_len );
-    if( i_read < 0 )
+    if( !ReadFile(p_sys->h, p_buffer, i_len, &i_read, NULL) )
     {
-        msg_Err( p_access, "read failed (%s)", vlc_strerror_c(errno) );
-        i_read = 0;
+        msg_Err( p_access, "read failed (%lu)", GetLastError() );
+        return -1;
     }
 
     return i_read;
@@ -246,7 +246,9 @@ static int Control( stream_t *p_access, int i_query, va_list args )
     case STREAM_GET_SIZE:
         if( p_access->pf_readdir != NULL )
             return VLC_EGENERIC;
-        *va_arg( args, uint64_t * ) = sys->size;
+        if( sys->size.QuadPart == LONG_LONG_MIN )
+            return VLC_EGENERIC;
+        *va_arg( args, uint64_t * ) = sys->size.QuadPart;
         break;
 
     case STREAM_GET_PTS_DELAY:
@@ -270,9 +272,9 @@ static int Open(vlc_object_t *obj)
     stream_t *access = (stream_t *)obj;
     vlc_url_t url;
     vlc_credential credential;
-    char *psz_decoded_path = NULL, *psz_uri = NULL, *psz_var_domain = NULL;
-    int fd;
-    uint64_t size;
+    char *psz_decoded_path = NULL, *psz_var_domain = NULL;
+    HANDLE h;
+    wchar_t *w_uri;
     bool is_dir;
 
     if (vlc_UrlParseFixup(&url, access->psz_url) != 0)
@@ -305,7 +307,7 @@ static int Open(vlc_object_t *obj)
 
     for (;;)
     {
-        struct stat st;
+        char *psz_uri;
 
         if (smb_get_uri(access, &psz_uri,
                         credential.psz_username, credential.psz_password,
@@ -318,19 +320,20 @@ static int Open(vlc_object_t *obj)
             return VLC_ENOMEM;
         }
 
-        if (stat(psz_uri, &st) == 0)
+        w_uri = ToWide( psz_uri );
+        free( psz_uri );
+        if( unlikely(w_uri == NULL) )
+            break;
+
+        DWORD f = GetFileAttributesW( w_uri );
+        if (f == INVALID_FILE_ATTRIBUTES)
         {
-            is_dir = S_ISDIR(st.st_mode) != 0;
-            size = st.st_size;
+            free( w_uri );
+            w_uri = NULL;
             break;
         }
 
-        /* stat() fails with servers or shares. Assume directory. */
-        is_dir = true;
-        size = 0;
-
-        if (errno != EACCES)
-            break;
+        is_dir = (f & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
 
         errno = 0;
         if (vlc_credential_get(&credential, access, "smb-user",
@@ -344,11 +347,17 @@ static int Open(vlc_object_t *obj)
     free(psz_var_domain);
     free(psz_decoded_path);
 
+    if ( w_uri == NULL)
+    {
+        vlc_UrlClean(&url);
+        return VLC_EGENERIC;
+    }
+
     /* Init access */
     access_sys_t *sys = vlc_obj_calloc(obj, 1, sizeof (*sys));
     if (unlikely(sys == NULL))
     {
-        free(psz_uri);
+        free(w_uri);
         vlc_UrlClean(&url);
         return VLC_ENOMEM;
     }
@@ -360,20 +369,31 @@ static int Open(vlc_object_t *obj)
         sys->url = url;
         access->pf_readdir = DirRead;
         access->pf_control = access_vaDirectoryControlHelper;
-        fd = -1;
+        h = INVALID_HANDLE_VALUE;
     }
     else
     {
+        vlc_UrlClean(&url);
+        h = CreateFileW(w_uri, GENERIC_READ,
+            FILE_SHARE_READ | FILE_SHARE_WRITE,
+            NULL, OPEN_EXISTING,
+            FILE_FLAG_RANDOM_ACCESS, NULL);
+        if (h == INVALID_HANDLE_VALUE)
+        {
+            free(w_uri);
+            return VLC_EACCES;
+        }
+
         access->pf_read = Read;
         access->pf_control = Control;
         access->pf_seek = Seek;
-        fd = open(psz_uri, O_RDONLY, 0);
-        vlc_UrlClean(&url);
+
+        if (!GetFileSizeEx(h, &sys->size))
+            sys->size.QuadPart = LONG_LONG_MIN;
     }
-    free(psz_uri);
+    free(w_uri);
 
-    sys->size = size;
-    sys->i_smb = fd;
+    sys->h = h;
 
     return VLC_SUCCESS;
 }
@@ -384,7 +404,7 @@ static void Close(vlc_object_t *obj)
     access_sys_t *sys = access->p_sys;
 
     vlc_UrlClean(&sys->url);
-    close(sys->i_smb);
+    CloseHandle(sys->h);
 }
 
 vlc_module_begin()