Beispiel #1
0
static void test_RemoveDirectoryW(void)
{
    WCHAR tmpdir[MAX_PATH];
    BOOL ret;
    static const WCHAR tmp_dir_name[] = {'P','l','e','a','s','e',' ','R','e','m','o','v','e',' ','M','e',0};
    static const WCHAR questionW[] = {'?',0};

    GetTempPathW(MAX_PATH, tmpdir);
    lstrcatW(tmpdir, tmp_dir_name);
    ret = CreateDirectoryW(tmpdir, NULL);
    if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
    {
        win_skip("CreateDirectoryW is not available\n");
        return;
    }

    ok(ret == TRUE, "CreateDirectoryW should always succeed\n");

    ret = RemoveDirectoryW(tmpdir);
    ok(ret == TRUE, "RemoveDirectoryW should always succeed\n");

    lstrcatW(tmpdir, questionW);
    ret = RemoveDirectoryW(tmpdir);
    ok(ret == FALSE && GetLastError() == ERROR_INVALID_NAME,
       "RemoveDirectoryW with wildcard should fail with error 183, ret=%s error=%d\n",
       ret ? " True" : "False", GetLastError());

    tmpdir[lstrlenW(tmpdir) - 1] = '*';
    ret = RemoveDirectoryW(tmpdir);
    ok(ret == FALSE && GetLastError() == ERROR_INVALID_NAME,
       "RemoveDirectoryW with * wildcard name should fail with error 183, ret=%s error=%d\n",
       ret ? " True" : "False", GetLastError());
}
Beispiel #2
0
BOOL WINAPI ResilientRemoveDirectoryW(
    LPCWSTR lpPathName)
{
    BOOL Success;
    DWORD LastError;

    Success = RemoveDirectoryW(lpPathName);
    LastError = GetLastError();

    if (Success)
        WaitDeletePending(lpPathName);
    else
    {
        for (ULONG MaxTries = DeleteMaxTries;
            !Success && ERROR_SHARING_VIOLATION == GetLastError() && 0 != MaxTries;
            MaxTries--)
        {
            Sleep(DeleteSleepTimeout);
            Success = RemoveDirectoryW(lpPathName);
        }
    }

    SetLastError(LastError);
    return Success;
}
Beispiel #3
0
void removeAll()
{
    RemoveDirectoryW(szDirName);
    RemoveDirectoryW(szDirName_02);

    DeleteFileW(szFindName);
    DeleteFileW(szFindName_02);
    DeleteFileW(szFindName_03);
}
	/*!
	 * Removes the existing empty directory.
	 *
	 * @param directoryName Path to the directory.
	 * @returns True if directory was successfully deleted.
	 */
	GDAPI bool FileUtilitiesWindows::DirectoryRemove(WideString const& directoryName)
	{
		auto const directoryNameSystem = Paths::Platformize(directoryName);
		if (RemoveDirectoryW(directoryNameSystem.CStr()) == FALSE)
		{
			Sleep(0);
			return RemoveDirectoryW(directoryNameSystem.CStr()) == TRUE;
		}
		return false;
	}
bool os_remove_nonempty_dir(const std::wstring &path)
{
	WIN32_FIND_DATAW wfd; 
	HANDLE hf=FindFirstFileW((path+L"\\*").c_str(), &wfd);
	BOOL b=true;
	while( b )
	{
		if( (std::wstring)wfd.cFileName!=L"." && (std::wstring)wfd.cFileName!=L".." )
		{
			if(	wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
			{
				os_remove_nonempty_dir(path+L"\\"+wfd.cFileName);
			}
			else
			{
				DeleteFileW((path+L"\\"+wfd.cFileName).c_str());
			}
		}
		b=FindNextFileW(hf,&wfd);			
	}

	FindClose(hf);
	RemoveDirectoryW(path.c_str());
	return true;
}
Beispiel #6
0
bool tr_sys_path_remove(char const* path, tr_error** error)
{
    TR_ASSERT(path != NULL);

    bool ret = false;
    wchar_t* wide_path = path_to_native_path(path);

    if (wide_path != NULL)
    {
        DWORD const attributes = GetFileAttributesW(wide_path);

        if (attributes != INVALID_FILE_ATTRIBUTES)
        {
            if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
            {
                ret = RemoveDirectoryW(wide_path);
            }
            else
            {
                ret = DeleteFileW(wide_path);
            }
        }
    }

    if (!ret)
    {
        set_system_error(error, GetLastError());
    }

    tr_free(wide_path);

    return ret;
}
Beispiel #7
0
int32_t
omrfile_unlinkdir(struct OMRPortLibrary *portLibrary, const char *path)
{
	wchar_t unicodeBuffer[UNICODE_BUFFER_SIZE], *unicodePath;
	BOOL result;

	/* Convert the filename from UTF8 to Unicode */
	unicodePath = file_get_unicode_path(portLibrary, path, unicodeBuffer, UNICODE_BUFFER_SIZE);
	if (NULL == unicodePath) {
		return -1;
	}

	/*PR 93036 - should be able to delete read-only dirs, so we set the file attribute back to normal*/
	if (0 == SetFileAttributesW(unicodePath, FILE_ATTRIBUTE_NORMAL)) {
		int32_t error = GetLastError();
		portLibrary->error_set_last_error(portLibrary, error, findError(error));	 /* continue */
	}

	result = RemoveDirectoryW(unicodePath);
	if (unicodeBuffer != unicodePath) {
		portLibrary->mem_free_memory(portLibrary, unicodePath);
	}

	if (!result) {
		int32_t error = GetLastError();
		portLibrary->error_set_last_error(portLibrary, error, findError(error));
		return -1;
	}
	return 0;
}
Beispiel #8
0
bool CFileAccess::remove(const char *file, bool recursive /* = false */)
{
	Win32Wide wfile(file);
	DWORD att = GetFileAttributesW(wfile);
	if(att==0xFFFFFFFF)
		return false;
	SetFileAttributesW(wfile,att&~FILE_ATTRIBUTE_READONLY);
	if(att&FILE_ATTRIBUTE_DIRECTORY)
	{
		if(!recursive)
		{
			if(!RemoveDirectoryW(wfile))
				return false;
		}
		else
		{
			cvs::wstring wpath = wfile;
			if(!_remove(wpath))
				return false;
		}
	}
	else
	{
		if(!DeleteFileW(wfile))
			return false;
	}
	return true;
}
Beispiel #9
0
/*********************************************************************
 *		_wrmdir (MSVCRT.@)
 *
 * Unicode version of _rmdir.
 */
int CDECL MSVCRT__wrmdir(const MSVCRT_wchar_t * dir)
{
  if (RemoveDirectoryW(dir))
    return 0;
  msvcrt_set_errno(GetLastError());
  return -1;
}
Beispiel #10
0
static void exec_rename_dir_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout)
{
    void *memfs = memfs_start_ex(Flags, FileInfoTimeout);

    WCHAR Dir1Path[MAX_PATH], Dir2Path[MAX_PATH], FilePath[MAX_PATH];
    HANDLE Process;

    StringCbPrintfW(Dir1Path, sizeof Dir1Path, L"%s%s\\dir1",
        Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));

    StringCbPrintfW(Dir2Path, sizeof Dir2Path, L"%s%s\\dir2",
        Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));

    StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\dir1\\helper.exe",
        Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));

    ASSERT(CreateDirectoryW(Dir1Path, 0));

    ExecHelper(FilePath, 2000, &Process);

    Sleep(1000); /* give time for file handles to be closed (FlushAndPurgeOnCleanup) */

    ASSERT(MoveFileExW(Dir1Path, Dir2Path, MOVEFILE_REPLACE_EXISTING));
    ASSERT(MoveFileExW(Dir2Path, Dir1Path, MOVEFILE_REPLACE_EXISTING));

    WaitHelper(Process, 2000);

    ASSERT(DeleteFileW(FilePath));

    ASSERT(RemoveDirectoryW(Dir1Path));

    memfs_stop(memfs);
}
Beispiel #11
0
bool RemoveDirectoryIfExists(const char* path)
{
    AWS_LOGSTREAM_INFO(FILE_SYSTEM_UTILS_LOG_TAG, "Removing directory at " << path);

    if(RemoveDirectoryW(ToLongPath(Aws::Utils::StringUtils::ToWString(path)).c_str()))
    {
        AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG,  "The remove operation of file at " << path << " Succeeded.");
        return true;
    }
    else
    {
        int errorCode = GetLastError();
        if (errorCode == ERROR_DIR_NOT_EMPTY)
        {
            AWS_LOGSTREAM_ERROR(FILE_SYSTEM_UTILS_LOG_TAG, "The remove operation of file at " << path << " failed. with error code because it was not empty.");
        }

        else if(errorCode == ERROR_DIRECTORY)
        {
            AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG, "The deletion of directory at " << path << " failed because it doesn't exist.");
            return true;

        }

        AWS_LOGSTREAM_DEBUG(FILE_SYSTEM_UTILS_LOG_TAG,  "The remove operation of file at " << path << " failed. with error code " << errorCode);
        return false;
    }
}
void  CDownloadOperation::deleteDirectoryW(LPWSTR path)
{
	WIN32_FIND_DATAW  fw;
	std::wstring wstrPath = path ;
	wstrPath              += L"*.*";
	HANDLE hFind= FindFirstFileW(wstrPath.c_str(), &fw);

	if(hFind == INVALID_HANDLE_VALUE)
		return ;

	do
	{
		if(wcscmp(fw.cFileName,L".") == 0 || wcscmp(fw.cFileName,L"..") == 0 || wcscmp(fw.cFileName,L".svn") == 0)
			continue;

		if(fw.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			std::wstring wstrDirectory = path;
			wstrDirectory             += fw.cFileName;
			wstrDirectory             += L"\\";
	
			deleteDirectoryW((LPWSTR)wstrDirectory.c_str());
			RemoveDirectoryW(wstrDirectory.c_str() );
		}
		else
		{
			std::wstring existingFile = path;
			existingFile += fw.cFileName;
			DeleteFileW(existingFile.c_str() );
		}
	}
	while( FindNextFile(hFind,&fw) );  

	FindClose(hFind);
}
Beispiel #13
0
/*
 * Arguments: path (string)
 * Returns: [boolean]
 */
static int
sys_rmdir (lua_State *L)
{
  const char *path = luaL_checkstring(L, 1);
  int res;

#ifndef _WIN32
  sys_vm_leave(L);
  res = rmdir(path);
  sys_vm_enter(L);
#else
  {
    void *os_path = utf8_to_filename(path);
    if (!os_path)
      return sys_seterror(L, ERROR_NOT_ENOUGH_MEMORY);

    sys_vm_leave(L);
    res = is_WinNT
     ? !RemoveDirectoryW(os_path)
     : !RemoveDirectoryA(os_path);

    free(os_path);
    sys_vm_enter(L);
  }
#endif
  if (!res) {
    lua_pushboolean(L, 1);
    return 1;
  }
  return sys_seterror(L, 0);
}
bool
HostFolder::remove(const std::string &name)
{
   auto hostPath = mPath.join(name);
   auto winPath = platform::toWinApiString(hostPath.path());
   auto child = findChild(name);

   if (!child) {
      // File / Directory does not exist, nothing to do
      return true;
   }

   if (!checkPermission(Permissions::Write)) {
      return false;
   }

   auto removed = false;

   if (child->type() == NodeType::FileNode) {
      removed = !!DeleteFileW(winPath.c_str());
   } else if (child->type() == NodeType::FolderNode) {
      removed = !!RemoveDirectoryW(winPath.c_str());
   }

   if (removed) {
      mVirtual.deleteChild(child);
   }

   return removed;
}
Beispiel #15
0
bool
tr_sys_path_remove (const char  * path,
                    tr_error   ** error)
{
  bool ret = false;
  wchar_t * wide_path;

  assert (path != NULL);

  wide_path = tr_win32_utf8_to_native (path, -1);

  if (wide_path != NULL)
    {
      const DWORD attributes = GetFileAttributesW (wide_path);

      if (attributes != INVALID_FILE_ATTRIBUTES)
        {
          if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
            ret = RemoveDirectoryW (wide_path);
          else
            ret = DeleteFileW (wide_path);
        }
    }

  if (!ret)
    set_system_error (error, GetLastError ());

  tr_free (wide_path);

  return ret;
}
Beispiel #16
0
bool File::remove_dir_nt(const wstring& file_path) {
  ArclitePrivateInfo* system_functions = Far::get_system_functions();
  if (system_functions)
    return system_functions->RemoveDirectory(long_path(file_path).c_str()) != 0;
  else
    return RemoveDirectoryW(long_path(file_path).c_str()) != 0;
}
Beispiel #17
0
HRESULT __cdecl SchRpcDelete(const WCHAR *path, DWORD flags)
{
    WCHAR *full_name;
    HRESULT hr = S_OK;

    TRACE("%s,%#x\n", debugstr_w(path), flags);

    if (flags) return E_INVALIDARG;

    while (*path == '\\' || *path == '/') path++;
    if (!*path) return E_ACCESSDENIED;

    full_name = get_full_name(path, NULL);
    if (!full_name) return E_OUTOFMEMORY;

    if (!RemoveDirectoryW(full_name))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        if (hr == HRESULT_FROM_WIN32(ERROR_DIRECTORY))
            hr = DeleteFileW(full_name) ? S_OK : HRESULT_FROM_WIN32(GetLastError());
    }

    heap_free(full_name);
    return hr;
}
Beispiel #18
0
int
iop_rmdir(io_args_t *const args)
{
	const char *const path = args->arg1.path;

	int result;

	ioeta_update(args->estim, path, path, 0, 0);

#ifndef _WIN32
	result = rmdir(path);
	if(result != 0)
	{
		(void)ioe_errlst_append(&args->result.errors, path, errno, strerror(errno));
	}
#else
	{
		wchar_t *const utf16_path = utf8_to_utf16(path);
		result = RemoveDirectoryW(utf16_path) == 0;

		if(result)
		{
			/* FIXME: use real system error message here. */
			(void)ioe_errlst_append(&args->result.errors, path, IO_ERR_UNKNOWN,
					"Directory removal failed");
		}

		free(utf16_path);
	}
#endif

	ioeta_update(args->estim, NULL, NULL, 1, 0);

	return result;
}
Beispiel #19
0
bool fs::remove_dir(const std::string& path)
{
	if (auto device = get_virtual_device(path))
	{
		return device->remove_dir(path);
	}

#ifdef _WIN32
	if (!RemoveDirectoryW(to_wchar(path).get()))
	{
		g_tls_error = to_error(GetLastError());
		return false;
	}

	return true;
#else
	if (::rmdir(path.c_str()) != 0)
	{
		g_tls_error = to_error(errno);
		return false;
	}

	return true;
#endif
}
Beispiel #20
0
static int win_RemoveDir(lua_State *L)
{
	if(RemoveDirectoryW(check_utf8_string(L, 1, NULL)))
		return lua_pushboolean(L, 1), 1;

	return SysErrorReturn(L);
}
Beispiel #21
0
static int doPlatformDelete(LPWSTR wpath)
{
    const int isdir = (GetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY);
    const BOOL rc = (isdir) ? RemoveDirectoryW(wpath) : DeleteFileW(wpath);
    BAIL_IF_MACRO(!rc, errcodeFromWinApi(), 0);
    return 1;   /* if you made it here, it worked. */
} /* doPlatformDelete */
Beispiel #22
0
BOOL msi_remove_directory( MSIPACKAGE *package, const WCHAR *path )
{
    BOOL ret;
    msi_disable_fs_redirection( package );
    ret = RemoveDirectoryW( path );
    msi_revert_fs_redirection( package );
    return ret;
}
Beispiel #23
0
static int do_RemoveDirectory(int argc, wchar_t **argv)
{
    if (argc != 2)
        fail("usage: RemoveDirectory PathName");
    BOOL r = RemoveDirectoryW(argv[1]);
    errprint(r);
    return 0;
}
 BOOL
 WINAPI
 MyRemoveDirectoryA(
     __in LPCSTR lpPathName
     )
 {
     return RemoveDirectoryW( FromUTF8( lpPathName ) );
 }
Beispiel #25
0
    bool DirectoryInfo::RemoveDirectoryA(LPCSTR dirName,bool recursive)
    { WCHAR dirNameW[MAX_PATH];

      if( NULL!=dirName )
      { THROW_LASTERROREXCEPTION1( ::MultiByteToWideChar( CP_ACP, 0, dirName, -1,dirNameW, MAX_PATH) ); }

      return dirName!=NULL ? RemoveDirectoryW(dirNameW,recursive) : false;;
    } // of DirectoryInfo::RemoveDirectoryA()
bool DirMan::rmAbsPath(const std::string &dirPath)
{
    BOOL ret = TRUE;
    struct DirStackEntry
    {
        std::wstring path;
        HANDLE hFind;
        WIN32_FIND_DATAW data;
    };

    std::stack<DirStackEntry> dirStack;
    DirStackEntry ds;
    ds.hFind = NULL;
    memset(&ds.data, 0, sizeof(WIN32_FIND_DATAW));
    ds.path = Str2WStr(dirPath);
    dirStack.push(ds);

    while(!dirStack.empty())
    {
        DirStackEntry *e = &dirStack.top();
        e->hFind = FindFirstFileW((e->path + L"/*").c_str(), &e->data);
        bool walkUp = false;
        if(e->hFind != INVALID_HANDLE_VALUE)
        {
            do
            {
                if((wcscmp(e->data.cFileName, L"..") == 0) || (wcscmp(e->data.cFileName, L".") == 0))
                    continue;
                std::wstring path = e->path + L"/" + e->data.cFileName;

                if((e->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
                {
                    FindClose(e->hFind);
                    ds.path = path;
                    dirStack.push(ds);
                    walkUp = true;
                    break;
                }
                else
                {
                    if(DeleteFileW(path.c_str()) == FALSE)
                        ret = FALSE;
                }
            }
            while(FindNextFileW(e->hFind, &e->data));
        }

        if(!walkUp)
        {
            if(e->hFind) FindClose(e->hFind);
            if(RemoveDirectoryW(e->path.c_str()) == FALSE)
                ret = FALSE;
            e = NULL;
            dirStack.pop();
        }
    }
    return (ret == TRUE);
}
Beispiel #27
0
static bool _recursive_delete_directory(WCHAR *directory)
{
	if (directory == NULL) {
		return false;
	}
	WCHAR find_pattern[MAX_PATH];
	wcsncpy(find_pattern, directory, MAX_PATH);
	wcsncat(find_pattern, L"\\*", MAX_PATH);
	WCHAR dir_path[MAX_PATH];
	wcsncpy(dir_path, directory, MAX_PATH);
	wcsncat(dir_path, L"\\", MAX_PATH);
	WCHAR file_path[MAX_PATH];
	wcsncpy(file_path, dir_path, MAX_PATH);
	DWORD err;

	WIN32_FIND_DATAW find_data;
	HANDLE find_handle = FindFirstFileW(find_pattern, &find_data);
	if (find_handle == INVALID_HANDLE_VALUE) {
		err = GetLastError();
		char *error_message = oscap_windows_error_message(err);
		oscap_seterr(OSCAP_EFAMILY_WINDOWS, "FindFirstFileW error: %s", error_message);
		free(error_message);
		return false;
	}

	do {
		if (wcscmp(find_data.cFileName, L".") != 0 && wcscmp(find_data.cFileName, L"..") != 0) {
			wcsncat(file_path, find_data.cFileName, MAX_PATH);
			if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
				if (!_recursive_delete_directory(file_path)) {
					FindClose(find_handle);
					return false;
				}
			} else {
				if (!DeleteFileW(file_path)) {
					err = GetLastError();
					char *error_message = oscap_windows_error_message(err);
					oscap_seterr(OSCAP_EFAMILY_WINDOWS, "DeleteFileW Error: %s", error_message);
					free(error_message);
					FindClose(find_handle);
					return false;
				}
			}
			wcsncpy(file_path, dir_path, MAX_PATH);
		}
	} while (FindNextFileW(find_handle, &find_data) != 0);
	FindClose(find_handle);

	if (!RemoveDirectoryW(dir_path)) {
		err = GetLastError();
		char *error_message = oscap_windows_error_message(err);
		oscap_seterr(OSCAP_EFAMILY_WINDOWS, "RemoveDirectoryW error: %s", error_message);
		free(error_message);
		return false;
	}

	return true;
}
Beispiel #28
0
CAMLprim value win_rmdir(value path, value wpath)
{
  CAMLparam2(path, wpath);
  if (!RemoveDirectoryW((LPWSTR)String_val(wpath))) {
    win32_maperr (GetLastError ());
    uerror("rmdir", path);
  }
  CAMLreturn (Val_unit);
}
bool os_link_symbolic_junctions(const std::wstring &target, const std::wstring &lname)
{
	bool ret=false;
	std::wstring wtarget=target;
	HANDLE hJunc=INVALID_HANDLE_VALUE;
	char *buf=NULL;

	if(wtarget.find(os_file_prefix(L""))==0)
		wtarget.erase(0, os_file_prefix(L"").size());
	if(!wtarget.empty() && wtarget[0]!='\\')
		wtarget=L"\\??\\"+wtarget;
	if(!wtarget.empty() && wtarget[target.size()-1]!='\\')
		wtarget+=L"\\";

	if(!CreateDirectoryW(lname.c_str(), NULL) )
	{
		goto cleanup;
	}

	hJunc=CreateFileW(lname.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL);
	if(hJunc==INVALID_HANDLE_VALUE)
		goto cleanup;

	size_t bsize=sizeof(REPARSE_MOUNTPOINT_DATA_BUFFER) + (wtarget.size()+1) * sizeof(wchar_t)+30;
	buf=new char[bsize];
	memset(buf, 0, bsize);

	REPARSE_MOUNTPOINT_DATA_BUFFER *rb=(REPARSE_MOUNTPOINT_DATA_BUFFER*)buf;
	rb->ReparseTag=IO_REPARSE_TAG_MOUNT_POINT;
	rb->ReparseTargetMaximumLength=(WORD)((wtarget.size()+1)*sizeof(wchar_t));
	rb->ReparseTargetLength=rb->ReparseTargetMaximumLength-1*sizeof(wchar_t);
	rb->ReparseDataLength=rb->ReparseTargetLength+12;
	memcpy(rb->ReparseTarget, wtarget.c_str(), rb->ReparseTargetMaximumLength);

	DWORD bytes_ret;
	if(!DeviceIoControl(hJunc, FSCTL_SET_REPARSE_POINT, rb, rb->ReparseDataLength+REPARSE_MOUNTPOINT_HEADER_SIZE, NULL, 0, &bytes_ret, NULL) )
	{
		goto cleanup;
	}
	ret=true;

cleanup:
	if(!ret)
	{
		#ifndef OS_FUNC_NO_SERVER
		Server->Log("Creating junction failed. Last error="+nconvert((int)GetLastError()), LL_ERROR);
		#endif
	}
	delete []buf;
	if(hJunc!=INVALID_HANDLE_VALUE)
		CloseHandle(hJunc);
	if(!ret)
	{
		RemoveDirectoryW(lname.c_str());
	}
	return ret;
}
Beispiel #30
0
int FSSys::RmDir( FSPath& path, int* err, FSCInfo* info )
{
	std::vector<wchar_t> sp = SysPathStr( _drive, path.GetUnicode( '\\' ) );

	if ( RemoveDirectoryW( sp.data() ) ) { return 0; }

	DWORD lastError  = GetLastError();

	if ( lastError == ERROR_ACCESS_DENIED ) //возможно read only аттрибут, пытаемся сбросить
	{
		if ( SetFileAttributesW( sp.data(), 0 ) && RemoveDirectoryW( sp.data() ) ) { return 0; }

		lastError  = GetLastError();
	}

	SetError( err, lastError );
	return -1;
}