Geoff Chappell, Software Analyst
This function stops the profiling that has been configured for a given profile object.
NTSTATUS NtStopProfile (HANDLE ProfileHandle);
The ProfileHandle argument is a handle to an executive profile object, such as created by NtCreateProfile or NtCreateProfileEx.
The function returns STATUS_SUCCESS if successful, else a negative error code.
The NtStopProfile function and its alias ZwStopProfile are exported by name from NTDLL in version 3.10 and higher. In kernel mode, where ZwStopProfile is a stub and NtStopProfile is the implementation, neither is exported until the 1607 release of Windows 10 exports the stub.
Neither NtStopProfile nor its alias is documented. As ZwStopProfile, it is declared in the ZWAPI.H file from an Enterprise edition of the Windows Driver Kit (WDK) for Windows 10.
Unusually for native API functions, no repackaging of NtStopProfile, documented or not, is known in any higher-level user-mode module that is distributed as standard with Windows.
The following implementation notes come mainly from inspection of the kernel from the original release of Windows 10. They may some day get revised to account for other versions. Where anything is written about earlier versions, take it not as an attempt at presenting a comprehensive history but as a bonus from my being unable to resist a quick trip down memory lane. I have no programme of revisiting this analysis for later releases. Updates mean just that I happen to have noticed something and to have found time to add it.
The function fails unless the given handle references an executive profile object (rather than any other type of object) and has whatever permission is represented by the access mask 0x00000001. Microsoft’s name for this one permission that is defined for profile objects is not known, but there would be no surprise if it turns out to be EPROFILE.
The profile object retains parameters that were supplied on some earlier call to NtCreateProfile or NtCreateProfileEx. Among these is the address of a buffer that is to receive the ULONG counters of times that execution is discovered in successive buckets that span a profiled region of address space. Because the counters will be incremented while handling a hardware interrupt this buffer—well, that part of it that will be needed for the counters—must be locked into physical memory and mapped into system address space at all times that profiling is started but not yet stopped. This mapped address for the buffer is also kept with the profile object. If it’s not present, then there is no profiling to stop, and the function returns STATUS_PROFILING_NOT_STARTED.
The function’s remaining work, which cannot fail, is to stop the profiling but not to end it. It undoes just the work of NtStartProfile. The executive profile object remains. The caller retains a handle to it and may reuse it in any number of paired calls to NtStartProfile and NtStopProfile. Complete cleanup is done only when the handle gets closed.