0

The relevant Microsoft doc is: https://msdn.microsoft.com/en-us/library/aa363911.aspx

But it describe how to move existing fragmented file to new continuous logical blocks. I want to create new file without fragmentation. At first i get free logical blocks by FSCTL_GET_VOLUME_BITMAP. How to write file in concrete free logical block now?

Andy
  • 1
  • 1
    I don't think you can. You have to unfragment the file after writing it. – Ross Ridge Jul 25 '15 at 14:34
  • 1
    I would guess that provided you set the final size of the file immediately, Windows will probably try to avoid fragmenting it if possible. Alternatively, it should be very efficient to unfragment a file that has been allocated but not yet written, Windows ought to recognize that there is no actual data needing to be copied. – Harry Johnston Jul 25 '15 at 21:28

1 Answers1

-1

use ZwCreateFile - AllocationSize parameter. if it present file system try find first continuous free clusters run with RtlFindClearBits. this is solution

i make small test

void PrintAllocSize(HANDLE hFile)
{
    IO_STATUS_BLOCK iosb;
    FILE_STANDARD_INFORMATION fsi;
    if (0 <= ZwQueryInformationFile(hFile, &iosb, &fsi, sizeof(fsi), FileStandardInformation))
    {
        DbgPrint("AllocationSize=%I64x, EndOfFile=%I64x\n", fsi.AllocationSize.QuadPart, fsi.EndOfFile.QuadPart);
    }

    STARTING_VCN_INPUT_BUFFER vcn = {};
    RETRIEVAL_POINTERS_BUFFER rpb;

    NTSTATUS status = ZwFsControlFile(hFile, 0, 0, 0, &iosb, FSCTL_GET_RETRIEVAL_POINTERS, &vcn, sizeof(vcn), &rpb, sizeof(rpb));

    switch (status)
    {
    case STATUS_SUCCESS:
    case STATUS_BUFFER_OVERFLOW:
        DbgPrint("ExtentCount=%x\n", rpb.ExtentCount);
        break;
    case STATUS_END_OF_FILE:
        DbgPrint("File Is Empty\n", rpb.ExtentCount);
        break;
    default:
        DbgPrint("ZwFsControlFile return %x\n", status);
    }
}

void DoTest(POBJECT_ATTRIBUTES poa)
{
    HANDLE hFile;
    IO_STATUS_BLOCK iosb;
    LARGE_INTEGER AllocationSize = { 0x100000 };
    if (0 <= ZwCreateFile(&hFile, FILE_APPEND_DATA|SYNCHRONIZE, poa, &iosb, &AllocationSize, 0, 0, FILE_SUPERSEDE, FILE_SYNCHRONOUS_IO_NONALERT, 0, 0))
    {
        PrintAllocSize(hFile);
        ZwClose(hFile);
    }

    DbgPrint("===============================\n");

    if (0 <= ZwOpenFile(&hFile, SYNCHRONIZE, poa, &iosb, 0, FILE_SYNCHRONOUS_IO_NONALERT))
    {
        PrintAllocSize(hFile);
        ZwClose(hFile);
    }

    ZwDeleteFile(poa);
}

and output

AllocationSize=100000, EndOfFile=0
ExtentCount=1
===============================
AllocationSize=0, EndOfFile=0
File Is Empty

when we create file with not zero AllocationSize — file-system reserve space, but file size still 0 — (AllocationSize=100000, EndOfFile=0, ExtentCount=1) if we close handle, without write data - file-system free allocated clusters (AllocationSize=0, EndOfFile=0, File Is Empty)

verizon
  • 1
  • 2
  • Interesting point. I *think* that creating the file and then immediately extending it would have the same effect, so it probably isn't necessary to use unsupported functions. But the OP may wish to experiment. – Harry Johnston Jul 25 '15 at 23:06
  • what you mean under "unsupported functions" ? ZwCreateFile ??this is normal api. supported in all windows, begin even from nt4. i always use it for create new file and AllocationSize too - when it known at file create point. – verizon Jul 25 '15 at 23:15
  • The use of Zw functions in user-mode applications is not supported. They're intended only for use in device drivers (and by the OS itself). You shouldn't be using it in production user-mode code unless you have no other choice, and even then you need to be aware that there is no guarantee that it will continue to work as expected in future versions of Windows. (On the other hand, it's a *reasonably* safe bet that it will in fact continue to do so.) – Harry Johnston Jul 25 '15 at 23:30
  • The use of Zw functions in user-mode applications is not supported. - this is absolute nonsense. it supported. and work. i already 10+ years use this from user mode too. in what problem ?? simply link with ntdll.lib and use export from ntdll – verizon Jul 25 '15 at 23:59
  • If you were supposed to use Zw functions from user-mode applications, they would be included in the Platform SDK headers. But if you can find documentation from Microsoft saying that they support the use of Zw functions from user mode applications, go ahead and post it. – Harry Johnston Jul 26 '15 at 00:17
  • Actually, NtCreateFile is one of a relatively few special cases that used to be documented (see [archived article](https://msdn.microsoft.com/en-us/library/bb432380(VS.85).aspx)) but even then it was [subject to a caveat](https://msdn.microsoft.com/en-us/library/bb432200(v=vs.85).aspx): "The functions and structures in Winternl.h are internal to the operating system and subject to change from one release of Windows to the next, and possibly even between service packs for each release. To maintain the compatibility of your application, you should use the equivalent public functions instead." – Harry Johnston Jul 26 '15 at 00:25
  • ... so arguably I should have said "internal functions" rather than "unsupported functions" but the upshot is the same - don't use unless absolutely necessary, because there are no compatibility guarantees. – Harry Johnston Jul 26 '15 at 00:26
  • i use both SDK and WDK headers. "But if you can find documentation from Microsoft saying.." - D) i not need documentation. i simply use it :) and this not "subject to change" - this api present already more than 15 years. from windows nt4 up to latest windows 10. i use allot of api from ntdll many years - and all work great. – verizon Jul 26 '15 at 00:44
  • about documentation - several years ago here writed that drivers cannot be written on c++, but only on c. and cannot build project in visual studio, only from bat/make files. but i never listen this idiocy and use only c++ in drivers and build it only in visual studio as dll project. when documentation sayed that we cannot use ntdll api in user mode - this is also absolute idiocy. i can and i use. and will be use. I am free from the taboo. subject to change ? not more then CreateFile subject to change. and less then CommonControls behavior – verizon Jul 26 '15 at 00:44
  • Cowboy programming. You've been lucky. One day your luck may run out. But you've chosen to take that risk and that's OK, I just want to make it clear to other readers that it *is* a risk. They can then judge for themselves whether it's one they want to take. (Incidentally, MS do document the use of C++ in device drivers, if I remember correctly. Subject to certain constraints, it's perfectly safe.) – Harry Johnston Jul 26 '15 at 01:09
  • "Cowboy programming. You've been lucky." - no, this is not luck. this is freedom. and this freedom give me huge advantage over 99,9% programmers. and luck cannot continuous more than 10 years. "that it is a risk." this is not risk. really this is removal of religious taboos. "Incidentally, MS do document the use of C++ in device drivers" - now yes. but i remember begin of 200-x when in documentation say that only c can be used in drivers, no c++. and special building/build utility not need for drivers. i for example without any problems build drivers in vs98 with standard dll project – verizon Jul 26 '15 at 08:04
  • Given that there is no Visual Studio 98, I'm having a hard time believing, that you build drivers in Visual Studio 98. – IInspectable Jul 26 '15 at 16:46
  • sorry have problems with english. really i want say than begin build drivers yet in vs98. now of course i use more new version of vs – verizon Jul 26 '15 at 18:07