/* Copyright (C) 2015-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk4dirwc.ctr */ /** @file dk4dirwc.c The dk4dirwc module. */ #line 211 "dk4dirwc.ctr" #include "dk4conf.h" #if DK4_ON_WINDOWS #ifndef WINDOWS_H_INCLUDED #include #define WINDOWS_H_INCLUDED 1 #endif #endif #include "dk4dirwc.h" #ifndef DK4DIR_H_INCLUDED #include "dk4dir.h" #endif #ifndef DK4PATHW_H_INCLUDED #include "dk4pathw.h" #endif #ifndef DK4STR8_H_INCLUDED #include "dk4strw.h" #endif #ifndef DK4STAT_H_INCLUDED #include "dk4stat.h" #endif #ifndef DK4STAT8_H_INCLUDED #include "dk4statw.h" #endif #ifndef DK4MEM_H_INCLUDED #include "dk4mem.h" #endif #ifndef DK4MPL_H_INCLUDED #include "dk4mpl.h" #endif #ifndef DK4MAASZ_H_INCLUDED #include "dk4maasz.h" #endif #if DK4_HAVE_SYS_TYPES_H #ifndef SYS_TYPES_H_INCLUDED #include #define SYS_TYPES_H_INCLUDED 1 #endif #endif #if DK4_HAVE_WCHAR_H #ifndef WCHAR_H_INCLUDED #include #define WCHAR_H_INCLUDED 1 #endif #endif #if DK4_HAVE_DIRENT_H #ifndef DIRENT_H_INCLUDED #include #define DIRENT_H_INCLUDED 1 #endif #endif #if DK4_HAVE_ERRNO_H #ifndef ERRNO_H_INCLUDED #include #define ERRNO_H_INCLUDED 1 #endif #endif #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif #include "dk4unused.h" #line 296 "dk4dirwc.ctr" #if DK4_ON_WINDOWS int dk4dir_wc_compare(const void *l, const void *r, int DK4_ARG_UNUSED(cr)) { int back = 0; DK4_UNUSED_ARG(cr) if (NULL != l) { if (NULL != r) { back = dk4strw_pathcmp((const wchar_t *)l, (const wchar_t *)r); } else { back = 1; } } else { if (NULL != r) { back = -1; } } return back; } #endif static void dk4dir_wc_clean_storage(dk4_sto_t *s, dk4_sto_it_t *i) { wchar_t *n; if (NULL != s) { if (NULL != i) { dk4sto_it_reset(i); while (NULL != (n = (wchar_t *)dk4sto_it_next(i))) { dk4mem_free(n); } dk4sto_it_close(i); } dk4sto_close(s); } } void dk4dir_wc_close(dk4_dir_wc_t *dptr) { #if DK4_USE_ASSERT assert(NULL != dptr); #endif if (NULL != dptr) { dk4mem_release(dptr->path); dk4dir_wc_clean_storage(dptr->s_dir, dptr->i_dir); dptr->s_dir = NULL; dptr->i_dir = NULL; dk4dir_wc_clean_storage(dptr->s_file, dptr->i_file); dptr->s_file = NULL; dptr->i_file = NULL; dk4mem_free(dptr); } } #if DK4_ON_WINDOWS /** Fixed texts used by the module. */ static const wchar_t * const dk4dir_wc_kw[] = { /* 0 */ L".", /* 1 */ L"..", /* 2 */ L"/", /* 3 */ L"\\", /* 4 */ L"*", NULL #line 385 "dk4dirwc.ctr" }; static int dk4dir_wc_fill_with_pab( dk4_dir_wc_t *dptr, int om, wchar_t *pab, size_t szpab, dk4_er_t *erp ) { WIN32_FIND_DATAW ffdata; /* Find result */ HANDLE ffres; /* Result from findfirst */ dkChar *nn; /* Copy of name, dyn */ DWORD attr; /* File attributes */ size_t slen; /* Entry name length. */ int isdir; /* Flag: Entry is directory */ int back = 0; #line 407 "dk4dirwc.ctr" #if DK4_USE_ASSERT assert(NULL != dptr); assert(NULL != pab); assert(0 < szpab); #endif if (dk4strw_cpy_s(pab, szpab, dptr->path, erp)) { if (dk4strw_cat_s(pab, szpab, dk4dir_wc_kw[3], erp)) { if (dk4strw_cat_s(pab, szpab, dk4dir_wc_kw[4], erp)) { ffres = FindFirstFileW(pab, &ffdata); if (INVALID_HANDLE_VALUE != ffres) { back = 1; do { if (0 != dk4strw_cmp(dk4dir_wc_kw[0], ffdata.cFileName)) { if (0 != dk4strw_cmp(dk4dir_wc_kw[1], ffdata.cFileName)) { slen = dk4strw_len(ffdata.cFileName); if (slen > dptr->maxlen) { dptr->maxlen = slen; } nn = dk4strw_dup(ffdata.cFileName, erp); if (NULL != nn) { isdir = 0; attr = ffdata.dwFileAttributes; if (0 != (FILE_ATTRIBUTE_DIRECTORY & attr)) { isdir = 1; if (0 != (FILE_ATTRIBUTE_REPARSE_POINT & attr)) { if (0 != (DK4_DIR_SYMLINK_DIR_AS_FILE & om)) { isdir = 0; } } } if (0 != isdir) { if (0 == dk4sto_add(dptr->s_dir, (void *)nn, erp)) { back = 0; dk4mem_free(nn); } } else { if (0 == dk4sto_add(dptr->s_file, (void *)nn, erp)) { back = 0; dk4mem_free(nn); } } } else { back = 0; } } } } while(FindNextFileW(ffres, &ffdata)); FindClose(ffres); } else { /* ERROR: FindFirstFile failed */ dk4error_set_ldetails( erp, DK4_E_FINDFIRSTFILE_FAILED, (long)((unsigned long)GetLastError()) ); } } } } #line 464 "dk4dirwc.ctr" return back; } static int dk4dir_wc_fill_with_local(dk4_dir_wc_t *dptr, int om, dk4_er_t *erp) { wchar_t pab[DK4_MAX_PATH]; #if DK4_USE_ASSERT assert(NULL != dptr); #endif return (dk4dir_wc_fill_with_pab(dptr, om, pab, DK4_SIZEOF(pab,wchar_t), erp)); } /** Fill directory structure with data about subdirectories and files. @param dptr Directory structure to fill. @param om Opening mode. @param erp Error report, may be NULL. @return 1 on success, 0 on errors. */ static int dk4dir_wc_fill_directory(dk4_dir_wc_t *dptr, int om, dk4_er_t *erp) { dk4_er_t er; wchar_t *pab; size_t dptrlgt; int back = 0; #if DK4_USE_ASSERT assert(NULL != dptr); #endif dptrlgt = dk4strw_len(dptr->path); if ((DK4_MAX_PATH - 2) > dptrlgt) { back = dk4dir_wc_fill_with_local(dptr, om, erp); } else { dk4error_init(&er); dptrlgt = dk4ma_size_t_add(dptrlgt, 3, &er); if (DK4_E_NONE == er.ec) { pab = dk4mem_new(wchar_t, dptrlgt, erp); if (NULL != pab) { back = dk4dir_wc_fill_with_pab(dptr, om, pab, dptrlgt, erp); dk4mem_free(pab); } } else { dk4error_copy(erp, &er); } } return back; } #endif dk4_dir_wc_t * dk4dir_wc_open( const wchar_t *path, #if DK4_ON_WINDOWS int om, #else int DK4_ARG_UNUSED(om), #endif dk4_er_t *erp ) { dk4_dir_wc_t *back = NULL; #if DK4_ON_WINDOWS int ok = 0; #endif #if DK4_USE_ASSERT assert(NULL != path); #endif if (NULL != path) { #if DK4_ON_WINDOWS back = dk4mem_new(dk4_dir_wc_t, 1, erp); if (NULL != back) { back->path = NULL; back->s_dir = NULL; back->i_dir = NULL; back->s_file = NULL; back->i_file = NULL; back->path = dk4strw_dup(path, erp); back->maxlen = 0; if (NULL != back->path) { back->s_dir = dk4sto_open(erp); if (NULL != back->s_dir) { if (0 != (DK4_DIR_OPEN_SORTED & om)) { dk4sto_set_comp(back->s_dir, dk4dir_wc_compare, 0); } back->i_dir = dk4sto_it_open(back->s_dir, erp); if (NULL != back->i_dir) { back->s_file = dk4sto_open(erp); if (NULL != back->s_file) { if (0 != (DK4_DIR_OPEN_SORTED & om)) { dk4sto_set_comp(back->s_file, dk4dir_wc_compare, 0); } back->i_file = dk4sto_it_open(back->s_file, erp); if (NULL != back->i_file) { ok = dk4dir_wc_fill_directory(back, om, erp); } } } } } if (0 == ok) { dk4dir_wc_close(back); back = NULL; } } #else DK4_UNUSED_ARG(om) dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; } void dk4dir_wc_reset(dk4_dir_wc_t *dptr) { #if DK4_USE_ASSERT assert(NULL != dptr); #endif if (NULL != dptr) { if ((NULL != dptr->s_dir) && (NULL != dptr->i_dir)) { dk4sto_it_reset(dptr->i_dir); } if ((NULL != dptr->s_file) && (NULL != dptr->i_file)) { dk4sto_it_reset(dptr->i_file); } } } const wchar_t * dk4dir_wc_get_path(dk4_dir_wc_t const *dptr) { const wchar_t *back = NULL; #if DK4_USE_ASSERT assert(NULL != dptr); #endif if (NULL != dptr) { back = (const wchar_t *)(dptr->path); } return back; } const wchar_t * dk4dir_wc_next_dir(dk4_dir_wc_t *dptr) { const wchar_t *back = NULL; #if DK4_USE_ASSERT assert(NULL != dptr); #endif if (NULL != dptr) { if ((NULL != dptr->s_dir) && (NULL != dptr->i_dir)) { back = (const wchar_t *)dk4sto_it_next(dptr->i_dir); } } return back; } const wchar_t * dk4dir_wc_next_file(dk4_dir_wc_t *dptr) { const wchar_t *back = NULL; #if DK4_USE_ASSERT assert(NULL != dptr); #endif if (NULL != dptr) { if ((NULL != dptr->s_file) && (NULL != dptr->i_file)) { back = (const wchar_t *)dk4sto_it_next(dptr->i_file); } } return back; } void dk4dir_wc_skip_files(dk4_dir_wc_t *dptr) { #if DK4_USE_ASSERT assert(NULL != dptr); #endif if (NULL != dptr) { dk4dir_wc_clean_storage(dptr->s_file, dptr->i_file); dptr->s_file = NULL; dptr->i_file = NULL; } } size_t dk4dir_wc_get_max_entry_length(dk4_dir_wc_t const *dptr) { size_t back = 0; #if DK4_USE_ASSERT assert(NULL != dptr); #endif if (NULL != dptr) { back = dptr->maxlen; } return back; } int dk4dir_wc_full_name_buffer( wchar_t *buffer, size_t szbuf, dk4_dir_wc_t const *pdir, wchar_t const *fn, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != pdir); assert(NULL != fn); assert(NULL != buffer); assert(0 < szbuf); #endif if ((NULL != buffer) && (NULL != pdir) && (NULL != fn) && (0 < szbuf)) { back = dk4pathw_concatenate_buffer(buffer, szbuf, pdir->path, fn, erp); } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; } wchar_t * dk4dir_wc_full_name_new( dk4_dir_wc_t const *pdir, wchar_t const *fn, dk4_er_t * erp ) { wchar_t *back = NULL; #if DK4_USE_ASSERT assert(NULL != pdir); assert(NULL != fn); #endif if ((NULL != pdir) && (NULL != fn)) { back = dk4pathw_concatenate_new(pdir->path, fn, erp); } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; }