2

I found old, huge open source code which performs some computations on binary data stored in file on disk, output is also saved as binary file.

There is one root method which I would like to use, simplified signature:

int magic(FILE* input, FILE* output);

The problem is that I store input data in process memory and I would like to have output also as memory in process. Code is so big that I'm not able to rewrite it in resonable time.

This API forces me to make two huge I/O on every call to magic().

Is there any possibility to map BYTE array as FILE* on Windows using C/C++ mechanisms?

elklepo
  • 509
  • 4
  • 17
  • 3
    It sounds like you are asking about a memory mapped file. Is this any help: https://msdn.microsoft.com/en-us/library/ms810613.aspx ? – user4581301 Oct 19 '17 at 18:40
  • Another option: create a RAM disk. Write your input data to a file on the RAM disk, open the input `FILE *` and the output `FILE *` on the RAM disk, run your process, then copy the output data from the RAM disk, then cleanup. See https://superuser.com/questions/1091597/create-a-ram-drive-in-windows-10-to-improve-a-modded-instance-of-tes-v-skyrim – Andrew Henle Oct 19 '17 at 20:10
  • 1
    (caveat: I haven't tried this in this context) CreateFile is probably your friend here if you own the allocation of the bytes. Instead of malloc, Use CreateFile to create a temporary, delete on close file. The filesystem is smart enough to only do write-outs if needed. Essentially, you have an in-memory file. Use the memory mapping code to create a buffer, and use that for your data. Then, use the approach here to get a FILE * from your file HANDLE from CreateFile. https://stackoverflow.com/questions/5193579/how-make-file-from-handle-in-winapi – Ben Kuhn Oct 20 '17 at 05:17
  • Possible duplicate of [How to write to a memory buffer with a FILE\*?](https://stackoverflow.com/questions/539537/how-to-write-to-a-memory-buffer-with-a-file) – phuclv Apr 23 '19 at 10:48

1 Answers1

3

It seems that you need the functionality of fmemopen:

http://man7.org/linux/man-pages/man3/fmemopen.3.html

Which takes a memory region and returns a file descriptor. Unfortunately, this is a POSIX function that does not have an equivalent in Windows. Memory mapped files are probably not what you want, as they take an existing file and map it to a memory region, not the other way around as with fmemopen. The only options you have are to either use fmemopen with mingw on Windows (don't know if you can do this) or roll out your own versions of fopen, fwrite and so on.

mnistic
  • 10,866
  • 2
  • 19
  • 33
  • *roll out your own versions of fopen, fwrite and so on* I worked on getting some of the first 64-bit Tivoli SANergy products working on 64-bit Solaris - those versions were based on interposing on IO calls, and that can be a lot harder than it seems at first. Interposing on the entire `FILE *`-based API is a considerable task. Depending on how the target code/application uses the calls, it may not even be possible, especially if the source isn't available and digs into the `FILE *` structures directly. Luckily Sun wisely made the 64-bit Solaris `FILE *` structure completely opaque. – Andrew Henle Oct 19 '17 at 20:17