Create file with certain size - c++

Is there any method to create a file of desired size whenever I create a file using CreateFile().
Thanks.

SetEndOfFile can be used to extend or truncate a file.

I think (in case you are sitting in front of a *nix box) you can handle this with the default low-lewel write() / fsync() APIs.
Regards,
dley

you might use, at the prompt (with admin credentials), "fsutil file createnew" followed by the file name and the desired size (in bytes)

Related

Getting around the 8192 byte var limit in NSIS?

I'm supplying a c++ .dll to a user who is writing an installer via an NSIS script. Using System.dll, the user can call my .dll as such:
System::Call 'my.dll::GetJson(v) t .r0'
DetailPrint $0
The return value of GetJson() gets stored in $0. This is all working correctly, though GetJson() may return a json blob whose length is > 8192, in which case the value stored in $0 gets truncated.
I looked at trying to increase NSIS_MAX_STRLEN by building NSIS myself using scons, as mentioned here: https://nsis.sourceforge.io/Special_Builds
scons NSIS_MAX_STRLEN=16384 PREFIX=C:\somewhere install-compiler install-stubs
However, after doing this, the NSIS-compiled .exes crashed upon running. It seems like 8192 may be some kind of memory limitation.
Is there any way around this for me? For example, would it be possible to call
System::Call 'mydll::GetJson(v) t .r0'
But instead of the return value being stored in $0, have it be split into chunks? Perhaps it's possible to write the contents of GetJson() to a file first, and then NSIS can read that and split it?
Any help is appreciated. Thank you.
If the user needs to edit a very long string you basically have two options:
Use the system plug-in to fill a text field on a nsDialogs custom page. You can't use the registers to store the string, you need to use ...func()p.r0 to get the raw address of the string from your plug-in and use Sendmesage to fill the text field. To save you need to allocate memory, get the text with SendMessage and write it to a file and finally free the memory.
The other option is to create the custom page with your custom plug-in.

WriteFileGather - append buffers to file

Using Windows API's WriteFileGather, I am writing a file to the disk.
I want to append new buffers to the existing file.
What is the way to prevent WriteFileGather from overwriting the existing file?
WriteFileGather will never overwrite the file unless you ask it to - theres no implied overwrite/append option, theres ONLY a 'please write data at file position X option'.
You should open the file handle normally (making sure you've got GENERIC_WRITE access and specifying flags at least flags FILE_FLAG_OVERLAPPED and FILE_FLAG_NO_BUFFERING by using CreateFile
Then you set the position the file writes at by using the Offset and OffsetHigh members of the OVERLAPPED you pass in as the 5th parameter.
This is similar to the way WriteFile works when its running in asynchronous mode - you must specify the position to write at. Its probably easier to learn how to do positional asyncronous writes using WriteFile first then move onto WriteFileGather if you need its additional power.
See here for docs.
EDIT: To answer the comment from Harry, to get the end of file you can either remember how much you've written before (assuming this is a new file you created) or get the current file size from a HANDLE using SetFilePointerEx with distance 0 and method FILE_END which will return to you the end of the file. There are other ways of getting a file size but beware you may get a cached answer (e.g. if iterating over a directory) and so the above is recommended.

What is the most efficient way to remove first N bytes from a file on Windows?

Say, I have a file of an arbitrary length S and I need to remove first of its N bytes (where N is much less than S.) What is the most efficient way to do it on Windows?
I'm looking for a WinAPI to do this, if one is available.
Otherwise, what are my options -- to load it into RAM and then re-write the existing file with the remainder of data? (In this case I cannot be sure that the PC has enough RAM?) Or write the remainder of file data into a new file, erase the old one, and rename the new file into the old one. (In this case what to do if any of these steps fail? Plus how about defragmentation that this method causes on disk?)
There is no general way to do this built into the OS. There are theoretical ways to edit the file system's data structures underneath the operating system on sector or cluster boundaries, but this is different for each file system, and would need to violate any security model.
To accomplish this you can read in the data starting at byte N in chunks of say 4k, and then write them back out starting at byte zero, and then use the file truncate command (setendoffile) to set the new smaller end of file when you are finished copying the data.
The most efficient method to delete data at the beginning of the file is to modify the directory entry, on the hard drive, that tells where the data starts. Again, this is the most efficient method.
Note: This may not be possible, if the data must start on a new boundary. If this is the case, you may have to write the remainder data on the sector(s) to new sector(s), essentially moving the data.
The preferred method is to write a new file that starts with data copied after the deleted area.
Moving files on same drive is faster than copying files since data isn't duplicated; only the file pointer, (symbolic)links & file allocation/index table is updated.
The move command in CMD could be modified to allow user to set file start & end markers, effecting file truncation without copying file data, saving valuable time & RAM/Disk overheads.
Alternative would be to send the commands direct to the device/disk driver bypassing the Operating System as long as OS knows where to find the file & file properties eg. file size, name & sectors occupied on disk.

How to read metafiles of NTFS file system using C

Can anyone show me how to directly access metafiles ($MFT, $Volume, $Bitmap...) ?
I need to get info from these files.
You can use the ioctl function, FSCTL_GET_NTFS_FILE_RECORD.

How to get file type on linux?

I need to get file type without using file extensions on linux. There is "file" utility, which can do this. How can I do the same using C/C++? Not 'system(const char *)', of course... Thanks)
AFAIK file is implemented over libmagic. For more reference see:
file sources
and maybe this link: http://linux.die.net/man/3/libmagic.
Either call file as a child process or emulate what it does. There are no other options if you want to intelligently examine a file's content to guess what it contains.