4

I would like to open an anonymous file that is what would be the result under linux of opening a file an unlink it or using memfd_create, but none of these seem to be available under windows (you could make delete a file work, but it's name doesn't seem to be removed until the file is closed). Getting a file descriptor that isn't backed with something visible in the file system.

Is there a way to achieve this under windows? Preferably I'd like it to never appear in the file system.

The reason why I want this is because I need a FILE* to be sent as an argument to a function that expects that (and I don't want it to clobber the file system). Changing the libraries does not look like a feasible option (besides the libraries has to work on other OSes as well - so they can't rely on windows specific abstractions anyway).

skyking
  • 13,817
  • 1
  • 35
  • 57
  • I have no idea why this was downvoted, so I had to guess how I could improve the question:( – skyking Aug 24 '15 at 08:35
  • 2
    If the FILE * is only read or written to, with no seeking, you might able to use a named pipe for this. – Ross Ridge Aug 25 '15 at 00:09
  • Related: [memory buffer as FILE\*](http://stackoverflow.com/questions/539537/memory-buffer-as-file) – anatolyg Aug 25 '15 at 11:16
  • @anatolyg That's related, but the answers there either says it cannot be done (the accepted answer) or provides solutions that rely on unix behavior or the GNU c-library. – skyking Aug 26 '15 at 05:57

2 Answers2

1

The most reasonably close to memfd_create you have in Windows are Memory-Mapped files. MSDN article about it here: http://go.microsoft.com/fwlink/?linkid=180801

But basically, the CreateFileMapping/OpenFileMapping API calls.

This does not use the physical disk (unless it needs the memory paged on disk) for it, but as far as I know, neither does memfd_create

Jcl
  • 27,696
  • 5
  • 61
  • 92
  • Actually I'm about to memory map it so this sounds promising, but as far as I can see the `CreateFileMapping` returns (a handle to) an file mapping object. It doesn't seem to be possible to do fx `_open_osfhandle` on it. – skyking Aug 24 '15 at 08:33
  • Yeah, I never went that far to create a a C-descriptor from a memory mapped file, so it might not be doable in Windows (not by using MMFs anyway), that's why I didn't say it was equal, just "reasonably close". You get a file handle which you can use with the Win32 API, but not a C-style descriptor (or so it seems by your comment) – Jcl Aug 24 '15 at 08:41
  • Uhm... what the hell is *"virtual RAM"*? @skyking: Read the [documentation](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366537.aspx): *"hFile: If hFile is INVALID_HANDLE_VALUE, the calling process must also specify a size for the file mapping object in the dwMaximumSizeHigh and dwMaximumSizeLow parameters. In this scenario, CreateFileMapping creates a file mapping object of a specified size that is **backed by the system paging file instead of by a file in the file system.**"* – IInspectable Aug 24 '15 at 09:40
  • @IInspectable RAM paged on disk, sorry there, my mind was a bit fuzzy, I'll edit – Jcl Aug 24 '15 at 09:41
  • RAM is not ever paged to disk. Memory is. – IInspectable Aug 24 '15 at 09:42
  • @IInspectable Yes, I've read the documentation and tried with `INVALID_HANDLE_VALUE`, but still the handle returned by the call doesn't seem to be that of a file (ie can't be accepted by `WriteFile` or `_open_osfhandle`). – skyking Aug 24 '15 at 09:43
  • 1
    @skyking: Stop thinking like a Unix-mind. **Not** everything is a file, and using `WriteFile` on a chunk of memory feels so Unix-y, it hurts. Use `memcpy`. – IInspectable Aug 24 '15 at 09:45
  • @IInspectable Since I wrote I wanted a file descriptor, I think it's reasonable to assume that I want something that resembles that. – skyking Aug 24 '15 at 09:50
  • @skyking To the extent of my knowledge, I don't think what you want is supported in Windows. Memory mapped files are kind of the opposite (you take a file handle and work on it like if it was a buffer, vs. taking a buffer and work on it as if it was a file -ala `fmemopen` or similar-). – Jcl Aug 24 '15 at 09:54
  • @skyking: Exactly. Stop thinking like a Unix geek. A file descriptor may feel natural to you, since your brain has been taught, that you cannot ever go wrong, as long as you follow the Everything Is A File mantra. On Windows you generally have more appropriate abstractions. I would recommend to update your question and specify, what problem you are trying to solve. As written, it's asking for help with what you **think** is an appropriate solution. I doubt that it is. – IInspectable Aug 24 '15 at 09:54
  • @IInspectable Actually I need a `FILE*`. I don't really see the point in questioning the reason one would want that, in fact the solution has to work on other OS'es as well so relying on more "appropriate" abstractions are probably not so appropriate. – skyking Aug 24 '15 at 10:41
  • @skyking look at this http://stackoverflow.com/questions/10305095/can-i-replace-a-call-to-open-memstream-with-a-malloc-and-an-implicit-cast , it seems they kinda achieved what you wanted using memory mapped files. It uses `tmpfile` though, which in the Windows implementation might use a file accessible on disk while it's open, don't know if this would be suitable for you (it's against the requirements in the question, but if what you are aiming at is "portability", then it might do)... again, it really depends on very specific requirements – Jcl Aug 24 '15 at 10:55
  • @Jcl I don't like the idea of having unnecessary files visible in the file system (another time it comes handy it may be required that they are not visible), but the major downside with `tmpfile` is that it creates a file in the root directory which means you have to have administrator rights. – skyking Aug 24 '15 at 13:37
  • @skyking I understand your concerns. Then again, maybe the problem is using libraries that use file descriptors as parameters for functions that do stuff on things that are not necessarily files – Jcl Aug 24 '15 at 14:09
  • @skyking: I'm confused; if you're going to memory map the file, why do you also want a `FILE *` ? The two aren't *strictly* mutually exclusive, but since there is no coherency guarantee I can't think of any situation in which it is sensible to both memory map a file *and* do ordinary I/O. – Harry Johnston Aug 24 '15 at 23:11
  • @HarryJohnston Actually I ended up not memory mapping the file, the main reason is to have somithing that can be passed to functions that expect a `FILE*` (and I think occupying a file name in the filesystem seems uneccesary). – skyking Aug 25 '15 at 06:35
0

No, there is no such thing as an anonymous file in Windows.

(Of course, that does not necessarily mean that you cannot have a FILE * that does what you need; for example, I like Ross's suggestion of using a named pipe.)

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
  • Do you have a source for that claim? – skyking Aug 25 '15 at 06:32
  • @anatolyg: it may be possible to create a `FILE *` object that can meet the OPs needs, but since it wouldn't *actually* be a file I stand by my answer. But it should also be noted that most of the answers to the question you linked to don't apply to Windows, and the only one that does is output-only. (I like Ross's suggestion of using a named pipe, for example.) – Harry Johnston Aug 25 '15 at 20:38
  • @skyking: documentation, as a general rule, describes what *is* possible rather than what is *not* possible, so no, I don't have a canonical source. :-) But I would be *extremely* surprised to discover otherwise. – Harry Johnston Aug 25 '15 at 20:50
  • (Not that there is anything preventing a third-party file system from implementing them. But I assume you want this to work on a vanilla Windows system, i.e., NTFS.) – Harry Johnston Aug 25 '15 at 20:50
  • ... there are also various oddball approaches, such as a RAM disk or a shadow volume. But IMO they would be more intrusive, not less, than a temporary file. – Harry Johnston Aug 25 '15 at 21:14
  • @anatolyg If you think there is you're welcome to provide an answer on how they are created (other than Ross' suggestion of using anonymous pipes). – skyking Aug 26 '15 at 05:59
  • @anatolyg As I have not seen any evidence of the opposite I consider this the correct answer. It's always easier to prove that something exists than something doesn't exist. A somewhat reasonable claim that something doesn't exist consequently has to stand until somebody provides a well founded argument that it does in fact exist. – skyking Aug 28 '15 at 09:40