PsSetLoadImageNotifyRoutine routine

The PsSetLoadImageNotifyRoutine routine registers a driver-supplied callback that is subsequently notified whenever an image is loaded (or mapped into memory).

Syntax


NTSTATUS PsSetLoadImageNotifyRoutine(
  _In_  PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine
);

Parameters

NotifyRoutine [in]

A pointer to the caller-implemented callback routine for load-image notifications.

Return value

PsSetLoadImageNotifyRoutine either returns STATUS_SUCCESS or it returns STATUS_INSUFFICIENT_RESOURCES if it failed the callback registration.

Remarks

Highest-level system-profiling drivers can call PsSetLoadImageNotifyRoutine to set up their load-image notify routines, declared as follows:


VOID
  (*PLOAD_IMAGE_NOTIFY_ROUTINE)(
    __in_opt PUNICODE_STRING  FullImageName,
    __in HANDLE  ProcessId,
    __in PIMAGE_INFO  ImageInfo
    );

After a driver registers a load-image notify routine, the operating system calls this routine to notify the driver when a driver image or a user image (for example, a DLL or EXE) is mapped into virtual memory. This call occurs after the image is mapped and before execution of the image starts.

The maximum number of drivers that can be simultaneously registered to receive load-image notifications is eight. If the maximum number of load-image notify routines is already registered when a driver calls PsSetLoadImageNotifyRoutine to try to register an additional notify routine, PsSetLoadImageNotifyRoutine fails and returns STATUS_INSUFFICIENT_RESOURCES.

Notes

  • An update for Windows 8.1 increases the maximum number of drivers registered to receive load-image notifications from eight to 64. This update is installed as part of a cumulative update that is available through Windows Update starting on April 8, 2014. In addition, this cumulative update is available at http://support.microsoft.com/kb/2919355.
  • Users of Windows 7 with Service Pack 1 (SP1) can install a hotfix to increase the maximum number of drivers registered to receive load-image notifications from eight to 64. This hotfix is available at http://support.microsoft.com/kb/2922790.

The operating system does not call load-image notify routines when sections created with the SEC_IMAGE_NO_EXECUTE attribute are mapped to virtual memory.

In Windows 7, Windows Server 2008 R2, and earlier versions of Windows, the operating system holds an internal system lock during calls to load-image notify routines for images loaded in user process address space (user space). To avoid deadlocks, load-image notify routines must not call system routines that map, allocate, query, free, or perform other operations on user-space virtual memory.

A driver must remove any callbacks it registers before it unloads. You can remove the callback by calling the PsRemoveLoadImageNotifyRoutine routine.

When the main executable image for a newly created process is loaded, the load-image notify routine runs in the context of the new process. The operating system calls the driver's load-image notify routine at PASSIVE_LEVEL inside a critical region with normal kernel APCs disabled.

When the load-image notify routine is called, the input FullImageName points to a buffered Unicode string that identifies the executable image file. (The FullImageName parameter can be NULL in cases in which the operating system is unable to obtain the full name of the image at process creation time.) The ProcessId handle identifies the process in which the image has been mapped, but this handle is zero if the newly loaded image is a driver. The buffered data at ImageInfo is formatted as follows:


typedef struct  _IMAGE_INFO {
    union {
        ULONG  Properties;
        struct {
            ULONG ImageAddressingMode  : 8; //code addressing mode
            ULONG SystemModeImage      : 1; //system mode image
            ULONG ImageMappedToAllPids : 1; //mapped in all processes
            ULONG Reserved             : 22;
        };
    };
    PVOID  ImageBase;
    ULONG  ImageSelector;
    ULONG  ImageSize;
    ULONG  ImageSectionNumber;
} IMAGE_INFO, *PIMAGE_INFO;

When such a profiling driver's load-image routine is called, the members of this structure contain the following information:

ImageAddressingMode

Always set to IMAGE_ADDRESSING_MODE_32BIT.

SystemModeImage

Set either to one for newly loaded kernel-mode components, such as drivers, or to zero for images that are mapped into user space.

ImageMappedToAllPids and Reserved

Always set to zero.

ImageBase

Set to the virtual base address of the image.

ImageSelector

Always set to zero.

ImageSize

Set to the virtual size, in bytes, of the image.

ImageSectionNumber

Always set to zero.

Starting with Windows Vista, the IMAGE_INFO structure definition changes to the following:


typedef struct _IMAGE_INFO {
    union {
        ULONG Properties;
        struct {
            ULONG ImageAddressingMode  : 8;  // Code addressing mode
            ULONG SystemModeImage      : 1;  // System mode image
            ULONG ImageMappedToAllPids : 1;  // Image mapped into all processes
            ULONG ExtendedInfoPresent  : 1;  // IMAGE_INFO_EX available
            ULONG Reserved             : 21;
        };
    };
    PVOID       ImageBase;
    ULONG       ImageSelector;
    SIZE_T      ImageSize;
    ULONG       ImageSectionNumber;
} IMAGE_INFO, *PIMAGE_INFO;

If the ExtendedInfoPresent flag is set, the IMAGE_INFO structure is part of a larger, extended version of the image information structure. In this case, the load-image notify routine can use the CONTAINING_RECORD macro in the Winnt.h header file to obtain the base address of the following structure:


typedef struct _IMAGE_INFO_EX {
    SIZE_T              Size;
    IMAGE_INFO          ImageInfo;
    struct _FILE_OBJECT *FileObject;
} IMAGE_INFO_EX, *PIMAGE_INFO_EX;

The Size field specifies the size, in bytes, of the IMAGE_INFO_EX structure. The FileObject field contains a pointer to the file object of the backing file for the image. The driver can take a reference to this object or use it for other operations.

Requirements

Version

Available starting with Windows 2000.

Header

Ntddk.h (include Ntddk.h)

Library

Ntoskrnl.lib

IRQL

PASSIVE_LEVEL

DDI compliance rules

IrqlPsPassive, PowerIrpDDis, HwStorPortProhibitedDDIs

See also

PsGetCurrentProcessId
PsRemoveLoadImageNotifyRoutine
PsSetCreateProcessNotifyRoutine
PsSetCreateThreadNotifyRoutine

 

 

Send comments about this topic to Microsoft

Show:
© 2014 Microsoft. All rights reserved.