0

The problem at first glance looks ridiculous. I am writing a simple application in C++. I compiled code. Everything worked perfectly, until I moved the exe to a different partition than the system. I have two partition (C: with system and E: with data, they both are NTFS), from C:, eg. from Desktop, from root of C:\ etc., program doesn't have any problems. From E:\, rename() function throws an error "Access Denied".

To clarify:
- I have full admin rights
- The program is run with administrative rights
- Transferred files aren't used by any process
- The system partition both as E: \ in security policy has granted full rights to the Administrators group and for me personally.

How to solve it?
For example: Games that can save files in the same place doesn't have a problem with that, even without administrator rights.

When I tried uses MoveFileEx I got error with code 5. Code 5 means "Access denied". Also because it's an other partition

Maxie
  • 98
  • 3
  • 13
  • are you sure the filename is correct? – David Haim Nov 10 '15 at 17:28
  • 2
    You can have all the rights in the world and still wont be able to rename a file or directory if it is currently being used. Its a matter of semantics not permission. – Havenard Nov 10 '15 at 17:29
  • @DavidHaim Sure. A program that checks if the file exists before **rename**. From another location it works perfectly (from C: partition). – Maxie Nov 10 '15 at 17:30
  • Did you escape all backslashes in the filename? Can you post a short version of the program (with hardcoded paths) that causes the error on your system? – Simon Kraemer Nov 10 '15 at 17:31
  • Are `oldname` and `newname` on the same partition/drive? – Simon Kraemer Nov 10 '15 at 17:32
  • Try running the program as Administrator (right-click it and Run as Administrator) to see if it works. If it does, its because you are trying to modify a file in a path that is protected by UAC, only applications that require permission will be able to modify those files. – Havenard Nov 10 '15 at 17:32
  • @Havenard File isn't used. I can **rename** it from C: partition and I can move it manually. – Maxie Nov 10 '15 at 17:32
  • @SimonKraemer No, isn't. This may be the reason? – Maxie Nov 10 '15 at 17:35
  • Psychic debugging would say either one or more of your paths aren't absolute (so it's accessing relative to `E:` when the files are on `C:`), and/or the old and new names aren't on the same partition; `rename` isn't just "move it for me"; if the source and target aren't on the same partition/mount point, `rename` doesn't work, you need to copy the file (and metadata if desired) then delete the original. – ShadowRanger Nov 10 '15 at 17:35
  • @Maxie Afaik `rename` doesn't work between different partitions. I would recommend writing your own rename that copies the file and deletes it on success, when the integrated rename fails. – Simon Kraemer Nov 10 '15 at 17:38
  • @Havenard: Why should you not be able to rename a file/directory in use? Is that some broken OS stuff? – too honest for this site Nov 10 '15 at 17:42
  • 2
    @Olaf In Windows it is possible to open files exclusivly, which prevents the file from being opened(or renamed, etc) by any other program as long as the handle is open. – Simon Kraemer Nov 10 '15 at 17:46
  • 3
    @Olaf: Also, the implementation of `rename` on Windows is not the same as on POSIX systems. On Windows, [`rename` is documented to fail if the new name exists](https://msdn.microsoft.com/en-us/library/zw5t957f.aspx), where the [POSIX `rename` explicitly stomps existing files](http://linux.die.net/man/3/rename). – ShadowRanger Nov 10 '15 at 17:49
  • @Maxie Are you copying files or folders or both? – Simon Kraemer Nov 10 '15 at 18:35
  • @SimonKraemer: That is the same in Linux/POSIX. However, it is not the default. – too honest for this site Nov 10 '15 at 19:46
  • @Olaf Try to delete/rename/move/replace e.g. a running executable in a Windows and a Linux system. Windows won't let you., Linux will. I haven't found a way yet to prevent a file from being deleted by using file locking. – Simon Kraemer Nov 10 '15 at 20:33
  • @Olaf: http://stackoverflow.com/a/2031100/4181011 – Simon Kraemer Nov 10 '15 at 20:34
  • @SimonKraemer: Well, you do not delete the file anyway in Linux, but the directory-entry (that's why the system call in Unixoids is called `unlink`, not delete/remove). Linux manages files vers similar to the heap management in languages with garbage collection. And directory-entries are a matter of filesystem/directory access rights, not the inodes. I just though Windows had finally trahsed that stupid behaviour. Was always annoyed I could not rename a file which was open. – too honest for this site Nov 10 '15 at 20:56

1 Answers1

3

Based on comments, your original and new names aren't on the same partition/drive/mount point. rename only changes names, it's not actually a "move" command (it just happens to be usable as such when the source and dest are on the same file system).

If you need to move across partitions, on Windows, you can use the MoveFile function which will either rename if possible, or "copy and delete original" when the destination is on a different partition.

If you need to stomp existing files (MoveFile refuses to overwrite an existing file), use MoveFileEx with the flags MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING (optionally or-ing in MOVEFILE_WRITE_THROUGH so the operation blocks until the file finishes being moved when an atomic rename isn't possible).

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • It should also be mentioned that _"The one caveat is that the MoveFile function will fail on directory moves when the destination is on a different volume."_ – Simon Kraemer Nov 10 '15 at 17:44
  • @SimonKraemer: Yeah, I omitted that information because the OP is clearly working with files, not directories, but it's a worthwhile note. – ShadowRanger Nov 10 '15 at 17:47
  • @ShadowRanger Sorry, but when I tries use MoveFileEx I got error with code 5. Code 5 means Access denied. Also because it's an other partition. – Maxie Nov 10 '15 at 17:55
  • @Maxie: If `MoveFileEx` is still failing with Access Denied even when flagged for `MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING`, then you've got some other issue. Could be an issue with virus scanners or indexers, could be an issue with using relative paths (that point to the wrong/non-existent directory on `E:`; `MoveFile` doesn't create parent directories, so every path component aside from the file itself must already exist). You haven't given us example paths, existing state of the file system, or any other information to work from. – ShadowRanger Nov 10 '15 at 18:15
  • @Maxie Try to break your code down to a MCVE and update your question with it. Don't worry about the paths itself. – Simon Kraemer Nov 10 '15 at 20:35