ZwFreeVirtualMemory() and its RegionSize arg

IFS docs (Built on Friday, May 03, 2002) say the following about
ZwFreeVirtualMemory():

NTSTATUS
ZwFreeVirtualMemory(
IN PHANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN OUT PULONG RegionSize,
IN ULONG FreeType
);

RegionSize
Size, in bytes, of the region of memory to free.
If the MEM_RELEASE flag is set in the FreeType parameter,
RegionSize must be zero. The function frees the entire region that was
reserved
in the initial allocation call to ZwAllocateVirtualMemory.

The IFS example driver (src\filesys\smbmrx\w2k\sys\SESSETUP.C(523))
doesn’t pass 0 as RegionSize:

TemporaryStatus = ZwFreeVirtualMemory(
NtCurrentProcess(),
&InToken,
&AllocateSize,
MEM_RELEASE);

Who is right here?

What is the meaning of BaseAddress args after calling this function? it Is
IN OUT argument,
so it can be changed by ZwFreeVirtualMemory().

Dmitriy Budko
Member of technical Staff, VMware

Certainly it is safe to pass 0 as RegionSize for MEM_RELEASE as the
documentation states; the disassembly of NtFreeVirtualMemory explicitly
handles this case. What happens if you specify non-0 as RegionSize for
MEM_RELEASE is tedious to figure out; I suspect it just works as long as
you pass in the correct RegionSize (else Microsoft’s sample has a major
bug). What Microsoft is trying to tell you of course is that you can
freely commit and decommit pages in a random-access manner within a
range of reserved pages, but the range of reserved pages must be
released as a whole.

The documentation on the BaseAddress parameter is simply incorrect; it
doesn’t return the “actual size, in bytes, of the freed region of
pages”, it returns the beginning of the decommitted or released region.
The RegionSize parameter will return the byte size of the decommitted or
released region.

Somebody needs to do a rewrite on the documentation for this function.

Dmitriy Budko wrote:

IFS docs (Built on Friday, May 03, 2002) say the following about
ZwFreeVirtualMemory():

NTSTATUS
ZwFreeVirtualMemory(
IN PHANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN OUT PULONG RegionSize,
IN ULONG FreeType
);

RegionSize
Size, in bytes, of the region of memory to free.
If the MEM_RELEASE flag is set in the FreeType parameter,
RegionSize must be zero. The function frees the entire region that was
reserved
in the initial allocation call to ZwAllocateVirtualMemory.

The IFS example driver (src\filesys\smbmrx\w2k\sys\SESSETUP.C(523))
doesn’t pass 0 as RegionSize:

TemporaryStatus = ZwFreeVirtualMemory(
NtCurrentProcess(),
&InToken,
&AllocateSize,
MEM_RELEASE);

Who is right here?

What is the meaning of BaseAddress args after calling this function? it Is
IN OUT argument,
so it can be changed by ZwFreeVirtualMemory().

Dmitriy Budko
Member of technical Staff, VMware


Nick Ryan