mirror of
https://github.com/nextcloud/desktop.git
synced 2024-10-24 05:15:40 +03:00
vio local: Use win32 native functions to traverse the file tree.
Native functions to replace the not native readdir and opendir functions. This works with long filenames now.
This commit is contained in:
parent
5caff8cc93
commit
2b391396c6
1 changed files with 75 additions and 9 deletions
|
@ -56,17 +56,48 @@ typedef struct dhandle_s {
|
|||
|
||||
csync_vio_handle_t *csync_vio_local_opendir(const char *name) {
|
||||
dhandle_t *handle = NULL;
|
||||
mbchar_t *dirname = c_utf8_to_locale(name);
|
||||
mbchar_t *dirname = NULL;
|
||||
|
||||
handle = c_malloc(sizeof(dhandle_t));
|
||||
|
||||
#ifdef _WIN32
|
||||
// the file wildcard has to be attached
|
||||
int len_name = strlen(name);
|
||||
if( len_name ) {
|
||||
char *h = NULL;
|
||||
|
||||
// alloc an enough large buffer to take the name + '/*' + the closing zero.
|
||||
h = c_malloc(len_name+3);
|
||||
strcpy( h, name);
|
||||
strcat(h, "/*");
|
||||
|
||||
dirname = c_utf8_to_locale(h);
|
||||
SAFE_FREE(h);
|
||||
}
|
||||
|
||||
if( dirname ) {
|
||||
handle->hFind = FindFirstFile(dirname, &(handle->ffd));
|
||||
}
|
||||
|
||||
if (!dirname || handle->hFind == INVALID_HANDLE_VALUE) {
|
||||
SAFE_FREE(handle);
|
||||
return NULL;
|
||||
}
|
||||
// FIXME: Handle the case of no files in a dir.
|
||||
// dwError = GetLastError();
|
||||
// if (dwError != ERROR_NO_MORE_FILES) {
|
||||
handle->firstFind = 1; // Set a flag that there first fileinfo is available.
|
||||
// }
|
||||
#else
|
||||
dirname = c_utf8_to_locale(name);
|
||||
|
||||
handle->dh = _topendir( dirname );
|
||||
if (handle->dh == NULL) {
|
||||
c_free_locale_string(dirname);
|
||||
SAFE_FREE(handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
handle->path = c_strdup(name);
|
||||
c_free_locale_string(dirname);
|
||||
|
||||
|
@ -83,7 +114,14 @@ int csync_vio_local_closedir(csync_vio_handle_t *dhandle) {
|
|||
}
|
||||
|
||||
handle = (dhandle_t *) dhandle;
|
||||
#ifdef _WIN32
|
||||
// FindClose returns non-zero on success
|
||||
if( FindClose(handle->hFind) != 0 ) {
|
||||
rc = 0;
|
||||
}
|
||||
#else
|
||||
rc = _tclosedir(handle->dh);
|
||||
#endif
|
||||
|
||||
SAFE_FREE(handle->path);
|
||||
SAFE_FREE(handle);
|
||||
|
@ -100,6 +138,39 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
|
|||
handle = (dhandle_t *) dhandle;
|
||||
|
||||
errno = 0;
|
||||
file_stat = csync_vio_file_stat_new();
|
||||
if (file_stat == NULL) {
|
||||
goto err;
|
||||
}
|
||||
file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
|
||||
|
||||
#ifdef _WIN32
|
||||
// the win32 functions get the first valid entry with the opendir
|
||||
// thus we must not jump to next entry if it was the first find.
|
||||
if( handle->firstFind ) {
|
||||
handle->firstFind = 0;
|
||||
} else {
|
||||
if( FindNextFile(handle->hFind, &(handle->ffd)) == 0 ) {
|
||||
// might be error, check!
|
||||
int dwError = GetLastError();
|
||||
if (dwError != ERROR_NO_MORE_FILES) {
|
||||
errno = EACCES; // FIXME: Is this a good errno?
|
||||
goto err;
|
||||
} else {
|
||||
// Normal case that no more is in the dir.
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
file_stat->name = c_utf8_from_locale(handle->ffd.cFileName);
|
||||
|
||||
file_stat->fields |= CSYNC_VIO_FILE_STAT_FIELDS_TYPE;
|
||||
if (handle->ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
file_stat->type = CSYNC_VIO_FILE_TYPE_DIRECTORY;
|
||||
} else {
|
||||
file_stat->type = CSYNC_VIO_FILE_TYPE_REGULAR;
|
||||
}
|
||||
#else
|
||||
dirent = _treaddir(handle->dh);
|
||||
if (dirent == NULL) {
|
||||
if (errno) {
|
||||
|
@ -108,14 +179,7 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
file_stat = csync_vio_file_stat_new();
|
||||
if (file_stat == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
file_stat->name = c_utf8_from_locale(dirent->d_name);
|
||||
file_stat->fields = CSYNC_VIO_FILE_STAT_FIELDS_NONE;
|
||||
|
||||
/* Check for availability of d_type, see manpage. */
|
||||
#ifdef _DIRENT_HAVE_D_TYPE
|
||||
|
@ -142,6 +206,8 @@ csync_vio_file_stat_t *csync_vio_local_readdir(csync_vio_handle_t *dhandle) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif // non WIN32
|
||||
|
||||
return file_stat;
|
||||
|
||||
err:
|
||||
|
|
Loading…
Reference in a new issue