remove() implementation for Windows XP and older
| 1824 | |
| 1825 | //! remove() implementation for Windows XP and older |
| 1826 | bool remove_nt5_impl(path const& p, DWORD attrs, error_code* ec) |
| 1827 | { |
| 1828 | const bool is_directory = (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0; |
| 1829 | const bool is_read_only = (attrs & FILE_ATTRIBUTE_READONLY) != 0; |
| 1830 | if (is_read_only) |
| 1831 | { |
| 1832 | // RemoveDirectoryW and DeleteFileW do not allow to remove a read-only file, so we have to drop the attribute |
| 1833 | DWORD new_attrs = attrs & ~FILE_ATTRIBUTE_READONLY; |
| 1834 | BOOL res = ::SetFileAttributesW(p.c_str(), new_attrs); |
| 1835 | if (BOOST_UNLIKELY(!res)) |
| 1836 | { |
| 1837 | DWORD err = ::GetLastError(); |
| 1838 | if (!not_found_error(err)) |
| 1839 | emit_error(err, p, ec, "boost::filesystem::remove"); |
| 1840 | |
| 1841 | return false; |
| 1842 | } |
| 1843 | } |
| 1844 | |
| 1845 | BOOL res; |
| 1846 | if (!is_directory) |
| 1847 | { |
| 1848 | // DeleteFileW works for file symlinks by removing the symlink, not the target. |
| 1849 | res = ::DeleteFileW(p.c_str()); |
| 1850 | } |
| 1851 | else |
| 1852 | { |
| 1853 | // RemoveDirectoryW works for symlinks and junctions by removing the symlink, not the target, |
| 1854 | // even if the target directory is not empty. |
| 1855 | // Note that unlike opening the directory with FILE_FLAG_DELETE_ON_CLOSE flag, RemoveDirectoryW |
| 1856 | // will fail if the directory is not empty. |
| 1857 | res = ::RemoveDirectoryW(p.c_str()); |
| 1858 | } |
| 1859 | |
| 1860 | if (BOOST_UNLIKELY(!res)) |
| 1861 | { |
| 1862 | DWORD err = ::GetLastError(); |
| 1863 | if (!not_found_error(err)) |
| 1864 | { |
| 1865 | if (is_read_only) |
| 1866 | { |
| 1867 | // Try to restore the read-only attribute |
| 1868 | ::SetFileAttributesW(p.c_str(), attrs); |
| 1869 | } |
| 1870 | |
| 1871 | emit_error(err, p, ec, "boost::filesystem::remove"); |
| 1872 | } |
| 1873 | |
| 1874 | return false; |
| 1875 | } |
| 1876 | |
| 1877 | return true; |
| 1878 | } |
| 1879 | |
| 1880 | //! remove() by handle implementation for Windows Vista and newer |
| 1881 | DWORD remove_nt6_by_handle(HANDLE handle, remove_impl_type impl) |
no test coverage detected