ReactOS 0.4.17-dev-1196-gb6224c3
driver.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <mm/ARM3/miarm.h>
Include dependency graph for driver.c:

Go to the source code of this file.

Classes

struct  _LOAD_UNLOAD_PARAMS
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _LOAD_UNLOAD_PARAMS LOAD_UNLOAD_PARAMS
 
typedef struct _LOAD_UNLOAD_PARAMS * PLOAD_UNLOAD_PARAMS
 

Functions

NTSTATUS IopDoLoadUnloadDriver (_In_opt_ PUNICODE_STRING RegistryPath, _Inout_ PDRIVER_OBJECT *DriverObject)
 Process load and unload driver operations. This is mostly for NtLoadDriver and NtUnloadDriver, because their code should run inside PsInitialSystemProcess.
 
NTSTATUS NTAPI IopInvalidDeviceRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
VOID NTAPI IopDeleteDriver (IN PVOID ObjectBody)
 
NTSTATUS IopGetDriverNames (_In_ HANDLE ServiceHandle, _Out_ PUNICODE_STRING DriverName, _Out_opt_ PUNICODE_STRING ServiceName)
 
static BOOLEAN IopSuffixUnicodeString (_In_ PCUNICODE_STRING String1, _In_ PCUNICODE_STRING String2, _In_ BOOLEAN CaseInSensitive)
 Determines whether String1 may be a suffix of String2.
 
static VOID FASTCALL IopDisplayLoadingMessage (_In_ PCUNICODE_STRING ServiceName)
 Displays a driver-loading message in SOS mode.
 
NTSTATUS FASTCALL IopNormalizeImagePath (_Inout_ _When_(return >=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem))) PUNICODE_STRING ImagePath, _In_ PUNICODE_STRING ServiceName)
 
NTSTATUS IopInitializeDriverModule (_In_ PLDR_DATA_TABLE_ENTRY ModuleObject, _In_ HANDLE ServiceHandle, _Out_ PDRIVER_OBJECT *OutDriverObject, _Out_ NTSTATUS *DriverEntryStatus)
 Initialize a loaded driver.
 
NTSTATUS NTAPI MiResolveImageReferences (IN PVOID ImageBase, IN PUNICODE_STRING ImageFileDirectory, IN PUNICODE_STRING NamePrefix OPTIONAL, OUT PCHAR *MissingApi, OUT PWCHAR *MissingDriver, OUT PLOAD_IMPORTS *LoadImports)
 
NTSTATUS NTAPI LdrProcessDriverModule (PLDR_DATA_TABLE_ENTRY LdrEntry, PUNICODE_STRING FileName, PLDR_DATA_TABLE_ENTRY *ModuleObject)
 
PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance (PUNICODE_STRING DeviceInstance)
 
static BOOLEAN IopInitializeBuiltinDriver (IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
 
VOID FASTCALL IopInitializeBootDrivers (VOID)
 
VOID FASTCALL IopInitializeSystemDrivers (VOID)
 
NTSTATUS NTAPI IopUnloadDriver (PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
 
VOID NTAPI IopReinitializeDrivers (VOID)
 
VOID NTAPI IopReinitializeBootDrivers (VOID)
 
NTSTATUS NTAPI IoCreateDriver (_In_opt_ PUNICODE_STRING DriverName, _In_ PDRIVER_INITIALIZE InitializationFunction)
 
VOID NTAPI IoDeleteDriver (_In_ PDRIVER_OBJECT DriverObject)
 
VOID NTAPI IoRegisterBootDriverReinitialization (IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
 
VOID NTAPI IoRegisterDriverReinitialization (IN PDRIVER_OBJECT DriverObject, IN PDRIVER_REINITIALIZE ReinitRoutine, IN PVOID Context)
 
NTSTATUS NTAPI IoAllocateDriverObjectExtension (IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
 
PVOID NTAPI IoGetDriverObjectExtension (IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
 
NTSTATUS IopLoadDriver (_In_ HANDLE ServiceHandle, _Out_ PDRIVER_OBJECT *DriverObject)
 
static VOID NTAPI IopLoadUnloadDriverWorker (_Inout_ PVOID Parameter)
 
NTSTATUS NTAPI NtLoadDriver (IN PUNICODE_STRING DriverServiceName)
 
NTSTATUS NTAPI NtUnloadDriver (IN PUNICODE_STRING DriverServiceName)
 

Variables

ERESOURCE IopDriverLoadResource
 
LIST_ENTRY DriverReinitListHead
 
KSPIN_LOCK DriverReinitListLock
 
PLIST_ENTRY DriverReinitTailEntry
 
PLIST_ENTRY DriverBootReinitTailEntry
 
LIST_ENTRY DriverBootReinitListHead
 
KSPIN_LOCK DriverBootReinitListLock
 
UNICODE_STRING IopHardwareDatabaseKey
 
static const WCHAR ServicesKeyName [] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
 
POBJECT_TYPE IoDriverObjectType = NULL
 
BOOLEAN PnpSystemInit
 
BOOLEAN PnPBootDriversLoaded
 
KEVENT PiEnumerationFinished
 
USHORT IopGroupIndex
 
PLIST_ENTRY IopGroupTable
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file driver.c.

Typedef Documentation

◆ LOAD_UNLOAD_PARAMS

◆ PLOAD_UNLOAD_PARAMS

Function Documentation

◆ IoAllocateDriverObjectExtension()

NTSTATUS NTAPI IoAllocateDriverObjectExtension ( IN PDRIVER_OBJECT  DriverObject,
IN PVOID  ClientIdentificationAddress,
IN ULONG  DriverObjectExtensionSize,
OUT PVOID *  DriverObjectExtension 
)

Definition at line 1847 of file driver.c.

1851{
1852 KIRQL OldIrql;
1853 PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1854 BOOLEAN Inserted = FALSE;
1855
1856 /* Assume failure */
1857 *DriverObjectExtension = NULL;
1858
1859 /* Allocate the extension */
1860 NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1861 sizeof(IO_CLIENT_EXTENSION) +
1862 DriverObjectExtensionSize,
1864 if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1865
1866 /* Clear the extension for teh caller */
1867 RtlZeroMemory(NewDriverExtension,
1868 sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1869
1870 /* Acqure lock */
1872
1873 /* Fill out the extension */
1875
1876 /* Loop the current extensions */
1877 DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1878 ClientDriverExtension;
1879 while (DriverExtensions)
1880 {
1881 /* Check if the identifier matches */
1882 if (DriverExtensions->ClientIdentificationAddress ==
1884 {
1885 /* We have a collision, break out */
1886 break;
1887 }
1888
1889 /* Go to the next one */
1890 DriverExtensions = DriverExtensions->NextExtension;
1891 }
1892
1893 /* Check if we didn't collide */
1894 if (!DriverExtensions)
1895 {
1896 /* Link this one in */
1897 NewDriverExtension->NextExtension =
1898 IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1899 IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1900 NewDriverExtension;
1901 Inserted = TRUE;
1902 }
1903
1904 /* Release the lock */
1906
1907 /* Check if insertion failed */
1908 if (!Inserted)
1909 {
1910 /* Free the entry and fail */
1911 ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1913 }
1914
1915 /* Otherwise, return the pointer */
1916 *DriverObjectExtension = NewDriverExtension + 1;
1917 return STATUS_SUCCESS;
1918}
unsigned char BOOLEAN
Definition: actypes.h:127
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define NonPagedPool
Definition: env_spec_w32.h:307
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:68
static LPWSTR ClientIdentificationAddress
Definition: hidclass.c:16
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define IoGetDrvObjExtension(DriverObject)
Definition: io.h:135
#define STATUS_SUCCESS
Definition: shellext.h:65
PVOID ClientIdentificationAddress
Definition: iotypes.h:989
struct _IO_CLIENT_EXTENSION * NextExtension
Definition: iotypes.h:988
#define TAG_DRIVER_EXTENSION
Definition: tag.h:61
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by _IRQL_requires_max_(), DriverEntry(), HidRegisterMinidriver(), KoDriverInitialize(), KsInitializeDriver(), Mx::MxAllocateDriverObjectExtension(), NdisMRegisterMiniport(), PciIdeXInitialize(), ScsiPortInitialize(), StorPortInitialize(), StreamClassRegisterAdapter(), VideoPortInitialize(), and WdfWriteKmdfVersionToRegistry().

◆ IoCreateDriver()

NTSTATUS NTAPI IoCreateDriver ( _In_opt_ PUNICODE_STRING  DriverName,
_In_ PDRIVER_INITIALIZE  InitializationFunction 
)

Definition at line 1594 of file driver.c.

1597{
1598 WCHAR NameBuffer[100];
1599 USHORT NameLength;
1600 UNICODE_STRING LocalDriverName;
1603 ULONG ObjectSize;
1605 UNICODE_STRING ServiceKeyName;
1607 ULONG i, RetryCount = 0;
1608
1609try_again:
1610 /* First, create a unique name for the driver if we don't have one */
1611 if (!DriverName)
1612 {
1613 /* Create a random name and set up the string */
1614 NameLength = (USHORT)_swprintf(NameBuffer,
1615 DRIVER_ROOT_NAME L"%08u",
1617 LocalDriverName.Length = NameLength * sizeof(WCHAR);
1618 LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1619 LocalDriverName.Buffer = NameBuffer;
1620 }
1621 else
1622 {
1623 /* So we can avoid another code path, use a local var */
1624 LocalDriverName = *DriverName;
1625 }
1626
1627 /* Initialize the Attributes */
1628 ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1630 &LocalDriverName,
1632 NULL,
1633 NULL);
1634
1635 /* Create the Object */
1639 KernelMode,
1640 NULL,
1641 ObjectSize,
1642 0,
1643 0,
1644 (PVOID*)&DriverObject);
1645 if (!NT_SUCCESS(Status)) return Status;
1646
1647 DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1648
1649 /* Set up the Object */
1650 RtlZeroMemory(DriverObject, ObjectSize);
1652 DriverObject->Size = sizeof(DRIVER_OBJECT);
1654 DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
1655 DriverObject->DriverExtension->DriverObject = DriverObject;
1656 DriverObject->DriverInit = InitializationFunction;
1657 /* Loop all Major Functions */
1658 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1659 {
1660 /* Invalidate each function */
1661 DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1662 }
1663
1664 /* Set up the service key name buffer */
1665 ServiceKeyName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1666 ServiceKeyName.Buffer = ExAllocatePoolWithTag(PagedPool, LocalDriverName.MaximumLength, TAG_IO);
1667 if (!ServiceKeyName.Buffer)
1668 {
1669 /* Fail */
1673 }
1674
1675 /* For builtin drivers, the ServiceKeyName is equal to DriverName */
1676 RtlCopyUnicodeString(&ServiceKeyName, &LocalDriverName);
1677 ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1678 DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1679
1680 /* Make a copy of the driver name to store in the driver object */
1681 DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1682 DriverObject->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
1683 DriverObject->DriverName.MaximumLength,
1684 TAG_IO);
1685 if (!DriverObject->DriverName.Buffer)
1686 {
1687 /* Fail */
1691 }
1692
1693 RtlCopyUnicodeString(&DriverObject->DriverName, &LocalDriverName);
1694
1695 /* Add the Object and get its handle */
1697 NULL,
1699 0,
1700 NULL,
1701 &hDriver);
1702
1703 /* Eliminate small possibility when this function is called more than
1704 once in a row, and KeTickCount doesn't get enough time to change */
1705 if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1706 {
1707 RetryCount++;
1708 goto try_again;
1709 }
1710
1711 if (!NT_SUCCESS(Status)) return Status;
1712
1713 /* Now reference it */
1715 0,
1717 KernelMode,
1719 NULL);
1720
1721 /* Close the extra handle */
1723
1724 if (!NT_SUCCESS(Status))
1725 {
1726 /* Fail */
1729 return Status;
1730 }
1731
1732 /* Finally, call its init function */
1733 DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1734 Status = InitializationFunction(DriverObject, NULL);
1735 if (!NT_SUCCESS(Status))
1736 {
1737 /* If it didn't work, then kill the object */
1738 DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", &LocalDriverName, Status);
1741 return Status;
1742 }
1743
1744 /* Give the Kernel Shim Engine a chance to hook the driver callbacks */
1746
1747 /* Windows does this fixup, keep it for compatibility */
1748 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1749 {
1750 /*
1751 * Make sure the driver didn't set any dispatch entry point to NULL!
1752 * Doing so is illegal; drivers shouldn't touch entry points they
1753 * do not implement.
1754 */
1755
1756 /* Check if it did so anyway */
1757 if (!DriverObject->MajorFunction[i])
1758 {
1759 /* Print a warning in the debug log */
1760 DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1761 &DriverObject->DriverName, i);
1762
1763 /* Fix it up */
1764 DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1765 }
1766 }
1767
1768 /* Return the Status */
1769 return Status;
1770}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define L(x)
Definition: resources.c:13
#define PagedPool
Definition: env_spec_w32.h:308
Status
Definition: gdiplustypes.h:24
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS NTAPI KseShimDriverIoCallbacks(_In_ PDRIVER_OBJECT DriverObject)
Definition: kse.c:301
#define DRIVER_ROOT_NAME
Definition: ldr.h:5
#define _swprintf(buf, format,...)
Definition: sprintf.c:56
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
#define KernelMode
Definition: asm.h:38
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define FILE_READ_DATA
Definition: nt_native.h:628
#define UNICODE_NULL
NTKERNELAPI volatile KSYSTEM_TIME KeTickCount
Definition: clock.c:19
POBJECT_TYPE IoDriverObjectType
Definition: driver.c:34
NTSTATUS NTAPI IopInvalidDeviceRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: driver.c:65
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2962
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1049
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1459
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:493
short WCHAR
Definition: pedump.c:58
unsigned short USHORT
Definition: pedump.c:61
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
#define DPRINT
Definition: sndvol32.h:73
PDRIVER_INITIALIZE DriverInit
Definition: iotypes.h:2301
ULONG LowPart
Definition: wdm.h:5
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TAG_IO
Definition: tag.h:79
uint32_t ULONG
Definition: typedefs.h:59
_In_ LPWSTR _In_ ULONG _In_ ULONG _In_ ULONG _Out_ DEVINFO _In_ HDEV _In_ LPWSTR _In_ HANDLE hDriver
Definition: winddi.h:3557
#define DRVO_BUILTIN_DRIVER
Definition: iotypes.h:2242
struct _DRIVER_OBJECT DRIVER_OBJECT
struct _DRIVER_EXTENSION * PDRIVER_EXTENSION
#define IO_TYPE_DRIVER
#define IRP_MJ_MAXIMUM_FUNCTION
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by HaliInitPnpDriver(), IopInitializeBootDrivers(), IopInitializePlugPlayServices(), KdpInitDriver(), and WmiInitialize().

◆ IoDeleteDriver()

VOID NTAPI IoDeleteDriver ( _In_ PDRIVER_OBJECT  DriverObject)

Definition at line 1777 of file driver.c.

1779{
1780 /* Simply dereference the Object */
1782}

Referenced by KdpDriverReinit().

◆ IoGetDriverObjectExtension()

PVOID NTAPI IoGetDriverObjectExtension ( IN PDRIVER_OBJECT  DriverObject,
IN PVOID  ClientIdentificationAddress 
)

Definition at line 1925 of file driver.c.

1927{
1928 KIRQL OldIrql;
1929 PIO_CLIENT_EXTENSION DriverExtensions;
1930
1931 /* Acquire lock */
1933
1934 /* Loop the list until we find the right one */
1935 DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1936 while (DriverExtensions)
1937 {
1938 /* Check for a match */
1939 if (DriverExtensions->ClientIdentificationAddress ==
1941 {
1942 /* Break out */
1943 break;
1944 }
1945
1946 /* Keep looping */
1947 DriverExtensions = DriverExtensions->NextExtension;
1948 }
1949
1950 /* Release lock */
1952
1953 /* Return nothing or the extension */
1954 if (!DriverExtensions) return NULL;
1955 return DriverExtensions + 1;
1956}

Referenced by _Dispatch_type_(), _IRQL_requires_max_(), ClassAddDevice(), ClassDispatchPnp(), ClassGetPdoId(), ClassPnpQueryFdoRelations(), ClassPnpStartDevice(), ClassUnload(), ConDrvCreateController(), ConDrvDeleteController(), CreateClassDeviceObject(), CreateGreenFdo(), DestroyPortDriver(), GreenAddDevice(), GreenDispatch(), HidClassAddDevice(), i8042RemoveDevice(), IntVideoPortAddDevice(), IntVideoPortFilterResourceRequirements(), IntVideoPortPnPStartDevice(), KeyboardAddDevice(), KopDispatchCreate(), KsAddDevice(), Mx::MxGetDriverObjectExtension(), NdisIAddDevice(), PciIdeXAddDeviceEx(), PortAddDevice(), PortUnload(), ScreenAddDevice(), ScsiPortInitialize(), SermouseAddDevice(), StorPortInitialize(), StreamClassAddDevice(), StreamClassStartDevice(), VfdCreateDevice(), VfdDeleteDevice(), VfdStoreLink(), VfdUnloadDriver(), VideoPortGetAccessRanges(), VideoPortInitialize(), and WdfDeleteKmdfVersionFromRegistry().

◆ IopDeleteDriver()

VOID NTAPI IopDeleteDriver ( IN PVOID  ObjectBody)

Definition at line 77 of file driver.c.

78{
79 PDRIVER_OBJECT DriverObject = ObjectBody;
80 PIO_CLIENT_EXTENSION DriverExtension, NextDriverExtension;
81 PAGED_CODE();
82
83 DPRINT1("Deleting driver object '%wZ'\n", &DriverObject->DriverName);
84
85 /* There must be no device objects remaining at this point */
86 ASSERT(!DriverObject->DeviceObject);
87
88 /* Get the extension and loop them */
89 DriverExtension = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
90 while (DriverExtension)
91 {
92 /* Get the next one */
93 NextDriverExtension = DriverExtension->NextExtension;
95
96 /* Move on */
97 DriverExtension = NextDriverExtension;
98 }
99
100 /* Check if the driver image is still loaded */
101 if (DriverObject->DriverSection)
102 {
103 /* Unload it */
104 MmUnloadSystemImage(DriverObject->DriverSection);
105 }
106
107 /* Check if it has a name */
108 if (DriverObject->DriverName.Buffer)
109 {
110 /* Free it */
111 ExFreePool(DriverObject->DriverName.Buffer);
112 }
113
114 /* Check if it has a service key name */
115 if (DriverObject->DriverExtension->ServiceKeyName.Buffer)
116 {
117 /* Free it */
118 ExFreePool(DriverObject->DriverExtension->ServiceKeyName.Buffer);
119 }
120}
#define PAGED_CODE()
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define ASSERT(a)
Definition: mode.c:44
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:976
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:31

Referenced by IopCreateObjectTypes().

◆ IopDisplayLoadingMessage()

static VOID FASTCALL IopDisplayLoadingMessage ( _In_ PCUNICODE_STRING  ServiceName)
static

Displays a driver-loading message in SOS mode.

Definition at line 334 of file driver.c.

336{
337 extern BOOLEAN SosEnabled; // See ex/init.c
338 static const UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS");
339 CHAR TextBuffer[256];
340
341 if (!SosEnabled) return;
342 if (!KeLoaderBlock) return;
344 "%s%sSystem32\\Drivers\\%wZ%s\r\n",
349 ? "" : ".SYS");
351}
static WCHAR ServiceName[]
Definition: browser.c:20
char TextBuffer[BUFFERLEN]
Definition: combotst.c:45
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
static BOOLEAN IopSuffixUnicodeString(_In_ PCUNICODE_STRING String1, _In_ PCUNICODE_STRING String2, _In_ BOOLEAN CaseInSensitive)
Determines whether String1 may be a suffix of String2.
Definition: driver.c:286
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
NTSYSAPI PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:28
char CHAR
Definition: pedump.c:57
PSTR ArcBootDeviceName
Definition: arc.h:841
BOOLEAN SosEnabled
Definition: winldr.c:34

Referenced by IopInitializeBuiltinDriver(), and IopLoadDriver().

◆ IopDoLoadUnloadDriver()

NTSTATUS IopDoLoadUnloadDriver ( _In_opt_ PUNICODE_STRING  RegistryPath,
_Inout_ PDRIVER_OBJECT *  DriverObject 
)

Process load and unload driver operations. This is mostly for NtLoadDriver and NtUnloadDriver, because their code should run inside PsInitialSystemProcess.

Parameters
[in]RegistryPathThe registry path
DriverObjectThe driver object
Returns
Status of the operation

Definition at line 2126 of file driver.c.

2129{
2130 LOAD_UNLOAD_PARAMS LoadParams;
2131
2132 /* Prepare parameters block */
2133 LoadParams.RegistryPath = RegistryPath;
2134 LoadParams.DriverObject = *DriverObject;
2135
2137 {
2138 LoadParams.SetEvent = TRUE;
2140
2141 /* Initialize and queue a work item */
2142 ExInitializeWorkItem(&LoadParams.WorkItem, IopLoadUnloadDriverWorker, &LoadParams);
2144
2145 /* And wait till it completes */
2147 }
2148 else
2149 {
2150 /* If we're already in a system process, call it right here */
2151 LoadParams.SetEvent = FALSE;
2152 IopLoadUnloadDriverWorker(&LoadParams);
2153 }
2154
2155 return LoadParams.Status;
2156}
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
@ NotificationEvent
static VOID NTAPI IopLoadUnloadDriverWorker(_Inout_ PVOID Parameter)
Definition: driver.c:2080
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
WORK_QUEUE_ITEM WorkItem
Definition: driver.c:50
NTSTATUS Status
Definition: driver.c:48
BOOLEAN SetEvent
Definition: driver.c:53
PUNICODE_STRING RegistryPath
Definition: driver.c:49
PDRIVER_OBJECT DriverObject
Definition: driver.c:52
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:727
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ DelayedWorkQueue
Definition: extypes.h:190
@ UserRequest
Definition: ketypes.h:473
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by IopUnloadDriver(), and NtLoadDriver().

◆ IopGetDeviceObjectFromDeviceInstance()

PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance ( PUNICODE_STRING  DeviceInstance)

Definition at line 234 of file plugplay.c.

235{
237 IOP_FIND_DEVICE_INSTANCE_TRAVERSE_CONTEXT DeviceInstanceContext;
238
239 if (IopRootDeviceNode == NULL)
240 return NULL;
241
242 if (DeviceInstance == NULL ||
243 DeviceInstance->Length == 0)
244 {
246 {
249 }
250 else
251 return NULL;
252 }
253
254 /* Traverse the device tree to find the matching device node */
255 DeviceInstanceContext.InstancePath = DeviceInstance;
256 DeviceInstanceContext.DeviceObject = NULL;
260 &DeviceInstanceContext);
262
263 /* In case of error or instance not found, this will still be NULL from above. */
264 return DeviceInstanceContext.DeviceObject;
265}
static const WCHAR DeviceInstance[]
Definition: interface.c:28
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define IopInitDeviceTreeTraverseContext( _DeviceTreeTraverseContext, _DeviceNode, _Action, _Context)
Definition: io.h:228
NTSTATUS IopTraverseDeviceTree(PDEVICETREE_TRAVERSE_CONTEXT Context)
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
NTSTATUS IopFindDeviceInstanceTraverse(_In_ PDEVICE_NODE DeviceNode, _Inout_ PVOID Context)
Definition: plugplay.c:214
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:1015
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by IopInitializeBuiltinDriver().

◆ IopGetDriverNames()

NTSTATUS IopGetDriverNames ( _In_ HANDLE  ServiceHandle,
_Out_ PUNICODE_STRING  DriverName,
_Out_opt_ PUNICODE_STRING  ServiceName 
)

Definition at line 123 of file driver.c.

127{
128 UNICODE_STRING driverName = {.Buffer = NULL}, serviceName;
131
132 PAGED_CODE();
133
134 /* 1. Check the "ObjectName" field in the driver's registry key (it has priority) */
135 status = IopGetRegistryValue(ServiceHandle, L"ObjectName", &kvInfo);
136 if (NT_SUCCESS(status))
137 {
138 /* We've got the ObjectName, use it as the driver name */
139 if ((kvInfo->Type != REG_SZ) ||
140 (kvInfo->DataLength < sizeof(UNICODE_NULL)) ||
142 ((kvInfo->DataLength % sizeof(WCHAR)) != 0))
143 {
144 DPRINT1("ObjectName invalid (Type = %lu, DataLength = %lu)\n",
145 kvInfo->Type,
146 kvInfo->DataLength);
147 ExFreePool(kvInfo);
149 }
150
151 driverName.Length = (USHORT)(kvInfo->DataLength - sizeof(UNICODE_NULL));
152 driverName.MaximumLength = kvInfo->DataLength;
154 if (!driverName.Buffer)
155 {
156 ExFreePool(kvInfo);
158 }
159
160 RtlMoveMemory(driverName.Buffer,
161 (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
162 driverName.Length);
163 driverName.Buffer[driverName.Length / sizeof(WCHAR)] = UNICODE_NULL;
164 ExFreePool(kvInfo);
165 }
166
167 /* Check whether we need to get ServiceName as well, either to construct
168 * the driver name (because we could not use "ObjectName"), or because
169 * it is requested by the caller. */
170 PKEY_BASIC_INFORMATION basicInfo = NULL;
171 if (!NT_SUCCESS(status) || ServiceName != NULL)
172 {
173 /* Retrieve the necessary buffer size */
174 ULONG infoLength;
175 status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
177 {
179 goto Cleanup;
180 }
181
182 /* Allocate the buffer and retrieve the data */
183 basicInfo = ExAllocatePoolWithTag(PagedPool, infoLength, TAG_IO);
184 if (!basicInfo)
185 {
187 goto Cleanup;
188 }
189
190 status = ZwQueryKey(ServiceHandle, KeyBasicInformation, basicInfo, infoLength, &infoLength);
191 if (!NT_SUCCESS(status))
192 {
193 goto Cleanup;
194 }
195
196 serviceName.Length = basicInfo->NameLength;
197 serviceName.MaximumLength = basicInfo->NameLength;
198 serviceName.Buffer = basicInfo->Name;
199 }
200
201 /* 2. There is no "ObjectName" - construct it ourselves. Depending on the driver type,
202 * it will be either "\Driver<ServiceName>" or "\FileSystem<ServiceName>" */
203 if (driverName.Buffer == NULL)
204 {
205 ASSERT(basicInfo); // Container for serviceName
206
207 /* Retrieve the driver type */
208 ULONG driverType;
209 status = IopGetRegistryValue(ServiceHandle, L"Type", &kvInfo);
210 if (!NT_SUCCESS(status))
211 {
212 goto Cleanup;
213 }
214 if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
215 {
216 ExFreePool(kvInfo);
218 goto Cleanup;
219 }
220
221 RtlMoveMemory(&driverType,
222 (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
223 sizeof(ULONG));
224 ExFreePool(kvInfo);
225
226 /* Compute the necessary driver name string size */
227 if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
228 driverName.MaximumLength = sizeof(FILESYSTEM_ROOT_NAME);
229 else
230 driverName.MaximumLength = sizeof(DRIVER_ROOT_NAME);
231
232 driverName.MaximumLength += serviceName.Length;
233 driverName.Length = 0;
234
235 /* Allocate and build it */
237 if (!driverName.Buffer)
238 {
240 goto Cleanup;
241 }
242
243 if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
245 else
247
249 }
250
251 if (ServiceName != NULL)
252 {
253 ASSERT(basicInfo); // Container for serviceName
254
255 /* Allocate a copy for the caller */
257 if (!buf)
258 {
260 goto Cleanup;
261 }
262 RtlMoveMemory(buf, serviceName.Buffer, serviceName.Length);
263 ServiceName->MaximumLength = serviceName.Length;
264 ServiceName->Length = serviceName.Length;
265 ServiceName->Buffer = buf;
266 }
267
268 *DriverName = driverName;
270
271Cleanup:
272 if (basicInfo)
273 ExFreePoolWithTag(basicInfo, TAG_IO);
274
275 if (!NT_SUCCESS(status) && driverName.Buffer)
276 ExFreePoolWithTag(driverName.Buffer, TAG_IO);
277
278 return status;
279}
#define REG_SZ
Definition: layer.c:22
static const WCHAR Cleanup[]
Definition: register.c:80
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define FILESYSTEM_ROOT_NAME
Definition: ldr.h:6
@ KeyBasicInformation
Definition: nt_native.h:1134
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define UNICODE_STRING_MAX_BYTES
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1036
#define STATUS_ILL_FORMED_SERVICE_ENTRY
Definition: ntstatus.h:682
#define REG_DWORD
Definition: sdbapi.c:615
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
Definition: ps.c:97
char serviceName[]
Definition: tftpd.cpp:34
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define SERVICE_RECOGNIZER_DRIVER
Definition: cmtypes.h:957
#define SERVICE_FILE_SYSTEM_DRIVER
Definition: cmtypes.h:955

Referenced by IopInitializeDriverModule(), and PiAttachFilterDriversCallback().

◆ IopInitializeBootDrivers()

VOID FASTCALL IopInitializeBootDrivers ( VOID  )

Definition at line 1041 of file driver.c.

1042{
1043 PLIST_ENTRY ListHead, NextEntry, NextEntry2;
1044 PLDR_DATA_TABLE_ENTRY LdrEntry;
1046 UNICODE_STRING DriverName;
1047 ULONG i, Index;
1048 PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
1050 PBOOT_DRIVER_LIST_ENTRY BootEntry;
1051 DPRINT("IopInitializeBootDrivers()\n");
1052
1053 /* Create the RAW FS built-in driver */
1054 RtlInitUnicodeString(&DriverName, L"\\FileSystem\\RAW");
1055
1056 Status = IoCreateDriver(&DriverName, RawFsDriverEntry);
1057 if (!NT_SUCCESS(Status))
1058 {
1059 /* Fail */
1060 return;
1061 }
1062
1063 /* Get highest group order index */
1065 if (IopGroupIndex == 0xFFFF)
1066 {
1068 }
1069
1070 /* Allocate the group table */
1072 IopGroupIndex * sizeof(LIST_ENTRY),
1073 TAG_IO);
1074 if (IopGroupTable == NULL)
1075 {
1077 }
1078
1079 /* Initialize the group table lists */
1080 for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
1081
1082 /* Loop the boot modules */
1083 ListHead = &KeLoaderBlock->LoadOrderListHead;
1084 for (NextEntry = ListHead->Flink;
1085 NextEntry != ListHead;
1086 NextEntry = NextEntry->Flink)
1087 {
1088 /* Get the entry */
1089 LdrEntry = CONTAINING_RECORD(NextEntry,
1091 InLoadOrderLinks);
1092
1093 /* Check if the DLL needs to be initialized */
1094 if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1095 {
1096 /* Call its entrypoint */
1097 MmCallDllInitialize(LdrEntry, NULL);
1098 }
1099 }
1100
1101 /* Loop the boot drivers */
1102 ListHead = &KeLoaderBlock->BootDriverListHead;
1103 for (NextEntry = ListHead->Flink;
1104 NextEntry != ListHead;
1105 NextEntry = NextEntry->Flink)
1106 {
1107 /* Get the entry */
1108 BootEntry = CONTAINING_RECORD(NextEntry,
1110 Link);
1111
1112 // FIXME: TODO: This LdrEntry is to be used in a special handling
1113 // for SETUPLDR (a similar procedure is done on Windows), where
1114 // the loader would, under certain conditions, be loaded in the
1115 // SETUPLDR-specific code block below...
1116#if 0
1117 /* Get the driver loader entry */
1118 LdrEntry = BootEntry->LdrEntry;
1119#endif
1120
1121 /* Allocate our internal accounting structure */
1123 sizeof(DRIVER_INFORMATION),
1124 TAG_IO);
1125 if (DriverInfo)
1126 {
1127 /* Zero it and initialize it */
1130 DriverInfo->DataTableEntry = BootEntry;
1131
1132 /* Open the registry key */
1134 NULL,
1135 &BootEntry->RegistryPath,
1136 KEY_READ);
1137 DPRINT("IopOpenRegistryKeyEx(%wZ) returned 0x%08lx\n", &BootEntry->RegistryPath, Status);
1138#if 0
1139 if (NT_SUCCESS(Status))
1140#else // Hack still needed...
1141 if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
1142 ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
1143#endif
1144 {
1145 /* Save the handle */
1147
1148 /* Get the group oder index */
1150
1151 /* Get the tag position */
1153
1154 /* Insert it into the list, at the right place */
1156 NextEntry2 = IopGroupTable[Index].Flink;
1157 while (NextEntry2 != &IopGroupTable[Index])
1158 {
1159 /* Get the driver info */
1160 DriverInfoTag = CONTAINING_RECORD(NextEntry2,
1162 Link);
1163
1164 /* Check if we found the right tag position */
1165 if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
1166 {
1167 /* We're done */
1168 break;
1169 }
1170
1171 /* Next entry */
1172 NextEntry2 = NextEntry2->Flink;
1173 }
1174
1175 /* Insert us right before the next entry */
1176 NextEntry2 = NextEntry2->Blink;
1177 InsertHeadList(NextEntry2, &DriverInfo->Link);
1178 }
1179 }
1180 }
1181
1182 /* Loop each group index */
1183 for (i = 0; i < IopGroupIndex; i++)
1184 {
1185 /* Loop each group table */
1186 for (NextEntry = IopGroupTable[i].Flink;
1187 NextEntry != &IopGroupTable[i];
1188 NextEntry = NextEntry->Flink)
1189 {
1190 /* Get the entry */
1191 DriverInfo = CONTAINING_RECORD(NextEntry,
1193 Link);
1194
1195 /* Get the driver loader entry */
1196 LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
1197
1198 /* Initialize it */
1199 if (IopInitializeBuiltinDriver(LdrEntry))
1200 {
1201 // it does not make sense to enumerate the tree if there are no new devices added
1204 NULL,
1205 NULL);
1206 }
1207 }
1208 }
1209
1210 /* HAL Root Bus is being initialized before loading the boot drivers so this may cause issues
1211 * when some devices are not being initialized with their drivers. This flag is used to delay
1212 * all actions with devices (except PnP root device) until boot drivers are loaded.
1213 * See PiQueueDeviceAction function
1214 */
1216
1217 DbgPrint("BOOT DRIVERS LOADED\n");
1218
1221 NULL,
1222 NULL);
1223}
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define InsertHeadList(ListHead, Entry)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DbgPrint
Definition: hal.h:12
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:60
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
DRIVER_INFORMATION DriverInfo
Definition: main.c:60
#define KEY_READ
Definition: nt_native.h:1026
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:885
NTSTATUS NTAPI RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: rawfs.c:1193
@ PiActionEnumRootDevices
Definition: io.h:526
@ PiActionEnumDeviceTree
Definition: io.h:525
USHORT NTAPI PpInitGetGroupOrderIndex(IN HANDLE ServiceHandle)
Definition: pnpinit.c:149
USHORT NTAPI PipGetDriverTagPriority(IN HANDLE ServiceHandle)
Definition: pnpinit.c:192
VOID PiQueueDeviceAction(_In_ PDEVICE_OBJECT DeviceObject, _In_ DEVICE_ACTION Action, _In_opt_ PKEVENT CompletionEvent, _Out_opt_ NTSTATUS *CompletionStatus)
Queue a device operation to a worker thread.
Definition: devaction.c:2668
NTSTATUS NTAPI MmCallDllInitialize(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry, _In_ PLIST_ENTRY ModuleListHead)
Definition: sysldr.c:464
static BOOLEAN IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
Definition: driver.c:816
NTSTATUS NTAPI IoCreateDriver(_In_opt_ PUNICODE_STRING DriverName, _In_ PDRIVER_INITIALIZE InitializationFunction)
Definition: driver.c:1594
PLIST_ENTRY IopGroupTable
Definition: driver.c:41
USHORT IopGroupIndex
Definition: driver.c:40
BOOLEAN PnPBootDriversLoaded
Definition: pnpinit.c:20
Definition: arc.h:334
UNICODE_STRING RegistryPath
Definition: arc.h:337
struct _LDR_DATA_TABLE_ENTRY * LdrEntry
Definition: arc.h:338
HANDLE ServiceHandle
Definition: io.h:405
PBOOT_DRIVER_LIST_ENTRY DataTableEntry
Definition: io.h:404
LIST_ENTRY Link
Definition: io.h:402
USHORT TagPosition
Definition: io.h:406
Definition: btrfs_drv.h:1876
ULONG Flags
Definition: ntddk_ex.h:207
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY BootDriverListHead
Definition: arc.h:822
LIST_ENTRY LoadOrderListHead
Definition: arc.h:820
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
static int Link(const char **args)
Definition: vfdcmd.c:2414
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by IoInitSystem().

◆ IopInitializeBuiltinDriver()

static BOOLEAN IopInitializeBuiltinDriver ( IN PLDR_DATA_TABLE_ENTRY  BootLdrEntry)
static

Definition at line 816 of file driver.c.

817{
820 PWCHAR Buffer, FileNameWithoutPath;
821 PWSTR FileExtension;
822 PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
823 PLDR_DATA_TABLE_ENTRY LdrEntry;
824 PLIST_ENTRY NextEntry;
827
828 /*
829 * Display 'Loading XXX...' message
830 */
833
835 ModuleName->Length + sizeof(UNICODE_NULL),
836 TAG_IO);
837 if (Buffer == NULL)
838 {
839 return FALSE;
840 }
841
844
845 /*
846 * Generate filename without path (not needed by freeldr)
847 */
848 FileNameWithoutPath = wcsrchr(Buffer, L'\\');
849 if (FileNameWithoutPath == NULL)
850 {
851 FileNameWithoutPath = Buffer;
852 }
853 else
854 {
855 FileNameWithoutPath++;
856 }
857
858 /*
859 * Strip the file extension from ServiceName
860 */
861 Success = RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
863 if (!Success)
864 {
865 return FALSE;
866 }
867
868 FileExtension = wcsrchr(ServiceName.Buffer, L'.');
869 if (FileExtension != NULL)
870 {
871 ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
872 FileExtension[0] = UNICODE_NULL;
873 }
874
876
877 // Make the registry path for the driver
878 RegistryPath.Length = 0;
879 RegistryPath.MaximumLength = sizeof(ServicesKeyName) + ServiceName.Length;
881 if (RegistryPath.Buffer == NULL)
882 {
883 return FALSE;
884 }
888
889 HANDLE serviceHandle;
892 if (!NT_SUCCESS(Status))
893 {
894 return FALSE;
895 }
896
897 /* Lookup the new Ldr entry in PsLoadedModuleList */
898 for (NextEntry = PsLoadedModuleList.Flink;
899 NextEntry != &PsLoadedModuleList;
900 NextEntry = NextEntry->Flink)
901 {
902 LdrEntry = CONTAINING_RECORD(NextEntry,
904 InLoadOrderLinks);
906 {
907 break;
908 }
909 }
910 ASSERT(NextEntry != &PsLoadedModuleList);
911
912 /* Apply the kernel shims to the driver */
913 KseDriverLoadImage(LdrEntry);
914
915 /*
916 * Initialize the driver
917 */
918 NTSTATUS driverEntryStatus;
920 serviceHandle,
922 &driverEntryStatus);
923
924 if (!NT_SUCCESS(Status))
925 {
926 DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
927 return FALSE;
928 }
929
930 // The driver has been loaded, now check if where are any PDOs
931 // for that driver, and queue AddDevice call for them.
932 // The check is possible because HKLM/SYSTEM/CCS/Services/<ServiceName>/Enum directory
933 // is populated upon a new device arrival based on a (critical) device database
934
935 // Legacy drivers may add devices inside DriverEntry.
936 // We're lazy and always assume that they are doing so
937 BOOLEAN deviceAdded = !!(DriverObject->Flags & DRVO_LEGACY_DRIVER);
938
939 HANDLE enumServiceHandle;
940 UNICODE_STRING enumName = RTL_CONSTANT_STRING(L"Enum");
941
942 Status = IopOpenRegistryKeyEx(&enumServiceHandle, serviceHandle, &enumName, KEY_READ);
943 ZwClose(serviceHandle);
944
945 if (NT_SUCCESS(Status))
946 {
947 ULONG instanceCount = 0;
949 Status = IopGetRegistryValue(enumServiceHandle, L"Count", &kvInfo);
950 if (!NT_SUCCESS(Status))
951 {
952 goto Cleanup;
953 }
954 if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
955 {
956 ExFreePool(kvInfo);
957 goto Cleanup;
958 }
959
960 RtlMoveMemory(&instanceCount,
961 (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
962 sizeof(ULONG));
963 ExFreePool(kvInfo);
964
965 DPRINT("Processing %u instances for %wZ module\n", instanceCount, ModuleName);
966
967 for (ULONG i = 0; i < instanceCount; i++)
968 {
969 WCHAR num[11];
970 UNICODE_STRING instancePath;
971 RtlStringCbPrintfW(num, sizeof(num), L"%u", i);
972
973 Status = IopGetRegistryValue(enumServiceHandle, num, &kvInfo);
974 if (!NT_SUCCESS(Status))
975 {
976 continue;
977 }
978 if ((kvInfo->Type != REG_SZ) ||
979 (kvInfo->DataLength < sizeof(UNICODE_NULL)) ||
981 ((kvInfo->DataLength % sizeof(WCHAR)) != 0))
982 {
983 DPRINT1("ObjectName invalid (Type = %lu, DataLength = %lu)\n",
984 kvInfo->Type,
985 kvInfo->DataLength);
986 ExFreePool(kvInfo);
987 continue;
988 }
989
990 instancePath.Length = (USHORT)(kvInfo->DataLength - sizeof(UNICODE_NULL));
991 instancePath.MaximumLength = kvInfo->DataLength;
993 instancePath.MaximumLength,
994 TAG_IO);
995 if (instancePath.Buffer)
996 {
997 RtlMoveMemory(instancePath.Buffer,
998 (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
999 instancePath.Length);
1000 instancePath.Buffer[instancePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1001
1003 if (pdo != NULL)
1004 {
1007 deviceAdded = TRUE;
1008 }
1009 else
1010 {
1011 DPRINT1("No device node found matching instance path '%wZ'\n", &instancePath);
1012 }
1013 }
1014
1015 ExFreePool(kvInfo);
1016 }
1017
1018 ZwClose(enumServiceHandle);
1019 }
1020Cleanup:
1021 /* Remove extra reference from IopInitializeDriverModule */
1023
1024 return deviceAdded;
1025}
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1280
Definition: bufpool.h:45
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define wcsrchr
Definition: compat.h:16
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
@ Success
Definition: eventcreate.c:712
GLuint GLuint num
Definition: glext.h:9618
VOID NTAPI InbvIndicateProgress(VOID)
Gives some progress feedback, without specifying any explicit number of progress steps or percentage....
Definition: inbv.c:632
NTSTATUS NTAPI KseDriverLoadImage(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: kse.c:773
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
@ PiActionAddBootDevices
Definition: io.h:528
static VOID FASTCALL IopDisplayLoadingMessage(_In_ PCUNICODE_STRING ServiceName)
Displays a driver-loading message in SOS mode.
Definition: driver.c:334
PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance)
Definition: plugplay.c:234
static const WCHAR ServicesKeyName[]
Definition: driver.c:32
NTSTATUS IopInitializeDriverModule(_In_ PLDR_DATA_TABLE_ENTRY ModuleObject, _In_ HANDLE ServiceHandle, _Out_ PDRIVER_OBJECT *OutDriverObject, _Out_ NTSTATUS *DriverEntryStatus)
Initialize a loaded driver.
Definition: driver.c:449
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:149
ACPI_SIZE Length
Definition: actypes.h:1053
uint16_t * PWSTR
Definition: typedefs.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2241

Referenced by IopInitializeBootDrivers().

◆ IopInitializeDriverModule()

NTSTATUS IopInitializeDriverModule ( _In_ PLDR_DATA_TABLE_ENTRY  ModuleObject,
_In_ HANDLE  ServiceHandle,
_Out_ PDRIVER_OBJECT *  OutDriverObject,
_Out_ NTSTATUS *  DriverEntryStatus 
)

Initialize a loaded driver.

Parameters
[in]ModuleObjectModule object representing the driver. It can be retrieved by IopLoadServiceModule. Freed on failure, so in a such case this should not be accessed anymore
[in]ServiceHandleHandle to a driver's CCS/Services/<ServiceName> key
[out]DriverObjectThis contains the driver object if it was created (even with unsuccessfull result)
[out]DriverEntryStatusThis contains the status value returned by the driver's DriverEntry routine (will not be valid of the return value is not STATUS_SUCCESS or STATUS_FAILED_DRIVER_ENTRY)
Returns
Status of the operation

Definition at line 449 of file driver.c.

454{
457
458 PAGED_CODE();
459
460 Status = IopGetDriverNames(ServiceHandle, &DriverName, &ServiceName);
461 if (!NT_SUCCESS(Status))
462 {
463 MmUnloadSystemImage(ModuleObject);
464 return Status;
465 }
466
467 DPRINT("Driver name: '%wZ'\n", &DriverName);
468
469 /*
470 * Retrieve the driver's PE image NT header and perform some sanity checks.
471 * NOTE: We suppose that since the driver has been successfully loaded,
472 * its NT and optional headers are all valid and have expected sizes.
473 */
474 PIMAGE_NT_HEADERS NtHeaders = RtlImageNtHeader(ModuleObject->DllBase);
475 ASSERT(NtHeaders);
476 // NOTE: ModuleObject->SizeOfImage is actually (number of PTEs)*PAGE_SIZE.
477 ASSERT(ModuleObject->SizeOfImage == ROUND_TO_PAGES(NtHeaders->OptionalHeader.SizeOfImage));
478 ASSERT(ModuleObject->EntryPoint == RVA(ModuleObject->DllBase, NtHeaders->OptionalHeader.AddressOfEntryPoint));
479
480 /* Obtain the registry path for the DriverInit routine */
481 PKEY_NAME_INFORMATION nameInfo;
482 ULONG infoLength;
483 Status = ZwQueryKey(ServiceHandle, KeyNameInformation, NULL, 0, &infoLength);
485 {
486 nameInfo = ExAllocatePoolWithTag(NonPagedPool, infoLength, TAG_IO);
487 if (nameInfo)
488 {
489 Status = ZwQueryKey(ServiceHandle,
491 nameInfo,
492 infoLength,
493 &infoLength);
494 if (NT_SUCCESS(Status))
495 {
496 RegistryPath.Length = nameInfo->NameLength;
497 RegistryPath.MaximumLength = nameInfo->NameLength;
498 RegistryPath.Buffer = nameInfo->Name;
499 }
500 else
501 {
502 ExFreePoolWithTag(nameInfo, TAG_IO);
503 }
504 }
505 else
506 {
508 }
509 }
510 else
511 {
513 }
514
515 if (!NT_SUCCESS(Status))
516 {
518 RtlFreeUnicodeString(&DriverName);
519 MmUnloadSystemImage(ModuleObject);
520 return Status;
521 }
522
523 /* Create the driver object */
526 &DriverName,
528 NULL,
529 NULL);
530
531 /* Honor the internal I/O System case (in)sensitivity */
533
534 PDRIVER_OBJECT driverObject;
535 ULONG ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
540 NULL,
541 ObjectSize,
542 0,
543 0,
544 (PVOID*)&driverObject);
545 if (!NT_SUCCESS(Status))
546 {
547 ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
549 RtlFreeUnicodeString(&DriverName);
550 MmUnloadSystemImage(ModuleObject);
551 DPRINT1("Error while creating driver object \"%wZ\" status %x\n", &DriverName, Status);
552 return Status;
553 }
554
555 DPRINT("Created driver object 0x%p for \"%wZ\"\n", driverObject, &DriverName);
556
557 RtlZeroMemory(driverObject, ObjectSize);
558 driverObject->Type = IO_TYPE_DRIVER;
559 driverObject->Size = sizeof(DRIVER_OBJECT);
560
561 /* Set the legacy flag if this is not a WDM driver */
563 driverObject->Flags |= DRVO_LEGACY_DRIVER;
564
565 driverObject->DriverSection = ModuleObject;
566 driverObject->DriverStart = ModuleObject->DllBase;
567 driverObject->DriverSize = ModuleObject->SizeOfImage;
568 driverObject->DriverInit = ModuleObject->EntryPoint;
570 driverObject->DriverExtension = (PDRIVER_EXTENSION)(driverObject + 1);
571 driverObject->DriverExtension->DriverObject = driverObject;
572
573 /* Loop all Major Functions */
574 for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
575 {
576 /* Invalidate each function */
577 driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
578 }
579
580 /* Add the Object and get its handle */
582 Status = ObInsertObject(driverObject, NULL, FILE_READ_DATA, 0, NULL, &hDriver);
583 if (!NT_SUCCESS(Status))
584 {
585 ExFreePoolWithTag(nameInfo, TAG_IO);
587 RtlFreeUnicodeString(&DriverName);
588 return Status;
589 }
590
591 /* Now reference it */
593 0,
596 (PVOID*)&driverObject,
597 NULL);
598
599 /* Close the extra handle */
601
602 if (!NT_SUCCESS(Status))
603 {
604 ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
606 RtlFreeUnicodeString(&DriverName);
607 return Status;
608 }
609
610 /* Set up the service key name buffer */
611 UNICODE_STRING serviceKeyName;
612 serviceKeyName.Length = 0;
613 // NULL-terminate for Windows compatibility
614 serviceKeyName.MaximumLength = ServiceName.MaximumLength + sizeof(UNICODE_NULL);
616 serviceKeyName.MaximumLength,
617 TAG_IO);
618 if (!serviceKeyName.Buffer)
619 {
620 ObMakeTemporaryObject(driverObject);
621 ObDereferenceObject(driverObject);
622 ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
624 RtlFreeUnicodeString(&DriverName);
626 }
627
628 /* Copy the name and set it in the driver extension */
629 RtlCopyUnicodeString(&serviceKeyName, &ServiceName);
631 driverObject->DriverExtension->ServiceKeyName = serviceKeyName;
632
633 /* Make a copy of the driver name to store in the driver object */
634 UNICODE_STRING driverNamePaged;
635 driverNamePaged.Length = 0;
636 // NULL-terminate for Windows compatibility
637 driverNamePaged.MaximumLength = DriverName.MaximumLength + sizeof(UNICODE_NULL);
638 driverNamePaged.Buffer = ExAllocatePoolWithTag(PagedPool,
639 driverNamePaged.MaximumLength,
640 TAG_IO);
641 if (!driverNamePaged.Buffer)
642 {
643 ObMakeTemporaryObject(driverObject);
644 ObDereferenceObject(driverObject);
645 ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
646 RtlFreeUnicodeString(&DriverName);
648 }
649
650 RtlCopyUnicodeString(&driverNamePaged, &DriverName);
651 driverObject->DriverName = driverNamePaged;
652
653 /* Finally, call its init function */
654 Status = driverObject->DriverInit(driverObject, &RegistryPath);
655 *DriverEntryStatus = Status;
656 if (!NT_SUCCESS(Status))
657 {
658 DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", &DriverName, Status);
659 // return a special status value in case of failure
661 }
662
663 /* HACK: We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
664 * Other parts of the I/O manager depend on this behavior */
665 if (!driverObject->DeviceObject)
666 {
667 driverObject->Flags &= ~DRVO_LEGACY_DRIVER;
668 }
669
670 /* Windows does this fixup, keep it for compatibility */
671 for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
672 {
673 /*
674 * Make sure the driver didn't set any dispatch entry point to NULL!
675 * Doing so is illegal; drivers shouldn't touch entry points they
676 * do not implement.
677 */
678
679 /* Check if it did so anyway */
680 if (!driverObject->MajorFunction[i])
681 {
682 /* Print a warning in the debug log */
683 DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
684 &driverObject->DriverName, i);
685
686 /* Fix it up */
687 driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
688 }
689 }
690
691 // TODO: for legacy drivers, unload the driver if it didn't create any DO
692
693 ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
694 RtlFreeUnicodeString(&DriverName);
695
696 if (!NT_SUCCESS(Status))
697 {
698 // if the driver entry has been failed, clear the object
699 ObMakeTemporaryObject(driverObject);
700 ObDereferenceObject(driverObject);
701 return Status;
702 }
703
704 *OutDriverObject = driverObject;
705
707
708 /* Set the driver as initialized */
709 IopReadyDeviceObjects(driverObject);
710
712
713 return STATUS_SUCCESS;
714}
DWORD RVA
Definition: compat.h:1262
#define RtlImageNtHeader
Definition: compat.h:806
#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER
Definition: ntimage.h:462
ULONG IopCaseInsensitive
Definition: iomgr.c:38
VOID NTAPI IopReadyDeviceObjects(IN PDRIVER_OBJECT Driver)
Definition: device.c:34
VOID NTAPI MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:1715
BOOLEAN PnpSystemInit
Definition: iomgr.c:33
NTSTATUS IopGetDriverNames(_In_ HANDLE ServiceHandle, _Out_ PUNICODE_STRING DriverName, _Out_opt_ PUNICODE_STRING ServiceName)
Definition: driver.c:123
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1514
UNICODE_STRING IopHardwareDatabaseKey
Definition: driver.c:30
#define STATUS_FAILED_DRIVER_ENTRY
Definition: ntstatus.h:1039
struct _DRIVER_OBJECT * DriverObject
Definition: iotypes.h:2234
UNICODE_STRING ServiceKeyName
Definition: iotypes.h:2237
PUNICODE_STRING HardwareDatabase
Definition: iotypes.h:2299
PVOID DriverStart
Definition: iotypes.h:2294
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2304
PVOID DriverSection
Definition: iotypes.h:2296
CSHORT Size
Definition: iotypes.h:2291
ULONG DriverSize
Definition: iotypes.h:2295
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2297
CSHORT Type
Definition: iotypes.h:2290
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2292
UNICODE_STRING DriverName
Definition: iotypes.h:2298
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
int32_t INT
Definition: typedefs.h:58
@ KeyNameInformation
Definition: winternl.h:1852
#define ROUND_TO_PAGES(Size)

Referenced by IopInitializeBuiltinDriver(), and IopLoadDriver().

◆ IopInitializeSystemDrivers()

VOID FASTCALL IopInitializeSystemDrivers ( VOID  )

Definition at line 1228 of file driver.c.

1229{
1230 PUNICODE_STRING *DriverList, *SavedList;
1231
1233
1234 /* HACK: No system drivers on the BootCD */
1235 if (KeLoaderBlock->SetupLdrBlock) return;
1236
1237 /* Get the driver list */
1238 SavedList = DriverList = CmGetSystemDriverList();
1239 ASSERT(DriverList);
1240
1241 /* Loop it */
1242 while (*DriverList)
1243 {
1244 /* Load the driver */
1245 ZwLoadDriver(*DriverList);
1246
1247 /* Free the entry */
1248 RtlFreeUnicodeString(*DriverList);
1249 ExFreePool(*DriverList);
1250
1251 /* Next entry */
1253 DriverList++;
1254 }
1255
1256 /* Free the list */
1257 ExFreePool(SavedList);
1258
1261 NULL,
1262 NULL);
1263}
PUNICODE_STRING *NTAPI CmGetSystemDriverList(VOID)
Definition: cmsysini.c:1864
NTSTATUS PiPerformSyncDeviceAction(_In_ PDEVICE_OBJECT DeviceObject, _In_ DEVICE_ACTION Action)
Perfom a device operation synchronously via PiQueueDeviceAction.
Definition: devaction.c:2727

Referenced by IoInitSystem().

◆ IopInvalidDeviceRequest()

NTSTATUS NTAPI IopInvalidDeviceRequest ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 65 of file driver.c.

68{
69 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
70 Irp->IoStatus.Information = 0;
73}
_In_ PIRP Irp
Definition: kse.h:79
#define IoCompleteRequest
Definition: irp.c:1272
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by IoCreateDriver(), and IopInitializeDriverModule().

◆ IopLoadDriver()

NTSTATUS IopLoadDriver ( _In_ HANDLE  ServiceHandle,
_Out_ PDRIVER_OBJECT *  DriverObject 
)

Definition at line 1959 of file driver.c.

1962{
1963 UNICODE_STRING ImagePath;
1965 PLDR_DATA_TABLE_ENTRY ModuleObject;
1967
1969 Status = IopGetRegistryValue(ServiceHandle, L"ImagePath", &kvInfo);
1970 if (NT_SUCCESS(Status))
1971 {
1972 if ((kvInfo->Type != REG_EXPAND_SZ && kvInfo->Type != REG_SZ) ||
1973 (kvInfo->DataLength < sizeof(UNICODE_NULL)) ||
1975 ((kvInfo->DataLength % sizeof(WCHAR)) != 0))
1976 {
1977 DPRINT1("ObjectName invalid (Type = %lu, DataLength = %lu)\n",
1978 kvInfo->Type,
1979 kvInfo->DataLength);
1980 ExFreePool(kvInfo);
1982 }
1983
1984 ImagePath.Length = (USHORT)(kvInfo->DataLength - sizeof(UNICODE_NULL));
1985 ImagePath.MaximumLength = kvInfo->DataLength;
1987 if (!ImagePath.Buffer)
1988 {
1989 ExFreePool(kvInfo);
1991 }
1992
1993 RtlMoveMemory(ImagePath.Buffer,
1994 (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
1995 ImagePath.Length);
1996 ImagePath.Buffer[ImagePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1997 ExFreePool(kvInfo);
1998 }
1999 else
2000 {
2001 return Status;
2002 }
2003
2004 /*
2005 * Normalize the image path for all later processing.
2006 */
2007 Status = IopNormalizeImagePath(&ImagePath, NULL);
2008 if (!NT_SUCCESS(Status))
2009 {
2010 DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
2011 return Status;
2012 }
2013
2014 DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
2015
2018
2019 /*
2020 * Load the driver module
2021 */
2022 DPRINT("Loading module from %wZ\n", &ImagePath);
2023 Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
2024 RtlFreeUnicodeString(&ImagePath);
2025
2026 if (!NT_SUCCESS(Status))
2027 {
2028 DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
2031 return Status;
2032 }
2033
2034 // Display the loading message
2035 ULONG infoLength;
2036 Status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
2038 {
2040 if (servName)
2041 {
2042 Status = ZwQueryKey(ServiceHandle,
2044 servName,
2045 infoLength,
2046 &infoLength);
2047 if (NT_SUCCESS(Status))
2048 {
2050 .Length = servName->NameLength,
2051 .MaximumLength = servName->NameLength,
2052 .Buffer = servName->Name
2053 };
2054
2056 }
2057 ExFreePoolWithTag(servName, TAG_IO);
2058 }
2059 }
2060
2061 NTSTATUS driverEntryStatus;
2062 Status = IopInitializeDriverModule(ModuleObject,
2063 ServiceHandle,
2065 &driverEntryStatus);
2066 if (!NT_SUCCESS(Status))
2067 {
2068 DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
2069 }
2070
2073
2074 return Status;
2075}
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize _Pre_valid_ PVOID * BaseAddress
Definition: mmfuncs.h:408
#define REG_EXPAND_SZ
Definition: nt_native.h:1497
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
NTSTATUS NTAPI MmLoadSystemImage(IN PUNICODE_STRING FileName, IN PUNICODE_STRING NamePrefix OPTIONAL, IN PUNICODE_STRING LoadedName OPTIONAL, IN ULONG Flags, OUT PVOID *ModuleObject, OUT PVOID *ImageBaseAddress)
Definition: sysldr.c:2991
ERESOURCE IopDriverLoadResource
Definition: driver.c:20
NTSTATUS FASTCALL IopNormalizeImagePath(_Inout_ _When_(return >=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem))) PUNICODE_STRING ImagePath, _In_ PUNICODE_STRING ServiceName)
Definition: driver.c:375
#define TAG_RTLREGISTRY
Definition: tag.h:96

Referenced by IopLoadUnloadDriverWorker(), and PiAttachFilterDriversCallback().

◆ IopLoadUnloadDriverWorker()

static VOID NTAPI IopLoadUnloadDriverWorker ( _Inout_ PVOID  Parameter)
static

Definition at line 2080 of file driver.c.

2082{
2083 PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
2084
2086
2087 if (LoadParams->DriverObject)
2088 {
2089 // unload request
2090 LoadParams->DriverObject->DriverUnload(LoadParams->DriverObject);
2091 LoadParams->Status = STATUS_SUCCESS;
2092 }
2093 else
2094 {
2095 // load request
2096 HANDLE serviceHandle;
2098 status = IopOpenRegistryKeyEx(&serviceHandle, NULL, LoadParams->RegistryPath, KEY_READ);
2099 if (!NT_SUCCESS(status))
2100 {
2101 LoadParams->Status = status;
2102 }
2103 else
2104 {
2105 LoadParams->Status = IopLoadDriver(serviceHandle, &LoadParams->DriverObject);
2106 ZwClose(serviceHandle);
2107 }
2108 }
2109
2110 if (LoadParams->SetEvent)
2111 {
2112 KeSetEvent(&LoadParams->Event, 0, FALSE);
2113 }
2114}
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
NTSTATUS IopLoadDriver(_In_ HANDLE ServiceHandle, _Out_ PDRIVER_OBJECT *DriverObject)
Definition: driver.c:1959
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2303
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:336

Referenced by IopDoLoadUnloadDriver().

◆ IopNormalizeImagePath()

NTSTATUS FASTCALL IopNormalizeImagePath ( _Inout_ _When_(return >=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem))) PUNICODE_STRING  ImagePath,
_In_ PUNICODE_STRING  ServiceName 
)

Definition at line 375 of file driver.c.

379{
380 UNICODE_STRING SystemRootString = RTL_CONSTANT_STRING(L"\\SystemRoot\\");
381 UNICODE_STRING DriversPathString = RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\drivers\\");
382 UNICODE_STRING DotSysString = RTL_CONSTANT_STRING(L".sys");
383 UNICODE_STRING InputImagePath;
384
385 DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
386
387 InputImagePath = *ImagePath;
388 if (InputImagePath.Length == 0)
389 {
390 ImagePath->Length = 0;
391 ImagePath->MaximumLength = DriversPathString.Length +
392 ServiceName->Length +
393 DotSysString.Length +
394 sizeof(UNICODE_NULL);
395 ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
396 ImagePath->MaximumLength,
397 TAG_IO);
398 if (ImagePath->Buffer == NULL)
399 return STATUS_NO_MEMORY;
400
401 RtlCopyUnicodeString(ImagePath, &DriversPathString);
403 RtlAppendUnicodeStringToString(ImagePath, &DotSysString);
404 }
405 else if (InputImagePath.Buffer[0] != L'\\')
406 {
407 ImagePath->Length = 0;
408 ImagePath->MaximumLength = SystemRootString.Length +
409 InputImagePath.Length +
410 sizeof(UNICODE_NULL);
411 ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
412 ImagePath->MaximumLength,
413 TAG_IO);
414 if (ImagePath->Buffer == NULL)
415 return STATUS_NO_MEMORY;
416
417 RtlCopyUnicodeString(ImagePath, &SystemRootString);
418 RtlAppendUnicodeStringToString(ImagePath, &InputImagePath);
419
420 /* Free caller's string */
422 }
423
424 DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
425
426 return STATUS_SUCCESS;
427}
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51

Referenced by IopLoadDriver(), and IopUnloadDriver().

◆ IopReinitializeBootDrivers()

VOID NTAPI IopReinitializeBootDrivers ( VOID  )

Definition at line 1550 of file driver.c.

1551{
1552 PDRIVER_REINIT_ITEM ReinitItem;
1554
1555 /* Get the first entry and start looping */
1558 while (Entry)
1559 {
1560 /* Get the item */
1561 ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1562
1563 /* Increment reinitialization counter */
1564 ReinitItem->DriverObject->DriverExtension->Count++;
1565
1566 /* Remove the device object flag */
1567 ReinitItem->DriverObject->Flags &= ~DRVO_BOOTREINIT_REGISTERED;
1568
1569 /* Call the routine */
1570 ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1571 ReinitItem->Context,
1572 ReinitItem->DriverObject->
1573 DriverExtension->Count);
1574
1575 /* Free the entry */
1577
1578 /* Move to the next one */
1581 }
1582
1583 /* Wait for all device actions being finished*/
1585}
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
KEVENT PiEnumerationFinished
Definition: devaction.c:50
KSPIN_LOCK DriverBootReinitListLock
Definition: driver.c:28
LIST_ENTRY DriverBootReinitListHead
Definition: driver.c:27
Entry
Definition: section.c:5216
PDRIVER_OBJECT DriverObject
Definition: io.h:448
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:449
PVOID Context
Definition: io.h:450
@ Executive
Definition: ketypes.h:467

Referenced by IoInitSystem().

◆ IopReinitializeDrivers()

VOID NTAPI IopReinitializeDrivers ( VOID  )

Definition at line 1514 of file driver.c.

1515{
1516 PDRIVER_REINIT_ITEM ReinitItem;
1518
1519 /* Get the first entry and start looping */
1522 while (Entry)
1523 {
1524 /* Get the item */
1525 ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1526
1527 /* Increment reinitialization counter */
1528 ReinitItem->DriverObject->DriverExtension->Count++;
1529
1530 /* Remove the device object flag */
1531 ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1532
1533 /* Call the routine */
1534 ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1535 ReinitItem->Context,
1536 ReinitItem->DriverObject->
1537 DriverExtension->Count);
1538
1539 /* Free the entry */
1541
1542 /* Move to the next one */
1545 }
1546}
LIST_ENTRY DriverReinitListHead
Definition: driver.c:22
KSPIN_LOCK DriverReinitListLock
Definition: driver.c:23

Referenced by IoInitSystem(), and IopInitializeDriverModule().

◆ IopSuffixUnicodeString()

static BOOLEAN IopSuffixUnicodeString ( _In_ PCUNICODE_STRING  String1,
_In_ PCUNICODE_STRING  String2,
_In_ BOOLEAN  CaseInSensitive 
)
static

Determines whether String1 may be a suffix of String2.

Returns
TRUE if String2 contains String1 as a suffix.

Definition at line 286 of file driver.c.

290{
291 PWCHAR pc1, pc2;
292 ULONG NumChars;
293
294 if (String2->Length < String1->Length)
295 return FALSE;
296
297 NumChars = String1->Length / sizeof(WCHAR);
298 pc1 = String1->Buffer;
299 pc2 = &String2->Buffer[String2->Length / sizeof(WCHAR) - NumChars];
300
301 if (pc1 && pc2)
302 {
303 if (CaseInSensitive)
304 {
305 while (NumChars--)
306 {
307 if (RtlUpcaseUnicodeChar(*pc1++) !=
309 {
310 return FALSE;
311 }
312 }
313 }
314 else
315 {
316 while (NumChars--)
317 {
318 if (*pc1++ != *pc2++)
319 return FALSE;
320 }
321 }
322
323 return TRUE;
324 }
325
326 return FALSE;
327}
_In_ const STRING * String2
Definition: rtlfuncs.h:2404
_In_ const STRING _In_ BOOLEAN CaseInSensitive
Definition: rtlfuncs.h:2437
WCHAR NTAPI RtlUpcaseUnicodeChar(_In_ WCHAR Source)
Definition: nlsboot.c:177
static const unsigned char pc1[56]
Definition: des.c:54
static const unsigned char pc2[48]
Definition: des.c:68

Referenced by IopDisplayLoadingMessage().

◆ IopUnloadDriver()

NTSTATUS NTAPI IopUnloadDriver ( PUNICODE_STRING  DriverServiceName,
BOOLEAN  UnloadPnpDrivers 
)

Definition at line 1287 of file driver.c.

1288{
1289 UNICODE_STRING Backslash = RTL_CONSTANT_STRING(L"\\");
1291 UNICODE_STRING ImagePath;
1296 PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1298 USHORT LastBackslash;
1299 BOOLEAN SafeToUnload = TRUE;
1301 UNICODE_STRING CapturedServiceName;
1302
1303 PAGED_CODE();
1304
1306
1307 /* Need the appropriate priviliege */
1309 {
1310 DPRINT1("No unload privilege!\n");
1312 }
1313
1314 /* Capture the service name */
1315 Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
1317 DriverServiceName);
1318 if (!NT_SUCCESS(Status))
1319 {
1320 return Status;
1321 }
1322
1323 DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1324
1325 /* We need a service name */
1326 if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
1327 {
1328 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1330 }
1331
1332 /*
1333 * Get the service name from the registry key name
1334 */
1336 &CapturedServiceName,
1337 &Backslash,
1338 &LastBackslash);
1339 if (NT_SUCCESS(Status))
1340 {
1341 NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
1342 ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / sizeof(WCHAR) + 1];
1343 ServiceName.Length = CapturedServiceName.Length - LastBackslash - sizeof(WCHAR);
1344 ServiceName.MaximumLength = CapturedServiceName.MaximumLength - LastBackslash - sizeof(WCHAR);
1345 }
1346 else
1347 {
1348 ServiceName = CapturedServiceName;
1349 }
1350
1351 /*
1352 * Construct the driver object name
1353 */
1354 Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
1355 ServiceName.Length,
1356 &ObjectName.MaximumLength);
1357 if (!NT_SUCCESS(Status))
1358 {
1359 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1360 return Status;
1361 }
1362 ObjectName.Length = 0;
1364 ObjectName.MaximumLength,
1365 TAG_IO);
1366 if (!ObjectName.Buffer)
1367 {
1368 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1370 }
1373
1374 /*
1375 * Find the driver object
1376 */
1378 0,
1379 0,
1380 0,
1382 KernelMode,
1383 0,
1384 (PVOID*)&DriverObject);
1385
1386 if (!NT_SUCCESS(Status))
1387 {
1388 DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1390 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1391 return Status;
1392 }
1393
1394 /* Free the buffer for driver object name */
1396
1397 /* Check that driver is not already unloading */
1398 if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
1399 {
1400 DPRINT1("Driver deletion pending\n");
1402 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1403 return STATUS_DELETE_PENDING;
1404 }
1405
1406 /*
1407 * Get path of service...
1408 */
1410
1411 RtlInitUnicodeString(&ImagePath, NULL);
1412
1413 QueryTable[0].Name = L"ImagePath";
1415 QueryTable[0].EntryContext = &ImagePath;
1416
1418 CapturedServiceName.Buffer,
1419 QueryTable,
1420 NULL,
1421 NULL);
1422
1423 /* We no longer need service name */
1424 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1425
1426 if (!NT_SUCCESS(Status))
1427 {
1428 DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1430 return Status;
1431 }
1432
1433 /*
1434 * Normalize the image path for all later processing.
1435 */
1437
1438 if (!NT_SUCCESS(Status))
1439 {
1440 DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1442 return Status;
1443 }
1444
1445 /* Free the service path */
1446 ExFreePool(ImagePath.Buffer);
1447
1448 /*
1449 * Unload the module and release the references to the device object
1450 */
1451
1452 /* Call the load/unload routine, depending on current process */
1453 if (DriverObject->DriverUnload && DriverObject->DriverSection &&
1454 (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1455 {
1456 /* Loop through each device object of the driver
1457 and set DOE_UNLOAD_PENDING flag */
1458 DeviceObject = DriverObject->DeviceObject;
1459 while (DeviceObject)
1460 {
1461 /* Set the unload pending flag for the device */
1462 DeviceExtension = IoGetDevObjExtension(DeviceObject);
1463 DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1464
1465 /* Make sure there are no attached devices or no reference counts */
1466 if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1467 {
1468 /* Not safe to unload */
1469 DPRINT1("Drivers device object is referenced or has attached devices\n");
1470
1471 SafeToUnload = FALSE;
1472 }
1473
1474 DeviceObject = DeviceObject->NextDevice;
1475 }
1476
1477 /* If not safe to unload, then return success */
1478 if (!SafeToUnload)
1479 {
1481 return STATUS_SUCCESS;
1482 }
1483
1484 DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1485
1486 /* Set the unload invoked flag and call the unload routine */
1490
1491 /* Mark the driver object temporary, so it could be deleted later */
1493
1494 /* Dereference it 2 times */
1497
1498 return Status;
1499 }
1500 else
1501 {
1502 DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1503
1504 /* Dereference one time (refd inside this function) */
1506
1507 /* Return unloading failure */
1509 }
1510}
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
#define ExGetPreviousMode
Definition: ex.h:143
#define DOE_UNLOAD_PENDING
Definition: iotypes.h:153
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4231
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:128
#define RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END
Definition: rtl.h:25
NTSTATUS NTAPI RtlFindCharInUnicodeString(_In_ ULONG Flags, _In_ PCUNICODE_STRING SearchString, _In_ PCUNICODE_STRING MatchString, _Out_ PUSHORT Position)
const LUID SeLoadDriverPrivilege
Definition: priv.c:29
NTSTATUS IopDoLoadUnloadDriver(_In_opt_ PUNICODE_STRING RegistryPath, _Inout_ PDRIVER_OBJECT *DriverObject)
Process load and unload driver operations. This is mostly for NtLoadDriver and NtUnloadDriver,...
Definition: driver.c:2126
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:416
NTSTATUS NTAPI ObReferenceObjectByName(IN PUNICODE_STRING ObjectPath, IN ULONG Attributes, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext, OUT PVOID *ObjectPtr)
Definition: obref.c:408
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64
#define DRVO_UNLOAD_INVOKED
Definition: iotypes.h:2240
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define NT_ASSERT
Definition: rtlfuncs.h:3334
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3311

Referenced by NtUnloadDriver().

◆ IoRegisterBootDriverReinitialization()

VOID NTAPI IoRegisterBootDriverReinitialization ( IN PDRIVER_OBJECT  DriverObject,
IN PDRIVER_REINITIALIZE  ReinitRoutine,
IN PVOID  Context 
)

Definition at line 1789 of file driver.c.

1792{
1793 PDRIVER_REINIT_ITEM ReinitItem;
1794
1795 /* Allocate the entry */
1797 sizeof(DRIVER_REINIT_ITEM),
1798 TAG_REINIT);
1799 if (!ReinitItem) return;
1800
1801 /* Fill it out */
1802 ReinitItem->DriverObject = DriverObject;
1803 ReinitItem->ReinitRoutine = ReinitRoutine;
1804 ReinitItem->Context = Context;
1805
1806 /* Set the Driver Object flag and insert the entry into the list */
1809 &ReinitItem->ItemEntry,
1811}
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
LIST_ENTRY ItemEntry
Definition: io.h:447
#define TAG_REINIT
Definition: tag.h:83
#define DRVO_BOOTREINIT_REGISTERED
Definition: iotypes.h:4487

Referenced by DriverEntry(), KdpDriverEntry(), and KdpDriverReinit().

◆ IoRegisterDriverReinitialization()

VOID NTAPI IoRegisterDriverReinitialization ( IN PDRIVER_OBJECT  DriverObject,
IN PDRIVER_REINITIALIZE  ReinitRoutine,
IN PVOID  Context 
)

Definition at line 1818 of file driver.c.

1821{
1822 PDRIVER_REINIT_ITEM ReinitItem;
1823
1824 /* Allocate the entry */
1826 sizeof(DRIVER_REINIT_ITEM),
1827 TAG_REINIT);
1828 if (!ReinitItem) return;
1829
1830 /* Fill it out */
1831 ReinitItem->DriverObject = DriverObject;
1832 ReinitItem->ReinitRoutine = ReinitRoutine;
1833 ReinitItem->Context = Context;
1834
1835 /* Set the Driver Object flag and insert the entry into the list */
1838 &ReinitItem->ItemEntry,
1840}
#define DRVO_REINIT_REGISTERED
Definition: iotypes.h:4485

Referenced by DiskBootDriverReinit(), DriverEntry(), and KdpDriverReinit().

◆ LdrProcessDriverModule()

NTSTATUS NTAPI LdrProcessDriverModule ( PLDR_DATA_TABLE_ENTRY  LdrEntry,
PUNICODE_STRING  FileName,
PLDR_DATA_TABLE_ENTRY *  ModuleObject 
)

Definition at line 731 of file driver.c.

734{
736 UNICODE_STRING BaseName, BaseDirectory;
737 PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS;
738 PCHAR MissingApiName, Buffer;
739 PWCHAR MissingDriverName;
740 PVOID DriverBase = LdrEntry->DllBase;
741
742 /* Allocate a buffer we'll use for names */
746 if (!Buffer)
747 {
748 /* Fail */
750 }
751
752 /* Check for a separator */
753 if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
754 {
755 PWCHAR p;
756 ULONG BaseLength;
757
758 /* Loop the path until we get to the base name */
759 p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
760 while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
761
762 /* Get the length */
763 BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
764 BaseLength *= sizeof(WCHAR);
765
766 /* Setup the string */
767 BaseName.Length = (USHORT)BaseLength;
768 BaseName.Buffer = p;
769 }
770 else
771 {
772 /* Otherwise, we already have a base name */
773 BaseName.Length = FileName->Length;
774 BaseName.Buffer = FileName->Buffer;
775 }
776
777 /* Setup the maximum length */
778 BaseName.MaximumLength = BaseName.Length;
779
780 /* Now compute the base directory */
781 BaseDirectory = *FileName;
782 BaseDirectory.Length -= BaseName.Length;
783 BaseDirectory.MaximumLength = BaseDirectory.Length;
784
785 /* Resolve imports */
786 MissingApiName = Buffer;
787 Status = MiResolveImageReferences(DriverBase,
788 &BaseDirectory,
789 NULL,
790 &MissingApiName,
791 &MissingDriverName,
792 &LoadedImports);
793
794 /* Free the temporary buffer */
796
797 /* Check the result of the imports resolution */
798 if (!NT_SUCCESS(Status)) return Status;
799
800 /* Return */
801 *ModuleObject = LdrEntry;
802 return STATUS_SUCCESS;
803}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
struct _FileName FileName
Definition: fatprocs.h:897
GLfloat GLfloat p
Definition: glext.h:8902
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:214
NTSTATUS NTAPI MiResolveImageReferences(IN PVOID ImageBase, IN PUNICODE_STRING ImageFileDirectory, IN PUNICODE_STRING NamePrefix OPTIONAL, OUT PCHAR *MissingApi, OUT PWCHAR *MissingDriver, OUT PLOAD_IMPORTS *LoadImports)
Definition: sysldr.c:1076
PVOID DllBase
Definition: btrfs_drv.h:1880
#define TAG_LDR_WSTR
Definition: tag.h:102
char * PCHAR
Definition: typedefs.h:51

◆ MiResolveImageReferences()

NTSTATUS NTAPI MiResolveImageReferences ( IN PVOID  ImageBase,
IN PUNICODE_STRING  ImageFileDirectory,
IN PUNICODE_STRING NamePrefix  OPTIONAL,
OUT PCHAR *  MissingApi,
OUT PWCHAR *  MissingDriver,
OUT PLOAD_IMPORTS *  LoadImports 
)

Definition at line 1076 of file sysldr.c.

1082{
1083 static UNICODE_STRING DriversFolderName = RTL_CONSTANT_STRING(L"drivers\\");
1084 PCHAR MissingApiBuffer = *MissingApi, ImportName;
1085 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport;
1086 ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize;
1087 PLOAD_IMPORTS LoadedImports, NewImports;
1088 ULONG i;
1089 BOOLEAN GdiLink, NormalLink;
1090 BOOLEAN ReferenceNeeded, Loaded;
1091 ANSI_STRING TempString;
1092 UNICODE_STRING NameString, DllName;
1093 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL, DllEntry, ImportEntry = NULL;
1094 PVOID ImportBase, DllBase;
1095 PLIST_ENTRY NextEntry;
1096 PIMAGE_EXPORT_DIRECTORY ExportDirectory;
1098 PIMAGE_THUNK_DATA OrigThunk, FirstThunk;
1099
1100 PAGED_CODE();
1101
1102 DPRINT("%s - ImageBase: %p. ImageFileDirectory: %wZ\n",
1103 __FUNCTION__, ImageBase, ImageFileDirectory);
1104
1105 /* No name string buffer yet */
1106 NameString.Buffer = NULL;
1107
1108 /* Assume no imports */
1109 *LoadImports = MM_SYSLDR_NO_IMPORTS;
1110
1111 /* Get the import descriptor */
1112 ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase,
1113 TRUE,
1115 &ImportSize);
1116 if (!ImportDescriptor) return STATUS_SUCCESS;
1117
1118 /* Loop all imports to count them */
1119 for (CurrentImport = ImportDescriptor;
1120 (CurrentImport->Name) && (CurrentImport->OriginalFirstThunk);
1121 CurrentImport++)
1122 {
1123 /* One more */
1124 ImportCount++;
1125 }
1126
1127 /* Make sure we have non-zero imports */
1128 if (ImportCount)
1129 {
1130 /* Calculate and allocate the list we'll need */
1131 LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1132 LoadedImports = ExAllocatePoolWithTag(PagedPool,
1133 LoadedImportsSize,
1135 if (LoadedImports)
1136 {
1137 /* Zero it */
1138 RtlZeroMemory(LoadedImports, LoadedImportsSize);
1139 LoadedImports->Count = ImportCount;
1140 }
1141 }
1142 else
1143 {
1144 /* No table */
1145 LoadedImports = NULL;
1146 }
1147
1148 /* Reset the import count and loop descriptors again */
1149 GdiLink = NormalLink = FALSE;
1150 ImportCount = 0;
1151 while ((ImportDescriptor->Name) && (ImportDescriptor->OriginalFirstThunk))
1152 {
1153 /* Get the name */
1154 ImportName = (PCHAR)((ULONG_PTR)ImageBase + ImportDescriptor->Name);
1155
1156 /* Check if this is a GDI driver */
1157 GdiLink = GdiLink ||
1158 !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1));
1159
1160 /* We can also allow dxapi (for Windows compat, allow IRT and coverage) */
1161 NormalLink = NormalLink ||
1162 ((_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) &&
1163 (_strnicmp(ImportName, "dxapi", sizeof("dxapi") - 1)) &&
1164 (_strnicmp(ImportName, "coverage", sizeof("coverage") - 1)) &&
1165 (_strnicmp(ImportName, "irt", sizeof("irt") - 1)));
1166
1167 /* Check if this is a valid GDI driver */
1168 if (GdiLink && NormalLink)
1169 {
1170 /* It's not, it's importing stuff it shouldn't be! */
1172 goto Failure;
1173 }
1174
1175 /* Check for user-mode printer or video card drivers, which don't belong */
1176 if (!(_strnicmp(ImportName, "ntdll", sizeof("ntdll") - 1)) ||
1177 !(_strnicmp(ImportName, "winsrv", sizeof("winsrv") - 1)) ||
1178 !(_strnicmp(ImportName, "advapi32", sizeof("advapi32") - 1)) ||
1179 !(_strnicmp(ImportName, "kernel32", sizeof("kernel32") - 1)) ||
1180 !(_strnicmp(ImportName, "user32", sizeof("user32") - 1)) ||
1181 !(_strnicmp(ImportName, "gdi32", sizeof("gdi32") - 1)))
1182 {
1183 /* This is not kernel code */
1185 goto Failure;
1186 }
1187
1188 /* Check if this is a "core" import, which doesn't get referenced */
1189 if (!(_strnicmp(ImportName, "ntoskrnl", sizeof("ntoskrnl") - 1)) ||
1190 !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) ||
1191 !(_strnicmp(ImportName, "hal", sizeof("hal") - 1)))
1192 {
1193 /* Don't reference this */
1194 ReferenceNeeded = FALSE;
1195 }
1196 else
1197 {
1198 /* Reference these modules */
1199 ReferenceNeeded = TRUE;
1200 }
1201
1202 /* Now setup a unicode string for the import */
1203 RtlInitAnsiString(&TempString, ImportName);
1204 Status = RtlAnsiStringToUnicodeString(&NameString, &TempString, TRUE);
1205 if (!NT_SUCCESS(Status))
1206 {
1207 /* Failed */
1208 goto Failure;
1209 }
1210
1211 /* We don't support name prefixes yet */
1212 if (NamePrefix) DPRINT1("Name Prefix not yet supported!\n");
1213
1214 /* Remember that we haven't loaded the import at this point */
1215CheckDllState:
1216 Loaded = FALSE;
1217 ImportBase = NULL;
1218
1219 /* Loop the driver list */
1220 NextEntry = PsLoadedModuleList.Flink;
1221 while (NextEntry != &PsLoadedModuleList)
1222 {
1223 /* Get the loader entry and compare the name */
1224 LdrEntry = CONTAINING_RECORD(NextEntry,
1226 InLoadOrderLinks);
1227 if (RtlEqualUnicodeString(&NameString,
1228 &LdrEntry->BaseDllName,
1229 TRUE))
1230 {
1231 /* Get the base address */
1232 ImportBase = LdrEntry->DllBase;
1233
1234 /* Check if we haven't loaded yet, and we need references */
1235 if (!(Loaded) && (ReferenceNeeded))
1236 {
1237 /* Make sure we're not already loading */
1238 if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1239 {
1240 /* Increase the load count */
1241 LdrEntry->LoadCount++;
1242 }
1243 }
1244
1245 /* Done, break out */
1246 break;
1247 }
1248
1249 /* Go to the next entry */
1250 NextEntry = NextEntry->Flink;
1251 }
1252
1253 /* Check if we haven't loaded the import yet */
1254 if (!ImportBase)
1255 {
1256 /* Setup the import DLL name */
1257 DllName.MaximumLength = NameString.Length +
1258 ImageFileDirectory->Length +
1259 sizeof(UNICODE_NULL);
1261 DllName.MaximumLength,
1262 TAG_LDR_WSTR);
1263 if (!DllName.Buffer)
1264 {
1265 /* We're out of resources */
1267 goto Failure;
1268 }
1269
1270 /* Add the import name to the base directory */
1271 RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1273 &NameString);
1274
1275 /* Load the image */
1276 Status = MmLoadSystemImage(&DllName,
1277 NamePrefix,
1278 NULL,
1279 FALSE,
1280 (PVOID *)&DllEntry,
1281 &DllBase);
1282
1283 /* win32k / GDI drivers can also import from system32 folder */
1285 (MI_IS_SESSION_ADDRESS(ImageBase) || 1)) // HACK
1286 {
1287 /* Free the old name buffer */
1289
1290 /* Calculate size for a string the adds 'drivers\' */
1291 DllName.MaximumLength += DriversFolderName.Length;
1292
1293 /* Allocate the new buffer */
1295 DllName.MaximumLength,
1296 TAG_LDR_WSTR);
1297 if (!DllName.Buffer)
1298 {
1299 /* We're out of resources */
1301 goto Failure;
1302 }
1303
1304 /* Copy image directory and append 'drivers\' folder name */
1305 RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1306 RtlAppendUnicodeStringToString(&DllName, &DriversFolderName);
1307
1308 /* Now add the import name */
1309 RtlAppendUnicodeStringToString(&DllName, &NameString);
1310
1311 /* Try once again to load the image */
1312 Status = MmLoadSystemImage(&DllName,
1313 NamePrefix,
1314 NULL,
1315 FALSE,
1316 (PVOID *)&DllEntry,
1317 &DllBase);
1318 }
1319
1320 if (!NT_SUCCESS(Status))
1321 {
1322 /* Fill out the information for the error */
1323 *MissingDriver = DllName.Buffer;
1324 *(PULONG)MissingDriver |= 1;
1325 *MissingApi = NULL;
1326
1327 DPRINT1("Failed to load dependency: %wZ\n", &DllName);
1328
1329 /* Don't free the name */
1330 DllName.Buffer = NULL;
1331
1332 /* Cleanup and return */
1333 goto Failure;
1334 }
1335
1336 /* We can free the DLL Name */
1338 DllName.Buffer = NULL;
1339
1340 /* We're now loaded */
1341 Loaded = TRUE;
1342
1343 /* Sanity check */
1344 ASSERT(DllBase == DllEntry->DllBase);
1345
1346 /* Call the initialization routines */
1348 if (!NT_SUCCESS(Status))
1349 {
1350 /* We failed, unload the image */
1351 MmUnloadSystemImage(DllEntry);
1352 ERROR_DBGBREAK("MmCallDllInitialize failed with status 0x%x\n", Status);
1353 Loaded = FALSE;
1354 }
1355
1356 /* Loop again to make sure that everything is OK */
1357 goto CheckDllState;
1358 }
1359
1360 /* Check if we're support to reference this import */
1361 if ((ReferenceNeeded) && (LoadedImports))
1362 {
1363 /* Make sure we're not already loading */
1364 if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1365 {
1366 /* Add the entry */
1367 LoadedImports->Entry[ImportCount] = LdrEntry;
1368 ImportCount++;
1369 }
1370 }
1371
1372 /* Free the import name */
1373 RtlFreeUnicodeString(&NameString);
1374
1375 /* Set the missing driver name and get the export directory */
1376 *MissingDriver = LdrEntry->BaseDllName.Buffer;
1377 ExportDirectory = RtlImageDirectoryEntryToData(ImportBase,
1378 TRUE,
1380 &ExportSize);
1381 if (!ExportDirectory)
1382 {
1383 /* Cleanup and return */
1384 DPRINT1("Warning: Driver failed to load, %S not found\n", *MissingDriver);
1386 goto Failure;
1387 }
1388
1389 /* Make sure we have an IAT */
1390 if (ImportDescriptor->OriginalFirstThunk)
1391 {
1392 /* Get the first thunks */
1393 OrigThunk = (PVOID)((ULONG_PTR)ImageBase +
1394 ImportDescriptor->OriginalFirstThunk);
1395 FirstThunk = (PVOID)((ULONG_PTR)ImageBase +
1396 ImportDescriptor->FirstThunk);
1397
1398 /* Loop the IAT */
1399 while (OrigThunk->u1.AddressOfData)
1400 {
1401 /* Snap thunk */
1402 Status = MiSnapThunk(ImportBase,
1403 ImageBase,
1404 OrigThunk++,
1405 FirstThunk++,
1406 ExportDirectory,
1407 ExportSize,
1408 FALSE,
1409 MissingApi);
1410 if (!NT_SUCCESS(Status))
1411 {
1412 /* Cleanup and return */
1413 goto Failure;
1414 }
1415
1416 /* Reset the buffer */
1417 *MissingApi = MissingApiBuffer;
1418 }
1419 }
1420
1421 /* Go to the next import */
1422 ImportDescriptor++;
1423 }
1424
1425 /* Check if we have an import list */
1426 if (LoadedImports)
1427 {
1428 /* Reset the count again, and loop entries */
1429 ImportCount = 0;
1430 for (i = 0; i < LoadedImports->Count; i++)
1431 {
1432 if (LoadedImports->Entry[i])
1433 {
1434 /* Got an entry, OR it with 1 in case it's the single entry */
1435 ImportEntry = (PVOID)((ULONG_PTR)LoadedImports->Entry[i] |
1437 ImportCount++;
1438 }
1439 }
1440
1441 /* Check if we had no imports */
1442 if (!ImportCount)
1443 {
1444 /* Free the list and set it to no imports */
1445 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1446 LoadedImports = MM_SYSLDR_NO_IMPORTS;
1447 }
1448 else if (ImportCount == 1)
1449 {
1450 /* Just one entry, we can free the table and only use our entry */
1451 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1452 LoadedImports = (PLOAD_IMPORTS)ImportEntry;
1453 }
1454 else if (ImportCount != LoadedImports->Count)
1455 {
1456 /* Allocate a new list */
1457 LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1458 NewImports = ExAllocatePoolWithTag(PagedPool,
1459 LoadedImportsSize,
1461 if (NewImports)
1462 {
1463 /* Set count */
1464 NewImports->Count = 0;
1465
1466 /* Loop all the imports */
1467 for (i = 0; i < LoadedImports->Count; i++)
1468 {
1469 /* Make sure it's valid */
1470 if (LoadedImports->Entry[i])
1471 {
1472 /* Copy it */
1473 NewImports->Entry[NewImports->Count] = LoadedImports->Entry[i];
1474 NewImports->Count++;
1475 }
1476 }
1477
1478 /* Free the old copy */
1479 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1480 LoadedImports = NewImports;
1481 }
1482 }
1483
1484 /* Return the list */
1485 *LoadImports = LoadedImports;
1486 }
1487
1488 /* Return success */
1489 return STATUS_SUCCESS;
1490
1491Failure:
1492
1493 /* Cleanup and return */
1494 RtlFreeUnicodeString(&NameString);
1495
1496 if (LoadedImports)
1497 {
1498 MiDereferenceImports(LoadedImports);
1499 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1500 }
1501
1502 return Status;
1503}
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define __FUNCTION__
Definition: types.h:116
@ Loaded
Definition: fs_rec.h:187
#define LDRP_LOAD_IN_PROGRESS
Definition: ldrtypes.h:46
struct _LOAD_IMPORTS * PLOAD_IMPORTS
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:185
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:216
#define PCHAR
Definition: match.c:90
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:858
#define STATUS_PROCEDURE_NOT_FOUND
Definition: ntstatus.h:452
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
#define ERROR_DBGBREAK(...)
Definition: debug.h:221
union _IMAGE_THUNK_DATA32::@2585 u1
USHORT LoadCount
Definition: ntddk_ex.h:208
SIZE_T Count
Definition: ldrtypes.h:176
PLDR_DATA_TABLE_ENTRY Entry[1]
Definition: ldrtypes.h:177
NTSTATUS NTAPI MiSnapThunk(IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA Name, IN PIMAGE_THUNK_DATA Address, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN SnapForwarder, OUT PCHAR *MissingApi)
Definition: sysldr.c:779
NTSTATUS NTAPI MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
Definition: sysldr.c:558
NTSTATUS NTAPI MmLoadSystemImage(IN PUNICODE_STRING FileName, IN PUNICODE_STRING NamePrefix OPTIONAL, IN PUNICODE_STRING LoadedName OPTIONAL, IN ULONG Flags, OUT PVOID *ModuleObject, OUT PVOID *ImageBaseAddress)
Definition: sysldr.c:2991
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
NTSTATUS NTAPI MmCallDllInitialize(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry, _In_ PLIST_ENTRY ModuleListHead)
Definition: sysldr.c:464
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:976
#define TAG_LDR_IMPORTS
Definition: tag.h:103
uint32_t * PULONG
Definition: typedefs.h:59
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149

Referenced by LdrProcessDriverModule(), and MmLoadSystemImage().

◆ NtLoadDriver()

NTSTATUS NTAPI NtLoadDriver ( IN PUNICODE_STRING  DriverServiceName)

Definition at line 2174 of file driver.c.

2175{
2176 UNICODE_STRING CapturedServiceName = { 0, 0, NULL };
2180
2181 PAGED_CODE();
2182
2184
2185 /* Need the appropriate priviliege */
2187 {
2188 DPRINT1("No load privilege!\n");
2190 }
2191
2192 /* Capture the service name */
2193 Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
2195 DriverServiceName);
2196 if (!NT_SUCCESS(Status))
2197 {
2198 return Status;
2199 }
2200
2201 DPRINT("NtLoadDriver('%wZ')\n", &CapturedServiceName);
2202
2203 /* We need a service name */
2204 if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
2205 {
2206 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2208 }
2209
2210 /* Load driver and call its entry point */
2212 Status = IopDoLoadUnloadDriver(&CapturedServiceName, &DriverObject);
2213
2214 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2215 return Status;
2216}
#define KeGetPreviousMode()
Definition: ketypes.h:1115

Referenced by NtStartDriver(), ScmLoadDriver(), and wmain().

◆ NtUnloadDriver()

NTSTATUS NTAPI NtUnloadDriver ( IN PUNICODE_STRING  DriverServiceName)

Definition at line 2235 of file driver.c.

2236{
2237 return IopUnloadDriver(DriverServiceName, FALSE);
2238}
NTSTATUS NTAPI IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
Definition: driver.c:1287

Referenced by LoadVia_SystemExtendServiceTableInformation(), LoadVia_SystemLoadGdiDriverInformation(), NtStopDriver(), ScmUnloadDriver(), START_TEST(), and wmain().

Variable Documentation

◆ DriverBootReinitListHead

LIST_ENTRY DriverBootReinitListHead

◆ DriverBootReinitListLock

KSPIN_LOCK DriverBootReinitListLock

◆ DriverBootReinitTailEntry

PLIST_ENTRY DriverBootReinitTailEntry

Definition at line 26 of file driver.c.

◆ DriverReinitListHead

LIST_ENTRY DriverReinitListHead

Definition at line 22 of file driver.c.

Referenced by IoInitSystem(), IopReinitializeDrivers(), and IoRegisterDriverReinitialization().

◆ DriverReinitListLock

KSPIN_LOCK DriverReinitListLock

Definition at line 23 of file driver.c.

Referenced by IoInitSystem(), IopReinitializeDrivers(), and IoRegisterDriverReinitialization().

◆ DriverReinitTailEntry

PLIST_ENTRY DriverReinitTailEntry

Definition at line 24 of file driver.c.

◆ IoDriverObjectType

◆ IopDriverLoadResource

ERESOURCE IopDriverLoadResource

Definition at line 20 of file driver.c.

Referenced by IoInitSystem(), and IopLoadDriver().

◆ IopGroupIndex

USHORT IopGroupIndex

Definition at line 40 of file driver.c.

Referenced by IopInitializeBootDrivers().

◆ IopGroupTable

PLIST_ENTRY IopGroupTable

Definition at line 41 of file driver.c.

Referenced by IopInitializeBootDrivers().

◆ IopHardwareDatabaseKey

UNICODE_STRING IopHardwareDatabaseKey
Initial value:
=
RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM")

Definition at line 30 of file driver.c.

Referenced by IopInitializeDriverModule().

◆ PiEnumerationFinished

KEVENT PiEnumerationFinished
extern

Definition at line 50 of file devaction.c.

Referenced by IopReinitializeBootDrivers().

◆ PnPBootDriversLoaded

BOOLEAN PnPBootDriversLoaded
extern

Definition at line 20 of file pnpinit.c.

Referenced by IopInitializeBootDrivers().

◆ PnpSystemInit

BOOLEAN PnpSystemInit
extern

Definition at line 33 of file iomgr.c.

Referenced by IopInitializeDriverModule().

◆ ServicesKeyName

const WCHAR ServicesKeyName[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
static

Definition at line 32 of file driver.c.

Referenced by IopInitializeBuiltinDriver(), and MmCallDllInitialize().