示例#1
1
文件: move.c 项目: RPG-7/reactos
/*
 * @implemented
 */
BOOL
WINAPI
ReplaceFileA(IN LPCSTR lpReplacedFileName,
             IN LPCSTR lpReplacementFileName,
             IN LPCSTR lpBackupFileName OPTIONAL,
             IN DWORD dwReplaceFlags,
             IN LPVOID lpExclude,
             IN LPVOID lpReserved)
{
    BOOL Ret;
    UNICODE_STRING ReplacedFileNameW, ReplacementFileNameW, BackupFileNameW;

    if (!lpReplacedFileName || !lpReplacementFileName || lpExclude || lpReserved || dwReplaceFlags & ~(REPLACEFILE_WRITE_THROUGH | REPLACEFILE_IGNORE_MERGE_ERRORS))
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (!Basep8BitStringToDynamicUnicodeString(&ReplacedFileNameW, lpReplacedFileName))
    {
        return FALSE;
    }

    if (!Basep8BitStringToDynamicUnicodeString(&ReplacementFileNameW, lpReplacementFileName))
    {
        RtlFreeUnicodeString(&ReplacedFileNameW);
        return FALSE;
    }

    if (lpBackupFileName)
    {
        if (!Basep8BitStringToDynamicUnicodeString(&BackupFileNameW, lpBackupFileName))
        {
            RtlFreeUnicodeString(&ReplacementFileNameW);
            RtlFreeUnicodeString(&ReplacedFileNameW);
            return FALSE;
        }
    }
    else
    {
        BackupFileNameW.Buffer = NULL;
    }

    Ret = ReplaceFileW(ReplacedFileNameW.Buffer, ReplacementFileNameW.Buffer, BackupFileNameW.Buffer, dwReplaceFlags, 0, 0);

    if (lpBackupFileName)
    {
        RtlFreeUnicodeString(&BackupFileNameW);
    }
    RtlFreeUnicodeString(&ReplacementFileNameW);
    RtlFreeUnicodeString(&ReplacedFileNameW);

    return Ret;
}
void FileAccessWindows::close() {

    if (!f)
        return;

    fclose(f);
    f = NULL;

    if (save_path!="") {

        //unlink(save_path.utf8().get_data());
        //print_line("renaming..");
        //_wunlink(save_path.c_str()); //unlink if exists
        //int rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str());


        bool rename_error;
        if (!PathFileExistsW(save_path.c_str())) {
            //creating new file
            rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str())!=0;
        } else {
            //atomic replace for existing file
            rename_error = !ReplaceFileW(save_path.c_str(), (save_path+".tmp").c_str(), NULL, 2|4, NULL, NULL);
        }
        save_path="";
        ERR_FAIL_COND( rename_error );
    }


}
示例#3
0
int os_safe_replace(const char *target, const char *from, const char *backup)
{
	wchar_t *wtarget = NULL;
	wchar_t *wfrom = NULL;
	wchar_t *wbackup = NULL;
	int code = -1;

	if (!target || !from)
		return -1;
	if (!os_utf8_to_wcs_ptr(target, 0, &wtarget))
		return -1;
	if (!os_utf8_to_wcs_ptr(from, 0, &wfrom))
		goto fail;
	if (backup && !os_utf8_to_wcs_ptr(backup, 0, &wbackup))
		goto fail;

	if (ReplaceFileW(wtarget, wfrom, wbackup, 0, NULL, NULL)) {
		code = 0;
	} else if (GetLastError() == ERROR_FILE_NOT_FOUND) {
		code = MoveFileExW(wfrom, wtarget, MOVEFILE_REPLACE_EXISTING)
			? 0 : -1;
	}

fail:
	bfree(wtarget);
	bfree(wfrom);
	bfree(wbackup);
	return code;
}
示例#4
0
void FileAccessWindows::close() {

	if (!f)
		return;

	fclose(f);
	f = NULL;

	if (save_path!="") {

		//unlink(save_path.utf8().get_data());
		//print_line("renaming..");
		//_wunlink(save_path.c_str()); //unlink if exists
		//int rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str());


		bool rename_error;

#ifdef WINRT_ENABLED
		// WinRT has no PathFileExists, so we check attributes instead
		DWORD fileAttr;

		fileAttr = GetFileAttributesW(save_path.c_str());
		if (INVALID_FILE_ATTRIBUTES == fileAttr) {
#else
		if (!PathFileExistsW(save_path.c_str())) {
#endif
			//creating new file
			rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str())!=0;
		} else {
			//atomic replace for existing file
			rename_error = !ReplaceFileW(save_path.c_str(), (save_path+".tmp").c_str(), NULL, 2|4, NULL, NULL);
		}
		if (rename_error && close_fail_notify) {
			close_fail_notify(save_path);
		}

		save_path="";
		ERR_FAIL_COND( rename_error );
	}

}
bool FileAccessWindows::is_open() const {

	return (f!=NULL);
}
void FileAccessWindows::seek(size_t p_position) {

	ERR_FAIL_COND(!f);
	last_error=OK;
	if ( fseek(f,p_position,SEEK_SET) )
		check_errors();
}
示例#5
0
void FileAccessWindows::close() {

	if (!f)
		return;

	fclose(f);
	f = NULL;

	if (save_path != "") {

		bool rename_error = true;
		int attempts = 4;
		while (rename_error && attempts) {
			// This workaround of trying multiple times is added to deal with paranoid Windows
			// antiviruses that love reading just written files even if they are not executable, thus
			// locking the file and preventing renaming from happening.

#ifdef UWP_ENABLED
			// UWP has no PathFileExists, so we check attributes instead
			DWORD fileAttr;

			fileAttr = GetFileAttributesW(save_path.c_str());
			if (INVALID_FILE_ATTRIBUTES == fileAttr) {
#else
			if (!PathFileExistsW(save_path.c_str())) {
#endif
				//creating new file
				rename_error = _wrename((save_path + ".tmp").c_str(), save_path.c_str()) != 0;
			} else {
				//atomic replace for existing file
				rename_error = !ReplaceFileW(save_path.c_str(), (save_path + ".tmp").c_str(), NULL, 2 | 4, NULL, NULL);
			}
			if (rename_error) {
				attempts--;
				OS::get_singleton()->delay_usec(100000); // wait 100msec and try again
			}
		}

		if (rename_error) {
			if (close_fail_notify) {
				close_fail_notify(save_path);
			}

			ERR_EXPLAIN("Safe save failed. This may be a permissions problem, but also may happen because you are running a paranoid antivirus. If this is the case, please switch to Windows Defender or disable the 'safe save' option in editor settings. This makes it work, but increases the risk of file corruption in a crash.");
		}

		save_path = "";

		ERR_FAIL_COND(rename_error);
	}
}

String FileAccessWindows::get_path() const {

	return path_src;
}

String FileAccessWindows::get_path_absolute() const {

	return path;
}

bool FileAccessWindows::is_open() const {

	return (f != NULL);
}
void FileAccessWindows::seek(size_t p_position) {

	ERR_FAIL_COND(!f);
	last_error = OK;
	if (fseek(f, p_position, SEEK_SET))
		check_errors();
}
示例#6
0
void FileAccessWindows::close() {

	if (!f)
		return;

	fclose(f);
	f = NULL;

	if (save_path != "") {

		//unlink(save_path.utf8().get_data());
		//print_line("renaming..");
		//_wunlink(save_path.c_str()); //unlink if exists
		//int rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str());

		bool rename_error = true;
		int attempts = 4;
		while (rename_error && attempts) {
		// This workaround of trying multiple times is added to deal with paranoid Windows
		// antiviruses that love reading just written files even if they are not executable, thus
		// locking the file and preventing renaming from happening.

#ifdef UWP_ENABLED
			// UWP has no PathFileExists, so we check attributes instead
			DWORD fileAttr;

			fileAttr = GetFileAttributesW(save_path.c_str());
			if (INVALID_FILE_ATTRIBUTES == fileAttr) {
#else
			if (!PathFileExistsW(save_path.c_str())) {
#endif
				//creating new file
				rename_error = _wrename((save_path + ".tmp").c_str(), save_path.c_str()) != 0;
			} else {
				//atomic replace for existing file
				rename_error = !ReplaceFileW(save_path.c_str(), (save_path + ".tmp").c_str(), NULL, 2 | 4, NULL, NULL);
			}
			if (rename_error && close_fail_notify) {
				close_fail_notify(save_path);
			}
			if (rename_error) {
				attempts--;
				OS::get_singleton()->delay_usec(1000000); //wait 100msec and try again
			}
		}

		save_path = "";
		ERR_FAIL_COND(rename_error);
	}
}
bool FileAccessWindows::is_open() const {

	return (f != NULL);
}
void FileAccessWindows::seek(size_t p_position) {

	ERR_FAIL_COND(!f);
	last_error = OK;
	if (fseek(f, p_position, SEEK_SET))
		check_errors();
}