[vlc-commits] [Git][videolan/vlc][master] unc: use Windows API to handle shares
Felix Paul Kühne (@fkuehne)
gitlab at videolan.org
Sat Mar 8 15:15:30 UTC 2025
Felix Paul Kühne pushed to branch master at VideoLAN / VLC
Commits:
fde35591 by Steve Lhomme at 2025-03-08T15:01:09+00:00
unc: use Windows API to handle shares
Using the wide char API allows handling pathes with non ANSI characters.
Using the native Windows API allows retrieving just the flags we want.
This should work in UWP apart from the network connection with the credentials.
- - - - -
1 changed file:
- modules/access/unc.c
Changes:
=====================================
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()
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/fde35591e3eb98f89ef872fb9b3132bf585414b0
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/fde35591e3eb98f89ef872fb9b3132bf585414b0
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list