📄 directory_functions.hpp
字号:
if( ERROR_DIR_NOT_EMPTY != removeError &&
ERROR_SHARING_VIOLATION != removeError)
{
dwRet = removeError;
if(NULL != pfn)
{
(void)(*pfn)(param, dir, NULL, dwRet);
}
}
else
{
// It has some contents, so we need to remove them
ss_typename_type_k traits_t::stat_data_type st;
file_path_buffer_t sz;
HANDLE hSrch;
ws_size_t n;
traits_t::str_copy(&sz[0], dir);
traits_t::ensure_dir_end(&sz[0]);
n = traits_t::str_len(sz.c_str());
traits_t::str_cat(&sz[0], traits_t::pattern_all());
hSrch = traits_t::find_first_file(sz.c_str(), &st);
if(INVALID_HANDLE_VALUE == hSrch)
{
dwRet = traits_t::get_last_error();
}
else
{
dwRet = ERROR_SUCCESS;
do
{
if(!traits_t::is_dots(st.cFileName))
{
traits_t::str_copy(&sz[n], st.cFileName);
if(traits_t::is_file(sz.c_str()))
{
// If it's a file, the pfn must be consulted, otherwise
// it's an automatic failure
ws_int_t r = 0;
if( NULL == pfn ||
0 == (r = (*pfn)(param, dir, &st, ERROR_SUCCESS)))
{
dwRet = ERROR_DIR_NOT_EMPTY;
if(NULL != pfn)
{
(void)(*pfn)(param, dir, &st, dwRet);
}
break;
}
else
{
if(r > 0)
{
if(!traits_t::delete_file(sz.c_str()))
{
dwRet = traits_t::get_last_error();
if(NULL != pfn)
{
(void)(*pfn)(param, dir, &st, dwRet);
}
break;
}
}
}
}
else
{
ws_int_t r = 1;
// If it's a directory, then pfn is consulted, otherwise
// it's an automatic attempt to recursively delete
if( NULL != pfn &&
0 == (r = (*pfn)(param, dir, &st, ERROR_SUCCESS)))
{
dwRet = ERROR_DIR_NOT_EMPTY;
if(NULL != pfn)
{
(void)(*pfn)(param, dir, &st, dwRet);
}
break;
}
else
{
if(r > 0)
{
dwRet = remove_directory_recurse_impl(sz.c_str(), pfn, param);
}
}
}
}
} while(traits_t::find_next_file(hSrch, &st));
traits_t::find_file_close(hSrch);
if(ERROR_SUCCESS == dwRet)
{
if(traits_t::remove_directory(dir))
{
if(NULL != pfn)
{
(void)(*pfn)(param, dir, NULL, ERROR_SUCCESS); // Deleted
}
}
else
{
dwRet = traits_t::get_last_error();
}
}
}
}
}
}
}
}
return dwRet;
}
/* /////////////////////////////////////////////////////////////////////////
* Functions
*/
/** \brief Creates the given directory, including all its parent directories, applying
* the given mode.
*
* \ingroup group__library__filesystem
*
* \param dir The path of the directory to create
* \param lpsa The security attributes with which each directory is to be created
*/
inline ws_bool_t create_directory_recurse(ws_char_a_t const* dir, LPSECURITY_ATTRIBUTES lpsa = NULL)
{
return create_directory_recurse_impl(dir, lpsa);
}
/** \brief Creates the given directory, including all its parent directories, applying
* the given mode.
*
* \ingroup group__library__filesystem
*
* \param dir The path of the directory to create
* \param lpsa The security attributes with which each directory is to be created
*/
inline ws_bool_t create_directory_recurse(ws_char_w_t const* dir, LPSECURITY_ATTRIBUTES lpsa = NULL)
{
return create_directory_recurse_impl(dir, lpsa);
}
/** \brief Creates the given directory, including all its parent directories, applying
* the given mode.
*
* \ingroup group__library__filesystem
*
* \param dir The path of the directory to create
* \param lpsa The security attributes with which each directory is to be created
*/
template <ss_typename_param_k S>
inline ws_bool_t create_directory_recurse(S const& dir, LPSECURITY_ATTRIBUTES lpsa = NULL)
{
return create_directory_recurse(stlsoft_ns_qual(c_str_ptr)(dir), lpsa);
}
/** \brief Removes the given directory, and all its subdirectories.
*
* \ingroup group__library__filesystem
*
* \param dir The path of the directory to remove
* \param pfn Pointer to a callback function, which will receive notifications
* and requests for file/directory deletion. The semantics of the
* parameters are specified in the note below
* \param param Caller-supplied parameter, passed through to the callback
* function
*
* \note If no callback function is specified, then the function will remove
* only empty subdirectories, i.e. no files will be removed. To remove
* files, a function must be
*
* \note The semantics of the callback function's parameters are as follows:
* \par If the err param is ~0 (-1 on UNIX), then the dir param specifies
* the name of the current directory being traversed. All other params
* are unspecified. The return value is ignored.
* \par If the err param is 0 and the st param is NULL, then dir specifies
* the name of a directory that has been successfully removed. All
* other params are unspecified. The return value is ignored.
* \par If the err param is 0 and the st param is not NULL, then dir specifies
* the name of the currently traversing directory, st specifies the
* stat information and the name of the entry within directory dir that
* is a candidate for removal. Return >0 to enable removal of this
* entry, or 0 to prevent removal and cancel the overall operation, or
* <0 to prevent removal and continue.
* All other params are unspecified. The return value is ignored.
* \par If the err param is any other value, and the st param is NULL, then
* the dir param specifies the name of a directory that could not be
* deleted and err specifies the errno value associated with the failure.
* All other params are unspecified. The return value is ignored.
* \par If the err param is any other value, and the st param is not NULL, then
* the dir param specifies the name of a directory within which an entry
* could not be deleted, st specifies the stat information and the name
* of the entry that could not be deleted, and err specifies the errno
* value associated with the failure. All other params are unspecified.
* The return value is ignored.
*/
inline ws_bool_t remove_directory_recurse( ws_char_a_t const* dir
, ws_int_t (*pfn)(void* param, ws_char_a_t const* subDir, WIN32_FIND_DATAA const* st, DWORD err)
, void* param)
{
typedef filesystem_traits<ws_char_a_t> traits_t;
ws_dword_t dwRet = remove_directory_recurse_impl<ws_char_a_t, WIN32_FIND_DATAA>(dir, pfn, param);
traits_t::set_last_error(dwRet);
return ERROR_SUCCESS == dwRet;
}
/** \brief Removes the given directory, and all its subdirectories.
*
* \ingroup group__library__filesystem
*/
inline ws_bool_t remove_directory_recurse(ws_char_a_t const* dir)
{
return remove_directory_recurse(dir, NULL, NULL);
}
/** \brief Removes the given directory, and all its subdirectories.
*
* \ingroup group__library__filesystem
*/
inline ws_bool_t remove_directory_recurse( ws_char_w_t const* dir
, ws_int_t (*pfn)(void* param, ws_char_w_t const* subDir, WIN32_FIND_DATAW const* st, DWORD err)
, void* param)
{
typedef filesystem_traits<ws_char_w_t> traits_t;
ws_dword_t dwRet = remove_directory_recurse_impl<ws_char_w_t, WIN32_FIND_DATAW>(dir, pfn, param);
traits_t::set_last_error(dwRet);
return ERROR_SUCCESS == dwRet;
}
/** \brief Removes the given directory, and all its subdirectories.
*
* \ingroup group__library__filesystem
*/
inline ws_bool_t remove_directory_recurse(ws_char_w_t const* dir)
{
return remove_directory_recurse(dir, NULL, NULL);
}
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
/** \brief Removes the given directory, and all its subdirectories.
*
* \ingroup group__library__filesystem
*/
template <ss_typename_param_k S>
inline ws_bool_t remove_directory_recurse(S const& dir)
{
typedef filesystem_traits<ws_char_w_t> traits_t;
ws_dword_t dwRet = remove_directory_recurse(stlsoft_ns_qual(c_str_ptr)(dir), NULL, NULL);
traits_t::set_last_error(dwRet);
return ERROR_SUCCESS == dwRet;
}
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
/* /////////////////////////////////////////////////////////////////////////
* Unit-testing
*/
#ifdef STLSOFT_UNITTEST
# include "./unittest/directory_functions_unittest_.h"
#endif /* STLSOFT_UNITTEST */
/* ////////////////////////////////////////////////////////////////////// */
#ifndef _WINSTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
} // namespace winstl
# else
} // namespace winstl_project
} // namespace stlsoft
# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_WINSTL_NO_NAMESPACE */
/* ////////////////////////////////////////////////////////////////////// */
#endif /* WINSTL_INCL_WINSTL_FILESYSTEM_HPP_DIRECTORY_FUNCTIONS */
/* ////////////////////////////////////////////////////////////////////// */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -